Agent: resolve "today" in the browser's timezone, not hardcoded CR

The CR-hardcoded today broke two scenarios: the owner traveling, and
any future non-CR user. Now the provider sends the browser's IANA
timezone (X-Client-Timezone) with every CopilotKit request — the
runtime forwards x-* headers to the agent on its own — and the backend
binds it to a per-request ContextVar next to the DB session.
get_current_date and the future-cuota bounds use it; the tool also
reports the timezone so the model can echo it. Unknown or absent zones
(n8n posts, tests) fall back to Costa Rica; comma-joined duplicate
header values are tolerated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Carlos Escalante
2026-07-04 19:33:27 -06:00
parent 8f51e33fe0
commit 7b7c741ba2
6 changed files with 96 additions and 18 deletions

View File

@@ -23,6 +23,7 @@ from app.auth import (
from app.config import settings
from app.db import get_session, run_alembic_upgrade
from app.seed import seed_db
from app.timeutil import reset_client_timezone, set_client_timezone
from app.services.exchange_rate import refresh_rates_periodically
@@ -136,9 +137,13 @@ async def agent_auth_and_session(request: Request, call_next):
session_gen = get_session()
session = next(session_gen)
token_var = set_session(session)
# Browser's IANA timezone, forwarded by the BFF — lets tools resolve
# "today" wherever the user is (falls back to Costa Rica).
tz_token = set_client_timezone(request.headers.get("x-client-timezone"))
try:
return await call_next(request)
finally:
reset_client_timezone(tz_token)
reset_session(token_var)
try:
next(session_gen)