Skip to content

feat(guidance): in-flight user guidance injection - #215

Merged
bouillipx merged 2 commits into
mainfrom
feat/issue-201-guidance-injection
Mar 11, 2026
Merged

bouillipx merged 2 commits into
mainfrom
feat/issue-201-guidance-injection

Conversation

@bouillipx

Copy link
Copy Markdown
Collaborator

Summary

  • Adds a lightweight guidance injection pipeline for issue feat(runtime): support in-flight user guidance injection into next context assemble #201
  • Users can inject corrective "guidance" messages during agent execution via /guide <text> or headless guide:inject action
  • Guidance is consumed at the next Context.assemble() cycle (not immediately), ensuring "next assemble" semantics
  • 21 unit tests covering GuidanceQueue, GuidanceActionHandler, and context injection

Changes

  • New: dare_framework/guidance/ — GuidanceQueue (thread-safe FIFO with consume-on-drain) + GuidanceActionHandler (guide:inject/list/clear)
  • Modified: Context.assemble() drains guidance queue into STM at the top of each call
  • Modified: builder.py creates GuidanceQueue, passes to Context, registers handler
  • Modified: client/main.py — adds guide actions to headless control-stdin whitelist
  • Modified: Examples 05/06 — /guide CLI command
  • Modified: test_client_cli_flow.py — updated actions:list expected result

Data Flow

/guide <text> → ACTION(guide:inject) → GuidanceActionHandler → GuidanceQueue
→ [next] Context.assemble() → _drain_guidance() → stm_add(role=USER, source=user_guidance) → LLM

Test plan

  • test_guidance_queue.py — 8 tests: enqueue/drain/peek/clear/empty/reject/max_size/timestamp
  • test_guidance_action_handler.py — 6 tests: supports/inject/missing-content/list/clear/lifecycle
  • test_guidance_context_injection.py — 7 tests: inject-at-assemble/consumed-once/no-guidance-unchanged/multiple-order/role-metadata/after-existing
  • Full suite: 769 passed, 2 pre-existing failures unrelated to this PR

Closes #201

🤖 Generated with Claude Code

Add a lightweight guidance injection pipeline that allows users to
inject corrective messages during agent execution. Guidance is picked
up at the next context assembly cycle without interrupting streaming.

Pipeline: client → ACTION envelope → GuidanceActionHandler →
GuidanceQueue → Context.assemble() → STM → LLM

New components:
- GuidanceQueue: thread-safe FIFO with consume-on-drain semantics
- GuidanceActionHandler: guide:inject/list/clear actions
- Context._drain_guidance(): drains queue into STM at assemble time

Also: /guide CLI command in examples 05/06, headless control-stdin
whitelist, 21 unit tests covering queue, handler, and context injection.

Closes #201

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c570579824

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread dare_framework/context/context.py
Address review feedback: guidance messages were drained only in
assemble(), which runs after compress() in assemble_for_model().
This meant guidance payloads bypassed token-budget pruning and could
push the final prompt over the context window.

Now _drain_guidance() is called in assemble_for_model() before
compress(), so guidance participates in MovingCompressor pruning.
The drain in assemble() is kept for direct callers (plan loop,
execute loop) — it is idempotent on an empty queue.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@bouillipx

Copy link
Copy Markdown
Collaborator Author

Re: P1 — Drain guidance before model-side compression

Good catch. Fixed in 1e32bbe: _drain_guidance() is now called in assemble_for_model() before compress(), so guidance messages participate in MovingCompressor pruning and respect the token budget. The drain in assemble() is kept for direct callers (plan loop, execute loop) — it is idempotent on an empty queue.

@bouillipx
bouillipx merged commit d78b0a5 into main Mar 11, 2026
3 of 11 checks passed
@bouillipx
bouillipx deleted the feat/issue-201-guidance-injection branch March 11, 2026 02:54

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1e32bbe28c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +247 to 249
self._drain_guidance()
await self.compress(**options)
return self.assemble()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Drain guidance exactly once before model compression

assemble_for_model() drains pending guidance before await self.compress(...) but then calls self.assemble(), which drains again. In the in-flight injection scenario this feature targets, guidance enqueued while compression is awaiting (e.g., during moving-compressor summarization) is consumed by the second drain and appended after pruning, so it can bypass the context-window budget and violate the documented “next assemble cycle” boundary. Build the assembled context directly after compression (without re-entering assemble()) so late guidance is deferred to the next cycle.

Useful? React with 👍 / 👎.

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.

feat(runtime): support in-flight user guidance injection into next context assemble

1 participant