claude-code-rust 0.10.0 → 0.11.1
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 +7 -6
- package/agent-sdk/README.md +1 -1
- package/agent-sdk/dist/bridge/commands.js +71 -2
- package/agent-sdk/dist/bridge/events.js +11 -4
- package/agent-sdk/dist/bridge/history.js +9 -4
- package/agent-sdk/dist/bridge/logger.js +8 -0
- package/agent-sdk/dist/bridge/message_handlers.js +235 -23
- package/agent-sdk/dist/bridge/session_lifecycle.js +389 -7
- package/agent-sdk/dist/bridge/state_parsing.js +61 -0
- package/agent-sdk/dist/bridge/tool_calls.js +96 -8
- package/agent-sdk/dist/bridge/tooling.js +60 -27
- package/agent-sdk/dist/bridge.js +203 -21
- package/agent-sdk/dist/bridge.test.js +765 -23
- package/package.json +2 -2
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { asRecordOrNull } from "./shared.js";
|
|
2
|
-
import { toPermissionMode, buildModeState } 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, unwrapToolUseResult } from "./tooling.js";
|
|
5
|
-
import { emitToolCall, emitToolCallUpdate, emitPlanIfTodoWrite, emitToolResultUpdate, finalizeOpenToolCalls, emitToolProgressUpdate, emitToolSummaryUpdate, ensureToolCallVisible, resolveTaskToolUseId, taskProgressText, } from "./tool_calls.js";
|
|
5
|
+
import { emitToolCall, emitToolCallUpdate, emitPlanIfTodoWrite, emitToolResultUpdate, finalizeOpenToolCalls, emitToolProgressUpdate, emitToolSummaryUpdate, ensureToolCallVisible, resolveTaskToolUseId, taskProgressText, taskUpdatedFields, } from "./tool_calls.js";
|
|
6
6
|
import { emitAuthRequired, classifyTurnErrorKind, emitFastModeUpdateIfChanged } from "./error_classification.js";
|
|
7
7
|
import { mapAvailableAgentsFromNames, emitAvailableAgentsIfChanged, refreshAvailableAgents } from "./agents.js";
|
|
8
|
-
import { buildRateLimitUpdate, numberField } from "./state_parsing.js";
|
|
8
|
+
import { buildApiRetryUpdate, buildRateLimitUpdate, normalizeSettingsParseErrors, numberField, parseRuntimeSessionState, } from "./state_parsing.js";
|
|
9
9
|
import { looksLikeAuthRequired } from "./auth.js";
|
|
10
|
-
import { updateSessionId } from "./session_lifecycle.js";
|
|
10
|
+
import { emitCurrentModelUpdate, refreshCurrentModel, updateSessionId } from "./session_lifecycle.js";
|
|
11
11
|
import { bridgeLogger, LOG_TARGETS } from "./logger.js";
|
|
12
12
|
export function textFromPrompt(command) {
|
|
13
13
|
const chunks = command.chunks ?? [];
|
|
@@ -80,11 +80,12 @@ export function contentFromPrompt(command) {
|
|
|
80
80
|
});
|
|
81
81
|
continue;
|
|
82
82
|
}
|
|
83
|
+
const supportedMimeType = mimeType;
|
|
83
84
|
content.push({
|
|
84
85
|
type: "image",
|
|
85
86
|
source: {
|
|
86
87
|
type: "base64",
|
|
87
|
-
media_type:
|
|
88
|
+
media_type: supportedMimeType,
|
|
88
89
|
data,
|
|
89
90
|
},
|
|
90
91
|
});
|
|
@@ -93,7 +94,10 @@ export function contentFromPrompt(command) {
|
|
|
93
94
|
return content;
|
|
94
95
|
}
|
|
95
96
|
export function handleTaskSystemMessage(session, subtype, msg) {
|
|
96
|
-
if (subtype !== "task_started" &&
|
|
97
|
+
if (subtype !== "task_started" &&
|
|
98
|
+
subtype !== "task_progress" &&
|
|
99
|
+
subtype !== "task_updated" &&
|
|
100
|
+
subtype !== "task_notification") {
|
|
97
101
|
return;
|
|
98
102
|
}
|
|
99
103
|
const taskId = typeof msg.task_id === "string" ? msg.task_id : "";
|
|
@@ -102,7 +106,52 @@ export function handleTaskSystemMessage(session, subtype, msg) {
|
|
|
102
106
|
session.taskToolUseIds.set(taskId, explicitToolUseId);
|
|
103
107
|
}
|
|
104
108
|
const toolUseId = resolveTaskToolUseId(session, msg);
|
|
109
|
+
bridgeLogger.debug({
|
|
110
|
+
target: LOG_TARGETS.APP_TOOL,
|
|
111
|
+
eventName: "sdk_task_linkage_observed",
|
|
112
|
+
message: "SDK task lifecycle linkage observed",
|
|
113
|
+
outcome: toolUseId ? "resolved" : "unresolved",
|
|
114
|
+
sessionId: session.sessionId,
|
|
115
|
+
toolCallId: toolUseId || explicitToolUseId || undefined,
|
|
116
|
+
fields: {
|
|
117
|
+
sdk_subtype: subtype,
|
|
118
|
+
task_id: taskId || undefined,
|
|
119
|
+
explicit_tool_use_id: explicitToolUseId || undefined,
|
|
120
|
+
resolved_tool_use_id: toolUseId || undefined,
|
|
121
|
+
task_status: typeof msg.status === "string" ? msg.status : undefined,
|
|
122
|
+
has_description: typeof msg.description === "string" && msg.description.length > 0,
|
|
123
|
+
has_summary: typeof msg.summary === "string" && msg.summary.length > 0,
|
|
124
|
+
last_tool_name: typeof msg.last_tool_name === "string" ? msg.last_tool_name : undefined,
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
if (subtype === "task_updated") {
|
|
128
|
+
bridgeLogger.debug({
|
|
129
|
+
target: LOG_TARGETS.APP_TOOL,
|
|
130
|
+
eventName: "task_updated_received",
|
|
131
|
+
message: "task update received",
|
|
132
|
+
outcome: toolUseId ? "resolved" : "unresolved",
|
|
133
|
+
sessionId: session.sessionId,
|
|
134
|
+
toolCallId: toolUseId || undefined,
|
|
135
|
+
fields: {
|
|
136
|
+
task_id: taskId,
|
|
137
|
+
explicit_tool_use_id: explicitToolUseId || undefined,
|
|
138
|
+
patch_keys: msg.patch && typeof msg.patch === "object"
|
|
139
|
+
? Object.keys(msg.patch).sort()
|
|
140
|
+
: undefined,
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
}
|
|
105
144
|
if (!toolUseId) {
|
|
145
|
+
if (subtype === "task_updated" && taskId) {
|
|
146
|
+
bridgeLogger.debug({
|
|
147
|
+
target: LOG_TARGETS.APP_TOOL,
|
|
148
|
+
eventName: "task_updated_unlinked",
|
|
149
|
+
message: "task update skipped because no visible tool call was linked",
|
|
150
|
+
outcome: "skipped",
|
|
151
|
+
sessionId: session.sessionId,
|
|
152
|
+
fields: { task_id: taskId, subtype },
|
|
153
|
+
});
|
|
154
|
+
}
|
|
106
155
|
return;
|
|
107
156
|
}
|
|
108
157
|
const toolCall = ensureToolCallVisible(session, toolUseId, "Agent", {});
|
|
@@ -133,9 +182,32 @@ export function handleTaskSystemMessage(session, subtype, msg) {
|
|
|
133
182
|
}, "task_progress");
|
|
134
183
|
return;
|
|
135
184
|
}
|
|
185
|
+
if (subtype === "task_updated") {
|
|
186
|
+
const fields = taskUpdatedFields(msg);
|
|
187
|
+
if (Object.keys(fields).length === 0) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
bridgeLogger.debug({
|
|
191
|
+
target: LOG_TARGETS.APP_TOOL,
|
|
192
|
+
eventName: "task_updated_emitted",
|
|
193
|
+
message: "task update mapped to tool call update",
|
|
194
|
+
outcome: "success",
|
|
195
|
+
sessionId: session.sessionId,
|
|
196
|
+
toolCallId: toolUseId,
|
|
197
|
+
fields: {
|
|
198
|
+
task_id: taskId,
|
|
199
|
+
mapped_status: fields.status,
|
|
200
|
+
has_description: fields.content !== undefined,
|
|
201
|
+
has_error: Boolean(fields.task_metadata?.error),
|
|
202
|
+
is_backgrounded: fields.task_metadata?.is_backgrounded,
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
emitToolCallUpdate(session, toolUseId, fields, "task_updated");
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
136
208
|
const status = typeof msg.status === "string" ? msg.status : "";
|
|
137
209
|
const summary = typeof msg.summary === "string" ? msg.summary : "";
|
|
138
|
-
const finalStatus = status === "completed" ? "completed" : "failed";
|
|
210
|
+
const finalStatus = status === "completed" ? "completed" : status === "stopped" ? "killed" : "failed";
|
|
139
211
|
const fields = { status: finalStatus };
|
|
140
212
|
if (summary) {
|
|
141
213
|
fields.raw_output = summary;
|
|
@@ -146,7 +218,27 @@ export function handleTaskSystemMessage(session, subtype, msg) {
|
|
|
146
218
|
session.taskToolUseIds.delete(taskId);
|
|
147
219
|
}
|
|
148
220
|
}
|
|
149
|
-
|
|
221
|
+
function logContentBlockLinkage(session, blockType, toolUseId, toolName, linkage) {
|
|
222
|
+
if (!toolUseId && !linkage?.parentToolUseId) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
bridgeLogger.debug({
|
|
226
|
+
target: LOG_TARGETS.APP_TOOL,
|
|
227
|
+
eventName: "sdk_tool_linkage_observed",
|
|
228
|
+
message: "SDK tool linkage observed",
|
|
229
|
+
outcome: linkage?.parentToolUseId ? "child" : "root_or_unknown",
|
|
230
|
+
sessionId: session.sessionId,
|
|
231
|
+
toolCallId: toolUseId || undefined,
|
|
232
|
+
fields: {
|
|
233
|
+
source: linkage?.source,
|
|
234
|
+
block_type: blockType || undefined,
|
|
235
|
+
tool_name: toolName,
|
|
236
|
+
tool_use_id: toolUseId || undefined,
|
|
237
|
+
parent_tool_use_id: linkage?.parentToolUseId,
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
export function handleContentBlock(session, block, linkage) {
|
|
150
242
|
const blockType = typeof block.type === "string" ? block.type : "";
|
|
151
243
|
if (blockType === "text") {
|
|
152
244
|
const text = typeof block.text === "string" ? block.text : "";
|
|
@@ -169,8 +261,9 @@ export function handleContentBlock(session, block) {
|
|
|
169
261
|
if (!toolUseId) {
|
|
170
262
|
return;
|
|
171
263
|
}
|
|
264
|
+
logContentBlockLinkage(session, blockType, toolUseId, name, linkage);
|
|
172
265
|
emitPlanIfTodoWrite(session, name, input);
|
|
173
|
-
emitToolCall(session, toolUseId, name, input);
|
|
266
|
+
emitToolCall(session, toolUseId, name, input, linkage?.parentToolUseId ?? null);
|
|
174
267
|
return;
|
|
175
268
|
}
|
|
176
269
|
if (TOOL_RESULT_TYPES.has(blockType)) {
|
|
@@ -178,15 +271,19 @@ export function handleContentBlock(session, block) {
|
|
|
178
271
|
if (!toolUseId) {
|
|
179
272
|
return;
|
|
180
273
|
}
|
|
274
|
+
logContentBlockLinkage(session, blockType, toolUseId, undefined, linkage);
|
|
181
275
|
const isError = Boolean(block.is_error);
|
|
182
276
|
emitToolResultUpdate(session, toolUseId, isError, block.content, block);
|
|
183
277
|
}
|
|
184
278
|
}
|
|
185
|
-
export function handleStreamEvent(session, event) {
|
|
279
|
+
export function handleStreamEvent(session, event, parentToolUseId) {
|
|
186
280
|
const eventType = typeof event.type === "string" ? event.type : "";
|
|
187
281
|
if (eventType === "content_block_start") {
|
|
188
282
|
if (event.content_block && typeof event.content_block === "object") {
|
|
189
|
-
handleContentBlock(session, event.content_block
|
|
283
|
+
handleContentBlock(session, event.content_block, {
|
|
284
|
+
source: "stream_event",
|
|
285
|
+
parentToolUseId,
|
|
286
|
+
});
|
|
190
287
|
}
|
|
191
288
|
return;
|
|
192
289
|
}
|
|
@@ -232,7 +329,8 @@ export function handleAssistantMessage(session, message) {
|
|
|
232
329
|
blockType === "server_tool_use" ||
|
|
233
330
|
blockType === "mcp_tool_use" ||
|
|
234
331
|
TOOL_RESULT_TYPES.has(blockType)) {
|
|
235
|
-
|
|
332
|
+
const parentToolUseId = typeof message.parent_tool_use_id === "string" ? message.parent_tool_use_id : undefined;
|
|
333
|
+
handleContentBlock(session, blockRecord, { source: "assistant", parentToolUseId });
|
|
236
334
|
}
|
|
237
335
|
}
|
|
238
336
|
}
|
|
@@ -251,17 +349,23 @@ export function handleUserToolResultBlocks(session, message) {
|
|
|
251
349
|
const blockRecord = block;
|
|
252
350
|
const blockType = typeof blockRecord.type === "string" ? blockRecord.type : "";
|
|
253
351
|
if (TOOL_RESULT_TYPES.has(blockType)) {
|
|
254
|
-
|
|
352
|
+
const parentToolUseId = typeof message.parent_tool_use_id === "string" ? message.parent_tool_use_id : undefined;
|
|
353
|
+
handleContentBlock(session, blockRecord, { source: "user", parentToolUseId });
|
|
255
354
|
}
|
|
256
355
|
}
|
|
257
356
|
}
|
|
258
357
|
export function handleResultMessage(session, message) {
|
|
259
358
|
emitFastModeUpdateIfChanged(session, message.fast_mode_state);
|
|
359
|
+
const terminalReason = terminalReasonFromValue(message.terminal_reason);
|
|
260
360
|
const subtype = typeof message.subtype === "string" ? message.subtype : "";
|
|
261
361
|
if (subtype === "success") {
|
|
262
362
|
session.lastAssistantError = undefined;
|
|
263
363
|
finalizeOpenToolCalls(session, "completed");
|
|
264
|
-
writeEvent({
|
|
364
|
+
writeEvent({
|
|
365
|
+
event: "turn_complete",
|
|
366
|
+
session_id: session.sessionId,
|
|
367
|
+
...(terminalReason ? { terminal_reason: terminalReason } : {}),
|
|
368
|
+
});
|
|
265
369
|
return;
|
|
266
370
|
}
|
|
267
371
|
const errors = Array.isArray(message.errors) && message.errors.every((entry) => typeof entry === "string")
|
|
@@ -285,25 +389,63 @@ export function handleResultMessage(session, message) {
|
|
|
285
389
|
error_kind: errorKind,
|
|
286
390
|
...(subtype ? { sdk_result_subtype: subtype } : {}),
|
|
287
391
|
...(assistantError ? { assistant_error: assistantError } : {}),
|
|
392
|
+
...(terminalReason ? { terminal_reason: terminalReason } : {}),
|
|
288
393
|
});
|
|
289
394
|
session.lastAssistantError = undefined;
|
|
290
395
|
}
|
|
396
|
+
function terminalReasonFromValue(value) {
|
|
397
|
+
switch (value) {
|
|
398
|
+
case "blocking_limit":
|
|
399
|
+
case "rapid_refill_breaker":
|
|
400
|
+
case "prompt_too_long":
|
|
401
|
+
case "image_error":
|
|
402
|
+
case "model_error":
|
|
403
|
+
case "aborted_streaming":
|
|
404
|
+
case "aborted_tools":
|
|
405
|
+
case "stop_hook_prevented":
|
|
406
|
+
case "hook_stopped":
|
|
407
|
+
case "tool_deferred":
|
|
408
|
+
case "max_turns":
|
|
409
|
+
case "completed":
|
|
410
|
+
return value;
|
|
411
|
+
default:
|
|
412
|
+
return undefined;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
291
415
|
export function handleSdkMessage(session, message) {
|
|
292
416
|
const msg = message;
|
|
293
417
|
const type = typeof msg.type === "string" ? msg.type : "";
|
|
294
418
|
if (type === "system") {
|
|
295
419
|
const subtype = typeof msg.subtype === "string" ? msg.subtype : "";
|
|
420
|
+
if (subtype === "api_retry") {
|
|
421
|
+
const update = buildApiRetryUpdate(msg);
|
|
422
|
+
if (update) {
|
|
423
|
+
emitSessionUpdate(session.sessionId, update);
|
|
424
|
+
}
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
if (subtype === "session_state_changed") {
|
|
428
|
+
const state = parseRuntimeSessionState(msg.state);
|
|
429
|
+
if (state) {
|
|
430
|
+
emitSessionUpdate(session.sessionId, {
|
|
431
|
+
type: "runtime_session_state_update",
|
|
432
|
+
state,
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
296
437
|
if (subtype === "init") {
|
|
297
438
|
const previousSessionId = session.sessionId;
|
|
298
439
|
const incomingSessionId = typeof msg.session_id === "string" ? msg.session_id : session.sessionId;
|
|
299
440
|
updateSessionId(session, incomingSessionId);
|
|
300
|
-
const previousModelName = session.model;
|
|
301
441
|
const modelName = typeof msg.model === "string" ? msg.model : session.model;
|
|
302
442
|
session.model = modelName;
|
|
443
|
+
const currentModelChanged = refreshCurrentModel(session, false);
|
|
303
444
|
const incomingMode = typeof msg.permissionMode === "string" ? toPermissionMode(msg.permissionMode) : null;
|
|
304
445
|
if (incomingMode) {
|
|
305
446
|
session.mode = incomingMode;
|
|
306
447
|
}
|
|
448
|
+
refreshSupportedModesForSession(session);
|
|
307
449
|
emitFastModeUpdateIfChanged(session, msg.fast_mode_state);
|
|
308
450
|
if (!session.connected) {
|
|
309
451
|
emitConnectEvent(session);
|
|
@@ -312,17 +454,13 @@ export function handleSdkMessage(session, message) {
|
|
|
312
454
|
emitSessionReplacedEvent(session);
|
|
313
455
|
}
|
|
314
456
|
else {
|
|
315
|
-
if (
|
|
316
|
-
|
|
317
|
-
type: "config_option_update",
|
|
318
|
-
option_id: "model",
|
|
319
|
-
value: session.model,
|
|
320
|
-
});
|
|
457
|
+
if (currentModelChanged) {
|
|
458
|
+
emitCurrentModelUpdate(session);
|
|
321
459
|
}
|
|
322
460
|
if (incomingMode) {
|
|
323
461
|
emitSessionUpdate(session.sessionId, {
|
|
324
462
|
type: "mode_state_update",
|
|
325
|
-
mode: buildModeState(incomingMode),
|
|
463
|
+
mode: buildModeState(session, incomingMode),
|
|
326
464
|
});
|
|
327
465
|
}
|
|
328
466
|
}
|
|
@@ -351,12 +489,19 @@ export function handleSdkMessage(session, message) {
|
|
|
351
489
|
// Best-effort only; slash commands from init were already emitted.
|
|
352
490
|
});
|
|
353
491
|
refreshAvailableAgents(session);
|
|
492
|
+
for (const settingsError of normalizeSettingsParseErrors(msg.settings_errors ?? msg.settingsErrors)) {
|
|
493
|
+
emitSessionUpdate(session.sessionId, {
|
|
494
|
+
type: "settings_parse_error",
|
|
495
|
+
...settingsError,
|
|
496
|
+
});
|
|
497
|
+
}
|
|
354
498
|
return;
|
|
355
499
|
}
|
|
356
500
|
if (subtype === "status") {
|
|
357
501
|
const mode = typeof msg.permissionMode === "string" ? toPermissionMode(msg.permissionMode) : null;
|
|
358
502
|
if (mode) {
|
|
359
503
|
session.mode = mode;
|
|
504
|
+
refreshSupportedModesForSession(session);
|
|
360
505
|
emitSessionUpdate(session.sessionId, { type: "current_mode_update", current_mode_id: mode });
|
|
361
506
|
}
|
|
362
507
|
if (msg.status === "compacting") {
|
|
@@ -412,6 +557,22 @@ export function handleSdkMessage(session, message) {
|
|
|
412
557
|
handleTaskSystemMessage(session, subtype, msg);
|
|
413
558
|
return;
|
|
414
559
|
}
|
|
560
|
+
if (type === "prompt_suggestion") {
|
|
561
|
+
const suggestion = typeof msg.suggestion === "string" ? msg.suggestion.trim() : "";
|
|
562
|
+
if (suggestion) {
|
|
563
|
+
emitSessionUpdate(session.sessionId, { type: "prompt_suggestion_update", suggestion });
|
|
564
|
+
}
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
if (type === "settings_parse_error") {
|
|
568
|
+
for (const settingsError of normalizeSettingsParseErrors(msg)) {
|
|
569
|
+
emitSessionUpdate(session.sessionId, {
|
|
570
|
+
type: "settings_parse_error",
|
|
571
|
+
...settingsError,
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
415
576
|
if (type === "auth_status") {
|
|
416
577
|
const output = Array.isArray(msg.output)
|
|
417
578
|
? msg.output.filter((entry) => typeof entry === "string").join("\n")
|
|
@@ -425,13 +586,28 @@ export function handleSdkMessage(session, message) {
|
|
|
425
586
|
}
|
|
426
587
|
if (type === "stream_event") {
|
|
427
588
|
if (msg.event && typeof msg.event === "object") {
|
|
428
|
-
|
|
589
|
+
const parentToolUseId = typeof msg.parent_tool_use_id === "string" ? msg.parent_tool_use_id : undefined;
|
|
590
|
+
handleStreamEvent(session, msg.event, parentToolUseId);
|
|
429
591
|
}
|
|
430
592
|
return;
|
|
431
593
|
}
|
|
432
594
|
if (type === "tool_progress") {
|
|
433
595
|
const toolUseId = typeof msg.tool_use_id === "string" ? msg.tool_use_id : "";
|
|
434
596
|
const toolName = typeof msg.tool_name === "string" ? msg.tool_name : "Tool";
|
|
597
|
+
bridgeLogger.debug({
|
|
598
|
+
target: LOG_TARGETS.APP_TOOL,
|
|
599
|
+
eventName: "sdk_tool_progress_linkage_observed",
|
|
600
|
+
message: "SDK tool progress linkage observed",
|
|
601
|
+
outcome: typeof msg.parent_tool_use_id === "string" ? "child" : "root_or_unknown",
|
|
602
|
+
sessionId: session.sessionId,
|
|
603
|
+
toolCallId: toolUseId || undefined,
|
|
604
|
+
fields: {
|
|
605
|
+
tool_name: toolName,
|
|
606
|
+
tool_use_id: toolUseId || undefined,
|
|
607
|
+
parent_tool_use_id: typeof msg.parent_tool_use_id === "string" ? msg.parent_tool_use_id : undefined,
|
|
608
|
+
task_id: typeof msg.task_id === "string" ? msg.task_id : undefined,
|
|
609
|
+
},
|
|
610
|
+
});
|
|
435
611
|
if (toolUseId) {
|
|
436
612
|
emitToolProgressUpdate(session, toolUseId, toolName);
|
|
437
613
|
}
|
|
@@ -450,7 +626,43 @@ export function handleSdkMessage(session, message) {
|
|
|
450
626
|
return;
|
|
451
627
|
}
|
|
452
628
|
if (type === "rate_limit_event") {
|
|
629
|
+
const rateLimitInfo = asRecordOrNull(msg.rate_limit_info);
|
|
453
630
|
const update = buildRateLimitUpdate(msg.rate_limit_info);
|
|
631
|
+
bridgeLogger.debug({
|
|
632
|
+
target: LOG_TARGETS.APP_SESSION,
|
|
633
|
+
eventName: "sdk_rate_limit_event_received",
|
|
634
|
+
message: "SDK rate limit event received",
|
|
635
|
+
outcome: update ? "success" : "dropped",
|
|
636
|
+
sessionId: session.sessionId,
|
|
637
|
+
fields: {
|
|
638
|
+
raw_status: typeof rateLimitInfo?.status === "string" ? rateLimitInfo.status : undefined,
|
|
639
|
+
raw_rate_limit_type: typeof rateLimitInfo?.rateLimitType === "string" ? rateLimitInfo.rateLimitType : undefined,
|
|
640
|
+
raw_utilization: numberField(rateLimitInfo ?? {}, "utilization"),
|
|
641
|
+
raw_resets_at: numberField(rateLimitInfo ?? {}, "resetsAt"),
|
|
642
|
+
raw_overage_status: typeof rateLimitInfo?.overageStatus === "string" ? rateLimitInfo.overageStatus : undefined,
|
|
643
|
+
raw_overage_resets_at: numberField(rateLimitInfo ?? {}, "overageResetsAt"),
|
|
644
|
+
raw_is_using_overage: typeof rateLimitInfo?.isUsingOverage === "boolean" ? rateLimitInfo.isUsingOverage : undefined,
|
|
645
|
+
raw_surpassed_threshold: numberField(rateLimitInfo ?? {}, "surpassedThreshold"),
|
|
646
|
+
parsed_status: update?.status,
|
|
647
|
+
parsed_rate_limit_type: update?.rate_limit_type,
|
|
648
|
+
parsed_utilization: update?.utilization,
|
|
649
|
+
parsed_resets_at: update?.resets_at,
|
|
650
|
+
parsed_overage_status: update?.overage_status,
|
|
651
|
+
parsed_overage_resets_at: update?.overage_resets_at,
|
|
652
|
+
parsed_is_using_overage: update?.is_using_overage,
|
|
653
|
+
parsed_surpassed_threshold: update?.surpassed_threshold,
|
|
654
|
+
},
|
|
655
|
+
});
|
|
656
|
+
bridgeLogger.debug({
|
|
657
|
+
target: LOG_TARGETS.APP_SESSION,
|
|
658
|
+
eventName: "sdk_rate_limit_event_raw",
|
|
659
|
+
message: "SDK rate limit event raw payload",
|
|
660
|
+
outcome: rateLimitInfo ? "success" : "dropped",
|
|
661
|
+
sessionId: session.sessionId,
|
|
662
|
+
fields: {
|
|
663
|
+
raw_rate_limit_info: msg.rate_limit_info,
|
|
664
|
+
},
|
|
665
|
+
});
|
|
454
666
|
if (update) {
|
|
455
667
|
emitSessionUpdate(session.sessionId, update);
|
|
456
668
|
}
|