@linzumi/cli 1.0.180 → 1.0.182
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/impl-ts/index.js
CHANGED
|
@@ -1510,7 +1510,7 @@ To kick the agent off:
|
|
|
1510
1510
|
`,O=Buffer.byteLength(T,"utf8");if(O>s)return l("runner_diagnostics.spool_entry_dropped",{reason:"entry_too_large",entry_bytes:O,max_entry_bytes:s}),!1;BEe(n,{recursive:!0}),m(u)+O>i&&f(),_(O);let P=b()?`
|
|
1511
1511
|
`:"";return NEe(u,`${P}${T}`,"utf8"),!0}catch(R){return l("runner_diagnostics.spool_failed",{error:R instanceof Error?R.message:String(R)}),!1}},w=S=>{let R=[],T=KEe(S,"utf8");for(let O of T.split(`
|
|
1512
1512
|
`))if(O.trim()!=="")try{let P=JSON.parse(O);P!==null&&typeof P=="object"&&R.push({parsed:P,raw:O})}catch{}return R};return{append:v,drain:async S=>{if(c)return{uploadedBatches:0,uploadedEntries:0,remainingBatches:p().length,skipped:!0};c=!0;let R=0,T=0;try{f(),_(0);let O=a()-o;for(let P of p()){let A;try{A=w(P)}catch(Z){l("runner_diagnostics.spool_batch_unreadable",{file:P,error:Z instanceof Error?Z.message:String(Z)}),y(P,"unreadable");continue}let q=A.filter(Z=>{let H=d1e(Z.parsed);return H===void 0||H>=O});if(q.length===0){y(P,"empty_or_expired");continue}let E=RR(P,".jsonl"),N=q.map(Z=>Z.raw).join(`
|
|
1513
|
-
`),V=q.map(Z=>Z.parsed.spooled_at).filter(Z=>typeof Z=="string"),G={bundle_name:"runner-diagnostics-spool",exported_at:new Date(a()).toISOString(),idempotency_key:E,diagnostics:{kind:"runner_diagnostic_log",spool_batch:!0,idempotency_key:E,entry_count:q.length,...V.length===0?{}:{first_spooled_at:V[0],last_spooled_at:V[V.length-1]}},telemetry_ndjson:N};try{await S(G)}catch(Z){l("runner_diagnostics.spool_upload_failed",{file:P,remaining_batches:p().length,error:Z instanceof Error?Z.message:String(Z)});break}R+=1,T+=q.length;try{UJ(P)}catch(Z){l("runner_diagnostics.spool_delete_failed",{file:P,error:Z instanceof Error?Z.message:String(Z)})}}}catch(O){l("runner_diagnostics.spool_drain_failed",{error:O instanceof Error?O.message:String(O)})}finally{c=!1}return{uploadedBatches:R,uploadedEntries:T,remainingBatches:p().length,skipped:!1}},pendingBatchFiles:p}}var QEe,XEe,YEe,e1e,n1e,BJ,r1e,o1e,KJ=F(()=>{"use strict";jx();QEe=32*1024*1024,XEe=10080*60*1e3,YEe=4*1024*1024,e1e=1024*1024,n1e="spool.jsonl",BJ=/^batch-(\d{1,16})-[0-9a-f-]+\.jsonl$/;r1e=/\b([A-Z][A-Z0-9_]{1,})=("[^"\n]*"|'[^'\n]*'|[^\s"'`;,)\]}]+)/g,o1e=/(?:\/(?:[A-Za-z0-9._@~+-]|%[0-9A-Fa-f]{2})+){2,}/g});var Vt,DR,Sa=F(()=>{"use strict";Vt="1.0.
|
|
1513
|
+
`),V=q.map(Z=>Z.parsed.spooled_at).filter(Z=>typeof Z=="string"),G={bundle_name:"runner-diagnostics-spool",exported_at:new Date(a()).toISOString(),idempotency_key:E,diagnostics:{kind:"runner_diagnostic_log",spool_batch:!0,idempotency_key:E,entry_count:q.length,...V.length===0?{}:{first_spooled_at:V[0],last_spooled_at:V[V.length-1]}},telemetry_ndjson:N};try{await S(G)}catch(Z){l("runner_diagnostics.spool_upload_failed",{file:P,remaining_batches:p().length,error:Z instanceof Error?Z.message:String(Z)});break}R+=1,T+=q.length;try{UJ(P)}catch(Z){l("runner_diagnostics.spool_delete_failed",{file:P,error:Z instanceof Error?Z.message:String(Z)})}}}catch(O){l("runner_diagnostics.spool_drain_failed",{error:O instanceof Error?O.message:String(O)})}finally{c=!1}return{uploadedBatches:R,uploadedEntries:T,remainingBatches:p().length,skipped:!1}},pendingBatchFiles:p}}var QEe,XEe,YEe,e1e,n1e,BJ,r1e,o1e,KJ=F(()=>{"use strict";jx();QEe=32*1024*1024,XEe=10080*60*1e3,YEe=4*1024*1024,e1e=1024*1024,n1e="spool.jsonl",BJ=/^batch-(\d{1,16})-[0-9a-f-]+\.jsonl$/;r1e=/\b([A-Z][A-Z0-9_]{1,})=("[^"\n]*"|'[^'\n]*'|[^\s"'`;,)\]}]+)/g,o1e=/(?:\/(?:[A-Za-z0-9._@~+-]|%[0-9A-Fa-f]{2})+){2,}/g});var Vt,DR,Sa=F(()=>{"use strict";Vt="1.0.182",DR=`linzumi ${Vt}`});import{closeSync as WJ,existsSync as AR,mkdirSync as u1e,openSync as HJ,readFileSync as GJ,renameSync as c1e,unlinkSync as eu,writeFileSync as l1e,writeSync as ZJ}from"node:fs";import{dirname as QJ,join as p1e}from"node:path";function OR(e){return e instanceof Ds||e instanceof Error&&e.name===YJ&&"lockPath"in e&&"heldBy"in e}function $R(e,n=et(),t){let r=t===void 0?encodeURIComponent(e):Vd(t);return p1e(QJ(n),"runners",`${r}.lock`)}function Qb(e){let n=$R(e.machineId,e.configPath,e.linzumiUrl),t=e.isPidAlive??sK,r=e.now??(()=>new Date),o=e.killPid??C1e,i=r().toISOString(),s={version:1,machineId:e.machineId,runnerId:e.runnerId,pid:e.pid??process.pid,cwd:e.cwd,workspace:e.workspace,...e.linzumiUrl===void 0?{}:{linzumiUrl:zn(e.linzumiUrl)},...e.launchSource===void 0?{}:{launchSource:e.launchSource},startedAt:i,heartbeatAt:i,cliVersion:e.cliVersion??Vt,...e.gracefulUpdateDrain===!0?{gracefulUpdateDrain:!0}:{}};g1e(e.machineId,e.configPath,e.linzumiUrl,t,r,o,e.onTakeover),y1e(n,s,t,r,o,e.onTakeover,e.beforeReadExistingLock,e.beforeReplaceStaleLock);let a=()=>eK(n,s,r),d=setInterval(a,XJ);return d.unref(),{path:n,record:s,heartbeat:a,release:()=>{clearInterval(d),oK(n,s)}}}function eK(e,n,t){try{let r=Yb(e);if(r===void 0||r.machineId!==n.machineId||r.runnerId!==n.runnerId||r.pid!==n.pid||r.startedAt!==n.startedAt)return;let o={...r,heartbeatAt:t().toISOString()},i=`${e}.tmp`;l1e(i,`${JSON.stringify(o,null,2)}
|
|
1514
1514
|
`,"utf8"),c1e(i,e)}catch{}}function nu(e,n,t){if(!n(e.pid))return{state:"dead"};let r=e.heartbeatAt??e.startedAt,o=Date.parse(r);return Number.isNaN(o)||t().getTime()-o>f1e?{state:"wedged",reason:e.heartbeatAt===void 0?"missing_heartbeat":"stale_heartbeat"}:{state:"live"}}function nK(e,n,t,r){return t!==Xb||e.launchSource!==Xb?!1:r.state!=="live"?!0:m1e(n,e.cliVersion)>0}function m1e(e,n){let t=VJ(e),r=VJ(n);for(let o=0;o<3;o++){let i=t.core[o],s=r.core[o];if(i===void 0||s===void 0)throw new Error(`compareCliVersions: unexpected undefined at core index ${o}`);if(i!==s)return i>s?1:-1}return t.prerelease.length===0&&r.prerelease.length===0?0:t.prerelease.length===0?1:r.prerelease.length===0?-1:h1e(t.prerelease,r.prerelease)}function VJ(e){let n=e.trim().replace(/^v/i,"").split("+",1)[0]??"",t=n.indexOf("-"),r=t===-1?n:n.slice(0,t),o=t===-1?"":n.slice(t+1),i=r.split("."),s=[MR(i[0]),MR(i[1]),MR(i[2])],a=o===""?[]:o.split(".").filter(d=>d!=="");return{core:s,prerelease:a}}function MR(e){let n=Number.parseInt(e??"",10);return Number.isInteger(n)&&n>=0?n:0}function h1e(e,n){let t=Math.max(e.length,n.length);for(let r=0;r<t;r++){let o=e[r],i=n[r];if(o===void 0)return-1;if(i===void 0)return 1;let s=Number.parseInt(o,10),a=Number.parseInt(i,10),d=s.toString()===o,u=a.toString()===i;if(d&&u){if(s!==a)return s>a?1:-1}else{if(d!==u)return d?-1:1;if(o!==i)return o>i?1:-1}}return 0}function tK(e,n,t,r,o){try{r(n.pid)}catch(i){let s=i!==null&&typeof i=="object"&&"code"in i?i.code:void 0;if(s!=="ESRCH")throw s==="EPERM"||s==="EACCES"?new Error(`Cannot take over the runner lock at ${e}: its holder process (pid ${n.pid}) is owned by another user and cannot be stopped. Stop that process, or remove the lock file, then retry.`):i}o?.({lockPath:e,holderPid:n.pid,holderRunnerId:n.runnerId,reason:t})}function g1e(e,n,t,r,o,i,s){if(t===void 0||kr(t)!==kr(Xt))return;let a=$R(e,n),d=Yb(a);if(d!==void 0){if(nu(d,r,o).state==="live")throw new Ds(a,d);rK(a,r,()=>{let u=AR(a)?LR(a):void 0;if(u===void 0)return;let c=nu(u,r,o);if(c.state==="live")throw new Ds(a,u);c.state==="wedged"&&tK(a,u,c.reason,i,s),eu(a)})}}function y1e(e,n,t,r,o,i,s,a){if(Zb(e,n))return;s?.();let d=Yb(e);if(d===void 0){if(Zb(e,n))return;throw new Error(`another Linzumi runner lock appeared while starting: ${e}`)}if(nu(d,t,r).state==="live")throw new Ds(e,d);a?.(),rK(e,t,()=>{let u=AR(e)?LR(e):void 0;if(u!==void 0){let c=nu(u,t,r);if(c.state==="live")throw new Ds(e,u);c.state==="wedged"&&tK(e,u,c.reason,o,i),eu(e)}if(!Zb(e,n))throw new Error(`another Linzumi runner lock appeared while starting: ${e}`)})}function Zb(e,n){u1e(QJ(e),{recursive:!0});try{let t=HJ(e,"wx");try{ZJ(t,`${JSON.stringify(n,null,2)}
|
|
1515
1515
|
`)}finally{WJ(t)}return!0}catch(t){if(Rl(t,"EEXIST"))return!1;throw t}}function rK(e,n,t){let r=`${e}.replace`;for(;;)try{let o=HJ(r,"wx");try{ZJ(o,`${process.pid}
|
|
1516
1516
|
`),t()}finally{WJ(o),eu(r)}return}catch(o){if(Rl(o,"EEXIST")){let i=_1e(r);if(i===void 0)continue;if(n(i))throw new Error(["another Linzumi runner is already replacing a stale runner lock",`lock: ${e}`,"Wait for that startup to finish, then retry."].join(`
|
package/package.json
CHANGED
|
@@ -54,6 +54,7 @@ import {
|
|
|
54
54
|
fetchThreadTranscriptForRehydrationForTest,
|
|
55
55
|
resumeCodexThreadForReconnect,
|
|
56
56
|
} from './src/runner';
|
|
57
|
+
import { withCodexCompletionSnapshotRequestTimeout } from './src/channelSession';
|
|
57
58
|
|
|
58
59
|
// Scripted codex JSON-RPC request seam: replies are consumed in call
|
|
59
60
|
// order; every call is traced with its params. An exhausted script
|
|
@@ -179,6 +180,45 @@ async function runFetchTranscriptCase(input) {
|
|
|
179
180
|
return { trace };
|
|
180
181
|
}
|
|
181
182
|
|
|
183
|
+
// The completion-snapshot bound (channelSession.ts
|
|
184
|
+
// withCodexCompletionSnapshotRequestTimeout - the 2026-07-28 impl-res
|
|
185
|
+
// silent-wedge law): the REAL wrapper runs against a scripted request
|
|
186
|
+
// (result / rejection / never-settle hang). When the case carries an
|
|
187
|
+
// explicit boundMs, it is passed as the third argument (the non-positive
|
|
188
|
+
// unbounded guard); otherwise the wrapper resolves its bound through the
|
|
189
|
+
// SAME LINZUMI_CODEX_START_REQUEST_TIMEOUT_MS knob as the start bound
|
|
190
|
+
// (codexCompletionSnapshotRequestTimeoutMs delegates to it), set per case
|
|
191
|
+
// - a hang genuinely waits the (small) bound out.
|
|
192
|
+
async function runSnapshotTimeoutCase(input) {
|
|
193
|
+
process.env.LINZUMI_CODEX_START_REQUEST_TIMEOUT_MS = String(
|
|
194
|
+
input.timeoutMs
|
|
195
|
+
);
|
|
196
|
+
const trace = [];
|
|
197
|
+
const step = input.requestStep ?? {};
|
|
198
|
+
const request =
|
|
199
|
+
step.hang === true
|
|
200
|
+
? new Promise(() => {})
|
|
201
|
+
: step.reject !== undefined
|
|
202
|
+
? Promise.reject(new Error(step.reject))
|
|
203
|
+
: Promise.resolve({ result: step.result ?? {} });
|
|
204
|
+
const outcome = await (input.boundMs === undefined
|
|
205
|
+
? withCodexCompletionSnapshotRequestTimeout(input.method, request)
|
|
206
|
+
: withCodexCompletionSnapshotRequestTimeout(
|
|
207
|
+
input.method,
|
|
208
|
+
request,
|
|
209
|
+
input.boundMs
|
|
210
|
+
)
|
|
211
|
+
).then(
|
|
212
|
+
(value) => ({ ok: true, value }),
|
|
213
|
+
(error) => ({
|
|
214
|
+
ok: false,
|
|
215
|
+
message: error instanceof Error ? error.message : String(error),
|
|
216
|
+
})
|
|
217
|
+
);
|
|
218
|
+
trace.push({ t: 'outcome', outcome });
|
|
219
|
+
return { trace };
|
|
220
|
+
}
|
|
221
|
+
|
|
182
222
|
async function runCase(input) {
|
|
183
223
|
switch (input.kind) {
|
|
184
224
|
case 'resumeRun':
|
|
@@ -187,6 +227,8 @@ async function runCase(input) {
|
|
|
187
227
|
return runFetchMessagesCase(input);
|
|
188
228
|
case 'fetchTranscriptRun':
|
|
189
229
|
return runFetchTranscriptCase(input);
|
|
230
|
+
case 'snapshotTimeoutRun':
|
|
231
|
+
return runSnapshotTimeoutCase(input);
|
|
190
232
|
default:
|
|
191
233
|
return { error: 'unknown case kind ' + String(input.kind) };
|
|
192
234
|
}
|