Skip to content

feat(overlay): project agent stages onto overlay messages (Issue #8790) - #8797

Merged
PolinaGurinovich97 merged 2 commits into
developmentfrom
feat/overlay-stages
Sep 15, 2026
Merged

PolinaGurinovich97 merged 2 commits into
developmentfrom
feat/overlay-stages

Conversation

@PolinaGurinovich97

Copy link
Copy Markdown
Collaborator

The overlay protocol dropped custom_content when it replaced the chat's internal message entity with a narrow projection, which took the agent's execution stages with it. A host that reacted to tool calls — refreshing its own view once a particular tool had run — lost its only signal and was left with GPT_END_GENERATING plus an unconditional refresh.

OverlayChatMessage now carries an optional stages array. The protocol keeps its own OverlayMessageStage/OverlayStageStatus types rather than re- exporting Stage from chat-shared, and toOverlayMessages translates between them explicitly, so an unrecognised status degrades to "still running" instead of crossing the boundary untranslated. Stage attachments are not projected: they carry host-resolvable URLs the protocol has no counterpart for.

Stages stay a read, not a push — a host subscribes to GPT_END_GENERATING and calls getMessages(). A per-stage streaming event is the follow-up slice in Issue #8790.

Description of changes

Applicable issues

  • fixes #<ISSUE_ID>

UI changes

<Please, provide Screenshots or Figma links>

Checklist

  • the pull request name ends with (Issue #<ISSUE_ID>) (comma-separated list of issues)
  • I confirm that I don't share any confidential information like API keys or any other secrets and private URLs
PR title cheatsheet

<type>[optional scope]: <description>

  1. type (required)
    • feat - A new feature
    • fix - A bug fix
    • docs - Documentation only changes
    • test - Adding missing tests or correcting existing tests
    • ci - Changes to our CI configuration files and scripts
    • chore - Other changes that are minor and/or not user-facing
  2. scope (optional, current repo suggestions below)
    • chat
    • overlay
    • shared
    • sandbox-overlay
    • visualizer-connector

The overlay protocol dropped `custom_content` when it replaced the chat's
internal message entity with a narrow projection, which took the agent's
execution stages with it. A host that reacted to tool calls — refreshing its
own view once a particular tool had run — lost its only signal and was left
with GPT_END_GENERATING plus an unconditional refresh.

`OverlayChatMessage` now carries an optional `stages` array. The protocol keeps
its own `OverlayMessageStage`/`OverlayStageStatus` types rather than re-
exporting `Stage` from chat-shared, and `toOverlayMessages` translates between
them explicitly, so an unrecognised status degrades to "still running" instead
of crossing the boundary untranslated. Stage attachments are not projected:
they carry host-resolvable URLs the protocol has no counterpart for.

Stages stay a read, not a push — a host subscribes to GPT_END_GENERATING and
calls getMessages(). A per-stage streaming event is the follow-up slice in
Issue #8790.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@PolinaGurinovich97
PolinaGurinovich97 marked this pull request as ready for review September 14, 2026 18:49
@github-actions

Copy link
Copy Markdown

security-review: No security issues found. Stage data flows through postMessage JSON serialization only; no new innerHTML, eval, or injection surfaces introduced.

Run details


`stages` is the one part of `custom_content` the protocol projects: a message
that carries agent execution stages exposes them as `OverlayMessageStage[]`,
with `index`, `name`, `status` (`null` while running, otherwise

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

code-review · fyi

FYI: the migration-guide wording that stage projection syncs with the chat's own stages. In the chat, stage content/name are delta-merged across chunks and a first-chunk name: null coalesces to '' (apply-chunk.ts). A host that pattern-matches on stage name or content should expect display-merged text, not exact per-chunk labels. The doc's phrase 'the one part of custom_content the protocol projects' is fine.

*/
const toOverlayStageStatus = (
status: Stage['status'],
): OverlayStageStatus | null => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

code-review · fyi

FYI (not a defect): toOverlayStageStatus maps any unrecognized StageStatus value to null ('still running'), as the comment documents. This silently conflates 'legitimately running' with 'unrecognized settled value'. Harmless today since StageStatus has only Completed/Failed, but worth remembering if a third state (e.g. cancelled/interrupted) is added upstream — the overlay callers would see it as in-progress.

});
});

it('getMessages exposes the agent stages attached to a message', () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

code-review · optional

Optional: good round-trip coverage through the bridge. One behavioral surface without a direct test: the sendMessage response messages (the README example reads stages off sendMessage/getMessages results). Both routes call toOverlayMessages on the same ref, so coverage is effectively shared, but an explicit assertion that the post-send messages include stages when the ref already contains them would lock the send-path contract too.

Comment thread libs/chat-hooks/src/conversation/overlay-messages.ts
@github-actions

Copy link
Copy Markdown

⚠️ code-review: Small, well-tested stage projection into the overlay; no blocking issues, a few fyi/optional items.

Severity Location Message
fyi None Review note: npm run validate:docs (touches libs/chat-overlay + libs/chat-hooks READMEs and docs/chat-overlay-migration-guide.md) and nx test for the touched projects were not run by this pipeline; run them before merge. The examples in the changed README sections were checked by hand against the source and reference only existing symbols (OverlayChatMessage, OverlayStageStatus, toOverlayMessages, OverlayEventType.GptEndGenerating). Minor: chat-overlay README says status example via stage.status === OverlayStageStatus.CompletedOverlayStageStatus is exported from the package, so the example compiles.

4 finding(s) posted as inline review comments.

Run details

@PolinaGurinovich97
PolinaGurinovich97 merged commit 46e6b7a into development Sep 15, 2026
21 checks passed
@PolinaGurinovich97
PolinaGurinovich97 deleted the feat/overlay-stages branch September 15, 2026 11:17
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