@jacobbd/relay-ai 0.10.1 → 0.11.1
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.
- package/README.md +2 -2
- package/dist/chunk-JIDIH7DS.js +28 -0
- package/dist/chunk-O2XZFXHG.js +4763 -0
- package/dist/chunk-O2XZFXHG.js.map +1 -0
- package/dist/{chunk-TFMHIGRX.js → chunk-TRM2WGI6.js} +6 -23
- package/dist/chunk-TRM2WGI6.js.map +1 -0
- package/dist/chunk-VXQ7ZVTW.js +152 -0
- package/dist/chunk-VXQ7ZVTW.js.map +1 -0
- package/dist/{chunk-YYI6EJ2X.js → chunk-YD6A3ZB3.js} +2246 -6802
- package/dist/chunk-YD6A3ZB3.js.map +1 -0
- package/dist/cli.js +1203 -1072
- package/dist/cli.js.map +1 -1
- package/dist/core/index.js +84 -30
- package/dist/core/index.js.map +1 -1
- package/dist/manual-models-VEBTRQFK.js +12 -0
- package/dist/manual-models-VEBTRQFK.js.map +1 -0
- package/dist/{provider-templates-JWT6U5B7.js → provider-templates-JY3NXZK7.js} +3 -2
- package/dist/provider-templates-JY3NXZK7.js.map +1 -0
- package/dist/ui/public/app.js +153 -2
- package/dist/ui/public/style.css +28 -0
- package/dist/{ui-command-LZWTWTQ6.js → ui-command-WKPJI2CU.js} +118 -30
- package/dist/ui-command-WKPJI2CU.js.map +1 -0
- package/package.json +22 -23
- package/dist/chunk-TFMHIGRX.js.map +0 -1
- package/dist/chunk-YYI6EJ2X.js.map +0 -1
- package/dist/ui-command-LZWTWTQ6.js.map +0 -1
- /package/dist/{provider-templates-JWT6U5B7.js.map → chunk-JIDIH7DS.js.map} +0 -0
package/dist/core/index.js
CHANGED
|
@@ -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.
|
|
53
|
+
version: "0.11.1",
|
|
54
54
|
publishConfig: {
|
|
55
55
|
access: "public"
|
|
56
56
|
},
|
|
@@ -82,7 +82,7 @@ var package_default = {
|
|
|
82
82
|
"README.md"
|
|
83
83
|
],
|
|
84
84
|
engines: {
|
|
85
|
-
node: ">=
|
|
85
|
+
node: ">=22"
|
|
86
86
|
},
|
|
87
87
|
scripts: {
|
|
88
88
|
build: "tsup && tsup --config tsup.core.config.ts && node scripts/copy-ui-assets.mjs",
|
|
@@ -96,35 +96,34 @@ var package_default = {
|
|
|
96
96
|
prepublishOnly: "npm run release:check && npm run build"
|
|
97
97
|
},
|
|
98
98
|
dependencies: {
|
|
99
|
-
"@ai-sdk/alibaba": "^
|
|
100
|
-
"@ai-sdk/amazon-bedrock": "^
|
|
101
|
-
"@ai-sdk/azure": "^
|
|
102
|
-
"@ai-sdk/cerebras": "^
|
|
103
|
-
"@ai-sdk/cohere": "^
|
|
104
|
-
"@ai-sdk/deepinfra": "^
|
|
105
|
-
"@ai-sdk/gateway": "^
|
|
106
|
-
"@ai-sdk/google": "^
|
|
107
|
-
"@ai-sdk/google-vertex": "^
|
|
108
|
-
"@ai-sdk/groq": "^
|
|
109
|
-
"@ai-sdk/mistral": "^
|
|
110
|
-
"@ai-sdk/openai": "^
|
|
111
|
-
"@ai-sdk/openai-compatible": "^
|
|
112
|
-
"@ai-sdk/perplexity": "^
|
|
113
|
-
"@ai-sdk/togetherai": "^
|
|
114
|
-
"@ai-sdk/vercel": "^
|
|
115
|
-
"@ai-sdk/xai": "^
|
|
99
|
+
"@ai-sdk/alibaba": "^2.0.41",
|
|
100
|
+
"@ai-sdk/amazon-bedrock": "^5.0.76",
|
|
101
|
+
"@ai-sdk/azure": "^4.0.63",
|
|
102
|
+
"@ai-sdk/cerebras": "^3.0.44",
|
|
103
|
+
"@ai-sdk/cohere": "^4.0.37",
|
|
104
|
+
"@ai-sdk/deepinfra": "^3.0.44",
|
|
105
|
+
"@ai-sdk/gateway": "^4.0.75",
|
|
106
|
+
"@ai-sdk/google": "^4.0.64",
|
|
107
|
+
"@ai-sdk/google-vertex": "^5.0.76",
|
|
108
|
+
"@ai-sdk/groq": "^4.0.37",
|
|
109
|
+
"@ai-sdk/mistral": "^4.0.39",
|
|
110
|
+
"@ai-sdk/openai": "^4.0.60",
|
|
111
|
+
"@ai-sdk/openai-compatible": "^3.0.44",
|
|
112
|
+
"@ai-sdk/perplexity": "^4.0.39",
|
|
113
|
+
"@ai-sdk/togetherai": "^3.0.45",
|
|
114
|
+
"@ai-sdk/vercel": "^3.0.30",
|
|
115
|
+
"@ai-sdk/xai": "^4.0.54",
|
|
116
116
|
"@clack/prompts": "^0.9.1",
|
|
117
|
-
"@openrouter/ai-sdk-provider": "^
|
|
118
|
-
ai: "^
|
|
117
|
+
"@openrouter/ai-sdk-provider": "^3.0.0",
|
|
118
|
+
ai: "^7.0.93",
|
|
119
119
|
"cross-spawn": "^7.0.6",
|
|
120
|
-
"gitlab-ai-provider": "^6.
|
|
120
|
+
"gitlab-ai-provider": "^6.15.0",
|
|
121
121
|
graphql: "^16.14.2",
|
|
122
122
|
"ipaddr.js": "^2.4.0",
|
|
123
123
|
"node-forge": "^1.4.0",
|
|
124
124
|
open: "^11.0.0",
|
|
125
125
|
picocolors: "^1.1.1",
|
|
126
126
|
"smol-toml": "^1.6.1",
|
|
127
|
-
"venice-ai-sdk-provider": "^2.0.2",
|
|
128
127
|
ws: "^8.21.0",
|
|
129
128
|
zod: "^3.25.76"
|
|
130
129
|
},
|
|
@@ -157,7 +156,7 @@ var package_default = {
|
|
|
157
156
|
|
|
158
157
|
// src/constants.ts
|
|
159
158
|
var CODEX_RESPONSES_LITE_WS_URL = "wss://chatgpt.com/backend-api/codex/responses";
|
|
160
|
-
var CODEX_RESPONSES_LITE_VERSION = "0.
|
|
159
|
+
var CODEX_RESPONSES_LITE_VERSION = "0.153.4";
|
|
161
160
|
var CODEX_RESPONSES_WEBSOCKETS_BETA = "responses_websockets=2026-02-06";
|
|
162
161
|
var OPENCODE_CACHE_PATH = join2(homedir2(), ".cache", "opencode", "models.json");
|
|
163
162
|
var CODEX_SUBAGENT_MODEL_CAP = 1;
|
|
@@ -874,6 +873,9 @@ var OPENAI_CHAT_COMPLETIONS_ONLY = [
|
|
|
874
873
|
function shouldUseOpenAiResponsesEndpoint(modelId) {
|
|
875
874
|
return !OPENAI_CHAT_COMPLETIONS_ONLY.includes(modelId.toLowerCase());
|
|
876
875
|
}
|
|
876
|
+
function resolveProviderNpm(npm) {
|
|
877
|
+
return npm === "venice-ai-sdk-provider" ? "@ai-sdk/openai-compatible" : npm;
|
|
878
|
+
}
|
|
877
879
|
function findCreateFactory(mod) {
|
|
878
880
|
for (const value of Object.values(mod)) {
|
|
879
881
|
if (typeof value === "function" && value.name.startsWith("create")) {
|
|
@@ -903,7 +905,8 @@ async function loadSdkProviderFactory(npm) {
|
|
|
903
905
|
return cached;
|
|
904
906
|
}
|
|
905
907
|
async function createLanguageModel(spec) {
|
|
906
|
-
const
|
|
908
|
+
const npm = resolveProviderNpm(spec.npm);
|
|
909
|
+
const { modelId, apiKey, baseURL } = spec;
|
|
907
910
|
if (npm === VERTEX_ANTHROPIC_NPM) {
|
|
908
911
|
if (!spec.vertex?.project) {
|
|
909
912
|
throw new Error("Vertex project is required for @ai-sdk/google-vertex/anthropic");
|
|
@@ -1620,6 +1623,51 @@ function isValidProviderId(id) {
|
|
|
1620
1623
|
return PROVIDER_ID_PATTERN.test(id);
|
|
1621
1624
|
}
|
|
1622
1625
|
|
|
1626
|
+
// src/registry/provider-models.ts
|
|
1627
|
+
var MANUAL_MODEL_PACKAGES = /* @__PURE__ */ new Set([
|
|
1628
|
+
"@ai-sdk/openai-compatible",
|
|
1629
|
+
"@ai-sdk/openai",
|
|
1630
|
+
"@ai-sdk/anthropic",
|
|
1631
|
+
"@openrouter/ai-sdk-provider"
|
|
1632
|
+
]);
|
|
1633
|
+
function supportsManualModels(provider) {
|
|
1634
|
+
return provider.authType !== "oauth" && !["zen", "go", "antigravity"].includes(provider.templateId) && MANUAL_MODEL_PACKAGES.has(provider.api.npm ?? "");
|
|
1635
|
+
}
|
|
1636
|
+
function getProviderModels(provider) {
|
|
1637
|
+
const models = new Map((provider.modelsCache?.models ?? []).map((model) => [model.id, model]));
|
|
1638
|
+
if (supportsManualModels(provider)) {
|
|
1639
|
+
for (const model of provider.manualModels ?? []) {
|
|
1640
|
+
models.set(model.id, { ...model, modelFormat: provider.api.npm === "@ai-sdk/anthropic" ? "anthropic" : "openai" });
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
return [...models.values()];
|
|
1644
|
+
}
|
|
1645
|
+
function modelIdError(value) {
|
|
1646
|
+
if (typeof value !== "string" || !value.trim()) return "Model ID is required.";
|
|
1647
|
+
if (value.trim().length > 512 || /[\s\u0000-\u001f\u007f]/u.test(value.trim())) {
|
|
1648
|
+
return "Model ID must be at most 512 characters with no whitespace or control characters.";
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
function contextWindowError(value) {
|
|
1652
|
+
if (value !== void 0 && (!Number.isSafeInteger(value) || Number(value) <= 0)) {
|
|
1653
|
+
return "Context size must be a positive whole number of tokens, or left blank.";
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
function parseManualModel(raw) {
|
|
1657
|
+
if (!raw || typeof raw !== "object") return void 0;
|
|
1658
|
+
const m = raw;
|
|
1659
|
+
if (modelIdError(m.id) || typeof m.name !== "string" || !m.name.trim() || m.name.length > 200 || m.source !== "manual" || typeof m.validatedAt !== "string" || !Number.isFinite(Date.parse(m.validatedAt)) || contextWindowError(m.contextWindow) || m.modelFormat !== "openai" && m.modelFormat !== "anthropic") return void 0;
|
|
1660
|
+
return {
|
|
1661
|
+
id: m.id.trim(),
|
|
1662
|
+
name: m.name.trim(),
|
|
1663
|
+
upstreamModelId: m.id.trim(),
|
|
1664
|
+
modelFormat: m.modelFormat,
|
|
1665
|
+
source: "manual",
|
|
1666
|
+
validatedAt: m.validatedAt,
|
|
1667
|
+
...m.contextWindow === void 0 ? {} : { contextWindow: m.contextWindow, contextWindowSource: "user" }
|
|
1668
|
+
};
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1623
1671
|
// src/registry/io.ts
|
|
1624
1672
|
var DIR_MODE = 448;
|
|
1625
1673
|
var FILE_MODE = 384;
|
|
@@ -1672,6 +1720,12 @@ function parseProvider(raw) {
|
|
|
1672
1720
|
provider.authType = p.authType;
|
|
1673
1721
|
}
|
|
1674
1722
|
if (typeof p.refreshedAt === "string") provider.refreshedAt = p.refreshedAt;
|
|
1723
|
+
if (Array.isArray(p.manualModels)) {
|
|
1724
|
+
provider.manualModels = p.manualModels.flatMap((raw2) => {
|
|
1725
|
+
const model = parseManualModel(raw2);
|
|
1726
|
+
return model ? [model] : [];
|
|
1727
|
+
});
|
|
1728
|
+
}
|
|
1675
1729
|
if (p.modelsCache && typeof p.modelsCache === "object") {
|
|
1676
1730
|
const cache = p.modelsCache;
|
|
1677
1731
|
if (typeof cache.fetchedAt === "string" && Array.isArray(cache.models)) {
|
|
@@ -1997,7 +2051,7 @@ var PROVIDER_TEMPLATES = [
|
|
|
1997
2051
|
id: "venice",
|
|
1998
2052
|
name: "Venice AI",
|
|
1999
2053
|
authType: "api",
|
|
2000
|
-
npm: "
|
|
2054
|
+
npm: "@ai-sdk/openai-compatible",
|
|
2001
2055
|
defaultBaseUrl: "https://api.venice.ai/api/v1",
|
|
2002
2056
|
signupUrl: "https://venice.ai/settings/api",
|
|
2003
2057
|
modelSource: "api-list",
|
|
@@ -2317,7 +2371,7 @@ async function withReasoningProviderOptions(model, providerOptions) {
|
|
|
2317
2371
|
// interface; everything Core builds is a concrete current-spec model.
|
|
2318
2372
|
model,
|
|
2319
2373
|
middleware: {
|
|
2320
|
-
specificationVersion: "
|
|
2374
|
+
specificationVersion: "v4",
|
|
2321
2375
|
transformParams: async ({ params }) => ({
|
|
2322
2376
|
...params,
|
|
2323
2377
|
providerOptions: deepMergeProviderOptions(
|
|
@@ -2333,7 +2387,7 @@ async function withRequestHeaders(model, headers) {
|
|
|
2333
2387
|
return wrapLanguageModel2({
|
|
2334
2388
|
model,
|
|
2335
2389
|
middleware: {
|
|
2336
|
-
specificationVersion: "
|
|
2390
|
+
specificationVersion: "v4",
|
|
2337
2391
|
transformParams: async ({ params }) => ({
|
|
2338
2392
|
...params,
|
|
2339
2393
|
headers: mergeHeaders(
|
|
@@ -2451,7 +2505,7 @@ function listRelayModels(registryPath) {
|
|
|
2451
2505
|
const descriptors = [];
|
|
2452
2506
|
for (const provider of registry.providers) {
|
|
2453
2507
|
if (!provider.enabled) continue;
|
|
2454
|
-
for (const model of provider
|
|
2508
|
+
for (const model of getProviderModels(provider)) {
|
|
2455
2509
|
descriptors.push(toDescriptor(provider, model, favorites));
|
|
2456
2510
|
}
|
|
2457
2511
|
}
|
|
@@ -3821,7 +3875,7 @@ function findRoute(registry, providerId, modelId, routeId) {
|
|
|
3821
3875
|
if (!provider.enabled) {
|
|
3822
3876
|
throw new RelayCoreError("PROVIDER_DISABLED", `Provider "${provider.name}" is disabled \u2014 enable it in relay-ai ui.`, { providerId, routeId });
|
|
3823
3877
|
}
|
|
3824
|
-
const model = provider.
|
|
3878
|
+
const model = getProviderModels(provider).find((m) => m.id === modelId);
|
|
3825
3879
|
if (!model) {
|
|
3826
3880
|
throw new RelayCoreError("UNSUPPORTED_MODEL", `Provider "${provider.name}" has no cached model "${modelId}" \u2014 refresh its models in relay-ai ui.`, { providerId, routeId });
|
|
3827
3881
|
}
|