Skip to content

fix(agentkit): preserve late runtime prompts - #96

Merged
delete-cloud merged 3 commits into
mainfrom
fix/runtime-message-prompt-loss
May 4, 2026
Merged

delete-cloud merged 3 commits into
mainfrom
fix/runtime-message-prompt-loss

Conversation

@delete-cloud

@delete-cloud delete-cloud commented May 3, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Rebuild prompt context when prompt-affecting runtime messages arrive after build_context but before model streaming.
  • Keep prompt-affecting runtime messages that arrive after run_model for the next turn instead of consuming them during post-model stages.
  • Add regression tests for both same-turn late prompt delivery and next-turn retention.

Verification

  • uv run pytest tests/agentkit/runtime/test_runtime_messages.py tests/agentkit/runtime/test_pipeline.py -q
  • uv run pytest tests/coding_agent/test_approval_runtime_messages.py tests/ui/test_session_manager_approval_runtime.py -q
  • uv run basedpyright src/agentkit/runtime/pipeline.py tests/agentkit/runtime/test_pipeline.py --level error
  • uv run python -m py_compile src/agentkit/runtime/pipeline.py tests/agentkit/runtime/test_pipeline.py
  • GIT_MASTER=1 git diff --check
  • Manual Pipeline QA: late user_steer published after build_context appears in the streamed prompt.

Summary by CodeRabbit

  • New Features

    • Improved detection and handling of prompt changes during agent execution with automatic context rebuilding
    • Enhanced interruption handling at different execution stages for more responsive behavior
  • Tests

    • Expanded test coverage for runtime message consumption and prompt synchronization throughout the execution lifecycle

Rebuild prompt context when runtime messages arrive after build_context but before model streaming, and avoid consuming prompt-affecting messages after run_model until the next turn.
@coderabbitai

coderabbitai Bot commented May 3, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@delete-cloud has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 44 minutes and 26 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ad50378d-5fa7-4553-b059-27e22781da14

📥 Commits

Reviewing files that changed from the base of the PR and between f33a3c2 and 672109f.

📒 Files selected for processing (2)
  • coding-agent/src/agentkit/runtime/pipeline.py
  • coding-agent/tests/agentkit/runtime/test_pipeline.py
📝 Walkthrough

Walkthrough

The pipeline's runtime-message handling is extended to detect prompt-relevant message kinds (USER_STEER, SUBAGENT_MESSAGE, SYSTEM_NOTICE) and trigger context rebuilds. _consume_runtime_messages now returns a boolean indicating prompt-relevant consumption. A new _raise_if_runtime_interrupted method handles interrupts separately. Consumption and conditional context rebuilds are inserted at multiple stages throughout the turn lifecycle.

Changes

Runtime Message Prompt-Change Detection and Context Rebuild Flow

Layer / File(s) Summary
Data Shape & Constants
coding-agent/src/agentkit/runtime/pipeline.py
Introduces _PROMPT_RUNTIME_MESSAGE_KINDS constant identifying which message types trigger context rebuilds (USER_STEER, SUBAGENT_MESSAGE, SYSTEM_NOTICE).
Core Message Consumption Logic
coding-agent/src/agentkit/runtime/pipeline.py
_consume_runtime_messages signature changes to return bool, indicating whether any consumed message is prompt-relevant; still raises on INTERRUPT messages and advances cursor.
Interrupt Handling
coding-agent/src/agentkit/runtime/pipeline.py
New _raise_if_runtime_interrupted method consumes only INTERRUPT messages and raises PipelineError with resolved interruption reason.
Stage-Level Integration
coding-agent/src/agentkit/runtime/pipeline.py
run_turn stage loop calls _raise_if_runtime_interrupted before save_state/render/dispatch; for other stages, uses _consume_runtime_messages boolean return to trigger context rebuild before run_model.
Model Stage Runtime Consumption
coding-agent/src/agentkit/runtime/pipeline.py
_stage_run_model inserts consumption and conditional context-rebuild calls before tool-round iterations and after assembling executable tool calls.
Supporting Refactors
coding-agent/src/agentkit/runtime/pipeline.py
Tool call rejection message construction refactored to multi-line form; ToolExecutionOptions reformatted for readability.
Tests & Validation
coding-agent/tests/agentkit/runtime/test_pipeline.py
Updated existing test assertions to verify context budget and active approvals in prompts. Added three new tests validating message consumption timing: messages during build-context reach current prompt; messages after run\_model or during stream are deferred to next turn. Updated interrupt assertions to multi-line pytest.raises form.

Sequence Diagram

sequenceDiagram
    participant RunTurn as run_turn Stage Loop
    participant Consume as _consume_runtime_messages
    participant RaiseInterrupt as _raise_if_runtime_interrupted
    participant BuildCtx as _stage_build_context
    participant RunModel as _stage_run_model
    participant RuntimeBus as Runtime Bus

    RunTurn->>RaiseInterrupt: (for save_state/render/dispatch)
    RaiseInterrupt->>RuntimeBus: Check for INTERRUPT
    alt INTERRUPT found
        RaiseInterrupt--xRunTurn: Raise PipelineError
    end

    RunTurn->>Consume: (for other stages like run_model)
    Consume->>RuntimeBus: Consume messages
    alt Prompt-relevant message found
        Consume-->>RunTurn: return True
        RunTurn->>BuildCtx: Rebuild context before run_model
        BuildCtx->>RuntimeBus: Consume messages during build
        BuildCtx-->>RunTurn: Context ready
    else No prompt-relevant messages
        Consume-->>RunTurn: return False
    end

    RunTurn->>RunModel: Execute run_model stage
    RunModel->>Consume: (before tool iterations)
    Consume->>RuntimeBus: Consume messages
    alt Prompt-relevant message found
        Consume-->>RunModel: return True
        RunModel->>BuildCtx: Rebuild context
    end

    RunModel->>RuntimeBus: Execute tools
    RunModel->>Consume: (after tool execution)
    Consume->>RuntimeBus: Consume messages
    alt Prompt-relevant message found
        Consume-->>RunModel: return True
        RunModel->>BuildCtx: Rebuild context before next iteration
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • [codex] Add runtime message bus #93: Introduces the runtime message bus and initial pipeline consumption behavior that this PR extends with prompt-change detection and granular interrupt handling via the new _raise_if_runtime_interrupted method and conditional context rebuilds.

Poem

🐰 A rabbit hops through pipelines deep,
Where prompts wake and messages creep,
With builds that bend to steering's call,
And interrupts that heed the hall,
Runtime flows now truly complete!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: preserving prompt context when runtime messages arrive late in the pipeline execution.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/runtime-message-prompt-loss

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 44 minutes and 26 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

Lock in that prompt-affecting runtime messages published during active model streaming stay queued until the next turn instead of being consumed by post-model stages.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@coding-agent/src/agentkit/runtime/pipeline.py`:
- Around line 713-714: The pre-execution consume call currently advances
ctx.runtime_message_cursor and triggers a prompt rebuild unconditionally, which
can lose non-interrupt runtime messages if subsequent tool execution or rebuild
fails; change the condition so _stage_build_context(ctx) is invoked only when
the consumed messages include interrupts—e.g., update the call to await
self._consume_runtime_messages(ctx, stage="run_model", interrupt_only=True) (or
otherwise inspect the returned value to detect interrupt-type messages) and only
call await self._stage_build_context(ctx) when those interrupt messages are
present, leaving non-interrupt messages unconsumed so they can be replayed next
turn.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 82a79dd9-b1db-420d-ad3f-05e5f9be3559

📥 Commits

Reviewing files that changed from the base of the PR and between 4f729fe and f33a3c2.

📒 Files selected for processing (2)
  • coding-agent/src/agentkit/runtime/pipeline.py
  • coding-agent/tests/agentkit/runtime/test_pipeline.py

Leave prompt-affecting runtime messages queued when a tool-call turn has not yet reached the next model invocation, so failed tool execution or rebuild paths can replay them on the next turn.
@delete-cloud
delete-cloud merged commit 38931ac into main May 4, 2026
1 check passed
@delete-cloud
delete-cloud deleted the fix/runtime-message-prompt-loss branch May 4, 2026 02: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.

1 participant