@sleep2agi/agent-node 2.5.0-preview.10 → 2.5.0-preview.11
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 +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -127,7 +127,7 @@ ${B}`;break;case"retry":if(O3(B))Q[C]=B;break;case"id":if(P3(B))Q[C]=B;break;cas
|
|
|
127
127
|
`));return I.name="CodexSdkUnavailable",I}function iF(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 UM(A){return/[^A-Za-z0-9_\-./@~]/.test(A)?`'${A.replace(/'/g,"'\\''")}'`:A}function JM(A){return async(Q,I)=>{let C=I.map(UM).join(" "),B=`npm install --no-save --prefix ${UM(Q)} ${C}`;A(B,{stdio:"pipe",timeout:90000})}}async function E6(A,Q,I={}){let C=Math.max(1,Math.min(100,I.limit??100)),B=Math.max(1,Math.min(50,I.topN??10));try{let g=I.serverSupportsFromNodeId===!0&&!!A.nodeId?{from_node_id:A.nodeId,limit:C}:{from_name:A.alias,limit:C},D=await Q(g),U=Array.isArray(D?.tasks)?D.tasks:[],F=(Y)=>{let J=typeof Y.from_node_id==="string"?Y.from_node_id:"",N=typeof Y.from_name==="string"?Y.from_name:"";if(J&&A.nodeId)return J===A.nodeId;if(N)return N===A.alias;return!1};return U.filter((Y)=>!!Y&&typeof Y.task_id==="string"&&typeof Y.to_name==="string"&&(Y.status==="delivered"||Y.status==="started")).filter(F).slice(0,B)}catch{return[]}}function g6(A){if(!A.length)return null;return["【⚠ 节点 resume 提醒 — 你停机前已派出但仍在等回复的任务】","",A.map((I,C)=>{let B=String(I.task_id||"?").slice(0,8),E=String(I.to_name||"?"),g=I.created_at?`, sent ${I.created_at}`:"",D=oT(I.content);return` ${C+1}. → ${E} [task ${B}${g}]: ${D}`}).join(`
|
|
128
128
|
`),"","重要约束 (do NOT re-dispatch):","- 上面这些任务 **已经发出去过**, 对方尚未回复。**不要再次** 用 commhub_send_task 发同样内容。",'- 如果需要跟进进度, 用 commhub_send_message(alias=对方, message="任务 <task_id> 进度?") 发一条**轻问询**, **不是** send_task。',"- server 端有自动去重护栏会拒绝重复 send_task, 但请不要靠它兜底 — 直接按上面规则处理。",'- 如果用户现在派的新任务跟上面某条**实质相同**, 直接告诉用户 "task <id> 已派给 <对方>, 仍在等回复, 不重新派", 不要 send_task。'].join(`
|
|
129
129
|
`)}function oT(A){let Q=String(A??"").replace(/```/g,"ʼʼʼ").replace(/\s+/g," ").trim(),I=120;return Q.length>120?Q.slice(0,117)+"...":Q||"(empty content)"}class NM{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 I=(async()=>{try{let C=await this.opts.fetchCanonicalAlias(this.opts.nodeId);if(C&&C.length>0&&C!==this.cachedAlias)this.opts.onDrift?.(this.cachedAlias,C,"fetch"),this.cachedAlias=C}catch(C){this.opts.warn?.(`currentAlias: fetch failed (${C?.message??C}); keeping cached value "${this.cachedAlias}"`)}finally{this.cachedAt=A,this.fetchInFlight=null}return this.cachedAlias})();return this.fetchInFlight=I,I}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 D6(A,Q,I){if(!Array.isArray(A))return{exists:!1,reason:"no_sessions_field"};if(A.length===0)return{exists:!1,reason:"empty_sessions"};let C=(Q??"").trim(),B=(I??"").trim();if(!C)return{exists:!1,reason:"not_in_sessions"};let E=!1;for(let g of A){let D=typeof g?.alias==="string"?g.alias.trim():"";if(!D)continue;if(D===C){if(D===B){E=!0;continue}return{exists:!0,source:"session"}}}return{exists:!1,reason:E?"self_only":"not_in_sessions"}}function xg(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 jI(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 GM(A,Q){let I=Q?.baseUrl;if(A.errorMessage){if(xg(A.errorMessage))return{kind:"soft-fail-quota",reason:A.errorMessage,hint:jI(I)};return{kind:"error",reason:A.errorMessage}}let C=A.usage??{},B=C.input_tokens??null,E=C.output_tokens??null,g=A.totalCostUsd??null;if(B===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:jI(I)};if(A.result===null||A.result===void 0||A.result==="")return{kind:"soft-fail-empty",reason:"empty vendor result despite success signal",hint:jI(I)};return{kind:"success"}}function wM(A,Q){let I=Q.usage?.input_tokens??0,C=Q.usage?.output_tokens??0;switch(A.kind){case"soft-fail-quota":return`执行出错: ${Q.runtime} 限流/配额耗尽 (${(A.reason||"").slice(0,80)})${A.hint?` — ${A.hint}`:""}`;case"soft-fail-empty":return`执行出错: ${Q.runtime} 返回空响应 (in=${I} out=${C}) — 疑似 vendor 静默限流/配额. ${A.hint||""}`.trim();case"error":return`执行出错: ${Q.runtime} — ${(A.reason||"未知错误").slice(0,200)}`;case"success":return""}}class lC extends Error{label;timeoutMs;constructor(A,Q){super(`${Q?`[${Q}] `:""}timed out after ${A}ms`);this.name="TimeoutError",this.label=Q,this.timeoutMs=A}}async function dF(A,Q,I,C){let B=new AbortController,E;if(C?.externalSignal)if(C.externalSignal.aborted)B.abort();else E=()=>B.abort(),C.externalSignal.addEventListener("abort",E,{once:!0});if(Q<=0)try{return await A(B.signal)}finally{if(E&&C?.externalSignal)C.externalSignal.removeEventListener("abort",E)}let g,D=new Promise((U,F)=>{g=setTimeout(()=>{B.abort(),F(new lC(Q,I))},Q)});try{return await Promise.race([A(B.signal),D])}finally{if(g)clearTimeout(g);if(E&&C?.externalSignal)C.externalSignal.removeEventListener("abort",E)}}function nF(A){let Q=A.minMs??0,I=A.maxMs??Number.MAX_SAFE_INTEGER,C=(E)=>{if(E<Q)return{value:Q,clamped:!0};if(E>I)return{value:I,clamped:!0};return{value:E,clamped:!1}};if(A.envValue!==void 0&&A.envValue!==null&&A.envValue!==""){let E=Number(A.envValue);if(Number.isFinite(E)&&E>=0){let g=C(E);return{valueMs:g.value,source:"env",clamped:g.clamped}}}if(typeof A.flagValue==="number"&&Number.isFinite(A.flagValue)&&A.flagValue>=0){let E=C(A.flagValue);return{valueMs:E.value,source:"flag",clamped:E.clamped}}let B=C(A.defaultMs);return{valueMs:B.value,source:"default",clamped:B.clamped}}var rT=(A)=>new Promise((Q)=>setTimeout(Q,Math.max(0,A)));async function $M(A){let Q=A.baseDelayMs??1000,I=A.maxDelayMs??30000,C=A.jitterRatio??0.25,B=A.abandonAfterMs??Number.POSITIVE_INFINITY,E=A.sleep??rT,g=A.random??Math.random,D=A.now??Date.now,U=Q,F=null;while(!A.shutdownGate()){let Y=!1,J={markStable(){if(Y)return;Y=!0,U=Q,F=null}};try{await A.runOnce(J)}catch(w){A.onError?.(w)}if(A.shutdownGate())break;if(!Y){if(F===null)F=D();if(D()-F>B){A.onAbandon?.();return}}let N=C>0?U*C*(g()*2-1):0,G=Math.max(100,Math.round(U+N));A.onRetryWait?.(G,U),await E(G),U=Math.min(U*2,I)}}import{existsSync as MM,copyFileSync as F6,readFileSync as U6,writeFileSync as aT,renameSync as tT,unlinkSync as sT}from"node:fs";var yg=75,Y6=new Set(["permissionMode","dangerouslySkipPermissions","maxTurns","budget","timeout"]),eT=new Set(["permissionMode","dangerouslySkipPermissions","timeout"]);function J6(A){if(A.model!==void 0){if(typeof A.model!=="string"||A.model.length===0||A.model.length>200)return{field:"model",reason:"must be a non-empty string ≤ 200 chars"}}let Q=A.flags||{};for(let[I,C]of Object.entries(Q)){if(!Y6.has(I))return{field:`flags.${I}`,reason:"not in local allowlist"};switch(I){case"permissionMode":if(typeof C!=="string"||!["default","auto","bypassPermissions","acceptEdits","plan"].includes(C))return{field:"flags.permissionMode",reason:"invalid enum"};break;case"dangerouslySkipPermissions":if(typeof C!=="boolean")return{field:`flags.${I}`,reason:"must be boolean"};break;case"maxTurns":if(typeof C!=="number"||!Number.isInteger(C)||C<0||C>1e4)return{field:"flags.maxTurns",reason:"must be int in [0, 10000]"};break;case"budget":if(typeof C!=="number"||C<0||C>1e6)return{field:"flags.budget",reason:"must be number in [0, 1_000_000]"};break;case"timeout":if(typeof C!=="number"||!Number.isInteger(C)||C<0||C>3600000)return{field:"flags.timeout",reason:"must be int ms in [0, 3_600_000]"};break}}return null}function N6(A){let Q=A.model!==void 0,I=A.flags||{},C=Object.keys(I);if(!Q&&C.length===0)return"restart_only";if(Q)return"restart";for(let B of C)if(eT.has(B))return"restart";return"hot"}function G6(A,Q){let I=`${A}.tmp.${process.pid}.${Date.now()}`;try{aT(I,JSON.stringify(Q,null,2)+`
|
|
130
|
-
`),tT(I,A)}catch(C){try{if(MM(I))sT(I)}catch{}throw C}}function w6(A){if(!MM(A))return{backedUp:!1};return F6(A,`${A}.prev`),{backedUp:!0}}function $6(A){let Q;try{let C=U6(A,"utf-8");return{config:JSON.parse(C),source:"primary"}}catch(C){Q=String(C?.message||C)}let I=`${A}.prev`;if(!MM(I))throw Error(`config.json parse failed (${Q}) and no .prev backup exists`);try{let C=U6(I,"utf-8"),B=JSON.parse(C);return F6(I,A),{config:B,source:"prev",primaryError:Q}}catch(C){throw Error(`config.json parse failed (${Q}); .prev parse also failed (${String(C?.message||C)})`)}}function M6(A,Q){let I=JSON.parse(JSON.stringify(A||{}));if(Q.model!==void 0)I.model=Q.model;if(Q.flags)I.flags={...I.flags||{},...Q.flags};return I}function V6(A,Q,I){let C={model:typeof A?.model==="string"?A.model:null,flags:{},config_revision:I,config_update_capable:Q,role:typeof A?.role==="string"?A.role:null},B=A?.flags||{};for(let
|
|
130
|
+
`),tT(I,A)}catch(C){try{if(MM(I))sT(I)}catch{}throw C}}function w6(A){if(!MM(A))return{backedUp:!1};return F6(A,`${A}.prev`),{backedUp:!0}}function $6(A){let Q;try{let C=U6(A,"utf-8");return{config:JSON.parse(C),source:"primary"}}catch(C){Q=String(C?.message||C)}let I=`${A}.prev`;if(!MM(I))throw Error(`config.json parse failed (${Q}) and no .prev backup exists`);try{let C=U6(I,"utf-8"),B=JSON.parse(C);return F6(I,A),{config:B,source:"prev",primaryError:Q}}catch(C){throw Error(`config.json parse failed (${Q}); .prev parse also failed (${String(C?.message||C)})`)}}function M6(A,Q){let I=JSON.parse(JSON.stringify(A||{}));if(Q.model!==void 0)I.model=Q.model;if(Q.flags)I.flags={...I.flags||{},...Q.flags};return I}function V6(A,Q,I){let C={model:typeof A?.model==="string"?A.model:null,flags:{},config_revision:I,config_update_capable:Q,role:typeof A?.role==="string"?A.role:null},B=A?.runtimes_supported;if(Array.isArray(B)&&B.every((D)=>typeof D==="string"))C.runtimes_supported=B;let E=A?.allowed_secret_keys;if(Array.isArray(E)&&E.every((D)=>typeof D==="string"))C.allowed_secret_keys=E;let g=A?.flags||{};for(let D of Y6)if(D in g)C.flags[D]=g[D];return C}function W6(A){let Q=A.parsedAccess?.allowFrom,I=Aq({channel:"telegram",channelDir:A.channelDir,allowFrom:Q});return{allowFromRaw:Q,bootWarn:I}}function L6(A){if(Array.isArray(A))return{list:A.filter((I)=>typeof I==="string"&&I.length>0).map((I)=>String(I)),malformed:!1};if(A===void 0||A===null)return{list:[],malformed:!1};return{list:[],malformed:!0}}function X6(A){let{list:Q,malformed:I}=L6(A.allowFrom);if(Q.length===0)return{allow:!1,kind:"empty-fail-closed",reason:I?"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 C=A.senderId||"",B=(A.senderUsername||"").trim();if(C&&Q.includes(C))return{allow:!0,kind:"explicit-allow",reason:`sender id ${C} in allowFrom`};if(B&&Q.includes(B))return{allow:!0,kind:"explicit-allow",reason:`sender username ${B} in allowFrom`};return{allow:!1,kind:"denied",reason:`sender id=${C} username=${B||"(none)"} not in allowFrom`}}function Aq(A){let{list:Q,malformed:I}=L6(A.allowFrom);if(Q.length>0)return null;let C=I?"malformed (not a string[])":"empty";return`[${A.channel}] FAIL-CLOSED: ${A.channelDir}/access.json allowFrom is ${C} — `+'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).'}import{mkdirSync as TS,appendFileSync as od}from"fs";var __dirname="/tmp/p-feishu/agent-node/src";var RS=Hd(),qQ=process.argv.slice(2),EA={},KS=[],zS="2.1.0";try{let A=new URL(".",import.meta.url).pathname;for(let Q of["../package.json","../../package.json"])try{let I=JSON.parse(gC(WA(A,Q),"utf-8"));if(I.version){zS=I.version;break}}catch{}}catch{}for(let A=0;A<qQ.length;A++){if(qQ[A]==="--version"||qQ[A]==="-v")console.log(`agent-node v${zS}`),process.exit(0);if(qQ[A]==="-h"||qQ[A]==="--help")console.log(`
|
|
131
131
|
@sleep2agi/agent-node — AI Agent 节点,一行命令加入 CommHub 网络
|
|
132
132
|
|
|
133
133
|
用法:
|
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.11",
|
|
4
4
|
"description": "AI Agent runtime for CommHub networks. Supports 4 runtimes: Claude Code CLI, Claude Agent SDK, Codex SDK, and Grok Build ACP.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"agent-node": "dist/cli.js"
|