@sleep2agi/agent-node 2.5.0-preview.162 → 2.5.0-preview.164
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/cli.js +3 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -317,14 +317,14 @@ ${A}`}function _y(A,Q,B,I,C){let{interactiveDashboardTask:E,messageType:g}=B,U=N
|
|
|
317
317
|
`));return B.name="CodexSdkUnavailable",B}function N9(A){if(!A)return"unknown";if(A instanceof Error)return A.message||A.name||"unknown Error";if(typeof A==="string")return A;try{return JSON.stringify(A).slice(0,240)}catch{return String(A)}}function EH(A){return/[^A-Za-z0-9_\-./@~]/.test(A)?`'${A.replace(/'/g,"'\\''")}'`:A}function JH(A){return async(Q,B)=>{let I=B.map(EH).join(" "),C=`npm install --no-save --prefix ${EH(Q)} ${I}`;A(C,{stdio:"pipe",timeout:90000})}}import{existsSync as l4A,readFileSync as p4A}from"node:fs";import{dirname as Pf,join as i4A,parse as d4A}from"node:path";var L$="@anthropic-ai/claude-agent-sdk",YH="@anthropic-ai/claude-agent-sdk-linux-x64",xf=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;function Sf(A,Q){try{let B=JSON.parse(Q(A));if(B?.name!==L$)return null;if(typeof B.version!=="string"||!xf.test(B.version))throw Error("installed Claude SDK package.json has an invalid exact version");return B.version}catch(B){if(String(B?.message||B).includes("invalid exact version"))throw B;return null}}function n4A(A={resolvePackage:(Q)=>S.resolve(Q)}){let Q=A.readText??((E)=>p4A(E,"utf8")),B=A.pathExists??l4A;try{let E=A.resolvePackage(`${L$}/package.json`),g=Sf(E,Q);if(g)return g}catch{}let I;try{I=Pf(A.resolvePackage(L$))}catch(E){throw Error(`cannot resolve installed ${L$}: ${E?.message||E}`)}let C=d4A(I).root;while(I!==C){let E=i4A(I,"package.json");if(B(E)){let g=Sf(E,Q);if(g)return g}I=Pf(I)}throw Error(`cannot attest installed ${L$} version`)}function o4A(A){if(!xf.test(A))throw Error("refusing non-exact Claude SDK native binary version");return`${YH}@${A}`}function kf(A){let Q=n4A(A),B=o4A(Q);return A.runNpm(["install","--no-save","--prefix",A.prefix,B]),{sdkVersion:Q,packageSpec:B}}async function vf(A,Q,B={}){let I=Math.max(1,Math.min(100,B.limit??100)),C=Math.max(1,Math.min(50,B.topN??10));try{let g=B.serverSupportsFromNodeId===!0&&!!A.nodeId?{from_node_id:A.nodeId,limit:I}:{from_name:A.alias,limit:I},U=await Q(g),J=Array.isArray(U?.tasks)?U.tasks:[],Y=(F)=>{let G=typeof F.from_node_id==="string"?F.from_node_id:"",$=typeof F.from_name==="string"?F.from_name:"";if(G&&A.nodeId)return G===A.nodeId;if($)return $===A.alias;return!1};return J.filter((F)=>!!F&&typeof F.task_id==="string"&&typeof F.to_name==="string"&&(F.status==="delivered"||F.status==="started")).filter(Y).slice(0,C)}catch{return[]}}function bf(A){if(!A.length)return null;return["【⚠ 节点 resume 提醒 — 你停机前已派出但仍在等回复的任务】","",A.map((B,I)=>{let C=String(B.task_id||"?").slice(0,8),E=String(B.to_name||"?"),g=B.created_at?`, sent ${B.created_at}`:"",U=a4A(B.content);return` ${I+1}. → ${E} [task ${C}${g}]: ${U}`}).join(`
|
|
318
318
|
`),"","重要约束 (do NOT re-dispatch):","- 上面这些任务 **已经发出去过**, 对方尚未回复。**不要再次** 用 commhub_send_task 发同样内容。",'- 如果需要跟进进度, 用 commhub_send_message(alias=对方, message="任务 <task_id> 进度?") 发一条**轻问询**, **不是** send_task。',"- server 端有自动去重护栏会拒绝重复 send_task, 但请不要靠它兜底 — 直接按上面规则处理。",'- 如果用户现在派的新任务跟上面某条**实质相同**, 直接告诉用户 "task <id> 已派给 <对方>, 仍在等回复, 不重新派", 不要 send_task。'].join(`
|
|
319
319
|
`)}function a4A(A){let Q=String(A??"").replace(/```/g,"ʼʼʼ").replace(/\s+/g," ").trim(),B=120;return Q.length>120?Q.slice(0,117)+"...":Q||"(empty content)"}class FH{opts;cachedAlias;cachedAt;fetchInFlight=null;cacheTtlMs;constructor(A){this.opts=A;this.cachedAlias=A.initialAlias,this.cachedAt=0,this.cacheTtlMs=A.cacheTtlMs??30000}current(){return this.cachedAlias}async refresh(A=Date.now()){if(!this.opts.nodeId)return this.cachedAlias;let Q=A-this.cachedAt;if(this.cacheTtlMs>0&&this.cachedAt>0&&Q>=0&&Q<this.cacheTtlMs)return this.cachedAlias;if(this.fetchInFlight)return this.fetchInFlight;let B=(async()=>{try{let I=await this.opts.fetchCanonicalAlias(this.opts.nodeId);if(I&&I.length>0&&I!==this.cachedAlias)this.opts.onDrift?.(this.cachedAlias,I,"fetch"),this.cachedAlias=I}catch(I){this.opts.warn?.(`currentAlias: fetch failed (${I?.message??I}); keeping cached value "${this.cachedAlias}"`)}finally{this.cachedAt=A,this.fetchInFlight=null}return this.cachedAlias})();return this.fetchInFlight=B,B}set(A,Q=Date.now()){if(!A)return;if(A!==this.cachedAlias)this.opts.onDrift?.(this.cachedAlias,A,"snapshot"),this.cachedAlias=A;this.cachedAt=Q}get nodeId(){return this.opts.nodeId}ageMs(A=Date.now()){if(this.cachedAt===0)return Number.POSITIVE_INFINITY;return Math.max(0,A-this.cachedAt)}isFresh(A=Date.now()){if(this.cachedAt===0)return!1;let Q=A-this.cachedAt;return Q>=0&&Q<this.cacheTtlMs}}function yf(A){let Q=A.fetchImpl??fetch,B=A.now??Date.now,I=A.timeoutMs??2500,C=A.probeTtlMs??600000,E=null,g=0;async function U(G,$){let D={Accept:"application/json"},N=$?A.token?.():void 0;if(N)D.Authorization=`Bearer ${N}`;let V=new AbortController,Z=setTimeout(()=>V.abort(),I);try{return await Q(G,{headers:D,signal:V.signal})}finally{clearTimeout(Z)}}async function J(){if(E!==null&&B()-g<C&&B()>=g)return E;g=B();try{let G=await U(`${A.hubUrl}/health`,!1),$=G.ok?await G.json():null;E=Array.isArray($?.capabilities)&&$.capabilities.includes("status_node_id")}catch{E=!1}return E}let Y=(G)=>{let $=[A.networkId?`network_id=${encodeURIComponent(A.networkId)}`:"",G].filter(Boolean).join("&");return`${A.hubUrl}/api/status${$?`?${$}`:""}`};async function F(G){let $=await U(Y(""),!0);if(!$.ok)return null;return(await $.json()).sessions?.find((N)=>N.node_id===G)?.alias??null}return async(G)=>{try{if(await J()){let $=await U(Y(`node_id=${encodeURIComponent(G)}&light=1`),!0);if($.ok){let D=(await $.json()).sessions;if(Array.isArray(D)){let N=D.find((V)=>V.node_id===G);if(N)return N.alias??null;if(D.length===0)return null;E=!1}}}return await F(G)}catch{return null}}}function ff(A,Q,B){if(!Array.isArray(A))return{exists:!1,reason:"no_sessions_field"};if(A.length===0)return{exists:!1,reason:"empty_sessions"};let I=(Q??"").trim(),C=(B??"").trim();if(!I)return{exists:!1,reason:"not_in_sessions"};let E=!1;for(let g of A){let U=typeof g?.alias==="string"?g.alias.trim():"";if(!U)continue;if(U===I){if(U===C){E=!0;continue}return{exists:!0,source:"session"}}}return{exists:!1,reason:E?"self_only":"not_in_sessions"}}function z$(A){return A==="host_supervisor"}function hf(A){return[`[${A}] 我是 daemon(host_supervisor 守护进程节点),不运行大模型。`,"我只执行结构化的节点生命周期命令:创建 / 停止 / 重启 / 删除 / 探测节点(由 Hub 下发的门铃事件驱动,全程无 AI)。","自由文本任务我不会调用 AI 去理解。需要 AI 协助,请把任务发给一个 agent 节点,或使用 anet CLI / 客户端里的 AI 助手。"].join(`
|
|
320
|
-
`)}import{join as GH}from"path";function $H(A){return[GH(A.projectCwd,".anet"),GH(A.userHome,".anet"),A.nodeConfigPath||"",GH(A.projectCwd,".mcp.json")]}function K$(A){if(!A)return!1;return/\b(429|529)\b|rate[_\s-]?limit|quota[_\s-]?(exceeded|exhaust)|overloaded(_error)?|too[_\s-]?many[_\s-]?requests|usage[_\s-]?limit|insufficient[_\s-]?quota|capacity[_\s-]?exceeded|token\s*plan.*(上限|exceeded)/i.test(A)}function DH(A){if(!A||typeof A!=="string")return null;let Q=A.match(/\b(2056)\b/);if(Q)return`MiniMax code ${Q[1]}`;let B=A.match(/\b(insufficient_quota|rate_limit_exceeded|billing_hard_limit_reached)\b/);if(B)return B[1];let I=A.match(/\b(429|529)\b/);if(I)return`HTTP ${I[1]}`;return null}function NH(A){if(!A||typeof A!=="string")return null;let Q=A.match(/已达到[^。\n]{2,140}/);if(Q)return Q[0].slice(0,200);let B=A.match(/(insufficient_quota|exceeded[^\n]{2,140})/i);if(B)return B[0].slice(0,200);return null}function yg(A){let Q=(A||"").toLowerCase();if(Q.includes("intern-ai.org.cn"))return"→ 检查 chat.intern-ai.org.cn 配额/Token Plan 上限/降并发";if(Q.includes("minimaxi")||Q.includes("minimax"))return"→ 检查 platform.minimaxi.com 配额/Token Plan 上限/降并发";if(Q.includes("deepseek"))return"→ 检查 platform.deepseek.com 配额/账户余额/降并发";if(Q.includes("anthropic"))return"→ 检查 console.anthropic.com 配额/usage limit/降并发";if(Q.includes("xiaomimimo")||Q.includes("mimo"))return"→ 检查 platform.xiaomimimo.com 配额/降并发";return"→ 检查 vendor 配额/限流 dashboard / 降并发"}function VH(A,Q){let B=Q?.baseUrl;if(A.errorMessage){if(K$(A.errorMessage))return{kind:"soft-fail-quota",reason:A.errorMessage,hint:yg(B)};return{kind:"error",reason:A.errorMessage}}let I=A.usage??{},C=I.input_tokens??null,E=I.output_tokens??null,g=A.totalCostUsd??null;if(C===0&&E===0&&g===0)return{kind:"soft-fail-empty",reason:"vendor returned in=0 out=0 cost=0 — upstream silent reject (suspect 429/quota/auth without explicit error)",hint:yg(B)};if(A.result===null||A.result===void 0||A.result==="")return{kind:"soft-fail-empty",reason:"empty vendor result despite success signal",hint:yg(B)};return{kind:"success"}}function Z9(A,Q){switch(A.kind){case"soft-fail-quota":{let B=A.reason||"",I=NH(B),C=DH(B),E=C?` [${C}]`:"",g=I??B.slice(0,80);return`[额度用尽]${E} ${g}`.trim()}case"soft-fail-empty":return"抱歉,本轮暂时没能给出答复,请再问我一次。";case"error":return"请求出错,请稍后重试。";case"success":return""}}function ZH(A,Q){let B=Q.usage?.input_tokens??0,I=Q.usage?.output_tokens??0;switch(A.kind){case"soft-fail-quota":{let C=A.reason||"",E=NH(C),g=DH(C),U=g?` [${g}]`:"",J=E??C.slice(0,80);return`执行出错: [额度用尽]${U} ${Q.runtime}: ${J}${A.hint?` — ${A.hint}`:""}`}case"soft-fail-empty":return`执行出错: ${Q.runtime} 返回空响应 (in=${B} out=${I}). `+"可能原因: (a) vendor 内容过滤 (请求含 credential 字面, 见 [outbound-mask] 日志) "+"(b) 静默限流/配额撞顶 (查 vendor dashboard 用量) "+"(c) 模型仅生成 reasoning/thinking 无 text (加大 max_tokens 或换 prompt). "+`${A.hint||""}`.trim();case"error":return`执行出错: ${Q.runtime} — ${(A.reason||"未知错误").slice(0,200)}`;case"success":return""}}function mf(A,Q){if(!Q)return A;if(Q.kind==="success")return"success";return`${A}→rejected:${Q.kind}`}function uf(A,Q){let B=typeof A.model==="string"?A.model.trim():"";if(!B)return null;if(A.session_id&&A.session_id===Q)return null;return`[claude] model in use: ${B}`}function cf(){let A=null;return{push(Q,B){let I=A;return A=B?Q:null,I},pendingEmpty(){return A}}}function lf(A,Q,B){if(typeof A!=="number"||!Number.isFinite(A))return"$?";let I;if(typeof Q==="number"&&Number.isFinite(Q)&&A>=Q)I=A-Q;else if(!B||typeof Q==="number"&&A<Q)I=A;return`$${I===void 0?"?":I.toFixed(4)} (session $${A.toFixed(4)})`}KX();var r4A=(A)=>new Promise((Q)=>setTimeout(Q,Math.max(0,A)));async function WH(A){let Q=A.baseDelayMs??1000,B=A.maxDelayMs??30000,I=A.jitterRatio??0.25,C=A.abandonAfterMs??Number.POSITIVE_INFINITY,E=A.sleep??r4A,g=A.random??Math.random,U=A.now??Date.now,J=Q,Y=null;while(!A.shutdownGate()){let F=!1,G=0,$={deferNextAttempt(V){G=Number.isFinite(V)&&V>0?V:0},markStable(){if(F)return;F=!0,J=Q,Y=null}};try{await A.runOnce($)}catch(V){A.onError?.(V)}if(A.shutdownGate())break;if(!F){if(Y===null)Y=U();if(U()-Y>C){A.onAbandon?.();return}}let D=I>0?J*I*(g()*2-1):0,N=Math.max(100,Math.round(J+D),G);A.onRetryWait?.(N,J),await E(N),J=Math.min(J*2,B)}}import{randomUUID as s4A}from"node:crypto";var t4A="node_connection_superseded",e4A="superseded_by_new_connection",A1A="replaced_by_reconnect",Q1A="X-Anet-Instance-Id",B1A=/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;function pf(A=s4A){let Q=`an-${A()}`;if(!B1A.test(Q))throw Error(`generated instance id does not match the Hub's format: ${Q}`);return Q}function df(A,Q){let B={Accept:"text/event-stream","Cache-Control":"no-cache",[Q1A]:Q};if(A)B.Authorization=`Bearer ${A}`;return B}function nf(A){if(!A||typeof A!=="object")return null;let Q=A;if(Q.type!==t4A)return null;let B=Q.by&&typeof Q.by==="object"?Q.by:{},I=(C)=>typeof C==="string"&&C?C:null;return{reason:I(Q.reason)??e4A,instanceMatch:I(Q.instance_match),byInstanceId:I(B.instance_id),byRemote:I(B.remote)}}var I1A=30000,XH=600000;class MH{baseMs;maxMs;streakResetMs;streak=0;connectedAt=null;suspended=!1;constructor(A={}){this.baseMs=A.baseMs??I1A,this.maxMs=A.maxMs??XH,this.streakResetMs=A.streakResetMs??XH}noteConnected(A){this.connectedAt=A,this.suspended=!1}onSuperseded(A,Q){if(A.reason===A1A)return{kind:"reconnect"};if(this.connectedAt!==null&&Q-this.connectedAt>=this.streakResetMs)this.streak=0;return this.streak+=1,this.connectedAt=null,this.suspended=!0,{kind:"back_off",waitMs:Math.min(this.baseMs*2**(this.streak-1),this.maxMs),streak:this.streak}}get inboxSuspended(){return this.suspended}get supersededStreak(){return this.streak}}function of(A,Q,B,I,C){let E=B.byRemote?` from ${B.byRemote}`:"",g=B.byInstanceId?` (instance ${B.byInstanceId})`:" (instance id not reported — older agent-node?)";return`[node-identity] another copy of node "${A}" is running and took this node's Hub stream${E}${g}; this copy is instance ${Q}. Two processes share one node identity (copied node directory?) — `+`stop one of them. This copy stops taking inbox work and reconnects in ${Math.round(I/1000)}s (superseded ${C}x in a row, backoff capped at ${Math.round(XH/60000)} min).`}z0();S$();K0();import{lstatSync as pC,readFileSync as SH,readdirSync as jh,realpathSync as _h}from"node:fs";import{isAbsolute as k1A,join as YY,relative as v1A,sep as b1A}from"node:path";var w9=32,y1A=400,f1A=4,h1A=new Set(["node_modules",".git",".hg",".svn","dist","build",".cache","coverage","target","vendor"]);function PH(A,Q){let B=v1A(Q,A);return B===""||!k1A(B)&&B!==".."&&!B.startsWith(`..${b1A}`)}function m1A(A,Q){return Q==="linux"&&A.role==="host_supervisor"&&A.uid>=0&&A.daemonEnv.ANET_NODE_MARKER===void 0&&A.adoptRoots.length>0&&A.adoptRoots.every((B)=>typeof B==="string"&&B.startsWith("/"))}function u1A(A){try{let Q=uC(A),B=new Set,I=new Set;for(let[C,E]of Object.entries(Q))if(B.add(C),E&&typeof E==="object"&&typeof E.node_id==="string")I.add(E.node_id);return{aliases:B,nodeIds:I}}catch{return null}}function c1A(A){try{return SH(`/proc/${A}/environ`,"utf8")}catch{return null}}function l1A(A,Q,B){let I=YY(A,".pid");try{let C=pC(I);if(!C.isFile()||C.isSymbolicLink()||C.uid!==Q||C.mode&18)return"unverified";let E=SH(I,"utf8").trim();if(!/^\d+$/.test(E)||Number(E)<=1)return"unverified";let g=B(Number(E));if(g==null)return"unverified";return g.split("\x00").some((U)=>U.startsWith("TMUX="))?"tmux":"bare"}catch(C){return C?.code==="ENOENT"?"stopped":"unverified"}}function p1A(A){let Q=A.runtime;return typeof Q==="string"&&Q.length>0&&Q.length<=64&&/^[A-Za-z0-9._-]+$/.test(Q)?Q:null}function i1A(A){let Q=A.platform??process.platform;if(!m1A(A,Q))return;let B=u1A(A.workDir);if(!B)return;let I=A.readEnviron??c1A,C=A.maxVisits??y1A,E=A.maxDepth??f1A,g=[];for(let $ of A.adoptRoots)try{let D=pC($);if(D.isSymbolicLink()||!D.isDirectory())continue;let N=_h($);if(!g.some((V)=>PH(N,V)||PH(V,N)))g.push(N)}catch{}let U=[],J=new Set,Y=0,F=($)=>{let D=YY($,".anet"),N;try{N=pC(D)}catch{return!1}if(N.isSymbolicLink()||!N.isDirectory())return!1;let V=YY(D,"nodes"),Z=[];try{if(pC(V).isSymbolicLink()||!pC(V).isDirectory())return!0;Z=jh(V).sort()}catch{return!0}for(let W of Z){if(U.length>=w9)break;let X=YY(V,W),L=YY(X,"config.json"),M;try{if(pC(X).isSymbolicLink()||!pC(X).isDirectory())continue;if(pC(L).isSymbolicLink())continue;M=JSON.parse(SH(L,"utf8"))}catch{continue}if(!M||typeof M!=="object"||Array.isArray(M))continue;let z=typeof M.alias==="string"?M.alias:M.node_name;if(typeof M.node_id!=="string"||typeof z!=="string"||typeof M.network_id!=="string")continue;if(B.aliases.has(z)||B.nodeIds.has(M.node_id))continue;try{let K=lC({node_id:M.node_id,alias:z,network_id:M.network_id,workdir:$},{home:A.home,hubUrl:A.hubUrl,networkId:A.networkId,adoptRoots:A.adoptRoots,uid:A.uid,daemonEnv:A.daemonEnv}),_=`${K.nodeId}\x00${K.workdir}`;if(J.has(_))continue;J.add(_),U.push({node_id:K.nodeId,alias:K.alias,workdir:K.workdir,runtime:p1A(K.config),launch_hint:l1A(K.nodeDir,A.uid,I)})}catch{}}return!0},G=($,D)=>{if(U.length>=w9||Y>=C||D>E)return;let N;try{if(pC($).isSymbolicLink()||!pC($).isDirectory())return;N=_h($)}catch{return}if(!g.some((Z)=>PH(N,Z)))return;if(Y++,F($))return;if(D===E)return;let V=[];try{V=jh($).sort()}catch{return}for(let Z of V){if(U.length>=w9||Y>=C)return;if(h1A.has(Z))continue;G(YY($,Z),D+1)}};for(let $ of g)G($,0);return U.sort(($,D)=>$.alias.localeCompare(D.alias)||$.node_id.localeCompare(D.node_id)||$.workdir.localeCompare(D.workdir)),U.slice(0,w9)}function Rh(A,Q){if(!Array.isArray(Q))return A;let B=A.daemon_capabilities??{};return{...A,daemon_capabilities:{...B,adoption_candidates:Q}}}var JY;function wh(A,Q,B,I=Date.now()){let C=Array.isArray(A?.adopt_roots)?A.adopt_roots:[],E=JSON.stringify([process.cwd(),Q,B,process.env.HOME||"",A?.role??null,C]);if(JY&&JY.key===E&&I-JY.at<60000&&I>=JY.at)return JY.value;let g=i1A({workDir:process.cwd(),home:process.env.HOME||"",hubUrl:Q,networkId:B,uid:process.getuid?.()??-1,daemonEnv:process.env,adoptRoots:C,role:A?.role});return JY={key:E,at:I,value:g},g}function qh(A){if(A.role!=="host_supervisor")return;let Q=A.now(),B=A.probe();if(B.state==="ready"){if(A.logState.last!=="ready")A.log("[anet-daemon] #1545 create capability: ready (anet bin pin verified)"),A.logState.last="ready";return{ok:!0,probedAtMs:Q}}if(A.logState.last!==B.code)A.log(`[anet-daemon] #1545 create capability blocked: ${B.code} — ${B.detail}`),A.logState.last=B.code;return{ok:!1,reason:B.code,probedAtMs:Q}}H0();BB();var gj="gpt-5.6-sol";function bY(A){return A||"gpt-5.6-sol"}_$();var SXA="never",xXA="danger-full-access";function _V(A,Q){let B=A&&typeof A==="object"?A:{};return{skipGitRepoCheck:B.skipGitRepoCheck===!1?!1:!0,approvalPolicy:typeof B.approvalPolicy==="string"?B.approvalPolicy:SXA,model:Q,sandboxMode:typeof B.sandboxMode==="string"?B.sandboxMode:xXA,modelReasoningEffort:H$(B.modelReasoningEffort)?B.modelReasoningEffort:"low"}}function ic(A,Q,B){return A.startThread(_V(Q,B))}var kXA="on-request";function dc(A,Q){let B=A&&typeof A==="object"?A:{},I={model:Q,approvalPolicy:typeof B.approvalPolicy==="string"?B.approvalPolicy:kXA};if(typeof B.sandboxMode==="string")I.sandbox=B.sandboxMode;return I}function vXA(A,Q,B){return{threadId:B,...dc(A,Q)}}function bXA(A){return/no rollout found for thread id|invalid (thread|session) id/i.test(A)}function pc(A){let Q=A.cause.replace(/\s+/g," ").trim().slice(0,200),B=A.configPath?`remove "session" from ${A.configPath}`:'remove "session" from the node config';if(bXA(A.cause))return`recorded codex thread ${A.threadId} cannot be resumed (${Q}) — refusing to start a fresh thread in its place. `+`Pick another: anet resume ${A.alias} --pick · or start fresh on purpose: ${B} and restart the node`;return`codex thread/resume of recorded thread ${A.threadId} failed (${Q}) — not starting a fresh thread; `+"resend the task, and if it repeats check the agent-node log [codex-stdio] lines"}class Uj extends Error{code="codex_stdio_resume_failed";constructor(A){super(A);this.name="CodexStdioResumeError"}}var yXA=60000;async function nc(A,Q){let B=Q.recordedThreadId||"";if(B){let C;try{C=await A.request("thread/resume",vXA(Q.flags,Q.model,B),yXA)}catch(g){let U=g instanceof Error?g.message:String(g);throw new Uj(pc({alias:Q.alias,threadId:B,cause:U,configPath:Q.configPath}))}let E=C?.thread?.id;if(E!==B)throw new Uj(pc({alias:Q.alias,threadId:B,cause:`app-server answered with thread ${typeof E==="string"?E:"(none)"}`,configPath:Q.configPath}));return{threadId:B,resumed:!0}}return{threadId:(await A.request("thread/start",dc(Q.flags,Q.model))).thread.id,resumed:!1}}var fXA=1e4;function hXA(A){let Q=A&&typeof A==="object"?A:{};if(Q.willRetry===!0)return null;let B=Q.error?.message;return typeof B==="string"&&B.trim()?B:"codex reported an error without a message"}function mXA(A,Q){let B=A?.error?.message;if(typeof B==="string"&&B.trim())return B;if(Q)return Q;if(A?.status==="failed")return"Codex turn failed without an error message";if(A?.status==="interrupted")return"Codex turn was interrupted without an error message";return null}class Jj extends Error{upstream;turnId;code="codex_stdio_turn_failed";constructor(A,Q){super(`codex turn failed: ${A.replace(/\s+/g," ").trim().slice(0,500)}`);this.upstream=A;this.turnId=Q;this.name="CodexStdioTurnError"}}class RV extends Error{timeoutMs;interrupted;code="codex_stdio_turn_timeout";constructor(A,Q,B){super(A);this.timeoutMs=Q;this.interrupted=B;this.name="CodexStdioTurnTimeoutError"}}function oc(A,Q){let B=Q.now??Date.now,I=Q.log??(()=>{}),C=null,E="",g=0,U=null,J=0,Y=B(),F=!1,G,$,D,N=new Promise((X,L)=>{$=X,D=L});N.catch(()=>{});let V=(X)=>{let L=X?.turn?.id??X?.turnId??null;return Boolean(C&&L&&L!==C)},Z=()=>{if(F=!0,G)clearTimeout(G);A.off("notification",W)};function W(X){if(F)return;let L=X?.params;if(V(L))return;if(J++,Y=B(),X.method==="item/completed"){let M=L?.item;if(!M)return;if(g++,M.type==="agentMessage"&&typeof M.text==="string")E=M.text}else if(X.method==="error"){let M=hXA(L);if(M)U=M,I(`[codex-stdio] ✗ codex error: ${M.replace(/\s+/g," ").slice(0,300)}`);else I(`[codex-stdio] codex error (willRetry): ${String(L?.error?.message??"").slice(0,200)}`)}else if(X.method==="turn/completed"){Z();let M=L?.turn?.id??L?.turnId??C??"";$({turnId:M,finalText:E,itemCount:g,status:typeof L?.turn?.status==="string"?L.turn.status:void 0,failure:mXA(L?.turn,U)})}}if(A.on("notification",W),Q.timeoutMs>0)G=setTimeout(async()=>{if(F)return;Z();let X=B()-Y,L=$9(J,X),M=U?`;codex 最后报错: ${U.replace(/\s+/g," ").slice(0,200)}`:"",z=!1,K;if(!C)K="turn/start 尚未返回 turn id,无法 turn/interrupt";else try{await A.request("turn/interrupt",{threadId:Q.threadId,turnId:C},fXA),z=!0,K=`已用 turn/interrupt 中止 turn ${C}`}catch(_){K=`turn/interrupt 失败(${(_ instanceof Error?_.message:String(_)).replace(/\s+/g," ").slice(0,160)})`}I(`[codex-stdio] ✗ turn timed out after ${Q.timeoutMs}ms; ${L}; ${K}`),D(new RV(`codex-stdio 调用超时 (${Math.round(Q.timeoutMs/1000)}s) — ${L}${M};${K}。`+"确切原因见节点日志里 [codex-stdio] 开头那几行。",Q.timeoutMs,z))},Q.timeoutMs);return{setTurnId(X){if(X)C=X},done:N,cancel(){if(!F)Z()},fail(X){if(F)return;Z(),D(X)}}}function ac(A){let Q=A.parsedAccess?.allowFrom,B=uXA({channel:"telegram",channelDir:A.channelDir,allowFrom:Q});return{allowFromRaw:Q,bootWarn:B}}function rc(A){if(Array.isArray(A))return{list:A.filter((B)=>typeof B==="string"&&B.length>0).map((B)=>String(B)),malformed:!1};if(A===void 0||A===null)return{list:[],malformed:!1};return{list:[],malformed:!0}}function sc(A){let{list:Q,malformed:B}=rc(A.allowFrom);if(Q.length===0)return{allow:!1,kind:"empty-fail-closed",reason:B?"allowFrom malformed (not a string[]) — fail-closed":'allowFrom empty — fail-closed (set ["*"] to open to all, or add specific ids)'};if(Q.includes("*"))return{allow:!0,kind:"wildcard-allow",reason:'allowFrom=["*"]'};let I=A.senderId||"",C=(A.senderUsername||"").trim();if(I&&Q.includes(I))return{allow:!0,kind:"explicit-allow",reason:`sender id ${I} in allowFrom`};if(C&&Q.includes(C))return{allow:!0,kind:"explicit-allow",reason:`sender username ${C} in allowFrom`};return{allow:!1,kind:"denied",reason:`sender id=${I} username=${C||"(none)"} not in allowFrom`}}function uXA(A){let{list:Q,malformed:B}=rc(A.allowFrom);if(Q.length>0)return null;let I=B?"malformed (not a string[])":"empty";return`[${A.channel}] FAIL-CLOSED: ${A.channelDir}/access.json allowFrom is ${I} — `+'ALL inbound messages will be denied. To open the channel: edit access.json and set `"allowFrom": ["*"]` for any-sender, or add specific sender ids. Pre-v0.11 behaviour was fail-open; this is a deliberate security change (see release notes).'}UQ();import{randomBytes as cXA}from"crypto";import{closeSync as EU,constants as OB,fchmodSync as lXA,fstatSync as YD,fsyncSync as tc,lstatSync as yY,openSync as fY,readFileSync as ec,realpathSync as Yj,rmSync as pXA,writeFileSync as iXA}from"fs";import{basename as dXA,dirname as Fj,resolve as nXA}from"path";class TB extends Error{}function rC(A,Q){return A.dev===Q.dev&&A.ino===Q.ino}function Al(A){try{return yY(A)}catch(Q){if(Q?.code==="ENOENT")return;throw Q}}function qV(A,Q){let B=nXA(A),I=yY(B);if(I.isSymbolicLink()||!I.isDirectory()||Yj(B)!==B)throw new TB(`OpenCode state refuses ${Q} at ${B}: expected a canonical real directory`);let C;try{C=fY(B,OB.O_RDONLY|(OB.O_DIRECTORY||0)|(OB.O_NOFOLLOW||0));let E=YD(C),g=yY(B),U=process.getuid?.();if(!E.isDirectory()||g.isSymbolicLink()||!rC(I,E)||!rC(E,g)||Yj(B)!==B)throw new TB(`OpenCode state refuses ${Q} at ${B}: directory identity changed`);if(U===void 0||E.uid!==U||(E.mode&511)!==448)throw new TB(`OpenCode state refuses ${Q} at ${B}: owner/mode must be current uid/0700`);return E}finally{if(C!==void 0)EU(C)}}function wV(A,Q,B=!1){let I=Al(A);if(!I){if(B)return;throw new TB(`OpenCode state refuses ${Q} at ${A}: file is missing`)}if(I.isSymbolicLink()||!I.isFile()||I.nlink!==1||Yj(A)!==A)throw new TB(`OpenCode state refuses ${Q} at ${A}: expected a canonical single-link regular file`);let C;try{C=fY(A,OB.O_RDONLY|(OB.O_NOFOLLOW||0));let E=YD(C),g=yY(A),U=process.getuid?.();if(!E.isFile()||E.nlink!==1||g.isSymbolicLink()||!rC(I,E)||!rC(E,g))throw new TB(`OpenCode state refuses ${Q} at ${A}: file identity changed`);if(U===void 0||E.uid!==U||(E.mode&511)!==384)throw new TB(`OpenCode state refuses ${Q} at ${A}: owner/mode must be current uid/0600`);return E}catch(E){if(E?.code==="ELOOP")throw new TB(`OpenCode state refuses ${Q} at ${A}: symlinks are not allowed`);throw E}finally{if(C!==void 0)EU(C)}}function gU(A,Q){qV(Fj(A),`${Q} parent`);let B=wV(A,Q),I=fY(A,OB.O_RDONLY|(OB.O_NOFOLLOW||0));try{let C=YD(I),E=yY(A);if(!C.isFile()||C.nlink!==1||!rC(B,C)||!rC(C,E))throw new TB(`OpenCode state refuses ${Q} at ${A}: file changed before read`);return{body:ec(I,"utf8"),stat:C}}finally{EU(I)}}function FD(A,Q,B,I){let C=Fj(A);qV(C,`${B} parent`);let E=wV(A,B,!0);if(I&&(!E||!rC(I,E)))throw new TB(`OpenCode state refuses ${B} at ${A}: target changed after read`);let g=`${C}/.${dXA(A)}.${cXA(12).toString("hex")}.tmp`,U;try{U=fY(g,OB.O_WRONLY|OB.O_CREAT|OB.O_EXCL|(OB.O_NOFOLLOW||0),384),iXA(U,Q,"utf8"),lXA(U,384),tc(U);let J=YD(U),Y=process.getuid?.();if(!J.isFile()||J.nlink!==1||Y===void 0||J.uid!==Y)throw new TB(`OpenCode state refuses ${B}: temporary file is not owner-controlled`);EU(U),U=void 0,qV(C,`${B} parent`);let F=wV(A,B,!0);if(E===void 0!==(F===void 0)||E&&F&&!rC(E,F))throw new TB(`OpenCode state refuses ${B} at ${A}: target changed before atomic rename`);GA(g,A),wV(A,B);let G=fY(C,OB.O_RDONLY|(OB.O_DIRECTORY||0)|(OB.O_NOFOLLOW||0));try{tc(G)}finally{EU(G)}}catch(J){if(U!==void 0)try{EU(U)}catch{}throw pXA(g,{force:!0}),J}}function Ql(A){for(let Q of[A,`${A}.prev`]){let B=Al(Q);if(!B)continue;if(B.isSymbolicLink()||!B.isFile()||B.nlink!==1)throw new TB(`config state refuses ${Q}: symlinks, hardlinks, and non-files are not allowed`);let I=fY(Q,OB.O_RDONLY|(OB.O_NOFOLLOW||0));try{let C=YD(I),E=yY(Q);if(!C.isFile()||C.nlink!==1||!rC(B,C)||!rC(C,E))throw new TB(`config state refuses ${Q}: identity changed`);try{let g=JSON.parse(ec(I,"utf8"));if(g?.runtime==="opencode-cli"||g?.runtime==="opencode")return!0}catch{}}finally{EU(I)}}return!1}function Bl(A){qV(Fj(A),"node workDir");let Q,B;try{return Q=gU(A,"config.json"),{config:JSON.parse(Q.body),source:"primary"}}catch(E){if(E instanceof TB)throw E;B=String(E?.message||E)}let I;try{I=gU(`${A}.prev`,"config.json.prev")}catch(E){throw Error(`OpenCode config parse failed (${B}) and no safe .prev backup exists: ${E?.message||E}`)}let C;try{C=JSON.parse(I.body)}catch(E){throw Error(`OpenCode config parse failed (${B}); safe .prev parse also failed (${E?.message||E})`)}return FD(A,JSON.stringify(C,null,2)+`
|
|
320
|
+
`)}import{join as GH}from"path";function $H(A){return[GH(A.projectCwd,".anet"),GH(A.userHome,".anet"),A.nodeConfigPath||"",GH(A.projectCwd,".mcp.json")]}function K$(A){if(!A)return!1;return/\b(429|529)\b|rate[_\s-]?limit|quota[_\s-]?(exceeded|exhaust)|overloaded(_error)?|too[_\s-]?many[_\s-]?requests|usage[_\s-]?limit|insufficient[_\s-]?quota|capacity[_\s-]?exceeded|token\s*plan.*(上限|exceeded)/i.test(A)}function DH(A){if(!A||typeof A!=="string")return null;let Q=A.match(/\b(2056)\b/);if(Q)return`MiniMax code ${Q[1]}`;let B=A.match(/\b(insufficient_quota|rate_limit_exceeded|billing_hard_limit_reached)\b/);if(B)return B[1];let I=A.match(/\b(429|529)\b/);if(I)return`HTTP ${I[1]}`;return null}function NH(A){if(!A||typeof A!=="string")return null;let Q=A.match(/已达到[^。\n]{2,140}/);if(Q)return Q[0].slice(0,200);let B=A.match(/(insufficient_quota|exceeded[^\n]{2,140})/i);if(B)return B[0].slice(0,200);return null}function yg(A){let Q=(A||"").toLowerCase();if(Q.includes("intern-ai.org.cn"))return"→ 检查 chat.intern-ai.org.cn 配额/Token Plan 上限/降并发";if(Q.includes("minimaxi")||Q.includes("minimax"))return"→ 检查 platform.minimaxi.com 配额/Token Plan 上限/降并发";if(Q.includes("deepseek"))return"→ 检查 platform.deepseek.com 配额/账户余额/降并发";if(Q.includes("anthropic"))return"→ 检查 console.anthropic.com 配额/usage limit/降并发";if(Q.includes("xiaomimimo")||Q.includes("mimo"))return"→ 检查 platform.xiaomimimo.com 配额/降并发";return"→ 检查 vendor 配额/限流 dashboard / 降并发"}function VH(A,Q){let B=Q?.baseUrl;if(A.errorMessage){if(K$(A.errorMessage))return{kind:"soft-fail-quota",reason:A.errorMessage,hint:yg(B)};return{kind:"error",reason:A.errorMessage}}let I=A.usage??{},C=I.input_tokens??null,E=I.output_tokens??null,g=A.totalCostUsd??null;if(C===0&&E===0&&g===0)return{kind:"soft-fail-empty",reason:"vendor returned in=0 out=0 cost=0 — upstream silent reject (suspect 429/quota/auth without explicit error)",hint:yg(B)};if(A.result===null||A.result===void 0||A.result==="")return{kind:"soft-fail-empty",reason:"empty vendor result despite success signal",hint:yg(B)};return{kind:"success"}}function Z9(A,Q){switch(A.kind){case"soft-fail-quota":{let B=A.reason||"",I=NH(B),C=DH(B),E=C?` [${C}]`:"",g=I??B.slice(0,80);return`[额度用尽]${E} ${g}`.trim()}case"soft-fail-empty":return"抱歉,本轮暂时没能给出答复,请再问我一次。";case"error":return"请求出错,请稍后重试。";case"success":return""}}function ZH(A,Q){let B=Q.usage?.input_tokens??0,I=Q.usage?.output_tokens??0;switch(A.kind){case"soft-fail-quota":{let C=A.reason||"",E=NH(C),g=DH(C),U=g?` [${g}]`:"",J=E??C.slice(0,80);return`执行出错: [额度用尽]${U} ${Q.runtime}: ${J}${A.hint?` — ${A.hint}`:""}`}case"soft-fail-empty":return`执行出错: ${Q.runtime} 返回空响应 (in=${B} out=${I}). `+"可能原因: (a) vendor 内容过滤 (请求含 credential 字面, 见 [outbound-mask] 日志) "+"(b) 静默限流/配额撞顶 (查 vendor dashboard 用量) "+"(c) 模型仅生成 reasoning/thinking 无 text (加大 max_tokens 或换 prompt). "+`${A.hint||""}`.trim();case"error":return`执行出错: ${Q.runtime} — ${(A.reason||"未知错误").slice(0,200)}`;case"success":return""}}function mf(A,Q){if(!Q)return A;if(Q.kind==="success")return"success";return`${A}→rejected:${Q.kind}`}function uf(A,Q){let B=typeof A.model==="string"?A.model.trim():"";if(!B)return null;if(A.session_id&&A.session_id===Q)return null;return`[claude] model in use: ${B}`}function cf(){let A=null;return{push(Q,B){let I=A;return A=B?Q:null,I},pendingEmpty(){return A}}}function lf(A,Q,B){if(typeof A!=="number"||!Number.isFinite(A))return"$?";let I;if(typeof Q==="number"&&Number.isFinite(Q)&&A>=Q)I=A-Q;else if(!B||typeof Q==="number"&&A<Q)I=A;return`$${I===void 0?"?":I.toFixed(4)} (session $${A.toFixed(4)})`}KX();var r4A=(A)=>new Promise((Q)=>setTimeout(Q,Math.max(0,A)));async function WH(A){let Q=A.baseDelayMs??1000,B=A.maxDelayMs??30000,I=A.jitterRatio??0.25,C=A.firstRetrySpreadMs??0,E=A.abandonAfterMs??Number.POSITIVE_INFINITY,g=A.sleep??r4A,U=A.random??Math.random,J=A.now??Date.now,Y=Q,F=null;while(!A.shutdownGate()){let G=!1,$=0,D={deferNextAttempt(W){$=Number.isFinite(W)&&W>0?W:0},markStable(){if(G)return;G=!0,Y=Q,F=null}};try{await A.runOnce(D)}catch(W){A.onError?.(W)}if(A.shutdownGate())break;if(!G){if(F===null)F=J();if(J()-F>E){A.onAbandon?.();return}}let N=I>0?Y*I*(U()*2-1):0,V=C>0&&Y===Q?Math.floor(U()*C):0,Z=Math.max(100,Math.round(Y+N)+V,$);A.onRetryWait?.(Z,Y),await g(Z),Y=Math.min(Y*2,B)}}import{randomUUID as s4A}from"node:crypto";var t4A="node_connection_superseded",e4A="superseded_by_new_connection",A1A="replaced_by_reconnect",Q1A="X-Anet-Instance-Id",B1A=/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;function pf(A=s4A){let Q=`an-${A()}`;if(!B1A.test(Q))throw Error(`generated instance id does not match the Hub's format: ${Q}`);return Q}function df(A,Q){let B={Accept:"text/event-stream","Cache-Control":"no-cache",[Q1A]:Q};if(A)B.Authorization=`Bearer ${A}`;return B}function nf(A){if(!A||typeof A!=="object")return null;let Q=A;if(Q.type!==t4A)return null;let B=Q.by&&typeof Q.by==="object"?Q.by:{},I=(C)=>typeof C==="string"&&C?C:null;return{reason:I(Q.reason)??e4A,instanceMatch:I(Q.instance_match),byInstanceId:I(B.instance_id),byRemote:I(B.remote)}}var I1A=30000,XH=600000;class MH{baseMs;maxMs;streakResetMs;streak=0;connectedAt=null;suspended=!1;constructor(A={}){this.baseMs=A.baseMs??I1A,this.maxMs=A.maxMs??XH,this.streakResetMs=A.streakResetMs??XH}noteConnected(A){this.connectedAt=A,this.suspended=!1}onSuperseded(A,Q){if(A.reason===A1A)return{kind:"reconnect"};if(this.connectedAt!==null&&Q-this.connectedAt>=this.streakResetMs)this.streak=0;return this.streak+=1,this.connectedAt=null,this.suspended=!0,{kind:"back_off",waitMs:Math.min(this.baseMs*2**(this.streak-1),this.maxMs),streak:this.streak}}get inboxSuspended(){return this.suspended}get supersededStreak(){return this.streak}}function of(A,Q,B,I,C){let E=B.byRemote?` from ${B.byRemote}`:"",g=B.byInstanceId?` (instance ${B.byInstanceId})`:" (instance id not reported — older agent-node?)";return`[node-identity] another copy of node "${A}" is running and took this node's Hub stream${E}${g}; this copy is instance ${Q}. Two processes share one node identity (copied node directory?) — `+`stop one of them. This copy stops taking inbox work and reconnects in ${Math.round(I/1000)}s (superseded ${C}x in a row, backoff capped at ${Math.round(XH/60000)} min).`}z0();S$();K0();import{lstatSync as pC,readFileSync as SH,readdirSync as jh,realpathSync as _h}from"node:fs";import{isAbsolute as k1A,join as YY,relative as v1A,sep as b1A}from"node:path";var w9=32,y1A=400,f1A=4,h1A=new Set(["node_modules",".git",".hg",".svn","dist","build",".cache","coverage","target","vendor"]);function PH(A,Q){let B=v1A(Q,A);return B===""||!k1A(B)&&B!==".."&&!B.startsWith(`..${b1A}`)}function m1A(A,Q){return Q==="linux"&&A.role==="host_supervisor"&&A.uid>=0&&A.daemonEnv.ANET_NODE_MARKER===void 0&&A.adoptRoots.length>0&&A.adoptRoots.every((B)=>typeof B==="string"&&B.startsWith("/"))}function u1A(A){try{let Q=uC(A),B=new Set,I=new Set;for(let[C,E]of Object.entries(Q))if(B.add(C),E&&typeof E==="object"&&typeof E.node_id==="string")I.add(E.node_id);return{aliases:B,nodeIds:I}}catch{return null}}function c1A(A){try{return SH(`/proc/${A}/environ`,"utf8")}catch{return null}}function l1A(A,Q,B){let I=YY(A,".pid");try{let C=pC(I);if(!C.isFile()||C.isSymbolicLink()||C.uid!==Q||C.mode&18)return"unverified";let E=SH(I,"utf8").trim();if(!/^\d+$/.test(E)||Number(E)<=1)return"unverified";let g=B(Number(E));if(g==null)return"unverified";return g.split("\x00").some((U)=>U.startsWith("TMUX="))?"tmux":"bare"}catch(C){return C?.code==="ENOENT"?"stopped":"unverified"}}function p1A(A){let Q=A.runtime;return typeof Q==="string"&&Q.length>0&&Q.length<=64&&/^[A-Za-z0-9._-]+$/.test(Q)?Q:null}function i1A(A){let Q=A.platform??process.platform;if(!m1A(A,Q))return;let B=u1A(A.workDir);if(!B)return;let I=A.readEnviron??c1A,C=A.maxVisits??y1A,E=A.maxDepth??f1A,g=[];for(let $ of A.adoptRoots)try{let D=pC($);if(D.isSymbolicLink()||!D.isDirectory())continue;let N=_h($);if(!g.some((V)=>PH(N,V)||PH(V,N)))g.push(N)}catch{}let U=[],J=new Set,Y=0,F=($)=>{let D=YY($,".anet"),N;try{N=pC(D)}catch{return!1}if(N.isSymbolicLink()||!N.isDirectory())return!1;let V=YY(D,"nodes"),Z=[];try{if(pC(V).isSymbolicLink()||!pC(V).isDirectory())return!0;Z=jh(V).sort()}catch{return!0}for(let W of Z){if(U.length>=w9)break;let X=YY(V,W),L=YY(X,"config.json"),M;try{if(pC(X).isSymbolicLink()||!pC(X).isDirectory())continue;if(pC(L).isSymbolicLink())continue;M=JSON.parse(SH(L,"utf8"))}catch{continue}if(!M||typeof M!=="object"||Array.isArray(M))continue;let z=typeof M.alias==="string"?M.alias:M.node_name;if(typeof M.node_id!=="string"||typeof z!=="string"||typeof M.network_id!=="string")continue;if(B.aliases.has(z)||B.nodeIds.has(M.node_id))continue;try{let K=lC({node_id:M.node_id,alias:z,network_id:M.network_id,workdir:$},{home:A.home,hubUrl:A.hubUrl,networkId:A.networkId,adoptRoots:A.adoptRoots,uid:A.uid,daemonEnv:A.daemonEnv}),_=`${K.nodeId}\x00${K.workdir}`;if(J.has(_))continue;J.add(_),U.push({node_id:K.nodeId,alias:K.alias,workdir:K.workdir,runtime:p1A(K.config),launch_hint:l1A(K.nodeDir,A.uid,I)})}catch{}}return!0},G=($,D)=>{if(U.length>=w9||Y>=C||D>E)return;let N;try{if(pC($).isSymbolicLink()||!pC($).isDirectory())return;N=_h($)}catch{return}if(!g.some((Z)=>PH(N,Z)))return;if(Y++,F($))return;if(D===E)return;let V=[];try{V=jh($).sort()}catch{return}for(let Z of V){if(U.length>=w9||Y>=C)return;if(h1A.has(Z))continue;G(YY($,Z),D+1)}};for(let $ of g)G($,0);return U.sort(($,D)=>$.alias.localeCompare(D.alias)||$.node_id.localeCompare(D.node_id)||$.workdir.localeCompare(D.workdir)),U.slice(0,w9)}function Rh(A,Q){if(!Array.isArray(Q))return A;let B=A.daemon_capabilities??{};return{...A,daemon_capabilities:{...B,adoption_candidates:Q}}}var JY;function wh(A,Q,B,I=Date.now()){let C=Array.isArray(A?.adopt_roots)?A.adopt_roots:[],E=JSON.stringify([process.cwd(),Q,B,process.env.HOME||"",A?.role??null,C]);if(JY&&JY.key===E&&I-JY.at<60000&&I>=JY.at)return JY.value;let g=i1A({workDir:process.cwd(),home:process.env.HOME||"",hubUrl:Q,networkId:B,uid:process.getuid?.()??-1,daemonEnv:process.env,adoptRoots:C,role:A?.role});return JY={key:E,at:I,value:g},g}function qh(A){if(A.role!=="host_supervisor")return;let Q=A.now(),B=A.probe();if(B.state==="ready"){if(A.logState.last!=="ready")A.log("[anet-daemon] #1545 create capability: ready (anet bin pin verified)"),A.logState.last="ready";return{ok:!0,probedAtMs:Q}}if(A.logState.last!==B.code)A.log(`[anet-daemon] #1545 create capability blocked: ${B.code} — ${B.detail}`),A.logState.last=B.code;return{ok:!1,reason:B.code,probedAtMs:Q}}H0();BB();var gj="gpt-5.6-sol";function bY(A){return A||"gpt-5.6-sol"}_$();var SXA="never",xXA="danger-full-access";function _V(A,Q){let B=A&&typeof A==="object"?A:{};return{skipGitRepoCheck:B.skipGitRepoCheck===!1?!1:!0,approvalPolicy:typeof B.approvalPolicy==="string"?B.approvalPolicy:SXA,model:Q,sandboxMode:typeof B.sandboxMode==="string"?B.sandboxMode:xXA,modelReasoningEffort:H$(B.modelReasoningEffort)?B.modelReasoningEffort:"low"}}function ic(A,Q,B){return A.startThread(_V(Q,B))}var kXA="on-request";function dc(A,Q){let B=A&&typeof A==="object"?A:{},I={model:Q,approvalPolicy:typeof B.approvalPolicy==="string"?B.approvalPolicy:kXA};if(typeof B.sandboxMode==="string")I.sandbox=B.sandboxMode;return I}function vXA(A,Q,B){return{threadId:B,...dc(A,Q)}}function bXA(A){return/no rollout found for thread id|invalid (thread|session) id/i.test(A)}function pc(A){let Q=A.cause.replace(/\s+/g," ").trim().slice(0,200),B=A.configPath?`remove "session" from ${A.configPath}`:'remove "session" from the node config';if(bXA(A.cause))return`recorded codex thread ${A.threadId} cannot be resumed (${Q}) — refusing to start a fresh thread in its place. `+`Pick another: anet resume ${A.alias} --pick · or start fresh on purpose: ${B} and restart the node`;return`codex thread/resume of recorded thread ${A.threadId} failed (${Q}) — not starting a fresh thread; `+"resend the task, and if it repeats check the agent-node log [codex-stdio] lines"}class Uj extends Error{code="codex_stdio_resume_failed";constructor(A){super(A);this.name="CodexStdioResumeError"}}var yXA=60000;async function nc(A,Q){let B=Q.recordedThreadId||"";if(B){let C;try{C=await A.request("thread/resume",vXA(Q.flags,Q.model,B),yXA)}catch(g){let U=g instanceof Error?g.message:String(g);throw new Uj(pc({alias:Q.alias,threadId:B,cause:U,configPath:Q.configPath}))}let E=C?.thread?.id;if(E!==B)throw new Uj(pc({alias:Q.alias,threadId:B,cause:`app-server answered with thread ${typeof E==="string"?E:"(none)"}`,configPath:Q.configPath}));return{threadId:B,resumed:!0}}return{threadId:(await A.request("thread/start",dc(Q.flags,Q.model))).thread.id,resumed:!1}}var fXA=1e4;function hXA(A){let Q=A&&typeof A==="object"?A:{};if(Q.willRetry===!0)return null;let B=Q.error?.message;return typeof B==="string"&&B.trim()?B:"codex reported an error without a message"}function mXA(A,Q){let B=A?.error?.message;if(typeof B==="string"&&B.trim())return B;if(Q)return Q;if(A?.status==="failed")return"Codex turn failed without an error message";if(A?.status==="interrupted")return"Codex turn was interrupted without an error message";return null}class Jj extends Error{upstream;turnId;code="codex_stdio_turn_failed";constructor(A,Q){super(`codex turn failed: ${A.replace(/\s+/g," ").trim().slice(0,500)}`);this.upstream=A;this.turnId=Q;this.name="CodexStdioTurnError"}}class RV extends Error{timeoutMs;interrupted;code="codex_stdio_turn_timeout";constructor(A,Q,B){super(A);this.timeoutMs=Q;this.interrupted=B;this.name="CodexStdioTurnTimeoutError"}}function oc(A,Q){let B=Q.now??Date.now,I=Q.log??(()=>{}),C=null,E="",g=0,U=null,J=0,Y=B(),F=!1,G,$,D,N=new Promise((X,L)=>{$=X,D=L});N.catch(()=>{});let V=(X)=>{let L=X?.turn?.id??X?.turnId??null;return Boolean(C&&L&&L!==C)},Z=()=>{if(F=!0,G)clearTimeout(G);A.off("notification",W)};function W(X){if(F)return;let L=X?.params;if(V(L))return;if(J++,Y=B(),X.method==="item/completed"){let M=L?.item;if(!M)return;if(g++,M.type==="agentMessage"&&typeof M.text==="string")E=M.text}else if(X.method==="error"){let M=hXA(L);if(M)U=M,I(`[codex-stdio] ✗ codex error: ${M.replace(/\s+/g," ").slice(0,300)}`);else I(`[codex-stdio] codex error (willRetry): ${String(L?.error?.message??"").slice(0,200)}`)}else if(X.method==="turn/completed"){Z();let M=L?.turn?.id??L?.turnId??C??"";$({turnId:M,finalText:E,itemCount:g,status:typeof L?.turn?.status==="string"?L.turn.status:void 0,failure:mXA(L?.turn,U)})}}if(A.on("notification",W),Q.timeoutMs>0)G=setTimeout(async()=>{if(F)return;Z();let X=B()-Y,L=$9(J,X),M=U?`;codex 最后报错: ${U.replace(/\s+/g," ").slice(0,200)}`:"",z=!1,K;if(!C)K="turn/start 尚未返回 turn id,无法 turn/interrupt";else try{await A.request("turn/interrupt",{threadId:Q.threadId,turnId:C},fXA),z=!0,K=`已用 turn/interrupt 中止 turn ${C}`}catch(_){K=`turn/interrupt 失败(${(_ instanceof Error?_.message:String(_)).replace(/\s+/g," ").slice(0,160)})`}I(`[codex-stdio] ✗ turn timed out after ${Q.timeoutMs}ms; ${L}; ${K}`),D(new RV(`codex-stdio 调用超时 (${Math.round(Q.timeoutMs/1000)}s) — ${L}${M};${K}。`+"确切原因见节点日志里 [codex-stdio] 开头那几行。",Q.timeoutMs,z))},Q.timeoutMs);return{setTurnId(X){if(X)C=X},done:N,cancel(){if(!F)Z()},fail(X){if(F)return;Z(),D(X)}}}function ac(A){let Q=A.parsedAccess?.allowFrom,B=uXA({channel:"telegram",channelDir:A.channelDir,allowFrom:Q});return{allowFromRaw:Q,bootWarn:B}}function rc(A){if(Array.isArray(A))return{list:A.filter((B)=>typeof B==="string"&&B.length>0).map((B)=>String(B)),malformed:!1};if(A===void 0||A===null)return{list:[],malformed:!1};return{list:[],malformed:!0}}function sc(A){let{list:Q,malformed:B}=rc(A.allowFrom);if(Q.length===0)return{allow:!1,kind:"empty-fail-closed",reason:B?"allowFrom malformed (not a string[]) — fail-closed":'allowFrom empty — fail-closed (set ["*"] to open to all, or add specific ids)'};if(Q.includes("*"))return{allow:!0,kind:"wildcard-allow",reason:'allowFrom=["*"]'};let I=A.senderId||"",C=(A.senderUsername||"").trim();if(I&&Q.includes(I))return{allow:!0,kind:"explicit-allow",reason:`sender id ${I} in allowFrom`};if(C&&Q.includes(C))return{allow:!0,kind:"explicit-allow",reason:`sender username ${C} in allowFrom`};return{allow:!1,kind:"denied",reason:`sender id=${I} username=${C||"(none)"} not in allowFrom`}}function uXA(A){let{list:Q,malformed:B}=rc(A.allowFrom);if(Q.length>0)return null;let I=B?"malformed (not a string[])":"empty";return`[${A.channel}] FAIL-CLOSED: ${A.channelDir}/access.json allowFrom is ${I} — `+'ALL inbound messages will be denied. To open the channel: edit access.json and set `"allowFrom": ["*"]` for any-sender, or add specific sender ids. Pre-v0.11 behaviour was fail-open; this is a deliberate security change (see release notes).'}UQ();import{randomBytes as cXA}from"crypto";import{closeSync as EU,constants as OB,fchmodSync as lXA,fstatSync as YD,fsyncSync as tc,lstatSync as yY,openSync as fY,readFileSync as ec,realpathSync as Yj,rmSync as pXA,writeFileSync as iXA}from"fs";import{basename as dXA,dirname as Fj,resolve as nXA}from"path";class TB extends Error{}function rC(A,Q){return A.dev===Q.dev&&A.ino===Q.ino}function Al(A){try{return yY(A)}catch(Q){if(Q?.code==="ENOENT")return;throw Q}}function qV(A,Q){let B=nXA(A),I=yY(B);if(I.isSymbolicLink()||!I.isDirectory()||Yj(B)!==B)throw new TB(`OpenCode state refuses ${Q} at ${B}: expected a canonical real directory`);let C;try{C=fY(B,OB.O_RDONLY|(OB.O_DIRECTORY||0)|(OB.O_NOFOLLOW||0));let E=YD(C),g=yY(B),U=process.getuid?.();if(!E.isDirectory()||g.isSymbolicLink()||!rC(I,E)||!rC(E,g)||Yj(B)!==B)throw new TB(`OpenCode state refuses ${Q} at ${B}: directory identity changed`);if(U===void 0||E.uid!==U||(E.mode&511)!==448)throw new TB(`OpenCode state refuses ${Q} at ${B}: owner/mode must be current uid/0700`);return E}finally{if(C!==void 0)EU(C)}}function wV(A,Q,B=!1){let I=Al(A);if(!I){if(B)return;throw new TB(`OpenCode state refuses ${Q} at ${A}: file is missing`)}if(I.isSymbolicLink()||!I.isFile()||I.nlink!==1||Yj(A)!==A)throw new TB(`OpenCode state refuses ${Q} at ${A}: expected a canonical single-link regular file`);let C;try{C=fY(A,OB.O_RDONLY|(OB.O_NOFOLLOW||0));let E=YD(C),g=yY(A),U=process.getuid?.();if(!E.isFile()||E.nlink!==1||g.isSymbolicLink()||!rC(I,E)||!rC(E,g))throw new TB(`OpenCode state refuses ${Q} at ${A}: file identity changed`);if(U===void 0||E.uid!==U||(E.mode&511)!==384)throw new TB(`OpenCode state refuses ${Q} at ${A}: owner/mode must be current uid/0600`);return E}catch(E){if(E?.code==="ELOOP")throw new TB(`OpenCode state refuses ${Q} at ${A}: symlinks are not allowed`);throw E}finally{if(C!==void 0)EU(C)}}function gU(A,Q){qV(Fj(A),`${Q} parent`);let B=wV(A,Q),I=fY(A,OB.O_RDONLY|(OB.O_NOFOLLOW||0));try{let C=YD(I),E=yY(A);if(!C.isFile()||C.nlink!==1||!rC(B,C)||!rC(C,E))throw new TB(`OpenCode state refuses ${Q} at ${A}: file changed before read`);return{body:ec(I,"utf8"),stat:C}}finally{EU(I)}}function FD(A,Q,B,I){let C=Fj(A);qV(C,`${B} parent`);let E=wV(A,B,!0);if(I&&(!E||!rC(I,E)))throw new TB(`OpenCode state refuses ${B} at ${A}: target changed after read`);let g=`${C}/.${dXA(A)}.${cXA(12).toString("hex")}.tmp`,U;try{U=fY(g,OB.O_WRONLY|OB.O_CREAT|OB.O_EXCL|(OB.O_NOFOLLOW||0),384),iXA(U,Q,"utf8"),lXA(U,384),tc(U);let J=YD(U),Y=process.getuid?.();if(!J.isFile()||J.nlink!==1||Y===void 0||J.uid!==Y)throw new TB(`OpenCode state refuses ${B}: temporary file is not owner-controlled`);EU(U),U=void 0,qV(C,`${B} parent`);let F=wV(A,B,!0);if(E===void 0!==(F===void 0)||E&&F&&!rC(E,F))throw new TB(`OpenCode state refuses ${B} at ${A}: target changed before atomic rename`);GA(g,A),wV(A,B);let G=fY(C,OB.O_RDONLY|(OB.O_DIRECTORY||0)|(OB.O_NOFOLLOW||0));try{tc(G)}finally{EU(G)}}catch(J){if(U!==void 0)try{EU(U)}catch{}throw pXA(g,{force:!0}),J}}function Ql(A){for(let Q of[A,`${A}.prev`]){let B=Al(Q);if(!B)continue;if(B.isSymbolicLink()||!B.isFile()||B.nlink!==1)throw new TB(`config state refuses ${Q}: symlinks, hardlinks, and non-files are not allowed`);let I=fY(Q,OB.O_RDONLY|(OB.O_NOFOLLOW||0));try{let C=YD(I),E=yY(Q);if(!C.isFile()||C.nlink!==1||!rC(B,C)||!rC(C,E))throw new TB(`config state refuses ${Q}: identity changed`);try{let g=JSON.parse(ec(I,"utf8"));if(g?.runtime==="opencode-cli"||g?.runtime==="opencode")return!0}catch{}}finally{EU(I)}}return!1}function Bl(A){qV(Fj(A),"node workDir");let Q,B;try{return Q=gU(A,"config.json"),{config:JSON.parse(Q.body),source:"primary"}}catch(E){if(E instanceof TB)throw E;B=String(E?.message||E)}let I;try{I=gU(`${A}.prev`,"config.json.prev")}catch(E){throw Error(`OpenCode config parse failed (${B}) and no safe .prev backup exists: ${E?.message||E}`)}let C;try{C=JSON.parse(I.body)}catch(E){throw Error(`OpenCode config parse failed (${B}); safe .prev parse also failed (${E?.message||E})`)}return FD(A,JSON.stringify(C,null,2)+`
|
|
321
321
|
`,"config.json",Q?.stat),{config:C,source:"prev",primaryError:B}}function Il(A){return JSON.parse(gU(A,"config.json").body)}function Gj(A,Q){let B=gU(A,"config.json");FD(A,JSON.stringify(Q,null,2)+`
|
|
322
322
|
`,"config.json",B.stat)}function $j(A){let Q=gU(A,"config.json");return FD(`${A}.prev`,Q.body,"config.json.prev"),{backedUp:!0}}function Cl(A,Q){let B=gU(A,"config.json"),I=JSON.parse(B.body);if(I.session===Q)return!1;return I.session=Q,FD(A,JSON.stringify(I,null,2)+`
|
|
323
323
|
`,"config.json",B.stat),!0}function Dj(A,Q){let B=gU(A,"config.json"),I=JSON.parse(B.body);if(I.opencodeConfiguredModelAtLastOpen===Q)return!1;return I.opencodeConfiguredModelAtLastOpen=Q,FD(A,JSON.stringify(I,null,2)+`
|
|
324
324
|
`,"config.json",B.stat),!0}function El(A,Q){return typeof A.opencodeConfiguredModelAtLastOpen==="string"&&A.opencodeConfiguredModelAtLastOpen!==Q}P0();UC();async function gl(A,Q){let B=!1,I;for(let C of A)try{await Q(C)}catch(E){if(!B)I=E;B=!0}if(B)throw I}function Nj(A,Q){let B=Promise.resolve(),I=new Map,C=async(E)=>{let g=Q?.initialDelayMs??0;while(!0)try{await E();return}catch(U){if(A(U),!Q)return;await new Promise((J)=>{setTimeout(J,g).unref?.()}),g=Math.min(g*2,Q.maxDelayMs)}};return{schedule(E){let g=I.get(E);if(g){g.dirty=!0;return}let U={dirty:!1};I.set(E,U);let J=async()=>{try{do U.dirty=!1,await C(E);while(U.dirty)}finally{I.delete(E)}};B=B.then(J,J)},idle(){return B}}}var oXA=new Set(["replied","failed","cancelled","expired"]);function aXA(A){return typeof A==="string"&&oXA.has(A)}async function Ul(A,Q){if(!Q)return{skip:!1,status:null,reason:"no-task-id"};let B;try{B=await A(Q)}catch{return{skip:!1,status:null,reason:"lookup-failed"}}if(!B||B.ok===!1||!B.task)return{skip:!1,status:null,reason:"not-found"};let I=typeof B.task.status==="string"?B.task.status:null;return aXA(I)?{skip:!0,status:I,reason:"terminal"}:{skip:!1,status:I,reason:"open"}}function Jl(A){if(A.meta&&typeof A.meta==="object"&&!Array.isArray(A.meta))return A.meta;if(typeof A.meta_json!=="string"||A.meta_json.length===0)return null;try{let Q=JSON.parse(A.meta_json);return Q&&typeof Q==="object"&&!Array.isArray(Q)?Q:null}catch{return null}}function OV(A){let Q=A.type??"task";if(Q!=="task"&&Q!=="broadcast")return!1;let B=Jl(A);if(!B||B.source!=="dashboard-chat")return!1;if(typeof B.client_request_id!=="string"||!/^dreq_[a-f0-9]{32}$/.test(B.client_request_id))return!1;return B.auth_origin==="user"}function Yl(A){if(!OV(A))return null;let Q=Jl(A)?.client_request_id;return typeof Q==="string"?Q:null}async function Fl(A,Q){for(let B of A)await Q(B)}function Gl(A){if(!Number.isInteger(A.maxConcurrent)||A.maxConcurrent<1)throw Error("maxConcurrent must be a positive integer");let Q=new Set,B=new Set,I=A.reservedPrioritySlots??0;if(!Number.isInteger(I)||I<0||I>=A.maxConcurrent)throw Error("reservedPrioritySlots out of range");let C=new Set,E=[],g=()=>{while(Q.size<A.maxConcurrent&&E.length>0){if(!E[0].priority&&B.size>=A.maxConcurrent-I)break;let U=E.shift(),J=A.key(U.message);if(C.delete(J),Q.add(J),!U.priority)B.add(J);let Y;try{Y=U.handler(U.message)}catch(F){Y=Promise.reject(F)}Y.catch(A.onError).finally(()=>{Q.delete(J),B.delete(J);try{A.onSettled?.()}catch(F){A.onError(F)}finally{g()}})}};return{submit(U,J){let Y=0,F=0;for(let G of U){let $=A.key(G);if(Q.has($)||C.has($)){F++;continue}C.add($);let D=A.prioritize?.(G)===!0||A.prioritizeRecovery?.(G)===!0,N=D?E.findIndex((Z)=>!Z.priority):-1,V={message:G,handler:J,priority:D};if(N<0)E.push(V);else E.splice(N,0,V);Y++}return g(),{active:Q.size,queued:E.length,accepted:Y,deduplicated:F}},stats(){return{active:Q.size,queued:E.length}}}}function $l(A,Q){return A!=="codex-app-server"||Q===0}var rXA={self:"sender alias equals node alias; reply-loop guard","own-prefix":"message carries this node's own reply prefix; reply-loop guard",cooldown:"sender cooldown is active","low-value-inbound":"non-task message matched the low-value filter"};function Dl(A){let Q=rXA[A.reason]||"inbound filter rejected the message";return`skipped inbound ${A.messageType} ${A.taskId} from ${A.sender}: ${A.reason} (${Q}); acknowledged without model delivery`}function Nl(A){let Q=A||"task";return Q==="task"||Q==="broadcast"}function Vl(A){let{alias:Q,from:B,content:I,msgType:C}=A;if(B===Q&&!A.imBridge)return"self";if(I.startsWith(`[${Q}]`))return"own-prefix";let E=C==="task"||C==="broadcast"||C==="reply";if(!E&&B!=="hub"&&B!=="api"){if(A.lastReplyAt&&A.now-A.lastReplyAt<A.cooldownMs)return"cooldown"}if(!E&&A.isLowValue(I))return"low-value-inbound";return null}var sXA="skipped by agent-node: self-sent task (sender is this node; reply-loop guard), no turn ran. To wake a node later, use a Hub scheduled task or /aloop instead of send_task to yourself. (#519)",tXA="skipped by agent-node: task text starts with this node's own reply prefix (echo of its own reply; reply-loop guard), no turn ran. (#519)";function eXA(A){if(A==="self")return sXA;if(A==="own-prefix")return tXA;return null}async function Zl(A,Q){let B=eXA(Q.reason);if(!B)return{kind:"not-applicable",detail:`reason ${Q.reason} does not close a task`};if(!Nl(Q.msgType))return{kind:"not-applicable",detail:`type ${Q.msgType} carries no task`};if(!Q.taskId)return{kind:"not-applicable",detail:"no task id"};try{let I=await A("cancel_task",{task_id:Q.taskId,reason:B});if(I&&typeof I==="object"&&I.ok===!0)return{kind:"closed",tool:"cancel_task"};return{kind:"not-closed",tool:"cancel_task",detail:JSON.stringify(I??null).slice(0,200)}}catch(I){return{kind:"error",tool:"cancel_task",detail:String(I?.message??I).slice(0,200)}}}async function Wl(A,Q){if(!Nl(Q.msgType))return{kind:"not-applicable",detail:`type ${Q.msgType} carries no task`};if(!Q.taskId)return{kind:"not-applicable",detail:"no task id"};let I=`${Q.result.trim()||"(empty reply)"} [low-value reply withheld from sender by agent-node (#519)]`.slice(0,4000);try{return await A("report_completion",{alias:Q.alias,task:Q.taskId,result:I}),{kind:"closed",tool:"report_completion"}}catch(C){return{kind:"error",tool:"report_completion",detail:String(C?.message??C).slice(0,200)}}}function GD(A,Q){switch(Q.kind){case"closed":return`closed task ${A} via ${Q.tool} (#519)`;case"not-closed":return`task ${A} not closed by ${Q.tool} (already terminal?): ${Q.detail}`;case"not-applicable":return`task ${A} left as-is: ${Q.detail}`;case"error":return`failed to close task ${A} via ${Q.tool}: ${Q.detail}`}}function TV(){let A=null;return{run(Q){if(A)return A;let B=Promise.resolve().then(Q);return A=B,B.finally(()=>{if(A===B)A=null}).catch(()=>{}),B},pending(){return A}}}function Xl(){let A=null,Q=TV();return{async getOrOpen(B){if(A?.isRunning)return A;return Q.run(async()=>{if(A?.isRunning)return A;A=null;let I=await B();if(!I.isRunning)throw Error("codex app-server session stopped while opening");return A=I,I})},invalidate(B){if(!B||A===B)A=null},current(){return A},pending(){return Q.pending()}}}$D();I4();import{closeSync as DD,constants as vE,existsSync as EMA,fchmodSync as SV,fstatSync as Ll,fsyncSync as gMA,ftruncateSync as UMA,lstatSync as JMA,mkdirSync as YMA,openSync as Mj,readdirSync as FMA,readFileSync as GMA,realpathSync as Xj,writeSync as $MA}from"node:fs";import{join as zl,resolve as Lj}from"node:path";function Kl(){return process.platform==="linux"&&EMA("/proc/self/fd")}function Hl(A,Q){return Kl()?`/proc/self/fd/${A}`:Q}function jl(A,Q){let B=Ll(A),I=process.getuid?.();if(!B.isFile()||B.nlink!==1||I!==void 0&&B.uid!==I)throw Error(`private log is not a single owner-controlled file: ${Q}`);SV(A,384)}function _l(A){let Q=Lj(A);if(Xj(Q)!==Q)throw Error(`private log directory is not canonical: ${Q}`);let B=Mj(Q,vE.O_RDONLY|(vE.O_DIRECTORY||0)|(vE.O_NOFOLLOW||0));try{let I=Ll(B),C=process.getuid?.();if(!I.isDirectory()||C!==void 0&&I.uid!==C)throw Error(`private log directory is not owner-controlled: ${Q}`);if(Kl()&&Xj(`/proc/self/fd/${B}`)!==Q)throw Error(`private log directory changed during validation: ${Q}`);if(process.platform!=="win32")SV(B,448);return B}catch(I){throw DD(B),I}}function Rl(A,Q,B){let I=0;while(I<Q.length){let C=$MA(A,Q,I,Q.length-I,B===null?null:B+I);if(C<=0)throw Error("private log write made no progress");I+=C}}function DMA(A,Q){let B=Mj(A,vE.O_RDWR|(vE.O_NOFOLLOW||0));try{jl(B,A);let I=Buffer.from(Q.redactText(GMA(B,"utf8")).text,"utf8");if(UMA(B,0),I.length>0)Rl(B,I,0);gMA(B),SV(B,384)}finally{DD(B)}}function wl(A,Q){let B=Lj(A);YMA(B,{recursive:!0,mode:448});let I=JMA(B),C=process.getuid?.();if(I.isSymbolicLink()||!I.isDirectory()||Xj(B)!==B||C!==void 0&&I.uid!==C)throw Error(`private log directory is not owner-controlled: ${B}`);let E=_l(B);try{let g=Hl(E,B);for(let U of FMA(g)){if(!U.endsWith(".log"))continue;DMA(zl(g,U),Q)}}finally{DD(E)}return B}function zj(A,Q,B,I){if(!/^\d{4}-\d{2}-\d{2}\.log$/.test(Q))throw Error("private log filename is not a canonical daily log name");let C=_l(A),E=zl(Hl(C,Lj(A)),Q),g;try{g=Mj(E,vE.O_WRONLY|vE.O_CREAT|vE.O_APPEND|(vE.O_NOFOLLOW||0),384),jl(g,E);let U=Buffer.from(I.redactText(B).text,"utf8");if(U.length>0)Rl(g,U,null);SV(g,384)}finally{if(g!==void 0)DD(g);DD(C)}}function Kj(A){return JSON.stringify(A)}function ql(A){let Q=A.configNodeId||"",B=A.envNodeId||"";if(Q){if(B&&B!==Q)A.warn?.(`COMMHUB_NODE_ID mismatch: env=${Kj(B)} config=${Kj(Q)} config_path=${Kj(A.configPath||"config.json")}; ignoring env COMMHUB_NODE_ID, using config node_id`);return{value:Q,source:"config"}}if(B)return{value:B,source:"env"};return{value:"",source:"none"}}function NMA(A){let Q=A?.task_id||A?.message_id||A?.id;if(Q)return String(Q);let B=A?.content?.[0]?.text;if(typeof B!=="string")return null;try{let I=JSON.parse(B);return I?.task_id||I?.message_id||I?.id||null}catch{return null}}function hY(A,Q,B,I={}){let C=o1({from_alias:A.fromAlias,to_alias:A.toAlias,task_id:B,parent_task_id:A.parentTaskId,network_id:A.networkId,transport:"mcp_http",status:Q,duration_ms:Date.now()-A.startedAt,lifecycle_tracking:"tracked",...I.errorCode?{error_code:I.errorCode}:{},...I.errorMessage?{error_message:d1(I.errorMessage)}:{}});if(I.event)C.event=I.event;A.log(n1(C))}async function Ol(A,Q,B){let I=B.now??Date.now,C=B.sleep??((V)=>new Promise((Z)=>setTimeout(Z,V))),E=B.timeoutMs??120000,g=B.pollIntervalMs??2000,U=B.stale30Ms??30000,J=B.stale60Ms??60000,Y=B.emit,F=I()+E,G=null,$=new Set,D=!1,N=!1;while(I()<F){G=await B.getTask(A);let V=G?.task||G,Z=V?.status;if((Z==="acked"||Z==="running"||Z==="processing")&&!$.has(Z))$.add(Z),Y(Z==="acked"?"acked":"started",A);if(Z==="replied"||Z==="failed"||Z==="cancelled")return Y(Z==="replied"?"replied":"failed",A,{...Z==="replied"?{}:{errorCode:`task_${Z}`,event:"task.failed"}}),{kind:"terminal",status:Z,latest:G,row:V};let W=I()-Q;if(!D&&W>=U&&Z==="delivered")D=!0,Y("delivered",A,{event:"task.warning.delivered_stale_30s"});if(!N&&W>=J&&Z==="delivered")N=!0,Y("delivered",A,{event:"task.warning.delivered_stale_60s"});await C(g)}return Y("expired",A,{errorCode:"lifecycle_timeout"}),{kind:"expired",latest:G}}async function Tl(A,Q,B){hY(Q,"sending",null);try{let I=await B({alias:A.alias,task:A.task,priority:A.priority||"normal",from_session:Q.fromAlias,parent_task_id:Q.parentTaskId||void 0}),C=NMA(I);if(!C)hY(Q,"failed",null,{errorCode:"missing_task_id",errorMessage:"CommHub response omitted task_id"});else hY(Q,"delivered",C);return I}catch(I){throw hY(Q,"failed",null,{errorCode:"send_failed",errorMessage:I}),I}}function Pl(A){let Q=A||"task";if(Q==="task"||Q==="broadcast")return{deliverToRuntime:!0,replyExpected:!0};if(Q==="reply")return{deliverToRuntime:!0,replyExpected:!1};return{deliverToRuntime:!1,replyExpected:!1}}async function Sl(A,Q,B){let I=await B.deliverToRuntime(A);if(Q)return{kind:"request",result:I};return await B.acknowledge(A.id),{kind:"terminal_peer_reply",result:I}}function xl(A,Q){if(A.type!=="new_reply")return!1;return Q(),!0}F9();function Hj(){return{hubSupportsTool:null}}function VMA(A){if(!(A instanceof II))return!1;if(A.code===-32601)return!0;let Q=String(A.message||"");return A.code===-32602&&/(?:unknown|not found|does not exist).{0,80}send_peer_reply|send_peer_reply.{0,80}(?:unknown|not found|does not exist)/i.test(Q)}function ZMA(A){if(!(A instanceof II))return!1;return A.code==="peer_reply_unsupported"||A.code==="peer_reply_origin_not_node"||A.code==="reply_task_not_owned"||A.code==="peer_reply_node_token_required"||VMA(A)}async function kl(A,Q,B=Hj()){try{let I=await Q.sendAtomic(A);return B.hubSupportsTool=!0,{route:"atomic",payload:I}}catch(I){if(!ZMA(I))throw I;return{route:"legacy-reply",payload:await Q.sendLegacyReply(A)}}}UQ();import{chmodSync as vl,closeSync as jj,existsSync as WMA,fchmodSync as XMA,fsyncSync as MMA,openSync as bl,readFileSync as LMA,unlinkSync as yl,writeFileSync as zMA}from"node:fs";import{randomBytes as KMA}from"node:crypto";var fl=15000,HMA=2500,ul=300000,ND=2000,jMA=new Set(["replied","failed","cancelled","expired"]);function Rj(A){if(A===void 0||A===null||String(A).trim()==="")return fl;let Q=Number(A);if(!Number.isSafeInteger(Q))return fl;return Math.min(ul,Math.max(HMA,Q))}function _j(){return{version:3,consumed_task_ids:[],consumed_client_request_ids:[],surfaced_outbound_terminal_ids:[],outbound_deliveries:[],outbound_terminal_watermark:0,inbound_lifecycle:[],last_success_at:null}}function m0(A){if(!Array.isArray(A))return[];return[...new Set(A.filter((Q)=>typeof Q==="string"&&Q.length>0&&Q.length<=512))].slice(-ND)}function _MA(A){if(!A||typeof A!=="object")return _j();let Q=A;return{version:3,consumed_task_ids:m0(Q.consumed_task_ids),consumed_client_request_ids:m0(Q.consumed_client_request_ids),surfaced_outbound_terminal_ids:m0(Q.surfaced_outbound_terminal_ids),outbound_deliveries:Array.isArray(Q.outbound_deliveries)?Q.outbound_deliveries.filter((B)=>!!B&&typeof B.task_id==="string"&&typeof B.idempotency_key==="string"&&["pending","delivering","delivered"].includes(B.state)).slice(-ND):m0(Q.surfaced_outbound_terminal_ids).map((B)=>({task_id:B,idempotency_key:`commhub-terminal:${B}`,state:"delivered"})),outbound_terminal_watermark:Number.isSafeInteger(Q.outbound_terminal_watermark)&&Number(Q.outbound_terminal_watermark)>=0?Number(Q.outbound_terminal_watermark):0,inbound_lifecycle:Array.isArray(Q.inbound_lifecycle)?Q.inbound_lifecycle.filter((B)=>!!B&&typeof B.task_id==="string"&&["delivered","submitted","consumed","completed"].includes(B.state)).slice(-ND):m0(Q.consumed_task_ids).map((B)=>({task_id:B,state:"consumed"})),last_success_at:typeof Q.last_success_at==="string"?Q.last_success_at:null}}function hl(A){return Yl(A)}function ml(A){return typeof A.task_id==="string"&&A.task_id?A.task_id:A.id}function RMA(A){let Q=A,B=String(Q?.message??A??"");return Q?.code===-32601||Q?.code===-32602||/unknown tool|tool .+ not found|method not found|-3260[12]/i.test(B)}var wMA=new Set(["from_node_id_identity_mismatch","node_token_required"]);function qMA(A){let Q=A;return Q?.appLevel===!0&&typeof Q.code==="string"&&wMA.has(Q.code)}class cl{path;state;constructor(A){this.path=A;this.state=this.read()}snapshot(){return this.state=this.read(),this.state}update(A){this.withLock(()=>{let Q=this.read();A(Q),Q.consumed_task_ids=m0(Q.consumed_task_ids),Q.consumed_client_request_ids=m0(Q.consumed_client_request_ids),Q.surfaced_outbound_terminal_ids=m0(Q.surfaced_outbound_terminal_ids),Q.outbound_deliveries=Q.outbound_deliveries.filter((B)=>B.state!=="delivered").slice(-ND),Q.inbound_lifecycle=Q.inbound_lifecycle.slice(-ND),this.write(Q),this.state=Q})}claimOutbound(A,Q,B,I){return this.withLock(()=>{let C=this.read(),E=C.outbound_deliveries.find((g)=>g.task_id===A);if(E?.state==="delivered"||E?.state==="delivering"&&(E.lease_until??0)>B)return!1;if(E)E.state="delivering",E.lease_until=B+I;else C.outbound_deliveries.push({task_id:A,idempotency_key:Q,state:"delivering",lease_until:B+I});return this.write(C),this.state=C,!0},!1)}withLock(A,Q){let B=`${this.path}.lock`,I;try{I=bl(B,"wx",384)}catch{if(arguments.length>1)return Q;throw Error("compensation cursor is locked")}try{return A()}finally{jj(I);try{yl(B)}catch{}}}read(){if(!WMA(this.path))return _j();try{let A=_MA(JSON.parse(LMA(this.path,"utf8")));return vl(this.path,384),A}catch{return _j()}}write(A){let Q=`${this.path}.tmp-${process.pid}-${KMA(6).toString("hex")}`,B=null;try{B=bl(Q,"wx",384),XMA(B,384),zMA(B,`${JSON.stringify(A)}
|
|
325
325
|
`,"utf8"),MMA(B),jj(B),B=null,GA(Q,this.path),vl(this.path,384)}finally{if(B!==null)jj(B);try{yl(Q)}catch{}}}}function ll(A){let Q=Rj(A.intervalMs),B=A.adapters,I=new cl(A.cursorPath),C="probing",E=null,g=!1,U=!1,J=null,Y=0,F=!1,G=!1,$=B.now??Date.now,D=Math.max(30000,Q*2),N=B.setTimer??((_,h)=>{let x=setTimeout(_,h);return x.unref?.(),x}),V=B.clearTimer??((_)=>clearTimeout(_)),Z=(_)=>{let h=I.snapshot(),x=ml(_),k=hl(_);return h.consumed_task_ids.includes(x)||!!k&&h.consumed_client_request_ids.includes(k)},W=(_)=>{let h=ml(_),x=hl(_);I.update((k)=>{if(k.consumed_task_ids.push(h),x)k.consumed_client_request_ids.push(x);let b=k.inbound_lifecycle.find((y)=>y.task_id===h);if(b)b.state="completed";else k.inbound_lifecycle.push({task_id:h,state:"completed"})})},X={delivered:0,submitted:1,consumed:2,completed:3},L=(_,h)=>{if(!_)return;I.update((x)=>{let k=x.inbound_lifecycle.find((b)=>b.task_id===_);if(!k)x.inbound_lifecycle.push({task_id:_,state:h});else if(X[h]>X[k.state])k.state=h;if(X[h]>=X.consumed)x.consumed_task_ids.push(_)})},M=(_)=>{if(U||C==="realtime-only")return;if(J!==null)V(J);J=N(()=>{J=null,K("timer")},_)},z=async(_)=>{try{let h=I.snapshot().outbound_terminal_watermark,[x,k]=await Promise.all([B.getInbox(),G?Promise.resolve({tasks:[],hasMore:!1}):B.listOutbound(h).catch((y)=>{if(!qMA(y))throw y;return G=!0,B.warn(`[commhub-compensation] outbound reconciliation disabled: this node's token is not bound to its node_id (${y.code}); inbox compensation continues. Re-issue a node-bound token to restore lost-reply reconciliation.`),{tasks:[],hasMore:!1}})]),b=k.tasks;if(C==="probing")C="active",B.log(`[commhub-compensation] active (${Q}ms; SSE remains primary)`);if(x.some((y)=>!Z(y)))B.scheduleInboxDrain();for(let y of b){if(!y?.task_id||!jMA.has(y.status))continue;if(!Number.isSafeInteger(y.terminal_seq)||Number(y.terminal_seq)<=0)throw Object.assign(Error("Hub terminal sequence missing"),{code:-32602});let T=Number(y.terminal_seq),n=I.snapshot();if(T<=n.outbound_terminal_watermark)continue;let u=I.snapshot().outbound_deliveries.find((v)=>v.task_id===y.task_id);if(u?.state==="delivered"){I.update((v)=>{v.outbound_terminal_watermark=Math.max(v.outbound_terminal_watermark,T)});continue}let O=u?.idempotency_key??`commhub-terminal:${y.task_id}`;if(!I.claimOutbound(y.task_id,O,$(),D))break;try{await B.onOutboundTerminal(y,O)}catch(v){throw I.update((e)=>{let s=e.outbound_deliveries.find((EA)=>EA.task_id===y.task_id);if(s)s.state="pending",s.lease_until=0}),v}I.update((v)=>{let e=v.outbound_deliveries.find((s)=>s.task_id===y.task_id);if(e)e.state="delivered",e.lease_until=0;v.outbound_terminal_watermark=Math.max(v.outbound_terminal_watermark,T)})}if(I.update((y)=>{y.last_success_at=new Date($()).toISOString()}),k.hasMore)g=!0;Y=0,B.log(`[commhub-compensation] ${_} poll ok; inbox=${x.length} outbound=${b.length}`),M(Q)}catch(h){if(RMA(h)){if(C="realtime-only",!F)F=!0,B.warn("[commhub-compensation] Hub lacks durable inbox/outbox polling capability; realtime-only mode (SSE/turn-steer only)");return}Y++;let x=Math.min(ul,Q*2**Math.min(Y,5));B.warn(`[commhub-compensation] poll failed; retry in ${x}ms: ${h instanceof Error?h.message:String(h)}`),M(x)}},K=(_)=>{if(U||C==="realtime-only")return;if(E){g=!0;return}E=(async()=>{let h=_;do g=!1,await z(h),h="idle";while(g&&!U&&C!=="realtime-only")})().finally(()=>{E=null})};return{get mode(){return C},get outboundDisabled(){return G},trigger:K,recordConsumed:W,recordLifecycle:L,wasConsumed:Z,async idle(){await E},stop(){if(U=!0,J!==null)V(J);J=null}}}import{appendFileSync as dgA,mkdirSync as eW,statSync as ngA}from"fs";import{appendFileSync as OMA,mkdirSync as TMA,writeSync as PMA}from"node:fs";import{join as SMA}from"node:path";function pl(A){if(A instanceof Error)return`${A.name}: ${A.message}`.replace(/[\r\n]+/g," ");return String(A).replace(/[\r\n]+/g," ")}function xMA(A){if(A instanceof Error)return A.stack||`${A.name}: ${A.message}`;return String(A)}function il(A){let Q=A.stdout??process.stdout,B=A.stderr??process.stderr,I=A.now??(()=>new Date),C=A.redact??((Z)=>Z),E=A.exit??((Z)=>process.exit(Z)),g=A.alias??"agent-node",U=!1,J=!1,Y=!1,F="normal",G=!1,$=(Z,W,X)=>{return`[${I().toISOString().slice(11,19)}] [${Z.padEnd(5)}] [${g}] [${W}] ${X}`},D=(Z)=>{try{let W=I().toISOString().slice(0,10),X=C(Z);if(A.appendLine)A.appendLine(W,X);else TMA(A.logDir,{recursive:!0,mode:448}),OMA(SMA(A.logDir,`${W}.log`),X+`
|
|
326
326
|
`,{mode:384})}catch{}},N=(Z)=>(W)=>{if(W?.code==="EPIPE"){if(Z==="stdout")U=!0;else J=!0;if(!Y)Y=!0,D($("WARN","stream",`${Z} EPIPE; terminal output disabled, file logging continues`));return}if(F=`${Z} error: ${pl(W)}`,!G)G=!0,E(1)};Q.on("error",N("stdout")),B.on("error",N("stderr"));let V=(Z,W)=>{if(G)return;G=!0,F=`${Z}: ${pl(W)}`;let X=xMA(W);if(D($("ERROR","fatal",`${Z}: ${X}`)),!J)try{PMA(2,`${X}
|
|
327
|
-
`)}catch(L){if(L?.code==="EPIPE")J=!0}E(1)};return process.on("uncaughtException",(Z)=>V("uncaughtException",Z)),process.on("unhandledRejection",(Z)=>V("unhandledRejection",Z)),process.on("exit",(Z)=>D($(Z===0?"INFO":"ERROR","exit",`code=${Z} reason=${F}`))),{outputBroken:()=>U||J}}var dl={name:"@sleep2agi/agent-node",version:"2.5.0-preview.
|
|
327
|
+
`)}catch(L){if(L?.code==="EPIPE")J=!0}E(1)};return process.on("uncaughtException",(Z)=>V("uncaughtException",Z)),process.on("unhandledRejection",(Z)=>V("unhandledRejection",Z)),process.on("exit",(Z)=>D($(Z===0?"INFO":"ERROR","exit",`code=${Z} reason=${F}`))),{outputBroken:()=>U||J}}var dl={name:"@sleep2agi/agent-node",version:"2.5.0-preview.164",description:"AI Agent runtime for CommHub networks. Supports Claude Code CLI, Claude Agent SDK, Codex SDK, Codex app-server, Grok Build ACP, and OpenCode CLI.",bin:{"agent-node":"dist/cli.js"},type:"module",files:["dist","README.md"],scripts:{build:"bun build src/cli.ts --outdir dist --entry-naming cli.js --target node --minify --external @anthropic-ai/claude-agent-sdk --external '@anthropic-ai/claude-agent-sdk-*' --external @openai/codex-sdk --external node-pty && bun build src/upload-file-mcp-stdio.ts --outdir dist --entry-naming upload-file-mcp-stdio.js --target node --minify",prepublishOnly:"npm run build"},keywords:["agent","ai","commhub","claude","claude-code","codex","gpt5","grok","xai","grok-build-cli","copresence","acp","sdk","minimax","mimo","runtime","node","anthropic"],author:"sleep2agi",license:"Apache-2.0",homepage:"https://anet.sh",repository:{type:"git",url:"git+https://github.com/sleep2agi/agent-network.git",directory:"agent-node"},publishConfig:{access:"public",tag:"preview"},bugs:{url:"https://github.com/sleep2agi/agent-network/issues"},engines:{node:">=18.17.0"},dependencies:{"@anthropic-ai/claude-agent-sdk":"0.3.289",undici:"^6.27.0",ws:"^8.22.0",zod:"^4.4.3"},optionalDependencies:{"@openai/codex":"^0.133.0","@openai/codex-sdk":"^0.133.0","node-pty":"^1.1.0"},devDependencies:{"@types/ws":"^8.18.2"}};a$();_$();import{chmodSync as vMA,existsSync as bMA,mkdirSync as yMA,readFileSync as fMA,writeFileSync as hMA}from"node:fs";import{join as mMA}from"node:path";var nl="model_reasoning_effort";function wj(A){return H$(A)}function uMA(A,Q){let B=A.includes(`\r
|
|
328
328
|
`)?`\r
|
|
329
329
|
`:`
|
|
330
330
|
`,I=A.endsWith(`
|
|
@@ -419,5 +419,5 @@ ${$}`,j(`[feishu] msg ${I.idempotencyKey?.slice(-12)||"?"} attachments=${U.lengt
|
|
|
419
419
|
|
|
420
420
|
`+`[飞书 outbound] 这条会话的文件分发目录: ${E}
|
|
421
421
|
`+"把要发给用户的文件存到这个目录里,回复末尾加一行 [[send-file:绝对路径]] 即可发送 (一文件一行)。路径必须严格在这个目录下,否则 bridge 会拒绝。";let G;if(!F.trim())G="[agent-node] 收到事件但没有可处理的文本/图片内容。";else try{let $=await DX(F,Y,null);G=$.failed?`[agent-node 处理失败] ${$.text}`:$.text}catch($){R(`[feishu] think() threw: ${$?.message??$}`),G=`[agent-node 异常] ${$?.message??String($)}`}if(AQ==="cli")G=XI.redactText(G).text;if(typeof A.send!=="function")return;try{A.send({type:"reply",eventKey:I.idempotencyKey,text:G})}catch($){R(`[feishu] reply send failed: ${$?.message||$}`)}})().catch((g)=>{R(`[feishu] message handler outer error: ${g?.message??g}`)})})}function pmA(A){if(!A||typeof A!=="object")return!1;let Q=A;if(Q.type!=="event")return!1;let B=Q.event;return!!B&&typeof B==="object"&&typeof B.idempotencyKey==="string"}async function imA(A){let Q={channel:A,apiBase:`https://api.telegram.org/bot${A.token}`,fileBase:`https://api.telegram.org/file/bot${A.token}`,offset:0};try{let U=await gX(Q,"getMe",{});j(`Telegram bot: @${U.username} (${U.first_name})`)}catch(U){OC(`Telegram token 无效: ${U.message}`),process.exit(1)}let B=NA(A.dir,"state.json");try{let U=JSON.parse(fI(B,"utf-8"));if(U.offset)Q.offset=U.offset,HA(`Telegram offset restored: ${Q.offset}`)}catch{}let I=()=>{try{rT(B,JSON.stringify({offset:Q.offset})+`
|
|
422
|
-
`)}catch{}},C=!1,E=[];async function g(){if(C)return;C=!0;while(E.length){let{msg:U,updateId:J}=E.shift();try{await mmA(Q,U),Q.offset=J+1,I()}catch(Y){OC(`TG handle: ${Y.message}`)}}C=!1}j(`Telegram polling: ${A.dir}`);while(!0)try{let J=await(await PN((Y)=>fetch(`${Q.apiBase}/getUpdates?offset=${Q.offset}&timeout=30`,{signal:Y}),ShA,"telegram-getUpdates")).json();if(!J.ok)throw Error(J.description||"getUpdates failed");for(let Y of J.result||[])if(Q.offset=Y.update_id+1,Y.message){let F=Y.message,G=MUA(F),$=F.text||F.caption||"";if(j(`← TG [${G}] ${$.slice(0,80)}${F.photo?" +img":""}${F.document?" +file":""}`),F.chat?.id&&F.message_id)gX(Q,"setMessageReaction",{chat_id:F.chat.id,message_id:F.message_id,reaction:[{type:"emoji",emoji:E.length>0?"⏳":"\uD83D\uDC40"}]}).catch(()=>{});E.push({msg:F,updateId:Y.update_id}),g()}}catch(U){R(`Telegram polling error: ${U.message}`),await new Promise((J)=>setTimeout(J,3000))}}async function wgA(A=60000){VP=!0;let Q=Date.now();try{await Promise.race([dT,new Promise((I)=>setTimeout(I,A))])}catch{}let B=Date.now()-Q;j(`[config-apply] drained in-flight think (${B}ms${B>=A?`, hard-cap ${A}ms hit`:""})`)}async function LUA(){let A="";try{let B=(await ZA("get_config_update",{}))?.update;if(!B){HA("[config-apply] no pending update for this node");return}if(A=B.update_id,j(`[config-apply] pulled ${A} mode=${B.apply_mode}`),B.apply_mode==="restart_only"){try{await ZA("ack_config_update",{update_id:A,status:"restarting"})}catch(Y){R(`[config-apply] restart_only ack restarting failed (continuing to exit): ${Y?.message||Y}`)}await wgA(),await CX("config restart_only"),j(`[config-apply] exiting with RESTART_SENTINEL=${w$} for parent supervisor`),process.exit(w$)}let I=Qh(B.patch,{runtime:w?.runtime});if(I){R(`[config-apply] local validate rejected ${A}: ${I.field}=${I.reason}`),await ZA("ack_config_update",{update_id:A,status:"rejected",error:`local validate: ${I.field}=${I.reason}`});return}let C=Bh(B.patch,{runtime:w?.runtime,opencodeGeneration:w?.opencodeGeneration,requestedMode:B.apply_mode,hotModelSwitchAvailable:GB?.isRunning===!0&&typeof GB.setSelectedModel==="function"});if(C!==B.apply_mode)R(`[config-apply] mode mismatch hub=${B.apply_mode} local=${C}; trusting local for safety`);let E=C;if(!QA){R(`[config-apply] no configFilePath (node started without --config); rejecting ${A}`),await ZA("ack_config_update",{update_id:A,status:"rejected",error:"no config file path on this node — start with --config to enable remote apply"});return}if(E==="hot"&&B.patch.model&&r==="opencode"&&zB==="v2"){let Y=GB;if(!Y?.isRunning||!Y.setSelectedModel){await ZA("ack_config_update",{update_id:A,status:"rejected",error:"OpenCode V2 session is not running; model was not changed"});return}try{await HP(Y.setSelectedModel(B.patch.model),ZX,`OpenCode session model switch timed out after ${ZX}ms`)}catch($){let D=String($?.message||$).slice(0,400);R(`[config-apply] OpenCode V2 model switch failed: ${D}`);try{await ZA("ack_config_update",{update_id:A,status:"rejected",error:`OpenCode session model switch failed: ${D}`},0)}catch(N){R(`[config-apply] ack rejected failed: ${N?.message||N}`)}return}let F=$j(QA),G=wH(w,{model:B.patch.model});Gj(QA,G),Dj(QA,B.patch.model),QJ=B.patch.model,w=G,JG+=1,await ZA("ack_config_update",{update_id:A,status:"applied",new_revision:JG}),j(`[config-apply] OpenCode V2 session model=${B.patch.model} (no restart, .prev backedUp=${F.backedUp})`),qQ(KB.status,KB.task).catch(()=>{});return}let g=r==="opencode"?$j(QA):gh(QA),U=wH(w,B.patch);if(r==="opencode")Gj(QA,U);else YQ(QA,U);let J=B.patch.flags?.modelReasoningEffort;if(J!==void 0&&U.runtime==="codex-app-server"&&QA){let Y=AC(QA),{codexHome:F}=q7({nodeDir:Y,config:U,exists:WI});if(wj(J))ol(F,J),j(`[config-apply] wrote ${NA(F,"config.toml")} (model_reasoning_effort)`)}if(j(`[config-apply] wrote ${QA} (.prev backedUp=${g.backedUp})`),E==="hot"){w=U,KV(w.daemonExtraPath),JG+=1,await ZA("ack_config_update",{update_id:A,status:"applied",new_revision:JG}),j(`[config-apply] HOT applied ${A} → revision=${JG}`);return}try{await ZA("ack_config_update",{update_id:A,status:"restarting"})}catch(Y){R(`[config-apply] restart ack restarting failed (continuing to exit): ${Y?.message||Y}`)}await wgA(),await CX("config restart"),j(`[config-apply] exiting with RESTART_SENTINEL=${w$} for parent supervisor`),process.exit(w$)}catch(Q){if(OC(`[config-apply] failed: ${Q?.message||Q}`),A)try{await ZA("ack_config_update",{update_id:A,status:"rejected",error:`apply runtime: ${String(Q?.message||Q).slice(0,500)}`})}catch(B){R(`[config-apply] ack rejected failed: ${B?.message||B}`)}}}async function dmA(){await LUA()}var Dg=new Set,lW=new Set,pW=new Set;async function nmA(){let A=`${sA}/events/${encodeURIComponent(BA)}`,Q=3600000,B=!0;await WH({label:"sse",shutdownGate:()=>!1,abandonAfterMs:3600000,onAbandon:()=>OC(ly(BA,sA)),onRetryWait:(I)=>HA(`SSE reconnecting (${(I/1000).toFixed(1)}s)...`),onError:(I)=>R(`SSE error: ${I?.message||I}`),runOnce:async(I)=>{HA(`SSE connecting: ${A}`);let C=await fetch(A,{headers:df(QQ,bT)});if(!C.ok||!C.body){if(C.status===401){if(xhA()){R(`SSE 401: ntok_ 已刷新,正在用 .anet/nodes/${BA}/config.json 里的新 token 重试`),I.markStable();return}OC("SSE 401: ntok_ 已失效(hub DB 可能被重置或 token 被撤销)。试 `anet doctor --fix`")}else R(`SSE failed: ${C.status}`);return}let E=C.body.getReader(),g=new TextDecoder,U="",J=!1;while(!J){let{done:Y,value:F}=await E.read();if(Y)break;U+=g.decode(F,{stream:!0});let G=U.split(`
|
|
422
|
+
`)}catch{}},C=!1,E=[];async function g(){if(C)return;C=!0;while(E.length){let{msg:U,updateId:J}=E.shift();try{await mmA(Q,U),Q.offset=J+1,I()}catch(Y){OC(`TG handle: ${Y.message}`)}}C=!1}j(`Telegram polling: ${A.dir}`);while(!0)try{let J=await(await PN((Y)=>fetch(`${Q.apiBase}/getUpdates?offset=${Q.offset}&timeout=30`,{signal:Y}),ShA,"telegram-getUpdates")).json();if(!J.ok)throw Error(J.description||"getUpdates failed");for(let Y of J.result||[])if(Q.offset=Y.update_id+1,Y.message){let F=Y.message,G=MUA(F),$=F.text||F.caption||"";if(j(`← TG [${G}] ${$.slice(0,80)}${F.photo?" +img":""}${F.document?" +file":""}`),F.chat?.id&&F.message_id)gX(Q,"setMessageReaction",{chat_id:F.chat.id,message_id:F.message_id,reaction:[{type:"emoji",emoji:E.length>0?"⏳":"\uD83D\uDC40"}]}).catch(()=>{});E.push({msg:F,updateId:Y.update_id}),g()}}catch(U){R(`Telegram polling error: ${U.message}`),await new Promise((J)=>setTimeout(J,3000))}}async function wgA(A=60000){VP=!0;let Q=Date.now();try{await Promise.race([dT,new Promise((I)=>setTimeout(I,A))])}catch{}let B=Date.now()-Q;j(`[config-apply] drained in-flight think (${B}ms${B>=A?`, hard-cap ${A}ms hit`:""})`)}async function LUA(){let A="";try{let B=(await ZA("get_config_update",{}))?.update;if(!B){HA("[config-apply] no pending update for this node");return}if(A=B.update_id,j(`[config-apply] pulled ${A} mode=${B.apply_mode}`),B.apply_mode==="restart_only"){try{await ZA("ack_config_update",{update_id:A,status:"restarting"})}catch(Y){R(`[config-apply] restart_only ack restarting failed (continuing to exit): ${Y?.message||Y}`)}await wgA(),await CX("config restart_only"),j(`[config-apply] exiting with RESTART_SENTINEL=${w$} for parent supervisor`),process.exit(w$)}let I=Qh(B.patch,{runtime:w?.runtime});if(I){R(`[config-apply] local validate rejected ${A}: ${I.field}=${I.reason}`),await ZA("ack_config_update",{update_id:A,status:"rejected",error:`local validate: ${I.field}=${I.reason}`});return}let C=Bh(B.patch,{runtime:w?.runtime,opencodeGeneration:w?.opencodeGeneration,requestedMode:B.apply_mode,hotModelSwitchAvailable:GB?.isRunning===!0&&typeof GB.setSelectedModel==="function"});if(C!==B.apply_mode)R(`[config-apply] mode mismatch hub=${B.apply_mode} local=${C}; trusting local for safety`);let E=C;if(!QA){R(`[config-apply] no configFilePath (node started without --config); rejecting ${A}`),await ZA("ack_config_update",{update_id:A,status:"rejected",error:"no config file path on this node — start with --config to enable remote apply"});return}if(E==="hot"&&B.patch.model&&r==="opencode"&&zB==="v2"){let Y=GB;if(!Y?.isRunning||!Y.setSelectedModel){await ZA("ack_config_update",{update_id:A,status:"rejected",error:"OpenCode V2 session is not running; model was not changed"});return}try{await HP(Y.setSelectedModel(B.patch.model),ZX,`OpenCode session model switch timed out after ${ZX}ms`)}catch($){let D=String($?.message||$).slice(0,400);R(`[config-apply] OpenCode V2 model switch failed: ${D}`);try{await ZA("ack_config_update",{update_id:A,status:"rejected",error:`OpenCode session model switch failed: ${D}`},0)}catch(N){R(`[config-apply] ack rejected failed: ${N?.message||N}`)}return}let F=$j(QA),G=wH(w,{model:B.patch.model});Gj(QA,G),Dj(QA,B.patch.model),QJ=B.patch.model,w=G,JG+=1,await ZA("ack_config_update",{update_id:A,status:"applied",new_revision:JG}),j(`[config-apply] OpenCode V2 session model=${B.patch.model} (no restart, .prev backedUp=${F.backedUp})`),qQ(KB.status,KB.task).catch(()=>{});return}let g=r==="opencode"?$j(QA):gh(QA),U=wH(w,B.patch);if(r==="opencode")Gj(QA,U);else YQ(QA,U);let J=B.patch.flags?.modelReasoningEffort;if(J!==void 0&&U.runtime==="codex-app-server"&&QA){let Y=AC(QA),{codexHome:F}=q7({nodeDir:Y,config:U,exists:WI});if(wj(J))ol(F,J),j(`[config-apply] wrote ${NA(F,"config.toml")} (model_reasoning_effort)`)}if(j(`[config-apply] wrote ${QA} (.prev backedUp=${g.backedUp})`),E==="hot"){w=U,KV(w.daemonExtraPath),JG+=1,await ZA("ack_config_update",{update_id:A,status:"applied",new_revision:JG}),j(`[config-apply] HOT applied ${A} → revision=${JG}`);return}try{await ZA("ack_config_update",{update_id:A,status:"restarting"})}catch(Y){R(`[config-apply] restart ack restarting failed (continuing to exit): ${Y?.message||Y}`)}await wgA(),await CX("config restart"),j(`[config-apply] exiting with RESTART_SENTINEL=${w$} for parent supervisor`),process.exit(w$)}catch(Q){if(OC(`[config-apply] failed: ${Q?.message||Q}`),A)try{await ZA("ack_config_update",{update_id:A,status:"rejected",error:`apply runtime: ${String(Q?.message||Q).slice(0,500)}`})}catch(B){R(`[config-apply] ack rejected failed: ${B?.message||B}`)}}}async function dmA(){await LUA()}var Dg=new Set,lW=new Set,pW=new Set;async function nmA(){let A=`${sA}/events/${encodeURIComponent(BA)}`,Q=3600000,B=!0;await WH({label:"sse",shutdownGate:()=>!1,abandonAfterMs:3600000,onAbandon:()=>OC(ly(BA,sA)),onRetryWait:(I)=>HA(`SSE reconnecting (${(I/1000).toFixed(1)}s)...`),firstRetrySpreadMs:8000,onError:(I)=>R(`SSE error: ${I?.message||I}`),runOnce:async(I)=>{HA(`SSE connecting: ${A}`);let C=await fetch(A,{headers:df(QQ,bT)});if(!C.ok||!C.body){if(C.status===401){if(xhA()){R(`SSE 401: ntok_ 已刷新,正在用 .anet/nodes/${BA}/config.json 里的新 token 重试`),I.markStable();return}OC("SSE 401: ntok_ 已失效(hub DB 可能被重置或 token 被撤销)。试 `anet doctor --fix`")}else R(`SSE failed: ${C.status}`);return}let E=C.body.getReader(),g=new TextDecoder,U="",J=!1;while(!J){let{done:Y,value:F}=await E.read();if(Y)break;U+=g.decode(F,{stream:!0});let G=U.split(`
|
|
423
423
|
`);U=G.pop()||"";for(let $ of G){if(!$.startsWith("data: "))continue;try{let D=JSON.parse($.slice(6)),N=nf(D);if(N){J=!0;let V=rW.onSuperseded(N,Date.now());if(V.kind==="back_off")OC(of(BA,bT,N,V.waitMs,V.streak)),I.deferNextAttempt(V.waitMs);else j(`SSE stream replaced by this process's own reconnect (${N.reason}); reconnecting`);break}if(D.type==="connected"){if(j("SSE connected"),rW.noteConnected(Date.now()),I.markStable(),!B)j("re-registering after SSE reconnect"),UP().catch((V)=>R(`re-register failed: ${V?.message||V}`));if(B=!1,CJ(),nT(),ZI?.trigger("sse-reconnect"),sX(YgA()).catch((V)=>R(`[rules-file] connect catch-up failed: ${V?.message||V}`)),Zg&&w.node_id&&w.network_id)Promise.resolve().then(() => (wO(),RO)).then(({reconcileNodeSecrets:V})=>V({callCommHub:ZA,nodeDir:Zg,nodeId:SA,networkId:HQ,warn:R})).catch(()=>R("[node-secrets] module unavailable"));if(w.role==="host_supervisor")Promise.resolve().then(() => (TO(),OO)).then(({reconcileScopedSecrets:V})=>V({callCommHub:ZA,workDir:process.cwd(),alias:BA,networkId:HQ,daemonId:SA,warn:R})).catch(()=>R("[daemon-secrets] module unavailable")),Promise.resolve().then(() => (lO(),cO)).then(({reconcileProviderSnapshots:V})=>V({callCommHub:ZA,workDir:process.cwd(),alias:BA,networkId:HQ,daemonId:SA,serverUrl:sA,warn:(Z)=>R(Z)})).catch(()=>R("[daemon-provider] readback module unavailable")),Promise.resolve().then(() => (BB(),BU)).then(({handleCreateNodeDoorbell:V,reconcilePendingCreateRequestsOnConnect:Z,serializeEnvLocalDaemon:W})=>{Z({callCommHub:ZA,recentlyHandledRequestIds:Dg,log:(X)=>j(X),warn:(X)=>R(X),handleCloneNodeDoorbell:(X)=>Promise.resolve().then(() => (dO(),iO)).then(({handleCloneNodeDoorbell:L})=>L(X,{callCommHub:ZA,workDir:process.cwd(),hubUrl:sA,log:(M)=>j(M),warn:(M)=>R(M),serializeEnvLocal:W,allowedRuntimes:Array.isArray(w.allowed_runtimes)?w.allowed_runtimes:null})),handleCreateNodeDoorbell:(X)=>V(X,{callCommHub:ZA,workDir:process.cwd(),hubUrl:sA,providerScope:{alias:BA,networkId:HQ,daemonId:SA},log:(L)=>j(L),warn:(L)=>R(L),serializeEnvLocal:W,allowedRuntimes:Array.isArray(w.allowed_runtimes)?w.allowed_runtimes:null})}).catch((X)=>R(`create-node pending reconcile failed: ${X?.message||X}`))}).catch((V)=>R(`create-node-daemon import for reconcile failed: ${V?.message||V}`));if(w.role==="host_supervisor")Promise.all([Promise.resolve().then(() => WEA),Promise.resolve().then(() => (qB(),dI)),Promise.resolve().then(() => (tO(),sO))]).then(([{reconcilePendingLifecycleRequestsOnConnect:V},{handleStopDoorbell:Z},{handleStartDoorbell:W}])=>{return V({callCommHub:ZA,log:(X)=>j(X),warn:(X)=>R(X),recentlyHandledStopRequestIds:lW,recentlyHandledStartRequestIds:pW,handleStopDoorbell:(X)=>Z(X,{adoption:cW(),callCommHub:ZA,workDir:process.cwd(),log:(L)=>j(L),warn:(L)=>R(L)}),handleStartDoorbell:(X)=>W(X,{adoption:cW(),callCommHub:ZA,workDir:process.cwd(),log:(L)=>j(L),warn:(L)=>R(L)})})}).catch((V)=>R(`lifecycle pending reconcile failed: ${V?.message||V}`));continue}if(D.type==="new_message"&&r==="opencode"&&MI==="copresence")j(`← SSE ${D.type}`),nT();else if(["new_task","new_message","broadcast"].includes(D.type))j(`← SSE ${D.type}`),CJ();if(D.type==="new_reply")j(`← SSE reply from ${D.from||"?"}${D.in_reply_to?` (task ${D.in_reply_to.slice(0,8)})`:""}`),xl(D,CJ);if(D.type==="session_control")XN?.trigger();if(D.type==="config_update")j(`← SSE config_update ${D.update_id||""}`),LUA().catch((V)=>R(`config-apply failed: ${V?.message||V}`));if(D.type==="rules_file")j("[rules-file] doorbell received"),sX(YgA()).catch((V)=>R(`[rules-file] doorbell handler failed: ${V?.message||V}`));if(D.type==="restart")j(`← SSE restart ${D.update_id||""}`),dmA().catch((V)=>R(`restart-apply failed: ${V?.message||V}`));if(D.type==="external_schedule_edit")j(`← SSE external_schedule_edit ${D.intent_id||""}`),JX?.trigger();if((D.type==="adopt_node"||D.type==="unadopt_node")&&w.role==="host_supervisor"){let V=typeof D.request_id==="string"?D.request_id:"";if(!V)continue;let Z={callCommHub:ZA,workDir:process.cwd(),home:process.env.HOME||"",hubUrl:sA,networkId:HQ,uid:process.getuid?.()??-1,daemonEnv:process.env,adoptRoots:Array.isArray(w.adopt_roots)?w.adopt_roots:[],warn:(W)=>R(W)};Promise.resolve().then(() => (y7(),uu)).then(async({handleAdoptDoorbell:W,handleUnadoptDoorbell:X})=>{if(D.type==="adopt_node")await W({request_id:V},Z);else if(typeof D.node_id==="string")await X({request_id:V,node_id:D.node_id},Z)}).catch(()=>R("[adopt-daemon] protocol operation failed; no process action taken"))}if(D.type==="create_node"&&w.role==="host_supervisor"){let V=typeof D.request_id==="string"?D.request_id:"";if(!V||Dg.has(V))continue;Dg.add(V),j(`← SSE create_node ${V}`),Promise.resolve().then(() => (BB(),BU)).then(({handleCreateNodeDoorbell:Z,serializeEnvLocalDaemon:W})=>{Z({request_id:V},{callCommHub:ZA,workDir:process.cwd(),hubUrl:sA,providerScope:{alias:BA,networkId:HQ,daemonId:SA},log:(X)=>j(X),warn:(X)=>R(X),serializeEnvLocal:W,allowedRuntimes:Array.isArray(w.allowed_runtimes)?w.allowed_runtimes:null}).catch((X)=>{Dg.delete(V),R(`create-node-daemon failed: ${X?.message||X}`)})}).catch((Z)=>{Dg.delete(V),R(`create-node-daemon import failed: ${Z?.message||Z}`)})}if(D.type==="clone_node"&&w.role==="host_supervisor"){let V=typeof D.request_id==="string"?D.request_id:"";if(!V||Dg.has(V))continue;Dg.add(V),j(`← SSE clone_node ${V}`),Promise.all([Promise.resolve().then(() => (dO(),iO)),Promise.resolve().then(() => (BB(),BU))]).then(([{handleCloneNodeDoorbell:Z},{serializeEnvLocalDaemon:W}])=>{return Z({request_id:V},{callCommHub:ZA,workDir:process.cwd(),hubUrl:sA,log:(X)=>j(X),warn:(X)=>R(X),serializeEnvLocal:W,allowedRuntimes:Array.isArray(w.allowed_runtimes)?w.allowed_runtimes:null})}).catch((Z)=>{Dg.delete(V),R(`clone-node failed: ${Z?.message||Z}`)})}if(D.type==="stop_node"&&w.role==="host_supervisor"){j(`← SSE stop_node ${D.request_id||""}`);let V=D.request_id;if(V&&!lW.has(V))lW.add(V),Promise.resolve().then(() => (qB(),dI)).then(({handleStopDoorbell:Z})=>Z({request_id:V},{adoption:cW(),callCommHub:ZA,workDir:process.cwd(),log:(W)=>j(W),warn:(W)=>R(W)})).catch((Z)=>{lW.delete(V),R(`stop-daemon failed: ${Z?.message||Z}`)})}if(D.type==="start_node"&&w.role==="host_supervisor"){j(`← SSE start_node ${D.request_id||""}`);let V=D.request_id;if(V&&!pW.has(V))pW.add(V),Promise.resolve().then(() => (tO(),sO)).then(({handleStartDoorbell:Z})=>Z({request_id:V},{adoption:cW(),callCommHub:ZA,workDir:process.cwd(),log:(W)=>j(W),warn:(W)=>R(W)})).catch((Z)=>{pW.delete(V),R(`start-daemon failed: ${Z?.message||Z}`)})}if(D.type==="daemon_provider_snapshot"&&w.role==="host_supervisor")Promise.resolve().then(() => (lO(),cO)).then(({reconcileProviderSnapshots:V})=>V({callCommHub:ZA,workDir:process.cwd(),alias:BA,networkId:HQ,daemonId:SA,serverUrl:sA,warn:(Z)=>R(Z)})).catch(()=>R("[daemon-provider] readback module unavailable"));if(D.type==="node_secrets"&&Zg&&w.node_id&&w.network_id)Promise.resolve().then(() => (wO(),RO)).then(({reconcileNodeSecrets:V})=>V({callCommHub:ZA,nodeDir:Zg,nodeId:SA,networkId:HQ,warn:R})).catch(()=>R("[node-secrets] module unavailable"));if(D.type==="scoped_secrets"&&w.role==="host_supervisor")Promise.resolve().then(() => (TO(),OO)).then(({reconcileScopedSecrets:V})=>V({callCommHub:ZA,workDir:process.cwd(),alias:BA,networkId:HQ,daemonId:SA,warn:R})).catch(()=>R("[daemon-secrets] module unavailable"));if(D.type==="probe_provider"&&w.role==="host_supervisor")j(`← SSE probe_provider ${D.probe_id||""}`),Promise.resolve().then(() => (hEA(),fEA)).then(({handleProbeDoorbell:V})=>{V({probe_id:D.probe_id},{callCommHub:ZA,log:(Z)=>j(Z),warn:(Z)=>R(Z)}).catch((Z)=>R(`probe-daemon failed: ${Z?.message||Z}`))}).catch((V)=>R(`probe-daemon import failed: ${V?.message||V}`));if(D.type==="opencode_catalog"&&w.role==="host_supervisor")j(`← SSE opencode_catalog ${D.request_id||""}`),Promise.resolve().then(() => (aEA(),oEA)).then(({handleOpenCodeCatalogDoorbell:V})=>{V({request_id:D.request_id},{callCommHub:ZA,daemonWorkDir:process.cwd(),log:(Z)=>j(Z),warn:(Z)=>R(Z)}).catch((Z)=>R(`opencode-catalog failed: ${Z?.message||Z}`))}).catch((V)=>R(`opencode-catalog import failed: ${V?.message||V}`))}catch{}}}if(J)try{await E.cancel()}catch{}}})}j("启动");j(` alias: ${BA||"(none!)"} [from: ${whA}]`);j(` runtime: ${r}${EJ===r?"":` (input: ${EJ})`}`);var omA=jQ||(r==="grok"?"configured by Grok CLI":r==="codex"||r==="codex-app-server"?gj:"(account default)");j(` model: ${omA} ${!jQ&&(r==="codex"||r==="codex-app-server")?"(default)":""}`);j(` hub: ${sA}${QQ?" (auth)":" (no auth!)"}`);j(` instance: ${bT}`);if(r==="grok"&&AQ==="acp"){let A=G9({envValue:process.env.GROK_ACP_TIMEOUT_MS,flagValue:w.flags?.grokAcpTimeoutMs,defaultMs:300000}),Q=A.source==="flags"?"flags.grokAcpTimeoutMs":A.source==="env"?"env GROK_ACP_TIMEOUT_MS":"default";j(` [grok] session/prompt idle timeout = ${A.valueMs}ms (source: ${Q})`)}else if(r==="grok"){let A=process.env.GROK_CLI_TIMEOUT_MS||w.flags?.grokCliTimeoutMs||"300000";j(` [grok-cli] execution mode=${LB?"co-presence TUI":"headless TUI engine"}; idle timeout=${A}ms`)}if(QQ)try{let A=await fetch(`${sA}/api/auth/me`,{headers:{Authorization:`Bearer ${QQ}`}}).then((Q)=>Q.json()).catch(()=>null);if(A?.ok&&A.user)if(j(` user: ${A.user.username} (${A.user.role})`),A.current_network){let Q=A.networks?.find((B)=>B.network_id===A.current_network)?.network_name;j(` network: ${Q||A.current_network}`)}else j(` network: ${HQ||"(global)"}`);else if(A?.ok===!1)j(` network: ${HQ||"(global)"}`);else R(" token 验证失败 — 检查 token 是否有效。运行: anet login")}catch{j(` network: ${HQ||"(global)"}`)}else R(" 未配置 token — agent 数据不隔离。运行: anet login");var amA=Array.isArray(NE)?NE.length?`[${NE.join(",")}]`:"(none)":"all (Claude Code preset — built-in: WebFetch/WebSearch/Bash/Read/Write/Edit/Glob/Grep/Task/...)";j(` tools: ${LB?HN==="x-search"?"fixed x-search profile [todo_write,search_tool,use_tool,web_search] (general web; no web-fetch/filesystem/shell/media/subagents)":HN==="repo-read"?"fixed repo-read profile [todo_write,search_tool,use_tool,read_file,grep,list_dir] (strict CWD reads; no shell/write/web/media/subagents)":"fixed commhub-only profile [todo_write,search_tool,use_tool] (no filesystem/shell/web/media/subagents)":amA}`);j(` channels:${[sW.length?`telegram(${sW.map((A)=>A.dir).join(",")})`:"",tW.length?`feishu(${tW.map((A)=>A.dir).join(",")})`:""].filter((A)=>A).join(" ")||" (none)"}`);j(` session: ${$B||"(new)"}`);j(` log-dir: ${gJ}`);j(` goals: ${QP}`);var iW=await TC.load();if(!iW.ok)R(` goals load recovered: ${iW.error||"unknown"}${iW.recovered?` (${iW.recovered})`:""}`);var zUA=await TC.list(),qgA=zUA.filter((A)=>A.status==="active");if(qgA.length)j(` goals active: ${qgA.length}`);var aT=C9(r),NN=xy(aT,zUA),OgA=NN.runScheduler;switch(NN.kind){case"ok":j(` goals scheduler: enabled (runtime=${aT})`);break;case"skip":j(` goals scheduler: skipped — ${NN.reason}`);break;case"archive":{R(` goals scheduler: ${NN.reason}`);let A=await TC.archiveAndClear(NN.reason);if(A)R(` goals archived → ${A}`);else R(" goals archive skipped — no file to back up");j(` goals scheduler: enabled (runtime=${aT}, fresh store)`);break}}if(LB)await NUA();if(r==="codex"||r==="codex-app-server"){let A=eB||(process.env.CODEX_HOME&&process.env.CODEX_HOME.trim()?process.env.CODEX_HOME.trim():NA(sT(),".codex"));try{let Q=VS(process.env);oW=NS({nodeDir:yI,alias:BA,codexHome:A,nodeId:SA||null,say:R,minIntervalMs:Q}),oW.refresh(),setInterval(()=>{try{if(oW?.tick())qQ(KB.status,KB.task).catch(()=>{})}catch{}},Q).unref?.()}catch(Q){R(`[codex] shared-login check skipped: ${Q?.message||Q}`)}}await UP();j("已注册到 CommHub");if(r==="codex-app-server"&&DE)try{let A=await YJ();j(`[codex-app-server] client-health role=bridge remote=${DE} thread=${A.threadId}`)}catch(A){OC(`[codex-app-server] shared bridge startup failed: ${A?.message||A}`),await qQ("offline").catch(()=>{}),process.exit(1)}if(WQ?.load().length)FUA();if(WQ?.load().some((A)=>A.version===2))$UA();if(WQ)setInterval(()=>{if(WQ.load().length)FUA();if(WQ.load().some((A)=>A.version===2))$UA()},30000).unref?.();if(r==="codex-app-server"){let A=Ap(process.platform,process.env,BA),Q=process.env.ANET_COPRESENCE_BRIDGE==="1"&&!!DE,B=Q&&A?Wp(A):void 0,I=process.env.ANET_NODE_MARKER||void 0,C=null,E=()=>{if(!B||!DE||process.platform!=="linux")return;let J=vj({session:B,url:DE,marker:I,panes:mY(),proc:JU,sessionId:MD(B)});if(J.ok&&J.snapshot.pid!==C?.pid)C=J.snapshot,j(`[app-server-watchdog] launch snapshot tmux=${J.snapshot.session} pid=${J.snapshot.pid} argv0=${J.snapshot.argv[0]}`);else if(!J.ok&&!C)R(`[app-server-watchdog] no launch snapshot yet: ${J.reason}`)};E();let g=()=>{if(process.platform!=="linux")return`co-presence app-server auto-restart needs Linux /proc (this host is ${process.platform})`;if(!eB)return"this node has no CODEX_HOME";if(QA&&!Kp(NA(AC(QA),"copresence-identity.json"),I))return"co-presence identity marker is gone or replaced (node is being stopped or restarted)";return null},U=Vp(process.env);nW=Dp({...Np(process.env),canRestart:()=>{if(AX)return"node is shutting down";if(!Q)return null;return g()??bj(C,{marker:I,token:QQ,panes:mY,proc:JU})},appServerAlive:()=>!AX&&Q&&!g()&&!!C&&QQ.startsWith("ntok_")&&yj(C,{marker:I,proc:JU}),canKillHung:()=>{if(!eB)return"this node has no CODEX_HOME";return fj(C,{marker:I,codexHome:eB,panes:mY,proc:JU,sessionId:MD})},restart:async(J,Y)=>{if(Y?.killHung&&C&&eB){let G=await Xp(C,Mp({codexHome:eB,marker:I,graceMs:U,log:j}));j(`[app-server-watchdog] hung app-server stopped (${G}); relaunching on the original session`)}if(Q&&C&&eB){let G=await F4("codex app-server relaunch",{nodeId:SA||void 0,log:j,warn:R});try{C=await Lp(C,zp({codexHome:eB,marker:I,token:QQ,log:j}))}finally{G.release()}}tU.invalidate(tU.current());let F=await YJ();j(`[app-server-watchdog] bridge re-attached ${F.url??"?"} thread=${F.threadId}`)},onSettled:()=>{setTimeout(()=>{eU?.tick()},500).unref?.()},log:j,warn:R}),eU=Bp({appServerUrl:()=>DE||tU.current()?.url||fT,intervalMs:Qp(process.env),appServerWasUp:()=>ogA,onAppServerProbe:(J)=>{if(J.ok)E();return nW?nW.observe(J):J},tuiSession:A,probeNativeTui:process.platform==="win32"&&process.env.ANET_COPRESENCE_BRIDGE==="1"&&I&&SA?async()=>{let J=DE||tU.current()?.url||fT;if(!J)return;let Y=Ip(NA(yI,"windows-tui-health.json"),{nodeId:SA,marker:I,remote:J});return Y?Cp(Y):void 0}:void 0,modelAuth:jN,probeAppServer:async(J)=>{let{resolveWebSocketCtor:Y}=await Promise.resolve().then(() => (iw(),WQA));return el(J,{wsCtor:Y()})},authFileMtimeMs:()=>{if(!eB)return null;try{return ngA(NA(eB,"auth.json")).mtimeMs}catch{return null}},onChange:(J)=>{j(`[health] app_server=${J.app_server?J.app_server.ok?"ok":`down(${J.app_server.last_error??"?"})`:"-"} tui=${J.tui?J.tui.ok?"ok":J.tui.reason:"-"} model_auth=${J.model_auth}`),qQ(KB.status,KB.task).catch(()=>{})}}),eU.start()}var rmA=w?.flags?.sideThreads===!0||process.env.ANET_ENABLE_SIDE_THREADS==="1";if(rmA)if(r!=="codex-app-server"||!SA||!process.env.CODEX_HOME)MN={supported:!1,runtime:EJ,runtimeVersion:"unknown",topology:"unknown",evidenceRevision:"test1190-wire-v2",reason:"runtime"},R("[side-thread] enable requested but codex-app-server, stable node_id, or dedicated CODEX_HOME is unavailable");else{let A={...KB};try{let Q=await YJ(),{openCodexAppServerRuntime:B}=await Promise.resolve().then(() => (v2(),k2)),I=Q.threadId,{selectOwnedSideThreadSession:C}=await Promise.resolve().then(() => rEA),E=await C(Q,()=>B({threadId:I,approvalPolicy:w.flags?.approvalPolicy,sandboxMode:w.flags?.sandboxMode,commhubMcpUrl:`${sA.replace(/\/+$/,"")}/mcp`,commhubToken:QQ||void 0,codexHome:eB,startGate:JUA(),log:(Y)=>j(`[side-thread-owned] ${Y}`),warn:(Y)=>R(`[side-thread-owned] ${Y}`)})),g=E.session;if(E.dedicated)iT=g;let{startCliSideThreadConsumer:U,detectCodexRuntimeVersion:J}=await Promise.resolve().then(() => (u0A(),m0A));pT=U({enabled:!0,client:g.client,hubUrl:sA,nodeId:SA,token:()=>QQ,codexHome:process.env.CODEX_HOME,runtimeVersion:J(),topology:"owned-stdio",experimentalApi:w?.flags?.sideThreadExperimentalApi===!0,log:j,warn:R}),MN=pT.capability}catch(Q){MN={supported:!1,runtime:"codex-app-server",runtimeVersion:"unknown",topology:"unknown",evidenceRevision:"test1190-wire-v2",reason:"runtime"},R(`[side-thread] startup failed closed: ${Q?.message||Q}`)}finally{YUA(A)}}var JX=null;try{if(JX=Ky({enabled:AP,hubUrl:sA,token:()=>QQ,nodeId:SA||"",configPath:QA,log:(A)=>R(`[owner-schedule] ${A}`)}),JX.enabled)j(" owner schedule control: enabled (process-pinned)")}catch(A){OC(`[owner-schedule] startup refused: ${A?.message||A}`),process.exit(1)}CJ();nT();ZI?.trigger("startup");qQ("idle").catch((A)=>R(`initial reportStatus failed: ${A?.message||A}`));var KUA=(()=>{let A=Number(process.env.ANET_STATUS_HEARTBEAT_MS);if(Number.isFinite(A)&&A>=200&&A<=180000)return A;return 180000})(),TgA=(()=>{let A=Number(process.env.ANET_STATUS_HEARTBEAT_JITTER_MS);if(Number.isFinite(A)&&A>=0&&A<=60000)return A;return Math.min(30000,Math.round(KUA*0.2))})(),smA=()=>{let A=KB;if(A.status==="working"&&typeof A.task==="string"&&A.task.startsWith("模型满载,")){qQ("working",A.task).catch(()=>{});return}if(Vg){qQ("working",Vg).catch(()=>{});return}qQ("idle").catch(()=>{})},HUA=()=>{let A=TgA>0?Math.floor(Math.random()*TgA):0;setTimeout(()=>{smA(),HUA()},KUA+A)?.unref?.()};HUA();if(r==="opencode"&&zB==="v2"&&MI==="copresence"){if(setInterval(()=>{EUA()},EmA).unref(),XN){let A=()=>{XN.register().then((B)=>{if(B)XN.trigger()})};A();let Q=()=>{setTimeout(()=>{A(),Q()},30000+Math.floor(Math.random()*9000))?.unref?.()};Q()}}if(w.role==="host_supervisor")Promise.resolve().then(() => (nO(),zEA)).then((A)=>{hT=A.createCodexForkCapabilityMonitor({cwd:process.cwd(),onChange:()=>{qQ(KB.status,KB.task).catch(()=>{})}}),hT.start()}).catch(()=>R("[codex-fork-capability] init unavailable")),Promise.all([Promise.resolve().then(() => (ED(),zc)),Promise.resolve().then(() => (BB(),BU))]).then(([A,Q])=>{let B=A.createRuntimeReadinessMonitor({runtimes:()=>{let I=w?.runtimes_supported;return Array.isArray(I)?I.filter((C)=>typeof C==="string"):[]},deps:()=>A.realReadinessDeps({childEnv:Q.minimalEnv()}),intervalMs:A.readinessIntervalFromEnv(process.env),warn:(I)=>R(I),onChange:(I)=>{let C=Object.entries(I).map(([E,g])=>`${E}=${g.state}`).join(" ");j(`[runtime-readiness] ${C}`),qQ(KB.status,KB.task).catch(()=>{})}});rgA=B,B.start()}).catch((A)=>R(`[runtime-readiness] init failed: ${A?.message||A}`)),Promise.resolve().then(() => (d0A(),i0A)).then(({startDeletedSweeper:A})=>{A({log:(Q)=>j(Q),warn:(Q)=>R(Q)}),j("[deleted-sweeper] started (every 24h, retention 30d)")}).catch((A)=>R(`deleted-sweeper import failed: ${A?.message||A}`)),setTimeout(()=>{Promise.resolve().then(() => (qB(),dI)).then(({rebuildChildrenMapOnBoot:A})=>{A({callCommHub:ZA,workDir:process.cwd(),log:(Q)=>j(Q),warn:(Q)=>R(Q)}).catch((Q)=>R(`rebuildChildrenMapOnBoot failed: ${Q?.message||Q}`))}).catch((A)=>R(`stop-daemon import for rebuild failed: ${A?.message||A}`))},3000);Promise.resolve().then(() => (HO(),KO)).then(({startAttachmentCacheSweeper:A})=>{let Q=NA(yB,".anet","cache","attachments",BA||"default");A({cacheDir:Q,log:(B)=>j(B),warn:(B)=>R(B)}),j(`[attachment-cache] sweeper started (hourly tick, 24h TTL, dir=${Q})`)}).catch((A)=>R(`attachment-cache sweeper import failed: ${A?.message||A}`));if(OgA&&!z$(w.role))setInterval(()=>NgA().catch(()=>{}),khA),NgA().catch(()=>{});else if(OgA&&z$(w.role))j("[goals] scheduler suppressed — host_supervisor daemon runs no LLM turns");var VN=null;if(r==="codex"||r==="grok"||r==="codex-app-server")try{let{startLoopsHttpServer:A}=await Promise.resolve().then(() => (o0A(),n0A)),Q=parseInt(process.env.COMMHUB_MAX_GOALS_PER_NODE||"",10),B=process.env.LOOPS_MCP_TOKEN||void 0;VN=await A({ctx:{store:TC,runtime:EJ,defaultTz:w?.flags?.timezone||"Asia/Shanghai",maxActiveGoals:Number.isFinite(Q)&&Q>0?Q:void 0,recentCancels:cgA,pendingConfirmTokens:lgA},token:B}),process.env.LOOPS_MCP_TOKEN=VN.token,process.env.LOOPS_MCP_URL=VN.url,j(`[loops] HTTP MCP server bound to ${VN.url} (${r} self-loop tools)`)}catch(A){R(`[loops] HTTP MCP server failed to start (${A?.message??A}); ${r} self-loop tools unavailable`)}var PgA=!1,ZP=async()=>{if(PgA)return;PgA=!0,AX=!0,JX?.stop(),pT?.close(),iT?.client.close(),iT?.proc?.kill("SIGTERM"),j("shutting down..."),await Promise.resolve().then(() => (fO(),tCA)).then((Q)=>Q.closeProviderLogins()).catch(()=>{}),await CX("signal shutdown"),await B0?.close().catch((Q)=>{R(`[grok-copresence] close failed: ${Q?.message||Q}`)});for(let Q of EX)Q.abort();let A=Date.now()+1500;while(EX.size>0&&Date.now()<A)await new Promise((Q)=>setTimeout(Q,25));oT=!0;for(let Q of UX)try{Q.kill("SIGTERM")}catch{}setTimeout(()=>{for(let Q of UX)try{Q.kill("SIGKILL")}catch{}},500);try{await VN?.close()}catch{}ZI?.stop(),await qQ("offline").catch(()=>{}),process.exit(0)};process.on("SIGINT",ZP);process.on("SIGTERM",ZP);process.on("SIGHUP",ZP);if(r==="opencode"&&MI==="copresence")try{await NP()}catch(A){console.error(`[${BA}] OpenCode copresence startup failed: ${A?.message??A}`),await CX("startup failure"),process.exit(1)}for(let A of sW)imA(A);for(let A of tW)cmA(A);nmA();if(w.telegram?.watchdog===!0){let A=w.env?.TELEGRAM_STATE_DIR;if(!A)R("telegram.watchdog enabled but TELEGRAM_STATE_DIR not set in config.env — "+"watchdog cannot locate bot.pid. Either unset telegram.watchdog or add env.TELEGRAM_STATE_DIR.");else try{cy({stateDir:A,alias:BA,commhubUrl:sA,commhubToken:QQ},(Q)=>j(`[telegram-watchdog] ${Q}`))}catch(Q){R(`telegram-watchdog start failed: ${Q?.message??String(Q)}`)}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sleep2agi/agent-node",
|
|
3
|
-
"version": "2.5.0-preview.
|
|
3
|
+
"version": "2.5.0-preview.164",
|
|
4
4
|
"description": "AI Agent runtime for CommHub networks. Supports Claude Code CLI, Claude Agent SDK, Codex SDK, Codex app-server, Grok Build ACP, and OpenCode CLI.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"agent-node": "dist/cli.js"
|