agent-nuvira 3.3.7 → 3.3.9

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 (257) hide show
  1. package/README.md +57 -50
  2. package/dist/agents/agents/planner.d.ts.map +1 -1
  3. package/dist/agents/agents/planner.js +41 -0
  4. package/dist/agents/agents/planner.js.map +1 -1
  5. package/dist/agents/agents/reasoner.d.ts.map +1 -1
  6. package/dist/agents/agents/reasoner.js +6 -0
  7. package/dist/agents/agents/reasoner.js.map +1 -1
  8. package/dist/agents/agents/runner.d.ts +6 -0
  9. package/dist/agents/agents/runner.d.ts.map +1 -1
  10. package/dist/agents/agents/runner.js +82 -5
  11. package/dist/agents/agents/runner.js.map +1 -1
  12. package/dist/agents/agents/writer-tool-calling.d.ts.map +1 -1
  13. package/dist/agents/agents/writer-tool-calling.js +5 -2
  14. package/dist/agents/agents/writer-tool-calling.js.map +1 -1
  15. package/dist/agents/agents/writer.d.ts.map +1 -1
  16. package/dist/agents/agents/writer.js +8 -4
  17. package/dist/agents/agents/writer.js.map +1 -1
  18. package/dist/agents/fanout-scheduler.d.ts +72 -0
  19. package/dist/agents/fanout-scheduler.d.ts.map +1 -0
  20. package/dist/agents/fanout-scheduler.js +100 -0
  21. package/dist/agents/fanout-scheduler.js.map +1 -0
  22. package/dist/agents/orchestrator.d.ts.map +1 -1
  23. package/dist/agents/orchestrator.js +30 -1
  24. package/dist/agents/orchestrator.js.map +1 -1
  25. package/dist/agents/plan-quality.d.ts +58 -0
  26. package/dist/agents/plan-quality.d.ts.map +1 -0
  27. package/dist/agents/plan-quality.js +152 -0
  28. package/dist/agents/plan-quality.js.map +1 -0
  29. package/dist/agents/prompt-assembly.d.ts +8 -0
  30. package/dist/agents/prompt-assembly.d.ts.map +1 -1
  31. package/dist/agents/prompt-assembly.js +18 -0
  32. package/dist/agents/prompt-assembly.js.map +1 -1
  33. package/dist/agents/step-handoff.d.ts +12 -2
  34. package/dist/agents/step-handoff.d.ts.map +1 -1
  35. package/dist/agents/step-handoff.js +65 -8
  36. package/dist/agents/step-handoff.js.map +1 -1
  37. package/dist/agents/tool-calling-agent.d.ts.map +1 -1
  38. package/dist/agents/tool-calling-agent.js +18 -0
  39. package/dist/agents/tool-calling-agent.js.map +1 -1
  40. package/dist/cli/cache.d.ts.map +1 -1
  41. package/dist/cli/cache.js +34 -4
  42. package/dist/cli/cache.js.map +1 -1
  43. package/dist/cli/chat.d.ts +6 -0
  44. package/dist/cli/chat.d.ts.map +1 -1
  45. package/dist/cli/chat.js +79 -18
  46. package/dist/cli/chat.js.map +1 -1
  47. package/dist/cli/cli-program.d.ts.map +1 -1
  48. package/dist/cli/cli-program.js +6 -0
  49. package/dist/cli/cli-program.js.map +1 -1
  50. package/dist/cli/config.d.ts +10 -0
  51. package/dist/cli/config.d.ts.map +1 -1
  52. package/dist/cli/config.js +179 -1
  53. package/dist/cli/config.js.map +1 -1
  54. package/dist/cli/continuity.d.ts +61 -0
  55. package/dist/cli/continuity.d.ts.map +1 -0
  56. package/dist/cli/continuity.js +112 -0
  57. package/dist/cli/continuity.js.map +1 -0
  58. package/dist/cli/dashboard.d.ts +3 -1
  59. package/dist/cli/dashboard.d.ts.map +1 -1
  60. package/dist/cli/dashboard.js +5 -16
  61. package/dist/cli/dashboard.js.map +1 -1
  62. package/dist/cli/doctor.d.ts.map +1 -1
  63. package/dist/cli/doctor.js +48 -1
  64. package/dist/cli/doctor.js.map +1 -1
  65. package/dist/cli/execute.d.ts +8 -0
  66. package/dist/cli/execute.d.ts.map +1 -1
  67. package/dist/cli/execute.js +34 -1
  68. package/dist/cli/execute.js.map +1 -1
  69. package/dist/cli/loop-executor.d.ts +24 -0
  70. package/dist/cli/loop-executor.d.ts.map +1 -1
  71. package/dist/cli/loop-executor.js +134 -13
  72. package/dist/cli/loop-executor.js.map +1 -1
  73. package/dist/cli/website.d.ts +25 -0
  74. package/dist/cli/website.d.ts.map +1 -0
  75. package/dist/cli/website.js +58 -0
  76. package/dist/cli/website.js.map +1 -0
  77. package/dist/config/manager.d.ts.map +1 -1
  78. package/dist/config/manager.js +35 -0
  79. package/dist/config/manager.js.map +1 -1
  80. package/dist/config/process-env.d.ts.map +1 -1
  81. package/dist/config/process-env.js +20 -0
  82. package/dist/config/process-env.js.map +1 -1
  83. package/dist/config/provider-env.d.ts +2 -1
  84. package/dist/config/provider-env.d.ts.map +1 -1
  85. package/dist/config/provider-env.js +19 -2
  86. package/dist/config/provider-env.js.map +1 -1
  87. package/dist/config/service-catalog.d.ts +81 -0
  88. package/dist/config/service-catalog.d.ts.map +1 -0
  89. package/dist/config/service-catalog.js +286 -0
  90. package/dist/config/service-catalog.js.map +1 -0
  91. package/dist/config/service-probe.d.ts +27 -0
  92. package/dist/config/service-probe.d.ts.map +1 -0
  93. package/dist/config/service-probe.js +104 -0
  94. package/dist/config/service-probe.js.map +1 -0
  95. package/dist/config/types.d.ts +63 -0
  96. package/dist/config/types.d.ts.map +1 -1
  97. package/dist/context/cache.d.ts +46 -2
  98. package/dist/context/cache.d.ts.map +1 -1
  99. package/dist/context/cache.js +85 -7
  100. package/dist/context/cache.js.map +1 -1
  101. package/dist/findings/verdicts.d.ts +59 -0
  102. package/dist/findings/verdicts.d.ts.map +1 -1
  103. package/dist/findings/verdicts.js +117 -0
  104. package/dist/findings/verdicts.js.map +1 -1
  105. package/dist/forwarded.d.ts +2 -0
  106. package/dist/forwarded.d.ts.map +1 -0
  107. package/dist/forwarded.js +2 -0
  108. package/dist/forwarded.js.map +1 -0
  109. package/dist/gateway/registry.d.ts.map +1 -1
  110. package/dist/gateway/registry.js +9 -0
  111. package/dist/gateway/registry.js.map +1 -1
  112. package/dist/learning/auto-router.d.ts +30 -0
  113. package/dist/learning/auto-router.d.ts.map +1 -1
  114. package/dist/learning/auto-router.js +69 -12
  115. package/dist/learning/auto-router.js.map +1 -1
  116. package/dist/learning/context-assembly.d.ts +37 -0
  117. package/dist/learning/context-assembly.d.ts.map +1 -0
  118. package/dist/learning/context-assembly.js +63 -0
  119. package/dist/learning/context-assembly.js.map +1 -0
  120. package/dist/learning/reasoning-trace.d.ts +26 -5
  121. package/dist/learning/reasoning-trace.d.ts.map +1 -1
  122. package/dist/learning/reasoning-trace.js +21 -1
  123. package/dist/learning/reasoning-trace.js.map +1 -1
  124. package/dist/learning/session-digest.d.ts +78 -0
  125. package/dist/learning/session-digest.d.ts.map +1 -0
  126. package/dist/learning/session-digest.js +185 -0
  127. package/dist/learning/session-digest.js.map +1 -0
  128. package/dist/learning/session-recall.d.ts +135 -0
  129. package/dist/learning/session-recall.d.ts.map +1 -0
  130. package/dist/learning/session-recall.js +305 -0
  131. package/dist/learning/session-recall.js.map +1 -0
  132. package/dist/learning/session-store.d.ts +172 -0
  133. package/dist/learning/session-store.d.ts.map +1 -0
  134. package/dist/learning/session-store.js +424 -0
  135. package/dist/learning/session-store.js.map +1 -0
  136. package/dist/learning/step-checkpoint.d.ts +28 -0
  137. package/dist/learning/step-checkpoint.d.ts.map +1 -1
  138. package/dist/learning/step-checkpoint.js +90 -6
  139. package/dist/learning/step-checkpoint.js.map +1 -1
  140. package/dist/learning/working-state.d.ts +19 -0
  141. package/dist/learning/working-state.d.ts.map +1 -1
  142. package/dist/learning/working-state.js +34 -1
  143. package/dist/learning/working-state.js.map +1 -1
  144. package/dist/parity/drivers.d.ts.map +1 -1
  145. package/dist/parity/drivers.js +29 -0
  146. package/dist/parity/drivers.js.map +1 -1
  147. package/dist/parity/wire-fixtures.d.ts +88 -0
  148. package/dist/parity/wire-fixtures.d.ts.map +1 -0
  149. package/dist/parity/wire-fixtures.js +405 -0
  150. package/dist/parity/wire-fixtures.js.map +1 -0
  151. package/dist/tools/artifact-append.d.ts +23 -0
  152. package/dist/tools/artifact-append.d.ts.map +1 -1
  153. package/dist/tools/artifact-append.js +28 -0
  154. package/dist/tools/artifact-append.js.map +1 -1
  155. package/dist/tools/ask-user.d.ts +5 -0
  156. package/dist/tools/ask-user.d.ts.map +1 -1
  157. package/dist/tools/ask-user.js +51 -5
  158. package/dist/tools/ask-user.js.map +1 -1
  159. package/dist/tools/child-agent-entry.js +1 -0
  160. package/dist/tools/child-agent-entry.js.map +1 -1
  161. package/dist/tools/child-agent-runtime.d.ts +7 -0
  162. package/dist/tools/child-agent-runtime.d.ts.map +1 -1
  163. package/dist/tools/child-agent-runtime.js +116 -6
  164. package/dist/tools/child-agent-runtime.js.map +1 -1
  165. package/dist/tools/child-agent-worker.d.ts +15 -0
  166. package/dist/tools/child-agent-worker.d.ts.map +1 -0
  167. package/dist/tools/child-agent-worker.js.map +1 -0
  168. package/dist/tools/coding-tools.d.ts.map +1 -1
  169. package/dist/tools/coding-tools.js +11 -0
  170. package/dist/tools/coding-tools.js.map +1 -1
  171. package/dist/tools/finding-tool.d.ts +6 -1
  172. package/dist/tools/finding-tool.d.ts.map +1 -1
  173. package/dist/tools/finding-tool.js +15 -2
  174. package/dist/tools/finding-tool.js.map +1 -1
  175. package/dist/tools/followup-utils.d.ts +35 -0
  176. package/dist/tools/followup-utils.d.ts.map +1 -1
  177. package/dist/tools/followup-utils.js +36 -0
  178. package/dist/tools/followup-utils.js.map +1 -1
  179. package/dist/tools/loop-project-context.d.ts +4 -1
  180. package/dist/tools/loop-project-context.d.ts.map +1 -1
  181. package/dist/tools/loop-project-context.js +48 -1
  182. package/dist/tools/loop-project-context.js.map +1 -1
  183. package/dist/tools/loop-skill-hint.d.ts.map +1 -1
  184. package/dist/tools/loop-skill-hint.js +7 -0
  185. package/dist/tools/loop-skill-hint.js.map +1 -1
  186. package/dist/tools/modality/image-gen.d.ts +25 -6
  187. package/dist/tools/modality/image-gen.d.ts.map +1 -1
  188. package/dist/tools/modality/image-gen.js +46 -27
  189. package/dist/tools/modality/image-gen.js.map +1 -1
  190. package/dist/tools/modality/image-providers.d.ts +71 -0
  191. package/dist/tools/modality/image-providers.d.ts.map +1 -0
  192. package/dist/tools/modality/image-providers.js +277 -0
  193. package/dist/tools/modality/image-providers.js.map +1 -0
  194. package/dist/tools/registry.d.ts +10 -1
  195. package/dist/tools/registry.d.ts.map +1 -1
  196. package/dist/tools/registry.js +35 -8
  197. package/dist/tools/registry.js.map +1 -1
  198. package/dist/tools/run-cli.d.ts.map +1 -1
  199. package/dist/tools/run-cli.js +39 -1
  200. package/dist/tools/run-cli.js.map +1 -1
  201. package/dist/tools/run-terminal.d.ts.map +1 -1
  202. package/dist/tools/run-terminal.js +50 -6
  203. package/dist/tools/run-terminal.js.map +1 -1
  204. package/dist/tools/subagent-spawner.d.ts +8 -0
  205. package/dist/tools/subagent-spawner.d.ts.map +1 -1
  206. package/dist/tools/subagent-spawner.js +3 -0
  207. package/dist/tools/subagent-spawner.js.map +1 -1
  208. package/dist/tools/tool-loop.d.ts +55 -0
  209. package/dist/tools/tool-loop.d.ts.map +1 -1
  210. package/dist/tools/tool-loop.js +136 -0
  211. package/dist/tools/tool-loop.js.map +1 -1
  212. package/dist/tools/untrusted-content.d.ts +29 -0
  213. package/dist/tools/untrusted-content.d.ts.map +1 -0
  214. package/dist/tools/untrusted-content.js +53 -0
  215. package/dist/tools/untrusted-content.js.map +1 -0
  216. package/dist/tools/web-research.d.ts +76 -14
  217. package/dist/tools/web-research.d.ts.map +1 -1
  218. package/dist/tools/web-research.js +280 -35
  219. package/dist/tools/web-research.js.map +1 -1
  220. package/dist/utils/effect-verification.d.ts +115 -0
  221. package/dist/utils/effect-verification.d.ts.map +1 -0
  222. package/dist/utils/effect-verification.js +337 -0
  223. package/dist/utils/effect-verification.js.map +1 -0
  224. package/dist/utils/open-url.d.ts +16 -0
  225. package/dist/utils/open-url.d.ts.map +1 -0
  226. package/dist/utils/open-url.js +32 -0
  227. package/dist/utils/open-url.js.map +1 -0
  228. package/dist/utils/project-env.d.ts +146 -0
  229. package/dist/utils/project-env.d.ts.map +1 -0
  230. package/dist/utils/project-env.js +584 -0
  231. package/dist/utils/project-env.js.map +1 -0
  232. package/dist/utils/shell.d.ts +7 -0
  233. package/dist/utils/shell.d.ts.map +1 -1
  234. package/dist/utils/shell.js +2 -0
  235. package/dist/utils/shell.js.map +1 -1
  236. package/dist/web-dashboard/chat-console.d.ts +2 -0
  237. package/dist/web-dashboard/chat-console.d.ts.map +1 -1
  238. package/dist/web-dashboard/chat-console.js +7 -0
  239. package/dist/web-dashboard/chat-console.js.map +1 -1
  240. package/dist/web-dashboard/server.d.ts +3 -1
  241. package/dist/web-dashboard/server.d.ts.map +1 -1
  242. package/dist/web-dashboard/server.js +534 -8
  243. package/dist/web-dashboard/server.js.map +1 -1
  244. package/dist/web-dashboard/src/types.d.ts +150 -1
  245. package/dist/web-dashboard/src/types.d.ts.map +1 -1
  246. package/dist/web-dashboard/workspace-guard.d.ts +40 -0
  247. package/dist/web-dashboard/workspace-guard.d.ts.map +1 -0
  248. package/dist/web-dashboard/workspace-guard.js +92 -0
  249. package/dist/web-dashboard/workspace-guard.js.map +1 -0
  250. package/package.json +4 -1
  251. package/src/web-dashboard/public/assets/index-Beportyl.js +207 -0
  252. package/src/web-dashboard/public/assets/index-Beportyl.js.map +1 -0
  253. package/src/web-dashboard/public/assets/index-gtQyg9nm.css +1 -0
  254. package/src/web-dashboard/public/index.html +2 -2
  255. package/src/web-dashboard/public/assets/index-D1YFCcIZ.js +0 -207
  256. package/src/web-dashboard/public/assets/index-D1YFCcIZ.js.map +0 -1
  257. package/src/web-dashboard/public/assets/index-jkW5qcf-.css +0 -1
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Image-generation provider registry (`src/tools/modality/image-providers.ts`).
3
+ *
4
+ * The single source of truth for every backend `generate_image` can reach —
5
+ * mirroring the LLM `provider-catalog.ts` pattern so "add a provider" is data,
6
+ * not a code path. This is what makes BYOK real for images: a user who sets
7
+ * `GEMINI_API_KEY`, `OPENAI_API_KEY` or `STABILITY_API_KEY` gets that backend
8
+ * automatically; with nothing configured the free Pollinations endpoint runs.
9
+ *
10
+ * Selection (`resolveImageProvider`):
11
+ * 1. an explicit `provider` option / `modality.image.provider` config;
12
+ * 2. otherwise the first AVAILABLE provider in `IMAGE_PROVIDER_PRIORITY`
13
+ * (Gemini → OpenAI → Stability → local ComfyUI → Pollinations).
14
+ * A configured-but-failing backend falls back to Pollinations in `generate-image.ts`.
15
+ *
16
+ * Env vars are read dual-form (`NUVIRA_`/`BUFF_` prefixed OR plain) so both a
17
+ * bare `export GEMINI_API_KEY=…` and the nuvira-style override work.
18
+ */
19
+ export type ImageProviderId = 'gemini' | 'openai' | 'stability' | 'comfyui' | 'pollinations';
20
+ export interface ImageGenerationRequest {
21
+ prompt: string;
22
+ width: number;
23
+ height: number;
24
+ /** Model override (provider-specific). */
25
+ model?: string;
26
+ /** Explicit local endpoint (overrides the IMAGE_API_URL env). */
27
+ endpoint?: string;
28
+ }
29
+ export interface ImageGenerationResult {
30
+ bytes: Buffer;
31
+ /** File extension including the dot ('.png' | '.jpg'). */
32
+ ext: '.png' | '.jpg';
33
+ }
34
+ export interface ImageProvider {
35
+ id: ImageProviderId;
36
+ label: string;
37
+ /** Env vars that can supply the key (prefixed or plain; first set wins). */
38
+ keyEnvVars: string[];
39
+ /** Default model when none is configured. */
40
+ defaultModel: string;
41
+ /** Approximate USD per image (0 = free). */
42
+ costPerUnit: number;
43
+ /** Quality score 0–1 (used only for reporting/priority). */
44
+ quality: number;
45
+ /** True when this backend needs an API key / endpoint to run. */
46
+ requiresConfig: boolean;
47
+ /** Is the backend usable right now (key/endpoint present)? */
48
+ available(): boolean;
49
+ /** Generate the image bytes, or throw with a descriptive message. */
50
+ generate(req: ImageGenerationRequest): Promise<ImageGenerationResult>;
51
+ }
52
+ /** The local ComfyUI / Stable Diffusion endpoint, if configured. */
53
+ export declare function localImageEndpoint(): string | undefined;
54
+ /** The registry — single source of image-backend metadata + generation. */
55
+ export declare const IMAGE_PROVIDERS: Record<ImageProviderId, ImageProvider>;
56
+ /**
57
+ * Auto-selection order when nothing is configured explicitly. Cloud backends
58
+ * the user paid for outrank the local/free ones; Pollinations is always the
59
+ * last-resort fallback.
60
+ */
61
+ export declare const IMAGE_PROVIDER_PRIORITY: readonly ImageProviderId[];
62
+ /** Is the provider a known registry id? */
63
+ export declare function isImageProviderId(value: string | undefined): value is ImageProviderId;
64
+ /** Provider ids currently usable (for CLI/dashboard diagnostics). */
65
+ export declare function availableImageProviders(): ImageProviderId[];
66
+ /**
67
+ * Which backend will run. An explicit, known `provider` wins; else the first
68
+ * available provider in priority order; else Pollinations.
69
+ */
70
+ export declare function resolveImageProvider(requested?: string): ImageProviderId;
71
+ //# sourceMappingURL=image-providers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-providers.d.ts","sourceRoot":"","sources":["../../../src/tools/modality/image-providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,cAAc,CAAC;AAE7F,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,eAAe,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,6CAA6C;IAC7C,YAAY,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,cAAc,EAAE,OAAO,CAAC;IACxB,8DAA8D;IAC9D,SAAS,IAAI,OAAO,CAAC;IACrB,qEAAqE;IACrE,QAAQ,CAAC,GAAG,EAAE,sBAAsB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;CACvE;AAaD,oEAAoE;AACpE,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,SAAS,CAEvD;AAkID,2EAA2E;AAC3E,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,eAAe,EAAE,aAAa,CAwDlE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,eAAe,EAM7D,CAAC;AAIF,2CAA2C;AAC3C,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,IAAI,eAAe,CAErF;AAED,qEAAqE;AACrE,wBAAgB,uBAAuB,IAAI,eAAe,EAAE,CAE3D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,eAAe,CAMxE"}
@@ -0,0 +1,277 @@
1
+ /**
2
+ * Image-generation provider registry (`src/tools/modality/image-providers.ts`).
3
+ *
4
+ * The single source of truth for every backend `generate_image` can reach —
5
+ * mirroring the LLM `provider-catalog.ts` pattern so "add a provider" is data,
6
+ * not a code path. This is what makes BYOK real for images: a user who sets
7
+ * `GEMINI_API_KEY`, `OPENAI_API_KEY` or `STABILITY_API_KEY` gets that backend
8
+ * automatically; with nothing configured the free Pollinations endpoint runs.
9
+ *
10
+ * Selection (`resolveImageProvider`):
11
+ * 1. an explicit `provider` option / `modality.image.provider` config;
12
+ * 2. otherwise the first AVAILABLE provider in `IMAGE_PROVIDER_PRIORITY`
13
+ * (Gemini → OpenAI → Stability → local ComfyUI → Pollinations).
14
+ * A configured-but-failing backend falls back to Pollinations in `generate-image.ts`.
15
+ *
16
+ * Env vars are read dual-form (`NUVIRA_`/`BUFF_` prefixed OR plain) so both a
17
+ * bare `export GEMINI_API_KEY=…` and the nuvira-style override work.
18
+ */
19
+ import { envBuff } from '../../config/paths.js';
20
+ // ─── Env helpers ────────────────────────────────────────────────────────────
21
+ /** Read the first non-empty value among names (prefixed + plain). */
22
+ function keyFromEnv(names) {
23
+ for (const name of names) {
24
+ const value = (envBuff(name) ?? process.env[name])?.trim();
25
+ if (value)
26
+ return value;
27
+ }
28
+ return undefined;
29
+ }
30
+ /** The local ComfyUI / Stable Diffusion endpoint, if configured. */
31
+ export function localImageEndpoint() {
32
+ return envBuff('IMAGE_API_URL') || process.env.IMAGE_API_URL;
33
+ }
34
+ // ─── Provider implementations ───────────────────────────────────────────────
35
+ const POLLINATIONS_BASE = 'https://image.pollinations.ai/prompt/';
36
+ const GEMINI_BASE = 'https://generativelanguage.googleapis.com/v1beta/models';
37
+ /** Gemini / Imagen ("Nano Banana") image generation. */
38
+ async function geminiGenerate(req) {
39
+ const key = keyFromEnv(['GEMINI_API_KEY', 'GOOGLE_API_KEY']);
40
+ if (!key)
41
+ throw new Error('Gemini API key is not configured');
42
+ const model = req.model || 'gemini-2.5-flash-image';
43
+ if (/imagen/i.test(model)) {
44
+ // Imagen models use the :predict endpoint.
45
+ const res = await fetch(`${GEMINI_BASE}/${model}:predict?key=${encodeURIComponent(key)}`, {
46
+ method: 'POST',
47
+ headers: { 'content-type': 'application/json' },
48
+ body: JSON.stringify({ instances: [{ prompt: req.prompt }], parameters: { sampleCount: 1 } }),
49
+ });
50
+ if (!res.ok)
51
+ throw new Error(`Gemini Imagen HTTP ${res.status}`);
52
+ const data = (await res.json());
53
+ const pred = data.predictions?.[0];
54
+ if (!pred?.bytesBase64Encoded)
55
+ throw new Error('Gemini Imagen returned no image');
56
+ return { bytes: Buffer.from(pred.bytesBase64Encoded, 'base64'), ext: mimeToExt(pred.mimeType) };
57
+ }
58
+ // Gemini image models use :generateContent with IMAGE response modality.
59
+ const res = await fetch(`${GEMINI_BASE}/${model}:generateContent?key=${encodeURIComponent(key)}`, {
60
+ method: 'POST',
61
+ headers: { 'content-type': 'application/json' },
62
+ body: JSON.stringify({
63
+ contents: [{ parts: [{ text: req.prompt }] }],
64
+ generationConfig: { responseModalities: ['IMAGE'] },
65
+ }),
66
+ });
67
+ if (!res.ok)
68
+ throw new Error(`Gemini image HTTP ${res.status}`);
69
+ const data = (await res.json());
70
+ const parts = data.candidates?.[0]?.content?.parts ?? [];
71
+ const withImage = parts.find((p) => p.inlineData?.data || p.inline_data?.data);
72
+ const b64 = withImage?.inlineData?.data ?? withImage?.inline_data?.data;
73
+ if (!b64)
74
+ throw new Error('Gemini returned no image');
75
+ const mime = withImage?.inlineData?.mimeType ?? withImage?.inline_data?.mime_type;
76
+ return { bytes: Buffer.from(b64, 'base64'), ext: mimeToExt(mime) };
77
+ }
78
+ /** OpenAI image models: DALL·E (2/3) and gpt-image-1. */
79
+ async function openaiGenerate(req) {
80
+ const key = keyFromEnv(['OPENAI_API_KEY']);
81
+ if (!key)
82
+ throw new Error('OpenAI API key is not configured');
83
+ const model = req.model || 'gpt-image-1';
84
+ const body = { model, prompt: req.prompt, n: 1 };
85
+ // gpt-image-* always returns b64 and rejects response_format; dall-e-* needs it.
86
+ if (!/gpt-image/i.test(model))
87
+ body.response_format = 'b64_json';
88
+ const size = pickOpenAiSize(model, req.width, req.height);
89
+ if (size)
90
+ body.size = size;
91
+ const res = await fetch('https://api.openai.com/v1/images/generations', {
92
+ method: 'POST',
93
+ headers: { Authorization: `Bearer ${key}`, 'content-type': 'application/json' },
94
+ body: JSON.stringify(body),
95
+ });
96
+ if (!res.ok)
97
+ throw new Error(`OpenAI image HTTP ${res.status}`);
98
+ const data = (await res.json());
99
+ const first = data.data?.[0];
100
+ if (first?.b64_json)
101
+ return { bytes: Buffer.from(first.b64_json, 'base64'), ext: '.png' };
102
+ if (first?.url) {
103
+ const img = await fetch(first.url);
104
+ if (!img.ok)
105
+ throw new Error(`OpenAI image download HTTP ${img.status}`);
106
+ return { bytes: Buffer.from(await img.arrayBuffer()), ext: '.png' };
107
+ }
108
+ throw new Error('OpenAI returned no image');
109
+ }
110
+ /** Stability AI (Stable Image Core / SD3). */
111
+ async function stabilityGenerate(req) {
112
+ const key = keyFromEnv(['STABILITY_API_KEY']);
113
+ if (!key)
114
+ throw new Error('Stability API key is not configured');
115
+ const form = new FormData();
116
+ form.append('prompt', req.prompt);
117
+ form.append('output_format', 'png');
118
+ form.append('aspect_ratio', aspectRatio(req.width, req.height));
119
+ if (req.model)
120
+ form.append('model', req.model);
121
+ const res = await fetch('https://api.stability.ai/v2beta/stable-image/generate/core', {
122
+ method: 'POST',
123
+ headers: { Authorization: `Bearer ${key}`, Accept: 'image/*' },
124
+ body: form,
125
+ });
126
+ if (!res.ok)
127
+ throw new Error(`Stability HTTP ${res.status}`);
128
+ const contentType = res.headers.get('content-type') ?? '';
129
+ if (!contentType.startsWith('image/'))
130
+ throw new Error(`Stability returned ${contentType || 'a non-image response'}`);
131
+ const bytes = Buffer.from(await res.arrayBuffer());
132
+ if (bytes.length === 0)
133
+ throw new Error('Stability returned an empty image');
134
+ return { bytes, ext: contentType.includes('jpeg') ? '.jpg' : '.png' };
135
+ }
136
+ /** Local Stable Diffusion / ComfyUI — POST {prompt,width,height} → bytes. */
137
+ async function comfyuiGenerate(req) {
138
+ const url = req.endpoint ?? localImageEndpoint();
139
+ if (!url)
140
+ throw new Error('local image endpoint (BUFF_IMAGE_API_URL) is not configured');
141
+ const res = await fetch(url, {
142
+ method: 'POST',
143
+ headers: { 'content-type': 'application/json' },
144
+ body: JSON.stringify({ prompt: req.prompt, width: req.width, height: req.height }),
145
+ });
146
+ if (!res.ok)
147
+ throw new Error(`local backend HTTP ${res.status}`);
148
+ const contentType = res.headers.get('content-type') ?? '';
149
+ const bytes = Buffer.from(await res.arrayBuffer());
150
+ if (bytes.length === 0)
151
+ throw new Error('local backend returned an empty image');
152
+ return { bytes, ext: contentType.includes('jpeg') ? '.jpg' : '.png' };
153
+ }
154
+ /** Pollinations.ai — free, keyless, `{prompt}.png` with size params. */
155
+ async function pollinationsGenerate(req) {
156
+ const url = `${POLLINATIONS_BASE}${encodeURIComponent(req.prompt)}?width=${req.width}&height=${req.height}&nologo=true`;
157
+ const res = await fetch(url);
158
+ if (!res.ok)
159
+ throw new Error(`image fetch failed: HTTP ${res.status}`);
160
+ const bytes = Buffer.from(await res.arrayBuffer());
161
+ if (bytes.length === 0)
162
+ throw new Error('image fetch returned empty body');
163
+ return { bytes, ext: '.png' };
164
+ }
165
+ // ─── Catalog ────────────────────────────────────────────────────────────────
166
+ /** The registry — single source of image-backend metadata + generation. */
167
+ export const IMAGE_PROVIDERS = {
168
+ gemini: {
169
+ id: 'gemini',
170
+ label: 'Google Gemini / Imagen (Nano Banana)',
171
+ keyEnvVars: ['GEMINI_API_KEY', 'GOOGLE_API_KEY'],
172
+ defaultModel: 'gemini-2.5-flash-image',
173
+ costPerUnit: 0.039,
174
+ quality: 0.9,
175
+ requiresConfig: true,
176
+ available: () => Boolean(keyFromEnv(['GEMINI_API_KEY', 'GOOGLE_API_KEY'])),
177
+ generate: geminiGenerate,
178
+ },
179
+ openai: {
180
+ id: 'openai',
181
+ label: 'OpenAI (DALL·E / gpt-image)',
182
+ keyEnvVars: ['OPENAI_API_KEY'],
183
+ defaultModel: 'gpt-image-1',
184
+ costPerUnit: 0.04,
185
+ quality: 0.95,
186
+ requiresConfig: true,
187
+ available: () => Boolean(keyFromEnv(['OPENAI_API_KEY'])),
188
+ generate: openaiGenerate,
189
+ },
190
+ stability: {
191
+ id: 'stability',
192
+ label: 'Stability AI',
193
+ keyEnvVars: ['STABILITY_API_KEY'],
194
+ defaultModel: 'stable-image-core',
195
+ costPerUnit: 0.002,
196
+ quality: 0.85,
197
+ requiresConfig: true,
198
+ available: () => Boolean(keyFromEnv(['STABILITY_API_KEY'])),
199
+ generate: stabilityGenerate,
200
+ },
201
+ comfyui: {
202
+ id: 'comfyui',
203
+ label: 'Local ComfyUI / Stable Diffusion',
204
+ keyEnvVars: [],
205
+ defaultModel: 'local',
206
+ costPerUnit: 0,
207
+ quality: 0.9,
208
+ requiresConfig: true,
209
+ available: () => Boolean(localImageEndpoint()),
210
+ generate: comfyuiGenerate,
211
+ },
212
+ pollinations: {
213
+ id: 'pollinations',
214
+ label: 'Pollinations.ai (free)',
215
+ keyEnvVars: [],
216
+ defaultModel: 'pollinations',
217
+ costPerUnit: 0,
218
+ quality: 0.7,
219
+ requiresConfig: false,
220
+ available: () => true,
221
+ generate: pollinationsGenerate,
222
+ },
223
+ };
224
+ /**
225
+ * Auto-selection order when nothing is configured explicitly. Cloud backends
226
+ * the user paid for outrank the local/free ones; Pollinations is always the
227
+ * last-resort fallback.
228
+ */
229
+ export const IMAGE_PROVIDER_PRIORITY = [
230
+ 'gemini',
231
+ 'openai',
232
+ 'stability',
233
+ 'comfyui',
234
+ 'pollinations',
235
+ ];
236
+ // ─── Selection ──────────────────────────────────────────────────────────────
237
+ /** Is the provider a known registry id? */
238
+ export function isImageProviderId(value) {
239
+ return Boolean(value && Object.prototype.hasOwnProperty.call(IMAGE_PROVIDERS, value));
240
+ }
241
+ /** Provider ids currently usable (for CLI/dashboard diagnostics). */
242
+ export function availableImageProviders() {
243
+ return IMAGE_PROVIDER_PRIORITY.filter((id) => IMAGE_PROVIDERS[id].available());
244
+ }
245
+ /**
246
+ * Which backend will run. An explicit, known `provider` wins; else the first
247
+ * available provider in priority order; else Pollinations.
248
+ */
249
+ export function resolveImageProvider(requested) {
250
+ if (isImageProviderId(requested))
251
+ return requested;
252
+ for (const id of IMAGE_PROVIDER_PRIORITY) {
253
+ if (IMAGE_PROVIDERS[id].available())
254
+ return id;
255
+ }
256
+ return 'pollinations';
257
+ }
258
+ // ─── Small helpers ──────────────────────────────────────────────────────────
259
+ function mimeToExt(mime) {
260
+ return (mime ?? '').includes('jpeg') || (mime ?? '').includes('jpg') ? '.jpg' : '.png';
261
+ }
262
+ /** Pick a size string OpenAI accepts for the given model. */
263
+ function pickOpenAiSize(model, width, height) {
264
+ const gpt = /gpt-image/i.test(model);
265
+ if (width === height)
266
+ return '1024x1024';
267
+ if (gpt)
268
+ return width > height ? '1536x1024' : '1024x1536';
269
+ return width > height ? '1792x1024' : '1024x1792';
270
+ }
271
+ /** Stability wants an aspect ratio, not pixel dimensions. */
272
+ function aspectRatio(width, height) {
273
+ if (width === height)
274
+ return '1:1';
275
+ return width > height ? '16:9' : '9:16';
276
+ }
277
+ //# sourceMappingURL=image-providers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-providers.js","sourceRoot":"","sources":["../../../src/tools/modality/image-providers.ts"],"names":[],"mappings":"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"}
@@ -215,6 +215,15 @@ export interface ToolContext {
215
215
  * (tests, non-tiered callers) simply never extend the schema set.
216
216
  */
217
217
  loadedExtraTools?: Set<string>;
218
+ /**
219
+ * The actions this turn actually PERFORMED, as the loop observed them
220
+ * (successes and failures alike), appended per tool call. Gives a tool that
221
+ * reports a claim the reality its own prose cannot be: `finding` uses it to
222
+ * refuse a CONFIRMED verdict built on a command or path that never happened
223
+ * (see `enforceEvidenceProvenance` in `src/findings/verdicts.ts`). Optional —
224
+ * a direct call or a bare test context simply skips the provenance check.
225
+ */
226
+ executedActions?: import('../findings/verdicts.js').ExecutedAction[];
218
227
  }
219
228
  /** A clarify-style choice. */
220
229
  export interface AskUserChoice {
@@ -384,5 +393,5 @@ export declare const TOOL_CONTRACT_JSON = "You have tools available. Call them w
384
393
  * unparseable or schema-invalid (callers fall back to rule-based suggestions).
385
394
  */
386
395
  export declare function toFollowupSuggestions(raw: string): FollowupSuggestion[];
387
- export { MAX_FOLLOWUPS, MAX_FOLLOWUP_PROMPT_CHARS, MAX_FOLLOWUP_LABEL_CHARS, normalizeFollowups, FOLLOWUP_CONTINUATION_MARKER, buildFollowupContinuationPrompt, isFollowupContinuation, isSuggestedFollowup, } from './followup-utils.js';
396
+ export { MAX_FOLLOWUPS, MAX_FOLLOWUP_PROMPT_CHARS, MAX_FOLLOWUP_LABEL_CHARS, normalizeFollowups, FOLLOWUP_CONTINUATION_MARKER, buildFollowupContinuationPrompt, isFollowupContinuation, isSuggestedFollowup, withContinuationFollowups, CONTINUE_PROMPT, RETRY_PROMPT, } from './followup-utils.js';
388
397
  //# sourceMappingURL=registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"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"}
@@ -28,6 +28,7 @@ import { z, toJSONSchema } from 'zod';
28
28
  import { ACTION_BY_INTENT } from '../nlu/actions.js';
29
29
  import { detectPermissionSeeking, IRREVERSIBLE_ACTION_RE } from '../learning/autonomy-policy.js';
30
30
  import { createFindingTool } from './finding-tool.js';
31
+ import { recordArtifact } from './artifact-append.js';
31
32
  // ─── Tool definitions ───────────────────────────────────────────────────────
32
33
  // ─── Shared auto-delivery helper ─────────────────────────────────────────
33
34
  // Tools that produce artifact files (generate_image, speak, video_generate)
@@ -221,11 +222,15 @@ const browserSchema = z.object({
221
222
  text: z.string().optional().describe('Text to type (action=type)'),
222
223
  timeout_ms: z.number().int().min(500).max(120000).default(15000).optional().describe('Navigation/timeout in ms'),
223
224
  });
224
- /** I3 — generate_image tool args: free image generation. */
225
+ /** I3 — generate_image tool args: bring-your-own-key image generation. */
225
226
  const imageGenSchema = z.object({
226
227
  prompt: z.string().min(1).describe('The image description'),
227
228
  width: z.number().int().min(64).max(2048).default(1024).optional().describe('Image width (default 1024)'),
228
229
  height: z.number().int().min(64).max(2048).default(1024).optional().describe('Image height (default 1024)'),
230
+ provider: z
231
+ .enum(['gemini', 'openai', 'stability', 'comfyui', 'pollinations'])
232
+ .optional()
233
+ .describe('Optional backend override: gemini (Imagen/Nano Banana), openai (DALL-E/gpt-image), stability, comfyui (local), or pollinations (free). Defaults to the first backend whose API key is configured.'),
229
234
  });
230
235
  /** I4 — voice tools: TTS + transcription (optional installs). */
231
236
  const speakSchema = z.object({
@@ -475,7 +480,7 @@ registerTool({
475
480
  });
476
481
  registerTool({
477
482
  name: 'ask_user',
478
- description: 'Ask the user a clarifying question with 2–4 choices (multi-select optional). Use when a request is ambiguous or missing information.',
483
+ description: 'Ask the user a clarifying question with 2–4 choices (multi-select optional). Every surface also offers the user a free-text "Other" answer, so a reply may be their own words instead of one of your choices. Use when a request is ambiguous or missing information.',
479
484
  category: 'experience',
480
485
  inputSchema: askUserSchema,
481
486
  // NOT a dispenser: the tool result is the user's ANSWER, which the model
@@ -711,16 +716,19 @@ registerTool(createFindingTool());
711
716
  // `src/tools/web-research.ts` (mocked-fetch tests, no network).
712
717
  registerTool({
713
718
  name: 'web_search',
714
- description: 'Search the web for a query, returning title/url/snippet hits (DuckDuckGo free tier or a configured SearXNG). Use to ground answers in current information.',
719
+ description: 'Search the web for a query, returning title/url/snippet hits. Uses the first available backend: a configured Brave/Serper/Tavily/Google-CSE key, a self-hosted SearXNG, or the keyless DuckDuckGo fallback. Set the backend with `tools.toolsets.web.provider` or an API-key env var. Use to ground answers in current information.',
715
720
  category: 'workflow',
716
721
  inputSchema: webSearchSchema,
717
722
  endsAgentStep: false,
718
- run: async (args) => {
723
+ run: async (args, ctx) => {
719
724
  const { query, max_results } = webSearchSchema.parse(args);
720
725
  const { searchWeb } = await import('./web-research.js');
721
- // Self-hosted SearXNG opt-in via env (free/OSS); unset → DuckDuckGo.
726
+ // Backend selection: an explicit `tools.toolsets.web.provider` wins, else
727
+ // the first backend with a configured key (Brave/Serper/Tavily/Google CSE),
728
+ // else SearXNG, else the keyless DuckDuckGo default.
722
729
  const searxngUrl = envBuff('SEARXNG_URL');
723
- const results = await searchWeb(query, { maxResults: max_results, searxngUrl });
730
+ const provider = ctx?.configManager?.getAll?.()?.tools?.toolsets?.web?.provider;
731
+ const results = await searchWeb(query, { maxResults: max_results, searxngUrl, provider });
724
732
  if (results.length === 0) {
725
733
  return `web_search: no results for "${query}" (backend unavailable or network error).`;
726
734
  }
@@ -764,7 +772,7 @@ registerTool({
764
772
  });
765
773
  registerTool({
766
774
  name: 'generate_image',
767
- description: 'Generate an image from a text prompt (Pollinations.ai free endpoint, or a local Stable Diffusion/ComfyUI via BUFF_IMAGE_API_URL). The image is saved to the sandbox images/ dir and the path is returned. When running in a gateway context (WhatsApp/Telegram/etc.), the image is automatically sent back to the originating channel.',
775
+ description: 'Generate an image from a text prompt using a bring-your-own-key backend: Google Gemini/Imagen (GEMINI_API_KEY), OpenAI DALL-E/gpt-image (OPENAI_API_KEY), Stability AI (STABILITY_API_KEY), a local ComfyUI/Stable Diffusion (BUFF_IMAGE_API_URL), or the free keyless Pollinations.ai fallback. The first backend whose key is configured wins (override with `modality.image.provider`), and a failing backend falls back to Pollinations. The image is saved to the sandbox images/ dir and the path is returned. When running in a gateway context (WhatsApp/Telegram/etc.), the image is automatically sent back to the originating channel.',
768
776
  category: 'workflow',
769
777
  inputSchema: imageGenSchema,
770
778
  endsAgentStep: false,
@@ -773,14 +781,27 @@ registerTool({
773
781
  const { generateImage, isImageGenAvailable } = await import('./modality/image-gen.js');
774
782
  if (!isImageGenAvailable())
775
783
  return 'generate_image: unavailable (no image backend configured).';
784
+ // Config (`modality.image.*`) supplies the default backend/model; an
785
+ // explicit tool arg overrides it.
786
+ const modality = ctx?.configManager?.getAll?.()?.modality?.image ?? {};
776
787
  const result = await generateImage(parsed.prompt, {
777
788
  width: parsed.width,
778
789
  height: parsed.height,
779
790
  apiUrl: envBuff('IMAGE_API_URL'),
791
+ provider: parsed.provider ?? modality.provider,
792
+ model: modality.model,
780
793
  });
781
794
  if (!result.ok)
782
795
  return `generate_image: failed — ${result.error}`;
783
796
  const file = result.file;
797
+ // I3 — the generated image is a deliverable: register it so the dashboard's
798
+ // Artifacts tab can show (and re-open) what this turn produced.
799
+ recordArtifact(ctx?.artifacts, {
800
+ kind: 'media',
801
+ title: `image: ${parsed.prompt.slice(0, 60)}`,
802
+ path: file,
803
+ mime: 'image/png',
804
+ });
784
805
  const delivered = await tryAutoDeliver(file, parsed.prompt, ctx, 'image');
785
806
  return `generate_image: saved to ${file}${delivered}`;
786
807
  },
@@ -798,6 +819,12 @@ registerTool({
798
819
  if (!result.ok)
799
820
  return `speak: failed — ${result.error}`;
800
821
  const file = result.file;
822
+ recordArtifact(ctx?.artifacts, {
823
+ kind: 'media',
824
+ title: `speech: ${parsed.text.slice(0, 60)}`,
825
+ path: file,
826
+ mime: 'audio/mpeg',
827
+ });
801
828
  const delivered = await tryAutoDeliver(file, parsed.text, ctx, 'audio');
802
829
  return `speak: saved to ${file}${delivered}`;
803
830
  },
@@ -976,7 +1003,7 @@ export function toFollowupSuggestions(raw) {
976
1003
  // and dashboard must be able to normalise a followup (and recognise a clicked
977
1004
  // one) WITHOUT pulling the whole 110-tool registry into their import graph —
978
1005
  // doing so measurably slowed those hot paths.
979
- export { MAX_FOLLOWUPS, MAX_FOLLOWUP_PROMPT_CHARS, MAX_FOLLOWUP_LABEL_CHARS, normalizeFollowups, FOLLOWUP_CONTINUATION_MARKER, buildFollowupContinuationPrompt, isFollowupContinuation, isSuggestedFollowup, } from './followup-utils.js';
1006
+ export { MAX_FOLLOWUPS, MAX_FOLLOWUP_PROMPT_CHARS, MAX_FOLLOWUP_LABEL_CHARS, normalizeFollowups, FOLLOWUP_CONTINUATION_MARKER, buildFollowupContinuationPrompt, isFollowupContinuation, isSuggestedFollowup, withContinuationFollowups, CONTINUE_PROMPT, RETRY_PROMPT, } from './followup-utils.js';
980
1007
  // ─── Tool run implementations (deferred imports to avoid cycles) ────────────
981
1008
  /** Run a C3 pipeline action (build/resume/repair + E3c task tools) — see executor.ts. */
982
1009
  function runPipelineTool(action, args, ctx) {