codex-to-im 1.0.46 → 1.0.47

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.
Files changed (2) hide show
  1. package/dist/daemon.mjs +257 -12
  2. package/package.json +2 -2
package/dist/daemon.mjs CHANGED
@@ -571,7 +571,8 @@ var init_codex_provider = __esm({
571
571
  usage: usage ? {
572
572
  input_tokens: usage.input_tokens ?? 0,
573
573
  output_tokens: usage.output_tokens ?? 0,
574
- cache_read_input_tokens: usage.cached_input_tokens ?? 0
574
+ cache_read_input_tokens: usage.cached_input_tokens ?? 0,
575
+ reasoning_output_tokens: usage.reasoning_output_tokens ?? 0
575
576
  } : void 0,
576
577
  ...threadId ? { session_id: threadId } : {}
577
578
  }));
@@ -10071,6 +10072,13 @@ function parseUpdatePlanTasks(argumentsJson) {
10071
10072
  if (!parsed || typeof parsed !== "object") return [];
10072
10073
  return parseTaskProgressItems(parsed.plan ?? parsed.tasks);
10073
10074
  }
10075
+ function extractReasoningSummary(payload) {
10076
+ for (const value of [payload.summary, payload.content, payload.text, payload.message]) {
10077
+ const text2 = extractNormalizedStructuredText(value);
10078
+ if (text2) return text2;
10079
+ }
10080
+ return "";
10081
+ }
10074
10082
  function extractToolOutputText(value) {
10075
10083
  if (typeof value !== "string") return extractNormalizedFreeText(value);
10076
10084
  const trimmed = value.trim();
@@ -10084,6 +10092,39 @@ function extractToolOutputText(value) {
10084
10092
  }
10085
10093
  return extractNormalizedFreeText(value);
10086
10094
  }
10095
+ function summarizePatchChanges(value) {
10096
+ if (!value || typeof value !== "object") return "";
10097
+ return Object.entries(value).map(([filePath, detail]) => {
10098
+ const kind = detail && typeof detail === "object" ? extractNormalizedFreeText(detail.type ?? detail.kind) : "";
10099
+ return kind ? `${kind}: ${filePath}` : filePath;
10100
+ }).filter(Boolean).join("\n");
10101
+ }
10102
+ function summarizeToolSearchOutput(value) {
10103
+ if (!Array.isArray(value)) return "";
10104
+ let count = 0;
10105
+ const names = [];
10106
+ for (const entry of value) {
10107
+ if (!entry || typeof entry !== "object") continue;
10108
+ const namespaceName = extractNormalizedFreeText(entry.name);
10109
+ if (namespaceName) names.push(namespaceName);
10110
+ const tools = entry.tools;
10111
+ if (Array.isArray(tools)) count += tools.length;
10112
+ }
10113
+ const prefix = count > 0 ? `Found ${count} tools` : "";
10114
+ const suffix = names.length > 0 ? names.slice(0, 5).join(", ") : "";
10115
+ return [prefix, suffix].filter(Boolean).join(": ");
10116
+ }
10117
+ function getDynamicToolCallId(payload) {
10118
+ return extractNormalizedFreeText(payload.call_id ?? payload.callId);
10119
+ }
10120
+ function formatDesktopToolName(namespaceValue, nameValue) {
10121
+ const name = extractNormalizedFreeText(nameValue);
10122
+ if (!name) return "";
10123
+ const namespace = extractNormalizedFreeText(namespaceValue);
10124
+ if (!namespace) return name;
10125
+ if (name.startsWith(namespace)) return name;
10126
+ return namespace.endsWith("__") || namespace.endsWith("/") || namespace.endsWith(".") ? `${namespace}${name}` : `${namespace}__${name}`;
10127
+ }
10087
10128
  function createDesktopEventSignature(rawLine) {
10088
10129
  return crypto4.createHash("sha1").update(rawLine).digest("hex");
10089
10130
  }
@@ -10115,7 +10156,28 @@ function isSessionMessageLine(line) {
10115
10156
  function isTurnContextLine(line) {
10116
10157
  return line.type === "turn_context";
10117
10158
  }
10159
+ var IGNORED_EVENT_MSG_TYPES = /* @__PURE__ */ new Set([
10160
+ "context_compacted",
10161
+ "thread_name_updated",
10162
+ "thread_rolled_back",
10163
+ "token_count"
10164
+ ]);
10165
+ var IGNORED_RESPONSE_ITEM_TYPES = /* @__PURE__ */ new Set([
10166
+ "web_search_call"
10167
+ ]);
10168
+ function isIgnoredMirrorLineKind(line) {
10169
+ if (isSessionEventLine(line)) {
10170
+ const payloadType = typeof line.payload?.type === "string" ? line.payload.type.trim() : "";
10171
+ return IGNORED_EVENT_MSG_TYPES.has(payloadType);
10172
+ }
10173
+ if (isSessionMessageLine(line)) {
10174
+ const payloadType = typeof line.payload?.type === "string" ? line.payload.type.trim() : "";
10175
+ return IGNORED_RESPONSE_ITEM_TYPES.has(payloadType);
10176
+ }
10177
+ return false;
10178
+ }
10118
10179
  function describeUnhandledMirrorLineKind(line) {
10180
+ if (isIgnoredMirrorLineKind(line)) return null;
10119
10181
  if (isSessionEventLine(line)) {
10120
10182
  const payloadType = typeof line.payload?.type === "string" ? line.payload.type.trim() : "";
10121
10183
  return `event_msg:${payloadType || "<unknown>"}`;
@@ -10192,6 +10254,20 @@ function pushDesktopSessionEvent(events, parsed, rawLine) {
10192
10254
  });
10193
10255
  return;
10194
10256
  }
10257
+ if (isSessionEventLine(parsed) && parsed.payload?.type === "agent_message") {
10258
+ const text2 = extractNormalizedStructuredText(parsed.payload.message);
10259
+ if (!text2) return;
10260
+ const role = parsed.payload.phase === "commentary" ? "commentary" : "assistant";
10261
+ const lastEvent = events[events.length - 1];
10262
+ if (lastEvent?.role === role && lastEvent.content === text2) return;
10263
+ events.push({
10264
+ signature: createDesktopEventSignature(rawLine),
10265
+ role,
10266
+ content: text2,
10267
+ timestamp: parsed.timestamp || ""
10268
+ });
10269
+ return;
10270
+ }
10195
10271
  if (isSessionEventLine(parsed) && parsed.payload?.type === "task_complete") {
10196
10272
  const text2 = extractNormalizedStructuredText(parsed.payload.last_agent_message);
10197
10273
  if (!text2) return;
@@ -10210,10 +10286,14 @@ function pushDesktopSessionEvent(events, parsed, rawLine) {
10210
10286
  if (isSessionMessageLine(parsed) && parsed.payload?.type === "message" && parsed.payload.role === "assistant") {
10211
10287
  const text2 = extractDesktopMessageText(parsed);
10212
10288
  if (!text2) return;
10289
+ const role = parsed.payload.phase === "commentary" ? "commentary" : "assistant";
10290
+ const content = parsed.payload.phase === "commentary" ? text2.replace(/^\[commentary\]\n/, "") : text2;
10291
+ const lastEvent = events[events.length - 1];
10292
+ if (lastEvent?.role === role && lastEvent.content === content) return;
10213
10293
  events.push({
10214
10294
  signature: createDesktopEventSignature(rawLine),
10215
- role: parsed.payload.phase === "commentary" ? "commentary" : "assistant",
10216
- content: parsed.payload.phase === "commentary" ? text2.replace(/^\[commentary\]\n/, "") : text2,
10295
+ role,
10296
+ content,
10217
10297
  timestamp: parsed.timestamp || ""
10218
10298
  });
10219
10299
  }
@@ -10250,6 +10330,22 @@ function pushDesktopMirrorEventRecord(records, parsed, rawLine, activeTurnId) {
10250
10330
  });
10251
10331
  return true;
10252
10332
  }
10333
+ if (isIgnoredMirrorLineKind(parsed)) {
10334
+ return true;
10335
+ }
10336
+ if (parsed.payload?.type === "agent_message") {
10337
+ const text2 = extractNormalizedStructuredText(parsed.payload.message);
10338
+ if (!text2) return true;
10339
+ records.push({
10340
+ signature,
10341
+ type: "message",
10342
+ role: parsed.payload.phase === "commentary" ? "commentary" : "assistant",
10343
+ content: text2,
10344
+ timestamp,
10345
+ ...activeTurnId ? { turnId: activeTurnId } : {}
10346
+ });
10347
+ return true;
10348
+ }
10253
10349
  if (parsed.payload?.type === "agent_reasoning") {
10254
10350
  const text2 = extractNormalizedStructuredText(parsed.payload.text);
10255
10351
  if (!text2) return true;
@@ -10292,6 +10388,68 @@ function pushDesktopMirrorEventRecord(records, parsed, rawLine, activeTurnId) {
10292
10388
  });
10293
10389
  return true;
10294
10390
  }
10391
+ if (parsed.payload?.type === "exec_command_end") {
10392
+ const toolId = extractNormalizedFreeText(parsed.payload.call_id) || signature;
10393
+ const exitCode = typeof parsed.payload.exit_code === "number" ? parsed.payload.exit_code : null;
10394
+ const status = extractNormalizedFreeText(parsed.payload.status).toLowerCase();
10395
+ records.push({
10396
+ signature,
10397
+ type: "tool_finished",
10398
+ content: extractToolOutputText(
10399
+ parsed.payload.aggregated_output ?? parsed.payload.formatted_output ?? parsed.payload.stdout ?? parsed.payload.stderr ?? parsed.payload.command
10400
+ ),
10401
+ timestamp,
10402
+ ...parsed.payload.turn_id || activeTurnId ? { turnId: parsed.payload.turn_id || activeTurnId || void 0 } : {},
10403
+ toolId,
10404
+ toolName: "Bash",
10405
+ isError: status === "failed" || exitCode != null && exitCode !== 0
10406
+ });
10407
+ return true;
10408
+ }
10409
+ if (parsed.payload?.type === "patch_apply_end") {
10410
+ const toolId = extractNormalizedFreeText(parsed.payload.call_id) || signature;
10411
+ const status = extractNormalizedFreeText(parsed.payload.status).toLowerCase();
10412
+ records.push({
10413
+ signature,
10414
+ type: "tool_finished",
10415
+ content: summarizePatchChanges(parsed.payload.changes) || extractToolOutputText(parsed.payload.stdout ?? parsed.payload.stderr),
10416
+ timestamp,
10417
+ ...parsed.payload.turn_id || activeTurnId ? { turnId: parsed.payload.turn_id || activeTurnId || void 0 } : {},
10418
+ toolId,
10419
+ toolName: "apply_patch",
10420
+ isError: parsed.payload.success === false || status === "failed"
10421
+ });
10422
+ return true;
10423
+ }
10424
+ if (parsed.payload?.type === "dynamic_tool_call_request") {
10425
+ const toolId = getDynamicToolCallId(parsed.payload) || signature;
10426
+ const toolName = extractNormalizedFreeText(parsed.payload.tool) || "tool";
10427
+ records.push({
10428
+ signature,
10429
+ type: "tool_started",
10430
+ content: "",
10431
+ timestamp,
10432
+ ...parsed.payload.turnId || activeTurnId ? { turnId: parsed.payload.turnId || activeTurnId || void 0 } : {},
10433
+ toolId,
10434
+ toolName
10435
+ });
10436
+ return true;
10437
+ }
10438
+ if (parsed.payload?.type === "dynamic_tool_call_response") {
10439
+ const toolId = getDynamicToolCallId(parsed.payload) || signature;
10440
+ const toolName = extractNormalizedFreeText(parsed.payload.tool) || "tool";
10441
+ records.push({
10442
+ signature,
10443
+ type: "tool_finished",
10444
+ content: extractToolOutputText(parsed.payload.content_items ?? parsed.payload.error),
10445
+ timestamp,
10446
+ ...parsed.payload.turn_id || activeTurnId ? { turnId: parsed.payload.turn_id || activeTurnId || void 0 } : {},
10447
+ toolId,
10448
+ toolName,
10449
+ isError: parsed.payload.success === false
10450
+ });
10451
+ return true;
10452
+ }
10295
10453
  if (parsed.payload?.type === "user_message") {
10296
10454
  const text2 = extractNormalizedStructuredText(parsed.payload.message);
10297
10455
  if (!text2) return true;
@@ -10321,6 +10479,21 @@ function pushDesktopMirrorEventRecord(records, parsed, rawLine, activeTurnId) {
10321
10479
  function pushDesktopMirrorResponseRecord(records, parsed, rawLine, activeTurnId, activeSpecialCallIds) {
10322
10480
  const signature = createDesktopEventSignature(rawLine);
10323
10481
  const timestamp = parsed.timestamp || "";
10482
+ if (isIgnoredMirrorLineKind(parsed)) {
10483
+ return true;
10484
+ }
10485
+ if (parsed.payload?.type === "reasoning") {
10486
+ const text2 = extractReasoningSummary(parsed.payload);
10487
+ if (!text2) return true;
10488
+ records.push({
10489
+ signature,
10490
+ type: "reasoning",
10491
+ content: text2,
10492
+ timestamp,
10493
+ ...activeTurnId ? { turnId: activeTurnId } : {}
10494
+ });
10495
+ return true;
10496
+ }
10324
10497
  if (parsed.payload?.type === "message" && parsed.payload.role === "assistant") {
10325
10498
  const text2 = extractDesktopMessageText(parsed);
10326
10499
  if (!text2) return true;
@@ -10334,8 +10507,36 @@ function pushDesktopMirrorResponseRecord(records, parsed, rawLine, activeTurnId,
10334
10507
  });
10335
10508
  return true;
10336
10509
  }
10510
+ if (parsed.payload?.type === "tool_search_call") {
10511
+ const toolId = extractNormalizedFreeText(parsed.payload.call_id) || signature;
10512
+ records.push({
10513
+ signature,
10514
+ type: "tool_started",
10515
+ content: "",
10516
+ timestamp,
10517
+ ...activeTurnId ? { turnId: activeTurnId } : {},
10518
+ toolId,
10519
+ toolName: "tool_search"
10520
+ });
10521
+ return true;
10522
+ }
10523
+ if (parsed.payload?.type === "tool_search_output") {
10524
+ const toolId = extractNormalizedFreeText(parsed.payload.call_id) || signature;
10525
+ const status = extractNormalizedFreeText(parsed.payload.status).toLowerCase();
10526
+ records.push({
10527
+ signature,
10528
+ type: "tool_finished",
10529
+ content: summarizeToolSearchOutput(parsed.payload.tools),
10530
+ timestamp,
10531
+ ...activeTurnId ? { turnId: activeTurnId } : {},
10532
+ toolId,
10533
+ toolName: "tool_search",
10534
+ isError: status === "failed"
10535
+ });
10536
+ return true;
10537
+ }
10337
10538
  if (parsed.payload?.type === "function_call") {
10338
- const toolName = extractNormalizedFreeText(parsed.payload.name);
10539
+ const toolName = formatDesktopToolName(parsed.payload.namespace, parsed.payload.name);
10339
10540
  const toolId = extractNormalizedFreeText(parsed.payload.call_id) || signature;
10340
10541
  if (!toolName) return true;
10341
10542
  if (toolName === "update_plan") {
@@ -10363,7 +10564,7 @@ function pushDesktopMirrorResponseRecord(records, parsed, rawLine, activeTurnId,
10363
10564
  return true;
10364
10565
  }
10365
10566
  if (parsed.payload?.type === "custom_tool_call") {
10366
- const toolName = extractNormalizedFreeText(parsed.payload.name);
10567
+ const toolName = formatDesktopToolName(parsed.payload.namespace, parsed.payload.name);
10367
10568
  const toolId = extractNormalizedFreeText(parsed.payload.call_id) || signature;
10368
10569
  if (!toolName) return true;
10369
10570
  if (toolName === "update_plan") {
@@ -11801,6 +12002,7 @@ ${notice}` : notice;
11801
12002
  function nowIso2() {
11802
12003
  return (/* @__PURE__ */ new Date()).toISOString();
11803
12004
  }
12005
+ var MIRROR_DUPLICATE_TEXT_WINDOW_MS = 2e3;
11804
12006
  function createMirrorTurnState(sessionId, timestamp, turnId) {
11805
12007
  const safeTimestamp = timestamp || nowIso2();
11806
12008
  return {
@@ -11865,6 +12067,14 @@ function markMirrorContentResponse(turnState, timestamp) {
11865
12067
  turnState.lastContentResponseAt = responseAt;
11866
12068
  turnState.lastResponseAt = responseAt;
11867
12069
  }
12070
+ function isNearDuplicateMirrorText(previousText, nextText, previousTimestamp, nextTimestamp) {
12071
+ if (previousText !== nextText) return false;
12072
+ if (!previousTimestamp || !nextTimestamp) return true;
12073
+ const previousMs = Date.parse(previousTimestamp);
12074
+ const nextMs = Date.parse(nextTimestamp);
12075
+ if (!Number.isFinite(previousMs) || !Number.isFinite(nextMs)) return true;
12076
+ return Math.abs(nextMs - previousMs) <= MIRROR_DUPLICATE_TEXT_WINDOW_MS;
12077
+ }
11868
12078
  function finalizeMirrorTurn(subscription, signature, timestamp, status, preferredText) {
11869
12079
  const pendingTurn = subscription.pendingTurn;
11870
12080
  subscription.pendingTurn = null;
@@ -11934,7 +12144,14 @@ function consumeMirrorRecords(subscription, records, hooks = {}) {
11934
12144
  if (record.role === "assistant") {
11935
12145
  const text2 = record.content.trim();
11936
12146
  if (text2) {
12147
+ if (isNearDuplicateMirrorText(
12148
+ pendingTurn.lastAssistantText,
12149
+ text2,
12150
+ pendingTurn.lastAssistantTextAt ?? null,
12151
+ record.timestamp
12152
+ )) continue;
11937
12153
  pendingTurn.lastAssistantText = text2;
12154
+ pendingTurn.lastAssistantTextAt = record.timestamp || nowIso2();
11938
12155
  appendMirrorStreamText(pendingTurn, text2);
11939
12156
  markMirrorContentResponse(pendingTurn, record.timestamp);
11940
12157
  hooks.onStreamText?.(subscription, pendingTurn);
@@ -11942,7 +12159,14 @@ function consumeMirrorRecords(subscription, records, hooks = {}) {
11942
12159
  } else if (record.role === "commentary") {
11943
12160
  const text2 = record.content.trim();
11944
12161
  if (text2) {
12162
+ if (isNearDuplicateMirrorText(
12163
+ pendingTurn.lastCommentaryText,
12164
+ text2,
12165
+ pendingTurn.lastCommentaryTextAt ?? null,
12166
+ record.timestamp
12167
+ )) continue;
11945
12168
  pendingTurn.lastCommentaryText = text2;
12169
+ pendingTurn.lastCommentaryTextAt = record.timestamp || nowIso2();
11946
12170
  appendMirrorStreamText(pendingTurn, text2);
11947
12171
  markMirrorContentResponse(pendingTurn, record.timestamp);
11948
12172
  hooks.onStreamText?.(subscription, pendingTurn);
@@ -14243,6 +14467,10 @@ function shouldShowStreamLastContentResponseAge(state, nowMs, config2) {
14243
14467
  const ageMs = getStreamLastContentResponseAgeMs(state, nowMs);
14244
14468
  return ageMs != null && ageMs >= Math.max(1e3, config2.heartbeatMs);
14245
14469
  }
14470
+ function getVisibleStreamLastContentResponseAgeMs(state, nowMs, config2) {
14471
+ if (!shouldShowStreamLastContentResponseAge(state, nowMs, config2)) return null;
14472
+ return getStreamLastContentResponseAgeMs(state, nowMs);
14473
+ }
14246
14474
  function buildStreamRuntimeStatus(state, nowMs, options = {}) {
14247
14475
  return formatStreamRuntimeStatus(
14248
14476
  Math.max(0, nowMs - state.startedAtMs),
@@ -14479,11 +14707,20 @@ async function runInteractiveMessage(adapter, msg, text2, attachments, deps) {
14479
14707
  if (!snapshot) return;
14480
14708
  deps.recordInteractiveStreamUiSnapshot?.(binding.codepilotSessionId, snapshot);
14481
14709
  };
14710
+ const getVisibleLastResponseAgeMs = () => getVisibleStreamLastContentResponseAgeMs(
14711
+ streamState,
14712
+ nowMs(),
14713
+ {
14714
+ idleStartMs: streamStatusIdleDetectionStartMs,
14715
+ heartbeatMs: streamStatusHeartbeatMs
14716
+ }
14717
+ );
14482
14718
  const pushRunningStatus = (lastResponseAgeMs) => {
14483
14719
  if (!supportsStructuredStreamUi || streamStatusUpdatesClosed) return;
14720
+ const effectiveLastResponseAgeMs = lastResponseAgeMs === void 0 ? getVisibleLastResponseAgeMs() : lastResponseAgeMs;
14484
14721
  pushStreamFeedbackStatus(
14485
14722
  streamFeedbackTarget,
14486
- lastResponseAgeMs == null ? buildStreamRuntimeStatus(streamState, nowMs()) : formatStreamRuntimeStatus(nowMs() - taskStartedAt, lastResponseAgeMs, streamState.statusNote)
14723
+ effectiveLastResponseAgeMs == null ? buildStreamRuntimeStatus(streamState, nowMs()) : formatStreamRuntimeStatus(nowMs() - taskStartedAt, effectiveLastResponseAgeMs, streamState.statusNote)
14487
14724
  );
14488
14725
  syncStructuredStreamUiSnapshot();
14489
14726
  };
@@ -14570,7 +14807,7 @@ async function runInteractiveMessage(adapter, msg, text2, attachments, deps) {
14570
14807
  if (hasStreamingCards) {
14571
14808
  pushStreamFeedbackTools(streamFeedbackTarget, Array.from(toolCallTracker.values()));
14572
14809
  }
14573
- pushRunningStatus(null);
14810
+ pushRunningStatus();
14574
14811
  syncStructuredStreamUiSnapshot();
14575
14812
  };
14576
14813
  const onTaskEvent = (tasks) => {
@@ -14580,14 +14817,14 @@ async function runInteractiveMessage(adapter, msg, text2, attachments, deps) {
14580
14817
  if (hasStreamingCards) {
14581
14818
  pushStreamFeedbackTasks(streamFeedbackTarget, latestTasks);
14582
14819
  }
14583
- pushRunningStatus(null);
14820
+ pushRunningStatus();
14584
14821
  syncStructuredStreamUiSnapshot();
14585
14822
  };
14586
14823
  const onStatusNote = (note) => {
14587
14824
  if (!deps.isCurrentInteractiveTask(binding.codepilotSessionId, taskId)) return;
14588
14825
  updateStreamStatusNote(streamState, note, nowMs());
14589
14826
  if (streamState.statusNote) markActivity();
14590
- pushRunningStatus(null);
14827
+ pushRunningStatus();
14591
14828
  syncStructuredStreamUiSnapshot();
14592
14829
  };
14593
14830
  const onPartialText = (fullText) => {
@@ -14598,7 +14835,7 @@ async function runInteractiveMessage(adapter, msg, text2, attachments, deps) {
14598
14835
  deps.recordInteractiveHealthProgress(binding.codepilotSessionId, "text");
14599
14836
  previewOnPartialText?.(fullText);
14600
14837
  onStreamCardText?.(fullText);
14601
- pushRunningStatus(null);
14838
+ pushRunningStatus();
14602
14839
  syncStructuredStreamUiSnapshot();
14603
14840
  };
14604
14841
  const waitForDesktopTerminalFinalization = async () => {
@@ -14690,7 +14927,7 @@ async function runInteractiveMessage(adapter, msg, text2, attachments, deps) {
14690
14927
  `\u5F53\u524D\u6B63\u5728\u7B49\u5F85\u5DE5\u5177 ${perm.toolName} \u7684\u6743\u9650\u786E\u8BA4\u3002`
14691
14928
  );
14692
14929
  markActivity();
14693
- pushRunningStatus(null);
14930
+ pushRunningStatus();
14694
14931
  syncStructuredStreamUiSnapshot();
14695
14932
  },
14696
14933
  taskAbort.signal,
@@ -15724,9 +15961,16 @@ function createMirrorFeedbackController(deps) {
15724
15961
  if (minIntervalMs > 0 && turnState.lastStatusAt > 0 && nowMs - turnState.lastStatusAt < minIntervalMs) {
15725
15962
  return;
15726
15963
  }
15964
+ const lastContentResponseAtMs = turnState.lastContentResponseAt ? Date.parse(turnState.lastContentResponseAt) : turnState.lastResponseAt ? Date.parse(turnState.lastResponseAt) : null;
15965
+ const streamState = {
15966
+ startedAtMs,
15967
+ lastContentResponseAtMs: Number.isFinite(lastContentResponseAtMs) ? lastContentResponseAtMs : null
15968
+ };
15969
+ const statusConfig = deps.getStructuredStreamStatusConfig?.();
15970
+ const effectiveLastResponseAgeMs = Object.prototype.hasOwnProperty.call(options, "lastResponseAgeMs") ? options.lastResponseAgeMs : statusConfig ? getVisibleStreamLastContentResponseAgeMs(streamState, nowMs, statusConfig) : null;
15727
15971
  const statusText = formatStreamRuntimeStatus(
15728
15972
  Math.max(0, nowMs - startedAtMs),
15729
- options.lastResponseAgeMs,
15973
+ effectiveLastResponseAgeMs,
15730
15974
  turnState.statusNote
15731
15975
  );
15732
15976
  if (turnState.lastStatusText === statusText) return;
@@ -16889,6 +17133,7 @@ function getMirrorStructuredStreamStatusConfig() {
16889
17133
  var MIRROR_FEEDBACK = createMirrorFeedbackController({
16890
17134
  getAdapter: (channelType) => getState().adapters.get(channelType) || null,
16891
17135
  getThreadTitle: (threadId) => getDesktopThreadTitle(threadId),
17136
+ getStructuredStreamStatusConfig: getMirrorStructuredStreamStatusConfig,
16892
17137
  nowIso: nowIso3,
16893
17138
  eventBatchLimit: MIRROR_EVENT_BATCH_LIMIT,
16894
17139
  deliverResponse
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-to-im",
3
- "version": "1.0.46",
3
+ "version": "1.0.47",
4
4
  "description": "Installable Codex-to-IM bridge with local setup UI and background service",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/zhangle1987/codex-to-im#readme",
@@ -41,7 +41,7 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "@larksuiteoapi/node-sdk": "^1.59.0",
44
- "@openai/codex-sdk": "^0.124.0",
44
+ "@openai/codex-sdk": "^0.130.0",
45
45
  "markdown-it": "^14.1.1",
46
46
  "qrcode": "^1.5.4",
47
47
  "ws": "^8.18.0"