@elvatis_com/openclaw-cli-bridge-elvatis 0.2.8 → 0.2.9
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/index.ts +39 -28
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -354,24 +354,32 @@ const plugin = {
|
|
|
354
354
|
let proxyServer: import("node:http").Server | null = null;
|
|
355
355
|
|
|
356
356
|
if (enableProxy) {
|
|
357
|
-
//
|
|
358
|
-
//
|
|
359
|
-
//
|
|
360
|
-
//
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
357
|
+
// Probe whether a healthy proxy is already listening on our port.
|
|
358
|
+
// This handles hot-reloads where the previous plugin instance's server.close()
|
|
359
|
+
// may not have completed yet — rather than killing anything (dangerous: fuser -k
|
|
360
|
+
// can kill the gateway process itself during in-process hot-reloads), we just
|
|
361
|
+
// check if the existing server still responds and reuse it if so.
|
|
362
|
+
const probeExisting = (): Promise<boolean> => {
|
|
363
|
+
return new Promise((resolve) => {
|
|
364
|
+
const req = http.request(
|
|
365
|
+
{ hostname: "127.0.0.1", port, path: "/v1/models", method: "GET",
|
|
366
|
+
headers: { Authorization: `Bearer ${apiKey}` } },
|
|
367
|
+
(res) => { res.resume(); resolve(res.statusCode === 200); }
|
|
368
|
+
);
|
|
369
|
+
req.setTimeout(800, () => { req.destroy(); resolve(false); });
|
|
370
|
+
req.on("error", () => resolve(false));
|
|
371
|
+
req.end();
|
|
372
|
+
});
|
|
372
373
|
};
|
|
373
374
|
|
|
374
375
|
const startProxy = async (): Promise<void> => {
|
|
376
|
+
// If a healthy proxy is already up, reuse it — no need to rebind.
|
|
377
|
+
const alive = await probeExisting();
|
|
378
|
+
if (alive) {
|
|
379
|
+
api.logger.info(`[cli-bridge] proxy already running on :${port} — reusing`);
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
|
|
375
383
|
try {
|
|
376
384
|
const server = await startProxyServer({
|
|
377
385
|
port,
|
|
@@ -393,25 +401,28 @@ const plugin = {
|
|
|
393
401
|
} catch (err: unknown) {
|
|
394
402
|
const msg = (err as Error).message ?? String(err);
|
|
395
403
|
if (msg.includes("EADDRINUSE")) {
|
|
396
|
-
//
|
|
397
|
-
api.logger.warn(`[cli-bridge] port ${port}
|
|
398
|
-
await new Promise((r) => setTimeout(r,
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
404
|
+
// Port is busy but probe didn't respond — wait for the OS to release it
|
|
405
|
+
api.logger.warn(`[cli-bridge] port ${port} busy, waiting 1s for OS release…`);
|
|
406
|
+
await new Promise((r) => setTimeout(r, 1000));
|
|
407
|
+
// One final attempt
|
|
408
|
+
try {
|
|
409
|
+
const server = await startProxyServer({
|
|
410
|
+
port, apiKey, timeoutMs,
|
|
411
|
+
log: (msg) => api.logger.info(msg),
|
|
412
|
+
warn: (msg) => api.logger.warn(msg),
|
|
413
|
+
});
|
|
414
|
+
proxyServer = server;
|
|
415
|
+
api.logger.info(`[cli-bridge] proxy ready on :${port} (retry)`);
|
|
416
|
+
} catch (e2: unknown) {
|
|
417
|
+
api.logger.warn(`[cli-bridge] proxy unavailable after retry: ${(e2 as Error).message}`);
|
|
418
|
+
}
|
|
408
419
|
} else {
|
|
409
420
|
api.logger.warn(`[cli-bridge] proxy failed to start on port ${port}: ${msg}`);
|
|
410
421
|
}
|
|
411
422
|
}
|
|
412
423
|
};
|
|
413
424
|
|
|
414
|
-
|
|
425
|
+
startProxy().catch(() => {});
|
|
415
426
|
}
|
|
416
427
|
|
|
417
428
|
// ── Cleanup: close proxy server on plugin stop (hot-reload / gateway restart) ──
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "openclaw-cli-bridge-elvatis",
|
|
3
3
|
"name": "OpenClaw CLI Bridge",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.9",
|
|
5
5
|
"description": "Phase 1: openai-codex auth bridge. Phase 2: local HTTP proxy routing model calls through gemini/claude CLIs (vllm provider).",
|
|
6
6
|
"providers": [
|
|
7
7
|
"openai-codex"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elvatis_com/openclaw-cli-bridge-elvatis",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.9",
|
|
4
4
|
"description": "Bridges gemini, claude, and codex CLI tools as OpenClaw model providers. Reads existing CLI auth without re-login.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"openclaw": {
|