@annals/agent-bridge 0.1.3 → 0.1.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/dist/chunk-W24WCWEC.js +86 -0
- package/dist/index.js +113 -219
- package/dist/openclaw-config-OFFNWVDK.js +11 -0
- package/package.json +1 -1
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/utils/openclaw-config.ts
|
|
4
|
+
import { readFileSync } from "fs";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
import { homedir } from "os";
|
|
7
|
+
|
|
8
|
+
// src/utils/logger.ts
|
|
9
|
+
var RESET = "\x1B[0m";
|
|
10
|
+
var RED = "\x1B[31m";
|
|
11
|
+
var GREEN = "\x1B[32m";
|
|
12
|
+
var YELLOW = "\x1B[33m";
|
|
13
|
+
var BLUE = "\x1B[34m";
|
|
14
|
+
var GRAY = "\x1B[90m";
|
|
15
|
+
var BOLD = "\x1B[1m";
|
|
16
|
+
function timestamp() {
|
|
17
|
+
return (/* @__PURE__ */ new Date()).toISOString().slice(11, 19);
|
|
18
|
+
}
|
|
19
|
+
var log = {
|
|
20
|
+
info(msg, ...args) {
|
|
21
|
+
console.log(`${GRAY}${timestamp()}${RESET} ${BLUE}INFO${RESET} ${msg}`, ...args);
|
|
22
|
+
},
|
|
23
|
+
success(msg, ...args) {
|
|
24
|
+
console.log(`${GRAY}${timestamp()}${RESET} ${GREEN}OK${RESET} ${msg}`, ...args);
|
|
25
|
+
},
|
|
26
|
+
warn(msg, ...args) {
|
|
27
|
+
console.warn(`${GRAY}${timestamp()}${RESET} ${YELLOW}WARN${RESET} ${msg}`, ...args);
|
|
28
|
+
},
|
|
29
|
+
error(msg, ...args) {
|
|
30
|
+
console.error(`${GRAY}${timestamp()}${RESET} ${RED}ERROR${RESET} ${msg}`, ...args);
|
|
31
|
+
},
|
|
32
|
+
debug(msg, ...args) {
|
|
33
|
+
if (process.env.DEBUG) {
|
|
34
|
+
console.log(`${GRAY}${timestamp()} DEBUG ${msg}${RESET}`, ...args);
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
banner(text) {
|
|
38
|
+
console.log(`
|
|
39
|
+
${BOLD}${text}${RESET}
|
|
40
|
+
`);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// src/utils/openclaw-config.ts
|
|
45
|
+
var OPENCLAW_CONFIG_PATH = join(homedir(), ".openclaw", "openclaw.json");
|
|
46
|
+
function readOpenClawConfig(configPath) {
|
|
47
|
+
const path = configPath || OPENCLAW_CONFIG_PATH;
|
|
48
|
+
try {
|
|
49
|
+
const raw = readFileSync(path, "utf-8");
|
|
50
|
+
return JSON.parse(raw);
|
|
51
|
+
} catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function isChatCompletionsEnabled(configPath) {
|
|
56
|
+
const config = readOpenClawConfig(configPath);
|
|
57
|
+
if (!config) return false;
|
|
58
|
+
try {
|
|
59
|
+
const enabled = config?.gateway?.http?.endpoints?.chatCompletions?.enabled;
|
|
60
|
+
return enabled === true;
|
|
61
|
+
} catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function readOpenClawToken(configPath) {
|
|
66
|
+
const path = configPath || OPENCLAW_CONFIG_PATH;
|
|
67
|
+
try {
|
|
68
|
+
const raw = readFileSync(path, "utf-8");
|
|
69
|
+
const config = JSON.parse(raw);
|
|
70
|
+
const token = config?.gateway?.auth?.token;
|
|
71
|
+
if (typeof token === "string" && token.length > 0) {
|
|
72
|
+
return token;
|
|
73
|
+
}
|
|
74
|
+
log.warn("OpenClaw config found but gateway.auth.token is missing or empty");
|
|
75
|
+
return null;
|
|
76
|
+
} catch {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export {
|
|
82
|
+
log,
|
|
83
|
+
readOpenClawConfig,
|
|
84
|
+
isChatCompletionsEnabled,
|
|
85
|
+
readOpenClawToken
|
|
86
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
log,
|
|
4
|
+
readOpenClawToken
|
|
5
|
+
} from "./chunk-W24WCWEC.js";
|
|
2
6
|
|
|
3
7
|
// src/index.ts
|
|
4
8
|
import { program } from "commander";
|
|
@@ -49,44 +53,6 @@ function hasToken() {
|
|
|
49
53
|
import { EventEmitter } from "events";
|
|
50
54
|
import WebSocket from "ws";
|
|
51
55
|
import { BRIDGE_PROTOCOL_VERSION } from "@annals/bridge-protocol";
|
|
52
|
-
|
|
53
|
-
// src/utils/logger.ts
|
|
54
|
-
var RESET = "\x1B[0m";
|
|
55
|
-
var RED = "\x1B[31m";
|
|
56
|
-
var GREEN = "\x1B[32m";
|
|
57
|
-
var YELLOW = "\x1B[33m";
|
|
58
|
-
var BLUE = "\x1B[34m";
|
|
59
|
-
var GRAY = "\x1B[90m";
|
|
60
|
-
var BOLD = "\x1B[1m";
|
|
61
|
-
function timestamp() {
|
|
62
|
-
return (/* @__PURE__ */ new Date()).toISOString().slice(11, 19);
|
|
63
|
-
}
|
|
64
|
-
var log = {
|
|
65
|
-
info(msg, ...args) {
|
|
66
|
-
console.log(`${GRAY}${timestamp()}${RESET} ${BLUE}INFO${RESET} ${msg}`, ...args);
|
|
67
|
-
},
|
|
68
|
-
success(msg, ...args) {
|
|
69
|
-
console.log(`${GRAY}${timestamp()}${RESET} ${GREEN}OK${RESET} ${msg}`, ...args);
|
|
70
|
-
},
|
|
71
|
-
warn(msg, ...args) {
|
|
72
|
-
console.warn(`${GRAY}${timestamp()}${RESET} ${YELLOW}WARN${RESET} ${msg}`, ...args);
|
|
73
|
-
},
|
|
74
|
-
error(msg, ...args) {
|
|
75
|
-
console.error(`${GRAY}${timestamp()}${RESET} ${RED}ERROR${RESET} ${msg}`, ...args);
|
|
76
|
-
},
|
|
77
|
-
debug(msg, ...args) {
|
|
78
|
-
if (process.env.DEBUG) {
|
|
79
|
-
console.log(`${GRAY}${timestamp()} DEBUG ${msg}${RESET}`, ...args);
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
banner(text) {
|
|
83
|
-
console.log(`
|
|
84
|
-
${BOLD}${text}${RESET}
|
|
85
|
-
`);
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
// src/platform/ws-client.ts
|
|
90
56
|
var HEARTBEAT_INTERVAL = 3e4;
|
|
91
57
|
var INITIAL_RECONNECT_DELAY = 1e3;
|
|
92
58
|
var MAX_RECONNECT_DELAY = 3e4;
|
|
@@ -399,39 +365,34 @@ var BridgeManager = class {
|
|
|
399
365
|
}
|
|
400
366
|
};
|
|
401
367
|
|
|
402
|
-
// src/adapters/openclaw.ts
|
|
403
|
-
import WebSocket2 from "ws";
|
|
404
|
-
import { randomUUID } from "crypto";
|
|
405
|
-
|
|
406
368
|
// src/adapters/base.ts
|
|
407
369
|
var AgentAdapter = class {
|
|
408
370
|
};
|
|
409
371
|
|
|
410
372
|
// src/adapters/openclaw.ts
|
|
411
|
-
var DEFAULT_GATEWAY_URL = "
|
|
373
|
+
var DEFAULT_GATEWAY_URL = "http://127.0.0.1:18789";
|
|
374
|
+
function normalizeUrl(url) {
|
|
375
|
+
if (url.startsWith("wss://")) return url.replace("wss://", "https://");
|
|
376
|
+
if (url.startsWith("ws://")) return url.replace("ws://", "http://");
|
|
377
|
+
return url;
|
|
378
|
+
}
|
|
412
379
|
var OpenClawSession = class {
|
|
413
380
|
constructor(sessionId, config) {
|
|
414
381
|
this.config = config;
|
|
415
|
-
this.
|
|
416
|
-
this.
|
|
417
|
-
this.sessionKey =
|
|
418
|
-
}
|
|
382
|
+
this.baseUrl = normalizeUrl(config.gatewayUrl || DEFAULT_GATEWAY_URL);
|
|
383
|
+
this.token = config.gatewayToken || "";
|
|
384
|
+
this.sessionKey = sessionId;
|
|
385
|
+
}
|
|
386
|
+
messages = [];
|
|
387
|
+
abortController = null;
|
|
388
|
+
baseUrl;
|
|
389
|
+
token;
|
|
390
|
+
sessionKey;
|
|
419
391
|
chunkCallbacks = [];
|
|
420
392
|
doneCallbacks = [];
|
|
421
393
|
errorCallbacks = [];
|
|
422
|
-
fullText = "";
|
|
423
|
-
ws = null;
|
|
424
|
-
isConnected = false;
|
|
425
|
-
gatewayUrl;
|
|
426
|
-
gatewayToken;
|
|
427
|
-
sessionKey;
|
|
428
394
|
send(message, _attachments) {
|
|
429
|
-
|
|
430
|
-
this.sendAgentRequest(message);
|
|
431
|
-
return;
|
|
432
|
-
}
|
|
433
|
-
this.fullText = "";
|
|
434
|
-
this.connectAndSend(message);
|
|
395
|
+
this.sendRequest(message);
|
|
435
396
|
}
|
|
436
397
|
onChunk(cb) {
|
|
437
398
|
this.chunkCallbacks.push(cb);
|
|
@@ -443,130 +404,78 @@ var OpenClawSession = class {
|
|
|
443
404
|
this.errorCallbacks.push(cb);
|
|
444
405
|
}
|
|
445
406
|
kill() {
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
this.ws = null;
|
|
449
|
-
}
|
|
450
|
-
this.isConnected = false;
|
|
451
|
-
}
|
|
452
|
-
connectAndSend(message) {
|
|
453
|
-
try {
|
|
454
|
-
this.ws = new WebSocket2(this.gatewayUrl);
|
|
455
|
-
} catch (err) {
|
|
456
|
-
this.emitError(new Error(`Failed to connect to OpenClaw: ${err}`));
|
|
457
|
-
return;
|
|
458
|
-
}
|
|
459
|
-
this.ws.on("open", () => {
|
|
460
|
-
log.debug(`OpenClaw WS connected to ${this.gatewayUrl}`);
|
|
461
|
-
const connectMsg = {
|
|
462
|
-
type: "req",
|
|
463
|
-
id: randomUUID(),
|
|
464
|
-
method: "connect",
|
|
465
|
-
params: {
|
|
466
|
-
minProtocol: 3,
|
|
467
|
-
maxProtocol: 3,
|
|
468
|
-
client: {
|
|
469
|
-
id: "gateway-client",
|
|
470
|
-
displayName: "Agent Bridge CLI",
|
|
471
|
-
version: "0.1.0",
|
|
472
|
-
platform: "node",
|
|
473
|
-
mode: "backend"
|
|
474
|
-
},
|
|
475
|
-
role: "operator",
|
|
476
|
-
scopes: ["operator.read", "operator.write"],
|
|
477
|
-
caps: [],
|
|
478
|
-
commands: [],
|
|
479
|
-
permissions: {},
|
|
480
|
-
auth: { token: this.gatewayToken }
|
|
481
|
-
}
|
|
482
|
-
};
|
|
483
|
-
this.ws.send(JSON.stringify(connectMsg));
|
|
484
|
-
});
|
|
485
|
-
this.ws.on("message", (data) => {
|
|
486
|
-
this.handleMessage(data.toString(), message);
|
|
487
|
-
});
|
|
488
|
-
this.ws.on("error", (err) => {
|
|
489
|
-
this.emitError(new Error(`OpenClaw WebSocket error: ${err.message}`));
|
|
490
|
-
});
|
|
491
|
-
this.ws.on("close", () => {
|
|
492
|
-
this.isConnected = false;
|
|
493
|
-
});
|
|
407
|
+
this.abortController?.abort();
|
|
408
|
+
this.abortController = null;
|
|
494
409
|
}
|
|
495
|
-
|
|
496
|
-
|
|
410
|
+
async sendRequest(message) {
|
|
411
|
+
this.messages.push({ role: "user", content: message });
|
|
412
|
+
this.abortController = new AbortController();
|
|
497
413
|
try {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
this.ws?.close();
|
|
517
|
-
}
|
|
518
|
-
return;
|
|
519
|
-
}
|
|
520
|
-
if (msg.type === "event" && msg.event === "agent" && msg.payload) {
|
|
521
|
-
const { stream, data } = msg.payload;
|
|
522
|
-
if (stream === "assistant" && data?.text) {
|
|
523
|
-
const prevLen = this.fullText.length;
|
|
524
|
-
this.fullText = data.text;
|
|
525
|
-
if (this.fullText.length > prevLen) {
|
|
526
|
-
const delta = this.fullText.slice(prevLen);
|
|
527
|
-
for (const cb of this.chunkCallbacks) cb(delta);
|
|
528
|
-
}
|
|
414
|
+
const response = await fetch(`${this.baseUrl}/v1/chat/completions`, {
|
|
415
|
+
method: "POST",
|
|
416
|
+
headers: {
|
|
417
|
+
"Content-Type": "application/json",
|
|
418
|
+
"Authorization": `Bearer ${this.token}`,
|
|
419
|
+
"x-openclaw-session-key": this.sessionKey
|
|
420
|
+
},
|
|
421
|
+
body: JSON.stringify({
|
|
422
|
+
model: "openclaw:main",
|
|
423
|
+
messages: [...this.messages],
|
|
424
|
+
stream: true
|
|
425
|
+
}),
|
|
426
|
+
signal: this.abortController.signal
|
|
427
|
+
});
|
|
428
|
+
if (!response.ok) {
|
|
429
|
+
const text = await response.text().catch(() => "");
|
|
430
|
+
this.emitError(new Error(`OpenClaw HTTP ${response.status}: ${text || response.statusText}`));
|
|
431
|
+
return;
|
|
529
432
|
}
|
|
530
|
-
if (
|
|
531
|
-
|
|
433
|
+
if (!response.body) {
|
|
434
|
+
this.emitError(new Error("OpenClaw response has no body"));
|
|
435
|
+
return;
|
|
532
436
|
}
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
437
|
+
const reader = response.body.getReader();
|
|
438
|
+
const decoder = new TextDecoder();
|
|
439
|
+
let buffer = "";
|
|
440
|
+
let fullText = "";
|
|
441
|
+
while (true) {
|
|
442
|
+
const { done, value } = await reader.read();
|
|
443
|
+
if (done) break;
|
|
444
|
+
buffer += decoder.decode(value, { stream: true });
|
|
445
|
+
const lines = buffer.split("\n");
|
|
446
|
+
buffer = lines.pop();
|
|
447
|
+
for (const line of lines) {
|
|
448
|
+
const trimmed = line.trim();
|
|
449
|
+
if (!trimmed || trimmed.startsWith(":")) continue;
|
|
450
|
+
if (!trimmed.startsWith("data: ")) continue;
|
|
451
|
+
const data = trimmed.slice(6);
|
|
452
|
+
if (data === "[DONE]") {
|
|
453
|
+
if (fullText) {
|
|
454
|
+
this.messages.push({ role: "assistant", content: fullText });
|
|
455
|
+
}
|
|
456
|
+
for (const cb of this.doneCallbacks) cb();
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
try {
|
|
460
|
+
const parsed = JSON.parse(data);
|
|
461
|
+
const content = parsed.choices?.[0]?.delta?.content;
|
|
462
|
+
if (content) {
|
|
463
|
+
fullText += content;
|
|
464
|
+
for (const cb of this.chunkCallbacks) cb(content);
|
|
465
|
+
}
|
|
466
|
+
} catch {
|
|
467
|
+
}
|
|
542
468
|
}
|
|
543
|
-
for (const cb of this.doneCallbacks) cb();
|
|
544
|
-
} else {
|
|
545
|
-
this.emitError(
|
|
546
|
-
new Error(`OpenClaw error: ${msg.error?.message || "unknown"}`)
|
|
547
|
-
);
|
|
548
469
|
}
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
if (msg.type === "error") {
|
|
552
|
-
this.emitError(new Error(`OpenClaw error: ${msg.message || "unknown"}`));
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
sendAgentRequest(message) {
|
|
556
|
-
const req = {
|
|
557
|
-
type: "req",
|
|
558
|
-
id: randomUUID(),
|
|
559
|
-
method: "agent",
|
|
560
|
-
params: {
|
|
561
|
-
message,
|
|
562
|
-
sessionKey: this.sessionKey,
|
|
563
|
-
idempotencyKey: `idem-${Date.now()}-${randomUUID().slice(0, 8)}`
|
|
470
|
+
if (fullText) {
|
|
471
|
+
this.messages.push({ role: "assistant", content: fullText });
|
|
564
472
|
}
|
|
565
|
-
|
|
566
|
-
try {
|
|
567
|
-
this.ws.send(JSON.stringify(req));
|
|
473
|
+
for (const cb of this.doneCallbacks) cb();
|
|
568
474
|
} catch (err) {
|
|
569
|
-
|
|
475
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
this.emitError(err instanceof Error ? err : new Error(String(err)));
|
|
570
479
|
}
|
|
571
480
|
}
|
|
572
481
|
emitError(err) {
|
|
@@ -587,30 +496,28 @@ var OpenClawAdapter = class extends AgentAdapter {
|
|
|
587
496
|
this.config = config;
|
|
588
497
|
}
|
|
589
498
|
async isAvailable() {
|
|
590
|
-
const
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
resolve(false);
|
|
602
|
-
return;
|
|
603
|
-
}
|
|
604
|
-
ws.on("open", () => {
|
|
605
|
-
clearTimeout(timer);
|
|
606
|
-
ws.close();
|
|
607
|
-
resolve(true);
|
|
608
|
-
});
|
|
609
|
-
ws.on("error", () => {
|
|
610
|
-
clearTimeout(timer);
|
|
611
|
-
resolve(false);
|
|
499
|
+
const baseUrl = normalizeUrl(this.config.gatewayUrl || DEFAULT_GATEWAY_URL);
|
|
500
|
+
try {
|
|
501
|
+
const response = await fetch(`${baseUrl}/v1/chat/completions`, {
|
|
502
|
+
method: "POST",
|
|
503
|
+
headers: { "Content-Type": "application/json" },
|
|
504
|
+
body: JSON.stringify({
|
|
505
|
+
model: "openclaw:main",
|
|
506
|
+
messages: [],
|
|
507
|
+
stream: false
|
|
508
|
+
}),
|
|
509
|
+
signal: AbortSignal.timeout(5e3)
|
|
612
510
|
});
|
|
613
|
-
|
|
511
|
+
if (response.status === 404) {
|
|
512
|
+
log.warn(
|
|
513
|
+
"OpenClaw endpoint not found. Enable chatCompletions in openclaw.json."
|
|
514
|
+
);
|
|
515
|
+
return false;
|
|
516
|
+
}
|
|
517
|
+
return true;
|
|
518
|
+
} catch {
|
|
519
|
+
return false;
|
|
520
|
+
}
|
|
614
521
|
}
|
|
615
522
|
createSession(id, config) {
|
|
616
523
|
const merged = { ...this.config, ...config };
|
|
@@ -1112,27 +1019,6 @@ var GeminiAdapter = class extends AgentAdapter {
|
|
|
1112
1019
|
}
|
|
1113
1020
|
};
|
|
1114
1021
|
|
|
1115
|
-
// src/utils/openclaw-config.ts
|
|
1116
|
-
import { readFileSync as readFileSync2 } from "fs";
|
|
1117
|
-
import { join as join4 } from "path";
|
|
1118
|
-
import { homedir as homedir2 } from "os";
|
|
1119
|
-
var OPENCLAW_CONFIG_PATH = join4(homedir2(), ".openclaw", "openclaw.json");
|
|
1120
|
-
function readOpenClawToken(configPath) {
|
|
1121
|
-
const path = configPath || OPENCLAW_CONFIG_PATH;
|
|
1122
|
-
try {
|
|
1123
|
-
const raw = readFileSync2(path, "utf-8");
|
|
1124
|
-
const config = JSON.parse(raw);
|
|
1125
|
-
const token = config?.gateway?.auth?.token;
|
|
1126
|
-
if (typeof token === "string" && token.length > 0) {
|
|
1127
|
-
return token;
|
|
1128
|
-
}
|
|
1129
|
-
log.warn("OpenClaw config found but gateway.auth.token is missing or empty");
|
|
1130
|
-
return null;
|
|
1131
|
-
} catch {
|
|
1132
|
-
return null;
|
|
1133
|
-
}
|
|
1134
|
-
}
|
|
1135
|
-
|
|
1136
1022
|
// src/commands/connect.ts
|
|
1137
1023
|
var DEFAULT_BRIDGE_URL = "wss://bridge.agents.hot/ws";
|
|
1138
1024
|
function createAdapter(type, config) {
|
|
@@ -1219,6 +1105,14 @@ function registerConnectCommand(program2) {
|
|
|
1219
1105
|
log.warn("Sandbox not available on this platform, continuing without sandbox");
|
|
1220
1106
|
}
|
|
1221
1107
|
}
|
|
1108
|
+
if (agentType === "openclaw") {
|
|
1109
|
+
const { isChatCompletionsEnabled } = await import("./openclaw-config-OFFNWVDK.js");
|
|
1110
|
+
if (!isChatCompletionsEnabled()) {
|
|
1111
|
+
log.warn(
|
|
1112
|
+
'OpenClaw chatCompletions endpoint may not be enabled.\n Add to ~/.openclaw/openclaw.json:\n { "gateway": { "http": { "endpoints": { "chatCompletions": { "enabled": true } } } } }\n Continuing anyway (gateway may be on a remote host)...'
|
|
1113
|
+
);
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1222
1116
|
const adapterConfig = {
|
|
1223
1117
|
project: opts.project,
|
|
1224
1118
|
gatewayUrl: opts.gatewayUrl || config.gatewayUrl,
|