agentix-cli 0.142.0 → 0.144.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 (157) hide show
  1. package/dist/{App-VHAMAS4I.js → App-N2U77ED7.js} +2 -2
  2. package/dist/{ChatApp-Y7HOL45K.js → ChatApp-GYVTECF6.js} +2 -2
  3. package/dist/{absorb-eval-VHACXZ3H.js → absorb-eval-WSAVWCZV.js} +2 -2
  4. package/dist/{agent-M7ID5U3U.js → agent-SLRGXBMK.js} +2 -2
  5. package/dist/{board-dashboard-VHUZMYOV.js → board-dashboard-B3T7VCRQ.js} +320 -268
  6. package/dist/board-dashboard-B3T7VCRQ.js.map +1 -0
  7. package/dist/{chunk-S3LWGPNZ.js → chunk-2GJFLPS7.js} +3 -3
  8. package/dist/{chunk-TFNBUHRW.js → chunk-3LAQ74H7.js} +2 -2
  9. package/dist/{chunk-3NKCOZQO.js → chunk-45TKVOJX.js} +2 -2
  10. package/dist/{chunk-B5744ATM.js → chunk-4JHMV3D3.js} +2 -2
  11. package/dist/{chunk-QSKG754X.js → chunk-5TTHN7DP.js} +12 -8
  12. package/dist/chunk-5TTHN7DP.js.map +1 -0
  13. package/dist/{chunk-S6QUFAHD.js → chunk-BAO77R4L.js} +2 -2
  14. package/dist/{chunk-S6QUFAHD.js.map → chunk-BAO77R4L.js.map} +1 -1
  15. package/dist/{chunk-IFUN332M.js → chunk-CZWEXRIE.js} +2 -2
  16. package/dist/{chunk-2TLOZN7P.js → chunk-DFWPTNZ5.js} +2 -2
  17. package/dist/chunk-DG2DC43E.js +11 -0
  18. package/dist/chunk-DG2DC43E.js.map +1 -0
  19. package/dist/chunk-DPIQCHXB.js +62 -0
  20. package/dist/chunk-DPIQCHXB.js.map +1 -0
  21. package/dist/{chunk-5SEUBOUH.js → chunk-EX4AREN5.js} +2 -2
  22. package/dist/{chunk-QTS7MHIA.js → chunk-GOAMSJ2D.js} +2 -2
  23. package/dist/{chunk-6PJKKLKV.js → chunk-GWBBWYGM.js} +58 -55
  24. package/dist/chunk-GWBBWYGM.js.map +1 -0
  25. package/dist/{chunk-6YPJVGYF.js → chunk-JGX5IWNX.js} +2 -2
  26. package/dist/chunk-KV4ZA7FS.js +4 -0
  27. package/dist/chunk-KV4ZA7FS.js.map +1 -0
  28. package/dist/{chunk-YXFTUOZR.js → chunk-LLJZMS23.js} +2 -2
  29. package/dist/{chunk-ZWL44UJS.js → chunk-LVQHNTXV.js} +2 -2
  30. package/dist/{chunk-UNIXYV3U.js → chunk-M7527M7D.js} +2 -2
  31. package/dist/{chunk-NFI4BCCO.js → chunk-MXWAREAQ.js} +2 -2
  32. package/dist/{chunk-UF4OTZ7D.js → chunk-PJGLIAEP.js} +282 -274
  33. package/dist/chunk-PJGLIAEP.js.map +1 -0
  34. package/dist/{chunk-7H7LUBPC.js → chunk-Q73QQPDB.js} +2 -2
  35. package/dist/{chunk-25XO6P7W.js → chunk-QI4FYJGJ.js} +2 -2
  36. package/dist/{chunk-KEBTFUOZ.js → chunk-R5VGRKUW.js} +2 -2
  37. package/dist/{chunk-SLJFY2AQ.js → chunk-RGBQULXX.js} +2 -2
  38. package/dist/{chunk-GPCBOXZM.js → chunk-RV4WJZW5.js} +2 -2
  39. package/dist/{chunk-7Y3FEIX7.js → chunk-SFUNL7RV.js} +2 -2
  40. package/dist/{chunk-EMA67BJ5.js → chunk-SVNYI6GR.js} +2 -2
  41. package/dist/{chunk-WEHEI3JO.js → chunk-TTBCXVPJ.js} +6 -6
  42. package/dist/chunk-TTBCXVPJ.js.map +1 -0
  43. package/dist/{chunk-MLLMBE2W.js → chunk-UII54DAP.js} +2 -2
  44. package/dist/{chunk-JH6C2Y5D.js → chunk-UNZRZOED.js} +2 -2
  45. package/dist/{chunk-Y4CYQV7G.js → chunk-VY7TBMJU.js} +2 -2
  46. package/dist/chunk-VY7TBMJU.js.map +1 -0
  47. package/dist/{chunk-3E4AEZ2J.js → chunk-VYLMC5DO.js} +2 -2
  48. package/dist/{chunk-SHEUCITK.js → chunk-WBG6NA7R.js} +2 -2
  49. package/dist/{chunk-SHEUCITK.js.map → chunk-WBG6NA7R.js.map} +1 -1
  50. package/dist/cli.js +1 -1
  51. package/dist/{client-ISQF24N5.js → client-B7FXDTYK.js} +2 -2
  52. package/dist/config-MLP33NWR.js +2 -0
  53. package/dist/{config-mutate-YZ3IH6CJ.js → config-mutate-XQRUAVEH.js} +2 -2
  54. package/dist/config-mutator-5JFTMQ43.js +2 -0
  55. package/dist/{contributions-FQGIRD44.js → contributions-ESUSYUQG.js} +2 -2
  56. package/dist/{doctor-FMW2SSCN.js → doctor-DIYZGSIS.js} +2 -2
  57. package/dist/{failure-candidates-XZSZP4HT.js → failure-candidates-NQX2JMMS.js} +2 -2
  58. package/dist/{follow-up-tool-I7PPM2R5.js → follow-up-tool-QXEYEWX7.js} +2 -2
  59. package/dist/{grants-CEUGZBQ4.js → grants-MM7U6GCK.js} +2 -2
  60. package/dist/{hub-Z3X4LWMI.js → hub-OC7PH2AR.js} +2 -2
  61. package/dist/index.d.ts +382 -131
  62. package/dist/index.js +1 -1
  63. package/dist/{program-I7WCAMBP.js → program-LZPM6I2Q.js} +289 -252
  64. package/dist/program-LZPM6I2Q.js.map +1 -0
  65. package/dist/{promote-7YUBVKRC.js → promote-SIC6RWCX.js} +2 -2
  66. package/dist/{query-TMALX5BE.js → query-OP2MSR2G.js} +2 -2
  67. package/dist/{query-settings-3PEV5GIH.js → query-settings-67332F5V.js} +2 -2
  68. package/dist/{registry-6ZIBMOZQ.js → registry-G2ZG5TIN.js} +2 -2
  69. package/dist/{request-planner-GLNHHQXA.js → request-planner-THTPE3FP.js} +2 -2
  70. package/dist/{review-candidates-DJXNTOG6.js → review-candidates-7PS7CHXF.js} +2 -2
  71. package/dist/{routing-YWP2AF56.js → routing-PE7DB7WA.js} +2 -2
  72. package/dist/schedule-tool-3FXRKJGN.js +2 -0
  73. package/dist/{scheduler-HK362U53.js → scheduler-YTXCIQTZ.js} +2 -2
  74. package/dist/{seat-4PPUZXFN.js → seat-6DMK4274.js} +2 -2
  75. package/dist/{select-ULCUVM7N.js → select-CLDYPAOS.js} +2 -2
  76. package/dist/{set-enabled-G4PLW5WK.js → set-enabled-ZH2DH4GU.js} +2 -2
  77. package/dist/tool-4AO3ZMAY.js +6 -0
  78. package/dist/tool-4AO3ZMAY.js.map +1 -0
  79. package/dist/{tool-KGOC2NUZ.js → tool-MKDTKBJ4.js} +3 -3
  80. package/dist/{tool-KGOC2NUZ.js.map → tool-MKDTKBJ4.js.map} +1 -1
  81. package/dist/traces-GVEQZX24.js +2 -0
  82. package/dist/{wiki-32G6TGCI.js → wiki-CH2HYJVI.js} +2 -2
  83. package/dist/wiki-enrich-VEAYFVR2.js +2 -0
  84. package/dist/wiki-enrich-VEAYFVR2.js.map +1 -0
  85. package/dist/workflow-pilot-HCPSMGIC.js +2 -0
  86. package/dist/workflow-pilot-HCPSMGIC.js.map +1 -0
  87. package/package.json +1 -1
  88. package/dist/board-dashboard-VHUZMYOV.js.map +0 -1
  89. package/dist/chunk-3W2BHUGM.js +0 -11
  90. package/dist/chunk-3W2BHUGM.js.map +0 -1
  91. package/dist/chunk-6PJKKLKV.js.map +0 -1
  92. package/dist/chunk-AKWBDCMU.js +0 -4
  93. package/dist/chunk-AKWBDCMU.js.map +0 -1
  94. package/dist/chunk-JYPXNH4C.js +0 -54
  95. package/dist/chunk-JYPXNH4C.js.map +0 -1
  96. package/dist/chunk-QSKG754X.js.map +0 -1
  97. package/dist/chunk-UF4OTZ7D.js.map +0 -1
  98. package/dist/chunk-WEHEI3JO.js.map +0 -1
  99. package/dist/chunk-Y4CYQV7G.js.map +0 -1
  100. package/dist/config-Z64VWERV.js +0 -2
  101. package/dist/config-mutator-3HTNXOPU.js +0 -2
  102. package/dist/program-I7WCAMBP.js.map +0 -1
  103. package/dist/schedule-tool-4O4XWGVA.js +0 -2
  104. package/dist/tool-CBDT7TAG.js +0 -6
  105. package/dist/tool-CBDT7TAG.js.map +0 -1
  106. package/dist/wiki-enrich-XBRY4ZRD.js +0 -2
  107. /package/dist/{App-VHAMAS4I.js.map → App-N2U77ED7.js.map} +0 -0
  108. /package/dist/{ChatApp-Y7HOL45K.js.map → ChatApp-GYVTECF6.js.map} +0 -0
  109. /package/dist/{absorb-eval-VHACXZ3H.js.map → absorb-eval-WSAVWCZV.js.map} +0 -0
  110. /package/dist/{agent-M7ID5U3U.js.map → agent-SLRGXBMK.js.map} +0 -0
  111. /package/dist/{chunk-S3LWGPNZ.js.map → chunk-2GJFLPS7.js.map} +0 -0
  112. /package/dist/{chunk-TFNBUHRW.js.map → chunk-3LAQ74H7.js.map} +0 -0
  113. /package/dist/{chunk-3NKCOZQO.js.map → chunk-45TKVOJX.js.map} +0 -0
  114. /package/dist/{chunk-B5744ATM.js.map → chunk-4JHMV3D3.js.map} +0 -0
  115. /package/dist/{chunk-IFUN332M.js.map → chunk-CZWEXRIE.js.map} +0 -0
  116. /package/dist/{chunk-2TLOZN7P.js.map → chunk-DFWPTNZ5.js.map} +0 -0
  117. /package/dist/{chunk-5SEUBOUH.js.map → chunk-EX4AREN5.js.map} +0 -0
  118. /package/dist/{chunk-QTS7MHIA.js.map → chunk-GOAMSJ2D.js.map} +0 -0
  119. /package/dist/{chunk-6YPJVGYF.js.map → chunk-JGX5IWNX.js.map} +0 -0
  120. /package/dist/{chunk-YXFTUOZR.js.map → chunk-LLJZMS23.js.map} +0 -0
  121. /package/dist/{chunk-ZWL44UJS.js.map → chunk-LVQHNTXV.js.map} +0 -0
  122. /package/dist/{chunk-UNIXYV3U.js.map → chunk-M7527M7D.js.map} +0 -0
  123. /package/dist/{chunk-NFI4BCCO.js.map → chunk-MXWAREAQ.js.map} +0 -0
  124. /package/dist/{chunk-7H7LUBPC.js.map → chunk-Q73QQPDB.js.map} +0 -0
  125. /package/dist/{chunk-25XO6P7W.js.map → chunk-QI4FYJGJ.js.map} +0 -0
  126. /package/dist/{chunk-KEBTFUOZ.js.map → chunk-R5VGRKUW.js.map} +0 -0
  127. /package/dist/{chunk-SLJFY2AQ.js.map → chunk-RGBQULXX.js.map} +0 -0
  128. /package/dist/{chunk-GPCBOXZM.js.map → chunk-RV4WJZW5.js.map} +0 -0
  129. /package/dist/{chunk-7Y3FEIX7.js.map → chunk-SFUNL7RV.js.map} +0 -0
  130. /package/dist/{chunk-EMA67BJ5.js.map → chunk-SVNYI6GR.js.map} +0 -0
  131. /package/dist/{chunk-MLLMBE2W.js.map → chunk-UII54DAP.js.map} +0 -0
  132. /package/dist/{chunk-JH6C2Y5D.js.map → chunk-UNZRZOED.js.map} +0 -0
  133. /package/dist/{chunk-3E4AEZ2J.js.map → chunk-VYLMC5DO.js.map} +0 -0
  134. /package/dist/{client-ISQF24N5.js.map → client-B7FXDTYK.js.map} +0 -0
  135. /package/dist/{config-Z64VWERV.js.map → config-MLP33NWR.js.map} +0 -0
  136. /package/dist/{config-mutate-YZ3IH6CJ.js.map → config-mutate-XQRUAVEH.js.map} +0 -0
  137. /package/dist/{config-mutator-3HTNXOPU.js.map → config-mutator-5JFTMQ43.js.map} +0 -0
  138. /package/dist/{contributions-FQGIRD44.js.map → contributions-ESUSYUQG.js.map} +0 -0
  139. /package/dist/{doctor-FMW2SSCN.js.map → doctor-DIYZGSIS.js.map} +0 -0
  140. /package/dist/{failure-candidates-XZSZP4HT.js.map → failure-candidates-NQX2JMMS.js.map} +0 -0
  141. /package/dist/{follow-up-tool-I7PPM2R5.js.map → follow-up-tool-QXEYEWX7.js.map} +0 -0
  142. /package/dist/{grants-CEUGZBQ4.js.map → grants-MM7U6GCK.js.map} +0 -0
  143. /package/dist/{hub-Z3X4LWMI.js.map → hub-OC7PH2AR.js.map} +0 -0
  144. /package/dist/{promote-7YUBVKRC.js.map → promote-SIC6RWCX.js.map} +0 -0
  145. /package/dist/{query-TMALX5BE.js.map → query-OP2MSR2G.js.map} +0 -0
  146. /package/dist/{query-settings-3PEV5GIH.js.map → query-settings-67332F5V.js.map} +0 -0
  147. /package/dist/{registry-6ZIBMOZQ.js.map → registry-G2ZG5TIN.js.map} +0 -0
  148. /package/dist/{request-planner-GLNHHQXA.js.map → request-planner-THTPE3FP.js.map} +0 -0
  149. /package/dist/{review-candidates-DJXNTOG6.js.map → review-candidates-7PS7CHXF.js.map} +0 -0
  150. /package/dist/{routing-YWP2AF56.js.map → routing-PE7DB7WA.js.map} +0 -0
  151. /package/dist/{schedule-tool-4O4XWGVA.js.map → schedule-tool-3FXRKJGN.js.map} +0 -0
  152. /package/dist/{scheduler-HK362U53.js.map → scheduler-YTXCIQTZ.js.map} +0 -0
  153. /package/dist/{seat-4PPUZXFN.js.map → seat-6DMK4274.js.map} +0 -0
  154. /package/dist/{select-ULCUVM7N.js.map → select-CLDYPAOS.js.map} +0 -0
  155. /package/dist/{set-enabled-G4PLW5WK.js.map → set-enabled-ZH2DH4GU.js.map} +0 -0
  156. /package/dist/{wiki-32G6TGCI.js.map → traces-GVEQZX24.js.map} +0 -0
  157. /package/dist/{wiki-enrich-XBRY4ZRD.js.map → wiki-CH2HYJVI.js.map} +0 -0
@@ -1,4 +1,4 @@
1
- import{a as _,b as F,c as K,d as z,e as J}from"./chunk-SKSYII3K.js";import{a as j,b as I,c as Y,d as V,e as B,j as G}from"./chunk-MLLMBE2W.js";import{a as H}from"./chunk-MWNCS57L.js";import{y as N,z as ot}from"./chunk-KEBTFUOZ.js";import{g as Q}from"./chunk-6TURWSMN.js";import{b as E,c as L}from"./chunk-QOYAX2FT.js";import{readFileSync as lt,existsSync as X}from"fs";ot();import{resolve as R}from"path";import{execSync as ct}from"child_process";var ht="haiku",dt="sonnet",pt=.8;function mt(e,r,o,t){if(t.size===0)return 0;let c=e.listArticles(r||"").map(l=>l.path).filter(l=>!l.includes("/_versions/"));return c.length===0&&(c=o.sharedPool.map(l=>l.path)),c.length===0?0:c.filter(l=>t.has(l)).length/c.length}async function _t(e,r,o,t={}){let c=t.selectorModel??ht,l=t.synthModel??dt,m=t.maxCandidates??3,g=t.maxHops??2,d=t.maxArticles??8,i=t.timeoutMs??6e4,s=t.log??console.error.bind(console,"[wiki-query]"),h=t.messagePath?.length?t.messagePath:void 0,n=t.graphWeight??W,a=R(r.baseDir,"_index.md"),p=tt(r,o,t.shared),b=t.method??"catalog";if(b!=="catalog"){let u=z(r,t.shared);if(b==="summaries"||mt(r,o,p,u)>=pt){let f=t.summaries??K,P=t.notes&&o&&t.notes.owner===o?F(t.notes):void 0,y=await J(e,P?gt(p,P):p,P?new Map([...u,...P.summaries]):u,{...f,navigatorModel:t.selectorModel??f.navigatorModel,answerModel:t.synthModel??f.answerModel},{call:t.call??H,fetch:t.fetch,timeoutMs:i,log:s}),$=y.picked.map(w=>({title:w.meta.title,path:w.path,type:_(w.path)?"note":w.meta.type,hop:w.hop}));return{answer:y.answer,citations:y.status==="ok"?$.map(({hop:w,...v})=>v):[],candidates:$.filter(w=>w.hop===0).map(({title:w,path:v})=>({title:w,path:v})),walked:$,status:y.status,method:"summaries",basis:y.basis,live:y.live,liveAsked:y.liveAsked,trace:y.trace,...y.error?{error:y.error}:{}}}}if(!X(a)&&p.sharedPool.length===0)return M("no-catalog",e,"No _index.md found \u2014 run `agentx wiki status` to rebuild.");let it=(X(a)?lt(a,"utf-8"):"")+yt(e,p.sharedPool,h,n),T=Date.now(),A=[],S="";try{let u=await nt(e,p.pool,o,m,h,n);u?(A=u,S=`[wiki-rerank seat] ${u.map(f=>f.title).join(" | ")}`):(S=await Z(wt(e,it,m,h),c,i),A=bt(S))}catch(u){return s("selector failed:",u?.message),{...M("error",e,`Selector: ${u?.message||"unknown"}`),trace:{selectorMs:Date.now()-T,synthesisMs:0,selectorOutput:S}}}let x=Date.now()-T;if(A.length===0)return{...M("no-candidates",e,"Selector returned no candidates."),trace:{selectorMs:x,synthesisMs:0,selectorOutput:S}};let C=rt(A,p,g,d);if(C.length===0)return{...M("no-candidates",e,"Candidates did not resolve to readable articles."),candidates:A,trace:{selectorMs:x,synthesisMs:0,selectorOutput:S}};let D=Date.now(),U="";try{U=await Z(kt(e,C),l,i*2)}catch(u){return s("synthesis failed:",u?.message),{...M("error",e,`Synthesis: ${u?.message||"unknown"}`),candidates:A,walked:C.map(f=>({title:f.meta.title,path:f.path,type:f.meta.type,hop:f.hop??0})),trace:{selectorMs:x,synthesisMs:Date.now()-D,selectorOutput:S}}}let st=Date.now()-D;return{answer:U.trim(),citations:C.map(u=>({title:u.meta.title,path:u.path,type:u.meta.type})),candidates:A,walked:C.map(u=>({title:u.meta.title,path:u.path,type:u.meta.type,hop:u.hop??0})),status:"ok",trace:{selectorMs:x,synthesisMs:st,selectorOutput:S}}}async function Rt(e,r,o,t={}){let c=t.maxCandidates??3,l=t.graphWeight??W,m=t.messagePath?.length?t.messagePath:void 0,g=t.pool??q(r);if(g.length===0||!e.trim())return[];let d=await nt(e,g,o,c,m,l,t.stage??"retrieve");if(!d){let i=new Set(L(e,E(g.map(at))).map(s=>s.docIndex));d=O(e,g,m,l).filter(s=>i.has(s)).slice(0,c).map(s=>({title:g[s].title,path:g[s].path}))}return d.length===0?[]:rt(d,tt(r,o),t.maxHops??1,t.maxArticles??6)}function q(e){try{return(e.rebuildIndex().articles??[]).filter(r=>r.path&&!r.path.includes("/_versions/"))}catch{return[]}}function M(e,r,o){return{answer:"",citations:[],candidates:[],walked:[],status:e,error:o}}function tt(e,r,o=[]){let t=new Map,c=[];for(let i of e.listArticles(r||""))t.set(i.meta.title.toLowerCase(),i.path),c.push({path:i.path,related:i.meta.related??[],lastUpdated:i.meta.lastUpdated??""});let l=[],m=new Map;for(let i of o)if(i.store.baseDir!==e.baseDir){m.set(i.id,i);for(let s of i.store.listArticles(r||"")){if(s.path.includes("/_versions/")||i.skip?.(s.path))continue;let h=`@${i.id}/${s.path}`;l.push(ut(s,h)),c.push({path:h,related:s.meta.related??[],lastUpdated:s.meta.lastUpdated??""});let n=s.meta.title.toLowerCase();t.has(n)||t.set(n,h)}}let g=new Map;if(m.size>0)for(let i of[...c].sort((s,h)=>h.lastUpdated.localeCompare(s.lastUpdated)))for(let s of i.related){let h=s.toLowerCase(),n=g.get(h)??[];n.includes(i.path)||n.push(i.path),g.set(h,n)}let d;return{backlinks:g,readable:new Set(c.map(i=>i.path)),get pool(){return d??=[...q(e),...l]},sharedPool:l,titleIndex:t,read(i){let s=i.match(/^@([^/]+)\/(.+)$/),h=s?m.get(s[1]):void 0;if(s&&!h)return null;let n=h?.store??e,a=s?s[2]:i,p=r?n.readArticleAs(a,r):n.readArticle(a);return p?{...p,path:i}:null},links(i){let s=(i.meta.related??[]).map(a=>t.get(a.toLowerCase())).filter(a=>!!a),h=[i.meta.title,...i.meta.aliases??[]].map(a=>a.toLowerCase()),n=[...new Set(h.flatMap(a=>g.get(a)??[]))].filter(a=>a!==i.path).slice(0,et);return[...new Set([...s,...n])].filter(a=>a!==i.path)}}}function gt(e,r){return{...e,pool:[...e.pool,...r.pool],readable:new Set([...e.readable,...r.pool.map(o=>o.path)]),read:o=>_(o)?r.read(o):e.read(o)}}function ut(e,r){return{path:r,title:e.meta.title,type:e.meta.type,related:e.meta.related,tags:e.meta.tags||[],owner:e.meta.owner,access:e.meta.access,sharedWith:e.meta.sharedWith,aliases:[e.meta.title.toLowerCase(),...(e.meta.aliases??[]).map(o=>o.toLowerCase())],backlinks:0,sources:e.meta.sources,lastUpdated:e.meta.lastUpdated,graphPath:e.meta.graphPath}}var ft=150;function yt(e,r,o,t){return r.length===0?"":`
1
+ import{a as _,b as F,c as K,d as z,e as J}from"./chunk-SKSYII3K.js";import{a as j,b as I,c as Y,d as V,e as B,j as G}from"./chunk-UII54DAP.js";import{a as H}from"./chunk-MWNCS57L.js";import{y as N,z as ot}from"./chunk-R5VGRKUW.js";import{g as Q}from"./chunk-6TURWSMN.js";import{b as E,c as L}from"./chunk-QOYAX2FT.js";import{readFileSync as lt,existsSync as X}from"fs";ot();import{resolve as R}from"path";import{execSync as ct}from"child_process";var ht="haiku",dt="sonnet",pt=.8;function mt(e,r,o,t){if(t.size===0)return 0;let c=e.listArticles(r||"").map(l=>l.path).filter(l=>!l.includes("/_versions/"));return c.length===0&&(c=o.sharedPool.map(l=>l.path)),c.length===0?0:c.filter(l=>t.has(l)).length/c.length}async function _t(e,r,o,t={}){let c=t.selectorModel??ht,l=t.synthModel??dt,m=t.maxCandidates??3,g=t.maxHops??2,d=t.maxArticles??8,i=t.timeoutMs??6e4,s=t.log??console.error.bind(console,"[wiki-query]"),h=t.messagePath?.length?t.messagePath:void 0,n=t.graphWeight??W,a=R(r.baseDir,"_index.md"),p=tt(r,o,t.shared),b=t.method??"catalog";if(b!=="catalog"){let u=z(r,t.shared);if(b==="summaries"||mt(r,o,p,u)>=pt){let f=t.summaries??K,P=t.notes&&o&&t.notes.owner===o?F(t.notes):void 0,y=await J(e,P?gt(p,P):p,P?new Map([...u,...P.summaries]):u,{...f,navigatorModel:t.selectorModel??f.navigatorModel,answerModel:t.synthModel??f.answerModel},{call:t.call??H,fetch:t.fetch,timeoutMs:i,log:s}),$=y.picked.map(w=>({title:w.meta.title,path:w.path,type:_(w.path)?"note":w.meta.type,hop:w.hop}));return{answer:y.answer,citations:y.status==="ok"?$.map(({hop:w,...v})=>v):[],candidates:$.filter(w=>w.hop===0).map(({title:w,path:v})=>({title:w,path:v})),walked:$,status:y.status,method:"summaries",basis:y.basis,live:y.live,liveAsked:y.liveAsked,trace:y.trace,...y.error?{error:y.error}:{}}}}if(!X(a)&&p.sharedPool.length===0)return M("no-catalog",e,"No _index.md found \u2014 run `agentx wiki status` to rebuild.");let it=(X(a)?lt(a,"utf-8"):"")+yt(e,p.sharedPool,h,n),T=Date.now(),A=[],S="";try{let u=await nt(e,p.pool,o,m,h,n);u?(A=u,S=`[wiki-rerank seat] ${u.map(f=>f.title).join(" | ")}`):(S=await Z(wt(e,it,m,h),c,i),A=bt(S))}catch(u){return s("selector failed:",u?.message),{...M("error",e,`Selector: ${u?.message||"unknown"}`),trace:{selectorMs:Date.now()-T,synthesisMs:0,selectorOutput:S}}}let x=Date.now()-T;if(A.length===0)return{...M("no-candidates",e,"Selector returned no candidates."),trace:{selectorMs:x,synthesisMs:0,selectorOutput:S}};let C=rt(A,p,g,d);if(C.length===0)return{...M("no-candidates",e,"Candidates did not resolve to readable articles."),candidates:A,trace:{selectorMs:x,synthesisMs:0,selectorOutput:S}};let D=Date.now(),U="";try{U=await Z(kt(e,C),l,i*2)}catch(u){return s("synthesis failed:",u?.message),{...M("error",e,`Synthesis: ${u?.message||"unknown"}`),candidates:A,walked:C.map(f=>({title:f.meta.title,path:f.path,type:f.meta.type,hop:f.hop??0})),trace:{selectorMs:x,synthesisMs:Date.now()-D,selectorOutput:S}}}let st=Date.now()-D;return{answer:U.trim(),citations:C.map(u=>({title:u.meta.title,path:u.path,type:u.meta.type})),candidates:A,walked:C.map(u=>({title:u.meta.title,path:u.path,type:u.meta.type,hop:u.hop??0})),status:"ok",trace:{selectorMs:x,synthesisMs:st,selectorOutput:S}}}async function Rt(e,r,o,t={}){let c=t.maxCandidates??3,l=t.graphWeight??W,m=t.messagePath?.length?t.messagePath:void 0,g=t.pool??q(r);if(g.length===0||!e.trim())return[];let d=await nt(e,g,o,c,m,l,t.stage??"retrieve");if(!d){let i=new Set(L(e,E(g.map(at))).map(s=>s.docIndex));d=O(e,g,m,l).filter(s=>i.has(s)).slice(0,c).map(s=>({title:g[s].title,path:g[s].path}))}return d.length===0?[]:rt(d,tt(r,o),t.maxHops??1,t.maxArticles??6)}function q(e){try{return(e.rebuildIndex().articles??[]).filter(r=>r.path&&!r.path.includes("/_versions/"))}catch{return[]}}function M(e,r,o){return{answer:"",citations:[],candidates:[],walked:[],status:e,error:o}}function tt(e,r,o=[]){let t=new Map,c=[];for(let i of e.listArticles(r||""))t.set(i.meta.title.toLowerCase(),i.path),c.push({path:i.path,related:i.meta.related??[],lastUpdated:i.meta.lastUpdated??""});let l=[],m=new Map;for(let i of o)if(i.store.baseDir!==e.baseDir){m.set(i.id,i);for(let s of i.store.listArticles(r||"")){if(s.path.includes("/_versions/")||i.skip?.(s.path))continue;let h=`@${i.id}/${s.path}`;l.push(ut(s,h)),c.push({path:h,related:s.meta.related??[],lastUpdated:s.meta.lastUpdated??""});let n=s.meta.title.toLowerCase();t.has(n)||t.set(n,h)}}let g=new Map;if(m.size>0)for(let i of[...c].sort((s,h)=>h.lastUpdated.localeCompare(s.lastUpdated)))for(let s of i.related){let h=s.toLowerCase(),n=g.get(h)??[];n.includes(i.path)||n.push(i.path),g.set(h,n)}let d;return{backlinks:g,readable:new Set(c.map(i=>i.path)),get pool(){return d??=[...q(e),...l]},sharedPool:l,titleIndex:t,read(i){let s=i.match(/^@([^/]+)\/(.+)$/),h=s?m.get(s[1]):void 0;if(s&&!h)return null;let n=h?.store??e,a=s?s[2]:i,p=r?n.readArticleAs(a,r):n.readArticle(a);return p?{...p,path:i}:null},links(i){let s=(i.meta.related??[]).map(a=>t.get(a.toLowerCase())).filter(a=>!!a),h=[i.meta.title,...i.meta.aliases??[]].map(a=>a.toLowerCase()),n=[...new Set(h.flatMap(a=>g.get(a)??[]))].filter(a=>a!==i.path).slice(0,et);return[...new Set([...s,...n])].filter(a=>a!==i.path)}}}function gt(e,r){return{...e,pool:[...e.pool,...r.pool],readable:new Set([...e.readable,...r.pool.map(o=>o.path)]),read:o=>_(o)?r.read(o):e.read(o)}}function ut(e,r){return{path:r,title:e.meta.title,type:e.meta.type,related:e.meta.related,tags:e.meta.tags||[],owner:e.meta.owner,access:e.meta.access,sharedWith:e.meta.sharedWith,aliases:[e.meta.title.toLowerCase(),...(e.meta.aliases??[]).map(o=>o.toLowerCase())],backlinks:0,sources:e.meta.sources,lastUpdated:e.meta.lastUpdated,graphPath:e.meta.graphPath}}var ft=150;function yt(e,r,o,t){return r.length===0?"":`
2
2
 
3
3
  ## Shared wiki (other agents' articles)
4
4
 
@@ -51,5 +51,5 @@ ${o}
51
51
 
52
52
  Answer the question in 2\u20136 sentences. Cite articles by their title in square brackets like [Article Title]. When two articles disagree, prefer the one updated more recently, and say which agent's page and date the answer comes from. If the articles do not answer the question, say so plainly (do not invent). Prefer concrete facts over hedging.
53
53
 
54
- Output ONLY the answer \u2014 no preamble, no "here is my answer:", no markdown fencing.`}function bt(e){let r=e.match(/\[[\s\S]*?\]/);if(!r)return[];try{let o=JSON.parse(r[0]);return Array.isArray(o)?o.filter(t=>t&&typeof t.title=="string"&&typeof t.path=="string").map(t=>({title:t.title,path:t.path})):[]}catch{return[]}}async function Z(e,r,o){let{writeFileSync:t,mkdirSync:c,rmSync:l}=await import("fs"),{tmpdir:m}=await import("os"),g=R(m(),`agentx-wiki-query-${process.pid}`);c(g,{recursive:!0});let d=R(g,`prompt-${Date.now()}.txt`);t(d,e);try{let i=`cat '${d}' | claude -p - --output-format json --max-turns 1 --model ${r} --disallowedTools "Bash Read Write Edit Glob Grep Agent WebSearch WebFetch NotebookEdit"`,s=ct(i,{env:Q(),encoding:"utf-8",timeout:o,maxBuffer:4*1024*1024});try{let h=JSON.parse(s);return String(h.result||h.content||"")}catch{return s}}finally{try{l(d,{force:!0})}catch{}}}async function Ot(e){try{let{loadDaemonConfig:r}=await import("./config-Z64VWERV.js");return r(e).wiki.query.shared}catch{return!0}}export{ht as a,dt as b,pt as c,_t as d,Rt as e,q as f,ft as g,W as h,O as i,Ot as j};
55
- //# sourceMappingURL=chunk-S3LWGPNZ.js.map
54
+ Output ONLY the answer \u2014 no preamble, no "here is my answer:", no markdown fencing.`}function bt(e){let r=e.match(/\[[\s\S]*?\]/);if(!r)return[];try{let o=JSON.parse(r[0]);return Array.isArray(o)?o.filter(t=>t&&typeof t.title=="string"&&typeof t.path=="string").map(t=>({title:t.title,path:t.path})):[]}catch{return[]}}async function Z(e,r,o){let{writeFileSync:t,mkdirSync:c,rmSync:l}=await import("fs"),{tmpdir:m}=await import("os"),g=R(m(),`agentx-wiki-query-${process.pid}`);c(g,{recursive:!0});let d=R(g,`prompt-${Date.now()}.txt`);t(d,e);try{let i=`cat '${d}' | claude -p - --output-format json --max-turns 1 --model ${r} --disallowedTools "Bash Read Write Edit Glob Grep Agent WebSearch WebFetch NotebookEdit"`,s=ct(i,{env:Q(),encoding:"utf-8",timeout:o,maxBuffer:4*1024*1024});try{let h=JSON.parse(s);return String(h.result||h.content||"")}catch{return s}}finally{try{l(d,{force:!0})}catch{}}}async function Ot(e){try{let{loadDaemonConfig:r}=await import("./config-MLP33NWR.js");return r(e).wiki.query.shared}catch{return!0}}export{ht as a,dt as b,pt as c,_t as d,Rt as e,q as f,ft as g,W as h,O as i,Ot as j};
55
+ //# sourceMappingURL=chunk-2GJFLPS7.js.map
@@ -1,4 +1,4 @@
1
- import{b as S,c as O}from"./chunk-7Y3FEIX7.js";import{h as B,j as J}from"./chunk-3UOTLMXD.js";import{a as I,b as P}from"./chunk-FCPTN6NF.js";import{a as X,b as ue}from"./chunk-7I7IEX4S.js";import{d as F}from"./chunk-QIJLFPWE.js";import{execFile as Ae}from"child_process";import{writeFileSync as ie,mkdirSync as x,existsSync as b,readFileSync as ke}from"fs";import{resolve as v}from"path";var le=["off","shadow","authoritative"],ge={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"},me="INTENT_LEDGER_MODE";function G(i,e=process.env){let t=U(e[ge[i]]);if(t)return t;let n=U(e[me]);return n||"off"}function U(i){if(typeof i!="string")return null;let e=i.trim().toLowerCase();return le.includes(e)?e:null}P();import he from"better-sqlite3";import{existsSync as Ue,mkdirSync as fe}from"fs";import{dirname as pe,resolve as Ee}from"path";var T=class{db;path;constructor(e={}){this.path=Ee(process.cwd(),e.path??".agentx/intent/ledger.sqlite"),fe(pe(this.path),{recursive:!0}),this.db=new he(this.path),this.db.pragma("journal_mode = WAL"),this.db.pragma("synchronous = NORMAL"),this.db.pragma("foreign_keys = ON"),ye(this.db)}close(){this.db.close()}schemaVersion(){return this.db.prepare("SELECT MAX(v) AS v FROM schema_version").get().v??0}recordEvent(e){if(e.sourceEventId!==null){let n=this.findEventBySourceId(e.source,e.sourceEventId);if(n)return n}let t={id:e.id??I(e.ts),ts:e.ts,source:e.source,sourceEventId:e.sourceEventId,project:e.project,subject:e.subject,intent:e.intent,rawJson:e.rawJson};return this.db.prepare(`INSERT INTO intent_events (id, ts, source, source_event_id, project, subject, intent, raw_json)
1
+ import{b as S,c as O}from"./chunk-SFUNL7RV.js";import{h as B,j as J}from"./chunk-3UOTLMXD.js";import{a as I,b as P}from"./chunk-FCPTN6NF.js";import{a as X,b as ue}from"./chunk-7I7IEX4S.js";import{d as F}from"./chunk-QIJLFPWE.js";import{execFile as Ae}from"child_process";import{writeFileSync as ie,mkdirSync as x,existsSync as b,readFileSync as ke}from"fs";import{resolve as v}from"path";var le=["off","shadow","authoritative"],ge={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"},me="INTENT_LEDGER_MODE";function G(i,e=process.env){let t=U(e[ge[i]]);if(t)return t;let n=U(e[me]);return n||"off"}function U(i){if(typeof i!="string")return null;let e=i.trim().toLowerCase();return le.includes(e)?e:null}P();import he from"better-sqlite3";import{existsSync as Ue,mkdirSync as fe}from"fs";import{dirname as pe,resolve as Ee}from"path";var T=class{db;path;constructor(e={}){this.path=Ee(process.cwd(),e.path??".agentx/intent/ledger.sqlite"),fe(pe(this.path),{recursive:!0}),this.db=new he(this.path),this.db.pragma("journal_mode = WAL"),this.db.pragma("synchronous = NORMAL"),this.db.pragma("foreign_keys = ON"),ye(this.db)}close(){this.db.close()}schemaVersion(){return this.db.prepare("SELECT MAX(v) AS v FROM schema_version").get().v??0}recordEvent(e){if(e.sourceEventId!==null){let n=this.findEventBySourceId(e.source,e.sourceEventId);if(n)return n}let t={id:e.id??I(e.ts),ts:e.ts,source:e.source,sourceEventId:e.sourceEventId,project:e.project,subject:e.subject,intent:e.intent,rawJson:e.rawJson};return this.db.prepare(`INSERT INTO intent_events (id, ts, source, source_event_id, project, subject, intent, raw_json)
2
2
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(t.id,t.ts,t.source,t.sourceEventId,t.project,t.subject,t.intent,t.rawJson),t}findEventBySourceId(e,t){let n=this.db.prepare(`SELECT id, ts, source, source_event_id, project, subject, intent, raw_json
3
3
  FROM intent_events WHERE source = ? AND source_event_id = ?`).get(e,t);return n?Y(n):null}getEventById(e){let t=this.db.prepare(`SELECT id, ts, source, source_event_id, project, subject, intent, raw_json
4
4
  FROM intent_events WHERE id = ?`).get(e);return t?Y(t):null}recordDecision(e){this.db.prepare(`INSERT INTO intent_decisions (event_id, decided_at, decided_by, agent_id, outcome, reason)
@@ -125,4 +125,4 @@ ${se(o.block,r.prompt)}`,r.maxOutputTokens),agentId:r.agent,autonomy:r.autonomy,
125
125
  `);return t.length<=e?t.join(`
126
126
  `):t.slice(-e).join(`
127
127
  `)}function Xe(i,e,t){return new Promise((n,r)=>{Ae("/bin/sh",["-c",i],{timeout:e,maxBuffer:8*1024*1024,...t?{env:t}:{}},(s,a,o)=>{if(s&&s.killed){r(new Error(`command timed out after ${Math.round(e/1e3)}s`));return}n({stdout:String(a??""),stderr:String(o??""),code:s?typeof s.code=="number"?s.code:1:0})})})}export{T as a,V as b,ot as c,we as d,at as e,ct as f,$ as g,ee as h,G as i,We as j,z as k,Q as l,lt as m,Ce as n,oe as o,ae as p,ce as q,C as r,M as s};
128
- //# sourceMappingURL=chunk-TFNBUHRW.js.map
128
+ //# sourceMappingURL=chunk-3LAQ74H7.js.map
@@ -1,4 +1,4 @@
1
- import{b as St,c as At}from"./chunk-QSKG754X.js";import{c as bt}from"./chunk-SZDACK6O.js";import{b as xe}from"./chunk-AFRHKA7B.js";import{b as ht,e as wt,f as yt,i as It,k as vt,l as $t,q as Rt}from"./chunk-TFNBUHRW.js";import{b as ft,d as gt,e as mt}from"./chunk-PE5V2LI7.js";import{e as ut,g as ct,h as pt,i as Re}from"./chunk-GQ76J72O.js";import{a as kt}from"./chunk-GV7S5BAX.js";import{y as at,z as Bn}from"./chunk-KEBTFUOZ.js";import{b as st,f as Kn}from"./chunk-72SZI2UW.js";import{a as dt,b as $e,c as Se,d as lt,e as Ae}from"./chunk-QD6IICK7.js";import{c as ot,d as it}from"./chunk-QOYAX2FT.js";import{f as ve,n as Hn}from"./chunk-UIBUZ2N3.js";import{existsSync as qn,mkdirSync as xt,readFileSync as zn,writeFileSync as Jn,renameSync as Yn}from"fs";import{resolve as Pt,dirname as Gn}from"path";var Tt=class{filePath;log;constructor(e={}){let t=e.baseDir??Pt(process.cwd(),".agentx");this.filePath=Pt(t,"handover.json"),this.log=e.log??console.error.bind(console,"[handover]"),xt(t,{recursive:!0})}key(e,t,r){return`${e}::${t}::${r||"-"}`}load(){if(!qn(this.filePath))return{version:1,overrides:{}};try{let e=zn(this.filePath,"utf-8"),t=JSON.parse(e);return!t||typeof t!="object"?{version:1,overrides:{}}:(t.overrides||(t.overrides={}),t)}catch(e){return this.log(`load failed, starting empty: ${e?.message||e}`),{version:1,overrides:{}}}}save(e){xt(Gn(this.filePath),{recursive:!0});let t=`${this.filePath}.tmp-${process.pid}`;Jn(t,JSON.stringify(e,null,2)),Yn(t,this.filePath)}get(e,t,r){let s=this.load().overrides[this.key(e,t,r)];if(s&&!(s.expiresAt&&Date.parse(s.expiresAt)<Date.now()))return s}set(e){if(!e.channel||!e.chatId||!e.toAgent)throw new Error("channel, chatId and toAgent are required");let t=this.load(),r={...e,createdAt:e.createdAt??new Date().toISOString()};return t.overrides[this.key(r.channel,r.chatId,r.accountId)]=r,this.save(t),r}remove(e,t,r){let o=this.load(),s=this.key(e,t,r);return s in o.overrides?(delete o.overrides[s],this.save(o),!0):!1}consumeSummary(e,t,r){let o=this.load(),s=o.overrides[this.key(e,t,r)];if(!s||!s.summary||s.summaryConsumedAt)return;let a=s.summary;return s.summaryConsumedAt=new Date().toISOString(),this.save(o),a}listActive(){let e=this.load(),t=Date.now();return Object.values(e.overrides).filter(r=>!r.expiresAt||Date.parse(r.expiresAt)>=t)}listByAgent(e){let t=this.listActive();return{incoming:t.filter(r=>r.toAgent===e),outgoing:t.filter(r=>r.fromAgent===e)}}};import{readFileSync as Et,writeFileSync as Pe,appendFileSync as Xn,mkdirSync as er,existsSync as Mt,statSync as tr}from"fs";import{resolve as ne}from"path";var Wt="[Agent Memory \u2014 persistent facts from past conversations]",Vn=2400;function Nt(n,e){return n?`UNVERIFIED (${e===null?"age unknown":`${e}d old`}) `:""}function Qn(n,e=Date.now()){let t=gt(n,e),r=n.undated?"UNVERIFIED (never checked) ":Nt(t,ut(n.verifiedAt,e));return{line:`- [wiki ${n.id}] ${r}${n.subject} \xB7 ${n.attribute}: ${n.value} (${n.source}, checked ${n.verifiedAt.slice(0,10)} by ${n.verifiedBy})`,unverified:t}}function Zn(n,e){let r=!n.source.chatId.startsWith("-")&&/^\d+$/.test(n.source.chatId)?"DM":n.source.chatId,o=pt(n,e);return{line:`- [${n.category}] ${Nt(o,ct(n,e))}${n.content} (${r}, ${n.source.date})`,unverified:o}}function Dt(n,e=[],t=Date.now()){let r=[],o=new Set,s=Wt.length,a=!1;for(let i of n){let d=e.length>0?mt(i.content,e):null,l,p,c=d&&Date.parse(i.createdAt)>Date.parse(d.verifiedAt)&&!i.content.toLowerCase().includes(d.value.toLowerCase());if(d&&!c){if(o.has(d.id))continue;o.add(d.id),l=Qn(d,t),p=d.id}else l=Zn(i,t),d&&(l.line+=` [differs from wiki ${d.id}]`);let f=l.unverified&&!a?Re.length:0;if(s+f+l.line.length>Vn)break;r.push({fact:i,...l,...p?{wikiRef:p}:{}}),s+=f+l.line.length,f&&(a=!0)}return r}function Ot(n){if(n.length===0)return"";let e=n.some(t=>t.unverified)?[Re]:[];return[Wt,...e,...n.map(t=>t.line),"[End Memory]"].join(`
1
+ import{c as bt}from"./chunk-SZDACK6O.js";import{b as xe}from"./chunk-AFRHKA7B.js";import{b as St,c as At}from"./chunk-5TTHN7DP.js";import{b as ht,e as wt,f as yt,i as It,k as vt,l as $t,q as Rt}from"./chunk-3LAQ74H7.js";import{b as ft,d as gt,e as mt}from"./chunk-PE5V2LI7.js";import{e as ut,g as ct,h as pt,i as Re}from"./chunk-GQ76J72O.js";import{a as kt}from"./chunk-GV7S5BAX.js";import{y as at,z as Bn}from"./chunk-R5VGRKUW.js";import{b as st,f as Kn}from"./chunk-72SZI2UW.js";import{a as dt,b as $e,c as Se,d as lt,e as Ae}from"./chunk-QD6IICK7.js";import{c as ot,d as it}from"./chunk-QOYAX2FT.js";import{f as ve,n as Hn}from"./chunk-UIBUZ2N3.js";import{existsSync as qn,mkdirSync as xt,readFileSync as zn,writeFileSync as Jn,renameSync as Yn}from"fs";import{resolve as Pt,dirname as Gn}from"path";var Tt=class{filePath;log;constructor(e={}){let t=e.baseDir??Pt(process.cwd(),".agentx");this.filePath=Pt(t,"handover.json"),this.log=e.log??console.error.bind(console,"[handover]"),xt(t,{recursive:!0})}key(e,t,r){return`${e}::${t}::${r||"-"}`}load(){if(!qn(this.filePath))return{version:1,overrides:{}};try{let e=zn(this.filePath,"utf-8"),t=JSON.parse(e);return!t||typeof t!="object"?{version:1,overrides:{}}:(t.overrides||(t.overrides={}),t)}catch(e){return this.log(`load failed, starting empty: ${e?.message||e}`),{version:1,overrides:{}}}}save(e){xt(Gn(this.filePath),{recursive:!0});let t=`${this.filePath}.tmp-${process.pid}`;Jn(t,JSON.stringify(e,null,2)),Yn(t,this.filePath)}get(e,t,r){let s=this.load().overrides[this.key(e,t,r)];if(s&&!(s.expiresAt&&Date.parse(s.expiresAt)<Date.now()))return s}set(e){if(!e.channel||!e.chatId||!e.toAgent)throw new Error("channel, chatId and toAgent are required");let t=this.load(),r={...e,createdAt:e.createdAt??new Date().toISOString()};return t.overrides[this.key(r.channel,r.chatId,r.accountId)]=r,this.save(t),r}remove(e,t,r){let o=this.load(),s=this.key(e,t,r);return s in o.overrides?(delete o.overrides[s],this.save(o),!0):!1}consumeSummary(e,t,r){let o=this.load(),s=o.overrides[this.key(e,t,r)];if(!s||!s.summary||s.summaryConsumedAt)return;let a=s.summary;return s.summaryConsumedAt=new Date().toISOString(),this.save(o),a}listActive(){let e=this.load(),t=Date.now();return Object.values(e.overrides).filter(r=>!r.expiresAt||Date.parse(r.expiresAt)>=t)}listByAgent(e){let t=this.listActive();return{incoming:t.filter(r=>r.toAgent===e),outgoing:t.filter(r=>r.fromAgent===e)}}};import{readFileSync as Et,writeFileSync as Pe,appendFileSync as Xn,mkdirSync as er,existsSync as Mt,statSync as tr}from"fs";import{resolve as ne}from"path";var Wt="[Agent Memory \u2014 persistent facts from past conversations]",Vn=2400;function Nt(n,e){return n?`UNVERIFIED (${e===null?"age unknown":`${e}d old`}) `:""}function Qn(n,e=Date.now()){let t=gt(n,e),r=n.undated?"UNVERIFIED (never checked) ":Nt(t,ut(n.verifiedAt,e));return{line:`- [wiki ${n.id}] ${r}${n.subject} \xB7 ${n.attribute}: ${n.value} (${n.source}, checked ${n.verifiedAt.slice(0,10)} by ${n.verifiedBy})`,unverified:t}}function Zn(n,e){let r=!n.source.chatId.startsWith("-")&&/^\d+$/.test(n.source.chatId)?"DM":n.source.chatId,o=pt(n,e);return{line:`- [${n.category}] ${Nt(o,ct(n,e))}${n.content} (${r}, ${n.source.date})`,unverified:o}}function Dt(n,e=[],t=Date.now()){let r=[],o=new Set,s=Wt.length,a=!1;for(let i of n){let d=e.length>0?mt(i.content,e):null,l,p,c=d&&Date.parse(i.createdAt)>Date.parse(d.verifiedAt)&&!i.content.toLowerCase().includes(d.value.toLowerCase());if(d&&!c){if(o.has(d.id))continue;o.add(d.id),l=Qn(d,t),p=d.id}else l=Zn(i,t),d&&(l.line+=` [differs from wiki ${d.id}]`);let f=l.unverified&&!a?Re.length:0;if(s+f+l.line.length>Vn)break;r.push({fact:i,...l,...p?{wikiRef:p}:{}}),s+=f+l.line.length,f&&(a=!0)}return r}function Ot(n){if(n.length===0)return"";let e=n.some(t=>t.unverified)?[Re]:[];return[Wt,...e,...n.map(t=>t.line),"[End Memory]"].join(`
2
2
  `)}var Ft=200,nr=7,jt=class{memoryDir;ledger;constructor(e=process.cwd()){this.memoryDir=ne(e,".agentx/memory"),this.ledger=new ft(ne(e,".agentx/wiki")),Mt(this.memoryDir)||er(this.memoryDir,{recursive:!0})}filePath(e){return ne(this.memoryDir,`${e}.jsonl`)}addMemory(e,t){if(t.category==="secret"||$e(t.content))return!1;let r=t.source.trust??dt(t.source.channel),o=t.review??lt(r),s={...t,source:{...t.source,trust:r},...o?{review:o}:{},id:`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,createdAt:new Date().toISOString()};return Xn(this.filePath(e),JSON.stringify(s)+`
3
3
  `),!0}parsedCache=new Map;getAll(e){let t=this.filePath(e);if(!Mt(t))return[];try{let{mtimeMs:r,size:o}=tr(t),s=this.parsedCache.get(t);if(s&&s.mtimeMs===r&&s.size===o)return s.facts.slice();let i=Et(t,"utf-8").split(`
4
4
  `).filter(d=>d.trim()).map(d=>{try{return JSON.parse(d)}catch{return null}}).filter(d=>d!==null);return this.parsedCache.set(t,{mtimeMs:r,size:o,facts:i}),i.slice()}catch{return[]}}findRelevant(e,t,r=8){let o=this.getAll(t).filter(Ae);if(o.length===0)return[];let s=o.map(g=>`${g.keywords.join(" ")} ${g.content}`),a=ne(this.memoryDir,`${t}_bm25_cache.json`),i=it(s,a),d=ot(e,i),l=new Map(d.map(g=>[g.docIndex,g.score])),c=o.map((g,m)=>{let y=l.get(m)??0;return g.category==="commitment"&&(y+=1),{memory:g,score:y}}).filter(g=>g.score>0);if(c.length===0)return o.slice(-r);let f=c.sort((g,m)=>m.score-g.score).slice(0,r).map(g=>g.memory);if(f.length>0)try{this.recordAccess(t,f.map(g=>g.id))}catch{}return f}buildContext(e){return Ot(this.contextLines(e))}contextFacts(e){return this.contextLines(e).map(t=>t.fact)}contextLines(e){let t=[];try{t=this.ledger.list()}catch{}return Dt(e,t)}recordAccess(e,t){if(t.length===0)return;let r=this.getAll(e),o=new Set(t),s=!1;for(let a of r)if(o.has(a.id)){a.accessCount=(a.accessCount||0)+1,a.lastAccessed=new Date().toISOString();let i=a.intervalDays||1;a.intervalDays=Math.min(i*2,30),a.nextReview=new Date(Date.now()+a.intervalDays*864e5).toISOString(),s=!0}s&&Pe(this.filePath(e),r.map(a=>JSON.stringify(a)).join(`
@@ -38,4 +38,4 @@ ${n.text}`}async function me(n,e){let t=n.channels[e.channel],r={channel:e.chann
38
38
  `).filter(Boolean),o=[];for(let s=r.length-1;s>=0&&o.length<t;s--)try{let a=JSON.parse(r[s]);(!e||a.person===e)&&o.push(a)}catch{}return o}load(){if(Xe(this.file))try{let e=JSON.parse(et(this.file,"utf-8"));if(e&&Array.isArray(e.devices))return e}catch{}return{devices:[]}}save(e){Sn(xn(this.file),{recursive:!0});let t=`${this.file}.${process.pid}.${Tn(4).toString("hex")}.tmp`;Rn(t,JSON.stringify(e,null,2)+`
39
39
  `,{encoding:"utf-8",mode:384}),An(t,this.file)}};import{extname as li}from"path";var Nn=/<agentx-artifact>([\s\S]*?)<\/agentx-artifact>/gi,Dn=/<agentx-artifact>[\s\S]*$/i;function ld(n,e=1/0,t=!1){let r=[],o=String(n??"");if(!/<agentx-artifact>/i.test(o))return{text:o,artifacts:r};let s=o.replace(Nn,(a,i)=>{try{let d=JSON.parse(i.trim());if(d&&typeof d.filename=="string"&&typeof d.mime=="string"&&r.length<e){let l=d.mime,p=l.startsWith("image/")?"image":l==="application/pdf"?"pdf":l.startsWith("text/")?"text":"file";r.push({type:p,filename:d.filename,mime:l})}}catch{}return""});return{text:(t?s.replace(Dn,""):s).trim(),artifacts:r}}function ud(n,e=!1){let t=String(n??""),r=t;if(/<agentx-artifact>/i.test(t)){let o=t.replace(Nn,(s,a)=>{try{let i=JSON.parse(a.trim());return i&&typeof i.filename=="string"?i.filename:""}catch{return""}});r=(e?o.replace(Dn,""):o).trim()}return r.replace(/```[\s\S]*?```|`[^`\n]*`|!\[([^\]\n]*)\]\(([^)\s]+)\)/g,(o,s,a)=>s===void 0||a===void 0?o:`[${s||a}](${a})`)}var ui={".png":{mime:"image/png",kind:"image"},".jpg":{mime:"image/jpeg",kind:"image"},".jpeg":{mime:"image/jpeg",kind:"image"},".gif":{mime:"image/gif",kind:"image"},".webp":{mime:"image/webp",kind:"image"},".svg":{mime:"image/svg+xml",kind:"file"},".pdf":{mime:"application/pdf",kind:"file"},".txt":{mime:"text/plain; charset=utf-8",kind:"file"},".md":{mime:"text/markdown; charset=utf-8",kind:"file"},".csv":{mime:"text/csv; charset=utf-8",kind:"file"},".json":{mime:"application/json",kind:"file"},".mp3":{mime:"audio/mpeg",kind:"audio"},".m4a":{mime:"audio/mp4",kind:"audio"},".wav":{mime:"audio/wav",kind:"audio"},".mp4":{mime:"video/mp4",kind:"video"},".webm":{mime:"video/webm",kind:"video"}},cd={bytes:20*1024*1024,perMessage:20,pathChars:512};function pd(n){return ui[li(n).toLowerCase()]??null}var ci=["[Phone app: showing files]","To show the owner a file you created (a chart, a screenshot, a PDF, a recording), save or copy it into .agentx/outbox/ in your workspace and end your reply with one line per file:",'<agentx-artifact>{"filename":".agentx/outbox/<name.ext>","mime":"<mime/type>"}</agentx-artifact>',"Files outside your workspace (/tmp, your home folder) are refused. Outbox files are removed after 7 days.","The line is removed from the text. Images show in the reply, audio and video get a player, other files an Open link. Allowed: png, jpg, gif, webp, svg, pdf, txt, md, csv, json, mp3, m4a, wav, mp4, webm; up to 20 MB and 20 files per reply.","A picture already on the web can go inline as ![what it shows](https://...)."].join(`
40
40
  `);function fd(n,e,t){return n==="app"&&e&&t!==!1?ci:void 0}import{lstatSync as nt,mkdirSync as pi,readdirSync as fi,realpathSync as tt,unlinkSync as gi}from"fs";import{join as be,resolve as On}from"path";var En=".agentx/outbox",mi=7*24*60*60*1e3;function hi(n,e){try{let t=tt(On(e,n)),r=be(t,En);return tt(r)===r&&nt(r).isDirectory()?r:null}catch{return null}}function wd(n,e={}){let t=e.cwd??process.cwd();if(e.create!==!1)try{let o=tt(On(t,n));nt(be(o,".agentx"),{throwIfNoEntry:!1})?.isSymbolicLink()||pi(be(o,En),{recursive:!0})}catch{return 0}let r=hi(n,t);return r?Mn(r,(e.now??Date.now())-(e.maxAgeMs??mi)):0}function Mn(n,e){let t=0;for(let r of fi(n)){let o=be(n,r);try{let s=nt(o);s.isDirectory()?t+=Mn(o,e):Math.max(s.mtimeMs,s.ctimeMs)<e&&(gi(o),t++)}catch{}}return t}export{Tt as a,jt as b,Ct as c,Di as d,ir as e,Oi as f,T as g,z as h,S as i,oe as j,Ir as k,Oe as l,F as m,Fe as n,Ce as o,Ge as p,To as q,Mo as r,Qe as s,_r as t,Go as u,Na as v,Da as w,Oa as x,Ea as y,Ma as z,Vo as A,Qo as B,Fa as C,ja as D,Ca as E,_a as F,Ha as G,Ka as H,Ba as I,qa as J,za as K,Ja as L,Ya as M,Ga as N,Va as O,Qa as P,Za as Q,ri as R,Xa as S,ed as T,td as U,nd as V,Wn as W,ld as X,ud as Y,cd as Z,pd as _,fd as $,En as aa,wd as ba};
41
- //# sourceMappingURL=chunk-3NKCOZQO.js.map
41
+ //# sourceMappingURL=chunk-45TKVOJX.js.map
@@ -1,2 +1,2 @@
1
- import{y as l,z as T}from"./chunk-KEBTFUOZ.js";import{a,f as w}from"./chunk-72SZI2UW.js";T();w();var d="task-tier";function u(e){return{task:b(e.message,2e3),agent:e.agent,channel:e.channel??null,continuesExistingSession:e.isFollowUp??!1,...e.toolsAvailable?{toolsAvailable:e.toolsAvailable}:{}}}var c={needsFlagship:a("This task needs the strongest available model to be done correctly.",{true:"Doing it well takes real reasoning: writing or reviewing code, diagnosing a failure, planning work across several steps, weighing a judgement, handling money, touching production or anything irreversible, following a long or ambiguous instruction, or work where being subtly wrong would not be noticed. Anything where a weaker model would produce something that LOOKS right belongs here.",false:"It is mechanical and its result is obvious on sight: acknowledging or confirming a message, restating or formatting something already written, a greeting, a status echo, reading one file and reporting what it says, a lookup with one right answer, a scheduled heartbeat with nothing to decide."})};function g(e){return e.needsFlagship.noul}function b(e,n){return e.length>n?`${e.slice(0,n)}\u2026`:e}var h=.2;function p(e){return e==="voice"||e==="desktop"||e==="opencode"}var f=60*60*1e3;function M(e,n){if(e==="claude-code"){let t=n?.cheapModels?.[e]??n?.cheapModel;return t&&/^(claude-|haiku$|sonnet$|opus$)/.test(t)?t:void 0}if(e==="codex-cli"){let t=n?.cheapModels?.[e];return t&&/^(gpt-|o\d)/.test(t)?t:void 0}}async function v(e){let n=(s,r=null)=>({downgraded:!1,needsFlagship:r,reason:s});if(p(e.channel))return n(`${e.channel} requests retain the configured model`);if(!e.cheapModel)return n("no cheaper model configured");if(e.isFollowUp){let s=e.sessionIdleMs??0,r=e.cacheTtlMs??f;if(s<r)return n(`follow-up on a warm cache (idle ${Math.round(s/1e3)}s) \u2014 swapping would cost more than it saves`)}let t;try{t=await l(d,u(e),c,{incumbent:{needsFlagship:1},features:{agent:e.agent,channel:e.channel??"unknown"},timeoutMs:1500})}catch{return n("routing seat threw \u2014 keeping the flagship")}if(!t)return n("routing seat unavailable \u2014 keeping the flagship");let o=g(t.answers);if(t.mode!=="active")return n(`shadow \u2014 would ${o<(e.threshold??h)?"downgrade":"keep"} (${o.toFixed(2)})`,o);let i=e.threshold??h;return o>=i?n(`needs the flagship (${o.toFixed(2)})`,o):{model:e.cheapModel,downgraded:!0,needsFlagship:o,reason:`mechanical task (${o.toFixed(2)} below ${i}) \u2192 ${e.cheapModel}`}}var A=["labeled","unlabeled","closed"];function y(e){let n=r=>({downgraded:!1,needsFlagship:null,reason:r});if(p(e.channel))return n(`${e.channel} requests retain the configured model`);let t=e.eventActions??[];if(!t.length)return n("not started by a platform event");let o=e.triage?.actions??A,i=t.find(r=>!o.includes(r));if(i)return n(`"${i}" is not a triage action`);let s=M(e.tier,{cheapModels:e.triage?.models});if(!s)return n(`no triage model set for ${e.tier}`);if(e.isFollowUp){let r=e.sessionIdleMs??0,m=e.cacheTtlMs??f;if(r<m)return n(`follow-up on a warm cache (idle ${Math.round(r/1e3)}s) \u2014 keeping the session's model`)}return{model:s,downgraded:!0,needsFlagship:null,reason:`triage event (${t.join(", ")}) \u2192 ${s}`}}export{h as a,p as b,M as c,v as d,A as e,y as f};
2
- //# sourceMappingURL=chunk-B5744ATM.js.map
1
+ import{y as l,z as T}from"./chunk-R5VGRKUW.js";import{a,f as w}from"./chunk-72SZI2UW.js";T();w();var d="task-tier";function u(e){return{task:b(e.message,2e3),agent:e.agent,channel:e.channel??null,continuesExistingSession:e.isFollowUp??!1,...e.toolsAvailable?{toolsAvailable:e.toolsAvailable}:{}}}var c={needsFlagship:a("This task needs the strongest available model to be done correctly.",{true:"Doing it well takes real reasoning: writing or reviewing code, diagnosing a failure, planning work across several steps, weighing a judgement, handling money, touching production or anything irreversible, following a long or ambiguous instruction, or work where being subtly wrong would not be noticed. Anything where a weaker model would produce something that LOOKS right belongs here.",false:"It is mechanical and its result is obvious on sight: acknowledging or confirming a message, restating or formatting something already written, a greeting, a status echo, reading one file and reporting what it says, a lookup with one right answer, a scheduled heartbeat with nothing to decide."})};function g(e){return e.needsFlagship.noul}function b(e,n){return e.length>n?`${e.slice(0,n)}\u2026`:e}var h=.2;function p(e){return e==="voice"||e==="desktop"||e==="opencode"}var f=60*60*1e3;function M(e,n){if(e==="claude-code"){let t=n?.cheapModels?.[e]??n?.cheapModel;return t&&/^(claude-|haiku$|sonnet$|opus$)/.test(t)?t:void 0}if(e==="codex-cli"){let t=n?.cheapModels?.[e];return t&&/^(gpt-|o\d)/.test(t)?t:void 0}}async function v(e){let n=(s,r=null)=>({downgraded:!1,needsFlagship:r,reason:s});if(p(e.channel))return n(`${e.channel} requests retain the configured model`);if(!e.cheapModel)return n("no cheaper model configured");if(e.isFollowUp){let s=e.sessionIdleMs??0,r=e.cacheTtlMs??f;if(s<r)return n(`follow-up on a warm cache (idle ${Math.round(s/1e3)}s) \u2014 swapping would cost more than it saves`)}let t;try{t=await l(d,u(e),c,{incumbent:{needsFlagship:1},features:{agent:e.agent,channel:e.channel??"unknown"},timeoutMs:1500})}catch{return n("routing seat threw \u2014 keeping the flagship")}if(!t)return n("routing seat unavailable \u2014 keeping the flagship");let o=g(t.answers);if(t.mode!=="active")return n(`shadow \u2014 would ${o<(e.threshold??h)?"downgrade":"keep"} (${o.toFixed(2)})`,o);let i=e.threshold??h;return o>=i?n(`needs the flagship (${o.toFixed(2)})`,o):{model:e.cheapModel,downgraded:!0,needsFlagship:o,reason:`mechanical task (${o.toFixed(2)} below ${i}) \u2192 ${e.cheapModel}`}}var A=["labeled","unlabeled","closed"];function y(e){let n=r=>({downgraded:!1,needsFlagship:null,reason:r});if(p(e.channel))return n(`${e.channel} requests retain the configured model`);let t=e.eventActions??[];if(!t.length)return n("not started by a platform event");let o=e.triage?.actions??A,i=t.find(r=>!o.includes(r));if(i)return n(`"${i}" is not a triage action`);let s=M(e.tier,{cheapModels:e.triage?.models});if(!s)return n(`no triage model set for ${e.tier}`);if(e.isFollowUp){let r=e.sessionIdleMs??0,m=e.cacheTtlMs??f;if(r<m)return n(`follow-up on a warm cache (idle ${Math.round(r/1e3)}s) \u2014 keeping the session's model`)}return{model:s,downgraded:!0,needsFlagship:null,reason:`triage event (${t.join(", ")}) \u2192 ${s}`}}export{h as a,p as b,M as c,v as d,A as e,y as f};
2
+ //# sourceMappingURL=chunk-4JHMV3D3.js.map
@@ -1,11 +1,11 @@
1
- import{a as i,b as c}from"./chunk-FCPTN6NF.js";var m="[Institutional Wiki";function u(e){return[...new Set(e)].slice(0,20).map(n=>n.slice(0,80))}function p(e,n){let t=e??"";return{memory:u((n.memory??[]).filter(r=>r.content&&t.includes(r.content)).map(r=>r.id)),procedures:u((n.procedures??[]).filter(r=>t.includes(`[Known procedure: ${r.title}]`)).map(r=>r.id)),wiki:!!n.wikiContext&&t.includes(m)}}function o(e){return{memory:u(e.memory),procedures:u(e.procedures),wiki:e.wiki===!0}}c();function h(e,n,t=i()){return e.prepare(`
1
+ import{a as o,b as d}from"./chunk-FCPTN6NF.js";d();var m="[Institutional Wiki";function u(e){return[...new Set(e)].slice(0,20).map(n=>n.slice(0,80))}function p(e,n){let t=e??"";return{memory:u((n.memory??[]).filter(r=>r.content&&t.includes(r.content)).map(r=>r.id)),procedures:u((n.procedures??[]).filter(r=>t.includes(`[Known procedure: ${r.title}]`)).map(r=>r.id)),wiki:!!n.wikiContext&&t.includes(m)}}function c(e){return{memory:u(e.memory),procedures:u(e.procedures),wiki:e.wiki===!0}}function h(e,n,t=o()){return e.prepare(`
2
2
  INSERT INTO task_traces (
3
3
  task_id, agent_id, channel, chat_id, workflow_run_id, workflow_id,
4
4
  workflow_node_id, intent_event_id, intent_decided_by, resume_session_id,
5
5
  model, status, started_at, message_preview, original_message,
6
6
  resume_origin, resume_attempt, resumed_from, person
7
7
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'in-flight', ?, ?, ?, ?, ?, ?, ?)
8
- `).run(t,n.agentId,n.channel??null,n.chatId??null,n.workflowRunId??null,n.workflowId??null,n.workflowNodeId??null,n.intentEventId??null,n.intentDecidedBy??null,n.resumeSessionId??null,n.model??null,Date.now(),n.messagePreview??null,n.originalMessage??null,n.resumeOrigin??null,n.resumeAttempt??0,n.resumedFrom??null,n.person??null),t}function T(e,n,t){let r=Date.now();e.prepare(`
8
+ `).run(t,n.agentId,n.channel??null,n.chatId??null,n.workflowRunId??null,n.workflowId??null,n.workflowNodeId??null,n.intentEventId??null,n.intentDecidedBy??null,n.resumeSessionId??null,n.model??null,Date.now(),n.messagePreview??null,n.originalMessage??null,n.resumeOrigin??null,n.resumeAttempt??0,n.resumedFrom??null,n.person??null),t}function E(e,n,t){let r=Date.now();e.prepare(`
9
9
  UPDATE task_traces SET
10
10
  status = ?,
11
11
  final_session_id = ?,
@@ -24,14 +24,15 @@ import{a as i,b as c}from"./chunk-FCPTN6NF.js";var m="[Institutional Wiki";funct
24
24
  injected_context = COALESCE(?, injected_context),
25
25
  error = ?,
26
26
  final_response = COALESCE(?, final_response),
27
+ model = COALESCE(?, model),
27
28
  finished_at = ?,
28
29
  duration_ms = ? - started_at
29
30
  WHERE task_id = ?
30
- `).run(t.status,t.finalSessionId??null,t.inputTokens??null,t.outputTokens??null,t.cacheReadTokens??null,t.cacheCreateTokens??null,t.tier2InputTokens??null,t.tier2OutputTokens??null,t.tier2CacheReadTokens??null,t.tier2CacheCreateTokens??null,t.resumed==null?null:t.resumed?1:0,t.resumeSessionId??null,t.jevArm??null,t.numTurns??null,t.injectedContext?JSON.stringify(o(t.injectedContext)):null,t.error??null,t.finalResponse??null,r,r,n)}function E(e,n,t){let r=Date.now();return e.transaction(()=>{let l=(e.prepare("SELECT MAX(seq) AS max_seq FROM task_trace_steps WHERE task_id = ?").get(n)?.max_seq??-1)+1;return e.prepare(`
31
+ `).run(t.status,t.finalSessionId??null,t.inputTokens??null,t.outputTokens??null,t.cacheReadTokens??null,t.cacheCreateTokens??null,t.tier2InputTokens??null,t.tier2OutputTokens??null,t.tier2CacheReadTokens??null,t.tier2CacheCreateTokens??null,t.resumed==null?null:t.resumed?1:0,t.resumeSessionId??null,t.jevArm??null,t.numTurns??null,t.injectedContext?JSON.stringify(c(t.injectedContext)):null,t.error??null,t.finalResponse??null,t.model??null,r,r,n)}function T(e,n,t){let r=Date.now();return e.transaction(()=>{let i=(e.prepare("SELECT MAX(seq) AS max_seq FROM task_trace_steps WHERE task_id = ?").get(n)?.max_seq??-1)+1;return e.prepare(`
31
32
  INSERT INTO task_trace_steps (
32
33
  task_id, seq, name, action, status, input_summary, output_summary, error, ms, started_at
33
34
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
34
- `).run(n,l,t.name,t.action??null,t.status??null,t.inputSummary??null,t.outputSummary??null,t.error??null,t.ms??null,r),l})()}function g(e){if(typeof e!="string")return null;try{let n=JSON.parse(e);if(!n||typeof n!="object")return null;let t=r=>Array.isArray(r)?r.filter(s=>typeof s=="string"):[];return{memory:t(n.memory),procedures:t(n.procedures),wiki:n.wiki===!0}}catch{return null}}function d(e){return{taskId:e.task_id,agentId:e.agent_id,channel:e.channel??null,chatId:e.chat_id??null,workflowRunId:e.workflow_run_id??null,workflowId:e.workflow_id??null,workflowNodeId:e.workflow_node_id??null,intentEventId:e.intent_event_id??null,intentDecidedBy:e.intent_decided_by??null,resumeSessionId:e.resume_session_id??null,finalSessionId:e.final_session_id??null,model:e.model??null,status:e.status,startedAt:e.started_at,finishedAt:e.finished_at??null,durationMs:e.duration_ms??null,inputTokens:e.input_tokens??null,outputTokens:e.output_tokens??null,cacheReadTokens:e.cache_read_tokens??null,cacheCreateTokens:e.cache_create_tokens??null,tier2InputTokens:e.tier2_input_tokens??null,tier2OutputTokens:e.tier2_output_tokens??null,tier2CacheReadTokens:e.tier2_cache_read_tokens??null,tier2CacheCreateTokens:e.tier2_cache_create_tokens??null,resumed:e.resumed==null?null:e.resumed===1,jevArm:e.jev_arm??null,numTurns:e.num_turns??null,injectedContext:g(e.injected_context),error:e.error??null,messagePreview:e.message_preview??null,originalMessage:e.original_message??null,finalResponse:e.final_response??null}}function _(e){return{taskId:e.task_id,seq:e.seq,name:e.name,action:e.action??null,status:e.status??null,inputSummary:e.input_summary??null,outputSummary:e.output_summary??null,error:e.error??null,ms:e.ms??null,startedAt:e.started_at}}function b(e,n){let t=e.prepare("SELECT * FROM task_traces WHERE task_id = ?").get(n);if(!t)return null;let r=e.prepare("SELECT * FROM task_trace_steps WHERE task_id = ? ORDER BY seq").all(n);return{task:d(t),steps:r.map(_)}}function R(e){let n=Date.now();return e.prepare(`
35
+ `).run(n,i,t.name,t.action??null,t.status??null,t.inputSummary??null,t.outputSummary??null,t.error??null,t.ms??null,r),i})()}function g(e){if(typeof e!="string")return null;try{let n=JSON.parse(e);if(!n||typeof n!="object")return null;let t=r=>Array.isArray(r)?r.filter(s=>typeof s=="string"):[];return{memory:t(n.memory),procedures:t(n.procedures),wiki:n.wiki===!0}}catch{return null}}function l(e){return{taskId:e.task_id,agentId:e.agent_id,channel:e.channel??null,chatId:e.chat_id??null,workflowRunId:e.workflow_run_id??null,workflowId:e.workflow_id??null,workflowNodeId:e.workflow_node_id??null,intentEventId:e.intent_event_id??null,intentDecidedBy:e.intent_decided_by??null,resumeSessionId:e.resume_session_id??null,finalSessionId:e.final_session_id??null,model:e.model??null,status:e.status,startedAt:e.started_at,finishedAt:e.finished_at??null,durationMs:e.duration_ms??null,inputTokens:e.input_tokens??null,outputTokens:e.output_tokens??null,cacheReadTokens:e.cache_read_tokens??null,cacheCreateTokens:e.cache_create_tokens??null,tier2InputTokens:e.tier2_input_tokens??null,tier2OutputTokens:e.tier2_output_tokens??null,tier2CacheReadTokens:e.tier2_cache_read_tokens??null,tier2CacheCreateTokens:e.tier2_cache_create_tokens??null,resumed:e.resumed==null?null:e.resumed===1,jevArm:e.jev_arm??null,numTurns:e.num_turns??null,injectedContext:g(e.injected_context),error:e.error??null,messagePreview:e.message_preview??null,originalMessage:e.original_message??null,finalResponse:e.final_response??null}}function _(e){return{taskId:e.task_id,seq:e.seq,name:e.name,action:e.action??null,status:e.status??null,inputSummary:e.input_summary??null,outputSummary:e.output_summary??null,error:e.error??null,ms:e.ms??null,startedAt:e.started_at}}function R(e,n){let t=e.prepare("SELECT * FROM task_traces WHERE task_id = ?").get(n);if(!t)return null;let r=e.prepare("SELECT * FROM task_trace_steps WHERE task_id = ? ORDER BY seq").all(n);return{task:l(t),steps:r.map(_)}}function b(e){let n=Date.now();return e.prepare(`
35
36
  UPDATE task_traces
36
37
  SET status = 'canceled',
37
38
  error = 'daemon-restart (orphaned in-flight)',
@@ -52,13 +53,16 @@ import{a as i,b as c}from"./chunk-FCPTN6NF.js";var m="[Institutional Wiki";funct
52
53
  `);return t().map(s=>({taskId:s.task_id,agentId:s.agent_id,channel:s.channel??null,chatId:s.chat_id??null,workflowRunId:s.workflow_run_id??null,startedAt:s.started_at,originalMessage:s.original_message??null,resumeOrigin:s.resume_origin??null,resumeAttempt:s.resume_attempt??0,toolCalls:r.all(s.task_id).map(a=>({action:a.action??null,inputSummary:a.input_summary??null}))}))}function S(e,n){return(e.prepare(`
53
54
  UPDATE task_traces SET resume_decision = 'deciding'
54
55
  WHERE task_id = ? AND resume_decision = 'interrupted'
55
- `).run(n).changes??0)===1}function y(e,n,t,r){e.prepare("UPDATE task_traces SET resume_decision = ?, resume_reason = ? WHERE task_id = ?").run(t,r.slice(0,500),n)}function D(e,n={}){let t=[],r=[];n.agentId&&(t.push("agent_id = ?"),r.push(n.agentId)),n.channel&&(t.push("channel = ?"),r.push(n.channel)),n.chatId&&(t.push("chat_id = ?"),r.push(n.chatId)),n.workflowRunId&&(t.push("workflow_run_id = ?"),r.push(n.workflowRunId)),n.status&&(t.push("status = ?"),r.push(n.status)),n.since!==void 0&&(t.push("started_at >= ?"),r.push(n.since)),n.until!==void 0&&(t.push("started_at <= ?"),r.push(n.until));let s=Math.max(1,Math.min(n.limit??100,1e3)),a=`
56
+ `).run(n).changes??0)===1}function D(e,n,t,r){e.prepare("UPDATE task_traces SET resume_decision = ?, resume_reason = ? WHERE task_id = ?").run(t,r.slice(0,500),n)}function w(e,n={}){let t=[],r=[];n.agentId&&(t.push("agent_id = ?"),r.push(n.agentId)),n.channel&&(t.push("channel = ?"),r.push(n.channel)),n.chatId&&(t.push("chat_id = ?"),r.push(n.chatId)),n.workflowRunId&&(t.push("workflow_run_id = ?"),r.push(n.workflowRunId)),n.status&&(t.push("status = ?"),r.push(n.status)),n.since!==void 0&&(t.push("started_at >= ?"),r.push(n.since)),n.until!==void 0&&(t.push("started_at <= ?"),r.push(n.until));let s=Math.max(1,Math.min(n.limit??100,1e3)),a=`
56
57
  SELECT * FROM task_traces
57
58
  ${t.length>0?"WHERE "+t.join(" AND "):""}
58
59
  ORDER BY started_at DESC
59
60
  LIMIT ?
60
- `;return r.push(s),e.prepare(a).all(...r).map(d)}function A(e,n,t=200){return e.prepare(`
61
+ `;return r.push(s),e.prepare(a).all(...r).map(l)}function y(e,n){let t=[];for(let r=0;r<n.length;r+=500){let s=n.slice(r,r+500);if(!s.length)continue;let a=e.prepare(`
62
+ SELECT * FROM task_traces WHERE workflow_run_id IN (${s.map(()=>"?").join(",")})
63
+ ORDER BY started_at
64
+ `).all(...s);t.push(...a.map(l))}return t}function A(e,n,t=200){return e.prepare(`
61
65
  SELECT action, input_summary FROM task_trace_steps
62
66
  WHERE task_id = ? AND name = 'tool_use' ORDER BY seq LIMIT ?
63
- `).all(n,t).map(s=>({action:s.action??null,inputSummary:s.input_summary??null}))}export{p as a,h as b,T as c,E as d,g as e,b as f,R as g,C as h,S as i,y as j,D as k,A as l};
64
- //# sourceMappingURL=chunk-QSKG754X.js.map
67
+ `).all(n,t).map(s=>({action:s.action??null,inputSummary:s.input_summary??null}))}export{p as a,h as b,E as c,T as d,g as e,R as f,b as g,C as h,S as i,D as j,w as k,y as l,A as m};
68
+ //# sourceMappingURL=chunk-5TTHN7DP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/storage/traces.ts","../src/agents/injected-context.ts"],"sourcesContent":["import type Database from \"better-sqlite3\"\nimport { newEventId } from \"@/intent/ulid\"\nimport { boundInjectedContext } from \"@/agents/injected-context\"\n\n// --- Task trace store ---\n//\n// Improvement plan #2 — per-task observability backed by SQLite. One\n// task_traces row per executeTask invocation, an append-only stream of\n// task_trace_steps inside it. The store is intentionally dumb: it stores\n// what callers give it. Callers (capture sites in src/agents/runtime.ts)\n// are responsible for byte-capping large step payloads so the daemon\n// memory stays bounded under tool-heavy turns.\n//\n// Why a separate store layer (vs writing inline in runtime.ts)?\n// - Tests can exercise the trace lifecycle against a temp SQLite without\n// spinning up the agent runtime.\n// - The HTTP endpoints (GET /task/:id/trace) read through the same\n// functions producers write through, so there's a single source of\n// truth on field names + semantics.\n// - Future capture sites (sdk tier, orchestrator tier) reuse this API\n// without copying SQL.\n//\n// Why ULID for task_id?\n// - URL-safe in HTTP routes (GET /task/:id/trace).\n// - Time-sortable, so listTraces ORDER BY started_at and ORDER BY\n// task_id agree without an explicit timestamp column index.\n// - Already in-tree (src/intent/ulid.ts); no new dep.\n//\n// Cross-DB FK note:\n// intent_event_id and intent_decided_by are logical foreign keys into\n// the intent ledger at .agentx/intent/ledger.sqlite. better-sqlite3\n// doesn't enforce cross-database FKs and we don't ATTACH the ledger\n// here on purpose — the rescue plan's append-only contract on the\n// ledger is honoured by routing all writes through src/intent/ledger.ts.\n// Joins happen at the HTTP / CLI layer when needed.\n\nexport interface TraceStartInput {\n agentId: string\n channel?: string | null\n chatId?: string | null\n messagePreview?: string | null\n /** Full untruncated user message — used by `agentx trace replay <taskId>`\n * to re-fire a recorded task against the current agent config. NULL on\n * rows from before migration v8, in which case replay falls back to\n * messagePreview (which is capped at 200 chars). */\n originalMessage?: string | null\n workflowRunId?: string | null\n workflowId?: string | null\n workflowNodeId?: string | null\n intentEventId?: string | null\n intentDecidedBy?: string | null\n resumeSessionId?: string | null\n model?: string | null\n /** How to re-enter this run after a restart (JSON, see agents/resume). */\n resumeOrigin?: string | null\n /** 0 for a fresh run; n for the n-th resume of a cut-off run. */\n resumeAttempt?: number | null\n /** The cut-off run this one continues. */\n resumedFrom?: string | null\n /** The known person who started the chain (people, #384). */\n person?: string | null\n}\n\nexport interface TraceEndInput {\n status: \"ok\" | \"error\" | \"timeout\" | \"stopped\"\n finalSessionId?: string | null\n inputTokens?: number | null\n outputTokens?: number | null\n cacheReadTokens?: number | null\n cacheCreateTokens?: number | null\n tier2InputTokens?: number | null\n tier2OutputTokens?: number | null\n tier2CacheReadTokens?: number | null\n tier2CacheCreateTokens?: number | null\n /** Whether the turn continued a provider session. The resume decision\n * is made after task:started, so it is recorded at the end. Omitted\n * leaves both resumed and resume_session_id untouched. */\n resumed?: boolean | null\n resumeSessionId?: string | null\n /** Request-gate experiment arm: \"treatment\" | \"holdout\". */\n jevArm?: string | null\n /** Runtime-reported turn count (Claude `num_turns`). */\n numTurns?: number | null\n /** Lessons injected into the prompt. See InjectedContext. */\n injectedContext?: InjectedContext | null\n error?: string | null\n /** The agent's final reply text. Stored verbatim so `replay --diff`\n * can compare original output vs the new run's output without\n * reconstructing it from the step ledger. NULL when the response\n * wasn't captured (older rows or non-text outputs). */\n finalResponse?: string | null\n /** Model the turn was billed on. Known only once the turn ends, so the\n * start row usually has none. Omitted leaves the column untouched. */\n model?: string | null\n}\n\n/** Ids of the lessons injected into one task's prompt. Memory facts and\n * procedures are matched per message, so their ids are recorded; the wiki\n * is injected as a whole catalog, so only its presence is. */\nexport interface InjectedContext {\n memory: string[]\n procedures: string[]\n wiki: boolean\n}\n\nexport interface TraceStepInput {\n /** Coarse step kind. Conventional values: \"tool_use\" | \"tool_result\" |\n * \"llm_message\" | \"session_rotation\" | \"error\" | \"preflight\". Free-form\n * strings allowed so future capture sites don't need a schema bump. */\n name: string\n /** Fine-grained name within the kind. For \"tool_use\", this is the tool\n * name (e.g. \"Bash\", \"Edit\"). Optional. */\n action?: string | null\n status?: \"ok\" | \"error\" | \"in-flight\" | null\n /** JSON-stringified input or human-readable summary. Caller-byte-capped. */\n inputSummary?: string | null\n outputSummary?: string | null\n error?: string | null\n /** Step duration when known. Optional — many step kinds are point-in-time. */\n ms?: number | null\n}\n\nexport interface TraceRecord {\n taskId: string\n agentId: string\n channel: string | null\n chatId: string | null\n workflowRunId: string | null\n workflowId: string | null\n workflowNodeId: string | null\n intentEventId: string | null\n intentDecidedBy: string | null\n resumeSessionId: string | null\n finalSessionId: string | null\n model: string | null\n status: string\n startedAt: number\n finishedAt: number | null\n durationMs: number | null\n inputTokens: number | null\n outputTokens: number | null\n cacheReadTokens: number | null\n cacheCreateTokens: number | null\n tier2InputTokens: number | null\n tier2OutputTokens: number | null\n tier2CacheReadTokens: number | null\n tier2CacheCreateTokens: number | null\n /** NULL on rows recorded before migration v12. */\n resumed: boolean | null\n /** NULL when the request gate was not active (or before migration v13). */\n jevArm: string | null\n /** NULL on rows recorded before lesson-impact capture (#98) or when the\n * runtime does not report a turn count. */\n numTurns: number | null\n /** NULL on rows recorded before lesson-impact capture (#98). */\n injectedContext: InjectedContext | null\n error: string | null\n messagePreview: string | null\n /** Full untruncated user message — populated for traces from migration v8\n * onward. NULL on older rows; consumers should fall back to messagePreview. */\n originalMessage: string | null\n /** Agent's final reply text — populated for traces from migration v8\n * onward when the executor records it on end. */\n finalResponse: string | null\n}\n\nexport interface TraceStepRecord {\n taskId: string\n seq: number\n name: string\n action: string | null\n status: string | null\n inputSummary: string | null\n outputSummary: string | null\n error: string | null\n ms: number | null\n startedAt: number\n}\n\nexport interface ListTracesFilters {\n agentId?: string\n channel?: string\n chatId?: string\n workflowRunId?: string\n status?: string\n /** ms epoch */\n since?: number\n /** ms epoch */\n until?: number\n /** Default 100, capped at 1000. */\n limit?: number\n}\n\n/**\n * Insert an in-flight trace row and return its ULID. Callers thread the\n * returned id through the executor and call recordTraceEnd at finish time.\n *\n * `taskId` is optional — when supplied, the caller has already allocated\n * a ULID upstream (e.g. registry.execute generating it before the bus\n * event so the runtime can capture per-step rows under the same id).\n * When omitted, a fresh ULID is allocated here.\n */\nexport function recordTraceStart(\n db: Database.Database,\n input: TraceStartInput,\n taskId: string = newEventId(),\n): string {\n db.prepare(`\n INSERT INTO task_traces (\n task_id, agent_id, channel, chat_id, workflow_run_id, workflow_id,\n workflow_node_id, intent_event_id, intent_decided_by, resume_session_id,\n model, status, started_at, message_preview, original_message,\n resume_origin, resume_attempt, resumed_from, person\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'in-flight', ?, ?, ?, ?, ?, ?, ?)\n `).run(\n taskId,\n input.agentId,\n input.channel ?? null,\n input.chatId ?? null,\n input.workflowRunId ?? null,\n input.workflowId ?? null,\n input.workflowNodeId ?? null,\n input.intentEventId ?? null,\n input.intentDecidedBy ?? null,\n input.resumeSessionId ?? null,\n input.model ?? null,\n Date.now(),\n input.messagePreview ?? null,\n input.originalMessage ?? null,\n input.resumeOrigin ?? null,\n input.resumeAttempt ?? 0,\n input.resumedFrom ?? null,\n input.person ?? null,\n )\n return taskId\n}\n\n/**\n * Finalize a trace. duration_ms is computed from finished_at - started_at\n * inside the UPDATE so the two columns can never disagree. Idempotent —\n * calling twice on the same task_id overwrites the prior end values; the\n * second call's status wins. (Soft-overwrite is intentional: timeout\n * handlers may write before a late stream-completion arrives.)\n */\nexport function recordTraceEnd(db: Database.Database, taskId: string, input: TraceEndInput): void {\n const finishedAt = Date.now()\n db.prepare(`\n UPDATE task_traces SET\n status = ?,\n final_session_id = ?,\n input_tokens = ?,\n output_tokens = ?,\n cache_read_tokens = ?,\n cache_create_tokens = ?,\n tier2_input_tokens = ?,\n tier2_output_tokens = ?,\n tier2_cache_read_tokens = ?,\n tier2_cache_create_tokens = ?,\n resumed = COALESCE(?, resumed),\n resume_session_id = COALESCE(?, resume_session_id),\n jev_arm = COALESCE(?, jev_arm),\n num_turns = COALESCE(?, num_turns),\n injected_context = COALESCE(?, injected_context),\n error = ?,\n final_response = COALESCE(?, final_response),\n model = COALESCE(?, model),\n finished_at = ?,\n duration_ms = ? - started_at\n WHERE task_id = ?\n `).run(\n input.status,\n input.finalSessionId ?? null,\n input.inputTokens ?? null,\n input.outputTokens ?? null,\n input.cacheReadTokens ?? null,\n input.cacheCreateTokens ?? null,\n input.tier2InputTokens ?? null,\n input.tier2OutputTokens ?? null,\n input.tier2CacheReadTokens ?? null,\n input.tier2CacheCreateTokens ?? null,\n input.resumed == null ? null : input.resumed ? 1 : 0,\n input.resumeSessionId ?? null,\n input.jevArm ?? null,\n input.numTurns ?? null,\n input.injectedContext ? JSON.stringify(boundInjectedContext(input.injectedContext)) : null,\n input.error ?? null,\n input.finalResponse ?? null,\n input.model ?? null,\n finishedAt,\n finishedAt,\n taskId,\n )\n}\n\n/**\n * Append a step. seq is auto-allocated as MAX(seq)+1 within a transaction\n * so concurrent step writes for the same task_id can't collide. Returns\n * the assigned seq, useful for downstream correlation.\n */\nexport function recordTraceStep(db: Database.Database, taskId: string, input: TraceStepInput): number {\n const startedAt = Date.now()\n const allocateAndInsert = db.transaction((): number => {\n const row = db\n .prepare(\"SELECT MAX(seq) AS max_seq FROM task_trace_steps WHERE task_id = ?\")\n .get(taskId) as { max_seq: number | null } | undefined\n const seq = ((row?.max_seq ?? -1) as number) + 1\n db.prepare(`\n INSERT INTO task_trace_steps (\n task_id, seq, name, action, status, input_summary, output_summary, error, ms, started_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n taskId,\n seq,\n input.name,\n input.action ?? null,\n input.status ?? null,\n input.inputSummary ?? null,\n input.outputSummary ?? null,\n input.error ?? null,\n input.ms ?? null,\n startedAt,\n )\n return seq\n })\n return allocateAndInsert()\n}\n\nexport function parseInjectedContext(raw: unknown): InjectedContext | null {\n if (typeof raw !== \"string\") return null\n try {\n const v = JSON.parse(raw)\n if (!v || typeof v !== \"object\") return null\n const ids = (x: unknown) => (Array.isArray(x) ? x.filter((i): i is string => typeof i === \"string\") : [])\n return { memory: ids(v.memory), procedures: ids(v.procedures), wiki: v.wiki === true }\n } catch {\n return null\n }\n}\n\nfunction rowToTrace(row: Record<string, unknown>): TraceRecord {\n return {\n taskId: row.task_id as string,\n agentId: row.agent_id as string,\n channel: (row.channel as string) ?? null,\n chatId: (row.chat_id as string) ?? null,\n workflowRunId: (row.workflow_run_id as string) ?? null,\n workflowId: (row.workflow_id as string) ?? null,\n workflowNodeId: (row.workflow_node_id as string) ?? null,\n intentEventId: (row.intent_event_id as string) ?? null,\n intentDecidedBy: (row.intent_decided_by as string) ?? null,\n resumeSessionId: (row.resume_session_id as string) ?? null,\n finalSessionId: (row.final_session_id as string) ?? null,\n model: (row.model as string) ?? null,\n status: row.status as string,\n startedAt: row.started_at as number,\n finishedAt: (row.finished_at as number) ?? null,\n durationMs: (row.duration_ms as number) ?? null,\n inputTokens: (row.input_tokens as number) ?? null,\n outputTokens: (row.output_tokens as number) ?? null,\n cacheReadTokens: (row.cache_read_tokens as number) ?? null,\n cacheCreateTokens: (row.cache_create_tokens as number) ?? null,\n tier2InputTokens: (row.tier2_input_tokens as number) ?? null,\n tier2OutputTokens: (row.tier2_output_tokens as number) ?? null,\n tier2CacheReadTokens: (row.tier2_cache_read_tokens as number) ?? null,\n tier2CacheCreateTokens: (row.tier2_cache_create_tokens as number) ?? null,\n resumed: row.resumed == null ? null : row.resumed === 1,\n jevArm: (row.jev_arm as string) ?? null,\n numTurns: (row.num_turns as number) ?? null,\n injectedContext: parseInjectedContext(row.injected_context),\n error: (row.error as string) ?? null,\n messagePreview: (row.message_preview as string) ?? null,\n originalMessage: (row.original_message as string) ?? null,\n finalResponse: (row.final_response as string) ?? null,\n }\n}\n\nfunction rowToStep(row: Record<string, unknown>): TraceStepRecord {\n return {\n taskId: row.task_id as string,\n seq: row.seq as number,\n name: row.name as string,\n action: (row.action as string) ?? null,\n status: (row.status as string) ?? null,\n inputSummary: (row.input_summary as string) ?? null,\n outputSummary: (row.output_summary as string) ?? null,\n error: (row.error as string) ?? null,\n ms: (row.ms as number) ?? null,\n startedAt: row.started_at as number,\n }\n}\n\n/** Fetch a trace + its ordered steps. Returns null if no such task_id. */\nexport function getTrace(\n db: Database.Database,\n taskId: string,\n): { task: TraceRecord; steps: TraceStepRecord[] } | null {\n const row = db.prepare(\"SELECT * FROM task_traces WHERE task_id = ?\").get(taskId) as\n | Record<string, unknown>\n | undefined\n if (!row) return null\n const stepRows = db\n .prepare(\"SELECT * FROM task_trace_steps WHERE task_id = ? ORDER BY seq\")\n .all(taskId) as Record<string, unknown>[]\n return { task: rowToTrace(row), steps: stepRows.map(rowToStep) }\n}\n\n/**\n * Cancel any in-flight trace rows left over from a previous daemon\n * lifetime. Mirrors the intent ledger's startup cleanup (rescue plan\n * Phase 1 commit a8514d9): a hard-killed daemon never gets to fire\n * task:completed, so the row sits \"in-flight\" forever and contaminates\n * triage queries (`agentx trace list --status in-flight`) with stale\n * orphans. Run once at daemon boot before subscribers attach.\n *\n * Returns the number of rows updated. duration_ms is intentionally NOT\n * computed — we don't know when the task actually ended; preserving\n * NULL there is more honest than backdating to \"now\".\n */\nexport function cleanupOrphanedTraces(db: Database.Database): number {\n const now = Date.now()\n const r = db.prepare(`\n UPDATE task_traces\n SET status = 'canceled',\n error = 'daemon-restart (orphaned in-flight)',\n finished_at = ?\n WHERE status = 'in-flight'\n `).run(now)\n return (r.changes ?? 0) as number\n}\n\n// --- Resume after restart (#103) -------------------------------------------\n\n/** A run that was still going when the previous daemon stopped. */\nexport interface InterruptedRun {\n taskId: string\n agentId: string\n channel: string | null\n chatId: string | null\n workflowRunId: string | null\n startedAt: number\n originalMessage: string | null\n resumeOrigin: string | null\n resumeAttempt: number\n /** Tool calls it had made, in order, for the resume note. */\n toolCalls: Array<{ action: string | null; inputSummary: string | null }>\n}\n\n/** Close every run left in flight by the previous daemon, marking it\n * `interrupted` for the resume planner, and return them. One transaction,\n * so a second process booting on the same database gets nothing. */\nexport function takeInterruptedRuns(db: Database.Database, now = Date.now()): InterruptedRun[] {\n const take = db.transaction(() => {\n const rows = db.prepare(`\n SELECT task_id, agent_id, channel, chat_id, workflow_run_id, started_at,\n original_message, resume_origin, resume_attempt\n FROM task_traces WHERE status = 'in-flight' ORDER BY started_at\n `).all() as Array<Record<string, any>>\n db.prepare(`\n UPDATE task_traces\n SET status = 'canceled', error = 'daemon-restart (interrupted)',\n finished_at = ?, resume_decision = 'interrupted'\n WHERE status = 'in-flight'\n `).run(now)\n return rows\n })\n const steps = db.prepare(`\n SELECT action, input_summary FROM task_trace_steps\n WHERE task_id = ? AND name = 'tool_use' ORDER BY seq\n `)\n return take().map((r) => ({\n taskId: r.task_id,\n agentId: r.agent_id,\n channel: r.channel ?? null,\n chatId: r.chat_id ?? null,\n workflowRunId: r.workflow_run_id ?? null,\n startedAt: r.started_at,\n originalMessage: r.original_message ?? null,\n resumeOrigin: r.resume_origin ?? null,\n resumeAttempt: r.resume_attempt ?? 0,\n toolCalls: (steps.all(r.task_id) as Array<Record<string, any>>).map((s) => ({\n action: s.action ?? null, inputSummary: s.input_summary ?? null,\n })),\n }))\n}\n\n/** Claim an interrupted run before deciding what to do with it. Returns\n * false when another process already claimed or decided it, so a run is\n * never resumed — or its chat told — twice. */\nexport function claimResume(db: Database.Database, taskId: string): boolean {\n const r = db.prepare(`\n UPDATE task_traces SET resume_decision = 'deciding'\n WHERE task_id = ? AND resume_decision = 'interrupted'\n `).run(taskId)\n return (r.changes ?? 0) === 1\n}\n\nexport type ResumeDecision = \"resumed\" | \"reported\" | \"skipped\" | \"resume-failed\"\n\nexport function recordResumeDecision(\n db: Database.Database, taskId: string, decision: ResumeDecision, reason: string,\n): void {\n db.prepare(\"UPDATE task_traces SET resume_decision = ?, resume_reason = ? WHERE task_id = ?\")\n .run(decision, reason.slice(0, 500), taskId)\n}\n\n/** Triage / dashboard surface — list traces newest-first, filtered. */\nexport function listTraces(db: Database.Database, filters: ListTracesFilters = {}): TraceRecord[] {\n const where: string[] = []\n const params: unknown[] = []\n if (filters.agentId) { where.push(\"agent_id = ?\"); params.push(filters.agentId) }\n if (filters.channel) { where.push(\"channel = ?\"); params.push(filters.channel) }\n if (filters.chatId) { where.push(\"chat_id = ?\"); params.push(filters.chatId) }\n if (filters.workflowRunId) { where.push(\"workflow_run_id = ?\"); params.push(filters.workflowRunId) }\n if (filters.status) { where.push(\"status = ?\"); params.push(filters.status) }\n if (filters.since !== undefined) { where.push(\"started_at >= ?\"); params.push(filters.since) }\n if (filters.until !== undefined) { where.push(\"started_at <= ?\"); params.push(filters.until) }\n\n const limit = Math.max(1, Math.min(filters.limit ?? 100, 1000))\n const sql = `\n SELECT * FROM task_traces\n ${where.length > 0 ? \"WHERE \" + where.join(\" AND \") : \"\"}\n ORDER BY started_at DESC\n LIMIT ?\n `\n params.push(limit)\n return (db.prepare(sql).all(...params) as Record<string, unknown>[]).map(rowToTrace)\n}\n\n/** Every trace row of these workflow runs, oldest first. Unbounded by\n * design: a report over a few hundred runs needs all of their rows. */\nexport function listTracesForRuns(db: Database.Database, runIds: string[]): TraceRecord[] {\n const out: TraceRecord[] = []\n // SQLite caps bound parameters; stay well under it.\n for (let i = 0; i < runIds.length; i += 500) {\n const chunk = runIds.slice(i, i + 500)\n if (!chunk.length) continue\n const rows = db.prepare(`\n SELECT * FROM task_traces WHERE workflow_run_id IN (${chunk.map(() => \"?\").join(\",\")})\n ORDER BY started_at\n `).all(...chunk) as Record<string, unknown>[]\n out.push(...rows.map(rowToTrace))\n }\n return out\n}\n\n/** The tool calls one run made, in order: what a stop signal's resume plan\n * lists when the agent wrote none (#857). Bounded. */\nexport function traceToolCalls(\n db: Database.Database, taskId: string, limit = 200,\n): Array<{ action: string | null; inputSummary: string | null }> {\n const rows = db.prepare(`\n SELECT action, input_summary FROM task_trace_steps\n WHERE task_id = ? AND name = 'tool_use' ORDER BY seq LIMIT ?\n `).all(taskId, limit) as Array<Record<string, any>>\n return rows.map((s) => ({ action: s.action ?? null, inputSummary: s.input_summary ?? null }))\n}\n","import type { InjectedContext } from \"@/storage/traces\"\n\n// --- Injected lessons per task (#98) ---\n//\n// Which memory facts, procedures and wiki catalog actually reached the\n// prompt. Candidates are not enough: the request-context selector can drop\n// a whole layer, and the layer budgets in buildAgentContext can cut a layer\n// short. So a lesson counts as injected only when its text is in the\n// assembled context. Only ids are recorded, never content, and the lists\n// are capped, so the trace row stays small.\n\nexport const MAX_INJECTED_IDS = 20\nconst MAX_ID_LENGTH = 80\n\nexport interface InjectionCandidates {\n memory?: Array<{ id: string; content: string }>\n procedures?: Array<{ id: string; title: string }>\n /** The wiki catalog block offered to the prompt, if any. */\n wikiContext?: string\n}\n\n/** The first line of the wiki catalog block; see buildWikiContext. */\nconst WIKI_MARKER = \"[Institutional Wiki\"\n\nfunction capIds(ids: string[]): string[] {\n return [...new Set(ids)].slice(0, MAX_INJECTED_IDS).map((id) => id.slice(0, MAX_ID_LENGTH))\n}\n\nexport function injectedContextOf(assembled: string, candidates: InjectionCandidates): InjectedContext {\n const text = assembled ?? \"\"\n return {\n memory: capIds((candidates.memory ?? []).filter((m) => m.content && text.includes(m.content)).map((m) => m.id)),\n procedures: capIds(\n (candidates.procedures ?? []).filter((p) => text.includes(`[Known procedure: ${p.title}]`)).map((p) => p.id),\n ),\n wiki: Boolean(candidates.wikiContext) && text.includes(WIKI_MARKER),\n }\n}\n\n/** Clamp an InjectedContext from any source to the recorded bounds. */\nexport function boundInjectedContext(ctx: InjectedContext): InjectedContext {\n return { memory: capIds(ctx.memory), procedures: capIds(ctx.procedures), wiki: ctx.wiki === true }\n}\n"],"mappings":"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","names":["init_ulid","WIKI_MARKER","capIds","ids","id","injectedContextOf","assembled","candidates","text","m","p","boundInjectedContext","ctx","recordTraceStart","db","input","taskId","newEventId","recordTraceEnd","finishedAt","boundInjectedContext","recordTraceStep","startedAt","seq","parseInjectedContext","raw","v","ids","x","i","rowToTrace","row","rowToStep","getTrace","stepRows","cleanupOrphanedTraces","now","takeInterruptedRuns","take","rows","steps","r","s","claimResume","recordResumeDecision","decision","reason","listTraces","filters","where","params","limit","sql","listTracesForRuns","runIds","out","chunk","traceToolCalls"]}
@@ -1,4 +1,4 @@
1
- import{a as Re,b as w,c as z,d as Pe,e as ie,f as se,g as M,h as le,i as N,j as O,n as De,o as ze,p as _e,q as We}from"./chunk-XVTD6I34.js";import{e as Ee,i as Te}from"./chunk-QAWKN2N4.js";import{b as oe}from"./chunk-MTX4UPNB.js";import{c as Ie,d as ae,e as T,f as re,g as B}from"./chunk-B2QYMUTD.js";import{a as G,b as Ce}from"./chunk-IFUN332M.js";import{a as Se}from"./chunk-7LN4VKDU.js";import{a as Ae}from"./chunk-IMLAPB7G.js";import{b as $e}from"./chunk-MRIVENBY.js";import{i as ne,k as ke}from"./chunk-AKWBDCMU.js";import{b as xe}from"./chunk-YMX3QCV7.js";import{c as ye,e as we}from"./chunk-LQE73AZR.js";import{G as K}from"./chunk-3NKCOZQO.js";import{a as L,b as F}from"./chunk-7Y3FEIX7.js";import{a as ve}from"./chunk-7H7LUBPC.js";import{a as be}from"./chunk-ROLSSYXE.js";import{A as me,Ea as te,G as dt,X as fe,ca as ct,ta as ee,va as H,wa as he,z as Z}from"./chunk-JYPXNH4C.js";import{existsSync as j,readFileSync as Oe,writeFileSync as Ue,appendFileSync as ut,mkdirSync as mt}from"fs";import{dirname as ft,resolve as _}from"path";import{fileURLToPath as ht}from"url";import{hostname as bt}from"os";import{spawn as vt}from"child_process";function Me(e,t){let n=e.configExists?e.agentCount===0?"Add your first agent":"Add another agent":"Set up your team",a=`<header class="ax-topbar">
1
+ import{a as Re,b as w,c as z,d as Pe,e as ie,f as se,g as M,h as le,i as N,j as O,n as De,o as ze,p as _e,q as We}from"./chunk-XVTD6I34.js";import{e as Ee,i as Te}from"./chunk-QAWKN2N4.js";import{b as oe}from"./chunk-MTX4UPNB.js";import{a as G,b as Ce}from"./chunk-CZWEXRIE.js";import{c as Ie,d as ae,e as T,f as re,g as B}from"./chunk-B2QYMUTD.js";import{a as Se}from"./chunk-7LN4VKDU.js";import{a as Ae}from"./chunk-IMLAPB7G.js";import{b as $e}from"./chunk-MRIVENBY.js";import{l as ne,n as ke}from"./chunk-KV4ZA7FS.js";import{b as xe}from"./chunk-YMX3QCV7.js";import{c as ye,e as we}from"./chunk-LQE73AZR.js";import{G as K}from"./chunk-45TKVOJX.js";import{a as L,b as F}from"./chunk-SFUNL7RV.js";import{a as ve}from"./chunk-Q73QQPDB.js";import{a as be}from"./chunk-ROLSSYXE.js";import{Ha as ee,Ja as H,Ka as he,L as Z,M as me,Sa as te,T as dt,ia as fe,pa as ct}from"./chunk-DPIQCHXB.js";import{existsSync as j,readFileSync as Oe,writeFileSync as Ue,appendFileSync as ut,mkdirSync as mt}from"fs";import{dirname as ft,resolve as _}from"path";import{fileURLToPath as ht}from"url";import{hostname as bt}from"os";import{spawn as vt}from"child_process";function Me(e,t){let n=e.configExists?e.agentCount===0?"Add your first agent":"Add another agent":"Set up your team",a=`<header class="ax-topbar">
2
2
  <div class="ax-topbar__left">
3
3
  <div class="ax-brand">
4
4
  <span class="ax-brand__mark">AX</span>
@@ -858,4 +858,4 @@ tr:hover td { background: var(--bg-hover); }
858
858
  WHERE person = ? AND state IN (${n.map(()=>"?").join(",")})
859
859
  ${a}`).all(t,...n,...o).map(i=>({id:i.id,state:i.state,channel:i.channel,agentId:i.agent_id,text:i.text,createdAt:i.created_at})):[]}function ga(e,t){return et(e,t,Z,"ORDER BY created_at")}function ua(e,t,n=50){return et(e,t,[...Z,...me],"ORDER BY created_at DESC, rowid DESC LIMIT ?",Math.max(1,Math.min(n,500)))}ct();var ue="member:",Yt=90,Vt="members",Xt="tailscale-user-login",Qt=400,Zt=60*60*1e3;function en(e){let t=e.scopes.find(n=>n.startsWith(ue));return t?t.slice(ue.length):null}function nt(e,t){if(!e)return null;let n=t.verify(e),a=n?en(n):null;return n&&a?{rec:n,personId:a}:null}function ya(e,t){let n=e.people().find(s=>s.id===t);if(!n)return{ok:!1,error:`No person "${t}". Add them first: agentx people add ${t} --name "\u2026"`};let{token:a,record:o}=e.tokens.create({name:`${n.name} (machine not paired yet)`,scopes:[`${ue}${n.id}`],expiresInDays:Yt}),{code:r,expiresAt:i}=e.codes.create({token:a,tokenId:o.id,name:n.id});return e.members.log({person:n.id,device:o.id,event:"invited"}),{ok:!0,code:r,expiresAt:i,tokenId:o.id,person:n}}var tn=Math.round(ye/6e4);function nn(e){return e==="client"?"Your project":"My work"}function wa(e){let t=nn(e.person.role),n=e.person.role==="client"?`I use AgentX to keep track of the work I do for you. It has a page for you, "${t}": what you asked us for, and where each request stands.`:`I use AgentX to give our AI agents their jobs. It has a page for you, "${t}": what you asked the agents for, and where each request stands.`;return[`Hi ${e.person.name},`,"",n,"","To open it:","1. Accept the Tailscale share I sent you. Tailscale is a small program that connects your computer to mine, privately.",`2. Open ${e.origin.replace(/\/+$/,"")}/member in Edge or Chrome, give your computer a name and type this code: ${we(e.code)}`,` The code works once, for ${tn} minutes. If it has stopped working, tell me and I will send you a new one.`,"","I then approve your machine, and the page opens by itself."].join(`
860
860
  `)}var an="The private network says someone else is connecting from this machine. Ask the person who invited you for a new code.",rn="Too many machines are waiting for the owner's answer. Try again later.",tt="That code didn't work. Check it, or ask the person who invited you for a new one.",at=(e,t)=>{let n=e.headers[t];return(Array.isArray(n)?n[0]:n||"").trim()};function rt(e){let t=e.socket?.remoteAddress||"";return t==="127.0.0.1"||t==="::1"||t==="::ffff:127.0.0.1"}function on(e){if(!rt(e))return null;let t=at(e,Xt).toLowerCase();return t?t.slice(0,80):null}function sn(e){let t=e.socket?.remoteAddress||"unknown";if(!rt(e))return t;let n=at(e,"x-forwarded-for").split(",").pop().trim();return/^[0-9a-fA-F:.]{2,45}$/.test(n)?n:t}function ln(e){return typeof e=="string"?e.replace(/[^\p{L}\p{N} ._'()-]/gu," ").replace(/\s+/g," ").trim().slice(0,60):""}function dn(e){return e.identities.map(fe).filter(t=>!!t&&t.channel==="tailscale").map(t=>t.value)}async function ka(e,t){let n=Date.now(),a=t.now??Date.now,o=t.log??(b=>console.log(b)),r=sn(e),i=t.limiter.retryAfter(r);if(i>0)return o(`[member] pair-code refused from ${r}: locked out for ${i}s more`),{status:429,body:{error:"too many attempts",retryAfter:i},retryAfter:i};let s=null,l="";try{let b=await xe(e,2048);s=b.code,l=ln(b.machine)}catch{}let c=t.codes.redeem(s),d=c?nt(c.token,t.tokens):null;if(await pn(n,t.minMs??Qt),!c||!d)return t.limiter.fail(r),o(`[member] pair-code failed from ${r}`),{status:401,body:{error:tt}};t.limiter.succeed(r);let{rec:m,personId:p}=d,k=t.people().find(b=>b.id===p);if(!k)return t.tokens.revoke(m.id),t.members.log({person:p,device:m.id,event:"refused",address:r,detail:"person no longer listed"}),o(`[member] pair-code for ${p} refused from ${r}: person no longer listed`),{status:403,body:{error:tt}};let u=on(e),f=dn(k);if(f.length&&(!u||!f.includes(u)))return t.tokens.revoke(m.id),t.members.log({person:p,device:m.id,event:"refused",address:r,detail:`network login ${u??"missing"}; expected ${f.join(" or ")}`}),o(`[member] ${p}: pairing from ${r} refused: the network says "${u??"nobody"}", expected ${f.join(" or ")}`),{status:403,body:{error:an}};let I=l||"Unnamed machine",x=k.name.slice(0,40),v=ke(t.root,{title:`New machine for ${x}`,ask:`From ${r}, ${u?`network login ${u}`:"no network login reported"}. Machine name, as typed there: "${I}". Let it see ${x}'s own work?`,recommend:`Yes if ${x} told you they just paired this machine. No if you did not expect it.`,if_silent:"discard",raised_by:Vt},{now:a()});return v.ok?(t.members.add({tokenId:m.id,personId:p,name:I,state:"pending",cardId:v.card.id,address:r,...u?{network:u}:{},createdAt:new Date(a()).toISOString()}),t.members.log({person:p,device:m.id,event:"paired",address:r,detail:I}),o(`[member] ${p} paired "${I}" from ${r}; waiting for the owner (card ${v.card.id})`),{status:200,body:{person:p,name:I,state:"pending"},token:c.token}):(t.tokens.revoke(m.id),t.members.log({person:p,device:m.id,event:"refused",address:r,detail:v.error}),o(`[member] ${p}: pairing from ${r} refused: ${v.error}`),{status:503,body:{error:rn}})}var Q="this machine is not paired",cn="waiting for the owner to approve this machine";function ot(e){return e?e.status==="decided"?e.verdict??null:e.status==="expired"?"no":null:null}function $a(e,t){return t.state==="pending"&&t.cardId?ot(ne(e,t.cardId)):null}function Aa(e,t,n){let a=t.now??Date.now,o=t.log??(d=>console.log(d)),r=nt(e,t.tokens);if(!r)return{ok:!1,status:401,error:Q};let{rec:i,personId:s}=r,l=t.members.byToken(i.id);if(!l||l.state==="removed"||l.personId!==s)return{ok:!1,status:401,error:Q};if(t.people&&!t.people().some(d=>d.id===s))return it(t,i.id,"person no longer listed"),o(`[member] ${s}: "${l.name}" ended: person no longer listed`),{ok:!1,status:401,error:Q};if(l.state==="pending"){let d=l.cardId?ne(t.root,l.cardId):null,m=ot(d);if(m==="yes")l=t.members.update(i.id,{state:"active",approvedAt:new Date(a()).toISOString()})??l,t.members.log({person:s,device:i.id,event:"approved",detail:d?.decided_by}),o(`[member] ${s}: "${l.name}" approved`);else if(m==="no"){let p=d?.status==="expired"?"the owner did not answer in time":"the owner said no";return t.tokens.revoke(i.id),t.members.update(i.id,{state:"removed",removedAt:new Date(a()).toISOString(),removedReason:p}),t.members.log({person:s,device:i.id,event:"refused",detail:p}),o(`[member] ${s}: "${l.name}" refused: ${p}`),{ok:!1,status:401,error:Q}}else return{ok:!1,status:403,error:cn,waiting:!0}}let c=l.lastSeenAt?Date.parse(l.lastSeenAt):0;return n&&(a()-c>=Zt||l.lastAddress!==n)&&(l=t.members.update(i.id,{lastSeenAt:new Date(a()).toISOString(),lastAddress:n})??l,t.members.log({person:s,device:i.id,event:"signed-in",address:n})),{ok:!0,device:l,personId:s,rec:i}}function it(e,t,n="removed by the owner"){let a=e.members.byToken(t);if(!a)return null;e.tokens.revoke(t);let o=e.members.update(t,{state:"removed",removedAt:new Date((e.now??Date.now)()).toISOString(),removedReason:n});return e.members.log({person:a.personId,device:t,event:"removed",detail:n}),o}function Sa(e,t){return e.members.devices(t).filter(n=>n.state!=="removed").map(n=>it(e,n.tokenId,"person removed by the owner")).filter(n=>!!n)}async function pn(e,t){let n=e+t-Date.now();n>0&&await new Promise(a=>setTimeout(a,n))}var st=["gitlab","github"];function gn(e,t,n){let a=String(t||"").trim().toLowerCase();if(!st.includes(a))throw new Error(`Request status works on ${st.join(" and ")}, not on "${t}".`);e.requestStatus=e.requestStatus&&typeof e.requestStatus=="object"?e.requestStatus:{};let o=Array.isArray(e.requestStatus.channels)?e.requestStatus.channels.map(r=>String(r).toLowerCase()):[];return e.requestStatus.channels=n?[...new Set([...o,a])]:o.filter(r=>r!==a),`request status on ${a} is ${n?"on":"off"}`}function Ea(e){return Array.isArray(e?.requestStatus?.channels)?e.requestStatus.channels.map(t=>String(t).toLowerCase()):[]}function Ta(e){let{summary:t}=G(n=>gn(n,e?.channel,!!e?.enabled));return{summary:t}}function Pa(e){return new Set(Object.entries(e).filter(([,t])=>t?.wiki?.absorb?.enabled===!1).map(([t])=>t))}function Da(e,t){return t.only?{agents:[t.only],skipped:[]}:{agents:e.filter(n=>!t.off.has(n)),skipped:e.filter(n=>t.off.has(n))}}function za(e,t){return`absorb is off for this agent (agents.${e}.wiki.absorb.enabled); skipped.${e===t?" It reads the wiki notes inbox, so the inbox was not read.":""} Use --agent ${e} to run it anyway.`}function _a(e,t){if(t){if(!e.wiki?.absorb)return;delete e.wiki.absorb.enabled,Object.keys(e.wiki.absorb).length===0&&delete e.wiki.absorb,Object.keys(e.wiki).length===0&&delete e.wiki;return}e.wiki??={},e.wiki.absorb??={},e.wiki.absorb.enabled=!1}var un="https://ntfy.sh";function Ma(e){return{enabled:!!e?.enabled,server:e?.server||un,topicSet:!!e?.topic,tokenSet:!!e?.token}}function Na(e,t){let n={...e??{}};if("enabled"in t&&(n.enabled=!!t.enabled),"server"in t){let a=String(t.server).trim().replace(/\/+$/,"");if(!/^https?:\/\/\S+$/.test(a))throw new Error("ntfy server must be an http(s) URL");n.server=a}if("topic"in t){let a=String(t.topic).trim();if(!a)throw new Error("ntfy topic cannot be empty");n.topic=a}if("token"in t){let a=String(t.token??"").trim();a?n.token=a:delete n.token}if(n.enabled&&!n.topic)throw new Error("set a topic before enabling ntfy");return n}export{Be as a,An as b,Sn as c,In as d,Pn as e,Dn as f,zn as g,pa as h,ga as i,ua as j,Yt as k,ya as l,tn as m,nn as n,wa as o,sn as p,ka as q,$a as r,Aa as s,it as t,Sa as u,st as v,gn as w,Ea as x,Ta as y,Pa as z,Da as A,za as B,_a as C,Ma as D,Na as E,Ht as F,ta as G,sa as H,la as I};
861
- //# sourceMappingURL=chunk-S6QUFAHD.js.map
861
+ //# sourceMappingURL=chunk-BAO77R4L.js.map