Found while working M10a (#233).
Problem
With checkpointed sessions (mountChannels(agent, channels, { store: { sessions, checkpoints } }), e.g. a SqliteStore), a Slack or Discord button click after a restart resolves the approval and posts the continuation, but:
- the continuation is not appended to the session transcript (docs/channels.md says so), and
decide() in src/channels/mountChannels.ts calls agent.approvals.resolve() without the approval bound to a session, so resolveAfterApproval runs without the session's checkpoint store. In a Slack test (fake fetch, KVCheckpointStore over a Map) a thread message after such a click was ignored: no transcript had ever been saved for the thread, so hasSession() is false.
Likely fix
The same binding M10a adds for questions: when decide() gets a decision whose id is not in paused but carries inbound, open agent.session({ id, store }), check pending() is awaiting-approval with that approvalId, call resume() once and catch SessionAwaitingApprovalError (this binds the approval to the session in createAgentApprovals), then resolve. Test: the click-after-restart tests in slackChannel.test.ts / discordChannel.test.ts with durableStores() from src/channels/__fixtures__/durableStores.ts, asserting the transcript holds the tool call, its result and the reply, and that the next thread message continues the session.
Out of M10a's scope ("Approval clicks: already survive a restart").
Found while working M10a (#233).
Problem
With checkpointed sessions (
mountChannels(agent, channels, { store: { sessions, checkpoints } }), e.g. aSqliteStore), a Slack or Discord button click after a restart resolves the approval and posts the continuation, but:decide()insrc/channels/mountChannels.tscallsagent.approvals.resolve()without the approval bound to a session, soresolveAfterApprovalruns without the session's checkpoint store. In a Slack test (fake fetch,KVCheckpointStoreover a Map) a thread message after such a click was ignored: no transcript had ever been saved for the thread, sohasSession()is false.Likely fix
The same binding M10a adds for questions: when
decide()gets a decision whose id is not inpausedbut carriesinbound, openagent.session({ id, store }), checkpending()isawaiting-approvalwith thatapprovalId, callresume()once and catchSessionAwaitingApprovalError(this binds the approval to the session increateAgentApprovals), then resolve. Test: the click-after-restart tests inslackChannel.test.ts/discordChannel.test.tswithdurableStores()fromsrc/channels/__fixtures__/durableStores.ts, asserting the transcript holds the tool call, its result and the reply, and that the next thread message continues the session.Out of M10a's scope ("Approval clicks: already survive a restart").