Spaces:
Running
Running
Refactor caching logic to improve cacheability determination based on conversation context; ensure session turns are persisted even on cache hits.
Browse files
routes/agents/agents_orchestration.py
CHANGED
|
@@ -462,7 +462,13 @@ async def _run_pipeline(
|
|
| 462 |
if route == RouteType.SQL_QUERY and token_user_id:
|
| 463 |
access_scope = await run_in_threadpool(get_user_source_access, token_user_id) or ""
|
| 464 |
cache_key = _cache_key(route, token_user_id, payload, access_scope)
|
| 465 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 466 |
if cacheable:
|
| 467 |
try:
|
| 468 |
cached = await get_redis_client().get(cache_key)
|
|
@@ -652,12 +658,15 @@ async def multi_agent_chat(
|
|
| 652 |
result = await _run_pipeline(payload, token_user_id, trace_id, start)
|
| 653 |
await _write_cache(result)
|
| 654 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 655 |
if not result.from_cache:
|
| 656 |
-
if result.session_id and result.response.answer:
|
| 657 |
-
background_tasks.add_task(
|
| 658 |
-
_persist_session_turn, token_user_id, result.session_id,
|
| 659 |
-
payload.query, result.response.answer,
|
| 660 |
-
)
|
| 661 |
background_tasks.add_task(
|
| 662 |
log_chat_event, **_chat_log_kwargs(result, payload, token_user_id, trace_id)
|
| 663 |
)
|
|
@@ -702,11 +711,13 @@ async def multi_agent_chat_stream(
|
|
| 702 |
# The client gets the result first; bookkeeping below is best-effort.
|
| 703 |
await queue.put(("result", json.loads(result.response.model_dump_json())))
|
| 704 |
await _write_cache(result)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 705 |
if not result.from_cache:
|
| 706 |
-
if result.session_id and result.response.answer:
|
| 707 |
-
await _persist_session_turn(
|
| 708 |
-
token_user_id, result.session_id, payload.query, result.response.answer
|
| 709 |
-
)
|
| 710 |
await log_chat_event(**_chat_log_kwargs(result, payload, token_user_id, trace_id))
|
| 711 |
except HTTPException as exc: # already logged inside the pipeline
|
| 712 |
await queue.put(("error", {"status_code": exc.status_code, "detail": exc.detail, "trace_id": trace_id}))
|
|
|
|
| 462 |
if route == RouteType.SQL_QUERY and token_user_id:
|
| 463 |
access_scope = await run_in_threadpool(get_user_source_access, token_user_id) or ""
|
| 464 |
cache_key = _cache_key(route, token_user_id, payload, access_scope)
|
| 465 |
+
# Cacheability depends on conversation *context*, not on session identity.
|
| 466 |
+
# `history` is already resolved above (client-provided, or the Redis session
|
| 467 |
+
# fallback for a session_id with empty client history), so any turn with real
|
| 468 |
+
# prior context is non-empty here and stays uncacheable; a contextless first
|
| 469 |
+
# turn — even one carrying a session_id — is cacheable. The cache key does not
|
| 470 |
+
# include history, which is exactly why we only cache when it's empty.
|
| 471 |
+
cacheable = route not in _UNCACHEABLE_ROUTES and not history
|
| 472 |
if cacheable:
|
| 473 |
try:
|
| 474 |
cached = await get_redis_client().get(cache_key)
|
|
|
|
| 658 |
result = await _run_pipeline(payload, token_user_id, trace_id, start)
|
| 659 |
await _write_cache(result)
|
| 660 |
|
| 661 |
+
# Persist the session turn even on a cache hit — a cacheable first turn may now
|
| 662 |
+
# carry a session_id, and skipping this would leave it out of the Redis session
|
| 663 |
+
# store. Logging stays gated on a fresh (non-cached) answer.
|
| 664 |
+
if result.session_id and result.response.answer:
|
| 665 |
+
background_tasks.add_task(
|
| 666 |
+
_persist_session_turn, token_user_id, result.session_id,
|
| 667 |
+
payload.query, result.response.answer,
|
| 668 |
+
)
|
| 669 |
if not result.from_cache:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 670 |
background_tasks.add_task(
|
| 671 |
log_chat_event, **_chat_log_kwargs(result, payload, token_user_id, trace_id)
|
| 672 |
)
|
|
|
|
| 711 |
# The client gets the result first; bookkeeping below is best-effort.
|
| 712 |
await queue.put(("result", json.loads(result.response.model_dump_json())))
|
| 713 |
await _write_cache(result)
|
| 714 |
+
# Persist the session turn even on a cache hit (see JSON endpoint);
|
| 715 |
+
# logging stays gated on a fresh answer.
|
| 716 |
+
if result.session_id and result.response.answer:
|
| 717 |
+
await _persist_session_turn(
|
| 718 |
+
token_user_id, result.session_id, payload.query, result.response.answer
|
| 719 |
+
)
|
| 720 |
if not result.from_cache:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 721 |
await log_chat_event(**_chat_log_kwargs(result, payload, token_user_id, trace_id))
|
| 722 |
except HTTPException as exc: # already logged inside the pipeline
|
| 723 |
await queue.put(("error", {"status_code": exc.status_code, "detail": exc.detail, "trace_id": trace_id}))
|