mirror of
https://github.com/stablyai/orca.git
synced 2026-09-29 08:03:20 +00:00
fix(codex): publish the turn tail for a subagent item the roster claims
Main's #19055 added a `subAgentActivity` arm to the provider activity table, which is reached only through `publishActivity`. The roster's admission returned above that call, so every `subAgentActivity` item bypassed it and a fan-out that reports nothing else left the turn tail stuck on the previous frame's text. `publishActivity` already no-ops on a refused admission and on a non-primary thread, so routing the roster's admission through it is safe. Also corrects a docstring the frames extraction copy-pasted onto `settleOversizedNotification`.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { agentJournalItemKey } from '../../shared/agent-session-journal-item-key'
|
||||
import type { AgentSessionTurnActivity } from '../../shared/agent-session-wire'
|
||||
import type {
|
||||
AgentJournalItemBody,
|
||||
AgentJournalItemIdentity
|
||||
@@ -17,11 +18,13 @@ type Row = { key: string; body: AgentJournalItemBody }
|
||||
|
||||
function harness() {
|
||||
const rows: Row[] = []
|
||||
const activities: (AgentSessionTurnActivity | null)[] = []
|
||||
const sink: StructuredAgentSessionEventSink = {
|
||||
appendItem: (identity: AgentJournalItemIdentity, body) =>
|
||||
rows.push({ key: agentJournalItemKey(identity), body }),
|
||||
appendTombstone: () => {},
|
||||
publish: () => {}
|
||||
publish: () => {},
|
||||
setActivity: (activity) => activities.push(activity)
|
||||
}
|
||||
const translator = createCodexJournalTranslator({
|
||||
sink,
|
||||
@@ -31,7 +34,7 @@ function harness() {
|
||||
return () => {}
|
||||
}
|
||||
})
|
||||
return { translator, rows }
|
||||
return { translator, rows, activities }
|
||||
}
|
||||
|
||||
function notification(method: string, params: unknown): CodexStructuredSessionEvent {
|
||||
@@ -88,6 +91,22 @@ describe('codex journal translation — subagents', () => {
|
||||
expect(rows.filter((row) => row.key.startsWith('orca:codex-subagents'))).toHaveLength(1)
|
||||
})
|
||||
|
||||
// The roster claims the item, but claiming it must not take the turn tail with
|
||||
// it: the activity table is reached only through the publish arm, so a bare
|
||||
// return leaves the tail stuck on whatever the previous frame said.
|
||||
it('still publishes the turn tail for an item the roster claims', () => {
|
||||
const { translator, activities } = harness()
|
||||
|
||||
translator.handle(notification('turn/started', { turn: { id: TURN_ID } }))
|
||||
activities.length = 0
|
||||
deliverActivity(translator, subagentItem('started', 'child-1', '/root/read'))
|
||||
|
||||
expect(activities.at(-1)).toEqual({
|
||||
turnId: TURN_ID,
|
||||
text: 'Coordinating with another agent'
|
||||
})
|
||||
})
|
||||
|
||||
it('consumes thread/tokenUsage/updated instead of swallowing it as chrome', () => {
|
||||
const { translator, rows } = harness()
|
||||
|
||||
|
||||
@@ -191,7 +191,9 @@ export function createCodexJournalTranslator(
|
||||
})
|
||||
: null
|
||||
if (subagentAdmission) {
|
||||
return subagentAdmission
|
||||
// Not a bare return: the roster claiming the item must not skip the
|
||||
// turn-tail arm, which is the only publisher of its activity copy.
|
||||
return publishActivity(event, subagentAdmission)
|
||||
}
|
||||
const translated = items.handle(event)
|
||||
return publishActivity(
|
||||
@@ -224,7 +226,8 @@ export function createCodexJournalTranslator(
|
||||
}
|
||||
}
|
||||
|
||||
/** Routes a `subAgentActivity` item to the roster; null when it is not one. */
|
||||
/** Settles the item a notification the transport refused to carry left
|
||||
* mid-flight; null when the frame is not one. */
|
||||
function settleOversizedNotification(event: {
|
||||
sessionId: string
|
||||
threadId: string
|
||||
|
||||
@@ -28,6 +28,16 @@ describe('provider frame activity', () => {
|
||||
expect(codexProviderFrameActivity('item/reasoning/summaryPartAdded', {})).toBeNull()
|
||||
})
|
||||
|
||||
it('names a fan-out from either Codex item type that reports one', () => {
|
||||
for (const type of ['collabAgentToolCall', 'subAgentActivity']) {
|
||||
expect(
|
||||
codexProviderFrameActivity('item/started', {
|
||||
item: { type, kind: 'started', agentThreadId: 'child-1', agentPath: '/root/read' }
|
||||
})
|
||||
).toBe('Coordinating with another agent')
|
||||
}
|
||||
})
|
||||
|
||||
it('uses Claude descriptions and safe semantic status without exposing tool labels', () => {
|
||||
expect(
|
||||
claudeProviderFrameActivity('message:system:task_started', {
|
||||
|
||||
Reference in New Issue
Block a user