@jami-studio/core 0.92.25 → 0.92.27

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.
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Workerd-safe memoization for module-scope init promises.
3
+ *
4
+ * Nearly every SQL-backed store memoizes its table-creation promise at module
5
+ * scope (`let _initPromise`). On Cloudflare Workers (workerd) that pattern has
6
+ * a lethal failure mode: workerd cancels a request's pending I/O the moment
7
+ * its response returns, so an init promise CREATED during an early-responding
8
+ * request (auth probe, 404) FREEZES forever — and every later caller that
9
+ * awaits the memo hangs permanently. Proven live: `ensureObservabilityTables`
10
+ * frozen by a `get-session`-first ordering wedged every agent chat run at
11
+ * "Starting agent" on the unified Cloudflare runtime.
12
+ *
13
+ * `createInitMemo` keeps the single-flight memo semantics everywhere, and on
14
+ * workerd adds two layers of defense:
15
+ * 1. The init promise is tied to the creating request's lifetime via
16
+ * `__cf_ctx.waitUntil`, so workerd keeps its I/O alive to completion
17
+ * even when the response returns first (same remedy as the plugin-init
18
+ * freeze fix in framework-request-handler.ts).
19
+ * 2. Awaits on a still-pending memo are bounded; on timeout the memo is
20
+ * re-run under the CURRENT (live) request. Init bodies are idempotent
21
+ * (CREATE TABLE IF NOT EXISTS / guarded ALTERs), so a re-run is safe.
22
+ *
23
+ * On Node the behavior is identical to the raw memo pattern (single flight,
24
+ * failed init clears the memo so the next caller retries).
25
+ */
26
+
27
+ import { isCloudflareRuntime } from "./runtime.js";
28
+
29
+ /** How long a pending memo may be awaited on workerd before it is presumed
30
+ * frozen and re-run. Long enough for a slow cold init (Neon DDL over HTTP),
31
+ * short enough that a frozen memo degrades to a slow call, not a hang. */
32
+ export const INIT_MEMO_FROZEN_RETRY_MS = 15_000;
33
+
34
+ const FROZEN = Symbol("init-memo-frozen");
35
+
36
+ export function createInitMemo(
37
+ init: () => Promise<void>,
38
+ options?: { frozenRetryMs?: number; label?: string },
39
+ ): () => Promise<void> {
40
+ const frozenRetryMs = options?.frozenRetryMs ?? INIT_MEMO_FROZEN_RETRY_MS;
41
+ let promise: Promise<void> | undefined;
42
+ let settled = false;
43
+
44
+ const start = (): Promise<void> => {
45
+ settled = false;
46
+ const p = init().then(
47
+ () => {
48
+ settled = true;
49
+ },
50
+ (err) => {
51
+ // Failed init must not be memoized — the next caller retries.
52
+ promise = undefined;
53
+ throw err;
54
+ },
55
+ );
56
+ // Keep the init's I/O alive past the creating request's response on
57
+ // workerd. The extra catch keeps waitUntil from surfacing the rejection
58
+ // twice; callers still see it through the memoized promise.
59
+ try {
60
+ (
61
+ globalThis as {
62
+ __cf_ctx?: { waitUntil?: (p: Promise<unknown>) => void };
63
+ }
64
+ ).__cf_ctx?.waitUntil?.(p.catch(() => {}));
65
+ } catch {
66
+ /* not on Cloudflare — nothing to extend */
67
+ }
68
+ return p;
69
+ };
70
+
71
+ return async (): Promise<void> => {
72
+ if (!promise) promise = start();
73
+ if (settled || !isCloudflareRuntime()) return promise;
74
+
75
+ // workerd + still pending: the memo may belong to a completed request
76
+ // whose I/O was frozen. Bounded wait, then re-run under this request.
77
+ let timer: ReturnType<typeof setTimeout> | undefined;
78
+ const raced = await Promise.race([
79
+ promise,
80
+ new Promise<typeof FROZEN>((resolve) => {
81
+ timer = setTimeout(() => resolve(FROZEN), frozenRetryMs);
82
+ }),
83
+ ]).finally(() => {
84
+ if (timer) clearTimeout(timer);
85
+ });
86
+ if (raced !== FROZEN) return;
87
+
88
+ console.warn(
89
+ `[agent-native] init memo${options?.label ? ` (${options.label})` : ""} still pending after ${frozenRetryMs}ms — presumed frozen by a completed request; re-running under the current request`,
90
+ );
91
+ promise = start();
92
+ return promise;
93
+ };
94
+ }
@@ -32,12 +32,11 @@ function parseMentions(value: string | null): Mention[] {
32
32
  export default defineAction({
33
33
  description: "List all comments on a document, grouped by thread.",
34
34
  schema: z.object({
35
- documentId: z.string().optional().describe("Document ID (required)"),
35
+ documentId: z.string().min(1).describe("Document ID (required)"),
36
36
  }),
37
37
  http: { method: "GET" },
38
38
  run: async (args) => {
39
39
  const documentId = args.documentId;
40
- if (!documentId) throw new Error("--documentId is required");
41
40
 
42
41
  const access = await assertAccess("document", documentId, "viewer");
43
42
  const ownerEmail = access.resource.ownerEmail as string;
@@ -62,11 +62,11 @@ export declare const postAwareness: import("h3").EventHandlerWithFetch<import("h
62
62
  error: string;
63
63
  states?: undefined;
64
64
  } | {
65
- error?: undefined;
66
65
  states: {
67
66
  clientId: number;
68
67
  state: string;
69
68
  }[];
69
+ error?: undefined;
70
70
  }>>;
71
71
  /**
72
72
  * GET /_agent-native/collab/:docId/users
@@ -77,10 +77,10 @@ export declare const getActiveUsers: import("h3").EventHandlerWithFetch<import("
77
77
  error: string;
78
78
  users?: undefined;
79
79
  } | {
80
- error?: undefined;
81
80
  users: {
82
81
  clientId: number;
83
82
  lastSeen: number;
84
83
  }[];
84
+ error?: undefined;
85
85
  }>>;
86
86
  //# sourceMappingURL=awareness.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"awareness.d.ts","sourceRoot":"","sources":["../../src/collab/awareness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAgB3C,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAOD,eAAO,MAAM,sBAAsB,EAAG,kBAA2B,CAAC;AAElE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,kBAAkB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAOD,wBAAgB,mBAAmB,IAAI,YAAY,CAElD;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,cAAc,GAAG,SAAS,GAChC,IAAI,CAON;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EAClD,KAAK,CAAC,EAAE,cAAc,GACrB,IAAI,CAgBN;AAoBD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,MAAmB,GAC7B,IAAI,CAON;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAE1E;AAiBD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAO1E;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,IAAI,CAOnE;AAkCD;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa;;;;;;kBAwDa,MAAM;eAAS,MAAM;;GAoB1D,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;;;;kBAYM,MAAM;kBAAY,MAAM;;GAMvD,CAAC"}
1
+ {"version":3,"file":"awareness.d.ts","sourceRoot":"","sources":["../../src/collab/awareness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAgB3C,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAOD,eAAO,MAAM,sBAAsB,EAAG,kBAA2B,CAAC;AAElE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,kBAAkB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAOD,wBAAgB,mBAAmB,IAAI,YAAY,CAElD;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,cAAc,GAAG,SAAS,GAChC,IAAI,CAON;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EAClD,KAAK,CAAC,EAAE,cAAc,GACrB,IAAI,CAgBN;AAoBD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,MAAmB,GAC7B,IAAI,CAON;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAE1E;AAiBD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAO1E;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,IAAI,CAOnE;AAkCD;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa;;;;;kBAwDa,MAAM;eAAS,MAAM;;;GAoB1D,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;;;kBAYM,MAAM;kBAAY,MAAM;;;GAMvD,CAAC"}
@@ -5,6 +5,20 @@ export declare function isBlockedExtensionUrl(url: string): boolean;
5
5
  * "public hostname resolves to a private address" gap before dispatch.
6
6
  */
7
7
  export declare function isBlockedExtensionUrlWithDns(url: string): Promise<boolean>;
8
+ /**
9
+ * Origins the deployment itself declares as its own surfaces. These come from
10
+ * operator-controlled configuration (env), NOT from user/agent input, so a
11
+ * fetch to them is a self-call, not an SSRF: cross-app A2A on a workspace
12
+ * (call-agent) targets sibling apps at the deployment's own base URL, and in
13
+ * local dev / self-hosted private networks that origin is a loopback or
14
+ * RFC-1918 address the private-address guard would otherwise block — which
15
+ * broke every workspace-internal agent call on `wrangler pages dev` and the
16
+ * dev gateway. Only EXACT origin matches (scheme + host + port) are trusted;
17
+ * everything else keeps the full SSRF policy (including redirect hops).
18
+ */
19
+ export declare function trustedInternalOrigins(): Set<string>;
20
+ /** True when `url`'s origin exactly matches a configured internal origin. */
21
+ export declare function isTrustedInternalUrl(url: string): boolean;
8
22
  /**
9
23
  * Build an undici Dispatcher whose connect-time DNS lookup runs through a
10
24
  * private-IP guard. This closes the TOCTOU gap where:
@@ -1 +1 @@
1
- {"version":3,"file":"url-safety.d.ts","sourceRoot":"","sources":["../../src/extensions/url-safety.ts"],"names":[],"mappings":"AA4FA,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAoB1D;AASD;;;;GAIG;AACH,wBAAsB,4BAA4B,CAChD,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,OAAO,CAAC,CAoBlB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAmExE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,WAAgB,EACtB,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3D,OAAO,CAAC,QAAQ,CAAC,CAqCnB;AAQD,OAAO,EAAE,qBAAqB,IAAI,gBAAgB,EAAE,CAAC;AACrD,OAAO,EAAE,4BAA4B,IAAI,uBAAuB,EAAE,CAAC;AACnE,OAAO,EAAE,aAAa,IAAI,iBAAiB,EAAE,CAAC"}
1
+ {"version":3,"file":"url-safety.d.ts","sourceRoot":"","sources":["../../src/extensions/url-safety.ts"],"names":[],"mappings":"AA4FA,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAoB1D;AASD;;;;GAIG;AACH,wBAAsB,4BAA4B,CAChD,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,OAAO,CAAC,CAoBlB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,IAAI,GAAG,CAAC,MAAM,CAAC,CA2BpD;AAED,6EAA6E;AAC7E,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAMzD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAmExE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,IAAI,GAAE,WAAgB,EACtB,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3D,OAAO,CAAC,QAAQ,CAAC,CA6CnB;AAQD,OAAO,EAAE,qBAAqB,IAAI,gBAAgB,EAAE,CAAC;AACrD,OAAO,EAAE,4BAA4B,IAAI,uBAAuB,EAAE,CAAC;AACnE,OAAO,EAAE,aAAa,IAAI,iBAAiB,EAAE,CAAC"}
@@ -157,6 +157,58 @@ export async function isBlockedExtensionUrlWithDns(url) {
157
157
  return false;
158
158
  }
159
159
  }
160
+ /**
161
+ * Origins the deployment itself declares as its own surfaces. These come from
162
+ * operator-controlled configuration (env), NOT from user/agent input, so a
163
+ * fetch to them is a self-call, not an SSRF: cross-app A2A on a workspace
164
+ * (call-agent) targets sibling apps at the deployment's own base URL, and in
165
+ * local dev / self-hosted private networks that origin is a loopback or
166
+ * RFC-1918 address the private-address guard would otherwise block — which
167
+ * broke every workspace-internal agent call on `wrangler pages dev` and the
168
+ * dev gateway. Only EXACT origin matches (scheme + host + port) are trusted;
169
+ * everything else keeps the full SSRF policy (including redirect hops).
170
+ */
171
+ export function trustedInternalOrigins() {
172
+ const origins = new Set();
173
+ const addUrl = (value) => {
174
+ if (typeof value !== "string" || !value.trim())
175
+ return;
176
+ try {
177
+ origins.add(new URL(value).origin);
178
+ }
179
+ catch {
180
+ // Ignore malformed configured URLs — they never matched anything.
181
+ }
182
+ };
183
+ const env = globalThis?.process?.env ?? {};
184
+ addUrl(env.APP_URL);
185
+ addUrl(env.BETTER_AUTH_URL);
186
+ addUrl(env.WEBHOOK_BASE_URL);
187
+ addUrl(env.WORKSPACE_GATEWAY_URL);
188
+ const manifestJson = env.AGENT_NATIVE_WORKSPACE_APPS_JSON;
189
+ if (typeof manifestJson === "string" && manifestJson.trim()) {
190
+ try {
191
+ const apps = JSON.parse(manifestJson);
192
+ if (Array.isArray(apps)) {
193
+ for (const app of apps)
194
+ addUrl(app?.url);
195
+ }
196
+ }
197
+ catch {
198
+ // Malformed manifest — no trusted origins from it.
199
+ }
200
+ }
201
+ return origins;
202
+ }
203
+ /** True when `url`'s origin exactly matches a configured internal origin. */
204
+ export function isTrustedInternalUrl(url) {
205
+ try {
206
+ return trustedInternalOrigins().has(new URL(url).origin);
207
+ }
208
+ catch {
209
+ return false;
210
+ }
211
+ }
160
212
  /**
161
213
  * Build an undici Dispatcher whose connect-time DNS lookup runs through a
162
214
  * private-IP guard. This closes the TOCTOU gap where:
@@ -250,14 +302,22 @@ export async function ssrfSafeFetch(url, init = {}, options = {}) {
250
302
  if (options.httpsOnly && new URL(currentUrl).protocol !== "https:") {
251
303
  throw new Error(`SSRF blocked: refusing to fetch non-HTTPS address (${currentUrl})`);
252
304
  }
253
- if (await isBlockedExtensionUrlWithDns(currentUrl)) {
305
+ // The deployment's own configured origins are self-calls (workspace A2A,
306
+ // self-dispatch), not attacker-controlled targets — skip only the
307
+ // private-address block for exact origin matches. Each redirect hop is
308
+ // still re-validated, so a trusted origin cannot 30x into the private
309
+ // network.
310
+ const trustedHop = isTrustedInternalUrl(currentUrl);
311
+ if (!trustedHop && (await isBlockedExtensionUrlWithDns(currentUrl))) {
254
312
  throw new Error(`SSRF blocked: refusing to fetch private/internal address (${currentUrl})`);
255
313
  }
256
314
  const fetchOpts = {
257
315
  ...init,
258
316
  redirect: "manual",
259
317
  };
260
- if (dispatcher)
318
+ // The connect-time guard would also reject a trusted internal origin's
319
+ // loopback/private IP at the TCP layer — attach it only to untrusted hops.
320
+ if (dispatcher && !trustedHop)
261
321
  fetchOpts.dispatcher = dispatcher;
262
322
  const response = await fetch(currentUrl, fetchOpts);
263
323
  if (response.status >= 300 && response.status < 400) {
@@ -1 +1 @@
1
- {"version":3,"file":"url-safety.js","sourceRoot":"","sources":["../../src/extensions/url-safety.ts"],"names":[],"mappings":"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","sourcesContent":["const METADATA_HOSTS = [\r\n \"metadata.google.internal\",\r\n \"metadata.google.internal.\",\r\n];\r\n\r\nconst DNS_REBIND_SUFFIXES = [\r\n \".nip.io\",\r\n \".sslip.io\",\r\n \".xip.io\",\r\n \".localtest.me\",\r\n \".lvh.me\",\r\n];\r\n\r\nfunction isPrivateIpv4(a: number, b: number, c = 0, d = 0): boolean {\r\n if (![a, b, c, d].every((part) => part >= 0 && part <= 255)) return true;\r\n if (a === 127) return true;\r\n if (a === 10) return true;\r\n if (a === 172 && b >= 16 && b <= 31) return true;\r\n if (a === 192 && b === 168) return true;\r\n if (a === 169 && b === 254) return true;\r\n if (a === 0) return true;\r\n if (a === 100 && b >= 64 && b <= 127) return true;\r\n if (a === 192 && b === 0) return true;\r\n if (a === 198 && (b === 18 || b === 19)) return true;\r\n if (a === 192 && b === 0 && c === 2) return true;\r\n if (a === 198 && b === 51 && c === 100) return true;\r\n if (a === 203 && b === 0 && c === 113) return true;\r\n if (a >= 224) return true;\r\n return false;\r\n}\r\n\r\nfunction isPrivateIpv4MappedHex(host: string): boolean {\r\n const mapped = host.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i);\r\n if (!mapped) return false;\r\n const high = Number.parseInt(mapped[1], 16);\r\n const low = Number.parseInt(mapped[2], 16);\r\n if (high < 0 || high > 0xffff || low < 0 || low > 0xffff) return false;\r\n const a = (high >> 8) & 0xff;\r\n const b = high & 0xff;\r\n const c = (low >> 8) & 0xff;\r\n const d = low & 0xff;\r\n return isPrivateIpv4(a, b, c, d);\r\n}\r\n\r\nfunction isPrivateHost(hostname: string): boolean {\r\n const host = hostname.toLowerCase().replace(/^\\[|\\]$/g, \"\");\r\n if (\r\n host === \"localhost\" ||\r\n host === \"::1\" ||\r\n host === \"::0\" ||\r\n host === \"::\"\r\n ) {\r\n return true;\r\n }\r\n if (METADATA_HOSTS.includes(host)) return true;\r\n\r\n // IPv6 ULA/link-local/multicast.\r\n if (/^f[cd]/.test(host) || /^fe[89ab]/.test(host)) return true;\r\n if (/^ff/i.test(host)) return true;\r\n\r\n // IPv4-mapped IPv6. URL parsing may preserve dotted form in some runtimes\r\n // or normalize it to hex, e.g. [::ffff:127.0.0.1] -> ::ffff:7f00:1.\r\n const v4mappedDotted = host.match(/^::ffff:(\\d+\\.\\d+\\.\\d+\\.\\d+)$/);\r\n if (v4mappedDotted) {\r\n const [a, b, c, d] = v4mappedDotted[1].split(\".\").map(Number);\r\n if (isPrivateIpv4(a, b, c, d)) return true;\r\n }\r\n if (isPrivateIpv4MappedHex(host)) return true;\r\n\r\n // Dotted IPv4. URL parsing normalizes shorthand/octal/hex IPv4 forms to\r\n // dotted decimal before we reach this point.\r\n const parts = host.split(\".\");\r\n if (parts.length === 4 && parts.every((p) => /^\\d+$/.test(p))) {\r\n const [a, b, c, d] = parts.map(Number);\r\n if (isPrivateIpv4(a, b, c, d)) return true;\r\n }\r\n\r\n // Decimal integer IPv4.\r\n if (/^\\d+$/.test(host)) {\r\n const num = Number(host);\r\n if (num >= 0 && num <= 0xffffffff) {\r\n const a = (num >>> 24) & 0xff;\r\n const b = (num >>> 16) & 0xff;\r\n const c = (num >>> 8) & 0xff;\r\n const d = num & 0xff;\r\n if (isPrivateIpv4(a, b, c, d)) return true;\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\nexport function isBlockedExtensionUrl(url: string): boolean {\r\n try {\r\n const parsed = new URL(url);\r\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\r\n return true;\r\n }\r\n const host = parsed.hostname.toLowerCase();\r\n if (isPrivateHost(host)) return true;\r\n if (\r\n DNS_REBIND_SUFFIXES.some((suffix) => {\r\n const bare = suffix.slice(1);\r\n return host === bare || host.endsWith(suffix);\r\n })\r\n ) {\r\n return true;\r\n }\r\n } catch {\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\nfunction isIpLiteralHost(hostname: string): boolean {\r\n const host = hostname.toLowerCase().replace(/^\\[|\\]$/g, \"\");\r\n if (host.includes(\":\")) return true;\r\n const parts = host.split(\".\");\r\n return parts.length === 4 && parts.every((p) => /^\\d+$/.test(p));\r\n}\r\n\r\n/**\r\n * Async SSRF guard for environments that can resolve DNS. The synchronous\r\n * guard catches literals and known rebinding domains; this closes the common\r\n * \"public hostname resolves to a private address\" gap before dispatch.\r\n */\r\nexport async function isBlockedExtensionUrlWithDns(\r\n url: string,\r\n): Promise<boolean> {\r\n if (isBlockedExtensionUrl(url)) return true;\r\n\r\n let hostname: string;\r\n try {\r\n hostname = new URL(url).hostname.toLowerCase();\r\n } catch {\r\n return true;\r\n }\r\n if (!hostname || isIpLiteralHost(hostname)) return false;\r\n\r\n try {\r\n const { lookup } = await import(\"node:dns/promises\");\r\n const records = await lookup(hostname, { all: true, verbatim: true });\r\n return records.some((record) => isPrivateHost(record.address));\r\n } catch {\r\n // Some edge runtimes do not expose DNS lookup. Keep the deterministic\r\n // parser-based protections instead of failing every outbound request.\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Build an undici Dispatcher whose connect-time DNS lookup runs through a\r\n * private-IP guard. This closes the TOCTOU gap where:\r\n * 1. We resolve hostname → public IP and pass.\r\n * 2. Between that lookup and the actual connect, DNS rebinding flips the\r\n * record to a private IP.\r\n * 3. fetch() resolves again and connects to the private IP.\r\n *\r\n * With a custom dispatcher, the same lookup that produces the IP also gates\r\n * the connect: if the IP is in the private set, the connect throws.\r\n *\r\n * Returns `null` if undici / node:dns are not available (e.g. some edge\r\n * runtimes); the caller should fall back to the regular `fetch` path —\r\n * `isBlockedExtensionUrlWithDns` will still have caught most rebinding cases.\r\n */\r\nexport async function createSsrfSafeDispatcher(): Promise<unknown | null> {\r\n // Keep the optional undici import opaque to Vite/Rolldown. A static\r\n // `import(\"undici\")` makes browser builds try to resolve and bundle undici\r\n // even though this dispatcher is only useful in Node server runtimes.\r\n let undici: any;\r\n let dnsModule: any;\r\n try {\r\n const runtimeImport = new Function(\r\n \"specifier\",\r\n \"return import(specifier)\",\r\n ) as (specifier: string) => Promise<any>;\r\n undici = await runtimeImport(\"undici\");\r\n dnsModule = await import(\"node:dns\");\r\n } catch {\r\n return null;\r\n }\r\n\r\n const { Agent } = undici;\r\n const { lookup } = dnsModule;\r\n if (!Agent || !lookup) return null;\r\n\r\n return new Agent({\r\n connect: {\r\n // Override DNS lookup at connect time so the IP we hand to undici's\r\n // socket is the one we authorized. Reject any record in the private\r\n // set BEFORE the TCP handshake.\r\n lookup: (\r\n hostname: string,\r\n options: any,\r\n callback: (\r\n err: NodeJS.ErrnoException | null,\r\n address?: string | { address: string; family: number }[],\r\n family?: number,\r\n ) => void,\r\n ) => {\r\n lookup(\r\n hostname,\r\n { all: true, verbatim: true },\r\n (err: NodeJS.ErrnoException | null, addresses: any) => {\r\n if (err) return callback(err);\r\n const list: { address: string; family: number }[] = Array.isArray(\r\n addresses,\r\n )\r\n ? addresses\r\n : [{ address: addresses, family: 4 }];\r\n for (const record of list) {\r\n if (isPrivateHost(record.address)) {\r\n const e = new Error(\r\n `Connect blocked: ${hostname} resolved to private address ${record.address}`,\r\n ) as NodeJS.ErrnoException;\r\n e.code = \"EAI_BLOCKED\";\r\n return callback(e);\r\n }\r\n }\r\n // Mirror Node's lookup behavior: when `all` is true, return the\r\n // array; otherwise the first entry. undici's connect honors\r\n // `options.all`.\r\n if (options && options.all) {\r\n return callback(null, list as any);\r\n }\r\n const first = list[0];\r\n return callback(null, first.address, first.family);\r\n },\r\n );\r\n },\r\n },\r\n });\r\n}\r\n\r\n/**\r\n * SSRF-safe `fetch` for any server-side request to a user/agent-supplied URL.\r\n *\r\n * Applies the same protections the extension proxy uses, so every call site\r\n * that fetches an untrusted URL gets them without re-implementing the loop:\r\n * 1. Pre-flight DNS-aware private-address check (isBlockedExtensionUrlWithDns)\r\n * on the initial URL and on every redirect hop.\r\n * 2. A connect-time dispatcher that re-checks the resolved IP at TCP-connect\r\n * time (closes the DNS-rebinding TOCTOU) when undici is available.\r\n * 3. Manual redirect handling — a public URL cannot 30x-redirect into the\r\n * private network because each hop is re-validated before it is followed.\r\n *\r\n * Throws an Error whose message starts with \"SSRF blocked:\" when a target\r\n * (initial or via redirect) resolves to a private/internal address, or when the\r\n * redirect limit is exceeded. Otherwise returns the final Response.\r\n *\r\n * `httpsOnly` extends the per-hop validation to the URL scheme: redirects are\r\n * followed only to `https:` targets, so an HTTPS-only caller cannot be\r\n * downgraded to plain HTTP by a 30x from the (untrusted) origin.\r\n */\r\nexport async function ssrfSafeFetch(\r\n url: string,\r\n init: RequestInit = {},\r\n options: { maxRedirects?: number; httpsOnly?: boolean } = {},\r\n): Promise<Response> {\r\n const maxRedirects = options.maxRedirects ?? 3;\r\n const dispatcher = (await createSsrfSafeDispatcher()) ?? undefined;\r\n\r\n let currentUrl = url;\r\n for (let hop = 0; hop <= maxRedirects; hop++) {\r\n if (options.httpsOnly && new URL(currentUrl).protocol !== \"https:\") {\r\n throw new Error(\r\n `SSRF blocked: refusing to fetch non-HTTPS address (${currentUrl})`,\r\n );\r\n }\r\n if (await isBlockedExtensionUrlWithDns(currentUrl)) {\r\n throw new Error(\r\n `SSRF blocked: refusing to fetch private/internal address (${currentUrl})`,\r\n );\r\n }\r\n const fetchOpts: RequestInit & { dispatcher?: unknown } = {\r\n ...init,\r\n redirect: \"manual\",\r\n };\r\n if (dispatcher) fetchOpts.dispatcher = dispatcher;\r\n\r\n const response = await fetch(currentUrl, fetchOpts);\r\n if (response.status >= 300 && response.status < 400) {\r\n const location = response.headers.get(\"location\");\r\n if (!location) return response;\r\n // Drain the redirect body so the hop's connection is released instead\r\n // of being held until GC.\r\n await response.body?.cancel().catch(() => {});\r\n currentUrl = new URL(location, currentUrl).href;\r\n continue;\r\n }\r\n return response;\r\n }\r\n throw new Error(\r\n `SSRF blocked: too many redirects (>${maxRedirects}) while fetching ${url}`,\r\n );\r\n}\r\n\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n// Legacy aliases — predate the Tools → Extensions rename. Templates import\r\n// these via the legacy `@agent-native/core/tools/url-safety` subpath; keep\r\n// the names exported so they keep resolving until every consumer updates.\r\n// ─────────────────────────────────────────────────────────────────────────────\r\n\r\nexport { isBlockedExtensionUrl as isBlockedToolUrl };\r\nexport { isBlockedExtensionUrlWithDns as isBlockedToolUrlWithDns };\r\nexport { ssrfSafeFetch as ssrfSafeToolFetch };\r\n"]}
1
+ {"version":3,"file":"url-safety.js","sourceRoot":"","sources":["../../src/extensions/url-safety.ts"],"names":[],"mappings":"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","sourcesContent":["const METADATA_HOSTS = [\n \"metadata.google.internal\",\n \"metadata.google.internal.\",\n];\n\nconst DNS_REBIND_SUFFIXES = [\n \".nip.io\",\n \".sslip.io\",\n \".xip.io\",\n \".localtest.me\",\n \".lvh.me\",\n];\n\nfunction isPrivateIpv4(a: number, b: number, c = 0, d = 0): boolean {\n if (![a, b, c, d].every((part) => part >= 0 && part <= 255)) return true;\n if (a === 127) return true;\n if (a === 10) return true;\n if (a === 172 && b >= 16 && b <= 31) return true;\n if (a === 192 && b === 168) return true;\n if (a === 169 && b === 254) return true;\n if (a === 0) return true;\n if (a === 100 && b >= 64 && b <= 127) return true;\n if (a === 192 && b === 0) return true;\n if (a === 198 && (b === 18 || b === 19)) return true;\n if (a === 192 && b === 0 && c === 2) return true;\n if (a === 198 && b === 51 && c === 100) return true;\n if (a === 203 && b === 0 && c === 113) return true;\n if (a >= 224) return true;\n return false;\n}\n\nfunction isPrivateIpv4MappedHex(host: string): boolean {\n const mapped = host.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i);\n if (!mapped) return false;\n const high = Number.parseInt(mapped[1], 16);\n const low = Number.parseInt(mapped[2], 16);\n if (high < 0 || high > 0xffff || low < 0 || low > 0xffff) return false;\n const a = (high >> 8) & 0xff;\n const b = high & 0xff;\n const c = (low >> 8) & 0xff;\n const d = low & 0xff;\n return isPrivateIpv4(a, b, c, d);\n}\n\nfunction isPrivateHost(hostname: string): boolean {\n const host = hostname.toLowerCase().replace(/^\\[|\\]$/g, \"\");\n if (\n host === \"localhost\" ||\n host === \"::1\" ||\n host === \"::0\" ||\n host === \"::\"\n ) {\n return true;\n }\n if (METADATA_HOSTS.includes(host)) return true;\n\n // IPv6 ULA/link-local/multicast.\n if (/^f[cd]/.test(host) || /^fe[89ab]/.test(host)) return true;\n if (/^ff/i.test(host)) return true;\n\n // IPv4-mapped IPv6. URL parsing may preserve dotted form in some runtimes\n // or normalize it to hex, e.g. [::ffff:127.0.0.1] -> ::ffff:7f00:1.\n const v4mappedDotted = host.match(/^::ffff:(\\d+\\.\\d+\\.\\d+\\.\\d+)$/);\n if (v4mappedDotted) {\n const [a, b, c, d] = v4mappedDotted[1].split(\".\").map(Number);\n if (isPrivateIpv4(a, b, c, d)) return true;\n }\n if (isPrivateIpv4MappedHex(host)) return true;\n\n // Dotted IPv4. URL parsing normalizes shorthand/octal/hex IPv4 forms to\n // dotted decimal before we reach this point.\n const parts = host.split(\".\");\n if (parts.length === 4 && parts.every((p) => /^\\d+$/.test(p))) {\n const [a, b, c, d] = parts.map(Number);\n if (isPrivateIpv4(a, b, c, d)) return true;\n }\n\n // Decimal integer IPv4.\n if (/^\\d+$/.test(host)) {\n const num = Number(host);\n if (num >= 0 && num <= 0xffffffff) {\n const a = (num >>> 24) & 0xff;\n const b = (num >>> 16) & 0xff;\n const c = (num >>> 8) & 0xff;\n const d = num & 0xff;\n if (isPrivateIpv4(a, b, c, d)) return true;\n }\n }\n\n return false;\n}\n\nexport function isBlockedExtensionUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n return true;\n }\n const host = parsed.hostname.toLowerCase();\n if (isPrivateHost(host)) return true;\n if (\n DNS_REBIND_SUFFIXES.some((suffix) => {\n const bare = suffix.slice(1);\n return host === bare || host.endsWith(suffix);\n })\n ) {\n return true;\n }\n } catch {\n return true;\n }\n return false;\n}\n\nfunction isIpLiteralHost(hostname: string): boolean {\n const host = hostname.toLowerCase().replace(/^\\[|\\]$/g, \"\");\n if (host.includes(\":\")) return true;\n const parts = host.split(\".\");\n return parts.length === 4 && parts.every((p) => /^\\d+$/.test(p));\n}\n\n/**\n * Async SSRF guard for environments that can resolve DNS. The synchronous\n * guard catches literals and known rebinding domains; this closes the common\n * \"public hostname resolves to a private address\" gap before dispatch.\n */\nexport async function isBlockedExtensionUrlWithDns(\n url: string,\n): Promise<boolean> {\n if (isBlockedExtensionUrl(url)) return true;\n\n let hostname: string;\n try {\n hostname = new URL(url).hostname.toLowerCase();\n } catch {\n return true;\n }\n if (!hostname || isIpLiteralHost(hostname)) return false;\n\n try {\n const { lookup } = await import(\"node:dns/promises\");\n const records = await lookup(hostname, { all: true, verbatim: true });\n return records.some((record) => isPrivateHost(record.address));\n } catch {\n // Some edge runtimes do not expose DNS lookup. Keep the deterministic\n // parser-based protections instead of failing every outbound request.\n return false;\n }\n}\n\n/**\n * Origins the deployment itself declares as its own surfaces. These come from\n * operator-controlled configuration (env), NOT from user/agent input, so a\n * fetch to them is a self-call, not an SSRF: cross-app A2A on a workspace\n * (call-agent) targets sibling apps at the deployment's own base URL, and in\n * local dev / self-hosted private networks that origin is a loopback or\n * RFC-1918 address the private-address guard would otherwise block — which\n * broke every workspace-internal agent call on `wrangler pages dev` and the\n * dev gateway. Only EXACT origin matches (scheme + host + port) are trusted;\n * everything else keeps the full SSRF policy (including redirect hops).\n */\nexport function trustedInternalOrigins(): Set<string> {\n const origins = new Set<string>();\n const addUrl = (value: unknown) => {\n if (typeof value !== \"string\" || !value.trim()) return;\n try {\n origins.add(new URL(value).origin);\n } catch {\n // Ignore malformed configured URLs — they never matched anything.\n }\n };\n const env = (globalThis as any)?.process?.env ?? {};\n addUrl(env.APP_URL);\n addUrl(env.BETTER_AUTH_URL);\n addUrl(env.WEBHOOK_BASE_URL);\n addUrl(env.WORKSPACE_GATEWAY_URL);\n const manifestJson = env.AGENT_NATIVE_WORKSPACE_APPS_JSON;\n if (typeof manifestJson === \"string\" && manifestJson.trim()) {\n try {\n const apps = JSON.parse(manifestJson);\n if (Array.isArray(apps)) {\n for (const app of apps) addUrl(app?.url);\n }\n } catch {\n // Malformed manifest — no trusted origins from it.\n }\n }\n return origins;\n}\n\n/** True when `url`'s origin exactly matches a configured internal origin. */\nexport function isTrustedInternalUrl(url: string): boolean {\n try {\n return trustedInternalOrigins().has(new URL(url).origin);\n } catch {\n return false;\n }\n}\n\n/**\n * Build an undici Dispatcher whose connect-time DNS lookup runs through a\n * private-IP guard. This closes the TOCTOU gap where:\n * 1. We resolve hostname → public IP and pass.\n * 2. Between that lookup and the actual connect, DNS rebinding flips the\n * record to a private IP.\n * 3. fetch() resolves again and connects to the private IP.\n *\n * With a custom dispatcher, the same lookup that produces the IP also gates\n * the connect: if the IP is in the private set, the connect throws.\n *\n * Returns `null` if undici / node:dns are not available (e.g. some edge\n * runtimes); the caller should fall back to the regular `fetch` path —\n * `isBlockedExtensionUrlWithDns` will still have caught most rebinding cases.\n */\nexport async function createSsrfSafeDispatcher(): Promise<unknown | null> {\n // Keep the optional undici import opaque to Vite/Rolldown. A static\n // `import(\"undici\")` makes browser builds try to resolve and bundle undici\n // even though this dispatcher is only useful in Node server runtimes.\n let undici: any;\n let dnsModule: any;\n try {\n const runtimeImport = new Function(\n \"specifier\",\n \"return import(specifier)\",\n ) as (specifier: string) => Promise<any>;\n undici = await runtimeImport(\"undici\");\n dnsModule = await import(\"node:dns\");\n } catch {\n return null;\n }\n\n const { Agent } = undici;\n const { lookup } = dnsModule;\n if (!Agent || !lookup) return null;\n\n return new Agent({\n connect: {\n // Override DNS lookup at connect time so the IP we hand to undici's\n // socket is the one we authorized. Reject any record in the private\n // set BEFORE the TCP handshake.\n lookup: (\n hostname: string,\n options: any,\n callback: (\n err: NodeJS.ErrnoException | null,\n address?: string | { address: string; family: number }[],\n family?: number,\n ) => void,\n ) => {\n lookup(\n hostname,\n { all: true, verbatim: true },\n (err: NodeJS.ErrnoException | null, addresses: any) => {\n if (err) return callback(err);\n const list: { address: string; family: number }[] = Array.isArray(\n addresses,\n )\n ? addresses\n : [{ address: addresses, family: 4 }];\n for (const record of list) {\n if (isPrivateHost(record.address)) {\n const e = new Error(\n `Connect blocked: ${hostname} resolved to private address ${record.address}`,\n ) as NodeJS.ErrnoException;\n e.code = \"EAI_BLOCKED\";\n return callback(e);\n }\n }\n // Mirror Node's lookup behavior: when `all` is true, return the\n // array; otherwise the first entry. undici's connect honors\n // `options.all`.\n if (options && options.all) {\n return callback(null, list as any);\n }\n const first = list[0];\n return callback(null, first.address, first.family);\n },\n );\n },\n },\n });\n}\n\n/**\n * SSRF-safe `fetch` for any server-side request to a user/agent-supplied URL.\n *\n * Applies the same protections the extension proxy uses, so every call site\n * that fetches an untrusted URL gets them without re-implementing the loop:\n * 1. Pre-flight DNS-aware private-address check (isBlockedExtensionUrlWithDns)\n * on the initial URL and on every redirect hop.\n * 2. A connect-time dispatcher that re-checks the resolved IP at TCP-connect\n * time (closes the DNS-rebinding TOCTOU) when undici is available.\n * 3. Manual redirect handling — a public URL cannot 30x-redirect into the\n * private network because each hop is re-validated before it is followed.\n *\n * Throws an Error whose message starts with \"SSRF blocked:\" when a target\n * (initial or via redirect) resolves to a private/internal address, or when the\n * redirect limit is exceeded. Otherwise returns the final Response.\n *\n * `httpsOnly` extends the per-hop validation to the URL scheme: redirects are\n * followed only to `https:` targets, so an HTTPS-only caller cannot be\n * downgraded to plain HTTP by a 30x from the (untrusted) origin.\n */\nexport async function ssrfSafeFetch(\n url: string,\n init: RequestInit = {},\n options: { maxRedirects?: number; httpsOnly?: boolean } = {},\n): Promise<Response> {\n const maxRedirects = options.maxRedirects ?? 3;\n const dispatcher = (await createSsrfSafeDispatcher()) ?? undefined;\n\n let currentUrl = url;\n for (let hop = 0; hop <= maxRedirects; hop++) {\n if (options.httpsOnly && new URL(currentUrl).protocol !== \"https:\") {\n throw new Error(\n `SSRF blocked: refusing to fetch non-HTTPS address (${currentUrl})`,\n );\n }\n // The deployment's own configured origins are self-calls (workspace A2A,\n // self-dispatch), not attacker-controlled targets — skip only the\n // private-address block for exact origin matches. Each redirect hop is\n // still re-validated, so a trusted origin cannot 30x into the private\n // network.\n const trustedHop = isTrustedInternalUrl(currentUrl);\n if (!trustedHop && (await isBlockedExtensionUrlWithDns(currentUrl))) {\n throw new Error(\n `SSRF blocked: refusing to fetch private/internal address (${currentUrl})`,\n );\n }\n const fetchOpts: RequestInit & { dispatcher?: unknown } = {\n ...init,\n redirect: \"manual\",\n };\n // The connect-time guard would also reject a trusted internal origin's\n // loopback/private IP at the TCP layer — attach it only to untrusted hops.\n if (dispatcher && !trustedHop) fetchOpts.dispatcher = dispatcher;\n\n const response = await fetch(currentUrl, fetchOpts);\n if (response.status >= 300 && response.status < 400) {\n const location = response.headers.get(\"location\");\n if (!location) return response;\n // Drain the redirect body so the hop's connection is released instead\n // of being held until GC.\n await response.body?.cancel().catch(() => {});\n currentUrl = new URL(location, currentUrl).href;\n continue;\n }\n return response;\n }\n throw new Error(\n `SSRF blocked: too many redirects (>${maxRedirects}) while fetching ${url}`,\n );\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Legacy aliases — predate the Tools → Extensions rename. Templates import\n// these via the legacy `@agent-native/core/tools/url-safety` subpath; keep\n// the names exported so they keep resolving until every consumer updates.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport { isBlockedExtensionUrl as isBlockedToolUrl };\nexport { isBlockedExtensionUrlWithDns as isBlockedToolUrlWithDns };\nexport { ssrfSafeFetch as ssrfSafeToolFetch };\n"]}
@@ -17,12 +17,12 @@ declare const _default: import("../../action.js").ActionDefinition<{
17
17
  id?: undefined;
18
18
  provider?: undefined;
19
19
  } | {
20
- error?: undefined;
21
20
  configured?: undefined;
22
21
  connectPath?: undefined;
23
22
  url: string;
24
23
  id: string;
25
24
  provider: string;
25
+ error?: undefined;
26
26
  }>;
27
27
  export default _default;
28
28
  //# sourceMappingURL=upload-image.d.ts.map
@@ -41,16 +41,16 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
41
41
  thumbsUpRate: number;
42
42
  avgEvalScore: number;
43
43
  } | {
44
- error?: undefined;
45
44
  summary: import("./types.js").TraceSummary;
46
45
  spans: import("./types.js").TraceSpan[];
47
46
  id?: undefined;
47
+ error?: undefined;
48
48
  ok?: undefined;
49
49
  } | {
50
- error?: undefined;
51
50
  summary?: undefined;
52
51
  spans?: undefined;
53
52
  id: string;
53
+ error?: undefined;
54
54
  ok?: undefined;
55
55
  } | {
56
56
  summary?: undefined;
@@ -59,10 +59,10 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
59
59
  error: any;
60
60
  ok?: undefined;
61
61
  } | {
62
- error?: undefined;
63
62
  summary?: undefined;
64
63
  spans?: undefined;
65
64
  id?: undefined;
65
+ error?: undefined;
66
66
  ok: boolean;
67
67
  }>>;
68
68
  //# sourceMappingURL=routes.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import type { TraceSpan, TraceSummary, FeedbackEntry, SatisfactionScore, EvalResult, EvalDataset, Experiment, ExperimentAssignment, ExperimentMetricResult } from "./types.js";
2
- export declare function ensureObservabilityTables(): Promise<void>;
2
+ export declare const ensureObservabilityTables: () => Promise<void>;
3
3
  export declare function insertTraceSpan(span: TraceSpan): Promise<void>;
4
4
  export declare function upsertTraceSummary(summary: TraceSummary): Promise<void>;
5
5
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/observability/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/observability/store.ts"],"names":[],"mappings":"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"}