Repository navigation
fix: Move Per-Turn Context Out of the System Prompt When an Agent Has No Instructions - #668
Draft
Shabonasar wants to merge 1 commit into
Draft
Shabonasar wants to merge 1 commit into
Shabonasar wants to merge 1 commit into
Conversation
…re no stable instructions With Anthropic or OpenRouter prompt caching, additional_instructions moved next to the newest user message only when stable instructions existed. Without them (no system prompt, RAG chunks or memory in the tail) the per-turn text stayed in the system message, ahead of the history, and every turn missed the cache from the first message. The tail now moves whenever it is set; the system message is omitted when nothing is left in it. Reported-by: jamesleslie-uom
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.
Part of LibreChat-AI/LibreChat#17102
Fixes #667
Summary
With Anthropic or OpenRouter prompt caching,
additional_instructionsmoves next to the newest user message so that per-turn context does not invalidate the cached history. The move was skipped when the agent had no instructions: the per-turn text then became the whole system message, ahead of the history, and every turn missed the cache. Triggered by RAG or memory in a chat with no system prompt (report). This PR moves the tail whenever it is set and omits the system message when nothing is left in it. Result in the run below: from turn 3 on, the history of earlier turns is read from cache instead of 0 tokens.Related to LibreChat-AI/LibreChat#17102. Base:
main, no dependency on other PRs; LibreChat needs no change.How it works
shouldMoveDynamicInstructionsno longer requires stable instructions.buildSystemMessagereturns no system message when there are no stable instructions and the tail was moved. The OpenRouter branch that kept a dynamic-only system message is no longer reachable and is removed.Type of change
Testing
Tested environments/configuration:
LibreChat
dev76c25680c, custom endpoint withprovider: anthropic, Qwen3.8-27B (vLLM behind NVIDIA Dynamo, through LiteLLM), no system prompt, no tools, a text file uploaded for File Search with each of 5 questions (retrieval from a local stand-in for rag_api). Two runs per arm; tokens read from cache / prompt, run 1:system. This PR: from turn 3 each request reads up to the block limit (the model reuses whole 1600-token blocks); turn 2 still misses once, because the turn 1 tail stood before the first question.integration/prompt-cachewithstableContext: true: 62.9-63.0%, 0 misses with and without this PR (there the retrieved context goes into the user message of its turn, not intoadditional_instructions).Automated tests:
AgentContext.test.ts: new "keeps the Anthropic history prefix when only per-turn context changes". Two existing tests are rewritten, since they asserted the old behavior: "omits Anthropic cache control when only dynamic system text exists" is now "sends dynamic-only Anthropic instructions without a system message", and "keeps dynamic-only OpenRouter instructions as system text" is now "moves dynamic-only OpenRouter instructions next to the latest user message". All three fail onmain.anthropic,google,vertexaillm.spec.ts), as onmain.packages/apisrc/agentswith this change: 5884 passed, as without it (suites that need MongoDB or Redis not run).Screenshots / recordings
No user-facing change.
Risk / compatibility
(promptCacheProvider != null || bedrockCache) && dynamicInstructions !== '', and the system message is omitted when stable and conversation instructions are both empty and the tail was moved (this also covers Bedrock).Checklist