codex-to-im 1.0.19 → 1.0.20
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/dist/daemon.mjs +116 -30
- package/package.json +1 -1
package/dist/daemon.mjs
CHANGED
|
@@ -5649,7 +5649,16 @@ var FeishuAdapter = class extends BaseChannelAdapter {
|
|
|
5649
5649
|
status: statusLabels[status] || status,
|
|
5650
5650
|
elapsed: formatElapsed(elapsedMs)
|
|
5651
5651
|
};
|
|
5652
|
-
const
|
|
5652
|
+
const existingText = state.pendingText || "";
|
|
5653
|
+
const trimmedExisting = existingText.trim();
|
|
5654
|
+
const trimmedResponse = responseText.trim();
|
|
5655
|
+
let finalText = trimmedResponse || trimmedExisting;
|
|
5656
|
+
if (status === "interrupted" && trimmedExisting && trimmedResponse && trimmedResponse !== trimmedExisting && !trimmedExisting.includes(trimmedResponse)) {
|
|
5657
|
+
finalText = `${trimmedExisting}
|
|
5658
|
+
|
|
5659
|
+
${trimmedResponse}`;
|
|
5660
|
+
}
|
|
5661
|
+
const finalCardJson = buildFinalCardJson(finalText, state.toolCalls, footer);
|
|
5653
5662
|
state.sequence++;
|
|
5654
5663
|
await cardkit.card.update({
|
|
5655
5664
|
path: { card_id: state.cardId },
|
|
@@ -16798,7 +16807,8 @@ var MIRROR_WATCH_DEBOUNCE_MS = 350;
|
|
|
16798
16807
|
var MIRROR_EVENT_BATCH_LIMIT = 8;
|
|
16799
16808
|
var MIRROR_SUPPRESSION_WINDOW_MS = 4e3;
|
|
16800
16809
|
var MIRROR_PROMPT_MATCH_GRACE_MS = 12e4;
|
|
16801
|
-
var
|
|
16810
|
+
var INTERACTIVE_IDLE_REMINDER_MS = 6e5;
|
|
16811
|
+
var MIRROR_IDLE_TIMEOUT_MS = 6e5;
|
|
16802
16812
|
var AVAILABLE_CODEX_MODELS = listSelectableCodexModels();
|
|
16803
16813
|
var AVAILABLE_CODEX_MODEL_MAP = new Map(AVAILABLE_CODEX_MODELS.map((model) => [model.slug, model]));
|
|
16804
16814
|
function generateDraftId() {
|
|
@@ -17486,6 +17496,53 @@ function getQueuedCount(sessionId) {
|
|
|
17486
17496
|
const state = getState();
|
|
17487
17497
|
return state.queuedCounts.get(sessionId) || 0;
|
|
17488
17498
|
}
|
|
17499
|
+
function buildInteractiveIdleReminderNotice() {
|
|
17500
|
+
return [
|
|
17501
|
+
"\u63D0\u9192\uFF1A\u8FD9\u8F6E\u4EFB\u52A1\u4ECD\u5728\u8FD0\u884C\uFF0C\u4F46\u5DF2\u7ECF\u8D85\u8FC7 10 \u5206\u949F\u6CA1\u6709\u65B0\u7684\u6267\u884C\u8F93\u51FA\u3002",
|
|
17502
|
+
"\u7CFB\u7EDF\u4E0D\u4F1A\u81EA\u52A8\u7EC8\u6B62\u5B83\uFF1B\u5982\u679C\u4F60\u4ECD\u5728\u5BF9\u5E94\u7EBF\u7A0B\uFF0C\u53EF\u53D1\u9001 `/stop` \u4E3B\u52A8\u505C\u6B62\uFF1B\u5982\u679C\u5DF2\u7ECF\u5207\u5230\u522B\u7684\u7EBF\u7A0B\uFF0C\u9700\u8981\u5148\u5207\u56DE\u5BF9\u5E94\u7EBF\u7A0B\u3002"
|
|
17503
|
+
].join("\n");
|
|
17504
|
+
}
|
|
17505
|
+
function isCurrentInteractiveTask(sessionId, taskId) {
|
|
17506
|
+
return getState().activeTasks.get(sessionId)?.id === taskId;
|
|
17507
|
+
}
|
|
17508
|
+
function touchInteractiveTask(sessionId, taskId) {
|
|
17509
|
+
const task = getState().activeTasks.get(sessionId);
|
|
17510
|
+
if (task?.id !== taskId) return;
|
|
17511
|
+
task.lastActivityAt = Date.now();
|
|
17512
|
+
task.idleReminderSent = false;
|
|
17513
|
+
}
|
|
17514
|
+
function releaseInteractiveTask(sessionId, taskId) {
|
|
17515
|
+
const state = getState();
|
|
17516
|
+
const current = state.activeTasks.get(sessionId);
|
|
17517
|
+
if (current?.id !== taskId) return;
|
|
17518
|
+
state.activeTasks.delete(sessionId);
|
|
17519
|
+
syncSessionRuntimeState(sessionId);
|
|
17520
|
+
}
|
|
17521
|
+
async function remindIdleInteractiveTask(task) {
|
|
17522
|
+
if (!isCurrentInteractiveTask(task.sessionId, task.id) || task.idleReminderSent) return;
|
|
17523
|
+
task.idleReminderSent = true;
|
|
17524
|
+
try {
|
|
17525
|
+
await deliver(task.adapter, {
|
|
17526
|
+
address: task.address,
|
|
17527
|
+
text: renderFeedbackTextForChannel(
|
|
17528
|
+
task.adapter.channelType,
|
|
17529
|
+
buildInteractiveIdleReminderNotice()
|
|
17530
|
+
),
|
|
17531
|
+
parseMode: getFeedbackParseMode(task.adapter.channelType),
|
|
17532
|
+
replyToMessageId: task.requestMessageId
|
|
17533
|
+
});
|
|
17534
|
+
} catch {
|
|
17535
|
+
}
|
|
17536
|
+
}
|
|
17537
|
+
async function reconcileIdleInteractiveTasks() {
|
|
17538
|
+
const now2 = Date.now();
|
|
17539
|
+
const tasks = Array.from(getState().activeTasks.values());
|
|
17540
|
+
for (const task of tasks) {
|
|
17541
|
+
if (task.idleReminderSent) continue;
|
|
17542
|
+
if (now2 - task.lastActivityAt < INTERACTIVE_IDLE_REMINDER_MS) continue;
|
|
17543
|
+
await remindIdleInteractiveTask(task);
|
|
17544
|
+
}
|
|
17545
|
+
}
|
|
17489
17546
|
function syncSessionRuntimeState(sessionId) {
|
|
17490
17547
|
const { store } = getBridgeContext();
|
|
17491
17548
|
const session = store.getSession(sessionId);
|
|
@@ -18517,6 +18574,9 @@ async function start() {
|
|
|
18517
18574
|
void syncConfiguredAdapters({ startLoops: true }).catch((err) => {
|
|
18518
18575
|
console.error("[bridge-manager] Adapter reconcile failed:", err);
|
|
18519
18576
|
});
|
|
18577
|
+
void reconcileIdleInteractiveTasks().catch((err) => {
|
|
18578
|
+
console.error("[bridge-manager] Interactive idle reminder reconcile failed:", err);
|
|
18579
|
+
});
|
|
18520
18580
|
}, 5e3);
|
|
18521
18581
|
state.mirrorPollTimer = setInterval(() => {
|
|
18522
18582
|
void reconcileMirrorSubscriptions().catch((err) => {
|
|
@@ -18550,8 +18610,8 @@ async function stop() {
|
|
|
18550
18610
|
}
|
|
18551
18611
|
state.loopAborts.clear();
|
|
18552
18612
|
const activeSessionIds = Array.from(state.activeTasks.keys());
|
|
18553
|
-
for (const
|
|
18554
|
-
|
|
18613
|
+
for (const task of state.activeTasks.values()) {
|
|
18614
|
+
task.abortController.abort();
|
|
18555
18615
|
}
|
|
18556
18616
|
state.activeTasks.clear();
|
|
18557
18617
|
state.mirrorSuppressUntil.clear();
|
|
@@ -18759,10 +18819,25 @@ async function handleMessage(adapter, msg) {
|
|
|
18759
18819
|
const streamKey = buildInteractiveStreamKey(binding.codepilotSessionId, msg.messageId);
|
|
18760
18820
|
adapter.onMessageStart?.(msg.address.chatId, streamKey);
|
|
18761
18821
|
const taskAbort = new AbortController();
|
|
18822
|
+
const taskId = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
18762
18823
|
const state = getState();
|
|
18763
18824
|
resetMirrorSessionForInteractiveRun(binding.codepilotSessionId);
|
|
18764
|
-
|
|
18765
|
-
|
|
18825
|
+
const taskState = {
|
|
18826
|
+
id: taskId,
|
|
18827
|
+
abortController: taskAbort,
|
|
18828
|
+
adapter,
|
|
18829
|
+
address: msg.address,
|
|
18830
|
+
requestMessageId: msg.messageId,
|
|
18831
|
+
streamKey,
|
|
18832
|
+
sessionId: binding.codepilotSessionId,
|
|
18833
|
+
hasStreamingCards: false,
|
|
18834
|
+
lastActivityAt: Date.now(),
|
|
18835
|
+
idleReminderSent: false,
|
|
18836
|
+
streamFinalized: false,
|
|
18837
|
+
uiEnded: false,
|
|
18838
|
+
mirrorSuppressionId: null
|
|
18839
|
+
};
|
|
18840
|
+
state.activeTasks.set(binding.codepilotSessionId, taskState);
|
|
18766
18841
|
syncSessionRuntimeState(binding.codepilotSessionId);
|
|
18767
18842
|
let previewState = null;
|
|
18768
18843
|
const caps = adapter.getPreviewCapabilities?.(msg.address.chatId) ?? null;
|
|
@@ -18811,8 +18886,10 @@ async function handleMessage(adapter, msg) {
|
|
|
18811
18886
|
flushPreview(adapter, ps, cfg);
|
|
18812
18887
|
} : void 0;
|
|
18813
18888
|
const hasStreamingCards = typeof adapter.onStreamText === "function";
|
|
18889
|
+
taskState.hasStreamingCards = hasStreamingCards;
|
|
18814
18890
|
const toolCallTracker = /* @__PURE__ */ new Map();
|
|
18815
18891
|
const onStreamCardText = hasStreamingCards ? (fullText) => {
|
|
18892
|
+
if (!isCurrentInteractiveTask(binding.codepilotSessionId, taskId)) return;
|
|
18816
18893
|
const rendered = renderFeedbackTextForChannel(
|
|
18817
18894
|
adapter.channelType,
|
|
18818
18895
|
stripOutboundArtifactBlocksForStreaming(fullText)
|
|
@@ -18823,6 +18900,8 @@ async function handleMessage(adapter, msg) {
|
|
|
18823
18900
|
}
|
|
18824
18901
|
} : void 0;
|
|
18825
18902
|
const onToolEvent = hasStreamingCards ? (toolId, toolName, status) => {
|
|
18903
|
+
if (!isCurrentInteractiveTask(binding.codepilotSessionId, taskId)) return;
|
|
18904
|
+
touchInteractiveTask(binding.codepilotSessionId, taskId);
|
|
18826
18905
|
if (toolName) {
|
|
18827
18906
|
toolCallTracker.set(toolId, { id: toolId, name: toolName, status });
|
|
18828
18907
|
} else {
|
|
@@ -18835,6 +18914,8 @@ async function handleMessage(adapter, msg) {
|
|
|
18835
18914
|
}
|
|
18836
18915
|
} : void 0;
|
|
18837
18916
|
const onPartialText = previewOnPartialText || onStreamCardText ? (fullText) => {
|
|
18917
|
+
if (!isCurrentInteractiveTask(binding.codepilotSessionId, taskId)) return;
|
|
18918
|
+
touchInteractiveTask(binding.codepilotSessionId, taskId);
|
|
18838
18919
|
if (previewOnPartialText) previewOnPartialText(fullText);
|
|
18839
18920
|
if (onStreamCardText) onStreamCardText(fullText);
|
|
18840
18921
|
} : void 0;
|
|
@@ -18852,10 +18933,13 @@ async function handleMessage(adapter, msg) {
|
|
|
18852
18933
|
msg.messageId
|
|
18853
18934
|
);
|
|
18854
18935
|
}, taskAbort.signal, hasAttachments ? msg.attachments : void 0, onPartialText, onToolEvent, (preparedPrompt) => {
|
|
18855
|
-
if (!mirrorSuppressionId) {
|
|
18856
|
-
mirrorSuppressionId = beginMirrorSuppression(binding.codepilotSessionId, preparedPrompt);
|
|
18936
|
+
if (!taskState.mirrorSuppressionId) {
|
|
18937
|
+
taskState.mirrorSuppressionId = beginMirrorSuppression(binding.codepilotSessionId, preparedPrompt);
|
|
18857
18938
|
}
|
|
18858
18939
|
});
|
|
18940
|
+
if (!isCurrentInteractiveTask(binding.codepilotSessionId, taskId)) {
|
|
18941
|
+
return;
|
|
18942
|
+
}
|
|
18859
18943
|
let cardFinalized = false;
|
|
18860
18944
|
if (hasStreamingCards && adapter.onStreamEnd) {
|
|
18861
18945
|
try {
|
|
@@ -18866,6 +18950,7 @@ async function handleMessage(adapter, msg) {
|
|
|
18866
18950
|
renderFeedbackTextForChannel(adapter.channelType, result.responseText),
|
|
18867
18951
|
streamKey
|
|
18868
18952
|
);
|
|
18953
|
+
taskState.streamFinalized = cardFinalized;
|
|
18869
18954
|
} catch (err) {
|
|
18870
18955
|
console.warn("[bridge-manager] Card finalize failed:", err instanceof Error ? err.message : err);
|
|
18871
18956
|
}
|
|
@@ -18890,14 +18975,9 @@ async function handleMessage(adapter, msg) {
|
|
|
18890
18975
|
[]
|
|
18891
18976
|
);
|
|
18892
18977
|
}
|
|
18893
|
-
|
|
18894
|
-
|
|
18895
|
-
|
|
18896
|
-
if (update !== null) {
|
|
18897
|
-
store.updateChannelBinding(binding.id, { sdkSessionId: update });
|
|
18898
|
-
}
|
|
18899
|
-
} catch {
|
|
18900
|
-
}
|
|
18978
|
+
try {
|
|
18979
|
+
persistSdkSessionUpdate(binding.codepilotSessionId, result.sdkSessionId, result.hasError);
|
|
18980
|
+
} catch {
|
|
18901
18981
|
}
|
|
18902
18982
|
} finally {
|
|
18903
18983
|
if (previewState) {
|
|
@@ -18907,18 +18987,22 @@ async function handleMessage(adapter, msg) {
|
|
|
18907
18987
|
}
|
|
18908
18988
|
adapter.endPreview?.(msg.address.chatId, previewState.draftId);
|
|
18909
18989
|
}
|
|
18910
|
-
if (hasStreamingCards && adapter.onStreamEnd && taskAbort.signal.aborted) {
|
|
18990
|
+
if (hasStreamingCards && adapter.onStreamEnd && taskAbort.signal.aborted && !taskState.streamFinalized) {
|
|
18911
18991
|
try {
|
|
18912
18992
|
await adapter.onStreamEnd(msg.address.chatId, "interrupted", "", streamKey);
|
|
18993
|
+
taskState.streamFinalized = true;
|
|
18913
18994
|
} catch {
|
|
18914
18995
|
}
|
|
18915
18996
|
}
|
|
18916
|
-
if (mirrorSuppressionId) {
|
|
18917
|
-
settleMirrorSuppression(binding.codepilotSessionId, mirrorSuppressionId);
|
|
18997
|
+
if (taskState.mirrorSuppressionId) {
|
|
18998
|
+
settleMirrorSuppression(binding.codepilotSessionId, taskState.mirrorSuppressionId);
|
|
18999
|
+
taskState.mirrorSuppressionId = null;
|
|
19000
|
+
}
|
|
19001
|
+
releaseInteractiveTask(binding.codepilotSessionId, taskId);
|
|
19002
|
+
if (!taskState.uiEnded) {
|
|
19003
|
+
adapter.onMessageEnd?.(msg.address.chatId, streamKey);
|
|
19004
|
+
taskState.uiEnded = true;
|
|
18918
19005
|
}
|
|
18919
|
-
state.activeTasks.delete(binding.codepilotSessionId);
|
|
18920
|
-
syncSessionRuntimeState(binding.codepilotSessionId);
|
|
18921
|
-
adapter.onMessageEnd?.(msg.address.chatId, streamKey);
|
|
18922
19006
|
ack();
|
|
18923
19007
|
}
|
|
18924
19008
|
}
|
|
@@ -18971,13 +19055,6 @@ async function handleCommand(adapter, msg, text2) {
|
|
|
18971
19055
|
response = resolved.message;
|
|
18972
19056
|
break;
|
|
18973
19057
|
}
|
|
18974
|
-
if (currentBinding) {
|
|
18975
|
-
const st = getState();
|
|
18976
|
-
const oldTask = st.activeTasks.get(currentBinding.codepilotSessionId);
|
|
18977
|
-
if (oldTask) {
|
|
18978
|
-
oldTask.abort();
|
|
18979
|
-
}
|
|
18980
|
-
}
|
|
18981
19058
|
const workDir = resolved.workDir;
|
|
18982
19059
|
ensureWorkingDirectoryExists(workDir);
|
|
18983
19060
|
const binding = createBinding(msg.address, workDir);
|
|
@@ -18991,6 +19068,7 @@ async function handleCommand(adapter, msg, text2) {
|
|
|
18991
19068
|
],
|
|
18992
19069
|
[
|
|
18993
19070
|
args.trim() ? "\u63A5\u4E0B\u6765\u76F4\u63A5\u53D1\u9001\u6587\u672C\u5373\u53EF\u7EE7\u7EED\u3002" : "\u5DF2\u5728\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u4E0B\u65B0\u5EFA\u4E00\u4E2A\u7EBF\u7A0B\u3002\u63A5\u4E0B\u6765\u76F4\u63A5\u53D1\u9001\u6587\u672C\u5373\u53EF\u7EE7\u7EED\u3002",
|
|
19071
|
+
"\u5982\u679C\u5F53\u524D\u804A\u5929\u91CC\u5DF2\u6709\u65E7\u4EFB\u52A1\u5728\u8FD0\u884C\uFF0C\u5B83\u4E0D\u4F1A\u88AB\u7EC8\u6B62\uFF0C\u4ECD\u4F1A\u5728\u540E\u53F0\u7EE7\u7EED\u6267\u884C\u5E76\u53EF\u80FD\u7A0D\u540E\u56DE\u6D88\u606F\u3002",
|
|
18994
19072
|
"\u8FD9\u662F IM \u4FA7\u7EBF\u7A0B\uFF0C\u5F53\u524D\u53EA\u4FDD\u8BC1\u5728 IM \u4E2D\u53EF\u7EE7\u7EED\uFF1B\u4E0D\u4F1A\u81EA\u52A8\u51FA\u73B0\u5728 Codex Desktop \u4F1A\u8BDD\u5217\u8868\u4E2D\u3002"
|
|
18995
19073
|
],
|
|
18996
19074
|
responseParseMode === "Markdown"
|
|
@@ -19402,6 +19480,7 @@ ${truncateHistoryContent(formatStoredMessageContent(message.content))}`;
|
|
|
19402
19480
|
return {
|
|
19403
19481
|
heading: `${getSessionDisplayName(session, session.working_directory)}${session.id === currentBinding?.codepilotSessionId ? " [\u5F53\u524D]" : ""}`,
|
|
19404
19482
|
details: [
|
|
19483
|
+
`\u72B6\u6001\uFF1A${formatRuntimeStatus(session)}`,
|
|
19405
19484
|
`\u76EE\u5F55\uFF1A${formatCommandPath(session.working_directory)}`
|
|
19406
19485
|
]
|
|
19407
19486
|
};
|
|
@@ -19420,7 +19499,7 @@ ${truncateHistoryContent(formatStoredMessageContent(message.content))}`;
|
|
|
19420
19499
|
const st = getState();
|
|
19421
19500
|
const taskAbort = st.activeTasks.get(binding.codepilotSessionId);
|
|
19422
19501
|
if (taskAbort) {
|
|
19423
|
-
taskAbort.abort();
|
|
19502
|
+
taskAbort.abortController.abort();
|
|
19424
19503
|
response = "\u6B63\u5728\u505C\u6B62\u5F53\u524D\u4EFB\u52A1...";
|
|
19425
19504
|
} else {
|
|
19426
19505
|
response = "\u5F53\u524D\u6CA1\u6709\u6B63\u5728\u8FD0\u884C\u7684\u4EFB\u52A1\u3002";
|
|
@@ -19525,6 +19604,13 @@ function computeSdkSessionUpdate(sdkSessionId, hasError) {
|
|
|
19525
19604
|
}
|
|
19526
19605
|
return null;
|
|
19527
19606
|
}
|
|
19607
|
+
function persistSdkSessionUpdate(sessionId, sdkSessionId, hasError) {
|
|
19608
|
+
const update = computeSdkSessionUpdate(sdkSessionId, hasError);
|
|
19609
|
+
if (update === null) {
|
|
19610
|
+
return;
|
|
19611
|
+
}
|
|
19612
|
+
getBridgeContext().store.updateSdkSessionId(sessionId, update);
|
|
19613
|
+
}
|
|
19528
19614
|
|
|
19529
19615
|
// src/store.ts
|
|
19530
19616
|
import fs9 from "node:fs";
|
package/package.json
CHANGED