@0xmaxma/claude-gateway 2.0.12 → 2.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config.template.json +1 -1
- package/dist/agent/runner.d.ts.map +1 -1
- package/dist/agent/runner.js +2 -25
- package/dist/agent/runner.js.map +1 -1
- package/dist/build-provenance.json +4 -4
- package/dist/orchestration/bridge.d.ts +3 -0
- package/dist/orchestration/bridge.d.ts.map +1 -1
- package/dist/orchestration/bridge.js +22 -11
- package/dist/orchestration/bridge.js.map +1 -1
- package/dist/orchestration/cli-skills.d.ts +5 -0
- package/dist/orchestration/cli-skills.d.ts.map +1 -1
- package/dist/orchestration/cli-skills.js +63 -0
- package/dist/orchestration/cli-skills.js.map +1 -1
- package/dist/orchestration/config.d.ts +44 -0
- package/dist/orchestration/config.d.ts.map +1 -1
- package/dist/orchestration/config.js +18 -5
- package/dist/orchestration/config.js.map +1 -1
- package/dist/orchestration/conversation-intake.d.ts +1 -1
- package/dist/orchestration/conversation-intake.d.ts.map +1 -1
- package/dist/orchestration/conversation-intake.js +6 -5
- package/dist/orchestration/conversation-intake.js.map +1 -1
- package/dist/orchestration/delivery.d.ts +1 -0
- package/dist/orchestration/delivery.d.ts.map +1 -1
- package/dist/orchestration/delivery.js +1 -1
- package/dist/orchestration/delivery.js.map +1 -1
- package/dist/orchestration/file-delivery.d.ts.map +1 -1
- package/dist/orchestration/file-delivery.js +47 -3
- package/dist/orchestration/file-delivery.js.map +1 -1
- package/dist/orchestration/input-batch.d.ts +16 -0
- package/dist/orchestration/input-batch.d.ts.map +1 -0
- package/dist/orchestration/input-batch.js +59 -0
- package/dist/orchestration/input-batch.js.map +1 -0
- package/dist/orchestration/narrate.d.ts +42 -0
- package/dist/orchestration/narrate.d.ts.map +1 -0
- package/dist/orchestration/narrate.js +197 -0
- package/dist/orchestration/narrate.js.map +1 -0
- package/dist/orchestration/process-turn.js +1 -1
- package/dist/orchestration/process-turn.js.map +1 -1
- package/dist/orchestration/runtime.d.ts +2 -0
- package/dist/orchestration/runtime.d.ts.map +1 -1
- package/dist/orchestration/runtime.js +84 -16
- package/dist/orchestration/runtime.js.map +1 -1
- package/dist/orchestration/skills.d.ts +6 -0
- package/dist/orchestration/skills.d.ts.map +1 -1
- package/dist/orchestration/skills.js +9 -2
- package/dist/orchestration/skills.js.map +1 -1
- package/dist/orchestration/task-files.d.ts +10 -1
- package/dist/orchestration/task-files.d.ts.map +1 -1
- package/dist/orchestration/task-files.js +46 -8
- package/dist/orchestration/task-files.js.map +1 -1
- package/dist/session/runtime-profile.d.ts.map +1 -1
- package/dist/session/runtime-profile.js +2 -1
- package/dist/session/runtime-profile.js.map +1 -1
- package/dist/voice/line-audio.d.ts +10 -1
- package/dist/voice/line-audio.d.ts.map +1 -1
- package/dist/voice/line-audio.js +19 -6
- package/dist/voice/line-audio.js.map +1 -1
- package/dist/voice/narrate-split.d.ts +17 -0
- package/dist/voice/narrate-split.d.ts.map +1 -0
- package/dist/voice/narrate-split.js +77 -0
- package/dist/voice/narrate-split.js.map +1 -0
- package/mcp/lazy-tools.test.ts +2 -1
- package/mcp/modules.ts +2 -0
- package/mcp/server.ts +2 -1
- package/mcp/tools/narrate/module.ts +42 -0
- package/mcp/tools/tasks/module.ts +7 -2
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.AgentOrchestrationRuntime = exports.GATEWAY_TASK_INSTRUCTIONS = void 0;
|
|
4
4
|
exports.readRequestDirective = readRequestDirective;
|
|
5
5
|
exports.agentHandoffDirective = agentHandoffDirective;
|
|
6
|
+
const input_batch_1 = require("./input-batch");
|
|
6
7
|
const computer_prompt_1 = require("./computer-prompt");
|
|
7
8
|
const control_notification_1 = require("./control-notification");
|
|
8
9
|
const computer_choice_ids_1 = require("../automation/computer-choice-ids");
|
|
@@ -91,6 +92,7 @@ const bounded_queue_1 = require("./bounded-queue");
|
|
|
91
92
|
const capacity_1 = require("./capacity");
|
|
92
93
|
const cleanup_1 = require("./tasks/cleanup");
|
|
93
94
|
const task_files_1 = require("./task-files");
|
|
95
|
+
const narrate_1 = require("./narrate");
|
|
94
96
|
const worker_shares_1 = require("./worker-shares");
|
|
95
97
|
const provider_admission_1 = require("./provider-admission");
|
|
96
98
|
const provider_scope_1 = require("./provider-scope");
|
|
@@ -322,6 +324,10 @@ class AgentOrchestrationRuntime {
|
|
|
322
324
|
progress: (task, report) => store.transaction(() => { const current = store.task(task.taskId); if (!current || current.activeAttemptId !== task.activeAttemptId || !['starting', 'running', 'interrupting'].includes(current.state))
|
|
323
325
|
return; current.computerReport = report; current.latestProgress = { source: 'runtime', observedAt: Date.now(), text: `Computer Use: ${report.phase} · ${report.steps} actions · ${report.evaluations ?? 0} evaluations.${current.queuedCommands?.length ? ` ${current.queuedCommands.length} queued command${current.queuedCommands.length === 1 ? '' : 's'} waiting.` : ''}` }; store.saveTask(current, current.stateVersion); }) }));
|
|
324
326
|
const bridge = new bridge_1.TaskBridge(tasks, files, (0, worker_shares_1.workerShares)(files, agent, gateway), host.skills ? () => host.skills() : undefined, agent.type === 'app-agent' ? { agent, spool: (0, path_1.join)(root, 'container-files') } : undefined, (0, worker_crons_1.workerCrons)(files, agent, gateway), gatewayAdapters);
|
|
327
|
+
const voiceConfig = () => (0, config_2.resolveOrchestrationConfig)(agent.orchestration, agent.voice ?? { enabled: false }).voice;
|
|
328
|
+
const narrateVoices = new telegram_voices_1.TelegramVoices(store, () => voiceConfig().tts);
|
|
329
|
+
bridge.narrateCall = (0, narrate_1.workerNarrate)({ files, config: () => voiceConfig().narrate, voiceEnabled: () => voiceConfig().enabled,
|
|
330
|
+
settings: chat => narrateVoices.settings((0, store_1.channelVoiceKey)(chat.source, chat.chat_id, chat.thread_key ?? '')) });
|
|
325
331
|
bridge.computerEnabled = computerAllowed;
|
|
326
332
|
bridge.jevEnabled = () => (0, jev_gateway_1.jevAllowed)(gateway, agent);
|
|
327
333
|
bridge.browserEnabled = () => Boolean(gateway.gateway.jev?.browser) && (0, jev_gateway_1.jevAllowed)(gateway, agent) && gateway.gateway.jev?.features?.browserTasks?.enabled === true;
|
|
@@ -1124,12 +1130,18 @@ class AgentOrchestrationRuntime {
|
|
|
1124
1130
|
mailboxCursor = Number(row.mailbox_row);
|
|
1125
1131
|
if (this.active.size >= this.config.conversation.maxActiveSessions)
|
|
1126
1132
|
break;
|
|
1127
|
-
|
|
1128
|
-
|
|
1133
|
+
// Batch members share the row's conversation and session, so admission is
|
|
1134
|
+
// decided before scanning later rows for the batch.
|
|
1135
|
+
const head = JSON.parse(String(row.ingress_json));
|
|
1136
|
+
if (!head.scope || !head.capabilities || this.active.has(head.scope.agentSessionId))
|
|
1129
1137
|
continue;
|
|
1130
|
-
if (visitedSessions.has(
|
|
1138
|
+
if (visitedSessions.has(head.scope.agentSessionId))
|
|
1139
|
+
continue;
|
|
1140
|
+
visitedSessions.add(head.scope.agentSessionId);
|
|
1141
|
+
const batch = (0, input_batch_1.inputBatch)(this.store, row, this.batchDebounceMs(), this.config.conversation.inputMaxWaitMs);
|
|
1142
|
+
const input = batch.input;
|
|
1143
|
+
if (Date.now() < batch.readyAt)
|
|
1131
1144
|
continue;
|
|
1132
|
-
visitedSessions.add(input.scope.agentSessionId);
|
|
1133
1145
|
const scope = (0, provider_scope_1.resolveProviderScope)(this.agent, this.gateway, input.model, 'agent');
|
|
1134
1146
|
const waiting = this.providerAdmission.inspect(scope, this.config.providerAdmission);
|
|
1135
1147
|
if (waiting) {
|
|
@@ -1140,7 +1152,7 @@ class AgentOrchestrationRuntime {
|
|
|
1140
1152
|
}
|
|
1141
1153
|
// A persisted input retains the authenticated scope and model from ingress.
|
|
1142
1154
|
// Recovery can repeat inference, but committed tool receipts remain fenced.
|
|
1143
|
-
const result = this.send({ ...input, acceptedInputId: String(
|
|
1155
|
+
const result = this.send({ ...input, acceptedInputId: String(batch.last.id) }, input.capabilities, { inputIds: batch.inputIds, timeoutMs: this.config.conversation.maxDecisionDurationMs, model: input.model, onTool: event => this.inputTools.get(String(row.id))?.(event), onText: text => {
|
|
1144
1156
|
const responseId = this.responseIdForInput(String(row.id));
|
|
1145
1157
|
if (input.modality !== 'live_voice' && responseId) {
|
|
1146
1158
|
try {
|
|
@@ -1149,13 +1161,26 @@ class AgentOrchestrationRuntime {
|
|
|
1149
1161
|
catch { /* slow audio cannot stall inference */ }
|
|
1150
1162
|
}
|
|
1151
1163
|
} });
|
|
1152
|
-
void result.then(text =>
|
|
1153
|
-
|
|
1164
|
+
void result.then(text => {
|
|
1165
|
+
// Superseded, uncommitted inputs remain durable and their callers wait
|
|
1166
|
+
// for the replacement decision rather than receiving an empty answer.
|
|
1167
|
+
for (const id of batch.inputIds)
|
|
1168
|
+
if (this.store.get('SELECT status FROM conversation_inputs WHERE id=?', id)?.status === 'handled') {
|
|
1169
|
+
this.deferred.get(id)?.resolve(text);
|
|
1170
|
+
this.deferred.delete(id);
|
|
1171
|
+
}
|
|
1172
|
+
}, error => { for (const id of batch.inputIds) {
|
|
1173
|
+
this.deferred.get(id)?.reject(error);
|
|
1174
|
+
this.deferred.delete(id);
|
|
1175
|
+
} });
|
|
1154
1176
|
}
|
|
1155
1177
|
if (this.active.size >= this.config.conversation.maxActiveSessions)
|
|
1156
1178
|
break mailbox;
|
|
1157
1179
|
}
|
|
1158
1180
|
}
|
|
1181
|
+
batchDebounceMs() {
|
|
1182
|
+
return this.config.conversation.semanticIntake ? this.config.conversation.inputDebounceMs : 0;
|
|
1183
|
+
}
|
|
1159
1184
|
async run(input, capabilities, options) {
|
|
1160
1185
|
const sessionId = input.scope.agentSessionId;
|
|
1161
1186
|
const channelTts = this.telegramVoices.settings((0, store_1.channelVoiceKey)(input.scope.source, input.scope.chatId, input.scope.threadKey));
|
|
@@ -1205,7 +1230,7 @@ class AgentOrchestrationRuntime {
|
|
|
1205
1230
|
this.store.run("UPDATE conversations SET status='draining' WHERE id=?", receipt.conversationId);
|
|
1206
1231
|
this.seenSessions.add(sessionId);
|
|
1207
1232
|
this.questionControls.tick();
|
|
1208
|
-
const decision = this.decisions.begin(receipt.conversationId, input.scope.principalId, [receipt.inputId], input.requestId);
|
|
1233
|
+
const decision = this.decisions.begin(receipt.conversationId, input.scope.principalId, options.inputIds ?? [receipt.inputId], input.requestId);
|
|
1209
1234
|
active.decision = decision;
|
|
1210
1235
|
if (questionReview) {
|
|
1211
1236
|
// Notifications may arrive after this internal input was queued. A
|
|
@@ -1272,9 +1297,9 @@ class AgentOrchestrationRuntime {
|
|
|
1272
1297
|
const semantic = this.config.conversation.semanticIntake && !active.notification && !liveControl;
|
|
1273
1298
|
const prepared = semantic ? this.intake.context(receipt.conversationId, input.scope.principalId, String(admitted.binding_id)) : undefined;
|
|
1274
1299
|
const recoveryInputId = input.ingressKey?.startsWith('intake-recovery:') ? input.ingressKey.slice('intake-recovery:'.length) : undefined;
|
|
1275
|
-
const preparedInputIds = [...new Set([...(prepared?.inputIds ?? []), ...(recoveryInputId ? [recoveryInputId] : [])])];
|
|
1300
|
+
const preparedInputIds = [...new Set([...(prepared?.inputIds ?? []), ...(!recoveryInputId && (prepared?.inputIds?.length || decision.inputIds.length > 1) ? decision.inputIds : []), ...(recoveryInputId ? [recoveryInputId] : [])])];
|
|
1276
1301
|
const preparedInputs = preparedInputIds.length ? this.store.all(`SELECT id,text,attachment_refs_json,ingress_json FROM conversation_inputs
|
|
1277
|
-
WHERE conversation_id=? AND principal_id=? AND binding_id=? AND id IN (SELECT value FROM json_each(?))`, receipt.conversationId, input.scope.principalId, admitted.binding_id, JSON.stringify(preparedInputIds)) : [];
|
|
1302
|
+
WHERE conversation_id=? AND principal_id=? AND binding_id=? AND id IN (SELECT value FROM json_each(?)) ORDER BY input_seq`, receipt.conversationId, input.scope.principalId, admitted.binding_id, JSON.stringify(preparedInputIds)) : [];
|
|
1278
1303
|
const preparedRefs = preparedInputs.flatMap(row => JSON.parse(String(row.attachment_refs_json)));
|
|
1279
1304
|
if (preparedRefs.length)
|
|
1280
1305
|
input = { ...input, attachmentIds: [...new Set([...(input.attachmentIds ?? []), ...preparedRefs])] };
|
|
@@ -1309,14 +1334,18 @@ class AgentOrchestrationRuntime {
|
|
|
1309
1334
|
}
|
|
1310
1335
|
// Immutable source IDs remain available to workers. Only the model delivery
|
|
1311
1336
|
// is incremental; full canonical text and attachment references are retained.
|
|
1312
|
-
|
|
1337
|
+
// Unresolved execution is an obligation, not optional cached context. Replay
|
|
1338
|
+
// it on follow-up/recovery even when this CLI has seen it before.
|
|
1339
|
+
const replayPending = Boolean(prepared?.deferredDispatch || recoveryInputId);
|
|
1340
|
+
const freshPreparedInputs = preparedInputs.filter(row => row.id !== receipt.inputId && (replayPending || !contextPlan.includes('materials', String(row.id))));
|
|
1313
1341
|
for (const row of freshPreparedInputs)
|
|
1314
1342
|
contextPlan.mark('materials', String(row.id), true);
|
|
1315
1343
|
contextPlan.mark('materials', receipt.inputId, true);
|
|
1316
1344
|
const intakeValue = (value) => value ? { mode: value.mode, deferredDispatch: value.deferredDispatch,
|
|
1317
1345
|
preparation: value.preparation, inputIds: value.inputIds, task_id: value.task_id, resolution: value.resolution } : null;
|
|
1318
1346
|
const pendingState = intakeValue(prepared);
|
|
1319
|
-
const
|
|
1347
|
+
const pendingDelta = contextPlan.select('intake', [{ id: 'pending', value: pendingState }], row => row.id);
|
|
1348
|
+
const pendingChanges = replayPending ? [{ id: 'pending', value: pendingState }] : pendingDelta;
|
|
1320
1349
|
if (!semantic && input.skill && input.modality !== 'live_voice' && !channelSpeech && !visualInput.images.length && !visualInput.unavailable.length) {
|
|
1321
1350
|
const task = this.tasks.spawn({ ...capabilities, ...receipt, ...decision, principalId: input.scope.principalId,
|
|
1322
1351
|
model: options.model ?? this.agent.claude.model, actionId: `skill:${receipt.inputId}` }, {
|
|
@@ -1464,7 +1493,7 @@ class AgentOrchestrationRuntime {
|
|
|
1464
1493
|
return;
|
|
1465
1494
|
if (!intakeChoice || intakeChoice.mode === 'wait' || intakeChoice.mode === 'resolve' || !acknowledgementReady)
|
|
1466
1495
|
throw new types_2.OrchestrationError('ACKNOWLEDGEMENT_REQUIRED');
|
|
1467
|
-
if (tool === 'task_spawn' && preparedInputs.length)
|
|
1496
|
+
if (tool === 'task_spawn' && !args.gateway_target && preparedInputs.length)
|
|
1468
1497
|
args.context_refs = [...new Set([...(Array.isArray(args.context_refs) ? args.context_refs : []), ...preparedRefs, ...preparedInputs.map(row => String(row.id))])];
|
|
1469
1498
|
if (intakeChoice.mode === 'update' && (tool === 'task_spawn' || args.task_id !== intakeChoice.task_id)) {
|
|
1470
1499
|
const attempt = attemptedTaskActions.get(actionId);
|
|
@@ -1658,14 +1687,18 @@ class AgentOrchestrationRuntime {
|
|
|
1658
1687
|
await this.flushHistory();
|
|
1659
1688
|
return display;
|
|
1660
1689
|
}
|
|
1690
|
+
let unsafeToReplay = false;
|
|
1661
1691
|
agentSession.on('output', (0, tool_activity_1.toolActivity)(event => {
|
|
1692
|
+
if (event.type === 'tool_use' && !/^(StructuredOutput|mcp__gateway__(conversation_intake|capabilities_list|memory_get|memory_search|task_status))$/.test(event.name))
|
|
1693
|
+
unsafeToReplay = true;
|
|
1662
1694
|
this.store.transaction(() => this.store.appendEvent(receipt.conversationId, internalReview ? 'progress.review.tool' : 'tool.activity', { ...event, responseId: decision.responseId, role: 'agent' }));
|
|
1663
1695
|
if (!internalReview)
|
|
1664
1696
|
options.onTool?.(event);
|
|
1665
1697
|
}));
|
|
1698
|
+
const bufferChat = semantic && this.config.conversation.inputDebounceMs > 0 && (0, input_batch_1.batchableInput)(input);
|
|
1666
1699
|
let rawDisplay = '', structuredStarted = false;
|
|
1667
1700
|
const displayChunk = (chunk) => {
|
|
1668
|
-
if (internalReview || questionReview)
|
|
1701
|
+
if (internalReview || questionReview || bufferChat || recoveryInputId)
|
|
1669
1702
|
return; // Buffer until the notify/silence decision is final.
|
|
1670
1703
|
if (semantic && (intakeChoice?.mode === 'wait' || intakeDeferred || acknowledgementId))
|
|
1671
1704
|
return;
|
|
@@ -1721,6 +1754,28 @@ class AgentOrchestrationRuntime {
|
|
|
1721
1754
|
}
|
|
1722
1755
|
catch { /* Provider bookkeeping cannot invalidate a completed inference. */ }
|
|
1723
1756
|
}
|
|
1757
|
+
const committedAction = this.store.get('SELECT action_id FROM task_commands WHERE decision_id=? LIMIT 1', decision.decisionId);
|
|
1758
|
+
const supersededCount = Number(this.store.get("SELECT count(*) n FROM conversation_events WHERE conversation_id=? AND type='response.superseded' AND json_extract(payload_json,'$.payload.inputId')=?", receipt.conversationId, decision.inputIds[0])?.n ?? 0);
|
|
1759
|
+
// Supersede only when the batcher would now absorb newer input into this
|
|
1760
|
+
// batch; an incompatible follow-up gets its own turn without re-inference.
|
|
1761
|
+
const batchGrows = () => {
|
|
1762
|
+
const first = this.store.get('SELECT * FROM conversation_inputs WHERE id=?', decision.inputIds[0]);
|
|
1763
|
+
return !!first && (0, input_batch_1.inputBatch)(this.store, first, this.batchDebounceMs(), this.config.conversation.inputMaxWaitMs, decision.inputIds)
|
|
1764
|
+
.inputIds.some(id => !decision.inputIds.includes(id));
|
|
1765
|
+
};
|
|
1766
|
+
if (bufferChat && newerInputPending() && batchGrows() && !response.interrupted && !active.stopping && !acknowledgementId && !committedAction && !unsafeToReplay && supersededCount < 2) {
|
|
1767
|
+
this.store.compose(() => {
|
|
1768
|
+
this.decisions.finish(decision, '', 'interrupted', undefined, false);
|
|
1769
|
+
for (const id of decision.inputIds)
|
|
1770
|
+
this.store.run("UPDATE conversation_inputs SET status='accepted' WHERE id=?", id);
|
|
1771
|
+
this.store.appendEvent(receipt.conversationId, 'response.superseded', { responseId: decision.responseId, inputId: decision.inputIds[0], inputIds: decision.inputIds });
|
|
1772
|
+
});
|
|
1773
|
+
// No user-visible answer or task action was committed. Re-read canonical
|
|
1774
|
+
// inputs with the newer messages; do not checkpoint discarded context.
|
|
1775
|
+
contextPlan.invalidate();
|
|
1776
|
+
await this.flushHistory();
|
|
1777
|
+
return '';
|
|
1778
|
+
}
|
|
1724
1779
|
if (!response.interrupted) {
|
|
1725
1780
|
// A completed CLI turn has consumed its tool results. Failed/interrupted
|
|
1726
1781
|
// turns never advance this checkpoint, so committed receipts can recover.
|
|
@@ -1806,7 +1861,20 @@ class AgentOrchestrationRuntime {
|
|
|
1806
1861
|
: 'The requested task was not started or updated. Please try again.';
|
|
1807
1862
|
surfaces.spoken = '';
|
|
1808
1863
|
}
|
|
1809
|
-
const
|
|
1864
|
+
const dispatchCommitted = this.store.get("SELECT action_id FROM task_commands WHERE decision_id=? AND command_type IN ('spawn','update','answer') LIMIT 1", decision.decisionId);
|
|
1865
|
+
if (semantic && !response.interrupted && !active.stopping && intakeChoice && ['ready', 'update'].includes(intakeChoice.mode) && !dispatchCommitted)
|
|
1866
|
+
this.intake.deferDispatch(receipt.inputId);
|
|
1867
|
+
const unresolved = semantic && this.intake.context(receipt.conversationId, input.scope.principalId, String(admitted.binding_id));
|
|
1868
|
+
const recoveryFailed = Boolean(recoveryInputId && unresolved?.deferredDispatch && unresolved.mode !== 'wait' && !response.interrupted && !active.stopping && !newerInputPending());
|
|
1869
|
+
if (recoveryFailed) {
|
|
1870
|
+
const thai = /[\u0E00-\u0E7F]/.test(input.text + String(unresolved && unresolved.preparation) + preparedInputs.map(row => row.text).join('') + response.text);
|
|
1871
|
+
surfaces.display = thai
|
|
1872
|
+
? 'ระบบยังจัดการคำขอค้างไม่สำเร็จ: agent จบการกู้คืนโดยไม่ได้ยืนยันว่างานถูกส่งต่อหรือปิดเรื่องแล้ว คำขอเดิมยังถูกเก็บไว้และยังไม่ถือว่าเสร็จค่ะ'
|
|
1873
|
+
: 'The agent ended recovery without confirming that the pending request was dispatched or resolved. The request is still retained and is not complete.';
|
|
1874
|
+
surfaces.spoken = '';
|
|
1875
|
+
this.store.transaction(() => this.store.appendEvent(receipt.conversationId, 'response.dispatch_unresolved', { responseId: decision.responseId, inputId: receipt.inputId }));
|
|
1876
|
+
}
|
|
1877
|
+
const intakeSilent = !recoveryFailed && semantic && !uncommittedDispatch && (intakeChoice?.mode === 'wait' || intakeDeferred || (acknowledgementId && unresolved?.deferredDispatch && !dispatchCommitted) || (acknowledgementId && this.store.get("SELECT action_id FROM task_commands WHERE decision_id=? AND command_type IN ('spawn','update','answer') LIMIT 1", decision.decisionId)));
|
|
1810
1878
|
if (intakeSilent) {
|
|
1811
1879
|
// A receipt/preparation turn has not reported older task results. Keep
|
|
1812
1880
|
// their notifications (and attachments) available to the next report.
|
|
@@ -1826,7 +1894,7 @@ class AgentOrchestrationRuntime {
|
|
|
1826
1894
|
for (const image of endScreenshots) {
|
|
1827
1895
|
(0, computer_end_screenshot_1.attachComputerEndScreenshot)(this.store, (0, path_1.join)(this.agent.workspace, '../..'), { ...image, responseId: decision.responseId, principalId: input.scope.principalId, conversationId: receipt.conversationId });
|
|
1828
1896
|
}
|
|
1829
|
-
this.decisions.finish(decision, display, response.interrupted ? 'interrupted' : 'completed', channelSpeech && !silent ? taskSpeech || surfaces.spoken : undefined, !active.stopping && !silent);
|
|
1897
|
+
this.decisions.finish(decision, display, response.interrupted ? 'interrupted' : recoveryFailed ? 'failed' : 'completed', channelSpeech && !silent ? taskSpeech || surfaces.spoken : undefined, !active.stopping && !silent);
|
|
1830
1898
|
if (active.notification && !response.interrupted) {
|
|
1831
1899
|
const batch = this.store.get('SELECT COUNT(*)-COUNT(DISTINCT task_id) n FROM notifications WHERE decision_id=?', decision.decisionId);
|
|
1832
1900
|
try {
|