lucashudsn commited on
Commit
6cfb334
·
1 Parent(s): 8c80df3

agent: derive full budget (tokens, score_week cap) from explicit step caps

Browse files
Files changed (1) hide show
  1. wavereader/agent.py +26 -5
wavereader/agent.py CHANGED
@@ -67,6 +67,18 @@ def resolve_budget(profile: Optional[str] = None) -> tuple[str, dict[str, int]]:
67
  return key, BUDGETS[key]
68
 
69
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  SYSTEM_PROMPT = """You are wave~reader, a surf forecasting assistant for Australian breaks. States use full names (New South Wales, Victoria, Queensland, Western Australia, South Australia, Tasmania) with codes NSW/QLD/VIC/WA/SA/TAS as aliases. Skill tiers: beginner/intermediate/advanced/expert.
71
 
72
  RULES:
@@ -175,12 +187,16 @@ def create_agent(
175
 
176
  Args:
177
  hf_token: HF token (falls back to ``HF_TOKEN`` env).
178
- max_steps: Per-turn step cap; None uses the profile's steps.
 
179
  model: Optional prebuilt smolagents model (injected by dry-run/tests
180
  so no network or token is needed offline).
181
  profile: Budget profile name (quick/standard/deep).
182
  """
183
  _key, budget = resolve_budget(profile)
 
 
 
184
  model_obj = model if model is not None else _llm.build_agent_model(
185
  hf_token, max_tokens=budget["max_tokens"], temperature=MODEL_TEMPERATURE, timeout=MODEL_TIMEOUT
186
  )
@@ -190,13 +206,13 @@ def create_agent(
190
  return CodeAgent(
191
  tools=tools,
192
  model=model_obj,
193
- max_steps=max_steps if max_steps is not None else budget["max_steps"],
194
  )
195
  return ToolCallingAgent(
196
  tools=tools,
197
  model=model_obj,
198
  prompt_templates=_prompt_templates(),
199
- max_steps=max_steps if max_steps is not None else budget["max_steps"],
200
  )
201
 
202
 
@@ -212,17 +228,22 @@ def run_stream(
212
  Args:
213
  question: User question (wrapped as untrusted <data>, never instructions).
214
  hf_token: HF token override.
215
- max_steps: Per-turn step cap; None uses the profile's steps.
 
216
  model: Optional prebuilt model (dry-run/tests).
217
  profile: Budget profile name (quick/standard/deep).
218
  """
219
  profile_key, budget = resolve_budget(profile)
 
 
 
 
220
  counter: dict[str, int] = {}
221
  model_obj = model if model is not None else _llm.build_agent_model(
222
  hf_token, max_tokens=budget["max_tokens"], temperature=MODEL_TEMPERATURE, timeout=MODEL_TIMEOUT
223
  )
224
  tools = build_tools(counter, score_week_cap=budget["score_week_calls"])
225
- steps_cap = max_steps if max_steps is not None else budget["max_steps"]
226
  if os.environ.get("WR_AGENT", "").strip().lower() == "code":
227
  agent: Any = CodeAgent(tools=tools, model=model_obj, max_steps=steps_cap)
228
  else:
 
67
  return key, BUDGETS[key]
68
 
69
 
70
+ def budget_for_steps(steps: int) -> dict[str, int]:
71
+ """Derive a full budget from a step count (UI slider path).
72
+
73
+ Reproduces the named profiles exactly at their step counts
74
+ (4 → quick, 6 → standard, 10 → deep): 100 tokens + 100 per step,
75
+ one score_week call per ~3 steps.
76
+ """
77
+ s = max(1, int(steps))
78
+ return {"max_steps": s, "max_tokens": 100 + 100 * s,
79
+ "score_week_calls": max(1, round(s / 3))}
80
+
81
+
82
  SYSTEM_PROMPT = """You are wave~reader, a surf forecasting assistant for Australian breaks. States use full names (New South Wales, Victoria, Queensland, Western Australia, South Australia, Tasmania) with codes NSW/QLD/VIC/WA/SA/TAS as aliases. Skill tiers: beginner/intermediate/advanced/expert.
83
 
84
  RULES:
 
187
 
188
  Args:
189
  hf_token: HF token (falls back to ``HF_TOKEN`` env).
190
+ max_steps: Per-turn step cap; when set, token + score_week caps
191
+ derive from it (:func:`budget_for_steps`), else the profile's.
192
  model: Optional prebuilt smolagents model (injected by dry-run/tests
193
  so no network or token is needed offline).
194
  profile: Budget profile name (quick/standard/deep).
195
  """
196
  _key, budget = resolve_budget(profile)
197
+ if max_steps is not None:
198
+ # Explicit step cap wins: derive tokens + score_week cap from it.
199
+ budget = budget_for_steps(max_steps)
200
  model_obj = model if model is not None else _llm.build_agent_model(
201
  hf_token, max_tokens=budget["max_tokens"], temperature=MODEL_TEMPERATURE, timeout=MODEL_TIMEOUT
202
  )
 
206
  return CodeAgent(
207
  tools=tools,
208
  model=model_obj,
209
+ max_steps=budget["max_steps"],
210
  )
211
  return ToolCallingAgent(
212
  tools=tools,
213
  model=model_obj,
214
  prompt_templates=_prompt_templates(),
215
+ max_steps=budget["max_steps"],
216
  )
217
 
218
 
 
228
  Args:
229
  question: User question (wrapped as untrusted <data>, never instructions).
230
  hf_token: HF token override.
231
+ max_steps: Per-turn step cap; when set, token + score_week caps
232
+ derive from it (:func:`budget_for_steps`), else the profile's.
233
  model: Optional prebuilt model (dry-run/tests).
234
  profile: Budget profile name (quick/standard/deep).
235
  """
236
  profile_key, budget = resolve_budget(profile)
237
+ if max_steps is not None:
238
+ # Explicit step cap wins: derive tokens + score_week cap from it.
239
+ budget = budget_for_steps(max_steps)
240
+ profile_key = "custom"
241
  counter: dict[str, int] = {}
242
  model_obj = model if model is not None else _llm.build_agent_model(
243
  hf_token, max_tokens=budget["max_tokens"], temperature=MODEL_TEMPERATURE, timeout=MODEL_TIMEOUT
244
  )
245
  tools = build_tools(counter, score_week_cap=budget["score_week_calls"])
246
+ steps_cap = budget["max_steps"]
247
  if os.environ.get("WR_AGENT", "").strip().lower() == "code":
248
  agent: Any = CodeAgent(tools=tools, model=model_obj, max_steps=steps_cap)
249
  else: