fix: Keep Dynamic Tool Context After Additional Instructions for Prefix Caching - #16369
Open
Shabonasar wants to merge 1 commit into
Open
Shabonasar wants to merge 1 commit into
Shabonasar wants to merge 1 commit into
Conversation
The per-request web search context (current date/time with milliseconds) was joined before additional_instructions, which carry mostly static text such as the artifacts prompt. Provider-side prefix caches stopped at the timestamp, so the static text after it was recomputed on every request. Move the dynamic context to the end via buildAdditionalInstructions and cover the ordering with unit tests.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request
Summary
The per-request web search context (
Conversation Date & Time: <ISO timestamp with milliseconds>) is joined beforeagent.additional_instructionswhen the run builds the system prompt.additional_instructionscarry mostly static text, most notably the artifacts prompt (~11k characters). Because the timestamp changes on every request, provider-side prefix caching stops at the timestamp and everything after it is recomputed each time. This affects self-hosted models with automatic prefix caching (e.g. vLLM, SGLang) and any provider that caches by prompt prefix; it is triggered whenever web search is enabled together with anything that lands inadditional_instructions(artifacts, memory guard, instructions with temporal variables).This PR moves the dynamic tool context to the end, so the static part stays a stable prefix across requests. The date/time is still present in the prompt, only its position changes.
How it works
buildAdditionalInstructionsis a small exported helper inrun.tsthat puts static instructions first and the per-request context last, so the ordering can be unit-tested.Type of change
Testing
Captured the chat completion requests sent to an OpenAI-compatible endpoint for two consecutive new conversations (artifacts and web search enabled) and compared the system prompts character by character. Before the change they diverged at the timestamp, about 3k characters into the system message; after the change they are identical up to the timestamp, which is now the last line.
Measured on a locally hosted model served by vLLM with automatic prefix caching, ~8.6k prompt tokens per request: cached prompt tokens went from 3,168 to 6,336 per request (35% to 74%). The remainder is the user message, the timestamp and cache block rounding.
Tested environments/configuration:
Automated tests:
buildAdditionalInstructionstests inpackages/api/src/agents/run.spec.tsScreenshots / recordings
No user-facing change
Risk / compatibility
Only the order of text inside the system prompt changes; no content is added or removed.
Checklist