@anuma/sdk 2.7.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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) {
@@ -2280,6 +1240,67 @@ async function messageToStored(message, walletAddress, signMessage, embeddedWall
2280
1240
  }
2281
1241
  return baseMessage;
2282
1242
  }
1243
+ function rawDate(value) {
1244
+ return new Date(typeof value === "number" ? value : 0);
1245
+ }
1246
+ function messageRawToStoredRaw(raw, projection) {
1247
+ const parseJsonField = (rawValue) => {
1248
+ if (!rawValue) return void 0;
1249
+ if (typeof rawValue === "string") {
1250
+ if (rawValue.startsWith("enc:")) return rawValue;
1251
+ try {
1252
+ return JSON.parse(rawValue);
1253
+ } catch {
1254
+ return void 0;
1255
+ }
1256
+ }
1257
+ return rawValue;
1258
+ };
1259
+ const skipEmbeddings = projection?.skipEmbeddings === true;
1260
+ const vectorRaw = skipEmbeddings ? null : raw.vector;
1261
+ const chunksRaw = skipEmbeddings ? null : raw.chunks;
1262
+ return {
1263
+ uniqueId: raw.id,
1264
+ messageId: raw.message_id,
1265
+ conversationId: raw.conversation_id ?? "",
1266
+ role: raw.role ?? "",
1267
+ content: raw.content ?? "",
1268
+ model: raw.model,
1269
+ imageModel: raw.image_model,
1270
+ files: parseJsonField(raw.files),
1271
+ fileIds: parseJsonField(raw.file_ids),
1272
+ createdAt: rawDate(raw.created_at),
1273
+ updatedAt: rawDate(raw.updated_at),
1274
+ vector: skipEmbeddings ? void 0 : parseJsonField(vectorRaw),
1275
+ embeddingModel: raw.embedding_model,
1276
+ chunks: skipEmbeddings ? void 0 : parseJsonField(chunksRaw),
1277
+ usage: parseJsonField(raw.usage),
1278
+ sources: parseJsonField(raw.sources),
1279
+ responseDuration: raw.response_duration,
1280
+ // `was_stopped` is an OPTIONAL boolean: an unset row sanitizes to null, and the Model path
1281
+ // (message.wasStopped) returns that null verbatim. Preserve it (don't collapse to false) so the
1282
+ // raw path is byte-identical. When set, coerce SQLite 0/1 and LokiJS true/false alike.
1283
+ wasStopped: raw.was_stopped === null || raw.was_stopped === void 0 ? raw.was_stopped : raw.was_stopped === true || raw.was_stopped === 1,
1284
+ error: raw.error,
1285
+ thoughtProcess: parseJsonField(raw.thought_process),
1286
+ thinking: raw.thinking,
1287
+ parentMessageId: raw.parent_message_id,
1288
+ feedback: raw.feedback || null,
1289
+ toolCallEvents: parseJsonField(raw.tool_call_events)
1290
+ };
1291
+ }
1292
+ async function messageRawToStored(raw, walletAddress, signMessage, embeddedWalletSigner, projection) {
1293
+ const baseMessage = messageRawToStoredRaw(raw, projection);
1294
+ if (walletAddress) {
1295
+ return await decryptMessageFields(
1296
+ baseMessage,
1297
+ walletAddress,
1298
+ signMessage,
1299
+ embeddedWalletSigner
1300
+ );
1301
+ }
1302
+ return baseMessage;
1303
+ }
2283
1304
  function conversationToStoredRaw(conversation) {
2284
1305
  return {
2285
1306
  uniqueId: conversation.id,
@@ -2304,14 +1325,41 @@ async function conversationToStored(conversation, walletAddress, signMessage, em
2304
1325
  }
2305
1326
  return baseConversation;
2306
1327
  }
2307
- async function createConversationOp(ctx, opts, defaultTitle = "New Conversation") {
2308
- const convId = opts?.conversationId || generateConversationId();
2309
- const title = opts?.title || defaultTitle;
2310
- const convOpts = {
2311
- conversationId: convId,
2312
- title,
2313
- projectId: opts?.projectId
2314
- };
1328
+ function conversationRawToStoredRaw(raw) {
1329
+ const pinnedAt = raw.pinned_at;
1330
+ return {
1331
+ uniqueId: raw.id,
1332
+ conversationId: raw.conversation_id ?? "",
1333
+ title: raw.title ?? "",
1334
+ projectId: raw.project_id,
1335
+ createdAt: rawDate(raw.created_at),
1336
+ updatedAt: rawDate(raw.updated_at),
1337
+ // SQLite stores booleans as 0/1, LokiJS as true/false — coerce both.
1338
+ isDeleted: raw.is_deleted === true || raw.is_deleted === 1,
1339
+ // @date maps a non-number raw column (incl. an explicit unpin null) to null; a number → Date.
1340
+ pinnedAt: typeof pinnedAt === "number" ? new Date(pinnedAt) : null
1341
+ };
1342
+ }
1343
+ async function conversationRawToStored(raw, walletAddress, signMessage, embeddedWalletSigner) {
1344
+ const baseConversation = conversationRawToStoredRaw(raw);
1345
+ if (walletAddress) {
1346
+ return await decryptConversationFields(
1347
+ baseConversation,
1348
+ walletAddress,
1349
+ signMessage,
1350
+ embeddedWalletSigner
1351
+ );
1352
+ }
1353
+ return baseConversation;
1354
+ }
1355
+ async function createConversationOp(ctx, opts, defaultTitle = "New Conversation") {
1356
+ const convId = opts?.conversationId || generateConversationId();
1357
+ const title = opts?.title || defaultTitle;
1358
+ const convOpts = {
1359
+ conversationId: convId,
1360
+ title,
1361
+ projectId: opts?.projectId
1362
+ };
2315
1363
  const encryptedOpts = ctx.walletAddress && ctx.signMessage ? await encryptConversationFields(
2316
1364
  convOpts,
2317
1365
  ctx.walletAddress,
@@ -2343,36 +1391,51 @@ async function getConversationOp(ctx, id) {
2343
1391
  ) : null;
2344
1392
  }
2345
1393
  async function getConversationsOp(ctx) {
2346
- const results = await ctx.conversationsCollection.query(import_watermelondb.Q.where("is_deleted", false), import_watermelondb.Q.sortBy("created_at", import_watermelondb.Q.desc)).fetch();
1394
+ const results = await ctx.conversationsCollection.query(import_watermelondb.Q.where("is_deleted", false), import_watermelondb.Q.sortBy("created_at", import_watermelondb.Q.desc)).unsafeFetchRaw();
2347
1395
  return Promise.all(
2348
1396
  results.map(
2349
- (conv) => conversationToStored(conv, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
1397
+ (raw) => conversationRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
2350
1398
  )
2351
1399
  );
2352
1400
  }
2353
- function conversationToLazyStored(conversation) {
1401
+ function conversationRawToLazyStored(raw) {
1402
+ const pinnedAt = raw.pinned_at;
2354
1403
  return {
2355
- uniqueId: conversation.id,
2356
- conversationId: conversation.conversationId,
2357
- encryptedTitle: conversation.title,
2358
- projectId: conversation.projectId,
2359
- createdAt: conversation.createdAt,
2360
- updatedAt: conversation.updatedAt,
2361
- isDeleted: conversation.isDeleted,
2362
- pinnedAt: conversation.pinnedAt
1404
+ uniqueId: raw.id,
1405
+ conversationId: raw.conversation_id ?? "",
1406
+ encryptedTitle: raw.title ?? "",
1407
+ projectId: raw.project_id,
1408
+ createdAt: rawDate(raw.created_at),
1409
+ updatedAt: rawDate(raw.updated_at),
1410
+ isDeleted: raw.is_deleted === true || raw.is_deleted === 1,
1411
+ pinnedAt: typeof pinnedAt === "number" ? new Date(pinnedAt) : null
2363
1412
  };
2364
1413
  }
2365
1414
  async function getConversationsLazyOp(ctx) {
2366
- const results = await ctx.conversationsCollection.query(import_watermelondb.Q.where("is_deleted", false), import_watermelondb.Q.sortBy("created_at", import_watermelondb.Q.desc)).fetch();
2367
- return results.map(conversationToLazyStored);
1415
+ const results = await ctx.conversationsCollection.query(import_watermelondb.Q.where("is_deleted", false), import_watermelondb.Q.sortBy("created_at", import_watermelondb.Q.desc)).unsafeFetchRaw();
1416
+ return results.map(conversationRawToLazyStored);
1417
+ }
1418
+ async function getConversationsPageOp(ctx, options) {
1419
+ const limit = Math.floor(options?.limit ?? 200);
1420
+ if (!Number.isFinite(limit) || limit < 1) return [];
1421
+ const exclude = new Set(options?.boundaryExcludeUniqueIds ?? []);
1422
+ const clauses = [import_watermelondb.Q.where("is_deleted", false)];
1423
+ if (options?.before !== void 0) {
1424
+ clauses.push(
1425
+ exclude.size > 0 ? import_watermelondb.Q.where("created_at", import_watermelondb.Q.lte(options.before)) : import_watermelondb.Q.where("created_at", import_watermelondb.Q.lt(options.before))
1426
+ );
1427
+ }
1428
+ const fetched = await ctx.conversationsCollection.query(...clauses, import_watermelondb.Q.sortBy("created_at", import_watermelondb.Q.desc), import_watermelondb.Q.take(limit + exclude.size)).unsafeFetchRaw();
1429
+ const results = exclude.size > 0 ? fetched.filter((raw) => !exclude.has(raw.id)) : fetched;
1430
+ return results.slice(0, limit).map(conversationRawToLazyStored);
2368
1431
  }
2369
1432
  async function getConversationsByProjectLazyOp(ctx, projectId) {
2370
1433
  const results = await ctx.conversationsCollection.query(
2371
1434
  import_watermelondb.Q.where("project_id", projectId === null ? "" : projectId),
2372
1435
  import_watermelondb.Q.where("is_deleted", false),
2373
1436
  import_watermelondb.Q.sortBy("created_at", import_watermelondb.Q.desc)
2374
- ).fetch();
2375
- return results.map(conversationToLazyStored);
1437
+ ).unsafeFetchRaw();
1438
+ return results.map(conversationRawToLazyStored);
2376
1439
  }
2377
1440
  async function updateConversationTitleOp(ctx, id, title) {
2378
1441
  const results = await ctx.conversationsCollection.query(import_watermelondb.Q.where("conversation_id", id), import_watermelondb.Q.where("is_deleted", false)).fetch();
@@ -2434,18 +1497,18 @@ async function getConversationsByProjectOp(ctx, projectId) {
2434
1497
  import_watermelondb.Q.where("project_id", projectId === null ? "" : projectId),
2435
1498
  import_watermelondb.Q.where("is_deleted", false),
2436
1499
  import_watermelondb.Q.sortBy("created_at", import_watermelondb.Q.desc)
2437
- ).fetch();
1500
+ ).unsafeFetchRaw();
2438
1501
  return Promise.all(
2439
1502
  results.map(
2440
- (conv) => conversationToStored(conv, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
1503
+ (raw) => conversationRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
2441
1504
  )
2442
1505
  );
2443
1506
  }
2444
1507
  async function getMessagesOp(ctx, convId) {
2445
- const results = await ctx.messagesCollection.query(import_watermelondb.Q.where("conversation_id", convId), import_watermelondb.Q.sortBy("message_id", import_watermelondb.Q.asc)).fetch();
1508
+ const results = await ctx.messagesCollection.query(import_watermelondb.Q.where("conversation_id", convId), import_watermelondb.Q.sortBy("message_id", import_watermelondb.Q.asc)).unsafeFetchRaw();
2446
1509
  return Promise.all(
2447
1510
  results.map(
2448
- (msg) => messageToStored(msg, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
1511
+ (raw) => messageRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner)
2449
1512
  )
2450
1513
  );
2451
1514
  }
@@ -2462,39 +1525,40 @@ async function getMessagesPageOp(ctx, convId, opts) {
2462
1525
  exclude.size > 0 ? import_watermelondb.Q.where("message_id", import_watermelondb.Q.lte(opts.beforeMessageId)) : import_watermelondb.Q.where("message_id", import_watermelondb.Q.lt(opts.beforeMessageId))
2463
1526
  );
2464
1527
  }
2465
- const fetched = await ctx.messagesCollection.query(...clauses, import_watermelondb.Q.sortBy("message_id", import_watermelondb.Q.desc), import_watermelondb.Q.take(limit + exclude.size)).fetch();
2466
- const results = (exclude.size > 0 ? fetched.filter((msg) => !exclude.has(msg.id)) : fetched).slice(0, limit);
1528
+ const fetched = await ctx.messagesCollection.query(...clauses, import_watermelondb.Q.sortBy("message_id", import_watermelondb.Q.desc), import_watermelondb.Q.take(limit + exclude.size)).unsafeFetchRaw();
1529
+ const results = (exclude.size > 0 ? fetched.filter((raw) => !exclude.has(raw.id)) : fetched).slice(0, limit);
2467
1530
  results.reverse();
2468
1531
  return Promise.all(
2469
1532
  results.map(
2470
- (msg) => messageToStored(msg, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner, {
1533
+ (raw) => messageRawToStored(raw, ctx.walletAddress, ctx.signMessage, ctx.embeddedWalletSigner, {
2471
1534
  skipEmbeddings: true
2472
1535
  })
2473
1536
  )
2474
1537
  );
2475
1538
  }
2476
1539
  async function getMessageSkeletonsOp(ctx, convId) {
2477
- const results = await ctx.messagesCollection.query(import_watermelondb.Q.where("conversation_id", convId), import_watermelondb.Q.sortBy("message_id", import_watermelondb.Q.asc)).fetch();
1540
+ const results = await ctx.messagesCollection.query(import_watermelondb.Q.where("conversation_id", convId), import_watermelondb.Q.sortBy("message_id", import_watermelondb.Q.asc)).unsafeFetchRaw();
2478
1541
  const roleById = /* @__PURE__ */ new Map();
2479
- for (const msg of results) {
2480
- roleById.set(msg.id, msg.role);
2481
- }
2482
- const skeletons = results.map((msg) => ({
2483
- uniqueId: msg.id,
2484
- messageId: msg.messageId,
2485
- conversationId: String(msg._getRaw("conversation_id")),
2486
- role: msg.role,
2487
- createdAt: msg.createdAt,
1542
+ for (const raw of results) {
1543
+ roleById.set(raw.id, raw.role);
1544
+ }
1545
+ const skeletons = results.map((raw) => ({
1546
+ uniqueId: raw.id,
1547
+ messageId: raw.message_id,
1548
+ conversationId: raw.conversation_id ?? "",
1549
+ role: raw.role ?? "",
1550
+ createdAt: rawDate(raw.created_at),
2488
1551
  // WatermelonDB surfaces unset text columns as null at runtime — normalize
2489
1552
  // to undefined so `parentMessageId ?? undefined` keying works everywhere.
2490
- parentMessageId: msg.parentMessageId ?? void 0,
2491
- model: msg.model ?? void 0
1553
+ parentMessageId: raw.parent_message_id ?? void 0,
1554
+ model: raw.model ?? void 0
2492
1555
  }));
2493
1556
  const artifactIndices = [];
2494
1557
  for (let i = 0; i < results.length; i++) {
2495
- const msg = results[i];
2496
- if (msg.role !== "user" || !msg.parentMessageId) continue;
2497
- if (roleById.get(msg.parentMessageId) === "user") {
1558
+ const raw = results[i];
1559
+ const parentMessageId = raw.parent_message_id;
1560
+ if (raw.role !== "user" || !parentMessageId) continue;
1561
+ if (roleById.get(parentMessageId) === "user") {
2498
1562
  artifactIndices.push(i);
2499
1563
  }
2500
1564
  }
@@ -3132,7 +2196,7 @@ var init_constants = __esm({
3132
2196
  }
3133
2197
  });
3134
2198
 
3135
- // src/lib/memoryEngine/embeddings.ts
2199
+ // src/lib/memoryEngine/generate.ts
3136
2200
  async function withEmbeddingRetry(call) {
3137
2201
  let last;
3138
2202
  let lastThrown;
@@ -3168,7 +2232,7 @@ async function generateEmbedding(text12, options) {
3168
2232
  const { baseUrl = BASE_URL, getToken, apiKey, model, cache } = options;
3169
2233
  if (cache) {
3170
2234
  const cached = cache.get(text12);
3171
- if (cached) return cached;
2235
+ if (cached) return Array.from(cached);
3172
2236
  }
3173
2237
  let headers;
3174
2238
  if (apiKey) {
@@ -3183,7 +2247,7 @@ async function generateEmbedding(text12, options) {
3183
2247
  throw new Error("Either apiKey or getToken must be provided");
3184
2248
  }
3185
2249
  const response = await withEmbeddingRetry(
3186
- () => postApiV1Embeddings({
2250
+ () => (0, import_client.postApiV1Embeddings)({
3187
2251
  baseUrl,
3188
2252
  body: {
3189
2253
  // Mask PII from the request body only — the cache above still keys on
@@ -3207,14 +2271,15 @@ async function generateEmbedding(text12, options) {
3207
2271
  totalTokens: response.data.usage.total_tokens ?? 0
3208
2272
  });
3209
2273
  }
2274
+ const f32Embedding = Float32Array.from(embedding);
3210
2275
  if (cache) {
3211
- cache.set(text12, embedding);
2276
+ cache.set(text12, f32Embedding);
3212
2277
  }
3213
- return embedding;
2278
+ return Array.from(f32Embedding);
3214
2279
  }
3215
2280
  async function generateEmbeddingsBatch(texts, headers, baseUrl, model, onUsage, maskInput) {
3216
2281
  const response = await withEmbeddingRetry(
3217
- () => postApiV1Embeddings({
2282
+ () => (0, import_client.postApiV1Embeddings)({
3218
2283
  baseUrl,
3219
2284
  // Mask PII from the request body only; cache/order still key on originals.
3220
2285
  body: { input: maskInput ? texts.map(maskInput) : texts, model },
@@ -3246,7 +2311,7 @@ async function generateEmbeddings(texts, options) {
3246
2311
  if (cache) {
3247
2312
  const cached = cache.get(texts[i]);
3248
2313
  if (cached) {
3249
- results[i] = cached;
2314
+ results[i] = Array.from(cached);
3250
2315
  continue;
3251
2316
  }
3252
2317
  }
@@ -3307,13 +2372,35 @@ async function generateEmbeddings(texts, options) {
3307
2372
  newEmbeddings = allEmbeddings.flat();
3308
2373
  }
3309
2374
  for (let i = 0; i < uncachedIndices.length; i++) {
3310
- results[uncachedIndices[i]] = newEmbeddings[i];
2375
+ const f32Embedding = Float32Array.from(newEmbeddings[i]);
2376
+ results[uncachedIndices[i]] = Array.from(f32Embedding);
3311
2377
  if (cache) {
3312
- cache.set(uncachedTexts[i], newEmbeddings[i]);
2378
+ cache.set(uncachedTexts[i], f32Embedding);
3313
2379
  }
3314
2380
  }
3315
2381
  return results;
3316
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
3317
2404
  async function embedMessage(ctx, messageId, options) {
3318
2405
  let message;
3319
2406
  const conversations = await getConversationsOp(ctx);
@@ -3469,27 +2556,17 @@ async function chunkAndEmbedAllMessages(ctx, options, filter) {
3469
2556
  }
3470
2557
  return embeddedCount;
3471
2558
  }
3472
- var DEFAULT_MIN_CONTENT_LENGTH, EMBED_MAX_ATTEMPTS, EmbeddingHttpError, DEFAULT_EMBEDDING_BATCH_SIZE, DEFAULT_EMBEDDING_BATCH_CONCURRENCY;
2559
+ var DEFAULT_MIN_CONTENT_LENGTH;
3473
2560
  var init_embeddings = __esm({
3474
2561
  "src/lib/memoryEngine/embeddings.ts"() {
3475
2562
  "use strict";
3476
- init_client2();
3477
- init_clientConfig();
3478
2563
  init_operations();
3479
2564
  init_logger();
3480
2565
  init_chunking();
3481
2566
  init_constants();
2567
+ init_generate();
2568
+ init_generate();
3482
2569
  DEFAULT_MIN_CONTENT_LENGTH = 10;
3483
- EMBED_MAX_ATTEMPTS = 4;
3484
- EmbeddingHttpError = class extends Error {
3485
- constructor(message, status) {
3486
- super(message);
3487
- this.name = "EmbeddingHttpError";
3488
- this.status = status;
3489
- }
3490
- };
3491
- DEFAULT_EMBEDDING_BATCH_SIZE = 100;
3492
- DEFAULT_EMBEDDING_BATCH_CONCURRENCY = 3;
3493
2570
  }
3494
2571
  });
3495
2572
 
@@ -7597,6 +6674,7 @@ __export(index_exports, {
7597
6674
  getConversationsByProjectLazyOp: () => getConversationsByProjectLazyOp,
7598
6675
  getConversationsByProjectOp: () => getConversationsByProjectOp,
7599
6676
  getConversationsLazyOp: () => getConversationsLazyOp,
6677
+ getConversationsPageOp: () => getConversationsPageOp,
7600
6678
  getDocumentsOp: () => getDocumentsOp,
7601
6679
  getDriveAccessToken: () => getDriveAccessToken,
7602
6680
  getEncryptionKey: () => getEncryptionKey,
@@ -7792,8 +6870,142 @@ module.exports = __toCommonJS(index_exports);
7792
6870
  // src/lib/chat/resumeStream.ts
7793
6871
  init_clientConfig();
7794
6872
 
6873
+ // src/client/core/serverSentEvents.gen.ts
6874
+ var createSseClient = ({
6875
+ onRequest,
6876
+ onSseError,
6877
+ onSseEvent,
6878
+ responseTransformer,
6879
+ responseValidator,
6880
+ sseDefaultRetryDelay,
6881
+ sseMaxRetryAttempts,
6882
+ sseMaxRetryDelay,
6883
+ sseSleepFn,
6884
+ url,
6885
+ ...options
6886
+ }) => {
6887
+ let lastEventId;
6888
+ const sleep4 = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
6889
+ const createStream = async function* () {
6890
+ let retryDelay = sseDefaultRetryDelay ?? 3e3;
6891
+ let attempt = 0;
6892
+ const signal = options.signal ?? new AbortController().signal;
6893
+ while (true) {
6894
+ if (signal.aborted) break;
6895
+ attempt++;
6896
+ const headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers);
6897
+ if (lastEventId !== void 0) {
6898
+ headers.set("Last-Event-ID", lastEventId);
6899
+ }
6900
+ try {
6901
+ const requestInit = {
6902
+ redirect: "follow",
6903
+ ...options,
6904
+ body: options.serializedBody,
6905
+ headers,
6906
+ signal
6907
+ };
6908
+ let request = new Request(url, requestInit);
6909
+ if (onRequest) {
6910
+ request = await onRequest(url, requestInit);
6911
+ }
6912
+ const _fetch = options.fetch ?? globalThis.fetch;
6913
+ const response = await _fetch(request);
6914
+ if (!response.ok)
6915
+ throw new Error(
6916
+ `SSE failed: ${response.status} ${response.statusText}`
6917
+ );
6918
+ if (!response.body) throw new Error("No body in SSE response");
6919
+ const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
6920
+ let buffer = "";
6921
+ const abortHandler = () => {
6922
+ try {
6923
+ reader.cancel();
6924
+ } catch {
6925
+ }
6926
+ };
6927
+ signal.addEventListener("abort", abortHandler);
6928
+ try {
6929
+ while (true) {
6930
+ const { done, value } = await reader.read();
6931
+ if (done) break;
6932
+ buffer += value;
6933
+ const chunks = buffer.split("\n\n");
6934
+ buffer = chunks.pop() ?? "";
6935
+ for (const chunk of chunks) {
6936
+ const lines = chunk.split("\n");
6937
+ const dataLines = [];
6938
+ let eventName;
6939
+ for (const line of lines) {
6940
+ if (line.startsWith("data:")) {
6941
+ dataLines.push(line.replace(/^data:\s*/, ""));
6942
+ } else if (line.startsWith("event:")) {
6943
+ eventName = line.replace(/^event:\s*/, "");
6944
+ } else if (line.startsWith("id:")) {
6945
+ lastEventId = line.replace(/^id:\s*/, "");
6946
+ } else if (line.startsWith("retry:")) {
6947
+ const parsed = Number.parseInt(
6948
+ line.replace(/^retry:\s*/, ""),
6949
+ 10
6950
+ );
6951
+ if (!Number.isNaN(parsed)) {
6952
+ retryDelay = parsed;
6953
+ }
6954
+ }
6955
+ }
6956
+ let data;
6957
+ let parsedJson = false;
6958
+ if (dataLines.length) {
6959
+ const rawData = dataLines.join("\n");
6960
+ try {
6961
+ data = JSON.parse(rawData);
6962
+ parsedJson = true;
6963
+ } catch {
6964
+ data = rawData;
6965
+ }
6966
+ }
6967
+ if (parsedJson) {
6968
+ if (responseValidator) {
6969
+ await responseValidator(data);
6970
+ }
6971
+ if (responseTransformer) {
6972
+ data = await responseTransformer(data);
6973
+ }
6974
+ }
6975
+ onSseEvent?.({
6976
+ data,
6977
+ event: eventName,
6978
+ id: lastEventId,
6979
+ retry: retryDelay
6980
+ });
6981
+ if (dataLines.length) {
6982
+ yield data;
6983
+ }
6984
+ }
6985
+ }
6986
+ } finally {
6987
+ signal.removeEventListener("abort", abortHandler);
6988
+ reader.releaseLock();
6989
+ }
6990
+ break;
6991
+ } catch (error) {
6992
+ onSseError?.(error);
6993
+ if (sseMaxRetryAttempts !== void 0 && attempt >= sseMaxRetryAttempts) {
6994
+ break;
6995
+ }
6996
+ const backoff = Math.min(
6997
+ retryDelay * 2 ** (attempt - 1),
6998
+ sseMaxRetryDelay ?? 3e4
6999
+ );
7000
+ await sleep4(backoff);
7001
+ }
7002
+ }
7003
+ };
7004
+ const stream = createStream();
7005
+ return { stream };
7006
+ };
7007
+
7795
7008
  // src/lib/chat/toolLoop.ts
7796
- init_serverSentEvents_gen();
7797
7009
  init_clientConfig();
7798
7010
  init_embeddings();
7799
7011
  init_redactor();
@@ -15205,8 +14417,12 @@ init_recall();
15205
14417
 
15206
14418
  // src/lib/memory/recallTool.ts
15207
14419
  init_recall();
14420
+
14421
+ // src/lib/memory/recallConstants.ts
15208
14422
  var RECALL_TOOL_NAME = "recall_memory";
15209
14423
  var RECALL_MAX_LIMIT = 50;
14424
+
14425
+ // src/lib/memory/recallTool.ts
15210
14426
  var DEFAULT_LIMIT2 = 8;
15211
14427
  var DEFAULT_BUDGET2 = "low";
15212
14428
  function formatEventTime(start, end, kind) {
@@ -16002,6 +15218,7 @@ init_redactor();
16002
15218
  init_logger();
16003
15219
 
16004
15220
  // src/lib/processors/encoding.ts
15221
+ var B64_ENCODE_CHUNK = 32768 * 3;
16005
15222
  async function dataUrlToArrayBuffer(dataUrl) {
16006
15223
  if (dataUrl.startsWith("blob:") || dataUrl.startsWith("http://") || dataUrl.startsWith("https://")) {
16007
15224
  const response = await fetch(dataUrl);
@@ -16024,11 +15241,28 @@ function uint8ArrayToBase64(data) {
16024
15241
  if (typeof Buffer !== "undefined") {
16025
15242
  return Buffer.from(data).toString("base64");
16026
15243
  }
16027
- let binary = "";
16028
- for (let i = 0; i < data.length; i++) {
16029
- binary += String.fromCharCode(data[i]);
15244
+ let base64 = "";
15245
+ for (let i = 0; i < data.length; i += B64_ENCODE_CHUNK) {
15246
+ const slice = data.subarray(i, i + B64_ENCODE_CHUNK);
15247
+ let binary = "";
15248
+ for (let j = 0; j < slice.length; j++) {
15249
+ binary += String.fromCharCode(slice[j]);
15250
+ }
15251
+ base64 += btoa(binary);
15252
+ }
15253
+ return base64;
15254
+ }
15255
+ function base64ToUint8Array(base64) {
15256
+ if (typeof Buffer !== "undefined") {
15257
+ const buf = Buffer.from(base64, "base64");
15258
+ return new Uint8Array(buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength));
15259
+ }
15260
+ const binary = atob(base64);
15261
+ const bytes = new Uint8Array(binary.length);
15262
+ for (let i = 0; i < binary.length; i++) {
15263
+ bytes[i] = binary.charCodeAt(i);
16030
15264
  }
16031
- return btoa(binary);
15265
+ return bytes;
16032
15266
  }
16033
15267
 
16034
15268
  // src/lib/processors/ExcelProcessor.ts
@@ -16757,6 +15991,9 @@ async function preprocessFiles(files, options = {}) {
16757
15991
  };
16758
15992
  }
16759
15993
 
15994
+ // src/lib/tools/clientToolSelection.ts
15995
+ init_generate();
15996
+
16760
15997
  // src/tools/appBuilderPrompt.ts
16761
15998
  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.
16762
15999
 
@@ -16861,7 +16098,7 @@ WORKFLOW:
16861
16098
 
16862
16099
  // src/lib/tools/serverTools.ts
16863
16100
  init_logger();
16864
- init_embeddings();
16101
+ init_generate();
16865
16102
  init_vector();
16866
16103
  var DEFAULT_CACHE_EXPIRATION_MS = 24 * 60 * 60 * 1e3;
16867
16104
  var SERVER_TOOLS_CACHE_KEY = "sdk_server_tools_cache";
@@ -16929,7 +16166,7 @@ function getCachedServerTools() {
16929
16166
  if (!cached) return null;
16930
16167
  const parsed = JSON.parse(cached);
16931
16168
  if (parsed.version !== CACHE_VERSION) {
16932
- clearServerToolsCache();
16169
+ removeLocalStorageCache();
16933
16170
  return null;
16934
16171
  }
16935
16172
  return parsed;
@@ -16941,37 +16178,45 @@ function isCacheExpired(cache, expirationMs = DEFAULT_CACHE_EXPIRATION_MS) {
16941
16178
  if (!cache) return true;
16942
16179
  return Date.now() - cache.timestamp > expirationMs;
16943
16180
  }
16944
- function cacheServerTools(tools, checksum) {
16945
- if (typeof localStorage === "undefined") return;
16946
- const cacheData = {
16181
+ function buildCacheEntry(tools, checksum) {
16182
+ return {
16947
16183
  tools,
16948
16184
  timestamp: Date.now(),
16949
16185
  version: CACHE_VERSION,
16950
16186
  ...checksum && { checksum }
16951
16187
  };
16188
+ }
16189
+ function writeLocalStorageCache(entry) {
16190
+ if (typeof localStorage === "undefined") return;
16952
16191
  try {
16953
- localStorage.setItem(SERVER_TOOLS_CACHE_KEY, JSON.stringify(cacheData));
16192
+ localStorage.setItem(SERVER_TOOLS_CACHE_KEY, JSON.stringify(entry));
16954
16193
  } catch (error) {
16955
16194
  getLogger().warn("[serverTools] Failed to cache tools:", error);
16956
16195
  }
16957
16196
  }
16958
- function clearServerToolsCache() {
16197
+ function removeLocalStorageCache() {
16959
16198
  if (typeof localStorage === "undefined") return;
16960
16199
  localStorage.removeItem(SERVER_TOOLS_CACHE_KEY);
16961
16200
  }
16962
- function getToolsChecksum2() {
16963
- const cached = getCachedServerTools();
16964
- return cached?.checksum;
16201
+ var localStorageToolsCache = {
16202
+ get: getCachedServerTools,
16203
+ set: writeLocalStorageCache,
16204
+ clear: removeLocalStorageCache
16205
+ };
16206
+ function clearServerToolsCache(cache = localStorageToolsCache) {
16207
+ return cache.clear?.();
16208
+ }
16209
+ function getToolsChecksum2(cache = localStorageToolsCache) {
16210
+ const cached = cache.get();
16211
+ return cached instanceof Promise ? cached.then((c) => c?.checksum) : cached?.checksum;
16965
16212
  }
16966
- function shouldRefreshTools(responseChecksum) {
16213
+ function shouldRefreshTools(responseChecksum, cache = localStorageToolsCache) {
16967
16214
  if (!responseChecksum) {
16968
16215
  return false;
16969
16216
  }
16970
- const cachedChecksum = getToolsChecksum2();
16971
- if (!cachedChecksum) {
16972
- return true;
16973
- }
16974
- return cachedChecksum !== responseChecksum;
16217
+ const decide = (cachedChecksum2) => !cachedChecksum2 || cachedChecksum2 !== responseChecksum;
16218
+ const cachedChecksum = getToolsChecksum2(cache);
16219
+ return cachedChecksum instanceof Promise ? cachedChecksum.then(decide) : decide(cachedChecksum);
16975
16220
  }
16976
16221
  async function fetchServerToolsFromApi(baseUrl, token) {
16977
16222
  const response = await fetch(`${baseUrl}/api/v1/tools`, {
@@ -16993,9 +16238,23 @@ async function getServerTools(options) {
16993
16238
  cacheExpirationMs = DEFAULT_CACHE_EXPIRATION_MS,
16994
16239
  forceRefresh = false,
16995
16240
  getToken,
16996
- apiKey
16241
+ apiKey,
16242
+ cache = localStorageToolsCache
16997
16243
  } = options;
16998
- const cached = getCachedServerTools();
16244
+ const persistCache = async (entry) => {
16245
+ try {
16246
+ await cache.set(entry);
16247
+ } catch (error) {
16248
+ getLogger().warn("[serverTools] Cache write failed (non-fatal):", error);
16249
+ }
16250
+ };
16251
+ let rawCached = null;
16252
+ try {
16253
+ rawCached = await cache.get();
16254
+ } catch (error) {
16255
+ getLogger().warn("[serverTools] Cache read failed; falling through to server fetch:", error);
16256
+ }
16257
+ const cached = rawCached && rawCached.version === CACHE_VERSION ? rawCached : null;
16999
16258
  const cacheValid = !isCacheExpired(cached, cacheExpirationMs);
17000
16259
  if (cached && cacheValid && !forceRefresh) {
17001
16260
  return cached.tools;
@@ -17016,7 +16275,7 @@ async function getServerTools(options) {
17016
16275
  }
17017
16276
  const data = await response.json();
17018
16277
  const { tools: tools2, checksum: checksum2 } = convertServerToolsResponse(data);
17019
- cacheServerTools(tools2, checksum2);
16278
+ await persistCache(buildCacheEntry(tools2, checksum2));
17020
16279
  return tools2;
17021
16280
  }
17022
16281
  if (!getToken) {
@@ -17029,7 +16288,7 @@ async function getServerTools(options) {
17029
16288
  return cached?.tools ?? [];
17030
16289
  }
17031
16290
  const { tools, checksum } = await fetchServerToolsFromApi(effectiveBaseUrl, token);
17032
- cacheServerTools(tools, checksum);
16291
+ await persistCache(buildCacheEntry(tools, checksum));
17033
16292
  return tools;
17034
16293
  } catch (error) {
17035
16294
  getLogger().error("[serverTools] Failed to fetch server tools:", error);
@@ -17534,13 +16793,14 @@ async function selectServerToolsForPrompt(options) {
17534
16793
  baseUrl,
17535
16794
  embeddingModel,
17536
16795
  cacheExpirationMs,
16796
+ cache,
17537
16797
  deferLoading
17538
16798
  } = options;
17539
16799
  if (serverToolsFilter === void 0) return [];
17540
16800
  if (Array.isArray(serverToolsFilter) && serverToolsFilter.length === 0) return [];
17541
16801
  let allServerTools;
17542
16802
  try {
17543
- allServerTools = await getServerTools({ baseUrl, cacheExpirationMs, getToken });
16803
+ allServerTools = await getServerTools({ baseUrl, cacheExpirationMs, getToken, cache });
17544
16804
  } catch {
17545
16805
  return [];
17546
16806
  }
@@ -17564,6 +16824,123 @@ async function selectServerToolsForPrompt(options) {
17564
16824
  return filterServerTools(allServerTools, serverToolsFilter);
17565
16825
  }
17566
16826
 
16827
+ // src/lib/tools/clientToolSelection.ts
16828
+ function getToolName2(t) {
16829
+ const fn = t.function;
16830
+ return fn?.name || t.name || "";
16831
+ }
16832
+ function getToolDescription(t) {
16833
+ const fn = t.function;
16834
+ return fn?.description || t.description || getToolName2(t);
16835
+ }
16836
+ function computeToolGuidance(selectedServerTools, selectedClientTools, extraToolSets, activatedSetNames) {
16837
+ const names = [
16838
+ ...selectedServerTools.map((t) => t.name),
16839
+ ...(selectedClientTools ?? []).map(getToolName2)
16840
+ ].filter(Boolean);
16841
+ const toolSets = extraToolSets.length > 0 ? [...BUILT_IN_TOOL_SETS, ...extraToolSets] : BUILT_IN_TOOL_SETS;
16842
+ const prompts = toolSetSystemPrompts(names, toolSets, activatedSetNames);
16843
+ return prompts.length > 0 ? prompts.join("\n\n") : void 0;
16844
+ }
16845
+ async function autoFilterClientTools(clientTools, promptEmbeddings, cache, embeddingOptions, extraToolSets = [], activeToolSets = [], noEmbeddingsReason = "short-prompt") {
16846
+ const isMemoryTool = (t) => {
16847
+ const name = getToolName2(t);
16848
+ return name.startsWith("memory_vault_") || name === RECALL_TOOL_NAME;
16849
+ };
16850
+ const alwaysInclude = clientTools.filter(isMemoryTool);
16851
+ const filterCandidates = clientTools.filter((t) => !isMemoryTool(t));
16852
+ if (filterCandidates.length === 0) {
16853
+ return { tools: clientTools, activatedSetNames: /* @__PURE__ */ new Set() };
16854
+ }
16855
+ if (!promptEmbeddings && noEmbeddingsReason === "error") {
16856
+ return { tools: clientTools, activatedSetNames: /* @__PURE__ */ new Set() };
16857
+ }
16858
+ if (!promptEmbeddings) {
16859
+ if (activeToolSets.length === 0) {
16860
+ return { tools: [], activatedSetNames: /* @__PURE__ */ new Set() };
16861
+ }
16862
+ const allSets = extraToolSets.length > 0 ? [...BUILT_IN_TOOL_SETS, ...extraToolSets] : BUILT_IN_TOOL_SETS;
16863
+ const activeSets = allSets.filter((s) => activeToolSets.includes(s.name));
16864
+ const stickyMembers = new Set(activeSets.flatMap((s) => s.members));
16865
+ return {
16866
+ tools: [
16867
+ ...alwaysInclude,
16868
+ ...filterCandidates.filter((t) => stickyMembers.has(getToolName2(t)))
16869
+ ],
16870
+ activatedSetNames: new Set(activeSets.map((s) => s.name))
16871
+ };
16872
+ }
16873
+ const toolsNeedingEmbeddings = [];
16874
+ for (const t of filterCandidates) {
16875
+ const name = getToolName2(t);
16876
+ if (name && !cache.has(name)) {
16877
+ toolsNeedingEmbeddings.push({ name, description: getToolDescription(t) });
16878
+ }
16879
+ }
16880
+ if (toolsNeedingEmbeddings.length > 0) {
16881
+ try {
16882
+ const descriptions = toolsNeedingEmbeddings.map((t) => t.description);
16883
+ const embeddings = await generateEmbeddings(descriptions, embeddingOptions);
16884
+ for (let i = 0; i < toolsNeedingEmbeddings.length; i++) {
16885
+ cache.set(toolsNeedingEmbeddings[i].name, embeddings[i]);
16886
+ }
16887
+ } catch {
16888
+ return { tools: clientTools, activatedSetNames: /* @__PURE__ */ new Set() };
16889
+ }
16890
+ }
16891
+ const pseudoServerTools = [];
16892
+ for (const t of filterCandidates) {
16893
+ const name = getToolName2(t);
16894
+ const embedding = cache.get(name);
16895
+ if (!embedding) continue;
16896
+ const fn = t.function;
16897
+ const params = fn?.parameters || fn?.arguments || {
16898
+ type: "object",
16899
+ properties: {},
16900
+ required: []
16901
+ };
16902
+ pseudoServerTools.push({
16903
+ type: "function",
16904
+ name,
16905
+ description: getToolDescription(t),
16906
+ parameters: params,
16907
+ embedding
16908
+ });
16909
+ }
16910
+ const matches = findMatchingTools(promptEmbeddings, pseudoServerTools, {
16911
+ limit: MAX_CLIENT_TOOLS_AFTER_FILTER,
16912
+ minSimilarity: CLIENT_TOOLS_MIN_SIMILARITY,
16913
+ filterAmbiguous: true,
16914
+ // See CLIENT_TOOLS_RELEVANCE_RATIO: 0.75 admits the second intent of a
16915
+ // multi-intent prompt (which lands ~75-80% of the dominant match), while
16916
+ // still trimming the loose tail. The earlier 0.9 made a second intent
16917
+ // structurally unselectable; the anchorMinSimilarity gates (0.53-0.55)
16918
+ // remain the guard against borderline anchors activating a whole set.
16919
+ relevanceRatio: CLIENT_TOOLS_RELEVANCE_RATIO
16920
+ });
16921
+ const matchedNames = new Set(matches.map((m) => m.tool.name));
16922
+ const scores = scoreTools(promptEmbeddings, pseudoServerTools);
16923
+ const availableNames = new Set(filterCandidates.map(getToolName2));
16924
+ const toolSets = extraToolSets.length > 0 ? [...BUILT_IN_TOOL_SETS, ...extraToolSets] : BUILT_IN_TOOL_SETS;
16925
+ const activeSetNames = activeToolSets.length > 0 ? new Set(activeToolSets) : void 0;
16926
+ const finalNames = expandToolSetsAdditive(
16927
+ matchedNames,
16928
+ availableNames,
16929
+ scores,
16930
+ toolSets,
16931
+ activeSetNames
16932
+ );
16933
+ const activatedSetNames = activatedToolSetNames(scores, toolSets, activeSetNames);
16934
+ if (finalNames.size === 0) {
16935
+ return { tools: alwaysInclude, activatedSetNames };
16936
+ }
16937
+ const filtered = filterCandidates.filter((t) => {
16938
+ const name = getToolName2(t);
16939
+ return name && finalNames.has(name);
16940
+ });
16941
+ return { tools: [...alwaysInclude, ...filtered], activatedSetNames };
16942
+ }
16943
+
17567
16944
  // src/react/useChatMedia.ts
17568
16945
  var import_react4 = require("react");
17569
16946
  init_logger();
@@ -17817,121 +17194,6 @@ function useChatMedia(options) {
17817
17194
  // src/react/useChatStorage.ts
17818
17195
  init_useEncryption();
17819
17196
  init_useEncryption();
17820
- function getToolName2(t) {
17821
- const fn = t.function;
17822
- return fn?.name || t.name || "";
17823
- }
17824
- function getToolDescription(t) {
17825
- const fn = t.function;
17826
- return fn?.description || t.description || getToolName2(t);
17827
- }
17828
- function computeToolGuidance(selectedServerTools, selectedClientTools, extraToolSets, activatedSetNames) {
17829
- const names = [
17830
- ...selectedServerTools.map((t) => t.name),
17831
- ...(selectedClientTools ?? []).map(getToolName2)
17832
- ].filter(Boolean);
17833
- const toolSets = extraToolSets.length > 0 ? [...BUILT_IN_TOOL_SETS, ...extraToolSets] : BUILT_IN_TOOL_SETS;
17834
- const prompts = toolSetSystemPrompts(names, toolSets, activatedSetNames);
17835
- return prompts.length > 0 ? prompts.join("\n\n") : void 0;
17836
- }
17837
- async function autoFilterClientTools(clientTools, promptEmbeddings, cache, embeddingOptions, extraToolSets = [], activeToolSets = [], noEmbeddingsReason = "short-prompt") {
17838
- const isMemoryTool = (t) => {
17839
- const name = getToolName2(t);
17840
- return name.startsWith("memory_vault_") || name === RECALL_TOOL_NAME;
17841
- };
17842
- const alwaysInclude = clientTools.filter(isMemoryTool);
17843
- const filterCandidates = clientTools.filter((t) => !isMemoryTool(t));
17844
- if (filterCandidates.length === 0) {
17845
- return { tools: clientTools, activatedSetNames: /* @__PURE__ */ new Set() };
17846
- }
17847
- if (!promptEmbeddings && noEmbeddingsReason === "error") {
17848
- return { tools: clientTools, activatedSetNames: /* @__PURE__ */ new Set() };
17849
- }
17850
- if (!promptEmbeddings) {
17851
- if (activeToolSets.length === 0) {
17852
- return { tools: [], activatedSetNames: /* @__PURE__ */ new Set() };
17853
- }
17854
- const allSets = extraToolSets.length > 0 ? [...BUILT_IN_TOOL_SETS, ...extraToolSets] : BUILT_IN_TOOL_SETS;
17855
- const activeSets = allSets.filter((s) => activeToolSets.includes(s.name));
17856
- const stickyMembers = new Set(activeSets.flatMap((s) => s.members));
17857
- return {
17858
- tools: [
17859
- ...alwaysInclude,
17860
- ...filterCandidates.filter((t) => stickyMembers.has(getToolName2(t)))
17861
- ],
17862
- activatedSetNames: new Set(activeSets.map((s) => s.name))
17863
- };
17864
- }
17865
- const toolsNeedingEmbeddings = [];
17866
- for (const t of filterCandidates) {
17867
- const name = getToolName2(t);
17868
- if (name && !cache.has(name)) {
17869
- toolsNeedingEmbeddings.push({ name, description: getToolDescription(t) });
17870
- }
17871
- }
17872
- if (toolsNeedingEmbeddings.length > 0) {
17873
- try {
17874
- const descriptions = toolsNeedingEmbeddings.map((t) => t.description);
17875
- const embeddings = await generateEmbeddings(descriptions, embeddingOptions);
17876
- for (let i = 0; i < toolsNeedingEmbeddings.length; i++) {
17877
- cache.set(toolsNeedingEmbeddings[i].name, embeddings[i]);
17878
- }
17879
- } catch {
17880
- return { tools: clientTools, activatedSetNames: /* @__PURE__ */ new Set() };
17881
- }
17882
- }
17883
- const pseudoServerTools = [];
17884
- for (const t of filterCandidates) {
17885
- const name = getToolName2(t);
17886
- const embedding = cache.get(name);
17887
- if (!embedding) continue;
17888
- const fn = t.function;
17889
- const params = fn?.parameters || fn?.arguments || {
17890
- type: "object",
17891
- properties: {},
17892
- required: []
17893
- };
17894
- pseudoServerTools.push({
17895
- type: "function",
17896
- name,
17897
- description: getToolDescription(t),
17898
- parameters: params,
17899
- embedding
17900
- });
17901
- }
17902
- const matches = findMatchingTools(promptEmbeddings, pseudoServerTools, {
17903
- limit: MAX_CLIENT_TOOLS_AFTER_FILTER,
17904
- minSimilarity: CLIENT_TOOLS_MIN_SIMILARITY,
17905
- filterAmbiguous: true,
17906
- // See CLIENT_TOOLS_RELEVANCE_RATIO: 0.75 admits the second intent of a
17907
- // multi-intent prompt (which lands ~75-80% of the dominant match), while
17908
- // still trimming the loose tail. The earlier 0.9 made a second intent
17909
- // structurally unselectable; the anchorMinSimilarity gates (0.53-0.55)
17910
- // remain the guard against borderline anchors activating a whole set.
17911
- relevanceRatio: CLIENT_TOOLS_RELEVANCE_RATIO
17912
- });
17913
- const matchedNames = new Set(matches.map((m) => m.tool.name));
17914
- const scores = scoreTools(promptEmbeddings, pseudoServerTools);
17915
- const availableNames = new Set(filterCandidates.map(getToolName2));
17916
- const toolSets = extraToolSets.length > 0 ? [...BUILT_IN_TOOL_SETS, ...extraToolSets] : BUILT_IN_TOOL_SETS;
17917
- const activeSetNames = activeToolSets.length > 0 ? new Set(activeToolSets) : void 0;
17918
- const finalNames = expandToolSetsAdditive(
17919
- matchedNames,
17920
- availableNames,
17921
- scores,
17922
- toolSets,
17923
- activeSetNames
17924
- );
17925
- const activatedSetNames = activatedToolSetNames(scores, toolSets, activeSetNames);
17926
- if (finalNames.size === 0) {
17927
- return { tools: alwaysInclude, activatedSetNames };
17928
- }
17929
- const filtered = filterCandidates.filter((t) => {
17930
- const name = getToolName2(t);
17931
- return name && finalNames.has(name);
17932
- });
17933
- return { tools: [...alwaysInclude, ...filtered], activatedSetNames };
17934
- }
17935
17197
  async function previewToolSelection(options) {
17936
17198
  const {
17937
17199
  prompt,
@@ -17970,7 +17232,8 @@ async function previewToolSelection(options) {
17970
17232
  baseUrl,
17971
17233
  cacheExpirationMs: serverToolsConfig?.cacheExpirationMs,
17972
17234
  getToken,
17973
- apiKey
17235
+ apiKey,
17236
+ cache: serverToolsConfig?.cache
17974
17237
  });
17975
17238
  const allow = new Set(serverToolsFilter);
17976
17239
  gatedServerNames = allServerTools.filter((t) => allow.has(t.name)).map((t) => t.name);
@@ -18018,7 +17281,8 @@ async function previewToolSelection(options) {
18018
17281
  baseUrl,
18019
17282
  cacheExpirationMs: serverToolsConfig?.cacheExpirationMs,
18020
17283
  getToken,
18021
- apiKey
17284
+ apiKey,
17285
+ cache: serverToolsConfig?.cache
18022
17286
  });
18023
17287
  if (serverToolsConfig?.deferLoading?.enabled) {
18024
17288
  serverToolNames = allServerTools.map((t) => t.name);
@@ -19011,7 +18275,8 @@ function useChatStorage(options) {
19011
18275
  const allServerTools = await getServerTools({
19012
18276
  baseUrl,
19013
18277
  cacheExpirationMs: serverToolsConfig?.cacheExpirationMs,
19014
- getToken
18278
+ getToken,
18279
+ cache: serverToolsConfig?.cache
19015
18280
  });
19016
18281
  if (serverToolsConfig?.deferLoading?.enabled) {
19017
18282
  filteredServerTools2 = allServerTools;
@@ -19029,12 +18294,14 @@ function useChatStorage(options) {
19029
18294
  let filteredClientTools2 = clientTools;
19030
18295
  let clientActivatedSetNames2;
19031
18296
  if (clientToolsFilter && clientTools?.length) {
19032
- const clientToolNames = clientToolsFilter(skipStorageEmbeddings, clientTools);
19033
- filteredClientTools2 = clientTools.filter((t) => {
19034
- const fn = t.function;
19035
- const name = fn?.name || t.name;
19036
- return clientToolNames.includes(name);
19037
- });
18297
+ if (!skipStorageEmbeddingsFailed) {
18298
+ const clientToolNames = clientToolsFilter(skipStorageEmbeddings, clientTools);
18299
+ filteredClientTools2 = clientTools.filter((t) => {
18300
+ const fn = t.function;
18301
+ const name = fn?.name || t.name;
18302
+ return clientToolNames.includes(name);
18303
+ });
18304
+ }
19038
18305
  } else if (clientTools?.length && getToken) {
19039
18306
  const clientFilterResult = await autoFilterClientTools(
19040
18307
  clientTools,
@@ -19101,8 +18368,20 @@ function useChatStorage(options) {
19101
18368
  error: result2.error || "Unknown error"
19102
18369
  };
19103
18370
  }
19104
- if (getToken && shouldRefreshTools(getToolsChecksum(result2.data))) {
19105
- getServerTools({ baseUrl, getToken, forceRefresh: true }).catch((err) => {
18371
+ const refreshResponse = result2.data;
18372
+ if (getToken) {
18373
+ Promise.resolve().then(
18374
+ () => shouldRefreshTools(getToolsChecksum(refreshResponse), serverToolsConfig?.cache)
18375
+ ).then((refresh) => {
18376
+ if (refresh) {
18377
+ return getServerTools({
18378
+ baseUrl,
18379
+ getToken,
18380
+ forceRefresh: true,
18381
+ cache: serverToolsConfig?.cache
18382
+ });
18383
+ }
18384
+ }).catch((err) => {
19106
18385
  getLogger().warn("[useChatStorage] Failed to refresh server tools cache:", err);
19107
18386
  });
19108
18387
  }
@@ -19369,7 +18648,8 @@ function useChatStorage(options) {
19369
18648
  const allServerTools = await getServerTools({
19370
18649
  baseUrl,
19371
18650
  cacheExpirationMs: serverToolsConfig?.cacheExpirationMs,
19372
- getToken
18651
+ getToken,
18652
+ cache: serverToolsConfig?.cache
19373
18653
  });
19374
18654
  if (serverToolsConfig?.deferLoading?.enabled && effectiveApiType === "responses") {
19375
18655
  filteredServerTools = allServerTools;
@@ -19387,12 +18667,14 @@ function useChatStorage(options) {
19387
18667
  let filteredClientTools = clientTools;
19388
18668
  let clientActivatedSetNames;
19389
18669
  if (clientToolsFilter && clientTools?.length) {
19390
- const clientToolNames = clientToolsFilter(userMessageEmbeddings ?? null, clientTools);
19391
- filteredClientTools = clientTools.filter((t) => {
19392
- const fn = t.function;
19393
- const name = fn?.name || t.name;
19394
- return clientToolNames.includes(name);
19395
- });
18670
+ if (!userMessageEmbeddingsFailed) {
18671
+ const clientToolNames = clientToolsFilter(userMessageEmbeddings ?? null, clientTools);
18672
+ filteredClientTools = clientTools.filter((t) => {
18673
+ const fn = t.function;
18674
+ const name = fn?.name || t.name;
18675
+ return clientToolNames.includes(name);
18676
+ });
18677
+ }
19396
18678
  } else if (clientTools?.length && getToken) {
19397
18679
  const clientFilterResult = await autoFilterClientTools(
19398
18680
  clientTools,
@@ -19712,8 +18994,17 @@ Based on these results, continue with the task.`;
19712
18994
  } catch {
19713
18995
  }
19714
18996
  }
19715
- if (getToken && shouldRefreshTools(getToolsChecksum(responseData))) {
19716
- getServerTools({ baseUrl, getToken, forceRefresh: true }).catch((err) => {
18997
+ if (getToken) {
18998
+ Promise.resolve().then(() => shouldRefreshTools(getToolsChecksum(responseData), serverToolsConfig?.cache)).then((refresh) => {
18999
+ if (refresh) {
19000
+ return getServerTools({
19001
+ baseUrl,
19002
+ getToken,
19003
+ forceRefresh: true,
19004
+ cache: serverToolsConfig?.cache
19005
+ });
19006
+ }
19007
+ }).catch((err) => {
19717
19008
  getLogger().warn("[useChatStorage] Failed to refresh server tools cache:", err);
19718
19009
  });
19719
19010
  }
@@ -23282,452 +22573,1270 @@ function useExportPdf() {
23282
22573
  const canvas = await renderElementToCanvas(element, { onProgress: setProgress });
23283
22574
  return canvas;
23284
22575
  } catch (err) {
23285
- const processed = toError(err);
23286
- setError(processed);
23287
- throw processed;
22576
+ const processed = toError(err);
22577
+ setError(processed);
22578
+ throw processed;
22579
+ } finally {
22580
+ setIsExporting(false);
22581
+ }
22582
+ },
22583
+ []
22584
+ );
22585
+ return {
22586
+ exportElementToPdf: wrappedExportElement,
22587
+ exportMarkdownToPdf: wrappedExportMarkdown,
22588
+ downloadElementAsPdf,
22589
+ downloadMarkdownAsPdf,
22590
+ renderElementToCanvas: wrappedRenderToCanvas,
22591
+ isExporting,
22592
+ progress,
22593
+ error
22594
+ };
22595
+ }
22596
+
22597
+ // src/react/useOCR.ts
22598
+ var import_react11 = require("react");
22599
+ var import_tesseract = __toESM(require("tesseract.js"));
22600
+ init_logger();
22601
+ function useOCR() {
22602
+ const [isProcessing, setIsProcessing] = (0, import_react11.useState)(false);
22603
+ const [error, setError] = (0, import_react11.useState)(null);
22604
+ const extractOCRContext = (0, import_react11.useCallback)(async (files) => {
22605
+ setIsProcessing(true);
22606
+ setError(null);
22607
+ try {
22608
+ if (files.length === 0) {
22609
+ return null;
22610
+ }
22611
+ const contexts = await Promise.all(
22612
+ files.map(async (file) => {
22613
+ try {
22614
+ let imagesToProcess = [];
22615
+ const language = file.language || "eng";
22616
+ const filename = file.filename || (file.url instanceof File ? file.url.name : "");
22617
+ let isPdf = false;
22618
+ if (typeof file.url === "string") {
22619
+ isPdf = file.url.toLowerCase().endsWith(".pdf") || (filename?.toLowerCase().endsWith(".pdf") ?? false);
22620
+ } else if (file.url instanceof Blob) {
22621
+ isPdf = file.url.type === "application/pdf" || (filename?.toLowerCase().endsWith(".pdf") ?? false);
22622
+ }
22623
+ if (isPdf) {
22624
+ let pdfUrl;
22625
+ let shouldRevoke = false;
22626
+ if (typeof file.url === "string") {
22627
+ pdfUrl = file.url;
22628
+ } else {
22629
+ pdfUrl = URL.createObjectURL(file.url);
22630
+ shouldRevoke = true;
22631
+ }
22632
+ try {
22633
+ const pdfImages = await convertPdfToImages(pdfUrl);
22634
+ imagesToProcess = pdfImages;
22635
+ } catch (e) {
22636
+ getLogger().error("Failed to convert PDF to images", e);
22637
+ throw e;
22638
+ } finally {
22639
+ if (shouldRevoke) {
22640
+ URL.revokeObjectURL(pdfUrl);
22641
+ }
22642
+ }
22643
+ } else {
22644
+ imagesToProcess = [file.url];
22645
+ }
22646
+ const pageTexts = [];
22647
+ for (const image of imagesToProcess) {
22648
+ const result = await import_tesseract.default.recognize(image, language);
22649
+ pageTexts.push(result.data.text);
22650
+ }
22651
+ const text12 = pageTexts.join("\n\n");
22652
+ if (!text12.trim()) {
22653
+ getLogger().warn(`No text found in OCR source ${filename || "unknown"}`);
22654
+ return null;
22655
+ }
22656
+ return `[Context from OCR attachment ${filename || "unknown"}]:
22657
+ ${text12}`;
22658
+ } catch (err) {
22659
+ getLogger().error(`Failed to process OCR for ${file.filename || "unknown"}:`, err);
22660
+ return null;
22661
+ }
22662
+ })
22663
+ );
22664
+ const mergedContext = contexts.filter(Boolean).join("\n\n");
22665
+ return mergedContext || null;
22666
+ } catch (err) {
22667
+ const processedError = err instanceof Error ? err : new Error(String(err));
22668
+ setError(processedError);
22669
+ throw processedError;
22670
+ } finally {
22671
+ setIsProcessing(false);
22672
+ }
22673
+ }, []);
22674
+ return {
22675
+ extractOCRContext,
22676
+ isProcessing,
22677
+ error
22678
+ };
22679
+ }
22680
+
22681
+ // src/react/usePdf.ts
22682
+ var import_react12 = require("react");
22683
+ init_logger();
22684
+ var PDF_MIME_TYPE = "application/pdf";
22685
+ function usePdf() {
22686
+ const [isProcessing, setIsProcessing] = (0, import_react12.useState)(false);
22687
+ const [error, setError] = (0, import_react12.useState)(null);
22688
+ const extractPdfContext = (0, import_react12.useCallback)(async (files) => {
22689
+ setIsProcessing(true);
22690
+ setError(null);
22691
+ try {
22692
+ const pdfFiles = files.filter(
22693
+ (file) => file.mediaType === PDF_MIME_TYPE || file.filename?.toLowerCase().endsWith(".pdf")
22694
+ );
22695
+ if (pdfFiles.length === 0) {
22696
+ return null;
22697
+ }
22698
+ const contexts = await Promise.all(
22699
+ pdfFiles.map(async (file) => {
22700
+ try {
22701
+ const text12 = await extractTextFromPdf(file.url);
22702
+ if (!text12.trim()) {
22703
+ getLogger().warn(`No text found in PDF ${file.filename}`);
22704
+ return null;
22705
+ }
22706
+ return `[Context from PDF attachment ${file.filename}]:
22707
+ ${text12}`;
22708
+ } catch (err) {
22709
+ getLogger().error(`Failed to process PDF ${file.filename}:`, err);
22710
+ return null;
22711
+ }
22712
+ })
22713
+ );
22714
+ const mergedContext = contexts.filter(Boolean).join("\n\n");
22715
+ return mergedContext || null;
22716
+ } catch (err) {
22717
+ const processedError = err instanceof Error ? err : new Error(String(err));
22718
+ setError(processedError);
22719
+ throw processedError;
22720
+ } finally {
22721
+ setIsProcessing(false);
22722
+ }
22723
+ }, []);
22724
+ return {
22725
+ extractPdfContext,
22726
+ isProcessing,
22727
+ error
22728
+ };
22729
+ }
22730
+
22731
+ // src/react/useVoice.ts
22732
+ var import_react13 = require("react");
22733
+ function getOnDeviceSpeechRecognition() {
22734
+ if (typeof window === "undefined") return null;
22735
+ if (!/iPhone|iPad|iPod/.test(navigator.userAgent)) return null;
22736
+ const SR = window.SpeechRecognition ?? window.webkitSpeechRecognition;
22737
+ return SR ?? null;
22738
+ }
22739
+ var SUPPORTED_MIME_TYPES = [
22740
+ "audio/webm;codecs=opus",
22741
+ "audio/webm",
22742
+ "audio/mp4",
22743
+ "audio/ogg;codecs=opus",
22744
+ "audio/ogg"
22745
+ ];
22746
+ function getSupportedMimeType() {
22747
+ if (typeof MediaRecorder === "undefined") {
22748
+ return "audio/webm";
22749
+ }
22750
+ for (const type of SUPPORTED_MIME_TYPES) {
22751
+ if (MediaRecorder.isTypeSupported(type)) {
22752
+ return type;
22753
+ }
22754
+ }
22755
+ return "audio/webm";
22756
+ }
22757
+ var SAMPLE_RATE = 16e3;
22758
+ async function audioToFloat32(blob) {
22759
+ const arrayBuffer = await blob.arrayBuffer();
22760
+ const audioContext = new AudioContext({ sampleRate: SAMPLE_RATE });
22761
+ try {
22762
+ const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
22763
+ if (audioBuffer.numberOfChannels === 1) {
22764
+ return audioBuffer.getChannelData(0);
22765
+ }
22766
+ const length = audioBuffer.length;
22767
+ const mono = new Float32Array(length);
22768
+ const channels = audioBuffer.numberOfChannels;
22769
+ for (let ch = 0; ch < channels; ch++) {
22770
+ const data = audioBuffer.getChannelData(ch);
22771
+ for (let i = 0; i < length; i++) {
22772
+ mono[i] += data[i];
22773
+ }
22774
+ }
22775
+ for (let i = 0; i < length; i++) {
22776
+ mono[i] /= channels;
22777
+ }
22778
+ return mono;
22779
+ } finally {
22780
+ await audioContext.close();
22781
+ }
22782
+ }
22783
+ function useVoice(options) {
22784
+ const [isRecording, setIsRecording] = (0, import_react13.useState)(false);
22785
+ const [isTranscribing, setIsTranscribing] = (0, import_react13.useState)(false);
22786
+ const [isModelLoaded, setIsModelLoaded] = (0, import_react13.useState)(false);
22787
+ const [isLoadingModel, setIsLoadingModel] = (0, import_react13.useState)(false);
22788
+ const [recording, setRecording] = (0, import_react13.useState)(null);
22789
+ const [transcription, setTranscription] = (0, import_react13.useState)(null);
22790
+ const [error, setError] = (0, import_react13.useState)(null);
22791
+ const mediaRecorderRef = (0, import_react13.useRef)(null);
22792
+ const mediaStreamRef = (0, import_react13.useRef)(null);
22793
+ const chunksRef = (0, import_react13.useRef)([]);
22794
+ const startTimeRef = (0, import_react13.useRef)(0);
22795
+ const pipelineRef = (0, import_react13.useRef)(null);
22796
+ const modelNameRef = (0, import_react13.useRef)(null);
22797
+ const getModelName = (0, import_react13.useCallback)(() => {
22798
+ const model = options?.model ?? "whisper-tiny";
22799
+ return `onnx-community/${model}`;
22800
+ }, [options?.model]);
22801
+ const loadPipeline = (0, import_react13.useCallback)(async () => {
22802
+ const modelName = getModelName();
22803
+ if (pipelineRef.current && modelNameRef.current === modelName) {
22804
+ return pipelineRef.current;
22805
+ }
22806
+ setIsLoadingModel(true);
22807
+ setError(null);
22808
+ try {
22809
+ const { pipeline } = await import("@huggingface/transformers");
22810
+ const transcriber = await pipeline("automatic-speech-recognition", modelName, {
22811
+ dtype: "q4",
22812
+ device: "wasm",
22813
+ progress_callback: options?.onModelProgress ? (progress) => {
22814
+ if (progress.file && progress.progress !== null && progress.progress !== void 0) {
22815
+ options.onModelProgress({
22816
+ file: progress.file,
22817
+ progress: progress.progress / 100,
22818
+ loaded: progress.loaded ?? 0,
22819
+ total: progress.total ?? 0
22820
+ });
22821
+ }
22822
+ } : void 0
22823
+ });
22824
+ pipelineRef.current = transcriber;
22825
+ modelNameRef.current = modelName;
22826
+ setIsModelLoaded(true);
22827
+ return pipelineRef.current;
22828
+ } catch (err) {
22829
+ const processedError = err instanceof Error ? err : new Error("Failed to load Whisper model");
22830
+ setError(processedError);
22831
+ throw processedError;
22832
+ } finally {
22833
+ setIsLoadingModel(false);
22834
+ }
22835
+ }, [getModelName, options?.onModelProgress]);
22836
+ const preloadModel = (0, import_react13.useCallback)(async () => {
22837
+ await loadPipeline();
22838
+ }, [loadPipeline]);
22839
+ const disposeModel = (0, import_react13.useCallback)(async () => {
22840
+ const pipe = pipelineRef.current;
22841
+ if (pipe?.dispose) {
22842
+ await pipe.dispose();
22843
+ }
22844
+ pipelineRef.current = null;
22845
+ modelNameRef.current = null;
22846
+ setIsModelLoaded(false);
22847
+ }, []);
22848
+ const startRecording = (0, import_react13.useCallback)(async () => {
22849
+ setError(null);
22850
+ setRecording(null);
22851
+ setTranscription(null);
22852
+ try {
22853
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
22854
+ mediaStreamRef.current = stream;
22855
+ const mimeType = getSupportedMimeType();
22856
+ const recorder = new MediaRecorder(stream, { mimeType });
22857
+ mediaRecorderRef.current = recorder;
22858
+ chunksRef.current = [];
22859
+ recorder.ondataavailable = (e) => {
22860
+ if (e.data.size > 0) {
22861
+ chunksRef.current.push(e.data);
22862
+ }
22863
+ };
22864
+ recorder.start();
22865
+ startTimeRef.current = Date.now();
22866
+ setIsRecording(true);
22867
+ } catch (err) {
22868
+ const processedError = err instanceof Error ? err : new Error("Failed to start recording");
22869
+ setError(processedError);
22870
+ throw processedError;
22871
+ }
22872
+ }, []);
22873
+ const stopRecording = (0, import_react13.useCallback)(async () => {
22874
+ return new Promise((resolve, reject) => {
22875
+ const recorder = mediaRecorderRef.current;
22876
+ if (!recorder || recorder.state === "inactive") {
22877
+ const err = new Error("No active recording");
22878
+ setError(err);
22879
+ reject(err);
22880
+ return;
22881
+ }
22882
+ recorder.onstop = () => {
22883
+ const mimeType = recorder.mimeType || "audio/webm";
22884
+ const blob = new Blob(chunksRef.current, { type: mimeType });
22885
+ const duration = Date.now() - startTimeRef.current;
22886
+ mediaStreamRef.current?.getTracks().forEach((t) => t.stop());
22887
+ mediaStreamRef.current = null;
22888
+ mediaRecorderRef.current = null;
22889
+ const result = { blob, duration, mimeType };
22890
+ setRecording(result);
22891
+ setIsRecording(false);
22892
+ resolve(result);
22893
+ };
22894
+ recorder.onerror = () => {
22895
+ const err = new Error("Recording failed");
22896
+ setError(err);
22897
+ setIsRecording(false);
22898
+ reject(err);
22899
+ };
22900
+ recorder.stop();
22901
+ });
22902
+ }, []);
22903
+ const transcribe = (0, import_react13.useCallback)(
22904
+ async (rec) => {
22905
+ const target = rec ?? recording;
22906
+ if (!target) {
22907
+ const err = new Error("No recording to transcribe");
22908
+ setError(err);
22909
+ throw err;
22910
+ }
22911
+ setIsTranscribing(true);
22912
+ setError(null);
22913
+ try {
22914
+ const pipe = await loadPipeline();
22915
+ const audio = await audioToFloat32(target.blob);
22916
+ const result = await pipe(audio, {
22917
+ language: options?.language,
22918
+ return_timestamps: true
22919
+ });
22920
+ const transcriptionResult = {
22921
+ text: result.text.trim(),
22922
+ chunks: result.chunks
22923
+ };
22924
+ setTranscription(transcriptionResult);
22925
+ return transcriptionResult;
22926
+ } catch (err) {
22927
+ const processedError = err instanceof Error ? err : new Error("Transcription failed");
22928
+ setError(processedError);
22929
+ throw processedError;
23288
22930
  } finally {
23289
- setIsExporting(false);
22931
+ setIsTranscribing(false);
23290
22932
  }
23291
22933
  },
23292
- []
22934
+ [recording, loadPipeline, options?.language]
23293
22935
  );
23294
- return {
23295
- exportElementToPdf: wrappedExportElement,
23296
- exportMarkdownToPdf: wrappedExportMarkdown,
23297
- downloadElementAsPdf,
23298
- downloadMarkdownAsPdf,
23299
- renderElementToCanvas: wrappedRenderToCanvas,
23300
- isExporting,
23301
- progress,
23302
- error
23303
- };
23304
- }
23305
-
23306
- // src/react/useOCR.ts
23307
- var import_react11 = require("react");
23308
- var import_tesseract = __toESM(require("tesseract.js"));
23309
- init_logger();
23310
- function useOCR() {
23311
- const [isProcessing, setIsProcessing] = (0, import_react11.useState)(false);
23312
- const [error, setError] = (0, import_react11.useState)(null);
23313
- const extractOCRContext = (0, import_react11.useCallback)(async (files) => {
23314
- setIsProcessing(true);
22936
+ const nativeSpeechAvailable = (0, import_react13.useMemo)(() => getOnDeviceSpeechRecognition() !== null, []);
22937
+ const [isNativeListening, setIsNativeListening] = (0, import_react13.useState)(false);
22938
+ const nativeRecognitionRef = (0, import_react13.useRef)(null);
22939
+ const nativeTextRef = (0, import_react13.useRef)("");
22940
+ const nativeResolveRef = (0, import_react13.useRef)(null);
22941
+ const startNativeTranscription = (0, import_react13.useCallback)(() => {
22942
+ const SR = getOnDeviceSpeechRecognition();
22943
+ if (!SR) return;
22944
+ nativeTextRef.current = "";
23315
22945
  setError(null);
23316
- try {
23317
- if (files.length === 0) {
23318
- return null;
22946
+ const recognition = new SR();
22947
+ recognition.continuous = true;
22948
+ recognition.interimResults = false;
22949
+ recognition.lang = options?.language ?? "";
22950
+ recognition.onresult = (event) => {
22951
+ let text12 = "";
22952
+ for (let i = 0; i < event.results.length; i++) {
22953
+ const result = event.results[i];
22954
+ if (result && result.isFinal && result[0]) {
22955
+ text12 += result[0].transcript + " ";
22956
+ }
23319
22957
  }
23320
- const contexts = await Promise.all(
23321
- files.map(async (file) => {
23322
- try {
23323
- let imagesToProcess = [];
23324
- const language = file.language || "eng";
23325
- const filename = file.filename || (file.url instanceof File ? file.url.name : "");
23326
- let isPdf = false;
23327
- if (typeof file.url === "string") {
23328
- isPdf = file.url.toLowerCase().endsWith(".pdf") || (filename?.toLowerCase().endsWith(".pdf") ?? false);
23329
- } else if (file.url instanceof Blob) {
23330
- isPdf = file.url.type === "application/pdf" || (filename?.toLowerCase().endsWith(".pdf") ?? false);
23331
- }
23332
- if (isPdf) {
23333
- let pdfUrl;
23334
- let shouldRevoke = false;
23335
- if (typeof file.url === "string") {
23336
- pdfUrl = file.url;
23337
- } else {
23338
- pdfUrl = URL.createObjectURL(file.url);
23339
- shouldRevoke = true;
23340
- }
23341
- try {
23342
- const pdfImages = await convertPdfToImages(pdfUrl);
23343
- imagesToProcess = pdfImages;
23344
- } catch (e) {
23345
- getLogger().error("Failed to convert PDF to images", e);
23346
- throw e;
23347
- } finally {
23348
- if (shouldRevoke) {
23349
- URL.revokeObjectURL(pdfUrl);
23350
- }
23351
- }
23352
- } else {
23353
- imagesToProcess = [file.url];
23354
- }
23355
- const pageTexts = [];
23356
- for (const image of imagesToProcess) {
23357
- const result = await import_tesseract.default.recognize(image, language);
23358
- pageTexts.push(result.data.text);
23359
- }
23360
- const text12 = pageTexts.join("\n\n");
23361
- if (!text12.trim()) {
23362
- getLogger().warn(`No text found in OCR source ${filename || "unknown"}`);
23363
- return null;
23364
- }
23365
- return `[Context from OCR attachment ${filename || "unknown"}]:
23366
- ${text12}`;
23367
- } catch (err) {
23368
- getLogger().error(`Failed to process OCR for ${file.filename || "unknown"}:`, err);
23369
- return null;
23370
- }
23371
- })
23372
- );
23373
- const mergedContext = contexts.filter(Boolean).join("\n\n");
23374
- return mergedContext || null;
23375
- } catch (err) {
23376
- const processedError = err instanceof Error ? err : new Error(String(err));
23377
- setError(processedError);
23378
- throw processedError;
23379
- } finally {
23380
- setIsProcessing(false);
22958
+ nativeTextRef.current = text12.trim();
22959
+ };
22960
+ recognition.onerror = (event) => {
22961
+ if (event.error !== "aborted" && event.error !== "no-speech") {
22962
+ setError(new Error(`Speech recognition error: ${event.error}`));
22963
+ }
22964
+ };
22965
+ recognition.onend = () => {
22966
+ setIsNativeListening(false);
22967
+ nativeRecognitionRef.current = null;
22968
+ const resolve = nativeResolveRef.current;
22969
+ if (resolve) {
22970
+ nativeResolveRef.current = null;
22971
+ resolve({ text: nativeTextRef.current });
22972
+ }
22973
+ };
22974
+ nativeRecognitionRef.current = recognition;
22975
+ recognition.start();
22976
+ setIsNativeListening(true);
22977
+ }, [options?.language]);
22978
+ const stopNativeTranscription = (0, import_react13.useCallback)(() => {
22979
+ return new Promise((resolve) => {
22980
+ const recognition = nativeRecognitionRef.current;
22981
+ if (!recognition) {
22982
+ resolve({ text: nativeTextRef.current || "" });
22983
+ return;
22984
+ }
22985
+ nativeResolveRef.current = resolve;
22986
+ recognition.stop();
22987
+ });
22988
+ }, []);
22989
+ const abortNativeTranscription = (0, import_react13.useCallback)(() => {
22990
+ const recognition = nativeRecognitionRef.current;
22991
+ if (recognition) {
22992
+ nativeResolveRef.current = null;
22993
+ recognition.abort();
22994
+ nativeRecognitionRef.current = null;
22995
+ setIsNativeListening(false);
23381
22996
  }
23382
22997
  }, []);
23383
22998
  return {
23384
- extractOCRContext,
23385
- isProcessing,
23386
- error
22999
+ isRecording,
23000
+ startRecording,
23001
+ stopRecording,
23002
+ isTranscribing,
23003
+ transcribe,
23004
+ preloadModel,
23005
+ disposeModel,
23006
+ isModelLoaded,
23007
+ isLoadingModel,
23008
+ recording,
23009
+ transcription,
23010
+ error,
23011
+ nativeSpeechAvailable,
23012
+ startNativeTranscription,
23013
+ stopNativeTranscription,
23014
+ abortNativeTranscription,
23015
+ isNativeListening
23387
23016
  };
23388
23017
  }
23389
23018
 
23390
- // src/react/usePdf.ts
23391
- var import_react12 = require("react");
23392
- init_logger();
23393
- var PDF_MIME_TYPE = "application/pdf";
23394
- function usePdf() {
23395
- const [isProcessing, setIsProcessing] = (0, import_react12.useState)(false);
23396
- const [error, setError] = (0, import_react12.useState)(null);
23397
- const extractPdfContext = (0, import_react12.useCallback)(async (files) => {
23398
- setIsProcessing(true);
23399
- setError(null);
23400
- try {
23401
- const pdfFiles = files.filter(
23402
- (file) => file.mediaType === PDF_MIME_TYPE || file.filename?.toLowerCase().endsWith(".pdf")
23403
- );
23404
- if (pdfFiles.length === 0) {
23405
- return null;
23019
+ // src/react/useCredits.ts
23020
+ var import_react14 = require("react");
23021
+
23022
+ // src/client/core/bodySerializer.gen.ts
23023
+ var jsonBodySerializer = {
23024
+ bodySerializer: (body) => JSON.stringify(
23025
+ body,
23026
+ (_key, value) => typeof value === "bigint" ? value.toString() : value
23027
+ )
23028
+ };
23029
+
23030
+ // src/client/core/pathSerializer.gen.ts
23031
+ var separatorArrayExplode = (style) => {
23032
+ switch (style) {
23033
+ case "label":
23034
+ return ".";
23035
+ case "matrix":
23036
+ return ";";
23037
+ case "simple":
23038
+ return ",";
23039
+ default:
23040
+ return "&";
23041
+ }
23042
+ };
23043
+ var separatorArrayNoExplode = (style) => {
23044
+ switch (style) {
23045
+ case "form":
23046
+ return ",";
23047
+ case "pipeDelimited":
23048
+ return "|";
23049
+ case "spaceDelimited":
23050
+ return "%20";
23051
+ default:
23052
+ return ",";
23053
+ }
23054
+ };
23055
+ var separatorObjectExplode = (style) => {
23056
+ switch (style) {
23057
+ case "label":
23058
+ return ".";
23059
+ case "matrix":
23060
+ return ";";
23061
+ case "simple":
23062
+ return ",";
23063
+ default:
23064
+ return "&";
23065
+ }
23066
+ };
23067
+ var serializeArrayParam = ({
23068
+ allowReserved,
23069
+ explode,
23070
+ name,
23071
+ style,
23072
+ value
23073
+ }) => {
23074
+ if (!explode) {
23075
+ const joinedValues2 = (allowReserved ? value : value.map((v) => encodeURIComponent(v))).join(separatorArrayNoExplode(style));
23076
+ switch (style) {
23077
+ case "label":
23078
+ return `.${joinedValues2}`;
23079
+ case "matrix":
23080
+ return `;${name}=${joinedValues2}`;
23081
+ case "simple":
23082
+ return joinedValues2;
23083
+ default:
23084
+ return `${name}=${joinedValues2}`;
23085
+ }
23086
+ }
23087
+ const separator = separatorArrayExplode(style);
23088
+ const joinedValues = value.map((v) => {
23089
+ if (style === "label" || style === "simple") {
23090
+ return allowReserved ? v : encodeURIComponent(v);
23091
+ }
23092
+ return serializePrimitiveParam({
23093
+ allowReserved,
23094
+ name,
23095
+ value: v
23096
+ });
23097
+ }).join(separator);
23098
+ return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
23099
+ };
23100
+ var serializePrimitiveParam = ({
23101
+ allowReserved,
23102
+ name,
23103
+ value
23104
+ }) => {
23105
+ if (value === void 0 || value === null) {
23106
+ return "";
23107
+ }
23108
+ if (typeof value === "object") {
23109
+ throw new Error(
23110
+ "Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these."
23111
+ );
23112
+ }
23113
+ return `${name}=${allowReserved ? value : encodeURIComponent(value)}`;
23114
+ };
23115
+ var serializeObjectParam = ({
23116
+ allowReserved,
23117
+ explode,
23118
+ name,
23119
+ style,
23120
+ value,
23121
+ valueOnly
23122
+ }) => {
23123
+ if (value instanceof Date) {
23124
+ return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`;
23125
+ }
23126
+ if (style !== "deepObject" && !explode) {
23127
+ let values = [];
23128
+ Object.entries(value).forEach(([key, v]) => {
23129
+ values = [
23130
+ ...values,
23131
+ key,
23132
+ allowReserved ? v : encodeURIComponent(v)
23133
+ ];
23134
+ });
23135
+ const joinedValues2 = values.join(",");
23136
+ switch (style) {
23137
+ case "form":
23138
+ return `${name}=${joinedValues2}`;
23139
+ case "label":
23140
+ return `.${joinedValues2}`;
23141
+ case "matrix":
23142
+ return `;${name}=${joinedValues2}`;
23143
+ default:
23144
+ return joinedValues2;
23145
+ }
23146
+ }
23147
+ const separator = separatorObjectExplode(style);
23148
+ const joinedValues = Object.entries(value).map(
23149
+ ([key, v]) => serializePrimitiveParam({
23150
+ allowReserved,
23151
+ name: style === "deepObject" ? `${name}[${key}]` : key,
23152
+ value: v
23153
+ })
23154
+ ).join(separator);
23155
+ return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
23156
+ };
23157
+
23158
+ // src/client/core/utils.gen.ts
23159
+ function getValidRequestBody(options) {
23160
+ const hasBody = options.body !== void 0;
23161
+ const isSerializedBody = hasBody && options.bodySerializer;
23162
+ if (isSerializedBody) {
23163
+ if ("serializedBody" in options) {
23164
+ const hasSerializedBody = options.serializedBody !== void 0 && options.serializedBody !== "";
23165
+ return hasSerializedBody ? options.serializedBody : null;
23166
+ }
23167
+ return options.body !== "" ? options.body : null;
23168
+ }
23169
+ if (hasBody) {
23170
+ return options.body;
23171
+ }
23172
+ return void 0;
23173
+ }
23174
+
23175
+ // src/client/core/auth.gen.ts
23176
+ var getAuthToken = async (auth, callback) => {
23177
+ const token = typeof callback === "function" ? await callback(auth) : callback;
23178
+ if (!token) {
23179
+ return;
23180
+ }
23181
+ if (auth.scheme === "bearer") {
23182
+ return `Bearer ${token}`;
23183
+ }
23184
+ if (auth.scheme === "basic") {
23185
+ return `Basic ${btoa(token)}`;
23186
+ }
23187
+ return token;
23188
+ };
23189
+
23190
+ // src/client/client/utils.gen.ts
23191
+ var PATH_PARAM_RE = /\{[^{}]+\}/g;
23192
+ var defaultPathSerializer = ({ path, url: _url }) => {
23193
+ let url = _url;
23194
+ const matches = _url.match(PATH_PARAM_RE);
23195
+ if (matches) {
23196
+ for (const match of matches) {
23197
+ let explode = false;
23198
+ let name = match.substring(1, match.length - 1);
23199
+ let style = "simple";
23200
+ if (name.endsWith("*")) {
23201
+ explode = true;
23202
+ name = name.substring(0, name.length - 1);
23203
+ }
23204
+ if (name.startsWith(".")) {
23205
+ name = name.substring(1);
23206
+ style = "label";
23207
+ } else if (name.startsWith(";")) {
23208
+ name = name.substring(1);
23209
+ style = "matrix";
23210
+ }
23211
+ const value = path[name];
23212
+ if (value === void 0 || value === null) {
23213
+ continue;
23406
23214
  }
23407
- const contexts = await Promise.all(
23408
- pdfFiles.map(async (file) => {
23409
- try {
23410
- const text12 = await extractTextFromPdf(file.url);
23411
- if (!text12.trim()) {
23412
- getLogger().warn(`No text found in PDF ${file.filename}`);
23413
- return null;
23414
- }
23415
- return `[Context from PDF attachment ${file.filename}]:
23416
- ${text12}`;
23417
- } catch (err) {
23418
- getLogger().error(`Failed to process PDF ${file.filename}:`, err);
23419
- return null;
23420
- }
23421
- })
23215
+ if (Array.isArray(value)) {
23216
+ url = url.replace(
23217
+ match,
23218
+ serializeArrayParam({ explode, name, style, value })
23219
+ );
23220
+ continue;
23221
+ }
23222
+ if (typeof value === "object") {
23223
+ url = url.replace(
23224
+ match,
23225
+ serializeObjectParam({
23226
+ explode,
23227
+ name,
23228
+ style,
23229
+ value,
23230
+ valueOnly: true
23231
+ })
23232
+ );
23233
+ continue;
23234
+ }
23235
+ if (style === "matrix") {
23236
+ url = url.replace(
23237
+ match,
23238
+ `;${serializePrimitiveParam({
23239
+ name,
23240
+ value
23241
+ })}`
23242
+ );
23243
+ continue;
23244
+ }
23245
+ const replaceValue = encodeURIComponent(
23246
+ style === "label" ? `.${value}` : value
23422
23247
  );
23423
- const mergedContext = contexts.filter(Boolean).join("\n\n");
23424
- return mergedContext || null;
23425
- } catch (err) {
23426
- const processedError = err instanceof Error ? err : new Error(String(err));
23427
- setError(processedError);
23428
- throw processedError;
23429
- } finally {
23430
- setIsProcessing(false);
23248
+ url = url.replace(match, replaceValue);
23431
23249
  }
23432
- }, []);
23433
- return {
23434
- extractPdfContext,
23435
- isProcessing,
23436
- error
23250
+ }
23251
+ return url;
23252
+ };
23253
+ var createQuerySerializer = ({
23254
+ parameters = {},
23255
+ ...args
23256
+ } = {}) => {
23257
+ const querySerializer = (queryParams) => {
23258
+ const search = [];
23259
+ if (queryParams && typeof queryParams === "object") {
23260
+ for (const name in queryParams) {
23261
+ const value = queryParams[name];
23262
+ if (value === void 0 || value === null) {
23263
+ continue;
23264
+ }
23265
+ const options = parameters[name] || args;
23266
+ if (Array.isArray(value)) {
23267
+ const serializedArray = serializeArrayParam({
23268
+ allowReserved: options.allowReserved,
23269
+ explode: true,
23270
+ name,
23271
+ style: "form",
23272
+ value,
23273
+ ...options.array
23274
+ });
23275
+ if (serializedArray) search.push(serializedArray);
23276
+ } else if (typeof value === "object") {
23277
+ const serializedObject = serializeObjectParam({
23278
+ allowReserved: options.allowReserved,
23279
+ explode: true,
23280
+ name,
23281
+ style: "deepObject",
23282
+ value,
23283
+ ...options.object
23284
+ });
23285
+ if (serializedObject) search.push(serializedObject);
23286
+ } else {
23287
+ const serializedPrimitive = serializePrimitiveParam({
23288
+ allowReserved: options.allowReserved,
23289
+ name,
23290
+ value
23291
+ });
23292
+ if (serializedPrimitive) search.push(serializedPrimitive);
23293
+ }
23294
+ }
23295
+ }
23296
+ return search.join("&");
23437
23297
  };
23438
- }
23439
-
23440
- // src/react/useVoice.ts
23441
- var import_react13 = require("react");
23442
- function getOnDeviceSpeechRecognition() {
23443
- if (typeof window === "undefined") return null;
23444
- if (!/iPhone|iPad|iPod/.test(navigator.userAgent)) return null;
23445
- const SR = window.SpeechRecognition ?? window.webkitSpeechRecognition;
23446
- return SR ?? null;
23447
- }
23448
- var SUPPORTED_MIME_TYPES = [
23449
- "audio/webm;codecs=opus",
23450
- "audio/webm",
23451
- "audio/mp4",
23452
- "audio/ogg;codecs=opus",
23453
- "audio/ogg"
23454
- ];
23455
- function getSupportedMimeType() {
23456
- if (typeof MediaRecorder === "undefined") {
23457
- return "audio/webm";
23298
+ return querySerializer;
23299
+ };
23300
+ var getParseAs = (contentType) => {
23301
+ if (!contentType) {
23302
+ return "stream";
23458
23303
  }
23459
- for (const type of SUPPORTED_MIME_TYPES) {
23460
- if (MediaRecorder.isTypeSupported(type)) {
23461
- return type;
23304
+ const cleanContent = contentType.split(";")[0]?.trim();
23305
+ if (!cleanContent) {
23306
+ return;
23307
+ }
23308
+ if (cleanContent.startsWith("application/json") || cleanContent.endsWith("+json")) {
23309
+ return "json";
23310
+ }
23311
+ if (cleanContent === "multipart/form-data") {
23312
+ return "formData";
23313
+ }
23314
+ if (["application/", "audio/", "image/", "video/"].some(
23315
+ (type) => cleanContent.startsWith(type)
23316
+ )) {
23317
+ return "blob";
23318
+ }
23319
+ if (cleanContent.startsWith("text/")) {
23320
+ return "text";
23321
+ }
23322
+ return;
23323
+ };
23324
+ var checkForExistence = (options, name) => {
23325
+ if (!name) {
23326
+ return false;
23327
+ }
23328
+ if (options.headers.has(name) || options.query?.[name] || options.headers.get("Cookie")?.includes(`${name}=`)) {
23329
+ return true;
23330
+ }
23331
+ return false;
23332
+ };
23333
+ var setAuthParams = async ({
23334
+ security,
23335
+ ...options
23336
+ }) => {
23337
+ for (const auth of security) {
23338
+ if (checkForExistence(options, auth.name)) {
23339
+ continue;
23340
+ }
23341
+ const token = await getAuthToken(auth, options.auth);
23342
+ if (!token) {
23343
+ continue;
23344
+ }
23345
+ const name = auth.name ?? "Authorization";
23346
+ switch (auth.in) {
23347
+ case "query":
23348
+ if (!options.query) {
23349
+ options.query = {};
23350
+ }
23351
+ options.query[name] = token;
23352
+ break;
23353
+ case "cookie":
23354
+ options.headers.append("Cookie", `${name}=${token}`);
23355
+ break;
23356
+ case "header":
23357
+ default:
23358
+ options.headers.set(name, token);
23359
+ break;
23462
23360
  }
23463
23361
  }
23464
- return "audio/webm";
23465
- }
23466
- var SAMPLE_RATE = 16e3;
23467
- async function audioToFloat32(blob) {
23468
- const arrayBuffer = await blob.arrayBuffer();
23469
- const audioContext = new AudioContext({ sampleRate: SAMPLE_RATE });
23470
- try {
23471
- const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
23472
- if (audioBuffer.numberOfChannels === 1) {
23473
- return audioBuffer.getChannelData(0);
23362
+ };
23363
+ var buildUrl = (options) => {
23364
+ const url = getUrl({
23365
+ baseUrl: options.baseUrl,
23366
+ path: options.path,
23367
+ query: options.query,
23368
+ querySerializer: typeof options.querySerializer === "function" ? options.querySerializer : createQuerySerializer(options.querySerializer),
23369
+ url: options.url
23370
+ });
23371
+ return url;
23372
+ };
23373
+ var getUrl = ({
23374
+ baseUrl,
23375
+ path,
23376
+ query,
23377
+ querySerializer,
23378
+ url: _url
23379
+ }) => {
23380
+ const pathUrl = _url.startsWith("/") ? _url : `/${_url}`;
23381
+ let url = (baseUrl ?? "") + pathUrl;
23382
+ if (path) {
23383
+ url = defaultPathSerializer({ path, url });
23384
+ }
23385
+ let search = query ? querySerializer(query) : "";
23386
+ if (search.startsWith("?")) {
23387
+ search = search.substring(1);
23388
+ }
23389
+ if (search) {
23390
+ url += `?${search}`;
23391
+ }
23392
+ return url;
23393
+ };
23394
+ var mergeConfigs = (a, b) => {
23395
+ const config = { ...a, ...b };
23396
+ if (config.baseUrl?.endsWith("/")) {
23397
+ config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1);
23398
+ }
23399
+ config.headers = mergeHeaders(a.headers, b.headers);
23400
+ return config;
23401
+ };
23402
+ var headersEntries = (headers) => {
23403
+ const entries = [];
23404
+ headers.forEach((value, key) => {
23405
+ entries.push([key, value]);
23406
+ });
23407
+ return entries;
23408
+ };
23409
+ var mergeHeaders = (...headers) => {
23410
+ const mergedHeaders = new Headers();
23411
+ for (const header of headers) {
23412
+ if (!header || typeof header !== "object") {
23413
+ continue;
23474
23414
  }
23475
- const length = audioBuffer.length;
23476
- const mono = new Float32Array(length);
23477
- const channels = audioBuffer.numberOfChannels;
23478
- for (let ch = 0; ch < channels; ch++) {
23479
- const data = audioBuffer.getChannelData(ch);
23480
- for (let i = 0; i < length; i++) {
23481
- mono[i] += data[i];
23415
+ const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header);
23416
+ for (const [key, value] of iterator) {
23417
+ if (value === null) {
23418
+ mergedHeaders.delete(key);
23419
+ } else if (Array.isArray(value)) {
23420
+ for (const v of value) {
23421
+ mergedHeaders.append(key, v);
23422
+ }
23423
+ } else if (value !== void 0) {
23424
+ mergedHeaders.set(
23425
+ key,
23426
+ typeof value === "object" ? JSON.stringify(value) : value
23427
+ );
23482
23428
  }
23483
23429
  }
23484
- for (let i = 0; i < length; i++) {
23485
- mono[i] /= channels;
23430
+ }
23431
+ return mergedHeaders;
23432
+ };
23433
+ var Interceptors = class {
23434
+ constructor() {
23435
+ this.fns = [];
23436
+ }
23437
+ clear() {
23438
+ this.fns = [];
23439
+ }
23440
+ eject(id) {
23441
+ const index = this.getInterceptorIndex(id);
23442
+ if (this.fns[index]) {
23443
+ this.fns[index] = null;
23486
23444
  }
23487
- return mono;
23488
- } finally {
23489
- await audioContext.close();
23490
23445
  }
23491
- }
23492
- function useVoice(options) {
23493
- const [isRecording, setIsRecording] = (0, import_react13.useState)(false);
23494
- const [isTranscribing, setIsTranscribing] = (0, import_react13.useState)(false);
23495
- const [isModelLoaded, setIsModelLoaded] = (0, import_react13.useState)(false);
23496
- const [isLoadingModel, setIsLoadingModel] = (0, import_react13.useState)(false);
23497
- const [recording, setRecording] = (0, import_react13.useState)(null);
23498
- const [transcription, setTranscription] = (0, import_react13.useState)(null);
23499
- const [error, setError] = (0, import_react13.useState)(null);
23500
- const mediaRecorderRef = (0, import_react13.useRef)(null);
23501
- const mediaStreamRef = (0, import_react13.useRef)(null);
23502
- const chunksRef = (0, import_react13.useRef)([]);
23503
- const startTimeRef = (0, import_react13.useRef)(0);
23504
- const pipelineRef = (0, import_react13.useRef)(null);
23505
- const modelNameRef = (0, import_react13.useRef)(null);
23506
- const getModelName = (0, import_react13.useCallback)(() => {
23507
- const model = options?.model ?? "whisper-tiny";
23508
- return `onnx-community/${model}`;
23509
- }, [options?.model]);
23510
- const loadPipeline = (0, import_react13.useCallback)(async () => {
23511
- const modelName = getModelName();
23512
- if (pipelineRef.current && modelNameRef.current === modelName) {
23513
- return pipelineRef.current;
23446
+ exists(id) {
23447
+ const index = this.getInterceptorIndex(id);
23448
+ return Boolean(this.fns[index]);
23449
+ }
23450
+ getInterceptorIndex(id) {
23451
+ if (typeof id === "number") {
23452
+ return this.fns[id] ? id : -1;
23514
23453
  }
23515
- setIsLoadingModel(true);
23516
- setError(null);
23517
- try {
23518
- const { pipeline } = await import("@huggingface/transformers");
23519
- const transcriber = await pipeline("automatic-speech-recognition", modelName, {
23520
- dtype: "q4",
23521
- device: "wasm",
23522
- progress_callback: options?.onModelProgress ? (progress) => {
23523
- if (progress.file && progress.progress !== null && progress.progress !== void 0) {
23524
- options.onModelProgress({
23525
- file: progress.file,
23526
- progress: progress.progress / 100,
23527
- loaded: progress.loaded ?? 0,
23528
- total: progress.total ?? 0
23529
- });
23530
- }
23531
- } : void 0
23454
+ return this.fns.indexOf(id);
23455
+ }
23456
+ update(id, fn) {
23457
+ const index = this.getInterceptorIndex(id);
23458
+ if (this.fns[index]) {
23459
+ this.fns[index] = fn;
23460
+ return id;
23461
+ }
23462
+ return false;
23463
+ }
23464
+ use(fn) {
23465
+ this.fns.push(fn);
23466
+ return this.fns.length - 1;
23467
+ }
23468
+ };
23469
+ var createInterceptors = () => ({
23470
+ error: new Interceptors(),
23471
+ request: new Interceptors(),
23472
+ response: new Interceptors()
23473
+ });
23474
+ var defaultQuerySerializer = createQuerySerializer({
23475
+ allowReserved: false,
23476
+ array: {
23477
+ explode: true,
23478
+ style: "form"
23479
+ },
23480
+ object: {
23481
+ explode: true,
23482
+ style: "deepObject"
23483
+ }
23484
+ });
23485
+ var defaultHeaders = {
23486
+ "Content-Type": "application/json"
23487
+ };
23488
+ var createConfig = (override = {}) => ({
23489
+ ...jsonBodySerializer,
23490
+ headers: defaultHeaders,
23491
+ parseAs: "auto",
23492
+ querySerializer: defaultQuerySerializer,
23493
+ ...override
23494
+ });
23495
+
23496
+ // src/client/client/client.gen.ts
23497
+ var createClient = (config = {}) => {
23498
+ let _config = mergeConfigs(createConfig(), config);
23499
+ const getConfig = () => ({ ..._config });
23500
+ const setConfig = (config2) => {
23501
+ _config = mergeConfigs(_config, config2);
23502
+ return getConfig();
23503
+ };
23504
+ const interceptors = createInterceptors();
23505
+ const beforeRequest = async (options) => {
23506
+ const opts = {
23507
+ ..._config,
23508
+ ...options,
23509
+ fetch: options.fetch ?? _config.fetch ?? globalThis.fetch,
23510
+ headers: mergeHeaders(_config.headers, options.headers),
23511
+ serializedBody: void 0
23512
+ };
23513
+ if (opts.security) {
23514
+ await setAuthParams({
23515
+ ...opts,
23516
+ security: opts.security
23532
23517
  });
23533
- pipelineRef.current = transcriber;
23534
- modelNameRef.current = modelName;
23535
- setIsModelLoaded(true);
23536
- return pipelineRef.current;
23537
- } catch (err) {
23538
- const processedError = err instanceof Error ? err : new Error("Failed to load Whisper model");
23539
- setError(processedError);
23540
- throw processedError;
23541
- } finally {
23542
- setIsLoadingModel(false);
23543
23518
  }
23544
- }, [getModelName, options?.onModelProgress]);
23545
- const preloadModel = (0, import_react13.useCallback)(async () => {
23546
- await loadPipeline();
23547
- }, [loadPipeline]);
23548
- const disposeModel = (0, import_react13.useCallback)(async () => {
23549
- const pipe = pipelineRef.current;
23550
- if (pipe?.dispose) {
23551
- await pipe.dispose();
23519
+ if (opts.requestValidator) {
23520
+ await opts.requestValidator(opts);
23552
23521
  }
23553
- pipelineRef.current = null;
23554
- modelNameRef.current = null;
23555
- setIsModelLoaded(false);
23556
- }, []);
23557
- const startRecording = (0, import_react13.useCallback)(async () => {
23558
- setError(null);
23559
- setRecording(null);
23560
- setTranscription(null);
23561
- try {
23562
- const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
23563
- mediaStreamRef.current = stream;
23564
- const mimeType = getSupportedMimeType();
23565
- const recorder = new MediaRecorder(stream, { mimeType });
23566
- mediaRecorderRef.current = recorder;
23567
- chunksRef.current = [];
23568
- recorder.ondataavailable = (e) => {
23569
- if (e.data.size > 0) {
23570
- chunksRef.current.push(e.data);
23571
- }
23572
- };
23573
- recorder.start();
23574
- startTimeRef.current = Date.now();
23575
- setIsRecording(true);
23576
- } catch (err) {
23577
- const processedError = err instanceof Error ? err : new Error("Failed to start recording");
23578
- setError(processedError);
23579
- throw processedError;
23522
+ if (opts.body !== void 0 && opts.bodySerializer) {
23523
+ opts.serializedBody = opts.bodySerializer(opts.body);
23580
23524
  }
23581
- }, []);
23582
- const stopRecording = (0, import_react13.useCallback)(async () => {
23583
- return new Promise((resolve, reject) => {
23584
- const recorder = mediaRecorderRef.current;
23585
- if (!recorder || recorder.state === "inactive") {
23586
- const err = new Error("No active recording");
23587
- setError(err);
23588
- reject(err);
23589
- return;
23525
+ if (opts.body === void 0 || opts.serializedBody === "") {
23526
+ opts.headers.delete("Content-Type");
23527
+ }
23528
+ const url = buildUrl(opts);
23529
+ return { opts, url };
23530
+ };
23531
+ const request = async (options) => {
23532
+ const { opts, url } = await beforeRequest(options);
23533
+ for (const fn of interceptors.request.fns) {
23534
+ if (fn) {
23535
+ await fn(opts);
23590
23536
  }
23591
- recorder.onstop = () => {
23592
- const mimeType = recorder.mimeType || "audio/webm";
23593
- const blob = new Blob(chunksRef.current, { type: mimeType });
23594
- const duration = Date.now() - startTimeRef.current;
23595
- mediaStreamRef.current?.getTracks().forEach((t) => t.stop());
23596
- mediaStreamRef.current = null;
23597
- mediaRecorderRef.current = null;
23598
- const result = { blob, duration, mimeType };
23599
- setRecording(result);
23600
- setIsRecording(false);
23601
- resolve(result);
23602
- };
23603
- recorder.onerror = () => {
23604
- const err = new Error("Recording failed");
23605
- setError(err);
23606
- setIsRecording(false);
23607
- reject(err);
23608
- };
23609
- recorder.stop();
23610
- });
23611
- }, []);
23612
- const transcribe = (0, import_react13.useCallback)(
23613
- async (rec) => {
23614
- const target = rec ?? recording;
23615
- if (!target) {
23616
- const err = new Error("No recording to transcribe");
23617
- setError(err);
23618
- throw err;
23537
+ }
23538
+ const _fetch = opts.fetch;
23539
+ const requestInit = {
23540
+ ...opts,
23541
+ body: getValidRequestBody(opts)
23542
+ };
23543
+ let response = await _fetch(url, requestInit);
23544
+ for (const fn of interceptors.response.fns) {
23545
+ if (fn) {
23546
+ response = await fn(response, opts);
23619
23547
  }
23620
- setIsTranscribing(true);
23621
- setError(null);
23622
- try {
23623
- const pipe = await loadPipeline();
23624
- const audio = await audioToFloat32(target.blob);
23625
- const result = await pipe(audio, {
23626
- language: options?.language,
23627
- return_timestamps: true
23628
- });
23629
- const transcriptionResult = {
23630
- text: result.text.trim(),
23631
- chunks: result.chunks
23548
+ }
23549
+ const result = {
23550
+ response
23551
+ };
23552
+ if (response.ok) {
23553
+ const parseAs = (opts.parseAs === "auto" ? getParseAs(response.headers.get("Content-Type")) : opts.parseAs) ?? "json";
23554
+ if (response.status === 204 || response.headers.get("Content-Length") === "0") {
23555
+ let emptyData;
23556
+ switch (parseAs) {
23557
+ case "arrayBuffer":
23558
+ case "blob":
23559
+ case "text":
23560
+ emptyData = await response[parseAs]();
23561
+ break;
23562
+ case "formData":
23563
+ emptyData = new FormData();
23564
+ break;
23565
+ case "stream":
23566
+ emptyData = response.body;
23567
+ break;
23568
+ case "json":
23569
+ default:
23570
+ emptyData = {};
23571
+ break;
23572
+ }
23573
+ return {
23574
+ data: emptyData,
23575
+ ...result
23632
23576
  };
23633
- setTranscription(transcriptionResult);
23634
- return transcriptionResult;
23635
- } catch (err) {
23636
- const processedError = err instanceof Error ? err : new Error("Transcription failed");
23637
- setError(processedError);
23638
- throw processedError;
23639
- } finally {
23640
- setIsTranscribing(false);
23641
23577
  }
23642
- },
23643
- [recording, loadPipeline, options?.language]
23644
- );
23645
- const nativeSpeechAvailable = (0, import_react13.useMemo)(() => getOnDeviceSpeechRecognition() !== null, []);
23646
- const [isNativeListening, setIsNativeListening] = (0, import_react13.useState)(false);
23647
- const nativeRecognitionRef = (0, import_react13.useRef)(null);
23648
- const nativeTextRef = (0, import_react13.useRef)("");
23649
- const nativeResolveRef = (0, import_react13.useRef)(null);
23650
- const startNativeTranscription = (0, import_react13.useCallback)(() => {
23651
- const SR = getOnDeviceSpeechRecognition();
23652
- if (!SR) return;
23653
- nativeTextRef.current = "";
23654
- setError(null);
23655
- const recognition = new SR();
23656
- recognition.continuous = true;
23657
- recognition.interimResults = false;
23658
- recognition.lang = options?.language ?? "";
23659
- recognition.onresult = (event) => {
23660
- let text12 = "";
23661
- for (let i = 0; i < event.results.length; i++) {
23662
- const result = event.results[i];
23663
- if (result && result.isFinal && result[0]) {
23664
- text12 += result[0].transcript + " ";
23665
- }
23578
+ let data;
23579
+ switch (parseAs) {
23580
+ case "arrayBuffer":
23581
+ case "blob":
23582
+ case "formData":
23583
+ case "json":
23584
+ case "text":
23585
+ data = await response[parseAs]();
23586
+ break;
23587
+ case "stream":
23588
+ return {
23589
+ data: response.body,
23590
+ ...result
23591
+ };
23666
23592
  }
23667
- nativeTextRef.current = text12.trim();
23668
- };
23669
- recognition.onerror = (event) => {
23670
- if (event.error !== "aborted" && event.error !== "no-speech") {
23671
- setError(new Error(`Speech recognition error: ${event.error}`));
23593
+ if (parseAs === "json") {
23594
+ if (opts.responseValidator) {
23595
+ await opts.responseValidator(data);
23596
+ }
23597
+ if (opts.responseTransformer) {
23598
+ data = await opts.responseTransformer(data);
23599
+ }
23672
23600
  }
23673
- };
23674
- recognition.onend = () => {
23675
- setIsNativeListening(false);
23676
- nativeRecognitionRef.current = null;
23677
- const resolve = nativeResolveRef.current;
23678
- if (resolve) {
23679
- nativeResolveRef.current = null;
23680
- resolve({ text: nativeTextRef.current });
23601
+ return {
23602
+ data,
23603
+ ...result
23604
+ };
23605
+ }
23606
+ const textError = await response.text();
23607
+ let jsonError;
23608
+ try {
23609
+ jsonError = JSON.parse(textError);
23610
+ } catch {
23611
+ }
23612
+ const error = jsonError ?? textError;
23613
+ let finalError = error;
23614
+ for (const fn of interceptors.error.fns) {
23615
+ if (fn) {
23616
+ finalError = await fn(error, response, opts);
23681
23617
  }
23618
+ }
23619
+ finalError = finalError || {};
23620
+ if (opts.throwOnError) {
23621
+ throw finalError;
23622
+ }
23623
+ return {
23624
+ error: finalError,
23625
+ ...result
23682
23626
  };
23683
- nativeRecognitionRef.current = recognition;
23684
- recognition.start();
23685
- setIsNativeListening(true);
23686
- }, [options?.language]);
23687
- const stopNativeTranscription = (0, import_react13.useCallback)(() => {
23688
- return new Promise((resolve) => {
23689
- const recognition = nativeRecognitionRef.current;
23690
- if (!recognition) {
23691
- resolve({ text: nativeTextRef.current || "" });
23692
- return;
23693
- }
23694
- nativeResolveRef.current = resolve;
23695
- recognition.stop();
23627
+ };
23628
+ const makeMethodFn = (method) => (options) => request({ ...options, method });
23629
+ const makeSseFn = (method) => async (options) => {
23630
+ const { opts, url } = await beforeRequest(options);
23631
+ return createSseClient({
23632
+ ...opts,
23633
+ body: opts.body,
23634
+ headers: opts.headers,
23635
+ method,
23636
+ onRequest: async (url2, init) => {
23637
+ let request2 = new Request(url2, init);
23638
+ const requestInit = {
23639
+ ...init,
23640
+ method: init.method,
23641
+ url: url2
23642
+ };
23643
+ for (const fn of interceptors.request.fns) {
23644
+ if (fn) {
23645
+ await fn(requestInit);
23646
+ request2 = new Request(requestInit.url, requestInit);
23647
+ }
23648
+ }
23649
+ return request2;
23650
+ },
23651
+ url
23696
23652
  });
23697
- }, []);
23698
- const abortNativeTranscription = (0, import_react13.useCallback)(() => {
23699
- const recognition = nativeRecognitionRef.current;
23700
- if (recognition) {
23701
- nativeResolveRef.current = null;
23702
- recognition.abort();
23703
- nativeRecognitionRef.current = null;
23704
- setIsNativeListening(false);
23705
- }
23706
- }, []);
23653
+ };
23707
23654
  return {
23708
- isRecording,
23709
- startRecording,
23710
- stopRecording,
23711
- isTranscribing,
23712
- transcribe,
23713
- preloadModel,
23714
- disposeModel,
23715
- isModelLoaded,
23716
- isLoadingModel,
23717
- recording,
23718
- transcription,
23719
- error,
23720
- nativeSpeechAvailable,
23721
- startNativeTranscription,
23722
- stopNativeTranscription,
23723
- abortNativeTranscription,
23724
- isNativeListening
23655
+ buildUrl,
23656
+ connect: makeMethodFn("CONNECT"),
23657
+ delete: makeMethodFn("DELETE"),
23658
+ get: makeMethodFn("GET"),
23659
+ getConfig,
23660
+ head: makeMethodFn("HEAD"),
23661
+ interceptors,
23662
+ options: makeMethodFn("OPTIONS"),
23663
+ patch: makeMethodFn("PATCH"),
23664
+ post: makeMethodFn("POST"),
23665
+ put: makeMethodFn("PUT"),
23666
+ request,
23667
+ setConfig,
23668
+ sse: {
23669
+ connect: makeSseFn("CONNECT"),
23670
+ delete: makeSseFn("DELETE"),
23671
+ get: makeSseFn("GET"),
23672
+ head: makeSseFn("HEAD"),
23673
+ options: makeSseFn("OPTIONS"),
23674
+ patch: makeSseFn("PATCH"),
23675
+ post: makeSseFn("POST"),
23676
+ put: makeSseFn("PUT"),
23677
+ trace: makeSseFn("TRACE")
23678
+ },
23679
+ trace: makeMethodFn("TRACE")
23725
23680
  };
23726
- }
23681
+ };
23682
+
23683
+ // src/client/client.gen.ts
23684
+ init_clientConfig();
23685
+ var client = createClient(createClientConfig(createConfig()));
23686
+
23687
+ // src/client/sdk.gen.ts
23688
+ var getApiV1Config = (options) => {
23689
+ return (options?.client ?? client).get({
23690
+ url: "/api/v1/config",
23691
+ ...options
23692
+ });
23693
+ };
23694
+ var getApiV1CreditsBalance = (options) => {
23695
+ return (options?.client ?? client).get({
23696
+ url: "/api/v1/credits/balance",
23697
+ ...options
23698
+ });
23699
+ };
23700
+ var getApiV1CreditsPacks = (options) => {
23701
+ return (options?.client ?? client).get({
23702
+ url: "/api/v1/credits/packs",
23703
+ ...options
23704
+ });
23705
+ };
23706
+ var postApiV1CreditsPurchase = (options) => {
23707
+ return (options.client ?? client).post({
23708
+ url: "/api/v1/credits/purchase",
23709
+ ...options,
23710
+ headers: {
23711
+ "Content-Type": "application/json",
23712
+ ...options.headers
23713
+ }
23714
+ });
23715
+ };
23716
+ var getApiV1Models = (options) => {
23717
+ return (options?.client ?? client).get({
23718
+ url: "/api/v1/models",
23719
+ ...options
23720
+ });
23721
+ };
23722
+ var postApiV1PhoneCalls = (options) => {
23723
+ return (options.client ?? client).post({
23724
+ url: "/api/v1/phone-calls",
23725
+ ...options,
23726
+ headers: {
23727
+ "Content-Type": "application/json",
23728
+ ...options.headers
23729
+ }
23730
+ });
23731
+ };
23732
+ var getApiV1PhoneCallsByCallId = (options) => {
23733
+ return (options.client ?? client).get({
23734
+ url: "/api/v1/phone-calls/{call_id}",
23735
+ ...options
23736
+ });
23737
+ };
23738
+ var postApiV1SubscriptionsCancel = (options) => {
23739
+ return (options?.client ?? client).post({
23740
+ url: "/api/v1/subscriptions/cancel",
23741
+ ...options,
23742
+ headers: {
23743
+ "Content-Type": "application/json",
23744
+ ...options?.headers
23745
+ }
23746
+ });
23747
+ };
23748
+ var postApiV1SubscriptionsCreateCheckoutSession = (options) => {
23749
+ return (options.client ?? client).post({
23750
+ url: "/api/v1/subscriptions/create-checkout-session",
23751
+ ...options,
23752
+ headers: {
23753
+ "Content-Type": "application/json",
23754
+ ...options.headers
23755
+ }
23756
+ });
23757
+ };
23758
+ var postApiV1SubscriptionsCustomerPortal = (options) => {
23759
+ return (options.client ?? client).post({
23760
+ url: "/api/v1/subscriptions/customer-portal",
23761
+ ...options,
23762
+ headers: {
23763
+ "Content-Type": "application/json",
23764
+ ...options.headers
23765
+ }
23766
+ });
23767
+ };
23768
+ var postApiV1SubscriptionsRenew = (options) => {
23769
+ return (options?.client ?? client).post({
23770
+ url: "/api/v1/subscriptions/renew",
23771
+ ...options
23772
+ });
23773
+ };
23774
+ var getApiV1SubscriptionsStatus = (options) => {
23775
+ return (options?.client ?? client).get({
23776
+ url: "/api/v1/subscriptions/status",
23777
+ ...options
23778
+ });
23779
+ };
23780
+ var getApiV1WalletsBinding = (options) => {
23781
+ return (options?.client ?? client).get({
23782
+ url: "/api/v1/wallets/binding",
23783
+ ...options
23784
+ });
23785
+ };
23786
+ var postApiV1WalletsBinding = (options) => {
23787
+ return (options.client ?? client).post({
23788
+ url: "/api/v1/wallets/binding",
23789
+ ...options,
23790
+ headers: {
23791
+ "Content-Type": "application/json",
23792
+ ...options.headers
23793
+ }
23794
+ });
23795
+ };
23796
+ var postApiV1WalletsBindingNonce = (options) => {
23797
+ return (options?.client ?? client).post({
23798
+ url: "/api/v1/wallets/binding/nonce",
23799
+ ...options
23800
+ });
23801
+ };
23802
+ var deleteApiV1WalletsBindingByAddress = (options) => {
23803
+ return (options.client ?? client).delete({
23804
+ url: "/api/v1/wallets/binding/{address}",
23805
+ ...options
23806
+ });
23807
+ };
23808
+ var postAuthOauthByProviderExchange = (options) => {
23809
+ return (options.client ?? client).post({
23810
+ url: "/auth/oauth/{provider}/exchange",
23811
+ ...options,
23812
+ headers: {
23813
+ "Content-Type": "application/json",
23814
+ ...options.headers
23815
+ }
23816
+ });
23817
+ };
23818
+ var postAuthOauthByProviderRefresh = (options) => {
23819
+ return (options.client ?? client).post({
23820
+ url: "/auth/oauth/{provider}/refresh",
23821
+ ...options,
23822
+ headers: {
23823
+ "Content-Type": "application/json",
23824
+ ...options.headers
23825
+ }
23826
+ });
23827
+ };
23828
+ var postAuthOauthByProviderRevoke = (options) => {
23829
+ return (options.client ?? client).post({
23830
+ url: "/auth/oauth/{provider}/revoke",
23831
+ ...options,
23832
+ headers: {
23833
+ "Content-Type": "application/json",
23834
+ ...options.headers
23835
+ }
23836
+ });
23837
+ };
23727
23838
 
23728
23839
  // src/react/useCredits.ts
23729
- var import_react14 = require("react");
23730
- init_sdk_gen();
23731
23840
  init_clientConfig();
23732
23841
  function useCredits(options = {}) {
23733
23842
  const { getToken, baseUrl = BASE_URL, autoFetch = true, onError } = options;
@@ -23886,7 +23995,6 @@ function useCredits(options = {}) {
23886
23995
 
23887
23996
  // src/react/useModels.ts
23888
23997
  var import_react15 = require("react");
23889
- init_sdk_gen();
23890
23998
  init_clientConfig();
23891
23999
  function useModels(options = {}) {
23892
24000
  const { getToken, baseUrl = BASE_URL, provider, autoFetch = true } = options;
@@ -23992,7 +24100,6 @@ function useModels(options = {}) {
23992
24100
 
23993
24101
  // src/react/usePhoneCalls.ts
23994
24102
  var import_react16 = require("react");
23995
- init_sdk_gen();
23996
24103
  init_clientConfig();
23997
24104
  var DEFAULT_POLL_INTERVAL_MS = 5e3;
23998
24105
  var DEFAULT_POLL_MAX_ATTEMPTS = 60;
@@ -24292,7 +24399,6 @@ function usePhoneCalls(options = {}) {
24292
24399
 
24293
24400
  // src/react/useSubscription.ts
24294
24401
  var import_react17 = require("react");
24295
- init_sdk_gen();
24296
24402
  init_clientConfig();
24297
24403
  function useSubscription(options = {}) {
24298
24404
  const { getToken, baseUrl = BASE_URL, autoFetch = true, onError } = options;
@@ -24498,7 +24604,6 @@ function useSubscription(options = {}) {
24498
24604
 
24499
24605
  // src/react/useWalletBinding.ts
24500
24606
  var import_react18 = require("react");
24501
- init_sdk_gen();
24502
24607
  init_clientConfig();
24503
24608
  function useWalletBinding(options = {}) {
24504
24609
  const { getToken, baseUrl = BASE_URL, autoFetch = true, onError } = options;
@@ -24682,7 +24787,6 @@ function useWalletBinding(options = {}) {
24682
24787
  var import_react19 = require("react");
24683
24788
 
24684
24789
  // src/lib/backup/dropbox/auth.ts
24685
- init_sdk_gen();
24686
24790
  init_logger();
24687
24791
 
24688
24792
  // src/lib/backup/oauth/storage.ts
@@ -25439,7 +25543,6 @@ function useDropboxBackup(options) {
25439
25543
  var import_react21 = require("react");
25440
25544
 
25441
25545
  // src/lib/backup/google/auth.ts
25442
- init_sdk_gen();
25443
25546
  init_logger();
25444
25547
  var PROVIDER2 = "google-drive";
25445
25548
  var CODE_STORAGE_KEY = "google_oauth_state";
@@ -26344,7 +26447,7 @@ async function uploadFileToICloud(filename, content) {
26344
26447
  const database = container.privateCloudDatabase;
26345
26448
  const recordName = `backup_${filename.replace(/[^a-zA-Z0-9]/g, "_")}`;
26346
26449
  const arrayBuffer = await content.arrayBuffer();
26347
- const base64Data = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
26450
+ const base64Data = uint8ArrayToBase64(new Uint8Array(arrayBuffer));
26348
26451
  const record = {
26349
26452
  recordType: RECORD_TYPE,
26350
26453
  recordName,
@@ -26406,11 +26509,7 @@ async function downloadICloudFile(recordName) {
26406
26509
  throw new Error("No data in record");
26407
26510
  }
26408
26511
  if (typeof dataField === "string") {
26409
- const binaryString = atob(dataField);
26410
- const bytes = new Uint8Array(binaryString.length);
26411
- for (let i = 0; i < binaryString.length; i++) {
26412
- bytes[i] = binaryString.charCodeAt(i);
26413
- }
26512
+ const bytes = base64ToUint8Array(dataField);
26414
26513
  return new Blob([bytes], { type: "application/json" });
26415
26514
  }
26416
26515
  if (typeof dataField === "object" && "downloadURL" in dataField) {
@@ -27242,7 +27341,6 @@ function useBackup(options) {
27242
27341
  }
27243
27342
 
27244
27343
  // src/lib/auth/google-calendar.ts
27245
- init_sdk_gen();
27246
27344
  init_useEncryption();
27247
27345
  init_logger();
27248
27346
  var PROVIDER3 = "google-drive";
@@ -27568,7 +27666,6 @@ async function migrateCalendarToken(walletAddress) {
27568
27666
  }
27569
27667
 
27570
27668
  // src/lib/auth/google-drive.ts
27571
- init_sdk_gen();
27572
27669
  init_useEncryption();
27573
27670
  init_logger();
27574
27671
  var PROVIDER4 = "google-drive";
@@ -28445,7 +28542,6 @@ function getNotionMCPUrl() {
28445
28542
  }
28446
28543
 
28447
28544
  // src/lib/auth/github.ts
28448
- init_sdk_gen();
28449
28545
  init_useEncryption();
28450
28546
  init_logger();
28451
28547
  var PROVIDER5 = "github";
@@ -30593,6 +30689,7 @@ function renderAnumaJsx(jsx3) {
30593
30689
  getConversationsByProjectLazyOp,
30594
30690
  getConversationsByProjectOp,
30595
30691
  getConversationsLazyOp,
30692
+ getConversationsPageOp,
30596
30693
  getDocumentsOp,
30597
30694
  getDriveAccessToken,
30598
30695
  getEncryptionKey,