agentix-cli 0.22.0 → 0.23.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.
- package/dist/{agent-Y4U4R3ZZ.js → agent-FSE4KRLX.js} +2 -2
- package/dist/{board-dashboard-2CPBWFOB.js → board-dashboard-PUACKWAN.js} +4 -4
- package/dist/builtin-TQKMR42Z.js +2 -0
- package/dist/{chunk-OPKQNLGX.js → chunk-3SHMHYPD.js} +71 -71
- package/dist/chunk-3SHMHYPD.js.map +1 -0
- package/dist/{chunk-KX626FN4.js → chunk-4INOOHND.js} +2 -2
- package/dist/{chunk-OZOQKPJV.js → chunk-72PAN7UI.js} +51 -50
- package/dist/chunk-72PAN7UI.js.map +1 -0
- package/dist/chunk-BOUKM2PS.js +163 -0
- package/dist/chunk-BOUKM2PS.js.map +1 -0
- package/dist/{chunk-P3TJHGO5.js → chunk-DXTIG5YV.js} +2 -2
- package/dist/chunk-EK37JHJI.js +13 -0
- package/dist/chunk-EK37JHJI.js.map +1 -0
- package/dist/chunk-EQPUB7CZ.js +685 -0
- package/dist/chunk-EQPUB7CZ.js.map +1 -0
- package/dist/{chunk-WHP4I44J.js → chunk-KWUWZQGV.js} +2 -2
- package/dist/{chunk-ABVZHJUO.js → chunk-PD5Q7D6Z.js} +2 -2
- package/dist/{chunk-VYLZ7UYM.js → chunk-Q6CAFGXT.js} +2 -2
- package/dist/chunk-ZZFXI3CS.js +8 -0
- package/dist/chunk-ZZFXI3CS.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/{config-BLOKGMER.js → config-ADS54KLC.js} +2 -2
- package/dist/config-mutator-WTRMBZTO.js +2 -0
- package/dist/doctor-T6RB4Q5X.js +2 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/program-V7NGFB2R.js +2 -0
- package/dist/registry-42HEWCLA.js +2 -0
- package/dist/scheduler-C56ABAVP.js +2 -0
- package/dist/scheduler-C56ABAVP.js.map +1 -0
- package/dist/web/workflow-editor.global.js +11 -11
- package/dist/web/workflow-editor.global.js.map +1 -1
- package/package.json +2 -1
- package/dist/chunk-2HXSJYAJ.js +0 -15
- package/dist/chunk-2HXSJYAJ.js.map +0 -1
- package/dist/chunk-CO4YCIIA.js +0 -13
- package/dist/chunk-CO4YCIIA.js.map +0 -1
- package/dist/chunk-OPKQNLGX.js.map +0 -1
- package/dist/chunk-OZOQKPJV.js.map +0 -1
- package/dist/chunk-X5D5AV5N.js +0 -833
- package/dist/chunk-X5D5AV5N.js.map +0 -1
- package/dist/config-mutator-RG7QY2EL.js +0 -2
- package/dist/doctor-ZTECTUHX.js +0 -2
- package/dist/program-GZOJIWTB.js +0 -2
- package/dist/registry-QZIUSQ5J.js +0 -2
- package/dist/scheduler-B2BQPV4M.js +0 -2
- /package/dist/{agent-Y4U4R3ZZ.js.map → agent-FSE4KRLX.js.map} +0 -0
- /package/dist/{board-dashboard-2CPBWFOB.js.map → board-dashboard-PUACKWAN.js.map} +0 -0
- /package/dist/{config-BLOKGMER.js.map → builtin-TQKMR42Z.js.map} +0 -0
- /package/dist/{chunk-KX626FN4.js.map → chunk-4INOOHND.js.map} +0 -0
- /package/dist/{chunk-P3TJHGO5.js.map → chunk-DXTIG5YV.js.map} +0 -0
- /package/dist/{chunk-WHP4I44J.js.map → chunk-KWUWZQGV.js.map} +0 -0
- /package/dist/{chunk-ABVZHJUO.js.map → chunk-PD5Q7D6Z.js.map} +0 -0
- /package/dist/{chunk-VYLZ7UYM.js.map → chunk-Q6CAFGXT.js.map} +0 -0
- /package/dist/{config-mutator-RG7QY2EL.js.map → config-ADS54KLC.js.map} +0 -0
- /package/dist/{doctor-ZTECTUHX.js.map → config-mutator-WTRMBZTO.js.map} +0 -0
- /package/dist/{program-GZOJIWTB.js.map → doctor-T6RB4Q5X.js.map} +0 -0
- /package/dist/{registry-QZIUSQ5J.js.map → program-V7NGFB2R.js.map} +0 -0
- /package/dist/{scheduler-B2BQPV4M.js.map → registry-42HEWCLA.js.map} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as K,b as X,c as D,d as I,e as M,f as W}from"./chunk-CNNLREHD.js";import{e as B}from"./chunk-
|
|
1
|
+
import{a as K,b as X,c as D,d as I,e as M,f as W}from"./chunk-CNNLREHD.js";import{e as B}from"./chunk-EK37JHJI.js";import{f as J}from"./chunk-7P5QRX5W.js";import{existsSync as _,readFileSync as ae,writeFileSync as ne,appendFileSync as ve,mkdirSync as xe}from"fs";import{resolve as R}from"path";import{hostname as be}from"os";import{spawn as ye}from"child_process";import{existsSync as G,readFileSync as Y,writeFileSync as j,copyFileSync as me}from"fs";import{resolve as V}from"path";function Q(t,e={}){let n=e.configPath||V(process.cwd(),"agentx.json");if(!G(n))throw new Error(`agentx.json not found at ${n}`);let a=JSON.parse(Y(n,"utf-8")),r=t(a),s=typeof r=="string"?{summary:r}:r,o=JSON.stringify(a,null,2)+`
|
|
2
2
|
`,p=n+".tmp";j(p,o,"utf-8");try{JSON.parse(Y(p,"utf-8"))}catch(d){throw new Error(`config did not round-trip cleanly: ${d.message}`)}let i;return e.skipBackup||(i=`${n}.bak.${Date.now()}`,me(n,i)),j(n,o,"utf-8"),e.skipReload||he().catch(()=>{}),{summary:s.summary,payload:s.payload,backupPath:i}}function Z(t,e={}){let n=e.configPath||V(process.cwd(),"agentx.json");if(G(n)&&!e.overwrite)throw new Error(`agentx.json already exists at ${n}. Pass overwrite=true to replace it.`);return j(n,JSON.stringify(t,null,2)+`
|
|
3
3
|
`,"utf-8"),{file:n}}async function he(){try{let e=B().dashboard.daemonUrl?.replace(/\/+$/,"")||"http://127.0.0.1:18800";await fetch(`${e}/reload`,{method:"POST"}).catch(()=>null)}catch{}}function ee(t,e){let n=t.configExists?t.agentCount===0?"Add your first agent":"Add another agent":"Set up your team",a=`<header class="ax-topbar">
|
|
4
4
|
<div class="ax-topbar__left">
|
|
@@ -740,4 +740,4 @@ tr:hover td { background: var(--bg-hover); }
|
|
|
740
740
|
<div class="meta-line">${U((d.meta.tags||[]).slice(0,6),e)}</div>
|
|
741
741
|
<h3><a href="${p}/article/${encodeURIComponent(d.path)}">${l(d.meta.title)}</a></h3>
|
|
742
742
|
</div>`;return $(`${e} \xB7 ${n}`,C(r),i)}function P(t,e,n){let a=t.rebuildIndex(),r=L(a.articles.map(o=>({title:o.title,path:o.path,tags:o.tags}))),s='<div class="nav-section">';s+=`<div class="nav-section-title">${l(e)}</div>`,s+=`<a class="nav-item${n?"":" active"}" href="/">Home</a>`,s+='<a class="nav-item" href="/lint">Health check</a>',s+="</div>";for(let[o,p]of r){s+='<div class="nav-section">',s+=`<div class="nav-section-title">${q(o)}</div>`;for(let i of p){let d=i.path===n;s+=`<a class="nav-item${d?" active":""}" href="/article/${encodeURIComponent(i.path)}">${l(i.title)}</a>`}s+="</div>"}return s}function Je(t){let{wikiDir:e,agentFilter:n,peerUrls:a=[],mode:r="graph",pathPrefix:s=""}=t,o=s.replace(/\/+$/,""),p=new J(e,void 0,r),i=a.length>0?new H(a):null;return async(d,g)=>{let x=new URL(d.url||"/","http://localhost"),c=decodeURIComponent(x.pathname),u=o&&c.startsWith(o)?c.slice(o.length)||"/":c,f=null,z=200;try{if(u.startsWith("/remote/")&&i){let y=u.slice(8).split("/article/");if(y.length===2){let[b,v]=y,m=b.indexOf("/"),k=decodeURIComponent(b.slice(0,m)),h=b.slice(m+1),w=await i.getRemoteArticle(k,h,v);if(w){let E=await i.getRemoteAgents(),N=[...p.summary(),...E.map(S=>({...S,agentId:`${S.agentId} @${S.nodeId}`}))],A=`<div class="breadcrumb"><a href="/">Hub</a> / <span class="tag">remote</span> ${l(h)} @ ${l(k)}</div>`;A+=`<h1>${l(w.meta.title)}</h1>`,A+='<dl class="meta">',A+=`<dt>Tags</dt><dd>${(w.meta.tags||[]).map(S=>`<span class="tag">${S}</span>`).join(" ")}</dd>`,A+=`<dt>Owner</dt><dd>${l(w.meta.owner)}</dd>`,A+=`<dt>Source</dt><dd><span class="tag">remote</span> ${l(k)}</dd>`,A+=`<dt>Updated</dt><dd>${w.meta.lastUpdated}</dd>`,A+="</dl>";let T=new Map;A+=O(w.content,T),f=$(w.meta.title,C(N),A)}}}if(!f&&n){let y=p.getAgentWiki(n);if(u==="/"||u===""){let b=y.rebuildIndex(),v=p.getAgentEntries(n),m=`<h1>${l(n)}</h1>`;if(m+='<div class="stats">',m+=`<div class="stat-card"><div class="number">${b.articles.length}</div><div class="label">Articles</div></div>`,m+=`<div class="stat-card"><div class="number">${v.length}</div><div class="label">Entries</div></div>`,m+="</div>",b.articles.length>0){m+="<h2>Articles</h2><table><tr><th>Title</th><th>Type</th><th>Updated</th></tr>";for(let k of b.articles)m+=`<tr><td><a href="/article/${encodeURIComponent(k.path)}">${l(k.title)}</a></td><td><span class="tag">${(k.tags||[]).slice(0,3).join(", ")}</span></td><td>${k.lastUpdated||""}</td></tr>`;m+="</table>"}f=$(n,P(y,n),m)}else if(u.startsWith("/article/")){let b=u.slice(9),v=y.readArticle(b);if(v){let m=y.rebuildIndex(),k=new Map;for(let w of m.articles)k.set(w.title,w.path);let h=`<h1>${l(v.meta.title)}</h1>`;h+='<dl class="meta">',h+=`<dt>Tags</dt><dd>${(v.meta.tags||[]).map(w=>`<span class="tag">${w}</span>`).join(" ")}</dd>`,h+=`<dt>Updated</dt><dd>${v.meta.lastUpdated}</dd>`,v.meta.sources?.length&&(h+=`<dt>Sources</dt><dd>${v.meta.sources.length} entries</dd>`),h+="</dl>",h+=O(v.content,k),f=$(v.meta.title,P(y,n,b),h)}}else if(u==="/lint"){let b=y.lint(),v="<h1>Health Check</h1>";if(b.length===0)v+='<p style="color:green;">No issues.</p>';else{v+="<table><tr><th>Type</th><th>Article</th><th>Issue</th></tr>";for(let m of b)v+=`<tr><td><span class="tag">${m.type}</span></td><td>${l(m.article)}</td><td>${l(m.message)}</td></tr>`;v+="</table>"}f=$("Health Check",P(y,n),v)}else if(u==="/search"){let b=x.searchParams.get("q")||"",v=y.findRelevant(b,void 0,20),m=`<h1>Search: "${l(b)}"</h1>`;for(let k of v)m+=`<div class="entry-card"><h3><a href="/article/${encodeURIComponent(k.path)}">${l(k.meta.title)}</a></h3><p>${l(k.content.slice(0,200))}...</p></div>`;v.length===0&&(m+="<p>No results.</p>"),f=$(`Search: ${b}`,P(y,n),m)}else if(u.startsWith("/tag/")){let b=decodeURIComponent(u.slice(5)),v=y.findByTags([b],void 0,100),m=`<h1>Tag: <a class="tag" href="#">${l(b)}</a></h1>`;m+=`<p>${v.length} article${v.length===1?"":"s"} tagged <code>${l(b)}</code></p>`;for(let k of v)m+=`<div class="entry-card"><h3><a href="/article/${encodeURIComponent(k.path)}">${l(k.meta.title)}</a></h3><div class="meta-line">${U((k.meta.tags||[]).slice(0,6))}</div></div>`;v.length===0&&(m+="<p>No articles with this tag.</p>"),f=$(`Tag: ${b}`,P(y,n),m)}}else{let y=i?await i.getRemoteAgents():[],b=p.summary(),v=new Map(b.map(h=>[h.agentId,h])),m=[],k=new Set;for(let h of b){let w=y.find(E=>E.agentId===h.agentId);w&&w.totalArticles>h.totalArticles?m.push({...w,totalEntries:Math.max(h.totalEntries,w.totalEntries),unabsorbed:Math.max(h.unabsorbed,w.unabsorbed)}):m.push(h),k.add(h.agentId)}for(let h of y)k.has(h.agentId)||(m.push(h),k.add(h.agentId));if(u==="/"||u==="")f=Oe(p,m,y);else if(u==="/entries")f=je(p,m);else if(u==="/search")f=Fe(p,x.searchParams.get("q")||"",m);else if(u.startsWith("/tag/"))f=Le(p,decodeURIComponent(u.slice(5)),m);else if(u.match(/^\/agent\/[^/]+\/tag\/.+/)){let h=u.match(/^\/agent\/([^/]+)\/tag\/(.+)$/);f=qe(p,decodeURIComponent(h[1]),decodeURIComponent(h[2]),m)}else if(u.startsWith("/agent/")){let h=u.slice(7),w=h.indexOf("/article/");if(w===-1)f=De(p,h,m);else{let E=h.slice(0,w),N=h.slice(w+9);if(f=Me(p,E,N,m),!f&&i){let A=y.find(T=>T.agentId===E);if(A){let T=await i.getRemoteArticle(A.peerUrl,E,N);if(T){let S=`<div class="breadcrumb"><a href="/">Hub</a> / <span class="tag">remote @ ${l(A.nodeId)}</span> / ${l(E)}</div>`;S+=`<h1>${l(T.meta.title)}</h1>`,S+='<dl class="meta">',S+=`<dt>Tags</dt><dd>${(T.meta.tags||[]).map(ge=>`<span class="tag">${ge}</span>`).join(" ")}</dd>`,S+=`<dt>Source</dt><dd><span class="tag">remote</span> ${l(A.nodeId)}</dd>`,S+=`<dt>Updated</dt><dd>${T.meta.lastUpdated}</dd>`,S+="</dl>",S+=O(T.content,new Map),f=$(T.meta.title,C(m),S)}}}}}}if(!f){z=404;let y=n?P(p.getAgentWiki(n),n):C(p.summary());f=$("Not Found",y,"<h1>Page not found</h1>")}}catch(y){z=500,f=$("Error","",`<h1>Error</h1><pre>${l(y.message)}</pre>`)}g.writeHead(z,{"Content-Type":"text/html; charset=utf-8"}),g.end(o?Ke(f,o):f)}}function Ke(t,e){t=t.replace(/(\s(?:href|action)=")\/(?!\/)/g,`$1${e}/`),t=t.replace(new RegExp(`(${e})${e}/`,"g"),`${e}/`);let n=`<a href="/admin" style="position:fixed;top:10px;right:14px;z-index:9999;padding:5px 11px;background:rgba(0,0,0,0.55);color:#fff;font:12px/1.2 'IBM Plex Sans',system-ui,sans-serif;text-decoration:none;border-radius:6px;border:1px solid rgba(255,255,255,0.18);backdrop-filter:blur(6px)">\u2190 Dashboard</a>`;return t=t.replace(/<body([^>]*)>/,`<body$1>${n}`),t}function kt(t,e=4200,n,a=[],r="graph"){let s=Je({wikiDir:t,agentFilter:n,peerUrls:a,mode:r});We((p,i)=>{s(p,i)}).listen(e)}export{Q as a,re as b,ot as c,lt as d,ct as e,ce as f,ht as g,ut as h,Je as i,kt as j};
|
|
743
|
-
//# sourceMappingURL=chunk-
|
|
743
|
+
//# sourceMappingURL=chunk-KWUWZQGV.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{a as C,b as T}from"./chunk-
|
|
1
|
+
import{a as C,b as T}from"./chunk-DXTIG5YV.js";import{a as S,c as x}from"./chunk-GOLZ6NEL.js";import{a as L}from"./chunk-VJUTQAPJ.js";import{writeFileSync as P,mkdirSync as R,existsSync as D,readFileSync as q}from"fs";import{resolve as v}from"path";var H=["off","shadow","authoritative"],z={telegram:"INTENT_LEDGER_MODE_TELEGRAM",slack:"INTENT_LEDGER_MODE_SLACK",whatsapp:"INTENT_LEDGER_MODE_WHATSAPP",discord:"INTENT_LEDGER_MODE_DISCORD",gitlab:"INTENT_LEDGER_MODE_GITLAB",github:"INTENT_LEDGER_MODE_GITHUB",workflow:"INTENT_LEDGER_MODE_WORKFLOW",cron:"INTENT_LEDGER_MODE_CRON",mesh:"INTENT_LEDGER_MODE_MESH"},K="INTENT_LEDGER_MODE";function O(s,e=process.env){let n=_(e[z[s]]);if(n)return n;let t=_(e[K]);return t||"off"}function _(s){if(typeof s!="string")return null;let e=s.trim().toLowerCase();return H.includes(e)?e:null}var A;function X(s){A=s}function N(){return A}function k(s,e,n,t=Date.now,r){return s.db.transaction(i=>{let c=s.recordEvent(e),a=r??N(),u=a?.pmFor?.(c.project),d=u?`pm:${u}`:n.decidedBy,p=s.getDecisionsForEvent(c.id).find(h=>h.decidedBy===d);if(p)return p;let y=s.getActiveDecisionForSubject(c.project,c.subject);if(y){let h={eventId:c.id,decidedAt:i,decidedBy:d,agentId:null,outcome:"deduped",reason:`active dispatch in flight: ${y.decidedBy} \u2192 ${y.agentId??"?"}`};return s.recordDecision(h),h}let g=n.decide(c),l=g?g.agentId:null,f=g?g.outcome:"halted",m=g?g.reason:"no policy match";if(a?.canHandle&&f==="dispatched"&&l&&!a.canHandle(l,c.project,c.intent)){let $=l;l=null,f="halted",m=`org-chart: agent "${$}" cannot handle (${c.project??"no-project"}/${c.intent??"no-intent"})`}if(a?.withinDelegationBudget&&f==="dispatched"&&l&&!a.withinDelegationBudget(l,c.project,c.subject)){let h=l;l=null,f="halted",m=`delegation-budget: agent "${h}" depth-limit exceeded on ${c.project??"?"}/${c.subject??"?"}`}u&&f==="dispatched"&&l&&(m=m?`${m} (pm-gate: rubber-stamped by ${u})`:`pm-gate: rubber-stamped by ${u}`);let E={eventId:c.id,decidedAt:i,decidedBy:d,agentId:l,outcome:f,reason:m};return s.recordDecision(E),E})(t())}function M(s,e,n,t,r=Date.now){if(U(n,t))return!1;let o=r(),i={id:S(o),ts:o,source:e,eventId:n.eventId,decidedBy:n.decidedBy,ledgerAgentId:n.agentId,ledgerOutcome:n.outcome,ledgerReason:n.reason,legacyAgentId:t.agentId,legacyOutcome:t.outcome,legacyReason:t.reason??null};return s.recordDivergence(i),L.warn(`[ledger-divergence] source=${e} event=${n.eventId} decided_by=${n.decidedBy} ledger=${n.outcome}/${n.agentId??"null"} legacy=${t.outcome}/${t.agentId??"null"}`),!0}function U(s,e){return s.outcome===e.outcome&&s.agentId===e.agentId}function V(s,e,n=Date.now){return{ts:n(),source:"cron",sourceEventId:`${s.jobId}:${s.firedAt.getTime()}`,project:null,subject:`cron:${s.jobId}`,intent:"cron.fired",rawJson:e}}function W(s){return{decidedBy:"cron-scheduler",decide:()=>({agentId:s.agentId,outcome:s.outcome==="deduped"?"halted":s.outcome,reason:s.outcome==="deduped"?`legacy-dedup: ${s.reason??""}`.trim():s.reason??null})}}function J(s,e,n,t,r=Date.now){let o=V(e,n,r),i=W(t),c=k(s,o,i,r);return M(s,"cron",c,t,r),c}function F(s,e){if(!e)return s;let n=e*4;return`${s}
|
|
2
2
|
|
|
3
3
|
[Response budget]
|
|
4
4
|
Keep your response under ~${e} tokens (~${n} chars). Be concise \u2014 this is automated batch work, not a conversation.`}function b(s,e,n){let t=[];for(let r of s.split(","))if(r==="*")for(let o=e;o<=n;o++)t.push(o);else if(r.includes("/")){let[o,i]=r.split("/"),c=parseInt(i,10),a=o==="*"?e:parseInt(o,10);for(let u=a;u<=n;u+=c)t.push(u)}else if(r.includes("-")){let[o,i]=r.split("-").map(Number);for(let c=o;c<=i;c++)t.push(c)}else t.push(parseInt(r,10));return[...new Set(t)].sort((r,o)=>r-o)}function B(s,e,n){let t=s.trim().split(/\s+/);if(t.length!==5)throw new Error(`Invalid cron: ${s}`);let r=b(t[0],0,59),o=b(t[1],0,23),i=b(t[2],1,31),c=b(t[3],1,12),a=b(t[4],0,6),u=new Intl.DateTimeFormat("en-US",{timeZone:n,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hour12:!1}),d=new Date(e.getTime()+6e4);d.setSeconds(0,0);let p=new Date(d.getTime()+366*24*60*60*1e3);for(;d<p;){let y=u.formatToParts(d),g=$=>parseInt(y.find(j=>j.type===$)?.value||"0",10),l=g("minute"),f=g("hour"),m=g("day"),E=g("month"),h=d.getDay();if(r.includes(l)&&o.includes(f)&&i.includes(m)&&c.includes(E)&&a.includes(h))return d;d.setTime(d.getTime()+6e4)}throw new Error(`No next run found for cron "${s}" within 1 year`)}var I=5,w=[3e4,6e4,3e5,9e5,36e5],G=class{jobs=new Map;timers=new Map;registry;hooks;runsDir;lastRunFile;running=!1;notifyCallback;log;constructor(e,n,t,r=console.error.bind(console,"[cron]")){this.registry=n,this.hooks=t,this.log=r,this.runsDir=v(process.cwd(),".agentx/cron/runs"),this.lastRunFile=v(process.cwd(),".agentx/cron/last-runs.json");for(let[o,i]of Object.entries(e.crons))this.jobs.set(o,{id:o,enabled:i.enabled,schedule:i.schedule,timezone:i.timezone,agent:i.agent,prompt:i.prompt,timeout:i.timeout,model:i.model,maxOutputTokens:i.maxOutputTokens,onError:i.onError,consecutiveErrors:0,totalRuns:0,totalFailures:0})}setNotifyCallback(e){this.notifyCallback=e}async start(){this.running=!0,D(this.runsDir)||R(this.runsDir,{recursive:!0});let e=this.detectMissedRuns();if(e.length>0){this.log(`Detected ${e.length} missed cron run(s) while daemon was down:`);for(let{jobId:n,missedAt:t}of e)this.log(` "${n}" should have run at ${t.toISOString()}`);this.executeMissedRuns(e).catch(n=>{this.log(`Error executing missed runs: ${n.message}`)})}for(let[n,t]of this.jobs){if(!t.enabled){this.log(`Job "${n}" is disabled, skipping`);continue}this.scheduleNext(n)}this.log(`${this.jobs.size} cron job(s) loaded, ${Array.from(this.jobs.values()).filter(n=>n.enabled).length} enabled`)}async stop(){this.running=!1;for(let e of this.timers.values())clearTimeout(e);this.timers.clear(),this.saveLastRuns()}scheduleNext(e){let n=this.jobs.get(e);if(!n||!n.enabled||!this.running)return;let t=this.timers.get(e);t&&clearTimeout(t);try{let r=B(n.schedule,new Date,n.timezone);n.nextRun=r,n.retryPending=!1;let o=r.getTime()-Date.now();this.log(`Job "${e}" next run: ${r.toISOString()} (in ${Math.round(o/1e3)}s)`);let i=setTimeout(()=>this.executeJob(e),o);this.timers.set(e,i)}catch(r){this.log(`Failed to schedule "${e}": ${r.message}`)}}scheduleRetry(e,n){let t=this.jobs.get(e);if(!t||!t.enabled||!this.running)return;if(n>=I){this.log(`Job "${e}" exhausted all ${I} retries, scheduling next regular run`),this.scheduleNext(e);return}let r=w[n]||w[w.length-1];t.retryPending=!0,this.log(`Job "${e}" retry ${n+1}/${I} in ${Math.round(r/1e3)}s`);let o=setTimeout(()=>this.executeJob(e,n+1),r);this.timers.set(e,o)}recordCronDecisionInLedger(e,n,t,r){if(O("cron")!=="off")try{let o=J(x(),{jobId:e,agentId:n,firedAt:t},JSON.stringify({jobId:e,agentId:n,firedAt:t.toISOString()}),r);return o.outcome==="dispatched"?{eventId:o.eventId,decidedBy:o.decidedBy}:void 0}catch(o){this.log(`[ledger] cron "${e}" record failed: ${o?.message??o}`);return}}async executeJob(e,n=0){let t=this.jobs.get(e);if(!t||!this.running)return;let r=n>0,o=new Date;if(this.hooks?.has("pre:cron-run")){let a=await this.hooks.execute("pre:cron-run",{event:"pre:cron-run",jobId:e,agent:t.agent,prompt:t.prompt});if(a.blocked){this.log(`Job "${e}" blocked by hook: ${a.message}`),this.recordCronDecisionInLedger(e,t.agent,o,{agentId:null,outcome:"halted",reason:`pre-hook blocked: ${a.message??""}`.trim()}),this.scheduleNext(e);return}}this.log(`${r?`[retry ${n}] `:""}Executing job "${e}" -> agent "${t.agent}"`);let i=o;t.lastRun=i,t.totalRuns++;let c=this.recordCronDecisionInLedger(e,t.agent,o,{agentId:t.agent,outcome:"dispatched",reason:r?`retry ${n}`:null});try{let a=await this.registry.execute({message:F(t.prompt,t.maxOutputTokens),agentId:t.agent,model:t.model,intentRef:c,context:{channel:"cron",chatId:`cron:${e}`}}),u={jobId:e,startedAt:i,completedAt:new Date,success:!a.error,response:a.content,error:a.error,duration:a.duration||Date.now()-i.getTime(),isRetry:r,retryAttempt:n};if(a.error){if(t.consecutiveErrors++,t.totalFailures++,t.lastError=a.error,this.log(`Job "${e}" failed (${t.consecutiveErrors} consecutive): ${a.error}`),await this.notifyFailure(t,a.error),t.onError.includes("disable")&&t.consecutiveErrors>=3){t.enabled=!1,this.log(`Job "${e}" disabled after ${t.consecutiveErrors} consecutive errors`);try{let d=await C(p=>T(p,`crons.${e}.enabled`,!1),{reload:!1});d.success||this.log(`Failed to persist disable for "${e}": ${d.error}`)}catch(d){this.log(`Failed to persist disable for "${e}": ${d.message}`)}await this.notifyDisabled(t)}this.logRun(u),this.scheduleRetry(e,n);return}else t.consecutiveErrors>0&&this.log(`Job "${e}" recovered after ${t.consecutiveErrors} failure(s)`),t.consecutiveErrors=0,t.lastSuccess=new Date,t.lastError=void 0,t.retryPending=!1,this.log(`Job "${e}" completed in ${u.duration}ms`);this.logRun(u),this.hooks?.has("post:cron-run")&&await this.hooks.execute("post:cron-run",{event:"post:cron-run",jobId:e,success:u.success,duration:u.duration,error:u.error?new Error(u.error):void 0})}catch(a){t.consecutiveErrors++,t.totalFailures++,t.lastError=a.message,this.log(`Job "${e}" threw: ${a.message}`),await this.notifyFailure(t,a.message),this.scheduleRetry(e,n);return}this.saveLastRuns(),this.scheduleNext(e)}detectMissedRuns(){let e=[],n=this.loadLastRuns();if(!n)return e;for(let[t,r]of this.jobs){if(!r.enabled)continue;let o=n[t];if(!o)continue;let i=new Date(o);try{let c=B(r.schedule,i,r.timezone);c.getTime()<Date.now()&&e.push({jobId:t,missedAt:c})}catch{}}return e}async executeMissedRuns(e){for(let{jobId:n,missedAt:t}of e){let r=this.jobs.get(n);if(!(!r||!r.enabled)){this.log(`Running missed job "${n}" (was due at ${t.toISOString()})`);try{let o=await this.registry.execute({message:F(`[MISSED RUN \u2014 was scheduled for ${t.toISOString()}]
|
|
5
5
|
|
|
6
6
|
${r.prompt}`,r.maxOutputTokens),agentId:r.agent,context:{channel:"cron",chatId:`cron:${n}`}}),i={jobId:n,startedAt:new Date,completedAt:new Date,success:!o.error,response:o.content,error:o.error,duration:o.duration||0,isRetry:!1};this.logRun(i),o.error?this.log(`Missed job "${n}" failed: ${o.error}`):(this.log(`Missed job "${n}" completed`),r.lastSuccess=new Date),r.lastRun=new Date,r.totalRuns++}catch(o){this.log(`Missed job "${n}" threw: ${o.message}`)}}}this.saveLastRuns()}async notifyFailure(e,n){if(!(!e.onError.includes("notify")&&e.consecutiveErrors<2)){if(!this.notifyCallback){this.log(`[ALERT] Cron "${e.id}" failed (${e.consecutiveErrors}x): ${n.slice(0,200)}`);return}try{await this.notifyCallback(e.id,e.agent,n,e.consecutiveErrors)}catch{}}}async notifyDisabled(e){if(!this.notifyCallback){this.log(`[ALERT] Cron "${e.id}" has been DISABLED after ${e.consecutiveErrors} consecutive failures`);return}try{await this.notifyCallback(e.id,e.agent,`AUTO-DISABLED after ${e.consecutiveErrors} consecutive failures. Last error: ${e.lastError||"unknown"}`,e.consecutiveErrors)}catch{}}saveLastRuns(){try{let e={};for(let[t,r]of this.jobs)r.lastRun&&(e[t]=r.lastRun.toISOString());let n=v(process.cwd(),".agentx/cron");D(n)||R(n,{recursive:!0}),P(this.lastRunFile,JSON.stringify(e,null,2))}catch{}}loadLastRuns(){try{return D(this.lastRunFile)?JSON.parse(q(this.lastRunFile,"utf-8")):null}catch{return null}}logRun(e){try{let n=v(this.runsDir,e.jobId);D(n)||R(n,{recursive:!0});let t=`${e.startedAt.toISOString().replace(/[:.]/g,"-")}.json`;P(v(n,t),JSON.stringify(e,null,2))}catch{}}list(){return Array.from(this.jobs.values())}health(){let e=Array.from(this.jobs.values()),n=this.detectMissedRuns();return{healthy:e.filter(t=>t.enabled&&t.consecutiveErrors===0).length,failing:e.filter(t=>t.enabled&&t.consecutiveErrors>0).length,disabled:e.filter(t=>!t.enabled).length,missed:n.length,jobs:e.map(t=>({id:t.id,status:t.enabled?t.retryPending?"retrying":t.consecutiveErrors>0?"failing":"healthy":"disabled",consecutiveErrors:t.consecutiveErrors,lastError:t.lastError}))}}};export{O as a,X as b,k as c,M as d,B as e,G as f};
|
|
7
|
-
//# sourceMappingURL=chunk-
|
|
7
|
+
//# sourceMappingURL=chunk-PD5Q7D6Z.js.map
|
|
@@ -48,7 +48,7 @@ The "modified" field is optional and can contain updated values to pass forward.
|
|
|
48
48
|
... (output truncated)`:i;return s.exitCode!==0?{tool_use_id:e.id,content:`Command exited with code ${s.exitCode}:
|
|
49
49
|
${l}`,is_error:!0}:{tool_use_id:e.id,content:l||"(no output)"}}async editFile(e){let t=String(e.input.path||""),o=e.input.edits,n=pe.resolve(this.cwd,t);if(!o||o.length===0)return{tool_use_id:e.id,content:"No edits provided.",is_error:!0};let s=await N.checkFileWrite(t);if(s==="deny")return{tool_use_id:e.id,content:`File write blocked by permissions: ${t}`,is_error:!0};if(s==="skip")return{tool_use_id:e.id,content:`File write skipped (plan mode): ${t}`};if(d.has("pre:file-write")){let a=await d.execute("pre:file-write",{event:"pre:file-write",file:n,cwd:this.cwd});if(a.blocked)return{tool_use_id:e.id,content:a.message||`File edit blocked by pre:file-write hook: ${t}`,is_error:!0}}let i=await ee.readFile(n,"utf8"),l=[];for(let a of o)i.includes(a.old_text)?(i=i.replace(a.old_text,a.new_text),l.push(`Replaced: "${a.old_text.slice(0,40)}..."`)):l.push(`Not found: "${a.old_text.slice(0,40)}..."`);return this.options.dryRun||await ee.writeFile(n,i,"utf8"),d.has("post:file-write")&&await d.execute("post:file-write",{event:"post:file-write",file:n,fileContent:i,cwd:this.cwd}),{tool_use_id:e.id,content:`Edited ${t}:
|
|
50
50
|
${l.join(`
|
|
51
|
-
`)}`}}async createFiles(e){let t=e.input,o=t.files||[];return{tool_use_id:e.id,content:t.summary||`Queued ${o.length} file(s) for creation.`,files:o}}async spawnAgent(e){let t=String(e.input.agent_id||""),o=String(e.input.prompt||""),n=Number(e.input.timeout_seconds)||300;if(!t||!o)return{tool_use_id:e.id,content:"agent_id and prompt are required.",is_error:!0};try{let{SubAgentManager:s}=await import("./subagent-WV7QKQ3L.js"),{getGlobalRegistry:i}=await import("./registry-
|
|
51
|
+
`)}`}}async createFiles(e){let t=e.input,o=t.files||[];return{tool_use_id:e.id,content:t.summary||`Queued ${o.length} file(s) for creation.`,files:o}}async spawnAgent(e){let t=String(e.input.agent_id||""),o=String(e.input.prompt||""),n=Number(e.input.timeout_seconds)||300;if(!t||!o)return{tool_use_id:e.id,content:"agent_id and prompt are required.",is_error:!0};try{let{SubAgentManager:s}=await import("./subagent-WV7QKQ3L.js"),{getGlobalRegistry:i}=await import("./registry-42HEWCLA.js"),l=i();if(!l)return{tool_use_id:e.id,content:"Sub-agent spawning requires the daemon to be running.",is_error:!0};let p=await new s(l).spawn({targetAgentId:t,prompt:o,parentAgentId:"orchestrator",timeout:n*1e3});return p.success?{tool_use_id:e.id,content:`Sub-agent "${t}" completed (${Math.round(p.duration/1e3)}s):
|
|
52
52
|
|
|
53
53
|
${p.content}`}:{tool_use_id:e.id,content:`Sub-agent "${t}" failed: ${p.error}`,is_error:!0}}catch(s){return{tool_use_id:e.id,content:`Failed to spawn sub-agent: ${s.message}`,is_error:!0}}}async askUser(e){let t=String(e.input.question||""),o=e.input.options,n=t;return o?.length&&(n+=`
|
|
54
54
|
Options: ${o.join(", ")}`),{tool_use_id:e.id,content:"Question sent to user.",followUp:n}}};async function Re(r){let{provider:e,systemPrompt:t,messages:o,providerOptions:n,cwd:s,maxIterations:i=20,enabledTools:l,interactive:a=!0,overwrite:p=!1,dryRun:c=!1,onProgress:u}=r;if(!e.generateRaw)return et(r);let y=new te(s,{interactive:a,overwrite:p,dryRun:c}),k=he(l),A=o.filter(v=>v.role!=="system").map(v=>({role:v.role,content:v.content})),F=[],C=0,T="",I,O=0;for(;O<i;){O++,u?.({type:"iteration_start",iteration:O}),x.step(O,`Agentic loop iteration (${k.length} tools available)`);let v;try{v=await e.generateRaw(A,t,k,n)}catch(w){if(w.message?.includes("not available"))return et(r);throw w}C+=v.usage.input_tokens+v.usage.output_tokens;for(let w of v.content)w.type==="text"&&(T+=w.text,u?.({type:"text_delta",text:w.text}));if(v.stop_reason==="end_turn"||v.stop_reason==="max_tokens")break;if(v.stop_reason==="tool_use"){let w=v.content.filter(_=>_.type==="tool_use");if(w.length===0)break;A.push({role:"assistant",content:v.content});let E=[];for(let _ of w){u?.({type:"tool_call",name:_.name,id:_.id,input:_.input}),x.step(O,`Tool call: ${_.name}`);let b=await y.execute({name:_.name,id:_.id,input:_.input});u?.({type:"tool_result",name:_.name,id:_.id,content:b.content.slice(0,200),is_error:b.is_error}),b.files?.length&&(F.push(...b.files),u?.({type:"files_created",files:b.files})),b.followUp&&(I=b.followUp),E.push({type:"tool_result",tool_use_id:b.tool_use_id,content:b.content,is_error:b.is_error})}if(A.push({role:"user",content:E}),I)break;continue}break}return u?.({type:"complete",iterations:O,totalTokens:C}),{files:F,content:T,followUp:I,tokensUsed:C,iterations:O}}async function et(r){let{provider:e,systemPrompt:t,messages:o,providerOptions:n,maxIterations:s=5}=r,l=[{role:"system",content:t+`
|
|
@@ -115,4 +115,4 @@ ${r.projectInstructions}`),r.memoryContext&&o.push(r.memoryContext),o.push(`# Ou
|
|
|
115
115
|
Generate output appropriate for: ${e}. Use the \`create_files\` tool to output all files.`),o.join(`
|
|
116
116
|
|
|
117
117
|
`)}export{je as a,$t as b,Mt as c,Ue as d,De as e,Ne as f,Le as g,_e as h,V as i,Se as j,re as k,Q as l,ut as m,X as n,ht as o,d as p,ze as q,Ke as r,Pe as s,ie as t,N as u,Z as v,Xe as w,Te as x,Ce as y,te as z,tt as A,Cn as B,Tn as C};
|
|
118
|
-
//# sourceMappingURL=chunk-
|
|
118
|
+
//# sourceMappingURL=chunk-Q6CAFGXT.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
var y=new Map,X=/^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)*$/;function h(t){if(!X.test(t.name))throw new Error(`built-in action name must be dotted lowercase identifier (got "${t.name}")`);y.set(t.name,t)}function Y(t){return y.get(t)}function q(){let t=[];for(let[n,e]of y.entries())t.push({name:n,description:e.description,timeoutMs:e.timeoutMs});return t.sort((n,e)=>n.name.localeCompare(e.name)),t}function I(){y.clear()}var G=6e4;async function K(t,n){let e=y.get(t);if(!e)throw new Error(`unknown built-in action: ${t}`);let r=e.inputSchema.parse(n),o=e.timeoutMs??G,s=e.handler(r),i=new Promise((f,g)=>{setTimeout(()=>g(new Error(`built-in action ${t} timed out after ${o}ms`)),o)}),a=await Promise.race([s,i]),p=e.outputSchema.safeParse(a);return p.success||process.stderr.write(`[builtin-action] ${t} output failed schema validation: ${p.error.message}
|
|
2
|
+
`),a}import{z as l}from"zod";var V=l.object({model:l.string().default("claude-haiku-4-5"),prompt:l.string().min(1),schema:l.record(l.string(),l.unknown()),systemPrompt:l.string().optional(),maxTokens:l.number().int().min(1).max(8e3).default(1024),timeoutMs:l.number().int().min(1).max(12e4).default(6e4)}),Q=l.object({data:l.unknown(),model:l.string(),usage:l.object({inputTokens:l.number().int(),outputTokens:l.number().int()})}),Z="https://api.anthropic.com/v1/messages",tt="2023-06-01",_={name:"extract.structured",description:"Single-call typed extraction: prompt + JSON-Schema \u2192 structured data via forced tool_use",inputSchema:V,outputSchema:Q,timeoutMs:12e4,handler:async t=>{let n=process.env.ANTHROPIC_API_KEY;if(!n)throw new Error("ANTHROPIC_API_KEY env var is not set \u2014 extract.structured needs direct API access");let e={model:t.model,max_tokens:t.maxTokens,messages:[{role:"user",content:t.prompt}],tools:[{name:"respond_with_structure",description:"Return a structured value matching the schema",input_schema:t.schema}],tool_choice:{type:"tool",name:"respond_with_structure"}};t.systemPrompt&&(e.system=t.systemPrompt);let r=new AbortController,o=setTimeout(()=>r.abort(),t.timeoutMs),s;try{s=await fetch(Z,{method:"POST",headers:{"Content-Type":"application/json","x-api-key":n,"anthropic-version":tt},body:JSON.stringify(e),signal:r.signal})}finally{clearTimeout(o)}if(!s.ok){let g=await s.text().catch(()=>"");throw new Error(`anthropic API ${s.status}: ${g.slice(0,500)}`)}let i=await s.json(),a=Array.isArray(i.content)?i.content:[],p=a.find(g=>g?.type==="tool_use"&&g?.name==="respond_with_structure");if(!p||p.input===void 0)throw new Error(`anthropic API returned no respond_with_structure tool_use (got ${a.length} blocks)`);let f=i.usage??{};return{data:p.input,model:typeof i.model=="string"?i.model:t.model,usage:{inputTokens:typeof f.input_tokens=="number"?f.input_tokens:0,outputTokens:typeof f.output_tokens=="number"?f.output_tokens:0}}}};import{z as c}from"zod";import{existsSync as et,readFileSync as nt,appendFileSync as rt,mkdirSync as ot,statSync as st}from"fs";import{resolve as A,dirname as it,isAbsolute as at}from"path";var O=8*1024*1024;function M(t){let n=at(t)?t:A(process.cwd(),t),r=(process.env.AGENTX_BUILTIN_FILE_ROOTS||process.cwd()).split(":").map(o=>A(o));for(let o of r)if(n===o||n.startsWith(o+"/"))return n;throw new Error(`path "${t}" is outside the allowed roots`)}var ct=c.object({path:c.string().min(1),maxLines:c.number().int().min(1).max(1e4).default(200),fromEnd:c.boolean().default(!1)}),ut=c.object({path:c.string(),lines:c.array(c.string()),totalLines:c.number().int(),truncated:c.boolean()}),T={name:"file.read_lines",description:"Read a text file as an array of lines (utf-8, 8MB cap, scoped to allowed roots)",inputSchema:ct,outputSchema:ut,timeoutMs:1e4,handler:async t=>{let n=M(t.path);if(!et(n))throw new Error(`file not found: ${t.path}`);let e=st(n);if(!e.isFile())throw new Error(`not a regular file: ${t.path}`);if(e.size>O)throw new Error(`file too large (${e.size} > ${O} bytes)`);let o=nt(n,"utf8").split(`
|
|
3
|
+
`);o.length>0&&o[o.length-1]===""&&o.pop();let s=o.length,i,a;return s<=t.maxLines?(i=o,a=!1):(a=!0,i=t.fromEnd?o.slice(s-t.maxLines):o.slice(0,t.maxLines)),{path:n,lines:i,totalLines:s,truncated:a}}},lt=c.object({path:c.string().min(1),records:c.array(c.unknown()).min(1),createDirs:c.boolean().default(!1)}),pt=c.object({path:c.string(),written:c.number().int(),bytesAppended:c.number().int()}),E={name:"file.write_jsonl",description:"Append JSON records to a file as newline-delimited JSON (utf-8, scoped to allowed roots)",inputSchema:lt,outputSchema:pt,timeoutMs:1e4,handler:async t=>{let n=M(t.path),e=[];for(let o of t.records)try{e.push(JSON.stringify(o))}catch(s){throw new Error(`record ${e.length} not JSON-serializable: ${s?.message||String(s)}`)}let r=e.join(`
|
|
4
|
+
`)+`
|
|
5
|
+
`;return t.createDirs&&ot(it(n),{recursive:!0}),rt(n,r,"utf8"),{path:n,written:e.length,bytesAppended:Buffer.byteLength(r,"utf8")}}};import{z as u}from"zod";var B=1024*1024,b=u.record(u.string(),u.string()),dt=["http:","https:"];function D(t){let n;try{n=new URL(t)}catch{throw new Error(`invalid url: ${t}`)}if(!dt.includes(n.protocol))throw new Error(`scheme not allowed (only http/https): ${n.protocol}`);return n}var mt=u.object({url:u.string().min(1),headers:b.optional(),timeoutMs:u.number().int().min(1).max(6e4).default(3e4)}),L=u.object({status:u.number().int(),statusText:u.string(),headers:b,body:u.string(),truncated:u.boolean(),url:u.string()});async function k(t){if(!t.body)return{body:"",truncated:!1};let n=t.body.getReader(),e=new TextDecoder,r=0,o="",s=!1;for(;;){let{done:i,value:a}=await n.read();if(i)break;if(a){if(r+=a.length,r>B){o+=e.decode(a.slice(0,B-(r-a.length)),{stream:!1}),s=!0;try{await n.cancel()}catch{}break}o+=e.decode(a,{stream:!0})}}return o+=e.decode(),{body:o,truncated:s}}function R(t){let n={};return t.forEach((e,r)=>{n[r]=e}),n}var P={name:"http.fetch",description:"GET a URL, return body + status + headers (1MB cap, http/https only)",inputSchema:mt,outputSchema:L,timeoutMs:35e3,handler:async t=>{D(t.url);let n=new AbortController,e=setTimeout(()=>n.abort(),t.timeoutMs);try{let r=await fetch(t.url,{method:"GET",headers:t.headers??{},signal:n.signal}),{body:o,truncated:s}=await k(r);return{status:r.status,statusText:r.statusText,headers:R(r.headers),body:o,truncated:s,url:r.url}}finally{clearTimeout(e)}}},ft=u.object({url:u.string().min(1),body:u.unknown(),headers:b.optional(),timeoutMs:u.number().int().min(1).max(6e4).default(3e4)}),z={name:"http.post",description:"POST a JSON body to a URL, return body + status + headers (1MB cap, http/https only)",inputSchema:ft,outputSchema:L,timeoutMs:35e3,handler:async t=>{D(t.url);let n=new AbortController,e=setTimeout(()=>n.abort(),t.timeoutMs);try{let r={"Content-Type":"application/json",...t.headers??{}},o=await fetch(t.url,{method:"POST",headers:r,body:JSON.stringify(t.body??{}),signal:n.signal}),{body:s,truncated:i}=await k(o);return{status:o.status,statusText:o.statusText,headers:R(o.headers),body:s,truncated:i,url:o.url}}finally{clearTimeout(e)}}};import{z as m}from"zod";var v=null;function F(){return v}function jt(t){v=t}var ht=m.object({peer:m.string().min(1),agent:m.string().optional(),message:m.string().min(1),timeoutMs:m.number().int().min(1).max(6e5).default(9e4),senderAgentId:m.string().optional()}),gt=m.object({peer:m.string(),agent:m.string().nullable(),response:m.string()}),$={name:"mesh.delegate",description:"Send a task to a remote mesh peer's agent and return the response text",inputSchema:ht,outputSchema:gt,timeoutMs:6e5,handler:async t=>{let n=F();if(!n)throw new Error("mesh not enabled on this daemon (config.mesh.enabled = false)");let e=await n.sendTask(t.peer,t.message,t.agent,{timeoutMs:t.timeoutMs,senderAgentId:t.senderAgentId});return{peer:t.peer,agent:t.agent??null,response:e}}};import{z as d}from"zod";import{existsSync as j,mkdirSync as yt,readFileSync as w,writeFileSync as bt,statSync as xt}from"fs";import{resolve as N,basename as wt,relative as St}from"path";import It from"fast-glob";import J from"minisearch";var C=["title","body"],U=["title","body","path","indexedAt"];function S(t,n=".agentx/rag"){return N(process.cwd(),n,t,"index.json")}function _t(){return new J({fields:C,storeFields:U,searchOptions:{boost:{title:2},fuzzy:.2,prefix:!0}})}function At(t,n){let e=w(t,"utf8"),r=e.match(/^\s*#\s+(.+)$/m),o=r?r[1].trim():wt(t).replace(/\.[^.]+$/,"");return{id:n,title:o,body:e,path:t,indexedAt:new Date().toISOString()}}async function qt(t,n,e={}){let r=e.cwd??process.cwd(),o=(await It(n,{cwd:r,absolute:!0,dot:!1})).filter(a=>{try{return xt(a).isFile()}catch{return!1}}),s=_t();for(let a of o){let p=St(r,a),f=At(a,p);s.add(f),e.verbose&&process.stderr.write(`[rag] indexed ${p} (${f.body.length} bytes)
|
|
6
|
+
`)}let i=S(t,e.baseDir);return yt(N(i,".."),{recursive:!0}),bt(i,JSON.stringify(s.toJSON()),"utf8"),{docs:o.length,path:i}}function Ot(t,n={}){let e=S(t,n.baseDir);if(!j(e))return null;try{let r=w(e,"utf8");return J.loadJSON(r,{fields:C,storeFields:U,searchOptions:{boost:{title:2},fuzzy:.2,prefix:!0}})}catch(r){return process.stderr.write(`[rag] failed to load ${e}: ${r?.message||String(r)}
|
|
7
|
+
`),null}}var x=80,Mt=x*2+60;function Tt(t,n){let e=t.toLowerCase(),r=-1;for(let a of n){let p=e.indexOf(a.toLowerCase());p>=0&&(r===-1||p<r)&&(r=p)}if(r===-1)return t.slice(0,Mt).replace(/\s+/g," ").trim();let o=Math.max(0,r-x),s=Math.min(t.length,r+x),i=t.slice(o,s).replace(/\s+/g," ").trim();return(o>0?"\u2026":"")+i+(s<t.length?"\u2026":"")}function H(t,n,e={}){let r=Ot(t,{baseDir:e.baseDir});if(!r)return[];let o=Math.max(1,Math.min(50,e.k??5));return r.search(n).slice(0,o).map(i=>({id:i.id,title:i.title,path:i.path,score:i.score,snippet:Tt(i.body||"",i.terms||[])}))}function Gt(t,n={}){let e=S(t,n.baseDir);if(!j(e))return{exists:!1,path:e,docs:0};try{let r=JSON.parse(w(e,"utf8")),o=r?.storedFields??r?._storedFields;if(typeof r?.documentCount=="number")return{exists:!0,path:e,docs:r.documentCount};let s=o&&typeof o=="object"?Object.keys(o).length:0;return{exists:!0,path:e,docs:s}}catch{return{exists:!0,path:e,docs:0}}}var Et=d.object({agentId:d.string().min(1),query:d.string().min(1),k:d.number().int().min(1).max(50).default(5)}),Bt=d.object({hits:d.array(d.object({id:d.string(),title:d.string(),path:d.string(),score:d.number(),snippet:d.string()}))}),W={name:"rag.lexical",description:"BM25-style lexical search over an agent's pre-built index (no embeddings, deterministic)",inputSchema:Et,outputSchema:Bt,timeoutMs:5e3,handler:async t=>({hits:H(t.agentId,t.query,{k:t.k})})};function ie(){h(_),h(T),h(E),h(P),h(z),h($),h(W)}function ae(){I()}export{Y as a,q as b,K as c,jt as d,qt as e,H as f,Gt as g,ie as h,ae as i};
|
|
8
|
+
//# sourceMappingURL=chunk-ZZFXI3CS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/actions/builtin/registry.ts","../src/actions/builtin/extract.ts","../src/actions/builtin/file.ts","../src/actions/builtin/http.ts","../src/actions/builtin/mesh.ts","../src/a2a/mesh-instance.ts","../src/actions/builtin/rag.ts","../src/rag/lexical-index.ts","../src/actions/builtin/index.ts"],"sourcesContent":["import type { BuiltinAction, BuiltinActionMetadata } from \"./types\"\n\n// --- Built-in action registry ---\n//\n// Process-global. Built-ins register at module-load time via the\n// barrel in ./index.ts; the daemon never has to wire them up\n// explicitly. Lookup is O(1).\n\nconst _registry = new Map<string, BuiltinAction>()\n\nconst NAME_PATTERN = /^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)*$/\n\n/**\n * Register a built-in. Idempotent — re-registering the same name\n * overwrites (useful for tests). Throws on malformed names so the\n * dotted-namespace contract stays consistent across the codebase.\n */\nexport function registerBuiltin<I, O>(action: BuiltinAction<I, O>): void {\n if (!NAME_PATTERN.test(action.name)) {\n throw new Error(`built-in action name must be dotted lowercase identifier (got \"${action.name}\")`)\n }\n _registry.set(action.name, action as BuiltinAction)\n}\n\nexport function getBuiltin(name: string): BuiltinAction | undefined {\n return _registry.get(name)\n}\n\n/** List metadata for every registered built-in, sorted by name. The\n * full schemas aren't included here — operators fetch the JSON-schema\n * rendering separately to keep the list response small. */\nexport function listBuiltins(): BuiltinActionMetadata[] {\n const out: BuiltinActionMetadata[] = []\n for (const [name, a] of _registry.entries()) {\n out.push({ name, description: a.description, timeoutMs: a.timeoutMs })\n }\n out.sort((a, b) => a.name.localeCompare(b.name))\n return out\n}\n\n/** Test-only — wipe the registry between cases. Production never clears. */\nexport function _resetBuiltinsForTesting(): void {\n _registry.clear()\n}\n\nconst DEFAULT_TIMEOUT_MS = 60_000\n\n/**\n * Run a built-in. Wraps the handler in:\n * - input validation (Zod parse — throws on bad shape)\n * - per-action timeout (with daemon-default fallback)\n * - output validation (Zod parse — log on mismatch but pass through;\n * output drift shouldn't break callers, just signal)\n *\n * Returns the validated output, or rejects on timeout / handler error.\n * Callers (HTTP route, CLI) catch and translate to error responses.\n */\nexport async function runBuiltin<I, O>(name: string, rawInput: unknown): Promise<O> {\n const action = _registry.get(name) as BuiltinAction<I, O> | undefined\n if (!action) {\n throw new Error(`unknown built-in action: ${name}`)\n }\n const input = action.inputSchema.parse(rawInput) as I\n const timeoutMs = action.timeoutMs ?? DEFAULT_TIMEOUT_MS\n\n const handlerPromise = action.handler(input)\n const timeoutPromise = new Promise<O>((_, reject) => {\n setTimeout(() => reject(new Error(`built-in action ${name} timed out after ${timeoutMs}ms`)), timeoutMs)\n })\n\n const output = await Promise.race([handlerPromise, timeoutPromise])\n\n // Soft validation on output — log mismatches but pass the value\n // through. A handler that drifts from its schema shouldn't break\n // production; surfacing the drift in the daemon log is enough signal.\n const parsed = action.outputSchema.safeParse(output)\n if (!parsed.success) {\n process.stderr.write(`[builtin-action] ${name} output failed schema validation: ${parsed.error.message}\\n`)\n }\n return output\n}\n","import { z } from \"zod\"\nimport type { BuiltinAction } from \"./types\"\n\n// --- extract.structured ---\n//\n// Single-call structured extraction: ask Claude for a JSON value\n// matching a caller-supplied JSON-Schema. The agent / workflow gets\n// typed structured data back — no parser needed downstream.\n//\n// Implementation: Anthropic Messages API with a forced tool_use whose\n// input_schema is the caller's schema. Forced tool use guarantees the\n// model's response is the structured value, not free-form text. We\n// extract the tool's `input` and return it verbatim.\n//\n// Why we hit the API directly instead of routing through the\n// claude-code subprocess (or the SDK):\n// - The persistent-process path keeps a turn slot busy for >2s\n// even on warm cache; for a single extraction this is overkill.\n// - The SDK adds a 10MB+ dependency; raw fetch needs zero new deps.\n// - The model + auth are the same — ANTHROPIC_API_KEY env var.\n//\n// Input shape:\n// model: Anthropic model id (\"claude-sonnet-4-6\" / \"claude-haiku-4-5\" / etc.)\n// prompt: User-message text the model extracts from.\n// schema: JSON-Schema-shaped object (NOT a Zod schema) — this is what\n// the model is told to fill in. Caller-defined.\n// maxTokens: Output-token cap, default 1024.\n//\n// Output shape:\n// data: The structured value, exactly as the model returned it.\n// Validated only against \"is an object/array/scalar\" — the\n// caller's schema is the contract; we don't re-validate\n// because that would require shipping a JSON-Schema validator.\n// usage: Token counts for cost accounting.\n// model: Model that actually billed (echoed from the response).\n\nconst extractInput = z.object({\n model: z.string().default(\"claude-haiku-4-5\"),\n prompt: z.string().min(1),\n /** JSON-Schema describing the output shape. Passed to the Claude\n * API as the input_schema of a forced tool_use. */\n schema: z.record(z.string(), z.unknown()),\n /** Optional system prompt prepended to the conversation. */\n systemPrompt: z.string().optional(),\n maxTokens: z.number().int().min(1).max(8_000).default(1024),\n /** Per-call timeout. Default 60s. */\n timeoutMs: z.number().int().min(1).max(120_000).default(60_000),\n})\ntype ExtractInput = z.infer<typeof extractInput>\n\nconst extractOutput = z.object({\n data: z.unknown(),\n model: z.string(),\n usage: z.object({\n inputTokens: z.number().int(),\n outputTokens: z.number().int(),\n }),\n})\ntype ExtractOutput = z.infer<typeof extractOutput>\n\nconst ANTHROPIC_API = \"https://api.anthropic.com/v1/messages\"\nconst ANTHROPIC_VERSION = \"2023-06-01\"\n\nexport const extractStructured: BuiltinAction<ExtractInput, ExtractOutput> = {\n name: \"extract.structured\",\n description: \"Single-call typed extraction: prompt + JSON-Schema → structured data via forced tool_use\",\n inputSchema: extractInput,\n outputSchema: extractOutput,\n timeoutMs: 120_000,\n handler: async (input) => {\n const apiKey = process.env.ANTHROPIC_API_KEY\n if (!apiKey) {\n throw new Error(\"ANTHROPIC_API_KEY env var is not set — extract.structured needs direct API access\")\n }\n\n // Use a forced tool_use with input_schema = the caller's schema.\n // tool_choice: { type: \"tool\", name: \"respond_with_structure\" }\n // makes the model produce a tool_use block as the entire reply,\n // whose `input` field IS the structured value.\n const requestBody: Record<string, unknown> = {\n model: input.model,\n max_tokens: input.maxTokens,\n messages: [{ role: \"user\", content: input.prompt }],\n tools: [{\n name: \"respond_with_structure\",\n description: \"Return a structured value matching the schema\",\n input_schema: input.schema,\n }],\n tool_choice: { type: \"tool\", name: \"respond_with_structure\" },\n }\n if (input.systemPrompt) {\n requestBody.system = input.systemPrompt\n }\n\n const ctrl = new AbortController()\n const t = setTimeout(() => ctrl.abort(), input.timeoutMs)\n let res: Response\n try {\n res = await fetch(ANTHROPIC_API, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-api-key\": apiKey,\n \"anthropic-version\": ANTHROPIC_VERSION,\n },\n body: JSON.stringify(requestBody),\n signal: ctrl.signal,\n })\n } finally {\n clearTimeout(t)\n }\n\n if (!res.ok) {\n const errBody = await res.text().catch(() => \"\")\n throw new Error(`anthropic API ${res.status}: ${errBody.slice(0, 500)}`)\n }\n const body: any = await res.json()\n const blocks = Array.isArray(body.content) ? body.content : []\n const toolUse = blocks.find((b: any) => b?.type === \"tool_use\" && b?.name === \"respond_with_structure\")\n if (!toolUse || toolUse.input === undefined) {\n throw new Error(`anthropic API returned no respond_with_structure tool_use (got ${blocks.length} blocks)`)\n }\n\n const usage = body.usage ?? {}\n return {\n data: toolUse.input,\n model: typeof body.model === \"string\" ? body.model : input.model,\n usage: {\n inputTokens: typeof usage.input_tokens === \"number\" ? usage.input_tokens : 0,\n outputTokens: typeof usage.output_tokens === \"number\" ? usage.output_tokens : 0,\n },\n }\n },\n}\n","import { z } from \"zod\"\nimport { existsSync, readFileSync, appendFileSync, mkdirSync, statSync } from \"fs\"\nimport { resolve, dirname, isAbsolute } from \"path\"\nimport type { BuiltinAction } from \"./types\"\n\n// --- Built-in file actions ---\n//\n// file.read_lines — read a text file, return up to maxLines string lines\n// file.write_jsonl — append N JSON objects as newline-delimited records\n//\n// Both are workspace-scoped: paths must resolve under one of the\n// allowed roots set via AGENTX_BUILTIN_FILE_ROOTS env var (or the cwd\n// by default). This is the boundary that keeps an agent from reading\n// /etc/passwd or writing into the daemon's own .agentx state. Path\n// traversal (../..) is rejected via the resolved-path containment\n// check, not regex on the input.\n//\n// Why these two specifically (per improvement plan #6 catalog):\n// - read_lines: typed plumbing for \"give me the last N log lines\"\n// pattern that workflows currently shell out to `tail` for.\n// - write_jsonl: typed plumbing for \"log a structured event into\n// this agent's working file\" — the workflow-as-program framing\n// wants this as a primitive, not as `echo {} >> file`.\n\nconst MAX_FILE_BYTES = 8 * 1024 * 1024 // 8 MB cap on read\n\n/**\n * Resolve and validate a target path against the allowed roots.\n * Returns the absolute path on success; throws otherwise. Allowed\n * roots default to process.cwd() unless the operator overrides via\n * AGENTX_BUILTIN_FILE_ROOTS (colon-separated). This mirrors how\n * Claude Code's own --add-dir flag is applied at spawn.\n */\nfunction resolveAllowed(input: string): string {\n const abs = isAbsolute(input) ? input : resolve(process.cwd(), input)\n const rootsEnv = process.env.AGENTX_BUILTIN_FILE_ROOTS || process.cwd()\n const roots = rootsEnv.split(\":\").map((r) => resolve(r))\n for (const root of roots) {\n if (abs === root || abs.startsWith(root + \"/\")) return abs\n }\n throw new Error(`path \"${input}\" is outside the allowed roots`)\n}\n\nconst readLinesInput = z.object({\n path: z.string().min(1),\n /** Cap the returned line count. Default 200, hard cap 10000. */\n maxLines: z.number().int().min(1).max(10_000).default(200),\n /** When true, return only the LAST maxLines (tail-style). Default false (head). */\n fromEnd: z.boolean().default(false),\n})\ntype ReadLinesInput = z.infer<typeof readLinesInput>\n\nconst readLinesOutput = z.object({\n path: z.string(),\n lines: z.array(z.string()),\n totalLines: z.number().int(),\n truncated: z.boolean(),\n})\ntype ReadLinesOutput = z.infer<typeof readLinesOutput>\n\nexport const fileReadLines: BuiltinAction<ReadLinesInput, ReadLinesOutput> = {\n name: \"file.read_lines\",\n description: \"Read a text file as an array of lines (utf-8, 8MB cap, scoped to allowed roots)\",\n inputSchema: readLinesInput,\n outputSchema: readLinesOutput,\n timeoutMs: 10_000,\n handler: async (input) => {\n const abs = resolveAllowed(input.path)\n if (!existsSync(abs)) throw new Error(`file not found: ${input.path}`)\n const stat = statSync(abs)\n if (!stat.isFile()) throw new Error(`not a regular file: ${input.path}`)\n if (stat.size > MAX_FILE_BYTES) {\n throw new Error(`file too large (${stat.size} > ${MAX_FILE_BYTES} bytes)`)\n }\n const content = readFileSync(abs, \"utf8\")\n // Split on \\n but drop a trailing empty token if the file ended in \\n —\n // the canonical \"logs end with a newline\" case.\n const all = content.split(\"\\n\")\n if (all.length > 0 && all[all.length - 1] === \"\") all.pop()\n const totalLines = all.length\n let lines: string[]\n let truncated: boolean\n if (totalLines <= input.maxLines) {\n lines = all\n truncated = false\n } else {\n truncated = true\n lines = input.fromEnd ? all.slice(totalLines - input.maxLines) : all.slice(0, input.maxLines)\n }\n return { path: abs, lines, totalLines, truncated }\n },\n}\n\nconst writeJsonlInput = z.object({\n path: z.string().min(1),\n /** Records to append, one JSON line each. Each must be a JSON-serializable\n * value; non-serializable inputs are rejected before any FS write. */\n records: z.array(z.unknown()).min(1),\n /** When true, ensure the parent directory exists (mkdir -p). Default false. */\n createDirs: z.boolean().default(false),\n})\ntype WriteJsonlInput = z.infer<typeof writeJsonlInput>\n\nconst writeJsonlOutput = z.object({\n path: z.string(),\n written: z.number().int(),\n bytesAppended: z.number().int(),\n})\ntype WriteJsonlOutput = z.infer<typeof writeJsonlOutput>\n\nexport const fileWriteJsonl: BuiltinAction<WriteJsonlInput, WriteJsonlOutput> = {\n name: \"file.write_jsonl\",\n description: \"Append JSON records to a file as newline-delimited JSON (utf-8, scoped to allowed roots)\",\n inputSchema: writeJsonlInput,\n outputSchema: writeJsonlOutput,\n timeoutMs: 10_000,\n handler: async (input) => {\n const abs = resolveAllowed(input.path)\n\n // Pre-serialize EVERYTHING before opening the file so a bad\n // record can't leave a half-written file behind. Each record\n // becomes one JSON line; embedded newlines in strings are\n // escaped naturally by JSON.stringify.\n const lines: string[] = []\n for (const r of input.records) {\n try {\n lines.push(JSON.stringify(r))\n } catch (e: any) {\n throw new Error(`record ${lines.length} not JSON-serializable: ${e?.message || String(e)}`)\n }\n }\n const payload = lines.join(\"\\n\") + \"\\n\"\n\n if (input.createDirs) {\n mkdirSync(dirname(abs), { recursive: true })\n }\n appendFileSync(abs, payload, \"utf8\")\n return { path: abs, written: lines.length, bytesAppended: Buffer.byteLength(payload, \"utf8\") }\n },\n}\n","import { z } from \"zod\"\nimport type { BuiltinAction } from \"./types\"\n\n// --- Built-in HTTP actions ---\n//\n// http.fetch — typed GET, returns body+status+headers\n// http.post — typed POST with JSON body, same response shape\n//\n// Why bake these in when agents already have Bash + curl: the typed\n// shape lets workflows pipe response data into structured downstream\n// nodes without parsing curl output. Headers and status are\n// first-class. Errors are returned as a result, not thrown — so\n// workflow conditional nodes can branch on them.\n//\n// Body size is capped at 1MB to keep responses bounded; truncate is\n// reported back. Allowed schemes are http and https only — file:// /\n// data:// / etc. would let an agent read arbitrary local resources\n// through this action, which violates the \"agents talk over the\n// network\" boundary.\n\nconst MAX_BODY_BYTES = 1024 * 1024 // 1 MB\n\nconst HEADER_RECORD = z.record(z.string(), z.string())\n\nconst allowedSchemes = [\"http:\", \"https:\"] as const\n\nfunction assertAllowed(url: string): URL {\n let u: URL\n try { u = new URL(url) }\n catch { throw new Error(`invalid url: ${url}`) }\n if (!(allowedSchemes as readonly string[]).includes(u.protocol)) {\n throw new Error(`scheme not allowed (only http/https): ${u.protocol}`)\n }\n return u\n}\n\nconst fetchInput = z.object({\n url: z.string().min(1),\n headers: HEADER_RECORD.optional(),\n /** Per-call timeout in ms. Default 30s. Capped at the registry's\n * 60s ceiling regardless. */\n timeoutMs: z.number().int().min(1).max(60_000).default(30_000),\n})\ntype FetchInput = z.infer<typeof fetchInput>\n\nconst fetchOutput = z.object({\n status: z.number().int(),\n statusText: z.string(),\n headers: HEADER_RECORD,\n body: z.string(),\n truncated: z.boolean(),\n url: z.string(),\n})\ntype FetchOutput = z.infer<typeof fetchOutput>\n\nasync function readCappedText(res: Response): Promise<{ body: string; truncated: boolean }> {\n if (!res.body) return { body: \"\", truncated: false }\n const reader = res.body.getReader()\n const dec = new TextDecoder()\n let total = 0\n let body = \"\"\n let truncated = false\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n if (value) {\n total += value.length\n if (total > MAX_BODY_BYTES) {\n // Keep what we have, mark truncated, stop reading.\n body += dec.decode(value.slice(0, MAX_BODY_BYTES - (total - value.length)), { stream: false })\n truncated = true\n try { await reader.cancel() } catch { /* */ }\n break\n }\n body += dec.decode(value, { stream: true })\n }\n }\n body += dec.decode()\n return { body, truncated }\n}\n\nfunction headersToObject(h: Headers): Record<string, string> {\n const out: Record<string, string> = {}\n h.forEach((v, k) => { out[k] = v })\n return out\n}\n\nexport const httpFetch: BuiltinAction<FetchInput, FetchOutput> = {\n name: \"http.fetch\",\n description: \"GET a URL, return body + status + headers (1MB cap, http/https only)\",\n inputSchema: fetchInput,\n outputSchema: fetchOutput,\n timeoutMs: 35_000,\n handler: async (input) => {\n assertAllowed(input.url)\n const ctrl = new AbortController()\n const t = setTimeout(() => ctrl.abort(), input.timeoutMs)\n try {\n const res = await fetch(input.url, { method: \"GET\", headers: input.headers ?? {}, signal: ctrl.signal })\n const { body, truncated } = await readCappedText(res)\n return {\n status: res.status,\n statusText: res.statusText,\n headers: headersToObject(res.headers),\n body,\n truncated,\n url: res.url,\n }\n } finally {\n clearTimeout(t)\n }\n },\n}\n\nconst postInput = z.object({\n url: z.string().min(1),\n /** JSON body, serialized to string at request time. Caller passes\n * any JSON-serializable value here — strings, objects, arrays. */\n body: z.unknown(),\n headers: HEADER_RECORD.optional(),\n timeoutMs: z.number().int().min(1).max(60_000).default(30_000),\n})\ntype PostInput = z.infer<typeof postInput>\n\nexport const httpPost: BuiltinAction<PostInput, FetchOutput> = {\n name: \"http.post\",\n description: \"POST a JSON body to a URL, return body + status + headers (1MB cap, http/https only)\",\n inputSchema: postInput,\n outputSchema: fetchOutput,\n timeoutMs: 35_000,\n handler: async (input) => {\n assertAllowed(input.url)\n const ctrl = new AbortController()\n const t = setTimeout(() => ctrl.abort(), input.timeoutMs)\n try {\n const headers = { \"Content-Type\": \"application/json\", ...(input.headers ?? {}) }\n const res = await fetch(input.url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(input.body ?? {}),\n signal: ctrl.signal,\n })\n const { body, truncated } = await readCappedText(res)\n return {\n status: res.status,\n statusText: res.statusText,\n headers: headersToObject(res.headers),\n body,\n truncated,\n url: res.url,\n }\n } finally {\n clearTimeout(t)\n }\n },\n}\n","import { z } from \"zod\"\nimport { getMesh } from \"@/a2a/mesh-instance\"\nimport type { BuiltinAction } from \"./types\"\n\n// --- mesh.delegate ---\n//\n// Send a task to a remote agentx peer (mesh node) and return the\n// peer's response text. Same wire as the legacy POST /mesh/task HTTP\n// route, but typed and callable directly from agents and workflows\n// without a Bash shell-out — exactly the \"mesh.delegate (peer call,\n// no shell required)\" line item from improvement plan #6.\n//\n// Why this matters even though POST /mesh/task already exists:\n// - Workflows can pipe the response into a typed downstream node.\n// - Agent-side, the call is one /api/actions/builtin POST instead\n// of \"shell out, parse JSON, hope you wrote the curl right\".\n// - The action interface advertises peer-name + agent-name shape\n// so authoring tools can validate before dispatch.\n\nconst meshDelegateInput = z.object({\n /** Mesh peer name as configured in mesh.peers[].name. */\n peer: z.string().min(1),\n /** Optional remote agent id; falls back to first agent on the peer. */\n agent: z.string().optional(),\n message: z.string().min(1),\n /** Per-call timeout. Default 90s; capped by the registry's 60s\n * ceiling unless the action declares a larger timeoutMs. */\n timeoutMs: z.number().int().min(1).max(600_000).default(90_000),\n /** Identity of the agent making the delegated call. Forwarded to\n * the receiving daemon for route-trace + (eventually) capability\n * validation. Optional during the log-warn rollout. */\n senderAgentId: z.string().optional(),\n})\ntype MeshDelegateInput = z.infer<typeof meshDelegateInput>\n\nconst meshDelegateOutput = z.object({\n peer: z.string(),\n agent: z.string().nullable(),\n response: z.string(),\n})\ntype MeshDelegateOutput = z.infer<typeof meshDelegateOutput>\n\nexport const meshDelegate: BuiltinAction<MeshDelegateInput, MeshDelegateOutput> = {\n name: \"mesh.delegate\",\n description: \"Send a task to a remote mesh peer's agent and return the response text\",\n inputSchema: meshDelegateInput,\n outputSchema: meshDelegateOutput,\n // Allow the action's max well above the registry default so a\n // long peer task isn't capped at 60s.\n timeoutMs: 600_000,\n handler: async (input) => {\n const mesh = getMesh()\n if (!mesh) {\n throw new Error(\"mesh not enabled on this daemon (config.mesh.enabled = false)\")\n }\n const response = await mesh.sendTask(input.peer, input.message, input.agent, {\n timeoutMs: input.timeoutMs,\n senderAgentId: input.senderAgentId,\n })\n return {\n peer: input.peer,\n agent: input.agent ?? null,\n response,\n }\n },\n}\n","import type { A2AMesh } from \"./mesh\"\n\n// --- Singleton accessor for the live A2AMesh ---\n//\n// Mirrors src/agents/process-registry-instance.ts. The daemon\n// instantiates A2AMesh in its boot sequence and registers it here so\n// process-global consumers (built-in actions, mesh.delegate) can reach\n// it without changing every call site's signature. Setter is null-able\n// because mesh-disabled deployments still need a valid module.\n\nlet _mesh: A2AMesh | null = null\n\nexport function getMesh(): A2AMesh | null {\n return _mesh\n}\n\nexport function setMesh(m: A2AMesh | null): void {\n _mesh = m\n}\n\n/** Test-only — clears the reference between cases. */\nexport function _resetMeshForTesting(): void {\n _mesh = null\n}\n","import { z } from \"zod\"\nimport { lexicalSearch } from \"@/rag/lexical-index\"\nimport type { BuiltinAction } from \"./types\"\n\n// --- rag.lexical ---\n//\n// Improvement plan #7 — embedding-free retrieval-augmented context.\n// Looks up an agent's lexical (BM25) index built via `agentx rag add`\n// and returns the top hits with score + path + body excerpt. No\n// embedding API call, no key, deterministic.\n\nconst ragLexicalInput = z.object({\n /** Agent whose index to query. Each agent has its own index at\n * .agentx/rag/<agentId>/. */\n agentId: z.string().min(1),\n query: z.string().min(1),\n /** Top-k results. Default 5, hard cap 50. */\n k: z.number().int().min(1).max(50).default(5),\n})\ntype RagLexicalInput = z.infer<typeof ragLexicalInput>\n\nconst ragLexicalOutput = z.object({\n hits: z.array(z.object({\n id: z.string(),\n title: z.string(),\n path: z.string(),\n score: z.number(),\n snippet: z.string(),\n })),\n})\ntype RagLexicalOutput = z.infer<typeof ragLexicalOutput>\n\nexport const ragLexical: BuiltinAction<RagLexicalInput, RagLexicalOutput> = {\n name: \"rag.lexical\",\n description: \"BM25-style lexical search over an agent's pre-built index (no embeddings, deterministic)\",\n inputSchema: ragLexicalInput,\n outputSchema: ragLexicalOutput,\n timeoutMs: 5_000,\n handler: async (input) => {\n const hits = lexicalSearch(input.agentId, input.query, { k: input.k })\n return { hits }\n },\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync, statSync } from \"fs\"\nimport { resolve, basename, relative } from \"path\"\nimport fg from \"fast-glob\"\n// minisearch ships both CJS and ESM; tsup transpiles either way.\nimport MiniSearch from \"minisearch\"\n\n// --- Lexical RAG index per agent ---\n//\n// Improvement plan #7 — embedding-free retrieval-augmented context for\n// agents. BM25-style scoring via the minisearch library (~30KB pure\n// JS, no native deps). Each agent gets its own index at\n// `.agentx/rag/<agentId>/index.json`; `agentx rag add` builds it from\n// a glob, the rag.lexical built-in action queries it.\n//\n// Fields indexed: title (extracted from first H1 or filename) + body\n// (full file text). Title is boosted 2× at search time so a\n// well-titled doc beats a body-only mention. Path is stored as a\n// non-indexed field so query results can cite the source file.\n//\n// Why not use embeddings: zero new keys, deterministic results, fast\n// (sub-ms search even with hundreds of docs), works offline. The\n// trade is no semantic synonymy — but for the kinds of operator\n// docs / wiki entries / playbook lookups agents typically need,\n// keyword recall is enough. Embedding-backed mode is opt-in\n// future work.\n\nexport interface IndexedDoc {\n /** Stable id within an index — usually the workspace-relative path. */\n id: string\n title: string\n body: string\n /** Absolute path on disk. Stored, not indexed. */\n path: string\n /** ISO timestamp when this doc was indexed. */\n indexedAt: string\n}\n\nexport interface RagSearchHit {\n id: string\n title: string\n path: string\n score: number\n /** A short body excerpt around the highest-scoring term. Useful for\n * citation-style \"here's what we found\" responses. */\n snippet: string\n}\n\nconst FIELDS_INDEXED = [\"title\", \"body\"]\nconst FIELDS_STORED = [\"title\", \"body\", \"path\", \"indexedAt\"]\n\nfunction indexFilePath(agentId: string, baseDir: string = \".agentx/rag\"): string {\n return resolve(process.cwd(), baseDir, agentId, \"index.json\")\n}\n\nfunction newSearchEngine(): MiniSearch<IndexedDoc> {\n return new MiniSearch<IndexedDoc>({\n fields: FIELDS_INDEXED,\n storeFields: FIELDS_STORED,\n searchOptions: { boost: { title: 2 }, fuzzy: 0.2, prefix: true },\n })\n}\n\n/**\n * Read a markdown / text file and split into indexable fields. Title\n * comes from the first H1 line (`# ...`); falls back to the filename\n * stem when there isn't one. Body is the full text.\n */\nfunction fileToDoc(absPath: string, idBase: string): IndexedDoc {\n const text = readFileSync(absPath, \"utf8\")\n const h1Match = text.match(/^\\s*#\\s+(.+)$/m)\n const title = h1Match ? h1Match[1].trim() : basename(absPath).replace(/\\.[^.]+$/, \"\")\n return {\n id: idBase,\n title,\n body: text,\n path: absPath,\n indexedAt: new Date().toISOString(),\n }\n}\n\n/**\n * Build an index from one or more globs. Globs resolve from cwd. The\n * resulting index is persisted under .agentx/rag/<agentId>/index.json\n * and returned to the caller for synchronous use.\n */\nexport async function buildIndex(\n agentId: string,\n globs: string[],\n opts: { baseDir?: string; cwd?: string; verbose?: boolean } = {},\n): Promise<{ docs: number; path: string }> {\n const cwd = opts.cwd ?? process.cwd()\n const files = (await fg(globs, { cwd, absolute: true, dot: false }))\n .filter((p) => {\n try { return statSync(p).isFile() } catch { return false }\n })\n\n const ms = newSearchEngine()\n for (const abs of files) {\n const idBase = relative(cwd, abs)\n const doc = fileToDoc(abs, idBase)\n ms.add(doc)\n if (opts.verbose) process.stderr.write(`[rag] indexed ${idBase} (${doc.body.length} bytes)\\n`)\n }\n\n const out = indexFilePath(agentId, opts.baseDir)\n mkdirSync(resolve(out, \"..\"), { recursive: true })\n writeFileSync(out, JSON.stringify(ms.toJSON()), \"utf8\")\n return { docs: files.length, path: out }\n}\n\n/**\n * Load a previously-built index. Returns null when no index exists for\n * this agent (caller can fall back to \"no RAG\" gracefully). Loading is\n * a small JSON parse + minisearch deserialize — sub-millisecond on\n * typical operator-doc indices.\n */\nexport function loadIndex(\n agentId: string,\n opts: { baseDir?: string } = {},\n): MiniSearch<IndexedDoc> | null {\n const path = indexFilePath(agentId, opts.baseDir)\n if (!existsSync(path)) return null\n try {\n const raw = readFileSync(path, \"utf8\")\n return MiniSearch.loadJSON<IndexedDoc>(raw, {\n fields: FIELDS_INDEXED,\n storeFields: FIELDS_STORED,\n searchOptions: { boost: { title: 2 }, fuzzy: 0.2, prefix: true },\n })\n } catch (e: any) {\n process.stderr.write(`[rag] failed to load ${path}: ${e?.message || String(e)}\\n`)\n return null\n }\n}\n\nconst SNIPPET_RADIUS = 80\nconst SNIPPET_MAX = SNIPPET_RADIUS * 2 + 60\n\n/** Extract a snippet around the FIRST occurrence of any of `terms` in\n * `body`. Returns the head of the body when no term hits. */\nfunction makeSnippet(body: string, terms: string[]): string {\n const lc = body.toLowerCase()\n let bestPos = -1\n for (const t of terms) {\n const i = lc.indexOf(t.toLowerCase())\n if (i >= 0 && (bestPos === -1 || i < bestPos)) bestPos = i\n }\n if (bestPos === -1) {\n return body.slice(0, SNIPPET_MAX).replace(/\\s+/g, \" \").trim()\n }\n const start = Math.max(0, bestPos - SNIPPET_RADIUS)\n const end = Math.min(body.length, bestPos + SNIPPET_RADIUS)\n const slice = body.slice(start, end).replace(/\\s+/g, \" \").trim()\n return (start > 0 ? \"…\" : \"\") + slice + (end < body.length ? \"…\" : \"\")\n}\n\nexport interface SearchOpts {\n /** How many top hits to return. Default 5, capped at 50. */\n k?: number\n baseDir?: string\n}\n\n/**\n * Lexical query against an agent's index. Returns at most `k` results,\n * each with a score, the title, the source path, and a snippet around\n * the matched term. Empty array when no index exists or no hits.\n */\nexport function lexicalSearch(\n agentId: string,\n query: string,\n opts: SearchOpts = {},\n): RagSearchHit[] {\n const ms = loadIndex(agentId, { baseDir: opts.baseDir })\n if (!ms) return []\n const k = Math.max(1, Math.min(50, opts.k ?? 5))\n const raw = ms.search(query) as unknown as Array<{\n id: string\n score: number\n title: string\n body: string\n path: string\n terms: string[]\n }>\n return raw.slice(0, k).map((r) => ({\n id: r.id,\n title: r.title,\n path: r.path,\n score: r.score,\n snippet: makeSnippet(r.body || \"\", r.terms || []),\n }))\n}\n\n/** List metadata about an agent's index without loading the full thing. */\nexport function indexInfo(agentId: string, opts: { baseDir?: string } = {}): {\n exists: boolean\n path: string\n docs: number\n} {\n const path = indexFilePath(agentId, opts.baseDir)\n if (!existsSync(path)) return { exists: false, path, docs: 0 }\n try {\n const raw = JSON.parse(readFileSync(path, \"utf8\"))\n // minisearch v7 puts the stored fields under `storedFields` (no\n // leading underscore), keyed by internal numeric doc id. Earlier\n // versions used `_storedFields`. Honour both for robustness across\n // minor minisearch upgrades.\n const sf = raw?.storedFields ?? raw?._storedFields\n if (typeof raw?.documentCount === \"number\") return { exists: true, path, docs: raw.documentCount }\n const docs = sf && typeof sf === \"object\" ? Object.keys(sf).length : 0\n return { exists: true, path, docs }\n } catch {\n return { exists: true, path, docs: 0 }\n }\n}\n","// --- Built-in actions barrel ---\n//\n// Importing this module registers every shipped built-in into the\n// process-global registry. The daemon imports it once at startup so\n// callers (HTTP routes, CLI, workflows) can look actions up by name.\n//\n// To add a new built-in: define it in a sibling file, import here,\n// pass it to registerBuiltin(). Keep the imports alphabetical for\n// human review.\n\nimport { registerBuiltin, _resetBuiltinsForTesting as _registryReset } from \"./registry\"\nimport { extractStructured } from \"./extract\"\nimport { fileReadLines, fileWriteJsonl } from \"./file\"\nimport { httpFetch, httpPost } from \"./http\"\nimport { meshDelegate } from \"./mesh\"\nimport { ragLexical } from \"./rag\"\n\n/**\n * Register every shipped built-in. Idempotent — re-registering the\n * same name overwrites with the latest handler (registerBuiltin's\n * own contract), so calling this multiple times is safe and matches\n * the in-memory registry's current state.\n */\nexport function registerAllBuiltins(): void {\n registerBuiltin(extractStructured)\n registerBuiltin(fileReadLines)\n registerBuiltin(fileWriteJsonl)\n registerBuiltin(httpFetch)\n registerBuiltin(httpPost)\n registerBuiltin(meshDelegate)\n registerBuiltin(ragLexical)\n}\n\n/** Test-only — clears the registry. Re-call registerAllBuiltins to repopulate. */\nexport function _resetBuiltinsForTesting(): void {\n _registryReset()\n}\n\nexport { getBuiltin, listBuiltins, runBuiltin } from \"./registry\"\nexport type { BuiltinAction, BuiltinActionMetadata } from \"./types\"\n"],"mappings":"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","names":["_registry","NAME_PATTERN","registerBuiltin","action","getBuiltin","name","listBuiltins","out","a","b","_resetBuiltinsForTesting","DEFAULT_TIMEOUT_MS","runBuiltin","rawInput","input","timeoutMs","handlerPromise","timeoutPromise","_","reject","output","parsed","z","extractInput","extractOutput","ANTHROPIC_API","ANTHROPIC_VERSION","extractStructured","input","apiKey","requestBody","ctrl","t","res","errBody","body","blocks","toolUse","b","usage","z","existsSync","readFileSync","appendFileSync","mkdirSync","statSync","resolve","dirname","isAbsolute","MAX_FILE_BYTES","resolveAllowed","input","abs","roots","r","root","readLinesInput","readLinesOutput","fileReadLines","stat","all","totalLines","lines","truncated","writeJsonlInput","writeJsonlOutput","fileWriteJsonl","e","payload","z","MAX_BODY_BYTES","HEADER_RECORD","allowedSchemes","assertAllowed","url","u","fetchInput","fetchOutput","readCappedText","res","reader","dec","total","body","truncated","done","value","headersToObject","h","out","v","k","httpFetch","input","ctrl","t","postInput","httpPost","headers","z","_mesh","getMesh","setMesh","m","meshDelegateInput","z","meshDelegateOutput","meshDelegate","input","mesh","getMesh","response","z","existsSync","mkdirSync","readFileSync","writeFileSync","statSync","resolve","basename","relative","fg","MiniSearch","FIELDS_INDEXED","FIELDS_STORED","indexFilePath","agentId","baseDir","newSearchEngine","fileToDoc","absPath","idBase","text","h1Match","title","buildIndex","globs","opts","cwd","files","p","ms","abs","doc","out","loadIndex","path","raw","e","SNIPPET_RADIUS","SNIPPET_MAX","makeSnippet","body","terms","lc","bestPos","t","i","start","end","slice","lexicalSearch","query","k","r","indexInfo","sf","docs","ragLexicalInput","z","ragLexicalOutput","ragLexical","input","lexicalSearch","registerAllBuiltins","registerBuiltin","extractStructured","fileReadLines","fileWriteJsonl","httpFetch","httpPost","meshDelegate","ragLexical","_resetBuiltinsForTesting"]}
|
package/dist/cli.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as s}from"./chunk-
|
|
2
|
+
import{a as s}from"./chunk-3SHMHYPD.js";import"./chunk-KWUWZQGV.js";import"./chunk-CNNLREHD.js";import"./chunk-4INOOHND.js";import"./chunk-GV7S5BAX.js";import"./chunk-GSX4NK2N.js";import"./chunk-SZDACK6O.js";import"./chunk-EQPUB7CZ.js";import"./chunk-BOUKM2PS.js";import"./chunk-N67JZAXU.js";import"./chunk-AFRHKA7B.js";import"./chunk-EW27SCCC.js";import"./chunk-Q6CAFGXT.js";import"./chunk-SFQUP3BP.js";import"./chunk-ZZFXI3CS.js";import"./chunk-PD5Q7D6Z.js";import"./chunk-DXTIG5YV.js";import"./chunk-EK37JHJI.js";import"./chunk-BHSPAP4U.js";import"./chunk-CDNWCYF7.js";import"./chunk-72PAN7UI.js";import"./chunk-5F3J55LG.js";import"./chunk-GOLZ6NEL.js";import"./chunk-WJXU5F4Z.js";import"./chunk-VWTBHLMX.js";import"./chunk-7P5QRX5W.js";import"./chunk-JTJIPNXY.js";import"./chunk-64P4QHSZ.js";import"./chunk-BFZUG66X.js";import"./chunk-SR3X25TN.js";import"./chunk-53NRX2NA.js";import"./chunk-A6BKSZQA.js";import"./chunk-JGXE2YNV.js";import"./chunk-VJUTQAPJ.js";import"./chunk-DJEZ2HVU.js";import"./chunk-DSYKYZMT.js";import"./chunk-IKBHHTIT.js";import"./chunk-QOYAX2FT.js";import"./chunk-4YCH6IZV.js";process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));async function o(){let r=await s();if(process.argv.slice(2).length===0){r.outputHelp();return}r.parse()}o();
|
|
3
3
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { buildProgram } from \"@/program\"\n\nprocess.on(\"SIGINT\", () => process.exit(0))\nprocess.on(\"SIGTERM\", () => process.exit(0))\n\nasync function main() {\n const program = await buildProgram()\n\n const args = process.argv.slice(2)\n if (args.length === 0) {\n program.outputHelp()\n return\n }\n\n program.parse()\n}\n\nmain()\n"],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { buildProgram } from \"@/program\"\n\nprocess.on(\"SIGINT\", () => process.exit(0))\nprocess.on(\"SIGTERM\", () => process.exit(0))\n\nasync function main() {\n const program = await buildProgram()\n\n const args = process.argv.slice(2)\n if (args.length === 0) {\n program.outputHelp()\n return\n }\n\n program.parse()\n}\n\nmain()\n"],"mappings":";glCAGA,QAAQ,GAAG,SAAU,IAAM,QAAQ,KAAK,CAAC,CAAC,EAC1C,QAAQ,GAAG,UAAW,IAAM,QAAQ,KAAK,CAAC,CAAC,EAE3C,eAAeA,GAAO,CACpB,IAAMC,EAAU,MAAMC,EAAa,EAGnC,GADa,QAAQ,KAAK,MAAM,CAAC,EACxB,SAAW,EAAG,CACrBD,EAAQ,WAAW,EACnB,OAGFA,EAAQ,MAAM,CAChB,CAEAD,EAAK","names":["main","program","buildProgram"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{c as a,d as b,e as c,f as d}from"./chunk-
|
|
2
|
-
//# sourceMappingURL=config-
|
|
1
|
+
import{c as a,d as b,e as c,f as d}from"./chunk-EK37JHJI.js";import"./chunk-4YCH6IZV.js";export{a as daemonConfigSchema,b as expandEnvVars,c as loadDaemonConfig,d as validateWorkspaces};
|
|
2
|
+
//# sourceMappingURL=config-ADS54KLC.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1366,6 +1366,21 @@ declare const agentConfigSchema: z.ZodObject<{
|
|
|
1366
1366
|
* agents that do long investigations or multi-file refactors. */
|
|
1367
1367
|
maxExecutionMinutes: z.ZodDefault<z.ZodNumber>;
|
|
1368
1368
|
permissionMode: z.ZodDefault<z.ZodString>;
|
|
1369
|
+
/** Improvement plan #3 — tool-use-required preset. When set,
|
|
1370
|
+
* AgentX inspects the stream-json events from each task and
|
|
1371
|
+
* fails the response with `tool_required_not_called: <name>`
|
|
1372
|
+
* when none of the listed tool names was invoked. Catches the
|
|
1373
|
+
* silent-degrade pattern observed when a model below the
|
|
1374
|
+
* capability bar (e.g. Haiku on a Write-required prompt)
|
|
1375
|
+
* produces a plausible-looking text response without ever
|
|
1376
|
+
* calling the required tool. Caller can retry with a stronger
|
|
1377
|
+
* model or sharpen the prompt.
|
|
1378
|
+
*
|
|
1379
|
+
* Tool names match the canonical Claude Code names ("Write",
|
|
1380
|
+
* "Edit", "Bash", "Read", …). Free-form so future tools work
|
|
1381
|
+
* without a schema bump. Empty/unset means no enforcement
|
|
1382
|
+
* (default — backward compatible). */
|
|
1383
|
+
toolUseRequired: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
1369
1384
|
/** When true, this agent's claude-code dispatches reuse a long-lived
|
|
1370
1385
|
* subprocess per (channel, chatId) instead of spawning a fresh
|
|
1371
1386
|
* `claude -p` per turn. Driven over stdin via stream-json input,
|
|
@@ -1412,6 +1427,7 @@ declare const agentConfigSchema: z.ZodObject<{
|
|
|
1412
1427
|
maxConcurrent: number;
|
|
1413
1428
|
maxExecutionMinutes: number;
|
|
1414
1429
|
permissionMode: string;
|
|
1430
|
+
toolUseRequired: string[];
|
|
1415
1431
|
persistentProcess: boolean;
|
|
1416
1432
|
queueMode: "collect" | "followup" | "drop";
|
|
1417
1433
|
heartbeat: {
|
|
@@ -1450,6 +1466,7 @@ declare const agentConfigSchema: z.ZodObject<{
|
|
|
1450
1466
|
maxConcurrent?: number | undefined;
|
|
1451
1467
|
maxExecutionMinutes?: number | undefined;
|
|
1452
1468
|
permissionMode?: string | undefined;
|
|
1469
|
+
toolUseRequired?: string[] | undefined;
|
|
1453
1470
|
persistentProcess?: boolean | undefined;
|
|
1454
1471
|
queueMode?: "collect" | "followup" | "drop" | undefined;
|
|
1455
1472
|
heartbeat?: {
|
|
@@ -1621,6 +1638,21 @@ declare const daemonConfigSchema: z.ZodObject<{
|
|
|
1621
1638
|
* agents that do long investigations or multi-file refactors. */
|
|
1622
1639
|
maxExecutionMinutes: z.ZodDefault<z.ZodNumber>;
|
|
1623
1640
|
permissionMode: z.ZodDefault<z.ZodString>;
|
|
1641
|
+
/** Improvement plan #3 — tool-use-required preset. When set,
|
|
1642
|
+
* AgentX inspects the stream-json events from each task and
|
|
1643
|
+
* fails the response with `tool_required_not_called: <name>`
|
|
1644
|
+
* when none of the listed tool names was invoked. Catches the
|
|
1645
|
+
* silent-degrade pattern observed when a model below the
|
|
1646
|
+
* capability bar (e.g. Haiku on a Write-required prompt)
|
|
1647
|
+
* produces a plausible-looking text response without ever
|
|
1648
|
+
* calling the required tool. Caller can retry with a stronger
|
|
1649
|
+
* model or sharpen the prompt.
|
|
1650
|
+
*
|
|
1651
|
+
* Tool names match the canonical Claude Code names ("Write",
|
|
1652
|
+
* "Edit", "Bash", "Read", …). Free-form so future tools work
|
|
1653
|
+
* without a schema bump. Empty/unset means no enforcement
|
|
1654
|
+
* (default — backward compatible). */
|
|
1655
|
+
toolUseRequired: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
1624
1656
|
/** When true, this agent's claude-code dispatches reuse a long-lived
|
|
1625
1657
|
* subprocess per (channel, chatId) instead of spawning a fresh
|
|
1626
1658
|
* `claude -p` per turn. Driven over stdin via stream-json input,
|
|
@@ -1667,6 +1699,7 @@ declare const daemonConfigSchema: z.ZodObject<{
|
|
|
1667
1699
|
maxConcurrent: number;
|
|
1668
1700
|
maxExecutionMinutes: number;
|
|
1669
1701
|
permissionMode: string;
|
|
1702
|
+
toolUseRequired: string[];
|
|
1670
1703
|
persistentProcess: boolean;
|
|
1671
1704
|
queueMode: "collect" | "followup" | "drop";
|
|
1672
1705
|
heartbeat: {
|
|
@@ -1705,6 +1738,7 @@ declare const daemonConfigSchema: z.ZodObject<{
|
|
|
1705
1738
|
maxConcurrent?: number | undefined;
|
|
1706
1739
|
maxExecutionMinutes?: number | undefined;
|
|
1707
1740
|
permissionMode?: string | undefined;
|
|
1741
|
+
toolUseRequired?: string[] | undefined;
|
|
1708
1742
|
persistentProcess?: boolean | undefined;
|
|
1709
1743
|
queueMode?: "collect" | "followup" | "drop" | undefined;
|
|
1710
1744
|
heartbeat?: {
|
|
@@ -3457,6 +3491,7 @@ declare const daemonConfigSchema: z.ZodObject<{
|
|
|
3457
3491
|
maxConcurrent: number;
|
|
3458
3492
|
maxExecutionMinutes: number;
|
|
3459
3493
|
permissionMode: string;
|
|
3494
|
+
toolUseRequired: string[];
|
|
3460
3495
|
persistentProcess: boolean;
|
|
3461
3496
|
queueMode: "collect" | "followup" | "drop";
|
|
3462
3497
|
heartbeat: {
|
|
@@ -3843,6 +3878,7 @@ declare const daemonConfigSchema: z.ZodObject<{
|
|
|
3843
3878
|
maxConcurrent?: number | undefined;
|
|
3844
3879
|
maxExecutionMinutes?: number | undefined;
|
|
3845
3880
|
permissionMode?: string | undefined;
|
|
3881
|
+
toolUseRequired?: string[] | undefined;
|
|
3846
3882
|
persistentProcess?: boolean | undefined;
|
|
3847
3883
|
queueMode?: "collect" | "followup" | "drop" | undefined;
|
|
3848
3884
|
heartbeat?: {
|
|
@@ -4813,6 +4849,21 @@ interface AgentTask {
|
|
|
4813
4849
|
* parser can append rows under the same id. Optional — when unset,
|
|
4814
4850
|
* step capture is a no-op. */
|
|
4815
4851
|
taskId?: string;
|
|
4852
|
+
/** Improvement plan #8 — when true, the dispatcher discards any
|
|
4853
|
+
* cached session for this (agent, channel, chatId) before
|
|
4854
|
+
* executing: the claudeSessionId is cleared (no --resume) and
|
|
4855
|
+
* any persistent-process handle is killed so the next dispatch
|
|
4856
|
+
* spawns fresh. Use from triage→sub-agent delegation paths where
|
|
4857
|
+
* the caller knows this is a NEW visitor on a chatId that may
|
|
4858
|
+
* collide with prior conversations.
|
|
4859
|
+
*
|
|
4860
|
+
* Caught in benchmark Run 3 (2026-05-04): a triage agent
|
|
4861
|
+
* delegated to "lead" for a brand-new visitor; lead's warm
|
|
4862
|
+
* persistent process replied with the previous visitor's
|
|
4863
|
+
* confirmation message. freshSession: true defends against
|
|
4864
|
+
* that pattern without requiring callers to invent unique
|
|
4865
|
+
* chatIds. */
|
|
4866
|
+
freshSession?: boolean;
|
|
4816
4867
|
context?: {
|
|
4817
4868
|
channel?: string;
|
|
4818
4869
|
sender?: string;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as U}from"./chunk-4ITQP3XL.js";import{a as yt,b as re,c as ae,d as vt,e as xt,f as Ct,
|
|
1
|
+
import{a as U}from"./chunk-4ITQP3XL.js";import{a as yt,b as re,c as ae,d as vt,e as xt,f as Ct,j as bt,k as $t,l as Tt}from"./chunk-EQPUB7CZ.js";import"./chunk-BOUKM2PS.js";import"./chunk-N67JZAXU.js";import"./chunk-AFRHKA7B.js";import"./chunk-EW27SCCC.js";import{A as H,B as E,C as I,a as be,b as $e,c as Te,d as je,e as _e,f as Ue,g as Be,h as We,i as qe,j as Ve,k as Ye,l as F,m as Q,n as Ze,o as et,p as tt,q as j,r as st,s as ot,t as nt,u as P,v as Z,w as it,x as rt,y as at,z as ht}from"./chunk-Q6CAFGXT.js";import{a as X,b as M,c as _}from"./chunk-SFQUP3BP.js";import"./chunk-ZZFXI3CS.js";import{f as Pt}from"./chunk-PD5Q7D6Z.js";import"./chunk-DXTIG5YV.js";import{c as kt,e as wt,f as St}from"./chunk-EK37JHJI.js";import"./chunk-BHSPAP4U.js";import"./chunk-CDNWCYF7.js";import{d as lt,e as ct,f as dt,g as pt,q as ut}from"./chunk-72PAN7UI.js";import"./chunk-5F3J55LG.js";import"./chunk-GOLZ6NEL.js";import"./chunk-WJXU5F4Z.js";import"./chunk-VWTBHLMX.js";import{a as gt,b as mt,e as ft}from"./chunk-7P5QRX5W.js";import"./chunk-JTJIPNXY.js";import"./chunk-64P4QHSZ.js";import"./chunk-BFZUG66X.js";import"./chunk-SR3X25TN.js";import"./chunk-53NRX2NA.js";import"./chunk-A6BKSZQA.js";import{a as Re,b as Ae,c as Me,d as Ee,e as Ie,f as Oe,g as Ge,h as De,i as Le,j as Ne,k as Fe,l as A}from"./chunk-JGXE2YNV.js";import{a as m}from"./chunk-VJUTQAPJ.js";import{a as He,b as Je,c as N,d as Ke}from"./chunk-DJEZ2HVU.js";import{a as ze,b as Xe,e as Qe}from"./chunk-DSYKYZMT.js";import"./chunk-IKBHHTIT.js";import"./chunk-QOYAX2FT.js";import"./chunk-4YCH6IZV.js";import{execa as Rt}from"execa";import{existsSync as le,promises as ee}from"fs";import x from"path";import pe from"node-fetch";async function At(n,e){let t=n.split("/");if(t.length<2)throw new Error(`Invalid skill package ID: ${n}. Expected format: owner/repo`);let s=t[0],i=t[1],o=t[2];try{let a=o?`${s}/${i}/${o}`:`${s}/${i}`;await Rt("npx",["-y","skills","add",a],{cwd:e,stdio:"pipe"}),m.success(`Installed skill package: ${n}`);let r=x.resolve(e,".skills",`${s}_${i}`);if(le(r))return await de(r,n);let l=x.resolve(e,".skills");return le(l)?await de(l,n):[]}catch{return m.info(`Fetching skills directly from GitHub: ${s}/${i}`),await Mt(s,i,o,e)}}async function Mt(n,e,t,s){let i=[];try{let o=`https://api.github.com/repos/${n}/${e}/git/trees/main?recursive=1`,a=await pe(o);if(!a.ok)throw new Error(`GitHub API error: ${a.status}`);let l=(await a.json()).tree.filter(c=>c.type==="blob"&&c.path.endsWith("SKILL.md"));if(t){let c=l.find(g=>g.path.includes(`/${t}/`)||g.path===`${t}/SKILL.md`);if(c){let g=await ce(n,e,c.path,s);g&&i.push(g)}}else for(let c of l){let g=await ce(n,e,c.path,s);g&&i.push(g)}}catch(o){m.error(`Failed to fetch skills from GitHub: ${o.message}`)}return i}async function ce(n,e,t,s){try{let i=`https://raw.githubusercontent.com/${n}/${e}/main/${t}`,o=await pe(i);if(!o.ok)return null;let a=await o.text(),r=N(a);if(r){r.source="remote",r.packageId=`${n}/${e}`;let l=x.dirname(t),c=x.resolve(s,".skills",`${n}_${e}`,l);await ee.mkdir(c,{recursive:!0}),await ee.writeFile(x.resolve(c,"SKILL.md"),a),r.path=x.resolve(c,"SKILL.md")}return r}catch{return null}}async function de(n,e){let t=[],{default:s}=await import("fast-glob"),i=await s.glob("**/SKILL.md",{cwd:n,deep:5});for(let o of i)try{let a=x.resolve(n,o),r=await ee.readFile(a,"utf8"),l=N(r);l&&(l.source="remote",l.path=a,l.packageId=e,t.push(l))}catch{}return t}async function Et(n,e,t,s,i){let o=["---",`name: ${n}`,`description: ${e}`];if(s?.length){o.push("tags:");for(let a of s)o.push(` - ${a}`)}if(i?.length){o.push("globs:");for(let a of i)o.push(` - ${a}`)}return o.push("---"),`${o.join(`
|
|
2
2
|
`)}
|
|
3
3
|
|
|
4
4
|
${t}`}async function It(n){let{loadLocalSkills:e}=await import("./loader-5CA3O5GM.js");return e(n)}async function Ot(n,e,t,s,i){let a=[{role:"system",content:`You are a skill author for the Agent Skills ecosystem (skills.sh).
|