Skip to content

Fix agent switching cache issue#411

Open
itkonen wants to merge 3 commits intoeditor-code-assistant:masterfrom
itkonen:master
Open

Fix agent switching cache issue#411
itkonen wants to merge 3 commits intoeditor-code-assistant:masterfrom
itkonen:master

Conversation

@itkonen
Copy link
Copy Markdown

@itkonen itkonen commented Apr 14, 2026

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:

> Are you in planner mode?

Thought 0s

Not currently—I’m in normal execution mode.

If you want, I can switch to a **planner-style workflow** (create a task list, track steps, and execute in order) for the next task.

**[Agent switched to planner mode]**

> HOw about now?

Thought 2s

Yes — now I’m in **planner mode** for this chat.

I’ll focus on planning only (Understand → Explore → Decide → Present Plan), and I won’t modify files unless you explicitly ask for a preview.

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

  • Static prompt cache in chat is now keyed by agent and 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

  • The agent parameter is now passed through all relevant chat and LLM API functions, including prompt!, 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

  • The prompt_cache_key for OpenAI requests now includes the agent name as a suffix when present, ensuring cache separation per agent.

Testing Improvements

  • Added a test (prompt-cache-agent-switch-test) to verify that switching agents invalidates and rebuilds the static prompt cache.
  • Added a test to ensure prompt_cache_key includes 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.

  • I added a entry in changelog under unreleased section.
  • This is not an AI slop.

Copilot AI and others added 3 commits April 14, 2026 11:47
…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>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a bug in ECA chat where switching agents mid-conversation (e.g., codeplan) 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 agent and rebuild cached instructions when the agent changes.
  • Propagate :agent through the LLM API pipeline and include it in OpenAI prompt_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.

Comment thread src/eca/llm_providers/openai.clj
Comment on lines +457 to +467
(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")))))
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@zikajk
Copy link
Copy Markdown
Member

zikajk commented Apr 16, 2026

@ericdallo @itkonen Looks good to me — this makes sense, and it will also help with my WIP improve-rules branch where I need something similar.

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.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants