Fix agent switching cache issue#411
Fix agent switching cache issue#411itkonen wants to merge 3 commits intoeditor-code-assistant:masterfrom
Conversation
…ponses API models Agent-Logs-Url: https://github.com/itkonen/eca/sessions/31a220cd-fd4c-41fa-b2bd-e292a2879c08 Co-authored-by: itkonen <37696708+itkonen@users.noreply.github.com>
…tests for prompt_cache_key and agent-switch cache Agent-Logs-Url: https://github.com/itkonen/eca/sessions/a1bf3128-3fa9-4c4c-8086-274b450c3c69 Co-authored-by: itkonen <37696708+itkonen@users.noreply.github.com>
…idate-agent-name doesn't normalize both to fallback Agent-Logs-Url: https://github.com/itkonen/eca/sessions/7e74f85c-65b6-48d5-a71a-782423d348d2 Co-authored-by: itkonen <37696708+itkonen@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Fixes a bug in ECA chat where switching agents mid-conversation (e.g., code → plan) didn’t reliably change the effective system prompt for OpenAI Responses API models due to prompt caching not being scoped to the active agent.
Changes:
- Key chat static system-prompt caching by
agentand rebuild cached instructions when the agent changes. - Propagate
:agentthrough the LLM API pipeline and include it in OpenAIprompt_cache_key. - Add regression tests for agent-based cache invalidation and prompt cache key behavior; update changelog.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/eca/features/chat.clj |
Stores :agent alongside cached static instructions and invalidates cache on agent change. |
src/eca/llm_api.clj |
Threads :agent through prompt calls into provider handlers. |
src/eca/llm_providers/openai.clj |
Appends agent to :prompt_cache_key to separate OpenAI prompt cache per agent. |
test/eca/features/chat_test.clj |
Adds regression test ensuring static prompt cache rebuilds when agent switches. |
test/eca/llm_providers/openai_test.clj |
Adds tests asserting agent suffix behavior in prompt_cache_key. |
CHANGELOG.md |
Documents the fix under Unreleased. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| (let [body* (atom nil)] | ||
| (with-redefs [llm-providers.openai/base-responses-request! | ||
| (fn [{:keys [body on-stream]}] | ||
| (reset! body* body) | ||
| (on-stream "response.completed" | ||
| {:response {:output [] :usage {:input_tokens 1 :output_tokens 1}}}))] | ||
| (llm-providers.openai/create-response! | ||
| (base-provider-params) | ||
| (base-callbacks {})) | ||
| (is (not (string/includes? (:prompt_cache_key @body*) "/")) | ||
| "prompt_cache_key should not contain / when agent is nil"))))) |
There was a problem hiding this comment.
Check if it is even possible for the agent name to contain a slash or be nil. I think there always should be an agent specified (at least "plan" and "code" shipped by ECA). And we need to guarantee that the agent name does not contain a slash. I assume this is already restricted when defining an agent with an markdown file, but the json config could contain a slash. Anyway, I think this rather a marginal concern and should be dealt with a lightweight agent name validator.
|
@ericdallo @itkonen Looks good to me — this makes sense, and it will also help with my WIP One broader thought: should ECA's local static-prompt cache and the provider-side prompt cache share the same invalidation identity, at least conceptually? Rules, skills, and tool availability may affect ECA's static prompt identity (at least when tools influence Selmer rendering). That makes me wonder whether we should eventually compute a fingerprint from the inputs that define the static prompt/request identity and use that consistently for both caches. (Hashing the fully rendered system prompt itself probably wouldn't be great for ECA's local cache, because we'd need to render it first just to know whether we can reuse it — which makes the cache much less useful. So if we go in that direction, hashing normalized inputs would probably be the better approach.) |
Changing the agent when using OpenAI models via the Responses API did not have an affect on the system prompt, so I couldn't switch between planning mode and code mode. This PR fixes the problem by invalidating the prompt cache when the agent is changed. Testing locally the model now sees the agent has changed:
Copilot summary
This pull request fixes a bug where switching agents (such as from "code" to "plan") during a conversation with OpenAI Responses API models did not take effect immediately, due to static system prompt caching not being properly keyed per agent. The cache is now correctly invalidated and rebuilt when the agent changes. Additionally, tests have been added to ensure the cache behaves as expected, and the agent is now included in the prompt cache key for OpenAI requests.
Bug Fix: Agent Switching and Prompt Cache
agentand invalidated when the agent changes, ensuring agent switches (e.g., "code" → "plan") take effect immediately for OpenAI Responses API models (openai/gpt-5.3-codex,github-copilot/gpt-5.3-codex). [1] [2]Code Changes: Agent Propagation
agentparameter is now passed through all relevant chat and LLM API functions, includingprompt!,sync-or-async-prompt!, and provider-specific calls, ensuring correct context and cache behavior. [1] [2] [3] [4] [5] [6] [7] [8] [9]OpenAI Provider: Prompt Cache Key
prompt_cache_keyfor OpenAI requests now includes the agent name as a suffix when present, ensuring cache separation per agent.Testing Improvements
prompt-cache-agent-switch-test) to verify that switching agents invalidates and rebuilds the static prompt cache.prompt_cache_keyincludes the agent suffix when provided and omits it when not. [1] [2]These changes ensure that agent switching works as intended and that caching is correctly scoped, preventing stale prompts from being used when the agent changes.