Spaces:
Running
Running
Pulastya B
commited on
Commit
Β·
b8bcf55
1
Parent(s):
562b130
feat: Add dynamic prompt system for small context window models (Groq support)
Browse files- Created dynamic_prompts.py with intent-based tool loading
- Reduces prompt from ~20K to ~2K tokens (90% reduction)
- Auto-detects user intent and loads only relevant tools
- Enables Groq support without context overflow
- Automatically enabled for Groq, optional for Gemini
- Supports: viz-only, profiling, ML training, code execution
- Fixed 'output' parameter hallucination with general correction
- src/api/app.py +8 -1
- src/dynamic_prompts.py +281 -0
- src/orchestrator.py +18 -2
src/api/app.py
CHANGED
|
@@ -61,11 +61,18 @@ async def startup_event():
|
|
| 61 |
global agent
|
| 62 |
try:
|
| 63 |
logger.info("Initializing DataScienceCopilot...")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
agent = DataScienceCopilot(
|
| 65 |
reasoning_effort="medium",
|
| 66 |
-
provider=
|
|
|
|
| 67 |
)
|
| 68 |
logger.info(f"β
Agent initialized with provider: {agent.provider}")
|
|
|
|
|
|
|
| 69 |
except Exception as e:
|
| 70 |
logger.error(f"β Failed to initialize agent: {e}")
|
| 71 |
raise
|
|
|
|
| 61 |
global agent
|
| 62 |
try:
|
| 63 |
logger.info("Initializing DataScienceCopilot...")
|
| 64 |
+
provider = os.getenv("LLM_PROVIDER", "groq")
|
| 65 |
+
# Auto-enable compact prompts for Groq (small context window)
|
| 66 |
+
use_compact = provider.lower() == "groq"
|
| 67 |
+
|
| 68 |
agent = DataScienceCopilot(
|
| 69 |
reasoning_effort="medium",
|
| 70 |
+
provider=provider,
|
| 71 |
+
use_compact_prompts=use_compact
|
| 72 |
)
|
| 73 |
logger.info(f"β
Agent initialized with provider: {agent.provider}")
|
| 74 |
+
if use_compact:
|
| 75 |
+
logger.info("π§ Compact prompts enabled for small context window")
|
| 76 |
except Exception as e:
|
| 77 |
logger.error(f"β Failed to initialize agent: {e}")
|
| 78 |
raise
|
src/dynamic_prompts.py
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Dynamic prompt generation for small context window models.
|
| 3 |
+
Loads only relevant tools based on user intent to reduce token usage.
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
from typing import List, Dict, Set
|
| 7 |
+
import re
|
| 8 |
+
|
| 9 |
+
# Intent categories and their keywords
|
| 10 |
+
INTENT_KEYWORDS = {
|
| 11 |
+
"data_quality": ["clean", "missing", "outlier", "quality", "duplicates", "null", "na", "impute"],
|
| 12 |
+
"visualization": ["plot", "chart", "graph", "visualize", "dashboard", "scatter", "histogram", "heatmap"],
|
| 13 |
+
"feature_engineering": ["feature", "encode", "transform", "scale", "normalize", "binning", "interaction"],
|
| 14 |
+
"model_training": ["train", "model", "predict", "classify", "regression", "forecast", "xgboost", "accuracy"],
|
| 15 |
+
"eda": ["profile", "describe", "summary", "statistics", "distribution", "correlation", "eda"],
|
| 16 |
+
"time_series": ["time", "date", "datetime", "temporal", "trend", "seasonality", "forecast"],
|
| 17 |
+
"optimization": ["tune", "optimize", "hyperparameter", "improve", "best parameters"],
|
| 18 |
+
"code_execution": ["execute", "run code", "calculate", "custom", "python"],
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
# Tool categories mapping
|
| 22 |
+
TOOL_CATEGORIES = {
|
| 23 |
+
"data_quality": [
|
| 24 |
+
"detect_data_quality_issues",
|
| 25 |
+
"clean_missing_values",
|
| 26 |
+
"handle_outliers",
|
| 27 |
+
"detect_and_remove_duplicates",
|
| 28 |
+
"force_numeric_conversion",
|
| 29 |
+
],
|
| 30 |
+
"visualization": [
|
| 31 |
+
"generate_interactive_scatter",
|
| 32 |
+
"generate_interactive_histogram",
|
| 33 |
+
"generate_interactive_correlation_heatmap",
|
| 34 |
+
"generate_interactive_box_plots",
|
| 35 |
+
"generate_interactive_time_series",
|
| 36 |
+
"generate_plotly_dashboard",
|
| 37 |
+
"generate_all_plots",
|
| 38 |
+
"generate_data_quality_plots",
|
| 39 |
+
"generate_eda_plots",
|
| 40 |
+
],
|
| 41 |
+
"feature_engineering": [
|
| 42 |
+
"encode_categorical",
|
| 43 |
+
"perform_feature_scaling",
|
| 44 |
+
"create_time_features",
|
| 45 |
+
"create_ratio_features",
|
| 46 |
+
"create_statistical_features",
|
| 47 |
+
"create_log_features",
|
| 48 |
+
"create_binned_features",
|
| 49 |
+
"auto_feature_engineering",
|
| 50 |
+
],
|
| 51 |
+
"model_training": [
|
| 52 |
+
"train_baseline_models",
|
| 53 |
+
"hyperparameter_tuning",
|
| 54 |
+
"train_ensemble_models",
|
| 55 |
+
"perform_cross_validation",
|
| 56 |
+
"handle_imbalanced_data",
|
| 57 |
+
"auto_ml_pipeline",
|
| 58 |
+
],
|
| 59 |
+
"eda": [
|
| 60 |
+
"profile_dataset",
|
| 61 |
+
"generate_ydata_profiling_report",
|
| 62 |
+
"analyze_distribution",
|
| 63 |
+
"detect_trends_and_seasonality",
|
| 64 |
+
"perform_hypothesis_testing",
|
| 65 |
+
],
|
| 66 |
+
"time_series": [
|
| 67 |
+
"create_time_features",
|
| 68 |
+
"forecast_time_series",
|
| 69 |
+
"detect_trends_and_seasonality",
|
| 70 |
+
"generate_interactive_time_series",
|
| 71 |
+
],
|
| 72 |
+
"optimization": [
|
| 73 |
+
"hyperparameter_tuning",
|
| 74 |
+
"auto_feature_selection",
|
| 75 |
+
"detect_and_handle_multicollinearity",
|
| 76 |
+
],
|
| 77 |
+
"code_execution": [
|
| 78 |
+
"execute_python_code",
|
| 79 |
+
"execute_code_from_file",
|
| 80 |
+
],
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
# Core tools always included (used in all workflows)
|
| 84 |
+
CORE_TOOLS = [
|
| 85 |
+
"profile_dataset",
|
| 86 |
+
"detect_data_quality_issues",
|
| 87 |
+
"clean_missing_values",
|
| 88 |
+
"encode_categorical",
|
| 89 |
+
]
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
def detect_intent(query: str) -> Set[str]:
|
| 93 |
+
"""
|
| 94 |
+
Detect user intent from query using keyword matching.
|
| 95 |
+
|
| 96 |
+
Args:
|
| 97 |
+
query: User's natural language query
|
| 98 |
+
|
| 99 |
+
Returns:
|
| 100 |
+
Set of intent categories detected
|
| 101 |
+
"""
|
| 102 |
+
query_lower = query.lower()
|
| 103 |
+
detected_intents = set()
|
| 104 |
+
|
| 105 |
+
for intent, keywords in INTENT_KEYWORDS.items():
|
| 106 |
+
for keyword in keywords:
|
| 107 |
+
if keyword in query_lower:
|
| 108 |
+
detected_intents.add(intent)
|
| 109 |
+
break
|
| 110 |
+
|
| 111 |
+
# Default to EDA if no specific intent detected
|
| 112 |
+
if not detected_intents:
|
| 113 |
+
detected_intents.add("eda")
|
| 114 |
+
|
| 115 |
+
return detected_intents
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
def get_relevant_tools(intents: Set[str]) -> List[str]:
|
| 119 |
+
"""
|
| 120 |
+
Get list of relevant tools based on detected intents.
|
| 121 |
+
|
| 122 |
+
Args:
|
| 123 |
+
intents: Set of detected intent categories
|
| 124 |
+
|
| 125 |
+
Returns:
|
| 126 |
+
List of tool names to include in prompt
|
| 127 |
+
"""
|
| 128 |
+
tools = set(CORE_TOOLS) # Always include core tools
|
| 129 |
+
|
| 130 |
+
for intent in intents:
|
| 131 |
+
if intent in TOOL_CATEGORIES:
|
| 132 |
+
tools.update(TOOL_CATEGORIES[intent])
|
| 133 |
+
|
| 134 |
+
return sorted(list(tools))
|
| 135 |
+
|
| 136 |
+
|
| 137 |
+
def build_compact_system_prompt(user_query: str = None, detected_intents: Set[str] = None) -> str:
|
| 138 |
+
"""
|
| 139 |
+
Build a compact system prompt with only relevant tools.
|
| 140 |
+
|
| 141 |
+
Args:
|
| 142 |
+
user_query: Optional user query to detect intent
|
| 143 |
+
detected_intents: Optional pre-detected intents
|
| 144 |
+
|
| 145 |
+
Returns:
|
| 146 |
+
Compact system prompt string
|
| 147 |
+
"""
|
| 148 |
+
# Detect intents if not provided
|
| 149 |
+
if detected_intents is None and user_query:
|
| 150 |
+
detected_intents = detect_intent(user_query)
|
| 151 |
+
elif detected_intents is None:
|
| 152 |
+
detected_intents = {"eda"} # Default
|
| 153 |
+
|
| 154 |
+
# Get relevant tools
|
| 155 |
+
relevant_tools = get_relevant_tools(detected_intents)
|
| 156 |
+
|
| 157 |
+
# Build tool list string
|
| 158 |
+
tool_list = "\n".join([f"- {tool}" for tool in relevant_tools])
|
| 159 |
+
|
| 160 |
+
prompt = f"""You are an autonomous Data Science Agent. You EXECUTE tasks, not advise.
|
| 161 |
+
|
| 162 |
+
**TOOL CALLING FORMAT:**
|
| 163 |
+
When you need to use a tool, respond with JSON:
|
| 164 |
+
```json
|
| 165 |
+
{{
|
| 166 |
+
"tool": "tool_name",
|
| 167 |
+
"arguments": {{"param1": "value1"}}
|
| 168 |
+
}}
|
| 169 |
+
```
|
| 170 |
+
|
| 171 |
+
**RELEVANT TOOLS FOR THIS TASK:**
|
| 172 |
+
{tool_list}
|
| 173 |
+
|
| 174 |
+
**WORKFLOW RULES:**
|
| 175 |
+
1. **Execute tools sequentially** - ONE tool per response
|
| 176 |
+
2. **Use tool outputs** as inputs to next tool
|
| 177 |
+
3. **Save outputs** to ./outputs/data/ or ./outputs/plots/
|
| 178 |
+
4. **Error recovery**: If tool fails, retry with corrected parameters OR skip to next step
|
| 179 |
+
5. **Never repeat** successful tools
|
| 180 |
+
6. **Stop when done** - Don't continue after fulfilling user request
|
| 181 |
+
|
| 182 |
+
**COMMON WORKFLOWS:**
|
| 183 |
+
|
| 184 |
+
**Visualization Only:**
|
| 185 |
+
- User wants plots/charts/dashboard
|
| 186 |
+
- generate_plotly_dashboard OR generate_interactive_scatter β STOP
|
| 187 |
+
|
| 188 |
+
**Data Profiling:**
|
| 189 |
+
- User wants "detailed report"
|
| 190 |
+
- generate_ydata_profiling_report β STOP
|
| 191 |
+
|
| 192 |
+
**Full ML Pipeline:**
|
| 193 |
+
- User wants model training
|
| 194 |
+
- profile_dataset β detect_data_quality_issues β clean_missing_values β
|
| 195 |
+
encode_categorical β train_baseline_models β generate_plotly_dashboard
|
| 196 |
+
|
| 197 |
+
**PARAMETER CORRECTIONS:**
|
| 198 |
+
- Use exact column names from error messages
|
| 199 |
+
- If "Did you mean X?" β retry with X
|
| 200 |
+
- output_path (not output or output_dir)
|
| 201 |
+
- file_path for data files
|
| 202 |
+
|
| 203 |
+
**ERROR RECOVERY:**
|
| 204 |
+
- Column not found? Use suggested column from error
|
| 205 |
+
- File not found? Use last successful file
|
| 206 |
+
- Missing param? Add the required parameter
|
| 207 |
+
- Tool failed? Skip to next step (don't get stuck)
|
| 208 |
+
|
| 209 |
+
Execute the user's task efficiently with relevant tools."""
|
| 210 |
+
|
| 211 |
+
return prompt
|
| 212 |
+
|
| 213 |
+
|
| 214 |
+
def get_full_system_prompt() -> str:
|
| 215 |
+
"""
|
| 216 |
+
Get the original full system prompt for models with large context windows.
|
| 217 |
+
This is the complete version used with Gemini 2.5 Flash.
|
| 218 |
+
"""
|
| 219 |
+
# Import the original prompt from orchestrator
|
| 220 |
+
from src.orchestrator import DataScienceCopilot
|
| 221 |
+
copilot = DataScienceCopilot.__new__(DataScienceCopilot)
|
| 222 |
+
return copilot._build_system_prompt()
|
| 223 |
+
|
| 224 |
+
|
| 225 |
+
# Quick stats
|
| 226 |
+
def get_prompt_stats(prompt: str) -> Dict[str, int]:
|
| 227 |
+
"""Get token count estimate and character count for prompt."""
|
| 228 |
+
chars = len(prompt)
|
| 229 |
+
# Rough estimate: 1 token β 4 characters
|
| 230 |
+
tokens = chars // 4
|
| 231 |
+
lines = len(prompt.split('\n'))
|
| 232 |
+
|
| 233 |
+
return {
|
| 234 |
+
"characters": chars,
|
| 235 |
+
"estimated_tokens": tokens,
|
| 236 |
+
"lines": lines,
|
| 237 |
+
}
|
| 238 |
+
|
| 239 |
+
|
| 240 |
+
if __name__ == "__main__":
|
| 241 |
+
# Demo: Compare full vs compact prompts
|
| 242 |
+
print("=" * 80)
|
| 243 |
+
print("DYNAMIC PROMPT SYSTEM DEMO")
|
| 244 |
+
print("=" * 80)
|
| 245 |
+
|
| 246 |
+
# Example 1: Visualization request
|
| 247 |
+
query1 = "Generate interactive plots for magnitude and latitude"
|
| 248 |
+
intents1 = detect_intent(query1)
|
| 249 |
+
prompt1 = build_compact_system_prompt(user_query=query1)
|
| 250 |
+
stats1 = get_prompt_stats(prompt1)
|
| 251 |
+
|
| 252 |
+
print(f"\nπ Example 1: '{query1}'")
|
| 253 |
+
print(f"Detected intents: {intents1}")
|
| 254 |
+
print(f"Tools loaded: {len(get_relevant_tools(intents1))}")
|
| 255 |
+
print(f"Prompt stats: {stats1['estimated_tokens']} tokens, {stats1['lines']} lines")
|
| 256 |
+
|
| 257 |
+
# Example 2: Full ML pipeline
|
| 258 |
+
query2 = "Train a model to predict earthquake magnitude"
|
| 259 |
+
intents2 = detect_intent(query2)
|
| 260 |
+
prompt2 = build_compact_system_prompt(user_query=query2)
|
| 261 |
+
stats2 = get_prompt_stats(prompt2)
|
| 262 |
+
|
| 263 |
+
print(f"\nπ€ Example 2: '{query2}'")
|
| 264 |
+
print(f"Detected intents: {intents2}")
|
| 265 |
+
print(f"Tools loaded: {len(get_relevant_tools(intents2))}")
|
| 266 |
+
print(f"Prompt stats: {stats2['estimated_tokens']} tokens, {stats2['lines']} lines")
|
| 267 |
+
|
| 268 |
+
# Example 3: Data profiling
|
| 269 |
+
query3 = "Generate a detailed profiling report"
|
| 270 |
+
intents3 = detect_intent(query3)
|
| 271 |
+
prompt3 = build_compact_system_prompt(user_query=query3)
|
| 272 |
+
stats3 = get_prompt_stats(prompt3)
|
| 273 |
+
|
| 274 |
+
print(f"\nπ Example 3: '{query3}'")
|
| 275 |
+
print(f"Detected intents: {intents3}")
|
| 276 |
+
print(f"Tools loaded: {len(get_relevant_tools(intents3))}")
|
| 277 |
+
print(f"Prompt stats: {stats3['estimated_tokens']} tokens, {stats3['lines']} lines")
|
| 278 |
+
|
| 279 |
+
print("\n" + "=" * 80)
|
| 280 |
+
print("SUMMARY: Compact prompts reduce tokens by 80-90% for small context models!")
|
| 281 |
+
print("=" * 80)
|
src/orchestrator.py
CHANGED
|
@@ -137,7 +137,8 @@ class DataScienceCopilot:
|
|
| 137 |
reasoning_effort: str = "medium",
|
| 138 |
provider: Optional[str] = None,
|
| 139 |
session_id: Optional[str] = None,
|
| 140 |
-
use_session_memory: bool = True
|
|
|
|
| 141 |
"""
|
| 142 |
Initialize the Data Science Copilot.
|
| 143 |
|
|
@@ -149,6 +150,7 @@ class DataScienceCopilot:
|
|
| 149 |
provider: LLM provider - 'groq' or 'gemini' (or set LLM_PROVIDER env var)
|
| 150 |
session_id: Session ID to resume (None = auto-resume recent or create new)
|
| 151 |
use_session_memory: Enable session-based memory for context across requests
|
|
|
|
| 152 |
"""
|
| 153 |
# Load environment variables
|
| 154 |
load_dotenv()
|
|
@@ -156,6 +158,9 @@ class DataScienceCopilot:
|
|
| 156 |
# Determine provider
|
| 157 |
self.provider = provider or os.getenv("LLM_PROVIDER", "groq").lower()
|
| 158 |
|
|
|
|
|
|
|
|
|
|
| 159 |
if self.provider == "groq":
|
| 160 |
# Initialize Groq client
|
| 161 |
api_key = groq_api_key or os.getenv("GROQ_API_KEY")
|
|
@@ -848,6 +853,11 @@ You are a DOER. Complete workflows based on user intent."""
|
|
| 848 |
# Convert directory to full file path
|
| 849 |
arguments["output_path"] = f"{output_dir}/ydata_profile.html"
|
| 850 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 851 |
# Fix "None" string being passed as actual None
|
| 852 |
for key, value in list(arguments.items()):
|
| 853 |
if isinstance(value, str) and value.lower() in ["none", "null", "undefined"]:
|
|
@@ -1294,7 +1304,13 @@ You are a DOER. Complete workflows based on user intent."""
|
|
| 1294 |
return cached
|
| 1295 |
|
| 1296 |
# Build initial messages
|
| 1297 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1298 |
|
| 1299 |
# π§ RESOLVE AMBIGUITY USING SESSION MEMORY
|
| 1300 |
original_file_path = file_path
|
|
|
|
| 137 |
reasoning_effort: str = "medium",
|
| 138 |
provider: Optional[str] = None,
|
| 139 |
session_id: Optional[str] = None,
|
| 140 |
+
use_session_memory: bool = True,
|
| 141 |
+
use_compact_prompts: bool = False):
|
| 142 |
"""
|
| 143 |
Initialize the Data Science Copilot.
|
| 144 |
|
|
|
|
| 150 |
provider: LLM provider - 'groq' or 'gemini' (or set LLM_PROVIDER env var)
|
| 151 |
session_id: Session ID to resume (None = auto-resume recent or create new)
|
| 152 |
use_session_memory: Enable session-based memory for context across requests
|
| 153 |
+
use_compact_prompts: Use compact prompts for small context window models (e.g., Groq)
|
| 154 |
"""
|
| 155 |
# Load environment variables
|
| 156 |
load_dotenv()
|
|
|
|
| 158 |
# Determine provider
|
| 159 |
self.provider = provider or os.getenv("LLM_PROVIDER", "groq").lower()
|
| 160 |
|
| 161 |
+
# Set compact prompts: Auto-enable for Groq, manual for others
|
| 162 |
+
self.use_compact_prompts = use_compact_prompts or (self.provider == "groq")
|
| 163 |
+
|
| 164 |
if self.provider == "groq":
|
| 165 |
# Initialize Groq client
|
| 166 |
api_key = groq_api_key or os.getenv("GROQ_API_KEY")
|
|
|
|
| 853 |
# Convert directory to full file path
|
| 854 |
arguments["output_path"] = f"{output_dir}/ydata_profile.html"
|
| 855 |
|
| 856 |
+
# General parameter corrections for common LLM hallucinations
|
| 857 |
+
if "output" in arguments and "output_path" not in arguments:
|
| 858 |
+
# Many tools use 'output_path' but LLM uses 'output'
|
| 859 |
+
arguments["output_path"] = arguments.pop("output")
|
| 860 |
+
|
| 861 |
# Fix "None" string being passed as actual None
|
| 862 |
for key, value in list(arguments.items()):
|
| 863 |
if isinstance(value, str) and value.lower() in ["none", "null", "undefined"]:
|
|
|
|
| 1304 |
return cached
|
| 1305 |
|
| 1306 |
# Build initial messages
|
| 1307 |
+
# Use dynamic prompts for small context models
|
| 1308 |
+
if self.use_compact_prompts:
|
| 1309 |
+
from .dynamic_prompts import build_compact_system_prompt
|
| 1310 |
+
system_prompt = build_compact_system_prompt(user_query=task_description)
|
| 1311 |
+
print("π§ Using compact prompt for small context window")
|
| 1312 |
+
else:
|
| 1313 |
+
system_prompt = self._build_system_prompt()
|
| 1314 |
|
| 1315 |
# π§ RESOLVE AMBIGUITY USING SESSION MEMORY
|
| 1316 |
original_file_path = file_path
|