@anuma/sdk 3.0.0 → 3.1.1

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.
@@ -75,1113 +75,73 @@ var init_clientConfig = __esm({
75
75
  }
76
76
  });
77
77
 
78
- // src/client/core/serverSentEvents.gen.ts
79
- var createSseClient;
80
- var init_serverSentEvents_gen = __esm({
81
- "src/client/core/serverSentEvents.gen.ts"() {
82
- "use strict";
83
- createSseClient = ({
84
- onRequest,
85
- onSseError,
86
- onSseEvent,
87
- responseTransformer,
88
- responseValidator,
89
- sseDefaultRetryDelay,
90
- sseMaxRetryAttempts,
91
- sseMaxRetryDelay,
92
- sseSleepFn,
93
- url,
94
- ...options
95
- }) => {
96
- let lastEventId;
97
- const sleep4 = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
98
- const createStream = async function* () {
99
- let retryDelay = sseDefaultRetryDelay ?? 3e3;
100
- let attempt = 0;
101
- const signal = options.signal ?? new AbortController().signal;
102
- while (true) {
103
- if (signal.aborted) break;
104
- attempt++;
105
- const headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers);
106
- if (lastEventId !== void 0) {
107
- headers.set("Last-Event-ID", lastEventId);
108
- }
109
- try {
110
- const requestInit = {
111
- redirect: "follow",
112
- ...options,
113
- body: options.serializedBody,
114
- headers,
115
- signal
116
- };
117
- let request = new Request(url, requestInit);
118
- if (onRequest) {
119
- request = await onRequest(url, requestInit);
120
- }
121
- const _fetch = options.fetch ?? globalThis.fetch;
122
- const response = await _fetch(request);
123
- if (!response.ok)
124
- throw new Error(
125
- `SSE failed: ${response.status} ${response.statusText}`
126
- );
127
- if (!response.body) throw new Error("No body in SSE response");
128
- const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
129
- let buffer = "";
130
- const abortHandler = () => {
131
- try {
132
- reader.cancel();
133
- } catch {
134
- }
135
- };
136
- signal.addEventListener("abort", abortHandler);
137
- try {
138
- while (true) {
139
- const { done, value } = await reader.read();
140
- if (done) break;
141
- buffer += value;
142
- const chunks = buffer.split("\n\n");
143
- buffer = chunks.pop() ?? "";
144
- for (const chunk of chunks) {
145
- const lines = chunk.split("\n");
146
- const dataLines = [];
147
- let eventName;
148
- for (const line of lines) {
149
- if (line.startsWith("data:")) {
150
- dataLines.push(line.replace(/^data:\s*/, ""));
151
- } else if (line.startsWith("event:")) {
152
- eventName = line.replace(/^event:\s*/, "");
153
- } else if (line.startsWith("id:")) {
154
- lastEventId = line.replace(/^id:\s*/, "");
155
- } else if (line.startsWith("retry:")) {
156
- const parsed = Number.parseInt(
157
- line.replace(/^retry:\s*/, ""),
158
- 10
159
- );
160
- if (!Number.isNaN(parsed)) {
161
- retryDelay = parsed;
162
- }
163
- }
164
- }
165
- let data;
166
- let parsedJson = false;
167
- if (dataLines.length) {
168
- const rawData = dataLines.join("\n");
169
- try {
170
- data = JSON.parse(rawData);
171
- parsedJson = true;
172
- } catch {
173
- data = rawData;
174
- }
175
- }
176
- if (parsedJson) {
177
- if (responseValidator) {
178
- await responseValidator(data);
179
- }
180
- if (responseTransformer) {
181
- data = await responseTransformer(data);
182
- }
183
- }
184
- onSseEvent?.({
185
- data,
186
- event: eventName,
187
- id: lastEventId,
188
- retry: retryDelay
189
- });
190
- if (dataLines.length) {
191
- yield data;
192
- }
193
- }
194
- }
195
- } finally {
196
- signal.removeEventListener("abort", abortHandler);
197
- reader.releaseLock();
198
- }
199
- break;
200
- } catch (error) {
201
- onSseError?.(error);
202
- if (sseMaxRetryAttempts !== void 0 && attempt >= sseMaxRetryAttempts) {
203
- break;
204
- }
205
- const backoff = Math.min(
206
- retryDelay * 2 ** (attempt - 1),
207
- sseMaxRetryDelay ?? 3e4
208
- );
209
- await sleep4(backoff);
210
- }
211
- }
212
- };
213
- const stream = createStream();
214
- return { stream };
215
- };
216
- }
217
- });
218
-
219
- // src/client/core/bodySerializer.gen.ts
220
- var jsonBodySerializer;
221
- var init_bodySerializer_gen = __esm({
222
- "src/client/core/bodySerializer.gen.ts"() {
223
- "use strict";
224
- jsonBodySerializer = {
225
- bodySerializer: (body) => JSON.stringify(
226
- body,
227
- (_key, value) => typeof value === "bigint" ? value.toString() : value
228
- )
229
- };
230
- }
231
- });
232
-
233
- // src/client/core/pathSerializer.gen.ts
234
- var separatorArrayExplode, separatorArrayNoExplode, separatorObjectExplode, serializeArrayParam, serializePrimitiveParam, serializeObjectParam;
235
- var init_pathSerializer_gen = __esm({
236
- "src/client/core/pathSerializer.gen.ts"() {
78
+ // src/lib/logger.ts
79
+ function setLogger(logger) {
80
+ currentLogger = logger;
81
+ }
82
+ function getLogger() {
83
+ return currentLogger;
84
+ }
85
+ var consoleLogger, noopLogger, currentLogger;
86
+ var init_logger = __esm({
87
+ "src/lib/logger.ts"() {
237
88
  "use strict";
238
- separatorArrayExplode = (style) => {
239
- switch (style) {
240
- case "label":
241
- return ".";
242
- case "matrix":
243
- return ";";
244
- case "simple":
245
- return ",";
246
- default:
247
- return "&";
248
- }
249
- };
250
- separatorArrayNoExplode = (style) => {
251
- switch (style) {
252
- case "form":
253
- return ",";
254
- case "pipeDelimited":
255
- return "|";
256
- case "spaceDelimited":
257
- return "%20";
258
- default:
259
- return ",";
260
- }
261
- };
262
- separatorObjectExplode = (style) => {
263
- switch (style) {
264
- case "label":
265
- return ".";
266
- case "matrix":
267
- return ";";
268
- case "simple":
269
- return ",";
270
- default:
271
- return "&";
272
- }
273
- };
274
- serializeArrayParam = ({
275
- allowReserved,
276
- explode,
277
- name,
278
- style,
279
- value
280
- }) => {
281
- if (!explode) {
282
- const joinedValues2 = (allowReserved ? value : value.map((v) => encodeURIComponent(v))).join(separatorArrayNoExplode(style));
283
- switch (style) {
284
- case "label":
285
- return `.${joinedValues2}`;
286
- case "matrix":
287
- return `;${name}=${joinedValues2}`;
288
- case "simple":
289
- return joinedValues2;
290
- default:
291
- return `${name}=${joinedValues2}`;
292
- }
293
- }
294
- const separator = separatorArrayExplode(style);
295
- const joinedValues = value.map((v) => {
296
- if (style === "label" || style === "simple") {
297
- return allowReserved ? v : encodeURIComponent(v);
298
- }
299
- return serializePrimitiveParam({
300
- allowReserved,
301
- name,
302
- value: v
303
- });
304
- }).join(separator);
305
- return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
306
- };
307
- serializePrimitiveParam = ({
308
- allowReserved,
309
- name,
310
- value
311
- }) => {
312
- if (value === void 0 || value === null) {
313
- return "";
314
- }
315
- if (typeof value === "object") {
316
- throw new Error(
317
- "Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these."
318
- );
319
- }
320
- return `${name}=${allowReserved ? value : encodeURIComponent(value)}`;
89
+ consoleLogger = {
90
+ debug: console.log.bind(console),
91
+ info: console.info.bind(console),
92
+ warn: console.warn.bind(console),
93
+ error: console.error.bind(console)
321
94
  };
322
- serializeObjectParam = ({
323
- allowReserved,
324
- explode,
325
- name,
326
- style,
327
- value,
328
- valueOnly
329
- }) => {
330
- if (value instanceof Date) {
331
- return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`;
332
- }
333
- if (style !== "deepObject" && !explode) {
334
- let values = [];
335
- Object.entries(value).forEach(([key, v]) => {
336
- values = [
337
- ...values,
338
- key,
339
- allowReserved ? v : encodeURIComponent(v)
340
- ];
341
- });
342
- const joinedValues2 = values.join(",");
343
- switch (style) {
344
- case "form":
345
- return `${name}=${joinedValues2}`;
346
- case "label":
347
- return `.${joinedValues2}`;
348
- case "matrix":
349
- return `;${name}=${joinedValues2}`;
350
- default:
351
- return joinedValues2;
352
- }
95
+ noopLogger = {
96
+ debug: () => {
97
+ },
98
+ info: () => {
99
+ },
100
+ warn: () => {
101
+ },
102
+ error: () => {
353
103
  }
354
- const separator = separatorObjectExplode(style);
355
- const joinedValues = Object.entries(value).map(
356
- ([key, v]) => serializePrimitiveParam({
357
- allowReserved,
358
- name: style === "deepObject" ? `${name}[${key}]` : key,
359
- value: v
360
- })
361
- ).join(separator);
362
- return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
363
104
  };
105
+ currentLogger = consoleLogger;
364
106
  }
365
107
  });
366
108
 
367
- // src/client/core/utils.gen.ts
368
- function getValidRequestBody(options) {
369
- const hasBody = options.body !== void 0;
370
- const isSerializedBody = hasBody && options.bodySerializer;
371
- if (isSerializedBody) {
372
- if ("serializedBody" in options) {
373
- const hasSerializedBody = options.serializedBody !== void 0 && options.serializedBody !== "";
374
- return hasSerializedBody ? options.serializedBody : null;
109
+ // src/react/useEncryption.ts
110
+ function onClearAllEncryptionState(callback) {
111
+ clearAllEncryptionStateCallbacks.add(callback);
112
+ return () => {
113
+ clearAllEncryptionStateCallbacks.delete(callback);
114
+ };
115
+ }
116
+ function onKeyAvailable(address, callback) {
117
+ if (encryptionKeyStore.has(address)) {
118
+ try {
119
+ callback();
120
+ } catch {
375
121
  }
376
- return options.body !== "" ? options.body : null;
377
122
  }
378
- if (hasBody) {
379
- return options.body;
123
+ let callbacks = keyAvailableCallbacks.get(address);
124
+ if (!callbacks) {
125
+ callbacks = /* @__PURE__ */ new Set();
126
+ keyAvailableCallbacks.set(address, callbacks);
380
127
  }
381
- return void 0;
128
+ callbacks.add(callback);
129
+ return () => {
130
+ callbacks.delete(callback);
131
+ if (callbacks.size === 0) {
132
+ keyAvailableCallbacks.delete(address);
133
+ }
134
+ };
382
135
  }
383
- var init_utils_gen = __esm({
384
- "src/client/core/utils.gen.ts"() {
385
- "use strict";
386
- }
387
- });
388
-
389
- // src/client/core/auth.gen.ts
390
- var getAuthToken;
391
- var init_auth_gen = __esm({
392
- "src/client/core/auth.gen.ts"() {
393
- "use strict";
394
- getAuthToken = async (auth, callback) => {
395
- const token = typeof callback === "function" ? await callback(auth) : callback;
396
- if (!token) {
397
- return;
398
- }
399
- if (auth.scheme === "bearer") {
400
- return `Bearer ${token}`;
401
- }
402
- if (auth.scheme === "basic") {
403
- return `Basic ${btoa(token)}`;
136
+ function notifyKeyAvailable(address) {
137
+ const callbacks = keyAvailableCallbacks.get(address);
138
+ if (callbacks) {
139
+ for (const cb of callbacks) {
140
+ try {
141
+ cb();
142
+ } catch {
404
143
  }
405
- return token;
406
- };
407
- }
408
- });
409
-
410
- // src/client/client/utils.gen.ts
411
- var PATH_PARAM_RE, defaultPathSerializer, createQuerySerializer, getParseAs, checkForExistence, setAuthParams, buildUrl, getUrl, mergeConfigs, headersEntries, mergeHeaders, Interceptors, createInterceptors, defaultQuerySerializer, defaultHeaders, createConfig;
412
- var init_utils_gen2 = __esm({
413
- "src/client/client/utils.gen.ts"() {
414
- "use strict";
415
- init_auth_gen();
416
- init_bodySerializer_gen();
417
- init_pathSerializer_gen();
418
- PATH_PARAM_RE = /\{[^{}]+\}/g;
419
- defaultPathSerializer = ({ path, url: _url }) => {
420
- let url = _url;
421
- const matches = _url.match(PATH_PARAM_RE);
422
- if (matches) {
423
- for (const match of matches) {
424
- let explode = false;
425
- let name = match.substring(1, match.length - 1);
426
- let style = "simple";
427
- if (name.endsWith("*")) {
428
- explode = true;
429
- name = name.substring(0, name.length - 1);
430
- }
431
- if (name.startsWith(".")) {
432
- name = name.substring(1);
433
- style = "label";
434
- } else if (name.startsWith(";")) {
435
- name = name.substring(1);
436
- style = "matrix";
437
- }
438
- const value = path[name];
439
- if (value === void 0 || value === null) {
440
- continue;
441
- }
442
- if (Array.isArray(value)) {
443
- url = url.replace(
444
- match,
445
- serializeArrayParam({ explode, name, style, value })
446
- );
447
- continue;
448
- }
449
- if (typeof value === "object") {
450
- url = url.replace(
451
- match,
452
- serializeObjectParam({
453
- explode,
454
- name,
455
- style,
456
- value,
457
- valueOnly: true
458
- })
459
- );
460
- continue;
461
- }
462
- if (style === "matrix") {
463
- url = url.replace(
464
- match,
465
- `;${serializePrimitiveParam({
466
- name,
467
- value
468
- })}`
469
- );
470
- continue;
471
- }
472
- const replaceValue = encodeURIComponent(
473
- style === "label" ? `.${value}` : value
474
- );
475
- url = url.replace(match, replaceValue);
476
- }
477
- }
478
- return url;
479
- };
480
- createQuerySerializer = ({
481
- parameters = {},
482
- ...args
483
- } = {}) => {
484
- const querySerializer = (queryParams) => {
485
- const search = [];
486
- if (queryParams && typeof queryParams === "object") {
487
- for (const name in queryParams) {
488
- const value = queryParams[name];
489
- if (value === void 0 || value === null) {
490
- continue;
491
- }
492
- const options = parameters[name] || args;
493
- if (Array.isArray(value)) {
494
- const serializedArray = serializeArrayParam({
495
- allowReserved: options.allowReserved,
496
- explode: true,
497
- name,
498
- style: "form",
499
- value,
500
- ...options.array
501
- });
502
- if (serializedArray) search.push(serializedArray);
503
- } else if (typeof value === "object") {
504
- const serializedObject = serializeObjectParam({
505
- allowReserved: options.allowReserved,
506
- explode: true,
507
- name,
508
- style: "deepObject",
509
- value,
510
- ...options.object
511
- });
512
- if (serializedObject) search.push(serializedObject);
513
- } else {
514
- const serializedPrimitive = serializePrimitiveParam({
515
- allowReserved: options.allowReserved,
516
- name,
517
- value
518
- });
519
- if (serializedPrimitive) search.push(serializedPrimitive);
520
- }
521
- }
522
- }
523
- return search.join("&");
524
- };
525
- return querySerializer;
526
- };
527
- getParseAs = (contentType) => {
528
- if (!contentType) {
529
- return "stream";
530
- }
531
- const cleanContent = contentType.split(";")[0]?.trim();
532
- if (!cleanContent) {
533
- return;
534
- }
535
- if (cleanContent.startsWith("application/json") || cleanContent.endsWith("+json")) {
536
- return "json";
537
- }
538
- if (cleanContent === "multipart/form-data") {
539
- return "formData";
540
- }
541
- if (["application/", "audio/", "image/", "video/"].some(
542
- (type) => cleanContent.startsWith(type)
543
- )) {
544
- return "blob";
545
- }
546
- if (cleanContent.startsWith("text/")) {
547
- return "text";
548
- }
549
- return;
550
- };
551
- checkForExistence = (options, name) => {
552
- if (!name) {
553
- return false;
554
- }
555
- if (options.headers.has(name) || options.query?.[name] || options.headers.get("Cookie")?.includes(`${name}=`)) {
556
- return true;
557
- }
558
- return false;
559
- };
560
- setAuthParams = async ({
561
- security,
562
- ...options
563
- }) => {
564
- for (const auth of security) {
565
- if (checkForExistence(options, auth.name)) {
566
- continue;
567
- }
568
- const token = await getAuthToken(auth, options.auth);
569
- if (!token) {
570
- continue;
571
- }
572
- const name = auth.name ?? "Authorization";
573
- switch (auth.in) {
574
- case "query":
575
- if (!options.query) {
576
- options.query = {};
577
- }
578
- options.query[name] = token;
579
- break;
580
- case "cookie":
581
- options.headers.append("Cookie", `${name}=${token}`);
582
- break;
583
- case "header":
584
- default:
585
- options.headers.set(name, token);
586
- break;
587
- }
588
- }
589
- };
590
- buildUrl = (options) => {
591
- const url = getUrl({
592
- baseUrl: options.baseUrl,
593
- path: options.path,
594
- query: options.query,
595
- querySerializer: typeof options.querySerializer === "function" ? options.querySerializer : createQuerySerializer(options.querySerializer),
596
- url: options.url
597
- });
598
- return url;
599
- };
600
- getUrl = ({
601
- baseUrl,
602
- path,
603
- query,
604
- querySerializer,
605
- url: _url
606
- }) => {
607
- const pathUrl = _url.startsWith("/") ? _url : `/${_url}`;
608
- let url = (baseUrl ?? "") + pathUrl;
609
- if (path) {
610
- url = defaultPathSerializer({ path, url });
611
- }
612
- let search = query ? querySerializer(query) : "";
613
- if (search.startsWith("?")) {
614
- search = search.substring(1);
615
- }
616
- if (search) {
617
- url += `?${search}`;
618
- }
619
- return url;
620
- };
621
- mergeConfigs = (a, b) => {
622
- const config = { ...a, ...b };
623
- if (config.baseUrl?.endsWith("/")) {
624
- config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1);
625
- }
626
- config.headers = mergeHeaders(a.headers, b.headers);
627
- return config;
628
- };
629
- headersEntries = (headers) => {
630
- const entries = [];
631
- headers.forEach((value, key) => {
632
- entries.push([key, value]);
633
- });
634
- return entries;
635
- };
636
- mergeHeaders = (...headers) => {
637
- const mergedHeaders = new Headers();
638
- for (const header of headers) {
639
- if (!header || typeof header !== "object") {
640
- continue;
641
- }
642
- const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header);
643
- for (const [key, value] of iterator) {
644
- if (value === null) {
645
- mergedHeaders.delete(key);
646
- } else if (Array.isArray(value)) {
647
- for (const v of value) {
648
- mergedHeaders.append(key, v);
649
- }
650
- } else if (value !== void 0) {
651
- mergedHeaders.set(
652
- key,
653
- typeof value === "object" ? JSON.stringify(value) : value
654
- );
655
- }
656
- }
657
- }
658
- return mergedHeaders;
659
- };
660
- Interceptors = class {
661
- constructor() {
662
- this.fns = [];
663
- }
664
- clear() {
665
- this.fns = [];
666
- }
667
- eject(id) {
668
- const index = this.getInterceptorIndex(id);
669
- if (this.fns[index]) {
670
- this.fns[index] = null;
671
- }
672
- }
673
- exists(id) {
674
- const index = this.getInterceptorIndex(id);
675
- return Boolean(this.fns[index]);
676
- }
677
- getInterceptorIndex(id) {
678
- if (typeof id === "number") {
679
- return this.fns[id] ? id : -1;
680
- }
681
- return this.fns.indexOf(id);
682
- }
683
- update(id, fn) {
684
- const index = this.getInterceptorIndex(id);
685
- if (this.fns[index]) {
686
- this.fns[index] = fn;
687
- return id;
688
- }
689
- return false;
690
- }
691
- use(fn) {
692
- this.fns.push(fn);
693
- return this.fns.length - 1;
694
- }
695
- };
696
- createInterceptors = () => ({
697
- error: new Interceptors(),
698
- request: new Interceptors(),
699
- response: new Interceptors()
700
- });
701
- defaultQuerySerializer = createQuerySerializer({
702
- allowReserved: false,
703
- array: {
704
- explode: true,
705
- style: "form"
706
- },
707
- object: {
708
- explode: true,
709
- style: "deepObject"
710
- }
711
- });
712
- defaultHeaders = {
713
- "Content-Type": "application/json"
714
- };
715
- createConfig = (override = {}) => ({
716
- ...jsonBodySerializer,
717
- headers: defaultHeaders,
718
- parseAs: "auto",
719
- querySerializer: defaultQuerySerializer,
720
- ...override
721
- });
722
- }
723
- });
724
-
725
- // src/client/client/client.gen.ts
726
- var createClient;
727
- var init_client_gen = __esm({
728
- "src/client/client/client.gen.ts"() {
729
- "use strict";
730
- init_serverSentEvents_gen();
731
- init_utils_gen();
732
- init_utils_gen2();
733
- createClient = (config = {}) => {
734
- let _config = mergeConfigs(createConfig(), config);
735
- const getConfig = () => ({ ..._config });
736
- const setConfig = (config2) => {
737
- _config = mergeConfigs(_config, config2);
738
- return getConfig();
739
- };
740
- const interceptors = createInterceptors();
741
- const beforeRequest = async (options) => {
742
- const opts = {
743
- ..._config,
744
- ...options,
745
- fetch: options.fetch ?? _config.fetch ?? globalThis.fetch,
746
- headers: mergeHeaders(_config.headers, options.headers),
747
- serializedBody: void 0
748
- };
749
- if (opts.security) {
750
- await setAuthParams({
751
- ...opts,
752
- security: opts.security
753
- });
754
- }
755
- if (opts.requestValidator) {
756
- await opts.requestValidator(opts);
757
- }
758
- if (opts.body !== void 0 && opts.bodySerializer) {
759
- opts.serializedBody = opts.bodySerializer(opts.body);
760
- }
761
- if (opts.body === void 0 || opts.serializedBody === "") {
762
- opts.headers.delete("Content-Type");
763
- }
764
- const url = buildUrl(opts);
765
- return { opts, url };
766
- };
767
- const request = async (options) => {
768
- const { opts, url } = await beforeRequest(options);
769
- for (const fn of interceptors.request.fns) {
770
- if (fn) {
771
- await fn(opts);
772
- }
773
- }
774
- const _fetch = opts.fetch;
775
- const requestInit = {
776
- ...opts,
777
- body: getValidRequestBody(opts)
778
- };
779
- let response = await _fetch(url, requestInit);
780
- for (const fn of interceptors.response.fns) {
781
- if (fn) {
782
- response = await fn(response, opts);
783
- }
784
- }
785
- const result = {
786
- response
787
- };
788
- if (response.ok) {
789
- const parseAs = (opts.parseAs === "auto" ? getParseAs(response.headers.get("Content-Type")) : opts.parseAs) ?? "json";
790
- if (response.status === 204 || response.headers.get("Content-Length") === "0") {
791
- let emptyData;
792
- switch (parseAs) {
793
- case "arrayBuffer":
794
- case "blob":
795
- case "text":
796
- emptyData = await response[parseAs]();
797
- break;
798
- case "formData":
799
- emptyData = new FormData();
800
- break;
801
- case "stream":
802
- emptyData = response.body;
803
- break;
804
- case "json":
805
- default:
806
- emptyData = {};
807
- break;
808
- }
809
- return {
810
- data: emptyData,
811
- ...result
812
- };
813
- }
814
- let data;
815
- switch (parseAs) {
816
- case "arrayBuffer":
817
- case "blob":
818
- case "formData":
819
- case "json":
820
- case "text":
821
- data = await response[parseAs]();
822
- break;
823
- case "stream":
824
- return {
825
- data: response.body,
826
- ...result
827
- };
828
- }
829
- if (parseAs === "json") {
830
- if (opts.responseValidator) {
831
- await opts.responseValidator(data);
832
- }
833
- if (opts.responseTransformer) {
834
- data = await opts.responseTransformer(data);
835
- }
836
- }
837
- return {
838
- data,
839
- ...result
840
- };
841
- }
842
- const textError = await response.text();
843
- let jsonError;
844
- try {
845
- jsonError = JSON.parse(textError);
846
- } catch {
847
- }
848
- const error = jsonError ?? textError;
849
- let finalError = error;
850
- for (const fn of interceptors.error.fns) {
851
- if (fn) {
852
- finalError = await fn(error, response, opts);
853
- }
854
- }
855
- finalError = finalError || {};
856
- if (opts.throwOnError) {
857
- throw finalError;
858
- }
859
- return {
860
- error: finalError,
861
- ...result
862
- };
863
- };
864
- const makeMethodFn = (method) => (options) => request({ ...options, method });
865
- const makeSseFn = (method) => async (options) => {
866
- const { opts, url } = await beforeRequest(options);
867
- return createSseClient({
868
- ...opts,
869
- body: opts.body,
870
- headers: opts.headers,
871
- method,
872
- onRequest: async (url2, init) => {
873
- let request2 = new Request(url2, init);
874
- const requestInit = {
875
- ...init,
876
- method: init.method,
877
- url: url2
878
- };
879
- for (const fn of interceptors.request.fns) {
880
- if (fn) {
881
- await fn(requestInit);
882
- request2 = new Request(requestInit.url, requestInit);
883
- }
884
- }
885
- return request2;
886
- },
887
- url
888
- });
889
- };
890
- return {
891
- buildUrl,
892
- connect: makeMethodFn("CONNECT"),
893
- delete: makeMethodFn("DELETE"),
894
- get: makeMethodFn("GET"),
895
- getConfig,
896
- head: makeMethodFn("HEAD"),
897
- interceptors,
898
- options: makeMethodFn("OPTIONS"),
899
- patch: makeMethodFn("PATCH"),
900
- post: makeMethodFn("POST"),
901
- put: makeMethodFn("PUT"),
902
- request,
903
- setConfig,
904
- sse: {
905
- connect: makeSseFn("CONNECT"),
906
- delete: makeSseFn("DELETE"),
907
- get: makeSseFn("GET"),
908
- head: makeSseFn("HEAD"),
909
- options: makeSseFn("OPTIONS"),
910
- patch: makeSseFn("PATCH"),
911
- post: makeSseFn("POST"),
912
- put: makeSseFn("PUT"),
913
- trace: makeSseFn("TRACE")
914
- },
915
- trace: makeMethodFn("TRACE")
916
- };
917
- };
918
- }
919
- });
920
-
921
- // src/client/client/index.ts
922
- var init_client = __esm({
923
- "src/client/client/index.ts"() {
924
- "use strict";
925
- init_client_gen();
926
- init_utils_gen2();
927
- }
928
- });
929
-
930
- // src/client/client.gen.ts
931
- var client;
932
- var init_client_gen2 = __esm({
933
- "src/client/client.gen.ts"() {
934
- "use strict";
935
- init_client();
936
- init_clientConfig();
937
- client = createClient(createClientConfig(createConfig()));
938
- }
939
- });
940
-
941
- // src/client/sdk.gen.ts
942
- var getApiV1Config, getApiV1CreditsBalance, getApiV1CreditsPacks, postApiV1CreditsPurchase, postApiV1Embeddings, getApiV1Models, postApiV1PhoneCalls, getApiV1PhoneCallsByCallId, postApiV1SubscriptionsCancel, postApiV1SubscriptionsCreateCheckoutSession, postApiV1SubscriptionsCustomerPortal, postApiV1SubscriptionsRenew, getApiV1SubscriptionsStatus, getApiV1WalletsBinding, postApiV1WalletsBinding, postApiV1WalletsBindingNonce, deleteApiV1WalletsBindingByAddress, postAuthOauthByProviderExchange, postAuthOauthByProviderRefresh, postAuthOauthByProviderRevoke;
943
- var init_sdk_gen = __esm({
944
- "src/client/sdk.gen.ts"() {
945
- "use strict";
946
- init_client_gen2();
947
- getApiV1Config = (options) => {
948
- return (options?.client ?? client).get({
949
- url: "/api/v1/config",
950
- ...options
951
- });
952
- };
953
- getApiV1CreditsBalance = (options) => {
954
- return (options?.client ?? client).get({
955
- url: "/api/v1/credits/balance",
956
- ...options
957
- });
958
- };
959
- getApiV1CreditsPacks = (options) => {
960
- return (options?.client ?? client).get({
961
- url: "/api/v1/credits/packs",
962
- ...options
963
- });
964
- };
965
- postApiV1CreditsPurchase = (options) => {
966
- return (options.client ?? client).post({
967
- url: "/api/v1/credits/purchase",
968
- ...options,
969
- headers: {
970
- "Content-Type": "application/json",
971
- ...options.headers
972
- }
973
- });
974
- };
975
- postApiV1Embeddings = (options) => {
976
- return (options.client ?? client).post({
977
- url: "/api/v1/embeddings",
978
- ...options,
979
- headers: {
980
- "Content-Type": "application/json",
981
- ...options.headers
982
- }
983
- });
984
- };
985
- getApiV1Models = (options) => {
986
- return (options?.client ?? client).get({
987
- url: "/api/v1/models",
988
- ...options
989
- });
990
- };
991
- postApiV1PhoneCalls = (options) => {
992
- return (options.client ?? client).post({
993
- url: "/api/v1/phone-calls",
994
- ...options,
995
- headers: {
996
- "Content-Type": "application/json",
997
- ...options.headers
998
- }
999
- });
1000
- };
1001
- getApiV1PhoneCallsByCallId = (options) => {
1002
- return (options.client ?? client).get({
1003
- url: "/api/v1/phone-calls/{call_id}",
1004
- ...options
1005
- });
1006
- };
1007
- postApiV1SubscriptionsCancel = (options) => {
1008
- return (options?.client ?? client).post({
1009
- url: "/api/v1/subscriptions/cancel",
1010
- ...options,
1011
- headers: {
1012
- "Content-Type": "application/json",
1013
- ...options?.headers
1014
- }
1015
- });
1016
- };
1017
- postApiV1SubscriptionsCreateCheckoutSession = (options) => {
1018
- return (options.client ?? client).post({
1019
- url: "/api/v1/subscriptions/create-checkout-session",
1020
- ...options,
1021
- headers: {
1022
- "Content-Type": "application/json",
1023
- ...options.headers
1024
- }
1025
- });
1026
- };
1027
- postApiV1SubscriptionsCustomerPortal = (options) => {
1028
- return (options.client ?? client).post({
1029
- url: "/api/v1/subscriptions/customer-portal",
1030
- ...options,
1031
- headers: {
1032
- "Content-Type": "application/json",
1033
- ...options.headers
1034
- }
1035
- });
1036
- };
1037
- postApiV1SubscriptionsRenew = (options) => {
1038
- return (options?.client ?? client).post({
1039
- url: "/api/v1/subscriptions/renew",
1040
- ...options
1041
- });
1042
- };
1043
- getApiV1SubscriptionsStatus = (options) => {
1044
- return (options?.client ?? client).get({
1045
- url: "/api/v1/subscriptions/status",
1046
- ...options
1047
- });
1048
- };
1049
- getApiV1WalletsBinding = (options) => {
1050
- return (options?.client ?? client).get({
1051
- url: "/api/v1/wallets/binding",
1052
- ...options
1053
- });
1054
- };
1055
- postApiV1WalletsBinding = (options) => {
1056
- return (options.client ?? client).post({
1057
- url: "/api/v1/wallets/binding",
1058
- ...options,
1059
- headers: {
1060
- "Content-Type": "application/json",
1061
- ...options.headers
1062
- }
1063
- });
1064
- };
1065
- postApiV1WalletsBindingNonce = (options) => {
1066
- return (options?.client ?? client).post({
1067
- url: "/api/v1/wallets/binding/nonce",
1068
- ...options
1069
- });
1070
- };
1071
- deleteApiV1WalletsBindingByAddress = (options) => {
1072
- return (options.client ?? client).delete({
1073
- url: "/api/v1/wallets/binding/{address}",
1074
- ...options
1075
- });
1076
- };
1077
- postAuthOauthByProviderExchange = (options) => {
1078
- return (options.client ?? client).post({
1079
- url: "/auth/oauth/{provider}/exchange",
1080
- ...options,
1081
- headers: {
1082
- "Content-Type": "application/json",
1083
- ...options.headers
1084
- }
1085
- });
1086
- };
1087
- postAuthOauthByProviderRefresh = (options) => {
1088
- return (options.client ?? client).post({
1089
- url: "/auth/oauth/{provider}/refresh",
1090
- ...options,
1091
- headers: {
1092
- "Content-Type": "application/json",
1093
- ...options.headers
1094
- }
1095
- });
1096
- };
1097
- postAuthOauthByProviderRevoke = (options) => {
1098
- return (options.client ?? client).post({
1099
- url: "/auth/oauth/{provider}/revoke",
1100
- ...options,
1101
- headers: {
1102
- "Content-Type": "application/json",
1103
- ...options.headers
1104
- }
1105
- });
1106
- };
1107
- }
1108
- });
1109
-
1110
- // src/client/index.ts
1111
- var init_client2 = __esm({
1112
- "src/client/index.ts"() {
1113
- "use strict";
1114
- init_sdk_gen();
1115
- }
1116
- });
1117
-
1118
- // src/lib/logger.ts
1119
- function setLogger(logger) {
1120
- currentLogger = logger;
1121
- }
1122
- function getLogger() {
1123
- return currentLogger;
1124
- }
1125
- var consoleLogger, noopLogger, currentLogger;
1126
- var init_logger = __esm({
1127
- "src/lib/logger.ts"() {
1128
- "use strict";
1129
- consoleLogger = {
1130
- debug: console.log.bind(console),
1131
- info: console.info.bind(console),
1132
- warn: console.warn.bind(console),
1133
- error: console.error.bind(console)
1134
- };
1135
- noopLogger = {
1136
- debug: () => {
1137
- },
1138
- info: () => {
1139
- },
1140
- warn: () => {
1141
- },
1142
- error: () => {
1143
- }
1144
- };
1145
- currentLogger = consoleLogger;
1146
- }
1147
- });
1148
-
1149
- // src/react/useEncryption.ts
1150
- function onClearAllEncryptionState(callback) {
1151
- clearAllEncryptionStateCallbacks.add(callback);
1152
- return () => {
1153
- clearAllEncryptionStateCallbacks.delete(callback);
1154
- };
1155
- }
1156
- function onKeyAvailable(address, callback) {
1157
- if (encryptionKeyStore.has(address)) {
1158
- try {
1159
- callback();
1160
- } catch {
1161
- }
1162
- }
1163
- let callbacks = keyAvailableCallbacks.get(address);
1164
- if (!callbacks) {
1165
- callbacks = /* @__PURE__ */ new Set();
1166
- keyAvailableCallbacks.set(address, callbacks);
1167
- }
1168
- callbacks.add(callback);
1169
- return () => {
1170
- callbacks.delete(callback);
1171
- if (callbacks.size === 0) {
1172
- keyAvailableCallbacks.delete(address);
1173
- }
1174
- };
1175
- }
1176
- function notifyKeyAvailable(address) {
1177
- const callbacks = keyAvailableCallbacks.get(address);
1178
- if (callbacks) {
1179
- for (const cb of callbacks) {
1180
- try {
1181
- cb();
1182
- } catch {
1183
- }
1184
- }
144
+ }
1185
145
  }
1186
146
  }
1187
147
  function getStoredKey(address) {
@@ -3236,7 +2196,7 @@ var init_constants = __esm({
3236
2196
  }
3237
2197
  });
3238
2198
 
3239
- // src/lib/memoryEngine/embeddings.ts
2199
+ // src/lib/memoryEngine/generate.ts
3240
2200
  async function withEmbeddingRetry(call) {
3241
2201
  let last;
3242
2202
  let lastThrown;
@@ -3287,7 +2247,7 @@ async function generateEmbedding(text12, options) {
3287
2247
  throw new Error("Either apiKey or getToken must be provided");
3288
2248
  }
3289
2249
  const response = await withEmbeddingRetry(
3290
- () => postApiV1Embeddings({
2250
+ () => (0, import_client.postApiV1Embeddings)({
3291
2251
  baseUrl,
3292
2252
  body: {
3293
2253
  // Mask PII from the request body only — the cache above still keys on
@@ -3319,7 +2279,7 @@ async function generateEmbedding(text12, options) {
3319
2279
  }
3320
2280
  async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage, maskInput) {
3321
2281
  const response = await withEmbeddingRetry(
3322
- () => postApiV1Embeddings({
2282
+ () => (0, import_client.postApiV1Embeddings)({
3323
2283
  baseUrl,
3324
2284
  // Mask PII from the request body only; cache/order still key on originals.
3325
2285
  body: { input: maskInput ? texts.map(maskInput) : texts, model },
@@ -3420,6 +2380,27 @@ async function generateEmbeddings(texts, options) {
3420
2380
  }
3421
2381
  return results;
3422
2382
  }
2383
+ var import_client, EMBED_MAX_ATTEMPTS, EmbeddingHttpError, DEFAULT_EMBEDDING_BATCH_SIZE, DEFAULT_EMBEDDING_BATCH_CONCURRENCY;
2384
+ var init_generate = __esm({
2385
+ "src/lib/memoryEngine/generate.ts"() {
2386
+ "use strict";
2387
+ import_client = require("@anuma/sdk");
2388
+ init_clientConfig();
2389
+ init_constants();
2390
+ EMBED_MAX_ATTEMPTS = 4;
2391
+ EmbeddingHttpError = class extends Error {
2392
+ constructor(message, status) {
2393
+ super(message);
2394
+ this.name = "EmbeddingHttpError";
2395
+ this.status = status;
2396
+ }
2397
+ };
2398
+ DEFAULT_EMBEDDING_BATCH_SIZE = 100;
2399
+ DEFAULT_EMBEDDING_BATCH_CONCURRENCY = 3;
2400
+ }
2401
+ });
2402
+
2403
+ // src/lib/memoryEngine/embeddings.ts
3423
2404
  async function embedMessage(ctx, messageId, options) {
3424
2405
  let message;
3425
2406
  const conversations = await getConversationsOp(ctx);
@@ -3575,27 +2556,17 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
3575
2556
  }
3576
2557
  return embeddedCount;
3577
2558
  }
3578
- var DEFAULT_MIN_CONTENT_LENGTH, EMBED_MAX_ATTEMPTS, EmbeddingHttpError, DEFAULT_EMBEDDING_BATCH_SIZE, DEFAULT_EMBEDDING_BATCH_CONCURRENCY;
2559
+ var DEFAULT_MIN_CONTENT_LENGTH;
3579
2560
  var init_embeddings = __esm({
3580
2561
  "src/lib/memoryEngine/embeddings.ts"() {
3581
2562
  "use strict";
3582
- init_client2();
3583
- init_clientConfig();
3584
2563
  init_operations();
3585
2564
  init_logger();
3586
2565
  init_chunking();
3587
2566
  init_constants();
2567
+ init_generate();
2568
+ init_generate();
3588
2569
  DEFAULT_MIN_CONTENT_LENGTH = 10;
3589
- EMBED_MAX_ATTEMPTS = 4;
3590
- EmbeddingHttpError = class extends Error {
3591
- constructor(message, status) {
3592
- super(message);
3593
- this.name = "EmbeddingHttpError";
3594
- this.status = status;
3595
- }
3596
- };
3597
- DEFAULT_EMBEDDING_BATCH_SIZE = 100;
3598
- DEFAULT_EMBEDDING_BATCH_CONCURRENCY = 3;
3599
2570
  }
3600
2571
  });
3601
2572
 
@@ -5085,31 +4056,29 @@ async function stampTopicsExtractedAtOp(ctx, memoryIds, extractedAt, version = T
5085
4056
  for (let i = 0; i < uniqueIds.length; i += CHUNK) {
5086
4057
  const chunkIds = uniqueIds.slice(i, i + CHUNK);
5087
4058
  await ctx.database.write(async () => {
5088
- const prepared = [];
4059
+ const records = [];
5089
4060
  for (const id of chunkIds) {
5090
- let record;
5091
4061
  try {
5092
- record = await ctx.vaultMemoryCollection.find(id);
4062
+ records.push(await ctx.vaultMemoryCollection.find(id));
5093
4063
  } catch {
5094
- continue;
5095
- }
5096
- if (record.isDeleted || !isOwnedByCtxUser(ctx, record) || record.topicsUserManaged) {
5097
- continue;
5098
4064
  }
5099
- const originalUpdatedAt = record.updatedAt.getTime();
5100
- prepared.push(
5101
- record.prepareUpdate((r) => {
5102
- r._setRaw("topics_extracted_at", extractedAt);
5103
- r._setRaw("topics_extracted_version", version);
5104
- r._setRaw("updated_at", originalUpdatedAt);
5105
- })
5106
- );
5107
- stamped.push(id);
5108
4065
  }
5109
- if (prepared.length > 0) await ctx.database.batch(...prepared);
5110
- });
5111
- }
5112
- return stamped;
4066
+ const eligible = records.filter(
4067
+ (record) => !record.isDeleted && isOwnedByCtxUser(ctx, record) && !record.topicsUserManaged
4068
+ );
4069
+ const prepared = eligible.map((record) => {
4070
+ const originalUpdatedAt = record.updatedAt.getTime();
4071
+ return record.prepareUpdate((r) => {
4072
+ r._setRaw("topics_extracted_at", extractedAt);
4073
+ r._setRaw("topics_extracted_version", version);
4074
+ r._setRaw("updated_at", originalUpdatedAt);
4075
+ });
4076
+ });
4077
+ for (const record of eligible) stamped.push(record.id);
4078
+ if (prepared.length > 0) await ctx.database.batch(...prepared);
4079
+ });
4080
+ }
4081
+ return stamped;
5113
4082
  }
5114
4083
  async function deleteAllVaultMemoriesForUserOp(ctx, userId) {
5115
4084
  if (ctx.userId !== void 0 && ctx.userId !== userId) return 0;
@@ -7899,8 +6868,142 @@ module.exports = __toCommonJS(index_exports);
7899
6868
  // src/lib/chat/resumeStream.ts
7900
6869
  init_clientConfig();
7901
6870
 
6871
+ // src/client/core/serverSentEvents.gen.ts
6872
+ var createSseClient = ({
6873
+ onRequest,
6874
+ onSseError,
6875
+ onSseEvent,
6876
+ responseTransformer,
6877
+ responseValidator,
6878
+ sseDefaultRetryDelay,
6879
+ sseMaxRetryAttempts,
6880
+ sseMaxRetryDelay,
6881
+ sseSleepFn,
6882
+ url,
6883
+ ...options
6884
+ }) => {
6885
+ let lastEventId;
6886
+ const sleep4 = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
6887
+ const createStream = async function* () {
6888
+ let retryDelay = sseDefaultRetryDelay ?? 3e3;
6889
+ let attempt = 0;
6890
+ const signal = options.signal ?? new AbortController().signal;
6891
+ while (true) {
6892
+ if (signal.aborted) break;
6893
+ attempt++;
6894
+ const headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers);
6895
+ if (lastEventId !== void 0) {
6896
+ headers.set("Last-Event-ID", lastEventId);
6897
+ }
6898
+ try {
6899
+ const requestInit = {
6900
+ redirect: "follow",
6901
+ ...options,
6902
+ body: options.serializedBody,
6903
+ headers,
6904
+ signal
6905
+ };
6906
+ let request = new Request(url, requestInit);
6907
+ if (onRequest) {
6908
+ request = await onRequest(url, requestInit);
6909
+ }
6910
+ const _fetch = options.fetch ?? globalThis.fetch;
6911
+ const response = await _fetch(request);
6912
+ if (!response.ok)
6913
+ throw new Error(
6914
+ `SSE failed: ${response.status} ${response.statusText}`
6915
+ );
6916
+ if (!response.body) throw new Error("No body in SSE response");
6917
+ const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
6918
+ let buffer = "";
6919
+ const abortHandler = () => {
6920
+ try {
6921
+ reader.cancel();
6922
+ } catch {
6923
+ }
6924
+ };
6925
+ signal.addEventListener("abort", abortHandler);
6926
+ try {
6927
+ while (true) {
6928
+ const { done, value } = await reader.read();
6929
+ if (done) break;
6930
+ buffer += value;
6931
+ const chunks = buffer.split("\n\n");
6932
+ buffer = chunks.pop() ?? "";
6933
+ for (const chunk of chunks) {
6934
+ const lines = chunk.split("\n");
6935
+ const dataLines = [];
6936
+ let eventName;
6937
+ for (const line of lines) {
6938
+ if (line.startsWith("data:")) {
6939
+ dataLines.push(line.replace(/^data:\s*/, ""));
6940
+ } else if (line.startsWith("event:")) {
6941
+ eventName = line.replace(/^event:\s*/, "");
6942
+ } else if (line.startsWith("id:")) {
6943
+ lastEventId = line.replace(/^id:\s*/, "");
6944
+ } else if (line.startsWith("retry:")) {
6945
+ const parsed = Number.parseInt(
6946
+ line.replace(/^retry:\s*/, ""),
6947
+ 10
6948
+ );
6949
+ if (!Number.isNaN(parsed)) {
6950
+ retryDelay = parsed;
6951
+ }
6952
+ }
6953
+ }
6954
+ let data;
6955
+ let parsedJson = false;
6956
+ if (dataLines.length) {
6957
+ const rawData = dataLines.join("\n");
6958
+ try {
6959
+ data = JSON.parse(rawData);
6960
+ parsedJson = true;
6961
+ } catch {
6962
+ data = rawData;
6963
+ }
6964
+ }
6965
+ if (parsedJson) {
6966
+ if (responseValidator) {
6967
+ await responseValidator(data);
6968
+ }
6969
+ if (responseTransformer) {
6970
+ data = await responseTransformer(data);
6971
+ }
6972
+ }
6973
+ onSseEvent?.({
6974
+ data,
6975
+ event: eventName,
6976
+ id: lastEventId,
6977
+ retry: retryDelay
6978
+ });
6979
+ if (dataLines.length) {
6980
+ yield data;
6981
+ }
6982
+ }
6983
+ }
6984
+ } finally {
6985
+ signal.removeEventListener("abort", abortHandler);
6986
+ reader.releaseLock();
6987
+ }
6988
+ break;
6989
+ } catch (error) {
6990
+ onSseError?.(error);
6991
+ if (sseMaxRetryAttempts !== void 0 && attempt >= sseMaxRetryAttempts) {
6992
+ break;
6993
+ }
6994
+ const backoff = Math.min(
6995
+ retryDelay * 2 ** (attempt - 1),
6996
+ sseMaxRetryDelay ?? 3e4
6997
+ );
6998
+ await sleep4(backoff);
6999
+ }
7000
+ }
7001
+ };
7002
+ const stream = createStream();
7003
+ return { stream };
7004
+ };
7005
+
7902
7006
  // src/lib/chat/toolLoop.ts
7903
- init_serverSentEvents_gen();
7904
7007
  init_clientConfig();
7905
7008
  init_embeddings();
7906
7009
  init_redactor();
@@ -15312,8 +14415,12 @@ init_recall();
15312
14415
 
15313
14416
  // src/lib/memory/recallTool.ts
15314
14417
  init_recall();
14418
+
14419
+ // src/lib/memory/recallConstants.ts
15315
14420
  var RECALL_TOOL_NAME = "recall_memory";
15316
14421
  var RECALL_MAX_LIMIT = 50;
14422
+
14423
+ // src/lib/memory/recallTool.ts
15317
14424
  var DEFAULT_LIMIT2 = 8;
15318
14425
  var DEFAULT_BUDGET2 = "low";
15319
14426
  function formatEventTime(start, end, kind) {
@@ -16882,6 +15989,9 @@ async function preprocessFiles(files, options = {}) {
16882
15989
  };
16883
15990
  }
16884
15991
 
15992
+ // src/lib/tools/clientToolSelection.ts
15993
+ init_generate();
15994
+
16885
15995
  // src/tools/appBuilderPrompt.ts
16886
15996
  var APP_BUILDER_PROMPT = `App Builder tools (create_file, patch_file, and the rest described below) are available this turn, but they are OPTIONAL \u2014 having them does not mean you should build anything.
16887
15997
 
@@ -16986,7 +16096,7 @@ WORKFLOW:
16986
16096
 
16987
16097
  // src/lib/tools/serverTools.ts
16988
16098
  init_logger();
16989
- init_embeddings();
16099
+ init_generate();
16990
16100
  init_vector();
16991
16101
  var DEFAULT_CACHE_EXPIRATION_MS = 24 * 60 * 60 * 1e3;
16992
16102
  var SERVER_TOOLS_CACHE_KEY = "sdk_server_tools_cache";
@@ -17054,7 +16164,7 @@ function getCachedServerTools() {
17054
16164
  if (!cached) return null;
17055
16165
  const parsed = JSON.parse(cached);
17056
16166
  if (parsed.version !== CACHE_VERSION) {
17057
- clearServerToolsCache();
16167
+ removeLocalStorageCache();
17058
16168
  return null;
17059
16169
  }
17060
16170
  return parsed;
@@ -17066,37 +16176,45 @@ function isCacheExpired(cache, expirationMs = DEFAULT_CACHE_EXPIRATION_MS) {
17066
16176
  if (!cache) return true;
17067
16177
  return Date.now() - cache.timestamp > expirationMs;
17068
16178
  }
17069
- function cacheServerTools(tools, checksum) {
17070
- if (typeof localStorage === "undefined") return;
17071
- const cacheData = {
16179
+ function buildCacheEntry(tools, checksum) {
16180
+ return {
17072
16181
  tools,
17073
16182
  timestamp: Date.now(),
17074
16183
  version: CACHE_VERSION,
17075
16184
  ...checksum && { checksum }
17076
16185
  };
16186
+ }
16187
+ function writeLocalStorageCache(entry) {
16188
+ if (typeof localStorage === "undefined") return;
17077
16189
  try {
17078
- localStorage.setItem(SERVER_TOOLS_CACHE_KEY, JSON.stringify(cacheData));
16190
+ localStorage.setItem(SERVER_TOOLS_CACHE_KEY, JSON.stringify(entry));
17079
16191
  } catch (error) {
17080
16192
  getLogger().warn("[serverTools] Failed to cache tools:", error);
17081
16193
  }
17082
16194
  }
17083
- function clearServerToolsCache() {
16195
+ function removeLocalStorageCache() {
17084
16196
  if (typeof localStorage === "undefined") return;
17085
16197
  localStorage.removeItem(SERVER_TOOLS_CACHE_KEY);
17086
16198
  }
17087
- function getToolsChecksum2() {
17088
- const cached = getCachedServerTools();
17089
- return cached?.checksum;
16199
+ var localStorageToolsCache = {
16200
+ get: getCachedServerTools,
16201
+ set: writeLocalStorageCache,
16202
+ clear: removeLocalStorageCache
16203
+ };
16204
+ function clearServerToolsCache(cache = localStorageToolsCache) {
16205
+ return cache.clear?.();
16206
+ }
16207
+ function getToolsChecksum2(cache = localStorageToolsCache) {
16208
+ const cached = cache.get();
16209
+ return cached instanceof Promise ? cached.then((c) => c?.checksum) : cached?.checksum;
17090
16210
  }
17091
- function shouldRefreshTools(responseChecksum) {
16211
+ function shouldRefreshTools(responseChecksum, cache = localStorageToolsCache) {
17092
16212
  if (!responseChecksum) {
17093
16213
  return false;
17094
16214
  }
17095
- const cachedChecksum = getToolsChecksum2();
17096
- if (!cachedChecksum) {
17097
- return true;
17098
- }
17099
- return cachedChecksum !== responseChecksum;
16215
+ const decide = (cachedChecksum2) => !cachedChecksum2 || cachedChecksum2 !== responseChecksum;
16216
+ const cachedChecksum = getToolsChecksum2(cache);
16217
+ return cachedChecksum instanceof Promise ? cachedChecksum.then(decide) : decide(cachedChecksum);
17100
16218
  }
17101
16219
  async function fetchServerToolsFromApi(baseUrl, token) {
17102
16220
  const response = await fetch(`${baseUrl}/api/v1/tools`, {
@@ -17118,9 +16236,23 @@ async function getServerTools(options) {
17118
16236
  cacheExpirationMs = DEFAULT_CACHE_EXPIRATION_MS,
17119
16237
  forceRefresh = false,
17120
16238
  getToken,
17121
- apiKey
16239
+ apiKey,
16240
+ cache = localStorageToolsCache
17122
16241
  } = options;
17123
- const cached = getCachedServerTools();
16242
+ const persistCache = async (entry) => {
16243
+ try {
16244
+ await cache.set(entry);
16245
+ } catch (error) {
16246
+ getLogger().warn("[serverTools] Cache write failed (non-fatal):", error);
16247
+ }
16248
+ };
16249
+ let rawCached = null;
16250
+ try {
16251
+ rawCached = await cache.get();
16252
+ } catch (error) {
16253
+ getLogger().warn("[serverTools] Cache read failed; falling through to server fetch:", error);
16254
+ }
16255
+ const cached = rawCached && rawCached.version === CACHE_VERSION ? rawCached : null;
17124
16256
  const cacheValid = !isCacheExpired(cached, cacheExpirationMs);
17125
16257
  if (cached && cacheValid && !forceRefresh) {
17126
16258
  return cached.tools;
@@ -17141,7 +16273,7 @@ async function getServerTools(options) {
17141
16273
  }
17142
16274
  const data = await response.json();
17143
16275
  const { tools: tools2, checksum: checksum2 } = convertServerToolsResponse(data);
17144
- cacheServerTools(tools2, checksum2);
16276
+ await persistCache(buildCacheEntry(tools2, checksum2));
17145
16277
  return tools2;
17146
16278
  }
17147
16279
  if (!getToken) {
@@ -17154,7 +16286,7 @@ async function getServerTools(options) {
17154
16286
  return cached?.tools ?? [];
17155
16287
  }
17156
16288
  const { tools, checksum } = await fetchServerToolsFromApi(effectiveBaseUrl, token);
17157
- cacheServerTools(tools, checksum);
16289
+ await persistCache(buildCacheEntry(tools, checksum));
17158
16290
  return tools;
17159
16291
  } catch (error) {
17160
16292
  getLogger().error("[serverTools] Failed to fetch server tools:", error);
@@ -17659,13 +16791,14 @@ async function selectServerToolsForPrompt(options) {
17659
16791
  baseUrl,
17660
16792
  embeddingModel,
17661
16793
  cacheExpirationMs,
16794
+ cache,
17662
16795
  deferLoading
17663
16796
  } = options;
17664
16797
  if (serverToolsFilter === void 0) return [];
17665
16798
  if (Array.isArray(serverToolsFilter) && serverToolsFilter.length === 0) return [];
17666
16799
  let allServerTools;
17667
16800
  try {
17668
- allServerTools = await getServerTools({ baseUrl, cacheExpirationMs, getToken });
16801
+ allServerTools = await getServerTools({ baseUrl, cacheExpirationMs, getToken, cache });
17669
16802
  } catch {
17670
16803
  return [];
17671
16804
  }
@@ -17689,6 +16822,123 @@ async function selectServerToolsForPrompt(options) {
17689
16822
  return filterServerTools(allServerTools, serverToolsFilter);
17690
16823
  }
17691
16824
 
16825
+ // src/lib/tools/clientToolSelection.ts
16826
+ function getToolName2(t) {
16827
+ const fn = t.function;
16828
+ return fn?.name || t.name || "";
16829
+ }
16830
+ function getToolDescription(t) {
16831
+ const fn = t.function;
16832
+ return fn?.description || t.description || getToolName2(t);
16833
+ }
16834
+ function computeToolGuidance(selectedServerTools, selectedClientTools, extraToolSets, activatedSetNames) {
16835
+ const names = [
16836
+ ...selectedServerTools.map((t) => t.name),
16837
+ ...(selectedClientTools ?? []).map(getToolName2)
16838
+ ].filter(Boolean);
16839
+ const toolSets = extraToolSets.length > 0 ? [...BUILT_IN_TOOL_SETS, ...extraToolSets] : BUILT_IN_TOOL_SETS;
16840
+ const prompts = toolSetSystemPrompts(names, toolSets, activatedSetNames);
16841
+ return prompts.length > 0 ? prompts.join("\n\n") : void 0;
16842
+ }
16843
+ async function autoFilterClientTools(clientTools, promptEmbeddings, cache, embeddingOptions, extraToolSets = [], activeToolSets = [], noEmbeddingsReason = "short-prompt") {
16844
+ const isMemoryTool = (t) => {
16845
+ const name = getToolName2(t);
16846
+ return name.startsWith("memory_vault_") || name === RECALL_TOOL_NAME;
16847
+ };
16848
+ const alwaysInclude = clientTools.filter(isMemoryTool);
16849
+ const filterCandidates = clientTools.filter((t) => !isMemoryTool(t));
16850
+ if (filterCandidates.length === 0) {
16851
+ return { tools: clientTools, activatedSetNames: /* @__PURE__ */ new Set() };
16852
+ }
16853
+ if (!promptEmbeddings && noEmbeddingsReason === "error") {
16854
+ return { tools: clientTools, activatedSetNames: /* @__PURE__ */ new Set() };
16855
+ }
16856
+ if (!promptEmbeddings) {
16857
+ if (activeToolSets.length === 0) {
16858
+ return { tools: [], activatedSetNames: /* @__PURE__ */ new Set() };
16859
+ }
16860
+ const allSets = extraToolSets.length > 0 ? [...BUILT_IN_TOOL_SETS, ...extraToolSets] : BUILT_IN_TOOL_SETS;
16861
+ const activeSets = allSets.filter((s) => activeToolSets.includes(s.name));
16862
+ const stickyMembers = new Set(activeSets.flatMap((s) => s.members));
16863
+ return {
16864
+ tools: [
16865
+ ...alwaysInclude,
16866
+ ...filterCandidates.filter((t) => stickyMembers.has(getToolName2(t)))
16867
+ ],
16868
+ activatedSetNames: new Set(activeSets.map((s) => s.name))
16869
+ };
16870
+ }
16871
+ const toolsNeedingEmbeddings = [];
16872
+ for (const t of filterCandidates) {
16873
+ const name = getToolName2(t);
16874
+ if (name && !cache.has(name)) {
16875
+ toolsNeedingEmbeddings.push({ name, description: getToolDescription(t) });
16876
+ }
16877
+ }
16878
+ if (toolsNeedingEmbeddings.length > 0) {
16879
+ try {
16880
+ const descriptions = toolsNeedingEmbeddings.map((t) => t.description);
16881
+ const embeddings = await generateEmbeddings(descriptions, embeddingOptions);
16882
+ for (let i = 0; i < toolsNeedingEmbeddings.length; i++) {
16883
+ cache.set(toolsNeedingEmbeddings[i].name, embeddings[i]);
16884
+ }
16885
+ } catch {
16886
+ return { tools: clientTools, activatedSetNames: /* @__PURE__ */ new Set() };
16887
+ }
16888
+ }
16889
+ const pseudoServerTools = [];
16890
+ for (const t of filterCandidates) {
16891
+ const name = getToolName2(t);
16892
+ const embedding = cache.get(name);
16893
+ if (!embedding) continue;
16894
+ const fn = t.function;
16895
+ const params = fn?.parameters || fn?.arguments || {
16896
+ type: "object",
16897
+ properties: {},
16898
+ required: []
16899
+ };
16900
+ pseudoServerTools.push({
16901
+ type: "function",
16902
+ name,
16903
+ description: getToolDescription(t),
16904
+ parameters: params,
16905
+ embedding
16906
+ });
16907
+ }
16908
+ const matches = findMatchingTools(promptEmbeddings, pseudoServerTools, {
16909
+ limit: MAX_CLIENT_TOOLS_AFTER_FILTER,
16910
+ minSimilarity: CLIENT_TOOLS_MIN_SIMILARITY,
16911
+ filterAmbiguous: true,
16912
+ // See CLIENT_TOOLS_RELEVANCE_RATIO: 0.75 admits the second intent of a
16913
+ // multi-intent prompt (which lands ~75-80% of the dominant match), while
16914
+ // still trimming the loose tail. The earlier 0.9 made a second intent
16915
+ // structurally unselectable; the anchorMinSimilarity gates (0.53-0.55)
16916
+ // remain the guard against borderline anchors activating a whole set.
16917
+ relevanceRatio: CLIENT_TOOLS_RELEVANCE_RATIO
16918
+ });
16919
+ const matchedNames = new Set(matches.map((m) => m.tool.name));
16920
+ const scores = scoreTools(promptEmbeddings, pseudoServerTools);
16921
+ const availableNames = new Set(filterCandidates.map(getToolName2));
16922
+ const toolSets = extraToolSets.length > 0 ? [...BUILT_IN_TOOL_SETS, ...extraToolSets] : BUILT_IN_TOOL_SETS;
16923
+ const activeSetNames = activeToolSets.length > 0 ? new Set(activeToolSets) : void 0;
16924
+ const finalNames = expandToolSetsAdditive(
16925
+ matchedNames,
16926
+ availableNames,
16927
+ scores,
16928
+ toolSets,
16929
+ activeSetNames
16930
+ );
16931
+ const activatedSetNames = activatedToolSetNames(scores, toolSets, activeSetNames);
16932
+ if (finalNames.size === 0) {
16933
+ return { tools: alwaysInclude, activatedSetNames };
16934
+ }
16935
+ const filtered = filterCandidates.filter((t) => {
16936
+ const name = getToolName2(t);
16937
+ return name && finalNames.has(name);
16938
+ });
16939
+ return { tools: [...alwaysInclude, ...filtered], activatedSetNames };
16940
+ }
16941
+
17692
16942
  // src/react/useChatMedia.ts
17693
16943
  var import_react4 = require("react");
17694
16944
  init_logger();
@@ -17942,142 +17192,27 @@ function useChatMedia(options) {
17942
17192
  // src/react/useChatStorage.ts
17943
17193
  init_useEncryption();
17944
17194
  init_useEncryption();
17945
- function getToolName2(t) {
17946
- const fn = t.function;
17947
- return fn?.name || t.name || "";
17948
- }
17949
- function getToolDescription(t) {
17950
- const fn = t.function;
17951
- return fn?.description || t.description || getToolName2(t);
17952
- }
17953
- function computeToolGuidance(selectedServerTools, selectedClientTools, extraToolSets, activatedSetNames) {
17954
- const names = [
17955
- ...selectedServerTools.map((t) => t.name),
17956
- ...(selectedClientTools ?? []).map(getToolName2)
17957
- ].filter(Boolean);
17958
- const toolSets = extraToolSets.length > 0 ? [...BUILT_IN_TOOL_SETS, ...extraToolSets] : BUILT_IN_TOOL_SETS;
17959
- const prompts = toolSetSystemPrompts(names, toolSets, activatedSetNames);
17960
- return prompts.length > 0 ? prompts.join("\n\n") : void 0;
17961
- }
17962
- async function autoFilterClientTools(clientTools, promptEmbeddings, cache, embeddingOptions, extraToolSets = [], activeToolSets = [], noEmbeddingsReason = "short-prompt") {
17963
- const isMemoryTool = (t) => {
17964
- const name = getToolName2(t);
17965
- return name.startsWith("memory_vault_") || name === RECALL_TOOL_NAME;
17966
- };
17967
- const alwaysInclude = clientTools.filter(isMemoryTool);
17968
- const filterCandidates = clientTools.filter((t) => !isMemoryTool(t));
17969
- if (filterCandidates.length === 0) {
17970
- return { tools: clientTools, activatedSetNames: /* @__PURE__ */ new Set() };
17971
- }
17972
- if (!promptEmbeddings && noEmbeddingsReason === "error") {
17973
- return { tools: clientTools, activatedSetNames: /* @__PURE__ */ new Set() };
17195
+ async function previewToolSelection(options) {
17196
+ const {
17197
+ prompt,
17198
+ clientTools = [],
17199
+ serverToolsFilter,
17200
+ serverToolsConfig,
17201
+ getToken,
17202
+ apiKey,
17203
+ baseUrl,
17204
+ embeddingModel = DEFAULT_API_EMBEDDING_MODEL,
17205
+ extraToolSets,
17206
+ activeToolSets,
17207
+ clientToolEmbeddingsCache
17208
+ } = options;
17209
+ if (!getToken && !apiKey) {
17210
+ throw new Error(
17211
+ "previewToolSelection requires either `getToken` (Bearer auth) or `apiKey` (X-API-Key auth) \u2014 without one, embeddings and the server tool catalog cannot be fetched."
17212
+ );
17974
17213
  }
17975
- if (!promptEmbeddings) {
17976
- if (activeToolSets.length === 0) {
17977
- return { tools: [], activatedSetNames: /* @__PURE__ */ new Set() };
17978
- }
17979
- const allSets = extraToolSets.length > 0 ? [...BUILT_IN_TOOL_SETS, ...extraToolSets] : BUILT_IN_TOOL_SETS;
17980
- const activeSets = allSets.filter((s) => activeToolSets.includes(s.name));
17981
- const stickyMembers = new Set(activeSets.flatMap((s) => s.members));
17982
- return {
17983
- tools: [
17984
- ...alwaysInclude,
17985
- ...filterCandidates.filter((t) => stickyMembers.has(getToolName2(t)))
17986
- ],
17987
- activatedSetNames: new Set(activeSets.map((s) => s.name))
17988
- };
17989
- }
17990
- const toolsNeedingEmbeddings = [];
17991
- for (const t of filterCandidates) {
17992
- const name = getToolName2(t);
17993
- if (name && !cache.has(name)) {
17994
- toolsNeedingEmbeddings.push({ name, description: getToolDescription(t) });
17995
- }
17996
- }
17997
- if (toolsNeedingEmbeddings.length > 0) {
17998
- try {
17999
- const descriptions = toolsNeedingEmbeddings.map((t) => t.description);
18000
- const embeddings = await generateEmbeddings(descriptions, embeddingOptions);
18001
- for (let i = 0; i < toolsNeedingEmbeddings.length; i++) {
18002
- cache.set(toolsNeedingEmbeddings[i].name, embeddings[i]);
18003
- }
18004
- } catch {
18005
- return { tools: clientTools, activatedSetNames: /* @__PURE__ */ new Set() };
18006
- }
18007
- }
18008
- const pseudoServerTools = [];
18009
- for (const t of filterCandidates) {
18010
- const name = getToolName2(t);
18011
- const embedding = cache.get(name);
18012
- if (!embedding) continue;
18013
- const fn = t.function;
18014
- const params = fn?.parameters || fn?.arguments || {
18015
- type: "object",
18016
- properties: {},
18017
- required: []
18018
- };
18019
- pseudoServerTools.push({
18020
- type: "function",
18021
- name,
18022
- description: getToolDescription(t),
18023
- parameters: params,
18024
- embedding
18025
- });
18026
- }
18027
- const matches = findMatchingTools(promptEmbeddings, pseudoServerTools, {
18028
- limit: MAX_CLIENT_TOOLS_AFTER_FILTER,
18029
- minSimilarity: CLIENT_TOOLS_MIN_SIMILARITY,
18030
- filterAmbiguous: true,
18031
- // See CLIENT_TOOLS_RELEVANCE_RATIO: 0.75 admits the second intent of a
18032
- // multi-intent prompt (which lands ~75-80% of the dominant match), while
18033
- // still trimming the loose tail. The earlier 0.9 made a second intent
18034
- // structurally unselectable; the anchorMinSimilarity gates (0.53-0.55)
18035
- // remain the guard against borderline anchors activating a whole set.
18036
- relevanceRatio: CLIENT_TOOLS_RELEVANCE_RATIO
18037
- });
18038
- const matchedNames = new Set(matches.map((m) => m.tool.name));
18039
- const scores = scoreTools(promptEmbeddings, pseudoServerTools);
18040
- const availableNames = new Set(filterCandidates.map(getToolName2));
18041
- const toolSets = extraToolSets.length > 0 ? [...BUILT_IN_TOOL_SETS, ...extraToolSets] : BUILT_IN_TOOL_SETS;
18042
- const activeSetNames = activeToolSets.length > 0 ? new Set(activeToolSets) : void 0;
18043
- const finalNames = expandToolSetsAdditive(
18044
- matchedNames,
18045
- availableNames,
18046
- scores,
18047
- toolSets,
18048
- activeSetNames
18049
- );
18050
- const activatedSetNames = activatedToolSetNames(scores, toolSets, activeSetNames);
18051
- if (finalNames.size === 0) {
18052
- return { tools: alwaysInclude, activatedSetNames };
18053
- }
18054
- const filtered = filterCandidates.filter((t) => {
18055
- const name = getToolName2(t);
18056
- return name && finalNames.has(name);
18057
- });
18058
- return { tools: [...alwaysInclude, ...filtered], activatedSetNames };
18059
- }
18060
- async function previewToolSelection(options) {
18061
- const {
18062
- prompt,
18063
- clientTools = [],
18064
- serverToolsFilter,
18065
- serverToolsConfig,
18066
- getToken,
18067
- apiKey,
18068
- baseUrl,
18069
- embeddingModel = DEFAULT_API_EMBEDDING_MODEL,
18070
- extraToolSets,
18071
- activeToolSets,
18072
- clientToolEmbeddingsCache
18073
- } = options;
18074
- if (!getToken && !apiKey) {
18075
- throw new Error(
18076
- "previewToolSelection requires either `getToken` (Bearer auth) or `apiKey` (X-API-Key auth) \u2014 without one, embeddings and the server tool catalog cannot be fetched."
18077
- );
18078
- }
18079
- if (!prompt.trim()) {
18080
- return { clientToolNames: [], serverToolNames: [] };
17214
+ if (!prompt.trim()) {
17215
+ return { clientToolNames: [], serverToolNames: [] };
18081
17216
  }
18082
17217
  if (prompt.length < MIN_CONTENT_LENGTH_FOR_TOOLS) {
18083
17218
  const { tools: gatedTools } = await autoFilterClientTools(
@@ -18095,7 +17230,8 @@ async function previewToolSelection(options) {
18095
17230
  baseUrl,
18096
17231
  cacheExpirationMs: serverToolsConfig?.cacheExpirationMs,
18097
17232
  getToken,
18098
- apiKey
17233
+ apiKey,
17234
+ cache: serverToolsConfig?.cache
18099
17235
  });
18100
17236
  const allow = new Set(serverToolsFilter);
18101
17237
  gatedServerNames = allServerTools.filter((t) => allow.has(t.name)).map((t) => t.name);
@@ -18143,7 +17279,8 @@ async function previewToolSelection(options) {
18143
17279
  baseUrl,
18144
17280
  cacheExpirationMs: serverToolsConfig?.cacheExpirationMs,
18145
17281
  getToken,
18146
- apiKey
17282
+ apiKey,
17283
+ cache: serverToolsConfig?.cache
18147
17284
  });
18148
17285
  if (serverToolsConfig?.deferLoading?.enabled) {
18149
17286
  serverToolNames = allServerTools.map((t) => t.name);
@@ -19136,7 +18273,8 @@ function useChatStorage(options) {
19136
18273
  const allServerTools = await getServerTools({
19137
18274
  baseUrl,
19138
18275
  cacheExpirationMs: serverToolsConfig?.cacheExpirationMs,
19139
- getToken
18276
+ getToken,
18277
+ cache: serverToolsConfig?.cache
19140
18278
  });
19141
18279
  if (serverToolsConfig?.deferLoading?.enabled) {
19142
18280
  filteredServerTools2 = allServerTools;
@@ -19154,12 +18292,14 @@ function useChatStorage(options) {
19154
18292
  let filteredClientTools2 = clientTools;
19155
18293
  let clientActivatedSetNames2;
19156
18294
  if (clientToolsFilter && clientTools?.length) {
19157
- const clientToolNames = clientToolsFilter(skipStorageEmbeddings, clientTools);
19158
- filteredClientTools2 = clientTools.filter((t) => {
19159
- const fn = t.function;
19160
- const name = fn?.name || t.name;
19161
- return clientToolNames.includes(name);
19162
- });
18295
+ if (!skipStorageEmbeddingsFailed) {
18296
+ const clientToolNames = clientToolsFilter(skipStorageEmbeddings, clientTools);
18297
+ filteredClientTools2 = clientTools.filter((t) => {
18298
+ const fn = t.function;
18299
+ const name = fn?.name || t.name;
18300
+ return clientToolNames.includes(name);
18301
+ });
18302
+ }
19163
18303
  } else if (clientTools?.length && getToken) {
19164
18304
  const clientFilterResult = await autoFilterClientTools(
19165
18305
  clientTools,
@@ -19226,8 +18366,20 @@ function useChatStorage(options) {
19226
18366
  error: result2.error || "Unknown error"
19227
18367
  };
19228
18368
  }
19229
- if (getToken && shouldRefreshTools(getToolsChecksum(result2.data))) {
19230
- getServerTools({ baseUrl, getToken, forceRefresh: true }).catch((err) => {
18369
+ const refreshResponse = result2.data;
18370
+ if (getToken) {
18371
+ Promise.resolve().then(
18372
+ () => shouldRefreshTools(getToolsChecksum(refreshResponse), serverToolsConfig?.cache)
18373
+ ).then((refresh) => {
18374
+ if (refresh) {
18375
+ return getServerTools({
18376
+ baseUrl,
18377
+ getToken,
18378
+ forceRefresh: true,
18379
+ cache: serverToolsConfig?.cache
18380
+ });
18381
+ }
18382
+ }).catch((err) => {
19231
18383
  getLogger().warn("[useChatStorage] Failed to refresh server tools cache:", err);
19232
18384
  });
19233
18385
  }
@@ -19494,7 +18646,8 @@ function useChatStorage(options) {
19494
18646
  const allServerTools = await getServerTools({
19495
18647
  baseUrl,
19496
18648
  cacheExpirationMs: serverToolsConfig?.cacheExpirationMs,
19497
- getToken
18649
+ getToken,
18650
+ cache: serverToolsConfig?.cache
19498
18651
  });
19499
18652
  if (serverToolsConfig?.deferLoading?.enabled && effectiveApiType === "responses") {
19500
18653
  filteredServerTools = allServerTools;
@@ -19512,12 +18665,14 @@ function useChatStorage(options) {
19512
18665
  let filteredClientTools = clientTools;
19513
18666
  let clientActivatedSetNames;
19514
18667
  if (clientToolsFilter && clientTools?.length) {
19515
- const clientToolNames = clientToolsFilter(userMessageEmbeddings ?? null, clientTools);
19516
- filteredClientTools = clientTools.filter((t) => {
19517
- const fn = t.function;
19518
- const name = fn?.name || t.name;
19519
- return clientToolNames.includes(name);
19520
- });
18668
+ if (!userMessageEmbeddingsFailed) {
18669
+ const clientToolNames = clientToolsFilter(userMessageEmbeddings ?? null, clientTools);
18670
+ filteredClientTools = clientTools.filter((t) => {
18671
+ const fn = t.function;
18672
+ const name = fn?.name || t.name;
18673
+ return clientToolNames.includes(name);
18674
+ });
18675
+ }
19521
18676
  } else if (clientTools?.length && getToken) {
19522
18677
  const clientFilterResult = await autoFilterClientTools(
19523
18678
  clientTools,
@@ -19837,8 +18992,17 @@ Based on these results, continue with the task.`;
19837
18992
  } catch {
19838
18993
  }
19839
18994
  }
19840
- if (getToken && shouldRefreshTools(getToolsChecksum(responseData))) {
19841
- getServerTools({ baseUrl, getToken, forceRefresh: true }).catch((err) => {
18995
+ if (getToken) {
18996
+ Promise.resolve().then(() => shouldRefreshTools(getToolsChecksum(responseData), serverToolsConfig?.cache)).then((refresh) => {
18997
+ if (refresh) {
18998
+ return getServerTools({
18999
+ baseUrl,
19000
+ getToken,
19001
+ forceRefresh: true,
19002
+ cache: serverToolsConfig?.cache
19003
+ });
19004
+ }
19005
+ }).catch((err) => {
19842
19006
  getLogger().warn("[useChatStorage] Failed to refresh server tools cache:", err);
19843
19007
  });
19844
19008
  }
@@ -21932,6 +21096,7 @@ async function updateVaultFolderOp(ctx, id, opts) {
21932
21096
  if (record.isDeleted) return null;
21933
21097
  const scopeChanged = opts.scope !== void 0 && opts.scope !== record.scope;
21934
21098
  const updated = await ctx.database.write(async () => {
21099
+ const memories = scopeChanged ? await ctx.vaultMemoryCollection.query(import_watermelondb27.Q.where("folder_id", id), import_watermelondb27.Q.where("is_deleted", false)).fetch() : [];
21935
21100
  const updates = [];
21936
21101
  updates.push(
21937
21102
  record.prepareUpdate((r) => {
@@ -21939,15 +21104,12 @@ async function updateVaultFolderOp(ctx, id, opts) {
21939
21104
  if (opts.scope !== void 0) r._setRaw("scope", opts.scope);
21940
21105
  })
21941
21106
  );
21942
- if (scopeChanged) {
21943
- const memories = await ctx.vaultMemoryCollection.query(import_watermelondb27.Q.where("folder_id", id), import_watermelondb27.Q.where("is_deleted", false)).fetch();
21944
- for (const memory of memories) {
21945
- updates.push(
21946
- memory.prepareUpdate((r) => {
21947
- r._setRaw("scope", opts.scope);
21948
- })
21949
- );
21950
- }
21107
+ for (const memory of memories) {
21108
+ updates.push(
21109
+ memory.prepareUpdate((r) => {
21110
+ r._setRaw("scope", opts.scope);
21111
+ })
21112
+ );
21951
21113
  }
21952
21114
  await ctx.database.batch(...updates);
21953
21115
  return ctx.vaultFolderCollection.find(id);
@@ -23407,452 +22569,1270 @@ function useExportPdf() {
23407
22569
  const canvas = await renderElementToCanvas(element, { onProgress: setProgress });
23408
22570
  return canvas;
23409
22571
  } catch (err) {
23410
- const processed = toError(err);
23411
- setError(processed);
23412
- throw processed;
22572
+ const processed = toError(err);
22573
+ setError(processed);
22574
+ throw processed;
22575
+ } finally {
22576
+ setIsExporting(false);
22577
+ }
22578
+ },
22579
+ []
22580
+ );
22581
+ return {
22582
+ exportElementToPdf: wrappedExportElement,
22583
+ exportMarkdownToPdf: wrappedExportMarkdown,
22584
+ downloadElementAsPdf,
22585
+ downloadMarkdownAsPdf,
22586
+ renderElementToCanvas: wrappedRenderToCanvas,
22587
+ isExporting,
22588
+ progress,
22589
+ error
22590
+ };
22591
+ }
22592
+
22593
+ // src/react/useOCR.ts
22594
+ var import_react11 = require("react");
22595
+ var import_tesseract = __toESM(require("tesseract.js"));
22596
+ init_logger();
22597
+ function useOCR() {
22598
+ const [isProcessing, setIsProcessing] = (0, import_react11.useState)(false);
22599
+ const [error, setError] = (0, import_react11.useState)(null);
22600
+ const extractOCRContext = (0, import_react11.useCallback)(async (files) => {
22601
+ setIsProcessing(true);
22602
+ setError(null);
22603
+ try {
22604
+ if (files.length === 0) {
22605
+ return null;
22606
+ }
22607
+ const contexts = await Promise.all(
22608
+ files.map(async (file) => {
22609
+ try {
22610
+ let imagesToProcess = [];
22611
+ const language = file.language || "eng";
22612
+ const filename = file.filename || (file.url instanceof File ? file.url.name : "");
22613
+ let isPdf = false;
22614
+ if (typeof file.url === "string") {
22615
+ isPdf = file.url.toLowerCase().endsWith(".pdf") || (filename?.toLowerCase().endsWith(".pdf") ?? false);
22616
+ } else if (file.url instanceof Blob) {
22617
+ isPdf = file.url.type === "application/pdf" || (filename?.toLowerCase().endsWith(".pdf") ?? false);
22618
+ }
22619
+ if (isPdf) {
22620
+ let pdfUrl;
22621
+ let shouldRevoke = false;
22622
+ if (typeof file.url === "string") {
22623
+ pdfUrl = file.url;
22624
+ } else {
22625
+ pdfUrl = URL.createObjectURL(file.url);
22626
+ shouldRevoke = true;
22627
+ }
22628
+ try {
22629
+ const pdfImages = await convertPdfToImages(pdfUrl);
22630
+ imagesToProcess = pdfImages;
22631
+ } catch (e) {
22632
+ getLogger().error("Failed to convert PDF to images", e);
22633
+ throw e;
22634
+ } finally {
22635
+ if (shouldRevoke) {
22636
+ URL.revokeObjectURL(pdfUrl);
22637
+ }
22638
+ }
22639
+ } else {
22640
+ imagesToProcess = [file.url];
22641
+ }
22642
+ const pageTexts = [];
22643
+ for (const image of imagesToProcess) {
22644
+ const result = await import_tesseract.default.recognize(image, language);
22645
+ pageTexts.push(result.data.text);
22646
+ }
22647
+ const text12 = pageTexts.join("\n\n");
22648
+ if (!text12.trim()) {
22649
+ getLogger().warn(`No text found in OCR source ${filename || "unknown"}`);
22650
+ return null;
22651
+ }
22652
+ return `[Context from OCR attachment ${filename || "unknown"}]:
22653
+ ${text12}`;
22654
+ } catch (err) {
22655
+ getLogger().error(`Failed to process OCR for ${file.filename || "unknown"}:`, err);
22656
+ return null;
22657
+ }
22658
+ })
22659
+ );
22660
+ const mergedContext = contexts.filter(Boolean).join("\n\n");
22661
+ return mergedContext || null;
22662
+ } catch (err) {
22663
+ const processedError = err instanceof Error ? err : new Error(String(err));
22664
+ setError(processedError);
22665
+ throw processedError;
22666
+ } finally {
22667
+ setIsProcessing(false);
22668
+ }
22669
+ }, []);
22670
+ return {
22671
+ extractOCRContext,
22672
+ isProcessing,
22673
+ error
22674
+ };
22675
+ }
22676
+
22677
+ // src/react/usePdf.ts
22678
+ var import_react12 = require("react");
22679
+ init_logger();
22680
+ var PDF_MIME_TYPE = "application/pdf";
22681
+ function usePdf() {
22682
+ const [isProcessing, setIsProcessing] = (0, import_react12.useState)(false);
22683
+ const [error, setError] = (0, import_react12.useState)(null);
22684
+ const extractPdfContext = (0, import_react12.useCallback)(async (files) => {
22685
+ setIsProcessing(true);
22686
+ setError(null);
22687
+ try {
22688
+ const pdfFiles = files.filter(
22689
+ (file) => file.mediaType === PDF_MIME_TYPE || file.filename?.toLowerCase().endsWith(".pdf")
22690
+ );
22691
+ if (pdfFiles.length === 0) {
22692
+ return null;
22693
+ }
22694
+ const contexts = await Promise.all(
22695
+ pdfFiles.map(async (file) => {
22696
+ try {
22697
+ const text12 = await extractTextFromPdf(file.url);
22698
+ if (!text12.trim()) {
22699
+ getLogger().warn(`No text found in PDF ${file.filename}`);
22700
+ return null;
22701
+ }
22702
+ return `[Context from PDF attachment ${file.filename}]:
22703
+ ${text12}`;
22704
+ } catch (err) {
22705
+ getLogger().error(`Failed to process PDF ${file.filename}:`, err);
22706
+ return null;
22707
+ }
22708
+ })
22709
+ );
22710
+ const mergedContext = contexts.filter(Boolean).join("\n\n");
22711
+ return mergedContext || null;
22712
+ } catch (err) {
22713
+ const processedError = err instanceof Error ? err : new Error(String(err));
22714
+ setError(processedError);
22715
+ throw processedError;
22716
+ } finally {
22717
+ setIsProcessing(false);
22718
+ }
22719
+ }, []);
22720
+ return {
22721
+ extractPdfContext,
22722
+ isProcessing,
22723
+ error
22724
+ };
22725
+ }
22726
+
22727
+ // src/react/useVoice.ts
22728
+ var import_react13 = require("react");
22729
+ function getOnDeviceSpeechRecognition() {
22730
+ if (typeof window === "undefined") return null;
22731
+ if (!/iPhone|iPad|iPod/.test(navigator.userAgent)) return null;
22732
+ const SR = window.SpeechRecognition ?? window.webkitSpeechRecognition;
22733
+ return SR ?? null;
22734
+ }
22735
+ var SUPPORTED_MIME_TYPES = [
22736
+ "audio/webm;codecs=opus",
22737
+ "audio/webm",
22738
+ "audio/mp4",
22739
+ "audio/ogg;codecs=opus",
22740
+ "audio/ogg"
22741
+ ];
22742
+ function getSupportedMimeType() {
22743
+ if (typeof MediaRecorder === "undefined") {
22744
+ return "audio/webm";
22745
+ }
22746
+ for (const type of SUPPORTED_MIME_TYPES) {
22747
+ if (MediaRecorder.isTypeSupported(type)) {
22748
+ return type;
22749
+ }
22750
+ }
22751
+ return "audio/webm";
22752
+ }
22753
+ var SAMPLE_RATE = 16e3;
22754
+ async function audioToFloat32(blob) {
22755
+ const arrayBuffer = await blob.arrayBuffer();
22756
+ const audioContext = new AudioContext({ sampleRate: SAMPLE_RATE });
22757
+ try {
22758
+ const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
22759
+ if (audioBuffer.numberOfChannels === 1) {
22760
+ return audioBuffer.getChannelData(0);
22761
+ }
22762
+ const length = audioBuffer.length;
22763
+ const mono = new Float32Array(length);
22764
+ const channels = audioBuffer.numberOfChannels;
22765
+ for (let ch = 0; ch < channels; ch++) {
22766
+ const data = audioBuffer.getChannelData(ch);
22767
+ for (let i = 0; i < length; i++) {
22768
+ mono[i] += data[i];
22769
+ }
22770
+ }
22771
+ for (let i = 0; i < length; i++) {
22772
+ mono[i] /= channels;
22773
+ }
22774
+ return mono;
22775
+ } finally {
22776
+ await audioContext.close();
22777
+ }
22778
+ }
22779
+ function useVoice(options) {
22780
+ const [isRecording, setIsRecording] = (0, import_react13.useState)(false);
22781
+ const [isTranscribing, setIsTranscribing] = (0, import_react13.useState)(false);
22782
+ const [isModelLoaded, setIsModelLoaded] = (0, import_react13.useState)(false);
22783
+ const [isLoadingModel, setIsLoadingModel] = (0, import_react13.useState)(false);
22784
+ const [recording, setRecording] = (0, import_react13.useState)(null);
22785
+ const [transcription, setTranscription] = (0, import_react13.useState)(null);
22786
+ const [error, setError] = (0, import_react13.useState)(null);
22787
+ const mediaRecorderRef = (0, import_react13.useRef)(null);
22788
+ const mediaStreamRef = (0, import_react13.useRef)(null);
22789
+ const chunksRef = (0, import_react13.useRef)([]);
22790
+ const startTimeRef = (0, import_react13.useRef)(0);
22791
+ const pipelineRef = (0, import_react13.useRef)(null);
22792
+ const modelNameRef = (0, import_react13.useRef)(null);
22793
+ const getModelName = (0, import_react13.useCallback)(() => {
22794
+ const model = options?.model ?? "whisper-tiny";
22795
+ return `onnx-community/${model}`;
22796
+ }, [options?.model]);
22797
+ const loadPipeline = (0, import_react13.useCallback)(async () => {
22798
+ const modelName = getModelName();
22799
+ if (pipelineRef.current && modelNameRef.current === modelName) {
22800
+ return pipelineRef.current;
22801
+ }
22802
+ setIsLoadingModel(true);
22803
+ setError(null);
22804
+ try {
22805
+ const { pipeline } = await import("@huggingface/transformers");
22806
+ const transcriber = await pipeline("automatic-speech-recognition", modelName, {
22807
+ dtype: "q4",
22808
+ device: "wasm",
22809
+ progress_callback: options?.onModelProgress ? (progress) => {
22810
+ if (progress.file && progress.progress !== null && progress.progress !== void 0) {
22811
+ options.onModelProgress({
22812
+ file: progress.file,
22813
+ progress: progress.progress / 100,
22814
+ loaded: progress.loaded ?? 0,
22815
+ total: progress.total ?? 0
22816
+ });
22817
+ }
22818
+ } : void 0
22819
+ });
22820
+ pipelineRef.current = transcriber;
22821
+ modelNameRef.current = modelName;
22822
+ setIsModelLoaded(true);
22823
+ return pipelineRef.current;
22824
+ } catch (err) {
22825
+ const processedError = err instanceof Error ? err : new Error("Failed to load Whisper model");
22826
+ setError(processedError);
22827
+ throw processedError;
22828
+ } finally {
22829
+ setIsLoadingModel(false);
22830
+ }
22831
+ }, [getModelName, options?.onModelProgress]);
22832
+ const preloadModel = (0, import_react13.useCallback)(async () => {
22833
+ await loadPipeline();
22834
+ }, [loadPipeline]);
22835
+ const disposeModel = (0, import_react13.useCallback)(async () => {
22836
+ const pipe = pipelineRef.current;
22837
+ if (pipe?.dispose) {
22838
+ await pipe.dispose();
22839
+ }
22840
+ pipelineRef.current = null;
22841
+ modelNameRef.current = null;
22842
+ setIsModelLoaded(false);
22843
+ }, []);
22844
+ const startRecording = (0, import_react13.useCallback)(async () => {
22845
+ setError(null);
22846
+ setRecording(null);
22847
+ setTranscription(null);
22848
+ try {
22849
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
22850
+ mediaStreamRef.current = stream;
22851
+ const mimeType = getSupportedMimeType();
22852
+ const recorder = new MediaRecorder(stream, { mimeType });
22853
+ mediaRecorderRef.current = recorder;
22854
+ chunksRef.current = [];
22855
+ recorder.ondataavailable = (e) => {
22856
+ if (e.data.size > 0) {
22857
+ chunksRef.current.push(e.data);
22858
+ }
22859
+ };
22860
+ recorder.start();
22861
+ startTimeRef.current = Date.now();
22862
+ setIsRecording(true);
22863
+ } catch (err) {
22864
+ const processedError = err instanceof Error ? err : new Error("Failed to start recording");
22865
+ setError(processedError);
22866
+ throw processedError;
22867
+ }
22868
+ }, []);
22869
+ const stopRecording = (0, import_react13.useCallback)(async () => {
22870
+ return new Promise((resolve, reject) => {
22871
+ const recorder = mediaRecorderRef.current;
22872
+ if (!recorder || recorder.state === "inactive") {
22873
+ const err = new Error("No active recording");
22874
+ setError(err);
22875
+ reject(err);
22876
+ return;
22877
+ }
22878
+ recorder.onstop = () => {
22879
+ const mimeType = recorder.mimeType || "audio/webm";
22880
+ const blob = new Blob(chunksRef.current, { type: mimeType });
22881
+ const duration = Date.now() - startTimeRef.current;
22882
+ mediaStreamRef.current?.getTracks().forEach((t) => t.stop());
22883
+ mediaStreamRef.current = null;
22884
+ mediaRecorderRef.current = null;
22885
+ const result = { blob, duration, mimeType };
22886
+ setRecording(result);
22887
+ setIsRecording(false);
22888
+ resolve(result);
22889
+ };
22890
+ recorder.onerror = () => {
22891
+ const err = new Error("Recording failed");
22892
+ setError(err);
22893
+ setIsRecording(false);
22894
+ reject(err);
22895
+ };
22896
+ recorder.stop();
22897
+ });
22898
+ }, []);
22899
+ const transcribe = (0, import_react13.useCallback)(
22900
+ async (rec) => {
22901
+ const target = rec ?? recording;
22902
+ if (!target) {
22903
+ const err = new Error("No recording to transcribe");
22904
+ setError(err);
22905
+ throw err;
22906
+ }
22907
+ setIsTranscribing(true);
22908
+ setError(null);
22909
+ try {
22910
+ const pipe = await loadPipeline();
22911
+ const audio = await audioToFloat32(target.blob);
22912
+ const result = await pipe(audio, {
22913
+ language: options?.language,
22914
+ return_timestamps: true
22915
+ });
22916
+ const transcriptionResult = {
22917
+ text: result.text.trim(),
22918
+ chunks: result.chunks
22919
+ };
22920
+ setTranscription(transcriptionResult);
22921
+ return transcriptionResult;
22922
+ } catch (err) {
22923
+ const processedError = err instanceof Error ? err : new Error("Transcription failed");
22924
+ setError(processedError);
22925
+ throw processedError;
23413
22926
  } finally {
23414
- setIsExporting(false);
22927
+ setIsTranscribing(false);
23415
22928
  }
23416
22929
  },
23417
- []
22930
+ [recording, loadPipeline, options?.language]
23418
22931
  );
23419
- return {
23420
- exportElementToPdf: wrappedExportElement,
23421
- exportMarkdownToPdf: wrappedExportMarkdown,
23422
- downloadElementAsPdf,
23423
- downloadMarkdownAsPdf,
23424
- renderElementToCanvas: wrappedRenderToCanvas,
23425
- isExporting,
23426
- progress,
23427
- error
23428
- };
23429
- }
23430
-
23431
- // src/react/useOCR.ts
23432
- var import_react11 = require("react");
23433
- var import_tesseract = __toESM(require("tesseract.js"));
23434
- init_logger();
23435
- function useOCR() {
23436
- const [isProcessing, setIsProcessing] = (0, import_react11.useState)(false);
23437
- const [error, setError] = (0, import_react11.useState)(null);
23438
- const extractOCRContext = (0, import_react11.useCallback)(async (files) => {
23439
- setIsProcessing(true);
22932
+ const nativeSpeechAvailable = (0, import_react13.useMemo)(() => getOnDeviceSpeechRecognition() !== null, []);
22933
+ const [isNativeListening, setIsNativeListening] = (0, import_react13.useState)(false);
22934
+ const nativeRecognitionRef = (0, import_react13.useRef)(null);
22935
+ const nativeTextRef = (0, import_react13.useRef)("");
22936
+ const nativeResolveRef = (0, import_react13.useRef)(null);
22937
+ const startNativeTranscription = (0, import_react13.useCallback)(() => {
22938
+ const SR = getOnDeviceSpeechRecognition();
22939
+ if (!SR) return;
22940
+ nativeTextRef.current = "";
23440
22941
  setError(null);
23441
- try {
23442
- if (files.length === 0) {
23443
- return null;
22942
+ const recognition = new SR();
22943
+ recognition.continuous = true;
22944
+ recognition.interimResults = false;
22945
+ recognition.lang = options?.language ?? "";
22946
+ recognition.onresult = (event) => {
22947
+ let text12 = "";
22948
+ for (let i = 0; i < event.results.length; i++) {
22949
+ const result = event.results[i];
22950
+ if (result && result.isFinal && result[0]) {
22951
+ text12 += result[0].transcript + " ";
22952
+ }
23444
22953
  }
23445
- const contexts = await Promise.all(
23446
- files.map(async (file) => {
23447
- try {
23448
- let imagesToProcess = [];
23449
- const language = file.language || "eng";
23450
- const filename = file.filename || (file.url instanceof File ? file.url.name : "");
23451
- let isPdf = false;
23452
- if (typeof file.url === "string") {
23453
- isPdf = file.url.toLowerCase().endsWith(".pdf") || (filename?.toLowerCase().endsWith(".pdf") ?? false);
23454
- } else if (file.url instanceof Blob) {
23455
- isPdf = file.url.type === "application/pdf" || (filename?.toLowerCase().endsWith(".pdf") ?? false);
23456
- }
23457
- if (isPdf) {
23458
- let pdfUrl;
23459
- let shouldRevoke = false;
23460
- if (typeof file.url === "string") {
23461
- pdfUrl = file.url;
23462
- } else {
23463
- pdfUrl = URL.createObjectURL(file.url);
23464
- shouldRevoke = true;
23465
- }
23466
- try {
23467
- const pdfImages = await convertPdfToImages(pdfUrl);
23468
- imagesToProcess = pdfImages;
23469
- } catch (e) {
23470
- getLogger().error("Failed to convert PDF to images", e);
23471
- throw e;
23472
- } finally {
23473
- if (shouldRevoke) {
23474
- URL.revokeObjectURL(pdfUrl);
23475
- }
23476
- }
23477
- } else {
23478
- imagesToProcess = [file.url];
23479
- }
23480
- const pageTexts = [];
23481
- for (const image of imagesToProcess) {
23482
- const result = await import_tesseract.default.recognize(image, language);
23483
- pageTexts.push(result.data.text);
23484
- }
23485
- const text12 = pageTexts.join("\n\n");
23486
- if (!text12.trim()) {
23487
- getLogger().warn(`No text found in OCR source ${filename || "unknown"}`);
23488
- return null;
23489
- }
23490
- return `[Context from OCR attachment ${filename || "unknown"}]:
23491
- ${text12}`;
23492
- } catch (err) {
23493
- getLogger().error(`Failed to process OCR for ${file.filename || "unknown"}:`, err);
23494
- return null;
23495
- }
23496
- })
23497
- );
23498
- const mergedContext = contexts.filter(Boolean).join("\n\n");
23499
- return mergedContext || null;
23500
- } catch (err) {
23501
- const processedError = err instanceof Error ? err : new Error(String(err));
23502
- setError(processedError);
23503
- throw processedError;
23504
- } finally {
23505
- setIsProcessing(false);
22954
+ nativeTextRef.current = text12.trim();
22955
+ };
22956
+ recognition.onerror = (event) => {
22957
+ if (event.error !== "aborted" && event.error !== "no-speech") {
22958
+ setError(new Error(`Speech recognition error: ${event.error}`));
22959
+ }
22960
+ };
22961
+ recognition.onend = () => {
22962
+ setIsNativeListening(false);
22963
+ nativeRecognitionRef.current = null;
22964
+ const resolve = nativeResolveRef.current;
22965
+ if (resolve) {
22966
+ nativeResolveRef.current = null;
22967
+ resolve({ text: nativeTextRef.current });
22968
+ }
22969
+ };
22970
+ nativeRecognitionRef.current = recognition;
22971
+ recognition.start();
22972
+ setIsNativeListening(true);
22973
+ }, [options?.language]);
22974
+ const stopNativeTranscription = (0, import_react13.useCallback)(() => {
22975
+ return new Promise((resolve) => {
22976
+ const recognition = nativeRecognitionRef.current;
22977
+ if (!recognition) {
22978
+ resolve({ text: nativeTextRef.current || "" });
22979
+ return;
22980
+ }
22981
+ nativeResolveRef.current = resolve;
22982
+ recognition.stop();
22983
+ });
22984
+ }, []);
22985
+ const abortNativeTranscription = (0, import_react13.useCallback)(() => {
22986
+ const recognition = nativeRecognitionRef.current;
22987
+ if (recognition) {
22988
+ nativeResolveRef.current = null;
22989
+ recognition.abort();
22990
+ nativeRecognitionRef.current = null;
22991
+ setIsNativeListening(false);
23506
22992
  }
23507
22993
  }, []);
23508
22994
  return {
23509
- extractOCRContext,
23510
- isProcessing,
23511
- error
22995
+ isRecording,
22996
+ startRecording,
22997
+ stopRecording,
22998
+ isTranscribing,
22999
+ transcribe,
23000
+ preloadModel,
23001
+ disposeModel,
23002
+ isModelLoaded,
23003
+ isLoadingModel,
23004
+ recording,
23005
+ transcription,
23006
+ error,
23007
+ nativeSpeechAvailable,
23008
+ startNativeTranscription,
23009
+ stopNativeTranscription,
23010
+ abortNativeTranscription,
23011
+ isNativeListening
23512
23012
  };
23513
23013
  }
23514
23014
 
23515
- // src/react/usePdf.ts
23516
- var import_react12 = require("react");
23517
- init_logger();
23518
- var PDF_MIME_TYPE = "application/pdf";
23519
- function usePdf() {
23520
- const [isProcessing, setIsProcessing] = (0, import_react12.useState)(false);
23521
- const [error, setError] = (0, import_react12.useState)(null);
23522
- const extractPdfContext = (0, import_react12.useCallback)(async (files) => {
23523
- setIsProcessing(true);
23524
- setError(null);
23525
- try {
23526
- const pdfFiles = files.filter(
23527
- (file) => file.mediaType === PDF_MIME_TYPE || file.filename?.toLowerCase().endsWith(".pdf")
23528
- );
23529
- if (pdfFiles.length === 0) {
23530
- return null;
23015
+ // src/react/useCredits.ts
23016
+ var import_react14 = require("react");
23017
+
23018
+ // src/client/core/bodySerializer.gen.ts
23019
+ var jsonBodySerializer = {
23020
+ bodySerializer: (body) => JSON.stringify(
23021
+ body,
23022
+ (_key, value) => typeof value === "bigint" ? value.toString() : value
23023
+ )
23024
+ };
23025
+
23026
+ // src/client/core/pathSerializer.gen.ts
23027
+ var separatorArrayExplode = (style) => {
23028
+ switch (style) {
23029
+ case "label":
23030
+ return ".";
23031
+ case "matrix":
23032
+ return ";";
23033
+ case "simple":
23034
+ return ",";
23035
+ default:
23036
+ return "&";
23037
+ }
23038
+ };
23039
+ var separatorArrayNoExplode = (style) => {
23040
+ switch (style) {
23041
+ case "form":
23042
+ return ",";
23043
+ case "pipeDelimited":
23044
+ return "|";
23045
+ case "spaceDelimited":
23046
+ return "%20";
23047
+ default:
23048
+ return ",";
23049
+ }
23050
+ };
23051
+ var separatorObjectExplode = (style) => {
23052
+ switch (style) {
23053
+ case "label":
23054
+ return ".";
23055
+ case "matrix":
23056
+ return ";";
23057
+ case "simple":
23058
+ return ",";
23059
+ default:
23060
+ return "&";
23061
+ }
23062
+ };
23063
+ var serializeArrayParam = ({
23064
+ allowReserved,
23065
+ explode,
23066
+ name,
23067
+ style,
23068
+ value
23069
+ }) => {
23070
+ if (!explode) {
23071
+ const joinedValues2 = (allowReserved ? value : value.map((v) => encodeURIComponent(v))).join(separatorArrayNoExplode(style));
23072
+ switch (style) {
23073
+ case "label":
23074
+ return `.${joinedValues2}`;
23075
+ case "matrix":
23076
+ return `;${name}=${joinedValues2}`;
23077
+ case "simple":
23078
+ return joinedValues2;
23079
+ default:
23080
+ return `${name}=${joinedValues2}`;
23081
+ }
23082
+ }
23083
+ const separator = separatorArrayExplode(style);
23084
+ const joinedValues = value.map((v) => {
23085
+ if (style === "label" || style === "simple") {
23086
+ return allowReserved ? v : encodeURIComponent(v);
23087
+ }
23088
+ return serializePrimitiveParam({
23089
+ allowReserved,
23090
+ name,
23091
+ value: v
23092
+ });
23093
+ }).join(separator);
23094
+ return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
23095
+ };
23096
+ var serializePrimitiveParam = ({
23097
+ allowReserved,
23098
+ name,
23099
+ value
23100
+ }) => {
23101
+ if (value === void 0 || value === null) {
23102
+ return "";
23103
+ }
23104
+ if (typeof value === "object") {
23105
+ throw new Error(
23106
+ "Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these."
23107
+ );
23108
+ }
23109
+ return `${name}=${allowReserved ? value : encodeURIComponent(value)}`;
23110
+ };
23111
+ var serializeObjectParam = ({
23112
+ allowReserved,
23113
+ explode,
23114
+ name,
23115
+ style,
23116
+ value,
23117
+ valueOnly
23118
+ }) => {
23119
+ if (value instanceof Date) {
23120
+ return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`;
23121
+ }
23122
+ if (style !== "deepObject" && !explode) {
23123
+ let values = [];
23124
+ Object.entries(value).forEach(([key, v]) => {
23125
+ values = [
23126
+ ...values,
23127
+ key,
23128
+ allowReserved ? v : encodeURIComponent(v)
23129
+ ];
23130
+ });
23131
+ const joinedValues2 = values.join(",");
23132
+ switch (style) {
23133
+ case "form":
23134
+ return `${name}=${joinedValues2}`;
23135
+ case "label":
23136
+ return `.${joinedValues2}`;
23137
+ case "matrix":
23138
+ return `;${name}=${joinedValues2}`;
23139
+ default:
23140
+ return joinedValues2;
23141
+ }
23142
+ }
23143
+ const separator = separatorObjectExplode(style);
23144
+ const joinedValues = Object.entries(value).map(
23145
+ ([key, v]) => serializePrimitiveParam({
23146
+ allowReserved,
23147
+ name: style === "deepObject" ? `${name}[${key}]` : key,
23148
+ value: v
23149
+ })
23150
+ ).join(separator);
23151
+ return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
23152
+ };
23153
+
23154
+ // src/client/core/utils.gen.ts
23155
+ function getValidRequestBody(options) {
23156
+ const hasBody = options.body !== void 0;
23157
+ const isSerializedBody = hasBody && options.bodySerializer;
23158
+ if (isSerializedBody) {
23159
+ if ("serializedBody" in options) {
23160
+ const hasSerializedBody = options.serializedBody !== void 0 && options.serializedBody !== "";
23161
+ return hasSerializedBody ? options.serializedBody : null;
23162
+ }
23163
+ return options.body !== "" ? options.body : null;
23164
+ }
23165
+ if (hasBody) {
23166
+ return options.body;
23167
+ }
23168
+ return void 0;
23169
+ }
23170
+
23171
+ // src/client/core/auth.gen.ts
23172
+ var getAuthToken = async (auth, callback) => {
23173
+ const token = typeof callback === "function" ? await callback(auth) : callback;
23174
+ if (!token) {
23175
+ return;
23176
+ }
23177
+ if (auth.scheme === "bearer") {
23178
+ return `Bearer ${token}`;
23179
+ }
23180
+ if (auth.scheme === "basic") {
23181
+ return `Basic ${btoa(token)}`;
23182
+ }
23183
+ return token;
23184
+ };
23185
+
23186
+ // src/client/client/utils.gen.ts
23187
+ var PATH_PARAM_RE = /\{[^{}]+\}/g;
23188
+ var defaultPathSerializer = ({ path, url: _url }) => {
23189
+ let url = _url;
23190
+ const matches = _url.match(PATH_PARAM_RE);
23191
+ if (matches) {
23192
+ for (const match of matches) {
23193
+ let explode = false;
23194
+ let name = match.substring(1, match.length - 1);
23195
+ let style = "simple";
23196
+ if (name.endsWith("*")) {
23197
+ explode = true;
23198
+ name = name.substring(0, name.length - 1);
23199
+ }
23200
+ if (name.startsWith(".")) {
23201
+ name = name.substring(1);
23202
+ style = "label";
23203
+ } else if (name.startsWith(";")) {
23204
+ name = name.substring(1);
23205
+ style = "matrix";
23206
+ }
23207
+ const value = path[name];
23208
+ if (value === void 0 || value === null) {
23209
+ continue;
23531
23210
  }
23532
- const contexts = await Promise.all(
23533
- pdfFiles.map(async (file) => {
23534
- try {
23535
- const text12 = await extractTextFromPdf(file.url);
23536
- if (!text12.trim()) {
23537
- getLogger().warn(`No text found in PDF ${file.filename}`);
23538
- return null;
23539
- }
23540
- return `[Context from PDF attachment ${file.filename}]:
23541
- ${text12}`;
23542
- } catch (err) {
23543
- getLogger().error(`Failed to process PDF ${file.filename}:`, err);
23544
- return null;
23545
- }
23546
- })
23211
+ if (Array.isArray(value)) {
23212
+ url = url.replace(
23213
+ match,
23214
+ serializeArrayParam({ explode, name, style, value })
23215
+ );
23216
+ continue;
23217
+ }
23218
+ if (typeof value === "object") {
23219
+ url = url.replace(
23220
+ match,
23221
+ serializeObjectParam({
23222
+ explode,
23223
+ name,
23224
+ style,
23225
+ value,
23226
+ valueOnly: true
23227
+ })
23228
+ );
23229
+ continue;
23230
+ }
23231
+ if (style === "matrix") {
23232
+ url = url.replace(
23233
+ match,
23234
+ `;${serializePrimitiveParam({
23235
+ name,
23236
+ value
23237
+ })}`
23238
+ );
23239
+ continue;
23240
+ }
23241
+ const replaceValue = encodeURIComponent(
23242
+ style === "label" ? `.${value}` : value
23547
23243
  );
23548
- const mergedContext = contexts.filter(Boolean).join("\n\n");
23549
- return mergedContext || null;
23550
- } catch (err) {
23551
- const processedError = err instanceof Error ? err : new Error(String(err));
23552
- setError(processedError);
23553
- throw processedError;
23554
- } finally {
23555
- setIsProcessing(false);
23244
+ url = url.replace(match, replaceValue);
23556
23245
  }
23557
- }, []);
23558
- return {
23559
- extractPdfContext,
23560
- isProcessing,
23561
- error
23246
+ }
23247
+ return url;
23248
+ };
23249
+ var createQuerySerializer = ({
23250
+ parameters = {},
23251
+ ...args
23252
+ } = {}) => {
23253
+ const querySerializer = (queryParams) => {
23254
+ const search = [];
23255
+ if (queryParams && typeof queryParams === "object") {
23256
+ for (const name in queryParams) {
23257
+ const value = queryParams[name];
23258
+ if (value === void 0 || value === null) {
23259
+ continue;
23260
+ }
23261
+ const options = parameters[name] || args;
23262
+ if (Array.isArray(value)) {
23263
+ const serializedArray = serializeArrayParam({
23264
+ allowReserved: options.allowReserved,
23265
+ explode: true,
23266
+ name,
23267
+ style: "form",
23268
+ value,
23269
+ ...options.array
23270
+ });
23271
+ if (serializedArray) search.push(serializedArray);
23272
+ } else if (typeof value === "object") {
23273
+ const serializedObject = serializeObjectParam({
23274
+ allowReserved: options.allowReserved,
23275
+ explode: true,
23276
+ name,
23277
+ style: "deepObject",
23278
+ value,
23279
+ ...options.object
23280
+ });
23281
+ if (serializedObject) search.push(serializedObject);
23282
+ } else {
23283
+ const serializedPrimitive = serializePrimitiveParam({
23284
+ allowReserved: options.allowReserved,
23285
+ name,
23286
+ value
23287
+ });
23288
+ if (serializedPrimitive) search.push(serializedPrimitive);
23289
+ }
23290
+ }
23291
+ }
23292
+ return search.join("&");
23562
23293
  };
23563
- }
23564
-
23565
- // src/react/useVoice.ts
23566
- var import_react13 = require("react");
23567
- function getOnDeviceSpeechRecognition() {
23568
- if (typeof window === "undefined") return null;
23569
- if (!/iPhone|iPad|iPod/.test(navigator.userAgent)) return null;
23570
- const SR = window.SpeechRecognition ?? window.webkitSpeechRecognition;
23571
- return SR ?? null;
23572
- }
23573
- var SUPPORTED_MIME_TYPES = [
23574
- "audio/webm;codecs=opus",
23575
- "audio/webm",
23576
- "audio/mp4",
23577
- "audio/ogg;codecs=opus",
23578
- "audio/ogg"
23579
- ];
23580
- function getSupportedMimeType() {
23581
- if (typeof MediaRecorder === "undefined") {
23582
- return "audio/webm";
23294
+ return querySerializer;
23295
+ };
23296
+ var getParseAs = (contentType) => {
23297
+ if (!contentType) {
23298
+ return "stream";
23583
23299
  }
23584
- for (const type of SUPPORTED_MIME_TYPES) {
23585
- if (MediaRecorder.isTypeSupported(type)) {
23586
- return type;
23300
+ const cleanContent = contentType.split(";")[0]?.trim();
23301
+ if (!cleanContent) {
23302
+ return;
23303
+ }
23304
+ if (cleanContent.startsWith("application/json") || cleanContent.endsWith("+json")) {
23305
+ return "json";
23306
+ }
23307
+ if (cleanContent === "multipart/form-data") {
23308
+ return "formData";
23309
+ }
23310
+ if (["application/", "audio/", "image/", "video/"].some(
23311
+ (type) => cleanContent.startsWith(type)
23312
+ )) {
23313
+ return "blob";
23314
+ }
23315
+ if (cleanContent.startsWith("text/")) {
23316
+ return "text";
23317
+ }
23318
+ return;
23319
+ };
23320
+ var checkForExistence = (options, name) => {
23321
+ if (!name) {
23322
+ return false;
23323
+ }
23324
+ if (options.headers.has(name) || options.query?.[name] || options.headers.get("Cookie")?.includes(`${name}=`)) {
23325
+ return true;
23326
+ }
23327
+ return false;
23328
+ };
23329
+ var setAuthParams = async ({
23330
+ security,
23331
+ ...options
23332
+ }) => {
23333
+ for (const auth of security) {
23334
+ if (checkForExistence(options, auth.name)) {
23335
+ continue;
23336
+ }
23337
+ const token = await getAuthToken(auth, options.auth);
23338
+ if (!token) {
23339
+ continue;
23340
+ }
23341
+ const name = auth.name ?? "Authorization";
23342
+ switch (auth.in) {
23343
+ case "query":
23344
+ if (!options.query) {
23345
+ options.query = {};
23346
+ }
23347
+ options.query[name] = token;
23348
+ break;
23349
+ case "cookie":
23350
+ options.headers.append("Cookie", `${name}=${token}`);
23351
+ break;
23352
+ case "header":
23353
+ default:
23354
+ options.headers.set(name, token);
23355
+ break;
23587
23356
  }
23588
23357
  }
23589
- return "audio/webm";
23590
- }
23591
- var SAMPLE_RATE = 16e3;
23592
- async function audioToFloat32(blob) {
23593
- const arrayBuffer = await blob.arrayBuffer();
23594
- const audioContext = new AudioContext({ sampleRate: SAMPLE_RATE });
23595
- try {
23596
- const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
23597
- if (audioBuffer.numberOfChannels === 1) {
23598
- return audioBuffer.getChannelData(0);
23358
+ };
23359
+ var buildUrl = (options) => {
23360
+ const url = getUrl({
23361
+ baseUrl: options.baseUrl,
23362
+ path: options.path,
23363
+ query: options.query,
23364
+ querySerializer: typeof options.querySerializer === "function" ? options.querySerializer : createQuerySerializer(options.querySerializer),
23365
+ url: options.url
23366
+ });
23367
+ return url;
23368
+ };
23369
+ var getUrl = ({
23370
+ baseUrl,
23371
+ path,
23372
+ query,
23373
+ querySerializer,
23374
+ url: _url
23375
+ }) => {
23376
+ const pathUrl = _url.startsWith("/") ? _url : `/${_url}`;
23377
+ let url = (baseUrl ?? "") + pathUrl;
23378
+ if (path) {
23379
+ url = defaultPathSerializer({ path, url });
23380
+ }
23381
+ let search = query ? querySerializer(query) : "";
23382
+ if (search.startsWith("?")) {
23383
+ search = search.substring(1);
23384
+ }
23385
+ if (search) {
23386
+ url += `?${search}`;
23387
+ }
23388
+ return url;
23389
+ };
23390
+ var mergeConfigs = (a, b) => {
23391
+ const config = { ...a, ...b };
23392
+ if (config.baseUrl?.endsWith("/")) {
23393
+ config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1);
23394
+ }
23395
+ config.headers = mergeHeaders(a.headers, b.headers);
23396
+ return config;
23397
+ };
23398
+ var headersEntries = (headers) => {
23399
+ const entries = [];
23400
+ headers.forEach((value, key) => {
23401
+ entries.push([key, value]);
23402
+ });
23403
+ return entries;
23404
+ };
23405
+ var mergeHeaders = (...headers) => {
23406
+ const mergedHeaders = new Headers();
23407
+ for (const header of headers) {
23408
+ if (!header || typeof header !== "object") {
23409
+ continue;
23599
23410
  }
23600
- const length = audioBuffer.length;
23601
- const mono = new Float32Array(length);
23602
- const channels = audioBuffer.numberOfChannels;
23603
- for (let ch = 0; ch < channels; ch++) {
23604
- const data = audioBuffer.getChannelData(ch);
23605
- for (let i = 0; i < length; i++) {
23606
- mono[i] += data[i];
23411
+ const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header);
23412
+ for (const [key, value] of iterator) {
23413
+ if (value === null) {
23414
+ mergedHeaders.delete(key);
23415
+ } else if (Array.isArray(value)) {
23416
+ for (const v of value) {
23417
+ mergedHeaders.append(key, v);
23418
+ }
23419
+ } else if (value !== void 0) {
23420
+ mergedHeaders.set(
23421
+ key,
23422
+ typeof value === "object" ? JSON.stringify(value) : value
23423
+ );
23607
23424
  }
23608
23425
  }
23609
- for (let i = 0; i < length; i++) {
23610
- mono[i] /= channels;
23426
+ }
23427
+ return mergedHeaders;
23428
+ };
23429
+ var Interceptors = class {
23430
+ constructor() {
23431
+ this.fns = [];
23432
+ }
23433
+ clear() {
23434
+ this.fns = [];
23435
+ }
23436
+ eject(id) {
23437
+ const index = this.getInterceptorIndex(id);
23438
+ if (this.fns[index]) {
23439
+ this.fns[index] = null;
23611
23440
  }
23612
- return mono;
23613
- } finally {
23614
- await audioContext.close();
23615
23441
  }
23616
- }
23617
- function useVoice(options) {
23618
- const [isRecording, setIsRecording] = (0, import_react13.useState)(false);
23619
- const [isTranscribing, setIsTranscribing] = (0, import_react13.useState)(false);
23620
- const [isModelLoaded, setIsModelLoaded] = (0, import_react13.useState)(false);
23621
- const [isLoadingModel, setIsLoadingModel] = (0, import_react13.useState)(false);
23622
- const [recording, setRecording] = (0, import_react13.useState)(null);
23623
- const [transcription, setTranscription] = (0, import_react13.useState)(null);
23624
- const [error, setError] = (0, import_react13.useState)(null);
23625
- const mediaRecorderRef = (0, import_react13.useRef)(null);
23626
- const mediaStreamRef = (0, import_react13.useRef)(null);
23627
- const chunksRef = (0, import_react13.useRef)([]);
23628
- const startTimeRef = (0, import_react13.useRef)(0);
23629
- const pipelineRef = (0, import_react13.useRef)(null);
23630
- const modelNameRef = (0, import_react13.useRef)(null);
23631
- const getModelName = (0, import_react13.useCallback)(() => {
23632
- const model = options?.model ?? "whisper-tiny";
23633
- return `onnx-community/${model}`;
23634
- }, [options?.model]);
23635
- const loadPipeline = (0, import_react13.useCallback)(async () => {
23636
- const modelName = getModelName();
23637
- if (pipelineRef.current && modelNameRef.current === modelName) {
23638
- return pipelineRef.current;
23442
+ exists(id) {
23443
+ const index = this.getInterceptorIndex(id);
23444
+ return Boolean(this.fns[index]);
23445
+ }
23446
+ getInterceptorIndex(id) {
23447
+ if (typeof id === "number") {
23448
+ return this.fns[id] ? id : -1;
23639
23449
  }
23640
- setIsLoadingModel(true);
23641
- setError(null);
23642
- try {
23643
- const { pipeline } = await import("@huggingface/transformers");
23644
- const transcriber = await pipeline("automatic-speech-recognition", modelName, {
23645
- dtype: "q4",
23646
- device: "wasm",
23647
- progress_callback: options?.onModelProgress ? (progress) => {
23648
- if (progress.file && progress.progress !== null && progress.progress !== void 0) {
23649
- options.onModelProgress({
23650
- file: progress.file,
23651
- progress: progress.progress / 100,
23652
- loaded: progress.loaded ?? 0,
23653
- total: progress.total ?? 0
23654
- });
23655
- }
23656
- } : void 0
23657
- });
23658
- pipelineRef.current = transcriber;
23659
- modelNameRef.current = modelName;
23660
- setIsModelLoaded(true);
23661
- return pipelineRef.current;
23662
- } catch (err) {
23663
- const processedError = err instanceof Error ? err : new Error("Failed to load Whisper model");
23664
- setError(processedError);
23665
- throw processedError;
23666
- } finally {
23667
- setIsLoadingModel(false);
23450
+ return this.fns.indexOf(id);
23451
+ }
23452
+ update(id, fn) {
23453
+ const index = this.getInterceptorIndex(id);
23454
+ if (this.fns[index]) {
23455
+ this.fns[index] = fn;
23456
+ return id;
23668
23457
  }
23669
- }, [getModelName, options?.onModelProgress]);
23670
- const preloadModel = (0, import_react13.useCallback)(async () => {
23671
- await loadPipeline();
23672
- }, [loadPipeline]);
23673
- const disposeModel = (0, import_react13.useCallback)(async () => {
23674
- const pipe = pipelineRef.current;
23675
- if (pipe?.dispose) {
23676
- await pipe.dispose();
23458
+ return false;
23459
+ }
23460
+ use(fn) {
23461
+ this.fns.push(fn);
23462
+ return this.fns.length - 1;
23463
+ }
23464
+ };
23465
+ var createInterceptors = () => ({
23466
+ error: new Interceptors(),
23467
+ request: new Interceptors(),
23468
+ response: new Interceptors()
23469
+ });
23470
+ var defaultQuerySerializer = createQuerySerializer({
23471
+ allowReserved: false,
23472
+ array: {
23473
+ explode: true,
23474
+ style: "form"
23475
+ },
23476
+ object: {
23477
+ explode: true,
23478
+ style: "deepObject"
23479
+ }
23480
+ });
23481
+ var defaultHeaders = {
23482
+ "Content-Type": "application/json"
23483
+ };
23484
+ var createConfig = (override = {}) => ({
23485
+ ...jsonBodySerializer,
23486
+ headers: defaultHeaders,
23487
+ parseAs: "auto",
23488
+ querySerializer: defaultQuerySerializer,
23489
+ ...override
23490
+ });
23491
+
23492
+ // src/client/client/client.gen.ts
23493
+ var createClient = (config = {}) => {
23494
+ let _config = mergeConfigs(createConfig(), config);
23495
+ const getConfig = () => ({ ..._config });
23496
+ const setConfig = (config2) => {
23497
+ _config = mergeConfigs(_config, config2);
23498
+ return getConfig();
23499
+ };
23500
+ const interceptors = createInterceptors();
23501
+ const beforeRequest = async (options) => {
23502
+ const opts = {
23503
+ ..._config,
23504
+ ...options,
23505
+ fetch: options.fetch ?? _config.fetch ?? globalThis.fetch,
23506
+ headers: mergeHeaders(_config.headers, options.headers),
23507
+ serializedBody: void 0
23508
+ };
23509
+ if (opts.security) {
23510
+ await setAuthParams({
23511
+ ...opts,
23512
+ security: opts.security
23513
+ });
23677
23514
  }
23678
- pipelineRef.current = null;
23679
- modelNameRef.current = null;
23680
- setIsModelLoaded(false);
23681
- }, []);
23682
- const startRecording = (0, import_react13.useCallback)(async () => {
23683
- setError(null);
23684
- setRecording(null);
23685
- setTranscription(null);
23686
- try {
23687
- const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
23688
- mediaStreamRef.current = stream;
23689
- const mimeType = getSupportedMimeType();
23690
- const recorder = new MediaRecorder(stream, { mimeType });
23691
- mediaRecorderRef.current = recorder;
23692
- chunksRef.current = [];
23693
- recorder.ondataavailable = (e) => {
23694
- if (e.data.size > 0) {
23695
- chunksRef.current.push(e.data);
23696
- }
23697
- };
23698
- recorder.start();
23699
- startTimeRef.current = Date.now();
23700
- setIsRecording(true);
23701
- } catch (err) {
23702
- const processedError = err instanceof Error ? err : new Error("Failed to start recording");
23703
- setError(processedError);
23704
- throw processedError;
23515
+ if (opts.requestValidator) {
23516
+ await opts.requestValidator(opts);
23705
23517
  }
23706
- }, []);
23707
- const stopRecording = (0, import_react13.useCallback)(async () => {
23708
- return new Promise((resolve, reject) => {
23709
- const recorder = mediaRecorderRef.current;
23710
- if (!recorder || recorder.state === "inactive") {
23711
- const err = new Error("No active recording");
23712
- setError(err);
23713
- reject(err);
23714
- return;
23518
+ if (opts.body !== void 0 && opts.bodySerializer) {
23519
+ opts.serializedBody = opts.bodySerializer(opts.body);
23520
+ }
23521
+ if (opts.body === void 0 || opts.serializedBody === "") {
23522
+ opts.headers.delete("Content-Type");
23523
+ }
23524
+ const url = buildUrl(opts);
23525
+ return { opts, url };
23526
+ };
23527
+ const request = async (options) => {
23528
+ const { opts, url } = await beforeRequest(options);
23529
+ for (const fn of interceptors.request.fns) {
23530
+ if (fn) {
23531
+ await fn(opts);
23715
23532
  }
23716
- recorder.onstop = () => {
23717
- const mimeType = recorder.mimeType || "audio/webm";
23718
- const blob = new Blob(chunksRef.current, { type: mimeType });
23719
- const duration = Date.now() - startTimeRef.current;
23720
- mediaStreamRef.current?.getTracks().forEach((t) => t.stop());
23721
- mediaStreamRef.current = null;
23722
- mediaRecorderRef.current = null;
23723
- const result = { blob, duration, mimeType };
23724
- setRecording(result);
23725
- setIsRecording(false);
23726
- resolve(result);
23727
- };
23728
- recorder.onerror = () => {
23729
- const err = new Error("Recording failed");
23730
- setError(err);
23731
- setIsRecording(false);
23732
- reject(err);
23733
- };
23734
- recorder.stop();
23735
- });
23736
- }, []);
23737
- const transcribe = (0, import_react13.useCallback)(
23738
- async (rec) => {
23739
- const target = rec ?? recording;
23740
- if (!target) {
23741
- const err = new Error("No recording to transcribe");
23742
- setError(err);
23743
- throw err;
23533
+ }
23534
+ const _fetch = opts.fetch;
23535
+ const requestInit = {
23536
+ ...opts,
23537
+ body: getValidRequestBody(opts)
23538
+ };
23539
+ let response = await _fetch(url, requestInit);
23540
+ for (const fn of interceptors.response.fns) {
23541
+ if (fn) {
23542
+ response = await fn(response, opts);
23744
23543
  }
23745
- setIsTranscribing(true);
23746
- setError(null);
23747
- try {
23748
- const pipe = await loadPipeline();
23749
- const audio = await audioToFloat32(target.blob);
23750
- const result = await pipe(audio, {
23751
- language: options?.language,
23752
- return_timestamps: true
23753
- });
23754
- const transcriptionResult = {
23755
- text: result.text.trim(),
23756
- chunks: result.chunks
23544
+ }
23545
+ const result = {
23546
+ response
23547
+ };
23548
+ if (response.ok) {
23549
+ const parseAs = (opts.parseAs === "auto" ? getParseAs(response.headers.get("Content-Type")) : opts.parseAs) ?? "json";
23550
+ if (response.status === 204 || response.headers.get("Content-Length") === "0") {
23551
+ let emptyData;
23552
+ switch (parseAs) {
23553
+ case "arrayBuffer":
23554
+ case "blob":
23555
+ case "text":
23556
+ emptyData = await response[parseAs]();
23557
+ break;
23558
+ case "formData":
23559
+ emptyData = new FormData();
23560
+ break;
23561
+ case "stream":
23562
+ emptyData = response.body;
23563
+ break;
23564
+ case "json":
23565
+ default:
23566
+ emptyData = {};
23567
+ break;
23568
+ }
23569
+ return {
23570
+ data: emptyData,
23571
+ ...result
23757
23572
  };
23758
- setTranscription(transcriptionResult);
23759
- return transcriptionResult;
23760
- } catch (err) {
23761
- const processedError = err instanceof Error ? err : new Error("Transcription failed");
23762
- setError(processedError);
23763
- throw processedError;
23764
- } finally {
23765
- setIsTranscribing(false);
23766
23573
  }
23767
- },
23768
- [recording, loadPipeline, options?.language]
23769
- );
23770
- const nativeSpeechAvailable = (0, import_react13.useMemo)(() => getOnDeviceSpeechRecognition() !== null, []);
23771
- const [isNativeListening, setIsNativeListening] = (0, import_react13.useState)(false);
23772
- const nativeRecognitionRef = (0, import_react13.useRef)(null);
23773
- const nativeTextRef = (0, import_react13.useRef)("");
23774
- const nativeResolveRef = (0, import_react13.useRef)(null);
23775
- const startNativeTranscription = (0, import_react13.useCallback)(() => {
23776
- const SR = getOnDeviceSpeechRecognition();
23777
- if (!SR) return;
23778
- nativeTextRef.current = "";
23779
- setError(null);
23780
- const recognition = new SR();
23781
- recognition.continuous = true;
23782
- recognition.interimResults = false;
23783
- recognition.lang = options?.language ?? "";
23784
- recognition.onresult = (event) => {
23785
- let text12 = "";
23786
- for (let i = 0; i < event.results.length; i++) {
23787
- const result = event.results[i];
23788
- if (result && result.isFinal && result[0]) {
23789
- text12 += result[0].transcript + " ";
23790
- }
23574
+ let data;
23575
+ switch (parseAs) {
23576
+ case "arrayBuffer":
23577
+ case "blob":
23578
+ case "formData":
23579
+ case "json":
23580
+ case "text":
23581
+ data = await response[parseAs]();
23582
+ break;
23583
+ case "stream":
23584
+ return {
23585
+ data: response.body,
23586
+ ...result
23587
+ };
23791
23588
  }
23792
- nativeTextRef.current = text12.trim();
23793
- };
23794
- recognition.onerror = (event) => {
23795
- if (event.error !== "aborted" && event.error !== "no-speech") {
23796
- setError(new Error(`Speech recognition error: ${event.error}`));
23589
+ if (parseAs === "json") {
23590
+ if (opts.responseValidator) {
23591
+ await opts.responseValidator(data);
23592
+ }
23593
+ if (opts.responseTransformer) {
23594
+ data = await opts.responseTransformer(data);
23595
+ }
23797
23596
  }
23798
- };
23799
- recognition.onend = () => {
23800
- setIsNativeListening(false);
23801
- nativeRecognitionRef.current = null;
23802
- const resolve = nativeResolveRef.current;
23803
- if (resolve) {
23804
- nativeResolveRef.current = null;
23805
- resolve({ text: nativeTextRef.current });
23597
+ return {
23598
+ data,
23599
+ ...result
23600
+ };
23601
+ }
23602
+ const textError = await response.text();
23603
+ let jsonError;
23604
+ try {
23605
+ jsonError = JSON.parse(textError);
23606
+ } catch {
23607
+ }
23608
+ const error = jsonError ?? textError;
23609
+ let finalError = error;
23610
+ for (const fn of interceptors.error.fns) {
23611
+ if (fn) {
23612
+ finalError = await fn(error, response, opts);
23806
23613
  }
23614
+ }
23615
+ finalError = finalError || {};
23616
+ if (opts.throwOnError) {
23617
+ throw finalError;
23618
+ }
23619
+ return {
23620
+ error: finalError,
23621
+ ...result
23807
23622
  };
23808
- nativeRecognitionRef.current = recognition;
23809
- recognition.start();
23810
- setIsNativeListening(true);
23811
- }, [options?.language]);
23812
- const stopNativeTranscription = (0, import_react13.useCallback)(() => {
23813
- return new Promise((resolve) => {
23814
- const recognition = nativeRecognitionRef.current;
23815
- if (!recognition) {
23816
- resolve({ text: nativeTextRef.current || "" });
23817
- return;
23818
- }
23819
- nativeResolveRef.current = resolve;
23820
- recognition.stop();
23623
+ };
23624
+ const makeMethodFn = (method) => (options) => request({ ...options, method });
23625
+ const makeSseFn = (method) => async (options) => {
23626
+ const { opts, url } = await beforeRequest(options);
23627
+ return createSseClient({
23628
+ ...opts,
23629
+ body: opts.body,
23630
+ headers: opts.headers,
23631
+ method,
23632
+ onRequest: async (url2, init) => {
23633
+ let request2 = new Request(url2, init);
23634
+ const requestInit = {
23635
+ ...init,
23636
+ method: init.method,
23637
+ url: url2
23638
+ };
23639
+ for (const fn of interceptors.request.fns) {
23640
+ if (fn) {
23641
+ await fn(requestInit);
23642
+ request2 = new Request(requestInit.url, requestInit);
23643
+ }
23644
+ }
23645
+ return request2;
23646
+ },
23647
+ url
23821
23648
  });
23822
- }, []);
23823
- const abortNativeTranscription = (0, import_react13.useCallback)(() => {
23824
- const recognition = nativeRecognitionRef.current;
23825
- if (recognition) {
23826
- nativeResolveRef.current = null;
23827
- recognition.abort();
23828
- nativeRecognitionRef.current = null;
23829
- setIsNativeListening(false);
23830
- }
23831
- }, []);
23649
+ };
23832
23650
  return {
23833
- isRecording,
23834
- startRecording,
23835
- stopRecording,
23836
- isTranscribing,
23837
- transcribe,
23838
- preloadModel,
23839
- disposeModel,
23840
- isModelLoaded,
23841
- isLoadingModel,
23842
- recording,
23843
- transcription,
23844
- error,
23845
- nativeSpeechAvailable,
23846
- startNativeTranscription,
23847
- stopNativeTranscription,
23848
- abortNativeTranscription,
23849
- isNativeListening
23651
+ buildUrl,
23652
+ connect: makeMethodFn("CONNECT"),
23653
+ delete: makeMethodFn("DELETE"),
23654
+ get: makeMethodFn("GET"),
23655
+ getConfig,
23656
+ head: makeMethodFn("HEAD"),
23657
+ interceptors,
23658
+ options: makeMethodFn("OPTIONS"),
23659
+ patch: makeMethodFn("PATCH"),
23660
+ post: makeMethodFn("POST"),
23661
+ put: makeMethodFn("PUT"),
23662
+ request,
23663
+ setConfig,
23664
+ sse: {
23665
+ connect: makeSseFn("CONNECT"),
23666
+ delete: makeSseFn("DELETE"),
23667
+ get: makeSseFn("GET"),
23668
+ head: makeSseFn("HEAD"),
23669
+ options: makeSseFn("OPTIONS"),
23670
+ patch: makeSseFn("PATCH"),
23671
+ post: makeSseFn("POST"),
23672
+ put: makeSseFn("PUT"),
23673
+ trace: makeSseFn("TRACE")
23674
+ },
23675
+ trace: makeMethodFn("TRACE")
23850
23676
  };
23851
- }
23677
+ };
23678
+
23679
+ // src/client/client.gen.ts
23680
+ init_clientConfig();
23681
+ var client = createClient(createClientConfig(createConfig()));
23682
+
23683
+ // src/client/sdk.gen.ts
23684
+ var getApiV1Config = (options) => {
23685
+ return (options?.client ?? client).get({
23686
+ url: "/api/v1/config",
23687
+ ...options
23688
+ });
23689
+ };
23690
+ var getApiV1CreditsBalance = (options) => {
23691
+ return (options?.client ?? client).get({
23692
+ url: "/api/v1/credits/balance",
23693
+ ...options
23694
+ });
23695
+ };
23696
+ var getApiV1CreditsPacks = (options) => {
23697
+ return (options?.client ?? client).get({
23698
+ url: "/api/v1/credits/packs",
23699
+ ...options
23700
+ });
23701
+ };
23702
+ var postApiV1CreditsPurchase = (options) => {
23703
+ return (options.client ?? client).post({
23704
+ url: "/api/v1/credits/purchase",
23705
+ ...options,
23706
+ headers: {
23707
+ "Content-Type": "application/json",
23708
+ ...options.headers
23709
+ }
23710
+ });
23711
+ };
23712
+ var getApiV1Models = (options) => {
23713
+ return (options?.client ?? client).get({
23714
+ url: "/api/v1/models",
23715
+ ...options
23716
+ });
23717
+ };
23718
+ var postApiV1PhoneCalls = (options) => {
23719
+ return (options.client ?? client).post({
23720
+ url: "/api/v1/phone-calls",
23721
+ ...options,
23722
+ headers: {
23723
+ "Content-Type": "application/json",
23724
+ ...options.headers
23725
+ }
23726
+ });
23727
+ };
23728
+ var getApiV1PhoneCallsByCallId = (options) => {
23729
+ return (options.client ?? client).get({
23730
+ url: "/api/v1/phone-calls/{call_id}",
23731
+ ...options
23732
+ });
23733
+ };
23734
+ var postApiV1SubscriptionsCancel = (options) => {
23735
+ return (options?.client ?? client).post({
23736
+ url: "/api/v1/subscriptions/cancel",
23737
+ ...options,
23738
+ headers: {
23739
+ "Content-Type": "application/json",
23740
+ ...options?.headers
23741
+ }
23742
+ });
23743
+ };
23744
+ var postApiV1SubscriptionsCreateCheckoutSession = (options) => {
23745
+ return (options.client ?? client).post({
23746
+ url: "/api/v1/subscriptions/create-checkout-session",
23747
+ ...options,
23748
+ headers: {
23749
+ "Content-Type": "application/json",
23750
+ ...options.headers
23751
+ }
23752
+ });
23753
+ };
23754
+ var postApiV1SubscriptionsCustomerPortal = (options) => {
23755
+ return (options.client ?? client).post({
23756
+ url: "/api/v1/subscriptions/customer-portal",
23757
+ ...options,
23758
+ headers: {
23759
+ "Content-Type": "application/json",
23760
+ ...options.headers
23761
+ }
23762
+ });
23763
+ };
23764
+ var postApiV1SubscriptionsRenew = (options) => {
23765
+ return (options?.client ?? client).post({
23766
+ url: "/api/v1/subscriptions/renew",
23767
+ ...options
23768
+ });
23769
+ };
23770
+ var getApiV1SubscriptionsStatus = (options) => {
23771
+ return (options?.client ?? client).get({
23772
+ url: "/api/v1/subscriptions/status",
23773
+ ...options
23774
+ });
23775
+ };
23776
+ var getApiV1WalletsBinding = (options) => {
23777
+ return (options?.client ?? client).get({
23778
+ url: "/api/v1/wallets/binding",
23779
+ ...options
23780
+ });
23781
+ };
23782
+ var postApiV1WalletsBinding = (options) => {
23783
+ return (options.client ?? client).post({
23784
+ url: "/api/v1/wallets/binding",
23785
+ ...options,
23786
+ headers: {
23787
+ "Content-Type": "application/json",
23788
+ ...options.headers
23789
+ }
23790
+ });
23791
+ };
23792
+ var postApiV1WalletsBindingNonce = (options) => {
23793
+ return (options?.client ?? client).post({
23794
+ url: "/api/v1/wallets/binding/nonce",
23795
+ ...options
23796
+ });
23797
+ };
23798
+ var deleteApiV1WalletsBindingByAddress = (options) => {
23799
+ return (options.client ?? client).delete({
23800
+ url: "/api/v1/wallets/binding/{address}",
23801
+ ...options
23802
+ });
23803
+ };
23804
+ var postAuthOauthByProviderExchange = (options) => {
23805
+ return (options.client ?? client).post({
23806
+ url: "/auth/oauth/{provider}/exchange",
23807
+ ...options,
23808
+ headers: {
23809
+ "Content-Type": "application/json",
23810
+ ...options.headers
23811
+ }
23812
+ });
23813
+ };
23814
+ var postAuthOauthByProviderRefresh = (options) => {
23815
+ return (options.client ?? client).post({
23816
+ url: "/auth/oauth/{provider}/refresh",
23817
+ ...options,
23818
+ headers: {
23819
+ "Content-Type": "application/json",
23820
+ ...options.headers
23821
+ }
23822
+ });
23823
+ };
23824
+ var postAuthOauthByProviderRevoke = (options) => {
23825
+ return (options.client ?? client).post({
23826
+ url: "/auth/oauth/{provider}/revoke",
23827
+ ...options,
23828
+ headers: {
23829
+ "Content-Type": "application/json",
23830
+ ...options.headers
23831
+ }
23832
+ });
23833
+ };
23852
23834
 
23853
23835
  // src/react/useCredits.ts
23854
- var import_react14 = require("react");
23855
- init_sdk_gen();
23856
23836
  init_clientConfig();
23857
23837
  function useCredits(options = {}) {
23858
23838
  const { getToken, baseUrl = BASE_URL, autoFetch = true, onError } = options;
@@ -24011,7 +23991,6 @@ function useCredits(options = {}) {
24011
23991
 
24012
23992
  // src/react/useModels.ts
24013
23993
  var import_react15 = require("react");
24014
- init_sdk_gen();
24015
23994
  init_clientConfig();
24016
23995
  function useModels(options = {}) {
24017
23996
  const { getToken, baseUrl = BASE_URL, provider, autoFetch = true } = options;
@@ -24117,7 +24096,6 @@ function useModels(options = {}) {
24117
24096
 
24118
24097
  // src/react/usePhoneCalls.ts
24119
24098
  var import_react16 = require("react");
24120
- init_sdk_gen();
24121
24099
  init_clientConfig();
24122
24100
  var DEFAULT_POLL_INTERVAL_MS = 5e3;
24123
24101
  var DEFAULT_POLL_MAX_ATTEMPTS = 60;
@@ -24417,7 +24395,6 @@ function usePhoneCalls(options = {}) {
24417
24395
 
24418
24396
  // src/react/useSubscription.ts
24419
24397
  var import_react17 = require("react");
24420
- init_sdk_gen();
24421
24398
  init_clientConfig();
24422
24399
  function useSubscription(options = {}) {
24423
24400
  const { getToken, baseUrl = BASE_URL, autoFetch = true, onError } = options;
@@ -24623,7 +24600,6 @@ function useSubscription(options = {}) {
24623
24600
 
24624
24601
  // src/react/useWalletBinding.ts
24625
24602
  var import_react18 = require("react");
24626
- init_sdk_gen();
24627
24603
  init_clientConfig();
24628
24604
  function useWalletBinding(options = {}) {
24629
24605
  const { getToken, baseUrl = BASE_URL, autoFetch = true, onError } = options;
@@ -24807,7 +24783,6 @@ function useWalletBinding(options = {}) {
24807
24783
  var import_react19 = require("react");
24808
24784
 
24809
24785
  // src/lib/backup/dropbox/auth.ts
24810
- init_sdk_gen();
24811
24786
  init_logger();
24812
24787
 
24813
24788
  // src/lib/backup/oauth/storage.ts
@@ -25564,7 +25539,6 @@ function useDropboxBackup(options) {
25564
25539
  var import_react21 = require("react");
25565
25540
 
25566
25541
  // src/lib/backup/google/auth.ts
25567
- init_sdk_gen();
25568
25542
  init_logger();
25569
25543
  var PROVIDER2 = "google-drive";
25570
25544
  var CODE_STORAGE_KEY = "google_oauth_state";
@@ -27363,7 +27337,6 @@ function useBackup(options) {
27363
27337
  }
27364
27338
 
27365
27339
  // src/lib/auth/google-calendar.ts
27366
- init_sdk_gen();
27367
27340
  init_useEncryption();
27368
27341
  init_logger();
27369
27342
  var PROVIDER3 = "google-drive";
@@ -27689,7 +27662,6 @@ async function migrateCalendarToken(walletAddress) {
27689
27662
  }
27690
27663
 
27691
27664
  // src/lib/auth/google-drive.ts
27692
- init_sdk_gen();
27693
27665
  init_useEncryption();
27694
27666
  init_logger();
27695
27667
  var PROVIDER4 = "google-drive";
@@ -28566,7 +28538,6 @@ function getNotionMCPUrl() {
28566
28538
  }
28567
28539
 
28568
28540
  // src/lib/auth/github.ts
28569
- init_sdk_gen();
28570
28541
  init_useEncryption();
28571
28542
  init_logger();
28572
28543
  var PROVIDER5 = "github";