agentix-cli 0.48.0 → 0.49.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/AgentClient.swift +17 -5
- package/apps/mac-voice/Sources/AgentXVoice/Config.swift +6 -1
- package/apps/mac-voice/Sources/AgentXVoice/main.swift +5 -2
- package/dist/{App-EXB4HP3B.js → App-KE4SURSS.js} +2 -2
- package/dist/{ChatApp-XMNE3SPH.js → ChatApp-NNHIKXO2.js} +2 -2
- package/dist/{agent-ORYXXL5K.js → agent-J7SLJYQ6.js} +2 -2
- package/dist/{board-dashboard-2B3HYIXD.js → board-dashboard-LG3ECH7C.js} +5 -5
- package/dist/board-dashboard-LG3ECH7C.js.map +1 -0
- package/dist/{chunk-GIK7S3OY.js → chunk-3L2FKVR6.js} +7 -7
- package/dist/chunk-3L2FKVR6.js.map +1 -0
- package/dist/{chunk-26OP3X5B.js → chunk-4NBWF4TL.js} +2 -2
- package/dist/{chunk-P7MR53U7.js → chunk-4TITGMPX.js} +2 -2
- package/dist/{chunk-XM7ZQW4F.js → chunk-5ALS7SVV.js} +2 -2
- package/dist/{chunk-3ZHMIWSV.js → chunk-5XQCGPQJ.js} +2 -2
- package/dist/{chunk-FRHSQVFN.js → chunk-AQASR6KR.js} +3 -3
- package/dist/chunk-AQASR6KR.js.map +1 -0
- package/dist/{chunk-M5R3PWW5.js → chunk-B5XHX44Y.js} +2 -2
- package/dist/{chunk-DIV66W3N.js → chunk-DTJKN5VT.js} +10 -10
- package/dist/chunk-DTJKN5VT.js.map +1 -0
- package/dist/{chunk-OZX7HVHC.js → chunk-FM2GGPSD.js} +172 -165
- package/dist/chunk-FM2GGPSD.js.map +1 -0
- package/dist/{chunk-4ZX4E7P3.js → chunk-HGT4AKOH.js} +7 -7
- package/dist/chunk-HGT4AKOH.js.map +1 -0
- package/dist/{chunk-ZUZESPCH.js → chunk-HVQJIROJ.js} +64 -64
- package/dist/chunk-HVQJIROJ.js.map +1 -0
- package/dist/{chunk-MLLEOFX2.js → chunk-IXUEJBHD.js} +2 -2
- package/dist/{chunk-LDILAHMN.js → chunk-JVNFRS26.js} +2 -2
- package/dist/{chunk-SL657MIM.js → chunk-MWUJOAAW.js} +2 -2
- package/dist/{chunk-DJQA2CWD.js → chunk-N6EWZGIX.js} +6 -6
- package/dist/{chunk-DJQA2CWD.js.map → chunk-N6EWZGIX.js.map} +1 -1
- package/dist/{chunk-HEQPHUTR.js → chunk-NLZD2QKF.js} +2 -2
- package/dist/chunk-OHA3J5ZV.js +243 -0
- package/dist/chunk-OHA3J5ZV.js.map +1 -0
- package/dist/{chunk-P5JXQRBH.js → chunk-OTW5MPFT.js} +2 -2
- package/dist/{chunk-WMI5B36E.js → chunk-OUZ7YVQZ.js} +2 -2
- package/dist/{chunk-GAGVFSZM.js → chunk-P2ZYT5D6.js} +2 -2
- package/dist/chunk-P2ZYT5D6.js.map +1 -0
- package/dist/{chunk-2WPTP5HO.js → chunk-PZCTCCC5.js} +2 -2
- package/dist/chunk-Q7C3X3R6.js +61 -0
- package/dist/chunk-Q7C3X3R6.js.map +1 -0
- package/dist/{chunk-3WLO2UKI.js → chunk-QDE75R4U.js} +2 -2
- package/dist/{chunk-2GSEEKQK.js → chunk-RKAJR37K.js} +2 -2
- package/dist/{chunk-SFLF64Q3.js → chunk-Z3IP66SL.js} +2 -2
- package/dist/cli.js +1 -1
- package/dist/client-JZTH46N2.js +2 -0
- package/dist/{config-ROQ4VEU3.js → config-R47ITLIY.js} +2 -2
- package/dist/config-mutator-T6JGXJ26.js +2 -0
- package/dist/context-planner-FJMU5WAT.js +17 -0
- package/dist/context-planner-FJMU5WAT.js.map +1 -0
- package/dist/doctor-2DMGAWMW.js +2 -0
- package/dist/failure-candidates-ARRMFXRY.js +8 -0
- package/dist/failure-candidates-ARRMFXRY.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +1 -1
- package/dist/program-3CDFUJVE.js +2 -0
- package/dist/promote-57YNOVXV.js +2 -0
- package/dist/proposals-TX2HBBYV.js +2 -0
- package/dist/query-ZT7WXY2F.js +2 -0
- package/dist/registry-722GXALE.js +2 -0
- package/dist/{request-planner-FAFNFVFX.js → request-planner-PEAYYXAP.js} +2 -2
- package/dist/{review-candidates-2XKJ2R6U.js → review-candidates-W7NIHNAI.js} +2 -2
- package/dist/{routing-PUPVGJ77.js → routing-7LCO7UJ7.js} +2 -2
- package/dist/schedule-tool-ZD3VBUBW.js +2 -0
- package/dist/scheduler-GC3FQKXY.js +2 -0
- package/dist/{seat-2MW3DEXX.js → seat-HR6QMAR2.js} +2 -2
- package/dist/{select-Q3AGLQQX.js → select-4XYRIZ5L.js} +2 -2
- package/dist/{surface-usage-FM2ZHGYE.js → surface-usage-V2BX4SBD.js} +2 -2
- package/dist/{tool-IVUNSAXY.js → tool-PAQ47HV2.js} +2 -2
- package/dist/wiki-EREMPSAE.js +2 -0
- package/package.json +1 -1
- package/dist/board-dashboard-2B3HYIXD.js.map +0 -1
- package/dist/chunk-4ZX4E7P3.js.map +0 -1
- package/dist/chunk-DIV66W3N.js.map +0 -1
- package/dist/chunk-FRHSQVFN.js.map +0 -1
- package/dist/chunk-GAGVFSZM.js.map +0 -1
- package/dist/chunk-GIK7S3OY.js.map +0 -1
- package/dist/chunk-OZX7HVHC.js.map +0 -1
- package/dist/chunk-RYLTCOYE.js +0 -241
- package/dist/chunk-RYLTCOYE.js.map +0 -1
- package/dist/chunk-WZGABQ72.js +0 -59
- package/dist/chunk-WZGABQ72.js.map +0 -1
- package/dist/chunk-ZUZESPCH.js.map +0 -1
- package/dist/client-6HCY7UMW.js +0 -2
- package/dist/config-mutator-ML4BAOFT.js +0 -2
- package/dist/context-planner-AQHJMVY2.js +0 -17
- package/dist/context-planner-AQHJMVY2.js.map +0 -1
- package/dist/doctor-3HWGAPET.js +0 -2
- package/dist/program-JLZOHWIU.js +0 -2
- package/dist/promote-YGNTKEXI.js +0 -2
- package/dist/proposals-MWMEXRDW.js +0 -2
- package/dist/query-V76JDSOC.js +0 -2
- package/dist/registry-DKN4HEI3.js +0 -2
- package/dist/schedule-tool-6J7AHAHH.js +0 -2
- package/dist/scheduler-ZHQBSSRH.js +0 -2
- package/dist/wiki-FPX2YBKS.js +0 -2
- /package/dist/{App-EXB4HP3B.js.map → App-KE4SURSS.js.map} +0 -0
- /package/dist/{ChatApp-XMNE3SPH.js.map → ChatApp-NNHIKXO2.js.map} +0 -0
- /package/dist/{agent-ORYXXL5K.js.map → agent-J7SLJYQ6.js.map} +0 -0
- /package/dist/{chunk-26OP3X5B.js.map → chunk-4NBWF4TL.js.map} +0 -0
- /package/dist/{chunk-P7MR53U7.js.map → chunk-4TITGMPX.js.map} +0 -0
- /package/dist/{chunk-XM7ZQW4F.js.map → chunk-5ALS7SVV.js.map} +0 -0
- /package/dist/{chunk-3ZHMIWSV.js.map → chunk-5XQCGPQJ.js.map} +0 -0
- /package/dist/{chunk-M5R3PWW5.js.map → chunk-B5XHX44Y.js.map} +0 -0
- /package/dist/{chunk-MLLEOFX2.js.map → chunk-IXUEJBHD.js.map} +0 -0
- /package/dist/{chunk-LDILAHMN.js.map → chunk-JVNFRS26.js.map} +0 -0
- /package/dist/{chunk-SL657MIM.js.map → chunk-MWUJOAAW.js.map} +0 -0
- /package/dist/{chunk-HEQPHUTR.js.map → chunk-NLZD2QKF.js.map} +0 -0
- /package/dist/{chunk-P5JXQRBH.js.map → chunk-OTW5MPFT.js.map} +0 -0
- /package/dist/{chunk-WMI5B36E.js.map → chunk-OUZ7YVQZ.js.map} +0 -0
- /package/dist/{chunk-2WPTP5HO.js.map → chunk-PZCTCCC5.js.map} +0 -0
- /package/dist/{chunk-3WLO2UKI.js.map → chunk-QDE75R4U.js.map} +0 -0
- /package/dist/{chunk-2GSEEKQK.js.map → chunk-RKAJR37K.js.map} +0 -0
- /package/dist/{chunk-SFLF64Q3.js.map → chunk-Z3IP66SL.js.map} +0 -0
- /package/dist/{client-6HCY7UMW.js.map → client-JZTH46N2.js.map} +0 -0
- /package/dist/{config-ROQ4VEU3.js.map → config-R47ITLIY.js.map} +0 -0
- /package/dist/{config-mutator-ML4BAOFT.js.map → config-mutator-T6JGXJ26.js.map} +0 -0
- /package/dist/{doctor-3HWGAPET.js.map → doctor-2DMGAWMW.js.map} +0 -0
- /package/dist/{program-JLZOHWIU.js.map → program-3CDFUJVE.js.map} +0 -0
- /package/dist/{promote-YGNTKEXI.js.map → promote-57YNOVXV.js.map} +0 -0
- /package/dist/{proposals-MWMEXRDW.js.map → proposals-TX2HBBYV.js.map} +0 -0
- /package/dist/{query-V76JDSOC.js.map → query-ZT7WXY2F.js.map} +0 -0
- /package/dist/{registry-DKN4HEI3.js.map → registry-722GXALE.js.map} +0 -0
- /package/dist/{request-planner-FAFNFVFX.js.map → request-planner-PEAYYXAP.js.map} +0 -0
- /package/dist/{review-candidates-2XKJ2R6U.js.map → review-candidates-W7NIHNAI.js.map} +0 -0
- /package/dist/{routing-PUPVGJ77.js.map → routing-7LCO7UJ7.js.map} +0 -0
- /package/dist/{schedule-tool-6J7AHAHH.js.map → schedule-tool-ZD3VBUBW.js.map} +0 -0
- /package/dist/{scheduler-ZHQBSSRH.js.map → scheduler-GC3FQKXY.js.map} +0 -0
- /package/dist/{seat-2MW3DEXX.js.map → seat-HR6QMAR2.js.map} +0 -0
- /package/dist/{select-Q3AGLQQX.js.map → select-4XYRIZ5L.js.map} +0 -0
- /package/dist/{surface-usage-FM2ZHGYE.js.map → surface-usage-V2BX4SBD.js.map} +0 -0
- /package/dist/{tool-IVUNSAXY.js.map → tool-PAQ47HV2.js.map} +0 -0
- /package/dist/{wiki-FPX2YBKS.js.map → wiki-EREMPSAE.js.map} +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import{a as i,b as c}from"./chunk-ZTEU5JVQ.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(`
|
|
2
|
+
INSERT INTO task_traces (
|
|
3
|
+
task_id, agent_id, channel, chat_id, workflow_run_id, workflow_id,
|
|
4
|
+
workflow_node_id, intent_event_id, intent_decided_by, resume_session_id,
|
|
5
|
+
model, status, started_at, message_preview, original_message,
|
|
6
|
+
resume_origin, resume_attempt, resumed_from
|
|
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),t}function T(e,n,t){let r=Date.now();e.prepare(`
|
|
9
|
+
UPDATE task_traces SET
|
|
10
|
+
status = ?,
|
|
11
|
+
final_session_id = ?,
|
|
12
|
+
input_tokens = ?,
|
|
13
|
+
output_tokens = ?,
|
|
14
|
+
cache_read_tokens = ?,
|
|
15
|
+
cache_create_tokens = ?,
|
|
16
|
+
tier2_input_tokens = ?,
|
|
17
|
+
tier2_output_tokens = ?,
|
|
18
|
+
tier2_cache_read_tokens = ?,
|
|
19
|
+
tier2_cache_create_tokens = ?,
|
|
20
|
+
resumed = COALESCE(?, resumed),
|
|
21
|
+
resume_session_id = COALESCE(?, resume_session_id),
|
|
22
|
+
jev_arm = COALESCE(?, jev_arm),
|
|
23
|
+
num_turns = COALESCE(?, num_turns),
|
|
24
|
+
injected_context = COALESCE(?, injected_context),
|
|
25
|
+
error = ?,
|
|
26
|
+
final_response = COALESCE(?, final_response),
|
|
27
|
+
finished_at = ?,
|
|
28
|
+
duration_ms = ? - started_at
|
|
29
|
+
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
|
+
INSERT INTO task_trace_steps (
|
|
32
|
+
task_id, seq, name, action, status, input_summary, output_summary, error, ms, started_at
|
|
33
|
+
) 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
|
+
UPDATE task_traces
|
|
36
|
+
SET status = 'canceled',
|
|
37
|
+
error = 'daemon-restart (orphaned in-flight)',
|
|
38
|
+
finished_at = ?
|
|
39
|
+
WHERE status = 'in-flight'
|
|
40
|
+
`).run(n).changes??0}function C(e,n=Date.now()){let t=e.transaction(()=>{let s=e.prepare(`
|
|
41
|
+
SELECT task_id, agent_id, channel, chat_id, workflow_run_id, started_at,
|
|
42
|
+
original_message, resume_origin, resume_attempt
|
|
43
|
+
FROM task_traces WHERE status = 'in-flight' ORDER BY started_at
|
|
44
|
+
`).all();return e.prepare(`
|
|
45
|
+
UPDATE task_traces
|
|
46
|
+
SET status = 'canceled', error = 'daemon-restart (interrupted)',
|
|
47
|
+
finished_at = ?, resume_decision = 'interrupted'
|
|
48
|
+
WHERE status = 'in-flight'
|
|
49
|
+
`).run(n),s}),r=e.prepare(`
|
|
50
|
+
SELECT action, input_summary FROM task_trace_steps
|
|
51
|
+
WHERE task_id = ? AND name = 'tool_use' ORDER BY seq
|
|
52
|
+
`);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
|
+
UPDATE task_traces SET resume_decision = 'deciding'
|
|
54
|
+
WHERE task_id = ? AND resume_decision = 'interrupted'
|
|
55
|
+
`).run(n).changes??0)===1}function A(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
|
+
SELECT * FROM task_traces
|
|
57
|
+
${t.length>0?"WHERE "+t.join(" AND "):""}
|
|
58
|
+
ORDER BY started_at DESC
|
|
59
|
+
LIMIT ?
|
|
60
|
+
`;return r.push(s),e.prepare(a).all(...r).map(d)}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,A as j,D as k};
|
|
61
|
+
//# sourceMappingURL=chunk-Q7C3X3R6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/agents/injected-context.ts","../src/storage/traces.ts"],"sourcesContent":["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","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}\n\nexport interface TraceEndInput {\n status: \"ok\" | \"error\" | \"timeout\"\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}\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\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 )\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 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 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"],"mappings":"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","names":["WIKI_MARKER","capIds","ids","id","injectedContextOf","assembled","candidates","text","m","p","boundInjectedContext","ctx","init_ulid","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"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as R,b as j,c as O,d as W,e as D}from"./chunk-AJ5RMU7X.js";import{b as C}from"./chunk-2GIDVZ4H.js";import{v,w as Q}from"./chunk-
|
|
1
|
+
import{a as R,b as j,c as O,d as W,e as D}from"./chunk-AJ5RMU7X.js";import{b as C}from"./chunk-2GIDVZ4H.js";import{v,w as Q}from"./chunk-4NBWF4TL.js";import{b as $,c as M}from"./chunk-QOYAX2FT.js";import{readFileSync as T,existsSync as _}from"fs";Q();import{resolve as b}from"path";import{execSync as Y}from"child_process";async function V(n,i,s,e={}){let d=e.selectorModel??"haiku",a=e.synthModel??"sonnet",c=e.maxCandidates??3,l=e.maxHops??2,r=e.maxArticles??8,p=e.timeoutMs??6e4,u=e.log??console.error.bind(console,"[wiki-query]"),h=b(i.baseDir,"_index.md");if(!_(h))return w("no-catalog",n,"No _index.md found \u2014 run `agentx wiki status` to rebuild.");let k=T(h,"utf-8"),t=Date.now(),g=[],m="";try{let o=await B(n,i,s,c);o?(g=o,m=`[wiki-rerank seat] ${o.map(y=>y.title).join(" | ")}`):(m=await N(I(n,k,c),d,p),g=F(m))}catch(o){return u("selector failed:",o?.message),{...w("error",n,`Selector: ${o?.message||"unknown"}`),trace:{selectorMs:Date.now()-t,synthesisMs:0,selectorOutput:m}}}let A=Date.now()-t;if(g.length===0)return{...w("no-candidates",n,"Selector returned no candidates."),trace:{selectorMs:A,synthesisMs:0,selectorOutput:m}};let f=E(g,i,s,l,r);if(f.length===0)return{...w("no-candidates",n,"Candidates did not resolve to readable articles."),candidates:g,trace:{selectorMs:A,synthesisMs:0,selectorOutput:m}};let S=Date.now(),x="";try{x=await N(L(n,f),a,p*2)}catch(o){return u("synthesis failed:",o?.message),{...w("error",n,`Synthesis: ${o?.message||"unknown"}`),candidates:g,walked:f.map(y=>({title:y.meta.title,path:y.path,type:y.meta.type,hop:y.hop??0})),trace:{selectorMs:A,synthesisMs:Date.now()-S,selectorOutput:m}}}let P=Date.now()-S;return{answer:x.trim(),citations:f.map(o=>({title:o.meta.title,path:o.path,type:o.meta.type})),candidates:g,walked:f.map(o=>({title:o.meta.title,path:o.path,type:o.meta.type,hop:o.hop??0})),status:"ok",trace:{selectorMs:A,synthesisMs:P,selectorOutput:m}}}function w(n,i,s){return{answer:"",citations:[],candidates:[],walked:[],status:n,error:s}}function E(n,i,s,e,d){let a=new Map;for(let r of i.listArticles(s||""))a.set(r.meta.title.toLowerCase(),r.path);let c=new Map,l=[];for(let r of n)c.has(r.path)||l.push({path:r.path,hop:0});for(;l.length&&c.size<d;){let r=l.shift();if(c.has(r.path)||r.hop>e)continue;let p=s?i.readArticleAs(r.path,s):i.readArticle(r.path);if(p&&(c.set(r.path,{...p,hop:r.hop}),!(r.hop>=e)))for(let u of p.meta.related||[]){let h=a.get(u.toLowerCase());h&&!c.has(h)&&l.push({path:h,hop:r.hop+1})}}return Array.from(c.values())}async function B(n,i,s,e){try{let a=(i.rebuildIndex().articles??[]).filter(t=>t.path&&!t.path.includes("/_versions/"));if(a.length<2)return null;let c=a.map(t=>[t.title,(t.tags??[]).join(" "),(t.related??[]).join(" ")].join(" ")),l=M(n,$(c)).map(t=>t.docIndex);for(let t=0;t<a.length;t++)l.includes(t)||l.push(t);let p=l.slice(0,j).map(t=>({id:`k${t}`,title:a[t].title||a[t].path,tags:a[t].tags,excerpt:[a[t].type?`type: ${a[t].type}`:"",(a[t].related??[]).length?`related: ${(a[t].related??[]).join(", ")}`:""].filter(Boolean).join(" \xB7 ")})),u=await v(R,O({query:n,candidates:p,excerptChars:300}),W(p),{features:{agent:s??"unknown",stage:"catalog-selector"}});if(!u||u.mode!=="active")return null;let k=D(u.answers,p).ranked.slice(0,e).map(t=>a[Number(t.slice(1))]).filter(Boolean).map(t=>({title:t.title,path:t.path}));return k.length>0?k:null}catch{return null}}function I(n,i,s){return`You are picking candidate articles from a wiki catalog to answer a question. You do NOT answer the question. You pick which articles the answer is likely to come from.
|
|
2
2
|
|
|
3
3
|
## Question
|
|
4
4
|
|
|
@@ -42,4 +42,4 @@ ${s}
|
|
|
42
42
|
Answer the question in 2\u20136 sentences. Cite articles by their title in square brackets like [Article Title]. If the articles do not answer the question, say so plainly (do not invent). Prefer concrete facts over hedging.
|
|
43
43
|
|
|
44
44
|
Output ONLY the answer \u2014 no preamble, no "here is my answer:", no markdown fencing.`}function F(n){let i=n.match(/\[[\s\S]*?\]/);if(!i)return[];try{let s=JSON.parse(i[0]);return Array.isArray(s)?s.filter(e=>e&&typeof e.title=="string"&&typeof e.path=="string").map(e=>({title:e.title,path:e.path})):[]}catch{return[]}}async function N(n,i,s){let{writeFileSync:e,mkdirSync:d,rmSync:a}=await import("fs"),{tmpdir:c}=await import("os"),l=b(c(),`agentx-wiki-query-${process.pid}`);d(l,{recursive:!0});let r=b(l,`prompt-${Date.now()}.txt`);e(r,n);try{let p=`cat '${r}' | claude -p - --output-format json --max-turns 1 --model ${i} --disallowedTools "Bash Read Write Edit Glob Grep Agent WebSearch WebFetch NotebookEdit"`,u=Y(p,{env:C({...process.env}),encoding:"utf-8",timeout:s,maxBuffer:4*1024*1024});try{let h=JSON.parse(u);return String(h.result||h.content||"")}catch{return u}}finally{try{a(r,{force:!0})}catch{}}}export{V as a};
|
|
45
|
-
//# sourceMappingURL=chunk-
|
|
45
|
+
//# sourceMappingURL=chunk-QDE75R4U.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{b as Q,c as Z,d as ee,e as F,f as I,g as j,h as W}from"./chunk-DLKRPK5M.js";import{a as G,b as V}from"./chunk-
|
|
1
|
+
import{b as Q,c as Z,d as ee,e as F,f as I,g as j,h as W}from"./chunk-DLKRPK5M.js";import{a as G,b as V}from"./chunk-NLZD2QKF.js";import{a as X}from"./chunk-IXUEJBHD.js";import{j as O,l as Y,m as B,p as M}from"./chunk-P2ZYT5D6.js";import{existsSync as _,readFileSync as le,writeFileSync as de,appendFileSync as $e,mkdirSync as Ae}from"fs";import{dirname as Se,resolve as R}from"path";import{fileURLToPath as Ie}from"url";import{hostname as Ce}from"os";import{spawn as Ee}from"child_process";M();import{existsSync as ne,readFileSync as te,writeFileSync as L,copyFileSync as be}from"fs";import{resolve as ae}from"path";function re(e,t={}){let n=t.configPath||ae(process.cwd(),"agentx.json");if(!ne(n))throw new Error(`agentx.json not found at ${n}`);let a=JSON.parse(te(n,"utf-8")),r=e(a),i=typeof r=="string"?{summary:r}:r,l=JSON.stringify(a,null,2)+`
|
|
2
2
|
`,p=n+".tmp";L(p,l,"utf-8");try{JSON.parse(te(p,"utf-8"))}catch(c){throw new Error(`config did not round-trip cleanly: ${c.message}`)}let s;return t.skipBackup||(s=`${n}.bak.${Date.now()}`,be(n,s)),L(n,l,"utf-8"),t.skipReload||ye().catch(()=>{}),{summary:i.summary,payload:i.payload,backupPath:s}}function ie(e,t={}){let n=t.configPath||ae(process.cwd(),"agentx.json");if(ne(n)&&!t.overwrite)throw new Error(`agentx.json already exists at ${n}. Pass overwrite=true to replace it.`);return L(n,JSON.stringify(e,null,2)+`
|
|
3
3
|
`,"utf-8"),{file:n}}async function ye(){try{let t=B().dashboard.daemonUrl?.replace(/\/+$/,"")||"http://127.0.0.1:18800";await fetch(`${t}/reload`,{method:"POST"}).catch(()=>null)}catch{}}function se(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">
|
|
4
4
|
<div class="ax-topbar__left">
|
|
@@ -737,4 +737,4 @@ tr:hover td { background: var(--bg-hover); }
|
|
|
737
737
|
<div class="meta-line">${P((c.meta.tags||[]).slice(0,6),t)}</div>
|
|
738
738
|
<h3><a href="${p}/article/${encodeURIComponent(c.path)}">${o(c.meta.title)}</a></h3>
|
|
739
739
|
</div>`;return $(`${t} \xB7 ${n}`,C(r),s)}function U(e,t,n){let a=e.rebuildIndex(),r=q(a.articles.map(l=>({title:l.title,path:l.path,tags:l.tags}))),i='<div class="nav-section">';i+=`<div class="nav-section-title">${o(t)}</div>`,i+=`<a class="nav-item${n?"":" active"}" href="/">Home</a>`,i+='<a class="nav-item" href="/lint">Health check</a>',i+="</div>";for(let[l,p]of r){i+='<div class="nav-section">',i+=`<div class="nav-section-title">${K(l)}</div>`;for(let s of p){let c=s.path===n;i+=`<a class="nav-item${c?" active":""}" href="/article/${encodeURIComponent(s.path)}">${o(s.title)}</a>`}i+="</div>"}return i}function et(e){let{wikiDir:t,agentFilter:n,peerUrls:a=[],mode:r="graph",pathPrefix:i=""}=e,l=i.replace(/\/+$/,""),p=new X(t,void 0,r),s=a.length>0?new D(a):null;return async(c,g)=>{let x=new URL(c.url||"/","http://localhost"),d=decodeURIComponent(x.pathname),h=l&&d.startsWith(l)?d.slice(l.length)||"/":d,f=null,T=200;try{if(h.startsWith("/remote/")&&s){let y=h.slice(8).split("/article/");if(y.length===2){let[b,v]=y,m=b.indexOf("/"),k=decodeURIComponent(b.slice(0,m)),u=b.slice(m+1),w=await s.getRemoteArticle(k,u,v);if(w){let z=await s.getRemoteAgents(),N=[...p.summary(),...z.map(S=>({...S,agentId:`${S.agentId} @${S.nodeId}`}))],A=`<div class="breadcrumb"><a href="/">Hub</a> / <span class="tag">remote</span> ${o(u)} @ ${o(k)}</div>`;A+=`<h1>${o(w.meta.title)}</h1>`,A+='<dl class="meta">',A+=`<dt>Tags</dt><dd>${(w.meta.tags||[]).map(S=>`<span class="tag">${S}</span>`).join(" ")}</dd>`,A+=`<dt>Owner</dt><dd>${o(w.meta.owner)}</dd>`,A+=`<dt>Source</dt><dd><span class="tag">remote</span> ${o(k)}</dd>`,A+=`<dt>Updated</dt><dd>${w.meta.lastUpdated}</dd>`,A+="</dl>";let E=new Map;A+=H(w.content,E),f=$(w.meta.title,C(N),A)}}}if(!f&&n){let y=p.getAgentWiki(n);if(h==="/"||h===""){let b=y.rebuildIndex(),v=p.getAgentEntries(n),m=`<h1>${o(n)}</h1>`;if(m+='<div class="stats">',m+=`<div class="stat-card"><div class="number">${b.articles.length}</div><div class="label">Articles</div></div>`,m+=`<div class="stat-card"><div class="number">${v.length}</div><div class="label">Entries</div></div>`,m+="</div>",b.articles.length>0){m+="<h2>Articles</h2><table><tr><th>Title</th><th>Type</th><th>Updated</th></tr>";for(let k of b.articles)m+=`<tr><td><a href="/article/${encodeURIComponent(k.path)}">${o(k.title)}</a></td><td><span class="tag">${(k.tags||[]).slice(0,3).join(", ")}</span></td><td>${k.lastUpdated||""}</td></tr>`;m+="</table>"}f=$(n,U(y,n),m)}else if(h.startsWith("/article/")){let b=h.slice(9),v=y.readArticle(b);if(v){let m=y.rebuildIndex(),k=new Map;for(let w of m.articles)k.set(w.title,w.path);let u=`<h1>${o(v.meta.title)}</h1>`;u+='<dl class="meta">',u+=`<dt>Tags</dt><dd>${(v.meta.tags||[]).map(w=>`<span class="tag">${w}</span>`).join(" ")}</dd>`,u+=`<dt>Updated</dt><dd>${v.meta.lastUpdated}</dd>`,v.meta.sources?.length&&(u+=`<dt>Sources</dt><dd>${v.meta.sources.length} entries</dd>`),u+="</dl>",u+=H(v.content,k),f=$(v.meta.title,U(y,n,b),u)}}else if(h==="/lint"){let b=y.lint(),v="<h1>Health Check</h1>";if(b.length===0)v+='<p style="color:green;">No issues.</p>';else{v+="<table><tr><th>Type</th><th>Article</th><th>Issue</th></tr>";for(let m of b)v+=`<tr><td><span class="tag">${m.type}</span></td><td>${o(m.article)}</td><td>${o(m.message)}</td></tr>`;v+="</table>"}f=$("Health Check",U(y,n),v)}else if(h==="/search"){let b=x.searchParams.get("q")||"",v=await y.findRelevantReranked(b,void 0,20),m=`<h1>Search: "${o(b)}"</h1>`;for(let k of v)m+=`<div class="entry-card"><h3><a href="/article/${encodeURIComponent(k.path)}">${o(k.meta.title)}</a></h3><p>${o(k.content.slice(0,200))}...</p></div>`;v.length===0&&(m+="<p>No results.</p>"),f=$(`Search: ${b}`,U(y,n),m)}else if(h.startsWith("/tag/")){let b=decodeURIComponent(h.slice(5)),v=y.findByTags([b],void 0,100),m=`<h1>Tag: <a class="tag" href="#">${o(b)}</a></h1>`;m+=`<p>${v.length} article${v.length===1?"":"s"} tagged <code>${o(b)}</code></p>`;for(let k of v)m+=`<div class="entry-card"><h3><a href="/article/${encodeURIComponent(k.path)}">${o(k.meta.title)}</a></h3><div class="meta-line">${P((k.meta.tags||[]).slice(0,6))}</div></div>`;v.length===0&&(m+="<p>No articles with this tag.</p>"),f=$(`Tag: ${b}`,U(y,n),m)}}else{let y=s?await s.getRemoteAgents():[],b=p.summary(),v=new Map(b.map(u=>[u.agentId,u])),m=[],k=new Set;for(let u of b){let w=y.find(z=>z.agentId===u.agentId);w&&w.totalArticles>u.totalArticles?m.push({...w,totalEntries:Math.max(u.totalEntries,w.totalEntries),unabsorbed:Math.max(u.unabsorbed,w.unabsorbed)}):m.push(u),k.add(u.agentId)}for(let u of y)k.has(u.agentId)||(m.push(u),k.add(u.agentId));if(h==="/"||h==="")f=Ke(p,m,y);else if(h==="/entries")f=Ge(p,m);else if(h==="/search")f=Ve(p,x.searchParams.get("q")||"",m);else if(h.startsWith("/tag/"))f=Qe(p,decodeURIComponent(h.slice(5)),m);else if(h.match(/^\/agent\/[^/]+\/tag\/.+/)){let u=h.match(/^\/agent\/([^/]+)\/tag\/(.+)$/);f=Ze(p,decodeURIComponent(u[1]),decodeURIComponent(u[2]),m)}else if(h.startsWith("/agent/")){let u=h.slice(7),w=u.indexOf("/article/");if(w===-1)f=Ye(p,u,m);else{let z=u.slice(0,w),N=u.slice(w+9);if(f=Xe(p,z,N,m),!f&&s){let A=y.find(E=>E.agentId===z);if(A){let E=await s.getRemoteArticle(A.peerUrl,z,N);if(E){let S=`<div class="breadcrumb"><a href="/">Hub</a> / <span class="tag">remote @ ${o(A.nodeId)}</span> / ${o(z)}</div>`;S+=`<h1>${o(E.meta.title)}</h1>`,S+='<dl class="meta">',S+=`<dt>Tags</dt><dd>${(E.meta.tags||[]).map(xe=>`<span class="tag">${xe}</span>`).join(" ")}</dd>`,S+=`<dt>Source</dt><dd><span class="tag">remote</span> ${o(A.nodeId)}</dd>`,S+=`<dt>Updated</dt><dd>${E.meta.lastUpdated}</dd>`,S+="</dl>",S+=H(E.content,new Map),f=$(E.meta.title,C(m),S)}}}}}}if(!f){T=404;let y=n?U(p.getAgentWiki(n),n):C(p.summary());f=$("Not Found",y,"<h1>Page not found</h1>")}}catch(y){T=500,f=$("Error","",`<h1>Error</h1><pre>${o(y.message)}</pre>`)}g.writeHead(T,{"Content-Type":"text/html; charset=utf-8"}),g.end(l?tt(f,l):f)}}function tt(e,t){e=e.replace(/(\s(?:href|action)=")\/(?!\/)/g,`$1${t}/`),e=e.replace(new RegExp(`(${t})${t}/`,"g"),`${t}/`);let n=`<a href="/admin" style="position:fixed;top:10px;right:14px;z-index:9999;padding:5px 11px;background:rgba(0,0,0,0.55);color:#fff;font:12px/1.2 'IBM Plex Sans',system-ui,sans-serif;text-decoration:none;border-radius:6px;border:1px solid rgba(255,255,255,0.18);backdrop-filter:blur(6px)">\u2190 Dashboard</a>`;return e=e.replace(/<body([^>]*)>/,`<body$1>${n}`),e}function Wt(e,t=4200,n,a=[],r="graph"){let i=et({wikiDir:e,agentFilter:n,peerUrls:a,mode:r});Fe((p,s)=>{i(p,s)}).listen(t)}import{existsSync as nt,readFileSync as at}from"fs";M();function Ht(e){let t=G(e),n={};if(nt(t))try{n=Y(JSON.parse(at(t,"utf-8")))}catch{n={}}let a=O.safeParse(n?.approvals);return a.success?a.data:O.parse(void 0)}function Ot(e){let t=e.indexOf(":");return t<=0||t===e.length-1?null:{channel:e.slice(0,t).trim(),chatId:e.slice(t+1).trim()}}async function Mt(e,t={}){return V(n=>{let a=n.approvals??={};e.defaultExpiryDays!==void 0&&(a.defaultExpiryDays=e.defaultExpiryDays),e.maxExpiryDays!==void 0&&(a.maxExpiryDays=e.maxExpiryDays),e.laterHours!==void 0&&(a.laterHours=e.laterHours),e.notifyAgent!==void 0&&(a.notifyAgent=e.notifyAgent);let r=a.digest??={};e.digestEnabled!==void 0&&(r.enabled=e.digestEnabled),e.digestTime!==void 0&&(r.time=e.digestTime),e.digestTimezone===null?delete r.timezone:e.digestTimezone!==void 0&&(r.timezone=e.digestTimezone),e.destination===null?delete r.destination:e.destination!==void 0&&(r.destination=e.destination);let i=a.defaultExpiryDays??3,l=a.maxExpiryDays??30;if(i>l)throw new Error(`defaultExpiryDays (${i}) can't be more than maxExpiryDays (${l})`)},{configPath:t.configPath,reload:t.reload})}var rt="https://ntfy.sh";function jt(e){return{enabled:!!e?.enabled,server:e?.server||rt,topicSet:!!e?.topic,tokenSet:!!e?.token}}function Lt(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{re as a,ce as b,bt as c,yt as d,kt as e,he as f,It as g,Ct as h,Ht as i,Ot as j,Mt as k,jt as l,Lt as m,et as n,Wt as o};
|
|
740
|
-
//# sourceMappingURL=chunk-
|
|
740
|
+
//# sourceMappingURL=chunk-RKAJR37K.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as o}from"./chunk-
|
|
1
|
+
import{a as o}from"./chunk-N6EWZGIX.js";import{existsSync as s}from"fs";import{resolve as a}from"path";function u(){return!!(process.env.VITEST||process.env.NODE_ENV==="test"||process.env.AGENTX_NO_TELEMETRY)}function c(){let n=process.cwd();for(let t=0;t<5;t++){if(s(a(n,".agentx"))||s(a(n,"agentx.json")))return n;let e=a(n,"..");if(e===n)break;n=e}return null}function d(n=new Date){return n.toISOString().slice(0,10)}function m(n,t,e=new Date){try{if(!t||u()||!c())return;let r=o({quiet:!0});if(!r)return;r.prepare(`INSERT INTO surface_usage (kind, name, day, count, last_at)
|
|
2
2
|
VALUES (?, ?, ?, 1, ?)
|
|
3
3
|
ON CONFLICT(kind, name, day)
|
|
4
4
|
DO UPDATE SET count = count + 1, last_at = excluded.last_at`).run(n,t,d(e),e.toISOString())}catch{}}function g(n={}){try{let t=o({quiet:!0});if(!t)return[];let e=new Date(Date.now()-(n.sinceDays??30)*864e5).toISOString().slice(0,10),r=["day >= ?"],i=[e];return n.kind&&(r.push("kind = ?"),i.push(n.kind)),t.prepare(`SELECT kind, name, SUM(count) AS count, COUNT(DISTINCT day) AS days, MAX(last_at) AS last_at
|
|
@@ -6,4 +6,4 @@ import{a as o}from"./chunk-DJQA2CWD.js";import{existsSync as s}from"fs";import{r
|
|
|
6
6
|
WHERE ${r.join(" AND ")}
|
|
7
7
|
GROUP BY kind, name
|
|
8
8
|
ORDER BY count DESC`).all(...i)}catch{return[]}}function E(n){let t=[],e=n;for(;e&&typeof e.name=="function";){let r=e.name();e.parent&&t.unshift(r),e=e.parent}return t.join(" ")}var f=new Set(["guard check","completion","serve"]);function T(n){return!!n&&!f.has(n)}export{m as a,g as b,E as c,T as d};
|
|
9
|
-
//# sourceMappingURL=chunk-
|
|
9
|
+
//# sourceMappingURL=chunk-Z3IP66SL.js.map
|
package/dist/cli.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as n}from"./chunk-
|
|
2
|
+
import{a as n}from"./chunk-FM2GGPSD.js";import"./chunk-OUZ7YVQZ.js";import"./chunk-RKAJR37K.js";import"./chunk-Z3IP66SL.js";import"./chunk-DLKRPK5M.js";import"./chunk-OTW5MPFT.js";import"./chunk-RKPAVWXF.js";import"./chunk-GV7S5BAX.js";import"./chunk-GSX4NK2N.js";import"./chunk-SZDACK6O.js";import"./chunk-HGT4AKOH.js";import"./chunk-DTJKN5VT.js";import"./chunk-PZCTCCC5.js";import"./chunk-LQRBGQIR.js";import"./chunk-ZVP6GB4G.js";import"./chunk-FULEQYM6.js";import"./chunk-OHA3J5ZV.js";import"./chunk-3SCPRYJB.js";import"./chunk-AQASR6KR.js";import"./chunk-L53FTKEP.js";import"./chunk-HVQJIROJ.js";import"./chunk-3L2FKVR6.js";import"./chunk-N6EWZGIX.js";import"./chunk-Q7C3X3R6.js";import"./chunk-DP7RTNDM.js";import"./chunk-MWUJOAAW.js";import"./chunk-SFQUP3BP.js";import"./chunk-5XQCGPQJ.js";import"./chunk-B5XHX44Y.js";import"./chunk-WPMX3VGI.js";import"./chunk-K33GIBSE.js";import"./chunk-76Z4VHDX.js";import"./chunk-W4YR2RO2.js";import"./chunk-AFRHKA7B.js";import"./chunk-NLZD2QKF.js";import"./chunk-5ALS7SVV.js";import"./chunk-DWADWDMU.js";import"./chunk-DVNIFP7S.js";import"./chunk-7DXE264B.js";import"./chunk-VWTBHLMX.js";import"./chunk-IXUEJBHD.js";import"./chunk-JVNFRS26.js";import"./chunk-PNWNVOEZ.js";import"./chunk-64P4QHSZ.js";import"./chunk-QDE75R4U.js";import"./chunk-AJ5RMU7X.js";import"./chunk-2GIDVZ4H.js";import"./chunk-4NBWF4TL.js";import"./chunk-F4HZTZHW.js";import"./chunk-AJONZWLT.js";import"./chunk-ZTEU5JVQ.js";import"./chunk-QOYAX2FT.js";import"./chunk-LCIREYTD.js";import"./chunk-L2WSPY6S.js";import"./chunk-VDMYBPYB.js";import"./chunk-DSYKYZMT.js";import"./chunk-P2ZYT5D6.js";import"./chunk-BH3GTCZ6.js";import"./chunk-FIOB3MEX.js";var r=["SIGINT","SIGTERM"];function o(t=process){for(let i of r)t.on(i,()=>{t.listenerCount(i)<=1&&t.exit(0)})}o();async function s(){let t=await n();if(process.argv.slice(2).length===0){t.outputHelp();return}t.parse()}s();
|
|
3
3
|
//# sourceMappingURL=cli.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{i as a,j as b,k as c,l as d,m as e,n as f,p as g}from"./chunk-
|
|
2
|
-
//# sourceMappingURL=config-
|
|
1
|
+
import{i as a,j as b,k as c,l as d,m as e,n as f,p as g}from"./chunk-P2ZYT5D6.js";import"./chunk-FIOB3MEX.js";g();export{a as INTEGRATION_KINDS,b as approvalsConfigSchema,c as daemonConfigSchema,d as expandEnvVars,e as loadDaemonConfig,f as validateWorkspaces};
|
|
2
|
+
//# sourceMappingURL=config-R47ITLIY.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import{a as y,b as C}from"./chunk-AJONZWLT.js";import"./chunk-FIOB3MEX.js";C();var I="claude-haiku-4-5-20251001",M=`You are a context planner for an AI agent. Given the user's current message and recent conversation tail, decide what historical context the agent needs.
|
|
2
|
+
|
|
3
|
+
Output ONE JSON object on one line, no prose, no fences:
|
|
4
|
+
{ "recentTurns": number, "memory": { "include": boolean, "query": string }, "crossChat": boolean, "reasoning": string }
|
|
5
|
+
|
|
6
|
+
Rules:
|
|
7
|
+
- "recentTurns" in [0,6]. Short acknowledgments ("ok", "yes", "do it", "continue") need 2-3 turns to know what they refer to. New topics need 0. Technical follow-ups need 3-5.
|
|
8
|
+
- "memory.include" = true only when the message likely references a person, past event, decision, or project the agent should recall. "memory.query" = 3-8 words distilling what to search for (leave "" when include=false).
|
|
9
|
+
- "crossChat" = true only when the message references another chat ("DM", "the group", "earlier conversation", a peer agent's name). Most messages = false.
|
|
10
|
+
- "reasoning" = one short phrase explaining the plan.
|
|
11
|
+
|
|
12
|
+
Be conservative \u2014 unneeded context costs tokens. When in doubt, exclude.`;async function P(e){let c=Date.now(),i=e.timeoutMs??8e3,r=T(e.sessions,e.agentId,e.channel,e.chatId,4),o=[`Agent: ${e.agentId}`,`Channel: ${e.channel}`,r?`Recent conversation:
|
|
13
|
+
${r}`:"Recent conversation: (none \u2014 first message)","",`Current message: ${e.message.slice(0,1500)}`].join(`
|
|
14
|
+
`),n;try{let{createProvider:m}=await import("./providers-KO2DODIO.js"),b=m("claude"),p=new AbortController,x=setTimeout(()=>p.abort(),i);try{let S=await b.generate([{role:"system",content:M},{role:"user",content:o}],{model:I,maxTokens:256});n=y(S.content)}finally{clearTimeout(x)}}catch(m){return process.env.AGENTX_PLANNER_DEBUG&&console.error(`[planner] error: ${m?.message??m}`),null}if(!n||typeof n!="object")return null;let l=v(n.recentTurns,0,6,3),t=!!n.memory?.include,s=typeof n.memory?.query=="string"?n.memory.query:"",a=!!n.crossChat,g=typeof n.reasoning=="string"?n.reasoning:void 0,f=w(e.sessions,e.agentId,e.channel,e.chatId,l),u="",h=[];if(t&&s)try{let m=e.memoryStore.findRelevant(s,e.agentId,5);u=e.memoryStore.buildContext(m),h=e.memoryStore.contextFacts(m)}catch{}let d="";return a&&(d=e.sessions.getCrossSessionSummary(e.agentId,e.channel,e.chatId,"")),{sessionHistory:f,memoryContext:u,memoryFacts:h,crossChatContext:d,debug:{recentTurns:l,memoryIncluded:t,memoryQuery:s||void 0,crossChatIncluded:a,reasoning:g,planLatencyMs:Date.now()-c}}}function w(e,c,i,r,o){if(o<=0)return"";let n=e.getSession(c,i,r);if(n.messages.length===0)return"";let l=Math.min(n.messages.length,o*2),t=n.messages.slice(-l),s=[`[Recent exchange \u2014 last ${t.length} messages]`];for(let a of t){let g=a.name||(a.role==="user"?"User":"Agent");s.push(`${g}: ${a.content}`)}return s.push("[End recent exchange \u2014 respond to the latest message above]"),s.push(""),s.join(`
|
|
15
|
+
`)}function T(e,c,i,r,o){let n=e.getSession(c,i,r);return n.messages.length===0?"":n.messages.slice(-o).map(t=>{let s=t.name||(t.role==="user"?"User":"Agent"),a=t.content.length>200?t.content.slice(0,200)+"\u2026":t.content;return` ${s}: ${a}`}).join(`
|
|
16
|
+
`)}function v(e,c,i,r){let o=typeof e=="number"?Math.floor(e):Number.parseInt(String(e??""),10);return Number.isFinite(o)?Math.min(i,Math.max(c,o)):r}export{P as planContext};
|
|
17
|
+
//# sourceMappingURL=context-planner-FJMU5WAT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/agents/context-planner.ts"],"sourcesContent":["// --- Context Planner ---\n//\n// A Haiku pre-call that decides what context to retrieve for the current\n// message, replacing the blind \"stack every layer\" approach of the layered\n// strategy. Drops --resume bloat by avoiding the full session history blob\n// on every turn; instead pulls only the specific facts / memory / cross-chat\n// the current message actually needs.\n//\n// Always-on core (handled by registry, not the planner): channel, scope,\n// landscape, identity, intent, and a small `recentTurns`-sized tail of the\n// session verbatim. The planner decides: how many tail turns to keep, and\n// whether to pull memory or cross-chat on top.\n//\n// Fail-open: any planner error returns null and the registry falls back to\n// the layered strategy. This keeps the feature safe to enable even when\n// the planner model is misbehaving.\n//\n// Cost model: one small Haiku call per message (~300 input / ~80 output\n// tokens, ~$0.0005). Win threshold is when it avoids shipping ≥5K tokens\n// of layered history/memory the agent didn't need — typical for short\n// \"ok / yes / do it\" messages where the layered path still dumps the\n// whole 12K-char session blob.\n\nimport type { SessionStore, SessionMessage } from \"./sessions\"\nimport { extractJson } from \"@/utils/extract-json\"\nimport type { MemoryFact, MemoryStore } from \"./memory-store\"\n\n/** Planner output. When `null`, the caller falls back to the layered\n * strategy. Otherwise each field overrides the corresponding context\n * layer — an empty string means \"skip this layer entirely\". */\nexport interface ContextPlan {\n /** Rendered session history (same shape buildHistoryContext returns),\n * truncated to the last N turns the planner picked. */\n sessionHistory: string\n /** Rendered memory context, or \"\" when the planner decided memory\n * isn't relevant to this message. */\n memoryContext: string\n /** The memory facts rendered into memoryContext. */\n memoryFacts: MemoryFact[]\n /** Rendered cross-chat summary, or \"\" when not needed. */\n crossChatContext: string\n /** Debug metadata — surfaced in logs + bench output so operators can\n * see what the planner chose. Not sent to the main agent. */\n debug: {\n recentTurns: number\n memoryIncluded: boolean\n memoryQuery?: string\n crossChatIncluded: boolean\n reasoning?: string\n planLatencyMs: number\n }\n}\n\nexport interface PlanContextInput {\n agentId: string\n channel: string\n chatId: string\n message: string\n sessions: SessionStore\n memoryStore: MemoryStore\n /** Caller-controlled timeout for the Haiku planner call. Defaults to\n * 8s — the planner is in the critical path before the main agent\n * runs, so we can't afford a long timeout. Fail-open if exceeded. */\n timeoutMs?: number\n}\n\nconst PLANNER_MODEL = \"claude-haiku-4-5-20251001\"\nconst PLANNER_PROMPT = `You are a context planner for an AI agent. Given the user's current message and recent conversation tail, decide what historical context the agent needs.\n\nOutput ONE JSON object on one line, no prose, no fences:\n { \"recentTurns\": number, \"memory\": { \"include\": boolean, \"query\": string }, \"crossChat\": boolean, \"reasoning\": string }\n\nRules:\n- \"recentTurns\" in [0,6]. Short acknowledgments (\"ok\", \"yes\", \"do it\", \"continue\") need 2-3 turns to know what they refer to. New topics need 0. Technical follow-ups need 3-5.\n- \"memory.include\" = true only when the message likely references a person, past event, decision, or project the agent should recall. \"memory.query\" = 3-8 words distilling what to search for (leave \"\" when include=false).\n- \"crossChat\" = true only when the message references another chat (\"DM\", \"the group\", \"earlier conversation\", a peer agent's name). Most messages = false.\n- \"reasoning\" = one short phrase explaining the plan.\n\nBe conservative — unneeded context costs tokens. When in doubt, exclude.`\n\nexport async function planContext(input: PlanContextInput): Promise<ContextPlan | null> {\n const start = Date.now()\n const timeoutMs = input.timeoutMs ?? 8_000\n\n // Snapshot the session tail for the planner prompt. Don't send the\n // whole session — the planner only needs enough to judge whether the\n // message is a follow-up, and we pay tokens for every line we ship.\n const recentTail = sessionTail(input.sessions, input.agentId, input.channel, input.chatId, 4)\n\n const userPrompt = [\n `Agent: ${input.agentId}`,\n `Channel: ${input.channel}`,\n recentTail ? `Recent conversation:\\n${recentTail}` : \"Recent conversation: (none — first message)\",\n ``,\n `Current message: ${input.message.slice(0, 1500)}`,\n ].join(\"\\n\")\n\n // Use the Anthropic SDK path — warm HTTP client, no subprocess cold-start.\n // resolveToken now recognizes CLAUDE_CODE_OAUTH_TOKEN so this works out\n // of the box for any operator who already has Claude CLI auth set up.\n // Planner timeout is tight (8s default) because plan latency is in the\n // critical path before the main agent runs.\n let planJson: any\n try {\n const { createProvider } = await import(\"@/agent/providers\")\n const provider = createProvider(\"claude\")\n const ac = new AbortController()\n const timer = setTimeout(() => ac.abort(), timeoutMs)\n try {\n const result = await provider.generate(\n [\n { role: \"system\", content: PLANNER_PROMPT },\n { role: \"user\", content: userPrompt },\n ],\n { model: PLANNER_MODEL, maxTokens: 256 },\n )\n planJson = extractJson(result.content)\n } finally {\n clearTimeout(timer)\n }\n } catch (err: any) {\n // Temporary: surface planner errors for debugging. Will silence once\n // we're confident the SDK path is stable.\n if (process.env.AGENTX_PLANNER_DEBUG) {\n // eslint-disable-next-line no-console\n console.error(`[planner] error: ${err?.message ?? err}`)\n }\n return null\n }\n\n if (!planJson || typeof planJson !== \"object\") return null\n\n const recentTurns = clampInt(planJson.recentTurns, 0, 6, 3)\n const memoryInclude = Boolean(planJson.memory?.include)\n const memoryQuery: string = typeof planJson.memory?.query === \"string\" ? planJson.memory.query : \"\"\n const crossChatInclude = Boolean(planJson.crossChat)\n const reasoning = typeof planJson.reasoning === \"string\" ? planJson.reasoning : undefined\n\n // Resolve the plan into actual retrieval strings.\n const sessionHistory = renderSessionTail(\n input.sessions,\n input.agentId,\n input.channel,\n input.chatId,\n recentTurns,\n )\n\n let memoryContext = \"\"\n let memoryFacts: MemoryFact[] = []\n if (memoryInclude && memoryQuery) {\n try {\n const relevant = input.memoryStore.findRelevant(memoryQuery, input.agentId, 5)\n memoryContext = input.memoryStore.buildContext(relevant)\n memoryFacts = input.memoryStore.contextFacts(relevant)\n } catch {\n // Memory retrieval is best-effort; planner proceeds with empty memory.\n }\n }\n\n let crossChatContext = \"\"\n if (crossChatInclude) {\n // Force-include via empty message arg — the planner already decided.\n crossChatContext = input.sessions.getCrossSessionSummary(\n input.agentId, input.channel, input.chatId, \"\",\n )\n }\n\n return {\n sessionHistory,\n memoryContext,\n memoryFacts,\n crossChatContext,\n debug: {\n recentTurns,\n memoryIncluded: memoryInclude,\n memoryQuery: memoryQuery || undefined,\n crossChatIncluded: crossChatInclude,\n reasoning,\n planLatencyMs: Date.now() - start,\n },\n }\n}\n\n/** Render the last N message pairs as a compact prompt tail. Returns \"\" when\n * there's no session on disk yet (first message). Format mirrors\n * SessionStore.buildHistoryContext but with an N-turn cap — the planner's\n * whole point is to cap this instead of dumping the full 12K-char log. */\nfunction renderSessionTail(\n sessions: SessionStore,\n agentId: string,\n channel: string,\n chatId: string,\n turns: number,\n): string {\n if (turns <= 0) return \"\"\n const session = sessions.getSession(agentId, channel, chatId)\n if (session.messages.length === 0) return \"\"\n // N \"turns\" = N*2 messages (user+agent pairs). Round to nearest message\n // count so a partial trailing user message still gets included.\n const msgCount = Math.min(session.messages.length, turns * 2)\n const tail = session.messages.slice(-msgCount)\n const lines: string[] = [`[Recent exchange — last ${tail.length} messages]`]\n for (const msg of tail) {\n const name = msg.name || (msg.role === \"user\" ? \"User\" : \"Agent\")\n lines.push(`${name}: ${msg.content}`)\n }\n lines.push(\"[End recent exchange — respond to the latest message above]\")\n lines.push(\"\")\n return lines.join(\"\\n\")\n}\n\n/** Very small tail for the planner's own prompt — enough for the planner to\n * decide whether this message is a follow-up, not enough to bloat the\n * planner call itself. Distinct from renderSessionTail (used for the main\n * agent) because we cap more aggressively here. */\nfunction sessionTail(\n sessions: SessionStore,\n agentId: string,\n channel: string,\n chatId: string,\n maxMessages: number,\n): string {\n const session = sessions.getSession(agentId, channel, chatId)\n if (session.messages.length === 0) return \"\"\n const tail = session.messages.slice(-maxMessages)\n return tail\n .map((m: SessionMessage) => {\n const name = m.name || (m.role === \"user\" ? \"User\" : \"Agent\")\n const content = m.content.length > 200 ? m.content.slice(0, 200) + \"…\" : m.content\n return ` ${name}: ${content}`\n })\n .join(\"\\n\")\n}\n\n/** Extract the first JSON object from a text response. Haiku sometimes\n * wraps output in backticks or prose despite the instructions, so we\n * scan for the first `{...}` span. */\n\nfunction clampInt(v: unknown, min: number, max: number, fallback: number): number {\n const n = typeof v === \"number\" ? Math.floor(v) : Number.parseInt(String(v ?? \"\"), 10)\n if (!Number.isFinite(n)) return fallback\n return Math.min(max, Math.max(min, n))\n}\n"],"mappings":"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","names":["init_extract_json","PLANNER_MODEL","PLANNER_PROMPT","planContext","input","start","timeoutMs","recentTail","sessionTail","userPrompt","planJson","createProvider","provider","ac","timer","result","extractJson","err","recentTurns","clampInt","memoryInclude","memoryQuery","crossChatInclude","reasoning","sessionHistory","renderSessionTail","memoryContext","memoryFacts","relevant","crossChatContext","sessions","agentId","channel","chatId","turns","session","msgCount","tail","lines","msg","name","maxMessages","m","content","v","min","max","fallback","n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{f,k as I}from"./chunk-Q7C3X3R6.js";import"./chunk-ZTEU5JVQ.js";import"./chunk-FIOB3MEX.js";import{createHash as $}from"crypto";var k="failure:",x=3,p=5,A=["error","timeout"],T=["memory-promote","procedure-miner"];function h(t,s){return(s??"").toLowerCase().replace(/https?:\/\/\S+/g,"<url>").replace(/(["'`]).*?\1/g,"<v>").replace(/(?:~|\.{0,2})?\/[\w.@-]+(?:\/[\w.@-]+)*/g,"<path>").replace(/\b[0-9a-z]*\d[0-9a-z]*\b/g,"<n>").replace(/[^a-z<>\s]+/g," ").replace(/\s+/g," ").trim().split(" ").filter(Boolean).slice(0,8).join(" ")||t}function y(t){return`${t.agentId}|${t.tool??"no-tool"}|${t.status}|${h(t.status,t.error)}`}function S(t){return $("sha1").update(t).digest("hex").slice(0,10)}function w(t,s){return`${k}${S(t)}@${Math.floor(Math.log2(Math.max(1,s)))}`}function F(t){return t.finalSessionId??t.resumeSessionId??t.taskId}function _(t,s={}){return A.flatMap(e=>I(t,{status:e,since:s.since,limit:1e3})).filter(e=>!T.some(i=>(e.chatId??"").startsWith(i))).map(e=>{let{tool:i,error:n}=b(f(t,e.taskId)?.steps??[]);return{taskId:e.taskId,agentId:e.agentId,chatId:e.chatId,sessionId:F(e),status:e.status,startedAt:e.startedAt,error:n??e.error,messagePreview:e.messagePreview,tool:i}})}function b(t){let s=null,a=null;for(let e of t)e.name==="tool_use"&&e.action?(s=e.action,e.status==="error"&&(a={tool:e.action,error:e.error??e.outputSummary})):e.name==="tool_result"&&e.status==="error"&&(a={tool:e.action??s,error:e.error??e.outputSummary});return a??{tool:s,error:null}}function C(t,s={}){let a=Math.max(2,s.minSessions??x),e=new Map;for(let n of t){let r=y(n);e.set(r,[...e.get(r)??[],n])}let i=[];for(let[n,r]of e){let l=[...new Set([...r].sort((c,g)=>g.startedAt-c.startedAt).map(c=>c.sessionId))];if(l.length<a)continue;r.sort((c,g)=>g.startedAt-c.startedAt);let o=r[0],u=o.tool??"no tool",d=h(o.status,o.error),m=`failure-${S(n)}`;i.push({occurrences:l.length,sessions:l.slice(0,p),tasks:r.slice(0,p).map(c=>c.taskId),failure:{tool:u,errorClass:d,runs:r.length},agentId:o.agentId,key:`${o.agentId}/feedback_${m}`,stamp:w(n,l.length),memory:{name:m,type:"feedback",description:`${o.agentId}: ${u} keeps failing (${d}) in ${l.length} sessions`.slice(0,200),body:E(o.agentId,u,d,l.length,r),createdAt:new Date(r[r.length-1].startedAt).toISOString(),updatedAt:new Date(o.startedAt).toISOString()}})}return i.sort((n,r)=>r.occurrences-n.occurrences)}function E(t,s,a,e,i){let n=i.slice(0,p).map(r=>{let l=(r.messagePreview??"").replace(/\s+/g," ").trim().slice(0,120),o=(r.error??r.status).replace(/\s+/g," ").trim().slice(0,160);return`- ${new Date(r.startedAt).toISOString().slice(0,10)} \`${r.taskId}\` (${r.status})${l?` \u2014 task: ${l}`:""}
|
|
2
|
+
error: ${o}`});return[`**${t}** hit the same failure in ${e} separate sessions (${i.length} runs).`,`- Tool: \`${s}\`
|
|
3
|
+
- Error class: \`${a}\``,"Recurrence across sessions is the finding: any one of these runs is session state. Propose the fix that stops it recurring \u2014 what fails, the likely cause, and what to do instead (a missing fact, a better approach, or a tool or configuration change to make) \u2014 or skip it if the examples do not share a cause.",`**Examples (newest first):**
|
|
4
|
+
${n.join(`
|
|
5
|
+
`)}`].join(`
|
|
6
|
+
|
|
7
|
+
`)}export{x as DEFAULT_MIN_SESSIONS,k as FAILURE_STAMP_PREFIX,p as MAX_FAILURE_EXAMPLES,h as errorClass,b as failingTool,y as failureSignature,w as failureStamp,C as failuresToCandidates,_ as loadFailedTraces,F as sessionOf};
|
|
8
|
+
//# sourceMappingURL=failure-candidates-ARRMFXRY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/wiki/failure-candidates.ts"],"sourcesContent":["import { createHash } from \"crypto\"\nimport type Database from \"better-sqlite3\"\nimport { getTrace, listTraces, type TraceRecord, type TraceStepRecord } from \"@/storage/traces\"\nimport type { MemoryCandidate } from \"./promote\"\n\n// Failed traces → wiki promotion candidates.\n//\n// Every other learning pass reads successes: the procedure miner loads\n// `status: ok` traces, and promotion reads memories an agent chose to\n// write. A tool that keeps failing, or the same wrong turn taken in\n// session after session, never reaches either — nothing in a failed run\n// is written down as a memory, and the miner never looks at it.\n//\n// This groups failed and timed-out traces by a failure signature (agent\n// + tool + outcome + error class) and offers only the signatures that recur across\n// several sessions to `wiki promote`. They join the same pool as memories\n// and monitor findings, so the judge, the ledger and the proposal review\n// are shared rather than rebuilt. One failure is session state; the same\n// failure in five sessions is something the fleet should know.\n\nexport const FAILURE_STAMP_PREFIX = \"failure:\"\nexport const DEFAULT_MIN_SESSIONS = 3\n/** Example runs kept per signature; the counts carry the rest. */\nexport const MAX_FAILURE_EXAMPLES = 5\n\n/** Trace statuses that count as a failure. `cancelled` does not: an\n * operator or a daemon restart stopped the run, the agent did not fail. */\nconst FAILED_STATUSES = [\"error\", \"timeout\"]\n\n/** Chats a learning pass itself runs in. Learning from those would make\n * the system learn from itself (same rule as the procedure miner). */\nconst SELF_CHAT_PREFIXES = [\"memory-promote\", \"procedure-miner\"]\n\nexport interface FailedTrace {\n taskId: string\n agentId: string\n chatId: string | null\n /** The session the run belongs to — the provider session when one is\n * known, else the run itself. See sessionOf(). */\n sessionId: string\n status: string\n startedAt: number\n error: string | null\n messagePreview: string | null\n /** The failing tool — see failingTool(); null when the run failed\n * before or outside any tool. */\n tool: string | null\n}\n\nexport interface FailureCandidate extends MemoryCandidate {\n /** Distinct sessions that hit this signature. */\n occurrences: number\n /** Some of those sessions, newest first. */\n sessions: string[]\n /** Some of the failed runs (task ids), newest first. */\n tasks: string[]\n failure: { tool: string; errorClass: string; runs: number }\n}\n\n/**\n * Reduce an error message to its class: the words that stay the same\n * when the same thing breaks again. Ids, numbers, paths, URLs and quoted\n * values change every time and would split one failure into many.\n */\nexport function errorClass(status: string, error: string | null): string {\n const text = (error ?? \"\")\n .toLowerCase()\n .replace(/https?:\\/\\/\\S+/g, \"<url>\")\n .replace(/([\"'`]).*?\\1/g, \"<v>\")\n .replace(/(?:~|\\.{0,2})?\\/[\\w.@-]+(?:\\/[\\w.@-]+)*/g, \"<path>\")\n .replace(/\\b[0-9a-z]*\\d[0-9a-z]*\\b/g, \"<n>\")\n .replace(/[^a-z<>\\s]+/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim()\n const words = text.split(\" \").filter(Boolean).slice(0, 8).join(\" \")\n return words || status\n}\n\n/** Agent + tool + outcome + error class. A timeout and an error in the\n * same tool are different failures with different fixes. */\nexport function failureSignature(t: Pick<FailedTrace, \"agentId\" | \"tool\" | \"status\" | \"error\">): string {\n return `${t.agentId}|${t.tool ?? \"no-tool\"}|${t.status}|${errorClass(t.status, t.error)}`\n}\n\nfunction digest(signature: string): string {\n return createHash(\"sha1\").update(signature).digest(\"hex\").slice(0, 10)\n}\n\n/**\n * The stamp changes only when recurrence doubles (2–3 → 4–7 → 8–15 …).\n * A lesson skipped or rejected at three sessions is offered again once\n * it has been seen in four, and next at eight; it is not re-offered every\n * night because one more session hit it.\n */\nexport function failureStamp(signature: string, sessions: number): string {\n return `${FAILURE_STAMP_PREFIX}${digest(signature)}@${Math.floor(Math.log2(Math.max(1, sessions)))}`\n}\n\n/**\n * Which session a run belongs to. The provider session is the honest\n * unit: two failures inside one continuing conversation are one session\n * going wrong, not two. A run that never got a session is its own. The\n * chat id is deliberately not used — a scheduled job reuses one chat id\n * forever, which would count a job failing every night as one session.\n */\nexport function sessionOf(t: Pick<TraceRecord, \"taskId\" | \"finalSessionId\" | \"resumeSessionId\">): string {\n return t.finalSessionId ?? t.resumeSessionId ?? t.taskId\n}\n\n/** Load failed and timed-out traces in the window, with their failing tool. */\nexport function loadFailedTraces(db: Database.Database, opts: { since?: number } = {}): FailedTrace[] {\n const traces = FAILED_STATUSES.flatMap((status) =>\n listTraces(db, { status, since: opts.since, limit: 1000 }))\n return traces\n .filter((t) => !SELF_CHAT_PREFIXES.some((p) => (t.chatId ?? \"\").startsWith(p)))\n .map((t) => {\n const { tool, error } = failingTool(getTrace(db, t.taskId)?.steps ?? [])\n return {\n taskId: t.taskId,\n agentId: t.agentId,\n chatId: t.chatId,\n sessionId: sessionOf(t),\n status: t.status,\n startedAt: t.startedAt,\n error: error ?? t.error,\n messagePreview: t.messagePreview,\n tool,\n }\n })\n}\n\n/**\n * The tool a run failed in, and that tool's error. The stream records a\n * call as a `tool_use` step (named, status in-flight) and its outcome as\n * a separate `tool_result` step that carries no tool name, so an errored\n * result is paired with the call before it. The last error wins; with no\n * errored call the run is attributed to the last tool it used, keeping\n * the run's own error.\n */\nexport function failingTool(\n steps: Array<Pick<TraceStepRecord, \"name\" | \"action\" | \"status\" | \"error\" | \"outputSummary\">>,\n): { tool: string | null; error: string | null } {\n let last: string | null = null\n let failing: { tool: string | null; error: string | null } | null = null\n for (const s of steps) {\n if (s.name === \"tool_use\" && s.action) {\n last = s.action\n if (s.status === \"error\") failing = { tool: s.action, error: s.error ?? s.outputSummary }\n } else if (s.name === \"tool_result\" && s.status === \"error\") {\n failing = { tool: s.action ?? last, error: s.error ?? s.outputSummary }\n }\n }\n return failing ?? { tool: last, error: null }\n}\n\n/** Group failures by signature; keep those seen in at least `minSessions`\n * distinct sessions (never fewer than 2 — one session is not a pattern).\n * Most recurrent first. */\nexport function failuresToCandidates(\n traces: FailedTrace[],\n opts: { minSessions?: number } = {},\n): FailureCandidate[] {\n const minSessions = Math.max(2, opts.minSessions ?? DEFAULT_MIN_SESSIONS)\n const groups = new Map<string, FailedTrace[]>()\n for (const t of traces) {\n const sig = failureSignature(t)\n groups.set(sig, [...(groups.get(sig) ?? []), t])\n }\n\n const out: FailureCandidate[] = []\n for (const [signature, list] of groups) {\n const sessions = [...new Set([...list].sort((a, b) => b.startedAt - a.startedAt).map((t) => t.sessionId))]\n if (sessions.length < minSessions) continue\n list.sort((a, b) => b.startedAt - a.startedAt)\n const latest = list[0]\n const tool = latest.tool ?? \"no tool\"\n const cls = errorClass(latest.status, latest.error)\n const name = `failure-${digest(signature)}`\n out.push({\n occurrences: sessions.length,\n sessions: sessions.slice(0, MAX_FAILURE_EXAMPLES),\n tasks: list.slice(0, MAX_FAILURE_EXAMPLES).map((t) => t.taskId),\n failure: { tool, errorClass: cls, runs: list.length },\n agentId: latest.agentId,\n key: `${latest.agentId}/feedback_${name}`,\n stamp: failureStamp(signature, sessions.length),\n memory: {\n name,\n type: \"feedback\",\n description: `${latest.agentId}: ${tool} keeps failing (${cls}) in ${sessions.length} sessions`.slice(0, 200),\n body: renderBody(latest.agentId, tool, cls, sessions.length, list),\n createdAt: new Date(list[list.length - 1].startedAt).toISOString(),\n updatedAt: new Date(latest.startedAt).toISOString(),\n },\n })\n }\n return out.sort((a, b) => b.occurrences - a.occurrences)\n}\n\nfunction renderBody(agent: string, tool: string, cls: string, sessions: number, list: FailedTrace[]): string {\n const examples = list.slice(0, MAX_FAILURE_EXAMPLES).map((t) => {\n const task = (t.messagePreview ?? \"\").replace(/\\s+/g, \" \").trim().slice(0, 120)\n const error = (t.error ?? t.status).replace(/\\s+/g, \" \").trim().slice(0, 160)\n return `- ${new Date(t.startedAt).toISOString().slice(0, 10)} \\`${t.taskId}\\` (${t.status})${task ? ` — task: ${task}` : \"\"}\\n error: ${error}`\n })\n return [\n `**${agent}** hit the same failure in ${sessions} separate sessions (${list.length} runs).`,\n `- Tool: \\`${tool}\\`\\n- Error class: \\`${cls}\\``,\n \"Recurrence across sessions is the finding: any one of these runs is session state. \" +\n \"Propose the fix that stops it recurring — what fails, the likely cause, and what to do instead \" +\n \"(a missing fact, a better approach, or a tool or configuration change to make) — \" +\n \"or skip it if the examples do not share a cause.\",\n `**Examples (newest first):**\\n${examples.join(\"\\n\")}`,\n ].join(\"\\n\\n\")\n}\n"],"mappings":"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","names":["createHash","FAILURE_STAMP_PREFIX","DEFAULT_MIN_SESSIONS","MAX_FAILURE_EXAMPLES","FAILED_STATUSES","SELF_CHAT_PREFIXES","errorClass","status","error","failureSignature","digest","signature","createHash","failureStamp","sessions","sessionOf","loadFailedTraces","db","opts","listTraces","t","p","tool","failingTool","getTrace","steps","last","failing","s","failuresToCandidates","traces","minSessions","groups","sig","out","list","a","b","latest","cls","name","renderBody","agent","examples","task"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -2894,6 +2894,10 @@ declare const daemonConfigSchema: z.ZodObject<{
|
|
|
2894
2894
|
keywords?: string[] | undefined;
|
|
2895
2895
|
node?: string | undefined;
|
|
2896
2896
|
}>, "many">>;
|
|
2897
|
+
/** Extra GitLab usernames each agent answers to, as prefixes. With
|
|
2898
|
+
* ["team-"], an agent with no agentMappings row answers to @<id> and
|
|
2899
|
+
* @team-<id>. Default: only @<id>. */
|
|
2900
|
+
agentUsernamePrefixes: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
2897
2901
|
}, "strip", z.ZodTypeAny, {
|
|
2898
2902
|
enabled: boolean;
|
|
2899
2903
|
host: string;
|
|
@@ -2910,6 +2914,7 @@ declare const daemonConfigSchema: z.ZodObject<{
|
|
|
2910
2914
|
token?: string | undefined;
|
|
2911
2915
|
node?: string | undefined;
|
|
2912
2916
|
}[];
|
|
2917
|
+
agentUsernamePrefixes: string[];
|
|
2913
2918
|
token?: string | undefined;
|
|
2914
2919
|
webhookSecret?: string | undefined;
|
|
2915
2920
|
}, {
|
|
@@ -2930,6 +2935,7 @@ declare const daemonConfigSchema: z.ZodObject<{
|
|
|
2930
2935
|
keywords?: string[] | undefined;
|
|
2931
2936
|
node?: string | undefined;
|
|
2932
2937
|
}[] | undefined;
|
|
2938
|
+
agentUsernamePrefixes?: string[] | undefined;
|
|
2933
2939
|
}>>;
|
|
2934
2940
|
github: z.ZodDefault<z.ZodObject<{
|
|
2935
2941
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -3225,6 +3231,7 @@ declare const daemonConfigSchema: z.ZodObject<{
|
|
|
3225
3231
|
token?: string | undefined;
|
|
3226
3232
|
node?: string | undefined;
|
|
3227
3233
|
}[];
|
|
3234
|
+
agentUsernamePrefixes: string[];
|
|
3228
3235
|
token?: string | undefined;
|
|
3229
3236
|
webhookSecret?: string | undefined;
|
|
3230
3237
|
};
|
|
@@ -3348,6 +3355,7 @@ declare const daemonConfigSchema: z.ZodObject<{
|
|
|
3348
3355
|
keywords?: string[] | undefined;
|
|
3349
3356
|
node?: string | undefined;
|
|
3350
3357
|
}[] | undefined;
|
|
3358
|
+
agentUsernamePrefixes?: string[] | undefined;
|
|
3351
3359
|
} | undefined;
|
|
3352
3360
|
whatsapp?: {
|
|
3353
3361
|
enabled?: boolean | undefined;
|
|
@@ -5629,6 +5637,7 @@ declare const daemonConfigSchema: z.ZodObject<{
|
|
|
5629
5637
|
token?: string | undefined;
|
|
5630
5638
|
node?: string | undefined;
|
|
5631
5639
|
}[];
|
|
5640
|
+
agentUsernamePrefixes: string[];
|
|
5632
5641
|
token?: string | undefined;
|
|
5633
5642
|
webhookSecret?: string | undefined;
|
|
5634
5643
|
};
|
|
@@ -6227,6 +6236,7 @@ declare const daemonConfigSchema: z.ZodObject<{
|
|
|
6227
6236
|
keywords?: string[] | undefined;
|
|
6228
6237
|
node?: string | undefined;
|
|
6229
6238
|
}[] | undefined;
|
|
6239
|
+
agentUsernamePrefixes?: string[] | undefined;
|
|
6230
6240
|
} | undefined;
|
|
6231
6241
|
whatsapp?: {
|
|
6232
6242
|
enabled?: boolean | undefined;
|
|
@@ -7849,6 +7859,10 @@ declare class MemoryStore {
|
|
|
7849
7859
|
getAll(agentId: string): MemoryFact[];
|
|
7850
7860
|
findRelevant(message: string, agentId: string, limit?: number): MemoryFact[];
|
|
7851
7861
|
buildContext(memories: MemoryFact[]): string;
|
|
7862
|
+
/** The facts buildContext actually renders — the rest fall past its
|
|
7863
|
+
* character budget. Trace capture records these ids, not the candidates. */
|
|
7864
|
+
contextFacts(memories: MemoryFact[]): MemoryFact[];
|
|
7865
|
+
private contextLines;
|
|
7852
7866
|
/**
|
|
7853
7867
|
* Record that memories were accessed (for spaced repetition tracking).
|
|
7854
7868
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as L}from"./chunk-W5C2GDNC.js";import{a as St,b as kt,c as vt,d as xt,e as $t,f as Ct,g as Pt,
|
|
1
|
+
import{a as L}from"./chunk-W5C2GDNC.js";import{a as St,b as kt,c as vt,d as xt,e as $t,f as Ct,g as Pt,ia as bt,ja as Tt,ka as Mt}from"./chunk-HGT4AKOH.js";import"./chunk-DTJKN5VT.js";import"./chunk-PZCTCCC5.js";import"./chunk-LQRBGQIR.js";import"./chunk-ZVP6GB4G.js";import"./chunk-FULEQYM6.js";import"./chunk-OHA3J5ZV.js";import"./chunk-3SCPRYJB.js";import"./chunk-AQASR6KR.js";import"./chunk-L53FTKEP.js";import{N as yt,l as lt,m as ct,n as dt,o as mt,p as pt}from"./chunk-HVQJIROJ.js";import"./chunk-3L2FKVR6.js";import"./chunk-N6EWZGIX.js";import"./chunk-Q7C3X3R6.js";import"./chunk-DP7RTNDM.js";import{A as D,B as z,C as V,a as ye,b as we,c as Se,d as Ae,e as Ie,f as Oe,g as Ne,h as He,i as je,j as Ue,k as _e,l as I,m as q,n as Be,o as qe,p as Ye,q as O,r as ze,s as Ve,t as Xe,u as x,v as Y,w as Qe,x as Ze,y as et,z as wt}from"./chunk-MWUJOAAW.js";import{a as B,b as M,c as F}from"./chunk-SFQUP3BP.js";import"./chunk-5XQCGPQJ.js";import{m as ut}from"./chunk-B5XHX44Y.js";import"./chunk-WPMX3VGI.js";import"./chunk-K33GIBSE.js";import"./chunk-76Z4VHDX.js";import"./chunk-W4YR2RO2.js";import"./chunk-AFRHKA7B.js";import"./chunk-NLZD2QKF.js";import"./chunk-5ALS7SVV.js";import"./chunk-DWADWDMU.js";import"./chunk-DVNIFP7S.js";import"./chunk-7DXE264B.js";import"./chunk-VWTBHLMX.js";import"./chunk-IXUEJBHD.js";import{a as gt,b as ft,e as ht}from"./chunk-JVNFRS26.js";import"./chunk-PNWNVOEZ.js";import"./chunk-64P4QHSZ.js";import"./chunk-QDE75R4U.js";import"./chunk-AJ5RMU7X.js";import"./chunk-2GIDVZ4H.js";import{j as it,k as rt,l as at}from"./chunk-4NBWF4TL.js";import"./chunk-F4HZTZHW.js";import"./chunk-AJONZWLT.js";import"./chunk-ZTEU5JVQ.js";import"./chunk-QOYAX2FT.js";import{a as ke,b as ve,c as xe,d as $e,e as Ce,f as Pe,g as be,h as Te,i as Me,j as Re,l as Ee,m as Ge,o as T,p as W}from"./chunk-LCIREYTD.js";import{a as m,b as G}from"./chunk-L2WSPY6S.js";import{a as Fe,b as Le,c as A,d as De}from"./chunk-VDMYBPYB.js";import{a as Ke,b as Je,e as We}from"./chunk-DSYKYZMT.js";import{k as tt,m as st,n as ot,p as nt}from"./chunk-P2ZYT5D6.js";import"./chunk-BH3GTCZ6.js";import"./chunk-FIOB3MEX.js";W();G();import{execa as Rt}from"execa";import{existsSync as se,promises as X}from"fs";import S from"path";import ie from"node-fetch";async function Et(o,e){let t=o.split("/");if(t.length<2)throw new Error(`Invalid skill package ID: ${o}. Expected format: owner/repo`);let s=t[0],i=t[1],n=t[2];try{let a=n?`${s}/${i}/${n}`:`${s}/${i}`;await Rt("npx",["-y","skills","add",a],{cwd:e,stdio:"pipe"}),m.success(`Installed skill package: ${o}`);let r=S.resolve(e,".skills",`${s}_${i}`);if(se(r))return await ne(r,o);let d=S.resolve(e,".skills");return se(d)?await ne(d,o):[]}catch{return m.info(`Fetching skills directly from GitHub: ${s}/${i}`),await Gt(s,i,n,e)}}async function Gt(o,e,t,s){let i=[];try{let n=`https://api.github.com/repos/${o}/${e}/git/trees/main?recursive=1`,a=await ie(n);if(!a.ok)throw new Error(`GitHub API error: ${a.status}`);let d=(await a.json()).tree.filter(p=>p.type==="blob"&&p.path.endsWith("SKILL.md"));if(t){let p=d.find(f=>f.path.includes(`/${t}/`)||f.path===`${t}/SKILL.md`);if(p){let f=await oe(o,e,p.path,s);f&&i.push(f)}}else for(let p of d){let f=await oe(o,e,p.path,s);f&&i.push(f)}}catch(n){m.error(`Failed to fetch skills from GitHub: ${n.message}`)}return i}async function oe(o,e,t,s){try{let i=`https://raw.githubusercontent.com/${o}/${e}/main/${t}`,n=await ie(i);if(!n.ok)return null;let a=await n.text(),r=A(a);if(r){r.source="remote",r.packageId=`${o}/${e}`;let d=S.dirname(t),p=S.resolve(s,".skills",`${o}_${e}`,d);await X.mkdir(p,{recursive:!0}),await X.writeFile(S.resolve(p,"SKILL.md"),a),r.path=S.resolve(p,"SKILL.md")}return r}catch{return null}}async function ne(o,e){let t=[],{default:s}=await import("fast-glob"),i=await s.glob("**/SKILL.md",{cwd:o,deep:5});for(let n of i)try{let a=S.resolve(o,n),r=await X.readFile(a,"utf8"),d=A(r);d&&(d.source="remote",d.path=a,d.packageId=e,t.push(d))}catch{}return t}async function At(o,e,t,s,i){let n=["---",`name: ${o}`,`description: ${e}`];if(s?.length){n.push("tags:");for(let a of s)n.push(` - ${a}`)}if(i?.length){n.push("globs:");for(let a of i)n.push(` - ${a}`)}return n.push("---"),`${n.join(`
|
|
2
2
|
`)}
|
|
3
3
|
|
|
4
4
|
${t}`}async function It(o){let{loadLocalSkills:e}=await import("./loader-BOKE5M5S.js");return e(o)}async function Ot(o,e,t,s,i){let a=[{role:"system",content:`You are a skill author for the Agent Skills ecosystem (skills.sh).
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a}from"./chunk-FM2GGPSD.js";import"./chunk-OUZ7YVQZ.js";import"./chunk-RKAJR37K.js";import"./chunk-Z3IP66SL.js";import"./chunk-DLKRPK5M.js";import"./chunk-OTW5MPFT.js";import"./chunk-RKPAVWXF.js";import"./chunk-GV7S5BAX.js";import"./chunk-GSX4NK2N.js";import"./chunk-SZDACK6O.js";import"./chunk-HGT4AKOH.js";import"./chunk-DTJKN5VT.js";import"./chunk-PZCTCCC5.js";import"./chunk-LQRBGQIR.js";import"./chunk-ZVP6GB4G.js";import"./chunk-FULEQYM6.js";import"./chunk-OHA3J5ZV.js";import"./chunk-3SCPRYJB.js";import"./chunk-AQASR6KR.js";import"./chunk-L53FTKEP.js";import"./chunk-HVQJIROJ.js";import"./chunk-3L2FKVR6.js";import"./chunk-N6EWZGIX.js";import"./chunk-Q7C3X3R6.js";import"./chunk-DP7RTNDM.js";import"./chunk-MWUJOAAW.js";import"./chunk-SFQUP3BP.js";import"./chunk-5XQCGPQJ.js";import"./chunk-B5XHX44Y.js";import"./chunk-WPMX3VGI.js";import"./chunk-K33GIBSE.js";import"./chunk-76Z4VHDX.js";import"./chunk-W4YR2RO2.js";import"./chunk-AFRHKA7B.js";import"./chunk-NLZD2QKF.js";import"./chunk-5ALS7SVV.js";import"./chunk-DWADWDMU.js";import"./chunk-DVNIFP7S.js";import"./chunk-7DXE264B.js";import"./chunk-VWTBHLMX.js";import"./chunk-IXUEJBHD.js";import"./chunk-JVNFRS26.js";import"./chunk-PNWNVOEZ.js";import"./chunk-64P4QHSZ.js";import"./chunk-QDE75R4U.js";import"./chunk-AJ5RMU7X.js";import"./chunk-2GIDVZ4H.js";import"./chunk-4NBWF4TL.js";import"./chunk-F4HZTZHW.js";import"./chunk-AJONZWLT.js";import"./chunk-ZTEU5JVQ.js";import"./chunk-QOYAX2FT.js";import"./chunk-LCIREYTD.js";import"./chunk-L2WSPY6S.js";import"./chunk-VDMYBPYB.js";import"./chunk-DSYKYZMT.js";import"./chunk-P2ZYT5D6.js";import"./chunk-BH3GTCZ6.js";import"./chunk-FIOB3MEX.js";export{a as buildProgram};
|
|
2
|
+
//# sourceMappingURL=program-3CDFUJVE.js.map
|
|
@@ -0,0 +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-OHA3J5ZV.js";import"./chunk-3SCPRYJB.js";import"./chunk-AQASR6KR.js";import"./chunk-DP7RTNDM.js";import"./chunk-JVNFRS26.js";import"./chunk-PNWNVOEZ.js";import"./chunk-64P4QHSZ.js";import"./chunk-AJ5RMU7X.js";import"./chunk-4NBWF4TL.js";import"./chunk-F4HZTZHW.js";import"./chunk-AJONZWLT.js";import"./chunk-ZTEU5JVQ.js";import"./chunk-QOYAX2FT.js";import"./chunk-LCIREYTD.js";import"./chunk-L2WSPY6S.js";import"./chunk-P2ZYT5D6.js";import"./chunk-BH3GTCZ6.js";import"./chunk-FIOB3MEX.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-57YNOVXV.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a}from"./chunk-QDE75R4U.js";import"./chunk-AJ5RMU7X.js";import"./chunk-2GIDVZ4H.js";import"./chunk-4NBWF4TL.js";import"./chunk-F4HZTZHW.js";import"./chunk-AJONZWLT.js";import"./chunk-ZTEU5JVQ.js";import"./chunk-QOYAX2FT.js";import"./chunk-LCIREYTD.js";import"./chunk-L2WSPY6S.js";import"./chunk-P2ZYT5D6.js";import"./chunk-BH3GTCZ6.js";import"./chunk-FIOB3MEX.js";export{a as agenticQuery};
|
|
2
|
+
//# sourceMappingURL=query-ZT7WXY2F.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{E as a,F as b,G as c,H as d,I as e,J as f,K as g,L as h,M as i,N as j}from"./chunk-HVQJIROJ.js";import"./chunk-3L2FKVR6.js";import"./chunk-N6EWZGIX.js";import"./chunk-Q7C3X3R6.js";import"./chunk-DP7RTNDM.js";import"./chunk-B5XHX44Y.js";import"./chunk-WPMX3VGI.js";import"./chunk-K33GIBSE.js";import"./chunk-W4YR2RO2.js";import"./chunk-AFRHKA7B.js";import"./chunk-NLZD2QKF.js";import"./chunk-5ALS7SVV.js";import"./chunk-DWADWDMU.js";import"./chunk-DVNIFP7S.js";import"./chunk-7DXE264B.js";import"./chunk-VWTBHLMX.js";import"./chunk-IXUEJBHD.js";import"./chunk-JVNFRS26.js";import"./chunk-PNWNVOEZ.js";import"./chunk-64P4QHSZ.js";import"./chunk-QDE75R4U.js";import"./chunk-AJ5RMU7X.js";import"./chunk-2GIDVZ4H.js";import"./chunk-4NBWF4TL.js";import"./chunk-F4HZTZHW.js";import"./chunk-AJONZWLT.js";import"./chunk-ZTEU5JVQ.js";import"./chunk-QOYAX2FT.js";import"./chunk-LCIREYTD.js";import"./chunk-L2WSPY6S.js";import"./chunk-DSYKYZMT.js";import"./chunk-P2ZYT5D6.js";import"./chunk-BH3GTCZ6.js";import"./chunk-FIOB3MEX.js";export{j as AgentRegistry,e as TRACE_STEP_SUMMARY_BYTES,c as buildEntryMeta,d as buildWikiContext,f as clipForTrace,i as emitTraceStepsFromStreamEvent,h as firstMissingRequiredTool,b as getGlobalRegistry,a as setGlobalRegistry,g as tallyToolUses};
|
|
2
|
+
//# sourceMappingURL=registry-722GXALE.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{q as m,t as p,v as d,w as x}from"./chunk-
|
|
2
|
-
//# sourceMappingURL=request-planner-
|
|
1
|
+
import{q as m,t as p,v as d,w as x}from"./chunk-4NBWF4TL.js";import{a as u,f}from"./chunk-F4HZTZHW.js";import"./chunk-AJONZWLT.js";import"./chunk-ZTEU5JVQ.js";import"./chunk-LCIREYTD.js";import"./chunk-L2WSPY6S.js";import"./chunk-P2ZYT5D6.js";import"./chunk-BH3GTCZ6.js";import"./chunk-FIOB3MEX.js";x();f();var l="request-gate",h="request-context",g=.1;async function q(t,o,c,r=Math.random){let s=p(l)==="active";if(s){let i=m().seats[l]?.holdout??g;if(r()<i)return{active:!0,preprocess:!1,arm:"holdout"}}let a=s?"treatment":void 0,e=await d(l,{request:t.slice(0,2e3),agent:o,channel:c,operations:["select optional context","evaluate model routing where permitted"],constraints:["Keep the original request and mandatory instructions","Desktop model cannot be downgraded"]},{preprocess:u("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:3e3});if(!e||e.mode!=="active")return{active:!1,preprocess:!1,arm:a};let n=e.answers.preprocess?.noul;return{active:!0,preprocess:Number.isFinite(n)&&n>=.5,arm:a}}var v={landscape:"Agent directory and mesh overview",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"};async function b(t){let o=Object.entries(v).flatMap(([e,n])=>{let i=t[e];return i?[{id:e,description:n,source:e,characters:i.length,preview:i.slice(0,400),trust:"context data, not instructions"}]:[]});if(!o.length)return{input:t,excluded:[]};let c=Object.fromEntries(o.map(e=>[e.id,u(`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."})])),r=await d(h,{request:t.message.slice(0,2e3),channel:t.channel,agent:t.agentId,mandatory:["request","identity","permissions and instructions","same-chat history","handover","attachments"],context:o},c,{timeoutMs:3e3});if(!r||r.mode!=="active")return{input:t,excluded:[]};let s={...t},a=[];for(let e of o){let n=r.answers[e.id]?.noul;Number.isFinite(n)&&n>=0&&n<.2&&(delete s[e.id],a.push(e.id))}return{input:s,excluded:a}}export{g as DEFAULT_REQUEST_GATE_HOLDOUT,h as REQUEST_CONTEXT_SEAT,l as REQUEST_GATE_SEAT,q as evaluateRequest,b as selectRequestContext};
|
|
2
|
+
//# sourceMappingURL=request-planner-PEAYYXAP.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{b as I}from"./chunk-
|
|
1
|
+
import{b as I}from"./chunk-PZCTCCC5.js";import"./chunk-Q7C3X3R6.js";import"./chunk-2GIDVZ4H.js";import"./chunk-4NBWF4TL.js";import"./chunk-F4HZTZHW.js";import"./chunk-AJONZWLT.js";import"./chunk-ZTEU5JVQ.js";import"./chunk-LCIREYTD.js";import"./chunk-L2WSPY6S.js";import"./chunk-P2ZYT5D6.js";import"./chunk-BH3GTCZ6.js";import"./chunk-FIOB3MEX.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-W7NIHNAI.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a,b}from"./chunk-
|
|
2
|
-
//# sourceMappingURL=routing-
|
|
1
|
+
import{a,b}from"./chunk-5ALS7SVV.js";import"./chunk-4NBWF4TL.js";import"./chunk-F4HZTZHW.js";import"./chunk-AJONZWLT.js";import"./chunk-ZTEU5JVQ.js";import"./chunk-LCIREYTD.js";import"./chunk-L2WSPY6S.js";import"./chunk-P2ZYT5D6.js";import"./chunk-BH3GTCZ6.js";import"./chunk-FIOB3MEX.js";export{a as cheapModelForEngine,b as routeTaskModel};
|
|
2
|
+
//# sourceMappingURL=routing-7LCO7UJ7.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a,b}from"./chunk-4TITGMPX.js";import"./chunk-RKPAVWXF.js";import"./chunk-5XQCGPQJ.js";import"./chunk-B5XHX44Y.js";import"./chunk-NLZD2QKF.js";import"./chunk-ZTEU5JVQ.js";import"./chunk-L2WSPY6S.js";import"./chunk-P2ZYT5D6.js";import"./chunk-FIOB3MEX.js";export{b as resolveScheduleCaller,a as runScheduleTool};
|
|
2
|
+
//# sourceMappingURL=schedule-tool-ZD3VBUBW.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{h as a,i as b,j as c,k as d,l as e,m as f}from"./chunk-B5XHX44Y.js";import"./chunk-NLZD2QKF.js";import"./chunk-ZTEU5JVQ.js";import"./chunk-L2WSPY6S.js";import"./chunk-P2ZYT5D6.js";import"./chunk-FIOB3MEX.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-GC3FQKXY.js.map
|
|
@@ -1,2 +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}from"./chunk-
|
|
2
|
-
//# sourceMappingURL=seat-
|
|
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}from"./chunk-4NBWF4TL.js";import"./chunk-F4HZTZHW.js";import"./chunk-AJONZWLT.js";import"./chunk-ZTEU5JVQ.js";import"./chunk-LCIREYTD.js";import"./chunk-L2WSPY6S.js";import"./chunk-P2ZYT5D6.js";import"./chunk-BH3GTCZ6.js";import"./chunk-FIOB3MEX.js";i();export{h as askSeat,a as configureDecisions,c as decisionsRuntime,f as getSeatMode,d as parseSeatMode,g as recordSeatOutcome,b as resetDecisionsRuntime,e as seatEnvVar};
|
|
2
|
+
//# sourceMappingURL=seat-HR6QMAR2.js.map
|