claude-code-rust 0.14.2 → 0.14.4
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/README.md +2 -3
- package/agent-sdk/dist/bridge/account_metadata.js +6 -2
- package/agent-sdk/dist/bridge/agents.js +9 -3
- package/agent-sdk/dist/bridge/available_commands.js +13 -3
- package/agent-sdk/dist/bridge/command_lifecycle.js +79 -4
- package/agent-sdk/dist/bridge/command_scheduler.js +7 -2
- package/agent-sdk/dist/bridge/command_session_control.js +5 -1
- package/agent-sdk/dist/bridge/command_session_data.js +225 -10
- package/agent-sdk/dist/bridge/commands.js +48 -11
- package/agent-sdk/dist/bridge/error_classification.js +5 -1
- package/agent-sdk/dist/bridge/events.js +45 -7
- package/agent-sdk/dist/bridge/history.js +33 -10
- package/agent-sdk/dist/bridge/logger.js +19 -3
- package/agent-sdk/dist/bridge/mcp.js +7 -2
- package/agent-sdk/dist/bridge/mcp_auth_adapter.js +4 -2
- package/agent-sdk/dist/bridge/mcp_metadata.js +113 -39
- package/agent-sdk/dist/bridge/mcp_monitor.js +6 -1
- package/agent-sdk/dist/bridge/message_handlers.js +336 -74
- package/agent-sdk/dist/bridge/model_metadata.js +19 -6
- package/agent-sdk/dist/bridge/permissions.js +32 -8
- package/agent-sdk/dist/bridge/session_lifecycle.js +224 -45
- package/agent-sdk/dist/bridge/state_parsing.js +23 -9
- package/agent-sdk/dist/bridge/tasks.js +62 -22
- package/agent-sdk/dist/bridge/tool_calls.js +89 -31
- package/agent-sdk/dist/bridge/tooling.js +430 -82
- package/agent-sdk/dist/bridge/user_interaction.js +45 -13
- package/agent-sdk/dist/bridge.js +200 -104
- package/package.json +8 -8
|
@@ -23,6 +23,19 @@ const WORKFLOW_TOOL_NAME = "Workflow";
|
|
|
23
23
|
const PROJECTS_TOOL_NAME = "Projects";
|
|
24
24
|
const ARTIFACT_TOOL_NAME = "Artifact";
|
|
25
25
|
const SHOW_ONBOARDING_ROLE_PICKER_TOOL_NAME = "ShowOnboardingRolePicker";
|
|
26
|
+
const SKILL_TOOL_NAME = "Skill";
|
|
27
|
+
const SKILL_WORD_OVERRIDES = {
|
|
28
|
+
api: "API",
|
|
29
|
+
ci: "CI",
|
|
30
|
+
cli: "CLI",
|
|
31
|
+
gh: "GH",
|
|
32
|
+
github: "GitHub",
|
|
33
|
+
mcp: "MCP",
|
|
34
|
+
pdf: "PDF",
|
|
35
|
+
sdk: "SDK",
|
|
36
|
+
ui: "UI",
|
|
37
|
+
ux: "UX",
|
|
38
|
+
};
|
|
26
39
|
const READ_MCP_RESOURCE_TOOL_NAME = "ReadMcpResource";
|
|
27
40
|
const READ_MCP_RESOURCE_DIR_TOOL_NAME = "ReadMcpResourceDir";
|
|
28
41
|
const SEARCH_OUTPUT_MODES = new Set(["content", "files_with_matches", "count"]);
|
|
@@ -37,14 +50,18 @@ export function isToolSearchToolResultType(blockType) {
|
|
|
37
50
|
return blockType === "tool_search_tool_result";
|
|
38
51
|
}
|
|
39
52
|
export function isToolUseBlockType(blockType) {
|
|
40
|
-
return blockType === "tool_use" ||
|
|
53
|
+
return (blockType === "tool_use" ||
|
|
54
|
+
blockType === "server_tool_use" ||
|
|
55
|
+
blockType === "mcp_tool_use");
|
|
41
56
|
}
|
|
42
57
|
function inputString(input, key) {
|
|
43
58
|
return typeof input[key] === "string" ? input[key].trim() : "";
|
|
44
59
|
}
|
|
45
60
|
function inputNumber(input, key) {
|
|
46
61
|
const value = input[key];
|
|
47
|
-
return typeof value === "number" && Number.isFinite(value)
|
|
62
|
+
return typeof value === "number" && Number.isFinite(value)
|
|
63
|
+
? value
|
|
64
|
+
: undefined;
|
|
48
65
|
}
|
|
49
66
|
function inputBoolean(input, key) {
|
|
50
67
|
return typeof input[key] === "boolean" ? input[key] : undefined;
|
|
@@ -56,7 +73,8 @@ export function isShellToolName(name) {
|
|
|
56
73
|
return name === "Bash" || name === "PowerShell";
|
|
57
74
|
}
|
|
58
75
|
function isMcpResourceReadToolName(name) {
|
|
59
|
-
return name === READ_MCP_RESOURCE_TOOL_NAME ||
|
|
76
|
+
return (name === READ_MCP_RESOURCE_TOOL_NAME ||
|
|
77
|
+
name === READ_MCP_RESOURCE_DIR_TOOL_NAME);
|
|
60
78
|
}
|
|
61
79
|
function agentInputTitle(name, input) {
|
|
62
80
|
if (!isAgentLikeToolName(name)) {
|
|
@@ -183,6 +201,7 @@ export function normalizeToolKind(name) {
|
|
|
183
201
|
case "Projects":
|
|
184
202
|
case "Artifact":
|
|
185
203
|
case "ShowOnboardingRolePicker":
|
|
204
|
+
case SKILL_TOOL_NAME:
|
|
186
205
|
return "other";
|
|
187
206
|
case "Task":
|
|
188
207
|
case "Agent":
|
|
@@ -194,6 +213,34 @@ export function normalizeToolKind(name) {
|
|
|
194
213
|
return "think";
|
|
195
214
|
}
|
|
196
215
|
}
|
|
216
|
+
function skillDisplayName(rawName) {
|
|
217
|
+
const trimmed = rawName.trim();
|
|
218
|
+
const segments = trimmed.split(":");
|
|
219
|
+
if (segments.length > 2 ||
|
|
220
|
+
segments.some((segment) => !segment || !/^[a-zA-Z0-9]+(?:[-_][a-zA-Z0-9]+)*$/.test(segment))) {
|
|
221
|
+
return trimmed;
|
|
222
|
+
}
|
|
223
|
+
const displaySegments = segments.map((segment) => segment
|
|
224
|
+
.split(/[-_]/)
|
|
225
|
+
.map((word) => skillDisplayWord(word))
|
|
226
|
+
.join(" "));
|
|
227
|
+
if (displaySegments.length === 2 &&
|
|
228
|
+
displaySegments[0].toLowerCase() === displaySegments[1].toLowerCase()) {
|
|
229
|
+
return displaySegments[1];
|
|
230
|
+
}
|
|
231
|
+
return displaySegments.join(" / ");
|
|
232
|
+
}
|
|
233
|
+
function skillDisplayWord(word) {
|
|
234
|
+
const override = SKILL_WORD_OVERRIDES[word.toLowerCase()];
|
|
235
|
+
if (override) {
|
|
236
|
+
return override;
|
|
237
|
+
}
|
|
238
|
+
if (/^[A-Z0-9]+$/.test(word) ||
|
|
239
|
+
(/[a-z]/.test(word) && /[A-Z]/.test(word) && !/^[A-Z][a-z0-9]*$/.test(word))) {
|
|
240
|
+
return word;
|
|
241
|
+
}
|
|
242
|
+
return `${word.charAt(0).toUpperCase()}${word.slice(1).toLowerCase()}`;
|
|
243
|
+
}
|
|
197
244
|
export function toolTitle(name, input, context = {}) {
|
|
198
245
|
const agentTitle = agentInputTitle(name, input);
|
|
199
246
|
if (agentTitle) {
|
|
@@ -236,7 +283,9 @@ export function toolTitle(name, input, context = {}) {
|
|
|
236
283
|
}
|
|
237
284
|
if (name === REMOTE_TRIGGER_TOOL_NAME) {
|
|
238
285
|
const action = typeof input.action === "string" ? input.action.trim() : "";
|
|
239
|
-
return action
|
|
286
|
+
return action
|
|
287
|
+
? `${REMOTE_TRIGGER_TOOL_NAME}: ${action}`
|
|
288
|
+
: REMOTE_TRIGGER_TOOL_NAME;
|
|
240
289
|
}
|
|
241
290
|
if (name === ENTER_PLAN_MODE_TOOL_NAME) {
|
|
242
291
|
return name;
|
|
@@ -247,11 +296,15 @@ export function toolTitle(name, input, context = {}) {
|
|
|
247
296
|
}
|
|
248
297
|
if (name === MONITOR_TOOL_NAME) {
|
|
249
298
|
const description = nonEmptyString(input.description);
|
|
250
|
-
return description
|
|
299
|
+
return description
|
|
300
|
+
? `${MONITOR_TOOL_NAME}: ${description}`
|
|
301
|
+
: MONITOR_TOOL_NAME;
|
|
251
302
|
}
|
|
252
303
|
if (name === WORKFLOW_TOOL_NAME) {
|
|
253
304
|
const workflowName = nonEmptyString(input.name);
|
|
254
|
-
return workflowName
|
|
305
|
+
return workflowName
|
|
306
|
+
? `${WORKFLOW_TOOL_NAME}: ${workflowName}`
|
|
307
|
+
: WORKFLOW_TOOL_NAME;
|
|
255
308
|
}
|
|
256
309
|
if (name === PROJECTS_TOOL_NAME) {
|
|
257
310
|
return formatProjectsTitle(input);
|
|
@@ -263,6 +316,12 @@ export function toolTitle(name, input, context = {}) {
|
|
|
263
316
|
if (name === SHOW_ONBOARDING_ROLE_PICKER_TOOL_NAME) {
|
|
264
317
|
return SHOW_ONBOARDING_ROLE_PICKER_TOOL_NAME;
|
|
265
318
|
}
|
|
319
|
+
if (name === SKILL_TOOL_NAME) {
|
|
320
|
+
const skillName = nonEmptyString(input.skill);
|
|
321
|
+
return skillName
|
|
322
|
+
? `${SKILL_TOOL_NAME}: ${skillDisplayName(skillName)}`
|
|
323
|
+
: SKILL_TOOL_NAME;
|
|
324
|
+
}
|
|
266
325
|
if (name === "EnterWorktree") {
|
|
267
326
|
const worktreeName = typeof input.name === "string" ? input.name.trim() : "";
|
|
268
327
|
return worktreeName || "EnterWorktree";
|
|
@@ -270,7 +329,8 @@ export function toolTitle(name, input, context = {}) {
|
|
|
270
329
|
if (name === "ExitWorktree") {
|
|
271
330
|
return "ExitWorktree";
|
|
272
331
|
}
|
|
273
|
-
if ((name === "Read" || name === "Write" || name === "Edit") &&
|
|
332
|
+
if ((name === "Read" || name === "Write" || name === "Edit") &&
|
|
333
|
+
typeof input.file_path === "string") {
|
|
274
334
|
return `${name} ${input.file_path}`;
|
|
275
335
|
}
|
|
276
336
|
if (isMcpResourceReadToolName(name)) {
|
|
@@ -287,7 +347,9 @@ export function toolTitle(name, input, context = {}) {
|
|
|
287
347
|
}
|
|
288
348
|
function formatProjectsTitle(input) {
|
|
289
349
|
const method = nonEmptyString(input.method);
|
|
290
|
-
const action = method?.startsWith("project_")
|
|
350
|
+
const action = method?.startsWith("project_")
|
|
351
|
+
? method.slice("project_".length)
|
|
352
|
+
: method;
|
|
291
353
|
const suffix = nonEmptyString(input.path) ?? nonEmptyString(input.query);
|
|
292
354
|
const base = action ? `${PROJECTS_TOOL_NAME}: ${action}` : PROJECTS_TOOL_NAME;
|
|
293
355
|
return suffix ? `${base} ${suffix}` : base;
|
|
@@ -303,14 +365,30 @@ function editDiffContent(name, input) {
|
|
|
303
365
|
if (!oldText && !newText) {
|
|
304
366
|
return [];
|
|
305
367
|
}
|
|
306
|
-
return [
|
|
368
|
+
return [
|
|
369
|
+
{
|
|
370
|
+
type: "diff",
|
|
371
|
+
old_path: filePath,
|
|
372
|
+
new_path: filePath,
|
|
373
|
+
old: oldText,
|
|
374
|
+
new: newText,
|
|
375
|
+
},
|
|
376
|
+
];
|
|
307
377
|
}
|
|
308
378
|
if (name === "Write") {
|
|
309
379
|
const newText = typeof input.content === "string" ? input.content : "";
|
|
310
380
|
if (!newText) {
|
|
311
381
|
return [];
|
|
312
382
|
}
|
|
313
|
-
return [
|
|
383
|
+
return [
|
|
384
|
+
{
|
|
385
|
+
type: "diff",
|
|
386
|
+
old_path: filePath,
|
|
387
|
+
new_path: filePath,
|
|
388
|
+
old: "",
|
|
389
|
+
new: newText,
|
|
390
|
+
},
|
|
391
|
+
];
|
|
314
392
|
}
|
|
315
393
|
return [];
|
|
316
394
|
}
|
|
@@ -369,6 +447,17 @@ function resultRecordCandidates(rawResult, rawContent) {
|
|
|
369
447
|
pushNestedRecords(rawContent);
|
|
370
448
|
return candidates;
|
|
371
449
|
}
|
|
450
|
+
function imageReadResultText(rawResult, rawContent, rawInput) {
|
|
451
|
+
const isImage = resultRecordCandidates(rawResult, rawContent).some((candidate) => candidate.type === "image");
|
|
452
|
+
if (!isImage) {
|
|
453
|
+
return undefined;
|
|
454
|
+
}
|
|
455
|
+
const input = asRecordOrNull(rawInput);
|
|
456
|
+
const filePath = typeof input?.file_path === "string" ? input.file_path.trim() : "";
|
|
457
|
+
const normalizedPath = filePath.replaceAll("\\", "/");
|
|
458
|
+
const fileName = normalizedPath.slice(normalizedPath.lastIndexOf("/") + 1);
|
|
459
|
+
return fileName ? `Viewed Image ${fileName}` : "Viewed Image";
|
|
460
|
+
}
|
|
372
461
|
function parseJsonCandidate(value) {
|
|
373
462
|
const text = typeof value === "string" ? value : extractText(value);
|
|
374
463
|
const trimmed = text.trim();
|
|
@@ -403,11 +492,18 @@ function pushStructuredRecordCandidates(candidates, value) {
|
|
|
403
492
|
}
|
|
404
493
|
function mcpResourceContentFromResult(rawResult, rawContent) {
|
|
405
494
|
const candidates = [];
|
|
406
|
-
for (const candidate of [
|
|
495
|
+
for (const candidate of [
|
|
496
|
+
rawResult,
|
|
497
|
+
rawContent,
|
|
498
|
+
parseJsonCandidate(rawResult),
|
|
499
|
+
parseJsonCandidate(rawContent),
|
|
500
|
+
]) {
|
|
407
501
|
pushStructuredRecordCandidates(candidates, candidate);
|
|
408
502
|
}
|
|
409
503
|
for (const candidate of candidates) {
|
|
410
|
-
const contents = Array.isArray(candidate.contents)
|
|
504
|
+
const contents = Array.isArray(candidate.contents)
|
|
505
|
+
? candidate.contents
|
|
506
|
+
: null;
|
|
411
507
|
if (!contents || contents.length === 0) {
|
|
412
508
|
continue;
|
|
413
509
|
}
|
|
@@ -421,11 +517,14 @@ function mcpResourceContentFromResult(rawResult, rawContent) {
|
|
|
421
517
|
if (!uri) {
|
|
422
518
|
continue;
|
|
423
519
|
}
|
|
424
|
-
const text = typeof record.text === "string" && record.text.length > 0
|
|
520
|
+
const text = typeof record.text === "string" && record.text.length > 0
|
|
521
|
+
? record.text
|
|
522
|
+
: undefined;
|
|
425
523
|
const mimeType = typeof record.mimeType === "string" && record.mimeType.trim().length > 0
|
|
426
524
|
? record.mimeType.trim()
|
|
427
525
|
: undefined;
|
|
428
|
-
const blobSavedTo = typeof record.blobSavedTo === "string" &&
|
|
526
|
+
const blobSavedTo = typeof record.blobSavedTo === "string" &&
|
|
527
|
+
record.blobSavedTo.trim().length > 0
|
|
429
528
|
? record.blobSavedTo.trim()
|
|
430
529
|
: undefined;
|
|
431
530
|
if (!text && !blobSavedTo) {
|
|
@@ -484,10 +583,15 @@ function extractToolOutputMetadata(toolName, rawResult, rawContent) {
|
|
|
484
583
|
const hasAssistantAutoBackgrounded = typeof candidate.assistantAutoBackgrounded === "boolean";
|
|
485
584
|
const timedOutAfterMs = nonNegativeInteger(candidate.timedOutAfterMs);
|
|
486
585
|
const backgroundCwdHint = nonEmptyString(candidate.backgroundCwdHint);
|
|
487
|
-
|
|
586
|
+
const hasBackgroundEndsWithFinalResponse = typeof candidate.backgroundEndsWithFinalResponse === "boolean";
|
|
587
|
+
if (hasAssistantAutoBackgrounded ||
|
|
588
|
+
timedOutAfterMs !== undefined ||
|
|
589
|
+
backgroundCwdHint ||
|
|
590
|
+
hasBackgroundEndsWithFinalResponse) {
|
|
488
591
|
const bashMetadata = {};
|
|
489
592
|
if (hasAssistantAutoBackgrounded) {
|
|
490
|
-
bashMetadata.assistant_auto_backgrounded =
|
|
593
|
+
bashMetadata.assistant_auto_backgrounded =
|
|
594
|
+
candidate.assistantAutoBackgrounded;
|
|
491
595
|
}
|
|
492
596
|
if (timedOutAfterMs !== undefined) {
|
|
493
597
|
bashMetadata.timed_out_after_ms = timedOutAfterMs;
|
|
@@ -495,6 +599,10 @@ function extractToolOutputMetadata(toolName, rawResult, rawContent) {
|
|
|
495
599
|
if (backgroundCwdHint) {
|
|
496
600
|
bashMetadata.background_cwd_hint = backgroundCwdHint;
|
|
497
601
|
}
|
|
602
|
+
if (hasBackgroundEndsWithFinalResponse) {
|
|
603
|
+
bashMetadata.background_ends_with_final_response =
|
|
604
|
+
candidate.backgroundEndsWithFinalResponse;
|
|
605
|
+
}
|
|
498
606
|
metadata.bash = bashMetadata;
|
|
499
607
|
break;
|
|
500
608
|
}
|
|
@@ -592,7 +700,10 @@ export function extractText(value) {
|
|
|
592
700
|
if (typeof entry === "string") {
|
|
593
701
|
return entry;
|
|
594
702
|
}
|
|
595
|
-
if (entry &&
|
|
703
|
+
if (entry &&
|
|
704
|
+
typeof entry === "object" &&
|
|
705
|
+
"text" in entry &&
|
|
706
|
+
typeof entry.text === "string") {
|
|
596
707
|
return entry.text;
|
|
597
708
|
}
|
|
598
709
|
return "";
|
|
@@ -600,7 +711,10 @@ export function extractText(value) {
|
|
|
600
711
|
.filter((part) => part.length > 0)
|
|
601
712
|
.join("\n");
|
|
602
713
|
}
|
|
603
|
-
if (value &&
|
|
714
|
+
if (value &&
|
|
715
|
+
typeof value === "object" &&
|
|
716
|
+
"text" in value &&
|
|
717
|
+
typeof value.text === "string") {
|
|
604
718
|
return value.text;
|
|
605
719
|
}
|
|
606
720
|
return "";
|
|
@@ -685,7 +799,15 @@ function writeDiffFromInput(rawInput) {
|
|
|
685
799
|
if (!filePath || !content) {
|
|
686
800
|
return [];
|
|
687
801
|
}
|
|
688
|
-
return [
|
|
802
|
+
return [
|
|
803
|
+
{
|
|
804
|
+
type: "diff",
|
|
805
|
+
old_path: filePath,
|
|
806
|
+
new_path: filePath,
|
|
807
|
+
old: "",
|
|
808
|
+
new: content,
|
|
809
|
+
},
|
|
810
|
+
];
|
|
689
811
|
}
|
|
690
812
|
function editDiffFromInput(rawInput) {
|
|
691
813
|
const input = asRecordOrNull(rawInput);
|
|
@@ -706,7 +828,15 @@ function editDiffFromInput(rawInput) {
|
|
|
706
828
|
if (!filePath || (!oldText && !newText)) {
|
|
707
829
|
return [];
|
|
708
830
|
}
|
|
709
|
-
return [
|
|
831
|
+
return [
|
|
832
|
+
{
|
|
833
|
+
type: "diff",
|
|
834
|
+
old_path: filePath,
|
|
835
|
+
new_path: filePath,
|
|
836
|
+
old: oldText,
|
|
837
|
+
new: newText,
|
|
838
|
+
},
|
|
839
|
+
];
|
|
710
840
|
}
|
|
711
841
|
function writeDiffFromResult(rawContent) {
|
|
712
842
|
const candidates = Array.isArray(rawContent) ? rawContent : [rawContent];
|
|
@@ -721,15 +851,24 @@ function writeDiffFromResult(rawContent) {
|
|
|
721
851
|
? record.file_path
|
|
722
852
|
: "";
|
|
723
853
|
const content = typeof record.content === "string" ? record.content : "";
|
|
724
|
-
const originalRaw = "originalFile" in record
|
|
854
|
+
const originalRaw = "originalFile" in record
|
|
855
|
+
? record.originalFile
|
|
856
|
+
: "original_file" in record
|
|
857
|
+
? record.original_file
|
|
858
|
+
: undefined;
|
|
725
859
|
const gitDiff = asRecordOrNull(record.gitDiff);
|
|
726
|
-
const repository = typeof gitDiff?.repository === "string" &&
|
|
860
|
+
const repository = typeof gitDiff?.repository === "string" &&
|
|
861
|
+
gitDiff.repository.trim().length > 0
|
|
727
862
|
? gitDiff.repository.trim()
|
|
728
863
|
: undefined;
|
|
729
864
|
if (!filePath || !content || originalRaw === undefined) {
|
|
730
865
|
continue;
|
|
731
866
|
}
|
|
732
|
-
const original = typeof originalRaw === "string"
|
|
867
|
+
const original = typeof originalRaw === "string"
|
|
868
|
+
? originalRaw
|
|
869
|
+
: originalRaw === null
|
|
870
|
+
? ""
|
|
871
|
+
: "";
|
|
733
872
|
return [
|
|
734
873
|
{
|
|
735
874
|
type: "diff",
|
|
@@ -772,7 +911,8 @@ function editDiffFromResult(rawResult, rawInput) {
|
|
|
772
911
|
if (candidatePath && candidatePath !== filePath) {
|
|
773
912
|
continue;
|
|
774
913
|
}
|
|
775
|
-
const repository = typeof gitDiff?.repository === "string" &&
|
|
914
|
+
const repository = typeof gitDiff?.repository === "string" &&
|
|
915
|
+
gitDiff.repository.trim().length > 0
|
|
776
916
|
? gitDiff.repository.trim()
|
|
777
917
|
: undefined;
|
|
778
918
|
return [
|
|
@@ -862,12 +1002,17 @@ function firstSearchRecord(toolName, rawResult, rawContent) {
|
|
|
862
1002
|
return undefined;
|
|
863
1003
|
}
|
|
864
1004
|
const candidates = resultRecordCandidates(rawResult, rawContent);
|
|
865
|
-
for (const parsed of [
|
|
1005
|
+
for (const parsed of [
|
|
1006
|
+
parseJsonCandidate(rawResult),
|
|
1007
|
+
parseJsonCandidate(rawContent),
|
|
1008
|
+
]) {
|
|
866
1009
|
candidates.push(...resultRecordCandidates(parsed, undefined));
|
|
867
1010
|
}
|
|
868
1011
|
return candidates.find((candidate) => {
|
|
869
1012
|
if (toolName === "Glob") {
|
|
870
|
-
return Array.isArray(candidate.filenames) ||
|
|
1013
|
+
return (Array.isArray(candidate.filenames) ||
|
|
1014
|
+
"numFiles" in candidate ||
|
|
1015
|
+
"truncated" in candidate);
|
|
871
1016
|
}
|
|
872
1017
|
return (Array.isArray(candidate.filenames) ||
|
|
873
1018
|
"numFiles" in candidate ||
|
|
@@ -878,7 +1023,9 @@ function firstSearchRecord(toolName, rawResult, rawContent) {
|
|
|
878
1023
|
}
|
|
879
1024
|
function recordNumber(record, key) {
|
|
880
1025
|
const value = record[key];
|
|
881
|
-
return typeof value === "number" && Number.isFinite(value)
|
|
1026
|
+
return typeof value === "number" && Number.isFinite(value)
|
|
1027
|
+
? value
|
|
1028
|
+
: undefined;
|
|
882
1029
|
}
|
|
883
1030
|
function recordNonNegativeInteger(record, key) {
|
|
884
1031
|
return nonNegativeInteger(record[key]);
|
|
@@ -934,7 +1081,8 @@ function grepResultText(record) {
|
|
|
934
1081
|
const numFiles = totalFiles ??
|
|
935
1082
|
(legacyNumFiles !== 0 || !hasVisibleMatches ? legacyNumFiles : undefined) ??
|
|
936
1083
|
(filenames.length > 0 ? filenames.length : undefined);
|
|
937
|
-
const numLines = recordNonNegativeInteger(record, "totalLines") ??
|
|
1084
|
+
const numLines = recordNonNegativeInteger(record, "totalLines") ??
|
|
1085
|
+
recordNonNegativeInteger(record, "numLines");
|
|
938
1086
|
const numMatches = recordNumber(record, "numMatches");
|
|
939
1087
|
const appliedLimit = recordNumber(record, "appliedLimit");
|
|
940
1088
|
const appliedOffset = recordNumber(record, "appliedOffset");
|
|
@@ -987,12 +1135,19 @@ function worktreeResultFields(toolName, rawResult, rawContent) {
|
|
|
987
1135
|
return undefined;
|
|
988
1136
|
}
|
|
989
1137
|
const candidates = resultRecordCandidates(rawResult, rawContent);
|
|
990
|
-
for (const parsed of [
|
|
1138
|
+
for (const parsed of [
|
|
1139
|
+
parseJsonCandidate(rawResult),
|
|
1140
|
+
parseJsonCandidate(rawContent),
|
|
1141
|
+
]) {
|
|
991
1142
|
candidates.push(...resultRecordCandidates(parsed, undefined));
|
|
992
1143
|
}
|
|
993
1144
|
for (const candidate of candidates) {
|
|
994
|
-
const branch = typeof candidate.worktreeBranch === "string"
|
|
995
|
-
|
|
1145
|
+
const branch = typeof candidate.worktreeBranch === "string"
|
|
1146
|
+
? candidate.worktreeBranch.trim()
|
|
1147
|
+
: "";
|
|
1148
|
+
const path = typeof candidate.worktreePath === "string"
|
|
1149
|
+
? candidate.worktreePath.trim()
|
|
1150
|
+
: "";
|
|
996
1151
|
const output = branch ? `Branch: ${branch}` : path ? `Path: ${path}` : "";
|
|
997
1152
|
const isStructuredWorktreeOutput = "message" in candidate ||
|
|
998
1153
|
"worktreeBranch" in candidate ||
|
|
@@ -1058,8 +1213,24 @@ const CRON_WEEKDAY_NAMES = [
|
|
|
1058
1213
|
"Friday",
|
|
1059
1214
|
"Saturday",
|
|
1060
1215
|
];
|
|
1061
|
-
const CRON_MONTH_ALIASES = new Map([
|
|
1062
|
-
|
|
1216
|
+
const CRON_MONTH_ALIASES = new Map([
|
|
1217
|
+
"JAN",
|
|
1218
|
+
"FEB",
|
|
1219
|
+
"MAR",
|
|
1220
|
+
"APR",
|
|
1221
|
+
"MAY",
|
|
1222
|
+
"JUN",
|
|
1223
|
+
"JUL",
|
|
1224
|
+
"AUG",
|
|
1225
|
+
"SEP",
|
|
1226
|
+
"OCT",
|
|
1227
|
+
"NOV",
|
|
1228
|
+
"DEC",
|
|
1229
|
+
].map((name, index) => [name, index + 1]));
|
|
1230
|
+
const CRON_WEEKDAY_ALIASES = new Map(["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"].map((name, index) => [
|
|
1231
|
+
name,
|
|
1232
|
+
index,
|
|
1233
|
+
]));
|
|
1063
1234
|
function parseCronValue(value, min, max, aliases) {
|
|
1064
1235
|
const normalized = value.trim().toUpperCase();
|
|
1065
1236
|
const aliased = aliases?.get(normalized);
|
|
@@ -1077,14 +1248,18 @@ function parseCronField(rawField, min, max, aliases) {
|
|
|
1077
1248
|
const stepMatch = raw.match(/^\*\/(\d+)$/);
|
|
1078
1249
|
if (stepMatch) {
|
|
1079
1250
|
const step = Number(stepMatch[1]);
|
|
1080
|
-
return Number.isInteger(step) && step > 0
|
|
1251
|
+
return Number.isInteger(step) && step > 0
|
|
1252
|
+
? { kind: "step", raw, step }
|
|
1253
|
+
: { kind: "unsupported", raw };
|
|
1081
1254
|
}
|
|
1082
1255
|
if (raw.includes(",")) {
|
|
1083
1256
|
const values = raw
|
|
1084
1257
|
.split(",")
|
|
1085
1258
|
.map((part) => parseCronValue(part, min, max, aliases))
|
|
1086
1259
|
.filter((value) => value !== undefined);
|
|
1087
|
-
return values.length === raw.split(",").length
|
|
1260
|
+
return values.length === raw.split(",").length
|
|
1261
|
+
? { kind: "list", raw, values }
|
|
1262
|
+
: { kind: "unsupported", raw };
|
|
1088
1263
|
}
|
|
1089
1264
|
const rangeMatch = raw.match(/^([^/-]+)-([^/-]+)$/);
|
|
1090
1265
|
if (rangeMatch) {
|
|
@@ -1095,7 +1270,9 @@ function parseCronField(rawField, min, max, aliases) {
|
|
|
1095
1270
|
: { kind: "unsupported", raw };
|
|
1096
1271
|
}
|
|
1097
1272
|
const value = parseCronValue(raw, min, max, aliases);
|
|
1098
|
-
return value !== undefined
|
|
1273
|
+
return value !== undefined
|
|
1274
|
+
? { kind: "single", raw, value }
|
|
1275
|
+
: { kind: "unsupported", raw };
|
|
1099
1276
|
}
|
|
1100
1277
|
function isCronAny(field) {
|
|
1101
1278
|
return field.kind === "any";
|
|
@@ -1136,12 +1313,16 @@ function weekdayDescription(field) {
|
|
|
1136
1313
|
return "day";
|
|
1137
1314
|
}
|
|
1138
1315
|
if (field.kind === "list") {
|
|
1139
|
-
const normalized = [
|
|
1316
|
+
const normalized = [
|
|
1317
|
+
...new Set(field.values.map((value) => (value === 7 ? 0 : value))),
|
|
1318
|
+
].sort((left, right) => left - right);
|
|
1140
1319
|
if (normalized.length === 2 && normalized[0] === 0 && normalized[1] === 6) {
|
|
1141
1320
|
return "weekend day";
|
|
1142
1321
|
}
|
|
1143
1322
|
const names = normalized.map(weekdayName);
|
|
1144
|
-
return names.every((name) => name !== undefined)
|
|
1323
|
+
return names.every((name) => name !== undefined)
|
|
1324
|
+
? joinEnglishList(names)
|
|
1325
|
+
: undefined;
|
|
1145
1326
|
}
|
|
1146
1327
|
return undefined;
|
|
1147
1328
|
}
|
|
@@ -1152,7 +1333,9 @@ function hourlyScheduleText(minute) {
|
|
|
1152
1333
|
if (minute.kind !== "single") {
|
|
1153
1334
|
return undefined;
|
|
1154
1335
|
}
|
|
1155
|
-
return minute.value === 0
|
|
1336
|
+
return minute.value === 0
|
|
1337
|
+
? "Every hour on the hour"
|
|
1338
|
+
: `Every hour at minute ${padCronNumber(minute.value)}`;
|
|
1156
1339
|
}
|
|
1157
1340
|
function cronScheduleFromExpression(cron) {
|
|
1158
1341
|
const parts = cron.trim().split(/\s+/);
|
|
@@ -1180,7 +1363,9 @@ function cronScheduleFromExpression(cron) {
|
|
|
1180
1363
|
return hourlyScheduleText(minute);
|
|
1181
1364
|
}
|
|
1182
1365
|
if (everyDay && minute.kind === "single" && hour.kind === "step") {
|
|
1183
|
-
const suffix = minute.value === 0
|
|
1366
|
+
const suffix = minute.value === 0
|
|
1367
|
+
? "on the hour"
|
|
1368
|
+
: `at minute ${padCronNumber(minute.value)}`;
|
|
1184
1369
|
return `Every ${hour.step} ${pluralUnit(hour.step, "hour")} ${suffix}`;
|
|
1185
1370
|
}
|
|
1186
1371
|
const time = cronTime(hour, minute);
|
|
@@ -1205,13 +1390,17 @@ function cronScheduleFromExpression(cron) {
|
|
|
1205
1390
|
if (dayOfMonth.kind === "single" && isCronAny(dayOfWeek)) {
|
|
1206
1391
|
if (month.kind === "single") {
|
|
1207
1392
|
const monthLabel = monthName(month.value);
|
|
1208
|
-
return monthLabel
|
|
1393
|
+
return monthLabel
|
|
1394
|
+
? `Every ${monthLabel} ${dayOfMonth.value} at ${time}`
|
|
1395
|
+
: undefined;
|
|
1209
1396
|
}
|
|
1210
1397
|
if (month.kind === "step") {
|
|
1211
1398
|
return `Every ${month.step} ${pluralUnit(month.step, "month")} on day ${dayOfMonth.value} at ${time}`;
|
|
1212
1399
|
}
|
|
1213
1400
|
}
|
|
1214
|
-
if (isCronAny(dayOfMonth) &&
|
|
1401
|
+
if (isCronAny(dayOfMonth) &&
|
|
1402
|
+
month.kind === "single" &&
|
|
1403
|
+
isCronAny(dayOfWeek)) {
|
|
1215
1404
|
const monthLabel = monthName(month.value);
|
|
1216
1405
|
return monthLabel ? `Every day in ${monthLabel} at ${time}` : undefined;
|
|
1217
1406
|
}
|
|
@@ -1226,7 +1415,11 @@ function normalizeHumanSchedule(value) {
|
|
|
1226
1415
|
if (hourlyMinute) {
|
|
1227
1416
|
const minute = Number(hourlyMinute[1]);
|
|
1228
1417
|
if (Number.isInteger(minute) && minute >= 0 && minute <= 59) {
|
|
1229
|
-
return hourlyScheduleText({
|
|
1418
|
+
return hourlyScheduleText({
|
|
1419
|
+
kind: "single",
|
|
1420
|
+
raw: hourlyMinute[1],
|
|
1421
|
+
value: minute,
|
|
1422
|
+
});
|
|
1230
1423
|
}
|
|
1231
1424
|
}
|
|
1232
1425
|
return text;
|
|
@@ -1258,13 +1451,17 @@ function cronCreateResultText(candidate, rawInput) {
|
|
|
1258
1451
|
return lines.join("\n");
|
|
1259
1452
|
}
|
|
1260
1453
|
function cronDeleteResultText(candidate) {
|
|
1261
|
-
return typeof candidate.id === "string"
|
|
1454
|
+
return typeof candidate.id === "string"
|
|
1455
|
+
? `Schedule ID: ${candidate.id}`
|
|
1456
|
+
: undefined;
|
|
1262
1457
|
}
|
|
1263
1458
|
function cronListResultText(candidate) {
|
|
1264
1459
|
if (!Array.isArray(candidate.jobs)) {
|
|
1265
1460
|
return undefined;
|
|
1266
1461
|
}
|
|
1267
|
-
const jobs = candidate.jobs
|
|
1462
|
+
const jobs = candidate.jobs
|
|
1463
|
+
.map(asRecordOrNull)
|
|
1464
|
+
.filter((job) => job !== null);
|
|
1268
1465
|
if (jobs.length === 0) {
|
|
1269
1466
|
return "Jobs: none";
|
|
1270
1467
|
}
|
|
@@ -1314,7 +1511,10 @@ function cronResultText(toolName, rawResult, rawContent, rawInput) {
|
|
|
1314
1511
|
return undefined;
|
|
1315
1512
|
}
|
|
1316
1513
|
const candidates = resultRecordCandidates(rawResult, rawContent);
|
|
1317
|
-
for (const parsed of [
|
|
1514
|
+
for (const parsed of [
|
|
1515
|
+
parseJsonCandidate(rawResult),
|
|
1516
|
+
parseJsonCandidate(rawContent),
|
|
1517
|
+
]) {
|
|
1318
1518
|
candidates.push(...resultRecordCandidates(parsed, undefined));
|
|
1319
1519
|
}
|
|
1320
1520
|
for (const candidate of candidates) {
|
|
@@ -1382,7 +1582,10 @@ function scheduleWakeupResultText(toolName, rawResult, rawContent) {
|
|
|
1382
1582
|
return undefined;
|
|
1383
1583
|
}
|
|
1384
1584
|
const candidates = resultRecordCandidates(rawResult, rawContent);
|
|
1385
|
-
for (const parsed of [
|
|
1585
|
+
for (const parsed of [
|
|
1586
|
+
parseJsonCandidate(rawResult),
|
|
1587
|
+
parseJsonCandidate(rawContent),
|
|
1588
|
+
]) {
|
|
1386
1589
|
candidates.push(...resultRecordCandidates(parsed, undefined));
|
|
1387
1590
|
}
|
|
1388
1591
|
for (const candidate of candidates) {
|
|
@@ -1392,7 +1595,9 @@ function scheduleWakeupResultText(toolName, rawResult, rawContent) {
|
|
|
1392
1595
|
const clampedDelaySeconds = typeof candidate.clampedDelaySeconds === "number"
|
|
1393
1596
|
? formatDurationSeconds(candidate.clampedDelaySeconds)
|
|
1394
1597
|
: undefined;
|
|
1395
|
-
if (!scheduledFor ||
|
|
1598
|
+
if (!scheduledFor ||
|
|
1599
|
+
!clampedDelaySeconds ||
|
|
1600
|
+
typeof candidate.wasClamped !== "boolean") {
|
|
1396
1601
|
continue;
|
|
1397
1602
|
}
|
|
1398
1603
|
return [
|
|
@@ -1421,7 +1626,10 @@ function pushNotificationResultText(toolName, rawResult, rawContent, rawInput) {
|
|
|
1421
1626
|
}
|
|
1422
1627
|
const inputMessage = nonEmptyString(asRecordOrNull(rawInput)?.message);
|
|
1423
1628
|
const candidates = resultRecordCandidates(rawResult, rawContent);
|
|
1424
|
-
for (const parsed of [
|
|
1629
|
+
for (const parsed of [
|
|
1630
|
+
parseJsonCandidate(rawResult),
|
|
1631
|
+
parseJsonCandidate(rawContent),
|
|
1632
|
+
]) {
|
|
1425
1633
|
candidates.push(...resultRecordCandidates(parsed, undefined));
|
|
1426
1634
|
}
|
|
1427
1635
|
for (const candidate of candidates) {
|
|
@@ -1446,7 +1654,8 @@ function pushNotificationResultText(toolName, rawResult, rawContent, rawInput) {
|
|
|
1446
1654
|
if (disabledReason) {
|
|
1447
1655
|
lines.push(`Disabled reason: ${disabledReason}`);
|
|
1448
1656
|
}
|
|
1449
|
-
if (typeof candidate.idleSec === "number" &&
|
|
1657
|
+
if (typeof candidate.idleSec === "number" &&
|
|
1658
|
+
Number.isFinite(candidate.idleSec)) {
|
|
1450
1659
|
lines.push(`Idle time: ${formatDurationSeconds(candidate.idleSec)}`);
|
|
1451
1660
|
}
|
|
1452
1661
|
pushBooleanField(lines, "App focused", candidate.hasFocus);
|
|
@@ -1496,11 +1705,15 @@ function remoteTriggerResultFields(toolName, rawResult, rawContent) {
|
|
|
1496
1705
|
return undefined;
|
|
1497
1706
|
}
|
|
1498
1707
|
const candidates = resultRecordCandidates(rawResult, rawContent);
|
|
1499
|
-
for (const parsed of [
|
|
1708
|
+
for (const parsed of [
|
|
1709
|
+
parseJsonCandidate(rawResult),
|
|
1710
|
+
parseJsonCandidate(rawContent),
|
|
1711
|
+
]) {
|
|
1500
1712
|
candidates.push(...resultRecordCandidates(parsed, undefined));
|
|
1501
1713
|
}
|
|
1502
1714
|
for (const candidate of candidates) {
|
|
1503
|
-
if (typeof candidate.status !== "number" ||
|
|
1715
|
+
if (typeof candidate.status !== "number" ||
|
|
1716
|
+
typeof candidate.json !== "string") {
|
|
1504
1717
|
continue;
|
|
1505
1718
|
}
|
|
1506
1719
|
const lines = [`Status: ${candidate.status}`];
|
|
@@ -1508,11 +1721,9 @@ function remoteTriggerResultFields(toolName, rawResult, rawContent) {
|
|
|
1508
1721
|
if (summary) {
|
|
1509
1722
|
lines.push(`Summary: ${summary}`);
|
|
1510
1723
|
}
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
lines.push(`Response: ${response}`);
|
|
1515
|
-
}
|
|
1724
|
+
const response = compactParsedJsonString(candidate.json);
|
|
1725
|
+
if (response) {
|
|
1726
|
+
lines.push(`Response: ${response}`);
|
|
1516
1727
|
}
|
|
1517
1728
|
return { output: lines.join("\n"), failed: candidate.status >= 400 };
|
|
1518
1729
|
}
|
|
@@ -1542,7 +1753,10 @@ function replResultFields(toolName, rawResult, rawContent) {
|
|
|
1542
1753
|
return undefined;
|
|
1543
1754
|
}
|
|
1544
1755
|
const candidates = resultRecordCandidates(rawResult, rawContent);
|
|
1545
|
-
for (const parsed of [
|
|
1756
|
+
for (const parsed of [
|
|
1757
|
+
parseJsonCandidate(rawResult),
|
|
1758
|
+
parseJsonCandidate(rawContent),
|
|
1759
|
+
]) {
|
|
1546
1760
|
candidates.push(...resultRecordCandidates(parsed, undefined));
|
|
1547
1761
|
}
|
|
1548
1762
|
for (const candidate of candidates) {
|
|
@@ -1588,18 +1802,68 @@ function replResultFields(toolName, rawResult, rawContent) {
|
|
|
1588
1802
|
}
|
|
1589
1803
|
function collectResultCandidates(rawResult, rawContent) {
|
|
1590
1804
|
const candidates = resultRecordCandidates(rawResult, rawContent);
|
|
1591
|
-
for (const parsed of [
|
|
1805
|
+
for (const parsed of [
|
|
1806
|
+
parseJsonCandidate(rawResult),
|
|
1807
|
+
parseJsonCandidate(rawContent),
|
|
1808
|
+
]) {
|
|
1592
1809
|
candidates.push(...resultRecordCandidates(parsed, undefined));
|
|
1593
1810
|
}
|
|
1594
1811
|
return candidates;
|
|
1595
1812
|
}
|
|
1813
|
+
function parseSkillResult(toolName, rawResult, rawContent) {
|
|
1814
|
+
if (toolName !== SKILL_TOOL_NAME) {
|
|
1815
|
+
return undefined;
|
|
1816
|
+
}
|
|
1817
|
+
for (const candidate of collectResultCandidates(rawResult, rawContent)) {
|
|
1818
|
+
const commandName = nonEmptyString(candidate.commandName);
|
|
1819
|
+
if (!commandName || typeof candidate.success !== "boolean") {
|
|
1820
|
+
continue;
|
|
1821
|
+
}
|
|
1822
|
+
if (candidate.status === "forked") {
|
|
1823
|
+
const agentId = nonEmptyString(candidate.agentId);
|
|
1824
|
+
if (!agentId || typeof candidate.result !== "string") {
|
|
1825
|
+
continue;
|
|
1826
|
+
}
|
|
1827
|
+
if (candidate.background !== undefined &&
|
|
1828
|
+
typeof candidate.background !== "boolean") {
|
|
1829
|
+
continue;
|
|
1830
|
+
}
|
|
1831
|
+
return {
|
|
1832
|
+
success: candidate.success,
|
|
1833
|
+
commandName,
|
|
1834
|
+
status: "forked",
|
|
1835
|
+
agentId,
|
|
1836
|
+
result: candidate.result,
|
|
1837
|
+
...(typeof candidate.background === "boolean"
|
|
1838
|
+
? { background: candidate.background }
|
|
1839
|
+
: {}),
|
|
1840
|
+
};
|
|
1841
|
+
}
|
|
1842
|
+
if (candidate.status === undefined || candidate.status === "inline") {
|
|
1843
|
+
const allowedToolsValid = candidate.allowedTools === undefined ||
|
|
1844
|
+
(Array.isArray(candidate.allowedTools) &&
|
|
1845
|
+
candidate.allowedTools.every((tool) => typeof tool === "string"));
|
|
1846
|
+
const modelValid = candidate.model === undefined || typeof candidate.model === "string";
|
|
1847
|
+
if (!allowedToolsValid || !modelValid) {
|
|
1848
|
+
continue;
|
|
1849
|
+
}
|
|
1850
|
+
return {
|
|
1851
|
+
success: candidate.success,
|
|
1852
|
+
commandName,
|
|
1853
|
+
status: "inline",
|
|
1854
|
+
};
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
return undefined;
|
|
1858
|
+
}
|
|
1596
1859
|
function monitorResultFields(toolName, rawResult, rawContent) {
|
|
1597
1860
|
if (toolName !== MONITOR_TOOL_NAME) {
|
|
1598
1861
|
return undefined;
|
|
1599
1862
|
}
|
|
1600
1863
|
for (const candidate of collectResultCandidates(rawResult, rawContent)) {
|
|
1601
1864
|
const taskId = nonEmptyString(candidate.taskId);
|
|
1602
|
-
const timeoutMs = typeof candidate.timeoutMs === "number" &&
|
|
1865
|
+
const timeoutMs = typeof candidate.timeoutMs === "number" &&
|
|
1866
|
+
Number.isFinite(candidate.timeoutMs)
|
|
1603
1867
|
? Math.max(0, Math.trunc(candidate.timeoutMs))
|
|
1604
1868
|
: undefined;
|
|
1605
1869
|
const persistent = typeof candidate.persistent === "boolean"
|
|
@@ -1609,7 +1873,9 @@ function monitorResultFields(toolName, rawResult, rawContent) {
|
|
|
1609
1873
|
: timeoutMs !== undefined
|
|
1610
1874
|
? false
|
|
1611
1875
|
: undefined;
|
|
1612
|
-
const isStructuredMonitorOutput = taskId !== undefined ||
|
|
1876
|
+
const isStructuredMonitorOutput = taskId !== undefined ||
|
|
1877
|
+
timeoutMs !== undefined ||
|
|
1878
|
+
persistent !== undefined;
|
|
1613
1879
|
if (!isStructuredMonitorOutput) {
|
|
1614
1880
|
continue;
|
|
1615
1881
|
}
|
|
@@ -1728,7 +1994,10 @@ function enterPlanModeStructuredOutputHandled(toolName, rawResult, rawContent) {
|
|
|
1728
1994
|
return false;
|
|
1729
1995
|
}
|
|
1730
1996
|
const candidates = resultRecordCandidates(rawResult, rawContent);
|
|
1731
|
-
for (const parsed of [
|
|
1997
|
+
for (const parsed of [
|
|
1998
|
+
parseJsonCandidate(rawResult),
|
|
1999
|
+
parseJsonCandidate(rawContent),
|
|
2000
|
+
]) {
|
|
1732
2001
|
candidates.push(...resultRecordCandidates(parsed, undefined));
|
|
1733
2002
|
}
|
|
1734
2003
|
for (const candidate of candidates) {
|
|
@@ -1778,10 +2047,12 @@ function webFetchResultText(toolName, rawResult, rawContent) {
|
|
|
1778
2047
|
const codeText = nonEmptyString(candidate.codeText);
|
|
1779
2048
|
lines.push(`Status: ${candidate.code}${codeText ? ` ${codeText}` : ""}`);
|
|
1780
2049
|
}
|
|
1781
|
-
if (typeof candidate.bytes === "number" &&
|
|
2050
|
+
if (typeof candidate.bytes === "number" &&
|
|
2051
|
+
Number.isFinite(candidate.bytes)) {
|
|
1782
2052
|
lines.push(`Bytes: ${Math.max(0, Math.trunc(candidate.bytes))}`);
|
|
1783
2053
|
}
|
|
1784
|
-
if (typeof candidate.durationMs === "number" &&
|
|
2054
|
+
if (typeof candidate.durationMs === "number" &&
|
|
2055
|
+
Number.isFinite(candidate.durationMs)) {
|
|
1785
2056
|
lines.push(`Duration: ${Math.max(0, Math.trunc(candidate.durationMs))}ms`);
|
|
1786
2057
|
}
|
|
1787
2058
|
return lines.length > 0 ? lines.join("\n") : undefined;
|
|
@@ -1797,10 +2068,46 @@ export function buildToolResultFields(isError, rawContent, base, rawResult, _con
|
|
|
1797
2068
|
if (outputMetadata) {
|
|
1798
2069
|
fields.output_metadata = outputMetadata;
|
|
1799
2070
|
}
|
|
1800
|
-
const
|
|
2071
|
+
const skillResult = !isError
|
|
2072
|
+
? parseSkillResult(toolName, rawResult, rawContent)
|
|
2073
|
+
: undefined;
|
|
2074
|
+
if (skillResult) {
|
|
2075
|
+
fields.title = `${SKILL_TOOL_NAME}: ${skillDisplayName(skillResult.commandName)}`;
|
|
2076
|
+
if (!skillResult.success) {
|
|
2077
|
+
fields.status = "failed";
|
|
2078
|
+
}
|
|
2079
|
+
else if (skillResult.status === "inline") {
|
|
2080
|
+
return fields;
|
|
2081
|
+
}
|
|
2082
|
+
else {
|
|
2083
|
+
const output = skillResult.result.trim();
|
|
2084
|
+
if (output) {
|
|
2085
|
+
fields.raw_output = output;
|
|
2086
|
+
fields.content = [
|
|
2087
|
+
{ type: "content", content: { type: "text", text: output } },
|
|
2088
|
+
];
|
|
2089
|
+
}
|
|
2090
|
+
return fields;
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
const imageReadText = !isError && toolName === "Read"
|
|
2094
|
+
? imageReadResultText(rawResult, rawContent, base?.raw_input)
|
|
2095
|
+
: undefined;
|
|
2096
|
+
if (imageReadText !== undefined) {
|
|
2097
|
+
fields.raw_output = imageReadText;
|
|
2098
|
+
fields.content = [
|
|
2099
|
+
{ type: "content", content: { type: "text", text: imageReadText } },
|
|
2100
|
+
];
|
|
2101
|
+
return fields;
|
|
2102
|
+
}
|
|
2103
|
+
const fileUnchangedText = !isError && toolName === "Read"
|
|
2104
|
+
? fileUnchangedResultText(rawResult, rawContent)
|
|
2105
|
+
: "";
|
|
1801
2106
|
if (fileUnchangedText) {
|
|
1802
2107
|
fields.raw_output = fileUnchangedText;
|
|
1803
|
-
fields.content = [
|
|
2108
|
+
fields.content = [
|
|
2109
|
+
{ type: "content", content: { type: "text", text: fileUnchangedText } },
|
|
2110
|
+
];
|
|
1804
2111
|
return fields;
|
|
1805
2112
|
}
|
|
1806
2113
|
const agentTitle = !isError && toolName === "Agent"
|
|
@@ -1813,7 +2120,12 @@ export function buildToolResultFields(isError, rawContent, base, rawResult, _con
|
|
|
1813
2120
|
if (readMcpResourceError) {
|
|
1814
2121
|
fields.status = "failed";
|
|
1815
2122
|
fields.raw_output = readMcpResourceError;
|
|
1816
|
-
fields.content = [
|
|
2123
|
+
fields.content = [
|
|
2124
|
+
{
|
|
2125
|
+
type: "content",
|
|
2126
|
+
content: { type: "text", text: readMcpResourceError },
|
|
2127
|
+
},
|
|
2128
|
+
];
|
|
1817
2129
|
return fields;
|
|
1818
2130
|
}
|
|
1819
2131
|
const readMcpResourceDirOutput = !isError
|
|
@@ -1822,20 +2134,31 @@ export function buildToolResultFields(isError, rawContent, base, rawResult, _con
|
|
|
1822
2134
|
if (readMcpResourceDirOutput !== undefined) {
|
|
1823
2135
|
fields.raw_output = readMcpResourceDirOutput;
|
|
1824
2136
|
fields.content = [
|
|
1825
|
-
{
|
|
2137
|
+
{
|
|
2138
|
+
type: "content",
|
|
2139
|
+
content: { type: "text", text: readMcpResourceDirOutput },
|
|
2140
|
+
},
|
|
1826
2141
|
];
|
|
1827
2142
|
return fields;
|
|
1828
2143
|
}
|
|
1829
|
-
const searchOutput = !isError
|
|
2144
|
+
const searchOutput = !isError
|
|
2145
|
+
? searchResultText(toolName, rawResult, rawContent)
|
|
2146
|
+
: undefined;
|
|
1830
2147
|
if (searchOutput !== undefined) {
|
|
1831
2148
|
fields.raw_output = searchOutput;
|
|
1832
|
-
fields.content = [
|
|
2149
|
+
fields.content = [
|
|
2150
|
+
{ type: "content", content: { type: "text", text: searchOutput } },
|
|
2151
|
+
];
|
|
1833
2152
|
return fields;
|
|
1834
2153
|
}
|
|
1835
|
-
const webFetchOutput = !isError
|
|
2154
|
+
const webFetchOutput = !isError
|
|
2155
|
+
? webFetchResultText(toolName, rawResult, rawContent)
|
|
2156
|
+
: undefined;
|
|
1836
2157
|
if (webFetchOutput !== undefined) {
|
|
1837
2158
|
fields.raw_output = webFetchOutput;
|
|
1838
|
-
fields.content = [
|
|
2159
|
+
fields.content = [
|
|
2160
|
+
{ type: "content", content: { type: "text", text: webFetchOutput } },
|
|
2161
|
+
];
|
|
1839
2162
|
return fields;
|
|
1840
2163
|
}
|
|
1841
2164
|
const worktreeOutput = !isError
|
|
@@ -1845,7 +2168,10 @@ export function buildToolResultFields(isError, rawContent, base, rawResult, _con
|
|
|
1845
2168
|
if (worktreeOutput.output) {
|
|
1846
2169
|
fields.raw_output = worktreeOutput.output;
|
|
1847
2170
|
fields.content = [
|
|
1848
|
-
{
|
|
2171
|
+
{
|
|
2172
|
+
type: "content",
|
|
2173
|
+
content: { type: "text", text: worktreeOutput.output },
|
|
2174
|
+
},
|
|
1849
2175
|
];
|
|
1850
2176
|
}
|
|
1851
2177
|
return fields;
|
|
@@ -1855,7 +2181,9 @@ export function buildToolResultFields(isError, rawContent, base, rawResult, _con
|
|
|
1855
2181
|
: undefined;
|
|
1856
2182
|
if (cronOutput !== undefined) {
|
|
1857
2183
|
fields.raw_output = cronOutput;
|
|
1858
|
-
fields.content = [
|
|
2184
|
+
fields.content = [
|
|
2185
|
+
{ type: "content", content: { type: "text", text: cronOutput } },
|
|
2186
|
+
];
|
|
1859
2187
|
return fields;
|
|
1860
2188
|
}
|
|
1861
2189
|
const scheduleWakeupOutput = !isError
|
|
@@ -1864,7 +2192,10 @@ export function buildToolResultFields(isError, rawContent, base, rawResult, _con
|
|
|
1864
2192
|
if (scheduleWakeupOutput !== undefined) {
|
|
1865
2193
|
fields.raw_output = scheduleWakeupOutput;
|
|
1866
2194
|
fields.content = [
|
|
1867
|
-
{
|
|
2195
|
+
{
|
|
2196
|
+
type: "content",
|
|
2197
|
+
content: { type: "text", text: scheduleWakeupOutput },
|
|
2198
|
+
},
|
|
1868
2199
|
];
|
|
1869
2200
|
return fields;
|
|
1870
2201
|
}
|
|
@@ -1874,7 +2205,10 @@ export function buildToolResultFields(isError, rawContent, base, rawResult, _con
|
|
|
1874
2205
|
if (pushNotificationOutput !== undefined) {
|
|
1875
2206
|
fields.raw_output = pushNotificationOutput;
|
|
1876
2207
|
fields.content = [
|
|
1877
|
-
{
|
|
2208
|
+
{
|
|
2209
|
+
type: "content",
|
|
2210
|
+
content: { type: "text", text: pushNotificationOutput },
|
|
2211
|
+
},
|
|
1878
2212
|
];
|
|
1879
2213
|
return fields;
|
|
1880
2214
|
}
|
|
@@ -1890,7 +2224,10 @@ export function buildToolResultFields(isError, rawContent, base, rawResult, _con
|
|
|
1890
2224
|
if (remoteTriggerOutput.output) {
|
|
1891
2225
|
fields.raw_output = remoteTriggerOutput.output;
|
|
1892
2226
|
fields.content = [
|
|
1893
|
-
{
|
|
2227
|
+
{
|
|
2228
|
+
type: "content",
|
|
2229
|
+
content: { type: "text", text: remoteTriggerOutput.output },
|
|
2230
|
+
},
|
|
1894
2231
|
];
|
|
1895
2232
|
}
|
|
1896
2233
|
return fields;
|
|
@@ -1920,7 +2257,10 @@ export function buildToolResultFields(isError, rawContent, base, rawResult, _con
|
|
|
1920
2257
|
if (backgroundLaunchOutput.output) {
|
|
1921
2258
|
fields.raw_output = backgroundLaunchOutput.output;
|
|
1922
2259
|
fields.content = [
|
|
1923
|
-
{
|
|
2260
|
+
{
|
|
2261
|
+
type: "content",
|
|
2262
|
+
content: { type: "text", text: backgroundLaunchOutput.output },
|
|
2263
|
+
},
|
|
1924
2264
|
];
|
|
1925
2265
|
}
|
|
1926
2266
|
return fields;
|
|
@@ -1936,15 +2276,21 @@ export function buildToolResultFields(isError, rawContent, base, rawResult, _con
|
|
|
1936
2276
|
fields.raw_output = rawOutput;
|
|
1937
2277
|
}
|
|
1938
2278
|
if (!isError && isTaskToolName(toolName)) {
|
|
1939
|
-
if (toolName === "TaskUpdate" &&
|
|
2279
|
+
if (toolName === "TaskUpdate" &&
|
|
2280
|
+
taskUpdateSucceeded(rawResult, rawContent) === false) {
|
|
1940
2281
|
fields.status = "failed";
|
|
1941
2282
|
}
|
|
1942
2283
|
const taskOutput = taskToolResultText(toolName, rawResult, rawContent, base?.raw_input);
|
|
1943
2284
|
if (taskOutput) {
|
|
1944
|
-
fields.content = [
|
|
2285
|
+
fields.content = [
|
|
2286
|
+
{ type: "content", content: { type: "text", text: taskOutput } },
|
|
2287
|
+
];
|
|
1945
2288
|
return fields;
|
|
1946
2289
|
}
|
|
1947
|
-
if (toolName === "TaskCreate" ||
|
|
2290
|
+
if (toolName === "TaskCreate" ||
|
|
2291
|
+
toolName === "TaskUpdate" ||
|
|
2292
|
+
toolName === "TaskOutput" ||
|
|
2293
|
+
toolName === "TaskStop") {
|
|
1948
2294
|
return fields;
|
|
1949
2295
|
}
|
|
1950
2296
|
}
|
|
@@ -1978,7 +2324,9 @@ export function buildToolResultFields(isError, rawContent, base, rawResult, _con
|
|
|
1978
2324
|
}
|
|
1979
2325
|
}
|
|
1980
2326
|
if (rawOutput) {
|
|
1981
|
-
fields.content = [
|
|
2327
|
+
fields.content = [
|
|
2328
|
+
{ type: "content", content: { type: "text", text: rawOutput } },
|
|
2329
|
+
];
|
|
1982
2330
|
}
|
|
1983
2331
|
return fields;
|
|
1984
2332
|
}
|