@reverbia/sdk 1.0.0-next.20251208093930 → 1.0.0-next.20251208102554
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/react/{chunk-2WZDKSTC.mjs → chunk-BG7SZT33.mjs} +47 -17
- package/dist/react/index.cjs +193 -45
- package/dist/react/index.d.mts +12 -1
- package/dist/react/index.d.ts +12 -1
- package/dist/react/index.mjs +135 -18
- package/dist/react/{selector-BWDBB4Y5.mjs → selector-XMR5KL3E.mjs} +1 -1
- package/package.json +4 -3
|
@@ -16,27 +16,54 @@ Task: "${userMessage}"
|
|
|
16
16
|
|
|
17
17
|
Best tool:`;
|
|
18
18
|
}
|
|
19
|
-
function
|
|
19
|
+
function buildParamExtractionPrompt(userMessage, paramName, paramDescription) {
|
|
20
|
+
const desc = paramDescription ? ` (${paramDescription})` : "";
|
|
21
|
+
return `Extract the value for "${paramName}"${desc} from the user message. Reply with ONLY the extracted value, nothing else.
|
|
22
|
+
|
|
23
|
+
User message: "${userMessage}"
|
|
24
|
+
|
|
25
|
+
Value for ${paramName}:`;
|
|
26
|
+
}
|
|
27
|
+
async function extractParams(userMessage, tool, options) {
|
|
20
28
|
const params = {};
|
|
21
|
-
if (!tool.parameters) return params;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
if (!tool.parameters || tool.parameters.length === 0) return params;
|
|
30
|
+
const { model, device } = options;
|
|
31
|
+
try {
|
|
32
|
+
const pipeline = await getTextGenerationPipeline({
|
|
33
|
+
model,
|
|
34
|
+
device,
|
|
35
|
+
dtype: "q4"
|
|
36
|
+
});
|
|
37
|
+
for (const param of tool.parameters) {
|
|
38
|
+
const prompt = buildParamExtractionPrompt(
|
|
39
|
+
userMessage,
|
|
40
|
+
param.name,
|
|
41
|
+
param.description
|
|
29
42
|
);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
43
|
+
const output = await pipeline(prompt, {
|
|
44
|
+
max_new_tokens: 32,
|
|
45
|
+
// Allow reasonable length for parameter values
|
|
46
|
+
temperature: 0,
|
|
47
|
+
do_sample: false,
|
|
48
|
+
return_full_text: false
|
|
49
|
+
});
|
|
50
|
+
const generatedText = output?.[0]?.generated_text || output?.generated_text || "";
|
|
51
|
+
const extractedValue = generatedText.trim().split("\n")[0].trim();
|
|
52
|
+
console.log(
|
|
53
|
+
`[Tool Selector] Extracted param "${param.name}":`,
|
|
54
|
+
extractedValue
|
|
55
|
+
);
|
|
56
|
+
params[param.name] = extractedValue || userMessage;
|
|
57
|
+
}
|
|
58
|
+
} catch (error) {
|
|
59
|
+
console.error("[Tool Selector] Error extracting params:", error);
|
|
60
|
+
for (const param of tool.parameters) {
|
|
34
61
|
params[param.name] = userMessage;
|
|
35
62
|
}
|
|
36
63
|
}
|
|
37
64
|
return params;
|
|
38
65
|
}
|
|
39
|
-
function parseToolSelectionResponse(response, tools, userMessage) {
|
|
66
|
+
async function parseToolSelectionResponse(response, tools, userMessage, options) {
|
|
40
67
|
console.log("[Tool Selector] Raw response:", response);
|
|
41
68
|
const cleaned = response.toLowerCase().trim().split(/[\s\n,.]+/)[0].replace(/[^a-z0-9_-]/g, "");
|
|
42
69
|
console.log("[Tool Selector] Parsed tool name:", cleaned);
|
|
@@ -51,7 +78,7 @@ function parseToolSelectionResponse(response, tools, userMessage) {
|
|
|
51
78
|
);
|
|
52
79
|
if (fuzzyTool) {
|
|
53
80
|
console.log(`[Tool Selector] Fuzzy matched tool: ${fuzzyTool.name}`);
|
|
54
|
-
const params2 = extractParams(userMessage, fuzzyTool);
|
|
81
|
+
const params2 = await extractParams(userMessage, fuzzyTool, options);
|
|
55
82
|
return {
|
|
56
83
|
toolSelected: true,
|
|
57
84
|
toolName: fuzzyTool.name,
|
|
@@ -62,7 +89,7 @@ function parseToolSelectionResponse(response, tools, userMessage) {
|
|
|
62
89
|
console.warn(`[Tool Selector] Unknown tool: ${cleaned}`);
|
|
63
90
|
return { toolSelected: false };
|
|
64
91
|
}
|
|
65
|
-
const params = extractParams(userMessage, selectedTool);
|
|
92
|
+
const params = await extractParams(userMessage, selectedTool, options);
|
|
66
93
|
console.log(`[Tool Selector] Selected tool: ${selectedTool.name}`, params);
|
|
67
94
|
return {
|
|
68
95
|
toolSelected: true,
|
|
@@ -103,7 +130,10 @@ async function selectTool(userMessage, tools, options = {}) {
|
|
|
103
130
|
return { toolSelected: false };
|
|
104
131
|
}
|
|
105
132
|
const generatedText = output?.[0]?.generated_text || output?.generated_text || "";
|
|
106
|
-
return parseToolSelectionResponse(generatedText, tools, userMessage
|
|
133
|
+
return await parseToolSelectionResponse(generatedText, tools, userMessage, {
|
|
134
|
+
model,
|
|
135
|
+
device
|
|
136
|
+
});
|
|
107
137
|
} catch (error) {
|
|
108
138
|
console.error("[Tool Selector] Error:", error);
|
|
109
139
|
return { toolSelected: false };
|
package/dist/react/index.cjs
CHANGED
|
@@ -47215,27 +47215,54 @@ Task: "${userMessage}"
|
|
|
47215
47215
|
|
|
47216
47216
|
Best tool:`;
|
|
47217
47217
|
}
|
|
47218
|
-
function
|
|
47218
|
+
function buildParamExtractionPrompt(userMessage, paramName, paramDescription) {
|
|
47219
|
+
const desc = paramDescription ? ` (${paramDescription})` : "";
|
|
47220
|
+
return `Extract the value for "${paramName}"${desc} from the user message. Reply with ONLY the extracted value, nothing else.
|
|
47221
|
+
|
|
47222
|
+
User message: "${userMessage}"
|
|
47223
|
+
|
|
47224
|
+
Value for ${paramName}:`;
|
|
47225
|
+
}
|
|
47226
|
+
async function extractParams(userMessage, tool, options) {
|
|
47219
47227
|
const params = {};
|
|
47220
|
-
if (!tool.parameters) return params;
|
|
47221
|
-
|
|
47222
|
-
|
|
47223
|
-
|
|
47224
|
-
|
|
47225
|
-
|
|
47226
|
-
|
|
47227
|
-
|
|
47228
|
+
if (!tool.parameters || tool.parameters.length === 0) return params;
|
|
47229
|
+
const { model, device } = options;
|
|
47230
|
+
try {
|
|
47231
|
+
const pipeline = await getTextGenerationPipeline({
|
|
47232
|
+
model,
|
|
47233
|
+
device,
|
|
47234
|
+
dtype: "q4"
|
|
47235
|
+
});
|
|
47236
|
+
for (const param of tool.parameters) {
|
|
47237
|
+
const prompt = buildParamExtractionPrompt(
|
|
47238
|
+
userMessage,
|
|
47239
|
+
param.name,
|
|
47240
|
+
param.description
|
|
47228
47241
|
);
|
|
47229
|
-
|
|
47230
|
-
|
|
47231
|
-
|
|
47232
|
-
|
|
47242
|
+
const output = await pipeline(prompt, {
|
|
47243
|
+
max_new_tokens: 32,
|
|
47244
|
+
// Allow reasonable length for parameter values
|
|
47245
|
+
temperature: 0,
|
|
47246
|
+
do_sample: false,
|
|
47247
|
+
return_full_text: false
|
|
47248
|
+
});
|
|
47249
|
+
const generatedText = output?.[0]?.generated_text || output?.generated_text || "";
|
|
47250
|
+
const extractedValue = generatedText.trim().split("\n")[0].trim();
|
|
47251
|
+
console.log(
|
|
47252
|
+
`[Tool Selector] Extracted param "${param.name}":`,
|
|
47253
|
+
extractedValue
|
|
47254
|
+
);
|
|
47255
|
+
params[param.name] = extractedValue || userMessage;
|
|
47256
|
+
}
|
|
47257
|
+
} catch (error) {
|
|
47258
|
+
console.error("[Tool Selector] Error extracting params:", error);
|
|
47259
|
+
for (const param of tool.parameters) {
|
|
47233
47260
|
params[param.name] = userMessage;
|
|
47234
47261
|
}
|
|
47235
47262
|
}
|
|
47236
47263
|
return params;
|
|
47237
47264
|
}
|
|
47238
|
-
function parseToolSelectionResponse(response, tools, userMessage) {
|
|
47265
|
+
async function parseToolSelectionResponse(response, tools, userMessage, options) {
|
|
47239
47266
|
console.log("[Tool Selector] Raw response:", response);
|
|
47240
47267
|
const cleaned = response.toLowerCase().trim().split(/[\s\n,.]+/)[0].replace(/[^a-z0-9_-]/g, "");
|
|
47241
47268
|
console.log("[Tool Selector] Parsed tool name:", cleaned);
|
|
@@ -47250,7 +47277,7 @@ function parseToolSelectionResponse(response, tools, userMessage) {
|
|
|
47250
47277
|
);
|
|
47251
47278
|
if (fuzzyTool) {
|
|
47252
47279
|
console.log(`[Tool Selector] Fuzzy matched tool: ${fuzzyTool.name}`);
|
|
47253
|
-
const params2 = extractParams(userMessage, fuzzyTool);
|
|
47280
|
+
const params2 = await extractParams(userMessage, fuzzyTool, options);
|
|
47254
47281
|
return {
|
|
47255
47282
|
toolSelected: true,
|
|
47256
47283
|
toolName: fuzzyTool.name,
|
|
@@ -47261,7 +47288,7 @@ function parseToolSelectionResponse(response, tools, userMessage) {
|
|
|
47261
47288
|
console.warn(`[Tool Selector] Unknown tool: ${cleaned}`);
|
|
47262
47289
|
return { toolSelected: false };
|
|
47263
47290
|
}
|
|
47264
|
-
const params = extractParams(userMessage, selectedTool);
|
|
47291
|
+
const params = await extractParams(userMessage, selectedTool, options);
|
|
47265
47292
|
console.log(`[Tool Selector] Selected tool: ${selectedTool.name}`, params);
|
|
47266
47293
|
return {
|
|
47267
47294
|
toolSelected: true,
|
|
@@ -47302,7 +47329,10 @@ async function selectTool(userMessage, tools, options = {}) {
|
|
|
47302
47329
|
return { toolSelected: false };
|
|
47303
47330
|
}
|
|
47304
47331
|
const generatedText = output?.[0]?.generated_text || output?.generated_text || "";
|
|
47305
|
-
return parseToolSelectionResponse(generatedText, tools, userMessage
|
|
47332
|
+
return await parseToolSelectionResponse(generatedText, tools, userMessage, {
|
|
47333
|
+
model,
|
|
47334
|
+
device
|
|
47335
|
+
});
|
|
47306
47336
|
} catch (error) {
|
|
47307
47337
|
console.error("[Tool Selector] Error:", error);
|
|
47308
47338
|
return { toolSelected: false };
|
|
@@ -47370,6 +47400,7 @@ __export(index_exports, {
|
|
|
47370
47400
|
useImageGeneration: () => useImageGeneration,
|
|
47371
47401
|
useMemory: () => useMemory,
|
|
47372
47402
|
useModels: () => useModels,
|
|
47403
|
+
useOCR: () => useOCR,
|
|
47373
47404
|
usePdf: () => usePdf,
|
|
47374
47405
|
useSearch: () => useSearch
|
|
47375
47406
|
});
|
|
@@ -49409,6 +49440,31 @@ async function extractTextFromPdf(pdfDataUrl) {
|
|
|
49409
49440
|
throw error;
|
|
49410
49441
|
}
|
|
49411
49442
|
}
|
|
49443
|
+
async function convertPdfToImages(pdfDataUrl) {
|
|
49444
|
+
const images = [];
|
|
49445
|
+
try {
|
|
49446
|
+
const loadingTask = pdfjs.getDocument(pdfDataUrl);
|
|
49447
|
+
const pdf = await loadingTask.promise;
|
|
49448
|
+
for (let i = 1; i <= pdf.numPages; i++) {
|
|
49449
|
+
const page = await pdf.getPage(i);
|
|
49450
|
+
const viewport = page.getViewport({ scale: 1.5 });
|
|
49451
|
+
const canvas = document.createElement("canvas");
|
|
49452
|
+
const context = canvas.getContext("2d");
|
|
49453
|
+
if (!context) continue;
|
|
49454
|
+
canvas.height = viewport.height;
|
|
49455
|
+
canvas.width = viewport.width;
|
|
49456
|
+
await page.render({
|
|
49457
|
+
canvasContext: context,
|
|
49458
|
+
viewport
|
|
49459
|
+
}).promise;
|
|
49460
|
+
images.push(canvas.toDataURL("image/png"));
|
|
49461
|
+
}
|
|
49462
|
+
} catch (error) {
|
|
49463
|
+
console.error("Error converting PDF to images:", error);
|
|
49464
|
+
throw error;
|
|
49465
|
+
}
|
|
49466
|
+
return images;
|
|
49467
|
+
}
|
|
49412
49468
|
|
|
49413
49469
|
// src/react/usePdf.ts
|
|
49414
49470
|
var PDF_MIME_TYPE = "application/pdf";
|
|
@@ -49461,23 +49517,114 @@ ${text}`;
|
|
|
49461
49517
|
};
|
|
49462
49518
|
}
|
|
49463
49519
|
|
|
49464
|
-
// src/react/
|
|
49520
|
+
// src/react/useOCR.ts
|
|
49465
49521
|
var import_react4 = require("react");
|
|
49522
|
+
var import_tesseract = __toESM(require("tesseract.js"));
|
|
49523
|
+
function useOCR() {
|
|
49524
|
+
const [isProcessing, setIsProcessing] = (0, import_react4.useState)(false);
|
|
49525
|
+
const [error, setError] = (0, import_react4.useState)(null);
|
|
49526
|
+
const extractOCRContext = (0, import_react4.useCallback)(
|
|
49527
|
+
async (files) => {
|
|
49528
|
+
setIsProcessing(true);
|
|
49529
|
+
setError(null);
|
|
49530
|
+
try {
|
|
49531
|
+
if (files.length === 0) {
|
|
49532
|
+
return null;
|
|
49533
|
+
}
|
|
49534
|
+
const contexts = await Promise.all(
|
|
49535
|
+
files.map(async (file) => {
|
|
49536
|
+
try {
|
|
49537
|
+
let imagesToProcess = [];
|
|
49538
|
+
const language = file.language || "eng";
|
|
49539
|
+
const filename = file.filename || (file.url instanceof File ? file.url.name : "");
|
|
49540
|
+
let isPdf = false;
|
|
49541
|
+
if (typeof file.url === "string") {
|
|
49542
|
+
isPdf = file.url.toLowerCase().endsWith(".pdf") || (filename?.toLowerCase().endsWith(".pdf") ?? false);
|
|
49543
|
+
} else if (file.url instanceof Blob) {
|
|
49544
|
+
isPdf = file.url.type === "application/pdf" || (filename?.toLowerCase().endsWith(".pdf") ?? false);
|
|
49545
|
+
}
|
|
49546
|
+
if (isPdf) {
|
|
49547
|
+
let pdfUrl;
|
|
49548
|
+
let shouldRevoke = false;
|
|
49549
|
+
if (typeof file.url === "string") {
|
|
49550
|
+
pdfUrl = file.url;
|
|
49551
|
+
} else {
|
|
49552
|
+
pdfUrl = URL.createObjectURL(file.url);
|
|
49553
|
+
shouldRevoke = true;
|
|
49554
|
+
}
|
|
49555
|
+
try {
|
|
49556
|
+
const pdfImages = await convertPdfToImages(pdfUrl);
|
|
49557
|
+
imagesToProcess = pdfImages;
|
|
49558
|
+
} catch (e) {
|
|
49559
|
+
console.error("Failed to convert PDF to images", e);
|
|
49560
|
+
throw e;
|
|
49561
|
+
} finally {
|
|
49562
|
+
if (shouldRevoke) {
|
|
49563
|
+
URL.revokeObjectURL(pdfUrl);
|
|
49564
|
+
}
|
|
49565
|
+
}
|
|
49566
|
+
} else {
|
|
49567
|
+
imagesToProcess = [file.url];
|
|
49568
|
+
}
|
|
49569
|
+
const pageTexts = [];
|
|
49570
|
+
for (const image of imagesToProcess) {
|
|
49571
|
+
const result = await import_tesseract.default.recognize(image, language);
|
|
49572
|
+
pageTexts.push(result.data.text);
|
|
49573
|
+
}
|
|
49574
|
+
const text = pageTexts.join("\n\n");
|
|
49575
|
+
if (!text.trim()) {
|
|
49576
|
+
console.warn(
|
|
49577
|
+
`No text found in OCR source ${filename || "unknown"}`
|
|
49578
|
+
);
|
|
49579
|
+
return null;
|
|
49580
|
+
}
|
|
49581
|
+
return `[Context from OCR attachment ${filename || "unknown"}]:
|
|
49582
|
+
${text}`;
|
|
49583
|
+
} catch (err) {
|
|
49584
|
+
console.error(
|
|
49585
|
+
`Failed to process OCR for ${file.filename || "unknown"}:`,
|
|
49586
|
+
err
|
|
49587
|
+
);
|
|
49588
|
+
return null;
|
|
49589
|
+
}
|
|
49590
|
+
})
|
|
49591
|
+
);
|
|
49592
|
+
const mergedContext = contexts.filter(Boolean).join("\n\n");
|
|
49593
|
+
return mergedContext || null;
|
|
49594
|
+
} catch (err) {
|
|
49595
|
+
const processedError = err instanceof Error ? err : new Error(String(err));
|
|
49596
|
+
setError(processedError);
|
|
49597
|
+
throw processedError;
|
|
49598
|
+
} finally {
|
|
49599
|
+
setIsProcessing(false);
|
|
49600
|
+
}
|
|
49601
|
+
},
|
|
49602
|
+
[]
|
|
49603
|
+
);
|
|
49604
|
+
return {
|
|
49605
|
+
extractOCRContext,
|
|
49606
|
+
isProcessing,
|
|
49607
|
+
error
|
|
49608
|
+
};
|
|
49609
|
+
}
|
|
49610
|
+
|
|
49611
|
+
// src/react/useModels.ts
|
|
49612
|
+
var import_react5 = require("react");
|
|
49466
49613
|
function useModels(options = {}) {
|
|
49467
49614
|
const { getToken, baseUrl = BASE_URL, provider, autoFetch = true } = options;
|
|
49468
|
-
const [models, setModels] = (0,
|
|
49469
|
-
const [isLoading, setIsLoading] = (0,
|
|
49470
|
-
const [error, setError] = (0,
|
|
49471
|
-
const getTokenRef = (0,
|
|
49472
|
-
const baseUrlRef = (0,
|
|
49473
|
-
const providerRef = (0,
|
|
49474
|
-
const abortControllerRef = (0,
|
|
49475
|
-
(0,
|
|
49615
|
+
const [models, setModels] = (0, import_react5.useState)([]);
|
|
49616
|
+
const [isLoading, setIsLoading] = (0, import_react5.useState)(false);
|
|
49617
|
+
const [error, setError] = (0, import_react5.useState)(null);
|
|
49618
|
+
const getTokenRef = (0, import_react5.useRef)(getToken);
|
|
49619
|
+
const baseUrlRef = (0, import_react5.useRef)(baseUrl);
|
|
49620
|
+
const providerRef = (0, import_react5.useRef)(provider);
|
|
49621
|
+
const abortControllerRef = (0, import_react5.useRef)(null);
|
|
49622
|
+
(0, import_react5.useEffect)(() => {
|
|
49476
49623
|
getTokenRef.current = getToken;
|
|
49477
49624
|
baseUrlRef.current = baseUrl;
|
|
49478
49625
|
providerRef.current = provider;
|
|
49479
49626
|
});
|
|
49480
|
-
(0,
|
|
49627
|
+
(0, import_react5.useEffect)(() => {
|
|
49481
49628
|
return () => {
|
|
49482
49629
|
if (abortControllerRef.current) {
|
|
49483
49630
|
abortControllerRef.current.abort();
|
|
@@ -49485,7 +49632,7 @@ function useModels(options = {}) {
|
|
|
49485
49632
|
}
|
|
49486
49633
|
};
|
|
49487
49634
|
}, []);
|
|
49488
|
-
const fetchModels = (0,
|
|
49635
|
+
const fetchModels = (0, import_react5.useCallback)(async () => {
|
|
49489
49636
|
if (abortControllerRef.current) {
|
|
49490
49637
|
abortControllerRef.current.abort();
|
|
49491
49638
|
}
|
|
@@ -49543,12 +49690,12 @@ function useModels(options = {}) {
|
|
|
49543
49690
|
}
|
|
49544
49691
|
}
|
|
49545
49692
|
}, []);
|
|
49546
|
-
const refetch = (0,
|
|
49693
|
+
const refetch = (0, import_react5.useCallback)(async () => {
|
|
49547
49694
|
setModels([]);
|
|
49548
49695
|
await fetchModels();
|
|
49549
49696
|
}, [fetchModels]);
|
|
49550
|
-
const hasFetchedRef = (0,
|
|
49551
|
-
(0,
|
|
49697
|
+
const hasFetchedRef = (0, import_react5.useRef)(false);
|
|
49698
|
+
(0, import_react5.useEffect)(() => {
|
|
49552
49699
|
if (autoFetch && !hasFetchedRef.current) {
|
|
49553
49700
|
hasFetchedRef.current = true;
|
|
49554
49701
|
fetchModels();
|
|
@@ -49566,15 +49713,15 @@ function useModels(options = {}) {
|
|
|
49566
49713
|
}
|
|
49567
49714
|
|
|
49568
49715
|
// src/react/useSearch.ts
|
|
49569
|
-
var
|
|
49716
|
+
var import_react6 = require("react");
|
|
49570
49717
|
function useSearch(options = {}) {
|
|
49571
49718
|
const { getToken, baseUrl = BASE_URL, onError } = options;
|
|
49572
|
-
const [isLoading, setIsLoading] = (0,
|
|
49573
|
-
const [results, setResults] = (0,
|
|
49574
|
-
const [response, setResponse] = (0,
|
|
49575
|
-
const [error, setError] = (0,
|
|
49576
|
-
const abortControllerRef = (0,
|
|
49577
|
-
(0,
|
|
49719
|
+
const [isLoading, setIsLoading] = (0, import_react6.useState)(false);
|
|
49720
|
+
const [results, setResults] = (0, import_react6.useState)(null);
|
|
49721
|
+
const [response, setResponse] = (0, import_react6.useState)(null);
|
|
49722
|
+
const [error, setError] = (0, import_react6.useState)(null);
|
|
49723
|
+
const abortControllerRef = (0, import_react6.useRef)(null);
|
|
49724
|
+
(0, import_react6.useEffect)(() => {
|
|
49578
49725
|
return () => {
|
|
49579
49726
|
if (abortControllerRef.current) {
|
|
49580
49727
|
abortControllerRef.current.abort();
|
|
@@ -49582,7 +49729,7 @@ function useSearch(options = {}) {
|
|
|
49582
49729
|
}
|
|
49583
49730
|
};
|
|
49584
49731
|
}, []);
|
|
49585
|
-
const search = (0,
|
|
49732
|
+
const search = (0, import_react6.useCallback)(
|
|
49586
49733
|
async (query, searchOptions = {}) => {
|
|
49587
49734
|
if (abortControllerRef.current) {
|
|
49588
49735
|
abortControllerRef.current.abort();
|
|
@@ -49650,12 +49797,12 @@ function useSearch(options = {}) {
|
|
|
49650
49797
|
}
|
|
49651
49798
|
|
|
49652
49799
|
// src/react/useImageGeneration.ts
|
|
49653
|
-
var
|
|
49800
|
+
var import_react7 = require("react");
|
|
49654
49801
|
function useImageGeneration(options = {}) {
|
|
49655
49802
|
const { getToken, baseUrl = BASE_URL, onFinish, onError } = options;
|
|
49656
|
-
const [isLoading, setIsLoading] = (0,
|
|
49657
|
-
const abortControllerRef = (0,
|
|
49658
|
-
(0,
|
|
49803
|
+
const [isLoading, setIsLoading] = (0, import_react7.useState)(false);
|
|
49804
|
+
const abortControllerRef = (0, import_react7.useRef)(null);
|
|
49805
|
+
(0, import_react7.useEffect)(() => {
|
|
49659
49806
|
return () => {
|
|
49660
49807
|
if (abortControllerRef.current) {
|
|
49661
49808
|
abortControllerRef.current.abort();
|
|
@@ -49663,13 +49810,13 @@ function useImageGeneration(options = {}) {
|
|
|
49663
49810
|
}
|
|
49664
49811
|
};
|
|
49665
49812
|
}, []);
|
|
49666
|
-
const stop = (0,
|
|
49813
|
+
const stop = (0, import_react7.useCallback)(() => {
|
|
49667
49814
|
if (abortControllerRef.current) {
|
|
49668
49815
|
abortControllerRef.current.abort();
|
|
49669
49816
|
abortControllerRef.current = null;
|
|
49670
49817
|
}
|
|
49671
49818
|
}, []);
|
|
49672
|
-
const generateImage = (0,
|
|
49819
|
+
const generateImage = (0, import_react7.useCallback)(
|
|
49673
49820
|
async (args) => {
|
|
49674
49821
|
if (abortControllerRef.current) {
|
|
49675
49822
|
abortControllerRef.current.abort();
|
|
@@ -49806,6 +49953,7 @@ init_selector();
|
|
|
49806
49953
|
useImageGeneration,
|
|
49807
49954
|
useMemory,
|
|
49808
49955
|
useModels,
|
|
49956
|
+
useOCR,
|
|
49809
49957
|
usePdf,
|
|
49810
49958
|
useSearch
|
|
49811
49959
|
});
|
package/dist/react/index.d.mts
CHANGED
|
@@ -722,6 +722,17 @@ declare function usePdf(): {
|
|
|
722
722
|
error: Error | null;
|
|
723
723
|
};
|
|
724
724
|
|
|
725
|
+
interface OCRFile {
|
|
726
|
+
url: string | File | Blob;
|
|
727
|
+
filename?: string;
|
|
728
|
+
language?: string;
|
|
729
|
+
}
|
|
730
|
+
declare function useOCR(): {
|
|
731
|
+
extractOCRContext: (files: OCRFile[]) => Promise<string | null>;
|
|
732
|
+
isProcessing: boolean;
|
|
733
|
+
error: Error | null;
|
|
734
|
+
};
|
|
735
|
+
|
|
725
736
|
type UseModelsOptions = {
|
|
726
737
|
/**
|
|
727
738
|
* Custom function to get auth token for API calls
|
|
@@ -880,4 +891,4 @@ declare function executeTool(tool: ClientTool, params: Record<string, unknown>):
|
|
|
880
891
|
error?: string;
|
|
881
892
|
}>;
|
|
882
893
|
|
|
883
|
-
export { type ClientTool, DEFAULT_TOOL_SELECTOR_MODEL, type PdfFile, type SignMessageFn, type ToolExecutionResult, type ToolParameter, type ToolSelectionResult, createMemoryContextSystemMessage, decryptData, decryptDataBytes, encryptData, executeTool, extractConversationContext, formatMemoriesForChat, hasEncryptionKey, requestEncryptionKey, selectTool, useChat, useEncryption, useImageGeneration, useMemory, useModels, usePdf, useSearch };
|
|
894
|
+
export { type ClientTool, DEFAULT_TOOL_SELECTOR_MODEL, type OCRFile, type PdfFile, type SignMessageFn, type ToolExecutionResult, type ToolParameter, type ToolSelectionResult, createMemoryContextSystemMessage, decryptData, decryptDataBytes, encryptData, executeTool, extractConversationContext, formatMemoriesForChat, hasEncryptionKey, requestEncryptionKey, selectTool, useChat, useEncryption, useImageGeneration, useMemory, useModels, useOCR, usePdf, useSearch };
|
package/dist/react/index.d.ts
CHANGED
|
@@ -722,6 +722,17 @@ declare function usePdf(): {
|
|
|
722
722
|
error: Error | null;
|
|
723
723
|
};
|
|
724
724
|
|
|
725
|
+
interface OCRFile {
|
|
726
|
+
url: string | File | Blob;
|
|
727
|
+
filename?: string;
|
|
728
|
+
language?: string;
|
|
729
|
+
}
|
|
730
|
+
declare function useOCR(): {
|
|
731
|
+
extractOCRContext: (files: OCRFile[]) => Promise<string | null>;
|
|
732
|
+
isProcessing: boolean;
|
|
733
|
+
error: Error | null;
|
|
734
|
+
};
|
|
735
|
+
|
|
725
736
|
type UseModelsOptions = {
|
|
726
737
|
/**
|
|
727
738
|
* Custom function to get auth token for API calls
|
|
@@ -880,4 +891,4 @@ declare function executeTool(tool: ClientTool, params: Record<string, unknown>):
|
|
|
880
891
|
error?: string;
|
|
881
892
|
}>;
|
|
882
893
|
|
|
883
|
-
export { type ClientTool, DEFAULT_TOOL_SELECTOR_MODEL, type PdfFile, type SignMessageFn, type ToolExecutionResult, type ToolParameter, type ToolSelectionResult, createMemoryContextSystemMessage, decryptData, decryptDataBytes, encryptData, executeTool, extractConversationContext, formatMemoriesForChat, hasEncryptionKey, requestEncryptionKey, selectTool, useChat, useEncryption, useImageGeneration, useMemory, useModels, usePdf, useSearch };
|
|
894
|
+
export { type ClientTool, DEFAULT_TOOL_SELECTOR_MODEL, type OCRFile, type PdfFile, type SignMessageFn, type ToolExecutionResult, type ToolParameter, type ToolSelectionResult, createMemoryContextSystemMessage, decryptData, decryptDataBytes, encryptData, executeTool, extractConversationContext, formatMemoriesForChat, hasEncryptionKey, requestEncryptionKey, selectTool, useChat, useEncryption, useImageGeneration, useMemory, useModels, useOCR, usePdf, useSearch };
|
package/dist/react/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
DEFAULT_TOOL_SELECTOR_MODEL,
|
|
3
3
|
executeTool,
|
|
4
4
|
selectTool
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-BG7SZT33.mjs";
|
|
6
6
|
import "./chunk-Q6FVPTTV.mjs";
|
|
7
7
|
import "./chunk-FBCDBTKJ.mjs";
|
|
8
8
|
|
|
@@ -862,7 +862,7 @@ var webFeatures = null;
|
|
|
862
862
|
var webFeaturesPromise = isReactNative ? Promise.resolve(null) : Promise.all([
|
|
863
863
|
import("./generation-NG4QVPCR.mjs"),
|
|
864
864
|
import("./constants-WUGUGYE3.mjs"),
|
|
865
|
-
import("./selector-
|
|
865
|
+
import("./selector-XMR5KL3E.mjs")
|
|
866
866
|
]).then(([generation, constants, selector]) => {
|
|
867
867
|
webFeatures = {
|
|
868
868
|
generateLocalChatCompletion: generation.generateLocalChatCompletion,
|
|
@@ -2040,6 +2040,31 @@ async function extractTextFromPdf(pdfDataUrl) {
|
|
|
2040
2040
|
throw error;
|
|
2041
2041
|
}
|
|
2042
2042
|
}
|
|
2043
|
+
async function convertPdfToImages(pdfDataUrl) {
|
|
2044
|
+
const images = [];
|
|
2045
|
+
try {
|
|
2046
|
+
const loadingTask = pdfjs.getDocument(pdfDataUrl);
|
|
2047
|
+
const pdf = await loadingTask.promise;
|
|
2048
|
+
for (let i = 1; i <= pdf.numPages; i++) {
|
|
2049
|
+
const page = await pdf.getPage(i);
|
|
2050
|
+
const viewport = page.getViewport({ scale: 1.5 });
|
|
2051
|
+
const canvas = document.createElement("canvas");
|
|
2052
|
+
const context = canvas.getContext("2d");
|
|
2053
|
+
if (!context) continue;
|
|
2054
|
+
canvas.height = viewport.height;
|
|
2055
|
+
canvas.width = viewport.width;
|
|
2056
|
+
await page.render({
|
|
2057
|
+
canvasContext: context,
|
|
2058
|
+
viewport
|
|
2059
|
+
}).promise;
|
|
2060
|
+
images.push(canvas.toDataURL("image/png"));
|
|
2061
|
+
}
|
|
2062
|
+
} catch (error) {
|
|
2063
|
+
console.error("Error converting PDF to images:", error);
|
|
2064
|
+
throw error;
|
|
2065
|
+
}
|
|
2066
|
+
return images;
|
|
2067
|
+
}
|
|
2043
2068
|
|
|
2044
2069
|
// src/react/usePdf.ts
|
|
2045
2070
|
var PDF_MIME_TYPE = "application/pdf";
|
|
@@ -2092,13 +2117,104 @@ ${text}`;
|
|
|
2092
2117
|
};
|
|
2093
2118
|
}
|
|
2094
2119
|
|
|
2120
|
+
// src/react/useOCR.ts
|
|
2121
|
+
import { useCallback as useCallback4, useState as useState3 } from "react";
|
|
2122
|
+
import Tesseract from "tesseract.js";
|
|
2123
|
+
function useOCR() {
|
|
2124
|
+
const [isProcessing, setIsProcessing] = useState3(false);
|
|
2125
|
+
const [error, setError] = useState3(null);
|
|
2126
|
+
const extractOCRContext = useCallback4(
|
|
2127
|
+
async (files) => {
|
|
2128
|
+
setIsProcessing(true);
|
|
2129
|
+
setError(null);
|
|
2130
|
+
try {
|
|
2131
|
+
if (files.length === 0) {
|
|
2132
|
+
return null;
|
|
2133
|
+
}
|
|
2134
|
+
const contexts = await Promise.all(
|
|
2135
|
+
files.map(async (file) => {
|
|
2136
|
+
try {
|
|
2137
|
+
let imagesToProcess = [];
|
|
2138
|
+
const language = file.language || "eng";
|
|
2139
|
+
const filename = file.filename || (file.url instanceof File ? file.url.name : "");
|
|
2140
|
+
let isPdf = false;
|
|
2141
|
+
if (typeof file.url === "string") {
|
|
2142
|
+
isPdf = file.url.toLowerCase().endsWith(".pdf") || (filename?.toLowerCase().endsWith(".pdf") ?? false);
|
|
2143
|
+
} else if (file.url instanceof Blob) {
|
|
2144
|
+
isPdf = file.url.type === "application/pdf" || (filename?.toLowerCase().endsWith(".pdf") ?? false);
|
|
2145
|
+
}
|
|
2146
|
+
if (isPdf) {
|
|
2147
|
+
let pdfUrl;
|
|
2148
|
+
let shouldRevoke = false;
|
|
2149
|
+
if (typeof file.url === "string") {
|
|
2150
|
+
pdfUrl = file.url;
|
|
2151
|
+
} else {
|
|
2152
|
+
pdfUrl = URL.createObjectURL(file.url);
|
|
2153
|
+
shouldRevoke = true;
|
|
2154
|
+
}
|
|
2155
|
+
try {
|
|
2156
|
+
const pdfImages = await convertPdfToImages(pdfUrl);
|
|
2157
|
+
imagesToProcess = pdfImages;
|
|
2158
|
+
} catch (e) {
|
|
2159
|
+
console.error("Failed to convert PDF to images", e);
|
|
2160
|
+
throw e;
|
|
2161
|
+
} finally {
|
|
2162
|
+
if (shouldRevoke) {
|
|
2163
|
+
URL.revokeObjectURL(pdfUrl);
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
} else {
|
|
2167
|
+
imagesToProcess = [file.url];
|
|
2168
|
+
}
|
|
2169
|
+
const pageTexts = [];
|
|
2170
|
+
for (const image of imagesToProcess) {
|
|
2171
|
+
const result = await Tesseract.recognize(image, language);
|
|
2172
|
+
pageTexts.push(result.data.text);
|
|
2173
|
+
}
|
|
2174
|
+
const text = pageTexts.join("\n\n");
|
|
2175
|
+
if (!text.trim()) {
|
|
2176
|
+
console.warn(
|
|
2177
|
+
`No text found in OCR source ${filename || "unknown"}`
|
|
2178
|
+
);
|
|
2179
|
+
return null;
|
|
2180
|
+
}
|
|
2181
|
+
return `[Context from OCR attachment ${filename || "unknown"}]:
|
|
2182
|
+
${text}`;
|
|
2183
|
+
} catch (err) {
|
|
2184
|
+
console.error(
|
|
2185
|
+
`Failed to process OCR for ${file.filename || "unknown"}:`,
|
|
2186
|
+
err
|
|
2187
|
+
);
|
|
2188
|
+
return null;
|
|
2189
|
+
}
|
|
2190
|
+
})
|
|
2191
|
+
);
|
|
2192
|
+
const mergedContext = contexts.filter(Boolean).join("\n\n");
|
|
2193
|
+
return mergedContext || null;
|
|
2194
|
+
} catch (err) {
|
|
2195
|
+
const processedError = err instanceof Error ? err : new Error(String(err));
|
|
2196
|
+
setError(processedError);
|
|
2197
|
+
throw processedError;
|
|
2198
|
+
} finally {
|
|
2199
|
+
setIsProcessing(false);
|
|
2200
|
+
}
|
|
2201
|
+
},
|
|
2202
|
+
[]
|
|
2203
|
+
);
|
|
2204
|
+
return {
|
|
2205
|
+
extractOCRContext,
|
|
2206
|
+
isProcessing,
|
|
2207
|
+
error
|
|
2208
|
+
};
|
|
2209
|
+
}
|
|
2210
|
+
|
|
2095
2211
|
// src/react/useModels.ts
|
|
2096
|
-
import { useCallback as
|
|
2212
|
+
import { useCallback as useCallback5, useEffect as useEffect2, useRef as useRef3, useState as useState4 } from "react";
|
|
2097
2213
|
function useModels(options = {}) {
|
|
2098
2214
|
const { getToken, baseUrl = BASE_URL, provider, autoFetch = true } = options;
|
|
2099
|
-
const [models, setModels] =
|
|
2100
|
-
const [isLoading, setIsLoading] =
|
|
2101
|
-
const [error, setError] =
|
|
2215
|
+
const [models, setModels] = useState4([]);
|
|
2216
|
+
const [isLoading, setIsLoading] = useState4(false);
|
|
2217
|
+
const [error, setError] = useState4(null);
|
|
2102
2218
|
const getTokenRef = useRef3(getToken);
|
|
2103
2219
|
const baseUrlRef = useRef3(baseUrl);
|
|
2104
2220
|
const providerRef = useRef3(provider);
|
|
@@ -2116,7 +2232,7 @@ function useModels(options = {}) {
|
|
|
2116
2232
|
}
|
|
2117
2233
|
};
|
|
2118
2234
|
}, []);
|
|
2119
|
-
const fetchModels =
|
|
2235
|
+
const fetchModels = useCallback5(async () => {
|
|
2120
2236
|
if (abortControllerRef.current) {
|
|
2121
2237
|
abortControllerRef.current.abort();
|
|
2122
2238
|
}
|
|
@@ -2174,7 +2290,7 @@ function useModels(options = {}) {
|
|
|
2174
2290
|
}
|
|
2175
2291
|
}
|
|
2176
2292
|
}, []);
|
|
2177
|
-
const refetch =
|
|
2293
|
+
const refetch = useCallback5(async () => {
|
|
2178
2294
|
setModels([]);
|
|
2179
2295
|
await fetchModels();
|
|
2180
2296
|
}, [fetchModels]);
|
|
@@ -2197,13 +2313,13 @@ function useModels(options = {}) {
|
|
|
2197
2313
|
}
|
|
2198
2314
|
|
|
2199
2315
|
// src/react/useSearch.ts
|
|
2200
|
-
import { useCallback as
|
|
2316
|
+
import { useCallback as useCallback6, useEffect as useEffect3, useRef as useRef4, useState as useState5 } from "react";
|
|
2201
2317
|
function useSearch(options = {}) {
|
|
2202
2318
|
const { getToken, baseUrl = BASE_URL, onError } = options;
|
|
2203
|
-
const [isLoading, setIsLoading] =
|
|
2204
|
-
const [results, setResults] =
|
|
2205
|
-
const [response, setResponse] =
|
|
2206
|
-
const [error, setError] =
|
|
2319
|
+
const [isLoading, setIsLoading] = useState5(false);
|
|
2320
|
+
const [results, setResults] = useState5(null);
|
|
2321
|
+
const [response, setResponse] = useState5(null);
|
|
2322
|
+
const [error, setError] = useState5(null);
|
|
2207
2323
|
const abortControllerRef = useRef4(null);
|
|
2208
2324
|
useEffect3(() => {
|
|
2209
2325
|
return () => {
|
|
@@ -2213,7 +2329,7 @@ function useSearch(options = {}) {
|
|
|
2213
2329
|
}
|
|
2214
2330
|
};
|
|
2215
2331
|
}, []);
|
|
2216
|
-
const search =
|
|
2332
|
+
const search = useCallback6(
|
|
2217
2333
|
async (query, searchOptions = {}) => {
|
|
2218
2334
|
if (abortControllerRef.current) {
|
|
2219
2335
|
abortControllerRef.current.abort();
|
|
@@ -2281,10 +2397,10 @@ function useSearch(options = {}) {
|
|
|
2281
2397
|
}
|
|
2282
2398
|
|
|
2283
2399
|
// src/react/useImageGeneration.ts
|
|
2284
|
-
import { useCallback as
|
|
2400
|
+
import { useCallback as useCallback7, useEffect as useEffect4, useRef as useRef5, useState as useState6 } from "react";
|
|
2285
2401
|
function useImageGeneration(options = {}) {
|
|
2286
2402
|
const { getToken, baseUrl = BASE_URL, onFinish, onError } = options;
|
|
2287
|
-
const [isLoading, setIsLoading] =
|
|
2403
|
+
const [isLoading, setIsLoading] = useState6(false);
|
|
2288
2404
|
const abortControllerRef = useRef5(null);
|
|
2289
2405
|
useEffect4(() => {
|
|
2290
2406
|
return () => {
|
|
@@ -2294,13 +2410,13 @@ function useImageGeneration(options = {}) {
|
|
|
2294
2410
|
}
|
|
2295
2411
|
};
|
|
2296
2412
|
}, []);
|
|
2297
|
-
const stop =
|
|
2413
|
+
const stop = useCallback7(() => {
|
|
2298
2414
|
if (abortControllerRef.current) {
|
|
2299
2415
|
abortControllerRef.current.abort();
|
|
2300
2416
|
abortControllerRef.current = null;
|
|
2301
2417
|
}
|
|
2302
2418
|
}, []);
|
|
2303
|
-
const generateImage =
|
|
2419
|
+
const generateImage = useCallback7(
|
|
2304
2420
|
async (args) => {
|
|
2305
2421
|
if (abortControllerRef.current) {
|
|
2306
2422
|
abortControllerRef.current.abort();
|
|
@@ -2433,6 +2549,7 @@ export {
|
|
|
2433
2549
|
useImageGeneration,
|
|
2434
2550
|
useMemory,
|
|
2435
2551
|
useModels,
|
|
2552
|
+
useOCR,
|
|
2436
2553
|
usePdf,
|
|
2437
2554
|
useSearch
|
|
2438
2555
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reverbia/sdk",
|
|
3
|
-
"version": "1.0.0-next.
|
|
3
|
+
"version": "1.0.0-next.20251208102554",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -72,9 +72,10 @@
|
|
|
72
72
|
"homepage": "https://github.com/zeta-chain/ai-sdk#readme",
|
|
73
73
|
"dependencies": {
|
|
74
74
|
"@huggingface/transformers": "^3.8.0",
|
|
75
|
-
"pdfjs-dist": "^4.10.38",
|
|
76
75
|
"@reverbia/portal": "1.0.0-next.20251202220311",
|
|
77
|
-
"ai": "5.0.93"
|
|
76
|
+
"ai": "5.0.93",
|
|
77
|
+
"pdfjs-dist": "^4.10.38",
|
|
78
|
+
"tesseract.js": "^6.0.1"
|
|
78
79
|
},
|
|
79
80
|
"devDependencies": {
|
|
80
81
|
"@hey-api/openapi-ts": "0.87.2",
|