claude-code-rust 0.14.3 → 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 +288 -66
- 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 +22 -8
- package/agent-sdk/dist/bridge/tasks.js +62 -22
- package/agent-sdk/dist/bridge/tool_calls.js +82 -25
- package/agent-sdk/dist/bridge/tooling.js +304 -86
- package/agent-sdk/dist/bridge/user_interaction.js +45 -13
- package/agent-sdk/dist/bridge.js +200 -104
- package/package.json +8 -8
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { asRecordOrNull } from "./shared.js";
|
|
2
|
-
import { toPermissionMode, buildModeState, refreshSupportedModesForSession } from "./commands.js";
|
|
2
|
+
import { toPermissionMode, buildModeState, refreshSupportedModesForSession, } from "./commands.js";
|
|
3
3
|
import { writeEvent, emitSessionUpdate, emitConnectEvent, emitSessionReplacedEvent, } from "./events.js";
|
|
4
4
|
import { TOOL_RESULT_TYPES, isToolSearchToolName, isToolSearchToolResultType, unwrapToolUseResult, parseToolNonExecutionMetadata, } from "./tooling.js";
|
|
5
5
|
import { emitToolCall, emitToolCallUpdate, emitToolResultUpdate, finalizeOpenToolCalls, emitToolProgressUpdate, emitToolSummaryUpdate, ensureToolCallVisible, resolveTaskToolUseId, defersTaskNotificationCompletion, toolAcceptsTaskLifecycle, taskProgressText, taskUpdatedFields, } from "./tool_calls.js";
|
|
6
|
-
import { applyBackgroundTasksChanged, applyTaskLifecycleState } from "./tasks.js";
|
|
6
|
+
import { applyBackgroundTasksChanged, applyTaskLifecycleState, } from "./tasks.js";
|
|
7
7
|
import { linkTaskToolUse, unlinkTaskToolUse } from "./task_links.js";
|
|
8
8
|
import { emitAuthRequired, classifyTurnErrorKind, emitFastModeUpdate, emitFastModeUpdateIfChanged, setFastModeSnapshotIfChanged, } from "./error_classification.js";
|
|
9
|
-
import { mapAvailableAgentsFromNames, emitAvailableAgentsIfChanged, refreshAvailableAgents } from "./agents.js";
|
|
9
|
+
import { mapAvailableAgentsFromNames, emitAvailableAgentsIfChanged, refreshAvailableAgents, } from "./agents.js";
|
|
10
10
|
import { mapInitSlashCommands, mapSdkSlashCommands, updateAvailableCommands, } from "./available_commands.js";
|
|
11
11
|
import { buildApiRetryUpdate, buildRateLimitUpdate, buildSubagentRetryUpdate, normalizeSettingsParseErrors, nonNegativeIntegerField, numberField, parseApiRetryError, parseRuntimeSessionState, } from "./state_parsing.js";
|
|
12
12
|
import { looksLikeAuthRequired } from "./auth.js";
|
|
13
|
-
import { emitCurrentModelUpdate, refreshCurrentModel, updateSessionId } from "./session_lifecycle.js";
|
|
13
|
+
import { emitCurrentModelUpdate, refreshCurrentModel, updateSessionId, } from "./session_lifecycle.js";
|
|
14
14
|
import { bridgeLogger, LOG_TARGETS } from "./logger.js";
|
|
15
15
|
import { emitMcpSnapshotFromStatuses } from "./mcp.js";
|
|
16
16
|
export function textFromPrompt(command) {
|
|
@@ -38,23 +38,41 @@ function sdkCorrelationMetadata(msg) {
|
|
|
38
38
|
return {
|
|
39
39
|
requestId: typeof msg.request_id === "string" ? msg.request_id : undefined,
|
|
40
40
|
subagentType: typeof msg.subagent_type === "string" ? msg.subagent_type : undefined,
|
|
41
|
-
taskDescription: typeof msg.task_description === "string"
|
|
41
|
+
taskDescription: typeof msg.task_description === "string"
|
|
42
|
+
? msg.task_description
|
|
43
|
+
: undefined,
|
|
42
44
|
parentAgentId: typeof msg.parent_agent_id === "string" ? msg.parent_agent_id : undefined,
|
|
43
45
|
};
|
|
44
46
|
}
|
|
45
47
|
function sdkTaskMetadata(msg) {
|
|
46
48
|
const metadata = sdkCorrelationMetadata(msg);
|
|
47
|
-
const taskType = typeof msg.task_type === "string" && msg.task_type.length > 0
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
const taskType = typeof msg.task_type === "string" && msg.task_type.length > 0
|
|
50
|
+
? msg.task_type
|
|
51
|
+
: undefined;
|
|
52
|
+
const workflowName = typeof msg.workflow_name === "string" && msg.workflow_name.length > 0
|
|
53
|
+
? msg.workflow_name
|
|
54
|
+
: undefined;
|
|
55
|
+
const prompt = typeof msg.prompt === "string" && msg.prompt.length > 0
|
|
56
|
+
? msg.prompt
|
|
57
|
+
: undefined;
|
|
58
|
+
const outputFile = typeof msg.output_file === "string" && msg.output_file.length > 0
|
|
59
|
+
? msg.output_file
|
|
60
|
+
: undefined;
|
|
61
|
+
const status = typeof msg.status === "string" && msg.status.length > 0
|
|
62
|
+
? msg.status
|
|
63
|
+
: undefined;
|
|
64
|
+
const summary = status && typeof msg.summary === "string" && msg.summary.length > 0
|
|
65
|
+
? msg.summary
|
|
66
|
+
: undefined;
|
|
53
67
|
const taskMetadata = {
|
|
54
68
|
...(metadata.requestId ? { request_id: metadata.requestId } : {}),
|
|
55
69
|
...(metadata.subagentType ? { subagent_type: metadata.subagentType } : {}),
|
|
56
|
-
...(metadata.taskDescription
|
|
57
|
-
|
|
70
|
+
...(metadata.taskDescription
|
|
71
|
+
? { task_description: metadata.taskDescription }
|
|
72
|
+
: {}),
|
|
73
|
+
...(metadata.parentAgentId
|
|
74
|
+
? { parent_agent_id: metadata.parentAgentId }
|
|
75
|
+
: {}),
|
|
58
76
|
...(taskType ? { task_type: taskType } : {}),
|
|
59
77
|
...(workflowName ? { workflow_name: workflowName } : {}),
|
|
60
78
|
...(prompt ? { prompt } : {}),
|
|
@@ -66,10 +84,67 @@ function sdkTaskMetadata(msg) {
|
|
|
66
84
|
return Object.keys(taskMetadata).length > 0 ? taskMetadata : undefined;
|
|
67
85
|
}
|
|
68
86
|
function sdkMessageOriginKind(msg) {
|
|
69
|
-
const origin = msg.origin && typeof msg.origin === "object"
|
|
87
|
+
const origin = msg.origin && typeof msg.origin === "object"
|
|
88
|
+
? msg.origin
|
|
89
|
+
: null;
|
|
70
90
|
return typeof origin?.kind === "string" ? origin.kind : undefined;
|
|
71
91
|
}
|
|
92
|
+
function externalMessageUpdateFromSdkUser(msg) {
|
|
93
|
+
const origin = asRecordOrNull(msg.origin);
|
|
94
|
+
if (!origin) {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
const kind = typeof origin?.kind === "string" ? origin.kind : undefined;
|
|
98
|
+
if (kind !== "peer" && kind !== "task-notification") {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
const payload = asRecordOrNull(msg.message);
|
|
102
|
+
const content = payload?.content;
|
|
103
|
+
const contentText = typeof content === "string"
|
|
104
|
+
? content
|
|
105
|
+
: Array.isArray(content)
|
|
106
|
+
? content
|
|
107
|
+
.flatMap((block) => {
|
|
108
|
+
const record = asRecordOrNull(block);
|
|
109
|
+
return record?.type === "text" && typeof record.text === "string"
|
|
110
|
+
? [record.text]
|
|
111
|
+
: [];
|
|
112
|
+
})
|
|
113
|
+
.join("\n")
|
|
114
|
+
: "";
|
|
115
|
+
const text = typeof origin.body === "string" ? origin.body : contentText;
|
|
116
|
+
if (!text.trim()) {
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
type: "external_message_update",
|
|
121
|
+
content: text,
|
|
122
|
+
...(sourceMessageUuid(msg)
|
|
123
|
+
? { source_message_uuid: sourceMessageUuid(msg) }
|
|
124
|
+
: {}),
|
|
125
|
+
origin: {
|
|
126
|
+
kind,
|
|
127
|
+
...(typeof origin.subkind === "string"
|
|
128
|
+
? { subkind: origin.subkind }
|
|
129
|
+
: {}),
|
|
130
|
+
...(typeof origin.from === "string" ? { from: origin.from } : {}),
|
|
131
|
+
...(typeof origin.name === "string" ? { name: origin.name } : {}),
|
|
132
|
+
...(typeof origin.fromSession === "string"
|
|
133
|
+
? { from_session: origin.fromSession }
|
|
134
|
+
: {}),
|
|
135
|
+
...(typeof origin.senderTaskId === "string"
|
|
136
|
+
? { sender_task_id: origin.senderTaskId }
|
|
137
|
+
: {}),
|
|
138
|
+
...(typeof origin.verifiedPeerPid === "number" &&
|
|
139
|
+
Number.isSafeInteger(origin.verifiedPeerPid) &&
|
|
140
|
+
origin.verifiedPeerPid >= 0
|
|
141
|
+
? { verified_peer_pid: origin.verifiedPeerPid }
|
|
142
|
+
: {}),
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
72
146
|
function logSdkMessageOrigin(session, msg) {
|
|
147
|
+
const origin = asRecordOrNull(msg.origin);
|
|
73
148
|
const originKind = sdkMessageOriginKind(msg);
|
|
74
149
|
if (!originKind) {
|
|
75
150
|
return;
|
|
@@ -83,6 +158,16 @@ function logSdkMessageOrigin(session, msg) {
|
|
|
83
158
|
fields: {
|
|
84
159
|
message_type: typeof msg.type === "string" ? msg.type : undefined,
|
|
85
160
|
origin_kind: originKind,
|
|
161
|
+
origin_subkind: typeof origin?.subkind === "string" ? origin.subkind : undefined,
|
|
162
|
+
origin_from_session: typeof origin?.fromSession === "string"
|
|
163
|
+
? origin.fromSession
|
|
164
|
+
: undefined,
|
|
165
|
+
origin_sender_task_id: typeof origin?.senderTaskId === "string"
|
|
166
|
+
? origin.senderTaskId
|
|
167
|
+
: undefined,
|
|
168
|
+
origin_verified_peer_pid: typeof origin?.verifiedPeerPid === "number"
|
|
169
|
+
? origin.verifiedPeerPid
|
|
170
|
+
: undefined,
|
|
86
171
|
},
|
|
87
172
|
});
|
|
88
173
|
}
|
|
@@ -91,7 +176,11 @@ function emitSystemNoticeUpdate(session, severity, message) {
|
|
|
91
176
|
if (!trimmed) {
|
|
92
177
|
return;
|
|
93
178
|
}
|
|
94
|
-
emitSessionUpdate(session.sessionId, {
|
|
179
|
+
emitSessionUpdate(session.sessionId, {
|
|
180
|
+
type: "system_notice_update",
|
|
181
|
+
severity,
|
|
182
|
+
message: trimmed,
|
|
183
|
+
});
|
|
95
184
|
}
|
|
96
185
|
const MAX_INFORMATIONAL_DEDUP_KEYS = 256;
|
|
97
186
|
function shouldEmitInformationalMessage(session, level, content, toolUseId) {
|
|
@@ -203,7 +292,9 @@ function handleModelRefusalNoFallbackMessage(session, msg) {
|
|
|
203
292
|
}
|
|
204
293
|
function workerShutdownMessage(reason) {
|
|
205
294
|
const trimmed = reason.trim();
|
|
206
|
-
return trimmed
|
|
295
|
+
return trimmed
|
|
296
|
+
? `Claude worker is shutting down: ${trimmed}`
|
|
297
|
+
: "Claude worker is shutting down.";
|
|
207
298
|
}
|
|
208
299
|
function handleWorkerShuttingDownSystemMessage(session, msg) {
|
|
209
300
|
const reason = typeof msg.reason === "string" ? msg.reason.trim() : "";
|
|
@@ -280,7 +371,9 @@ export function contentFromPrompt(command) {
|
|
|
280
371
|
}
|
|
281
372
|
}
|
|
282
373
|
else if (chunk.kind === "image") {
|
|
283
|
-
const val = chunk.value && typeof chunk.value === "object"
|
|
374
|
+
const val = chunk.value && typeof chunk.value === "object"
|
|
375
|
+
? chunk.value
|
|
376
|
+
: null;
|
|
284
377
|
if (!val)
|
|
285
378
|
continue;
|
|
286
379
|
const data = typeof val.data === "string" ? val.data : "";
|
|
@@ -400,7 +493,9 @@ export function handleTaskSystemMessage(session, subtype, msg) {
|
|
|
400
493
|
const fields = {
|
|
401
494
|
status: "in_progress",
|
|
402
495
|
raw_output: description,
|
|
403
|
-
content: [
|
|
496
|
+
content: [
|
|
497
|
+
{ type: "content", content: { type: "text", text: description } },
|
|
498
|
+
],
|
|
404
499
|
...(messageTaskMetadata ? { task_metadata: messageTaskMetadata } : {}),
|
|
405
500
|
};
|
|
406
501
|
emitToolCallUpdate(session, toolUseId, fields, "task_started");
|
|
@@ -423,7 +518,10 @@ export function handleTaskSystemMessage(session, subtype, msg) {
|
|
|
423
518
|
if (subtype === "task_updated") {
|
|
424
519
|
const fields = taskUpdatedFields(msg);
|
|
425
520
|
if (messageTaskMetadata) {
|
|
426
|
-
fields.task_metadata = {
|
|
521
|
+
fields.task_metadata = {
|
|
522
|
+
...(fields.task_metadata ?? {}),
|
|
523
|
+
...messageTaskMetadata,
|
|
524
|
+
};
|
|
427
525
|
}
|
|
428
526
|
if (Object.keys(fields).length === 0) {
|
|
429
527
|
return true;
|
|
@@ -451,15 +549,23 @@ export function handleTaskSystemMessage(session, subtype, msg) {
|
|
|
451
549
|
}
|
|
452
550
|
const status = typeof msg.status === "string" ? msg.status : "";
|
|
453
551
|
const summary = typeof msg.summary === "string" ? msg.summary : "";
|
|
454
|
-
const finalStatus = status === "completed"
|
|
552
|
+
const finalStatus = status === "completed"
|
|
553
|
+
? "completed"
|
|
554
|
+
: status === "stopped"
|
|
555
|
+
? "killed"
|
|
556
|
+
: "failed";
|
|
455
557
|
const deferCompletion = finalStatus === "completed" && defersTaskNotificationCompletion(toolCall);
|
|
456
|
-
const fields = deferCompletion
|
|
558
|
+
const fields = deferCompletion
|
|
559
|
+
? {}
|
|
560
|
+
: { status: finalStatus };
|
|
457
561
|
if (messageTaskMetadata) {
|
|
458
562
|
fields.task_metadata = messageTaskMetadata;
|
|
459
563
|
}
|
|
460
564
|
if (summary) {
|
|
461
565
|
fields.raw_output = summary;
|
|
462
|
-
fields.content = [
|
|
566
|
+
fields.content = [
|
|
567
|
+
{ type: "content", content: { type: "text", text: summary } },
|
|
568
|
+
];
|
|
463
569
|
}
|
|
464
570
|
if (Object.keys(fields).length > 0) {
|
|
465
571
|
emitToolCallUpdate(session, toolUseId, fields, "task_notification");
|
|
@@ -510,10 +616,19 @@ function emitTranscriptRetraction(session, messageUuids, reason, metadata = {})
|
|
|
510
616
|
...(metadata.requestId ? { request_id: metadata.requestId } : {}),
|
|
511
617
|
...(metadata.trigger ? { trigger: metadata.trigger } : {}),
|
|
512
618
|
...(metadata.direction ? { direction: metadata.direction } : {}),
|
|
513
|
-
...(metadata.originalModel
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
...(metadata.
|
|
619
|
+
...(metadata.originalModel
|
|
620
|
+
? { original_model: metadata.originalModel }
|
|
621
|
+
: {}),
|
|
622
|
+
...(metadata.fallbackModel
|
|
623
|
+
? { fallback_model: metadata.fallbackModel }
|
|
624
|
+
: {}),
|
|
625
|
+
...(metadata.scope ? { scope: metadata.scope } : {}),
|
|
626
|
+
...(metadata.apiRefusalCategory
|
|
627
|
+
? { api_refusal_category: metadata.apiRefusalCategory }
|
|
628
|
+
: {}),
|
|
629
|
+
...(metadata.apiRefusalExplanation
|
|
630
|
+
? { api_refusal_explanation: metadata.apiRefusalExplanation }
|
|
631
|
+
: {}),
|
|
517
632
|
...(metadata.content ? { content: metadata.content } : {}),
|
|
518
633
|
});
|
|
519
634
|
return true;
|
|
@@ -530,6 +645,7 @@ function handleFallbackRetractionMessage(session, subtype, msg) {
|
|
|
530
645
|
direction: stringField(msg, "direction"),
|
|
531
646
|
originalModel: stringField(msg, "original_model"),
|
|
532
647
|
fallbackModel: stringField(msg, "fallback_model"),
|
|
648
|
+
scope: stringField(msg, "scope") ?? "session",
|
|
533
649
|
apiRefusalCategory: nullableStringField(msg, "api_refusal_category"),
|
|
534
650
|
apiRefusalExplanation: nullableStringField(msg, "api_refusal_explanation"),
|
|
535
651
|
content: stringField(msg, "content"),
|
|
@@ -549,6 +665,7 @@ function handleFallbackRetractionMessage(session, subtype, msg) {
|
|
|
549
665
|
direction: metadata.direction,
|
|
550
666
|
original_model: metadata.originalModel,
|
|
551
667
|
fallback_model: metadata.fallbackModel,
|
|
668
|
+
scope: metadata.scope,
|
|
552
669
|
api_refusal_category: metadata.apiRefusalCategory,
|
|
553
670
|
has_api_refusal_explanation: metadata.apiRefusalExplanation !== undefined,
|
|
554
671
|
has_content: metadata.content !== undefined,
|
|
@@ -621,7 +738,9 @@ export function handleContentBlock(session, block, linkage) {
|
|
|
621
738
|
emitSessionUpdate(session.sessionId, {
|
|
622
739
|
type: "agent_message_chunk",
|
|
623
740
|
content: { type: "text", text },
|
|
624
|
-
...(linkage?.sourceMessageUuid
|
|
741
|
+
...(linkage?.sourceMessageUuid
|
|
742
|
+
? { source_message_uuid: linkage.sourceMessageUuid }
|
|
743
|
+
: {}),
|
|
625
744
|
});
|
|
626
745
|
}
|
|
627
746
|
return;
|
|
@@ -632,15 +751,21 @@ export function handleContentBlock(session, block, linkage) {
|
|
|
632
751
|
emitSessionUpdate(session.sessionId, {
|
|
633
752
|
type: "agent_thought_chunk",
|
|
634
753
|
content: { type: "text", text },
|
|
635
|
-
...(linkage?.sourceMessageUuid
|
|
754
|
+
...(linkage?.sourceMessageUuid
|
|
755
|
+
? { source_message_uuid: linkage.sourceMessageUuid }
|
|
756
|
+
: {}),
|
|
636
757
|
});
|
|
637
758
|
}
|
|
638
759
|
return;
|
|
639
760
|
}
|
|
640
|
-
if (blockType === "tool_use" ||
|
|
761
|
+
if (blockType === "tool_use" ||
|
|
762
|
+
blockType === "server_tool_use" ||
|
|
763
|
+
blockType === "mcp_tool_use") {
|
|
641
764
|
const toolUseId = typeof block.id === "string" ? block.id : "";
|
|
642
765
|
const name = typeof block.name === "string" ? block.name : "Tool";
|
|
643
|
-
const input = block.input && typeof block.input === "object"
|
|
766
|
+
const input = block.input && typeof block.input === "object"
|
|
767
|
+
? block.input
|
|
768
|
+
: {};
|
|
644
769
|
if (!toolUseId) {
|
|
645
770
|
return;
|
|
646
771
|
}
|
|
@@ -688,7 +813,9 @@ export function handleStreamEvent(session, event, parentToolUseId, sourceMessage
|
|
|
688
813
|
emitSessionUpdate(session.sessionId, {
|
|
689
814
|
type: "agent_message_chunk",
|
|
690
815
|
content: { type: "text", text },
|
|
691
|
-
...(sourceMessageUuid
|
|
816
|
+
...(sourceMessageUuid
|
|
817
|
+
? { source_message_uuid: sourceMessageUuid }
|
|
818
|
+
: {}),
|
|
692
819
|
});
|
|
693
820
|
}
|
|
694
821
|
}
|
|
@@ -698,7 +825,9 @@ export function handleStreamEvent(session, event, parentToolUseId, sourceMessage
|
|
|
698
825
|
emitSessionUpdate(session.sessionId, {
|
|
699
826
|
type: "agent_thought_chunk",
|
|
700
827
|
content: { type: "text", text },
|
|
701
|
-
...(sourceMessageUuid
|
|
828
|
+
...(sourceMessageUuid
|
|
829
|
+
? { source_message_uuid: sourceMessageUuid }
|
|
830
|
+
: {}),
|
|
702
831
|
});
|
|
703
832
|
}
|
|
704
833
|
}
|
|
@@ -718,7 +847,9 @@ export function handleAssistantMessage(session, message) {
|
|
|
718
847
|
if (!messageObject) {
|
|
719
848
|
return;
|
|
720
849
|
}
|
|
721
|
-
const content = Array.isArray(messageObject.content)
|
|
850
|
+
const content = Array.isArray(messageObject.content)
|
|
851
|
+
? messageObject.content
|
|
852
|
+
: [];
|
|
722
853
|
for (const block of content) {
|
|
723
854
|
if (!block || typeof block !== "object") {
|
|
724
855
|
continue;
|
|
@@ -729,7 +860,9 @@ export function handleAssistantMessage(session, message) {
|
|
|
729
860
|
blockType === "server_tool_use" ||
|
|
730
861
|
blockType === "mcp_tool_use" ||
|
|
731
862
|
TOOL_RESULT_TYPES.has(blockType)) {
|
|
732
|
-
const parentToolUseId = typeof message.parent_tool_use_id === "string"
|
|
863
|
+
const parentToolUseId = typeof message.parent_tool_use_id === "string"
|
|
864
|
+
? message.parent_tool_use_id
|
|
865
|
+
: undefined;
|
|
733
866
|
handleContentBlock(session, blockRecord, {
|
|
734
867
|
source: "assistant",
|
|
735
868
|
parentToolUseId,
|
|
@@ -755,7 +888,9 @@ export function handleUserToolResultBlocks(session, message) {
|
|
|
755
888
|
if (!messageObject) {
|
|
756
889
|
return false;
|
|
757
890
|
}
|
|
758
|
-
const content = Array.isArray(messageObject.content)
|
|
891
|
+
const content = Array.isArray(messageObject.content)
|
|
892
|
+
? messageObject.content
|
|
893
|
+
: [];
|
|
759
894
|
const nonExecutionByToolUseId = parseToolNonExecutionMetadata(message.tool_result_meta);
|
|
760
895
|
let handled = false;
|
|
761
896
|
for (const block of content) {
|
|
@@ -765,8 +900,12 @@ export function handleUserToolResultBlocks(session, message) {
|
|
|
765
900
|
const blockRecord = block;
|
|
766
901
|
const blockType = typeof blockRecord.type === "string" ? blockRecord.type : "";
|
|
767
902
|
if (TOOL_RESULT_TYPES.has(blockType)) {
|
|
768
|
-
const parentToolUseId = typeof message.parent_tool_use_id === "string"
|
|
769
|
-
|
|
903
|
+
const parentToolUseId = typeof message.parent_tool_use_id === "string"
|
|
904
|
+
? message.parent_tool_use_id
|
|
905
|
+
: undefined;
|
|
906
|
+
const toolUseId = typeof blockRecord.tool_use_id === "string"
|
|
907
|
+
? blockRecord.tool_use_id
|
|
908
|
+
: "";
|
|
770
909
|
if (!toolUseId) {
|
|
771
910
|
continue;
|
|
772
911
|
}
|
|
@@ -798,9 +937,30 @@ export function handleResultMessage(session, message) {
|
|
|
798
937
|
});
|
|
799
938
|
return;
|
|
800
939
|
}
|
|
801
|
-
const errors = Array.isArray(message.errors) &&
|
|
940
|
+
const errors = Array.isArray(message.errors) &&
|
|
941
|
+
message.errors.every((entry) => typeof entry === "string")
|
|
802
942
|
? message.errors
|
|
803
943
|
: [];
|
|
944
|
+
const resumeDropsTurnRefusal = errors.find((entry) => entry.startsWith("Resume rejected by --resume-drops-turn:"));
|
|
945
|
+
if (session.deferConnect &&
|
|
946
|
+
session.resumeDropsTurn &&
|
|
947
|
+
resumeDropsTurnRefusal) {
|
|
948
|
+
session.initializationReady = false;
|
|
949
|
+
session.initializationError = resumeDropsTurnRefusal;
|
|
950
|
+
bridgeLogger.warn({
|
|
951
|
+
target: LOG_TARGETS.APP_SESSION,
|
|
952
|
+
eventName: "session_resume_drops_turn_rejected",
|
|
953
|
+
message: "guarded resume candidate rejected because the source session changed",
|
|
954
|
+
outcome: "failure",
|
|
955
|
+
sessionId: session.sessionId,
|
|
956
|
+
fields: {
|
|
957
|
+
drop_turn_id: session.resumeDropsTurn,
|
|
958
|
+
validation_fence_complete: session.resumeGuardFenceComplete === true,
|
|
959
|
+
error_message: resumeDropsTurnRefusal,
|
|
960
|
+
},
|
|
961
|
+
});
|
|
962
|
+
return;
|
|
963
|
+
}
|
|
804
964
|
const assistantError = session.lastAssistantError;
|
|
805
965
|
const authHint = errors.find((entry) => looksLikeAuthRequired(entry));
|
|
806
966
|
if (authHint) {
|
|
@@ -820,7 +980,9 @@ export function handleResultMessage(session, message) {
|
|
|
820
980
|
error_kind: errorKind,
|
|
821
981
|
...(subtype ? { sdk_result_subtype: subtype } : {}),
|
|
822
982
|
...(assistantError ? { assistant_error: assistantError } : {}),
|
|
823
|
-
...(apiErrorStatus !== undefined
|
|
983
|
+
...(apiErrorStatus !== undefined
|
|
984
|
+
? { api_error_status: apiErrorStatus }
|
|
985
|
+
: {}),
|
|
824
986
|
...(terminalReason ? { terminal_reason: terminalReason } : {}),
|
|
825
987
|
});
|
|
826
988
|
session.lastAssistantError = undefined;
|
|
@@ -940,8 +1102,12 @@ export function handleSdkMessage(session, message) {
|
|
|
940
1102
|
fields: {
|
|
941
1103
|
tool_name: typeof msg.tool_name === "string" ? msg.tool_name : undefined,
|
|
942
1104
|
agent_id: typeof msg.agent_id === "string" ? msg.agent_id : undefined,
|
|
943
|
-
decision_reason_type: typeof msg.decision_reason_type === "string"
|
|
944
|
-
|
|
1105
|
+
decision_reason_type: typeof msg.decision_reason_type === "string"
|
|
1106
|
+
? msg.decision_reason_type
|
|
1107
|
+
: undefined,
|
|
1108
|
+
decision_reason: typeof msg.decision_reason === "string"
|
|
1109
|
+
? msg.decision_reason
|
|
1110
|
+
: undefined,
|
|
945
1111
|
denial_message: typeof msg.message === "string" ? msg.message : undefined,
|
|
946
1112
|
},
|
|
947
1113
|
});
|
|
@@ -956,9 +1122,15 @@ export function handleSdkMessage(session, message) {
|
|
|
956
1122
|
sessionId: session.sessionId,
|
|
957
1123
|
fields: {
|
|
958
1124
|
sdk_subtype: subtype,
|
|
959
|
-
memory_count: Array.isArray(msg.memories)
|
|
960
|
-
|
|
961
|
-
|
|
1125
|
+
memory_count: Array.isArray(msg.memories)
|
|
1126
|
+
? msg.memories.length
|
|
1127
|
+
: undefined,
|
|
1128
|
+
estimated_tokens: typeof msg.estimated_tokens === "number"
|
|
1129
|
+
? msg.estimated_tokens
|
|
1130
|
+
: undefined,
|
|
1131
|
+
estimated_tokens_delta: typeof msg.estimated_tokens_delta === "number"
|
|
1132
|
+
? msg.estimated_tokens_delta
|
|
1133
|
+
: undefined,
|
|
962
1134
|
},
|
|
963
1135
|
});
|
|
964
1136
|
return;
|
|
@@ -987,7 +1159,9 @@ export function handleSdkMessage(session, message) {
|
|
|
987
1159
|
const modelName = typeof msg.model === "string" ? msg.model : session.model;
|
|
988
1160
|
session.model = modelName;
|
|
989
1161
|
const currentModelChanged = refreshCurrentModel(session, false);
|
|
990
|
-
const incomingMode = typeof msg.permissionMode === "string"
|
|
1162
|
+
const incomingMode = typeof msg.permissionMode === "string"
|
|
1163
|
+
? toPermissionMode(msg.permissionMode)
|
|
1164
|
+
: null;
|
|
991
1165
|
if (incomingMode) {
|
|
992
1166
|
session.mode = incomingMode;
|
|
993
1167
|
}
|
|
@@ -1019,7 +1193,8 @@ export function handleSdkMessage(session, message) {
|
|
|
1019
1193
|
if (Array.isArray(msg.mcp_servers)) {
|
|
1020
1194
|
emitMcpSnapshotFromStatuses(session, msg.mcp_servers, "init");
|
|
1021
1195
|
}
|
|
1022
|
-
if (session.lastAvailableAgentsSignature === undefined &&
|
|
1196
|
+
if (session.lastAvailableAgentsSignature === undefined &&
|
|
1197
|
+
Array.isArray(msg.agents)) {
|
|
1023
1198
|
emitAvailableAgentsIfChanged(session, mapAvailableAgentsFromNames(msg.agents));
|
|
1024
1199
|
}
|
|
1025
1200
|
void session.query
|
|
@@ -1041,17 +1216,28 @@ export function handleSdkMessage(session, message) {
|
|
|
1041
1216
|
return;
|
|
1042
1217
|
}
|
|
1043
1218
|
if (subtype === "status") {
|
|
1044
|
-
const mode = typeof msg.permissionMode === "string"
|
|
1219
|
+
const mode = typeof msg.permissionMode === "string"
|
|
1220
|
+
? toPermissionMode(msg.permissionMode)
|
|
1221
|
+
: null;
|
|
1045
1222
|
if (mode) {
|
|
1046
1223
|
session.mode = mode;
|
|
1047
1224
|
refreshSupportedModesForSession(session);
|
|
1048
|
-
emitSessionUpdate(session.sessionId, {
|
|
1225
|
+
emitSessionUpdate(session.sessionId, {
|
|
1226
|
+
type: "current_mode_update",
|
|
1227
|
+
current_mode_id: mode,
|
|
1228
|
+
});
|
|
1049
1229
|
}
|
|
1050
1230
|
if (msg.status === "compacting") {
|
|
1051
|
-
emitSessionUpdate(session.sessionId, {
|
|
1231
|
+
emitSessionUpdate(session.sessionId, {
|
|
1232
|
+
type: "compaction_update",
|
|
1233
|
+
phase: "started",
|
|
1234
|
+
});
|
|
1052
1235
|
}
|
|
1053
1236
|
else if (msg.status === "requesting") {
|
|
1054
|
-
emitSessionUpdate(session.sessionId, {
|
|
1237
|
+
emitSessionUpdate(session.sessionId, {
|
|
1238
|
+
type: "session_status_update",
|
|
1239
|
+
status: "requesting",
|
|
1240
|
+
});
|
|
1055
1241
|
}
|
|
1056
1242
|
else if (msg.status === null) {
|
|
1057
1243
|
if (msg.compact_result === "success") {
|
|
@@ -1062,7 +1248,8 @@ export function handleSdkMessage(session, message) {
|
|
|
1062
1248
|
});
|
|
1063
1249
|
}
|
|
1064
1250
|
else if (msg.compact_result === "failed") {
|
|
1065
|
-
const compactError = typeof msg.compact_error === "string" &&
|
|
1251
|
+
const compactError = typeof msg.compact_error === "string" &&
|
|
1252
|
+
msg.compact_error.trim().length > 0
|
|
1066
1253
|
? msg.compact_error.trim()
|
|
1067
1254
|
: undefined;
|
|
1068
1255
|
emitSessionUpdate(session.sessionId, {
|
|
@@ -1073,7 +1260,10 @@ export function handleSdkMessage(session, message) {
|
|
|
1073
1260
|
...(compactError ? { error: compactError } : {}),
|
|
1074
1261
|
});
|
|
1075
1262
|
}
|
|
1076
|
-
emitSessionUpdate(session.sessionId, {
|
|
1263
|
+
emitSessionUpdate(session.sessionId, {
|
|
1264
|
+
type: "session_status_update",
|
|
1265
|
+
status: "idle",
|
|
1266
|
+
});
|
|
1077
1267
|
}
|
|
1078
1268
|
emitFastModeUpdateIfChanged(session, msg.fast_mode_state, msg.fast_mode_disabled_reason);
|
|
1079
1269
|
return;
|
|
@@ -1087,7 +1277,8 @@ export function handleSdkMessage(session, message) {
|
|
|
1087
1277
|
const preTokens = nonNegativeIntegerField(compactMetadata, "pre_tokens", "preTokens");
|
|
1088
1278
|
const postTokens = nonNegativeIntegerField(compactMetadata, "post_tokens", "postTokens");
|
|
1089
1279
|
const durationMs = nonNegativeIntegerField(compactMetadata, "duration_ms", "durationMs");
|
|
1090
|
-
if ((trigger === "manual" || trigger === "auto") &&
|
|
1280
|
+
if ((trigger === "manual" || trigger === "auto") &&
|
|
1281
|
+
preTokens !== undefined) {
|
|
1091
1282
|
emitSessionUpdate(session.sessionId, {
|
|
1092
1283
|
type: "compaction_update",
|
|
1093
1284
|
phase: "boundary",
|
|
@@ -1105,7 +1296,9 @@ export function handleSdkMessage(session, message) {
|
|
|
1105
1296
|
emitSessionUpdate(session.sessionId, {
|
|
1106
1297
|
type: "agent_message_chunk",
|
|
1107
1298
|
content: { type: "text", text: content },
|
|
1108
|
-
...(sourceMessageUuid(msg)
|
|
1299
|
+
...(sourceMessageUuid(msg)
|
|
1300
|
+
? { source_message_uuid: sourceMessageUuid(msg) }
|
|
1301
|
+
: {}),
|
|
1109
1302
|
});
|
|
1110
1303
|
}
|
|
1111
1304
|
return;
|
|
@@ -1120,7 +1313,9 @@ export function handleSdkMessage(session, message) {
|
|
|
1120
1313
|
session_id: session.sessionId,
|
|
1121
1314
|
completion: {
|
|
1122
1315
|
elicitation_id: elicitationId,
|
|
1123
|
-
...(typeof msg.mcp_server_name === "string"
|
|
1316
|
+
...(typeof msg.mcp_server_name === "string"
|
|
1317
|
+
? { server_name: msg.mcp_server_name }
|
|
1318
|
+
: {}),
|
|
1124
1319
|
},
|
|
1125
1320
|
});
|
|
1126
1321
|
return;
|
|
@@ -1143,7 +1338,10 @@ export function handleSdkMessage(session, message) {
|
|
|
1143
1338
|
if (type === "prompt_suggestion") {
|
|
1144
1339
|
const suggestion = typeof msg.suggestion === "string" ? msg.suggestion.trim() : "";
|
|
1145
1340
|
if (suggestion) {
|
|
1146
|
-
emitSessionUpdate(session.sessionId, {
|
|
1341
|
+
emitSessionUpdate(session.sessionId, {
|
|
1342
|
+
type: "prompt_suggestion_update",
|
|
1343
|
+
suggestion,
|
|
1344
|
+
});
|
|
1147
1345
|
}
|
|
1148
1346
|
return;
|
|
1149
1347
|
}
|
|
@@ -1158,10 +1356,14 @@ export function handleSdkMessage(session, message) {
|
|
|
1158
1356
|
}
|
|
1159
1357
|
if (type === "auth_status") {
|
|
1160
1358
|
const output = Array.isArray(msg.output)
|
|
1161
|
-
? msg.output
|
|
1359
|
+
? msg.output
|
|
1360
|
+
.filter((entry) => typeof entry === "string")
|
|
1361
|
+
.join("\n")
|
|
1162
1362
|
: "";
|
|
1163
1363
|
const errorText = typeof msg.error === "string" ? msg.error : "";
|
|
1164
|
-
const combined = [errorText, output]
|
|
1364
|
+
const combined = [errorText, output]
|
|
1365
|
+
.filter((entry) => entry.length > 0)
|
|
1366
|
+
.join("\n");
|
|
1165
1367
|
if (combined && looksLikeAuthRequired(combined)) {
|
|
1166
1368
|
emitAuthRequired(session, combined);
|
|
1167
1369
|
}
|
|
@@ -1169,7 +1371,9 @@ export function handleSdkMessage(session, message) {
|
|
|
1169
1371
|
}
|
|
1170
1372
|
if (type === "stream_event") {
|
|
1171
1373
|
if (msg.event && typeof msg.event === "object") {
|
|
1172
|
-
const parentToolUseId = typeof msg.parent_tool_use_id === "string"
|
|
1374
|
+
const parentToolUseId = typeof msg.parent_tool_use_id === "string"
|
|
1375
|
+
? msg.parent_tool_use_id
|
|
1376
|
+
: undefined;
|
|
1173
1377
|
handleStreamEvent(session, msg.event, parentToolUseId, sourceMessageUuid(msg));
|
|
1174
1378
|
}
|
|
1175
1379
|
return;
|
|
@@ -1179,7 +1383,9 @@ export function handleSdkMessage(session, message) {
|
|
|
1179
1383
|
const toolName = typeof msg.tool_name === "string" ? msg.tool_name : "Tool";
|
|
1180
1384
|
const parentToolUseId = typeof msg.parent_tool_use_id === "string" ? msg.parent_tool_use_id : "";
|
|
1181
1385
|
const taskId = typeof msg.task_id === "string" ? msg.task_id : "";
|
|
1182
|
-
const taskToolUseId = taskId
|
|
1386
|
+
const taskToolUseId = taskId
|
|
1387
|
+
? (session.taskToolUseIds.get(taskId) ?? "")
|
|
1388
|
+
: "";
|
|
1183
1389
|
if (isHiddenToolUse(session, toolUseId, toolName)) {
|
|
1184
1390
|
return;
|
|
1185
1391
|
}
|
|
@@ -1204,7 +1410,9 @@ export function handleSdkMessage(session, message) {
|
|
|
1204
1410
|
});
|
|
1205
1411
|
if (resolvedToolUseId) {
|
|
1206
1412
|
const hasSubagentRetry = Object.hasOwn(msg, "subagent_retry");
|
|
1207
|
-
const subagentRetry = hasSubagentRetry
|
|
1413
|
+
const subagentRetry = hasSubagentRetry
|
|
1414
|
+
? buildSubagentRetryUpdate(msg)
|
|
1415
|
+
: null;
|
|
1208
1416
|
if (hasSubagentRetry && !subagentRetry) {
|
|
1209
1417
|
bridgeLogger.warn({
|
|
1210
1418
|
target: LOG_TARGETS.APP_TOOL,
|
|
@@ -1247,8 +1455,12 @@ export function handleSdkMessage(session, message) {
|
|
|
1247
1455
|
if (type === "rate_limit_event") {
|
|
1248
1456
|
const rateLimitInfo = asRecordOrNull(msg.rate_limit_info);
|
|
1249
1457
|
const update = buildRateLimitUpdate(msg.rate_limit_info);
|
|
1250
|
-
const rawIsUsingOverage = typeof rateLimitInfo?.isUsingOverage === "boolean"
|
|
1251
|
-
|
|
1458
|
+
const rawIsUsingOverage = typeof rateLimitInfo?.isUsingOverage === "boolean"
|
|
1459
|
+
? rateLimitInfo.isUsingOverage
|
|
1460
|
+
: undefined;
|
|
1461
|
+
const rawOverageInUse = typeof rateLimitInfo?.overageInUse === "boolean"
|
|
1462
|
+
? rateLimitInfo.overageInUse
|
|
1463
|
+
: undefined;
|
|
1252
1464
|
if (rawIsUsingOverage !== undefined &&
|
|
1253
1465
|
rawOverageInUse !== undefined &&
|
|
1254
1466
|
rawIsUsingOverage !== rawOverageInUse) {
|
|
@@ -1271,11 +1483,17 @@ export function handleSdkMessage(session, message) {
|
|
|
1271
1483
|
outcome: update ? "success" : "dropped",
|
|
1272
1484
|
sessionId: session.sessionId,
|
|
1273
1485
|
fields: {
|
|
1274
|
-
raw_status: typeof rateLimitInfo?.status === "string"
|
|
1275
|
-
|
|
1486
|
+
raw_status: typeof rateLimitInfo?.status === "string"
|
|
1487
|
+
? rateLimitInfo.status
|
|
1488
|
+
: undefined,
|
|
1489
|
+
raw_rate_limit_type: typeof rateLimitInfo?.rateLimitType === "string"
|
|
1490
|
+
? rateLimitInfo.rateLimitType
|
|
1491
|
+
: undefined,
|
|
1276
1492
|
raw_utilization: numberField(rateLimitInfo ?? {}, "utilization"),
|
|
1277
1493
|
raw_resets_at: numberField(rateLimitInfo ?? {}, "resetsAt"),
|
|
1278
|
-
raw_overage_status: typeof rateLimitInfo?.overageStatus === "string"
|
|
1494
|
+
raw_overage_status: typeof rateLimitInfo?.overageStatus === "string"
|
|
1495
|
+
? rateLimitInfo.overageStatus
|
|
1496
|
+
: undefined,
|
|
1279
1497
|
raw_overage_resets_at: numberField(rateLimitInfo ?? {}, "overageResetsAt"),
|
|
1280
1498
|
raw_is_using_overage: rawIsUsingOverage,
|
|
1281
1499
|
raw_overage_in_use: rawOverageInUse,
|
|
@@ -1306,6 +1524,10 @@ export function handleSdkMessage(session, message) {
|
|
|
1306
1524
|
return;
|
|
1307
1525
|
}
|
|
1308
1526
|
if (type === "user") {
|
|
1527
|
+
const externalMessageUpdate = externalMessageUpdateFromSdkUser(msg);
|
|
1528
|
+
if (externalMessageUpdate) {
|
|
1529
|
+
emitSessionUpdate(session.sessionId, externalMessageUpdate);
|
|
1530
|
+
}
|
|
1309
1531
|
const handledBlocks = handleUserToolResultBlocks(session, msg);
|
|
1310
1532
|
const toolUseId = typeof msg.parent_tool_use_id === "string" ? msg.parent_tool_use_id : "";
|
|
1311
1533
|
const rawToolUseResult = messageToolUseResult(msg);
|