bazilion 0.21.0 → 0.22.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 (101) hide show
  1. package/dist/cli.js +25 -6
  2. package/dist/cli.js.map +1 -1
  3. package/dist/daemon.js +1046 -152
  4. package/dist/daemon.js.map +1 -1
  5. package/dist/migrations/0004_image_generation.sql +25 -0
  6. package/dist/web/client/assets/{AgentTabs-BT7RsEUU.js → AgentTabs-CBFT1Qg2.js} +1 -1
  7. package/dist/web/client/assets/{ChatPane-3I0Vsgz1.js → ChatPane-2r2r-Ac6.js} +2 -2
  8. package/dist/web/client/assets/{ConfigPage-hftJBBIY.js → ConfigPage-Cv0KGMX2.js} +1 -1
  9. package/dist/web/client/assets/{ConfirmDialog-gjgxRmxG.js → ConfirmDialog-DEwIcBm4.js} +1 -1
  10. package/dist/web/client/assets/FieldRow-C2ZAwThs.js +1 -0
  11. package/dist/web/client/assets/{ProductionTeamPolicyEditor-D4WcyDGX.js → ProductionTeamPolicyEditor-CziOzJPc.js} +1 -1
  12. package/dist/web/client/assets/{ProfileCommunicationEditor-CgIyV1rY.js → ProfileCommunicationEditor-DRasiT4-.js} +1 -1
  13. package/dist/web/client/assets/{RecoveryState-CbuT_rGW.js → RecoveryState-BZVq08km.js} +1 -1
  14. package/dist/web/client/assets/ResultCard-Dv5E8nX2.js +1 -0
  15. package/dist/web/client/assets/{ResultSourceConversation-CYBczpnZ.js → ResultSourceConversation-DutMGQB2.js} +1 -1
  16. package/dist/web/client/assets/{SectionTabs-t8xkqWIa.js → SectionTabs-mrflsPU-.js} +1 -1
  17. package/dist/web/client/assets/{TeamTabs-BN6P91fO.js → TeamTabs-DMVP5Hce.js} +1 -1
  18. package/dist/web/client/assets/{TemplatesTabs-DwG1CWan.js → TemplatesTabs-PxjxEiJG.js} +1 -1
  19. package/dist/web/client/assets/{UnsavedChangesGuard-fTPP7TCu.js → UnsavedChangesGuard-DfuiWMQ_.js} +1 -1
  20. package/dist/web/client/assets/{_id-Bcqu2cAS.js → _id-AcER9d-z.js} +1 -1
  21. package/dist/web/client/assets/{_id-CZG5wnur.js → _id-BTqFkUlB.js} +1 -1
  22. package/dist/web/client/assets/{_id-Bqk9L9xm.js → _id-Btgd0eQD.js} +1 -1
  23. package/dist/web/client/assets/{_id-DbwNJKQ8.js → _id-CgRuUtaW.js} +1 -1
  24. package/dist/web/client/assets/{_id-Di_SGuwC.js → _id-CrshYgbI.js} +1 -1
  25. package/dist/web/client/assets/{_id-DoW8SZjQ.js → _id-D51zCmQL.js} +1 -1
  26. package/dist/web/client/assets/{_id-DYkghdJm.js → _id-DqfO8lgv.js} +1 -1
  27. package/dist/web/client/assets/{_id-CRG3gXZW.js → _id-danxFImG.js} +1 -1
  28. package/dist/web/client/assets/{activity-vP2HVz4C.js → activity-CMaTYBPw.js} +1 -1
  29. package/dist/web/client/assets/{activity-Bt9WrtwT.js → activity-TilqK2MN.js} +1 -1
  30. package/dist/web/client/assets/{agents-gvU7Aqby.js → agents-D2gE-ZHl.js} +1 -1
  31. package/dist/web/client/assets/{agents-Bo7EfRdf.js → agents-D5_60Do4.js} +1 -1
  32. package/dist/web/client/assets/{agents-DaNXwDyg.js → agents-DPFzFgU2.js} +1 -1
  33. package/dist/web/client/assets/{approvals-DmJ5zwtE.js → approvals-BfoaMnwC.js} +1 -1
  34. package/dist/web/client/assets/{approvals-BOJoboDp.js → approvals-Du7G-YHg.js} +1 -1
  35. package/dist/web/client/assets/{attention-yEG75DvH.js → attention-C11m4NJY.js} +1 -1
  36. package/dist/web/client/assets/{attention-DWPCjYsx.js → attention-Cv18TBIb.js} +1 -1
  37. package/dist/web/client/assets/chevron-right-WaxL25XX.js +1 -0
  38. package/dist/web/client/assets/{config-B8YR3RWJ.js → config-crruyOmj.js} +2 -2
  39. package/dist/web/client/assets/{context-Cqc6E2UY.js → context-JT1dYNoO.js} +1 -1
  40. package/dist/web/client/assets/{inbox-PEvgddwX.js → inbox-DC5XSXiy.js} +1 -1
  41. package/dist/web/client/assets/{inbox-C2B8Re-f.js → inbox-OQ0QyvzA.js} +1 -1
  42. package/dist/web/client/assets/{index-CK_tkx73.js → index-DThtB1z2.js} +2 -2
  43. package/dist/web/client/assets/{learning-C8u7s_fv.js → learning-CeMSJbAY.js} +1 -1
  44. package/dist/web/client/assets/{learning-CTOIJfXI.js → learning-MO7fDBpd.js} +1 -1
  45. package/dist/web/client/assets/{login-32oN5__g.js → login-B1mPI9h5.js} +1 -1
  46. package/dist/web/client/assets/{mcp-BatNZnwC.js → mcp-Bo-E-MdF.js} +1 -1
  47. package/dist/web/client/assets/{mcp-CMdrj5RZ.js → mcp-CmzHMhei.js} +1 -1
  48. package/dist/web/client/assets/{members-CIVp1pgE.js → members-C7bazwZU.js} +1 -1
  49. package/dist/web/client/assets/{members-CdL5g4oy.js → members-sxSJCxkS.js} +1 -1
  50. package/dist/web/client/assets/{memory-DB2R5Zna.js → memory-BiBOuBA1.js} +1 -1
  51. package/dist/web/client/assets/{memory-kGfkKaO9.js → memory-VYCztjts.js} +1 -1
  52. package/dist/web/client/assets/{policy-D6mIMw1q.js → policy-C8SKHMJc.js} +1 -1
  53. package/dist/web/client/assets/{policy-3wgqPeNP.js → policy-CxN-ZrEm.js} +1 -1
  54. package/dist/web/client/assets/{results-Bt-h8qZH.js → results-BI_dzjgu.js} +1 -1
  55. package/dist/web/client/assets/{results-DNv3ByLD.js → results-DnrL5Mvt.js} +1 -1
  56. package/dist/web/client/assets/{review-CT9N-mCa.js → review-CtGjuoBA.js} +1 -1
  57. package/dist/web/client/assets/{review-NchTcTNb.js → review-D_F2VNul.js} +1 -1
  58. package/dist/web/client/assets/{routes-Dsbob2Ux.js → routes-CLcJb0Gu.js} +1 -1
  59. package/dist/web/client/assets/{services-BRUdbA_y.js → services-Ca1LbXwW.js} +1 -1
  60. package/dist/web/client/assets/{services-CkInaMBQ.js → services-D3rWjxvT.js} +1 -1
  61. package/dist/web/client/assets/{skills-By2Mztj4.js → skills-CbaN9DoR.js} +1 -1
  62. package/dist/web/client/assets/{skills-BYlQVmk4.js → skills-xLrt1IKk.js} +1 -1
  63. package/dist/web/client/assets/{teams-Ckkao-PS.js → teams-DagnWLAA.js} +1 -1
  64. package/dist/web/client/assets/{teams-CVAt-A9j.js → teams-DwSzsbr8.js} +1 -1
  65. package/dist/web/client/assets/{teams--rX4Emqg.js → teams-WVfQMDzi.js} +1 -1
  66. package/dist/web/client/assets/{teams-DokMjbwf.js → teams-tpI7S4u0.js} +1 -1
  67. package/dist/web/client/assets/{telegram-HbT_i0ez.js → telegram-hnIzZf3m.js} +1 -1
  68. package/dist/web/client/assets/{templates-ChE1fd0Z.js → templates-dmFNbHkN.js} +1 -1
  69. package/dist/web/client/assets/{tokens-BV8ipZCW.js → tokens-DMbCr1_1.js} +1 -1
  70. package/dist/web/client/assets/{tokens-CBjv3oax.js → tokens-DUx-zUYt.js} +1 -1
  71. package/dist/web/client/assets/{triggers-BhpXkk_u.js → triggers-BwjNuh-V.js} +1 -1
  72. package/dist/web/client/assets/{triggers-Fe-XQRpk.js → triggers-CM4j23G4.js} +1 -1
  73. package/dist/web/client/assets/{verifications-CPV9gl2d.js → verifications-DGVTf-_3.js} +1 -1
  74. package/dist/web/client/assets/{verifications-CRrwQEXg.js → verifications-bgpZuwOC.js} +1 -1
  75. package/dist/web/client/assets/{welcome-DD_q6paM.js → welcome-p8_5r05g.js} +1 -1
  76. package/dist/web/client/assets/{x-DHrC-Hx0.js → x-CGJA1SM6.js} +1 -1
  77. package/dist/web/server/assets/{ChatPane-CLUUTi2r.js → ChatPane-DsDa1E0a.js} +3 -3
  78. package/dist/web/server/assets/{FieldRow-BEFxeckR.js → FieldRow-DPO8x_le.js} +21 -1
  79. package/dist/web/server/assets/{ResultCard-CFjh8884.js → ResultCard-BtVFqdRU.js} +20 -1
  80. package/dist/web/server/assets/{ResultSourceConversation-BoRcXEfg.js → ResultSourceConversation-NKiRGO6_.js} +1 -1
  81. package/dist/web/server/assets/{_id-B-tA4zr0.js → _id-BLHUW0oS.js} +1 -1
  82. package/dist/web/server/assets/{_id-j2iOW-7w.js → _id-BxTsdM7U.js} +3 -3
  83. package/dist/web/server/assets/{_id-4t_AIt1b.js → _id-CAxK6pln.js} +1 -1
  84. package/dist/web/server/assets/{_id-B8EgU2la.js → _id-CmS2d0me.js} +2 -2
  85. package/dist/web/server/assets/{_tanstack-start-manifest_v-D6Cx8dbN.js → _tanstack-start-manifest_v-DsMaFmpx.js} +133 -133
  86. package/dist/web/server/assets/{config-C63Rp2Tc.js → config-DM2DIzMT.js} +1 -1
  87. package/dist/web/server/assets/{config-Cnj8GNk_.js → config-DX3c4Co0.js} +5 -3
  88. package/dist/web/server/assets/{results-m4JaXsRF.js → results-BFPu3tcP.js} +1 -1
  89. package/dist/web/server/assets/{results-BWsxk1aR.js → results-TR7VXLdQ.js} +3 -3
  90. package/dist/web/server/assets/{router-CMMB5oyy.js → router-DlwGPg99.js} +6 -6
  91. package/dist/web/server/assets/{routes-DFAvoScC.js → routes-BGMHt0b0.js} +2 -2
  92. package/dist/web/server/assets/{routes-BrtSbu3l.js → routes-kSjMHwrg.js} +1 -1
  93. package/dist/web/server/assets/{services-W4rO8Lc-.js → services-T8adll3y.js} +14 -6
  94. package/dist/web/server/assets/{services-2f0nAQPX.js → services-UL_2b8PP.js} +1 -1
  95. package/dist/web/server/server.js +2 -2
  96. package/dist/worker.js +208 -2
  97. package/dist/worker.js.map +1 -1
  98. package/package.json +6 -6
  99. package/dist/web/client/assets/FieldRow-VR8Sv-gN.js +0 -1
  100. package/dist/web/client/assets/ResultCard-D1bopCj0.js +0 -1
  101. package/dist/web/client/assets/chevron-right-BxPmmRg9.js +0 -1
@@ -3558,7 +3558,7 @@ var defaultSerovalPlugins = [
3558
3558
  * the dev styles URL for route-scoped CSS collection.
3559
3559
  */
3560
3560
  async function getStartManifest(matchedRoutes) {
3561
- const { tsrStartManifest } = await import("./assets/_tanstack-start-manifest_v-D6Cx8dbN.js");
3561
+ const { tsrStartManifest } = await import("./assets/_tanstack-start-manifest_v-DsMaFmpx.js");
3562
3562
  const startManifest = tsrStartManifest();
3563
3563
  let routes = startManifest.routes;
3564
3564
  routes[rootRouteId];
@@ -5648,7 +5648,7 @@ var getBaseManifest = getProdBaseManifest;
5648
5648
  var createEarlyHintsForRequest = createEarlyHintsCollector;
5649
5649
  async function loadEntries() {
5650
5650
  const [routerEntry, startEntry, pluginAdapters] = await Promise.all([
5651
- import("./assets/router-CMMB5oyy.js"),
5651
+ import("./assets/router-DlwGPg99.js"),
5652
5652
  import("./assets/start-D4Wq9iTa.js"),
5653
5653
  import("./assets/empty-plugin-adapters-Cq4--YW-.js")
5654
5654
  ]);
package/dist/worker.js CHANGED
@@ -121,6 +121,18 @@ import { randomUUID as randomUUID5 } from "crypto";
121
121
  import { createHash, randomUUID as randomUUID6 } from "crypto";
122
122
  var DEFAULT_TTL_MS = 24 * 60 * 60 * 1e3;
123
123
 
124
+ // ../daemon/src/core/image-generation-config.ts
125
+ var OPENROUTER_IMAGE_MODELS = [
126
+ "google/gemini-3.1-flash-image",
127
+ "openai/gpt-image-2"
128
+ ];
129
+ var IMAGE_MODELS = [
130
+ ...OPENROUTER_IMAGE_MODELS,
131
+ "openai:gpt-image-2",
132
+ "openai-codex:gpt-image-2"
133
+ ];
134
+ var IMAGE_MODEL_CHOICES = ["auto", ...IMAGE_MODELS];
135
+
124
136
  // ../daemon/src/core/services.ts
125
137
  var SERVICES = [
126
138
  // --- LLM providers (configured via API keys / URLs) ---
@@ -386,6 +398,20 @@ var SERVICES = [
386
398
  hint: "GLM coding endpoint \xB7 open.bigmodel.cn",
387
399
  fields: [{ envVar: "ZAI_CODING_CN_API_KEY", kind: "secret", label: "API key" }]
388
400
  },
401
+ {
402
+ id: "meta",
403
+ displayName: "Meta",
404
+ category: "provider",
405
+ hint: "Meta model API \xB7 api.meta.ai",
406
+ fields: [{ envVar: "META_API_KEY", kind: "secret", label: "API key" }]
407
+ },
408
+ {
409
+ id: "radius",
410
+ displayName: "Radius",
411
+ category: "provider",
412
+ hint: "Radius gateway \xB7 radius.pi.dev",
413
+ fields: [{ envVar: "RADIUS_API_KEY", kind: "secret", label: "API key" }]
414
+ },
389
415
  {
390
416
  id: "huggingface",
391
417
  displayName: "Hugging Face",
@@ -510,6 +536,36 @@ var SERVICES = [
510
536
  ]
511
537
  },
512
538
  // --- Ancillary services (web search, etc) ---
539
+ {
540
+ id: "image-generation",
541
+ displayName: "Image generation",
542
+ category: "service",
543
+ team: "Content tools",
544
+ hint: "Automatic (default) follows your enabled OpenAI text providers: API key \u2192 separate API billing; ChatGPT/Codex login \u2192 subscription usage. If both are enabled, OpenAI/ChatGPT Agents use their own text provider; other Agents need an explicit image choice. Saved credentials alone never select a route. OpenRouter is explicit only. Provider failures never switch billing routes. Image generation still requires the separate on switch. Four requests/turn, one in flight/home; environment variables override saved settings.",
545
+ fields: [
546
+ {
547
+ envVar: "BAZILION_IMAGE_MODEL",
548
+ kind: "config",
549
+ label: "Default image route / model",
550
+ options: IMAGE_MODEL_CHOICES,
551
+ optionLabels: {
552
+ auto: "Automatic \xB7 follow enabled OpenAI text providers",
553
+ "google/gemini-3.1-flash-image": "OpenRouter \xB7 Gemini 3.1 Flash Image",
554
+ "openai/gpt-image-2": "OpenRouter \xB7 GPT Image 2",
555
+ "openai:gpt-image-2": "OpenAI API key \xB7 GPT Image 2",
556
+ "openai-codex:gpt-image-2": "ChatGPT/Codex login \xB7 GPT Image 2 (requested)"
557
+ },
558
+ description: "Unset or Automatic follows enabled text providers. Explicit selections override automatic routing. API-key routes incur API charges; ChatGPT image entitlement is account-dependent and not tested by saving settings."
559
+ },
560
+ {
561
+ envVar: "BAZILION_IMAGE_GENERATION",
562
+ kind: "config",
563
+ label: "Image generation",
564
+ options: ["off", "on"],
565
+ description: "Off by default. Enabling permits image requests (API charges or subscription usage) from normal Agent turns, including background turns."
566
+ }
567
+ ]
568
+ },
513
569
  {
514
570
  id: "firecrawl",
515
571
  displayName: "Firecrawl",
@@ -758,6 +814,15 @@ import { randomUUID as randomUUID10 } from "crypto";
758
814
  // ../daemon/src/core/repos/webPairingTokens.ts
759
815
  import { createHash as createHash3, randomBytes as randomBytes3, randomUUID as randomUUID11 } from "crypto";
760
816
 
817
+ // ../../packages/api-types/src/image-generation.ts
818
+ function imageGenerationRouteLabel(model) {
819
+ if (model === "openai:gpt-image-2") return "OpenAI API key";
820
+ if (model === "openai-codex:gpt-image-2") return "ChatGPT/Codex login";
821
+ if (model === "google/gemini-3.1-flash-image" || model === "openai/gpt-image-2")
822
+ return "OpenRouter";
823
+ return "Unknown image route";
824
+ }
825
+
761
826
  // ../../packages/api-types/src/git-review.ts
762
827
  var REVIEW_LIMITS = {
763
828
  files: 1e3,
@@ -1410,6 +1475,7 @@ function piMessagesToProviderView(messages, questionResultVisible) {
1410
1475
  toolCallId: tr.toolCallId,
1411
1476
  toolName: tr.toolName,
1412
1477
  result: extractResultReference(m),
1478
+ results: extractResultReferences(m),
1413
1479
  ...images.length > 0 ? { images } : {}
1414
1480
  });
1415
1481
  break;
@@ -1420,6 +1486,15 @@ function piMessagesToProviderView(messages, questionResultVisible) {
1420
1486
  }
1421
1487
  return out;
1422
1488
  }
1489
+ function extractResultReferences(value) {
1490
+ if (!value || typeof value !== "object") return void 0;
1491
+ const refs = value.details?.results;
1492
+ if (!Array.isArray(refs) || refs.length > 4) return void 0;
1493
+ return refs.flatMap((ref) => {
1494
+ const parsed = extractResultReference({ details: { result: ref } });
1495
+ return parsed ? [parsed] : [];
1496
+ });
1497
+ }
1423
1498
  function extractResultReference(value) {
1424
1499
  if (!value || typeof value !== "object") return void 0;
1425
1500
  const details = value.details;
@@ -3493,6 +3568,8 @@ var PROTECTED_PROVIDER_NAMES = [
3493
3568
  "opencode",
3494
3569
  "opencode-go",
3495
3570
  "zai-coding-cn",
3571
+ "meta",
3572
+ "radius",
3496
3573
  "github-copilot",
3497
3574
  "cloudflare-ai-gateway",
3498
3575
  "cloudflare-workers-ai",
@@ -3543,6 +3620,8 @@ var PROVIDER_API_KEY_ENV = {
3543
3620
  opencode: ["OPENCODE_API_KEY"],
3544
3621
  "opencode-go": ["OPENCODE_GO_API_KEY"],
3545
3622
  "zai-coding-cn": ["ZAI_CODING_CN_API_KEY"],
3623
+ meta: ["META_API_KEY"],
3624
+ radius: ["RADIUS_API_KEY"],
3546
3625
  "github-copilot": ["COPILOT_GITHUB_TOKEN"],
3547
3626
  "cloudflare-ai-gateway": ["CLOUDFLARE_API_KEY"],
3548
3627
  "cloudflare-workers-ai": ["CLOUDFLARE_API_KEY"],
@@ -4087,6 +4166,8 @@ var REASONING_LEVELS2 = /* @__PURE__ */ new Set([
4087
4166
  var CONFIGURED_KEYS = /* @__PURE__ */ new Set([
4088
4167
  "containerNamespace",
4089
4168
  "configuredDocker",
4169
+ "imageGenerationEnabled",
4170
+ "webSearchEnabled",
4090
4171
  "repositoryContext",
4091
4172
  "questionEnabled",
4092
4173
  "conversation",
@@ -4114,6 +4195,7 @@ var CONFIGURED_REQUIRED_KEYS = /* @__PURE__ */ new Set([
4114
4195
  "bashApprovalMode"
4115
4196
  ]);
4116
4197
  var PROTECTED_KEYS = /* @__PURE__ */ new Set([
4198
+ "imageGenerationEnabled",
4117
4199
  "containerNamespace",
4118
4200
  "repositoryContext",
4119
4201
  "questionEnabled",
@@ -4128,12 +4210,13 @@ var PROTECTED_KEYS = /* @__PURE__ */ new Set([
4128
4210
  "paths",
4129
4211
  "docker",
4130
4212
  "webFetchEnabled",
4213
+ "webSearchEnabled",
4131
4214
  "apiKeyRefreshEnabled",
4132
4215
  "scratch"
4133
4216
  ]);
4134
4217
  var PROTECTED_REQUIRED_KEYS = new Set(
4135
4218
  [...PROTECTED_KEYS].filter(
4136
- (key) => key !== "images" && key !== "questionEnabled" && key !== "containerNamespace"
4219
+ (key) => key !== "images" && key !== "questionEnabled" && key !== "containerNamespace" && key !== "imageGenerationEnabled" && key !== "webSearchEnabled"
4137
4220
  )
4138
4221
  );
4139
4222
  var STATIC_REVIEW_KEYS = /* @__PURE__ */ new Set([
@@ -4217,6 +4300,10 @@ function parseWorkerInput(value) {
4217
4300
  const kind = input.kind;
4218
4301
  if (input.containerNamespace !== void 0 && (typeof input.containerNamespace !== "string" || !/^[a-f0-9-]{36}$/.test(input.containerNamespace)))
4219
4302
  throw new Error("Invalid container namespace");
4303
+ if (input.imageGenerationEnabled !== void 0 && typeof input.imageGenerationEnabled !== "boolean")
4304
+ throw new Error("Invalid worker image capability");
4305
+ if (input.webSearchEnabled !== void 0 && typeof input.webSearchEnabled !== "boolean")
4306
+ throw new Error("Invalid worker web search capability");
4220
4307
  if (input.questionEnabled !== void 0 && typeof input.questionEnabled !== "boolean")
4221
4308
  throw new Error("Invalid worker question capability");
4222
4309
  if (kind === "configured_operator_http") {
@@ -5284,6 +5371,53 @@ function rejectExistingSymlinkOrNonFile(path) {
5284
5371
  }
5285
5372
  }
5286
5373
 
5374
+ // ../daemon/src/runtime/tools/image-generate.ts
5375
+ function imageGenerateTool(generate, sessionId) {
5376
+ return {
5377
+ def: {
5378
+ name: "image_generate",
5379
+ description: "Generate original images from a text prompt using the operator-selected image route/model (API billing or ChatGPT subscription usage). Saved Results are delivered subject to Team Policy. Rework is a new generation, not a pixel edit. Do not automatically retry a failed or uncertain request; it may already have been billed. No social publication.",
5380
+ parameters: {
5381
+ type: "object",
5382
+ properties: {
5383
+ prompt: {
5384
+ type: "string",
5385
+ description: "Describe the desired image. Maximum 8 KiB UTF-8."
5386
+ },
5387
+ name: {
5388
+ type: "string",
5389
+ description: "Optional display filename, not a path (ASCII, maximum 120 characters)."
5390
+ }
5391
+ },
5392
+ required: ["prompt"],
5393
+ additionalProperties: false
5394
+ }
5395
+ },
5396
+ async invoke(args, context) {
5397
+ if (!context?.toolCallId || !sessionId)
5398
+ throw new Error("image_generate: missing source operation");
5399
+ if (typeof args.prompt !== "string" || args.name !== void 0 && typeof args.name !== "string" || Object.keys(args).some((key) => !["prompt", "name"].includes(key))) {
5400
+ throw new Error("image_generate: invalid arguments");
5401
+ }
5402
+ const output = await generate({
5403
+ sessionId,
5404
+ toolCallId: context.toolCallId,
5405
+ prompt: args.prompt,
5406
+ ...args.name === void 0 ? {} : { name: args.name }
5407
+ });
5408
+ return {
5409
+ content: [
5410
+ {
5411
+ type: "text",
5412
+ text: `Saved ${output.files.length} image(s) via ${imageGenerationRouteLabel(output.model)} (selected: ${output.model}). Delivery is subject to Team Policy. ${output.files.map((file) => `${file.name}: ${file.result.resultId}`).join("; ")}`
5413
+ }
5414
+ ],
5415
+ results: output.files.map((file) => file.result)
5416
+ };
5417
+ }
5418
+ };
5419
+ }
5420
+
5287
5421
  // ../daemon/src/runtime/tools/mcp.ts
5288
5422
  function mcpProxyTools(host, tools) {
5289
5423
  return tools.map((t) => ({
@@ -6473,6 +6607,32 @@ function protectedWebFetchTool(opts) {
6473
6607
  if (!tool) throw new Error("protected web_fetch tool construction failed");
6474
6608
  return tool;
6475
6609
  }
6610
+ function protectedWebSearchTool(host) {
6611
+ return {
6612
+ def: {
6613
+ name: "web_search",
6614
+ description: "Search the web via the daemon-approved discovery backend. Returns bounded titles, URLs and snippets as UNTRUSTED data \u2014 verify before relying on them; fetching a URL still goes through web_fetch. Requires operator-configured discovery; report its absence instead of working around it.",
6615
+ parameters: {
6616
+ type: "object",
6617
+ properties: {
6618
+ query: { type: "string", description: "Search query (max 512 chars)" },
6619
+ count: { type: "number", description: "Max results, 1-8 (default 5)" }
6620
+ },
6621
+ required: ["query"]
6622
+ }
6623
+ },
6624
+ async invoke(args) {
6625
+ const query = typeof args.query === "string" ? args.query : "";
6626
+ if (!query.trim()) throw new Error("web_search: query is required");
6627
+ const count2 = typeof args.count === "number" ? args.count : void 0;
6628
+ const output = await host.search({ query, count: count2 });
6629
+ if (output.results.length === 0) return "No results found.";
6630
+ return output.results.map((r) => `- ${r.title}
6631
+ ${r.url}${r.snippet ? `
6632
+ ${r.snippet}` : ""}`).join("\n");
6633
+ }
6634
+ };
6635
+ }
6476
6636
  function buildWebTools(opts, includeSearch) {
6477
6637
  const fetchFn = opts?.fetchImpl ?? undiciFetch2;
6478
6638
  const env = opts?.env ?? process.env;
@@ -6637,7 +6797,7 @@ function ourToolToPiTool(h) {
6637
6797
  const out = await h.invoke(params, { toolCallId });
6638
6798
  return {
6639
6799
  content: toPiContent(out),
6640
- details: typeof out === "object" && !Array.isArray(out) ? "result" in out ? { result: out.result } : { questionReceipt: out.questionReceipt } : {}
6800
+ details: typeof out === "object" && !Array.isArray(out) ? "result" in out ? { result: out.result } : "results" in out ? { results: out.results } : { questionReceipt: out.questionReceipt } : {}
6641
6801
  };
6642
6802
  }
6643
6803
  };
@@ -6670,6 +6830,14 @@ function createBazilionCustomTools(opts) {
6670
6830
  if (opts.fileSink) {
6671
6831
  handlers.push(deliverFileTool(opts.agent.team.path, opts.fileSink, opts.sessionId));
6672
6832
  }
6833
+ if (opts.imageGenerationHost) {
6834
+ handlers.push(
6835
+ imageGenerateTool(
6836
+ opts.imageGenerationHost.generate.bind(opts.imageGenerationHost),
6837
+ opts.sessionId ?? ""
6838
+ )
6839
+ );
6840
+ }
6673
6841
  if (opts.verificationRequestHost) {
6674
6842
  handlers.push(verificationRequestTool(opts.verificationRequestHost));
6675
6843
  }
@@ -6685,10 +6853,27 @@ function createProtectedBazilionCustomTools(opts) {
6685
6853
  ...homeTools(opts.agent.agent.dir),
6686
6854
  bootstrapTool(opts.agent.agent.dir),
6687
6855
  protectedWebFetchTool(),
6856
+ ...opts.webSearchHost ? [
6857
+ protectedWebSearchTool({
6858
+ search: (args) => {
6859
+ const host = opts.webSearchHost;
6860
+ if (!host) throw new Error("web search host disappeared mid-turn");
6861
+ return host.search(args);
6862
+ }
6863
+ })
6864
+ ] : [],
6688
6865
  ...messagingTools(opts.messagingHost, opts.agent.agent.id),
6689
6866
  ...userMdTools(opts.userMdHost, opts.agent.team.id),
6690
6867
  deliverFileTool(opts.agent.team.path, opts.fileSink, opts.sessionId)
6691
6868
  ];
6869
+ if (opts.imageGenerationHost) {
6870
+ handlers.push(
6871
+ imageGenerateTool(
6872
+ opts.imageGenerationHost.generate.bind(opts.imageGenerationHost),
6873
+ opts.sessionId ?? ""
6874
+ )
6875
+ );
6876
+ }
6692
6877
  if (opts.verificationRequestHost) {
6693
6878
  handlers.push(verificationRequestTool(opts.verificationRequestHost));
6694
6879
  }
@@ -6796,6 +6981,7 @@ async function createBazilionSession(opts) {
6796
6981
  mcpHost,
6797
6982
  mcpTools,
6798
6983
  fileSink,
6984
+ imageGenerationHost: opts.imageGenerationHost,
6799
6985
  askUser,
6800
6986
  sessionId: sessionManager.getSessionId(),
6801
6987
  env,
@@ -6921,6 +7107,8 @@ async function createProtectedBazilionSession(opts) {
6921
7107
  messagingHost: opts.messagingHost,
6922
7108
  userMdHost: opts.userMdHost,
6923
7109
  fileSink: opts.fileSink,
7110
+ webSearchHost: opts.webSearchHost,
7111
+ imageGenerationHost: opts.imageGenerationHost,
6924
7112
  askUser: opts.askUser,
6925
7113
  sessionId: sessionManager.getSessionId(),
6926
7114
  verificationRequestHost: opts.verificationRequestHost,
@@ -7419,6 +7607,20 @@ function createIpcVerificationHost(ipcCall, identity2) {
7419
7607
  async function createSessionForInput(input, ipcCall) {
7420
7608
  if (input.kind !== "restricted_review" && input.kind !== "specialist_verification" && input.kind !== "packet_review" && !input.repositoryContext)
7421
7609
  throw new Error("Coding turn requires daemon-prepared repository context");
7610
+ const imageGenerationHost = (input.kind === "configured_operator_http" || input.kind === "protected") && input.imageGenerationEnabled ? {
7611
+ generate: async (request) => {
7612
+ const output = await ipcCall(
7613
+ "generateImages",
7614
+ request
7615
+ );
7616
+ for (const file of output.files)
7617
+ emit({ kind: "event", event: { type: "file", ...file } });
7618
+ return output;
7619
+ }
7620
+ } : void 0;
7621
+ const webSearchHost = (input.kind === "configured_operator_http" || input.kind === "protected") && input.webSearchEnabled ? {
7622
+ search: async (args) => ipcCall("webSearch", args)
7623
+ } : void 0;
7422
7624
  if (input.kind === "configured_operator_http") {
7423
7625
  const paths = resolvePaths();
7424
7626
  const memory2 = qmdBackend(`${input.agent.team.path}/memory`);
@@ -7456,6 +7658,7 @@ async function createSessionForInput(input, ipcCall) {
7456
7658
  // worker kind reaches this builder, and it is an ordinary coding turn.
7457
7659
  verificationRequestHost: createIpcVerificationRequestHost(ipcCall),
7458
7660
  reviewRequestHost: createIpcReviewRequestHost(ipcCall),
7661
+ imageGenerationHost,
7459
7662
  apiKey: input.apiKey,
7460
7663
  refreshApiKey: refreshApiKey2,
7461
7664
  browserHost,
@@ -7528,6 +7731,8 @@ async function createSessionForInput(input, ipcCall) {
7528
7731
  repositoryContext: input.repositoryContext,
7529
7732
  repositoryContextHost: (target) => ipcCall("repositoryContext", { target }),
7530
7733
  codingHost: { invoke: (request) => ipcCall("coding", request) },
7734
+ imageGenerationHost,
7735
+ webSearchHost,
7531
7736
  runtime: input.runtime,
7532
7737
  paths: input.paths,
7533
7738
  scratch: input.scratch,
@@ -7646,6 +7851,7 @@ async function main() {
7646
7851
  } catch {
7647
7852
  }
7648
7853
  }
7854
+ process.exit(process.exitCode ?? 0);
7649
7855
  }
7650
7856
  main().catch((error) => {
7651
7857
  try {