@superatomai/sdk-node 0.0.8 → 0.0.10
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 +942 -942
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +155 -541
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +158 -570
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -8,9 +8,6 @@ var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
|
8
8
|
var __esm = (fn, res) => function __init() {
|
|
9
9
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
10
|
};
|
|
11
|
-
var __commonJS = (cb, mod) => function __require() {
|
|
12
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
13
|
-
};
|
|
14
11
|
var __export = (target, all) => {
|
|
15
12
|
for (var name in all)
|
|
16
13
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -33,404 +30,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
33
30
|
));
|
|
34
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
35
32
|
|
|
36
|
-
// node_modules/dotenv/package.json
|
|
37
|
-
var require_package = __commonJS({
|
|
38
|
-
"node_modules/dotenv/package.json"(exports2, module2) {
|
|
39
|
-
module2.exports = {
|
|
40
|
-
name: "dotenv",
|
|
41
|
-
version: "17.2.3",
|
|
42
|
-
description: "Loads environment variables from .env file",
|
|
43
|
-
main: "lib/main.js",
|
|
44
|
-
types: "lib/main.d.ts",
|
|
45
|
-
exports: {
|
|
46
|
-
".": {
|
|
47
|
-
types: "./lib/main.d.ts",
|
|
48
|
-
require: "./lib/main.js",
|
|
49
|
-
default: "./lib/main.js"
|
|
50
|
-
},
|
|
51
|
-
"./config": "./config.js",
|
|
52
|
-
"./config.js": "./config.js",
|
|
53
|
-
"./lib/env-options": "./lib/env-options.js",
|
|
54
|
-
"./lib/env-options.js": "./lib/env-options.js",
|
|
55
|
-
"./lib/cli-options": "./lib/cli-options.js",
|
|
56
|
-
"./lib/cli-options.js": "./lib/cli-options.js",
|
|
57
|
-
"./package.json": "./package.json"
|
|
58
|
-
},
|
|
59
|
-
scripts: {
|
|
60
|
-
"dts-check": "tsc --project tests/types/tsconfig.json",
|
|
61
|
-
lint: "standard",
|
|
62
|
-
pretest: "npm run lint && npm run dts-check",
|
|
63
|
-
test: "tap run tests/**/*.js --allow-empty-coverage --disable-coverage --timeout=60000",
|
|
64
|
-
"test:coverage": "tap run tests/**/*.js --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov",
|
|
65
|
-
prerelease: "npm test",
|
|
66
|
-
release: "standard-version"
|
|
67
|
-
},
|
|
68
|
-
repository: {
|
|
69
|
-
type: "git",
|
|
70
|
-
url: "git://github.com/motdotla/dotenv.git"
|
|
71
|
-
},
|
|
72
|
-
homepage: "https://github.com/motdotla/dotenv#readme",
|
|
73
|
-
funding: "https://dotenvx.com",
|
|
74
|
-
keywords: [
|
|
75
|
-
"dotenv",
|
|
76
|
-
"env",
|
|
77
|
-
".env",
|
|
78
|
-
"environment",
|
|
79
|
-
"variables",
|
|
80
|
-
"config",
|
|
81
|
-
"settings"
|
|
82
|
-
],
|
|
83
|
-
readmeFilename: "README.md",
|
|
84
|
-
license: "BSD-2-Clause",
|
|
85
|
-
devDependencies: {
|
|
86
|
-
"@types/node": "^18.11.3",
|
|
87
|
-
decache: "^4.6.2",
|
|
88
|
-
sinon: "^14.0.1",
|
|
89
|
-
standard: "^17.0.0",
|
|
90
|
-
"standard-version": "^9.5.0",
|
|
91
|
-
tap: "^19.2.0",
|
|
92
|
-
typescript: "^4.8.4"
|
|
93
|
-
},
|
|
94
|
-
engines: {
|
|
95
|
-
node: ">=12"
|
|
96
|
-
},
|
|
97
|
-
browser: {
|
|
98
|
-
fs: false
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
// node_modules/dotenv/lib/main.js
|
|
105
|
-
var require_main = __commonJS({
|
|
106
|
-
"node_modules/dotenv/lib/main.js"(exports2, module2) {
|
|
107
|
-
"use strict";
|
|
108
|
-
var fs8 = require("fs");
|
|
109
|
-
var path7 = require("path");
|
|
110
|
-
var os4 = require("os");
|
|
111
|
-
var crypto2 = require("crypto");
|
|
112
|
-
var packageJson = require_package();
|
|
113
|
-
var version = packageJson.version;
|
|
114
|
-
var TIPS = [
|
|
115
|
-
"\u{1F510} encrypt with Dotenvx: https://dotenvx.com",
|
|
116
|
-
"\u{1F510} prevent committing .env to code: https://dotenvx.com/precommit",
|
|
117
|
-
"\u{1F510} prevent building .env in docker: https://dotenvx.com/prebuild",
|
|
118
|
-
"\u{1F4E1} add observability to secrets: https://dotenvx.com/ops",
|
|
119
|
-
"\u{1F465} sync secrets across teammates & machines: https://dotenvx.com/ops",
|
|
120
|
-
"\u{1F5C2}\uFE0F backup and recover secrets: https://dotenvx.com/ops",
|
|
121
|
-
"\u2705 audit secrets and track compliance: https://dotenvx.com/ops",
|
|
122
|
-
"\u{1F504} add secrets lifecycle management: https://dotenvx.com/ops",
|
|
123
|
-
"\u{1F511} add access controls to secrets: https://dotenvx.com/ops",
|
|
124
|
-
"\u{1F6E0}\uFE0F run anywhere with `dotenvx run -- yourcommand`",
|
|
125
|
-
"\u2699\uFE0F specify custom .env file path with { path: '/custom/path/.env' }",
|
|
126
|
-
"\u2699\uFE0F enable debug logging with { debug: true }",
|
|
127
|
-
"\u2699\uFE0F override existing env vars with { override: true }",
|
|
128
|
-
"\u2699\uFE0F suppress all logs with { quiet: true }",
|
|
129
|
-
"\u2699\uFE0F write to custom object with { processEnv: myObject }",
|
|
130
|
-
"\u2699\uFE0F load multiple .env files with { path: ['.env.local', '.env'] }"
|
|
131
|
-
];
|
|
132
|
-
function _getRandomTip() {
|
|
133
|
-
return TIPS[Math.floor(Math.random() * TIPS.length)];
|
|
134
|
-
}
|
|
135
|
-
function parseBoolean(value) {
|
|
136
|
-
if (typeof value === "string") {
|
|
137
|
-
return !["false", "0", "no", "off", ""].includes(value.toLowerCase());
|
|
138
|
-
}
|
|
139
|
-
return Boolean(value);
|
|
140
|
-
}
|
|
141
|
-
function supportsAnsi() {
|
|
142
|
-
return process.stdout.isTTY;
|
|
143
|
-
}
|
|
144
|
-
function dim(text) {
|
|
145
|
-
return supportsAnsi() ? `\x1B[2m${text}\x1B[0m` : text;
|
|
146
|
-
}
|
|
147
|
-
var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
|
|
148
|
-
function parse(src) {
|
|
149
|
-
const obj = {};
|
|
150
|
-
let lines = src.toString();
|
|
151
|
-
lines = lines.replace(/\r\n?/mg, "\n");
|
|
152
|
-
let match;
|
|
153
|
-
while ((match = LINE.exec(lines)) != null) {
|
|
154
|
-
const key = match[1];
|
|
155
|
-
let value = match[2] || "";
|
|
156
|
-
value = value.trim();
|
|
157
|
-
const maybeQuote = value[0];
|
|
158
|
-
value = value.replace(/^(['"`])([\s\S]*)\1$/mg, "$2");
|
|
159
|
-
if (maybeQuote === '"') {
|
|
160
|
-
value = value.replace(/\\n/g, "\n");
|
|
161
|
-
value = value.replace(/\\r/g, "\r");
|
|
162
|
-
}
|
|
163
|
-
obj[key] = value;
|
|
164
|
-
}
|
|
165
|
-
return obj;
|
|
166
|
-
}
|
|
167
|
-
function _parseVault(options) {
|
|
168
|
-
options = options || {};
|
|
169
|
-
const vaultPath = _vaultPath(options);
|
|
170
|
-
options.path = vaultPath;
|
|
171
|
-
const result = DotenvModule.configDotenv(options);
|
|
172
|
-
if (!result.parsed) {
|
|
173
|
-
const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`);
|
|
174
|
-
err.code = "MISSING_DATA";
|
|
175
|
-
throw err;
|
|
176
|
-
}
|
|
177
|
-
const keys = _dotenvKey(options).split(",");
|
|
178
|
-
const length = keys.length;
|
|
179
|
-
let decrypted;
|
|
180
|
-
for (let i = 0; i < length; i++) {
|
|
181
|
-
try {
|
|
182
|
-
const key = keys[i].trim();
|
|
183
|
-
const attrs = _instructions(result, key);
|
|
184
|
-
decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key);
|
|
185
|
-
break;
|
|
186
|
-
} catch (error) {
|
|
187
|
-
if (i + 1 >= length) {
|
|
188
|
-
throw error;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
return DotenvModule.parse(decrypted);
|
|
193
|
-
}
|
|
194
|
-
function _warn(message) {
|
|
195
|
-
console.error(`[dotenv@${version}][WARN] ${message}`);
|
|
196
|
-
}
|
|
197
|
-
function _debug(message) {
|
|
198
|
-
console.log(`[dotenv@${version}][DEBUG] ${message}`);
|
|
199
|
-
}
|
|
200
|
-
function _log(message) {
|
|
201
|
-
console.log(`[dotenv@${version}] ${message}`);
|
|
202
|
-
}
|
|
203
|
-
function _dotenvKey(options) {
|
|
204
|
-
if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {
|
|
205
|
-
return options.DOTENV_KEY;
|
|
206
|
-
}
|
|
207
|
-
if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {
|
|
208
|
-
return process.env.DOTENV_KEY;
|
|
209
|
-
}
|
|
210
|
-
return "";
|
|
211
|
-
}
|
|
212
|
-
function _instructions(result, dotenvKey) {
|
|
213
|
-
let uri;
|
|
214
|
-
try {
|
|
215
|
-
uri = new URL(dotenvKey);
|
|
216
|
-
} catch (error) {
|
|
217
|
-
if (error.code === "ERR_INVALID_URL") {
|
|
218
|
-
const err = new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development");
|
|
219
|
-
err.code = "INVALID_DOTENV_KEY";
|
|
220
|
-
throw err;
|
|
221
|
-
}
|
|
222
|
-
throw error;
|
|
223
|
-
}
|
|
224
|
-
const key = uri.password;
|
|
225
|
-
if (!key) {
|
|
226
|
-
const err = new Error("INVALID_DOTENV_KEY: Missing key part");
|
|
227
|
-
err.code = "INVALID_DOTENV_KEY";
|
|
228
|
-
throw err;
|
|
229
|
-
}
|
|
230
|
-
const environment = uri.searchParams.get("environment");
|
|
231
|
-
if (!environment) {
|
|
232
|
-
const err = new Error("INVALID_DOTENV_KEY: Missing environment part");
|
|
233
|
-
err.code = "INVALID_DOTENV_KEY";
|
|
234
|
-
throw err;
|
|
235
|
-
}
|
|
236
|
-
const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`;
|
|
237
|
-
const ciphertext = result.parsed[environmentKey];
|
|
238
|
-
if (!ciphertext) {
|
|
239
|
-
const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`);
|
|
240
|
-
err.code = "NOT_FOUND_DOTENV_ENVIRONMENT";
|
|
241
|
-
throw err;
|
|
242
|
-
}
|
|
243
|
-
return { ciphertext, key };
|
|
244
|
-
}
|
|
245
|
-
function _vaultPath(options) {
|
|
246
|
-
let possibleVaultPath = null;
|
|
247
|
-
if (options && options.path && options.path.length > 0) {
|
|
248
|
-
if (Array.isArray(options.path)) {
|
|
249
|
-
for (const filepath of options.path) {
|
|
250
|
-
if (fs8.existsSync(filepath)) {
|
|
251
|
-
possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
} else {
|
|
255
|
-
possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
|
|
256
|
-
}
|
|
257
|
-
} else {
|
|
258
|
-
possibleVaultPath = path7.resolve(process.cwd(), ".env.vault");
|
|
259
|
-
}
|
|
260
|
-
if (fs8.existsSync(possibleVaultPath)) {
|
|
261
|
-
return possibleVaultPath;
|
|
262
|
-
}
|
|
263
|
-
return null;
|
|
264
|
-
}
|
|
265
|
-
function _resolveHome(envPath) {
|
|
266
|
-
return envPath[0] === "~" ? path7.join(os4.homedir(), envPath.slice(1)) : envPath;
|
|
267
|
-
}
|
|
268
|
-
function _configVault(options) {
|
|
269
|
-
const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || options && options.debug);
|
|
270
|
-
const quiet = parseBoolean(process.env.DOTENV_CONFIG_QUIET || options && options.quiet);
|
|
271
|
-
if (debug || !quiet) {
|
|
272
|
-
_log("Loading env from encrypted .env.vault");
|
|
273
|
-
}
|
|
274
|
-
const parsed = DotenvModule._parseVault(options);
|
|
275
|
-
let processEnv = process.env;
|
|
276
|
-
if (options && options.processEnv != null) {
|
|
277
|
-
processEnv = options.processEnv;
|
|
278
|
-
}
|
|
279
|
-
DotenvModule.populate(processEnv, parsed, options);
|
|
280
|
-
return { parsed };
|
|
281
|
-
}
|
|
282
|
-
function configDotenv(options) {
|
|
283
|
-
const dotenvPath = path7.resolve(process.cwd(), ".env");
|
|
284
|
-
let encoding = "utf8";
|
|
285
|
-
let processEnv = process.env;
|
|
286
|
-
if (options && options.processEnv != null) {
|
|
287
|
-
processEnv = options.processEnv;
|
|
288
|
-
}
|
|
289
|
-
let debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || options && options.debug);
|
|
290
|
-
let quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || options && options.quiet);
|
|
291
|
-
if (options && options.encoding) {
|
|
292
|
-
encoding = options.encoding;
|
|
293
|
-
} else {
|
|
294
|
-
if (debug) {
|
|
295
|
-
_debug("No encoding is specified. UTF-8 is used by default");
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
let optionPaths = [dotenvPath];
|
|
299
|
-
if (options && options.path) {
|
|
300
|
-
if (!Array.isArray(options.path)) {
|
|
301
|
-
optionPaths = [_resolveHome(options.path)];
|
|
302
|
-
} else {
|
|
303
|
-
optionPaths = [];
|
|
304
|
-
for (const filepath of options.path) {
|
|
305
|
-
optionPaths.push(_resolveHome(filepath));
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
let lastError;
|
|
310
|
-
const parsedAll = {};
|
|
311
|
-
for (const path8 of optionPaths) {
|
|
312
|
-
try {
|
|
313
|
-
const parsed = DotenvModule.parse(fs8.readFileSync(path8, { encoding }));
|
|
314
|
-
DotenvModule.populate(parsedAll, parsed, options);
|
|
315
|
-
} catch (e) {
|
|
316
|
-
if (debug) {
|
|
317
|
-
_debug(`Failed to load ${path8} ${e.message}`);
|
|
318
|
-
}
|
|
319
|
-
lastError = e;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
const populated = DotenvModule.populate(processEnv, parsedAll, options);
|
|
323
|
-
debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || debug);
|
|
324
|
-
quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || quiet);
|
|
325
|
-
if (debug || !quiet) {
|
|
326
|
-
const keysCount = Object.keys(populated).length;
|
|
327
|
-
const shortPaths = [];
|
|
328
|
-
for (const filePath of optionPaths) {
|
|
329
|
-
try {
|
|
330
|
-
const relative = path7.relative(process.cwd(), filePath);
|
|
331
|
-
shortPaths.push(relative);
|
|
332
|
-
} catch (e) {
|
|
333
|
-
if (debug) {
|
|
334
|
-
_debug(`Failed to load ${filePath} ${e.message}`);
|
|
335
|
-
}
|
|
336
|
-
lastError = e;
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
_log(`injecting env (${keysCount}) from ${shortPaths.join(",")} ${dim(`-- tip: ${_getRandomTip()}`)}`);
|
|
340
|
-
}
|
|
341
|
-
if (lastError) {
|
|
342
|
-
return { parsed: parsedAll, error: lastError };
|
|
343
|
-
} else {
|
|
344
|
-
return { parsed: parsedAll };
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
function config(options) {
|
|
348
|
-
if (_dotenvKey(options).length === 0) {
|
|
349
|
-
return DotenvModule.configDotenv(options);
|
|
350
|
-
}
|
|
351
|
-
const vaultPath = _vaultPath(options);
|
|
352
|
-
if (!vaultPath) {
|
|
353
|
-
_warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`);
|
|
354
|
-
return DotenvModule.configDotenv(options);
|
|
355
|
-
}
|
|
356
|
-
return DotenvModule._configVault(options);
|
|
357
|
-
}
|
|
358
|
-
function decrypt(encrypted, keyStr) {
|
|
359
|
-
const key = Buffer.from(keyStr.slice(-64), "hex");
|
|
360
|
-
let ciphertext = Buffer.from(encrypted, "base64");
|
|
361
|
-
const nonce = ciphertext.subarray(0, 12);
|
|
362
|
-
const authTag = ciphertext.subarray(-16);
|
|
363
|
-
ciphertext = ciphertext.subarray(12, -16);
|
|
364
|
-
try {
|
|
365
|
-
const aesgcm = crypto2.createDecipheriv("aes-256-gcm", key, nonce);
|
|
366
|
-
aesgcm.setAuthTag(authTag);
|
|
367
|
-
return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
|
|
368
|
-
} catch (error) {
|
|
369
|
-
const isRange = error instanceof RangeError;
|
|
370
|
-
const invalidKeyLength = error.message === "Invalid key length";
|
|
371
|
-
const decryptionFailed = error.message === "Unsupported state or unable to authenticate data";
|
|
372
|
-
if (isRange || invalidKeyLength) {
|
|
373
|
-
const err = new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");
|
|
374
|
-
err.code = "INVALID_DOTENV_KEY";
|
|
375
|
-
throw err;
|
|
376
|
-
} else if (decryptionFailed) {
|
|
377
|
-
const err = new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");
|
|
378
|
-
err.code = "DECRYPTION_FAILED";
|
|
379
|
-
throw err;
|
|
380
|
-
} else {
|
|
381
|
-
throw error;
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
function populate(processEnv, parsed, options = {}) {
|
|
386
|
-
const debug = Boolean(options && options.debug);
|
|
387
|
-
const override = Boolean(options && options.override);
|
|
388
|
-
const populated = {};
|
|
389
|
-
if (typeof parsed !== "object") {
|
|
390
|
-
const err = new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
|
|
391
|
-
err.code = "OBJECT_REQUIRED";
|
|
392
|
-
throw err;
|
|
393
|
-
}
|
|
394
|
-
for (const key of Object.keys(parsed)) {
|
|
395
|
-
if (Object.prototype.hasOwnProperty.call(processEnv, key)) {
|
|
396
|
-
if (override === true) {
|
|
397
|
-
processEnv[key] = parsed[key];
|
|
398
|
-
populated[key] = parsed[key];
|
|
399
|
-
}
|
|
400
|
-
if (debug) {
|
|
401
|
-
if (override === true) {
|
|
402
|
-
_debug(`"${key}" is already defined and WAS overwritten`);
|
|
403
|
-
} else {
|
|
404
|
-
_debug(`"${key}" is already defined and was NOT overwritten`);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
} else {
|
|
408
|
-
processEnv[key] = parsed[key];
|
|
409
|
-
populated[key] = parsed[key];
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
return populated;
|
|
413
|
-
}
|
|
414
|
-
var DotenvModule = {
|
|
415
|
-
configDotenv,
|
|
416
|
-
_configVault,
|
|
417
|
-
_parseVault,
|
|
418
|
-
config,
|
|
419
|
-
decrypt,
|
|
420
|
-
parse,
|
|
421
|
-
populate
|
|
422
|
-
};
|
|
423
|
-
module2.exports.configDotenv = DotenvModule.configDotenv;
|
|
424
|
-
module2.exports._configVault = DotenvModule._configVault;
|
|
425
|
-
module2.exports._parseVault = DotenvModule._parseVault;
|
|
426
|
-
module2.exports.config = DotenvModule.config;
|
|
427
|
-
module2.exports.decrypt = DotenvModule.decrypt;
|
|
428
|
-
module2.exports.parse = DotenvModule.parse;
|
|
429
|
-
module2.exports.populate = DotenvModule.populate;
|
|
430
|
-
module2.exports = DotenvModule;
|
|
431
|
-
}
|
|
432
|
-
});
|
|
433
|
-
|
|
434
33
|
// src/userResponse/utils.ts
|
|
435
34
|
var utils_exports = {};
|
|
436
35
|
__export(utils_exports, {
|
|
@@ -861,7 +460,7 @@ var UserPromptSuggestionsMessageSchema = import_zod3.z.object({
|
|
|
861
460
|
payload: UserPromptSuggestionsPayloadSchema
|
|
862
461
|
});
|
|
863
462
|
var ComponentPropsSchema = import_zod3.z.object({
|
|
864
|
-
query: import_zod3.z.string().optional(),
|
|
463
|
+
query: import_zod3.z.string().or(import_zod3.z.object({})).optional(),
|
|
865
464
|
title: import_zod3.z.string().optional(),
|
|
866
465
|
description: import_zod3.z.string().optional(),
|
|
867
466
|
config: import_zod3.z.record(import_zod3.z.unknown()).optional(),
|
|
@@ -2060,7 +1659,7 @@ function sendDataResponse3(id, res, sendMessage, clientId) {
|
|
|
2060
1659
|
}
|
|
2061
1660
|
|
|
2062
1661
|
// src/userResponse/groq.ts
|
|
2063
|
-
var import_dotenv = __toESM(
|
|
1662
|
+
var import_dotenv = __toESM(require("dotenv"));
|
|
2064
1663
|
|
|
2065
1664
|
// src/userResponse/base-llm.ts
|
|
2066
1665
|
init_utils();
|
|
@@ -2688,6 +2287,7 @@ When the user asks about data
|
|
|
2688
2287
|
|
|
2689
2288
|
After analyzing the query results, you MUST suggest appropriate dashboard components for displaying the data. Use this format:
|
|
2690
2289
|
|
|
2290
|
+
<DashboardComponents>
|
|
2691
2291
|
**Dashboard Components:**
|
|
2692
2292
|
Format: \`{number}.{component_type} : {clear reasoning}\`
|
|
2693
2293
|
|
|
@@ -2696,9 +2296,9 @@ Format: \`{number}.{component_type} : {clear reasoning}\`
|
|
|
2696
2296
|
1. Analyze the query results structure and data type
|
|
2697
2297
|
2. Suggest components that would best visualize the data
|
|
2698
2298
|
3. Each component suggestion must be on a new line
|
|
2299
|
+
</DashboardComponents>
|
|
2699
2300
|
|
|
2700
|
-
|
|
2701
|
-
IMPORTANT: Always include the **Dashboard Components:** section with at least one component suggestion when data is returned.
|
|
2301
|
+
IMPORTANT: Always wrap component suggestions with <DashboardComponents> tags and include at least one component suggestion when data is returned.
|
|
2702
2302
|
|
|
2703
2303
|
## Output Format
|
|
2704
2304
|
|
|
@@ -2706,7 +2306,7 @@ Respond with plain text that includes:
|
|
|
2706
2306
|
|
|
2707
2307
|
1. **Query Analysis** (if applicable): Brief explanation of what data was fetched
|
|
2708
2308
|
2. **Results Summary**: Present the data in a clear, readable format
|
|
2709
|
-
3. **Dashboard Components**: List suggested components in
|
|
2309
|
+
3. **Dashboard Components**: List suggested components wrapped in <DashboardComponents> tags
|
|
2710
2310
|
|
|
2711
2311
|
|
|
2712
2312
|
**CRITICAL:**
|
|
@@ -2783,39 +2383,22 @@ You will receive a text response containing:
|
|
|
2783
2383
|
3. **Dashboard Components:** suggestions (1:component_type : reasoning format)
|
|
2784
2384
|
|
|
2785
2385
|
Your job is to:
|
|
2786
|
-
1. **
|
|
2787
|
-
2.
|
|
2788
|
-
3.
|
|
2789
|
-
4.
|
|
2790
|
-
5. Generate
|
|
2791
|
-
6. **Generate intelligent follow-up questions (actions)** that the user might naturally ask next based on the data analysis
|
|
2386
|
+
1. **Parse the component suggestions** from the text response (format: 1:component_type : reasoning)
|
|
2387
|
+
2. **Match each suggestion with an actual component** from the available list
|
|
2388
|
+
3. **Generate proper props** for each matched component to **visualize the analysis results** that were already fetched
|
|
2389
|
+
4. **SELECT the best dashboard layout component** that can accommodate all the matched components
|
|
2390
|
+
5. **Generate intelligent follow-up questions (actions)** that the user might naturally ask next based on the data analysis
|
|
2792
2391
|
|
|
2793
2392
|
**CRITICAL GOAL**: Create dashboard components that display the **same data that was already analyzed** - NOT new data. The queries already ran and got results. You're just creating different visualizations of those results.
|
|
2794
2393
|
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
## Layout Component Discovery
|
|
2798
|
-
**Find layout components** by looking for components with \`type: "DashboardLayout"\`
|
|
2799
|
-
|
|
2800
|
-
## Layout Selection Logic
|
|
2801
|
-
1. **Read each layout's description** to understand:
|
|
2802
|
-
- What structure it provides
|
|
2803
|
-
- When it's best used (e.g., comprehensive analysis vs focused analysis)
|
|
2804
|
-
- The exact number and types of components it requires
|
|
2805
|
-
2. **Select the best layout** based on:
|
|
2806
|
-
- Which layout structure best fits the analysis needs
|
|
2807
|
-
- The component suggestions from the text response
|
|
2808
|
-
- The user question and data complexity
|
|
2809
|
-
3. **Generate EXACTLY the components specified** in the selected layout's description
|
|
2810
|
-
|
|
2811
|
-
**IMPORTANT:** Always prefer structured dashboard layouts when available. The layout component's description will tell you exactly what components to generate.
|
|
2394
|
+
**APPROACH**: First match all the components suggested in the text response, THEN find the layout that best fits those components.
|
|
2812
2395
|
|
|
2813
2396
|
## Available Components
|
|
2814
2397
|
|
|
2815
2398
|
{{AVAILABLE_COMPONENTS}}
|
|
2816
2399
|
|
|
2817
|
-
## Component Matching Rules
|
|
2818
|
-
For each component suggestion (c1, c2, c3, etc.):
|
|
2400
|
+
## Component Matching Rules (STEP 1)
|
|
2401
|
+
For each component suggestion (c1, c2, c3, etc.) from the text response:
|
|
2819
2402
|
|
|
2820
2403
|
1. **Match by type**: Find components whose \`type\` matches the suggested component type
|
|
2821
2404
|
2. **Refine by relevance**: If multiple components match, choose based on:
|
|
@@ -2823,6 +2406,24 @@ For each component suggestion (c1, c2, c3, etc.):
|
|
|
2823
2406
|
- Best fit for the data being visualized
|
|
2824
2407
|
3. **Fallback**: If no exact type match, find the closest alternative
|
|
2825
2408
|
|
|
2409
|
+
## Layout Selection Logic (STEP 2 - After Matching Components)
|
|
2410
|
+
|
|
2411
|
+
**After you have matched all components**, select the best dashboard layout:
|
|
2412
|
+
|
|
2413
|
+
1. **Find layout components** by looking for components with \`type: "DashboardLayout"\` in the available components list
|
|
2414
|
+
2. **Read each layout's description** to understand:
|
|
2415
|
+
- What structure it provides
|
|
2416
|
+
- When it's best used (e.g., comprehensive analysis vs focused analysis)
|
|
2417
|
+
- The number and types of components it can accommodate
|
|
2418
|
+
3. **Select the best layout** based on:
|
|
2419
|
+
- Which layout can best display ALL the matched components
|
|
2420
|
+
- The layout's capacity (how many components it supports)
|
|
2421
|
+
- The types of matched components (KPI, charts, tables, etc.)
|
|
2422
|
+
- The user question and data complexity
|
|
2423
|
+
4. **If no specific layout fits**, fall back to "MultiComponentContainer" as the default layout
|
|
2424
|
+
|
|
2425
|
+
**IMPORTANT:** The layout should be chosen to FIT the matched components, not the other way around. Don't force components to fit a layout - find a layout that accommodates your components.
|
|
2426
|
+
|
|
2826
2427
|
## Props Generation Rules
|
|
2827
2428
|
|
|
2828
2429
|
For each matched component, generate complete props:
|
|
@@ -2935,7 +2536,6 @@ You MUST respond with ONLY a valid JSON object (no markdown, no code blocks):
|
|
|
2935
2536
|
|
|
2936
2537
|
\`\`\`json
|
|
2937
2538
|
{
|
|
2938
|
-
"selectedLayout": "Name of the selected layout component from available components",
|
|
2939
2539
|
"selectedLayoutId": "id_of_the_selected_layout_component",
|
|
2940
2540
|
"layoutReasoning": "Why this layout was selected based on its description and the analysis needs",
|
|
2941
2541
|
"matchedComponents": [
|
|
@@ -2967,13 +2567,14 @@ You MUST respond with ONLY a valid JSON object (no markdown, no code blocks):
|
|
|
2967
2567
|
\`\`\`
|
|
2968
2568
|
|
|
2969
2569
|
**CRITICAL:**
|
|
2970
|
-
- \`
|
|
2971
|
-
- \`selectedLayoutId\` MUST be the ID of the selected layout component
|
|
2570
|
+
- \`matchedComponents\` MUST include ALL components suggested in the text response (match them first!)
|
|
2571
|
+
- \`selectedLayoutId\` MUST be the ID of the selected layout component (must have type "DashboardLayout")
|
|
2972
2572
|
- \`layoutReasoning\` MUST explain:
|
|
2973
2573
|
- Why you chose this specific layout component
|
|
2974
|
-
- How
|
|
2975
|
-
-
|
|
2976
|
-
-
|
|
2574
|
+
- How many components you matched (e.g., "Matched 3 components: 1 KPI, 1 chart, 1 table")
|
|
2575
|
+
- Why this layout is the best fit for displaying these specific matched components
|
|
2576
|
+
- What makes this layout appropriate for the component types and count
|
|
2577
|
+
- The layout selection happens AFTER component matching - don't force components to fit a pre-selected layout
|
|
2977
2578
|
- \`actions\` MUST be an array of 4-5 intelligent follow-up questions based on the analysis
|
|
2978
2579
|
- Return ONLY valid JSON (no markdown code blocks, no text before/after)
|
|
2979
2580
|
- Generate complete props for each component
|
|
@@ -3169,6 +2770,7 @@ var promptLoader = new PromptLoader({
|
|
|
3169
2770
|
// src/llm.ts
|
|
3170
2771
|
var import_sdk = __toESM(require("@anthropic-ai/sdk"));
|
|
3171
2772
|
var import_groq_sdk = __toESM(require("groq-sdk"));
|
|
2773
|
+
var import_jsonrepair = require("jsonrepair");
|
|
3172
2774
|
var LLM = class {
|
|
3173
2775
|
/* Get a complete text response from an LLM (Anthropic or Groq) */
|
|
3174
2776
|
static async text(messages, options = {}) {
|
|
@@ -3290,65 +2892,110 @@ var LLM = class {
|
|
|
3290
2892
|
let finalText = "";
|
|
3291
2893
|
while (iterations < maxIterations) {
|
|
3292
2894
|
iterations++;
|
|
3293
|
-
const
|
|
2895
|
+
const stream = await client.messages.create({
|
|
3294
2896
|
model: modelName,
|
|
3295
2897
|
max_tokens: options.maxTokens || 4e3,
|
|
3296
2898
|
temperature: options.temperature,
|
|
3297
2899
|
system: messages.sys,
|
|
3298
2900
|
messages: conversationMessages,
|
|
3299
|
-
tools
|
|
2901
|
+
tools,
|
|
2902
|
+
stream: true
|
|
2903
|
+
// Enable streaming
|
|
3300
2904
|
});
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
2905
|
+
let stopReason = null;
|
|
2906
|
+
const contentBlocks = [];
|
|
2907
|
+
let currentTextBlock = "";
|
|
2908
|
+
let currentToolUse = null;
|
|
2909
|
+
for await (const chunk of stream) {
|
|
2910
|
+
if (chunk.type === "message_start") {
|
|
2911
|
+
contentBlocks.length = 0;
|
|
2912
|
+
currentTextBlock = "";
|
|
2913
|
+
currentToolUse = null;
|
|
2914
|
+
}
|
|
2915
|
+
if (chunk.type === "content_block_start") {
|
|
2916
|
+
if (chunk.content_block.type === "text") {
|
|
2917
|
+
currentTextBlock = "";
|
|
2918
|
+
} else if (chunk.content_block.type === "tool_use") {
|
|
2919
|
+
currentToolUse = {
|
|
2920
|
+
type: "tool_use",
|
|
2921
|
+
id: chunk.content_block.id,
|
|
2922
|
+
name: chunk.content_block.name,
|
|
2923
|
+
input: {}
|
|
2924
|
+
};
|
|
2925
|
+
}
|
|
2926
|
+
}
|
|
2927
|
+
if (chunk.type === "content_block_delta") {
|
|
2928
|
+
if (chunk.delta.type === "text_delta") {
|
|
2929
|
+
const text = chunk.delta.text;
|
|
2930
|
+
currentTextBlock += text;
|
|
2931
|
+
if (options.partial) {
|
|
2932
|
+
options.partial(text);
|
|
2933
|
+
}
|
|
2934
|
+
} else if (chunk.delta.type === "input_json_delta" && currentToolUse) {
|
|
2935
|
+
currentToolUse.inputJson = (currentToolUse.inputJson || "") + chunk.delta.partial_json;
|
|
3307
2936
|
}
|
|
3308
2937
|
}
|
|
2938
|
+
if (chunk.type === "content_block_stop") {
|
|
2939
|
+
if (currentTextBlock) {
|
|
2940
|
+
contentBlocks.push({
|
|
2941
|
+
type: "text",
|
|
2942
|
+
text: currentTextBlock
|
|
2943
|
+
});
|
|
2944
|
+
finalText = currentTextBlock;
|
|
2945
|
+
currentTextBlock = "";
|
|
2946
|
+
} else if (currentToolUse) {
|
|
2947
|
+
try {
|
|
2948
|
+
currentToolUse.input = currentToolUse.inputJson ? JSON.parse(currentToolUse.inputJson) : {};
|
|
2949
|
+
} catch (error) {
|
|
2950
|
+
currentToolUse.input = {};
|
|
2951
|
+
}
|
|
2952
|
+
delete currentToolUse.inputJson;
|
|
2953
|
+
contentBlocks.push(currentToolUse);
|
|
2954
|
+
currentToolUse = null;
|
|
2955
|
+
}
|
|
2956
|
+
}
|
|
2957
|
+
if (chunk.type === "message_delta") {
|
|
2958
|
+
stopReason = chunk.delta.stop_reason || stopReason;
|
|
2959
|
+
}
|
|
2960
|
+
if (chunk.type === "message_stop") {
|
|
2961
|
+
break;
|
|
2962
|
+
}
|
|
2963
|
+
}
|
|
2964
|
+
if (stopReason === "end_turn") {
|
|
3309
2965
|
break;
|
|
3310
2966
|
}
|
|
3311
|
-
if (
|
|
3312
|
-
const toolUses =
|
|
2967
|
+
if (stopReason === "tool_use") {
|
|
2968
|
+
const toolUses = contentBlocks.filter((block) => block.type === "tool_use");
|
|
3313
2969
|
if (toolUses.length === 0) {
|
|
3314
2970
|
break;
|
|
3315
2971
|
}
|
|
3316
2972
|
conversationMessages.push({
|
|
3317
2973
|
role: "assistant",
|
|
3318
|
-
content:
|
|
2974
|
+
content: contentBlocks
|
|
3319
2975
|
});
|
|
3320
2976
|
const toolResults = {
|
|
3321
2977
|
role: "user",
|
|
3322
2978
|
content: []
|
|
3323
2979
|
};
|
|
3324
2980
|
for (const toolUse of toolUses) {
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
});
|
|
3340
|
-
}
|
|
2981
|
+
try {
|
|
2982
|
+
const result = await toolHandler(toolUse.name, toolUse.input);
|
|
2983
|
+
toolResults.content.push({
|
|
2984
|
+
type: "tool_result",
|
|
2985
|
+
tool_use_id: toolUse.id,
|
|
2986
|
+
content: typeof result === "string" ? result : JSON.stringify(result)
|
|
2987
|
+
});
|
|
2988
|
+
} catch (error) {
|
|
2989
|
+
toolResults.content.push({
|
|
2990
|
+
type: "tool_result",
|
|
2991
|
+
tool_use_id: toolUse.id,
|
|
2992
|
+
content: error instanceof Error ? error.message : String(error),
|
|
2993
|
+
is_error: true
|
|
2994
|
+
});
|
|
3341
2995
|
}
|
|
3342
2996
|
}
|
|
3343
2997
|
conversationMessages.push(toolResults);
|
|
3344
2998
|
} else {
|
|
3345
|
-
const textBlock = response.content.find((block) => block.type === "text");
|
|
3346
|
-
if (textBlock && textBlock.type === "text") {
|
|
3347
|
-
finalText = textBlock.text;
|
|
3348
|
-
if (options.partial) {
|
|
3349
|
-
options.partial(finalText);
|
|
3350
|
-
}
|
|
3351
|
-
}
|
|
3352
2999
|
break;
|
|
3353
3000
|
}
|
|
3354
3001
|
}
|
|
@@ -3411,9 +3058,9 @@ var LLM = class {
|
|
|
3411
3058
|
// ============================================================
|
|
3412
3059
|
/**
|
|
3413
3060
|
* Parse JSON string, handling markdown code blocks and surrounding text
|
|
3414
|
-
* Enhanced version from
|
|
3061
|
+
* Enhanced version with jsonrepair to handle malformed JSON from LLMs
|
|
3415
3062
|
* @param text - Text that may contain JSON wrapped in ```json...``` or with surrounding text
|
|
3416
|
-
* @returns Parsed JSON object
|
|
3063
|
+
* @returns Parsed JSON object or array
|
|
3417
3064
|
*/
|
|
3418
3065
|
static _parseJSON(text) {
|
|
3419
3066
|
let jsonText = text.trim();
|
|
@@ -3423,11 +3070,29 @@ var LLM = class {
|
|
|
3423
3070
|
jsonText = jsonText.replace(/^```\s*\n?/, "").replace(/\n?```\s*$/, "");
|
|
3424
3071
|
}
|
|
3425
3072
|
const firstBrace = jsonText.indexOf("{");
|
|
3073
|
+
const firstBracket = jsonText.indexOf("[");
|
|
3426
3074
|
const lastBrace = jsonText.lastIndexOf("}");
|
|
3427
|
-
|
|
3428
|
-
|
|
3075
|
+
const lastBracket = jsonText.lastIndexOf("]");
|
|
3076
|
+
let startIdx = -1;
|
|
3077
|
+
let endIdx = -1;
|
|
3078
|
+
if (firstBrace !== -1 && (firstBracket === -1 || firstBrace < firstBracket)) {
|
|
3079
|
+
startIdx = firstBrace;
|
|
3080
|
+
endIdx = lastBrace;
|
|
3081
|
+
} else if (firstBracket !== -1) {
|
|
3082
|
+
startIdx = firstBracket;
|
|
3083
|
+
endIdx = lastBracket;
|
|
3084
|
+
}
|
|
3085
|
+
if (startIdx !== -1 && endIdx !== -1 && startIdx < endIdx) {
|
|
3086
|
+
jsonText = jsonText.substring(startIdx, endIdx + 1);
|
|
3087
|
+
}
|
|
3088
|
+
try {
|
|
3089
|
+
const repairedJson = (0, import_jsonrepair.jsonrepair)(jsonText);
|
|
3090
|
+
return JSON.parse(repairedJson);
|
|
3091
|
+
} catch (error) {
|
|
3092
|
+
throw new Error(`Failed to parse JSON: ${error instanceof Error ? error.message : String(error)}
|
|
3093
|
+
|
|
3094
|
+
Original text: ${jsonText.substring(0, 200)}...`);
|
|
3429
3095
|
}
|
|
3430
|
-
return JSON.parse(jsonText);
|
|
3431
3096
|
}
|
|
3432
3097
|
};
|
|
3433
3098
|
|
|
@@ -4040,7 +3705,7 @@ var BaseLLM = class {
|
|
|
4040
3705
|
logger.debug(`[${this.getProviderName()}] Loaded match-text-components prompts`);
|
|
4041
3706
|
logger.file("\n=============================\nmatch text components system prompt:", prompts.system);
|
|
4042
3707
|
logCollector?.info("Matching components from text response...");
|
|
4043
|
-
const
|
|
3708
|
+
const result = await LLM.stream(
|
|
4044
3709
|
{
|
|
4045
3710
|
sys: prompts.system,
|
|
4046
3711
|
user: prompts.user
|
|
@@ -4051,60 +3716,12 @@ var BaseLLM = class {
|
|
|
4051
3716
|
temperature: 0.2,
|
|
4052
3717
|
apiKey: this.getApiKey(apiKey)
|
|
4053
3718
|
},
|
|
4054
|
-
|
|
4055
|
-
//
|
|
3719
|
+
true
|
|
3720
|
+
// Parse as JSON
|
|
4056
3721
|
);
|
|
4057
|
-
logger.debug(`[${this.getProviderName()}]
|
|
4058
|
-
let result;
|
|
4059
|
-
try {
|
|
4060
|
-
let cleanedResponse = rawResponse || "";
|
|
4061
|
-
cleanedResponse = cleanedResponse.replace(/```json\n?/g, "").replace(/```\n?/g, "").trim();
|
|
4062
|
-
const jsonMatch = cleanedResponse.match(/\{[\s\S]*\}/);
|
|
4063
|
-
if (jsonMatch) {
|
|
4064
|
-
cleanedResponse = jsonMatch[0];
|
|
4065
|
-
}
|
|
4066
|
-
result = JSON.parse(cleanedResponse);
|
|
4067
|
-
} catch (parseError) {
|
|
4068
|
-
logger.error(`[${this.getProviderName()}] Failed to parse component matching JSON response`);
|
|
4069
|
-
const errorMsg = parseError instanceof Error ? parseError.message : String(parseError);
|
|
4070
|
-
const posMatch = errorMsg.match(/position (\d+)/);
|
|
4071
|
-
const errorPos = posMatch ? parseInt(posMatch[1]) : -1;
|
|
4072
|
-
if (errorPos > 0 && rawResponse) {
|
|
4073
|
-
const start = Math.max(0, errorPos - 200);
|
|
4074
|
-
const end = Math.min(rawResponse.length, errorPos + 200);
|
|
4075
|
-
logger.debug(`[${this.getProviderName()}] Error context (position ${errorPos}):`);
|
|
4076
|
-
logger.debug(rawResponse.substring(start, end));
|
|
4077
|
-
logger.debug(" ".repeat(Math.min(200, errorPos - start)) + "^--- Error here");
|
|
4078
|
-
}
|
|
4079
|
-
logger.debug(`[${this.getProviderName()}] Raw response (first 2000 chars):`, rawResponse?.substring(0, 2e3));
|
|
4080
|
-
logger.debug(`[${this.getProviderName()}] Parse error:`, parseError);
|
|
4081
|
-
logCollector?.error(`Failed to parse component matching response: ${errorMsg}`);
|
|
4082
|
-
try {
|
|
4083
|
-
logger.info(`[${this.getProviderName()}] Attempting aggressive JSON cleanup...`);
|
|
4084
|
-
let aggressive = rawResponse || "";
|
|
4085
|
-
aggressive = aggressive.replace(/```json\n?/g, "").replace(/```\n?/g, "").trim();
|
|
4086
|
-
const match = aggressive.match(/\{[\s\S]*\}/);
|
|
4087
|
-
if (match) {
|
|
4088
|
-
aggressive = match[0];
|
|
4089
|
-
}
|
|
4090
|
-
aggressive = aggressive.replace(/,(\s*[}\]])/g, "$1");
|
|
4091
|
-
result = JSON.parse(aggressive);
|
|
4092
|
-
logger.info(`[${this.getProviderName()}] Aggressive cleanup succeeded!`);
|
|
4093
|
-
} catch (secondError) {
|
|
4094
|
-
logger.error(`[${this.getProviderName()}] Aggressive cleanup also failed`);
|
|
4095
|
-
return {
|
|
4096
|
-
components: [],
|
|
4097
|
-
selectedLayout: "MultiComponentContainer",
|
|
4098
|
-
selectedLayoutId: "",
|
|
4099
|
-
selectedLayoutComponent: null,
|
|
4100
|
-
layoutReasoning: "No layout selected",
|
|
4101
|
-
actions: []
|
|
4102
|
-
};
|
|
4103
|
-
}
|
|
4104
|
-
}
|
|
3722
|
+
logger.debug(`[${this.getProviderName()}] Component matching response parsed successfully`);
|
|
4105
3723
|
const matchedComponents = result.matchedComponents || [];
|
|
4106
|
-
const
|
|
4107
|
-
const selectedLayoutId = result.selectedLayoutId || "";
|
|
3724
|
+
const selectedLayoutId = result.selectedLayoutId || "multi-component-container";
|
|
4108
3725
|
const layoutReasoning = result.layoutReasoning || "No layout reasoning provided";
|
|
4109
3726
|
const rawActions = result.actions || [];
|
|
4110
3727
|
const actions = convertQuestionsToActions(rawActions);
|
|
@@ -4116,11 +3733,11 @@ var BaseLLM = class {
|
|
|
4116
3733
|
}
|
|
4117
3734
|
}
|
|
4118
3735
|
logger.info(`[${this.getProviderName()}] Matched ${matchedComponents.length} components from text response`);
|
|
4119
|
-
logger.info(`[${this.getProviderName()}] Selected layout:
|
|
3736
|
+
logger.info(`[${this.getProviderName()}] Selected layout: (ID: ${selectedLayoutId})`);
|
|
4120
3737
|
logger.info(`[${this.getProviderName()}] Layout reasoning: ${layoutReasoning}`);
|
|
4121
3738
|
logger.info(`[${this.getProviderName()}] Generated ${actions.length} follow-up actions`);
|
|
4122
3739
|
if (matchedComponents.length > 0) {
|
|
4123
|
-
logCollector?.info(`Matched ${matchedComponents.length} components for visualization
|
|
3740
|
+
logCollector?.info(`Matched ${matchedComponents.length} components for visualization `);
|
|
4124
3741
|
logCollector?.info(`Layout reasoning: ${layoutReasoning}`);
|
|
4125
3742
|
matchedComponents.forEach((comp, idx) => {
|
|
4126
3743
|
logCollector?.info(` ${idx + 1}. ${comp.componentName} (${comp.componentType}): ${comp.reasoning}`);
|
|
@@ -4155,7 +3772,6 @@ var BaseLLM = class {
|
|
|
4155
3772
|
}).filter(Boolean);
|
|
4156
3773
|
return {
|
|
4157
3774
|
components: finalComponents,
|
|
4158
|
-
selectedLayout,
|
|
4159
3775
|
selectedLayoutId,
|
|
4160
3776
|
selectedLayoutComponent,
|
|
4161
3777
|
layoutReasoning,
|
|
@@ -4163,15 +3779,13 @@ var BaseLLM = class {
|
|
|
4163
3779
|
};
|
|
4164
3780
|
} catch (error) {
|
|
4165
3781
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
4166
|
-
logger.error(`[${this.getProviderName()}] Error matching components
|
|
4167
|
-
|
|
4168
|
-
logCollector?.error(`Error matching components: ${errorMsg}`);
|
|
3782
|
+
logger.error(`[${this.getProviderName()}] Error matching components: ${errorMsg}`);
|
|
3783
|
+
logCollector?.error(`Failed to match components: ${errorMsg}`);
|
|
4169
3784
|
return {
|
|
4170
3785
|
components: [],
|
|
4171
|
-
selectedLayout: "MultiComponentContainer",
|
|
4172
3786
|
selectedLayoutId: "",
|
|
4173
3787
|
selectedLayoutComponent: null,
|
|
4174
|
-
layoutReasoning: "
|
|
3788
|
+
layoutReasoning: "Failed to match components due to parsing error",
|
|
4175
3789
|
actions: []
|
|
4176
3790
|
};
|
|
4177
3791
|
}
|
|
@@ -4438,7 +4052,7 @@ ${errorMsg}
|
|
|
4438
4052
|
container_componet = {
|
|
4439
4053
|
...selectedLayoutComponent,
|
|
4440
4054
|
id: `${selectedLayoutComponent.id}_${Date.now()}`,
|
|
4441
|
-
|
|
4055
|
+
// Make ID unique for each instance
|
|
4442
4056
|
props: {
|
|
4443
4057
|
...selectedLayoutComponent.props,
|
|
4444
4058
|
config: {
|
|
@@ -4807,7 +4421,7 @@ var GroqLLM = class extends BaseLLM {
|
|
|
4807
4421
|
var groqLLM = new GroqLLM();
|
|
4808
4422
|
|
|
4809
4423
|
// src/userResponse/anthropic.ts
|
|
4810
|
-
var import_dotenv2 = __toESM(
|
|
4424
|
+
var import_dotenv2 = __toESM(require("dotenv"));
|
|
4811
4425
|
import_dotenv2.default.config();
|
|
4812
4426
|
var AnthropicLLM = class extends BaseLLM {
|
|
4813
4427
|
constructor(config) {
|
|
@@ -4826,7 +4440,7 @@ var AnthropicLLM = class extends BaseLLM {
|
|
|
4826
4440
|
var anthropicLLM = new AnthropicLLM();
|
|
4827
4441
|
|
|
4828
4442
|
// src/userResponse/index.ts
|
|
4829
|
-
var import_dotenv3 = __toESM(
|
|
4443
|
+
var import_dotenv3 = __toESM(require("dotenv"));
|
|
4830
4444
|
import_dotenv3.default.config();
|
|
4831
4445
|
function getLLMProviders() {
|
|
4832
4446
|
const envProviders = process.env.LLM_PROVIDERS;
|
|
@@ -7285,7 +6899,7 @@ var SuperatomSDK = class {
|
|
|
7285
6899
|
url.searchParams.set("projectId", this.projectId);
|
|
7286
6900
|
url.searchParams.set("userId", this.userId);
|
|
7287
6901
|
url.searchParams.set("type", this.type);
|
|
7288
|
-
logger.info(`Connecting to WebSocket: ${url.
|
|
6902
|
+
logger.info(`Connecting to WebSocket: ${url.toString()}`);
|
|
7289
6903
|
this.ws = createWebSocket(url.toString());
|
|
7290
6904
|
this.ws.addEventListener("open", () => {
|
|
7291
6905
|
this.connected = true;
|