@jini-ai/agent-runtime 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/README.md +2 -2
- package/dist/agent-protocol/acp/session.d.ts +206 -1
- package/dist/agent-protocol/acp/session.d.ts.map +1 -1
- package/dist/agent-protocol/acp/session.js +505 -350
- package/dist/agent-protocol/acp/session.js.map +1 -1
- package/dist/agent-protocol/core/json-line-stream.d.ts +53 -0
- package/dist/agent-protocol/core/json-line-stream.d.ts.map +1 -1
- package/dist/agent-protocol/core/json-line-stream.js +307 -255
- package/dist/agent-protocol/core/json-line-stream.js.map +1 -1
- package/dist/agent-protocol/pi-rpc/events.d.ts +22 -1
- package/dist/agent-protocol/pi-rpc/events.d.ts.map +1 -1
- package/dist/agent-protocol/pi-rpc/events.js +189 -153
- package/dist/agent-protocol/pi-rpc/events.js.map +1 -1
- package/dist/agent-protocol/pi-rpc/session.d.ts +39 -0
- package/dist/agent-protocol/pi-rpc/session.d.ts.map +1 -1
- package/dist/agent-protocol/pi-rpc/session.js +143 -107
- package/dist/agent-protocol/pi-rpc/session.js.map +1 -1
- package/dist/claude-stream.d.ts +64 -1
- package/dist/claude-stream.d.ts.map +1 -1
- package/dist/claude-stream.js +568 -441
- package/dist/claude-stream.js.map +1 -1
- package/dist/defs/aider.d.ts.map +1 -1
- package/dist/defs/aider.js +13 -1
- package/dist/defs/aider.js.map +1 -1
- package/dist/defs/amp.d.ts.map +1 -1
- package/dist/defs/amp.js +16 -1
- package/dist/defs/amp.js.map +1 -1
- package/dist/defs/amr.d.ts +2 -1
- package/dist/defs/amr.d.ts.map +1 -1
- package/dist/defs/amr.js +12 -1
- package/dist/defs/amr.js.map +1 -1
- package/dist/defs/antigravity.d.ts +41 -2
- package/dist/defs/antigravity.d.ts.map +1 -1
- package/dist/defs/antigravity.js +201 -22
- package/dist/defs/antigravity.js.map +1 -1
- package/dist/defs/claude.d.ts +2 -0
- package/dist/defs/claude.d.ts.map +1 -1
- package/dist/defs/claude.js +58 -3
- package/dist/defs/claude.js.map +1 -1
- package/dist/defs/codebuddy.d.ts.map +1 -1
- package/dist/defs/codebuddy.js +9 -1
- package/dist/defs/codebuddy.js.map +1 -1
- package/dist/defs/codex.d.ts +1 -0
- package/dist/defs/codex.d.ts.map +1 -1
- package/dist/defs/codex.js +34 -0
- package/dist/defs/codex.js.map +1 -1
- package/dist/defs/copilot.d.ts.map +1 -1
- package/dist/defs/copilot.js +15 -1
- package/dist/defs/copilot.js.map +1 -1
- package/dist/defs/cursor-agent.d.ts.map +1 -1
- package/dist/defs/cursor-agent.js +24 -2
- package/dist/defs/cursor-agent.js.map +1 -1
- package/dist/defs/deepseek.d.ts.map +1 -1
- package/dist/defs/deepseek.js +12 -0
- package/dist/defs/deepseek.js.map +1 -1
- package/dist/defs/devin.d.ts +2 -1
- package/dist/defs/devin.d.ts.map +1 -1
- package/dist/defs/devin.js +12 -7
- package/dist/defs/devin.js.map +1 -1
- package/dist/defs/grok-build.d.ts.map +1 -1
- package/dist/defs/grok-build.js +10 -0
- package/dist/defs/grok-build.js.map +1 -1
- package/dist/defs/hermes.d.ts +1 -0
- package/dist/defs/hermes.d.ts.map +1 -1
- package/dist/defs/hermes.js +3 -0
- package/dist/defs/hermes.js.map +1 -1
- package/dist/defs/kilo.d.ts +1 -0
- package/dist/defs/kilo.d.ts.map +1 -1
- package/dist/defs/kilo.js +3 -0
- package/dist/defs/kilo.js.map +1 -1
- package/dist/defs/kimi.d.ts +1 -0
- package/dist/defs/kimi.d.ts.map +1 -1
- package/dist/defs/kimi.js +3 -0
- package/dist/defs/kimi.js.map +1 -1
- package/dist/defs/kiro.d.ts +1 -0
- package/dist/defs/kiro.d.ts.map +1 -1
- package/dist/defs/kiro.js +3 -0
- package/dist/defs/kiro.js.map +1 -1
- package/dist/defs/pi.d.ts +1 -1
- package/dist/defs/pi.d.ts.map +1 -1
- package/dist/defs/pi.js +6 -1
- package/dist/defs/pi.js.map +1 -1
- package/dist/defs/qoder.d.ts +1 -0
- package/dist/defs/qoder.d.ts.map +1 -1
- package/dist/defs/qoder.js +15 -0
- package/dist/defs/qoder.js.map +1 -1
- package/dist/defs/qwen.d.ts.map +1 -1
- package/dist/defs/qwen.js +9 -0
- package/dist/defs/qwen.js.map +1 -1
- package/dist/defs/reasonix.d.ts +1 -0
- package/dist/defs/reasonix.d.ts.map +1 -1
- package/dist/defs/reasonix.js +3 -0
- package/dist/defs/reasonix.js.map +1 -1
- package/dist/defs/shared.d.ts +31 -1
- package/dist/defs/shared.d.ts.map +1 -1
- package/dist/defs/shared.js +35 -0
- package/dist/defs/shared.js.map +1 -1
- package/dist/defs/trae-cli.d.ts +1 -0
- package/dist/defs/trae-cli.d.ts.map +1 -1
- package/dist/defs/trae-cli.js +3 -0
- package/dist/defs/trae-cli.js.map +1 -1
- package/dist/defs/vibe.d.ts +1 -0
- package/dist/defs/vibe.d.ts.map +1 -1
- package/dist/defs/vibe.js +3 -0
- package/dist/defs/vibe.js.map +1 -1
- package/dist/detection.d.ts +1 -1
- package/dist/detection.d.ts.map +1 -1
- package/dist/detection.js +7 -2
- package/dist/detection.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/log-file.d.ts +23 -0
- package/dist/log-file.d.ts.map +1 -0
- package/dist/log-file.js +56 -0
- package/dist/log-file.js.map +1 -0
- package/dist/model-registry.d.ts +7 -45
- package/dist/model-registry.d.ts.map +1 -1
- package/dist/model-registry.js.map +1 -1
- package/dist/providers/anthropic-messages.d.ts +198 -6
- package/dist/providers/anthropic-messages.d.ts.map +1 -1
- package/dist/providers/anthropic-messages.js +317 -140
- package/dist/providers/anthropic-messages.js.map +1 -1
- package/dist/providers/azure-chat.d.ts +113 -3
- package/dist/providers/azure-chat.d.ts.map +1 -1
- package/dist/providers/azure-chat.js +114 -21
- package/dist/providers/azure-chat.js.map +1 -1
- package/dist/providers/connection-guard.d.ts +121 -1
- package/dist/providers/connection-guard.d.ts.map +1 -1
- package/dist/providers/connection-guard.js +205 -3
- package/dist/providers/connection-guard.js.map +1 -1
- package/dist/providers/connection-test.d.ts +62 -0
- package/dist/providers/connection-test.d.ts.map +1 -0
- package/dist/providers/connection-test.js +404 -0
- package/dist/providers/connection-test.js.map +1 -0
- package/dist/providers/elevenlabs.d.ts.map +1 -1
- package/dist/providers/elevenlabs.js +3 -2
- package/dist/providers/elevenlabs.js.map +1 -1
- package/dist/providers/google-messages.d.ts +208 -7
- package/dist/providers/google-messages.d.ts.map +1 -1
- package/dist/providers/google-messages.js +331 -105
- package/dist/providers/google-messages.js.map +1 -1
- package/dist/providers/index.d.ts +1 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +1 -0
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/model-catalog.d.ts.map +1 -1
- package/dist/providers/model-catalog.js +21 -0
- package/dist/providers/model-catalog.js.map +1 -1
- package/dist/providers/ollama-chat.d.ts +190 -1
- package/dist/providers/ollama-chat.d.ts.map +1 -1
- package/dist/providers/ollama-chat.js +319 -110
- package/dist/providers/ollama-chat.js.map +1 -1
- package/dist/providers/openai-chat.d.ts +222 -14
- package/dist/providers/openai-chat.d.ts.map +1 -1
- package/dist/providers/openai-chat.js +377 -128
- package/dist/providers/openai-chat.js.map +1 -1
- package/dist/providers/sse-decode.d.ts +2 -2
- package/dist/providers/sse-decode.js +2 -2
- package/dist/types.d.ts +169 -87
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -4
|
@@ -16,6 +16,24 @@
|
|
|
16
16
|
* or RFC1918/link-local/CGNAT/metadata-service addresses, and strip bearer
|
|
17
17
|
* tokens / API-key headers / `?key=` query values out of free-form text
|
|
18
18
|
* before it is logged or surfaced to a caller.
|
|
19
|
+
*
|
|
20
|
+
* Also exports `pinnedFetch` — a `node:https`/`node:http`-based POST that dials the exact address
|
|
21
|
+
* `validateBaseUrlResolved` already validated, instead of leaving the transport to re-resolve DNS
|
|
22
|
+
* independently when it connects. Added later than the four functions above, for the same
|
|
23
|
+
* dependency-free package; see `pinnedFetch`'s own doc for why `fetch()` itself cannot do this.
|
|
24
|
+
*
|
|
25
|
+
* ## Paired with `@jini-ai/ui`'s `utils/endpoint-policy.ts`
|
|
26
|
+
*
|
|
27
|
+
* That module carries a browser-safe copy of the SYNCHRONOUS half below —
|
|
28
|
+
* `isLoopbackApiHost`/`isBlockedExternalApiHostname`/`validateBaseUrl` — so the
|
|
29
|
+
* settings tabs can reject a bad endpoint as the operator types it. It is a
|
|
30
|
+
* copy rather than an import because `endpoint-policy.ts` itself has zero
|
|
31
|
+
* imports by design and this package is Node-only (`validateBaseUrlResolved`
|
|
32
|
+
* needs `node:dns`); see that file's header for the full reasoning.
|
|
33
|
+
*
|
|
34
|
+
* **If the block-list here changes, change it there too.** A divergence means
|
|
35
|
+
* the UI accepts an endpoint this guard then refuses — or, in the direction
|
|
36
|
+
* that actually matters, the UI accepts one this guard would have refused.
|
|
19
37
|
*/
|
|
20
38
|
function normalizeBracketedIpv6(hostname) {
|
|
21
39
|
const stripped = hostname.startsWith('[') && hostname.endsWith(']')
|
|
@@ -106,11 +124,32 @@ export function isBlockedExternalApiHostname(hostname) {
|
|
|
106
124
|
const mapped = ipv4MappedToDotted(host);
|
|
107
125
|
return Boolean(mapped && isBlockedIpv4(mapped));
|
|
108
126
|
}
|
|
109
|
-
/**
|
|
127
|
+
/**
|
|
128
|
+
* Synchronous base-URL check: scheme allow-list + literal-hostname block-list.
|
|
129
|
+
* Does not resolve DNS — see {@link validateBaseUrlResolved}.
|
|
130
|
+
*
|
|
131
|
+
* **Trims before parsing, and must keep doing so.** `@jini-ai/ui`'s
|
|
132
|
+
* `isAllowedEndpointUrl` is a deliberate browser-safe copy of this function and
|
|
133
|
+
* trims its input; this one did not. WHATWG URL parsing strips leading/trailing
|
|
134
|
+
* ASCII space itself, so the two agreed on `" https://x "` and diverged only on
|
|
135
|
+
* whitespace `String.prototype.trim` removes but the URL parser does not — NBSP,
|
|
136
|
+
* BOM, thin space and friends. A URL pasted from a rich-text source therefore
|
|
137
|
+
* passed the UI and was refused at connection time.
|
|
138
|
+
* `endpoint-policy.parity.test.ts` now holds the two in agreement mechanically.
|
|
139
|
+
*
|
|
140
|
+
* Trimming cannot weaken the block-list. Checked across every whitespace
|
|
141
|
+
* character `trim` strips, against blocked/loopback/public hosts in all three
|
|
142
|
+
* padding positions: an untrimmed parse either fails outright or yields a
|
|
143
|
+
* hostname IDENTICAL to the trimmed one. It never yields a DIFFERENT host, which
|
|
144
|
+
* is the only shape that would let the block-list inspect one string while the
|
|
145
|
+
* network used another.
|
|
146
|
+
*/
|
|
110
147
|
export function validateBaseUrl(baseUrl) {
|
|
111
148
|
let parsed;
|
|
112
149
|
try {
|
|
113
|
-
|
|
150
|
+
// Trim BEFORE stripping trailing slashes: in `"https://x/ "` the trailing
|
|
151
|
+
// character is the space, so the slash strip alone would never reach it.
|
|
152
|
+
parsed = new URL(String(baseUrl).trim().replace(/\/+$/, ''));
|
|
114
153
|
}
|
|
115
154
|
catch {
|
|
116
155
|
return { error: 'Invalid baseUrl' };
|
|
@@ -144,6 +183,25 @@ function looksLikeIpLiteral(hostname) {
|
|
|
144
183
|
* hostname that resolves to a loopback address (including `*.localhost` per
|
|
145
184
|
* RFC 6761 and IPv4-mapped IPv6 loopback) follows the same carve-out.
|
|
146
185
|
*
|
|
186
|
+
* ## The TOCTOU this closes, and how
|
|
187
|
+
*
|
|
188
|
+
* A validator that only checks and returns pass/fail has a gap: `fetch` (or any transport) then
|
|
189
|
+
* resolves the hostname AGAIN, independently, when it dials. Between those two resolutions the
|
|
190
|
+
* answer can change — a DNS rebinding attacker returns a public address to this check and a
|
|
191
|
+
* private one to the connection. No amount of re-checking closes that on its own; the request has
|
|
192
|
+
* to dial the exact address that was approved. So this function does the resolution exactly ONCE
|
|
193
|
+
* and hands the first validated address back as `pinnedAddress` — feed it to {@link pinnedFetch},
|
|
194
|
+
* which dials that address directly instead of letting the transport re-resolve. `pinnedAddress` is
|
|
195
|
+
* only set when a lookup actually happened (i.e. never for the loopback-literal / IP-literal hosts
|
|
196
|
+
* below, which need no pinning: an IP literal never re-resolves to anything else, and loopback
|
|
197
|
+
* literals are outside this threat model — see the carve-out above).
|
|
198
|
+
*
|
|
199
|
+
* That said, `baseUrl` here is operator-configured provider config, not attacker-supplied input —
|
|
200
|
+
* pinning is defence-in-depth rather than the primary trust boundary. Callers should additionally
|
|
201
|
+
* refuse redirects (`redirect: 'error'`), which closes the OTHER way a validated origin reaches an
|
|
202
|
+
* unvalidated address; `pinnedFetch` never follows one regardless (`node:https`/`node:http` don't,
|
|
203
|
+
* unlike `fetch`'s default), but callers still pass `redirect: 'error'` for self-documentation.
|
|
204
|
+
*
|
|
147
205
|
* DNS lookup failures are not treated as a security signal — the caller is
|
|
148
206
|
* going to surface a connection error from `fetch` anyway, and turning a
|
|
149
207
|
* transient resolver hiccup into a rejection would just confuse callers. The
|
|
@@ -176,7 +234,151 @@ export async function validateBaseUrlResolved(baseUrl, lookup) {
|
|
|
176
234
|
return { error: 'Internal IPs blocked', forbidden: true };
|
|
177
235
|
}
|
|
178
236
|
}
|
|
179
|
-
|
|
237
|
+
// Pin to the FIRST resolved address — the loop above already proved every address in this list
|
|
238
|
+
// cleared the block-list, so this is "the address the guard actually approved", singular, ready
|
|
239
|
+
// to hand to `pinnedFetch`. An empty `addresses` array (a `lookup` that resolves to nothing
|
|
240
|
+
// without throwing) leaves `pinnedAddress` unset; a real `dns.lookup` throws ENOTFOUND rather
|
|
241
|
+
// than resolving to `[]`, so this is not a realistic gap, just a graceful fallback to the
|
|
242
|
+
// pre-pinning pass-through behavior.
|
|
243
|
+
const pinnedAddress = addresses[0];
|
|
244
|
+
return pinnedAddress ? { ...sync, pinnedAddress } : sync;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Idle-socket safety net, applied to every `pinnedFetch` request regardless of `init.signal`.
|
|
248
|
+
* Plain `http(s).request` has NO default timeout at all — unlike `fetch`, which is backed by
|
|
249
|
+
* undici's `Agent` defaults (`headersTimeout`/`bodyTimeout`, both 300_000ms there). Without this,
|
|
250
|
+
* a truly silent/dead connection would hang forever where `fetch` previously would not have. This
|
|
251
|
+
* is a ceiling underneath a caller-supplied `AbortSignal`, not a replacement for one — whichever
|
|
252
|
+
* fires first wins; the number matches undici's default rather than inventing a new one.
|
|
253
|
+
*/
|
|
254
|
+
const PINNED_FETCH_IDLE_TIMEOUT_MS = 300_000;
|
|
255
|
+
/**
|
|
256
|
+
* `fetch()`-shaped POST that dials `pinnedAddress` directly instead of letting the transport
|
|
257
|
+
* re-resolve DNS when it connects — see {@link validateBaseUrlResolved}'s doc for the TOCTOU this
|
|
258
|
+
* closes and why `pinnedAddress` is the exact address that function already validated.
|
|
259
|
+
*
|
|
260
|
+
* Built on `node:https`/`node:http`, not `fetch`, because Node's global `fetch` is backed by an
|
|
261
|
+
* internal, non-importable copy of undici and exposes no `lookup`/dispatcher hook without adding
|
|
262
|
+
* `undici` (or an equivalent) as a runtime dependency — confirmed empirically against this
|
|
263
|
+
* package's pinned Node version (`require('node:undici')` throws `No such built-in module`, i.e.
|
|
264
|
+
* it is not a stable built-in here even though Node's own `fetch` uses it internally). This
|
|
265
|
+
* package carries no external runtime dependencies by design (module doc), so `node:https`/
|
|
266
|
+
* `node:http`'s own `lookup` option — which `net.connect` already accepts for exactly this purpose
|
|
267
|
+
* — is the only built-in path.
|
|
268
|
+
*
|
|
269
|
+
* `hostname`/`servername` passed to the transport stay the ORIGINAL host from `url`, not
|
|
270
|
+
* `pinnedAddress`; only the `lookup` override changes which address the socket actually dials.
|
|
271
|
+
* That is what keeps this a pin rather than a redirect to a different origin: the Host header and,
|
|
272
|
+
* for https, the TLS SNI + certificate hostname validation are unaffected, so a certificate for the
|
|
273
|
+
* real hostname still validates normally against a connection that happens to land on the address
|
|
274
|
+
* the guard already approved. Never follows a redirect — `http(s).request` doesn't, unlike
|
|
275
|
+
* `fetch`'s default — which is the other half of the rebinding surface `redirect: 'error'`
|
|
276
|
+
* documents at each call site.
|
|
277
|
+
*
|
|
278
|
+
* When `pinnedAddress` is `undefined` — the loopback-literal / IP-literal hosts
|
|
279
|
+
* `validateBaseUrlResolved` never runs a lookup for — this issues a normal, unpinned request
|
|
280
|
+
* (`lookup` option simply omitted). That is intentional, not a gap: an IP literal has nothing left
|
|
281
|
+
* to re-resolve, and loopback literals are the documented carve-out, outside this threat model.
|
|
282
|
+
*/
|
|
283
|
+
export async function pinnedFetch(url, init, pinnedAddress) {
|
|
284
|
+
const parsed = new URL(url);
|
|
285
|
+
const isHttps = parsed.protocol === 'https:';
|
|
286
|
+
const { request: httpsRequest } = await import('node:https');
|
|
287
|
+
const { request: httpRequest } = await import('node:http');
|
|
288
|
+
const transportRequest = isHttps ? httpsRequest : httpRequest;
|
|
289
|
+
const family = pinnedAddress?.family === 6 ? 6 : 4;
|
|
290
|
+
return new Promise((resolve, reject) => {
|
|
291
|
+
const req = transportRequest({
|
|
292
|
+
hostname: parsed.hostname,
|
|
293
|
+
...(parsed.port ? { port: Number(parsed.port) } : {}),
|
|
294
|
+
path: `${parsed.pathname}${parsed.search}`,
|
|
295
|
+
method: init.method,
|
|
296
|
+
// `identity` is explicit, not incidental. `fetch` transparently decompresses a response;
|
|
297
|
+
// `http(s).request` does NOT, so a compressed body would reach a caller that parses it as
|
|
298
|
+
// UTF-8 SSE and produce silent garbage — surfacing far from the cause as an empty stream
|
|
299
|
+
// or a JSON parse error. Node sends no `Accept-Encoding` of its own, so this only makes
|
|
300
|
+
// the existing behaviour explicit and survives a caller that sets its own headers.
|
|
301
|
+
// Paired with the `content-encoding` check below, which covers a server that compresses
|
|
302
|
+
// unbidden anyway.
|
|
303
|
+
headers: { 'accept-encoding': 'identity', ...init.headers },
|
|
304
|
+
// `servername` set explicitly to the ORIGINAL hostname (not `pinnedAddress`) is what SNI
|
|
305
|
+
// and certificate hostname validation actually run against — this is what makes it a pin
|
|
306
|
+
// rather than a redirect to a different origin. `rejectUnauthorized` is left at its
|
|
307
|
+
// `node:https` default (`true`, i.e. certificate validation stays ON); nothing in this
|
|
308
|
+
// function ever sets it, and it must stay that way.
|
|
309
|
+
...(isHttps ? { servername: parsed.hostname } : {}),
|
|
310
|
+
...(pinnedAddress
|
|
311
|
+
? {
|
|
312
|
+
// Happy Eyeballs (`autoSelectFamily`, on by default since Node 20) races several
|
|
313
|
+
// resolved addresses and expects `lookup` to support its array-returning calling
|
|
314
|
+
// convention — the opposite of what pinning wants (exactly one address, no fallback
|
|
315
|
+
// to any other). Disabling it keeps `net`'s classic single-address `lookup` contract,
|
|
316
|
+
// which is what the callback below implements.
|
|
317
|
+
autoSelectFamily: false,
|
|
318
|
+
lookup: (_hostname, _options, callback) => {
|
|
319
|
+
callback(null, pinnedAddress.address, family);
|
|
320
|
+
},
|
|
321
|
+
}
|
|
322
|
+
: {}),
|
|
323
|
+
}, (res) => {
|
|
324
|
+
const status = res.statusCode ?? 0;
|
|
325
|
+
// A server may compress despite `accept-encoding: identity`. Nothing downstream
|
|
326
|
+
// decompresses, so failing loudly here is strictly better than handing back bytes the
|
|
327
|
+
// caller will misparse: a hard error names the cause, silent garbage does not.
|
|
328
|
+
const encoding = res.headers['content-encoding'];
|
|
329
|
+
if (typeof encoding === 'string' && encoding.trim() !== '' && encoding.trim().toLowerCase() !== 'identity') {
|
|
330
|
+
res.resume(); // drain, so the socket is not left half-read
|
|
331
|
+
reject(new Error(`pinnedFetch: response used unsupported content-encoding "${encoding}". `
|
|
332
|
+
+ 'This transport does not decompress; the request asked for identity.'));
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
// `http(s).request` never auto-follows a redirect the way `fetch`'s default does, but
|
|
336
|
+
// that alone is a WEAKER posture than the `redirect: 'error'` callers ask for: real
|
|
337
|
+
// `fetch` THROWS on a 3xx, whereas simply not following one would resolve normally with
|
|
338
|
+
// `status: 302` and a likely-empty body — turning the guard's hard failure into a quiet
|
|
339
|
+
// `ok: false` a caller could half-handle as a generic upstream error. That undersells the
|
|
340
|
+
// reviewer's original finding: a guard-passing endpoint could 302 into blocked address
|
|
341
|
+
// space with auth headers still attached. So this rejects explicitly, matching `fetch`'s
|
|
342
|
+
// throw rather than merely approximating it by omission. Only the five redirect codes
|
|
343
|
+
// `fetch` itself treats as redirects (a `Location` header is what actually enables the
|
|
344
|
+
// rebinding hop) — NOT every 3xx: `304 Not Modified` carries no `Location` and no provider
|
|
345
|
+
// in this package sends conditional-request headers that could ever produce one.
|
|
346
|
+
if (status === 301 || status === 302 || status === 303 || status === 307 || status === 308) {
|
|
347
|
+
res.resume();
|
|
348
|
+
reject(new Error(`pinnedFetch: refused to follow a ${status} redirect`
|
|
349
|
+
+ (typeof res.headers.location === 'string' ? ` to "${res.headers.location}"` : '')
|
|
350
|
+
+ '. Matches fetch\'s redirect: \'error\' behavior — a guard-passing endpoint redirecting into blocked address space is the other half of the SSRF finding this transport closes.'));
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
resolve({
|
|
354
|
+
ok: status >= 200 && status < 300,
|
|
355
|
+
status,
|
|
356
|
+
body: res,
|
|
357
|
+
text: () => new Promise((resolveText, rejectText) => {
|
|
358
|
+
const chunks = [];
|
|
359
|
+
res.on('data', (chunk) => chunks.push(chunk));
|
|
360
|
+
res.on('end', () => resolveText(Buffer.concat(chunks).toString('utf8')));
|
|
361
|
+
res.on('error', rejectText);
|
|
362
|
+
}),
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
if (init.signal) {
|
|
366
|
+
if (init.signal.aborted) {
|
|
367
|
+
req.destroy(new Error('The operation was aborted'));
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
init.signal.addEventListener('abort', () => req.destroy(new Error('The operation was aborted')), { once: true });
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
// Fires on socket INACTIVITY (no bytes sent or received), covering connect hangs, a
|
|
374
|
+
// provider that accepts the connection and then never speaks, and a body that stalls
|
|
375
|
+
// mid-stream — not on total request duration, matching `setTimeout`'s own semantics.
|
|
376
|
+
req.setTimeout(PINNED_FETCH_IDLE_TIMEOUT_MS, () => {
|
|
377
|
+
req.destroy(new Error(`pinnedFetch: no activity for ${PINNED_FETCH_IDLE_TIMEOUT_MS}ms`));
|
|
378
|
+
});
|
|
379
|
+
req.on('error', reject);
|
|
380
|
+
req.end(init.body);
|
|
381
|
+
});
|
|
180
382
|
}
|
|
181
383
|
function escapeRegExp(value) {
|
|
182
384
|
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection-guard.js","sourceRoot":"","sources":["../../src/providers/connection-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAQH,SAAS,sBAAsB,CAAC,QAAgB;IAC9C,MAAM,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC;QACjE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACvB,CAAC,CAAC,QAAQ,CAAC;IACb,wEAAwE;IACxE,0EAA0E;IAC1E,wEAAwE;IACxE,+DAA+D;IAC/D,OAAO,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,SAAS,CAAC,QAAgB;IACjC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACpC,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QAChC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACzC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IACnD,CAAC,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACtD,OAAO,MAA0C,CAAC;AACpD,CAAC;AAED,SAAS,cAAc,CAAC,QAAgB;IACtC,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IAClC,OAAO,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,aAAa,CAAC,QAAgB;IACrC,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IAClC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC;IACrB,OAAO,CACL,CAAC,KAAK,CAAC;QACP,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC;QAClC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC;QACxB,CAAC,KAAK,EAAE;QACR,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC;QACxB,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QACjC,CAAC,IAAI,GAAG,CACT,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAgB;IAC1C,MAAM,IAAI,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAChD,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,SAAS,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QAAE,OAAO,MAAM,CAAC,WAAW,EAAE,CAAC;IACjE,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnC,IACE,QAAQ,CAAC,MAAM,KAAK,CAAC;QACrB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EACxD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,0EAA0E;IAC1E,6DAA6D;IAC7D,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC;IACxB,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC;IACxB,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACxE,OAAO;QACL,CAAC,KAAK,KAAK,EAAE,CAAC,GAAG,GAAG;QACpB,CAAC,KAAK,KAAK,EAAE,CAAC,GAAG,GAAG;QACpB,CAAC,KAAK,KAAK,CAAC,CAAC,GAAG,GAAG;QACnB,KAAK,GAAG,GAAG;KACZ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACd,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,MAAM,IAAI,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IAC9C,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IACxD,IAAI,cAAc,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,gKAAgK;AAChK,MAAM,UAAU,4BAA4B,CAAC,QAAgB;IAC3D,MAAM,IAAI,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IAC9C,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC/B,IAAI,aAAa,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,IAAI,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAClD,IAAI,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAClD,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO,OAAO,CAAC,MAAM,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,+IAA+I;AAC/I,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC;IACtC,CAAC;IACD,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnD,OAAO,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC;IAC9C,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IAC/C,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,IAAI,4BAA4B,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3E,OAAO,EAAE,KAAK,EAAE,sBAAsB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC5D,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC;AAKD,SAAS,kBAAkB,CAAC,QAAgB;IAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC;QAC7D,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACvB,CAAC,CAAC,QAAQ,CAAC;IACb,IAAI,2BAA2B,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACxD,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,OAAe,EACf,MAAmB;IAEnB,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACtC,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAE5C,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IACpD,IAAI,iBAAiB,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7C,IAAI,kBAAkB,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAE9C,IAAI,SAA6B,CAAC;IAClC,IAAI,CAAC;QACH,SAAS,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;QAC9C,IAAI,iBAAiB,CAAC,EAAE,CAAC;YAAE,SAAS;QACpC,IAAI,4BAA4B,CAAC,EAAE,CAAC,EAAE,CAAC;YACrC,OAAO,EAAE,KAAK,EAAE,sBAAsB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,OAAO,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AACtD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAY,EACZ,eAAyD,EAAE;IAE3D,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC7D,IAAI,QAAQ,GAAG,IAAI;SAChB,OAAO,CAAC,gCAAgC,EAAE,mBAAmB,CAAC;SAC9D,OAAO,CAAC,0DAA0D,EAAE,gBAAgB,CAAC;SACrF,OAAO,CAAC,qBAAqB,EAAE,cAAc,CAAC,CAAC;IAClD,KAAK,MAAM,MAAM,IAAI,YAAY,EAAE,CAAC;QAClC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAChE,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,EAAE,YAAY,CAAC,CAAC;IACnF,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,kIAAkI;AAClI,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,QAAgB;IACrD,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5E,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;AACpE,CAAC"}
|
|
1
|
+
{"version":3,"file":"connection-guard.js","sourceRoot":"","sources":["../../src/providers/connection-guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module providers/connection-test
|
|
3
|
+
*
|
|
4
|
+
* BYOK connection smoke test — sends a tiny "Reply with only: ok" completion
|
|
5
|
+
* request to the configured provider endpoint and classifies the outcome, so
|
|
6
|
+
* a settings UI can tell the operator "this endpoint works" without spending
|
|
7
|
+
* a real chat turn to find out. Ported from OD's `apps/daemon/src/connectionTest.ts`
|
|
8
|
+
* (`testProviderConnection` + `buildProviderCall` + `inspectProviderCompletion`),
|
|
9
|
+
* narrowed to the four protocols `@jini-ai/ui`'s execution-tab canary exposes
|
|
10
|
+
* (`anthropic` / `openai` / `azure` / `google`) — the origin also covers
|
|
11
|
+
* `ollama` / `senseaudio` / `aihubmix` / `bedrock`, which stay out of scope
|
|
12
|
+
* here the same way `model-catalog.ts` keeps Bedrock to a static seed and
|
|
13
|
+
* Azure to an explicit "unsupported" response for model discovery.
|
|
14
|
+
*
|
|
15
|
+
* Shares this package's own vendored SSRF guard / secret redaction
|
|
16
|
+
* (`connection-guard.ts`) and vendored connectivity types (`types.ts`) —
|
|
17
|
+
* no OD workspace-package imports, matching every other file in this
|
|
18
|
+
* directory.
|
|
19
|
+
*/
|
|
20
|
+
import type { DnsLookupFn } from './connection-guard.js';
|
|
21
|
+
import type { ConnectionTestKind, ConnectionTestProtocol } from './types.js';
|
|
22
|
+
/** The four wire protocols this smoke test knows how to speak. A narrower
|
|
23
|
+
* type than {@link ConnectionTestProtocol} on purpose — see this module's
|
|
24
|
+
* header for what's out of scope and why. */
|
|
25
|
+
export type SupportedConnectionTestProtocol = 'anthropic' | 'openai' | 'azure' | 'google';
|
|
26
|
+
export interface ProviderConnectionTestRequest {
|
|
27
|
+
protocol: ConnectionTestProtocol;
|
|
28
|
+
baseUrl: string;
|
|
29
|
+
apiKey: string;
|
|
30
|
+
model: string;
|
|
31
|
+
/** Azure only — the `api-version` query param. */
|
|
32
|
+
apiVersion?: string;
|
|
33
|
+
}
|
|
34
|
+
export type ProviderConnectionTestInput = ProviderConnectionTestRequest & {
|
|
35
|
+
signal?: AbortSignal;
|
|
36
|
+
requestInit?: Pick<RequestInit, 'dispatcher'>;
|
|
37
|
+
/** Injectable DNS resolver for the base-URL SSRF guard; defaults to `node:dns`. */
|
|
38
|
+
dnsLookup?: DnsLookupFn;
|
|
39
|
+
};
|
|
40
|
+
export interface ConnectionTestResponse {
|
|
41
|
+
ok: boolean;
|
|
42
|
+
kind: ConnectionTestKind;
|
|
43
|
+
latencyMs: number;
|
|
44
|
+
model?: string;
|
|
45
|
+
status?: number;
|
|
46
|
+
detail?: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Probes a BYOK provider endpoint with the supplied credentials by sending a
|
|
50
|
+
* tiny smoke-test completion request, and classifies the result. Validates
|
|
51
|
+
* the base URL (sync + DNS-resolved SSRF guard) before issuing any request,
|
|
52
|
+
* exactly like {@link import('./model-catalog.js').listProviderModels}.
|
|
53
|
+
*
|
|
54
|
+
* Never throws for provider-side or network failures — every failure path
|
|
55
|
+
* resolves to `{ ok: false, kind, detail }`. Only truly unsupported
|
|
56
|
+
* protocols short-circuit before any network access.
|
|
57
|
+
*
|
|
58
|
+
* @complexity O(1) — one bounded-size HTTP request with a hard timeout.
|
|
59
|
+
* @overallScore 100
|
|
60
|
+
*/
|
|
61
|
+
export declare function testProviderConnection(input: ProviderConnectionTestInput): Promise<ConnectionTestResponse>;
|
|
62
|
+
//# sourceMappingURL=connection-test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-test.d.ts","sourceRoot":"","sources":["../../src/providers/connection-test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAE7E;;8CAE8C;AAC9C,MAAM,MAAM,+BAA+B,GAAG,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE1F,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,EAAE,sBAAsB,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,2BAA2B,GAAG,6BAA6B,GAAG;IACxE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,WAAW,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAC9C,mFAAmF;IACnF,SAAS,CAAC,EAAE,WAAW,CAAC;CACzB,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,kBAAkB,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAuPD;;;;;;;;;;;;GAYG;AACH,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,GAAG,OAAO,CAAC,sBAAsB,CAAC,CA0IhH"}
|