open-agents-ai 0.103.36 → 0.103.38
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/README.md +89 -4
- package/dist/index.js +116 -32
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -72,7 +72,8 @@ The agent uses tools autonomously in a loop — reading errors, fixing code, and
|
|
|
72
72
|
- **Task templates** — specialized system prompts and tool recommendations for code, document, analysis, plan tasks
|
|
73
73
|
- **Inference capability scoring** — canirun.ai-style hardware assessment at first launch: memory/compute/speed scores, per-model compatibility matrix, recommended model selection
|
|
74
74
|
- **Auto-install everything** — first-run wizard auto-installs Ollama, curl, Python3, python3-venv with platform-aware package managers (apt, dnf, yum, pacman, apk, zypper, brew)
|
|
75
|
-
- **P2P inference network** — `/
|
|
75
|
+
- **P2P inference network** — `/expose` local models or forward any `/endpoint` (Chutes, Groq, OpenRouter, etc.) through the libp2p P2P mesh. Passthrough mode (`/expose passthrough`) relays upstream API requests; `--loadbalance` distributes rate-limited token budgets across peers. `/expose config` provides an arrow-key menu for all settings. Gateway stats show budget remaining from `x-ratelimit-*` headers. Background daemon persists across OA restarts
|
|
76
|
+
- **P2P mesh networking** — `/p2p` with secret-safe variable placeholders (`{{OA_VAR_*}}`), trust tiers (LOCAL/TEE/VERIFIED/PUBLIC), WebSocket peer mesh, and inference routing with automatic secret redaction/injection
|
|
76
77
|
- **Secret vault** — `/secrets` manages API keys and credentials with AES-256-GCM encrypted persistence; secrets are automatically redacted before sending to untrusted inference peers and re-injected on response
|
|
77
78
|
- **Auto-expanding context** — detects RAM/VRAM and creates an optimized model variant on first run
|
|
78
79
|
- **Mid-task steering** — type while the agent works to add context without interrupting
|
|
@@ -277,7 +278,7 @@ On startup and `/model` switch, Open Agents detects your RAM/VRAM and creates an
|
|
|
277
278
|
| `aiwg_workflow` | Execute AIWG commands and workflows |
|
|
278
279
|
| **Nexus P2P & x402 Payments** | |
|
|
279
280
|
| `nexus` | Decentralized agent networking — connect, rooms, DMs, peer discovery, invoke capabilities, metering, trust/blocking, IPFS storage |
|
|
280
|
-
| `nexus:expose` | Expose local
|
|
281
|
+
| `nexus:expose` | Expose local models or forward upstream endpoints as metered inference capabilities with pricing, passthrough, and load balancing |
|
|
281
282
|
| `nexus:wallet_create` | Generate secp256k1/EVM wallet (Base mainnet USDC) with AES-256-GCM encryption + x402-wallet.key |
|
|
282
283
|
| `nexus:spend` | Sign EIP-3009 USDC TransferWithAuthorization — budget-checked, gasless for payer |
|
|
283
284
|
| `nexus:remote_infer` | Route inference to a remote peer's model — auto-discovers peers, budget-checks, invokes, returns result |
|
|
@@ -956,8 +957,12 @@ The TUI features an animated multilingual phrase carousel, live metrics bar with
|
|
|
956
957
|
| `/expose ollama` | Expose local inference via libp2p (default) |
|
|
957
958
|
| `/expose ollama --tunnel` | Expose via cloudflared tunnel |
|
|
958
959
|
| `/expose ollama --full` | Allow full Ollama API access (pull/delete) |
|
|
959
|
-
| `/expose
|
|
960
|
-
| `/expose
|
|
960
|
+
| `/expose passthrough` | Forward configured `/endpoint` through libp2p P2P |
|
|
961
|
+
| `/expose forward --loadbalance` | Passthrough with distributed rate-limit budget |
|
|
962
|
+
| `/expose config` | Interactive expose configuration menu (arrow-key nav) |
|
|
963
|
+
| `/expose stop` | Stop all expose gateways |
|
|
964
|
+
| `/expose stop --libp2p` | Stop libp2p gateway only |
|
|
965
|
+
| `/expose status` | Show expose usage stats + budget |
|
|
961
966
|
| **Metrics & Updates** | |
|
|
962
967
|
| `/cost` | Show token cost breakdown for the current session |
|
|
963
968
|
| `/score` | Show inference capability scorecard (memory, compute, speed, model compatibility) |
|
|
@@ -1526,6 +1531,86 @@ Expose your local Ollama models to the decentralized nexus network, or consume a
|
|
|
1526
1531
|
|
|
1527
1532
|
Transport: DHT + mDNS + NATS relay + circuit relay. Auth key is auto-generated and required for all requests. System metrics (CPU/GPU/memory) are available to consumers via the `system_metrics` capability. Without `--full`, destructive Ollama API endpoints (`/api/pull`, `/api/delete`, `/api/create`) are blocked.
|
|
1528
1533
|
|
|
1534
|
+
#### Passthrough & Forward Mode
|
|
1535
|
+
|
|
1536
|
+
Forward any configured `/endpoint` (Chutes, Groq, OpenRouter, Together, vLLM, etc.) through the libp2p P2P network. Your node becomes a relay — peers connect to you via libp2p and you forward their requests to your upstream API:
|
|
1537
|
+
|
|
1538
|
+
```bash
|
|
1539
|
+
# Set your upstream endpoint first
|
|
1540
|
+
/endpoint https://llm.chutes.ai --auth cpk_your_key_here
|
|
1541
|
+
|
|
1542
|
+
# Expose it through P2P — peers discover and invoke via libp2p
|
|
1543
|
+
/expose passthrough
|
|
1544
|
+
# or equivalently:
|
|
1545
|
+
/expose forward
|
|
1546
|
+
|
|
1547
|
+
# With load balancing: distributes daily token budget across peers
|
|
1548
|
+
/expose passthrough --loadbalance
|
|
1549
|
+
```
|
|
1550
|
+
|
|
1551
|
+
**How it works:**
|
|
1552
|
+
- Your node registers inference capabilities on the P2P mesh using your upstream endpoint's models
|
|
1553
|
+
- Remote peers discover and invoke these capabilities via libp2p streams (DHT/mDNS/NATS)
|
|
1554
|
+
- Requests are forwarded to your upstream API, responses streamed back to the peer
|
|
1555
|
+
- The libp2p daemon persists in the background — it survives OA restarts and remains discoverable even when the TUI is closed
|
|
1556
|
+
- When you reopen OA, it reconnects to the existing daemon and resumes stats tracking
|
|
1557
|
+
|
|
1558
|
+
**Rate limit distribution (`--loadbalance`):**
|
|
1559
|
+
- Captures `x-ratelimit-remaining-tokens` and `x-ratelimit-limit-tokens` headers from upstream API responses
|
|
1560
|
+
- Displays remaining token budget in the gateway stats under "Budget"
|
|
1561
|
+
- Distributes the total daily token budget across connected peers proportionally
|
|
1562
|
+
- Prevents any single peer from exhausting the shared budget
|
|
1563
|
+
|
|
1564
|
+
#### Budget & Rate Limit Monitoring
|
|
1565
|
+
|
|
1566
|
+
When exposing an upstream endpoint that returns rate-limit headers (most cloud providers do), the gateway stats automatically track your remaining budget:
|
|
1567
|
+
|
|
1568
|
+
```
|
|
1569
|
+
Expose Gateway Stats (libp2p passthrough)
|
|
1570
|
+
Status active
|
|
1571
|
+
Transport libp2p (passthrough)
|
|
1572
|
+
Peer ID 12D3KooWSzC75QX...
|
|
1573
|
+
Uptime 2h 15m
|
|
1574
|
+
Total requests 847
|
|
1575
|
+
Tokens in 125.4K
|
|
1576
|
+
Tokens out 892.1K
|
|
1577
|
+
Budget 1.2M/10M (12% left)
|
|
1578
|
+
|
|
1579
|
+
Models
|
|
1580
|
+
qwen3.5-4b 412 reqs in:52.3K out:401.2K
|
|
1581
|
+
qwen3.5-9b 435 reqs in:73.1K out:490.9K
|
|
1582
|
+
|
|
1583
|
+
Active Peers (3)
|
|
1584
|
+
12D3KooWSwaCi1Jg...
|
|
1585
|
+
Session: 1h 45m Last seen: now Requests: 523
|
|
1586
|
+
Tokens: in:82.1K out:612.4K
|
|
1587
|
+
· qwen3.5-4b 312req 401.2Ktok
|
|
1588
|
+
· qwen3.5-9b 211req 293.3Ktok
|
|
1589
|
+
12D3KooWKnCgxx7D...
|
|
1590
|
+
Session: 45m Last seen: 2m ago Requests: 324
|
|
1591
|
+
Tokens: in:43.3K out:279.7K
|
|
1592
|
+
· qwen3.5-9b 224req 197.6Ktok
|
|
1593
|
+
```
|
|
1594
|
+
|
|
1595
|
+
Internal capabilities (`system_metrics`, `__list_capabilities`) are hidden from all displays — both the full stats view and the compact status bar one-liner.
|
|
1596
|
+
|
|
1597
|
+
#### `/expose config` — Interactive Configuration
|
|
1598
|
+
|
|
1599
|
+
Arrow-key navigable menu for all expose settings:
|
|
1600
|
+
|
|
1601
|
+
```bash
|
|
1602
|
+
/expose config
|
|
1603
|
+
```
|
|
1604
|
+
|
|
1605
|
+
Shows options to:
|
|
1606
|
+
- View current stats
|
|
1607
|
+
- Stop all gateways
|
|
1608
|
+
- Start Ollama (libp2p or tunnel)
|
|
1609
|
+
- Start passthrough (with or without load balancing)
|
|
1610
|
+
- Start vLLM
|
|
1611
|
+
|
|
1612
|
+
Uses the same arrow-key navigation pattern as `/model` and `/endpoint` selection.
|
|
1613
|
+
|
|
1529
1614
|
### Endpoint Cascade Failover
|
|
1530
1615
|
|
|
1531
1616
|
When you've used multiple endpoints, the agent automatically builds a failover cascade. If the primary endpoint fails with transient errors (502, connection refused, timeout), it transparently switches to the next endpoint that has the same model — then periodically probes the primary to return when it recovers:
|
package/dist/index.js
CHANGED
|
@@ -12607,30 +12607,74 @@ async function handleCmd(cmd) {
|
|
|
12607
12607
|
dlog('expose: auth key configured (' + exposeAuthKey.length + ' chars)');
|
|
12608
12608
|
}
|
|
12609
12609
|
|
|
12610
|
-
//
|
|
12610
|
+
// Passthrough mode: forward from a remote /endpoint (Chutes, Groq, etc.)
|
|
12611
|
+
var isPassthrough = args.passthrough === 'true';
|
|
12612
|
+
var endpointAuth = args.endpoint_auth || '';
|
|
12613
|
+
if (isPassthrough) {
|
|
12614
|
+
dlog('expose: PASSTHROUGH mode \u2014 forwarding from upstream endpoint');
|
|
12615
|
+
}
|
|
12616
|
+
|
|
12617
|
+
// Query models from the backend
|
|
12611
12618
|
const ollamaUrl = args.ollama_url || process.env.OLLAMA_URL || 'http://localhost:11434';
|
|
12612
12619
|
let models = [];
|
|
12613
|
-
|
|
12614
|
-
|
|
12615
|
-
|
|
12616
|
-
|
|
12617
|
-
|
|
12618
|
-
|
|
12619
|
-
|
|
12620
|
-
|
|
12621
|
-
|
|
12622
|
-
|
|
12623
|
-
|
|
12620
|
+
|
|
12621
|
+
if (isPassthrough) {
|
|
12622
|
+
// Passthrough: query /v1/models from the upstream endpoint (OpenAI-compatible)
|
|
12623
|
+
try {
|
|
12624
|
+
var modelsHeaders = { 'Content-Type': 'application/json' };
|
|
12625
|
+
if (endpointAuth) modelsHeaders['Authorization'] = 'Bearer ' + endpointAuth;
|
|
12626
|
+
var modelsUrl = ollamaUrl.replace(/\\/+$/, '') + '/v1/models';
|
|
12627
|
+
dlog('expose: passthrough querying models from ' + modelsUrl);
|
|
12628
|
+
const modelsResp = await fetch(modelsUrl, { headers: modelsHeaders });
|
|
12629
|
+
if (modelsResp.ok) {
|
|
12630
|
+
const modelsData = await modelsResp.json();
|
|
12631
|
+
var modelList = modelsData.data || modelsData.models || [];
|
|
12632
|
+
models = modelList.map(function(m) {
|
|
12633
|
+
return {
|
|
12634
|
+
name: m.id || m.name || 'unknown',
|
|
12635
|
+
size: 0,
|
|
12636
|
+
parameterSize: '',
|
|
12637
|
+
family: m.owned_by || '',
|
|
12638
|
+
quantization: '',
|
|
12639
|
+
};
|
|
12640
|
+
});
|
|
12641
|
+
} else {
|
|
12642
|
+
var errText = '';
|
|
12643
|
+
try { errText = await modelsResp.text(); } catch {}
|
|
12644
|
+
writeResp(id, { ok: false, output: 'Upstream /v1/models returned ' + modelsResp.status + ': ' + errText.slice(0, 200) });
|
|
12645
|
+
return;
|
|
12646
|
+
}
|
|
12647
|
+
} catch (e) {
|
|
12648
|
+
writeResp(id, { ok: false, output: 'Cannot reach upstream endpoint at ' + ollamaUrl + ': ' + e.message });
|
|
12649
|
+
return;
|
|
12650
|
+
}
|
|
12651
|
+
} else {
|
|
12652
|
+
// Local Ollama: query /api/tags
|
|
12653
|
+
try {
|
|
12654
|
+
const tagsResp = await fetch(ollamaUrl + '/api/tags');
|
|
12655
|
+
if (tagsResp.ok) {
|
|
12656
|
+
const tagsData = await tagsResp.json();
|
|
12657
|
+
models = (tagsData.models || []).map(function(m) {
|
|
12658
|
+
return {
|
|
12659
|
+
name: m.name,
|
|
12660
|
+
size: m.size || 0,
|
|
12661
|
+
parameterSize: m.details ? m.details.parameter_size || '' : '',
|
|
12662
|
+
family: m.details ? m.details.family || '' : '',
|
|
12663
|
+
quantization: m.details ? m.details.quantization_level || '' : '',
|
|
12664
|
+
};
|
|
12665
|
+
});
|
|
12666
|
+
}
|
|
12667
|
+
} catch (e) {
|
|
12668
|
+
writeResp(id, { ok: false, output: 'Cannot reach Ollama at ' + ollamaUrl + ': ' + e.message });
|
|
12669
|
+
return;
|
|
12624
12670
|
}
|
|
12625
|
-
} catch (e) {
|
|
12626
|
-
writeResp(id, { ok: false, output: 'Cannot reach Ollama at ' + ollamaUrl + ': ' + e.message });
|
|
12627
|
-
return;
|
|
12628
12671
|
}
|
|
12629
12672
|
|
|
12630
12673
|
if (models.length === 0) {
|
|
12631
|
-
writeResp(id, { ok: false, output: 'No models found on Ollama. Pull a model first.' });
|
|
12674
|
+
writeResp(id, { ok: false, output: isPassthrough ? 'No models found on upstream endpoint.' : 'No models found on Ollama. Pull a model first.' });
|
|
12632
12675
|
return;
|
|
12633
12676
|
}
|
|
12677
|
+
dlog('expose: found ' + models.length + ' models' + (isPassthrough ? ' (passthrough)' : ''));
|
|
12634
12678
|
|
|
12635
12679
|
// Fetch market rates from OpenRouter (free, no auth)
|
|
12636
12680
|
let marketRates = {};
|
|
@@ -12782,10 +12826,12 @@ async function handleCmd(cmd) {
|
|
|
12782
12826
|
if (parsedReq.temperature !== undefined) chatBody.temperature = parsedReq.temperature;
|
|
12783
12827
|
if (parsedReq.max_tokens) chatBody.max_tokens = parsedReq.max_tokens;
|
|
12784
12828
|
|
|
12785
|
-
|
|
12829
|
+
var chatHeaders = { 'Content-Type': 'application/json' };
|
|
12830
|
+
if (isPassthrough && endpointAuth) chatHeaders['Authorization'] = 'Bearer ' + endpointAuth;
|
|
12831
|
+
dlog('expose: calling /v1/chat/completions with ' + chatBody.messages.length + ' messages, tools=' + (chatBody.tools ? chatBody.tools.length : 0) + (isPassthrough ? ' (passthrough)' : ''));
|
|
12786
12832
|
genResp = await fetch(ollamaUrl + '/v1/chat/completions', {
|
|
12787
12833
|
method: 'POST',
|
|
12788
|
-
headers:
|
|
12834
|
+
headers: chatHeaders,
|
|
12789
12835
|
body: JSON.stringify(chatBody),
|
|
12790
12836
|
});
|
|
12791
12837
|
genData = await genResp.json();
|
|
@@ -12816,8 +12862,36 @@ async function handleCmd(cmd) {
|
|
|
12816
12862
|
usage: { input_tokens: inputTokens, output_tokens: outputTokens },
|
|
12817
12863
|
pricing: entry.pricing,
|
|
12818
12864
|
};
|
|
12865
|
+
} else if (isPassthrough) {
|
|
12866
|
+
// Passthrough flat prompt \u2014 convert to /v1/chat/completions (upstream has no /api/generate)
|
|
12867
|
+
var flatPrompt = parsedReq && parsedReq.prompt ? parsedReq.prompt : (prompt || 'Hello');
|
|
12868
|
+
var ptHeaders = { 'Content-Type': 'application/json' };
|
|
12869
|
+
if (endpointAuth) ptHeaders['Authorization'] = 'Bearer ' + endpointAuth;
|
|
12870
|
+
genResp = await fetch(ollamaUrl + '/v1/chat/completions', {
|
|
12871
|
+
method: 'POST',
|
|
12872
|
+
headers: ptHeaders,
|
|
12873
|
+
body: JSON.stringify({
|
|
12874
|
+
model: model.name,
|
|
12875
|
+
messages: [{ role: 'user', content: flatPrompt }],
|
|
12876
|
+
stream: false,
|
|
12877
|
+
}),
|
|
12878
|
+
});
|
|
12879
|
+
genData = await genResp.json();
|
|
12880
|
+
var ptChoices = genData.choices || [];
|
|
12881
|
+
var ptMsg = (ptChoices[0] || {}).message || {};
|
|
12882
|
+
output = (ptMsg.content || '').replace(/<think>[\\s\\S]*?<\\/think>/g, '').trim();
|
|
12883
|
+
inputTokens = (genData.usage || {}).prompt_tokens || 0;
|
|
12884
|
+
outputTokens = (genData.usage || {}).completion_tokens || 0;
|
|
12885
|
+
|
|
12886
|
+
responsePayload = {
|
|
12887
|
+
model: model.name,
|
|
12888
|
+
response: output,
|
|
12889
|
+
choices: ptChoices,
|
|
12890
|
+
usage: { input_tokens: inputTokens, output_tokens: outputTokens },
|
|
12891
|
+
pricing: entry.pricing,
|
|
12892
|
+
};
|
|
12819
12893
|
} else {
|
|
12820
|
-
// Flat prompt \u2014 use /api/generate (
|
|
12894
|
+
// Flat prompt \u2014 use /api/generate (local Ollama)
|
|
12821
12895
|
var flatPrompt = parsedReq && parsedReq.prompt ? parsedReq.prompt : (prompt || 'Hello');
|
|
12822
12896
|
genResp = await fetch(ollamaUrl + '/api/generate', {
|
|
12823
12897
|
method: 'POST',
|
|
@@ -26371,10 +26445,15 @@ function renderSlashHelp() {
|
|
|
26371
26445
|
["/nexus", "Show nexus P2P network status (or connect/disconnect/rooms)"],
|
|
26372
26446
|
["/nexus connect", "Connect to the agent mesh network"],
|
|
26373
26447
|
["/nexus wallet", "Show wallet address and x402 payment status"],
|
|
26374
|
-
["/expose <backend>", "
|
|
26375
|
-
["/expose <backend> --
|
|
26376
|
-
["/expose
|
|
26377
|
-
["/expose
|
|
26448
|
+
["/expose <backend>", "Expose local inference via libp2p (default)"],
|
|
26449
|
+
["/expose <backend> --tunnel", "Expose via cloudflared tunnel"],
|
|
26450
|
+
["/expose passthrough", "Forward configured /endpoint through libp2p P2P"],
|
|
26451
|
+
["/expose forward --loadbalance", "Passthrough with distributed rate-limit budget"],
|
|
26452
|
+
["/expose config", "Interactive expose configuration menu"],
|
|
26453
|
+
["/expose status", "Show gateway stats (requests, models, budget)"],
|
|
26454
|
+
["/expose stop", "Stop all expose gateways"],
|
|
26455
|
+
["/expose stop --tunnel", "Stop tunnel gateway only"],
|
|
26456
|
+
["/expose stop --libp2p", "Stop libp2p gateway only"],
|
|
26378
26457
|
["/p2p start", "Join the P2P agent mesh network"],
|
|
26379
26458
|
["/p2p status", "Show mesh peers and rooms"],
|
|
26380
26459
|
["/p2p stop", "Leave the mesh network"],
|
|
@@ -28353,6 +28432,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
28353
28432
|
_margin;
|
|
28354
28433
|
_passthrough = false;
|
|
28355
28434
|
_loadbalance = false;
|
|
28435
|
+
_endpointAuth;
|
|
28356
28436
|
_pollTimer = null;
|
|
28357
28437
|
_stats = {
|
|
28358
28438
|
status: "standby",
|
|
@@ -28397,6 +28477,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
28397
28477
|
this._margin = options.margin ?? 0.5;
|
|
28398
28478
|
this._passthrough = options.passthrough ?? false;
|
|
28399
28479
|
this._loadbalance = options.loadbalance ?? false;
|
|
28480
|
+
this._endpointAuth = options.endpointAuth;
|
|
28400
28481
|
this._onInfo = options.onInfo;
|
|
28401
28482
|
this._onError = options.onError;
|
|
28402
28483
|
if (options.authKey === void 0 || options.authKey === "") {
|
|
@@ -28416,21 +28497,23 @@ ${this.formatConnectionInfo()}`);
|
|
|
28416
28497
|
throw new Error(`Nexus daemon connect failed: ${connectResult.error}`);
|
|
28417
28498
|
}
|
|
28418
28499
|
await new Promise((r) => setTimeout(r, 500));
|
|
28419
|
-
this._onInfo?.("Registering inference capabilities...");
|
|
28420
|
-
|
|
28500
|
+
this._onInfo?.(this._passthrough ? `Registering passthrough capabilities (\u2192 ${this._targetUrl})...` : "Registering inference capabilities...");
|
|
28501
|
+
const exposeArgs = {
|
|
28421
28502
|
action: "expose",
|
|
28422
28503
|
ollama_url: this._targetUrl,
|
|
28423
28504
|
margin: String(this._margin),
|
|
28424
28505
|
auth_key: this._authKey
|
|
28425
|
-
}
|
|
28506
|
+
};
|
|
28507
|
+
if (this._passthrough) {
|
|
28508
|
+
exposeArgs.passthrough = "true";
|
|
28509
|
+
if (this._endpointAuth) {
|
|
28510
|
+
exposeArgs.endpoint_auth = this._endpointAuth;
|
|
28511
|
+
}
|
|
28512
|
+
}
|
|
28513
|
+
let exposeResult = await this._nexusTool.execute(exposeArgs);
|
|
28426
28514
|
if (!exposeResult.success && exposeResult.error?.includes("not running")) {
|
|
28427
28515
|
await new Promise((r) => setTimeout(r, 1500));
|
|
28428
|
-
exposeResult = await this._nexusTool.execute(
|
|
28429
|
-
action: "expose",
|
|
28430
|
-
ollama_url: this._targetUrl,
|
|
28431
|
-
margin: String(this._margin),
|
|
28432
|
-
auth_key: this._authKey
|
|
28433
|
-
});
|
|
28516
|
+
exposeResult = await this._nexusTool.execute(exposeArgs);
|
|
28434
28517
|
}
|
|
28435
28518
|
if (!exposeResult.success) {
|
|
28436
28519
|
throw new Error(`Expose failed: ${exposeResult.error}`);
|
|
@@ -46912,6 +46995,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
46912
46995
|
stateDir: join50(repoRoot, ".oa"),
|
|
46913
46996
|
passthrough: passthrough ?? false,
|
|
46914
46997
|
loadbalance: loadbalance ?? false,
|
|
46998
|
+
endpointAuth: passthrough ? config.apiKey : void 0,
|
|
46915
46999
|
onInfo: (msg) => {
|
|
46916
47000
|
exposeSpinnerMsg = msg;
|
|
46917
47001
|
},
|
package/package.json
CHANGED