openclaw-abacusai-auth 1.2.4 → 1.2.5
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 +47 -18
- package/openclaw.plugin.json +1 -1
- package/package.json +8 -1
- package/tsconfig.json +16 -0
package/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
1
|
+
import { existsSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { createServer, type IncomingMessage, type ServerResponse } from "node:http";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
@@ -15,8 +15,9 @@ const DEFAULT_MAX_TOKENS = 8192;
|
|
|
15
15
|
|
|
16
16
|
// Proxy configuration
|
|
17
17
|
const PROXY_HOST = "127.0.0.1";
|
|
18
|
-
//
|
|
19
|
-
|
|
18
|
+
// Fixed port for the proxy so the baseUrl saved at auth time always works
|
|
19
|
+
const PROXY_PORT_DEFAULT = 18862;
|
|
20
|
+
let proxyPort = PROXY_PORT_DEFAULT;
|
|
20
21
|
|
|
21
22
|
// Models available on AbacusAI RouteLLM endpoint (OpenAI-compatible, with
|
|
22
23
|
// function calling support). Verified 2026-02.
|
|
@@ -443,6 +444,13 @@ function normalizeToolsForRouteLLM(tools: unknown[]): unknown[] {
|
|
|
443
444
|
fn.parameters = cleanSchema(fn.parameters);
|
|
444
445
|
}
|
|
445
446
|
|
|
447
|
+
// RouteLLM REQUIRES every tool to have a `parameters` field.
|
|
448
|
+
// If a tool has no parameters (e.g. cognitive_assess, flare_plan),
|
|
449
|
+
// add a default empty object schema.
|
|
450
|
+
if (!fn.parameters) {
|
|
451
|
+
fn.parameters = { type: "object", properties: {} };
|
|
452
|
+
}
|
|
453
|
+
|
|
446
454
|
copy.function = fn;
|
|
447
455
|
|
|
448
456
|
// Promote name and parameters to top level for RouteLLM
|
|
@@ -559,6 +567,8 @@ async function handleProxyRequest(req: IncomingMessage, res: ServerResponse) {
|
|
|
559
567
|
const parsed = JSON.parse(raw.toString()) as Record<string, unknown>;
|
|
560
568
|
// Normalize tools for RouteLLM: remove `strict` field, clean schemas
|
|
561
569
|
// (remove patternProperties, add additionalProperties: false, etc.)
|
|
570
|
+
|
|
571
|
+
|
|
562
572
|
if (Array.isArray(parsed.tools)) {
|
|
563
573
|
parsed.tools = normalizeToolsForRouteLLM(parsed.tools);
|
|
564
574
|
}
|
|
@@ -677,18 +687,34 @@ function startProxy(apiKey: string): Promise<void> {
|
|
|
677
687
|
sendJsonResponse(res, 500, { error: { message: String(err) } });
|
|
678
688
|
});
|
|
679
689
|
});
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
proxyPort =
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
690
|
+
|
|
691
|
+
// Try fixed port first, then retry with port+1, +2, etc.
|
|
692
|
+
const tryListen = (port: number, attempt: number) => {
|
|
693
|
+
proxyServer!.listen(port, PROXY_HOST, () => {
|
|
694
|
+
proxyPort = port;
|
|
695
|
+
console.log(`[abacusai] proxy listening on http://${PROXY_HOST}:${proxyPort}`);
|
|
696
|
+
resolve();
|
|
697
|
+
});
|
|
698
|
+
proxyServer!.once("error", (err: NodeJS.ErrnoException) => {
|
|
699
|
+
if (err.code === "EADDRINUSE" && attempt < 10) {
|
|
700
|
+
console.log(`[abacusai] port ${port} in use, trying ${port + 1}...`);
|
|
701
|
+
proxyServer!.removeAllListeners("error");
|
|
702
|
+
proxyServer!.close(() => {
|
|
703
|
+
proxyServer = createServer((req, res) => {
|
|
704
|
+
handleProxyRequest(req, res).catch((e) => {
|
|
705
|
+
console.error("[abacusai] proxy error:", e);
|
|
706
|
+
sendJsonResponse(res, 500, { error: { message: String(e) } });
|
|
707
|
+
});
|
|
708
|
+
});
|
|
709
|
+
tryListen(port + 1, attempt + 1);
|
|
710
|
+
});
|
|
711
|
+
} else {
|
|
712
|
+
reject(err);
|
|
713
|
+
}
|
|
714
|
+
});
|
|
715
|
+
};
|
|
716
|
+
|
|
717
|
+
tryListen(PROXY_PORT_DEFAULT, 0);
|
|
692
718
|
});
|
|
693
719
|
}
|
|
694
720
|
|
|
@@ -742,7 +768,9 @@ function updateBaseUrlInConfig(): void {
|
|
|
742
768
|
const configPath = join(stateDir, "openclaw.json");
|
|
743
769
|
if (!existsSync(configPath)) return;
|
|
744
770
|
|
|
745
|
-
|
|
771
|
+
let raw = readFileSync(configPath, "utf-8");
|
|
772
|
+
// Strip UTF-8 BOM if present
|
|
773
|
+
if (raw.charCodeAt(0) === 0xFEFF) raw = raw.slice(1);
|
|
746
774
|
const config = JSON.parse(raw);
|
|
747
775
|
const currentUrl = config?.models?.providers?.abacusai?.baseUrl;
|
|
748
776
|
|
|
@@ -783,7 +811,7 @@ interface PluginAuthContext {
|
|
|
783
811
|
}
|
|
784
812
|
|
|
785
813
|
const abacusaiPlugin = {
|
|
786
|
-
id: "abacusai-auth",
|
|
814
|
+
id: "openclaw-abacusai-auth",
|
|
787
815
|
name: "AbacusAI Auth",
|
|
788
816
|
description: "AbacusAI RouteLLM provider plugin with direct connection and schema normalization",
|
|
789
817
|
configSchema: emptyPluginConfigSchema(),
|
|
@@ -934,7 +962,7 @@ const abacusaiPlugin = {
|
|
|
934
962
|
// and adding `additionalProperties: false`
|
|
935
963
|
baseUrl: `http://${PROXY_HOST}:${proxyPort}`,
|
|
936
964
|
api: "openai-completions",
|
|
937
|
-
|
|
965
|
+
apiKey: "abacusai-proxy",
|
|
938
966
|
models: modelIds.map((id) => buildModelDefinition(id)),
|
|
939
967
|
},
|
|
940
968
|
},
|
|
@@ -965,3 +993,4 @@ const abacusaiPlugin = {
|
|
|
965
993
|
};
|
|
966
994
|
|
|
967
995
|
export default abacusaiPlugin;
|
|
996
|
+
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openclaw-abacusai-auth",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.5",
|
|
4
4
|
"description": "OpenClaw AbacusAI provider plugin - Third-party plugin for AbacusAI RouteLLM integration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
],
|
|
19
19
|
"author": "tonyhu2006",
|
|
20
20
|
"license": "MIT",
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsc"
|
|
23
|
+
},
|
|
21
24
|
"peerDependencies": {
|
|
22
25
|
"openclaw": ">=2026.2.0"
|
|
23
26
|
},
|
|
@@ -25,5 +28,9 @@
|
|
|
25
28
|
"extensions": [
|
|
26
29
|
"./index.ts"
|
|
27
30
|
]
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^25.3.3",
|
|
34
|
+
"typescript": "^5.9.3"
|
|
28
35
|
}
|
|
29
36
|
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es2022",
|
|
4
|
+
"module": "nodenext",
|
|
5
|
+
"moduleResolution": "nodenext",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"forceConsistentCasingInFileNames": true,
|
|
10
|
+
"outDir": "./dist",
|
|
11
|
+
"declaration": true
|
|
12
|
+
},
|
|
13
|
+
"include": [
|
|
14
|
+
"index.ts"
|
|
15
|
+
]
|
|
16
|
+
}
|