mirror of
https://github.com/stablyai/orca.git
synced 2026-11-03 18:47:40 +00:00
fix(agent-status): keep the conversation id across hookless claude turns (#36208)
Claude reports slash commands like /context over OSC 7501 with no hooks, so idle panes lost their session and mobile chat could not find it. Fixes #36033
This commit is contained in:
@@ -215,7 +215,31 @@ describe('AgentHookServer ingestTerminalStatus', () => {
|
||||
}
|
||||
)
|
||||
|
||||
it('drops the cached provider session when an OSC status starts a new turn', () => {
|
||||
// Claude reports hookless slash commands (`/context`) as OSC 7501 working then done; the session lives on (#36033).
|
||||
it('keeps the cached provider session when an OSC status starts a turn after done', () => {
|
||||
const server = new AgentHookServer()
|
||||
const providerSession = { key: 'session_id' as const, id: 'claude-session-1' }
|
||||
|
||||
server.ingestRemote(
|
||||
{
|
||||
paneKey: PANE,
|
||||
providerSession,
|
||||
payload: { state: 'done', prompt: 'first', agentType: 'claude' }
|
||||
},
|
||||
'conn-1'
|
||||
)
|
||||
for (const state of ['working', 'done'] as const) {
|
||||
server.ingestTerminalStatus({
|
||||
paneKey: PANE,
|
||||
connectionId: 'conn-1',
|
||||
payload: { state, prompt: '', agentType: 'claude' }
|
||||
})
|
||||
}
|
||||
|
||||
expect(server.getStatusSnapshot()[0]).toMatchObject({ state: 'done', providerSession })
|
||||
})
|
||||
|
||||
it('drops the cached provider session when a relaunched agent starts a turn after the old one exited', () => {
|
||||
const server = new AgentHookServer()
|
||||
|
||||
server.ingestRemote(
|
||||
@@ -226,10 +250,12 @@ describe('AgentHookServer ingestTerminalStatus', () => {
|
||||
},
|
||||
'conn-1'
|
||||
)
|
||||
server.reconcileEndedProcessForPaneKeys([PANE], { preserveResumeIdentity: true })
|
||||
expect(server.getStatusSnapshot()[0]).toMatchObject({ providerSessionOnly: true })
|
||||
server.ingestTerminalStatus({
|
||||
paneKey: PANE,
|
||||
connectionId: 'conn-1',
|
||||
payload: { state: 'working', prompt: 'second', agentType: 'claude' }
|
||||
payload: { state: 'working', prompt: '', agentType: 'claude' }
|
||||
})
|
||||
|
||||
expect(server.getStatusSnapshot()[0]?.providerSession).toBeUndefined()
|
||||
|
||||
@@ -280,13 +280,14 @@ export abstract class AgentHookServerIngestTerminal extends AgentHookServerInges
|
||||
event.payload.agentType && event.payload.agentType !== 'unknown'
|
||||
? event.payload.agentType
|
||||
: undefined
|
||||
// Launch seeds are not completed turns; real completed sessions must not leak into reused panes.
|
||||
// A live agent's turn after `done` keeps its session (OSC 7501 reports hookless slash commands); a new run or an exited agent's resume-only row does not. Launch seeds are not completed turns.
|
||||
const preservedProviderSession =
|
||||
previous?.providerSession &&
|
||||
(claimedAgentType === undefined || claimedAgentType === previous.payload.agentType) &&
|
||||
(previous.payload.state !== 'done' ||
|
||||
event.payload.state === 'done' ||
|
||||
previous.observation?.origin === 'launch')
|
||||
previous.observation?.origin === 'launch' ||
|
||||
(!newRun && previous.providerSessionOnly !== true))
|
||||
? previous.providerSession
|
||||
: undefined
|
||||
// Without a new main-agent fact, preserve it only while the row's state and agent still match.
|
||||
|
||||
Reference in New Issue
Block a user