@superatomai/sdk-node 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +528 -85
- package/dist/index.d.mts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +408 -166
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +408 -166
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1866,53 +1866,126 @@ import fs3 from "fs";
|
|
|
1866
1866
|
import path3 from "path";
|
|
1867
1867
|
var PromptLoader = class {
|
|
1868
1868
|
constructor(config) {
|
|
1869
|
+
this.promptCache = /* @__PURE__ */ new Map();
|
|
1870
|
+
this.isInitialized = false;
|
|
1871
|
+
logger.debug("Initializing PromptLoader...", process.cwd());
|
|
1869
1872
|
this.promptsDir = config?.promptsDir || path3.join(process.cwd(), ".prompts");
|
|
1873
|
+
this.defaultPromptsDir = path3.join(__dirname, "..", "..", ".prompts");
|
|
1870
1874
|
}
|
|
1871
1875
|
/**
|
|
1872
|
-
*
|
|
1876
|
+
* Initialize and cache all prompts into memory
|
|
1877
|
+
* This should be called once at SDK startup
|
|
1878
|
+
*/
|
|
1879
|
+
async initialize() {
|
|
1880
|
+
if (this.isInitialized) {
|
|
1881
|
+
logger.debug("PromptLoader already initialized, skipping...");
|
|
1882
|
+
return;
|
|
1883
|
+
}
|
|
1884
|
+
logger.info("Loading prompts into memory...");
|
|
1885
|
+
const promptTypes = [
|
|
1886
|
+
"classify",
|
|
1887
|
+
"match-component",
|
|
1888
|
+
"modify-props",
|
|
1889
|
+
"single-component",
|
|
1890
|
+
"mutli-component",
|
|
1891
|
+
"actions",
|
|
1892
|
+
"container-metadata"
|
|
1893
|
+
];
|
|
1894
|
+
for (const promptType of promptTypes) {
|
|
1895
|
+
try {
|
|
1896
|
+
const template = await this.loadPromptTemplate(promptType);
|
|
1897
|
+
this.promptCache.set(promptType, template);
|
|
1898
|
+
logger.debug(`Cached prompt: ${promptType}`);
|
|
1899
|
+
} catch (error) {
|
|
1900
|
+
logger.error(`Failed to load prompt '${promptType}':`, error);
|
|
1901
|
+
throw error;
|
|
1902
|
+
}
|
|
1903
|
+
}
|
|
1904
|
+
this.isInitialized = true;
|
|
1905
|
+
logger.info(`Successfully loaded ${this.promptCache.size} prompt templates into memory`);
|
|
1906
|
+
}
|
|
1907
|
+
/**
|
|
1908
|
+
* Load a prompt template from file system (tries custom dir first, then defaults to SDK dir)
|
|
1873
1909
|
* @param promptName - Name of the prompt folder
|
|
1874
|
-
* @
|
|
1875
|
-
* @param variables - Variables to replace in the template
|
|
1876
|
-
* @returns Processed prompt string
|
|
1910
|
+
* @returns Template with system and user prompts
|
|
1877
1911
|
*/
|
|
1878
|
-
async
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
promptName,
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1912
|
+
async loadPromptTemplate(promptName) {
|
|
1913
|
+
const tryLoadFromDir = (dir) => {
|
|
1914
|
+
try {
|
|
1915
|
+
const systemPath = path3.join(dir, promptName, "system.md");
|
|
1916
|
+
const userPath = path3.join(dir, promptName, "user.md");
|
|
1917
|
+
if (fs3.existsSync(systemPath) && fs3.existsSync(userPath)) {
|
|
1918
|
+
const system = fs3.readFileSync(systemPath, "utf-8");
|
|
1919
|
+
const user = fs3.readFileSync(userPath, "utf-8");
|
|
1920
|
+
logger.debug(`Loaded prompt '${promptName}' from ${dir}`);
|
|
1921
|
+
return { system, user };
|
|
1922
|
+
}
|
|
1923
|
+
return null;
|
|
1924
|
+
} catch (error) {
|
|
1925
|
+
return null;
|
|
1890
1926
|
}
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1927
|
+
};
|
|
1928
|
+
let template = tryLoadFromDir(this.promptsDir);
|
|
1929
|
+
if (!template) {
|
|
1930
|
+
logger.warn(`Prompt '${promptName}' not found in ${this.promptsDir}, trying default location...`);
|
|
1931
|
+
template = tryLoadFromDir(this.defaultPromptsDir);
|
|
1932
|
+
}
|
|
1933
|
+
if (!template) {
|
|
1934
|
+
throw new Error(`Prompt template '${promptName}' not found in either ${this.promptsDir} or ${this.defaultPromptsDir}`);
|
|
1895
1935
|
}
|
|
1936
|
+
return template;
|
|
1896
1937
|
}
|
|
1897
1938
|
/**
|
|
1898
|
-
*
|
|
1939
|
+
* Replace variables in a template string using {{VARIABLE_NAME}} pattern
|
|
1940
|
+
* @param template - Template string with placeholders
|
|
1941
|
+
* @param variables - Variables to replace in the template
|
|
1942
|
+
* @returns Processed string
|
|
1943
|
+
*/
|
|
1944
|
+
replaceVariables(template, variables) {
|
|
1945
|
+
let content = template;
|
|
1946
|
+
for (const [key, value] of Object.entries(variables)) {
|
|
1947
|
+
const pattern = new RegExp(`{{${key}}}`, "g");
|
|
1948
|
+
const replacementValue = typeof value === "string" ? value : JSON.stringify(value);
|
|
1949
|
+
content = content.replace(pattern, replacementValue);
|
|
1950
|
+
}
|
|
1951
|
+
return content;
|
|
1952
|
+
}
|
|
1953
|
+
/**
|
|
1954
|
+
* Load both system and user prompts from cache and replace variables
|
|
1899
1955
|
* @param promptName - Name of the prompt folder
|
|
1900
1956
|
* @param variables - Variables to replace in the templates
|
|
1901
1957
|
* @returns Object containing both system and user prompts
|
|
1902
1958
|
*/
|
|
1903
1959
|
async loadPrompts(promptName, variables) {
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
this.
|
|
1907
|
-
|
|
1908
|
-
|
|
1960
|
+
if (!this.isInitialized) {
|
|
1961
|
+
logger.warn("PromptLoader not initialized, loading prompts on-demand (not recommended)");
|
|
1962
|
+
await this.initialize();
|
|
1963
|
+
}
|
|
1964
|
+
const template = this.promptCache.get(promptName);
|
|
1965
|
+
if (!template) {
|
|
1966
|
+
throw new Error(`Prompt template '${promptName}' not found in cache. Available prompts: ${Array.from(this.promptCache.keys()).join(", ")}`);
|
|
1967
|
+
}
|
|
1968
|
+
return {
|
|
1969
|
+
system: this.replaceVariables(template.system, variables),
|
|
1970
|
+
user: this.replaceVariables(template.user, variables)
|
|
1971
|
+
};
|
|
1909
1972
|
}
|
|
1910
1973
|
/**
|
|
1911
|
-
*
|
|
1974
|
+
* DEPRECATED: Use loadPrompts instead
|
|
1975
|
+
* Load a single prompt file and replace variables using {{VARIABLE_NAME}} pattern
|
|
1976
|
+
*/
|
|
1977
|
+
async loadPrompt(promptName, promptType, variables) {
|
|
1978
|
+
const prompts = await this.loadPrompts(promptName, variables);
|
|
1979
|
+
return promptType === "system" ? prompts.system : prompts.user;
|
|
1980
|
+
}
|
|
1981
|
+
/**
|
|
1982
|
+
* Set custom prompts directory (requires re-initialization)
|
|
1912
1983
|
* @param dir - Path to the prompts directory
|
|
1913
1984
|
*/
|
|
1914
1985
|
setPromptsDir(dir) {
|
|
1915
1986
|
this.promptsDir = dir;
|
|
1987
|
+
this.isInitialized = false;
|
|
1988
|
+
this.promptCache.clear();
|
|
1916
1989
|
}
|
|
1917
1990
|
/**
|
|
1918
1991
|
* Get current prompts directory
|
|
@@ -1921,8 +1994,23 @@ var PromptLoader = class {
|
|
|
1921
1994
|
getPromptsDir() {
|
|
1922
1995
|
return this.promptsDir;
|
|
1923
1996
|
}
|
|
1997
|
+
/**
|
|
1998
|
+
* Check if prompts are loaded in memory
|
|
1999
|
+
*/
|
|
2000
|
+
isReady() {
|
|
2001
|
+
return this.isInitialized;
|
|
2002
|
+
}
|
|
2003
|
+
/**
|
|
2004
|
+
* Get the number of cached prompts
|
|
2005
|
+
*/
|
|
2006
|
+
getCacheSize() {
|
|
2007
|
+
return this.promptCache.size;
|
|
2008
|
+
}
|
|
1924
2009
|
};
|
|
1925
|
-
var
|
|
2010
|
+
var defaultPromptsPath = process.env.PROMPTS_DIR || path3.join(process.cwd(), ".prompts");
|
|
2011
|
+
var promptLoader = new PromptLoader({
|
|
2012
|
+
promptsDir: defaultPromptsPath
|
|
2013
|
+
});
|
|
1926
2014
|
|
|
1927
2015
|
// src/llm.ts
|
|
1928
2016
|
import Anthropic from "@anthropic-ai/sdk";
|
|
@@ -1960,7 +2048,7 @@ var LLM = class {
|
|
|
1960
2048
|
*
|
|
1961
2049
|
* @example
|
|
1962
2050
|
* "anthropic/claude-sonnet-4-5" → ["anthropic", "claude-sonnet-4-5"]
|
|
1963
|
-
* "groq/gpt-oss-120b" → ["groq", "gpt-oss-120b"]
|
|
2051
|
+
* "groq/openai/gpt-oss-120b" → ["groq", "openai/gpt-oss-120b"]
|
|
1964
2052
|
* "claude-sonnet-4-5" → ["anthropic", "claude-sonnet-4-5"] (default)
|
|
1965
2053
|
*/
|
|
1966
2054
|
static _parseModel(modelString) {
|
|
@@ -1968,8 +2056,10 @@ var LLM = class {
|
|
|
1968
2056
|
return ["anthropic", "claude-sonnet-4-5"];
|
|
1969
2057
|
}
|
|
1970
2058
|
if (modelString.includes("/")) {
|
|
1971
|
-
const
|
|
1972
|
-
|
|
2059
|
+
const firstSlashIndex = modelString.indexOf("/");
|
|
2060
|
+
const provider = modelString.substring(0, firstSlashIndex).toLowerCase().trim();
|
|
2061
|
+
const model = modelString.substring(firstSlashIndex + 1).trim();
|
|
2062
|
+
return [provider, model];
|
|
1973
2063
|
}
|
|
1974
2064
|
return ["anthropic", modelString];
|
|
1975
2065
|
}
|
|
@@ -1977,8 +2067,9 @@ var LLM = class {
|
|
|
1977
2067
|
// ANTHROPIC IMPLEMENTATION
|
|
1978
2068
|
// ============================================================
|
|
1979
2069
|
static async _anthropicText(messages, modelName, options) {
|
|
2070
|
+
const apiKey = options.apiKey || process.env.ANTHROPIC_API_KEY || "";
|
|
1980
2071
|
const client = new Anthropic({
|
|
1981
|
-
apiKey
|
|
2072
|
+
apiKey
|
|
1982
2073
|
});
|
|
1983
2074
|
const response = await client.messages.create({
|
|
1984
2075
|
model: modelName,
|
|
@@ -1994,8 +2085,9 @@ var LLM = class {
|
|
|
1994
2085
|
return textBlock?.type === "text" ? textBlock.text : "";
|
|
1995
2086
|
}
|
|
1996
2087
|
static async _anthropicStream(messages, modelName, options, json) {
|
|
2088
|
+
const apiKey = options.apiKey || process.env.ANTHROPIC_API_KEY || "";
|
|
1997
2089
|
const client = new Anthropic({
|
|
1998
|
-
apiKey
|
|
2090
|
+
apiKey
|
|
1999
2091
|
});
|
|
2000
2092
|
const stream = await client.messages.create({
|
|
2001
2093
|
model: modelName,
|
|
@@ -2042,8 +2134,9 @@ var LLM = class {
|
|
|
2042
2134
|
return response.choices[0]?.message?.content || "";
|
|
2043
2135
|
}
|
|
2044
2136
|
static async _groqStream(messages, modelName, options, json) {
|
|
2137
|
+
const apiKey = options.apiKey || process.env.GROQ_API_KEY || "";
|
|
2045
2138
|
const client = new Groq({
|
|
2046
|
-
apiKey
|
|
2139
|
+
apiKey
|
|
2047
2140
|
});
|
|
2048
2141
|
const stream = await client.chat.completions.create({
|
|
2049
2142
|
model: modelName,
|
|
@@ -2113,10 +2206,8 @@ var BaseLLM = class {
|
|
|
2113
2206
|
* Classify user question to determine the type and required visualizations
|
|
2114
2207
|
*/
|
|
2115
2208
|
async classifyUserQuestion(userPrompt, apiKey, logCollector, conversationHistory) {
|
|
2116
|
-
const schemaDoc = schema.generateSchemaDocumentation();
|
|
2117
2209
|
try {
|
|
2118
2210
|
const prompts = await promptLoader.loadPrompts("classify", {
|
|
2119
|
-
SCHEMA_DOC: schemaDoc || "No schema available",
|
|
2120
2211
|
USER_PROMPT: userPrompt,
|
|
2121
2212
|
CONVERSATION_HISTORY: conversationHistory || "No previous conversation"
|
|
2122
2213
|
});
|
|
@@ -2171,6 +2262,7 @@ var BaseLLM = class {
|
|
|
2171
2262
|
CURRENT_PROPS: JSON.stringify(originalProps, null, 2),
|
|
2172
2263
|
CONVERSATION_HISTORY: conversationHistory || "No previous conversation"
|
|
2173
2264
|
});
|
|
2265
|
+
logger.debug("props-modification: System prompt\n", prompts.system.substring(0, 100), "\n\n\n", "User prompt:", prompts.user.substring(0, 50));
|
|
2174
2266
|
const result = await LLM.stream(
|
|
2175
2267
|
{
|
|
2176
2268
|
sys: prompts.system,
|
|
@@ -2218,21 +2310,47 @@ var BaseLLM = class {
|
|
|
2218
2310
|
}
|
|
2219
2311
|
}
|
|
2220
2312
|
/**
|
|
2221
|
-
*
|
|
2222
|
-
* This
|
|
2313
|
+
* Match and select a component from available components filtered by type
|
|
2314
|
+
* This picks the best matching component based on user prompt and modifies its props
|
|
2223
2315
|
*/
|
|
2224
|
-
async generateAnalyticalComponent(userPrompt, preferredVisualizationType, apiKey, logCollector, conversationHistory) {
|
|
2225
|
-
const schemaDoc = schema.generateSchemaDocumentation();
|
|
2316
|
+
async generateAnalyticalComponent(userPrompt, components, preferredVisualizationType, apiKey, logCollector, conversationHistory) {
|
|
2226
2317
|
try {
|
|
2318
|
+
const filteredComponents = preferredVisualizationType ? components.filter((c) => c.type === preferredVisualizationType) : components;
|
|
2319
|
+
if (filteredComponents.length === 0) {
|
|
2320
|
+
logCollector?.warn(
|
|
2321
|
+
`No components found of type ${preferredVisualizationType}`,
|
|
2322
|
+
"explanation",
|
|
2323
|
+
{ reason: "No matching components available for this visualization type" }
|
|
2324
|
+
);
|
|
2325
|
+
return {
|
|
2326
|
+
component: null,
|
|
2327
|
+
reasoning: `No components available of type ${preferredVisualizationType}`,
|
|
2328
|
+
isGenerated: false
|
|
2329
|
+
};
|
|
2330
|
+
}
|
|
2331
|
+
const componentsText = filteredComponents.map((comp, idx) => {
|
|
2332
|
+
const keywords = comp.keywords ? comp.keywords.join(", ") : "";
|
|
2333
|
+
const category = comp.category || "general";
|
|
2334
|
+
const propsPreview = comp.props ? JSON.stringify(comp.props, null, 2) : "No props";
|
|
2335
|
+
return `${idx + 1}. ID: ${comp.id}
|
|
2336
|
+
Name: ${comp.name}
|
|
2337
|
+
Type: ${comp.type}
|
|
2338
|
+
Category: ${category}
|
|
2339
|
+
Description: ${comp.description || "No description"}
|
|
2340
|
+
Keywords: ${keywords}
|
|
2341
|
+
Props Preview: ${propsPreview}`;
|
|
2342
|
+
}).join("\n\n");
|
|
2227
2343
|
const visualizationConstraint = preferredVisualizationType ? `
|
|
2228
|
-
**IMPORTANT:
|
|
2344
|
+
**IMPORTANT: Components are filtered to type ${preferredVisualizationType}. Select the best match.**
|
|
2229
2345
|
` : "";
|
|
2230
2346
|
const prompts = await promptLoader.loadPrompts("single-component", {
|
|
2231
|
-
|
|
2347
|
+
COMPONENT_TYPE: preferredVisualizationType || "any",
|
|
2348
|
+
COMPONENTS_LIST: componentsText,
|
|
2232
2349
|
VISUALIZATION_CONSTRAINT: visualizationConstraint,
|
|
2233
2350
|
USER_PROMPT: userPrompt,
|
|
2234
2351
|
CONVERSATION_HISTORY: conversationHistory || "No previous conversation"
|
|
2235
2352
|
});
|
|
2353
|
+
logger.debug("single-component: System prompt\n", prompts.system.substring(0, 100), "\n\n\n", "User prompt:", prompts.user.substring(0, 50));
|
|
2236
2354
|
const result = await LLM.stream(
|
|
2237
2355
|
{
|
|
2238
2356
|
sys: prompts.system,
|
|
@@ -2247,53 +2365,63 @@ var BaseLLM = class {
|
|
|
2247
2365
|
true
|
|
2248
2366
|
// Parse as JSON
|
|
2249
2367
|
);
|
|
2250
|
-
if (!result.canGenerate) {
|
|
2368
|
+
if (!result.canGenerate || result.confidence < 50) {
|
|
2251
2369
|
logCollector?.warn(
|
|
2252
|
-
"Cannot
|
|
2370
|
+
"Cannot match component",
|
|
2253
2371
|
"explanation",
|
|
2254
|
-
{ reason: result.reasoning || "Unable to
|
|
2372
|
+
{ reason: result.reasoning || "Unable to find matching component for this question" }
|
|
2255
2373
|
);
|
|
2256
2374
|
return {
|
|
2257
2375
|
component: null,
|
|
2258
|
-
reasoning: result.reasoning || "Unable to
|
|
2376
|
+
reasoning: result.reasoning || "Unable to find matching component for this question",
|
|
2259
2377
|
isGenerated: false
|
|
2260
2378
|
};
|
|
2261
2379
|
}
|
|
2262
|
-
const
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2380
|
+
const componentIndex = result.componentIndex;
|
|
2381
|
+
const componentId = result.componentId;
|
|
2382
|
+
let matchedComponent = null;
|
|
2383
|
+
if (componentId) {
|
|
2384
|
+
matchedComponent = filteredComponents.find((c) => c.id === componentId);
|
|
2385
|
+
}
|
|
2386
|
+
if (!matchedComponent && componentIndex) {
|
|
2387
|
+
matchedComponent = filteredComponents[componentIndex - 1];
|
|
2388
|
+
}
|
|
2389
|
+
if (!matchedComponent) {
|
|
2390
|
+
logCollector?.warn("Component not found in filtered list");
|
|
2391
|
+
return {
|
|
2392
|
+
component: null,
|
|
2393
|
+
reasoning: "Component not found in filtered list",
|
|
2394
|
+
isGenerated: false
|
|
2395
|
+
};
|
|
2396
|
+
}
|
|
2397
|
+
logCollector?.info(`Matched component: ${matchedComponent.name} (confidence: ${result.confidence}%)`);
|
|
2398
|
+
const propsValidation = await this.validateAndModifyProps(
|
|
2399
|
+
userPrompt,
|
|
2400
|
+
matchedComponent.props,
|
|
2401
|
+
matchedComponent.name,
|
|
2402
|
+
matchedComponent.type,
|
|
2403
|
+
matchedComponent.description,
|
|
2404
|
+
apiKey,
|
|
2405
|
+
logCollector,
|
|
2406
|
+
conversationHistory
|
|
2271
2407
|
);
|
|
2408
|
+
const modifiedComponent = {
|
|
2409
|
+
...matchedComponent,
|
|
2410
|
+
props: propsValidation.props
|
|
2411
|
+
};
|
|
2272
2412
|
logCollector?.logExplanation(
|
|
2273
|
-
"Analytical component
|
|
2274
|
-
result.reasoning || "
|
|
2413
|
+
"Analytical component selected and modified",
|
|
2414
|
+
result.reasoning || "Selected component based on analytical question",
|
|
2275
2415
|
{
|
|
2276
|
-
|
|
2277
|
-
|
|
2416
|
+
componentName: matchedComponent.name,
|
|
2417
|
+
componentType: matchedComponent.type,
|
|
2418
|
+
confidence: result.confidence,
|
|
2419
|
+
propsModified: propsValidation.isModified
|
|
2278
2420
|
}
|
|
2279
2421
|
);
|
|
2280
|
-
const dynamicComponent = {
|
|
2281
|
-
id: `dynamic_${Date.now()}`,
|
|
2282
|
-
name: `Dynamic${result.componentType}`,
|
|
2283
|
-
type: result.componentType,
|
|
2284
|
-
description: result.description,
|
|
2285
|
-
category: "dynamic",
|
|
2286
|
-
keywords: [],
|
|
2287
|
-
props: {
|
|
2288
|
-
query,
|
|
2289
|
-
title: result.title,
|
|
2290
|
-
description: result.description,
|
|
2291
|
-
config: result.config || {}
|
|
2292
|
-
}
|
|
2293
|
-
};
|
|
2294
2422
|
return {
|
|
2295
|
-
component:
|
|
2296
|
-
reasoning: result.reasoning || "
|
|
2423
|
+
component: modifiedComponent,
|
|
2424
|
+
reasoning: result.reasoning || "Selected and modified component based on analytical question",
|
|
2297
2425
|
isGenerated: true
|
|
2298
2426
|
};
|
|
2299
2427
|
} catch (error) {
|
|
@@ -2301,6 +2429,51 @@ var BaseLLM = class {
|
|
|
2301
2429
|
throw error;
|
|
2302
2430
|
}
|
|
2303
2431
|
}
|
|
2432
|
+
/**
|
|
2433
|
+
* Generate container metadata (title and description) for multi-component dashboard
|
|
2434
|
+
*/
|
|
2435
|
+
async generateContainerMetadata(userPrompt, visualizationTypes, apiKey, logCollector, conversationHistory) {
|
|
2436
|
+
try {
|
|
2437
|
+
const prompts = await promptLoader.loadPrompts("container-metadata", {
|
|
2438
|
+
USER_PROMPT: userPrompt,
|
|
2439
|
+
VISUALIZATION_TYPES: visualizationTypes.join(", "),
|
|
2440
|
+
CONVERSATION_HISTORY: conversationHistory || "No previous conversation"
|
|
2441
|
+
});
|
|
2442
|
+
const result = await LLM.stream(
|
|
2443
|
+
{
|
|
2444
|
+
sys: prompts.system,
|
|
2445
|
+
user: prompts.user
|
|
2446
|
+
},
|
|
2447
|
+
{
|
|
2448
|
+
model: this.model,
|
|
2449
|
+
maxTokens: 500,
|
|
2450
|
+
temperature: 0.3,
|
|
2451
|
+
apiKey: this.getApiKey(apiKey)
|
|
2452
|
+
},
|
|
2453
|
+
true
|
|
2454
|
+
// Parse as JSON
|
|
2455
|
+
);
|
|
2456
|
+
logCollector?.logExplanation(
|
|
2457
|
+
"Container metadata generated",
|
|
2458
|
+
`Generated title and description for multi-component dashboard`,
|
|
2459
|
+
{
|
|
2460
|
+
title: result.title,
|
|
2461
|
+
description: result.description,
|
|
2462
|
+
visualizationTypes
|
|
2463
|
+
}
|
|
2464
|
+
);
|
|
2465
|
+
return {
|
|
2466
|
+
title: result.title || `${userPrompt} - Dashboard`,
|
|
2467
|
+
description: result.description || `Multi-component dashboard showing ${visualizationTypes.join(", ")}`
|
|
2468
|
+
};
|
|
2469
|
+
} catch (error) {
|
|
2470
|
+
console.error("Error generating container metadata:", error);
|
|
2471
|
+
return {
|
|
2472
|
+
title: `${userPrompt} - Dashboard`,
|
|
2473
|
+
description: `Multi-component dashboard showing ${visualizationTypes.join(", ")}`
|
|
2474
|
+
};
|
|
2475
|
+
}
|
|
2476
|
+
}
|
|
2304
2477
|
/**
|
|
2305
2478
|
* Match component from a list with enhanced props modification
|
|
2306
2479
|
*/
|
|
@@ -2362,12 +2535,12 @@ var BaseLLM = class {
|
|
|
2362
2535
|
const noMatchMsg = `No matching component found (confidence: ${confidence}%)`;
|
|
2363
2536
|
console.log("\u2717", noMatchMsg);
|
|
2364
2537
|
logCollector?.warn(noMatchMsg);
|
|
2365
|
-
const genMsg = "Attempting to
|
|
2538
|
+
const genMsg = "Attempting to match component from analytical question...";
|
|
2366
2539
|
console.log("\u2713", genMsg);
|
|
2367
2540
|
logCollector?.info(genMsg);
|
|
2368
|
-
const generatedResult = await this.generateAnalyticalComponent(userPrompt, void 0, apiKey, logCollector, conversationHistory);
|
|
2541
|
+
const generatedResult = await this.generateAnalyticalComponent(userPrompt, components, void 0, apiKey, logCollector, conversationHistory);
|
|
2369
2542
|
if (generatedResult.component) {
|
|
2370
|
-
const genSuccessMsg = `Successfully
|
|
2543
|
+
const genSuccessMsg = `Successfully matched component: ${generatedResult.component.name}`;
|
|
2371
2544
|
logCollector?.info(genSuccessMsg);
|
|
2372
2545
|
return {
|
|
2373
2546
|
component: generatedResult.component,
|
|
@@ -2379,10 +2552,10 @@ var BaseLLM = class {
|
|
|
2379
2552
|
queryModified: false
|
|
2380
2553
|
};
|
|
2381
2554
|
}
|
|
2382
|
-
logCollector?.error("Failed to
|
|
2555
|
+
logCollector?.error("Failed to match component");
|
|
2383
2556
|
return {
|
|
2384
2557
|
component: null,
|
|
2385
|
-
reasoning: result.reasoning || "No matching component found and unable to
|
|
2558
|
+
reasoning: result.reasoning || "No matching component found and unable to match component",
|
|
2386
2559
|
method: `${this.getProviderName()}-llm`,
|
|
2387
2560
|
confidence
|
|
2388
2561
|
};
|
|
@@ -2430,15 +2603,15 @@ var BaseLLM = class {
|
|
|
2430
2603
|
}
|
|
2431
2604
|
}
|
|
2432
2605
|
/**
|
|
2433
|
-
*
|
|
2606
|
+
* Match multiple components for analytical questions by visualization types
|
|
2434
2607
|
* This is used when the user needs multiple visualizations
|
|
2435
2608
|
*/
|
|
2436
|
-
async generateMultipleAnalyticalComponents(userPrompt, visualizationTypes, apiKey, logCollector, conversationHistory) {
|
|
2609
|
+
async generateMultipleAnalyticalComponents(userPrompt, availableComponents, visualizationTypes, apiKey, logCollector, conversationHistory) {
|
|
2437
2610
|
try {
|
|
2438
|
-
console.log("\u2713
|
|
2611
|
+
console.log("\u2713 Matching multiple components:", visualizationTypes);
|
|
2439
2612
|
const components = [];
|
|
2440
2613
|
for (const vizType of visualizationTypes) {
|
|
2441
|
-
const result = await this.generateAnalyticalComponent(userPrompt, vizType, apiKey, logCollector, conversationHistory);
|
|
2614
|
+
const result = await this.generateAnalyticalComponent(userPrompt, availableComponents, vizType, apiKey, logCollector, conversationHistory);
|
|
2442
2615
|
if (result.component) {
|
|
2443
2616
|
components.push(result.component);
|
|
2444
2617
|
}
|
|
@@ -2446,75 +2619,45 @@ var BaseLLM = class {
|
|
|
2446
2619
|
if (components.length === 0) {
|
|
2447
2620
|
return {
|
|
2448
2621
|
components: [],
|
|
2449
|
-
reasoning: "Failed to
|
|
2622
|
+
reasoning: "Failed to match any components",
|
|
2450
2623
|
isGenerated: false
|
|
2451
2624
|
};
|
|
2452
2625
|
}
|
|
2453
2626
|
return {
|
|
2454
2627
|
components,
|
|
2455
|
-
reasoning: `
|
|
2628
|
+
reasoning: `Matched ${components.length} components: ${visualizationTypes.join(", ")}`,
|
|
2456
2629
|
isGenerated: true
|
|
2457
2630
|
};
|
|
2458
2631
|
} catch (error) {
|
|
2459
|
-
console.error("Error
|
|
2632
|
+
console.error("Error matching multiple analytical components:", error);
|
|
2460
2633
|
return {
|
|
2461
2634
|
components: [],
|
|
2462
|
-
reasoning: "Error occurred while
|
|
2635
|
+
reasoning: "Error occurred while matching components",
|
|
2463
2636
|
isGenerated: false
|
|
2464
2637
|
};
|
|
2465
2638
|
}
|
|
2466
2639
|
}
|
|
2467
2640
|
/**
|
|
2468
|
-
*
|
|
2641
|
+
* Match multiple components and wrap them in a container
|
|
2469
2642
|
*/
|
|
2470
|
-
async generateMultiComponentResponse(userPrompt, visualizationTypes, apiKey, logCollector, conversationHistory) {
|
|
2471
|
-
const schemaDoc = schema.generateSchemaDocumentation();
|
|
2643
|
+
async generateMultiComponentResponse(userPrompt, availableComponents, visualizationTypes, apiKey, logCollector, conversationHistory) {
|
|
2472
2644
|
try {
|
|
2473
|
-
const
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
const result = await LLM.stream(
|
|
2481
|
-
{
|
|
2482
|
-
sys: prompts.system,
|
|
2483
|
-
user: prompts.user
|
|
2484
|
-
},
|
|
2485
|
-
{
|
|
2486
|
-
model: this.model,
|
|
2487
|
-
maxTokens: 3e3,
|
|
2488
|
-
temperature: 0.2,
|
|
2489
|
-
apiKey: this.getApiKey(apiKey)
|
|
2490
|
-
},
|
|
2491
|
-
true
|
|
2492
|
-
// Parse as JSON
|
|
2645
|
+
const matchResult = await this.generateMultipleAnalyticalComponents(
|
|
2646
|
+
userPrompt,
|
|
2647
|
+
availableComponents,
|
|
2648
|
+
visualizationTypes,
|
|
2649
|
+
apiKey,
|
|
2650
|
+
logCollector,
|
|
2651
|
+
conversationHistory
|
|
2493
2652
|
);
|
|
2494
|
-
if (!
|
|
2653
|
+
if (!matchResult.isGenerated || matchResult.components.length === 0) {
|
|
2495
2654
|
return {
|
|
2496
2655
|
containerComponent: null,
|
|
2497
|
-
reasoning:
|
|
2656
|
+
reasoning: matchResult.reasoning || "Unable to match multi-component dashboard",
|
|
2498
2657
|
isGenerated: false
|
|
2499
2658
|
};
|
|
2500
2659
|
}
|
|
2501
|
-
const generatedComponents =
|
|
2502
|
-
const query = ensureQueryLimit(compData.query, this.defaultLimit);
|
|
2503
|
-
return {
|
|
2504
|
-
id: `dynamic_${compData.componentType.toLowerCase()}_${Date.now()}_${index}`,
|
|
2505
|
-
name: `Dynamic${compData.componentType}`,
|
|
2506
|
-
type: compData.componentType,
|
|
2507
|
-
description: compData.description,
|
|
2508
|
-
category: "dynamic",
|
|
2509
|
-
keywords: [],
|
|
2510
|
-
props: {
|
|
2511
|
-
query,
|
|
2512
|
-
title: compData.title,
|
|
2513
|
-
description: compData.description,
|
|
2514
|
-
config: compData.config || {}
|
|
2515
|
-
}
|
|
2516
|
-
};
|
|
2517
|
-
});
|
|
2660
|
+
const generatedComponents = matchResult.components;
|
|
2518
2661
|
generatedComponents.forEach((component, index) => {
|
|
2519
2662
|
if (component.props.query) {
|
|
2520
2663
|
logCollector?.logQuery(
|
|
@@ -2529,21 +2672,24 @@ var BaseLLM = class {
|
|
|
2529
2672
|
);
|
|
2530
2673
|
}
|
|
2531
2674
|
});
|
|
2675
|
+
const containerTitle = `${userPrompt} - Dashboard`;
|
|
2676
|
+
const containerDescription = `Multi-component dashboard showing ${visualizationTypes.join(", ")}`;
|
|
2532
2677
|
logCollector?.logExplanation(
|
|
2533
|
-
"Multi-component dashboard
|
|
2534
|
-
|
|
2678
|
+
"Multi-component dashboard matched",
|
|
2679
|
+
matchResult.reasoning || `Matched ${generatedComponents.length} components for comprehensive analysis`,
|
|
2535
2680
|
{
|
|
2536
2681
|
totalComponents: generatedComponents.length,
|
|
2537
2682
|
componentTypes: generatedComponents.map((c) => c.type),
|
|
2538
|
-
|
|
2539
|
-
|
|
2683
|
+
componentNames: generatedComponents.map((c) => c.name),
|
|
2684
|
+
containerTitle,
|
|
2685
|
+
containerDescription
|
|
2540
2686
|
}
|
|
2541
2687
|
);
|
|
2542
2688
|
const containerComponent = {
|
|
2543
2689
|
id: `multi_container_${Date.now()}`,
|
|
2544
2690
|
name: "MultiComponentContainer",
|
|
2545
2691
|
type: "Container",
|
|
2546
|
-
description:
|
|
2692
|
+
description: containerDescription,
|
|
2547
2693
|
category: "dynamic",
|
|
2548
2694
|
keywords: ["multi", "container", "dashboard"],
|
|
2549
2695
|
props: {
|
|
@@ -2551,14 +2697,14 @@ var BaseLLM = class {
|
|
|
2551
2697
|
components: generatedComponents,
|
|
2552
2698
|
layout: "grid",
|
|
2553
2699
|
spacing: 24,
|
|
2554
|
-
title:
|
|
2555
|
-
description:
|
|
2700
|
+
title: containerTitle,
|
|
2701
|
+
description: containerDescription
|
|
2556
2702
|
}
|
|
2557
2703
|
}
|
|
2558
2704
|
};
|
|
2559
2705
|
return {
|
|
2560
2706
|
containerComponent,
|
|
2561
|
-
reasoning:
|
|
2707
|
+
reasoning: matchResult.reasoning || `Matched multi-component dashboard with ${generatedComponents.length} components`,
|
|
2562
2708
|
isGenerated: true
|
|
2563
2709
|
};
|
|
2564
2710
|
} catch (error) {
|
|
@@ -2579,41 +2725,89 @@ var BaseLLM = class {
|
|
|
2579
2725
|
const classInfo = `Question type: ${classification.questionType}, Visualizations: ${classification.visualizations.join(", ") || "None"}, Multiple components: ${classification.needsMultipleComponents}`;
|
|
2580
2726
|
logCollector?.info(classInfo);
|
|
2581
2727
|
if (classification.questionType === "analytical") {
|
|
2582
|
-
if (classification.visualizations.length >
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2728
|
+
if (classification.visualizations.length > 1) {
|
|
2729
|
+
const multiMsg = `Matching ${classification.visualizations.length} components for types: ${classification.visualizations.join(", ")}`;
|
|
2730
|
+
logCollector?.info(multiMsg);
|
|
2731
|
+
const matchedComponents = [];
|
|
2732
|
+
for (const vizType of classification.visualizations) {
|
|
2733
|
+
logCollector?.info(`Matching component for type: ${vizType}`);
|
|
2734
|
+
const result = await this.generateAnalyticalComponent(
|
|
2587
2735
|
userPrompt,
|
|
2588
|
-
|
|
2736
|
+
components,
|
|
2737
|
+
vizType,
|
|
2589
2738
|
apiKey,
|
|
2590
2739
|
logCollector,
|
|
2591
2740
|
conversationHistory
|
|
2592
2741
|
);
|
|
2742
|
+
if (result.component) {
|
|
2743
|
+
matchedComponents.push(result.component);
|
|
2744
|
+
logCollector?.info(`Matched: ${result.component.name}`);
|
|
2745
|
+
} else {
|
|
2746
|
+
logCollector?.warn(`Failed to match component for type: ${vizType}`);
|
|
2747
|
+
}
|
|
2748
|
+
}
|
|
2749
|
+
if (matchedComponents.length === 0) {
|
|
2593
2750
|
return {
|
|
2594
|
-
component:
|
|
2595
|
-
reasoning:
|
|
2596
|
-
method: "classification-multi-
|
|
2751
|
+
component: null,
|
|
2752
|
+
reasoning: "Failed to match any components for the requested visualization types",
|
|
2753
|
+
method: "classification-multi-failed",
|
|
2597
2754
|
questionType: classification.questionType,
|
|
2598
2755
|
needsMultipleComponents: true,
|
|
2599
2756
|
propsModified: false,
|
|
2600
2757
|
queryModified: false
|
|
2601
2758
|
};
|
|
2602
|
-
} else {
|
|
2603
|
-
const vizType = classification.visualizations[0];
|
|
2604
|
-
const result = await this.generateAnalyticalComponent(userPrompt, vizType, apiKey, logCollector, conversationHistory);
|
|
2605
|
-
return {
|
|
2606
|
-
component: result.component,
|
|
2607
|
-
reasoning: result.reasoning,
|
|
2608
|
-
method: "classification-generated",
|
|
2609
|
-
questionType: classification.questionType,
|
|
2610
|
-
needsMultipleComponents: false,
|
|
2611
|
-
propsModified: false,
|
|
2612
|
-
queryModified: false
|
|
2613
|
-
};
|
|
2614
2759
|
}
|
|
2760
|
+
logCollector?.info("Generating container metadata...");
|
|
2761
|
+
const containerMetadata = await this.generateContainerMetadata(
|
|
2762
|
+
userPrompt,
|
|
2763
|
+
classification.visualizations,
|
|
2764
|
+
apiKey,
|
|
2765
|
+
logCollector,
|
|
2766
|
+
conversationHistory
|
|
2767
|
+
);
|
|
2768
|
+
const containerComponent = {
|
|
2769
|
+
id: `multi_container_${Date.now()}`,
|
|
2770
|
+
name: "MultiComponentContainer",
|
|
2771
|
+
type: "Container",
|
|
2772
|
+
description: containerMetadata.description,
|
|
2773
|
+
category: "dynamic",
|
|
2774
|
+
keywords: ["multi", "container", "dashboard"],
|
|
2775
|
+
props: {
|
|
2776
|
+
config: {
|
|
2777
|
+
components: matchedComponents,
|
|
2778
|
+
layout: "grid",
|
|
2779
|
+
spacing: 24,
|
|
2780
|
+
title: containerMetadata.title,
|
|
2781
|
+
description: containerMetadata.description
|
|
2782
|
+
}
|
|
2783
|
+
}
|
|
2784
|
+
};
|
|
2785
|
+
logCollector?.info(`Created multi-component container with ${matchedComponents.length} components: "${containerMetadata.title}"`);
|
|
2786
|
+
return {
|
|
2787
|
+
component: containerComponent,
|
|
2788
|
+
reasoning: `Matched ${matchedComponents.length} components for visualization types: ${classification.visualizations.join(", ")}`,
|
|
2789
|
+
method: "classification-multi-generated",
|
|
2790
|
+
questionType: classification.questionType,
|
|
2791
|
+
needsMultipleComponents: true,
|
|
2792
|
+
propsModified: false,
|
|
2793
|
+
queryModified: false
|
|
2794
|
+
};
|
|
2795
|
+
} else if (classification.visualizations.length === 1) {
|
|
2796
|
+
const vizType = classification.visualizations[0];
|
|
2797
|
+
logCollector?.info(`Matching single component for type: ${vizType}`);
|
|
2798
|
+
const result = await this.generateAnalyticalComponent(userPrompt, components, vizType, apiKey, logCollector, conversationHistory);
|
|
2799
|
+
return {
|
|
2800
|
+
component: result.component,
|
|
2801
|
+
reasoning: result.reasoning,
|
|
2802
|
+
method: "classification-generated",
|
|
2803
|
+
questionType: classification.questionType,
|
|
2804
|
+
needsMultipleComponents: false,
|
|
2805
|
+
propsModified: false,
|
|
2806
|
+
queryModified: false
|
|
2807
|
+
};
|
|
2615
2808
|
} else {
|
|
2616
|
-
|
|
2809
|
+
logCollector?.info("No specific visualization type - matching from all components");
|
|
2810
|
+
const result = await this.generateAnalyticalComponent(userPrompt, components, void 0, apiKey, logCollector, conversationHistory);
|
|
2617
2811
|
return {
|
|
2618
2812
|
component: result.component,
|
|
2619
2813
|
reasoning: result.reasoning,
|
|
@@ -2624,7 +2818,7 @@ var BaseLLM = class {
|
|
|
2624
2818
|
queryModified: false
|
|
2625
2819
|
};
|
|
2626
2820
|
}
|
|
2627
|
-
} else if (classification.questionType === "data_modification") {
|
|
2821
|
+
} else if (classification.questionType === "data_modification" || classification.questionType === "general") {
|
|
2628
2822
|
const matchMsg = "Using component matching for data modification...";
|
|
2629
2823
|
logCollector?.info(matchMsg);
|
|
2630
2824
|
const matchResult = await this.matchComponent(userPrompt, components, apiKey, logCollector, conversationHistory);
|
|
@@ -2770,8 +2964,14 @@ var useAnthropicMethod = async (prompt, components, apiKey, logCollector, conver
|
|
|
2770
2964
|
logCollector?.error(emptyMsg);
|
|
2771
2965
|
return { success: false, reason: emptyMsg };
|
|
2772
2966
|
}
|
|
2773
|
-
|
|
2774
|
-
|
|
2967
|
+
try {
|
|
2968
|
+
const matchResult = await anthropicLLM.handleUserRequest(prompt, components, apiKey, logCollector, conversationHistory);
|
|
2969
|
+
return { success: true, data: matchResult };
|
|
2970
|
+
} catch (error) {
|
|
2971
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
2972
|
+
logCollector?.error(`Anthropic method failed: ${errorMsg}`);
|
|
2973
|
+
throw error;
|
|
2974
|
+
}
|
|
2775
2975
|
};
|
|
2776
2976
|
var useGroqMethod = async (prompt, components, apiKey, logCollector, conversationHistory) => {
|
|
2777
2977
|
const msg = "Using Groq LLM matching method...";
|
|
@@ -2782,8 +2982,14 @@ var useGroqMethod = async (prompt, components, apiKey, logCollector, conversatio
|
|
|
2782
2982
|
logCollector?.error(emptyMsg);
|
|
2783
2983
|
return { success: false, reason: emptyMsg };
|
|
2784
2984
|
}
|
|
2785
|
-
|
|
2786
|
-
|
|
2985
|
+
try {
|
|
2986
|
+
const matchResult = await groqLLM.handleUserRequest(prompt, components, apiKey, logCollector, conversationHistory);
|
|
2987
|
+
return { success: true, data: matchResult };
|
|
2988
|
+
} catch (error) {
|
|
2989
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
2990
|
+
logCollector?.error(`Groq method failed: ${errorMsg}`);
|
|
2991
|
+
throw error;
|
|
2992
|
+
}
|
|
2787
2993
|
};
|
|
2788
2994
|
var getUserResponseFromCache = async (prompt) => {
|
|
2789
2995
|
return false;
|
|
@@ -3004,6 +3210,7 @@ var CONTEXT_CONFIG = {
|
|
|
3004
3210
|
};
|
|
3005
3211
|
|
|
3006
3212
|
// src/handlers/user-prompt-request.ts
|
|
3213
|
+
var processedMessageIds = /* @__PURE__ */ new Set();
|
|
3007
3214
|
async function handleUserPromptRequest(data, components, sendMessage, anthropicApiKey, groqApiKey, llmProviders) {
|
|
3008
3215
|
try {
|
|
3009
3216
|
const userPromptRequest = UserPromptRequestMessageSchema.parse(data);
|
|
@@ -3011,6 +3218,18 @@ async function handleUserPromptRequest(data, components, sendMessage, anthropicA
|
|
|
3011
3218
|
const prompt = payload.prompt;
|
|
3012
3219
|
const SA_RUNTIME = payload.SA_RUNTIME;
|
|
3013
3220
|
const wsId = userPromptRequest.from.id || "unknown";
|
|
3221
|
+
logger.info(`[REQUEST ${id}] Processing user prompt: "${prompt.substring(0, 50)}..."`);
|
|
3222
|
+
if (processedMessageIds.has(id)) {
|
|
3223
|
+
logger.warn(`[REQUEST ${id}] Duplicate request detected - ignoring`);
|
|
3224
|
+
return;
|
|
3225
|
+
}
|
|
3226
|
+
processedMessageIds.add(id);
|
|
3227
|
+
if (processedMessageIds.size > 100) {
|
|
3228
|
+
const firstId = processedMessageIds.values().next().value;
|
|
3229
|
+
if (firstId) {
|
|
3230
|
+
processedMessageIds.delete(firstId);
|
|
3231
|
+
}
|
|
3232
|
+
}
|
|
3014
3233
|
if (!SA_RUNTIME) {
|
|
3015
3234
|
sendDataResponse4(id, {
|
|
3016
3235
|
success: false,
|
|
@@ -3050,7 +3269,6 @@ async function handleUserPromptRequest(data, components, sendMessage, anthropicA
|
|
|
3050
3269
|
return;
|
|
3051
3270
|
}
|
|
3052
3271
|
logCollector.info(`Starting user prompt request with ${components.length} components`);
|
|
3053
|
-
logger.info(`components length: ${components.length}`);
|
|
3054
3272
|
const threadManager = ThreadManager.getInstance();
|
|
3055
3273
|
let thread = threadManager.getThread(threadId);
|
|
3056
3274
|
if (!thread) {
|
|
@@ -4210,6 +4428,9 @@ var UserManager = class {
|
|
|
4210
4428
|
if (!user) {
|
|
4211
4429
|
return false;
|
|
4212
4430
|
}
|
|
4431
|
+
if (!user.wsIds || !Array.isArray(user.wsIds)) {
|
|
4432
|
+
user.wsIds = [];
|
|
4433
|
+
}
|
|
4213
4434
|
if (!user.wsIds.includes(wsId)) {
|
|
4214
4435
|
user.wsIds.push(wsId);
|
|
4215
4436
|
this.hasChanged = true;
|
|
@@ -4228,6 +4449,9 @@ var UserManager = class {
|
|
|
4228
4449
|
if (!user) {
|
|
4229
4450
|
return false;
|
|
4230
4451
|
}
|
|
4452
|
+
if (!user.wsIds || !Array.isArray(user.wsIds)) {
|
|
4453
|
+
return false;
|
|
4454
|
+
}
|
|
4231
4455
|
const initialLength = user.wsIds.length;
|
|
4232
4456
|
user.wsIds = user.wsIds.filter((id) => id !== wsId);
|
|
4233
4457
|
if (user.wsIds.length < initialLength) {
|
|
@@ -4793,6 +5017,9 @@ var SuperatomSDK = class {
|
|
|
4793
5017
|
this.userManager = new UserManager(this.projectId, 5e3);
|
|
4794
5018
|
this.dashboardManager = new DashboardManager(this.projectId);
|
|
4795
5019
|
this.reportManager = new ReportManager(this.projectId);
|
|
5020
|
+
this.initializePromptLoader(config.promptsDir).catch((error) => {
|
|
5021
|
+
logger.error("Failed to initialize PromptLoader:", error);
|
|
5022
|
+
});
|
|
4796
5023
|
this.initializeUserManager().catch((error) => {
|
|
4797
5024
|
logger.error("Failed to initialize UserManager:", error);
|
|
4798
5025
|
});
|
|
@@ -4802,6 +5029,21 @@ var SuperatomSDK = class {
|
|
|
4802
5029
|
logger.error("Failed to connect to Superatom:", error);
|
|
4803
5030
|
});
|
|
4804
5031
|
}
|
|
5032
|
+
/**
|
|
5033
|
+
* Initialize PromptLoader and load prompts into memory
|
|
5034
|
+
*/
|
|
5035
|
+
async initializePromptLoader(promptsDir) {
|
|
5036
|
+
try {
|
|
5037
|
+
if (promptsDir) {
|
|
5038
|
+
promptLoader.setPromptsDir(promptsDir);
|
|
5039
|
+
}
|
|
5040
|
+
await promptLoader.initialize();
|
|
5041
|
+
logger.info(`PromptLoader initialized with ${promptLoader.getCacheSize()} prompts from ${promptLoader.getPromptsDir()}`);
|
|
5042
|
+
} catch (error) {
|
|
5043
|
+
logger.error("Failed to initialize PromptLoader:", error);
|
|
5044
|
+
throw error;
|
|
5045
|
+
}
|
|
5046
|
+
}
|
|
4805
5047
|
/**
|
|
4806
5048
|
* Initialize UserManager for the project
|
|
4807
5049
|
*/
|