Skip to content

Conversation

@Tarquinen
Copy link
Collaborator

Summary

This PR refactors the plugin to use System Message Injection instead of "synthetic user message injection" for communicating pruning instructions to the model.

Key Changes

  • Architecture: Replaced injectSynth and injectPrunableList in FormatDescriptor with a single injectSystemMessage method.
  • Cleanup: Deleted synthetic.txt and system-reminder.txt as they are no longer needed.
  • Prompts: Updated tool.txt (Prune tool definition) to explicitly enforce the "Distill before Pruning" workflow using strict instructions.
  • Providers: Implemented native system message injection for:
    • OpenAI: Inserts/Appends to system role.
    • Bedrock: Appends to system array.
    • Gemini: Appends to systemInstruction.parts.

Motivation

The previous approach of hiding instructions inside user messages (synthetic injection) was brittle and complex to maintain. Moving these instructions to the System Prompt is cleaner, more robust, and leverages the model's native understanding of system-level constraints.

Impact

  • Simplifies handler.ts logic significantly.
  • Improves adherence to pruning workflows by placing instructions in the authoritative system context.
  • Reduces risk of leaking synthetic instructions into user-visible logs (since they are now handled at the protocol level).

Status: Experimental. Needs testing to ensure models respect dynamic system prompt updates.

- Remove brittle 'synthetic injection' logic that modified user messages.
- Introduce 'injectSystemMessage' to FormatDescriptor interface.
- Implement system message injection for OpenAI, Bedrock, and Gemini.
- Update 'prune' tool prompt to focus on distillation workflow.
- Remove obsolete prompt files (synthetic.txt, system-reminder.txt).
- Simplify handler.ts to treat prunable lists as system instructions.
- Implement dedicated 'anthropic' format adapter in lib/fetch-wrapper/formats/anthropic.ts.
- Handle top-level 'system' field injection (supports string and array).
- Handle 'tool_result' content blocks in user messages.
- Update fetch wrapper detection order to prioritize Anthropic over OpenAI-compatible.
- Fixes incompatibility where OpenAI adapter would inject invalid 'system' role messages into Anthropic requests.
- Apply code formatting standards.
- Add documentation files (ANTHROPIC_IMPLEMENTATION.md, IMPLEMENTATION_SUMMARY.md).
- Include test-anthropic-format.js for verification.
Removed temporary documentation files ANTHROPIC_IMPLEMENTATION.md and IMPLEMENTATION_SUMMARY.md as requested.
Changed 'SYSTEM ROLE' to 'SYSTEM PROMPT' in tool.txt to be provider-agnostic, as not all providers use the term 'role' for system instructions.
- Add baseline synthetic.txt with context management protocol always present
- Enhance nudge.txt with urgent, actionable context warnings
- Update tool.txt with three distinct pruning scenarios (Task Completion, Noise Removal, Context Conservation)
- Refactor prunable-list.ts to always inject synthetic instruction, optionally add nudge
- Clarify when distillation is required vs forbidden for each scenario
- Split context management injection: core protocol remains in system message, but dynamic tool list moves to user message for better adherence
- Add injectUserMessage support to all provider formats
- Update synthetic prompt with system-reminder to prevent model from referencing invisible injected content
- Centralize formatting logic in display-utils.ts to share between tool output and notifications
- Update pruning tool to return a detailed, human-readable summary of actions taken
- Simplify notification logic by reusing shared formatting functions
…ions

Allows LLM to specify why it's pruning (completion, noise, consolidation)
as the first element of the ids array. Reason is displayed in UI
notifications but hidden from tool output to avoid redundancy.
… new user message

This change addresses models consistently responding to the injected prunable
list even when instructed not to. By appending to the last assistant message
instead of creating a new user message, the list appears as part of the model's
own context state awareness rather than user input to respond to.

- Rename injectUserMessage -> appendToLastAssistantMessage across all formats
- Each format handler now finds and appends to the last assistant/model message
- Update synthetic.txt prompt to reflect the new assistant message framing
- Rename buildUserInjection -> buildAssistantInjection
- Streamline synthetic.txt system-reminder to single sentence
- Rename 'CONTEXT CONSERVATION' to 'CONTEXT CONSOLIDATION' for clarity
- Update tool.txt to reference assistant messages (matching new injection method)
- Set nudge_freq default to 0 (disabled)
@Tarquinen Tarquinen merged commit 8894796 into master Dec 9, 2025
1 check passed
@jorgenwh jorgenwh deleted the refactor/system-message-injection branch December 13, 2025 19:18
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.

2 participants