agentix-cli 0.69.3 → 0.70.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/dist/agent-V223TG6H.js +2 -0
  2. package/dist/{board-dashboard-U6IZQA4W.js → board-dashboard-HR3PQPFW.js} +2 -2
  3. package/dist/{board-dashboard-U6IZQA4W.js.map → board-dashboard-HR3PQPFW.js.map} +1 -1
  4. package/dist/{chunk-NO2HOK4B.js → chunk-23A5K5UW.js} +3 -3
  5. package/dist/chunk-23A5K5UW.js.map +1 -0
  6. package/dist/{chunk-DW5EHX3M.js → chunk-3IY2YWXP.js} +2 -2
  7. package/dist/{chunk-IULWZA3J.js → chunk-3RC4LO2G.js} +6 -6
  8. package/dist/chunk-3RC4LO2G.js.map +1 -0
  9. package/dist/{chunk-SZJMS7K4.js → chunk-5MUJZODV.js} +19 -19
  10. package/dist/chunk-5MUJZODV.js.map +1 -0
  11. package/dist/{chunk-KPPGT5FJ.js → chunk-6QDOUOKD.js} +2 -2
  12. package/dist/{chunk-E7OACKES.js → chunk-BBIWAJRX.js} +2 -2
  13. package/dist/{chunk-Y57CULGE.js → chunk-C245D4BZ.js} +2 -2
  14. package/dist/{chunk-64P4QHSZ.js → chunk-CECHWYJ2.js} +1 -1
  15. package/dist/{chunk-64P4QHSZ.js.map → chunk-CECHWYJ2.js.map} +1 -1
  16. package/dist/chunk-FBDIJEKL.js +152 -0
  17. package/dist/chunk-FBDIJEKL.js.map +1 -0
  18. package/dist/chunk-JHCI6XCJ.js +5 -0
  19. package/dist/chunk-JHCI6XCJ.js.map +1 -0
  20. package/dist/{chunk-USMCN2X3.js → chunk-LHLNARRW.js} +13 -13
  21. package/dist/chunk-ML6CNRBK.js +105 -0
  22. package/dist/chunk-ML6CNRBK.js.map +1 -0
  23. package/dist/{chunk-FGFDPYL4.js → chunk-P2RYUODK.js} +2 -2
  24. package/dist/chunk-P2RYUODK.js.map +1 -0
  25. package/dist/{chunk-SXKOI2IF.js → chunk-PHDS2HIN.js} +118 -118
  26. package/dist/chunk-PHDS2HIN.js.map +1 -0
  27. package/dist/{chunk-RN5NOIBH.js → chunk-SN5N2FPG.js} +2 -2
  28. package/dist/chunk-TLDQWTSW.js +49 -0
  29. package/dist/chunk-TLDQWTSW.js.map +1 -0
  30. package/dist/chunk-TTVVXBCM.js +2 -0
  31. package/dist/chunk-TTVVXBCM.js.map +1 -0
  32. package/dist/{chunk-B7S66EK7.js → chunk-W7SEPJFH.js} +14 -14
  33. package/dist/chunk-W7SEPJFH.js.map +1 -0
  34. package/dist/chunk-WLMQ5JMX.js +6 -0
  35. package/dist/chunk-WLMQ5JMX.js.map +1 -0
  36. package/dist/{chunk-3FWJXI7H.js → chunk-YBF2QVZ7.js} +2 -2
  37. package/dist/{chunk-VVMOTM3V.js → chunk-YK7GFEGO.js} +2 -2
  38. package/dist/cli.js +1 -1
  39. package/dist/cli.js.map +1 -1
  40. package/dist/{compaction-H5U32UU6.js → compaction-MECSN36J.js} +4 -4
  41. package/dist/compaction-MECSN36J.js.map +1 -0
  42. package/dist/{context-planner-LJT5IKH6.js → context-planner-JU7CNXCB.js} +3 -3
  43. package/dist/context-planner-JU7CNXCB.js.map +1 -0
  44. package/dist/graph-FJ53FDWK.js +2 -0
  45. package/dist/heal-CMQL5SG4.js +2 -0
  46. package/dist/index.d.ts +41 -6
  47. package/dist/index.js +2 -2
  48. package/dist/index.js.map +1 -1
  49. package/dist/loader-YFVSSYSL.js +2 -0
  50. package/dist/memory-extract-YCNCARZ2.js +2 -0
  51. package/dist/migrate-v2-ZOIMGITH.js +4 -0
  52. package/dist/{migrate-v2-KOMPDC6U.js.map → migrate-v2-ZOIMGITH.js.map} +1 -1
  53. package/dist/program-UTELWTXC.js +2 -0
  54. package/dist/promote-B5AOKPQR.js +2 -0
  55. package/dist/{providers-NRPX2FHP.js → providers-ES5KVLI4.js} +2 -2
  56. package/dist/query-QLJNQUUP.js +2 -0
  57. package/dist/registry-CTZFLXGB.js +2 -0
  58. package/dist/{request-planner-YIG5RUN2.js → request-planner-NMOAOZIM.js} +2 -2
  59. package/dist/{review-candidates-2JFQ2M53.js → review-candidates-FLY6HZEN.js} +2 -2
  60. package/dist/{routing-3CIQQZJ4.js → routing-SMIZ77CT.js} +2 -2
  61. package/dist/{seat-HMF3G6BR.js → seat-F3S2HG5G.js} +2 -2
  62. package/dist/{select-2P73MN6O.js → select-5GC7CTPQ.js} +2 -2
  63. package/dist/types-NZOBHQGS.js +2 -0
  64. package/dist/wiki-X76JUHXT.js +2 -0
  65. package/dist/wiki-X76JUHXT.js.map +1 -0
  66. package/package.json +1 -1
  67. package/dist/agent-OJQKD5AI.js +0 -2
  68. package/dist/chunk-4DRNEOOW.js +0 -2
  69. package/dist/chunk-4DRNEOOW.js.map +0 -1
  70. package/dist/chunk-B7S66EK7.js.map +0 -1
  71. package/dist/chunk-EQTSOK7L.js +0 -109
  72. package/dist/chunk-EQTSOK7L.js.map +0 -1
  73. package/dist/chunk-FGFDPYL4.js.map +0 -1
  74. package/dist/chunk-IULWZA3J.js.map +0 -1
  75. package/dist/chunk-JQXG2OO6.js +0 -152
  76. package/dist/chunk-JQXG2OO6.js.map +0 -1
  77. package/dist/chunk-JYBSYW7T.js +0 -45
  78. package/dist/chunk-JYBSYW7T.js.map +0 -1
  79. package/dist/chunk-NO2HOK4B.js.map +0 -1
  80. package/dist/chunk-SXKOI2IF.js.map +0 -1
  81. package/dist/chunk-SZJMS7K4.js.map +0 -1
  82. package/dist/chunk-VDMYBPYB.js +0 -5
  83. package/dist/chunk-VDMYBPYB.js.map +0 -1
  84. package/dist/compaction-H5U32UU6.js.map +0 -1
  85. package/dist/context-planner-LJT5IKH6.js.map +0 -1
  86. package/dist/heal-HVYQD3EZ.js +0 -2
  87. package/dist/loader-EVHZ2R73.js +0 -2
  88. package/dist/memory-extract-F76BE6KA.js +0 -2
  89. package/dist/migrate-v2-KOMPDC6U.js +0 -4
  90. package/dist/program-O67GMIWX.js +0 -2
  91. package/dist/promote-7SU6IJDC.js +0 -2
  92. package/dist/query-CY7F5ZFR.js +0 -2
  93. package/dist/registry-K76DGYLW.js +0 -2
  94. package/dist/types-S6NHM5C3.js +0 -2
  95. package/dist/wiki-VXTUHSRH.js +0 -2
  96. /package/dist/{agent-OJQKD5AI.js.map → agent-V223TG6H.js.map} +0 -0
  97. /package/dist/{chunk-DW5EHX3M.js.map → chunk-3IY2YWXP.js.map} +0 -0
  98. /package/dist/{chunk-KPPGT5FJ.js.map → chunk-6QDOUOKD.js.map} +0 -0
  99. /package/dist/{chunk-E7OACKES.js.map → chunk-BBIWAJRX.js.map} +0 -0
  100. /package/dist/{chunk-Y57CULGE.js.map → chunk-C245D4BZ.js.map} +0 -0
  101. /package/dist/{chunk-USMCN2X3.js.map → chunk-LHLNARRW.js.map} +0 -0
  102. /package/dist/{chunk-RN5NOIBH.js.map → chunk-SN5N2FPG.js.map} +0 -0
  103. /package/dist/{chunk-3FWJXI7H.js.map → chunk-YBF2QVZ7.js.map} +0 -0
  104. /package/dist/{chunk-VVMOTM3V.js.map → chunk-YK7GFEGO.js.map} +0 -0
  105. /package/dist/{heal-HVYQD3EZ.js.map → graph-FJ53FDWK.js.map} +0 -0
  106. /package/dist/{loader-EVHZ2R73.js.map → heal-CMQL5SG4.js.map} +0 -0
  107. /package/dist/{memory-extract-F76BE6KA.js.map → loader-YFVSSYSL.js.map} +0 -0
  108. /package/dist/{program-O67GMIWX.js.map → memory-extract-YCNCARZ2.js.map} +0 -0
  109. /package/dist/{promote-7SU6IJDC.js.map → program-UTELWTXC.js.map} +0 -0
  110. /package/dist/{providers-NRPX2FHP.js.map → promote-B5AOKPQR.js.map} +0 -0
  111. /package/dist/{query-CY7F5ZFR.js.map → providers-ES5KVLI4.js.map} +0 -0
  112. /package/dist/{registry-K76DGYLW.js.map → query-QLJNQUUP.js.map} +0 -0
  113. /package/dist/{routing-3CIQQZJ4.js.map → registry-CTZFLXGB.js.map} +0 -0
  114. /package/dist/{request-planner-YIG5RUN2.js.map → request-planner-NMOAOZIM.js.map} +0 -0
  115. /package/dist/{review-candidates-2JFQ2M53.js.map → review-candidates-FLY6HZEN.js.map} +0 -0
  116. /package/dist/{seat-HMF3G6BR.js.map → routing-SMIZ77CT.js.map} +0 -0
  117. /package/dist/{types-S6NHM5C3.js.map → seat-F3S2HG5G.js.map} +0 -0
  118. /package/dist/{select-2P73MN6O.js.map → select-5GC7CTPQ.js.map} +0 -0
  119. /package/dist/{wiki-VXTUHSRH.js.map → types-NZOBHQGS.js.map} +0 -0
@@ -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, abortSignal: ac.signal },\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,2 @@
1
+ import{a as m,b as n,c as o,d as p,e as q,f as r}from"./chunk-WLMQ5JMX.js";import{a,b,c,d,e,f,g,h,i,j,k,l}from"./chunk-TTVVXBCM.js";import"./chunk-BBIWAJRX.js";import"./chunk-FX3D7YON.js";import"./chunk-72SZI2UW.js";import"./chunk-FCPTN6NF.js";import"./chunk-5MUJZODV.js";import"./chunk-7I7IEX4S.js";import"./chunk-DTX4I5LQ.js";import"./chunk-RGDKHYY2.js";import"./chunk-QIJLFPWE.js";export{o as Classifier,n as GraphStore,m as STARTER_SCHEMA,r as ancestryScore,b as axisDefSchema,a as axisTypeSchema,i as classificationSchema,g as classificationSourceSchema,h as classificationStatusSchema,j as fingerprintEntrySchema,f as graphNodeSchema,d as graphSchemaSchema,p as hashPath,l as indexFileSchema,c as levelDefSchema,e as nodeIdSchema,k as nodesFileSchema,q as pathLabel};
2
+ //# sourceMappingURL=graph-FJ53FDWK.js.map
@@ -0,0 +1,2 @@
1
+ import{a}from"./chunk-C245D4BZ.js";import"./chunk-SFQUP3BP.js";import"./chunk-5MUJZODV.js";import"./chunk-7I7IEX4S.js";import"./chunk-QIJLFPWE.js";export{a as HealEngine};
2
+ //# sourceMappingURL=heal-CMQL5SG4.js.map
package/dist/index.d.ts CHANGED
@@ -29,6 +29,11 @@ interface ProviderOptions {
29
29
  * marks the task aborted in the registry; the underlying request
30
30
  * can hang for hours waiting for the model to finish thinking. */
31
31
  abortSignal?: AbortSignal;
32
+ /** Plain text generation only: no tools, no MCP servers, no hooks, no
33
+ * user/project settings, no session persistence. Helper calls
34
+ * (classifier, summaries, extraction) set this so a CLI-backed provider
35
+ * skips the full interactive startup instead of paying it per call. */
36
+ bare?: boolean;
32
37
  /** Force the model to call one specific tool, making its whole reply the
33
38
  * tool's structured `input`. Anthropic renders this as
34
39
  * `tool_choice: {type:"tool", name}`; OpenAI as
@@ -8726,6 +8731,10 @@ declare class MemoryStore {
8726
8731
  /** Store a fact. Refuses secrets (returns false). Stamps the source's
8727
8732
  * trust, and holds facts from external sources for review. */
8728
8733
  addMemory(agentId: string, fact: Omit<MemoryFact, "id" | "createdAt">): boolean;
8734
+ /** Parsed facts per file, valid while the file's mtime and size hold.
8735
+ * The store is read on every turn and the file only grows, so without
8736
+ * this each task re-parsed a hundred-kilobyte log on the event loop. */
8737
+ private parsedCache;
8729
8738
  getAll(agentId: string): MemoryFact[];
8730
8739
  findRelevant(message: string, agentId: string, limit?: number): MemoryFact[];
8731
8740
  buildContext(memories: MemoryFact[]): string;
@@ -9151,6 +9160,8 @@ interface WikiIndex {
9151
9160
  backlinks: number;
9152
9161
  sources?: string[];
9153
9162
  lastUpdated?: string;
9163
+ /** Intent-graph path the article's sources were classified under. */
9164
+ graphPath?: string[];
9154
9165
  }>;
9155
9166
  lastRebuilt: string;
9156
9167
  }
@@ -9213,6 +9224,11 @@ declare class WikiStore {
9213
9224
  /**
9214
9225
  * List all articles accessible to an agent.
9215
9226
  */
9227
+ /** Catalog per agent, valid while no article file changed. The walk is
9228
+ * repeated (names, mtimes, sizes) but the frontmatter parse of every
9229
+ * article is not; on a wiki of ten thousand files that parse was the
9230
+ * cost of every fresh session. */
9231
+ private listCache;
9216
9232
  listArticles(agentId: string): WikiArticle[];
9217
9233
  /**
9218
9234
  * Search articles by keyword. Returns articles the agent can read.
@@ -9691,7 +9707,8 @@ declare const graphNodeSchema: z.ZodObject<{
9691
9707
  createdBy?: string | undefined;
9692
9708
  }>;
9693
9709
  type GraphNode = z.infer<typeof graphNodeSchema>;
9694
- declare const classificationSourceSchema: z.ZodEnum<["llm", "user", "cache"]>;
9710
+ /** "seat": the intent-path decision seat picked an existing path. */
9711
+ declare const classificationSourceSchema: z.ZodEnum<["llm", "user", "cache", "seat"]>;
9695
9712
  type ClassificationSource = z.infer<typeof classificationSourceSchema>;
9696
9713
  declare const classificationStatusSchema: z.ZodEnum<["pending", "approved", "rejected"]>;
9697
9714
  type ClassificationStatus = z.infer<typeof classificationStatusSchema>;
@@ -9701,6 +9718,9 @@ declare const classificationSchema: z.ZodObject<{
9701
9718
  agentId: z.ZodOptional<z.ZodString>;
9702
9719
  channel: z.ZodOptional<z.ZodString>;
9703
9720
  sender: z.ZodOptional<z.ZodString>;
9721
+ /** The conversation the message belongs to. Lets a tool running inside
9722
+ * that conversation find the path its request was filed under. */
9723
+ chatId: z.ZodOptional<z.ZodString>;
9704
9724
  /** Node ids from root to leaf, one per level. Shorter-than-full paths are
9705
9725
  * allowed if the classifier was only confident down to a certain depth. */
9706
9726
  path: z.ZodArray<z.ZodString, "many">;
@@ -9718,7 +9738,7 @@ declare const classificationSchema: z.ZodObject<{
9718
9738
  output?: string | undefined;
9719
9739
  input?: string | undefined;
9720
9740
  }>>;
9721
- source: z.ZodEnum<["llm", "user", "cache"]>;
9741
+ source: z.ZodEnum<["llm", "user", "cache", "seat"]>;
9722
9742
  status: z.ZodEnum<["pending", "approved", "rejected"]>;
9723
9743
  confidence: z.ZodOptional<z.ZodNumber>;
9724
9744
  /** Redacted first ~200 chars of the message, for the approval UI. */
@@ -9726,7 +9746,7 @@ declare const classificationSchema: z.ZodObject<{
9726
9746
  }, "strip", z.ZodTypeAny, {
9727
9747
  path: string[];
9728
9748
  status: "pending" | "approved" | "rejected";
9729
- source: "user" | "llm" | "cache";
9749
+ source: "user" | "seat" | "llm" | "cache";
9730
9750
  ts: string;
9731
9751
  msgHash: string;
9732
9752
  proposedAxes: Record<string, Record<string, string>>;
@@ -9736,17 +9756,19 @@ declare const classificationSchema: z.ZodObject<{
9736
9756
  };
9737
9757
  channel?: string | undefined;
9738
9758
  preview?: string | undefined;
9759
+ chatId?: string | undefined;
9739
9760
  agentId?: string | undefined;
9740
9761
  confidence?: number | undefined;
9741
9762
  sender?: string | undefined;
9742
9763
  }, {
9743
9764
  path: string[];
9744
9765
  status: "pending" | "approved" | "rejected";
9745
- source: "user" | "llm" | "cache";
9766
+ source: "user" | "seat" | "llm" | "cache";
9746
9767
  ts: string;
9747
9768
  msgHash: string;
9748
9769
  channel?: string | undefined;
9749
9770
  preview?: string | undefined;
9771
+ chatId?: string | undefined;
9750
9772
  agentId?: string | undefined;
9751
9773
  confidence?: number | undefined;
9752
9774
  sender?: string | undefined;
@@ -10009,10 +10031,23 @@ declare class GraphStore {
10009
10031
  }): Classification | null;
10010
10032
  /** Read the last N classifications, newest first. Cheap enough for the admin UI. */
10011
10033
  readRecentClassifications(limit?: number): Classification[];
10034
+ /**
10035
+ * The path the most recent classification in a conversation was filed
10036
+ * under, or undefined. Used by tools running inside that conversation
10037
+ * (`agentx_wiki_query`) to bias retrieval toward articles on the same
10038
+ * branch. Bounded by age so a stale label from a day-old thread does not
10039
+ * steer an unrelated question.
10040
+ */
10041
+ latestPathForChat(agentId: string, channel: string, chatId: string, maxAgeMs?: number): string[] | undefined;
10012
10042
  /**
10013
10043
  * Hash that represents "this kind of message" for snap-to-path caching.
10014
- * Normalizes casing + whitespace; includes channel + sender so two people
10015
- * writing the same words can still land on different paths if they should.
10044
+ *
10045
+ * Keyed on the normalized wording plus the channel. The sender used to be
10046
+ * part of the key too, and the exact text was: measured over the last
10047
+ * 2,000 classifications, 89% missed, so nearly every task paid an LLM
10048
+ * call for a taxonomy label. Identifiers, numbers, links and mentions
10049
+ * are what differ between two messages that mean the same thing, so
10050
+ * they are folded away (see `normalizeForFingerprint`).
10016
10051
  */
10017
10052
  fingerprint(msg: {
10018
10053
  text: string;
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import{a as L}from"./chunk-Y57CULGE.js";import{a as St,b as kt,c as vt,d as xt,da as Tt,e as $t,ea as Mt,f as Ct,g as Pt,h as bt}from"./chunk-SXKOI2IF.js";import"./chunk-DW5EHX3M.js";import"./chunk-BYJ3A55Y.js";import"./chunk-NMFXY3QU.js";import"./chunk-3FWJXI7H.js";import"./chunk-LQRBGQIR.js";import"./chunk-ZVP6GB4G.js";import"./chunk-VVMOTM3V.js";import"./chunk-2D3RYIDU.js";import"./chunk-EKJG63EJ.js";import{S as yt,l as lt,m as ct,n as dt,o as mt,p as pt}from"./chunk-JQXG2OO6.js";import"./chunk-B7S66EK7.js";import"./chunk-N6EWZGIX.js";import"./chunk-WP6KLXTP.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-IULWZA3J.js";import{a as B,b as M,c as F}from"./chunk-SFQUP3BP.js";import"./chunk-FSYA4GNU.js";import"./chunk-2AXFYDWF.js";import"./chunk-AQASR6KR.js";import"./chunk-76Z4VHDX.js";import"./chunk-W4YR2RO2.js";import"./chunk-AFRHKA7B.js";import{s as ut}from"./chunk-OPUPVGYP.js";import"./chunk-YL223TEU.js";import"./chunk-KA2UIZXG.js";import"./chunk-GQ76J72O.js";import"./chunk-ILEC3IAV.js";import"./chunk-J3SOEFRE.js";import"./chunk-SIU6STB2.js";import"./chunk-X5C5W3E4.js";import"./chunk-FGFDPYL4.js";import"./chunk-DWADWDMU.js";import"./chunk-NO2HOK4B.js";import"./chunk-QD6IICK7.js";import"./chunk-VWTBHLMX.js";import"./chunk-RN5NOIBH.js";import{a as gt,b as ft,e as ht}from"./chunk-EQTSOK7L.js";import"./chunk-4DRNEOOW.js";import"./chunk-64P4QHSZ.js";import"./chunk-JYBSYW7T.js";import"./chunk-TFVUOC2C.js";import"./chunk-2GIDVZ4H.js";import{j as it,k as rt,l as at}from"./chunk-E7OACKES.js";import"./chunk-FX3D7YON.js";import"./chunk-72SZI2UW.js";import"./chunk-FCPTN6NF.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-SZJMS7K4.js";import{a as m,b as G}from"./chunk-7I7IEX4S.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{u as tt,w as st,x as ot,z as nt}from"./chunk-DTX4I5LQ.js";import"./chunk-RGDKHYY2.js";import"./chunk-QIJLFPWE.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(`
1
+ import{a as L}from"./chunk-C245D4BZ.js";import{a as St,b as kt,c as vt,d as xt,da as Tt,e as $t,ea as Mt,f as Ct,g as Pt,h as bt}from"./chunk-PHDS2HIN.js";import"./chunk-3IY2YWXP.js";import"./chunk-YBF2QVZ7.js";import"./chunk-BYJ3A55Y.js";import"./chunk-NMFXY3QU.js";import"./chunk-LQRBGQIR.js";import"./chunk-ZVP6GB4G.js";import"./chunk-YK7GFEGO.js";import"./chunk-AQASR6KR.js";import"./chunk-2D3RYIDU.js";import"./chunk-EKJG63EJ.js";import{S as yt,l as lt,m as ct,n as dt,o as mt,p as pt}from"./chunk-FBDIJEKL.js";import"./chunk-W7SEPJFH.js";import"./chunk-WP6KLXTP.js";import"./chunk-N6EWZGIX.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-3RC4LO2G.js";import{a as B,b as M,c as F}from"./chunk-SFQUP3BP.js";import"./chunk-FSYA4GNU.js";import"./chunk-2AXFYDWF.js";import"./chunk-76Z4VHDX.js";import"./chunk-W4YR2RO2.js";import"./chunk-AFRHKA7B.js";import{s as ut}from"./chunk-OPUPVGYP.js";import"./chunk-YL223TEU.js";import"./chunk-VWTBHLMX.js";import"./chunk-SN5N2FPG.js";import{a as ht}from"./chunk-ML6CNRBK.js";import"./chunk-KA2UIZXG.js";import"./chunk-GQ76J72O.js";import"./chunk-ILEC3IAV.js";import"./chunk-J3SOEFRE.js";import"./chunk-SIU6STB2.js";import"./chunk-X5C5W3E4.js";import"./chunk-P2RYUODK.js";import"./chunk-DWADWDMU.js";import"./chunk-23A5K5UW.js";import"./chunk-QD6IICK7.js";import"./chunk-CECHWYJ2.js";import"./chunk-TLDQWTSW.js";import"./chunk-TFVUOC2C.js";import"./chunk-2GIDVZ4H.js";import"./chunk-QOYAX2FT.js";import{a as gt,b as ft}from"./chunk-WLMQ5JMX.js";import"./chunk-TTVVXBCM.js";import{j as it,k as rt,l as at}from"./chunk-BBIWAJRX.js";import"./chunk-FX3D7YON.js";import"./chunk-72SZI2UW.js";import"./chunk-FCPTN6NF.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-5MUJZODV.js";import{a as m,b as G}from"./chunk-7I7IEX4S.js";import{b as Fe,c as Le,d as A,e as De}from"./chunk-JHCI6XCJ.js";import{a as Ke,b as Je,e as We}from"./chunk-DSYKYZMT.js";import{u as tt,w as st,x as ot,z as nt}from"./chunk-DTX4I5LQ.js";import"./chunk-RGDKHYY2.js";import"./chunk-QIJLFPWE.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
- ${t}`}async function It(o){let{loadLocalSkills:e}=await import("./loader-EVHZ2R73.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).
4
+ ${t}`}async function It(o){let{loadLocalSkills:e}=await import("./loader-YFVSSYSL.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).
5
5
  You create high-quality SKILL.md files that provide reusable instructions for AI coding agents.
6
6
 
7
7
  A skill is a markdown document with YAML frontmatter that teaches an agent how to perform a specific task.