codex-to-im 1.0.46 → 1.0.48

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 +271 -13
  2. package/package.json +2 -2
package/dist/daemon.mjs CHANGED
@@ -359,6 +359,10 @@ function getTerminalDrainTimeoutMs() {
359
359
  function isAbortError(error) {
360
360
  return error instanceof DOMException && error.name === "AbortError" || error instanceof Error && error.name === "AbortError";
361
361
  }
362
+ function isWindowsProcessTerminationParseNoise(message) {
363
+ const normalized = message.replace(/\s+/g, " ").trim().toLowerCase();
364
+ return normalized.startsWith("failed to parse item: success:") && normalized.includes("the process with pid") && normalized.includes("has been terminated");
365
+ }
362
366
  function normalizeTaskText(value) {
363
367
  return typeof value === "string" ? value.trim() : "";
364
368
  }
@@ -505,6 +509,7 @@ var init_codex_provider = __esm({
505
509
  }
506
510
  let sawAnyEvent = false;
507
511
  let sawTerminalEvent = false;
512
+ let sawCompletedAssistantContent = false;
508
513
  const runAbortController = new AbortController();
509
514
  let terminalDrainTimer = null;
510
515
  const clearTerminalDrainTimer = () => {
@@ -555,10 +560,14 @@ var init_codex_provider = __esm({
555
560
  case "item.updated":
556
561
  case "item.completed": {
557
562
  const item = event.item;
563
+ const phase = event.type === "item.started" ? "started" : event.type === "item.updated" ? "updated" : "completed";
564
+ if (phase === "completed" && item.type === "agent_message" && typeof item.text === "string" && item.text.trim()) {
565
+ sawCompletedAssistantContent = true;
566
+ }
558
567
  self.handleItemEvent(
559
568
  controller,
560
569
  item,
561
- event.type === "item.started" ? "started" : event.type === "item.updated" ? "updated" : "completed",
570
+ phase,
562
571
  params.sessionId,
563
572
  emittedToolStarts
564
573
  );
@@ -571,7 +580,8 @@ var init_codex_provider = __esm({
571
580
  usage: usage ? {
572
581
  input_tokens: usage.input_tokens ?? 0,
573
582
  output_tokens: usage.output_tokens ?? 0,
574
- cache_read_input_tokens: usage.cached_input_tokens ?? 0
583
+ cache_read_input_tokens: usage.cached_input_tokens ?? 0,
584
+ reasoning_output_tokens: usage.reasoning_output_tokens ?? 0
575
585
  } : void 0,
576
586
  ...threadId ? { session_id: threadId } : {}
577
587
  }));
@@ -617,6 +627,10 @@ var init_codex_provider = __esm({
617
627
  if (sawTerminalEvent && (runAbortController.signal.aborted || isAbortError(err)) && !userAborted) {
618
628
  break;
619
629
  }
630
+ if ((sawTerminalEvent || sawCompletedAssistantContent) && isWindowsProcessTerminationParseNoise(message)) {
631
+ console.warn("[codex-provider] Suppressed Codex SDK Windows process cleanup parse noise:", message);
632
+ break;
633
+ }
620
634
  if (savedThreadId && !retryFresh && !sawAnyEvent && shouldRetryFreshThread(message)) {
621
635
  console.warn("[codex-provider] Resume failed, retrying with a fresh thread:", message);
622
636
  self.clearCachedThreadId(params.sessionId);
@@ -10071,6 +10085,13 @@ function parseUpdatePlanTasks(argumentsJson) {
10071
10085
  if (!parsed || typeof parsed !== "object") return [];
10072
10086
  return parseTaskProgressItems(parsed.plan ?? parsed.tasks);
10073
10087
  }
10088
+ function extractReasoningSummary(payload) {
10089
+ for (const value of [payload.summary, payload.content, payload.text, payload.message]) {
10090
+ const text2 = extractNormalizedStructuredText(value);
10091
+ if (text2) return text2;
10092
+ }
10093
+ return "";
10094
+ }
10074
10095
  function extractToolOutputText(value) {
10075
10096
  if (typeof value !== "string") return extractNormalizedFreeText(value);
10076
10097
  const trimmed = value.trim();
@@ -10084,6 +10105,39 @@ function extractToolOutputText(value) {
10084
10105
  }
10085
10106
  return extractNormalizedFreeText(value);
10086
10107
  }
10108
+ function summarizePatchChanges(value) {
10109
+ if (!value || typeof value !== "object") return "";
10110
+ return Object.entries(value).map(([filePath, detail]) => {
10111
+ const kind = detail && typeof detail === "object" ? extractNormalizedFreeText(detail.type ?? detail.kind) : "";
10112
+ return kind ? `${kind}: ${filePath}` : filePath;
10113
+ }).filter(Boolean).join("\n");
10114
+ }
10115
+ function summarizeToolSearchOutput(value) {
10116
+ if (!Array.isArray(value)) return "";
10117
+ let count = 0;
10118
+ const names = [];
10119
+ for (const entry of value) {
10120
+ if (!entry || typeof entry !== "object") continue;
10121
+ const namespaceName = extractNormalizedFreeText(entry.name);
10122
+ if (namespaceName) names.push(namespaceName);
10123
+ const tools = entry.tools;
10124
+ if (Array.isArray(tools)) count += tools.length;
10125
+ }
10126
+ const prefix = count > 0 ? `Found ${count} tools` : "";
10127
+ const suffix = names.length > 0 ? names.slice(0, 5).join(", ") : "";
10128
+ return [prefix, suffix].filter(Boolean).join(": ");
10129
+ }
10130
+ function getDynamicToolCallId(payload) {
10131
+ return extractNormalizedFreeText(payload.call_id ?? payload.callId);
10132
+ }
10133
+ function formatDesktopToolName(namespaceValue, nameValue) {
10134
+ const name = extractNormalizedFreeText(nameValue);
10135
+ if (!name) return "";
10136
+ const namespace = extractNormalizedFreeText(namespaceValue);
10137
+ if (!namespace) return name;
10138
+ if (name.startsWith(namespace)) return name;
10139
+ return namespace.endsWith("__") || namespace.endsWith("/") || namespace.endsWith(".") ? `${namespace}${name}` : `${namespace}__${name}`;
10140
+ }
10087
10141
  function createDesktopEventSignature(rawLine) {
10088
10142
  return crypto4.createHash("sha1").update(rawLine).digest("hex");
10089
10143
  }
@@ -10115,7 +10169,28 @@ function isSessionMessageLine(line) {
10115
10169
  function isTurnContextLine(line) {
10116
10170
  return line.type === "turn_context";
10117
10171
  }
10172
+ var IGNORED_EVENT_MSG_TYPES = /* @__PURE__ */ new Set([
10173
+ "context_compacted",
10174
+ "thread_name_updated",
10175
+ "thread_rolled_back",
10176
+ "token_count"
10177
+ ]);
10178
+ var IGNORED_RESPONSE_ITEM_TYPES = /* @__PURE__ */ new Set([
10179
+ "web_search_call"
10180
+ ]);
10181
+ function isIgnoredMirrorLineKind(line) {
10182
+ if (isSessionEventLine(line)) {
10183
+ const payloadType = typeof line.payload?.type === "string" ? line.payload.type.trim() : "";
10184
+ return IGNORED_EVENT_MSG_TYPES.has(payloadType);
10185
+ }
10186
+ if (isSessionMessageLine(line)) {
10187
+ const payloadType = typeof line.payload?.type === "string" ? line.payload.type.trim() : "";
10188
+ return IGNORED_RESPONSE_ITEM_TYPES.has(payloadType);
10189
+ }
10190
+ return false;
10191
+ }
10118
10192
  function describeUnhandledMirrorLineKind(line) {
10193
+ if (isIgnoredMirrorLineKind(line)) return null;
10119
10194
  if (isSessionEventLine(line)) {
10120
10195
  const payloadType = typeof line.payload?.type === "string" ? line.payload.type.trim() : "";
10121
10196
  return `event_msg:${payloadType || "<unknown>"}`;
@@ -10192,6 +10267,20 @@ function pushDesktopSessionEvent(events, parsed, rawLine) {
10192
10267
  });
10193
10268
  return;
10194
10269
  }
10270
+ if (isSessionEventLine(parsed) && parsed.payload?.type === "agent_message") {
10271
+ const text2 = extractNormalizedStructuredText(parsed.payload.message);
10272
+ if (!text2) return;
10273
+ const role = parsed.payload.phase === "commentary" ? "commentary" : "assistant";
10274
+ const lastEvent = events[events.length - 1];
10275
+ if (lastEvent?.role === role && lastEvent.content === text2) return;
10276
+ events.push({
10277
+ signature: createDesktopEventSignature(rawLine),
10278
+ role,
10279
+ content: text2,
10280
+ timestamp: parsed.timestamp || ""
10281
+ });
10282
+ return;
10283
+ }
10195
10284
  if (isSessionEventLine(parsed) && parsed.payload?.type === "task_complete") {
10196
10285
  const text2 = extractNormalizedStructuredText(parsed.payload.last_agent_message);
10197
10286
  if (!text2) return;
@@ -10210,10 +10299,14 @@ function pushDesktopSessionEvent(events, parsed, rawLine) {
10210
10299
  if (isSessionMessageLine(parsed) && parsed.payload?.type === "message" && parsed.payload.role === "assistant") {
10211
10300
  const text2 = extractDesktopMessageText(parsed);
10212
10301
  if (!text2) return;
10302
+ const role = parsed.payload.phase === "commentary" ? "commentary" : "assistant";
10303
+ const content = parsed.payload.phase === "commentary" ? text2.replace(/^\[commentary\]\n/, "") : text2;
10304
+ const lastEvent = events[events.length - 1];
10305
+ if (lastEvent?.role === role && lastEvent.content === content) return;
10213
10306
  events.push({
10214
10307
  signature: createDesktopEventSignature(rawLine),
10215
- role: parsed.payload.phase === "commentary" ? "commentary" : "assistant",
10216
- content: parsed.payload.phase === "commentary" ? text2.replace(/^\[commentary\]\n/, "") : text2,
10308
+ role,
10309
+ content,
10217
10310
  timestamp: parsed.timestamp || ""
10218
10311
  });
10219
10312
  }
@@ -10250,6 +10343,22 @@ function pushDesktopMirrorEventRecord(records, parsed, rawLine, activeTurnId) {
10250
10343
  });
10251
10344
  return true;
10252
10345
  }
10346
+ if (isIgnoredMirrorLineKind(parsed)) {
10347
+ return true;
10348
+ }
10349
+ if (parsed.payload?.type === "agent_message") {
10350
+ const text2 = extractNormalizedStructuredText(parsed.payload.message);
10351
+ if (!text2) return true;
10352
+ records.push({
10353
+ signature,
10354
+ type: "message",
10355
+ role: parsed.payload.phase === "commentary" ? "commentary" : "assistant",
10356
+ content: text2,
10357
+ timestamp,
10358
+ ...activeTurnId ? { turnId: activeTurnId } : {}
10359
+ });
10360
+ return true;
10361
+ }
10253
10362
  if (parsed.payload?.type === "agent_reasoning") {
10254
10363
  const text2 = extractNormalizedStructuredText(parsed.payload.text);
10255
10364
  if (!text2) return true;
@@ -10292,6 +10401,68 @@ function pushDesktopMirrorEventRecord(records, parsed, rawLine, activeTurnId) {
10292
10401
  });
10293
10402
  return true;
10294
10403
  }
10404
+ if (parsed.payload?.type === "exec_command_end") {
10405
+ const toolId = extractNormalizedFreeText(parsed.payload.call_id) || signature;
10406
+ const exitCode = typeof parsed.payload.exit_code === "number" ? parsed.payload.exit_code : null;
10407
+ const status = extractNormalizedFreeText(parsed.payload.status).toLowerCase();
10408
+ records.push({
10409
+ signature,
10410
+ type: "tool_finished",
10411
+ content: extractToolOutputText(
10412
+ parsed.payload.aggregated_output ?? parsed.payload.formatted_output ?? parsed.payload.stdout ?? parsed.payload.stderr ?? parsed.payload.command
10413
+ ),
10414
+ timestamp,
10415
+ ...parsed.payload.turn_id || activeTurnId ? { turnId: parsed.payload.turn_id || activeTurnId || void 0 } : {},
10416
+ toolId,
10417
+ toolName: "Bash",
10418
+ isError: status === "failed" || exitCode != null && exitCode !== 0
10419
+ });
10420
+ return true;
10421
+ }
10422
+ if (parsed.payload?.type === "patch_apply_end") {
10423
+ const toolId = extractNormalizedFreeText(parsed.payload.call_id) || signature;
10424
+ const status = extractNormalizedFreeText(parsed.payload.status).toLowerCase();
10425
+ records.push({
10426
+ signature,
10427
+ type: "tool_finished",
10428
+ content: summarizePatchChanges(parsed.payload.changes) || extractToolOutputText(parsed.payload.stdout ?? parsed.payload.stderr),
10429
+ timestamp,
10430
+ ...parsed.payload.turn_id || activeTurnId ? { turnId: parsed.payload.turn_id || activeTurnId || void 0 } : {},
10431
+ toolId,
10432
+ toolName: "apply_patch",
10433
+ isError: parsed.payload.success === false || status === "failed"
10434
+ });
10435
+ return true;
10436
+ }
10437
+ if (parsed.payload?.type === "dynamic_tool_call_request") {
10438
+ const toolId = getDynamicToolCallId(parsed.payload) || signature;
10439
+ const toolName = extractNormalizedFreeText(parsed.payload.tool) || "tool";
10440
+ records.push({
10441
+ signature,
10442
+ type: "tool_started",
10443
+ content: "",
10444
+ timestamp,
10445
+ ...parsed.payload.turnId || activeTurnId ? { turnId: parsed.payload.turnId || activeTurnId || void 0 } : {},
10446
+ toolId,
10447
+ toolName
10448
+ });
10449
+ return true;
10450
+ }
10451
+ if (parsed.payload?.type === "dynamic_tool_call_response") {
10452
+ const toolId = getDynamicToolCallId(parsed.payload) || signature;
10453
+ const toolName = extractNormalizedFreeText(parsed.payload.tool) || "tool";
10454
+ records.push({
10455
+ signature,
10456
+ type: "tool_finished",
10457
+ content: extractToolOutputText(parsed.payload.content_items ?? parsed.payload.error),
10458
+ timestamp,
10459
+ ...parsed.payload.turn_id || activeTurnId ? { turnId: parsed.payload.turn_id || activeTurnId || void 0 } : {},
10460
+ toolId,
10461
+ toolName,
10462
+ isError: parsed.payload.success === false
10463
+ });
10464
+ return true;
10465
+ }
10295
10466
  if (parsed.payload?.type === "user_message") {
10296
10467
  const text2 = extractNormalizedStructuredText(parsed.payload.message);
10297
10468
  if (!text2) return true;
@@ -10321,6 +10492,21 @@ function pushDesktopMirrorEventRecord(records, parsed, rawLine, activeTurnId) {
10321
10492
  function pushDesktopMirrorResponseRecord(records, parsed, rawLine, activeTurnId, activeSpecialCallIds) {
10322
10493
  const signature = createDesktopEventSignature(rawLine);
10323
10494
  const timestamp = parsed.timestamp || "";
10495
+ if (isIgnoredMirrorLineKind(parsed)) {
10496
+ return true;
10497
+ }
10498
+ if (parsed.payload?.type === "reasoning") {
10499
+ const text2 = extractReasoningSummary(parsed.payload);
10500
+ if (!text2) return true;
10501
+ records.push({
10502
+ signature,
10503
+ type: "reasoning",
10504
+ content: text2,
10505
+ timestamp,
10506
+ ...activeTurnId ? { turnId: activeTurnId } : {}
10507
+ });
10508
+ return true;
10509
+ }
10324
10510
  if (parsed.payload?.type === "message" && parsed.payload.role === "assistant") {
10325
10511
  const text2 = extractDesktopMessageText(parsed);
10326
10512
  if (!text2) return true;
@@ -10334,8 +10520,36 @@ function pushDesktopMirrorResponseRecord(records, parsed, rawLine, activeTurnId,
10334
10520
  });
10335
10521
  return true;
10336
10522
  }
10523
+ if (parsed.payload?.type === "tool_search_call") {
10524
+ const toolId = extractNormalizedFreeText(parsed.payload.call_id) || signature;
10525
+ records.push({
10526
+ signature,
10527
+ type: "tool_started",
10528
+ content: "",
10529
+ timestamp,
10530
+ ...activeTurnId ? { turnId: activeTurnId } : {},
10531
+ toolId,
10532
+ toolName: "tool_search"
10533
+ });
10534
+ return true;
10535
+ }
10536
+ if (parsed.payload?.type === "tool_search_output") {
10537
+ const toolId = extractNormalizedFreeText(parsed.payload.call_id) || signature;
10538
+ const status = extractNormalizedFreeText(parsed.payload.status).toLowerCase();
10539
+ records.push({
10540
+ signature,
10541
+ type: "tool_finished",
10542
+ content: summarizeToolSearchOutput(parsed.payload.tools),
10543
+ timestamp,
10544
+ ...activeTurnId ? { turnId: activeTurnId } : {},
10545
+ toolId,
10546
+ toolName: "tool_search",
10547
+ isError: status === "failed"
10548
+ });
10549
+ return true;
10550
+ }
10337
10551
  if (parsed.payload?.type === "function_call") {
10338
- const toolName = extractNormalizedFreeText(parsed.payload.name);
10552
+ const toolName = formatDesktopToolName(parsed.payload.namespace, parsed.payload.name);
10339
10553
  const toolId = extractNormalizedFreeText(parsed.payload.call_id) || signature;
10340
10554
  if (!toolName) return true;
10341
10555
  if (toolName === "update_plan") {
@@ -10363,7 +10577,7 @@ function pushDesktopMirrorResponseRecord(records, parsed, rawLine, activeTurnId,
10363
10577
  return true;
10364
10578
  }
10365
10579
  if (parsed.payload?.type === "custom_tool_call") {
10366
- const toolName = extractNormalizedFreeText(parsed.payload.name);
10580
+ const toolName = formatDesktopToolName(parsed.payload.namespace, parsed.payload.name);
10367
10581
  const toolId = extractNormalizedFreeText(parsed.payload.call_id) || signature;
10368
10582
  if (!toolName) return true;
10369
10583
  if (toolName === "update_plan") {
@@ -11801,6 +12015,7 @@ ${notice}` : notice;
11801
12015
  function nowIso2() {
11802
12016
  return (/* @__PURE__ */ new Date()).toISOString();
11803
12017
  }
12018
+ var MIRROR_DUPLICATE_TEXT_WINDOW_MS = 2e3;
11804
12019
  function createMirrorTurnState(sessionId, timestamp, turnId) {
11805
12020
  const safeTimestamp = timestamp || nowIso2();
11806
12021
  return {
@@ -11865,6 +12080,14 @@ function markMirrorContentResponse(turnState, timestamp) {
11865
12080
  turnState.lastContentResponseAt = responseAt;
11866
12081
  turnState.lastResponseAt = responseAt;
11867
12082
  }
12083
+ function isNearDuplicateMirrorText(previousText, nextText, previousTimestamp, nextTimestamp) {
12084
+ if (previousText !== nextText) return false;
12085
+ if (!previousTimestamp || !nextTimestamp) return true;
12086
+ const previousMs = Date.parse(previousTimestamp);
12087
+ const nextMs = Date.parse(nextTimestamp);
12088
+ if (!Number.isFinite(previousMs) || !Number.isFinite(nextMs)) return true;
12089
+ return Math.abs(nextMs - previousMs) <= MIRROR_DUPLICATE_TEXT_WINDOW_MS;
12090
+ }
11868
12091
  function finalizeMirrorTurn(subscription, signature, timestamp, status, preferredText) {
11869
12092
  const pendingTurn = subscription.pendingTurn;
11870
12093
  subscription.pendingTurn = null;
@@ -11934,7 +12157,14 @@ function consumeMirrorRecords(subscription, records, hooks = {}) {
11934
12157
  if (record.role === "assistant") {
11935
12158
  const text2 = record.content.trim();
11936
12159
  if (text2) {
12160
+ if (isNearDuplicateMirrorText(
12161
+ pendingTurn.lastAssistantText,
12162
+ text2,
12163
+ pendingTurn.lastAssistantTextAt ?? null,
12164
+ record.timestamp
12165
+ )) continue;
11937
12166
  pendingTurn.lastAssistantText = text2;
12167
+ pendingTurn.lastAssistantTextAt = record.timestamp || nowIso2();
11938
12168
  appendMirrorStreamText(pendingTurn, text2);
11939
12169
  markMirrorContentResponse(pendingTurn, record.timestamp);
11940
12170
  hooks.onStreamText?.(subscription, pendingTurn);
@@ -11942,7 +12172,14 @@ function consumeMirrorRecords(subscription, records, hooks = {}) {
11942
12172
  } else if (record.role === "commentary") {
11943
12173
  const text2 = record.content.trim();
11944
12174
  if (text2) {
12175
+ if (isNearDuplicateMirrorText(
12176
+ pendingTurn.lastCommentaryText,
12177
+ text2,
12178
+ pendingTurn.lastCommentaryTextAt ?? null,
12179
+ record.timestamp
12180
+ )) continue;
11945
12181
  pendingTurn.lastCommentaryText = text2;
12182
+ pendingTurn.lastCommentaryTextAt = record.timestamp || nowIso2();
11946
12183
  appendMirrorStreamText(pendingTurn, text2);
11947
12184
  markMirrorContentResponse(pendingTurn, record.timestamp);
11948
12185
  hooks.onStreamText?.(subscription, pendingTurn);
@@ -14243,6 +14480,10 @@ function shouldShowStreamLastContentResponseAge(state, nowMs, config2) {
14243
14480
  const ageMs = getStreamLastContentResponseAgeMs(state, nowMs);
14244
14481
  return ageMs != null && ageMs >= Math.max(1e3, config2.heartbeatMs);
14245
14482
  }
14483
+ function getVisibleStreamLastContentResponseAgeMs(state, nowMs, config2) {
14484
+ if (!shouldShowStreamLastContentResponseAge(state, nowMs, config2)) return null;
14485
+ return getStreamLastContentResponseAgeMs(state, nowMs);
14486
+ }
14246
14487
  function buildStreamRuntimeStatus(state, nowMs, options = {}) {
14247
14488
  return formatStreamRuntimeStatus(
14248
14489
  Math.max(0, nowMs - state.startedAtMs),
@@ -14479,11 +14720,20 @@ async function runInteractiveMessage(adapter, msg, text2, attachments, deps) {
14479
14720
  if (!snapshot) return;
14480
14721
  deps.recordInteractiveStreamUiSnapshot?.(binding.codepilotSessionId, snapshot);
14481
14722
  };
14723
+ const getVisibleLastResponseAgeMs = () => getVisibleStreamLastContentResponseAgeMs(
14724
+ streamState,
14725
+ nowMs(),
14726
+ {
14727
+ idleStartMs: streamStatusIdleDetectionStartMs,
14728
+ heartbeatMs: streamStatusHeartbeatMs
14729
+ }
14730
+ );
14482
14731
  const pushRunningStatus = (lastResponseAgeMs) => {
14483
14732
  if (!supportsStructuredStreamUi || streamStatusUpdatesClosed) return;
14733
+ const effectiveLastResponseAgeMs = lastResponseAgeMs === void 0 ? getVisibleLastResponseAgeMs() : lastResponseAgeMs;
14484
14734
  pushStreamFeedbackStatus(
14485
14735
  streamFeedbackTarget,
14486
- lastResponseAgeMs == null ? buildStreamRuntimeStatus(streamState, nowMs()) : formatStreamRuntimeStatus(nowMs() - taskStartedAt, lastResponseAgeMs, streamState.statusNote)
14736
+ effectiveLastResponseAgeMs == null ? buildStreamRuntimeStatus(streamState, nowMs()) : formatStreamRuntimeStatus(nowMs() - taskStartedAt, effectiveLastResponseAgeMs, streamState.statusNote)
14487
14737
  );
14488
14738
  syncStructuredStreamUiSnapshot();
14489
14739
  };
@@ -14570,7 +14820,7 @@ async function runInteractiveMessage(adapter, msg, text2, attachments, deps) {
14570
14820
  if (hasStreamingCards) {
14571
14821
  pushStreamFeedbackTools(streamFeedbackTarget, Array.from(toolCallTracker.values()));
14572
14822
  }
14573
- pushRunningStatus(null);
14823
+ pushRunningStatus();
14574
14824
  syncStructuredStreamUiSnapshot();
14575
14825
  };
14576
14826
  const onTaskEvent = (tasks) => {
@@ -14580,14 +14830,14 @@ async function runInteractiveMessage(adapter, msg, text2, attachments, deps) {
14580
14830
  if (hasStreamingCards) {
14581
14831
  pushStreamFeedbackTasks(streamFeedbackTarget, latestTasks);
14582
14832
  }
14583
- pushRunningStatus(null);
14833
+ pushRunningStatus();
14584
14834
  syncStructuredStreamUiSnapshot();
14585
14835
  };
14586
14836
  const onStatusNote = (note) => {
14587
14837
  if (!deps.isCurrentInteractiveTask(binding.codepilotSessionId, taskId)) return;
14588
14838
  updateStreamStatusNote(streamState, note, nowMs());
14589
14839
  if (streamState.statusNote) markActivity();
14590
- pushRunningStatus(null);
14840
+ pushRunningStatus();
14591
14841
  syncStructuredStreamUiSnapshot();
14592
14842
  };
14593
14843
  const onPartialText = (fullText) => {
@@ -14598,7 +14848,7 @@ async function runInteractiveMessage(adapter, msg, text2, attachments, deps) {
14598
14848
  deps.recordInteractiveHealthProgress(binding.codepilotSessionId, "text");
14599
14849
  previewOnPartialText?.(fullText);
14600
14850
  onStreamCardText?.(fullText);
14601
- pushRunningStatus(null);
14851
+ pushRunningStatus();
14602
14852
  syncStructuredStreamUiSnapshot();
14603
14853
  };
14604
14854
  const waitForDesktopTerminalFinalization = async () => {
@@ -14690,7 +14940,7 @@ async function runInteractiveMessage(adapter, msg, text2, attachments, deps) {
14690
14940
  `\u5F53\u524D\u6B63\u5728\u7B49\u5F85\u5DE5\u5177 ${perm.toolName} \u7684\u6743\u9650\u786E\u8BA4\u3002`
14691
14941
  );
14692
14942
  markActivity();
14693
- pushRunningStatus(null);
14943
+ pushRunningStatus();
14694
14944
  syncStructuredStreamUiSnapshot();
14695
14945
  },
14696
14946
  taskAbort.signal,
@@ -15724,9 +15974,16 @@ function createMirrorFeedbackController(deps) {
15724
15974
  if (minIntervalMs > 0 && turnState.lastStatusAt > 0 && nowMs - turnState.lastStatusAt < minIntervalMs) {
15725
15975
  return;
15726
15976
  }
15977
+ const lastContentResponseAtMs = turnState.lastContentResponseAt ? Date.parse(turnState.lastContentResponseAt) : turnState.lastResponseAt ? Date.parse(turnState.lastResponseAt) : null;
15978
+ const streamState = {
15979
+ startedAtMs,
15980
+ lastContentResponseAtMs: Number.isFinite(lastContentResponseAtMs) ? lastContentResponseAtMs : null
15981
+ };
15982
+ const statusConfig = deps.getStructuredStreamStatusConfig?.();
15983
+ const effectiveLastResponseAgeMs = Object.prototype.hasOwnProperty.call(options, "lastResponseAgeMs") ? options.lastResponseAgeMs : statusConfig ? getVisibleStreamLastContentResponseAgeMs(streamState, nowMs, statusConfig) : null;
15727
15984
  const statusText = formatStreamRuntimeStatus(
15728
15985
  Math.max(0, nowMs - startedAtMs),
15729
- options.lastResponseAgeMs,
15986
+ effectiveLastResponseAgeMs,
15730
15987
  turnState.statusNote
15731
15988
  );
15732
15989
  if (turnState.lastStatusText === statusText) return;
@@ -16889,6 +17146,7 @@ function getMirrorStructuredStreamStatusConfig() {
16889
17146
  var MIRROR_FEEDBACK = createMirrorFeedbackController({
16890
17147
  getAdapter: (channelType) => getState().adapters.get(channelType) || null,
16891
17148
  getThreadTitle: (threadId) => getDesktopThreadTitle(threadId),
17149
+ getStructuredStreamStatusConfig: getMirrorStructuredStreamStatusConfig,
16892
17150
  nowIso: nowIso3,
16893
17151
  eventBatchLimit: MIRROR_EVENT_BATCH_LIMIT,
16894
17152
  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.48",
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"