@jacobbd/relay-ai 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -6
- package/dist/{chunk-5DDQJSTU.js → chunk-R4AWEK7T.js} +392 -117
- package/dist/chunk-R4AWEK7T.js.map +1 -0
- package/dist/cli.js +1618 -341
- package/dist/cli.js.map +1 -1
- package/dist/core/index.js +93 -79
- package/dist/core/index.js.map +1 -1
- package/dist/ui/public/app.js +164 -41
- package/dist/ui/public/index.html +32 -0
- package/dist/ui/public/provider-model-browser.js +18 -2
- package/dist/{ui-command-RYWL36VR.js → ui-command-FARF2BF4.js} +54 -10
- package/dist/ui-command-FARF2BF4.js.map +1 -0
- package/package.json +4 -3
- package/dist/chunk-5DDQJSTU.js.map +0 -1
- package/dist/ui-command-RYWL36VR.js.map +0 -1
package/dist/core/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/config.ts
|
|
2
|
-
import { dirname, join as
|
|
2
|
+
import { dirname, join as join3 } from "path";
|
|
3
3
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "fs";
|
|
4
4
|
|
|
5
5
|
// src/paths.ts
|
|
@@ -43,83 +43,14 @@ function getLegacyConfPath(env = process.env, platform = process.platform) {
|
|
|
43
43
|
return join(env.XDG_CONFIG_HOME ?? join(home, ".config"), appName, "config.json");
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
// src/config.ts
|
|
47
|
-
function readJsonFile(path) {
|
|
48
|
-
try {
|
|
49
|
-
const parsed = JSON.parse(readFileSync(path, "utf8"));
|
|
50
|
-
return parsed && typeof parsed === "object" ? parsed : null;
|
|
51
|
-
} catch {
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
function ensureAppHomeMigrated() {
|
|
56
|
-
const configPath = getConfigPath();
|
|
57
|
-
if (existsSync(configPath)) return;
|
|
58
|
-
const legacyConfig = join2(getLegacyAppHome(), "config.json");
|
|
59
|
-
if (!existsSync(legacyConfig)) return;
|
|
60
|
-
mkdirSync(getAppHome(), { recursive: true, mode: 448 });
|
|
61
|
-
copyFileSync(legacyConfig, configPath);
|
|
62
|
-
const legacyVertex = join2(getLegacyAppHome(), "vertex-models.json");
|
|
63
|
-
const vertexPath = join2(getAppHome(), "vertex-models.json");
|
|
64
|
-
if (existsSync(legacyVertex) && !existsSync(vertexPath)) {
|
|
65
|
-
copyFileSync(legacyVertex, vertexPath);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
function ensureConfigMigrated() {
|
|
69
|
-
ensureAppHomeMigrated();
|
|
70
|
-
const configPath = getConfigPath();
|
|
71
|
-
if (existsSync(configPath)) return;
|
|
72
|
-
const legacyPath = getLegacyConfPath();
|
|
73
|
-
if (!existsSync(legacyPath)) return;
|
|
74
|
-
const legacy = readJsonFile(legacyPath);
|
|
75
|
-
if (!legacy) return;
|
|
76
|
-
mkdirSync(dirname(configPath), { recursive: true, mode: 448 });
|
|
77
|
-
writeFileSync(configPath, `${JSON.stringify(legacy, null, 2)}
|
|
78
|
-
`, { encoding: "utf8", mode: 384 });
|
|
79
|
-
try {
|
|
80
|
-
renameSync(legacyPath, `${legacyPath}.migrated`);
|
|
81
|
-
} catch {
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
function readConfig() {
|
|
85
|
-
ensureConfigMigrated();
|
|
86
|
-
return readJsonFile(getConfigPath()) ?? {};
|
|
87
|
-
}
|
|
88
|
-
function loadPreferences() {
|
|
89
|
-
const config = readConfig();
|
|
90
|
-
const lastProvider = config.lastProvider === "opencode" ? "zen" : config.lastProvider;
|
|
91
|
-
return {
|
|
92
|
-
lastBackend: config.lastBackend,
|
|
93
|
-
lastModel: config.lastModel,
|
|
94
|
-
lastProvider,
|
|
95
|
-
lastCodexProvider: config.lastCodexProvider,
|
|
96
|
-
lastCodexModel: config.lastCodexModel,
|
|
97
|
-
lastGeminiProvider: config.lastGeminiProvider,
|
|
98
|
-
lastGeminiModel: config.lastGeminiModel,
|
|
99
|
-
lastAntigravityProvider: config.lastAntigravityProvider,
|
|
100
|
-
lastAntigravityModel: config.lastAntigravityModel,
|
|
101
|
-
lastClaudeTransparentMode: config.lastClaudeTransparentMode,
|
|
102
|
-
recentModelsByProvider: config.recentModelsByProvider,
|
|
103
|
-
favoriteModels: config.favoriteModels,
|
|
104
|
-
antigravityCliFavoriteModels: config.antigravityCliFavoriteModels,
|
|
105
|
-
antigravityCliFavoritesHintShown: config.antigravityCliFavoritesHintShown,
|
|
106
|
-
appPathOverrides: config.appPathOverrides,
|
|
107
|
-
recentLaunchFolders: config.recentLaunchFolders,
|
|
108
|
-
server: config.server
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// src/provider-factory.ts
|
|
113
|
-
import { wrapLanguageModel, extractReasoningMiddleware } from "ai";
|
|
114
|
-
|
|
115
46
|
// src/constants.ts
|
|
116
47
|
import { homedir as homedir2 } from "os";
|
|
117
|
-
import { join as
|
|
48
|
+
import { join as join2 } from "path";
|
|
118
49
|
|
|
119
50
|
// package.json
|
|
120
51
|
var package_default = {
|
|
121
52
|
name: "@jacobbd/relay-ai",
|
|
122
|
-
version: "0.
|
|
53
|
+
version: "0.9.0",
|
|
123
54
|
publishConfig: {
|
|
124
55
|
access: "public"
|
|
125
56
|
},
|
|
@@ -202,10 +133,11 @@ var package_default = {
|
|
|
202
133
|
"@types/node": "^22.0.0",
|
|
203
134
|
"@types/node-forge": "^1.3.14",
|
|
204
135
|
"@types/ws": "^8.18.1",
|
|
205
|
-
"@vitest/coverage-v8": "^
|
|
136
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
206
137
|
tsup: "^8.0.0",
|
|
207
138
|
typescript: "^5.5.0",
|
|
208
|
-
|
|
139
|
+
"vite-node": "^6.0.0",
|
|
140
|
+
vitest: "^4.1.10"
|
|
209
141
|
},
|
|
210
142
|
optionalDependencies: {
|
|
211
143
|
"@napi-rs/keyring": "^1.3.0"
|
|
@@ -227,10 +159,81 @@ var package_default = {
|
|
|
227
159
|
var CODEX_RESPONSES_LITE_WS_URL = "wss://chatgpt.com/backend-api/codex/responses";
|
|
228
160
|
var CODEX_RESPONSES_LITE_VERSION = "0.144.1";
|
|
229
161
|
var CODEX_RESPONSES_WEBSOCKETS_BETA = "responses_websockets=2026-02-06";
|
|
230
|
-
var OPENCODE_CACHE_PATH =
|
|
162
|
+
var OPENCODE_CACHE_PATH = join2(homedir2(), ".cache", "opencode", "models.json");
|
|
163
|
+
var CODEX_SUBAGENT_MODEL_CAP = 1;
|
|
231
164
|
var VERTEX_ANTHROPIC_NPM = "@ai-sdk/google-vertex/anthropic";
|
|
232
165
|
var VERSION = package_default.version;
|
|
233
166
|
|
|
167
|
+
// src/config.ts
|
|
168
|
+
function readJsonFile(path) {
|
|
169
|
+
try {
|
|
170
|
+
const parsed = JSON.parse(readFileSync(path, "utf8"));
|
|
171
|
+
return parsed && typeof parsed === "object" ? parsed : null;
|
|
172
|
+
} catch {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function ensureAppHomeMigrated() {
|
|
177
|
+
const configPath = getConfigPath();
|
|
178
|
+
if (existsSync(configPath)) return;
|
|
179
|
+
const legacyConfig = join3(getLegacyAppHome(), "config.json");
|
|
180
|
+
if (!existsSync(legacyConfig)) return;
|
|
181
|
+
mkdirSync(getAppHome(), { recursive: true, mode: 448 });
|
|
182
|
+
copyFileSync(legacyConfig, configPath);
|
|
183
|
+
const legacyVertex = join3(getLegacyAppHome(), "vertex-models.json");
|
|
184
|
+
const vertexPath = join3(getAppHome(), "vertex-models.json");
|
|
185
|
+
if (existsSync(legacyVertex) && !existsSync(vertexPath)) {
|
|
186
|
+
copyFileSync(legacyVertex, vertexPath);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
function ensureConfigMigrated() {
|
|
190
|
+
ensureAppHomeMigrated();
|
|
191
|
+
const configPath = getConfigPath();
|
|
192
|
+
if (existsSync(configPath)) return;
|
|
193
|
+
const legacyPath = getLegacyConfPath();
|
|
194
|
+
if (!existsSync(legacyPath)) return;
|
|
195
|
+
const legacy = readJsonFile(legacyPath);
|
|
196
|
+
if (!legacy) return;
|
|
197
|
+
mkdirSync(dirname(configPath), { recursive: true, mode: 448 });
|
|
198
|
+
writeFileSync(configPath, `${JSON.stringify(legacy, null, 2)}
|
|
199
|
+
`, { encoding: "utf8", mode: 384 });
|
|
200
|
+
try {
|
|
201
|
+
renameSync(legacyPath, `${legacyPath}.migrated`);
|
|
202
|
+
} catch {
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function readConfig() {
|
|
206
|
+
ensureConfigMigrated();
|
|
207
|
+
return readJsonFile(getConfigPath()) ?? {};
|
|
208
|
+
}
|
|
209
|
+
function loadPreferences() {
|
|
210
|
+
const config = readConfig();
|
|
211
|
+
const lastProvider = config.lastProvider === "opencode" ? "zen" : config.lastProvider;
|
|
212
|
+
return {
|
|
213
|
+
lastBackend: config.lastBackend,
|
|
214
|
+
lastModel: config.lastModel,
|
|
215
|
+
lastProvider,
|
|
216
|
+
lastCodexProvider: config.lastCodexProvider,
|
|
217
|
+
lastCodexModel: config.lastCodexModel,
|
|
218
|
+
lastGeminiProvider: config.lastGeminiProvider,
|
|
219
|
+
lastGeminiModel: config.lastGeminiModel,
|
|
220
|
+
lastAntigravityProvider: config.lastAntigravityProvider,
|
|
221
|
+
lastAntigravityModel: config.lastAntigravityModel,
|
|
222
|
+
lastClaudeTransparentMode: config.lastClaudeTransparentMode,
|
|
223
|
+
recentModelsByProvider: config.recentModelsByProvider,
|
|
224
|
+
favoriteModels: config.favoriteModels,
|
|
225
|
+
codexSubagentModels: Array.isArray(config.codexSubagentModels) ? config.codexSubagentModels.slice(0, CODEX_SUBAGENT_MODEL_CAP) : void 0,
|
|
226
|
+
antigravityCliFavoriteModels: config.antigravityCliFavoriteModels,
|
|
227
|
+
antigravityCliFavoritesHintShown: config.antigravityCliFavoritesHintShown,
|
|
228
|
+
appPathOverrides: config.appPathOverrides,
|
|
229
|
+
recentLaunchFolders: config.recentLaunchFolders,
|
|
230
|
+
server: config.server
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// src/provider-factory.ts
|
|
235
|
+
import { wrapLanguageModel, extractReasoningMiddleware } from "ai";
|
|
236
|
+
|
|
234
237
|
// src/oauth/refresh-http.ts
|
|
235
238
|
async function postOAuthRefresh(url, body, options) {
|
|
236
239
|
const isJson = options.contentType === "json";
|
|
@@ -1710,6 +1713,9 @@ var KEYRING_CHUNK_SIZE = 1200;
|
|
|
1710
1713
|
var LEGACY_KEYRING_SERVICE = "opencode-starter";
|
|
1711
1714
|
var LEGACY_KEYRING_ACCOUNT = "opencode-starter";
|
|
1712
1715
|
var GLOBAL_OPENCODE_KEYRING_ACCOUNT = "global:opencode";
|
|
1716
|
+
function providerKeyringAccount(providerId) {
|
|
1717
|
+
return `provider:${providerId}`;
|
|
1718
|
+
}
|
|
1713
1719
|
function oauthProviderIdFromAccount(account) {
|
|
1714
1720
|
const prefix = "oauth:provider:";
|
|
1715
1721
|
return account.startsWith(prefix) ? account.slice(prefix.length) : null;
|
|
@@ -1801,10 +1807,14 @@ async function readGlobalOpencodeCredential(diag) {
|
|
|
1801
1807
|
}
|
|
1802
1808
|
}
|
|
1803
1809
|
async function resolveProviderCredential(providerId, authRef, diag) {
|
|
1804
|
-
const namespaced = readEnvCredential(relayAiKeyEnvVar(providerId));
|
|
1805
|
-
if (namespaced) return namespaced;
|
|
1806
1810
|
const parsed = parseAuthRef(authRef);
|
|
1807
1811
|
if (!parsed) return null;
|
|
1812
|
+
if (parsed.kind === "keyring" && parsed.account === GLOBAL_OPENCODE_KEYRING_ACCOUNT) {
|
|
1813
|
+
const relayOverride = await readProviderSecret(providerKeyringAccount("opencode"), diag);
|
|
1814
|
+
if (relayOverride) return relayOverride;
|
|
1815
|
+
}
|
|
1816
|
+
const namespaced = readEnvCredential(relayAiKeyEnvVar(providerId));
|
|
1817
|
+
if (namespaced) return namespaced;
|
|
1808
1818
|
if (parsed.kind === "env") {
|
|
1809
1819
|
return readEnvCredential(parsed.varName);
|
|
1810
1820
|
}
|
|
@@ -1814,12 +1824,16 @@ async function resolveProviderCredential(providerId, authRef, diag) {
|
|
|
1814
1824
|
return readProviderSecret(parsed.account, diag);
|
|
1815
1825
|
}
|
|
1816
1826
|
async function forceRefreshProviderCredential(providerId, authRef, diag) {
|
|
1817
|
-
const namespaced = readEnvCredential(relayAiKeyEnvVar(providerId));
|
|
1818
|
-
if (namespaced) return namespaced;
|
|
1819
1827
|
const parsed = parseAuthRef(authRef);
|
|
1820
1828
|
if (!parsed || parsed.kind !== "keyring") {
|
|
1821
1829
|
return resolveProviderCredential(providerId, authRef, diag);
|
|
1822
1830
|
}
|
|
1831
|
+
if (parsed.account === GLOBAL_OPENCODE_KEYRING_ACCOUNT) {
|
|
1832
|
+
const relayOverride = await readProviderSecret(providerKeyringAccount("opencode"), diag);
|
|
1833
|
+
if (relayOverride) return relayOverride;
|
|
1834
|
+
}
|
|
1835
|
+
const namespaced = readEnvCredential(relayAiKeyEnvVar(providerId));
|
|
1836
|
+
if (namespaced) return namespaced;
|
|
1823
1837
|
const oauthProviderId = oauthProviderIdFromAccount(parsed.account);
|
|
1824
1838
|
const raw = await readKeyringAccount(parsed.account, diag);
|
|
1825
1839
|
if (!raw || !oauthProviderId) return decodeProviderSecret(raw);
|