@linzumi/cli 0.0.98-beta → 0.0.100-beta
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 +1 -1
- package/dist/index.js +157 -47
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -19803,7 +19803,7 @@ var linzumiCliVersion, linzumiCliVersionText;
|
|
|
19803
19803
|
var init_version = __esm({
|
|
19804
19804
|
"src/version.ts"() {
|
|
19805
19805
|
"use strict";
|
|
19806
|
-
linzumiCliVersion = "0.0.
|
|
19806
|
+
linzumiCliVersion = "0.0.100-beta";
|
|
19807
19807
|
linzumiCliVersionText = `linzumi ${linzumiCliVersion}`;
|
|
19808
19808
|
}
|
|
19809
19809
|
});
|
|
@@ -22098,6 +22098,37 @@ var init_runnerConsoleReporter = __esm({
|
|
|
22098
22098
|
}
|
|
22099
22099
|
});
|
|
22100
22100
|
|
|
22101
|
+
// src/threadRebuildSerializer.ts
|
|
22102
|
+
function createThreadRebuildSerializer() {
|
|
22103
|
+
const chains = /* @__PURE__ */ new Map();
|
|
22104
|
+
return {
|
|
22105
|
+
async run(key, fn) {
|
|
22106
|
+
const prior = chains.get(key) ?? Promise.resolve();
|
|
22107
|
+
const run = prior.then(fn, fn);
|
|
22108
|
+
const tail = run.then(
|
|
22109
|
+
() => void 0,
|
|
22110
|
+
() => void 0
|
|
22111
|
+
);
|
|
22112
|
+
chains.set(key, tail);
|
|
22113
|
+
try {
|
|
22114
|
+
return await run;
|
|
22115
|
+
} finally {
|
|
22116
|
+
if (chains.get(key) === tail) {
|
|
22117
|
+
chains.delete(key);
|
|
22118
|
+
}
|
|
22119
|
+
}
|
|
22120
|
+
},
|
|
22121
|
+
activeKeyCount() {
|
|
22122
|
+
return chains.size;
|
|
22123
|
+
}
|
|
22124
|
+
};
|
|
22125
|
+
}
|
|
22126
|
+
var init_threadRebuildSerializer = __esm({
|
|
22127
|
+
"src/threadRebuildSerializer.ts"() {
|
|
22128
|
+
"use strict";
|
|
22129
|
+
}
|
|
22130
|
+
});
|
|
22131
|
+
|
|
22101
22132
|
// src/telemetry.ts
|
|
22102
22133
|
import { mkdirSync as mkdirSync11, readFileSync as readFileSync14, writeFileSync as writeFileSync9 } from "node:fs";
|
|
22103
22134
|
import { dirname as dirname11, basename as basename7, join as join18 } from "node:path";
|
|
@@ -24579,6 +24610,17 @@ async function openLocalCodexRunner(options, log2, cleanup, close) {
|
|
|
24579
24610
|
}
|
|
24580
24611
|
const dynamicChannelSessions = /* @__PURE__ */ new Map();
|
|
24581
24612
|
const dynamicChannelSessionAttachInFlight = /* @__PURE__ */ new Map();
|
|
24613
|
+
const dynamicChannelSessionAttachWaiters = /* @__PURE__ */ new Map();
|
|
24614
|
+
const resolveDynamicChannelSessionAttachWaiters = (codexThreadId, session) => {
|
|
24615
|
+
const waiters = dynamicChannelSessionAttachWaiters.get(codexThreadId);
|
|
24616
|
+
if (waiters === void 0) {
|
|
24617
|
+
return;
|
|
24618
|
+
}
|
|
24619
|
+
dynamicChannelSessionAttachWaiters.delete(codexThreadId);
|
|
24620
|
+
for (const waiter of waiters) {
|
|
24621
|
+
waiter(session);
|
|
24622
|
+
}
|
|
24623
|
+
};
|
|
24582
24624
|
const dynamicChannelSessionCodexClients = /* @__PURE__ */ new Map();
|
|
24583
24625
|
const codexTurnFailureGuards = /* @__PURE__ */ new Map();
|
|
24584
24626
|
const lossReportPushes = [];
|
|
@@ -24640,6 +24682,7 @@ async function openLocalCodexRunner(options, log2, cleanup, close) {
|
|
|
24640
24682
|
);
|
|
24641
24683
|
dynamicChannelSessions.clear();
|
|
24642
24684
|
dynamicChannelSessionCodexClients.clear();
|
|
24685
|
+
dynamicChannelSessionAttachWaiters.clear();
|
|
24643
24686
|
const claudeSessions = [...activeClaudeCodeSessions.values()];
|
|
24644
24687
|
for (const session of claudeSessions) {
|
|
24645
24688
|
try {
|
|
@@ -24687,6 +24730,7 @@ async function openLocalCodexRunner(options, log2, cleanup, close) {
|
|
|
24687
24730
|
);
|
|
24688
24731
|
threadRunnerProcesses.clear();
|
|
24689
24732
|
});
|
|
24733
|
+
const threadRebuildSerializer = createThreadRebuildSerializer();
|
|
24690
24734
|
const evictStaleDynamicChannelSession = async (codexThreadId, expectClient) => {
|
|
24691
24735
|
const session = dynamicChannelSessions.get(codexThreadId);
|
|
24692
24736
|
const boundClient = dynamicChannelSessionCodexClients.get(codexThreadId);
|
|
@@ -24716,6 +24760,28 @@ async function openLocalCodexRunner(options, log2, cleanup, close) {
|
|
|
24716
24760
|
}
|
|
24717
24761
|
return true;
|
|
24718
24762
|
};
|
|
24763
|
+
const resolveLiveDynamicChannelSession = async (codexThreadId, options2 = {}) => {
|
|
24764
|
+
const existing = dynamicChannelSessions.get(codexThreadId);
|
|
24765
|
+
if (existing !== void 0) {
|
|
24766
|
+
return existing;
|
|
24767
|
+
}
|
|
24768
|
+
const inFlight = dynamicChannelSessionAttachInFlight.get(codexThreadId);
|
|
24769
|
+
if (inFlight !== void 0) {
|
|
24770
|
+
const attached = await inFlight;
|
|
24771
|
+
if (attached !== void 0) {
|
|
24772
|
+
return attached;
|
|
24773
|
+
}
|
|
24774
|
+
}
|
|
24775
|
+
const settled = dynamicChannelSessions.get(codexThreadId);
|
|
24776
|
+
if (settled !== void 0 || options2.waitForSiblingSpawn !== true) {
|
|
24777
|
+
return settled;
|
|
24778
|
+
}
|
|
24779
|
+
return await new Promise((resolve12) => {
|
|
24780
|
+
const waiters = dynamicChannelSessionAttachWaiters.get(codexThreadId) ?? [];
|
|
24781
|
+
waiters.push(resolve12);
|
|
24782
|
+
dynamicChannelSessionAttachWaiters.set(codexThreadId, waiters);
|
|
24783
|
+
});
|
|
24784
|
+
};
|
|
24719
24785
|
const attachThreadSessionWithCodex = async (args) => {
|
|
24720
24786
|
const { control, cwd, codexThreadId, sessionCodex } = args;
|
|
24721
24787
|
const portForwardWatcherRootPid = args.portForwardWatcherRootPid;
|
|
@@ -24744,36 +24810,50 @@ async function openLocalCodexRunner(options, log2, cleanup, close) {
|
|
|
24744
24810
|
);
|
|
24745
24811
|
}
|
|
24746
24812
|
const runtimeSettings = startInstanceRuntimeSettings(options, control);
|
|
24747
|
-
const rebuildOnDeadCodexWorker = shouldUseThreadProcesses(options) ? async (rebuildArgs) =>
|
|
24748
|
-
|
|
24749
|
-
|
|
24750
|
-
|
|
24751
|
-
const reconnectControl = {
|
|
24752
|
-
type: "reconnect_thread",
|
|
24753
|
-
workspace: workspaceSlug,
|
|
24754
|
-
channel: channelSlug,
|
|
24755
|
-
threadId: rebuildArgs.kandanThreadId,
|
|
24756
|
-
codexThreadId: rebuildArgs.codexThreadId,
|
|
24757
|
-
cwd,
|
|
24758
|
-
// Carry the conversation context through the rebuild-replay so
|
|
24759
|
-
// the respawned worker's developer instructions match what the
|
|
24760
|
-
// server would have replayed (parity with the live reconnect
|
|
24761
|
-
// control built above at channelSession.linzumiContext).
|
|
24762
|
-
...control.linzumiContext === void 0 ? {} : { linzumiContext: control.linzumiContext },
|
|
24763
|
-
...integerValue(control.rootSeq) === void 0 ? {} : { rootSeq: integerValue(control.rootSeq) },
|
|
24764
|
-
sourceSeq: message.seq,
|
|
24765
|
-
workDescription: message.body,
|
|
24766
|
-
...runtimeSettings.model === void 0 ? {} : { model: runtimeSettings.model },
|
|
24767
|
-
...runtimeSettings.reasoningEffort === void 0 ? {} : { reasoningEffort: runtimeSettings.reasoningEffort },
|
|
24768
|
-
...runtimeSettings.sandbox === void 0 ? {} : { sandbox: runtimeSettings.sandbox },
|
|
24769
|
-
...runtimeSettings.approvalPolicy === void 0 ? {} : { approvalPolicy: runtimeSettings.approvalPolicy },
|
|
24770
|
-
...runtimeSettings.fast === void 0 ? {} : { fast: runtimeSettings.fast }
|
|
24771
|
-
};
|
|
24772
|
-
const liveSession = dynamicChannelSessions.get(
|
|
24813
|
+
const rebuildOnDeadCodexWorker = shouldUseThreadProcesses(options) ? async (rebuildArgs) => threadRebuildSerializer.run(
|
|
24814
|
+
rebuildArgs.kandanThreadId,
|
|
24815
|
+
async () => {
|
|
24816
|
+
await evictStaleDynamicChannelSession(
|
|
24773
24817
|
rebuildArgs.codexThreadId
|
|
24774
24818
|
);
|
|
24775
|
-
|
|
24776
|
-
|
|
24819
|
+
let rebuilt = false;
|
|
24820
|
+
for (const message of rebuildArgs.pendingMessages) {
|
|
24821
|
+
const reconnectControl = {
|
|
24822
|
+
type: "reconnect_thread",
|
|
24823
|
+
workspace: workspaceSlug,
|
|
24824
|
+
channel: channelSlug,
|
|
24825
|
+
threadId: rebuildArgs.kandanThreadId,
|
|
24826
|
+
codexThreadId: rebuildArgs.codexThreadId,
|
|
24827
|
+
cwd,
|
|
24828
|
+
// Carry the conversation context through the rebuild-replay so
|
|
24829
|
+
// the respawned worker's developer instructions match what the
|
|
24830
|
+
// server would have replayed (parity with the live reconnect
|
|
24831
|
+
// control built above at channelSession.linzumiContext).
|
|
24832
|
+
...control.linzumiContext === void 0 ? {} : { linzumiContext: control.linzumiContext },
|
|
24833
|
+
...integerValue(control.rootSeq) === void 0 ? {} : { rootSeq: integerValue(control.rootSeq) },
|
|
24834
|
+
sourceSeq: message.seq,
|
|
24835
|
+
workDescription: message.body,
|
|
24836
|
+
...runtimeSettings.model === void 0 ? {} : { model: runtimeSettings.model },
|
|
24837
|
+
...runtimeSettings.reasoningEffort === void 0 ? {} : { reasoningEffort: runtimeSettings.reasoningEffort },
|
|
24838
|
+
...runtimeSettings.sandbox === void 0 ? {} : { sandbox: runtimeSettings.sandbox },
|
|
24839
|
+
...runtimeSettings.approvalPolicy === void 0 ? {} : { approvalPolicy: runtimeSettings.approvalPolicy },
|
|
24840
|
+
...runtimeSettings.fast === void 0 ? {} : { fast: runtimeSettings.fast }
|
|
24841
|
+
};
|
|
24842
|
+
const replayOntoLiveSession = async (options2) => {
|
|
24843
|
+
const liveSession = await withCodexStartRequestTimeout(
|
|
24844
|
+
"thread/attach",
|
|
24845
|
+
resolveLiveDynamicChannelSession(
|
|
24846
|
+
rebuildArgs.codexThreadId,
|
|
24847
|
+
{
|
|
24848
|
+
waitForSiblingSpawn: options2.waitForSiblingSpawn
|
|
24849
|
+
}
|
|
24850
|
+
)
|
|
24851
|
+
);
|
|
24852
|
+
if (liveSession === void 0) {
|
|
24853
|
+
throw new Error(
|
|
24854
|
+
`dead-worker rebuild could not resolve a live session for codex thread ${rebuildArgs.codexThreadId}`
|
|
24855
|
+
);
|
|
24856
|
+
}
|
|
24777
24857
|
await liveSession.startThreadMessageTurn({
|
|
24778
24858
|
seq: message.seq,
|
|
24779
24859
|
body: message.body,
|
|
@@ -24781,22 +24861,45 @@ async function openLocalCodexRunner(options, log2, cleanup, close) {
|
|
|
24781
24861
|
actorUserId: message.actorUserId,
|
|
24782
24862
|
boundStartTimeout: true
|
|
24783
24863
|
});
|
|
24784
|
-
}
|
|
24785
|
-
|
|
24864
|
+
};
|
|
24865
|
+
try {
|
|
24866
|
+
if (rebuilt) {
|
|
24867
|
+
await replayOntoLiveSession({
|
|
24868
|
+
waitForSiblingSpawn: false
|
|
24869
|
+
});
|
|
24870
|
+
} else {
|
|
24871
|
+
const startResult = await startThreadRunnerProcess(
|
|
24872
|
+
reconnectControl,
|
|
24873
|
+
cwd
|
|
24874
|
+
);
|
|
24875
|
+
if (threadStartDelegatedToSibling(startResult)) {
|
|
24876
|
+
log2(
|
|
24877
|
+
"runner.thread_dead_worker_rebuild_replay_on_sibling",
|
|
24878
|
+
{
|
|
24879
|
+
codex_thread_id: rebuildArgs.codexThreadId,
|
|
24880
|
+
kandan_thread_id: rebuildArgs.kandanThreadId,
|
|
24881
|
+
seq: message.seq
|
|
24882
|
+
}
|
|
24883
|
+
);
|
|
24884
|
+
await replayOntoLiveSession({
|
|
24885
|
+
waitForSiblingSpawn: true
|
|
24886
|
+
});
|
|
24887
|
+
}
|
|
24888
|
+
}
|
|
24889
|
+
rebuilt = true;
|
|
24890
|
+
} catch (error) {
|
|
24891
|
+
log2("runner.thread_dead_worker_rebuild_failed", {
|
|
24892
|
+
codex_thread_id: rebuildArgs.codexThreadId,
|
|
24893
|
+
kandan_thread_id: rebuildArgs.kandanThreadId,
|
|
24894
|
+
seq: message.seq,
|
|
24895
|
+
message: error instanceof Error ? error.message : String(error)
|
|
24896
|
+
});
|
|
24897
|
+
return false;
|
|
24786
24898
|
}
|
|
24787
|
-
rebuilt = true;
|
|
24788
|
-
} catch (error) {
|
|
24789
|
-
log2("runner.thread_dead_worker_rebuild_failed", {
|
|
24790
|
-
codex_thread_id: rebuildArgs.codexThreadId,
|
|
24791
|
-
kandan_thread_id: rebuildArgs.kandanThreadId,
|
|
24792
|
-
seq: message.seq,
|
|
24793
|
-
message: error instanceof Error ? error.message : String(error)
|
|
24794
|
-
});
|
|
24795
|
-
return false;
|
|
24796
24899
|
}
|
|
24900
|
+
return rebuilt;
|
|
24797
24901
|
}
|
|
24798
|
-
|
|
24799
|
-
} : void 0;
|
|
24902
|
+
) : void 0;
|
|
24800
24903
|
const session = await attachChannelSession({
|
|
24801
24904
|
kandan,
|
|
24802
24905
|
codex: sessionCodex,
|
|
@@ -24854,6 +24957,7 @@ async function openLocalCodexRunner(options, log2, cleanup, close) {
|
|
|
24854
24957
|
});
|
|
24855
24958
|
dynamicChannelSessions.set(codexThreadId, session);
|
|
24856
24959
|
dynamicChannelSessionCodexClients.set(codexThreadId, sessionCodex);
|
|
24960
|
+
resolveDynamicChannelSessionAttachWaiters(codexThreadId, session);
|
|
24857
24961
|
threadSessionRegistry.upsert({
|
|
24858
24962
|
workspace: workspaceSlug,
|
|
24859
24963
|
channel: channelSlug,
|
|
@@ -25973,6 +26077,9 @@ function controlTargetsInstance(control, instanceId) {
|
|
|
25973
26077
|
function controlInstanceId(control) {
|
|
25974
26078
|
return "instanceId" in control ? control.instanceId : void 0;
|
|
25975
26079
|
}
|
|
26080
|
+
function threadStartDelegatedToSibling(startResult) {
|
|
26081
|
+
return startResult !== void 0 && startResult.delegated === true && startResult.threadProcess === "already_started";
|
|
26082
|
+
}
|
|
25976
26083
|
function shouldUseThreadProcesses(options) {
|
|
25977
26084
|
if (options.threadProcess?.role === "thread") {
|
|
25978
26085
|
return false;
|
|
@@ -27119,7 +27226,10 @@ async function applyControl(codex, kandan, topic, instanceId, options, agentProv
|
|
|
27119
27226
|
ensureCodexProjectTrusted(cwd.cwd);
|
|
27120
27227
|
}
|
|
27121
27228
|
const runtimeSettings = startInstanceRuntimeSettings(options, control);
|
|
27122
|
-
const startedThreadSession = onStartedThread === void 0 ? void 0 : await
|
|
27229
|
+
const startedThreadSession = onStartedThread === void 0 ? void 0 : await withCodexStartRequestTimeout(
|
|
27230
|
+
"thread/attach",
|
|
27231
|
+
onStartedThread(control, cwd.cwd, codexThreadId)
|
|
27232
|
+
);
|
|
27123
27233
|
if (workDescription !== void 0) {
|
|
27124
27234
|
const rootSeq = integerValue(control.rootSeq);
|
|
27125
27235
|
const sourceSeq = integerValue(control.sourceSeq) ?? rootSeq;
|
|
@@ -27811,10 +27921,9 @@ async function startCodexProviderInstance(args) {
|
|
|
27811
27921
|
let startedThreadSession;
|
|
27812
27922
|
if (codexThreadId !== void 0 && args.onStartedThread !== void 0) {
|
|
27813
27923
|
args.setStartupStage("binding_kandan_thread");
|
|
27814
|
-
startedThreadSession = await
|
|
27815
|
-
|
|
27816
|
-
args.cwd,
|
|
27817
|
-
codexThreadId
|
|
27924
|
+
startedThreadSession = await withCodexStartRequestTimeout(
|
|
27925
|
+
"thread/attach",
|
|
27926
|
+
args.onStartedThread(args.control, args.cwd, codexThreadId)
|
|
27818
27927
|
);
|
|
27819
27928
|
}
|
|
27820
27929
|
if (codexThreadId !== void 0 && workDescription !== void 0) {
|
|
@@ -31130,6 +31239,7 @@ var init_runner = __esm({
|
|
|
31130
31239
|
init_runnerLockTakeover();
|
|
31131
31240
|
init_runnerConsoleReporter();
|
|
31132
31241
|
init_version();
|
|
31242
|
+
init_threadRebuildSerializer();
|
|
31133
31243
|
init_telemetry();
|
|
31134
31244
|
init_mcpConfig();
|
|
31135
31245
|
init_linzumiApiClient();
|
package/package.json
CHANGED