Repository navigation
feat(host): a window follows an agent's transcript as a stream of pushed pages - #4175
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
luke-agent
Bot
force-pushed
the
luke/live-transcript-clock-edges
branch
from
October 20, 2026 20:06
bd721c4 to
b60a57c
Compare
luke-agent
Bot
force-pushed
the
luke/transcript-push-host-main
branch
from
October 20, 2026 20:16
9c4159e to
ada9754
Compare
luke-agent
Bot
force-pushed
the
luke/live-transcript-clock-edges
branch
from
October 20, 2026 20:31
b60a57c to
7766e7e
Compare
luke-agent
Bot
force-pushed
the
luke/transcript-push-host-main
branch
from
October 20, 2026 20:34
ada9754 to
ecb4073
Compare
luke-agent
Bot
force-pushed
the
luke/live-transcript-clock-edges
branch
from
October 20, 2026 21:11
589b9b1 to
82bf07f
Compare
luke-agent
Bot
force-pushed
the
luke/transcript-push-host-main
branch
from
October 20, 2026 21:14
ecb4073 to
073bd12
Compare
…hed pages The act port gains `codingAgents.transcript`, an event-iterator procedure. It follows one agent's transcript, one of its workers', or a task's planning worker's while the window keeps the stream open, and lets it go once the last stream of that transcript closes. The first page comes from the start and each later one is what moved past the last. It also notes the agent's title and status from each page, as the read did. On the gateway, `codingAgents.transcriptFollow`/`Unfollow` follow an agent's transcript on its existing Neon Realtime subscription and tell each page as `transcript.changed`. A planning worker is followed on the service's held read until it gets live statements of its own. Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
…er than asking again at once Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
luke-agent
Bot
force-pushed
the
luke/transcript-push-host-main
branch
from
October 20, 2026 21:27
29cfe7d to
ee66ec2
Compare
…t the asks Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
luke-agent Bot
added a commit
that referenced
this pull request
Oct 21, 2026
…hat draw them from Neon Realtime A workspace's members, and who its work names but left, are now followed over Realtime while a window draws them, on the act port's own stream (`workspace.people`, an eventIterator), as #4175 streams a transcript: the procedure counts the streams open of each workspace, has the host follow it afresh as each opens, so the window hears where they stand, and lets it go with the last. The host follows each workspace (WORKSPACES_PEOPLE_FOLLOW, polled while Realtime fails it) and tells every change, or why there is none, as WORKSPACE_PEOPLE_CHANGED, never through app state, which the voice window reads too. A web tab serves the same procedure with nothing of its own. The members read stays as the first read; the re-read whenever the workspace's member count changed, and the settings page's read before Transfer ownership, are gone: a member joining, leaving, or given another role elsewhere is pushed. Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
luke-agent Bot
added a commit
that referenced
this pull request
Oct 21, 2026
…hat draw them from Neon Realtime A workspace's members, and who its work names but left, are now followed over Realtime while a window draws them, on the act port's own stream (`workspace.people`, an eventIterator), as #4175 streams a transcript: the procedure counts the streams open of each workspace, has the host follow it afresh as each opens, so the window hears where they stand, and lets it go with the last. The host follows each workspace (WORKSPACES_PEOPLE_FOLLOW, polled while Realtime fails it) and tells every change, or why there is none, as WORKSPACE_PEOPLE_CHANGED, never through app state, which the voice window reads too. A web tab serves the same procedure with nothing of its own. The members read stays as the first read; the re-read whenever the workspace's member count changed, and the settings page's read before Transfer ownership, are gone: a member joining, leaving, or given another role elsewhere is pushed. Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
luke-agent Bot
added a commit
that referenced
this pull request
Oct 21, 2026
…hat draw them from Neon Realtime A workspace's members, and who its work names but left, are now followed over Realtime while a window draws them, on the act port's own stream (`workspace.people`, an eventIterator), as #4175 streams a transcript: the procedure counts the streams open of each workspace, has the host follow it afresh as each opens, so the window hears where they stand, and lets it go with the last. The host follows each workspace (WORKSPACES_PEOPLE_FOLLOW, polled while Realtime fails it) and tells every change, or why there is none, as WORKSPACE_PEOPLE_CHANGED, never through app state, which the voice window reads too. A web tab serves the same procedure with nothing of its own. The members read stays as the first read; the re-read whenever the workspace's member count changed, and the settings page's read before Transfer ownership, are gone: a member joining, leaving, or given another role elsewhere is pushed. Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
luke-agent Bot
added a commit
that referenced
this pull request
Oct 21, 2026
…hat draw them from Neon Realtime A workspace's members, and who its work names but left, are now followed over Realtime while a window draws them, on the act port's own stream (`workspace.people`, an eventIterator), as #4175 streams a transcript: the procedure counts the streams open of each workspace, has the host follow it afresh as each opens, so the window hears where they stand, and lets it go with the last. The host follows each workspace (WORKSPACES_PEOPLE_FOLLOW, polled while Realtime fails it) and tells every change, or why there is none, as WORKSPACE_PEOPLE_CHANGED, never through app state, which the voice window reads too. A web tab serves the same procedure with nothing of its own. The members read stays as the first read; the re-read whenever the workspace's member count changed, and the settings page's read before Transfer ownership, are gone: a member joining, leaving, or given another role elsewhere is pushed. Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
luke-agent Bot
added a commit
that referenced
this pull request
Oct 21, 2026
…hat draw them from Neon Realtime A workspace's members, and who its work names but left, are now followed over Realtime while a window draws them, on the act port's own stream (`workspace.people`, an eventIterator), as #4175 streams a transcript: the procedure counts the streams open of each workspace, has the host follow it afresh as each opens, so the window hears where they stand, and lets it go with the last. The host follows each workspace (WORKSPACES_PEOPLE_FOLLOW, polled while Realtime fails it) and tells every change, or why there is none, as WORKSPACE_PEOPLE_CHANGED, never through app state, which the voice window reads too. A web tab serves the same procedure with nothing of its own. The members read stays as the first read; the re-read whenever the workspace's member count changed, and the settings page's read before Transfer ownership, are gone: a member joining, leaving, or given another role elsewhere is pushed. Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
luke-agent Bot
added a commit
that referenced
this pull request
Oct 21, 2026
…hat draw them from Neon Realtime A workspace's members, and who its work names but left, are now followed over Realtime while a window draws them, on the act port's own stream (`workspace.people`, an eventIterator), as #4175 streams a transcript: the procedure counts the streams open of each workspace, has the host follow it afresh as each opens, so the window hears where they stand, and lets it go with the last. The host follows each workspace (WORKSPACES_PEOPLE_FOLLOW, polled while Realtime fails it) and tells every change, or why there is none, as WORKSPACE_PEOPLE_CHANGED, never through app state, which the voice window reads too. A web tab serves the same procedure with nothing of its own. The members read stays as the first read; the re-read whenever the workspace's member count changed, and the settings page's read before Transfer ownership, are gone: a member joining, leaving, or given another role elsewhere is pushed. Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
luke-agent Bot
added a commit
that referenced
this pull request
Oct 21, 2026
…hat draw them from Neon Realtime A workspace's members, and who its work names but left, are now followed over Realtime while a window draws them, on the act port's own stream (`workspace.people`, an eventIterator), as #4175 streams a transcript: the procedure counts the streams open of each workspace, has the host follow it afresh as each opens, so the window hears where they stand, and lets it go with the last. The host follows each workspace (WORKSPACES_PEOPLE_FOLLOW, polled while Realtime fails it) and tells every change, or why there is none, as WORKSPACE_PEOPLE_CHANGED, never through app state, which the voice window reads too. A web tab serves the same procedure with nothing of its own. The members read stays as the first read; the re-read whenever the workspace's member count changed, and the settings page's read before Transfer ownership, are gone: a member joining, leaving, or given another role elsewhere is pushed. Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
luke-agent Bot
added a commit
that referenced
this pull request
Oct 21, 2026
…hat draw them from Neon Realtime A workspace's members, and who its work names but left, are now followed over Realtime while a window draws them, on the act port's own stream (`workspace.people`, an eventIterator), as #4175 streams a transcript: the procedure counts the streams open of each workspace, has the host follow it afresh as each opens, so the window hears where they stand, and lets it go with the last. The host follows each workspace (WORKSPACES_PEOPLE_FOLLOW, polled while Realtime fails it) and tells every change, or why there is none, as WORKSPACE_PEOPLE_CHANGED, never through app state, which the voice window reads too. A web tab serves the same procedure with nothing of its own. The members read stays as the first read; the re-read whenever the workspace's member count changed, and the settings page's read before Transfer ownership, are gone: a member joining, leaving, or given another role elsewhere is pushed. Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
luke-agent Bot
added a commit
that referenced
this pull request
Oct 21, 2026
…hat draw them from Neon Realtime A workspace's members, and who its work names but left, are now followed over Realtime while a window draws them, on the act port's own stream (`workspace.people`, an eventIterator), as #4175 streams a transcript: the procedure counts the streams open of each workspace, has the host follow it afresh as each opens, so the window hears where they stand, and lets it go with the last. The host follows each workspace (WORKSPACES_PEOPLE_FOLLOW, polled while Realtime fails it) and tells every change, or why there is none, as WORKSPACE_PEOPLE_CHANGED, never through app state, which the voice window reads too. A web tab serves the same procedure with nothing of its own. The members read stays as the first read; the re-read whenever the workspace's member count changed, and the settings page's read before Transfer ownership, are gone: a member joining, leaving, or given another role elsewhere is pushed. Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
luke-agent Bot
added a commit
that referenced
this pull request
Oct 21, 2026
…hat draw them from Neon Realtime A workspace's members, and who its work names but left, are now followed over Realtime while a window draws them, on the act port's own stream (`workspace.people`, an eventIterator), as #4175 streams a transcript: the procedure counts the streams open of each workspace, has the host follow it afresh as each opens, so the window hears where they stand, and lets it go with the last. The host follows each workspace (WORKSPACES_PEOPLE_FOLLOW, polled while Realtime fails it) and tells every change, or why there is none, as WORKSPACE_PEOPLE_CHANGED, never through app state, which the voice window reads too. A web tab serves the same procedure with nothing of its own. The members read stays as the first read; the re-read whenever the workspace's member count changed, and the settings page's read before Transfer ownership, are gone: a member joining, leaving, or given another role elsewhere is pushed. Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
github-merge-queue Bot
pushed a commit
that referenced
this pull request
Oct 21, 2026
…hat draw them from Neon Realtime (#3942) A workspace's members, and who its work names but left, are now followed over Realtime while a window draws them, on the act port's own stream (`workspace.people`, an eventIterator), as #4175 streams a transcript: the procedure counts the streams open of each workspace, has the host follow it afresh as each opens, so the window hears where they stand, and lets it go with the last. The host follows each workspace (WORKSPACES_PEOPLE_FOLLOW, polled while Realtime fails it) and tells every change, or why there is none, as WORKSPACE_PEOPLE_CHANGED, never through app state, which the voice window reads too. A web tab serves the same procedure with nothing of its own. The members read stays as the first read; the re-read whenever the workspace's member count changed, and the settings page's read before Transfer ownership, are gone: a member joining, leaving, or given another role elsewhere is pushed. Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The host half of making the agent transcript live on
main. It's stacked on #3298 (luke/live-transcript-clock-edges) and replaces #3909, which was built on the old stack. The window moves over in the next PR.What changed
codingAgents.transcript, takes a transcript key and yields its pages for as long as the window keeps the stream open.callId), or a task's planning worker's.codingAgents.transcriptFollow/Unfollow:followTranscriptreads on the transcript's existing Realtime subscription (transcriptFollows) and tells each page astranscript.changed. It reads the first page from the start, the next one right away after a page with messages, and otherwise again only when the statements move or the service'swakeInedge passes.tasks.workerTranscriptFollow/Unfollow: a planning worker is followed on the service's heldtasks.messagesread until feat(service,host): a planning worker's transcript is followed through the shared live layer #3311 gives it live statements of its own. The follow stops once the worker has ended and its page is empty.codingAgentTranscriptKeySchemaandcodingAgentTranscriptChangedSchema, recorded inhosted-wire-schemas.test.tswith goldens generated underLUKE_UPDATE_FIXTURES=1.Tests
compose-coding-agents.test.ts: a followed agent transcript is told page by page; a transcript the account can't reach is told not found once; behind a closed gate it's told unanswered; sign-out lets it go.compose-tasks.test.ts: a planning worker is told page by page on the held read, and the follow ends with the worker.agents-procedures.test.ts: two streams of one transcript each hear its pages and nothing of another's; the host lets it go only when the last stream closes.Checks run locally
pnpm check:affectedgets OOM-killed in the sandbox, so I ran its pieces one at a time:repository-checks.sh,biome check .,oxlint,knipdiscarded-effect(with a larger heap)tscfor host, desktop, web and panelWhat to check by hand
Nothing visible changes yet: no window opens the stream until the next PR.
Made with Luke