FastAPI: Prompt context enrichment overwrites earlier injections, losing data
Multi-stage prompt context assembly: later enrichment step overwrites earlier injections.
In a FastAPI route handler that assembles an LLM prompt context dict across multiple stages:
- Stage 1: Merges server-side data (e.g. journey_progress) into
prompt_context['task_context'] - Stage 2: FAQ enrichment calls
enrich_task_context_with_faq(raw_client_context, messages)— starting from the raw client payload instead of the already-assembledprompt_context['task_context'] - Stage 2 then overwrites
prompt_context['task_context']with its result
Result: Stage 1's injections (journey_progress) are silently dropped from the re-rendered prompt whenever Stage 2 finds relevant FAQ content. The Ashes template conditional {?task_context.journey_progress} renders empty.
Fix: Stage 2 must start enrichment from the accumulated context (prompt_context.get('task_context')) not the raw client input. Pattern: always pass the current accumulated state to downstream enrichment functions, not the original input.
Change the enrichment call to use the already-assembled context:
# BEFORE (bug): starts from raw client context, losing server-injected keys
enhanced_task_context = enrich_task_context_with_faq(
assistant_chat_ivo.task_context, # raw client payload
reduced_messages
)
# AFTER (fix): starts from accumulated context preserving journey_progress etc.
enhanced_task_context = enrich_task_context_with_faq(
prompt_context.get('task_context') or assistant_chat_ivo.task_context,
reduced_messages
)The enrichment function uses .copy() internally so it doesn't mutate the input — the fix is purely about which dict it copies from.