@agent-native/core 0.208.0 → 0.209.0-nightly-20261014070126
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/agent-native.eject.json +1 -0
- package/dist/agent/approval-key.d.ts +2 -0
- package/dist/agent/approval-key.js +12 -0
- package/dist/agent/context-xray/tokenize.js +12 -3
- package/dist/agent/engine/translate-anthropic.js +4 -0
- package/dist/agent/engine/types.d.ts +2 -0
- package/dist/agent/production-agent.d.ts +20 -5
- package/dist/agent/production-agent.js +227 -34
- package/dist/agent/run-manager.js +57 -11
- package/dist/agent/run-store.d.ts +10 -0
- package/dist/agent/run-store.js +49 -4
- package/dist/agent/thread-data-builder.d.ts +2 -0
- package/dist/agent/thread-data-builder.js +288 -14
- package/dist/agent/tool-approval-store.d.ts +3 -1
- package/dist/agent/tool-approval-store.js +26 -12
- package/dist/agent/tool-call-journal.d.ts +1 -1
- package/dist/agent/tool-call-journal.js +5 -3
- package/dist/agent/types.d.ts +7 -0
- package/dist/client/chat/agentkit-agent-native.js +18 -0
- package/dist/client/chat/agentkit-protocol.js +56 -5
- package/dist/client/chat/runtime.d.ts +10 -0
- package/dist/client/chat/runtime.js +257 -26
- package/dist/client/sse-event-processor.d.ts +22 -0
- package/dist/client/sse-event-processor.js +91 -11
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/connections/catalog.d.ts +24 -1
- package/dist/connections/catalog.js +12 -0
- package/dist/data-programs/schema.d.ts +1 -0
- package/dist/data-programs/schema.js +3 -0
- package/dist/data-programs/store.js +2 -1
- package/dist/deploy/build.js +16 -14
- package/dist/eject/workspace-connections.js +1 -0
- package/dist/extensions/fetch-tool.js +114 -23
- package/dist/extensions/schema.d.ts +1 -0
- package/dist/extensions/schema.js +3 -0
- package/dist/extensions/store.js +2 -1
- package/dist/extensions/web-content.d.ts +5 -1
- package/dist/extensions/web-content.js +24 -6
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
- package/dist/provider-api/actions/provider-api.d.ts +9 -9
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/provider-api/index.d.ts +2 -0
- package/dist/provider-api/index.js +95 -12
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/server/agent-engine-default-model-route.d.ts +2 -2
- package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
- package/dist/server/auth.js +1 -0
- package/dist/server/core-routes-plugin.js +1 -0
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.js +2 -1
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/server/workspace-provider-oauth.d.ts +1 -1
- package/dist/server/workspace-provider-oauth.js +2 -0
- package/dist/shared/context-status.js +1 -1
- package/dist/shared/optional-peer-ssr.d.ts +2 -0
- package/dist/shared/optional-peer-ssr.js +123 -0
- package/dist/shared/tool-inputs.d.ts +2 -0
- package/dist/shared/tool-inputs.js +56 -0
- package/dist/sharing/actions/list-resource-shares.d.ts +1 -1
- package/dist/tracking/index.d.ts +1 -0
- package/dist/tracking/index.js +1 -0
- package/dist/vite/client.js +46 -3
- package/dist/workspace-connections/store.d.ts +3 -1
- package/dist/workspace-connections/store.js +18 -8
- package/dist/workspace-files/constants.d.ts +3 -0
- package/dist/workspace-files/constants.js +3 -0
- package/dist/workspace-files/store.d.ts +2 -3
- package/dist/workspace-files/store.js +2 -3
- package/docs/content/automations.mdx +19 -13
- package/package.json +3 -3
- package/src/eject/workspace-connections.ts +1 -0
|
@@ -4,6 +4,8 @@ import { isCredentialGapCodeAgentEvent, normalizeCodeAgentTranscript, } from "..
|
|
|
4
4
|
import { stripAgentChatContextFromMessage } from "../shared/agent-chat-context.js";
|
|
5
5
|
import { RUN_NOT_STARTED_METADATA_KEY, } from "../shared/agent-chat-run-not-started.js";
|
|
6
6
|
import { parseBase64DataUrl } from "../shared/data-url.js";
|
|
7
|
+
import { toolInputFingerprint, toolInputsMatch, } from "../shared/tool-inputs.js";
|
|
8
|
+
import { approvalKeyForHistory } from "./approval-key.js";
|
|
7
9
|
import { BUILDER_GATEWAY_INTERNAL_ERROR_CODE } from "./engine/error-detail.js";
|
|
8
10
|
import { INTERRUPTED_TOOL_RESULT_MARKER as INTERRUPTED_TOOL_RESULT, stringifyToolUseInputForGateway, } from "./engine/translate-anthropic.js";
|
|
9
11
|
import { parseFollowUpSuggestions } from "./follow-up-suggestions.js";
|
|
@@ -138,6 +140,7 @@ function isInternalContinuationError(event) {
|
|
|
138
140
|
export function buildAssistantMessage(events, runId, options = {}) {
|
|
139
141
|
const content = [];
|
|
140
142
|
const explicitUnknownOutcomes = new Set();
|
|
143
|
+
const approvalPauseCandidates = new Set();
|
|
141
144
|
let toolCallCounter = 0;
|
|
142
145
|
let runError = null;
|
|
143
146
|
let endedAtInternalContinuationBoundary = false;
|
|
@@ -203,16 +206,17 @@ export function buildAssistantMessage(events, runId, options = {}) {
|
|
|
203
206
|
continue;
|
|
204
207
|
}
|
|
205
208
|
if (event.type === "approval_required") {
|
|
206
|
-
const matchingIndex = findApprovalToolCallIndex(content, event.tool ?? "unknown", event.toolCallId);
|
|
209
|
+
const matchingIndex = findApprovalToolCallIndex(content, event.tool ?? "unknown", event.toolCallId, event.input);
|
|
207
210
|
const part = content[matchingIndex];
|
|
208
211
|
if (part?.type === "tool-call") {
|
|
209
212
|
part.approval = {
|
|
210
|
-
approvalKey: event.approvalKey,
|
|
213
|
+
approvalKey: approvalKeyForHistory(event.approvalKey),
|
|
211
214
|
...(event.askId ? { askId: event.askId } : {}),
|
|
212
215
|
...(event.allowPersistentApproval === false
|
|
213
216
|
? { allowPersistentApproval: false }
|
|
214
217
|
: {}),
|
|
215
218
|
};
|
|
219
|
+
approvalPauseCandidates.add(part);
|
|
216
220
|
}
|
|
217
221
|
continue;
|
|
218
222
|
}
|
|
@@ -244,6 +248,17 @@ export function buildAssistantMessage(events, runId, options = {}) {
|
|
|
244
248
|
const part = content[matchingIndex];
|
|
245
249
|
if (part?.type === "tool-call") {
|
|
246
250
|
part.result = event.result ?? "";
|
|
251
|
+
// Older journals have approval_required but no pause marker on tool_done.
|
|
252
|
+
const inferredLegacyPause = event.approvalPause === undefined &&
|
|
253
|
+
approvalPauseCandidates.has(part);
|
|
254
|
+
if (event.approvalPause === true || inferredLegacyPause) {
|
|
255
|
+
part.approvalPause = true;
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
delete part.approvalPause;
|
|
259
|
+
delete part.approval;
|
|
260
|
+
}
|
|
261
|
+
approvalPauseCandidates.delete(part);
|
|
247
262
|
if (event.isError !== undefined)
|
|
248
263
|
part.isError = event.isError;
|
|
249
264
|
if (event.outcomeUnknown === true) {
|
|
@@ -484,7 +499,7 @@ function normalizeAttachmentIdentity(attachments) {
|
|
|
484
499
|
contentType: att?.contentType,
|
|
485
500
|
}));
|
|
486
501
|
}
|
|
487
|
-
function findApprovalToolCallIndex(content, toolName, toolCallId) {
|
|
502
|
+
function findApprovalToolCallIndex(content, toolName, toolCallId, approvalInput) {
|
|
488
503
|
if (toolCallId) {
|
|
489
504
|
for (let i = content.length - 1; i >= 0; i--) {
|
|
490
505
|
const part = content[i];
|
|
@@ -501,21 +516,26 @@ function findApprovalToolCallIndex(content, toolName, toolCallId) {
|
|
|
501
516
|
part.toolName === toolName &&
|
|
502
517
|
part.result === undefined &&
|
|
503
518
|
typeof part.toolCallId === "string" &&
|
|
504
|
-
|
|
519
|
+
/(?:^|:)tc_\d+$/.test(part.toolCallId) &&
|
|
520
|
+
toolInputsMatch(part.args, approvalInput)) {
|
|
505
521
|
readerLocalCandidates.push(i);
|
|
506
522
|
}
|
|
507
523
|
}
|
|
508
524
|
return readerLocalCandidates.length === 1 ? readerLocalCandidates[0] : -1;
|
|
509
525
|
}
|
|
510
|
-
|
|
526
|
+
const matchingInputCandidates = [];
|
|
527
|
+
for (let i = 0; i < content.length; i += 1) {
|
|
511
528
|
const part = content[i];
|
|
512
529
|
if (part.type === "tool-call" &&
|
|
513
530
|
part.toolName === toolName &&
|
|
514
|
-
part.result === undefined
|
|
515
|
-
|
|
531
|
+
part.result === undefined &&
|
|
532
|
+
toolInputsMatch(part.args, approvalInput)) {
|
|
533
|
+
matchingInputCandidates.push(i);
|
|
516
534
|
}
|
|
517
535
|
}
|
|
518
|
-
return
|
|
536
|
+
return matchingInputCandidates.length === 1
|
|
537
|
+
? matchingInputCandidates[0]
|
|
538
|
+
: -1;
|
|
519
539
|
}
|
|
520
540
|
function normalizeContentForFingerprint(content) {
|
|
521
541
|
if (!Array.isArray(content))
|
|
@@ -853,6 +873,12 @@ function assistantReplayContent(message, text) {
|
|
|
853
873
|
toolName: name,
|
|
854
874
|
toolInput: stringifyToolUseInputForGateway(input),
|
|
855
875
|
...result,
|
|
876
|
+
...(part.approvalPause === true ? { approvalPause: true } : {}),
|
|
877
|
+
...(typeof part.approval?.askId === "string"
|
|
878
|
+
? { approvalAskId: part.approval.askId }
|
|
879
|
+
: typeof part.approvalAskId === "string"
|
|
880
|
+
? { approvalAskId: part.approvalAskId }
|
|
881
|
+
: {}),
|
|
856
882
|
...(part.isError === true || result.outcome === "unknown"
|
|
857
883
|
? { isError: true }
|
|
858
884
|
: {}),
|
|
@@ -1327,7 +1353,227 @@ function snapshotAssistantTextKey(message, runIds) {
|
|
|
1327
1353
|
message.parts.map((part) => [part.text, part.format ?? null]),
|
|
1328
1354
|
]);
|
|
1329
1355
|
}
|
|
1330
|
-
function
|
|
1356
|
+
function snapshotAssistantText(message) {
|
|
1357
|
+
if (message?.role !== "assistant" ||
|
|
1358
|
+
!Array.isArray(message.parts) ||
|
|
1359
|
+
message.parts.length === 0 ||
|
|
1360
|
+
!message.parts.every((part) => part?.type === "text" && typeof part.text === "string")) {
|
|
1361
|
+
return undefined;
|
|
1362
|
+
}
|
|
1363
|
+
return message.parts.map((part) => part.text).join("");
|
|
1364
|
+
}
|
|
1365
|
+
function removeSupersededAgentKitMessagePrefixes(messages, agentKit, previousAgentKit, incomingAgentKit) {
|
|
1366
|
+
if (!Array.isArray(messages))
|
|
1367
|
+
return undefined;
|
|
1368
|
+
const completedMessagesByRun = new Map();
|
|
1369
|
+
const events = [previousAgentKit, incomingAgentKit, agentKit].flatMap((snapshot) => (Array.isArray(snapshot.events) ? snapshot.events : []));
|
|
1370
|
+
for (const event of events) {
|
|
1371
|
+
const messageId = event?.message?.id;
|
|
1372
|
+
if (event?.type !== "message.completed" ||
|
|
1373
|
+
event.message?.role !== "assistant" ||
|
|
1374
|
+
typeof event.runId !== "string" ||
|
|
1375
|
+
typeof messageId !== "string") {
|
|
1376
|
+
continue;
|
|
1377
|
+
}
|
|
1378
|
+
const messageIds = completedMessagesByRun.get(event.runId) ?? new Set();
|
|
1379
|
+
messageIds.add(messageId);
|
|
1380
|
+
completedMessagesByRun.set(event.runId, messageIds);
|
|
1381
|
+
}
|
|
1382
|
+
if (completedMessagesByRun.size === 0)
|
|
1383
|
+
return messages;
|
|
1384
|
+
const runningRunSnapshots = [previousAgentKit, incomingAgentKit].flatMap((snapshot) => Array.isArray(snapshot.runs)
|
|
1385
|
+
? snapshot.runs.flatMap((run) => run?.status === "running" &&
|
|
1386
|
+
typeof run.id === "string" &&
|
|
1387
|
+
typeof run.activeMessageId === "string" &&
|
|
1388
|
+
typeof run.lastSequence === "number" &&
|
|
1389
|
+
Number.isSafeInteger(run.lastSequence)
|
|
1390
|
+
? [{ run, messages: snapshot.messages }]
|
|
1391
|
+
: [])
|
|
1392
|
+
: []);
|
|
1393
|
+
const removedIds = new Set();
|
|
1394
|
+
for (const run of Array.isArray(agentKit.runs) ? agentKit.runs : []) {
|
|
1395
|
+
if (run?.status !== "completed" ||
|
|
1396
|
+
typeof run.id !== "string" ||
|
|
1397
|
+
typeof run.activeMessageId !== "string" ||
|
|
1398
|
+
typeof run.lastSequence !== "number" ||
|
|
1399
|
+
!Number.isSafeInteger(run.lastSequence)) {
|
|
1400
|
+
continue;
|
|
1401
|
+
}
|
|
1402
|
+
const staleRunningSnapshot = runningRunSnapshots
|
|
1403
|
+
.filter(({ run: candidateRun }) => candidateRun.id === run.id &&
|
|
1404
|
+
candidateRun.activeMessageId !== run.activeMessageId &&
|
|
1405
|
+
candidateRun.lastSequence < run.lastSequence &&
|
|
1406
|
+
!completedMessagesByRun
|
|
1407
|
+
.get(run.id)
|
|
1408
|
+
?.has(candidateRun.activeMessageId))
|
|
1409
|
+
.sort((left, right) => right.run.lastSequence - left.run.lastSequence)[0];
|
|
1410
|
+
if (!staleRunningSnapshot ||
|
|
1411
|
+
!completedMessagesByRun.get(run.id)?.has(run.activeMessageId) ||
|
|
1412
|
+
!events.some((event) => event?.type === "message.completed" &&
|
|
1413
|
+
event.runId === run.id &&
|
|
1414
|
+
event.message?.role === "assistant" &&
|
|
1415
|
+
event.message?.id === run.activeMessageId &&
|
|
1416
|
+
typeof event.sequence === "number" &&
|
|
1417
|
+
Number.isSafeInteger(event.sequence) &&
|
|
1418
|
+
event.sequence > staleRunningSnapshot.run.lastSequence &&
|
|
1419
|
+
event.sequence <= run.lastSequence)) {
|
|
1420
|
+
continue;
|
|
1421
|
+
}
|
|
1422
|
+
const completedIndex = messages.findIndex((entry) => snapshotEntryId(entry, "message") === run.activeMessageId &&
|
|
1423
|
+
entry?.role === "assistant");
|
|
1424
|
+
if (completedIndex === -1)
|
|
1425
|
+
continue;
|
|
1426
|
+
const completedText = snapshotAssistantText(messages[completedIndex]);
|
|
1427
|
+
if (completedText === undefined)
|
|
1428
|
+
continue;
|
|
1429
|
+
const lastUserIndexBefore = (messageIndex) => {
|
|
1430
|
+
for (let index = messageIndex - 1; index >= 0; index--) {
|
|
1431
|
+
if (messages[index]?.role === "user")
|
|
1432
|
+
return index;
|
|
1433
|
+
}
|
|
1434
|
+
return -1;
|
|
1435
|
+
};
|
|
1436
|
+
const lastUserIndex = lastUserIndexBefore(completedIndex);
|
|
1437
|
+
if (lastUserIndex === -1 ||
|
|
1438
|
+
lastUserIndexBefore(messages.findIndex((entry) => snapshotEntryId(entry, "message") ===
|
|
1439
|
+
staleRunningSnapshot.run.activeMessageId)) !== lastUserIndex) {
|
|
1440
|
+
continue;
|
|
1441
|
+
}
|
|
1442
|
+
const candidateId = staleRunningSnapshot.run.activeMessageId;
|
|
1443
|
+
const candidate = Array.isArray(staleRunningSnapshot.messages)
|
|
1444
|
+
? staleRunningSnapshot.messages.find((entry) => snapshotEntryId(entry, "message") === candidateId)
|
|
1445
|
+
: undefined;
|
|
1446
|
+
const candidateIndex = messages.findIndex((entry) => snapshotEntryId(entry, "message") === candidateId);
|
|
1447
|
+
const candidateText = snapshotAssistantText(candidate);
|
|
1448
|
+
if (candidateIndex <= lastUserIndex ||
|
|
1449
|
+
candidateText === undefined ||
|
|
1450
|
+
candidateText.length === 0 ||
|
|
1451
|
+
candidateText.length >= completedText.length ||
|
|
1452
|
+
!completedText.startsWith(candidateText)) {
|
|
1453
|
+
continue;
|
|
1454
|
+
}
|
|
1455
|
+
removedIds.add(candidateId);
|
|
1456
|
+
}
|
|
1457
|
+
return removedIds.size === 0
|
|
1458
|
+
? messages
|
|
1459
|
+
: messages.filter((entry) => {
|
|
1460
|
+
const id = snapshotEntryId(entry, "message");
|
|
1461
|
+
return !id || !removedIds.has(id);
|
|
1462
|
+
});
|
|
1463
|
+
}
|
|
1464
|
+
function isApprovalPauseToolCall(toolCall) {
|
|
1465
|
+
if (toolCall?.metadata?.approvalPause === true)
|
|
1466
|
+
return true;
|
|
1467
|
+
return (typeof toolCall?.output === "string" &&
|
|
1468
|
+
toolCall.output.startsWith("Awaiting") &&
|
|
1469
|
+
toolCall.output.includes("did NOT execute"));
|
|
1470
|
+
}
|
|
1471
|
+
function toolCallHasCompletedSideEffect(toolCall) {
|
|
1472
|
+
return toolCall?.metadata?.completedSideEffect === true;
|
|
1473
|
+
}
|
|
1474
|
+
function toolCallInputValuesMatch(left, right) {
|
|
1475
|
+
if (Object.is(left, right))
|
|
1476
|
+
return true;
|
|
1477
|
+
if (Array.isArray(left) || Array.isArray(right)) {
|
|
1478
|
+
return (Array.isArray(left) &&
|
|
1479
|
+
Array.isArray(right) &&
|
|
1480
|
+
left.length === right.length &&
|
|
1481
|
+
left.every((value, index) => toolCallInputValuesMatch(value, right[index])));
|
|
1482
|
+
}
|
|
1483
|
+
return toolInputsMatch(left, right);
|
|
1484
|
+
}
|
|
1485
|
+
function toolCallInputsMatch(existing, incoming) {
|
|
1486
|
+
const existingInput = existing?.input;
|
|
1487
|
+
const incomingInput = incoming?.input;
|
|
1488
|
+
if (existingInput !== undefined && incomingInput !== undefined) {
|
|
1489
|
+
return toolCallInputValuesMatch(existingInput, incomingInput);
|
|
1490
|
+
}
|
|
1491
|
+
const existingSnapshot = existing?.metadata?.agentKitSnapshot;
|
|
1492
|
+
const incomingSnapshot = incoming?.metadata?.agentKitSnapshot;
|
|
1493
|
+
const existingFingerprint = typeof existingSnapshot?.inputFingerprint === "string"
|
|
1494
|
+
? existingSnapshot.inputFingerprint
|
|
1495
|
+
: existingInput === undefined
|
|
1496
|
+
? undefined
|
|
1497
|
+
: toolInputFingerprint(existingInput);
|
|
1498
|
+
const incomingFingerprint = typeof incomingSnapshot?.inputFingerprint === "string"
|
|
1499
|
+
? incomingSnapshot.inputFingerprint
|
|
1500
|
+
: incomingInput === undefined
|
|
1501
|
+
? undefined
|
|
1502
|
+
: toolInputFingerprint(incomingInput);
|
|
1503
|
+
if (existingFingerprint || incomingFingerprint) {
|
|
1504
|
+
return (typeof existingFingerprint === "string" &&
|
|
1505
|
+
existingFingerprint === incomingFingerprint);
|
|
1506
|
+
}
|
|
1507
|
+
return existingInput === undefined && incomingInput === undefined;
|
|
1508
|
+
}
|
|
1509
|
+
function toolCallIdentityMatches(existing, incoming) {
|
|
1510
|
+
return (typeof existing?.id === "string" &&
|
|
1511
|
+
existing.id === incoming?.id &&
|
|
1512
|
+
typeof existing?.name === "string" &&
|
|
1513
|
+
existing.name === incoming?.name &&
|
|
1514
|
+
toolCallInputsMatch(existing, incoming));
|
|
1515
|
+
}
|
|
1516
|
+
function toolCallsMatch(existing, incoming) {
|
|
1517
|
+
return (existing?.status === "completed" &&
|
|
1518
|
+
incoming?.status === "completed" &&
|
|
1519
|
+
toolCallIdentityMatches(existing, incoming));
|
|
1520
|
+
}
|
|
1521
|
+
function isIncomingToolCallRunNewer(existing, incoming, existingRuns, incomingRuns) {
|
|
1522
|
+
const existingRunId = existing?.runId;
|
|
1523
|
+
const incomingRunId = incoming?.runId;
|
|
1524
|
+
if (typeof incomingRunId !== "string")
|
|
1525
|
+
return false;
|
|
1526
|
+
if (typeof existingRunId !== "string")
|
|
1527
|
+
return true;
|
|
1528
|
+
const findRun = (runs, runId) => Array.isArray(runs) ? runs.find((run) => run?.id === runId) : undefined;
|
|
1529
|
+
const existingRun = findRun(existingRuns, existingRunId);
|
|
1530
|
+
const incomingRun = findRun(incomingRuns, incomingRunId);
|
|
1531
|
+
if (existingRunId === incomingRunId) {
|
|
1532
|
+
return (Number.isSafeInteger(existingRun?.lastSequence) &&
|
|
1533
|
+
Number.isSafeInteger(incomingRun?.lastSequence) &&
|
|
1534
|
+
incomingRun.lastSequence > existingRun.lastSequence);
|
|
1535
|
+
}
|
|
1536
|
+
const existingStartedAt = Date.parse(existingRun?.startedAt ?? "");
|
|
1537
|
+
const incomingStartedAt = Date.parse(incomingRun?.startedAt ?? "");
|
|
1538
|
+
return (Number.isFinite(existingStartedAt) &&
|
|
1539
|
+
Number.isFinite(incomingStartedAt) &&
|
|
1540
|
+
incomingStartedAt > existingStartedAt);
|
|
1541
|
+
}
|
|
1542
|
+
function prefersApprovalReplaySnapshot(existing, incoming, existingRuns, incomingRuns) {
|
|
1543
|
+
if (!toolCallsMatch(existing, incoming))
|
|
1544
|
+
return false;
|
|
1545
|
+
const incomingIsNewer = isIncomingToolCallRunNewer(existing, incoming, existingRuns, incomingRuns);
|
|
1546
|
+
return ((isApprovalPauseToolCall(existing) &&
|
|
1547
|
+
toolCallHasCompletedSideEffect(incoming) &&
|
|
1548
|
+
incomingIsNewer) ||
|
|
1549
|
+
(toolCallHasCompletedSideEffect(existing) &&
|
|
1550
|
+
isApprovalPauseToolCall(incoming) &&
|
|
1551
|
+
incomingIsNewer));
|
|
1552
|
+
}
|
|
1553
|
+
function incomingRunIsNotProvenNewer(existing, incoming, existingRuns, incomingRuns) {
|
|
1554
|
+
const existingRunId = existing?.runId;
|
|
1555
|
+
const incomingRunId = incoming?.runId;
|
|
1556
|
+
if (typeof existingRunId !== "string" && typeof incomingRunId !== "string") {
|
|
1557
|
+
return false;
|
|
1558
|
+
}
|
|
1559
|
+
if (typeof existingRunId !== "string" || typeof incomingRunId !== "string") {
|
|
1560
|
+
return true;
|
|
1561
|
+
}
|
|
1562
|
+
const findRun = (runs, runId) => Array.isArray(runs) ? runs.find((run) => run?.id === runId) : undefined;
|
|
1563
|
+
const existingRun = findRun(existingRuns, existingRunId);
|
|
1564
|
+
const incomingRun = findRun(incomingRuns, incomingRunId);
|
|
1565
|
+
if (existingRunId === incomingRunId) {
|
|
1566
|
+
return !(Number.isSafeInteger(existingRun?.lastSequence) &&
|
|
1567
|
+
Number.isSafeInteger(incomingRun?.lastSequence) &&
|
|
1568
|
+
incomingRun.lastSequence > existingRun.lastSequence);
|
|
1569
|
+
}
|
|
1570
|
+
const existingStartedAt = Date.parse(existingRun?.startedAt ?? "");
|
|
1571
|
+
const incomingStartedAt = Date.parse(incomingRun?.startedAt ?? "");
|
|
1572
|
+
return (!Number.isFinite(existingStartedAt) ||
|
|
1573
|
+
!Number.isFinite(incomingStartedAt) ||
|
|
1574
|
+
incomingStartedAt <= existingStartedAt);
|
|
1575
|
+
}
|
|
1576
|
+
function preferIncomingSnapshotEntry(kind, existing, incoming, existingRuns, incomingRuns) {
|
|
1331
1577
|
if (kind === "message") {
|
|
1332
1578
|
const rank = (message) => message.status === "complete" ? 2 : message.status === "error" ? 1 : 0;
|
|
1333
1579
|
if (rank(existing) !== rank(incoming))
|
|
@@ -1340,6 +1586,11 @@ function preferIncomingSnapshotEntry(kind, existing, incoming) {
|
|
|
1340
1586
|
return textLength(incoming) > textLength(existing);
|
|
1341
1587
|
}
|
|
1342
1588
|
if (kind === "toolCall") {
|
|
1589
|
+
if (existing.status === "running" &&
|
|
1590
|
+
incoming.status !== "running" &&
|
|
1591
|
+
incomingRunIsNotProvenNewer(existing, incoming, existingRuns, incomingRuns)) {
|
|
1592
|
+
return false;
|
|
1593
|
+
}
|
|
1343
1594
|
return existing.status === "running" && incoming.status !== "running";
|
|
1344
1595
|
}
|
|
1345
1596
|
return (existing.widget?.state === "active" && incoming.widget?.state !== "active");
|
|
@@ -1357,7 +1608,7 @@ function withToolCallMessageIdFallback(preferred, fallback) {
|
|
|
1357
1608
|
}
|
|
1358
1609
|
return preferred;
|
|
1359
1610
|
}
|
|
1360
|
-
function mergeAgentKitHistoryArray(existing, incoming, kind, existingMessageRunIds, incomingMessageRunIds, promptRunIds) {
|
|
1611
|
+
function mergeAgentKitHistoryArray(existing, incoming, kind, existingMessageRunIds, incomingMessageRunIds, promptRunIds, existingRuns, incomingRuns) {
|
|
1361
1612
|
if (!Array.isArray(existing) && !Array.isArray(incoming))
|
|
1362
1613
|
return undefined;
|
|
1363
1614
|
const merged = Array.isArray(existing) ? [...existing] : [];
|
|
@@ -1400,11 +1651,13 @@ function mergeAgentKitHistoryArray(existing, incoming, kind, existingMessageRunI
|
|
|
1400
1651
|
matchedAssistantTextPositions.add(index);
|
|
1401
1652
|
if (id && idIndex === undefined)
|
|
1402
1653
|
positions.set(id, index);
|
|
1403
|
-
const preferIncoming = preferIncomingSnapshotEntry(kind, merged[index], entry);
|
|
1654
|
+
const preferIncoming = preferIncomingSnapshotEntry(kind, merged[index], entry, existingRuns, incomingRuns);
|
|
1655
|
+
const preferApprovedReplay = kind === "toolCall" &&
|
|
1656
|
+
prefersApprovalReplaySnapshot(merged[index], entry, existingRuns, incomingRuns);
|
|
1404
1657
|
const preferCurrentMessageId = kind === "message" &&
|
|
1405
1658
|
textIndex !== undefined &&
|
|
1406
|
-
!preferIncomingSnapshotEntry(kind, entry, merged[index]);
|
|
1407
|
-
if (preferIncoming || preferCurrentMessageId) {
|
|
1659
|
+
!preferIncomingSnapshotEntry(kind, entry, merged[index], incomingRuns, existingRuns);
|
|
1660
|
+
if (preferIncoming || preferApprovedReplay || preferCurrentMessageId) {
|
|
1408
1661
|
merged[index] =
|
|
1409
1662
|
kind === "toolCall"
|
|
1410
1663
|
? withToolCallMessageIdFallback(entry, merged[index])
|
|
@@ -2495,7 +2748,7 @@ function mergeAgentKitHistory(existing, incoming, promptRunIds, onAnnotationConf
|
|
|
2495
2748
|
["toolCalls", "toolCall"],
|
|
2496
2749
|
["widgets", "widget"],
|
|
2497
2750
|
]) {
|
|
2498
|
-
const entries = mergeAgentKitHistoryArray(previous[key], next[key], kind, existingMessageRunIds, incomingMessageRunIds, promptRunIds);
|
|
2751
|
+
const entries = mergeAgentKitHistoryArray(previous[key], next[key], kind, existingMessageRunIds, incomingMessageRunIds, promptRunIds, previous.runs, next.runs);
|
|
2499
2752
|
if (entries)
|
|
2500
2753
|
merged[key] = entries;
|
|
2501
2754
|
}
|
|
@@ -2569,6 +2822,9 @@ function mergeAgentKitHistory(existing, incoming, promptRunIds, onAnnotationConf
|
|
|
2569
2822
|
merged._eventRunWatermarks = previous._eventRunWatermarks;
|
|
2570
2823
|
}
|
|
2571
2824
|
}
|
|
2825
|
+
const messages = removeSupersededAgentKitMessagePrefixes(merged.messages, merged, previous, next);
|
|
2826
|
+
if (messages)
|
|
2827
|
+
merged.messages = messages;
|
|
2572
2828
|
delete merged._snapshotDelta;
|
|
2573
2829
|
delete merged.eventRunReplacements;
|
|
2574
2830
|
delete merged.eventRunSnapshotWatermarks;
|
|
@@ -3131,6 +3387,24 @@ function assistantContentWeight(content) {
|
|
|
3131
3387
|
function appendFoldedContent(existing, incoming) {
|
|
3132
3388
|
const merged = existing.map((p) => ({ ...p }));
|
|
3133
3389
|
for (const part of incoming) {
|
|
3390
|
+
if (part?.type === "tool-call" && part.result !== undefined) {
|
|
3391
|
+
let pausedCallIndex = -1;
|
|
3392
|
+
for (let index = merged.length - 1; index >= 0; index -= 1) {
|
|
3393
|
+
const candidate = merged[index];
|
|
3394
|
+
if (candidate?.type === "tool-call" &&
|
|
3395
|
+
candidate.approvalPause === true &&
|
|
3396
|
+
candidate.toolCallId === part.toolCallId &&
|
|
3397
|
+
candidate.toolName === part.toolName &&
|
|
3398
|
+
toolInputsMatch(candidate.args, part.args)) {
|
|
3399
|
+
pausedCallIndex = index;
|
|
3400
|
+
break;
|
|
3401
|
+
}
|
|
3402
|
+
}
|
|
3403
|
+
if (pausedCallIndex !== -1) {
|
|
3404
|
+
merged[pausedCallIndex] = { ...part };
|
|
3405
|
+
continue;
|
|
3406
|
+
}
|
|
3407
|
+
}
|
|
3134
3408
|
const last = merged[merged.length - 1];
|
|
3135
3409
|
if (part?.type === "text" &&
|
|
3136
3410
|
typeof part.text === "string" &&
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { hashAgentToolApprovalKey } from "./approval-key.js";
|
|
1
2
|
export declare function ensureAgentToolApprovalTable(): Promise<void>;
|
|
2
3
|
export declare function ensureAgentToolApprovalPolicyTable(): Promise<void>;
|
|
3
4
|
export interface AgentToolApprovalBinding {
|
|
@@ -8,9 +9,9 @@ export interface AgentToolApprovalBinding {
|
|
|
8
9
|
toolName: string;
|
|
9
10
|
callId: string;
|
|
10
11
|
approvalKey: string;
|
|
12
|
+
approvalId?: string;
|
|
11
13
|
expiresAt?: number;
|
|
12
14
|
}
|
|
13
|
-
export declare function hashAgentToolApprovalKey(approvalKey: string): string;
|
|
14
15
|
export interface AgentToolApprovalPolicyBinding {
|
|
15
16
|
ownerEmail: string;
|
|
16
17
|
orgId?: string | null;
|
|
@@ -27,6 +28,7 @@ export declare function resolveAgentToolApprovalTurnId(binding: {
|
|
|
27
28
|
threadId?: string | null;
|
|
28
29
|
requestedTurnId?: string | null;
|
|
29
30
|
approvalKeys: readonly string[];
|
|
31
|
+
approvalId?: string;
|
|
30
32
|
}): Promise<string | null>;
|
|
31
33
|
export declare function createAgentToolApproval(binding: AgentToolApprovalBinding): Promise<string>;
|
|
32
34
|
/**
|
|
@@ -2,7 +2,9 @@ import { createHash, randomUUID } from "node:crypto";
|
|
|
2
2
|
import { getDbExec } from "../db/client.js";
|
|
3
3
|
import { ensureIndexExists, ensureTableExists } from "../db/ddl-guard.js";
|
|
4
4
|
import { retainRequestDbPoolScope } from "../db/request-pool-context.js";
|
|
5
|
+
import { hashAgentToolApprovalKey } from "./approval-key.js";
|
|
5
6
|
import { AGENT_TOOL_APPROVAL_INDEX_SQL, AGENT_TOOL_APPROVAL_LOGICAL_INDEX_SQL, AGENT_TOOL_APPROVAL_POLICY_INDEX_SQL, AGENT_TOOL_APPROVAL_POLICY_TABLE_SQL, AGENT_TOOL_APPROVAL_RECOVERY_INDEX_SQL, AGENT_TOOL_APPROVAL_TABLE_SQL, } from "./tool-approval-migrations.js";
|
|
7
|
+
export { hashAgentToolApprovalKey } from "./approval-key.js";
|
|
6
8
|
const APPROVAL_TTL_MS = 60 * 60_000;
|
|
7
9
|
const APPROVAL_CLEANUP_AGE_MS = 24 * 60 * 60_000;
|
|
8
10
|
let initPromise;
|
|
@@ -35,9 +37,6 @@ export async function ensureAgentToolApprovalPolicyTable() {
|
|
|
35
37
|
}
|
|
36
38
|
return policyInitPromise;
|
|
37
39
|
}
|
|
38
|
-
export function hashAgentToolApprovalKey(approvalKey) {
|
|
39
|
-
return createHash("sha256").update(approvalKey).digest("hex");
|
|
40
|
-
}
|
|
41
40
|
function normalizeApprovalPolicyBinding(binding) {
|
|
42
41
|
const ownerEmail = binding.ownerEmail.trim().toLowerCase();
|
|
43
42
|
const toolName = binding.toolName.trim();
|
|
@@ -85,7 +84,7 @@ export async function isAgentToolAlwaysAllowed(input) {
|
|
|
85
84
|
const result = await getDbExec().execute({
|
|
86
85
|
sql: `SELECT 1 FROM agent_tool_approval_policies
|
|
87
86
|
WHERE owner_email = ?
|
|
88
|
-
AND ((org_id IS NULL AND CAST(? AS TEXT) IS NULL) OR org_id = ?)
|
|
87
|
+
AND ((org_id IS NULL AND CAST(? AS TEXT) IS NULL) OR org_id = CAST(? AS TEXT))
|
|
89
88
|
AND tool_name = ?
|
|
90
89
|
AND enabled = TRUE
|
|
91
90
|
LIMIT 1`,
|
|
@@ -101,12 +100,15 @@ export async function resolveAgentToolApprovalTurnId(binding) {
|
|
|
101
100
|
const now = Date.now();
|
|
102
101
|
const hashes = approvalKeys.map(hashAgentToolApprovalKey);
|
|
103
102
|
const placeholders = hashes.map(() => "?").join(", ");
|
|
103
|
+
const exactApprovalFilter = binding.approvalId ? "AND id = ?" : "";
|
|
104
|
+
const approvalIdArgs = binding.approvalId ? [binding.approvalId] : [];
|
|
104
105
|
const result = await getDbExec().execute({
|
|
105
106
|
sql: `SELECT turn_id FROM agent_tool_approvals
|
|
106
107
|
WHERE owner_email = ?
|
|
107
|
-
AND ((org_id IS NULL AND CAST(? AS TEXT) IS NULL) OR org_id = ?)
|
|
108
|
-
AND ((thread_id IS NULL AND CAST(? AS TEXT) IS NULL) OR thread_id = ?)
|
|
108
|
+
AND ((org_id IS NULL AND CAST(? AS TEXT) IS NULL) OR org_id = CAST(? AS TEXT))
|
|
109
|
+
AND ((thread_id IS NULL AND CAST(? AS TEXT) IS NULL) OR thread_id = CAST(? AS TEXT))
|
|
109
110
|
AND approval_key_hash IN (${placeholders})
|
|
111
|
+
${exactApprovalFilter}
|
|
110
112
|
AND status = 'pending'
|
|
111
113
|
AND expires_at > ?
|
|
112
114
|
AND turn_id IS NOT NULL`,
|
|
@@ -117,6 +119,7 @@ export async function resolveAgentToolApprovalTurnId(binding) {
|
|
|
117
119
|
binding.threadId,
|
|
118
120
|
binding.threadId,
|
|
119
121
|
...hashes,
|
|
122
|
+
...approvalIdArgs,
|
|
120
123
|
now,
|
|
121
124
|
],
|
|
122
125
|
});
|
|
@@ -127,6 +130,14 @@ export async function resolveAgentToolApprovalTurnId(binding) {
|
|
|
127
130
|
})
|
|
128
131
|
.filter((turnId) => turnId !== null));
|
|
129
132
|
const requestedTurnId = binding.requestedTurnId?.trim();
|
|
133
|
+
if (binding.approvalId) {
|
|
134
|
+
if (turnIds.size !== 1)
|
|
135
|
+
return null;
|
|
136
|
+
const exactTurnId = [...turnIds][0];
|
|
137
|
+
return requestedTurnId && requestedTurnId !== exactTurnId
|
|
138
|
+
? null
|
|
139
|
+
: exactTurnId;
|
|
140
|
+
}
|
|
130
141
|
if (requestedTurnId && turnIds.has(requestedTurnId))
|
|
131
142
|
return requestedTurnId;
|
|
132
143
|
return turnIds.size === 1 ? [...turnIds][0] : null;
|
|
@@ -177,21 +188,23 @@ export async function createAgentToolApproval(binding) {
|
|
|
177
188
|
export async function consumeAgentToolApproval(binding) {
|
|
178
189
|
await ensureAgentToolApprovalTable();
|
|
179
190
|
const now = Date.now();
|
|
191
|
+
const exactApprovalFilter = binding.approvalId ? "AND id = ?" : "";
|
|
192
|
+
const approvalIdArgs = binding.approvalId ? [binding.approvalId] : [];
|
|
180
193
|
const result = await getDbExec().execute({
|
|
181
194
|
sql: `UPDATE agent_tool_approvals
|
|
182
195
|
SET status = 'consumed', consumed_at = ?, updated_at = ?
|
|
183
196
|
WHERE id = (
|
|
184
|
-
SELECT id FROM agent_tool_approvals
|
|
197
|
+
SELECT MIN(id) FROM agent_tool_approvals
|
|
185
198
|
WHERE owner_email = ?
|
|
186
|
-
AND ((org_id IS NULL AND CAST(? AS TEXT) IS NULL) OR org_id = ?)
|
|
187
|
-
AND ((thread_id IS NULL AND CAST(? AS TEXT) IS NULL) OR thread_id = ?)
|
|
188
|
-
AND ((turn_id IS NULL AND CAST(? AS TEXT) IS NULL) OR turn_id = ?)
|
|
199
|
+
AND ((org_id IS NULL AND CAST(? AS TEXT) IS NULL) OR org_id = CAST(? AS TEXT))
|
|
200
|
+
AND ((thread_id IS NULL AND CAST(? AS TEXT) IS NULL) OR thread_id = CAST(? AS TEXT))
|
|
201
|
+
AND ((turn_id IS NULL AND CAST(? AS TEXT) IS NULL) OR turn_id = CAST(? AS TEXT))
|
|
189
202
|
AND tool_name = ?
|
|
190
203
|
AND approval_key_hash = ?
|
|
204
|
+
${exactApprovalFilter}
|
|
191
205
|
AND status = 'pending'
|
|
192
206
|
AND expires_at > ?
|
|
193
|
-
|
|
194
|
-
LIMIT 1
|
|
207
|
+
HAVING COUNT(*) = 1
|
|
195
208
|
)
|
|
196
209
|
AND status = 'pending'`,
|
|
197
210
|
args: [
|
|
@@ -206,6 +219,7 @@ export async function consumeAgentToolApproval(binding) {
|
|
|
206
219
|
binding.turnId ?? null,
|
|
207
220
|
binding.toolName,
|
|
208
221
|
hashAgentToolApprovalKey(binding.approvalKey),
|
|
222
|
+
...approvalIdArgs,
|
|
209
223
|
now,
|
|
210
224
|
],
|
|
211
225
|
});
|
|
@@ -19,7 +19,7 @@ export interface ToolCallJournal {
|
|
|
19
19
|
interrupted: ToolCallJournalEntry[];
|
|
20
20
|
}
|
|
21
21
|
export declare function toolCallInputFingerprint(input: unknown): string;
|
|
22
|
-
export declare function
|
|
22
|
+
export declare function isUnavailableToolCallInput(input: unknown): boolean;
|
|
23
23
|
export declare function isConsistentToolCallInputFingerprint(input: unknown, fingerprint: string | undefined, storedFingerprint?: string): boolean;
|
|
24
24
|
export declare function classifyToolCallJournal(events: readonly AgentChatEvent[]): ToolCallJournal;
|
|
25
25
|
export declare function isJournalEmpty(journal: ToolCallJournal): boolean;
|
|
@@ -17,14 +17,16 @@ function inputSignature(input) {
|
|
|
17
17
|
export function toolCallInputFingerprint(input) {
|
|
18
18
|
return createHash("sha256").update(inputSignature(input)).digest("hex");
|
|
19
19
|
}
|
|
20
|
-
export function
|
|
20
|
+
export function isUnavailableToolCallInput(input) {
|
|
21
21
|
if (typeof input === "string")
|
|
22
22
|
return /\[inline [^\]]+ data omitted\]/.test(input);
|
|
23
23
|
if (!input || typeof input !== "object")
|
|
24
24
|
return false;
|
|
25
|
-
if ("omitted" in input &&
|
|
25
|
+
if ("omitted" in input &&
|
|
26
|
+
(input.omitted === "inline-bytes" || input.omitted === "tool-input")) {
|
|
26
27
|
return true;
|
|
27
|
-
|
|
28
|
+
}
|
|
29
|
+
return Object.values(input).some(isUnavailableToolCallInput);
|
|
28
30
|
}
|
|
29
31
|
export function isConsistentToolCallInputFingerprint(input, fingerprint, storedFingerprint) {
|
|
30
32
|
if (storedFingerprint !== undefined)
|
package/dist/agent/types.d.ts
CHANGED
|
@@ -67,6 +67,8 @@ export type AgentChatStructuredContentPart = {
|
|
|
67
67
|
toolName?: string;
|
|
68
68
|
input?: unknown;
|
|
69
69
|
args?: unknown;
|
|
70
|
+
approvalKey?: string;
|
|
71
|
+
approvalAskId?: string;
|
|
70
72
|
} | {
|
|
71
73
|
type: "tool-result";
|
|
72
74
|
toolCallId: string;
|
|
@@ -74,6 +76,8 @@ export type AgentChatStructuredContentPart = {
|
|
|
74
76
|
toolInput?: string;
|
|
75
77
|
content: string;
|
|
76
78
|
isError?: boolean;
|
|
79
|
+
approvalPause?: boolean;
|
|
80
|
+
approvalAskId?: string;
|
|
77
81
|
};
|
|
78
82
|
export interface AgentChatStructuredMessage {
|
|
79
83
|
role: "user" | "assistant";
|
|
@@ -215,6 +219,7 @@ export interface AgentChatRequest {
|
|
|
215
219
|
harness?: AgentChatHarnessRequest;
|
|
216
220
|
trackInRunsTray?: boolean;
|
|
217
221
|
approvedToolCalls?: string[];
|
|
222
|
+
approvedToolCallAskIds?: string[];
|
|
218
223
|
skipPendingSelectionContext?: boolean;
|
|
219
224
|
}
|
|
220
225
|
export type AgentToolInput = Record<string, unknown>;
|
|
@@ -287,6 +292,8 @@ export type AgentChatEvent = {
|
|
|
287
292
|
isError?: boolean;
|
|
288
293
|
errorCode?: string;
|
|
289
294
|
completedSideEffect?: boolean;
|
|
295
|
+
/** False marks current completed events; absence is reserved for older journals. */
|
|
296
|
+
approvalPause?: boolean;
|
|
290
297
|
outcomeUnknown?: true;
|
|
291
298
|
replayed?: true;
|
|
292
299
|
fileMutation?: AgentFileMutationProof;
|
|
@@ -3,6 +3,7 @@ import { agentEventSequenceEnd, isAgentKitProtocolVersion, parseAgentQueuedMessa
|
|
|
3
3
|
import { failedRunIdsWithError, isRenderedRunNotStartedNotice, projectRootAssistantMessages, } from "../../agent/thread-message-projection.js";
|
|
4
4
|
import { RUN_NOT_STARTED_METADATA_KEY, retryContextFromRequest, } from "../../shared/agent-chat-run-not-started.js";
|
|
5
5
|
import { assertNoInlineImageBytes, stripInlineBytes, } from "../../shared/inline-bytes.js";
|
|
6
|
+
import { toolInputFingerprint } from "../../shared/tool-inputs.js";
|
|
6
7
|
import { agentEngineStatusUrlForChatApi, requireAgentEngineConfiguredForDispatch, } from "../agent-engine-readiness.js";
|
|
7
8
|
import { agentNativePath } from "../api-path.js";
|
|
8
9
|
import { CHAT_REQUEST_TOO_LARGE_MESSAGE } from "../error-format.js";
|
|
@@ -1585,6 +1586,15 @@ function persistedToolCalls(toolCalls = []) {
|
|
|
1585
1586
|
new TextEncoder().encode(serialized).byteLength <= 64 * 1024) {
|
|
1586
1587
|
return [JSON.parse(serialized)];
|
|
1587
1588
|
}
|
|
1589
|
+
const metadata = asRecord(toolCall.metadata);
|
|
1590
|
+
const agentKitSnapshot = asRecord(metadata?.agentKitSnapshot);
|
|
1591
|
+
const inputFingerprint = toolCall.input === undefined
|
|
1592
|
+
? agentKitSnapshot?.inputFingerprint
|
|
1593
|
+
: toolInputFingerprint(toolCall.input);
|
|
1594
|
+
const approvalAskId = typeof metadata?.approvalAskId === "string" &&
|
|
1595
|
+
metadata.approvalAskId.length <= 512
|
|
1596
|
+
? metadata.approvalAskId
|
|
1597
|
+
: undefined;
|
|
1588
1598
|
return [
|
|
1589
1599
|
{
|
|
1590
1600
|
id: toolCall.id,
|
|
@@ -1593,9 +1603,17 @@ function persistedToolCalls(toolCalls = []) {
|
|
|
1593
1603
|
...(toolCall.runId ? { runId: toolCall.runId } : {}),
|
|
1594
1604
|
...(toolCall.messageId ? { messageId: toolCall.messageId } : {}),
|
|
1595
1605
|
metadata: {
|
|
1606
|
+
...(metadata?.approvalPause === true ? { approvalPause: true } : {}),
|
|
1607
|
+
...(metadata?.completedSideEffect === true
|
|
1608
|
+
? { completedSideEffect: true }
|
|
1609
|
+
: {}),
|
|
1610
|
+
...(approvalAskId ? { approvalAskId } : {}),
|
|
1596
1611
|
agentKitSnapshot: {
|
|
1597
1612
|
toolCallResult: "omitted",
|
|
1598
1613
|
reason: serialized ? "size_limit" : "not_json",
|
|
1614
|
+
...(typeof inputFingerprint === "string"
|
|
1615
|
+
? { inputFingerprint }
|
|
1616
|
+
: {}),
|
|
1599
1617
|
},
|
|
1600
1618
|
},
|
|
1601
1619
|
},
|