mu-agent 0.1.7 → 0.1.8

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 (143) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +5 -4
  3. package/dist/bundle/chunks/anthropic-messages-MI4QHRXW.js +6 -0
  4. package/dist/bundle/chunks/anthropic.js +2 -2
  5. package/dist/bundle/chunks/azure-openai-responses-E3QGN4VN.js +2 -0
  6. package/dist/bundle/chunks/bedrock-converse-stream.js +2 -2
  7. package/dist/bundle/chunks/chunk-33KL6IIQ.js +20 -0
  8. package/dist/bundle/chunks/chunk-4OBXYPH4.js +4 -0
  9. package/dist/bundle/chunks/chunk-C47CLQZK.js +2 -0
  10. package/dist/bundle/chunks/chunk-F5ZABL6Z.js +20 -0
  11. package/dist/bundle/chunks/chunk-H3QXYIF7.js +31 -0
  12. package/dist/bundle/chunks/chunk-HQHD6PZI.js +2 -0
  13. package/dist/bundle/chunks/chunk-KJUDFE6Y.js +11 -0
  14. package/dist/bundle/chunks/chunk-LD2P6SFZ.js +2 -0
  15. package/dist/bundle/chunks/chunk-NG4PO5FP.js +1204 -0
  16. package/dist/bundle/chunks/chunk-NTSWBG4X.js +2 -0
  17. package/dist/bundle/chunks/chunk-RLZVFGW4.js +127 -0
  18. package/dist/bundle/chunks/{chunk-XDUWOHPL.js → chunk-S3GGRYIO.js} +2 -2
  19. package/dist/bundle/chunks/{chunk-4O2SCVYF.js → chunk-TAOL3JFA.js} +1 -1
  20. package/dist/bundle/chunks/chunk-TE3GUV6H.js +9 -0
  21. package/dist/bundle/chunks/chunk-VIV3CWXG.js +2 -0
  22. package/dist/bundle/chunks/{chunk-V7IXECST.js → chunk-WE4MXUQS.js} +3 -3
  23. package/dist/bundle/chunks/chunk-Y2PP32XV.js +2 -0
  24. package/dist/bundle/chunks/chunk-YLY6CKPK.js +132 -0
  25. package/dist/bundle/chunks/chunk-ZE5FMF3V.js +99 -0
  26. package/dist/bundle/chunks/cli-AOVD3SSZ.js +51 -0
  27. package/dist/bundle/chunks/cloudflare-workers-ai-system-one-NM3JRRWQ.js +2 -0
  28. package/dist/bundle/chunks/codemode-worker.js +374 -0
  29. package/dist/bundle/chunks/easter-egg-3d-G2LUBEMZ.js +2 -0
  30. package/dist/bundle/chunks/execute-MZVUC6BB.js +388 -0
  31. package/dist/bundle/chunks/github-copilot.js +1 -1
  32. package/dist/bundle/chunks/{google-generative-ai-C44KRRZ4.js → google-generative-ai-XMFHGQC5.js} +1 -1
  33. package/dist/bundle/chunks/{google-vertex-25DUXPTJ.js → google-vertex-4XRRNP74.js} +1 -1
  34. package/dist/bundle/chunks/{lib-HGQMNYVT.js → lib-TEDK3E5I.js} +2 -2
  35. package/dist/bundle/chunks/llama-cpp-classify-XT44PI3C.js +22 -0
  36. package/dist/bundle/chunks/mistral-conversations-Q22M3IBG.js +5 -0
  37. package/dist/bundle/chunks/node-N5BSDOA5.js +16 -0
  38. package/dist/bundle/chunks/openai-chatgpt.js +86 -0
  39. package/dist/bundle/chunks/{openai-codex-responses-3UAYOSSR.js → openai-codex-responses-4MYQSO5E.js} +1 -1
  40. package/dist/bundle/chunks/openai-codex.js +2 -2
  41. package/dist/bundle/chunks/openai-completions-OSRCWAAA.js +7 -0
  42. package/dist/bundle/chunks/openai-responses-UHF3DHNG.js +3 -0
  43. package/dist/bundle/chunks/{openrouter-images-JVEJN44Q.js → openrouter-images-ZVXWCSIM.js} +1 -1
  44. package/dist/bundle/chunks/openrouter.js +2 -2
  45. package/dist/bundle/chunks/radius.js +2 -2
  46. package/dist/bundle/chunks/runtime-VJMMDLVH.js +2 -0
  47. package/dist/bundle/chunks/typesafe-system-one-PRR5K6CI.js +2 -0
  48. package/dist/bundle/chunks/virtual-modules-RJXJGCPI.js +2 -0
  49. package/dist/bundle/cli-runtime.js +1 -1
  50. package/dist/bundle/index.js +1 -1
  51. package/dist/bundle/native/darwin/prebuilds/darwin-arm64/darwin-platform.node +0 -0
  52. package/dist/bundle/native/darwin/prebuilds/darwin-x64/darwin-platform.node +0 -0
  53. package/dist/bundle/rpc-entry.js +1 -1
  54. package/dist/core/export-html/template.js +16 -0
  55. package/dist/modes/interactive/theme/dark.json +59 -72
  56. package/dist/modes/interactive/theme/light.json +57 -69
  57. package/dist/modes/interactive/theme/system-theme.d.ts +55 -0
  58. package/dist/modes/interactive/theme/system-theme.d.ts.map +1 -0
  59. package/dist/modes/interactive/theme/system-theme.js +546 -0
  60. package/dist/modes/interactive/theme/system-theme.js.map +1 -0
  61. package/dist/modes/interactive/theme/theme-controller.d.ts +43 -9
  62. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  63. package/dist/modes/interactive/theme/theme-controller.js +121 -79
  64. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  65. package/dist/modes/interactive/theme/theme-json.d.ts.map +1 -1
  66. package/dist/modes/interactive/theme/theme-json.js +1 -1
  67. package/dist/modes/interactive/theme/theme-json.js.map +1 -1
  68. package/dist/modes/interactive/theme/theme-schema.json +2 -2
  69. package/dist/modes/interactive/theme/theme.d.ts +34 -40
  70. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  71. package/dist/modes/interactive/theme/theme.js +139 -126
  72. package/dist/modes/interactive/theme/theme.js.map +1 -1
  73. package/dist/native/darwin/prebuilds/darwin-arm64/darwin-platform.node +0 -0
  74. package/dist/native/darwin/prebuilds/darwin-x64/darwin-platform.node +0 -0
  75. package/docs/cli.md +60 -7
  76. package/docs/codemode.md +207 -0
  77. package/docs/configuration.md +2 -0
  78. package/docs/docs.json +13 -1
  79. package/docs/environment-variables.md +2 -2
  80. package/docs/extensions.md +53 -0
  81. package/docs/index.md +1 -1
  82. package/docs/keybindings.md +2 -2
  83. package/docs/llama-cpp.md +13 -0
  84. package/docs/mcp.md +270 -0
  85. package/docs/models.md +83 -1
  86. package/docs/packages.md +1 -1
  87. package/docs/providers.md +19 -6
  88. package/docs/quickstart.md +16 -2
  89. package/docs/rpc-commands.md +9 -3
  90. package/docs/rpc.md +3 -1
  91. package/docs/sdk.md +8 -3
  92. package/docs/security.md +2 -0
  93. package/docs/session-format.md +5 -1
  94. package/docs/settings.md +24 -5
  95. package/docs/themes.md +28 -6
  96. package/docs/usage.md +1 -1
  97. package/docs/virtual-models.md +114 -0
  98. package/docs/windows.md +2 -0
  99. package/examples/README.md +1 -1
  100. package/examples/extensions/README.md +1 -0
  101. package/examples/extensions/built-in-tool-renderer.ts +16 -40
  102. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  103. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  104. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  105. package/examples/extensions/custom-provider-gitlab-duo/test.ts +5 -5
  106. package/examples/extensions/gondolin/package-lock.json +2 -2
  107. package/examples/extensions/gondolin/package.json +1 -1
  108. package/examples/extensions/jev-router.ts +113 -0
  109. package/examples/extensions/minimal-mode.ts +24 -96
  110. package/examples/extensions/sandbox/package-lock.json +2 -2
  111. package/examples/extensions/sandbox/package.json +1 -1
  112. package/examples/extensions/with-deps/package-lock.json +2 -2
  113. package/examples/extensions/with-deps/package.json +1 -1
  114. package/examples/rpc-client.ts +1 -1
  115. package/examples/rpc-extension-ui.ts +1 -1
  116. package/examples/sdk/14-codemode-mcp.ts +61 -0
  117. package/examples/sdk/README.md +2 -1
  118. package/judge/THIRD_PARTY_NOTICES.md +63 -0
  119. package/judge/dist/auth.js +128 -113
  120. package/judge/dist/import.js +10 -9
  121. package/judge/dist/kyrn-judge.js +5444 -5354
  122. package/judge/dist/setup.js +138 -12
  123. package/judge/manifest.json +414 -102
  124. package/kyrn/bin/kyrn-doctor +61 -11
  125. package/kyrn/bin/mu.mjs +84 -69
  126. package/package.json +4 -4
  127. package/dist/bundle/chunks/anthropic-messages-VMESUHQ7.js +0 -6
  128. package/dist/bundle/chunks/azure-openai-responses-K232MQFF.js +0 -2
  129. package/dist/bundle/chunks/chunk-AYFRR3OD.js +0 -2
  130. package/dist/bundle/chunks/chunk-DTD7JQ7Y.js +0 -42
  131. package/dist/bundle/chunks/chunk-FU4XQUSL.js +0 -11
  132. package/dist/bundle/chunks/chunk-GNYZK6XN.js +0 -2
  133. package/dist/bundle/chunks/chunk-HEMXN7VJ.js +0 -1653
  134. package/dist/bundle/chunks/chunk-MVPXOVOJ.js +0 -2
  135. package/dist/bundle/chunks/chunk-NUHFSC37.js +0 -25
  136. package/dist/bundle/chunks/chunk-XNGRGP62.js +0 -2
  137. package/dist/bundle/chunks/cloudflare-workers-ai-system-one-NR2TDCXU.js +0 -2
  138. package/dist/bundle/chunks/mistral-conversations-6IHQOR4R.js +0 -5
  139. package/dist/bundle/chunks/node-O3RIBJRH.js +0 -16
  140. package/dist/bundle/chunks/openai-completions-FIEQGWAH.js +0 -7
  141. package/dist/bundle/chunks/openai-responses-OZJXLHFC.js +0 -2
  142. package/dist/bundle/chunks/typesafe-system-one-VKYX4OGY.js +0 -2
  143. package/dist/bundle/chunks/virtual-modules-V7SXVVLP.js +0 -2
@@ -8,6 +8,7 @@ import { homedir } from "node:os";
8
8
  import { join } from "node:path";
9
9
  import { pathToFileURL } from "node:url";
10
10
  import {
11
+ dependenciesInstalled,
11
12
  detectWsl,
12
13
  envFilePath,
13
14
  findOnPath,
@@ -17,7 +18,6 @@ import {
17
18
  packageEntries,
18
19
  parseEnvFile,
19
20
  platformName,
20
- resolveTsx,
21
21
  } from "./mu.mjs";
22
22
 
23
23
  const [root, link] = process.argv.slice(2);
@@ -68,12 +68,11 @@ if (layout === "package") {
68
68
  });
69
69
  row(onPath ? "ok" : "fix", "command", onPath ? tilde(onPath) : "`mu` is not on PATH: add npm's global bin folder (npm prefix -g) to it");
70
70
  } else {
71
- // The JavaScript behind tsx, which is what the launcher runs: node_modules/.bin holds a .cmd shim on Windows.
72
- const tsx = resolveTsx({ root, platform: process.platform, exists: existsSync, readFile: (path) => readFileSync(path, "utf8") });
71
+ const installed = dependenciesInstalled({ root, platform: process.platform, exists: existsSync });
73
72
  row(
74
- tsx ? "ok" : "fix",
73
+ installed ? "ok" : "fix",
75
74
  "dependencies",
76
- tsx
75
+ installed
77
76
  ? "installed"
78
77
  : `missing: cd ${root} && npm ci --ignore-scripts && npm run hydrate:model-data`,
79
78
  );
@@ -118,7 +117,7 @@ row(
118
117
 
119
118
  const config = readJson(join(agentDir, "mu.json")) ?? readJson(join(agentDir, "kyrn.json"));
120
119
  const tiers = (env("JUDGE") ? env("JUDGE").split(",") : (config?.tiers ?? ["jev"])).map((tier) => tier.trim());
121
- const mode = env("JUDGE_MODE") ?? config?.modes?.default ?? "shadow";
120
+ const mode = env("JUDGE_MODE") ?? config?.modes?.default ?? "active";
122
121
  row("--", "judges", `${tiers.join(" > ")} · decisions ${mode}${env("JUDGE") ? " (from MU_JUDGE)" : ""}`);
123
122
  const overrides = Object.entries(config?.modes ?? {}).filter(([id]) => id !== "default");
124
123
  if (overrides.length > 0) row("--", "modes", overrides.map(([id, value]) => `${id}=${value}`).join(" "));
@@ -155,6 +154,21 @@ const JEV_ROUTES = {
155
154
  "jev-openrouter": { type: "typesafe", baseUrl: "https://openrouter.ai/api/v1/systemone", apiKeyEnv: "MU_JUDGE_OPENROUTER_API_KEY" },
156
155
  "jev-gateway": { type: "gateway" },
157
156
  gateway: { type: "gateway" },
157
+ "jev-opencode": { type: "classifier", model: "opencode/jev-1.13" },
158
+ "jev-opencode-free": { type: "classifier", model: "opencode/jev-1.13-free" },
159
+ "jev-cloudflare": { type: "classifier", model: "cloudflare-workers-ai/typesafe/jev" },
160
+ clef: { type: "classifier", model: "cloudflare-workers-ai/@cf/cloudflare/clef" },
161
+ "clef-flash": { type: "classifier", model: "cloudflare-workers-ai/@cf/cloudflare/clef-flash" },
162
+ };
163
+ // The variables pi reads a classifier provider's credentials from (packages/ai/src/env-api-keys.ts); a key stored
164
+ // with /login or `mu auth` works as well. llama.cpp on this machine needs none.
165
+ const CLASSIFIER_KEYS = {
166
+ opencode: ["OPENCODE_API_KEY"],
167
+ "cloudflare-workers-ai": ["CLOUDFLARE_API_KEY", "CLOUDFLARE_ACCOUNT_ID"],
168
+ openrouter: ["OPENROUTER_API_KEY"],
169
+ typesafe: ["TYPESAFE_API_KEY"],
170
+ "vercel-ai-gateway": ["AI_GATEWAY_API_KEY"],
171
+ "llama.cpp": [],
158
172
  };
159
173
  // Parsed the way the launcher parses it (quotes, `export `), and only asked whether a name has a value.
160
174
  const fromFile = existsSync(envFile) ? parseEnvFile(readFileSync(envFile, "utf8")).entries : [];
@@ -164,18 +178,21 @@ const jevTier = tiers.find((tier) => ["jev", "typesafe", "gateway"].includes((co
164
178
  if (jevTier) {
165
179
  const judge = config?.judges?.[jevTier] ?? JEV_ROUTES[jevTier];
166
180
  if (judge.type === "jev") {
167
- // The order the registry tries: TypeSafe directly, Jev on OpenRouter, the Vercel AI Gateway.
181
+ // The order the registry tries: TypeSafe directly, Jev on OpenRouter, the Vercel AI Gateway, OpenCode Zen,
182
+ // Cloudflare Workers AI (key and account). With none of them, a gateway key kept with /login, else the free Jev.
168
183
  const route = [
169
184
  ["TYPESAFE_API_KEY", "Jev is called directly at api.typesafe.ai"],
170
185
  ["MU_JUDGE_OPENROUTER_API_KEY", "Jev is called through OpenRouter"],
171
186
  ["AI_GATEWAY_API_KEY", "Jev is called through the Vercel AI Gateway"],
172
- ].find(([name]) => has(name));
187
+ ["OPENCODE_API_KEY", "Jev is called on OpenCode Zen (jev-1.13)"],
188
+ ["CLOUDFLARE_API_KEY", "Jev is called on Cloudflare Workers AI", "CLOUDFLARE_ACCOUNT_ID"],
189
+ ].find(([name, , also]) => has(name) && (!also || has(also)));
173
190
  row(
174
- route ? "ok" : "fix",
191
+ route ? "ok" : "--",
175
192
  "jev key",
176
193
  route
177
194
  ? `${route[0]} is set: ${route[1]} (value not shown)`
178
- : `missing: add TYPESAFE_API_KEY (or MU_JUDGE_OPENROUTER_API_KEY, or AI_GATEWAY_API_KEY) ${where}`,
195
+ : `none set: Jev 1.13 on OpenCode Zen answers, free for a limited time (what it judges goes to OpenCode). For your own key, add TYPESAFE_API_KEY (or MU_JUDGE_OPENROUTER_API_KEY, AI_GATEWAY_API_KEY, OPENCODE_API_KEY) ${where}`,
179
196
  );
180
197
  } else {
181
198
  const name = judge.apiKeyEnv ?? (judge.type === "gateway" ? "AI_GATEWAY_API_KEY" : "TYPESAFE_API_KEY");
@@ -198,6 +215,35 @@ if (jevTier) {
198
215
  }
199
216
  }
200
217
 
218
+ // Classifier models of pi's catalog (Jev on OpenCode Zen or Cloudflare, Clef, …), for the tiers and routes that use them.
219
+ const classifierOf = (tier) =>
220
+ tier.startsWith("classifier:")
221
+ ? { type: "classifier", model: tier.slice("classifier:".length) }
222
+ : (config?.judges?.[tier] ?? JEV_ROUTES[tier]);
223
+ const askedTiers = [
224
+ ...tiers,
225
+ ...Object.values(config?.routes ?? {}).flatMap((value) => (Array.isArray(value) ? value : String(value).split(","))),
226
+ ].map((tier) => String(tier).trim());
227
+ for (const model of new Set(askedTiers.map(classifierOf).filter((judge) => judge?.type === "classifier").map((judge) => judge.model))) {
228
+ const provider = String(model ?? "").split("/")[0];
229
+ // OpenCode's free models answer without a key (the client sends "public", as OpenCode's own does).
230
+ const names = provider === "opencode" && String(model).endsWith("-free") ? [] : CLASSIFIER_KEYS[provider];
231
+ if (!model?.includes("/")) {
232
+ row("fix", "classifier", `${model ?? "a classifier judge"} needs a model written "provider/model-id"`);
233
+ } else if (!names) {
234
+ row("--", "classifier", `${model}: a provider of your own; its key is the one models.json names`);
235
+ } else if (names.every(has)) {
236
+ row("ok", "classifier", `${model}: ${names.length > 0 ? `${names.join(", ")} set (value not shown)` : "no key needed"}`);
237
+ } else {
238
+ const unset = names.filter((name) => !has(name));
239
+ row(
240
+ authBytes > 8 ? "--" : "fix",
241
+ "classifier",
242
+ `${model}: ${unset.join(" and ")} not set${authBytes > 8 ? `; a key stored with /login ${provider} works too (not read here)` : `: add ${unset.join(", ")} ${where}, or store a key with /login ${provider}`}`,
243
+ );
244
+ }
245
+ }
246
+
201
247
  // CLM-8B behind `clm-serve` (github.com/Contrastive-LM/CLM), for the tiers and routes that use it.
202
248
  /** As packages/kyrn-judge/src/providers/typesafe.ts reads a CLM address: `http://host:8700` is enough. */
203
249
  function clmEndpoint(baseUrl) {
@@ -271,7 +317,11 @@ row(
271
317
  );
272
318
  for (const line of moreAdvice) row("--", "", line);
273
319
  const canRelate = (tier) =>
274
- tier.startsWith("jev") || tier === "gateway" || tier.startsWith("llm:") || ["llm", "clm"].includes(judgeOf(tier)?.type);
320
+ tier.startsWith("jev") ||
321
+ tier === "gateway" ||
322
+ tier.startsWith("llm:") ||
323
+ tier.startsWith("classifier:") ||
324
+ ["llm", "clm", "classifier"].includes(judgeOf(tier)?.type);
275
325
  const browseTiers = config?.routes?.["browser.step"] ?? tiers;
276
326
  const routed = Object.entries(config?.routes ?? {});
277
327
  if (routed.length > 0) row("--", "routes", routed.map(([id, value]) => `${id} -> ${[value].flat().join(" > ")}`).join(" · "));
package/kyrn/bin/mu.mjs CHANGED
@@ -339,35 +339,19 @@ export function envFilePath({ layout, root, muDir, platform }) {
339
339
  }
340
340
 
341
341
  /**
342
- * The JavaScript file behind the `tsx` command. node_modules/.bin/tsx is a `.cmd` shim on Windows, and a shim
343
- * can only be started through a shell, where a prompt with quotes or `&` in it is re-parsed. Running the real
344
- * entry with the Node that runs this file avoids the shell on every platform.
342
+ * Whether a checkout's dependencies are installed: undici, which pi and the judgment layer both depend on, is found
343
+ * the way Node resolves an import: here, then in every parent. A git worktree of this repository kept under the
344
+ * main checkout (as the agent worktrees are) has no node_modules of its own and runs on the main checkout's,
345
+ * exactly as its imports do.
345
346
  */
346
- export function resolveTsx({ root, platform, exists, readFile }) {
347
+ export function dependenciesInstalled({ root, platform, exists }) {
347
348
  const path = pathFor(platform);
348
- // Looked for the way Node resolves an import: here, then in every parent. A git worktree of this repository
349
- // kept under the main checkout (as the agent worktrees are) has no node_modules of its own and runs on the
350
- // main checkout's, exactly as its imports do.
351
349
  for (let dir = root; ; dir = path.dirname(dir)) {
352
- const entry = tsxEntry(path.join(dir, "node_modules", "tsx"), path, exists, readFile);
353
- if (entry) return entry;
354
- if (path.dirname(dir) === dir) return undefined;
350
+ if (exists(path.join(dir, "node_modules", "undici", "package.json"))) return true;
351
+ if (path.dirname(dir) === dir) return false;
355
352
  }
356
353
  }
357
354
 
358
- function tsxEntry(dir, path, exists, readFile) {
359
- let bin;
360
- try {
361
- bin = JSON.parse(readFile(path.join(dir, "package.json"))).bin;
362
- } catch {
363
- return undefined;
364
- }
365
- const relative = typeof bin === "string" ? bin : bin?.tsx;
366
- if (typeof relative !== "string") return undefined;
367
- const entry = path.join(dir, ...relative.split("/").filter((part) => part && part !== "."));
368
- return exists(entry) ? entry : undefined;
369
- }
370
-
371
355
  export function installHint({ root, platform }) {
372
356
  const steps = [`cd ${root}`, "npm ci --ignore-scripts", "npm run hydrate:model-data"];
373
357
  // Windows PowerShell 5 has no `&&`.
@@ -376,22 +360,24 @@ export function installHint({ root, platform }) {
376
360
  : `mu's dependencies are not installed. Run: ${steps.join(" && ")}`;
377
361
  }
378
362
 
363
+ /** What mu says on a Node that does not strip TypeScript types, which a checkout cannot run on. */
364
+ const NO_TYPE_STRIPPING =
365
+ "mu runs a checkout's TypeScript with Node's own type stripping (on by default from Node 22.18), and this Node does not strip types";
366
+
379
367
  /**
380
- * Node's arguments for running a checkout's TypeScript, up to the entry file. A Node that strips types itself (on
381
- * by default from 22.18) runs the sources as they are, with pi's own source resolver
382
- * (packages/coding-agent/src/experimental/source-resolver.ts: each workspace package resolves to its sources, as
383
- * tsconfig.json's paths say) and Node's compile cache (compile-cache.mjs). tsx runs its loader on a thread of its
384
- * own and hands every file over from there: pi with the judgment layer took 2 s to start that way, about 0.85 s
385
- * this way, and a checkout starts mu for every conversation the desktop app opens. A runtime that does not strip
386
- * types (`stripsTypes` false; an Electron that runs mu as Node may not), or a checkout from before the resolver,
387
- * still goes through tsx. tsx is one of the checkout's dependencies either way: without it they are not installed.
368
+ * Node's arguments for running a checkout's TypeScript, up to the entry file. Node strips the types itself (on by
369
+ * default from 22.18, in both Electrons the desktop app runs mu with too) and runs the sources as they are, with
370
+ * pi's own source resolver (packages/coding-agent/src/experimental/source-resolver.ts: each workspace package
371
+ * resolves to its sources, as tsconfig.json's paths say) and Node's compile cache (compile-cache.mjs), the way pi
372
+ * runs its own checkout (pi-test.sh). A runtime that does not strip types, a checkout whose dependencies are not
373
+ * installed and one without the resolver are each said, not left to a failed import.
388
374
  */
389
- export function sourceRuntime({ root, platform, stripsTypes, exists, readFile }) {
375
+ export function sourceRuntime({ root, platform, stripsTypes, exists }) {
390
376
  const path = pathFor(platform);
391
- const tsx = resolveTsx({ root, platform, exists, readFile });
392
- if (!tsx) return { error: installHint({ root, platform }) };
377
+ if (!stripsTypes) return { error: NO_TYPE_STRIPPING };
378
+ if (!dependenciesInstalled({ root, platform, exists })) return { error: installHint({ root, platform }) };
393
379
  const resolver = path.join(root, "packages", "coding-agent", "src", "experimental", "source-resolver.ts");
394
- if (!stripsTypes || !exists(resolver)) return { args: [tsx, "--tsconfig", path.join(root, "tsconfig.json")] };
380
+ if (!exists(resolver)) return { error: `pi's source resolver is missing from this checkout (${resolver})` };
395
381
  // As URLs: `--import` reads a Windows path such as C:\... as a URL whose scheme is c:.
396
382
  const url = (file) => pathToFileURL(file, { windows: platform === "win32" }).href;
397
383
  return {
@@ -458,6 +444,17 @@ export function launchStrategy({ platform, env, canExec }) {
458
444
  return "exec";
459
445
  }
460
446
 
447
+ /** How the judgment layer's extension joins pi's arguments: in front for a session, never in front of pi's own
448
+ * commands (PI_COMMANDS), which pi reads as its first argument — an -e before them would turn them into a prompt.
449
+ * The judgment layer never runs for them, so its extension stays out of their way. */
450
+ function judgeArgs({ argv, layout, root, platform }) {
451
+ if (PI_COMMANDS.has(argv[0])) return [];
452
+ const path = pathFor(platform);
453
+ return layout === "package"
454
+ ? ["-e", packageEntries({ root, platform }).extension]
455
+ : ["-e", path.join(root, "packages", "kyrn-judge", "src", "extension", "kyrn-judge.ts")];
456
+ }
457
+
461
458
  /**
462
459
  * Everything about starting pi, decided without touching anything: the command, its arguments as an array
463
460
  * (never a shell string) and the child's whole environment.
@@ -484,16 +481,11 @@ export function planLaunch({
484
481
  if (!fs.exists(files.extension)) {
485
482
  return { error: `This mu-agent package is incomplete (${files.extension} is missing). Reinstall it: npm i -g mu-agent` };
486
483
  }
487
- entry = [files.cli, "-e", files.extension];
484
+ entry = [files.cli];
488
485
  } else {
489
- const runtime = sourceRuntime({ root, platform, stripsTypes, exists: fs.exists, readFile: fs.readFile });
486
+ const runtime = sourceRuntime({ root, platform, stripsTypes, exists: fs.exists });
490
487
  if (runtime.error) return { error: runtime.error };
491
- entry = [
492
- ...runtime.args,
493
- path.join(root, "packages", "coding-agent", "src", "experimental", "cli.ts"),
494
- "-e",
495
- path.join(root, "packages", "kyrn-judge", "src", "extension", "kyrn-judge.ts"),
496
- ];
488
+ entry = [...runtime.args, path.join(root, "packages", "coding-agent", "src", "experimental", "cli.ts")];
497
489
  }
498
490
 
499
491
  const muDir = muHome({ home, platform, isDir: fs.isDir });
@@ -541,7 +533,7 @@ export function planLaunch({
541
533
 
542
534
  return {
543
535
  command: execPath,
544
- args: [...entry, ...argv],
536
+ args: [...entry, ...judgeArgs({ argv, layout, root, platform }), ...argv],
545
537
  env: childEnv,
546
538
  strategy: launchStrategy({ platform, env, canExec }),
547
539
  layout,
@@ -560,8 +552,7 @@ export function planLaunch({
560
552
  * Node flags that process starts with, pi's arguments (the judgment layer, then `argv`) and its whole environment.
561
553
  * The app's pi and the command line's are then one: the same files, settings, sign-ins and keys.
562
554
  *
563
- * A checkout runs in such a process only on a Node that strips TypeScript types itself, with pi's source resolver:
564
- * tsx cannot be put in front of a module another program imports. Returns { error } otherwise.
555
+ * A checkout runs there as it runs on the command line (sourceRuntime). Returns { error } when pi cannot run.
565
556
  */
566
557
  export function planHost({ platform, env, argv, root, home, fs, wsl = false, stripsTypes = true }) {
567
558
  const path = pathFor(platform);
@@ -581,22 +572,16 @@ export function planHost({ platform, env, argv, root, home, fs, wsl = false, str
581
572
  ...common,
582
573
  module: path.join(root, "dist", "bundle", "index.js"),
583
574
  execArgv: [],
584
- args: ["-e", packageEntries({ root, platform }).extension, ...argv],
575
+ args: [...judgeArgs({ argv, layout: launch.layout, root, platform }), ...argv],
585
576
  };
586
577
  }
587
- const resolver = path.join(root, "packages", "coding-agent", "src", "experimental", "source-resolver.ts");
588
- if (!stripsTypes || !fs.exists(resolver)) {
589
- return {
590
- error: `pi's sources run inside another program only on a Node that strips TypeScript types itself (22.18 or newer), with pi's source resolver (${resolver})`,
591
- };
592
- }
593
- const runtime = sourceRuntime({ root, platform, stripsTypes, exists: fs.exists, readFile: fs.readFile });
578
+ const runtime = sourceRuntime({ root, platform, stripsTypes, exists: fs.exists });
594
579
  if (runtime.error) return { error: runtime.error };
595
580
  return {
596
581
  ...common,
597
582
  module: path.join(root, "packages", "coding-agent", "src", "index.ts"),
598
583
  execArgv: runtime.args,
599
- args: ["-e", path.join(root, "packages", "kyrn-judge", "src", "extension", "kyrn-judge.ts"), ...argv],
584
+ args: [...judgeArgs({ argv, layout: launch.layout, root, platform }), ...argv],
600
585
  };
601
586
  }
602
587
 
@@ -671,7 +656,7 @@ export function planAuth({ platform, env, argv, root, home, execPath, fs, canExe
671
656
  }
672
657
  entry = [auth];
673
658
  } else {
674
- const runtime = sourceRuntime({ root, platform, stripsTypes, exists: fs.exists, readFile: fs.readFile });
659
+ const runtime = sourceRuntime({ root, platform, stripsTypes, exists: fs.exists });
675
660
  if (runtime.error) return { error: runtime.error };
676
661
  entry = [...runtime.args, path.join(root, "packages", "kyrn-judge", "src", "auth", "main.ts")];
677
662
  }
@@ -705,8 +690,7 @@ export function planJudge({ platform, env, argv, bin, wsl = false }) {
705
690
  /**
706
691
  * `mu import`: Claude Code and Codex conversations into mu's sessions (packages/kyrn-judge/src/import). The importer
707
692
  * needs nothing but Node: the npm package runs its build, judge/dist/import.js, and a checkout its TypeScript with
708
- * Node's own type stripping (on by default from 22.18). A runtime that does not strip types (`stripsTypes` false;
709
- * an Electron that runs mu as Node may not) takes the sources through tsx, as pi runs in a checkout.
693
+ * Node's own type stripping (on by default from 22.18).
710
694
  */
711
695
  export function planImport({ platform, env, argv, root, home, execPath, fs, stripsTypes = true }) {
712
696
  const path = pathFor(platform);
@@ -720,12 +704,8 @@ export function planImport({ platform, env, argv, root, home, execPath, fs, stri
720
704
  } else {
721
705
  const source = path.join(root, "packages", "kyrn-judge", "src", "import", "cli.ts");
722
706
  if (!fs.exists(source)) return { error: `mu import is missing from this checkout (${source})` };
723
- if (stripsTypes) entry = ["--disable-warning=ExperimentalWarning", source];
724
- else {
725
- const tsx = resolveTsx({ root, platform, exists: fs.exists, readFile: fs.readFile });
726
- if (!tsx) return { error: installHint({ root, platform }) };
727
- entry = [tsx, "--tsconfig", path.join(root, "tsconfig.json"), source];
728
- }
707
+ if (!stripsTypes) return { error: NO_TYPE_STRIPPING };
708
+ entry = ["--disable-warning=ExperimentalWarning", source];
729
709
  }
730
710
  const agentDir = agentDirFor({ env, muDir: muHome({ home, platform, isDir: fs.isDir }), platform });
731
711
  const childEnv = {};
@@ -763,6 +743,8 @@ export const MODEL_KEY_VARIABLES = [
763
743
  "ANTHROPIC_AUTH_TOKEN",
764
744
  "ANTHROPIC_OAUTH_TOKEN",
765
745
  "ANTHROPIC_API_KEY",
746
+ // Anthropic's workload identity federation needs three variables together; its rule id stands for them.
747
+ "ANTHROPIC_FEDERATION_RULE_ID",
766
748
  "ANT_LING_API_KEY",
767
749
  "QWEN_TOKEN_PLAN_API_KEY",
768
750
  "QWEN_TOKEN_PLAN_CN_API_KEY",
@@ -816,7 +798,7 @@ export function planSetup({ platform, env, argv, root, home, execPath, fs, strip
816
798
  }
817
799
  entry = [setup];
818
800
  } else {
819
- const runtime = sourceRuntime({ root, platform, stripsTypes, exists: fs.exists, readFile: fs.readFile });
801
+ const runtime = sourceRuntime({ root, platform, stripsTypes, exists: fs.exists });
820
802
  if (runtime.error) return { error: runtime.error };
821
803
  entry = [...runtime.args, path.join(root, "packages", "kyrn-judge", "src", "setup", "main.ts")];
822
804
  }
@@ -846,8 +828,41 @@ export function planSetup({ platform, env, argv, root, home, execPath, fs, strip
846
828
  return { command: execPath, args: [...entry, ...args], env: childEnv, strategy: "spawn", agentDir, keyGiven: key !== undefined };
847
829
  }
848
830
 
849
- /** pi's own commands: none of them starts a session. */
850
- const PI_COMMANDS = new Set(["install", "remove", "uninstall", "update", "list", "config", "auth"]);
831
+ /** pi's own commands, read from its first argument: none of them starts a session. */
832
+ const PI_COMMANDS = new Set(["install", "remove", "uninstall", "update", "list", "config", "auth", "mcp"]);
833
+
834
+ /** Options of `pi mcp add` that take a value (extensions/mcp/cli.ts); the rest are flags. */
835
+ const MCP_ADD_VALUES = new Set([
836
+ "--url",
837
+ "--env",
838
+ "--cwd",
839
+ "--header",
840
+ "--bearer-token-env-var",
841
+ "--oauth-client-id",
842
+ "--oauth-client-secret",
843
+ "--oauth-callback-port",
844
+ "--oauth-client-name",
845
+ "--exposure",
846
+ "--description",
847
+ ]);
848
+
849
+ /**
850
+ * `mu mcp add` without `--exposure`: the server's tools are `deferred`, loaded by tool_search when a task needs them,
851
+ * instead of pi's default `codemode`, which reaches them only from scripts. Like pi, the options end at `--` or at the
852
+ * second positional argument; what follows belongs to the server's command.
853
+ */
854
+ export function mcpAddDefaults(argv) {
855
+ if (argv[0] !== "mcp" || argv[1] !== "add") return argv;
856
+ let positionals = 0;
857
+ for (let index = 2; index < argv.length && positionals < 2; index++) {
858
+ const arg = argv[index];
859
+ if (arg === "--") break;
860
+ if (arg === "--exposure") return argv;
861
+ if (MCP_ADD_VALUES.has(arg)) index++;
862
+ else if (!arg.startsWith("-")) positionals++;
863
+ }
864
+ return [...argv.slice(0, 2), "--exposure", "deferred", ...argv.slice(2)];
865
+ }
851
866
  /** Options for a run without a person (-p, --mode rpc), one that ends at once, or one that names its model itself. */
852
867
  const NO_SETUP_FLAGS = new Set([
853
868
  "-p",
@@ -1436,7 +1451,7 @@ export async function main(argv = process.argv.slice(2)) {
1436
1451
  return handOver({ command: plan.command, args: plan.args, env: plan.env, strategy });
1437
1452
  }
1438
1453
  // What the session gets, when there is one: after a `mu setup` that ends in "start mu now", a plain session.
1439
- let sessionArgv = argv;
1454
+ let sessionArgv = mcpAddDefaults(argv);
1440
1455
  if (command === "setup") {
1441
1456
  const plan = planSetup({
1442
1457
  platform,
@@ -1508,7 +1523,7 @@ export async function main(argv = process.argv.slice(2)) {
1508
1523
  return 0;
1509
1524
  }
1510
1525
  // Asked before `version` too, as it always was: a checkout without its dependencies says so at the first command.
1511
- if (layout === "repo" && !resolveTsx({ root, platform, exists: existsSync, readFile: readText })) {
1526
+ if (layout === "repo" && !dependenciesInstalled({ root, platform, exists: existsSync })) {
1512
1527
  err(installHint({ root, platform }));
1513
1528
  return 1;
1514
1529
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mu-agent",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "mu: a coding agent that thinks before it acts. A small, fast judge makes the routine calls; the big model keeps its attention for the work. Built on pi.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -33,13 +33,13 @@
33
33
  "node": ">=22.19.0"
34
34
  },
35
35
  "dependencies": {
36
- "@earendil-works/chord": "0.87.1",
36
+ "@earendil-works/chord": "1.0.2",
37
37
  "@silvia-odwyer/photon-node": "0.3.4",
38
38
  "jiti": "2.7.0"
39
39
  },
40
40
  "muBuild": {
41
- "pi": "0.87.1",
41
+ "pi": "1.0.2",
42
42
  "judge": "0.1.0",
43
- "commit": "c645b9c64"
43
+ "commit": "a63b81be9"
44
44
  }
45
45
  }
@@ -1,6 +0,0 @@
1
- import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url);
2
- import{buildCopilotDynamicHeaders,hasCopilotVisionInput}from"./chunk-PGXDEOVV.js";import{Anthropic}from"./chunk-DTD7JQ7Y.js";import{retryProviderRequest}from"./chunk-XNGRGP62.js";import{adjustMaxTokensForThinking,buildBaseOptions,clampMaxTokensToContext,getJsonSchemaToolParameters,getPiUserAgent,resolveJsonSchemaStrictSampling,transformMessages}from"./chunk-GNYZK6XN.js";import{sanitizeSurrogates}from"./chunk-L2ZPNLYD.js";import{headersToRecord}from"./chunk-UTB4DTYQ.js";import{getProviderEnvValue}from"./chunk-DRQDKNXA.js";import{parseJsonWithRepair,parseStreamingJson}from"./chunk-TRDNDS6A.js";import{calculateCost,getCurrentTools,getDeclaredTools,getInitialSystemMessage,getSystemMessageText,hasToolRedefinitions,renderSystemMessageUpdate,resolveTranscript}from"./chunk-FU4XQUSL.js";import{AssistantMessageEventStream,appendAssistantMessageDiagnostic}from"./chunk-A3JYRWB6.js";import"./chunk-4L3WN2XY.js";function resolveCacheRetention(cacheRetention,env){return cacheRetention||(getProviderEnvValue("PI_CACHE_RETENTION",env)==="long"?"long":"short")}function getCacheControl(model,cacheRetention,env){let retention=resolveCacheRetention(cacheRetention,env);if(retention==="none")return{retention};let ttl=retention==="long"&&getAnthropicCompat(model).supportsLongCacheRetention?"1h":void 0;return{retention,cacheControl:{type:"ephemeral",...ttl&&{ttl}}}}var claudeCodeVersion="2.1.280",claudeCodeTools=["Read","Write","Edit","Bash","Grep","Glob","AskUserQuestion","EnterPlanMode","ExitPlanMode","KillShell","NotebookEdit","Skill","Task","TaskOutput","TodoWrite","WebFetch","WebSearch"],ccToolLookup=new Map(claudeCodeTools.map(t=>[t.toLowerCase(),t])),toClaudeCodeName=name=>ccToolLookup.get(name.toLowerCase())??name,fromClaudeCodeName=(name,tools)=>{if(tools&&tools.length>0){let lowerName=name.toLowerCase(),matchedTool=tools.find(tool=>tool.name.toLowerCase()===lowerName);if(matchedTool)return matchedTool.name}return name};function convertContentBlocks(content){if(!content.some(c=>c.type==="image"))return sanitizeSurrogates(content.map(c=>c.text).join(`
3
- `));let blocks=content.map(block=>block.type==="text"?{type:"text",text:sanitizeSurrogates(block.text)}:{type:"image",source:{type:"base64",media_type:block.mimeType,data:block.data}});return blocks.some(b=>b.type==="text")||blocks.unshift({type:"text",text:"(see attached image)"}),blocks}var FINE_GRAINED_TOOL_STREAMING_BETA="fine-grained-tool-streaming-2025-05-14",INTERLEAVED_THINKING_BETA="interleaved-thinking-2025-05-14",SERVER_SIDE_FALLBACK_BETA="server-side-fallback-2026-07-01",MID_CONVERSATION_OUTPUT_CONFIG_BETA="mid-conversation-output-config-2026-07-01",THINKING_BINDING_CONTROLS_BETA="thinking-binding-controls-2026-08-01",MID_CONVERSATION_TOOL_CHANGES_BETA="mid-conversation-tool-changes-2026-07-01",DEFERRED_TOOL_PLACEHOLDER={name:"__pi_deferred_placeholder__",description:"Reserved placeholder. Never available. Never call this.",input_schema:{type:"object",properties:{},required:[]},defer_loading:!0};function shouldUseServerSideFallbackBeta(model){return(model.compat?.allowedFallbackModels?.length??0)>0}function getAnthropicCompat(model){let isOpenRouter=model.provider==="openrouter"||model.baseUrl.includes("openrouter.ai");return{supportsEagerToolInputStreaming:model.compat?.supportsEagerToolInputStreaming??!0,supportsLongCacheRetention:model.compat?.supportsLongCacheRetention??!0,sendSessionAffinityHeaders:model.compat?.sendSessionAffinityHeaders??isOpenRouter,sessionAffinityFormat:model.compat?.sessionAffinityFormat??(isOpenRouter?"openrouter":void 0),supportsCacheControlOnTools:model.compat?.supportsCacheControlOnTools??!0,supportsTemperature:model.compat?.supportsTemperature??!0,allowEmptySignature:model.compat?.allowEmptySignature??!1,supportsStrictTools:model.compat?.supportsStrictTools??!1,supportsMidConvoSystemMessages:model.compat?.supportsMidConvoSystemMessages??!1,supportsMidConvoToolChanges:model.compat?.supportsMidConvoToolChanges??!1}}function mergeHeaders(...headerSources){let merged={};for(let headers of headerSources)headers&&Object.assign(merged,headers);return merged}function mergeClientHeaders(...headerSources){return mergeHeaders({"User-Agent":getPiUserAgent()},...headerSources)}function hasHeader(headers,name){if(!headers)return!1;let expected=name.toLowerCase();for(let[key,value]of Object.entries(headers))if(key.toLowerCase()===expected&&value!==null&&value.trim().length>0)return!0;return!1}function assertRequestAuth(provider,apiKey,headers){if(!apiKey&&!(hasHeader(headers,"authorization")||hasHeader(headers,"x-api-key")||hasHeader(headers,"cf-aig-authorization")))throw new Error(`No API key for provider: ${provider}`)}var ANTHROPIC_MESSAGE_EVENTS=new Set(["message_start","message_delta","message_stop","content_block_start","content_block_delta","content_block_stop"]);function flushSseEvent(state){if(!state.event&&state.data.length===0)return null;let event={event:state.event,data:state.data.join(`
4
- `),raw:[...state.raw]};return state.event=null,state.data=[],state.raw=[],event}function decodeSseLine(line,state){if(line==="")return flushSseEvent(state);if(state.raw.push(line),line.startsWith(":"))return null;let delimiterIndex=line.indexOf(":"),fieldName=delimiterIndex===-1?line:line.slice(0,delimiterIndex),value=delimiterIndex===-1?"":line.slice(delimiterIndex+1);return value.startsWith(" ")&&(value=value.slice(1)),fieldName==="event"?state.event=value:fieldName==="data"&&state.data.push(value),null}function nextLineBreakIndex(text){let carriageReturnIndex=text.indexOf("\r"),newlineIndex=text.indexOf(`
5
- `);return carriageReturnIndex===-1?newlineIndex:newlineIndex===-1?carriageReturnIndex:Math.min(carriageReturnIndex,newlineIndex)}function consumeLine(text){let lineBreakIndex=nextLineBreakIndex(text);if(lineBreakIndex===-1)return null;let nextIndex=lineBreakIndex+1;return text[lineBreakIndex]==="\r"&&text[nextIndex]===`
6
- `&&(nextIndex+=1),{line:text.slice(0,lineBreakIndex),rest:text.slice(nextIndex)}}async function*iterateSseMessages(body,signal){let reader=body.getReader(),decoder=new TextDecoder,state={event:null,data:[],raw:[]},buffer="";try{for(;;){if(signal?.aborted)throw new Error("Request was aborted");let{value,done}=await reader.read();if(done)break;buffer+=decoder.decode(value,{stream:!0});let consumed2=consumeLine(buffer);for(;consumed2;){buffer=consumed2.rest;let event=decodeSseLine(consumed2.line,state);event&&(yield event),consumed2=consumeLine(buffer)}}buffer+=decoder.decode();let consumed=consumeLine(buffer);for(;consumed;){buffer=consumed.rest;let event=decodeSseLine(consumed.line,state);event&&(yield event),consumed=consumeLine(buffer)}if(buffer.length>0){let event=decodeSseLine(buffer,state);event&&(yield event)}let trailingEvent=flushSseEvent(state);trailingEvent&&(yield trailingEvent)}finally{reader.releaseLock()}}async function*iterateAnthropicEvents(response,signal){if(!response.body)throw new Error("Attempted to iterate over an Anthropic response with no body");let sawMessageStart=!1,sawMessageEnd=!1;for await(let sse of iterateSseMessages(response.body,signal)){if(sse.event==="error")throw new Error(sse.data);if(ANTHROPIC_MESSAGE_EVENTS.has(sse.event??""))try{let event=parseJsonWithRepair(sse.data);event.type==="message_start"?sawMessageStart=!0:event.type==="message_stop"&&(sawMessageEnd=!0),yield event}catch(error){let message=error instanceof Error?error.message:String(error);throw new Error(`Could not parse Anthropic SSE event ${sse.event}: ${message}; data=${sse.data}; raw=${sse.raw.join("\\n")}`)}}if(sawMessageStart&&!sawMessageEnd)throw new Error("Anthropic stream ended before message_stop")}var stream=(model,context,options)=>{let stream2=new AssistantMessageEventStream,normalizedContext=resolveTranscript(context,getAnthropicCompat(model).supportsMidConvoSystemMessages),currentTools=getCurrentTools(normalizedContext.messages);return(async()=>{let providerThinkingLevel=model.compat?.supportsMidConvoEffort?options?.effort??"high":void 0,output={role:"assistant",content:[],api:model.api,provider:model.provider,model:model.id,...providerThinkingLevel===void 0?{}:{providerThinkingLevel},usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"pending",timestamp:Date.now()};try{let client,isOAuth,usageModel=model,inputTransformations;if(options?.client)client=options.client,isOAuth=!1;else{let apiKey=options?.apiKey;assertRequestAuth(model.provider,apiKey,options?.headers);let copilotDynamicHeaders;if(model.provider==="github-copilot"){let hasImages=hasCopilotVisionInput(normalizedContext.messages);copilotDynamicHeaders=buildCopilotDynamicHeaders({messages:normalizedContext.messages,hasImages})}let cacheSessionId=resolveCacheRetention(options?.cacheRetention,options?.env)==="none"?void 0:options?.sessionId,created=createClient(model,apiKey,options?.headers,options?.fetch,copilotDynamicHeaders,cacheSessionId);client=created.client,isOAuth=created.isOAuthToken}let params=buildParams(model,normalizedContext,isOAuth,options),nextParams=await options?.onPayload?.(params,model);nextParams!==void 0&&(params={...nextParams,stream:!0});let requestOptions={...options?.signal?{signal:options.signal}:{},...options?.timeoutMs!==void 0?{timeout:options.timeoutMs}:{},maxRetries:0},response=await retryProviderRequest(()=>client.beta.messages.create(params,requestOptions).asResponse(),{maxRetries:options?.maxRetries,maxRetryDelayMs:options?.maxRetryDelayMs,signal:options?.signal});await options?.onResponse?.({status:response.status,headers:headersToRecord(response.headers)},model),stream2.push({type:"start",partial:output});let blocks=output.content;for await(let event of iterateAnthropicEvents(response,options?.signal))if(await options?.onProviderStreamEvent?.(event,model),event.type==="message_start"){output.responseId=event.message.id;let transformations=event.message.input_transformations;Array.isArray(transformations)&&(inputTransformations=transformations);let responseModel=event.message.model;responseModel!==model.id&&(output.responseModel=responseModel);let fallbackCost=responseModel===model.id?void 0:model.compat?.allowedFallbackModels?.find(fallback=>fallback.provider===model.provider&&fallback.model===responseModel)?.cost;usageModel=fallbackCost?{...model,id:responseModel,cost:fallbackCost}:model,output.usage.input=event.message.usage.input_tokens||0,output.usage.output=event.message.usage.output_tokens||0,output.usage.cacheRead=event.message.usage.cache_read_input_tokens||0,output.usage.cacheWrite=event.message.usage.cache_creation_input_tokens||0,output.usage.cacheWrite1h=event.message.usage.cache_creation?.ephemeral_1h_input_tokens||0,output.usage.totalTokens=output.usage.input+output.usage.output+output.usage.cacheRead+output.usage.cacheWrite,calculateCost(usageModel,output.usage)}else if(event.type==="content_block_start"){if(event.content_block.type==="fallback"){if(output.content.length>0)throw new Error("Anthropic performed an unsupported mid-output model fallback");continue}if(event.content_block.type==="text"){let block={type:"text",text:event.content_block.text??"",index:event.index};output.content.push(block),stream2.push({type:"text_start",contentIndex:output.content.length-1,partial:output})}else if(event.content_block.type==="thinking"){let block={type:"thinking",thinking:event.content_block.thinking??"",thinkingSignature:event.content_block.signature??"",index:event.index};output.content.push(block),stream2.push({type:"thinking_start",contentIndex:output.content.length-1,partial:output})}else if(event.content_block.type==="redacted_thinking"){let block={type:"thinking",thinking:"[Reasoning redacted]",thinkingSignature:event.content_block.data,redacted:!0,index:event.index};output.content.push(block),stream2.push({type:"thinking_start",contentIndex:output.content.length-1,partial:output})}else if(event.content_block.type==="tool_use"){let block={type:"toolCall",id:event.content_block.id,name:isOAuth?fromClaudeCodeName(event.content_block.name,currentTools):event.content_block.name,arguments:event.content_block.input??{},partialJson:"",index:event.index};output.content.push(block),stream2.push({type:"toolcall_start",contentIndex:output.content.length-1,partial:output})}}else if(event.type==="content_block_delta"){if(event.delta.type==="text_delta"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&block.type==="text"&&(block.text+=event.delta.text,stream2.push({type:"text_delta",contentIndex:index,delta:event.delta.text,partial:output}))}else if(event.delta.type==="thinking_delta"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&block.type==="thinking"&&(block.thinking+=event.delta.thinking,stream2.push({type:"thinking_delta",contentIndex:index,delta:event.delta.thinking,partial:output}))}else if(event.delta.type==="input_json_delta"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&block.type==="toolCall"&&(block.partialJson+=event.delta.partial_json,block.arguments=parseStreamingJson(block.partialJson),stream2.push({type:"toolcall_delta",contentIndex:index,delta:event.delta.partial_json,partial:output}))}else if(event.delta.type==="signature_delta"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&block.type==="thinking"&&(block.thinkingSignature=block.thinkingSignature||"",block.thinkingSignature+=event.delta.signature)}}else if(event.type==="content_block_stop"){let index=blocks.findIndex(b=>b.index===event.index),block=blocks[index];block&&(delete block.index,block.type==="text"?stream2.push({type:"text_end",contentIndex:index,content:block.text,partial:output}):block.type==="thinking"?stream2.push({type:"thinking_end",contentIndex:index,content:block.thinking,partial:output}):block.type==="toolCall"&&(block.arguments=parseStreamingJson(block.partialJson),delete block.partialJson,stream2.push({type:"toolcall_end",contentIndex:index,toolCall:block,partial:output})))}else if(event.type==="message_delta"){let transformations=event.input_transformations;if(Array.isArray(transformations)&&(inputTransformations=transformations),event.delta.stop_reason){output.rawStopReason=event.delta.stop_reason;let stopReasonResult=mapStopReason(event.delta.stop_reason,event.delta.stop_details);output.stopReason=stopReasonResult.stopReason,stopReasonResult.errorMessage&&(output.errorMessage=stopReasonResult.errorMessage)}if(event.usage){event.usage.input_tokens!=null&&(output.usage.input=event.usage.input_tokens),event.usage.output_tokens!=null&&(output.usage.output=event.usage.output_tokens),event.usage.cache_read_input_tokens!=null&&(output.usage.cacheRead=event.usage.cache_read_input_tokens),event.usage.cache_creation_input_tokens!=null&&(output.usage.cacheWrite=event.usage.cache_creation_input_tokens);let cacheCreation=event.usage.cache_creation;cacheCreation?.ephemeral_1h_input_tokens!=null&&(output.usage.cacheWrite1h=cacheCreation.ephemeral_1h_input_tokens);let thinkingTokens=event.usage.output_tokens_details?.thinking_tokens;thinkingTokens!=null&&(output.usage.reasoning=thinkingTokens)}output.usage.totalTokens=output.usage.input+output.usage.output+output.usage.cacheRead+output.usage.cacheWrite,calculateCost(usageModel,output.usage)}if(options?.signal?.aborted)throw new Error("Request was aborted");if(output.stopReason==="pending")throw new Error("Anthropic stream ended without a stop reason");if(output.stopReason==="aborted"||output.stopReason==="error")throw new Error(output.errorMessage||"An unknown error occurred");inputTransformations&&inputTransformations.length>0&&appendAssistantMessageDiagnostic(output,{type:"anthropic_input_transformations",timestamp:Date.now(),details:{transformations:inputTransformations.map(transformation=>({type:transformation.type??void 0,path:transformation.path??void 0,reason:transformation.reason??void 0}))}}),stream2.push({type:"done",reason:output.stopReason,message:output}),stream2.end()}catch(error){for(let block of output.content)delete block.index,delete block.partialJson;output.stopReason=options?.signal?.aborted?"aborted":"error",output.errorMessage=error instanceof Error?error.message:JSON.stringify(error),stream2.push({type:"error",reason:output.stopReason,error:output}),stream2.end()}})(),stream2};function mapThinkingLevelToEffort(model,level){let mapped=level?model.thinkingLevelMap?.[level]:void 0;if(typeof mapped=="string")return mapped;switch(level){case"minimal":case"low":return"low";case"medium":return"medium";case"high":return"high";default:return"high"}}var streamSimple=(model,context,options)=>{assertRequestAuth(model.provider,options?.apiKey,options?.headers);let base={...buildBaseOptions(model,context,options,options?.apiKey),toolChoice:options?.toolChoice};if(!options?.reasoning)return stream(model,context,{...base,thinkingEnabled:!1});if(model.compat?.forceAdaptiveThinking===!0){let effort=mapThinkingLevelToEffort(model,options.reasoning);return stream(model,context,{...base,thinkingEnabled:!0,effort})}let adjusted=adjustMaxTokensForThinking(base.maxTokens,model.maxTokens,options.reasoning,options.thinkingBudgets),maxTokens=clampMaxTokensToContext(model,context,adjusted.maxTokens);return stream(model,context,{...base,maxTokens,thinkingEnabled:!0,thinkingBudgetTokens:Math.min(adjusted.thinkingBudget,Math.max(0,maxTokens-1024))})};function isOAuthToken(apiKey){return apiKey.includes("sk-ant-oat")}function createClient(model,apiKey,optionsHeaders,fetch,dynamicHeaders,sessionId){if(model.provider==="github-copilot")return{client:new Anthropic({apiKey:null,authToken:apiKey??null,baseURL:model.baseUrl,dangerouslyAllowBrowser:!0,fetch,defaultHeaders:mergeClientHeaders({accept:"application/json","anthropic-dangerous-direct-browser-access":"true"},model.headers,dynamicHeaders,optionsHeaders)}),isOAuthToken:!1};if(apiKey&&isOAuthToken(apiKey))return{client:new Anthropic({apiKey:null,authToken:apiKey,baseURL:model.baseUrl,dangerouslyAllowBrowser:!0,fetch,defaultHeaders:mergeClientHeaders({accept:"application/json","anthropic-dangerous-direct-browser-access":"true","user-agent":`claude-cli/${claudeCodeVersion}`,"x-app":"cli"},model.headers,optionsHeaders)}),isOAuthToken:!0};let compat=getAnthropicCompat(model),sessionAffinityHeaders={};if(sessionId&&compat.sendSessionAffinityHeaders){let header=compat.sessionAffinityFormat==="openrouter"?"x-session-id":"x-session-affinity";sessionAffinityHeaders[header]=sessionId}let defaultHeaders=mergeClientHeaders({accept:"application/json","anthropic-dangerous-direct-browser-access":"true"},sessionAffinityHeaders,model.headers,optionsHeaders);return{client:new Anthropic({apiKey:apiKey??null,authToken:null,baseURL:model.baseUrl,dangerouslyAllowBrowser:!0,fetch,defaultHeaders}),isOAuthToken:!1}}function getBetaFeatures(model,context,isOAuthToken2,nativeToolChanges,options){let configuredFeatures;for(let headers of[model.headers,options?.headers])for(let[name,value]of Object.entries(headers??{}))name.toLowerCase()==="anthropic-beta"&&(configuredFeatures=value);if(configuredFeatures===null)return[];if(configuredFeatures!==void 0)return[...new Set(configuredFeatures.split(",").map(feature=>feature.trim()).filter(feature=>feature.length>0))];let features=[];return isOAuthToken2&&features.push("claude-code-20250219","oauth-2025-04-20"),shouldUseFineGrainedToolStreamingBeta(model,context)&&features.push(FINE_GRAINED_TOOL_STREAMING_BETA),model.reasoning&&options?.thinkingEnabled===!0&&(options.interleavedThinking??!0)&&model.compat?.forceAdaptiveThinking!==!0&&features.push(INTERLEAVED_THINKING_BETA),shouldUseServerSideFallbackBeta(model)&&features.push(SERVER_SIDE_FALLBACK_BETA),model.compat?.supportsMidConvoEffort===!0&&features.push(MID_CONVERSATION_OUTPUT_CONFIG_BETA,THINKING_BINDING_CONTROLS_BETA),nativeToolChanges&&features.push(MID_CONVERSATION_TOOL_CHANGES_BETA),[...new Set(features)]}function buildParams(model,context,isOAuthToken2,options){let{cacheControl}=getCacheControl(model,options?.cacheRetention,options?.env),compat=getAnthropicCompat(model),initialSystemMessage=getInitialSystemMessage(context.messages),initialSystemText=initialSystemMessage?getSystemMessageText(initialSystemMessage):"",transformedMessages=transformMessages(context.messages,model,normalizeToolCallId),conversationMessages=initialSystemMessage?transformedMessages.slice(1):transformedMessages,initialTools=initialSystemMessage?.toolsAdded??[],nativeToolChanges=compat.supportsMidConvoSystemMessages&&compat.supportsMidConvoToolChanges&&initialTools.length>0&&!hasToolRedefinitions(context.messages),converted=convertMessages(conversationMessages,isOAuthToken2,cacheControl,compat.allowEmptySignature,model.compat?.supportsMidConvoEffort===!0?model.provider:void 0,nativeToolChanges),activeEffort=options?.effort??"high",betaFeatures=getBetaFeatures(model,context,isOAuthToken2,nativeToolChanges,options),params={model:model.id,messages:model.compat?.supportsMidConvoEffort===!0?insertThinkingLevelMessages(converted,activeEffort):converted.messages,max_tokens:options?.maxTokens??model.maxTokens,stream:!0,...betaFeatures.length>0?{betas:betaFeatures}:{}};isOAuthToken2?(params.system=[{type:"text",text:"You are Claude Code, Anthropic's official CLI for Claude.",...cacheControl?{cache_control:cacheControl}:{}}],initialSystemText&&params.system.push({type:"text",text:sanitizeSurrogates(initialSystemText),...cacheControl?{cache_control:cacheControl}:{}})):initialSystemText&&(params.system=[{type:"text",text:sanitizeSurrogates(initialSystemText),...cacheControl?{cache_control:cacheControl}:{}}]),options?.temperature!==void 0&&!options?.thinkingEnabled&&model.compat?.supportsMidConvoEffort!==!0&&compat.supportsTemperature&&(params.temperature=options.temperature);let toolCacheControl=compat.supportsCacheControlOnTools?cacheControl:void 0;if(nativeToolChanges){let initialNames=new Set(initialTools.map(tool=>tool.name)),laterTools=getDeclaredTools(context.messages).filter(tool=>!initialNames.has(tool.name));params.tools=[...convertTools(initialTools,isOAuthToken2,compat.supportsEagerToolInputStreaming,compat.supportsStrictTools,toolCacheControl),DEFERRED_TOOL_PLACEHOLDER,...convertTools(laterTools,isOAuthToken2,compat.supportsEagerToolInputStreaming,compat.supportsStrictTools).map(tool=>({...tool,defer_loading:!0}))]}else{let tools=getCurrentTools(context.messages);tools.length>0&&(params.tools=convertTools(tools,isOAuthToken2,compat.supportsEagerToolInputStreaming,compat.supportsStrictTools,toolCacheControl))}if(model.compat?.supportsMidConvoEffort===!0)params.thinking={type:"adaptive",display:options?.thinkingDisplay??"summarized",block_binding:{prefix_mismatch_behavior:"drop_block"}},params.output_config={effort:"high"};else if(model.reasoning)if(options?.thinkingEnabled){let display=options.thinkingDisplay??"summarized";model.compat?.forceAdaptiveThinking===!0?(params.thinking={type:"adaptive",display},options.effort&&(params.output_config={effort:options.effort})):params.thinking={type:"enabled",budget_tokens:options.thinkingBudgetTokens||1024,display}}else options?.thinkingEnabled===!1&&model.thinkingLevelMap?.off!==null&&(params.thinking={type:"disabled"});if(options?.metadata){let userId=options.metadata.user_id;typeof userId=="string"&&(params.metadata={user_id:userId})}options?.toolChoice&&(typeof options.toolChoice=="string"?params.tool_choice={type:options.toolChoice}:params.tool_choice=options.toolChoice);let allowedFallbackModels=model.compat?.allowedFallbackModels;return allowedFallbackModels&&allowedFallbackModels.length>0&&(params.fallbacks=allowedFallbackModels.map(fallback=>({model:fallback.model}))),params}function normalizeToolCallId(id){return id.replace(/[^a-zA-Z0-9_-]/g,"_").slice(0,64)}function convertToolResult(msg){return{type:"tool_result",tool_use_id:msg.toolCallId,content:convertContentBlocks(msg.content),is_error:msg.isError}}function convertMessages(transformedMessages,isOAuthToken2,cacheControl,allowEmptySignature=!1,managedProvider,nativeToolChanges=!1){let params=[],assistantLevels=new Map,pendingSystemMessages=[],flushPendingSystemMessages=()=>{params.push(...pendingSystemMessages),pendingSystemMessages.length=0};for(let i=0;i<transformedMessages.length;i++){let msg=transformedMessages[i];if(msg.role==="system"){let text=renderSystemMessageUpdate(msg),blocks=[];if(text.length>0&&blocks.push({type:"text",text:sanitizeSurrogates(text)}),nativeToolChanges){for(let tool of msg.toolsRemoved??[])blocks.push({type:"tool_removal",tool:{type:"tool_reference",name:isOAuthToken2?toClaudeCodeName(tool.name):tool.name}});for(let tool of msg.toolsAdded??[])blocks.push({type:"tool_addition",tool:{type:"tool_reference",name:isOAuthToken2?toClaudeCodeName(tool.name):tool.name}})}blocks.length>0&&pendingSystemMessages.push({role:"system",content:blocks})}else if(msg.role==="user")if(typeof msg.content=="string")msg.content.trim().length>0&&params.push({role:"user",content:sanitizeSurrogates(msg.content)});else{let filteredBlocks=msg.content.map(item=>item.type==="text"?{type:"text",text:sanitizeSurrogates(item.text)}:{type:"image",source:{type:"base64",media_type:item.mimeType,data:item.data}}).filter(b=>b.type==="text"?b.text.trim().length>0:!0);if(filteredBlocks.length===0)continue;params.push({role:"user",content:filteredBlocks})}else if(msg.role==="assistant"){flushPendingSystemMessages();let blocks=[];for(let block of msg.content)if(block.type==="text"){if(block.text.trim().length===0)continue;blocks.push({type:"text",text:sanitizeSurrogates(block.text)})}else if(block.type==="thinking"){if(block.redacted){blocks.push({type:"redacted_thinking",data:block.thinkingSignature});continue}let thinkingSignature=block.thinkingSignature,hasThinkingSignature=!!thinkingSignature&&thinkingSignature.trim().length>0;if(block.thinking.trim().length===0&&!hasThinkingSignature)continue;hasThinkingSignature?blocks.push({type:"thinking",thinking:sanitizeSurrogates(block.thinking),signature:thinkingSignature}):blocks.push(allowEmptySignature?{type:"thinking",thinking:sanitizeSurrogates(block.thinking),signature:""}:{type:"text",text:sanitizeSurrogates(block.thinking)})}else block.type==="toolCall"&&blocks.push({type:"tool_use",id:block.id,name:isOAuthToken2?toClaudeCodeName(block.name):block.name,input:block.arguments??{}});if(blocks.length===0)continue;let messageIndex=params.length;params.push({role:"assistant",content:blocks}),managedProvider!==void 0&&msg.api==="anthropic-messages"&&msg.provider===managedProvider&&isAnthropicEffort(msg.providerThinkingLevel)&&assistantLevels.set(messageIndex,msg.providerThinkingLevel)}else if(msg.role==="toolResult"){let toolResults=[],j=i;for(;j<transformedMessages.length&&transformedMessages[j].role==="toolResult";)toolResults.push(convertToolResult(transformedMessages[j])),j++;i=j-1,params.push({role:"user",content:toolResults})}}if(flushPendingSystemMessages(),cacheControl&&params.length>0){let lastMessage=params[params.length-1];if(lastMessage.role==="user"||lastMessage.role==="system")if(Array.isArray(lastMessage.content)){let lastBlock=lastMessage.content[lastMessage.content.length-1];lastBlock&&(lastBlock.type==="text"||lastBlock.type==="image"||lastBlock.type==="tool_result"||lastBlock.type==="tool_addition"||lastBlock.type==="tool_removal")&&(lastBlock.cache_control=cacheControl)}else typeof lastMessage.content=="string"&&(lastMessage.content=[{type:"text",text:lastMessage.content,cache_control:cacheControl}])}return{messages:params,assistantLevels}}function isAnthropicEffort(value){return value==="low"||value==="medium"||value==="high"||value==="xhigh"||value==="max"}function insertThinkingLevelMessages(converted,activeEffort){let messages=[];for(let index=0;index<converted.messages.length;index++){let historicalEffort=converted.assistantLevels.get(index);historicalEffort!==void 0&&messages.push({role:"system",content:[],output_config:{effort:historicalEffort}}),messages.push(converted.messages[index])}return messages.push({role:"system",content:[],output_config:{effort:activeEffort}}),messages}function shouldUseFineGrainedToolStreamingBeta(model,context){return getCurrentTools(context.messages).length>0&&!getAnthropicCompat(model).supportsEagerToolInputStreaming}function convertTools(tools,isOAuthToken2,supportsEagerToolInputStreaming,supportsStrictTools,cacheControl){return tools?tools.map((tool,index)=>{let strict=resolveJsonSchemaStrictSampling(tool,supportsStrictTools),parameters=getJsonSchemaToolParameters(tool,strict),schema=parameters,legacyInputSchema={type:"object",properties:schema.properties??{},required:schema.required??[]},inputSchema=strict===!0?{...parameters,...legacyInputSchema}:legacyInputSchema;return{name:isOAuthToken2?toClaudeCodeName(tool.name):tool.name,description:tool.description,...supportsEagerToolInputStreaming?{eager_input_streaming:!0}:{},...strict===!0?{strict:!0}:{},input_schema:inputSchema,...cacheControl&&index===tools.length-1?{cache_control:cacheControl}:{}}}):[]}function mapStopReason(reason,stopDetails){switch(reason){case"end_turn":return{stopReason:"stop"};case"max_tokens":return{stopReason:"length"};case"tool_use":return{stopReason:"toolUse"};case"refusal":return{stopReason:"error",errorMessage:stopDetails?.explanation||"The model refused to complete the request"};case"pause_turn":return{stopReason:"stop"};case"stop_sequence":return{stopReason:"stop"};case"sensitive":return{stopReason:"error",errorMessage:"Provider stopped with: sensitive"};default:throw new Error(`Unhandled stop reason: ${reason}`)}}export{stream,streamSimple};
@@ -1,2 +0,0 @@
1
- import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url);
2
- import{convertResponsesMessages,convertResponsesTools,processResponsesStream}from"./chunk-V7IXECST.js";import{clampOpenAIPromptCacheKey}from"./chunk-PRRNXB7S.js";import{AzureOpenAI}from"./chunk-NUHFSC37.js";import{formatProviderError,normalizeProviderError}from"./chunk-TEPMHNKQ.js";import"./chunk-PJACZCIR.js";import{retryProviderRequest}from"./chunk-XNGRGP62.js";import{buildBaseOptions,createGrammarToolInputProperties,getPiUserAgent}from"./chunk-GNYZK6XN.js";import"./chunk-L2ZPNLYD.js";import{headersToRecord}from"./chunk-UTB4DTYQ.js";import{getProviderEnvValue}from"./chunk-DRQDKNXA.js";import"./chunk-TRDNDS6A.js";import{clampThinkingLevel,getDeclaredTools,resolveTranscript,resolveTranscriptTools}from"./chunk-FU4XQUSL.js";import{AssistantMessageEventStream}from"./chunk-A3JYRWB6.js";import"./chunk-4L3WN2XY.js";var DEFAULT_AZURE_API_VERSION="v1",AZURE_TOOL_CALL_PROVIDERS=new Set(["openai","openai-codex","opencode","azure-openai-responses"]),OPENAI_RESPONSES_MIN_OUTPUT_TOKENS=16;function parseDeploymentNameMap(value){let map=new Map;if(!value)return map;for(let entry of value.split(",")){let trimmed=entry.trim();if(!trimmed)continue;let[modelId,deploymentName]=trimmed.split("=",2);!modelId||!deploymentName||map.set(modelId.trim(),deploymentName.trim())}return map}function resolveDeploymentName(model,options){return options?.azureDeploymentName?options.azureDeploymentName:parseDeploymentNameMap(getProviderEnvValue("AZURE_OPENAI_DEPLOYMENT_NAME_MAP",options?.env)).get(model.id)||model.id}function formatAzureOpenAIError(error){return formatProviderError(normalizeProviderError(error),"Azure OpenAI API error")}var stream=(model,context,options)=>{let stream2=new AssistantMessageEventStream,normalizedContext=resolveTranscript(context,model.compat?.supportsMidConvoSystemMessages);return(async()=>{let deploymentName=resolveDeploymentName(model,options),output={role:"assistant",content:[],api:"azure-openai-responses",provider:model.provider,model:model.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"pending",timestamp:Date.now()};try{let apiKey=options?.apiKey;if(!apiKey)throw new Error(`No API key for provider: ${model.provider}`);let client=createClient(model,apiKey,options),grammarToolInputProperties=createGrammarToolInputProperties(getDeclaredTools(normalizedContext.messages),model.compat?.supportsOpenAIGrammarTools??!1),params=buildParams(model,normalizedContext,options,deploymentName,grammarToolInputProperties),nextParams=await options?.onPayload?.(params,model);nextParams!==void 0&&(params=nextParams);let requestOptions={...options?.signal?{signal:options.signal}:{},...options?.timeoutMs!==void 0?{timeout:options.timeoutMs}:{},maxRetries:0},{data:openaiStream,response}=await retryProviderRequest(()=>client.responses.create(params,requestOptions).withResponse(),{maxRetries:options?.maxRetries,maxRetryDelayMs:options?.maxRetryDelayMs,signal:options?.signal});if(await options?.onResponse?.({status:response.status,headers:headersToRecord(response.headers)},model),stream2.push({type:"start",partial:output}),await processResponsesStream(openaiStream,output,stream2,model,{onProviderStreamEvent:options?.onProviderStreamEvent,grammarToolInputProperties}),options?.signal?.aborted)throw new Error("Request was aborted");if(output.stopReason==="pending")throw new Error("Azure OpenAI Responses stream ended without a stop reason");if(output.stopReason==="aborted"||output.stopReason==="error")throw new Error(output.errorMessage||"An unknown error occurred");stream2.push({type:"done",reason:output.stopReason,message:output}),stream2.end()}catch(error){for(let block of output.content)delete block.index,delete block.partialJson,delete block.customInput;output.stopReason=options?.signal?.aborted?"aborted":"error",output.errorMessage=formatAzureOpenAIError(error),stream2.push({type:"error",reason:output.stopReason,error:output}),stream2.end()}})(),stream2},streamSimple=(model,context,options)=>{let apiKey=options?.apiKey;if(!apiKey)throw new Error(`No API key for provider: ${model.provider}`);let base={...buildBaseOptions(model,context,options,apiKey),toolChoice:options?.toolChoice},clampedReasoning=options?.reasoning?clampThinkingLevel(model,options.reasoning):void 0;return stream(model,context,{...base,reasoningEffort:clampedReasoning==="off"?void 0:clampedReasoning})};function normalizeAzureBaseUrl(baseUrl){let trimmed=baseUrl.trim().replace(/\/+$/,""),url;try{url=new URL(trimmed)}catch{throw new Error(`Invalid Azure OpenAI base URL: ${baseUrl}`)}let isAzureHost=url.hostname.endsWith(".openai.azure.com")||url.hostname.endsWith(".cognitiveservices.azure.com")||url.hostname.endsWith(".ai.azure.com"),normalizedPath=url.pathname.replace(/\/+$/,"");return isAzureHost&&(normalizedPath===""||normalizedPath==="/"||normalizedPath==="/openai"||normalizedPath==="/openai/v1/responses")&&(url.pathname="/openai/v1",url.search=""),url.toString().replace(/\/+$/,"")}function buildDefaultBaseUrl(resourceName){return`https://${resourceName}.openai.azure.com/openai/v1`}function resolveAzureConfig(model,options){let apiVersion=options?.azureApiVersion||getProviderEnvValue("AZURE_OPENAI_API_VERSION",options?.env)||DEFAULT_AZURE_API_VERSION,baseUrl=options?.azureBaseUrl?.trim()||getProviderEnvValue("AZURE_OPENAI_BASE_URL",options?.env)?.trim()||void 0,resourceName=options?.azureResourceName||getProviderEnvValue("AZURE_OPENAI_RESOURCE_NAME",options?.env),resolvedBaseUrl=baseUrl;if(!resolvedBaseUrl&&resourceName&&(resolvedBaseUrl=buildDefaultBaseUrl(resourceName)),!resolvedBaseUrl&&model.baseUrl&&(resolvedBaseUrl=model.baseUrl),!resolvedBaseUrl)throw new Error("Azure OpenAI base URL is required. Set AZURE_OPENAI_BASE_URL or AZURE_OPENAI_RESOURCE_NAME, or pass azureBaseUrl, azureResourceName, or model.baseUrl.");return{baseUrl:normalizeAzureBaseUrl(resolvedBaseUrl),apiVersion}}function createClient(model,apiKey,options){let headers={"User-Agent":getPiUserAgent(),...model.headers};options?.headers&&Object.assign(headers,options.headers);let{baseUrl,apiVersion}=resolveAzureConfig(model,options);return new AzureOpenAI({apiKey,apiVersion,dangerouslyAllowBrowser:!0,fetch:options?.fetch,defaultHeaders:headers,baseURL:baseUrl})}function buildParams(model,context,options,deploymentName,grammarToolInputProperties=createGrammarToolInputProperties(getDeclaredTools(context.messages),model.compat?.supportsOpenAIGrammarTools??!1)){let supportsAdditionalTools=model.compat?.supportsAdditionalTools??!1,supportsToolSearch=model.compat?.supportsToolSearch??!1,transcriptTools=resolveTranscriptTools(context.messages,supportsAdditionalTools||supportsToolSearch),messages=convertResponsesMessages(model,context,AZURE_TOOL_CALL_PROVIDERS,{grammarToolInputProperties,supportsMidConvoSystemMessages:model.compat?.supportsMidConvoSystemMessages??!1,supportsAdditionalTools,supportsToolSearch,toolOptions:{supportsStrictMode:model.compat?.supportsStrictMode??!0,supportsOpenAIGrammarTools:model.compat?.supportsOpenAIGrammarTools??!1}}),params={model:deploymentName,input:messages,stream:!0,prompt_cache_key:clampOpenAIPromptCacheKey(options?.sessionId),store:!1};if(options?.maxTokens&&(params.max_output_tokens=Math.max(options.maxTokens,OPENAI_RESPONSES_MIN_OUTPUT_TOKENS)),options?.temperature!==void 0&&(params.temperature=options?.temperature),transcriptTools.requestTools.length>0&&(params.tools=convertResponsesTools(transcriptTools.requestTools,{supportsStrictMode:model.compat?.supportsStrictMode??!0,supportsOpenAIGrammarTools:model.compat?.supportsOpenAIGrammarTools??!1})),options?.toolChoice!==void 0&&(params.tool_choice=options.toolChoice),model.reasoning)if(options?.reasoningEffort||options?.reasoningSummary){let effort=options?.reasoningEffort?model.thinkingLevelMap?.[options.reasoningEffort]??options.reasoningEffort:"medium";params.reasoning={effort,summary:options?.reasoningSummary||"auto"},params.include=["reasoning.encrypted_content"]}else model.thinkingLevelMap?.off!==null&&(params.reasoning={effort:model.thinkingLevelMap?.off??"none"});return options?.samplingParams&&Object.assign(params,options.samplingParams),params}export{stream,streamSimple};
@@ -1,2 +0,0 @@
1
- import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url);
2
- import{AgentSession,AgentSessionRuntime,ArminComponent,AssistantMessageComponent,BashExecutionComponent,BorderedLoader,BranchSummaryMessageComponent,CONFIG_DIR_NAME,CURRENT_SESSION_VERSION,CompactionSummaryMessageComponent,Container,CredentialSynchronizationError,CustomEditor,CustomMessageComponent,DEFAULT_COMPACTION_SETTINGS,DEFAULT_MAX_BYTES,DEFAULT_MAX_LINES,DefaultPackageManager,DefaultResourceLoader,DynamicBorder,ExtensionEditorComponent,ExtensionInputComponent,ExtensionRunner,ExtensionSelectorComponent,FooterComponent,InteractiveMode,LoginDialogComponent,ModelRegistry,ModelRuntime,ModelSelectorComponent,OAuthSelectorComponent,ProjectTrustStore,RpcClient,SelectList,SessionManager,SessionSelectorComponent,SettingsManager,SettingsSelectorComponent,SkillInvocationMessageComponent,Theme,ThinkingSelectorComponent,ToolExecutionComponent,TreeSelectorComponent,UserMessageComponent,UserMessageSelectorComponent,VERSION,applyHttpProxySettings,buildContextEntries,buildSessionContext,buildSessionProjection,calculateContextTokens,collectEntriesForBranchSummary,compact,configureHttpDispatcher,convertToLlm,convertToPng,copyToClipboard,createAgentSession,createAgentSessionFromServices,createAgentSessionRuntime,createAgentSessionServices,createBashTool,createBashToolDefinition,createCodingTools,createEditTool,createEditToolDefinition,createEventBus,createExtensionRuntime,createFindTool,createFindToolDefinition,createGrepTool,createGrepToolDefinition,createLocalBashOperations,createLocalPowerShellOperations,createLsTool,createLsToolDefinition,createPowerShellTool,createPowerShellToolDefinition,createReadOnlyTools,createReadTool,createReadToolDefinition,createSyntheticSourceInfo,createWriteTool,createWriteToolDefinition,defaultModelPerProvider,defineTool,detectSupportedImageMimeTypeFromFile,discoverAndLoadExtensions,estimateTokens,findCutPoint,findTurnStartIndex,formatDimensionNote,formatSize,formatSkillsForPrompt,generateBranchSummary,generateDiffString,generateSummary,generateSummaryWithUsage,generateUnifiedPatch,getAgentDir,getAvailableThemes,getDocsPath,getExamplesPath,getLanguageFromPath,getLastAssistantUsage,getLatestCompactionEntry,getMarkdownTheme,getPackageDir,getPowerShellConfig,getReadmePath,getSelectListTheme,getSettingsListTheme,getShellConfig,hasTrustRequiringProjectResources,highlightCode,initTheme,isBashToolResult,isEditToolResult,isFindToolResult,isGrepToolResult,isLsToolResult,isPowerShellToolResult,isReadToolResult,isToolCallEventType,isWriteToolResult,keyHint,keyText,loadProjectContextFiles,loadSkills,loadSkillsFromDir,main,migrateSessionEntries,parseArgs,parseFrontmatter,parseSessionEntries,parseSkillBlock,prepareBranchEntries,rawKeyHint,readStoredCredential,renderDiff,resizeImage,resolveCliModel,resolveModelScopeWithDiagnostics,runPrintMode,runRpcMode,serializeConversation,sessionEntryToContextMessages,setupCli,shouldCompact,stdioRpcTransport,stripFrontmatter,truncateHead,truncateLine,truncateTail,truncateToVisualLines,withFileMutationQueue,wrapRegisteredTool,wrapRegisteredTools}from"./chunk-HEMXN7VJ.js";import{__export}from"./chunk-4L3WN2XY.js";var dist_exports={};__export(dist_exports,{AgentSession:()=>AgentSession,AgentSessionRuntime:()=>AgentSessionRuntime,ArminComponent:()=>ArminComponent,AssistantMessageComponent:()=>AssistantMessageComponent,BashExecutionComponent:()=>BashExecutionComponent,BorderedLoader:()=>BorderedLoader,BranchSummaryMessageComponent:()=>BranchSummaryMessageComponent,CONFIG_DIR_NAME:()=>CONFIG_DIR_NAME,CURRENT_SESSION_VERSION:()=>CURRENT_SESSION_VERSION,CompactionSummaryMessageComponent:()=>CompactionSummaryMessageComponent,CredentialSynchronizationError:()=>CredentialSynchronizationError,CustomEditor:()=>CustomEditor,CustomMessageComponent:()=>CustomMessageComponent,DEFAULT_COMPACTION_SETTINGS:()=>DEFAULT_COMPACTION_SETTINGS,DEFAULT_MAX_BYTES:()=>DEFAULT_MAX_BYTES,DEFAULT_MAX_LINES:()=>DEFAULT_MAX_LINES,DefaultPackageManager:()=>DefaultPackageManager,DefaultResourceLoader:()=>DefaultResourceLoader,DynamicBorder:()=>DynamicBorder,ExtensionEditorComponent:()=>ExtensionEditorComponent,ExtensionInputComponent:()=>ExtensionInputComponent,ExtensionRunner:()=>ExtensionRunner,ExtensionSelectorComponent:()=>ExtensionSelectorComponent,FooterComponent:()=>FooterComponent,InteractiveMode:()=>InteractiveMode,LoginDialogComponent:()=>LoginDialogComponent,ModelRegistry:()=>ModelRegistry,ModelRuntime:()=>ModelRuntime,ModelSelectorComponent:()=>ModelSelectorComponent,OAuthSelectorComponent:()=>OAuthSelectorComponent,ProjectTrustStore:()=>ProjectTrustStore,RpcClient:()=>RpcClient,SessionManager:()=>SessionManager,SessionSelectorComponent:()=>SessionSelectorComponent,SettingsManager:()=>SettingsManager,SettingsSelectorComponent:()=>SettingsSelectorComponent,ShowImagesSelectorComponent:()=>ShowImagesSelectorComponent,SkillInvocationMessageComponent:()=>SkillInvocationMessageComponent,Theme:()=>Theme,ThemeSelectorComponent:()=>ThemeSelectorComponent,ThinkingSelectorComponent:()=>ThinkingSelectorComponent,ToolExecutionComponent:()=>ToolExecutionComponent,TreeSelectorComponent:()=>TreeSelectorComponent,UserMessageComponent:()=>UserMessageComponent,UserMessageSelectorComponent:()=>UserMessageSelectorComponent,VERSION:()=>VERSION,applyHttpProxySettings:()=>applyHttpProxySettings,buildContextEntries:()=>buildContextEntries,buildSessionContext:()=>buildSessionContext,buildSessionProjection:()=>buildSessionProjection,calculateContextTokens:()=>calculateContextTokens,collectEntriesForBranchSummary:()=>collectEntriesForBranchSummary,compact:()=>compact,configureHttpDispatcher:()=>configureHttpDispatcher,convertToLlm:()=>convertToLlm,convertToPng:()=>convertToPng,copyToClipboard:()=>copyToClipboard,createAgentSession:()=>createAgentSession,createAgentSessionFromServices:()=>createAgentSessionFromServices,createAgentSessionRuntime:()=>createAgentSessionRuntime,createAgentSessionServices:()=>createAgentSessionServices,createBashTool:()=>createBashTool,createBashToolDefinition:()=>createBashToolDefinition,createCodingTools:()=>createCodingTools,createEditTool:()=>createEditTool,createEditToolDefinition:()=>createEditToolDefinition,createEventBus:()=>createEventBus,createExtensionRuntime:()=>createExtensionRuntime,createFindTool:()=>createFindTool,createFindToolDefinition:()=>createFindToolDefinition,createGrepTool:()=>createGrepTool,createGrepToolDefinition:()=>createGrepToolDefinition,createLocalBashOperations:()=>createLocalBashOperations,createLocalPowerShellOperations:()=>createLocalPowerShellOperations,createLsTool:()=>createLsTool,createLsToolDefinition:()=>createLsToolDefinition,createPowerShellTool:()=>createPowerShellTool,createPowerShellToolDefinition:()=>createPowerShellToolDefinition,createReadOnlyTools:()=>createReadOnlyTools,createReadTool:()=>createReadTool,createReadToolDefinition:()=>createReadToolDefinition,createSyntheticSourceInfo:()=>createSyntheticSourceInfo,createWriteTool:()=>createWriteTool,createWriteToolDefinition:()=>createWriteToolDefinition,defaultModelPerProvider:()=>defaultModelPerProvider,defineTool:()=>defineTool,detectSupportedImageMimeTypeFromFile:()=>detectSupportedImageMimeTypeFromFile,discoverAndLoadExtensions:()=>discoverAndLoadExtensions,estimateTokens:()=>estimateTokens,findCutPoint:()=>findCutPoint,findTurnStartIndex:()=>findTurnStartIndex,formatDimensionNote:()=>formatDimensionNote,formatSize:()=>formatSize,formatSkillsForPrompt:()=>formatSkillsForPrompt,generateBranchSummary:()=>generateBranchSummary,generateDiffString:()=>generateDiffString,generateSummary:()=>generateSummary,generateSummaryWithUsage:()=>generateSummaryWithUsage,generateUnifiedPatch:()=>generateUnifiedPatch,getAgentDir:()=>getAgentDir,getDocsPath:()=>getDocsPath,getExamplesPath:()=>getExamplesPath,getLanguageFromPath:()=>getLanguageFromPath,getLastAssistantUsage:()=>getLastAssistantUsage,getLatestCompactionEntry:()=>getLatestCompactionEntry,getMarkdownTheme:()=>getMarkdownTheme,getPackageDir:()=>getPackageDir,getPowerShellConfig:()=>getPowerShellConfig,getReadmePath:()=>getReadmePath,getSelectListTheme:()=>getSelectListTheme,getSettingsListTheme:()=>getSettingsListTheme,getShellConfig:()=>getShellConfig,hasTrustRequiringProjectResources:()=>hasTrustRequiringProjectResources,highlightCode:()=>highlightCode,initTheme:()=>initTheme,isBashToolResult:()=>isBashToolResult,isEditToolResult:()=>isEditToolResult,isFindToolResult:()=>isFindToolResult,isGrepToolResult:()=>isGrepToolResult,isLsToolResult:()=>isLsToolResult,isPowerShellToolResult:()=>isPowerShellToolResult,isReadToolResult:()=>isReadToolResult,isToolCallEventType:()=>isToolCallEventType,isWriteToolResult:()=>isWriteToolResult,keyHint:()=>keyHint,keyText:()=>keyText,loadProjectContextFiles:()=>loadProjectContextFiles,loadSkills:()=>loadSkills,loadSkillsFromDir:()=>loadSkillsFromDir,main:()=>main,migrateSessionEntries:()=>migrateSessionEntries,parseArgs:()=>parseArgs,parseFrontmatter:()=>parseFrontmatter,parseSessionEntries:()=>parseSessionEntries,parseSkillBlock:()=>parseSkillBlock,prepareBranchEntries:()=>prepareBranchEntries,rawKeyHint:()=>rawKeyHint,readStoredCredential:()=>readStoredCredential,renderDiff:()=>renderDiff,resizeImage:()=>resizeImage,resolveCliModel:()=>resolveCliModel,resolveModelScopeWithDiagnostics:()=>resolveModelScopeWithDiagnostics,runPrintMode:()=>runPrintMode,runRpcMode:()=>runRpcMode,serializeConversation:()=>serializeConversation,sessionEntryToContextMessages:()=>sessionEntryToContextMessages,setupCli:()=>setupCli,shouldCompact:()=>shouldCompact,stdioRpcTransport:()=>stdioRpcTransport,stripFrontmatter:()=>stripFrontmatter,truncateHead:()=>truncateHead,truncateLine:()=>truncateLine,truncateTail:()=>truncateTail,truncateToVisualLines:()=>truncateToVisualLines,withFileMutationQueue:()=>withFileMutationQueue,wrapRegisteredTool:()=>wrapRegisteredTool,wrapRegisteredTools:()=>wrapRegisteredTools});var SHOW_IMAGES_SELECT_LIST_LAYOUT={minPrimaryColumnWidth:12,maxPrimaryColumnWidth:32},ShowImagesSelectorComponent=class extends Container{selectList;constructor(currentValue,onSelect,onCancel){super();let items=[{value:"yes",label:"Yes",description:"Show images inline in terminal"},{value:"no",label:"No",description:"Show text placeholder instead"}];this.addChild(new DynamicBorder),this.selectList=new SelectList(items,5,getSelectListTheme(),SHOW_IMAGES_SELECT_LIST_LAYOUT),this.selectList.setSelectedIndex(currentValue?0:1),this.selectList.onSelect=item=>{onSelect(item.value==="yes")},this.selectList.onCancel=()=>{onCancel()},this.addChild(this.selectList),this.addChild(new DynamicBorder)}getSelectList(){return this.selectList}};var THEME_SELECT_LIST_LAYOUT={minPrimaryColumnWidth:12,maxPrimaryColumnWidth:32},ThemeSelectorComponent=class extends Container{selectList;onPreview;constructor(currentTheme,onSelect,onCancel,onPreview){super(),this.onPreview=onPreview;let themes=getAvailableThemes(),themeItems=themes.map(name=>({value:name,label:name,description:name===currentTheme?"(current)":void 0}));this.addChild(new DynamicBorder),this.selectList=new SelectList(themeItems,10,getSelectListTheme(),THEME_SELECT_LIST_LAYOUT);let currentIndex=themes.indexOf(currentTheme);currentIndex!==-1&&this.selectList.setSelectedIndex(currentIndex),this.selectList.onSelect=item=>{onSelect(item.value)},this.selectList.onCancel=()=>{onCancel()},this.selectList.onSelectionChange=item=>{this.onPreview(item.value)},this.addChild(this.selectList),this.addChild(new DynamicBorder)}getSelectList(){return this.selectList}};export{ShowImagesSelectorComponent,ThemeSelectorComponent,dist_exports};