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