Skip to content

fix(run-events): emit canonical past-tense run event types and tool result content - #4495

Merged
kojiwakayama merged 4 commits into
mainfrom
fix/canonical-run-event-type-names
Sep 14, 2026
Merged

kojiwakayama merged 4 commits into
mainfrom
fix/canonical-run-event-type-names

Conversation

@kojiwakayama

@kojiwakayama kojiwakayama commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Summary

The runtime now emits the canonical past-tense run event type names, and tool results carry the canonical content field.

Run event type names

Every control plane event type this runtime writes uses its past-tense name:

Before After
AGENT_RUN_MODEL_CALL_CONTEXT AGENT_RUN_MODEL_CALL_CONTEXT_RECORDED
AGENT_RUN_TOOL_EXPOSURE_CHECKPOINT AGENT_RUN_TOOL_EXPOSURE_CHECKPOINTED
AGENT_RUN_PROVIDER_REPLAY_CHECKPOINT AGENT_RUN_PROVIDER_REPLAY_CHECKPOINTED
AGENT_RUN_PROVIDER_REPLAY_TURN_COMPLETE AGENT_RUN_PROVIDER_REPLAY_TURN_FINISHED

Emission sites:

  • hosted executor model dispatch (src/agent/hosted/executor-model-dispatch.ts)
  • direct model calls (src/runtime/runtime-bridge.ts)
  • the provider replay turn boundary in the internal runtime stream (src/internal-agents/run-stream.ts)
  • the tool exposure and provider replay checkpoint constants (src/agent/runtime/tool-exposure.ts, src/agent/runtime/provider-replay.ts), which every checkpoint append uses

veryfront/run-events (src/run-events/vocabulary.ts) lists all eight renamed control plane types under their past-tense names and wire names. The catalog digests in its test are recomputed.

Read compatibility:

  • The private-event boundary still recognizes the pre-rename spelling of the model call context and provider replay checkpoint.
  • An event from an older producer is therefore never classified as public.
  • Normalization rewrites it to the canonical name, so only past-tense names are appended.

The private SSE frame names (AgentRunModelCallContext, AgentRunProviderReplayTurnComplete) are intentionally unchanged: the receiving API matches them exactly.

Tool result content

AG-UI ToolCallResult frames now send content instead of result, from the stream encoder and the lifecycle adapter:

  • The value is passed through unchanged, which matches how a legacy result is stored.
  • The internal SSE payload allow-list now declares content. Before, an undeclared content was dropped silently.
  • parseAgUiSseResponse serializes content the same way it serialized result, so its output is unchanged.
  • The chat decoder already read content first.

Test plan

  • Tests that pin the emitted type names and the content field were changed first and failed, then passed after the implementation.
  • New read-compat tests cover the pre-rename private spellings.
  • deno task test:file over the agent, conversation, hosted, internal-agents, run-events, runtime and chat areas.
  • deno task typecheck, deno lint and deno fmt --check on the changed files, deno task docs:api-reference:check, deno task lint:style, deno task lint:anti-slop.

https://claude.ai/code/session_01CqY82FYm9aUkyawWmh4T9n

Summary by CodeRabbit

  • Changes
    • Renamed several run-event and checkpoint identifiers to clearer past-tense names, including model-call context, tool exposure, provider replay, retry, and billing events.
    • Updated provider replay completion naming to “turn finished.”
    • Tool-call results now use content as the canonical payload field.
    • Existing payloads using the legacy result field remain readable for compatibility.
    • Legacy event names continue to be accepted and normalized during reads.

…esult content

The runtime now writes the past-tense name for every control plane run event
type it produces:

- AGENT_RUN_MODEL_CALL_CONTEXT -> AGENT_RUN_MODEL_CALL_CONTEXT_RECORDED
- AGENT_RUN_TOOL_EXPOSURE_CHECKPOINT -> AGENT_RUN_TOOL_EXPOSURE_CHECKPOINTED
- AGENT_RUN_PROVIDER_REPLAY_CHECKPOINT -> AGENT_RUN_PROVIDER_REPLAY_CHECKPOINTED
- AGENT_RUN_PROVIDER_REPLAY_TURN_COMPLETE -> AGENT_RUN_PROVIDER_REPLAY_TURN_FINISHED

The `veryfront/run-events` vocabulary lists all eight renamed types under their
past-tense names and wire names, and its catalog digests are recomputed.

The private-event boundary still recognizes the pre-rename spellings of the
model call context and provider replay checkpoint, so an event from an older
producer is never treated as public, and normalization rewrites it to the
canonical name. The private SSE frame names are unchanged because the API
matches them exactly.

AG-UI `ToolCallResult` frames now carry the canonical `content` field instead
of `result`. The value is passed through unchanged. The internal SSE payload
allow-list declares `content`, so it is no longer dropped, and the SSE parser
serializes `content` the same way it serialized `result`.

Claude-Session: https://claude.ai/code/session_01CqY82FYm9aUkyawWmh4T9n
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

Warning

Review limit reached

Next included review available in 32 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: b2d96c56-cdf6-4236-8359-1f8633d240e4

📥 Commits

Reviewing files that changed from the base of the PR and between ea82597 and a769a31.

📒 Files selected for processing (4)
  • src/chat/ag-ui.test.ts
  • src/chat/ag-ui.ts
  • src/eval/agent-service.test.ts
  • src/eval/agent-service.ts

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 89d1d807-8aef-443e-82a7-2a01bca0d3a8

📥 Commits

Reviewing files that changed from the base of the PR and between f105ec1 and ea82597.

📒 Files selected for processing (39)
  • docs/architecture/28-model-driven-tool-discovery.md
  • src/agent/ag-ui/chunk-encoder.test.ts
  • src/agent/ag-ui/encoder.test.ts
  • src/agent/ag-ui/encoder.ts
  • src/agent/ag-ui/lifecycle-adapter.test.ts
  • src/agent/ag-ui/lifecycle-adapter.ts
  • src/agent/ag-ui/runtime-event-encoder.test.ts
  • src/agent/ag-ui/sse-parser.test.ts
  • src/agent/ag-ui/sse-parser.ts
  • src/agent/conversation/durable.test.ts
  • src/agent/conversation/legacy-run-read-adapter.test.ts
  • src/agent/conversation/private-run-event.test.ts
  • src/agent/conversation/private-run-event.ts
  • src/agent/conversation/run-chunk-mirror.test.ts
  • src/agent/conversation/run-event-normalization.test.ts
  • src/agent/conversation/run-event-normalization.ts
  • src/agent/hosted/chat-execution-runtime.test.ts
  • src/agent/hosted/chat-preparation.test.ts
  • src/agent/hosted/chat-request.test.ts
  • src/agent/hosted/child-fork-execution-runner.test.ts
  • src/agent/hosted/durable-run-event-sink.test.ts
  • src/agent/hosted/executor-model-dispatch.test.ts
  • src/agent/hosted/executor-model-dispatch.ts
  • src/agent/hosted/executor-persistence-bridge.test.ts
  • src/agent/runtime/provider-replay.ts
  • src/agent/runtime/provider-transport.test.ts
  • src/agent/runtime/tool-exposure.ts
  • src/internal-agents/ag-ui-sse.test.ts
  • src/internal-agents/ag-ui-sse.ts
  • src/internal-agents/provider-replay-checkpoint-persister.test.ts
  • src/internal-agents/run-stream.test.ts
  • src/internal-agents/run-stream.ts
  • src/run-events/vocabulary.test.ts
  • src/run-events/vocabulary.ts
  • src/runtime/model-call-context.test.ts
  • src/runtime/model-call-context.ts
  • src/runtime/runtime-bridge.test.ts
  • src/runtime/runtime-bridge.ts
  • tests/integration/agent/managed-broker-persistence.test.ts

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

Changes

Event vocabulary and compatibility

Layer / File(s) Summary
Canonical event contracts and producers
src/run-events/vocabulary.ts, src/runtime/*, src/agent/runtime/*, src/agent/hosted/*, src/internal-agents/run-stream.ts, docs/architecture/*
Eight control-plane event names and related wire names now use past-tense forms. Producers emit the canonical names.
Private-event normalization and legacy reads
src/agent/conversation/private-run-event.ts, src/agent/conversation/run-event-normalization.ts, src/agent/conversation/*test.ts
Legacy model-context and replay-checkpoint names remain recognized and are normalized to canonical names before validation.
AG-UI tool-result payloads
src/agent/ag-ui/*, src/internal-agents/ag-ui-sse.ts, src/agent/conversation/legacy-run-read-adapter.test.ts
Tool-result payloads now use content. SSE parsing gives content precedence and retains fallback support for result.
Regression coverage
src/agent/hosted/*test.ts, src/runtime/*test.ts, src/run-events/vocabulary.test.ts, tests/integration/*
Tests and catalog digests were updated for the renamed event types and payload field.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to ea825

The event and tool-result migrations include compatible reads for the documented legacy paths and targeted coverage for canonical payload handling. No merge-blocking issue is established.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 20 functions across 38 files. (1 skipped:… 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 and concisely describes the two main changes: canonical past-tense run event types and AG-UI tool result content.
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.
Full details: Docstring Coverage

Explanation

Docstring coverage is 45.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 20 functions across 38 files. (1 skipped: 1 unsupported.)

✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/canonical-run-event-type-names

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

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

@github-actions

Copy link
Copy Markdown

📦 Client bundle boundary

Entrypoint Modules Source size Server leaks
src/index.client.ts 289 2307 KiB ✅ 0

A server module in a client graph aborts hydration in the browser. New leaks fail CI; known leaks are tracked in scripts/lint/client-bundle-baseline.json to burn down.

@gitar-bot

gitar-bot Bot commented Sep 14, 2026

Copy link
Copy Markdown

Gitar is working

Gitar

Copy link
Copy Markdown
Contributor

Review: 90/100 — clean, thorough past-tense rename with well-scoped backward compatibility

Summary: A mechanical control-plane event rename done carefully, with read-compat added exactly where this codebase actually replays its own persisted private events, and no stray references left behind.

Strengths

  • The rename is applied consistently across emission sites, docs, tests, and the run-events vocabulary catalog, with the catalog's SHA-256 digests recomputed and dated. A repo-wide search turns up no leftover references to the old type-name string literals outside test fixtures and the intentional LEGACY_* constants.
  • Read compatibility is scoped deliberately, not blanket-applied: getCanonicalPrivateConversationRunEventType accepts either spelling only for AGENT_RUN_MODEL_CALL_CONTEXT/AGENT_RUN_PROVIDER_REPLAY_CHECKPOINT, the two private types this repo itself reads back via private-run-event.ts/run-event-normalization.ts. New tests directly cover that a pre-rename event is still classified private and gets rewritten to the canonical name on normalization.
  • The private SSE frame names (AgentRunModelCallContext, AgentRunProviderReplayTurnComplete) are correctly left unchanged, with a comment explaining that renaming them needs API-side coordination first — good judgment not to over-rename.
  • The resultcontent tool-result migration is handled on both ends of the wire: sse-parser.ts now accepts either key from a producer, and parseAgUiSseResponse/allow-list changes are covered by new tests pinning the exact wire format.

Minor concerns (non-blocking)

  • AGENT_RUN_TOOL_EXPOSURE_CHECKPOINT doesn't get the same legacy-spelling fallback as the other two private types. That appears intentional and safe — restoreToolExposureState takes its checkpoint from server-supplied config (initialToolExposureCheckpoint) rather than replaying a stored event by type — but a one-line comment analogous to the other two would save a future reader from having to trace that through agent-runtime-step.ts to confirm it's not an oversight.
  • The ToolCallResult payload allow-list schema now makes both content and result optional (previously result was required), which slightly loosens validation — a payload carrying neither field would now pass where it previously wouldn't. Likely fine given the emission sites always set content, but worth a sentence confirming that's intended rollout behavior rather than incidental.
  • isPrivateConversationRunEvent calls getCanonicalPrivateConversationRunEventType twice (once via hasPrivateConversationRunEventType, once directly) — trivial, not worth a standalone fix.

CI was still running several jobs (coverage shards, lint, integration tests) at review time but everything completed so far (typecheck, format, most test suites) was green.


Generated by Claude Code

@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: 02ba7c48ee

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/agent/ag-ui/sse-parser.ts Outdated
@codecov

codecov Bot commented Sep 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.90909% with 7 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/agent/ag-ui/lifecycle-adapter.ts 25.00% 3 Missing ⚠️
src/eval/agent-service.ts 57.14% 2 Missing and 1 partial ⚠️
src/agent/runtime/provider-replay.ts 87.50% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@kojiwakayama

Copy link
Copy Markdown
Contributor Author

@codex review

A ToolCallResult frame whose canonical content is null was left as raw
null by the SSE parser, and a frame carrying both a null content and a
legacy result substituted the legacy value. The parser now uses content
whenever the key is present and falls back to result only when it is
absent, so a null result still serializes to "null".

Claude-Session: https://claude.ai/code/session_01CqY82FYm9aUkyawWmh4T9n
@kojiwakayama

Copy link
Copy Markdown
Contributor Author

@codex review

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@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: ea825974fa

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/agent/ag-ui/encoder.ts
A tool that returns null now reaches the chat decoder as content: null.
The decoder read content ?? result, so a null output with no legacy
result became undefined and the tool-output-available event lost the
value. The decoder now uses content whenever the key is present and
falls back to result only when it is absent.

Claude-Session: https://claude.ai/code/session_01CqY82FYm9aUkyawWmh4T9n
@kojiwakayama

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@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: 50ca022307

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/agent/ag-ui/sse-parser.ts
The eval adapter read a ToolCallResult's legacy result before its
content. A frame carrying only content now reached getToolResultError as
a serialized JSON string, so a tool error recorded the raw JSON instead
of its message, and a frame carrying both fields recorded the stale
legacy output. Both extractors now select content whenever it is
present and fall back to result and output only without it.

Claude-Session: https://claude.ai/code/session_01CqY82FYm9aUkyawWmh4T9n
@kojiwakayama

Copy link
Copy Markdown
Contributor Author

@codex review

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: a769a31293

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@sonarqubecloud

Copy link
Copy Markdown

@kojiwakayama
kojiwakayama added this pull request to the merge queue Sep 14, 2026
Merged via the queue into main with commit c635f2b Sep 14, 2026
96 of 100 checks passed
@kojiwakayama
kojiwakayama deleted the fix/canonical-run-event-type-names branch September 14, 2026 08:06
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