@anuma/sdk 3.6.2 → 3.6.3
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-FKACNV6X.mjs} +809 -3
- package/dist/expo/index.cjs +909 -823
- package/dist/expo/index.mjs +7 -798
- package/dist/expo/{recall-IO4KJ5W7.mjs → recall-VZHV7ILE.mjs} +1 -1
- package/dist/react/{chunk-DDHTJGZN.mjs → chunk-ZGMHRWOR.mjs} +895 -3
- package/dist/react/index.cjs +1999 -1905
- package/dist/react/index.mjs +22 -869
- package/dist/react/{recall-OPKHWKZX.mjs → recall-JOLS3V4B.mjs} +1 -1
- package/dist/server/{chunk-V7SVKIXQ.mjs → chunk-66UWDXS3.mjs} +794 -3
- package/dist/server/index.cjs +886 -144
- package/dist/server/index.mjs +2 -128
- package/dist/server/{recall-IWY2MYHR.mjs → recall-UTVH2XPK.mjs} +1 -1
- 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 = {}) {
|
|
@@ -7392,165 +8342,39 @@ __export(index_exports, {
|
|
|
7392
8342
|
useChat: () => useChat,
|
|
7393
8343
|
useChatStorage: () => useChatStorage,
|
|
7394
8344
|
useCredits: () => useCredits,
|
|
7395
|
-
useDatabaseManager: () => useDatabaseManager,
|
|
7396
|
-
useDropboxAuth: () => useDropboxAuth,
|
|
7397
|
-
useDropboxBackup: () => useDropboxBackup,
|
|
7398
|
-
useEncryption: () => useEncryption,
|
|
7399
|
-
useExportPdf: () => useExportPdf,
|
|
7400
|
-
useFiles: () => useFiles,
|
|
7401
|
-
useGoogleDriveAuth: () => useGoogleDriveAuth,
|
|
7402
|
-
useGoogleDriveBackup: () => useGoogleDriveBackup,
|
|
7403
|
-
useICloudAuth: () => useICloudAuth,
|
|
7404
|
-
useICloudBackup: () => useICloudBackup,
|
|
7405
|
-
useModels: () => useModels,
|
|
7406
|
-
useOCR: () => useOCR,
|
|
7407
|
-
usePdf: () => usePdf,
|
|
7408
|
-
usePhoneCalls: () => usePhoneCalls,
|
|
7409
|
-
useProjects: () => useProjects,
|
|
7410
|
-
useSettings: () => useSettings,
|
|
7411
|
-
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
|
-
}
|
|
8345
|
+
useDatabaseManager: () => useDatabaseManager,
|
|
8346
|
+
useDropboxAuth: () => useDropboxAuth,
|
|
8347
|
+
useDropboxBackup: () => useDropboxBackup,
|
|
8348
|
+
useEncryption: () => useEncryption,
|
|
8349
|
+
useExportPdf: () => useExportPdf,
|
|
8350
|
+
useFiles: () => useFiles,
|
|
8351
|
+
useGoogleDriveAuth: () => useGoogleDriveAuth,
|
|
8352
|
+
useGoogleDriveBackup: () => useGoogleDriveBackup,
|
|
8353
|
+
useICloudAuth: () => useICloudAuth,
|
|
8354
|
+
useICloudBackup: () => useICloudBackup,
|
|
8355
|
+
useModels: () => useModels,
|
|
8356
|
+
useOCR: () => useOCR,
|
|
8357
|
+
usePdf: () => usePdf,
|
|
8358
|
+
usePhoneCalls: () => usePhoneCalls,
|
|
8359
|
+
useProjects: () => useProjects,
|
|
8360
|
+
useSettings: () => useSettings,
|
|
8361
|
+
useSubscription: () => useSubscription,
|
|
8362
|
+
useTools: () => useTools,
|
|
8363
|
+
useUIInteraction: () => useUIInteraction,
|
|
8364
|
+
useVoice: () => useVoice,
|
|
8365
|
+
useWalletBinding: () => useWalletBinding,
|
|
8366
|
+
userPreferencesStorageSchema: () => userPreferencesStorageSchema,
|
|
8367
|
+
walk: () => walk,
|
|
8368
|
+
webPlatformStorage: () => webPlatformStorage,
|
|
8369
|
+
writeEncryptedFile: () => writeEncryptedFile
|
|
8370
|
+
});
|
|
8371
|
+
module.exports = __toCommonJS(index_exports);
|
|
8372
|
+
|
|
8373
|
+
// src/lib/chat/resumeStream.ts
|
|
8374
|
+
init_clientConfig();
|
|
7552
8375
|
|
|
7553
8376
|
// src/lib/chat/toolLoop.ts
|
|
8377
|
+
init_serverSentEvents_gen();
|
|
7554
8378
|
init_clientConfig();
|
|
7555
8379
|
init_embeddings();
|
|
7556
8380
|
init_redactor();
|
|
@@ -24290,1296 +25114,557 @@ async function exportMarkdownToPdf(markdown, options) {
|
|
|
24290
25114
|
for (const row of rows) {
|
|
24291
25115
|
renderRow2(row, "normal");
|
|
24292
25116
|
}
|
|
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;
|
|
25117
|
+
cursorY += SPACING.MD;
|
|
25118
|
+
break;
|
|
24519
25119
|
}
|
|
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);
|
|
25120
|
+
case "space": {
|
|
25121
|
+
cursorY += SPACING.MD;
|
|
25122
|
+
break;
|
|
25123
|
+
}
|
|
25124
|
+
default:
|
|
25125
|
+
if (token.raw.trim()) {
|
|
25126
|
+
renderWrappedText(token.raw.trim(), opts.margins.left, cw, opts.fontSize);
|
|
25127
|
+
cursorY += SPACING.SM;
|
|
25128
|
+
}
|
|
25129
|
+
break;
|
|
24544
25130
|
}
|
|
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
25131
|
}
|
|
24572
|
-
|
|
24573
|
-
|
|
24574
|
-
return type;
|
|
24575
|
-
}
|
|
25132
|
+
if (opts.pageNumbers) {
|
|
25133
|
+
addPageNumbers(doc, pageW, pageH);
|
|
24576
25134
|
}
|
|
24577
|
-
|
|
25135
|
+
opts.onProgress?.({ stage: "complete", percent: 100 });
|
|
25136
|
+
return doc.output("blob");
|
|
24578
25137
|
}
|
|
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
|
-
}
|
|
25138
|
+
|
|
25139
|
+
// src/react/useExportPdf.ts
|
|
25140
|
+
var import_react10 = require("react");
|
|
25141
|
+
var DEFAULT_FILENAME2 = "document.pdf";
|
|
25142
|
+
function triggerDownload(blob, filename) {
|
|
25143
|
+
const url = URL.createObjectURL(blob);
|
|
25144
|
+
const a = document.createElement("a");
|
|
25145
|
+
a.href = url;
|
|
25146
|
+
a.download = filename;
|
|
25147
|
+
document.body.appendChild(a);
|
|
25148
|
+
a.click();
|
|
25149
|
+
document.body.removeChild(a);
|
|
25150
|
+
setTimeout(() => URL.revokeObjectURL(url), 100);
|
|
24604
25151
|
}
|
|
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;
|
|
25152
|
+
function toError(err) {
|
|
25153
|
+
return err instanceof Error ? err : new Error(String(err));
|
|
25154
|
+
}
|
|
25155
|
+
function useExportPdf() {
|
|
25156
|
+
const [isExporting, setIsExporting] = (0, import_react10.useState)(false);
|
|
25157
|
+
const [progress, setProgress] = (0, import_react10.useState)(null);
|
|
25158
|
+
const [error, setError] = (0, import_react10.useState)(null);
|
|
25159
|
+
const wrappedExportElement = (0, import_react10.useCallback)(
|
|
25160
|
+
async (element, options) => {
|
|
25161
|
+
setIsExporting(true);
|
|
25162
|
+
setError(null);
|
|
25163
|
+
setProgress({ stage: "preparing", percent: 0 });
|
|
25164
|
+
try {
|
|
25165
|
+
return await exportElementToPdf(element, {
|
|
25166
|
+
...options,
|
|
25167
|
+
onProgress: setProgress
|
|
25168
|
+
});
|
|
25169
|
+
} catch (err) {
|
|
25170
|
+
const processed = toError(err);
|
|
25171
|
+
setError(processed);
|
|
25172
|
+
throw processed;
|
|
25173
|
+
} finally {
|
|
25174
|
+
setIsExporting(false);
|
|
24732
25175
|
}
|
|
24733
|
-
|
|
25176
|
+
},
|
|
25177
|
+
[]
|
|
25178
|
+
);
|
|
25179
|
+
const wrappedExportMarkdown = (0, import_react10.useCallback)(
|
|
25180
|
+
async (markdown, options) => {
|
|
25181
|
+
setIsExporting(true);
|
|
24734
25182
|
setError(null);
|
|
25183
|
+
setProgress({ stage: "preparing", percent: 0 });
|
|
24735
25184
|
try {
|
|
24736
|
-
|
|
24737
|
-
|
|
24738
|
-
|
|
24739
|
-
language: options?.language,
|
|
24740
|
-
return_timestamps: true
|
|
25185
|
+
return await exportMarkdownToPdf(markdown, {
|
|
25186
|
+
...options,
|
|
25187
|
+
onProgress: setProgress
|
|
24741
25188
|
});
|
|
24742
|
-
const transcriptionResult = {
|
|
24743
|
-
text: result.text.trim(),
|
|
24744
|
-
chunks: result.chunks
|
|
24745
|
-
};
|
|
24746
|
-
setTranscription(transcriptionResult);
|
|
24747
|
-
return transcriptionResult;
|
|
24748
25189
|
} catch (err) {
|
|
24749
|
-
const
|
|
24750
|
-
setError(
|
|
24751
|
-
throw
|
|
25190
|
+
const processed = toError(err);
|
|
25191
|
+
setError(processed);
|
|
25192
|
+
throw processed;
|
|
24752
25193
|
} finally {
|
|
24753
|
-
|
|
25194
|
+
setIsExporting(false);
|
|
24754
25195
|
}
|
|
24755
25196
|
},
|
|
24756
|
-
[
|
|
25197
|
+
[]
|
|
24757
25198
|
);
|
|
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;
|
|
25199
|
+
const downloadElementAsPdf = (0, import_react10.useCallback)(
|
|
25200
|
+
async (element, options) => {
|
|
25201
|
+
const blob = await wrappedExportElement(element, options);
|
|
25202
|
+
triggerDownload(blob, options?.filename ?? DEFAULT_FILENAME2);
|
|
25203
|
+
},
|
|
25204
|
+
[wrappedExportElement]
|
|
25205
|
+
);
|
|
25206
|
+
const downloadMarkdownAsPdf = (0, import_react10.useCallback)(
|
|
25207
|
+
async (markdown, options) => {
|
|
25208
|
+
const blob = await wrappedExportMarkdown(markdown, options);
|
|
25209
|
+
triggerDownload(blob, options?.filename ?? DEFAULT_FILENAME2);
|
|
25210
|
+
},
|
|
25211
|
+
[wrappedExportMarkdown]
|
|
25212
|
+
);
|
|
25213
|
+
const wrappedRenderToCanvas = (0, import_react10.useCallback)(
|
|
25214
|
+
async (element) => {
|
|
25215
|
+
setIsExporting(true);
|
|
25216
|
+
setError(null);
|
|
25217
|
+
setProgress({ stage: "preparing", percent: 0 });
|
|
25218
|
+
try {
|
|
25219
|
+
const canvas = await renderElementToCanvas(element, { onProgress: setProgress });
|
|
25220
|
+
return canvas;
|
|
25221
|
+
} catch (err) {
|
|
25222
|
+
const processed = toError(err);
|
|
25223
|
+
setError(processed);
|
|
25224
|
+
throw processed;
|
|
25225
|
+
} finally {
|
|
25226
|
+
setIsExporting(false);
|
|
24806
25227
|
}
|
|
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
|
-
}, []);
|
|
25228
|
+
},
|
|
25229
|
+
[]
|
|
25230
|
+
);
|
|
24820
25231
|
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
|
|
25232
|
+
exportElementToPdf: wrappedExportElement,
|
|
25233
|
+
exportMarkdownToPdf: wrappedExportMarkdown,
|
|
25234
|
+
downloadElementAsPdf,
|
|
25235
|
+
downloadMarkdownAsPdf,
|
|
25236
|
+
renderElementToCanvas: wrappedRenderToCanvas,
|
|
25237
|
+
isExporting,
|
|
25238
|
+
progress,
|
|
25239
|
+
error
|
|
24838
25240
|
};
|
|
24839
25241
|
}
|
|
24840
25242
|
|
|
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;
|
|
25243
|
+
// src/react/useOCR.ts
|
|
25244
|
+
var import_react11 = require("react");
|
|
25245
|
+
var import_tesseract = __toESM(require("tesseract.js"));
|
|
25246
|
+
init_logger();
|
|
25247
|
+
function useOCR() {
|
|
25248
|
+
const [isProcessing, setIsProcessing] = (0, import_react11.useState)(false);
|
|
25249
|
+
const [error, setError] = (0, import_react11.useState)(null);
|
|
25250
|
+
const extractOCRContext = (0, import_react11.useCallback)(async (files) => {
|
|
25251
|
+
setIsProcessing(true);
|
|
25252
|
+
setError(null);
|
|
25253
|
+
try {
|
|
25254
|
+
if (files.length === 0) {
|
|
25255
|
+
return null;
|
|
25256
|
+
}
|
|
25257
|
+
const contexts = await Promise.all(
|
|
25258
|
+
files.map(async (file) => {
|
|
25259
|
+
try {
|
|
25260
|
+
let imagesToProcess = [];
|
|
25261
|
+
const language = file.language || "eng";
|
|
25262
|
+
const filename = file.filename || (file.url instanceof File ? file.url.name : "");
|
|
25263
|
+
let isPdf = false;
|
|
25264
|
+
if (typeof file.url === "string") {
|
|
25265
|
+
isPdf = file.url.toLowerCase().endsWith(".pdf") || (filename?.toLowerCase().endsWith(".pdf") ?? false);
|
|
25266
|
+
} else if (file.url instanceof Blob) {
|
|
25267
|
+
isPdf = file.url.type === "application/pdf" || (filename?.toLowerCase().endsWith(".pdf") ?? false);
|
|
25268
|
+
}
|
|
25269
|
+
if (isPdf) {
|
|
25270
|
+
let pdfUrl;
|
|
25271
|
+
let shouldRevoke = false;
|
|
25272
|
+
if (typeof file.url === "string") {
|
|
25273
|
+
pdfUrl = file.url;
|
|
25274
|
+
} else {
|
|
25275
|
+
pdfUrl = URL.createObjectURL(file.url);
|
|
25276
|
+
shouldRevoke = true;
|
|
25277
|
+
}
|
|
25278
|
+
try {
|
|
25279
|
+
const pdfImages = await convertPdfToImages(pdfUrl);
|
|
25280
|
+
imagesToProcess = pdfImages;
|
|
25281
|
+
} catch (e) {
|
|
25282
|
+
getLogger().error("Failed to convert PDF to images", e);
|
|
25283
|
+
throw e;
|
|
25284
|
+
} finally {
|
|
25285
|
+
if (shouldRevoke) {
|
|
25286
|
+
URL.revokeObjectURL(pdfUrl);
|
|
25287
|
+
}
|
|
25288
|
+
}
|
|
25289
|
+
} else {
|
|
25290
|
+
imagesToProcess = [file.url];
|
|
25291
|
+
}
|
|
25292
|
+
const pageTexts = [];
|
|
25293
|
+
for (const image of imagesToProcess) {
|
|
25294
|
+
const result = await import_tesseract.default.recognize(image, language);
|
|
25295
|
+
pageTexts.push(result.data.text);
|
|
25296
|
+
}
|
|
25297
|
+
const text12 = pageTexts.join("\n\n");
|
|
25298
|
+
if (!text12.trim()) {
|
|
25299
|
+
getLogger().warn(`No text found in OCR source ${filename || "unknown"}`);
|
|
25300
|
+
return null;
|
|
25301
|
+
}
|
|
25302
|
+
return `[Context from OCR attachment ${filename || "unknown"}]:
|
|
25303
|
+
${text12}`;
|
|
25304
|
+
} catch (err) {
|
|
25305
|
+
getLogger().error(`Failed to process OCR for ${file.filename || "unknown"}:`, err);
|
|
25306
|
+
return null;
|
|
25307
|
+
}
|
|
25308
|
+
})
|
|
25309
|
+
);
|
|
25310
|
+
const mergedContext = contexts.filter(Boolean).join("\n\n");
|
|
25311
|
+
return mergedContext || null;
|
|
25312
|
+
} catch (err) {
|
|
25313
|
+
const processedError = err instanceof Error ? err : new Error(String(err));
|
|
25314
|
+
setError(processedError);
|
|
25315
|
+
throw processedError;
|
|
25316
|
+
} finally {
|
|
25317
|
+
setIsProcessing(false);
|
|
24981
25318
|
}
|
|
24982
|
-
|
|
24983
|
-
|
|
24984
|
-
|
|
24985
|
-
|
|
24986
|
-
|
|
24987
|
-
|
|
25319
|
+
}, []);
|
|
25320
|
+
return {
|
|
25321
|
+
extractOCRContext,
|
|
25322
|
+
isProcessing,
|
|
25323
|
+
error
|
|
25324
|
+
};
|
|
24988
25325
|
}
|
|
24989
25326
|
|
|
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
|
|
25327
|
+
// src/react/usePdf.ts
|
|
25328
|
+
var import_react12 = require("react");
|
|
25329
|
+
init_logger();
|
|
25330
|
+
var PDF_MIME_TYPE = "application/pdf";
|
|
25331
|
+
function usePdf() {
|
|
25332
|
+
const [isProcessing, setIsProcessing] = (0, import_react12.useState)(false);
|
|
25333
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
25334
|
+
const extractPdfContext = (0, import_react12.useCallback)(async (files) => {
|
|
25335
|
+
setIsProcessing(true);
|
|
25336
|
+
setError(null);
|
|
25337
|
+
try {
|
|
25338
|
+
const pdfFiles = files.filter(
|
|
25339
|
+
(file) => file.mediaType === PDF_MIME_TYPE || file.filename?.toLowerCase().endsWith(".pdf")
|
|
25059
25340
|
);
|
|
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
|
-
}
|
|
25341
|
+
if (pdfFiles.length === 0) {
|
|
25342
|
+
return null;
|
|
25106
25343
|
}
|
|
25344
|
+
const contexts = await Promise.all(
|
|
25345
|
+
pdfFiles.map(async (file) => {
|
|
25346
|
+
try {
|
|
25347
|
+
const text12 = await extractTextFromPdf(file.url);
|
|
25348
|
+
if (!text12.trim()) {
|
|
25349
|
+
getLogger().warn(`No text found in PDF ${file.filename}`);
|
|
25350
|
+
return null;
|
|
25351
|
+
}
|
|
25352
|
+
return `[Context from PDF attachment ${file.filename}]:
|
|
25353
|
+
${text12}`;
|
|
25354
|
+
} catch (err) {
|
|
25355
|
+
getLogger().error(`Failed to process PDF ${file.filename}:`, err);
|
|
25356
|
+
return null;
|
|
25357
|
+
}
|
|
25358
|
+
})
|
|
25359
|
+
);
|
|
25360
|
+
const mergedContext = contexts.filter(Boolean).join("\n\n");
|
|
25361
|
+
return mergedContext || null;
|
|
25362
|
+
} catch (err) {
|
|
25363
|
+
const processedError = err instanceof Error ? err : new Error(String(err));
|
|
25364
|
+
setError(processedError);
|
|
25365
|
+
throw processedError;
|
|
25366
|
+
} finally {
|
|
25367
|
+
setIsProcessing(false);
|
|
25107
25368
|
}
|
|
25108
|
-
|
|
25369
|
+
}, []);
|
|
25370
|
+
return {
|
|
25371
|
+
extractPdfContext,
|
|
25372
|
+
isProcessing,
|
|
25373
|
+
error
|
|
25109
25374
|
};
|
|
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;
|
|
25375
|
+
}
|
|
25376
|
+
|
|
25377
|
+
// src/react/useVoice.ts
|
|
25378
|
+
var import_react13 = require("react");
|
|
25379
|
+
function getOnDeviceSpeechRecognition() {
|
|
25380
|
+
if (typeof window === "undefined") return null;
|
|
25381
|
+
if (!/iPhone|iPad|iPod/.test(navigator.userAgent)) return null;
|
|
25382
|
+
const SR = window.SpeechRecognition ?? window.webkitSpeechRecognition;
|
|
25383
|
+
return SR ?? null;
|
|
25384
|
+
}
|
|
25385
|
+
var SUPPORTED_MIME_TYPES = [
|
|
25386
|
+
"audio/webm;codecs=opus",
|
|
25387
|
+
"audio/webm",
|
|
25388
|
+
"audio/mp4",
|
|
25389
|
+
"audio/ogg;codecs=opus",
|
|
25390
|
+
"audio/ogg"
|
|
25391
|
+
];
|
|
25392
|
+
function getSupportedMimeType() {
|
|
25393
|
+
if (typeof MediaRecorder === "undefined") {
|
|
25394
|
+
return "audio/webm";
|
|
25140
25395
|
}
|
|
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;
|
|
25396
|
+
for (const type of SUPPORTED_MIME_TYPES) {
|
|
25397
|
+
if (MediaRecorder.isTypeSupported(type)) {
|
|
25398
|
+
return type;
|
|
25167
25399
|
}
|
|
25168
25400
|
}
|
|
25401
|
+
return "audio/webm";
|
|
25169
25402
|
}
|
|
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;
|
|
25403
|
+
var SAMPLE_RATE = 16e3;
|
|
25404
|
+
async function audioToFloat32(blob) {
|
|
25405
|
+
const arrayBuffer = await blob.arrayBuffer();
|
|
25406
|
+
const audioContext = new AudioContext({ sampleRate: SAMPLE_RATE });
|
|
25407
|
+
try {
|
|
25408
|
+
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
|
|
25409
|
+
if (audioBuffer.numberOfChannels === 1) {
|
|
25410
|
+
return audioBuffer.getChannelData(0);
|
|
25221
25411
|
}
|
|
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
|
-
);
|
|
25412
|
+
const length = audioBuffer.length;
|
|
25413
|
+
const mono = new Float32Array(length);
|
|
25414
|
+
const channels = audioBuffer.numberOfChannels;
|
|
25415
|
+
for (let ch = 0; ch < channels; ch++) {
|
|
25416
|
+
const data = audioBuffer.getChannelData(ch);
|
|
25417
|
+
for (let i = 0; i < length; i++) {
|
|
25418
|
+
mono[i] += data[i];
|
|
25235
25419
|
}
|
|
25236
25420
|
}
|
|
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;
|
|
25421
|
+
for (let i = 0; i < length; i++) {
|
|
25422
|
+
mono[i] /= channels;
|
|
25268
25423
|
}
|
|
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"
|
|
25424
|
+
return mono;
|
|
25425
|
+
} finally {
|
|
25426
|
+
await audioContext.close();
|
|
25290
25427
|
}
|
|
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);
|
|
25428
|
+
}
|
|
25429
|
+
function useVoice(options) {
|
|
25430
|
+
const [isRecording, setIsRecording] = (0, import_react13.useState)(false);
|
|
25431
|
+
const [isTranscribing, setIsTranscribing] = (0, import_react13.useState)(false);
|
|
25432
|
+
const [isModelLoaded, setIsModelLoaded] = (0, import_react13.useState)(false);
|
|
25433
|
+
const [isLoadingModel, setIsLoadingModel] = (0, import_react13.useState)(false);
|
|
25434
|
+
const [recording, setRecording] = (0, import_react13.useState)(null);
|
|
25435
|
+
const [transcription, setTranscription] = (0, import_react13.useState)(null);
|
|
25436
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
25437
|
+
const mediaRecorderRef = (0, import_react13.useRef)(null);
|
|
25438
|
+
const mediaStreamRef = (0, import_react13.useRef)(null);
|
|
25439
|
+
const chunksRef = (0, import_react13.useRef)([]);
|
|
25440
|
+
const startTimeRef = (0, import_react13.useRef)(0);
|
|
25441
|
+
const pipelineRef = (0, import_react13.useRef)(null);
|
|
25442
|
+
const modelNameRef = (0, import_react13.useRef)(null);
|
|
25443
|
+
const getModelName = (0, import_react13.useCallback)(() => {
|
|
25444
|
+
const model = options?.model ?? "whisper-tiny";
|
|
25445
|
+
return `onnx-community/${model}`;
|
|
25446
|
+
}, [options?.model]);
|
|
25447
|
+
const loadPipeline = (0, import_react13.useCallback)(async () => {
|
|
25448
|
+
const modelName = getModelName();
|
|
25449
|
+
if (pipelineRef.current && modelNameRef.current === modelName) {
|
|
25450
|
+
return pipelineRef.current;
|
|
25325
25451
|
}
|
|
25326
|
-
|
|
25327
|
-
|
|
25452
|
+
setIsLoadingModel(true);
|
|
25453
|
+
setError(null);
|
|
25454
|
+
try {
|
|
25455
|
+
const { pipeline } = await import("@huggingface/transformers");
|
|
25456
|
+
const transcriber = await pipeline("automatic-speech-recognition", modelName, {
|
|
25457
|
+
dtype: "q4",
|
|
25458
|
+
device: "wasm",
|
|
25459
|
+
progress_callback: options?.onModelProgress ? (progress) => {
|
|
25460
|
+
if (progress.file && progress.progress !== null && progress.progress !== void 0) {
|
|
25461
|
+
options.onModelProgress({
|
|
25462
|
+
file: progress.file,
|
|
25463
|
+
progress: progress.progress / 100,
|
|
25464
|
+
loaded: progress.loaded ?? 0,
|
|
25465
|
+
total: progress.total ?? 0
|
|
25466
|
+
});
|
|
25467
|
+
}
|
|
25468
|
+
} : void 0
|
|
25469
|
+
});
|
|
25470
|
+
pipelineRef.current = transcriber;
|
|
25471
|
+
modelNameRef.current = modelName;
|
|
25472
|
+
setIsModelLoaded(true);
|
|
25473
|
+
return pipelineRef.current;
|
|
25474
|
+
} catch (err) {
|
|
25475
|
+
const processedError = err instanceof Error ? err : new Error("Failed to load Whisper model");
|
|
25476
|
+
setError(processedError);
|
|
25477
|
+
throw processedError;
|
|
25478
|
+
} finally {
|
|
25479
|
+
setIsLoadingModel(false);
|
|
25328
25480
|
}
|
|
25329
|
-
|
|
25330
|
-
|
|
25481
|
+
}, [getModelName, options?.onModelProgress]);
|
|
25482
|
+
const preloadModel = (0, import_react13.useCallback)(async () => {
|
|
25483
|
+
await loadPipeline();
|
|
25484
|
+
}, [loadPipeline]);
|
|
25485
|
+
const disposeModel = (0, import_react13.useCallback)(async () => {
|
|
25486
|
+
const pipe = pipelineRef.current;
|
|
25487
|
+
if (pipe?.dispose) {
|
|
25488
|
+
await pipe.dispose();
|
|
25331
25489
|
}
|
|
25332
|
-
|
|
25333
|
-
|
|
25334
|
-
|
|
25335
|
-
};
|
|
25336
|
-
const
|
|
25337
|
-
|
|
25338
|
-
|
|
25490
|
+
pipelineRef.current = null;
|
|
25491
|
+
modelNameRef.current = null;
|
|
25492
|
+
setIsModelLoaded(false);
|
|
25493
|
+
}, []);
|
|
25494
|
+
const startRecording = (0, import_react13.useCallback)(async () => {
|
|
25495
|
+
setError(null);
|
|
25496
|
+
setRecording(null);
|
|
25497
|
+
setTranscription(null);
|
|
25339
25498
|
try {
|
|
25340
|
-
const
|
|
25341
|
-
|
|
25342
|
-
|
|
25343
|
-
|
|
25499
|
+
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
25500
|
+
mediaStreamRef.current = stream;
|
|
25501
|
+
const mimeType = getSupportedMimeType();
|
|
25502
|
+
const recorder = new MediaRecorder(stream, { mimeType });
|
|
25503
|
+
mediaRecorderRef.current = recorder;
|
|
25504
|
+
chunksRef.current = [];
|
|
25505
|
+
recorder.ondataavailable = (e) => {
|
|
25506
|
+
if (e.data.size > 0) {
|
|
25507
|
+
chunksRef.current.push(e.data);
|
|
25344
25508
|
}
|
|
25345
|
-
}
|
|
25346
|
-
const _fetch = opts.fetch;
|
|
25347
|
-
const requestInit = {
|
|
25348
|
-
...opts,
|
|
25349
|
-
body: getValidRequestBody(opts)
|
|
25350
25509
|
};
|
|
25351
|
-
|
|
25352
|
-
|
|
25353
|
-
|
|
25354
|
-
|
|
25355
|
-
|
|
25510
|
+
recorder.start();
|
|
25511
|
+
startTimeRef.current = Date.now();
|
|
25512
|
+
setIsRecording(true);
|
|
25513
|
+
} catch (err) {
|
|
25514
|
+
const processedError = err instanceof Error ? err : new Error("Failed to start recording");
|
|
25515
|
+
setError(processedError);
|
|
25516
|
+
throw processedError;
|
|
25517
|
+
}
|
|
25518
|
+
}, []);
|
|
25519
|
+
const stopRecording = (0, import_react13.useCallback)(async () => {
|
|
25520
|
+
return new Promise((resolve, reject) => {
|
|
25521
|
+
const recorder = mediaRecorderRef.current;
|
|
25522
|
+
if (!recorder || recorder.state === "inactive") {
|
|
25523
|
+
const err = new Error("No active recording");
|
|
25524
|
+
setError(err);
|
|
25525
|
+
reject(err);
|
|
25526
|
+
return;
|
|
25356
25527
|
}
|
|
25357
|
-
|
|
25358
|
-
|
|
25528
|
+
recorder.onstop = () => {
|
|
25529
|
+
const mimeType = recorder.mimeType || "audio/webm";
|
|
25530
|
+
const blob = new Blob(chunksRef.current, { type: mimeType });
|
|
25531
|
+
const duration = Date.now() - startTimeRef.current;
|
|
25532
|
+
mediaStreamRef.current?.getTracks().forEach((t) => t.stop());
|
|
25533
|
+
mediaStreamRef.current = null;
|
|
25534
|
+
mediaRecorderRef.current = null;
|
|
25535
|
+
const result = { blob, duration, mimeType };
|
|
25536
|
+
setRecording(result);
|
|
25537
|
+
setIsRecording(false);
|
|
25538
|
+
resolve(result);
|
|
25359
25539
|
};
|
|
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
|
-
};
|
|
25540
|
+
recorder.onerror = () => {
|
|
25541
|
+
const err = new Error("Recording failed");
|
|
25542
|
+
setError(err);
|
|
25543
|
+
setIsRecording(false);
|
|
25544
|
+
reject(err);
|
|
25545
|
+
};
|
|
25546
|
+
recorder.stop();
|
|
25547
|
+
});
|
|
25548
|
+
}, []);
|
|
25549
|
+
const transcribe = (0, import_react13.useCallback)(
|
|
25550
|
+
async (rec) => {
|
|
25551
|
+
const target = rec ?? recording;
|
|
25552
|
+
if (!target) {
|
|
25553
|
+
const err = new Error("No recording to transcribe");
|
|
25554
|
+
setError(err);
|
|
25555
|
+
throw err;
|
|
25417
25556
|
}
|
|
25418
|
-
|
|
25419
|
-
|
|
25557
|
+
setIsTranscribing(true);
|
|
25558
|
+
setError(null);
|
|
25420
25559
|
try {
|
|
25421
|
-
|
|
25422
|
-
|
|
25560
|
+
const pipe = await loadPipeline();
|
|
25561
|
+
const audio = await audioToFloat32(target.blob);
|
|
25562
|
+
const result = await pipe(audio, {
|
|
25563
|
+
language: options?.language,
|
|
25564
|
+
return_timestamps: true
|
|
25565
|
+
});
|
|
25566
|
+
const transcriptionResult = {
|
|
25567
|
+
text: result.text.trim(),
|
|
25568
|
+
chunks: result.chunks
|
|
25569
|
+
};
|
|
25570
|
+
setTranscription(transcriptionResult);
|
|
25571
|
+
return transcriptionResult;
|
|
25572
|
+
} catch (err) {
|
|
25573
|
+
const processedError = err instanceof Error ? err : new Error("Transcription failed");
|
|
25574
|
+
setError(processedError);
|
|
25575
|
+
throw processedError;
|
|
25576
|
+
} finally {
|
|
25577
|
+
setIsTranscribing(false);
|
|
25423
25578
|
}
|
|
25424
|
-
|
|
25425
|
-
|
|
25426
|
-
|
|
25427
|
-
|
|
25428
|
-
|
|
25429
|
-
|
|
25579
|
+
},
|
|
25580
|
+
[recording, loadPipeline, options?.language]
|
|
25581
|
+
);
|
|
25582
|
+
const nativeSpeechAvailable = (0, import_react13.useMemo)(() => getOnDeviceSpeechRecognition() !== null, []);
|
|
25583
|
+
const [isNativeListening, setIsNativeListening] = (0, import_react13.useState)(false);
|
|
25584
|
+
const nativeRecognitionRef = (0, import_react13.useRef)(null);
|
|
25585
|
+
const nativeTextRef = (0, import_react13.useRef)("");
|
|
25586
|
+
const nativeResolveRef = (0, import_react13.useRef)(null);
|
|
25587
|
+
const startNativeTranscription = (0, import_react13.useCallback)(() => {
|
|
25588
|
+
const SR = getOnDeviceSpeechRecognition();
|
|
25589
|
+
if (!SR) return;
|
|
25590
|
+
nativeTextRef.current = "";
|
|
25591
|
+
setError(null);
|
|
25592
|
+
const recognition = new SR();
|
|
25593
|
+
recognition.continuous = true;
|
|
25594
|
+
recognition.interimResults = false;
|
|
25595
|
+
recognition.lang = options?.language ?? "";
|
|
25596
|
+
recognition.onresult = (event) => {
|
|
25597
|
+
let text12 = "";
|
|
25598
|
+
for (let i = 0; i < event.results.length; i++) {
|
|
25599
|
+
const result = event.results[i];
|
|
25600
|
+
if (result && result.isFinal && result[0]) {
|
|
25601
|
+
text12 += result[0].transcript + " ";
|
|
25430
25602
|
}
|
|
25431
25603
|
}
|
|
25432
|
-
|
|
25433
|
-
|
|
25434
|
-
|
|
25604
|
+
nativeTextRef.current = text12.trim();
|
|
25605
|
+
};
|
|
25606
|
+
recognition.onerror = (event) => {
|
|
25607
|
+
if (event.error !== "aborted" && event.error !== "no-speech") {
|
|
25608
|
+
setError(new Error(`Speech recognition error: ${event.error}`));
|
|
25435
25609
|
}
|
|
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
|
|
25610
|
+
};
|
|
25611
|
+
recognition.onend = () => {
|
|
25612
|
+
setIsNativeListening(false);
|
|
25613
|
+
nativeRecognitionRef.current = null;
|
|
25614
|
+
const resolve = nativeResolveRef.current;
|
|
25615
|
+
if (resolve) {
|
|
25616
|
+
nativeResolveRef.current = null;
|
|
25617
|
+
resolve({ text: nativeTextRef.current });
|
|
25618
|
+
}
|
|
25619
|
+
};
|
|
25620
|
+
nativeRecognitionRef.current = recognition;
|
|
25621
|
+
recognition.start();
|
|
25622
|
+
setIsNativeListening(true);
|
|
25623
|
+
}, [options?.language]);
|
|
25624
|
+
const stopNativeTranscription = (0, import_react13.useCallback)(() => {
|
|
25625
|
+
return new Promise((resolve) => {
|
|
25626
|
+
const recognition = nativeRecognitionRef.current;
|
|
25627
|
+
if (!recognition) {
|
|
25628
|
+
resolve({ text: nativeTextRef.current || "" });
|
|
25629
|
+
return;
|
|
25630
|
+
}
|
|
25631
|
+
nativeResolveRef.current = resolve;
|
|
25632
|
+
recognition.stop();
|
|
25462
25633
|
});
|
|
25463
|
-
};
|
|
25464
|
-
const
|
|
25634
|
+
}, []);
|
|
25635
|
+
const abortNativeTranscription = (0, import_react13.useCallback)(() => {
|
|
25636
|
+
const recognition = nativeRecognitionRef.current;
|
|
25637
|
+
if (recognition) {
|
|
25638
|
+
nativeResolveRef.current = null;
|
|
25639
|
+
recognition.abort();
|
|
25640
|
+
nativeRecognitionRef.current = null;
|
|
25641
|
+
setIsNativeListening(false);
|
|
25642
|
+
}
|
|
25643
|
+
}, []);
|
|
25465
25644
|
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")
|
|
25645
|
+
isRecording,
|
|
25646
|
+
startRecording,
|
|
25647
|
+
stopRecording,
|
|
25648
|
+
isTranscribing,
|
|
25649
|
+
transcribe,
|
|
25650
|
+
preloadModel,
|
|
25651
|
+
disposeModel,
|
|
25652
|
+
isModelLoaded,
|
|
25653
|
+
isLoadingModel,
|
|
25654
|
+
recording,
|
|
25655
|
+
transcription,
|
|
25656
|
+
error,
|
|
25657
|
+
nativeSpeechAvailable,
|
|
25658
|
+
startNativeTranscription,
|
|
25659
|
+
stopNativeTranscription,
|
|
25660
|
+
abortNativeTranscription,
|
|
25661
|
+
isNativeListening
|
|
25491
25662
|
};
|
|
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
|
-
});
|
|
25663
|
+
}
|
|
25581
25664
|
|
|
25582
25665
|
// src/react/useCredits.ts
|
|
25666
|
+
var import_react14 = require("react");
|
|
25667
|
+
init_sdk_gen();
|
|
25583
25668
|
init_clientConfig();
|
|
25584
25669
|
function useCredits(options = {}) {
|
|
25585
25670
|
const { getToken, baseUrl = BASE_URL, autoFetch = true, onError } = options;
|
|
@@ -25738,6 +25823,7 @@ function useCredits(options = {}) {
|
|
|
25738
25823
|
|
|
25739
25824
|
// src/react/useModels.ts
|
|
25740
25825
|
var import_react15 = require("react");
|
|
25826
|
+
init_sdk_gen();
|
|
25741
25827
|
init_clientConfig();
|
|
25742
25828
|
function useModels(options = {}) {
|
|
25743
25829
|
const { getToken, baseUrl = BASE_URL, provider, autoFetch = true } = options;
|
|
@@ -25843,6 +25929,7 @@ function useModels(options = {}) {
|
|
|
25843
25929
|
|
|
25844
25930
|
// src/react/usePhoneCalls.ts
|
|
25845
25931
|
var import_react16 = require("react");
|
|
25932
|
+
init_sdk_gen();
|
|
25846
25933
|
init_clientConfig();
|
|
25847
25934
|
var DEFAULT_POLL_INTERVAL_MS = 5e3;
|
|
25848
25935
|
var DEFAULT_POLL_MAX_ATTEMPTS = 60;
|
|
@@ -26142,6 +26229,7 @@ function usePhoneCalls(options = {}) {
|
|
|
26142
26229
|
|
|
26143
26230
|
// src/react/useSubscription.ts
|
|
26144
26231
|
var import_react17 = require("react");
|
|
26232
|
+
init_sdk_gen();
|
|
26145
26233
|
init_clientConfig();
|
|
26146
26234
|
function useSubscription(options = {}) {
|
|
26147
26235
|
const { getToken, baseUrl = BASE_URL, autoFetch = true, onError } = options;
|
|
@@ -26347,6 +26435,7 @@ function useSubscription(options = {}) {
|
|
|
26347
26435
|
|
|
26348
26436
|
// src/react/useWalletBinding.ts
|
|
26349
26437
|
var import_react18 = require("react");
|
|
26438
|
+
init_sdk_gen();
|
|
26350
26439
|
init_clientConfig();
|
|
26351
26440
|
function useWalletBinding(options = {}) {
|
|
26352
26441
|
const { getToken, baseUrl = BASE_URL, autoFetch = true, onError } = options;
|
|
@@ -26530,6 +26619,7 @@ function useWalletBinding(options = {}) {
|
|
|
26530
26619
|
var import_react19 = require("react");
|
|
26531
26620
|
|
|
26532
26621
|
// src/lib/backup/dropbox/auth.ts
|
|
26622
|
+
init_sdk_gen();
|
|
26533
26623
|
init_logger();
|
|
26534
26624
|
|
|
26535
26625
|
// src/lib/backup/oauth/storage.ts
|
|
@@ -27286,6 +27376,7 @@ function useDropboxBackup(options) {
|
|
|
27286
27376
|
var import_react21 = require("react");
|
|
27287
27377
|
|
|
27288
27378
|
// src/lib/backup/google/auth.ts
|
|
27379
|
+
init_sdk_gen();
|
|
27289
27380
|
init_logger();
|
|
27290
27381
|
var PROVIDER2 = "google-drive";
|
|
27291
27382
|
var CODE_STORAGE_KEY = "google_oauth_state";
|
|
@@ -29084,6 +29175,7 @@ function useBackup(options) {
|
|
|
29084
29175
|
}
|
|
29085
29176
|
|
|
29086
29177
|
// src/lib/auth/google-calendar.ts
|
|
29178
|
+
init_sdk_gen();
|
|
29087
29179
|
init_useEncryption();
|
|
29088
29180
|
init_logger();
|
|
29089
29181
|
var PROVIDER3 = "google-drive";
|
|
@@ -29409,6 +29501,7 @@ async function migrateCalendarToken(walletAddress) {
|
|
|
29409
29501
|
}
|
|
29410
29502
|
|
|
29411
29503
|
// src/lib/auth/google-drive.ts
|
|
29504
|
+
init_sdk_gen();
|
|
29412
29505
|
init_useEncryption();
|
|
29413
29506
|
init_logger();
|
|
29414
29507
|
var PROVIDER4 = "google-drive";
|
|
@@ -30285,6 +30378,7 @@ function getNotionMCPUrl() {
|
|
|
30285
30378
|
}
|
|
30286
30379
|
|
|
30287
30380
|
// src/lib/auth/github.ts
|
|
30381
|
+
init_sdk_gen();
|
|
30288
30382
|
init_useEncryption();
|
|
30289
30383
|
init_logger();
|
|
30290
30384
|
var PROVIDER5 = "github";
|