agentix-cli 0.126.2 → 0.128.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 (152) hide show
  1. package/dist/{App-BUYK4EGC.js → App-BOLQUKCN.js} +2 -2
  2. package/dist/{ChatApp-ZS6EPDDK.js → ChatApp-72HXQV24.js} +2 -2
  3. package/dist/absorb-eval-O3HA6XA5.js +2 -0
  4. package/dist/{agent-WJTYM5HR.js → agent-S2DXXALS.js} +2 -2
  5. package/dist/{board-dashboard-DQR2OSV7.js → board-dashboard-ZKXXK5CG.js} +303 -228
  6. package/dist/board-dashboard-ZKXXK5CG.js.map +1 -0
  7. package/dist/chunk-2SV4RKRW.js +128 -0
  8. package/dist/chunk-2SV4RKRW.js.map +1 -0
  9. package/dist/{chunk-WUDVBPQV.js → chunk-4V7SWL2S.js} +2 -2
  10. package/dist/chunk-52SIHG45.js +4 -0
  11. package/dist/chunk-52SIHG45.js.map +1 -0
  12. package/dist/chunk-5DAEJF5S.js +36 -0
  13. package/dist/chunk-5DAEJF5S.js.map +1 -0
  14. package/dist/{chunk-GUQDPA6R.js → chunk-6GGGXCOY.js} +2 -2
  15. package/dist/{chunk-JIXNSA67.js → chunk-6KIUVVKX.js} +2 -2
  16. package/dist/{chunk-O4XEQTEN.js → chunk-C5MTLW7O.js} +3 -3
  17. package/dist/chunk-C5MTLW7O.js.map +1 -0
  18. package/dist/{chunk-FHBPKMCF.js → chunk-D2WX3BET.js} +2 -2
  19. package/dist/chunk-DN3RLR5Z.js +17 -0
  20. package/dist/chunk-DN3RLR5Z.js.map +1 -0
  21. package/dist/{chunk-Z7XXUYBB.js → chunk-DQ2LNQ2D.js} +33 -35
  22. package/dist/chunk-DQ2LNQ2D.js.map +1 -0
  23. package/dist/{chunk-UUVFH7BO.js → chunk-EJT4MA3J.js} +102 -102
  24. package/dist/chunk-EJT4MA3J.js.map +1 -0
  25. package/dist/chunk-FSW4FUMW.js +55 -0
  26. package/dist/chunk-FSW4FUMW.js.map +1 -0
  27. package/dist/chunk-FXBMFGOV.js +6 -0
  28. package/dist/chunk-FXBMFGOV.js.map +1 -0
  29. package/dist/{chunk-WMTGAVPW.js → chunk-HKW56YZK.js} +2 -2
  30. package/dist/{chunk-VXKNB4AW.js → chunk-LDS4SZBU.js} +2 -2
  31. package/dist/chunk-MRYA4J5F.js +54 -0
  32. package/dist/chunk-MRYA4J5F.js.map +1 -0
  33. package/dist/{chunk-LVV7JBHM.js → chunk-O2BS6N3T.js} +2 -2
  34. package/dist/{chunk-ZQWWMAMJ.js → chunk-P4XGM7ZM.js} +2 -2
  35. package/dist/{chunk-D6SWAB5J.js → chunk-QACEFESP.js} +32 -32
  36. package/dist/chunk-QACEFESP.js.map +1 -0
  37. package/dist/{chunk-6GLJIA25.js → chunk-QFZU5CEO.js} +2 -2
  38. package/dist/{chunk-FVG2BADS.js → chunk-QQFURUMS.js} +2 -2
  39. package/dist/chunk-QUXMLLX5.js +2 -0
  40. package/dist/chunk-QUXMLLX5.js.map +1 -0
  41. package/dist/{chunk-CY6ABHF2.js → chunk-TG6CT54D.js} +2 -2
  42. package/dist/chunk-TPNTFCSQ.js +4 -0
  43. package/dist/chunk-TPNTFCSQ.js.map +1 -0
  44. package/dist/{chunk-56KNKUFF.js → chunk-VD7IO653.js} +3 -3
  45. package/dist/{chunk-56KNKUFF.js.map → chunk-VD7IO653.js.map} +1 -1
  46. package/dist/{chunk-JUIL2EW3.js → chunk-YWKLUQDC.js} +2 -2
  47. package/dist/chunk-Z3W7D5RR.js +4 -0
  48. package/dist/chunk-Z3W7D5RR.js.map +1 -0
  49. package/dist/{chunk-QQYXYJOG.js → chunk-ZLC4TSXF.js} +2 -2
  50. package/dist/cli.js +1 -1
  51. package/dist/{client-PO5LDFS4.js → client-VBV7Q43P.js} +2 -2
  52. package/dist/config-52C3DJD2.js +2 -0
  53. package/dist/config-mutate-DKQESY6F.js +2 -0
  54. package/dist/config-mutator-BF4D4QGN.js +2 -0
  55. package/dist/contributions-5OEZWYXI.js +57 -0
  56. package/dist/contributions-5OEZWYXI.js.map +1 -0
  57. package/dist/doctor-VLRC4HW2.js +2 -0
  58. package/dist/{follow-up-tool-AIOLNUF7.js → follow-up-tool-235LDEMP.js} +2 -2
  59. package/dist/{follow-up-tool-AIOLNUF7.js.map → follow-up-tool-235LDEMP.js.map} +1 -1
  60. package/dist/hub-5QK7KYTZ.js +2 -0
  61. package/dist/index.d.ts +339 -50
  62. package/dist/index.js +1 -1
  63. package/dist/index.js.map +1 -1
  64. package/dist/notes-YLTNRMB5.js +2 -0
  65. package/dist/notes-settings-X63D5HPM.js +2 -0
  66. package/dist/{program-LGCT7FFJ.js → program-MVD57PKP.js} +236 -232
  67. package/dist/program-MVD57PKP.js.map +1 -0
  68. package/dist/{promote-MQYJMGGZ.js → promote-UPPQ4BQE.js} +2 -2
  69. package/dist/query-XQS5JN6E.js +2 -0
  70. package/dist/registry-MOMTLJ6R.js +2 -0
  71. package/dist/{request-planner-XYHM26CO.js → request-planner-QGZJEAKY.js} +2 -2
  72. package/dist/{review-candidates-XRBAMRBH.js → review-candidates-PAKF2JQF.js} +2 -2
  73. package/dist/{rotation-memo-6UW6DTBQ.js → rotation-memo-7VLREGS6.js} +2 -2
  74. package/dist/routing-JG3EV4O4.js +2 -0
  75. package/dist/schedule-tool-O7ZZ2A7X.js +2 -0
  76. package/dist/scheduler-LMPBAA34.js +2 -0
  77. package/dist/scheduler-LMPBAA34.js.map +1 -0
  78. package/dist/score-KDNIUTNV.js +3 -0
  79. package/dist/score-KDNIUTNV.js.map +1 -0
  80. package/dist/{seat-LKBZ6SDS.js → seat-JN3IVZ3G.js} +2 -2
  81. package/dist/seat-JN3IVZ3G.js.map +1 -0
  82. package/dist/{select-BSC3TFMZ.js → select-ZMMRFMNO.js} +2 -2
  83. package/dist/{set-enabled-YWXWSKME.js → set-enabled-7Y3TW6Z4.js} +2 -2
  84. package/dist/{tool-FZEC5FQX.js → tool-OCYXCDOK.js} +2 -2
  85. package/dist/{tool-FZEC5FQX.js.map → tool-OCYXCDOK.js.map} +1 -1
  86. package/dist/{tool-5JTCSRTW.js → tool-S7QI6HRA.js} +2 -2
  87. package/dist/{tool-5JTCSRTW.js.map → tool-S7QI6HRA.js.map} +1 -1
  88. package/dist/wiki-OCLFFZG6.js +2 -0
  89. package/dist/wiki-OCLFFZG6.js.map +1 -0
  90. package/package.json +1 -1
  91. package/dist/absorb-eval-5Y5IZWW2.js +0 -2
  92. package/dist/board-dashboard-DQR2OSV7.js.map +0 -1
  93. package/dist/chunk-2C3X6DVD.js +0 -49
  94. package/dist/chunk-2C3X6DVD.js.map +0 -1
  95. package/dist/chunk-2W3X6H7Z.js +0 -51
  96. package/dist/chunk-2W3X6H7Z.js.map +0 -1
  97. package/dist/chunk-46JKX6CT.js +0 -54
  98. package/dist/chunk-46JKX6CT.js.map +0 -1
  99. package/dist/chunk-5DFUUYEA.js +0 -126
  100. package/dist/chunk-5DFUUYEA.js.map +0 -1
  101. package/dist/chunk-D6SWAB5J.js.map +0 -1
  102. package/dist/chunk-O4XEQTEN.js.map +0 -1
  103. package/dist/chunk-UUVFH7BO.js.map +0 -1
  104. package/dist/chunk-YNA5T43U.js +0 -4
  105. package/dist/chunk-YNA5T43U.js.map +0 -1
  106. package/dist/chunk-Z7XXUYBB.js.map +0 -1
  107. package/dist/config-L2RQ6EJX.js +0 -2
  108. package/dist/config-mutator-44OAOZXM.js +0 -2
  109. package/dist/doctor-AU5TCOSG.js +0 -2
  110. package/dist/hub-53YQQCVA.js +0 -2
  111. package/dist/program-LGCT7FFJ.js.map +0 -1
  112. package/dist/query-DNJONEKC.js +0 -2
  113. package/dist/registry-5A3SLBVJ.js +0 -2
  114. package/dist/routing-OMIWZKNC.js +0 -2
  115. package/dist/schedule-tool-YRANRFHO.js +0 -2
  116. package/dist/scheduler-L4P4Z55R.js +0 -2
  117. package/dist/wiki-BT3H2WCD.js +0 -2
  118. /package/dist/{App-BUYK4EGC.js.map → App-BOLQUKCN.js.map} +0 -0
  119. /package/dist/{ChatApp-ZS6EPDDK.js.map → ChatApp-72HXQV24.js.map} +0 -0
  120. /package/dist/{absorb-eval-5Y5IZWW2.js.map → absorb-eval-O3HA6XA5.js.map} +0 -0
  121. /package/dist/{agent-WJTYM5HR.js.map → agent-S2DXXALS.js.map} +0 -0
  122. /package/dist/{chunk-WUDVBPQV.js.map → chunk-4V7SWL2S.js.map} +0 -0
  123. /package/dist/{chunk-GUQDPA6R.js.map → chunk-6GGGXCOY.js.map} +0 -0
  124. /package/dist/{chunk-JIXNSA67.js.map → chunk-6KIUVVKX.js.map} +0 -0
  125. /package/dist/{chunk-FHBPKMCF.js.map → chunk-D2WX3BET.js.map} +0 -0
  126. /package/dist/{chunk-WMTGAVPW.js.map → chunk-HKW56YZK.js.map} +0 -0
  127. /package/dist/{chunk-VXKNB4AW.js.map → chunk-LDS4SZBU.js.map} +0 -0
  128. /package/dist/{chunk-LVV7JBHM.js.map → chunk-O2BS6N3T.js.map} +0 -0
  129. /package/dist/{chunk-ZQWWMAMJ.js.map → chunk-P4XGM7ZM.js.map} +0 -0
  130. /package/dist/{chunk-6GLJIA25.js.map → chunk-QFZU5CEO.js.map} +0 -0
  131. /package/dist/{chunk-FVG2BADS.js.map → chunk-QQFURUMS.js.map} +0 -0
  132. /package/dist/{chunk-CY6ABHF2.js.map → chunk-TG6CT54D.js.map} +0 -0
  133. /package/dist/{chunk-JUIL2EW3.js.map → chunk-YWKLUQDC.js.map} +0 -0
  134. /package/dist/{chunk-QQYXYJOG.js.map → chunk-ZLC4TSXF.js.map} +0 -0
  135. /package/dist/{client-PO5LDFS4.js.map → client-VBV7Q43P.js.map} +0 -0
  136. /package/dist/{config-L2RQ6EJX.js.map → config-52C3DJD2.js.map} +0 -0
  137. /package/dist/{config-mutator-44OAOZXM.js.map → config-mutate-DKQESY6F.js.map} +0 -0
  138. /package/dist/{doctor-AU5TCOSG.js.map → config-mutator-BF4D4QGN.js.map} +0 -0
  139. /package/dist/{hub-53YQQCVA.js.map → doctor-VLRC4HW2.js.map} +0 -0
  140. /package/dist/{promote-MQYJMGGZ.js.map → hub-5QK7KYTZ.js.map} +0 -0
  141. /package/dist/{query-DNJONEKC.js.map → notes-YLTNRMB5.js.map} +0 -0
  142. /package/dist/{registry-5A3SLBVJ.js.map → notes-settings-X63D5HPM.js.map} +0 -0
  143. /package/dist/{routing-OMIWZKNC.js.map → promote-UPPQ4BQE.js.map} +0 -0
  144. /package/dist/{schedule-tool-YRANRFHO.js.map → query-XQS5JN6E.js.map} +0 -0
  145. /package/dist/{scheduler-L4P4Z55R.js.map → registry-MOMTLJ6R.js.map} +0 -0
  146. /package/dist/{request-planner-XYHM26CO.js.map → request-planner-QGZJEAKY.js.map} +0 -0
  147. /package/dist/{review-candidates-XRBAMRBH.js.map → review-candidates-PAKF2JQF.js.map} +0 -0
  148. /package/dist/{rotation-memo-6UW6DTBQ.js.map → rotation-memo-7VLREGS6.js.map} +0 -0
  149. /package/dist/{seat-LKBZ6SDS.js.map → routing-JG3EV4O4.js.map} +0 -0
  150. /package/dist/{wiki-BT3H2WCD.js.map → schedule-tool-O7ZZ2A7X.js.map} +0 -0
  151. /package/dist/{select-BSC3TFMZ.js.map → select-ZMMRFMNO.js.map} +0 -0
  152. /package/dist/{set-enabled-YWXWSKME.js.map → set-enabled-7Y3TW6Z4.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/wiki/contributions.ts"],"sourcesContent":["import { createHash } from \"crypto\"\nimport { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, writeFileSync } from \"fs\"\nimport { resolve } from \"path\"\nimport type Database from \"better-sqlite3\"\nimport { buildIndex, scoreAll } from \"@/memory/bm25\"\nimport { getTrace, listTraces } from \"@/storage/traces\"\nimport { FactLedger } from \"./facts/ledger\"\nimport { lostStructuredFacts } from \"./fact-guard\"\nimport type { WikiHub } from \"./hub\"\nimport type { WikiStore } from \"./store\"\nimport { isWikiArticleType, type WikiArticle, type WikiArticleType } from \"./types\"\n\n// --- Daily per-agent wiki contributions (#824) ---\n//\n// Only the central absorb wrote the wiki, and it missed what agents learn\n// while working: a fleet test found money and status facts weeks stale\n// although the owning agent had checked the current values that day.\n//\n// So each opted-in agent reviews its own work once a day (its chat turns\n// and its task traces, with the tool calls it ran) and proposes small,\n// sourced patches:\n//\n// add one fact line for a page\n// correct the page states an old value; give the exact old text and\n// the new value\n// create a short page for an entity that has none\n//\n// Every patch needs a source and a check date; one without is dropped.\n// There is no field for a page body, so an agent cannot rewrite a page:\n// rewrites are what lost facts in the test.\n//\n// One merge a day applies them all. Facts go through the fact ledger\n// (facts/ledger.ts), so the newest check wins and the older value stays\n// in the fact's history; pages keep every earlier body in `_versions/`.\n// A patch that removes a fact, or an edit that would lose a phone number,\n// email, role, contact marker, link or number, is held for a person.\n//\n// Storage, all skipped by the article index (`_` prefix):\n// _contributions/state.json per-agent cursor\n// _contributions/pending/<run>.json one batch per agent run\n// _contributions/merged/<run>.json batches a merge consumed\n// _contributions/reports/<time>.json what each merge did\n// _contributions/held.json patches waiting for a person\n\nexport type ContributionKind = \"add\" | \"correct\" | \"create\" | \"remove\"\n\nexport interface ContributionPatch {\n /** Stable for the same agent, page, attribute, value and check. */\n id: string\n kind: ContributionKind\n /** Title of the page the patch is about. */\n page: string\n /** For `create`: the article type. */\n pageType?: WikiArticleType\n /** For `create`: other names the subject goes by. */\n aliases?: string[]\n /** \"phone\", \"billing status\", \"main contact\"… */\n attribute?: string\n value?: string\n /** For `correct` and `remove`: the exact text on the page that is wrong. */\n previous?: string\n /** For `create`: one sentence saying what the entity is. */\n summary?: string\n /** Where the agent checked it: a system, command, URL or \"owner said\". */\n source: string\n /** When it was checked (ISO). */\n checkedAt: string\n agentId: string\n}\n\nexport interface ContributionBatch {\n id: string\n agentId: string\n runAt: string\n model: string\n /** Chat entries and task traces the run read. */\n workIds: string[]\n patches: ContributionPatch[]\n costUsd: number\n calls: number\n /** Why the run stopped before reading all of the agent's new work. */\n stoppedBy?: \"max-patches\" | \"max-cost\" | \"max-items\"\n}\n\nexport interface ContributionLimits {\n /** Patches one run may submit. */\n maxPatches: number\n /** Model spend one run may reach, in USD. Each call is capped at what\n * is left, and no call starts once it is spent. */\n maxCostUsd: number\n /** Chat entries and task traces one run reads. */\n maxItems: number\n}\n\nexport const DEFAULT_CONTRIBUTION_LIMITS: ContributionLimits = { maxPatches: 30, maxCostUsd: 0.5, maxItems: 60 }\n\n/** Work items sent to the model per call. */\nconst ITEMS_PER_CALL = 12\nconst ITEM_CHARS = 2000\nconst PAGE_CHARS = 1500\nconst PAGES_PER_CALL = 8\nconst FIELD_CHARS = 300\nconst STEPS_PER_TRACE = 12\nexport const FACTS_HEADING = \"## Checked facts\"\n\n// --- Storage -----------------------------------------------------------------\n\nexport function contributionsDir(wikiDir: string): string {\n return resolve(wikiDir, \"_contributions\")\n}\n\ninterface ContributionState {\n agents: Record<string, { lastRunAt: string; processed: string[] }>\n}\n\nfunction readJson<T>(file: string, fallback: T): T {\n if (!existsSync(file)) return fallback\n try {\n return JSON.parse(readFileSync(file, \"utf-8\")) as T\n } catch (err) {\n // A damaged file read as empty would be overwritten on the next save.\n throw new Error(`${file} is not valid JSON: ${(err as Error).message}`)\n }\n}\n\nfunction writeJson(file: string, data: unknown): void {\n mkdirSync(resolve(file, \"..\"), { recursive: true })\n const tmp = `${file}.${process.pid}.tmp`\n writeFileSync(tmp, `${JSON.stringify(data, null, 2)}\\n`)\n renameSync(tmp, file)\n}\n\nfunction readState(wikiDir: string): ContributionState {\n const s = readJson<ContributionState>(resolve(contributionsDir(wikiDir), \"state.json\"), { agents: {} })\n return { agents: s.agents ?? {} }\n}\n\nexport function listPendingBatches(wikiDir: string): ContributionBatch[] {\n const dir = resolve(contributionsDir(wikiDir), \"pending\")\n if (!existsSync(dir)) return []\n return readdirSync(dir).filter((f) => f.endsWith(\".json\")).sort()\n .map((f) => readJson<ContributionBatch | null>(resolve(dir, f), null))\n .filter((b): b is ContributionBatch => !!b)\n}\n\nexport interface HeldPatch {\n id: string\n patch: ContributionPatch\n reason: string\n /** Facts the change would have lost. */\n lost?: string[]\n heldAt: string\n status: \"held\" | \"approved\" | \"rejected\"\n decidedBy?: string\n decidedAt?: string\n}\n\nfunction heldFile(wikiDir: string): string {\n return resolve(contributionsDir(wikiDir), \"held.json\")\n}\n\n/** Held patches; only those still waiting unless `all`. */\nexport function listHeld(wikiDir: string, opts: { all?: boolean } = {}): HeldPatch[] {\n const list = readJson<HeldPatch[]>(heldFile(wikiDir), [])\n return opts.all ? list : list.filter((h) => h.status === \"held\")\n}\n\nexport function latestReport(wikiDir: string): MergeReport | null {\n const dir = resolve(contributionsDir(wikiDir), \"reports\")\n if (!existsSync(dir)) return null\n const last = readdirSync(dir).filter((f) => f.endsWith(\".json\")).sort().pop()\n return last ? readJson<MergeReport | null>(resolve(dir, last), null) : null\n}\n\n// --- What a run reads --------------------------------------------------------\n\n/** One piece of the agent's work: a chat turn or a task it ran. */\nexport interface WorkItem {\n id: string\n /** ISO time (or date) the work happened. */\n at: string\n kind: \"chat\" | \"task\"\n title: string\n text: string\n}\n\n/**\n * The agent's work since its last run, oldest first: its chat entries\n * from the wiki's raw pool and, given the trace database, the tasks it ran\n * with their tool calls and results. On a first run `since` (default:\n * the day before `now`) bounds the window.\n */\nexport function pendingWork(\n hub: WikiHub, wikiDir: string, agentId: string,\n opts: { db?: Database.Database; since?: string; now?: number } = {},\n): WorkItem[] {\n const state = readState(wikiDir).agents[agentId]\n const now = opts.now ?? Date.now()\n const since = opts.since ?? state?.lastRunAt ?? new Date(now - 86_400_000).toISOString()\n const sinceDay = since.slice(0, 10)\n const done = new Set(state?.processed ?? [])\n const items: WorkItem[] = []\n\n for (const e of hub.getAgentEntries(agentId)) {\n if (e.date < sinceDay || done.has(e.id)) continue\n items.push({ id: e.id, at: e.date, kind: \"chat\", title: [e.source, e.sourceContext].filter(Boolean).join(\" · \"), text: e.content })\n }\n\n if (opts.db) {\n const sinceMs = Date.parse(since)\n for (const t of listTraces(opts.db, { agentId, since: Number.isFinite(sinceMs) ? sinceMs : undefined, limit: 500 })) {\n if (t.status === \"in-flight\" || done.has(t.taskId)) continue\n const steps = getTrace(opts.db, t.taskId)?.steps ?? []\n const tools = steps\n .filter((s) => s.name === \"tool_use\" || s.action)\n .slice(0, STEPS_PER_TRACE)\n .map((s) => `- ${s.action ?? s.name}${s.inputSummary ? ` ${clip(s.inputSummary, 160)}` : \"\"}${s.outputSummary ? ` → ${clip(s.outputSummary, 240)}` : \"\"}${s.error ? ` ✗ ${clip(s.error, 120)}` : \"\"}`)\n const text = [\n `Request: ${clip(t.originalMessage ?? t.messagePreview ?? \"\", 600)}`,\n tools.length ? `Tool calls:\\n${tools.join(\"\\n\")}` : \"\",\n t.finalResponse ? `Reply: ${clip(t.finalResponse, 800)}` : \"\",\n ].filter(Boolean).join(\"\\n\")\n items.push({ id: t.taskId, at: new Date(t.startedAt).toISOString(), kind: \"task\", title: `task ${t.taskId}${t.channel ? ` · ${t.channel}` : \"\"}`, text })\n }\n }\n return items.sort((a, b) => a.at.localeCompare(b.at) || a.id.localeCompare(b.id))\n}\n\nfunction saveCursor(wikiDir: string, agentId: string, read: WorkItem[], unread: WorkItem[], now: number): void {\n const state = readState(wikiDir)\n const prev = state.agents[agentId]\n // The cursor stays on the oldest item not read yet, so a run cut short\n // by a cap picks up there tomorrow; ids read at or after it are skipped.\n const lastRunAt = unread.length ? unread[0].at : new Date(now).toISOString()\n const processed = [...new Set([...(prev?.processed ?? []), ...read.map((w) => w.id)])].slice(-5000)\n state.agents[agentId] = { lastRunAt, processed }\n writeJson(resolve(contributionsDir(wikiDir), \"state.json\"), state)\n}\n\n// --- The run -----------------------------------------------------------------\n\n/** One model call: the reply text and what it cost. `maxCostUsd` is what\n * is left of the run's cap; the call must not spend more. */\nexport type ContributionCall = (prompt: string, maxCostUsd: number) => Promise<{ text: string; costUsd?: number }>\n\nexport interface ContributeOptions extends Partial<ContributionLimits> {\n model: string\n call: ContributionCall\n db?: Database.Database\n since?: string\n now?: number\n /** Compute the batch without saving it or moving the cursor. */\n dryRun?: boolean\n}\n\n/**\n * Review an agent's work since its last run and queue sourced patches\n * for the daily merge. Stops at the patch cap, the cost cap or the item\n * cap, whichever comes first.\n */\nexport async function runContribution(hub: WikiHub, wikiDir: string, agentId: string, opts: ContributeOptions): Promise<ContributionBatch> {\n const limits: ContributionLimits = {\n maxPatches: opts.maxPatches ?? DEFAULT_CONTRIBUTION_LIMITS.maxPatches,\n maxCostUsd: opts.maxCostUsd ?? DEFAULT_CONTRIBUTION_LIMITS.maxCostUsd,\n maxItems: opts.maxItems ?? DEFAULT_CONTRIBUTION_LIMITS.maxItems,\n }\n const now = opts.now ?? Date.now()\n const all = pendingWork(hub, wikiDir, agentId, { db: opts.db, since: opts.since, now })\n const pages = all.length ? readablePages(hub, agentId) : []\n const batch: ContributionBatch = {\n id: `${new Date(now).toISOString().replace(/[:.]/g, \"-\")}-${agentId.replace(/[^\\w-]+/g, \"_\")}`,\n agentId, runAt: new Date(now).toISOString(), model: opts.model,\n workIds: [], patches: [], costUsd: 0, calls: 0,\n }\n\n const read: WorkItem[] = []\n const seen = new Set<string>()\n while (read.length < all.length) {\n if (batch.patches.length >= limits.maxPatches) { batch.stoppedBy = \"max-patches\"; break }\n if (batch.costUsd >= limits.maxCostUsd) { batch.stoppedBy = \"max-cost\"; break }\n if (read.length >= limits.maxItems) { batch.stoppedBy = \"max-items\"; break }\n const chunk = all.slice(read.length, read.length + Math.min(ITEMS_PER_CALL, limits.maxItems - read.length))\n const prompt = buildContributionPrompt(agentId, chunk, relevantPages(pages, chunk), limits.maxPatches - batch.patches.length)\n const reply = await opts.call(prompt, Math.max(0.01, limits.maxCostUsd - batch.costUsd))\n batch.calls++\n batch.costUsd += reply.costUsd ?? 0\n read.push(...chunk)\n for (const p of parseContributionPatches(reply.text, agentId, { now })) {\n if (batch.patches.length >= limits.maxPatches) break\n if (seen.has(p.id)) continue\n seen.add(p.id)\n batch.patches.push(p)\n }\n }\n batch.workIds = read.map((w) => w.id)\n batch.costUsd = Math.round(batch.costUsd * 10_000) / 10_000\n\n if (!opts.dryRun) {\n if (batch.patches.length) writeJson(resolve(contributionsDir(wikiDir), \"pending\", `${batch.id}.json`), batch)\n saveCursor(wikiDir, agentId, read, all.slice(read.length), now)\n }\n return batch\n}\n\ninterface PageRef {\n title: string\n aliases: string[]\n type?: WikiArticleType\n lastUpdated?: string\n content: string\n}\n\n/** Every page the agent may read: its own, then the shared wiki's. */\nfunction readablePages(hub: WikiHub, agentId: string): PageRef[] {\n const out: PageRef[] = []\n const add = (store: WikiStore, skip?: (p: string) => boolean) => {\n for (const a of store.listArticles(agentId)) {\n if (a.path.includes(\"/_versions/\") || skip?.(a.path)) continue\n out.push({ title: a.meta.title, aliases: a.meta.aliases ?? [], type: a.meta.type, lastUpdated: a.meta.lastUpdated, content: a.content })\n }\n }\n add(hub.getAgentWiki(agentId))\n for (const s of hub.sharedScope(agentId)) add(s.store, s.skip)\n return out\n}\n\n/**\n * Pages the work most likely touches: half by title and alias, half by\n * body. Titles alone missed a stale page whose title was worded\n * differently from the work, and the model created a duplicate instead\n * of correcting it (#824 review).\n */\nfunction relevantPages(pages: PageRef[], items: WorkItem[]): PageRef[] {\n if (pages.length === 0) return []\n const text = items.map((w) => `${w.title} ${w.text}`).join(\"\\n\")\n const byTitle = scoreAll(text, buildIndex(pages.map((p) => [p.title, ...p.aliases].join(\" \"))))\n const byBody = scoreAll(text, buildIndex(pages.map((p) => `${p.title} ${p.aliases.join(\" \")} ${clip(p.content, 4000)}`)))\n const picked: number[] = []\n const half = Math.ceil(PAGES_PER_CALL / 2)\n for (const r of byTitle.slice(0, half)) picked.push(r.docIndex)\n for (const r of byBody) {\n if (picked.length >= PAGES_PER_CALL) break\n if (!picked.includes(r.docIndex)) picked.push(r.docIndex)\n }\n for (const r of byTitle.slice(half)) {\n if (picked.length >= PAGES_PER_CALL) break\n if (!picked.includes(r.docIndex)) picked.push(r.docIndex)\n }\n return picked.map((i) => pages[i])\n}\n\nexport function buildContributionPrompt(agentId: string, items: WorkItem[], pages: PageRef[], maxPatches: number): string {\n const work = items.map((w) => `### ${w.at.slice(0, 16)} · ${w.kind} · ${w.title}\\n${clip(w.text, ITEM_CHARS)}`).join(\"\\n\\n\")\n const wiki = pages.length\n ? pages.map((p) => `### ${p.title}${p.type ? ` [${p.type}]` : \"\"}${p.lastUpdated ? ` (updated ${p.lastUpdated})` : \"\"}\\n${clip(p.content, PAGE_CHARS)}`).join(\"\\n\\n\")\n : \"(no matching pages)\"\n return `You are agent \"${agentId}\". Below is your own work since your last wiki contribution (chat turns, and tasks with the tool calls you ran and what they returned) and the wiki pages it seems to touch. Propose small, sourced patches to the shared wiki from what you actually used or checked.\n\n## Your work\n\n${work}\n\n## Current wiki pages\n\n${wiki}\n\n## Patch kinds\n\n- \"add\": a fact you used or checked that the page lacks.\n- \"correct\": the page states something your work shows is wrong or out of date. Put the exact wrong text from the page in \"previous\", and the right value in \"value\".\n- \"create\": an entity (person, organization, project, invoice, place…) you dealt with that has no page. Give a one-sentence \"summary\"; add its facts as separate \"add\" patches on the same page title.\n\n## Rules\n\n- Only facts your work shows you checked (a tool result, a system you read) or were told by someone who knows. No guesses, no inferences, nothing from general knowledge.\n- Every patch names its \"source\": the system, command, URL or person (e.g. \"invoice list in the billing app\", \"owner said in chat\"). A patch without a source is dropped.\n- \"checkedAt\" is the date and time of the work that shows the check (ISO). A patch without it is dropped.\n- One fact per patch: an \"attribute\" (\"phone\", \"role\", \"billing status\", \"due date\") and its \"value\", copied exactly.\n- Never rewrite or summarise a page, and never propose removing a fact.\n- Skip facts a page already states with the same value.\n- Put each fact on the page about its subject. If a page above is about the same thing under another name, use that page (with \"correct\" when it is out of date) instead of creating a new one. Create a page only when none of the pages above is about the subject.\n- State the fact itself, not the story of how you found it.\n- Do not record facts about the wiki, AgentX, this contribution run or your own tools, unless that is your job.\n- Skip anything you could not verify. \"Not checked\" or \"unknown\" is not a fact.\n- At most ${maxPatches} patches. Return [] when there is nothing worth adding.\n\nReturn ONLY a JSON array, no prose, no code fences:\n\n[\n {\"kind\": \"add\", \"page\": \"Exact Page Title\", \"attribute\": \"phone\", \"value\": \"+1 555 0100\", \"source\": \"contacts app\", \"checkedAt\": \"2026-01-31T10:00:00Z\"},\n {\"kind\": \"correct\", \"page\": \"Exact Page Title\", \"attribute\": \"billing status\", \"previous\": \"overdue\", \"value\": \"paid\", \"source\": \"invoice list\", \"checkedAt\": \"2026-01-31T10:00:00Z\"},\n {\"kind\": \"create\", \"page\": \"New Entity Name\", \"pageType\": \"person\", \"summary\": \"One sentence.\", \"source\": \"chat with the owner\", \"checkedAt\": \"2026-01-31T10:00:00Z\"}\n]`\n}\n\n/** Valid patches from a model reply; anything malformed is dropped. */\nexport function parseContributionPatches(raw: string, agentId: string, opts: { now?: number } = {}): ContributionPatch[] {\n const match = raw.match(/\\[[\\s\\S]*\\]/)\n if (!match) return []\n let parsed: unknown\n try { parsed = JSON.parse(match[0]) } catch { return [] }\n if (!Array.isArray(parsed)) return []\n const now = opts.now ?? Date.now()\n const out: ContributionPatch[] = []\n for (const x of parsed) {\n if (!x || typeof x !== \"object\") continue\n const r = x as Record<string, unknown>\n const kind = r.kind\n if (kind !== \"add\" && kind !== \"correct\" && kind !== \"create\" && kind !== \"remove\") continue\n const page = clean(r.page, 120)\n // The fact line adds \"checked <date> by <agent>\" itself.\n const rawSource = clean(r.source, FIELD_CHARS)\n const source = rawSource.replace(/[\\s,;(–—-]*\\bchecked\\b[^;]*$/i, \"\").replace(/[\\s,;(]+$/, \"\") || rawSource\n const checked = typeof r.checkedAt === \"string\" ? Date.parse(r.checkedAt) : NaN\n if (!page || !source || !Number.isFinite(checked)) continue\n const attribute = clean(r.attribute, 60)\n const value = clean(r.value, FIELD_CHARS)\n const previous = clean(r.previous, FIELD_CHARS)\n const summary = clean(r.summary, FIELD_CHARS)\n if ((kind === \"add\" || kind === \"correct\") && (!attribute || !value)) continue\n if (kind === \"remove\" && !attribute && !previous) continue\n if (kind === \"create\" && !summary) continue\n const aliases = Array.isArray(r.aliases) ? r.aliases.map((a) => clean(a, 120)).filter(Boolean).slice(0, 10) : []\n // A check can't be dated after the run.\n const checkedAt = new Date(Math.min(checked, now)).toISOString()\n const body = { kind, page, attribute, value, previous, summary, source, checkedAt, agentId }\n out.push({\n id: createHash(\"sha1\").update(JSON.stringify(body)).digest(\"hex\").slice(0, 12),\n kind, page, source, checkedAt, agentId,\n ...(attribute ? { attribute } : {}),\n ...(value ? { value } : {}),\n ...(previous && kind !== \"add\" && kind !== \"create\" ? { previous } : {}),\n ...(summary && kind === \"create\" ? { summary } : {}),\n ...(kind === \"create\" && isWikiArticleType(r.pageType) ? { pageType: r.pageType } : {}),\n ...(kind === \"create\" && aliases.length ? { aliases } : {}),\n })\n }\n return out\n}\n\n/** One line, trimmed, capped; \"\" for anything not a string. */\nfunction clean(v: unknown, max: number): string {\n return typeof v === \"string\" ? v.replace(/\\s+/g, \" \").trim().slice(0, max) : \"\"\n}\n\nfunction clip(s: string, max: number): string {\n return s.length > max ? `${s.slice(0, max)}…` : s\n}\n\n// --- The daily merge -----------------------------------------------------------\n\nexport interface MergeReport {\n at: string\n batches: string[]\n agents: string[]\n patches: number\n /** Facts the ledger took as new, newer or re-checked. */\n applied: Array<{ page: string; attribute: string; value: string; by: string; status: string }>\n /** Pages that got a new or changed fact. */\n pagesUpdated: string[]\n pagesCreated: string[]\n /** Patches with an older check than the wiki's: a question was raised. */\n contradictions: Array<{ page: string; attribute: string; value: string; by: string; questionId?: string }>\n held: Array<{ id: string; page: string; attribute?: string; by: string; reason: string; lost?: string[] }>\n /** Several pages for one subject: listed for a person to merge. */\n duplicates: Array<{ title: string; pages: string[] }>\n dryRun?: boolean\n}\n\ninterface PageTarget {\n agentId: string\n store: WikiStore\n path: string\n article: WikiArticle\n}\n\n/** Title or alias, without case or punctuation. */\nexport function pageKey(title: string): string {\n return (title || \"\").toLowerCase().replace(/[^\\p{L}\\p{N}]+/gu, \" \").trim()\n}\n\n/** Every page by title and alias, across agents. Copied agents are read-only here. */\nfunction pageTargets(hub: WikiHub): Map<string, PageTarget[]> {\n const targets = new Map<string, PageTarget[]>()\n for (const id of hub.listAgents()) {\n if (hub.syncedFrom(id)) continue\n const store = hub.getAgentWiki(id)\n for (const article of store.listAllArticles()) {\n if (article.path.includes(\"/_versions/\")) continue\n const keys = new Set([article.meta.title, ...(article.meta.aliases ?? [])].map(pageKey).filter(Boolean))\n for (const k of keys) {\n const list = targets.get(k) ?? []\n list.push({ agentId: id, store, path: article.path, article })\n targets.set(k, list)\n }\n }\n }\n return targets\n}\n\n/**\n * Apply every pending batch. The newest checked fact wins (the fact\n * ledger keeps the older one in its history), new pages for one subject\n * become one page, and a change that would lose a fact is held.\n */\nexport function mergeContributions(hub: WikiHub, wikiDir: string, opts: { now?: number; dryRun?: boolean; log?: (m: string) => void } = {}): MergeReport {\n const now = opts.now ?? Date.now()\n const nowIso = new Date(now).toISOString()\n const today = nowIso.slice(0, 10)\n const batches = listPendingBatches(wikiDir)\n // Oldest check first, so the ledger takes each newer value over the\n // last and keeps the older one in its history.\n const patches = batches.flatMap((b) => b.patches).sort((a, b) => a.checkedAt.localeCompare(b.checkedAt))\n const report: MergeReport = {\n at: nowIso, batches: batches.map((b) => b.id), agents: [...new Set(batches.map((b) => b.agentId))].sort(),\n patches: patches.length, applied: [], pagesUpdated: [], pagesCreated: [], contradictions: [], held: [], duplicates: [],\n ...(opts.dryRun ? { dryRun: true } : {}),\n }\n const held: HeldPatch[] = []\n const hold = (patch: ContributionPatch, reason: string, lost?: string[]) => {\n const id = `h-${patch.id}`\n held.push({ id, patch, reason, heldAt: nowIso, status: \"held\", ...(lost?.length ? { lost } : {}) })\n report.held.push({ id, page: patch.page, attribute: patch.attribute, by: patch.agentId, reason, ...(lost?.length ? { lost } : {}) })\n }\n\n const targets = pageTargets(hub)\n for (const [, list] of targets) {\n const distinct = [...new Map(list.map((t) => [`${t.agentId}:${t.path}`, t])).values()]\n const title = distinct[0]?.article.meta.title\n if (distinct.length > 1 && title && !report.duplicates.some((d) => d.title === title)) {\n report.duplicates.push({ title, pages: distinct.map((t) => `${t.agentId}/${t.path}`) })\n }\n }\n\n // New pages: one per subject, however many agents proposed it. A page\n // that already exists (by title or alias) takes the facts instead.\n const newPages = new Map<string, NewPage>()\n for (const p of patches) {\n if (p.kind !== \"create\") continue\n const key = pageKey(p.page)\n if (targets.has(key)) continue\n const draft = newPages.get(key) ?? { title: p.page, owner: p.agentId, summaries: [], sources: [], aliases: [], at: p.checkedAt }\n draft.type ??= p.pageType\n if (p.summary && !draft.summaries.includes(p.summary)) draft.summaries.push(p.summary)\n if (!draft.sources.includes(p.source)) draft.sources.push(p.source)\n for (const a of p.aliases ?? []) if (!draft.aliases.includes(a)) draft.aliases.push(a)\n newPages.set(key, draft)\n }\n for (const p of patches) {\n const key = pageKey(p.page)\n if ((p.kind === \"add\" || p.kind === \"correct\") && !targets.has(key) && !newPages.has(key)) {\n // A fact about a subject with no page and no `create`: start one.\n newPages.set(key, { title: p.page, owner: p.agentId, summaries: [], sources: [p.source], aliases: [], at: p.checkedAt })\n }\n }\n\n // A new page whose title is a near match of an existing one is probably\n // that page under a longer or shorter name; creating it is how the\n // first trial duplicated a stale page instead of correcting it.\n const existing = [...targets.values()].map((list) => list[0])\n const duplicateOf = new Map<string, string>()\n for (const [key, draft] of newPages) {\n const match = possibleDuplicate(draft.title, draft.type, existing.map((t) => ({ title: t.article.meta.title, type: t.article.meta.type, ref: `${t.agentId}/${t.path}` })))\n if (match) duplicateOf.set(key, match)\n }\n for (const key of duplicateOf.keys()) newPages.delete(key)\n\n const ledger = new FactLedger(wikiDir)\n // Keyed by the page itself, not by the name a patch used: a title patch\n // and an alias patch to one page each started from the same stored\n // body, and the second write dropped the first one's lines.\n const edits = new Map<string, PageEdit[]>()\n const editTargets = new Map<string, PageTarget>()\n const editKey = (key: string) => {\n const t = targets.get(key)?.[0]\n if (!t) return `new:${key}`\n const k = `page:${t.agentId}:${t.path}`\n editTargets.set(k, t)\n return k\n }\n for (const p of patches) {\n const key = pageKey(p.page)\n const dup = duplicateOf.get(key)\n if (dup && p.kind !== \"remove\") { hold(p, `possible duplicate of ${dup}`); continue }\n if (p.kind === \"create\") continue\n if (p.kind === \"remove\") { hold(p, \"removes a fact\"); continue }\n const target = targets.get(key)?.[0]\n if (target && !target.store.canRead(target.article.meta, p.agentId)) {\n hold(p, \"the contributing agent cannot read this page\")\n continue\n }\n const subject = target?.article.meta.title ?? newPages.get(key)!.title\n let status = \"planned\"\n let value = p.value!\n if (!opts.dryRun) {\n const r = ledger.write({ subject, attribute: p.attribute!, value, source: p.source, verifiedBy: p.agentId, verifiedAt: p.checkedAt }, { now })\n status = r.status\n if (r.status === \"contradiction\") {\n report.contradictions.push({ page: subject, attribute: p.attribute!, value, by: p.agentId, questionId: r.questionId })\n continue\n }\n if (r.status === \"unchanged\") continue\n value = r.fact.value\n }\n report.applied.push({ page: subject, attribute: p.attribute!, value, by: p.agentId, status })\n const list = edits.get(editKey(key)) ?? []\n const previous = p.kind === \"correct\" ? p.previous : undefined\n list.push({ line: { attribute: p.attribute!, value, source: p.source, checkedAt: p.checkedAt, by: p.agentId, previous }, previous, patch: p })\n edits.set(editKey(key), list)\n }\n\n const touched = new Set<WikiStore>()\n for (const [key, list] of edits) {\n const target = editTargets.get(key)\n if (!target) continue\n const r = updatePage(target, list, { guard: true, today, dryRun: opts.dryRun })\n if (r.lost) for (const e of list) hold(e.patch, \"the change would lose facts the page has\", r.lost)\n else if (r.denied) for (const e of list) hold(e.patch, `write denied for ${target.agentId}/${target.path}`)\n else if (r.changed) {\n report.pagesUpdated.push(`${target.agentId}/${target.path}`)\n if (!opts.dryRun) touched.add(target.store)\n }\n }\n\n for (const [key, draft] of newPages) {\n const list = edits.get(`new:${key}`) ?? []\n if (!draft.summaries.length && !list.length) continue\n const store = hub.getAgentWiki(draft.owner)\n const path = newPagePath(store, draft.title, draft.type)\n report.pagesCreated.push(`${draft.owner}/${path}`)\n if (opts.dryRun) continue\n if (createPage(store, path, draft, list.map((e) => e.line), today)) touched.add(store)\n }\n\n if (!opts.dryRun) {\n for (const store of touched) {\n try { store.rebuildIndex() } catch (err) { opts.log?.(`index rebuild failed: ${(err as Error).message}`) }\n }\n const dir = contributionsDir(wikiDir)\n if (held.length) {\n const known = listHeld(wikiDir, { all: true })\n writeJson(heldFile(wikiDir), [...known, ...held.filter((h) => !known.some((k) => k.id === h.id))])\n }\n mkdirSync(resolve(dir, \"merged\"), { recursive: true })\n for (const b of batches) renameSync(resolve(dir, \"pending\", `${b.id}.json`), resolve(dir, \"merged\", `${b.id}.json`))\n writeJson(resolve(dir, \"reports\", `${nowIso.replace(/[:.]/g, \"-\")}.json`), report)\n }\n return report\n}\n\nfunction createPage(store: WikiStore, path: string, draft: NewPage, lines: FactLine[], today: string): boolean {\n const intro = draft.summaries.length ? draft.summaries.join(\" \") : `${draft.title}.`\n const { body } = applyFactLines(`${intro}\\n\\n_Sources: ${draft.sources.join(\"; \")}._`, lines)\n return store.writeArticle(path, {\n title: draft.title,\n ...(draft.type ? { type: draft.type } : {}),\n ...(draft.aliases.length ? { aliases: draft.aliases } : {}),\n tags: [],\n owner: draft.owner,\n access: \"public\",\n created: today,\n lastUpdated: today,\n sources: [contributionStamp(draft.owner, draft.at), ...lines.map((l) => contributionStamp(l.by, l.checkedAt))]\n .filter((s, i, a) => a.indexOf(s) === i),\n }, body, draft.owner)\n}\n\nconst TITLE_STOPWORDS = new Set([\"the\", \"and\", \"for\", \"with\", \"von\", \"des\", \"les\", \"der\", \"die\", \"das\", \"une\", \"pour\", \"page\", \"of\", \"de\", \"la\", \"le\", \"du\", \"et\"])\n\nfunction titleTokens(title: string): Set<string> {\n return new Set((title.toLowerCase().match(/[\\p{L}\\p{N}]+/gu) ?? []).filter((t) => (t.length > 2 || /\\d/.test(t)) && !TITLE_STOPWORDS.has(t)))\n}\n\n/**\n * The existing page a new title most likely means, or undefined. A match\n * shares at least two significant words and most of the shorter title's\n * words (\"Tax Payment Plan\" and \"Tax Payment Plan Engagement 4471\"). A\n * person page never matches a page of another type, and titles carrying\n * different numbers never match.\n */\nexport function possibleDuplicate(\n title: string, type: WikiArticleType | undefined,\n pages: Array<{ title: string; type?: WikiArticleType; ref: string }>,\n): string | undefined {\n const mine = titleTokens(title)\n if (mine.size < 2) return undefined\n let best: { ref: string; title: string; score: number } | undefined\n for (const p of pages) {\n if (type && p.type && (type === \"person\") !== (p.type === \"person\")) continue\n const theirs = titleTokens(p.title)\n if (theirs.size < 2) continue\n // Two numbered things (invoices, issues) with different numbers are\n // different things, however alike the rest of the title.\n const nums = (set: Set<string>) => [...set].filter((t) => /\\d/.test(t))\n const [a, b] = [nums(mine), nums(theirs)]\n if (a.length && b.length && !a.some((n) => b.includes(n))) continue\n let shared = 0\n for (const t of mine) if (theirs.has(t)) shared++\n const score = shared / Math.min(mine.size, theirs.size)\n if (shared >= 2 && score >= 0.75 && (!best || score > best.score)) best = { ref: p.ref, title: p.title, score }\n }\n return best ? `\"${best.title}\" (${best.ref})` : undefined\n}\n\ninterface NewPage {\n title: string\n type?: WikiArticleType\n owner: string\n summaries: string[]\n sources: string[]\n aliases: string[]\n /** Earliest check behind it. */\n at: string\n}\n\ninterface PageEdit {\n line: FactLine\n /** For a correction the ledger accepted: the exact wrong text to replace in place. */\n previous?: string\n patch: ContributionPatch\n}\n\n/**\n * Write a page's fact lines and in-place corrections. With `guard`, an\n * edit that would lose a structured fact is not written and the lost\n * facts are returned.\n */\nfunction updatePage(\n target: PageTarget, list: PageEdit[],\n opts: { guard: boolean; today: string; dryRun?: boolean; remove?: { attribute?: string; text?: string } },\n): { changed: boolean; lost?: string[]; denied?: boolean } {\n const before = target.article.content\n let { body, superseded } = applyFactLines(before, list.map((e) => e.line))\n for (const e of list) {\n if (!e.previous || e.previous === e.line.value) continue\n const fixed = replaceOnce(body, e.previous, e.line.value)\n if (fixed !== body) { body = fixed; superseded.push(e.previous) }\n }\n if (opts.remove) body = removeFact(body, opts.remove)\n if (body === before) return { changed: false }\n if (opts.guard) {\n const lost = lostStructuredFacts(before, body, superseded)\n if (lost.length) return { changed: false, lost }\n }\n if (opts.dryRun) return { changed: true }\n const meta = target.article.meta\n const stamps = list.map((e) => contributionStamp(e.line.by, e.line.checkedAt))\n const ok = target.store.writeArticle(target.path, {\n ...meta,\n lastUpdated: opts.today,\n sources: [...meta.sources, ...stamps].filter((s, i, a) => a.indexOf(s) === i),\n }, body, meta.owner)\n return ok ? { changed: true } : { changed: false, denied: true }\n}\n\n/** Replace `old` with `next` when it occurs exactly once, as whole words,\n * outside the \"Checked facts\" section; anything else is ambiguous and\n * left alone. Whole words, so \"paid\" is not rewritten inside \"unpaid\". */\nexport function replaceOnce(body: string, old: string, next: string): string {\n if (!old) return body\n const at = body.indexOf(FACTS_HEADING)\n const prose = at === -1 ? body : body.slice(0, at)\n const escaped = old.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\n const hits = [...prose.matchAll(new RegExp(`(?<![\\\\p{L}\\\\p{N}])${escaped}(?![\\\\p{L}\\\\p{N}])`, \"gu\"))]\n if (hits.length !== 1) return body\n const first = hits[0].index!\n return body.slice(0, first) + next + body.slice(first + old.length)\n}\n\nfunction removeFact(body: string, remove: { attribute?: string; text?: string }): string {\n let out = body\n if (remove.attribute) {\n const attr = remove.attribute.toLowerCase()\n out = out.split(\"\\n\").filter((l) => l.match(LINE_RE)?.[1].toLowerCase() !== attr).join(\"\\n\")\n }\n if (remove.text) out = replaceOnce(out, remove.text, \"\")\n return out\n}\n\n// --- Held patches: a person decides ----------------------------------------\n\nexport type HeldDecision = { ok: true; held: HeldPatch; page?: string } | { ok: false; error: string }\n\n/**\n * Apply a held patch as it is, without the fact-loss guard: a person\n * looked at it. A removal deletes the attribute's fact line and the\n * exact text it names; the page's previous body stays in `_versions/`.\n */\nexport function approveHeld(hub: WikiHub, wikiDir: string, id: string, opts: { by?: string; now?: number } = {}): HeldDecision {\n const all = listHeld(wikiDir, { all: true })\n const h = all.find((x) => x.id === id)\n if (!h) return { ok: false, error: `no held patch \"${id}\"` }\n if (h.status !== \"held\") return { ok: false, error: `\"${id}\" is already ${h.status}` }\n const p = h.patch\n const now = opts.now ?? Date.now()\n const today = new Date(now).toISOString().slice(0, 10)\n const target = pageTargets(hub).get(pageKey(p.page))?.[0]\n if (!target) {\n // A held `create` (a possible duplicate), or a fact for the page it\n // would have made: a person said it is a new subject after all.\n if (p.kind === \"remove\") return { ok: false, error: `no page \"${p.page}\" (it may have been renamed)` }\n const lines: FactLine[] = []\n if (p.attribute && p.value) {\n const w = new FactLedger(wikiDir).write({ subject: p.page, attribute: p.attribute, value: p.value, source: p.source, verifiedBy: p.agentId, verifiedAt: p.checkedAt }, { now })\n if (w.status === \"contradiction\") return { ok: false, error: `the wiki has a newer check of ${p.attribute}; answer question ${w.questionId ?? \"(see wiki questions)\"} instead` }\n lines.push({ attribute: p.attribute, value: w.fact.value, source: p.source, checkedAt: p.checkedAt, by: p.agentId })\n }\n const store = hub.getAgentWiki(p.agentId)\n const path = newPagePath(store, p.page, p.pageType)\n const draft: NewPage = { title: p.page, type: p.pageType, owner: p.agentId, summaries: p.summary ? [p.summary] : [], sources: [p.source], aliases: p.aliases ?? [], at: p.checkedAt }\n if (!createPage(store, path, draft, lines, today)) return { ok: false, error: `write denied for ${p.agentId}/${path}` }\n try { store.rebuildIndex() } catch { /* the page is written; the next rebuild indexes it */ }\n return decide(wikiDir, all, h, \"approved\", opts.by, now, `${p.agentId}/${path}`)\n }\n\n let r: { changed: boolean; denied?: boolean }\n if (p.kind === \"remove\") {\n r = updatePage(target, [], { guard: false, today, remove: { attribute: p.attribute, text: p.previous } })\n } else {\n if (!p.attribute || !p.value) return { ok: false, error: `\"${id}\" carries no fact to apply` }\n const w = new FactLedger(wikiDir).write({ subject: target.article.meta.title, attribute: p.attribute, value: p.value, source: p.source, verifiedBy: p.agentId, verifiedAt: p.checkedAt }, { now })\n if (w.status === \"contradiction\") return { ok: false, error: `the wiki has a newer check of ${p.attribute}; answer question ${w.questionId ?? \"(see wiki questions)\"} instead` }\n const previous = p.kind === \"correct\" ? p.previous : undefined\n r = updatePage(target, [{ line: { attribute: p.attribute, value: w.fact.value, source: p.source, checkedAt: p.checkedAt, by: p.agentId, previous }, previous, patch: p }], { guard: false, today })\n }\n if (r.denied) return { ok: false, error: `write denied for ${target.agentId}/${target.path}` }\n if (r.changed) {\n try { target.store.rebuildIndex() } catch { /* the page is written; the next rebuild indexes it */ }\n }\n return decide(wikiDir, all, h, \"approved\", opts.by, now, `${target.agentId}/${target.path}`)\n}\n\nexport function rejectHeld(wikiDir: string, id: string, opts: { by?: string; now?: number } = {}): HeldDecision {\n const all = listHeld(wikiDir, { all: true })\n const h = all.find((x) => x.id === id)\n if (!h) return { ok: false, error: `no held patch \"${id}\"` }\n if (h.status !== \"held\") return { ok: false, error: `\"${id}\" is already ${h.status}` }\n return decide(wikiDir, all, h, \"rejected\", opts.by, opts.now ?? Date.now())\n}\n\nfunction decide(wikiDir: string, all: HeldPatch[], h: HeldPatch, status: \"approved\" | \"rejected\", by: string | undefined, now: number, page?: string): HeldDecision {\n const decided: HeldPatch = { ...h, status, decidedBy: by ?? \"operator\", decidedAt: new Date(now).toISOString() }\n writeJson(heldFile(wikiDir), all.map((x) => (x.id === h.id ? decided : x)))\n return { ok: true, held: decided, ...(page ? { page } : {}) }\n}\n\n// --- Page text -----------------------------------------------------------------\n\nexport interface FactLine {\n attribute: string\n value: string\n source: string\n checkedAt: string\n by: string\n previous?: string\n}\n\nconst LINE_RE = /^- \\*\\*(.+?):\\*\\* /\n\n/**\n * Add or update one line per attribute in the page's \"Checked facts\"\n * section. Nothing outside that section changes. A changed value keeps\n * the old one on its line as \"previously\", so a correction never drops a\n * fact from the page.\n *\n * `superseded` holds the replaced lines: their older parts live on in the\n * ledger's history and the page's versions, so the guard lets them go.\n */\nexport function applyFactLines(body: string, lines: FactLine[]): { body: string; superseded: string[] } {\n if (lines.length === 0) return { body, superseded: [] }\n const all = body.replace(/\\s+$/, \"\").split(\"\\n\")\n const start = all.findIndex((l) => l.trim() === FACTS_HEADING)\n let head = all\n let section: string[] = []\n let tail: string[] = []\n if (start !== -1) {\n head = all.slice(0, start)\n const rest = all.slice(start + 1)\n const end = rest.findIndex((l) => /^#{1,2} /.test(l))\n section = (end === -1 ? rest : rest.slice(0, end)).filter((l) => l.trim())\n tail = end === -1 ? [] : rest.slice(end)\n }\n\n const superseded: string[] = []\n for (const l of lines) {\n const at = section.findIndex((s) => s.match(LINE_RE)?.[1].toLowerCase() === l.attribute.toLowerCase())\n const old = at === -1 ? undefined : parseFactLine(section[at])\n if (at !== -1) superseded.push(section[at])\n // A re-check of the same value refreshes the line and keeps its history.\n const previous = old && old.value === l.value ? old.previous : old ? `${old.value}, checked ${old.checkedAt}` : l.previous\n // An existing line keeps its spelling of the attribute.\n const attribute = section[at]?.match(LINE_RE)?.[1] ?? l.attribute\n const line = renderFactLine({ ...l, attribute, previous })\n if (at === -1) section.push(line)\n else section[at] = line\n }\n\n const out = [...(head.some((l) => l.trim()) ? [...head, \"\"] : []), FACTS_HEADING, \"\", ...section]\n if (tail.length) out.push(\"\", ...tail)\n return { body: out.join(\"\\n\").replace(/\\n{3,}/g, \"\\n\\n\").trim(), superseded }\n}\n\nfunction renderFactLine(l: FactLine): string {\n const prev = l.previous ? ` (previously: ${l.previous})` : \"\"\n return `- **${l.attribute}:** ${l.value} — ${l.source}; checked ${l.checkedAt.slice(0, 10)} by ${l.by}${prev}`\n}\n\nfunction parseFactLine(line: string): { value: string; checkedAt: string; previous?: string } | undefined {\n const m = line.match(/^- \\*\\*.+?:\\*\\* (.*?) — .*?; checked (\\S+) by \\S+(?: \\(previously: (.*)\\))?$/)\n return m ? { value: m[1], checkedAt: m[2], ...(m[3] ? { previous: m[3] } : {}) } : undefined\n}\n\nfunction contributionStamp(agentId: string, at: string): string {\n return `contribution:${agentId}@${at.slice(0, 10)}`\n}\n\nconst TYPE_FOLDER: Record<WikiArticleType, string> = {\n person: \"people\", project: \"projects\", place: \"places\", concept: \"concepts\",\n event: \"events\", decision: \"decisions\", pattern: \"patterns\",\n}\n\nfunction newPagePath(store: WikiStore, title: string, type?: WikiArticleType): string {\n const slug = title.toLowerCase().replace(/[^\\p{L}\\p{N}]+/gu, \"-\").replace(/^-+|-+$/g, \"\").slice(0, 60) || \"page\"\n const folder = type ? TYPE_FOLDER[type] : \"contributions\"\n let path = `${folder}/${slug}.md`\n for (let n = 2; store.readArticle(path); n++) path = `${folder}/${slug}-${n}.md`\n return path\n}\n"],"mappings":"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","names":["createHash","existsSync","mkdirSync","readdirSync","readFileSync","renameSync","writeFileSync","resolve","DEFAULT_CONTRIBUTION_LIMITS","ITEMS_PER_CALL","ITEM_CHARS","PAGE_CHARS","PAGES_PER_CALL","FIELD_CHARS","STEPS_PER_TRACE","FACTS_HEADING","contributionsDir","wikiDir","resolve","readJson","file","fallback","existsSync","readFileSync","err","writeJson","data","mkdirSync","tmp","writeFileSync","renameSync","readState","listPendingBatches","dir","readdirSync","f","b","heldFile","listHeld","opts","list","h","latestReport","last","pendingWork","hub","agentId","state","now","since","sinceDay","done","items","e","sinceMs","t","listTraces","tools","getTrace","s","clip","text","a","saveCursor","read","unread","prev","lastRunAt","processed","w","runContribution","limits","all","pages","readablePages","batch","seen","chunk","prompt","buildContributionPrompt","relevantPages","reply","p","parseContributionPatches","out","add","store","skip","byTitle","scoreAll","buildIndex","byBody","picked","half","r","i","maxPatches","work","wiki","raw","match","parsed","x","kind","page","clean","rawSource","source","checked","attribute","value","previous","summary","aliases","checkedAt","body","createHash","isWikiArticleType","v","max","pageKey","title","pageTargets","targets","id","article","keys","k","mergeContributions","nowIso","today","batches","patches","report","held","hold","patch","reason","lost","distinct","d","newPages","key","draft","existing","duplicateOf","possibleDuplicate","ledger","FactLedger","edits","editTargets","editKey","dup","target","subject","status","touched","updatePage","path","newPagePath","createPage","known","lines","intro","applyFactLines","contributionStamp","l","TITLE_STOPWORDS","titleTokens","type","mine","best","theirs","nums","set","n","shared","score","before","superseded","fixed","replaceOnce","removeFact","lostStructuredFacts","meta","stamps","old","next","at","prose","escaped","hits","first","remove","attr","LINE_RE","approveHeld","decide","rejectHeld","by","decided","start","head","section","tail","rest","end","parseFactLine","line","renderFactLine","m","TYPE_FOLDER","slug","folder"]}
@@ -0,0 +1,2 @@
1
+ import{b as a,c as b,d as c,e as d,f as e}from"./chunk-QFZU5CEO.js";import"./chunk-S2GAEH2F.js";import"./chunk-JXF54PT7.js";import"./chunk-MRYA4J5F.js";import"./chunk-BRK6M6LA.js";import"./chunk-UIBUZ2N3.js";import"./chunk-2QNT5JDS.js";import"./chunk-QIJLFPWE.js";export{e as daemonVoiceCheck,b as doctor,a as runDoctorChecks,c as runNotificationChecks,d as runReminderChecks};
2
+ //# sourceMappingURL=doctor-VLRC4HW2.js.map
@@ -1,6 +1,6 @@
1
- import{b as h}from"./chunk-CY6ABHF2.js";import"./chunk-RKPAVWXF.js";import{b as m}from"./chunk-LLNPKE7H.js";import"./chunk-SHEUCITK.js";import"./chunk-QQYXYJOG.js";import"./chunk-5DFUUYEA.js";import"./chunk-WMTGAVPW.js";import"./chunk-FCPTN6NF.js";import"./chunk-7I7IEX4S.js";import"./chunk-46JKX6CT.js";import"./chunk-UIBUZ2N3.js";import"./chunk-BRK6M6LA.js";import"./chunk-2QNT5JDS.js";import"./chunk-QIJLFPWE.js";var p=t=>typeof t=="string"?t.trim():"";function k(t){return[`Run ${t.runId} "${t.title}" [${t.status}] on step ${t.step}: waiting on ${t.waitingOn}.`,t.tags?.length?`Tags: ${t.tags.join(", ")}`:"",...(t.steps??[]).slice(-8).map(r=>`- ${String(r.at).slice(0,16).replace("T"," ")} ${r.step} ${r.status}${r.note?`: ${r.note}`:""}`)].filter(Boolean).join(`
1
+ import{b as h}from"./chunk-TG6CT54D.js";import"./chunk-RKPAVWXF.js";import{b as m}from"./chunk-LLNPKE7H.js";import"./chunk-SHEUCITK.js";import"./chunk-ZLC4TSXF.js";import"./chunk-2SV4RKRW.js";import"./chunk-HKW56YZK.js";import"./chunk-52SIHG45.js";import"./chunk-FCPTN6NF.js";import"./chunk-7I7IEX4S.js";import"./chunk-MRYA4J5F.js";import"./chunk-BRK6M6LA.js";import"./chunk-UIBUZ2N3.js";import"./chunk-2QNT5JDS.js";import"./chunk-QIJLFPWE.js";var p=t=>typeof t=="string"?t.trim():"";function k(t){return[`Run ${t.runId} "${t.title}" [${t.status}] on step ${t.step}: waiting on ${t.waitingOn}.`,t.tags?.length?`Tags: ${t.tags.join(", ")}`:"",...(t.steps??[]).slice(-8).map(r=>`- ${String(r.at).slice(0,16).replace("T"," ")} ${r.step} ${r.status}${r.note?`: ${r.note}`:""}`)].filter(Boolean).join(`
2
2
  `)}async function T(t,u){let r=u.fetch??fetch,$=u.daemonUrl.replace(/\/$/,""),a=(p(t.action)||"list").toLowerCase(),f=u.env??process.env,w=async i=>{let l=await r(`${$}${i}`,{signal:AbortSignal.timeout(1e4)}),n=await l.json().catch(()=>({}));return{ok:l.ok,status:l.status,data:n}};try{if(a==="list"){let e=await w("/follow-up");if(!e.ok)return`Error: ${e.data?.error||`HTTP ${e.status}`}`;let o=e.data.groups??[];return o.length?o.map(c=>[`${c.tag}:`,...c.rows.map(s=>`- ${s.runId} "${s.title}" on ${s.step}: waiting on ${s.waitingOn} (since ${String(s.since).slice(0,16).replace("T"," ")} UTC)`)].join(`
3
3
  `)).join(`
4
4
  `):"No follow-up workflows are running."}if(a==="match"){let e=p(t.request)||p(t.title);if(!e)return"Error: match needs `request`: the owner's request in their words.";let o=h(t,f),c=await w(`/follow-up/match?q=${encodeURIComponent(e)}${o?`&agentId=${encodeURIComponent(o.agentId)}`:""}`);if(!c.ok)return`Error: ${c.data?.error||`HTTP ${c.status}`}`;let s=c.data.matches??[];return s.length?["Saved workflows, best fit first (confidence 0-1):",...s.map(d=>`- ${d.workflowId} "${d.title}" (${d.confidence}${d.autoStart?", starts without asking":""}): ${d.steps.map(I=>I.id).join(" \u2192 ")}`),'Start one with {action:"start", workflowId:"<id>", title:"\u2026", tags:["client:<name>"]}. Run its steps through the workflow, not by hand.'].join(`
5
5
  `):"No saved workflow fits. If the request has several steps, build one: start with title and steps."}if(a==="status"){let e=p(t.runId);if(!e)return"Error: status needs runId.";let o=await w(`/follow-up/${encodeURIComponent(e)}`);return o.ok?k(o.data.run):`Error: ${o.data?.error||`HTTP ${o.status}`}`}let i=h(t,f);if(!i)return"Error: couldn't tell which agent you are. Pass callerAgentId.";let l=await r(`${$}/follow-up`,{method:"POST",headers:{"Content-Type":"application/json",...m(f)},body:JSON.stringify({action:a,agentId:i.agentId,workflowId:t.workflowId,title:t.title,description:t.description,tags:t.tags,inputs:t.inputs,steps:t.steps,edges:t.edges,approval:t.approval,autoStart:t.autoStart,requestId:t.requestId,runId:t.runId,step:t.step,evidence:t.evidence,note:t.note,reason:t.reason,fromRun:t.fromRun}),signal:AbortSignal.timeout(2e4)}),n=await l.json().catch(()=>({}));if(!l.ok)return`Error: ${n?.error||`HTTP ${l.status}`}`;if(a==="start"){let e=n.run;return[`Started run ${e.runId} "${e.title}"${n.built?" (built from the steps you gave; propose it with fromRun to keep it)":""}.`,n.awaitingApproval?"It waits for the owner's approval before the first step.":`It is on step ${e.step}: ${e.waitingOn}.`,"AgentX follows it from here: it starts each step, reminds whoever is slow, and tells the owner when it ends. Do not run its steps by hand.",...n.warning?[`Note: ${n.warning}`]:[]].join(" ")}return a==="done"?`Step recorded as done. ${n.run?k(n.run):""}`.trim():a==="blocked"?"The step is marked blocked and the owner is told. Nothing more happens on it until it is sorted.":`Saved ${n.workflowId} switched off, and asked the owner (card ${n.cardId}) whether to keep it as a reusable workflow.`}catch(i){return`Error: couldn't reach the daemon (${i?.message??i}).`}}export{T as runWorkflowTool};
6
- //# sourceMappingURL=follow-up-tool-AIOLNUF7.js.map
6
+ //# sourceMappingURL=follow-up-tool-235LDEMP.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/workflows/follow-up-tool.ts"],"sourcesContent":["import { resolveScheduleCaller } from \"@/crons/schedule-tool\"\nimport { callerHeaders } from \"@/calls/service\"\n\n// --- Agent-facing `agentx_workflow` tool (#788) ---\n//\n// A request with several steps is run as a workflow, not by hand:\n// match saved workflows that fit the request in front of you\n// start start one (workflowId), or build one from the owner's words\n// (title + steps) and run it; tags say what it concerns\n// status one run: the step it is on and what it waits on\n// list every follow-up still going, grouped by tag\n// done the step you own is finished (evidence)\n// blocked your step cannot go on without the owner (reason)\n// propose ask the owner to keep a workflow as a reusable template\n// It talks to the daemon's /follow-up endpoints.\n\nexport interface WorkflowToolDeps {\n daemonUrl: string\n fetch?: typeof fetch\n env?: NodeJS.ProcessEnv\n}\n\nconst str = (v: unknown) => (typeof v === \"string\" ? v.trim() : \"\")\n\nfunction describe(run: any): string {\n const lines = [\n `Run ${run.runId} \"${run.title}\" [${run.status}] on step ${run.step}: waiting on ${run.waitingOn}.`,\n run.tags?.length ? `Tags: ${run.tags.join(\", \")}` : \"\",\n ...(run.steps ?? []).slice(-8).map((s: any) => `- ${String(s.at).slice(0, 16).replace(\"T\", \" \")} ${s.step} ${s.status}${s.note ? `: ${s.note}` : \"\"}`),\n ]\n return lines.filter(Boolean).join(\"\\n\")\n}\n\n/** Returns the text the agent sees. Every refusal is text, never a throw. */\nexport async function runWorkflowTool(args: Record<string, unknown>, deps: WorkflowToolDeps): Promise<string> {\n const doFetch = deps.fetch ?? fetch\n const base = deps.daemonUrl.replace(/\\/$/, \"\")\n const action = (str(args.action) || \"list\").toLowerCase()\n const env = deps.env ?? process.env\n const read = async (path: string) => {\n const res = await doFetch(`${base}${path}`, { signal: AbortSignal.timeout(10_000) })\n const data = await res.json().catch(() => ({})) as any\n return { ok: res.ok, status: res.status, data }\n }\n\n try {\n if (action === \"list\") {\n const r = await read(\"/follow-up\")\n if (!r.ok) return `Error: ${r.data?.error || `HTTP ${r.status}`}`\n const groups = r.data.groups ?? []\n if (!groups.length) return \"No follow-up workflows are running.\"\n return groups.map((g: any) => [`${g.tag}:`, ...g.rows.map((row: any) => `- ${row.runId} \"${row.title}\" on ${row.step}: waiting on ${row.waitingOn} (since ${String(row.since).slice(0, 16).replace(\"T\", \" \")} UTC)`)].join(\"\\n\")).join(\"\\n\")\n }\n if (action === \"match\") {\n const q = str(args.request) || str(args.title)\n if (!q) return \"Error: match needs `request`: the owner's request in their words.\"\n const caller = resolveScheduleCaller(args, env)\n const r = await read(`/follow-up/match?q=${encodeURIComponent(q)}${caller ? `&agentId=${encodeURIComponent(caller.agentId)}` : \"\"}`)\n if (!r.ok) return `Error: ${r.data?.error || `HTTP ${r.status}`}`\n const matches = r.data.matches ?? []\n if (!matches.length) return \"No saved workflow fits. If the request has several steps, build one: start with title and steps.\"\n return [\n \"Saved workflows, best fit first (confidence 0-1):\",\n ...matches.map((x: any) => `- ${x.workflowId} \"${x.title}\" (${x.confidence}${x.autoStart ? \", starts without asking\" : \"\"}): ${x.steps.map((s: any) => s.id).join(\" → \")}`),\n `Start one with {action:\"start\", workflowId:\"<id>\", title:\"…\", tags:[\"client:<name>\"]}. Run its steps through the workflow, not by hand.`,\n ].join(\"\\n\")\n }\n if (action === \"status\") {\n const runId = str(args.runId)\n if (!runId) return \"Error: status needs runId.\"\n const r = await read(`/follow-up/${encodeURIComponent(runId)}`)\n if (!r.ok) return `Error: ${r.data?.error || `HTTP ${r.status}`}`\n return describe(r.data.run)\n }\n\n const caller = resolveScheduleCaller(args, env)\n if (!caller) return \"Error: couldn't tell which agent you are. Pass callerAgentId.\"\n const res = await doFetch(`${base}/follow-up`, {\n method: \"POST\",\n // The headers name this run: the daemon refuses a write that does\n // not come from a running turn of the agent.\n headers: { \"Content-Type\": \"application/json\", ...callerHeaders(env) },\n body: JSON.stringify({\n action, agentId: caller.agentId,\n workflowId: args.workflowId, title: args.title, description: args.description, tags: args.tags, inputs: args.inputs,\n steps: args.steps, edges: args.edges, approval: args.approval, autoStart: args.autoStart, requestId: args.requestId,\n runId: args.runId, step: args.step, evidence: args.evidence, note: args.note, reason: args.reason, fromRun: args.fromRun,\n }),\n signal: AbortSignal.timeout(20_000),\n })\n const data = await res.json().catch(() => ({})) as any\n if (!res.ok) return `Error: ${data?.error || `HTTP ${res.status}`}`\n if (action === \"start\") {\n const run = data.run\n return [\n `Started run ${run.runId} \"${run.title}\"${data.built ? \" (built from the steps you gave; propose it with fromRun to keep it)\" : \"\"}.`,\n data.awaitingApproval ? \"It waits for the owner's approval before the first step.\" : `It is on step ${run.step}: ${run.waitingOn}.`,\n \"AgentX follows it from here: it starts each step, reminds whoever is slow, and tells the owner when it ends. Do not run its steps by hand.\",\n ...(data.warning ? [`Note: ${data.warning}`] : []),\n ].join(\" \")\n }\n if (action === \"done\") return `Step recorded as done. ${data.run ? describe(data.run) : \"\"}`.trim()\n if (action === \"blocked\") return \"The step is marked blocked and the owner is told. Nothing more happens on it until it is sorted.\"\n return `Saved ${data.workflowId} switched off, and asked the owner (card ${data.cardId}) whether to keep it as a reusable workflow.`\n } catch (e: any) {\n return `Error: couldn't reach the daemon (${e?.message ?? e}).`\n }\n}\n"],"mappings":"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","names":["str","v","describe","run","s","runWorkflowTool","args","deps","doFetch","base","action","env","read","path","res","data","r","groups","g","row","q","caller","resolveScheduleCaller","matches","x","runId","callerHeaders","e"]}
1
+ {"version":3,"sources":["../src/workflows/follow-up-tool.ts"],"sourcesContent":["import { resolveScheduleCaller } from \"@/crons/schedule-tool\"\nimport { callerHeaders } from \"@/calls/service\"\n\n// --- Agent-facing `agentx_workflow` tool (#788) ---\n//\n// A request with several steps is run as a workflow, not by hand:\n// match saved workflows that fit the request in front of you\n// start start one (workflowId), or build one from the owner's words\n// (title + steps) and run it; tags say what it concerns\n// status one run: the step it is on and what it waits on\n// list every follow-up still going, grouped by tag\n// done the step you own is finished (evidence)\n// blocked your step cannot go on without the owner (reason)\n// propose ask the owner to keep a workflow as a reusable template\n// It talks to the daemon's /follow-up endpoints.\n\nexport interface WorkflowToolDeps {\n daemonUrl: string\n fetch?: typeof fetch\n env?: NodeJS.ProcessEnv\n}\n\nconst str = (v: unknown) => (typeof v === \"string\" ? v.trim() : \"\")\n\nfunction describe(run: any): string {\n const lines = [\n `Run ${run.runId} \"${run.title}\" [${run.status}] on step ${run.step}: waiting on ${run.waitingOn}.`,\n run.tags?.length ? `Tags: ${run.tags.join(\", \")}` : \"\",\n ...(run.steps ?? []).slice(-8).map((s: any) => `- ${String(s.at).slice(0, 16).replace(\"T\", \" \")} ${s.step} ${s.status}${s.note ? `: ${s.note}` : \"\"}`),\n ]\n return lines.filter(Boolean).join(\"\\n\")\n}\n\n/** Returns the text the agent sees. Every refusal is text, never a throw. */\nexport async function runWorkflowTool(args: Record<string, unknown>, deps: WorkflowToolDeps): Promise<string> {\n const doFetch = deps.fetch ?? fetch\n const base = deps.daemonUrl.replace(/\\/$/, \"\")\n const action = (str(args.action) || \"list\").toLowerCase()\n const env = deps.env ?? process.env\n const read = async (path: string) => {\n const res = await doFetch(`${base}${path}`, { signal: AbortSignal.timeout(10_000) })\n const data = await res.json().catch(() => ({})) as any\n return { ok: res.ok, status: res.status, data }\n }\n\n try {\n if (action === \"list\") {\n const r = await read(\"/follow-up\")\n if (!r.ok) return `Error: ${r.data?.error || `HTTP ${r.status}`}`\n const groups = r.data.groups ?? []\n if (!groups.length) return \"No follow-up workflows are running.\"\n return groups.map((g: any) => [`${g.tag}:`, ...g.rows.map((row: any) => `- ${row.runId} \"${row.title}\" on ${row.step}: waiting on ${row.waitingOn} (since ${String(row.since).slice(0, 16).replace(\"T\", \" \")} UTC)`)].join(\"\\n\")).join(\"\\n\")\n }\n if (action === \"match\") {\n const q = str(args.request) || str(args.title)\n if (!q) return \"Error: match needs `request`: the owner's request in their words.\"\n const caller = resolveScheduleCaller(args, env)\n const r = await read(`/follow-up/match?q=${encodeURIComponent(q)}${caller ? `&agentId=${encodeURIComponent(caller.agentId)}` : \"\"}`)\n if (!r.ok) return `Error: ${r.data?.error || `HTTP ${r.status}`}`\n const matches = r.data.matches ?? []\n if (!matches.length) return \"No saved workflow fits. If the request has several steps, build one: start with title and steps.\"\n return [\n \"Saved workflows, best fit first (confidence 0-1):\",\n ...matches.map((x: any) => `- ${x.workflowId} \"${x.title}\" (${x.confidence}${x.autoStart ? \", starts without asking\" : \"\"}): ${x.steps.map((s: any) => s.id).join(\" → \")}`),\n `Start one with {action:\"start\", workflowId:\"<id>\", title:\"…\", tags:[\"client:<name>\"]}. Run its steps through the workflow, not by hand.`,\n ].join(\"\\n\")\n }\n if (action === \"status\") {\n const runId = str(args.runId)\n if (!runId) return \"Error: status needs runId.\"\n const r = await read(`/follow-up/${encodeURIComponent(runId)}`)\n if (!r.ok) return `Error: ${r.data?.error || `HTTP ${r.status}`}`\n return describe(r.data.run)\n }\n\n const caller = resolveScheduleCaller(args, env)\n if (!caller) return \"Error: couldn't tell which agent you are. Pass callerAgentId.\"\n const res = await doFetch(`${base}/follow-up`, {\n method: \"POST\",\n // The headers name this run: the daemon refuses a write that does\n // not come from a running turn of the agent.\n headers: { \"Content-Type\": \"application/json\", ...callerHeaders(env) },\n body: JSON.stringify({\n action, agentId: caller.agentId,\n workflowId: args.workflowId, title: args.title, description: args.description, tags: args.tags, inputs: args.inputs,\n steps: args.steps, edges: args.edges, approval: args.approval, autoStart: args.autoStart, requestId: args.requestId,\n runId: args.runId, step: args.step, evidence: args.evidence, note: args.note, reason: args.reason, fromRun: args.fromRun,\n }),\n signal: AbortSignal.timeout(20_000),\n })\n const data = await res.json().catch(() => ({})) as any\n if (!res.ok) return `Error: ${data?.error || `HTTP ${res.status}`}`\n if (action === \"start\") {\n const run = data.run\n return [\n `Started run ${run.runId} \"${run.title}\"${data.built ? \" (built from the steps you gave; propose it with fromRun to keep it)\" : \"\"}.`,\n data.awaitingApproval ? \"It waits for the owner's approval before the first step.\" : `It is on step ${run.step}: ${run.waitingOn}.`,\n \"AgentX follows it from here: it starts each step, reminds whoever is slow, and tells the owner when it ends. Do not run its steps by hand.\",\n ...(data.warning ? [`Note: ${data.warning}`] : []),\n ].join(\" \")\n }\n if (action === \"done\") return `Step recorded as done. ${data.run ? describe(data.run) : \"\"}`.trim()\n if (action === \"blocked\") return \"The step is marked blocked and the owner is told. Nothing more happens on it until it is sorted.\"\n return `Saved ${data.workflowId} switched off, and asked the owner (card ${data.cardId}) whether to keep it as a reusable workflow.`\n } catch (e: any) {\n return `Error: couldn't reach the daemon (${e?.message ?? e}).`\n }\n}\n"],"mappings":"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","names":["str","v","describe","run","s","runWorkflowTool","args","deps","doFetch","base","action","env","read","path","res","data","r","groups","g","row","q","caller","resolveScheduleCaller","matches","x","runId","callerHeaders","e"]}
@@ -0,0 +1,2 @@
1
+ import{a}from"./chunk-Z3W7D5RR.js";import"./chunk-P4XGM7ZM.js";import"./chunk-3PGPN323.js";import"./chunk-LDS4SZBU.js";import"./chunk-WPNRDEHW.js";import"./chunk-YWKLUQDC.js";import"./chunk-72SZI2UW.js";import"./chunk-FCPTN6NF.js";import"./chunk-MCI3DIWW.js";import"./chunk-QOYAX2FT.js";import"./chunk-4VVHGR7H.js";import"./chunk-2PJKGZWP.js";import"./chunk-7I7IEX4S.js";import"./chunk-MRYA4J5F.js";import"./chunk-BRK6M6LA.js";import"./chunk-UIBUZ2N3.js";import"./chunk-2QNT5JDS.js";import"./chunk-RGDKHYY2.js";import"./chunk-QIJLFPWE.js";export{a as WikiHub};
2
+ //# sourceMappingURL=hub-5QK7KYTZ.js.map