agentix-cli 0.121.0 → 0.122.0

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.
Files changed (114) hide show
  1. package/dist/{App-AMIGKAXO.js → App-2D5W26LY.js} +2 -2
  2. package/dist/{ChatApp-WMI4HQSY.js → ChatApp-FZFZD2XY.js} +2 -2
  3. package/dist/{agent-TQQOAVMU.js → agent-PCRE3TRK.js} +2 -2
  4. package/dist/{board-dashboard-FNMZAP7A.js → board-dashboard-ZDJ4UDW4.js} +264 -230
  5. package/dist/board-dashboard-ZDJ4UDW4.js.map +1 -0
  6. package/dist/{chunk-MORRCYJE.js → chunk-2UDSIG5K.js} +2 -2
  7. package/dist/{chunk-6FVFD5WU.js → chunk-54XX2LSW.js} +4 -4
  8. package/dist/{chunk-6FVFD5WU.js.map → chunk-54XX2LSW.js.map} +1 -1
  9. package/dist/{chunk-RMA7KKR7.js → chunk-5SLTRG66.js} +2 -2
  10. package/dist/chunk-7ZGTRXWS.js +4 -0
  11. package/dist/chunk-7ZGTRXWS.js.map +1 -0
  12. package/dist/{chunk-EI7D5V2L.js → chunk-BRVQZC6P.js} +2 -2
  13. package/dist/{chunk-6TUQHOO3.js → chunk-C52IPIKJ.js} +2 -2
  14. package/dist/chunk-DMPTCBX6.js +532 -0
  15. package/dist/chunk-DMPTCBX6.js.map +1 -0
  16. package/dist/{chunk-4GDLXWCH.js → chunk-EHKI2RKD.js} +2 -2
  17. package/dist/{chunk-CAS2IWSM.js → chunk-NFS2VR3L.js} +2 -2
  18. package/dist/{chunk-43CLFC4B.js → chunk-NYAMY7EA.js} +2 -2
  19. package/dist/{chunk-7ZABMMSW.js → chunk-QCPSGOSK.js} +2 -2
  20. package/dist/{chunk-BLEW5WQL.js → chunk-SB7WMFJV.js} +2 -2
  21. package/dist/{chunk-7KY7EEEI.js → chunk-TLCURHW3.js} +2 -2
  22. package/dist/{chunk-H5Z42X7W.js → chunk-TYFGL2YS.js} +2 -2
  23. package/dist/{chunk-I4IDZSGF.js → chunk-UVV6GUOG.js} +232 -228
  24. package/dist/chunk-UVV6GUOG.js.map +1 -0
  25. package/dist/{chunk-ELUEF4NC.js → chunk-WJDFR3WE.js} +2 -2
  26. package/dist/{chunk-IKBWV7YJ.js → chunk-XBRVV4ZT.js} +2 -2
  27. package/dist/{chunk-2NGXOYTS.js → chunk-XLCUHG3N.js} +69 -69
  28. package/dist/chunk-XLCUHG3N.js.map +1 -0
  29. package/dist/{chunk-2IMK3NGJ.js → chunk-XX6MLDTL.js} +2 -2
  30. package/dist/{chunk-PAWCJIPZ.js → chunk-YCMO3KZ4.js} +2 -2
  31. package/dist/{chunk-Y4PR5LR3.js → chunk-YUNMSLZN.js} +2 -2
  32. package/dist/{chunk-OPNZWQ6Y.js → chunk-ZLUROC2Y.js} +5 -5
  33. package/dist/chunk-ZLUROC2Y.js.map +1 -0
  34. package/dist/{chunk-25XR6QK2.js → chunk-ZWZADDXV.js} +2 -2
  35. package/dist/cli.js +1 -1
  36. package/dist/{client-ICDRAZBU.js → client-TFZEASIJ.js} +2 -2
  37. package/dist/config-IXCOAOPZ.js +2 -0
  38. package/dist/config-mutator-EPYIZVSG.js +2 -0
  39. package/dist/{doctor-LRTOOCM6.js → doctor-G5TM5GVF.js} +2 -2
  40. package/dist/{grants-ZMHSJMYE.js → grants-NGBKFONG.js} +2 -2
  41. package/dist/index.d.ts +161 -79
  42. package/dist/index.js +1 -1
  43. package/dist/{program-OKPC77BN.js → program-CGPPGRMR.js} +201 -199
  44. package/dist/program-CGPPGRMR.js.map +1 -0
  45. package/dist/{promote-4LW53AMH.js → promote-VTVIPRTC.js} +2 -2
  46. package/dist/{query-4OPS5PET.js → query-3CVDT2GZ.js} +2 -2
  47. package/dist/{registry-YHSHGJ4K.js → registry-NOJMMWE3.js} +2 -2
  48. package/dist/{request-planner-GDXSBNN4.js → request-planner-E2Q5O66N.js} +2 -2
  49. package/dist/{review-candidates-TUVDG2LR.js → review-candidates-I36HEYKX.js} +2 -2
  50. package/dist/{routing-OKDZ4VYH.js → routing-KBUZON5R.js} +2 -2
  51. package/dist/schedule-tool-GUHHYYTO.js +2 -0
  52. package/dist/scheduler-PGUELFMB.js +2 -0
  53. package/dist/{seat-K6FNHYMY.js → seat-NGY2BMP6.js} +2 -2
  54. package/dist/{select-QMJXHNUP.js → select-X7VBGZ6X.js} +2 -2
  55. package/dist/{set-enabled-I77LPL6Q.js → set-enabled-6NP63KCU.js} +2 -2
  56. package/dist/{tool-QTGNWXUA.js → tool-EZIILXYL.js} +2 -2
  57. package/dist/tool-WKIF52OH.js +6 -0
  58. package/dist/tool-WKIF52OH.js.map +1 -0
  59. package/dist/wiki-7BFVMMNR.js +2 -0
  60. package/package.json +1 -1
  61. package/dist/board-dashboard-FNMZAP7A.js.map +0 -1
  62. package/dist/chunk-2NGXOYTS.js.map +0 -1
  63. package/dist/chunk-BWHHZJNJ.js +0 -482
  64. package/dist/chunk-BWHHZJNJ.js.map +0 -1
  65. package/dist/chunk-DJQMG6TH.js +0 -4
  66. package/dist/chunk-DJQMG6TH.js.map +0 -1
  67. package/dist/chunk-I4IDZSGF.js.map +0 -1
  68. package/dist/chunk-OPNZWQ6Y.js.map +0 -1
  69. package/dist/config-K4UYPR7W.js +0 -2
  70. package/dist/config-mutator-IGA6D4S5.js +0 -2
  71. package/dist/program-OKPC77BN.js.map +0 -1
  72. package/dist/schedule-tool-MJLXMXN5.js +0 -2
  73. package/dist/scheduler-E5SASFAH.js +0 -2
  74. package/dist/tool-BQUKONSF.js +0 -4
  75. package/dist/tool-BQUKONSF.js.map +0 -1
  76. package/dist/wiki-F6EZBBUH.js +0 -2
  77. /package/dist/{App-AMIGKAXO.js.map → App-2D5W26LY.js.map} +0 -0
  78. /package/dist/{ChatApp-WMI4HQSY.js.map → ChatApp-FZFZD2XY.js.map} +0 -0
  79. /package/dist/{agent-TQQOAVMU.js.map → agent-PCRE3TRK.js.map} +0 -0
  80. /package/dist/{chunk-MORRCYJE.js.map → chunk-2UDSIG5K.js.map} +0 -0
  81. /package/dist/{chunk-RMA7KKR7.js.map → chunk-5SLTRG66.js.map} +0 -0
  82. /package/dist/{chunk-EI7D5V2L.js.map → chunk-BRVQZC6P.js.map} +0 -0
  83. /package/dist/{chunk-6TUQHOO3.js.map → chunk-C52IPIKJ.js.map} +0 -0
  84. /package/dist/{chunk-4GDLXWCH.js.map → chunk-EHKI2RKD.js.map} +0 -0
  85. /package/dist/{chunk-CAS2IWSM.js.map → chunk-NFS2VR3L.js.map} +0 -0
  86. /package/dist/{chunk-43CLFC4B.js.map → chunk-NYAMY7EA.js.map} +0 -0
  87. /package/dist/{chunk-7ZABMMSW.js.map → chunk-QCPSGOSK.js.map} +0 -0
  88. /package/dist/{chunk-BLEW5WQL.js.map → chunk-SB7WMFJV.js.map} +0 -0
  89. /package/dist/{chunk-7KY7EEEI.js.map → chunk-TLCURHW3.js.map} +0 -0
  90. /package/dist/{chunk-H5Z42X7W.js.map → chunk-TYFGL2YS.js.map} +0 -0
  91. /package/dist/{chunk-ELUEF4NC.js.map → chunk-WJDFR3WE.js.map} +0 -0
  92. /package/dist/{chunk-IKBWV7YJ.js.map → chunk-XBRVV4ZT.js.map} +0 -0
  93. /package/dist/{chunk-2IMK3NGJ.js.map → chunk-XX6MLDTL.js.map} +0 -0
  94. /package/dist/{chunk-PAWCJIPZ.js.map → chunk-YCMO3KZ4.js.map} +0 -0
  95. /package/dist/{chunk-Y4PR5LR3.js.map → chunk-YUNMSLZN.js.map} +0 -0
  96. /package/dist/{chunk-25XR6QK2.js.map → chunk-ZWZADDXV.js.map} +0 -0
  97. /package/dist/{client-ICDRAZBU.js.map → client-TFZEASIJ.js.map} +0 -0
  98. /package/dist/{config-K4UYPR7W.js.map → config-IXCOAOPZ.js.map} +0 -0
  99. /package/dist/{config-mutator-IGA6D4S5.js.map → config-mutator-EPYIZVSG.js.map} +0 -0
  100. /package/dist/{doctor-LRTOOCM6.js.map → doctor-G5TM5GVF.js.map} +0 -0
  101. /package/dist/{grants-ZMHSJMYE.js.map → grants-NGBKFONG.js.map} +0 -0
  102. /package/dist/{promote-4LW53AMH.js.map → promote-VTVIPRTC.js.map} +0 -0
  103. /package/dist/{query-4OPS5PET.js.map → query-3CVDT2GZ.js.map} +0 -0
  104. /package/dist/{registry-YHSHGJ4K.js.map → registry-NOJMMWE3.js.map} +0 -0
  105. /package/dist/{request-planner-GDXSBNN4.js.map → request-planner-E2Q5O66N.js.map} +0 -0
  106. /package/dist/{review-candidates-TUVDG2LR.js.map → review-candidates-I36HEYKX.js.map} +0 -0
  107. /package/dist/{routing-OKDZ4VYH.js.map → routing-KBUZON5R.js.map} +0 -0
  108. /package/dist/{schedule-tool-MJLXMXN5.js.map → schedule-tool-GUHHYYTO.js.map} +0 -0
  109. /package/dist/{scheduler-E5SASFAH.js.map → scheduler-PGUELFMB.js.map} +0 -0
  110. /package/dist/{seat-K6FNHYMY.js.map → seat-NGY2BMP6.js.map} +0 -0
  111. /package/dist/{select-QMJXHNUP.js.map → select-X7VBGZ6X.js.map} +0 -0
  112. /package/dist/{set-enabled-I77LPL6Q.js.map → set-enabled-6NP63KCU.js.map} +0 -0
  113. /package/dist/{tool-QTGNWXUA.js.map → tool-EZIILXYL.js.map} +0 -0
  114. /package/dist/{wiki-F6EZBBUH.js.map → wiki-7BFVMMNR.js.map} +0 -0
@@ -1,54 +1,54 @@
1
- import{B as nr,a as Ls,b as Fs,d as Hs,f as Ue,l as Vs,s as Zs,u as er,z as tr}from"./chunk-7KY7EEEI.js";import{a as Ns}from"./chunk-GLQLCBJS.js";import{b as Us}from"./chunk-6W74CHNW.js";import{a as Ys}from"./chunk-W4YR2RO2.js";import{b as js,c as Vt,d as Ws,e as Gs,h as Ks}from"./chunk-25XR6QK2.js";import{a as Es}from"./chunk-DJQMG6TH.js";import{e as Ds,f as Os}from"./chunk-36AXN6ZB.js";import{a as Xt,b as Bs}from"./chunk-J3SOEFRE.js";import{a as Yt,b as qs}from"./chunk-SIU6STB2.js";import{e as Js,i as Qs,j as zs,k as Xs}from"./chunk-X5C5W3E4.js";import{c as xs,f as Ss}from"./chunk-6TUQHOO3.js";import{a as Is,c as Ts}from"./chunk-MYVHVJWZ.js";import{a as vs,b as ks,c as As,d as $s,l as Cs}from"./chunk-AV7T3SYT.js";import{a as Ms,b as Ps}from"./chunk-Y5MFVVTM.js";import{g as _s,h as Rs}from"./chunk-ELUEF4NC.js";import{a as ve,d as ye}from"./chunk-56KNKUFF.js";import{s as ws,v as lt,w as bs,y as ue,z as zt}from"./chunk-4GDLXWCH.js";import{a as Fe,b as Te,f as ut}from"./chunk-72SZI2UW.js";import{a as Ie,b as qt}from"./chunk-FCPTN6NF.js";import{c as is,d as as}from"./chunk-QOYAX2FT.js";import{e as he}from"./chunk-DSYKYZMT.js";import{C as ls,E as Jt,G as Zi,J as gs,N as ea,T as ps,U as Qt,V as fs,W as Le,X as ms,Y as hs,_ as ys,ma as ta}from"./chunk-OPNZWQ6Y.js";import{g as Gt,h as Yi}from"./chunk-BRK6M6LA.js";import{f as Kt,n as Vi}from"./chunk-UIBUZ2N3.js";import{a as ds,b as ie,c as cs,d as us,e as Wt}from"./chunk-2QNT5JDS.js";zt();ut();var gt="tool-set",sr=["answer","code","full"],rr={answer:["Read","Grep","Glob"],code:["Read","Grep","Glob","Edit","MultiEdit","Write","Bash"]},na=.1;function ir(n){return{task:or(n.message,2e3),agent:n.agent,channel:n.channel??null,...n.agentPrompt?{agentInstructions:or(n.agentPrompt,600)}:{}}}var ar={bundle:Te({answer:"Read-only: the task can be done by reading, searching and listing files and then replying. It changes no file and runs no command (no tests, no git, no scripts).",code:"Change files or run commands in the workspace: edit or write files, run tests, builds, git or shell commands. Still all inside the workspace, with no web access, no sub-agents and no notebooks.",full:"Needs more than that, or it is not clear: fetching or searching the web, starting sub-agents, notebooks, or anything the other two do not clearly cover."},"Which set of built-in tools does an agent need to do this task completely? Pick the smallest set that is clearly enough.")};function dr(n,e=na){let s=n?.bundle?.probabilities;if(!s)return"full";let r=Zt(s.answer),o=Zt(s.code),i=Zt(s.full);return r===null||o===null||i===null?"full":o+i<e?"answer":i<e?"code":"full"}function cr(n){let e=[...n].filter(t=>!t.startsWith("mcp__"));return e.every(t=>rr.answer.includes(t))?"answer":e.every(t=>rr.code.includes(t))?"code":"full"}function ur(n,e){return sr.indexOf(n)<sr.indexOf(e)}function Zt(n){return typeof n=="number"&&Number.isFinite(n)?n:null}function or(n,e){return n.length>e?`${n.slice(0,e)}\u2026`:n}var lr=!1;function gr(n,e){let t=lt(gt);if(t!=="off")return t==="active"&&!lr&&(lr=!0,e(`[decisions] seat "${gt}" is set to active, but only shadow is built: it records and changes nothing`)),ue(gt,ir(n),ar,{incumbent:{bundle:"full"},links:[{kind:"task",id:n.taskId}],features:{agent:n.agent,channel:n.channel??"unknown"}}).then(s=>{if(!s)return null;let r=s.answers,o=dr(r),i=r.bundle?.probabilities??{};return{callId:s.callId,bundle:o,probabilities:i}}).catch(()=>null)}function pr(n,e,t){return n.then(s=>{if(!s||e.error||!e.eventsSeen)return;let r=[...e.toolUses.keys()],o=cr(r);bs(s.callId,"bundle",o,{kind:"outcome",labeledBy:"tool-use"});let i=a=>typeof s.probabilities[a]=="number"?s.probabilities[a].toFixed(2):"-";t(`[${e.agentId}] tool-set shadow: would start with ${s.bundle} (answer ${i("answer")}, code ${i("code")}, full ${i("full")}); run used ${r.filter(a=>!a.startsWith("mcp__")).join(", ")||"no built-in tool"} \u2192 needed ${o}`+(ur(s.bundle,o)?" \u2014 MISS":""))}).catch(()=>{})}function sa(n,e){return!n||n<=0||!e||e<=0?10:Math.min(200,Math.max(1,Math.round(e/n)))}function fr(n,e){let t=sa(n.contextTokens,n.turnInputTokens),s=n.idleMs<e.cacheTtlMinutes*6e4,r=.1*(t-1),o=e.freshTokens*(e.cacheWriteFactor+r),i=n.contextTokens;if(!i||i<=0)return{rotate:!1,resumeCost:null,freshCost:o,warm:s,requestsPerTurn:t};let a=i*((s?.1:e.cacheWriteFactor)+r);return{rotate:a>o*e.margin,resumeCost:a,freshCost:o,warm:s,requestsPerTurn:t}}function en(n){let e=s=>`${Math.round(s/1e3)}k`,t=n.warm?"warm cache":"cold cache";return n.resumeCost===null?`resume: no context reading (${t})`:`${n.rotate?"start fresh":"resume"}: resume \u2248${e(n.resumeCost)}, fresh \u2248${e(n.freshCost)} input-token equivalents (${t}, ${n.requestsPerTurn} requests/turn)`}zt();ut();var mr="session-continuity",hr={continues:Fe("The new request continues the task the user was already working on in the previous request, rather than starting a separate one.",{true:`The new request advances, narrows, corrects or follows up on the previous request's task \u2014 including terse replies such as "and the cost?" or "why?" that mean nothing on their own.`,false:"The new request opens a subject that could be answered without having seen the previous request, even if it arrived seconds later or belongs to the same broad field."}),needsHistory:Fe("Does the new request refer to something stated earlier in the conversation?")};function yr(n){let e=(n.recentRequests??[]).filter(Boolean);return{newRequest:tn(n.message,1200),previousRequest:n.previousMessage?tn(n.previousMessage,800):null,...e.length?{earlierRequests:e.map(t=>tn(t,400))}:{},minutesSinceLastTurn:n.minutesSinceLastTurn,turnsSoFar:n.turnCount,currentContextTokens:n.lastTurnContextTokens,agent:n.agentId,channel:n.channel}}function wr(n,e){if(e.mechanicalRotation)return!1;let t=e.maxContinuity??.2,s=n.continues.noul,r=n.needsHistory.noul;return s<=t&&r<=t}function tn(n,e){let t=String(n??"");return t.length>e?t.slice(0,e):t}import{execa as St}from"execa";import{spawn as ra}from"node:child_process";import{createHash as oa}from"node:crypto";import{createInterface as ia}from"node:readline";var le=class extends Error{},aa=n=>ra("codex",["app-server",...n.args],{cwd:n.cwd,env:n.env,stdio:["pipe","pipe","pipe"]}),nn=class{child;pending=new Map;nextId=0;dead=!1;busy=!1;threadId;idle;notify;failTurn;constructor(e,t){this.child=t(e),this.child.stderr.resume(),ia({input:this.child.stdout}).on("line",r=>{let o;try{o=JSON.parse(r)}catch{return}if(o.method&&o.id!==void 0)this.write({id:o.id,error:{code:-32601,message:"Interactive requests are not supported by AgentX"}});else if(o.id!==void 0){let i=this.pending.get(o.id);if(!i)return;this.pending.delete(o.id),o.error?i.reject(new Error(o.error.message||"Codex RPC failed")):i.resolve(o.result)}else o.method&&this.notify?.(o.method,o.params)}),this.child.on("error",r=>this.close(r)),this.child.stdin.on("error",r=>this.close(r)),this.child.on("exit",()=>this.close(new Error("Codex app-server exited")))}write(e){this.dead||this.child.stdin.write(JSON.stringify(e)+`
2
- `)}rpc(e,t){if(this.dead)return Promise.reject(new Error("Codex connection closed"));let s=++this.nextId;return new Promise((r,o)=>{this.pending.set(s,{resolve:r,reject:o}),this.write({id:s,method:e,params:t})})}close(e=new Error("Codex connection closed")){if(this.dead)return;this.dead=!0,clearTimeout(this.idle);for(let s of this.pending.values())s.reject(e);this.pending.clear(),this.failTurn?.(e),this.child.kill("SIGTERM"),setTimeout(()=>{this.child.exitCode===null&&this.child.kill("SIGKILL")},5e3).unref()}},sn=class{constructor(e=aa,t=8,s=3e5){this.launchProcess=e;this.capacity=t;this.idleMs=s}entries=new Map;stop(){for(let{connection:e}of this.entries.values())e.close();this.entries.clear()}async run(e){let t=Date.now();if(e.signal?.aborted)return{content:"",error:"task cancelled by operator",duration:0};let s=oa("sha256").update(JSON.stringify([e.cwd,e.model,e.bypass,e.args,Object.entries(e.env).sort(([b],[R])=>b.localeCompare(R))])).digest("hex"),r=this.entries.get(e.key);if(r?.connection.busy)throw new le("Conversation already running");r&&(r.fingerprint!==s||e.fresh||r.connection.dead)&&(r.connection.close(),this.entries.delete(e.key),r=void 0);let o=!!r;if(!r){if(this.entries.size>=this.capacity){let b=[...this.entries].find(([,R])=>!R.connection.busy);if(!b)throw new le("Codex warm process capacity reached");b[1].connection.close(),this.entries.delete(b[0])}try{r={fingerprint:s,connection:new nn(e,this.launchProcess)}}catch{throw new le("Could not start Codex app-server")}this.entries.set(e.key,r)}let i=r.connection;i.busy=!0,clearTimeout(i.idle);let a=!1,c="",d,u,l,f,h=!1,p=()=>i.close(new Error("task cancelled by operator"));e.signal?.addEventListener("abort",p,{once:!0});let I=setTimeout(()=>i.close(new Error("Codex turn timed out")),e.timeoutMs),A=setTimeout(()=>i.close(new Error("Codex initialization timed out")),15e3);try{o||(await i.rpc("initialize",{clientInfo:{name:"agentx",version:"1.0.0"},capabilities:{}}),i.write({method:"initialized",params:{}})),i.threadId&&i.threadId!==e.resume&&(await i.rpc("thread/unsubscribe",{threadId:i.threadId}),i.threadId=void 0);let b={cwd:e.cwd,model:e.model,approvalPolicy:"never",sandbox:e.bypass?"danger-full-access":"workspace-write"};u=(await i.rpc(e.resume&&!e.fresh?"thread/resume":"thread/start",{...b,...e.resume&&!e.fresh?{threadId:e.resume}:{}})).thread.id,i.threadId=u,clearTimeout(A),e.onEvent?.({type:"codex.ready",reused:o,startupMs:Date.now()-t,model:e.model});let E=new Promise((O,P)=>{i.failTurn=P,i.notify=(D,L)=>{if(L?.threadId!==u)return;let F=L.item,j={agentMessage:"agent_message",commandExecution:"command_execution",fileChange:"file_change",mcpToolCall:"mcp_tool_call"};if(e.onEvent?.({...L,type:D.replace("/","."),...F?{item:{...F,type:j[F.type]||F.type}}:{}}),D==="item/completed"&&F?.type==="agentMessage"&&F.phase==="final_answer"&&(d=F.text),D==="item/agentMessage/delta"&&(h||(h=!0,e.onEvent?.({type:"codex.first_output",elapsedMs:Date.now()-t,reused:o})),c+=L.delta,e.onDelta?.(L.delta,c)),D==="thread/tokenUsage/updated"){let H=L.tokenUsage.last;f=H.inputTokens;let W=H.cachedInputTokens||0;l={inputTokens:(l?.inputTokens||0)+Math.max(0,(H.inputTokens||0)-W),outputTokens:(l?.outputTokens||0)+(H.outputTokens||0),cacheReadTokens:(l?.cacheReadTokens||0)+W,cacheCreateTokens:(l?.cacheCreateTokens||0)+(H.cacheWriteInputTokens||0)}}D==="turn/completed"&&(L.turn.status==="completed"?O():P(new Error(L.turn.error?.message||`Codex turn ${L.turn.status}`)))}});return E.catch(()=>{}),a=!0,await i.rpc("turn/start",{threadId:u,input:[{type:"text",text:e.prompt,text_elements:[]}]}),await E,{content:d??c,codexSessionId:u,billedModel:e.model,usage:l,contextTokens:f,duration:Date.now()-t}}catch(b){if(i.close(),!a&&!e.signal?.aborted)throw new le(b.message);return{content:c,codexSessionId:u,usage:l,contextTokens:f,error:b.message,duration:Date.now()-t}}finally{clearTimeout(A),clearTimeout(I),e.signal?.removeEventListener("abort",p),i.notify=void 0,i.failTurn=void 0,i.busy=!1,i.dead?this.entries.get(e.key)?.connection===i&&this.entries.delete(e.key):(i.idle=setTimeout(()=>{i.close(),this.entries.delete(e.key)},this.idleMs),i.idle.unref())}}},br=new sn;import{execFile as Ca}from"child_process";import{StringDecoder as We}from"string_decoder";import{mkdtempSync as Lr,readFileSync as Fr,rmSync as Ur}from"fs";import{join as bt}from"path";import{tmpdir as Hr}from"os";function pt(n){let e=(n||"").trim();if(!e)return{message:"Unknown error from the model.",kind:"unknown",retryable:!1};if(/timed out after/i.test(e))return{message:e.slice(0,300),kind:"timeout",retryable:!0,raw:e};if(/not logged in|please run \/login/i.test(e))return{kind:"auth",retryable:!0,message:"The agent's Claude Code session is logged out.",fix:"Usually a transient OAuth refresh race under concurrent load \u2014 retry in a moment. If it persists, run `/login` in the agent's workspace.",raw:e};if(/specified API usage limits/i.test(e)){let d=e.match(/regain access on ([^.\n]+?)(?:\.|$)/i);return{kind:"usage_cap",retryable:!1,message:`Claude Code subscription /usage cap exhausted.${d?` Resets ${d[1].trim()}.`:""}`,fix:"Raise the cap at https://claude.ai/settings/usage (this is the user-set monthly limit on the OAuth account, not Anthropic API billing). If the daemon is using a different account than expected, check CLAUDE_CODE_OAUTH_TOKEN / ANTHROPIC_API_KEY in the spawn env \u2014 capped keys leak the same error.",raw:e}}if(/out of extra usage/i.test(e))return{kind:"overage_disabled",retryable:!0,message:"Claude Max-plan overage is unavailable (disabled or depleted at the org level).",fix:"Enable overage / extra usage at https://claude.ai/settings/usage (this is the subscription account's toggle \u2014 not Anthropic API billing). Warm sessions can still succeed via prompt cache; cold dispatches will keep failing until overage is re-enabled.",raw:e};if(/credit balance (is )?too low|out of credit|credit(s)? exhausted|insufficient credit/i.test(e))return{kind:"out_of_credits",retryable:!1,message:"The agent is out of Anthropic credits.",fix:"Top up at https://console.anthropic.com/settings/billing (or claude.ai/settings/usage for Max subscribers), then retry.",raw:e};let t=e.match(/\{.*\}\s*$/s)||e.match(/\{[\s\S]*\}/),s;if(t)try{s=JSON.parse(t[0])}catch{}let r=s?.error||s,o=typeof r?.type=="string"?r.type:void 0,i=typeof r?.message=="string"?r.message:void 0,a=e.match(/API Error:\s*(\d{3})/i),c=a?parseInt(a[1],10):void 0;return i&&/out of extra usage/i.test(i)?{kind:"overage_disabled",retryable:!0,message:"Claude Max-plan overage is unavailable (disabled or depleted at the org level).",fix:"Enable overage / extra usage at https://claude.ai/settings/usage (this is the subscription account's toggle \u2014 not Anthropic API billing). Warm sessions can still succeed via prompt cache; cold dispatches will keep failing until overage is re-enabled.",raw:e}:i&&/out of (extra )?usage|out of credit|credit(s)? exhausted|insufficient credit|credit balance (is )?too low|low credit balance/i.test(i)?{kind:"out_of_credits",retryable:!1,message:"The agent is out of Anthropic credits.",fix:"Top up at https://console.anthropic.com/settings/billing (or claude.ai/settings/usage for Max subscribers), then retry.",raw:e}:i&&/context|prompt is too long|too many tokens|maximum context length/i.test(i)?{kind:"context_too_large",retryable:!1,message:"The conversation has grown past what the model can hold.",fix:"Clear session history or switch the agent to a bigger context model.",raw:e}:o==="authentication_error"||i&&/authentication|invalid.*api.*key|no api key|not authenticated/i.test(i)?{kind:"auth",retryable:!1,message:"Authentication failed talking to Anthropic.",fix:"Check ANTHROPIC_API_KEY in .env (or the Claude Code login for claude-code tier agents).",raw:e}:o==="permission_error"||c===403?{kind:"permission",retryable:!1,message:i||"The API key doesn't have permission for this request.",raw:e}:o==="rate_limit_error"||c===429?{kind:"rate_limit",retryable:!0,message:"Anthropic's API rate-limited this request.",fix:"AgentX will retry automatically. If it recurs, lower the agent's concurrency or spread scheduled jobs.",raw:e}:o==="overloaded_error"||c===529||c===503?{kind:"overloaded",retryable:!0,message:"Anthropic's API is temporarily overloaded.",fix:"AgentX will retry in a moment.",raw:e}:o==="invalid_request_error"||c===400?{kind:"invalid_request",retryable:!1,message:i||"The model rejected the request as invalid.",raw:e}:c&&c>=500?{kind:"upstream_api",retryable:!0,message:i||`Anthropic API error (HTTP ${c}).`,fix:"Transient \u2014 retry. Check https://status.anthropic.com if it persists.",raw:e}:{kind:"unknown",retryable:!1,message:e.replace(/\s+/g," ").slice(0,220),raw:e}}function ft(n){return n.fix?`${n.message} \u2014 ${n.fix}`:n.message}function mt(n){if(!n||typeof n!="object")return;let e,t=-1,s=-1;for(let[r,o]of Object.entries(n)){let i=o&&typeof o=="object"?o:{},a=typeof i.costUSD=="number"?i.costUSD:0,c=(Number(i.inputTokens)||0)+(Number(i.outputTokens)||0)+(Number(i.cacheReadInputTokens)||0)+(Number(i.cacheCreationInputTokens)||0);(a>t||a===t&&c>s)&&(e=r,t=a,s=c)}return e}var xr=null;function ht(){return xr}function Bu(n){xr=n}function He(n){return`${n.agentId}:${n.channel}:${n.chatId}`}function da(n,e){if(n.state()==="busy")return null;let s=n.snapshot(),r=n.opts?.model;return r&&e.model&&r!==e.model?`model changed (${r} -> ${e.model})`:e.resumeSessionId?s.claudeSessionId&&s.claudeSessionId!==e.resumeSessionId?`session changed (${s.claudeSessionId.slice(0,8)} -> ${e.resumeSessionId.slice(0,8)})`:null:s.claudeSessionId?"session rotated":null}var ke=class extends Error{constructor(t,s,r){super(t);this.scope=s;this.cap=r;this.name="RegistryCapExceeded"}},Sr=class{handles=new Map;sweeper;handleWorkspace=new Map;cfg;constructor(e){this.cfg={maxProcessesGlobal:e.maxProcessesGlobal??64,maxProcessesPerAgent:e.maxProcessesPerAgent??16,idleTimeoutMs:e.idleTimeoutMs??3e4,staleTimeoutMs:e.staleTimeoutMs??45*60*1e3,sweepIntervalMs:e.sweepIntervalMs??5e3,factory:e.factory,log:e.log??(()=>{}),currentWorkspaceHash:e.currentWorkspaceHash}}start(){this.sweeper||(this.sweeper=setInterval(()=>this.sweepIdle(),this.cfg.sweepIntervalMs),typeof this.sweeper.unref=="function"&&this.sweeper.unref())}async stop(){this.sweeper&&(clearInterval(this.sweeper),this.sweeper=void 0);let e=Array.from(this.handles.values());this.handles.clear(),await Promise.allSettled(e.map(t=>t.kill("registry-stop")))}acquire(e,t){let s=He(e),r=this.handles.get(s);if(r&&r.state()!=="dead"){let a=da(r,t);if(!a)return r.claim?.(),r;this.handles.delete(s),this.handleWorkspace.delete(s),this.cfg.log(`[process-registry] respawning ${s}: ${a}`),r.kill(a).catch(()=>{})}if(this.handles.size>=this.cfg.maxProcessesGlobal&&this.evictOldestIdle({scope:"global"}),this.countForAgent(e.agentId)>=this.cfg.maxProcessesPerAgent&&this.evictOldestIdle({scope:"agent",agentId:e.agentId}),this.handles.size>=this.cfg.maxProcessesGlobal)throw new ke(`process registry at global cap (${this.cfg.maxProcessesGlobal}) and no idle handle to evict`,"global",this.cfg.maxProcessesGlobal);if(this.countForAgent(e.agentId)>=this.cfg.maxProcessesPerAgent)throw new ke(`process registry at per-agent cap for ${e.agentId} (${this.cfg.maxProcessesPerAgent}) and no idle handle to evict`,"agent",this.cfg.maxProcessesPerAgent);let i=this.cfg.factory.spawn(e,t);return this.handles.set(s,i),this.handleWorkspace.set(s,t.workspace),this.cfg.log(`[process-registry] spawned ${s}`),i}release(e,t={}){let s=He(e),r=this.handles.get(s);r&&(this.handles.delete(s),this.handleWorkspace.delete(s),t.kill&&r.kill(t.reason??"release"))}list(){return Array.from(this.handles.values()).map(e=>e.snapshot())}hasLive(e){let t=He(e),s=this.handles.get(t);return s!=null&&s.state()!=="dead"}async kill(e,t="operator"){let s=He(e),r=this.handles.get(s);r&&(this.handles.delete(s),this.handleWorkspace.delete(s),await r.kill(t))}countForAgent(e){let t=0;for(let s of this.handles.values())s.key.agentId===e&&s.state()!=="dead"&&(t+=1);return t}evictOldestIdle(e){let t,s=Number.POSITIVE_INFINITY;for(let o of this.handles.values()){if(o.state()!=="idle"||e.scope==="agent"&&o.key.agentId!==e.agentId)continue;let i=o.snapshot().lastTurnAt;i<s&&(s=i,t=o)}if(!t)return!1;let r=He(t.key);return this.handles.delete(r),t.kill("evicted (cap reached)"),this.cfg.log(`[process-registry] evicted ${r} (cap)`),!0}sweepIdle(){let e=Date.now();for(let[t,s]of this.handles.entries()){let r=s.snapshot();if(s.state()==="dead"){this.handles.delete(t),this.handleWorkspace.delete(t),this.cfg.log(`[process-registry] reaped dead ${t}`);continue}if(s.state()!=="idle")continue;let o=e-r.lastTurnAt;if(o>=this.cfg.staleTimeoutMs){this.handles.delete(t),this.handleWorkspace.delete(t),s.kill(`stale (idle ${Math.round(o/1e3)}s)`),this.cfg.log(`[process-registry] killed stale ${t}`);continue}if(o>=this.cfg.idleTimeoutMs){this.handles.delete(t),this.handleWorkspace.delete(t),s.kill(`idle (${Math.round(o/1e3)}s)`),this.cfg.log(`[process-registry] killed idle ${t}`);continue}if(this.cfg.currentWorkspaceHash){let i=this.handleWorkspace.get(t);if(i){let a=null;try{a=this.cfg.currentWorkspaceHash(s.key,i)}catch(c){this.cfg.log(`[process-registry] drift-check failed for ${t}: ${c?.message||c}`);continue}if(a!==r.claudeMdHash){this.handles.delete(t),this.handleWorkspace.delete(t);let c=r.claudeMdHash??"unmarked",d=a??"unmarked";s.kill(`claude-md drifted (${c} \u2192 ${d})`),this.cfg.log(`[process-registry] killed drifted ${t} (${c} \u2192 ${d})`)}}}}}};import{spawn as ca}from"child_process";import{randomUUID as ua}from"crypto";import{existsSync as la,readFileSync as ga}from"fs";import{resolve as pa}from"path";function fa(n){let e=pa(n,"CLAUDE.md");if(!la(e))return null;try{let t=ga(e,"utf8");return Cs(t)}catch{return null}}var ma=20*60*1e3,ha=5e3,Be=class extends Error{constructor(t){super(`turn exceeded its ${Math.round(t/6e4)}m budget`);this.budgetMs=t}},je=class extends Error{constructor(t){super(`claude process stopped mid-turn (${t})`);this.reason=t}};function ya(n,e){return n.AGENTX_AGENT_ID=e.agentId,n.AGENTX_CHANNEL=e.channel,n.AGENTX_CHAT_ID=e.chatId,delete n.AGENTX_TASK_ID,n}var Ir=class{constructor(e={}){this.opts=e}spawn(e,t){return new rn(e,t,this.opts)}},rn=class{constructor(e,t,s){this.key=e;this.opts=t;this.factoryOpts=s;let r=s.binary??"claude",o=this.buildArgs(t),i=this.log=s.log??(()=>{});this.child=ca(r,o,{cwd:t.workspace,env:ye(ya({...process.env},e),t.billing),stdio:["pipe","pipe","pipe"]}),this.snap={key:e,pid:this.child.pid??null,claudeSessionId:t.resumeSessionId??null,state:"warm-cold",spawnedAt:Date.now(),lastTurnAt:Date.now(),turnCount:0,lastInputTokens:0,pendingTaskId:null,claudeMdHash:fa(t.workspace)},this.child.stdout.setEncoding("utf8"),this.child.stdout.on("data",a=>this.onStdout(a)),this.child.stderr.setEncoding("utf8"),this.child.stderr.on("data",a=>i(`[claude pid=${this.snap.pid}] stderr: ${a.trim()}`)),this.child.on("exit",a=>{this.exited=!0,this.exitCode=a,this.snap={...this.snap,state:"dead",deadReason:this.killReason??`exit=${a}`};let c=this.waiters.splice(0);for(let d of c)d(null)}),this.child.on("error",a=>{i(`[claude pid=${this.snap.pid}] spawn error: ${a.message}`),this.killReason=`spawn-error: ${a.message}`})}child;buf="";pendingEvents=[];waiters=[];exited=!1;exitCode=null;killReason;turnQueue=Promise.resolve();snap;log;state(){return this.snap.state}snapshot(){return{...this.snap}}async*runTurn(e){let t,s=new Promise(h=>{t=h}),r=this.turnQueue;if(this.turnQueue=r.then(()=>s),await r,this.exited||this.snap.state==="dead")throw t(),new Error(`claude process for ${this.key.agentId}:${this.key.chatId} is dead (${this.snap.deadReason??"?"})`);let o=Date.now();this.snap={...this.snap,state:"busy",pendingTaskId:e.taskId,lastTurnAt:o};let i=ua(),a=JSON.stringify({type:"user",uuid:i,message:{role:"user",content:e.message}});this.child.stdin.write(a+`
3
- `);let c=e.deadlineMs??ma,d=o+c,u=()=>(this.kill(`turn deadline (${Math.round(c/6e4)}m)`),new Be(c)),l=!1,f=null;try{for(;;){let h=d-Date.now();if(h<=0)throw u();let p=await this.nextEvent(h);if(p===null&&this.killReason)throw new je(this.killReason);if(p===null&&!this.exited)throw u();if(p===null)throw new Error(`claude process exited mid-turn (code=${this.exitCode}, reason=${this.snap.deadReason??"?"})`);if(!l){if(p.type==="user"&&p.uuid===i)l=!0,f&&(yield{type:f.type,raw:f});else if(p.type==="system"&&p.subtype==="init")f=p;else if(p.type==="result"){f=null;let I=typeof p.result=="string"?p.result:"";this.log(`[claude pid=${this.snap.pid}] dropped a reply no question asked for (${I.length} chars): ${I.slice(0,120)}`)}continue}if(yield{type:p.type,raw:p},p.type==="result"){this.onResultEvent(p);return}}}finally{let h=this.snap.state==="busy";this.snap={...this.snap,...h?{state:"idle",lastTurnAt:Date.now()}:{},pendingTaskId:null},t()}}claim(){this.snap.state!=="dead"&&(this.snap={...this.snap,lastTurnAt:Date.now()})}async kill(e){if(this.exited)return;this.killReason=e,this.snap={...this.snap,state:"dead",deadReason:e};try{this.child.kill("SIGTERM")}catch{}let t=this.waiters.splice(0);for(let r of t)r(null);let s=await new Promise(r=>{let o=setTimeout(()=>{try{this.child.kill("SIGKILL")}catch{}r(!0)},ha);this.child.once("exit",()=>{clearTimeout(o),r(!1)})})}buildArgs(e){let t=["-p","--input-format","stream-json","--output-format","stream-json","--verbose","--replay-user-messages"];return e.model&&t.push("--model",e.model),e.permissionMode==="bypassPermissions"&&t.push("--dangerously-skip-permissions"),e.resumeSessionId&&t.push("--resume",e.resumeSessionId),e.systemPromptAppend&&e.systemPromptAppend.trim().length>0&&t.push("--append-system-prompt",e.systemPromptAppend),e.extraArgs&&t.push(...e.extraArgs),this.factoryOpts.extraArgs&&t.push(...this.factoryOpts.extraArgs),t}onStdout(e){this.buf+=e;let t;for(;(t=this.buf.indexOf(`
4
- `))!==-1;){let s=this.buf.slice(0,t);if(this.buf=this.buf.slice(t+1),!s.trim())continue;let r;try{r=JSON.parse(s)}catch{continue}this.waiters.length>0?this.waiters.shift()(r):this.pendingEvents.push(r)}}nextEvent(e){return this.pendingEvents.length>0?Promise.resolve(this.pendingEvents.shift()):this.exited?Promise.resolve(null):new Promise(t=>{let s=!1,r=setTimeout(()=>{if(s)return;s=!0;let i=this.waiters.indexOf(o);i>=0&&this.waiters.splice(i,1),t(null)},e),o=i=>{s||(s=!0,clearTimeout(r),t(i))};this.waiters.push(o)})}onResultEvent(e){let t=e.usage??{},s=typeof e.session_id=="string"?e.session_id:this.snap.claudeSessionId;this.snap={...this.snap,lastTurnAt:Date.now(),turnCount:this.snap.turnCount+1,lastInputTokens:typeof t.input_tokens=="number"?t.input_tokens:this.snap.lastInputTokens,claudeSessionId:s,state:"idle"}}};Wt();Vi();qt();import{resolve as Tr,join as vr}from"path";var wa=4e3;function yt(n){try{let e=vr(Tr(n.root),".agentx","db.sqlite"),t=Kt({path:e});if(!t)return null;try{t.pragma("busy_timeout = 3000")}catch{}let s=Ie(),r=n.input.command?n.input.command.slice(0,wa):n.input.filePath??null;return t.prepare(`INSERT INTO guardrail_decisions
1
+ import{B as sr,a as Fs,b as Us,d as Bs,f as Ue,l as Zs,s as er,u as tr,z as nr}from"./chunk-TLCURHW3.js";import{a as Ls}from"./chunk-GLQLCBJS.js";import{b as Hs}from"./chunk-6W74CHNW.js";import{a as Vs}from"./chunk-W4YR2RO2.js";import{b as qs,c as Zt,d as Gs,e as Ks,h as Js}from"./chunk-ZWZADDXV.js";import{a as Ds}from"./chunk-7ZGTRXWS.js";import{e as Os,f as Ns}from"./chunk-36AXN6ZB.js";import{a as Yt,b as js}from"./chunk-J3SOEFRE.js";import{a as Vt,b as Ws}from"./chunk-SIU6STB2.js";import{e as Qs,i as zs,j as Xs,k as Ys}from"./chunk-X5C5W3E4.js";import{c as Ss,f as Is}from"./chunk-C52IPIKJ.js";import{a as Ts,c as vs}from"./chunk-MYVHVJWZ.js";import{a as ks,b as As,c as $s,d as Cs,l as Ms}from"./chunk-AV7T3SYT.js";import{a as Ps,b as _s}from"./chunk-Y5MFVVTM.js";import{g as Rs,h as Es}from"./chunk-WJDFR3WE.js";import{a as ve,d as ye}from"./chunk-56KNKUFF.js";import{s as bs,v as gt,w as xs,y as ue,z as Xt}from"./chunk-EHKI2RKD.js";import{a as Fe,b as Te,f as lt}from"./chunk-72SZI2UW.js";import{a as Ie,b as Wt}from"./chunk-FCPTN6NF.js";import{c as as,d as ds}from"./chunk-QOYAX2FT.js";import{e as he}from"./chunk-DSYKYZMT.js";import{$ as ws,D as gs,F as Qt,H as ea,K as ps,O as ta,U as fs,V as zt,W as ms,X as Le,Y as hs,Z as ys,na}from"./chunk-ZLUROC2Y.js";import{g as Kt,h as Vi}from"./chunk-BRK6M6LA.js";import{f as Jt,n as Zi}from"./chunk-UIBUZ2N3.js";import{a as cs,b as ie,c as us,d as ls,e as Gt}from"./chunk-2QNT5JDS.js";Xt();lt();var pt="tool-set",rr=["answer","code","full"],or={answer:["Read","Grep","Glob"],code:["Read","Grep","Glob","Edit","MultiEdit","Write","Bash"]},sa=.1;function ar(n){return{task:ir(n.message,2e3),agent:n.agent,channel:n.channel??null,...n.agentPrompt?{agentInstructions:ir(n.agentPrompt,600)}:{}}}var dr={bundle:Te({answer:"Read-only: the task can be done by reading, searching and listing files and then replying. It changes no file and runs no command (no tests, no git, no scripts).",code:"Change files or run commands in the workspace: edit or write files, run tests, builds, git or shell commands. Still all inside the workspace, with no web access, no sub-agents and no notebooks.",full:"Needs more than that, or it is not clear: fetching or searching the web, starting sub-agents, notebooks, or anything the other two do not clearly cover."},"Which set of built-in tools does an agent need to do this task completely? Pick the smallest set that is clearly enough.")};function cr(n,e=sa){let s=n?.bundle?.probabilities;if(!s)return"full";let r=en(s.answer),o=en(s.code),i=en(s.full);return r===null||o===null||i===null?"full":o+i<e?"answer":i<e?"code":"full"}function ur(n){let e=[...n].filter(t=>!t.startsWith("mcp__"));return e.every(t=>or.answer.includes(t))?"answer":e.every(t=>or.code.includes(t))?"code":"full"}function lr(n,e){return rr.indexOf(n)<rr.indexOf(e)}function en(n){return typeof n=="number"&&Number.isFinite(n)?n:null}function ir(n,e){return n.length>e?`${n.slice(0,e)}\u2026`:n}var gr=!1;function pr(n,e){let t=gt(pt);if(t!=="off")return t==="active"&&!gr&&(gr=!0,e(`[decisions] seat "${pt}" is set to active, but only shadow is built: it records and changes nothing`)),ue(pt,ar(n),dr,{incumbent:{bundle:"full"},links:[{kind:"task",id:n.taskId}],features:{agent:n.agent,channel:n.channel??"unknown"}}).then(s=>{if(!s)return null;let r=s.answers,o=cr(r),i=r.bundle?.probabilities??{};return{callId:s.callId,bundle:o,probabilities:i}}).catch(()=>null)}function fr(n,e,t){return n.then(s=>{if(!s||e.error||!e.eventsSeen)return;let r=[...e.toolUses.keys()],o=ur(r);xs(s.callId,"bundle",o,{kind:"outcome",labeledBy:"tool-use"});let i=a=>typeof s.probabilities[a]=="number"?s.probabilities[a].toFixed(2):"-";t(`[${e.agentId}] tool-set shadow: would start with ${s.bundle} (answer ${i("answer")}, code ${i("code")}, full ${i("full")}); run used ${r.filter(a=>!a.startsWith("mcp__")).join(", ")||"no built-in tool"} \u2192 needed ${o}`+(lr(s.bundle,o)?" \u2014 MISS":""))}).catch(()=>{})}function ra(n,e){return!n||n<=0||!e||e<=0?10:Math.min(200,Math.max(1,Math.round(e/n)))}function mr(n,e){let t=ra(n.contextTokens,n.turnInputTokens),s=n.idleMs<e.cacheTtlMinutes*6e4,r=.1*(t-1),o=e.freshTokens*(e.cacheWriteFactor+r),i=n.contextTokens;if(!i||i<=0)return{rotate:!1,resumeCost:null,freshCost:o,warm:s,requestsPerTurn:t};let a=i*((s?.1:e.cacheWriteFactor)+r);return{rotate:a>o*e.margin,resumeCost:a,freshCost:o,warm:s,requestsPerTurn:t}}function tn(n){let e=s=>`${Math.round(s/1e3)}k`,t=n.warm?"warm cache":"cold cache";return n.resumeCost===null?`resume: no context reading (${t})`:`${n.rotate?"start fresh":"resume"}: resume \u2248${e(n.resumeCost)}, fresh \u2248${e(n.freshCost)} input-token equivalents (${t}, ${n.requestsPerTurn} requests/turn)`}Xt();lt();var hr="session-continuity",yr={continues:Fe("The new request continues the task the user was already working on in the previous request, rather than starting a separate one.",{true:`The new request advances, narrows, corrects or follows up on the previous request's task \u2014 including terse replies such as "and the cost?" or "why?" that mean nothing on their own.`,false:"The new request opens a subject that could be answered without having seen the previous request, even if it arrived seconds later or belongs to the same broad field."}),needsHistory:Fe("Does the new request refer to something stated earlier in the conversation?")};function wr(n){let e=(n.recentRequests??[]).filter(Boolean);return{newRequest:nn(n.message,1200),previousRequest:n.previousMessage?nn(n.previousMessage,800):null,...e.length?{earlierRequests:e.map(t=>nn(t,400))}:{},minutesSinceLastTurn:n.minutesSinceLastTurn,turnsSoFar:n.turnCount,currentContextTokens:n.lastTurnContextTokens,agent:n.agentId,channel:n.channel}}function br(n,e){if(e.mechanicalRotation)return!1;let t=e.maxContinuity??.2,s=n.continues.noul,r=n.needsHistory.noul;return s<=t&&r<=t}function nn(n,e){let t=String(n??"");return t.length>e?t.slice(0,e):t}import{execa as It}from"execa";import{spawn as oa}from"node:child_process";import{createHash as ia}from"node:crypto";import{createInterface as aa}from"node:readline";var le=class extends Error{},da=n=>oa("codex",["app-server",...n.args],{cwd:n.cwd,env:n.env,stdio:["pipe","pipe","pipe"]}),sn=class{child;pending=new Map;nextId=0;dead=!1;busy=!1;threadId;idle;notify;failTurn;constructor(e,t){this.child=t(e),this.child.stderr.resume(),aa({input:this.child.stdout}).on("line",r=>{let o;try{o=JSON.parse(r)}catch{return}if(o.method&&o.id!==void 0)this.write({id:o.id,error:{code:-32601,message:"Interactive requests are not supported by AgentX"}});else if(o.id!==void 0){let i=this.pending.get(o.id);if(!i)return;this.pending.delete(o.id),o.error?i.reject(new Error(o.error.message||"Codex RPC failed")):i.resolve(o.result)}else o.method&&this.notify?.(o.method,o.params)}),this.child.on("error",r=>this.close(r)),this.child.stdin.on("error",r=>this.close(r)),this.child.on("exit",()=>this.close(new Error("Codex app-server exited")))}write(e){this.dead||this.child.stdin.write(JSON.stringify(e)+`
2
+ `)}rpc(e,t){if(this.dead)return Promise.reject(new Error("Codex connection closed"));let s=++this.nextId;return new Promise((r,o)=>{this.pending.set(s,{resolve:r,reject:o}),this.write({id:s,method:e,params:t})})}close(e=new Error("Codex connection closed")){if(this.dead)return;this.dead=!0,clearTimeout(this.idle);for(let s of this.pending.values())s.reject(e);this.pending.clear(),this.failTurn?.(e),this.child.kill("SIGTERM"),setTimeout(()=>{this.child.exitCode===null&&this.child.kill("SIGKILL")},5e3).unref()}},rn=class{constructor(e=da,t=8,s=3e5){this.launchProcess=e;this.capacity=t;this.idleMs=s}entries=new Map;stop(){for(let{connection:e}of this.entries.values())e.close();this.entries.clear()}async run(e){let t=Date.now();if(e.signal?.aborted)return{content:"",error:"task cancelled by operator",duration:0};let s=ia("sha256").update(JSON.stringify([e.cwd,e.model,e.bypass,e.args,Object.entries(e.env).sort(([b],[R])=>b.localeCompare(R))])).digest("hex"),r=this.entries.get(e.key);if(r?.connection.busy)throw new le("Conversation already running");r&&(r.fingerprint!==s||e.fresh||r.connection.dead)&&(r.connection.close(),this.entries.delete(e.key),r=void 0);let o=!!r;if(!r){if(this.entries.size>=this.capacity){let b=[...this.entries].find(([,R])=>!R.connection.busy);if(!b)throw new le("Codex warm process capacity reached");b[1].connection.close(),this.entries.delete(b[0])}try{r={fingerprint:s,connection:new sn(e,this.launchProcess)}}catch{throw new le("Could not start Codex app-server")}this.entries.set(e.key,r)}let i=r.connection;i.busy=!0,clearTimeout(i.idle);let a=!1,c="",d,u,l,f,h=!1,p=()=>i.close(new Error("task cancelled by operator"));e.signal?.addEventListener("abort",p,{once:!0});let I=setTimeout(()=>i.close(new Error("Codex turn timed out")),e.timeoutMs),A=setTimeout(()=>i.close(new Error("Codex initialization timed out")),15e3);try{o||(await i.rpc("initialize",{clientInfo:{name:"agentx",version:"1.0.0"},capabilities:{}}),i.write({method:"initialized",params:{}})),i.threadId&&i.threadId!==e.resume&&(await i.rpc("thread/unsubscribe",{threadId:i.threadId}),i.threadId=void 0);let b={cwd:e.cwd,model:e.model,approvalPolicy:"never",sandbox:e.bypass?"danger-full-access":"workspace-write"};u=(await i.rpc(e.resume&&!e.fresh?"thread/resume":"thread/start",{...b,...e.resume&&!e.fresh?{threadId:e.resume}:{}})).thread.id,i.threadId=u,clearTimeout(A),e.onEvent?.({type:"codex.ready",reused:o,startupMs:Date.now()-t,model:e.model});let E=new Promise((O,P)=>{i.failTurn=P,i.notify=(D,L)=>{if(L?.threadId!==u)return;let F=L.item,j={agentMessage:"agent_message",commandExecution:"command_execution",fileChange:"file_change",mcpToolCall:"mcp_tool_call"};if(e.onEvent?.({...L,type:D.replace("/","."),...F?{item:{...F,type:j[F.type]||F.type}}:{}}),D==="item/completed"&&F?.type==="agentMessage"&&F.phase==="final_answer"&&(d=F.text),D==="item/agentMessage/delta"&&(h||(h=!0,e.onEvent?.({type:"codex.first_output",elapsedMs:Date.now()-t,reused:o})),c+=L.delta,e.onDelta?.(L.delta,c)),D==="thread/tokenUsage/updated"){let H=L.tokenUsage.last;f=H.inputTokens;let W=H.cachedInputTokens||0;l={inputTokens:(l?.inputTokens||0)+Math.max(0,(H.inputTokens||0)-W),outputTokens:(l?.outputTokens||0)+(H.outputTokens||0),cacheReadTokens:(l?.cacheReadTokens||0)+W,cacheCreateTokens:(l?.cacheCreateTokens||0)+(H.cacheWriteInputTokens||0)}}D==="turn/completed"&&(L.turn.status==="completed"?O():P(new Error(L.turn.error?.message||`Codex turn ${L.turn.status}`)))}});return E.catch(()=>{}),a=!0,await i.rpc("turn/start",{threadId:u,input:[{type:"text",text:e.prompt,text_elements:[]}]}),await E,{content:d??c,codexSessionId:u,billedModel:e.model,usage:l,contextTokens:f,duration:Date.now()-t}}catch(b){if(i.close(),!a&&!e.signal?.aborted)throw new le(b.message);return{content:c,codexSessionId:u,usage:l,contextTokens:f,error:b.message,duration:Date.now()-t}}finally{clearTimeout(A),clearTimeout(I),e.signal?.removeEventListener("abort",p),i.notify=void 0,i.failTurn=void 0,i.busy=!1,i.dead?this.entries.get(e.key)?.connection===i&&this.entries.delete(e.key):(i.idle=setTimeout(()=>{i.close(),this.entries.delete(e.key)},this.idleMs),i.idle.unref())}}},xr=new rn;import{execFile as Ma}from"child_process";import{StringDecoder as We}from"string_decoder";import{mkdtempSync as Fr,readFileSync as Ur,rmSync as Hr}from"fs";import{join as xt}from"path";import{tmpdir as Br}from"os";function ft(n){let e=(n||"").trim();if(!e)return{message:"Unknown error from the model.",kind:"unknown",retryable:!1};if(/timed out after/i.test(e))return{message:e.slice(0,300),kind:"timeout",retryable:!0,raw:e};if(/not logged in|please run \/login/i.test(e))return{kind:"auth",retryable:!0,message:"The agent's Claude Code session is logged out.",fix:"Usually a transient OAuth refresh race under concurrent load \u2014 retry in a moment. If it persists, run `/login` in the agent's workspace.",raw:e};if(/specified API usage limits/i.test(e)){let d=e.match(/regain access on ([^.\n]+?)(?:\.|$)/i);return{kind:"usage_cap",retryable:!1,message:`Claude Code subscription /usage cap exhausted.${d?` Resets ${d[1].trim()}.`:""}`,fix:"Raise the cap at https://claude.ai/settings/usage (this is the user-set monthly limit on the OAuth account, not Anthropic API billing). If the daemon is using a different account than expected, check CLAUDE_CODE_OAUTH_TOKEN / ANTHROPIC_API_KEY in the spawn env \u2014 capped keys leak the same error.",raw:e}}if(/out of extra usage/i.test(e))return{kind:"overage_disabled",retryable:!0,message:"Claude Max-plan overage is unavailable (disabled or depleted at the org level).",fix:"Enable overage / extra usage at https://claude.ai/settings/usage (this is the subscription account's toggle \u2014 not Anthropic API billing). Warm sessions can still succeed via prompt cache; cold dispatches will keep failing until overage is re-enabled.",raw:e};if(/credit balance (is )?too low|out of credit|credit(s)? exhausted|insufficient credit/i.test(e))return{kind:"out_of_credits",retryable:!1,message:"The agent is out of Anthropic credits.",fix:"Top up at https://console.anthropic.com/settings/billing (or claude.ai/settings/usage for Max subscribers), then retry.",raw:e};let t=e.match(/\{.*\}\s*$/s)||e.match(/\{[\s\S]*\}/),s;if(t)try{s=JSON.parse(t[0])}catch{}let r=s?.error||s,o=typeof r?.type=="string"?r.type:void 0,i=typeof r?.message=="string"?r.message:void 0,a=e.match(/API Error:\s*(\d{3})/i),c=a?parseInt(a[1],10):void 0;return i&&/out of extra usage/i.test(i)?{kind:"overage_disabled",retryable:!0,message:"Claude Max-plan overage is unavailable (disabled or depleted at the org level).",fix:"Enable overage / extra usage at https://claude.ai/settings/usage (this is the subscription account's toggle \u2014 not Anthropic API billing). Warm sessions can still succeed via prompt cache; cold dispatches will keep failing until overage is re-enabled.",raw:e}:i&&/out of (extra )?usage|out of credit|credit(s)? exhausted|insufficient credit|credit balance (is )?too low|low credit balance/i.test(i)?{kind:"out_of_credits",retryable:!1,message:"The agent is out of Anthropic credits.",fix:"Top up at https://console.anthropic.com/settings/billing (or claude.ai/settings/usage for Max subscribers), then retry.",raw:e}:i&&/context|prompt is too long|too many tokens|maximum context length/i.test(i)?{kind:"context_too_large",retryable:!1,message:"The conversation has grown past what the model can hold.",fix:"Clear session history or switch the agent to a bigger context model.",raw:e}:o==="authentication_error"||i&&/authentication|invalid.*api.*key|no api key|not authenticated/i.test(i)?{kind:"auth",retryable:!1,message:"Authentication failed talking to Anthropic.",fix:"Check ANTHROPIC_API_KEY in .env (or the Claude Code login for claude-code tier agents).",raw:e}:o==="permission_error"||c===403?{kind:"permission",retryable:!1,message:i||"The API key doesn't have permission for this request.",raw:e}:o==="rate_limit_error"||c===429?{kind:"rate_limit",retryable:!0,message:"Anthropic's API rate-limited this request.",fix:"AgentX will retry automatically. If it recurs, lower the agent's concurrency or spread scheduled jobs.",raw:e}:o==="overloaded_error"||c===529||c===503?{kind:"overloaded",retryable:!0,message:"Anthropic's API is temporarily overloaded.",fix:"AgentX will retry in a moment.",raw:e}:o==="invalid_request_error"||c===400?{kind:"invalid_request",retryable:!1,message:i||"The model rejected the request as invalid.",raw:e}:c&&c>=500?{kind:"upstream_api",retryable:!0,message:i||`Anthropic API error (HTTP ${c}).`,fix:"Transient \u2014 retry. Check https://status.anthropic.com if it persists.",raw:e}:{kind:"unknown",retryable:!1,message:e.replace(/\s+/g," ").slice(0,220),raw:e}}function mt(n){return n.fix?`${n.message} \u2014 ${n.fix}`:n.message}function ht(n){if(!n||typeof n!="object")return;let e,t=-1,s=-1;for(let[r,o]of Object.entries(n)){let i=o&&typeof o=="object"?o:{},a=typeof i.costUSD=="number"?i.costUSD:0,c=(Number(i.inputTokens)||0)+(Number(i.outputTokens)||0)+(Number(i.cacheReadInputTokens)||0)+(Number(i.cacheCreationInputTokens)||0);(a>t||a===t&&c>s)&&(e=r,t=a,s=c)}return e}var Sr=null;function yt(){return Sr}function ju(n){Sr=n}function He(n){return`${n.agentId}:${n.channel}:${n.chatId}`}function ca(n,e){if(n.state()==="busy")return null;let s=n.snapshot(),r=n.opts?.model;return r&&e.model&&r!==e.model?`model changed (${r} -> ${e.model})`:e.resumeSessionId?s.claudeSessionId&&s.claudeSessionId!==e.resumeSessionId?`session changed (${s.claudeSessionId.slice(0,8)} -> ${e.resumeSessionId.slice(0,8)})`:null:s.claudeSessionId?"session rotated":null}var ke=class extends Error{constructor(t,s,r){super(t);this.scope=s;this.cap=r;this.name="RegistryCapExceeded"}},Ir=class{handles=new Map;sweeper;handleWorkspace=new Map;cfg;constructor(e){this.cfg={maxProcessesGlobal:e.maxProcessesGlobal??64,maxProcessesPerAgent:e.maxProcessesPerAgent??16,idleTimeoutMs:e.idleTimeoutMs??3e4,staleTimeoutMs:e.staleTimeoutMs??45*60*1e3,sweepIntervalMs:e.sweepIntervalMs??5e3,factory:e.factory,log:e.log??(()=>{}),currentWorkspaceHash:e.currentWorkspaceHash}}start(){this.sweeper||(this.sweeper=setInterval(()=>this.sweepIdle(),this.cfg.sweepIntervalMs),typeof this.sweeper.unref=="function"&&this.sweeper.unref())}async stop(){this.sweeper&&(clearInterval(this.sweeper),this.sweeper=void 0);let e=Array.from(this.handles.values());this.handles.clear(),await Promise.allSettled(e.map(t=>t.kill("registry-stop")))}acquire(e,t){let s=He(e),r=this.handles.get(s);if(r&&r.state()!=="dead"){let a=ca(r,t);if(!a)return r.claim?.(),r;this.handles.delete(s),this.handleWorkspace.delete(s),this.cfg.log(`[process-registry] respawning ${s}: ${a}`),r.kill(a).catch(()=>{})}if(this.handles.size>=this.cfg.maxProcessesGlobal&&this.evictOldestIdle({scope:"global"}),this.countForAgent(e.agentId)>=this.cfg.maxProcessesPerAgent&&this.evictOldestIdle({scope:"agent",agentId:e.agentId}),this.handles.size>=this.cfg.maxProcessesGlobal)throw new ke(`process registry at global cap (${this.cfg.maxProcessesGlobal}) and no idle handle to evict`,"global",this.cfg.maxProcessesGlobal);if(this.countForAgent(e.agentId)>=this.cfg.maxProcessesPerAgent)throw new ke(`process registry at per-agent cap for ${e.agentId} (${this.cfg.maxProcessesPerAgent}) and no idle handle to evict`,"agent",this.cfg.maxProcessesPerAgent);let i=this.cfg.factory.spawn(e,t);return this.handles.set(s,i),this.handleWorkspace.set(s,t.workspace),this.cfg.log(`[process-registry] spawned ${s}`),i}release(e,t={}){let s=He(e),r=this.handles.get(s);r&&(this.handles.delete(s),this.handleWorkspace.delete(s),t.kill&&r.kill(t.reason??"release"))}list(){return Array.from(this.handles.values()).map(e=>e.snapshot())}hasLive(e){let t=He(e),s=this.handles.get(t);return s!=null&&s.state()!=="dead"}async kill(e,t="operator"){let s=He(e),r=this.handles.get(s);r&&(this.handles.delete(s),this.handleWorkspace.delete(s),await r.kill(t))}countForAgent(e){let t=0;for(let s of this.handles.values())s.key.agentId===e&&s.state()!=="dead"&&(t+=1);return t}evictOldestIdle(e){let t,s=Number.POSITIVE_INFINITY;for(let o of this.handles.values()){if(o.state()!=="idle"||e.scope==="agent"&&o.key.agentId!==e.agentId)continue;let i=o.snapshot().lastTurnAt;i<s&&(s=i,t=o)}if(!t)return!1;let r=He(t.key);return this.handles.delete(r),t.kill("evicted (cap reached)"),this.cfg.log(`[process-registry] evicted ${r} (cap)`),!0}sweepIdle(){let e=Date.now();for(let[t,s]of this.handles.entries()){let r=s.snapshot();if(s.state()==="dead"){this.handles.delete(t),this.handleWorkspace.delete(t),this.cfg.log(`[process-registry] reaped dead ${t}`);continue}if(s.state()!=="idle")continue;let o=e-r.lastTurnAt;if(o>=this.cfg.staleTimeoutMs){this.handles.delete(t),this.handleWorkspace.delete(t),s.kill(`stale (idle ${Math.round(o/1e3)}s)`),this.cfg.log(`[process-registry] killed stale ${t}`);continue}if(o>=this.cfg.idleTimeoutMs){this.handles.delete(t),this.handleWorkspace.delete(t),s.kill(`idle (${Math.round(o/1e3)}s)`),this.cfg.log(`[process-registry] killed idle ${t}`);continue}if(this.cfg.currentWorkspaceHash){let i=this.handleWorkspace.get(t);if(i){let a=null;try{a=this.cfg.currentWorkspaceHash(s.key,i)}catch(c){this.cfg.log(`[process-registry] drift-check failed for ${t}: ${c?.message||c}`);continue}if(a!==r.claudeMdHash){this.handles.delete(t),this.handleWorkspace.delete(t);let c=r.claudeMdHash??"unmarked",d=a??"unmarked";s.kill(`claude-md drifted (${c} \u2192 ${d})`),this.cfg.log(`[process-registry] killed drifted ${t} (${c} \u2192 ${d})`)}}}}}};import{spawn as ua}from"child_process";import{randomUUID as la}from"crypto";import{existsSync as ga,readFileSync as pa}from"fs";import{resolve as fa}from"path";function ma(n){let e=fa(n,"CLAUDE.md");if(!ga(e))return null;try{let t=pa(e,"utf8");return Ms(t)}catch{return null}}var ha=20*60*1e3,ya=5e3,Be=class extends Error{constructor(t){super(`turn exceeded its ${Math.round(t/6e4)}m budget`);this.budgetMs=t}},je=class extends Error{constructor(t){super(`claude process stopped mid-turn (${t})`);this.reason=t}};function wa(n,e){return n.AGENTX_AGENT_ID=e.agentId,n.AGENTX_CHANNEL=e.channel,n.AGENTX_CHAT_ID=e.chatId,delete n.AGENTX_TASK_ID,n}var Tr=class{constructor(e={}){this.opts=e}spawn(e,t){return new on(e,t,this.opts)}},on=class{constructor(e,t,s){this.key=e;this.opts=t;this.factoryOpts=s;let r=s.binary??"claude",o=this.buildArgs(t),i=this.log=s.log??(()=>{});this.child=ua(r,o,{cwd:t.workspace,env:ye(wa({...process.env},e),t.billing),stdio:["pipe","pipe","pipe"]}),this.snap={key:e,pid:this.child.pid??null,claudeSessionId:t.resumeSessionId??null,state:"warm-cold",spawnedAt:Date.now(),lastTurnAt:Date.now(),turnCount:0,lastInputTokens:0,pendingTaskId:null,claudeMdHash:ma(t.workspace)},this.child.stdout.setEncoding("utf8"),this.child.stdout.on("data",a=>this.onStdout(a)),this.child.stderr.setEncoding("utf8"),this.child.stderr.on("data",a=>i(`[claude pid=${this.snap.pid}] stderr: ${a.trim()}`)),this.child.on("exit",a=>{this.exited=!0,this.exitCode=a,this.snap={...this.snap,state:"dead",deadReason:this.killReason??`exit=${a}`};let c=this.waiters.splice(0);for(let d of c)d(null)}),this.child.on("error",a=>{i(`[claude pid=${this.snap.pid}] spawn error: ${a.message}`),this.killReason=`spawn-error: ${a.message}`})}child;buf="";pendingEvents=[];waiters=[];exited=!1;exitCode=null;killReason;turnQueue=Promise.resolve();snap;log;state(){return this.snap.state}snapshot(){return{...this.snap}}async*runTurn(e){let t,s=new Promise(h=>{t=h}),r=this.turnQueue;if(this.turnQueue=r.then(()=>s),await r,this.exited||this.snap.state==="dead")throw t(),new Error(`claude process for ${this.key.agentId}:${this.key.chatId} is dead (${this.snap.deadReason??"?"})`);let o=Date.now();this.snap={...this.snap,state:"busy",pendingTaskId:e.taskId,lastTurnAt:o};let i=la(),a=JSON.stringify({type:"user",uuid:i,message:{role:"user",content:e.message}});this.child.stdin.write(a+`
3
+ `);let c=e.deadlineMs??ha,d=o+c,u=()=>(this.kill(`turn deadline (${Math.round(c/6e4)}m)`),new Be(c)),l=!1,f=null;try{for(;;){let h=d-Date.now();if(h<=0)throw u();let p=await this.nextEvent(h);if(p===null&&this.killReason)throw new je(this.killReason);if(p===null&&!this.exited)throw u();if(p===null)throw new Error(`claude process exited mid-turn (code=${this.exitCode}, reason=${this.snap.deadReason??"?"})`);if(!l){if(p.type==="user"&&p.uuid===i)l=!0,f&&(yield{type:f.type,raw:f});else if(p.type==="system"&&p.subtype==="init")f=p;else if(p.type==="result"){f=null;let I=typeof p.result=="string"?p.result:"";this.log(`[claude pid=${this.snap.pid}] dropped a reply no question asked for (${I.length} chars): ${I.slice(0,120)}`)}continue}if(yield{type:p.type,raw:p},p.type==="result"){this.onResultEvent(p);return}}}finally{let h=this.snap.state==="busy";this.snap={...this.snap,...h?{state:"idle",lastTurnAt:Date.now()}:{},pendingTaskId:null},t()}}claim(){this.snap.state!=="dead"&&(this.snap={...this.snap,lastTurnAt:Date.now()})}async kill(e){if(this.exited)return;this.killReason=e,this.snap={...this.snap,state:"dead",deadReason:e};try{this.child.kill("SIGTERM")}catch{}let t=this.waiters.splice(0);for(let r of t)r(null);let s=await new Promise(r=>{let o=setTimeout(()=>{try{this.child.kill("SIGKILL")}catch{}r(!0)},ya);this.child.once("exit",()=>{clearTimeout(o),r(!1)})})}buildArgs(e){let t=["-p","--input-format","stream-json","--output-format","stream-json","--verbose","--replay-user-messages"];return e.model&&t.push("--model",e.model),e.permissionMode==="bypassPermissions"&&t.push("--dangerously-skip-permissions"),e.resumeSessionId&&t.push("--resume",e.resumeSessionId),e.systemPromptAppend&&e.systemPromptAppend.trim().length>0&&t.push("--append-system-prompt",e.systemPromptAppend),e.extraArgs&&t.push(...e.extraArgs),this.factoryOpts.extraArgs&&t.push(...this.factoryOpts.extraArgs),t}onStdout(e){this.buf+=e;let t;for(;(t=this.buf.indexOf(`
4
+ `))!==-1;){let s=this.buf.slice(0,t);if(this.buf=this.buf.slice(t+1),!s.trim())continue;let r;try{r=JSON.parse(s)}catch{continue}this.waiters.length>0?this.waiters.shift()(r):this.pendingEvents.push(r)}}nextEvent(e){return this.pendingEvents.length>0?Promise.resolve(this.pendingEvents.shift()):this.exited?Promise.resolve(null):new Promise(t=>{let s=!1,r=setTimeout(()=>{if(s)return;s=!0;let i=this.waiters.indexOf(o);i>=0&&this.waiters.splice(i,1),t(null)},e),o=i=>{s||(s=!0,clearTimeout(r),t(i))};this.waiters.push(o)})}onResultEvent(e){let t=e.usage??{},s=typeof e.session_id=="string"?e.session_id:this.snap.claudeSessionId;this.snap={...this.snap,lastTurnAt:Date.now(),turnCount:this.snap.turnCount+1,lastInputTokens:typeof t.input_tokens=="number"?t.input_tokens:this.snap.lastInputTokens,claudeSessionId:s,state:"idle"}}};Gt();Zi();Wt();import{resolve as vr,join as kr}from"path";var ba=4e3;function wt(n){try{let e=kr(vr(n.root),".agentx","db.sqlite"),t=Jt({path:e});if(!t)return null;try{t.pragma("busy_timeout = 3000")}catch{}let s=Ie(),r=n.input.command?n.input.command.slice(0,ba):n.input.filePath??null;return t.prepare(`INSERT INTO guardrail_decisions
5
5
  (id, ts, agent_id, task_id, tool, command, resolved_target, matched_rule,
6
6
  verdict, effective_action, mode, severity, approver, ms)
7
7
  VALUES (@id, @ts, @agent_id, @task_id, @tool, @command, @resolved_target, @matched_rule,
8
8
  @verdict, @effective_action, @mode, @severity, @approver, @ms)`).run({id:s,ts:Date.now(),agent_id:n.input.agentId??null,task_id:n.taskId??null,tool:n.input.tool,command:r,resolved_target:n.verdict.resolvedTarget,matched_rule:n.verdict.ruleId,verdict:n.verdict.action,effective_action:n.verdict.effectiveAction,mode:n.mode,severity:n.verdict.severity,approver:n.approver??null,ms:n.ms??null}),s}catch(e){return process.stderr.write(`[agentx-guard] audit write failed: ${e?.message}
9
- `),null}}function el(n){let e=vr(Tr(n.root),".agentx","db.sqlite"),t=Kt({path:e});if(!t)return[];let s=[],r={};n.verdict&&(s.push("verdict = @verdict"),r.verdict=n.verdict),n.agentId&&(s.push("agent_id = @agentId"),r.agentId=n.agentId),n.taskId&&(s.push("task_id = @taskId"),r.taskId=n.taskId);let o="SELECT * FROM guardrail_decisions"+(s.length?` WHERE ${s.join(" AND ")}`:"")+" ORDER BY ts DESC LIMIT @limit";return r.limit=n.limit??50,t.prepare(o).all(r)}Wt();var ba=50,xa=6*60*60*1e3,wt=null,Ae=new Map;function rl(n){wt=n===null?null:String(n)}function Ar(){return wt}function Sa(n,e,t,s){let r=new URLSearchParams({agent:e,autonomy:t,task:s}).toString();return`curl -sf --max-time 10 -H 'Content-Type: application/json' --data-binary @- '${`http://127.0.0.1:${n}/guard/check?${r}`}' || { echo '[agentx-autonomy] guard unreachable: tool call blocked (fail-closed)' >&2; exit 2; }`}function $r(n,e,t){if(!ie(n))return{args:[]};if(!wt)return{error:`autonomy "${n}" cannot be enforced: guard hook endpoint is not configured`};let s={hooks:{PreToolUse:[{matcher:"*",hooks:[{type:"command",command:Sa(wt,e,n,t),timeout:15}]}]}},r=[];return n==="report"&&r.push("--disallowedTools","Write,Edit,MultiEdit,NotebookEdit"),r.push("--settings",JSON.stringify(s)),{args:r}}function Cr(n,e){return!ie(n)||e==="claude-code"?null:`autonomy "${n}" is only enforceable on the claude-code tier (agent tier: ${e??"unknown"}); refusing to run it with full permissions`}function Ia(n){for(let[e,t]of Ae)n-t.at>xa&&Ae.delete(e)}function Ta(n,e){let t=Date.now();Ia(t);let s=Ae.get(n)??{at:t,blocks:[]};s.blocks.length<ba&&s.blocks.push(e),s.at=t,Ae.set(n,s)}function Mr(n){if(!n)return[];let e=Ae.get(n);return Ae.delete(n),e?.blocks??[]}function kr(n){return JSON.stringify({hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:n}})}function ol(n,e){let t=n.tool_name??"unknown",s=typeof n.tool_input?.command=="string"?n.tool_input.command:void 0,r=typeof n.tool_input?.file_path=="string"?n.tool_input.file_path:typeof n.tool_input?.notebook_path=="string"?n.tool_input.notebook_path:void 0;try{let o=ds.safeParse(e.level),i=o.success?cs(o.data,{tool:t,command:s,filePath:r}):{allowed:!1,ruleId:"autonomy.invalid",reason:`unknown autonomy level "${e.level}"`};if(i.allowed)return{stdout:"",blocked:null};let a=o.success?o.data:"report",c=i.ruleId??"autonomy",d=i.reason??"blocked",u={ts:Date.now(),tool:t,target:(s??r??null)?.slice(0,300)??null,ruleId:c,reason:d},l={matched:!0,action:"deny",effectiveAction:"deny",ruleId:c,severity:"high",message:d,resolvedTarget:null};return yt({root:e.root,input:{tool:t,command:s??(r?void 0:t),filePath:r,agentId:e.agentId},verdict:l,mode:"enforce",taskId:e.taskId??null}),e.taskId&&Ta(e.taskId,u),{stdout:kr(`[agentx-autonomy] Blocked: this routine runs at autonomy "${a}" and ${d} (rule: ${c}). Do not work around it. Finish the task within the limit and list this step in your final answer as a recommendation.`),blocked:u}}catch(o){return{stdout:kr(`[agentx-autonomy] Guard error (fail-closed): ${o?.message??o}`),blocked:null}}}hs();var va=6*60*60*1e3,qe=new Map;function ka(n){for(let[e,t]of qe)n-t.at>va&&qe.delete(e)}function Pr(n,e){let t=Date.now();ka(t),qe.set(n,{at:t,limits:e})}function _r(n){qe.delete(n)}function Aa(n,e,t){let s=new URLSearchParams({person:"1",task:e,...t?{agent:t}:{}}).toString();return`curl -sf --max-time 10 -H 'Content-Type: application/json' --data-binary @- '${`http://127.0.0.1:${n}/guard/check?${s}`}' || { echo '[agentx-people] guard unreachable: tool call blocked (fail-closed)' >&2; exit 2; }`}function Rr(n,e,t){let s=Ar();if(!s)return{error:"this person's tool and skill limits cannot be enforced: guard hook endpoint is not configured"};let r={matcher:"*",hooks:[{type:"command",command:Aa(s,e,t),timeout:15}]},o=[...n],i=o.indexOf("--settings");if(i===-1)return o.push("--settings",JSON.stringify({hooks:{PreToolUse:[r]}})),{args:o};let a=JSON.parse(o[i+1]);return a.hooks=a.hooks??{},a.hooks.PreToolUse=[...a.hooks.PreToolUse??[],r],o[i+1]=JSON.stringify(a),{args:o}}function Er(n){return n==="claude-code"?null:`this person's tool and skill limits are only enforceable on the claude-code tier (agent tier: ${n??"unknown"}); refusing to run without them`}function on(n){return JSON.stringify({hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:n}})}function $a(n,e,t){if(n.tools.some(s=>Le(s,e)))return{skill:null,what:e};if(e==="Skill"){let s=typeof t.skill=="string"?t.skill:typeof t.command=="string"?t.command:"";if(s&&n.skills.some(r=>Le(r,s)))return{skill:s,what:`the skill ${s}`}}return null}function ul(n,e){let t=n.tool_name??"unknown",s=n.tool_input??{};try{let r=e.taskId?qe.get(e.taskId):void 0;if(!r)return{stdout:on("[agentx-people] No limits are on record for this run, so the call is blocked (fail-closed)."),blocked:null};let{limits:o}=r,i=$a(o,t,s);if(!i)return{stdout:"",blocked:null};let a=`${o.name} may not use ${i.what}`,c={matched:!0,action:"deny",effectiveAction:"deny",ruleId:"people.deny",severity:"high",message:a,resolvedTarget:null};return yt({root:e.root,input:{tool:t,command:typeof s.command=="string"?s.command:t,agentId:e.agentId},verdict:c,mode:"enforce",taskId:e.taskId??null}),{stdout:on(`[agentx-people] Blocked: ${a} here (set by the owner). Do not work around it. Finish what you can without it and say in your answer what was not done and why.`),blocked:{personId:o.personId,tool:t,skill:i.skill,reason:a}}}catch(r){return{stdout:on(`[agentx-people] Guard error (fail-closed): ${r?.message??r}`),blocked:null}}}var Ma=5e3;function X(n){let e=pt(n);if(e.kind==="invalid_request"||e.kind==="unknown"){let t=(n||"").replace(/\s+/g," ").slice(0,800);t&&process.stderr.write(`[agentx][model-error][${e.kind}] raw=${t}
10
- `)}return{error:ft(e),errorKind:e.kind}}function Br(){return`Claude Code CLI not found on PATH. Install it before starting an agent: https://docs.claude.com/en/docs/claude-code . On Linux/macOS: npm i -g @anthropic-ai/claude-code then verify with claude --version. If you don't intend to use the claude-code engine, set the agent's tier to "sdk" or "orchestrator" in agentx.json.`}function xt(){return`Codex CLI not found on PATH. Install it before starting an agent: npm i -g @openai/codex then verify with codex --version. If you don't intend to use the codex-cli engine, set the agent's tier to "claude-code", "sdk", or "orchestrator" in agentx.json.`}function Dr(){return`OpenCode CLI not found on PATH. Install it from https://opencode.ai/docs/ and verify with opencode --version. If you don't intend to use the opencode engine, set the agent's tier to "claude-code", "codex-cli", "sdk", or "orchestrator" in agentx.json.`}function pe(n,e,t){let s=[];if(e.context&&!t){let r=e.context,o=["","[Environment]"],i=r.channel==="gitlab"||r.channel?.startsWith("webhook:"),a=r.channel==="telegram";if(r.channel&&o.push(`Channel: ${r.channel}`),r.group&&o.push(`Group: ${r.group}`),r.sender&&o.push(`Message from: ${r.sender}`),r.myHandle&&o.push(`Your handle on this channel: ${r.myHandle}`),i&&(o.push(""),o.push("[IMPORTANT: You are responding to a GitLab comment/event]"),o.push("- Keep it short \u2014 3-5 lines for the main message. Humans scan, not read"),o.push("- Lead with the result or action, not a narration of what you plan to do"),o.push("- Use <details><summary>Details</summary>\\n\\ncontent\\n</details> for verbose output (logs, full commands, step-by-step)"),o.push("- Do NOT mention Telegram handles \u2014 they don't work on GitLab"),o.push("- Do NOT try to delegate to other agents \u2014 reply directly"),o.push("- Reference issues with #IID and MRs with !IID")),a&&r.peers?.length){o.push(""),o.push("[Team \u2014 other agents you can mention to delegate or collaborate]");for(let c of r.peers){let d=c.handle?` (mention: ${c.handle})`:"",u=c.role?` \u2014 ${c.role}`:"";o.push(`\u2022 ${c.name}${d}${u}`)}o.push(""),o.push("To involve another agent, mention their handle in your response and they will automatically see it and reply.")}s.push(o.join(`
9
+ `),null}}function tl(n){let e=kr(vr(n.root),".agentx","db.sqlite"),t=Jt({path:e});if(!t)return[];let s=[],r={};n.verdict&&(s.push("verdict = @verdict"),r.verdict=n.verdict),n.agentId&&(s.push("agent_id = @agentId"),r.agentId=n.agentId),n.taskId&&(s.push("task_id = @taskId"),r.taskId=n.taskId);let o="SELECT * FROM guardrail_decisions"+(s.length?` WHERE ${s.join(" AND ")}`:"")+" ORDER BY ts DESC LIMIT @limit";return r.limit=n.limit??50,t.prepare(o).all(r)}Gt();var xa=50,Sa=6*60*60*1e3,bt=null,Ae=new Map;function ol(n){bt=n===null?null:String(n)}function $r(){return bt}function Ia(n,e,t,s){let r=new URLSearchParams({agent:e,autonomy:t,task:s}).toString();return`curl -sf --max-time 10 -H 'Content-Type: application/json' --data-binary @- '${`http://127.0.0.1:${n}/guard/check?${r}`}' || { echo '[agentx-autonomy] guard unreachable: tool call blocked (fail-closed)' >&2; exit 2; }`}function Cr(n,e,t){if(!ie(n))return{args:[]};if(!bt)return{error:`autonomy "${n}" cannot be enforced: guard hook endpoint is not configured`};let s={hooks:{PreToolUse:[{matcher:"*",hooks:[{type:"command",command:Ia(bt,e,n,t),timeout:15}]}]}},r=[];return n==="report"&&r.push("--disallowedTools","Write,Edit,MultiEdit,NotebookEdit"),r.push("--settings",JSON.stringify(s)),{args:r}}function Mr(n,e){return!ie(n)||e==="claude-code"?null:`autonomy "${n}" is only enforceable on the claude-code tier (agent tier: ${e??"unknown"}); refusing to run it with full permissions`}function Ta(n){for(let[e,t]of Ae)n-t.at>Sa&&Ae.delete(e)}function va(n,e){let t=Date.now();Ta(t);let s=Ae.get(n)??{at:t,blocks:[]};s.blocks.length<xa&&s.blocks.push(e),s.at=t,Ae.set(n,s)}function Pr(n){if(!n)return[];let e=Ae.get(n);return Ae.delete(n),e?.blocks??[]}function Ar(n){return JSON.stringify({hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:n}})}function il(n,e){let t=n.tool_name??"unknown",s=typeof n.tool_input?.command=="string"?n.tool_input.command:void 0,r=typeof n.tool_input?.file_path=="string"?n.tool_input.file_path:typeof n.tool_input?.notebook_path=="string"?n.tool_input.notebook_path:void 0;try{let o=cs.safeParse(e.level),i=o.success?us(o.data,{tool:t,command:s,filePath:r}):{allowed:!1,ruleId:"autonomy.invalid",reason:`unknown autonomy level "${e.level}"`};if(i.allowed)return{stdout:"",blocked:null};let a=o.success?o.data:"report",c=i.ruleId??"autonomy",d=i.reason??"blocked",u={ts:Date.now(),tool:t,target:(s??r??null)?.slice(0,300)??null,ruleId:c,reason:d},l={matched:!0,action:"deny",effectiveAction:"deny",ruleId:c,severity:"high",message:d,resolvedTarget:null};return wt({root:e.root,input:{tool:t,command:s??(r?void 0:t),filePath:r,agentId:e.agentId},verdict:l,mode:"enforce",taskId:e.taskId??null}),e.taskId&&va(e.taskId,u),{stdout:Ar(`[agentx-autonomy] Blocked: this routine runs at autonomy "${a}" and ${d} (rule: ${c}). Do not work around it. Finish the task within the limit and list this step in your final answer as a recommendation.`),blocked:u}}catch(o){return{stdout:Ar(`[agentx-autonomy] Guard error (fail-closed): ${o?.message??o}`),blocked:null}}}ys();var ka=6*60*60*1e3,qe=new Map;function Aa(n){for(let[e,t]of qe)n-t.at>ka&&qe.delete(e)}function _r(n,e){let t=Date.now();Aa(t),qe.set(n,{at:t,limits:e})}function Rr(n){qe.delete(n)}function $a(n,e,t){let s=new URLSearchParams({person:"1",task:e,...t?{agent:t}:{}}).toString();return`curl -sf --max-time 10 -H 'Content-Type: application/json' --data-binary @- '${`http://127.0.0.1:${n}/guard/check?${s}`}' || { echo '[agentx-people] guard unreachable: tool call blocked (fail-closed)' >&2; exit 2; }`}function Er(n,e,t){let s=$r();if(!s)return{error:"this person's tool and skill limits cannot be enforced: guard hook endpoint is not configured"};let r={matcher:"*",hooks:[{type:"command",command:$a(s,e,t),timeout:15}]},o=[...n],i=o.indexOf("--settings");if(i===-1)return o.push("--settings",JSON.stringify({hooks:{PreToolUse:[r]}})),{args:o};let a=JSON.parse(o[i+1]);return a.hooks=a.hooks??{},a.hooks.PreToolUse=[...a.hooks.PreToolUse??[],r],o[i+1]=JSON.stringify(a),{args:o}}function Dr(n){return n==="claude-code"?null:`this person's tool and skill limits are only enforceable on the claude-code tier (agent tier: ${n??"unknown"}); refusing to run without them`}function an(n){return JSON.stringify({hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:n}})}function Ca(n,e,t){if(n.tools.some(s=>Le(s,e)))return{skill:null,what:e};if(e==="Skill"){let s=typeof t.skill=="string"?t.skill:typeof t.command=="string"?t.command:"";if(s&&n.skills.some(r=>Le(r,s)))return{skill:s,what:`the skill ${s}`}}return null}function ll(n,e){let t=n.tool_name??"unknown",s=n.tool_input??{};try{let r=e.taskId?qe.get(e.taskId):void 0;if(!r)return{stdout:an("[agentx-people] No limits are on record for this run, so the call is blocked (fail-closed)."),blocked:null};let{limits:o}=r,i=Ca(o,t,s);if(!i)return{stdout:"",blocked:null};let a=`${o.name} may not use ${i.what}`,c={matched:!0,action:"deny",effectiveAction:"deny",ruleId:"people.deny",severity:"high",message:a,resolvedTarget:null};return wt({root:e.root,input:{tool:t,command:typeof s.command=="string"?s.command:t,agentId:e.agentId},verdict:c,mode:"enforce",taskId:e.taskId??null}),{stdout:an(`[agentx-people] Blocked: ${a} here (set by the owner). Do not work around it. Finish what you can without it and say in your answer what was not done and why.`),blocked:{personId:o.personId,tool:t,skill:i.skill,reason:a}}}catch(r){return{stdout:an(`[agentx-people] Guard error (fail-closed): ${r?.message??r}`),blocked:null}}}var Pa=5e3;function X(n){let e=ft(n);if(e.kind==="invalid_request"||e.kind==="unknown"){let t=(n||"").replace(/\s+/g," ").slice(0,800);t&&process.stderr.write(`[agentx][model-error][${e.kind}] raw=${t}
10
+ `)}return{error:mt(e),errorKind:e.kind}}function jr(){return`Claude Code CLI not found on PATH. Install it before starting an agent: https://docs.claude.com/en/docs/claude-code . On Linux/macOS: npm i -g @anthropic-ai/claude-code then verify with claude --version. If you don't intend to use the claude-code engine, set the agent's tier to "sdk" or "orchestrator" in agentx.json.`}function St(){return`Codex CLI not found on PATH. Install it before starting an agent: npm i -g @openai/codex then verify with codex --version. If you don't intend to use the codex-cli engine, set the agent's tier to "claude-code", "sdk", or "orchestrator" in agentx.json.`}function Or(){return`OpenCode CLI not found on PATH. Install it from https://opencode.ai/docs/ and verify with opencode --version. If you don't intend to use the opencode engine, set the agent's tier to "claude-code", "codex-cli", "sdk", or "orchestrator" in agentx.json.`}function pe(n,e,t){let s=[];if(e.context&&!t){let r=e.context,o=["","[Environment]"],i=r.channel==="gitlab"||r.channel?.startsWith("webhook:"),a=r.channel==="telegram";if(r.channel&&o.push(`Channel: ${r.channel}`),r.group&&o.push(`Group: ${r.group}`),r.sender&&o.push(`Message from: ${r.sender}`),r.myHandle&&o.push(`Your handle on this channel: ${r.myHandle}`),i&&(o.push(""),o.push("[IMPORTANT: You are responding to a GitLab comment/event]"),o.push("- Keep it short \u2014 3-5 lines for the main message. Humans scan, not read"),o.push("- Lead with the result or action, not a narration of what you plan to do"),o.push("- Use <details><summary>Details</summary>\\n\\ncontent\\n</details> for verbose output (logs, full commands, step-by-step)"),o.push("- Do NOT mention Telegram handles \u2014 they don't work on GitLab"),o.push("- Do NOT try to delegate to other agents \u2014 reply directly"),o.push("- Reference issues with #IID and MRs with !IID")),a&&r.peers?.length){o.push(""),o.push("[Team \u2014 other agents you can mention to delegate or collaborate]");for(let c of r.peers){let d=c.handle?` (mention: ${c.handle})`:"",u=c.role?` \u2014 ${c.role}`:"";o.push(`\u2022 ${c.name}${d}${u}`)}o.push(""),o.push("To involve another agent, mention their handle in your response and they will automatically see it and reply.")}s.push(o.join(`
11
11
  `))}return e.context?.replyToText&&(s.push(""),s.push(`[Replying to]: ${e.context.replyToText}`)),e.context?.mediaPath&&(s.push(""),s.push(`[Attached file: ${e.context.mediaPath}]`),s.push(`[File type: ${e.context.mediaType||"unknown"}]`),e.context.mediaType?.startsWith("image/")?s.push("Please read/view this image file and describe or respond to it."):e.context.mediaType?.startsWith("audio/")?s.push("Please transcribe this audio file and respond to its content."):e.context.mediaType?.startsWith("video/")?s.push("A video file is attached. Describe what you can determine about it."):s.push("Please read this file and respond based on its content.")),t&&(s.push(""),s.push(t)),s.push(""),s.push(e.message),s.join(`
12
- `)}function jr(n,e,t,s,r,o,i=[]){let a=["-p",e,"--output-format",t?"stream-json":"json"];t&&a.push("--verbose"),s&&a.push("--resume",s);let c=r||n.model;return c&&a.push("--model",c),n.permissionMode==="bypassPermissions"&&a.push("--dangerously-skip-permissions"),o&&o.trim().length>0&&a.push("--append-system-prompt",o),a.push(...i),a}function an(n,e){return!e||e.trim().length===0?n:`[System]
12
+ `)}function qr(n,e,t,s,r,o,i=[]){let a=["-p",e,"--output-format",t?"stream-json":"json"];t&&a.push("--verbose"),s&&a.push("--resume",s);let c=r||n.model;return c&&a.push("--model",c),n.permissionMode==="bypassPermissions"&&a.push("--dangerously-skip-permissions"),o&&o.trim().length>0&&a.push("--append-system-prompt",o),a.push(...i),a}function dn(n,e){return!e||e.trim().length===0?n:`[System]
13
13
  ${e.trim()}
14
14
 
15
15
  [User]
16
- ${n}`}function Pa(n,e,t,s,r){let o=["run","--format","json","--thinking"],i=t||n.model;return i&&o.push("--model",i),r&&o.push("--session",r),n.permissionMode==="bypassPermissions"&&o.push("--auto"),o.push(an(e,s)),o}function _a(n){if(!n||typeof n!="object"||n.type!=="error")return;let e=n.error?.message??n.error??n.message??n.part?.error?.message;return typeof e=="string"&&e.trim()?e.trim():void 0}function Or(n){return JSON.stringify(n)}function qr(){let n=process.argv[1]||"dist/cli.js";return["-c",`mcp_servers.agentx.command=${Or(process.execPath)}`,"-c",`mcp_servers.agentx.args=[${[n,"serve","--stdio","--cwd",process.cwd()].map(Or).join(",")}]`]}function Wr(n,e,t,s,r,o,i){let a=i?["exec","resume"]:["exec"];a.push("--ignore-user-config","--skip-git-repo-check",...qr()),i||a.push("--color","never");let c=s||n.model;return c&&a.push("--model",c),n.permissionMode==="bypassPermissions"?a.push("--dangerously-bypass-approvals-and-sandbox"):i||a.push("--sandbox","workspace-write"),(t||i||o)&&a.push("--json"),o&&a.push("--output-last-message",o),i&&a.push(i),a.push(an(e,r)),a}function It(n,e){let t=ve(n.workspace),s=t.HOME||process.env.HOME,r=[t.PATH||"",s?`${s}/.bun/bin`:"",s?`${s}/.local/bin`:"",s?`${s}/.opencode/bin`:"","/opt/homebrew/bin","/usr/local/bin"].filter(Boolean);return t.PATH=Array.from(new Set(r.flatMap(o=>o.split(":")).filter(Boolean))).join(":"),Ge(t,e)}function Ge(n,e){return n.AGENTX_AGENT_ID=e.agentId,e.runningTaskId&&(n.AGENTX_TASK_ID=e.runningTaskId),e.context?.channel&&(n.AGENTX_CHANNEL=e.context.channel),e.context?.chatId&&(n.AGENTX_CHAT_ID=e.context.chatId),n}function Tt(n={}){return{channel:n.channel||"api",chatId:n.chatId||n.group||n.sender||"default"}}function Ra(n,e){let t=It(n,e),s={};if(t.OPENCODE_CONFIG_CONTENT)try{s=JSON.parse(t.OPENCODE_CONFIG_CONTENT)}catch{}let r={...s.mcp||{}};for(let[i,a]of Object.entries(n.mcp||{}))r[i]=a.type==="http"?{type:"remote",url:a.url,headers:a.headers}:{type:"local",command:[a.command,...a.args||[]],environment:a.env};let o=process.argv[1]||"dist/cli.js";return r.agentx={type:"local",command:[process.execPath,o,"serve","--stdio","--cwd",process.cwd()]},t.OPENCODE_CONFIG_CONTENT=JSON.stringify({...s,mcp:r}),t}function Ea(n){if(!n||typeof n!="object")return;if(typeof n.delta=="string")return n.delta;if(typeof n.text_delta=="string")return n.text_delta;if(typeof n.message=="string"&&/message|delta/i.test(String(n.type||"")))return n.message;if(typeof n.text=="string"&&/message|delta|response/i.test(String(n.type||"")))return n.text;let e=n.item||n.msg||n.message;if(e?.type==="agent_message"&&typeof e.text=="string"||typeof e?.text=="string"&&/message|delta|response|item/i.test(String(n.type||"")))return e.text;let t=e?.content;if(Array.isArray(t)){let s=t.map(r=>typeof r?.text=="string"?r.text:"").join("");if(s)return s}}function ge(...n){for(let e of n)if(typeof e=="number"&&Number.isFinite(e))return e;return 0}function dn(n,e=0){if(!n||typeof n!="object"||e>4)return;let t=n.usage||n.token_usage||n.tokenUsage||n.metrics?.usage;if(t&&typeof t=="object")return{inputTokens:ge(t.input_tokens,t.inputTokens,t.prompt_tokens,t.promptTokens),outputTokens:ge(t.output_tokens,t.outputTokens,t.completion_tokens,t.completionTokens),cacheReadTokens:ge(t.cache_read_input_tokens,t.cached_input_tokens,t.cacheReadTokens,t.cachedInputTokens),cacheCreateTokens:ge(t.cache_creation_input_tokens,t.cacheCreateTokens)};for(let s of[n.msg,n.message,n.response,n.result,n.item]){let r=dn(s,e+1);if(r)return r}}function Gr(n){if(!(!n||typeof n!="object"))return typeof n.model=="string"&&n.model||typeof n.msg?.model=="string"&&n.msg.model||typeof n.message?.model=="string"&&n.message.model||typeof n.response?.model=="string"&&n.response.model||void 0}function cn(n,e=0){if(!(!n||typeof n!="object"||e>4)){for(let t of["thread_id","threadId","session_id","sessionId","conversation_id","conversationId"]){let s=n[t];if(typeof s=="string"&&s.trim())return s.trim()}for(let t of[n.msg,n.message,n.response,n.result,n.item]){let s=cn(t,e+1);if(s)return s}}}function Da(n){let e=typeof n=="string"?n:n?.toString("utf8")||"",t,s,r,o;for(let i of e.split(`
17
- `))if(i.trim())try{let a=JSON.parse(i);t=dn(a)||t,s=Gr(a)||s,r=cn(a)||r,o=Kr(a)||o}catch{}return{usage:t,billedModel:s,sessionId:r,apiError:o}}function Kr(n){if(!(!n||typeof n!="object")){if(n.type==="error"&&typeof n.message=="string")return Nr(n.message);if(n.type==="turn.failed"){let e=n.error?.message??n.error;if(typeof e=="string")return Nr(e)}}}function Nr(n){let e=n.trim();if(e.startsWith("{"))try{let t=JSON.parse(e),s=t?.error?.message??t?.message;if(typeof s=="string"&&s.trim())return s.trim()}catch{}return e}function Oa(n){let e=n.permissionMode||"default",t=e==="bypassPermissions",s=t?"bypassPermissions (--dangerously-skip-permissions)":`${e} (no skip-permissions flag)`;return{configured:e,skipPermissions:t,summary:s}}function un(n,e,t,s,r){let o=Oa(e),i=t||e.model||"<default>",a=s?` resume=${s.slice(0,8)}\u2026`:"";process.stderr.write(`[claude-spawn] agent=${n} via=${r} model=${i} perm=${o.summary}${a}
18
- `)}function Na(n){try{let e=JSON.parse(n);if(e&&e.is_error&&typeof e.result=="string")return e.result;if(e&&e.error&&typeof e.error=="string")return e.error}catch{}return null}function La(n){try{let e=JSON.parse(n),t=e.usage?{inputTokens:e.usage.input_tokens||0,outputTokens:e.usage.output_tokens||0,cacheReadTokens:e.usage.cache_read_input_tokens||0,cacheCreateTokens:e.usage.cache_creation_input_tokens||0}:void 0,s=typeof e.model=="string"&&e.model||typeof e.message?.model=="string"&&e.message.model||mt(e.modelUsage)||void 0;return{text:e.result||e.content||"",sessionId:e.session_id,usage:t,billedModel:s,numTurns:typeof e.num_turns=="number"?e.num_turns:void 0,costUsd:typeof e.total_cost_usd=="number"?e.total_cost_usd:void 0}}catch{return{text:n}}}async function Jr(n,e,t,s,r){let o=Date.now(),i=pe(n,e,t),a=zr(e);if("error"in a)return{content:"",error:a.error,duration:Date.now()-o};let c=jr(n,i,!1,s,e.model,e.systemPromptAppend,[...e.claudeArgs??[],...a.args]);if(un(e.agentId,n,e.model,s,"spawn"),r?.aborted)return{content:"",error:"task cancelled by operator",duration:Date.now()-o};let d;try{let u=Math.max(6e4,(n.maxExecutionMinutes??20)*6e4),{stdout:l,stderr:f,exitCode:h,killed:p}=await new Promise(b=>{let R=ye(Ge(ve(n.workspace),e),n.billing),E=!1,O=Ca("claude",c,{cwd:n.workspace,timeout:u,maxBuffer:10*1024*1024,env:{...R,HOME:R.HOME||"/home/"+(R.USER||"user")}},(P,D,L)=>{b({stdout:D||"",stderr:L||"",exitCode:P?P.code??1:0,killed:E})});if(O.stdin?.end(),r){let P=()=>{E=!0,d=r.reason?.message||(typeof r.reason=="string"?r.reason:"task cancelled by operator");try{O.kill("SIGTERM")}catch{}setTimeout(()=>{try{O.killed||O.kill("SIGKILL")}catch{}},3e3).unref?.()};r.aborted?P():r.addEventListener("abort",P,{once:!0})}});if(p)return{content:"",error:d||"task cancelled by operator",errorKind:"cancelled",duration:Date.now()-o};if(!l&&h!==0){let b,R=Date.now()-o;return h===143&&R<u-Ma?{content:"",error:`Claude Code was stopped (SIGTERM) after ${Math.round(R/1e3)}s, before its ${Math.round(u/6e4)}m time limit`,errorKind:"interrupted",duration:R}:(h===143?b=`Claude Code timed out after ${Math.round(u/6e4)}m (SIGTERM). Bump agent.maxExecutionMinutes for "${n.name||"this agent"}" if tasks need longer.`:h==="ENOENT"||/ENOENT|spawn claude/i.test(f||"")?b=Br():b=f?.trim()||`Claude Code exited with code ${h}`,{content:"",...X(b),duration:Date.now()-o})}let I=Na(l);if(I)return{content:"",...X(I),duration:Date.now()-o};let A=La(l);return{content:A.text,duration:Date.now()-o,claudeSessionId:A.sessionId,usage:A.usage,numTurns:A.numTurns,costUsd:A.costUsd,billedModel:A.billedModel}}catch(u){return console.error(`[runtime] execFile threw: ${u.message}`),{content:"",error:u.message||"Claude Code failed",duration:Date.now()-o}}}async function Qr(n,e,t,s,r,o,i){let a=Date.now();if(i?.aborted)return{content:"",error:"task cancelled by operator",duration:Date.now()-a};let c=pe(n,e,s),d=zr(e);if("error"in d)return{content:"",error:d.error,duration:Date.now()-a};let u=jr(n,c,!0,r,e.model,e.systemPromptAppend,[...e.claudeArgs??[],...d.args]);un(e.agentId,n,e.model,r,"stream");let l="",f,h,p,I,A,b,R;try{let E=Math.max(6e4,(n.maxExecutionMinutes??20)*6e4),O=ye(Ge(ve(n.workspace),e),n.billing),P=St("claude",u,{cwd:n.workspace,timeout:E,reject:!1,env:O,extendEnv:!1,buffer:!1,stdin:"ignore"}),D=()=>{},L=new Promise(T=>{D=T}),F=!1,j;if(i){let T=()=>{F=!0,j=i.reason?.message||(typeof i.reason=="string"?i.reason:"task cancelled by operator");try{P.kill("SIGTERM")}catch{}setTimeout(()=>{try{P.kill("SIGKILL")}catch{}},3e3).unref?.()};i.aborted?T():i.addEventListener("abort",T,{once:!0})}let H="",W=new We("utf8");P.stdout&&P.stdout.on("data",T=>{H+=W.write(T);let w=H.split(`
19
- `);H=w.pop()||"";for(let _ of w)if(_.trim())try{let x=JSON.parse(_);if(o)try{o(x)}catch{}if(x.type==="assistant"&&x.message?.usage){let k=x.message.usage,K=(k.input_tokens||0)+(k.cache_read_input_tokens||0)+(k.cache_creation_input_tokens||0);K>0&&(I=K)}if(x.type==="assistant"&&x.message?.content){for(let k of x.message.content)if(k.type==="text"&&k.text){let K=k.text.slice(l.length);K&&(l=k.text,t(K,l))}}if(x.type==="content_block_delta"&&x.delta?.text&&(l+=x.delta.text,t(x.delta.text,l)),x.type==="result"&&D(),x.type==="result"&&x.result){if(x.is_error&&typeof x.result=="string")R=x.result;else{let k=(typeof x.result=="string",x.result);if(typeof k=="string"&&k.length>l.length){let K=k.slice(l.length);l=k,K&&t(K,l)}}x.usage&&(h={inputTokens:x.usage.input_tokens||0,outputTokens:x.usage.output_tokens||0,cacheReadTokens:x.usage.cache_read_input_tokens||0,cacheCreateTokens:x.usage.cache_creation_input_tokens||0}),typeof x.model=="string"?f=x.model:f=mt(x.modelUsage)||f,typeof x.session_id=="string"&&(p=x.session_id),typeof x.num_turns=="number"&&(A=x.num_turns),typeof x.total_cost_usd=="number"&&(b=x.total_cost_usd)}x.type==="system"&&x.subtype==="init"&&(typeof x.model=="string"&&(f=x.model),process.env.AGENTX_DEBUG_CLAUDE_ENV==="1"&&process.stderr.write(`[claude-init] agent=${e.agentId} apiKeySource=${x.apiKeySource} version=${x.claude_code_version} model=${x.model} permMode=${x.permissionMode}
16
+ ${n}`}function _a(n,e,t,s,r){let o=["run","--format","json","--thinking"],i=t||n.model;return i&&o.push("--model",i),r&&o.push("--session",r),n.permissionMode==="bypassPermissions"&&o.push("--auto"),o.push(dn(e,s)),o}function Ra(n){if(!n||typeof n!="object"||n.type!=="error")return;let e=n.error?.message??n.error??n.message??n.part?.error?.message;return typeof e=="string"&&e.trim()?e.trim():void 0}function Nr(n){return JSON.stringify(n)}function Wr(){let n=process.argv[1]||"dist/cli.js";return["-c",`mcp_servers.agentx.command=${Nr(process.execPath)}`,"-c",`mcp_servers.agentx.args=[${[n,"serve","--stdio","--cwd",process.cwd()].map(Nr).join(",")}]`]}function Gr(n,e,t,s,r,o,i){let a=i?["exec","resume"]:["exec"];a.push("--ignore-user-config","--skip-git-repo-check",...Wr()),i||a.push("--color","never");let c=s||n.model;return c&&a.push("--model",c),n.permissionMode==="bypassPermissions"?a.push("--dangerously-bypass-approvals-and-sandbox"):i||a.push("--sandbox","workspace-write"),(t||i||o)&&a.push("--json"),o&&a.push("--output-last-message",o),i&&a.push(i),a.push(dn(e,r)),a}function Tt(n,e){let t=ve(n.workspace),s=t.HOME||process.env.HOME,r=[t.PATH||"",s?`${s}/.bun/bin`:"",s?`${s}/.local/bin`:"",s?`${s}/.opencode/bin`:"","/opt/homebrew/bin","/usr/local/bin"].filter(Boolean);return t.PATH=Array.from(new Set(r.flatMap(o=>o.split(":")).filter(Boolean))).join(":"),Ge(t,e)}function Ge(n,e){return n.AGENTX_AGENT_ID=e.agentId,e.runningTaskId&&(n.AGENTX_TASK_ID=e.runningTaskId),e.context?.channel&&(n.AGENTX_CHANNEL=e.context.channel),e.context?.chatId&&(n.AGENTX_CHAT_ID=e.context.chatId),n}function vt(n={}){return{channel:n.channel||"api",chatId:n.chatId||n.group||n.sender||"default"}}function Ea(n,e){let t=Tt(n,e),s={};if(t.OPENCODE_CONFIG_CONTENT)try{s=JSON.parse(t.OPENCODE_CONFIG_CONTENT)}catch{}let r={...s.mcp||{}};for(let[i,a]of Object.entries(n.mcp||{}))r[i]=a.type==="http"?{type:"remote",url:a.url,headers:a.headers}:{type:"local",command:[a.command,...a.args||[]],environment:a.env};let o=process.argv[1]||"dist/cli.js";return r.agentx={type:"local",command:[process.execPath,o,"serve","--stdio","--cwd",process.cwd()]},t.OPENCODE_CONFIG_CONTENT=JSON.stringify({...s,mcp:r}),t}function Da(n){if(!n||typeof n!="object")return;if(typeof n.delta=="string")return n.delta;if(typeof n.text_delta=="string")return n.text_delta;if(typeof n.message=="string"&&/message|delta/i.test(String(n.type||"")))return n.message;if(typeof n.text=="string"&&/message|delta|response/i.test(String(n.type||"")))return n.text;let e=n.item||n.msg||n.message;if(e?.type==="agent_message"&&typeof e.text=="string"||typeof e?.text=="string"&&/message|delta|response|item/i.test(String(n.type||"")))return e.text;let t=e?.content;if(Array.isArray(t)){let s=t.map(r=>typeof r?.text=="string"?r.text:"").join("");if(s)return s}}function ge(...n){for(let e of n)if(typeof e=="number"&&Number.isFinite(e))return e;return 0}function cn(n,e=0){if(!n||typeof n!="object"||e>4)return;let t=n.usage||n.token_usage||n.tokenUsage||n.metrics?.usage;if(t&&typeof t=="object")return{inputTokens:ge(t.input_tokens,t.inputTokens,t.prompt_tokens,t.promptTokens),outputTokens:ge(t.output_tokens,t.outputTokens,t.completion_tokens,t.completionTokens),cacheReadTokens:ge(t.cache_read_input_tokens,t.cached_input_tokens,t.cacheReadTokens,t.cachedInputTokens),cacheCreateTokens:ge(t.cache_creation_input_tokens,t.cacheCreateTokens)};for(let s of[n.msg,n.message,n.response,n.result,n.item]){let r=cn(s,e+1);if(r)return r}}function Kr(n){if(!(!n||typeof n!="object"))return typeof n.model=="string"&&n.model||typeof n.msg?.model=="string"&&n.msg.model||typeof n.message?.model=="string"&&n.message.model||typeof n.response?.model=="string"&&n.response.model||void 0}function un(n,e=0){if(!(!n||typeof n!="object"||e>4)){for(let t of["thread_id","threadId","session_id","sessionId","conversation_id","conversationId"]){let s=n[t];if(typeof s=="string"&&s.trim())return s.trim()}for(let t of[n.msg,n.message,n.response,n.result,n.item]){let s=un(t,e+1);if(s)return s}}}function Oa(n){let e=typeof n=="string"?n:n?.toString("utf8")||"",t,s,r,o;for(let i of e.split(`
17
+ `))if(i.trim())try{let a=JSON.parse(i);t=cn(a)||t,s=Kr(a)||s,r=un(a)||r,o=Jr(a)||o}catch{}return{usage:t,billedModel:s,sessionId:r,apiError:o}}function Jr(n){if(!(!n||typeof n!="object")){if(n.type==="error"&&typeof n.message=="string")return Lr(n.message);if(n.type==="turn.failed"){let e=n.error?.message??n.error;if(typeof e=="string")return Lr(e)}}}function Lr(n){let e=n.trim();if(e.startsWith("{"))try{let t=JSON.parse(e),s=t?.error?.message??t?.message;if(typeof s=="string"&&s.trim())return s.trim()}catch{}return e}function Na(n){let e=n.permissionMode||"default",t=e==="bypassPermissions",s=t?"bypassPermissions (--dangerously-skip-permissions)":`${e} (no skip-permissions flag)`;return{configured:e,skipPermissions:t,summary:s}}function ln(n,e,t,s,r){let o=Na(e),i=t||e.model||"<default>",a=s?` resume=${s.slice(0,8)}\u2026`:"";process.stderr.write(`[claude-spawn] agent=${n} via=${r} model=${i} perm=${o.summary}${a}
18
+ `)}function La(n){try{let e=JSON.parse(n);if(e&&e.is_error&&typeof e.result=="string")return e.result;if(e&&e.error&&typeof e.error=="string")return e.error}catch{}return null}function Fa(n){try{let e=JSON.parse(n),t=e.usage?{inputTokens:e.usage.input_tokens||0,outputTokens:e.usage.output_tokens||0,cacheReadTokens:e.usage.cache_read_input_tokens||0,cacheCreateTokens:e.usage.cache_creation_input_tokens||0}:void 0,s=typeof e.model=="string"&&e.model||typeof e.message?.model=="string"&&e.message.model||ht(e.modelUsage)||void 0;return{text:e.result||e.content||"",sessionId:e.session_id,usage:t,billedModel:s,numTurns:typeof e.num_turns=="number"?e.num_turns:void 0,costUsd:typeof e.total_cost_usd=="number"?e.total_cost_usd:void 0}}catch{return{text:n}}}async function Qr(n,e,t,s,r){let o=Date.now(),i=pe(n,e,t),a=Xr(e);if("error"in a)return{content:"",error:a.error,duration:Date.now()-o};let c=qr(n,i,!1,s,e.model,e.systemPromptAppend,[...e.claudeArgs??[],...a.args]);if(ln(e.agentId,n,e.model,s,"spawn"),r?.aborted)return{content:"",error:"task cancelled by operator",duration:Date.now()-o};let d;try{let u=Math.max(6e4,(n.maxExecutionMinutes??20)*6e4),{stdout:l,stderr:f,exitCode:h,killed:p}=await new Promise(b=>{let R=ye(Ge(ve(n.workspace),e),n.billing),E=!1,O=Ma("claude",c,{cwd:n.workspace,timeout:u,maxBuffer:10*1024*1024,env:{...R,HOME:R.HOME||"/home/"+(R.USER||"user")}},(P,D,L)=>{b({stdout:D||"",stderr:L||"",exitCode:P?P.code??1:0,killed:E})});if(O.stdin?.end(),r){let P=()=>{E=!0,d=r.reason?.message||(typeof r.reason=="string"?r.reason:"task cancelled by operator");try{O.kill("SIGTERM")}catch{}setTimeout(()=>{try{O.killed||O.kill("SIGKILL")}catch{}},3e3).unref?.()};r.aborted?P():r.addEventListener("abort",P,{once:!0})}});if(p)return{content:"",error:d||"task cancelled by operator",errorKind:"cancelled",duration:Date.now()-o};if(!l&&h!==0){let b,R=Date.now()-o;return h===143&&R<u-Pa?{content:"",error:`Claude Code was stopped (SIGTERM) after ${Math.round(R/1e3)}s, before its ${Math.round(u/6e4)}m time limit`,errorKind:"interrupted",duration:R}:(h===143?b=`Claude Code timed out after ${Math.round(u/6e4)}m (SIGTERM). Bump agent.maxExecutionMinutes for "${n.name||"this agent"}" if tasks need longer.`:h==="ENOENT"||/ENOENT|spawn claude/i.test(f||"")?b=jr():b=f?.trim()||`Claude Code exited with code ${h}`,{content:"",...X(b),duration:Date.now()-o})}let I=La(l);if(I)return{content:"",...X(I),duration:Date.now()-o};let A=Fa(l);return{content:A.text,duration:Date.now()-o,claudeSessionId:A.sessionId,usage:A.usage,numTurns:A.numTurns,costUsd:A.costUsd,billedModel:A.billedModel}}catch(u){return console.error(`[runtime] execFile threw: ${u.message}`),{content:"",error:u.message||"Claude Code failed",duration:Date.now()-o}}}async function zr(n,e,t,s,r,o,i){let a=Date.now();if(i?.aborted)return{content:"",error:"task cancelled by operator",duration:Date.now()-a};let c=pe(n,e,s),d=Xr(e);if("error"in d)return{content:"",error:d.error,duration:Date.now()-a};let u=qr(n,c,!0,r,e.model,e.systemPromptAppend,[...e.claudeArgs??[],...d.args]);ln(e.agentId,n,e.model,r,"stream");let l="",f,h,p,I,A,b,R;try{let E=Math.max(6e4,(n.maxExecutionMinutes??20)*6e4),O=ye(Ge(ve(n.workspace),e),n.billing),P=It("claude",u,{cwd:n.workspace,timeout:E,reject:!1,env:O,extendEnv:!1,buffer:!1,stdin:"ignore"}),D=()=>{},L=new Promise(T=>{D=T}),F=!1,j;if(i){let T=()=>{F=!0,j=i.reason?.message||(typeof i.reason=="string"?i.reason:"task cancelled by operator");try{P.kill("SIGTERM")}catch{}setTimeout(()=>{try{P.kill("SIGKILL")}catch{}},3e3).unref?.()};i.aborted?T():i.addEventListener("abort",T,{once:!0})}let H="",W=new We("utf8");P.stdout&&P.stdout.on("data",T=>{H+=W.write(T);let w=H.split(`
19
+ `);H=w.pop()||"";for(let _ of w)if(_.trim())try{let S=JSON.parse(_);if(o)try{o(S)}catch{}if(S.type==="assistant"&&S.message?.usage){let v=S.message.usage,K=(v.input_tokens||0)+(v.cache_read_input_tokens||0)+(v.cache_creation_input_tokens||0);K>0&&(I=K)}if(S.type==="assistant"&&S.message?.content){for(let v of S.message.content)if(v.type==="text"&&v.text){let K=v.text.slice(l.length);K&&(l=v.text,t(K,l))}}if(S.type==="content_block_delta"&&S.delta?.text&&(l+=S.delta.text,t(S.delta.text,l)),S.type==="result"&&D(),S.type==="result"&&S.result){if(S.is_error&&typeof S.result=="string")R=S.result;else{let v=(typeof S.result=="string",S.result);if(typeof v=="string"&&v.length>l.length){let K=v.slice(l.length);l=v,K&&t(K,l)}}S.usage&&(h={inputTokens:S.usage.input_tokens||0,outputTokens:S.usage.output_tokens||0,cacheReadTokens:S.usage.cache_read_input_tokens||0,cacheCreateTokens:S.usage.cache_creation_input_tokens||0}),typeof S.model=="string"?f=S.model:f=ht(S.modelUsage)||f,typeof S.session_id=="string"&&(p=S.session_id),typeof S.num_turns=="number"&&(A=S.num_turns),typeof S.total_cost_usd=="number"&&(b=S.total_cost_usd)}S.type==="system"&&S.subtype==="init"&&(typeof S.model=="string"&&(f=S.model),process.env.AGENTX_DEBUG_CLAUDE_ENV==="1"&&process.stderr.write(`[claude-init] agent=${e.agentId} apiKeySource=${S.apiKeySource} version=${S.claude_code_version} model=${S.model} permMode=${S.permissionMode}
20
20
  `))}catch{_.trim()&&!_.startsWith("{")&&(l+=_+`
21
21
  `,t(_+`
22
- `,l))}});let G=await Wa(P,L),$=W.end();if($&&(H+=$),F)return{content:"",error:j||"task cancelled by operator",errorKind:"cancelled",duration:Date.now()-a};if(!l&&G.stdout&&(l=typeof G.stdout=="string"?G.stdout:""),G.exitCode!==0&&!l){let T=typeof G.stderr=="string"?G.stderr:"",w=G,_;return w.timedOut?_=`Claude Code timed out after ${Math.round(E/6e4)}m. Bump agent.maxExecutionMinutes for "${n.name||"this agent"}" if tasks need longer.`:w.signal?_=T.trim()||`Claude Code killed by signal ${w.signal}`:w.code==="ENOENT"||/ENOENT|spawn claude/i.test((w.shortMessage||"")+" "+T)?_=Br():_=T.trim()||`Claude Code exited with code ${w.exitCode??"unknown"}`,{content:"",...X(_),duration:Date.now()-a}}return R?{content:"",...X(R),duration:Date.now()-a,usage:h,contextTokens:I,numTurns:A,billedModel:f,claudeSessionId:p}:{content:l,duration:Date.now()-a,usage:h,contextTokens:I,numTurns:A,costUsd:b,billedModel:f,claudeSessionId:p}}catch(E){return{content:l||"",...X(E.message),duration:Date.now()-a,usage:h,contextTokens:I,numTurns:A,billedModel:f,claudeSessionId:p}}}async function Fa(n,e,t,s){let r=Date.now(),o=pe(n,e,t),i=Lr(bt(Hr(),"agentx-codex-")),a=bt(i,"last-message.txt"),c=Wr(n,o,!1,e.model,e.systemPromptAppend,a,s);try{let d=Math.max(6e4,(n.maxExecutionMinutes??20)*6e4),u=await St("codex",c,{cwd:n.workspace,timeout:d,reject:!1,env:It(n,e),extendEnv:!1,stdin:"ignore"}),l=Da(u.stdout);if(u.exitCode!==0||l.apiError){let h=u,p;return h.timedOut?p=`Codex CLI timed out after ${Math.round(d/6e4)}m. Bump agent.maxExecutionMinutes for "${n.name||"this agent"}" if tasks need longer.`:l.apiError?p=l.apiError:h.signal?p=u.stderr.trim()||`Codex CLI killed by signal ${h.signal}`:h.code==="ENOENT"||/ENOENT|spawn codex/i.test((h.shortMessage||"")+" "+u.stderr)?p=xt():p=u.stderr.trim()||u.stdout.trim()||`Codex CLI exited with code ${h.exitCode??"unknown"}`,{content:"",...X(p),duration:Date.now()-r,usage:l.usage,billedModel:l.billedModel,codexSessionId:l.sessionId||s}}let f="";try{f=Fr(a,"utf8").trim()}catch{}return f||(f=u.stdout.trim()),{content:f,duration:Date.now()-r,usage:l.usage,billedModel:l.billedModel,codexSessionId:l.sessionId||s}}catch(d){let u=/ENOENT|spawn codex/i.test(d?.message||"")?xt():d?.message;return{content:"",...X(u||"Codex CLI failed"),duration:Date.now()-r}}finally{Ur(i,{recursive:!0,force:!0})}}async function Ua(n,e,t,s,r,o){let i=Date.now(),a=pe(n,e,s),c=Lr(bt(Hr(),"agentx-codex-")),d=bt(c,"last-message.txt"),u=Wr(n,a,!0,e.model,e.systemPromptAppend,d,r),l="",f,h,p,I;try{let A=Math.max(6e4,(n.maxExecutionMinutes??20)*6e4),b=St("codex",u,{cwd:n.workspace,timeout:A,reject:!1,env:It(n,e),extendEnv:!1,buffer:!1,stdin:"ignore"});if(o)try{o({type:"codex.spawned",model:e.model||n.model,resumeSessionId:r})}catch{}let R="",E="",O=!1,P=new We("utf8"),D=new We("utf8"),L=Math.min(A,Math.max(3e4,Number(process.env.AGENTX_CODEX_IDLE_TIMEOUT_MS||18e4))),F,j=()=>{F&&clearTimeout(F),F=setTimeout(()=>{O=!0,b.kill("SIGTERM",{forceKillAfterTimeout:5e3})},L)};j(),b.stderr?.on("data",T=>{j(),E+=D.write(T),E.length>16e3&&(E=E.slice(-16e3))}),b.stdout?.on("data",T=>{j(),R+=P.write(T);let w=R.split(`
23
- `);R=w.pop()||"";for(let _ of w)if(_.trim())try{let x=JSON.parse(_);if(o)try{o(x)}catch{}f=dn(x)||f,h=Gr(x)||h,p=cn(x)||p,I=Kr(x)||I;let k=Ea(x);if(k&&k!==l){let K=k.startsWith(l)?k.slice(l.length):k;l=k.startsWith(l)?k:l+k,K&&t(K,l)}}catch{l+=_+`
22
+ `,l))}});let G=await Ga(P,L),$=W.end();if($&&(H+=$),F)return{content:"",error:j||"task cancelled by operator",errorKind:"cancelled",duration:Date.now()-a};if(!l&&G.stdout&&(l=typeof G.stdout=="string"?G.stdout:""),G.exitCode!==0&&!l){let T=typeof G.stderr=="string"?G.stderr:"",w=G,_;return w.timedOut?_=`Claude Code timed out after ${Math.round(E/6e4)}m. Bump agent.maxExecutionMinutes for "${n.name||"this agent"}" if tasks need longer.`:w.signal?_=T.trim()||`Claude Code killed by signal ${w.signal}`:w.code==="ENOENT"||/ENOENT|spawn claude/i.test((w.shortMessage||"")+" "+T)?_=jr():_=T.trim()||`Claude Code exited with code ${w.exitCode??"unknown"}`,{content:"",...X(_),duration:Date.now()-a}}return R?{content:"",...X(R),duration:Date.now()-a,usage:h,contextTokens:I,numTurns:A,billedModel:f,claudeSessionId:p}:{content:l,duration:Date.now()-a,usage:h,contextTokens:I,numTurns:A,costUsd:b,billedModel:f,claudeSessionId:p}}catch(E){return{content:l||"",...X(E.message),duration:Date.now()-a,usage:h,contextTokens:I,numTurns:A,billedModel:f,claudeSessionId:p}}}async function Ua(n,e,t,s){let r=Date.now(),o=pe(n,e,t),i=Fr(xt(Br(),"agentx-codex-")),a=xt(i,"last-message.txt"),c=Gr(n,o,!1,e.model,e.systemPromptAppend,a,s);try{let d=Math.max(6e4,(n.maxExecutionMinutes??20)*6e4),u=await It("codex",c,{cwd:n.workspace,timeout:d,reject:!1,env:Tt(n,e),extendEnv:!1,stdin:"ignore"}),l=Oa(u.stdout);if(u.exitCode!==0||l.apiError){let h=u,p;return h.timedOut?p=`Codex CLI timed out after ${Math.round(d/6e4)}m. Bump agent.maxExecutionMinutes for "${n.name||"this agent"}" if tasks need longer.`:l.apiError?p=l.apiError:h.signal?p=u.stderr.trim()||`Codex CLI killed by signal ${h.signal}`:h.code==="ENOENT"||/ENOENT|spawn codex/i.test((h.shortMessage||"")+" "+u.stderr)?p=St():p=u.stderr.trim()||u.stdout.trim()||`Codex CLI exited with code ${h.exitCode??"unknown"}`,{content:"",...X(p),duration:Date.now()-r,usage:l.usage,billedModel:l.billedModel,codexSessionId:l.sessionId||s}}let f="";try{f=Ur(a,"utf8").trim()}catch{}return f||(f=u.stdout.trim()),{content:f,duration:Date.now()-r,usage:l.usage,billedModel:l.billedModel,codexSessionId:l.sessionId||s}}catch(d){let u=/ENOENT|spawn codex/i.test(d?.message||"")?St():d?.message;return{content:"",...X(u||"Codex CLI failed"),duration:Date.now()-r}}finally{Hr(i,{recursive:!0,force:!0})}}async function Ha(n,e,t,s,r,o){let i=Date.now(),a=pe(n,e,s),c=Fr(xt(Br(),"agentx-codex-")),d=xt(c,"last-message.txt"),u=Gr(n,a,!0,e.model,e.systemPromptAppend,d,r),l="",f,h,p,I;try{let A=Math.max(6e4,(n.maxExecutionMinutes??20)*6e4),b=It("codex",u,{cwd:n.workspace,timeout:A,reject:!1,env:Tt(n,e),extendEnv:!1,buffer:!1,stdin:"ignore"});if(o)try{o({type:"codex.spawned",model:e.model||n.model,resumeSessionId:r})}catch{}let R="",E="",O=!1,P=new We("utf8"),D=new We("utf8"),L=Math.min(A,Math.max(3e4,Number(process.env.AGENTX_CODEX_IDLE_TIMEOUT_MS||18e4))),F,j=()=>{F&&clearTimeout(F),F=setTimeout(()=>{O=!0,b.kill("SIGTERM",{forceKillAfterTimeout:5e3})},L)};j(),b.stderr?.on("data",T=>{j(),E+=D.write(T),E.length>16e3&&(E=E.slice(-16e3))}),b.stdout?.on("data",T=>{j(),R+=P.write(T);let w=R.split(`
23
+ `);R=w.pop()||"";for(let _ of w)if(_.trim())try{let S=JSON.parse(_);if(o)try{o(S)}catch{}f=cn(S)||f,h=Kr(S)||h,p=un(S)||p,I=Jr(S)||I;let v=Da(S);if(v&&v!==l){let K=v.startsWith(l)?v.slice(l.length):v;l=v.startsWith(l)?v:l+v,K&&t(K,l)}}catch{l+=_+`
24
24
  `,t(_+`
25
- `,l)}});let H=await b;F&&clearTimeout(F);let W=P.end();W&&(R+=W);let G=D.end();if(G&&(E+=G),H.exitCode!==0&&!l||I){let T=E||(typeof H.stderr=="string"?H.stderr:""),w=H,_;return O?_=`Codex CLI produced no output for ${Math.round(L/1e3)}s and was stopped. AgentX sent a smaller prompt; retry the task or set AGENTX_CODEX_IDLE_TIMEOUT_MS if this turn needs longer.`:w.timedOut?_=`Codex CLI timed out after ${Math.round(A/6e4)}m. Bump agent.maxExecutionMinutes for "${n.name||"this agent"}" if tasks need longer.`:I?_=I:w.signal?_=T.trim()||`Codex CLI killed by signal ${w.signal}`:w.code==="ENOENT"||/ENOENT|spawn codex/i.test((w.shortMessage||"")+" "+T)?_=xt():_=T.trim()||`Codex CLI exited with code ${w.exitCode??"unknown"}`,{content:"",...X(_),duration:Date.now()-i,usage:f,billedModel:h,codexSessionId:p||r}}let $="";try{$=Fr(d,"utf8").trim()}catch{}if($&&$!==l){let T=$.startsWith(l)?$.slice(l.length):$;l=$,T&&t(T,l)}return{content:l,duration:Date.now()-i,usage:f,billedModel:h,codexSessionId:p||r}}catch(A){let b=/ENOENT|spawn codex/i.test(A?.message||"")?xt():A?.message;return{content:l,...X(b||"Codex CLI failed"),duration:Date.now()-i,usage:f,billedModel:h,codexSessionId:p||r}}finally{Ur(c,{recursive:!0,force:!0})}}async function Ha(n,e,t,s,r,o,i,a){let c=Date.now();if(i?.aborted)return{content:"",error:"task cancelled by operator",errorKind:"cancelled",duration:0};let d=pe(n,e,s),u=Pa(n,d,e.model,e.systemPromptAppend,e.freshSession?void 0:r),l="",f,h=e.freshSession?void 0:r,p,I,A=!0,b;try{let R=Math.max(6e4,(n.maxExecutionMinutes??20)*6e4),E=Ra(n,e);if(n.persistentProcess)try{I=await Ts.acquire({key:JSON.stringify([e.agentId,e.context?.channel,e.context?.chatId]),cwd:n.workspace,env:E,model:e.model||n.model,permission:n.permissionMode,fresh:e.freshSession,signal:i}),u.splice(1,0,"--server",I.url),E=I.env,o?.({type:"opencode.ready",reused:I.reused,startupMs:Date.now()-c})}catch(T){if(!(T instanceof Is))throw T;T.standalone&&u.splice(1,0,"--standalone"),o?.({type:"opencode.fallback",reason:T.message})}if(i?.aborted)throw new Error("task cancelled by operator");let O=St("opencode",u,{cwd:n.workspace,timeout:R,reject:!1,env:E,extendEnv:!1,buffer:!1,stdin:"ignore"});try{o?.({type:"opencode.spawned",model:e.model||n.model,resumeSessionId:r})}catch{}let P=!1,D,L=()=>{I?.invalidate(),P=!0,D=i?.reason?.message||(typeof i?.reason=="string"?i.reason:"task cancelled by operator");try{O.kill("SIGTERM",{forceKillAfterTimeout:3e3})}catch{}};i&&i.addEventListener("abort",L,{once:!0}),b=()=>i?.removeEventListener("abort",L),i?.aborted&&L();let F="",j="",H=new We("utf8"),W=new We("utf8"),G=T=>{if(T.trim())try{let w=JSON.parse(T);try{o?.(w)}catch{}typeof w.sessionID=="string"&&(h=w.sessionID);let _=w.type==="text"&&typeof w.part?.text=="string"?w.part.text:void 0;_&&(l||o?.({type:"opencode.first_output",elapsedMs:Date.now()-c,reused:I?.reused??!1}),l+=_,t?.(_,l));let x=w.type==="reasoning"&&typeof w.part?.text=="string"?w.part.text:void 0;x&&a?.(x);let k=w.type==="step_finish"?w.part?.tokens:void 0;k&&(f={inputTokens:ge(k.input),outputTokens:ge(k.output),cacheReadTokens:ge(k.cache?.read),cacheCreateTokens:ge(k.cache?.write)}),p=_a(w)||p}catch{l+=T+`
25
+ `,l)}});let H=await b;F&&clearTimeout(F);let W=P.end();W&&(R+=W);let G=D.end();if(G&&(E+=G),H.exitCode!==0&&!l||I){let T=E||(typeof H.stderr=="string"?H.stderr:""),w=H,_;return O?_=`Codex CLI produced no output for ${Math.round(L/1e3)}s and was stopped. AgentX sent a smaller prompt; retry the task or set AGENTX_CODEX_IDLE_TIMEOUT_MS if this turn needs longer.`:w.timedOut?_=`Codex CLI timed out after ${Math.round(A/6e4)}m. Bump agent.maxExecutionMinutes for "${n.name||"this agent"}" if tasks need longer.`:I?_=I:w.signal?_=T.trim()||`Codex CLI killed by signal ${w.signal}`:w.code==="ENOENT"||/ENOENT|spawn codex/i.test((w.shortMessage||"")+" "+T)?_=St():_=T.trim()||`Codex CLI exited with code ${w.exitCode??"unknown"}`,{content:"",...X(_),duration:Date.now()-i,usage:f,billedModel:h,codexSessionId:p||r}}let $="";try{$=Ur(d,"utf8").trim()}catch{}if($&&$!==l){let T=$.startsWith(l)?$.slice(l.length):$;l=$,T&&t(T,l)}return{content:l,duration:Date.now()-i,usage:f,billedModel:h,codexSessionId:p||r}}catch(A){let b=/ENOENT|spawn codex/i.test(A?.message||"")?St():A?.message;return{content:l,...X(b||"Codex CLI failed"),duration:Date.now()-i,usage:f,billedModel:h,codexSessionId:p||r}}finally{Hr(c,{recursive:!0,force:!0})}}async function Ba(n,e,t,s,r,o,i,a){let c=Date.now();if(i?.aborted)return{content:"",error:"task cancelled by operator",errorKind:"cancelled",duration:0};let d=pe(n,e,s),u=_a(n,d,e.model,e.systemPromptAppend,e.freshSession?void 0:r),l="",f,h=e.freshSession?void 0:r,p,I,A=!0,b;try{let R=Math.max(6e4,(n.maxExecutionMinutes??20)*6e4),E=Ea(n,e);if(n.persistentProcess)try{I=await vs.acquire({key:JSON.stringify([e.agentId,e.context?.channel,e.context?.chatId]),cwd:n.workspace,env:E,model:e.model||n.model,permission:n.permissionMode,fresh:e.freshSession,signal:i}),u.splice(1,0,"--server",I.url),E=I.env,o?.({type:"opencode.ready",reused:I.reused,startupMs:Date.now()-c})}catch(T){if(!(T instanceof Ts))throw T;T.standalone&&u.splice(1,0,"--standalone"),o?.({type:"opencode.fallback",reason:T.message})}if(i?.aborted)throw new Error("task cancelled by operator");let O=It("opencode",u,{cwd:n.workspace,timeout:R,reject:!1,env:E,extendEnv:!1,buffer:!1,stdin:"ignore"});try{o?.({type:"opencode.spawned",model:e.model||n.model,resumeSessionId:r})}catch{}let P=!1,D,L=()=>{I?.invalidate(),P=!0,D=i?.reason?.message||(typeof i?.reason=="string"?i.reason:"task cancelled by operator");try{O.kill("SIGTERM",{forceKillAfterTimeout:3e3})}catch{}};i&&i.addEventListener("abort",L,{once:!0}),b=()=>i?.removeEventListener("abort",L),i?.aborted&&L();let F="",j="",H=new We("utf8"),W=new We("utf8"),G=T=>{if(T.trim())try{let w=JSON.parse(T);try{o?.(w)}catch{}typeof w.sessionID=="string"&&(h=w.sessionID);let _=w.type==="text"&&typeof w.part?.text=="string"?w.part.text:void 0;_&&(l||o?.({type:"opencode.first_output",elapsedMs:Date.now()-c,reused:I?.reused??!1}),l+=_,t?.(_,l));let S=w.type==="reasoning"&&typeof w.part?.text=="string"?w.part.text:void 0;S&&a?.(S);let v=w.type==="step_finish"?w.part?.tokens:void 0;v&&(f={inputTokens:ge(v.input),outputTokens:ge(v.output),cacheReadTokens:ge(v.cache?.read),cacheCreateTokens:ge(v.cache?.write)}),p=Ra(w)||p}catch{l+=T+`
26
26
  `,t?.(T+`
27
27
  `,l)}};O.stdout?.on("data",T=>{F+=H.write(T);let w=F.split(`
28
- `);F=w.pop()||"";for(let _ of w)G(_)}),O.stderr?.on("data",T=>{j+=W.write(T)});let $=await O;if(i&&i.removeEventListener("abort",L),F+=H.end(),F.trim()&&G(F),j+=W.end(),P)return{content:"",error:D||"task cancelled by operator",errorKind:"cancelled",duration:Date.now()-c,opencodeSessionId:h};if($.exitCode!==0||p){let T=$,w;return T.timedOut?w=`OpenCode timed out after ${Math.round(R/6e4)}m. Bump agent.maxExecutionMinutes for "${n.name||"this agent"}" if tasks need longer.`:p?w=p:T.code==="ENOENT"||/ENOENT|spawn opencode/i.test((T.shortMessage||"")+" "+j)?w=Dr():w=j.trim()||`OpenCode exited with code ${T.exitCode??"unknown"}`,{content:"",...X(w),duration:Date.now()-c,usage:f,opencodeSessionId:h}}return A=!1,{content:l.trim(),duration:Date.now()-c,usage:f,billedModel:e.model||n.model,opencodeSessionId:h}}catch(R){if(i?.aborted)return{content:"",error:"task cancelled by operator",errorKind:"cancelled",duration:Date.now()-c};let E=/ENOENT|spawn opencode/i.test(R?.message||"")?Dr():R?.message;return{content:l,...X(E||"OpenCode failed"),duration:Date.now()-c,usage:f,opencodeSessionId:h}}finally{b?.(),I?.release(A)}}async function Ba(n,e,t,s){let r=Date.now();try{let o=await import("@anthropic-ai/claude-agent-sdk"),{query:i}=o,a=pe(n,e,s),c="",d=i({prompt:a,options:{model:e.model||n.model,cwd:n.workspace,permissionMode:"bypassPermissions"}});for await(let u of d)u.type==="result"&&u.subtype==="success"&&(c=u.result||"");return{content:c,duration:Date.now()-r}}catch(o){return{content:"",...X(`SDK error: ${o.message}`),duration:Date.now()-r}}}async function ja(n,e,t,s,r,o,i,a,c){let d=Date.now(),u=Math.max(6e4,(n.maxExecutionMinutes??20)*6e4),l=new AbortController,f=!1,h=()=>{let A=a.reason?.message||(typeof a.reason=="string"?a.reason:"task cancelled by operator");try{l.abort(new Error(A))}catch{}};a&&(a.aborted?h():a.addEventListener("abort",h,{once:!0}));let p=setTimeout(()=>{f=!0;try{l.abort(new Error(`orchestrator timed out after ${Math.round(u/6e4)}m`))}catch{}},u);p.unref?.();let I=()=>({content:"",...X(`Orchestrator timed out after ${Math.round(u/6e4)}m. Bump agent.maxExecutionMinutes for "${n.name||"this agent"}" if tasks need longer.`),duration:Date.now()-d});try{let A=n.provider||"claude-code",b=s?`${s}
28
+ `);F=w.pop()||"";for(let _ of w)G(_)}),O.stderr?.on("data",T=>{j+=W.write(T)});let $=await O;if(i&&i.removeEventListener("abort",L),F+=H.end(),F.trim()&&G(F),j+=W.end(),P)return{content:"",error:D||"task cancelled by operator",errorKind:"cancelled",duration:Date.now()-c,opencodeSessionId:h};if($.exitCode!==0||p){let T=$,w;return T.timedOut?w=`OpenCode timed out after ${Math.round(R/6e4)}m. Bump agent.maxExecutionMinutes for "${n.name||"this agent"}" if tasks need longer.`:p?w=p:T.code==="ENOENT"||/ENOENT|spawn opencode/i.test((T.shortMessage||"")+" "+j)?w=Or():w=j.trim()||`OpenCode exited with code ${T.exitCode??"unknown"}`,{content:"",...X(w),duration:Date.now()-c,usage:f,opencodeSessionId:h}}return A=!1,{content:l.trim(),duration:Date.now()-c,usage:f,billedModel:e.model||n.model,opencodeSessionId:h}}catch(R){if(i?.aborted)return{content:"",error:"task cancelled by operator",errorKind:"cancelled",duration:Date.now()-c};let E=/ENOENT|spawn opencode/i.test(R?.message||"")?Or():R?.message;return{content:l,...X(E||"OpenCode failed"),duration:Date.now()-c,usage:f,opencodeSessionId:h}}finally{b?.(),I?.release(A)}}async function ja(n,e,t,s){let r=Date.now();try{let o=await import("@anthropic-ai/claude-agent-sdk"),{query:i}=o,a=pe(n,e,s),c="",d=i({prompt:a,options:{model:e.model||n.model,cwd:n.workspace,permissionMode:"bypassPermissions"}});for await(let u of d)u.type==="result"&&u.subtype==="success"&&(c=u.result||"");return{content:c,duration:Date.now()-r}}catch(o){return{content:"",...X(`SDK error: ${o.message}`),duration:Date.now()-r}}}async function qa(n,e,t,s,r,o,i,a,c){let d=Date.now(),u=Math.max(6e4,(n.maxExecutionMinutes??20)*6e4),l=new AbortController,f=!1,h=()=>{let A=a.reason?.message||(typeof a.reason=="string"?a.reason:"task cancelled by operator");try{l.abort(new Error(A))}catch{}};a&&(a.aborted?h():a.addEventListener("abort",h,{once:!0}));let p=setTimeout(()=>{f=!0;try{l.abort(new Error(`orchestrator timed out after ${Math.round(u/6e4)}m`))}catch{}},u);p.unref?.();let I=()=>({content:"",...X(`Orchestrator timed out after ${Math.round(u/6e4)}m. Bump agent.maxExecutionMinutes for "${n.name||"this agent"}" if tasks need longer.`),duration:Date.now()-d});try{let A=n.provider||"claude-code",b=s?`${s}
29
29
 
30
- ${e.message}`:e.message,R=e.context?.sender,E=typeof R=="string"&&/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(R),O=e.context?.channel==="web-chat"&&E?{userId:R,agentId:e.agentId||"acme-public"}:void 0,P=$s(n),D=Object.keys(P).length>0,L={task:b,cwd:n.workspace,provider:A,model:e.model||n.model,apiKey:t,overwrite:!0,interactive:!1,context7:!1,acmeContext:O,providerOpts:o,abortSignal:l.signal,mcpServers:D?P:void 0};if(r){let{generateStream:G}=await import("./agent-TQQOAVMU.js"),$="",T,w,_,x;for await(let k of G(L)){if(c)try{c(k)}catch{}if(k.type==="text_delta")$+=k.text,r(k.text,$);else if(k.type==="thinking_delta")k.text&&i&&i(k.text);else if(k.type==="generate_result"){if(k.result.content&&k.result.content!==$){let K=k.result.content.slice($.length);K?($=k.result.content,r(K,$)):$=k.result.content}T=k.result.tokensUsed,k.result.inputTokens!=null&&(w=k.result.inputTokens),k.result.outputTokens!=null&&(_=k.result.outputTokens)}else if(k.type==="done"){if(k.result.content&&k.result.content!==$){let K=k.result.content.slice($.length);K?($=k.result.content,r(K,$)):$=k.result.content}k.result.tokensUsed!=null&&(T=k.result.tokensUsed)}else k.type==="error"&&(x=k.error)}return x&&!$?f?I():x==="cancelled"||a?.aborted||l.signal.aborted?{content:"",error:"task cancelled by operator",errorKind:"cancelled",duration:Date.now()-d}:{content:"",...X(`Orchestrator error: ${x}`),duration:Date.now()-d}:((w===void 0||_===void 0)&&T&&(w=Math.round(T*.7),_=T-w),{content:$||"Done.",tokensUsed:T,usage:w!==void 0||_!==void 0?{inputTokens:w||0,outputTokens:_||0,cacheReadTokens:0,cacheCreateTokens:0}:void 0,duration:Date.now()-d})}let{generate:F}=await import("./agent-TQQOAVMU.js"),j=await F(L),H=j.inputTokens,W=j.outputTokens;if((H===void 0||W===void 0)&&j.tokensUsed){let G=j.tokensUsed;H=Math.round(G*.7),W=G-H}return{content:j.content||"Done.",tokensUsed:j.tokensUsed,usage:H!==void 0||W!==void 0?{inputTokens:H||0,outputTokens:W||0,cacheReadTokens:0,cacheCreateTokens:0}:void 0,duration:Date.now()-d}}catch(A){return f?I():A?.message==="cancelled"||a?.aborted||l.signal.aborted?{content:"",error:"task cancelled by operator",errorKind:"cancelled",duration:Date.now()-d}:{content:"",...X(`Orchestrator error: ${A.message}`),duration:Date.now()-d}}finally{clearTimeout(p),a&&a.removeEventListener("abort",h)}}var qa=1e3;async function Wa(n,e){let t=Promise.resolve(n).then(i=>({kind:"exit",r:i})),s,r=e.then(()=>new Promise(i=>{s=setTimeout(()=>i({kind:"grace"}),qa),s.unref?.()})),o=await Promise.race([t,r]);return s&&clearTimeout(s),o.kind==="exit"?o.r:(t.catch(()=>{}),{exitCode:0,stdout:"",stderr:"",detachedAfterResult:!0})}async function Ga(n,e,t,s,r,o,i){let a=ht();if(!a)return null;let c=Date.now(),{channel:d,chatId:u}=Tt(e.context),l={agentId:e.agentId,channel:d,chatId:u};if(e.freshSession)try{await a.kill(l,"freshSession=true")}catch{}let f,h=!1;try{let $=a.list().length;f=a.acquire(l,{agentId:e.agentId,channel:d,chatId:u,workspace:n.workspace,model:e.model||n.model,permissionMode:n.permissionMode,billing:n.billing,systemPromptAppend:e.systemPromptAppend,resumeSessionId:s,extraArgs:e.claudeArgs}),h=a.list().length>$}catch($){return $ instanceof ke,null}h&&un(e.agentId,n,e.model,s,"persistent");let p=pe(n,e,t),I="",A,b,R,E,O,P,D,L="",F="",j=$=>{if(!i||!$)return;let T;if(F&&$.startsWith(F)?T=$.slice(F.length):T=L&&!L.endsWith(`
30
+ ${e.message}`:e.message,R=e.context?.sender,E=typeof R=="string"&&/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(R),O=e.context?.channel==="web-chat"&&E?{userId:R,agentId:e.agentId||"acme-public"}:void 0,P=Cs(n),D=Object.keys(P).length>0,L={task:b,cwd:n.workspace,provider:A,model:e.model||n.model,apiKey:t,overwrite:!0,interactive:!1,context7:!1,acmeContext:O,providerOpts:o,abortSignal:l.signal,mcpServers:D?P:void 0};if(r){let{generateStream:G}=await import("./agent-PCRE3TRK.js"),$="",T,w,_,S;for await(let v of G(L)){if(c)try{c(v)}catch{}if(v.type==="text_delta")$+=v.text,r(v.text,$);else if(v.type==="thinking_delta")v.text&&i&&i(v.text);else if(v.type==="generate_result"){if(v.result.content&&v.result.content!==$){let K=v.result.content.slice($.length);K?($=v.result.content,r(K,$)):$=v.result.content}T=v.result.tokensUsed,v.result.inputTokens!=null&&(w=v.result.inputTokens),v.result.outputTokens!=null&&(_=v.result.outputTokens)}else if(v.type==="done"){if(v.result.content&&v.result.content!==$){let K=v.result.content.slice($.length);K?($=v.result.content,r(K,$)):$=v.result.content}v.result.tokensUsed!=null&&(T=v.result.tokensUsed)}else v.type==="error"&&(S=v.error)}return S&&!$?f?I():S==="cancelled"||a?.aborted||l.signal.aborted?{content:"",error:"task cancelled by operator",errorKind:"cancelled",duration:Date.now()-d}:{content:"",...X(`Orchestrator error: ${S}`),duration:Date.now()-d}:((w===void 0||_===void 0)&&T&&(w=Math.round(T*.7),_=T-w),{content:$||"Done.",tokensUsed:T,usage:w!==void 0||_!==void 0?{inputTokens:w||0,outputTokens:_||0,cacheReadTokens:0,cacheCreateTokens:0}:void 0,duration:Date.now()-d})}let{generate:F}=await import("./agent-PCRE3TRK.js"),j=await F(L),H=j.inputTokens,W=j.outputTokens;if((H===void 0||W===void 0)&&j.tokensUsed){let G=j.tokensUsed;H=Math.round(G*.7),W=G-H}return{content:j.content||"Done.",tokensUsed:j.tokensUsed,usage:H!==void 0||W!==void 0?{inputTokens:H||0,outputTokens:W||0,cacheReadTokens:0,cacheCreateTokens:0}:void 0,duration:Date.now()-d}}catch(A){return f?I():A?.message==="cancelled"||a?.aborted||l.signal.aborted?{content:"",error:"task cancelled by operator",errorKind:"cancelled",duration:Date.now()-d}:{content:"",...X(`Orchestrator error: ${A.message}`),duration:Date.now()-d}}finally{clearTimeout(p),a&&a.removeEventListener("abort",h)}}var Wa=1e3;async function Ga(n,e){let t=Promise.resolve(n).then(i=>({kind:"exit",r:i})),s,r=e.then(()=>new Promise(i=>{s=setTimeout(()=>i({kind:"grace"}),Wa),s.unref?.()})),o=await Promise.race([t,r]);return s&&clearTimeout(s),o.kind==="exit"?o.r:(t.catch(()=>{}),{exitCode:0,stdout:"",stderr:"",detachedAfterResult:!0})}async function Ka(n,e,t,s,r,o,i){let a=yt();if(!a)return null;let c=Date.now(),{channel:d,chatId:u}=vt(e.context),l={agentId:e.agentId,channel:d,chatId:u};if(e.freshSession)try{await a.kill(l,"freshSession=true")}catch{}let f,h=!1;try{let $=a.list().length;f=a.acquire(l,{agentId:e.agentId,channel:d,chatId:u,workspace:n.workspace,model:e.model||n.model,permissionMode:n.permissionMode,billing:n.billing,systemPromptAppend:e.systemPromptAppend,resumeSessionId:s,extraArgs:e.claudeArgs}),h=a.list().length>$}catch($){return $ instanceof ke,null}h&&ln(e.agentId,n,e.model,s,"persistent");let p=pe(n,e,t),I="",A,b,R,E,O,P,D,L="",F="",j=$=>{if(!i||!$)return;let T;if(F&&$.startsWith(F)?T=$.slice(F.length):T=L&&!L.endsWith(`
31
31
  `)?`
32
32
 
33
- ${$}`:$,F=$,!!T){L+=T;try{i(T,L)}catch{}}},H=!1,W=()=>{H=!0,a.kill(l,"operator-cancel").catch(()=>{})};o&&(o.aborted?W():o.addEventListener("abort",W,{once:!0}));let G=!1;try{let $=Math.max(6e4,(n.maxExecutionMinutes??20)*6e4);for await(let T of f.runTurn({message:p,taskId:e.taskId??"unknown",deadlineMs:$})){if(G=!0,r)try{r(T.raw)}catch{}if(T.type==="assistant"){let w=T.raw.message?.content??[];for(let x of w)x.type==="text"&&typeof x.text=="string"?(I=x.text,j(x.text)):x.type==="tool_use"&&(F="");let _=T.raw.message?.usage;if(_){let x=(_.input_tokens||0)+(_.cache_read_input_tokens||0)+(_.cache_creation_input_tokens||0);x>0&&(E=x)}}if(T.type==="result"){let w=T.raw;if(w.is_error){let _=X(typeof w.result=="string"?w.result:"claude error");A=_.error,b=_.errorKind}else typeof w.result=="string"&&w.result.length>0&&(I=w.result,L||j(w.result));typeof w.session_id=="string"&&(D=w.session_id),w.usage&&(R={inputTokens:w.usage.input_tokens||0,outputTokens:w.usage.output_tokens||0,cacheReadTokens:w.usage.cache_read_input_tokens||0,cacheCreateTokens:w.usage.cache_creation_input_tokens||0}),typeof w.num_turns=="number"&&(O=w.num_turns),typeof w.message?.model=="string"?P=w.message.model:typeof w.model=="string"?P=w.model:P=mt(w.modelUsage)||P}}}catch($){if(H)A="task cancelled by operator",b="cancelled";else if(G)if($ instanceof je)A=`Claude Code was stopped mid-turn (${$.reason}), before its time limit`,b="interrupted";else if($ instanceof Be){let T=X(`Claude Code timed out after ${Math.round($.budgetMs/6e4)}m. Bump agent.maxExecutionMinutes for "${n.name||e.agentId}" if tasks need longer.`);A=T.error,b=T.errorKind}else{let T=X(`persistent claude process error: ${$?.message||String($)}`);A=T.error,b=T.errorKind}else return console.error(`[runtime] persistent handle unusable before first event (${$?.message||$}); falling back to spawn-per-task`),a.release(l,{kill:!0,reason:"pre-turn failure"}),o&&o.removeEventListener("abort",W),null}finally{o&&o.removeEventListener("abort",W)}return H&&!A&&(A="task cancelled by operator",b="cancelled"),{content:H?"":I,error:A,errorKind:b,duration:Date.now()-c,usage:R,contextTokens:E,numTurns:O,billedModel:P,claudeSessionId:D}}function zr(n){let e=ie(n.autonomy);if(!e&&!n.personLimits)return{args:[]};if(!n.taskId)return{error:"a guarded task requires a task id to enforce"};let t=e?$r(n.autonomy,n.agentId,n.taskId):{args:[]};return"error"in t||!n.personLimits?t:Rr(t.args,n.taskId,n.agentId)}function Ka(n){return ie(n.autonomy)||!!n.personLimits}async function Ja(n,e,t,s,r,o,i){let a=ie(e.autonomy)?e.autonomy:void 0,c=a&&Cr(a,n.tier)||e.personLimits&&Er(n.tier);if(c)return{content:"",error:c,...a?{autonomy:a}:{}};let d=e.taskId||`guarded-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`,u={...e,taskId:d,message:a?`${us(a)}
33
+ ${$}`:$,F=$,!!T){L+=T;try{i(T,L)}catch{}}},H=!1,W=()=>{H=!0,a.kill(l,"operator-cancel").catch(()=>{})};o&&(o.aborted?W():o.addEventListener("abort",W,{once:!0}));let G=!1;try{let $=Math.max(6e4,(n.maxExecutionMinutes??20)*6e4);for await(let T of f.runTurn({message:p,taskId:e.taskId??"unknown",deadlineMs:$})){if(G=!0,r)try{r(T.raw)}catch{}if(T.type==="assistant"){let w=T.raw.message?.content??[];for(let S of w)S.type==="text"&&typeof S.text=="string"?(I=S.text,j(S.text)):S.type==="tool_use"&&(F="");let _=T.raw.message?.usage;if(_){let S=(_.input_tokens||0)+(_.cache_read_input_tokens||0)+(_.cache_creation_input_tokens||0);S>0&&(E=S)}}if(T.type==="result"){let w=T.raw;if(w.is_error){let _=X(typeof w.result=="string"?w.result:"claude error");A=_.error,b=_.errorKind}else typeof w.result=="string"&&w.result.length>0&&(I=w.result,L||j(w.result));typeof w.session_id=="string"&&(D=w.session_id),w.usage&&(R={inputTokens:w.usage.input_tokens||0,outputTokens:w.usage.output_tokens||0,cacheReadTokens:w.usage.cache_read_input_tokens||0,cacheCreateTokens:w.usage.cache_creation_input_tokens||0}),typeof w.num_turns=="number"&&(O=w.num_turns),typeof w.message?.model=="string"?P=w.message.model:typeof w.model=="string"?P=w.model:P=ht(w.modelUsage)||P}}}catch($){if(H)A="task cancelled by operator",b="cancelled";else if(G)if($ instanceof je)A=`Claude Code was stopped mid-turn (${$.reason}), before its time limit`,b="interrupted";else if($ instanceof Be){let T=X(`Claude Code timed out after ${Math.round($.budgetMs/6e4)}m. Bump agent.maxExecutionMinutes for "${n.name||e.agentId}" if tasks need longer.`);A=T.error,b=T.errorKind}else{let T=X(`persistent claude process error: ${$?.message||String($)}`);A=T.error,b=T.errorKind}else return console.error(`[runtime] persistent handle unusable before first event (${$?.message||$}); falling back to spawn-per-task`),a.release(l,{kill:!0,reason:"pre-turn failure"}),o&&o.removeEventListener("abort",W),null}finally{o&&o.removeEventListener("abort",W)}return H&&!A&&(A="task cancelled by operator",b="cancelled"),{content:H?"":I,error:A,errorKind:b,duration:Date.now()-c,usage:R,contextTokens:E,numTurns:O,billedModel:P,claudeSessionId:D}}function Xr(n){let e=ie(n.autonomy);if(!e&&!n.personLimits)return{args:[]};if(!n.taskId)return{error:"a guarded task requires a task id to enforce"};let t=e?Cr(n.autonomy,n.agentId,n.taskId):{args:[]};return"error"in t||!n.personLimits?t:Er(t.args,n.taskId,n.agentId)}function Ja(n){return ie(n.autonomy)||!!n.personLimits}async function Qa(n,e,t,s,r,o,i){let a=ie(e.autonomy)?e.autonomy:void 0,c=a&&Mr(a,n.tier)||e.personLimits&&Dr(n.tier);if(c)return{content:"",error:c,...a?{autonomy:a}:{}};let d=e.taskId||`guarded-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`,u={...e,taskId:d,message:a?`${ls(a)}
34
34
 
35
35
  ${e.message}`:e.message},l=[a?`level=${a}`:"",e.personLimits?`person=${e.personLimits.personId}`:""].filter(Boolean).join(" ");process.stderr.write(`[claude-guarded] agent=${e.agentId} ${l} task=${d} via=spawn (persistent process bypassed)
36
- `),e.personLimits&&Pr(d,e.personLimits);try{let f=t?await Qr(n,u,t,s,r,o,i):await Jr(n,u,s,r,i);if(!a)return f;let h=Mr(d);return{...f,autonomy:a,...h.length?{autonomyBlocks:h}:{}}}finally{e.personLimits&&_r(d)}}async function Xr(n,e,t,s,r,o,i,a,c){if(Ka(e))return Ja(n,e,s,r,o,i,a);switch(n.tier){case"claude-code":if(n.persistentProcess){let d=await Ga(n,e,r,o,i,a,s);if(d!==null)return d}return s?Qr(n,e,s,r,o,i,a):Jr(n,e,r,o,a);case"codex-cli":if(n.persistentProcess)try{let d=await br.run({key:JSON.stringify([e.agentId,e.context?.channel,e.context?.chatId]),cwd:n.workspace,env:It(n,e),args:qr(),model:e.model||n.model,bypass:n.permissionMode==="bypassPermissions",prompt:an(pe(n,e,r),e.systemPromptAppend),resume:o,fresh:e.freshSession,timeoutMs:Math.max(6e4,(n.maxExecutionMinutes??20)*6e4),signal:a,onEvent:i,onDelta:s});return{...d,...d.error?X(d.error):{}}}catch(d){if(!(d instanceof le))throw d;if(i?.({type:"codex.fallback",reason:d.message}),a?.aborted)return{content:"",error:"task cancelled by operator",errorKind:"cancelled"}}return s?Ua(n,e,s,r,o,i):Fa(n,e,r,o);case"opencode":return Ha(n,e,s,r,o,i,a,c);case"sdk":{let d=n.provider||"claude",u=t[d]?.apiKey;return u?Ba(n,e,u,r):{content:"",error:`No API key for provider "${d}". Configure providers.${d}.apiKey`}}case"orchestrator":{let d=n.provider||"claude-code",u=t[d],l=u?.apiKey;return ja(n,e,l,r,s,{thinking:u?.thinking},c,a,i)}default:return{content:"",error:`Unknown tier: ${n.tier}`}}}import{readFileSync as $e,writeFileSync as Yr,mkdirSync as Qa,existsSync as ln,readdirSync as gn}from"fs";import{resolve as Ce}from"path";var pn=12e3,Ke=30,za=720,Xa=40,Ya=18e4,Va="[Compacted conversation summary",Za=7*864e5,ed=[/\bearlier\b/i,/\bbefore\b/i,/\bjust said\b/i,/\btold (?:me|you|us|him|her|them)\b/i,/\bmention(?:ed|ing)?\b/i,/\bask(?:ed)? (?:me|you|him|her|them|about)\b/i,/\bping(?:ed)?\b/i,/\bdm\b/i,/\bdirect message\b/i,/\bother (?:chat|group|conversation|thread)\b/i,/\bthat (?:chat|group|conversation|thread)\b/i,/\bsame (?:issue|thread|conversation)\b/i,/\bcontinuing\b/i,/@\w{2,}_?(?:bot|agent)\b/i,/قلت/,/قال(?:لك|لي|له|لها|لنا)?/,/قبل/,/الحين/,/الثاني/,/المجموعة/];function td(n){return n?ed.some(e=>e.test(n)):!1}var nd=[{re:/\byesterday\b/i,days:2},{re:/\bأمس\b/,days:2},{re:/\bcouple (?:of )?days\b/i,days:4},{re:/\bfew days\b/i,days:4},{re:/\blast week\b/i,days:8},{re:/\bالأسبوع الماضي\b/,days:8},{re:/\bweek ago\b/i,days:8},{re:/\bremember\b/i,days:3},{re:/\bpreviously\b/i,days:3},{re:/\bwe (?:discussed|talked|agreed|decided)\b/i,days:3},{re:/\bas (?:i|we) (?:said|told|mentioned)\b/i,days:3},{re:/\bcontinue from\b/i,days:3},{re:/\bتذكر\b/,days:3}];function Zr(n){if(!n)return null;let e=0;for(let t of nd)t.re.test(n)&&(e=Math.max(e,t.days));return e>0?{lookbackDays:e}:null}function Vr(n,e,t,s){if(n.length===0)return!1;let r=n[n.length-1];return r.role===e&&(r.name??"")===t&&r.content===s}function eo(n,e){let t=(n??[]).filter(o=>o.role==="user"),s=t[t.length-1];return s?(s.content===e?t[t.length-2]:s)?.content??null:null}function to(n,e,t){if(t<=0)return[];let s=(n??[]).filter(i=>i.role==="user"),r=s[s.length-1],o=(r&&r.content===e?s.length-1:s.length)-1;return o<=0?[]:s.slice(Math.max(0,o-t),o).map(i=>i.content)}function sd(n){let e=n.slice(11,16),t=e.slice(0,2),s=parseInt(e.slice(3,5),10);if(Number.isNaN(s))return e;let r=Math.floor(s/15)*15;return`${t}:${r.toString().padStart(2,"0")}`}var vt=class{sessionsDir;cache=new Map;staleMinutes;maxTurnsPerSession;tierTwoThresholdTokens;tierTwoThresholdTokensByChannel;adapterResolver;seedingPromises=new Map;constructor(e=process.cwd(),t={}){this.sessionsDir=Ce(e,".agentx/sessions"),ln(this.sessionsDir)||Qa(this.sessionsDir,{recursive:!0}),this.staleMinutes=Math.max(1,t.staleMinutes??za),this.maxTurnsPerSession=Math.max(2,t.maxTurnsPerSession??Xa),this.tierTwoThresholdTokens=Math.max(5e4,t.tierTwoThresholdTokens??Ya),this.tierTwoThresholdTokensByChannel=Object.fromEntries(Object.entries(t.tierTwoThresholdTokensByChannel??{}).map(([s,r])=>[s,Math.max(5e4,r)]))}setAdapterResolver(e){this.adapterResolver=e}async seedIfEmpty(e,t,s,r){if(r?.length){let u=this.getSession(e,t,s);u.messages.length===0&&this.appendSeededMessages(u,r);return}if(!this.adapterResolver)return;let o=this.sessionKey(e,t,s),i=this.seedingPromises.get(o);if(i)return i;let a=this.getSession(e,t,s);if(a.messages.length>0)return;let c=this.adapterResolver(t);if(!c?.seedHistory)return;let d=(async()=>{try{let u=await c.seedHistory(s,{maxMessages:Ke,maxChars:pn});u.length>0&&this.appendSeededMessages(a,u)}catch{}})();this.seedingPromises.set(o,d);try{await d}finally{this.seedingPromises.delete(o)}}appendSeededMessages(e,t){if(t.length===0)return;let s=new Set;for(let o of e.messages)o.externalId&&s.add(o.externalId);let r=0;for(let o of t)o.externalId&&s.has(o.externalId)||(e.messages.push({role:o.role,name:o.name,content:o.content,timestamp:o.timestamp,seeded:!0,externalId:o.externalId}),r++);r!==0&&(this.trim(e),e.updatedAt=new Date().toISOString(),this.save(e))}sessionKey(e,t,s){let r=new Date().toISOString().slice(0,10);return`${e}:${t}:${s}:${r}`}sessionFile(e){let t=e.replace(/[^a-zA-Z0-9_:-]/g,"_");return Ce(this.sessionsDir,`${t}.json`)}getSession(e,t,s){let r=this.sessionKey(e,t,s);if(this.cache.has(r))return this.cache.get(r);let o=this.sessionFile(r);if(ln(o))try{let d=JSON.parse($e(o,"utf-8"));return this.cache.set(r,d),d}catch{}let i=this.loadPreviousDaySession(e,t,s),a=new Date().toISOString().slice(0,10),c={id:r,agentId:e,channel:t,chatId:s,day:a,messages:[],createdAt:new Date().toISOString(),updatedAt:i?.updatedAt??new Date().toISOString(),claudeSessionId:i?.claudeSessionId,codexSessionId:i?.codexSessionId,turnCount:i?.turnCount,lastTurnInputTokens:i?.lastTurnInputTokens,lastTurnContextTokens:i?.lastTurnContextTokens};return this.cache.set(r,c),this.save(c),c}loadPreviousDaySession(e,t,s){let r=new Date(Date.now()-864e5).toISOString().slice(0,10),o=`${e}:${t}:${s}:${r}`,i=this.sessionFile(o);if(!ln(i))return null;try{return JSON.parse($e(i,"utf-8"))}catch{return null}}addUserMessage(e,t,s,r,o){let i=this.getSession(e,t,s);Vr(i.messages,"user",r,o)||(i.messages.push({role:"user",name:r,content:o,timestamp:new Date().toISOString()}),this.trim(i),i.updatedAt=new Date().toISOString(),this.save(i))}removeLastUserMessageIfMatches(e,t,s,r){let o=this.getSession(e,t,s),i=o.messages[o.messages.length-1];return!i||i.role!=="user"||(i.content||"").trim()!==(r||"").trim()?!1:(o.messages.pop(),o.updatedAt=new Date().toISOString(),this.save(o),!0)}addAgentMessage(e,t,s,r){let o=this.getSession(e,t,s);Vr(o.messages,"agent",e,r)||(o.messages.push({role:"agent",name:e,content:r,timestamp:new Date().toISOString()}),this.trim(o),o.updatedAt=new Date().toISOString(),this.save(o))}getClaudeSessionId(e,t,s){return this.getSession(e,t,s).claudeSessionId}setClaudeSessionId(e,t,s,r){let o=this.getSession(e,t,s);o.claudeSessionId=r,o.updatedAt=new Date().toISOString(),this.save(o)}getCodexSessionId(e,t,s){return this.getSession(e,t,s).codexSessionId}setCodexSessionId(e,t,s,r){let o=this.getSession(e,t,s);o.codexSessionId=r,o.updatedAt=new Date().toISOString(),this.save(o)}getOpenCodeSessionId(e,t,s){return this.getSession(e,t,s).opencodeSessionId}setOpenCodeSessionId(e,t,s,r){let o=this.getSession(e,t,s);o.opencodeSessionId=r,o.updatedAt=new Date().toISOString(),this.save(o)}buildHistoryContext(e,t,s,r={}){let o=this.getSession(e,t,s);if(o.messages.length===0)return"";let i=Math.max(1,r.maxMessages??Ke),a=Math.max(200,r.maxChars??pn),c=[],d=0;for(let f=o.messages.length-1;f>=0&&c.length<i;f--){let h=o.messages[f];if(d+=h.content.length,c.push(h),d>=a)break}c.reverse();let u=[`[Conversation history for today (${o.day})]`],l="";for(let f of c){let h=sd(f.timestamp);h!==l&&(u.push(`\u2014 ${h} \u2014`),l=h);let p=f.name||(f.role==="user"?"User":"Agent");u.push(`${p}: ${f.content}`)}return u.push("[End of history \u2014 respond to the latest message above]"),u.push(""),u.join(`
37
- `)}recallTurns(e){let t=Math.min(Math.max(e.limit??10,1),100),s=new Date;s.setUTCHours(0,0,0,0);let r=typeof e.lookbackDays=="number"&&e.lookbackDays>0?new Date(Date.now()-e.lookbackDays*24*60*60*1e3).toISOString():s.toISOString(),o=e.after??r,i=e.before??new Date(Date.now()+1e3).toISOString(),a=e.agentId.replace(/[^a-zA-Z0-9_:-]/g,"_"),c;try{c=gn(this.sessionsDir).filter(O=>O.startsWith(`${a}:`)&&O.endsWith(".json"))}catch{return{turns:[],oldestTs:null,hasMore:!1,totalScanned:0}}let d=o.slice(0,10),u=i.slice(0,10),l=/:(\d{4}-\d{2}-\d{2})\.json$/,f=c.filter(O=>{let P=O.match(l);if(!P)return!1;let D=P[1];return D>=d&&D<=u}),h=[],p=0,I=e.query?.toLowerCase(),A=e.participants?.length?new Set(e.participants):void 0;for(let O of f){let P;try{P=JSON.parse($e(Ce(this.sessionsDir,O),"utf-8"))}catch{continue}if(P.agentId===e.agentId&&!(e.channel&&P.channel!==e.channel)&&!(e.chatId&&P.chatId!==e.chatId))for(let D of P.messages)p++,!(!D.timestamp||D.timestamp<o||D.timestamp>=i)&&(A&&D.role==="user"&&!A.has(D.name??"")||I&&!D.content.toLowerCase().includes(I)||h.push({ts:D.timestamp,role:D.role,senderName:D.name??"",content:D.content,channel:P.channel,chatId:P.chatId,day:P.day,sessionFile:O}))}h.sort((O,P)=>P.ts.localeCompare(O.ts));let b=h.slice(0,t),R=b.length>0?b[b.length-1].ts:null,E=h.length>t;return{turns:b,oldestTs:R,hasMore:E,totalScanned:p}}recentByChatId(e){let t=Math.min(Math.max(e.limit??Ke,1),200),s=e.sinceISO??new Date(Date.now()-24*60*60*1e3).toISOString(),r=s.slice(0,10),o;try{o=gn(this.sessionsDir).filter(l=>l.endsWith(".json"))}catch{return[]}let i=`:${e.channel}:${e.chatId}:`,a=o.filter(l=>{if(!l.includes(i))return!1;let f=l.match(/:(\d{4}-\d{2}-\d{2})\.json$/);return f?f[1]>=r:!1}),c=[];for(let l of a){let f;try{f=JSON.parse($e(Ce(this.sessionsDir,l),"utf-8"))}catch{continue}if(!(f.channel!==e.channel||f.chatId!==e.chatId))for(let h of f.messages)!h.timestamp||h.timestamp<s||c.push({ts:h.timestamp,role:h.role,senderName:h.name??"",content:h.content,agentId:f.agentId,sessionFile:l})}let d=new Set,u=[];for(let l of c){let f=`${l.ts}|${l.role}|${l.senderName}|${l.content}`;d.has(f)||(d.add(f),u.push(l))}return u.sort((l,f)=>l.ts.localeCompare(f.ts)),u.slice(-t)}sessionIdleMs(e,t,s){let r=this.getSession(e,t,s);return!r.claudeSessionId&&!r.codexSessionId&&!r.opencodeSessionId?null:Date.now()-new Date(r.updatedAt).getTime()}isSessionStale(e,t,s){let r=this.getSession(e,t,s);return!r.claudeSessionId&&!r.codexSessionId&&!r.opencodeSessionId?!1:Date.now()-new Date(r.updatedAt).getTime()>this.staleMinutes*60*1e3}getCrossSessionSummary(e,t,s,r){if(r!==void 0&&r!==""&&!td(r))return"";let o=new Date().toISOString().slice(0,10),i=this.sessionKey(e,t,s);try{let a=gn(this.sessionsDir).filter(d=>d.startsWith(e.replace(/[^a-zA-Z0-9_:-]/g,"_"))&&d.includes(o)&&d.endsWith(".json")),c=[];for(let d of a)try{let u=JSON.parse($e(Ce(this.sessionsDir,d),"utf-8"));if(u.id===i||u.messages.length===0)continue;let l=u.messages.slice(-4),h=!u.chatId.startsWith("-")&&/^\d+$/.test(u.chatId)?"DM":u.chatId,p=l.map(I=>` [${I.timestamp.slice(11,16)}] ${I.name||I.role}: ${I.content.slice(0,200)}`);c.push(`From ${h} (${u.channel}):
36
+ `),e.personLimits&&_r(d,e.personLimits);try{let f=t?await zr(n,u,t,s,r,o,i):await Qr(n,u,s,r,i);if(!a)return f;let h=Pr(d);return{...f,autonomy:a,...h.length?{autonomyBlocks:h}:{}}}finally{e.personLimits&&Rr(d)}}async function Yr(n,e,t,s,r,o,i,a,c){if(Ja(e))return Qa(n,e,s,r,o,i,a);switch(n.tier){case"claude-code":if(n.persistentProcess){let d=await Ka(n,e,r,o,i,a,s);if(d!==null)return d}return s?zr(n,e,s,r,o,i,a):Qr(n,e,r,o,a);case"codex-cli":if(n.persistentProcess)try{let d=await xr.run({key:JSON.stringify([e.agentId,e.context?.channel,e.context?.chatId]),cwd:n.workspace,env:Tt(n,e),args:Wr(),model:e.model||n.model,bypass:n.permissionMode==="bypassPermissions",prompt:dn(pe(n,e,r),e.systemPromptAppend),resume:o,fresh:e.freshSession,timeoutMs:Math.max(6e4,(n.maxExecutionMinutes??20)*6e4),signal:a,onEvent:i,onDelta:s});return{...d,...d.error?X(d.error):{}}}catch(d){if(!(d instanceof le))throw d;if(i?.({type:"codex.fallback",reason:d.message}),a?.aborted)return{content:"",error:"task cancelled by operator",errorKind:"cancelled"}}return s?Ha(n,e,s,r,o,i):Ua(n,e,r,o);case"opencode":return Ba(n,e,s,r,o,i,a,c);case"sdk":{let d=n.provider||"claude",u=t[d]?.apiKey;return u?ja(n,e,u,r):{content:"",error:`No API key for provider "${d}". Configure providers.${d}.apiKey`}}case"orchestrator":{let d=n.provider||"claude-code",u=t[d],l=u?.apiKey;return qa(n,e,l,r,s,{thinking:u?.thinking},c,a,i)}default:return{content:"",error:`Unknown tier: ${n.tier}`}}}import{readFileSync as $e,writeFileSync as Vr,mkdirSync as za,existsSync as gn,readdirSync as pn}from"fs";import{resolve as Ce}from"path";var fn=12e3,Ke=30,Xa=720,Ya=40,Va=18e4,Za="[Compacted conversation summary",ed=7*864e5,td=[/\bearlier\b/i,/\bbefore\b/i,/\bjust said\b/i,/\btold (?:me|you|us|him|her|them)\b/i,/\bmention(?:ed|ing)?\b/i,/\bask(?:ed)? (?:me|you|him|her|them|about)\b/i,/\bping(?:ed)?\b/i,/\bdm\b/i,/\bdirect message\b/i,/\bother (?:chat|group|conversation|thread)\b/i,/\bthat (?:chat|group|conversation|thread)\b/i,/\bsame (?:issue|thread|conversation)\b/i,/\bcontinuing\b/i,/@\w{2,}_?(?:bot|agent)\b/i,/قلت/,/قال(?:لك|لي|له|لها|لنا)?/,/قبل/,/الحين/,/الثاني/,/المجموعة/];function nd(n){return n?td.some(e=>e.test(n)):!1}var sd=[{re:/\byesterday\b/i,days:2},{re:/\bأمس\b/,days:2},{re:/\bcouple (?:of )?days\b/i,days:4},{re:/\bfew days\b/i,days:4},{re:/\blast week\b/i,days:8},{re:/\bالأسبوع الماضي\b/,days:8},{re:/\bweek ago\b/i,days:8},{re:/\bremember\b/i,days:3},{re:/\bpreviously\b/i,days:3},{re:/\bwe (?:discussed|talked|agreed|decided)\b/i,days:3},{re:/\bas (?:i|we) (?:said|told|mentioned)\b/i,days:3},{re:/\bcontinue from\b/i,days:3},{re:/\bتذكر\b/,days:3}];function eo(n){if(!n)return null;let e=0;for(let t of sd)t.re.test(n)&&(e=Math.max(e,t.days));return e>0?{lookbackDays:e}:null}function Zr(n,e,t,s){if(n.length===0)return!1;let r=n[n.length-1];return r.role===e&&(r.name??"")===t&&r.content===s}function to(n,e){let t=(n??[]).filter(o=>o.role==="user"),s=t[t.length-1];return s?(s.content===e?t[t.length-2]:s)?.content??null:null}function no(n,e,t){if(t<=0)return[];let s=(n??[]).filter(i=>i.role==="user"),r=s[s.length-1],o=(r&&r.content===e?s.length-1:s.length)-1;return o<=0?[]:s.slice(Math.max(0,o-t),o).map(i=>i.content)}function rd(n){let e=n.slice(11,16),t=e.slice(0,2),s=parseInt(e.slice(3,5),10);if(Number.isNaN(s))return e;let r=Math.floor(s/15)*15;return`${t}:${r.toString().padStart(2,"0")}`}var kt=class{sessionsDir;cache=new Map;staleMinutes;maxTurnsPerSession;tierTwoThresholdTokens;tierTwoThresholdTokensByChannel;adapterResolver;seedingPromises=new Map;constructor(e=process.cwd(),t={}){this.sessionsDir=Ce(e,".agentx/sessions"),gn(this.sessionsDir)||za(this.sessionsDir,{recursive:!0}),this.staleMinutes=Math.max(1,t.staleMinutes??Xa),this.maxTurnsPerSession=Math.max(2,t.maxTurnsPerSession??Ya),this.tierTwoThresholdTokens=Math.max(5e4,t.tierTwoThresholdTokens??Va),this.tierTwoThresholdTokensByChannel=Object.fromEntries(Object.entries(t.tierTwoThresholdTokensByChannel??{}).map(([s,r])=>[s,Math.max(5e4,r)]))}setAdapterResolver(e){this.adapterResolver=e}async seedIfEmpty(e,t,s,r){if(r?.length){let u=this.getSession(e,t,s);u.messages.length===0&&this.appendSeededMessages(u,r);return}if(!this.adapterResolver)return;let o=this.sessionKey(e,t,s),i=this.seedingPromises.get(o);if(i)return i;let a=this.getSession(e,t,s);if(a.messages.length>0)return;let c=this.adapterResolver(t);if(!c?.seedHistory)return;let d=(async()=>{try{let u=await c.seedHistory(s,{maxMessages:Ke,maxChars:fn});u.length>0&&this.appendSeededMessages(a,u)}catch{}})();this.seedingPromises.set(o,d);try{await d}finally{this.seedingPromises.delete(o)}}appendSeededMessages(e,t){if(t.length===0)return;let s=new Set;for(let o of e.messages)o.externalId&&s.add(o.externalId);let r=0;for(let o of t)o.externalId&&s.has(o.externalId)||(e.messages.push({role:o.role,name:o.name,content:o.content,timestamp:o.timestamp,seeded:!0,externalId:o.externalId}),r++);r!==0&&(this.trim(e),e.updatedAt=new Date().toISOString(),this.save(e))}sessionKey(e,t,s){let r=new Date().toISOString().slice(0,10);return`${e}:${t}:${s}:${r}`}sessionFile(e){let t=e.replace(/[^a-zA-Z0-9_:-]/g,"_");return Ce(this.sessionsDir,`${t}.json`)}getSession(e,t,s){let r=this.sessionKey(e,t,s);if(this.cache.has(r))return this.cache.get(r);let o=this.sessionFile(r);if(gn(o))try{let d=JSON.parse($e(o,"utf-8"));return this.cache.set(r,d),d}catch{}let i=this.loadPreviousDaySession(e,t,s),a=new Date().toISOString().slice(0,10),c={id:r,agentId:e,channel:t,chatId:s,day:a,messages:[],createdAt:new Date().toISOString(),updatedAt:i?.updatedAt??new Date().toISOString(),claudeSessionId:i?.claudeSessionId,codexSessionId:i?.codexSessionId,turnCount:i?.turnCount,lastTurnInputTokens:i?.lastTurnInputTokens,lastTurnContextTokens:i?.lastTurnContextTokens};return this.cache.set(r,c),this.save(c),c}loadPreviousDaySession(e,t,s){let r=new Date(Date.now()-864e5).toISOString().slice(0,10),o=`${e}:${t}:${s}:${r}`,i=this.sessionFile(o);if(!gn(i))return null;try{return JSON.parse($e(i,"utf-8"))}catch{return null}}addUserMessage(e,t,s,r,o){let i=this.getSession(e,t,s);Zr(i.messages,"user",r,o)||(i.messages.push({role:"user",name:r,content:o,timestamp:new Date().toISOString()}),this.trim(i),i.updatedAt=new Date().toISOString(),this.save(i))}removeLastUserMessageIfMatches(e,t,s,r){let o=this.getSession(e,t,s),i=o.messages[o.messages.length-1];return!i||i.role!=="user"||(i.content||"").trim()!==(r||"").trim()?!1:(o.messages.pop(),o.updatedAt=new Date().toISOString(),this.save(o),!0)}addAgentMessage(e,t,s,r){let o=this.getSession(e,t,s);Zr(o.messages,"agent",e,r)||(o.messages.push({role:"agent",name:e,content:r,timestamp:new Date().toISOString()}),this.trim(o),o.updatedAt=new Date().toISOString(),this.save(o))}getClaudeSessionId(e,t,s){return this.getSession(e,t,s).claudeSessionId}setClaudeSessionId(e,t,s,r){let o=this.getSession(e,t,s);o.claudeSessionId=r,o.updatedAt=new Date().toISOString(),this.save(o)}getCodexSessionId(e,t,s){return this.getSession(e,t,s).codexSessionId}setCodexSessionId(e,t,s,r){let o=this.getSession(e,t,s);o.codexSessionId=r,o.updatedAt=new Date().toISOString(),this.save(o)}getOpenCodeSessionId(e,t,s){return this.getSession(e,t,s).opencodeSessionId}setOpenCodeSessionId(e,t,s,r){let o=this.getSession(e,t,s);o.opencodeSessionId=r,o.updatedAt=new Date().toISOString(),this.save(o)}buildHistoryContext(e,t,s,r={}){let o=this.getSession(e,t,s);if(o.messages.length===0)return"";let i=Math.max(1,r.maxMessages??Ke),a=Math.max(200,r.maxChars??fn),c=[],d=0;for(let f=o.messages.length-1;f>=0&&c.length<i;f--){let h=o.messages[f];if(d+=h.content.length,c.push(h),d>=a)break}c.reverse();let u=[`[Conversation history for today (${o.day})]`],l="";for(let f of c){let h=rd(f.timestamp);h!==l&&(u.push(`\u2014 ${h} \u2014`),l=h);let p=f.name||(f.role==="user"?"User":"Agent");u.push(`${p}: ${f.content}`)}return u.push("[End of history \u2014 respond to the latest message above]"),u.push(""),u.join(`
37
+ `)}recallTurns(e){let t=Math.min(Math.max(e.limit??10,1),100),s=new Date;s.setUTCHours(0,0,0,0);let r=typeof e.lookbackDays=="number"&&e.lookbackDays>0?new Date(Date.now()-e.lookbackDays*24*60*60*1e3).toISOString():s.toISOString(),o=e.after??r,i=e.before??new Date(Date.now()+1e3).toISOString(),a=e.agentId.replace(/[^a-zA-Z0-9_:-]/g,"_"),c;try{c=pn(this.sessionsDir).filter(O=>O.startsWith(`${a}:`)&&O.endsWith(".json"))}catch{return{turns:[],oldestTs:null,hasMore:!1,totalScanned:0}}let d=o.slice(0,10),u=i.slice(0,10),l=/:(\d{4}-\d{2}-\d{2})\.json$/,f=c.filter(O=>{let P=O.match(l);if(!P)return!1;let D=P[1];return D>=d&&D<=u}),h=[],p=0,I=e.query?.toLowerCase(),A=e.participants?.length?new Set(e.participants):void 0;for(let O of f){let P;try{P=JSON.parse($e(Ce(this.sessionsDir,O),"utf-8"))}catch{continue}if(P.agentId===e.agentId&&!(e.channel&&P.channel!==e.channel)&&!(e.chatId&&P.chatId!==e.chatId))for(let D of P.messages)p++,!(!D.timestamp||D.timestamp<o||D.timestamp>=i)&&(A&&D.role==="user"&&!A.has(D.name??"")||I&&!D.content.toLowerCase().includes(I)||h.push({ts:D.timestamp,role:D.role,senderName:D.name??"",content:D.content,channel:P.channel,chatId:P.chatId,day:P.day,sessionFile:O}))}h.sort((O,P)=>P.ts.localeCompare(O.ts));let b=h.slice(0,t),R=b.length>0?b[b.length-1].ts:null,E=h.length>t;return{turns:b,oldestTs:R,hasMore:E,totalScanned:p}}recentByChatId(e){let t=Math.min(Math.max(e.limit??Ke,1),200),s=e.sinceISO??new Date(Date.now()-24*60*60*1e3).toISOString(),r=s.slice(0,10),o;try{o=pn(this.sessionsDir).filter(l=>l.endsWith(".json"))}catch{return[]}let i=`:${e.channel}:${e.chatId}:`,a=o.filter(l=>{if(!l.includes(i))return!1;let f=l.match(/:(\d{4}-\d{2}-\d{2})\.json$/);return f?f[1]>=r:!1}),c=[];for(let l of a){let f;try{f=JSON.parse($e(Ce(this.sessionsDir,l),"utf-8"))}catch{continue}if(!(f.channel!==e.channel||f.chatId!==e.chatId))for(let h of f.messages)!h.timestamp||h.timestamp<s||c.push({ts:h.timestamp,role:h.role,senderName:h.name??"",content:h.content,agentId:f.agentId,sessionFile:l})}let d=new Set,u=[];for(let l of c){let f=`${l.ts}|${l.role}|${l.senderName}|${l.content}`;d.has(f)||(d.add(f),u.push(l))}return u.sort((l,f)=>l.ts.localeCompare(f.ts)),u.slice(-t)}sessionIdleMs(e,t,s){let r=this.getSession(e,t,s);return!r.claudeSessionId&&!r.codexSessionId&&!r.opencodeSessionId?null:Date.now()-new Date(r.updatedAt).getTime()}isSessionStale(e,t,s,r){let o=this.getSession(e,t,s);return!o.claudeSessionId&&!o.codexSessionId&&!o.opencodeSessionId?!1:(r??Date.now()-new Date(o.updatedAt).getTime())>this.staleMinutes*60*1e3}getCrossSessionSummary(e,t,s,r){if(r!==void 0&&r!==""&&!nd(r))return"";let o=new Date().toISOString().slice(0,10),i=this.sessionKey(e,t,s);try{let a=pn(this.sessionsDir).filter(d=>d.startsWith(e.replace(/[^a-zA-Z0-9_:-]/g,"_"))&&d.includes(o)&&d.endsWith(".json")),c=[];for(let d of a)try{let u=JSON.parse($e(Ce(this.sessionsDir,d),"utf-8"));if(u.id===i||u.messages.length===0)continue;let l=u.messages.slice(-4),h=!u.chatId.startsWith("-")&&/^\d+$/.test(u.chatId)?"DM":u.chatId,p=l.map(I=>` [${I.timestamp.slice(11,16)}] ${I.name||I.role}: ${I.content.slice(0,200)}`);c.push(`From ${h} (${u.channel}):
38
38
  ${p.join(`
39
39
  `)}`)}catch{}return c.length===0?"":["[Cross-chat context \u2014 recent activity from your other conversations today]",...c,"[End cross-chat context \u2014 the user in THIS chat may be referring to actions from above]",""].join(`
40
- `)}catch{return""}}async compactIfNeeded(e,t,s,r){let o=this.getSession(e,t,s),{needsCompaction:i,compactSession:a,applyCompaction:c}=await import("./compaction-FS6XNRLM.js");if(!i(o.messages))return{compacted:!1};let d=await a(o.messages,e,r,{channel:t,chatId:s});return d.compactedCount===0?{compacted:!1}:(o.messages=c(o.messages,d),o.updatedAt=new Date().toISOString(),this.save(o),{compacted:!0,qualityScore:d.qualityScore,lostEntities:d.lostEntities,drift:d.drift})}hasCompaction(e,t,s){let r=this.getSession(e,t,s);return r.messages.length>0&&r.messages[0].content.startsWith(Va)}clearClaudeSessionId(e,t,s){let r=this.getSession(e,t,s);delete r.claudeSessionId,delete r.codexSessionId,delete r.opencodeSessionId,delete r.turnCount,delete r.lastTurnInputTokens,delete r.lastTurnContextTokens,r.updatedAt=new Date().toISOString(),this.save(r)}clearSession(e,t,s){let r=this.getSession(e,t,s);r.messages=[],delete r.claudeSessionId,delete r.codexSessionId,delete r.opencodeSessionId,delete r.turnCount,delete r.lastTurnInputTokens,delete r.lastTurnContextTokens,r.updatedAt=new Date().toISOString(),this.save(r)}shouldRotateByTurns(e,t,s){let r=this.getSession(e,t,s);return!r.claudeSessionId&&!r.codexSessionId&&!r.opencodeSessionId?!1:(r.turnCount??0)>=this.maxTurnsPerSession}shouldRotateByTierTwo(e,t,s){let r=this.getSession(e,t,s);return!r.claudeSessionId&&!r.codexSessionId&&!r.opencodeSessionId?!1:(r.lastTurnContextTokens??r.lastTurnInputTokens??0)>=this.getTierTwoThresholdTokens(t)}recordTurnUsage(e,t,s,r,o){let i=this.getSession(e,t,s);i.turnCount=(i.turnCount??0)+1,i.lastTurnInputTokens=(r.inputTokens||0)+(r.cacheReadTokens||0)+(r.cacheCreateTokens||0),i.lastTurnContextTokens=o,i.updatedAt=new Date().toISOString(),this.save(i)}rotationMemoFile(){return Ce(this.sessionsDir,"_rotation-memos.json")}readRotationMemos(){try{let e=JSON.parse($e(this.rotationMemoFile(),"utf-8"));return e&&typeof e=="object"?e:{}}catch{return{}}}setRotationMemo(e,t,s,r,o){let i=this.readRotationMemos();i[`${e}:${t}:${s}`]={memo:r,reason:o,capturedAt:new Date().toISOString()},Yr(this.rotationMemoFile(),JSON.stringify(i,null,2))}getRotationMemo(e,t,s){let r=this.readRotationMemos()[`${e}:${t}:${s}`];if(!r?.memo)return null;let o=Date.now()-Date.parse(r.capturedAt);return!Number.isFinite(o)||o>Za?null:r}getTurnCount(e,t,s){return this.getSession(e,t,s).turnCount??0}getLastTurnInputTokens(e,t,s){return this.getSession(e,t,s).lastTurnInputTokens??0}getLastTurnContextTokens(e,t,s){let r=this.getSession(e,t,s);return r.lastTurnContextTokens??r.lastTurnInputTokens??0}getMaxTurnsPerSession(){return this.maxTurnsPerSession}getTierTwoThresholdTokens(e){return(e?this.tierTwoThresholdTokensByChannel[e]:void 0)??this.tierTwoThresholdTokens}trim(e){let t=e.messages.length;e.messages.length>Ke&&(e.messages=e.messages.slice(-Ke));let s=e.messages.reduce((o,i)=>o+i.content.length,0);for(;s>pn&&e.messages.length>2;){let o=e.messages.shift();s-=o.content.length}let r=t-e.messages.length;r>0&&he.cat("context",`[${e.agentId}] ${e.channel}:${e.chatId} trim dropped ${r} message(s): ${t} -> ${e.messages.length} (${s}c)`)}save(e){try{let t=this.sessionFile(e.id);Yr(t,JSON.stringify(e,null,2))}catch{}}};var kt=class{windows=new Map;maxPerMinute;maxPerHour;constructor(e=10,t=100){this.maxPerMinute=e,this.maxPerHour=t}check(e){let t=Date.now(),s=this.windows.get(e)||[],r=t-36e5,o=s.filter(c=>c>r),i=t-6e4,a=o.filter(c=>c>i);if(a.length>=this.maxPerMinute){let c=a[0],d=Math.max(50,c+6e4-t);return{allowed:!1,reason:`Rate limit: ${a.length}/${this.maxPerMinute} per minute`,waitMs:d}}if(o.length>=this.maxPerHour){let c=o[0],d=Math.max(1e3,c+36e5-t);return{allowed:!1,reason:`Rate limit: ${o.length}/${this.maxPerHour} per hour`,waitMs:d}}return o.push(t),this.windows.set(e,o),{allowed:!0}}async acquire(e,t={}){let s=t.maxWaitMs??3e5,r=Date.now()+s,o=!0;for(;;){let i=this.check(e);if(i.allowed)return{ok:!0};if(Date.now()>=r)return{ok:!1,reason:`${i.reason} (waited ${Math.round(s/1e3)}s, giving up)`};o&&(o=!1,t.onWait?.(i.reason,i.waitMs));let a=r-Date.now(),c=Math.min(i.waitMs??1e3,a,5e3);await new Promise(d=>setTimeout(d,c))}}usage(e){let t=Date.now(),s=this.windows.get(e)||[];return{lastMinute:s.filter(r=>r>t-6e4).length,lastHour:s.filter(r=>r>t-36e5).length}}};var rd={totalBudget:6e3,layerBudgets:{channel:200,scope:200,landscape:800,identity:200,bootstrap:500,references:500,intent:200,artifacts:500,procedures:400,memory:400,history:1200,"cross-chat":800,wiki:2500}},no=4;function so(n,e=rd){let t=od(n,e);t.sort((i,a)=>i.priority-a.priority);let s=[],r=0,o=e.totalBudget*no;for(let i of t){if(!i.content)continue;let a=i.maxTokens*no,c=i.content.length>a?i.content.slice(0,a)+"...":i.content;if(r+c.length>o){let d=o-r;d>100&&s.push(c.slice(0,d)+"...");break}s.push(c),r+=c.length}return s.join(`
40
+ `)}catch{return""}}async compactIfNeeded(e,t,s,r){let o=this.getSession(e,t,s),{needsCompaction:i,compactSession:a,applyCompaction:c}=await import("./compaction-FS6XNRLM.js");if(!i(o.messages))return{compacted:!1};let d=await a(o.messages,e,r,{channel:t,chatId:s});return d.compactedCount===0?{compacted:!1}:(o.messages=c(o.messages,d),o.updatedAt=new Date().toISOString(),this.save(o),{compacted:!0,qualityScore:d.qualityScore,lostEntities:d.lostEntities,drift:d.drift})}hasCompaction(e,t,s){let r=this.getSession(e,t,s);return r.messages.length>0&&r.messages[0].content.startsWith(Za)}clearClaudeSessionId(e,t,s){let r=this.getSession(e,t,s);delete r.claudeSessionId,delete r.codexSessionId,delete r.opencodeSessionId,delete r.turnCount,delete r.lastTurnInputTokens,delete r.lastTurnContextTokens,r.updatedAt=new Date().toISOString(),this.save(r)}clearSession(e,t,s){let r=this.getSession(e,t,s);r.messages=[],delete r.claudeSessionId,delete r.codexSessionId,delete r.opencodeSessionId,delete r.turnCount,delete r.lastTurnInputTokens,delete r.lastTurnContextTokens,r.updatedAt=new Date().toISOString(),this.save(r)}shouldRotateByTurns(e,t,s){let r=this.getSession(e,t,s);return!r.claudeSessionId&&!r.codexSessionId&&!r.opencodeSessionId?!1:(r.turnCount??0)>=this.maxTurnsPerSession}shouldRotateByTierTwo(e,t,s){let r=this.getSession(e,t,s);return!r.claudeSessionId&&!r.codexSessionId&&!r.opencodeSessionId?!1:(r.lastTurnContextTokens??r.lastTurnInputTokens??0)>=this.getTierTwoThresholdTokens(t)}recordTurnUsage(e,t,s,r,o){let i=this.getSession(e,t,s);i.turnCount=(i.turnCount??0)+1,i.lastTurnInputTokens=(r.inputTokens||0)+(r.cacheReadTokens||0)+(r.cacheCreateTokens||0),i.lastTurnContextTokens=o,i.updatedAt=new Date().toISOString(),this.save(i)}rotationMemoFile(){return Ce(this.sessionsDir,"_rotation-memos.json")}readRotationMemos(){try{let e=JSON.parse($e(this.rotationMemoFile(),"utf-8"));return e&&typeof e=="object"?e:{}}catch{return{}}}setRotationMemo(e,t,s,r,o){let i=this.readRotationMemos();i[`${e}:${t}:${s}`]={memo:r,reason:o,capturedAt:new Date().toISOString()},Vr(this.rotationMemoFile(),JSON.stringify(i,null,2))}getRotationMemo(e,t,s){let r=this.readRotationMemos()[`${e}:${t}:${s}`];if(!r?.memo)return null;let o=Date.now()-Date.parse(r.capturedAt);return!Number.isFinite(o)||o>ed?null:r}getTurnCount(e,t,s){return this.getSession(e,t,s).turnCount??0}getLastTurnInputTokens(e,t,s){return this.getSession(e,t,s).lastTurnInputTokens??0}getLastTurnContextTokens(e,t,s){let r=this.getSession(e,t,s);return r.lastTurnContextTokens??r.lastTurnInputTokens??0}getRawLastTurnContextTokens(e,t,s){return this.getSession(e,t,s).lastTurnContextTokens??null}getMaxTurnsPerSession(){return this.maxTurnsPerSession}getTierTwoThresholdTokens(e){return(e?this.tierTwoThresholdTokensByChannel[e]:void 0)??this.tierTwoThresholdTokens}trim(e){let t=e.messages.length;e.messages.length>Ke&&(e.messages=e.messages.slice(-Ke));let s=e.messages.reduce((o,i)=>o+i.content.length,0);for(;s>fn&&e.messages.length>2;){let o=e.messages.shift();s-=o.content.length}let r=t-e.messages.length;r>0&&he.cat("context",`[${e.agentId}] ${e.channel}:${e.chatId} trim dropped ${r} message(s): ${t} -> ${e.messages.length} (${s}c)`)}save(e){try{let t=this.sessionFile(e.id);Vr(t,JSON.stringify(e,null,2))}catch{}}};var At=class{windows=new Map;maxPerMinute;maxPerHour;constructor(e=10,t=100){this.maxPerMinute=e,this.maxPerHour=t}check(e){let t=Date.now(),s=this.windows.get(e)||[],r=t-36e5,o=s.filter(c=>c>r),i=t-6e4,a=o.filter(c=>c>i);if(a.length>=this.maxPerMinute){let c=a[0],d=Math.max(50,c+6e4-t);return{allowed:!1,reason:`Rate limit: ${a.length}/${this.maxPerMinute} per minute`,waitMs:d}}if(o.length>=this.maxPerHour){let c=o[0],d=Math.max(1e3,c+36e5-t);return{allowed:!1,reason:`Rate limit: ${o.length}/${this.maxPerHour} per hour`,waitMs:d}}return o.push(t),this.windows.set(e,o),{allowed:!0}}async acquire(e,t={}){let s=t.maxWaitMs??3e5,r=Date.now()+s,o=!0;for(;;){let i=this.check(e);if(i.allowed)return{ok:!0};if(Date.now()>=r)return{ok:!1,reason:`${i.reason} (waited ${Math.round(s/1e3)}s, giving up)`};o&&(o=!1,t.onWait?.(i.reason,i.waitMs));let a=r-Date.now(),c=Math.min(i.waitMs??1e3,a,5e3);await new Promise(d=>setTimeout(d,c))}}usage(e){let t=Date.now(),s=this.windows.get(e)||[];return{lastMinute:s.filter(r=>r>t-6e4).length,lastHour:s.filter(r=>r>t-36e5).length}}};var od={totalBudget:6e3,layerBudgets:{channel:200,scope:200,landscape:800,identity:200,bootstrap:500,references:500,intent:200,artifacts:500,procedures:400,memory:400,history:1200,"cross-chat":800,wiki:2500}},so=4;function ro(n,e=od){let t=id(n,e);t.sort((i,a)=>i.priority-a.priority);let s=[],r=0,o=e.totalBudget*so;for(let i of t){if(!i.content)continue;let a=i.maxTokens*so,c=i.content.length>a?i.content.slice(0,a)+"...":i.content;if(r+c.length>o){let d=o-r;d>100&&s.push(c.slice(0,d)+"...");break}s.push(c),r+=c.length}return s.join(`
41
41
 
42
- `)}function od(n,e){let t=(i,a)=>e.layerBudgets?.[i]??a,s=[];if(s.push(id(n,t("channel",200))),s.push(ad(n,t("scope",200))),n.landscape&&s.push({name:"landscape",priority:3,maxTokens:t("landscape",350),content:n.landscape,tags:["landscape","world-model"]}),n.systemPrompt&&s.push({name:"identity",priority:4,maxTokens:t("identity",200),content:n.systemPrompt.split(`
42
+ `)}function id(n,e){let t=(i,a)=>e.layerBudgets?.[i]??a,s=[];if(s.push(ad(n,t("channel",200))),s.push(dd(n,t("scope",200))),n.landscape&&s.push({name:"landscape",priority:3,maxTokens:t("landscape",350),content:n.landscape,tags:["landscape","world-model"]}),n.systemPrompt&&s.push({name:"identity",priority:4,maxTokens:t("identity",200),content:n.systemPrompt.split(`
43
43
  `)[0],tags:["identity",n.agentId]}),n.bootstrapContext&&s.push({name:"bootstrap",priority:4.5,maxTokens:t("bootstrap",500),content:n.bootstrapContext,tags:["bootstrap","identity","personality"]}),n.references&&s.push({name:"references",priority:4.7,maxTokens:t("references",500),content:n.references,tags:["references","verified","deterministic"]}),n.intent&&n.intent.path.length>0){let i=[`[Intent path: ${n.intent.pathLabel}${n.intent.status==="pending"?" (pending approval)":""}]`],a=n.intent.path[n.intent.path.length-1],c=n.intent.axes?.[a];if(c&&Object.keys(c).length){let d=Object.entries(c).map(([u,l])=>` ${u}: ${l}`).join(`
44
44
  `);i.push(d)}n.intent.leaf?.input&&i.push(` input: ${n.intent.leaf.input}`),s.push({name:"intent",priority:5,maxTokens:t("intent",200),content:i.join(`
45
- `),tags:["intent",...n.intent.path]})}else{let i=dd(n.message);i.length&&s.push({name:"intent",priority:5,maxTokens:t("intent",200),content:`[Intent: ${i.join(", ")}]`,tags:i})}let r=[];n.replyToText&&r.push(`[Replying to]: ${n.replyToText.slice(0,300)}`),n.mediaPath&&(r.push(`[Attached file: ${n.mediaPath}]`),r.push(`[File type: ${n.mediaType||"unknown"}]`),n.mediaType?.startsWith("image/")?r.push("Please view this image and respond to it."):n.mediaType?.startsWith("audio/")&&r.push("Please transcribe this audio and respond.")),n.issueMR&&r.push(`[${n.issueMR.type} #${n.issueMR.iid}: ${n.issueMR.title}]`),r.length&&s.push({name:"artifacts",priority:6,maxTokens:t("artifacts",500),content:r.join(`
45
+ `),tags:["intent",...n.intent.path]})}else{let i=cd(n.message);i.length&&s.push({name:"intent",priority:5,maxTokens:t("intent",200),content:`[Intent: ${i.join(", ")}]`,tags:i})}let r=[];n.replyToText&&r.push(`[Replying to]: ${n.replyToText.slice(0,300)}`),n.mediaPath&&(r.push(`[Attached file: ${n.mediaPath}]`),r.push(`[File type: ${n.mediaType||"unknown"}]`),n.mediaType?.startsWith("image/")?r.push("Please view this image and respond to it."):n.mediaType?.startsWith("audio/")&&r.push("Please transcribe this audio and respond.")),n.issueMR&&r.push(`[${n.issueMR.type} #${n.issueMR.iid}: ${n.issueMR.title}]`),r.length&&s.push({name:"artifacts",priority:6,maxTokens:t("artifacts",500),content:r.join(`
46
46
  `),tags:["artifacts",...n.mediaType?["media"]:[]]}),n.skillInjection&&s.push({name:"skills",priority:6.4,maxTokens:t("skills",800),content:n.skillInjection,tags:["skills","auto-inject"]}),n.patternContext&&s.push({name:"patterns",priority:6.5,maxTokens:t("patterns",300),content:n.patternContext,tags:["patterns","behavioral","self-improving"]}),n.procedureContext&&s.push({name:"procedures",priority:6.6,maxTokens:t("procedures",400),content:n.procedureContext,tags:["procedures","sop"]}),n.memoryContext&&s.push({name:"memory",priority:6.7,maxTokens:t("memory",400),content:n.memoryContext,tags:["memory","persistent"]});let o=n.groupHistory||n.sessionHistory;if(o&&s.push({name:"history",priority:7,maxTokens:t("history",1200),content:o,tags:["history","conversation"]}),n.crossChatContext&&s.push({name:"cross-chat",priority:7,maxTokens:t("cross-chat",800),content:n.crossChatContext,tags:["history","cross-chat"]}),n.contextOnDemand&&s.push({name:"on-demand",priority:7,maxTokens:t("on-demand",150),content:n.contextOnDemand,tags:["history","on-demand","lean"]}),n.longMemoryRecall&&s.push({name:"long-memory",priority:7,maxTokens:t("long-memory",1500),content:n.longMemoryRecall,tags:["history","long-memory"]}),n.handoverNote){let i=[`[Handover] You are taking over this conversation from ${n.handoverNote.fromAgent}.`];n.handoverNote.summary&&i.push(`Operator summary: ${n.handoverNote.summary}`),i.push(`Handover time: ${n.handoverNote.at}`),s.push({name:"handover",priority:7.5,maxTokens:t("handover",400),content:i.join(`
47
47
  `),tags:["handover",n.handoverNote.fromAgent]})}return n.rotationMemo&&s.push({name:"rotation-memo",priority:7.6,maxTokens:t("rotation-memo",800),content:[`[Continuity memo \u2014 your previous session for this chat ended (${n.rotationMemo.reason}, ${n.rotationMemo.capturedAt}). Carry on from this work state; do not claim you lack prior context. It is a summary, not checked facts: re-check account, billing, outage or deploy state before stating it, or say it is unverified and ask the owner:]`,n.rotationMemo.memo].join(`
48
- `),tags:["continuity","rotation-memo"]}),n.eventDigest&&s.push({name:"events",priority:7.7,maxTokens:t("events",500),content:n.eventDigest,tags:["events","subscriptions"]}),n.attachHint&&s.push({name:"attachments",priority:2.5,maxTokens:t("attachments",250),content:n.attachHint,tags:["channel","attachments"]}),n.wikiContext&&s.push({name:"wiki",priority:6.1,maxTokens:t("wiki",2500),content:n.wikiContext,tags:["wiki","knowledge"]}),s}function id(n,e){let t=[`Channel: ${n.channel}`];n.chatId&&t.push(`Chat ID: ${n.chatId} (use this verbatim in /recall, /send)`);let s=[],r=[n.channel];switch(n.channel){case"telegram":n.agentHandle&&t.push(`Your handle: ${n.agentHandle}`),t.push(`From: ${n.sender}`),n.senderId&&t.push(`Telegram user ID: ${n.senderId}`),n.senderUsername&&t.push(`Username: @${n.senderUsername}`),s.push("Format responses using Telegram-compatible markdown"),s.push("Be brief \u2014 2-4 sentences max for the main point. Humans scan, not read"),s.push("Lead with the action or answer, skip preamble");break;case"whatsapp":t.push(`From: ${n.sender}`),s.push("Be brief \u2014 2-3 sentences max. WhatsApp is mobile-first"),s.push("No rich formatting \u2014 plain text only"),s.push("Lead with the action or answer, skip preamble");break;case"gitlab":t.push(`From: ${n.sender}`),s.push("Reply as a short, actionable GitLab comment \u2014 3-5 lines for the main message"),s.push("Do NOT mention Telegram handles \u2014 they don't work on GitLab"),s.push("Do NOT delegate to other agents"),s.push("Reference issues with #IID and merge requests with !IID"),s.push("Put verbose details (logs, full commands, step-by-step) inside collapsible sections: <details><summary>Title</summary>\\n\\ncontent\\n</details>"),s.push("Never narrate what you are about to do \u2014 just do it and report the result"),r.push("code-review");break;case"discord":t.push(`From: ${n.sender}`),s.push("Use Discord markdown for formatting"),s.push("Be brief \u2014 2-4 sentences for the main point");break;default:n.channel.startsWith("webhook:")&&(s.push("This is an automated event \u2014 respond with actionable steps"),r.push("webhook","automated"))}return s.length&&(t.push(""),t.push("[Rules]"),t.push(...s.map(o=>`- ${o}`))),{name:"channel",priority:1,maxTokens:e,content:t.join(`
49
- `),tags:r,rules:s}}function ad(n,e){let t=[],s=[];if(n.channelScope==="group"&&n.groupName?(t.push(`Group: ${n.groupName}`),s.push("group",n.groupName)):n.channelScope==="project"&&n.projectPath?(t.push(`Project: ${n.projectPath}`),s.push("project",n.projectPath)):n.channelScope==="personal"&&(t.push("Direct message"),s.push("dm")),n.channelMeta){let r=n.channelMeta;if(r.agents?.length&&(t.push(`[Verified bots in this chat: ${r.agents.map(o=>o.handle||o.name||o.id).join(", ")}]`),t.push("Only mention these agents as group members \u2014 do NOT assume others are present.")),r.project&&t.push(`Project: ${r.project}`),r.issue&&t.push(`${r.issue.type} #${r.issue.iid}${r.issue.title?`: ${r.issue.title}`:""}`),r.facts?.length)for(let o of r.facts)t.push(`\u2022 ${o}`)}return{name:"scope",priority:2,maxTokens:e,content:t.join(`
50
- `),tags:s}}function dd(n){let e=[],t=n.toLowerCase();return/deploy|push|release|ship/.test(t)&&e.push("deployment"),/review|check|look at|approve/.test(t)&&e.push("review"),/fix|bug|broken|error|issue/.test(t)&&e.push("bugfix"),/create|add|build|implement/.test(t)&&e.push("feature"),/test|spec|coverage/.test(t)&&e.push("testing"),/refactor|clean|improve/.test(t)&&e.push("refactor"),/docs|document|readme/.test(t)&&e.push("docs"),/security|vuln|auth|token/.test(t)&&e.push("security"),/perf|slow|optim|fast/.test(t)&&e.push("performance"),/status|update|progress|standup/.test(t)&&e.push("status"),/help|how|what|explain/.test(t)&&e.push("question"),/gitlab|merge|mr|issue|pipeline/.test(t)&&e.push("gitlab"),/seo|analytics|content|marketing/.test(t)&&e.push("marketing"),/infra|server|docker|k8s|devops/.test(t)&&e.push("devops"),e}var cd="resumeDelivery";function Fl(n){if(!n||n.kind!=="direct"||!n.context||n.context[cd]||String(n.context.channel??"").toLowerCase().split("@")[0]!=="a2a")return null;let s=String(n.context.sender??"").match(/^agent:([^\s]+)$/);return s?s[1]:null}var ud=32e3;function ro(n){if(!n)return null;try{let e=JSON.stringify(n);return e.length<=ud?e:null}catch{return null}}function Ul(n){if(!n)return null;try{let e=JSON.parse(n);if(e?.kind==="router"&&typeof e.adapter=="string"&&e.message&&typeof e.message=="object"||e?.kind==="mesh"&&typeof e.channel=="string"&&typeof e.chatId=="string"||e?.kind==="direct")return e}catch{}return null}function oo(n){return new Date(n).toISOString().slice(11,16)}function io(n,e=Date.now()){return!Number.isFinite(n)||e-n<=6e4?null:`[queued at ${oo(n)} UTC, running at ${oo(e)} UTC \u2014 anything it refers to (PR head, issue state, files) may have changed; re-check the current state before acting or replying]`}var At=class{queues=new Map;defaultMode;constructor(e="collect"){this.defaultMode=e}key(e,t,s){return`${e}:${t}:${s}`}getOrCreate(e,t,s){let r=this.key(e,t,s);return this.queues.has(r)||this.queues.set(r,{mode:this.defaultMode,pending:[],running:!1}),this.queues.get(r)}setMode(e,t,s,r){this.getOrCreate(e,t,s).mode=r}onFlush(e,t,s,r){this.getOrCreate(e,t,s).onFlush=r}isBusy(e,t,s){return this.getOrCreate(e,t,s).running}markRunning(e,t,s){let r=this.getOrCreate(e,t,s);return r.running?!1:(r.running=!0,!0)}enqueue(e,t,s,r){let o=this.getOrCreate(e,t,s);if(!o.running)return null;switch(o.mode){case"drop":return"drop";case"collect":case"followup":return o.pending.push(r),o.mode}}async markDone(e,t,s){let r=this.getOrCreate(e,t,s);if(r.running=!1,r.pending.length===0)return[];let o=[...r.pending];switch(r.pending=[],r.mode){case"collect":{let a={text:o.length===1?o[0].text:o.map(c=>`[${c.sender}, ${new Date(c.timestamp).toISOString().slice(11,16)}]: ${c.text}`).join(`
51
- `),sender:o[o.length-1].sender,timestamp:Date.now(),channel:o[0].channel,chatId:o[0].chatId,originalContext:o[o.length-1].originalContext,queuedAt:Math.min(...o.map(c=>c.queuedAt??c.timestamp))};return r.onFlush&&await r.onFlush([a]),[a]}case"followup":return r.onFlush&&await r.onFlush(o),o;case"drop":return[];default:return o}}pendingCount(e,t,s){return this.getOrCreate(e,t,s).pending.length}clear(e,t,s){let r=this.key(e,t,s);this.queues.delete(r)}stats(){return Array.from(this.queues.entries()).map(([e,t])=>({key:e,mode:t.mode,pending:t.pending.length,running:t.running}))}};import{readFileSync as ld,writeFileSync as ao,appendFileSync as gd,mkdirSync as pd,existsSync as co}from"fs";import{resolve as fn}from"path";var uo=50,fd="claude-haiku-4-5-20251001",md=`You are a behavioral pattern extractor. Given a conversation between a user and an AI agent, extract behavioral patterns \u2014 lessons about HOW to approach tasks, not facts about the world.
48
+ `),tags:["continuity","rotation-memo"]}),n.eventDigest&&s.push({name:"events",priority:7.7,maxTokens:t("events",500),content:n.eventDigest,tags:["events","subscriptions"]}),n.attachHint&&s.push({name:"attachments",priority:2.5,maxTokens:t("attachments",250),content:n.attachHint,tags:["channel","attachments"]}),n.wikiContext&&s.push({name:"wiki",priority:6.1,maxTokens:t("wiki",2500),content:n.wikiContext,tags:["wiki","knowledge"]}),s}function ad(n,e){let t=[`Channel: ${n.channel}`];n.chatId&&t.push(`Chat ID: ${n.chatId} (use this verbatim in /recall, /send)`);let s=[],r=[n.channel];switch(n.channel){case"telegram":n.agentHandle&&t.push(`Your handle: ${n.agentHandle}`),t.push(`From: ${n.sender}`),n.senderId&&t.push(`Telegram user ID: ${n.senderId}`),n.senderUsername&&t.push(`Username: @${n.senderUsername}`),s.push("Format responses using Telegram-compatible markdown"),s.push("Be brief \u2014 2-4 sentences max for the main point. Humans scan, not read"),s.push("Lead with the action or answer, skip preamble");break;case"whatsapp":t.push(`From: ${n.sender}`),s.push("Be brief \u2014 2-3 sentences max. WhatsApp is mobile-first"),s.push("No rich formatting \u2014 plain text only"),s.push("Lead with the action or answer, skip preamble");break;case"gitlab":t.push(`From: ${n.sender}`),s.push("Reply as a short, actionable GitLab comment \u2014 3-5 lines for the main message"),s.push("Do NOT mention Telegram handles \u2014 they don't work on GitLab"),s.push("Do NOT delegate to other agents"),s.push("Reference issues with #IID and merge requests with !IID"),s.push("Put verbose details (logs, full commands, step-by-step) inside collapsible sections: <details><summary>Title</summary>\\n\\ncontent\\n</details>"),s.push("Never narrate what you are about to do \u2014 just do it and report the result"),r.push("code-review");break;case"discord":t.push(`From: ${n.sender}`),s.push("Use Discord markdown for formatting"),s.push("Be brief \u2014 2-4 sentences for the main point");break;default:n.channel.startsWith("webhook:")&&(s.push("This is an automated event \u2014 respond with actionable steps"),r.push("webhook","automated"))}return s.length&&(t.push(""),t.push("[Rules]"),t.push(...s.map(o=>`- ${o}`))),{name:"channel",priority:1,maxTokens:e,content:t.join(`
49
+ `),tags:r,rules:s}}function dd(n,e){let t=[],s=[];if(n.channelScope==="group"&&n.groupName?(t.push(`Group: ${n.groupName}`),s.push("group",n.groupName)):n.channelScope==="project"&&n.projectPath?(t.push(`Project: ${n.projectPath}`),s.push("project",n.projectPath)):n.channelScope==="personal"&&(t.push("Direct message"),s.push("dm")),n.channelMeta){let r=n.channelMeta;if(r.agents?.length&&(t.push(`[Verified bots in this chat: ${r.agents.map(o=>o.handle||o.name||o.id).join(", ")}]`),t.push("Only mention these agents as group members \u2014 do NOT assume others are present.")),r.project&&t.push(`Project: ${r.project}`),r.issue&&t.push(`${r.issue.type} #${r.issue.iid}${r.issue.title?`: ${r.issue.title}`:""}`),r.facts?.length)for(let o of r.facts)t.push(`\u2022 ${o}`)}return{name:"scope",priority:2,maxTokens:e,content:t.join(`
50
+ `),tags:s}}function cd(n){let e=[],t=n.toLowerCase();return/deploy|push|release|ship/.test(t)&&e.push("deployment"),/review|check|look at|approve/.test(t)&&e.push("review"),/fix|bug|broken|error|issue/.test(t)&&e.push("bugfix"),/create|add|build|implement/.test(t)&&e.push("feature"),/test|spec|coverage/.test(t)&&e.push("testing"),/refactor|clean|improve/.test(t)&&e.push("refactor"),/docs|document|readme/.test(t)&&e.push("docs"),/security|vuln|auth|token/.test(t)&&e.push("security"),/perf|slow|optim|fast/.test(t)&&e.push("performance"),/status|update|progress|standup/.test(t)&&e.push("status"),/help|how|what|explain/.test(t)&&e.push("question"),/gitlab|merge|mr|issue|pipeline/.test(t)&&e.push("gitlab"),/seo|analytics|content|marketing/.test(t)&&e.push("marketing"),/infra|server|docker|k8s|devops/.test(t)&&e.push("devops"),e}var ud="resumeDelivery";function Ul(n){if(!n||n.kind!=="direct"||!n.context||n.context[ud]||String(n.context.channel??"").toLowerCase().split("@")[0]!=="a2a")return null;let s=String(n.context.sender??"").match(/^agent:([^\s]+)$/);return s?s[1]:null}var ld=32e3;function oo(n){if(!n)return null;try{let e=JSON.stringify(n);return e.length<=ld?e:null}catch{return null}}function Hl(n){if(!n)return null;try{let e=JSON.parse(n);if(e?.kind==="router"&&typeof e.adapter=="string"&&e.message&&typeof e.message=="object"||e?.kind==="mesh"&&typeof e.channel=="string"&&typeof e.chatId=="string"||e?.kind==="direct")return e}catch{}return null}function io(n){return new Date(n).toISOString().slice(11,16)}function ao(n,e=Date.now()){return!Number.isFinite(n)||e-n<=6e4?null:`[queued at ${io(n)} UTC, running at ${io(e)} UTC \u2014 anything it refers to (PR head, issue state, files) may have changed; re-check the current state before acting or replying]`}var $t=class{queues=new Map;defaultMode;constructor(e="collect"){this.defaultMode=e}key(e,t,s){return`${e}:${t}:${s}`}getOrCreate(e,t,s){let r=this.key(e,t,s);return this.queues.has(r)||this.queues.set(r,{mode:this.defaultMode,pending:[],running:!1}),this.queues.get(r)}setMode(e,t,s,r){this.getOrCreate(e,t,s).mode=r}onFlush(e,t,s,r){this.getOrCreate(e,t,s).onFlush=r}isBusy(e,t,s){return this.getOrCreate(e,t,s).running}markRunning(e,t,s){let r=this.getOrCreate(e,t,s);return r.running?!1:(r.running=!0,!0)}enqueue(e,t,s,r){let o=this.getOrCreate(e,t,s);if(!o.running)return null;switch(o.mode){case"drop":return"drop";case"collect":case"followup":return o.pending.push(r),o.mode}}async markDone(e,t,s){let r=this.getOrCreate(e,t,s);if(r.running=!1,r.pending.length===0)return[];let o=[...r.pending];switch(r.pending=[],r.mode){case"collect":{let a={text:o.length===1?o[0].text:o.map(c=>`[${c.sender}, ${new Date(c.timestamp).toISOString().slice(11,16)}]: ${c.text}`).join(`
51
+ `),sender:o[o.length-1].sender,timestamp:Date.now(),channel:o[0].channel,chatId:o[0].chatId,originalContext:o[o.length-1].originalContext,queuedAt:Math.min(...o.map(c=>c.queuedAt??c.timestamp))};return r.onFlush&&await r.onFlush([a]),[a]}case"followup":return r.onFlush&&await r.onFlush(o),o;case"drop":return[];default:return o}}pendingCount(e,t,s){return this.getOrCreate(e,t,s).pending.length}clear(e,t,s){let r=this.key(e,t,s);this.queues.delete(r)}stats(){return Array.from(this.queues.entries()).map(([e,t])=>({key:e,mode:t.mode,pending:t.pending.length,running:t.running}))}};import{readFileSync as gd,writeFileSync as co,appendFileSync as pd,mkdirSync as fd,existsSync as uo}from"fs";import{resolve as mn}from"path";var lo=50,md="claude-haiku-4-5-20251001",hd=`You are a behavioral pattern extractor. Given a conversation between a user and an AI agent, extract behavioral patterns \u2014 lessons about HOW to approach tasks, not facts about the world.
52
52
 
53
53
  Extract patterns like:
54
54
  - "When asked about X, the approach that works is Y"
@@ -64,52 +64,52 @@ SKIP:
64
64
  Output a JSON array:
65
65
  [{"pattern":"the behavioral lesson","context":"when this applies","confidence":0.5}]
66
66
 
67
- If nothing worth extracting, output: []`,$t=class{patternsDir;constructor(e=process.cwd()){this.patternsDir=fn(e,".agentx/patterns"),co(this.patternsDir)||pd(this.patternsDir,{recursive:!0})}filePath(e){return fn(this.patternsDir,`${e}.jsonl`)}getAll(e){let t=this.filePath(e);if(!co(t))return[];try{return ld(t,"utf-8").split(`
68
- `).filter(s=>s.trim()).map(s=>{try{return JSON.parse(s)}catch{return null}}).filter(s=>s!==null)}catch{return[]}}addPattern(e,t){let s={...t,id:`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,accessCount:0,createdAt:new Date().toISOString()};gd(this.filePath(e),JSON.stringify(s)+`
69
- `)}findRelevant(e,t,s=5){let r=this.getAll(t);if(r.length===0)return[];let o=r.map(u=>`${u.context} ${u.pattern}`),i=fn(this.patternsDir,`${t}_bm25_cache.json`),a=as(o,i),d=is(e,a).slice(0,s).map(u=>r[u.docIndex]).filter(u=>u.confidence>=.3);return d.length>0&&this.recordAccess(t,d.map(u=>u.id)),d}buildContext(e){if(e.length===0)return"";let t=["[Learned Patterns \u2014 behavioral lessons from past interactions]"];for(let s of e)t.push(`- ${s.pattern} (context: ${s.context}, confidence: ${Math.round(s.confidence*100)}%)`);return t.push("[Apply these patterns when relevant to the current task]"),t.join(`
70
- `)}hasSimilar(e,t){let s=this.getAll(e),r=t.toLowerCase().split(/\s+/).filter(o=>o.length>3);return s.some(o=>{let i=o.pattern.toLowerCase();return r.filter(c=>i.includes(c)).length>=r.length*.6})}recordAccess(e,t){let s=this.getAll(e),r=new Set(t),o=!1;for(let i of s)r.has(i.id)&&(i.accessCount++,i.lastUsed=new Date().toISOString(),i.confidence=Math.min(1,i.confidence+.05),o=!0);o&&ao(this.filePath(e),s.map(i=>JSON.stringify(i)).join(`
67
+ If nothing worth extracting, output: []`,Ct=class{patternsDir;constructor(e=process.cwd()){this.patternsDir=mn(e,".agentx/patterns"),uo(this.patternsDir)||fd(this.patternsDir,{recursive:!0})}filePath(e){return mn(this.patternsDir,`${e}.jsonl`)}getAll(e){let t=this.filePath(e);if(!uo(t))return[];try{return gd(t,"utf-8").split(`
68
+ `).filter(s=>s.trim()).map(s=>{try{return JSON.parse(s)}catch{return null}}).filter(s=>s!==null)}catch{return[]}}addPattern(e,t){let s={...t,id:`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,accessCount:0,createdAt:new Date().toISOString()};pd(this.filePath(e),JSON.stringify(s)+`
69
+ `)}findRelevant(e,t,s=5){let r=this.getAll(t);if(r.length===0)return[];let o=r.map(u=>`${u.context} ${u.pattern}`),i=mn(this.patternsDir,`${t}_bm25_cache.json`),a=ds(o,i),d=as(e,a).slice(0,s).map(u=>r[u.docIndex]).filter(u=>u.confidence>=.3);return d.length>0&&this.recordAccess(t,d.map(u=>u.id)),d}buildContext(e){if(e.length===0)return"";let t=["[Learned Patterns \u2014 behavioral lessons from past interactions]"];for(let s of e)t.push(`- ${s.pattern} (context: ${s.context}, confidence: ${Math.round(s.confidence*100)}%)`);return t.push("[Apply these patterns when relevant to the current task]"),t.join(`
70
+ `)}hasSimilar(e,t){let s=this.getAll(e),r=t.toLowerCase().split(/\s+/).filter(o=>o.length>3);return s.some(o=>{let i=o.pattern.toLowerCase();return r.filter(c=>i.includes(c)).length>=r.length*.6})}recordAccess(e,t){let s=this.getAll(e),r=new Set(t),o=!1;for(let i of s)r.has(i.id)&&(i.accessCount++,i.lastUsed=new Date().toISOString(),i.confidence=Math.min(1,i.confidence+.05),o=!0);o&&co(this.filePath(e),s.map(i=>JSON.stringify(i)).join(`
71
71
  `)+`
72
- `)}prune(e){let t=this.getAll(e);t.length<=uo||(t.sort((s,r)=>r.confidence*r.accessCount-s.confidence*s.accessCount),t=t.slice(0,uo),ao(this.filePath(e),t.map(s=>JSON.stringify(s)).join(`
72
+ `)}prune(e){let t=this.getAll(e);t.length<=lo||(t.sort((s,r)=>r.confidence*r.accessCount-s.confidence*s.accessCount),t=t.slice(0,lo),co(this.filePath(e),t.map(s=>JSON.stringify(s)).join(`
73
73
  `)+`
74
- `))}};async function lo(n,e,t,s,r){if(e.length<30&&t.length<100)return;let{createProvider:o}=await import("./providers-55NC2SFN.js"),c=(await o("claude").generate([{role:"system",content:md},{role:"user",content:`User: ${e.slice(0,500)}
74
+ `))}};async function go(n,e,t,s,r){if(e.length<30&&t.length<100)return;let{createProvider:o}=await import("./providers-55NC2SFN.js"),c=(await o("claude").generate([{role:"system",content:hd},{role:"user",content:`User: ${e.slice(0,500)}
75
75
 
76
- Agent: ${t.slice(0,1e3)}`}],{model:fd,maxTokens:512})).content.trim().match(/\[[\s\S]*\]/);if(!c)return;let d=JSON.parse(c[0]);if(!(!Array.isArray(d)||d.length===0)){for(let u of d)r.hasSimilar(n,u.pattern)||r.addPattern(n,{agentId:n,pattern:u.pattern,context:u.context,confidence:u.confidence||.5,source:s});Math.random()<.05&&r.prune(n)}}import{EventEmitter as hd}from"events";var yd=2e4,hn=class{inner=new hd;envelopeListeners=new Set;ring=new Ks;node="local";seen=new Map;constructor(){this.inner.setMaxListeners(50)}configure(e){return e.node&&(this.node=e.node),e.ringSize&&this.ring.resize(e.ringSize),this}on(e,t){return this.inner.on(e,t),this}off(e,t){return this.inner.off(e,t),this}emit(e,t){let s=this.inner.emit(e,t);try{this.publish(wd(e,t))}catch{}return s}publish(e){let t=Gs(),s=e.id??Ws(),r={id:s,rootId:e.rootId??t?.rootId??s,node:this.node,kind:e.kind,type:e.type,at:e.at??new Date().toISOString(),summary:Vt(e.summary)},o=e.parentId??t?.parentId;o&&(r.parentId=o),e.agentId&&(r.agentId=e.agentId),e.ref&&(r.ref=e.ref),this.ring.push(r);for(let i of this.envelopeListeners)try{i(r,e.data)}catch{}return r}get nodeName(){return this.node}isLocal(e){return e.node===this.node}ingest(e){if(!e.node||e.node===this.node)return!1;let t=`${e.node}:${e.id}`;if(this.seen.has(t))return!1;this.seen.set(t,!0),this.seen.size>yd&&this.seen.delete(this.seen.keys().next().value);let s={id:e.id,rootId:e.rootId||e.id,node:e.node,kind:e.kind,type:e.type,at:e.at,summary:Vt(e.summary??"")};e.parentId&&(s.parentId=e.parentId),e.agentId&&(s.agentId=e.agentId),e.ref&&(s.ref=e.ref),this.ring.push(s);for(let r of this.envelopeListeners)try{r(s)}catch{}return!0}hasRecent(e){return this.ring.has(e)}subscribe(e){return this.envelopeListeners.add(e),()=>{this.envelopeListeners.delete(e)}}recent(e){return this.ring.recent(e)}listenerCount(e){return this.inner.listenerCount(e)}removeAllListeners(){return this.inner.removeAllListeners(),this.envelopeListeners.clear(),this.ring.clear(),this.seen.clear(),this}};function wd(n,e){let t=e,s={type:n,at:t.at,agentId:t.agentId,ref:t.taskId};switch(n){case"message:matched":return{...s,kind:"message",ref:t.msgId,summary:`${t.channel} ${t.chatId} \u2192 ${t.agentId} (${t.decidingStage})`};case"message:dropped":return{...s,kind:"message",ref:t.msgId,summary:`${t.channel} ${t.chatId} dropped at ${t.decidingStage}: ${t.reason}`};case"task:queued":return{...s,kind:"agent",summary:`queued on ${t.channel} ${t.chatId}`};case"task:queue-flushed":return{...s,kind:"agent",summary:`${t.count} queued message(s) handed over on ${t.channel} ${t.chatId}`};case"task:queue-ended":return{...s,kind:"agent",summary:`queued turn ended on ${t.channel} ${t.chatId}`};case"task:started":return{...s,kind:"agent",summary:`started on ${t.channel} ${t.chatId}`};case"task:step":return{...s,kind:"agent",summary:[t.name,t.action,t.status].filter(Boolean).join(" ")};case"task:completed":return{...s,kind:"agent",summary:t.error?`failed after ${t.durationMs}ms: ${t.error}`:`completed in ${t.durationMs}ms`};case"session:rotated":return{...s,kind:"agent",summary:`session rotated (${t.reason})`};default:return{...s,kind:"agent",summary:String(n)}}}var mn;function Y(){return mn||(mn=new hn),mn}qt();qt();var go=["manual","notify","auto"];function bd(n){return typeof n=="string"&&go.includes(n)}var yn={claimTimeoutMs:9e4,staleSessionMs:15*6e4,maxDrainPerTurn:5,maxItemChars:4e3};var xd=7*24*60*6e4,Je=class{constructor(e={},t){this.store=t;this.opts={...yn,...e};let s={};try{s=t?.load()??{}}catch{s={}}let r=Date.now()-xd;for(let[o,i]of Object.entries(s))i&&Array.isArray(i.agentIds)&&(i.agentIds.length>0||i.watch)&&i.savedAt>=r&&this.saved.set(o,i)}sessions=new Map;items=new Map;waiters=new Map;saved=new Map;opts;options(){return this.opts}register(e,t={}){let s=t.now??Date.now(),r=this.sessions.get(e);if(r)return r.lastSeenAt=s,t.cwd&&(r.cwd=t.cwd),t.model&&(r.model=t.model),r;let o=this.saved.get(e),i={sessionId:e,cwd:t.cwd??o?.cwd??"",agentIds:o?o.agentIds.filter(a=>!this.sessionFor(a)):[],mode:o?.mode??"notify",lastSeenAt:s,registeredAt:s,model:t.model,drainedThisTurn:0};return o?.watch&&(i.watch={...o.watch}),this.sessions.set(e,i),o&&this.remember(i,s),i}touch(e,t=Date.now()){let s=this.sessions.get(e);return s?(s.lastSeenAt=t,s):this.saved.has(e)?this.register(e,{now:t}):void 0}get(e){return this.sessions.get(e)}list(){return[...this.sessions.values()].sort((e,t)=>t.lastSeenAt-e.lastSeenAt)}bind(e,t,s){let r=this.sessions.get(e);if(r){for(let o of this.sessions.values())o.sessionId!==e&&(o.agentIds=o.agentIds.filter(i=>i!==t));for(let[o,i]of this.saved)o!==e&&(i.agentIds=i.agentIds.filter(a=>a!==t));return r.agentIds.includes(t)||r.agentIds.push(t),s&&(r.mode=s),r.watch=void 0,this.remember(r),r}}unbind(e,t){let s=this.sessions.get(e);if(s)return s.agentIds=t?s.agentIds.filter(r=>r!==t):[],t||(s.watch=void 0),this.remember(s),s}watch(e,t,s=Date.now()){let r=this.sessions.get(e);if(r)return r.agentIds=[],r.awaitingAnswer=void 0,this.expireItemsOf(e,s,"session switched to watch mode"),r.watch={subscriptions:t.subscriptions,cursor:t.cursor,startedAt:s},this.remember(r,s),r}advanceWatch(e,t){let s=this.sessions.get(e);s?.watch&&(s.watch.cursor.id===t.id&&s.watch.cursor.at===t.at||(s.watch.cursor=t,this.remember(s)))}setMode(e,t){let s=this.sessions.get(e);if(s)return s.mode=t,this.remember(s),s}sessionFor(e){for(let t of this.sessions.values())if(t.agentIds.includes(e))return t}deregister(e,t=Date.now(),s={}){this.sessions.delete(e),s.forget&&this.saved.delete(e)&&this.persist(),this.expireItemsOf(e,t,"session ended")}expireItemsOf(e,t,s){for(let r of this.items.values())r.sessionId===e&&(r.state==="pending"||r.state==="claimed")&&this.settle(r,"expired",t,s)}offer(e,t=Date.now()){let s=this.sessionFor(e.agentId);if(!s)return null;if(t-s.lastSeenAt>this.opts.staleSessionMs)return this.deregister(s.sessionId,t),null;let r={id:Ie(t),agentId:e.agentId,sessionId:s.sessionId,state:"pending",text:Sd(e.text,this.opts.maxItemChars),channel:e.channel,chatId:e.chatId,sender:e.sender,createdAt:t};return this.items.set(r.id,r),new Promise(o=>{this.waiters.set(r.id,{resolve:o})})}pending(e){return[...this.items.values()].filter(t=>t.sessionId===e&&t.state==="pending").sort((t,s)=>t.createdAt-s.createdAt)}pendingCount(e){let t=0;for(let s of this.items.values())s.sessionId===e&&s.state==="pending"&&t++;return t}claim(e,t=Date.now()){let s=this.sessions.get(e);if(!s||s.awaitingAnswer)return;let r=this.pending(e)[0];if(!(!r||r.state!=="pending"))return r.state="claimed",r.claimedAt=t,s.awaitingAnswer=r.id,s.lastSeenAt=t,s.drainedThisTurn++,r}answer(e,t,s=Date.now()){let r=this.sessions.get(e);if(!r?.awaitingAnswer)return;let o=this.items.get(r.awaitingAnswer);if(r.awaitingAnswer=void 0,!(!o||o.state!=="claimed"))return o.answer=t,this.settle(o,"answered",s),o}release(e,t=Date.now()){let s=this.sessions.get(e);if(!s?.awaitingAnswer)return;let r=this.items.get(s.awaitingAnswer);if(s.awaitingAnswer=void 0,!(!r||r.state!=="claimed"))return r.state="pending",r.claimedAt=void 0,s.lastSeenAt=t,r}expire(e,t,s=Date.now()){let r=this.items.get(e);if(!r||r.state!=="pending"&&r.state!=="claimed")return!1;let o=this.sessions.get(r.sessionId);return o?.awaitingAnswer===r.id&&(o.awaitingAnswer=void 0),this.settle(r,"expired",s,t),!0}sweep(e=Date.now()){let t=0;for(let s of this.items.values())s.state==="pending"&&e-s.createdAt>=this.opts.claimTimeoutMs?this.expire(s.id,"not claimed in time",e)&&t++:s.state==="claimed"&&e-(s.claimedAt??s.createdAt)>=this.opts.claimTimeoutMs&&this.expire(s.id,"claimed but never answered",e)&&t++;for(let s of this.sessions.values())e-s.lastSeenAt>this.opts.staleSessionMs&&this.deregister(s.sessionId,e);return t}endTurn(e){let t=this.sessions.get(e);t&&(t.drainedThisTurn=0)}savedBindings(){return Object.fromEntries(this.saved)}remember(e,t=Date.now()){if(e.agentIds.length===0&&!e.watch)this.saved.delete(e.sessionId);else{let s={agentIds:[...e.agentIds],mode:e.mode,cwd:e.cwd||void 0,savedAt:t};e.watch&&(s.watch={...e.watch}),this.saved.set(e.sessionId,s)}for(let[s,r]of this.saved)r.agentIds.length===0&&!r.watch&&this.saved.delete(s);this.persist()}persist(){try{this.store?.save(Object.fromEntries(this.saved))}catch{}}item(e){return this.items.get(e)}prune(e=Date.now(),t=36e5){let s=0;for(let[r,o]of this.items)(o.state==="answered"||o.state==="expired")&&e-(o.settledAt??o.createdAt)>t&&(this.items.delete(r),s++);return s}settle(e,t,s,r){e.state=t,e.settledAt=s;let o=this.waiters.get(e.id);o&&(this.waiters.delete(e.id),o.resolve(t==="answered"?{kind:"answered",text:e.answer??"",sessionId:e.sessionId}:{kind:"expired",reason:r??"expired"}))}};function Sd(n,e){return n.length<=e?n:`${n.slice(0,e)}
77
- \u2026[truncated ${n.length-e} chars]`}ta();import{z as Id}from"zod";var fo=[{kinds:["task:completed"]},{kinds:["failed","timeout","completed"]},{kinds:["paused"],match:"checkpoint"},{kinds:["lost"]}];function Td(n){if(n==null)return{ok:!0,subscriptions:fo};let e=Id.array(ys).min(1).safeParse(n);if(!e.success){let t=e.error.issues[0];return{ok:!1,error:`invalid subscriptions: ${t?.path.join(".")||"value"} ${t?.message??""}`.trim()}}return{ok:!0,subscriptions:e.data}}var vd=15,kd=1500,po=200;function mo(n,e=Date.now()){let t=n[n.length-1];return t?{id:t.id,at:t.at}:{at:new Date(e).toISOString()}}function Ad(n,e){if(e.id){let s=n.findIndex(r=>r.id===e.id);if(s>=0)return n.slice(s+1)}let t=Date.parse(e.at);return Number.isNaN(t)?n:e.id?n.filter(s=>Date.parse(s.at)>t):n.filter(s=>Date.parse(s.at)>=t)}function ng(n,e,t={}){let s=Ad(e,n.cursor),r=s.length?mo(s):n.cursor,o=s.filter(d=>n.subscriptions.some(u=>Js(u,d)));if(o.length===0)return{cursor:r,matched:0,shown:0};let i=n.cursor.id??n.cursor.at,{text:a,shown:c}=$d(o,i,t);return{text:a,cursor:r,matched:o.length,shown:c}}function $d(n,e,t={}){let s=Math.max(3,t.maxLines??vd),r=Math.max(200,t.maxChars??kd),o=n.map(a=>Cd(`- ${zs(a)}`)),i=o.length;for(let a=Math.min(i,s-1);a>=0;a--){let c=i-a,u=[c?`[agentx watch] ${i} events since your last turn, newest ${a} shown:`:`[agentx watch] ${i} event${i===1?"":"s"} since your last turn:`,...o.slice(i-a)];c&&u.push(`+${c} more \u2014 \`agentx events --since ${e}\``);let l=u.join(`
78
- `);if(u.length<=s&&l.length<=r)return{text:l,shown:a}}return{text:`[agentx watch] ${i} events since your last turn \u2014 \`agentx events --since ${e}\``,shown:0}}function Cd(n){return n.length<=po?n:`${n.slice(0,po-1)}\u2026`}import{existsSync as Md,mkdirSync as Pd,readFileSync as _d,renameSync as Rd,writeFileSync as Ed}from"node:fs";import{homedir as Dd}from"node:os";import{dirname as Od,join as Nd}from"node:path";function Ld(n){return{load:()=>Md(n)?JSON.parse(_d(n,"utf-8")):{},save:e=>{Pd(Od(n),{recursive:!0});let t=`${n}.tmp`;Ed(t,JSON.stringify(e,null,2),{mode:384}),Rd(t,n)}}}function Fd(){if(!process.env.VITEST)return Ld(process.env.AGENTX_ATTACH_BINDINGS_FILE??Nd(Dd(),".agentx","attach-bindings.json"))}var wn;function ho(){return wn||(wn=new Je({},Fd())),wn}Wt();import{readFileSync as Ud}from"fs";import{homedir as Hd}from"os";import{join as Bd}from"path";var Qe=null,jd=6e4;function qd(){try{let n=Bd(Hd(),".claude.json"),e=Ud(n,"utf8"),t=JSON.parse(e);return t&&typeof t=="object"?t:null}catch{return null}}function Wd(n,e=Date.now()){if(!n)return{available:!0,checkedAt:e,unknown:!0};let t=typeof n.cachedExtraUsageDisabledReason=="string"?n.cachedExtraUsageDisabledReason:void 0;return{available:!(t==="org_level_disabled_until"),reason:t,checkedAt:e}}function Gd(n=!1){let e=Date.now();return!n&&Qe&&e-Qe.checkedAt<jd||(Qe=Wd(qd(),e)),Qe}function yo(n){let e=Gd();return e.available||n?null:{abort:!0,reason:e.reason||"overage_disabled",message:"Claude Max-plan overage is disabled at the org level and this agent has no warm Claude session to cache against. A cold dispatch would pay a fresh cache-create that spills past the regular allotment, producing 'out of extra usage'. Re-enable overage at claude.ai/settings/usage, OR wait until a peer agent has established a warm session this agent can inherit before retrying.",raw:e}}var bo={warnRatio:.8},Me={...bo},Kd=5*60*60*1e3,Jd=60*60*1e3,we=[];function xo(n){Me={...bo,...n||{}}}function So(n){let e=n-Kd,t=0;for(;t<we.length&&we[t]<e;)t++;t>0&&we.splice(0,t)}function Io(n=Date.now()){So(n),we.push(n)}var Pe=new Map,Qd=15*60*1e3;function To(n){if(typeof n=="number"&&Number.isFinite(n))return n;if(typeof n=="string"&&n.trim()!==""&&Number.isFinite(Number(n)))return Number(n)}function zd(n){let e=To(n);if(!(e===void 0||e<=0))return e<1e12?e*1e3:e}function Xd(n,e=Date.now()){if(!n||typeof n!="object")return null;let t=n;if(t.type!=="rate_limit_event")return null;let s=t.rate_limit_info??t.rateLimitInfo;if(!s||typeof s!="object")return null;let r=s.status;if(r!=="allowed"&&r!=="allowed_warning"&&r!=="rejected")return null;let o=String(s.rateLimitType??s.rate_limit_type??"unknown"),i=zd(s.resetsAt??s.resets_at),a=To(s.utilization),c=s.overageStatus??s.overage_status,d=r==="rejected"&&((s.isUsingOverage??s.is_using_overage)===!0||c==="allowed"||c==="allowed_warning");return{status:r,window:o,resetsAt:i,utilization:a,...d&&{usingOverage:d},seenAt:e}}function vo(n){return/_(opus|sonnet|haiku)$/.exec(n)?.[1]??null}function ko(n,e){let t=vo(n);return!t||!e||e.toLowerCase().includes(t)}function bn(n,e=Date.now(),t){let s=Xd(n,e);if(!s)return null;if(s.status!=="rejected")for(let[r,o]of Pe)o.status!=="rejected"||r===s.window||(!vo(r)||t&&ko(r,t))&&Pe.delete(r);return Pe.set(s.window,s),s}function Ao(n=Date.now()){return[...Pe.values()].filter(e=>e.status!=="rejected"||e.usingOverage?!1:(e.resetsAt??e.seenAt+Qd)>n)}function Yd(n=Date.now(),e){return Ao(n).find(t=>ko(t.window,e))??null}function hg(n=Date.now()){let e=Ao(n);for(let t of e)Pe.delete(t.window);return e}function Vd(){return[...Pe.values()].sort((n,e)=>e.seenAt-n.seenAt)}function wo(n){return typeof n=="number"&&n>0}function $o(n=Date.now()){So(n);let e=n-Jd,t=0;for(let o=we.length-1;o>=0&&we[o]>=e;o--)t++;let s=we.length,r={lastHour:t,last5h:s,maxPerHour:wo(Me.maxPerHour)?Me.maxPerHour:void 0,maxPer5h:wo(Me.maxPer5h)?Me.maxPer5h:void 0,provider:Vd()};return r.maxPerHour&&(r.hourlyRatio=t/r.maxPerHour),r.maxPer5h&&(r.fiveHourRatio=s/r.maxPer5h),r}function Co(n){return n.replace(/_/g," ")}function Mo(n,e){return n?`in about ${Math.max(1,Math.round((n-e)/6e4))} min (${new Date(n).toISOString()})`:"shortly"}function Po(n,e=Date.now(),t){let s=$o(e);if(n)return null;let r=Yd(e,t);return r?{abort:!0,reason:"provider_rate_limit",message:`Claude plan limit reached: Claude Code reports the ${Co(r.window)} window as rejected. Cold dispatches are held until it resets ${Mo(r.resetsAt,e)}; open conversations still go through. To try again now, run: agentx usage plan --lift`,usage:s}:s.maxPerHour&&s.lastHour>=s.maxPerHour?{abort:!0,reason:"hourly_cap",message:`Local dispatch cap reached: ${s.lastHour}/${s.maxPerHour} claude-code runs in the last hour. Cold dispatches are held; open conversations still go through. Raise or remove session.maxClaudeCodeDispatchesPerHour in agentx.json (applies on save).`,usage:s}:s.maxPer5h&&s.last5h>=s.maxPer5h?{abort:!0,reason:"five_hour_cap",message:`Local dispatch cap reached: ${s.last5h}/${s.maxPer5h} claude-code runs in the last 5h. Cold dispatches are held; open conversations still go through. Raise or remove session.maxClaudeCodeDispatchesPer5h in agentx.json (applies on save).`,usage:s}:null}function _o(n=Date.now()){let e=$o(n),t=e.provider.find(r=>r.status==="allowed_warning");if(t){let r=t.utilization!==void 0?` (${Math.round(t.utilization*100)}% used)`:"";return`claude plan ${Co(t.window)} window nearing its limit${r}, resets ${Mo(t.resetsAt,n)}`}let s=Me.warnRatio??.8;return e.hourlyRatio!==void 0&&e.hourlyRatio>=s&&e.hourlyRatio<1?`claude-code hourly usage ${e.lastHour}/${e.maxPerHour} (${Math.round(e.hourlyRatio*100)}% of local cap)`:e.fiveHourRatio!==void 0&&e.fiveHourRatio>=s&&e.fiveHourRatio<1?`claude-code 5h usage ${e.last5h}/${e.maxPer5h} (${Math.round(e.fiveHourRatio*100)}% of local cap)`:null}var xn=new Map;function Ro(n,e,t){return t?`${n}:${e}:${t}`:`${n}:${e}`}function Eo(n,e,t,s=Date.now()){let r=xn.get(n);r||(r={key:n,samples:0,baseline:e,current:e,peak:e,lastAt:s,ring:[]},xn.set(n,r)),r.samples+=1,r.baseline=.2*e+(1-.2)*r.baseline,r.current=e,r.peak=Math.max(r.peak,e),r.lastAt=s,r.ring.push({key:n,timestamp:s,total:e,parts:t}),r.ring.length>100&&r.ring.shift()}function Do(n){let e=xn.get(n);if(!e||e.samples<5)return null;let t=e.baseline*1.5;if(e.current<t)return null;let s=e.current/e.baseline;return`prompt-size drift for ${n}: ${e.current} bytes is ${s.toFixed(2)}x baseline (${Math.round(e.baseline)} bytes over ${e.samples} samples, peak ${e.peak})`}import{existsSync as rc,readFileSync as oc}from"fs";import{resolve as ic}from"path";import{existsSync as Zd,readFileSync as ec,unlinkSync as tc,writeFileSync as nc}from"fs";import{resolve as No}from"path";var Oo="_agentxManaged";function Ct(n=process){let e=n.argv[1]?No(n.argv[1]):"";return/\.[cm]?js$/.test(e)?{type:"stdio",command:n.execPath,args:[e,"serve","--stdio","--cwd",n.cwd()]}:{type:"stdio",command:"agentx",args:["serve","--stdio","--cwd",n.cwd()]}}function Sg(n,e){return!e||n.agentx?n:{...n,agentx:e}}function Ig(n,e){let t=No(n,".mcp.json"),s=Zd(t),r=s?sc(t):null,o=r!==null&&r[Oo]===!0;if(s&&!o)return"skipped-operator-owned";let i=Object.keys(e).length>0;if(!i&&!s)return"noop";if(!i&&o)return tc(t),"removed";let a={[Oo]:!0,mcpServers:e};return nc(t,JSON.stringify(a,null,2)+`
79
- `),s?"updated":"installed"}function sc(n){try{return JSON.parse(ec(n,"utf-8"))}catch{return null}}var ac=["github","a2a","workflow","cron"],dc=["claude-code","codex-cli"],cc={mcpServers:["agentx"],settingSources:["project","local"],contextOnDemand:!0,tools:[],toolsByChannel:{},agentxTools:[],agentxToolsByChannel:{}},uc="AGENTX_MCP_TOOLS",lc=["agentx_approval","agentx_request","agentx_events","agentx_attach_next"],gc=["agentx_agents","agentx_recent","agentx_wiki_query"];function Fo(n,e){let t=e?n.toolsByChannel?.[e]:void 0,s=t&&t.length?t:n.tools??[];return Array.from(new Set(s.map(r=>r.trim()).filter(Boolean)))}function Uo(n,e){let t=e?n.agentxToolsByChannel?.[e]:void 0,s=(t&&t.length?t:n.agentxTools??[]).map(o=>o.trim()).filter(Boolean);if(!s.length)return[];let r=[...lc,...n.contextOnDemand?gc:[],...s];return Array.from(new Set(r))}function pc(n,e){return!e.length||n.type==="http"?n:{...n,env:{...n.env??{},[uc]:e.join(",")}}}function Ho(n,e,t){if(!dc.includes(t))return"full";let s=n?.profileByChannel?.[e];return s||(ac.includes(e)?"lean":"full")}function Bo(n){return{...cc,...n?.lean??{}}}function jo(n){return n.settingSources.includes("project")}function fc(n,e,t=Ct(),s){let r=qo(n),o={};for(let i of e.mcpServers)r[i]&&(o[i]=r[i]);return o.agentx=pc(o.agentx??r.agentx??t,Uo(e,s)),o}function qo(n){let e=ic(n,".mcp.json");if(!rc(e))return{};try{let s=JSON.parse(oc(e,"utf-8"))?.mcpServers;return s&&typeof s=="object"?s:{}}catch{return{}}}function Wo(n,e,t=Ct(),s){let r=fc(n,e,t,s),o=["--strict-mcp-config","--mcp-config",JSON.stringify({mcpServers:r}),"--setting-sources",e.settingSources.join(",")],i=Fo(e,s);return i.length&&o.push("--tools",Go(i).join(",")),o}var Lo="ToolSearch";function Go(n){return n.includes(Lo)?n:[...n,Lo]}function Ko(n,e=Ct()){let t=qo(n);return["--mcp-config",JSON.stringify({mcpServers:{agentx:t.agentx??e}})]}function Jo(n,e){return["[Context on demand]",`Not pushed into this prompt, fetch with agentx MCP tools when the task needs them: the agent landscape (agentx_agents with landscape=true), earlier messages on this chat (agentx_recent with channel="${n}", chatId="${e}"), today's other chats of yours (agentx_recent without chatId), and stored knowledge (agentx_wiki_query).`].join(`
80
- `)}function Qo(n,e,t){if(n==="full")return"full";let s=[`mcp=${e.mcpServers.join("+")||"agentx"}`,`settings=${e.settingSources.join(",")||"none"}`,e.contextOnDemand?"context=on-demand":"context=pushed"],r=Fo(e,t);r.length&&s.push(`tools=${Go(r).join("+")}`);let o=Uo(e,t);return o.length&&s.push(`agentx-tools=${o.length}`),`lean (${s.join(" ")})`}import{existsSync as ne,mkdirSync as uu,readdirSync as ae,readFileSync as Ye,rmSync as lu,writeFileSync as gu}from"fs";import{resolve as J}from"path";import{existsSync as xe,mkdirSync as Sn,readFileSync as mc,readdirSync as hc,renameSync as yc,unlinkSync as wc,writeFileSync as Mt}from"fs";import{resolve as fe,relative as Pt}from"path";import{z}from"zod";var be=z.object({id:z.string().regex(/^[a-z0-9][a-z0-9_-]*$/,"procedure id must be lower-kebab"),title:z.string().min(1),trigger:z.string().min(1,"procedures must describe when they apply"),inputs:z.array(z.string()).default([]),expected:z.string().optional(),kpis:z.array(z.string()).default([]),owner:z.string().optional(),tags:z.array(z.string()).default([]),status:z.enum(["draft","active","deprecated"]).default("active"),source:z.string().optional(),evidence:z.array(z.string()).default([]),created:z.string().optional(),updated:z.string().optional(),related:z.array(z.string()).default([])});function bc(n){let e=n.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);if(!e)return{meta:{},body:n};let t={};for(let s of e[1].split(`
81
- `)){let r=s.match(/^([a-zA-Z_][a-zA-Z0-9_]*):\s*(.*)$/);if(!r)continue;let o=r[1],i=r[2].trim();if(i.startsWith("[")&&i.endsWith("]")){try{t[o]=JSON.parse(i);continue}catch{}t[o]=i.slice(1,-1).split(",").map(a=>a.trim().replace(/^"(.*)"$/,"$1")).filter(Boolean);continue}i.startsWith('"')&&i.endsWith('"')&&(i=i.slice(1,-1)),t[o]=i}return{meta:t,body:e[2]}}function _t(n){let e=["---"];return e.push(`id: ${n.id}`),e.push(`title: "${n.title.replace(/"/g,'\\"')}"`),e.push(`trigger: "${n.trigger.replace(/"/g,'\\"')}"`),n.inputs?.length&&e.push(`inputs: ${JSON.stringify(n.inputs)}`),n.expected&&e.push(`expected: "${n.expected.replace(/"/g,'\\"')}"`),n.kpis?.length&&e.push(`kpis: ${JSON.stringify(n.kpis)}`),n.owner&&e.push(`owner: ${n.owner}`),n.tags?.length&&e.push(`tags: ${JSON.stringify(n.tags)}`),e.push(`status: ${n.status}`),n.source&&e.push(`source: "${n.source.replace(/"/g,'\\"')}"`),n.evidence?.length&&e.push(`evidence: ${JSON.stringify(n.evidence)}`),n.related?.length&&e.push(`related: ${JSON.stringify(n.related)}`),n.created&&e.push(`created: ${n.created}`),n.updated&&e.push(`updated: ${n.updated}`),e.push("---"),e.join(`
82
- `)}var ze=class{baseDir;constructor(e={}){this.baseDir=e.baseDir??fe(process.cwd(),".agentx/procedures"),Sn(this.baseDir,{recursive:!0})}pathFor(e){return fe(this.baseDir,`${e}.md`)}get draftsDir(){return fe(this.baseDir,"_drafts")}draftPathFor(e){return fe(this.draftsDir,`${e}.md`)}parseFile(e){let t=mc(e,"utf-8"),{meta:s,body:r}=bc(t),o=be.safeParse({...s,inputs:s.inputs||[],kpis:s.kpis||[],tags:s.tags||[],related:s.related||[],evidence:s.evidence||[]});return o.success?{meta:o.data,body:r.trim(),path:Pt(this.baseDir,e)}:null}listDir(e){if(!xe(e))return[];let t=[];for(let s of hc(e,{withFileTypes:!0})){if(!s.isFile()||!s.name.endsWith(".md")||s.name.startsWith("_"))continue;let r=this.parseFile(fe(e,s.name));r&&t.push(r)}return t.sort((s,r)=>s.meta.id.localeCompare(r.meta.id))}list(){return this.listDir(this.baseDir)}listDrafts(){return this.listDir(this.draftsDir)}get(e){let t=this.pathFor(e);return xe(t)?this.parseFile(t):null}getDraft(e){let t=this.draftPathFor(e);return xe(t)?this.parseFile(t):null}add(e,t){let s=be.parse({...e,created:e.created||new Date().toISOString().slice(0,10),updated:new Date().toISOString().slice(0,10)}),r=this.pathFor(s.id);if(xe(r))throw new Error(`Procedure already exists: ${s.id}`);return Mt(r,_t(s)+`
76
+ Agent: ${t.slice(0,1e3)}`}],{model:md,maxTokens:512})).content.trim().match(/\[[\s\S]*\]/);if(!c)return;let d=JSON.parse(c[0]);if(!(!Array.isArray(d)||d.length===0)){for(let u of d)r.hasSimilar(n,u.pattern)||r.addPattern(n,{agentId:n,pattern:u.pattern,context:u.context,confidence:u.confidence||.5,source:s});Math.random()<.05&&r.prune(n)}}import{EventEmitter as yd}from"events";var wd=2e4,yn=class{inner=new yd;envelopeListeners=new Set;ring=new Js;node="local";seen=new Map;constructor(){this.inner.setMaxListeners(50)}configure(e){return e.node&&(this.node=e.node),e.ringSize&&this.ring.resize(e.ringSize),this}on(e,t){return this.inner.on(e,t),this}off(e,t){return this.inner.off(e,t),this}emit(e,t){let s=this.inner.emit(e,t);try{this.publish(bd(e,t))}catch{}return s}publish(e){let t=Ks(),s=e.id??Gs(),r={id:s,rootId:e.rootId??t?.rootId??s,node:this.node,kind:e.kind,type:e.type,at:e.at??new Date().toISOString(),summary:Zt(e.summary)},o=e.parentId??t?.parentId;o&&(r.parentId=o),e.agentId&&(r.agentId=e.agentId),e.ref&&(r.ref=e.ref),this.ring.push(r);for(let i of this.envelopeListeners)try{i(r,e.data)}catch{}return r}get nodeName(){return this.node}isLocal(e){return e.node===this.node}ingest(e){if(!e.node||e.node===this.node)return!1;let t=`${e.node}:${e.id}`;if(this.seen.has(t))return!1;this.seen.set(t,!0),this.seen.size>wd&&this.seen.delete(this.seen.keys().next().value);let s={id:e.id,rootId:e.rootId||e.id,node:e.node,kind:e.kind,type:e.type,at:e.at,summary:Zt(e.summary??"")};e.parentId&&(s.parentId=e.parentId),e.agentId&&(s.agentId=e.agentId),e.ref&&(s.ref=e.ref),this.ring.push(s);for(let r of this.envelopeListeners)try{r(s)}catch{}return!0}hasRecent(e){return this.ring.has(e)}subscribe(e){return this.envelopeListeners.add(e),()=>{this.envelopeListeners.delete(e)}}recent(e){return this.ring.recent(e)}listenerCount(e){return this.inner.listenerCount(e)}removeAllListeners(){return this.inner.removeAllListeners(),this.envelopeListeners.clear(),this.ring.clear(),this.seen.clear(),this}};function bd(n,e){let t=e,s={type:n,at:t.at,agentId:t.agentId,ref:t.taskId};switch(n){case"message:matched":return{...s,kind:"message",ref:t.msgId,summary:`${t.channel} ${t.chatId} \u2192 ${t.agentId} (${t.decidingStage})`};case"message:dropped":return{...s,kind:"message",ref:t.msgId,summary:`${t.channel} ${t.chatId} dropped at ${t.decidingStage}: ${t.reason}`};case"task:queued":return{...s,kind:"agent",summary:`queued on ${t.channel} ${t.chatId}`};case"task:queue-flushed":return{...s,kind:"agent",summary:`${t.count} queued message(s) handed over on ${t.channel} ${t.chatId}`};case"task:queue-ended":return{...s,kind:"agent",summary:`queued turn ended on ${t.channel} ${t.chatId}`};case"task:started":return{...s,kind:"agent",summary:`started on ${t.channel} ${t.chatId}`};case"task:step":return{...s,kind:"agent",summary:[t.name,t.action,t.status].filter(Boolean).join(" ")};case"task:completed":return{...s,kind:"agent",summary:t.error?`failed after ${t.durationMs}ms: ${t.error}`:`completed in ${t.durationMs}ms`};case"session:rotated":return{...s,kind:"agent",summary:`session rotated (${t.reason})`};default:return{...s,kind:"agent",summary:String(n)}}}var hn;function Y(){return hn||(hn=new yn),hn}Wt();Wt();var po=["manual","notify","auto"];function xd(n){return typeof n=="string"&&po.includes(n)}var wn={claimTimeoutMs:9e4,staleSessionMs:15*6e4,maxDrainPerTurn:5,maxItemChars:4e3};var Sd=7*24*60*6e4,Je=class{constructor(e={},t){this.store=t;this.opts={...wn,...e};let s={};try{s=t?.load()??{}}catch{s={}}let r=Date.now()-Sd;for(let[o,i]of Object.entries(s))i&&Array.isArray(i.agentIds)&&(i.agentIds.length>0||i.watch)&&i.savedAt>=r&&this.saved.set(o,i)}sessions=new Map;items=new Map;waiters=new Map;saved=new Map;opts;options(){return this.opts}register(e,t={}){let s=t.now??Date.now(),r=this.sessions.get(e);if(r)return r.lastSeenAt=s,t.cwd&&(r.cwd=t.cwd),t.model&&(r.model=t.model),r;let o=this.saved.get(e),i={sessionId:e,cwd:t.cwd??o?.cwd??"",agentIds:o?o.agentIds.filter(a=>!this.sessionFor(a)):[],mode:o?.mode??"notify",lastSeenAt:s,registeredAt:s,model:t.model,drainedThisTurn:0};return o?.watch&&(i.watch={...o.watch}),this.sessions.set(e,i),o&&this.remember(i,s),i}touch(e,t=Date.now()){let s=this.sessions.get(e);return s?(s.lastSeenAt=t,s):this.saved.has(e)?this.register(e,{now:t}):void 0}get(e){return this.sessions.get(e)}list(){return[...this.sessions.values()].sort((e,t)=>t.lastSeenAt-e.lastSeenAt)}bind(e,t,s){let r=this.sessions.get(e);if(r){for(let o of this.sessions.values())o.sessionId!==e&&(o.agentIds=o.agentIds.filter(i=>i!==t));for(let[o,i]of this.saved)o!==e&&(i.agentIds=i.agentIds.filter(a=>a!==t));return r.agentIds.includes(t)||r.agentIds.push(t),s&&(r.mode=s),r.watch=void 0,this.remember(r),r}}unbind(e,t){let s=this.sessions.get(e);if(s)return s.agentIds=t?s.agentIds.filter(r=>r!==t):[],t||(s.watch=void 0),this.remember(s),s}watch(e,t,s=Date.now()){let r=this.sessions.get(e);if(r)return r.agentIds=[],r.awaitingAnswer=void 0,this.expireItemsOf(e,s,"session switched to watch mode"),r.watch={subscriptions:t.subscriptions,cursor:t.cursor,startedAt:s},this.remember(r,s),r}advanceWatch(e,t){let s=this.sessions.get(e);s?.watch&&(s.watch.cursor.id===t.id&&s.watch.cursor.at===t.at||(s.watch.cursor=t,this.remember(s)))}setMode(e,t){let s=this.sessions.get(e);if(s)return s.mode=t,this.remember(s),s}sessionFor(e){for(let t of this.sessions.values())if(t.agentIds.includes(e))return t}deregister(e,t=Date.now(),s={}){this.sessions.delete(e),s.forget&&this.saved.delete(e)&&this.persist(),this.expireItemsOf(e,t,"session ended")}expireItemsOf(e,t,s){for(let r of this.items.values())r.sessionId===e&&(r.state==="pending"||r.state==="claimed")&&this.settle(r,"expired",t,s)}offer(e,t=Date.now()){let s=this.sessionFor(e.agentId);if(!s)return null;if(t-s.lastSeenAt>this.opts.staleSessionMs)return this.deregister(s.sessionId,t),null;let r={id:Ie(t),agentId:e.agentId,sessionId:s.sessionId,state:"pending",text:Id(e.text,this.opts.maxItemChars),channel:e.channel,chatId:e.chatId,sender:e.sender,createdAt:t};return this.items.set(r.id,r),new Promise(o=>{this.waiters.set(r.id,{resolve:o})})}pending(e){return[...this.items.values()].filter(t=>t.sessionId===e&&t.state==="pending").sort((t,s)=>t.createdAt-s.createdAt)}pendingCount(e){let t=0;for(let s of this.items.values())s.sessionId===e&&s.state==="pending"&&t++;return t}claim(e,t=Date.now()){let s=this.sessions.get(e);if(!s||s.awaitingAnswer)return;let r=this.pending(e)[0];if(!(!r||r.state!=="pending"))return r.state="claimed",r.claimedAt=t,s.awaitingAnswer=r.id,s.lastSeenAt=t,s.drainedThisTurn++,r}answer(e,t,s=Date.now()){let r=this.sessions.get(e);if(!r?.awaitingAnswer)return;let o=this.items.get(r.awaitingAnswer);if(r.awaitingAnswer=void 0,!(!o||o.state!=="claimed"))return o.answer=t,this.settle(o,"answered",s),o}release(e,t=Date.now()){let s=this.sessions.get(e);if(!s?.awaitingAnswer)return;let r=this.items.get(s.awaitingAnswer);if(s.awaitingAnswer=void 0,!(!r||r.state!=="claimed"))return r.state="pending",r.claimedAt=void 0,s.lastSeenAt=t,r}expire(e,t,s=Date.now()){let r=this.items.get(e);if(!r||r.state!=="pending"&&r.state!=="claimed")return!1;let o=this.sessions.get(r.sessionId);return o?.awaitingAnswer===r.id&&(o.awaitingAnswer=void 0),this.settle(r,"expired",s,t),!0}sweep(e=Date.now()){let t=0;for(let s of this.items.values())s.state==="pending"&&e-s.createdAt>=this.opts.claimTimeoutMs?this.expire(s.id,"not claimed in time",e)&&t++:s.state==="claimed"&&e-(s.claimedAt??s.createdAt)>=this.opts.claimTimeoutMs&&this.expire(s.id,"claimed but never answered",e)&&t++;for(let s of this.sessions.values())e-s.lastSeenAt>this.opts.staleSessionMs&&this.deregister(s.sessionId,e);return t}endTurn(e){let t=this.sessions.get(e);t&&(t.drainedThisTurn=0)}savedBindings(){return Object.fromEntries(this.saved)}remember(e,t=Date.now()){if(e.agentIds.length===0&&!e.watch)this.saved.delete(e.sessionId);else{let s={agentIds:[...e.agentIds],mode:e.mode,cwd:e.cwd||void 0,savedAt:t};e.watch&&(s.watch={...e.watch}),this.saved.set(e.sessionId,s)}for(let[s,r]of this.saved)r.agentIds.length===0&&!r.watch&&this.saved.delete(s);this.persist()}persist(){try{this.store?.save(Object.fromEntries(this.saved))}catch{}}item(e){return this.items.get(e)}prune(e=Date.now(),t=36e5){let s=0;for(let[r,o]of this.items)(o.state==="answered"||o.state==="expired")&&e-(o.settledAt??o.createdAt)>t&&(this.items.delete(r),s++);return s}settle(e,t,s,r){e.state=t,e.settledAt=s;let o=this.waiters.get(e.id);o&&(this.waiters.delete(e.id),o.resolve(t==="answered"?{kind:"answered",text:e.answer??"",sessionId:e.sessionId}:{kind:"expired",reason:r??"expired"}))}};function Id(n,e){return n.length<=e?n:`${n.slice(0,e)}
77
+ \u2026[truncated ${n.length-e} chars]`}na();import{z as Td}from"zod";var mo=[{kinds:["task:completed"]},{kinds:["failed","timeout","completed"]},{kinds:["paused"],match:"checkpoint"},{kinds:["lost"]}];function vd(n){if(n==null)return{ok:!0,subscriptions:mo};let e=Td.array(ws).min(1).safeParse(n);if(!e.success){let t=e.error.issues[0];return{ok:!1,error:`invalid subscriptions: ${t?.path.join(".")||"value"} ${t?.message??""}`.trim()}}return{ok:!0,subscriptions:e.data}}var kd=15,Ad=1500,fo=200;function ho(n,e=Date.now()){let t=n[n.length-1];return t?{id:t.id,at:t.at}:{at:new Date(e).toISOString()}}function $d(n,e){if(e.id){let s=n.findIndex(r=>r.id===e.id);if(s>=0)return n.slice(s+1)}let t=Date.parse(e.at);return Number.isNaN(t)?n:e.id?n.filter(s=>Date.parse(s.at)>t):n.filter(s=>Date.parse(s.at)>=t)}function sg(n,e,t={}){let s=$d(e,n.cursor),r=s.length?ho(s):n.cursor,o=s.filter(d=>n.subscriptions.some(u=>Qs(u,d)));if(o.length===0)return{cursor:r,matched:0,shown:0};let i=n.cursor.id??n.cursor.at,{text:a,shown:c}=Cd(o,i,t);return{text:a,cursor:r,matched:o.length,shown:c}}function Cd(n,e,t={}){let s=Math.max(3,t.maxLines??kd),r=Math.max(200,t.maxChars??Ad),o=n.map(a=>Md(`- ${Xs(a)}`)),i=o.length;for(let a=Math.min(i,s-1);a>=0;a--){let c=i-a,u=[c?`[agentx watch] ${i} events since your last turn, newest ${a} shown:`:`[agentx watch] ${i} event${i===1?"":"s"} since your last turn:`,...o.slice(i-a)];c&&u.push(`+${c} more \u2014 \`agentx events --since ${e}\``);let l=u.join(`
78
+ `);if(u.length<=s&&l.length<=r)return{text:l,shown:a}}return{text:`[agentx watch] ${i} events since your last turn \u2014 \`agentx events --since ${e}\``,shown:0}}function Md(n){return n.length<=fo?n:`${n.slice(0,fo-1)}\u2026`}import{existsSync as Pd,mkdirSync as _d,readFileSync as Rd,renameSync as Ed,writeFileSync as Dd}from"node:fs";import{homedir as Od}from"node:os";import{dirname as Nd,join as Ld}from"node:path";function Fd(n){return{load:()=>Pd(n)?JSON.parse(Rd(n,"utf-8")):{},save:e=>{_d(Nd(n),{recursive:!0});let t=`${n}.tmp`;Dd(t,JSON.stringify(e,null,2),{mode:384}),Ed(t,n)}}}function Ud(){if(!process.env.VITEST)return Fd(process.env.AGENTX_ATTACH_BINDINGS_FILE??Ld(Od(),".agentx","attach-bindings.json"))}var bn;function yo(){return bn||(bn=new Je({},Ud())),bn}Gt();import{readFileSync as Hd}from"fs";import{homedir as Bd}from"os";import{join as jd}from"path";var Qe=null,qd=6e4;function Wd(){try{let n=jd(Bd(),".claude.json"),e=Hd(n,"utf8"),t=JSON.parse(e);return t&&typeof t=="object"?t:null}catch{return null}}function Gd(n,e=Date.now()){if(!n)return{available:!0,checkedAt:e,unknown:!0};let t=typeof n.cachedExtraUsageDisabledReason=="string"?n.cachedExtraUsageDisabledReason:void 0;return{available:!(t==="org_level_disabled_until"),reason:t,checkedAt:e}}function Kd(n=!1){let e=Date.now();return!n&&Qe&&e-Qe.checkedAt<qd||(Qe=Gd(Wd(),e)),Qe}function wo(n){let e=Kd();return e.available||n?null:{abort:!0,reason:e.reason||"overage_disabled",message:"Claude Max-plan overage is disabled at the org level and this agent has no warm Claude session to cache against. A cold dispatch would pay a fresh cache-create that spills past the regular allotment, producing 'out of extra usage'. Re-enable overage at claude.ai/settings/usage, OR wait until a peer agent has established a warm session this agent can inherit before retrying.",raw:e}}var xo={warnRatio:.8},Me={...xo},Jd=5*60*60*1e3,Qd=60*60*1e3,we=[];function So(n){Me={...xo,...n||{}}}function Io(n){let e=n-Jd,t=0;for(;t<we.length&&we[t]<e;)t++;t>0&&we.splice(0,t)}function To(n=Date.now()){Io(n),we.push(n)}var Pe=new Map,zd=15*60*1e3;function vo(n){if(typeof n=="number"&&Number.isFinite(n))return n;if(typeof n=="string"&&n.trim()!==""&&Number.isFinite(Number(n)))return Number(n)}function Xd(n){let e=vo(n);if(!(e===void 0||e<=0))return e<1e12?e*1e3:e}function Yd(n,e=Date.now()){if(!n||typeof n!="object")return null;let t=n;if(t.type!=="rate_limit_event")return null;let s=t.rate_limit_info??t.rateLimitInfo;if(!s||typeof s!="object")return null;let r=s.status;if(r!=="allowed"&&r!=="allowed_warning"&&r!=="rejected")return null;let o=String(s.rateLimitType??s.rate_limit_type??"unknown"),i=Xd(s.resetsAt??s.resets_at),a=vo(s.utilization),c=s.overageStatus??s.overage_status,d=r==="rejected"&&((s.isUsingOverage??s.is_using_overage)===!0||c==="allowed"||c==="allowed_warning");return{status:r,window:o,resetsAt:i,utilization:a,...d&&{usingOverage:d},seenAt:e}}function ko(n){return/_(opus|sonnet|haiku)$/.exec(n)?.[1]??null}function Ao(n,e){let t=ko(n);return!t||!e||e.toLowerCase().includes(t)}function xn(n,e=Date.now(),t){let s=Yd(n,e);if(!s)return null;if(s.status!=="rejected")for(let[r,o]of Pe)o.status!=="rejected"||r===s.window||(!ko(r)||t&&Ao(r,t))&&Pe.delete(r);return Pe.set(s.window,s),s}function $o(n=Date.now()){return[...Pe.values()].filter(e=>e.status!=="rejected"||e.usingOverage?!1:(e.resetsAt??e.seenAt+zd)>n)}function Vd(n=Date.now(),e){return $o(n).find(t=>Ao(t.window,e))??null}function yg(n=Date.now()){let e=$o(n);for(let t of e)Pe.delete(t.window);return e}function Zd(){return[...Pe.values()].sort((n,e)=>e.seenAt-n.seenAt)}function bo(n){return typeof n=="number"&&n>0}function Co(n=Date.now()){Io(n);let e=n-Qd,t=0;for(let o=we.length-1;o>=0&&we[o]>=e;o--)t++;let s=we.length,r={lastHour:t,last5h:s,maxPerHour:bo(Me.maxPerHour)?Me.maxPerHour:void 0,maxPer5h:bo(Me.maxPer5h)?Me.maxPer5h:void 0,provider:Zd()};return r.maxPerHour&&(r.hourlyRatio=t/r.maxPerHour),r.maxPer5h&&(r.fiveHourRatio=s/r.maxPer5h),r}function Mo(n){return n.replace(/_/g," ")}function Po(n,e){return n?`in about ${Math.max(1,Math.round((n-e)/6e4))} min (${new Date(n).toISOString()})`:"shortly"}function _o(n,e=Date.now(),t){let s=Co(e);if(n)return null;let r=Vd(e,t);return r?{abort:!0,reason:"provider_rate_limit",message:`Claude plan limit reached: Claude Code reports the ${Mo(r.window)} window as rejected. Cold dispatches are held until it resets ${Po(r.resetsAt,e)}; open conversations still go through. To try again now, run: agentx usage plan --lift`,usage:s}:s.maxPerHour&&s.lastHour>=s.maxPerHour?{abort:!0,reason:"hourly_cap",message:`Local dispatch cap reached: ${s.lastHour}/${s.maxPerHour} claude-code runs in the last hour. Cold dispatches are held; open conversations still go through. Raise or remove session.maxClaudeCodeDispatchesPerHour in agentx.json (applies on save).`,usage:s}:s.maxPer5h&&s.last5h>=s.maxPer5h?{abort:!0,reason:"five_hour_cap",message:`Local dispatch cap reached: ${s.last5h}/${s.maxPer5h} claude-code runs in the last 5h. Cold dispatches are held; open conversations still go through. Raise or remove session.maxClaudeCodeDispatchesPer5h in agentx.json (applies on save).`,usage:s}:null}function Ro(n=Date.now()){let e=Co(n),t=e.provider.find(r=>r.status==="allowed_warning");if(t){let r=t.utilization!==void 0?` (${Math.round(t.utilization*100)}% used)`:"";return`claude plan ${Mo(t.window)} window nearing its limit${r}, resets ${Po(t.resetsAt,n)}`}let s=Me.warnRatio??.8;return e.hourlyRatio!==void 0&&e.hourlyRatio>=s&&e.hourlyRatio<1?`claude-code hourly usage ${e.lastHour}/${e.maxPerHour} (${Math.round(e.hourlyRatio*100)}% of local cap)`:e.fiveHourRatio!==void 0&&e.fiveHourRatio>=s&&e.fiveHourRatio<1?`claude-code 5h usage ${e.last5h}/${e.maxPer5h} (${Math.round(e.fiveHourRatio*100)}% of local cap)`:null}var Sn=new Map;function Eo(n,e,t){return t?`${n}:${e}:${t}`:`${n}:${e}`}function Do(n,e,t,s=Date.now()){let r=Sn.get(n);r||(r={key:n,samples:0,baseline:e,current:e,peak:e,lastAt:s,ring:[]},Sn.set(n,r)),r.samples+=1,r.baseline=.2*e+(1-.2)*r.baseline,r.current=e,r.peak=Math.max(r.peak,e),r.lastAt=s,r.ring.push({key:n,timestamp:s,total:e,parts:t}),r.ring.length>100&&r.ring.shift()}function Oo(n){let e=Sn.get(n);if(!e||e.samples<5)return null;let t=e.baseline*1.5;if(e.current<t)return null;let s=e.current/e.baseline;return`prompt-size drift for ${n}: ${e.current} bytes is ${s.toFixed(2)}x baseline (${Math.round(e.baseline)} bytes over ${e.samples} samples, peak ${e.peak})`}import{existsSync as oc,readFileSync as ic}from"fs";import{resolve as ac}from"path";import{existsSync as ec,readFileSync as tc,unlinkSync as nc,writeFileSync as sc}from"fs";import{resolve as Lo}from"path";var No="_agentxManaged";function Mt(n=process){let e=n.argv[1]?Lo(n.argv[1]):"";return/\.[cm]?js$/.test(e)?{type:"stdio",command:n.execPath,args:[e,"serve","--stdio","--cwd",n.cwd()]}:{type:"stdio",command:"agentx",args:["serve","--stdio","--cwd",n.cwd()]}}function Ig(n,e){return!e||n.agentx?n:{...n,agentx:e}}function Tg(n,e){let t=Lo(n,".mcp.json"),s=ec(t),r=s?rc(t):null,o=r!==null&&r[No]===!0;if(s&&!o)return"skipped-operator-owned";let i=Object.keys(e).length>0;if(!i&&!s)return"noop";if(!i&&o)return nc(t),"removed";let a={[No]:!0,mcpServers:e};return sc(t,JSON.stringify(a,null,2)+`
79
+ `),s?"updated":"installed"}function rc(n){try{return JSON.parse(tc(n,"utf-8"))}catch{return null}}var dc=["github","a2a","workflow","cron"],cc=["claude-code","codex-cli"],uc={mcpServers:["agentx"],settingSources:["project","local"],contextOnDemand:!0,tools:[],toolsByChannel:{},agentxTools:[],agentxToolsByChannel:{}},lc="AGENTX_MCP_TOOLS",gc=["agentx_approval","agentx_request","agentx_events","agentx_attach_next"],pc=["agentx_agents","agentx_recent","agentx_wiki_query"];function Uo(n,e){let t=e?n.toolsByChannel?.[e]:void 0,s=t&&t.length?t:n.tools??[];return Array.from(new Set(s.map(r=>r.trim()).filter(Boolean)))}function Ho(n,e){let t=e?n.agentxToolsByChannel?.[e]:void 0,s=(t&&t.length?t:n.agentxTools??[]).map(o=>o.trim()).filter(Boolean);if(!s.length)return[];let r=[...gc,...n.contextOnDemand?pc:[],...s];return Array.from(new Set(r))}function fc(n,e){return!e.length||n.type==="http"?n:{...n,env:{...n.env??{},[lc]:e.join(",")}}}function Bo(n,e,t){if(!cc.includes(t))return"full";let s=n?.profileByChannel?.[e];return s||(dc.includes(e)?"lean":"full")}function jo(n){return{...uc,...n?.lean??{}}}function qo(n){return n.settingSources.includes("project")}function mc(n,e,t=Mt(),s){let r=Wo(n),o={};for(let i of e.mcpServers)r[i]&&(o[i]=r[i]);return o.agentx=fc(o.agentx??r.agentx??t,Ho(e,s)),o}function Wo(n){let e=ac(n,".mcp.json");if(!oc(e))return{};try{let s=JSON.parse(ic(e,"utf-8"))?.mcpServers;return s&&typeof s=="object"?s:{}}catch{return{}}}function Go(n,e,t=Mt(),s){let r=mc(n,e,t,s),o=["--strict-mcp-config","--mcp-config",JSON.stringify({mcpServers:r}),"--setting-sources",e.settingSources.join(",")],i=Uo(e,s);return i.length&&o.push("--tools",Ko(i).join(",")),o}var Fo="ToolSearch";function Ko(n){return n.includes(Fo)?n:[...n,Fo]}function Jo(n,e=Mt()){let t=Wo(n);return["--mcp-config",JSON.stringify({mcpServers:{agentx:t.agentx??e}})]}function Qo(n,e){return["[Context on demand]",`Not pushed into this prompt, fetch with agentx MCP tools when the task needs them: the agent landscape (agentx_agents with landscape=true), earlier messages on this chat (agentx_recent with channel="${n}", chatId="${e}"), today's other chats of yours (agentx_recent without chatId), and stored knowledge (agentx_wiki_query).`].join(`
80
+ `)}function zo(n,e,t){if(n==="full")return"full";let s=[`mcp=${e.mcpServers.join("+")||"agentx"}`,`settings=${e.settingSources.join(",")||"none"}`,e.contextOnDemand?"context=on-demand":"context=pushed"],r=Uo(e,t);r.length&&s.push(`tools=${Ko(r).join("+")}`);let o=Ho(e,t);return o.length&&s.push(`agentx-tools=${o.length}`),`lean (${s.join(" ")})`}import{existsSync as ne,mkdirSync as lu,readdirSync as ae,readFileSync as Ye,rmSync as gu,writeFileSync as pu}from"fs";import{resolve as J}from"path";import{existsSync as xe,mkdirSync as In,readFileSync as hc,readdirSync as yc,renameSync as wc,unlinkSync as bc,writeFileSync as Pt}from"fs";import{resolve as fe,relative as _t}from"path";import{z}from"zod";var be=z.object({id:z.string().regex(/^[a-z0-9][a-z0-9_-]*$/,"procedure id must be lower-kebab"),title:z.string().min(1),trigger:z.string().min(1,"procedures must describe when they apply"),inputs:z.array(z.string()).default([]),expected:z.string().optional(),kpis:z.array(z.string()).default([]),owner:z.string().optional(),tags:z.array(z.string()).default([]),status:z.enum(["draft","active","deprecated"]).default("active"),source:z.string().optional(),evidence:z.array(z.string()).default([]),created:z.string().optional(),updated:z.string().optional(),related:z.array(z.string()).default([])});function xc(n){let e=n.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);if(!e)return{meta:{},body:n};let t={};for(let s of e[1].split(`
81
+ `)){let r=s.match(/^([a-zA-Z_][a-zA-Z0-9_]*):\s*(.*)$/);if(!r)continue;let o=r[1],i=r[2].trim();if(i.startsWith("[")&&i.endsWith("]")){try{t[o]=JSON.parse(i);continue}catch{}t[o]=i.slice(1,-1).split(",").map(a=>a.trim().replace(/^"(.*)"$/,"$1")).filter(Boolean);continue}i.startsWith('"')&&i.endsWith('"')&&(i=i.slice(1,-1)),t[o]=i}return{meta:t,body:e[2]}}function Rt(n){let e=["---"];return e.push(`id: ${n.id}`),e.push(`title: "${n.title.replace(/"/g,'\\"')}"`),e.push(`trigger: "${n.trigger.replace(/"/g,'\\"')}"`),n.inputs?.length&&e.push(`inputs: ${JSON.stringify(n.inputs)}`),n.expected&&e.push(`expected: "${n.expected.replace(/"/g,'\\"')}"`),n.kpis?.length&&e.push(`kpis: ${JSON.stringify(n.kpis)}`),n.owner&&e.push(`owner: ${n.owner}`),n.tags?.length&&e.push(`tags: ${JSON.stringify(n.tags)}`),e.push(`status: ${n.status}`),n.source&&e.push(`source: "${n.source.replace(/"/g,'\\"')}"`),n.evidence?.length&&e.push(`evidence: ${JSON.stringify(n.evidence)}`),n.related?.length&&e.push(`related: ${JSON.stringify(n.related)}`),n.created&&e.push(`created: ${n.created}`),n.updated&&e.push(`updated: ${n.updated}`),e.push("---"),e.join(`
82
+ `)}var ze=class{baseDir;constructor(e={}){this.baseDir=e.baseDir??fe(process.cwd(),".agentx/procedures"),In(this.baseDir,{recursive:!0})}pathFor(e){return fe(this.baseDir,`${e}.md`)}get draftsDir(){return fe(this.baseDir,"_drafts")}draftPathFor(e){return fe(this.draftsDir,`${e}.md`)}parseFile(e){let t=hc(e,"utf-8"),{meta:s,body:r}=xc(t),o=be.safeParse({...s,inputs:s.inputs||[],kpis:s.kpis||[],tags:s.tags||[],related:s.related||[],evidence:s.evidence||[]});return o.success?{meta:o.data,body:r.trim(),path:_t(this.baseDir,e)}:null}listDir(e){if(!xe(e))return[];let t=[];for(let s of yc(e,{withFileTypes:!0})){if(!s.isFile()||!s.name.endsWith(".md")||s.name.startsWith("_"))continue;let r=this.parseFile(fe(e,s.name));r&&t.push(r)}return t.sort((s,r)=>s.meta.id.localeCompare(r.meta.id))}list(){return this.listDir(this.baseDir)}listDrafts(){return this.listDir(this.draftsDir)}get(e){let t=this.pathFor(e);return xe(t)?this.parseFile(t):null}getDraft(e){let t=this.draftPathFor(e);return xe(t)?this.parseFile(t):null}add(e,t){let s=be.parse({...e,created:e.created||new Date().toISOString().slice(0,10),updated:new Date().toISOString().slice(0,10)}),r=this.pathFor(s.id);if(xe(r))throw new Error(`Procedure already exists: ${s.id}`);return Pt(r,Rt(s)+`
83
83
 
84
84
  `+t.trim()+`
85
- `),{meta:s,body:t.trim(),path:Pt(this.baseDir,r)}}update(e,t,s){let r=this.get(e);if(!r)throw new Error(`Procedure not found: ${e}`);let o=be.parse({...r.meta,...t,id:r.meta.id,updated:new Date().toISOString().slice(0,10)}),i=s!==void 0?s:r.body;return Mt(this.pathFor(e),_t(o)+`
85
+ `),{meta:s,body:t.trim(),path:_t(this.baseDir,r)}}update(e,t,s){let r=this.get(e);if(!r)throw new Error(`Procedure not found: ${e}`);let o=be.parse({...r.meta,...t,id:r.meta.id,updated:new Date().toISOString().slice(0,10)}),i=s!==void 0?s:r.body;return Pt(this.pathFor(e),Rt(o)+`
86
86
 
87
87
  `+i.trim()+`
88
- `),{meta:o,body:i.trim(),path:r.path}}addDraft(e,t){let s=be.parse({...e,status:"draft",created:e.created||new Date().toISOString().slice(0,10),updated:new Date().toISOString().slice(0,10)});if(this.get(s.id))throw new Error(`Procedure already exists: ${s.id}`);let r=this.draftPathFor(s.id);if(xe(r))throw new Error(`Draft already exists: ${s.id}`);return Sn(this.draftsDir,{recursive:!0}),Mt(r,_t(s)+`
88
+ `),{meta:o,body:i.trim(),path:r.path}}addDraft(e,t){let s=be.parse({...e,status:"draft",created:e.created||new Date().toISOString().slice(0,10),updated:new Date().toISOString().slice(0,10)});if(this.get(s.id))throw new Error(`Procedure already exists: ${s.id}`);let r=this.draftPathFor(s.id);if(xe(r))throw new Error(`Draft already exists: ${s.id}`);return In(this.draftsDir,{recursive:!0}),Pt(r,Rt(s)+`
89
89
 
90
90
  `+t.trim()+`
91
- `),{meta:s,body:t.trim(),path:Pt(this.baseDir,r)}}promoteDraft(e){let t=this.getDraft(e);if(!t)throw new Error(`Draft not found: ${e}`);if(this.get(e))throw new Error(`Procedure already exists: ${e}`);let s=be.parse({...t.meta,status:"active",updated:new Date().toISOString().slice(0,10)});return Mt(this.pathFor(e),_t(s)+`
91
+ `),{meta:s,body:t.trim(),path:_t(this.baseDir,r)}}promoteDraft(e){let t=this.getDraft(e);if(!t)throw new Error(`Draft not found: ${e}`);if(this.get(e))throw new Error(`Procedure already exists: ${e}`);let s=be.parse({...t.meta,status:"active",updated:new Date().toISOString().slice(0,10)});return Pt(this.pathFor(e),Rt(s)+`
92
92
 
93
93
  `+t.body+`
94
- `),wc(this.draftPathFor(e)),{meta:s,body:t.body,path:Pt(this.baseDir,this.pathFor(e))}}rejectDraft(e){let t=this.draftPathFor(e);if(!xe(t))throw new Error(`Draft not found: ${e}`);let s=fe(this.draftsDir,"_rejected");Sn(s,{recursive:!0}),yc(t,fe(s,`${e}.md`))}isRejected(e){return xe(fe(this.draftsDir,"_rejected",`${e}.md`))}deprecate(e){return this.update(e,{status:"deprecated"})}};import{existsSync as xc,mkdirSync as Sc,readFileSync as Ic,writeFileSync as Tc}from"fs";import{dirname as vc,resolve as kc}from"path";import{z as Z}from"zod";var Ac=Z.object({key:Z.string(),count:Z.number().int().min(0).default(0),firstSeen:Z.string(),lastSeen:Z.string(),taskIds:Z.array(Z.string()).default([]),sampleMessage:Z.string().default(""),status:Z.enum(["counting","drafted","promoted","rejected"]).default("counting"),procedureId:Z.string().optional()}),$c=Z.object({minedThrough:Z.string().optional(),candidates:Z.array(Ac).default([])});function zo(n){return kc(n,"_candidates.json")}function Cc(n){let e=zo(n);if(!xc(e))return{candidates:[]};try{let t=$c.safeParse(JSON.parse(Ic(e,"utf-8")));if(t.success)return t.data}catch{}return{candidates:[]}}function Mc(n,e){let t=zo(n);Sc(vc(t),{recursive:!0}),Tc(t,JSON.stringify(e,null,2)+`
95
- `)}function Pc(n,e,t,s,r){let o=n.candidates.find(i=>i.key===e);return o||(o={key:e,count:0,firstSeen:s,lastSeen:s,taskIds:[],sampleMessage:r,status:"counting"},n.candidates.push(o)),o.taskIds.includes(t)||(o.taskIds.push(t),o.count+=1,s<o.firstSeen&&(o.firstSeen=s),s>o.lastSeen&&(o.lastSeen=s),o.sampleMessage||(o.sampleMessage=r)),o}function _c(n,e){return n.candidates.filter(t=>t.status==="counting"&&t.count>=e).sort((t,s)=>s.count-t.count)}function Rc(n,e,t,s){let r=n.candidates.find(o=>o.key===e);r&&(r.status=t,s&&(r.procedureId=s))}function In(n){return new Set(n.toLowerCase().replace(/[^a-z0-9\s]/g," ").split(/\s+/).filter(e=>e.length>3))}function Xo(n,e){if(n.size===0||e.size===0)return 0;let t=0;for(let s of n)e.has(s)&&t++;return t/Math.max(n.size,e.size)}function Tn(n,e,t={}){let s=Math.max(1,t.limit??3),r=t.minScore??.2,o=In(n),i=[];for(let a of e){if(a.meta.status!=="active")continue;let c=[],d=Xo(o,In(a.meta.trigger));d>0&&c.push("trigger");let u=[a.meta.id,a.meta.title,...a.meta.tags,...a.meta.inputs].join(" "),l=Xo(o,In(u));l>0&&c.push("title/tags");let f=Math.min(1,d*.7+l*.5);f>=r&&i.push({procedure:a,score:f,reasons:c})}return i.sort((a,c)=>c.score-a.score).slice(0,s)}function vn(n){return["The user's request matches an established procedure. Follow its steps unless the user asks otherwise \u2014 they encode the known-good path.",...n.map(t=>{let s=t.procedure,r=[`[Known procedure: ${s.meta.title}]`,s.meta.trigger];return s.meta.inputs.length&&r.push(`Inputs: ${s.meta.inputs.join(", ")}`),r.push(s.body),s.meta.expected&&r.push(`Done when: ${s.meta.expected}`),r.push(`(details: agentx procedure show ${s.meta.id})`),r.join(`
94
+ `),bc(this.draftPathFor(e)),{meta:s,body:t.body,path:_t(this.baseDir,this.pathFor(e))}}rejectDraft(e){let t=this.draftPathFor(e);if(!xe(t))throw new Error(`Draft not found: ${e}`);let s=fe(this.draftsDir,"_rejected");In(s,{recursive:!0}),wc(t,fe(s,`${e}.md`))}isRejected(e){return xe(fe(this.draftsDir,"_rejected",`${e}.md`))}deprecate(e){return this.update(e,{status:"deprecated"})}};import{existsSync as Sc,mkdirSync as Ic,readFileSync as Tc,writeFileSync as vc}from"fs";import{dirname as kc,resolve as Ac}from"path";import{z as Z}from"zod";var $c=Z.object({key:Z.string(),count:Z.number().int().min(0).default(0),firstSeen:Z.string(),lastSeen:Z.string(),taskIds:Z.array(Z.string()).default([]),sampleMessage:Z.string().default(""),status:Z.enum(["counting","drafted","promoted","rejected"]).default("counting"),procedureId:Z.string().optional()}),Cc=Z.object({minedThrough:Z.string().optional(),candidates:Z.array($c).default([])});function Xo(n){return Ac(n,"_candidates.json")}function Mc(n){let e=Xo(n);if(!Sc(e))return{candidates:[]};try{let t=Cc.safeParse(JSON.parse(Tc(e,"utf-8")));if(t.success)return t.data}catch{}return{candidates:[]}}function Pc(n,e){let t=Xo(n);Ic(kc(t),{recursive:!0}),vc(t,JSON.stringify(e,null,2)+`
95
+ `)}function _c(n,e,t,s,r){let o=n.candidates.find(i=>i.key===e);return o||(o={key:e,count:0,firstSeen:s,lastSeen:s,taskIds:[],sampleMessage:r,status:"counting"},n.candidates.push(o)),o.taskIds.includes(t)||(o.taskIds.push(t),o.count+=1,s<o.firstSeen&&(o.firstSeen=s),s>o.lastSeen&&(o.lastSeen=s),o.sampleMessage||(o.sampleMessage=r)),o}function Rc(n,e){return n.candidates.filter(t=>t.status==="counting"&&t.count>=e).sort((t,s)=>s.count-t.count)}function Ec(n,e,t,s){let r=n.candidates.find(o=>o.key===e);r&&(r.status=t,s&&(r.procedureId=s))}function Tn(n){return new Set(n.toLowerCase().replace(/[^a-z0-9\s]/g," ").split(/\s+/).filter(e=>e.length>3))}function Yo(n,e){if(n.size===0||e.size===0)return 0;let t=0;for(let s of n)e.has(s)&&t++;return t/Math.max(n.size,e.size)}function vn(n,e,t={}){let s=Math.max(1,t.limit??3),r=t.minScore??.2,o=Tn(n),i=[];for(let a of e){if(a.meta.status!=="active")continue;let c=[],d=Yo(o,Tn(a.meta.trigger));d>0&&c.push("trigger");let u=[a.meta.id,a.meta.title,...a.meta.tags,...a.meta.inputs].join(" "),l=Yo(o,Tn(u));l>0&&c.push("title/tags");let f=Math.min(1,d*.7+l*.5);f>=r&&i.push({procedure:a,score:f,reasons:c})}return i.sort((a,c)=>c.score-a.score).slice(0,s)}function kn(n){return["The user's request matches an established procedure. Follow its steps unless the user asks otherwise \u2014 they encode the known-good path.",...n.map(t=>{let s=t.procedure,r=[`[Known procedure: ${s.meta.title}]`,s.meta.trigger];return s.meta.inputs.length&&r.push(`Inputs: ${s.meta.inputs.join(", ")}`),r.push(s.body),s.meta.expected&&r.push(`Done when: ${s.meta.expected}`),r.push(`(details: agentx procedure show ${s.meta.id})`),r.join(`
96
96
  `)})].join(`
97
97
 
98
- `)}zt();ut();var An="turn-progress",Yo={progress:Te({progressing:"Recent steps move the task forward: new files, commands or checks, results that differ from earlier ones, or a long step whose output shows it advancing.",looping:"The agent repeats the same or near-identical step (same command, same check, same edit retried with small tweaks) and gets the same failure or result each time.",blocked:"Progress depends on something the agent cannot change from here: missing access or credentials, a service that is down, or a decision only the user can make."},"How the agent's current turn is going, judged from its most recent steps.")},kn=(n,e)=>n.length>e?`${n.slice(0,e)}\u2026`:n;function Vo(n){return{agent:n.agent,request:kn(n.request,1500),elapsedMinutes:Math.round(n.elapsedMinutes),budgetMinutes:n.budgetMinutes,trigger:n.trigger,recentSteps:n.steps.map(e=>({tool:e.tool,input:kn(e.input,300),...e.result!==void 0?{result:kn(e.result,300)}:{},...e.error?{failed:!0}:{}})),...n.repeated?{mostRepeatedCall:n.repeated}:{}}}ut();var Zo="turn-handoff",ei="approval-binding",ti={nextStep:Te({proceed:"The question asks permission for a local, reversible next step that is already inside what the user asked for, such as writing or testing code in the working copy, reading, or running checks.",ask_outward:"The next step changes something outside the working copy or is hard to undo: pushing, publishing, merging, deploying, deleting, spending money, or messaging someone other than the user.",ask_ambiguous:"The agent cannot tell what the user wants: several different goals are plausible, or the user must choose between options with different results."},"What the agent should do with the question it ended its turn on.")},ni={approves:Fe("The user's message approves the plan or step the agent proposed at the end of its previous reply.",{true:'The message accepts the proposal, including terse replies such as "yes", "go ahead" or "ok do it", possibly with small additions that do not change the plan.',false:"The message declines, changes the plan, asks something new, or answers a different question than the one the agent asked."})},Ec=(n,e)=>n.length>e?`${n.slice(0,e)}\u2026`:n,si=(n,e)=>n.length>e?`\u2026${n.slice(-e)}`:n,Dc=/(should i|want me to|shall i|do you want|which (one|option|task)|let me know)[^\n]*$/i;function $n(n){let e=n.trim();return e?/\?\s*(\*\*)?\s*$/.test(e)?!0:Dc.test(e.split(`
99
- `).slice(-3).join(" ")):!1}var Oc=/^\s*(yes|yep|yeah|ok(ay)?|sure|go( ahead)?|proceed|do it|please do|confirmed?|approved?|go-ahead|let'?s go|oui|نعم)\b/i;function ri(n){return n.trim().length<=160&&Oc.test(n)}function oi(n){return n.trim().length<=160}function ii(n){return{agent:n.agent,channel:n.channel,request:Ec(n.request,1500),agentReplyEnding:si(n.reply,1200)}}function ai(n){return{agent:n.agent,channel:n.channel,userMessage:n.message,agentPreviousReplyEnding:si(n.previousReply,1200)}}var Nc=5*6e4,Lc=3,Fc=12,Uc=24*60*6e4,di=new Set(["cron","heartbeat","bench","a2a","business"]),Hc={observe(){},stop(){}};function ci(n){if(lt(An)==="off")return Hc;let e=n.now??Date.now,t=e(),s=[],r=new Map,o=new Map,i=new Set,a=0,c=!1,d=()=>{let f;for(let[h,p]of o)p>1&&(!f||p>f.times)&&(f={call:h,times:p});return f},u=f=>{if(c)return;c=!0,a=s.length;let h=Vo({agent:n.agent,request:n.request,elapsedMinutes:(e()-t)/6e4,budgetMinutes:n.budgetMinutes,steps:s.slice(-Fc),repeated:d(),trigger:f});ue(An,h,Yo,{links:[{kind:"task",id:n.taskId}],features:{agent:n.agent,trigger:f}}).finally(()=>{c=!1})},l=setInterval(()=>{s.length>a&&u("checkpoint")},n.checkpointMs??Nc);return l.unref?.(),{observe(f){let h=Array.isArray(f?.message?.content)?f.message.content:[];if(f?.type==="assistant")for(let p of h){if(p?.type!=="tool_use")continue;let I=p.input?JSON.stringify(p.input):"",A={tool:p.name||"tool",input:I};s.push(A),typeof p.id=="string"&&r.set(p.id,A);let b=`${A.tool}(${I})`,R=(o.get(b)??0)+1;o.set(b,R),R>=Lc&&!i.has(b)&&(i.add(b),u("repetition"))}else if(f?.type==="user")for(let p of h){if(p?.type!=="tool_result")continue;let I=r.get(p.tool_use_id);I&&(I.result=Array.isArray(p.content)?p.content.map(A=>typeof A?.text=="string"?A.text:"").join(""):typeof p.content=="string"?p.content:"",p.is_error&&(I.error=!0))}},stop(){clearInterval(l)}}}var Cn=new Map,ui=(n,e,t)=>`${n}\0${e}\0${t}`;function li(n){if(di.has(n.channel)||!$n(n.reply))return;let e=ui(n.agent,n.channel,n.chatId);ue(Zo,ii(n),ti,{links:[{kind:"task",id:n.taskId}],features:{agent:n.agent,channel:n.channel}}).then(t=>{t?.callId&&Cn.set(e,{callId:t.callId,at:Date.now()})})}function gi(n){if(di.has(n.channel))return;let e=ui(n.agent,n.channel,n.chatId),t=Cn.get(e);if(t){Cn.delete(e);let s=ws().store;if(s&&Date.now()-t.at<Uc)try{s.label(t.callId,"userReply",ri(n.message)?"approved":"redirected",{kind:"outcome",labeledBy:"next-user-message"})}catch{}}!n.previousReply||!oi(n.message)||!$n(n.previousReply)||ue(ei,ai({agent:n.agent,channel:n.channel,message:n.message,previousReply:n.previousReply}),ni,{links:[{kind:"task",id:n.taskId}],features:{agent:n.agent,channel:n.channel}})}Yi();Zi();ea();hs();function pi(n,e,t=0){return new Promise((s,r)=>{let o,i=()=>{o=setTimeout(()=>r(Xe(e)),t)},a=()=>{e.removeEventListener("abort",i),o&&clearTimeout(o)};n.then(c=>{a(),s(c)},c=>{a(),r(c)}),e.aborted?i():e.addEventListener("abort",i,{once:!0})})}function Xe(n){let e=n.reason;return e instanceof Error?e:new Error(typeof e=="string"?e:"task cancelled")}var _e=class extends Error{constructor(t,s){super(`step "${t}" exceeded its ${Math.round(s/1e3)}s budget`);this.step=t;this.budgetMs=s;this.name="StepBudgetExceeded"}};function fi(n,e,t){return e>0?new Promise((s,r)=>{let o=setTimeout(()=>r(new _e(t,e)),e);o.unref?.(),n.then(i=>{clearTimeout(o),s(i)},i=>{clearTimeout(o),r(i)})}):n}import{execFileSync as Bc,spawn as jc}from"child_process";import{existsSync as qc,mkdirSync as Wc,readFileSync as Gc,renameSync as Kc,writeFileSync as Jc}from"fs";import{dirname as Qc}from"path";var Et={enabled:!1,maxPerDay:0,openHours:24,launchTimeoutSeconds:120};function zc(n){if(!n)return;let t=n.trim().match(/^(?:(?:https?|ssh|git)(?::\/\/)(?:[^@\/]+@)?|git@|)(?:www\.)?github\.com[\/:]([^\/\s]+)\/([^\/\s]+?)(?:\.git)?\/?$/i);if(t)return`${t[1]}/${t[2]}`}function Xc(n){try{return!n||!qc(n)?void 0:Bc("git",["-C",n,"remote","get-url","origin"],{encoding:"utf8",stdio:["ignore","pipe","ignore"],timeout:5e3}).trim()||void 0}catch{return}}function Mn(n){if(!n)return;let e=n.split(":");if(e.length<3)return;let t=Number(e[e.length-1]),s=e[e.length-2],r=e.slice(0,-2).join(":");if(!(!Number.isInteger(t)||t<=0)&&!(s!=="issue"&&s!=="pull")&&/^[^\/\s]+\/[^\/\s]+$/.test(r))return{repo:r,kind:s,number:t}}function mi(n){let e={...Et,...n.agent.cloudSessions??{}};if(!e.enabled)return{route:"local",reason:"cloud sessions are off for this agent"};let t=n.context?.channel;if(t!=="github")return{route:"local",reason:`channel "${t||"api"}" does not send tasks to the cloud (GitHub only)`};if(!n.channelEnabled)return{route:"local",reason:"cloud sessions are off for the github channel"};if(n.agent.tier!=="claude-code")return{route:"local",reason:`agent tier "${n.agent.tier}" cannot run cloud sessions (claude-code only)`};let s=Mn(n.context?.chatId);if(!s)return{route:"local",reason:`task is not for a GitHub issue or pull request (chat "${n.context?.chatId||""}")`};if(n.openSession)return{route:"follow-up",session:n.openSession};if(e.maxPerDay>0&&(n.launchesToday??0)>=e.maxPerDay)return{route:"local",reason:`daily cap of ${e.maxPerDay} cloud launches reached`};let r=n.remoteOf??Xc,o=[n.context?.runbookPath,n.agent.workspace].filter(a=>!!a),i=s.repo.toLowerCase();for(let a of o){let c=zc(r(a));if(c&&c.toLowerCase()===i)return{route:"cloud",repo:s.repo,kind:s.kind,number:s.number,cwd:a}}return{route:"local",reason:`no checkout of ${s.repo} on this node (looked in ${o.join(", ")||"nothing"}); set the project rule's runbook path to a clone whose origin is github.com/${s.repo}`}}var Yc=24*60*60*1e3,Vc=7*Yc,Rt=class{constructor(e){this.file=e}sessions=[];loaded=!1;load(){if(!this.loaded){this.loaded=!0;try{let e=JSON.parse(Gc(this.file,"utf8")),t=Array.isArray(e?.sessions)?e.sessions:[];this.sessions=t.filter(s=>s&&typeof s.repo=="string"&&typeof s.sessionId=="string"&&Number.isFinite(s.startedAt))}catch{this.sessions=[]}}}save(){let e=Date.now();this.sessions=this.sessions.filter(t=>e-t.startedAt<Vc);try{Wc(Qc(this.file),{recursive:!0});let t=`${this.file}.${process.pid}.tmp`;Jc(t,JSON.stringify({sessions:this.sessions},null,2)),Kc(t,this.file)}catch{}}open(e,t,s,r=Date.now()){this.load();let o=e.toLowerCase();return this.sessions.find(i=>i.repo.toLowerCase()===o&&i.number===t&&r-i.startedAt<s*60*60*1e3)}record(e){this.load(),this.sessions=this.sessions.filter(t=>!(t.repo.toLowerCase()===e.repo.toLowerCase()&&t.number===e.number)),this.sessions.push(e),this.save()}touch(e,t=Date.now()){this.load();let s=this.sessions.find(r=>r.sessionId===e);s&&(s.lastMessageAt=t,this.save())}close(e,t){this.load();let s=this.sessions.length;return this.sessions=this.sessions.filter(r=>!(r.repo.toLowerCase()===e.toLowerCase()&&r.number===t)),this.sessions.length===s?!1:(this.save(),!0)}launchesToday(e,t=Date.now()){this.load();let s=new Date(t);return s.setHours(0,0,0,0),this.sessions.filter(r=>r.agentId===e&&r.startedAt>=s.getTime()&&r.startedAt<=t).length}all(){return this.load(),[...this.sessions]}},Zc=["import os, pty, sys","status = pty.spawn(sys.argv[1:])","sys.exit(os.waitstatus_to_exitcode(status) if isinstance(status, int) else 0)"].join(`
100
- `);function eu(n,e){return e?["-p",n,"--cloud",e]:["--cloud",n]}var tu=/\x1b\[[0-9;?]*[ -\/]*[@-~]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\x1b[()][AB012]|\r/g;function hi(n){return n.replace(tu,"")}function nu(n){let e=hi(n),t=e.match(/https:\/\/claude\.ai\/code\/[A-Za-z0-9_\-]+(?:\/[A-Za-z0-9_\-]+)*/)?.[0],s=e.match(/\bsession_[A-Za-z0-9]{6,}\b/)?.[0];if(!s&&t){let r=t.split("/").filter(Boolean).pop();r&&r!=="code"&&(s=r)}return{sessionId:s,url:t}}async function yi(n){let e=n.spawn??((c,d,u)=>jc(c,d,u)),t=n.python??"python3",s=["-c",Zc,"claude",...eu(n.prompt,n.sessionId)],r={...n.env,NO_COLOR:"1",FORCE_COLOR:"0"},o="",i=c=>{o+=c.toString(),o.length>64e3&&(o=o.slice(-64e3))},a=()=>hi(o).trim().split(`
98
+ `)}Xt();lt();var $n="turn-progress",Vo={progress:Te({progressing:"Recent steps move the task forward: new files, commands or checks, results that differ from earlier ones, or a long step whose output shows it advancing.",looping:"The agent repeats the same or near-identical step (same command, same check, same edit retried with small tweaks) and gets the same failure or result each time.",blocked:"Progress depends on something the agent cannot change from here: missing access or credentials, a service that is down, or a decision only the user can make."},"How the agent's current turn is going, judged from its most recent steps.")},An=(n,e)=>n.length>e?`${n.slice(0,e)}\u2026`:n;function Zo(n){return{agent:n.agent,request:An(n.request,1500),elapsedMinutes:Math.round(n.elapsedMinutes),budgetMinutes:n.budgetMinutes,trigger:n.trigger,recentSteps:n.steps.map(e=>({tool:e.tool,input:An(e.input,300),...e.result!==void 0?{result:An(e.result,300)}:{},...e.error?{failed:!0}:{}})),...n.repeated?{mostRepeatedCall:n.repeated}:{}}}lt();var ei="turn-handoff",ti="approval-binding",ni={nextStep:Te({proceed:"The question asks permission for a local, reversible next step that is already inside what the user asked for, such as writing or testing code in the working copy, reading, or running checks.",ask_outward:"The next step changes something outside the working copy or is hard to undo: pushing, publishing, merging, deploying, deleting, spending money, or messaging someone other than the user.",ask_ambiguous:"The agent cannot tell what the user wants: several different goals are plausible, or the user must choose between options with different results."},"What the agent should do with the question it ended its turn on.")},si={approves:Fe("The user's message approves the plan or step the agent proposed at the end of its previous reply.",{true:'The message accepts the proposal, including terse replies such as "yes", "go ahead" or "ok do it", possibly with small additions that do not change the plan.',false:"The message declines, changes the plan, asks something new, or answers a different question than the one the agent asked."})},Dc=(n,e)=>n.length>e?`${n.slice(0,e)}\u2026`:n,ri=(n,e)=>n.length>e?`\u2026${n.slice(-e)}`:n,Oc=/(should i|want me to|shall i|do you want|which (one|option|task)|let me know)[^\n]*$/i;function Cn(n){let e=n.trim();return e?/\?\s*(\*\*)?\s*$/.test(e)?!0:Oc.test(e.split(`
99
+ `).slice(-3).join(" ")):!1}var Nc=/^\s*(yes|yep|yeah|ok(ay)?|sure|go( ahead)?|proceed|do it|please do|confirmed?|approved?|go-ahead|let'?s go|oui|نعم)\b/i;function oi(n){return n.trim().length<=160&&Nc.test(n)}function ii(n){return n.trim().length<=160}function ai(n){return{agent:n.agent,channel:n.channel,request:Dc(n.request,1500),agentReplyEnding:ri(n.reply,1200)}}function di(n){return{agent:n.agent,channel:n.channel,userMessage:n.message,agentPreviousReplyEnding:ri(n.previousReply,1200)}}var Lc=5*6e4,Fc=3,Uc=12,Hc=24*60*6e4,ci=new Set(["cron","heartbeat","bench","a2a","business"]),Bc={observe(){},stop(){}};function ui(n){if(gt($n)==="off")return Bc;let e=n.now??Date.now,t=e(),s=[],r=new Map,o=new Map,i=new Set,a=0,c=!1,d=()=>{let f;for(let[h,p]of o)p>1&&(!f||p>f.times)&&(f={call:h,times:p});return f},u=f=>{if(c)return;c=!0,a=s.length;let h=Zo({agent:n.agent,request:n.request,elapsedMinutes:(e()-t)/6e4,budgetMinutes:n.budgetMinutes,steps:s.slice(-Uc),repeated:d(),trigger:f});ue($n,h,Vo,{links:[{kind:"task",id:n.taskId}],features:{agent:n.agent,trigger:f}}).finally(()=>{c=!1})},l=setInterval(()=>{s.length>a&&u("checkpoint")},n.checkpointMs??Lc);return l.unref?.(),{observe(f){let h=Array.isArray(f?.message?.content)?f.message.content:[];if(f?.type==="assistant")for(let p of h){if(p?.type!=="tool_use")continue;let I=p.input?JSON.stringify(p.input):"",A={tool:p.name||"tool",input:I};s.push(A),typeof p.id=="string"&&r.set(p.id,A);let b=`${A.tool}(${I})`,R=(o.get(b)??0)+1;o.set(b,R),R>=Fc&&!i.has(b)&&(i.add(b),u("repetition"))}else if(f?.type==="user")for(let p of h){if(p?.type!=="tool_result")continue;let I=r.get(p.tool_use_id);I&&(I.result=Array.isArray(p.content)?p.content.map(A=>typeof A?.text=="string"?A.text:"").join(""):typeof p.content=="string"?p.content:"",p.is_error&&(I.error=!0))}},stop(){clearInterval(l)}}}var Mn=new Map,li=(n,e,t)=>`${n}\0${e}\0${t}`;function gi(n){if(ci.has(n.channel)||!Cn(n.reply))return;let e=li(n.agent,n.channel,n.chatId);ue(ei,ai(n),ni,{links:[{kind:"task",id:n.taskId}],features:{agent:n.agent,channel:n.channel}}).then(t=>{t?.callId&&Mn.set(e,{callId:t.callId,at:Date.now()})})}function pi(n){if(ci.has(n.channel))return;let e=li(n.agent,n.channel,n.chatId),t=Mn.get(e);if(t){Mn.delete(e);let s=bs().store;if(s&&Date.now()-t.at<Hc)try{s.label(t.callId,"userReply",oi(n.message)?"approved":"redirected",{kind:"outcome",labeledBy:"next-user-message"})}catch{}}!n.previousReply||!ii(n.message)||!Cn(n.previousReply)||ue(ti,di({agent:n.agent,channel:n.channel,message:n.message,previousReply:n.previousReply}),si,{links:[{kind:"task",id:n.taskId}],features:{agent:n.agent,channel:n.channel}})}Vi();ea();ta();ys();function fi(n,e,t=0){return new Promise((s,r)=>{let o,i=()=>{o=setTimeout(()=>r(Xe(e)),t)},a=()=>{e.removeEventListener("abort",i),o&&clearTimeout(o)};n.then(c=>{a(),s(c)},c=>{a(),r(c)}),e.aborted?i():e.addEventListener("abort",i,{once:!0})})}function Xe(n){let e=n.reason;return e instanceof Error?e:new Error(typeof e=="string"?e:"task cancelled")}var _e=class extends Error{constructor(t,s){super(`step "${t}" exceeded its ${Math.round(s/1e3)}s budget`);this.step=t;this.budgetMs=s;this.name="StepBudgetExceeded"}};function mi(n,e,t){return e>0?new Promise((s,r)=>{let o=setTimeout(()=>r(new _e(t,e)),e);o.unref?.(),n.then(i=>{clearTimeout(o),s(i)},i=>{clearTimeout(o),r(i)})}):n}import{execFileSync as jc,spawn as qc}from"child_process";import{existsSync as Wc,mkdirSync as Gc,readFileSync as Kc,renameSync as Jc,writeFileSync as Qc}from"fs";import{dirname as zc}from"path";var Dt={enabled:!1,maxPerDay:0,openHours:24,launchTimeoutSeconds:120};function Xc(n){if(!n)return;let t=n.trim().match(/^(?:(?:https?|ssh|git)(?::\/\/)(?:[^@\/]+@)?|git@|)(?:www\.)?github\.com[\/:]([^\/\s]+)\/([^\/\s]+?)(?:\.git)?\/?$/i);if(t)return`${t[1]}/${t[2]}`}function Yc(n){try{return!n||!Wc(n)?void 0:jc("git",["-C",n,"remote","get-url","origin"],{encoding:"utf8",stdio:["ignore","pipe","ignore"],timeout:5e3}).trim()||void 0}catch{return}}function Pn(n){if(!n)return;let e=n.split(":");if(e.length<3)return;let t=Number(e[e.length-1]),s=e[e.length-2],r=e.slice(0,-2).join(":");if(!(!Number.isInteger(t)||t<=0)&&!(s!=="issue"&&s!=="pull")&&/^[^\/\s]+\/[^\/\s]+$/.test(r))return{repo:r,kind:s,number:t}}function hi(n){let e={...Dt,...n.agent.cloudSessions??{}};if(!e.enabled)return{route:"local",reason:"cloud sessions are off for this agent"};let t=n.context?.channel;if(t!=="github")return{route:"local",reason:`channel "${t||"api"}" does not send tasks to the cloud (GitHub only)`};if(!n.channelEnabled)return{route:"local",reason:"cloud sessions are off for the github channel"};if(n.agent.tier!=="claude-code")return{route:"local",reason:`agent tier "${n.agent.tier}" cannot run cloud sessions (claude-code only)`};let s=Pn(n.context?.chatId);if(!s)return{route:"local",reason:`task is not for a GitHub issue or pull request (chat "${n.context?.chatId||""}")`};if(n.openSession)return{route:"follow-up",session:n.openSession};if(e.maxPerDay>0&&(n.launchesToday??0)>=e.maxPerDay)return{route:"local",reason:`daily cap of ${e.maxPerDay} cloud launches reached`};let r=n.remoteOf??Yc,o=[n.context?.runbookPath,n.agent.workspace].filter(a=>!!a),i=s.repo.toLowerCase();for(let a of o){let c=Xc(r(a));if(c&&c.toLowerCase()===i)return{route:"cloud",repo:s.repo,kind:s.kind,number:s.number,cwd:a}}return{route:"local",reason:`no checkout of ${s.repo} on this node (looked in ${o.join(", ")||"nothing"}); set the project rule's runbook path to a clone whose origin is github.com/${s.repo}`}}var Vc=24*60*60*1e3,Zc=7*Vc,Et=class{constructor(e){this.file=e}sessions=[];loaded=!1;load(){if(!this.loaded){this.loaded=!0;try{let e=JSON.parse(Kc(this.file,"utf8")),t=Array.isArray(e?.sessions)?e.sessions:[];this.sessions=t.filter(s=>s&&typeof s.repo=="string"&&typeof s.sessionId=="string"&&Number.isFinite(s.startedAt))}catch{this.sessions=[]}}}save(){let e=Date.now();this.sessions=this.sessions.filter(t=>e-t.startedAt<Zc);try{Gc(zc(this.file),{recursive:!0});let t=`${this.file}.${process.pid}.tmp`;Qc(t,JSON.stringify({sessions:this.sessions},null,2)),Jc(t,this.file)}catch{}}open(e,t,s,r=Date.now()){this.load();let o=e.toLowerCase();return this.sessions.find(i=>i.repo.toLowerCase()===o&&i.number===t&&r-i.startedAt<s*60*60*1e3)}record(e){this.load(),this.sessions=this.sessions.filter(t=>!(t.repo.toLowerCase()===e.repo.toLowerCase()&&t.number===e.number)),this.sessions.push(e),this.save()}touch(e,t=Date.now()){this.load();let s=this.sessions.find(r=>r.sessionId===e);s&&(s.lastMessageAt=t,this.save())}close(e,t){this.load();let s=this.sessions.length;return this.sessions=this.sessions.filter(r=>!(r.repo.toLowerCase()===e.toLowerCase()&&r.number===t)),this.sessions.length===s?!1:(this.save(),!0)}launchesToday(e,t=Date.now()){this.load();let s=new Date(t);return s.setHours(0,0,0,0),this.sessions.filter(r=>r.agentId===e&&r.startedAt>=s.getTime()&&r.startedAt<=t).length}all(){return this.load(),[...this.sessions]}},eu=["import os, pty, sys","status = pty.spawn(sys.argv[1:])","sys.exit(os.waitstatus_to_exitcode(status) if isinstance(status, int) else 0)"].join(`
100
+ `);function tu(n,e){return e?["-p",n,"--cloud",e]:["--cloud",n]}var nu=/\x1b\[[0-9;?]*[ -\/]*[@-~]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\x1b[()][AB012]|\r/g;function yi(n){return n.replace(nu,"")}function su(n){let e=yi(n),t=e.match(/https:\/\/claude\.ai\/code\/[A-Za-z0-9_\-]+(?:\/[A-Za-z0-9_\-]+)*/)?.[0],s=e.match(/\bsession_[A-Za-z0-9]{6,}\b/)?.[0];if(!s&&t){let r=t.split("/").filter(Boolean).pop();r&&r!=="code"&&(s=r)}return{sessionId:s,url:t}}async function wi(n){let e=n.spawn??((c,d,u)=>qc(c,d,u)),t=n.python??"python3",s=["-c",eu,"claude",...tu(n.prompt,n.sessionId)],r={...n.env,NO_COLOR:"1",FORCE_COLOR:"0"},o="",i=c=>{o+=c.toString(),o.length>64e3&&(o=o.slice(-64e3))},a=()=>yi(o).trim().split(`
101
101
  `).slice(-5).join(`
102
- `).slice(-600);return new Promise(c=>{let d=!1,u=p=>{d||(d=!0,c(p))},l;try{l=e(t,s,{cwd:n.cwd,env:r,detached:!0,stdio:["ignore","pipe","pipe"]})}catch(p){u({ok:!1,reason:`could not start ${t}: ${p?.message||p}`,output:o});return}let f=p=>{try{l.pid&&process.kill(-l.pid,p)}catch{try{l.kill(p)}catch{}}},h=setTimeout(()=>{f("SIGTERM"),setTimeout(()=>f("SIGKILL"),3e3).unref?.(),u({ok:!1,reason:`claude --cloud did not print a session within ${Math.round(n.timeoutMs/1e3)}s${a()?`; last output: ${a()}`:""}`,output:o})},n.timeoutMs);h.unref?.(),l.stdout?.on("data",i),l.stderr?.on("data",i),l.on("error",p=>{clearTimeout(h);let I=p?.code==="ENOENT";u({ok:!1,reason:I?`${t} is not installed (needed to give claude --cloud a terminal)`:`launch failed: ${p?.message||p}`,output:o})}),l.on("close",p=>{if(clearTimeout(h),d)return;let I=nu(o);if(n.sessionId){if(p===0){u({ok:!0,sessionId:n.sessionId,url:I.url||"",output:o});return}u({ok:!1,reason:`claude -p --cloud exited with code ${p??"unknown"}${a()?`: ${a()}`:""}`,output:o});return}if(I.sessionId&&I.url){u({ok:!0,sessionId:I.sessionId,url:I.url,output:o});return}if(p!==0){u({ok:!1,reason:`claude --cloud exited with code ${p??"unknown"}${a()?`: ${a()}`:""}`,output:o});return}u({ok:!1,reason:`claude --cloud printed no session id or URL${a()?`; last output: ${a()}`:""}`,output:o})})})}var su=1e5;function ru(n,e){let s=`
102
+ `).slice(-600);return new Promise(c=>{let d=!1,u=p=>{d||(d=!0,c(p))},l;try{l=e(t,s,{cwd:n.cwd,env:r,detached:!0,stdio:["ignore","pipe","pipe"]})}catch(p){u({ok:!1,reason:`could not start ${t}: ${p?.message||p}`,output:o});return}let f=p=>{try{l.pid&&process.kill(-l.pid,p)}catch{try{l.kill(p)}catch{}}},h=setTimeout(()=>{f("SIGTERM"),setTimeout(()=>f("SIGKILL"),3e3).unref?.(),u({ok:!1,reason:`claude --cloud did not print a session within ${Math.round(n.timeoutMs/1e3)}s${a()?`; last output: ${a()}`:""}`,output:o})},n.timeoutMs);h.unref?.(),l.stdout?.on("data",i),l.stderr?.on("data",i),l.on("error",p=>{clearTimeout(h);let I=p?.code==="ENOENT";u({ok:!1,reason:I?`${t} is not installed (needed to give claude --cloud a terminal)`:`launch failed: ${p?.message||p}`,output:o})}),l.on("close",p=>{if(clearTimeout(h),d)return;let I=su(o);if(n.sessionId){if(p===0){u({ok:!0,sessionId:n.sessionId,url:I.url||"",output:o});return}u({ok:!1,reason:`claude -p --cloud exited with code ${p??"unknown"}${a()?`: ${a()}`:""}`,output:o});return}if(I.sessionId&&I.url){u({ok:!0,sessionId:I.sessionId,url:I.url,output:o});return}if(p!==0){u({ok:!1,reason:`claude --cloud exited with code ${p??"unknown"}${a()?`: ${a()}`:""}`,output:o});return}u({ok:!1,reason:`claude --cloud printed no session id or URL${a()?`; last output: ${a()}`:""}`,output:o})})})}var ru=1e5;function ou(n,e){let s=`
103
103
 
104
104
  ---
105
- This task comes from GitHub ${e.kind==="pull"?"pull request":"issue"} #${e.number} in ${e.repo}. Work in this repository and open or update a pull request that references #${e.number}.`,r=su-s.length;return`${n.length>r?`${n.slice(0,r)}
106
- [message cut at ${r} characters]`:n}${s}`}function ou(n,e,t){return[`Started a Claude cloud session for this ${e==="pull"?"pull request":"issue"}. The result arrives as a pull request.`,`Session: \`${n.sessionId}\``,n.url,`Comments here are forwarded to that session for the next ${t} hours.`].join(`
107
- `)}function iu(n){return`Forwarded to the open Claude cloud session \`${n.sessionId}\` (${n.url}).`}async function wi(n){let{route:e}=n,t=n.now??Date.now;if(e.route==="local")return n.trace({action:"skipped",status:"ok",summary:e.reason}),null;if(e.route==="follow-up"){let i=e.session,a=await n.launch({cwd:i.cwd||process.cwd(),prompt:n.message,sessionId:i.sessionId});return a.ok?(n.store.touch(i.sessionId,t()),n.log(`[${n.agentId}] forwarded to open cloud session ${i.sessionId} for ${i.repo}#${i.number}`),n.trace({action:"follow-up",status:"ok",summary:JSON.stringify({sessionId:i.sessionId,url:i.url})}),{content:iu(i),cloudSession:{id:i.sessionId,url:i.url,followUp:!0}}):(n.log(`[${n.agentId}] forwarding to cloud session ${i.sessionId} failed: ${a.reason}`),n.trace({action:"follow-up",status:"error",summary:a.reason}),{content:"",error:`Claude cloud session \`${i.sessionId}\` is still open for this ${i.kind==="pull"?"pull request":"issue"} (${i.url}); forwarding this comment to it failed: ${a.reason}. No local run starts while the session is open.`,cloudSession:{id:i.sessionId,url:i.url,followUp:!0}})}let s=ru(n.message,e),r=await n.launch({cwd:e.cwd,prompt:s});if(!r.ok)return n.log(`[${n.agentId}] cloud session launch for ${e.repo}#${e.number} failed, running locally: ${r.reason}`),n.trace({action:"fallback",status:"error",summary:r.reason}),null;let o={repo:e.repo,number:e.number,kind:e.kind,sessionId:r.sessionId,url:r.url,agentId:n.agentId,startedAt:t(),cwd:e.cwd,traceId:n.traceId};return n.store.record(o),n.log(`[${n.agentId}] cloud session ${r.sessionId} started for ${e.repo}#${e.number}: ${r.url}`),n.trace({action:"launched",status:"ok",summary:JSON.stringify({sessionId:r.sessionId,url:r.url,repo:e.repo,number:e.number})}),{content:ou(o,e.kind,n.settings.openHours),cloudSession:{id:r.sessionId,url:r.url}}}var du=250,cu=5e3,pu={"request-gate":5e3,"seed-history":3e4,skills:1e4,rotate:8e3,compact:3e4,references:1e4,"plan-context":12e3,"select-context":5e3,"route-model":5e3},bi=`[Operating principle]
108
- Always investigate the codebase before relying on issue history or comments. The code is the source of truth \u2014 start by reading relevant files (CLAUDE.md, then code), and consult conversation context only to clarify intent. Issue threads may contain wrong hypotheses; verify against the source.`,fu="Change files with the Edit tool, one exact replacement per edit, not with sed, awk or a shell rewrite: a pattern that misses or matches twice leaves the file broken and costs another round. Several edits can go in one turn, and the tests can run in that same turn.";function mu(n){return n==="claude-code"?`${bi}
109
- ${fu}`:n==="codex-cli"?bi:""}function xi(n,e){return e!=="claude-code"&&e!=="codex-cli"?!1:n==="github"||n==="gitlab"}var Ai;function af(n){Ai=n}function df(){return Ai}var Si=64*1024,hu=5*60*1e3,yu=3e4,wu=300,Re=".agentx/task-history",bu=30;function Ve(n,e=800){return n.length<=e?n:n.slice(0,e)+` \u2026[+${n.length-e} chars]`}function xu(n,e){let t={};return n?.path?.length&&(t.intentPath=n.path,t.intentPathLabel=n.pathLabel),e?.sender&&(t.sender=e.sender),e?.senderId&&(t.senderId=e.senderId),e?.senderUsername&&(t.senderUsername=e.senderUsername),e?.group&&e?.sender&&(t.group=e.group),Object.keys(t).length>0?t:void 0}function Su(n,e){if(!e?.some(r=>r.delivery==="digest"))return;let{shown:t,more:s}=Qs(n,e,Y().recent());return Xs(t,s)}function Iu(n,e,t={}){let s;try{s=n.listArticles(e)}catch{return""}if(s.length===0)return"";let r=new Map;for(let u of s){let l=u.meta.type||"untyped",f=r.get(l)||[];f.push(u.meta.title),r.set(l,f)}let o=t.maxArticles??400,i=s.length<=o,a=Array.from(r.entries()).sort().map(([u,l])=>i?`**${u}** (${l.length}) \u2014 ${l.sort().join(" \xB7 ")}`:`**${u}** \u2014 ${l.length} article${l.length===1?"":"s"}`).join(`
105
+ This task comes from GitHub ${e.kind==="pull"?"pull request":"issue"} #${e.number} in ${e.repo}. Work in this repository and open or update a pull request that references #${e.number}.`,r=ru-s.length;return`${n.length>r?`${n.slice(0,r)}
106
+ [message cut at ${r} characters]`:n}${s}`}function iu(n,e,t){return[`Started a Claude cloud session for this ${e==="pull"?"pull request":"issue"}. The result arrives as a pull request.`,`Session: \`${n.sessionId}\``,n.url,`Comments here are forwarded to that session for the next ${t} hours.`].join(`
107
+ `)}function au(n){return`Forwarded to the open Claude cloud session \`${n.sessionId}\` (${n.url}).`}async function bi(n){let{route:e}=n,t=n.now??Date.now;if(e.route==="local")return n.trace({action:"skipped",status:"ok",summary:e.reason}),null;if(e.route==="follow-up"){let i=e.session,a=await n.launch({cwd:i.cwd||process.cwd(),prompt:n.message,sessionId:i.sessionId});return a.ok?(n.store.touch(i.sessionId,t()),n.log(`[${n.agentId}] forwarded to open cloud session ${i.sessionId} for ${i.repo}#${i.number}`),n.trace({action:"follow-up",status:"ok",summary:JSON.stringify({sessionId:i.sessionId,url:i.url})}),{content:au(i),cloudSession:{id:i.sessionId,url:i.url,followUp:!0}}):(n.log(`[${n.agentId}] forwarding to cloud session ${i.sessionId} failed: ${a.reason}`),n.trace({action:"follow-up",status:"error",summary:a.reason}),{content:"",error:`Claude cloud session \`${i.sessionId}\` is still open for this ${i.kind==="pull"?"pull request":"issue"} (${i.url}); forwarding this comment to it failed: ${a.reason}. No local run starts while the session is open.`,cloudSession:{id:i.sessionId,url:i.url,followUp:!0}})}let s=ou(n.message,e),r=await n.launch({cwd:e.cwd,prompt:s});if(!r.ok)return n.log(`[${n.agentId}] cloud session launch for ${e.repo}#${e.number} failed, running locally: ${r.reason}`),n.trace({action:"fallback",status:"error",summary:r.reason}),null;let o={repo:e.repo,number:e.number,kind:e.kind,sessionId:r.sessionId,url:r.url,agentId:n.agentId,startedAt:t(),cwd:e.cwd,traceId:n.traceId};return n.store.record(o),n.log(`[${n.agentId}] cloud session ${r.sessionId} started for ${e.repo}#${e.number}: ${r.url}`),n.trace({action:"launched",status:"ok",summary:JSON.stringify({sessionId:r.sessionId,url:r.url,repo:e.repo,number:e.number})}),{content:iu(o,e.kind,n.settings.openHours),cloudSession:{id:r.sessionId,url:r.url}}}var cu=250,uu=5e3,fu={"request-gate":5e3,"seed-history":3e4,skills:1e4,rotate:8e3,compact:3e4,references:1e4,"plan-context":12e3,"select-context":5e3,"route-model":5e3},xi=`[Operating principle]
108
+ Always investigate the codebase before relying on issue history or comments. The code is the source of truth \u2014 start by reading relevant files (CLAUDE.md, then code), and consult conversation context only to clarify intent. Issue threads may contain wrong hypotheses; verify against the source.`,mu="Change files with the Edit tool, one exact replacement per edit, not with sed, awk or a shell rewrite: a pattern that misses or matches twice leaves the file broken and costs another round. Several edits can go in one turn, and the tests can run in that same turn.";function hu(n){return n==="claude-code"?`${xi}
109
+ ${mu}`:n==="codex-cli"?xi:""}function Si(n,e){return e!=="claude-code"&&e!=="codex-cli"?!1:n==="github"||n==="gitlab"}var $i;function df(n){$i=n}function cf(){return $i}var Ii=64*1024,yu=5*60*1e3,wu=3e4,bu=300,Re=".agentx/task-history",xu=30;function Ve(n,e=800){return n.length<=e?n:n.slice(0,e)+` \u2026[+${n.length-e} chars]`}function Su(n,e){let t={};return n?.path?.length&&(t.intentPath=n.path,t.intentPathLabel=n.pathLabel),e?.sender&&(t.sender=e.sender),e?.senderId&&(t.senderId=e.senderId),e?.senderUsername&&(t.senderUsername=e.senderUsername),e?.group&&e?.sender&&(t.group=e.group),Object.keys(t).length>0?t:void 0}function Iu(n,e){if(!e?.some(r=>r.delivery==="digest"))return;let{shown:t,more:s}=zs(n,e,Y().recent());return Ys(t,s)}function Tu(n,e,t={}){let s;try{s=n.listArticles(e)}catch{return""}if(s.length===0)return"";let r=new Map;for(let u of s){let l=u.meta.type||"untyped",f=r.get(l)||[];f.push(u.meta.title),r.set(l,f)}let o=t.maxArticles??400,i=s.length<=o,a=Array.from(r.entries()).sort().map(([u,l])=>i?`**${u}** (${l.length}) \u2014 ${l.sort().join(" \xB7 ")}`:`**${u}** \u2014 ${l.length} article${l.length===1?"":"s"}`).join(`
110
110
  `),c=process.argv[1]||"dist/cli.js",d=n.baseDir.replace(new RegExp(`/agents/${e}(/[^/]+)?$`),"");return["[Institutional Wiki \u2014 the single source of truth]",`${s.length} article${s.length===1?"":"s"}. This is long-term memory for the whole fleet: who people are, what systems exist, what happened, what was decided, how we do things.`,"","It outranks every other context you are given. Your workspace memory, injected skills, mined procedures and behavioural patterns are all either staged into the wiki or derived from it \u2014 where any of them disagrees with the wiki, the wiki is right and the other is stale.","","Catalog:",a,"",`For the contents of an article, or any question spanning several, run:
111
111
  node ${c} wiki query "the question" --dir ${d} --agent ${e}`,"","It walks the catalog and the wikilink graph and returns a cited answer. Ask it before you grep the workspace or answer from your own recollection.","",`Facts about outside systems (billing, accounts, outages, deploys) carry a source and a check date: \`node ${c} wiki facts list --dir ${d}\`. Past its time limit a fact must be re-checked at the source before you state it; record what you checked with \`wiki facts set ... --checked-at now\`. If you can't check, say it is unverified and ask the owner.`,"[End Institutional Wiki]"].join(`
112
- `)}var Pn=8*1024;function Tu(n,e){if(n)try{nr(n)}catch{}return e}function Ii(n){if(n.length<=Pn)return n;let e=n.length-Pn;return n.slice(0,Pn)+`\u2026[+${e}]`}function Ti(n,e){if(!e||typeof e!="object"||e.type!=="assistant")return;let t=e.message?.content;if(Array.isArray(t))for(let s of t){if(s?.type!=="tool_use")continue;let r=typeof s.name=="string"?s.name:"";r&&n.set(r,(n.get(r)??0)+1)}}function vu(n,e){if(!n||n.length===0)return null;for(let t of n)if((e.get(t)??0)===0)return t;return null}function vi(n,e,t){if(!t||typeof t!="object")return;let s=t.type,r=new Date().toISOString(),o=Y();if(s==="assistant"&&t.message?.content){for(let i of t.message.content)if(i.type==="tool_use"){let a=i.input!=null?JSON.stringify(i.input):"";o.emit("task:step",{taskId:n,agentId:e,name:"tool_use",action:typeof i.name=="string"?i.name:null,status:"in-flight",inputSummary:a?Ii(a):null,at:r})}return}if(s==="user"&&t.message?.content){for(let i of t.message.content)if(i.type==="tool_result"){let a=Array.isArray(i.content)?i.content.map(c=>typeof c?.text=="string"?c.text:"").join(""):typeof i.content=="string"?i.content:"";o.emit("task:step",{taskId:n,agentId:e,name:"tool_result",status:i.is_error?"error":"ok",outputSummary:a?Ii(a):null,at:r})}return}}function ku(){let n="",e="";return t=>{if(!t||typeof t!="object")return"";let s=t.type;if(s==="opencode.ready")return`. opencode ${t.reused?"reused":"started"} ready=${t.startupMs}ms
112
+ `)}var _n=8*1024;function vu(n,e){if(n)try{sr(n)}catch{}return e}function Ti(n){if(n.length<=_n)return n;let e=n.length-_n;return n.slice(0,_n)+`\u2026[+${e}]`}function vi(n,e){if(!e||typeof e!="object"||e.type!=="assistant")return;let t=e.message?.content;if(Array.isArray(t))for(let s of t){if(s?.type!=="tool_use")continue;let r=typeof s.name=="string"?s.name:"";r&&n.set(r,(n.get(r)??0)+1)}}function ku(n,e){if(!n||n.length===0)return null;for(let t of n)if((e.get(t)??0)===0)return t;return null}function ki(n,e,t){if(!t||typeof t!="object")return;let s=t.type,r=new Date().toISOString(),o=Y();if(s==="assistant"&&t.message?.content){for(let i of t.message.content)if(i.type==="tool_use"){let a=i.input!=null?JSON.stringify(i.input):"";o.emit("task:step",{taskId:n,agentId:e,name:"tool_use",action:typeof i.name=="string"?i.name:null,status:"in-flight",inputSummary:a?Ti(a):null,at:r})}return}if(s==="user"&&t.message?.content){for(let i of t.message.content)if(i.type==="tool_result"){let a=Array.isArray(i.content)?i.content.map(c=>typeof c?.text=="string"?c.text:"").join(""):typeof i.content=="string"?i.content:"";o.emit("task:step",{taskId:n,agentId:e,name:"tool_result",status:i.is_error?"error":"ok",outputSummary:a?Ti(a):null,at:r})}return}}function Au(){let n="",e="";return t=>{if(!t||typeof t!="object")return"";let s=t.type;if(s==="opencode.ready")return`. opencode ${t.reused?"reused":"started"} ready=${t.startupMs}ms
113
113
  `;if(s==="opencode.first_output")return`. opencode first output=${t.elapsedMs}ms
114
114
  `;if(s==="opencode.fallback")return`. opencode using CLI fallback: ${t.reason}
115
115
  `;if(s==="codex.ready")return`. codex ${t.reused?"reused":"started"} ready=${t.startupMs}ms
@@ -130,25 +130,25 @@ ${fu}`:n==="codex-cli"?bi:""}function xi(n,e){return e!=="claude-code"&&e!=="cod
130
130
  \u2192 ${i}(${a})
131
131
  `}return r}if(s==="user"&&t.message?.content){let r="";for(let o of t.message.content)if(o.type==="tool_result"){let i=Array.isArray(o.content)?o.content.map(c=>typeof c?.text=="string"?c.text:"").join(""):typeof o.content=="string"?o.content:"",a=o.is_error?"\u2190 [error] ":"\u2190 ";r+=`${a}${Ve(i,800)}
132
132
  `}return r}return s==="result"?`\xB7 done${t.duration_ms?` (${Math.round(t.duration_ms/1e3)}s)`:""}
133
- `:""}}var ki=class{agents=new Map;config;providers={};sessions;wikiHub;memoryStore;agentMemory=new Us;patternStore;rateLimiter;tokenTracker;landscape;meshFallback;workflowAutoRunner;messageQueue;voiceClaims=new Set;classifier;graphStore;handoverStore=new Ls;activeSouls=new Map;taskOutputs=new Map;taskAborts=new Map;interruptedRuns=new Map;cloudSessions;runningContexts=new Map;runReleases=new Map;lastSummaries=new Map;sparklineCache=new Map;referencesCache=new Map;log;constructor(e,t=console.error.bind(console,"[agents]")){if(this.log=t,this.config=e,this.providers=e.providers,this.sessions=new vt(process.cwd(),{staleMinutes:e.session.staleMinutes,maxTurnsPerSession:e.session.maxTurnsPerSession,tierTwoThresholdTokens:e.session.tierTwoThresholdTokens,tierTwoThresholdTokensByChannel:e.session.tierTwoThresholdTokensByChannel}),this.wikiHub=new Es(void 0,void 0,"graph"),this.memoryStore=new Fs,this.patternStore=new $t,this.rateLimiter=new kt,this.tokenTracker=new Os,this.messageQueue=new At,xo({maxPerHour:e.session.maxClaudeCodeDispatchesPerHour,maxPer5h:e.session.maxClaudeCodeDispatchesPer5h}),e.graph?.enabled){this.graphStore=new _s({baseDir:J(process.cwd(),e.graph.baseDir),log:(...r)=>t("[graph]",...r)});let s=e.graph.draftAgent||e.dashboard?.draftAgent;this.classifier=new Rs({store:this.graphStore,daemonUrl:e.dashboard.daemonUrl,token:e.dashboard.token,draftAgent:s,autoApproveStructure:e.graph.autoApproveStructure,autoApproveConfidence:e.graph.autoApproveConfidence,classifierModel:e.graph.classifierModel,log:(...r)=>t("[classifier]",...r)})}for(let[s,r]of Object.entries(e.agents))this.agents.set(s,{id:s,def:r,activeTasks:0,totalTasks:0,errors:0,runningTasks:[]})}setLandscape(e){this.landscape=e}setMeshFallback(e){this.meshFallback=e}setWorkflowAutoRunner(e){this.workflowAutoRunner=e}setProviders(e){this.providers=e}setConfig(e){this.config=e}setPeople(e){this.config={...this.config,people:e}}refusalFor(e,t){let s=fs(this.config.people,e,t);return s?(this.log(`[${e}] refused: ${s.person.id} may not reach this agent (people[].agents)`),this.memberTrail().log({person:s.person.id,event:"agent-refused",detail:e}),s.note):null}logToolRefusal(e,t,s){this.log(`[${t??"?"}] blocked for ${e}: ${s} (people[].deny)`),this.memberTrail().log({person:e,event:"tool-refused",detail:s})}memberTrail(){let e=this.config.members.logRetentionDays;return(!this.memberLog||this.memberLog.days!==e)&&(this.memberLog={days:e,store:new er(process.cwd(),Date.now,e)}),this.memberLog.store}memberLog;buildHandoverNote(e,t,s){let r=this.handoverStore.get(t,s);if(!r||r.toAgent!==e)return;let o=this.handoverStore.consumeSummary(t,s);if(!(!o&&r.summaryConsumedAt))return{fromAgent:r.fromAgent,summary:o||r.summary,at:r.createdAt}}getAgent(e){return this.agents.get(e)?.def}findByMention(e,t={}){let s=e.toLowerCase(),r,o=0;for(let[i,a]of this.agents)for(let c of a.def.mentions){if(t.atMentionsOnly&&!c.startsWith("@"))continue;let d=c.toLowerCase();s.includes(d)&&d.length>o&&(r=i,o=d.length)}return r}findAllMentioned(e){let t=e.toLowerCase(),s=[];for(let[r,o]of this.agents)for(let i of o.def.mentions)if(t.includes(i.toLowerCase())){s.push(r);break}return s}getWikiHub(){return this.wikiHub}getGraphStore(){return this.graphStore}getSessionStore(){return this.sessions}async maybeRotateForContinuity(e,t,s,r,o){let i=null,a=null,c=[];try{let f=this.sessions.getSession(e.agentId,s,r);i=eo(f.messages,e.message??""),c=to(f.messages,e.message??"",this.config.session.continuityStateTurns),f.updatedAt&&(a=Math.round((Date.now()-Date.parse(f.updatedAt))/6e4))}catch{}let d={message:e.message??"",previousMessage:i,recentRequests:c,minutesSinceLastTurn:a,turnCount:this.sessions.getTurnCount(e.agentId,s,r),lastTurnContextTokens:this.sessions.getLastTurnContextTokens(e.agentId,s,r)||null,agentId:e.agentId,channel:s},u=await ue(mr,yr(d),hr,{incumbent:{continues:"yes",needsHistory:"yes"},links:[{kind:"session",id:`${e.agentId}:${s}:${r}`}],features:{agent:e.agentId,channel:s},timeoutMs:1500});return!u||u.mode!=="active"||!wr(u.answers,{mechanicalRotation:!1})?!1:(this.log(`[${e.agentId}] continuity rotation for ${s}:${r} (new subject)`),this.captureRotationMemoAsync(e.agentId,t.def,o,s,r,"continuity"),this.sessions.clearClaudeSessionId(e.agentId,s,r),Y().emit("session:rotated",{agentId:e.agentId,channel:s,chatId:r,reason:"continuity",at:new Date().toISOString()}),!0)}async captureRotationMemoAsync(e,t,s,r,o,i){try{let{extractRotationMemo:a}=await import("./rotation-memo-6UW6DTBQ.js"),c=await a(t,s);if(!c.memo){this.log(`[${e}] rotation memo skipped (${i}, ${c.reason}, ${c.durationMs}ms)`);return}let{storeRotationMemo:d}=await import("./rotation-memo-store-A4YW6FSK.js"),u=d(this.memoryStore,this.sessions,{wikiDir:this.wikiHub.getBaseDir(),agentId:e,channel:r,chatId:o,reason:i,memo:c.memo});u.error&&this.log(`[${e}] memo claims not proposed: ${u.error}`),this.log(`[${e}] rotation memo captured (${i}, ${c.durationMs}ms, ${c.memo.length} chars, ${u.proposals} claim(s) proposed to the wiki)`)}catch(a){this.log(`rotation memo error: ${a?.message||a}`)}}buildPeerList(e,t){let s=[];for(let[r,o]of this.agents)r!==e&&s.push({name:o.def.name,handle:this.getChannelHandle(r,t),role:o.def.systemPrompt?.split(`
134
- `)[0]?.slice(0,80)});return s}getChannelHandle(e,t){let s=this.agents.get(e)?.def;if(s)return t==="telegram"?s.mentions.find(r=>r.startsWith("@")):s.mentions[0]}cloudSessionStore(){return this.cloudSessions||(this.cloudSessions=new Rt(J(process.cwd(),".agentx/cloud-sessions.json"))),this.cloudSessions}planCloudSession(e,t){let s={...Et,...e.cloudSessions??{}};if(!s.enabled)return{route:"local",reason:"cloud sessions are off for this agent"};let r=t.context?.channel||"api",o=this.config.channels?.[r],i=Mn(t.context?.chatId),a=this.cloudSessionStore();return mi({agent:e,channelEnabled:o?.cloudSessions===!0,context:t.context,openSession:i?a.open(i.repo,i.number,s.openHours):void 0,launchesToday:a.launchesToday(t.agentId)})}async runCloudSession(e,t,s,r){let o={...Et,...e.cloudSessions??{}},i=Date.now(),a=ye(Ge(ve(e.workspace),t),e.billing),c=await wi({route:s,agentId:t.agentId,message:t.message,settings:o,store:this.cloudSessionStore(),traceId:r,launch:d=>yi({...d,env:a,timeoutMs:o.launchTimeoutSeconds*1e3}),log:d=>this.log(d),trace:d=>{try{Y().emit("task:step",{taskId:r,agentId:t.agentId,name:"cloud_session",action:d.action,status:d.status,outputSummary:d.status==="ok"?d.summary:void 0,error:d.status==="error"?d.summary:void 0,ms:Date.now()-i,at:new Date().toISOString()})}catch{}}});return c?{content:c.content,error:c.error,cloudSession:c.cloudSession,duration:Date.now()-i}:null}async execute(e,t,s,r){let o=Date.now(),i;try{i=await this.executeInternal(e,t,s,r)}catch(d){i={content:"",error:d?.message??String(d)}}let a=e.runningTaskId?this.interruptedRuns.get(e.runningTaskId):void 0;a&&(this.interruptedRuns.delete(e.runningTaskId),i={...i,content:"",error:a,errorKind:"interrupted"}),e.runningTaskId&&this.runReleases.get(e.runningTaskId)?.(i);let c=!a&&i.error&&/^timed out before spawn after/.test(i.error);if(c&&!e.preSpawnRetry)return this.log(`[${e.agentId}] ${i.error}; retrying the run once`),this.execute({...e,preSpawnRetry:1,runningTaskId:void 0,onStart:void 0},t,s,r);if(c){let d=i.error.match(/in step "([^"]+)"/)?.[1]??"start";i={...i,error:`I couldn't get started on this: preparing the run stalled twice (step "${d}"). Please send it again.`,errorKind:"interrupted"}}if(e.intentRef)try{let d=i.error?Ue(i.error)?"queued":/timed out|timeout/i.test(i.error)?"timed-out":"failed":"completed";js().recordResolution({decisionEventId:e.intentRef.eventId,decisionDecidedBy:e.intentRef.decidedBy,resolvedAt:Date.now(),status:d,durationMs:Date.now()-o,resultSummary:i.error?i.error.slice(0,200):i.content?.slice(0,200)??null})}catch(d){this.log(`[ledger] resolution write failed for ${e.intentRef.eventId}/${e.intentRef.decidedBy}: ${d?.message??d}`)}return i}async executeInternal(e,t,s,r){let o=this.refusalFor(e.agentId,e.context);if(o)return{content:o,duration:0};let i=ie(e.autonomy),a=ms(this.config.people,e.context);a?e.personLimits=a:delete e.personLimits;let c=i||a?null:ho().offer({agentId:e.agentId,text:e.message,channel:e.context?.channel||"api",chatId:String(e.context?.chatId||e.context?.group||"default"),sender:String(e.context?.sender||"unknown")});if(c){let g=await c;if(g.kind==="answered")return this.log(`[${e.agentId}] answered by attached session ${g.sessionId}`),{content:g.text,viaAttachedSession:g.sessionId};this.log(`[${e.agentId}] attached session did not take it (${g.reason}) \u2014 spawning`)}let d=this.agents.get(e.agentId);if(!d){if(i)return{content:"",error:`autonomy "${e.autonomy}" cannot be enforced on a mesh peer \u2014 agent "${e.agentId}" is not local`,autonomy:e.autonomy};if(a)return{content:"",error:`${a.name}'s tool and skill limits cannot be enforced on a mesh peer \u2014 agent "${e.agentId}" is not local`};if(this.meshFallback){let g=this.meshFallback.directory().find(m=>m.healthy&&m.skills.some(S=>S.id===e.agentId));if(g){this.log(`[${e.agentId}] not local \u2014 routing to mesh peer "${g.peer}"`);try{let m=typeof e.timeoutMinutes=="number"&&e.timeoutMinutes>0?e.timeoutMinutes*60*1e3:void 0;return{content:await this.meshFallback.sendTask(g.peer,e.message,e.agentId,{timeoutMs:m}),viaMesh:g.peer}}catch(m){return this.log(`[${e.agentId}] mesh fallback to "${g.peer}" failed: ${m?.message??m}`),{content:"",error:`mesh fallback failed: ${m?.message??m}`}}}}return{content:"",error:`Unknown agent: ${e.agentId}`}}let{channel:u,chatId:l}=Tt(e.context),f;if(d.activeTasks>=d.def.maxConcurrent)if(u==="api"||u==="app"||u==="a2a"||u==="mcp"||u==="reminder"||u==="events"||u==="guest"||i){let g=Date.now(),m=25*6e4,S=500;for(;d.activeTasks>=d.def.maxConcurrent;){if(Date.now()-g>m)return{content:"",error:`Agent "${e.agentId}" busy \u2014 slot wait timed out after ${Math.round(m/6e4)}m`};await new Promise(M=>setTimeout(M,S))}}else if(u==="voice"){let g=Date.now(),m=25*6e4,S=`${e.agentId}\0${l}`;for(;this.messageQueue.isBusy(e.agentId,u,l)||this.voiceClaims.has(S);){if(Date.now()-g>m)return{content:"",error:`Agent "${e.agentId}" busy \u2014 voice wait timed out after ${Math.round(m/6e4)}m`};await new Promise(M=>setTimeout(M,500))}f=S,this.voiceClaims.add(S)}else{let g=d.def.queueMode||"collect",m=this.messageQueue.enqueue(e.agentId,u,l,{text:e.message,sender:e.context?.sender||"User",timestamp:Date.now(),channel:u,chatId:l,originalContext:e.context,queuedAt:e.queuedAt});if(m==="drop")return this.log(`[${e.agentId}] busy, message dropped (mode: drop)`),{content:"",error:`Agent "${e.agentId}" is busy \u2014 message dropped`};if(m){let S=this.messageQueue.pendingCount(e.agentId,u,l);return Y().emit("task:queued",{agentId:e.agentId,channel:u,chatId:l,at:new Date().toISOString(),sender:Jt(e.context),humanRoot:Gt(e.context),person:Qt(this.config.people,e.context)?.id??null,messagePreview:e.message.slice(0,200),queuedAt:Date.now()}),this.log(`[${e.agentId}] busy, message queued (mode: ${m}, pending: ${S}) behind=${d.runningTasks.map(M=>M.id).join(",")||"-"} chat=${u}:${l} at=${new Date().toISOString()}`),{content:"",error:Hs(m,S)}}}let h=await this.rateLimiter.acquire(e.agentId,{maxWaitMs:5*6e4,onWait:(g,m)=>{this.log(`[${e.agentId}] ${g} \u2014 queued, resumes in ~${Math.max(1,Math.round(m/1e3))}s`)}});if(f&&this.voiceClaims.delete(f),!h.ok)return this.log(`[${e.agentId}] ${h.reason}`),{content:"",error:h.reason};if(e.queuedAt!==void 0){let g=io(e.queuedAt);g&&(e.message=`${g}
135
- ${e.message}`),e.queuedAt=void 0}d.activeTasks++,d.totalTasks++,d.lastActive=new Date;let p={id:`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,messagePreview:(e.message||"").slice(0,200),message:e.message||"",channel:e.context?.channel||"api",chatId:e.context?.chatId||e.context?.group,sender:e.context?.sender,startedAt:new Date};d.runningTasks.push(p),e.runningTaskId=p.id;let I=Qt(this.config.people,e.context);if(e.context&&(I?e.context.person=I.id:delete e.context.person),this.runningContexts.set(p.id,e.context??{}),e.onStart)try{e.onStart(p.id)}catch{}let A=new AbortController;this.taskAborts.set(p.id,{agentId:e.agentId,channel:p.channel,chatId:typeof p.chatId=="string"?p.chatId:"",originalMessage:e.message||"",controller:A});let b={agentId:e.agentId,buffer:"",subscribers:new Set,done:!1};this.taskOutputs.set(p.id,b);let R=g=>{if(g){b.buffer+=g,b.buffer.length>Si&&(b.buffer=b.buffer.slice(b.buffer.length-Si));for(let m of b.subscribers)try{m(g)}catch{}}},E=Ie();e.taskId=E;let O=new Map,P=(g,m,S)=>{try{Y().emit("task:step",{taskId:E,agentId:e.agentId,name:"pipeline",action:g,status:S,ms:Date.now()-m,at:new Date().toISOString()})}catch{}},D=0,L=!1,F=()=>{L||(L=!0,D&&P("first-event",D,"ok"))},j;if(t){let g=ku();j=m=>{F();let S=g(m);if(S&&R(S),vi(E,e.agentId,m),Ti(O,m),bn(m,void 0,e.model||d.def.model),r)try{r(m)}catch{}}}else j=g=>{if(F(),vi(E,e.agentId,g),Ti(O,g),bn(g,void 0,e.model||d.def.model),r)try{r(g)}catch{}};let H=e.timeoutMinutes&&e.timeoutMinutes>0?e.timeoutMinutes*6e4:0,W=H?setTimeout(()=>A.abort(new Error(`timed out after ${Math.round(H/1e3)}s`)),H):void 0;W?.unref?.();let G=(d.def.preSpawnTimeoutSec??wu)*1e3,$=setTimeout(()=>{A.abort(new Error(`timed out before spawn after ${Math.round(G/1e3)}s in step "${p.step??"start"}"`))},G);$.unref?.();let T=()=>{$&&clearTimeout($),$=void 0},w=()=>`task=${p.id} chat=${u}:${l} at=${new Date().toISOString()}`,_;A.signal.addEventListener("abort",()=>{let g=Xe(A.signal).message;/^timed out/.test(g)&&(_=p.step??"start"),this.log(`[${e.agentId}] task ${p.id} aborted in step "${p.step??"start"}" \u2014 ${g} ${w()}`)},{once:!0});let x=g=>{p.step=g,this.log(`[${e.agentId}] step ${g} ${w()}`)},k=(g,m,S=0)=>{if(A.signal.aborted)return Promise.reject(Xe(A.signal));x(g),(g==="agent"||g==="workflow-auto-run")&&(T(),D=Date.now());let M=Date.now(),q=fi(m(),pu[g]??0,g);return pi(q,A.signal,S).then(B=>(P(g,M,"ok"),B),B=>{throw P(g,M,"error"),B instanceof _e&&this.log(`[${e.agentId}] ${B.message}; continuing without it ${w()}`),B})},K=async(g,m,S,M=0)=>{try{return await k(g,m,M)}catch(q){if(q instanceof _e)return S();throw q}},_n=!1,Rn=g=>{if(_n)return;_n=!0,this.runReleases.delete(p.id),W&&clearTimeout(W),T(),d.activeTasks--;let m=d.runningTasks.findIndex(S=>S.id===p.id);m!==-1&&d.runningTasks.splice(m,1),this.runningContexts.delete(p.id),this.taskAborts.delete(p.id),b.done=!0,b.endedAt=new Date;for(let S of b.subscribers)try{S(`
133
+ `:""}}var Ai=class{agents=new Map;config;providers={};sessions;wikiHub;memoryStore;agentMemory=new Hs;patternStore;rateLimiter;tokenTracker;landscape;meshFallback;workflowAutoRunner;messageQueue;voiceClaims=new Set;classifier;graphStore;handoverStore=new Fs;activeSouls=new Map;taskOutputs=new Map;taskAborts=new Map;interruptedRuns=new Map;cloudSessions;runningContexts=new Map;runReleases=new Map;lastSummaries=new Map;sparklineCache=new Map;referencesCache=new Map;log;constructor(e,t=console.error.bind(console,"[agents]")){if(this.log=t,this.config=e,this.providers=e.providers,this.sessions=new kt(process.cwd(),{staleMinutes:e.session.staleMinutes,maxTurnsPerSession:e.session.maxTurnsPerSession,tierTwoThresholdTokens:e.session.tierTwoThresholdTokens,tierTwoThresholdTokensByChannel:e.session.tierTwoThresholdTokensByChannel}),this.wikiHub=new Ds(void 0,void 0,"graph"),this.memoryStore=new Us,this.patternStore=new Ct,this.rateLimiter=new At,this.tokenTracker=new Ns,this.messageQueue=new $t,So({maxPerHour:e.session.maxClaudeCodeDispatchesPerHour,maxPer5h:e.session.maxClaudeCodeDispatchesPer5h}),e.graph?.enabled){this.graphStore=new Rs({baseDir:J(process.cwd(),e.graph.baseDir),log:(...r)=>t("[graph]",...r)});let s=e.graph.draftAgent||e.dashboard?.draftAgent;this.classifier=new Es({store:this.graphStore,daemonUrl:e.dashboard.daemonUrl,token:e.dashboard.token,draftAgent:s,autoApproveStructure:e.graph.autoApproveStructure,autoApproveConfidence:e.graph.autoApproveConfidence,classifierModel:e.graph.classifierModel,log:(...r)=>t("[classifier]",...r)})}for(let[s,r]of Object.entries(e.agents))this.agents.set(s,{id:s,def:r,activeTasks:0,totalTasks:0,errors:0,runningTasks:[]})}setLandscape(e){this.landscape=e}setMeshFallback(e){this.meshFallback=e}setWorkflowAutoRunner(e){this.workflowAutoRunner=e}setProviders(e){this.providers=e}setConfig(e){this.config=e}setPeople(e){this.config={...this.config,people:e}}refusalFor(e,t){let s=ms(this.config.people,e,t);return s?(this.log(`[${e}] refused: ${s.person.id} may not reach this agent (people[].agents)`),this.memberTrail().log({person:s.person.id,event:"agent-refused",detail:e}),s.note):null}logToolRefusal(e,t,s){this.log(`[${t??"?"}] blocked for ${e}: ${s} (people[].deny)`),this.memberTrail().log({person:e,event:"tool-refused",detail:s})}memberTrail(){let e=this.config.members.logRetentionDays;return(!this.memberLog||this.memberLog.days!==e)&&(this.memberLog={days:e,store:new tr(process.cwd(),Date.now,e)}),this.memberLog.store}memberLog;buildHandoverNote(e,t,s){let r=this.handoverStore.get(t,s);if(!r||r.toAgent!==e)return;let o=this.handoverStore.consumeSummary(t,s);if(!(!o&&r.summaryConsumedAt))return{fromAgent:r.fromAgent,summary:o||r.summary,at:r.createdAt}}getAgent(e){return this.agents.get(e)?.def}findByMention(e,t={}){let s=e.toLowerCase(),r,o=0;for(let[i,a]of this.agents)for(let c of a.def.mentions){if(t.atMentionsOnly&&!c.startsWith("@"))continue;let d=c.toLowerCase();s.includes(d)&&d.length>o&&(r=i,o=d.length)}return r}findAllMentioned(e){let t=e.toLowerCase(),s=[];for(let[r,o]of this.agents)for(let i of o.def.mentions)if(t.includes(i.toLowerCase())){s.push(r);break}return s}getWikiHub(){return this.wikiHub}getGraphStore(){return this.graphStore}getSessionStore(){return this.sessions}async maybeRotateForContinuity(e,t,s,r,o){let i=null,a=null,c=[];try{let f=this.sessions.getSession(e.agentId,s,r);i=to(f.messages,e.message??""),c=no(f.messages,e.message??"",this.config.session.continuityStateTurns),f.updatedAt&&(a=Math.round((Date.now()-Date.parse(f.updatedAt))/6e4))}catch{}let d={message:e.message??"",previousMessage:i,recentRequests:c,minutesSinceLastTurn:a,turnCount:this.sessions.getTurnCount(e.agentId,s,r),lastTurnContextTokens:this.sessions.getLastTurnContextTokens(e.agentId,s,r)||null,agentId:e.agentId,channel:s},u=await ue(hr,wr(d),yr,{incumbent:{continues:"yes",needsHistory:"yes"},links:[{kind:"session",id:`${e.agentId}:${s}:${r}`}],features:{agent:e.agentId,channel:s},timeoutMs:1500});return!u||u.mode!=="active"||!br(u.answers,{mechanicalRotation:!1})?!1:(this.log(`[${e.agentId}] continuity rotation for ${s}:${r} (new subject)`),this.captureRotationMemoAsync(e.agentId,t.def,o,s,r,"continuity"),this.sessions.clearClaudeSessionId(e.agentId,s,r),Y().emit("session:rotated",{agentId:e.agentId,channel:s,chatId:r,reason:"continuity",at:new Date().toISOString()}),!0)}async captureRotationMemoAsync(e,t,s,r,o,i){try{let{extractRotationMemo:a}=await import("./rotation-memo-6UW6DTBQ.js"),c=await a(t,s);if(!c.memo){this.log(`[${e}] rotation memo skipped (${i}, ${c.reason}, ${c.durationMs}ms)`);return}let{storeRotationMemo:d}=await import("./rotation-memo-store-A4YW6FSK.js"),u=d(this.memoryStore,this.sessions,{wikiDir:this.wikiHub.getBaseDir(),agentId:e,channel:r,chatId:o,reason:i,memo:c.memo});u.error&&this.log(`[${e}] memo claims not proposed: ${u.error}`),this.log(`[${e}] rotation memo captured (${i}, ${c.durationMs}ms, ${c.memo.length} chars, ${u.proposals} claim(s) proposed to the wiki)`)}catch(a){this.log(`rotation memo error: ${a?.message||a}`)}}buildPeerList(e,t){let s=[];for(let[r,o]of this.agents)r!==e&&s.push({name:o.def.name,handle:this.getChannelHandle(r,t),role:o.def.systemPrompt?.split(`
134
+ `)[0]?.slice(0,80)});return s}getChannelHandle(e,t){let s=this.agents.get(e)?.def;if(s)return t==="telegram"?s.mentions.find(r=>r.startsWith("@")):s.mentions[0]}cloudSessionStore(){return this.cloudSessions||(this.cloudSessions=new Et(J(process.cwd(),".agentx/cloud-sessions.json"))),this.cloudSessions}planCloudSession(e,t){let s={...Dt,...e.cloudSessions??{}};if(!s.enabled)return{route:"local",reason:"cloud sessions are off for this agent"};let r=t.context?.channel||"api",o=this.config.channels?.[r],i=Pn(t.context?.chatId),a=this.cloudSessionStore();return hi({agent:e,channelEnabled:o?.cloudSessions===!0,context:t.context,openSession:i?a.open(i.repo,i.number,s.openHours):void 0,launchesToday:a.launchesToday(t.agentId)})}async runCloudSession(e,t,s,r){let o={...Dt,...e.cloudSessions??{}},i=Date.now(),a=ye(Ge(ve(e.workspace),t),e.billing),c=await bi({route:s,agentId:t.agentId,message:t.message,settings:o,store:this.cloudSessionStore(),traceId:r,launch:d=>wi({...d,env:a,timeoutMs:o.launchTimeoutSeconds*1e3}),log:d=>this.log(d),trace:d=>{try{Y().emit("task:step",{taskId:r,agentId:t.agentId,name:"cloud_session",action:d.action,status:d.status,outputSummary:d.status==="ok"?d.summary:void 0,error:d.status==="error"?d.summary:void 0,ms:Date.now()-i,at:new Date().toISOString()})}catch{}}});return c?{content:c.content,error:c.error,cloudSession:c.cloudSession,duration:Date.now()-i}:null}async execute(e,t,s,r){let o=Date.now(),i;try{i=await this.executeInternal(e,t,s,r)}catch(d){i={content:"",error:d?.message??String(d)}}let a=e.runningTaskId?this.interruptedRuns.get(e.runningTaskId):void 0;a&&(this.interruptedRuns.delete(e.runningTaskId),i={...i,content:"",error:a,errorKind:"interrupted"}),e.runningTaskId&&this.runReleases.get(e.runningTaskId)?.(i);let c=!a&&i.error&&/^timed out before spawn after/.test(i.error);if(c&&!e.preSpawnRetry)return this.log(`[${e.agentId}] ${i.error}; retrying the run once`),this.execute({...e,preSpawnRetry:1,runningTaskId:void 0,onStart:void 0},t,s,r);if(c){let d=i.error.match(/in step "([^"]+)"/)?.[1]??"start";i={...i,error:`I couldn't get started on this: preparing the run stalled twice (step "${d}"). Please send it again.`,errorKind:"interrupted"}}if(e.intentRef)try{let d=i.error?Ue(i.error)?"queued":/timed out|timeout/i.test(i.error)?"timed-out":"failed":"completed";qs().recordResolution({decisionEventId:e.intentRef.eventId,decisionDecidedBy:e.intentRef.decidedBy,resolvedAt:Date.now(),status:d,durationMs:Date.now()-o,resultSummary:i.error?i.error.slice(0,200):i.content?.slice(0,200)??null})}catch(d){this.log(`[ledger] resolution write failed for ${e.intentRef.eventId}/${e.intentRef.decidedBy}: ${d?.message??d}`)}return i}async executeInternal(e,t,s,r){let o=this.refusalFor(e.agentId,e.context);if(o)return{content:o,duration:0};let i=ie(e.autonomy),a=hs(this.config.people,e.context);a?e.personLimits=a:delete e.personLimits;let c=i||a?null:yo().offer({agentId:e.agentId,text:e.message,channel:e.context?.channel||"api",chatId:String(e.context?.chatId||e.context?.group||"default"),sender:String(e.context?.sender||"unknown")});if(c){let g=await c;if(g.kind==="answered")return this.log(`[${e.agentId}] answered by attached session ${g.sessionId}`),{content:g.text,viaAttachedSession:g.sessionId};this.log(`[${e.agentId}] attached session did not take it (${g.reason}) \u2014 spawning`)}let d=this.agents.get(e.agentId);if(!d){if(i)return{content:"",error:`autonomy "${e.autonomy}" cannot be enforced on a mesh peer \u2014 agent "${e.agentId}" is not local`,autonomy:e.autonomy};if(a)return{content:"",error:`${a.name}'s tool and skill limits cannot be enforced on a mesh peer \u2014 agent "${e.agentId}" is not local`};if(this.meshFallback){let g=this.meshFallback.directory().find(m=>m.healthy&&m.skills.some(x=>x.id===e.agentId));if(g){this.log(`[${e.agentId}] not local \u2014 routing to mesh peer "${g.peer}"`);try{let m=typeof e.timeoutMinutes=="number"&&e.timeoutMinutes>0?e.timeoutMinutes*60*1e3:void 0;return{content:await this.meshFallback.sendTask(g.peer,e.message,e.agentId,{timeoutMs:m}),viaMesh:g.peer}}catch(m){return this.log(`[${e.agentId}] mesh fallback to "${g.peer}" failed: ${m?.message??m}`),{content:"",error:`mesh fallback failed: ${m?.message??m}`}}}}return{content:"",error:`Unknown agent: ${e.agentId}`}}let{channel:u,chatId:l}=vt(e.context),f;if(d.activeTasks>=d.def.maxConcurrent)if(u==="api"||u==="app"||u==="a2a"||u==="mcp"||u==="reminder"||u==="events"||u==="guest"||i){let g=Date.now(),m=25*6e4,x=500;for(;d.activeTasks>=d.def.maxConcurrent;){if(Date.now()-g>m)return{content:"",error:`Agent "${e.agentId}" busy \u2014 slot wait timed out after ${Math.round(m/6e4)}m`};await new Promise(M=>setTimeout(M,x))}}else if(u==="voice"){let g=Date.now(),m=25*6e4,x=`${e.agentId}\0${l}`;for(;this.messageQueue.isBusy(e.agentId,u,l)||this.voiceClaims.has(x);){if(Date.now()-g>m)return{content:"",error:`Agent "${e.agentId}" busy \u2014 voice wait timed out after ${Math.round(m/6e4)}m`};await new Promise(M=>setTimeout(M,500))}f=x,this.voiceClaims.add(x)}else{let g=d.def.queueMode||"collect",m=this.messageQueue.enqueue(e.agentId,u,l,{text:e.message,sender:e.context?.sender||"User",timestamp:Date.now(),channel:u,chatId:l,originalContext:e.context,queuedAt:e.queuedAt});if(m==="drop")return this.log(`[${e.agentId}] busy, message dropped (mode: drop)`),{content:"",error:`Agent "${e.agentId}" is busy \u2014 message dropped`};if(m){let x=this.messageQueue.pendingCount(e.agentId,u,l);return Y().emit("task:queued",{agentId:e.agentId,channel:u,chatId:l,at:new Date().toISOString(),sender:Qt(e.context),humanRoot:Kt(e.context),person:zt(this.config.people,e.context)?.id??null,messagePreview:e.message.slice(0,200),queuedAt:Date.now()}),this.log(`[${e.agentId}] busy, message queued (mode: ${m}, pending: ${x}) behind=${d.runningTasks.map(M=>M.id).join(",")||"-"} chat=${u}:${l} at=${new Date().toISOString()}`),{content:"",error:Bs(m,x)}}}let h=await this.rateLimiter.acquire(e.agentId,{maxWaitMs:5*6e4,onWait:(g,m)=>{this.log(`[${e.agentId}] ${g} \u2014 queued, resumes in ~${Math.max(1,Math.round(m/1e3))}s`)}});if(f&&this.voiceClaims.delete(f),!h.ok)return this.log(`[${e.agentId}] ${h.reason}`),{content:"",error:h.reason};if(e.queuedAt!==void 0){let g=ao(e.queuedAt);g&&(e.message=`${g}
135
+ ${e.message}`),e.queuedAt=void 0}d.activeTasks++,d.totalTasks++,d.lastActive=new Date;let p={id:`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,messagePreview:(e.message||"").slice(0,200),message:e.message||"",channel:e.context?.channel||"api",chatId:e.context?.chatId||e.context?.group,sender:e.context?.sender,startedAt:new Date};d.runningTasks.push(p),e.runningTaskId=p.id;let I=zt(this.config.people,e.context);if(e.context&&(I?e.context.person=I.id:delete e.context.person),this.runningContexts.set(p.id,e.context??{}),e.onStart)try{e.onStart(p.id)}catch{}let A=new AbortController;this.taskAborts.set(p.id,{agentId:e.agentId,channel:p.channel,chatId:typeof p.chatId=="string"?p.chatId:"",originalMessage:e.message||"",controller:A});let b={agentId:e.agentId,buffer:"",subscribers:new Set,done:!1};this.taskOutputs.set(p.id,b);let R=g=>{if(g){b.buffer+=g,b.buffer.length>Ii&&(b.buffer=b.buffer.slice(b.buffer.length-Ii));for(let m of b.subscribers)try{m(g)}catch{}}},E=Ie();e.taskId=E;let O=new Map,P=(g,m,x)=>{try{Y().emit("task:step",{taskId:E,agentId:e.agentId,name:"pipeline",action:g,status:x,ms:Date.now()-m,at:new Date().toISOString()})}catch{}},D=0,L=!1,F=()=>{L||(L=!0,D&&P("first-event",D,"ok"))},j;if(t){let g=Au();j=m=>{F();let x=g(m);if(x&&R(x),ki(E,e.agentId,m),vi(O,m),xn(m,void 0,e.model||d.def.model),r)try{r(m)}catch{}}}else j=g=>{if(F(),ki(E,e.agentId,g),vi(O,g),xn(g,void 0,e.model||d.def.model),r)try{r(g)}catch{}};let H=e.timeoutMinutes&&e.timeoutMinutes>0?e.timeoutMinutes*6e4:0,W=H?setTimeout(()=>A.abort(new Error(`timed out after ${Math.round(H/1e3)}s`)),H):void 0;W?.unref?.();let G=(d.def.preSpawnTimeoutSec??bu)*1e3,$=setTimeout(()=>{A.abort(new Error(`timed out before spawn after ${Math.round(G/1e3)}s in step "${p.step??"start"}"`))},G);$.unref?.();let T=()=>{$&&clearTimeout($),$=void 0},w=()=>`task=${p.id} chat=${u}:${l} at=${new Date().toISOString()}`,_;A.signal.addEventListener("abort",()=>{let g=Xe(A.signal).message;/^timed out/.test(g)&&(_=p.step??"start"),this.log(`[${e.agentId}] task ${p.id} aborted in step "${p.step??"start"}" \u2014 ${g} ${w()}`)},{once:!0});let S=g=>{p.step=g,this.log(`[${e.agentId}] step ${g} ${w()}`)},v=(g,m,x=0)=>{if(A.signal.aborted)return Promise.reject(Xe(A.signal));S(g),(g==="agent"||g==="workflow-auto-run")&&(T(),D=Date.now());let M=Date.now(),q=mi(m(),fu[g]??0,g);return fi(q,A.signal,x).then(B=>(P(g,M,"ok"),B),B=>{throw P(g,M,"error"),B instanceof _e&&this.log(`[${e.agentId}] ${B.message}; continuing without it ${w()}`),B})},K=async(g,m,x,M=0)=>{try{return await v(g,m,M)}catch(q){if(q instanceof _e)return x();throw q}},Rn=!1,En=g=>{if(Rn)return;Rn=!0,this.runReleases.delete(p.id),W&&clearTimeout(W),T(),d.activeTasks--;let m=d.runningTasks.findIndex(x=>x.id===p.id);m!==-1&&d.runningTasks.splice(m,1),this.runningContexts.delete(p.id),this.taskAborts.delete(p.id),b.done=!0,b.endedAt=new Date;for(let x of b.subscribers)try{x(`
136
136
  [task finished]
137
- `)}catch{}b.subscribers.clear(),setTimeout(()=>this.taskOutputs.delete(p.id),hu).unref?.();try{let S=b.endedAt,M={id:p.id,agentId:e.agentId,channel:p.channel,chatId:p.chatId,sender:p.sender,message:e.message||"",startedAt:p.startedAt.toISOString(),endedAt:S.toISOString(),durationMs:S.getTime()-p.startedAt.getTime(),ok:!g?.error,error:g?.error,..._?{status:"timeout",step:_}:{},responseText:g?.content||"",transcript:b.buffer};this.persistTaskRecord(M);let q=(M.responseText||M.error||"").trim();if(q){let B=q.split(/\r?\n/)[0].slice(0,140);this.lastSummaries.set(e.agentId,{text:B,at:S,ok:M.ok})}}catch(S){this.log(`[${e.agentId}] task history persist failed: ${S?.message}`)}this.messageQueue.markDone(e.agentId,u,l).then(S=>{if(S.length===0)return;this.log(`[${e.agentId}] flushing ${S.length} queued message(s) after task=${p.id} chat=${u}:${l} at=${new Date().toISOString()}`);let M=Date.now();Y().emit("task:queue-flushed",{agentId:e.agentId,channel:u,chatId:l,flushedAt:M,count:S.length,at:new Date().toISOString()});let q=()=>Y().emit("task:queue-ended",{agentId:e.agentId,channel:u,chatId:l,flushedAt:M,at:new Date().toISOString()});for(let B of S){let ee=B.originalContext||{channel:B.channel,sender:B.sender,chatId:B.chatId};this.execute({message:B.text,agentId:e.agentId,context:ee,queuedAt:B.queuedAt??B.timestamp}).then(te=>(Ue(te.error)||q(),this.postQueuedResponseToChannel(e.agentId,ee,te)),te=>{throw q(),te}).catch(te=>{this.log(`[${e.agentId}] queued message failed: ${te.message}`)})}}).catch(S=>{Y().emit("task:queue-ended",{agentId:e.agentId,channel:u,chatId:l,flushedAt:Date.now(),at:new Date().toISOString()}),this.log(`[${e.agentId}] queue flush failed: ${S.message}`)})};this.runReleases.set(p.id,Rn),this.messageQueue.markRunning(e.agentId,u,l),this.log(`[${e.agentId}] executing task (${d.activeTasks}/${d.def.maxConcurrent}) ${w()}`);let y=e.context?.channel||"api",{evaluateRequest:$i,selectRequestContext:Ci}=await import("./request-planner-GDXSBNN4.js"),En=K("request-gate",()=>$i(e.message,e.agentId,y),()=>({active:!1,preprocess:!1})),Dt=!1;En.then(()=>{Dt=!0},()=>{Dt=!0});let v=l,Ot=e.context?.sender||"User",se=d.def.tier==="codex-cli",Ee=Ho(this.config.session,y,d.def.tier),Ze=Bo(this.config.session),De=Ee==="lean"&&Ze.contextOnDemand;e.freshSession&&(this.sessions.clearSession(e.agentId,y,v),this.log(`[${e.agentId}] freshSession=true \u2192 cleared session history for ${y}:${v}`),Y().emit("session:rotated",{agentId:e.agentId,channel:y,chatId:v,reason:"stale",at:new Date().toISOString()})),e.freshSession||await K("seed-history",()=>this.sessions.seedIfEmpty(e.agentId,y,v,e.seedHistory),()=>{});let Mi=[...this.sessions.getSession(e.agentId,y,v).messages].reverse().find(g=>g.role==="agent")?.content;gi({agent:e.agentId,channel:y,chatId:v,message:e.message,previousReply:Mi,taskId:E}),this.sessions.addUserMessage(e.agentId,y,v,Ot,e.message);let Dn=Date.now();Y().emit("task:started",{agentId:e.agentId,channel:y,chatId:v,messagePreview:(e.message||"").slice(0,200),fullMessage:e.message||"",requestText:e.requestText,at:new Date(Dn).toISOString(),taskId:E,resumeOrigin:ro(e.origin??{kind:"direct",context:e.context,model:e.model,autonomy:e.autonomy}),resumeAttempt:e.resumeAttempt??0,resumedFrom:e.resumedFrom,sender:Jt(e.context),...I?{person:I}:{},humanRoot:Gt(e.context),pickup:ls(e.context),operator:gs(e.context)});let V,Nt,On=this.classifier;if(On&&y!=="a2a"&&!se){x("classify");let g=Date.now();Nt=On.classify({text:e.message,channel:y,sender:e.context?.sender,chatId:v,agentId:e.agentId}).then(m=>{V=m||void 0,V?.path?.length&&(p.intentPath=V.path.slice()),P("classify",g,"ok")},m=>{this.log(`[classifier] classify failed for ${e.agentId}: ${m?.message||m}`),P("classify",g,"error")})}let Nn=async g=>{if(!Nt)return;let m;await Promise.race([Nt,new Promise(S=>{m=setTimeout(S,g),m.unref?.()})]),m&&clearTimeout(m)};await Nn(du);let Oe=this.config.workflows?.matching,Se;if(this.config.workflows?.enabled&&Oe?.enabled&&!i)try{let g=new Vs({baseDir:J(process.cwd(),this.config.workflows.dir)}),m=Zs({agentId:e.agentId,channel:y,message:e.message,intentPath:V?.path},g.list());m&&m.confidence>=Oe.suggestThreshold&&(this.log(`[${e.agentId}] workflow match ${m.workflow.id} confidence=${m.confidence.toFixed(2)} mode=${Oe.mode} reasons=${m.reasons.join(",")||"n/a"}`),Oe.mode==="auto"&&m.confidence>=Oe.autoRunThreshold&&(this.workflowAutoRunner?Se={workflowId:m.workflow.id,confidence:m.confidence}:this.log(`[${e.agentId}] workflow auto-run requested but no runner wired; falling back to agent`)))}catch(g){this.log(`[${e.agentId}] workflow matcher failed (non-fatal): ${g?.message||g}`)}let Pi=this.wikiHub.getAgentWiki(e.agentId),Ln=this.memoryStore.findRelevant(e.message,e.agentId,se?3:8),Fn=this.memoryStore.buildContext(Ln),Un=this.memoryStore.contextFacts(Ln),_i=this.patternStore.findRelevant(e.message,e.agentId,5),Ri=this.patternStore.buildContext(_i),Hn="";if(!se)try{let{loadLocalSkills:g,getAutoInjectSkills:m}=await import("./loader-YFVSSYSL.js"),S=await k("skills",()=>g(d.def.workspace)),M=e.personLimits?.skills??[],q=M.length?S.filter(B=>!M.some(ee=>Le(ee,B.frontmatter.name))):S;Hn=m(q,e.message)}catch{}let N=d.def.tier==="claude-code"?this.sessions.getClaudeSessionId(e.agentId,y,v):d.def.tier==="codex-cli"?this.sessions.getCodexSessionId(e.agentId,y,v):d.def.tier==="opencode"?this.sessions.getOpenCodeSessionId(e.agentId,y,v):void 0;if(N&&this.sessions.isSessionStale(e.agentId,y,v)&&(this.log(`[${e.agentId}] session stale for ${y}:${v}, starting fresh`),d.def.tier==="claude-code"&&this.captureRotationMemoAsync(e.agentId,d.def,N,y,v,"stale"),this.sessions.clearClaudeSessionId(e.agentId,y,v),Y().emit("session:rotated",{agentId:e.agentId,channel:y,chatId:v,reason:"stale",at:new Date().toISOString()}),N=void 0),N&&this.sessions.shouldRotateByTierTwo(e.agentId,y,v)){let g=this.sessions.getLastTurnContextTokens(e.agentId,y,v);this.log(`[${e.agentId}] tier-2 rotation for ${y}:${v} (last turn context: ${g} tokens \u2265 ${this.sessions.getTierTwoThresholdTokens(y)})`),d.def.tier==="claude-code"&&this.captureRotationMemoAsync(e.agentId,d.def,N,y,v,"tier-2"),this.sessions.clearClaudeSessionId(e.agentId,y,v),Y().emit("session:rotated",{agentId:e.agentId,channel:y,chatId:v,reason:"tier-2",lastTurnInputTokens:g,at:new Date().toISOString()}),N=void 0}if(N&&this.sessions.shouldRotateByTurns(e.agentId,y,v)){let g=this.sessions.getTurnCount(e.agentId,y,v);this.log(`[${e.agentId}] max-turns rotation for ${y}:${v} (${g} turns \u2265 ${this.sessions.getMaxTurnsPerSession()})`),d.def.tier==="claude-code"&&this.captureRotationMemoAsync(e.agentId,d.def,N,y,v,"max-turns"),this.sessions.clearClaudeSessionId(e.agentId,y,v),Y().emit("session:rotated",{agentId:e.agentId,channel:y,chatId:v,reason:"max-turns",at:new Date().toISOString()}),N=void 0}if(N&&d.def.tier==="claude-code"){let g=this.config.session?.resumeGate;if(g&&g.mode!=="off"){let m=fr({contextTokens:this.sessions.getLastTurnContextTokens(e.agentId,y,v),turnInputTokens:this.sessions.getLastTurnInputTokens(e.agentId,y,v),idleMs:this.sessions.sessionIdleMs(e.agentId,y,v)??0},g);m.rotate&&g.mode==="active"?(this.log(`[${e.agentId}] cost rotation for ${y}:${v}: ${en(m)}`),this.captureRotationMemoAsync(e.agentId,d.def,N,y,v,"cost"),this.sessions.clearClaudeSessionId(e.agentId,y,v),Y().emit("session:rotated",{agentId:e.agentId,channel:y,chatId:v,reason:"cost",lastTurnInputTokens:this.sessions.getLastTurnInputTokens(e.agentId,y,v),at:new Date().toISOString()}),N=void 0):g.mode==="shadow"&&this.log(`[${e.agentId}] resume gate (shadow) for ${y}:${v}: would ${en(m)}`)}}if(N&&d.def.tier==="claude-code"){let g=N;await K("rotate",()=>this.maybeRotateForContinuity(e,d,y,v,g),()=>!1)&&(N=void 0)}try{let g=await k("compact",()=>this.sessions.compactIfNeeded(e.agentId,y,v,this.memoryStore));if(g.compacted){let m=g.qualityScore??"?",S=g.lostEntities?.length??0;if(this.log(`[${e.agentId}] session compacted for ${y}:${v} (quality: ${m}%, ${S} entities lost)`),g.lostEntities?.length&&this.log(`[${e.agentId}] lost entities: ${g.lostEntities.slice(0,5).join(", ")}`),g.drift){let M=g.drift;this.log(`[${e.agentId}] DRIFT DETECTED: score=${M.overallScore} (lexicon=${M.lexiconDecay}, tools=${M.toolShift}, semantic=${M.semanticDrift})`),M.lostWords.length&&this.log(`[${e.agentId}] lost domain words: ${M.lostWords.slice(0,5).join(", ")}`)}}}catch(g){this.log(`[${e.agentId}] compaction failed (non-fatal): ${g.message}`)}let Ei=process.env.AGENTX_CONTEXT_SURGERY==="1",Di=se?{maxMessages:8,maxChars:2400}:Ei&&xi(y,d.def.tier)?{maxMessages:6,maxChars:1800}:void 0,Oi=!N&&!se?Iu(Pi,e.agentId):void 0,et=!N&&!De?this.sessions.buildHistoryContext(e.agentId,y,v,Di):void 0,Ni=N?void 0:this.sessions.getRotationMemo(e.agentId,y,v)??void 0,Bn,jn=[];if(this.config.procedures?.injection?.enabled&&!N&&!se)try{let g=new ze({baseDir:J(process.cwd(),this.config.procedures.dir)}),m=Tn(e.message,g.list(),{limit:this.config.procedures.injection.maxProcedures,minScore:this.config.procedures.injection.minScore});if(m.length>0){Bn=vn(m),jn=m.map(S=>({id:S.procedure.meta.id,title:S.procedure.meta.title}));for(let S of m)this.log(`[${e.agentId}] procedure match ${S.procedure.meta.id} score=${S.score.toFixed(2)} (${S.reasons.join(",")})`)}}catch(g){this.log(`[${e.agentId}] procedure matcher failed (non-fatal): ${g?.message||g}`)}if(he&&he.cat)try{let m=this.sessions.getSession(e.agentId,y,v).messages,S=m[0],M=m[m.length-1],q=et===void 0?`resume=${N?N.slice(0,8):"?"} (no rebuild)`:`fresh history=${et.length}c/${et.split(`
138
- `).length}L`,B=`[${e.agentId}] ${y}:${v} ${q} | session.messages=${m.length}`+(m.length>0?` first=${S.timestamp.slice(11,19)}(${S.role}:${(S.content||"").slice(0,40).replace(/\n/g," ")}) last=${M.timestamp.slice(11,19)}(${M.role}:${(M.content||"").slice(0,40).replace(/\n/g," ")})`:"");he.cat("context",B)}catch(g){he.cat("context",`[${e.agentId}] context-diag error: ${g?.message??g}`)}let qn;if(d.def.contextReferences&&!N)try{let g=d.def.workspace,m=this.referencesCache.get(g);if(!m){let[M,q]=await k("references",()=>Promise.all([Xt(d.def.workspace),Yt(d.def.workspace)]));if(M.byId.size===0&&q.recipes.length===0){let[B,ee]=await k("references",()=>Promise.all([Xt(process.cwd()),Yt(process.cwd())]));m={refs:B,recipes:ee}}else m={refs:M,recipes:q};this.referencesCache.set(g,m)}let S=qs({agentId:e.agentId,intentTags:V?.path,message:e.message},m.recipes,m.refs);S.cards.length>0&&(qn=Bs(S.cards,500*4)),S.unresolvedIds.length>0&&this.log(`[${e.agentId}] references: unresolved ids: ${S.unresolvedIds.join(", ")}`)}catch(g){this.log(`[${e.agentId}] references resolver failed (non-fatal): ${g?.message||g}`)}let Wn=De?"":this.sessions.getCrossSessionSummary(e.agentId,y,v,e.message),Gn,tt=Zr(e.message);if(tt)try{let g=this.sessions.recallTurns({agentId:e.agentId,channel:y,chatId:v,lookbackDays:tt.lookbackDays,limit:12});if(g.turns.length>0){let m=[`[Long-memory recall \u2014 last ${tt.lookbackDays}d on this chat (cue-triggered)]`],S=[...g.turns].sort((M,q)=>M.ts.localeCompare(q.ts));for(let M of S){let q=M.ts.slice(11,16)+" "+M.day,B=M.role==="user"?M.senderName||"User":M.senderName||"Agent";m.push(`${q} ${B}: ${M.content}`)}g.hasMore&&m.push(`[\u2026${g.totalScanned-g.turns.length}+ older turns available \u2014 call /recall with before=${g.oldestTs} to walk further back]`),m.push("[End of long-memory recall \u2014 respond to the latest message above]"),Gn=m.join(`
139
- `),this.log(`[${e.agentId}] long-memory recall fired: lookback=${tt.lookbackDays}d, turns=${g.turns.length}, scanned=${g.totalScanned}`)}}catch(g){this.log(`[${e.agentId}] long-memory recall failed (non-fatal): ${g.message}`)}let Li=se?"layered":e.contextStrategy??d.def.contextStrategy??this.config.session.contextStrategy??"layered",Kn,Jn,Qn=!1;Dt||x("request-gate");let me=await En;if(me.arm==="holdout"&&this.log(`[${e.agentId}] request-gate holdout: skipping Jev preprocessing for this turn`),Li==="planner"&&!me.active&&!De&&y!=="voice"&&y!=="desktop"){try{let{planContext:g}=await import("./context-planner-BKHPKDX5.js"),m=await k("plan-context",()=>g({agentId:e.agentId,channel:y,chatId:v,message:e.message,sessions:this.sessions,memoryStore:this.memoryStore}));m?(Qn=!0,Kn=m.sessionHistory,Fn=m.memoryContext,Un=m.memoryFacts,Wn=m.crossChatContext,Jn=m.debug,this.log(`[${e.agentId}] planner: turns=${m.debug.recentTurns}, mem=${m.debug.memoryIncluded?"yes":"no"}, xchat=${m.debug.crossChatIncluded?"yes":"no"} (${m.debug.planLatencyMs}ms) \u2014 ${m.debug.reasoning??""}`)):this.log(`[${e.agentId}] planner returned null \u2014 falling back to layered (keeping --resume for continuity)`)}catch(g){this.log(`[${e.agentId}] planner failed (non-fatal): ${g.message} \u2014 falling back to layered (keeping --resume for continuity)`)}Qn&&N&&(this.sessions.clearClaudeSessionId(e.agentId,y,v),N=void 0)}let Lt=`${e.agentId}:${y}:${v}`,nt=As(e.message);nt&&(nt==="default"?(this.activeSouls.delete(Lt),this.log(`[${e.agentId}] Soul reset to default`)):(this.activeSouls.set(Lt,nt),this.log(`[${e.agentId}] Soul switched to: ${nt}`)));let Fi=this.activeSouls.get(Lt),Ui=vs(d.def.workspace,Fi),Hi=ks(Ui),Bi=this.agentMemory.indexMarkdown(e.agentId,this.config.session.memoryIndexMaxChars),ji=mu(d.def.tier),qi=Au(d.def.richMessages,y),Wi=d.def.tier==="claude-code"&&(Ee!=="lean"||jo(Ze)),zn="";if(d.def.workspace&&!Wi){let g=J(d.def.workspace,"CLAUDE.md");if(ne(g))try{let m=Ye(g,"utf-8");zn=`[Project CLAUDE.md]
137
+ `)}catch{}b.subscribers.clear(),setTimeout(()=>this.taskOutputs.delete(p.id),yu).unref?.();try{let x=b.endedAt,M={id:p.id,agentId:e.agentId,channel:p.channel,chatId:p.chatId,sender:p.sender,message:e.message||"",startedAt:p.startedAt.toISOString(),endedAt:x.toISOString(),durationMs:x.getTime()-p.startedAt.getTime(),ok:!g?.error,error:g?.error,..._?{status:"timeout",step:_}:{},responseText:g?.content||"",transcript:b.buffer};this.persistTaskRecord(M);let q=(M.responseText||M.error||"").trim();if(q){let B=q.split(/\r?\n/)[0].slice(0,140);this.lastSummaries.set(e.agentId,{text:B,at:x,ok:M.ok})}}catch(x){this.log(`[${e.agentId}] task history persist failed: ${x?.message}`)}this.messageQueue.markDone(e.agentId,u,l).then(x=>{if(x.length===0)return;this.log(`[${e.agentId}] flushing ${x.length} queued message(s) after task=${p.id} chat=${u}:${l} at=${new Date().toISOString()}`);let M=Date.now();Y().emit("task:queue-flushed",{agentId:e.agentId,channel:u,chatId:l,flushedAt:M,count:x.length,at:new Date().toISOString()});let q=()=>Y().emit("task:queue-ended",{agentId:e.agentId,channel:u,chatId:l,flushedAt:M,at:new Date().toISOString()});for(let B of x){let ee=B.originalContext||{channel:B.channel,sender:B.sender,chatId:B.chatId};this.execute({message:B.text,agentId:e.agentId,context:ee,queuedAt:B.queuedAt??B.timestamp}).then(te=>(Ue(te.error)||q(),this.postQueuedResponseToChannel(e.agentId,ee,te)),te=>{throw q(),te}).catch(te=>{this.log(`[${e.agentId}] queued message failed: ${te.message}`)})}}).catch(x=>{Y().emit("task:queue-ended",{agentId:e.agentId,channel:u,chatId:l,flushedAt:Date.now(),at:new Date().toISOString()}),this.log(`[${e.agentId}] queue flush failed: ${x.message}`)})};this.runReleases.set(p.id,En),this.messageQueue.markRunning(e.agentId,u,l),this.log(`[${e.agentId}] executing task (${d.activeTasks}/${d.def.maxConcurrent}) ${w()}`);let y=e.context?.channel||"api",{evaluateRequest:Ci,selectRequestContext:Mi}=await import("./request-planner-E2Q5O66N.js"),Dn=K("request-gate",()=>Ci(e.message,e.agentId,y),()=>({active:!1,preprocess:!1})),Ot=!1;Dn.then(()=>{Ot=!0},()=>{Ot=!0});let k=l,Nt=e.context?.sender||"User",se=d.def.tier==="codex-cli",Ee=Bo(this.config.session,y,d.def.tier),Ze=jo(this.config.session),De=Ee==="lean"&&Ze.contextOnDemand;e.freshSession&&(this.sessions.clearSession(e.agentId,y,k),this.log(`[${e.agentId}] freshSession=true \u2192 cleared session history for ${y}:${k}`),Y().emit("session:rotated",{agentId:e.agentId,channel:y,chatId:k,reason:"stale",at:new Date().toISOString()}));let et=this.sessions.sessionIdleMs(e.agentId,y,k);e.freshSession||await K("seed-history",()=>this.sessions.seedIfEmpty(e.agentId,y,k,e.seedHistory),()=>{});let Pi=[...this.sessions.getSession(e.agentId,y,k).messages].reverse().find(g=>g.role==="agent")?.content;pi({agent:e.agentId,channel:y,chatId:k,message:e.message,previousReply:Pi,taskId:E}),this.sessions.addUserMessage(e.agentId,y,k,Nt,e.message);let On=Date.now();Y().emit("task:started",{agentId:e.agentId,channel:y,chatId:k,messagePreview:(e.message||"").slice(0,200),fullMessage:e.message||"",requestText:e.requestText,at:new Date(On).toISOString(),taskId:E,resumeOrigin:oo(e.origin??{kind:"direct",context:e.context,model:e.model,autonomy:e.autonomy}),resumeAttempt:e.resumeAttempt??0,resumedFrom:e.resumedFrom,sender:Qt(e.context),...I?{person:I}:{},humanRoot:Kt(e.context),pickup:gs(e.context),operator:ps(e.context)});let V,Lt,Nn=this.classifier;if(Nn&&y!=="a2a"&&!se){S("classify");let g=Date.now();Lt=Nn.classify({text:e.message,channel:y,sender:e.context?.sender,chatId:k,agentId:e.agentId}).then(m=>{V=m||void 0,V?.path?.length&&(p.intentPath=V.path.slice()),P("classify",g,"ok")},m=>{this.log(`[classifier] classify failed for ${e.agentId}: ${m?.message||m}`),P("classify",g,"error")})}let Ln=async g=>{if(!Lt)return;let m;await Promise.race([Lt,new Promise(x=>{m=setTimeout(x,g),m.unref?.()})]),m&&clearTimeout(m)};await Ln(cu);let Oe=this.config.workflows?.matching,Se;if(this.config.workflows?.enabled&&Oe?.enabled&&!i)try{let g=new Zs({baseDir:J(process.cwd(),this.config.workflows.dir)}),m=er({agentId:e.agentId,channel:y,message:e.message,intentPath:V?.path},g.list());m&&m.confidence>=Oe.suggestThreshold&&(this.log(`[${e.agentId}] workflow match ${m.workflow.id} confidence=${m.confidence.toFixed(2)} mode=${Oe.mode} reasons=${m.reasons.join(",")||"n/a"}`),Oe.mode==="auto"&&m.confidence>=Oe.autoRunThreshold&&(this.workflowAutoRunner?Se={workflowId:m.workflow.id,confidence:m.confidence}:this.log(`[${e.agentId}] workflow auto-run requested but no runner wired; falling back to agent`)))}catch(g){this.log(`[${e.agentId}] workflow matcher failed (non-fatal): ${g?.message||g}`)}let _i=this.wikiHub.getAgentWiki(e.agentId),Fn=this.memoryStore.findRelevant(e.message,e.agentId,se?3:8),Un=this.memoryStore.buildContext(Fn),Hn=this.memoryStore.contextFacts(Fn),Ri=this.patternStore.findRelevant(e.message,e.agentId,5),Ei=this.patternStore.buildContext(Ri),Bn="";if(!se)try{let{loadLocalSkills:g,getAutoInjectSkills:m}=await import("./loader-YFVSSYSL.js"),x=await v("skills",()=>g(d.def.workspace)),M=e.personLimits?.skills??[],q=M.length?x.filter(B=>!M.some(ee=>Le(ee,B.frontmatter.name))):x;Bn=m(q,e.message)}catch{}let N=d.def.tier==="claude-code"?this.sessions.getClaudeSessionId(e.agentId,y,k):d.def.tier==="codex-cli"?this.sessions.getCodexSessionId(e.agentId,y,k):d.def.tier==="opencode"?this.sessions.getOpenCodeSessionId(e.agentId,y,k):void 0;if(N&&this.sessions.isSessionStale(e.agentId,y,k,et)&&(this.log(`[${e.agentId}] session stale for ${y}:${k}, starting fresh`),d.def.tier==="claude-code"&&this.captureRotationMemoAsync(e.agentId,d.def,N,y,k,"stale"),this.sessions.clearClaudeSessionId(e.agentId,y,k),Y().emit("session:rotated",{agentId:e.agentId,channel:y,chatId:k,reason:"stale",at:new Date().toISOString()}),N=void 0),N&&this.sessions.shouldRotateByTierTwo(e.agentId,y,k)){let g=this.sessions.getLastTurnContextTokens(e.agentId,y,k);this.log(`[${e.agentId}] tier-2 rotation for ${y}:${k} (last turn context: ${g} tokens \u2265 ${this.sessions.getTierTwoThresholdTokens(y)})`),d.def.tier==="claude-code"&&this.captureRotationMemoAsync(e.agentId,d.def,N,y,k,"tier-2"),this.sessions.clearClaudeSessionId(e.agentId,y,k),Y().emit("session:rotated",{agentId:e.agentId,channel:y,chatId:k,reason:"tier-2",lastTurnInputTokens:g,at:new Date().toISOString()}),N=void 0}if(N&&this.sessions.shouldRotateByTurns(e.agentId,y,k)){let g=this.sessions.getTurnCount(e.agentId,y,k);this.log(`[${e.agentId}] max-turns rotation for ${y}:${k} (${g} turns \u2265 ${this.sessions.getMaxTurnsPerSession()})`),d.def.tier==="claude-code"&&this.captureRotationMemoAsync(e.agentId,d.def,N,y,k,"max-turns"),this.sessions.clearClaudeSessionId(e.agentId,y,k),Y().emit("session:rotated",{agentId:e.agentId,channel:y,chatId:k,reason:"max-turns",at:new Date().toISOString()}),N=void 0}if(N&&d.def.tier==="claude-code"){let g=this.config.session?.resumeGate;if(g&&g.mode!=="off"){let m=mr({contextTokens:this.sessions.getRawLastTurnContextTokens(e.agentId,y,k),turnInputTokens:this.sessions.getLastTurnInputTokens(e.agentId,y,k),idleMs:et??0},g);if(m.rotate&&g.mode==="active"){this.log(`[${e.agentId}] cost rotation for ${y}:${k}: ${tn(m)}`),this.captureRotationMemoAsync(e.agentId,d.def,N,y,k,"cost");let x=this.sessions.getLastTurnInputTokens(e.agentId,y,k);this.sessions.clearClaudeSessionId(e.agentId,y,k),Y().emit("session:rotated",{agentId:e.agentId,channel:y,chatId:k,reason:"cost",lastTurnInputTokens:x,at:new Date().toISOString()}),N=void 0}else g.mode==="shadow"&&this.log(`[${e.agentId}] resume gate (shadow) for ${y}:${k}: would ${tn(m)}`)}}if(N&&d.def.tier==="claude-code"){let g=N;await K("rotate",()=>this.maybeRotateForContinuity(e,d,y,k,g),()=>!1)&&(N=void 0)}try{let g=await v("compact",()=>this.sessions.compactIfNeeded(e.agentId,y,k,this.memoryStore));if(g.compacted){let m=g.qualityScore??"?",x=g.lostEntities?.length??0;if(this.log(`[${e.agentId}] session compacted for ${y}:${k} (quality: ${m}%, ${x} entities lost)`),g.lostEntities?.length&&this.log(`[${e.agentId}] lost entities: ${g.lostEntities.slice(0,5).join(", ")}`),g.drift){let M=g.drift;this.log(`[${e.agentId}] DRIFT DETECTED: score=${M.overallScore} (lexicon=${M.lexiconDecay}, tools=${M.toolShift}, semantic=${M.semanticDrift})`),M.lostWords.length&&this.log(`[${e.agentId}] lost domain words: ${M.lostWords.slice(0,5).join(", ")}`)}}}catch(g){this.log(`[${e.agentId}] compaction failed (non-fatal): ${g.message}`)}let Di=process.env.AGENTX_CONTEXT_SURGERY==="1",Oi=se?{maxMessages:8,maxChars:2400}:Di&&Si(y,d.def.tier)?{maxMessages:6,maxChars:1800}:void 0,Ni=!N&&!se?Tu(_i,e.agentId):void 0,tt=!N&&!De?this.sessions.buildHistoryContext(e.agentId,y,k,Oi):void 0,Li=N?void 0:this.sessions.getRotationMemo(e.agentId,y,k)??void 0,jn,qn=[];if(this.config.procedures?.injection?.enabled&&!N&&!se)try{let g=new ze({baseDir:J(process.cwd(),this.config.procedures.dir)}),m=vn(e.message,g.list(),{limit:this.config.procedures.injection.maxProcedures,minScore:this.config.procedures.injection.minScore});if(m.length>0){jn=kn(m),qn=m.map(x=>({id:x.procedure.meta.id,title:x.procedure.meta.title}));for(let x of m)this.log(`[${e.agentId}] procedure match ${x.procedure.meta.id} score=${x.score.toFixed(2)} (${x.reasons.join(",")})`)}}catch(g){this.log(`[${e.agentId}] procedure matcher failed (non-fatal): ${g?.message||g}`)}if(he&&he.cat)try{let m=this.sessions.getSession(e.agentId,y,k).messages,x=m[0],M=m[m.length-1],q=tt===void 0?`resume=${N?N.slice(0,8):"?"} (no rebuild)`:`fresh history=${tt.length}c/${tt.split(`
138
+ `).length}L`,B=`[${e.agentId}] ${y}:${k} ${q} | session.messages=${m.length}`+(m.length>0?` first=${x.timestamp.slice(11,19)}(${x.role}:${(x.content||"").slice(0,40).replace(/\n/g," ")}) last=${M.timestamp.slice(11,19)}(${M.role}:${(M.content||"").slice(0,40).replace(/\n/g," ")})`:"");he.cat("context",B)}catch(g){he.cat("context",`[${e.agentId}] context-diag error: ${g?.message??g}`)}let Wn;if(d.def.contextReferences&&!N)try{let g=d.def.workspace,m=this.referencesCache.get(g);if(!m){let[M,q]=await v("references",()=>Promise.all([Yt(d.def.workspace),Vt(d.def.workspace)]));if(M.byId.size===0&&q.recipes.length===0){let[B,ee]=await v("references",()=>Promise.all([Yt(process.cwd()),Vt(process.cwd())]));m={refs:B,recipes:ee}}else m={refs:M,recipes:q};this.referencesCache.set(g,m)}let x=Ws({agentId:e.agentId,intentTags:V?.path,message:e.message},m.recipes,m.refs);x.cards.length>0&&(Wn=js(x.cards,500*4)),x.unresolvedIds.length>0&&this.log(`[${e.agentId}] references: unresolved ids: ${x.unresolvedIds.join(", ")}`)}catch(g){this.log(`[${e.agentId}] references resolver failed (non-fatal): ${g?.message||g}`)}let Gn=De?"":this.sessions.getCrossSessionSummary(e.agentId,y,k,e.message),Kn,nt=eo(e.message);if(nt)try{let g=this.sessions.recallTurns({agentId:e.agentId,channel:y,chatId:k,lookbackDays:nt.lookbackDays,limit:12});if(g.turns.length>0){let m=[`[Long-memory recall \u2014 last ${nt.lookbackDays}d on this chat (cue-triggered)]`],x=[...g.turns].sort((M,q)=>M.ts.localeCompare(q.ts));for(let M of x){let q=M.ts.slice(11,16)+" "+M.day,B=M.role==="user"?M.senderName||"User":M.senderName||"Agent";m.push(`${q} ${B}: ${M.content}`)}g.hasMore&&m.push(`[\u2026${g.totalScanned-g.turns.length}+ older turns available \u2014 call /recall with before=${g.oldestTs} to walk further back]`),m.push("[End of long-memory recall \u2014 respond to the latest message above]"),Kn=m.join(`
139
+ `),this.log(`[${e.agentId}] long-memory recall fired: lookback=${nt.lookbackDays}d, turns=${g.turns.length}, scanned=${g.totalScanned}`)}}catch(g){this.log(`[${e.agentId}] long-memory recall failed (non-fatal): ${g.message}`)}let Fi=se?"layered":e.contextStrategy??d.def.contextStrategy??this.config.session.contextStrategy??"layered",Jn,Qn,zn=!1;Ot||S("request-gate");let me=await Dn;if(me.arm==="holdout"&&this.log(`[${e.agentId}] request-gate holdout: skipping Jev preprocessing for this turn`),Fi==="planner"&&!me.active&&!De&&y!=="voice"&&y!=="desktop"){try{let{planContext:g}=await import("./context-planner-BKHPKDX5.js"),m=await v("plan-context",()=>g({agentId:e.agentId,channel:y,chatId:k,message:e.message,sessions:this.sessions,memoryStore:this.memoryStore}));m?(zn=!0,Jn=m.sessionHistory,Un=m.memoryContext,Hn=m.memoryFacts,Gn=m.crossChatContext,Qn=m.debug,this.log(`[${e.agentId}] planner: turns=${m.debug.recentTurns}, mem=${m.debug.memoryIncluded?"yes":"no"}, xchat=${m.debug.crossChatIncluded?"yes":"no"} (${m.debug.planLatencyMs}ms) \u2014 ${m.debug.reasoning??""}`)):this.log(`[${e.agentId}] planner returned null \u2014 falling back to layered (keeping --resume for continuity)`)}catch(g){this.log(`[${e.agentId}] planner failed (non-fatal): ${g.message} \u2014 falling back to layered (keeping --resume for continuity)`)}zn&&N&&(this.sessions.clearClaudeSessionId(e.agentId,y,k),N=void 0)}let Ft=`${e.agentId}:${y}:${k}`,st=$s(e.message);st&&(st==="default"?(this.activeSouls.delete(Ft),this.log(`[${e.agentId}] Soul reset to default`)):(this.activeSouls.set(Ft,st),this.log(`[${e.agentId}] Soul switched to: ${st}`)));let Ui=this.activeSouls.get(Ft),Hi=ks(d.def.workspace,Ui),Bi=As(Hi),ji=this.agentMemory.indexMarkdown(e.agentId,this.config.session.memoryIndexMaxChars),qi=hu(d.def.tier),Wi=$u(d.def.richMessages,y),Gi=d.def.tier==="claude-code"&&(Ee!=="lean"||qo(Ze)),Xn="";if(d.def.workspace&&!Gi){let g=J(d.def.workspace,"CLAUDE.md");if(ne(g))try{let m=Ye(g,"utf-8");Xn=`[Project CLAUDE.md]
140
140
  ${m.length>4e3?m.slice(0,4e3)+`
141
141
 
142
- [CLAUDE.md truncated to 4KB]`:m}`}catch{}}let st=e.context?.runbookPath,Ft=[];if(st&&ne(st)){let g=e.context?.runbookFiles&&e.context.runbookFiles.length>0?e.context.runbookFiles:["CLAUDE.md","AGENTS.md","DEPLOY.md","RUNBOOK.md"],m=0,S=4e3,M=16e3;for(let q of g){if(m>=M)break;let B=J(st,q);if(ne(B))try{let ee=Ye(B,"utf-8"),te=ee.length>S?ee.slice(0,S)+`
142
+ [CLAUDE.md truncated to 4KB]`:m}`}catch{}}let rt=e.context?.runbookPath,Ut=[];if(rt&&ne(rt)){let g=e.context?.runbookFiles&&e.context.runbookFiles.length>0?e.context.runbookFiles:["CLAUDE.md","AGENTS.md","DEPLOY.md","RUNBOOK.md"],m=0,x=4e3,M=16e3;for(let q of g){if(m>=M)break;let B=J(rt,q);if(ne(B))try{let ee=Ye(B,"utf-8"),te=ee.length>x?ee.slice(0,x)+`
143
143
 
144
- [${q} truncated to ${S} bytes]`:ee;Ft.push(`[Project Runbook \u2014 ${q} from ${st}]
145
- ${te}`),m+=te.length}catch{}}}let Gi=Ft.length>0?Ft.join(`
144
+ [${q} truncated to ${x} bytes]`:ee;Ut.push(`[Project Runbook \u2014 ${q} from ${rt}]
145
+ ${te}`),m+=te.length}catch{}}}let Ki=Ut.length>0?Ut.join(`
146
146
 
147
- `):"",Ut=[d.def.systemPrompt||"",ji,qi,zn,Gi,Hi||"",Bi||""].filter(g=>g.trim().length>0).join(`
147
+ `):"",Ht=[d.def.systemPrompt||"",qi,Wi,Xn,Ki,Bi||"",ji||""].filter(g=>g.trim().length>0).join(`
148
148
 
149
- `)||void 0,Ht={channel:y,chatId:v,channelScope:e.context?.group?"group":y==="gitlab"?"project":"personal",groupName:e.context?.group,agentId:e.agentId,agentName:d.def.name,agentHandle:this.getChannelHandle(e.agentId,y),systemPrompt:d.def.systemPrompt,sender:Ot,senderId:e.context?.senderId,senderUsername:e.context?.senderUsername,landscape:se||De||xi(y,d.def.tier)?void 0:this.landscape?.getForAgent(e.agentId),channelMeta:e.context?.channelMeta,mediaPath:e.context?.mediaPath,mediaType:e.context?.mediaType,replyToText:e.context?.replyToText,patternContext:se?void 0:Ri||void 0,procedureContext:Bn,references:qn,skillInjection:Hn||void 0,groupHistory:(e.context?.group,void 0),sessionHistory:Kn??et,memoryContext:Fn||void 0,crossChatContext:Wn||void 0,longMemoryRecall:Gn||void 0,contextOnDemand:De&&!N?Jo(y,v):void 0,wikiContext:Oi,handoverNote:this.buildHandoverNote(e.agentId,y,v),rotationMemo:Ni,eventDigest:N?void 0:Su(e.agentId,this.config.agents[e.agentId]?.subscriptions??d.def.subscriptions),attachHint:(()=>{let g=tr(y,!N,d.def.richMessages);return g?Tu(d.def.workspace,g):void 0})(),intent:V?{path:V.path,pathLabel:V.pathLabel,pathId:V.pathId,axes:V.axes,leaf:V.leaf,status:V.status}:void 0,message:e.message},rt=e.model?void 0:Ss({tier:d.def.tier,channel:y,eventActions:e.context?.channelMeta?.eventActions,triage:this.config.session.triage,isFollowUp:!!N,sessionIdleMs:this.sessions.sessionIdleMs(e.agentId,y,v)});rt?.downgraded&&this.log(`[${e.agentId}] ${rt.reason}`);let Xn=xs(d.def.tier,this.config.decisions.routing),Yn=rt?.downgraded?Promise.resolve(rt.model):!e.model&&Xn&&(!me.active||me.preprocess)?(async()=>{try{let{routeTaskModel:g}=await import("./routing-OKDZ4VYH.js"),m=await k("route-model",()=>g({message:e.message,agent:e.agentId,channel:y,isFollowUp:!!N,sessionIdleMs:this.sessions.sessionIdleMs(e.agentId,y,v),cheapModel:Xn}));if(m.downgraded)return this.log(`[${e.agentId}] ${m.reason}`),m.model}catch{}})():Promise.resolve(void 0),Vn=!1;Yn.then(()=>{Vn=!0});let ot=me.active&&me.preprocess?await K("select-context",()=>Ci(Ht),()=>({input:Ht,excluded:[]})):{input:Ht,excluded:[]};ot.excluded.length&&this.log(`[${e.agentId}] request-context excluded: ${ot.excluded.join(", ")}`);let it=so(ot.input,se?{totalBudget:1800,layerBudgets:{channel:180,scope:100,identity:120,references:250,intent:80,artifacts:250,memory:250,history:450,"cross-chat":200,"long-memory":350,handover:120}}:void 0),Ki=Ns(it,{memory:Un,procedures:jn,wikiContext:ot.input.wikiContext}),Bt=(it?.length??0)+(Ut?.length??0)+(e.message?.length??0),at={history:it?.length??0,sysPrompt:Ut?.length??0,message:e.message?.length??0},Zn=Ro(e.agentId,y,v);Eo(Zn,Bt,at);let es=Do(Zn);es&&this.log(`[${e.agentId}] ${es}`),Bt>16e3&&this.log(`[${e.agentId}] large context for ${y}:${v}: ${Bt} bytes (history=${at.history}, sysPrompt=${at.sysPrompt}, message=${at.message})`),Vn||x("route-model");let ts=await Yn,ns=d.def.tier!=="claude-code"?void 0:Ee==="lean"?Wo(d.def.workspace,Ze,void 0,y):Ko(d.def.workspace);Ee==="lean"&&!N&&this.log(`[${e.agentId}] session profile for ${y}: ${Qo(Ee,Ze,y)}`);let ss=d.def.tier==="claude-code"&&!N?gr({message:e.message??"",agent:e.agentId,channel:y,agentPrompt:d.def.systemPrompt??null,taskId:E},g=>this.log(g)):void 0,Ji={...e,systemPromptAppend:Ut,...ns?{claudeArgs:ns}:{},...ts?{model:ts}:{}},re,rs=!1,os=ci({agent:e.agentId,request:e.message,taskId:E,budgetMinutes:d.def.maxExecutionMinutes??20}),Qi=j;j=g=>{os.observe(g),Qi?.(g)};try{let g=this.workflowAutoRunner;if(Se&&g){let U=Se;try{let Q=await k("workflow-auto-run",()=>g({workflowId:U.workflowId,agentId:e.agentId,channel:y,chatId:v,message:e.message,payload:{message:e.message,agentId:e.agentId,channel:y,chatId:v,senderId:e.context?.senderId,senderUsername:e.context?.senderUsername,intentPath:V?.path,matchedWorkflowId:U.workflowId,matchConfidence:U.confidence}}));return this.log(`[${e.agentId}] workflow auto-run started ${Se.workflowId} run=${Q.runId||"?"}; agent execution skipped \u2014 workflow owns the reply`),re={content:"",duration:0,metadata:{handledByWorkflow:Se.workflowId,workflowRunId:Q.runId,workflowMatchConfidence:Se.confidence}},re}catch(Q){this.log(`[${e.agentId}] workflow auto-run failed; falling back to agent: ${Q?.message||Q}`)}}let m=()=>{if(d.def.tier!=="claude-code")return null;x("dispatch-gate");let U=d.def.persistentProcess?ht():null,Q=U!=null&&U.hasLive({agentId:e.agentId,channel:y,chatId:v}),ce=!!N||Q,oe=[yo(ce),Po(ce,void 0,e.model||d.def.model)].find(ct=>ct&&ct.abort);if(oe){this.log(`[${e.agentId}] skipping cold dispatch \u2014 ${oe.reason}`);let ct={content:"",error:oe.message,duration:0};if(!t){b.buffer=`[error] ${oe.message}`;for(let Xi of b.subscribers)try{Xi(b.buffer)}catch{}}return ct}Io();let Ne=_o();return Ne&&this.log(`[${e.agentId}] ${Ne}`),null},S=this.planCloudSession(d.def,e);if(S.route==="local"){let U=m();if(U)return d.errors++,re=U,U}let M=d.def.tier==="claude-code",q=M?t:(U,Q)=>{U&&R(U),t&&t(U,Q)},B=!1,ee=M?s:U=>{U&&(B?R(U):(R(`\u{1F4AD} ${U}`),B=!0)),s&&s(U)},te=()=>{B&&(R(`
150
- `),B=!1)},zi=M?q:q?(U,Q)=>{te(),q(U,Q)}:void 0,C=await k("agent",async()=>{if(S.route!=="local"){let U=await this.runCloudSession(d.def,e,S,E);if(U)return U;let Q=m();if(Q)return Q}return Xr(d.def,Ji,this.providers,zi,it,N,j,A.signal,ee)},yu);if(!C.error){let U=vu(d.def.toolUseRequired,O);if(U){let Q=Array.from(O.entries()).map(([ce,dt])=>`${ce}=${dt}`).join(", ")||"none";C.error=`tool_required_not_called: ${U} (invoked: ${Q})`,C.content="",this.log(`[${e.agentId}] tool-use contract violation \u2014 required ${U}, observed ${Q}`)}}ss&&pr(ss,{toolUses:O,eventsSeen:L,error:C.error,agentId:e.agentId},U=>this.log(U));let jt=this.interruptedRuns.get(p.id);jt&&(C.content="",C.error=jt,C.errorKind="interrupted"),re=C;let de=C.usage?Ds(C.usage):void 0;if(rs=!0,Y().emit("task:completed",{taskId:E,agentId:e.agentId,channel:y,chatId:v,durationMs:Date.now()-Dn,error:C.error||void 0,errorKind:C.error?C.errorKind:void 0,interrupted:jt?!0:void 0,inputTokens:de?.inputTokens,outputTokens:de?.outputTokens,cacheReadTokens:de?.cacheReadTokens,cacheCreateTokens:de?.cacheCreateTokens,tier2InputTokens:de?.tier2InputTokens,tier2OutputTokens:de?.tier2OutputTokens,tier2CacheReadTokens:de?.tier2CacheReadTokens,tier2CacheCreateTokens:de?.tier2CacheCreateTokens,resumed:!!N,resumeSessionId:N||void 0,jevArm:me.arm,numTurns:C.numTurns,injectedContext:Ki,finalResponse:C.content||void 0,billedModel:C.billedModel||d.def.model||void 0,at:new Date().toISOString()}),!t&&(C.content||C.error)){let U=C.error?`[error] ${C.error}`:C.content;b.buffer=U;for(let Q of b.subscribers)try{Q(U)}catch{}}if(C.error)d.errors++,this.log(`[${e.agentId}] error: ${C.error}`);else{if(this.sessions.addAgentMessage(e.agentId,y,v,C.content),li({agent:e.agentId,channel:y,chatId:v,request:e.message,reply:C.content,taskId:E}),C.claudeSessionId&&this.sessions.setClaudeSessionId(e.agentId,y,v,C.claudeSessionId),C.codexSessionId&&this.sessions.setCodexSessionId(e.agentId,y,v,C.codexSessionId),C.opencodeSessionId&&this.sessions.setOpenCodeSessionId(e.agentId,y,v,C.opencodeSessionId),(C.claudeSessionId||C.codexSessionId||C.opencodeSessionId)&&C.usage&&this.sessions.recordTurnUsage(e.agentId,y,v,C.usage,C.contextTokens),C.usage){let oe=C.contextTokens,Ne=(C.usage.inputTokens||0)+(C.usage.cacheReadTokens||0)+(C.usage.cacheCreateTokens||0);(oe??Ne)>=this.sessions.getTierTwoThresholdTokens(y)&&this.log(`[${e.agentId}] TIER-2 HIT on ${y}:${v}: context=${oe??"n/a"} tokens (cumulative turn total=${Ne}) \u2014 next turn will rotate`)}if(Ms({channel:y,content:`User: ${e.message}`,responseLength:C.content.length}).capture){await Nn(cu);try{let oe=`${e.agentId}-${Date.now().toString(36)}`;this.wikiHub.getSharedStore().addEntry({id:oe,date:new Date().toISOString().slice(0,10),agentId:e.agentId,source:y,sourceContext:e.context?.group||e.context?.sender,content:`User: ${e.message}
149
+ `)||void 0,Bt={channel:y,chatId:k,channelScope:e.context?.group?"group":y==="gitlab"?"project":"personal",groupName:e.context?.group,agentId:e.agentId,agentName:d.def.name,agentHandle:this.getChannelHandle(e.agentId,y),systemPrompt:d.def.systemPrompt,sender:Nt,senderId:e.context?.senderId,senderUsername:e.context?.senderUsername,landscape:se||De||Si(y,d.def.tier)?void 0:this.landscape?.getForAgent(e.agentId),channelMeta:e.context?.channelMeta,mediaPath:e.context?.mediaPath,mediaType:e.context?.mediaType,replyToText:e.context?.replyToText,patternContext:se?void 0:Ei||void 0,procedureContext:jn,references:Wn,skillInjection:Bn||void 0,groupHistory:(e.context?.group,void 0),sessionHistory:Jn??tt,memoryContext:Un||void 0,crossChatContext:Gn||void 0,longMemoryRecall:Kn||void 0,contextOnDemand:De&&!N?Qo(y,k):void 0,wikiContext:Ni,handoverNote:this.buildHandoverNote(e.agentId,y,k),rotationMemo:Li,eventDigest:N?void 0:Iu(e.agentId,this.config.agents[e.agentId]?.subscriptions??d.def.subscriptions),attachHint:(()=>{let g=nr(y,!N,d.def.richMessages);return g?vu(d.def.workspace,g):void 0})(),intent:V?{path:V.path,pathLabel:V.pathLabel,pathId:V.pathId,axes:V.axes,leaf:V.leaf,status:V.status}:void 0,message:e.message},ot=e.model?void 0:Is({tier:d.def.tier,channel:y,eventActions:e.context?.channelMeta?.eventActions,triage:this.config.session.triage,isFollowUp:!!N,sessionIdleMs:N?et:null});ot?.downgraded&&this.log(`[${e.agentId}] ${ot.reason}`);let Yn=Ss(d.def.tier,this.config.decisions.routing),Vn=ot?.downgraded?Promise.resolve(ot.model):!e.model&&Yn&&(!me.active||me.preprocess)?(async()=>{try{let{routeTaskModel:g}=await import("./routing-KBUZON5R.js"),m=await v("route-model",()=>g({message:e.message,agent:e.agentId,channel:y,isFollowUp:!!N,sessionIdleMs:N?et:null,cheapModel:Yn}));if(m.downgraded)return this.log(`[${e.agentId}] ${m.reason}`),m.model}catch{}})():Promise.resolve(void 0),Zn=!1;Vn.then(()=>{Zn=!0});let it=me.active&&me.preprocess?await K("select-context",()=>Mi(Bt),()=>({input:Bt,excluded:[]})):{input:Bt,excluded:[]};it.excluded.length&&this.log(`[${e.agentId}] request-context excluded: ${it.excluded.join(", ")}`);let at=ro(it.input,se?{totalBudget:1800,layerBudgets:{channel:180,scope:100,identity:120,references:250,intent:80,artifacts:250,memory:250,history:450,"cross-chat":200,"long-memory":350,handover:120}}:void 0),Ji=Ls(at,{memory:Hn,procedures:qn,wikiContext:it.input.wikiContext}),jt=(at?.length??0)+(Ht?.length??0)+(e.message?.length??0),dt={history:at?.length??0,sysPrompt:Ht?.length??0,message:e.message?.length??0},es=Eo(e.agentId,y,k);Do(es,jt,dt);let ts=Oo(es);ts&&this.log(`[${e.agentId}] ${ts}`),jt>16e3&&this.log(`[${e.agentId}] large context for ${y}:${k}: ${jt} bytes (history=${dt.history}, sysPrompt=${dt.sysPrompt}, message=${dt.message})`),Zn||S("route-model");let ns=await Vn,ss=d.def.tier!=="claude-code"?void 0:Ee==="lean"?Go(d.def.workspace,Ze,void 0,y):Jo(d.def.workspace);Ee==="lean"&&!N&&this.log(`[${e.agentId}] session profile for ${y}: ${zo(Ee,Ze,y)}`);let rs=d.def.tier==="claude-code"&&!N?pr({message:e.message??"",agent:e.agentId,channel:y,agentPrompt:d.def.systemPrompt??null,taskId:E},g=>this.log(g)):void 0,Qi={...e,systemPromptAppend:Ht,...ss?{claudeArgs:ss}:{},...ns?{model:ns}:{}},re,os=!1,is=ui({agent:e.agentId,request:e.message,taskId:E,budgetMinutes:d.def.maxExecutionMinutes??20}),zi=j;j=g=>{is.observe(g),zi?.(g)};try{let g=this.workflowAutoRunner;if(Se&&g){let U=Se;try{let Q=await v("workflow-auto-run",()=>g({workflowId:U.workflowId,agentId:e.agentId,channel:y,chatId:k,message:e.message,payload:{message:e.message,agentId:e.agentId,channel:y,chatId:k,senderId:e.context?.senderId,senderUsername:e.context?.senderUsername,intentPath:V?.path,matchedWorkflowId:U.workflowId,matchConfidence:U.confidence}}));return this.log(`[${e.agentId}] workflow auto-run started ${Se.workflowId} run=${Q.runId||"?"}; agent execution skipped \u2014 workflow owns the reply`),re={content:"",duration:0,metadata:{handledByWorkflow:Se.workflowId,workflowRunId:Q.runId,workflowMatchConfidence:Se.confidence}},re}catch(Q){this.log(`[${e.agentId}] workflow auto-run failed; falling back to agent: ${Q?.message||Q}`)}}let m=()=>{if(d.def.tier!=="claude-code")return null;S("dispatch-gate");let U=d.def.persistentProcess?yt():null,Q=U!=null&&U.hasLive({agentId:e.agentId,channel:y,chatId:k}),ce=!!N||Q,oe=[wo(ce),_o(ce,void 0,e.model||d.def.model)].find(ut=>ut&&ut.abort);if(oe){this.log(`[${e.agentId}] skipping cold dispatch \u2014 ${oe.reason}`);let ut={content:"",error:oe.message,duration:0};if(!t){b.buffer=`[error] ${oe.message}`;for(let Yi of b.subscribers)try{Yi(b.buffer)}catch{}}return ut}To();let Ne=Ro();return Ne&&this.log(`[${e.agentId}] ${Ne}`),null},x=this.planCloudSession(d.def,e);if(x.route==="local"){let U=m();if(U)return d.errors++,re=U,U}let M=d.def.tier==="claude-code",q=M?t:(U,Q)=>{U&&R(U),t&&t(U,Q)},B=!1,ee=M?s:U=>{U&&(B?R(U):(R(`\u{1F4AD} ${U}`),B=!0)),s&&s(U)},te=()=>{B&&(R(`
150
+ `),B=!1)},Xi=M?q:q?(U,Q)=>{te(),q(U,Q)}:void 0,C=await v("agent",async()=>{if(x.route!=="local"){let U=await this.runCloudSession(d.def,e,x,E);if(U)return U;let Q=m();if(Q)return Q}return Yr(d.def,Qi,this.providers,Xi,at,N,j,A.signal,ee)},wu);if(!C.error){let U=ku(d.def.toolUseRequired,O);if(U){let Q=Array.from(O.entries()).map(([ce,ct])=>`${ce}=${ct}`).join(", ")||"none";C.error=`tool_required_not_called: ${U} (invoked: ${Q})`,C.content="",this.log(`[${e.agentId}] tool-use contract violation \u2014 required ${U}, observed ${Q}`)}}rs&&fr(rs,{toolUses:O,eventsSeen:L,error:C.error,agentId:e.agentId},U=>this.log(U));let qt=this.interruptedRuns.get(p.id);qt&&(C.content="",C.error=qt,C.errorKind="interrupted"),re=C;let de=C.usage?Os(C.usage):void 0;if(os=!0,Y().emit("task:completed",{taskId:E,agentId:e.agentId,channel:y,chatId:k,durationMs:Date.now()-On,error:C.error||void 0,errorKind:C.error?C.errorKind:void 0,interrupted:qt?!0:void 0,inputTokens:de?.inputTokens,outputTokens:de?.outputTokens,cacheReadTokens:de?.cacheReadTokens,cacheCreateTokens:de?.cacheCreateTokens,tier2InputTokens:de?.tier2InputTokens,tier2OutputTokens:de?.tier2OutputTokens,tier2CacheReadTokens:de?.tier2CacheReadTokens,tier2CacheCreateTokens:de?.tier2CacheCreateTokens,resumed:!!N,resumeSessionId:N||void 0,jevArm:me.arm,numTurns:C.numTurns,injectedContext:Ji,finalResponse:C.content||void 0,billedModel:C.billedModel||d.def.model||void 0,at:new Date().toISOString()}),!t&&(C.content||C.error)){let U=C.error?`[error] ${C.error}`:C.content;b.buffer=U;for(let Q of b.subscribers)try{Q(U)}catch{}}if(C.error)d.errors++,this.log(`[${e.agentId}] error: ${C.error}`);else{if(this.sessions.addAgentMessage(e.agentId,y,k,C.content),gi({agent:e.agentId,channel:y,chatId:k,request:e.message,reply:C.content,taskId:E}),C.claudeSessionId&&this.sessions.setClaudeSessionId(e.agentId,y,k,C.claudeSessionId),C.codexSessionId&&this.sessions.setCodexSessionId(e.agentId,y,k,C.codexSessionId),C.opencodeSessionId&&this.sessions.setOpenCodeSessionId(e.agentId,y,k,C.opencodeSessionId),(C.claudeSessionId||C.codexSessionId||C.opencodeSessionId)&&C.usage&&this.sessions.recordTurnUsage(e.agentId,y,k,C.usage,C.contextTokens),C.usage){let oe=C.contextTokens,Ne=(C.usage.inputTokens||0)+(C.usage.cacheReadTokens||0)+(C.usage.cacheCreateTokens||0);(oe??Ne)>=this.sessions.getTierTwoThresholdTokens(y)&&this.log(`[${e.agentId}] TIER-2 HIT on ${y}:${k}: context=${oe??"n/a"} tokens (cumulative turn total=${Ne}) \u2014 next turn will rotate`)}if(Ps({channel:y,content:`User: ${e.message}`,responseLength:C.content.length}).capture){await Ln(uu);try{let oe=`${e.agentId}-${Date.now().toString(36)}`;this.wikiHub.getSharedStore().addEntry({id:oe,date:new Date().toISOString().slice(0,10),agentId:e.agentId,source:y,sourceContext:e.context?.group||e.context?.sender,content:`User: ${e.message}
151
151
 
152
- Agent: ${C.content}`,meta:xu(V,e.context)})}catch{}Ps(e.agentId,e.message,C.content,{channel:y,chatId:v,sender:Ot},this.memoryStore).catch(()=>{}),lo(e.agentId,e.message,C.content,{channel:y,date:new Date().toISOString().slice(0,10)},this.patternStore).catch(()=>{})}let Q=C.billedModel||e.model||d.def.model,ce=e.context?.channel,dt=ce&&(e.context?.chatId||e.context?.group||e.context?.sender)?`${ce}:${e.context?.chatId||e.context?.group||e.context?.sender}`:void 0;this.tokenTracker.record(e.agentId,C.duration||0,C.usage,e.message.length,C.content.length,!1,Q,ce,dt),this.log(`[${e.agentId}] completed in ${C.duration}ms`+(C.tokensUsed?` (${C.tokensUsed} tokens)`:"")+` ${w()}`)}return C}catch(g){d.errors++,this.log(`[${e.agentId}] unexpected error: ${g.message}`);let m=pt(g.message);return re={content:"",error:ft(m),errorKind:m.kind},re}finally{if(os.stop(),!rs)try{Y().emit("task:completed",{taskId:E,agentId:e.agentId,channel:u,chatId:l,durationMs:Date.now()-p.startedAt.getTime(),error:re?.error||(A.signal.aborted?Xe(A.signal).message:"run ended before completion"),errorKind:re?.errorKind,interrupted:this.interruptedRuns.has(p.id)?!0:void 0,at:new Date().toISOString()})}catch{}Rn(re)}}getActiveTaskCount(){let e=0;for(let t of this.agents.values())e+=t.activeTasks;return e}runningAgentDrainSeconds(){let e=[];for(let t of this.agents.values())t.activeTasks>0&&e.push(t.def.drainTimeoutSeconds);return e}list(){return Array.from(this.agents.values()).map(e=>{let t=this.lastSummaries.get(e.id);return{id:e.id,name:e.def.name,tier:e.def.tier,model:e.def.model,workspace:e.def.workspace,active:e.activeTasks,total:e.totalTasks,errors:e.errors,lastActive:e.lastActive,runningTasks:e.runningTasks,lastSummary:t?{text:t.text,at:t.at.toISOString(),ok:t.ok}:void 0,hourlyTasks:this.getHourlySparkline(e.id,24)}})}persistTaskRecord(e){let t=e.endedAt.slice(0,10),s=J(process.cwd(),Re,this.safe(e.agentId),t);ne(s)||uu(s,{recursive:!0});let r=J(s,`${this.safe(e.id)}.json`);gu(r,JSON.stringify(e,null,2),"utf-8")}getHourlySparkline(e,t=24){let s=Date.now(),r=this.sparklineCache.get(e);if(r&&s-r.at<6e4&&r.hourly.length===t)return r.hourly;let o=new Array(t).fill(0),i=s-t*36e5,a=J(process.cwd(),Re,this.safe(e));if(!ne(a))return this.sparklineCache.set(e,{hourly:o,at:s}),o;let c=new Date(s).toISOString().slice(0,10),d=new Date(s-864e5).toISOString().slice(0,10);new Date(s).setUTCHours(0,0,0,0);for(let l of[d,c]){let f=J(a,l);if(ne(f))try{for(let h of ae(f)){if(!h.endsWith(".json"))continue;let p=h.split("-")[0],I=parseInt(p,10);if(!Number.isFinite(I)||I<i||I>s)continue;let A=Math.floor((s-I)/36e5),b=t-1-A;b>=0&&b<t&&o[b]++}}catch{}}return this.sparklineCache.set(e,{hourly:o,at:s}),o}hydrateLastSummariesFromDisk(){let e=J(process.cwd(),Re);if(!ne(e))return 0;let t=0;for(let s of ae(e)){let r=J(e,s),o;try{o=ae(r).filter(i=>/^\d{4}-\d{2}-\d{2}$/.test(i)).sort().reverse()}catch{continue}e:for(let i of o){let a=J(r,i),c;try{c=ae(a).filter(d=>d.endsWith(".json")).sort().reverse()}catch{continue}for(let d of c)try{let u=JSON.parse(Ye(J(a,d),"utf-8")),l=(u.responseText||u.error||"").trim();if(!l)continue;let f=l.split(/\r?\n/)[0].slice(0,140);this.lastSummaries.set(u.agentId,{text:f,at:new Date(u.endedAt),ok:u.ok}),t++;break e}catch{}}}return t}pruneTaskHistory(e=bu){let t=J(process.cwd(),Re);if(!ne(t))return 0;let s=Date.now()-e*24*60*60*1e3,r=0;for(let o of ae(t)){let i=J(t,o),a;try{a=ae(i)}catch{continue}for(let c of a){let d=Date.parse(c+"T00:00:00Z");if(!(Number.isNaN(d)||d>=s))try{lu(J(i,c),{recursive:!0,force:!0}),r++}catch{}}}return r}listTaskHistory(e,t=50){let s=J(process.cwd(),Re,this.safe(e));if(!ne(s))return[];let r=ae(s).filter(i=>/^\d{4}-\d{2}-\d{2}$/.test(i)).sort().reverse(),o=[];for(let i of r){if(o.length>=t)break;let a=J(s,i),c;try{c=ae(a).filter(d=>d.endsWith(".json"))}catch{continue}c.sort().reverse();for(let d of c){if(o.length>=t)break;try{let u=JSON.parse(Ye(J(a,d),"utf-8")),{transcript:l,responseText:f,...h}=u;o.push(h)}catch{}}}return o}getTaskRecord(e,t){let s=J(process.cwd(),Re,this.safe(e));if(!ne(s))return null;let r=this.safe(t),o=ae(s).filter(i=>/^\d{4}-\d{2}-\d{2}$/.test(i)).sort().reverse();for(let i of o){let a=J(s,i,`${r}.json`);if(ne(a))try{return JSON.parse(Ye(a,"utf-8"))}catch{return null}}return null}safe(e){return e.replace(/[^a-zA-Z0-9_.:-]/g,"_")}postQueuedResponseToChannel(e,t,s){let r=Ys();if(!r)return;let o=t?.channel,i=t?.chatId;if(!o||!i||s.errorKind==="cancelled"||s.errorKind==="interrupted"||Ue(s.error))return;let a=s.error?`Error: ${s.error}`:(s.content||"").trim();a&&r.sendOutbound({channel:o,chatId:i,text:a,agentId:e}).catch(c=>this.log(`[${e}] queued response post failed: ${c?.message??c}`))}runningTaskOwner(e){for(let t of this.agents.values()){let s=t.runningTasks.find(r=>r.id===e);if(s)return{agentId:t.id,channel:s.channel,chatId:s.chatId}}return null}findRunningTurn(e,t={}){let s=this.agents.get(e);if(!s)return null;let r;if(t.taskId)r=s.runningTasks.find(i=>i.id===t.taskId);else if(t.channel&&t.chatId){let i=s.runningTasks.filter(a=>{let c=Tt(a);return c.channel===t.channel&&c.chatId===t.chatId});r=i.length===1?i[0]:void 0}if(!r)return null;let o=this.runningContexts.get(r.id);return o?{taskId:r.id,context:o}:null}slotHolders(e){let t=this.agents.get(e);return t?{full:t.activeTasks>=t.def.maxConcurrent,runIds:t.runningTasks.map(s=>s.id)}:null}isChatBusy(e,t,s){return this.messageQueue.isBusy(e,t,s)}runningIntentPath(e,t,s){let r=this.agents.get(e);if(!r)return;let o;for(let i of r.runningTasks)i.channel!==t||i.chatId!==s||(!o||i.startedAt>o.startedAt)&&(o=i);return o?.intentPath?.slice()}cancelRunningTask(e,t="operator"){let s=this.taskAborts.get(e);if(!s)return null;try{s.controller.abort(new Error(t))}catch{}return this.log(`[${s.agentId}] task ${e} cancelled \u2014 ${t}`),{agentId:s.agentId,channel:s.channel,chatId:s.chatId}}interruptRunning(e){let t=0;for(let[s,r]of this.taskAborts){this.interruptedRuns.set(s,e);try{r.controller.abort(new Error(e))}catch{}this.log(`[${r.agentId}] task ${s} interrupted \u2014 ${e}`),t++}return t}cancelChatTasks(e,t,s,r="operator"){let o=0;for(let[i,a]of this.taskAborts)a.agentId===e&&a.channel===t&&a.chatId===s&&this.cancelRunningTask(i,r)&&o++;return o}queueFollowUp(e,t,s,r={}){let o=this.taskAborts.get(e);if(!o)return null;let{agentId:i,channel:a,chatId:c,originalMessage:d}=o,u=o.controller.signal.aborted,l=!1;u&&d&&(l=this.sessions.removeLastUserMessageIfMatches(i,a,c,d));let f=Date.now();this.messageQueue.enqueue(i,a,c,{text:t,sender:s,timestamp:f,channel:a,chatId:c,originalContext:{channel:a,chatId:c,sender:s}});let h=this.messageQueue.pendingCount(i,a,c);Y().emit("task:queued",{agentId:i,channel:a,chatId:c,at:new Date(f).toISOString(),sender:{name:s},humanRoot:!1,person:ps(this.config.people)?.id??null,messagePreview:t.slice(0,200),queuedAt:f});let p=!1;if(r.replace){let I=r.reason||`replaced by follow-up from ${s}`;try{o.controller.abort(new Error(I))}catch{}this.log(`[${i}] task ${e} replaced by follow-up \u2014 ${I}`),p=!0}else this.log(`[${i}] follow-up queued for task ${e} (pending=${h}${l?", edited cancelled turn":""})`);return{agentId:i,channel:a,chatId:c,replaced:p,edited:l,pending:h}}async continueFinishedTask(e,t,s,r,o={}){let i=this.getTaskRecord(e,t);if(!i)return{ok:!1,status:404,error:`no task ${t} for agent ${e}`};if(i.channel!=="cron"||!i.chatId)return{ok:!1,status:409,error:`task ${t} is finished; only scheduled (cron) runs can be resumed from the dashboard`};let a=i.channel,c=i.chatId;return new Promise(d=>{let u=!1,l=f=>{u||(u=!0,d(f))};this.log(`[${e}] operator resumed ${a}:${c} from finished task ${t}`),this.execute({message:s,agentId:e,model:o.model?.(c),context:{channel:a,chatId:c,sender:r},onStart:f=>l({ok:!0,agentId:e,channel:a,chatId:c,taskId:f,queued:!1})}).then(f=>{Ue(f.error)?l({ok:!0,agentId:e,channel:a,chatId:c,queued:!0}):f.error?l({ok:!1,status:500,error:f.error||"run did not start"}):l({ok:!0,agentId:e,channel:a,chatId:c,queued:!1,answeredBy:f.viaAttachedSession?"attached":"other"})}).catch(f=>l({ok:!1,status:500,error:f?.message??String(f)}))})}subscribeToTaskOutput(e,t){let s=this.taskOutputs.get(e);return s?s.done?{initial:s.buffer,done:!0,unsubscribe:()=>{}}:(s.subscribers.add(t),{initial:s.buffer,done:!1,unsubscribe:()=>{s.subscribers.delete(t)}}):null}getUsage(e=7){return this.tokenTracker.summary(e)}getTodayUsage(){return this.tokenTracker.today()}getTokenTracker(){return this.tokenTracker}};function Au(n,e){return n===!1||e!=="telegram"&&e!=="whatsapp"&&e!=="app"?"":["[Rich replies]","On this chat channel you may add buttons, a poll, or media to a reply by appending ONE fenced block at the very end:","```agentx:ui",'{ "buttons": [{"label": "Open docs", "url": "https://..."}], "poll": {"question": "Ship it?", "options": ["Yes", "No"]}, "media": {"type": "image", "url": "https://..."} }',"```","All fields are optional; include only what helps. Buttons must be https URLs (tappable callback actions aren't supported yet). Use this sparingly \u2014 only when a link, choice, or image genuinely improves the reply. The block is stripped from the visible text.",...e==="app"?[`In this phone app you may also offer up to 4 short answers the user can tap instead of typing: "quickReplies": ["Yes", "Not now"] (at most 40 characters each), or a button with a reply instead of a url: {"label": "Run the tests", "reply": "Please run the tests"}. A tap sends that text as the user's next message, nothing more. Offer them only when the user is likely to answer with one of them.`]:[]].join(`
153
- `)}export{br as a,Bu as b,Sr as c,fa as d,Ir as e,yt as f,el as g,rl as h,ol as i,ul as j,Tt as k,Oa as l,Jr as m,Ha as n,Ba as o,ja as p,Xr as q,vt as r,kt as s,cd as t,Fl as u,Ul as v,hn as w,Y as x,go as y,bd as z,Td as A,mo as B,ng as C,ho as D,xo as E,Ao as F,hg as G,$o as H,Ct as I,Sg as J,Ig as K,ze as L,Cc as M,Mc as N,Pc as O,_c as P,Rc as Q,Tn as R,fu as S,mu as T,af as U,df as V,xu as W,Su as X,Iu as Y,Pn as Z,Ii as _,Ti as $,vu as aa,vi as ba,ki as ca,Au as da};
154
- //# sourceMappingURL=chunk-2NGXOYTS.js.map
152
+ Agent: ${C.content}`,meta:Su(V,e.context)})}catch{}_s(e.agentId,e.message,C.content,{channel:y,chatId:k,sender:Nt},this.memoryStore).catch(()=>{}),go(e.agentId,e.message,C.content,{channel:y,date:new Date().toISOString().slice(0,10)},this.patternStore).catch(()=>{})}let Q=C.billedModel||e.model||d.def.model,ce=e.context?.channel,ct=ce&&(e.context?.chatId||e.context?.group||e.context?.sender)?`${ce}:${e.context?.chatId||e.context?.group||e.context?.sender}`:void 0;this.tokenTracker.record(e.agentId,C.duration||0,C.usage,e.message.length,C.content.length,!1,Q,ce,ct),this.log(`[${e.agentId}] completed in ${C.duration}ms`+(C.tokensUsed?` (${C.tokensUsed} tokens)`:"")+` ${w()}`)}return C}catch(g){d.errors++,this.log(`[${e.agentId}] unexpected error: ${g.message}`);let m=ft(g.message);return re={content:"",error:mt(m),errorKind:m.kind},re}finally{if(is.stop(),!os)try{Y().emit("task:completed",{taskId:E,agentId:e.agentId,channel:u,chatId:l,durationMs:Date.now()-p.startedAt.getTime(),error:re?.error||(A.signal.aborted?Xe(A.signal).message:"run ended before completion"),errorKind:re?.errorKind,interrupted:this.interruptedRuns.has(p.id)?!0:void 0,at:new Date().toISOString()})}catch{}En(re)}}getActiveTaskCount(){let e=0;for(let t of this.agents.values())e+=t.activeTasks;return e}runningAgentDrainSeconds(){let e=[];for(let t of this.agents.values())t.activeTasks>0&&e.push(t.def.drainTimeoutSeconds);return e}list(){return Array.from(this.agents.values()).map(e=>{let t=this.lastSummaries.get(e.id);return{id:e.id,name:e.def.name,tier:e.def.tier,model:e.def.model,workspace:e.def.workspace,active:e.activeTasks,total:e.totalTasks,errors:e.errors,lastActive:e.lastActive,runningTasks:e.runningTasks,lastSummary:t?{text:t.text,at:t.at.toISOString(),ok:t.ok}:void 0,hourlyTasks:this.getHourlySparkline(e.id,24)}})}persistTaskRecord(e){let t=e.endedAt.slice(0,10),s=J(process.cwd(),Re,this.safe(e.agentId),t);ne(s)||lu(s,{recursive:!0});let r=J(s,`${this.safe(e.id)}.json`);pu(r,JSON.stringify(e,null,2),"utf-8")}getHourlySparkline(e,t=24){let s=Date.now(),r=this.sparklineCache.get(e);if(r&&s-r.at<6e4&&r.hourly.length===t)return r.hourly;let o=new Array(t).fill(0),i=s-t*36e5,a=J(process.cwd(),Re,this.safe(e));if(!ne(a))return this.sparklineCache.set(e,{hourly:o,at:s}),o;let c=new Date(s).toISOString().slice(0,10),d=new Date(s-864e5).toISOString().slice(0,10);new Date(s).setUTCHours(0,0,0,0);for(let l of[d,c]){let f=J(a,l);if(ne(f))try{for(let h of ae(f)){if(!h.endsWith(".json"))continue;let p=h.split("-")[0],I=parseInt(p,10);if(!Number.isFinite(I)||I<i||I>s)continue;let A=Math.floor((s-I)/36e5),b=t-1-A;b>=0&&b<t&&o[b]++}}catch{}}return this.sparklineCache.set(e,{hourly:o,at:s}),o}hydrateLastSummariesFromDisk(){let e=J(process.cwd(),Re);if(!ne(e))return 0;let t=0;for(let s of ae(e)){let r=J(e,s),o;try{o=ae(r).filter(i=>/^\d{4}-\d{2}-\d{2}$/.test(i)).sort().reverse()}catch{continue}e:for(let i of o){let a=J(r,i),c;try{c=ae(a).filter(d=>d.endsWith(".json")).sort().reverse()}catch{continue}for(let d of c)try{let u=JSON.parse(Ye(J(a,d),"utf-8")),l=(u.responseText||u.error||"").trim();if(!l)continue;let f=l.split(/\r?\n/)[0].slice(0,140);this.lastSummaries.set(u.agentId,{text:f,at:new Date(u.endedAt),ok:u.ok}),t++;break e}catch{}}}return t}pruneTaskHistory(e=xu){let t=J(process.cwd(),Re);if(!ne(t))return 0;let s=Date.now()-e*24*60*60*1e3,r=0;for(let o of ae(t)){let i=J(t,o),a;try{a=ae(i)}catch{continue}for(let c of a){let d=Date.parse(c+"T00:00:00Z");if(!(Number.isNaN(d)||d>=s))try{gu(J(i,c),{recursive:!0,force:!0}),r++}catch{}}}return r}listTaskHistory(e,t=50){let s=J(process.cwd(),Re,this.safe(e));if(!ne(s))return[];let r=ae(s).filter(i=>/^\d{4}-\d{2}-\d{2}$/.test(i)).sort().reverse(),o=[];for(let i of r){if(o.length>=t)break;let a=J(s,i),c;try{c=ae(a).filter(d=>d.endsWith(".json"))}catch{continue}c.sort().reverse();for(let d of c){if(o.length>=t)break;try{let u=JSON.parse(Ye(J(a,d),"utf-8")),{transcript:l,responseText:f,...h}=u;o.push(h)}catch{}}}return o}getTaskRecord(e,t){let s=J(process.cwd(),Re,this.safe(e));if(!ne(s))return null;let r=this.safe(t),o=ae(s).filter(i=>/^\d{4}-\d{2}-\d{2}$/.test(i)).sort().reverse();for(let i of o){let a=J(s,i,`${r}.json`);if(ne(a))try{return JSON.parse(Ye(a,"utf-8"))}catch{return null}}return null}safe(e){return e.replace(/[^a-zA-Z0-9_.:-]/g,"_")}postQueuedResponseToChannel(e,t,s){let r=Vs();if(!r)return;let o=t?.channel,i=t?.chatId;if(!o||!i||s.errorKind==="cancelled"||s.errorKind==="interrupted"||Ue(s.error))return;let a=s.error?`Error: ${s.error}`:(s.content||"").trim();a&&r.sendOutbound({channel:o,chatId:i,text:a,agentId:e}).catch(c=>this.log(`[${e}] queued response post failed: ${c?.message??c}`))}runningTaskOwner(e){for(let t of this.agents.values()){let s=t.runningTasks.find(r=>r.id===e);if(s)return{agentId:t.id,channel:s.channel,chatId:s.chatId}}return null}findRunningTurn(e,t={}){let s=this.agents.get(e);if(!s)return null;let r;if(t.taskId)r=s.runningTasks.find(i=>i.id===t.taskId);else if(t.channel&&t.chatId){let i=s.runningTasks.filter(a=>{let c=vt(a);return c.channel===t.channel&&c.chatId===t.chatId});r=i.length===1?i[0]:void 0}if(!r)return null;let o=this.runningContexts.get(r.id);return o?{taskId:r.id,context:o}:null}slotHolders(e){let t=this.agents.get(e);return t?{full:t.activeTasks>=t.def.maxConcurrent,runIds:t.runningTasks.map(s=>s.id)}:null}isChatBusy(e,t,s){return this.messageQueue.isBusy(e,t,s)}runningIntentPath(e,t,s){let r=this.agents.get(e);if(!r)return;let o;for(let i of r.runningTasks)i.channel!==t||i.chatId!==s||(!o||i.startedAt>o.startedAt)&&(o=i);return o?.intentPath?.slice()}cancelRunningTask(e,t="operator"){let s=this.taskAborts.get(e);if(!s)return null;try{s.controller.abort(new Error(t))}catch{}return this.log(`[${s.agentId}] task ${e} cancelled \u2014 ${t}`),{agentId:s.agentId,channel:s.channel,chatId:s.chatId}}interruptRunning(e){let t=0;for(let[s,r]of this.taskAborts){this.interruptedRuns.set(s,e);try{r.controller.abort(new Error(e))}catch{}this.log(`[${r.agentId}] task ${s} interrupted \u2014 ${e}`),t++}return t}cancelChatTasks(e,t,s,r="operator"){let o=0;for(let[i,a]of this.taskAborts)a.agentId===e&&a.channel===t&&a.chatId===s&&this.cancelRunningTask(i,r)&&o++;return o}queueFollowUp(e,t,s,r={}){let o=this.taskAborts.get(e);if(!o)return null;let{agentId:i,channel:a,chatId:c,originalMessage:d}=o,u=o.controller.signal.aborted,l=!1;u&&d&&(l=this.sessions.removeLastUserMessageIfMatches(i,a,c,d));let f=Date.now();this.messageQueue.enqueue(i,a,c,{text:t,sender:s,timestamp:f,channel:a,chatId:c,originalContext:{channel:a,chatId:c,sender:s}});let h=this.messageQueue.pendingCount(i,a,c);Y().emit("task:queued",{agentId:i,channel:a,chatId:c,at:new Date(f).toISOString(),sender:{name:s},humanRoot:!1,person:fs(this.config.people)?.id??null,messagePreview:t.slice(0,200),queuedAt:f});let p=!1;if(r.replace){let I=r.reason||`replaced by follow-up from ${s}`;try{o.controller.abort(new Error(I))}catch{}this.log(`[${i}] task ${e} replaced by follow-up \u2014 ${I}`),p=!0}else this.log(`[${i}] follow-up queued for task ${e} (pending=${h}${l?", edited cancelled turn":""})`);return{agentId:i,channel:a,chatId:c,replaced:p,edited:l,pending:h}}async continueFinishedTask(e,t,s,r,o={}){let i=this.getTaskRecord(e,t);if(!i)return{ok:!1,status:404,error:`no task ${t} for agent ${e}`};if(i.channel!=="cron"||!i.chatId)return{ok:!1,status:409,error:`task ${t} is finished; only scheduled (cron) runs can be resumed from the dashboard`};let a=i.channel,c=i.chatId;return new Promise(d=>{let u=!1,l=f=>{u||(u=!0,d(f))};this.log(`[${e}] operator resumed ${a}:${c} from finished task ${t}`),this.execute({message:s,agentId:e,model:o.model?.(c),context:{channel:a,chatId:c,sender:r},onStart:f=>l({ok:!0,agentId:e,channel:a,chatId:c,taskId:f,queued:!1})}).then(f=>{Ue(f.error)?l({ok:!0,agentId:e,channel:a,chatId:c,queued:!0}):f.error?l({ok:!1,status:500,error:f.error||"run did not start"}):l({ok:!0,agentId:e,channel:a,chatId:c,queued:!1,answeredBy:f.viaAttachedSession?"attached":"other"})}).catch(f=>l({ok:!1,status:500,error:f?.message??String(f)}))})}subscribeToTaskOutput(e,t){let s=this.taskOutputs.get(e);return s?s.done?{initial:s.buffer,done:!0,unsubscribe:()=>{}}:(s.subscribers.add(t),{initial:s.buffer,done:!1,unsubscribe:()=>{s.subscribers.delete(t)}}):null}getUsage(e=7){return this.tokenTracker.summary(e)}getTodayUsage(){return this.tokenTracker.today()}getTokenTracker(){return this.tokenTracker}};function $u(n,e){return n===!1||e!=="telegram"&&e!=="whatsapp"&&e!=="app"?"":["[Rich replies]","On this chat channel you may add buttons, a poll, or media to a reply by appending ONE fenced block at the very end:","```agentx:ui",'{ "buttons": [{"label": "Open docs", "url": "https://..."}], "poll": {"question": "Ship it?", "options": ["Yes", "No"]}, "media": {"type": "image", "url": "https://..."} }',"```","All fields are optional; include only what helps. Buttons must be https URLs (tappable callback actions aren't supported yet). Use this sparingly \u2014 only when a link, choice, or image genuinely improves the reply. The block is stripped from the visible text.",...e==="app"?[`In this phone app you may also offer up to 4 short answers the user can tap instead of typing: "quickReplies": ["Yes", "Not now"] (at most 40 characters each), or a button with a reply instead of a url: {"label": "Run the tests", "reply": "Please run the tests"}. A tap sends that text as the user's next message, nothing more. Offer them only when the user is likely to answer with one of them.`]:[]].join(`
153
+ `)}export{xr as a,ju as b,Ir as c,ma as d,Tr as e,wt as f,tl as g,ol as h,il as i,ll as j,vt as k,Na as l,Qr as m,Ba as n,ja as o,qa as p,Yr as q,kt as r,At as s,ud as t,Ul as u,Hl as v,yn as w,Y as x,po as y,xd as z,vd as A,ho as B,sg as C,yo as D,So as E,$o as F,yg as G,Co as H,Mt as I,Ig as J,Tg as K,ze as L,Mc as M,Pc as N,_c as O,Rc as P,Ec as Q,vn as R,mu as S,hu as T,df as U,cf as V,Su as W,Iu as X,Tu as Y,_n as Z,Ti as _,vi as $,ku as aa,ki as ba,Ai as ca,$u as da};
154
+ //# sourceMappingURL=chunk-XLCUHG3N.js.map