lua-cli 3.2.0 ā 3.4.0
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/logs.api.service.d.ts +1 -1
- package/dist/api/logs.api.service.js.map +1 -1
- package/dist/api/products.api.service.d.ts +17 -5
- package/dist/api/products.api.service.js +21 -9
- package/dist/api/products.api.service.js.map +1 -1
- package/dist/api/webhook.api.service.d.ts +4 -0
- package/dist/api/webhook.api.service.js.map +1 -1
- package/dist/api-exports.d.ts +19 -7
- package/dist/api-exports.js +20 -5
- package/dist/api-exports.js.map +1 -1
- package/dist/cli/command-definitions.js +323 -88
- package/dist/cli/command-definitions.js.map +1 -1
- package/dist/commands/apiKey.d.ts +5 -2
- package/dist/commands/apiKey.js +8 -2
- package/dist/commands/apiKey.js.map +1 -1
- package/dist/commands/channels.d.ts +4 -9
- package/dist/commands/channels.js +140 -84
- package/dist/commands/channels.js.map +1 -1
- package/dist/commands/chat.d.ts +4 -2
- package/dist/commands/chat.js +126 -32
- package/dist/commands/chat.js.map +1 -1
- package/dist/commands/chatClear.d.ts +3 -2
- package/dist/commands/chatClear.js +16 -15
- package/dist/commands/chatClear.js.map +1 -1
- package/dist/commands/compile.d.ts +5 -4
- package/dist/commands/compile.js +73 -9
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/deploy.d.ts +5 -24
- package/dist/commands/deploy.js +75 -48
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/destroy.d.ts +5 -2
- package/dist/commands/destroy.js +14 -2
- package/dist/commands/destroy.js.map +1 -1
- package/dist/commands/env.d.ts +3 -1
- package/dist/commands/env.js +322 -122
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/features.d.ts +5 -9
- package/dist/commands/features.js +249 -129
- package/dist/commands/features.js.map +1 -1
- package/dist/commands/init.d.ts +7 -1
- package/dist/commands/init.js +242 -59
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/jobs.d.ts +5 -13
- package/dist/commands/jobs.js +523 -360
- package/dist/commands/jobs.js.map +1 -1
- package/dist/commands/logs.d.ts +5 -10
- package/dist/commands/logs.js +259 -103
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/marketplace.d.ts +23 -2
- package/dist/commands/marketplace.js +530 -7
- package/dist/commands/marketplace.js.map +1 -1
- package/dist/commands/mcp.d.ts +5 -11
- package/dist/commands/mcp.js +304 -294
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/persona.d.ts +5 -9
- package/dist/commands/persona.js +349 -232
- package/dist/commands/persona.js.map +1 -1
- package/dist/commands/postprocessors.d.ts +6 -2
- package/dist/commands/postprocessors.js +387 -280
- package/dist/commands/postprocessors.js.map +1 -1
- package/dist/commands/preprocessors.d.ts +6 -2
- package/dist/commands/preprocessors.js +387 -280
- package/dist/commands/preprocessors.js.map +1 -1
- package/dist/commands/production.d.ts +5 -8
- package/dist/commands/production.js +317 -228
- package/dist/commands/production.js.map +1 -1
- package/dist/commands/push.js +385 -427
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/resources.d.ts +5 -10
- package/dist/commands/resources.js +219 -154
- package/dist/commands/resources.js.map +1 -1
- package/dist/commands/skills.d.ts +5 -9
- package/dist/commands/skills.js +435 -275
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/sync.d.ts +10 -8
- package/dist/commands/sync.js +110 -19
- package/dist/commands/sync.js.map +1 -1
- package/dist/commands/test.d.ts +1 -11
- package/dist/commands/test.js +395 -438
- package/dist/commands/test.js.map +1 -1
- package/dist/commands/webhooks.d.ts +5 -11
- package/dist/commands/webhooks.js +431 -287
- package/dist/commands/webhooks.js.map +1 -1
- package/dist/interfaces/index.d.ts +1 -1
- package/dist/interfaces/mcp.d.ts +39 -19
- package/dist/interfaces/mcp.js +3 -0
- package/dist/interfaces/mcp.js.map +1 -1
- package/dist/interfaces/product.d.ts +26 -0
- package/dist/interfaces/skills.d.ts +5 -0
- package/dist/types/api-contracts.d.ts +8 -4
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/skill.d.ts +146 -35
- package/dist/types/skill.js +31 -37
- package/dist/types/skill.js.map +1 -1
- package/dist/utils/bundling.d.ts +17 -0
- package/dist/utils/bundling.js +96 -0
- package/dist/utils/bundling.js.map +1 -1
- package/dist/utils/compile.d.ts +4 -0
- package/dist/utils/compile.js +5 -0
- package/dist/utils/compile.js.map +1 -1
- package/dist/utils/dev-helpers.d.ts +3 -2
- package/dist/utils/dev-helpers.js +3 -5
- package/dist/utils/dev-helpers.js.map +1 -1
- package/dist/utils/job-management.d.ts +4 -1
- package/dist/utils/job-management.js +15 -29
- package/dist/utils/job-management.js.map +1 -1
- package/dist/utils/mcp-server-management.d.ts +5 -2
- package/dist/utils/mcp-server-management.js +27 -43
- package/dist/utils/mcp-server-management.js.map +1 -1
- package/dist/utils/push-helpers.d.ts +1 -1
- package/dist/utils/push-helpers.js +5 -1
- package/dist/utils/push-helpers.js.map +1 -1
- package/dist/utils/skill-management.d.ts +7 -2
- package/dist/utils/skill-management.js +21 -30
- package/dist/utils/skill-management.js.map +1 -1
- package/dist/utils/webhook-management.d.ts +4 -1
- package/dist/utils/webhook-management.js +15 -29
- package/dist/utils/webhook-management.js.map +1 -1
- package/package.json +1 -1
- package/template/package.json +1 -1
package/dist/commands/test.js
CHANGED
|
@@ -12,26 +12,121 @@ import { readSkillConfig } from "../utils/files.js";
|
|
|
12
12
|
import { safePrompt } from "../utils/prompt-handler.js";
|
|
13
13
|
import { decompressCode, readDeployJson, extractToolsFromDeployData, hasEnvFile, } from "../utils/test-helpers.js";
|
|
14
14
|
import { promptToolSelection, generatePromptsForObject } from "../utils/test-prompts.js";
|
|
15
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
16
|
+
// Shared Helpers
|
|
17
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
18
|
+
/**
|
|
19
|
+
* Loads API key and agent ID, failing with clear error if not configured.
|
|
20
|
+
*/
|
|
21
|
+
async function loadAuthOrFail() {
|
|
22
|
+
const apiKey = await loadApiKey();
|
|
23
|
+
if (!apiKey) {
|
|
24
|
+
throw new Error("No API key found. Please run 'lua auth configure' first.");
|
|
25
|
+
}
|
|
26
|
+
const config = readSkillConfig();
|
|
27
|
+
const agentId = config?.agent?.agentId;
|
|
28
|
+
if (!agentId) {
|
|
29
|
+
throw new Error("No agent ID found in lua.skill.yaml. Please run 'lua init' first.");
|
|
30
|
+
}
|
|
31
|
+
return { apiKey, agentId, config };
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Wraps execution with sandbox environment (env vars setup/teardown).
|
|
35
|
+
*/
|
|
36
|
+
async function withSandboxEnv(fn) {
|
|
37
|
+
const envVars = loadEnvironmentVariables();
|
|
38
|
+
const originalEnv = { ...process.env };
|
|
39
|
+
for (const [key, value] of Object.entries(envVars)) {
|
|
40
|
+
process.env[key] = value;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
return await fn();
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
process.env = originalEnv;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Loads bundled JSON data from dist folder, failing with clear error if not found.
|
|
51
|
+
*/
|
|
52
|
+
function loadBundledJsonOrFail(filename, entityType) {
|
|
53
|
+
const filePath = path.join(process.cwd(), 'dist', filename);
|
|
54
|
+
if (!fs.existsSync(filePath)) {
|
|
55
|
+
console.error(`ā Bundled ${entityType} data not found. Please run compilation first.`);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
const data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
59
|
+
if (Array.isArray(data) && data.length === 0) {
|
|
60
|
+
console.error(`ā No ${entityType}s found.`);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
return data;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Parses JSON input, failing with formatted error message.
|
|
67
|
+
*/
|
|
68
|
+
function parseJsonInputOrFail(inputJson, expectedFormat) {
|
|
69
|
+
try {
|
|
70
|
+
return JSON.parse(inputJson);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
console.error(`ā Invalid JSON input: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
74
|
+
console.log(`Expected format: ${expectedFormat}`);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Selects an entity by name (non-interactive) or prompts user (interactive).
|
|
80
|
+
*/
|
|
81
|
+
async function selectEntityOrPrompt(options) {
|
|
82
|
+
const { items, entityName, entityType, idProperty, nameProperty, promptMessage, formatChoice } = options;
|
|
83
|
+
if (entityName) {
|
|
84
|
+
const selected = items.find((item) => item[idProperty] === entityName || item[nameProperty] === entityName);
|
|
85
|
+
if (!selected) {
|
|
86
|
+
console.error(`ā ${entityType} "${entityName}" not found`);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
writeProgress(`ā
Selected ${entityType.toLowerCase()}: ${selected[nameProperty]}`);
|
|
90
|
+
return selected;
|
|
91
|
+
}
|
|
92
|
+
const answer = await safePrompt([
|
|
93
|
+
{
|
|
94
|
+
type: 'list',
|
|
95
|
+
name: 'selected',
|
|
96
|
+
message: promptMessage,
|
|
97
|
+
choices: items.map((item) => ({
|
|
98
|
+
name: formatChoice ? formatChoice(item) : `${item[nameProperty]}`,
|
|
99
|
+
value: item
|
|
100
|
+
}))
|
|
101
|
+
}
|
|
102
|
+
]);
|
|
103
|
+
if (!answer)
|
|
104
|
+
return null;
|
|
105
|
+
return answer.selected;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Handles execution errors with consistent formatting.
|
|
109
|
+
*/
|
|
110
|
+
function handleExecutionError(error, entityType) {
|
|
111
|
+
console.error(`\nā ${entityType} execution failed:`);
|
|
112
|
+
console.error(error.message);
|
|
113
|
+
if (error.stack) {
|
|
114
|
+
console.error(error.stack);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
118
|
+
// Main Command
|
|
119
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
15
120
|
/**
|
|
16
121
|
* Main test command - tests tools, webhooks, jobs, preprocessors, or postprocessors.
|
|
17
|
-
*
|
|
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
|
|
24
|
-
*
|
|
25
|
-
* @param type - Optional type argument ('skill', 'webhook', 'job', 'preprocessor', 'postprocessor')
|
|
26
|
-
* @returns Promise that resolves when test completes
|
|
27
122
|
*/
|
|
28
|
-
export async function testCommand(type) {
|
|
123
|
+
export async function testCommand(type, cmdObj) {
|
|
29
124
|
return withErrorHandling(async () => {
|
|
125
|
+
const entityName = cmdObj?.name || null;
|
|
126
|
+
const inputJson = cmdObj?.input || null;
|
|
30
127
|
let selectedType;
|
|
31
|
-
// Step 1: Check if type was provided as argument
|
|
32
128
|
if (type) {
|
|
33
|
-
|
|
34
|
-
if (type !== 'skill' && type !== 'webhook' && type !== 'job' && type !== 'preprocessor' && type !== 'postprocessor') {
|
|
129
|
+
if (!['skill', 'webhook', 'job', 'preprocessor', 'postprocessor'].includes(type)) {
|
|
35
130
|
console.error(`ā Invalid type: "${type}". Must be "skill", "webhook", "job", "preprocessor", or "postprocessor".`);
|
|
36
131
|
console.log('\nUsage:');
|
|
37
132
|
console.log(' lua test - Interactive selection');
|
|
@@ -44,8 +139,14 @@ export async function testCommand(type) {
|
|
|
44
139
|
}
|
|
45
140
|
selectedType = type;
|
|
46
141
|
}
|
|
142
|
+
else if (entityName) {
|
|
143
|
+
console.error(`ā Type must be specified when using the --name option.`);
|
|
144
|
+
console.log('\nUsage:');
|
|
145
|
+
console.log(' lua test skill --name mySkill --input "{...}" Test skill with JSON input');
|
|
146
|
+
console.log(' lua test webhook --name myWebhook --input "{...}" Test webhook with JSON input');
|
|
147
|
+
process.exit(1);
|
|
148
|
+
}
|
|
47
149
|
else {
|
|
48
|
-
// Step 2: Prompt for type selection
|
|
49
150
|
const typeAnswer = await safePrompt([
|
|
50
151
|
{
|
|
51
152
|
type: 'list',
|
|
@@ -66,517 +167,373 @@ export async function testCommand(type) {
|
|
|
66
167
|
}
|
|
67
168
|
selectedType = typeAnswer.type;
|
|
68
169
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
170
|
+
switch (selectedType) {
|
|
171
|
+
case 'skill':
|
|
172
|
+
await testSkill(entityName, inputJson);
|
|
173
|
+
break;
|
|
174
|
+
case 'webhook':
|
|
175
|
+
await testWebhook(entityName, inputJson);
|
|
176
|
+
break;
|
|
177
|
+
case 'job':
|
|
178
|
+
await testJob(entityName);
|
|
179
|
+
break;
|
|
180
|
+
case 'preprocessor':
|
|
181
|
+
await testPreProcessor(entityName, inputJson);
|
|
182
|
+
break;
|
|
183
|
+
case 'postprocessor':
|
|
184
|
+
await testPostProcessor(entityName, inputJson);
|
|
185
|
+
break;
|
|
84
186
|
}
|
|
85
187
|
}, "testing");
|
|
86
188
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
async function testSkill() {
|
|
189
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
190
|
+
// Test Functions
|
|
191
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
192
|
+
async function testSkill(entityName, inputJson) {
|
|
91
193
|
writeProgress("š§Ŗ Testing Lua skill...");
|
|
92
|
-
// Step 1: Compile the code
|
|
93
194
|
writeProgress("š¦ Compiling code first...");
|
|
94
195
|
await compileCommand();
|
|
95
|
-
// Step 2: Load deploy data and extract tools
|
|
96
196
|
const deployData = readDeployJson();
|
|
97
197
|
const allTools = extractToolsFromDeployData(deployData);
|
|
98
|
-
|
|
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();
|
|
198
|
+
const { apiKey, agentId } = await loadAuthOrFail();
|
|
110
199
|
if (hasEnvFile()) {
|
|
111
200
|
writeProgress(`š Loaded environment variables from .env file`);
|
|
112
201
|
}
|
|
113
|
-
//
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
202
|
+
// Select tool
|
|
203
|
+
let selectedTool;
|
|
204
|
+
if (entityName) {
|
|
205
|
+
selectedTool = allTools.find((t) => t.id === entityName || t.name === entityName);
|
|
206
|
+
if (!selectedTool) {
|
|
207
|
+
console.error(`ā Tool "${entityName}" not found`);
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
writeProgress(`ā
Selected tool: ${selectedTool.name}`);
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
selectedTool = await promptToolSelection(allTools);
|
|
214
|
+
clearPromptLines(2);
|
|
215
|
+
writeProgress(`ā
Selected tool: ${selectedTool.name}`);
|
|
216
|
+
}
|
|
217
|
+
// Get input values
|
|
118
218
|
let inputValues = {};
|
|
119
219
|
const inputSchema = selectedTool.inputSchema;
|
|
120
|
-
if (
|
|
220
|
+
if (inputJson) {
|
|
221
|
+
inputValues = parseJsonInputOrFail(inputJson, '{"param1": "value1", ...}');
|
|
222
|
+
writeProgress(`Input: ${JSON.stringify(inputValues, null, 2)}`);
|
|
223
|
+
}
|
|
224
|
+
else if (inputSchema && inputSchema.properties) {
|
|
121
225
|
writeProgress("\nš Enter input values:");
|
|
122
226
|
inputValues = await generatePromptsForObject(inputSchema, '', inputSchema.required || []);
|
|
123
227
|
}
|
|
124
|
-
//
|
|
228
|
+
// Execute
|
|
125
229
|
writeProgress("\nš Executing tool...");
|
|
126
|
-
writeProgress(`Input: ${JSON.stringify(inputValues, null, 2)}`);
|
|
127
230
|
const toolCode = decompressCode(selectedTool.execute);
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
channel: 'dev',
|
|
140
|
-
});
|
|
141
|
-
writeSuccess("ā
Tool execution successful!");
|
|
142
|
-
console.log(`Output: ${JSON.stringify(result, null, 2)}`);
|
|
143
|
-
}
|
|
144
|
-
catch (executionError) {
|
|
145
|
-
console.error("\nā Tool execution failed:");
|
|
146
|
-
console.error(executionError.message);
|
|
147
|
-
if (executionError.stack) {
|
|
148
|
-
console.error(executionError.stack);
|
|
231
|
+
await withSandboxEnv(async () => {
|
|
232
|
+
try {
|
|
233
|
+
const result = await executeTool({
|
|
234
|
+
toolCode,
|
|
235
|
+
inputs: inputValues,
|
|
236
|
+
apiKey,
|
|
237
|
+
agentId,
|
|
238
|
+
channel: 'dev',
|
|
239
|
+
});
|
|
240
|
+
writeSuccess("ā
Tool execution successful!");
|
|
241
|
+
console.log(`Output: ${JSON.stringify(result, null, 2)}`);
|
|
149
242
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
handleExecutionError(error, 'Tool');
|
|
245
|
+
}
|
|
246
|
+
});
|
|
155
247
|
}
|
|
156
|
-
|
|
157
|
-
* Test a webhook interactively.
|
|
158
|
-
*/
|
|
159
|
-
async function testWebhook() {
|
|
248
|
+
async function testWebhook(entityName, inputJson) {
|
|
160
249
|
writeProgress("šŖ Testing webhook...");
|
|
161
|
-
// Step 1: Compile the code
|
|
162
250
|
writeProgress("š¦ Compiling code first...");
|
|
163
251
|
await compileCommand();
|
|
164
|
-
|
|
165
|
-
const config = readSkillConfig();
|
|
252
|
+
const { apiKey, agentId, config } = await loadAuthOrFail();
|
|
166
253
|
const webhooks = config.webhooks || [];
|
|
167
254
|
if (webhooks.length === 0) {
|
|
168
255
|
console.error("ā No webhooks found in configuration.");
|
|
169
256
|
console.log("š” Create a webhook using LuaWebhook in your code.");
|
|
170
257
|
return;
|
|
171
258
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
{
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
message: 'Select a webhook to test:',
|
|
185
|
-
choices: webhooks.map((webhook) => ({
|
|
186
|
-
name: `${webhook.name} (v${webhook.version})`,
|
|
187
|
-
value: webhook
|
|
188
|
-
}))
|
|
189
|
-
}
|
|
190
|
-
]);
|
|
191
|
-
if (!webhookAnswer) {
|
|
259
|
+
const bundledWebhooks = loadBundledJsonOrFail('webhooks.json', 'webhook');
|
|
260
|
+
// Select webhook
|
|
261
|
+
const selectedWebhook = await selectEntityOrPrompt({
|
|
262
|
+
items: webhooks,
|
|
263
|
+
entityName,
|
|
264
|
+
entityType: 'Webhook',
|
|
265
|
+
idProperty: 'webhookId',
|
|
266
|
+
nameProperty: 'name',
|
|
267
|
+
promptMessage: 'Select a webhook to test:',
|
|
268
|
+
formatChoice: (w) => `${w.name} (v${w.version})`
|
|
269
|
+
});
|
|
270
|
+
if (!selectedWebhook) {
|
|
192
271
|
console.log("Test cancelled.");
|
|
193
272
|
return;
|
|
194
273
|
}
|
|
195
|
-
const selectedWebhook = webhookAnswer.selectedWebhook;
|
|
196
|
-
// Find bundled webhook data
|
|
197
274
|
const bundledWebhook = bundledWebhooks.find((w) => w.name === selectedWebhook.name);
|
|
198
275
|
if (!bundledWebhook || !bundledWebhook.code) {
|
|
199
|
-
console.error(
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
// Step 5: Load authentication
|
|
203
|
-
const apiKey = await loadApiKey();
|
|
204
|
-
if (!apiKey) {
|
|
205
|
-
throw new Error("No API key found. Please run 'lua auth configure' first.");
|
|
276
|
+
console.error(`ā Bundled webhook code not found for "${selectedWebhook.name}"`);
|
|
277
|
+
process.exit(1);
|
|
206
278
|
}
|
|
207
|
-
|
|
208
|
-
if (!agentId) {
|
|
209
|
-
throw new Error("No agent ID found in lua.skill.yaml.");
|
|
210
|
-
}
|
|
211
|
-
// Step 6: Collect query parameters based on schema
|
|
279
|
+
// Get inputs
|
|
212
280
|
let query = {};
|
|
213
|
-
if (bundledWebhook.querySchema && bundledWebhook.querySchema.properties) {
|
|
214
|
-
writeProgress("\nš Enter query parameters:");
|
|
215
|
-
query = await generatePromptsForObject(bundledWebhook.querySchema, '', bundledWebhook.querySchema.required || []);
|
|
216
|
-
}
|
|
217
|
-
// Step 7: Collect headers based on schema
|
|
218
281
|
let headers = {};
|
|
219
|
-
if (bundledWebhook.headerSchema && bundledWebhook.headerSchema.properties) {
|
|
220
|
-
writeProgress("\nš Enter headers:");
|
|
221
|
-
headers = await generatePromptsForObject(bundledWebhook.headerSchema, '', bundledWebhook.headerSchema.required || []);
|
|
222
|
-
}
|
|
223
|
-
// Step 8: Collect body based on schema
|
|
224
282
|
let body = {};
|
|
225
|
-
if (
|
|
226
|
-
|
|
227
|
-
|
|
283
|
+
if (inputJson) {
|
|
284
|
+
const input = parseJsonInputOrFail(inputJson, '{"query": {}, "headers": {}, "body": {}}');
|
|
285
|
+
query = input.query || {};
|
|
286
|
+
headers = input.headers || {};
|
|
287
|
+
body = input.body || {};
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
if (bundledWebhook.querySchema?.properties) {
|
|
291
|
+
writeProgress("\nš Enter query parameters:");
|
|
292
|
+
query = await generatePromptsForObject(bundledWebhook.querySchema, '', bundledWebhook.querySchema.required || []);
|
|
293
|
+
}
|
|
294
|
+
if (bundledWebhook.headerSchema?.properties) {
|
|
295
|
+
writeProgress("\nš Enter headers:");
|
|
296
|
+
headers = await generatePromptsForObject(bundledWebhook.headerSchema, '', bundledWebhook.headerSchema.required || []);
|
|
297
|
+
}
|
|
298
|
+
if (bundledWebhook.bodySchema?.properties) {
|
|
299
|
+
writeProgress("\nš Enter request body:");
|
|
300
|
+
body = await generatePromptsForObject(bundledWebhook.bodySchema, '', bundledWebhook.bodySchema.required || []);
|
|
301
|
+
}
|
|
228
302
|
}
|
|
229
|
-
//
|
|
303
|
+
// Execute
|
|
230
304
|
writeProgress("\nš Executing webhook...");
|
|
231
305
|
writeProgress(`Query: ${JSON.stringify(query, null, 2)}`);
|
|
232
306
|
writeProgress(`Headers: ${JSON.stringify(headers, null, 2)}`);
|
|
233
307
|
writeProgress(`Body: ${JSON.stringify(body, null, 2)}`);
|
|
234
308
|
const webhookCode = decompressCode(bundledWebhook.code);
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
}
|
|
241
|
-
try {
|
|
242
|
-
const result = await executeWebhook({
|
|
243
|
-
webhookCode,
|
|
244
|
-
query,
|
|
245
|
-
headers,
|
|
246
|
-
body,
|
|
247
|
-
apiKey,
|
|
248
|
-
agentId
|
|
249
|
-
});
|
|
250
|
-
writeSuccess("\nā
Webhook execution successful!");
|
|
251
|
-
console.log(`Output: ${JSON.stringify(result, null, 2)}`);
|
|
252
|
-
}
|
|
253
|
-
catch (executionError) {
|
|
254
|
-
console.error("\nā Webhook execution failed:");
|
|
255
|
-
console.error(executionError.message);
|
|
256
|
-
if (executionError.stack) {
|
|
257
|
-
console.error(executionError.stack);
|
|
309
|
+
await withSandboxEnv(async () => {
|
|
310
|
+
try {
|
|
311
|
+
const result = await executeWebhook({ webhookCode, query, headers, body, apiKey, agentId });
|
|
312
|
+
writeSuccess("\nā
Webhook execution successful!");
|
|
313
|
+
console.log(`Output: ${JSON.stringify(result, null, 2)}`);
|
|
258
314
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}
|
|
315
|
+
catch (error) {
|
|
316
|
+
handleExecutionError(error, 'Webhook');
|
|
317
|
+
}
|
|
318
|
+
});
|
|
264
319
|
}
|
|
265
|
-
|
|
266
|
-
* Test a job by manually triggering it.
|
|
267
|
-
*/
|
|
268
|
-
async function testJob() {
|
|
320
|
+
async function testJob(entityName) {
|
|
269
321
|
writeProgress("ā° Testing job...");
|
|
270
|
-
// Step 1: Compile the code
|
|
271
322
|
writeProgress("š¦ Compiling code first...");
|
|
272
323
|
await compileCommand();
|
|
273
|
-
|
|
274
|
-
const apiKey = await loadApiKey();
|
|
275
|
-
if (!apiKey) {
|
|
276
|
-
throw new Error("No API key found. Please run 'lua auth configure' first.");
|
|
277
|
-
}
|
|
278
|
-
const config = readSkillConfig();
|
|
279
|
-
const agentId = config?.agent?.agentId;
|
|
280
|
-
if (!agentId) {
|
|
281
|
-
throw new Error("No agent ID found in lua.skill.yaml.");
|
|
282
|
-
}
|
|
324
|
+
const { apiKey, agentId, config } = await loadAuthOrFail();
|
|
283
325
|
const jobs = config.jobs || [];
|
|
284
326
|
if (jobs.length === 0) {
|
|
285
327
|
console.error("ā No jobs found in configuration.");
|
|
286
328
|
console.log("š” Create a job using LuaJob in your code.");
|
|
287
329
|
return;
|
|
288
330
|
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
{
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
message: 'Select a job to test:',
|
|
302
|
-
choices: jobs.map((job) => ({
|
|
303
|
-
name: `${job.name} (v${job.version}) - ${formatSchedule(job.schedule)}`,
|
|
304
|
-
value: job
|
|
305
|
-
}))
|
|
306
|
-
}
|
|
307
|
-
]);
|
|
308
|
-
if (!jobAnswer) {
|
|
331
|
+
const bundledJobs = loadBundledJsonOrFail('jobs.json', 'job');
|
|
332
|
+
// Select job
|
|
333
|
+
const selectedJob = await selectEntityOrPrompt({
|
|
334
|
+
items: jobs,
|
|
335
|
+
entityName,
|
|
336
|
+
entityType: 'Job',
|
|
337
|
+
idProperty: 'jobId',
|
|
338
|
+
nameProperty: 'name',
|
|
339
|
+
promptMessage: 'Select a job to test:',
|
|
340
|
+
formatChoice: (j) => `${j.name} (v${j.version}) - ${formatSchedule(j.schedule)}`
|
|
341
|
+
});
|
|
342
|
+
if (!selectedJob) {
|
|
309
343
|
console.log("Test cancelled.");
|
|
310
344
|
return;
|
|
311
345
|
}
|
|
312
|
-
const selectedJob = jobAnswer.selectedJob;
|
|
313
|
-
// Find bundled job data
|
|
314
346
|
const bundledJob = bundledJobs.find((j) => j.name === selectedJob.name);
|
|
315
347
|
if (!bundledJob || !bundledJob.code) {
|
|
316
|
-
console.error(
|
|
317
|
-
|
|
348
|
+
console.error(`ā Bundled job code not found for "${selectedJob.name}"`);
|
|
349
|
+
process.exit(1);
|
|
318
350
|
}
|
|
319
|
-
//
|
|
351
|
+
// Execute
|
|
320
352
|
writeProgress(`\nš Executing job: ${selectedJob.name}...`);
|
|
321
353
|
writeProgress(`š
Schedule: ${formatSchedule(selectedJob.schedule)}`);
|
|
322
354
|
const jobCode = decompressCode(bundledJob.code);
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
metadata: bundledJob.metadata || selectedJob.metadata || {}
|
|
340
|
-
}
|
|
341
|
-
});
|
|
342
|
-
writeSuccess("\nā
Job execution successful!");
|
|
343
|
-
console.log(`Output: ${JSON.stringify(result, null, 2)}`);
|
|
344
|
-
}
|
|
345
|
-
catch (executionError) {
|
|
346
|
-
console.error("\nā Job execution failed:");
|
|
347
|
-
console.error(executionError.message);
|
|
348
|
-
if (executionError.stack) {
|
|
349
|
-
console.error(executionError.stack);
|
|
355
|
+
await withSandboxEnv(async () => {
|
|
356
|
+
try {
|
|
357
|
+
const result = await executeJob({
|
|
358
|
+
jobCode,
|
|
359
|
+
apiKey,
|
|
360
|
+
agentId,
|
|
361
|
+
jobData: {
|
|
362
|
+
id: selectedJob.jobId,
|
|
363
|
+
jobId: selectedJob.jobId,
|
|
364
|
+
name: selectedJob.name,
|
|
365
|
+
schedule: selectedJob.schedule,
|
|
366
|
+
metadata: bundledJob.metadata || selectedJob.metadata || {}
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
writeSuccess("\nā
Job execution successful!");
|
|
370
|
+
console.log(`Output: ${JSON.stringify(result, null, 2)}`);
|
|
350
371
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
}
|
|
372
|
+
catch (error) {
|
|
373
|
+
handleExecutionError(error, 'Job');
|
|
374
|
+
}
|
|
375
|
+
});
|
|
356
376
|
}
|
|
357
|
-
|
|
358
|
-
* Test a preprocessor interactively.
|
|
359
|
-
*/
|
|
360
|
-
async function testPreProcessor() {
|
|
377
|
+
async function testPreProcessor(entityName, inputJson) {
|
|
361
378
|
writeProgress("š„ Testing preprocessor...");
|
|
362
|
-
// Step 1: Compile the code
|
|
363
379
|
writeProgress("š¦ Compiling code first...");
|
|
364
380
|
await compileCommand();
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
381
|
+
const preprocessors = loadBundledJsonOrFail('preprocessors.json', 'preprocessor');
|
|
382
|
+
// Select preprocessor
|
|
383
|
+
const selected = await selectEntityOrPrompt({
|
|
384
|
+
items: preprocessors,
|
|
385
|
+
entityName,
|
|
386
|
+
entityType: 'Preprocessor',
|
|
387
|
+
idProperty: 'preprocessorId',
|
|
388
|
+
nameProperty: 'name',
|
|
389
|
+
promptMessage: 'Select a preprocessor to test:',
|
|
390
|
+
formatChoice: (p) => `${p.name} (v${p.version})`
|
|
391
|
+
});
|
|
392
|
+
if (!selected)
|
|
374
393
|
return;
|
|
375
|
-
}
|
|
376
|
-
// Step 3: Select preprocessor to test
|
|
377
|
-
const preprocessorAnswer = await safePrompt([
|
|
378
|
-
{
|
|
379
|
-
type: 'list',
|
|
380
|
-
name: 'selected',
|
|
381
|
-
message: 'Select a preprocessor to test:',
|
|
382
|
-
choices: preprocessors.map((p) => ({
|
|
383
|
-
name: `${p.name} (v${p.version})`,
|
|
384
|
-
value: p
|
|
385
|
-
}))
|
|
386
|
-
}
|
|
387
|
-
]);
|
|
388
|
-
if (!preprocessorAnswer)
|
|
389
|
-
return;
|
|
390
|
-
const selected = preprocessorAnswer.selected;
|
|
391
394
|
if (!selected.code) {
|
|
392
395
|
console.error("ā Preprocessor code not found.");
|
|
393
396
|
return;
|
|
394
397
|
}
|
|
395
|
-
//
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
default: 'web'
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
398
|
+
// Get inputs
|
|
399
|
+
let message;
|
|
400
|
+
let channel;
|
|
401
|
+
if (inputJson) {
|
|
402
|
+
const input = parseJsonInputOrFail(inputJson, '{"message": "text", "channel": "channel_name"}');
|
|
403
|
+
message = input.message || 'Hello, I need help with my order';
|
|
404
|
+
channel = input.channel || 'web';
|
|
405
|
+
}
|
|
406
|
+
else {
|
|
407
|
+
const messageAnswer = await safePrompt([
|
|
408
|
+
{ type: 'input', name: 'message', message: 'Enter test message:', default: 'Hello, I need help with my order' }
|
|
409
|
+
]);
|
|
410
|
+
if (!messageAnswer)
|
|
411
|
+
return;
|
|
412
|
+
message = messageAnswer.message;
|
|
413
|
+
const channelAnswer = await safePrompt([
|
|
414
|
+
{ type: 'input', name: 'channel', message: 'Enter channel:', default: 'web' }
|
|
415
|
+
]);
|
|
416
|
+
if (!channelAnswer)
|
|
417
|
+
return;
|
|
418
|
+
channel = channelAnswer.channel;
|
|
419
|
+
}
|
|
420
|
+
// Execute
|
|
417
421
|
writeProgress("\nš Executing preprocessor...");
|
|
418
|
-
writeProgress(`Input message: ${
|
|
419
|
-
writeProgress(`Channel: ${
|
|
420
|
-
const apiKey = await
|
|
421
|
-
if (!apiKey)
|
|
422
|
-
throw new Error("No API key found.");
|
|
423
|
-
const config = readSkillConfig();
|
|
424
|
-
const agentId = config?.agent?.agentId;
|
|
425
|
-
if (!agentId)
|
|
426
|
-
throw new Error("No agent ID found.");
|
|
422
|
+
writeProgress(`Input message: ${message}`);
|
|
423
|
+
writeProgress(`Channel: ${channel}`);
|
|
424
|
+
const { apiKey, agentId } = await loadAuthOrFail();
|
|
427
425
|
const preprocessorCode = decompressCode(selected.code);
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
});
|
|
460
|
-
}
|
|
461
|
-
catch (error) {
|
|
462
|
-
console.error("\nā PreProcessor execution failed:");
|
|
463
|
-
console.error(error.message);
|
|
464
|
-
}
|
|
465
|
-
finally {
|
|
466
|
-
process.env = originalEnv;
|
|
467
|
-
}
|
|
426
|
+
await withSandboxEnv(async () => {
|
|
427
|
+
try {
|
|
428
|
+
const messages = [{ type: 'text', text: message }];
|
|
429
|
+
const result = await executePreProcessor({
|
|
430
|
+
processorCode: preprocessorCode,
|
|
431
|
+
messages,
|
|
432
|
+
channel,
|
|
433
|
+
apiKey,
|
|
434
|
+
agentId
|
|
435
|
+
});
|
|
436
|
+
writeSuccess("\nā
PreProcessor execution successful!");
|
|
437
|
+
console.log(`\nProcessed messages (${result.length}):`);
|
|
438
|
+
result.forEach((msg, idx) => {
|
|
439
|
+
if (msg.type === 'text') {
|
|
440
|
+
console.log(` ${idx + 1}. [TEXT] ${msg.text}`);
|
|
441
|
+
}
|
|
442
|
+
else if (msg.type === 'image') {
|
|
443
|
+
console.log(` ${idx + 1}. [IMAGE] ${msg.mimeType}`);
|
|
444
|
+
}
|
|
445
|
+
else if (msg.type === 'file') {
|
|
446
|
+
console.log(` ${idx + 1}. [FILE] ${msg.mimeType}`);
|
|
447
|
+
}
|
|
448
|
+
else {
|
|
449
|
+
console.log(` ${idx + 1}. [${msg.type}]`, msg);
|
|
450
|
+
}
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
catch (error) {
|
|
454
|
+
handleExecutionError(error, 'PreProcessor');
|
|
455
|
+
}
|
|
456
|
+
});
|
|
468
457
|
}
|
|
469
|
-
|
|
470
|
-
* Test a postprocessor interactively.
|
|
471
|
-
*/
|
|
472
|
-
async function testPostProcessor() {
|
|
458
|
+
async function testPostProcessor(entityName, inputJson) {
|
|
473
459
|
writeProgress("š¤ Testing postprocessor...");
|
|
474
|
-
// Step 1: Compile the code
|
|
475
460
|
writeProgress("š¦ Compiling code first...");
|
|
476
461
|
await compileCommand();
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
462
|
+
const postprocessors = loadBundledJsonOrFail('postprocessors.json', 'postprocessor');
|
|
463
|
+
// Select postprocessor
|
|
464
|
+
const selected = await selectEntityOrPrompt({
|
|
465
|
+
items: postprocessors,
|
|
466
|
+
entityName,
|
|
467
|
+
entityType: 'Postprocessor',
|
|
468
|
+
idProperty: 'postprocessorId',
|
|
469
|
+
nameProperty: 'name',
|
|
470
|
+
promptMessage: 'Select a postprocessor to test:',
|
|
471
|
+
formatChoice: (p) => `${p.name} (v${p.version})`
|
|
472
|
+
});
|
|
473
|
+
if (!selected)
|
|
486
474
|
return;
|
|
487
|
-
}
|
|
488
|
-
// Step 3: Select postprocessor to test
|
|
489
|
-
const postprocessorAnswer = await safePrompt([
|
|
490
|
-
{
|
|
491
|
-
type: 'list',
|
|
492
|
-
name: 'selected',
|
|
493
|
-
message: 'Select a postprocessor to test:',
|
|
494
|
-
choices: postprocessors.map((p) => ({
|
|
495
|
-
name: `${p.name} (v${p.version})`,
|
|
496
|
-
value: p
|
|
497
|
-
}))
|
|
498
|
-
}
|
|
499
|
-
]);
|
|
500
|
-
if (!postprocessorAnswer)
|
|
501
|
-
return;
|
|
502
|
-
const selected = postprocessorAnswer.selected;
|
|
503
475
|
if (!selected.code) {
|
|
504
476
|
console.error("ā Postprocessor code not found.");
|
|
505
477
|
return;
|
|
506
478
|
}
|
|
507
|
-
//
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
name: 'channel',
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
// Step 5: Execute postprocessor
|
|
479
|
+
// Get inputs
|
|
480
|
+
let message;
|
|
481
|
+
let response;
|
|
482
|
+
let channel;
|
|
483
|
+
if (inputJson) {
|
|
484
|
+
const input = parseJsonInputOrFail(inputJson, '{"message": "text", "response": "text", "channel": "channel_name"}');
|
|
485
|
+
message = input.message || 'What products do you have?';
|
|
486
|
+
response = input.response || 'We have laptops, phones, and tablets available.';
|
|
487
|
+
channel = input.channel || 'web';
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
const messageAnswer = await safePrompt([
|
|
491
|
+
{ type: 'input', name: 'message', message: 'Enter original user message:', default: 'What products do you have?' }
|
|
492
|
+
]);
|
|
493
|
+
if (!messageAnswer)
|
|
494
|
+
return;
|
|
495
|
+
message = messageAnswer.message;
|
|
496
|
+
const responseAnswer = await safePrompt([
|
|
497
|
+
{ type: 'input', name: 'response', message: 'Enter agent response to process:', default: 'We have laptops, phones, and tablets available.' }
|
|
498
|
+
]);
|
|
499
|
+
if (!responseAnswer)
|
|
500
|
+
return;
|
|
501
|
+
response = responseAnswer.response;
|
|
502
|
+
const channelAnswer = await safePrompt([
|
|
503
|
+
{ type: 'input', name: 'channel', message: 'Enter channel:', default: 'web' }
|
|
504
|
+
]);
|
|
505
|
+
if (!channelAnswer)
|
|
506
|
+
return;
|
|
507
|
+
channel = channelAnswer.channel;
|
|
508
|
+
}
|
|
509
|
+
// Execute
|
|
539
510
|
writeProgress("\nš Executing postprocessor...");
|
|
540
|
-
writeProgress(`Original message: ${
|
|
541
|
-
writeProgress(`Agent response: ${
|
|
542
|
-
writeProgress(`Channel: ${
|
|
543
|
-
const apiKey = await
|
|
544
|
-
if (!apiKey)
|
|
545
|
-
throw new Error("No API key found.");
|
|
546
|
-
const config = readSkillConfig();
|
|
547
|
-
const agentId = config?.agent?.agentId;
|
|
548
|
-
if (!agentId)
|
|
549
|
-
throw new Error("No agent ID found.");
|
|
511
|
+
writeProgress(`Original message: ${message}`);
|
|
512
|
+
writeProgress(`Agent response: ${response}`);
|
|
513
|
+
writeProgress(`Channel: ${channel}`);
|
|
514
|
+
const { apiKey, agentId } = await loadAuthOrFail();
|
|
550
515
|
const postprocessorCode = decompressCode(selected.code);
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
}
|
|
569
|
-
catch (error) {
|
|
570
|
-
console.error("\nā PostProcessor execution failed:");
|
|
571
|
-
console.error(error.message);
|
|
572
|
-
}
|
|
573
|
-
finally {
|
|
574
|
-
process.env = originalEnv;
|
|
575
|
-
}
|
|
516
|
+
await withSandboxEnv(async () => {
|
|
517
|
+
try {
|
|
518
|
+
const result = await executePostProcessor({
|
|
519
|
+
processorCode: postprocessorCode,
|
|
520
|
+
message,
|
|
521
|
+
response,
|
|
522
|
+
channel,
|
|
523
|
+
apiKey,
|
|
524
|
+
agentId
|
|
525
|
+
});
|
|
526
|
+
writeSuccess("\nā
PostProcessor execution successful!");
|
|
527
|
+
console.log(`Processed response: ${result}`);
|
|
528
|
+
}
|
|
529
|
+
catch (error) {
|
|
530
|
+
handleExecutionError(error, 'PostProcessor');
|
|
531
|
+
}
|
|
532
|
+
});
|
|
576
533
|
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
534
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
535
|
+
// Utility Functions
|
|
536
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
580
537
|
function formatSchedule(schedule) {
|
|
581
538
|
if (!schedule)
|
|
582
539
|
return 'Not configured';
|