@reverbia/sdk 1.0.0-next.20251202090922 → 1.0.0-next.20251202095402
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/index.cjs +466 -89
- package/dist/react/index.d.mts +149 -24
- package/dist/react/index.d.ts +149 -24
- package/dist/react/index.mjs +462 -88
- package/package.json +1 -1
package/dist/react/index.cjs
CHANGED
|
@@ -46669,12 +46669,15 @@ ${fake_token_around_image}${global_img_token}` + image_token.repeat(image_seq_le
|
|
|
46669
46669
|
// src/react/index.ts
|
|
46670
46670
|
var index_exports = {};
|
|
46671
46671
|
__export(index_exports, {
|
|
46672
|
+
DEFAULT_TOOL_SELECTOR_MODEL: () => DEFAULT_TOOL_SELECTOR_MODEL,
|
|
46672
46673
|
createMemoryContextSystemMessage: () => createMemoryContextSystemMessage,
|
|
46673
46674
|
decryptData: () => decryptData,
|
|
46674
46675
|
decryptDataBytes: () => decryptDataBytes,
|
|
46675
46676
|
encryptData: () => encryptData,
|
|
46677
|
+
executeTool: () => executeTool,
|
|
46676
46678
|
extractConversationContext: () => extractConversationContext,
|
|
46677
46679
|
formatMemoriesForChat: () => formatMemoriesForChat,
|
|
46680
|
+
selectTool: () => selectTool,
|
|
46678
46681
|
useChat: () => useChat,
|
|
46679
46682
|
useEncryption: () => useEncryption,
|
|
46680
46683
|
useMemory: () => useMemory,
|
|
@@ -47500,6 +47503,218 @@ var createClientConfig = (config) => ({
|
|
|
47500
47503
|
// src/client/client.gen.ts
|
|
47501
47504
|
var client = createClient(createClientConfig(createConfig()));
|
|
47502
47505
|
|
|
47506
|
+
// src/lib/chat/constants.ts
|
|
47507
|
+
var DEFAULT_LOCAL_CHAT_MODEL = "onnx-community/Qwen2.5-0.5B-Instruct";
|
|
47508
|
+
|
|
47509
|
+
// src/lib/chat/pipeline.ts
|
|
47510
|
+
var sharedPipeline = null;
|
|
47511
|
+
var currentModel = null;
|
|
47512
|
+
var currentDevice = null;
|
|
47513
|
+
async function getTextGenerationPipeline(options) {
|
|
47514
|
+
const { model, device = "wasm", dtype = "q4" } = options;
|
|
47515
|
+
if (sharedPipeline && currentModel === model && currentDevice === device) {
|
|
47516
|
+
return sharedPipeline;
|
|
47517
|
+
}
|
|
47518
|
+
const { pipeline, env: env3 } = await Promise.resolve().then(() => (init_transformers_node(), transformers_node_exports));
|
|
47519
|
+
env3.allowLocalModels = false;
|
|
47520
|
+
if (env3.backends?.onnx) {
|
|
47521
|
+
env3.backends.onnx.logLevel = "fatal";
|
|
47522
|
+
}
|
|
47523
|
+
console.log(`[Pipeline] Loading model: ${model} on ${device}...`);
|
|
47524
|
+
sharedPipeline = await pipeline("text-generation", model, {
|
|
47525
|
+
dtype,
|
|
47526
|
+
device
|
|
47527
|
+
});
|
|
47528
|
+
currentModel = model;
|
|
47529
|
+
currentDevice = device;
|
|
47530
|
+
console.log(`[Pipeline] Model loaded: ${model}`);
|
|
47531
|
+
return sharedPipeline;
|
|
47532
|
+
}
|
|
47533
|
+
|
|
47534
|
+
// src/lib/chat/generation.ts
|
|
47535
|
+
async function generateLocalChatCompletion(messages, options = {}) {
|
|
47536
|
+
const {
|
|
47537
|
+
model = DEFAULT_LOCAL_CHAT_MODEL,
|
|
47538
|
+
temperature = 0.7,
|
|
47539
|
+
max_tokens = 1024,
|
|
47540
|
+
top_p = 0.9,
|
|
47541
|
+
onToken,
|
|
47542
|
+
signal
|
|
47543
|
+
} = options;
|
|
47544
|
+
const { TextStreamer } = await Promise.resolve().then(() => (init_transformers_node(), transformers_node_exports));
|
|
47545
|
+
const chatPipeline = await getTextGenerationPipeline({
|
|
47546
|
+
model,
|
|
47547
|
+
device: "wasm",
|
|
47548
|
+
dtype: "q4"
|
|
47549
|
+
});
|
|
47550
|
+
class CallbackStreamer extends TextStreamer {
|
|
47551
|
+
constructor(tokenizer, cb) {
|
|
47552
|
+
super(tokenizer, {
|
|
47553
|
+
skip_prompt: true,
|
|
47554
|
+
skip_special_tokens: true
|
|
47555
|
+
});
|
|
47556
|
+
this.cb = cb;
|
|
47557
|
+
}
|
|
47558
|
+
on_finalized_text(text) {
|
|
47559
|
+
if (signal?.aborted) {
|
|
47560
|
+
throw new Error("AbortError");
|
|
47561
|
+
}
|
|
47562
|
+
this.cb(text);
|
|
47563
|
+
}
|
|
47564
|
+
}
|
|
47565
|
+
const streamer = onToken ? new CallbackStreamer(chatPipeline.tokenizer, onToken) : void 0;
|
|
47566
|
+
const output = await chatPipeline(messages, {
|
|
47567
|
+
max_new_tokens: max_tokens,
|
|
47568
|
+
temperature,
|
|
47569
|
+
top_p,
|
|
47570
|
+
streamer,
|
|
47571
|
+
return_full_text: false
|
|
47572
|
+
});
|
|
47573
|
+
return output;
|
|
47574
|
+
}
|
|
47575
|
+
|
|
47576
|
+
// src/lib/tools/selector.ts
|
|
47577
|
+
var DEFAULT_TOOL_SELECTOR_MODEL = "Xenova/LaMini-GPT-124M";
|
|
47578
|
+
function buildToolSelectionPrompt(userMessage, tools) {
|
|
47579
|
+
const toolList = tools.map((t) => `${t.name} (${t.description})`).join("\n");
|
|
47580
|
+
return `Pick the best tool for the task. Reply with ONLY the tool name.
|
|
47581
|
+
|
|
47582
|
+
Available tools:
|
|
47583
|
+
${toolList}
|
|
47584
|
+
none (no tool needed)
|
|
47585
|
+
|
|
47586
|
+
Task: "${userMessage}"
|
|
47587
|
+
|
|
47588
|
+
Best tool:`;
|
|
47589
|
+
}
|
|
47590
|
+
function extractParams(userMessage, tool) {
|
|
47591
|
+
const params = {};
|
|
47592
|
+
if (!tool.parameters) return params;
|
|
47593
|
+
for (const param of tool.parameters) {
|
|
47594
|
+
if (param.name === "expression" || param.name === "query") {
|
|
47595
|
+
params[param.name] = userMessage;
|
|
47596
|
+
} else if (param.name === "location" || param.name === "city") {
|
|
47597
|
+
const words = userMessage.split(/\s+/);
|
|
47598
|
+
const capitalizedWords = words.filter(
|
|
47599
|
+
(w) => w.length > 1 && w[0] === w[0].toUpperCase()
|
|
47600
|
+
);
|
|
47601
|
+
params[param.name] = capitalizedWords.length > 0 ? capitalizedWords.join(" ") : userMessage;
|
|
47602
|
+
} else if (param.name === "text" || param.name === "input") {
|
|
47603
|
+
params[param.name] = userMessage;
|
|
47604
|
+
} else {
|
|
47605
|
+
params[param.name] = userMessage;
|
|
47606
|
+
}
|
|
47607
|
+
}
|
|
47608
|
+
return params;
|
|
47609
|
+
}
|
|
47610
|
+
function parseToolSelectionResponse(response, tools, userMessage) {
|
|
47611
|
+
console.log("[Tool Selector] Raw response:", response);
|
|
47612
|
+
const cleaned = response.toLowerCase().trim().split(/[\s\n,.]+/)[0].replace(/[^a-z0-9_-]/g, "");
|
|
47613
|
+
console.log("[Tool Selector] Parsed tool name:", cleaned);
|
|
47614
|
+
if (cleaned === "none" || cleaned === "null" || cleaned === "") {
|
|
47615
|
+
console.log("[Tool Selector] No tool selected");
|
|
47616
|
+
return { toolSelected: false };
|
|
47617
|
+
}
|
|
47618
|
+
const selectedTool = tools.find((t) => t.name.toLowerCase() === cleaned);
|
|
47619
|
+
if (!selectedTool) {
|
|
47620
|
+
const fuzzyTool = tools.find(
|
|
47621
|
+
(t) => t.name.toLowerCase().includes(cleaned) || cleaned.includes(t.name.toLowerCase())
|
|
47622
|
+
);
|
|
47623
|
+
if (fuzzyTool) {
|
|
47624
|
+
console.log(`[Tool Selector] Fuzzy matched tool: ${fuzzyTool.name}`);
|
|
47625
|
+
const params2 = extractParams(userMessage, fuzzyTool);
|
|
47626
|
+
return {
|
|
47627
|
+
toolSelected: true,
|
|
47628
|
+
toolName: fuzzyTool.name,
|
|
47629
|
+
parameters: params2,
|
|
47630
|
+
confidence: 0.6
|
|
47631
|
+
};
|
|
47632
|
+
}
|
|
47633
|
+
console.warn(`[Tool Selector] Unknown tool: ${cleaned}`);
|
|
47634
|
+
return { toolSelected: false };
|
|
47635
|
+
}
|
|
47636
|
+
const params = extractParams(userMessage, selectedTool);
|
|
47637
|
+
console.log(`[Tool Selector] Selected tool: ${selectedTool.name}`, params);
|
|
47638
|
+
return {
|
|
47639
|
+
toolSelected: true,
|
|
47640
|
+
toolName: selectedTool.name,
|
|
47641
|
+
parameters: params,
|
|
47642
|
+
confidence: 0.9
|
|
47643
|
+
};
|
|
47644
|
+
}
|
|
47645
|
+
async function selectTool(userMessage, tools, options = {}) {
|
|
47646
|
+
const {
|
|
47647
|
+
model = DEFAULT_TOOL_SELECTOR_MODEL,
|
|
47648
|
+
signal,
|
|
47649
|
+
device = "wasm"
|
|
47650
|
+
} = options;
|
|
47651
|
+
if (!tools.length) {
|
|
47652
|
+
return { toolSelected: false };
|
|
47653
|
+
}
|
|
47654
|
+
console.log(
|
|
47655
|
+
`[Tool Selector] analyzing message: "${userMessage}" with model ${model}`
|
|
47656
|
+
);
|
|
47657
|
+
try {
|
|
47658
|
+
const selectorPipeline = await getTextGenerationPipeline({
|
|
47659
|
+
model,
|
|
47660
|
+
device,
|
|
47661
|
+
dtype: "q4"
|
|
47662
|
+
// Aggressive quantization for speed
|
|
47663
|
+
});
|
|
47664
|
+
const prompt = buildToolSelectionPrompt(userMessage, tools);
|
|
47665
|
+
const output = await selectorPipeline(prompt, {
|
|
47666
|
+
max_new_tokens: 4,
|
|
47667
|
+
// Just need the tool name
|
|
47668
|
+
temperature: 0,
|
|
47669
|
+
// Deterministic
|
|
47670
|
+
do_sample: false,
|
|
47671
|
+
return_full_text: false
|
|
47672
|
+
});
|
|
47673
|
+
if (signal?.aborted) {
|
|
47674
|
+
return { toolSelected: false };
|
|
47675
|
+
}
|
|
47676
|
+
const generatedText = output?.[0]?.generated_text || output?.generated_text || "";
|
|
47677
|
+
return parseToolSelectionResponse(generatedText, tools, userMessage);
|
|
47678
|
+
} catch (error) {
|
|
47679
|
+
console.error("[Tool Selector] Error:", error);
|
|
47680
|
+
return { toolSelected: false };
|
|
47681
|
+
}
|
|
47682
|
+
}
|
|
47683
|
+
var preloadPromise = null;
|
|
47684
|
+
async function preloadToolSelectorModel(options = {}) {
|
|
47685
|
+
if (preloadPromise) {
|
|
47686
|
+
return preloadPromise;
|
|
47687
|
+
}
|
|
47688
|
+
const { model = DEFAULT_TOOL_SELECTOR_MODEL, device = "wasm" } = options;
|
|
47689
|
+
console.log(`[Tool Selector] Preloading model: ${model}`);
|
|
47690
|
+
preloadPromise = getTextGenerationPipeline({
|
|
47691
|
+
model,
|
|
47692
|
+
device,
|
|
47693
|
+
dtype: "q4"
|
|
47694
|
+
}).then(() => {
|
|
47695
|
+
console.log(`[Tool Selector] Model preloaded: ${model}`);
|
|
47696
|
+
}).catch((error) => {
|
|
47697
|
+
console.warn("[Tool Selector] Failed to preload model:", error);
|
|
47698
|
+
preloadPromise = null;
|
|
47699
|
+
});
|
|
47700
|
+
return preloadPromise;
|
|
47701
|
+
}
|
|
47702
|
+
async function executeTool(tool, params) {
|
|
47703
|
+
try {
|
|
47704
|
+
console.log(
|
|
47705
|
+
`[Tool Selector] Executing tool ${tool.name} with params:`,
|
|
47706
|
+
params
|
|
47707
|
+
);
|
|
47708
|
+
const result = await tool.execute(params);
|
|
47709
|
+
console.log(`[Tool Selector] Tool ${tool.name} execution result:`, result);
|
|
47710
|
+
return { success: true, result };
|
|
47711
|
+
} catch (error) {
|
|
47712
|
+
const errorMessage = error instanceof Error ? error.message : "Tool execution failed";
|
|
47713
|
+
console.error(`[Tool Selector] Tool ${tool.name} failed:`, errorMessage);
|
|
47714
|
+
return { success: false, error: errorMessage };
|
|
47715
|
+
}
|
|
47716
|
+
}
|
|
47717
|
+
|
|
47503
47718
|
// src/react/useChat.ts
|
|
47504
47719
|
function useChat(options) {
|
|
47505
47720
|
const {
|
|
@@ -47507,9 +47722,15 @@ function useChat(options) {
|
|
|
47507
47722
|
baseUrl = BASE_URL,
|
|
47508
47723
|
onData: globalOnData,
|
|
47509
47724
|
onFinish,
|
|
47510
|
-
onError
|
|
47725
|
+
onError,
|
|
47726
|
+
chatProvider = "api",
|
|
47727
|
+
localModel = DEFAULT_LOCAL_CHAT_MODEL,
|
|
47728
|
+
tools,
|
|
47729
|
+
toolSelectorModel = DEFAULT_TOOL_SELECTOR_MODEL,
|
|
47730
|
+
onToolExecution
|
|
47511
47731
|
} = options || {};
|
|
47512
47732
|
const [isLoading, setIsLoading] = (0, import_react.useState)(false);
|
|
47733
|
+
const [isSelectingTool, setIsSelectingTool] = (0, import_react.useState)(false);
|
|
47513
47734
|
const abortControllerRef = (0, import_react.useRef)(null);
|
|
47514
47735
|
const stop = (0, import_react.useCallback)(() => {
|
|
47515
47736
|
if (abortControllerRef.current) {
|
|
@@ -47525,120 +47746,257 @@ function useChat(options) {
|
|
|
47525
47746
|
}
|
|
47526
47747
|
};
|
|
47527
47748
|
}, []);
|
|
47749
|
+
(0, import_react.useEffect)(() => {
|
|
47750
|
+
if (tools && tools.length > 0) {
|
|
47751
|
+
preloadToolSelectorModel({ model: toolSelectorModel });
|
|
47752
|
+
}
|
|
47753
|
+
}, [tools, toolSelectorModel]);
|
|
47528
47754
|
const sendMessage = (0, import_react.useCallback)(
|
|
47529
47755
|
async ({
|
|
47530
47756
|
messages,
|
|
47531
47757
|
model,
|
|
47532
|
-
onData
|
|
47758
|
+
onData,
|
|
47759
|
+
runTools = true
|
|
47533
47760
|
}) => {
|
|
47534
47761
|
if (!messages?.length) {
|
|
47535
47762
|
const errorMsg = "messages are required to call sendMessage.";
|
|
47536
47763
|
if (onError) onError(new Error(errorMsg));
|
|
47537
47764
|
return { data: null, error: errorMsg };
|
|
47538
47765
|
}
|
|
47539
|
-
if (!model) {
|
|
47540
|
-
const errorMsg = "model is required to call sendMessage.";
|
|
47541
|
-
if (onError) onError(new Error(errorMsg));
|
|
47542
|
-
return { data: null, error: errorMsg };
|
|
47543
|
-
}
|
|
47544
|
-
if (!getToken) {
|
|
47545
|
-
const errorMsg = "Token getter function is required.";
|
|
47546
|
-
if (onError) onError(new Error(errorMsg));
|
|
47547
|
-
return { data: null, error: errorMsg };
|
|
47548
|
-
}
|
|
47549
47766
|
if (abortControllerRef.current) {
|
|
47550
47767
|
abortControllerRef.current.abort();
|
|
47551
47768
|
}
|
|
47552
47769
|
const abortController = new AbortController();
|
|
47553
47770
|
abortControllerRef.current = abortController;
|
|
47554
47771
|
setIsLoading(true);
|
|
47555
|
-
|
|
47556
|
-
|
|
47557
|
-
|
|
47558
|
-
|
|
47559
|
-
|
|
47560
|
-
|
|
47561
|
-
|
|
47562
|
-
|
|
47563
|
-
|
|
47564
|
-
|
|
47565
|
-
|
|
47566
|
-
|
|
47567
|
-
|
|
47568
|
-
|
|
47569
|
-
|
|
47570
|
-
|
|
47571
|
-
|
|
47572
|
-
|
|
47573
|
-
|
|
47574
|
-
|
|
47575
|
-
|
|
47576
|
-
|
|
47577
|
-
|
|
47578
|
-
|
|
47579
|
-
|
|
47580
|
-
|
|
47581
|
-
|
|
47582
|
-
|
|
47583
|
-
|
|
47584
|
-
|
|
47585
|
-
|
|
47586
|
-
|
|
47587
|
-
|
|
47588
|
-
|
|
47589
|
-
|
|
47772
|
+
let toolExecutionResult;
|
|
47773
|
+
let messagesWithToolContext = messages;
|
|
47774
|
+
if (runTools && tools && tools.length > 0) {
|
|
47775
|
+
const lastUserMessage = [...messages].reverse().find((m) => m.role === "user");
|
|
47776
|
+
if (lastUserMessage?.content) {
|
|
47777
|
+
setIsSelectingTool(true);
|
|
47778
|
+
try {
|
|
47779
|
+
const selectionResult = await selectTool(
|
|
47780
|
+
lastUserMessage.content,
|
|
47781
|
+
tools,
|
|
47782
|
+
{
|
|
47783
|
+
model: toolSelectorModel,
|
|
47784
|
+
signal: abortController.signal
|
|
47785
|
+
}
|
|
47786
|
+
);
|
|
47787
|
+
if (selectionResult.toolSelected && selectionResult.toolName) {
|
|
47788
|
+
const selectedTool = tools.find(
|
|
47789
|
+
(t) => t.name === selectionResult.toolName
|
|
47790
|
+
);
|
|
47791
|
+
if (selectedTool) {
|
|
47792
|
+
const execResult = await executeTool(
|
|
47793
|
+
selectedTool,
|
|
47794
|
+
selectionResult.parameters || {}
|
|
47795
|
+
);
|
|
47796
|
+
toolExecutionResult = {
|
|
47797
|
+
toolName: selectionResult.toolName,
|
|
47798
|
+
success: execResult.success,
|
|
47799
|
+
result: execResult.result,
|
|
47800
|
+
error: execResult.error
|
|
47801
|
+
};
|
|
47802
|
+
if (onToolExecution) {
|
|
47803
|
+
onToolExecution(toolExecutionResult);
|
|
47804
|
+
}
|
|
47805
|
+
if (toolExecutionResult.success && toolExecutionResult.result !== void 0) {
|
|
47806
|
+
const toolResultContext = {
|
|
47807
|
+
role: "system",
|
|
47808
|
+
content: `Tool "${toolExecutionResult.toolName}" was executed with the following result:
|
|
47809
|
+
${JSON.stringify(
|
|
47810
|
+
toolExecutionResult.result,
|
|
47811
|
+
null,
|
|
47812
|
+
2
|
|
47813
|
+
)}
|
|
47814
|
+
|
|
47815
|
+
Use this information to respond to the user's request.`
|
|
47816
|
+
};
|
|
47817
|
+
messagesWithToolContext = [...messages, toolResultContext];
|
|
47818
|
+
} else if (toolExecutionResult.error) {
|
|
47819
|
+
const toolErrorContext = {
|
|
47820
|
+
role: "system",
|
|
47821
|
+
content: `Tool "${toolExecutionResult.toolName}" was executed but encountered an error: ${toolExecutionResult.error}
|
|
47822
|
+
|
|
47823
|
+
Please inform the user about this issue and try to help them alternatively.`
|
|
47824
|
+
};
|
|
47825
|
+
messagesWithToolContext = [...messages, toolErrorContext];
|
|
47826
|
+
}
|
|
47827
|
+
}
|
|
47590
47828
|
}
|
|
47591
|
-
|
|
47592
|
-
|
|
47829
|
+
} catch (err) {
|
|
47830
|
+
console.warn("Tool selection error:", err);
|
|
47831
|
+
} finally {
|
|
47832
|
+
setIsSelectingTool(false);
|
|
47833
|
+
}
|
|
47834
|
+
}
|
|
47835
|
+
}
|
|
47836
|
+
try {
|
|
47837
|
+
if (chatProvider === "local") {
|
|
47838
|
+
let accumulatedContent = "";
|
|
47839
|
+
const usedModel = localModel;
|
|
47840
|
+
const formattedMessages = messagesWithToolContext.map((m) => ({
|
|
47841
|
+
role: m.role || "user",
|
|
47842
|
+
content: m.content || ""
|
|
47843
|
+
}));
|
|
47844
|
+
await generateLocalChatCompletion(formattedMessages, {
|
|
47845
|
+
model: usedModel,
|
|
47846
|
+
signal: abortController.signal,
|
|
47847
|
+
onToken: (token) => {
|
|
47848
|
+
accumulatedContent += token;
|
|
47849
|
+
if (onData) onData(token);
|
|
47850
|
+
if (globalOnData) globalOnData(token);
|
|
47593
47851
|
}
|
|
47594
|
-
|
|
47595
|
-
|
|
47596
|
-
|
|
47597
|
-
|
|
47598
|
-
|
|
47852
|
+
});
|
|
47853
|
+
const completion = {
|
|
47854
|
+
id: `local-${Date.now()}`,
|
|
47855
|
+
model: usedModel,
|
|
47856
|
+
choices: [
|
|
47857
|
+
{
|
|
47858
|
+
index: 0,
|
|
47859
|
+
message: {
|
|
47860
|
+
role: "assistant",
|
|
47861
|
+
content: accumulatedContent
|
|
47862
|
+
},
|
|
47863
|
+
finish_reason: "stop"
|
|
47864
|
+
}
|
|
47865
|
+
],
|
|
47866
|
+
usage: {
|
|
47867
|
+
prompt_tokens: 0,
|
|
47868
|
+
// Not easily available from simple pipeline usage
|
|
47869
|
+
completion_tokens: 0,
|
|
47870
|
+
total_tokens: 0
|
|
47599
47871
|
}
|
|
47600
|
-
|
|
47601
|
-
|
|
47602
|
-
|
|
47603
|
-
|
|
47604
|
-
|
|
47605
|
-
|
|
47606
|
-
|
|
47872
|
+
};
|
|
47873
|
+
setIsLoading(false);
|
|
47874
|
+
if (onFinish) {
|
|
47875
|
+
onFinish(completion);
|
|
47876
|
+
}
|
|
47877
|
+
return {
|
|
47878
|
+
data: completion,
|
|
47879
|
+
error: null,
|
|
47880
|
+
toolExecution: toolExecutionResult
|
|
47881
|
+
};
|
|
47882
|
+
} else {
|
|
47883
|
+
if (!model) {
|
|
47884
|
+
const errorMsg = "model is required to call sendMessage.";
|
|
47885
|
+
if (onError) onError(new Error(errorMsg));
|
|
47886
|
+
return {
|
|
47887
|
+
data: null,
|
|
47888
|
+
error: errorMsg,
|
|
47889
|
+
toolExecution: toolExecutionResult
|
|
47890
|
+
};
|
|
47891
|
+
}
|
|
47892
|
+
if (!getToken) {
|
|
47893
|
+
const errorMsg = "Token getter function is required.";
|
|
47894
|
+
if (onError) onError(new Error(errorMsg));
|
|
47895
|
+
return {
|
|
47896
|
+
data: null,
|
|
47897
|
+
error: errorMsg,
|
|
47898
|
+
toolExecution: toolExecutionResult
|
|
47899
|
+
};
|
|
47900
|
+
}
|
|
47901
|
+
const token = await getToken();
|
|
47902
|
+
if (!token) {
|
|
47903
|
+
const errorMsg = "No access token available.";
|
|
47904
|
+
setIsLoading(false);
|
|
47905
|
+
if (onError) onError(new Error(errorMsg));
|
|
47906
|
+
return {
|
|
47907
|
+
data: null,
|
|
47908
|
+
error: errorMsg,
|
|
47909
|
+
toolExecution: toolExecutionResult
|
|
47910
|
+
};
|
|
47911
|
+
}
|
|
47912
|
+
const sseResult = await client.sse.post({
|
|
47913
|
+
baseUrl,
|
|
47914
|
+
url: "/api/v1/chat/completions",
|
|
47915
|
+
body: {
|
|
47916
|
+
messages: messagesWithToolContext,
|
|
47917
|
+
model,
|
|
47918
|
+
stream: true
|
|
47919
|
+
},
|
|
47920
|
+
headers: {
|
|
47921
|
+
"Content-Type": "application/json",
|
|
47922
|
+
Authorization: `Bearer ${token}`
|
|
47923
|
+
},
|
|
47924
|
+
signal: abortController.signal
|
|
47925
|
+
});
|
|
47926
|
+
let accumulatedContent = "";
|
|
47927
|
+
let completionId = "";
|
|
47928
|
+
let completionModel = "";
|
|
47929
|
+
let accumulatedUsage = {};
|
|
47930
|
+
let finishReason;
|
|
47931
|
+
for await (const chunk of sseResult.stream) {
|
|
47932
|
+
if (typeof chunk === "string" && (chunk.trim() === "[DONE]" || chunk.includes("[DONE]"))) {
|
|
47933
|
+
continue;
|
|
47934
|
+
}
|
|
47935
|
+
if (chunk && typeof chunk === "object") {
|
|
47936
|
+
const chunkData = chunk;
|
|
47937
|
+
if (chunkData.id && !completionId) {
|
|
47938
|
+
completionId = chunkData.id;
|
|
47939
|
+
}
|
|
47940
|
+
if (chunkData.model && !completionModel) {
|
|
47941
|
+
completionModel = chunkData.model;
|
|
47942
|
+
}
|
|
47943
|
+
if (chunkData.usage) {
|
|
47944
|
+
accumulatedUsage = {
|
|
47945
|
+
...accumulatedUsage,
|
|
47946
|
+
...chunkData.usage
|
|
47947
|
+
};
|
|
47948
|
+
}
|
|
47949
|
+
if (chunkData.choices && Array.isArray(chunkData.choices) && chunkData.choices.length > 0) {
|
|
47950
|
+
const choice = chunkData.choices[0];
|
|
47951
|
+
if (choice.delta?.content) {
|
|
47952
|
+
const content = choice.delta.content;
|
|
47953
|
+
accumulatedContent += content;
|
|
47954
|
+
if (onData) {
|
|
47955
|
+
onData(content);
|
|
47956
|
+
}
|
|
47957
|
+
if (globalOnData) {
|
|
47958
|
+
globalOnData(content);
|
|
47959
|
+
}
|
|
47607
47960
|
}
|
|
47608
|
-
if (
|
|
47609
|
-
|
|
47961
|
+
if (choice.finish_reason) {
|
|
47962
|
+
finishReason = choice.finish_reason;
|
|
47610
47963
|
}
|
|
47611
47964
|
}
|
|
47612
|
-
if (choice.finish_reason) {
|
|
47613
|
-
finishReason = choice.finish_reason;
|
|
47614
|
-
}
|
|
47615
47965
|
}
|
|
47616
47966
|
}
|
|
47967
|
+
const completion = {
|
|
47968
|
+
id: completionId,
|
|
47969
|
+
model: completionModel,
|
|
47970
|
+
choices: [
|
|
47971
|
+
{
|
|
47972
|
+
index: 0,
|
|
47973
|
+
message: {
|
|
47974
|
+
role: "assistant",
|
|
47975
|
+
content: accumulatedContent
|
|
47976
|
+
},
|
|
47977
|
+
finish_reason: finishReason
|
|
47978
|
+
}
|
|
47979
|
+
],
|
|
47980
|
+
usage: Object.keys(accumulatedUsage).length > 0 ? accumulatedUsage : void 0
|
|
47981
|
+
};
|
|
47982
|
+
setIsLoading(false);
|
|
47983
|
+
if (onFinish) {
|
|
47984
|
+
onFinish(completion);
|
|
47985
|
+
}
|
|
47986
|
+
return {
|
|
47987
|
+
data: completion,
|
|
47988
|
+
error: null,
|
|
47989
|
+
toolExecution: toolExecutionResult
|
|
47990
|
+
};
|
|
47617
47991
|
}
|
|
47618
|
-
const completion = {
|
|
47619
|
-
id: completionId,
|
|
47620
|
-
model: completionModel,
|
|
47621
|
-
choices: [
|
|
47622
|
-
{
|
|
47623
|
-
index: 0,
|
|
47624
|
-
message: {
|
|
47625
|
-
role: "assistant",
|
|
47626
|
-
content: accumulatedContent
|
|
47627
|
-
},
|
|
47628
|
-
finish_reason: finishReason
|
|
47629
|
-
}
|
|
47630
|
-
],
|
|
47631
|
-
usage: Object.keys(accumulatedUsage).length > 0 ? accumulatedUsage : void 0
|
|
47632
|
-
};
|
|
47633
|
-
setIsLoading(false);
|
|
47634
|
-
if (onFinish) {
|
|
47635
|
-
onFinish(completion);
|
|
47636
|
-
}
|
|
47637
|
-
return { data: completion, error: null };
|
|
47638
47992
|
} catch (err) {
|
|
47639
47993
|
if (err instanceof Error && err.name === "AbortError") {
|
|
47640
47994
|
setIsLoading(false);
|
|
47641
|
-
return {
|
|
47995
|
+
return {
|
|
47996
|
+
data: null,
|
|
47997
|
+
error: "Request aborted",
|
|
47998
|
+
toolExecution: toolExecutionResult
|
|
47999
|
+
};
|
|
47642
48000
|
}
|
|
47643
48001
|
const errorMsg = err instanceof Error ? err.message : "Failed to send message.";
|
|
47644
48002
|
const errorObj = err instanceof Error ? err : new Error(errorMsg);
|
|
@@ -47646,17 +48004,33 @@ function useChat(options) {
|
|
|
47646
48004
|
if (onError) {
|
|
47647
48005
|
onError(errorObj);
|
|
47648
48006
|
}
|
|
47649
|
-
return {
|
|
48007
|
+
return {
|
|
48008
|
+
data: null,
|
|
48009
|
+
error: errorMsg,
|
|
48010
|
+
toolExecution: toolExecutionResult
|
|
48011
|
+
};
|
|
47650
48012
|
} finally {
|
|
47651
48013
|
if (abortControllerRef.current === abortController) {
|
|
47652
48014
|
abortControllerRef.current = null;
|
|
47653
48015
|
}
|
|
47654
48016
|
}
|
|
47655
48017
|
},
|
|
47656
|
-
[
|
|
48018
|
+
[
|
|
48019
|
+
getToken,
|
|
48020
|
+
baseUrl,
|
|
48021
|
+
globalOnData,
|
|
48022
|
+
onFinish,
|
|
48023
|
+
onError,
|
|
48024
|
+
chatProvider,
|
|
48025
|
+
localModel,
|
|
48026
|
+
tools,
|
|
48027
|
+
toolSelectorModel,
|
|
48028
|
+
onToolExecution
|
|
48029
|
+
]
|
|
47657
48030
|
);
|
|
47658
48031
|
return {
|
|
47659
48032
|
isLoading,
|
|
48033
|
+
isSelectingTool,
|
|
47660
48034
|
sendMessage,
|
|
47661
48035
|
stop
|
|
47662
48036
|
};
|
|
@@ -48579,12 +48953,15 @@ var extractConversationContext = (messages, maxMessages = 3) => {
|
|
|
48579
48953
|
};
|
|
48580
48954
|
// Annotate the CommonJS export names for ESM import in node:
|
|
48581
48955
|
0 && (module.exports = {
|
|
48956
|
+
DEFAULT_TOOL_SELECTOR_MODEL,
|
|
48582
48957
|
createMemoryContextSystemMessage,
|
|
48583
48958
|
decryptData,
|
|
48584
48959
|
decryptDataBytes,
|
|
48585
48960
|
encryptData,
|
|
48961
|
+
executeTool,
|
|
48586
48962
|
extractConversationContext,
|
|
48587
48963
|
formatMemoriesForChat,
|
|
48964
|
+
selectTool,
|
|
48588
48965
|
useChat,
|
|
48589
48966
|
useEncryption,
|
|
48590
48967
|
useMemory,
|