feat: inject today's date into system prompt and add extended thinking support
Fixes age validation errors caused by the LLM not knowing the current date.
Changes:
- prompts.py: inject date.today() at the top of both system prompts so the
LLM can accurately calculate a child's age from their date of birth
- llm.py: add optional thinking_budget parameter to complete(); when set,
passes thinking={"type": "enabled", "budget_tokens": N} to litellm and
raises max_tokens to thinking_budget + 4096 (Anthropic models only)
- config.py: add thinking_budget field, read from THINKING_BUDGET env var
- .env.example: document the THINKING_BUDGET option
- core.py: pass thinking_budget through to llm.complete()
- main.py: pass thinking_budget when constructing EmailAgent
- chat_app.py: switch from stream_complete to asyncio.to_thread(complete)
so extended thinking works and so only the reply field is shown to
the parent (not the raw JSON wrapper)
To enable extended thinking set THINKING_BUDGET=8000 in .env.
https://claude.ai/code/session_01SUWzMzFvSfWiHXA2p6rPg9
This commit is contained in:
+33
-4
@@ -5,7 +5,12 @@ from collections.abc import Generator
|
||||
import litellm
|
||||
|
||||
|
||||
async def acomplete(model: str, system: str, messages: list) -> str:
|
||||
async def acomplete(
|
||||
model: str,
|
||||
system: str,
|
||||
messages: list,
|
||||
thinking_budget: int | None = None,
|
||||
) -> str:
|
||||
"""Call any LLM asynchronously and return the response text.
|
||||
|
||||
This is the async equivalent of ``complete()`` — use this from async
|
||||
@@ -16,17 +21,30 @@ async def acomplete(model: str, system: str, messages: list) -> str:
|
||||
model: litellm model string, e.g. "anthropic/claude-opus-4-6".
|
||||
system: System prompt text.
|
||||
messages: List of objects with .role and .content attributes.
|
||||
thinking_budget: When set, enables extended thinking (Anthropic models
|
||||
only). See ``complete()`` for details.
|
||||
|
||||
Returns:
|
||||
The model's reply as a plain string.
|
||||
"""
|
||||
api_messages = [{"role": "system", "content": system}]
|
||||
api_messages += [{"role": m.role, "content": m.content} for m in messages]
|
||||
response = await litellm.acompletion(model=model, messages=api_messages, max_tokens=2048)
|
||||
|
||||
kwargs: dict = {"model": model, "messages": api_messages, "max_tokens": 2048}
|
||||
if thinking_budget is not None:
|
||||
kwargs["thinking"] = {"type": "enabled", "budget_tokens": thinking_budget}
|
||||
kwargs["max_tokens"] = thinking_budget + 4096
|
||||
|
||||
response = await litellm.acompletion(**kwargs)
|
||||
return response.choices[0].message.content
|
||||
|
||||
|
||||
def complete(model: str, system: str, messages: list) -> str:
|
||||
def complete(
|
||||
model: str,
|
||||
system: str,
|
||||
messages: list,
|
||||
thinking_budget: int | None = None,
|
||||
) -> str:
|
||||
"""Call any LLM and return the response text.
|
||||
|
||||
Args:
|
||||
@@ -35,13 +53,24 @@ def complete(model: str, system: str, messages: list) -> str:
|
||||
environment variable (ANTHROPIC_API_KEY, OPENAI_API_KEY, …).
|
||||
system: System prompt text.
|
||||
messages: List of objects with .role and .content attributes.
|
||||
thinking_budget: When set, enables extended thinking (Anthropic models
|
||||
only). The value is the token budget for the thinking phase; the
|
||||
final ``max_tokens`` is set to ``thinking_budget + 4096`` so the
|
||||
model has enough room to both think and reply.
|
||||
|
||||
Returns:
|
||||
The model's reply as a plain string.
|
||||
"""
|
||||
api_messages = [{"role": "system", "content": system}]
|
||||
api_messages += [{"role": m.role, "content": m.content} for m in messages]
|
||||
response = litellm.completion(model=model, messages=api_messages, max_tokens=2048)
|
||||
|
||||
kwargs: dict = {"model": model, "messages": api_messages, "max_tokens": 2048}
|
||||
if thinking_budget is not None:
|
||||
kwargs["thinking"] = {"type": "enabled", "budget_tokens": thinking_budget}
|
||||
# max_tokens must exceed budget_tokens or the API returns an error.
|
||||
kwargs["max_tokens"] = thinking_budget + 4096
|
||||
|
||||
response = litellm.completion(**kwargs)
|
||||
return response.choices[0].message.content
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user