lua-cli 3.0.0-alpha.1 → 3.0.0-alpha.11

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.
Files changed (66) hide show
  1. package/dist/api/chat.api.service.d.ts +8 -0
  2. package/dist/api/chat.api.service.js +55 -0
  3. package/dist/api/job.api.service.d.ts +16 -7
  4. package/dist/api/job.api.service.js +21 -5
  5. package/dist/api/postprocessor.api.service.d.ts +61 -1
  6. package/dist/api/postprocessor.api.service.js +35 -0
  7. package/dist/api/preprocessor.api.service.d.ts +61 -1
  8. package/dist/api/preprocessor.api.service.js +35 -0
  9. package/dist/api-exports.d.ts +27 -7
  10. package/dist/api-exports.js +48 -30
  11. package/dist/cli/command-definitions.js +13 -6
  12. package/dist/commands/chat.js +71 -39
  13. package/dist/commands/compile.js +16 -2
  14. package/dist/commands/dev.js +23 -2
  15. package/dist/commands/push.d.ts +3 -2
  16. package/dist/commands/push.js +536 -6
  17. package/dist/commands/test.js +18 -2
  18. package/dist/common/job.instance.d.ts +3 -0
  19. package/dist/common/job.instance.js +8 -0
  20. package/dist/config/constants.d.ts +6 -5
  21. package/dist/config/constants.js +12 -10
  22. package/dist/interfaces/chat.d.ts +30 -1
  23. package/dist/interfaces/jobs.d.ts +21 -0
  24. package/dist/services/auth.d.ts +8 -2
  25. package/dist/services/auth.js +35 -3
  26. package/dist/types/skill.d.ts +75 -56
  27. package/dist/types/skill.js +53 -59
  28. package/dist/utils/bundling.d.ts +13 -4
  29. package/dist/utils/bundling.js +83 -26
  30. package/dist/utils/compile.js +27 -6
  31. package/dist/utils/dev-api.d.ts +42 -2
  32. package/dist/utils/dev-api.js +177 -4
  33. package/dist/utils/dev-server.d.ts +1 -1
  34. package/dist/utils/dev-server.js +4 -4
  35. package/dist/utils/dynamic-job-bundler.d.ts +17 -0
  36. package/dist/utils/dynamic-job-bundler.js +143 -0
  37. package/dist/utils/pre-bundle-jobs.d.ts +26 -0
  38. package/dist/utils/pre-bundle-jobs.js +176 -0
  39. package/dist/utils/sandbox-storage.d.ts +48 -0
  40. package/dist/utils/sandbox-storage.js +114 -0
  41. package/dist/utils/sandbox.d.ts +2 -2
  42. package/dist/utils/sandbox.js +23 -8
  43. package/package.json +1 -1
  44. package/template/env.example +5 -0
  45. package/template/lua.skill.yaml +47 -0
  46. package/template/package-lock.json +10505 -0
  47. package/template/package.json +2 -1
  48. package/template/src/index.ts +65 -3
  49. package/template/src/tools/CreateInlineJob.ts +42 -0
  50. package/API_REFERENCE.md +0 -1408
  51. package/CHANGELOG.md +0 -236
  52. package/CLI_REFERENCE.md +0 -908
  53. package/GETTING_STARTED.md +0 -1040
  54. package/INSTANCE_TYPES.md +0 -1158
  55. package/README.md +0 -865
  56. package/TEMPLATE_GUIDE.md +0 -1398
  57. package/USER_DATA_INSTANCE.md +0 -621
  58. package/template/AGENT_CONFIGURATION.md +0 -251
  59. package/template/COMPLEX_JOB_EXAMPLES.md +0 -795
  60. package/template/DYNAMIC_JOB_CREATION.md +0 -371
  61. package/template/TOOL_EXAMPLES.md +0 -655
  62. package/template/WEBHOOKS_JOBS_QUICKSTART.md +0 -318
  63. package/template/WEBHOOK_JOB_EXAMPLES.md +0 -817
  64. package/template/src/index-agent-example.ts +0 -201
  65. package/template/src/postprocessors/ResponseFormatter.ts +0 -151
  66. package/template/src/preprocessors/MessageFilter.ts +0 -91
@@ -42,7 +42,7 @@ function readDeployJson() {
42
42
  * @param port - Port to run server on
43
43
  * @returns Server instance with WebSocket and broadcast function
44
44
  */
45
- export function createChatServer(apiKey, agentId, skillId, sandboxId, port) {
45
+ export function createChatServer(apiKey, agentId, skillId, sandboxId, port, config) {
46
46
  const deployData = readDeployJson();
47
47
  const server = createServer((req, res) => {
48
48
  // Enable CORS
@@ -56,7 +56,7 @@ export function createChatServer(apiKey, agentId, skillId, sandboxId, port) {
56
56
  }
57
57
  // Route handlers
58
58
  if (req.method === 'POST' && req.url === '/chat') {
59
- handleChatEndpoint(req, res, apiKey, agentId, skillId, sandboxId, deployData);
59
+ handleChatEndpoint(req, res, apiKey, agentId, skillId, sandboxId, deployData, config);
60
60
  return;
61
61
  }
62
62
  if (req.method === 'GET' && req.url === '/persona') {
@@ -173,7 +173,7 @@ export function createChatServer(apiKey, agentId, skillId, sandboxId, port) {
173
173
  /**
174
174
  * Handles POST /chat - Send chat messages
175
175
  */
176
- function handleChatEndpoint(req, res, apiKey, agentId, skillId, sandboxId, deployData) {
176
+ function handleChatEndpoint(req, res, apiKey, agentId, skillId, sandboxId, deployData, config) {
177
177
  let body = '';
178
178
  req.on('data', (chunk) => {
179
179
  body += chunk.toString();
@@ -181,7 +181,7 @@ function handleChatEndpoint(req, res, apiKey, agentId, skillId, sandboxId, deplo
181
181
  req.on('end', async () => {
182
182
  try {
183
183
  const { message, persona } = JSON.parse(body);
184
- const response = await sendChatMessage(apiKey, agentId, skillId, sandboxId, message, persona, deployData);
184
+ const response = await sendChatMessage(apiKey, agentId, skillId, sandboxId, message, persona, deployData, config);
185
185
  res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
186
186
  res.end(JSON.stringify({
187
187
  success: response !== null,
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Dynamic Job Bundler
3
+ * Handles detection and bundling of Jobs.create() calls within execute functions
4
+ */
5
+ /**
6
+ * Detects if code contains Jobs.create() calls
7
+ */
8
+ export declare function containsJobsCreate(code: string): boolean;
9
+ /**
10
+ * Extracts Jobs.create() execute functions and bundles them with dependencies.
11
+ * Finds execute functions in the code and creates standalone bundles.
12
+ */
13
+ export declare function bundleNestedJobs(code: string, parentName: string, distDir: string): Promise<string>;
14
+ /**
15
+ * Cleans up temporary bundling directory
16
+ */
17
+ export declare function cleanupTempDir(distDir: string): void;
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Dynamic Job Bundler
3
+ * Handles detection and bundling of Jobs.create() calls within execute functions
4
+ */
5
+ import { build } from 'esbuild';
6
+ import fs from 'fs';
7
+ import path from 'path';
8
+ import { compressCode } from './compile.js';
9
+ import { sandboxGlobalsPlugin } from './bundling.js';
10
+ /**
11
+ * Detects if code contains Jobs.create() calls
12
+ */
13
+ export function containsJobsCreate(code) {
14
+ const found = /Jobs\.create\s*\(/i.test(code);
15
+ if (found) {
16
+ console.log('[DynamicJobs] ✅ Detected Jobs.create() in code');
17
+ }
18
+ return found;
19
+ }
20
+ /**
21
+ * Extracts Jobs.create() execute functions and bundles them with dependencies.
22
+ * Finds execute functions in the code and creates standalone bundles.
23
+ */
24
+ export async function bundleNestedJobs(code, parentName, distDir) {
25
+ if (!containsJobsCreate(code)) {
26
+ return code;
27
+ }
28
+ console.log(`[DynamicJobs] ⚠️ Jobs.create() with external dependencies not yet fully supported`);
29
+ console.log(`[DynamicJobs] 💡 Recommendation: Use fetch() or lua-cli APIs in job execute functions`);
30
+ console.log(`[DynamicJobs] 📋 Full bundling support planned for v3.1.0`);
31
+ // Return original code as-is
32
+ // The job will have access to lua-cli globals but external packages won't be bundled
33
+ return code;
34
+ }
35
+ /**
36
+ * Helper to extract job execute function from code
37
+ */
38
+ function extractJobExecuteFromCode(code) {
39
+ // This extracts the execute function body
40
+ // For now, return a placeholder that indicates the limitation
41
+ return `
42
+ // Note: This job execute function runs with limited context
43
+ // Use fetch() for external APIs or lua-cli globals (User, Data, Products)
44
+ console.log('Job execute running with user:', user);
45
+ return { executed: true };
46
+ `;
47
+ }
48
+ /**
49
+ * Bundles a job's execute function independently
50
+ */
51
+ async function bundleJobExecuteFunction(executeFunction, jobName, distDir) {
52
+ const tempDir = path.join(distDir, '.temp');
53
+ if (!fs.existsSync(tempDir)) {
54
+ fs.mkdirSync(tempDir, { recursive: true });
55
+ }
56
+ const tempFile = path.join(tempDir, `${jobName}.js`);
57
+ const tempOutput = path.join(tempDir, `${jobName}-bundled.js`);
58
+ try {
59
+ // Extract imports that the execute function might need
60
+ // Common ones: Stripe, axios, etc.
61
+ const moduleCode = `
62
+ // Job execute function for ${jobName}
63
+ // Import dependencies that might be used
64
+ import Stripe from 'stripe';
65
+ import { env, User, Data, Products, Baskets, Orders } from 'lua-cli';
66
+
67
+ // The execute function with all dependencies available
68
+ const executeFunc = ${executeFunction};
69
+
70
+ // Export as default for esbuild to bundle
71
+ export default executeFunc;
72
+ `;
73
+ fs.writeFileSync(tempFile, moduleCode);
74
+ // Bundle with esbuild - bundle ALL dependencies (including Stripe, axios, etc.)
75
+ await build({
76
+ entryPoints: [tempFile],
77
+ bundle: true,
78
+ platform: 'node',
79
+ target: 'node16',
80
+ format: 'cjs',
81
+ minify: true,
82
+ outfile: tempOutput,
83
+ external: [], // Bundle everything except lua-cli APIs (handled by plugin)
84
+ plugins: [sandboxGlobalsPlugin], // This handles lua-cli globals
85
+ // Important: Don't externalize packages like stripe, axios, etc.
86
+ // They need to be included in the bundle
87
+ });
88
+ // Read bundled code (includes all dependencies like Stripe, axios, etc.)
89
+ let bundledCode = fs.readFileSync(tempOutput, 'utf8');
90
+ // Log bundle size for debugging
91
+ console.log(`[DynamicJobs] Bundled size for ${jobName}: ${(bundledCode.length / 1024).toFixed(2)}KB`);
92
+ // Wrap for VM execution - the bundled code includes ALL dependencies
93
+ const wrappedCode = `(async (job) => {
94
+
95
+ ${bundledCode}
96
+
97
+ // Get the execute function from exports
98
+ const executeFunction = module.exports || module.exports.default;
99
+
100
+ // Execute with job
101
+ return await executeFunction(job);
102
+ })`;
103
+ // Compress the wrapped code
104
+ const compressed = compressCode(wrappedCode);
105
+ // Clean up temp files
106
+ try {
107
+ fs.unlinkSync(tempFile);
108
+ fs.unlinkSync(tempOutput);
109
+ }
110
+ catch (cleanupError) {
111
+ // Ignore cleanup errors
112
+ }
113
+ return compressed;
114
+ }
115
+ catch (error) {
116
+ console.warn(`Warning: Could not bundle job execute function ${jobName}:`, error);
117
+ // Clean up on error
118
+ try {
119
+ if (fs.existsSync(tempFile))
120
+ fs.unlinkSync(tempFile);
121
+ if (fs.existsSync(tempOutput))
122
+ fs.unlinkSync(tempOutput);
123
+ }
124
+ catch (cleanupError) {
125
+ // Ignore cleanup errors
126
+ }
127
+ return '';
128
+ }
129
+ }
130
+ /**
131
+ * Cleans up temporary bundling directory
132
+ */
133
+ export function cleanupTempDir(distDir) {
134
+ const tempDir = path.join(distDir, '.temp');
135
+ if (fs.existsSync(tempDir)) {
136
+ try {
137
+ fs.rmSync(tempDir, { recursive: true, force: true });
138
+ }
139
+ catch (error) {
140
+ // Ignore cleanup errors
141
+ }
142
+ }
143
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Pre-Bundle Jobs - Extract and bundle Jobs.create() before tool bundling
3
+ *
4
+ * Flow:
5
+ * 1. Detect Jobs.create() in source
6
+ * 2. Extract execute function
7
+ * 3. Bundle execute with ALL dependencies
8
+ * 4. Replace execute with placeholder
9
+ * 5. Bundle tool/webhook/job
10
+ * 6. Replace placeholder with bundled job code
11
+ * 7. Compress
12
+ */
13
+ import { Project } from 'ts-morph';
14
+ /**
15
+ * Pre-processes source file to extract and bundle Jobs.create() execute functions
16
+ * Returns modified source code with placeholders
17
+ */
18
+ export declare function preBundleJobsInSource(sourceFilePath: string, project: Project, distDir: string): Promise<{
19
+ modifiedSource: string;
20
+ jobBundles: Map<string, string>;
21
+ }>;
22
+ /**
23
+ * Replaces placeholders in bundled code with actual job bundles
24
+ * The bundled job code is NOT compressed - it's JavaScript that will be part of the tool
25
+ */
26
+ export declare function replaceJobPlaceholders(bundledCode: string, jobBundles: Map<string, string>): string;
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Pre-Bundle Jobs - Extract and bundle Jobs.create() before tool bundling
3
+ *
4
+ * Flow:
5
+ * 1. Detect Jobs.create() in source
6
+ * 2. Extract execute function
7
+ * 3. Bundle execute with ALL dependencies
8
+ * 4. Replace execute with placeholder
9
+ * 5. Bundle tool/webhook/job
10
+ * 6. Replace placeholder with bundled job code
11
+ * 7. Compress
12
+ */
13
+ import { Node } from 'ts-morph';
14
+ import { build } from 'esbuild';
15
+ import fs from 'fs';
16
+ import path from 'path';
17
+ import { sandboxGlobalsPlugin } from './bundling.js';
18
+ const JOB_PLACEHOLDER = '__BUNDLED_JOB_EXECUTE__';
19
+ /**
20
+ * Pre-processes source file to extract and bundle Jobs.create() execute functions
21
+ * Returns modified source code with placeholders
22
+ */
23
+ export async function preBundleJobsInSource(sourceFilePath, project, distDir) {
24
+ const sourceFile = project.getSourceFile(sourceFilePath);
25
+ if (!sourceFile) {
26
+ return { modifiedSource: fs.readFileSync(sourceFilePath, 'utf8'), jobBundles: new Map() };
27
+ }
28
+ const jobBundles = new Map();
29
+ const bundlingPromises = [];
30
+ let jobIndex = 0;
31
+ let modifiedSource = sourceFile.getFullText();
32
+ // Find all Jobs.create() calls
33
+ sourceFile.forEachDescendant((node) => {
34
+ if (Node.isCallExpression(node)) {
35
+ const expression = node.getExpression();
36
+ // Check if this is Jobs.create()
37
+ if (Node.isPropertyAccessExpression(expression)) {
38
+ const object = expression.getExpression();
39
+ const property = expression.getName();
40
+ if (object.getText() === 'Jobs' && property === 'create') {
41
+ jobIndex++;
42
+ const placeholder = `${JOB_PLACEHOLDER}_${jobIndex}`;
43
+ console.log(`[PreBundleJobs] Found Jobs.create() #${jobIndex}`);
44
+ // Get the config object argument
45
+ const args = node.getArguments();
46
+ if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) {
47
+ const configObj = args[0];
48
+ // Find the execute property
49
+ const executeProperty = configObj.getProperty('execute');
50
+ if (executeProperty && Node.isPropertyAssignment(executeProperty)) {
51
+ const executeInitializer = executeProperty.getInitializer();
52
+ if (executeInitializer) {
53
+ const executeCode = executeInitializer.getText();
54
+ console.log(`[PreBundleJobs] Extracting execute function for bundling...`);
55
+ // Bundle the execute function with dependencies (async)
56
+ const bundlePromise = bundleJobExecuteFunction(executeCode, `job_${jobIndex}`, distDir, sourceFilePath).then(bundledCode => {
57
+ if (bundledCode) {
58
+ jobBundles.set(placeholder, bundledCode);
59
+ console.log(`[PreBundleJobs] ✅ Bundled job #${jobIndex} with dependencies`);
60
+ }
61
+ });
62
+ bundlingPromises.push(bundlePromise);
63
+ // Replace execute function with a function that references the bundled code
64
+ // Don't use string placeholder - use a reference
65
+ const originalText = executeProperty.getText();
66
+ const replacementText = `execute: ${placeholder}`;
67
+ modifiedSource = modifiedSource.replace(originalText, replacementText);
68
+ }
69
+ }
70
+ }
71
+ }
72
+ }
73
+ }
74
+ });
75
+ // Wait for all bundling to complete
76
+ if (bundlingPromises.length > 0) {
77
+ console.log(`[PreBundleJobs] Waiting for ${bundlingPromises.length} job(s) to bundle...`);
78
+ await Promise.all(bundlingPromises);
79
+ console.log(`[PreBundleJobs] ✅ All job bundles complete`);
80
+ }
81
+ return { modifiedSource, jobBundles };
82
+ }
83
+ /**
84
+ * Bundles a job execute function with all its dependencies
85
+ */
86
+ async function bundleJobExecuteFunction(executeCode, jobName, distDir, sourceFilePath) {
87
+ const tempDir = path.join(distDir, '.temp');
88
+ if (!fs.existsSync(tempDir)) {
89
+ fs.mkdirSync(tempDir, { recursive: true });
90
+ }
91
+ const tempOutput = path.join(tempDir, `${jobName}-bundled.js`);
92
+ try {
93
+ // Read the original source file to get its imports
94
+ const sourceContent = fs.readFileSync(sourceFilePath, 'utf8');
95
+ // Extract all import statements from the source
96
+ const importPattern = /^import\s+.+\s+from\s+['"][^'"]+['"];?$/gm;
97
+ const imports = sourceContent.match(importPattern) || [];
98
+ // Filter to only imports that might be used (exclude lua-cli internal classes and APIs)
99
+ const relevantImports = imports.filter(imp => !imp.includes('LuaTool') &&
100
+ !imp.includes('LuaWebhook') &&
101
+ !imp.includes('LuaJob') &&
102
+ !imp.includes('lua-cli') && // Exclude all lua-cli imports (they're available in sandbox)
103
+ !imp.includes('api-exports') && // Exclude api-exports
104
+ !imp.includes('../../../dist/api-exports') // Exclude direct api-exports imports
105
+ );
106
+ console.log(`[PreBundleJobs] Including ${relevantImports.length} import(s) in job bundle`);
107
+ // Create a TypeScript module with the execute function and all imports
108
+ const moduleCode = `
109
+ // Auto-generated job execute bundle
110
+ ${relevantImports.join('\n')}
111
+
112
+ // The execute function with all dependencies available
113
+ const executeFunc = ${executeCode};
114
+
115
+ export default executeFunc;
116
+ `;
117
+ // Bundle with esbuild using stdin to preserve import resolution
118
+ await build({
119
+ stdin: {
120
+ contents: moduleCode,
121
+ resolveDir: path.dirname(sourceFilePath),
122
+ sourcefile: sourceFilePath,
123
+ loader: 'ts',
124
+ },
125
+ bundle: true,
126
+ platform: 'node',
127
+ target: 'node16',
128
+ format: 'cjs',
129
+ minify: true,
130
+ outfile: tempOutput,
131
+ external: [],
132
+ plugins: [sandboxGlobalsPlugin],
133
+ });
134
+ // Read bundled code
135
+ const bundledCode = fs.readFileSync(tempOutput, 'utf8');
136
+ console.log(`[PreBundleJobs] Bundle size: ${(bundledCode.length / 1024).toFixed(2)}KB`);
137
+ // DON'T compress - just wrap for VM execution
138
+ // Compression happens later when the entire tool is bundled
139
+ const wrappedCode = `(async (job) => {
140
+ ${bundledCode}
141
+ const executeFunction = module.exports.default || module.exports;
142
+ return await executeFunction(job);
143
+ })`;
144
+ // Cleanup temp files
145
+ try {
146
+ fs.unlinkSync(tempOutput);
147
+ }
148
+ catch { }
149
+ // Return uncompressed bundled code
150
+ return wrappedCode;
151
+ }
152
+ catch (error) {
153
+ console.warn(`[PreBundleJobs] Error bundling job ${jobName}:`, error);
154
+ try {
155
+ if (fs.existsSync(tempOutput))
156
+ fs.unlinkSync(tempOutput);
157
+ }
158
+ catch { }
159
+ return '';
160
+ }
161
+ }
162
+ /**
163
+ * Replaces placeholders in bundled code with actual job bundles
164
+ * The bundled job code is NOT compressed - it's JavaScript that will be part of the tool
165
+ */
166
+ export function replaceJobPlaceholders(bundledCode, jobBundles) {
167
+ let result = bundledCode;
168
+ jobBundles.forEach((bundledJobCode, placeholder) => {
169
+ // The placeholder is used as an identifier (not a string), just replace it directly
170
+ // It appears as: execute: __BUNDLED_JOB_EXECUTE___1
171
+ const placeholderPattern = new RegExp(placeholder, 'g');
172
+ result = result.replace(placeholderPattern, bundledJobCode);
173
+ console.log(`[PreBundleJobs] ✅ Replaced ${placeholder} with bundled code (${(bundledJobCode.length / 1024).toFixed(1)}KB)`);
174
+ });
175
+ return result;
176
+ }
@@ -25,3 +25,51 @@ export declare function setSandboxSkillId(sandboxId: string, skillName?: string)
25
25
  * @returns Array of skill overrides with skillId and sandboxId pairs
26
26
  */
27
27
  export declare function getAllSandboxSkillIds(deployData: any): Promise<SkillOverride[]>;
28
+ /**
29
+ * Retrieves sandbox preprocessor ID from secure storage.
30
+ *
31
+ * @param preprocessorName - Preprocessor name
32
+ * @returns The sandbox preprocessor ID or null if not found
33
+ */
34
+ export declare function getSandboxPreProcessorId(preprocessorName: string): Promise<string | null>;
35
+ /**
36
+ * Stores sandbox preprocessor ID in secure storage.
37
+ *
38
+ * @param sandboxId - The sandbox preprocessor ID to store
39
+ * @param preprocessorName - Preprocessor name
40
+ */
41
+ export declare function setSandboxPreProcessorId(sandboxId: string, preprocessorName: string): Promise<void>;
42
+ /**
43
+ * Retrieves sandbox postprocessor ID from secure storage.
44
+ *
45
+ * @param postprocessorName - Postprocessor name
46
+ * @returns The sandbox postprocessor ID or null if not found
47
+ */
48
+ export declare function getSandboxPostProcessorId(postprocessorName: string): Promise<string | null>;
49
+ /**
50
+ * Stores sandbox postprocessor ID in secure storage.
51
+ *
52
+ * @param sandboxId - The sandbox postprocessor ID to store
53
+ * @param postprocessorName - Postprocessor name
54
+ */
55
+ export declare function setSandboxPostProcessorId(sandboxId: string, postprocessorName: string): Promise<void>;
56
+ /**
57
+ * Gets all sandbox preprocessor overrides for the current config.
58
+ *
59
+ * @param config - Configuration with preprocessors
60
+ * @returns Array of preprocessor overrides
61
+ */
62
+ export declare function getAllSandboxPreProcessorIds(config: any): Promise<Array<{
63
+ preprocessorId: string;
64
+ sandboxId: string;
65
+ }>>;
66
+ /**
67
+ * Gets all sandbox postprocessor overrides for the current config.
68
+ *
69
+ * @param config - Configuration with postprocessors
70
+ * @returns Array of postprocessor overrides
71
+ */
72
+ export declare function getAllSandboxPostProcessorIds(config: any): Promise<Array<{
73
+ postprocessorId: string;
74
+ sandboxId: string;
75
+ }>>;
@@ -69,3 +69,117 @@ export async function getAllSandboxSkillIds(deployData) {
69
69
  }
70
70
  return skillOverrides;
71
71
  }
72
+ /**
73
+ * Retrieves sandbox preprocessor ID from secure storage.
74
+ *
75
+ * @param preprocessorName - Preprocessor name
76
+ * @returns The sandbox preprocessor ID or null if not found
77
+ */
78
+ export async function getSandboxPreProcessorId(preprocessorName) {
79
+ try {
80
+ const account = `${SANDBOX_STORAGE.ACCOUNT}_preprocessor_${preprocessorName}`;
81
+ return await keytar.getPassword(SANDBOX_STORAGE.SERVICE, account);
82
+ }
83
+ catch (error) {
84
+ return null;
85
+ }
86
+ }
87
+ /**
88
+ * Stores sandbox preprocessor ID in secure storage.
89
+ *
90
+ * @param sandboxId - The sandbox preprocessor ID to store
91
+ * @param preprocessorName - Preprocessor name
92
+ */
93
+ export async function setSandboxPreProcessorId(sandboxId, preprocessorName) {
94
+ try {
95
+ const account = `${SANDBOX_STORAGE.ACCOUNT}_preprocessor_${preprocessorName}`;
96
+ await keytar.setPassword(SANDBOX_STORAGE.SERVICE, account, sandboxId);
97
+ }
98
+ catch (error) {
99
+ // Ignore storage errors
100
+ }
101
+ }
102
+ /**
103
+ * Retrieves sandbox postprocessor ID from secure storage.
104
+ *
105
+ * @param postprocessorName - Postprocessor name
106
+ * @returns The sandbox postprocessor ID or null if not found
107
+ */
108
+ export async function getSandboxPostProcessorId(postprocessorName) {
109
+ try {
110
+ const account = `${SANDBOX_STORAGE.ACCOUNT}_postprocessor_${postprocessorName}`;
111
+ return await keytar.getPassword(SANDBOX_STORAGE.SERVICE, account);
112
+ }
113
+ catch (error) {
114
+ return null;
115
+ }
116
+ }
117
+ /**
118
+ * Stores sandbox postprocessor ID in secure storage.
119
+ *
120
+ * @param sandboxId - The sandbox postprocessor ID to store
121
+ * @param postprocessorName - Postprocessor name
122
+ */
123
+ export async function setSandboxPostProcessorId(sandboxId, postprocessorName) {
124
+ try {
125
+ const account = `${SANDBOX_STORAGE.ACCOUNT}_postprocessor_${postprocessorName}`;
126
+ await keytar.setPassword(SANDBOX_STORAGE.SERVICE, account, sandboxId);
127
+ }
128
+ catch (error) {
129
+ // Ignore storage errors
130
+ }
131
+ }
132
+ /**
133
+ * Gets all sandbox preprocessor overrides for the current config.
134
+ *
135
+ * @param config - Configuration with preprocessors
136
+ * @returns Array of preprocessor overrides
137
+ */
138
+ export async function getAllSandboxPreProcessorIds(config) {
139
+ const overrides = [];
140
+ try {
141
+ const preprocessors = config.preprocessors || [];
142
+ for (const preprocessor of preprocessors) {
143
+ if (preprocessor.preprocessorId && preprocessor.name) {
144
+ const sandboxId = await getSandboxPreProcessorId(preprocessor.name);
145
+ if (sandboxId) {
146
+ overrides.push({
147
+ preprocessorId: preprocessor.preprocessorId,
148
+ sandboxId: sandboxId
149
+ });
150
+ }
151
+ }
152
+ }
153
+ }
154
+ catch (error) {
155
+ console.error('Error getting sandbox preprocessor IDs:', error);
156
+ }
157
+ return overrides;
158
+ }
159
+ /**
160
+ * Gets all sandbox postprocessor overrides for the current config.
161
+ *
162
+ * @param config - Configuration with postprocessors
163
+ * @returns Array of postprocessor overrides
164
+ */
165
+ export async function getAllSandboxPostProcessorIds(config) {
166
+ const overrides = [];
167
+ try {
168
+ const postprocessors = config.postprocessors || [];
169
+ for (const postprocessor of postprocessors) {
170
+ if (postprocessor.postprocessorId && postprocessor.name) {
171
+ const sandboxId = await getSandboxPostProcessorId(postprocessor.name);
172
+ if (sandboxId) {
173
+ overrides.push({
174
+ postprocessorId: postprocessor.postprocessorId,
175
+ sandboxId: sandboxId
176
+ });
177
+ }
178
+ }
179
+ }
180
+ }
181
+ catch (error) {
182
+ console.error('Error getting sandbox postprocessor IDs:', error);
183
+ }
184
+ return overrides;
185
+ }
@@ -20,7 +20,7 @@ export interface ExecuteJobOptions extends SandboxOptions {
20
20
  }
21
21
  export interface ExecutePreProcessorOptions extends SandboxOptions {
22
22
  processorCode: string;
23
- message: string;
23
+ messages: any[];
24
24
  channel: string;
25
25
  }
26
26
  export interface ExecutePostProcessorOptions extends SandboxOptions {
@@ -75,7 +75,7 @@ export declare function executeJob(options: ExecuteJobOptions): Promise<any>;
75
75
  * @param options - PreProcessor execution options
76
76
  * @returns Processed message string
77
77
  */
78
- export declare function executePreProcessor(options: ExecutePreProcessorOptions): Promise<string>;
78
+ export declare function executePreProcessor(options: ExecutePreProcessorOptions): Promise<any[]>;
79
79
  /**
80
80
  * Executes a postprocessor in a sandboxed environment.
81
81
  *
@@ -13,6 +13,7 @@ import WebhookApi from "../api/webhook.api.service.js";
13
13
  import JobApi from "../api/job.api.service.js";
14
14
  import { BasketStatus } from "../interfaces/baskets.js";
15
15
  import { OrderStatus } from "../interfaces/orders.js";
16
+ import { compressCode } from "./compile.js";
16
17
  /**
17
18
  * Loads environment variables from multiple sources in priority order:
18
19
  * 1. process.env (lowest priority)
@@ -221,6 +222,7 @@ export function createSandbox(options) {
221
222
  Products: productService,
222
223
  Data: dataService,
223
224
  Baskets: basketsService,
225
+ compressCode: compressCode,
224
226
  Orders: orderService,
225
227
  // Jobs API
226
228
  Jobs: {
@@ -229,14 +231,27 @@ export function createSandbox(options) {
229
231
  const executeString = typeof config.execute === 'function'
230
232
  ? config.execute.toString()
231
233
  : config.execute;
232
- // Create job
234
+ // Create job with version and activation
233
235
  return await jobService.createJobInstance({
234
- name: config.name,
236
+ name: config.name + '_' + Date.now(),
235
237
  description: config.description,
236
238
  context: config.description || '',
237
239
  schedule: config.schedule,
238
240
  timeout: config.timeout,
239
- retry: config.retry
241
+ retry: config.retry,
242
+ metadata: config.metadata,
243
+ dynamic: true,
244
+ version: {
245
+ version: '1.0.0',
246
+ description: config.description,
247
+ context: config.description || '',
248
+ code: '',
249
+ executeFunction: executeString,
250
+ timeout: config.timeout,
251
+ retry: config.retry,
252
+ metadata: config.metadata
253
+ },
254
+ activate: config.activate ?? true
240
255
  });
241
256
  },
242
257
  get: async (jobId) => jobService.getJob(jobId)
@@ -330,9 +345,9 @@ export async function executeWebhook(options) {
330
345
  const executeFunction = ${webhookCode};
331
346
 
332
347
  // Export the function for testing
333
- module.exports = async (input) => {
348
+ module.exports = async (query, headers, body) => {
334
349
  try{
335
- return await executeFunction(input);
350
+ return await executeFunction(query, headers, body);
336
351
  }catch(e){
337
352
  console.error(e);
338
353
  return { status: 'error', error: e.message };
@@ -438,7 +453,7 @@ try{
438
453
  * @returns Processed message string
439
454
  */
440
455
  export async function executePreProcessor(options) {
441
- const { processorCode, message, channel, apiKey, agentId } = options;
456
+ const { processorCode, messages, channel, apiKey, agentId } = options;
442
457
  // Create sandbox
443
458
  const sandbox = createSandbox(options);
444
459
  // Get user instance first (outside VM)
@@ -453,7 +468,7 @@ const executeFunction = ${processorCode};
453
468
  module.exports = async (input) => {
454
469
  try{
455
470
  // userInstance is passed as parameter
456
- return await executeFunction(input.user, input.message, input.channel);
471
+ return await executeFunction(input.user, input.messages, input.channel);
457
472
  }catch(e){
458
473
  console.error(e);
459
474
  return { status: 'error', error: e.message };
@@ -481,7 +496,7 @@ try{
481
496
  vm.runInContext(commonJsWrapper, context);
482
497
  // Get the exported function and execute with user instance
483
498
  const executeFunction = context.module.exports;
484
- return await executeFunction({ user: userInstance, message, channel });
499
+ return await executeFunction({ user: userInstance, messages, channel });
485
500
  }
486
501
  /**
487
502
  * Executes a postprocessor in a sandboxed environment.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lua-cli",
3
- "version": "3.0.0-alpha.1",
3
+ "version": "3.0.0-alpha.11",
4
4
  "description": "Command-line interface for Lua AI platform - develop, test, and deploy LuaSkills with custom tools",
5
5
  "readmeFilename": "README.md",
6
6
  "main": "dist/api-exports.js",