Commit 81f1070
authored
fix(agent-gateway): seed agent phase when a transcript attaches mid-turn (#365)
## Requirement or Bug
Resolve #350
## Bug Reproduction Steps
In `transcriptContract.e2e.test.ts` S3, add `await new Promise((r) =>
setTimeout(r, 3000));` after `submitPrompt`. It then fails every time
with `expect(mid.meta.agent).toBeDefined()`. Without the sleep it fails
about 1 run in 4, and more often under load.
## Root Cause
The transcript store binds to the event bus lazily, on the first
transcript request. `meta.agent.phase` comes only from the projector's
phase merge, and that merge runs only when a new bus event arrives. On a
late attach, `subscribeAgent` (`coreBinding.ts`) restores the running
turn with `seedActiveTurn`, but it does not restore the phase.
`seedPendingInteractions` then adds the approval. The turn is blocked on
that approval, so no further event comes and `meta.agent` stays
undefined. In the product, a client that opens or reloads a session
while an approval is pending shows the approval with no agent status.
Fundamental fix.
## Code Changes
- `coreEventMap.ts`: new `AgentTranscriptProjector.seedPhase()`. It
recomputes the phase from the activity snapshot and the pending
approvals, and returns one `meta.merge`. The tracker set-up moves to
`tracker()`, which `phaseFor` reuses.
- `coreBinding.ts`: when attaching to a turn that is already running,
apply `seedPhase()` after `seedActiveTurn`. Idle and new agents are not
touched. A later phase event with the same value is deduplicated by the
tracker's `lastPhaseKey`.
- Test: `transcript.test.ts` checks that `seedPhase()` gives
`awaiting_approval` for a turn blocked on an approval.
Not in scope: `meta.agent.model` and `meta.agent.permission` on late
attach. S3 needs only the phase.
## Behavior Changes and Affected Users
| Behavior | Before | After | Who relies on the old behavior | Escape
hatch |
| --- | --- | --- | --- | --- |
| Transcript first opened while a turn is running | `meta.agent` missing
until the next phase event (never, if the turn is blocked on an
approval) | `meta.agent.phase` is set immediately | None. Clients
already handle `meta.agent.phase` from live events | None needed |
Consumers: web, desktop, and inspector clients that read
`meta.agent.phase`. The wire shape is unchanged. Verification:
forced-late S3 fails 2/2 without the fix and passes 2/2 with it. Full
agent-gateway suite: 1408/1408.
No quarantine for S3 exists in the repo, so there is nothing to remove.
## Checklist
- [x] I have read the
[CONTRIBUTING](https://github.com/PyModel/pythinker-code/blob/main/CONTRIBUTING.md)
document.
- [x] I have linked a related issue (external PRs: issue must have a
maintainer's `/approve`).
- [x] I have added tests that prove my feature works.
- [x] The behavior-change table above is complete, and every removed
behavior or flipped default is named in the changeset and either has an
escape hatch or was explicitly approved by a maintainer in this PR.
- [x] Ran `gen-changesets` skill, or this PR needs no changeset.
- [x] Ran `gen-docs` skill, or this PR needs no doc update.1 parent ecc2c3b commit 81f1070
4 files changed
Lines changed: 36 additions & 2 deletions
File tree
- .changeset
- packages/agent-gateway
- src/services/transcript
- test/services
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
Lines changed: 1 addition & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
155 | 155 | | |
156 | 156 | | |
157 | 157 | | |
| 158 | + | |
158 | 159 | | |
159 | 160 | | |
160 | 161 | | |
| |||
Lines changed: 12 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
357 | 357 | | |
358 | 358 | | |
359 | 359 | | |
360 | | - | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
361 | 366 | | |
362 | 367 | | |
363 | 368 | | |
364 | 369 | | |
365 | 370 | | |
366 | 371 | | |
367 | 372 | | |
368 | | - | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
369 | 379 | | |
370 | 380 | | |
371 | 381 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1597 | 1597 | | |
1598 | 1598 | | |
1599 | 1599 | | |
| 1600 | + | |
| 1601 | + | |
| 1602 | + | |
| 1603 | + | |
| 1604 | + | |
| 1605 | + | |
| 1606 | + | |
| 1607 | + | |
| 1608 | + | |
| 1609 | + | |
| 1610 | + | |
| 1611 | + | |
| 1612 | + | |
| 1613 | + | |
| 1614 | + | |
| 1615 | + | |
| 1616 | + | |
| 1617 | + | |
1600 | 1618 | | |
1601 | 1619 | | |
1602 | 1620 | | |
| |||
0 commit comments