agentix-cli 0.23.0 → 0.26.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 (191) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +103 -102
  3. package/agentx.example.json +9 -3
  4. package/dist/App-BPNHIGUX.js +8 -0
  5. package/dist/App-BPNHIGUX.js.map +1 -0
  6. package/dist/ChatApp-6XSSZB4U.js +7 -0
  7. package/dist/ChatApp-6XSSZB4U.js.map +1 -0
  8. package/dist/{agent-FSE4KRLX.js → agent-5QMITZT6.js} +2 -2
  9. package/dist/architect-SEPWMWS4.js +2 -0
  10. package/dist/{board-dashboard-PUACKWAN.js → board-dashboard-M3372FLO.js} +4697 -985
  11. package/dist/board-dashboard-M3372FLO.js.map +1 -0
  12. package/dist/builtin-FRKAQMFS.js +2 -0
  13. package/dist/chunk-2WVX3LEC.js +2 -0
  14. package/dist/chunk-2WVX3LEC.js.map +1 -0
  15. package/dist/chunk-3WQFCIB6.js +24 -0
  16. package/dist/chunk-3WQFCIB6.js.map +1 -0
  17. package/dist/{chunk-IKBHHTIT.js → chunk-5U35WAZF.js} +2 -2
  18. package/dist/chunk-67Q4DCPS.js +54 -0
  19. package/dist/chunk-67Q4DCPS.js.map +1 -0
  20. package/dist/chunk-76Z4VHDX.js +8 -0
  21. package/dist/chunk-76Z4VHDX.js.map +1 -0
  22. package/dist/{chunk-7P5QRX5W.js → chunk-BFXONUUN.js} +2 -2
  23. package/dist/chunk-BTHHSY7D.js +13 -0
  24. package/dist/chunk-BTHHSY7D.js.map +1 -0
  25. package/dist/chunk-BVGJSPW4.js +7 -0
  26. package/dist/chunk-BVGJSPW4.js.map +1 -0
  27. package/dist/chunk-D46VZ7K7.js +116 -0
  28. package/dist/chunk-D46VZ7K7.js.map +1 -0
  29. package/dist/chunk-E5CXCI33.js +155 -0
  30. package/dist/chunk-E5CXCI33.js.map +1 -0
  31. package/dist/chunk-FDWOECJY.js +54 -0
  32. package/dist/chunk-FDWOECJY.js.map +1 -0
  33. package/dist/{chunk-NOF4HSGK.js → chunk-H5D7ATXS.js} +2 -2
  34. package/dist/chunk-HR4JSRZS.js +3 -0
  35. package/dist/{chunk-A6BKSZQA.js.map → chunk-HR4JSRZS.js.map} +1 -1
  36. package/dist/chunk-I3SIXTJO.js +44 -0
  37. package/dist/chunk-I3SIXTJO.js.map +1 -0
  38. package/dist/chunk-ISEBLHWX.js +118 -0
  39. package/dist/chunk-ISEBLHWX.js.map +1 -0
  40. package/dist/{chunk-4ITQP3XL.js → chunk-JP5IEXR7.js} +2 -2
  41. package/dist/{chunk-DXTIG5YV.js → chunk-K2CAPYES.js} +2 -2
  42. package/dist/chunk-LDHPMJ7M.js +257 -0
  43. package/dist/chunk-LDHPMJ7M.js.map +1 -0
  44. package/dist/chunk-M4AMWP3H.js +178 -0
  45. package/dist/chunk-M4AMWP3H.js.map +1 -0
  46. package/dist/chunk-METYYZKQ.js +1115 -0
  47. package/dist/chunk-METYYZKQ.js.map +1 -0
  48. package/dist/chunk-MTAPOCGA.js +47 -0
  49. package/dist/chunk-MTAPOCGA.js.map +1 -0
  50. package/dist/chunk-O6YPEOQF.js +5 -0
  51. package/dist/chunk-O6YPEOQF.js.map +1 -0
  52. package/dist/{chunk-CNNLREHD.js → chunk-P4VWIVKN.js} +268 -410
  53. package/dist/chunk-P4VWIVKN.js.map +1 -0
  54. package/dist/chunk-U2CKL755.js +4 -0
  55. package/dist/chunk-U2CKL755.js.map +1 -0
  56. package/dist/chunk-UCQ2N3KO.js +9 -0
  57. package/dist/chunk-UCQ2N3KO.js.map +1 -0
  58. package/dist/chunk-UHE5FCPB.js +431 -0
  59. package/dist/chunk-UHE5FCPB.js.map +1 -0
  60. package/dist/{chunk-KWUWZQGV.js → chunk-V3U4OF7L.js} +29 -30
  61. package/dist/chunk-V3U4OF7L.js.map +1 -0
  62. package/dist/chunk-VT5XYFDD.js +126 -0
  63. package/dist/chunk-VT5XYFDD.js.map +1 -0
  64. package/dist/chunk-W4YR2RO2.js +2 -0
  65. package/dist/chunk-W4YR2RO2.js.map +1 -0
  66. package/dist/cli.js +1 -1
  67. package/dist/cli.js.map +1 -1
  68. package/dist/client-HGKAC6VP.js +2 -0
  69. package/dist/{compaction-BTUJJ3LJ.js → compaction-NWEMOSHA.js} +3 -3
  70. package/dist/config-A4RWEJHV.js +2 -0
  71. package/dist/config-mutator-MNSFUN7D.js +2 -0
  72. package/dist/{context-planner-I7ID7XF3.js → context-planner-45GEWKGL.js} +2 -2
  73. package/dist/doctor-3Q36ZFE6.js +2 -0
  74. package/dist/heal-HZ3EQD52.js +2 -0
  75. package/dist/index.d.ts +1250 -225
  76. package/dist/index.js +12 -12
  77. package/dist/index.js.map +1 -1
  78. package/dist/memory-extract-AENFVVO5.js +2 -0
  79. package/dist/processes-UIC4XXA6.js +2 -0
  80. package/dist/program-SAUNRCCD.js +2 -0
  81. package/dist/projects-api-KRME2YKZ.js +2 -0
  82. package/dist/projects-api-KRME2YKZ.js.map +1 -0
  83. package/dist/projects-mutate-3NHVG437.js +7 -0
  84. package/dist/projects-mutate-3NHVG437.js.map +1 -0
  85. package/dist/providers-L27BJ5A6.js +2 -0
  86. package/dist/registry-HK3WQ7BS.js +2 -0
  87. package/dist/rotation-memo-B3EXXSEH.js +13 -0
  88. package/dist/rotation-memo-B3EXXSEH.js.map +1 -0
  89. package/dist/scheduler-6T2SU5ST.js +2 -0
  90. package/dist/surface-usage-PRL6Z4U3.js +2 -0
  91. package/dist/wiki-M6YNRFC4.js +2 -0
  92. package/dist/workflows/templates/branching.yaml +75 -0
  93. package/dist/workflows/templates/extract.yaml +59 -0
  94. package/dist/workflows/templates/linear.yaml +37 -0
  95. package/dist/workflows/templates/retry.yaml +61 -0
  96. package/dist/workspace-setup-TBQAHYHJ.js +2 -0
  97. package/package.json +10 -3
  98. package/dist/board-dashboard-PUACKWAN.js.map +0 -1
  99. package/dist/builtin-TQKMR42Z.js +0 -2
  100. package/dist/chunk-3SHMHYPD.js +0 -450
  101. package/dist/chunk-3SHMHYPD.js.map +0 -1
  102. package/dist/chunk-4INOOHND.js +0 -6
  103. package/dist/chunk-4INOOHND.js.map +0 -1
  104. package/dist/chunk-5F3J55LG.js +0 -2
  105. package/dist/chunk-5F3J55LG.js.map +0 -1
  106. package/dist/chunk-72PAN7UI.js +0 -103
  107. package/dist/chunk-72PAN7UI.js.map +0 -1
  108. package/dist/chunk-A6BKSZQA.js +0 -3
  109. package/dist/chunk-BHSPAP4U.js +0 -44
  110. package/dist/chunk-BHSPAP4U.js.map +0 -1
  111. package/dist/chunk-BOUKM2PS.js +0 -163
  112. package/dist/chunk-BOUKM2PS.js.map +0 -1
  113. package/dist/chunk-CDNWCYF7.js +0 -2
  114. package/dist/chunk-CDNWCYF7.js.map +0 -1
  115. package/dist/chunk-CNNLREHD.js.map +0 -1
  116. package/dist/chunk-EK37JHJI.js +0 -13
  117. package/dist/chunk-EK37JHJI.js.map +0 -1
  118. package/dist/chunk-EQPUB7CZ.js +0 -685
  119. package/dist/chunk-EQPUB7CZ.js.map +0 -1
  120. package/dist/chunk-EW27SCCC.js +0 -2
  121. package/dist/chunk-EW27SCCC.js.map +0 -1
  122. package/dist/chunk-GOLZ6NEL.js +0 -111
  123. package/dist/chunk-GOLZ6NEL.js.map +0 -1
  124. package/dist/chunk-JGXE2YNV.js +0 -46
  125. package/dist/chunk-JGXE2YNV.js.map +0 -1
  126. package/dist/chunk-KWUWZQGV.js.map +0 -1
  127. package/dist/chunk-MTRWXRFF.js +0 -380
  128. package/dist/chunk-MTRWXRFF.js.map +0 -1
  129. package/dist/chunk-N67JZAXU.js +0 -2
  130. package/dist/chunk-N67JZAXU.js.map +0 -1
  131. package/dist/chunk-PD5Q7D6Z.js +0 -7
  132. package/dist/chunk-PD5Q7D6Z.js.map +0 -1
  133. package/dist/chunk-Q6CAFGXT.js +0 -118
  134. package/dist/chunk-Q6CAFGXT.js.map +0 -1
  135. package/dist/chunk-WJXU5F4Z.js +0 -53
  136. package/dist/chunk-WJXU5F4Z.js.map +0 -1
  137. package/dist/chunk-ZZFXI3CS.js +0 -8
  138. package/dist/chunk-ZZFXI3CS.js.map +0 -1
  139. package/dist/config-ADS54KLC.js +0 -2
  140. package/dist/config-mutator-WTRMBZTO.js +0 -2
  141. package/dist/doctor-T6RB4Q5X.js +0 -2
  142. package/dist/editor-chat-RVLCKKB7.js +0 -137
  143. package/dist/editor-chat-RVLCKKB7.js.map +0 -1
  144. package/dist/heal-YEQYWX2L.js +0 -2
  145. package/dist/inbox-BIN2S5XN.js +0 -2
  146. package/dist/memory-extract-KRCHD3OP.js +0 -2
  147. package/dist/processes-RJ6RDP32.js +0 -2
  148. package/dist/program-V7NGFB2R.js +0 -2
  149. package/dist/providers-WVCMIW67.js +0 -2
  150. package/dist/registry-42HEWCLA.js +0 -2
  151. package/dist/rotation-memo-GMTZPMNE.js +0 -13
  152. package/dist/rotation-memo-GMTZPMNE.js.map +0 -1
  153. package/dist/scheduler-C56ABAVP.js +0 -2
  154. package/dist/slack-6P7ZJ32Y.js +0 -3
  155. package/dist/slack-6P7ZJ32Y.js.map +0 -1
  156. package/dist/store-BAPDZHXE.js +0 -2
  157. package/dist/task-store-RHISEU6V.js +0 -2
  158. package/dist/telegram-PIYDRM46.js +0 -3
  159. package/dist/telegram-PIYDRM46.js.map +0 -1
  160. package/dist/types-ZRLHHCGB.js +0 -2
  161. package/dist/web/workflow-editor.global.js +0 -1452
  162. package/dist/web/workflow-editor.global.js.map +0 -1
  163. package/dist/whatsapp-PFRDMUMT.js +0 -3
  164. package/dist/whatsapp-PFRDMUMT.js.map +0 -1
  165. package/dist/wiki-53W5NLZV.js +0 -2
  166. package/dist/workspace-setup-DQCZX2NE.js +0 -2
  167. package/dist/workspace-setup-DQCZX2NE.js.map +0 -1
  168. /package/dist/{agent-FSE4KRLX.js.map → agent-5QMITZT6.js.map} +0 -0
  169. /package/dist/{builtin-TQKMR42Z.js.map → architect-SEPWMWS4.js.map} +0 -0
  170. /package/dist/{config-ADS54KLC.js.map → builtin-FRKAQMFS.js.map} +0 -0
  171. /package/dist/{chunk-IKBHHTIT.js.map → chunk-5U35WAZF.js.map} +0 -0
  172. /package/dist/{chunk-7P5QRX5W.js.map → chunk-BFXONUUN.js.map} +0 -0
  173. /package/dist/{chunk-NOF4HSGK.js.map → chunk-H5D7ATXS.js.map} +0 -0
  174. /package/dist/{chunk-4ITQP3XL.js.map → chunk-JP5IEXR7.js.map} +0 -0
  175. /package/dist/{chunk-DXTIG5YV.js.map → chunk-K2CAPYES.js.map} +0 -0
  176. /package/dist/{config-mutator-WTRMBZTO.js.map → client-HGKAC6VP.js.map} +0 -0
  177. /package/dist/{compaction-BTUJJ3LJ.js.map → compaction-NWEMOSHA.js.map} +0 -0
  178. /package/dist/{doctor-T6RB4Q5X.js.map → config-A4RWEJHV.js.map} +0 -0
  179. /package/dist/{heal-YEQYWX2L.js.map → config-mutator-MNSFUN7D.js.map} +0 -0
  180. /package/dist/{context-planner-I7ID7XF3.js.map → context-planner-45GEWKGL.js.map} +0 -0
  181. /package/dist/{inbox-BIN2S5XN.js.map → doctor-3Q36ZFE6.js.map} +0 -0
  182. /package/dist/{memory-extract-KRCHD3OP.js.map → heal-HZ3EQD52.js.map} +0 -0
  183. /package/dist/{processes-RJ6RDP32.js.map → memory-extract-AENFVVO5.js.map} +0 -0
  184. /package/dist/{program-V7NGFB2R.js.map → processes-UIC4XXA6.js.map} +0 -0
  185. /package/dist/{providers-WVCMIW67.js.map → program-SAUNRCCD.js.map} +0 -0
  186. /package/dist/{registry-42HEWCLA.js.map → providers-L27BJ5A6.js.map} +0 -0
  187. /package/dist/{scheduler-C56ABAVP.js.map → registry-HK3WQ7BS.js.map} +0 -0
  188. /package/dist/{store-BAPDZHXE.js.map → scheduler-6T2SU5ST.js.map} +0 -0
  189. /package/dist/{task-store-RHISEU6V.js.map → surface-usage-PRL6Z4U3.js.map} +0 -0
  190. /package/dist/{types-ZRLHHCGB.js.map → wiki-M6YNRFC4.js.map} +0 -0
  191. /package/dist/{wiki-53W5NLZV.js.map → workspace-setup-TBQAHYHJ.js.map} +0 -0
package/dist/index.d.ts CHANGED
@@ -23,6 +23,12 @@ interface ProviderOptions {
23
23
  maxTokens?: number;
24
24
  temperature?: number;
25
25
  apiKey?: string;
26
+ /** Operator-cancel signal — passed straight to fetch() so the in-
27
+ * flight HTTP request to the provider can be closed when the
28
+ * task is cancelled. Without this, /api/tasks/:id/cancel only
29
+ * marks the task aborted in the registry; the underlying request
30
+ * can hang for hours waiting for the model to finish thinking. */
31
+ abortSignal?: AbortSignal;
26
32
  }
27
33
  type StreamEvent = {
28
34
  type: "text_delta";
@@ -37,6 +43,9 @@ type StreamEvent = {
37
43
  } | {
38
44
  type: "tool_use_end";
39
45
  name: string;
46
+ } | {
47
+ type: "thinking_delta";
48
+ text: string;
40
49
  } | {
41
50
  type: "done";
42
51
  result: GenerationResult;
@@ -61,6 +70,9 @@ type ContentBlock = {
61
70
  tool_use_id: string;
62
71
  content: string;
63
72
  is_error?: boolean;
73
+ } | {
74
+ type: "reasoning";
75
+ text: string;
64
76
  };
65
77
  interface RawGenerationResult {
66
78
  content: ContentBlock[];
@@ -80,9 +92,41 @@ interface AgentProvider {
80
92
  description: string;
81
93
  input_schema: Record<string, unknown>;
82
94
  }>, options?: ProviderOptions): Promise<RawGenerationResult>;
95
+ /**
96
+ * Streaming variant of generateRaw — emits text_delta events as the
97
+ * model generates so callers can pipe per-token to UIs (voice TTS,
98
+ * SSE, etc.) AND still get the full RawGenerationResult at the end
99
+ * with the tool_use blocks intact, so the agentic loop's tool
100
+ * dispatch keeps working unchanged. Optional — runAgenticLoop falls
101
+ * back to generateRaw() when this isn't implemented.
102
+ */
103
+ generateRawStream?(messages: AnthropicMessage[], systemPrompt: string, tools: Array<{
104
+ name: string;
105
+ description: string;
106
+ input_schema: Record<string, unknown>;
107
+ }>, options?: ProviderOptions): AsyncIterable<RawStreamEvent>;
83
108
  }
109
+ /**
110
+ * Event stream from generateRawStream. text_delta arrives per chunk so
111
+ * the caller can stream to a UI; tool_use blocks accumulate silently and
112
+ * are surfaced in the terminal raw_result event so the agentic loop's
113
+ * tool dispatch logic stays unchanged.
114
+ */
115
+ type RawStreamEvent = {
116
+ type: "text_delta";
117
+ text: string;
118
+ } | {
119
+ type: "thinking_delta";
120
+ text: string;
121
+ } | {
122
+ type: "raw_result";
123
+ result: RawGenerationResult;
124
+ } | {
125
+ type: "error";
126
+ error: string;
127
+ };
84
128
  declare const agentConfigSchema$1: z.ZodObject<{
85
- provider: z.ZodDefault<z.ZodEnum<["claude-code", "claude", "openai", "ollama", "custom"]>>;
129
+ provider: z.ZodDefault<z.ZodEnum<["claude-code", "claude", "openai", "deepseek", "ollama", "demo", "custom"]>>;
86
130
  model: z.ZodOptional<z.ZodString>;
87
131
  apiKey: z.ZodOptional<z.ZodString>;
88
132
  skills: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
@@ -117,7 +161,7 @@ declare const agentConfigSchema$1: z.ZodObject<{
117
161
  disabledTools?: string[] | undefined;
118
162
  }>>;
119
163
  }, "strip", z.ZodTypeAny, {
120
- provider: "claude-code" | "claude" | "openai" | "ollama" | "custom";
164
+ provider: "claude-code" | "claude" | "openai" | "deepseek" | "ollama" | "demo" | "custom";
121
165
  skills: string[];
122
166
  output: {
123
167
  dir: string;
@@ -134,7 +178,7 @@ declare const agentConfigSchema$1: z.ZodObject<{
134
178
  model?: string | undefined;
135
179
  apiKey?: string | undefined;
136
180
  }, {
137
- provider?: "claude-code" | "claude" | "openai" | "ollama" | "custom" | undefined;
181
+ provider?: "claude-code" | "claude" | "openai" | "deepseek" | "ollama" | "demo" | "custom" | undefined;
138
182
  model?: string | undefined;
139
183
  apiKey?: string | undefined;
140
184
  skills?: string[] | undefined;
@@ -168,6 +212,25 @@ declare class ClaudeProvider implements AgentProvider {
168
212
  input_schema: Record<string, unknown>;
169
213
  }>, options?: ProviderOptions): Promise<RawGenerationResult>;
170
214
  stream(messages: GenerationMessage[], options?: ProviderOptions): AsyncIterable<StreamEvent>;
215
+ /**
216
+ * Streaming variant of generateRaw — yields text_delta events per
217
+ * chunk so callers can pipe per-token to a UI, AND assembles the full
218
+ * RawGenerationResult (with tool_use blocks intact, stop_reason set)
219
+ * so the agentic loop's tool dispatch keeps working unchanged.
220
+ *
221
+ * Implementation mirrors stream() but:
222
+ * - Targets generateRaw's signature (anthropicMessages + systemPrompt +
223
+ * tools as parameters, not interleaved messages).
224
+ * - Builds a ContentBlock[] with both text and tool_use blocks in the
225
+ * order they arrived, so the agentic loop's `result.content.filter(
226
+ * b => b.type === "tool_use")` still finds them.
227
+ * - Yields one terminal `raw_result` event the loop consumes.
228
+ */
229
+ generateRawStream(messages: AnthropicMessage[], systemPrompt: string, tools: Array<{
230
+ name: string;
231
+ description: string;
232
+ input_schema: Record<string, unknown>;
233
+ }>, options?: ProviderOptions): AsyncIterable<RawStreamEvent>;
171
234
  private buildHeaders;
172
235
  private callApi;
173
236
  private parseResponse;
@@ -228,8 +291,14 @@ declare class ClaudeCodeProvider implements AgentProvider {
228
291
  private parseApiResponse;
229
292
  }
230
293
 
231
- type ProviderName = "claude-code" | "claude" | "openai" | "ollama" | "custom";
232
- declare function createProvider(name?: ProviderName, apiKey?: string): AgentProvider;
294
+ type ProviderName = "claude-code" | "claude" | "openai" | "deepseek" | "ollama" | "demo" | "custom";
295
+ interface CreateProviderOptions {
296
+ /** Toggle DeepSeek thinking-mode (`reasoning_content` blocks). Default
297
+ * `true` for DeepSeek baseUrls. Wire this from
298
+ * `providers.<name>.thinking` in agentx.json. */
299
+ thinking?: boolean;
300
+ }
301
+ declare function createProvider(name?: ProviderName, apiKey?: string, opts?: CreateProviderOptions): AgentProvider;
233
302
 
234
303
  interface MemoryEntry {
235
304
  id: string;
@@ -328,6 +397,41 @@ declare class HealEngine {
328
397
  private generateFix;
329
398
  }
330
399
 
400
+ /**
401
+ * Get all tool definitions in Anthropic API format (for generateRaw()).
402
+ * Optionally filter by enabled tool names.
403
+ */
404
+ declare function getAnthropicTools(enabledTools?: string[]): Array<{
405
+ name: string;
406
+ description: string;
407
+ input_schema: Record<string, unknown>;
408
+ }>;
409
+ /**
410
+ * Get the legacy tools (create_files + ask_user) for backward compatibility.
411
+ */
412
+ declare function getLegacyTools(): Array<{
413
+ name: string;
414
+ description: string;
415
+ input_schema: Record<string, unknown>;
416
+ }>;
417
+ /**
418
+ * Format tool descriptions for inclusion in a system prompt.
419
+ * Used when the `claude` CLI binary handles its own tools —
420
+ * we describe our additional tools as text so the binary's built-in
421
+ * capabilities (read, write, bash) handle them natively.
422
+ */
423
+ declare function formatToolsForSystemPrompt(): string;
424
+ declare const ALL_TOOL_NAMES: string[];
425
+
426
+ interface NoqtaToolContext {
427
+ /** The noqta.tn user UUID this tool call impersonates. */
428
+ userId: string;
429
+ /** Logical agent id (for the audit table's X-Agent-Id column). */
430
+ agentId?: string;
431
+ /** Override the noqta.tn base URL — defaults to NOQTA_API_URL env or https://noqta.tn. */
432
+ apiUrl?: string;
433
+ }
434
+
331
435
  interface TechStack {
332
436
  languages: Language[];
333
437
  frameworks: Framework[];
@@ -467,6 +571,27 @@ interface SkillMatch {
467
571
  matchReason: string;
468
572
  }
469
573
 
574
+ /** stdio MCP server — spawned as a child process, JSON-RPC over NDJSON
575
+ * on stdin/stdout. The `type` field is optional for backward compat
576
+ * with the original config shape (`{ command, args, env }`). */
577
+ interface McpStdioSpec {
578
+ type?: "stdio";
579
+ command: string;
580
+ args?: string[];
581
+ env?: Record<string, string>;
582
+ }
583
+ /** HTTP MCP server (Streamable HTTP transport) — POST JSON-RPC bodies to
584
+ * `url`, server may answer as `application/json` or stream as
585
+ * `text/event-stream` (`data: <json>` lines). Optional `headers` get
586
+ * merged into every request (auth tokens, tenancy hints, etc.). */
587
+ interface McpHttpSpec {
588
+ type: "http";
589
+ url: string;
590
+ headers?: Record<string, string>;
591
+ }
592
+ type McpServerSpec = McpStdioSpec | McpHttpSpec;
593
+ type McpServerMap = Record<string, McpServerSpec>;
594
+
470
595
  interface AgentContext {
471
596
  techStack: TechStack;
472
597
  schemas: ProjectSchemas;
@@ -498,6 +623,34 @@ interface GenerateOptions {
498
623
  lintCommand?: string;
499
624
  maxAttempts?: number;
500
625
  };
626
+ /** Enables the noqta workspace tool catalog (list_projects, create_task,
627
+ * …) in the agentic loop and threads the user_id through to the
628
+ * executor. Without this set, the noqta-tools are absent from the
629
+ * agent's tool list — keeps non-noqta agents clean. The bearer is
630
+ * read from env at dispatch time and NEVER enters the prompt. */
631
+ noqtaContext?: NoqtaToolContext;
632
+ /** Provider-level options forwarded to `createProvider`. Today only
633
+ * `thinking` (for DeepSeek thinking-mode). Wired from
634
+ * `providers.<name>.thinking` in agentx.json by the daemon's
635
+ * orchestrator-tier dispatch path. */
636
+ providerOpts?: {
637
+ thinking?: boolean;
638
+ };
639
+ /** Operator-cancel signal. When the daemon's task-cancel API fires
640
+ * the AbortController, runAgenticLoop forwards this into the
641
+ * provider's fetch() so the in-flight HTTP call is actually
642
+ * closed. Without this, /api/tasks/:id/cancel for orchestrator-
643
+ * tier agents only marks the task `cancelled` in the registry
644
+ * while the underlying DeepSeek request keeps running (seen in
645
+ * production: 100+ minute hangs). */
646
+ abortSignal?: AbortSignal;
647
+ /** External MCP servers to boot for this generation. Each entry is
648
+ * spawned as a stdio child, its tools listed via tools/list, and
649
+ * exposed to the agentic loop as `mcp__<server>__<tool>`. Wired
650
+ * from `effectiveMcpConfig(agent)` by the orchestrator tier in
651
+ * src/agents/runtime.ts — CLI-backed tiers (claude-code, codex-cli)
652
+ * load their own `.mcp.json` natively and ignore this. */
653
+ mcpServers?: McpServerMap;
501
654
  }
502
655
  interface GenerateResult {
503
656
  files: WriteResult;
@@ -505,6 +658,11 @@ interface GenerateResult {
505
658
  outputType: OutputType;
506
659
  followUp?: string;
507
660
  tokensUsed?: number;
661
+ /** Split tokens when the provider supplies them (Claude raw mode does;
662
+ * CLI mode and legacy fallbacks may not). Callers that bill by
663
+ * direction should prefer these over a 30/70 estimate of tokensUsed. */
664
+ inputTokens?: number;
665
+ outputTokens?: number;
508
666
  healResult?: HealResult;
509
667
  }
510
668
  declare function createAgentContext(cwd: string, task: string, config?: Partial<AgentConfig>): Promise<AgentContext>;
@@ -562,32 +720,6 @@ interface OutputConfig {
562
720
  declare const OUTPUT_CONFIGS: Record<string, OutputConfig>;
563
721
  declare function resolveOutputType(userHint: string | undefined, taskDescription: string): OutputType;
564
722
 
565
- /**
566
- * Get all tool definitions in Anthropic API format (for generateRaw()).
567
- * Optionally filter by enabled tool names.
568
- */
569
- declare function getAnthropicTools(enabledTools?: string[]): Array<{
570
- name: string;
571
- description: string;
572
- input_schema: Record<string, unknown>;
573
- }>;
574
- /**
575
- * Get the legacy tools (create_files + ask_user) for backward compatibility.
576
- */
577
- declare function getLegacyTools(): Array<{
578
- name: string;
579
- description: string;
580
- input_schema: Record<string, unknown>;
581
- }>;
582
- /**
583
- * Format tool descriptions for inclusion in a system prompt.
584
- * Used when the `claude` CLI binary handles its own tools —
585
- * we describe our additional tools as text so the binary's built-in
586
- * capabilities (read, write, bash) handle them natively.
587
- */
588
- declare function formatToolsForSystemPrompt(): string;
589
- declare const ALL_TOOL_NAMES: string[];
590
-
591
723
  interface ToolCallInput {
592
724
  name: string;
593
725
  id: string;
@@ -606,6 +738,16 @@ interface ToolExecutorOptions {
606
738
  interactive?: boolean;
607
739
  overwrite?: boolean;
608
740
  dryRun?: boolean;
741
+ /** When set, noqta-tools (list_projects, create_task, etc.) become
742
+ * available — the executor dispatches them by POSTing to
743
+ * /api/agent/tools with the server-held bearer. The bearer NEVER
744
+ * enters the model's prompt context. Omit to leave noqta-tools off
745
+ * (the agent will see "Unknown tool" if it calls one anyway). */
746
+ noqtaContext?: NoqtaToolContext;
747
+ /** Operator-cancel signal. When fired we short-circuit `execute()`
748
+ * before dispatch and forward to execa as `cancelSignal` so a
749
+ * hung shell command can't outlive the abort. */
750
+ abortSignal?: AbortSignal;
609
751
  }
610
752
  declare class ToolExecutor {
611
753
  private cwd;
@@ -928,7 +1070,7 @@ declare class PermissionManager {
928
1070
  }
929
1071
  declare const globalPermissions: PermissionManager;
930
1072
 
931
- declare const HOOK_EVENTS: readonly ["pre:generate", "post:generate", "pre:file-write", "post:file-write", "pre:prompt", "post:response", "pre:command", "on:error", "pre:tool-call", "post:tool-call", "pre:channel-message", "post:channel-message", "pre:a2a-task", "pre:cron-run", "post:cron-run", "on:gitlab-pipeline", "on:gitlab-issue"];
1073
+ declare const HOOK_EVENTS: readonly ["pre:generate", "post:generate", "pre:file-write", "post:file-write", "pre:prompt", "post:response", "pre:command", "on:error", "pre:tool-call", "post:tool-call", "pre:channel-message", "post:channel-message", "pre:a2a-task", "pre:cron-run", "post:cron-run", "on:gitlab-pipeline", "on:gitlab-issue", "on:gitlab-mr", "on:gitlab-note", "on:github-issue", "on:github-pr", "on:github-push", "on:stripe-event", "on:sentry-issue", "on:vercel-deployment", "on:odoo-event", "on:hubspot-event"];
932
1074
  type HookEvent = (typeof HOOK_EVENTS)[number];
933
1075
  declare const BLOCKING_EVENTS: HookEvent[];
934
1076
  declare const hookDefinitionSchema: z.ZodObject<{
@@ -936,7 +1078,7 @@ declare const hookDefinitionSchema: z.ZodObject<{
936
1078
  type: z.ZodEnum<["command", "prompt", "script"]>;
937
1079
  command: z.ZodOptional<z.ZodString>;
938
1080
  prompt: z.ZodOptional<z.ZodString>;
939
- provider: z.ZodOptional<z.ZodEnum<["claude-code", "claude", "openai", "ollama", "custom"]>>;
1081
+ provider: z.ZodOptional<z.ZodEnum<["claude-code", "claude", "openai", "deepseek", "ollama", "custom"]>>;
940
1082
  model: z.ZodOptional<z.ZodString>;
941
1083
  script: z.ZodOptional<z.ZodString>;
942
1084
  priority: z.ZodDefault<z.ZodNumber>;
@@ -946,7 +1088,7 @@ declare const hookDefinitionSchema: z.ZodObject<{
946
1088
  enabled: boolean;
947
1089
  name: string;
948
1090
  priority: number;
949
- provider?: "claude-code" | "claude" | "openai" | "ollama" | "custom" | undefined;
1091
+ provider?: "claude-code" | "claude" | "openai" | "deepseek" | "ollama" | "custom" | undefined;
950
1092
  model?: string | undefined;
951
1093
  script?: string | undefined;
952
1094
  command?: string | undefined;
@@ -954,7 +1096,7 @@ declare const hookDefinitionSchema: z.ZodObject<{
954
1096
  }, {
955
1097
  type: "script" | "command" | "prompt";
956
1098
  name: string;
957
- provider?: "claude-code" | "claude" | "openai" | "ollama" | "custom" | undefined;
1099
+ provider?: "claude-code" | "claude" | "openai" | "deepseek" | "ollama" | "custom" | undefined;
958
1100
  model?: string | undefined;
959
1101
  enabled?: boolean | undefined;
960
1102
  script?: string | undefined;
@@ -1309,7 +1451,7 @@ declare class A2AClient {
1309
1451
  declare const agentConfigSchema: z.ZodObject<{
1310
1452
  name: z.ZodString;
1311
1453
  workspace: z.ZodString;
1312
- tier: z.ZodDefault<z.ZodEnum<["claude-code", "sdk", "orchestrator"]>>;
1454
+ tier: z.ZodDefault<z.ZodEnum<["claude-code", "codex-cli", "opencode", "sdk", "orchestrator"]>>;
1313
1455
  provider: z.ZodOptional<z.ZodString>;
1314
1456
  model: z.ZodOptional<z.ZodString>;
1315
1457
  systemPrompt: z.ZodOptional<z.ZodString>;
@@ -1336,19 +1478,44 @@ declare const agentConfigSchema: z.ZodObject<{
1336
1478
  /** MCP servers this agent's Claude Code session should load. Synced
1337
1479
  * to <workspace>/.mcp.json at daemon boot via agent-mcp.ts. Operator
1338
1480
  * edits to .mcp.json are respected (see SyncResult.skipped-operator-owned). */
1339
- mcp: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
1481
+ mcp: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodObject<{
1482
+ type: z.ZodLiteral<"http">;
1483
+ url: z.ZodString;
1484
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
1485
+ }, "strip", z.ZodTypeAny, {
1486
+ type: "http";
1487
+ url: string;
1488
+ headers?: Record<string, string> | undefined;
1489
+ }, {
1490
+ type: "http";
1491
+ url: string;
1492
+ headers?: Record<string, string> | undefined;
1493
+ }>, z.ZodObject<{
1494
+ type: z.ZodOptional<z.ZodLiteral<"stdio">>;
1340
1495
  command: z.ZodString;
1341
1496
  args: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
1342
1497
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
1343
1498
  }, "strip", z.ZodTypeAny, {
1344
1499
  command: string;
1345
1500
  args: string[];
1501
+ type?: "stdio" | undefined;
1346
1502
  env?: Record<string, string> | undefined;
1347
1503
  }, {
1348
1504
  command: string;
1505
+ type?: "stdio" | undefined;
1349
1506
  env?: Record<string, string> | undefined;
1350
1507
  args?: string[] | undefined;
1351
- }>>>;
1508
+ }>]>>>;
1509
+ /** Enable CodeGraph (https://github.com/colbymchenry/codegraph) for this
1510
+ * agent's claude-code or codex-cli workspace. When true, agentx (a) adds
1511
+ * a codegraph MCP server to <workspace>/.mcp.json, (b) extends
1512
+ * .claude/settings.json permissions.allow with the codegraph_* tools,
1513
+ * (c) appends a CodeGraph instruction section to the managed CLAUDE.md,
1514
+ * and (d) background-indexes the workspace at daemon boot if .codegraph/
1515
+ * is missing. Off by default — flip on for coding agents (mtgl-v2-coder,
1516
+ * ksi-v2-coder, hasanah-coding, etc.) where token-volume on exploration
1517
+ * loops is the bottleneck. */
1518
+ codegraph: z.ZodDefault<z.ZodBoolean>;
1352
1519
  /** Per-agent override for the global `session.contextStrategy`. Lets
1353
1520
  * one agent run `planner` (smaller upfront context, more tool-driven
1354
1521
  * exploration) while siblings stay on `layered`. Used for agents that
@@ -1360,6 +1527,10 @@ declare const agentConfigSchema: z.ZodObject<{
1360
1527
  * etc.) once a `references/` registry exists in the agent's workspace
1361
1528
  * or repo root. See src/agents/references/. */
1362
1529
  contextReferences: z.ZodDefault<z.ZodBoolean>;
1530
+ /** Whether this agent may emit in-band `agentx:ui` rich-message directives
1531
+ * (buttons/polls/media) on chat channels. Default true — set false to make
1532
+ * the render layer strip any directive and send plain text only. */
1533
+ richMessages: z.ZodDefault<z.ZodBoolean>;
1363
1534
  maxConcurrent: z.ZodDefault<z.ZodNumber>;
1364
1535
  /** Hard wall-clock cap on a single Claude Code invocation. Exceeding the
1365
1536
  * cap sends SIGTERM (exit 143). Default 20 min — bump for devops/coder
@@ -1381,6 +1552,14 @@ declare const agentConfigSchema: z.ZodObject<{
1381
1552
  * without a schema bump. Empty/unset means no enforcement
1382
1553
  * (default — backward compatible). */
1383
1554
  toolUseRequired: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
1555
+ /** Per-agent override for the channel-level `autoReplyLegacy` on
1556
+ * gitlab/github. When set, it wins over `channels.<name>.autoReplyLegacy`
1557
+ * for this agent's replies: `true` makes the daemon auto-post the agent's
1558
+ * final text as a comment (right for coder agents that end their turn with
1559
+ * a summary and don't call `agentx_channel_reply`); `false` suppresses it
1560
+ * (right for chatty agents whose reasoning shouldn't land as a comment).
1561
+ * Unset → fall back to the channel default. */
1562
+ gitlabAutoReply: z.ZodOptional<z.ZodBoolean>;
1384
1563
  /** When true, this agent's claude-code dispatches reuse a long-lived
1385
1564
  * subprocess per (channel, chatId) instead of spawning a fresh
1386
1565
  * `claude -p` per turn. Driven over stdin via stream-json input,
@@ -1416,14 +1595,98 @@ declare const agentConfigSchema: z.ZodObject<{
1416
1595
  * - "public": external apps can POST /api/public/agents/<id>/messages
1417
1596
  * with a scoped token (agent:<id> or agent:*). */
1418
1597
  access: z.ZodDefault<z.ZodEnum<["private", "public"]>>;
1598
+ /** Per-agent third-party integrations registry. Declares which services
1599
+ * this agent has credentials for (telegram-bot, hubspot, gitlab-user,
1600
+ * gmail, etc.). Secrets stay in env vars / keyring; this block holds
1601
+ * declarations + non-secret metadata only. Skills and channel adapters
1602
+ * read from here to know what the agent can use. See INTEGRATION_KINDS. */
1603
+ integrations: z.ZodDefault<z.ZodArray<z.ZodObject<{
1604
+ /** Service identifier — open string, well-known values in INTEGRATION_KINDS. */
1605
+ kind: z.ZodString;
1606
+ /** Human-readable label (e.g. "@cx_bot", "Noqta CRM", "anis@noqta.tn"). Unique per (agent, kind). */
1607
+ label: z.ZodString;
1608
+ credentials: z.ZodDefault<z.ZodObject<{
1609
+ /** Env var holding the secret. Uppercase identifier; daemon resolves at use-time. */
1610
+ tokenEnv: z.ZodOptional<z.ZodString>;
1611
+ /** Alternate env-var keys for credential schemes that need >1 secret
1612
+ * (e.g. HubSpot private app + portal id, OAuth refresh tokens). */
1613
+ privateAppTokenEnv: z.ZodOptional<z.ZodString>;
1614
+ apiKeyEnv: z.ZodOptional<z.ZodString>;
1615
+ refreshTokenEnv: z.ZodOptional<z.ZodString>;
1616
+ clientIdEnv: z.ZodOptional<z.ZodString>;
1617
+ clientSecretEnv: z.ZodOptional<z.ZodString>;
1618
+ /** OS keyring directive — credential lives in macOS Keychain / Linux
1619
+ * Secret Service / Windows Credential Manager. The skill that reads
1620
+ * this integration is responsible for resolving the keyring entry
1621
+ * (typically keyed by agentId+kind). */
1622
+ auth: z.ZodOptional<z.ZodLiteral<"keyring">>;
1623
+ /** File-based session directory (WhatsApp, Telegram MTProto, etc.). */
1624
+ sessionDir: z.ZodOptional<z.ZodString>;
1625
+ }, "strict", z.ZodTypeAny, {
1626
+ tokenEnv?: string | undefined;
1627
+ privateAppTokenEnv?: string | undefined;
1628
+ apiKeyEnv?: string | undefined;
1629
+ refreshTokenEnv?: string | undefined;
1630
+ clientIdEnv?: string | undefined;
1631
+ clientSecretEnv?: string | undefined;
1632
+ auth?: "keyring" | undefined;
1633
+ sessionDir?: string | undefined;
1634
+ }, {
1635
+ tokenEnv?: string | undefined;
1636
+ privateAppTokenEnv?: string | undefined;
1637
+ apiKeyEnv?: string | undefined;
1638
+ refreshTokenEnv?: string | undefined;
1639
+ clientIdEnv?: string | undefined;
1640
+ clientSecretEnv?: string | undefined;
1641
+ auth?: "keyring" | undefined;
1642
+ sessionDir?: string | undefined;
1643
+ }>>;
1644
+ /** Non-secret metadata — username, email, host URL, portal id, JID, etc.
1645
+ * Visible in the dashboard and to skills. */
1646
+ metadata: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
1647
+ /** Operator-set toggle without removing the entry. */
1648
+ enabled: z.ZodDefault<z.ZodBoolean>;
1649
+ }, "strip", z.ZodTypeAny, {
1650
+ enabled: boolean;
1651
+ credentials: {
1652
+ tokenEnv?: string | undefined;
1653
+ privateAppTokenEnv?: string | undefined;
1654
+ apiKeyEnv?: string | undefined;
1655
+ refreshTokenEnv?: string | undefined;
1656
+ clientIdEnv?: string | undefined;
1657
+ clientSecretEnv?: string | undefined;
1658
+ auth?: "keyring" | undefined;
1659
+ sessionDir?: string | undefined;
1660
+ };
1661
+ metadata: Record<string, string | number | boolean>;
1662
+ label: string;
1663
+ kind: string;
1664
+ }, {
1665
+ label: string;
1666
+ kind: string;
1667
+ enabled?: boolean | undefined;
1668
+ credentials?: {
1669
+ tokenEnv?: string | undefined;
1670
+ privateAppTokenEnv?: string | undefined;
1671
+ apiKeyEnv?: string | undefined;
1672
+ refreshTokenEnv?: string | undefined;
1673
+ clientIdEnv?: string | undefined;
1674
+ clientSecretEnv?: string | undefined;
1675
+ auth?: "keyring" | undefined;
1676
+ sessionDir?: string | undefined;
1677
+ } | undefined;
1678
+ metadata?: Record<string, string | number | boolean> | undefined;
1679
+ }>, "many">>;
1419
1680
  }, "strip", z.ZodTypeAny, {
1420
1681
  name: string;
1421
1682
  workspace: string;
1422
- tier: "claude-code" | "sdk" | "orchestrator";
1683
+ tier: "claude-code" | "codex-cli" | "opencode" | "sdk" | "orchestrator";
1423
1684
  mentions: string[];
1424
1685
  intents: string[];
1425
1686
  maxDelegationDepth: number;
1687
+ codegraph: boolean;
1426
1688
  contextReferences: boolean;
1689
+ richMessages: boolean;
1427
1690
  maxConcurrent: number;
1428
1691
  maxExecutionMinutes: number;
1429
1692
  permissionMode: string;
@@ -1437,36 +1700,66 @@ declare const agentConfigSchema: z.ZodObject<{
1437
1700
  intervalMinutes: number;
1438
1701
  };
1439
1702
  access: "private" | "public";
1703
+ integrations: {
1704
+ enabled: boolean;
1705
+ credentials: {
1706
+ tokenEnv?: string | undefined;
1707
+ privateAppTokenEnv?: string | undefined;
1708
+ apiKeyEnv?: string | undefined;
1709
+ refreshTokenEnv?: string | undefined;
1710
+ clientIdEnv?: string | undefined;
1711
+ clientSecretEnv?: string | undefined;
1712
+ auth?: "keyring" | undefined;
1713
+ sessionDir?: string | undefined;
1714
+ };
1715
+ metadata: Record<string, string | number | boolean>;
1716
+ label: string;
1717
+ kind: string;
1718
+ }[];
1440
1719
  provider?: string | undefined;
1441
1720
  model?: string | undefined;
1442
1721
  systemPrompt?: string | undefined;
1443
1722
  mcp?: Record<string, {
1444
1723
  command: string;
1445
1724
  args: string[];
1725
+ type?: "stdio" | undefined;
1446
1726
  env?: Record<string, string> | undefined;
1727
+ } | {
1728
+ type: "http";
1729
+ url: string;
1730
+ headers?: Record<string, string> | undefined;
1447
1731
  }> | undefined;
1448
1732
  contextStrategy?: "layered" | "planner" | undefined;
1733
+ gitlabAutoReply?: boolean | undefined;
1449
1734
  }, {
1450
1735
  name: string;
1451
1736
  workspace: string;
1452
1737
  provider?: string | undefined;
1453
1738
  model?: string | undefined;
1454
- tier?: "claude-code" | "sdk" | "orchestrator" | undefined;
1739
+ tier?: "claude-code" | "codex-cli" | "opencode" | "sdk" | "orchestrator" | undefined;
1455
1740
  systemPrompt?: string | undefined;
1456
1741
  mentions?: string[] | undefined;
1457
1742
  intents?: string[] | undefined;
1458
1743
  maxDelegationDepth?: number | undefined;
1459
1744
  mcp?: Record<string, {
1460
1745
  command: string;
1746
+ type?: "stdio" | undefined;
1461
1747
  env?: Record<string, string> | undefined;
1462
1748
  args?: string[] | undefined;
1749
+ } | {
1750
+ type: "http";
1751
+ url: string;
1752
+ headers?: Record<string, string> | undefined;
1463
1753
  }> | undefined;
1754
+ codegraph?: boolean | undefined;
1464
1755
  contextStrategy?: "layered" | "planner" | undefined;
1465
1756
  contextReferences?: boolean | undefined;
1757
+ richMessages?: boolean | undefined;
1466
1758
  maxConcurrent?: number | undefined;
1467
1759
  maxExecutionMinutes?: number | undefined;
1468
1760
  permissionMode?: string | undefined;
1469
1761
  toolUseRequired?: string[] | undefined;
1762
+ gitlabAutoReply?: boolean | undefined;
1470
1763
  persistentProcess?: boolean | undefined;
1471
1764
  queueMode?: "collect" | "followup" | "drop" | undefined;
1472
1765
  heartbeat?: {
@@ -1476,6 +1769,22 @@ declare const agentConfigSchema: z.ZodObject<{
1476
1769
  intervalMinutes?: number | undefined;
1477
1770
  } | undefined;
1478
1771
  access?: "private" | "public" | undefined;
1772
+ integrations?: {
1773
+ label: string;
1774
+ kind: string;
1775
+ enabled?: boolean | undefined;
1776
+ credentials?: {
1777
+ tokenEnv?: string | undefined;
1778
+ privateAppTokenEnv?: string | undefined;
1779
+ apiKeyEnv?: string | undefined;
1780
+ refreshTokenEnv?: string | undefined;
1781
+ clientIdEnv?: string | undefined;
1782
+ clientSecretEnv?: string | undefined;
1783
+ auth?: "keyring" | undefined;
1784
+ sessionDir?: string | undefined;
1785
+ } | undefined;
1786
+ metadata?: Record<string, string | number | boolean> | undefined;
1787
+ }[] | undefined;
1479
1788
  }>;
1480
1789
  declare const cronJobSchema: z.ZodObject<{
1481
1790
  enabled: z.ZodDefault<z.ZodBoolean>;
@@ -1569,19 +1878,28 @@ declare const daemonConfigSchema: z.ZodObject<{
1569
1878
  apiKey: z.ZodOptional<z.ZodString>;
1570
1879
  defaultModel: z.ZodOptional<z.ZodString>;
1571
1880
  baseUrl: z.ZodOptional<z.ZodString>;
1881
+ /** Toggle thinking-mode output on backends that support it (DeepSeek
1882
+ * V4 `reasoning_content`). When `true` (the DeepSeek default), the
1883
+ * agent streams its reasoning live in the dashboard task modal and
1884
+ * the agentic round-trip echoes it back on the next iteration. Set
1885
+ * to `false` to disable for cost/latency-sensitive agents. Ignored
1886
+ * on backends that don't speak the thinking-mode protocol. */
1887
+ thinking: z.ZodOptional<z.ZodBoolean>;
1572
1888
  }, "strip", z.ZodTypeAny, {
1573
1889
  apiKey?: string | undefined;
1890
+ thinking?: boolean | undefined;
1574
1891
  defaultModel?: string | undefined;
1575
1892
  baseUrl?: string | undefined;
1576
1893
  }, {
1577
1894
  apiKey?: string | undefined;
1895
+ thinking?: boolean | undefined;
1578
1896
  defaultModel?: string | undefined;
1579
1897
  baseUrl?: string | undefined;
1580
1898
  }>>>;
1581
1899
  agents: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
1582
1900
  name: z.ZodString;
1583
1901
  workspace: z.ZodString;
1584
- tier: z.ZodDefault<z.ZodEnum<["claude-code", "sdk", "orchestrator"]>>;
1902
+ tier: z.ZodDefault<z.ZodEnum<["claude-code", "codex-cli", "opencode", "sdk", "orchestrator"]>>;
1585
1903
  provider: z.ZodOptional<z.ZodString>;
1586
1904
  model: z.ZodOptional<z.ZodString>;
1587
1905
  systemPrompt: z.ZodOptional<z.ZodString>;
@@ -1608,19 +1926,44 @@ declare const daemonConfigSchema: z.ZodObject<{
1608
1926
  /** MCP servers this agent's Claude Code session should load. Synced
1609
1927
  * to <workspace>/.mcp.json at daemon boot via agent-mcp.ts. Operator
1610
1928
  * edits to .mcp.json are respected (see SyncResult.skipped-operator-owned). */
1611
- mcp: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
1929
+ mcp: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodObject<{
1930
+ type: z.ZodLiteral<"http">;
1931
+ url: z.ZodString;
1932
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
1933
+ }, "strip", z.ZodTypeAny, {
1934
+ type: "http";
1935
+ url: string;
1936
+ headers?: Record<string, string> | undefined;
1937
+ }, {
1938
+ type: "http";
1939
+ url: string;
1940
+ headers?: Record<string, string> | undefined;
1941
+ }>, z.ZodObject<{
1942
+ type: z.ZodOptional<z.ZodLiteral<"stdio">>;
1612
1943
  command: z.ZodString;
1613
1944
  args: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
1614
1945
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
1615
1946
  }, "strip", z.ZodTypeAny, {
1616
1947
  command: string;
1617
1948
  args: string[];
1949
+ type?: "stdio" | undefined;
1618
1950
  env?: Record<string, string> | undefined;
1619
1951
  }, {
1620
1952
  command: string;
1953
+ type?: "stdio" | undefined;
1621
1954
  env?: Record<string, string> | undefined;
1622
1955
  args?: string[] | undefined;
1623
- }>>>;
1956
+ }>]>>>;
1957
+ /** Enable CodeGraph (https://github.com/colbymchenry/codegraph) for this
1958
+ * agent's claude-code or codex-cli workspace. When true, agentx (a) adds
1959
+ * a codegraph MCP server to <workspace>/.mcp.json, (b) extends
1960
+ * .claude/settings.json permissions.allow with the codegraph_* tools,
1961
+ * (c) appends a CodeGraph instruction section to the managed CLAUDE.md,
1962
+ * and (d) background-indexes the workspace at daemon boot if .codegraph/
1963
+ * is missing. Off by default — flip on for coding agents (mtgl-v2-coder,
1964
+ * ksi-v2-coder, hasanah-coding, etc.) where token-volume on exploration
1965
+ * loops is the bottleneck. */
1966
+ codegraph: z.ZodDefault<z.ZodBoolean>;
1624
1967
  /** Per-agent override for the global `session.contextStrategy`. Lets
1625
1968
  * one agent run `planner` (smaller upfront context, more tool-driven
1626
1969
  * exploration) while siblings stay on `layered`. Used for agents that
@@ -1632,6 +1975,10 @@ declare const daemonConfigSchema: z.ZodObject<{
1632
1975
  * etc.) once a `references/` registry exists in the agent's workspace
1633
1976
  * or repo root. See src/agents/references/. */
1634
1977
  contextReferences: z.ZodDefault<z.ZodBoolean>;
1978
+ /** Whether this agent may emit in-band `agentx:ui` rich-message directives
1979
+ * (buttons/polls/media) on chat channels. Default true — set false to make
1980
+ * the render layer strip any directive and send plain text only. */
1981
+ richMessages: z.ZodDefault<z.ZodBoolean>;
1635
1982
  maxConcurrent: z.ZodDefault<z.ZodNumber>;
1636
1983
  /** Hard wall-clock cap on a single Claude Code invocation. Exceeding the
1637
1984
  * cap sends SIGTERM (exit 143). Default 20 min — bump for devops/coder
@@ -1653,6 +2000,14 @@ declare const daemonConfigSchema: z.ZodObject<{
1653
2000
  * without a schema bump. Empty/unset means no enforcement
1654
2001
  * (default — backward compatible). */
1655
2002
  toolUseRequired: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
2003
+ /** Per-agent override for the channel-level `autoReplyLegacy` on
2004
+ * gitlab/github. When set, it wins over `channels.<name>.autoReplyLegacy`
2005
+ * for this agent's replies: `true` makes the daemon auto-post the agent's
2006
+ * final text as a comment (right for coder agents that end their turn with
2007
+ * a summary and don't call `agentx_channel_reply`); `false` suppresses it
2008
+ * (right for chatty agents whose reasoning shouldn't land as a comment).
2009
+ * Unset → fall back to the channel default. */
2010
+ gitlabAutoReply: z.ZodOptional<z.ZodBoolean>;
1656
2011
  /** When true, this agent's claude-code dispatches reuse a long-lived
1657
2012
  * subprocess per (channel, chatId) instead of spawning a fresh
1658
2013
  * `claude -p` per turn. Driven over stdin via stream-json input,
@@ -1688,14 +2043,98 @@ declare const daemonConfigSchema: z.ZodObject<{
1688
2043
  * - "public": external apps can POST /api/public/agents/<id>/messages
1689
2044
  * with a scoped token (agent:<id> or agent:*). */
1690
2045
  access: z.ZodDefault<z.ZodEnum<["private", "public"]>>;
2046
+ /** Per-agent third-party integrations registry. Declares which services
2047
+ * this agent has credentials for (telegram-bot, hubspot, gitlab-user,
2048
+ * gmail, etc.). Secrets stay in env vars / keyring; this block holds
2049
+ * declarations + non-secret metadata only. Skills and channel adapters
2050
+ * read from here to know what the agent can use. See INTEGRATION_KINDS. */
2051
+ integrations: z.ZodDefault<z.ZodArray<z.ZodObject<{
2052
+ /** Service identifier — open string, well-known values in INTEGRATION_KINDS. */
2053
+ kind: z.ZodString;
2054
+ /** Human-readable label (e.g. "@cx_bot", "Noqta CRM", "anis@noqta.tn"). Unique per (agent, kind). */
2055
+ label: z.ZodString;
2056
+ credentials: z.ZodDefault<z.ZodObject<{
2057
+ /** Env var holding the secret. Uppercase identifier; daemon resolves at use-time. */
2058
+ tokenEnv: z.ZodOptional<z.ZodString>;
2059
+ /** Alternate env-var keys for credential schemes that need >1 secret
2060
+ * (e.g. HubSpot private app + portal id, OAuth refresh tokens). */
2061
+ privateAppTokenEnv: z.ZodOptional<z.ZodString>;
2062
+ apiKeyEnv: z.ZodOptional<z.ZodString>;
2063
+ refreshTokenEnv: z.ZodOptional<z.ZodString>;
2064
+ clientIdEnv: z.ZodOptional<z.ZodString>;
2065
+ clientSecretEnv: z.ZodOptional<z.ZodString>;
2066
+ /** OS keyring directive — credential lives in macOS Keychain / Linux
2067
+ * Secret Service / Windows Credential Manager. The skill that reads
2068
+ * this integration is responsible for resolving the keyring entry
2069
+ * (typically keyed by agentId+kind). */
2070
+ auth: z.ZodOptional<z.ZodLiteral<"keyring">>;
2071
+ /** File-based session directory (WhatsApp, Telegram MTProto, etc.). */
2072
+ sessionDir: z.ZodOptional<z.ZodString>;
2073
+ }, "strict", z.ZodTypeAny, {
2074
+ tokenEnv?: string | undefined;
2075
+ privateAppTokenEnv?: string | undefined;
2076
+ apiKeyEnv?: string | undefined;
2077
+ refreshTokenEnv?: string | undefined;
2078
+ clientIdEnv?: string | undefined;
2079
+ clientSecretEnv?: string | undefined;
2080
+ auth?: "keyring" | undefined;
2081
+ sessionDir?: string | undefined;
2082
+ }, {
2083
+ tokenEnv?: string | undefined;
2084
+ privateAppTokenEnv?: string | undefined;
2085
+ apiKeyEnv?: string | undefined;
2086
+ refreshTokenEnv?: string | undefined;
2087
+ clientIdEnv?: string | undefined;
2088
+ clientSecretEnv?: string | undefined;
2089
+ auth?: "keyring" | undefined;
2090
+ sessionDir?: string | undefined;
2091
+ }>>;
2092
+ /** Non-secret metadata — username, email, host URL, portal id, JID, etc.
2093
+ * Visible in the dashboard and to skills. */
2094
+ metadata: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
2095
+ /** Operator-set toggle without removing the entry. */
2096
+ enabled: z.ZodDefault<z.ZodBoolean>;
2097
+ }, "strip", z.ZodTypeAny, {
2098
+ enabled: boolean;
2099
+ credentials: {
2100
+ tokenEnv?: string | undefined;
2101
+ privateAppTokenEnv?: string | undefined;
2102
+ apiKeyEnv?: string | undefined;
2103
+ refreshTokenEnv?: string | undefined;
2104
+ clientIdEnv?: string | undefined;
2105
+ clientSecretEnv?: string | undefined;
2106
+ auth?: "keyring" | undefined;
2107
+ sessionDir?: string | undefined;
2108
+ };
2109
+ metadata: Record<string, string | number | boolean>;
2110
+ label: string;
2111
+ kind: string;
2112
+ }, {
2113
+ label: string;
2114
+ kind: string;
2115
+ enabled?: boolean | undefined;
2116
+ credentials?: {
2117
+ tokenEnv?: string | undefined;
2118
+ privateAppTokenEnv?: string | undefined;
2119
+ apiKeyEnv?: string | undefined;
2120
+ refreshTokenEnv?: string | undefined;
2121
+ clientIdEnv?: string | undefined;
2122
+ clientSecretEnv?: string | undefined;
2123
+ auth?: "keyring" | undefined;
2124
+ sessionDir?: string | undefined;
2125
+ } | undefined;
2126
+ metadata?: Record<string, string | number | boolean> | undefined;
2127
+ }>, "many">>;
1691
2128
  }, "strip", z.ZodTypeAny, {
1692
2129
  name: string;
1693
2130
  workspace: string;
1694
- tier: "claude-code" | "sdk" | "orchestrator";
2131
+ tier: "claude-code" | "codex-cli" | "opencode" | "sdk" | "orchestrator";
1695
2132
  mentions: string[];
1696
2133
  intents: string[];
1697
2134
  maxDelegationDepth: number;
2135
+ codegraph: boolean;
1698
2136
  contextReferences: boolean;
2137
+ richMessages: boolean;
1699
2138
  maxConcurrent: number;
1700
2139
  maxExecutionMinutes: number;
1701
2140
  permissionMode: string;
@@ -1709,36 +2148,66 @@ declare const daemonConfigSchema: z.ZodObject<{
1709
2148
  intervalMinutes: number;
1710
2149
  };
1711
2150
  access: "private" | "public";
2151
+ integrations: {
2152
+ enabled: boolean;
2153
+ credentials: {
2154
+ tokenEnv?: string | undefined;
2155
+ privateAppTokenEnv?: string | undefined;
2156
+ apiKeyEnv?: string | undefined;
2157
+ refreshTokenEnv?: string | undefined;
2158
+ clientIdEnv?: string | undefined;
2159
+ clientSecretEnv?: string | undefined;
2160
+ auth?: "keyring" | undefined;
2161
+ sessionDir?: string | undefined;
2162
+ };
2163
+ metadata: Record<string, string | number | boolean>;
2164
+ label: string;
2165
+ kind: string;
2166
+ }[];
1712
2167
  provider?: string | undefined;
1713
2168
  model?: string | undefined;
1714
2169
  systemPrompt?: string | undefined;
1715
2170
  mcp?: Record<string, {
1716
2171
  command: string;
1717
2172
  args: string[];
2173
+ type?: "stdio" | undefined;
1718
2174
  env?: Record<string, string> | undefined;
2175
+ } | {
2176
+ type: "http";
2177
+ url: string;
2178
+ headers?: Record<string, string> | undefined;
1719
2179
  }> | undefined;
1720
2180
  contextStrategy?: "layered" | "planner" | undefined;
2181
+ gitlabAutoReply?: boolean | undefined;
1721
2182
  }, {
1722
2183
  name: string;
1723
2184
  workspace: string;
1724
2185
  provider?: string | undefined;
1725
2186
  model?: string | undefined;
1726
- tier?: "claude-code" | "sdk" | "orchestrator" | undefined;
2187
+ tier?: "claude-code" | "codex-cli" | "opencode" | "sdk" | "orchestrator" | undefined;
1727
2188
  systemPrompt?: string | undefined;
1728
2189
  mentions?: string[] | undefined;
1729
2190
  intents?: string[] | undefined;
1730
2191
  maxDelegationDepth?: number | undefined;
1731
2192
  mcp?: Record<string, {
1732
2193
  command: string;
2194
+ type?: "stdio" | undefined;
1733
2195
  env?: Record<string, string> | undefined;
1734
2196
  args?: string[] | undefined;
2197
+ } | {
2198
+ type: "http";
2199
+ url: string;
2200
+ headers?: Record<string, string> | undefined;
1735
2201
  }> | undefined;
2202
+ codegraph?: boolean | undefined;
1736
2203
  contextStrategy?: "layered" | "planner" | undefined;
1737
2204
  contextReferences?: boolean | undefined;
2205
+ richMessages?: boolean | undefined;
1738
2206
  maxConcurrent?: number | undefined;
1739
2207
  maxExecutionMinutes?: number | undefined;
1740
2208
  permissionMode?: string | undefined;
1741
2209
  toolUseRequired?: string[] | undefined;
2210
+ gitlabAutoReply?: boolean | undefined;
1742
2211
  persistentProcess?: boolean | undefined;
1743
2212
  queueMode?: "collect" | "followup" | "drop" | undefined;
1744
2213
  heartbeat?: {
@@ -1748,6 +2217,22 @@ declare const daemonConfigSchema: z.ZodObject<{
1748
2217
  intervalMinutes?: number | undefined;
1749
2218
  } | undefined;
1750
2219
  access?: "private" | "public" | undefined;
2220
+ integrations?: {
2221
+ label: string;
2222
+ kind: string;
2223
+ enabled?: boolean | undefined;
2224
+ credentials?: {
2225
+ tokenEnv?: string | undefined;
2226
+ privateAppTokenEnv?: string | undefined;
2227
+ apiKeyEnv?: string | undefined;
2228
+ refreshTokenEnv?: string | undefined;
2229
+ clientIdEnv?: string | undefined;
2230
+ clientSecretEnv?: string | undefined;
2231
+ auth?: "keyring" | undefined;
2232
+ sessionDir?: string | undefined;
2233
+ } | undefined;
2234
+ metadata?: Record<string, string | number | boolean> | undefined;
2235
+ }[] | undefined;
1751
2236
  }>>>;
1752
2237
  channels: z.ZodDefault<z.ZodObject<{
1753
2238
  telegram: z.ZodDefault<z.ZodObject<{
@@ -1943,8 +2428,8 @@ declare const daemonConfigSchema: z.ZodObject<{
1943
2428
  defaultAgent?: string | undefined;
1944
2429
  }, {
1945
2430
  enabled?: boolean | undefined;
1946
- allowFrom?: string[] | undefined;
1947
2431
  sessionDir?: string | undefined;
2432
+ allowFrom?: string[] | undefined;
1948
2433
  defaultAgent?: string | undefined;
1949
2434
  routes?: {
1950
2435
  agent: string;
@@ -1969,43 +2454,19 @@ declare const daemonConfigSchema: z.ZodObject<{
1969
2454
  retentionDays?: number | undefined;
1970
2455
  } | undefined;
1971
2456
  }>>;
1972
- discord: z.ZodDefault<z.ZodObject<{
1973
- enabled: z.ZodDefault<z.ZodBoolean>;
1974
- token: z.ZodOptional<z.ZodString>;
1975
- agentBinding: z.ZodOptional<z.ZodString>;
1976
- }, "strip", z.ZodTypeAny, {
1977
- enabled: boolean;
1978
- token?: string | undefined;
1979
- agentBinding?: string | undefined;
1980
- }, {
1981
- enabled?: boolean | undefined;
1982
- token?: string | undefined;
1983
- agentBinding?: string | undefined;
1984
- }>>;
1985
- slack: z.ZodDefault<z.ZodObject<{
1986
- enabled: z.ZodDefault<z.ZodBoolean>;
1987
- /** xoxb-... — bot user OAuth token from the Slack app's "OAuth & Permissions" tab. */
1988
- botToken: z.ZodOptional<z.ZodString>;
1989
- /** xapp-... — app-level token with connections:write scope (for Socket Mode). */
1990
- appToken: z.ZodOptional<z.ZodString>;
1991
- agentBinding: z.ZodOptional<z.ZodString>;
1992
- }, "strip", z.ZodTypeAny, {
1993
- enabled: boolean;
1994
- agentBinding?: string | undefined;
1995
- botToken?: string | undefined;
1996
- appToken?: string | undefined;
1997
- }, {
1998
- enabled?: boolean | undefined;
1999
- agentBinding?: string | undefined;
2000
- botToken?: string | undefined;
2001
- appToken?: string | undefined;
2002
- }>>;
2003
2457
  gitlab: z.ZodDefault<z.ZodObject<{
2004
2458
  enabled: z.ZodDefault<z.ZodBoolean>;
2005
2459
  webhookPort: z.ZodDefault<z.ZodNumber>;
2006
2460
  webhookSecret: z.ZodOptional<z.ZodString>;
2007
2461
  host: z.ZodDefault<z.ZodString>;
2008
2462
  token: z.ZodOptional<z.ZodString>;
2463
+ /** Legacy auto-reply: when true (default), the router posts the agent's
2464
+ * `response.content` as a comment automatically. When false, the agent
2465
+ * must call the `channel.reply` action explicitly to reply — agent
2466
+ * reasoning text is logged but not posted. Flip to false once the
2467
+ * project's agents have migrated their gitlab skill to use channel.reply.
2468
+ * Default true preserves today's behaviour for unmigrated projects. */
2469
+ autoReplyLegacy: z.ZodDefault<z.ZodBoolean>;
2009
2470
  routes: z.ZodDefault<z.ZodArray<z.ZodObject<{
2010
2471
  project: z.ZodString;
2011
2472
  agent: z.ZodString;
@@ -2047,6 +2508,7 @@ declare const daemonConfigSchema: z.ZodObject<{
2047
2508
  }[];
2048
2509
  webhookPort: number;
2049
2510
  host: string;
2511
+ autoReplyLegacy: boolean;
2050
2512
  agentMappings: {
2051
2513
  agentId: string;
2052
2514
  gitlabUsernames: string[];
@@ -2066,6 +2528,7 @@ declare const daemonConfigSchema: z.ZodObject<{
2066
2528
  webhookPort?: number | undefined;
2067
2529
  webhookSecret?: string | undefined;
2068
2530
  host?: string | undefined;
2531
+ autoReplyLegacy?: boolean | undefined;
2069
2532
  agentMappings?: {
2070
2533
  agentId: string;
2071
2534
  token?: string | undefined;
@@ -2076,6 +2539,9 @@ declare const daemonConfigSchema: z.ZodObject<{
2076
2539
  }>>;
2077
2540
  github: z.ZodDefault<z.ZodObject<{
2078
2541
  enabled: z.ZodDefault<z.ZodBoolean>;
2542
+ /** Legacy auto-reply — same semantics as gitlab.autoReplyLegacy.
2543
+ * Defaults true; set false once agent skills use channel.reply. */
2544
+ autoReplyLegacy: z.ZodDefault<z.ZodBoolean>;
2079
2545
  /** GitHub PAT or env var (${GITHUB_TOKEN}) for posting comments back. */
2080
2546
  token: z.ZodOptional<z.ZodString>;
2081
2547
  /** Path to file containing the token (first line read at startup). */
@@ -2125,6 +2591,7 @@ declare const daemonConfigSchema: z.ZodObject<{
2125
2591
  agent: string;
2126
2592
  repo: string;
2127
2593
  }[];
2594
+ autoReplyLegacy: boolean;
2128
2595
  agentMappings: {
2129
2596
  agentId: string;
2130
2597
  githubUsernames: string[];
@@ -2146,6 +2613,7 @@ declare const daemonConfigSchema: z.ZodObject<{
2146
2613
  repo: string;
2147
2614
  }[] | undefined;
2148
2615
  webhookSecret?: string | undefined;
2616
+ autoReplyLegacy?: boolean | undefined;
2149
2617
  agentMappings?: {
2150
2618
  agentId: string;
2151
2619
  token?: string | undefined;
@@ -2324,6 +2792,7 @@ declare const daemonConfigSchema: z.ZodObject<{
2324
2792
  }[];
2325
2793
  webhookPort: number;
2326
2794
  host: string;
2795
+ autoReplyLegacy: boolean;
2327
2796
  agentMappings: {
2328
2797
  agentId: string;
2329
2798
  gitlabUsernames: string[];
@@ -2334,20 +2803,6 @@ declare const daemonConfigSchema: z.ZodObject<{
2334
2803
  token?: string | undefined;
2335
2804
  webhookSecret?: string | undefined;
2336
2805
  };
2337
- telegram: {
2338
- enabled: boolean;
2339
- accounts: Record<string, {
2340
- token: string;
2341
- agentBinding: string;
2342
- pollInbound: boolean;
2343
- allowFrom?: string[] | undefined;
2344
- }>;
2345
- policy: {
2346
- dm: "block" | "pair";
2347
- group: "all" | "mention-required";
2348
- allowFrom?: string[] | undefined;
2349
- };
2350
- };
2351
2806
  whatsapp: {
2352
2807
  enabled: boolean;
2353
2808
  sessionDir: string;
@@ -2376,16 +2831,19 @@ declare const daemonConfigSchema: z.ZodObject<{
2376
2831
  allowFrom?: string[] | undefined;
2377
2832
  defaultAgent?: string | undefined;
2378
2833
  };
2379
- discord: {
2380
- enabled: boolean;
2381
- token?: string | undefined;
2382
- agentBinding?: string | undefined;
2383
- };
2384
- slack: {
2834
+ telegram: {
2385
2835
  enabled: boolean;
2386
- agentBinding?: string | undefined;
2387
- botToken?: string | undefined;
2388
- appToken?: string | undefined;
2836
+ accounts: Record<string, {
2837
+ token: string;
2838
+ agentBinding: string;
2839
+ pollInbound: boolean;
2840
+ allowFrom?: string[] | undefined;
2841
+ }>;
2842
+ policy: {
2843
+ dm: "block" | "pair";
2844
+ group: "all" | "mention-required";
2845
+ allowFrom?: string[] | undefined;
2846
+ };
2389
2847
  };
2390
2848
  github: {
2391
2849
  enabled: boolean;
@@ -2393,6 +2851,7 @@ declare const daemonConfigSchema: z.ZodObject<{
2393
2851
  agent: string;
2394
2852
  repo: string;
2395
2853
  }[];
2854
+ autoReplyLegacy: boolean;
2396
2855
  agentMappings: {
2397
2856
  agentId: string;
2398
2857
  githubUsernames: string[];
@@ -2448,6 +2907,7 @@ declare const daemonConfigSchema: z.ZodObject<{
2448
2907
  webhookPort?: number | undefined;
2449
2908
  webhookSecret?: string | undefined;
2450
2909
  host?: string | undefined;
2910
+ autoReplyLegacy?: boolean | undefined;
2451
2911
  agentMappings?: {
2452
2912
  agentId: string;
2453
2913
  token?: string | undefined;
@@ -2456,24 +2916,10 @@ declare const daemonConfigSchema: z.ZodObject<{
2456
2916
  node?: string | undefined;
2457
2917
  }[] | undefined;
2458
2918
  } | undefined;
2459
- telegram?: {
2460
- enabled?: boolean | undefined;
2461
- accounts?: Record<string, {
2462
- token: string;
2463
- agentBinding: string;
2464
- allowFrom?: string[] | undefined;
2465
- pollInbound?: boolean | undefined;
2466
- }> | undefined;
2467
- policy?: {
2468
- allowFrom?: string[] | undefined;
2469
- dm?: "block" | "pair" | undefined;
2470
- group?: "all" | "mention-required" | undefined;
2471
- } | undefined;
2472
- } | undefined;
2473
2919
  whatsapp?: {
2474
2920
  enabled?: boolean | undefined;
2475
- allowFrom?: string[] | undefined;
2476
2921
  sessionDir?: string | undefined;
2922
+ allowFrom?: string[] | undefined;
2477
2923
  defaultAgent?: string | undefined;
2478
2924
  routes?: {
2479
2925
  agent: string;
@@ -2498,16 +2944,19 @@ declare const daemonConfigSchema: z.ZodObject<{
2498
2944
  retentionDays?: number | undefined;
2499
2945
  } | undefined;
2500
2946
  } | undefined;
2501
- discord?: {
2502
- enabled?: boolean | undefined;
2503
- token?: string | undefined;
2504
- agentBinding?: string | undefined;
2505
- } | undefined;
2506
- slack?: {
2947
+ telegram?: {
2507
2948
  enabled?: boolean | undefined;
2508
- agentBinding?: string | undefined;
2509
- botToken?: string | undefined;
2510
- appToken?: string | undefined;
2949
+ accounts?: Record<string, {
2950
+ token: string;
2951
+ agentBinding: string;
2952
+ allowFrom?: string[] | undefined;
2953
+ pollInbound?: boolean | undefined;
2954
+ }> | undefined;
2955
+ policy?: {
2956
+ allowFrom?: string[] | undefined;
2957
+ dm?: "block" | "pair" | undefined;
2958
+ group?: "all" | "mention-required" | undefined;
2959
+ } | undefined;
2511
2960
  } | undefined;
2512
2961
  github?: {
2513
2962
  enabled?: boolean | undefined;
@@ -2517,6 +2966,7 @@ declare const daemonConfigSchema: z.ZodObject<{
2517
2966
  repo: string;
2518
2967
  }[] | undefined;
2519
2968
  webhookSecret?: string | undefined;
2969
+ autoReplyLegacy?: boolean | undefined;
2520
2970
  agentMappings?: {
2521
2971
  agentId: string;
2522
2972
  token?: string | undefined;
@@ -2751,6 +3201,21 @@ declare const daemonConfigSchema: z.ZodObject<{
2751
3201
  url: string;
2752
3202
  token?: string | undefined;
2753
3203
  }>, "many">>;
3204
+ /** Empty by default — a node publishes no inboxes until an operator
3205
+ * declares one, so this feature is opt-in per node. */
3206
+ inboxes: z.ZodDefault<z.ZodArray<z.ZodObject<{
3207
+ name: z.ZodString;
3208
+ agent: z.ZodString;
3209
+ enabled: z.ZodDefault<z.ZodBoolean>;
3210
+ }, "strip", z.ZodTypeAny, {
3211
+ enabled: boolean;
3212
+ agent: string;
3213
+ name: string;
3214
+ }, {
3215
+ agent: string;
3216
+ name: string;
3217
+ enabled?: boolean | undefined;
3218
+ }>, "many">>;
2754
3219
  discovery: z.ZodDefault<z.ZodEnum<["static", "mdns"]>>;
2755
3220
  healthCheck: z.ZodDefault<z.ZodObject<{
2756
3221
  interval: z.ZodDefault<z.ZodNumber>;
@@ -2769,6 +3234,11 @@ declare const daemonConfigSchema: z.ZodObject<{
2769
3234
  url: string;
2770
3235
  token?: string | undefined;
2771
3236
  }[];
3237
+ inboxes: {
3238
+ enabled: boolean;
3239
+ agent: string;
3240
+ name: string;
3241
+ }[];
2772
3242
  discovery: "static" | "mdns";
2773
3243
  healthCheck: {
2774
3244
  timeout: number;
@@ -2781,6 +3251,11 @@ declare const daemonConfigSchema: z.ZodObject<{
2781
3251
  url: string;
2782
3252
  token?: string | undefined;
2783
3253
  }[] | undefined;
3254
+ inboxes?: {
3255
+ agent: string;
3256
+ name: string;
3257
+ enabled?: boolean | undefined;
3258
+ }[] | undefined;
2784
3259
  discovery?: "static" | "mdns" | undefined;
2785
3260
  healthCheck?: {
2786
3261
  timeout?: number | undefined;
@@ -3129,7 +3604,7 @@ declare const daemonConfigSchema: z.ZodObject<{
3129
3604
  }, "strip", z.ZodTypeAny, {
3130
3605
  id: string;
3131
3606
  title: string;
3132
- kind: "open-backlog" | "scoped-label" | "closed" | "label";
3607
+ kind: "label" | "open-backlog" | "scoped-label" | "closed";
3133
3608
  scopedPrefix: string;
3134
3609
  mapsToLabel?: string | undefined;
3135
3610
  scopedLabel?: string | undefined;
@@ -3137,7 +3612,7 @@ declare const daemonConfigSchema: z.ZodObject<{
3137
3612
  }, {
3138
3613
  id: string;
3139
3614
  title: string;
3140
- kind?: "open-backlog" | "scoped-label" | "closed" | "label" | undefined;
3615
+ kind?: "label" | "open-backlog" | "scoped-label" | "closed" | undefined;
3141
3616
  mapsToLabel?: string | undefined;
3142
3617
  scopedLabel?: string | undefined;
3143
3618
  scopedPrefix?: string | undefined;
@@ -3179,7 +3654,7 @@ declare const daemonConfigSchema: z.ZodObject<{
3179
3654
  columns: {
3180
3655
  id: string;
3181
3656
  title: string;
3182
- kind: "open-backlog" | "scoped-label" | "closed" | "label";
3657
+ kind: "label" | "open-backlog" | "scoped-label" | "closed";
3183
3658
  scopedPrefix: string;
3184
3659
  mapsToLabel?: string | undefined;
3185
3660
  scopedLabel?: string | undefined;
@@ -3211,7 +3686,7 @@ declare const daemonConfigSchema: z.ZodObject<{
3211
3686
  columns?: {
3212
3687
  id: string;
3213
3688
  title: string;
3214
- kind?: "open-backlog" | "scoped-label" | "closed" | "label" | undefined;
3689
+ kind?: "label" | "open-backlog" | "scoped-label" | "closed" | undefined;
3215
3690
  mapsToLabel?: string | undefined;
3216
3691
  scopedLabel?: string | undefined;
3217
3692
  scopedPrefix?: string | undefined;
@@ -3359,6 +3834,22 @@ declare const daemonConfigSchema: z.ZodObject<{
3359
3834
  workflows: z.ZodDefault<z.ZodObject<{
3360
3835
  enabled: z.ZodDefault<z.ZodBoolean>;
3361
3836
  dir: z.ZodDefault<z.ZodString>;
3837
+ matching: z.ZodDefault<z.ZodObject<{
3838
+ enabled: z.ZodDefault<z.ZodBoolean>;
3839
+ mode: z.ZodDefault<z.ZodEnum<["suggest", "auto"]>>;
3840
+ autoRunThreshold: z.ZodDefault<z.ZodNumber>;
3841
+ suggestThreshold: z.ZodDefault<z.ZodNumber>;
3842
+ }, "strip", z.ZodTypeAny, {
3843
+ enabled: boolean;
3844
+ mode: "auto" | "suggest";
3845
+ autoRunThreshold: number;
3846
+ suggestThreshold: number;
3847
+ }, {
3848
+ enabled?: boolean | undefined;
3849
+ mode?: "auto" | "suggest" | undefined;
3850
+ autoRunThreshold?: number | undefined;
3851
+ suggestThreshold?: number | undefined;
3852
+ }>>;
3362
3853
  /** Controls whether the dashboard exposes the visual editor. "readonly"
3363
3854
  * serves the list + run timelines but strips write controls from the
3364
3855
  * page. "disabled" hides the tab entirely. */
@@ -3366,18 +3857,108 @@ declare const daemonConfigSchema: z.ZodObject<{
3366
3857
  }, "strip", z.ZodTypeAny, {
3367
3858
  dir: string;
3368
3859
  enabled: boolean;
3860
+ matching: {
3861
+ enabled: boolean;
3862
+ mode: "auto" | "suggest";
3863
+ autoRunThreshold: number;
3864
+ suggestThreshold: number;
3865
+ };
3369
3866
  editor: "disabled" | "readonly" | "edit";
3370
3867
  }, {
3371
3868
  dir?: string | undefined;
3372
3869
  enabled?: boolean | undefined;
3870
+ matching?: {
3871
+ enabled?: boolean | undefined;
3872
+ mode?: "auto" | "suggest" | undefined;
3873
+ autoRunThreshold?: number | undefined;
3874
+ suggestThreshold?: number | undefined;
3875
+ } | undefined;
3373
3876
  editor?: "disabled" | "readonly" | "edit" | undefined;
3374
3877
  }>>;
3878
+ /** Procedures — user-perspective SOPs mined from recurring activity.
3879
+ * The extraction cadence itself lives in `crons.procedure-extract`
3880
+ * (written by `agentx procedure watch`); this block holds the miner's
3881
+ * thresholds and the injection gates the daemon reads. */
3882
+ procedures: z.ZodDefault<z.ZodObject<{
3883
+ enabled: z.ZodDefault<z.ZodBoolean>;
3884
+ dir: z.ZodDefault<z.ZodString>;
3885
+ extraction: z.ZodDefault<z.ZodObject<{
3886
+ enabled: z.ZodDefault<z.ZodBoolean>;
3887
+ /** Count patterns live after each completed task (no LLM cost). */
3888
+ onTaskCompletion: z.ZodDefault<z.ZodBoolean>;
3889
+ minOccurrences: z.ZodDefault<z.ZodNumber>;
3890
+ sinceDays: z.ZodDefault<z.ZodNumber>;
3891
+ maxClusters: z.ZodDefault<z.ZodNumber>;
3892
+ /** Agent whose session distills drafts (LLM path). */
3893
+ via: z.ZodOptional<z.ZodString>;
3894
+ }, "strip", z.ZodTypeAny, {
3895
+ enabled: boolean;
3896
+ onTaskCompletion: boolean;
3897
+ minOccurrences: number;
3898
+ sinceDays: number;
3899
+ maxClusters: number;
3900
+ via?: string | undefined;
3901
+ }, {
3902
+ enabled?: boolean | undefined;
3903
+ onTaskCompletion?: boolean | undefined;
3904
+ minOccurrences?: number | undefined;
3905
+ sinceDays?: number | undefined;
3906
+ maxClusters?: number | undefined;
3907
+ via?: string | undefined;
3908
+ }>>;
3909
+ /** Inject matching procedures into fresh agent sessions as guidance. */
3910
+ injection: z.ZodDefault<z.ZodObject<{
3911
+ enabled: z.ZodDefault<z.ZodBoolean>;
3912
+ maxProcedures: z.ZodDefault<z.ZodNumber>;
3913
+ minScore: z.ZodDefault<z.ZodNumber>;
3914
+ }, "strip", z.ZodTypeAny, {
3915
+ enabled: boolean;
3916
+ maxProcedures: number;
3917
+ minScore: number;
3918
+ }, {
3919
+ enabled?: boolean | undefined;
3920
+ maxProcedures?: number | undefined;
3921
+ minScore?: number | undefined;
3922
+ }>>;
3923
+ }, "strip", z.ZodTypeAny, {
3924
+ dir: string;
3925
+ enabled: boolean;
3926
+ extraction: {
3927
+ enabled: boolean;
3928
+ onTaskCompletion: boolean;
3929
+ minOccurrences: number;
3930
+ sinceDays: number;
3931
+ maxClusters: number;
3932
+ via?: string | undefined;
3933
+ };
3934
+ injection: {
3935
+ enabled: boolean;
3936
+ maxProcedures: number;
3937
+ minScore: number;
3938
+ };
3939
+ }, {
3940
+ dir?: string | undefined;
3941
+ enabled?: boolean | undefined;
3942
+ extraction?: {
3943
+ enabled?: boolean | undefined;
3944
+ onTaskCompletion?: boolean | undefined;
3945
+ minOccurrences?: number | undefined;
3946
+ sinceDays?: number | undefined;
3947
+ maxClusters?: number | undefined;
3948
+ via?: string | undefined;
3949
+ } | undefined;
3950
+ injection?: {
3951
+ enabled?: boolean | undefined;
3952
+ maxProcedures?: number | undefined;
3953
+ minScore?: number | undefined;
3954
+ } | undefined;
3955
+ }>>;
3375
3956
  /** Registered inbound webhooks — an inventory the dashboard manages. Each
3376
3957
  * entry binds an (agent, source) pair to an optional signing secret. The
3377
3958
  * actual inbound URL is always POST /webhook/<agentId>/<source>. */
3378
3959
  webhooks: z.ZodDefault<z.ZodArray<z.ZodObject<{
3379
3960
  id: z.ZodString;
3380
- source: z.ZodEnum<["gitlab", "github", "sentry", "stripe", "discord", "slack", "custom"]>;
3961
+ source: z.ZodString;
3381
3962
  agentId: z.ZodString;
3382
3963
  secretEnv: z.ZodOptional<z.ZodString>;
3383
3964
  description: z.ZodOptional<z.ZodString>;
@@ -3404,7 +3985,7 @@ declare const daemonConfigSchema: z.ZodObject<{
3404
3985
  }, "strip", z.ZodTypeAny, {
3405
3986
  enabled: boolean;
3406
3987
  id: string;
3407
- source: "custom" | "gitlab" | "discord" | "slack" | "github" | "sentry" | "stripe";
3988
+ source: string;
3408
3989
  agentId: string;
3409
3990
  description?: string | undefined;
3410
3991
  triggers?: Record<string, string> | undefined;
@@ -3413,7 +3994,7 @@ declare const daemonConfigSchema: z.ZodObject<{
3413
3994
  defaultWorkflow?: string | undefined;
3414
3995
  }, {
3415
3996
  id: string;
3416
- source: "custom" | "gitlab" | "discord" | "slack" | "github" | "sentry" | "stripe";
3997
+ source: string;
3417
3998
  agentId: string;
3418
3999
  enabled?: boolean | undefined;
3419
4000
  description?: string | undefined;
@@ -3423,17 +4004,19 @@ declare const daemonConfigSchema: z.ZodObject<{
3423
4004
  defaultWorkflow?: string | undefined;
3424
4005
  }>, "many">>;
3425
4006
  /** Session cache-reuse policy. Controls when we drop a Claude `--resume`
3426
- * session and rebuild the prompt from scratch.
3427
- * - `staleMinutes`: idle timeout before rotation. Longer is cheaper at
3428
- * Opus rates but lets a session accumulate tool-result bloat across an
3429
- * all-day chat.
3430
- * - `maxTurnsPerSession`: hard cap on turns per Claude session. Prevents
3431
- * unbounded `--resume` growth. When hit, next turn starts fresh with
3432
- * the compacted summary + recent-messages context.
3433
- * - `tierTwoThresholdTokens`: if the prior turn's (input + cacheRead +
3434
- * cacheCreate) exceeded this, rotate proactively. Claude bills tier-2
3435
- * at 1.5× above 200K total input, so rotating before that threshold
3436
- * undercuts the multiplier. */
4007
+ * session and rebuild the prompt from scratch. Every rotation captures a
4008
+ * continuity memo that's injected into the chat's next fresh session.
4009
+ * - `staleMinutes`: idle timeout before rotation. 12 h default — chat
4010
+ * conversations must survive a workday's pauses; overnight silence
4011
+ * starts fresh.
4012
+ * - `maxTurnsPerSession`: backstop cap on turns per Claude session.
4013
+ * Size-based rotation measures real context now, so this rarely fires
4014
+ * first.
4015
+ * - `tierTwoThresholdTokens`: rotate when the prior turn's END-OF-TURN
4016
+ * per-request context (last API call's input + cacheRead + cacheCreate)
4017
+ * reaches this. Claude bills the 1.5× long-context rate above 200K
4018
+ * per REQUEST — 180K leaves headroom. NOT the cumulative turn total:
4019
+ * that sums cache reads across every call and reads 10-20× too high. */
3437
4020
  session: z.ZodDefault<z.ZodObject<{
3438
4021
  staleMinutes: z.ZodDefault<z.ZodNumber>;
3439
4022
  maxTurnsPerSession: z.ZodDefault<z.ZodNumber>;
@@ -3479,15 +4062,45 @@ declare const daemonConfigSchema: z.ZodObject<{
3479
4062
  * default — installs that don't list plugins are unaffected. Plugin
3480
4063
  * authoring guide: docs/architecture/plugins.md. */
3481
4064
  plugins: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
4065
+ /** Persistent-process pool eviction knobs (handoff #8). The pool keeps
4066
+ * one warm Claude subprocess per (agent, channel, chatId) so latency
4067
+ * stays low; without bounds, an idle process can serve traffic days
4068
+ * later with stale context. These knobs cap that risk. All values are
4069
+ * in seconds for operator-friendliness; the registry uses ms internally.
4070
+ *
4071
+ * - `maxIdleSeconds`: a handle becomes eligible for cap-pressured
4072
+ * eviction this many seconds after its last turn. Default 30s
4073
+ * (matches the registry's pre-config behavior).
4074
+ * - `maxAgeSeconds`: a handle is killed unconditionally on the next
4075
+ * sweep once its total wall-clock idleness exceeds this. Default
4076
+ * 2700s (45min) — matches the registry's pre-config staleTimeoutMs.
4077
+ * - `sweepIntervalSeconds`: how often the sweeper checks. Default 5s.
4078
+ *
4079
+ * See `agents.<id>.persistentProcess` to opt an agent into the pool. */
4080
+ processPool: z.ZodDefault<z.ZodObject<{
4081
+ maxIdleSeconds: z.ZodDefault<z.ZodNumber>;
4082
+ maxAgeSeconds: z.ZodDefault<z.ZodNumber>;
4083
+ sweepIntervalSeconds: z.ZodDefault<z.ZodNumber>;
4084
+ }, "strip", z.ZodTypeAny, {
4085
+ maxIdleSeconds: number;
4086
+ maxAgeSeconds: number;
4087
+ sweepIntervalSeconds: number;
4088
+ }, {
4089
+ maxIdleSeconds?: number | undefined;
4090
+ maxAgeSeconds?: number | undefined;
4091
+ sweepIntervalSeconds?: number | undefined;
4092
+ }>>;
3482
4093
  }, "strip", z.ZodTypeAny, {
3483
4094
  agents: Record<string, {
3484
4095
  name: string;
3485
4096
  workspace: string;
3486
- tier: "claude-code" | "sdk" | "orchestrator";
4097
+ tier: "claude-code" | "codex-cli" | "opencode" | "sdk" | "orchestrator";
3487
4098
  mentions: string[];
3488
4099
  intents: string[];
3489
4100
  maxDelegationDepth: number;
4101
+ codegraph: boolean;
3490
4102
  contextReferences: boolean;
4103
+ richMessages: boolean;
3491
4104
  maxConcurrent: number;
3492
4105
  maxExecutionMinutes: number;
3493
4106
  permissionMode: string;
@@ -3501,15 +4114,37 @@ declare const daemonConfigSchema: z.ZodObject<{
3501
4114
  intervalMinutes: number;
3502
4115
  };
3503
4116
  access: "private" | "public";
4117
+ integrations: {
4118
+ enabled: boolean;
4119
+ credentials: {
4120
+ tokenEnv?: string | undefined;
4121
+ privateAppTokenEnv?: string | undefined;
4122
+ apiKeyEnv?: string | undefined;
4123
+ refreshTokenEnv?: string | undefined;
4124
+ clientIdEnv?: string | undefined;
4125
+ clientSecretEnv?: string | undefined;
4126
+ auth?: "keyring" | undefined;
4127
+ sessionDir?: string | undefined;
4128
+ };
4129
+ metadata: Record<string, string | number | boolean>;
4130
+ label: string;
4131
+ kind: string;
4132
+ }[];
3504
4133
  provider?: string | undefined;
3505
4134
  model?: string | undefined;
3506
4135
  systemPrompt?: string | undefined;
3507
4136
  mcp?: Record<string, {
3508
4137
  command: string;
3509
4138
  args: string[];
4139
+ type?: "stdio" | undefined;
3510
4140
  env?: Record<string, string> | undefined;
4141
+ } | {
4142
+ type: "http";
4143
+ url: string;
4144
+ headers?: Record<string, string> | undefined;
3511
4145
  }> | undefined;
3512
4146
  contextStrategy?: "layered" | "planner" | undefined;
4147
+ gitlabAutoReply?: boolean | undefined;
3513
4148
  }>;
3514
4149
  mesh: {
3515
4150
  enabled: boolean;
@@ -3518,6 +4153,11 @@ declare const daemonConfigSchema: z.ZodObject<{
3518
4153
  url: string;
3519
4154
  token?: string | undefined;
3520
4155
  }[];
4156
+ inboxes: {
4157
+ enabled: boolean;
4158
+ agent: string;
4159
+ name: string;
4160
+ }[];
3521
4161
  discovery: "static" | "mdns";
3522
4162
  healthCheck: {
3523
4163
  timeout: number;
@@ -3545,6 +4185,7 @@ declare const daemonConfigSchema: z.ZodObject<{
3545
4185
  };
3546
4186
  providers: Record<string, {
3547
4187
  apiKey?: string | undefined;
4188
+ thinking?: boolean | undefined;
3548
4189
  defaultModel?: string | undefined;
3549
4190
  baseUrl?: string | undefined;
3550
4191
  }>;
@@ -3557,6 +4198,7 @@ declare const daemonConfigSchema: z.ZodObject<{
3557
4198
  }[];
3558
4199
  webhookPort: number;
3559
4200
  host: string;
4201
+ autoReplyLegacy: boolean;
3560
4202
  agentMappings: {
3561
4203
  agentId: string;
3562
4204
  gitlabUsernames: string[];
@@ -3567,20 +4209,6 @@ declare const daemonConfigSchema: z.ZodObject<{
3567
4209
  token?: string | undefined;
3568
4210
  webhookSecret?: string | undefined;
3569
4211
  };
3570
- telegram: {
3571
- enabled: boolean;
3572
- accounts: Record<string, {
3573
- token: string;
3574
- agentBinding: string;
3575
- pollInbound: boolean;
3576
- allowFrom?: string[] | undefined;
3577
- }>;
3578
- policy: {
3579
- dm: "block" | "pair";
3580
- group: "all" | "mention-required";
3581
- allowFrom?: string[] | undefined;
3582
- };
3583
- };
3584
4212
  whatsapp: {
3585
4213
  enabled: boolean;
3586
4214
  sessionDir: string;
@@ -3609,16 +4237,19 @@ declare const daemonConfigSchema: z.ZodObject<{
3609
4237
  allowFrom?: string[] | undefined;
3610
4238
  defaultAgent?: string | undefined;
3611
4239
  };
3612
- discord: {
3613
- enabled: boolean;
3614
- token?: string | undefined;
3615
- agentBinding?: string | undefined;
3616
- };
3617
- slack: {
4240
+ telegram: {
3618
4241
  enabled: boolean;
3619
- agentBinding?: string | undefined;
3620
- botToken?: string | undefined;
3621
- appToken?: string | undefined;
4242
+ accounts: Record<string, {
4243
+ token: string;
4244
+ agentBinding: string;
4245
+ pollInbound: boolean;
4246
+ allowFrom?: string[] | undefined;
4247
+ }>;
4248
+ policy: {
4249
+ dm: "block" | "pair";
4250
+ group: "all" | "mention-required";
4251
+ allowFrom?: string[] | undefined;
4252
+ };
3622
4253
  };
3623
4254
  github: {
3624
4255
  enabled: boolean;
@@ -3626,6 +4257,7 @@ declare const daemonConfigSchema: z.ZodObject<{
3626
4257
  agent: string;
3627
4258
  repo: string;
3628
4259
  }[];
4260
+ autoReplyLegacy: boolean;
3629
4261
  agentMappings: {
3630
4262
  agentId: string;
3631
4263
  githubUsernames: string[];
@@ -3732,7 +4364,7 @@ declare const daemonConfigSchema: z.ZodObject<{
3732
4364
  columns: {
3733
4365
  id: string;
3734
4366
  title: string;
3735
- kind: "open-backlog" | "scoped-label" | "closed" | "label";
4367
+ kind: "label" | "open-backlog" | "scoped-label" | "closed";
3736
4368
  scopedPrefix: string;
3737
4369
  mapsToLabel?: string | undefined;
3738
4370
  scopedLabel?: string | undefined;
@@ -3767,12 +4399,35 @@ declare const daemonConfigSchema: z.ZodObject<{
3767
4399
  workflows: {
3768
4400
  dir: string;
3769
4401
  enabled: boolean;
4402
+ matching: {
4403
+ enabled: boolean;
4404
+ mode: "auto" | "suggest";
4405
+ autoRunThreshold: number;
4406
+ suggestThreshold: number;
4407
+ };
3770
4408
  editor: "disabled" | "readonly" | "edit";
3771
4409
  };
4410
+ procedures: {
4411
+ dir: string;
4412
+ enabled: boolean;
4413
+ extraction: {
4414
+ enabled: boolean;
4415
+ onTaskCompletion: boolean;
4416
+ minOccurrences: number;
4417
+ sinceDays: number;
4418
+ maxClusters: number;
4419
+ via?: string | undefined;
4420
+ };
4421
+ injection: {
4422
+ enabled: boolean;
4423
+ maxProcedures: number;
4424
+ minScore: number;
4425
+ };
4426
+ };
3772
4427
  webhooks: {
3773
4428
  enabled: boolean;
3774
4429
  id: string;
3775
- source: "custom" | "gitlab" | "discord" | "slack" | "github" | "sentry" | "stripe";
4430
+ source: string;
3776
4431
  agentId: string;
3777
4432
  description?: string | undefined;
3778
4433
  triggers?: Record<string, string> | undefined;
@@ -3789,6 +4444,11 @@ declare const daemonConfigSchema: z.ZodObject<{
3789
4444
  maxClaudeCodeDispatchesPer5h: number;
3790
4445
  };
3791
4446
  plugins: string[];
4447
+ processPool: {
4448
+ maxIdleSeconds: number;
4449
+ maxAgeSeconds: number;
4450
+ sweepIntervalSeconds: number;
4451
+ };
3792
4452
  business?: {
3793
4453
  enabled: boolean;
3794
4454
  projects: {
@@ -3863,22 +4523,30 @@ declare const daemonConfigSchema: z.ZodObject<{
3863
4523
  workspace: string;
3864
4524
  provider?: string | undefined;
3865
4525
  model?: string | undefined;
3866
- tier?: "claude-code" | "sdk" | "orchestrator" | undefined;
4526
+ tier?: "claude-code" | "codex-cli" | "opencode" | "sdk" | "orchestrator" | undefined;
3867
4527
  systemPrompt?: string | undefined;
3868
4528
  mentions?: string[] | undefined;
3869
4529
  intents?: string[] | undefined;
3870
4530
  maxDelegationDepth?: number | undefined;
3871
4531
  mcp?: Record<string, {
3872
4532
  command: string;
4533
+ type?: "stdio" | undefined;
3873
4534
  env?: Record<string, string> | undefined;
3874
4535
  args?: string[] | undefined;
4536
+ } | {
4537
+ type: "http";
4538
+ url: string;
4539
+ headers?: Record<string, string> | undefined;
3875
4540
  }> | undefined;
4541
+ codegraph?: boolean | undefined;
3876
4542
  contextStrategy?: "layered" | "planner" | undefined;
3877
4543
  contextReferences?: boolean | undefined;
4544
+ richMessages?: boolean | undefined;
3878
4545
  maxConcurrent?: number | undefined;
3879
4546
  maxExecutionMinutes?: number | undefined;
3880
4547
  permissionMode?: string | undefined;
3881
4548
  toolUseRequired?: string[] | undefined;
4549
+ gitlabAutoReply?: boolean | undefined;
3882
4550
  persistentProcess?: boolean | undefined;
3883
4551
  queueMode?: "collect" | "followup" | "drop" | undefined;
3884
4552
  heartbeat?: {
@@ -3888,6 +4556,22 @@ declare const daemonConfigSchema: z.ZodObject<{
3888
4556
  intervalMinutes?: number | undefined;
3889
4557
  } | undefined;
3890
4558
  access?: "private" | "public" | undefined;
4559
+ integrations?: {
4560
+ label: string;
4561
+ kind: string;
4562
+ enabled?: boolean | undefined;
4563
+ credentials?: {
4564
+ tokenEnv?: string | undefined;
4565
+ privateAppTokenEnv?: string | undefined;
4566
+ apiKeyEnv?: string | undefined;
4567
+ refreshTokenEnv?: string | undefined;
4568
+ clientIdEnv?: string | undefined;
4569
+ clientSecretEnv?: string | undefined;
4570
+ auth?: "keyring" | undefined;
4571
+ sessionDir?: string | undefined;
4572
+ } | undefined;
4573
+ metadata?: Record<string, string | number | boolean> | undefined;
4574
+ }[] | undefined;
3891
4575
  }> | undefined;
3892
4576
  mesh?: {
3893
4577
  enabled?: boolean | undefined;
@@ -3896,6 +4580,11 @@ declare const daemonConfigSchema: z.ZodObject<{
3896
4580
  url: string;
3897
4581
  token?: string | undefined;
3898
4582
  }[] | undefined;
4583
+ inboxes?: {
4584
+ agent: string;
4585
+ name: string;
4586
+ enabled?: boolean | undefined;
4587
+ }[] | undefined;
3899
4588
  discovery?: "static" | "mdns" | undefined;
3900
4589
  healthCheck?: {
3901
4590
  timeout?: number | undefined;
@@ -3917,6 +4606,7 @@ declare const daemonConfigSchema: z.ZodObject<{
3917
4606
  } | undefined;
3918
4607
  providers?: Record<string, {
3919
4608
  apiKey?: string | undefined;
4609
+ thinking?: boolean | undefined;
3920
4610
  defaultModel?: string | undefined;
3921
4611
  baseUrl?: string | undefined;
3922
4612
  }> | undefined;
@@ -3931,6 +4621,7 @@ declare const daemonConfigSchema: z.ZodObject<{
3931
4621
  webhookPort?: number | undefined;
3932
4622
  webhookSecret?: string | undefined;
3933
4623
  host?: string | undefined;
4624
+ autoReplyLegacy?: boolean | undefined;
3934
4625
  agentMappings?: {
3935
4626
  agentId: string;
3936
4627
  token?: string | undefined;
@@ -3939,24 +4630,10 @@ declare const daemonConfigSchema: z.ZodObject<{
3939
4630
  node?: string | undefined;
3940
4631
  }[] | undefined;
3941
4632
  } | undefined;
3942
- telegram?: {
3943
- enabled?: boolean | undefined;
3944
- accounts?: Record<string, {
3945
- token: string;
3946
- agentBinding: string;
3947
- allowFrom?: string[] | undefined;
3948
- pollInbound?: boolean | undefined;
3949
- }> | undefined;
3950
- policy?: {
3951
- allowFrom?: string[] | undefined;
3952
- dm?: "block" | "pair" | undefined;
3953
- group?: "all" | "mention-required" | undefined;
3954
- } | undefined;
3955
- } | undefined;
3956
4633
  whatsapp?: {
3957
4634
  enabled?: boolean | undefined;
3958
- allowFrom?: string[] | undefined;
3959
4635
  sessionDir?: string | undefined;
4636
+ allowFrom?: string[] | undefined;
3960
4637
  defaultAgent?: string | undefined;
3961
4638
  routes?: {
3962
4639
  agent: string;
@@ -3981,16 +4658,19 @@ declare const daemonConfigSchema: z.ZodObject<{
3981
4658
  retentionDays?: number | undefined;
3982
4659
  } | undefined;
3983
4660
  } | undefined;
3984
- discord?: {
3985
- enabled?: boolean | undefined;
3986
- token?: string | undefined;
3987
- agentBinding?: string | undefined;
3988
- } | undefined;
3989
- slack?: {
4661
+ telegram?: {
3990
4662
  enabled?: boolean | undefined;
3991
- agentBinding?: string | undefined;
3992
- botToken?: string | undefined;
3993
- appToken?: string | undefined;
4663
+ accounts?: Record<string, {
4664
+ token: string;
4665
+ agentBinding: string;
4666
+ allowFrom?: string[] | undefined;
4667
+ pollInbound?: boolean | undefined;
4668
+ }> | undefined;
4669
+ policy?: {
4670
+ allowFrom?: string[] | undefined;
4671
+ dm?: "block" | "pair" | undefined;
4672
+ group?: "all" | "mention-required" | undefined;
4673
+ } | undefined;
3994
4674
  } | undefined;
3995
4675
  github?: {
3996
4676
  enabled?: boolean | undefined;
@@ -4000,6 +4680,7 @@ declare const daemonConfigSchema: z.ZodObject<{
4000
4680
  repo: string;
4001
4681
  }[] | undefined;
4002
4682
  webhookSecret?: string | undefined;
4683
+ autoReplyLegacy?: boolean | undefined;
4003
4684
  agentMappings?: {
4004
4685
  agentId: string;
4005
4686
  token?: string | undefined;
@@ -4167,7 +4848,7 @@ declare const daemonConfigSchema: z.ZodObject<{
4167
4848
  columns?: {
4168
4849
  id: string;
4169
4850
  title: string;
4170
- kind?: "open-backlog" | "scoped-label" | "closed" | "label" | undefined;
4851
+ kind?: "label" | "open-backlog" | "scoped-label" | "closed" | undefined;
4171
4852
  mapsToLabel?: string | undefined;
4172
4853
  scopedLabel?: string | undefined;
4173
4854
  scopedPrefix?: string | undefined;
@@ -4201,11 +4882,34 @@ declare const daemonConfigSchema: z.ZodObject<{
4201
4882
  workflows?: {
4202
4883
  dir?: string | undefined;
4203
4884
  enabled?: boolean | undefined;
4885
+ matching?: {
4886
+ enabled?: boolean | undefined;
4887
+ mode?: "auto" | "suggest" | undefined;
4888
+ autoRunThreshold?: number | undefined;
4889
+ suggestThreshold?: number | undefined;
4890
+ } | undefined;
4204
4891
  editor?: "disabled" | "readonly" | "edit" | undefined;
4205
4892
  } | undefined;
4893
+ procedures?: {
4894
+ dir?: string | undefined;
4895
+ enabled?: boolean | undefined;
4896
+ extraction?: {
4897
+ enabled?: boolean | undefined;
4898
+ onTaskCompletion?: boolean | undefined;
4899
+ minOccurrences?: number | undefined;
4900
+ sinceDays?: number | undefined;
4901
+ maxClusters?: number | undefined;
4902
+ via?: string | undefined;
4903
+ } | undefined;
4904
+ injection?: {
4905
+ enabled?: boolean | undefined;
4906
+ maxProcedures?: number | undefined;
4907
+ minScore?: number | undefined;
4908
+ } | undefined;
4909
+ } | undefined;
4206
4910
  webhooks?: {
4207
4911
  id: string;
4208
- source: "custom" | "gitlab" | "discord" | "slack" | "github" | "sentry" | "stripe";
4912
+ source: string;
4209
4913
  agentId: string;
4210
4914
  enabled?: boolean | undefined;
4211
4915
  description?: string | undefined;
@@ -4223,6 +4927,11 @@ declare const daemonConfigSchema: z.ZodObject<{
4223
4927
  maxClaudeCodeDispatchesPer5h?: number | undefined;
4224
4928
  } | undefined;
4225
4929
  plugins?: string[] | undefined;
4930
+ processPool?: {
4931
+ maxIdleSeconds?: number | undefined;
4932
+ maxAgeSeconds?: number | undefined;
4933
+ sweepIntervalSeconds?: number | undefined;
4934
+ } | undefined;
4226
4935
  }>;
4227
4936
  type DaemonConfig = z.infer<typeof daemonConfigSchema>;
4228
4937
  type AgentDef = z.infer<typeof agentConfigSchema>;
@@ -4320,6 +5029,13 @@ declare class A2AMesh {
4320
5029
  * caller is allowed to act for this agent. Optional during the
4321
5030
  * log-warn rollout; missing values produce a server-side warning. */
4322
5031
  senderAgentId?: string;
5032
+ /** Force a fresh session on the receiving daemon (clears cached
5033
+ * claudeSessionId + kills any persistent-process handle keyed
5034
+ * on the receiver's (agent, channel, chatId) before exec).
5035
+ * Defaults undefined → receiver applies its own auto-default
5036
+ * (true when senderAgentId is set, otherwise false). Set
5037
+ * explicitly to override. */
5038
+ freshSession?: boolean;
4323
5039
  /** Origin context — channel, chatId, sender, channelMeta, etc. Forwarded
4324
5040
  * to the receiving daemon's /task handler verbatim so the receiver's
4325
5041
  * registry.execute() keys the session by the SAME (channel, chatId)
@@ -4330,6 +5046,27 @@ declare class A2AMesh {
4330
5046
  * 2026-04-29 issue #709. Shape matches AgentTask.context. */
4331
5047
  context?: Record<string, unknown>;
4332
5048
  }): Promise<string>;
5049
+ /**
5050
+ * Streaming variant of `sendTask`. POSTs to the peer's `/task` with
5051
+ * `Accept: text/event-stream`, parses the agentx SSE wire (event/data
5052
+ * pairs), and yields `{event, data}` records as they arrive — text
5053
+ * deltas, thinking chunks, tool start/result, and a terminal
5054
+ * `done` (or `error`).
5055
+ *
5056
+ * Same timeout + dispatcher story as sendTask: undici dispatcher with
5057
+ * disabled headersTimeout/bodyTimeout so a multi-minute agent run does
5058
+ * not get killed by the default 300s headers cap, while an
5059
+ * AbortController enforces our own wall-clock.
5060
+ */
5061
+ sendTaskStream(peerName: string, text: string, agentId?: string, opts?: {
5062
+ timeoutMs?: number;
5063
+ senderAgentId?: string;
5064
+ freshSession?: boolean;
5065
+ context?: Record<string, unknown>;
5066
+ }): AsyncGenerator<{
5067
+ event: string;
5068
+ data: any;
5069
+ }>;
4333
5070
  /**
4334
5071
  * Forward a WebRTC signaling message (SDP / ICE / hangup) to a remote peer's
4335
5072
  * /webrtc/signal endpoint. Not gated by peer health — a healthy control plane
@@ -4359,6 +5096,12 @@ declare class A2AMesh {
4359
5096
  * workflow `action.send` to forward outbound messages back to the peer
4360
5097
  * that owns the channel when the workflow runs on a different node.
4361
5098
  */
5099
+ /**
5100
+ * Auth headers for daemon-level fetches to a peer's protected endpoints.
5101
+ * Tokens deliberately never ride along in directory() — it is served to
5102
+ * dashboards and /mesh; look them up per-request by peer name instead.
5103
+ */
5104
+ authHeaders(peerName: string): Record<string, string>;
4362
5105
  directory(): Array<{
4363
5106
  peer: string;
4364
5107
  peerUrl: string;
@@ -4467,12 +5210,17 @@ declare class AgentXDaemon {
4467
5210
  private registry;
4468
5211
  private router;
4469
5212
  private cron;
5213
+ /** Per-project webhook rules. Hot-reloaded from .agentx/projects/.
5214
+ * Wired into the gitlab/github adapters at startup so they can gate
5215
+ * events and resolve runbook paths. */
5216
+ private projectRules;
4470
5217
  private mesh?;
4471
5218
  private hooks;
4472
5219
  private landscape;
4473
5220
  private heartbeat;
4474
5221
  private business?;
4475
5222
  private httpServer?;
5223
+ private attachSweep?;
4476
5224
  private webhooks;
4477
5225
  private github?;
4478
5226
  private webrtc?;
@@ -4553,6 +5301,13 @@ declare class AgentXDaemon {
4553
5301
  * The page does getUserMedia, RTCPeerConnection, and POSTs/listens signals.
4554
5302
  */
4555
5303
  private serveCallPage;
5304
+ /** POST endpoints that mesh peers call across the network. Everything
5305
+ * else on this server is either read-only, loopback-operated (CLI,
5306
+ * same-host dashboard), or carries its own secret (chat routes). */
5307
+ private static readonly MESH_PROTECTED_PATHS;
5308
+ /** Wraps decideMeshAuth (daemon/mesh-auth.ts) with token collection,
5309
+ * logging, and the 401 response. */
5310
+ private checkMeshAuth;
4556
5311
  private handleHttp;
4557
5312
  /**
4558
5313
  * OpenAI-compatible chat completions endpoint.
@@ -4567,6 +5322,13 @@ declare class AgentXDaemon {
4567
5322
  */
4568
5323
  private handleOpenAICompat;
4569
5324
  private json;
5325
+ /** Resolve a GitLab API token for the given agent, checking (in order):
5326
+ * 1. `channels.gitlab.agentMappings[].token` — legacy per-agent token
5327
+ * 2. `agents[id].integrations[]` (kind=gitlab-user, tokenEnv) — newer
5328
+ * style used by agents declared via `agentx manage`
5329
+ * 3. `channels.gitlab.token` — global fallback (group bot identity)
5330
+ * Returns the token plus a `source` tag for diagnostic logging. */
5331
+ private resolveGitlabTokenForAgent;
4570
5332
  /** Pick today's usage rollup according to AGENTX_USAGE_READ:
4571
5333
  * - "sqlite": SQLite only (empty if db null / no rows)
4572
5334
  * - "json": JSON only (legacy behaviour)
@@ -4594,10 +5356,6 @@ declare class AgentXDaemon {
4594
5356
  * heavy lifting is in `AgentRegistry.agentMemory` (AgentMemory); this
4595
5357
  * is a thin JSON wrapper that validates + delegates. */
4596
5358
  private handleMemoryApi;
4597
- /** Mesh receiver for forwarded workflow events. Peers POST the same
4598
- * payload shape the MeshForwarder sends. Enforces that the run is
4599
- * actually home'd here before acting — protects against routing loops. */
4600
- private handleTaskApi;
4601
5359
  private handleWorkflowEvent;
4602
5360
  /** Mesh-callable outbound send. A peer's workflow `action.send` invokes
4603
5361
  * this when the channel lives on this node (e.g. clawd-server hosts
@@ -4617,6 +5375,13 @@ declare class AgentXDaemon {
4617
5375
  * `sources` in the response tells the editor where the entries came from
4618
5376
  * so it can show that metadata alongside. */
4619
5377
  private handleChannelChats;
5378
+ /** Replay a draft as an ad-hoc workflow. The draft itself stays in
5379
+ * `_drafts/`; we register a copy as `_adhoc-replay-<draftId>-<ts>.yaml`
5380
+ * in the active store, hot-reload, and fire it through the dispatcher.
5381
+ * Input is sourced from a trace pulled out of the draft's
5382
+ * `sourceTaskIds` — caller can override which trace via `taskId` in the
5383
+ * body, or supply a payload directly via `input`. */
5384
+ private handleWorkflowDraftReplay;
4620
5385
  /** Manual run endpoint used by `agentx workflow run <id>`. Only workflows
4621
5386
  * whose trigger node is `trigger.manual` are runnable here — any other
4622
5387
  * source expects a live event and shouldn't race with a manual kick. */
@@ -4800,6 +5565,19 @@ declare class TokenTracker {
4800
5565
  private save;
4801
5566
  }
4802
5567
 
5568
+ interface FriendlyError {
5569
+ /** One-line, operator-facing message suitable for a dashboard card or chat reply. */
5570
+ message: string;
5571
+ /** Optional next step the user can take. */
5572
+ fix?: string;
5573
+ /** Machine-readable error category for routing / retries. */
5574
+ kind: "out_of_credits" | "overage_disabled" | "usage_cap" | "auth" | "permission" | "rate_limit" | "overloaded" | "context_too_large" | "invalid_request" | "upstream_api" | "timeout" | "cancelled" | "unknown";
5575
+ /** Whether this error is transient — a retry has a reasonable chance of succeeding. */
5576
+ retryable: boolean;
5577
+ /** Source error text retained for logs / debugging. */
5578
+ raw?: string;
5579
+ }
5580
+
4803
5581
  interface AgentPeer {
4804
5582
  id: string;
4805
5583
  name: string;
@@ -4902,15 +5680,38 @@ interface AgentTask {
4902
5680
  };
4903
5681
  facts?: string[];
4904
5682
  };
5683
+ /** Path to the project root whose runbook (CLAUDE.md / AGENTS.md / etc.)
5684
+ * should be injected into the agent's system prefix for this task.
5685
+ * Set by the gitlab/github adapters when a project rule resolves a
5686
+ * `runbook:` path. Optional. */
5687
+ runbookPath?: string;
5688
+ /** Override list of files to read from runbookPath. Optional. */
5689
+ runbookFiles?: string[];
4905
5690
  };
4906
5691
  }
4907
5692
  interface AgentResponse {
4908
5693
  content: string;
4909
5694
  error?: string;
5695
+ /** Typed discriminator on `error`. Lets dispatchers and workflow nodes
5696
+ * branch on the failure cause without string-matching the friendly
5697
+ * message (which is operator-facing prose, not machine input). The
5698
+ * full FriendlyError taxonomy is in error-map.ts; common ones to
5699
+ * branch on: `out_of_credits`, `rate_limit`, `auth`, `timeout`. */
5700
+ errorKind?: FriendlyError["kind"];
4910
5701
  tokensUsed?: number;
4911
5702
  duration?: number;
4912
5703
  claudeSessionId?: string;
5704
+ codexSessionId?: string;
5705
+ opencodeSessionId?: string;
4913
5706
  usage?: TokenUsage;
5707
+ /** End-of-turn context size: the LAST API call's (input + cacheRead +
5708
+ * cacheCreate) inside this turn, captured from the final assistant
5709
+ * stream event. `usage` above is CUMULATIVE across every call in the
5710
+ * agentic loop (a tool-heavy turn easily sums to millions via cache
5711
+ * reads) — only this field reflects how full the conversation context
5712
+ * actually is, so rotation decisions must use it, never `usage`.
5713
+ * Undefined on non-streaming paths (result JSON has no per-call data). */
5714
+ contextTokens?: number;
4914
5715
  /** The model Claude actually billed for (from the CLI's init event). When
4915
5716
  * absent, cost reporting should fall back to the model override / agent
4916
5717
  * config. Knowing the billed model is what makes cache-aware pricing
@@ -4921,6 +5722,10 @@ interface AgentResponse {
4921
5722
  * requested agent (the local registry didn't have it). Name of the
4922
5723
  * peer that actually ran it. */
4923
5724
  viaMesh?: string;
5725
+ /** Set when a live Claude Code session attached to this identity answered
5726
+ * the task instead of a spawned provider (attach mode). Claude Code
5727
+ * session id of the terminal that wrote the reply. */
5728
+ viaAttachedSession?: string;
4924
5729
  }
4925
5730
  /** Callback for streaming text deltas */
4926
5731
  type StreamCallback = (delta: string, fullText: string) => void;
@@ -4938,18 +5743,34 @@ interface TokenUsage {
4938
5743
  * Execute a task using the Claude Code CLI (tier: "claude-code").
4939
5744
  * Non-streaming — waits for full response.
4940
5745
  */
4941
- declare function executeClaudeCode(agent: AgentDef, task: AgentTask, historyContext?: string, resumeSessionId?: string): Promise<AgentResponse>;
5746
+ declare function executeClaudeCode(agent: AgentDef, task: AgentTask, historyContext?: string, resumeSessionId?: string, abortSignal?: AbortSignal): Promise<AgentResponse>;
5747
+ declare function executeOpenCodeCli(agent: AgentDef, task: AgentTask, onDelta?: StreamCallback, historyContext?: string, resumeSessionId?: string, onEvent?: (event: any) => void, abortSignal?: AbortSignal, onThinking?: ThinkingCallback): Promise<AgentResponse>;
4942
5748
  /**
4943
5749
  * Execute a task using the Claude Agent SDK (tier: "sdk").
4944
5750
  */
4945
5751
  declare function executeSdk(agent: AgentDef, task: AgentTask, apiKey: string, historyContext?: string): Promise<AgentResponse>;
4946
5752
  /**
4947
5753
  * Execute a task using agentx's own orchestrator (tier: "orchestrator").
5754
+ *
5755
+ * When `onDelta` is supplied, switches from `generate()` (single-shot) to
5756
+ * `generateStream()` and forwards text deltas as they arrive. This is what
5757
+ * lets the daemon's POST /chat?stream=true actually stream Claude/DeepSeek
5758
+ * tokens — without it, the orchestrator returned only after the agentic
5759
+ * loop finished and SSE clients saw `role` then `stop` with no content
5760
+ * between (the failure mode that surfaced on the noqta-public smoke test
5761
+ * after the tier switch).
4948
5762
  */
4949
- declare function executeOrchestrator(agent: AgentDef, task: AgentTask, apiKey?: string, historyContext?: string): Promise<AgentResponse>;
5763
+ /** Side-channel for reasoning/thinking chunks — distinct from
5764
+ * StreamCallback so callers can route them to a different UI lane
5765
+ * (e.g. a collapsible thinking block on noqta.tn, a dimmed terminal
5766
+ * block in the dashboard) without polluting the visible response. */
5767
+ type ThinkingCallback = (text: string) => void;
5768
+ declare function executeOrchestrator(agent: AgentDef, task: AgentTask, apiKey?: string, historyContext?: string, onDelta?: StreamCallback, providerOpts?: {
5769
+ thinking?: boolean;
5770
+ }, onThinking?: ThinkingCallback, abortSignal?: AbortSignal, onEvent?: (event: any) => void): Promise<AgentResponse>;
4950
5771
  declare function executeTask(agent: AgentDef, task: AgentTask, providers: Record<string, {
4951
5772
  apiKey?: string;
4952
- }>, onDelta?: StreamCallback, historyContext?: string, resumeSessionId?: string, onEvent?: (event: any) => void): Promise<AgentResponse>;
5773
+ }>, onDelta?: StreamCallback, historyContext?: string, resumeSessionId?: string, onEvent?: (event: any) => void, abortSignal?: AbortSignal, onThinking?: ThinkingCallback): Promise<AgentResponse>;
4953
5774
 
4954
5775
  interface DriftReport {
4955
5776
  /** 0-1 score: 0 = no drift, 1 = complete drift */
@@ -5092,6 +5913,17 @@ interface IncomingMessage {
5092
5913
  eventId: string;
5093
5914
  decidedBy: string;
5094
5915
  };
5916
+ /** Path to the project root whose runbook (CLAUDE.md / AGENTS.md / etc.)
5917
+ * the agent should consult for this task. Set by the gitlab/github
5918
+ * adapters when a project rule resolves a `runbook:` path. The agent
5919
+ * registry reads the file set into the cacheable system prefix.
5920
+ * Undefined when no rule matched — agent uses its own workspace's
5921
+ * CLAUDE.md as before. */
5922
+ runbookPath?: string;
5923
+ /** Override list of files the registry should read from runbookPath.
5924
+ * Carried alongside the path so per-project customisation applies
5925
+ * without the registry re-reading the rule. */
5926
+ runbookFiles?: string[];
5095
5927
  }
5096
5928
  interface OutgoingMessage {
5097
5929
  channel: string;
@@ -5112,6 +5944,12 @@ interface OutgoingMessage {
5112
5944
  mimetype?: string;
5113
5945
  fileName?: string;
5114
5946
  };
5947
+ /** URL inline buttons (Phase 1). Telegram renders an inline_keyboard;
5948
+ * channels without button support ignore them. */
5949
+ buttons?: Array<{
5950
+ label: string;
5951
+ url: string;
5952
+ }>;
5115
5953
  }
5116
5954
  interface ChannelAdapter {
5117
5955
  readonly name: string;
@@ -5178,6 +6016,8 @@ interface Session {
5178
6016
  chatId: string;
5179
6017
  day: string;
5180
6018
  claudeSessionId?: string;
6019
+ codexSessionId?: string;
6020
+ opencodeSessionId?: string;
5181
6021
  messages: SessionMessage[];
5182
6022
  createdAt: string;
5183
6023
  updatedAt: string;
@@ -5186,11 +6026,24 @@ interface Session {
5186
6026
  * Claude CLI replays the entire prior session on every turn, so long
5187
6027
  * sessions pay a linearly growing cache-read tax. */
5188
6028
  turnCount?: number;
5189
- /** Total billable input of the LAST turn on this claudeSessionId
5190
- * (inputTokens + cacheReadTokens + cacheCreateTokens). Used to detect
5191
- * tier-2 hits (>200K) from the prior turn so we can rotate before the
5192
- * next turn pays the 1.5× multiplier again. */
6029
+ /** CUMULATIVE billable input of the LAST turn on this claudeSessionId
6030
+ * (inputTokens + cacheReadTokens + cacheCreateTokens summed across every
6031
+ * API call in the agentic loop). Kept for observability/billing only —
6032
+ * a tool-heavy turn sums to millions via cache reads, so this must NOT
6033
+ * drive rotation decisions. See lastTurnContextTokens. */
5193
6034
  lastTurnInputTokens?: number;
6035
+ /** End-of-turn CONTEXT size: the last API call's (input + cacheRead +
6036
+ * cacheCreate) inside the previous turn — how full the conversation
6037
+ * window actually is. This is the tier-2 rotation metric. Absent when
6038
+ * the turn ran through a non-streaming path (no per-call usage). */
6039
+ lastTurnContextTokens?: number;
6040
+ }
6041
+ /** Continuity memo captured from a dying session at rotation time —
6042
+ * injected deterministically into the chat's next fresh session. */
6043
+ interface RotationMemoRecord {
6044
+ memo: string;
6045
+ reason: string;
6046
+ capturedAt: string;
5194
6047
  }
5195
6048
  declare class SessionStore {
5196
6049
  private sessionsDir;
@@ -5241,6 +6094,10 @@ declare class SessionStore {
5241
6094
  * Get or create a session for this agent+channel+chat+day.
5242
6095
  */
5243
6096
  getSession(agentId: string, channel: string, chatId: string): Session;
6097
+ /** Yesterday's (UTC) session record for the same triple, or null. Only
6098
+ * one day back — a gap of 2+ days is stale at any sane staleMinutes,
6099
+ * so scanning further would never change the outcome. */
6100
+ private loadPreviousDaySession;
5244
6101
  /**
5245
6102
  * Add a user message to the session. Consecutive duplicates from the same
5246
6103
  * sender are collapsed — when a user re-sends the exact same text (retry,
@@ -5248,6 +6105,14 @@ declare class SessionStore {
5248
6105
  * replayed history and re-burns tokens on every subsequent turn.
5249
6106
  */
5250
6107
  addUserMessage(agentId: string, channel: string, chatId: string, senderName: string, content: string): void;
6108
+ /**
6109
+ * Pop the last user message if it matches `expectedContent` (exact equality
6110
+ * after trim). Used by the operator Update flow when Stop was pressed
6111
+ * first — the cancelled user turn has no agent reply, so leaving it in
6112
+ * history makes the next Update read as a bare orphan ask. Match guard
6113
+ * prevents removing something a concurrent path just added.
6114
+ */
6115
+ removeLastUserMessageIfMatches(agentId: string, channel: string, chatId: string, expectedContent: string): boolean;
5251
6116
  /**
5252
6117
  * Add an agent response to the session. Same dedup rule as user messages —
5253
6118
  * retries and duplicate responses shouldn't be replayed on every turn.
@@ -5262,12 +6127,19 @@ declare class SessionStore {
5262
6127
  * Store the Claude Code session ID after first invocation.
5263
6128
  */
5264
6129
  setClaudeSessionId(agentId: string, channel: string, chatId: string, claudeSessionId: string): void;
6130
+ getCodexSessionId(agentId: string, channel: string, chatId: string): string | undefined;
6131
+ setCodexSessionId(agentId: string, channel: string, chatId: string, codexSessionId: string): void;
6132
+ getOpenCodeSessionId(agentId: string, channel: string, chatId: string): string | undefined;
6133
+ setOpenCodeSessionId(agentId: string, channel: string, chatId: string, opencodeSessionId: string): void;
5265
6134
  /**
5266
6135
  * Build conversation history string to prepend to the prompt.
5267
6136
  * Returns empty string if no history.
5268
6137
  * Used for non-claude-code tiers that don't have native sessions.
5269
6138
  */
5270
- buildHistoryContext(agentId: string, channel: string, chatId: string): string;
6139
+ buildHistoryContext(agentId: string, channel: string, chatId: string, opts?: {
6140
+ maxMessages?: number;
6141
+ maxChars?: number;
6142
+ }): string;
5271
6143
  /**
5272
6144
  * Recall conversation turns across multiple stored sessions for an agent.
5273
6145
  *
@@ -5339,7 +6211,7 @@ declare class SessionStore {
5339
6211
  sessionFile: string;
5340
6212
  }>;
5341
6213
  /**
5342
- * Check if a Claude session is stale (idle too long for --resume to be useful).
6214
+ * Check if a native CLI session is stale (idle too long for resume to be useful).
5343
6215
  * When stale, the resumed context will be too far behind — better to start fresh.
5344
6216
  */
5345
6217
  isSessionStale(agentId: string, channel: string, chatId: string): boolean;
@@ -5371,35 +6243,57 @@ declare class SessionStore {
5371
6243
  */
5372
6244
  hasCompaction(agentId: string, channel: string, chatId: string): boolean;
5373
6245
  /**
5374
- * Clear the stored Claude session ID so next invocation starts fresh.
6246
+ * Clear stored native CLI session IDs so next invocation starts fresh.
5375
6247
  * Also resets the per-session turn counter and last-turn input size —
5376
- * those are only meaningful relative to the current claudeSessionId.
6248
+ * those are only meaningful relative to the current native session.
5377
6249
  */
5378
6250
  clearClaudeSessionId(agentId: string, channel: string, chatId: string): void;
6251
+ /**
6252
+ * Reset the entire AgentX-side conversation for a delegated fresh session.
6253
+ * Claude needs the native session id cleared; Codex and other non-native
6254
+ * runtimes also need the rendered message history removed or they will see
6255
+ * stale turns through buildHistoryContext().
6256
+ */
6257
+ clearSession(agentId: string, channel: string, chatId: string): void;
5379
6258
  /**
5380
6259
  * Check whether this session has hit the max-turns cap. Rotate when true
5381
6260
  * to stop --resume replay from growing unbounded across a long chat.
5382
6261
  */
5383
6262
  shouldRotateByTurns(agentId: string, channel: string, chatId: string): boolean;
5384
6263
  /**
5385
- * Check whether the LAST turn on this session pushed total input past
5386
- * the tier-2 threshold. If yes, rotate so we don't pay the 1.5×
5387
- * multiplier again on the next turn.
6264
+ * Check whether the LAST turn left the conversation context near the
6265
+ * tier-2 boundary. Uses `lastTurnContextTokens` (the final API call's
6266
+ * per-request input — the true context size) when the runtime captured
6267
+ * it; falls back to the cumulative turn total only when it didn't.
6268
+ * The cumulative number sums cache reads across every call in an
6269
+ * agentic turn (easily 10-20× the real context), so preferring the
6270
+ * per-call metric is what stops rotation from firing on every
6271
+ * tool-heavy turn — the "agent forgets mid-task" bug.
5388
6272
  */
5389
6273
  shouldRotateByTierTwo(agentId: string, channel: string, chatId: string): boolean;
5390
6274
  /**
5391
6275
  * Record a completed turn's token usage and bump the turn counter.
5392
- * Called after a successful Claude response returns with usage info.
6276
+ * Called after a successful native CLI response returns with usage info.
6277
+ * `contextTokens` is the end-of-turn per-request context size (see
6278
+ * AgentResponse.contextTokens); undefined on non-streaming paths.
5393
6279
  */
5394
6280
  recordTurnUsage(agentId: string, channel: string, chatId: string, usage: {
5395
6281
  inputTokens: number;
5396
6282
  outputTokens: number;
5397
6283
  cacheReadTokens: number;
5398
6284
  cacheCreateTokens: number;
5399
- }): void;
6285
+ }, contextTokens?: number): void;
6286
+ private rotationMemoFile;
6287
+ private readRotationMemos;
6288
+ setRotationMemo(agentId: string, channel: string, chatId: string, memo: string, reason: string): void;
6289
+ /** Latest memo for this chat, or null when absent/expired (7-day TTL). */
6290
+ getRotationMemo(agentId: string, channel: string, chatId: string): RotationMemoRecord | null;
5400
6291
  /** Diagnostic getters — used by registry logging. */
5401
6292
  getTurnCount(agentId: string, channel: string, chatId: string): number;
5402
6293
  getLastTurnInputTokens(agentId: string, channel: string, chatId: string): number;
6294
+ /** The rotation metric shouldRotateByTierTwo actually used: per-request
6295
+ * context size when available, else the cumulative fallback. */
6296
+ getLastTurnContextTokens(agentId: string, channel: string, chatId: string): number;
5403
6297
  getMaxTurnsPerSession(): number;
5404
6298
  getTierTwoThresholdTokens(): number;
5405
6299
  /**
@@ -6026,10 +6920,10 @@ declare const classificationSchema: z.ZodObject<{
6026
6920
  input?: string | undefined;
6027
6921
  };
6028
6922
  channel?: string | undefined;
6923
+ preview?: string | undefined;
6029
6924
  agentId?: string | undefined;
6030
6925
  sender?: string | undefined;
6031
6926
  confidence?: number | undefined;
6032
- preview?: string | undefined;
6033
6927
  }, {
6034
6928
  path: string[];
6035
6929
  status: "pending" | "approved" | "rejected";
@@ -6037,6 +6931,7 @@ declare const classificationSchema: z.ZodObject<{
6037
6931
  ts: string;
6038
6932
  msgHash: string;
6039
6933
  channel?: string | undefined;
6934
+ preview?: string | undefined;
6040
6935
  agentId?: string | undefined;
6041
6936
  sender?: string | undefined;
6042
6937
  proposedAxes?: Record<string, Record<string, string>> | undefined;
@@ -6045,7 +6940,6 @@ declare const classificationSchema: z.ZodObject<{
6045
6940
  input?: string | undefined;
6046
6941
  } | undefined;
6047
6942
  confidence?: number | undefined;
6048
- preview?: string | undefined;
6049
6943
  }>;
6050
6944
  type Classification = z.infer<typeof classificationSchema>;
6051
6945
  /** Row in the fingerprint → path snap cache. */
@@ -6065,16 +6959,16 @@ declare const fingerprintEntrySchema: z.ZodObject<{
6065
6959
  updatedAt: z.ZodString;
6066
6960
  }, "strip", z.ZodTypeAny, {
6067
6961
  path: string[];
6962
+ updatedAt: string;
6068
6963
  leaf: {
6069
6964
  output?: string | undefined;
6070
6965
  input?: string | undefined;
6071
6966
  };
6072
6967
  fingerprint: string;
6073
- updatedAt: string;
6074
6968
  }, {
6075
6969
  path: string[];
6076
- fingerprint: string;
6077
6970
  updatedAt: string;
6971
+ fingerprint: string;
6078
6972
  leaf?: {
6079
6973
  output?: string | undefined;
6080
6974
  input?: string | undefined;
@@ -6152,16 +7046,16 @@ declare const indexFileSchema: z.ZodObject<{
6152
7046
  updatedAt: z.ZodString;
6153
7047
  }, "strip", z.ZodTypeAny, {
6154
7048
  path: string[];
7049
+ updatedAt: string;
6155
7050
  leaf: {
6156
7051
  output?: string | undefined;
6157
7052
  input?: string | undefined;
6158
7053
  };
6159
7054
  fingerprint: string;
6160
- updatedAt: string;
6161
7055
  }, {
6162
7056
  path: string[];
6163
- fingerprint: string;
6164
7057
  updatedAt: string;
7058
+ fingerprint: string;
6165
7059
  leaf?: {
6166
7060
  output?: string | undefined;
6167
7061
  input?: string | undefined;
@@ -6170,19 +7064,19 @@ declare const indexFileSchema: z.ZodObject<{
6170
7064
  }, "strip", z.ZodTypeAny, {
6171
7065
  entries: Record<string, {
6172
7066
  path: string[];
7067
+ updatedAt: string;
6173
7068
  leaf: {
6174
7069
  output?: string | undefined;
6175
7070
  input?: string | undefined;
6176
7071
  };
6177
7072
  fingerprint: string;
6178
- updatedAt: string;
6179
7073
  }>;
6180
7074
  version: number;
6181
7075
  }, {
6182
7076
  entries?: Record<string, {
6183
7077
  path: string[];
6184
- fingerprint: string;
6185
7078
  updatedAt: string;
7079
+ fingerprint: string;
6186
7080
  leaf?: {
6187
7081
  output?: string | undefined;
6188
7082
  input?: string | undefined;
@@ -6478,6 +7372,13 @@ declare class AgentRegistry {
6478
7372
  * the requested agent before returning "Unknown agent". Duck-typed so
6479
7373
  * we don't create a circular import with src/a2a/mesh.ts. */
6480
7374
  private meshFallback?;
7375
+ /** Workflow auto-runner — invoked when workflow matching is in `mode: "auto"`
7376
+ * and a candidate workflow's confidence ≥ autoRunThreshold. Wired by the
7377
+ * daemon after the workflow dispatcher is constructed. Returns the runId of
7378
+ * the started workflow run; the workflow itself owns posting any reply via
7379
+ * its `action.send` / `agent` nodes. Duck-typed to avoid a circular import
7380
+ * on WorkflowDispatcher. */
7381
+ private workflowAutoRunner?;
6481
7382
  private messageQueue;
6482
7383
  /** Intent Knowledge Graph classifier. Null when graph.enabled=false. */
6483
7384
  private classifier?;
@@ -6488,6 +7389,15 @@ declare class AgentRegistry {
6488
7389
  private activeSouls;
6489
7390
  /** Live output captured per running task id — drives the dashboard streaming modal. */
6490
7391
  private taskOutputs;
7392
+ /** Per-running-task AbortController. Set when execution starts, removed in
7393
+ * finally. Cancel paths (operator stop / replace) call .abort() and the
7394
+ * runtime kills the underlying claude subprocess.
7395
+ *
7396
+ * `originalMessage` is the user text recorded in SessionStore at the start
7397
+ * of this run. When the operator presses Stop first then Update, we use it
7398
+ * to drop the orphan cancelled turn from history so the Update reads as an
7399
+ * edit, not a bare follow-up. */
7400
+ private taskAborts;
6491
7401
  /** Last completed task summary per agent — single-line blurb for the dashboard card. */
6492
7402
  private lastSummaries;
6493
7403
  /** 24-hour sparkline cache per agent — recomputed from disk at most once a minute. */
@@ -6507,6 +7417,10 @@ declare class AgentRegistry {
6507
7417
  * agent this node doesn't have. Called by the daemon after mesh boot.
6508
7418
  * Pass `undefined` to disable fallback (testing, mesh disabled). */
6509
7419
  setMeshFallback(mesh: NonNullable<AgentRegistry["meshFallback"]>): void;
7420
+ /** Wire the workflow auto-runner — see field doc above. Daemon calls this
7421
+ * after WorkflowDispatcher boot. Pass undefined to detach (e.g. during
7422
+ * reload). */
7423
+ setWorkflowAutoRunner(runner: NonNullable<AgentRegistry["workflowAutoRunner"]> | undefined): void;
6510
7424
  /** Hot-swap the provider map. Daemon reload calls this after agentx.json
6511
7425
  * changes — the next task that executes will resolve credentials through
6512
7426
  * the fresh table (see executeTask call-site). In-flight tasks keep the
@@ -6584,7 +7498,7 @@ declare class AgentRegistry {
6584
7498
  * this, every dispatched decision sits in-flight forever and the
6585
7499
  * active-task check becomes vacuously over-aggressive.
6586
7500
  */
6587
- execute(task: AgentTask, onDelta?: StreamCallback): Promise<AgentResponse>;
7501
+ execute(task: AgentTask, onDelta?: StreamCallback, onThinking?: ThinkingCallback, onEvent?: (event: any) => void): Promise<AgentResponse>;
6588
7502
  /**
6589
7503
  * Internal dispatcher — the real body. See `execute` for the public
6590
7504
  * wrapper that adds intent-ledger resolution recording.
@@ -6647,6 +7561,47 @@ declare class AgentRegistry {
6647
7561
  */
6648
7562
  getTaskRecord(agentId: string, taskId: string): TaskRecord | null;
6649
7563
  private safe;
7564
+ /**
7565
+ * Post a queued message's response back to its originating channel.
7566
+ * Used by the flush block in `execute()` — channel messages that arrive
7567
+ * while the agent is busy are queued and re-dispatched here, bypassing
7568
+ * the router; without this helper the agent's reply would never reach
7569
+ * the user. Skipped silently for internal channels (`test`, `api`,
7570
+ * `a2a`, `cron`, `workflow`, …) where no adapter is registered.
7571
+ */
7572
+ private postQueuedResponseToChannel;
7573
+ /**
7574
+ * Operator stop. Aborts the in-flight run for `taskId` (kills the
7575
+ * underlying claude subprocess via the AbortSignal threaded through
7576
+ * runtime.ts). Returns the task's identity for HTTP / audit callers,
7577
+ * or null when no live run matches.
7578
+ */
7579
+ cancelRunningTask(taskId: string, reason?: string): {
7580
+ agentId: string;
7581
+ channel: string;
7582
+ chatId: string;
7583
+ } | null;
7584
+ /**
7585
+ * Queue a follow-up correction/update for an in-flight task. The message
7586
+ * lands in the per-session MessageQueue and is dispatched after the
7587
+ * current run finishes — same path channel messages take while the agent
7588
+ * is busy. With `replace=true` we cancel the current run first so the
7589
+ * follow-up runs immediately.
7590
+ *
7591
+ * Returns the resolved identity + queue position, or null when no live
7592
+ * run matches taskId.
7593
+ */
7594
+ queueFollowUp(taskId: string, message: string, sender: string, opts?: {
7595
+ replace?: boolean;
7596
+ reason?: string;
7597
+ }): {
7598
+ agentId: string;
7599
+ channel: string;
7600
+ chatId: string;
7601
+ replaced: boolean;
7602
+ edited: boolean;
7603
+ pending: number;
7604
+ } | null;
6650
7605
  /**
6651
7606
  * Subscribe to live output for a running task. Returns the buffer that has
6652
7607
  * accumulated so far plus an unsubscribe handle. If the task is unknown,
@@ -7451,6 +8406,7 @@ declare class KPI {
7451
8406
  recordBlocker(agentId: string): void;
7452
8407
  private recomputeUtil;
7453
8408
  private persist;
8409
+ private writeStats;
7454
8410
  flush(): void;
7455
8411
  snapshot(): DailyStats;
7456
8412
  /** Markdown summary for end-of-day main-channel post. */
@@ -7552,6 +8508,12 @@ declare class MessageRouter {
7552
8508
  * file is pruned to only live TTL entries before each write.
7553
8509
  */
7554
8510
  private recentMessageIds;
8511
+ private activeMessageKeys;
8512
+ /** Outbound idempotency table — opt-in via sendOutbound(opts.idempotencyKey).
8513
+ * Key: `channel|chatId|hash-or-key`. Value: { postedAt epochMs, messageId }.
8514
+ * Bounded growth — coarse "drop oldest 10%" sweep when over the cap. */
8515
+ private sendDedupeMap;
8516
+ private readonly SEND_DEDUPE_MAX;
7555
8517
  private readonly MESSAGE_ID_TTL_MS;
7556
8518
  private readonly MESSAGE_ID_MAX_ENTRIES;
7557
8519
  private readonly DEDUP_STORE_PATH;
@@ -7593,9 +8555,24 @@ declare class MessageRouter {
7593
8555
  * Used for agent-initiated messages, cron notifications, cross-channel routing.
7594
8556
  *
7595
8557
  * If accountId is not provided for Telegram, auto-resolves from agentId binding.
8558
+ *
8559
+ * `opts.idempotencyKey` — when set, the router caches the (channel,chatId,key)
8560
+ * tuple for `dedupeWindowMs` (default 60s) and returns the cached messageId
8561
+ * for repeat calls within the window. The default key is a sha256 of the
8562
+ * body so an agent that re-runs the same `channel.reply` tool call doesn't
8563
+ * produce duplicate comments — the canonical fix for the raw-curl-twice
8564
+ * scenario diagnosed on MR #236 (2026-05-08).
8565
+ *
8566
+ * Why here and not in the adapter: the router is the single funnel for
8567
+ * agent + cron + API + cross-channel sends. Workflow `action.send` lives
8568
+ * at a different abstraction (explicit, scripted, retry semantics owned
8569
+ * by the engine) so it intentionally stays on the direct adapter path.
7596
8570
  */
7597
8571
  sendOutbound(msg: OutgoingMessage & {
7598
8572
  accountId?: string;
8573
+ }, opts?: {
8574
+ idempotencyKey?: string;
8575
+ dedupeWindowMs?: number;
7599
8576
  }): Promise<string | void>;
7600
8577
  /** List registered channel names. */
7601
8578
  getChannelNames(): string[];
@@ -7612,6 +8589,7 @@ declare class MessageRouter {
7612
8589
  * Stamps the key when false. Size-bounded GC avoids unbounded growth.
7613
8590
  */
7614
8591
  private isDuplicateMessage;
8592
+ private messageKey;
7615
8593
  /**
7616
8594
  * Phase 1 commit 6.b — record one router decision in the intent ledger
7617
8595
  * when the source is enabled (mode != "off"). Covers all router
@@ -7642,9 +8620,42 @@ declare class MessageRouter {
7642
8620
  * Works on Telegram (multi-account), WhatsApp (shared number), Discord.
7643
8621
  */
7644
8622
  private handleBotToBotChain;
8623
+ private sendDedupeKey;
8624
+ private sendDedupeGet;
8625
+ private sendDedupeStore;
7645
8626
  private adapterSend;
8627
+ /** Whether an agent may emit rich `agentx:ui` messages on this channel.
8628
+ * Gated by per-agent `richMessages` (default true) and restricted to the
8629
+ * interactive chat channels that render buttons/polls natively. */
8630
+ private richMessagesAllowed;
8631
+ /** Attach directive extras to a just-delivered reply: buttons onto the last
8632
+ * text message (edit reply_markup), poll + media as follow-up messages.
8633
+ * Best-effort — a failure here never breaks the text reply. */
8634
+ private attachUiExtras;
7646
8635
  private adapterEdit;
7647
8636
  private adapterReact;
8637
+ /**
8638
+ * Threads that have already been told about a mesh failure, keyed
8639
+ * `${channel}:${chatId}`. Cleared on the next success for that thread, so a
8640
+ * fresh outage notifies again but a burst inside one outage does not.
8641
+ */
8642
+ private meshFailureNotified;
8643
+ /**
8644
+ * A mesh-routed task failed. React ❌ (as the agent, where the channel
8645
+ * supports identity) and — the FIRST time this thread fails — post one
8646
+ * short comment saying so.
8647
+ *
8648
+ * Why a comment at all: this used to be ❌-only, on the reasoning that
8649
+ * transient failures would pollute the thread. In practice a reporter who
8650
+ * @-mentions a bot and gets 👀 then silence assumes the bot is ignoring
8651
+ * them and keeps re-pinging — on noqta/minbar#46 that was 9 mentions over
8652
+ * 74 minutes of upstream 529s, every one of them silently dropped. One
8653
+ * comment per outage is far cheaper than that. Nothing retries on its own,
8654
+ * so the text says plainly that a re-mention is what resumes it.
8655
+ */
8656
+ private notifyMeshFailure;
8657
+ /** A mesh-routed task succeeded — re-arm the failure notice for this thread. */
8658
+ private clearMeshFailure;
7648
8659
  private startTypingLoop;
7649
8660
  private traceRoute;
7650
8661
  private runRoutingPipeline;
@@ -7697,6 +8708,7 @@ declare class TelegramAdapter implements ChannelAdapter {
7697
8708
  * or its token changes, so its pollLoop observes the stop and exits without
7698
8709
  * affecting siblings. Keyed by accountId. */
7699
8710
  private accountPolling;
8711
+ private accountVerifyRetryTimers;
7700
8712
  private log;
7701
8713
  /** Global allowlist fallback. When a per-account allowFrom is unset,
7702
8714
  * this list applies. When BOTH are unset, everything is rejected
@@ -7721,6 +8733,7 @@ declare class TelegramAdapter implements ChannelAdapter {
7721
8733
  * the bot's identity, then spawns the long-poll loop. No-op if the account
7722
8734
  * is already polling. */
7723
8735
  private startAccount;
8736
+ private scheduleVerifyRetry;
7724
8737
  /** Stop a single account's poll loop without touching siblings. Flips the
7725
8738
  * per-account gate and aborts the in-flight long-poll so Telegram releases
7726
8739
  * the server-side session immediately (otherwise a new start with the same
@@ -7771,6 +8784,12 @@ declare class TelegramAdapter implements ChannelAdapter {
7771
8784
  send(msg: OutgoingMessage & {
7772
8785
  accountId?: string;
7773
8786
  }): Promise<string>;
8787
+ /** Add/replace inline URL buttons on an existing message (editMessageReplyMarkup).
8788
+ * Used to attach an agentx:ui button row to a streamed reply. Best-effort. */
8789
+ setMessageButtons(chatId: string, messageId: string, buttons: Array<{
8790
+ label: string;
8791
+ url: string;
8792
+ }>, accountId?: string): Promise<boolean>;
7774
8793
  /** Best-effort outbound shadow log. Captures every successful send into
7775
8794
  * the same per-chat shadow file the inbound writer uses, so seedHistory
7776
8795
  * + agent introspection see a complete picture (which bot identity sent
@@ -7796,6 +8815,12 @@ declare class TelegramAdapter implements ChannelAdapter {
7796
8815
  accountId?: string;
7797
8816
  parseMode?: "markdown" | "html" | "plain";
7798
8817
  }): Promise<string>;
8818
+ /** Build a Telegram inline_keyboard reply_markup from URL buttons (one row
8819
+ * per button). Shared by sendWithInlineButtons and send()'s `buttons`. */
8820
+ private inlineKeyboardMarkup;
8821
+ /** Send a single (already chunk-sized) message with optional reply_markup,
8822
+ * with the standard HTML→plain parse-mode fallback. Returns message id. */
8823
+ private sendOneWithMarkup;
7799
8824
  /**
7800
8825
  * Edit an existing message (for streaming updates).
7801
8826
  */
@@ -8227,4 +9252,4 @@ declare function handleError(error: unknown): void;
8227
9252
  */
8228
9253
  declare function getPackageInfo(): PackageJson;
8229
9254
 
8230
- export { A2AClient, A2AMesh, A2AServer, A2AServerConfig, ALL_TOOL_NAMES, AgentCard, AgentConfig, AgentContext, AgentDef, AgentProvider, AgentRegistry, AgentResponse, AgentTask, AgentXDaemon, AgentXRuntime, AnthropicMessage, AuthConfig, AxisDef, AxisType, BLOCKING_EVENTS, ChannelAdapter, Classification, ClassificationSource, ClassificationStatus, ClaudeCodeProvider, ClaudeProvider, ContentBlock, ContextBuilder, CronJobDef, CronJobState, CronRunResult, CronScheduler, DaemonConfig, EnhanceConfig, EnhanceEngine, EnhanceResult, FingerprintEntry, GenerateOptions, GenerateResult, GenerateStreamEvent, GeneratedFile, GenerationMessage, GenerationResult, GitCommitResult, GitDiffFile, GitLogEntry, GitManager, GitStatus, GraphNode, GraphSchema, GraphStore, GraphStoreOptions, HOOK_EVENTS, HealConfig, HealEngine, HealResult, HookContext, HookDefinition, HookEvent, HookHandler, HookRegistry, HookResult, IncomingMessage, IndexFile, LevelDef, Memory, MemoryEntry, MemoryHierarchy, MemoryStore$1 as MemoryStore, MeshPeer, MessageRouter, MiddlewareFn, ModelUsage, NodesFile, OUTPUT_CONFIGS, OUTPUT_TYPES, OutgoingMessage, OutputConfig, OutputType, PERMISSION_MODES, PROVIDER_CAPABILITIES, PermissionAction, PermissionConfig, PermissionManager, PermissionMode, PermissionRule, Pipeline, PipelineRequest, PipelineResponse, ProjectSchemas, ProviderCapabilities, ProviderName, ProviderOptions, RawGenerationResult, ReplEngine, ReplOptions, RuntimeConfig, STARTER_SCHEMA, Session$1 as Session, StepUsage, StreamEvent, Task, TaskArtifact, TaskMessage, TaskState, TaskStatusUpdate, TechStack, TelegramAdapter, ToolCallInput, ToolExecutor, ToolExecutorOptions, ToolResult, UsageSummary, UsageTracker, WhatsAppAdapter, WikiAccess, WikiArticle, WikiArticleMeta, WikiEntry, WikiIndex, WikiStore, agentConfigSchema$1 as agentConfigSchema, checkCapabilities, createAgentContext, createProvider, createSession, daemonConfigSchema, debug, detectSchemas, detectTechStack, ensureCredentials, executeClaudeCode, executeOrchestrator, executeSdk, executeTask, exportSession, formatSchemas, formatTechStack, formatToolsForSystemPrompt, gatherContext7Docs, generate, generateSkill, generateSkillMd, generateStream, getAnthropicTools, getCommand, getLegacyTools, getPackageInfo, globalHooks, globalPermissions, globalTracker, handleError, installSkillPackage, isCommand, isDebug, listInstalledSkills, listSessions, loadAuthConfig, loadDaemonConfig, loadHooks, loadLatestSession, loadLocalSkills, loadProjectInstructions, loadSession, logger, matchSkillsToTask, outputTypeDescriptions, parseCommand, parseSkillContent, parseSkillFile, permissionConfigSchema, permissionModeSchema, registerCommand, resolveAtImports, resolveOutputType, resolveToken, runModelSetup, saveAuthConfig, saveSession, setDebug, startMcpServer, validateWorkspaces };
9255
+ export { A2AClient, A2AMesh, A2AServer, A2AServerConfig, ALL_TOOL_NAMES, AgentCard, AgentConfig, AgentContext, AgentDef, AgentProvider, AgentRegistry, AgentResponse, AgentTask, AgentXDaemon, AgentXRuntime, AnthropicMessage, AuthConfig, AxisDef, AxisType, BLOCKING_EVENTS, ChannelAdapter, Classification, ClassificationSource, ClassificationStatus, ClaudeCodeProvider, ClaudeProvider, ContentBlock, ContextBuilder, CronJobDef, CronJobState, CronRunResult, CronScheduler, DaemonConfig, EnhanceConfig, EnhanceEngine, EnhanceResult, FingerprintEntry, GenerateOptions, GenerateResult, GenerateStreamEvent, GeneratedFile, GenerationMessage, GenerationResult, GitCommitResult, GitDiffFile, GitLogEntry, GitManager, GitStatus, GraphNode, GraphSchema, GraphStore, GraphStoreOptions, HOOK_EVENTS, HealConfig, HealEngine, HealResult, HookContext, HookDefinition, HookEvent, HookHandler, HookRegistry, HookResult, IncomingMessage, IndexFile, LevelDef, Memory, MemoryEntry, MemoryHierarchy, MemoryStore$1 as MemoryStore, MeshPeer, MessageRouter, MiddlewareFn, ModelUsage, NodesFile, OUTPUT_CONFIGS, OUTPUT_TYPES, OutgoingMessage, OutputConfig, OutputType, PERMISSION_MODES, PROVIDER_CAPABILITIES, PermissionAction, PermissionConfig, PermissionManager, PermissionMode, PermissionRule, Pipeline, PipelineRequest, PipelineResponse, ProjectSchemas, ProviderCapabilities, ProviderName, ProviderOptions, RawGenerationResult, ReplEngine, ReplOptions, RuntimeConfig, STARTER_SCHEMA, Session$1 as Session, StepUsage, StreamEvent, Task, TaskArtifact, TaskMessage, TaskState, TaskStatusUpdate, TechStack, TelegramAdapter, ToolCallInput, ToolExecutor, ToolExecutorOptions, ToolResult, UsageSummary, UsageTracker, WhatsAppAdapter, WikiAccess, WikiArticle, WikiArticleMeta, WikiEntry, WikiIndex, WikiStore, agentConfigSchema$1 as agentConfigSchema, checkCapabilities, createAgentContext, createProvider, createSession, daemonConfigSchema, debug, detectSchemas, detectTechStack, ensureCredentials, executeClaudeCode, executeOpenCodeCli, executeOrchestrator, executeSdk, executeTask, exportSession, formatSchemas, formatTechStack, formatToolsForSystemPrompt, gatherContext7Docs, generate, generateSkill, generateSkillMd, generateStream, getAnthropicTools, getCommand, getLegacyTools, getPackageInfo, globalHooks, globalPermissions, globalTracker, handleError, installSkillPackage, isCommand, isDebug, listInstalledSkills, listSessions, loadAuthConfig, loadDaemonConfig, loadHooks, loadLatestSession, loadLocalSkills, loadProjectInstructions, loadSession, logger, matchSkillsToTask, outputTypeDescriptions, parseCommand, parseSkillContent, parseSkillFile, permissionConfigSchema, permissionModeSchema, registerCommand, resolveAtImports, resolveOutputType, resolveToken, runModelSetup, saveAuthConfig, saveSession, setDebug, startMcpServer, validateWorkspaces };