blob: 1f9e45036d6199a01ac5e8065945053eaacde39c [file]
import type { ToolResultContent } from '@maka/core';
import type { RuntimeEvent } from '@maka/core';
import type { ExecutionRuntimeEventWriter } from '@maka/storage/execution-stores';
const OUTCOME_UNKNOWN_TEXT =
'outcome_unknown: the Host restarted after dispatching this Client Capability call. The client-side effect may have happened; do not retry it automatically.';
export async function recoverClientCapabilityOutcomes(
store: ExecutionRuntimeEventWriter,
sessionIds: readonly string[],
now: () => number = Date.now,
): Promise<number> {
let recovered = 0;
for (const sessionId of sessionIds) {
const operations = await store.listUnsettledToolOperations(sessionId);
for (const operation of operations) {
if (operation.recoveryMode !== 'outcome_unknown') continue;
const ts = now();
const result = {
kind: 'text',
text: OUTCOME_UNKNOWN_TEXT,
uncertainOutcome: {
code: 'outcome_unknown',
retrySafe: false,
},
} as const satisfies ToolResultContent;
const runtimeEvent: RuntimeEvent = {
id: `${operation.operationId}_response`,
invocationId: operation.invocationId,
runId: operation.runId,
sessionId,
turnId: operation.turnId,
ts,
partial: false,
role: 'tool',
author: 'tool',
content: {
kind: 'function_response',
id: operation.providerToolCallId,
name: operation.toolName,
result,
isError: true,
},
refs: {
operationId: operation.operationId,
toolCallId: operation.providerToolCallId,
},
};
const committed = await store.commitToolOutcome({
operationId: operation.operationId,
journalEventId: `${operation.operationId}_outcome`,
runtimeEvent,
committedAt: ts,
});
if (committed.created) recovered += 1;
}
}
return recovered;
}