@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.mjs
CHANGED
|
@@ -1,439 +1,12 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
1
|
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
2
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
8
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
9
|
-
}) : x)(function(x) {
|
|
10
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
11
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
12
|
-
});
|
|
13
3
|
var __esm = (fn, res) => function __init() {
|
|
14
4
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
15
5
|
};
|
|
16
|
-
var __commonJS = (cb, mod) => function __require2() {
|
|
17
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
18
|
-
};
|
|
19
6
|
var __export = (target, all) => {
|
|
20
7
|
for (var name in all)
|
|
21
8
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
22
9
|
};
|
|
23
|
-
var __copyProps = (to, from, except, desc) => {
|
|
24
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
25
|
-
for (let key of __getOwnPropNames(from))
|
|
26
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
27
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
28
|
-
}
|
|
29
|
-
return to;
|
|
30
|
-
};
|
|
31
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
32
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
33
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
34
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
35
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
36
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
37
|
-
mod
|
|
38
|
-
));
|
|
39
|
-
|
|
40
|
-
// node_modules/dotenv/package.json
|
|
41
|
-
var require_package = __commonJS({
|
|
42
|
-
"node_modules/dotenv/package.json"(exports, module) {
|
|
43
|
-
module.exports = {
|
|
44
|
-
name: "dotenv",
|
|
45
|
-
version: "17.2.3",
|
|
46
|
-
description: "Loads environment variables from .env file",
|
|
47
|
-
main: "lib/main.js",
|
|
48
|
-
types: "lib/main.d.ts",
|
|
49
|
-
exports: {
|
|
50
|
-
".": {
|
|
51
|
-
types: "./lib/main.d.ts",
|
|
52
|
-
require: "./lib/main.js",
|
|
53
|
-
default: "./lib/main.js"
|
|
54
|
-
},
|
|
55
|
-
"./config": "./config.js",
|
|
56
|
-
"./config.js": "./config.js",
|
|
57
|
-
"./lib/env-options": "./lib/env-options.js",
|
|
58
|
-
"./lib/env-options.js": "./lib/env-options.js",
|
|
59
|
-
"./lib/cli-options": "./lib/cli-options.js",
|
|
60
|
-
"./lib/cli-options.js": "./lib/cli-options.js",
|
|
61
|
-
"./package.json": "./package.json"
|
|
62
|
-
},
|
|
63
|
-
scripts: {
|
|
64
|
-
"dts-check": "tsc --project tests/types/tsconfig.json",
|
|
65
|
-
lint: "standard",
|
|
66
|
-
pretest: "npm run lint && npm run dts-check",
|
|
67
|
-
test: "tap run tests/**/*.js --allow-empty-coverage --disable-coverage --timeout=60000",
|
|
68
|
-
"test:coverage": "tap run tests/**/*.js --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov",
|
|
69
|
-
prerelease: "npm test",
|
|
70
|
-
release: "standard-version"
|
|
71
|
-
},
|
|
72
|
-
repository: {
|
|
73
|
-
type: "git",
|
|
74
|
-
url: "git://github.com/motdotla/dotenv.git"
|
|
75
|
-
},
|
|
76
|
-
homepage: "https://github.com/motdotla/dotenv#readme",
|
|
77
|
-
funding: "https://dotenvx.com",
|
|
78
|
-
keywords: [
|
|
79
|
-
"dotenv",
|
|
80
|
-
"env",
|
|
81
|
-
".env",
|
|
82
|
-
"environment",
|
|
83
|
-
"variables",
|
|
84
|
-
"config",
|
|
85
|
-
"settings"
|
|
86
|
-
],
|
|
87
|
-
readmeFilename: "README.md",
|
|
88
|
-
license: "BSD-2-Clause",
|
|
89
|
-
devDependencies: {
|
|
90
|
-
"@types/node": "^18.11.3",
|
|
91
|
-
decache: "^4.6.2",
|
|
92
|
-
sinon: "^14.0.1",
|
|
93
|
-
standard: "^17.0.0",
|
|
94
|
-
"standard-version": "^9.5.0",
|
|
95
|
-
tap: "^19.2.0",
|
|
96
|
-
typescript: "^4.8.4"
|
|
97
|
-
},
|
|
98
|
-
engines: {
|
|
99
|
-
node: ">=12"
|
|
100
|
-
},
|
|
101
|
-
browser: {
|
|
102
|
-
fs: false
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
// node_modules/dotenv/lib/main.js
|
|
109
|
-
var require_main = __commonJS({
|
|
110
|
-
"node_modules/dotenv/lib/main.js"(exports, module) {
|
|
111
|
-
"use strict";
|
|
112
|
-
var fs8 = __require("fs");
|
|
113
|
-
var path7 = __require("path");
|
|
114
|
-
var os4 = __require("os");
|
|
115
|
-
var crypto2 = __require("crypto");
|
|
116
|
-
var packageJson = require_package();
|
|
117
|
-
var version = packageJson.version;
|
|
118
|
-
var TIPS = [
|
|
119
|
-
"\u{1F510} encrypt with Dotenvx: https://dotenvx.com",
|
|
120
|
-
"\u{1F510} prevent committing .env to code: https://dotenvx.com/precommit",
|
|
121
|
-
"\u{1F510} prevent building .env in docker: https://dotenvx.com/prebuild",
|
|
122
|
-
"\u{1F4E1} add observability to secrets: https://dotenvx.com/ops",
|
|
123
|
-
"\u{1F465} sync secrets across teammates & machines: https://dotenvx.com/ops",
|
|
124
|
-
"\u{1F5C2}\uFE0F backup and recover secrets: https://dotenvx.com/ops",
|
|
125
|
-
"\u2705 audit secrets and track compliance: https://dotenvx.com/ops",
|
|
126
|
-
"\u{1F504} add secrets lifecycle management: https://dotenvx.com/ops",
|
|
127
|
-
"\u{1F511} add access controls to secrets: https://dotenvx.com/ops",
|
|
128
|
-
"\u{1F6E0}\uFE0F run anywhere with `dotenvx run -- yourcommand`",
|
|
129
|
-
"\u2699\uFE0F specify custom .env file path with { path: '/custom/path/.env' }",
|
|
130
|
-
"\u2699\uFE0F enable debug logging with { debug: true }",
|
|
131
|
-
"\u2699\uFE0F override existing env vars with { override: true }",
|
|
132
|
-
"\u2699\uFE0F suppress all logs with { quiet: true }",
|
|
133
|
-
"\u2699\uFE0F write to custom object with { processEnv: myObject }",
|
|
134
|
-
"\u2699\uFE0F load multiple .env files with { path: ['.env.local', '.env'] }"
|
|
135
|
-
];
|
|
136
|
-
function _getRandomTip() {
|
|
137
|
-
return TIPS[Math.floor(Math.random() * TIPS.length)];
|
|
138
|
-
}
|
|
139
|
-
function parseBoolean(value) {
|
|
140
|
-
if (typeof value === "string") {
|
|
141
|
-
return !["false", "0", "no", "off", ""].includes(value.toLowerCase());
|
|
142
|
-
}
|
|
143
|
-
return Boolean(value);
|
|
144
|
-
}
|
|
145
|
-
function supportsAnsi() {
|
|
146
|
-
return process.stdout.isTTY;
|
|
147
|
-
}
|
|
148
|
-
function dim(text) {
|
|
149
|
-
return supportsAnsi() ? `\x1B[2m${text}\x1B[0m` : text;
|
|
150
|
-
}
|
|
151
|
-
var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
|
|
152
|
-
function parse(src) {
|
|
153
|
-
const obj = {};
|
|
154
|
-
let lines = src.toString();
|
|
155
|
-
lines = lines.replace(/\r\n?/mg, "\n");
|
|
156
|
-
let match;
|
|
157
|
-
while ((match = LINE.exec(lines)) != null) {
|
|
158
|
-
const key = match[1];
|
|
159
|
-
let value = match[2] || "";
|
|
160
|
-
value = value.trim();
|
|
161
|
-
const maybeQuote = value[0];
|
|
162
|
-
value = value.replace(/^(['"`])([\s\S]*)\1$/mg, "$2");
|
|
163
|
-
if (maybeQuote === '"') {
|
|
164
|
-
value = value.replace(/\\n/g, "\n");
|
|
165
|
-
value = value.replace(/\\r/g, "\r");
|
|
166
|
-
}
|
|
167
|
-
obj[key] = value;
|
|
168
|
-
}
|
|
169
|
-
return obj;
|
|
170
|
-
}
|
|
171
|
-
function _parseVault(options) {
|
|
172
|
-
options = options || {};
|
|
173
|
-
const vaultPath = _vaultPath(options);
|
|
174
|
-
options.path = vaultPath;
|
|
175
|
-
const result = DotenvModule.configDotenv(options);
|
|
176
|
-
if (!result.parsed) {
|
|
177
|
-
const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`);
|
|
178
|
-
err.code = "MISSING_DATA";
|
|
179
|
-
throw err;
|
|
180
|
-
}
|
|
181
|
-
const keys = _dotenvKey(options).split(",");
|
|
182
|
-
const length = keys.length;
|
|
183
|
-
let decrypted;
|
|
184
|
-
for (let i = 0; i < length; i++) {
|
|
185
|
-
try {
|
|
186
|
-
const key = keys[i].trim();
|
|
187
|
-
const attrs = _instructions(result, key);
|
|
188
|
-
decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key);
|
|
189
|
-
break;
|
|
190
|
-
} catch (error) {
|
|
191
|
-
if (i + 1 >= length) {
|
|
192
|
-
throw error;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
return DotenvModule.parse(decrypted);
|
|
197
|
-
}
|
|
198
|
-
function _warn(message) {
|
|
199
|
-
console.error(`[dotenv@${version}][WARN] ${message}`);
|
|
200
|
-
}
|
|
201
|
-
function _debug(message) {
|
|
202
|
-
console.log(`[dotenv@${version}][DEBUG] ${message}`);
|
|
203
|
-
}
|
|
204
|
-
function _log(message) {
|
|
205
|
-
console.log(`[dotenv@${version}] ${message}`);
|
|
206
|
-
}
|
|
207
|
-
function _dotenvKey(options) {
|
|
208
|
-
if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {
|
|
209
|
-
return options.DOTENV_KEY;
|
|
210
|
-
}
|
|
211
|
-
if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {
|
|
212
|
-
return process.env.DOTENV_KEY;
|
|
213
|
-
}
|
|
214
|
-
return "";
|
|
215
|
-
}
|
|
216
|
-
function _instructions(result, dotenvKey) {
|
|
217
|
-
let uri;
|
|
218
|
-
try {
|
|
219
|
-
uri = new URL(dotenvKey);
|
|
220
|
-
} catch (error) {
|
|
221
|
-
if (error.code === "ERR_INVALID_URL") {
|
|
222
|
-
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");
|
|
223
|
-
err.code = "INVALID_DOTENV_KEY";
|
|
224
|
-
throw err;
|
|
225
|
-
}
|
|
226
|
-
throw error;
|
|
227
|
-
}
|
|
228
|
-
const key = uri.password;
|
|
229
|
-
if (!key) {
|
|
230
|
-
const err = new Error("INVALID_DOTENV_KEY: Missing key part");
|
|
231
|
-
err.code = "INVALID_DOTENV_KEY";
|
|
232
|
-
throw err;
|
|
233
|
-
}
|
|
234
|
-
const environment = uri.searchParams.get("environment");
|
|
235
|
-
if (!environment) {
|
|
236
|
-
const err = new Error("INVALID_DOTENV_KEY: Missing environment part");
|
|
237
|
-
err.code = "INVALID_DOTENV_KEY";
|
|
238
|
-
throw err;
|
|
239
|
-
}
|
|
240
|
-
const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`;
|
|
241
|
-
const ciphertext = result.parsed[environmentKey];
|
|
242
|
-
if (!ciphertext) {
|
|
243
|
-
const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`);
|
|
244
|
-
err.code = "NOT_FOUND_DOTENV_ENVIRONMENT";
|
|
245
|
-
throw err;
|
|
246
|
-
}
|
|
247
|
-
return { ciphertext, key };
|
|
248
|
-
}
|
|
249
|
-
function _vaultPath(options) {
|
|
250
|
-
let possibleVaultPath = null;
|
|
251
|
-
if (options && options.path && options.path.length > 0) {
|
|
252
|
-
if (Array.isArray(options.path)) {
|
|
253
|
-
for (const filepath of options.path) {
|
|
254
|
-
if (fs8.existsSync(filepath)) {
|
|
255
|
-
possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
} else {
|
|
259
|
-
possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
|
|
260
|
-
}
|
|
261
|
-
} else {
|
|
262
|
-
possibleVaultPath = path7.resolve(process.cwd(), ".env.vault");
|
|
263
|
-
}
|
|
264
|
-
if (fs8.existsSync(possibleVaultPath)) {
|
|
265
|
-
return possibleVaultPath;
|
|
266
|
-
}
|
|
267
|
-
return null;
|
|
268
|
-
}
|
|
269
|
-
function _resolveHome(envPath) {
|
|
270
|
-
return envPath[0] === "~" ? path7.join(os4.homedir(), envPath.slice(1)) : envPath;
|
|
271
|
-
}
|
|
272
|
-
function _configVault(options) {
|
|
273
|
-
const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || options && options.debug);
|
|
274
|
-
const quiet = parseBoolean(process.env.DOTENV_CONFIG_QUIET || options && options.quiet);
|
|
275
|
-
if (debug || !quiet) {
|
|
276
|
-
_log("Loading env from encrypted .env.vault");
|
|
277
|
-
}
|
|
278
|
-
const parsed = DotenvModule._parseVault(options);
|
|
279
|
-
let processEnv = process.env;
|
|
280
|
-
if (options && options.processEnv != null) {
|
|
281
|
-
processEnv = options.processEnv;
|
|
282
|
-
}
|
|
283
|
-
DotenvModule.populate(processEnv, parsed, options);
|
|
284
|
-
return { parsed };
|
|
285
|
-
}
|
|
286
|
-
function configDotenv(options) {
|
|
287
|
-
const dotenvPath = path7.resolve(process.cwd(), ".env");
|
|
288
|
-
let encoding = "utf8";
|
|
289
|
-
let processEnv = process.env;
|
|
290
|
-
if (options && options.processEnv != null) {
|
|
291
|
-
processEnv = options.processEnv;
|
|
292
|
-
}
|
|
293
|
-
let debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || options && options.debug);
|
|
294
|
-
let quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || options && options.quiet);
|
|
295
|
-
if (options && options.encoding) {
|
|
296
|
-
encoding = options.encoding;
|
|
297
|
-
} else {
|
|
298
|
-
if (debug) {
|
|
299
|
-
_debug("No encoding is specified. UTF-8 is used by default");
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
let optionPaths = [dotenvPath];
|
|
303
|
-
if (options && options.path) {
|
|
304
|
-
if (!Array.isArray(options.path)) {
|
|
305
|
-
optionPaths = [_resolveHome(options.path)];
|
|
306
|
-
} else {
|
|
307
|
-
optionPaths = [];
|
|
308
|
-
for (const filepath of options.path) {
|
|
309
|
-
optionPaths.push(_resolveHome(filepath));
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
let lastError;
|
|
314
|
-
const parsedAll = {};
|
|
315
|
-
for (const path8 of optionPaths) {
|
|
316
|
-
try {
|
|
317
|
-
const parsed = DotenvModule.parse(fs8.readFileSync(path8, { encoding }));
|
|
318
|
-
DotenvModule.populate(parsedAll, parsed, options);
|
|
319
|
-
} catch (e) {
|
|
320
|
-
if (debug) {
|
|
321
|
-
_debug(`Failed to load ${path8} ${e.message}`);
|
|
322
|
-
}
|
|
323
|
-
lastError = e;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
const populated = DotenvModule.populate(processEnv, parsedAll, options);
|
|
327
|
-
debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || debug);
|
|
328
|
-
quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || quiet);
|
|
329
|
-
if (debug || !quiet) {
|
|
330
|
-
const keysCount = Object.keys(populated).length;
|
|
331
|
-
const shortPaths = [];
|
|
332
|
-
for (const filePath of optionPaths) {
|
|
333
|
-
try {
|
|
334
|
-
const relative = path7.relative(process.cwd(), filePath);
|
|
335
|
-
shortPaths.push(relative);
|
|
336
|
-
} catch (e) {
|
|
337
|
-
if (debug) {
|
|
338
|
-
_debug(`Failed to load ${filePath} ${e.message}`);
|
|
339
|
-
}
|
|
340
|
-
lastError = e;
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
_log(`injecting env (${keysCount}) from ${shortPaths.join(",")} ${dim(`-- tip: ${_getRandomTip()}`)}`);
|
|
344
|
-
}
|
|
345
|
-
if (lastError) {
|
|
346
|
-
return { parsed: parsedAll, error: lastError };
|
|
347
|
-
} else {
|
|
348
|
-
return { parsed: parsedAll };
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
function config(options) {
|
|
352
|
-
if (_dotenvKey(options).length === 0) {
|
|
353
|
-
return DotenvModule.configDotenv(options);
|
|
354
|
-
}
|
|
355
|
-
const vaultPath = _vaultPath(options);
|
|
356
|
-
if (!vaultPath) {
|
|
357
|
-
_warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`);
|
|
358
|
-
return DotenvModule.configDotenv(options);
|
|
359
|
-
}
|
|
360
|
-
return DotenvModule._configVault(options);
|
|
361
|
-
}
|
|
362
|
-
function decrypt(encrypted, keyStr) {
|
|
363
|
-
const key = Buffer.from(keyStr.slice(-64), "hex");
|
|
364
|
-
let ciphertext = Buffer.from(encrypted, "base64");
|
|
365
|
-
const nonce = ciphertext.subarray(0, 12);
|
|
366
|
-
const authTag = ciphertext.subarray(-16);
|
|
367
|
-
ciphertext = ciphertext.subarray(12, -16);
|
|
368
|
-
try {
|
|
369
|
-
const aesgcm = crypto2.createDecipheriv("aes-256-gcm", key, nonce);
|
|
370
|
-
aesgcm.setAuthTag(authTag);
|
|
371
|
-
return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
|
|
372
|
-
} catch (error) {
|
|
373
|
-
const isRange = error instanceof RangeError;
|
|
374
|
-
const invalidKeyLength = error.message === "Invalid key length";
|
|
375
|
-
const decryptionFailed = error.message === "Unsupported state or unable to authenticate data";
|
|
376
|
-
if (isRange || invalidKeyLength) {
|
|
377
|
-
const err = new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");
|
|
378
|
-
err.code = "INVALID_DOTENV_KEY";
|
|
379
|
-
throw err;
|
|
380
|
-
} else if (decryptionFailed) {
|
|
381
|
-
const err = new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");
|
|
382
|
-
err.code = "DECRYPTION_FAILED";
|
|
383
|
-
throw err;
|
|
384
|
-
} else {
|
|
385
|
-
throw error;
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
function populate(processEnv, parsed, options = {}) {
|
|
390
|
-
const debug = Boolean(options && options.debug);
|
|
391
|
-
const override = Boolean(options && options.override);
|
|
392
|
-
const populated = {};
|
|
393
|
-
if (typeof parsed !== "object") {
|
|
394
|
-
const err = new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
|
|
395
|
-
err.code = "OBJECT_REQUIRED";
|
|
396
|
-
throw err;
|
|
397
|
-
}
|
|
398
|
-
for (const key of Object.keys(parsed)) {
|
|
399
|
-
if (Object.prototype.hasOwnProperty.call(processEnv, key)) {
|
|
400
|
-
if (override === true) {
|
|
401
|
-
processEnv[key] = parsed[key];
|
|
402
|
-
populated[key] = parsed[key];
|
|
403
|
-
}
|
|
404
|
-
if (debug) {
|
|
405
|
-
if (override === true) {
|
|
406
|
-
_debug(`"${key}" is already defined and WAS overwritten`);
|
|
407
|
-
} else {
|
|
408
|
-
_debug(`"${key}" is already defined and was NOT overwritten`);
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
} else {
|
|
412
|
-
processEnv[key] = parsed[key];
|
|
413
|
-
populated[key] = parsed[key];
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
return populated;
|
|
417
|
-
}
|
|
418
|
-
var DotenvModule = {
|
|
419
|
-
configDotenv,
|
|
420
|
-
_configVault,
|
|
421
|
-
_parseVault,
|
|
422
|
-
config,
|
|
423
|
-
decrypt,
|
|
424
|
-
parse,
|
|
425
|
-
populate
|
|
426
|
-
};
|
|
427
|
-
module.exports.configDotenv = DotenvModule.configDotenv;
|
|
428
|
-
module.exports._configVault = DotenvModule._configVault;
|
|
429
|
-
module.exports._parseVault = DotenvModule._parseVault;
|
|
430
|
-
module.exports.config = DotenvModule.config;
|
|
431
|
-
module.exports.decrypt = DotenvModule.decrypt;
|
|
432
|
-
module.exports.parse = DotenvModule.parse;
|
|
433
|
-
module.exports.populate = DotenvModule.populate;
|
|
434
|
-
module.exports = DotenvModule;
|
|
435
|
-
}
|
|
436
|
-
});
|
|
437
10
|
|
|
438
11
|
// src/userResponse/utils.ts
|
|
439
12
|
var utils_exports = {};
|
|
@@ -847,7 +420,7 @@ var UserPromptSuggestionsMessageSchema = z3.object({
|
|
|
847
420
|
payload: UserPromptSuggestionsPayloadSchema
|
|
848
421
|
});
|
|
849
422
|
var ComponentPropsSchema = z3.object({
|
|
850
|
-
query: z3.string().optional(),
|
|
423
|
+
query: z3.string().or(z3.object({})).optional(),
|
|
851
424
|
title: z3.string().optional(),
|
|
852
425
|
description: z3.string().optional(),
|
|
853
426
|
config: z3.record(z3.unknown()).optional(),
|
|
@@ -2046,7 +1619,7 @@ function sendDataResponse3(id, res, sendMessage, clientId) {
|
|
|
2046
1619
|
}
|
|
2047
1620
|
|
|
2048
1621
|
// src/userResponse/groq.ts
|
|
2049
|
-
|
|
1622
|
+
import dotenv from "dotenv";
|
|
2050
1623
|
|
|
2051
1624
|
// src/userResponse/base-llm.ts
|
|
2052
1625
|
init_utils();
|
|
@@ -2674,6 +2247,7 @@ When the user asks about data
|
|
|
2674
2247
|
|
|
2675
2248
|
After analyzing the query results, you MUST suggest appropriate dashboard components for displaying the data. Use this format:
|
|
2676
2249
|
|
|
2250
|
+
<DashboardComponents>
|
|
2677
2251
|
**Dashboard Components:**
|
|
2678
2252
|
Format: \`{number}.{component_type} : {clear reasoning}\`
|
|
2679
2253
|
|
|
@@ -2682,9 +2256,9 @@ Format: \`{number}.{component_type} : {clear reasoning}\`
|
|
|
2682
2256
|
1. Analyze the query results structure and data type
|
|
2683
2257
|
2. Suggest components that would best visualize the data
|
|
2684
2258
|
3. Each component suggestion must be on a new line
|
|
2259
|
+
</DashboardComponents>
|
|
2685
2260
|
|
|
2686
|
-
|
|
2687
|
-
IMPORTANT: Always include the **Dashboard Components:** section with at least one component suggestion when data is returned.
|
|
2261
|
+
IMPORTANT: Always wrap component suggestions with <DashboardComponents> tags and include at least one component suggestion when data is returned.
|
|
2688
2262
|
|
|
2689
2263
|
## Output Format
|
|
2690
2264
|
|
|
@@ -2692,7 +2266,7 @@ Respond with plain text that includes:
|
|
|
2692
2266
|
|
|
2693
2267
|
1. **Query Analysis** (if applicable): Brief explanation of what data was fetched
|
|
2694
2268
|
2. **Results Summary**: Present the data in a clear, readable format
|
|
2695
|
-
3. **Dashboard Components**: List suggested components in
|
|
2269
|
+
3. **Dashboard Components**: List suggested components wrapped in <DashboardComponents> tags
|
|
2696
2270
|
|
|
2697
2271
|
|
|
2698
2272
|
**CRITICAL:**
|
|
@@ -2769,39 +2343,22 @@ You will receive a text response containing:
|
|
|
2769
2343
|
3. **Dashboard Components:** suggestions (1:component_type : reasoning format)
|
|
2770
2344
|
|
|
2771
2345
|
Your job is to:
|
|
2772
|
-
1. **
|
|
2773
|
-
2.
|
|
2774
|
-
3.
|
|
2775
|
-
4.
|
|
2776
|
-
5. Generate
|
|
2777
|
-
6. **Generate intelligent follow-up questions (actions)** that the user might naturally ask next based on the data analysis
|
|
2346
|
+
1. **Parse the component suggestions** from the text response (format: 1:component_type : reasoning)
|
|
2347
|
+
2. **Match each suggestion with an actual component** from the available list
|
|
2348
|
+
3. **Generate proper props** for each matched component to **visualize the analysis results** that were already fetched
|
|
2349
|
+
4. **SELECT the best dashboard layout component** that can accommodate all the matched components
|
|
2350
|
+
5. **Generate intelligent follow-up questions (actions)** that the user might naturally ask next based on the data analysis
|
|
2778
2351
|
|
|
2779
2352
|
**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.
|
|
2780
2353
|
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
## Layout Component Discovery
|
|
2784
|
-
**Find layout components** by looking for components with \`type: "DashboardLayout"\`
|
|
2785
|
-
|
|
2786
|
-
## Layout Selection Logic
|
|
2787
|
-
1. **Read each layout's description** to understand:
|
|
2788
|
-
- What structure it provides
|
|
2789
|
-
- When it's best used (e.g., comprehensive analysis vs focused analysis)
|
|
2790
|
-
- The exact number and types of components it requires
|
|
2791
|
-
2. **Select the best layout** based on:
|
|
2792
|
-
- Which layout structure best fits the analysis needs
|
|
2793
|
-
- The component suggestions from the text response
|
|
2794
|
-
- The user question and data complexity
|
|
2795
|
-
3. **Generate EXACTLY the components specified** in the selected layout's description
|
|
2796
|
-
|
|
2797
|
-
**IMPORTANT:** Always prefer structured dashboard layouts when available. The layout component's description will tell you exactly what components to generate.
|
|
2354
|
+
**APPROACH**: First match all the components suggested in the text response, THEN find the layout that best fits those components.
|
|
2798
2355
|
|
|
2799
2356
|
## Available Components
|
|
2800
2357
|
|
|
2801
2358
|
{{AVAILABLE_COMPONENTS}}
|
|
2802
2359
|
|
|
2803
|
-
## Component Matching Rules
|
|
2804
|
-
For each component suggestion (c1, c2, c3, etc.):
|
|
2360
|
+
## Component Matching Rules (STEP 1)
|
|
2361
|
+
For each component suggestion (c1, c2, c3, etc.) from the text response:
|
|
2805
2362
|
|
|
2806
2363
|
1. **Match by type**: Find components whose \`type\` matches the suggested component type
|
|
2807
2364
|
2. **Refine by relevance**: If multiple components match, choose based on:
|
|
@@ -2809,6 +2366,24 @@ For each component suggestion (c1, c2, c3, etc.):
|
|
|
2809
2366
|
- Best fit for the data being visualized
|
|
2810
2367
|
3. **Fallback**: If no exact type match, find the closest alternative
|
|
2811
2368
|
|
|
2369
|
+
## Layout Selection Logic (STEP 2 - After Matching Components)
|
|
2370
|
+
|
|
2371
|
+
**After you have matched all components**, select the best dashboard layout:
|
|
2372
|
+
|
|
2373
|
+
1. **Find layout components** by looking for components with \`type: "DashboardLayout"\` in the available components list
|
|
2374
|
+
2. **Read each layout's description** to understand:
|
|
2375
|
+
- What structure it provides
|
|
2376
|
+
- When it's best used (e.g., comprehensive analysis vs focused analysis)
|
|
2377
|
+
- The number and types of components it can accommodate
|
|
2378
|
+
3. **Select the best layout** based on:
|
|
2379
|
+
- Which layout can best display ALL the matched components
|
|
2380
|
+
- The layout's capacity (how many components it supports)
|
|
2381
|
+
- The types of matched components (KPI, charts, tables, etc.)
|
|
2382
|
+
- The user question and data complexity
|
|
2383
|
+
4. **If no specific layout fits**, fall back to "MultiComponentContainer" as the default layout
|
|
2384
|
+
|
|
2385
|
+
**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.
|
|
2386
|
+
|
|
2812
2387
|
## Props Generation Rules
|
|
2813
2388
|
|
|
2814
2389
|
For each matched component, generate complete props:
|
|
@@ -2921,7 +2496,6 @@ You MUST respond with ONLY a valid JSON object (no markdown, no code blocks):
|
|
|
2921
2496
|
|
|
2922
2497
|
\`\`\`json
|
|
2923
2498
|
{
|
|
2924
|
-
"selectedLayout": "Name of the selected layout component from available components",
|
|
2925
2499
|
"selectedLayoutId": "id_of_the_selected_layout_component",
|
|
2926
2500
|
"layoutReasoning": "Why this layout was selected based on its description and the analysis needs",
|
|
2927
2501
|
"matchedComponents": [
|
|
@@ -2953,13 +2527,14 @@ You MUST respond with ONLY a valid JSON object (no markdown, no code blocks):
|
|
|
2953
2527
|
\`\`\`
|
|
2954
2528
|
|
|
2955
2529
|
**CRITICAL:**
|
|
2956
|
-
- \`
|
|
2957
|
-
- \`selectedLayoutId\` MUST be the ID of the selected layout component
|
|
2530
|
+
- \`matchedComponents\` MUST include ALL components suggested in the text response (match them first!)
|
|
2531
|
+
- \`selectedLayoutId\` MUST be the ID of the selected layout component (must have type "DashboardLayout")
|
|
2958
2532
|
- \`layoutReasoning\` MUST explain:
|
|
2959
2533
|
- Why you chose this specific layout component
|
|
2960
|
-
- How
|
|
2961
|
-
-
|
|
2962
|
-
-
|
|
2534
|
+
- How many components you matched (e.g., "Matched 3 components: 1 KPI, 1 chart, 1 table")
|
|
2535
|
+
- Why this layout is the best fit for displaying these specific matched components
|
|
2536
|
+
- What makes this layout appropriate for the component types and count
|
|
2537
|
+
- The layout selection happens AFTER component matching - don't force components to fit a pre-selected layout
|
|
2963
2538
|
- \`actions\` MUST be an array of 4-5 intelligent follow-up questions based on the analysis
|
|
2964
2539
|
- Return ONLY valid JSON (no markdown code blocks, no text before/after)
|
|
2965
2540
|
- Generate complete props for each component
|
|
@@ -3155,6 +2730,7 @@ var promptLoader = new PromptLoader({
|
|
|
3155
2730
|
// src/llm.ts
|
|
3156
2731
|
import Anthropic from "@anthropic-ai/sdk";
|
|
3157
2732
|
import Groq from "groq-sdk";
|
|
2733
|
+
import { jsonrepair } from "jsonrepair";
|
|
3158
2734
|
var LLM = class {
|
|
3159
2735
|
/* Get a complete text response from an LLM (Anthropic or Groq) */
|
|
3160
2736
|
static async text(messages, options = {}) {
|
|
@@ -3276,65 +2852,110 @@ var LLM = class {
|
|
|
3276
2852
|
let finalText = "";
|
|
3277
2853
|
while (iterations < maxIterations) {
|
|
3278
2854
|
iterations++;
|
|
3279
|
-
const
|
|
2855
|
+
const stream = await client.messages.create({
|
|
3280
2856
|
model: modelName,
|
|
3281
2857
|
max_tokens: options.maxTokens || 4e3,
|
|
3282
2858
|
temperature: options.temperature,
|
|
3283
2859
|
system: messages.sys,
|
|
3284
2860
|
messages: conversationMessages,
|
|
3285
|
-
tools
|
|
2861
|
+
tools,
|
|
2862
|
+
stream: true
|
|
2863
|
+
// Enable streaming
|
|
3286
2864
|
});
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
2865
|
+
let stopReason = null;
|
|
2866
|
+
const contentBlocks = [];
|
|
2867
|
+
let currentTextBlock = "";
|
|
2868
|
+
let currentToolUse = null;
|
|
2869
|
+
for await (const chunk of stream) {
|
|
2870
|
+
if (chunk.type === "message_start") {
|
|
2871
|
+
contentBlocks.length = 0;
|
|
2872
|
+
currentTextBlock = "";
|
|
2873
|
+
currentToolUse = null;
|
|
2874
|
+
}
|
|
2875
|
+
if (chunk.type === "content_block_start") {
|
|
2876
|
+
if (chunk.content_block.type === "text") {
|
|
2877
|
+
currentTextBlock = "";
|
|
2878
|
+
} else if (chunk.content_block.type === "tool_use") {
|
|
2879
|
+
currentToolUse = {
|
|
2880
|
+
type: "tool_use",
|
|
2881
|
+
id: chunk.content_block.id,
|
|
2882
|
+
name: chunk.content_block.name,
|
|
2883
|
+
input: {}
|
|
2884
|
+
};
|
|
2885
|
+
}
|
|
2886
|
+
}
|
|
2887
|
+
if (chunk.type === "content_block_delta") {
|
|
2888
|
+
if (chunk.delta.type === "text_delta") {
|
|
2889
|
+
const text = chunk.delta.text;
|
|
2890
|
+
currentTextBlock += text;
|
|
2891
|
+
if (options.partial) {
|
|
2892
|
+
options.partial(text);
|
|
2893
|
+
}
|
|
2894
|
+
} else if (chunk.delta.type === "input_json_delta" && currentToolUse) {
|
|
2895
|
+
currentToolUse.inputJson = (currentToolUse.inputJson || "") + chunk.delta.partial_json;
|
|
2896
|
+
}
|
|
2897
|
+
}
|
|
2898
|
+
if (chunk.type === "content_block_stop") {
|
|
2899
|
+
if (currentTextBlock) {
|
|
2900
|
+
contentBlocks.push({
|
|
2901
|
+
type: "text",
|
|
2902
|
+
text: currentTextBlock
|
|
2903
|
+
});
|
|
2904
|
+
finalText = currentTextBlock;
|
|
2905
|
+
currentTextBlock = "";
|
|
2906
|
+
} else if (currentToolUse) {
|
|
2907
|
+
try {
|
|
2908
|
+
currentToolUse.input = currentToolUse.inputJson ? JSON.parse(currentToolUse.inputJson) : {};
|
|
2909
|
+
} catch (error) {
|
|
2910
|
+
currentToolUse.input = {};
|
|
2911
|
+
}
|
|
2912
|
+
delete currentToolUse.inputJson;
|
|
2913
|
+
contentBlocks.push(currentToolUse);
|
|
2914
|
+
currentToolUse = null;
|
|
3293
2915
|
}
|
|
3294
2916
|
}
|
|
2917
|
+
if (chunk.type === "message_delta") {
|
|
2918
|
+
stopReason = chunk.delta.stop_reason || stopReason;
|
|
2919
|
+
}
|
|
2920
|
+
if (chunk.type === "message_stop") {
|
|
2921
|
+
break;
|
|
2922
|
+
}
|
|
2923
|
+
}
|
|
2924
|
+
if (stopReason === "end_turn") {
|
|
3295
2925
|
break;
|
|
3296
2926
|
}
|
|
3297
|
-
if (
|
|
3298
|
-
const toolUses =
|
|
2927
|
+
if (stopReason === "tool_use") {
|
|
2928
|
+
const toolUses = contentBlocks.filter((block) => block.type === "tool_use");
|
|
3299
2929
|
if (toolUses.length === 0) {
|
|
3300
2930
|
break;
|
|
3301
2931
|
}
|
|
3302
2932
|
conversationMessages.push({
|
|
3303
2933
|
role: "assistant",
|
|
3304
|
-
content:
|
|
2934
|
+
content: contentBlocks
|
|
3305
2935
|
});
|
|
3306
2936
|
const toolResults = {
|
|
3307
2937
|
role: "user",
|
|
3308
2938
|
content: []
|
|
3309
2939
|
};
|
|
3310
2940
|
for (const toolUse of toolUses) {
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
});
|
|
3326
|
-
}
|
|
2941
|
+
try {
|
|
2942
|
+
const result = await toolHandler(toolUse.name, toolUse.input);
|
|
2943
|
+
toolResults.content.push({
|
|
2944
|
+
type: "tool_result",
|
|
2945
|
+
tool_use_id: toolUse.id,
|
|
2946
|
+
content: typeof result === "string" ? result : JSON.stringify(result)
|
|
2947
|
+
});
|
|
2948
|
+
} catch (error) {
|
|
2949
|
+
toolResults.content.push({
|
|
2950
|
+
type: "tool_result",
|
|
2951
|
+
tool_use_id: toolUse.id,
|
|
2952
|
+
content: error instanceof Error ? error.message : String(error),
|
|
2953
|
+
is_error: true
|
|
2954
|
+
});
|
|
3327
2955
|
}
|
|
3328
2956
|
}
|
|
3329
2957
|
conversationMessages.push(toolResults);
|
|
3330
2958
|
} else {
|
|
3331
|
-
const textBlock = response.content.find((block) => block.type === "text");
|
|
3332
|
-
if (textBlock && textBlock.type === "text") {
|
|
3333
|
-
finalText = textBlock.text;
|
|
3334
|
-
if (options.partial) {
|
|
3335
|
-
options.partial(finalText);
|
|
3336
|
-
}
|
|
3337
|
-
}
|
|
3338
2959
|
break;
|
|
3339
2960
|
}
|
|
3340
2961
|
}
|
|
@@ -3397,9 +3018,9 @@ var LLM = class {
|
|
|
3397
3018
|
// ============================================================
|
|
3398
3019
|
/**
|
|
3399
3020
|
* Parse JSON string, handling markdown code blocks and surrounding text
|
|
3400
|
-
* Enhanced version from
|
|
3021
|
+
* Enhanced version with jsonrepair to handle malformed JSON from LLMs
|
|
3401
3022
|
* @param text - Text that may contain JSON wrapped in ```json...``` or with surrounding text
|
|
3402
|
-
* @returns Parsed JSON object
|
|
3023
|
+
* @returns Parsed JSON object or array
|
|
3403
3024
|
*/
|
|
3404
3025
|
static _parseJSON(text) {
|
|
3405
3026
|
let jsonText = text.trim();
|
|
@@ -3409,11 +3030,29 @@ var LLM = class {
|
|
|
3409
3030
|
jsonText = jsonText.replace(/^```\s*\n?/, "").replace(/\n?```\s*$/, "");
|
|
3410
3031
|
}
|
|
3411
3032
|
const firstBrace = jsonText.indexOf("{");
|
|
3033
|
+
const firstBracket = jsonText.indexOf("[");
|
|
3412
3034
|
const lastBrace = jsonText.lastIndexOf("}");
|
|
3413
|
-
|
|
3414
|
-
|
|
3035
|
+
const lastBracket = jsonText.lastIndexOf("]");
|
|
3036
|
+
let startIdx = -1;
|
|
3037
|
+
let endIdx = -1;
|
|
3038
|
+
if (firstBrace !== -1 && (firstBracket === -1 || firstBrace < firstBracket)) {
|
|
3039
|
+
startIdx = firstBrace;
|
|
3040
|
+
endIdx = lastBrace;
|
|
3041
|
+
} else if (firstBracket !== -1) {
|
|
3042
|
+
startIdx = firstBracket;
|
|
3043
|
+
endIdx = lastBracket;
|
|
3044
|
+
}
|
|
3045
|
+
if (startIdx !== -1 && endIdx !== -1 && startIdx < endIdx) {
|
|
3046
|
+
jsonText = jsonText.substring(startIdx, endIdx + 1);
|
|
3047
|
+
}
|
|
3048
|
+
try {
|
|
3049
|
+
const repairedJson = jsonrepair(jsonText);
|
|
3050
|
+
return JSON.parse(repairedJson);
|
|
3051
|
+
} catch (error) {
|
|
3052
|
+
throw new Error(`Failed to parse JSON: ${error instanceof Error ? error.message : String(error)}
|
|
3053
|
+
|
|
3054
|
+
Original text: ${jsonText.substring(0, 200)}...`);
|
|
3415
3055
|
}
|
|
3416
|
-
return JSON.parse(jsonText);
|
|
3417
3056
|
}
|
|
3418
3057
|
};
|
|
3419
3058
|
|
|
@@ -4026,7 +3665,7 @@ var BaseLLM = class {
|
|
|
4026
3665
|
logger.debug(`[${this.getProviderName()}] Loaded match-text-components prompts`);
|
|
4027
3666
|
logger.file("\n=============================\nmatch text components system prompt:", prompts.system);
|
|
4028
3667
|
logCollector?.info("Matching components from text response...");
|
|
4029
|
-
const
|
|
3668
|
+
const result = await LLM.stream(
|
|
4030
3669
|
{
|
|
4031
3670
|
sys: prompts.system,
|
|
4032
3671
|
user: prompts.user
|
|
@@ -4037,60 +3676,12 @@ var BaseLLM = class {
|
|
|
4037
3676
|
temperature: 0.2,
|
|
4038
3677
|
apiKey: this.getApiKey(apiKey)
|
|
4039
3678
|
},
|
|
4040
|
-
|
|
4041
|
-
//
|
|
3679
|
+
true
|
|
3680
|
+
// Parse as JSON
|
|
4042
3681
|
);
|
|
4043
|
-
logger.debug(`[${this.getProviderName()}]
|
|
4044
|
-
let result;
|
|
4045
|
-
try {
|
|
4046
|
-
let cleanedResponse = rawResponse || "";
|
|
4047
|
-
cleanedResponse = cleanedResponse.replace(/```json\n?/g, "").replace(/```\n?/g, "").trim();
|
|
4048
|
-
const jsonMatch = cleanedResponse.match(/\{[\s\S]*\}/);
|
|
4049
|
-
if (jsonMatch) {
|
|
4050
|
-
cleanedResponse = jsonMatch[0];
|
|
4051
|
-
}
|
|
4052
|
-
result = JSON.parse(cleanedResponse);
|
|
4053
|
-
} catch (parseError) {
|
|
4054
|
-
logger.error(`[${this.getProviderName()}] Failed to parse component matching JSON response`);
|
|
4055
|
-
const errorMsg = parseError instanceof Error ? parseError.message : String(parseError);
|
|
4056
|
-
const posMatch = errorMsg.match(/position (\d+)/);
|
|
4057
|
-
const errorPos = posMatch ? parseInt(posMatch[1]) : -1;
|
|
4058
|
-
if (errorPos > 0 && rawResponse) {
|
|
4059
|
-
const start = Math.max(0, errorPos - 200);
|
|
4060
|
-
const end = Math.min(rawResponse.length, errorPos + 200);
|
|
4061
|
-
logger.debug(`[${this.getProviderName()}] Error context (position ${errorPos}):`);
|
|
4062
|
-
logger.debug(rawResponse.substring(start, end));
|
|
4063
|
-
logger.debug(" ".repeat(Math.min(200, errorPos - start)) + "^--- Error here");
|
|
4064
|
-
}
|
|
4065
|
-
logger.debug(`[${this.getProviderName()}] Raw response (first 2000 chars):`, rawResponse?.substring(0, 2e3));
|
|
4066
|
-
logger.debug(`[${this.getProviderName()}] Parse error:`, parseError);
|
|
4067
|
-
logCollector?.error(`Failed to parse component matching response: ${errorMsg}`);
|
|
4068
|
-
try {
|
|
4069
|
-
logger.info(`[${this.getProviderName()}] Attempting aggressive JSON cleanup...`);
|
|
4070
|
-
let aggressive = rawResponse || "";
|
|
4071
|
-
aggressive = aggressive.replace(/```json\n?/g, "").replace(/```\n?/g, "").trim();
|
|
4072
|
-
const match = aggressive.match(/\{[\s\S]*\}/);
|
|
4073
|
-
if (match) {
|
|
4074
|
-
aggressive = match[0];
|
|
4075
|
-
}
|
|
4076
|
-
aggressive = aggressive.replace(/,(\s*[}\]])/g, "$1");
|
|
4077
|
-
result = JSON.parse(aggressive);
|
|
4078
|
-
logger.info(`[${this.getProviderName()}] Aggressive cleanup succeeded!`);
|
|
4079
|
-
} catch (secondError) {
|
|
4080
|
-
logger.error(`[${this.getProviderName()}] Aggressive cleanup also failed`);
|
|
4081
|
-
return {
|
|
4082
|
-
components: [],
|
|
4083
|
-
selectedLayout: "MultiComponentContainer",
|
|
4084
|
-
selectedLayoutId: "",
|
|
4085
|
-
selectedLayoutComponent: null,
|
|
4086
|
-
layoutReasoning: "No layout selected",
|
|
4087
|
-
actions: []
|
|
4088
|
-
};
|
|
4089
|
-
}
|
|
4090
|
-
}
|
|
3682
|
+
logger.debug(`[${this.getProviderName()}] Component matching response parsed successfully`);
|
|
4091
3683
|
const matchedComponents = result.matchedComponents || [];
|
|
4092
|
-
const
|
|
4093
|
-
const selectedLayoutId = result.selectedLayoutId || "";
|
|
3684
|
+
const selectedLayoutId = result.selectedLayoutId || "multi-component-container";
|
|
4094
3685
|
const layoutReasoning = result.layoutReasoning || "No layout reasoning provided";
|
|
4095
3686
|
const rawActions = result.actions || [];
|
|
4096
3687
|
const actions = convertQuestionsToActions(rawActions);
|
|
@@ -4102,11 +3693,11 @@ var BaseLLM = class {
|
|
|
4102
3693
|
}
|
|
4103
3694
|
}
|
|
4104
3695
|
logger.info(`[${this.getProviderName()}] Matched ${matchedComponents.length} components from text response`);
|
|
4105
|
-
logger.info(`[${this.getProviderName()}] Selected layout:
|
|
3696
|
+
logger.info(`[${this.getProviderName()}] Selected layout: (ID: ${selectedLayoutId})`);
|
|
4106
3697
|
logger.info(`[${this.getProviderName()}] Layout reasoning: ${layoutReasoning}`);
|
|
4107
3698
|
logger.info(`[${this.getProviderName()}] Generated ${actions.length} follow-up actions`);
|
|
4108
3699
|
if (matchedComponents.length > 0) {
|
|
4109
|
-
logCollector?.info(`Matched ${matchedComponents.length} components for visualization
|
|
3700
|
+
logCollector?.info(`Matched ${matchedComponents.length} components for visualization `);
|
|
4110
3701
|
logCollector?.info(`Layout reasoning: ${layoutReasoning}`);
|
|
4111
3702
|
matchedComponents.forEach((comp, idx) => {
|
|
4112
3703
|
logCollector?.info(` ${idx + 1}. ${comp.componentName} (${comp.componentType}): ${comp.reasoning}`);
|
|
@@ -4141,7 +3732,6 @@ var BaseLLM = class {
|
|
|
4141
3732
|
}).filter(Boolean);
|
|
4142
3733
|
return {
|
|
4143
3734
|
components: finalComponents,
|
|
4144
|
-
selectedLayout,
|
|
4145
3735
|
selectedLayoutId,
|
|
4146
3736
|
selectedLayoutComponent,
|
|
4147
3737
|
layoutReasoning,
|
|
@@ -4149,15 +3739,13 @@ var BaseLLM = class {
|
|
|
4149
3739
|
};
|
|
4150
3740
|
} catch (error) {
|
|
4151
3741
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
4152
|
-
logger.error(`[${this.getProviderName()}] Error matching components
|
|
4153
|
-
|
|
4154
|
-
logCollector?.error(`Error matching components: ${errorMsg}`);
|
|
3742
|
+
logger.error(`[${this.getProviderName()}] Error matching components: ${errorMsg}`);
|
|
3743
|
+
logCollector?.error(`Failed to match components: ${errorMsg}`);
|
|
4155
3744
|
return {
|
|
4156
3745
|
components: [],
|
|
4157
|
-
selectedLayout: "MultiComponentContainer",
|
|
4158
3746
|
selectedLayoutId: "",
|
|
4159
3747
|
selectedLayoutComponent: null,
|
|
4160
|
-
layoutReasoning: "
|
|
3748
|
+
layoutReasoning: "Failed to match components due to parsing error",
|
|
4161
3749
|
actions: []
|
|
4162
3750
|
};
|
|
4163
3751
|
}
|
|
@@ -4424,7 +4012,7 @@ ${errorMsg}
|
|
|
4424
4012
|
container_componet = {
|
|
4425
4013
|
...selectedLayoutComponent,
|
|
4426
4014
|
id: `${selectedLayoutComponent.id}_${Date.now()}`,
|
|
4427
|
-
|
|
4015
|
+
// Make ID unique for each instance
|
|
4428
4016
|
props: {
|
|
4429
4017
|
...selectedLayoutComponent.props,
|
|
4430
4018
|
config: {
|
|
@@ -4775,7 +4363,7 @@ ${errorMsg}
|
|
|
4775
4363
|
};
|
|
4776
4364
|
|
|
4777
4365
|
// src/userResponse/groq.ts
|
|
4778
|
-
|
|
4366
|
+
dotenv.config();
|
|
4779
4367
|
var GroqLLM = class extends BaseLLM {
|
|
4780
4368
|
constructor(config) {
|
|
4781
4369
|
super(config);
|
|
@@ -4793,8 +4381,8 @@ var GroqLLM = class extends BaseLLM {
|
|
|
4793
4381
|
var groqLLM = new GroqLLM();
|
|
4794
4382
|
|
|
4795
4383
|
// src/userResponse/anthropic.ts
|
|
4796
|
-
|
|
4797
|
-
|
|
4384
|
+
import dotenv2 from "dotenv";
|
|
4385
|
+
dotenv2.config();
|
|
4798
4386
|
var AnthropicLLM = class extends BaseLLM {
|
|
4799
4387
|
constructor(config) {
|
|
4800
4388
|
super(config);
|
|
@@ -4812,8 +4400,8 @@ var AnthropicLLM = class extends BaseLLM {
|
|
|
4812
4400
|
var anthropicLLM = new AnthropicLLM();
|
|
4813
4401
|
|
|
4814
4402
|
// src/userResponse/index.ts
|
|
4815
|
-
|
|
4816
|
-
|
|
4403
|
+
import dotenv3 from "dotenv";
|
|
4404
|
+
dotenv3.config();
|
|
4817
4405
|
function getLLMProviders() {
|
|
4818
4406
|
const envProviders = process.env.LLM_PROVIDERS;
|
|
4819
4407
|
const DEFAULT_PROVIDERS = ["anthropic", "groq"];
|
|
@@ -7271,7 +6859,7 @@ var SuperatomSDK = class {
|
|
|
7271
6859
|
url.searchParams.set("projectId", this.projectId);
|
|
7272
6860
|
url.searchParams.set("userId", this.userId);
|
|
7273
6861
|
url.searchParams.set("type", this.type);
|
|
7274
|
-
logger.info(`Connecting to WebSocket: ${url.
|
|
6862
|
+
logger.info(`Connecting to WebSocket: ${url.toString()}`);
|
|
7275
6863
|
this.ws = createWebSocket(url.toString());
|
|
7276
6864
|
this.ws.addEventListener("open", () => {
|
|
7277
6865
|
this.connected = true;
|