@anuma/sdk 3.6.2 → 3.7.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.
Files changed (27) hide show
  1. package/dist/expo/{chunk-7TATXBC5.mjs → chunk-AAB7OG7Q.mjs} +810 -4
  2. package/dist/{react/chunk-DFVCS3QQ.mjs → expo/chunk-BOY27A2C.mjs} +30 -3
  3. package/dist/expo/{consolidate-3QQPUWD6.mjs → consolidate-J5PHQKKY.mjs} +1 -1
  4. package/dist/expo/index.cjs +931 -825
  5. package/dist/expo/index.d.mts +9 -0
  6. package/dist/expo/index.d.ts +9 -0
  7. package/dist/expo/index.mjs +14 -817
  8. package/dist/{react/recall-OPKHWKZX.mjs → expo/recall-YVU7OSSJ.mjs} +2 -2
  9. package/dist/react/{chunk-DDHTJGZN.mjs → chunk-3VPEZDYL.mjs} +896 -4
  10. package/dist/{expo/chunk-DFVCS3QQ.mjs → react/chunk-BOY27A2C.mjs} +30 -3
  11. package/dist/react/{consolidate-3MXZV3G7.mjs → consolidate-PWJCAPZA.mjs} +1 -1
  12. package/dist/react/index.cjs +2021 -1907
  13. package/dist/react/index.d.mts +9 -0
  14. package/dist/react/index.d.ts +9 -0
  15. package/dist/react/index.mjs +29 -888
  16. package/dist/{expo/recall-IO4KJ5W7.mjs → react/recall-Z7BWJ67X.mjs} +2 -2
  17. package/dist/server/{chunk-V7SVKIXQ.mjs → chunk-LSKFJNLF.mjs} +795 -4
  18. package/dist/server/{chunk-AHJT66EO.mjs → chunk-MIXEASUP.mjs} +30 -3
  19. package/dist/server/{consolidate-CN2GQV4D.mjs → consolidate-PCHO3D3G.mjs} +1 -1
  20. package/dist/server/index.cjs +925 -163
  21. package/dist/server/index.d.mts +36 -0
  22. package/dist/server/index.d.ts +36 -0
  23. package/dist/server/index.mjs +9 -147
  24. package/dist/server/{recall-IWY2MYHR.mjs → recall-XEOLXA6P.mjs} +2 -2
  25. package/dist/tools/selection/index.cjs +793 -3
  26. package/dist/tools/selection/index.mjs +791 -3
  27. package/package.json +2 -2
@@ -75,6 +75,138 @@ var init_clientConfig = __esm({
75
75
  }
76
76
  });
77
77
 
78
+ // src/client/core/serverSentEvents.gen.ts
79
+ function createSseClient({
80
+ onRequest,
81
+ onSseError,
82
+ onSseEvent,
83
+ responseTransformer,
84
+ responseValidator,
85
+ sseDefaultRetryDelay,
86
+ sseMaxRetryAttempts,
87
+ sseMaxRetryDelay,
88
+ sseSleepFn,
89
+ url,
90
+ ...options
91
+ }) {
92
+ let lastEventId;
93
+ const sleep4 = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
94
+ const createStream = async function* () {
95
+ let retryDelay = sseDefaultRetryDelay ?? 3e3;
96
+ let attempt = 0;
97
+ const signal = options.signal ?? new AbortController().signal;
98
+ while (true) {
99
+ if (signal.aborted) break;
100
+ attempt++;
101
+ const headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers);
102
+ if (lastEventId !== void 0) {
103
+ headers.set("Last-Event-ID", lastEventId);
104
+ }
105
+ try {
106
+ const requestInit = {
107
+ redirect: "follow",
108
+ ...options,
109
+ body: options.serializedBody,
110
+ headers,
111
+ signal
112
+ };
113
+ let request = new Request(url, requestInit);
114
+ if (onRequest) {
115
+ request = await onRequest(url, requestInit);
116
+ }
117
+ const _fetch = options.fetch ?? globalThis.fetch;
118
+ const response = await _fetch(request);
119
+ if (!response.ok) throw new Error(`SSE failed: ${response.status} ${response.statusText}`);
120
+ if (!response.body) throw new Error("No body in SSE response");
121
+ const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
122
+ let buffer = "";
123
+ const abortHandler = () => {
124
+ try {
125
+ reader.cancel();
126
+ } catch {
127
+ }
128
+ };
129
+ signal.addEventListener("abort", abortHandler);
130
+ try {
131
+ while (true) {
132
+ const { done, value } = await reader.read();
133
+ if (done) break;
134
+ buffer += value;
135
+ buffer = buffer.replace(/\r\n?/g, "\n");
136
+ const chunks = buffer.split("\n\n");
137
+ buffer = chunks.pop() ?? "";
138
+ for (const chunk of chunks) {
139
+ const lines = chunk.split("\n");
140
+ const dataLines = [];
141
+ let eventName;
142
+ for (const line of lines) {
143
+ if (line.startsWith("data:")) {
144
+ dataLines.push(line.replace(/^data:\s*/, ""));
145
+ } else if (line.startsWith("event:")) {
146
+ eventName = line.replace(/^event:\s*/, "");
147
+ } else if (line.startsWith("id:")) {
148
+ lastEventId = line.replace(/^id:\s*/, "");
149
+ } else if (line.startsWith("retry:")) {
150
+ const parsed = Number.parseInt(line.replace(/^retry:\s*/, ""), 10);
151
+ if (!Number.isNaN(parsed)) {
152
+ retryDelay = parsed;
153
+ }
154
+ }
155
+ }
156
+ let data;
157
+ let parsedJson = false;
158
+ if (dataLines.length) {
159
+ const rawData = dataLines.join("\n");
160
+ try {
161
+ data = JSON.parse(rawData);
162
+ parsedJson = true;
163
+ } catch {
164
+ data = rawData;
165
+ }
166
+ }
167
+ if (parsedJson) {
168
+ if (responseValidator) {
169
+ await responseValidator(data);
170
+ }
171
+ if (responseTransformer) {
172
+ data = await responseTransformer(data);
173
+ }
174
+ }
175
+ onSseEvent?.({
176
+ data,
177
+ event: eventName,
178
+ id: lastEventId,
179
+ retry: retryDelay
180
+ });
181
+ if (dataLines.length) {
182
+ yield data;
183
+ }
184
+ }
185
+ }
186
+ } finally {
187
+ signal.removeEventListener("abort", abortHandler);
188
+ reader.releaseLock();
189
+ }
190
+ break;
191
+ } catch (error) {
192
+ onSseError?.(error);
193
+ if (sseMaxRetryAttempts !== void 0 && attempt >= sseMaxRetryAttempts) {
194
+ break;
195
+ }
196
+ const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 3e4);
197
+ await sleep4(backoff);
198
+ }
199
+ }
200
+ };
201
+ const stream = createStream();
202
+ return { stream };
203
+ }
204
+ var init_serverSentEvents_gen = __esm({
205
+ "src/client/core/serverSentEvents.gen.ts"() {
206
+ "use strict";
207
+ }
208
+ });
209
+
78
210
  // src/lib/logger.ts
79
211
  function setLogger(logger) {
80
212
  currentLogger = logger;
@@ -2208,561 +2340,1379 @@ var init_constants = __esm({
2208
2340
  }
2209
2341
  });
2210
2342
 
2211
- // src/lib/memoryEngine/generate.ts
2212
- async function withEmbeddingRetry(call) {
2213
- let last;
2214
- let lastThrown;
2215
- let threw = false;
2216
- for (let attempt = 1; attempt <= EMBED_MAX_ATTEMPTS; attempt++) {
2217
- try {
2218
- threw = false;
2219
- last = await call();
2220
- if (!last.error) return last;
2221
- const status = last.response?.status;
2222
- const retryable = status === void 0 || status === 429 || status >= 500;
2223
- if (!retryable) return last;
2224
- } catch (err) {
2225
- threw = true;
2226
- lastThrown = err;
2227
- }
2228
- if (attempt < EMBED_MAX_ATTEMPTS) {
2229
- const base = 250 * 2 ** (attempt - 1);
2230
- await new Promise((r) => setTimeout(r, base + Math.random() * 0.4 * base));
2343
+ // src/client/core/bodySerializer.gen.ts
2344
+ var jsonBodySerializer;
2345
+ var init_bodySerializer_gen = __esm({
2346
+ "src/client/core/bodySerializer.gen.ts"() {
2347
+ "use strict";
2348
+ jsonBodySerializer = {
2349
+ bodySerializer: (body) => JSON.stringify(body, (_key, value) => typeof value === "bigint" ? value.toString() : value)
2350
+ };
2351
+ }
2352
+ });
2353
+
2354
+ // src/client/core/pathSerializer.gen.ts
2355
+ var separatorArrayExplode, separatorArrayNoExplode, separatorObjectExplode, serializeArrayParam, serializePrimitiveParam, serializeObjectParam;
2356
+ var init_pathSerializer_gen = __esm({
2357
+ "src/client/core/pathSerializer.gen.ts"() {
2358
+ "use strict";
2359
+ separatorArrayExplode = (style) => {
2360
+ switch (style) {
2361
+ case "label":
2362
+ return ".";
2363
+ case "matrix":
2364
+ return ";";
2365
+ case "simple":
2366
+ return ",";
2367
+ default:
2368
+ return "&";
2369
+ }
2370
+ };
2371
+ separatorArrayNoExplode = (style) => {
2372
+ switch (style) {
2373
+ case "form":
2374
+ return ",";
2375
+ case "pipeDelimited":
2376
+ return "|";
2377
+ case "spaceDelimited":
2378
+ return "%20";
2379
+ default:
2380
+ return ",";
2381
+ }
2382
+ };
2383
+ separatorObjectExplode = (style) => {
2384
+ switch (style) {
2385
+ case "label":
2386
+ return ".";
2387
+ case "matrix":
2388
+ return ";";
2389
+ case "simple":
2390
+ return ",";
2391
+ default:
2392
+ return "&";
2393
+ }
2394
+ };
2395
+ serializeArrayParam = ({
2396
+ allowReserved,
2397
+ explode,
2398
+ name,
2399
+ style,
2400
+ value
2401
+ }) => {
2402
+ if (!explode) {
2403
+ const joinedValues2 = (allowReserved ? value : value.map((v) => encodeURIComponent(v))).join(separatorArrayNoExplode(style));
2404
+ switch (style) {
2405
+ case "label":
2406
+ return `.${joinedValues2}`;
2407
+ case "matrix":
2408
+ return `;${name}=${joinedValues2}`;
2409
+ case "simple":
2410
+ return joinedValues2;
2411
+ default:
2412
+ return `${name}=${joinedValues2}`;
2413
+ }
2414
+ }
2415
+ const separator = separatorArrayExplode(style);
2416
+ const joinedValues = value.map((v) => {
2417
+ if (style === "label" || style === "simple") {
2418
+ return allowReserved ? v : encodeURIComponent(v);
2419
+ }
2420
+ return serializePrimitiveParam({
2421
+ allowReserved,
2422
+ name,
2423
+ value: v
2424
+ });
2425
+ }).join(separator);
2426
+ return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
2427
+ };
2428
+ serializePrimitiveParam = ({
2429
+ allowReserved,
2430
+ name,
2431
+ value
2432
+ }) => {
2433
+ if (value === void 0 || value === null) {
2434
+ return "";
2435
+ }
2436
+ if (typeof value === "object") {
2437
+ throw new Error(
2438
+ "Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these."
2439
+ );
2440
+ }
2441
+ return `${name}=${allowReserved ? value : encodeURIComponent(value)}`;
2442
+ };
2443
+ serializeObjectParam = ({
2444
+ allowReserved,
2445
+ explode,
2446
+ name,
2447
+ style,
2448
+ value,
2449
+ valueOnly
2450
+ }) => {
2451
+ if (value instanceof Date) {
2452
+ return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`;
2453
+ }
2454
+ if (style !== "deepObject" && !explode) {
2455
+ let values = [];
2456
+ Object.entries(value).forEach(([key, v]) => {
2457
+ values = [...values, key, allowReserved ? v : encodeURIComponent(v)];
2458
+ });
2459
+ const joinedValues2 = values.join(",");
2460
+ switch (style) {
2461
+ case "form":
2462
+ return `${name}=${joinedValues2}`;
2463
+ case "label":
2464
+ return `.${joinedValues2}`;
2465
+ case "matrix":
2466
+ return `;${name}=${joinedValues2}`;
2467
+ default:
2468
+ return joinedValues2;
2469
+ }
2470
+ }
2471
+ const separator = separatorObjectExplode(style);
2472
+ const joinedValues = Object.entries(value).map(
2473
+ ([key, v]) => serializePrimitiveParam({
2474
+ allowReserved,
2475
+ name: style === "deepObject" ? `${name}[${key}]` : key,
2476
+ value: v
2477
+ })
2478
+ ).join(separator);
2479
+ return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
2480
+ };
2481
+ }
2482
+ });
2483
+
2484
+ // src/client/core/utils.gen.ts
2485
+ function getValidRequestBody(options) {
2486
+ const hasBody = options.body !== void 0;
2487
+ const isSerializedBody = hasBody && options.bodySerializer;
2488
+ if (isSerializedBody) {
2489
+ if ("serializedBody" in options) {
2490
+ const hasSerializedBody = options.serializedBody !== void 0 && options.serializedBody !== "";
2491
+ return hasSerializedBody ? options.serializedBody : null;
2231
2492
  }
2493
+ return options.body !== "" ? options.body : null;
2232
2494
  }
2233
- if (threw) throw lastThrown;
2234
- if (last?.error instanceof Error && last.response?.status === void 0) {
2235
- throw last.error;
2495
+ if (hasBody) {
2496
+ return options.body;
2236
2497
  }
2237
- return last;
2238
- }
2239
- function isFatalEmbeddingError(err) {
2240
- return err instanceof EmbeddingHttpError && (err.status === 401 || err.status === 402 || err.status === 403);
2241
- }
2242
- function embeddingErrorFrom(response) {
2243
- const message = typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed";
2244
- return new EmbeddingHttpError(message, response.response?.status);
2498
+ return void 0;
2245
2499
  }
2246
- async function generateEmbedding(text12, options) {
2247
- const { baseUrl = BASE_URL, getToken, apiKey, model, cache } = options;
2248
- if (cache) {
2249
- const cached = cache.get(text12);
2250
- if (cached) return Array.from(cached);
2500
+ var init_utils_gen = __esm({
2501
+ "src/client/core/utils.gen.ts"() {
2502
+ "use strict";
2251
2503
  }
2252
- let headers;
2253
- if (apiKey) {
2254
- headers = { "X-API-Key": apiKey };
2255
- } else if (getToken) {
2256
- const token = await getToken();
2504
+ });
2505
+
2506
+ // src/client/core/auth.gen.ts
2507
+ var getAuthToken;
2508
+ var init_auth_gen = __esm({
2509
+ "src/client/core/auth.gen.ts"() {
2510
+ "use strict";
2511
+ getAuthToken = async (auth, callback) => {
2512
+ const token = typeof callback === "function" ? await callback(auth) : callback;
2513
+ if (!token) {
2514
+ return;
2515
+ }
2516
+ if (auth.scheme === "bearer") {
2517
+ return `Bearer ${token}`;
2518
+ }
2519
+ if (auth.scheme === "basic") {
2520
+ return `Basic ${btoa(token)}`;
2521
+ }
2522
+ return token;
2523
+ };
2524
+ }
2525
+ });
2526
+
2527
+ // src/client/client/utils.gen.ts
2528
+ async function setAuthParams(options) {
2529
+ for (const auth of options.security ?? []) {
2530
+ if (checkForExistence(options, auth.name)) {
2531
+ continue;
2532
+ }
2533
+ const token = await getAuthToken(auth, options.auth);
2257
2534
  if (!token) {
2258
- throw new Error("No token available for embedding generation");
2535
+ continue;
2536
+ }
2537
+ const name = auth.name ?? "Authorization";
2538
+ switch (auth.in) {
2539
+ case "query":
2540
+ if (!options.query) {
2541
+ options.query = {};
2542
+ }
2543
+ options.query[name] = token;
2544
+ break;
2545
+ case "cookie":
2546
+ options.headers.append("Cookie", `${name}=${token}`);
2547
+ break;
2548
+ case "header":
2549
+ default:
2550
+ options.headers.set(name, token);
2551
+ break;
2259
2552
  }
2260
- headers = { Authorization: `Bearer ${token}` };
2261
- } else {
2262
- throw new Error("Either apiKey or getToken must be provided");
2263
- }
2264
- const response = await withEmbeddingRetry(
2265
- () => (0, import_client.postApiV1Embeddings)({
2266
- baseUrl,
2267
- body: {
2268
- // Mask PII from the request body only — the cache above still keys on
2269
- // the original `text`, so callers keep their original values.
2270
- input: options.maskInput ? options.maskInput(text12) : text12,
2271
- model: model ?? DEFAULT_API_EMBEDDING_MODEL
2272
- },
2273
- headers
2274
- })
2275
- );
2276
- if (response.error) {
2277
- throw embeddingErrorFrom(response);
2278
- }
2279
- if (!response.data?.data?.[0]?.embedding) {
2280
- throw new Error("No embedding returned from API");
2281
- }
2282
- const embedding = response.data.data[0].embedding;
2283
- if (options.onUsage && response.data.usage) {
2284
- options.onUsage({
2285
- promptTokens: response.data.usage.prompt_tokens ?? 0,
2286
- totalTokens: response.data.usage.total_tokens ?? 0
2287
- });
2288
- }
2289
- const f32Embedding = Float32Array.from(embedding);
2290
- if (cache) {
2291
- cache.set(text12, f32Embedding);
2292
- }
2293
- return Array.from(f32Embedding);
2294
- }
2295
- async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage, maskInput) {
2296
- const response = await withEmbeddingRetry(
2297
- () => (0, import_client.postApiV1Embeddings)({
2298
- baseUrl,
2299
- // Mask PII from the request body only; cache/order still key on originals.
2300
- body: { input: maskInput ? texts.map(maskInput) : texts, model },
2301
- headers
2302
- })
2303
- );
2304
- if (response.error) {
2305
- throw embeddingErrorFrom(response);
2306
- }
2307
- if (!response.data?.data) {
2308
- throw new Error("No embeddings returned from API");
2309
- }
2310
- if (onUsage && response.data.usage) {
2311
- onUsage({
2312
- promptTokens: response.data.usage.prompt_tokens ?? 0,
2313
- totalTokens: response.data.usage.total_tokens ?? 0
2314
- });
2315
2553
  }
2316
- return response.data.data.map((item) => item.embedding ?? []);
2317
2554
  }
2318
- async function generateEmbeddings(texts, options) {
2319
- if (texts.length === 0) return [];
2320
- const { baseUrl = BASE_URL, getToken, apiKey, model, batchSize, cache } = options;
2321
- const chunkSize = batchSize ?? DEFAULT_EMBEDDING_BATCH_SIZE;
2322
- const results = new Array(texts.length).fill(null);
2323
- const uncachedIndices = [];
2324
- const uncachedTexts = [];
2325
- for (let i = 0; i < texts.length; i++) {
2326
- if (cache) {
2327
- const cached = cache.get(texts[i]);
2328
- if (cached) {
2329
- results[i] = Array.from(cached);
2330
- continue;
2555
+ var PATH_PARAM_RE, defaultPathSerializer, createQuerySerializer, getParseAs, checkForExistence, buildUrl, getUrl, mergeConfigs, headersEntries, mergeHeaders, Interceptors, createInterceptors, defaultQuerySerializer, defaultHeaders, createConfig;
2556
+ var init_utils_gen2 = __esm({
2557
+ "src/client/client/utils.gen.ts"() {
2558
+ "use strict";
2559
+ init_auth_gen();
2560
+ init_bodySerializer_gen();
2561
+ init_pathSerializer_gen();
2562
+ PATH_PARAM_RE = /\{[^{}]+\}/g;
2563
+ defaultPathSerializer = ({ path, url: _url }) => {
2564
+ let url = _url;
2565
+ const matches = _url.match(PATH_PARAM_RE);
2566
+ if (matches) {
2567
+ for (const match of matches) {
2568
+ let explode = false;
2569
+ let name = match.substring(1, match.length - 1);
2570
+ let style = "simple";
2571
+ if (name.endsWith("*")) {
2572
+ explode = true;
2573
+ name = name.substring(0, name.length - 1);
2574
+ }
2575
+ if (name.startsWith(".")) {
2576
+ name = name.substring(1);
2577
+ style = "label";
2578
+ } else if (name.startsWith(";")) {
2579
+ name = name.substring(1);
2580
+ style = "matrix";
2581
+ }
2582
+ const value = path[name];
2583
+ if (value === void 0 || value === null) {
2584
+ continue;
2585
+ }
2586
+ if (Array.isArray(value)) {
2587
+ url = url.replace(match, serializeArrayParam({ explode, name, style, value }));
2588
+ continue;
2589
+ }
2590
+ if (typeof value === "object") {
2591
+ url = url.replace(
2592
+ match,
2593
+ serializeObjectParam({
2594
+ explode,
2595
+ name,
2596
+ style,
2597
+ value,
2598
+ valueOnly: true
2599
+ })
2600
+ );
2601
+ continue;
2602
+ }
2603
+ if (style === "matrix") {
2604
+ url = url.replace(
2605
+ match,
2606
+ `;${serializePrimitiveParam({
2607
+ name,
2608
+ value
2609
+ })}`
2610
+ );
2611
+ continue;
2612
+ }
2613
+ const replaceValue = encodeURIComponent(
2614
+ style === "label" ? `.${value}` : value
2615
+ );
2616
+ url = url.replace(match, replaceValue);
2617
+ }
2331
2618
  }
2332
- }
2333
- uncachedIndices.push(i);
2334
- uncachedTexts.push(texts[i]);
2335
- }
2336
- if (uncachedTexts.length === 0) {
2337
- return results;
2338
- }
2339
- let headers;
2340
- if (apiKey) {
2341
- headers = { "X-API-Key": apiKey };
2342
- } else if (getToken) {
2343
- const token = await getToken();
2344
- if (!token) {
2345
- throw new Error("No token available for embedding generation");
2346
- }
2347
- headers = { Authorization: `Bearer ${token}` };
2348
- } else {
2349
- throw new Error("Either apiKey or getToken must be provided");
2350
- }
2351
- const embeddingModel = model ?? DEFAULT_API_EMBEDDING_MODEL;
2352
- let newEmbeddings;
2353
- if (uncachedTexts.length <= chunkSize) {
2354
- newEmbeddings = await generateEmbeddingsBatch(
2355
- uncachedTexts,
2356
- headers,
2619
+ return url;
2620
+ };
2621
+ createQuerySerializer = ({
2622
+ parameters = {},
2623
+ ...args
2624
+ } = {}) => {
2625
+ const querySerializer = (queryParams) => {
2626
+ const search = [];
2627
+ if (queryParams && typeof queryParams === "object") {
2628
+ for (const name in queryParams) {
2629
+ const value = queryParams[name];
2630
+ if (value === void 0 || value === null) {
2631
+ continue;
2632
+ }
2633
+ const options = parameters[name] || args;
2634
+ if (Array.isArray(value)) {
2635
+ const serializedArray = serializeArrayParam({
2636
+ allowReserved: options.allowReserved,
2637
+ explode: true,
2638
+ name,
2639
+ style: "form",
2640
+ value,
2641
+ ...options.array
2642
+ });
2643
+ if (serializedArray) search.push(serializedArray);
2644
+ } else if (typeof value === "object") {
2645
+ const serializedObject = serializeObjectParam({
2646
+ allowReserved: options.allowReserved,
2647
+ explode: true,
2648
+ name,
2649
+ style: "deepObject",
2650
+ value,
2651
+ ...options.object
2652
+ });
2653
+ if (serializedObject) search.push(serializedObject);
2654
+ } else {
2655
+ const serializedPrimitive = serializePrimitiveParam({
2656
+ allowReserved: options.allowReserved,
2657
+ name,
2658
+ value
2659
+ });
2660
+ if (serializedPrimitive) search.push(serializedPrimitive);
2661
+ }
2662
+ }
2663
+ }
2664
+ return search.join("&");
2665
+ };
2666
+ return querySerializer;
2667
+ };
2668
+ getParseAs = (contentType) => {
2669
+ if (!contentType) {
2670
+ return "stream";
2671
+ }
2672
+ const cleanContent = contentType.split(";")[0]?.trim();
2673
+ if (!cleanContent) {
2674
+ return;
2675
+ }
2676
+ if (cleanContent.startsWith("application/json") || cleanContent.endsWith("+json")) {
2677
+ return "json";
2678
+ }
2679
+ if (cleanContent === "multipart/form-data") {
2680
+ return "formData";
2681
+ }
2682
+ if (["application/", "audio/", "image/", "video/"].some((type) => cleanContent.startsWith(type))) {
2683
+ return "blob";
2684
+ }
2685
+ if (cleanContent.startsWith("text/")) {
2686
+ return "text";
2687
+ }
2688
+ return;
2689
+ };
2690
+ checkForExistence = (options, name) => {
2691
+ if (!name) {
2692
+ return false;
2693
+ }
2694
+ if (options.headers.has(name) || options.query?.[name] || options.headers.get("Cookie")?.includes(`${name}=`)) {
2695
+ return true;
2696
+ }
2697
+ return false;
2698
+ };
2699
+ buildUrl = (options) => {
2700
+ const url = getUrl({
2701
+ baseUrl: options.baseUrl,
2702
+ path: options.path,
2703
+ query: options.query,
2704
+ querySerializer: typeof options.querySerializer === "function" ? options.querySerializer : createQuerySerializer(options.querySerializer),
2705
+ url: options.url
2706
+ });
2707
+ return url;
2708
+ };
2709
+ getUrl = ({
2357
2710
  baseUrl,
2358
- embeddingModel,
2359
- options.onUsage,
2360
- options.maskInput
2361
- );
2362
- } else {
2363
- const chunks = [];
2364
- for (let i = 0; i < uncachedTexts.length; i += chunkSize) {
2365
- chunks.push(uncachedTexts.slice(i, i + chunkSize));
2366
- }
2367
- const allEmbeddings = new Array(chunks.length);
2368
- let nextIndex = 0;
2369
- const worker = async () => {
2370
- while (nextIndex < chunks.length) {
2371
- const idx = nextIndex++;
2372
- allEmbeddings[idx] = await generateEmbeddingsBatch(
2373
- chunks[idx],
2374
- headers,
2375
- baseUrl,
2376
- embeddingModel,
2377
- options.onUsage,
2378
- options.maskInput
2379
- );
2711
+ path,
2712
+ query,
2713
+ querySerializer,
2714
+ url: _url
2715
+ }) => {
2716
+ const pathUrl = _url.startsWith("/") ? _url : `/${_url}`;
2717
+ let url = (baseUrl ?? "") + pathUrl;
2718
+ if (path) {
2719
+ url = defaultPathSerializer({ path, url });
2380
2720
  }
2721
+ let search = query ? querySerializer(query) : "";
2722
+ if (search.startsWith("?")) {
2723
+ search = search.substring(1);
2724
+ }
2725
+ if (search) {
2726
+ url += `?${search}`;
2727
+ }
2728
+ return url;
2381
2729
  };
2382
- const workers = Array.from(
2383
- { length: Math.min(DEFAULT_EMBEDDING_BATCH_CONCURRENCY, chunks.length) },
2384
- () => worker()
2385
- );
2386
- await Promise.all(workers);
2387
- newEmbeddings = allEmbeddings.flat();
2388
- }
2389
- for (let i = 0; i < uncachedIndices.length; i++) {
2390
- const f32Embedding = Float32Array.from(newEmbeddings[i]);
2391
- results[uncachedIndices[i]] = Array.from(f32Embedding);
2392
- if (cache) {
2393
- cache.set(uncachedTexts[i], f32Embedding);
2394
- }
2395
- }
2396
- return results;
2397
- }
2398
- var import_client, EMBED_MAX_ATTEMPTS, EmbeddingHttpError, DEFAULT_EMBEDDING_BATCH_SIZE, DEFAULT_EMBEDDING_BATCH_CONCURRENCY;
2399
- var init_generate = __esm({
2400
- "src/lib/memoryEngine/generate.ts"() {
2401
- "use strict";
2402
- import_client = require("@anuma/sdk");
2403
- init_clientConfig();
2404
- init_constants();
2405
- EMBED_MAX_ATTEMPTS = 4;
2406
- EmbeddingHttpError = class extends Error {
2407
- constructor(message, status) {
2408
- super(message);
2409
- this.name = "EmbeddingHttpError";
2410
- this.status = status;
2730
+ mergeConfigs = (a, b) => {
2731
+ const config = { ...a, ...b };
2732
+ if (config.baseUrl?.endsWith("/")) {
2733
+ config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1);
2411
2734
  }
2735
+ config.headers = mergeHeaders(a.headers, b.headers);
2736
+ return config;
2412
2737
  };
2413
- DEFAULT_EMBEDDING_BATCH_SIZE = 100;
2414
- DEFAULT_EMBEDDING_BATCH_CONCURRENCY = 3;
2415
- }
2416
- });
2417
-
2418
- // src/lib/memoryEngine/embeddings.ts
2419
- async function embedMessage(ctx, messageId, options) {
2420
- const message = await getMessageOp(ctx, messageId);
2421
- if (!message) {
2422
- return null;
2423
- }
2424
- if (message.vector && message.vector.length > 0) {
2425
- return message;
2426
- }
2427
- const embedding = await generateEmbedding(message.content, options);
2428
- const embeddingModel = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
2429
- return updateMessageEmbeddingOp(ctx, messageId, embedding, embeddingModel);
2430
- }
2431
- async function embedAllMessages(ctx, options, filter) {
2432
- const embeddingModel = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
2433
- let embeddedCount = 0;
2434
- const conversations = await getConversationsOp(ctx);
2435
- const targetConversations = filter?.conversationId ? conversations.filter((c) => c.conversationId === filter.conversationId) : conversations;
2436
- for (const conv of targetConversations) {
2437
- const messages = await getMessagesOp(ctx, conv.conversationId);
2438
- for (const message of messages) {
2439
- if (message.vector && message.vector.length > 0) {
2440
- continue;
2738
+ headersEntries = (headers) => {
2739
+ const entries = [];
2740
+ headers.forEach((value, key) => {
2741
+ entries.push([key, value]);
2742
+ });
2743
+ return entries;
2744
+ };
2745
+ mergeHeaders = (...headers) => {
2746
+ const mergedHeaders = new Headers();
2747
+ for (const header of headers) {
2748
+ if (!header || typeof header !== "object") {
2749
+ continue;
2750
+ }
2751
+ const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header);
2752
+ for (const [key, value] of iterator) {
2753
+ if (value === null) {
2754
+ mergedHeaders.delete(key);
2755
+ } else if (Array.isArray(value)) {
2756
+ for (const v of value) {
2757
+ mergedHeaders.append(key, v);
2758
+ }
2759
+ } else if (value !== void 0) {
2760
+ mergedHeaders.set(
2761
+ key,
2762
+ typeof value === "object" ? JSON.stringify(value) : value
2763
+ );
2764
+ }
2765
+ }
2441
2766
  }
2442
- if (filter?.roles && !filter.roles.includes(message.role)) {
2443
- continue;
2767
+ return mergedHeaders;
2768
+ };
2769
+ Interceptors = class {
2770
+ constructor() {
2771
+ this.fns = [];
2444
2772
  }
2445
- if (message.role === "system") {
2446
- continue;
2773
+ clear() {
2774
+ this.fns = [];
2447
2775
  }
2448
- const minLength = filter?.minContentLength ?? DEFAULT_MIN_CONTENT_LENGTH;
2449
- if (message.content.length < minLength) {
2450
- continue;
2776
+ eject(id) {
2777
+ const index = this.getInterceptorIndex(id);
2778
+ if (this.fns[index]) {
2779
+ this.fns[index] = null;
2780
+ }
2451
2781
  }
2452
- try {
2453
- const embedding = await generateEmbedding(message.content, options);
2454
- await updateMessageEmbeddingOp(ctx, message.uniqueId, embedding, embeddingModel);
2455
- embeddedCount++;
2456
- } catch (error) {
2457
- if (isFatalEmbeddingError(error)) throw error;
2458
- getLogger().error(`Failed to embed message ${message.uniqueId}:`, error);
2782
+ exists(id) {
2783
+ const index = this.getInterceptorIndex(id);
2784
+ return Boolean(this.fns[index]);
2459
2785
  }
2460
- }
2461
- }
2462
- return embeddedCount;
2463
- }
2464
- async function chunkAndEmbedMessage(ctx, messageId, options) {
2465
- const { chunkSize = DEFAULT_CHUNK_SIZE } = options;
2466
- const message = await getMessageOp(ctx, messageId);
2467
- if (!message) {
2468
- return null;
2469
- }
2470
- if (message.chunks && message.chunks.length > 0) {
2471
- return message;
2472
- }
2473
- const embeddingModel = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
2474
- if (!shouldChunkMessage(message.content, chunkSize)) {
2475
- const embedding = await generateEmbedding(message.content, options);
2476
- return updateMessageEmbeddingOp(ctx, messageId, embedding, embeddingModel);
2477
- }
2478
- const textChunks = chunkText(message.content, options);
2479
- const chunkTexts = textChunks.map((c) => c.text);
2480
- const embeddings = await generateEmbeddings(chunkTexts, options);
2481
- const messageChunks = textChunks.map((chunk, i) => ({
2482
- text: chunk.text,
2483
- vector: embeddings[i],
2484
- startOffset: chunk.startOffset,
2485
- endOffset: chunk.endOffset
2486
- }));
2487
- return updateMessageChunksOp(ctx, messageId, messageChunks, embeddingModel);
2488
- }
2489
- async function chunkAndEmbedAllMessages(ctx, options, filter) {
2490
- const embeddingModel = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
2491
- const { chunkSize = DEFAULT_CHUNK_SIZE } = options;
2492
- const minLength = filter?.minContentLength ?? DEFAULT_MIN_CONTENT_LENGTH;
2493
- const conversations = await getConversationsOp(ctx);
2494
- const targetConversations = filter?.conversationId ? conversations.filter((c) => c.conversationId === filter.conversationId) : conversations;
2495
- const shortMessages = [];
2496
- const longMessages = [];
2497
- for (const conv of targetConversations) {
2498
- const messages = await getMessagesOp(ctx, conv.conversationId);
2499
- for (const message of messages) {
2500
- const isStale = message.embeddingModel !== void 0 && message.embeddingModel !== null && message.embeddingModel !== embeddingModel;
2501
- if (message.chunks && message.chunks.length > 0 && !isStale) continue;
2502
- const hasVector = message.vector && message.vector.length > 0;
2503
- if (hasVector && !filter?.rechunkExisting && !isStale) continue;
2504
- if (filter?.roles && !filter.roles.includes(message.role)) continue;
2505
- if (message.role === "system") continue;
2506
- if (message.content.length < minLength) continue;
2507
- if (shouldChunkMessage(message.content, chunkSize)) {
2508
- longMessages.push({
2509
- uniqueId: message.uniqueId,
2510
- textChunks: chunkText(message.content, options)
2511
- });
2512
- } else {
2513
- shortMessages.push({ uniqueId: message.uniqueId, content: message.content });
2786
+ getInterceptorIndex(id) {
2787
+ if (typeof id === "number") {
2788
+ return this.fns[id] ? id : -1;
2789
+ }
2790
+ return this.fns.indexOf(id);
2514
2791
  }
2515
- }
2792
+ update(id, fn) {
2793
+ const index = this.getInterceptorIndex(id);
2794
+ if (this.fns[index]) {
2795
+ this.fns[index] = fn;
2796
+ return id;
2797
+ }
2798
+ return false;
2799
+ }
2800
+ use(fn) {
2801
+ this.fns.push(fn);
2802
+ return this.fns.length - 1;
2803
+ }
2804
+ };
2805
+ createInterceptors = () => ({
2806
+ error: new Interceptors(),
2807
+ request: new Interceptors(),
2808
+ response: new Interceptors()
2809
+ });
2810
+ defaultQuerySerializer = createQuerySerializer({
2811
+ allowReserved: false,
2812
+ array: {
2813
+ explode: true,
2814
+ style: "form"
2815
+ },
2816
+ object: {
2817
+ explode: true,
2818
+ style: "deepObject"
2819
+ }
2820
+ });
2821
+ defaultHeaders = {
2822
+ "Content-Type": "application/json"
2823
+ };
2824
+ createConfig = (override = {}) => ({
2825
+ ...jsonBodySerializer,
2826
+ headers: defaultHeaders,
2827
+ parseAs: "auto",
2828
+ querySerializer: defaultQuerySerializer,
2829
+ ...override
2830
+ });
2516
2831
  }
2517
- let embeddedCount = 0;
2518
- if (shortMessages.length > 0) {
2519
- try {
2520
- const texts = shortMessages.map((m) => m.content);
2521
- const embeddings = await generateEmbeddings(texts, options);
2522
- for (let i = 0; i < shortMessages.length; i++) {
2832
+ });
2833
+
2834
+ // src/client/client/client.gen.ts
2835
+ var createClient;
2836
+ var init_client_gen = __esm({
2837
+ "src/client/client/client.gen.ts"() {
2838
+ "use strict";
2839
+ init_serverSentEvents_gen();
2840
+ init_utils_gen();
2841
+ init_utils_gen2();
2842
+ createClient = (config = {}) => {
2843
+ let _config = mergeConfigs(createConfig(), config);
2844
+ const getConfig = () => ({ ..._config });
2845
+ const setConfig = (config2) => {
2846
+ _config = mergeConfigs(_config, config2);
2847
+ return getConfig();
2848
+ };
2849
+ const interceptors = createInterceptors();
2850
+ const beforeRequest = async (options) => {
2851
+ const opts = {
2852
+ ..._config,
2853
+ ...options,
2854
+ fetch: options.fetch ?? _config.fetch ?? globalThis.fetch,
2855
+ headers: mergeHeaders(_config.headers, options.headers),
2856
+ serializedBody: void 0
2857
+ };
2858
+ if (opts.security) {
2859
+ await setAuthParams(opts);
2860
+ }
2861
+ if (opts.requestValidator) {
2862
+ await opts.requestValidator(opts);
2863
+ }
2864
+ if (opts.body !== void 0 && opts.bodySerializer) {
2865
+ opts.serializedBody = opts.bodySerializer(opts.body);
2866
+ }
2867
+ if (opts.body === void 0 || opts.serializedBody === "") {
2868
+ opts.headers.delete("Content-Type");
2869
+ }
2870
+ const resolvedOpts = opts;
2871
+ const url = buildUrl(resolvedOpts);
2872
+ return { opts: resolvedOpts, url };
2873
+ };
2874
+ const request = async (options) => {
2875
+ const throwOnError = options.throwOnError ?? _config.throwOnError;
2876
+ let response;
2523
2877
  try {
2524
- await updateMessageEmbeddingOp(
2525
- ctx,
2526
- shortMessages[i].uniqueId,
2527
- embeddings[i],
2528
- embeddingModel
2529
- );
2530
- embeddedCount++;
2878
+ const { opts, url } = await beforeRequest(options);
2879
+ for (const fn of interceptors.request.fns) {
2880
+ if (fn) {
2881
+ await fn(opts);
2882
+ }
2883
+ }
2884
+ const _fetch = opts.fetch;
2885
+ const requestInit = {
2886
+ ...opts,
2887
+ body: getValidRequestBody(opts)
2888
+ };
2889
+ response = await _fetch(url, requestInit);
2890
+ for (const fn of interceptors.response.fns) {
2891
+ if (fn) {
2892
+ response = await fn(response, opts);
2893
+ }
2894
+ }
2895
+ const result = {
2896
+ response
2897
+ };
2898
+ if (response.ok) {
2899
+ const parseAs = (opts.parseAs === "auto" ? getParseAs(response.headers.get("Content-Type")) : opts.parseAs) ?? "json";
2900
+ if (response.status === 204 || response.headers.get("Content-Length") === "0") {
2901
+ let emptyData;
2902
+ switch (parseAs) {
2903
+ case "arrayBuffer":
2904
+ case "blob":
2905
+ case "text":
2906
+ emptyData = await response[parseAs]();
2907
+ break;
2908
+ case "formData":
2909
+ emptyData = new FormData();
2910
+ break;
2911
+ case "stream":
2912
+ emptyData = response.body;
2913
+ break;
2914
+ case "json":
2915
+ default:
2916
+ emptyData = {};
2917
+ break;
2918
+ }
2919
+ return {
2920
+ data: emptyData,
2921
+ ...result
2922
+ };
2923
+ }
2924
+ let data;
2925
+ switch (parseAs) {
2926
+ case "arrayBuffer":
2927
+ case "blob":
2928
+ case "formData":
2929
+ case "text":
2930
+ data = await response[parseAs]();
2931
+ break;
2932
+ case "json": {
2933
+ const text12 = await response.text();
2934
+ data = text12 ? JSON.parse(text12) : {};
2935
+ break;
2936
+ }
2937
+ case "stream":
2938
+ return {
2939
+ data: response.body,
2940
+ ...result
2941
+ };
2942
+ }
2943
+ if (parseAs === "json") {
2944
+ if (opts.responseValidator) {
2945
+ await opts.responseValidator(data);
2946
+ }
2947
+ if (opts.responseTransformer) {
2948
+ data = await opts.responseTransformer(data);
2949
+ }
2950
+ }
2951
+ return {
2952
+ data,
2953
+ ...result
2954
+ };
2955
+ }
2956
+ const textError = await response.text();
2957
+ let jsonError;
2958
+ try {
2959
+ jsonError = JSON.parse(textError);
2960
+ } catch {
2961
+ }
2962
+ throw jsonError ?? textError;
2531
2963
  } catch (error) {
2532
- getLogger().error(
2533
- `Failed to save embedding for message ${shortMessages[i].uniqueId}:`,
2534
- error
2535
- );
2964
+ let finalError = error;
2965
+ for (const fn of interceptors.error.fns) {
2966
+ if (fn) {
2967
+ finalError = await fn(finalError, response, options);
2968
+ }
2969
+ }
2970
+ finalError = finalError || {};
2971
+ if (throwOnError) {
2972
+ throw finalError;
2973
+ }
2974
+ return {
2975
+ error: finalError,
2976
+ response
2977
+ };
2536
2978
  }
2537
- }
2538
- } catch (error) {
2539
- if (isFatalEmbeddingError(error)) throw error;
2540
- getLogger().error("Failed to batch-embed short messages:", error);
2541
- }
2979
+ };
2980
+ const makeMethodFn = (method) => (options) => request({ ...options, method });
2981
+ const makeSseFn = (method) => async (options) => {
2982
+ const { opts, url } = await beforeRequest(options);
2983
+ return createSseClient({
2984
+ ...opts,
2985
+ body: opts.body,
2986
+ method,
2987
+ onRequest: async (url2, init) => {
2988
+ let request2 = new Request(url2, init);
2989
+ const requestInit = { ...init, url: url2 };
2990
+ for (const fn of interceptors.request.fns) {
2991
+ if (fn) {
2992
+ await fn(requestInit);
2993
+ request2 = new Request(requestInit.url, requestInit);
2994
+ }
2995
+ }
2996
+ return request2;
2997
+ },
2998
+ serializedBody: getValidRequestBody(opts),
2999
+ url
3000
+ });
3001
+ };
3002
+ const _buildUrl = (options) => buildUrl({ ..._config, ...options });
3003
+ return {
3004
+ buildUrl: _buildUrl,
3005
+ connect: makeMethodFn("CONNECT"),
3006
+ delete: makeMethodFn("DELETE"),
3007
+ get: makeMethodFn("GET"),
3008
+ getConfig,
3009
+ head: makeMethodFn("HEAD"),
3010
+ interceptors,
3011
+ options: makeMethodFn("OPTIONS"),
3012
+ patch: makeMethodFn("PATCH"),
3013
+ post: makeMethodFn("POST"),
3014
+ put: makeMethodFn("PUT"),
3015
+ request,
3016
+ setConfig,
3017
+ sse: {
3018
+ connect: makeSseFn("CONNECT"),
3019
+ delete: makeSseFn("DELETE"),
3020
+ get: makeSseFn("GET"),
3021
+ head: makeSseFn("HEAD"),
3022
+ options: makeSseFn("OPTIONS"),
3023
+ patch: makeSseFn("PATCH"),
3024
+ post: makeSseFn("POST"),
3025
+ put: makeSseFn("PUT"),
3026
+ trace: makeSseFn("TRACE")
3027
+ },
3028
+ trace: makeMethodFn("TRACE")
3029
+ };
3030
+ };
2542
3031
  }
2543
- for (const msg of longMessages) {
2544
- try {
2545
- const chunkTexts = msg.textChunks.map((c) => c.text);
2546
- const embeddings = await generateEmbeddings(chunkTexts, options);
2547
- const messageChunks = msg.textChunks.map((chunk, i) => ({
2548
- text: chunk.text,
2549
- vector: embeddings[i],
2550
- startOffset: chunk.startOffset,
2551
- endOffset: chunk.endOffset
2552
- }));
2553
- await updateMessageChunksOp(ctx, msg.uniqueId, messageChunks, embeddingModel);
2554
- embeddedCount++;
2555
- } catch (error) {
2556
- if (isFatalEmbeddingError(error)) throw error;
2557
- getLogger().error(`Failed to embed message ${msg.uniqueId}:`, error);
2558
- }
3032
+ });
3033
+
3034
+ // src/client/client/index.ts
3035
+ var init_client = __esm({
3036
+ "src/client/client/index.ts"() {
3037
+ "use strict";
3038
+ init_client_gen();
3039
+ init_utils_gen2();
2559
3040
  }
2560
- return embeddedCount;
2561
- }
2562
- var DEFAULT_MIN_CONTENT_LENGTH;
2563
- var init_embeddings = __esm({
2564
- "src/lib/memoryEngine/embeddings.ts"() {
3041
+ });
3042
+
3043
+ // src/client/client.gen.ts
3044
+ var client;
3045
+ var init_client_gen2 = __esm({
3046
+ "src/client/client.gen.ts"() {
2565
3047
  "use strict";
2566
- init_operations();
2567
- init_logger();
2568
- init_chunking();
2569
- init_constants();
2570
- init_generate();
2571
- init_generate();
2572
- DEFAULT_MIN_CONTENT_LENGTH = 10;
3048
+ init_clientConfig();
3049
+ init_client();
3050
+ client = createClient(createClientConfig(createConfig()));
2573
3051
  }
2574
3052
  });
2575
3053
 
2576
- // src/lib/pii/patterns.ts
2577
- function luhnCheck(digits) {
2578
- let sum = 0;
2579
- let alternate = false;
2580
- for (let i = digits.length - 1; i >= 0; i--) {
2581
- let n = parseInt(digits[i], 10);
2582
- if (alternate) {
2583
- n *= 2;
2584
- if (n > 9) n -= 9;
2585
- }
2586
- sum += n;
2587
- alternate = !alternate;
3054
+ // src/client/sdk.gen.ts
3055
+ var getApiV1Config, getApiV1CreditsBalance, getApiV1CreditsPacks, postApiV1CreditsPurchase, postApiV1Embeddings, getApiV1Models, postApiV1PhoneCalls, getApiV1PhoneCallsByCallId, postApiV1SubscriptionsCancel, postApiV1SubscriptionsCreateCheckoutSession, postApiV1SubscriptionsCustomerPortal, postApiV1SubscriptionsRenew, getApiV1SubscriptionsStatus, getApiV1WalletsBinding, postApiV1WalletsBinding, postApiV1WalletsBindingNonce, deleteApiV1WalletsBindingByAddress, postAuthOauthByProviderExchange, postAuthOauthByProviderRefresh, postAuthOauthByProviderRevoke;
3056
+ var init_sdk_gen = __esm({
3057
+ "src/client/sdk.gen.ts"() {
3058
+ "use strict";
3059
+ init_client_gen2();
3060
+ getApiV1Config = (options) => (options?.client ?? client).get({ url: "/api/v1/config", ...options });
3061
+ getApiV1CreditsBalance = (options) => (options?.client ?? client).get({ url: "/api/v1/credits/balance", ...options });
3062
+ getApiV1CreditsPacks = (options) => (options?.client ?? client).get({ url: "/api/v1/credits/packs", ...options });
3063
+ postApiV1CreditsPurchase = (options) => (options.client ?? client).post({
3064
+ url: "/api/v1/credits/purchase",
3065
+ ...options,
3066
+ headers: {
3067
+ "Content-Type": "application/json",
3068
+ ...options.headers
3069
+ }
3070
+ });
3071
+ postApiV1Embeddings = (options) => (options.client ?? client).post({
3072
+ url: "/api/v1/embeddings",
3073
+ ...options,
3074
+ headers: {
3075
+ "Content-Type": "application/json",
3076
+ ...options.headers
3077
+ }
3078
+ });
3079
+ getApiV1Models = (options) => (options?.client ?? client).get({ url: "/api/v1/models", ...options });
3080
+ postApiV1PhoneCalls = (options) => (options.client ?? client).post({
3081
+ url: "/api/v1/phone-calls",
3082
+ ...options,
3083
+ headers: {
3084
+ "Content-Type": "application/json",
3085
+ ...options.headers
3086
+ }
3087
+ });
3088
+ getApiV1PhoneCallsByCallId = (options) => (options.client ?? client).get({ url: "/api/v1/phone-calls/{call_id}", ...options });
3089
+ postApiV1SubscriptionsCancel = (options) => (options?.client ?? client).post({
3090
+ url: "/api/v1/subscriptions/cancel",
3091
+ ...options,
3092
+ headers: {
3093
+ "Content-Type": "application/json",
3094
+ ...options?.headers
3095
+ }
3096
+ });
3097
+ postApiV1SubscriptionsCreateCheckoutSession = (options) => (options.client ?? client).post({
3098
+ url: "/api/v1/subscriptions/create-checkout-session",
3099
+ ...options,
3100
+ headers: {
3101
+ "Content-Type": "application/json",
3102
+ ...options.headers
3103
+ }
3104
+ });
3105
+ postApiV1SubscriptionsCustomerPortal = (options) => (options.client ?? client).post({
3106
+ url: "/api/v1/subscriptions/customer-portal",
3107
+ ...options,
3108
+ headers: {
3109
+ "Content-Type": "application/json",
3110
+ ...options.headers
3111
+ }
3112
+ });
3113
+ postApiV1SubscriptionsRenew = (options) => (options?.client ?? client).post({ url: "/api/v1/subscriptions/renew", ...options });
3114
+ getApiV1SubscriptionsStatus = (options) => (options?.client ?? client).get({ url: "/api/v1/subscriptions/status", ...options });
3115
+ getApiV1WalletsBinding = (options) => (options?.client ?? client).get({ url: "/api/v1/wallets/binding", ...options });
3116
+ postApiV1WalletsBinding = (options) => (options.client ?? client).post({
3117
+ url: "/api/v1/wallets/binding",
3118
+ ...options,
3119
+ headers: {
3120
+ "Content-Type": "application/json",
3121
+ ...options.headers
3122
+ }
3123
+ });
3124
+ postApiV1WalletsBindingNonce = (options) => (options?.client ?? client).post({ url: "/api/v1/wallets/binding/nonce", ...options });
3125
+ deleteApiV1WalletsBindingByAddress = (options) => (options.client ?? client).delete({ url: "/api/v1/wallets/binding/{address}", ...options });
3126
+ postAuthOauthByProviderExchange = (options) => (options.client ?? client).post({
3127
+ url: "/auth/oauth/{provider}/exchange",
3128
+ ...options,
3129
+ headers: {
3130
+ "Content-Type": "application/json",
3131
+ ...options.headers
3132
+ }
3133
+ });
3134
+ postAuthOauthByProviderRefresh = (options) => (options.client ?? client).post({
3135
+ url: "/auth/oauth/{provider}/refresh",
3136
+ ...options,
3137
+ headers: {
3138
+ "Content-Type": "application/json",
3139
+ ...options.headers
3140
+ }
3141
+ });
3142
+ postAuthOauthByProviderRevoke = (options) => (options.client ?? client).post({
3143
+ url: "/auth/oauth/{provider}/revoke",
3144
+ ...options,
3145
+ headers: {
3146
+ "Content-Type": "application/json",
3147
+ ...options.headers
3148
+ }
3149
+ });
2588
3150
  }
2589
- return sum % 10 === 0;
2590
- }
2591
- var PII_PATTERNS;
2592
- var init_patterns = __esm({
2593
- "src/lib/pii/patterns.ts"() {
3151
+ });
3152
+
3153
+ // src/client/index.ts
3154
+ var init_client2 = __esm({
3155
+ "src/client/index.ts"() {
2594
3156
  "use strict";
2595
- PII_PATTERNS = [
2596
- // Email — standard RFC-ish pattern.
2597
- // Quantifiers are bounded (local-part ≤ 64, domain ≤ 255, TLD ≤ 24 —
2598
- // all at or above real RFC 5321 limits) so the engine cannot backtrack
2599
- // quadratically on adversarial input like "a.a.a.a…" with no "@".
2600
- {
2601
- category: "EMAIL",
2602
- regex: /\b[a-zA-Z0-9._%+-]{1,64}@[a-zA-Z0-9.-]{1,255}\.[a-zA-Z]{2,24}\b/g
2603
- },
2604
- // SSN — US Social Security Number, dashed form (must run before phone)
2605
- {
2606
- category: "SSN",
2607
- regex: /\b\d{3}-\d{2}-\d{4}\b/g,
2608
- validate: (match) => {
2609
- const parts = match.split("-");
2610
- const area = parseInt(parts[0], 10);
2611
- return area !== 0 && area !== 666 && area < 900;
2612
- }
2613
- },
2614
- // SSN — dashless or space-separated form. Only redacted with an "SSN" /
2615
- // "social security" cue nearby: a bare 9-digit run is too ambiguous
2616
- // (ZIP+4, account numbers, etc.) to redact unconditionally.
2617
- {
2618
- category: "SSN",
2619
- regex: /\b\d{3}[ ]?\d{2}[ ]?\d{4}\b/g,
2620
- context: /(?:\bssn\b|\bsocial\s+security(?:\s+(?:number|no\.?|#))?\b)[^\d\n]{0,12}$/i,
2621
- validate: (match) => {
2622
- const digits = match.replace(/\D/g, "");
2623
- if (digits.length !== 9) return false;
2624
- const area = parseInt(digits.slice(0, 3), 10);
2625
- return area !== 0 && area !== 666 && area < 900;
2626
- }
2627
- },
2628
- // Credit card numbers — 13-19 contiguous digits or groups of 4 separated by spaces/dashes
2629
- // Must run before phone to avoid partial matches
2630
- {
2631
- category: "CREDIT_CARD",
2632
- regex: /\b\d{4}[\s-]\d{4}[\s-]\d{4}[\s-]\d{1,7}\b|\b\d{13,19}\b/g,
2633
- validate: (match) => {
2634
- const digits = match.replace(/\D/g, "");
2635
- if (digits.length < 13 || digits.length > 19) return false;
2636
- return luhnCheck(digits);
2637
- }
2638
- },
2639
- // IPv4 addresses (must run before phone to avoid partial matches)
2640
- {
2641
- category: "IP_ADDRESS",
2642
- regex: /\b(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\b/g,
2643
- validate: (match) => {
2644
- return match !== "0.0.0.0" && match !== "127.0.0.1" && match !== "255.255.255.255";
2645
- }
2646
- },
2647
- // IPv6 addresses — full and compressed (::) forms. Each alternative requires
2648
- // either a full 8-group address or a "::" compression, so ordinary
2649
- // colon-separated text (timestamps like 12:34:56) does not match. Loopback
2650
- // (::1) and unspecified (::) are excluded.
2651
- {
2652
- category: "IP_ADDRESS",
2653
- regex: /(?:(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?::[0-9a-fA-F]{1,4}){1,6}|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:))/g,
2654
- validate: (match) => match !== "::1" && match !== "::"
2655
- },
2656
- // Phone numbers. The separated form requires separator characters (dashes,
2657
- // spaces, dots, parens) to avoid matching bare digit sequences that are
2658
- // actually credit cards, IPs, or years. A second alternative matches E.164
2659
- // (a leading "+" then 10–15 digits, e.g. +14155552671), which is
2660
- // unambiguous; a bare 10-digit run with no "+" and no separators is
2661
- // intentionally not matched to avoid false positives.
2662
- {
2663
- category: "PHONE",
2664
- regex: /(?:\+\d{1,3}[\s.-])?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}\b|\+\d{10,15}\b/g
2665
- },
2666
- // API keys / secrets — long token with a key-like prefix. The validator
2667
- // requires entropy (at least one digit, or a mix of upper- and lower-case)
2668
- // so long all-lowercase prose identifiers like
2669
- // "accessibility_is_important_for_everyone" or
2670
- // "access-control-list-management-feature" are not redacted. Real keys and
2671
- // tokens essentially always contain digits or mixed case.
2672
- {
2673
- category: "API_KEY",
2674
- regex: /\b(?:sk|pk|api|key|token|secret|bearer|access)[_-]?[a-zA-Z0-9_-]{20,}\b/gi,
2675
- validate: (match) => {
2676
- const hasDigit = /\d/.test(match);
2677
- const hasMixedCase = /[a-z]/.test(match) && /[A-Z]/.test(match);
2678
- return hasDigit || hasMixedCase;
2679
- }
2680
- },
2681
- // US street addresses — house number + Title-Case street name + suffix.
2682
- // Intentionally NOT case-insensitive: the `[A-Z][a-z]+` guard requires
2683
- // properly-capitalized street words, so "123 main street", "100 MAIN
2684
- // STREET" and prose like "3 blocks down the road" / "5 minutes to drive"
2685
- // are not treated as addresses. Whitespace is `[ \t]` only (no newline
2686
- // spanning), and the suffix must end the segment (punctuation / newline /
2687
- // end of string) so "Driveway" or "Wayfair" don't match on the suffix.
2688
- {
2689
- category: "US_ADDRESS",
2690
- regex: /\b\d{1,5}[ \t]+(?:[A-Z][a-z]+[ \t]+){1,3}(?:St(?:reet)?|Ave(?:nue)?|Blvd|Boulevard|Dr(?:ive)?|Ln|Lane|Rd|Road|Ct|Court|Pl(?:ace)?|Way|Cir(?:cle)?|Pkwy|Parkway|Hwy|Highway)\.?(?=[\s,.;:!?)]|$)/g,
2691
- validate: (match) => {
2692
- return !/^0/.test(match.trim());
2693
- }
2694
- },
2695
- // Dates of birth — common US date formats. Only redacted when a birth-date
2696
- // cue ("DOB", "born", "birthday", "date of birth") appears just before the
2697
- // date, so ordinary calendar dates ("meeting 12/25/2024", deadlines,
2698
- // invoices) are left intact for the model. A calendar validator also rejects
2699
- // impossible dates like 02/31/1990.
2700
- {
2701
- category: "DATE_OF_BIRTH",
2702
- regex: /\b(?:(?:0?[1-9]|1[0-2])[/-](?:0?[1-9]|[12]\d|3[01])[/-](?:19|20)\d{2})\b/g,
2703
- context: /(?:\bdob\b|\bd\.?o\.?b\.?|\bborn\b|\bbirth\s?date\b|\bbirthdate\b|\bbirthday\b|\bdate\s+of\s+birth\b)[^\d\n]{0,12}$/i,
2704
- validate: (match) => {
2705
- const m = match.match(/(\d{1,2})[/-](\d{1,2})[/-](\d{4})/);
2706
- if (!m) return false;
2707
- const month = parseInt(m[1], 10);
2708
- const day = parseInt(m[2], 10);
2709
- const year = parseInt(m[3], 10);
2710
- const isLeap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
2711
- const daysInMonth = [31, isLeap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
2712
- return month >= 1 && month <= 12 && day >= 1 && day <= daysInMonth[month - 1];
2713
- }
2714
- }
2715
- ];
3157
+ init_sdk_gen();
2716
3158
  }
2717
3159
  });
2718
3160
 
2719
- // src/lib/pii/redactor.ts
2720
- function escapeRegExp(value) {
2721
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3161
+ // src/lib/memoryEngine/generate.ts
3162
+ async function withEmbeddingRetry(call) {
3163
+ let last;
3164
+ let lastThrown;
3165
+ let threw = false;
3166
+ for (let attempt = 1; attempt <= EMBED_MAX_ATTEMPTS; attempt++) {
3167
+ try {
3168
+ threw = false;
3169
+ last = await call();
3170
+ if (!last.error) return last;
3171
+ const status = last.response?.status;
3172
+ const retryable = status === void 0 || status === 429 || status >= 500;
3173
+ if (!retryable) return last;
3174
+ } catch (err) {
3175
+ threw = true;
3176
+ lastThrown = err;
3177
+ }
3178
+ if (attempt < EMBED_MAX_ATTEMPTS) {
3179
+ const base = 250 * 2 ** (attempt - 1);
3180
+ await new Promise((r) => setTimeout(r, base + Math.random() * 0.4 * base));
3181
+ }
3182
+ }
3183
+ if (threw) throw lastThrown;
3184
+ if (last?.error instanceof Error && last.response?.status === void 0) {
3185
+ throw last.error;
3186
+ }
3187
+ return last;
2722
3188
  }
2723
- function isWordChar(ch) {
2724
- return /[A-Za-z0-9_]/.test(ch) || ch.charCodeAt(0) > 127;
3189
+ function isFatalEmbeddingError(err) {
3190
+ return err instanceof EmbeddingHttpError && (err.status === 401 || err.status === 402 || err.status === 403);
2725
3191
  }
2726
- function isPiiRedactor(value) {
2727
- return typeof value === "object" && value !== null && typeof value.redactMessages === "function" && typeof value.deAnonymize === "function";
3192
+ function embeddingErrorFrom(response) {
3193
+ const message = typeof response.error === "object" && response.error && "error" in response.error ? response.error.error : "API embedding failed";
3194
+ return new EmbeddingHttpError(message, response.response?.status);
2728
3195
  }
2729
- function resolvePiiRedactor(piiRedaction) {
2730
- if (piiRedaction === true) return new PiiRedactor();
2731
- if (!piiRedaction) return void 0;
2732
- if (isPiiRedactor(piiRedaction)) return piiRedaction;
2733
- console.warn(
2734
- "[PiiRedactor] `piiRedaction` is neither `true` nor a PiiRedactor instance; PII redaction is DISABLED for this request."
3196
+ async function generateEmbedding(text12, options) {
3197
+ const { baseUrl = BASE_URL, getToken, apiKey, model, cache } = options;
3198
+ if (cache) {
3199
+ const cached = cache.get(text12);
3200
+ if (cached) return Array.from(cached);
3201
+ }
3202
+ let headers;
3203
+ if (apiKey) {
3204
+ headers = { "X-API-Key": apiKey };
3205
+ } else if (getToken) {
3206
+ const token = await getToken();
3207
+ if (!token) {
3208
+ throw new Error("No token available for embedding generation");
3209
+ }
3210
+ headers = { Authorization: `Bearer ${token}` };
3211
+ } else {
3212
+ throw new Error("Either apiKey or getToken must be provided");
3213
+ }
3214
+ const response = await withEmbeddingRetry(
3215
+ () => postApiV1Embeddings({
3216
+ baseUrl,
3217
+ body: {
3218
+ // Mask PII from the request body only — the cache above still keys on
3219
+ // the original `text`, so callers keep their original values.
3220
+ input: options.maskInput ? options.maskInput(text12) : text12,
3221
+ model: model ?? DEFAULT_API_EMBEDDING_MODEL
3222
+ },
3223
+ headers
3224
+ })
2735
3225
  );
2736
- return void 0;
3226
+ if (response.error) {
3227
+ throw embeddingErrorFrom(response);
3228
+ }
3229
+ if (!response.data?.data?.[0]?.embedding) {
3230
+ throw new Error("No embedding returned from API");
3231
+ }
3232
+ const embedding = response.data.data[0].embedding;
3233
+ if (options.onUsage && response.data.usage) {
3234
+ options.onUsage({
3235
+ promptTokens: response.data.usage.prompt_tokens ?? 0,
3236
+ totalTokens: response.data.usage.total_tokens ?? 0
3237
+ });
3238
+ }
3239
+ const f32Embedding = Float32Array.from(embedding);
3240
+ if (cache) {
3241
+ cache.set(text12, f32Embedding);
3242
+ }
3243
+ return Array.from(f32Embedding);
2737
3244
  }
2738
- function createStreamingDeAnonymizer(redactor, emit) {
2739
- let buffer = "";
2740
- const trailingFragment = /\[[A-Za-z0-9_]*$/;
2741
- return {
2742
- push(chunk) {
2743
- if (!chunk) return;
2744
- buffer += chunk;
2745
- const m = buffer.match(trailingFragment);
2746
- if (!m || m.index === void 0) {
2747
- emit(redactor.deAnonymize(buffer));
2748
- buffer = "";
2749
- } else if (m.index > 0) {
2750
- emit(redactor.deAnonymize(buffer.slice(0, m.index)));
2751
- buffer = buffer.slice(m.index);
2752
- }
2753
- },
2754
- flush() {
2755
- if (buffer) {
2756
- emit(redactor.deAnonymize(buffer));
2757
- buffer = "";
2758
- }
2759
- }
2760
- };
3245
+ async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage, maskInput) {
3246
+ const response = await withEmbeddingRetry(
3247
+ () => postApiV1Embeddings({
3248
+ baseUrl,
3249
+ // Mask PII from the request body only; cache/order still key on originals.
3250
+ body: { input: maskInput ? texts.map(maskInput) : texts, model },
3251
+ headers
3252
+ })
3253
+ );
3254
+ if (response.error) {
3255
+ throw embeddingErrorFrom(response);
3256
+ }
3257
+ if (!response.data?.data) {
3258
+ throw new Error("No embeddings returned from API");
3259
+ }
3260
+ if (onUsage && response.data.usage) {
3261
+ onUsage({
3262
+ promptTokens: response.data.usage.prompt_tokens ?? 0,
3263
+ totalTokens: response.data.usage.total_tokens ?? 0
3264
+ });
3265
+ }
3266
+ return response.data.data.map((item) => item.embedding ?? []);
2761
3267
  }
2762
- var PiiRedactor;
2763
- var init_redactor = __esm({
2764
- "src/lib/pii/redactor.ts"() {
2765
- "use strict";
3268
+ async function generateEmbeddings(texts, options) {
3269
+ if (texts.length === 0) return [];
3270
+ const { baseUrl = BASE_URL, getToken, apiKey, model, batchSize, cache } = options;
3271
+ const chunkSize = batchSize ?? DEFAULT_EMBEDDING_BATCH_SIZE;
3272
+ const results = new Array(texts.length).fill(null);
3273
+ const uncachedIndices = [];
3274
+ const uncachedTexts = [];
3275
+ for (let i = 0; i < texts.length; i++) {
3276
+ if (cache) {
3277
+ const cached = cache.get(texts[i]);
3278
+ if (cached) {
3279
+ results[i] = Array.from(cached);
3280
+ continue;
3281
+ }
3282
+ }
3283
+ uncachedIndices.push(i);
3284
+ uncachedTexts.push(texts[i]);
3285
+ }
3286
+ if (uncachedTexts.length === 0) {
3287
+ return results;
3288
+ }
3289
+ let headers;
3290
+ if (apiKey) {
3291
+ headers = { "X-API-Key": apiKey };
3292
+ } else if (getToken) {
3293
+ const token = await getToken();
3294
+ if (!token) {
3295
+ throw new Error("No token available for embedding generation");
3296
+ }
3297
+ headers = { Authorization: `Bearer ${token}` };
3298
+ } else {
3299
+ throw new Error("Either apiKey or getToken must be provided");
3300
+ }
3301
+ const embeddingModel = model ?? DEFAULT_API_EMBEDDING_MODEL;
3302
+ let newEmbeddings;
3303
+ if (uncachedTexts.length <= chunkSize) {
3304
+ newEmbeddings = await generateEmbeddingsBatch(
3305
+ uncachedTexts,
3306
+ headers,
3307
+ baseUrl,
3308
+ embeddingModel,
3309
+ options.onUsage,
3310
+ options.maskInput
3311
+ );
3312
+ } else {
3313
+ const chunks = [];
3314
+ for (let i = 0; i < uncachedTexts.length; i += chunkSize) {
3315
+ chunks.push(uncachedTexts.slice(i, i + chunkSize));
3316
+ }
3317
+ const allEmbeddings = new Array(chunks.length);
3318
+ let nextIndex = 0;
3319
+ const worker = async () => {
3320
+ while (nextIndex < chunks.length) {
3321
+ const idx = nextIndex++;
3322
+ allEmbeddings[idx] = await generateEmbeddingsBatch(
3323
+ chunks[idx],
3324
+ headers,
3325
+ baseUrl,
3326
+ embeddingModel,
3327
+ options.onUsage,
3328
+ options.maskInput
3329
+ );
3330
+ }
3331
+ };
3332
+ const workers = Array.from(
3333
+ { length: Math.min(DEFAULT_EMBEDDING_BATCH_CONCURRENCY, chunks.length) },
3334
+ () => worker()
3335
+ );
3336
+ await Promise.all(workers);
3337
+ newEmbeddings = allEmbeddings.flat();
3338
+ }
3339
+ for (let i = 0; i < uncachedIndices.length; i++) {
3340
+ const f32Embedding = Float32Array.from(newEmbeddings[i]);
3341
+ results[uncachedIndices[i]] = Array.from(f32Embedding);
3342
+ if (cache) {
3343
+ cache.set(uncachedTexts[i], f32Embedding);
3344
+ }
3345
+ }
3346
+ return results;
3347
+ }
3348
+ var EMBED_MAX_ATTEMPTS, EmbeddingHttpError, DEFAULT_EMBEDDING_BATCH_SIZE, DEFAULT_EMBEDDING_BATCH_CONCURRENCY;
3349
+ var init_generate = __esm({
3350
+ "src/lib/memoryEngine/generate.ts"() {
3351
+ "use strict";
3352
+ init_client2();
3353
+ init_clientConfig();
3354
+ init_constants();
3355
+ EMBED_MAX_ATTEMPTS = 4;
3356
+ EmbeddingHttpError = class extends Error {
3357
+ constructor(message, status) {
3358
+ super(message);
3359
+ this.name = "EmbeddingHttpError";
3360
+ this.status = status;
3361
+ }
3362
+ };
3363
+ DEFAULT_EMBEDDING_BATCH_SIZE = 100;
3364
+ DEFAULT_EMBEDDING_BATCH_CONCURRENCY = 3;
3365
+ }
3366
+ });
3367
+
3368
+ // src/lib/memoryEngine/embeddings.ts
3369
+ async function embedMessage(ctx, messageId, options) {
3370
+ const message = await getMessageOp(ctx, messageId);
3371
+ if (!message) {
3372
+ return null;
3373
+ }
3374
+ if (message.vector && message.vector.length > 0) {
3375
+ return message;
3376
+ }
3377
+ const embedding = await generateEmbedding(message.content, options);
3378
+ const embeddingModel = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
3379
+ return updateMessageEmbeddingOp(ctx, messageId, embedding, embeddingModel);
3380
+ }
3381
+ async function embedAllMessages(ctx, options, filter) {
3382
+ const embeddingModel = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
3383
+ let embeddedCount = 0;
3384
+ const conversations = await getConversationsOp(ctx);
3385
+ const targetConversations = filter?.conversationId ? conversations.filter((c) => c.conversationId === filter.conversationId) : conversations;
3386
+ for (const conv of targetConversations) {
3387
+ const messages = await getMessagesOp(ctx, conv.conversationId);
3388
+ for (const message of messages) {
3389
+ if (message.vector && message.vector.length > 0) {
3390
+ continue;
3391
+ }
3392
+ if (filter?.roles && !filter.roles.includes(message.role)) {
3393
+ continue;
3394
+ }
3395
+ if (message.role === "system") {
3396
+ continue;
3397
+ }
3398
+ const minLength = filter?.minContentLength ?? DEFAULT_MIN_CONTENT_LENGTH;
3399
+ if (message.content.length < minLength) {
3400
+ continue;
3401
+ }
3402
+ try {
3403
+ const embedding = await generateEmbedding(message.content, options);
3404
+ await updateMessageEmbeddingOp(ctx, message.uniqueId, embedding, embeddingModel);
3405
+ embeddedCount++;
3406
+ } catch (error) {
3407
+ if (isFatalEmbeddingError(error)) throw error;
3408
+ getLogger().error(`Failed to embed message ${message.uniqueId}:`, error);
3409
+ }
3410
+ }
3411
+ }
3412
+ return embeddedCount;
3413
+ }
3414
+ async function chunkAndEmbedMessage(ctx, messageId, options) {
3415
+ const { chunkSize = DEFAULT_CHUNK_SIZE } = options;
3416
+ const message = await getMessageOp(ctx, messageId);
3417
+ if (!message) {
3418
+ return null;
3419
+ }
3420
+ if (message.chunks && message.chunks.length > 0) {
3421
+ return message;
3422
+ }
3423
+ const embeddingModel = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
3424
+ if (!shouldChunkMessage(message.content, chunkSize)) {
3425
+ const embedding = await generateEmbedding(message.content, options);
3426
+ return updateMessageEmbeddingOp(ctx, messageId, embedding, embeddingModel);
3427
+ }
3428
+ const textChunks = chunkText(message.content, options);
3429
+ const chunkTexts = textChunks.map((c) => c.text);
3430
+ const embeddings = await generateEmbeddings(chunkTexts, options);
3431
+ const messageChunks = textChunks.map((chunk, i) => ({
3432
+ text: chunk.text,
3433
+ vector: embeddings[i],
3434
+ startOffset: chunk.startOffset,
3435
+ endOffset: chunk.endOffset
3436
+ }));
3437
+ return updateMessageChunksOp(ctx, messageId, messageChunks, embeddingModel);
3438
+ }
3439
+ async function chunkAndEmbedAllMessages(ctx, options, filter) {
3440
+ const embeddingModel = options.model ?? DEFAULT_API_EMBEDDING_MODEL;
3441
+ const { chunkSize = DEFAULT_CHUNK_SIZE } = options;
3442
+ const minLength = filter?.minContentLength ?? DEFAULT_MIN_CONTENT_LENGTH;
3443
+ const conversations = await getConversationsOp(ctx);
3444
+ const targetConversations = filter?.conversationId ? conversations.filter((c) => c.conversationId === filter.conversationId) : conversations;
3445
+ const shortMessages = [];
3446
+ const longMessages = [];
3447
+ for (const conv of targetConversations) {
3448
+ const messages = await getMessagesOp(ctx, conv.conversationId);
3449
+ for (const message of messages) {
3450
+ const isStale = message.embeddingModel !== void 0 && message.embeddingModel !== null && message.embeddingModel !== embeddingModel;
3451
+ if (message.chunks && message.chunks.length > 0 && !isStale) continue;
3452
+ const hasVector = message.vector && message.vector.length > 0;
3453
+ if (hasVector && !filter?.rechunkExisting && !isStale) continue;
3454
+ if (filter?.roles && !filter.roles.includes(message.role)) continue;
3455
+ if (message.role === "system") continue;
3456
+ if (message.content.length < minLength) continue;
3457
+ if (shouldChunkMessage(message.content, chunkSize)) {
3458
+ longMessages.push({
3459
+ uniqueId: message.uniqueId,
3460
+ textChunks: chunkText(message.content, options)
3461
+ });
3462
+ } else {
3463
+ shortMessages.push({ uniqueId: message.uniqueId, content: message.content });
3464
+ }
3465
+ }
3466
+ }
3467
+ let embeddedCount = 0;
3468
+ if (shortMessages.length > 0) {
3469
+ try {
3470
+ const texts = shortMessages.map((m) => m.content);
3471
+ const embeddings = await generateEmbeddings(texts, options);
3472
+ for (let i = 0; i < shortMessages.length; i++) {
3473
+ try {
3474
+ await updateMessageEmbeddingOp(
3475
+ ctx,
3476
+ shortMessages[i].uniqueId,
3477
+ embeddings[i],
3478
+ embeddingModel
3479
+ );
3480
+ embeddedCount++;
3481
+ } catch (error) {
3482
+ getLogger().error(
3483
+ `Failed to save embedding for message ${shortMessages[i].uniqueId}:`,
3484
+ error
3485
+ );
3486
+ }
3487
+ }
3488
+ } catch (error) {
3489
+ if (isFatalEmbeddingError(error)) throw error;
3490
+ getLogger().error("Failed to batch-embed short messages:", error);
3491
+ }
3492
+ }
3493
+ for (const msg of longMessages) {
3494
+ try {
3495
+ const chunkTexts = msg.textChunks.map((c) => c.text);
3496
+ const embeddings = await generateEmbeddings(chunkTexts, options);
3497
+ const messageChunks = msg.textChunks.map((chunk, i) => ({
3498
+ text: chunk.text,
3499
+ vector: embeddings[i],
3500
+ startOffset: chunk.startOffset,
3501
+ endOffset: chunk.endOffset
3502
+ }));
3503
+ await updateMessageChunksOp(ctx, msg.uniqueId, messageChunks, embeddingModel);
3504
+ embeddedCount++;
3505
+ } catch (error) {
3506
+ if (isFatalEmbeddingError(error)) throw error;
3507
+ getLogger().error(`Failed to embed message ${msg.uniqueId}:`, error);
3508
+ }
3509
+ }
3510
+ return embeddedCount;
3511
+ }
3512
+ var DEFAULT_MIN_CONTENT_LENGTH;
3513
+ var init_embeddings = __esm({
3514
+ "src/lib/memoryEngine/embeddings.ts"() {
3515
+ "use strict";
3516
+ init_operations();
3517
+ init_logger();
3518
+ init_chunking();
3519
+ init_constants();
3520
+ init_generate();
3521
+ init_generate();
3522
+ DEFAULT_MIN_CONTENT_LENGTH = 10;
3523
+ }
3524
+ });
3525
+
3526
+ // src/lib/pii/patterns.ts
3527
+ function luhnCheck(digits) {
3528
+ let sum = 0;
3529
+ let alternate = false;
3530
+ for (let i = digits.length - 1; i >= 0; i--) {
3531
+ let n = parseInt(digits[i], 10);
3532
+ if (alternate) {
3533
+ n *= 2;
3534
+ if (n > 9) n -= 9;
3535
+ }
3536
+ sum += n;
3537
+ alternate = !alternate;
3538
+ }
3539
+ return sum % 10 === 0;
3540
+ }
3541
+ var PII_PATTERNS;
3542
+ var init_patterns = __esm({
3543
+ "src/lib/pii/patterns.ts"() {
3544
+ "use strict";
3545
+ PII_PATTERNS = [
3546
+ // Email — standard RFC-ish pattern.
3547
+ // Quantifiers are bounded (local-part ≤ 64, domain ≤ 255, TLD ≤ 24 —
3548
+ // all at or above real RFC 5321 limits) so the engine cannot backtrack
3549
+ // quadratically on adversarial input like "a.a.a.a…" with no "@".
3550
+ {
3551
+ category: "EMAIL",
3552
+ regex: /\b[a-zA-Z0-9._%+-]{1,64}@[a-zA-Z0-9.-]{1,255}\.[a-zA-Z]{2,24}\b/g
3553
+ },
3554
+ // SSN — US Social Security Number, dashed form (must run before phone)
3555
+ {
3556
+ category: "SSN",
3557
+ regex: /\b\d{3}-\d{2}-\d{4}\b/g,
3558
+ validate: (match) => {
3559
+ const parts = match.split("-");
3560
+ const area = parseInt(parts[0], 10);
3561
+ return area !== 0 && area !== 666 && area < 900;
3562
+ }
3563
+ },
3564
+ // SSN — dashless or space-separated form. Only redacted with an "SSN" /
3565
+ // "social security" cue nearby: a bare 9-digit run is too ambiguous
3566
+ // (ZIP+4, account numbers, etc.) to redact unconditionally.
3567
+ {
3568
+ category: "SSN",
3569
+ regex: /\b\d{3}[ ]?\d{2}[ ]?\d{4}\b/g,
3570
+ context: /(?:\bssn\b|\bsocial\s+security(?:\s+(?:number|no\.?|#))?\b)[^\d\n]{0,12}$/i,
3571
+ validate: (match) => {
3572
+ const digits = match.replace(/\D/g, "");
3573
+ if (digits.length !== 9) return false;
3574
+ const area = parseInt(digits.slice(0, 3), 10);
3575
+ return area !== 0 && area !== 666 && area < 900;
3576
+ }
3577
+ },
3578
+ // Credit card numbers — 13-19 contiguous digits or groups of 4 separated by spaces/dashes
3579
+ // Must run before phone to avoid partial matches
3580
+ {
3581
+ category: "CREDIT_CARD",
3582
+ regex: /\b\d{4}[\s-]\d{4}[\s-]\d{4}[\s-]\d{1,7}\b|\b\d{13,19}\b/g,
3583
+ validate: (match) => {
3584
+ const digits = match.replace(/\D/g, "");
3585
+ if (digits.length < 13 || digits.length > 19) return false;
3586
+ return luhnCheck(digits);
3587
+ }
3588
+ },
3589
+ // IPv4 addresses (must run before phone to avoid partial matches)
3590
+ {
3591
+ category: "IP_ADDRESS",
3592
+ regex: /\b(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\b/g,
3593
+ validate: (match) => {
3594
+ return match !== "0.0.0.0" && match !== "127.0.0.1" && match !== "255.255.255.255";
3595
+ }
3596
+ },
3597
+ // IPv6 addresses — full and compressed (::) forms. Each alternative requires
3598
+ // either a full 8-group address or a "::" compression, so ordinary
3599
+ // colon-separated text (timestamps like 12:34:56) does not match. Loopback
3600
+ // (::1) and unspecified (::) are excluded.
3601
+ {
3602
+ category: "IP_ADDRESS",
3603
+ regex: /(?:(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?::[0-9a-fA-F]{1,4}){1,6}|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:))/g,
3604
+ validate: (match) => match !== "::1" && match !== "::"
3605
+ },
3606
+ // Phone numbers. The separated form requires separator characters (dashes,
3607
+ // spaces, dots, parens) to avoid matching bare digit sequences that are
3608
+ // actually credit cards, IPs, or years. A second alternative matches E.164
3609
+ // (a leading "+" then 10–15 digits, e.g. +14155552671), which is
3610
+ // unambiguous; a bare 10-digit run with no "+" and no separators is
3611
+ // intentionally not matched to avoid false positives.
3612
+ {
3613
+ category: "PHONE",
3614
+ regex: /(?:\+\d{1,3}[\s.-])?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}\b|\+\d{10,15}\b/g
3615
+ },
3616
+ // API keys / secrets — long token with a key-like prefix. The validator
3617
+ // requires entropy (at least one digit, or a mix of upper- and lower-case)
3618
+ // so long all-lowercase prose identifiers like
3619
+ // "accessibility_is_important_for_everyone" or
3620
+ // "access-control-list-management-feature" are not redacted. Real keys and
3621
+ // tokens essentially always contain digits or mixed case.
3622
+ {
3623
+ category: "API_KEY",
3624
+ regex: /\b(?:sk|pk|api|key|token|secret|bearer|access)[_-]?[a-zA-Z0-9_-]{20,}\b/gi,
3625
+ validate: (match) => {
3626
+ const hasDigit = /\d/.test(match);
3627
+ const hasMixedCase = /[a-z]/.test(match) && /[A-Z]/.test(match);
3628
+ return hasDigit || hasMixedCase;
3629
+ }
3630
+ },
3631
+ // US street addresses — house number + Title-Case street name + suffix.
3632
+ // Intentionally NOT case-insensitive: the `[A-Z][a-z]+` guard requires
3633
+ // properly-capitalized street words, so "123 main street", "100 MAIN
3634
+ // STREET" and prose like "3 blocks down the road" / "5 minutes to drive"
3635
+ // are not treated as addresses. Whitespace is `[ \t]` only (no newline
3636
+ // spanning), and the suffix must end the segment (punctuation / newline /
3637
+ // end of string) so "Driveway" or "Wayfair" don't match on the suffix.
3638
+ {
3639
+ category: "US_ADDRESS",
3640
+ regex: /\b\d{1,5}[ \t]+(?:[A-Z][a-z]+[ \t]+){1,3}(?:St(?:reet)?|Ave(?:nue)?|Blvd|Boulevard|Dr(?:ive)?|Ln|Lane|Rd|Road|Ct|Court|Pl(?:ace)?|Way|Cir(?:cle)?|Pkwy|Parkway|Hwy|Highway)\.?(?=[\s,.;:!?)]|$)/g,
3641
+ validate: (match) => {
3642
+ return !/^0/.test(match.trim());
3643
+ }
3644
+ },
3645
+ // Dates of birth — common US date formats. Only redacted when a birth-date
3646
+ // cue ("DOB", "born", "birthday", "date of birth") appears just before the
3647
+ // date, so ordinary calendar dates ("meeting 12/25/2024", deadlines,
3648
+ // invoices) are left intact for the model. A calendar validator also rejects
3649
+ // impossible dates like 02/31/1990.
3650
+ {
3651
+ category: "DATE_OF_BIRTH",
3652
+ regex: /\b(?:(?:0?[1-9]|1[0-2])[/-](?:0?[1-9]|[12]\d|3[01])[/-](?:19|20)\d{2})\b/g,
3653
+ context: /(?:\bdob\b|\bd\.?o\.?b\.?|\bborn\b|\bbirth\s?date\b|\bbirthdate\b|\bbirthday\b|\bdate\s+of\s+birth\b)[^\d\n]{0,12}$/i,
3654
+ validate: (match) => {
3655
+ const m = match.match(/(\d{1,2})[/-](\d{1,2})[/-](\d{4})/);
3656
+ if (!m) return false;
3657
+ const month = parseInt(m[1], 10);
3658
+ const day = parseInt(m[2], 10);
3659
+ const year = parseInt(m[3], 10);
3660
+ const isLeap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
3661
+ const daysInMonth = [31, isLeap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
3662
+ return month >= 1 && month <= 12 && day >= 1 && day <= daysInMonth[month - 1];
3663
+ }
3664
+ }
3665
+ ];
3666
+ }
3667
+ });
3668
+
3669
+ // src/lib/pii/redactor.ts
3670
+ function escapeRegExp(value) {
3671
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3672
+ }
3673
+ function isWordChar(ch) {
3674
+ return /[A-Za-z0-9_]/.test(ch) || ch.charCodeAt(0) > 127;
3675
+ }
3676
+ function isPiiRedactor(value) {
3677
+ return typeof value === "object" && value !== null && typeof value.redactMessages === "function" && typeof value.deAnonymize === "function";
3678
+ }
3679
+ function resolvePiiRedactor(piiRedaction) {
3680
+ if (piiRedaction === true) return new PiiRedactor();
3681
+ if (!piiRedaction) return void 0;
3682
+ if (isPiiRedactor(piiRedaction)) return piiRedaction;
3683
+ console.warn(
3684
+ "[PiiRedactor] `piiRedaction` is neither `true` nor a PiiRedactor instance; PII redaction is DISABLED for this request."
3685
+ );
3686
+ return void 0;
3687
+ }
3688
+ function createStreamingDeAnonymizer(redactor, emit) {
3689
+ let buffer = "";
3690
+ const trailingFragment = /\[[A-Za-z0-9_]*$/;
3691
+ return {
3692
+ push(chunk) {
3693
+ if (!chunk) return;
3694
+ buffer += chunk;
3695
+ const m = buffer.match(trailingFragment);
3696
+ if (!m || m.index === void 0) {
3697
+ emit(redactor.deAnonymize(buffer));
3698
+ buffer = "";
3699
+ } else if (m.index > 0) {
3700
+ emit(redactor.deAnonymize(buffer.slice(0, m.index)));
3701
+ buffer = buffer.slice(m.index);
3702
+ }
3703
+ },
3704
+ flush() {
3705
+ if (buffer) {
3706
+ emit(redactor.deAnonymize(buffer));
3707
+ buffer = "";
3708
+ }
3709
+ }
3710
+ };
3711
+ }
3712
+ var PiiRedactor;
3713
+ var init_redactor = __esm({
3714
+ "src/lib/pii/redactor.ts"() {
3715
+ "use strict";
2766
3716
  init_patterns();
2767
3717
  PiiRedactor = class {
2768
3718
  constructor(options = {}) {
@@ -3225,6 +4175,29 @@ var init_redactor = __esm({
3225
4175
  }
3226
4176
  });
3227
4177
 
4178
+ // src/lib/chat/endpointOverride.ts
4179
+ function validateEndpointOverride(override) {
4180
+ const trimmed = override.trim();
4181
+ if (trimmed === "") {
4182
+ return {
4183
+ valid: false,
4184
+ message: 'endpointOverride must be a non-empty, root-relative path (e.g. "/api/v1/utility/responses"); received an empty or whitespace-only string'
4185
+ };
4186
+ }
4187
+ if (trimmed.startsWith("//") || trimmed.includes("://")) {
4188
+ return {
4189
+ valid: false,
4190
+ message: `endpointOverride must be a root-relative path (e.g. "/api/v1/utility/responses"), not a protocol-relative or absolute URL; received "${trimmed}"`
4191
+ };
4192
+ }
4193
+ return { valid: true, endpoint: trimmed.startsWith("/") ? trimmed : `/${trimmed}` };
4194
+ }
4195
+ var init_endpointOverride = __esm({
4196
+ "src/lib/chat/endpointOverride.ts"() {
4197
+ "use strict";
4198
+ }
4199
+ });
4200
+
3228
4201
  // src/lib/db/entities/types.ts
3229
4202
  function normalizeEntityName(name) {
3230
4203
  return name.trim().toLowerCase();
@@ -4354,6 +5327,14 @@ async function resolvePortalAuthHeaders(auth, tag) {
4354
5327
  }
4355
5328
  async function callPortalJsonCompletion(req) {
4356
5329
  const log = getLogger();
5330
+ let endpoint = "/api/v1/chat/completions";
5331
+ if (req.endpointOverride !== void 0) {
5332
+ const overrideValidation = validateEndpointOverride(req.endpointOverride);
5333
+ if (!overrideValidation.valid) {
5334
+ throw new Error(overrideValidation.message);
5335
+ }
5336
+ endpoint = overrideValidation.endpoint;
5337
+ }
4357
5338
  const maxAttempts = Math.max(1, req.maxAttempts ?? 3);
4358
5339
  const startedAt = Date.now();
4359
5340
  const overBudget = () => req.totalTimeoutMs !== void 0 && Date.now() - startedAt >= req.totalTimeoutMs;
@@ -4369,7 +5350,7 @@ async function callPortalJsonCompletion(req) {
4369
5350
  Math.min(req.timeoutMs ?? 6e4, req.totalTimeoutMs - (Date.now() - startedAt))
4370
5351
  )
4371
5352
  } : req;
4372
- const outcome = await attemptPortalJson(attemptReq);
5353
+ const outcome = await attemptPortalJson(attemptReq, endpoint);
4373
5354
  if (outcome.kind === "ok") return outcome.value;
4374
5355
  if (outcome.kind === "terminal") {
4375
5356
  log.warn(`[${req.tag}] ${outcome.reason}`);
@@ -4392,7 +5373,7 @@ async function callPortalJsonCompletion(req) {
4392
5373
  }
4393
5374
  return null;
4394
5375
  }
4395
- async function attemptPortalJson(req) {
5376
+ async function attemptPortalJson(req, endpoint) {
4396
5377
  const baseUrl = req.baseUrl ?? defaultBaseUrl();
4397
5378
  const fetchImpl = req.fetchFn ?? fetch;
4398
5379
  const timeoutMs = req.timeoutMs ?? 6e4;
@@ -4417,7 +5398,7 @@ async function attemptPortalJson(req) {
4417
5398
  if (!supportsJsonObjectFormat) delete requestBody.response_format;
4418
5399
  let response;
4419
5400
  try {
4420
- response = await fetchImpl(`${baseUrl}/api/v1/chat/completions`, {
5401
+ response = await fetchImpl(`${baseUrl}${endpoint}`, {
4421
5402
  method: "POST",
4422
5403
  headers: { ...authHeaders, "Content-Type": "application/json" },
4423
5404
  body: JSON.stringify(requestBody),
@@ -4514,6 +5495,7 @@ var init_portalLlm = __esm({
4514
5495
  "src/lib/memory/portalLlm.ts"() {
4515
5496
  "use strict";
4516
5497
  init_clientConfig();
5498
+ init_endpointOverride();
4517
5499
  init_logger();
4518
5500
  RESPONSE_FORMAT_OK = /* @__PURE__ */ new Set(["openai", "inclusionai", "deepseek"]);
4519
5501
  RESPONSE_SCHEMA_OK = /* @__PURE__ */ new Set(["openai"]);
@@ -7409,151 +8391,26 @@ __export(index_exports, {
7409
8391
  useProjects: () => useProjects,
7410
8392
  useSettings: () => useSettings,
7411
8393
  useSubscription: () => useSubscription,
7412
- useTools: () => useTools,
7413
- useUIInteraction: () => useUIInteraction,
7414
- useVoice: () => useVoice,
7415
- useWalletBinding: () => useWalletBinding,
7416
- userPreferencesStorageSchema: () => userPreferencesStorageSchema,
7417
- walk: () => walk,
7418
- webPlatformStorage: () => webPlatformStorage,
7419
- writeEncryptedFile: () => writeEncryptedFile
7420
- });
7421
- module.exports = __toCommonJS(index_exports);
7422
-
7423
- // src/lib/chat/resumeStream.ts
7424
- init_clientConfig();
7425
-
7426
- // src/client/core/serverSentEvents.gen.ts
7427
- function createSseClient({
7428
- onRequest,
7429
- onSseError,
7430
- onSseEvent,
7431
- responseTransformer,
7432
- responseValidator,
7433
- sseDefaultRetryDelay,
7434
- sseMaxRetryAttempts,
7435
- sseMaxRetryDelay,
7436
- sseSleepFn,
7437
- url,
7438
- ...options
7439
- }) {
7440
- let lastEventId;
7441
- const sleep4 = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
7442
- const createStream = async function* () {
7443
- let retryDelay = sseDefaultRetryDelay ?? 3e3;
7444
- let attempt = 0;
7445
- const signal = options.signal ?? new AbortController().signal;
7446
- while (true) {
7447
- if (signal.aborted) break;
7448
- attempt++;
7449
- const headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers);
7450
- if (lastEventId !== void 0) {
7451
- headers.set("Last-Event-ID", lastEventId);
7452
- }
7453
- try {
7454
- const requestInit = {
7455
- redirect: "follow",
7456
- ...options,
7457
- body: options.serializedBody,
7458
- headers,
7459
- signal
7460
- };
7461
- let request = new Request(url, requestInit);
7462
- if (onRequest) {
7463
- request = await onRequest(url, requestInit);
7464
- }
7465
- const _fetch = options.fetch ?? globalThis.fetch;
7466
- const response = await _fetch(request);
7467
- if (!response.ok) throw new Error(`SSE failed: ${response.status} ${response.statusText}`);
7468
- if (!response.body) throw new Error("No body in SSE response");
7469
- const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
7470
- let buffer = "";
7471
- const abortHandler = () => {
7472
- try {
7473
- reader.cancel();
7474
- } catch {
7475
- }
7476
- };
7477
- signal.addEventListener("abort", abortHandler);
7478
- try {
7479
- while (true) {
7480
- const { done, value } = await reader.read();
7481
- if (done) break;
7482
- buffer += value;
7483
- buffer = buffer.replace(/\r\n?/g, "\n");
7484
- const chunks = buffer.split("\n\n");
7485
- buffer = chunks.pop() ?? "";
7486
- for (const chunk of chunks) {
7487
- const lines = chunk.split("\n");
7488
- const dataLines = [];
7489
- let eventName;
7490
- for (const line of lines) {
7491
- if (line.startsWith("data:")) {
7492
- dataLines.push(line.replace(/^data:\s*/, ""));
7493
- } else if (line.startsWith("event:")) {
7494
- eventName = line.replace(/^event:\s*/, "");
7495
- } else if (line.startsWith("id:")) {
7496
- lastEventId = line.replace(/^id:\s*/, "");
7497
- } else if (line.startsWith("retry:")) {
7498
- const parsed = Number.parseInt(line.replace(/^retry:\s*/, ""), 10);
7499
- if (!Number.isNaN(parsed)) {
7500
- retryDelay = parsed;
7501
- }
7502
- }
7503
- }
7504
- let data;
7505
- let parsedJson = false;
7506
- if (dataLines.length) {
7507
- const rawData = dataLines.join("\n");
7508
- try {
7509
- data = JSON.parse(rawData);
7510
- parsedJson = true;
7511
- } catch {
7512
- data = rawData;
7513
- }
7514
- }
7515
- if (parsedJson) {
7516
- if (responseValidator) {
7517
- await responseValidator(data);
7518
- }
7519
- if (responseTransformer) {
7520
- data = await responseTransformer(data);
7521
- }
7522
- }
7523
- onSseEvent?.({
7524
- data,
7525
- event: eventName,
7526
- id: lastEventId,
7527
- retry: retryDelay
7528
- });
7529
- if (dataLines.length) {
7530
- yield data;
7531
- }
7532
- }
7533
- }
7534
- } finally {
7535
- signal.removeEventListener("abort", abortHandler);
7536
- reader.releaseLock();
7537
- }
7538
- break;
7539
- } catch (error) {
7540
- onSseError?.(error);
7541
- if (sseMaxRetryAttempts !== void 0 && attempt >= sseMaxRetryAttempts) {
7542
- break;
7543
- }
7544
- const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 3e4);
7545
- await sleep4(backoff);
7546
- }
7547
- }
7548
- };
7549
- const stream = createStream();
7550
- return { stream };
7551
- }
8394
+ useTools: () => useTools,
8395
+ useUIInteraction: () => useUIInteraction,
8396
+ useVoice: () => useVoice,
8397
+ useWalletBinding: () => useWalletBinding,
8398
+ userPreferencesStorageSchema: () => userPreferencesStorageSchema,
8399
+ walk: () => walk,
8400
+ webPlatformStorage: () => webPlatformStorage,
8401
+ writeEncryptedFile: () => writeEncryptedFile
8402
+ });
8403
+ module.exports = __toCommonJS(index_exports);
8404
+
8405
+ // src/lib/chat/resumeStream.ts
8406
+ init_clientConfig();
7552
8407
 
7553
8408
  // src/lib/chat/toolLoop.ts
8409
+ init_serverSentEvents_gen();
7554
8410
  init_clientConfig();
7555
8411
  init_embeddings();
7556
8412
  init_redactor();
8413
+ init_endpointOverride();
7557
8414
 
7558
8415
  // src/lib/chat/runHooks.ts
7559
8416
  function composeHooks(hooks) {
@@ -9733,22 +10590,6 @@ function linkAbortSignals(a, b) {
9733
10590
  }
9734
10591
  };
9735
10592
  }
9736
- function validateEndpointOverride(override) {
9737
- const trimmed = override.trim();
9738
- if (trimmed === "") {
9739
- return {
9740
- valid: false,
9741
- message: 'endpointOverride must be a non-empty, root-relative path (e.g. "/api/v1/utility/responses"); received an empty or whitespace-only string'
9742
- };
9743
- }
9744
- if (trimmed.startsWith("//") || trimmed.includes("://")) {
9745
- return {
9746
- valid: false,
9747
- message: `endpointOverride must be a root-relative path (e.g. "/api/v1/utility/responses"), not a protocol-relative or absolute URL; received "${trimmed}"`
9748
- };
9749
- }
9750
- return { valid: true, endpoint: trimmed.startsWith("/") ? trimmed : `/${trimmed}` };
9751
- }
9752
10593
  async function runToolLoop(options) {
9753
10594
  const {
9754
10595
  model,
@@ -16457,6 +17298,9 @@ When a memory refers to one of these, reuse the EXACT existing name (same spelli
16457
17298
  ...options.apiKey !== void 0 && { apiKey: options.apiKey },
16458
17299
  ...options.getToken !== void 0 && { getToken: options.getToken },
16459
17300
  ...options.baseUrl !== void 0 && { baseUrl: options.baseUrl },
17301
+ ...options.endpointOverride !== void 0 && {
17302
+ endpointOverride: options.endpointOverride
17303
+ },
16460
17304
  model: options.model ?? DEFAULT_EXTRACTION_MODEL,
16461
17305
  systemPrompt: SYSTEM_PROMPT6,
16462
17306
  userMessage: `${vocabularyNote}Memories:
@@ -24290,1296 +25134,557 @@ async function exportMarkdownToPdf(markdown, options) {
24290
25134
  for (const row of rows) {
24291
25135
  renderRow2(row, "normal");
24292
25136
  }
24293
- cursorY += SPACING.MD;
24294
- break;
24295
- }
24296
- case "space": {
24297
- cursorY += SPACING.MD;
24298
- break;
24299
- }
24300
- default:
24301
- if (token.raw.trim()) {
24302
- renderWrappedText(token.raw.trim(), opts.margins.left, cw, opts.fontSize);
24303
- cursorY += SPACING.SM;
24304
- }
24305
- break;
24306
- }
24307
- }
24308
- if (opts.pageNumbers) {
24309
- addPageNumbers(doc, pageW, pageH);
24310
- }
24311
- opts.onProgress?.({ stage: "complete", percent: 100 });
24312
- return doc.output("blob");
24313
- }
24314
-
24315
- // src/react/useExportPdf.ts
24316
- var import_react10 = require("react");
24317
- var DEFAULT_FILENAME2 = "document.pdf";
24318
- function triggerDownload(blob, filename) {
24319
- const url = URL.createObjectURL(blob);
24320
- const a = document.createElement("a");
24321
- a.href = url;
24322
- a.download = filename;
24323
- document.body.appendChild(a);
24324
- a.click();
24325
- document.body.removeChild(a);
24326
- setTimeout(() => URL.revokeObjectURL(url), 100);
24327
- }
24328
- function toError(err) {
24329
- return err instanceof Error ? err : new Error(String(err));
24330
- }
24331
- function useExportPdf() {
24332
- const [isExporting, setIsExporting] = (0, import_react10.useState)(false);
24333
- const [progress, setProgress] = (0, import_react10.useState)(null);
24334
- const [error, setError] = (0, import_react10.useState)(null);
24335
- const wrappedExportElement = (0, import_react10.useCallback)(
24336
- async (element, options) => {
24337
- setIsExporting(true);
24338
- setError(null);
24339
- setProgress({ stage: "preparing", percent: 0 });
24340
- try {
24341
- return await exportElementToPdf(element, {
24342
- ...options,
24343
- onProgress: setProgress
24344
- });
24345
- } catch (err) {
24346
- const processed = toError(err);
24347
- setError(processed);
24348
- throw processed;
24349
- } finally {
24350
- setIsExporting(false);
24351
- }
24352
- },
24353
- []
24354
- );
24355
- const wrappedExportMarkdown = (0, import_react10.useCallback)(
24356
- async (markdown, options) => {
24357
- setIsExporting(true);
24358
- setError(null);
24359
- setProgress({ stage: "preparing", percent: 0 });
24360
- try {
24361
- return await exportMarkdownToPdf(markdown, {
24362
- ...options,
24363
- onProgress: setProgress
24364
- });
24365
- } catch (err) {
24366
- const processed = toError(err);
24367
- setError(processed);
24368
- throw processed;
24369
- } finally {
24370
- setIsExporting(false);
24371
- }
24372
- },
24373
- []
24374
- );
24375
- const downloadElementAsPdf = (0, import_react10.useCallback)(
24376
- async (element, options) => {
24377
- const blob = await wrappedExportElement(element, options);
24378
- triggerDownload(blob, options?.filename ?? DEFAULT_FILENAME2);
24379
- },
24380
- [wrappedExportElement]
24381
- );
24382
- const downloadMarkdownAsPdf = (0, import_react10.useCallback)(
24383
- async (markdown, options) => {
24384
- const blob = await wrappedExportMarkdown(markdown, options);
24385
- triggerDownload(blob, options?.filename ?? DEFAULT_FILENAME2);
24386
- },
24387
- [wrappedExportMarkdown]
24388
- );
24389
- const wrappedRenderToCanvas = (0, import_react10.useCallback)(
24390
- async (element) => {
24391
- setIsExporting(true);
24392
- setError(null);
24393
- setProgress({ stage: "preparing", percent: 0 });
24394
- try {
24395
- const canvas = await renderElementToCanvas(element, { onProgress: setProgress });
24396
- return canvas;
24397
- } catch (err) {
24398
- const processed = toError(err);
24399
- setError(processed);
24400
- throw processed;
24401
- } finally {
24402
- setIsExporting(false);
24403
- }
24404
- },
24405
- []
24406
- );
24407
- return {
24408
- exportElementToPdf: wrappedExportElement,
24409
- exportMarkdownToPdf: wrappedExportMarkdown,
24410
- downloadElementAsPdf,
24411
- downloadMarkdownAsPdf,
24412
- renderElementToCanvas: wrappedRenderToCanvas,
24413
- isExporting,
24414
- progress,
24415
- error
24416
- };
24417
- }
24418
-
24419
- // src/react/useOCR.ts
24420
- var import_react11 = require("react");
24421
- var import_tesseract = __toESM(require("tesseract.js"));
24422
- init_logger();
24423
- function useOCR() {
24424
- const [isProcessing, setIsProcessing] = (0, import_react11.useState)(false);
24425
- const [error, setError] = (0, import_react11.useState)(null);
24426
- const extractOCRContext = (0, import_react11.useCallback)(async (files) => {
24427
- setIsProcessing(true);
24428
- setError(null);
24429
- try {
24430
- if (files.length === 0) {
24431
- return null;
24432
- }
24433
- const contexts = await Promise.all(
24434
- files.map(async (file) => {
24435
- try {
24436
- let imagesToProcess = [];
24437
- const language = file.language || "eng";
24438
- const filename = file.filename || (file.url instanceof File ? file.url.name : "");
24439
- let isPdf = false;
24440
- if (typeof file.url === "string") {
24441
- isPdf = file.url.toLowerCase().endsWith(".pdf") || (filename?.toLowerCase().endsWith(".pdf") ?? false);
24442
- } else if (file.url instanceof Blob) {
24443
- isPdf = file.url.type === "application/pdf" || (filename?.toLowerCase().endsWith(".pdf") ?? false);
24444
- }
24445
- if (isPdf) {
24446
- let pdfUrl;
24447
- let shouldRevoke = false;
24448
- if (typeof file.url === "string") {
24449
- pdfUrl = file.url;
24450
- } else {
24451
- pdfUrl = URL.createObjectURL(file.url);
24452
- shouldRevoke = true;
24453
- }
24454
- try {
24455
- const pdfImages = await convertPdfToImages(pdfUrl);
24456
- imagesToProcess = pdfImages;
24457
- } catch (e) {
24458
- getLogger().error("Failed to convert PDF to images", e);
24459
- throw e;
24460
- } finally {
24461
- if (shouldRevoke) {
24462
- URL.revokeObjectURL(pdfUrl);
24463
- }
24464
- }
24465
- } else {
24466
- imagesToProcess = [file.url];
24467
- }
24468
- const pageTexts = [];
24469
- for (const image of imagesToProcess) {
24470
- const result = await import_tesseract.default.recognize(image, language);
24471
- pageTexts.push(result.data.text);
24472
- }
24473
- const text12 = pageTexts.join("\n\n");
24474
- if (!text12.trim()) {
24475
- getLogger().warn(`No text found in OCR source ${filename || "unknown"}`);
24476
- return null;
24477
- }
24478
- return `[Context from OCR attachment ${filename || "unknown"}]:
24479
- ${text12}`;
24480
- } catch (err) {
24481
- getLogger().error(`Failed to process OCR for ${file.filename || "unknown"}:`, err);
24482
- return null;
24483
- }
24484
- })
24485
- );
24486
- const mergedContext = contexts.filter(Boolean).join("\n\n");
24487
- return mergedContext || null;
24488
- } catch (err) {
24489
- const processedError = err instanceof Error ? err : new Error(String(err));
24490
- setError(processedError);
24491
- throw processedError;
24492
- } finally {
24493
- setIsProcessing(false);
24494
- }
24495
- }, []);
24496
- return {
24497
- extractOCRContext,
24498
- isProcessing,
24499
- error
24500
- };
24501
- }
24502
-
24503
- // src/react/usePdf.ts
24504
- var import_react12 = require("react");
24505
- init_logger();
24506
- var PDF_MIME_TYPE = "application/pdf";
24507
- function usePdf() {
24508
- const [isProcessing, setIsProcessing] = (0, import_react12.useState)(false);
24509
- const [error, setError] = (0, import_react12.useState)(null);
24510
- const extractPdfContext = (0, import_react12.useCallback)(async (files) => {
24511
- setIsProcessing(true);
24512
- setError(null);
24513
- try {
24514
- const pdfFiles = files.filter(
24515
- (file) => file.mediaType === PDF_MIME_TYPE || file.filename?.toLowerCase().endsWith(".pdf")
24516
- );
24517
- if (pdfFiles.length === 0) {
24518
- return null;
25137
+ cursorY += SPACING.MD;
25138
+ break;
24519
25139
  }
24520
- const contexts = await Promise.all(
24521
- pdfFiles.map(async (file) => {
24522
- try {
24523
- const text12 = await extractTextFromPdf(file.url);
24524
- if (!text12.trim()) {
24525
- getLogger().warn(`No text found in PDF ${file.filename}`);
24526
- return null;
24527
- }
24528
- return `[Context from PDF attachment ${file.filename}]:
24529
- ${text12}`;
24530
- } catch (err) {
24531
- getLogger().error(`Failed to process PDF ${file.filename}:`, err);
24532
- return null;
24533
- }
24534
- })
24535
- );
24536
- const mergedContext = contexts.filter(Boolean).join("\n\n");
24537
- return mergedContext || null;
24538
- } catch (err) {
24539
- const processedError = err instanceof Error ? err : new Error(String(err));
24540
- setError(processedError);
24541
- throw processedError;
24542
- } finally {
24543
- setIsProcessing(false);
25140
+ case "space": {
25141
+ cursorY += SPACING.MD;
25142
+ break;
25143
+ }
25144
+ default:
25145
+ if (token.raw.trim()) {
25146
+ renderWrappedText(token.raw.trim(), opts.margins.left, cw, opts.fontSize);
25147
+ cursorY += SPACING.SM;
25148
+ }
25149
+ break;
24544
25150
  }
24545
- }, []);
24546
- return {
24547
- extractPdfContext,
24548
- isProcessing,
24549
- error
24550
- };
24551
- }
24552
-
24553
- // src/react/useVoice.ts
24554
- var import_react13 = require("react");
24555
- function getOnDeviceSpeechRecognition() {
24556
- if (typeof window === "undefined") return null;
24557
- if (!/iPhone|iPad|iPod/.test(navigator.userAgent)) return null;
24558
- const SR = window.SpeechRecognition ?? window.webkitSpeechRecognition;
24559
- return SR ?? null;
24560
- }
24561
- var SUPPORTED_MIME_TYPES = [
24562
- "audio/webm;codecs=opus",
24563
- "audio/webm",
24564
- "audio/mp4",
24565
- "audio/ogg;codecs=opus",
24566
- "audio/ogg"
24567
- ];
24568
- function getSupportedMimeType() {
24569
- if (typeof MediaRecorder === "undefined") {
24570
- return "audio/webm";
24571
25151
  }
24572
- for (const type of SUPPORTED_MIME_TYPES) {
24573
- if (MediaRecorder.isTypeSupported(type)) {
24574
- return type;
24575
- }
25152
+ if (opts.pageNumbers) {
25153
+ addPageNumbers(doc, pageW, pageH);
24576
25154
  }
24577
- return "audio/webm";
25155
+ opts.onProgress?.({ stage: "complete", percent: 100 });
25156
+ return doc.output("blob");
24578
25157
  }
24579
- var SAMPLE_RATE = 16e3;
24580
- async function audioToFloat32(blob) {
24581
- const arrayBuffer = await blob.arrayBuffer();
24582
- const audioContext = new AudioContext({ sampleRate: SAMPLE_RATE });
24583
- try {
24584
- const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
24585
- if (audioBuffer.numberOfChannels === 1) {
24586
- return audioBuffer.getChannelData(0);
24587
- }
24588
- const length = audioBuffer.length;
24589
- const mono = new Float32Array(length);
24590
- const channels = audioBuffer.numberOfChannels;
24591
- for (let ch = 0; ch < channels; ch++) {
24592
- const data = audioBuffer.getChannelData(ch);
24593
- for (let i = 0; i < length; i++) {
24594
- mono[i] += data[i];
24595
- }
24596
- }
24597
- for (let i = 0; i < length; i++) {
24598
- mono[i] /= channels;
24599
- }
24600
- return mono;
24601
- } finally {
24602
- await audioContext.close();
24603
- }
25158
+
25159
+ // src/react/useExportPdf.ts
25160
+ var import_react10 = require("react");
25161
+ var DEFAULT_FILENAME2 = "document.pdf";
25162
+ function triggerDownload(blob, filename) {
25163
+ const url = URL.createObjectURL(blob);
25164
+ const a = document.createElement("a");
25165
+ a.href = url;
25166
+ a.download = filename;
25167
+ document.body.appendChild(a);
25168
+ a.click();
25169
+ document.body.removeChild(a);
25170
+ setTimeout(() => URL.revokeObjectURL(url), 100);
24604
25171
  }
24605
- function useVoice(options) {
24606
- const [isRecording, setIsRecording] = (0, import_react13.useState)(false);
24607
- const [isTranscribing, setIsTranscribing] = (0, import_react13.useState)(false);
24608
- const [isModelLoaded, setIsModelLoaded] = (0, import_react13.useState)(false);
24609
- const [isLoadingModel, setIsLoadingModel] = (0, import_react13.useState)(false);
24610
- const [recording, setRecording] = (0, import_react13.useState)(null);
24611
- const [transcription, setTranscription] = (0, import_react13.useState)(null);
24612
- const [error, setError] = (0, import_react13.useState)(null);
24613
- const mediaRecorderRef = (0, import_react13.useRef)(null);
24614
- const mediaStreamRef = (0, import_react13.useRef)(null);
24615
- const chunksRef = (0, import_react13.useRef)([]);
24616
- const startTimeRef = (0, import_react13.useRef)(0);
24617
- const pipelineRef = (0, import_react13.useRef)(null);
24618
- const modelNameRef = (0, import_react13.useRef)(null);
24619
- const getModelName = (0, import_react13.useCallback)(() => {
24620
- const model = options?.model ?? "whisper-tiny";
24621
- return `onnx-community/${model}`;
24622
- }, [options?.model]);
24623
- const loadPipeline = (0, import_react13.useCallback)(async () => {
24624
- const modelName = getModelName();
24625
- if (pipelineRef.current && modelNameRef.current === modelName) {
24626
- return pipelineRef.current;
24627
- }
24628
- setIsLoadingModel(true);
24629
- setError(null);
24630
- try {
24631
- const { pipeline } = await import("@huggingface/transformers");
24632
- const transcriber = await pipeline("automatic-speech-recognition", modelName, {
24633
- dtype: "q4",
24634
- device: "wasm",
24635
- progress_callback: options?.onModelProgress ? (progress) => {
24636
- if (progress.file && progress.progress !== null && progress.progress !== void 0) {
24637
- options.onModelProgress({
24638
- file: progress.file,
24639
- progress: progress.progress / 100,
24640
- loaded: progress.loaded ?? 0,
24641
- total: progress.total ?? 0
24642
- });
24643
- }
24644
- } : void 0
24645
- });
24646
- pipelineRef.current = transcriber;
24647
- modelNameRef.current = modelName;
24648
- setIsModelLoaded(true);
24649
- return pipelineRef.current;
24650
- } catch (err) {
24651
- const processedError = err instanceof Error ? err : new Error("Failed to load Whisper model");
24652
- setError(processedError);
24653
- throw processedError;
24654
- } finally {
24655
- setIsLoadingModel(false);
24656
- }
24657
- }, [getModelName, options?.onModelProgress]);
24658
- const preloadModel = (0, import_react13.useCallback)(async () => {
24659
- await loadPipeline();
24660
- }, [loadPipeline]);
24661
- const disposeModel = (0, import_react13.useCallback)(async () => {
24662
- const pipe = pipelineRef.current;
24663
- if (pipe?.dispose) {
24664
- await pipe.dispose();
24665
- }
24666
- pipelineRef.current = null;
24667
- modelNameRef.current = null;
24668
- setIsModelLoaded(false);
24669
- }, []);
24670
- const startRecording = (0, import_react13.useCallback)(async () => {
24671
- setError(null);
24672
- setRecording(null);
24673
- setTranscription(null);
24674
- try {
24675
- const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
24676
- mediaStreamRef.current = stream;
24677
- const mimeType = getSupportedMimeType();
24678
- const recorder = new MediaRecorder(stream, { mimeType });
24679
- mediaRecorderRef.current = recorder;
24680
- chunksRef.current = [];
24681
- recorder.ondataavailable = (e) => {
24682
- if (e.data.size > 0) {
24683
- chunksRef.current.push(e.data);
24684
- }
24685
- };
24686
- recorder.start();
24687
- startTimeRef.current = Date.now();
24688
- setIsRecording(true);
24689
- } catch (err) {
24690
- const processedError = err instanceof Error ? err : new Error("Failed to start recording");
24691
- setError(processedError);
24692
- throw processedError;
24693
- }
24694
- }, []);
24695
- const stopRecording = (0, import_react13.useCallback)(async () => {
24696
- return new Promise((resolve, reject) => {
24697
- const recorder = mediaRecorderRef.current;
24698
- if (!recorder || recorder.state === "inactive") {
24699
- const err = new Error("No active recording");
24700
- setError(err);
24701
- reject(err);
24702
- return;
24703
- }
24704
- recorder.onstop = () => {
24705
- const mimeType = recorder.mimeType || "audio/webm";
24706
- const blob = new Blob(chunksRef.current, { type: mimeType });
24707
- const duration = Date.now() - startTimeRef.current;
24708
- mediaStreamRef.current?.getTracks().forEach((t) => t.stop());
24709
- mediaStreamRef.current = null;
24710
- mediaRecorderRef.current = null;
24711
- const result = { blob, duration, mimeType };
24712
- setRecording(result);
24713
- setIsRecording(false);
24714
- resolve(result);
24715
- };
24716
- recorder.onerror = () => {
24717
- const err = new Error("Recording failed");
24718
- setError(err);
24719
- setIsRecording(false);
24720
- reject(err);
24721
- };
24722
- recorder.stop();
24723
- });
24724
- }, []);
24725
- const transcribe = (0, import_react13.useCallback)(
24726
- async (rec) => {
24727
- const target = rec ?? recording;
24728
- if (!target) {
24729
- const err = new Error("No recording to transcribe");
24730
- setError(err);
24731
- throw err;
25172
+ function toError(err) {
25173
+ return err instanceof Error ? err : new Error(String(err));
25174
+ }
25175
+ function useExportPdf() {
25176
+ const [isExporting, setIsExporting] = (0, import_react10.useState)(false);
25177
+ const [progress, setProgress] = (0, import_react10.useState)(null);
25178
+ const [error, setError] = (0, import_react10.useState)(null);
25179
+ const wrappedExportElement = (0, import_react10.useCallback)(
25180
+ async (element, options) => {
25181
+ setIsExporting(true);
25182
+ setError(null);
25183
+ setProgress({ stage: "preparing", percent: 0 });
25184
+ try {
25185
+ return await exportElementToPdf(element, {
25186
+ ...options,
25187
+ onProgress: setProgress
25188
+ });
25189
+ } catch (err) {
25190
+ const processed = toError(err);
25191
+ setError(processed);
25192
+ throw processed;
25193
+ } finally {
25194
+ setIsExporting(false);
24732
25195
  }
24733
- setIsTranscribing(true);
25196
+ },
25197
+ []
25198
+ );
25199
+ const wrappedExportMarkdown = (0, import_react10.useCallback)(
25200
+ async (markdown, options) => {
25201
+ setIsExporting(true);
24734
25202
  setError(null);
25203
+ setProgress({ stage: "preparing", percent: 0 });
24735
25204
  try {
24736
- const pipe = await loadPipeline();
24737
- const audio = await audioToFloat32(target.blob);
24738
- const result = await pipe(audio, {
24739
- language: options?.language,
24740
- return_timestamps: true
25205
+ return await exportMarkdownToPdf(markdown, {
25206
+ ...options,
25207
+ onProgress: setProgress
24741
25208
  });
24742
- const transcriptionResult = {
24743
- text: result.text.trim(),
24744
- chunks: result.chunks
24745
- };
24746
- setTranscription(transcriptionResult);
24747
- return transcriptionResult;
24748
25209
  } catch (err) {
24749
- const processedError = err instanceof Error ? err : new Error("Transcription failed");
24750
- setError(processedError);
24751
- throw processedError;
25210
+ const processed = toError(err);
25211
+ setError(processed);
25212
+ throw processed;
24752
25213
  } finally {
24753
- setIsTranscribing(false);
25214
+ setIsExporting(false);
24754
25215
  }
24755
25216
  },
24756
- [recording, loadPipeline, options?.language]
25217
+ []
24757
25218
  );
24758
- const nativeSpeechAvailable = (0, import_react13.useMemo)(() => getOnDeviceSpeechRecognition() !== null, []);
24759
- const [isNativeListening, setIsNativeListening] = (0, import_react13.useState)(false);
24760
- const nativeRecognitionRef = (0, import_react13.useRef)(null);
24761
- const nativeTextRef = (0, import_react13.useRef)("");
24762
- const nativeResolveRef = (0, import_react13.useRef)(null);
24763
- const startNativeTranscription = (0, import_react13.useCallback)(() => {
24764
- const SR = getOnDeviceSpeechRecognition();
24765
- if (!SR) return;
24766
- nativeTextRef.current = "";
24767
- setError(null);
24768
- const recognition = new SR();
24769
- recognition.continuous = true;
24770
- recognition.interimResults = false;
24771
- recognition.lang = options?.language ?? "";
24772
- recognition.onresult = (event) => {
24773
- let text12 = "";
24774
- for (let i = 0; i < event.results.length; i++) {
24775
- const result = event.results[i];
24776
- if (result && result.isFinal && result[0]) {
24777
- text12 += result[0].transcript + " ";
24778
- }
24779
- }
24780
- nativeTextRef.current = text12.trim();
24781
- };
24782
- recognition.onerror = (event) => {
24783
- if (event.error !== "aborted" && event.error !== "no-speech") {
24784
- setError(new Error(`Speech recognition error: ${event.error}`));
24785
- }
24786
- };
24787
- recognition.onend = () => {
24788
- setIsNativeListening(false);
24789
- nativeRecognitionRef.current = null;
24790
- const resolve = nativeResolveRef.current;
24791
- if (resolve) {
24792
- nativeResolveRef.current = null;
24793
- resolve({ text: nativeTextRef.current });
24794
- }
24795
- };
24796
- nativeRecognitionRef.current = recognition;
24797
- recognition.start();
24798
- setIsNativeListening(true);
24799
- }, [options?.language]);
24800
- const stopNativeTranscription = (0, import_react13.useCallback)(() => {
24801
- return new Promise((resolve) => {
24802
- const recognition = nativeRecognitionRef.current;
24803
- if (!recognition) {
24804
- resolve({ text: nativeTextRef.current || "" });
24805
- return;
25219
+ const downloadElementAsPdf = (0, import_react10.useCallback)(
25220
+ async (element, options) => {
25221
+ const blob = await wrappedExportElement(element, options);
25222
+ triggerDownload(blob, options?.filename ?? DEFAULT_FILENAME2);
25223
+ },
25224
+ [wrappedExportElement]
25225
+ );
25226
+ const downloadMarkdownAsPdf = (0, import_react10.useCallback)(
25227
+ async (markdown, options) => {
25228
+ const blob = await wrappedExportMarkdown(markdown, options);
25229
+ triggerDownload(blob, options?.filename ?? DEFAULT_FILENAME2);
25230
+ },
25231
+ [wrappedExportMarkdown]
25232
+ );
25233
+ const wrappedRenderToCanvas = (0, import_react10.useCallback)(
25234
+ async (element) => {
25235
+ setIsExporting(true);
25236
+ setError(null);
25237
+ setProgress({ stage: "preparing", percent: 0 });
25238
+ try {
25239
+ const canvas = await renderElementToCanvas(element, { onProgress: setProgress });
25240
+ return canvas;
25241
+ } catch (err) {
25242
+ const processed = toError(err);
25243
+ setError(processed);
25244
+ throw processed;
25245
+ } finally {
25246
+ setIsExporting(false);
24806
25247
  }
24807
- nativeResolveRef.current = resolve;
24808
- recognition.stop();
24809
- });
24810
- }, []);
24811
- const abortNativeTranscription = (0, import_react13.useCallback)(() => {
24812
- const recognition = nativeRecognitionRef.current;
24813
- if (recognition) {
24814
- nativeResolveRef.current = null;
24815
- recognition.abort();
24816
- nativeRecognitionRef.current = null;
24817
- setIsNativeListening(false);
24818
- }
24819
- }, []);
25248
+ },
25249
+ []
25250
+ );
24820
25251
  return {
24821
- isRecording,
24822
- startRecording,
24823
- stopRecording,
24824
- isTranscribing,
24825
- transcribe,
24826
- preloadModel,
24827
- disposeModel,
24828
- isModelLoaded,
24829
- isLoadingModel,
24830
- recording,
24831
- transcription,
24832
- error,
24833
- nativeSpeechAvailable,
24834
- startNativeTranscription,
24835
- stopNativeTranscription,
24836
- abortNativeTranscription,
24837
- isNativeListening
25252
+ exportElementToPdf: wrappedExportElement,
25253
+ exportMarkdownToPdf: wrappedExportMarkdown,
25254
+ downloadElementAsPdf,
25255
+ downloadMarkdownAsPdf,
25256
+ renderElementToCanvas: wrappedRenderToCanvas,
25257
+ isExporting,
25258
+ progress,
25259
+ error
24838
25260
  };
24839
25261
  }
24840
25262
 
24841
- // src/react/useCredits.ts
24842
- var import_react14 = require("react");
24843
-
24844
- // src/client/core/bodySerializer.gen.ts
24845
- var jsonBodySerializer = {
24846
- bodySerializer: (body) => JSON.stringify(body, (_key, value) => typeof value === "bigint" ? value.toString() : value)
24847
- };
24848
-
24849
- // src/client/core/pathSerializer.gen.ts
24850
- var separatorArrayExplode = (style) => {
24851
- switch (style) {
24852
- case "label":
24853
- return ".";
24854
- case "matrix":
24855
- return ";";
24856
- case "simple":
24857
- return ",";
24858
- default:
24859
- return "&";
24860
- }
24861
- };
24862
- var separatorArrayNoExplode = (style) => {
24863
- switch (style) {
24864
- case "form":
24865
- return ",";
24866
- case "pipeDelimited":
24867
- return "|";
24868
- case "spaceDelimited":
24869
- return "%20";
24870
- default:
24871
- return ",";
24872
- }
24873
- };
24874
- var separatorObjectExplode = (style) => {
24875
- switch (style) {
24876
- case "label":
24877
- return ".";
24878
- case "matrix":
24879
- return ";";
24880
- case "simple":
24881
- return ",";
24882
- default:
24883
- return "&";
24884
- }
24885
- };
24886
- var serializeArrayParam = ({
24887
- allowReserved,
24888
- explode,
24889
- name,
24890
- style,
24891
- value
24892
- }) => {
24893
- if (!explode) {
24894
- const joinedValues2 = (allowReserved ? value : value.map((v) => encodeURIComponent(v))).join(separatorArrayNoExplode(style));
24895
- switch (style) {
24896
- case "label":
24897
- return `.${joinedValues2}`;
24898
- case "matrix":
24899
- return `;${name}=${joinedValues2}`;
24900
- case "simple":
24901
- return joinedValues2;
24902
- default:
24903
- return `${name}=${joinedValues2}`;
24904
- }
24905
- }
24906
- const separator = separatorArrayExplode(style);
24907
- const joinedValues = value.map((v) => {
24908
- if (style === "label" || style === "simple") {
24909
- return allowReserved ? v : encodeURIComponent(v);
24910
- }
24911
- return serializePrimitiveParam({
24912
- allowReserved,
24913
- name,
24914
- value: v
24915
- });
24916
- }).join(separator);
24917
- return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
24918
- };
24919
- var serializePrimitiveParam = ({
24920
- allowReserved,
24921
- name,
24922
- value
24923
- }) => {
24924
- if (value === void 0 || value === null) {
24925
- return "";
24926
- }
24927
- if (typeof value === "object") {
24928
- throw new Error(
24929
- "Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these."
24930
- );
24931
- }
24932
- return `${name}=${allowReserved ? value : encodeURIComponent(value)}`;
24933
- };
24934
- var serializeObjectParam = ({
24935
- allowReserved,
24936
- explode,
24937
- name,
24938
- style,
24939
- value,
24940
- valueOnly
24941
- }) => {
24942
- if (value instanceof Date) {
24943
- return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`;
24944
- }
24945
- if (style !== "deepObject" && !explode) {
24946
- let values = [];
24947
- Object.entries(value).forEach(([key, v]) => {
24948
- values = [...values, key, allowReserved ? v : encodeURIComponent(v)];
24949
- });
24950
- const joinedValues2 = values.join(",");
24951
- switch (style) {
24952
- case "form":
24953
- return `${name}=${joinedValues2}`;
24954
- case "label":
24955
- return `.${joinedValues2}`;
24956
- case "matrix":
24957
- return `;${name}=${joinedValues2}`;
24958
- default:
24959
- return joinedValues2;
24960
- }
24961
- }
24962
- const separator = separatorObjectExplode(style);
24963
- const joinedValues = Object.entries(value).map(
24964
- ([key, v]) => serializePrimitiveParam({
24965
- allowReserved,
24966
- name: style === "deepObject" ? `${name}[${key}]` : key,
24967
- value: v
24968
- })
24969
- ).join(separator);
24970
- return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
24971
- };
24972
-
24973
- // src/client/core/utils.gen.ts
24974
- function getValidRequestBody(options) {
24975
- const hasBody = options.body !== void 0;
24976
- const isSerializedBody = hasBody && options.bodySerializer;
24977
- if (isSerializedBody) {
24978
- if ("serializedBody" in options) {
24979
- const hasSerializedBody = options.serializedBody !== void 0 && options.serializedBody !== "";
24980
- return hasSerializedBody ? options.serializedBody : null;
25263
+ // src/react/useOCR.ts
25264
+ var import_react11 = require("react");
25265
+ var import_tesseract = __toESM(require("tesseract.js"));
25266
+ init_logger();
25267
+ function useOCR() {
25268
+ const [isProcessing, setIsProcessing] = (0, import_react11.useState)(false);
25269
+ const [error, setError] = (0, import_react11.useState)(null);
25270
+ const extractOCRContext = (0, import_react11.useCallback)(async (files) => {
25271
+ setIsProcessing(true);
25272
+ setError(null);
25273
+ try {
25274
+ if (files.length === 0) {
25275
+ return null;
25276
+ }
25277
+ const contexts = await Promise.all(
25278
+ files.map(async (file) => {
25279
+ try {
25280
+ let imagesToProcess = [];
25281
+ const language = file.language || "eng";
25282
+ const filename = file.filename || (file.url instanceof File ? file.url.name : "");
25283
+ let isPdf = false;
25284
+ if (typeof file.url === "string") {
25285
+ isPdf = file.url.toLowerCase().endsWith(".pdf") || (filename?.toLowerCase().endsWith(".pdf") ?? false);
25286
+ } else if (file.url instanceof Blob) {
25287
+ isPdf = file.url.type === "application/pdf" || (filename?.toLowerCase().endsWith(".pdf") ?? false);
25288
+ }
25289
+ if (isPdf) {
25290
+ let pdfUrl;
25291
+ let shouldRevoke = false;
25292
+ if (typeof file.url === "string") {
25293
+ pdfUrl = file.url;
25294
+ } else {
25295
+ pdfUrl = URL.createObjectURL(file.url);
25296
+ shouldRevoke = true;
25297
+ }
25298
+ try {
25299
+ const pdfImages = await convertPdfToImages(pdfUrl);
25300
+ imagesToProcess = pdfImages;
25301
+ } catch (e) {
25302
+ getLogger().error("Failed to convert PDF to images", e);
25303
+ throw e;
25304
+ } finally {
25305
+ if (shouldRevoke) {
25306
+ URL.revokeObjectURL(pdfUrl);
25307
+ }
25308
+ }
25309
+ } else {
25310
+ imagesToProcess = [file.url];
25311
+ }
25312
+ const pageTexts = [];
25313
+ for (const image of imagesToProcess) {
25314
+ const result = await import_tesseract.default.recognize(image, language);
25315
+ pageTexts.push(result.data.text);
25316
+ }
25317
+ const text12 = pageTexts.join("\n\n");
25318
+ if (!text12.trim()) {
25319
+ getLogger().warn(`No text found in OCR source ${filename || "unknown"}`);
25320
+ return null;
25321
+ }
25322
+ return `[Context from OCR attachment ${filename || "unknown"}]:
25323
+ ${text12}`;
25324
+ } catch (err) {
25325
+ getLogger().error(`Failed to process OCR for ${file.filename || "unknown"}:`, err);
25326
+ return null;
25327
+ }
25328
+ })
25329
+ );
25330
+ const mergedContext = contexts.filter(Boolean).join("\n\n");
25331
+ return mergedContext || null;
25332
+ } catch (err) {
25333
+ const processedError = err instanceof Error ? err : new Error(String(err));
25334
+ setError(processedError);
25335
+ throw processedError;
25336
+ } finally {
25337
+ setIsProcessing(false);
24981
25338
  }
24982
- return options.body !== "" ? options.body : null;
24983
- }
24984
- if (hasBody) {
24985
- return options.body;
24986
- }
24987
- return void 0;
25339
+ }, []);
25340
+ return {
25341
+ extractOCRContext,
25342
+ isProcessing,
25343
+ error
25344
+ };
24988
25345
  }
24989
25346
 
24990
- // src/client/core/auth.gen.ts
24991
- var getAuthToken = async (auth, callback) => {
24992
- const token = typeof callback === "function" ? await callback(auth) : callback;
24993
- if (!token) {
24994
- return;
24995
- }
24996
- if (auth.scheme === "bearer") {
24997
- return `Bearer ${token}`;
24998
- }
24999
- if (auth.scheme === "basic") {
25000
- return `Basic ${btoa(token)}`;
25001
- }
25002
- return token;
25003
- };
25004
-
25005
- // src/client/client/utils.gen.ts
25006
- var PATH_PARAM_RE = /\{[^{}]+\}/g;
25007
- var defaultPathSerializer = ({ path, url: _url }) => {
25008
- let url = _url;
25009
- const matches = _url.match(PATH_PARAM_RE);
25010
- if (matches) {
25011
- for (const match of matches) {
25012
- let explode = false;
25013
- let name = match.substring(1, match.length - 1);
25014
- let style = "simple";
25015
- if (name.endsWith("*")) {
25016
- explode = true;
25017
- name = name.substring(0, name.length - 1);
25018
- }
25019
- if (name.startsWith(".")) {
25020
- name = name.substring(1);
25021
- style = "label";
25022
- } else if (name.startsWith(";")) {
25023
- name = name.substring(1);
25024
- style = "matrix";
25025
- }
25026
- const value = path[name];
25027
- if (value === void 0 || value === null) {
25028
- continue;
25029
- }
25030
- if (Array.isArray(value)) {
25031
- url = url.replace(match, serializeArrayParam({ explode, name, style, value }));
25032
- continue;
25033
- }
25034
- if (typeof value === "object") {
25035
- url = url.replace(
25036
- match,
25037
- serializeObjectParam({
25038
- explode,
25039
- name,
25040
- style,
25041
- value,
25042
- valueOnly: true
25043
- })
25044
- );
25045
- continue;
25046
- }
25047
- if (style === "matrix") {
25048
- url = url.replace(
25049
- match,
25050
- `;${serializePrimitiveParam({
25051
- name,
25052
- value
25053
- })}`
25054
- );
25055
- continue;
25056
- }
25057
- const replaceValue = encodeURIComponent(
25058
- style === "label" ? `.${value}` : value
25347
+ // src/react/usePdf.ts
25348
+ var import_react12 = require("react");
25349
+ init_logger();
25350
+ var PDF_MIME_TYPE = "application/pdf";
25351
+ function usePdf() {
25352
+ const [isProcessing, setIsProcessing] = (0, import_react12.useState)(false);
25353
+ const [error, setError] = (0, import_react12.useState)(null);
25354
+ const extractPdfContext = (0, import_react12.useCallback)(async (files) => {
25355
+ setIsProcessing(true);
25356
+ setError(null);
25357
+ try {
25358
+ const pdfFiles = files.filter(
25359
+ (file) => file.mediaType === PDF_MIME_TYPE || file.filename?.toLowerCase().endsWith(".pdf")
25059
25360
  );
25060
- url = url.replace(match, replaceValue);
25061
- }
25062
- }
25063
- return url;
25064
- };
25065
- var createQuerySerializer = ({
25066
- parameters = {},
25067
- ...args
25068
- } = {}) => {
25069
- const querySerializer = (queryParams) => {
25070
- const search = [];
25071
- if (queryParams && typeof queryParams === "object") {
25072
- for (const name in queryParams) {
25073
- const value = queryParams[name];
25074
- if (value === void 0 || value === null) {
25075
- continue;
25076
- }
25077
- const options = parameters[name] || args;
25078
- if (Array.isArray(value)) {
25079
- const serializedArray = serializeArrayParam({
25080
- allowReserved: options.allowReserved,
25081
- explode: true,
25082
- name,
25083
- style: "form",
25084
- value,
25085
- ...options.array
25086
- });
25087
- if (serializedArray) search.push(serializedArray);
25088
- } else if (typeof value === "object") {
25089
- const serializedObject = serializeObjectParam({
25090
- allowReserved: options.allowReserved,
25091
- explode: true,
25092
- name,
25093
- style: "deepObject",
25094
- value,
25095
- ...options.object
25096
- });
25097
- if (serializedObject) search.push(serializedObject);
25098
- } else {
25099
- const serializedPrimitive = serializePrimitiveParam({
25100
- allowReserved: options.allowReserved,
25101
- name,
25102
- value
25103
- });
25104
- if (serializedPrimitive) search.push(serializedPrimitive);
25105
- }
25361
+ if (pdfFiles.length === 0) {
25362
+ return null;
25106
25363
  }
25364
+ const contexts = await Promise.all(
25365
+ pdfFiles.map(async (file) => {
25366
+ try {
25367
+ const text12 = await extractTextFromPdf(file.url);
25368
+ if (!text12.trim()) {
25369
+ getLogger().warn(`No text found in PDF ${file.filename}`);
25370
+ return null;
25371
+ }
25372
+ return `[Context from PDF attachment ${file.filename}]:
25373
+ ${text12}`;
25374
+ } catch (err) {
25375
+ getLogger().error(`Failed to process PDF ${file.filename}:`, err);
25376
+ return null;
25377
+ }
25378
+ })
25379
+ );
25380
+ const mergedContext = contexts.filter(Boolean).join("\n\n");
25381
+ return mergedContext || null;
25382
+ } catch (err) {
25383
+ const processedError = err instanceof Error ? err : new Error(String(err));
25384
+ setError(processedError);
25385
+ throw processedError;
25386
+ } finally {
25387
+ setIsProcessing(false);
25107
25388
  }
25108
- return search.join("&");
25389
+ }, []);
25390
+ return {
25391
+ extractPdfContext,
25392
+ isProcessing,
25393
+ error
25109
25394
  };
25110
- return querySerializer;
25111
- };
25112
- var getParseAs = (contentType) => {
25113
- if (!contentType) {
25114
- return "stream";
25115
- }
25116
- const cleanContent = contentType.split(";")[0]?.trim();
25117
- if (!cleanContent) {
25118
- return;
25119
- }
25120
- if (cleanContent.startsWith("application/json") || cleanContent.endsWith("+json")) {
25121
- return "json";
25122
- }
25123
- if (cleanContent === "multipart/form-data") {
25124
- return "formData";
25125
- }
25126
- if (["application/", "audio/", "image/", "video/"].some((type) => cleanContent.startsWith(type))) {
25127
- return "blob";
25128
- }
25129
- if (cleanContent.startsWith("text/")) {
25130
- return "text";
25131
- }
25132
- return;
25133
- };
25134
- var checkForExistence = (options, name) => {
25135
- if (!name) {
25136
- return false;
25137
- }
25138
- if (options.headers.has(name) || options.query?.[name] || options.headers.get("Cookie")?.includes(`${name}=`)) {
25139
- return true;
25395
+ }
25396
+
25397
+ // src/react/useVoice.ts
25398
+ var import_react13 = require("react");
25399
+ function getOnDeviceSpeechRecognition() {
25400
+ if (typeof window === "undefined") return null;
25401
+ if (!/iPhone|iPad|iPod/.test(navigator.userAgent)) return null;
25402
+ const SR = window.SpeechRecognition ?? window.webkitSpeechRecognition;
25403
+ return SR ?? null;
25404
+ }
25405
+ var SUPPORTED_MIME_TYPES = [
25406
+ "audio/webm;codecs=opus",
25407
+ "audio/webm",
25408
+ "audio/mp4",
25409
+ "audio/ogg;codecs=opus",
25410
+ "audio/ogg"
25411
+ ];
25412
+ function getSupportedMimeType() {
25413
+ if (typeof MediaRecorder === "undefined") {
25414
+ return "audio/webm";
25140
25415
  }
25141
- return false;
25142
- };
25143
- async function setAuthParams(options) {
25144
- for (const auth of options.security ?? []) {
25145
- if (checkForExistence(options, auth.name)) {
25146
- continue;
25147
- }
25148
- const token = await getAuthToken(auth, options.auth);
25149
- if (!token) {
25150
- continue;
25151
- }
25152
- const name = auth.name ?? "Authorization";
25153
- switch (auth.in) {
25154
- case "query":
25155
- if (!options.query) {
25156
- options.query = {};
25157
- }
25158
- options.query[name] = token;
25159
- break;
25160
- case "cookie":
25161
- options.headers.append("Cookie", `${name}=${token}`);
25162
- break;
25163
- case "header":
25164
- default:
25165
- options.headers.set(name, token);
25166
- break;
25416
+ for (const type of SUPPORTED_MIME_TYPES) {
25417
+ if (MediaRecorder.isTypeSupported(type)) {
25418
+ return type;
25167
25419
  }
25168
25420
  }
25421
+ return "audio/webm";
25169
25422
  }
25170
- var buildUrl = (options) => {
25171
- const url = getUrl({
25172
- baseUrl: options.baseUrl,
25173
- path: options.path,
25174
- query: options.query,
25175
- querySerializer: typeof options.querySerializer === "function" ? options.querySerializer : createQuerySerializer(options.querySerializer),
25176
- url: options.url
25177
- });
25178
- return url;
25179
- };
25180
- var getUrl = ({
25181
- baseUrl,
25182
- path,
25183
- query,
25184
- querySerializer,
25185
- url: _url
25186
- }) => {
25187
- const pathUrl = _url.startsWith("/") ? _url : `/${_url}`;
25188
- let url = (baseUrl ?? "") + pathUrl;
25189
- if (path) {
25190
- url = defaultPathSerializer({ path, url });
25191
- }
25192
- let search = query ? querySerializer(query) : "";
25193
- if (search.startsWith("?")) {
25194
- search = search.substring(1);
25195
- }
25196
- if (search) {
25197
- url += `?${search}`;
25198
- }
25199
- return url;
25200
- };
25201
- var mergeConfigs = (a, b) => {
25202
- const config = { ...a, ...b };
25203
- if (config.baseUrl?.endsWith("/")) {
25204
- config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1);
25205
- }
25206
- config.headers = mergeHeaders(a.headers, b.headers);
25207
- return config;
25208
- };
25209
- var headersEntries = (headers) => {
25210
- const entries = [];
25211
- headers.forEach((value, key) => {
25212
- entries.push([key, value]);
25213
- });
25214
- return entries;
25215
- };
25216
- var mergeHeaders = (...headers) => {
25217
- const mergedHeaders = new Headers();
25218
- for (const header of headers) {
25219
- if (!header || typeof header !== "object") {
25220
- continue;
25423
+ var SAMPLE_RATE = 16e3;
25424
+ async function audioToFloat32(blob) {
25425
+ const arrayBuffer = await blob.arrayBuffer();
25426
+ const audioContext = new AudioContext({ sampleRate: SAMPLE_RATE });
25427
+ try {
25428
+ const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
25429
+ if (audioBuffer.numberOfChannels === 1) {
25430
+ return audioBuffer.getChannelData(0);
25221
25431
  }
25222
- const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header);
25223
- for (const [key, value] of iterator) {
25224
- if (value === null) {
25225
- mergedHeaders.delete(key);
25226
- } else if (Array.isArray(value)) {
25227
- for (const v of value) {
25228
- mergedHeaders.append(key, v);
25229
- }
25230
- } else if (value !== void 0) {
25231
- mergedHeaders.set(
25232
- key,
25233
- typeof value === "object" ? JSON.stringify(value) : value
25234
- );
25432
+ const length = audioBuffer.length;
25433
+ const mono = new Float32Array(length);
25434
+ const channels = audioBuffer.numberOfChannels;
25435
+ for (let ch = 0; ch < channels; ch++) {
25436
+ const data = audioBuffer.getChannelData(ch);
25437
+ for (let i = 0; i < length; i++) {
25438
+ mono[i] += data[i];
25235
25439
  }
25236
25440
  }
25237
- }
25238
- return mergedHeaders;
25239
- };
25240
- var Interceptors = class {
25241
- constructor() {
25242
- this.fns = [];
25243
- }
25244
- clear() {
25245
- this.fns = [];
25246
- }
25247
- eject(id) {
25248
- const index = this.getInterceptorIndex(id);
25249
- if (this.fns[index]) {
25250
- this.fns[index] = null;
25251
- }
25252
- }
25253
- exists(id) {
25254
- const index = this.getInterceptorIndex(id);
25255
- return Boolean(this.fns[index]);
25256
- }
25257
- getInterceptorIndex(id) {
25258
- if (typeof id === "number") {
25259
- return this.fns[id] ? id : -1;
25260
- }
25261
- return this.fns.indexOf(id);
25262
- }
25263
- update(id, fn) {
25264
- const index = this.getInterceptorIndex(id);
25265
- if (this.fns[index]) {
25266
- this.fns[index] = fn;
25267
- return id;
25441
+ for (let i = 0; i < length; i++) {
25442
+ mono[i] /= channels;
25268
25443
  }
25269
- return false;
25270
- }
25271
- use(fn) {
25272
- this.fns.push(fn);
25273
- return this.fns.length - 1;
25274
- }
25275
- };
25276
- var createInterceptors = () => ({
25277
- error: new Interceptors(),
25278
- request: new Interceptors(),
25279
- response: new Interceptors()
25280
- });
25281
- var defaultQuerySerializer = createQuerySerializer({
25282
- allowReserved: false,
25283
- array: {
25284
- explode: true,
25285
- style: "form"
25286
- },
25287
- object: {
25288
- explode: true,
25289
- style: "deepObject"
25444
+ return mono;
25445
+ } finally {
25446
+ await audioContext.close();
25290
25447
  }
25291
- });
25292
- var defaultHeaders = {
25293
- "Content-Type": "application/json"
25294
- };
25295
- var createConfig = (override = {}) => ({
25296
- ...jsonBodySerializer,
25297
- headers: defaultHeaders,
25298
- parseAs: "auto",
25299
- querySerializer: defaultQuerySerializer,
25300
- ...override
25301
- });
25302
-
25303
- // src/client/client/client.gen.ts
25304
- var createClient = (config = {}) => {
25305
- let _config = mergeConfigs(createConfig(), config);
25306
- const getConfig = () => ({ ..._config });
25307
- const setConfig = (config2) => {
25308
- _config = mergeConfigs(_config, config2);
25309
- return getConfig();
25310
- };
25311
- const interceptors = createInterceptors();
25312
- const beforeRequest = async (options) => {
25313
- const opts = {
25314
- ..._config,
25315
- ...options,
25316
- fetch: options.fetch ?? _config.fetch ?? globalThis.fetch,
25317
- headers: mergeHeaders(_config.headers, options.headers),
25318
- serializedBody: void 0
25319
- };
25320
- if (opts.security) {
25321
- await setAuthParams(opts);
25322
- }
25323
- if (opts.requestValidator) {
25324
- await opts.requestValidator(opts);
25448
+ }
25449
+ function useVoice(options) {
25450
+ const [isRecording, setIsRecording] = (0, import_react13.useState)(false);
25451
+ const [isTranscribing, setIsTranscribing] = (0, import_react13.useState)(false);
25452
+ const [isModelLoaded, setIsModelLoaded] = (0, import_react13.useState)(false);
25453
+ const [isLoadingModel, setIsLoadingModel] = (0, import_react13.useState)(false);
25454
+ const [recording, setRecording] = (0, import_react13.useState)(null);
25455
+ const [transcription, setTranscription] = (0, import_react13.useState)(null);
25456
+ const [error, setError] = (0, import_react13.useState)(null);
25457
+ const mediaRecorderRef = (0, import_react13.useRef)(null);
25458
+ const mediaStreamRef = (0, import_react13.useRef)(null);
25459
+ const chunksRef = (0, import_react13.useRef)([]);
25460
+ const startTimeRef = (0, import_react13.useRef)(0);
25461
+ const pipelineRef = (0, import_react13.useRef)(null);
25462
+ const modelNameRef = (0, import_react13.useRef)(null);
25463
+ const getModelName = (0, import_react13.useCallback)(() => {
25464
+ const model = options?.model ?? "whisper-tiny";
25465
+ return `onnx-community/${model}`;
25466
+ }, [options?.model]);
25467
+ const loadPipeline = (0, import_react13.useCallback)(async () => {
25468
+ const modelName = getModelName();
25469
+ if (pipelineRef.current && modelNameRef.current === modelName) {
25470
+ return pipelineRef.current;
25325
25471
  }
25326
- if (opts.body !== void 0 && opts.bodySerializer) {
25327
- opts.serializedBody = opts.bodySerializer(opts.body);
25472
+ setIsLoadingModel(true);
25473
+ setError(null);
25474
+ try {
25475
+ const { pipeline } = await import("@huggingface/transformers");
25476
+ const transcriber = await pipeline("automatic-speech-recognition", modelName, {
25477
+ dtype: "q4",
25478
+ device: "wasm",
25479
+ progress_callback: options?.onModelProgress ? (progress) => {
25480
+ if (progress.file && progress.progress !== null && progress.progress !== void 0) {
25481
+ options.onModelProgress({
25482
+ file: progress.file,
25483
+ progress: progress.progress / 100,
25484
+ loaded: progress.loaded ?? 0,
25485
+ total: progress.total ?? 0
25486
+ });
25487
+ }
25488
+ } : void 0
25489
+ });
25490
+ pipelineRef.current = transcriber;
25491
+ modelNameRef.current = modelName;
25492
+ setIsModelLoaded(true);
25493
+ return pipelineRef.current;
25494
+ } catch (err) {
25495
+ const processedError = err instanceof Error ? err : new Error("Failed to load Whisper model");
25496
+ setError(processedError);
25497
+ throw processedError;
25498
+ } finally {
25499
+ setIsLoadingModel(false);
25328
25500
  }
25329
- if (opts.body === void 0 || opts.serializedBody === "") {
25330
- opts.headers.delete("Content-Type");
25501
+ }, [getModelName, options?.onModelProgress]);
25502
+ const preloadModel = (0, import_react13.useCallback)(async () => {
25503
+ await loadPipeline();
25504
+ }, [loadPipeline]);
25505
+ const disposeModel = (0, import_react13.useCallback)(async () => {
25506
+ const pipe = pipelineRef.current;
25507
+ if (pipe?.dispose) {
25508
+ await pipe.dispose();
25331
25509
  }
25332
- const resolvedOpts = opts;
25333
- const url = buildUrl(resolvedOpts);
25334
- return { opts: resolvedOpts, url };
25335
- };
25336
- const request = async (options) => {
25337
- const throwOnError = options.throwOnError ?? _config.throwOnError;
25338
- let response;
25510
+ pipelineRef.current = null;
25511
+ modelNameRef.current = null;
25512
+ setIsModelLoaded(false);
25513
+ }, []);
25514
+ const startRecording = (0, import_react13.useCallback)(async () => {
25515
+ setError(null);
25516
+ setRecording(null);
25517
+ setTranscription(null);
25339
25518
  try {
25340
- const { opts, url } = await beforeRequest(options);
25341
- for (const fn of interceptors.request.fns) {
25342
- if (fn) {
25343
- await fn(opts);
25519
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
25520
+ mediaStreamRef.current = stream;
25521
+ const mimeType = getSupportedMimeType();
25522
+ const recorder = new MediaRecorder(stream, { mimeType });
25523
+ mediaRecorderRef.current = recorder;
25524
+ chunksRef.current = [];
25525
+ recorder.ondataavailable = (e) => {
25526
+ if (e.data.size > 0) {
25527
+ chunksRef.current.push(e.data);
25344
25528
  }
25345
- }
25346
- const _fetch = opts.fetch;
25347
- const requestInit = {
25348
- ...opts,
25349
- body: getValidRequestBody(opts)
25350
25529
  };
25351
- response = await _fetch(url, requestInit);
25352
- for (const fn of interceptors.response.fns) {
25353
- if (fn) {
25354
- response = await fn(response, opts);
25355
- }
25530
+ recorder.start();
25531
+ startTimeRef.current = Date.now();
25532
+ setIsRecording(true);
25533
+ } catch (err) {
25534
+ const processedError = err instanceof Error ? err : new Error("Failed to start recording");
25535
+ setError(processedError);
25536
+ throw processedError;
25537
+ }
25538
+ }, []);
25539
+ const stopRecording = (0, import_react13.useCallback)(async () => {
25540
+ return new Promise((resolve, reject) => {
25541
+ const recorder = mediaRecorderRef.current;
25542
+ if (!recorder || recorder.state === "inactive") {
25543
+ const err = new Error("No active recording");
25544
+ setError(err);
25545
+ reject(err);
25546
+ return;
25356
25547
  }
25357
- const result = {
25358
- response
25548
+ recorder.onstop = () => {
25549
+ const mimeType = recorder.mimeType || "audio/webm";
25550
+ const blob = new Blob(chunksRef.current, { type: mimeType });
25551
+ const duration = Date.now() - startTimeRef.current;
25552
+ mediaStreamRef.current?.getTracks().forEach((t) => t.stop());
25553
+ mediaStreamRef.current = null;
25554
+ mediaRecorderRef.current = null;
25555
+ const result = { blob, duration, mimeType };
25556
+ setRecording(result);
25557
+ setIsRecording(false);
25558
+ resolve(result);
25359
25559
  };
25360
- if (response.ok) {
25361
- const parseAs = (opts.parseAs === "auto" ? getParseAs(response.headers.get("Content-Type")) : opts.parseAs) ?? "json";
25362
- if (response.status === 204 || response.headers.get("Content-Length") === "0") {
25363
- let emptyData;
25364
- switch (parseAs) {
25365
- case "arrayBuffer":
25366
- case "blob":
25367
- case "text":
25368
- emptyData = await response[parseAs]();
25369
- break;
25370
- case "formData":
25371
- emptyData = new FormData();
25372
- break;
25373
- case "stream":
25374
- emptyData = response.body;
25375
- break;
25376
- case "json":
25377
- default:
25378
- emptyData = {};
25379
- break;
25380
- }
25381
- return {
25382
- data: emptyData,
25383
- ...result
25384
- };
25385
- }
25386
- let data;
25387
- switch (parseAs) {
25388
- case "arrayBuffer":
25389
- case "blob":
25390
- case "formData":
25391
- case "text":
25392
- data = await response[parseAs]();
25393
- break;
25394
- case "json": {
25395
- const text12 = await response.text();
25396
- data = text12 ? JSON.parse(text12) : {};
25397
- break;
25398
- }
25399
- case "stream":
25400
- return {
25401
- data: response.body,
25402
- ...result
25403
- };
25404
- }
25405
- if (parseAs === "json") {
25406
- if (opts.responseValidator) {
25407
- await opts.responseValidator(data);
25408
- }
25409
- if (opts.responseTransformer) {
25410
- data = await opts.responseTransformer(data);
25411
- }
25412
- }
25413
- return {
25414
- data,
25415
- ...result
25416
- };
25560
+ recorder.onerror = () => {
25561
+ const err = new Error("Recording failed");
25562
+ setError(err);
25563
+ setIsRecording(false);
25564
+ reject(err);
25565
+ };
25566
+ recorder.stop();
25567
+ });
25568
+ }, []);
25569
+ const transcribe = (0, import_react13.useCallback)(
25570
+ async (rec) => {
25571
+ const target = rec ?? recording;
25572
+ if (!target) {
25573
+ const err = new Error("No recording to transcribe");
25574
+ setError(err);
25575
+ throw err;
25417
25576
  }
25418
- const textError = await response.text();
25419
- let jsonError;
25577
+ setIsTranscribing(true);
25578
+ setError(null);
25420
25579
  try {
25421
- jsonError = JSON.parse(textError);
25422
- } catch {
25580
+ const pipe = await loadPipeline();
25581
+ const audio = await audioToFloat32(target.blob);
25582
+ const result = await pipe(audio, {
25583
+ language: options?.language,
25584
+ return_timestamps: true
25585
+ });
25586
+ const transcriptionResult = {
25587
+ text: result.text.trim(),
25588
+ chunks: result.chunks
25589
+ };
25590
+ setTranscription(transcriptionResult);
25591
+ return transcriptionResult;
25592
+ } catch (err) {
25593
+ const processedError = err instanceof Error ? err : new Error("Transcription failed");
25594
+ setError(processedError);
25595
+ throw processedError;
25596
+ } finally {
25597
+ setIsTranscribing(false);
25423
25598
  }
25424
- throw jsonError ?? textError;
25425
- } catch (error) {
25426
- let finalError = error;
25427
- for (const fn of interceptors.error.fns) {
25428
- if (fn) {
25429
- finalError = await fn(finalError, response, options);
25599
+ },
25600
+ [recording, loadPipeline, options?.language]
25601
+ );
25602
+ const nativeSpeechAvailable = (0, import_react13.useMemo)(() => getOnDeviceSpeechRecognition() !== null, []);
25603
+ const [isNativeListening, setIsNativeListening] = (0, import_react13.useState)(false);
25604
+ const nativeRecognitionRef = (0, import_react13.useRef)(null);
25605
+ const nativeTextRef = (0, import_react13.useRef)("");
25606
+ const nativeResolveRef = (0, import_react13.useRef)(null);
25607
+ const startNativeTranscription = (0, import_react13.useCallback)(() => {
25608
+ const SR = getOnDeviceSpeechRecognition();
25609
+ if (!SR) return;
25610
+ nativeTextRef.current = "";
25611
+ setError(null);
25612
+ const recognition = new SR();
25613
+ recognition.continuous = true;
25614
+ recognition.interimResults = false;
25615
+ recognition.lang = options?.language ?? "";
25616
+ recognition.onresult = (event) => {
25617
+ let text12 = "";
25618
+ for (let i = 0; i < event.results.length; i++) {
25619
+ const result = event.results[i];
25620
+ if (result && result.isFinal && result[0]) {
25621
+ text12 += result[0].transcript + " ";
25430
25622
  }
25431
25623
  }
25432
- finalError = finalError || {};
25433
- if (throwOnError) {
25434
- throw finalError;
25624
+ nativeTextRef.current = text12.trim();
25625
+ };
25626
+ recognition.onerror = (event) => {
25627
+ if (event.error !== "aborted" && event.error !== "no-speech") {
25628
+ setError(new Error(`Speech recognition error: ${event.error}`));
25435
25629
  }
25436
- return {
25437
- error: finalError,
25438
- response
25439
- };
25440
- }
25441
- };
25442
- const makeMethodFn = (method) => (options) => request({ ...options, method });
25443
- const makeSseFn = (method) => async (options) => {
25444
- const { opts, url } = await beforeRequest(options);
25445
- return createSseClient({
25446
- ...opts,
25447
- body: opts.body,
25448
- method,
25449
- onRequest: async (url2, init) => {
25450
- let request2 = new Request(url2, init);
25451
- const requestInit = { ...init, url: url2 };
25452
- for (const fn of interceptors.request.fns) {
25453
- if (fn) {
25454
- await fn(requestInit);
25455
- request2 = new Request(requestInit.url, requestInit);
25456
- }
25457
- }
25458
- return request2;
25459
- },
25460
- serializedBody: getValidRequestBody(opts),
25461
- url
25630
+ };
25631
+ recognition.onend = () => {
25632
+ setIsNativeListening(false);
25633
+ nativeRecognitionRef.current = null;
25634
+ const resolve = nativeResolveRef.current;
25635
+ if (resolve) {
25636
+ nativeResolveRef.current = null;
25637
+ resolve({ text: nativeTextRef.current });
25638
+ }
25639
+ };
25640
+ nativeRecognitionRef.current = recognition;
25641
+ recognition.start();
25642
+ setIsNativeListening(true);
25643
+ }, [options?.language]);
25644
+ const stopNativeTranscription = (0, import_react13.useCallback)(() => {
25645
+ return new Promise((resolve) => {
25646
+ const recognition = nativeRecognitionRef.current;
25647
+ if (!recognition) {
25648
+ resolve({ text: nativeTextRef.current || "" });
25649
+ return;
25650
+ }
25651
+ nativeResolveRef.current = resolve;
25652
+ recognition.stop();
25462
25653
  });
25463
- };
25464
- const _buildUrl = (options) => buildUrl({ ..._config, ...options });
25654
+ }, []);
25655
+ const abortNativeTranscription = (0, import_react13.useCallback)(() => {
25656
+ const recognition = nativeRecognitionRef.current;
25657
+ if (recognition) {
25658
+ nativeResolveRef.current = null;
25659
+ recognition.abort();
25660
+ nativeRecognitionRef.current = null;
25661
+ setIsNativeListening(false);
25662
+ }
25663
+ }, []);
25465
25664
  return {
25466
- buildUrl: _buildUrl,
25467
- connect: makeMethodFn("CONNECT"),
25468
- delete: makeMethodFn("DELETE"),
25469
- get: makeMethodFn("GET"),
25470
- getConfig,
25471
- head: makeMethodFn("HEAD"),
25472
- interceptors,
25473
- options: makeMethodFn("OPTIONS"),
25474
- patch: makeMethodFn("PATCH"),
25475
- post: makeMethodFn("POST"),
25476
- put: makeMethodFn("PUT"),
25477
- request,
25478
- setConfig,
25479
- sse: {
25480
- connect: makeSseFn("CONNECT"),
25481
- delete: makeSseFn("DELETE"),
25482
- get: makeSseFn("GET"),
25483
- head: makeSseFn("HEAD"),
25484
- options: makeSseFn("OPTIONS"),
25485
- patch: makeSseFn("PATCH"),
25486
- post: makeSseFn("POST"),
25487
- put: makeSseFn("PUT"),
25488
- trace: makeSseFn("TRACE")
25489
- },
25490
- trace: makeMethodFn("TRACE")
25665
+ isRecording,
25666
+ startRecording,
25667
+ stopRecording,
25668
+ isTranscribing,
25669
+ transcribe,
25670
+ preloadModel,
25671
+ disposeModel,
25672
+ isModelLoaded,
25673
+ isLoadingModel,
25674
+ recording,
25675
+ transcription,
25676
+ error,
25677
+ nativeSpeechAvailable,
25678
+ startNativeTranscription,
25679
+ stopNativeTranscription,
25680
+ abortNativeTranscription,
25681
+ isNativeListening
25491
25682
  };
25492
- };
25493
-
25494
- // src/client/client.gen.ts
25495
- init_clientConfig();
25496
- var client = createClient(createClientConfig(createConfig()));
25497
-
25498
- // src/client/sdk.gen.ts
25499
- var getApiV1Config = (options) => (options?.client ?? client).get({ url: "/api/v1/config", ...options });
25500
- var getApiV1CreditsBalance = (options) => (options?.client ?? client).get({ url: "/api/v1/credits/balance", ...options });
25501
- var getApiV1CreditsPacks = (options) => (options?.client ?? client).get({ url: "/api/v1/credits/packs", ...options });
25502
- var postApiV1CreditsPurchase = (options) => (options.client ?? client).post({
25503
- url: "/api/v1/credits/purchase",
25504
- ...options,
25505
- headers: {
25506
- "Content-Type": "application/json",
25507
- ...options.headers
25508
- }
25509
- });
25510
- var getApiV1Models = (options) => (options?.client ?? client).get({ url: "/api/v1/models", ...options });
25511
- var postApiV1PhoneCalls = (options) => (options.client ?? client).post({
25512
- url: "/api/v1/phone-calls",
25513
- ...options,
25514
- headers: {
25515
- "Content-Type": "application/json",
25516
- ...options.headers
25517
- }
25518
- });
25519
- var getApiV1PhoneCallsByCallId = (options) => (options.client ?? client).get({ url: "/api/v1/phone-calls/{call_id}", ...options });
25520
- var postApiV1SubscriptionsCancel = (options) => (options?.client ?? client).post({
25521
- url: "/api/v1/subscriptions/cancel",
25522
- ...options,
25523
- headers: {
25524
- "Content-Type": "application/json",
25525
- ...options?.headers
25526
- }
25527
- });
25528
- var postApiV1SubscriptionsCreateCheckoutSession = (options) => (options.client ?? client).post({
25529
- url: "/api/v1/subscriptions/create-checkout-session",
25530
- ...options,
25531
- headers: {
25532
- "Content-Type": "application/json",
25533
- ...options.headers
25534
- }
25535
- });
25536
- var postApiV1SubscriptionsCustomerPortal = (options) => (options.client ?? client).post({
25537
- url: "/api/v1/subscriptions/customer-portal",
25538
- ...options,
25539
- headers: {
25540
- "Content-Type": "application/json",
25541
- ...options.headers
25542
- }
25543
- });
25544
- var postApiV1SubscriptionsRenew = (options) => (options?.client ?? client).post({ url: "/api/v1/subscriptions/renew", ...options });
25545
- var getApiV1SubscriptionsStatus = (options) => (options?.client ?? client).get({ url: "/api/v1/subscriptions/status", ...options });
25546
- var getApiV1WalletsBinding = (options) => (options?.client ?? client).get({ url: "/api/v1/wallets/binding", ...options });
25547
- var postApiV1WalletsBinding = (options) => (options.client ?? client).post({
25548
- url: "/api/v1/wallets/binding",
25549
- ...options,
25550
- headers: {
25551
- "Content-Type": "application/json",
25552
- ...options.headers
25553
- }
25554
- });
25555
- var postApiV1WalletsBindingNonce = (options) => (options?.client ?? client).post({ url: "/api/v1/wallets/binding/nonce", ...options });
25556
- var deleteApiV1WalletsBindingByAddress = (options) => (options.client ?? client).delete({ url: "/api/v1/wallets/binding/{address}", ...options });
25557
- var postAuthOauthByProviderExchange = (options) => (options.client ?? client).post({
25558
- url: "/auth/oauth/{provider}/exchange",
25559
- ...options,
25560
- headers: {
25561
- "Content-Type": "application/json",
25562
- ...options.headers
25563
- }
25564
- });
25565
- var postAuthOauthByProviderRefresh = (options) => (options.client ?? client).post({
25566
- url: "/auth/oauth/{provider}/refresh",
25567
- ...options,
25568
- headers: {
25569
- "Content-Type": "application/json",
25570
- ...options.headers
25571
- }
25572
- });
25573
- var postAuthOauthByProviderRevoke = (options) => (options.client ?? client).post({
25574
- url: "/auth/oauth/{provider}/revoke",
25575
- ...options,
25576
- headers: {
25577
- "Content-Type": "application/json",
25578
- ...options.headers
25579
- }
25580
- });
25683
+ }
25581
25684
 
25582
25685
  // src/react/useCredits.ts
25686
+ var import_react14 = require("react");
25687
+ init_sdk_gen();
25583
25688
  init_clientConfig();
25584
25689
  function useCredits(options = {}) {
25585
25690
  const { getToken, baseUrl = BASE_URL, autoFetch = true, onError } = options;
@@ -25738,6 +25843,7 @@ function useCredits(options = {}) {
25738
25843
 
25739
25844
  // src/react/useModels.ts
25740
25845
  var import_react15 = require("react");
25846
+ init_sdk_gen();
25741
25847
  init_clientConfig();
25742
25848
  function useModels(options = {}) {
25743
25849
  const { getToken, baseUrl = BASE_URL, provider, autoFetch = true } = options;
@@ -25843,6 +25949,7 @@ function useModels(options = {}) {
25843
25949
 
25844
25950
  // src/react/usePhoneCalls.ts
25845
25951
  var import_react16 = require("react");
25952
+ init_sdk_gen();
25846
25953
  init_clientConfig();
25847
25954
  var DEFAULT_POLL_INTERVAL_MS = 5e3;
25848
25955
  var DEFAULT_POLL_MAX_ATTEMPTS = 60;
@@ -26142,6 +26249,7 @@ function usePhoneCalls(options = {}) {
26142
26249
 
26143
26250
  // src/react/useSubscription.ts
26144
26251
  var import_react17 = require("react");
26252
+ init_sdk_gen();
26145
26253
  init_clientConfig();
26146
26254
  function useSubscription(options = {}) {
26147
26255
  const { getToken, baseUrl = BASE_URL, autoFetch = true, onError } = options;
@@ -26347,6 +26455,7 @@ function useSubscription(options = {}) {
26347
26455
 
26348
26456
  // src/react/useWalletBinding.ts
26349
26457
  var import_react18 = require("react");
26458
+ init_sdk_gen();
26350
26459
  init_clientConfig();
26351
26460
  function useWalletBinding(options = {}) {
26352
26461
  const { getToken, baseUrl = BASE_URL, autoFetch = true, onError } = options;
@@ -26530,6 +26639,7 @@ function useWalletBinding(options = {}) {
26530
26639
  var import_react19 = require("react");
26531
26640
 
26532
26641
  // src/lib/backup/dropbox/auth.ts
26642
+ init_sdk_gen();
26533
26643
  init_logger();
26534
26644
 
26535
26645
  // src/lib/backup/oauth/storage.ts
@@ -27286,6 +27396,7 @@ function useDropboxBackup(options) {
27286
27396
  var import_react21 = require("react");
27287
27397
 
27288
27398
  // src/lib/backup/google/auth.ts
27399
+ init_sdk_gen();
27289
27400
  init_logger();
27290
27401
  var PROVIDER2 = "google-drive";
27291
27402
  var CODE_STORAGE_KEY = "google_oauth_state";
@@ -29084,6 +29195,7 @@ function useBackup(options) {
29084
29195
  }
29085
29196
 
29086
29197
  // src/lib/auth/google-calendar.ts
29198
+ init_sdk_gen();
29087
29199
  init_useEncryption();
29088
29200
  init_logger();
29089
29201
  var PROVIDER3 = "google-drive";
@@ -29409,6 +29521,7 @@ async function migrateCalendarToken(walletAddress) {
29409
29521
  }
29410
29522
 
29411
29523
  // src/lib/auth/google-drive.ts
29524
+ init_sdk_gen();
29412
29525
  init_useEncryption();
29413
29526
  init_logger();
29414
29527
  var PROVIDER4 = "google-drive";
@@ -30285,6 +30398,7 @@ function getNotionMCPUrl() {
30285
30398
  }
30286
30399
 
30287
30400
  // src/lib/auth/github.ts
30401
+ init_sdk_gen();
30288
30402
  init_useEncryption();
30289
30403
  init_logger();
30290
30404
  var PROVIDER5 = "github";