agentix-cli 0.110.0 → 0.111.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/mac-voice/Sources/AgentXVoice/Panel.swift +77 -30
- package/apps/mac-voice/Sources/AgentXVoice/PanelAnswer.swift +3 -2
- package/apps/mac-voice/Sources/AgentXVoice/PillForm.swift +55 -0
- package/apps/mac-voice/Sources/AgentXVoice/PillMenu.swift +8 -7
- package/apps/mac-voice/Sources/AgentXVoice/SettingsLook.swift +2 -2
- package/apps/mac-voice/Sources/AgentXVoice/StatusMenu.swift +5 -6
- package/apps/mac-voice/Sources/AgentXVoice/main.swift +7 -6
- package/dist/{App-4VWAQOVA.js → App-T4Q7SW6M.js} +2 -2
- package/dist/{ChatApp-KOTGUDZH.js → ChatApp-BKUJUIDL.js} +2 -2
- package/dist/{agent-CGRHC2IS.js → agent-YZVEXFE7.js} +2 -2
- package/dist/{board-dashboard-SAYBNLZW.js → board-dashboard-3TVUCOSI.js} +411 -257
- package/dist/board-dashboard-3TVUCOSI.js.map +1 -0
- package/dist/{chunk-UVMCAZL7.js → chunk-4FU4BFCH.js} +2 -2
- package/dist/{chunk-NIW75USA.js → chunk-4NFDDTGA.js} +2 -2
- package/dist/{chunk-2VGYRETU.js → chunk-53OS4TDU.js} +2 -2
- package/dist/{chunk-J32LSOBJ.js → chunk-7UNS34CN.js} +2 -2
- package/dist/chunk-AV7T3SYT.js +111 -0
- package/dist/chunk-AV7T3SYT.js.map +1 -0
- package/dist/chunk-DTQQ4DAY.js +154 -0
- package/dist/chunk-DTQQ4DAY.js.map +1 -0
- package/dist/{chunk-SFPMS55Z.js → chunk-DUBCOGQB.js} +49 -48
- package/dist/chunk-DUBCOGQB.js.map +1 -0
- package/dist/{chunk-BFOB6ERR.js → chunk-DXWDVKMX.js} +2 -2
- package/dist/{chunk-BZKGQMU2.js → chunk-FBODSJU6.js} +2 -2
- package/dist/{chunk-UTV4DRAW.js → chunk-GQMUFSKB.js} +14 -14
- package/dist/{chunk-UTV4DRAW.js.map → chunk-GQMUFSKB.js.map} +1 -1
- package/dist/{chunk-4UCDWEC4.js → chunk-HCTWKWS3.js} +2 -2
- package/dist/{chunk-EC6DKMR5.js → chunk-KDD6FPQ6.js} +238 -238
- package/dist/chunk-KDD6FPQ6.js.map +1 -0
- package/dist/{chunk-5O6PIO7F.js → chunk-LWYKS5JU.js} +2 -2
- package/dist/{chunk-QQAZ6EJP.js → chunk-M2L6S3Z5.js} +2 -2
- package/dist/{chunk-6F2E5NQA.js → chunk-QJP37VVA.js} +2 -2
- package/dist/{chunk-QFP4YZII.js → chunk-RS2T53EC.js} +2 -2
- package/dist/{chunk-E5OV6RTG.js → chunk-RXLU6HJ6.js} +3 -3
- package/dist/chunk-RXLU6HJ6.js.map +1 -0
- package/dist/{chunk-D7M4WQFU.js → chunk-SIOWVLZG.js} +4 -4
- package/dist/chunk-SIOWVLZG.js.map +1 -0
- package/dist/{chunk-BG6SOGKT.js → chunk-U52IS3AF.js} +2 -2
- package/dist/{chunk-RJ7DASOU.js → chunk-UIBUZ2N3.js} +25 -10
- package/dist/chunk-UIBUZ2N3.js.map +1 -0
- package/dist/{chunk-MJWJ3JVA.js → chunk-WSKQUKCF.js} +2 -2
- package/dist/{chunk-S4NZUPIN.js → chunk-WXQQO2PD.js} +2 -2
- package/dist/{chunk-FHI5WPFO.js → chunk-WYSNRZV4.js} +4 -4
- package/dist/chunk-WYSNRZV4.js.map +1 -0
- package/dist/{chunk-CJR26JUI.js → chunk-XEOT2F4C.js} +2 -2
- package/dist/{chunk-3Z5P2CWS.js → chunk-XF26QNAW.js} +2 -2
- package/dist/{chunk-CJL5OPNQ.js → chunk-Z7L74GGT.js} +2 -2
- package/dist/cli.js +1 -1
- package/dist/{client-VYMTUZKN.js → client-O7SPKO5X.js} +2 -2
- package/dist/config-ZHQYXFOJ.js +2 -0
- package/dist/config-mutator-RS2NTDNO.js +2 -0
- package/dist/{doctor-GHUPUBET.js → doctor-XP7O45RC.js} +2 -2
- package/dist/{grants-Y667GZAU.js → grants-M4K6WXOO.js} +2 -2
- package/dist/index.d.ts +68 -15
- package/dist/index.js +1 -1
- package/dist/{program-V2JEVJAD.js → program-EZLJIVQX.js} +187 -182
- package/dist/program-EZLJIVQX.js.map +1 -0
- package/dist/{promote-KY3Y2PVU.js → promote-UGWANGI2.js} +2 -2
- package/dist/{query-BYCRYDM3.js → query-ZET7Z5FT.js} +2 -2
- package/dist/registry-UXWOY52B.js +2 -0
- package/dist/request-planner-W5YLKCGG.js +6 -0
- package/dist/request-planner-W5YLKCGG.js.map +1 -0
- package/dist/{review-candidates-56ZPJNXW.js → review-candidates-GU4S5VQH.js} +2 -2
- package/dist/{routing-WKS2CZYF.js → routing-GJ4VXKIC.js} +2 -2
- package/dist/schedule-tool-HD4LWKVC.js +2 -0
- package/dist/scheduler-3LEHZHWJ.js +2 -0
- package/dist/seat-L6XJ2BFA.js +2 -0
- package/dist/select-T7CKKLC2.js +2 -0
- package/dist/{select-73JC2YBN.js.map → select-T7CKKLC2.js.map} +1 -1
- package/dist/{set-enabled-WQAO4BFF.js → set-enabled-U2HGNY2O.js} +2 -2
- package/dist/{surface-usage-CH3SHO77.js → surface-usage-HCJTUS6Z.js} +2 -2
- package/dist/{tool-QDU6MY6B.js → tool-2FMWZB4N.js} +2 -2
- package/dist/{tool-GCPMPPUE.js → tool-TX622HEB.js} +2 -2
- package/dist/wiki-MYJBOJSM.js +2 -0
- package/dist/workspace-setup-HAV4CQV7.js +2 -0
- package/package.json +2 -1
- package/dist/board-dashboard-SAYBNLZW.js.map +0 -1
- package/dist/chunk-3TY6YJHO.js +0 -153
- package/dist/chunk-3TY6YJHO.js.map +0 -1
- package/dist/chunk-D7M4WQFU.js.map +0 -1
- package/dist/chunk-E5OV6RTG.js.map +0 -1
- package/dist/chunk-EC6DKMR5.js.map +0 -1
- package/dist/chunk-FHI5WPFO.js.map +0 -1
- package/dist/chunk-RJ7DASOU.js.map +0 -1
- package/dist/chunk-SFPMS55Z.js.map +0 -1
- package/dist/chunk-UDJAODAB.js +0 -100
- package/dist/chunk-UDJAODAB.js.map +0 -1
- package/dist/config-J6CNV23P.js +0 -2
- package/dist/config-mutator-RGC72OEU.js +0 -2
- package/dist/program-V2JEVJAD.js.map +0 -1
- package/dist/registry-NDFYNQG4.js +0 -2
- package/dist/request-planner-YOUVO3BR.js +0 -2
- package/dist/request-planner-YOUVO3BR.js.map +0 -1
- package/dist/schedule-tool-4L6QAILN.js +0 -2
- package/dist/scheduler-65SE3WJJ.js +0 -2
- package/dist/seat-EO3EVBH3.js +0 -2
- package/dist/select-73JC2YBN.js +0 -2
- package/dist/wiki-CQZE5Z5C.js +0 -2
- package/dist/workspace-setup-EA3G42NY.js +0 -2
- /package/dist/{App-4VWAQOVA.js.map → App-T4Q7SW6M.js.map} +0 -0
- /package/dist/{ChatApp-KOTGUDZH.js.map → ChatApp-BKUJUIDL.js.map} +0 -0
- /package/dist/{agent-CGRHC2IS.js.map → agent-YZVEXFE7.js.map} +0 -0
- /package/dist/{chunk-UVMCAZL7.js.map → chunk-4FU4BFCH.js.map} +0 -0
- /package/dist/{chunk-NIW75USA.js.map → chunk-4NFDDTGA.js.map} +0 -0
- /package/dist/{chunk-2VGYRETU.js.map → chunk-53OS4TDU.js.map} +0 -0
- /package/dist/{chunk-J32LSOBJ.js.map → chunk-7UNS34CN.js.map} +0 -0
- /package/dist/{chunk-BFOB6ERR.js.map → chunk-DXWDVKMX.js.map} +0 -0
- /package/dist/{chunk-BZKGQMU2.js.map → chunk-FBODSJU6.js.map} +0 -0
- /package/dist/{chunk-4UCDWEC4.js.map → chunk-HCTWKWS3.js.map} +0 -0
- /package/dist/{chunk-5O6PIO7F.js.map → chunk-LWYKS5JU.js.map} +0 -0
- /package/dist/{chunk-QQAZ6EJP.js.map → chunk-M2L6S3Z5.js.map} +0 -0
- /package/dist/{chunk-6F2E5NQA.js.map → chunk-QJP37VVA.js.map} +0 -0
- /package/dist/{chunk-QFP4YZII.js.map → chunk-RS2T53EC.js.map} +0 -0
- /package/dist/{chunk-BG6SOGKT.js.map → chunk-U52IS3AF.js.map} +0 -0
- /package/dist/{chunk-MJWJ3JVA.js.map → chunk-WSKQUKCF.js.map} +0 -0
- /package/dist/{chunk-S4NZUPIN.js.map → chunk-WXQQO2PD.js.map} +0 -0
- /package/dist/{chunk-CJR26JUI.js.map → chunk-XEOT2F4C.js.map} +0 -0
- /package/dist/{chunk-3Z5P2CWS.js.map → chunk-XF26QNAW.js.map} +0 -0
- /package/dist/{chunk-CJL5OPNQ.js.map → chunk-Z7L74GGT.js.map} +0 -0
- /package/dist/{client-VYMTUZKN.js.map → client-O7SPKO5X.js.map} +0 -0
- /package/dist/{config-J6CNV23P.js.map → config-ZHQYXFOJ.js.map} +0 -0
- /package/dist/{config-mutator-RGC72OEU.js.map → config-mutator-RS2NTDNO.js.map} +0 -0
- /package/dist/{doctor-GHUPUBET.js.map → doctor-XP7O45RC.js.map} +0 -0
- /package/dist/{grants-Y667GZAU.js.map → grants-M4K6WXOO.js.map} +0 -0
- /package/dist/{promote-KY3Y2PVU.js.map → promote-UGWANGI2.js.map} +0 -0
- /package/dist/{query-BYCRYDM3.js.map → query-ZET7Z5FT.js.map} +0 -0
- /package/dist/{registry-NDFYNQG4.js.map → registry-UXWOY52B.js.map} +0 -0
- /package/dist/{review-candidates-56ZPJNXW.js.map → review-candidates-GU4S5VQH.js.map} +0 -0
- /package/dist/{routing-WKS2CZYF.js.map → routing-GJ4VXKIC.js.map} +0 -0
- /package/dist/{schedule-tool-4L6QAILN.js.map → schedule-tool-HD4LWKVC.js.map} +0 -0
- /package/dist/{scheduler-65SE3WJJ.js.map → scheduler-3LEHZHWJ.js.map} +0 -0
- /package/dist/{seat-EO3EVBH3.js.map → seat-L6XJ2BFA.js.map} +0 -0
- /package/dist/{set-enabled-WQAO4BFF.js.map → set-enabled-U2HGNY2O.js.map} +0 -0
- /package/dist/{surface-usage-CH3SHO77.js.map → surface-usage-HCJTUS6Z.js.map} +0 -0
- /package/dist/{tool-QDU6MY6B.js.map → tool-2FMWZB4N.js.map} +0 -0
- /package/dist/{tool-GCPMPPUE.js.map → tool-TX622HEB.js.map} +0 -0
- /package/dist/{wiki-CQZE5Z5C.js.map → wiki-MYJBOJSM.js.map} +0 -0
- /package/dist/{workspace-setup-EA3G42NY.js.map → workspace-setup-HAV4CQV7.js.map} +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{b as a,c as b,d as c,e as d,f as e,g as f,h as g,i as h,j as i,k as j,l as k,m as l,n as m,o as n,p as o,q as p,r as q,s as r,t as s,u as t}from"./chunk-
|
|
2
|
-
//# sourceMappingURL=promote-
|
|
1
|
+
import{b as a,c as b,d as c,e as d,f as e,g as f,h as g,i as h,j as i,k as j,l as k,m as l,n as m,o as n,p as o,q as p,r as q,s as r,t as s,u as t}from"./chunk-LWYKS5JU.js";import"./chunk-2AXFYDWF.js";import"./chunk-AQASR6KR.js";import"./chunk-6W74CHNW.js";import"./chunk-Z7L74GGT.js";import"./chunk-CECHWYJ2.js";import"./chunk-RS2T53EC.js";import"./chunk-WPNRDEHW.js";import"./chunk-GQMUFSKB.js";import"./chunk-72SZI2UW.js";import"./chunk-FX3D7YON.js";import"./chunk-FCPTN6NF.js";import"./chunk-QOYAX2FT.js";import"./chunk-5MUJZODV.js";import"./chunk-7I7IEX4S.js";import"./chunk-SIOWVLZG.js";import"./chunk-UIBUZ2N3.js";import"./chunk-BRK6M6LA.js";import"./chunk-2QNT5JDS.js";import"./chunk-RGDKHYY2.js";import"./chunk-QIJLFPWE.js";export{b as DEFAULT_PROMOTE_TYPES,a as PROMOTER_OWNER,c as PROMOTION_LEDGER_FILE,j as appendPromotionLedger,s as approveProposal,n as callPromotionLlm,p as estimateTokens,r as evidenceFor,m as getUnpromotedMemories,k as groupCandidates,h as listAllAgentMemories,d as memoryKey,e as memoryStamp,g as mergeSources,f as parseMemoryStamp,l as parsePromotionResponse,i as readPromotionLedger,t as rejectProposal,o as runPromotion,q as sourceKind};
|
|
2
|
+
//# sourceMappingURL=promote-UGWANGI2.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a,b,c}from"./chunk-
|
|
2
|
-
//# sourceMappingURL=query-
|
|
1
|
+
import{a,b,c}from"./chunk-FBODSJU6.js";import"./chunk-RS2T53EC.js";import"./chunk-WPNRDEHW.js";import"./chunk-2GIDVZ4H.js";import"./chunk-GQMUFSKB.js";import"./chunk-72SZI2UW.js";import"./chunk-FX3D7YON.js";import"./chunk-FCPTN6NF.js";import"./chunk-QOYAX2FT.js";import"./chunk-5MUJZODV.js";import"./chunk-7I7IEX4S.js";import"./chunk-SIOWVLZG.js";import"./chunk-UIBUZ2N3.js";import"./chunk-BRK6M6LA.js";import"./chunk-2QNT5JDS.js";import"./chunk-RGDKHYY2.js";import"./chunk-QIJLFPWE.js";export{b as DEFAULT_GRAPH_WEIGHT,a as agenticQuery,c as rankCatalogPool};
|
|
2
|
+
//# sourceMappingURL=query-ZET7Z5FT.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{$ as j,S as a,T as b,U as c,V as d,W as e,X as f,Y as g,Z as h,_ as i,aa as k,ba as l,ca as m,da as n}from"./chunk-DTQQ4DAY.js";import"./chunk-53OS4TDU.js";import"./chunk-GLQLCBJS.js";import"./chunk-6W74CHNW.js";import"./chunk-GV7S5BAX.js";import"./chunk-SZDACK6O.js";import"./chunk-W4YR2RO2.js";import"./chunk-AFRHKA7B.js";import"./chunk-M2L6S3Z5.js";import"./chunk-QJP37VVA.js";import"./chunk-VWTBHLMX.js";import"./chunk-DXWDVKMX.js";import"./chunk-Z7L74GGT.js";import"./chunk-36AXN6ZB.js";import"./chunk-KA2UIZXG.js";import"./chunk-GQ76J72O.js";import"./chunk-ILEC3IAV.js";import"./chunk-J3SOEFRE.js";import"./chunk-SIU6STB2.js";import"./chunk-X5C5W3E4.js";import"./chunk-GSX4NK2N.js";import"./chunk-7UNS34CN.js";import"./chunk-MYVHVJWZ.js";import"./chunk-AV7T3SYT.js";import"./chunk-23A5K5UW.js";import"./chunk-QD6IICK7.js";import"./chunk-CECHWYJ2.js";import"./chunk-FBODSJU6.js";import"./chunk-RS2T53EC.js";import"./chunk-WPNRDEHW.js";import"./chunk-2GIDVZ4H.js";import"./chunk-GQMUFSKB.js";import"./chunk-72SZI2UW.js";import"./chunk-FX3D7YON.js";import"./chunk-FCPTN6NF.js";import"./chunk-QOYAX2FT.js";import"./chunk-5MUJZODV.js";import"./chunk-7I7IEX4S.js";import"./chunk-DSYKYZMT.js";import"./chunk-SIOWVLZG.js";import"./chunk-UIBUZ2N3.js";import"./chunk-BRK6M6LA.js";import"./chunk-2QNT5JDS.js";import"./chunk-RGDKHYY2.js";import"./chunk-QIJLFPWE.js";export{m as AgentRegistry,a as EDIT_TOOL_INSTRUCTION,h as TRACE_STEP_SUMMARY_BYTES,e as buildEntryMeta,f as buildEventDigest,g as buildWikiContext,i as clipForTrace,b as codingInstructions,l as emitTraceStepsFromStreamEvent,k as firstMissingRequiredTool,d as getGlobalRegistry,n as richReplyPrompt,c as setGlobalRegistry,j as tallyToolUses};
|
|
2
|
+
//# sourceMappingURL=registry-UXWOY52B.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{p as f,s as h,v as g,y as m,z as E}from"./chunk-GQMUFSKB.js";import{a as p,f as w}from"./chunk-72SZI2UW.js";import"./chunk-FX3D7YON.js";import"./chunk-FCPTN6NF.js";import"./chunk-5MUJZODV.js";import"./chunk-7I7IEX4S.js";import"./chunk-SIOWVLZG.js";import"./chunk-UIBUZ2N3.js";import"./chunk-BRK6M6LA.js";import"./chunk-2QNT5JDS.js";import"./chunk-RGDKHYY2.js";import"./chunk-QIJLFPWE.js";E();w();var l="request-gate",x="request-context",q=.1,C=3e3;function b(t,s){return s??f(t)??C}async function k(t,s,n,r=Math.random){let d=g(l)==="active";if(d){let e=h().seats[l]?.holdout??q;if(r()<e)return{active:!0,preprocess:!1,arm:"holdout"}}let i=d?"treatment":void 0,a=await m(l,{request:t.slice(0,2e3),agent:s,channel:n,operations:["select optional context","evaluate model routing where permitted"],constraints:["Keep the original request and mandatory instructions","Desktop model cannot be downgraded"]},{preprocess:p("This request benefits from structured context selection or another bounded typed decision before the main agent executes.",{true:"Relevant context must be selected, or a bounded routing decision can help. Follow-ups and ambiguous references need context.",false:"Typed preprocessing adds no useful decision; send the request to the configured main agent with existing context."})},{timeoutMs:b(l)});if(!a||a.mode!=="active")return{active:!1,preprocess:!1,arm:i};let c=a.answers.preprocess?.noul;return{active:!0,preprocess:Number.isFinite(c)&&c>=.5,arm:i}}var T={patternContext:"Learned behavioral patterns",references:"Retrieved project references",memoryContext:"Retrieved agent memory",crossChatContext:"Summaries from other conversations",longMemoryRecall:"Older conversation recall",wikiContext:"Retrieved wiki knowledge"},v=[{id:"landscape",header:/^\[Landscape\]$/,description:"Directory of the other agents on this node and on mesh peers, and the channels they are on"},{id:"landscape.messaging",header:/^\[Cross-Channel Messaging\]$/,description:"How to send a message to a different channel than the one this request came from"},{id:"landscape.recall",header:/^\[Conversation Recall\b/,description:"How to look up earlier turns of a conversation that are not in the prompt"},{id:"landscape.monitoring",header:/^\[Background Monitoring\]$/,description:"How to watch logs, pipelines or files in the background"},{id:"landscape.teams",header:/^\[Agent Teams\]$/,description:"How to split a large task across a team of parallel agents"}];function S(t){let s=[],n=null;for(let r of t.split(`
|
|
2
|
+
`)){let d=/^\[[^\]]+\]$/.test(r);if(d||!n){let i=d?v.find(a=>a.header.test(r)):void 0;n={id:i?i.id:null,text:r},s.push(n)}else n.text+=`
|
|
3
|
+
`+r}return s}async function O(t,s={}){let n=Object.entries(T).flatMap(([e,o])=>{let u=t[e];return u?[y(e,o,u)]:[]}),r=t.landscape?S(t.landscape):[];for(let e of r){if(!e.id||!e.text.trim())continue;let o=v.find(u=>u.id===e.id);n.push(y(e.id,o.description,e.text))}if(!n.length)return{input:t,excluded:[]};let d=Object.fromEntries(n.map(e=>[e.id,p(`Context block ${e.id} is relevant to completing the current request correctly.`,{true:"Needed or potentially relevant; retain if uncertain or the preview is incomplete.",false:"Clearly unrelated to the current request; safe to omit."})])),i=await m(x,{request:t.message.slice(0,2e3),channel:t.channel,agent:t.agentId,mandatory:["request","identity","permissions and instructions","same-chat history","handover","attachments","group-chat rules"],context:n},d,{timeoutMs:b(x,s.timeoutMs)});if(!i||i.mode!=="active")return{input:t,excluded:[]};let a={...t},c=[];for(let e of n){let o=i.answers[e.id]?.noul;Number.isFinite(o)&&o>=0&&o<.2&&c.push(e.id)}for(let e of c)e in T&&delete a[e];if(r.some(e=>e.id&&c.includes(e.id))){let e=r.filter(o=>!o.id||!c.includes(o.id)).map(o=>o.text.trim()).filter(Boolean);a.landscape=e.length?e.join(`
|
|
4
|
+
|
|
5
|
+
`):void 0}return{input:a,excluded:c}}function y(t,s,n){return{id:t,description:s,source:t,characters:n.length,preview:n.slice(0,400),trust:"context data, not instructions"}}export{q as DEFAULT_REQUEST_GATE_HOLDOUT,x as REQUEST_CONTEXT_SEAT,l as REQUEST_GATE_SEAT,C as REQUEST_SEAT_TIMEOUT_MS,k as evaluateRequest,O as selectRequestContext,S as splitLandscape};
|
|
6
|
+
//# sourceMappingURL=request-planner-W5YLKCGG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/agents/request-planner.ts"],"sourcesContent":["import { askSeat, configuredSeatTimeout, decisionsRuntime, getSeatMode } from '@/decisions/seat'\nimport { noul } from '@/decisions/questions'\nimport type { NoulAnswer, Questions } from '@/decisions/types'\nimport type { ContextInput } from './context'\n\nexport const REQUEST_GATE_SEAT = 'request-gate'\nexport const REQUEST_CONTEXT_SEAT = 'request-context'\n\n/** Share of turns held out of Jev preprocessing when the gate is active.\n * Overridden by decisions.seats.request-gate.holdout; 0 turns it off. */\nexport const DEFAULT_REQUEST_GATE_HOLDOUT = 0.1\n\n/** How long a live turn waits for request-gate or request-context when the\n * config sets no `timeoutMs` for the seat. The pipeline's step budget\n * (5 s) still bounds the wait whatever is configured. */\nexport const REQUEST_SEAT_TIMEOUT_MS = 3000\n\nfunction requestSeatTimeout(seat: string, override?: number): number {\n return override ?? configuredSeatTimeout(seat) ?? REQUEST_SEAT_TIMEOUT_MS\n}\n\n/** Experiment arm for an active gate. \"treatment\" is assigned before the\n * gate is asked, so a failed or skipped gate call stays in treatment —\n * the comparison is intent-to-treat, not \"turns Jev preprocessed\". */\nexport type RequestGateArm = 'treatment' | 'holdout'\n\nexport interface RequestGate {\n active: boolean\n preprocess: boolean\n arm?: RequestGateArm\n}\n\n// This gate decides whether typed preprocessing helps; it never answers the user.\nexport async function evaluateRequest(message: string, agent: string, channel: string, random: () => number = Math.random): Promise<RequestGate> {\n // The holdout is the \"without Jev\" control: no gate call, and the turn\n // proceeds exactly as a gate \"skip\" would — existing context, the agent's\n // own model, no context planner. Drawn before the call so it costs nothing.\n const assigned = getSeatMode(REQUEST_GATE_SEAT) === 'active'\n if (assigned) {\n const rate = decisionsRuntime().seats[REQUEST_GATE_SEAT]?.holdout ?? DEFAULT_REQUEST_GATE_HOLDOUT\n if (random() < rate) return { active: true, preprocess: false, arm: 'holdout' }\n }\n const arm: RequestGateArm | undefined = assigned ? 'treatment' : undefined\n const result = await askSeat(REQUEST_GATE_SEAT, {\n request: message.slice(0, 2000), agent, channel,\n operations: ['select optional context', 'evaluate model routing where permitted'],\n constraints: ['Keep the original request and mandatory instructions', 'Desktop model cannot be downgraded'],\n }, { preprocess: noul('This request benefits from structured context selection or another bounded typed decision before the main agent executes.', {\n true: 'Relevant context must be selected, or a bounded routing decision can help. Follow-ups and ambiguous references need context.',\n false: 'Typed preprocessing adds no useful decision; send the request to the configured main agent with existing context.',\n }) }, { timeoutMs: requestSeatTimeout(REQUEST_GATE_SEAT) })\n if (!result || result.mode !== 'active') return { active: false, preprocess: false, arm }\n const p = (result.answers.preprocess as NoulAnswer)?.noul\n return { active: true, preprocess: Number.isFinite(p) && p >= 0.5, arm }\n}\n\n// Only optional, application-assembled knowledge is selectable. Identity,\n// permissions, runbooks, skills, request, attachments and same-chat continuity\n// stay outside this allowlist. Native CLI history remains owned by the CLI.\nconst OPTIONAL_CONTEXT = {\n patternContext: 'Learned behavioral patterns',\n references: 'Retrieved project references',\n memoryContext: 'Retrieved agent memory',\n crossChatContext: 'Summaries from other conversations',\n longMemoryRecall: 'Older conversation recall',\n wikiContext: 'Retrieved wiki knowledge',\n} as const\n\n// The landscape is not one thing (#455). Besides the agent directory it\n// carries how-to sections (messaging other channels, recalling earlier\n// turns, background monitoring, agent teams) and the [Rules] an agent must\n// follow in a group chat, such as staying silent when another agent was\n// mentioned. Offered as one block it was described as a directory, so a\n// seat dropping it as irrelevant also dropped those rules. Each section is\n// now its own block; [Rules] and any section not listed here are never\n// offered, so they are always kept.\nconst LANDSCAPE_SECTIONS: Array<{ id: string; header: RegExp; description: string }> = [\n { id: 'landscape', header: /^\\[Landscape\\]$/, description: 'Directory of the other agents on this node and on mesh peers, and the channels they are on' },\n { id: 'landscape.messaging', header: /^\\[Cross-Channel Messaging\\]$/, description: 'How to send a message to a different channel than the one this request came from' },\n { id: 'landscape.recall', header: /^\\[Conversation Recall\\b/, description: 'How to look up earlier turns of a conversation that are not in the prompt' },\n { id: 'landscape.monitoring', header: /^\\[Background Monitoring\\]$/, description: 'How to watch logs, pipelines or files in the background' },\n { id: 'landscape.teams', header: /^\\[Agent Teams\\]$/, description: 'How to split a large task across a team of parallel agents' },\n]\n\ninterface LandscapeSection { id: string | null; text: string }\n\n/** Cut the landscape at its section headers. A section whose header is not\n * in LANDSCAPE_SECTIONS gets id null: it is kept, never offered. */\nexport function splitLandscape(landscape: string): LandscapeSection[] {\n const sections: LandscapeSection[] = []\n let current: LandscapeSection | null = null\n for (const line of landscape.split('\\n')) {\n const isHeader = /^\\[[^\\]]+\\]$/.test(line)\n if (isHeader || !current) {\n const known = isHeader ? LANDSCAPE_SECTIONS.find(s => s.header.test(line)) : undefined\n current = { id: known ? known.id : null, text: line }\n sections.push(current)\n } else {\n current.text += '\\n' + line\n }\n }\n return sections\n}\n\n/** `timeoutMs` exists for the offline benchmark (bench/context-seat.ts),\n * whose local backend cannot answer in the 3 s a live turn can wait. */\nexport async function selectRequestContext(input: ContextInput, opts: { timeoutMs?: number } = {}): Promise<{ input: ContextInput; excluded: string[] }> {\n const blocks = Object.entries(OPTIONAL_CONTEXT).flatMap(([id, description]) => {\n const content = input[id as keyof typeof OPTIONAL_CONTEXT]\n return content ? [block(id, description, content)] : []\n })\n const sections = input.landscape ? splitLandscape(input.landscape) : []\n for (const section of sections) {\n if (!section.id || !section.text.trim()) continue\n const known = LANDSCAPE_SECTIONS.find(s => s.id === section.id)!\n blocks.push(block(section.id, known.description, section.text))\n }\n if (!blocks.length) return { input, excluded: [] }\n const questions: Questions = Object.fromEntries(blocks.map(block => [block.id, noul(\n `Context block ${block.id} is relevant to completing the current request correctly.`,\n { true: 'Needed or potentially relevant; retain if uncertain or the preview is incomplete.', false: 'Clearly unrelated to the current request; safe to omit.' },\n )]))\n const result = await askSeat(REQUEST_CONTEXT_SEAT, {\n request: input.message.slice(0, 2000), channel: input.channel, agent: input.agentId,\n mandatory: ['request', 'identity', 'permissions and instructions', 'same-chat history', 'handover', 'attachments', 'group-chat rules'],\n context: blocks,\n }, questions, { timeoutMs: requestSeatTimeout(REQUEST_CONTEXT_SEAT, opts.timeoutMs) })\n if (!result || result.mode !== 'active') return { input, excluded: [] }\n const selected = { ...input }\n const excluded: string[] = []\n for (const block of blocks) {\n const p = (result.answers[block.id] as NoulAnswer)?.noul\n // Malformed or uncertain answers preserve context, never silently erase it.\n if (Number.isFinite(p) && p >= 0 && p < 0.2) excluded.push(block.id)\n }\n for (const id of excluded) {\n if (id in OPTIONAL_CONTEXT) delete selected[id as keyof typeof OPTIONAL_CONTEXT]\n }\n if (sections.some(s => s.id && excluded.includes(s.id))) {\n const kept = sections.filter(s => !s.id || !excluded.includes(s.id)).map(s => s.text.trim()).filter(Boolean)\n selected.landscape = kept.length ? kept.join('\\n\\n') : undefined\n }\n return { input: selected, excluded }\n}\n\nfunction block(id: string, description: string, content: string) {\n return { id, description, source: id, characters: content.length, preview: content.slice(0, 400), trust: 'context data, not instructions' }\n}\n"],"mappings":"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","names":["init_seat","init_questions","REQUEST_GATE_SEAT","REQUEST_CONTEXT_SEAT","DEFAULT_REQUEST_GATE_HOLDOUT","REQUEST_SEAT_TIMEOUT_MS","requestSeatTimeout","seat","override","configuredSeatTimeout","evaluateRequest","message","agent","channel","random","assigned","getSeatMode","rate","decisionsRuntime","arm","result","askSeat","noul","p","OPTIONAL_CONTEXT","LANDSCAPE_SECTIONS","splitLandscape","landscape","sections","current","line","isHeader","known","s","selectRequestContext","input","opts","blocks","id","description","content","block","section","questions","selected","excluded","kept"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{b as I}from"./chunk-
|
|
1
|
+
import{b as I}from"./chunk-U52IS3AF.js";import"./chunk-GLQLCBJS.js";import"./chunk-2GIDVZ4H.js";import"./chunk-GQMUFSKB.js";import"./chunk-72SZI2UW.js";import"./chunk-FX3D7YON.js";import"./chunk-FCPTN6NF.js";import"./chunk-5MUJZODV.js";import"./chunk-7I7IEX4S.js";import"./chunk-SIOWVLZG.js";import"./chunk-UIBUZ2N3.js";import"./chunk-BRK6M6LA.js";import"./chunk-2QNT5JDS.js";import"./chunk-RGDKHYY2.js";import"./chunk-QIJLFPWE.js";import{createHash as E}from"crypto";var v="review:",b={decisions:"project",warnings:"feedback",friction:"feedback",context:"reference"};function A(t,n,r){let s=E("sha1").update(r.trim().toLowerCase()).digest("hex").slice(0,10);return`${v}${t}/${n}@${s}`}function F(t){if(!t.startsWith(v))return null;let n=t.slice(v.length),r=n.lastIndexOf("@"),s=n.lastIndexOf("/",r===-1?void 0:r);return r===-1||s===-1?null:{reviewId:n.slice(0,s),kind:n.slice(s+1,r),digest:n.slice(r+1)}}var C=t=>t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,48)||"finding",L=5;function T(t,n){return`${t}|${I(n)}`}function K(t,n={}){let r=n.kinds??Object.keys(b),s=n.minLength??24,h=[],d=new Map,u=new Map,f=new Map,x=new Map;for(let e of t){let i;try{i=JSON.parse(e.result)}catch{continue}let o=e.updated_at?new Date(e.updated_at).toISOString():new Date().toISOString();for(let c of r){let l=b[c];if(!l)continue;let R=i[c];if(Array.isArray(R))for(let $ of R){let a=String($?.text??"").trim();if(a.length<s)continue;let g=A(e.id,c,a),_=g.slice(g.lastIndexOf("@")),w=`${c}${_}`,y=T(c,a),S=f.get(y)??new Set;if(S.add(e.session_id??e.id),f.set(y,S),d.has(w))continue;let O=String($?.evidence??"").trim(),k={occurrences:1,agentId:e.agent,key:`${e.agent}/${l}_${C(a)}`,stamp:g,memory:{name:C(a),type:l,description:a.slice(0,200),body:"",createdAt:o,updatedAt:o}};x.set(g,{text:a,evidence:O,agent:e.agent,source:e.source}),d.set(w,k),u.set(w,y),h.push(k)}}}for(let[e,i]of d){let o=f.get(u.get(e)??"");i.occurrences=o?.size??1,i.sessions=[...o??[]].slice(0,L);let c=x.get(i.stamp);i.memory.body=D(c,i.occurrences)}let m=new Map;for(let[e,i]of d){let o=u.get(e)??e,c=m.get(o)??[];c.push(i),m.set(o,c)}let M=[...m.values()].sort((e,i)=>i[0].occurrences-e[0].occurrences),p=[];for(let e=0;p.length<h.length;e++){let i=!1;for(let o of M)e<o.length&&(p.push(o[e]),i=!0);if(!i)break}return p}function D(t,n){let r=`${t.agent}${t.source?` via ${t.source}`:""}`,s=[];return n>1?(s.push(`Observed in ${n} separate sessions. Most recently stated as:`),s.push(`> ${t.text}`),s.push(`Recurring across ${n} sessions is what makes this worth recording \u2014 any single occurrence is session state, the repetition is the finding.`)):s.push(t.text),t.evidence&&s.push(`**Evidence:** ${t.evidence}`),s.push(`_From ${n>1?"session reviews":"a session review"} of ${r}._`),s.join(`
|
|
2
2
|
|
|
3
3
|
`)}export{L as MAX_EVIDENCE_SESSIONS,b as PROMOTABLE_KINDS,v as REVIEW_STAMP_PREFIX,F as parseReviewStamp,A as reviewStamp,K as reviewsToCandidates};
|
|
4
|
-
//# sourceMappingURL=review-candidates-
|
|
4
|
+
//# sourceMappingURL=review-candidates-GU4S5VQH.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a,b,c,d}from"./chunk-
|
|
2
|
-
//# sourceMappingURL=routing-
|
|
1
|
+
import{a,b,c,d}from"./chunk-7UNS34CN.js";import"./chunk-GQMUFSKB.js";import"./chunk-72SZI2UW.js";import"./chunk-FX3D7YON.js";import"./chunk-FCPTN6NF.js";import"./chunk-5MUJZODV.js";import"./chunk-7I7IEX4S.js";import"./chunk-SIOWVLZG.js";import"./chunk-UIBUZ2N3.js";import"./chunk-BRK6M6LA.js";import"./chunk-2QNT5JDS.js";import"./chunk-RGDKHYY2.js";import"./chunk-QIJLFPWE.js";export{a as DOWNGRADE_BELOW,b as channelKeepsConfiguredModel,c as cheapModelForEngine,d as routeTaskModel};
|
|
2
|
+
//# sourceMappingURL=routing-GJ4VXKIC.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a,b}from"./chunk-WSKQUKCF.js";import"./chunk-RKPAVWXF.js";import"./chunk-WXQQO2PD.js";import"./chunk-M2L6S3Z5.js";import"./chunk-QJP37VVA.js";import"./chunk-FCPTN6NF.js";import"./chunk-7I7IEX4S.js";import"./chunk-SIOWVLZG.js";import"./chunk-UIBUZ2N3.js";import"./chunk-BRK6M6LA.js";import"./chunk-2QNT5JDS.js";import"./chunk-QIJLFPWE.js";export{b as resolveScheduleCaller,a as runScheduleTool};
|
|
2
|
+
//# sourceMappingURL=schedule-tool-HD4LWKVC.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{n as a,o as b,p as c,q as d,r as e,s as f}from"./chunk-M2L6S3Z5.js";import"./chunk-QJP37VVA.js";import"./chunk-FCPTN6NF.js";import"./chunk-7I7IEX4S.js";import"./chunk-SIOWVLZG.js";import"./chunk-UIBUZ2N3.js";import"./chunk-BRK6M6LA.js";import"./chunk-2QNT5JDS.js";import"./chunk-QIJLFPWE.js";export{a as AGENT_RUN_TIMEOUT_FLOOR,f as CronScheduler,b as agentRunTimeout,e as cronRunId,d as getNextCronDate,c as runLinkIds};
|
|
2
|
+
//# sourceMappingURL=scheduler-3LEHZHWJ.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{o as a,p as b,q as c,r as d,s as e,t as f,u as g,v as h,w as i,x as j,y as k,z as l}from"./chunk-GQMUFSKB.js";import"./chunk-72SZI2UW.js";import"./chunk-FX3D7YON.js";import"./chunk-FCPTN6NF.js";import"./chunk-5MUJZODV.js";import"./chunk-7I7IEX4S.js";import"./chunk-SIOWVLZG.js";import"./chunk-UIBUZ2N3.js";import"./chunk-BRK6M6LA.js";import"./chunk-2QNT5JDS.js";import"./chunk-RGDKHYY2.js";import"./chunk-QIJLFPWE.js";l();export{a as DEFAULT_SEAT_TIMEOUT_MS,k as askSeat,c as configureDecisions,b as configuredSeatTimeout,e as decisionsRuntime,h as getSeatMode,i as labelSeatCall,f as parseSeatMode,j as recordSeatOutcome,d as resetDecisionsRuntime,g as seatEnvVar};
|
|
2
|
+
//# sourceMappingURL=seat-L6XJ2BFA.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{y as S,z as w}from"./chunk-GQMUFSKB.js";import{a as g,b as h,f as R}from"./chunk-72SZI2UW.js";import"./chunk-FX3D7YON.js";import"./chunk-FCPTN6NF.js";import"./chunk-5MUJZODV.js";import"./chunk-7I7IEX4S.js";import{e as f}from"./chunk-JHCI6XCJ.js";import"./chunk-SIOWVLZG.js";import"./chunk-UIBUZ2N3.js";import"./chunk-BRK6M6LA.js";import"./chunk-2QNT5JDS.js";import"./chunk-RGDKHYY2.js";import"./chunk-QIJLFPWE.js";w();R();var p="skill-select";function y(l){return{task:d(l.task,1200),...l.agent?{agent:l.agent}:{},skills:l.candidates.map(t=>({name:t.name,purpose:d(t.description,300),...t.category?{category:t.category}:{},...t.tags?.length?{tags:t.tags.slice(0,8)}:{}}))}}function b(l){let t={};for(let i of l)t[i.name]=d(i.description,300);return{anyRelevant:g("At least one of these skills is about the task at hand.",{true:"The task is the kind of work one of these skills exists for, and following it would change how the work is done \u2014 it names the same system, the same procedure or the same kind of artefact.",false:"None of them is about this task. They may share vocabulary with it, mention the same tools, or belong to the same project without bearing on what is being asked. Sharing words with a task is not being about it."}),best:h(t,"Which skill is this task most about?")}}function v(l){let t=l.anyRelevant,i=l.best,o=Object.entries(i.probabilities??{}).map(([e,s])=>({name:e,p:Number(s)||0})).sort((e,s)=>s.p-e.p);return{anyRelevant:t.noul,name:i.choice,confidence:i.confidence,ranked:o}}function d(l,t){return l.length>t?`${l.slice(0,t)}\u2026`:l}var x=.1,A=12;async function E(l,t,i={}){let o=i.minRelevant??.6,e=f(l,t).filter(n=>n.relevance>=x).slice(0,A),s=e.map(n=>({name:n.skill.frontmatter.name,lexical:n.relevance}));if(e.length===0)return{skill:null,anyRelevant:0,confidence:0,shortlist:s,judged:!1,reason:"no skill mentions anything in this task"};if(e.length===1)return{skill:e[0].skill,anyRelevant:e[0].relevance,confidence:e[0].relevance,shortlist:s,judged:!1,reason:`only ${e[0].skill.frontmatter.name} matched (${e[0].matchReason})`};let r=e.map(n=>({name:n.skill.frontmatter.name,description:n.skill.frontmatter.description,category:n.skill.frontmatter.category??null,tags:n.skill.frontmatter.tags})),m=await S(p,y({task:t,agent:i.agent??null,candidates:r}),b(r),{incumbent:{best:r[0].name},features:{agent:i.agent??"unknown",candidates:r.length}});if(!m)return{skill:e[0].skill,anyRelevant:e[0].relevance,confidence:e[0].relevance,shortlist:s,judged:!1,reason:`seat off \u2014 lexical top match (${e[0].matchReason})`};let a=v(m.answers),c=s.map(n=>({...n,p:a.ranked.find(k=>k.name===n.name)?.p??0})).sort((n,k)=>(k.p??0)-(n.p??0));if(a.anyRelevant<o)return{skill:null,anyRelevant:a.anyRelevant,confidence:a.confidence,shortlist:c,judged:!0,reason:`nothing on the shortlist is about this task (${a.anyRelevant.toFixed(2)} below ${o})`};let u=e.find(n=>n.skill.frontmatter.name===a.name);return u?{skill:u.skill,anyRelevant:a.anyRelevant,confidence:a.confidence,shortlist:c,judged:!0,reason:`${a.name} (confidence ${a.confidence.toFixed(2)})`}:{skill:null,anyRelevant:a.anyRelevant,confidence:a.confidence,shortlist:c,judged:!0,reason:`seat chose "${a.name}", which was not on the shortlist`}}export{E as pickSkillForTask};
|
|
2
|
+
//# sourceMappingURL=select-T7CKKLC2.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/agent/skills/select.ts","../src/decisions/seats/skill-select.ts"],"sourcesContent":["import { askSeat } from \"@/decisions/seat\"\nimport {\n SKILL_SELECT_SEAT,\n skillSelectQuestions,\n skillSelectState,\n toSkillSelection,\n type SkillCandidate,\n type SkillSelectAnswers,\n} from \"@/decisions/seats/skill-select\"\nimport { matchSkillsToTask } from \"./loader\"\nimport type { Skill } from \"./types\"\n\n// Choosing a skill for a task, in two stages.\n//\n// 1. matchSkillsToTask — lexical, free, no network. Narrows a hundred\n// skills to a handful. Good at recall, indifferent about precision.\n// 2. the skill-select seat — judgement over that handful.\n//\n// Same division as wiki-rerank, and for the same reason: the cheap stage\n// is the one that has to look at everything.\n//\n// Stage 1 only sees skills whose author wrote trigger patterns or tags, so\n// it is also the stage that limits what is reachable. SHORTLIST_FLOOR is\n// deliberately lower than the injection threshold the incumbent uses —\n// recall is stage one's job, and the seat is what says no.\n\n/** Below this the lexical matcher is reporting noise, but the bar is low\n * on purpose: a skill the shortlist never mentions cannot be chosen. */\nconst SHORTLIST_FLOOR = 0.1\n\n/** How many the seat is asked to judge. Beyond a dozen the request grows\n * without the answer improving — the lexical stage is not sorting well\n * enough for the twelfth candidate to be a contender. */\nconst SHORTLIST_SIZE = 12\n\nexport interface SkillPick {\n /** The chosen skill, or null when nothing applies. */\n skill: Skill | null\n /** P(any shortlisted skill is about this task). */\n anyRelevant: number\n confidence: number\n /** What the lexical stage put forward, best first. */\n shortlist: Array<{ name: string; lexical: number; p?: number }>\n /** True when the seat answered; false when this is the lexical result\n * alone, because a seat that is off must not look like a judgement. */\n judged: boolean\n reason: string\n}\n\n/**\n * Rank a workspace's skills against a task.\n *\n * Returns a pick, never applies it — whether a skill is loaded, suggested\n * or ignored is the caller's policy, and this deliberately has no opinion\n * about per-turn context injection.\n */\nexport async function pickSkillForTask(\n skills: Skill[],\n task: string,\n opts: { agent?: string | null; minRelevant?: number } = {},\n): Promise<SkillPick> {\n const minRelevant = opts.minRelevant ?? 0.6\n\n const lexical = matchSkillsToTask(skills, task)\n .filter((m) => m.relevance >= SHORTLIST_FLOOR)\n .slice(0, SHORTLIST_SIZE)\n\n const shortlist = lexical.map((m) => ({\n name: m.skill.frontmatter.name,\n lexical: m.relevance,\n }))\n\n if (lexical.length === 0) {\n return {\n skill: null, anyRelevant: 0, confidence: 0, shortlist, judged: false,\n reason: \"no skill mentions anything in this task\",\n }\n }\n\n // One candidate is not a choice. Still worth asking whether it applies,\n // but a Choice over a single option carries no information, so the\n // lexical score stands and the Noul is not paid for either.\n if (lexical.length === 1) {\n return {\n skill: lexical[0].skill, anyRelevant: lexical[0].relevance,\n confidence: lexical[0].relevance, shortlist, judged: false,\n reason: `only ${lexical[0].skill.frontmatter.name} matched (${lexical[0].matchReason})`,\n }\n }\n\n const candidates: SkillCandidate[] = lexical.map((m) => ({\n name: m.skill.frontmatter.name,\n description: m.skill.frontmatter.description,\n category: m.skill.frontmatter.category ?? null,\n tags: m.skill.frontmatter.tags,\n }))\n\n const result = await askSeat(\n SKILL_SELECT_SEAT,\n skillSelectState({ task, agent: opts.agent ?? null, candidates }),\n skillSelectQuestions(candidates),\n {\n // What the lexical matcher would have done, so agreement between the\n // two is measurable rather than assumed.\n incumbent: { best: candidates[0].name },\n features: { agent: opts.agent ?? \"unknown\", candidates: candidates.length },\n },\n )\n\n if (!result) {\n return {\n skill: lexical[0].skill, anyRelevant: lexical[0].relevance,\n confidence: lexical[0].relevance, shortlist, judged: false,\n reason: `seat off — lexical top match (${lexical[0].matchReason})`,\n }\n }\n\n const selection = toSkillSelection(result.answers as SkillSelectAnswers)\n const ranked = shortlist.map((s) => ({\n ...s,\n p: selection.ranked.find((r) => r.name === s.name)?.p ?? 0,\n })).sort((a, b) => (b.p ?? 0) - (a.p ?? 0))\n\n // Read anyRelevant FIRST. The Choice named something regardless.\n if (selection.anyRelevant < minRelevant) {\n return {\n skill: null, anyRelevant: selection.anyRelevant, confidence: selection.confidence,\n shortlist: ranked, judged: true,\n reason: `nothing on the shortlist is about this task (${selection.anyRelevant.toFixed(2)} below ${minRelevant})`,\n }\n }\n\n const chosen = lexical.find((m) => m.skill.frontmatter.name === selection.name)\n if (!chosen) {\n // Named something outside the option set. Refuse rather than guess.\n return {\n skill: null, anyRelevant: selection.anyRelevant, confidence: selection.confidence,\n shortlist: ranked, judged: true,\n reason: `seat chose \"${selection.name}\", which was not on the shortlist`,\n }\n }\n\n return {\n skill: chosen.skill, anyRelevant: selection.anyRelevant,\n confidence: selection.confidence, shortlist: ranked, judged: true,\n reason: `${selection.name} (confidence ${selection.confidence.toFixed(2)})`,\n }\n}\n","import { choice, noul } from \"../questions\"\nimport type { AnswersFor, ChoiceAnswer, NoulAnswer, StateValue } from \"../types\"\n\n// Which skill, if any, a task should start from.\n//\n// The incumbent is matchSkillsToTask() in agent/skills/loader.ts: regex\n// triggers at 0.9, tag overlap at 0.3 per tag capped at 0.8, shared words\n// over four characters at 0.2 each capped at 0.6, and anything over 0.1\n// gets used. Those numbers are not wrong so much as unexamined — they were\n// chosen to make a lexical score come out roughly sorted, and they answer\n// \"which skill shares the most words with this sentence\", which is a\n// different question from \"which skill is this task about\".\n//\n// The lexical matcher stays. It is free, it runs with no network, and it\n// is a perfectly good way to narrow a hundred skills down to a handful.\n// This seat re-ranks that handful, which is the same division of labour as\n// wiki-rerank: cheap recall first, judgement second.\n//\n// `anyRelevant` is read FIRST and is the more valuable of the two answers.\n// A Choice over skills always names one, and the failure that matters here\n// is not picking the wrong skill — it is loading a skill at all for a task\n// that needed none, which spends context on instructions that do not\n// apply and quietly steers the agent toward them.\n//\n// One thing this seat can do that the incumbent cannot: rank by what a\n// skill is FOR. The lexical path needs an author to have written trigger\n// patterns and tags by hand, and across ten agent workspaces and 101 skill\n// files, exactly zero have opted into auto-injection. A description is\n// something every skill already has.\n\nexport const SKILL_SELECT_SEAT = \"skill-select\"\n\n/** Enough to judge a skill by, small enough that a dozen fit in one\n * request. The instructions themselves are deliberately excluded — they\n * are thousands of tokens each and the description is what says what the\n * skill is for. */\nexport interface SkillCandidate {\n name: string\n description: string\n category?: string | null\n tags?: string[]\n}\n\nexport interface SkillSelectInput {\n /** The task, in the words it arrived in. */\n task: string\n /** Which agent is about to run it — a deploy skill means something\n * different to devops than to a content writer. */\n agent?: string | null\n candidates: SkillCandidate[]\n}\n\nexport function skillSelectState(input: SkillSelectInput): StateValue {\n return {\n task: clip(input.task, 1200),\n ...(input.agent ? { agent: input.agent } : {}),\n skills: input.candidates.map((c) => ({\n name: c.name,\n purpose: clip(c.description, 300),\n ...(c.category ? { category: c.category } : {}),\n ...(c.tags?.length ? { tags: c.tags.slice(0, 8) } : {}),\n })),\n }\n}\n\n/** Built per call — the option set IS the shortlist. */\nexport function skillSelectQuestions(candidates: SkillCandidate[]) {\n const criteria: Record<string, string> = {}\n for (const c of candidates) criteria[c.name] = clip(c.description, 300)\n\n return {\n anyRelevant: noul(\n \"At least one of these skills is about the task at hand.\",\n {\n true:\n \"The task is the kind of work one of these skills exists for, and following it would change how the work is done — it names the same system, the same procedure or the same kind of artefact.\",\n false:\n \"None of them is about this task. They may share vocabulary with it, mention the same tools, or belong to the same project without bearing on what is being asked. Sharing words with a task is not being about it.\",\n },\n ),\n best: choice(criteria, \"Which skill is this task most about?\"),\n }\n}\n\nexport type SkillSelectAnswers = AnswersFor<ReturnType<typeof skillSelectQuestions>>\n\nexport interface SkillSelection {\n /** P(any of the shortlist applies). Read before `name`. */\n anyRelevant: number\n name: string\n /** Derived from the shape of the probabilities, never self-reported. */\n confidence: number\n ranked: Array<{ name: string; p: number }>\n}\n\nexport function toSkillSelection(answers: SkillSelectAnswers): SkillSelection {\n const any = answers.anyRelevant as NoulAnswer\n const best = answers.best as ChoiceAnswer\n const ranked = Object.entries(best.probabilities ?? {})\n .map(([name, p]) => ({ name, p: Number(p) || 0 }))\n .sort((a, b) => b.p - a.p)\n return {\n anyRelevant: any.noul,\n name: best.choice,\n confidence: best.confidence,\n ranked,\n }\n}\n\nfunction clip(s: string, max: number): string {\n return s.length > max ? `${s.slice(0, max)}…` : s\n}\n"],"mappings":"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","names":["init_seat","init_questions","SKILL_SELECT_SEAT","skillSelectState","input","clip","c","skillSelectQuestions","candidates","criteria","noul","choice","toSkillSelection","answers","any","best","ranked","name","p","a","b","s","max","SHORTLIST_FLOOR","SHORTLIST_SIZE","pickSkillForTask","skills","task","opts","minRelevant","lexical","matchSkillsToTask","m","shortlist","candidates","result","askSeat","SKILL_SELECT_SEAT","skillSelectState","skillSelectQuestions","selection","toSkillSelection","ranked","s","r","a","b","chosen"]}
|
|
1
|
+
{"version":3,"sources":["../src/agent/skills/select.ts","../src/decisions/seats/skill-select.ts"],"sourcesContent":["import { askSeat } from \"@/decisions/seat\"\nimport {\n SKILL_SELECT_SEAT,\n skillSelectQuestions,\n skillSelectState,\n toSkillSelection,\n type SkillCandidate,\n type SkillSelectAnswers,\n} from \"@/decisions/seats/skill-select\"\nimport { matchSkillsToTask } from \"./loader\"\nimport type { Skill } from \"./types\"\n\n// Choosing a skill for a task, in two stages.\n//\n// 1. matchSkillsToTask — lexical, free, no network. Narrows a hundred\n// skills to a handful. Good at recall, indifferent about precision.\n// 2. the skill-select seat — judgement over that handful.\n//\n// Same division as wiki-rerank, and for the same reason: the cheap stage\n// is the one that has to look at everything.\n//\n// Stage 1 only sees skills whose author wrote trigger patterns or tags, so\n// it is also the stage that limits what is reachable. SHORTLIST_FLOOR is\n// deliberately lower than the injection threshold the incumbent uses —\n// recall is stage one's job, and the seat is what says no.\n\n/** Below this the lexical matcher is reporting noise, but the bar is low\n * on purpose: a skill the shortlist never mentions cannot be chosen. */\nconst SHORTLIST_FLOOR = 0.1\n\n/** How many the seat is asked to judge. Beyond a dozen the request grows\n * without the answer improving — the lexical stage is not sorting well\n * enough for the twelfth candidate to be a contender. */\nconst SHORTLIST_SIZE = 12\n\nexport interface SkillPick {\n /** The chosen skill, or null when nothing applies. */\n skill: Skill | null\n /** P(any shortlisted skill is about this task). */\n anyRelevant: number\n confidence: number\n /** What the lexical stage put forward, best first. */\n shortlist: Array<{ name: string; lexical: number; p?: number }>\n /** True when the seat answered; false when this is the lexical result\n * alone, because a seat that is off must not look like a judgement. */\n judged: boolean\n reason: string\n}\n\n/**\n * Rank a workspace's skills against a task.\n *\n * Returns a pick, never applies it — whether a skill is loaded, suggested\n * or ignored is the caller's policy, and this deliberately has no opinion\n * about per-turn context injection.\n */\nexport async function pickSkillForTask(\n skills: Skill[],\n task: string,\n opts: { agent?: string | null; minRelevant?: number } = {},\n): Promise<SkillPick> {\n const minRelevant = opts.minRelevant ?? 0.6\n\n const lexical = matchSkillsToTask(skills, task)\n .filter((m) => m.relevance >= SHORTLIST_FLOOR)\n .slice(0, SHORTLIST_SIZE)\n\n const shortlist = lexical.map((m) => ({\n name: m.skill.frontmatter.name,\n lexical: m.relevance,\n }))\n\n if (lexical.length === 0) {\n return {\n skill: null, anyRelevant: 0, confidence: 0, shortlist, judged: false,\n reason: \"no skill mentions anything in this task\",\n }\n }\n\n // One candidate is not a choice. Still worth asking whether it applies,\n // but a Choice over a single option carries no information, so the\n // lexical score stands and the Noul is not paid for either.\n if (lexical.length === 1) {\n return {\n skill: lexical[0].skill, anyRelevant: lexical[0].relevance,\n confidence: lexical[0].relevance, shortlist, judged: false,\n reason: `only ${lexical[0].skill.frontmatter.name} matched (${lexical[0].matchReason})`,\n }\n }\n\n const candidates: SkillCandidate[] = lexical.map((m) => ({\n name: m.skill.frontmatter.name,\n description: m.skill.frontmatter.description,\n category: m.skill.frontmatter.category ?? null,\n tags: m.skill.frontmatter.tags,\n }))\n\n const result = await askSeat(\n SKILL_SELECT_SEAT,\n skillSelectState({ task, agent: opts.agent ?? null, candidates }),\n skillSelectQuestions(candidates),\n {\n // What the lexical matcher would have done, so agreement between the\n // two is measurable rather than assumed.\n incumbent: { best: candidates[0].name },\n features: { agent: opts.agent ?? \"unknown\", candidates: candidates.length },\n },\n )\n\n if (!result) {\n return {\n skill: lexical[0].skill, anyRelevant: lexical[0].relevance,\n confidence: lexical[0].relevance, shortlist, judged: false,\n reason: `seat off — lexical top match (${lexical[0].matchReason})`,\n }\n }\n\n const selection = toSkillSelection(result.answers as SkillSelectAnswers)\n const ranked = shortlist.map((s) => ({\n ...s,\n p: selection.ranked.find((r) => r.name === s.name)?.p ?? 0,\n })).sort((a, b) => (b.p ?? 0) - (a.p ?? 0))\n\n // Read anyRelevant FIRST. The Choice named something regardless.\n if (selection.anyRelevant < minRelevant) {\n return {\n skill: null, anyRelevant: selection.anyRelevant, confidence: selection.confidence,\n shortlist: ranked, judged: true,\n reason: `nothing on the shortlist is about this task (${selection.anyRelevant.toFixed(2)} below ${minRelevant})`,\n }\n }\n\n const chosen = lexical.find((m) => m.skill.frontmatter.name === selection.name)\n if (!chosen) {\n // Named something outside the option set. Refuse rather than guess.\n return {\n skill: null, anyRelevant: selection.anyRelevant, confidence: selection.confidence,\n shortlist: ranked, judged: true,\n reason: `seat chose \"${selection.name}\", which was not on the shortlist`,\n }\n }\n\n return {\n skill: chosen.skill, anyRelevant: selection.anyRelevant,\n confidence: selection.confidence, shortlist: ranked, judged: true,\n reason: `${selection.name} (confidence ${selection.confidence.toFixed(2)})`,\n }\n}\n","import { choice, noul } from \"../questions\"\nimport type { AnswersFor, ChoiceAnswer, NoulAnswer, StateValue } from \"../types\"\n\n// Which skill, if any, a task should start from.\n//\n// The incumbent is matchSkillsToTask() in agent/skills/loader.ts: regex\n// triggers at 0.9, tag overlap at 0.3 per tag capped at 0.8, shared words\n// over four characters at 0.2 each capped at 0.6, and anything over 0.1\n// gets used. Those numbers are not wrong so much as unexamined — they were\n// chosen to make a lexical score come out roughly sorted, and they answer\n// \"which skill shares the most words with this sentence\", which is a\n// different question from \"which skill is this task about\".\n//\n// The lexical matcher stays. It is free, it runs with no network, and it\n// is a perfectly good way to narrow a hundred skills down to a handful.\n// This seat re-ranks that handful, which is the same division of labour as\n// wiki-rerank: cheap recall first, judgement second.\n//\n// `anyRelevant` is read FIRST and is the more valuable of the two answers.\n// A Choice over skills always names one, and the failure that matters here\n// is not picking the wrong skill — it is loading a skill at all for a task\n// that needed none, which spends context on instructions that do not\n// apply and quietly steers the agent toward them.\n//\n// One thing this seat can do that the incumbent cannot: rank by what a\n// skill is FOR. The lexical path needs an author to have written trigger\n// patterns and tags by hand, and across ten agent workspaces and 101 skill\n// files, exactly zero have opted into auto-injection. A description is\n// something every skill already has.\n\nexport const SKILL_SELECT_SEAT = \"skill-select\"\n\n/** Enough to judge a skill by, small enough that a dozen fit in one\n * request. The instructions themselves are deliberately excluded — they\n * are thousands of tokens each and the description is what says what the\n * skill is for. */\nexport interface SkillCandidate {\n name: string\n description: string\n category?: string | null\n tags?: string[]\n}\n\nexport interface SkillSelectInput {\n /** The task, in the words it arrived in. */\n task: string\n /** Which agent is about to run it — a deploy skill means something\n * different to devops than to a content writer. */\n agent?: string | null\n candidates: SkillCandidate[]\n}\n\nexport function skillSelectState(input: SkillSelectInput): StateValue {\n return {\n task: clip(input.task, 1200),\n ...(input.agent ? { agent: input.agent } : {}),\n skills: input.candidates.map((c) => ({\n name: c.name,\n purpose: clip(c.description, 300),\n ...(c.category ? { category: c.category } : {}),\n ...(c.tags?.length ? { tags: c.tags.slice(0, 8) } : {}),\n })),\n }\n}\n\n/** Built per call — the option set IS the shortlist. */\nexport function skillSelectQuestions(candidates: SkillCandidate[]) {\n const criteria: Record<string, string> = {}\n for (const c of candidates) criteria[c.name] = clip(c.description, 300)\n\n return {\n anyRelevant: noul(\n \"At least one of these skills is about the task at hand.\",\n {\n true:\n \"The task is the kind of work one of these skills exists for, and following it would change how the work is done — it names the same system, the same procedure or the same kind of artefact.\",\n false:\n \"None of them is about this task. They may share vocabulary with it, mention the same tools, or belong to the same project without bearing on what is being asked. Sharing words with a task is not being about it.\",\n },\n ),\n best: choice(criteria, \"Which skill is this task most about?\"),\n }\n}\n\nexport type SkillSelectAnswers = AnswersFor<ReturnType<typeof skillSelectQuestions>>\n\nexport interface SkillSelection {\n /** P(any of the shortlist applies). Read before `name`. */\n anyRelevant: number\n name: string\n /** Derived from the shape of the probabilities, never self-reported. */\n confidence: number\n ranked: Array<{ name: string; p: number }>\n}\n\nexport function toSkillSelection(answers: SkillSelectAnswers): SkillSelection {\n const any = answers.anyRelevant as NoulAnswer\n const best = answers.best as ChoiceAnswer\n const ranked = Object.entries(best.probabilities ?? {})\n .map(([name, p]) => ({ name, p: Number(p) || 0 }))\n .sort((a, b) => b.p - a.p)\n return {\n anyRelevant: any.noul,\n name: best.choice,\n confidence: best.confidence,\n ranked,\n }\n}\n\nfunction clip(s: string, max: number): string {\n return s.length > max ? `${s.slice(0, max)}…` : s\n}\n"],"mappings":"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","names":["init_seat","init_questions","SKILL_SELECT_SEAT","skillSelectState","input","clip","c","skillSelectQuestions","candidates","criteria","noul","choice","toSkillSelection","answers","any","best","ranked","name","p","a","b","s","max","SHORTLIST_FLOOR","SHORTLIST_SIZE","pickSkillForTask","skills","task","opts","minRelevant","lexical","matchSkillsToTask","m","shortlist","candidates","result","askSeat","SKILL_SELECT_SEAT","skillSelectState","skillSelectQuestions","selection","toSkillSelection","ranked","s","r","a","b","chosen"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{b as a}from"./chunk-
|
|
2
|
-
//# sourceMappingURL=set-enabled-
|
|
1
|
+
import{b as a}from"./chunk-QJP37VVA.js";import"./chunk-SIOWVLZG.js";import"./chunk-UIBUZ2N3.js";import"./chunk-BRK6M6LA.js";import"./chunk-2QNT5JDS.js";import"./chunk-QIJLFPWE.js";async function i(o,r,s={}){let e=null,n=await a(l=>{let t=l.crons?.[o];if(t?r&&t.approval?.action==="create"?e={ok:!1,status:409,error:`schedule "${o}" is waiting for approval: agentx schedule approve ${o}`}:t.enabled===r&&(e={ok:!0,id:o,enabled:r,changed:!1}):e={ok:!1,status:404,error:`no schedule "${o}"`},e)throw new Error("no write");t.enabled=r,e={ok:!0,id:o,enabled:r,changed:!0}},{configPath:s.configPath,reload:!1});return e&&(!e.ok||!e.changed)?e:n.success?e??{ok:!1,status:500,error:"mutation did not run"}:{ok:!1,status:500,error:n.error||"could not write agentx.json"}}export{i as setCronEnabled};
|
|
2
|
+
//# sourceMappingURL=set-enabled-U2HGNY2O.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a,b,c,d}from"./chunk-
|
|
2
|
-
//# sourceMappingURL=surface-usage-
|
|
1
|
+
import{a,b,c,d}from"./chunk-4FU4BFCH.js";import"./chunk-UIBUZ2N3.js";import"./chunk-QIJLFPWE.js";export{c as commandPath,b as listSurfaceUse,a as recordSurfaceUse,d as shouldRecordCommand};
|
|
2
|
+
//# sourceMappingURL=surface-usage-HCJTUS6Z.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{b as g}from"./chunk-
|
|
1
|
+
import{b as g}from"./chunk-WSKQUKCF.js";import"./chunk-RKPAVWXF.js";import{b as h}from"./chunk-LLNPKE7H.js";import"./chunk-SHEUCITK.js";import"./chunk-WXQQO2PD.js";import"./chunk-M2L6S3Z5.js";import"./chunk-QJP37VVA.js";import"./chunk-FCPTN6NF.js";import"./chunk-7I7IEX4S.js";import"./chunk-SIOWVLZG.js";import"./chunk-UIBUZ2N3.js";import"./chunk-BRK6M6LA.js";import"./chunk-2QNT5JDS.js";import"./chunk-QIJLFPWE.js";var $=t=>typeof t=="string"?t.trim():"",w={in_progress:"in progress",waiting_owner:"waiting on the owner",waiting_other:"waiting on another agent",needs_attention:"needs attention"};function f(t){return t.length?t.map(e=>{let i=new Date(e.createdAt).toISOString().slice(0,16).replace("T"," "),a=e.state==="waiting_owner"&&e.question?` Question: ${e.question}`:e.state==="needs_attention"&&e.attentionReason?` ${e.attentionReason}`:"",n=String(e.text).replace(/\s+/g," ").trim();return`- ${e.id} [${w[e.state]??e.state}] ${i} UTC, ${e.channel}, ${e.agentId}: ${n.length>160?`${n.slice(0,159)}\u2026`:n}.${a}`}).join(`
|
|
2
2
|
`):"No open requests."}async function m(t,e){let i=e.fetch??fetch,a=e.daemonUrl.replace(/\/$/,""),n=($(t.action)||"list").toLowerCase();try{if(n==="list"){let d=await i(`${a}/requests`,{signal:AbortSignal.timeout(1e4)}),r=await d.json().catch(()=>({}));return d.ok?r.enabled?`${r.count} open request${r.count===1?"":"s"}, oldest first.
|
|
3
3
|
${f(r.items??[])}`:"Requests are turned off on this node (requests.enabled), so nothing is recorded.":`Error: ${r?.error||`HTTP ${d.status}`}`}let s=e.env??process.env,u=g(t,s);if(!u)return"Error: couldn't tell which agent you are. Pass callerAgentId.";let c=await i(`${a}/requests`,{method:"POST",headers:{"Content-Type":"application/json",...h(s)},body:JSON.stringify({action:n,agentId:u.agentId,id:t.id,question:t.question,evidence:t.evidence,reason:t.reason}),signal:AbortSignal.timeout(1e4)}),l=await c.json().catch(()=>({}));if(!c.ok)return`Error: ${l?.error||`HTTP ${c.status}`}`;let o=l.request;return n==="accept"?`Request ${o.id} is open and in progress. Close it with done (and a link to the evidence) or decline (and the reason); it stays on the owner's list until then.`:n==="wait"?`Request ${o.id} is waiting on the owner with your question. Ask them the question now, once.`:n==="done"?`Request ${o.id} is closed as done. Evidence: ${o.evidence}`:`Request ${o.id} is closed as declined. Reason: ${o.closeReason}`}catch(s){return`Error: couldn't reach the daemon (${s?.message??s}).`}}export{f as describeOpen,m as runRequestTool};
|
|
4
|
-
//# sourceMappingURL=tool-
|
|
4
|
+
//# sourceMappingURL=tool-2FMWZB4N.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{b as h}from"./chunk-
|
|
1
|
+
import{b as h}from"./chunk-WSKQUKCF.js";import"./chunk-RKPAVWXF.js";import{b as u}from"./chunk-LLNPKE7H.js";import"./chunk-SHEUCITK.js";import{f}from"./chunk-Y4CYQV7G.js";import"./chunk-WXQQO2PD.js";import"./chunk-M2L6S3Z5.js";import"./chunk-QJP37VVA.js";import"./chunk-FCPTN6NF.js";import"./chunk-7I7IEX4S.js";import"./chunk-SIOWVLZG.js";import"./chunk-UIBUZ2N3.js";import"./chunk-BRK6M6LA.js";import"./chunk-2QNT5JDS.js";import"./chunk-QIJLFPWE.js";var m=new Set(["cron","heartbeat","api","a2a","mesh","approvals","requests"]);function y(e){return typeof e=="string"?e.trim():""}async function A(e,i){let c=i.fetch??fetch,d=i.daemonUrl.replace(/\/$/,""),s=(y(e.action)||"create").toLowerCase(),r=h(e,i.env??process.env);if(s==="status"){let o=y(e.id);if(!o)return"Error: `id` is required for status (the card id you got when you raised it).";try{let n=await c(`${d}/approvals/${encodeURIComponent(o)}`,{signal:AbortSignal.timeout(1e4)}),a=await n.json().catch(()=>({}));if(!n.ok)return`Error: ${a?.error||`HTTP ${n.status}`}`;let t=a.card;if(r&&t.raised_by!==r.agentId)return`Error: card "${o}" was raised by another agent.`;if(t.status==="pending")return`Card ${t.id} is still waiting for the operator. It expires ${t.expires}; then "${t.if_silent}" applies.`;if(t.status==="decided"){let p=t.verdict==="yes"?f(t).join(`
|
|
2
2
|
`):"";return`Card ${t.id}: the operator said ${String(t.verdict).toUpperCase()}.${t.note?` Note: ${t.note}`:""}${p?`
|
|
3
3
|
${p}`:""}`}return`Card ${t.id} expired unanswered; the default applied: ${t.outcome??t.if_silent}.`}catch(n){return`Error: couldn't reach the daemon (${n?.message??n}).`}}if(s!=="create")return`Error: unknown action "${s}". Use create or status.`;if(!r)return"Error: couldn't tell which agent you are. Pass callerAgentId.";let l=r.channel&&r.chatId&&!m.has(r.channel)?{channel:r.channel,chatId:r.chatId,...r.accountId?{accountId:r.accountId}:{}}:void 0,$={title:e.title,ask:e.ask,recommend:e.recommend,if_silent:e.if_silent,expires:e.expires,source:e.source,choices:e.choices,draft:e.draft,say:e.say,context:e.context,raised_by:r.agentId,...l?{reply:l}:{}};try{let o=await c(`${d}/approvals`,{method:"POST",headers:{"Content-Type":"application/json",...u(i.env??process.env)},body:JSON.stringify($),signal:AbortSignal.timeout(1e4)}),n=await o.json().catch(()=>({}));if(!o.ok)return`Error: ${n?.error||`HTTP ${o.status}`}`;let a=n.card;return[`Decision card ${a.id} is in the operator's Approvals inbox.`,`If nobody answers by ${a.expires}, "${a.if_silent}" applies.`,"You will get a message with the result. Tell the requester it is waiting for approval; don't ask the operator again in chat."].join(" ")}catch(o){return`Error: couldn't reach the daemon (${o?.message??o}).`}}export{A as runApprovalTool};
|
|
4
|
-
//# sourceMappingURL=tool-
|
|
4
|
+
//# sourceMappingURL=tool-TX622HEB.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"./chunk-VWTBHLMX.js";import{a as b}from"./chunk-DXWDVKMX.js";import{a}from"./chunk-Z7L74GGT.js";import"./chunk-CECHWYJ2.js";import{a as c}from"./chunk-FBODSJU6.js";import"./chunk-RS2T53EC.js";import"./chunk-WPNRDEHW.js";import"./chunk-2GIDVZ4H.js";import"./chunk-GQMUFSKB.js";import"./chunk-72SZI2UW.js";import"./chunk-FX3D7YON.js";import"./chunk-FCPTN6NF.js";import"./chunk-QOYAX2FT.js";import"./chunk-5MUJZODV.js";import"./chunk-7I7IEX4S.js";import"./chunk-SIOWVLZG.js";import"./chunk-UIBUZ2N3.js";import"./chunk-BRK6M6LA.js";import"./chunk-2QNT5JDS.js";import"./chunk-RGDKHYY2.js";import"./chunk-QIJLFPWE.js";export{b as WikiHub,a as WikiStore,c as agenticQuery};
|
|
2
|
+
//# sourceMappingURL=wiki-MYJBOJSM.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{l as a,m as b,n as c,o as d,p as e,q as f}from"./chunk-AV7T3SYT.js";import"./chunk-QIJLFPWE.js";export{b as generateClaudeMd,d as patchGuardrails,e as patchObservationPack,a as readManagedHash,f as setupAllWorkspaces,c as setupWorkspace};
|
|
2
|
+
//# sourceMappingURL=workspace-setup-HAV4CQV7.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentix-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.111.0",
|
|
4
4
|
"description": "AI operations layer for small and medium businesses. Routes Telegram, WhatsApp, GitLab, GitHub, crons, webhooks, and mesh tasks to AI agents. Web wizard for operators, CLI for engineers. Self-hosted.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -74,6 +74,7 @@
|
|
|
74
74
|
"docs:demo": "node dist/cli.js demo --no-open --keep",
|
|
75
75
|
"docs:seed": "node docs/.scripts/seed-demo.mjs",
|
|
76
76
|
"docs:shots": "node docs/.scripts/capture.mjs",
|
|
77
|
+
"docs:shots:mobile": "node docs/.scripts/capture-mobile.mjs",
|
|
77
78
|
"docs:preview": "vitepress preview docs",
|
|
78
79
|
"prepublishOnly": "npm run build",
|
|
79
80
|
"postinstall": "node scripts/postinstall.mjs"
|