Skip to content

fix(reflection): hand the distiller instructions to the embedded runner as extraSystemPrompt - #1001

Closed
gorkem2020 wants to merge 1 commit into
CortexReach:masterfrom
gorkem2020:fix/reflection-system-prompt-split
Closed

gorkem2020 wants to merge 1 commit into
CortexReach:masterfrom
gorkem2020:fix/reflection-system-prompt-split

Conversation

@gorkem2020

Copy link
Copy Markdown
Contributor

Summary

The reflection distiller builds a system/user prompt pair (buildReflectionPrompt returns { system, user }), but the embedded runner call concatenated both halves into a single prompt. On current hosts the model therefore received the distiller identity and the section rules as user text, while the host's own minimal system prompt stood alone. The completion fallback already kept the split (completeText(system, user)), so the two runner paths disagreed on prompt shape.

This change passes the instructions as extraSystemPrompt and only the transcript as prompt on both runner names (runEmbeddedAgent, legacy runEmbeddedPiAgent). The host appends extraSystemPrompt to its minimal system prompt under a "Subagent Context" header; prompt mode none returns before that block, so the explicit minimal mode stays. The prompt hash still covers both halves, so dedup keys do not move.

Tests

  • test/reflection-runner-embedded-agent.test.mjs: two regression cases (new and legacy runner names) assert that extraSystemPrompt opens with the distiller identity, the user prompt carries the transcript, and neither the identity nor the section rules appear in the user prompt. Both fail on the previous code.
  • Full suite, typecheck and build green; dist rebuilt in the same commit.

Compatibility

No config, schema or manifest change. Hosts that ignore extraSystemPrompt keep the previous behaviour for the system half only; the transcript still arrives as the prompt.

…er as extraSystemPrompt

The reflection distiller already builds a system/user prompt pair, but the
embedded runner received both halves concatenated into one user prompt, so on
current hosts the model saw the distiller identity and the section rules as
user text while the host's own minimal system prompt stood alone. The
completion fallback kept the split.

Pass the instructions as extraSystemPrompt and only the transcript as prompt.
The host appends extraSystemPrompt to its minimal system prompt under a
"Subagent Context" header; prompt mode none would drop it, so the explicit
minimal mode stays. The prompt hash still covers both halves.

Tests: two regression cases on the runner harness (new and legacy runner
names) assert the split; both fail on the previous code.
@gorkem2020

Copy link
Copy Markdown
Contributor Author

Closing after the live check on our fleet: moving the distiller instructions under the host's system prompt does not give the distiller a system prompt of its own, it gives the host's agent persona the last word.

With promptMode: "minimal" the host appends extraSystemPrompt as a "Subagent Context" section after its own identity and bootstrap context, and mode none drops it entirely. In two /reset runs on a current host the model answered as the agent (a conversational follow-up in the agent's voice, no reflection headings), and one run ended with the provider's content_filter finish reason. The previous shape, where the instructions lead the user prompt, keeps producing well-formed reflections.

The completion fallback already receives a real system/user split through the plugin LLM lane, so a true split for the primary path would mean making that lane the primary transport, which is a design change rather than a fix. Leaving this closed; the branch stays on the fork for reference.

@gorkem2020 gorkem2020 closed this Sep 17, 2026
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.

1 participant