@alexkroman1/aai 0.10.3 → 0.10.4
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/_internal-types.d.ts +8 -1
- package/dist/_runtime-conformance.d.ts +64 -0
- package/dist/_test-utils.d.ts +70 -0
- package/dist/_utils.d.ts +1 -8
- package/dist/_utils.js +49 -2
- package/dist/builtin-tools.d.ts +1 -5
- package/dist/constants-BbAOvKl_.js +47 -0
- package/dist/constants.d.ts +44 -0
- package/dist/direct-executor-BfHrDdPL.js +1589 -0
- package/dist/direct-executor.d.ts +90 -31
- package/dist/hooks.d.ts +44 -0
- package/dist/hooks.js +58 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +2 -2
- package/dist/internal.d.ts +19 -0
- package/dist/internal.js +209 -0
- package/dist/kv.d.ts +1 -1
- package/dist/kv.js +32 -1
- package/dist/matchers.js +1 -1
- package/dist/protocol.d.ts +3 -29
- package/dist/protocol.js +140 -2
- package/dist/server.d.ts +27 -40
- package/dist/server.js +117 -145
- package/dist/session.d.ts +65 -44
- package/dist/{testing-BbitshLb.js → testing-BonJtfHJ.js} +25 -43
- package/dist/testing.d.ts +9 -14
- package/dist/testing.js +2 -2
- package/dist/types.d.ts +24 -226
- package/dist/types.js +176 -2
- package/dist/types.test-d.d.ts +7 -0
- package/dist/vite-plugin.d.ts +15 -0
- package/dist/vite-plugin.js +82 -0
- package/dist/ws-handler.d.ts +1 -2
- package/package.json +28 -88
- package/dist/_embeddings.d.ts +0 -31
- package/dist/_internal-types-IfPcaJd5.js +0 -61
- package/dist/_internal-types.js +0 -2
- package/dist/_session-ctx.d.ts +0 -73
- package/dist/_session-otel.d.ts +0 -43
- package/dist/_session-persist.d.ts +0 -30
- package/dist/_ssrf-DCp_27V4.js +0 -123
- package/dist/_ssrf.d.ts +0 -30
- package/dist/_ssrf.js +0 -2
- package/dist/_utils-DgzpOMSV.js +0 -61
- package/dist/direct-executor-B-5mq3cu.js +0 -570
- package/dist/kv-iXtikQmR.js +0 -32
- package/dist/middleware-core-BwyBIPed.js +0 -107
- package/dist/middleware-core.d.ts +0 -47
- package/dist/middleware-core.js +0 -2
- package/dist/middleware.d.ts +0 -37
- package/dist/protocol-B-H2Q4ox.js +0 -162
- package/dist/runtime-CxcwaK68.js +0 -58
- package/dist/runtime.js +0 -2
- package/dist/s2s-M7JqtgFw.js +0 -272
- package/dist/s2s.js +0 -2
- package/dist/session-BYlwcrya.js +0 -683
- package/dist/session.js +0 -2
- package/dist/telemetry-CJlaDFNc.js +0 -95
- package/dist/telemetry.d.ts +0 -49
- package/dist/telemetry.js +0 -2
- package/dist/types-D8ZBxTL_.js +0 -192
- package/dist/unstorage-kv-CDgP-frt.js +0 -64
- package/dist/unstorage-kv.js +0 -2
- package/dist/unstorage-vector-Cj5llNhg.js +0 -172
- package/dist/unstorage-vector.d.ts +0 -47
- package/dist/unstorage-vector.js +0 -2
- package/dist/vector.d.ts +0 -86
- package/dist/vector.js +0 -49
- package/dist/worker-entry-2jaiqIj0.js +0 -70
- package/dist/worker-entry.d.ts +0 -47
- package/dist/worker-entry.js +0 -2
- package/dist/ws-handler-C0Q6eSay.js +0 -207
- package/dist/ws-handler.js +0 -2
package/dist/_session-otel.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OpenTelemetry-instrumented session helpers.
|
|
3
|
-
*
|
|
4
|
-
* Extracted from session.ts to keep it under the file-length lint limit.
|
|
5
|
-
* These functions add trace spans and metric counters to the S2S session
|
|
6
|
-
* pipeline: tool calls, user turns, barge-ins, and session lifecycle.
|
|
7
|
-
*/
|
|
8
|
-
import type { S2sSessionCtx } from "./_session-ctx.ts";
|
|
9
|
-
import type { S2sHandle, S2sToolCall } from "./s2s.ts";
|
|
10
|
-
export { activeSessionsUpDown, sessionCounter } from "./telemetry.ts";
|
|
11
|
-
/**
|
|
12
|
-
* Orchestrate the full tool call pipeline for a single S2S tool invocation.
|
|
13
|
-
*
|
|
14
|
-
* Steps: resolve per-turn config → check step/tool limits → run middleware
|
|
15
|
-
* `interceptToolCall` (which may block, return a cached result, or modify args)
|
|
16
|
-
* → execute the tool → run `afterToolCall` middleware → record metrics and
|
|
17
|
-
* finish via {@link finishToolCall}. Each step is wrapped in an OpenTelemetry
|
|
18
|
-
* span (`tool.call`) with agent/session/tool attributes.
|
|
19
|
-
*
|
|
20
|
-
* @param ctx - The shared mutable session context (see {@link S2sSessionCtx}).
|
|
21
|
-
* @param detail - The tool call details from the S2S API (call ID, name, parsed args).
|
|
22
|
-
*/
|
|
23
|
-
export declare function handleToolCall(ctx: S2sSessionCtx, detail: S2sToolCall): Promise<void>;
|
|
24
|
-
/** Options for customizing S2S event listener behavior. */
|
|
25
|
-
export type SetupListenersOptions = {
|
|
26
|
-
/** Custom handler for session expiration. When provided, replaces the
|
|
27
|
-
* default behavior of closing the handle. Used by resume logic to
|
|
28
|
-
* fall back to a fresh session when S2S resume fails. */
|
|
29
|
-
onSessionExpired?: () => void;
|
|
30
|
-
};
|
|
31
|
-
/**
|
|
32
|
-
* Wire all S2S events to the client sink, hooks, and session state.
|
|
33
|
-
*
|
|
34
|
-
* Registers listeners on the S2S handle for: ready, session expiry, speech
|
|
35
|
-
* start/stop, user/agent transcripts, reply lifecycle, tool calls, audio
|
|
36
|
-
* chunks, errors, and close. Each listener delegates to a focused handler
|
|
37
|
-
* function that updates `ctx` and emits client events.
|
|
38
|
-
*
|
|
39
|
-
* @param ctx - The shared mutable session context.
|
|
40
|
-
* @param handle - The S2S WebSocket handle to listen on.
|
|
41
|
-
* @param opts - Optional overrides for listener behavior.
|
|
42
|
-
*/
|
|
43
|
-
export declare function setupListeners(ctx: S2sSessionCtx, handle: S2sHandle, opts?: SetupListenersOptions): void;
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Session persistence helpers.
|
|
3
|
-
*
|
|
4
|
-
* Saves and restores session state, conversation messages, and S2S session ID
|
|
5
|
-
* to/from the KV store for cross-reconnect session recovery.
|
|
6
|
-
*/
|
|
7
|
-
import type { Kv } from "./kv.ts";
|
|
8
|
-
import type { Logger } from "./runtime.ts";
|
|
9
|
-
import type { Message } from "./types.ts";
|
|
10
|
-
export declare function persistKey(sessionId: string): string;
|
|
11
|
-
export type PersistedSession = {
|
|
12
|
-
s2sSessionId: string | null;
|
|
13
|
-
messages: Message[];
|
|
14
|
-
state: Record<string, unknown>;
|
|
15
|
-
};
|
|
16
|
-
export type SessionPersistence = {
|
|
17
|
-
kv: Kv;
|
|
18
|
-
ttl: number;
|
|
19
|
-
getState: () => Record<string, unknown>;
|
|
20
|
-
setState: (state: Record<string, unknown>) => void;
|
|
21
|
-
};
|
|
22
|
-
type PersistCtx = {
|
|
23
|
-
pushMessages(...msgs: Message[]): void;
|
|
24
|
-
conversationMessages: Message[];
|
|
25
|
-
};
|
|
26
|
-
export declare function restorePersistedSession(persistence: SessionPersistence, resumeFrom: string, ctx: PersistCtx, log: Logger): Promise<string | null>;
|
|
27
|
-
export declare function saveSessionData(persistence: SessionPersistence, sessionId: string, ctx: PersistCtx, s2sSessionId: string | null, log: Logger,
|
|
28
|
-
/** Old session key to clean up (from a previous session we resumed from). */
|
|
29
|
-
cleanupKey?: string): Promise<void>;
|
|
30
|
-
export {};
|
package/dist/_ssrf-DCp_27V4.js
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import { lookup } from "node:dns/promises";
|
|
2
|
-
import { BlockList } from "node:net";
|
|
3
|
-
//#region _ssrf.ts
|
|
4
|
-
/**
|
|
5
|
-
* SSRF protection for AAI network tools.
|
|
6
|
-
*
|
|
7
|
-
* Validates URLs against private/reserved IP ranges and handles redirects
|
|
8
|
-
* safely by re-validating each redirect target. Used by both the SDK
|
|
9
|
-
* (self-hosted built-in tools) and the platform server.
|
|
10
|
-
*/
|
|
11
|
-
const privateBlocks = new BlockList();
|
|
12
|
-
for (const [prefix, bits] of [
|
|
13
|
-
["0.0.0.0", 8],
|
|
14
|
-
["10.0.0.0", 8],
|
|
15
|
-
["100.64.0.0", 10],
|
|
16
|
-
["127.0.0.0", 8],
|
|
17
|
-
["169.254.0.0", 16],
|
|
18
|
-
["172.16.0.0", 12],
|
|
19
|
-
["192.0.0.0", 24],
|
|
20
|
-
["192.168.0.0", 16],
|
|
21
|
-
["198.18.0.0", 15],
|
|
22
|
-
["224.0.0.0", 4],
|
|
23
|
-
["240.0.0.0", 4]
|
|
24
|
-
]) privateBlocks.addSubnet(prefix, bits, "ipv4");
|
|
25
|
-
for (const [prefix, bits] of [
|
|
26
|
-
["::1", 128],
|
|
27
|
-
["::", 128],
|
|
28
|
-
["fc00::", 7],
|
|
29
|
-
["fe80::", 10],
|
|
30
|
-
["ff00::", 8]
|
|
31
|
-
]) privateBlocks.addSubnet(prefix, bits, "ipv6");
|
|
32
|
-
/**
|
|
33
|
-
* Check whether an IP address falls within a private or reserved range.
|
|
34
|
-
*
|
|
35
|
-
* @param ip - An IPv4 or IPv6 address string.
|
|
36
|
-
* @returns `true` if the address is in a private/reserved range.
|
|
37
|
-
*/
|
|
38
|
-
function isPrivateIp(ip) {
|
|
39
|
-
const type = ip.includes(":") ? "ipv6" : "ipv4";
|
|
40
|
-
return privateBlocks.check(ip, type);
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Detect IPv4-mapped IPv6 addresses and extract the embedded IPv4.
|
|
44
|
-
* Handles both dotted form (`::ffff:127.0.0.1`) and hex form (`::ffff:7f00:1`).
|
|
45
|
-
*/
|
|
46
|
-
function extractMappedIp(ip) {
|
|
47
|
-
const mappedDotted = ip.match(/^::ffff:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/i);
|
|
48
|
-
if (mappedDotted) return mappedDotted[1];
|
|
49
|
-
const mappedHex = ip.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i);
|
|
50
|
-
if (mappedHex) {
|
|
51
|
-
const hi = Number.parseInt(mappedHex[1], 16);
|
|
52
|
-
const lo = Number.parseInt(mappedHex[2], 16);
|
|
53
|
-
return `${hi >> 8 & 255}.${hi & 255}.${lo >> 8 & 255}.${lo & 255}`;
|
|
54
|
-
}
|
|
55
|
-
return ip;
|
|
56
|
-
}
|
|
57
|
-
function isBlockedHostname(hostname) {
|
|
58
|
-
const lower = hostname.toLowerCase();
|
|
59
|
-
return lower === "localhost" || lower.endsWith(".local") || lower.endsWith(".internal") || lower === "169.254.169.254";
|
|
60
|
-
}
|
|
61
|
-
function isLiteralIp(hostname) {
|
|
62
|
-
return /^\d{1,3}(\.\d{1,3}){3}$/.test(hostname) || hostname.includes(":");
|
|
63
|
-
}
|
|
64
|
-
/** Resolve hostname and block if it points to a private IP (DNS rebinding). */
|
|
65
|
-
async function assertDnsResolvesPublic(hostname) {
|
|
66
|
-
try {
|
|
67
|
-
const { address } = await Promise.race([lookup(hostname), new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error("DNS lookup timed out")), 2e3))]);
|
|
68
|
-
const resolved = extractMappedIp(address);
|
|
69
|
-
if (isPrivateIp(address) || isPrivateIp(resolved)) throw new Error(`Blocked request: ${hostname} resolves to private address ${address}`);
|
|
70
|
-
} catch (err) {
|
|
71
|
-
if (err instanceof Error && err.message.startsWith("Blocked request")) throw err;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* SSRF guard: assert that a URL targets a public internet address.
|
|
76
|
-
*
|
|
77
|
-
* Blocks requests to:
|
|
78
|
-
* - Private IPv4 ranges (RFC 1918: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
|
|
79
|
-
* - Loopback (127.0.0.0/8), link-local (169.254.0.0/16), shared (100.64.0.0/10)
|
|
80
|
-
* - IPv4-mapped IPv6 addresses embedding private IPs (e.g. `::ffff:127.0.0.1`)
|
|
81
|
-
* - IPv6 loopback (`::1`), ULA (`fc00::/7`), link-local (`fe80::/10`)
|
|
82
|
-
* - `localhost`, `.local` (mDNS), `.internal` domains
|
|
83
|
-
* - Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`)
|
|
84
|
-
* - Non-http(s) schemes (e.g. `file:`, `ftp:`)
|
|
85
|
-
* - Hostnames that resolve to private IPs via DNS (prevents DNS rebinding)
|
|
86
|
-
*
|
|
87
|
-
* @param url - The URL to validate (must be parseable by `new URL()`).
|
|
88
|
-
* @throws {Error} If the URL targets a private/reserved address or uses a
|
|
89
|
-
* disallowed protocol scheme.
|
|
90
|
-
*/
|
|
91
|
-
async function assertPublicUrl(url) {
|
|
92
|
-
const parsed = new URL(url);
|
|
93
|
-
const hostname = parsed.hostname.replace(/^\[|\]$/g, "");
|
|
94
|
-
const effective = extractMappedIp(hostname);
|
|
95
|
-
if (isPrivateIp(hostname) || isPrivateIp(effective)) throw new Error(`Blocked request to private address: ${hostname}`);
|
|
96
|
-
if (isBlockedHostname(hostname)) throw new Error(`Blocked request to private address: ${hostname}`);
|
|
97
|
-
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") throw new Error(`Blocked request with disallowed protocol: ${parsed.protocol}`);
|
|
98
|
-
if (!isLiteralIp(hostname)) await assertDnsResolvesPublic(hostname);
|
|
99
|
-
}
|
|
100
|
-
/** Maximum number of redirects to follow manually. */
|
|
101
|
-
const MAX_REDIRECTS = 5;
|
|
102
|
-
/**
|
|
103
|
-
* Fetch with SSRF-safe redirect handling: validates each redirect URL
|
|
104
|
-
* against private/reserved IP ranges before following.
|
|
105
|
-
*/
|
|
106
|
-
async function ssrfSafeFetch(url, init, fetchFn) {
|
|
107
|
-
await assertPublicUrl(url);
|
|
108
|
-
let currentUrl = url;
|
|
109
|
-
for (let i = 0; i <= MAX_REDIRECTS; i++) {
|
|
110
|
-
const resp = await fetchFn(currentUrl, {
|
|
111
|
-
...init,
|
|
112
|
-
redirect: "manual"
|
|
113
|
-
});
|
|
114
|
-
if (resp.status < 300 || resp.status >= 400) return resp;
|
|
115
|
-
const location = resp.headers.get("location");
|
|
116
|
-
if (!location) return resp;
|
|
117
|
-
currentUrl = new URL(location, currentUrl).href;
|
|
118
|
-
await assertPublicUrl(currentUrl);
|
|
119
|
-
}
|
|
120
|
-
throw new Error("Too many redirects");
|
|
121
|
-
}
|
|
122
|
-
//#endregion
|
|
123
|
-
export { isPrivateIp as n, ssrfSafeFetch as r, assertPublicUrl as t };
|
package/dist/_ssrf.d.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Check whether an IP address falls within a private or reserved range.
|
|
3
|
-
*
|
|
4
|
-
* @param ip - An IPv4 or IPv6 address string.
|
|
5
|
-
* @returns `true` if the address is in a private/reserved range.
|
|
6
|
-
*/
|
|
7
|
-
export declare function isPrivateIp(ip: string): boolean;
|
|
8
|
-
/**
|
|
9
|
-
* SSRF guard: assert that a URL targets a public internet address.
|
|
10
|
-
*
|
|
11
|
-
* Blocks requests to:
|
|
12
|
-
* - Private IPv4 ranges (RFC 1918: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
|
|
13
|
-
* - Loopback (127.0.0.0/8), link-local (169.254.0.0/16), shared (100.64.0.0/10)
|
|
14
|
-
* - IPv4-mapped IPv6 addresses embedding private IPs (e.g. `::ffff:127.0.0.1`)
|
|
15
|
-
* - IPv6 loopback (`::1`), ULA (`fc00::/7`), link-local (`fe80::/10`)
|
|
16
|
-
* - `localhost`, `.local` (mDNS), `.internal` domains
|
|
17
|
-
* - Cloud metadata endpoints (`169.254.169.254`, `metadata.google.internal`)
|
|
18
|
-
* - Non-http(s) schemes (e.g. `file:`, `ftp:`)
|
|
19
|
-
* - Hostnames that resolve to private IPs via DNS (prevents DNS rebinding)
|
|
20
|
-
*
|
|
21
|
-
* @param url - The URL to validate (must be parseable by `new URL()`).
|
|
22
|
-
* @throws {Error} If the URL targets a private/reserved address or uses a
|
|
23
|
-
* disallowed protocol scheme.
|
|
24
|
-
*/
|
|
25
|
-
export declare function assertPublicUrl(url: string): Promise<void>;
|
|
26
|
-
/**
|
|
27
|
-
* Fetch with SSRF-safe redirect handling: validates each redirect URL
|
|
28
|
-
* against private/reserved IP ranges before following.
|
|
29
|
-
*/
|
|
30
|
-
export declare function ssrfSafeFetch(url: string, init: RequestInit, fetchFn: typeof globalThis.fetch): Promise<Response>;
|
package/dist/_ssrf.js
DELETED
package/dist/_utils-DgzpOMSV.js
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
//#region _utils.ts
|
|
2
|
-
/** Shared utility functions. */
|
|
3
|
-
/** Extract an error message from an unknown thrown value. */
|
|
4
|
-
function errorMessage(err) {
|
|
5
|
-
return err instanceof Error ? err.message : String(err);
|
|
6
|
-
}
|
|
7
|
-
/** Extract a detailed error string (message + stack) for diagnostic logging. */
|
|
8
|
-
function errorDetail(err) {
|
|
9
|
-
if (err instanceof Error) return err.stack ?? err.message;
|
|
10
|
-
return String(err);
|
|
11
|
-
}
|
|
12
|
-
/** Filter out undefined values from an env record. */
|
|
13
|
-
function filterEnv(env) {
|
|
14
|
-
return Object.fromEntries(Object.entries(env).filter((e) => e[1] !== void 0));
|
|
15
|
-
}
|
|
16
|
-
/** Set of filesystem operations that are safe for read-only access. */
|
|
17
|
-
const READ_ONLY_FS_OPS = new Set([
|
|
18
|
-
"read",
|
|
19
|
-
"stat",
|
|
20
|
-
"readdir",
|
|
21
|
-
"exists"
|
|
22
|
-
]);
|
|
23
|
-
/** Check whether a filesystem operation is a read-only operation. */
|
|
24
|
-
function isReadOnlyFsOp(op) {
|
|
25
|
-
return READ_ONLY_FS_OPS.has(op);
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Safely extract the port from `server.address()`, guarding against the
|
|
29
|
-
* string (pipe/socket) and null return types.
|
|
30
|
-
*/
|
|
31
|
-
function getServerPort(addr) {
|
|
32
|
-
if (addr && typeof addr === "object" && "port" in addr && typeof addr.port === "number") return addr.port;
|
|
33
|
-
throw new Error(`Expected server address with numeric port, got: ${JSON.stringify(addr)}`);
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Lazily initialized per-session state manager.
|
|
37
|
-
*
|
|
38
|
-
* On first access for a given session, calls `initState()` (if provided) to
|
|
39
|
-
* create the initial state. Returns `{}` if no initializer and no prior state.
|
|
40
|
-
*/
|
|
41
|
-
function createSessionStateMap(initState) {
|
|
42
|
-
const map = /* @__PURE__ */ new Map();
|
|
43
|
-
return {
|
|
44
|
-
get(sessionId) {
|
|
45
|
-
if (!map.has(sessionId) && initState) map.set(sessionId, initState());
|
|
46
|
-
return map.get(sessionId) ?? {};
|
|
47
|
-
},
|
|
48
|
-
set(sessionId, state) {
|
|
49
|
-
map.set(sessionId, state);
|
|
50
|
-
},
|
|
51
|
-
delete(sessionId) {
|
|
52
|
-
return map.delete(sessionId);
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
/** Return a JSON error string for the LLM: `'{"error":"<message>"}'`. */
|
|
57
|
-
function toolError(message) {
|
|
58
|
-
return JSON.stringify({ error: message });
|
|
59
|
-
}
|
|
60
|
-
//#endregion
|
|
61
|
-
export { getServerPort as a, filterEnv as i, errorDetail as n, isReadOnlyFsOp as o, errorMessage as r, toolError as s, createSessionStateMap as t };
|