lua-cli 2.5.7 ā 3.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/agent.api.service.d.ts +45 -0
- package/dist/api/agent.api.service.js +54 -0
- package/dist/api/job.api.service.d.ts +210 -0
- package/dist/api/job.api.service.js +200 -0
- package/dist/api/lazy-instances.d.ts +24 -0
- package/dist/api/lazy-instances.js +48 -0
- package/dist/api/postprocessor.api.service.d.ts +98 -0
- package/dist/api/postprocessor.api.service.js +76 -0
- package/dist/api/preprocessor.api.service.d.ts +98 -0
- package/dist/api/preprocessor.api.service.js +76 -0
- package/dist/api/user.data.api.service.d.ts +28 -0
- package/dist/api/user.data.api.service.js +51 -0
- package/dist/api/webhook.api.service.d.ts +151 -0
- package/dist/api/webhook.api.service.js +134 -0
- package/dist/api-exports.d.ts +156 -41
- package/dist/api-exports.js +182 -21
- package/dist/cli/command-definitions.js +149 -7
- package/dist/commands/compile.js +124 -5
- package/dist/commands/completion.d.ts +11 -0
- package/dist/commands/completion.js +209 -0
- package/dist/commands/env.d.ts +3 -2
- package/dist/commands/env.js +42 -17
- package/dist/commands/features.d.ts +16 -0
- package/dist/commands/features.js +352 -0
- package/dist/commands/index.d.ts +7 -0
- package/dist/commands/index.js +7 -0
- package/dist/commands/init.js +53 -7
- package/dist/commands/jobs.d.ts +20 -0
- package/dist/commands/jobs.js +533 -0
- package/dist/commands/logs.js +2 -5
- package/dist/commands/persona.d.ts +3 -2
- package/dist/commands/persona.js +43 -18
- package/dist/commands/postprocessors.d.ts +8 -0
- package/dist/commands/postprocessors.js +431 -0
- package/dist/commands/preprocessors.d.ts +8 -0
- package/dist/commands/preprocessors.js +431 -0
- package/dist/commands/push.d.ts +9 -13
- package/dist/commands/push.js +937 -69
- package/dist/commands/skills.d.ts +16 -0
- package/dist/commands/skills.js +438 -0
- package/dist/commands/test.d.ts +9 -18
- package/dist/commands/test.js +558 -82
- package/dist/commands/webhooks.d.ts +18 -0
- package/dist/commands/webhooks.js +424 -0
- package/dist/common/data.entry.instance.d.ts +7 -0
- package/dist/common/data.entry.instance.js +15 -0
- package/dist/common/job.instance.d.ts +77 -0
- package/dist/common/job.instance.js +108 -0
- package/dist/common/order.instance.d.ts +6 -0
- package/dist/common/order.instance.js +14 -0
- package/dist/common/product.instance.d.ts +6 -0
- package/dist/common/product.instance.js +14 -0
- package/dist/common/user.instance.d.ts +15 -0
- package/dist/common/user.instance.js +38 -0
- package/dist/config/constants.d.ts +2 -2
- package/dist/config/constants.js +4 -4
- package/dist/index.js +14 -3
- package/dist/interfaces/agent.d.ts +33 -1
- package/dist/interfaces/chat.d.ts +22 -0
- package/dist/interfaces/index.d.ts +10 -0
- package/dist/interfaces/index.js +7 -0
- package/dist/interfaces/jobs.d.ts +172 -0
- package/dist/interfaces/jobs.js +5 -0
- package/dist/interfaces/message.d.ts +18 -0
- package/dist/interfaces/message.js +1 -0
- package/dist/interfaces/postprocessors.d.ts +35 -0
- package/dist/interfaces/postprocessors.js +4 -0
- package/dist/interfaces/preprocessors.d.ts +35 -0
- package/dist/interfaces/preprocessors.js +4 -0
- package/dist/interfaces/webhooks.d.ts +104 -0
- package/dist/interfaces/webhooks.js +5 -0
- package/dist/types/api-contracts.d.ts +14 -0
- package/dist/types/api-contracts.js +0 -7
- package/dist/types/compile.types.d.ts +49 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/skill.d.ts +502 -0
- package/dist/types/skill.js +477 -0
- package/dist/utils/agent-management.d.ts +25 -0
- package/dist/utils/agent-management.js +67 -0
- package/dist/utils/bundling.d.ts +31 -1
- package/dist/utils/bundling.js +653 -10
- package/dist/utils/compile.d.ts +63 -0
- package/dist/utils/compile.js +691 -36
- package/dist/utils/deployment.d.ts +2 -1
- package/dist/utils/deployment.js +16 -2
- package/dist/utils/init-agent.d.ts +3 -1
- package/dist/utils/init-agent.js +6 -4
- package/dist/utils/init-prompts.d.ts +2 -1
- package/dist/utils/init-prompts.js +14 -9
- package/dist/utils/job-management.d.ts +24 -0
- package/dist/utils/job-management.js +264 -0
- package/dist/utils/postprocessor-management.d.ts +9 -0
- package/dist/utils/postprocessor-management.js +118 -0
- package/dist/utils/preprocessor-management.d.ts +9 -0
- package/dist/utils/preprocessor-management.js +118 -0
- package/dist/utils/sandbox.d.ts +61 -1
- package/dist/utils/sandbox.js +283 -72
- package/dist/utils/tool-detection.d.ts +3 -2
- package/dist/utils/tool-detection.js +18 -4
- package/dist/utils/webhook-management.d.ts +24 -0
- package/dist/utils/webhook-management.js +256 -0
- package/dist/web/app.css +152 -736
- package/dist/web/app.js +45 -45
- package/package.json +2 -2
- package/template/AGENT_CONFIGURATION.md +251 -0
- package/template/COMPLEX_JOB_EXAMPLES.md +795 -0
- package/template/DYNAMIC_JOB_CREATION.md +371 -0
- package/template/README.md +30 -2
- package/template/WEBHOOKS_JOBS_QUICKSTART.md +318 -0
- package/template/WEBHOOK_JOB_EXAMPLES.md +817 -0
- package/template/package.json +1 -1
- package/template/src/index-agent-example.ts +201 -0
- package/template/src/index.ts +39 -0
- package/template/src/jobs/AbandonedBasketProcessorJob.ts +139 -0
- package/template/src/jobs/DailyCleanupJob.ts +100 -0
- package/template/src/jobs/DataMigrationJob.ts +133 -0
- package/template/src/jobs/HealthCheckJob.ts +87 -0
- package/template/src/postprocessors/ResponseFormatter.ts +151 -0
- package/template/src/preprocessors/MessageFilter.ts +91 -0
- package/template/src/tools/GameScoreTrackerTool.ts +356 -0
- package/template/src/tools/SmartBasketTool.ts +188 -0
- package/template/src/webhooks/PaymentWebhook.ts +113 -0
- package/template/src/webhooks/UserEventWebhook.ts +77 -0
package/dist/commands/test.js
CHANGED
|
@@ -2,102 +2,578 @@
|
|
|
2
2
|
* Test Command
|
|
3
3
|
* Orchestrates the testing of individual tools in a local sandbox environment
|
|
4
4
|
*/
|
|
5
|
+
import fs from "fs";
|
|
6
|
+
import path from "path";
|
|
5
7
|
import { compileCommand } from "./compile.js";
|
|
6
8
|
import { withErrorHandling, clearPromptLines, writeProgress, writeSuccess } from "../utils/cli.js";
|
|
7
9
|
import { loadApiKey } from "../services/auth.js";
|
|
8
|
-
import { executeTool, loadEnvironmentVariables } from "../utils/sandbox.js";
|
|
10
|
+
import { executeTool, executeWebhook, executeJob, executePreProcessor, executePostProcessor, loadEnvironmentVariables } from "../utils/sandbox.js";
|
|
9
11
|
import { readSkillConfig } from "../utils/files.js";
|
|
12
|
+
import { safePrompt } from "../utils/prompt-handler.js";
|
|
10
13
|
import { decompressCode, readDeployJson, extractToolsFromDeployData, hasEnvFile, hasConfigEnvVars, } from "../utils/test-helpers.js";
|
|
11
14
|
import { promptToolSelection, generatePromptsForObject } from "../utils/test-prompts.js";
|
|
12
15
|
/**
|
|
13
|
-
* Main test command - tests
|
|
16
|
+
* Main test command - tests tools, webhooks, jobs, preprocessors, or postprocessors.
|
|
14
17
|
*
|
|
15
|
-
* This command
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* 6. Executes the tool in a sandboxed environment
|
|
22
|
-
* 7. Displays the results
|
|
23
|
-
*
|
|
24
|
-
* Features:
|
|
25
|
-
* - Interactive tool selection from compiled tools
|
|
26
|
-
* - Dynamic input prompts based on tool schemas
|
|
27
|
-
* - Support for nested object inputs
|
|
28
|
-
* - Environment variable injection
|
|
29
|
-
* - Secure sandbox execution
|
|
30
|
-
* - Detailed error reporting
|
|
18
|
+
* This command can test:
|
|
19
|
+
* - Skills/Tools: Interactive tool execution with input prompts
|
|
20
|
+
* - Webhooks: Test webhook with query params, headers, and body
|
|
21
|
+
* - Jobs: Trigger job execution manually
|
|
22
|
+
* - PreProcessors: Test message preprocessing
|
|
23
|
+
* - PostProcessors: Test response postprocessing
|
|
31
24
|
*
|
|
25
|
+
* @param type - Optional type argument ('skill', 'webhook', 'job', 'preprocessor', 'postprocessor')
|
|
32
26
|
* @returns Promise that resolves when test completes
|
|
33
27
|
*/
|
|
34
|
-
export async function testCommand() {
|
|
28
|
+
export async function testCommand(type) {
|
|
35
29
|
return withErrorHandling(async () => {
|
|
36
|
-
|
|
37
|
-
// Step 1:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
// Step 7: Execute the tool
|
|
73
|
-
writeProgress("\nš Executing tool...");
|
|
74
|
-
writeProgress(`Input: ${JSON.stringify(inputValues, null, 2)}`);
|
|
75
|
-
const toolCode = decompressCode(selectedTool.execute);
|
|
76
|
-
// Set environment variables for sandbox
|
|
77
|
-
const originalEnv = { ...process.env };
|
|
78
|
-
for (const [key, value] of Object.entries(envVars)) {
|
|
79
|
-
process.env[key] = value;
|
|
80
|
-
}
|
|
81
|
-
try {
|
|
82
|
-
const result = await executeTool({
|
|
83
|
-
toolCode,
|
|
84
|
-
inputs: inputValues,
|
|
85
|
-
apiKey,
|
|
86
|
-
agentId
|
|
87
|
-
});
|
|
88
|
-
writeSuccess("ā
Tool execution successful!");
|
|
89
|
-
console.log(`Output: ${JSON.stringify(result, null, 2)}`);
|
|
90
|
-
}
|
|
91
|
-
catch (executionError) {
|
|
92
|
-
console.error("\nā Tool execution failed:");
|
|
93
|
-
console.error(executionError.message);
|
|
94
|
-
if (executionError.stack) {
|
|
95
|
-
console.error(executionError.stack);
|
|
30
|
+
let selectedType;
|
|
31
|
+
// Step 1: Check if type was provided as argument
|
|
32
|
+
if (type) {
|
|
33
|
+
// Validate the provided type
|
|
34
|
+
if (type !== 'skill' && type !== 'webhook' && type !== 'job' && type !== 'preprocessor' && type !== 'postprocessor') {
|
|
35
|
+
console.error(`ā Invalid type: "${type}". Must be "skill", "webhook", "job", "preprocessor", or "postprocessor".`);
|
|
36
|
+
console.log('\nUsage:');
|
|
37
|
+
console.log(' lua test - Interactive selection');
|
|
38
|
+
console.log(' lua test skill - Test a skill/tool directly');
|
|
39
|
+
console.log(' lua test webhook - Test a webhook directly');
|
|
40
|
+
console.log(' lua test job - Test a job directly');
|
|
41
|
+
console.log(' lua test preprocessor - Test a preprocessor directly');
|
|
42
|
+
console.log(' lua test postprocessor - Test a postprocessor directly');
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
selectedType = type;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// Step 2: Prompt for type selection
|
|
49
|
+
const typeAnswer = await safePrompt([
|
|
50
|
+
{
|
|
51
|
+
type: 'list',
|
|
52
|
+
name: 'type',
|
|
53
|
+
message: 'What would you like to test?',
|
|
54
|
+
choices: [
|
|
55
|
+
{ name: 'š ļø Skill/Tool', value: 'skill' },
|
|
56
|
+
{ name: 'šŖ Webhook', value: 'webhook' },
|
|
57
|
+
{ name: 'ā° Job', value: 'job' },
|
|
58
|
+
{ name: 'š„ PreProcessor', value: 'preprocessor' },
|
|
59
|
+
{ name: 'š¤ PostProcessor', value: 'postprocessor' }
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
]);
|
|
63
|
+
if (!typeAnswer) {
|
|
64
|
+
console.log("Test cancelled.");
|
|
65
|
+
return;
|
|
96
66
|
}
|
|
67
|
+
selectedType = typeAnswer.type;
|
|
68
|
+
}
|
|
69
|
+
// Step 3: Route to appropriate function
|
|
70
|
+
if (selectedType === 'skill') {
|
|
71
|
+
await testSkill();
|
|
72
|
+
}
|
|
73
|
+
else if (selectedType === 'webhook') {
|
|
74
|
+
await testWebhook();
|
|
97
75
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
76
|
+
else if (selectedType === 'job') {
|
|
77
|
+
await testJob();
|
|
78
|
+
}
|
|
79
|
+
else if (selectedType === 'preprocessor') {
|
|
80
|
+
await testPreProcessor();
|
|
81
|
+
}
|
|
82
|
+
else if (selectedType === 'postprocessor') {
|
|
83
|
+
await testPostProcessor();
|
|
101
84
|
}
|
|
102
85
|
}, "testing");
|
|
103
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Test a skill/tool interactively.
|
|
89
|
+
*/
|
|
90
|
+
async function testSkill() {
|
|
91
|
+
writeProgress("š§Ŗ Testing Lua skill...");
|
|
92
|
+
// Step 1: Compile the code
|
|
93
|
+
writeProgress("š¦ Compiling code first...");
|
|
94
|
+
await compileCommand();
|
|
95
|
+
// Step 2: Load deploy data and extract tools
|
|
96
|
+
const deployData = readDeployJson();
|
|
97
|
+
const allTools = extractToolsFromDeployData(deployData);
|
|
98
|
+
// Step 3: Load authentication and configuration
|
|
99
|
+
const apiKey = await loadApiKey();
|
|
100
|
+
if (!apiKey) {
|
|
101
|
+
throw new Error("No API key found. Please run 'lua auth configure' first.");
|
|
102
|
+
}
|
|
103
|
+
const config = readSkillConfig();
|
|
104
|
+
const agentId = config?.agent?.agentId;
|
|
105
|
+
if (!agentId) {
|
|
106
|
+
throw new Error("No agent ID found in lua.skill.yaml. Please run 'lua init' first.");
|
|
107
|
+
}
|
|
108
|
+
// Step 4: Load environment variables
|
|
109
|
+
const envVars = loadEnvironmentVariables();
|
|
110
|
+
if (hasEnvFile()) {
|
|
111
|
+
writeProgress(`š Loaded environment variables from .env file`);
|
|
112
|
+
}
|
|
113
|
+
if (hasConfigEnvVars(config)) {
|
|
114
|
+
writeProgress(`š Loaded environment variables from lua.skill.yaml`);
|
|
115
|
+
}
|
|
116
|
+
// Step 5: Let user select a tool
|
|
117
|
+
const selectedTool = await promptToolSelection(allTools);
|
|
118
|
+
clearPromptLines(2);
|
|
119
|
+
writeProgress(`ā
Selected tool: ${selectedTool.name}`);
|
|
120
|
+
// Step 6: Collect input values based on schema
|
|
121
|
+
let inputValues = {};
|
|
122
|
+
const inputSchema = selectedTool.inputSchema;
|
|
123
|
+
if (inputSchema.properties) {
|
|
124
|
+
writeProgress("\nš Enter input values:");
|
|
125
|
+
inputValues = await generatePromptsForObject(inputSchema, '', inputSchema.required || []);
|
|
126
|
+
}
|
|
127
|
+
// Step 7: Execute the tool
|
|
128
|
+
writeProgress("\nš Executing tool...");
|
|
129
|
+
writeProgress(`Input: ${JSON.stringify(inputValues, null, 2)}`);
|
|
130
|
+
const toolCode = decompressCode(selectedTool.execute);
|
|
131
|
+
// Set environment variables for sandbox
|
|
132
|
+
const originalEnv = { ...process.env };
|
|
133
|
+
for (const [key, value] of Object.entries(envVars)) {
|
|
134
|
+
process.env[key] = value;
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
const result = await executeTool({
|
|
138
|
+
toolCode,
|
|
139
|
+
inputs: inputValues,
|
|
140
|
+
apiKey,
|
|
141
|
+
agentId
|
|
142
|
+
});
|
|
143
|
+
writeSuccess("ā
Tool execution successful!");
|
|
144
|
+
console.log(`Output: ${JSON.stringify(result, null, 2)}`);
|
|
145
|
+
}
|
|
146
|
+
catch (executionError) {
|
|
147
|
+
console.error("\nā Tool execution failed:");
|
|
148
|
+
console.error(executionError.message);
|
|
149
|
+
if (executionError.stack) {
|
|
150
|
+
console.error(executionError.stack);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
finally {
|
|
154
|
+
// Restore original environment variables
|
|
155
|
+
process.env = originalEnv;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Test a webhook interactively.
|
|
160
|
+
*/
|
|
161
|
+
async function testWebhook() {
|
|
162
|
+
writeProgress("šŖ Testing webhook...");
|
|
163
|
+
// Step 1: Compile the code
|
|
164
|
+
writeProgress("š¦ Compiling code first...");
|
|
165
|
+
await compileCommand();
|
|
166
|
+
// Step 2: Load configuration
|
|
167
|
+
const config = readSkillConfig();
|
|
168
|
+
const webhooks = config.webhooks || [];
|
|
169
|
+
if (webhooks.length === 0) {
|
|
170
|
+
console.error("ā No webhooks found in configuration.");
|
|
171
|
+
console.log("š” Create a webhook using LuaWebhook in your code.");
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
// Step 3: Load bundled webhook data
|
|
175
|
+
const bundledWebhooksPath = path.join(process.cwd(), 'dist', 'webhooks.json');
|
|
176
|
+
if (!fs.existsSync(bundledWebhooksPath)) {
|
|
177
|
+
console.error("ā Bundled webhook data not found. Please run compilation first.");
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const bundledWebhooks = JSON.parse(fs.readFileSync(bundledWebhooksPath, 'utf8'));
|
|
181
|
+
// Step 4: Select webhook to test
|
|
182
|
+
const webhookAnswer = await safePrompt([
|
|
183
|
+
{
|
|
184
|
+
type: 'list',
|
|
185
|
+
name: 'selectedWebhook',
|
|
186
|
+
message: 'Select a webhook to test:',
|
|
187
|
+
choices: webhooks.map((webhook) => ({
|
|
188
|
+
name: `${webhook.name} (v${webhook.version})`,
|
|
189
|
+
value: webhook
|
|
190
|
+
}))
|
|
191
|
+
}
|
|
192
|
+
]);
|
|
193
|
+
if (!webhookAnswer) {
|
|
194
|
+
console.log("Test cancelled.");
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const selectedWebhook = webhookAnswer.selectedWebhook;
|
|
198
|
+
// Find bundled webhook data
|
|
199
|
+
const bundledWebhook = bundledWebhooks.find((w) => w.name === selectedWebhook.name);
|
|
200
|
+
if (!bundledWebhook || !bundledWebhook.code) {
|
|
201
|
+
console.error("ā Bundled webhook code not found.");
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
// Step 5: Load authentication
|
|
205
|
+
const apiKey = await loadApiKey();
|
|
206
|
+
if (!apiKey) {
|
|
207
|
+
throw new Error("No API key found. Please run 'lua auth configure' first.");
|
|
208
|
+
}
|
|
209
|
+
const agentId = config?.agent?.agentId;
|
|
210
|
+
if (!agentId) {
|
|
211
|
+
throw new Error("No agent ID found in lua.skill.yaml.");
|
|
212
|
+
}
|
|
213
|
+
// Step 6: Collect query parameters based on schema
|
|
214
|
+
let query = {};
|
|
215
|
+
if (bundledWebhook.querySchema && bundledWebhook.querySchema.properties) {
|
|
216
|
+
writeProgress("\nš Enter query parameters:");
|
|
217
|
+
query = await generatePromptsForObject(bundledWebhook.querySchema, '', bundledWebhook.querySchema.required || []);
|
|
218
|
+
}
|
|
219
|
+
// Step 7: Collect headers based on schema
|
|
220
|
+
let headers = {};
|
|
221
|
+
if (bundledWebhook.headerSchema && bundledWebhook.headerSchema.properties) {
|
|
222
|
+
writeProgress("\nš Enter headers:");
|
|
223
|
+
headers = await generatePromptsForObject(bundledWebhook.headerSchema, '', bundledWebhook.headerSchema.required || []);
|
|
224
|
+
}
|
|
225
|
+
// Step 8: Collect body based on schema
|
|
226
|
+
let body = {};
|
|
227
|
+
if (bundledWebhook.bodySchema && bundledWebhook.bodySchema.properties) {
|
|
228
|
+
writeProgress("\nš Enter request body:");
|
|
229
|
+
body = await generatePromptsForObject(bundledWebhook.bodySchema, '', bundledWebhook.bodySchema.required || []);
|
|
230
|
+
}
|
|
231
|
+
// Step 9: Execute webhook through sandbox
|
|
232
|
+
writeProgress("\nš Executing webhook...");
|
|
233
|
+
writeProgress(`Query: ${JSON.stringify(query, null, 2)}`);
|
|
234
|
+
writeProgress(`Headers: ${JSON.stringify(headers, null, 2)}`);
|
|
235
|
+
writeProgress(`Body: ${JSON.stringify(body, null, 2)}`);
|
|
236
|
+
const webhookCode = decompressCode(bundledWebhook.code);
|
|
237
|
+
// Load environment variables
|
|
238
|
+
const envVars = loadEnvironmentVariables();
|
|
239
|
+
const originalEnv = { ...process.env };
|
|
240
|
+
for (const [key, value] of Object.entries(envVars)) {
|
|
241
|
+
process.env[key] = value;
|
|
242
|
+
}
|
|
243
|
+
try {
|
|
244
|
+
const result = await executeWebhook({
|
|
245
|
+
webhookCode,
|
|
246
|
+
query,
|
|
247
|
+
headers,
|
|
248
|
+
body,
|
|
249
|
+
apiKey,
|
|
250
|
+
agentId
|
|
251
|
+
});
|
|
252
|
+
writeSuccess("\nā
Webhook execution successful!");
|
|
253
|
+
console.log(`Output: ${JSON.stringify(result, null, 2)}`);
|
|
254
|
+
}
|
|
255
|
+
catch (executionError) {
|
|
256
|
+
console.error("\nā Webhook execution failed:");
|
|
257
|
+
console.error(executionError.message);
|
|
258
|
+
if (executionError.stack) {
|
|
259
|
+
console.error(executionError.stack);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
finally {
|
|
263
|
+
// Restore original environment variables
|
|
264
|
+
process.env = originalEnv;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Test a job by manually triggering it.
|
|
269
|
+
*/
|
|
270
|
+
async function testJob() {
|
|
271
|
+
writeProgress("ā° Testing job...");
|
|
272
|
+
// Step 1: Compile the code
|
|
273
|
+
writeProgress("š¦ Compiling code first...");
|
|
274
|
+
await compileCommand();
|
|
275
|
+
// Step 2: Load configuration
|
|
276
|
+
const apiKey = await loadApiKey();
|
|
277
|
+
if (!apiKey) {
|
|
278
|
+
throw new Error("No API key found. Please run 'lua auth configure' first.");
|
|
279
|
+
}
|
|
280
|
+
const config = readSkillConfig();
|
|
281
|
+
const agentId = config?.agent?.agentId;
|
|
282
|
+
if (!agentId) {
|
|
283
|
+
throw new Error("No agent ID found in lua.skill.yaml.");
|
|
284
|
+
}
|
|
285
|
+
const jobs = config.jobs || [];
|
|
286
|
+
if (jobs.length === 0) {
|
|
287
|
+
console.error("ā No jobs found in configuration.");
|
|
288
|
+
console.log("š” Create a job using LuaJob in your code.");
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
// Step 3: Load bundled job data
|
|
292
|
+
const bundledJobsPath = path.join(process.cwd(), 'dist', 'jobs.json');
|
|
293
|
+
if (!fs.existsSync(bundledJobsPath)) {
|
|
294
|
+
console.error("ā Bundled job data not found. Please run compilation first.");
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
const bundledJobs = JSON.parse(fs.readFileSync(bundledJobsPath, 'utf8'));
|
|
298
|
+
// Step 4: Select job to test
|
|
299
|
+
const jobAnswer = await safePrompt([
|
|
300
|
+
{
|
|
301
|
+
type: 'list',
|
|
302
|
+
name: 'selectedJob',
|
|
303
|
+
message: 'Select a job to test:',
|
|
304
|
+
choices: jobs.map((job) => ({
|
|
305
|
+
name: `${job.name} (v${job.version}) - ${formatSchedule(job.schedule)}`,
|
|
306
|
+
value: job
|
|
307
|
+
}))
|
|
308
|
+
}
|
|
309
|
+
]);
|
|
310
|
+
if (!jobAnswer) {
|
|
311
|
+
console.log("Test cancelled.");
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
const selectedJob = jobAnswer.selectedJob;
|
|
315
|
+
// Find bundled job data
|
|
316
|
+
const bundledJob = bundledJobs.find((j) => j.name === selectedJob.name);
|
|
317
|
+
if (!bundledJob || !bundledJob.code) {
|
|
318
|
+
console.error("ā Bundled job code not found.");
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
// Step 5: Execute job through sandbox
|
|
322
|
+
writeProgress(`\nš Executing job: ${selectedJob.name}...`);
|
|
323
|
+
writeProgress(`š
Schedule: ${formatSchedule(selectedJob.schedule)}`);
|
|
324
|
+
const jobCode = decompressCode(bundledJob.code);
|
|
325
|
+
// Load environment variables
|
|
326
|
+
const envVars = loadEnvironmentVariables();
|
|
327
|
+
const originalEnv = { ...process.env };
|
|
328
|
+
for (const [key, value] of Object.entries(envVars)) {
|
|
329
|
+
process.env[key] = value;
|
|
330
|
+
}
|
|
331
|
+
try {
|
|
332
|
+
const result = await executeJob({
|
|
333
|
+
jobCode,
|
|
334
|
+
apiKey,
|
|
335
|
+
agentId,
|
|
336
|
+
jobData: {
|
|
337
|
+
id: selectedJob.jobId,
|
|
338
|
+
jobId: selectedJob.jobId,
|
|
339
|
+
name: selectedJob.name,
|
|
340
|
+
schedule: selectedJob.schedule,
|
|
341
|
+
metadata: bundledJob.metadata || selectedJob.metadata || {}
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
writeSuccess("\nā
Job execution successful!");
|
|
345
|
+
console.log(`Output: ${JSON.stringify(result, null, 2)}`);
|
|
346
|
+
}
|
|
347
|
+
catch (executionError) {
|
|
348
|
+
console.error("\nā Job execution failed:");
|
|
349
|
+
console.error(executionError.message);
|
|
350
|
+
if (executionError.stack) {
|
|
351
|
+
console.error(executionError.stack);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
finally {
|
|
355
|
+
// Restore original environment variables
|
|
356
|
+
process.env = originalEnv;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Test a preprocessor interactively.
|
|
361
|
+
*/
|
|
362
|
+
async function testPreProcessor() {
|
|
363
|
+
writeProgress("š„ Testing preprocessor...");
|
|
364
|
+
// Step 1: Compile the code
|
|
365
|
+
writeProgress("š¦ Compiling code first...");
|
|
366
|
+
await compileCommand();
|
|
367
|
+
// Step 2: Load bundled preprocessor data
|
|
368
|
+
const preprocessorsPath = path.join(process.cwd(), 'dist', 'preprocessors.json');
|
|
369
|
+
if (!fs.existsSync(preprocessorsPath)) {
|
|
370
|
+
console.error("ā No preprocessors found. Create a PreProcessor in your code.");
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
const preprocessors = JSON.parse(fs.readFileSync(preprocessorsPath, 'utf8'));
|
|
374
|
+
if (preprocessors.length === 0) {
|
|
375
|
+
console.error("ā No preprocessors found.");
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
// Step 3: Select preprocessor to test
|
|
379
|
+
const preprocessorAnswer = await safePrompt([
|
|
380
|
+
{
|
|
381
|
+
type: 'list',
|
|
382
|
+
name: 'selected',
|
|
383
|
+
message: 'Select a preprocessor to test:',
|
|
384
|
+
choices: preprocessors.map((p) => ({
|
|
385
|
+
name: `${p.name} (v${p.version})`,
|
|
386
|
+
value: p
|
|
387
|
+
}))
|
|
388
|
+
}
|
|
389
|
+
]);
|
|
390
|
+
if (!preprocessorAnswer)
|
|
391
|
+
return;
|
|
392
|
+
const selected = preprocessorAnswer.selected;
|
|
393
|
+
if (!selected.code) {
|
|
394
|
+
console.error("ā Preprocessor code not found.");
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
// Step 4: Collect test inputs
|
|
398
|
+
const messageAnswer = await safePrompt([
|
|
399
|
+
{
|
|
400
|
+
type: 'input',
|
|
401
|
+
name: 'message',
|
|
402
|
+
message: 'Enter test message:',
|
|
403
|
+
default: 'Hello, I need help with my order'
|
|
404
|
+
}
|
|
405
|
+
]);
|
|
406
|
+
if (!messageAnswer)
|
|
407
|
+
return;
|
|
408
|
+
const channelAnswer = await safePrompt([
|
|
409
|
+
{
|
|
410
|
+
type: 'input',
|
|
411
|
+
name: 'channel',
|
|
412
|
+
message: 'Enter channel:',
|
|
413
|
+
default: 'web'
|
|
414
|
+
}
|
|
415
|
+
]);
|
|
416
|
+
if (!channelAnswer)
|
|
417
|
+
return;
|
|
418
|
+
// Step 5: Execute preprocessor
|
|
419
|
+
writeProgress("\nš Executing preprocessor...");
|
|
420
|
+
writeProgress(`Input message: ${messageAnswer.message}`);
|
|
421
|
+
writeProgress(`Channel: ${channelAnswer.channel}`);
|
|
422
|
+
const apiKey = await loadApiKey();
|
|
423
|
+
if (!apiKey)
|
|
424
|
+
throw new Error("No API key found.");
|
|
425
|
+
const config = readSkillConfig();
|
|
426
|
+
const agentId = config?.agent?.agentId;
|
|
427
|
+
if (!agentId)
|
|
428
|
+
throw new Error("No agent ID found.");
|
|
429
|
+
const preprocessorCode = decompressCode(selected.code);
|
|
430
|
+
// Load environment variables
|
|
431
|
+
const envVars = loadEnvironmentVariables();
|
|
432
|
+
const originalEnv = { ...process.env };
|
|
433
|
+
for (const [key, value] of Object.entries(envVars)) {
|
|
434
|
+
process.env[key] = value;
|
|
435
|
+
}
|
|
436
|
+
try {
|
|
437
|
+
const result = await executePreProcessor({
|
|
438
|
+
processorCode: preprocessorCode,
|
|
439
|
+
message: messageAnswer.message,
|
|
440
|
+
channel: channelAnswer.channel,
|
|
441
|
+
apiKey,
|
|
442
|
+
agentId
|
|
443
|
+
});
|
|
444
|
+
writeSuccess("\nā
PreProcessor execution successful!");
|
|
445
|
+
console.log(`Processed message: ${result}`);
|
|
446
|
+
}
|
|
447
|
+
catch (error) {
|
|
448
|
+
console.error("\nā PreProcessor execution failed:");
|
|
449
|
+
console.error(error.message);
|
|
450
|
+
}
|
|
451
|
+
finally {
|
|
452
|
+
process.env = originalEnv;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Test a postprocessor interactively.
|
|
457
|
+
*/
|
|
458
|
+
async function testPostProcessor() {
|
|
459
|
+
writeProgress("š¤ Testing postprocessor...");
|
|
460
|
+
// Step 1: Compile the code
|
|
461
|
+
writeProgress("š¦ Compiling code first...");
|
|
462
|
+
await compileCommand();
|
|
463
|
+
// Step 2: Load bundled postprocessor data
|
|
464
|
+
const postprocessorsPath = path.join(process.cwd(), 'dist', 'postprocessors.json');
|
|
465
|
+
if (!fs.existsSync(postprocessorsPath)) {
|
|
466
|
+
console.error("ā No postprocessors found. Create a PostProcessor in your code.");
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
const postprocessors = JSON.parse(fs.readFileSync(postprocessorsPath, 'utf8'));
|
|
470
|
+
if (postprocessors.length === 0) {
|
|
471
|
+
console.error("ā No postprocessors found.");
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
// Step 3: Select postprocessor to test
|
|
475
|
+
const postprocessorAnswer = await safePrompt([
|
|
476
|
+
{
|
|
477
|
+
type: 'list',
|
|
478
|
+
name: 'selected',
|
|
479
|
+
message: 'Select a postprocessor to test:',
|
|
480
|
+
choices: postprocessors.map((p) => ({
|
|
481
|
+
name: `${p.name} (v${p.version})`,
|
|
482
|
+
value: p
|
|
483
|
+
}))
|
|
484
|
+
}
|
|
485
|
+
]);
|
|
486
|
+
if (!postprocessorAnswer)
|
|
487
|
+
return;
|
|
488
|
+
const selected = postprocessorAnswer.selected;
|
|
489
|
+
if (!selected.code) {
|
|
490
|
+
console.error("ā Postprocessor code not found.");
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
// Step 4: Collect test inputs
|
|
494
|
+
const messageAnswer = await safePrompt([
|
|
495
|
+
{
|
|
496
|
+
type: 'input',
|
|
497
|
+
name: 'message',
|
|
498
|
+
message: 'Enter original user message:',
|
|
499
|
+
default: 'What products do you have?'
|
|
500
|
+
}
|
|
501
|
+
]);
|
|
502
|
+
if (!messageAnswer)
|
|
503
|
+
return;
|
|
504
|
+
const responseAnswer = await safePrompt([
|
|
505
|
+
{
|
|
506
|
+
type: 'input',
|
|
507
|
+
name: 'response',
|
|
508
|
+
message: 'Enter agent response to process:',
|
|
509
|
+
default: 'We have laptops, phones, and tablets available.'
|
|
510
|
+
}
|
|
511
|
+
]);
|
|
512
|
+
if (!responseAnswer)
|
|
513
|
+
return;
|
|
514
|
+
const channelAnswer = await safePrompt([
|
|
515
|
+
{
|
|
516
|
+
type: 'input',
|
|
517
|
+
name: 'channel',
|
|
518
|
+
message: 'Enter channel:',
|
|
519
|
+
default: 'web'
|
|
520
|
+
}
|
|
521
|
+
]);
|
|
522
|
+
if (!channelAnswer)
|
|
523
|
+
return;
|
|
524
|
+
// Step 5: Execute postprocessor
|
|
525
|
+
writeProgress("\nš Executing postprocessor...");
|
|
526
|
+
writeProgress(`Original message: ${messageAnswer.message}`);
|
|
527
|
+
writeProgress(`Agent response: ${responseAnswer.response}`);
|
|
528
|
+
writeProgress(`Channel: ${channelAnswer.channel}`);
|
|
529
|
+
const apiKey = await loadApiKey();
|
|
530
|
+
if (!apiKey)
|
|
531
|
+
throw new Error("No API key found.");
|
|
532
|
+
const config = readSkillConfig();
|
|
533
|
+
const agentId = config?.agent?.agentId;
|
|
534
|
+
if (!agentId)
|
|
535
|
+
throw new Error("No agent ID found.");
|
|
536
|
+
const postprocessorCode = decompressCode(selected.code);
|
|
537
|
+
// Load environment variables
|
|
538
|
+
const envVars = loadEnvironmentVariables();
|
|
539
|
+
const originalEnv = { ...process.env };
|
|
540
|
+
for (const [key, value] of Object.entries(envVars)) {
|
|
541
|
+
process.env[key] = value;
|
|
542
|
+
}
|
|
543
|
+
try {
|
|
544
|
+
const result = await executePostProcessor({
|
|
545
|
+
processorCode: postprocessorCode,
|
|
546
|
+
message: messageAnswer.message,
|
|
547
|
+
response: responseAnswer.response,
|
|
548
|
+
channel: channelAnswer.channel,
|
|
549
|
+
apiKey,
|
|
550
|
+
agentId
|
|
551
|
+
});
|
|
552
|
+
writeSuccess("\nā
PostProcessor execution successful!");
|
|
553
|
+
console.log(`Processed response: ${result}`);
|
|
554
|
+
}
|
|
555
|
+
catch (error) {
|
|
556
|
+
console.error("\nā PostProcessor execution failed:");
|
|
557
|
+
console.error(error.message);
|
|
558
|
+
}
|
|
559
|
+
finally {
|
|
560
|
+
process.env = originalEnv;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* Format schedule for display
|
|
565
|
+
*/
|
|
566
|
+
function formatSchedule(schedule) {
|
|
567
|
+
if (!schedule)
|
|
568
|
+
return 'Not configured';
|
|
569
|
+
switch (schedule.type) {
|
|
570
|
+
case 'cron':
|
|
571
|
+
return `Cron: ${schedule.expression}${schedule.timezone ? ` (${schedule.timezone})` : ''}`;
|
|
572
|
+
case 'once':
|
|
573
|
+
return `Once at: ${new Date(schedule.executeAt).toLocaleString()}`;
|
|
574
|
+
case 'interval':
|
|
575
|
+
return `Every ${schedule.seconds} seconds`;
|
|
576
|
+
default:
|
|
577
|
+
return 'Unknown schedule type';
|
|
578
|
+
}
|
|
579
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhooks Command
|
|
3
|
+
* Manages agent webhooks for sandbox and production environments
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Main webhooks command - manages agent webhooks
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - View deployed webhooks
|
|
10
|
+
* - View webhook versions
|
|
11
|
+
* - Deploy webhook versions to production
|
|
12
|
+
* - Activate/deactivate webhooks
|
|
13
|
+
*
|
|
14
|
+
* Note: For local testing, use `lua test webhook`
|
|
15
|
+
*
|
|
16
|
+
* @returns Promise that resolves when command completes
|
|
17
|
+
*/
|
|
18
|
+
export declare function webhooksCommand(): Promise<void>;
|