@superatomai/sdk-node 0.0.11 → 0.0.13
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/index.d.mts +30 -1
- package/dist/index.d.ts +30 -1
- package/dist/index.js +608 -24
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +608 -24
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -485,6 +485,13 @@ var ComponentListResponseMessageSchema = import_zod3.z.object({
|
|
|
485
485
|
type: import_zod3.z.literal("COMPONENT_LIST_RES"),
|
|
486
486
|
payload: ComponentListResponsePayloadSchema
|
|
487
487
|
});
|
|
488
|
+
var ToolSchema = import_zod3.z.object({
|
|
489
|
+
id: import_zod3.z.string(),
|
|
490
|
+
name: import_zod3.z.string(),
|
|
491
|
+
description: import_zod3.z.string(),
|
|
492
|
+
params: import_zod3.z.record(import_zod3.z.string()),
|
|
493
|
+
fn: import_zod3.z.function().args(import_zod3.z.any()).returns(import_zod3.z.any())
|
|
494
|
+
});
|
|
488
495
|
var UsersRequestPayloadSchema = import_zod3.z.object({
|
|
489
496
|
operation: import_zod3.z.enum(["create", "update", "delete", "getAll", "getOne"]),
|
|
490
497
|
data: import_zod3.z.object({
|
|
@@ -555,6 +562,26 @@ var ReportsRequestMessageSchema = import_zod3.z.object({
|
|
|
555
562
|
type: import_zod3.z.literal("REPORTS"),
|
|
556
563
|
payload: ReportsRequestPayloadSchema
|
|
557
564
|
});
|
|
565
|
+
var BookmarkDataSchema = import_zod3.z.object({
|
|
566
|
+
id: import_zod3.z.number().optional(),
|
|
567
|
+
uiblock: import_zod3.z.any(),
|
|
568
|
+
// JSON object
|
|
569
|
+
created_at: import_zod3.z.string().optional(),
|
|
570
|
+
updated_at: import_zod3.z.string().optional()
|
|
571
|
+
});
|
|
572
|
+
var BookmarksRequestPayloadSchema = import_zod3.z.object({
|
|
573
|
+
operation: import_zod3.z.enum(["create", "update", "delete", "getAll", "getOne"]),
|
|
574
|
+
data: import_zod3.z.object({
|
|
575
|
+
id: import_zod3.z.number().optional(),
|
|
576
|
+
uiblock: import_zod3.z.any().optional()
|
|
577
|
+
}).optional()
|
|
578
|
+
});
|
|
579
|
+
var BookmarksRequestMessageSchema = import_zod3.z.object({
|
|
580
|
+
id: import_zod3.z.string(),
|
|
581
|
+
from: MessageParticipantSchema,
|
|
582
|
+
type: import_zod3.z.literal("BOOKMARKS"),
|
|
583
|
+
payload: BookmarksRequestPayloadSchema
|
|
584
|
+
});
|
|
558
585
|
|
|
559
586
|
// src/utils/logger.ts
|
|
560
587
|
var import_fs = __toESM(require("fs"));
|
|
@@ -2610,6 +2637,71 @@ Format your response as a JSON object with this structure:
|
|
|
2610
2637
|
}
|
|
2611
2638
|
|
|
2612
2639
|
Return ONLY valid JSON.`
|
|
2640
|
+
},
|
|
2641
|
+
"execute-tools": {
|
|
2642
|
+
system: `You are an expert AI assistant that executes external tools to fetch data from external services.
|
|
2643
|
+
|
|
2644
|
+
You have access to external tools that can retrieve information like emails, calendar events, and other external data. When the user requests this information, you should call the appropriate tools.
|
|
2645
|
+
|
|
2646
|
+
## Available External Tools
|
|
2647
|
+
{{AVAILABLE_TOOLS}}
|
|
2648
|
+
|
|
2649
|
+
## Your Task
|
|
2650
|
+
|
|
2651
|
+
Analyze the user's request and:
|
|
2652
|
+
|
|
2653
|
+
1. **Determine if external tools are needed**
|
|
2654
|
+
- Examples that NEED external tools:
|
|
2655
|
+
- "Show me my emails" \u2192 needs email tool
|
|
2656
|
+
- "Get my last 5 Gmail messages" \u2192 needs Gmail tool
|
|
2657
|
+
- "Check my Outlook inbox" \u2192 needs Outlook tool
|
|
2658
|
+
|
|
2659
|
+
- Examples that DON'T need external tools:
|
|
2660
|
+
- "What is the total sales?" \u2192 database query (handled elsewhere)
|
|
2661
|
+
- "Show me revenue trends" \u2192 internal data analysis
|
|
2662
|
+
- "Hello" \u2192 general conversation
|
|
2663
|
+
|
|
2664
|
+
2. **Call the appropriate tools**
|
|
2665
|
+
- Use the tool calling mechanism to execute external tools
|
|
2666
|
+
- Extract parameters from the user's request
|
|
2667
|
+
- Use sensible defaults when parameters aren't specified:
|
|
2668
|
+
- For email limit: default to 10
|
|
2669
|
+
- For email address: use "me" for the authenticated user if not specified
|
|
2670
|
+
|
|
2671
|
+
3. **Handle errors and retry**
|
|
2672
|
+
- If a tool call fails, analyze the error message
|
|
2673
|
+
- Retry with corrected parameters if possible
|
|
2674
|
+
- You have up to 3 attempts per tool
|
|
2675
|
+
|
|
2676
|
+
## Important Guidelines
|
|
2677
|
+
|
|
2678
|
+
- **Only call external tools when necessary** - Don't call tools for database queries or general conversation
|
|
2679
|
+
- **Choose the right tool** - For email requests, select Gmail vs Outlook based on:
|
|
2680
|
+
- Explicit mention (e.g., "Gmail", "Outlook")
|
|
2681
|
+
- Email domain (e.g., @gmail.com \u2192 Gmail, @company.com \u2192 Outlook)
|
|
2682
|
+
- **Extract parameters carefully** - Use the user's exact values when provided
|
|
2683
|
+
- **If no tools are needed** - Simply respond that no external tools are required for this request
|
|
2684
|
+
|
|
2685
|
+
## Examples
|
|
2686
|
+
|
|
2687
|
+
**Example 1 - Gmail Request:**
|
|
2688
|
+
User: "Show me my last 5 Gmail messages"
|
|
2689
|
+
Action: Call get-gmail-mails tool with parameters: { email: "me", limit: 5 }
|
|
2690
|
+
|
|
2691
|
+
**Example 2 - Outlook Request:**
|
|
2692
|
+
User: "Get emails from john.doe@company.com"
|
|
2693
|
+
Action: Call get-outlook-mails tool with parameters: { email: "john.doe@company.com", limit: 10 }
|
|
2694
|
+
|
|
2695
|
+
**Example 3 - No Tools Needed:**
|
|
2696
|
+
User: "What is the total sales?"
|
|
2697
|
+
Response: This is a database query, not an external tool request. No external tools are needed.
|
|
2698
|
+
|
|
2699
|
+
**Example 4 - Error Retry:**
|
|
2700
|
+
Tool call fails with: "Invalid email parameter"
|
|
2701
|
+
Action: Analyze error, correct the parameter, and retry the tool call
|
|
2702
|
+
`,
|
|
2703
|
+
user: `{{USER_PROMPT}}
|
|
2704
|
+
`
|
|
2613
2705
|
}
|
|
2614
2706
|
};
|
|
2615
2707
|
|
|
@@ -3656,13 +3748,14 @@ var BaseLLM = class {
|
|
|
3656
3748
|
* Takes a text response with component suggestions (c1:type format) and matches with available components
|
|
3657
3749
|
* Also generates title, description, and intelligent follow-up questions (actions) based on the analysis
|
|
3658
3750
|
* All components are placed in a default MultiComponentContainer layout
|
|
3659
|
-
* @param
|
|
3751
|
+
* @param analysisContent - The text response containing component suggestions
|
|
3660
3752
|
* @param components - List of available components
|
|
3661
3753
|
* @param apiKey - Optional API key
|
|
3662
3754
|
* @param logCollector - Optional log collector
|
|
3755
|
+
* @param componentStreamCallback - Optional callback to stream primary KPI component as soon as it's identified
|
|
3663
3756
|
* @returns Object containing matched components, layout title/description, and follow-up actions
|
|
3664
3757
|
*/
|
|
3665
|
-
async
|
|
3758
|
+
async matchComponentsFromAnalysis(analysisContent, components, apiKey, logCollector, componentStreamCallback) {
|
|
3666
3759
|
try {
|
|
3667
3760
|
logger.debug(`[${this.getProviderName()}] Starting component matching from text response`);
|
|
3668
3761
|
let availableComponentsText = "No components available";
|
|
@@ -3679,14 +3772,94 @@ var BaseLLM = class {
|
|
|
3679
3772
|
}).join("\n\n");
|
|
3680
3773
|
}
|
|
3681
3774
|
const schemaDoc = schema.generateSchemaDocumentation();
|
|
3775
|
+
logger.file("\n=============================\nText analysis response:", analysisContent);
|
|
3682
3776
|
const prompts = await promptLoader.loadPrompts("match-text-components", {
|
|
3683
|
-
|
|
3777
|
+
ANALYSIS_CONTENT: analysisContent,
|
|
3684
3778
|
AVAILABLE_COMPONENTS: availableComponentsText,
|
|
3685
3779
|
SCHEMA_DOC: schemaDoc
|
|
3686
3780
|
});
|
|
3687
3781
|
logger.debug(`[${this.getProviderName()}] Loaded match-text-components prompts`);
|
|
3688
3782
|
logger.file("\n=============================\nmatch text components system prompt:", prompts.system);
|
|
3689
3783
|
logCollector?.info("Matching components from text response...");
|
|
3784
|
+
let fullResponseText = "";
|
|
3785
|
+
let answerComponentExtracted = false;
|
|
3786
|
+
const answerCallback = componentStreamCallback;
|
|
3787
|
+
const partialCallback = answerCallback ? (chunk) => {
|
|
3788
|
+
fullResponseText += chunk;
|
|
3789
|
+
if (!answerComponentExtracted && answerCallback) {
|
|
3790
|
+
const hasAnswerComponentMatch = fullResponseText.match(/"hasAnswerComponent"\s*:\s*(true|false)/);
|
|
3791
|
+
if (!hasAnswerComponentMatch || hasAnswerComponentMatch[1] !== "true") {
|
|
3792
|
+
return;
|
|
3793
|
+
}
|
|
3794
|
+
const answerComponentStartMatch = fullResponseText.match(/"answerComponent"\s*:\s*\{/);
|
|
3795
|
+
if (!answerComponentStartMatch) {
|
|
3796
|
+
return;
|
|
3797
|
+
}
|
|
3798
|
+
const startPos = answerComponentStartMatch.index + answerComponentStartMatch[0].length - 1;
|
|
3799
|
+
let braceDepth = 0;
|
|
3800
|
+
let inString = false;
|
|
3801
|
+
let escapeNext = false;
|
|
3802
|
+
let endPos = -1;
|
|
3803
|
+
for (let i = startPos; i < fullResponseText.length; i++) {
|
|
3804
|
+
const char = fullResponseText[i];
|
|
3805
|
+
if (escapeNext) {
|
|
3806
|
+
escapeNext = false;
|
|
3807
|
+
continue;
|
|
3808
|
+
}
|
|
3809
|
+
if (char === "\\") {
|
|
3810
|
+
escapeNext = true;
|
|
3811
|
+
continue;
|
|
3812
|
+
}
|
|
3813
|
+
if (char === '"') {
|
|
3814
|
+
inString = !inString;
|
|
3815
|
+
continue;
|
|
3816
|
+
}
|
|
3817
|
+
if (!inString) {
|
|
3818
|
+
if (char === "{") {
|
|
3819
|
+
braceDepth++;
|
|
3820
|
+
} else if (char === "}") {
|
|
3821
|
+
braceDepth--;
|
|
3822
|
+
if (braceDepth === 0) {
|
|
3823
|
+
endPos = i + 1;
|
|
3824
|
+
break;
|
|
3825
|
+
}
|
|
3826
|
+
}
|
|
3827
|
+
}
|
|
3828
|
+
}
|
|
3829
|
+
if (endPos > startPos) {
|
|
3830
|
+
const answerComponentString = fullResponseText.substring(startPos, endPos);
|
|
3831
|
+
try {
|
|
3832
|
+
const answerComponentData = JSON.parse(answerComponentString);
|
|
3833
|
+
if (answerComponentData && answerComponentData.componentId) {
|
|
3834
|
+
const originalComponent = components.find((c) => c.id === answerComponentData.componentId);
|
|
3835
|
+
if (originalComponent) {
|
|
3836
|
+
const answerComponent = {
|
|
3837
|
+
...originalComponent,
|
|
3838
|
+
props: {
|
|
3839
|
+
...originalComponent.props,
|
|
3840
|
+
...answerComponentData.props
|
|
3841
|
+
}
|
|
3842
|
+
};
|
|
3843
|
+
const streamTime = (/* @__PURE__ */ new Date()).toISOString();
|
|
3844
|
+
logger.info(`[${this.getProviderName()}] \u2713 [${streamTime}] Answer component detected in stream: ${answerComponent.name} (${answerComponent.type}) - STREAMING TO FRONTEND NOW`);
|
|
3845
|
+
logCollector?.info(`\u2713 Answer component: ${answerComponent.name} (${answerComponent.type}) - streaming to frontend at ${streamTime}`);
|
|
3846
|
+
if (answerComponentData.props?.query) {
|
|
3847
|
+
logCollector?.logQuery(
|
|
3848
|
+
"Answer component query",
|
|
3849
|
+
answerComponentData.props.query,
|
|
3850
|
+
{ componentName: answerComponent.name, componentType: answerComponent.type, reasoning: answerComponentData.reasoning }
|
|
3851
|
+
);
|
|
3852
|
+
}
|
|
3853
|
+
answerCallback(answerComponent);
|
|
3854
|
+
answerComponentExtracted = true;
|
|
3855
|
+
}
|
|
3856
|
+
}
|
|
3857
|
+
} catch (e) {
|
|
3858
|
+
logger.debug(`[${this.getProviderName()}] Partial answerComponent parse failed, waiting for more data...`);
|
|
3859
|
+
}
|
|
3860
|
+
}
|
|
3861
|
+
}
|
|
3862
|
+
} : void 0;
|
|
3690
3863
|
const result = await LLM.stream(
|
|
3691
3864
|
{
|
|
3692
3865
|
sys: prompts.system,
|
|
@@ -3696,23 +3869,54 @@ var BaseLLM = class {
|
|
|
3696
3869
|
model: this.model,
|
|
3697
3870
|
maxTokens: 3e3,
|
|
3698
3871
|
temperature: 0.2,
|
|
3699
|
-
apiKey: this.getApiKey(apiKey)
|
|
3872
|
+
apiKey: this.getApiKey(apiKey),
|
|
3873
|
+
partial: partialCallback
|
|
3700
3874
|
},
|
|
3701
3875
|
true
|
|
3702
3876
|
// Parse as JSON
|
|
3703
3877
|
);
|
|
3704
3878
|
logger.debug(`[${this.getProviderName()}] Component matching response parsed successfully`);
|
|
3879
|
+
const componentSuggestionPattern = /c\d+:(\w+)\s*:\s*(.+)/g;
|
|
3880
|
+
const suggestedComponents = [];
|
|
3881
|
+
let match;
|
|
3882
|
+
while ((match = componentSuggestionPattern.exec(analysisContent)) !== null) {
|
|
3883
|
+
suggestedComponents.push({
|
|
3884
|
+
type: match[1],
|
|
3885
|
+
reasoning: match[2].trim()
|
|
3886
|
+
});
|
|
3887
|
+
}
|
|
3705
3888
|
const matchedComponents = result.matchedComponents || [];
|
|
3706
3889
|
const layoutTitle = result.layoutTitle || "Dashboard";
|
|
3707
3890
|
const layoutDescription = result.layoutDescription || "Multi-component dashboard";
|
|
3891
|
+
logger.info(`[${this.getProviderName()}] \u{1F4CA} Component Suggestions from Text Analysis: ${suggestedComponents.length}`);
|
|
3892
|
+
suggestedComponents.forEach((comp, idx) => {
|
|
3893
|
+
logger.info(`[${this.getProviderName()}] c${idx + 1}: ${comp.type} - ${comp.reasoning}`);
|
|
3894
|
+
});
|
|
3895
|
+
logger.info(`[${this.getProviderName()}] \u{1F4E6} Matched Components from LLM: ${matchedComponents.length}`);
|
|
3896
|
+
matchedComponents.forEach((comp, idx) => {
|
|
3897
|
+
logger.info(`[${this.getProviderName()}] ${idx + 1}. ${comp.componentType} (${comp.componentName}) - ${comp.originalSuggestion || "N/A"}`);
|
|
3898
|
+
});
|
|
3899
|
+
if (suggestedComponents.length !== matchedComponents.length) {
|
|
3900
|
+
logger.warn(`[${this.getProviderName()}] \u26A0\uFE0F MISMATCH: Text suggested ${suggestedComponents.length} components, but LLM matched ${matchedComponents.length}`);
|
|
3901
|
+
}
|
|
3902
|
+
logger.file("\n=============================\nFull LLM response:", JSON.stringify(result, null, 2));
|
|
3708
3903
|
const rawActions = result.actions || [];
|
|
3709
3904
|
const actions = convertQuestionsToActions(rawActions);
|
|
3710
3905
|
logger.info(`[${this.getProviderName()}] Matched ${matchedComponents.length} components from text response`);
|
|
3711
3906
|
logger.info(`[${this.getProviderName()}] Layout title: "${layoutTitle}"`);
|
|
3712
3907
|
logger.info(`[${this.getProviderName()}] Layout description: "${layoutDescription}"`);
|
|
3713
3908
|
logger.info(`[${this.getProviderName()}] Generated ${actions.length} follow-up actions`);
|
|
3909
|
+
if (suggestedComponents.length > 0) {
|
|
3910
|
+
logCollector?.info(`\u{1F4DD} Text Analysis suggested ${suggestedComponents.length} dashboard components:`);
|
|
3911
|
+
suggestedComponents.forEach((comp, idx) => {
|
|
3912
|
+
logCollector?.info(` c${idx + 1}: ${comp.type} - ${comp.reasoning}`);
|
|
3913
|
+
});
|
|
3914
|
+
}
|
|
3714
3915
|
if (matchedComponents.length > 0) {
|
|
3715
|
-
logCollector?.info(
|
|
3916
|
+
logCollector?.info(`\u{1F4E6} Matched ${matchedComponents.length} components for dashboard`);
|
|
3917
|
+
if (suggestedComponents.length !== matchedComponents.length) {
|
|
3918
|
+
logCollector?.warn(`\u26A0\uFE0F Component count mismatch: Suggested ${suggestedComponents.length}, but matched ${matchedComponents.length}`);
|
|
3919
|
+
}
|
|
3716
3920
|
logCollector?.info(`Dashboard: "${layoutTitle}"`);
|
|
3717
3921
|
matchedComponents.forEach((comp, idx) => {
|
|
3718
3922
|
logCollector?.info(` ${idx + 1}. ${comp.componentName} (${comp.componentType}): ${comp.reasoning}`);
|
|
@@ -3763,6 +3967,152 @@ var BaseLLM = class {
|
|
|
3763
3967
|
};
|
|
3764
3968
|
}
|
|
3765
3969
|
}
|
|
3970
|
+
/**
|
|
3971
|
+
* Execute external tools based on user request using agentic LLM tool calling
|
|
3972
|
+
* The LLM can directly call tools and retry on errors
|
|
3973
|
+
* @param userPrompt - The user's question/request
|
|
3974
|
+
* @param availableTools - Array of available external tools
|
|
3975
|
+
* @param apiKey - Optional API key for LLM
|
|
3976
|
+
* @param logCollector - Optional log collector
|
|
3977
|
+
* @returns Object containing tool execution results and summary
|
|
3978
|
+
*/
|
|
3979
|
+
async executeExternalTools(userPrompt, availableTools, apiKey, logCollector) {
|
|
3980
|
+
const MAX_TOOL_ATTEMPTS = 3;
|
|
3981
|
+
const toolResults = [];
|
|
3982
|
+
try {
|
|
3983
|
+
logger.debug(`[${this.getProviderName()}] Starting agentic external tool execution`);
|
|
3984
|
+
logger.debug(`[${this.getProviderName()}] Available tools: ${availableTools.map((t) => t.name).join(", ")}`);
|
|
3985
|
+
const llmTools = availableTools.map((tool) => {
|
|
3986
|
+
const properties = {};
|
|
3987
|
+
const required = [];
|
|
3988
|
+
Object.entries(tool.params || {}).forEach(([key, type]) => {
|
|
3989
|
+
properties[key] = {
|
|
3990
|
+
type: String(type).toLowerCase(),
|
|
3991
|
+
description: `${key} parameter`
|
|
3992
|
+
};
|
|
3993
|
+
required.push(key);
|
|
3994
|
+
});
|
|
3995
|
+
return {
|
|
3996
|
+
name: tool.id,
|
|
3997
|
+
description: tool.description,
|
|
3998
|
+
input_schema: {
|
|
3999
|
+
type: "object",
|
|
4000
|
+
properties,
|
|
4001
|
+
required
|
|
4002
|
+
}
|
|
4003
|
+
};
|
|
4004
|
+
});
|
|
4005
|
+
const toolAttempts = /* @__PURE__ */ new Map();
|
|
4006
|
+
const toolHandler = async (toolName, toolInput) => {
|
|
4007
|
+
const tool = availableTools.find((t) => t.id === toolName);
|
|
4008
|
+
if (!tool) {
|
|
4009
|
+
const errorMsg = `Tool ${toolName} not found in available tools`;
|
|
4010
|
+
logger.error(`[${this.getProviderName()}] ${errorMsg}`);
|
|
4011
|
+
logCollector?.error(errorMsg);
|
|
4012
|
+
throw new Error(errorMsg);
|
|
4013
|
+
}
|
|
4014
|
+
const attempts = (toolAttempts.get(toolName) || 0) + 1;
|
|
4015
|
+
toolAttempts.set(toolName, attempts);
|
|
4016
|
+
logger.info(`[${this.getProviderName()}] Executing tool: ${tool.name} (attempt ${attempts}/${MAX_TOOL_ATTEMPTS})`);
|
|
4017
|
+
logCollector?.info(`Executing ${tool.name} (attempt ${attempts}/${MAX_TOOL_ATTEMPTS})...`);
|
|
4018
|
+
if (attempts > MAX_TOOL_ATTEMPTS) {
|
|
4019
|
+
const errorMsg = `Maximum attempts (${MAX_TOOL_ATTEMPTS}) reached for tool: ${tool.name}`;
|
|
4020
|
+
logger.error(`[${this.getProviderName()}] ${errorMsg}`);
|
|
4021
|
+
logCollector?.error(errorMsg);
|
|
4022
|
+
toolResults.push({
|
|
4023
|
+
toolName: tool.name,
|
|
4024
|
+
toolId: tool.id,
|
|
4025
|
+
result: null,
|
|
4026
|
+
error: errorMsg
|
|
4027
|
+
});
|
|
4028
|
+
throw new Error(errorMsg);
|
|
4029
|
+
}
|
|
4030
|
+
try {
|
|
4031
|
+
logger.debug(`[${this.getProviderName()}] Tool ${tool.name} parameters:`, toolInput);
|
|
4032
|
+
const result2 = await tool.fn(toolInput);
|
|
4033
|
+
logger.info(`[${this.getProviderName()}] Tool ${tool.name} executed successfully`);
|
|
4034
|
+
logCollector?.info(`\u2713 ${tool.name} completed successfully`);
|
|
4035
|
+
toolResults.push({
|
|
4036
|
+
toolName: tool.name,
|
|
4037
|
+
toolId: tool.id,
|
|
4038
|
+
result: result2
|
|
4039
|
+
});
|
|
4040
|
+
return JSON.stringify(result2, null, 2);
|
|
4041
|
+
} catch (error) {
|
|
4042
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
4043
|
+
logger.error(`[${this.getProviderName()}] Tool ${tool.name} failed (attempt ${attempts}): ${errorMsg}`);
|
|
4044
|
+
logCollector?.error(`\u2717 ${tool.name} failed: ${errorMsg}`);
|
|
4045
|
+
if (attempts >= MAX_TOOL_ATTEMPTS) {
|
|
4046
|
+
toolResults.push({
|
|
4047
|
+
toolName: tool.name,
|
|
4048
|
+
toolId: tool.id,
|
|
4049
|
+
result: null,
|
|
4050
|
+
error: errorMsg
|
|
4051
|
+
});
|
|
4052
|
+
}
|
|
4053
|
+
throw new Error(`Tool execution failed: ${errorMsg}`);
|
|
4054
|
+
}
|
|
4055
|
+
};
|
|
4056
|
+
const prompts = await promptLoader.loadPrompts("execute-tools", {
|
|
4057
|
+
USER_PROMPT: userPrompt,
|
|
4058
|
+
AVAILABLE_TOOLS: availableTools.map((tool, idx) => {
|
|
4059
|
+
const paramsText = Object.entries(tool.params || {}).map(([key, type]) => ` - ${key}: ${type}`).join("\n");
|
|
4060
|
+
return `${idx + 1}. ID: ${tool.id}
|
|
4061
|
+
Name: ${tool.name}
|
|
4062
|
+
Description: ${tool.description}
|
|
4063
|
+
Parameters:
|
|
4064
|
+
${paramsText}`;
|
|
4065
|
+
}).join("\n\n")
|
|
4066
|
+
});
|
|
4067
|
+
logger.debug(`[${this.getProviderName()}] Using agentic tool calling for external tools`);
|
|
4068
|
+
logCollector?.info("Analyzing request and executing external tools...");
|
|
4069
|
+
const result = await LLM.streamWithTools(
|
|
4070
|
+
{
|
|
4071
|
+
sys: prompts.system,
|
|
4072
|
+
user: prompts.user
|
|
4073
|
+
},
|
|
4074
|
+
llmTools,
|
|
4075
|
+
toolHandler,
|
|
4076
|
+
{
|
|
4077
|
+
model: this.model,
|
|
4078
|
+
maxTokens: 2e3,
|
|
4079
|
+
temperature: 0.2,
|
|
4080
|
+
apiKey: this.getApiKey(apiKey)
|
|
4081
|
+
},
|
|
4082
|
+
MAX_TOOL_ATTEMPTS + 2
|
|
4083
|
+
// max iterations: allows for retries + final response
|
|
4084
|
+
);
|
|
4085
|
+
logger.info(`[${this.getProviderName()}] External tool execution completed`);
|
|
4086
|
+
const successfulTools = toolResults.filter((r) => !r.error);
|
|
4087
|
+
const failedTools = toolResults.filter((r) => r.error);
|
|
4088
|
+
let summary = "";
|
|
4089
|
+
if (successfulTools.length > 0) {
|
|
4090
|
+
summary += `Successfully executed ${successfulTools.length} tool(s): ${successfulTools.map((t) => t.toolName).join(", ")}.
|
|
4091
|
+
`;
|
|
4092
|
+
}
|
|
4093
|
+
if (failedTools.length > 0) {
|
|
4094
|
+
summary += `Failed to execute ${failedTools.length} tool(s): ${failedTools.map((t) => t.toolName).join(", ")}.`;
|
|
4095
|
+
}
|
|
4096
|
+
if (toolResults.length === 0) {
|
|
4097
|
+
summary = "No external tools were needed for this request.";
|
|
4098
|
+
}
|
|
4099
|
+
logger.info(`[${this.getProviderName()}] Tool execution summary: ${summary}`);
|
|
4100
|
+
return {
|
|
4101
|
+
toolResults,
|
|
4102
|
+
summary,
|
|
4103
|
+
hasResults: successfulTools.length > 0
|
|
4104
|
+
};
|
|
4105
|
+
} catch (error) {
|
|
4106
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
4107
|
+
logger.error(`[${this.getProviderName()}] Error in external tool execution: ${errorMsg}`);
|
|
4108
|
+
logCollector?.error(`Error executing external tools: ${errorMsg}`);
|
|
4109
|
+
return {
|
|
4110
|
+
toolResults,
|
|
4111
|
+
summary: `Error executing external tools: ${errorMsg}`,
|
|
4112
|
+
hasResults: false
|
|
4113
|
+
};
|
|
4114
|
+
}
|
|
4115
|
+
}
|
|
3766
4116
|
/**
|
|
3767
4117
|
* Generate text-based response for user question
|
|
3768
4118
|
* This provides conversational text responses instead of component generation
|
|
@@ -3771,12 +4121,40 @@ var BaseLLM = class {
|
|
|
3771
4121
|
* @param streamCallback - Optional callback function to receive text chunks as they stream
|
|
3772
4122
|
* @param collections - Collection registry for executing database queries via database.execute
|
|
3773
4123
|
* @param components - Optional list of available components for matching suggestions
|
|
4124
|
+
* @param externalTools - Optional array of external tools (email, calendar, etc.) that can be called
|
|
3774
4125
|
*/
|
|
3775
|
-
async generateTextResponse(userPrompt, apiKey, logCollector, conversationHistory, streamCallback, collections, components) {
|
|
4126
|
+
async generateTextResponse(userPrompt, apiKey, logCollector, conversationHistory, streamCallback, collections, components, externalTools) {
|
|
3776
4127
|
const errors = [];
|
|
3777
4128
|
logger.debug(`[${this.getProviderName()}] Starting text response generation`);
|
|
3778
4129
|
logger.debug(`[${this.getProviderName()}] User prompt: "${userPrompt.substring(0, 50)}..."`);
|
|
3779
4130
|
try {
|
|
4131
|
+
let externalToolContext = "No external tools were used for this request.";
|
|
4132
|
+
if (externalTools && externalTools.length > 0) {
|
|
4133
|
+
logger.info(`[${this.getProviderName()}] Executing external tools...`);
|
|
4134
|
+
const toolExecution = await this.executeExternalTools(
|
|
4135
|
+
userPrompt,
|
|
4136
|
+
externalTools,
|
|
4137
|
+
apiKey,
|
|
4138
|
+
logCollector
|
|
4139
|
+
);
|
|
4140
|
+
if (toolExecution.hasResults) {
|
|
4141
|
+
const toolResultsText = toolExecution.toolResults.map((tr) => {
|
|
4142
|
+
if (tr.error) {
|
|
4143
|
+
return `**${tr.toolName}** (Failed): ${tr.error}`;
|
|
4144
|
+
}
|
|
4145
|
+
return `**${tr.toolName}** (Success):
|
|
4146
|
+
${JSON.stringify(tr.result, null, 2)}`;
|
|
4147
|
+
}).join("\n\n");
|
|
4148
|
+
externalToolContext = `## External Tool Results
|
|
4149
|
+
|
|
4150
|
+
${toolExecution.summary}
|
|
4151
|
+
|
|
4152
|
+
${toolResultsText}`;
|
|
4153
|
+
logger.info(`[${this.getProviderName()}] External tools executed, results available`);
|
|
4154
|
+
} else {
|
|
4155
|
+
logger.info(`[${this.getProviderName()}] No external tools were needed`);
|
|
4156
|
+
}
|
|
4157
|
+
}
|
|
3780
4158
|
const schemaDoc = schema.generateSchemaDocumentation();
|
|
3781
4159
|
const knowledgeBaseContext = await knowledge_base_default.getKnowledgeBase({
|
|
3782
4160
|
prompt: userPrompt,
|
|
@@ -3784,11 +4162,13 @@ var BaseLLM = class {
|
|
|
3784
4162
|
topK: 1
|
|
3785
4163
|
});
|
|
3786
4164
|
logger.file("\n=============================\nknowledge base context:", knowledgeBaseContext);
|
|
4165
|
+
logger.file("\n=============================\nexternal tool context:", externalToolContext);
|
|
3787
4166
|
const prompts = await promptLoader.loadPrompts("text-response", {
|
|
3788
4167
|
USER_PROMPT: userPrompt,
|
|
3789
4168
|
CONVERSATION_HISTORY: conversationHistory || "No previous conversation",
|
|
3790
4169
|
SCHEMA_DOC: schemaDoc,
|
|
3791
|
-
KNOWLEDGE_BASE_CONTEXT: knowledgeBaseContext || "No additional knowledge base context available."
|
|
4170
|
+
KNOWLEDGE_BASE_CONTEXT: knowledgeBaseContext || "No additional knowledge base context available.",
|
|
4171
|
+
EXTERNAL_TOOL_CONTEXT: externalToolContext
|
|
3792
4172
|
});
|
|
3793
4173
|
logger.file("\n=============================\nsystem prompt:", prompts.system);
|
|
3794
4174
|
logger.file("\n=============================\nuser prompt:", prompts.user);
|
|
@@ -4011,11 +4391,17 @@ ${errorMsg}
|
|
|
4011
4391
|
let actions = [];
|
|
4012
4392
|
if (components && components.length > 0) {
|
|
4013
4393
|
logger.info(`[${this.getProviderName()}] Matching components from text response...`);
|
|
4014
|
-
const
|
|
4394
|
+
const componentStreamCallback = wrappedStreamCallback ? (component) => {
|
|
4395
|
+
const answerMarker = `__ANSWER_COMPONENT_START__${JSON.stringify(component)}__ANSWER_COMPONENT_END__`;
|
|
4396
|
+
wrappedStreamCallback(answerMarker);
|
|
4397
|
+
logger.info(`[${this.getProviderName()}] Streamed answer component to frontend: ${component.name} (${component.type})`);
|
|
4398
|
+
} : void 0;
|
|
4399
|
+
const matchResult = await this.matchComponentsFromAnalysis(
|
|
4015
4400
|
textResponse,
|
|
4016
4401
|
components,
|
|
4017
4402
|
apiKey,
|
|
4018
|
-
logCollector
|
|
4403
|
+
logCollector,
|
|
4404
|
+
componentStreamCallback
|
|
4019
4405
|
);
|
|
4020
4406
|
matchedComponents = matchResult.components;
|
|
4021
4407
|
layoutTitle = matchResult.layoutTitle;
|
|
@@ -4259,8 +4645,9 @@ ${errorMsg}
|
|
|
4259
4645
|
* @param responseMode - 'component' for component generation (default), 'text' for text responses
|
|
4260
4646
|
* @param streamCallback - Optional callback function to receive text chunks as they stream (only for text mode)
|
|
4261
4647
|
* @param collections - Collection registry for executing database queries (required for text mode)
|
|
4648
|
+
* @param externalTools - Optional array of external tools (email, calendar, etc.) that can be called (only for text mode)
|
|
4262
4649
|
*/
|
|
4263
|
-
async handleUserRequest(userPrompt, components, apiKey, logCollector, conversationHistory, responseMode = "component", streamCallback, collections) {
|
|
4650
|
+
async handleUserRequest(userPrompt, components, apiKey, logCollector, conversationHistory, responseMode = "component", streamCallback, collections, externalTools) {
|
|
4264
4651
|
const startTime = Date.now();
|
|
4265
4652
|
logger.info(`[${this.getProviderName()}] handleUserRequest called with responseMode: ${responseMode}`);
|
|
4266
4653
|
if (responseMode === "text") {
|
|
@@ -4273,7 +4660,8 @@ ${errorMsg}
|
|
|
4273
4660
|
conversationHistory,
|
|
4274
4661
|
streamCallback,
|
|
4275
4662
|
collections,
|
|
4276
|
-
components
|
|
4663
|
+
components,
|
|
4664
|
+
externalTools
|
|
4277
4665
|
);
|
|
4278
4666
|
if (!textResponse.success) {
|
|
4279
4667
|
const elapsedTime3 = Date.now() - startTime;
|
|
@@ -4419,7 +4807,7 @@ function getLLMProviders() {
|
|
|
4419
4807
|
return DEFAULT_PROVIDERS;
|
|
4420
4808
|
}
|
|
4421
4809
|
}
|
|
4422
|
-
var useAnthropicMethod = async (prompt, components, apiKey, logCollector, conversationHistory, responseMode = "component", streamCallback, collections) => {
|
|
4810
|
+
var useAnthropicMethod = async (prompt, components, apiKey, logCollector, conversationHistory, responseMode = "component", streamCallback, collections, externalTools) => {
|
|
4423
4811
|
logger.debug("[useAnthropicMethod] Initializing Anthropic Claude matching method");
|
|
4424
4812
|
logger.debug(`[useAnthropicMethod] Response mode: ${responseMode}`);
|
|
4425
4813
|
const msg = `Using Anthropic Claude ${responseMode === "text" ? "text response" : "matching"} method...`;
|
|
@@ -4431,11 +4819,11 @@ var useAnthropicMethod = async (prompt, components, apiKey, logCollector, conver
|
|
|
4431
4819
|
return { success: false, errors: [emptyMsg] };
|
|
4432
4820
|
}
|
|
4433
4821
|
logger.debug(`[useAnthropicMethod] Processing with ${components.length} components`);
|
|
4434
|
-
const matchResult = await anthropicLLM.handleUserRequest(prompt, components, apiKey, logCollector, conversationHistory, responseMode, streamCallback, collections);
|
|
4822
|
+
const matchResult = await anthropicLLM.handleUserRequest(prompt, components, apiKey, logCollector, conversationHistory, responseMode, streamCallback, collections, externalTools);
|
|
4435
4823
|
logger.info(`[useAnthropicMethod] Successfully generated ${responseMode} using Anthropic`);
|
|
4436
4824
|
return matchResult;
|
|
4437
4825
|
};
|
|
4438
|
-
var useGroqMethod = async (prompt, components, apiKey, logCollector, conversationHistory, responseMode = "component", streamCallback, collections) => {
|
|
4826
|
+
var useGroqMethod = async (prompt, components, apiKey, logCollector, conversationHistory, responseMode = "component", streamCallback, collections, externalTools) => {
|
|
4439
4827
|
logger.debug("[useGroqMethod] Initializing Groq LLM matching method");
|
|
4440
4828
|
logger.debug(`[useGroqMethod] Response mode: ${responseMode}`);
|
|
4441
4829
|
const msg = `Using Groq LLM ${responseMode === "text" ? "text response" : "matching"} method...`;
|
|
@@ -4448,14 +4836,14 @@ var useGroqMethod = async (prompt, components, apiKey, logCollector, conversatio
|
|
|
4448
4836
|
return { success: false, errors: [emptyMsg] };
|
|
4449
4837
|
}
|
|
4450
4838
|
logger.debug(`[useGroqMethod] Processing with ${components.length} components`);
|
|
4451
|
-
const matchResult = await groqLLM.handleUserRequest(prompt, components, apiKey, logCollector, conversationHistory, responseMode, streamCallback, collections);
|
|
4839
|
+
const matchResult = await groqLLM.handleUserRequest(prompt, components, apiKey, logCollector, conversationHistory, responseMode, streamCallback, collections, externalTools);
|
|
4452
4840
|
logger.info(`[useGroqMethod] Successfully generated ${responseMode} using Groq`);
|
|
4453
4841
|
return matchResult;
|
|
4454
4842
|
};
|
|
4455
4843
|
var getUserResponseFromCache = async (prompt) => {
|
|
4456
4844
|
return false;
|
|
4457
4845
|
};
|
|
4458
|
-
var get_user_response = async (prompt, components, anthropicApiKey, groqApiKey, llmProviders, logCollector, conversationHistory, responseMode = "component", streamCallback, collections) => {
|
|
4846
|
+
var get_user_response = async (prompt, components, anthropicApiKey, groqApiKey, llmProviders, logCollector, conversationHistory, responseMode = "component", streamCallback, collections, externalTools) => {
|
|
4459
4847
|
logger.debug(`[get_user_response] Starting user response generation for prompt: "${prompt.substring(0, 50)}..."`);
|
|
4460
4848
|
logger.debug(`[get_user_response] Response mode: ${responseMode}`);
|
|
4461
4849
|
logger.debug("[get_user_response] Checking cache for existing response");
|
|
@@ -4488,9 +4876,9 @@ var get_user_response = async (prompt, components, anthropicApiKey, groqApiKey,
|
|
|
4488
4876
|
logCollector?.info(attemptMsg);
|
|
4489
4877
|
let result;
|
|
4490
4878
|
if (provider === "anthropic") {
|
|
4491
|
-
result = await useAnthropicMethod(prompt, components, anthropicApiKey, logCollector, conversationHistory, responseMode, streamCallback, collections);
|
|
4879
|
+
result = await useAnthropicMethod(prompt, components, anthropicApiKey, logCollector, conversationHistory, responseMode, streamCallback, collections, externalTools);
|
|
4492
4880
|
} else if (provider === "groq") {
|
|
4493
|
-
result = await useGroqMethod(prompt, components, groqApiKey, logCollector, conversationHistory, responseMode, streamCallback, collections);
|
|
4881
|
+
result = await useGroqMethod(prompt, components, groqApiKey, logCollector, conversationHistory, responseMode, streamCallback, collections, externalTools);
|
|
4494
4882
|
} else {
|
|
4495
4883
|
logger.warn(`[get_user_response] Unknown provider: ${provider} - skipping`);
|
|
4496
4884
|
errors.push(`Unknown provider: ${provider}`);
|
|
@@ -4718,7 +5106,7 @@ var CONTEXT_CONFIG = {
|
|
|
4718
5106
|
};
|
|
4719
5107
|
|
|
4720
5108
|
// src/handlers/user-prompt-request.ts
|
|
4721
|
-
var get_user_request = async (data, components, sendMessage, anthropicApiKey, groqApiKey, llmProviders, collections) => {
|
|
5109
|
+
var get_user_request = async (data, components, sendMessage, anthropicApiKey, groqApiKey, llmProviders, collections, externalTools) => {
|
|
4722
5110
|
const errors = [];
|
|
4723
5111
|
logger.debug("[USER_PROMPT_REQ] Parsing incoming message data");
|
|
4724
5112
|
const parseResult = UserPromptRequestMessageSchema.safeParse(data);
|
|
@@ -4798,7 +5186,8 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
4798
5186
|
conversationHistory,
|
|
4799
5187
|
responseMode,
|
|
4800
5188
|
streamCallback,
|
|
4801
|
-
collections
|
|
5189
|
+
collections,
|
|
5190
|
+
externalTools
|
|
4802
5191
|
);
|
|
4803
5192
|
logCollector.info("User prompt request completed");
|
|
4804
5193
|
const uiBlockId = existingUiBlockId;
|
|
@@ -4859,8 +5248,8 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
4859
5248
|
wsId
|
|
4860
5249
|
};
|
|
4861
5250
|
};
|
|
4862
|
-
async function handleUserPromptRequest(data, components, sendMessage, anthropicApiKey, groqApiKey, llmProviders, collections) {
|
|
4863
|
-
const response = await get_user_request(data, components, sendMessage, anthropicApiKey, groqApiKey, llmProviders, collections);
|
|
5251
|
+
async function handleUserPromptRequest(data, components, sendMessage, anthropicApiKey, groqApiKey, llmProviders, collections, externalTools) {
|
|
5252
|
+
const response = await get_user_request(data, components, sendMessage, anthropicApiKey, groqApiKey, llmProviders, collections, externalTools);
|
|
4864
5253
|
sendDataResponse4(
|
|
4865
5254
|
response.id || data.id,
|
|
4866
5255
|
{
|
|
@@ -4887,7 +5276,6 @@ function sendDataResponse4(id, res, sendMessage, clientId) {
|
|
|
4887
5276
|
...res
|
|
4888
5277
|
}
|
|
4889
5278
|
};
|
|
4890
|
-
logger.info("sending user prompt response", response);
|
|
4891
5279
|
sendMessage(response);
|
|
4892
5280
|
}
|
|
4893
5281
|
|
|
@@ -5934,6 +6322,183 @@ function sendResponse5(id, res, sendMessage, clientId) {
|
|
|
5934
6322
|
sendMessage(response);
|
|
5935
6323
|
}
|
|
5936
6324
|
|
|
6325
|
+
// src/handlers/bookmarks.ts
|
|
6326
|
+
async function handleBookmarksRequest(data, collections, sendMessage) {
|
|
6327
|
+
const executeCollection = async (collection, op, params) => {
|
|
6328
|
+
const handler = collections[collection]?.[op];
|
|
6329
|
+
if (!handler) {
|
|
6330
|
+
throw new Error(`Collection operation ${collection}.${op} not found`);
|
|
6331
|
+
}
|
|
6332
|
+
return await handler(params);
|
|
6333
|
+
};
|
|
6334
|
+
try {
|
|
6335
|
+
const request = BookmarksRequestMessageSchema.parse(data);
|
|
6336
|
+
const { id, payload, from } = request;
|
|
6337
|
+
const { operation, data: requestData } = payload;
|
|
6338
|
+
const bookmarkId = requestData?.id;
|
|
6339
|
+
const uiblock = requestData?.uiblock;
|
|
6340
|
+
switch (operation) {
|
|
6341
|
+
case "create":
|
|
6342
|
+
await handleCreate4(id, uiblock, executeCollection, sendMessage, from.id);
|
|
6343
|
+
break;
|
|
6344
|
+
case "update":
|
|
6345
|
+
await handleUpdate4(id, bookmarkId, uiblock, executeCollection, sendMessage, from.id);
|
|
6346
|
+
break;
|
|
6347
|
+
case "delete":
|
|
6348
|
+
await handleDelete4(id, bookmarkId, executeCollection, sendMessage, from.id);
|
|
6349
|
+
break;
|
|
6350
|
+
case "getAll":
|
|
6351
|
+
await handleGetAll4(id, executeCollection, sendMessage, from.id);
|
|
6352
|
+
break;
|
|
6353
|
+
case "getOne":
|
|
6354
|
+
await handleGetOne4(id, bookmarkId, executeCollection, sendMessage, from.id);
|
|
6355
|
+
break;
|
|
6356
|
+
default:
|
|
6357
|
+
sendResponse6(id, {
|
|
6358
|
+
success: false,
|
|
6359
|
+
error: `Unknown operation: ${operation}`
|
|
6360
|
+
}, sendMessage, from.id);
|
|
6361
|
+
}
|
|
6362
|
+
} catch (error) {
|
|
6363
|
+
logger.error("Failed to handle bookmarks request:", error);
|
|
6364
|
+
sendResponse6(null, {
|
|
6365
|
+
success: false,
|
|
6366
|
+
error: error instanceof Error ? error.message : "Unknown error occurred"
|
|
6367
|
+
}, sendMessage);
|
|
6368
|
+
}
|
|
6369
|
+
}
|
|
6370
|
+
async function handleCreate4(id, uiblock, executeCollection, sendMessage, clientId) {
|
|
6371
|
+
if (!uiblock) {
|
|
6372
|
+
sendResponse6(id, {
|
|
6373
|
+
success: false,
|
|
6374
|
+
error: "UIBlock data is required"
|
|
6375
|
+
}, sendMessage, clientId);
|
|
6376
|
+
return;
|
|
6377
|
+
}
|
|
6378
|
+
try {
|
|
6379
|
+
const result = await executeCollection("bookmarks", "create", { uiblock });
|
|
6380
|
+
sendResponse6(id, {
|
|
6381
|
+
success: true,
|
|
6382
|
+
data: result.data,
|
|
6383
|
+
message: "Bookmark created successfully"
|
|
6384
|
+
}, sendMessage, clientId);
|
|
6385
|
+
logger.info(`Bookmark created: ID ${result.data.id}`);
|
|
6386
|
+
} catch (error) {
|
|
6387
|
+
sendResponse6(id, {
|
|
6388
|
+
success: false,
|
|
6389
|
+
error: error instanceof Error ? error.message : "Failed to create bookmark"
|
|
6390
|
+
}, sendMessage, clientId);
|
|
6391
|
+
}
|
|
6392
|
+
}
|
|
6393
|
+
async function handleUpdate4(id, bookmarkId, uiblock, executeCollection, sendMessage, clientId) {
|
|
6394
|
+
if (!bookmarkId) {
|
|
6395
|
+
sendResponse6(id, {
|
|
6396
|
+
success: false,
|
|
6397
|
+
error: "Bookmark ID is required"
|
|
6398
|
+
}, sendMessage, clientId);
|
|
6399
|
+
return;
|
|
6400
|
+
}
|
|
6401
|
+
if (!uiblock) {
|
|
6402
|
+
sendResponse6(id, {
|
|
6403
|
+
success: false,
|
|
6404
|
+
error: "UIBlock data is required"
|
|
6405
|
+
}, sendMessage, clientId);
|
|
6406
|
+
return;
|
|
6407
|
+
}
|
|
6408
|
+
try {
|
|
6409
|
+
const result = await executeCollection("bookmarks", "update", { id: bookmarkId, uiblock });
|
|
6410
|
+
sendResponse6(id, {
|
|
6411
|
+
success: true,
|
|
6412
|
+
data: result.data,
|
|
6413
|
+
message: "Bookmark updated successfully"
|
|
6414
|
+
}, sendMessage, clientId);
|
|
6415
|
+
logger.info(`Bookmark updated: ID ${bookmarkId}`);
|
|
6416
|
+
} catch (error) {
|
|
6417
|
+
sendResponse6(id, {
|
|
6418
|
+
success: false,
|
|
6419
|
+
error: error instanceof Error ? error.message : "Failed to update bookmark"
|
|
6420
|
+
}, sendMessage, clientId);
|
|
6421
|
+
}
|
|
6422
|
+
}
|
|
6423
|
+
async function handleDelete4(id, bookmarkId, executeCollection, sendMessage, clientId) {
|
|
6424
|
+
if (!bookmarkId) {
|
|
6425
|
+
sendResponse6(id, {
|
|
6426
|
+
success: false,
|
|
6427
|
+
error: "Bookmark ID is required"
|
|
6428
|
+
}, sendMessage, clientId);
|
|
6429
|
+
return;
|
|
6430
|
+
}
|
|
6431
|
+
try {
|
|
6432
|
+
const result = await executeCollection("bookmarks", "delete", { id: bookmarkId });
|
|
6433
|
+
sendResponse6(id, {
|
|
6434
|
+
success: true,
|
|
6435
|
+
data: result.data,
|
|
6436
|
+
message: "Bookmark deleted successfully"
|
|
6437
|
+
}, sendMessage, clientId);
|
|
6438
|
+
logger.info(`Bookmark deleted: ID ${bookmarkId}`);
|
|
6439
|
+
} catch (error) {
|
|
6440
|
+
sendResponse6(id, {
|
|
6441
|
+
success: false,
|
|
6442
|
+
error: error instanceof Error ? error.message : "Failed to delete bookmark"
|
|
6443
|
+
}, sendMessage, clientId);
|
|
6444
|
+
}
|
|
6445
|
+
}
|
|
6446
|
+
async function handleGetAll4(id, executeCollection, sendMessage, clientId) {
|
|
6447
|
+
try {
|
|
6448
|
+
const result = await executeCollection("bookmarks", "getAll", {});
|
|
6449
|
+
sendResponse6(id, {
|
|
6450
|
+
success: true,
|
|
6451
|
+
data: result.data,
|
|
6452
|
+
count: result.count,
|
|
6453
|
+
message: `Retrieved ${result.count} bookmarks`
|
|
6454
|
+
}, sendMessage, clientId);
|
|
6455
|
+
logger.info(`Retrieved all bookmarks (count: ${result.count})`);
|
|
6456
|
+
} catch (error) {
|
|
6457
|
+
sendResponse6(id, {
|
|
6458
|
+
success: false,
|
|
6459
|
+
error: error instanceof Error ? error.message : "Failed to get bookmarks"
|
|
6460
|
+
}, sendMessage, clientId);
|
|
6461
|
+
}
|
|
6462
|
+
}
|
|
6463
|
+
async function handleGetOne4(id, bookmarkId, executeCollection, sendMessage, clientId) {
|
|
6464
|
+
if (!bookmarkId) {
|
|
6465
|
+
sendResponse6(id, {
|
|
6466
|
+
success: false,
|
|
6467
|
+
error: "Bookmark ID is required"
|
|
6468
|
+
}, sendMessage, clientId);
|
|
6469
|
+
return;
|
|
6470
|
+
}
|
|
6471
|
+
try {
|
|
6472
|
+
const result = await executeCollection("bookmarks", "getOne", { id: bookmarkId });
|
|
6473
|
+
sendResponse6(id, {
|
|
6474
|
+
success: true,
|
|
6475
|
+
data: result.data,
|
|
6476
|
+
message: `Retrieved bookmark ID ${bookmarkId}`
|
|
6477
|
+
}, sendMessage, clientId);
|
|
6478
|
+
logger.info(`Retrieved bookmark: ID ${bookmarkId}`);
|
|
6479
|
+
} catch (error) {
|
|
6480
|
+
sendResponse6(id, {
|
|
6481
|
+
success: false,
|
|
6482
|
+
error: error instanceof Error ? error.message : "Failed to get bookmark"
|
|
6483
|
+
}, sendMessage, clientId);
|
|
6484
|
+
}
|
|
6485
|
+
}
|
|
6486
|
+
function sendResponse6(id, res, sendMessage, clientId) {
|
|
6487
|
+
const response = {
|
|
6488
|
+
id: id || "unknown",
|
|
6489
|
+
type: "BOOKMARKS_RES",
|
|
6490
|
+
from: { type: "data-agent" },
|
|
6491
|
+
to: {
|
|
6492
|
+
type: "user",
|
|
6493
|
+
id: clientId
|
|
6494
|
+
},
|
|
6495
|
+
payload: {
|
|
6496
|
+
...res
|
|
6497
|
+
}
|
|
6498
|
+
};
|
|
6499
|
+
sendMessage(response);
|
|
6500
|
+
}
|
|
6501
|
+
|
|
5937
6502
|
// src/auth/user-manager.ts
|
|
5938
6503
|
var import_fs4 = __toESM(require("fs"));
|
|
5939
6504
|
var import_path3 = __toESM(require("path"));
|
|
@@ -6758,6 +7323,7 @@ var SuperatomSDK = class {
|
|
|
6758
7323
|
this.maxReconnectAttempts = 5;
|
|
6759
7324
|
this.collections = {};
|
|
6760
7325
|
this.components = [];
|
|
7326
|
+
this.tools = [];
|
|
6761
7327
|
if (config.logLevel) {
|
|
6762
7328
|
logger.setLogLevel(config.logLevel);
|
|
6763
7329
|
}
|
|
@@ -6913,7 +7479,7 @@ var SuperatomSDK = class {
|
|
|
6913
7479
|
});
|
|
6914
7480
|
break;
|
|
6915
7481
|
case "USER_PROMPT_REQ":
|
|
6916
|
-
handleUserPromptRequest(parsed, this.components, (msg) => this.send(msg), this.anthropicApiKey, this.groqApiKey, this.llmProviders, this.collections).catch((error) => {
|
|
7482
|
+
handleUserPromptRequest(parsed, this.components, (msg) => this.send(msg), this.anthropicApiKey, this.groqApiKey, this.llmProviders, this.collections, this.tools).catch((error) => {
|
|
6917
7483
|
logger.error("Failed to handle user prompt request:", error);
|
|
6918
7484
|
});
|
|
6919
7485
|
break;
|
|
@@ -6947,6 +7513,11 @@ var SuperatomSDK = class {
|
|
|
6947
7513
|
logger.error("Failed to handle reports request:", error);
|
|
6948
7514
|
});
|
|
6949
7515
|
break;
|
|
7516
|
+
case "BOOKMARKS":
|
|
7517
|
+
handleBookmarksRequest(parsed, this.collections, (msg) => this.send(msg)).catch((error) => {
|
|
7518
|
+
logger.error("Failed to handle bookmarks request:", error);
|
|
7519
|
+
});
|
|
7520
|
+
break;
|
|
6950
7521
|
default:
|
|
6951
7522
|
const handler = this.messageTypeHandlers.get(message.type);
|
|
6952
7523
|
if (handler) {
|
|
@@ -7053,6 +7624,19 @@ var SuperatomSDK = class {
|
|
|
7053
7624
|
storeComponents(components) {
|
|
7054
7625
|
this.components = components;
|
|
7055
7626
|
}
|
|
7627
|
+
/**
|
|
7628
|
+
* Set tools for the SDK instance
|
|
7629
|
+
*/
|
|
7630
|
+
setTools(tools) {
|
|
7631
|
+
this.tools = tools;
|
|
7632
|
+
logger.info(`Tools stored in SDK: ${tools.length} tools`);
|
|
7633
|
+
}
|
|
7634
|
+
/**
|
|
7635
|
+
* Get the stored tools
|
|
7636
|
+
*/
|
|
7637
|
+
getTools() {
|
|
7638
|
+
return this.tools;
|
|
7639
|
+
}
|
|
7056
7640
|
};
|
|
7057
7641
|
// Annotate the CommonJS export names for ESM import in node:
|
|
7058
7642
|
0 && (module.exports = {
|