jbai-cli 1.8.0 → 1.8.2
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/bin/jbai-codex.js +52 -25
- package/bin/jbai-opencode.js +1 -1
- package/package.json +1 -1
package/bin/jbai-codex.js
CHANGED
|
@@ -4,14 +4,45 @@ const { runWithHandoff, stripHandoffFlag } = require('../lib/interactive-handoff
|
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const path = require('path');
|
|
6
6
|
const os = require('os');
|
|
7
|
+
const http = require('http');
|
|
7
8
|
const config = require('../lib/config');
|
|
8
9
|
const { ensureToken } = require('../lib/ensure-token');
|
|
9
10
|
|
|
11
|
+
const PROXY_PORT = 18080;
|
|
12
|
+
const PROXY_PROVIDER = 'jbai-proxy';
|
|
13
|
+
|
|
14
|
+
function isProxyRunning() {
|
|
15
|
+
return new Promise((resolve) => {
|
|
16
|
+
const req = http.get(`http://127.0.0.1:${PROXY_PORT}/health`, { timeout: 1000 }, (res) => {
|
|
17
|
+
let body = '';
|
|
18
|
+
res.on('data', chunk => body += chunk);
|
|
19
|
+
res.on('end', () => {
|
|
20
|
+
try {
|
|
21
|
+
const info = JSON.parse(body);
|
|
22
|
+
resolve(info.status === 'ok');
|
|
23
|
+
} catch {
|
|
24
|
+
resolve(false);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
req.on('error', () => resolve(false));
|
|
29
|
+
req.on('timeout', () => { req.destroy(); resolve(false); });
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function startProxy() {
|
|
34
|
+
const { spawn } = require('child_process');
|
|
35
|
+
const proxyScript = path.join(__dirname, 'jbai-proxy.js');
|
|
36
|
+
const child = spawn(process.execPath, [proxyScript, '--port', String(PROXY_PORT), '--_daemon'], {
|
|
37
|
+
detached: true,
|
|
38
|
+
stdio: 'ignore',
|
|
39
|
+
});
|
|
40
|
+
child.unref();
|
|
41
|
+
}
|
|
42
|
+
|
|
10
43
|
(async () => {
|
|
11
44
|
const token = await ensureToken();
|
|
12
|
-
const endpoints = config.getEndpoints();
|
|
13
45
|
const environment = config.getEnvironment();
|
|
14
|
-
const providerName = environment === 'staging' ? 'jbai-staging' : 'jbai';
|
|
15
46
|
const envVarName = environment === 'staging' ? 'GRAZIE_STAGING_TOKEN' : 'GRAZIE_API_TOKEN';
|
|
16
47
|
let args = process.argv.slice(2);
|
|
17
48
|
const handoffConfig = stripHandoffFlag(args);
|
|
@@ -22,6 +53,13 @@ const { ensureToken } = require('../lib/ensure-token');
|
|
|
22
53
|
const superMode = args.some(a => superFlags.includes(a));
|
|
23
54
|
args = args.filter(a => !superFlags.includes(a));
|
|
24
55
|
|
|
56
|
+
// Auto-start proxy if not running (serves /v1/models with our model list)
|
|
57
|
+
if (!await isProxyRunning()) {
|
|
58
|
+
startProxy();
|
|
59
|
+
// Wait briefly for proxy to start
|
|
60
|
+
await new Promise(r => setTimeout(r, 500));
|
|
61
|
+
}
|
|
62
|
+
|
|
25
63
|
// Ensure Codex config exists
|
|
26
64
|
const codexDir = path.join(os.homedir(), '.codex');
|
|
27
65
|
const codexConfig = path.join(codexDir, 'config.toml');
|
|
@@ -30,40 +68,28 @@ const { ensureToken } = require('../lib/ensure-token');
|
|
|
30
68
|
fs.mkdirSync(codexDir, { recursive: true });
|
|
31
69
|
}
|
|
32
70
|
|
|
33
|
-
// Check if our provider is configured
|
|
71
|
+
// Check if our proxy provider is configured
|
|
34
72
|
let configContent = '';
|
|
35
73
|
if (fs.existsSync(codexConfig)) {
|
|
36
74
|
configContent = fs.readFileSync(codexConfig, 'utf-8');
|
|
37
75
|
}
|
|
38
76
|
|
|
39
|
-
if (!configContent.includes(`[model_providers.${
|
|
77
|
+
if (!configContent.includes(`[model_providers.${PROXY_PROVIDER}]`)) {
|
|
40
78
|
const providerConfig = `
|
|
41
|
-
# JetBrains AI (
|
|
42
|
-
[model_providers.${
|
|
43
|
-
name = "JetBrains AI (
|
|
44
|
-
base_url = "
|
|
45
|
-
|
|
79
|
+
# JetBrains AI via local proxy (serves model list + auto-injects auth)
|
|
80
|
+
[model_providers.${PROXY_PROVIDER}]
|
|
81
|
+
name = "JetBrains AI (Proxy)"
|
|
82
|
+
base_url = "http://localhost:${PROXY_PORT}/openai/v1"
|
|
83
|
+
env_key = "JBAI_PROXY_KEY"
|
|
46
84
|
wire_api = "responses"
|
|
47
85
|
`;
|
|
48
86
|
fs.appendFileSync(codexConfig, providerConfig);
|
|
49
|
-
console.log(`✅ Added ${
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Point Codex model picker to our proxy (serves our model list instead of chatgpt.com)
|
|
53
|
-
const proxyModelUrl = 'http://localhost:18080/';
|
|
54
|
-
if (!configContent.includes('chatgpt_base_url')) {
|
|
55
|
-
fs.appendFileSync(codexConfig, `\nchatgpt_base_url = "${proxyModelUrl}"\n`);
|
|
56
|
-
console.log('✅ Set chatgpt_base_url to jbai-proxy for model picker');
|
|
57
|
-
} else if (!configContent.includes(proxyModelUrl)) {
|
|
58
|
-
// Update existing chatgpt_base_url
|
|
59
|
-
configContent = fs.readFileSync(codexConfig, 'utf-8');
|
|
60
|
-
const updated = configContent.replace(/^chatgpt_base_url\s*=\s*"[^"]*"/m, `chatgpt_base_url = "${proxyModelUrl}"`);
|
|
61
|
-
fs.writeFileSync(codexConfig, updated);
|
|
62
|
-
console.log('✅ Updated chatgpt_base_url to jbai-proxy');
|
|
87
|
+
console.log(`✅ Added ${PROXY_PROVIDER} provider to Codex config`);
|
|
63
88
|
}
|
|
64
89
|
|
|
65
90
|
const hasModel = args.includes('--model');
|
|
66
|
-
|
|
91
|
+
// Use proxy provider so Codex fetches /v1/models from our proxy (shows all Grazie models)
|
|
92
|
+
const finalArgs = ['-c', `model_provider=${PROXY_PROVIDER}`];
|
|
67
93
|
|
|
68
94
|
if (!hasModel) {
|
|
69
95
|
finalArgs.push('--model', config.MODELS.codex?.default || config.MODELS.openai.default);
|
|
@@ -79,7 +105,8 @@ wire_api = "responses"
|
|
|
79
105
|
|
|
80
106
|
const childEnv = {
|
|
81
107
|
...process.env,
|
|
82
|
-
[envVarName]: token
|
|
108
|
+
[envVarName]: token,
|
|
109
|
+
JBAI_PROXY_KEY: 'placeholder', // Proxy handles auth via Grazie JWT
|
|
83
110
|
};
|
|
84
111
|
|
|
85
112
|
const child = runWithHandoff({
|
package/bin/jbai-opencode.js
CHANGED
|
@@ -114,7 +114,7 @@ const { ensureToken } = require('../lib/ensure-token');
|
|
|
114
114
|
|
|
115
115
|
// Check if model specified
|
|
116
116
|
const hasModel = args.includes('--model') || args.includes('-m');
|
|
117
|
-
let finalArgs = [
|
|
117
|
+
let finalArgs = [];
|
|
118
118
|
|
|
119
119
|
if (!hasModel) {
|
|
120
120
|
// Use provider/model format for OpenCode
|