@jacobbd/relay-ai 0.12.9 → 0.12.10

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.
@@ -10,7 +10,7 @@ import {
10
10
  supportsManualModels,
11
11
  translateRequest,
12
12
  validateCustomEndpointUrl
13
- } from "./chunk-3KCKQRRR.js";
13
+ } from "./chunk-OIL75EGI.js";
14
14
 
15
15
  // src/registry/validate-manual-model.ts
16
16
  import { randomUUID } from "crypto";
@@ -149,4 +149,4 @@ export {
149
149
  addManualModel,
150
150
  removeManualModel
151
151
  };
152
- //# sourceMappingURL=chunk-TRCGBOYR.js.map
152
+ //# sourceMappingURL=chunk-YIEEHFVL.js.map
package/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  addManualModel,
4
4
  removeManualModel
5
- } from "./chunk-TRCGBOYR.js";
5
+ } from "./chunk-YIEEHFVL.js";
6
6
  import {
7
7
  CODEX_APP_AUTO_COMPACT_RATIO,
8
8
  CODEX_APP_PROVIDER_ID,
@@ -148,7 +148,7 @@ import {
148
148
  waitForCodexAppQuit,
149
149
  writeSecureLogLine,
150
150
  zenRegistryStub
151
- } from "./chunk-KVH362S4.js";
151
+ } from "./chunk-2KEDU24N.js";
152
152
  import {
153
153
  filterTemplates,
154
154
  getTemplateById,
@@ -222,7 +222,7 @@ import {
222
222
  thinkingProviderOptions,
223
223
  upstreamHttpStatus,
224
224
  validateCustomEndpointUrl
225
- } from "./chunk-3KCKQRRR.js";
225
+ } from "./chunk-OIL75EGI.js";
226
226
  import "./chunk-JIDIH7DS.js";
227
227
 
228
228
  // src/cli.ts
@@ -16233,7 +16233,7 @@ Options:
16233
16233
  --trace Write debug logs under ~/.relay-ai/logs/`);
16234
16234
  return 0;
16235
16235
  }
16236
- const { runUiCommand } = await import("./ui-command-CLMJUDHR.js");
16236
+ const { runUiCommand } = await import("./ui-command-CJYKHNG6.js");
16237
16237
  return runUiCommand({ trace: parsed.trace, serverMode: parsed.uiServerMode });
16238
16238
  }
16239
16239
  if (parsed.command === "models") {
@@ -50,7 +50,7 @@ import { join as join2 } from "path";
50
50
  // package.json
51
51
  var package_default = {
52
52
  name: "@jacobbd/relay-ai",
53
- version: "0.12.9",
53
+ version: "0.12.10",
54
54
  publishConfig: {
55
55
  access: "public"
56
56
  },
@@ -1576,14 +1576,14 @@ function xaiDefaultReasoningEffort(modelId) {
1576
1576
  if (lower === "grok-4.5" || lower.startsWith("grok-4.5-")) return "high";
1577
1577
  return "low";
1578
1578
  }
1579
- var DEEPSEEK_V4_REASONING_ID = /^deepseek-v4(?:\.\d+)?-(?:flash|pro)(?:-|$)/;
1579
+ var DEEPSEEK_V4_REASONING_ID = /^(?:[a-z0-9-]+\/)?deepseek-v4(?:\.\d+)?-(?:flash|pro)(?:-|$)/;
1580
1580
  function isDeepSeekReasoningModel(modelId) {
1581
1581
  const lower = modelId.toLowerCase();
1582
1582
  return DEEPSEEK_V4_REASONING_ID.test(lower) || lower === "deepseek-reasoner" || lower === "deepseek-chat";
1583
1583
  }
1584
+ var KIMI_REASONING_ID = /^(?:[a-z0-9-]+\/)?kimi-/;
1584
1585
  function isKimiReasoningModel(modelId) {
1585
- const lower = modelId.toLowerCase();
1586
- return lower.startsWith("kimi-");
1586
+ return KIMI_REASONING_ID.test(modelId.toLowerCase().trim());
1587
1587
  }
1588
1588
  function isGlm52ReasoningModel(modelId) {
1589
1589
  const lower = modelId.toLowerCase();
@@ -1633,10 +1633,11 @@ function openRouterReasoningCapabilities(metadata) {
1633
1633
  }
1634
1634
  function deepSeekAcceptsNativeEfforts(metadata) {
1635
1635
  const providerId = metadata?.providerId?.toLowerCase();
1636
- if (providerId === "go" || providerId === "zen" || providerId === "opencode-go" || providerId === "opencode") {
1636
+ if (providerId === "go" || providerId === "zen" || providerId === "opencode-go" || providerId === "opencode" || providerId === "commandcode") {
1637
1637
  return true;
1638
1638
  }
1639
- return metadata?.apiBaseUrl?.includes("opencode.ai") === true;
1639
+ const baseUrl = metadata?.apiBaseUrl;
1640
+ return baseUrl?.includes("opencode.ai") === true || baseUrl?.includes("commandcode.ai") === true;
1640
1641
  }
1641
1642
  function mapCodexEffortToDeepSeek(effort, nativeEfforts) {
1642
1643
  switch (effort) {
@@ -4537,7 +4538,98 @@ function abortError(signal, cause) {
4537
4538
  return new DOMException("This operation was aborted", "AbortError");
4538
4539
  }
4539
4540
 
4541
+ // src/tool-schema.ts
4542
+ var GOOGLE_NPM = /* @__PURE__ */ new Set(["@ai-sdk/google", "@ai-sdk/google-vertex"]);
4543
+ function collapseSchemaUnionTypes(value) {
4544
+ if (Array.isArray(value)) return value.map(collapseSchemaUnionTypes);
4545
+ if (!value || typeof value !== "object") return value;
4546
+ const out = {};
4547
+ for (const [key, child] of Object.entries(value)) {
4548
+ if (key === "type" && Array.isArray(child)) {
4549
+ const nonNull = child.filter((entry) => entry !== "null");
4550
+ if (nonNull.length === 1) {
4551
+ out.type = nonNull[0];
4552
+ if (nonNull.length < child.length) out.nullable = true;
4553
+ continue;
4554
+ }
4555
+ }
4556
+ out[key] = collapseSchemaUnionTypes(child);
4557
+ }
4558
+ return out;
4559
+ }
4560
+ function isDigit(ch) {
4561
+ return ch !== void 0 && ch >= "0" && ch <= "9";
4562
+ }
4563
+ function rewriteNulEscapesInPattern(pattern) {
4564
+ let out = "";
4565
+ let escaped = false;
4566
+ let changed = false;
4567
+ for (let i = 0; i < pattern.length; i += 1) {
4568
+ const ch = pattern[i];
4569
+ if (escaped) {
4570
+ escaped = false;
4571
+ if (ch === "0" && !isDigit(pattern[i + 1])) {
4572
+ out += "x00";
4573
+ changed = true;
4574
+ } else {
4575
+ out += ch;
4576
+ }
4577
+ continue;
4578
+ }
4579
+ if (ch === "\\") escaped = true;
4580
+ out += ch;
4581
+ }
4582
+ return changed ? out : null;
4583
+ }
4584
+ function rewriteNulPatternEscapes(value) {
4585
+ if (Array.isArray(value)) {
4586
+ let changed2 = false;
4587
+ const out2 = value.map((entry) => {
4588
+ const next = rewriteNulPatternEscapes(entry);
4589
+ if (next !== entry) changed2 = true;
4590
+ return next;
4591
+ });
4592
+ return changed2 ? out2 : value;
4593
+ }
4594
+ if (!value || typeof value !== "object") return value;
4595
+ let changed = false;
4596
+ const out = {};
4597
+ for (const [key, child] of Object.entries(value)) {
4598
+ const next = key === "pattern" && typeof child === "string" ? rewriteNulEscapesInPattern(child) ?? child : rewriteNulPatternEscapes(child);
4599
+ if (next !== child) changed = true;
4600
+ out[key] = next;
4601
+ }
4602
+ return changed ? out : value;
4603
+ }
4604
+ function normalizeToolSchemaForNpm(schema, npm) {
4605
+ const portable = rewriteNulPatternEscapes(schema);
4606
+ if (!npm || !GOOGLE_NPM.has(npm)) return portable;
4607
+ return collapseSchemaUnionTypes(portable);
4608
+ }
4609
+
4540
4610
  // src/core/model.ts
4611
+ async function withPortableToolSchemas(model, npm) {
4612
+ const { wrapLanguageModel: wrapLanguageModel2 } = await import("ai");
4613
+ return wrapLanguageModel2({
4614
+ model,
4615
+ middleware: {
4616
+ specificationVersion: "v4",
4617
+ transformParams: async ({ params }) => {
4618
+ const tools = params.tools;
4619
+ if (!tools?.length) return params;
4620
+ let changed = false;
4621
+ const next = tools.map((entry) => {
4622
+ if (entry.type !== "function" || !entry.inputSchema || typeof entry.inputSchema !== "object") return entry;
4623
+ const inputSchema = normalizeToolSchemaForNpm(entry.inputSchema, npm);
4624
+ if (inputSchema === entry.inputSchema) return entry;
4625
+ changed = true;
4626
+ return { ...entry, inputSchema };
4627
+ });
4628
+ return changed ? { ...params, tools: next } : params;
4629
+ }
4630
+ }
4631
+ });
4632
+ }
4541
4633
  function isAntigravityCloudCodeRoute(provider, model) {
4542
4634
  return provider.id === "antigravity" && provider.authType === "oauth" && model.modelFormat === "cloud-code";
4543
4635
  }
@@ -4597,8 +4689,8 @@ async function createRelayModel(routeId, options) {
4597
4689
  // session here — a baked-in id would blend histories. The host passes sessionId.
4598
4690
  { generateFallbackSession: false }
4599
4691
  );
4600
- const finish = async (built) => {
4601
- let finished = built;
4692
+ const finish = async (built, schemaNpm) => {
4693
+ let finished = await withPortableToolSchemas(built, schemaNpm);
4602
4694
  if (reasoningOptions) finished = await withReasoningProviderOptions(finished, reasoningOptions);
4603
4695
  if (transportHeaders) finished = await withRequestHeaders(finished, transportHeaders);
4604
4696
  return finished;
@@ -4621,7 +4713,7 @@ async function createRelayModel(routeId, options) {
4621
4713
  projectId,
4622
4714
  refreshToken: providerRefreshToken(provider.id, provider.authType, provider.authRef),
4623
4715
  ...options?.onDebug ? { onDebug: options.onDebug } : {}
4624
- }));
4716
+ }), reasoningNpmForRoute(provider, model));
4625
4717
  } catch (err) {
4626
4718
  if (isRelayCoreError(err)) throw err;
4627
4719
  throw new RelayCoreError(
@@ -4658,7 +4750,7 @@ async function createRelayModel(routeId, options) {
4658
4750
  ...options?.onDebug ? { onDebug: options.onDebug } : {}
4659
4751
  };
4660
4752
  try {
4661
- return await finish(await createLanguageModel(spec));
4753
+ return await finish(await createLanguageModel(spec), npm);
4662
4754
  } catch (err) {
4663
4755
  if (isRelayCoreError(err)) throw err;
4664
4756
  throw new RelayCoreError(