aquaman-plugin 0.2.1 → 0.3.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/index.ts +72 -3
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
|
|
19
19
|
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
20
20
|
import { spawn, execSync, type ChildProcess } from "node:child_process";
|
|
21
|
+
import * as fs from "node:fs";
|
|
22
|
+
import * as path from "node:path";
|
|
23
|
+
import * as os from "node:os";
|
|
21
24
|
import { HttpInterceptor, createHttpInterceptor } from "./src/http-interceptor.js";
|
|
22
25
|
|
|
23
26
|
let proxyProcess: ChildProcess | null = null;
|
|
@@ -155,6 +158,8 @@ function activateHttpInterceptor(log: OpenClawPluginApi["logger"]): void {
|
|
|
155
158
|
['api.anthropic.com', 'anthropic'],
|
|
156
159
|
['api.openai.com', 'openai'],
|
|
157
160
|
['api.github.com', 'github'],
|
|
161
|
+
['api.x.ai', 'xai'],
|
|
162
|
+
['gateway.ai.cloudflare.com', 'cloudflare-ai'],
|
|
158
163
|
// Channel APIs
|
|
159
164
|
['slack.com', 'slack'],
|
|
160
165
|
['*.slack.com', 'slack'],
|
|
@@ -264,12 +269,59 @@ function registerStatusTool(api: OpenClawPluginApi): void {
|
|
|
264
269
|
);
|
|
265
270
|
}
|
|
266
271
|
|
|
272
|
+
/**
|
|
273
|
+
* Auto-generate auth-profiles.json with placeholder keys for proxied services.
|
|
274
|
+
* OpenClaw checks its auth store before making API calls — without a placeholder
|
|
275
|
+
* key, requests are rejected before they ever reach the proxy.
|
|
276
|
+
*/
|
|
277
|
+
function ensureAuthProfiles(log: OpenClawPluginApi["logger"]): void {
|
|
278
|
+
const stateDir =
|
|
279
|
+
process.env.OPENCLAW_STATE_DIR ||
|
|
280
|
+
path.join(os.homedir(), ".openclaw");
|
|
281
|
+
const profilesPath = path.join(
|
|
282
|
+
stateDir,
|
|
283
|
+
"agents",
|
|
284
|
+
"main",
|
|
285
|
+
"agent",
|
|
286
|
+
"auth-profiles.json"
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
if (fs.existsSync(profilesPath)) return;
|
|
290
|
+
|
|
291
|
+
const profiles: Record<string, any> = {};
|
|
292
|
+
const order: Record<string, string[]> = {};
|
|
293
|
+
|
|
294
|
+
for (const service of services) {
|
|
295
|
+
if (service === "anthropic" || service === "openai") {
|
|
296
|
+
profiles[`${service}:default`] = {
|
|
297
|
+
type: "api_key",
|
|
298
|
+
provider: service,
|
|
299
|
+
key: "aquaman-proxy-managed",
|
|
300
|
+
};
|
|
301
|
+
order[service] = [`${service}:default`];
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const dir = path.dirname(profilesPath);
|
|
306
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
307
|
+
fs.writeFileSync(
|
|
308
|
+
profilesPath,
|
|
309
|
+
JSON.stringify({ version: 1, profiles, order }, null, 2)
|
|
310
|
+
);
|
|
311
|
+
log.info(
|
|
312
|
+
`Generated auth-profiles.json with placeholder keys at ${profilesPath}`
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
|
|
267
316
|
/**
|
|
268
317
|
* OpenClaw plugin register function
|
|
269
318
|
*/
|
|
270
319
|
export default function register(api: OpenClawPluginApi): void {
|
|
271
320
|
api.logger.info("Aquaman plugin loaded");
|
|
272
321
|
|
|
322
|
+
// Auto-generate auth-profiles.json if missing
|
|
323
|
+
ensureAuthProfiles(api.logger);
|
|
324
|
+
|
|
273
325
|
const externalUrl = getExternalProxyUrl();
|
|
274
326
|
|
|
275
327
|
// External proxy mode (Docker two-container architecture)
|
|
@@ -304,7 +356,7 @@ export default function register(api: OpenClawPluginApi): void {
|
|
|
304
356
|
"aquaman CLI not found. Install with: npm install -g aquaman-proxy"
|
|
305
357
|
);
|
|
306
358
|
api.logger.warn(
|
|
307
|
-
"
|
|
359
|
+
"Then run: aquaman setup"
|
|
308
360
|
);
|
|
309
361
|
configureEnvironment(api.logger);
|
|
310
362
|
return;
|
|
@@ -327,8 +379,25 @@ export default function register(api: OpenClawPluginApi): void {
|
|
|
327
379
|
// Activate fetch interceptor to redirect channel HTTP traffic through proxy
|
|
328
380
|
activateHttpInterceptor(api.logger);
|
|
329
381
|
} else {
|
|
330
|
-
api.logger.error(
|
|
331
|
-
|
|
382
|
+
api.logger.error(
|
|
383
|
+
`Failed to start aquaman proxy on port ${proxyPort}`
|
|
384
|
+
);
|
|
385
|
+
// Check if another instance is already running on the port
|
|
386
|
+
try {
|
|
387
|
+
const resp = await fetch(
|
|
388
|
+
`http://127.0.0.1:${proxyPort}/_health`
|
|
389
|
+
);
|
|
390
|
+
if (resp.ok) {
|
|
391
|
+
api.logger.info(
|
|
392
|
+
`Another aquaman instance is already running on port ${proxyPort} — using it`
|
|
393
|
+
);
|
|
394
|
+
activateHttpInterceptor(api.logger);
|
|
395
|
+
}
|
|
396
|
+
} catch {
|
|
397
|
+
api.logger.error(
|
|
398
|
+
`Port ${proxyPort} may be in use. Check with: lsof -i :${proxyPort}`
|
|
399
|
+
);
|
|
400
|
+
}
|
|
332
401
|
}
|
|
333
402
|
},
|
|
334
403
|
|