lua-cli 3.1.0-alpha.3 → 3.1.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -4
- package/dist/api/job.api.service.d.ts +23 -100
- package/dist/api/job.api.service.js +13 -11
- package/dist/api/lazy-instances.d.ts +8 -0
- package/dist/api/lazy-instances.js +16 -0
- package/dist/api/postprocessor.api.service.d.ts +1 -8
- package/dist/api/postprocessor.api.service.js +1 -2
- package/dist/api/preprocessor.api.service.d.ts +1 -8
- package/dist/api/preprocessor.api.service.js +1 -2
- package/dist/api/webhook.api.service.d.ts +1 -3
- package/dist/api/webhook.api.service.js +1 -1
- package/dist/api/whatsapp-templates.api.service.d.ts +40 -0
- package/dist/api/whatsapp-templates.api.service.js +78 -0
- package/dist/api-exports.d.ts +81 -2
- package/dist/api-exports.js +91 -15
- package/dist/commands/chat.js +2 -4
- package/dist/commands/init.js +11 -44
- package/dist/commands/jobs.js +5 -5
- package/dist/commands/push.js +2 -9
- package/dist/common/job.instance.d.ts +35 -7
- package/dist/common/job.instance.js +46 -19
- package/dist/interfaces/agent.d.ts +0 -3
- package/dist/interfaces/index.d.ts +1 -1
- package/dist/interfaces/init.d.ts +0 -1
- package/dist/interfaces/jobs.d.ts +88 -132
- package/dist/interfaces/jobs.js +1 -1
- package/dist/interfaces/postprocessors.d.ts +0 -3
- package/dist/interfaces/preprocessors.d.ts +0 -3
- package/dist/interfaces/webhooks.d.ts +0 -5
- package/dist/interfaces/whatsapp-templates.d.ts +104 -0
- package/dist/interfaces/whatsapp-templates.js +5 -0
- package/dist/types/api-contracts.d.ts +32 -0
- package/dist/types/compile.types.d.ts +0 -6
- package/dist/types/index.d.ts +1 -1
- package/dist/types/skill.d.ts +61 -90
- package/dist/types/skill.js +28 -86
- package/dist/utils/agent-management.d.ts +3 -5
- package/dist/utils/agent-management.js +6 -8
- package/dist/utils/bundling.js +5 -6
- package/dist/utils/compile.d.ts +0 -1
- package/dist/utils/compile.js +1 -51
- package/dist/utils/deployment.js +0 -1
- package/dist/utils/dev-api.js +0 -2
- package/dist/utils/files.d.ts +3 -3
- package/dist/utils/files.js +4 -12
- package/dist/utils/init-agent.d.ts +1 -2
- package/dist/utils/init-agent.js +4 -6
- package/dist/utils/init-helpers.d.ts +2 -4
- package/dist/utils/init-helpers.js +4 -10
- package/dist/utils/job-management.js +0 -2
- package/dist/utils/postprocessor-management.js +2 -4
- package/dist/utils/preprocessor-management.js +2 -4
- package/dist/utils/sandbox.js +17 -7
- package/dist/utils/webhook-management.js +1 -3
- package/package.json +1 -1
- package/template/QUICKSTART.md +0 -13
- package/template/README.md +6 -7
- package/template/src/jobs/AbandonedBasketProcessorJob.ts +0 -3
- package/template/src/jobs/DailyCleanupJob.ts +0 -3
- package/template/src/jobs/DataMigrationJob.ts +0 -3
- package/template/src/jobs/HealthCheckJob.ts +0 -3
- package/template/src/postprocessors/modifyResponse.ts +0 -1
- package/template/src/preprocessors/messageMatching.ts +18 -5
- package/template/src/skills/basket.skill.ts +0 -1
- package/template/src/skills/product.skill.ts +0 -1
- package/template/src/skills/user.skill.ts +0 -1
- package/template/src/webhooks/PaymentWebhook.ts +12 -9
- package/template/src/webhooks/UserEventWebhook.ts +39 -11
package/dist/utils/files.js
CHANGED
|
@@ -53,14 +53,13 @@ function updatePackageJson(srcPath, destPath) {
|
|
|
53
53
|
// Write the updated package.json
|
|
54
54
|
fs.writeFileSync(destPath, JSON.stringify(templatePackageJson, null, 2) + '\n');
|
|
55
55
|
}
|
|
56
|
-
export function createSkillYaml(agentId, orgId, skillName, skillId, persona
|
|
56
|
+
export function createSkillYaml(agentId, orgId, skillName, skillId, persona) {
|
|
57
57
|
// Handle multiline strings properly for YAML
|
|
58
58
|
const personaSection = persona ? ` persona: |\n${persona.split('\n').map(line => ` ${line}`).join('\n')}\n` : '';
|
|
59
|
-
const welcomeMessageSection = welcomeMessage ? ` welcomeMessage: "${welcomeMessage}"\n` : '';
|
|
60
59
|
const yamlContent = `agent:
|
|
61
60
|
agentId: "${agentId}"
|
|
62
61
|
orgId: "${orgId}"
|
|
63
|
-
${personaSection}
|
|
62
|
+
${personaSection}
|
|
64
63
|
skills:
|
|
65
64
|
# Skills will be auto-generated during compilation
|
|
66
65
|
`;
|
|
@@ -81,7 +80,7 @@ export function readSkillConfig() {
|
|
|
81
80
|
/**
|
|
82
81
|
* Update only the agent information in an existing YAML file
|
|
83
82
|
*/
|
|
84
|
-
export function updateYamlAgent(agentId, orgId, persona
|
|
83
|
+
export function updateYamlAgent(agentId, orgId, persona) {
|
|
85
84
|
const yamlPath = path.join(process.cwd(), 'lua.skill.yaml');
|
|
86
85
|
if (!fs.existsSync(yamlPath)) {
|
|
87
86
|
throw new Error('lua.skill.yaml not found');
|
|
@@ -94,9 +93,6 @@ export function updateYamlAgent(agentId, orgId, persona, welcomeMessage) {
|
|
|
94
93
|
if (persona) {
|
|
95
94
|
config.agent.persona = persona;
|
|
96
95
|
}
|
|
97
|
-
if (welcomeMessage) {
|
|
98
|
-
config.agent.welcomeMessage = welcomeMessage;
|
|
99
|
-
}
|
|
100
96
|
// Write back to file
|
|
101
97
|
const yamlContent = dump(config, {
|
|
102
98
|
indent: 2,
|
|
@@ -105,7 +101,7 @@ export function updateYamlAgent(agentId, orgId, persona, welcomeMessage) {
|
|
|
105
101
|
});
|
|
106
102
|
fs.writeFileSync(yamlPath, yamlContent);
|
|
107
103
|
}
|
|
108
|
-
export function updateSkillYamlPersona(persona
|
|
104
|
+
export function updateSkillYamlPersona(persona) {
|
|
109
105
|
const yamlPath = path.join(process.cwd(), 'lua.skill.yaml');
|
|
110
106
|
if (!fs.existsSync(yamlPath)) {
|
|
111
107
|
console.error('❌ No lua.skill.yaml found. Please run this command from a skill directory.');
|
|
@@ -118,10 +114,6 @@ export function updateSkillYamlPersona(persona, welcomeMessage) {
|
|
|
118
114
|
data.agent = {};
|
|
119
115
|
}
|
|
120
116
|
data.agent.persona = persona;
|
|
121
|
-
// Update welcome message if provided
|
|
122
|
-
if (welcomeMessage) {
|
|
123
|
-
data.agent.welcomeMessage = welcomeMessage;
|
|
124
|
-
}
|
|
125
117
|
// Use yaml.dump to properly handle both old and new formats
|
|
126
118
|
const updatedYamlContent = dump(data, {
|
|
127
119
|
indent: 2,
|
|
@@ -40,10 +40,9 @@ export declare function createNewAgent(apiKey: string, agentType: AgentType, bus
|
|
|
40
40
|
*
|
|
41
41
|
* @param apiKey - User's API key
|
|
42
42
|
* @param agentId - Agent ID to fetch
|
|
43
|
-
* @returns Agent details including persona
|
|
43
|
+
* @returns Agent details including persona
|
|
44
44
|
* @throws Error if fetch fails
|
|
45
45
|
*/
|
|
46
46
|
export declare function fetchExistingAgentDetails(apiKey: string, agentId: string): Promise<{
|
|
47
47
|
persona?: string;
|
|
48
|
-
welcomeMessage?: string;
|
|
49
48
|
}>;
|
package/dist/utils/init-agent.js
CHANGED
|
@@ -98,8 +98,7 @@ export async function createNewAgent(apiKey, agentType, businessConfig, metadata
|
|
|
98
98
|
org: {
|
|
99
99
|
id: orgId
|
|
100
100
|
},
|
|
101
|
-
persona: agentDetails.persona
|
|
102
|
-
welcomeMessage: agentDetails.welcomeMessage
|
|
101
|
+
persona: agentDetails.persona
|
|
103
102
|
};
|
|
104
103
|
}
|
|
105
104
|
/**
|
|
@@ -114,7 +113,7 @@ async function waitForAgentReady() {
|
|
|
114
113
|
*
|
|
115
114
|
* @param agentApi - Agent API instance
|
|
116
115
|
* @param agentId - Agent ID to fetch
|
|
117
|
-
* @returns Agent details including persona
|
|
116
|
+
* @returns Agent details including persona
|
|
118
117
|
* @throws Error if fetch fails
|
|
119
118
|
*/
|
|
120
119
|
async function fetchAgentDetails(agentApi, agentId) {
|
|
@@ -125,8 +124,7 @@ async function fetchAgentDetails(agentApi, agentId) {
|
|
|
125
124
|
}
|
|
126
125
|
writeProgress("✅ Agent details loaded");
|
|
127
126
|
return {
|
|
128
|
-
persona: agentDetailsResult.data.persona
|
|
129
|
-
welcomeMessage: agentDetailsResult.data.welcomeMessage
|
|
127
|
+
persona: agentDetailsResult.data.persona
|
|
130
128
|
};
|
|
131
129
|
}
|
|
132
130
|
/**
|
|
@@ -135,7 +133,7 @@ async function fetchAgentDetails(agentApi, agentId) {
|
|
|
135
133
|
*
|
|
136
134
|
* @param apiKey - User's API key
|
|
137
135
|
* @param agentId - Agent ID to fetch
|
|
138
|
-
* @returns Agent details including persona
|
|
136
|
+
* @returns Agent details including persona
|
|
139
137
|
* @throws Error if fetch fails
|
|
140
138
|
*/
|
|
141
139
|
export async function fetchExistingAgentDetails(apiKey, agentId) {
|
|
@@ -14,10 +14,9 @@ export declare function getTemplateDir(): string;
|
|
|
14
14
|
* @param agentId - Agent ID for configuration
|
|
15
15
|
* @param orgId - Organization ID for configuration
|
|
16
16
|
* @param persona - Optional persona configuration
|
|
17
|
-
* @param welcomeMessage - Optional welcome message
|
|
18
17
|
* @returns Current working directory
|
|
19
18
|
*/
|
|
20
|
-
export declare function initializeProject(agentId: string, orgId: string, persona?: string,
|
|
19
|
+
export declare function initializeProject(agentId: string, orgId: string, persona?: string, agentName?: string): string;
|
|
21
20
|
/**
|
|
22
21
|
* Installs npm dependencies for the project.
|
|
23
22
|
*
|
|
@@ -45,6 +44,5 @@ export declare function clearLinesIfNeeded(lineCount: number): void;
|
|
|
45
44
|
* @param projectDir - Project directory containing src/index.ts
|
|
46
45
|
* @param agentName - Name of the agent
|
|
47
46
|
* @param persona - Agent persona
|
|
48
|
-
* @param welcomeMessage - Welcome message
|
|
49
47
|
*/
|
|
50
|
-
export declare function updateLuaAgentInIndexFile(projectDir: string, agentName?: string, persona?: string
|
|
48
|
+
export declare function updateLuaAgentInIndexFile(projectDir: string, agentName?: string, persona?: string): void;
|
|
@@ -24,16 +24,15 @@ export function getTemplateDir() {
|
|
|
24
24
|
* @param agentId - Agent ID for configuration
|
|
25
25
|
* @param orgId - Organization ID for configuration
|
|
26
26
|
* @param persona - Optional persona configuration
|
|
27
|
-
* @param welcomeMessage - Optional welcome message
|
|
28
27
|
* @returns Current working directory
|
|
29
28
|
*/
|
|
30
|
-
export function initializeProject(agentId, orgId, persona,
|
|
29
|
+
export function initializeProject(agentId, orgId, persona, agentName) {
|
|
31
30
|
const templateDir = getTemplateDir();
|
|
32
31
|
const currentDir = process.cwd();
|
|
33
32
|
copyTemplateFiles(templateDir, currentDir);
|
|
34
|
-
createSkillYaml(agentId, orgId, undefined, undefined, persona
|
|
33
|
+
createSkillYaml(agentId, orgId, undefined, undefined, persona);
|
|
35
34
|
// Update LuaAgent in index.ts with agent configuration
|
|
36
|
-
updateLuaAgentInIndexFile(currentDir, agentName, persona
|
|
35
|
+
updateLuaAgentInIndexFile(currentDir, agentName, persona);
|
|
37
36
|
writeProgress("✅ Created lua.skill.yaml");
|
|
38
37
|
writeProgress("✅ Copied template files");
|
|
39
38
|
writeProgress("✅ Updated LuaAgent configuration");
|
|
@@ -81,9 +80,8 @@ export function clearLinesIfNeeded(lineCount) {
|
|
|
81
80
|
* @param projectDir - Project directory containing src/index.ts
|
|
82
81
|
* @param agentName - Name of the agent
|
|
83
82
|
* @param persona - Agent persona
|
|
84
|
-
* @param welcomeMessage - Welcome message
|
|
85
83
|
*/
|
|
86
|
-
export function updateLuaAgentInIndexFile(projectDir, agentName, persona
|
|
84
|
+
export function updateLuaAgentInIndexFile(projectDir, agentName, persona) {
|
|
87
85
|
const indexPath = path.join(projectDir, 'src', 'index.ts');
|
|
88
86
|
if (!fs.existsSync(indexPath)) {
|
|
89
87
|
// If no index.ts, skip (might be an old template structure)
|
|
@@ -103,10 +101,6 @@ export function updateLuaAgentInIndexFile(projectDir, agentName, persona, welcom
|
|
|
103
101
|
if (persona) {
|
|
104
102
|
content = content.replace(/(persona:\s*['"`])[\s\S]*?(['"`])/, `$1${persona.replace(/'/g, "\\'").replace(/`/g, '\\`')}$2`);
|
|
105
103
|
}
|
|
106
|
-
// Update welcome message
|
|
107
|
-
if (welcomeMessage) {
|
|
108
|
-
content = content.replace(/(welcomeMessage:\s*['"])[\s\S]*?(['"])/, `$1${welcomeMessage.replace(/'/g, "\\'")}$2`);
|
|
109
|
-
}
|
|
110
104
|
fs.writeFileSync(indexPath, content);
|
|
111
105
|
}
|
|
112
106
|
catch (error) {
|
|
@@ -82,7 +82,6 @@ async function createJobViaApi(job, config, existingJobs, existingJob) {
|
|
|
82
82
|
const jobPayload = {
|
|
83
83
|
name: job.name,
|
|
84
84
|
description: job.description || `A Lua job for ${job.name}`,
|
|
85
|
-
context: job.context || '',
|
|
86
85
|
schedule: job.schedule || { type: 'cron', expression: '0 0 * * *' },
|
|
87
86
|
timeout: job.timeout,
|
|
88
87
|
retry: job.retry,
|
|
@@ -96,7 +95,6 @@ async function createJobViaApi(job, config, existingJobs, existingJob) {
|
|
|
96
95
|
if (!existingJob) {
|
|
97
96
|
existingJobs.push({
|
|
98
97
|
name: job.name || '',
|
|
99
|
-
version: job.version || SKILL_DEFAULTS.VERSION,
|
|
100
98
|
jobId: newJobId,
|
|
101
99
|
schedule: job.schedule
|
|
102
100
|
});
|
|
@@ -7,7 +7,7 @@ import yaml from "js-yaml";
|
|
|
7
7
|
import PostProcessorApi from '../api/postprocessor.api.service.js';
|
|
8
8
|
import { BASE_URLS } from '../config/constants.js';
|
|
9
9
|
import { loadApiKey } from '../services/auth.js';
|
|
10
|
-
import {
|
|
10
|
+
import { YAML_FORMAT } from '../config/compile.constants.js';
|
|
11
11
|
/**
|
|
12
12
|
* Ensures all detected postprocessors exist in the YAML config with valid IDs.
|
|
13
13
|
*/
|
|
@@ -45,8 +45,7 @@ async function createPostProcessorViaApi(postprocessor, config, existingPostProc
|
|
|
45
45
|
throw new Error("No agent ID found in lua.skill.yaml. Run 'lua init' first.");
|
|
46
46
|
const payload = {
|
|
47
47
|
name: postprocessor.name,
|
|
48
|
-
description: postprocessor.description || `A Lua postprocessor for ${postprocessor.name}
|
|
49
|
-
context: postprocessor.context || ''
|
|
48
|
+
description: postprocessor.description || `A Lua postprocessor for ${postprocessor.name}`
|
|
50
49
|
};
|
|
51
50
|
const api = new PostProcessorApi(BASE_URLS.API, apiKey, agentId);
|
|
52
51
|
const result = await api.createPostProcessor(payload);
|
|
@@ -55,7 +54,6 @@ async function createPostProcessorViaApi(postprocessor, config, existingPostProc
|
|
|
55
54
|
if (!existingPostProcessor) {
|
|
56
55
|
existingPostProcessors.push({
|
|
57
56
|
name: postprocessor.name || '',
|
|
58
|
-
version: postprocessor.version || SKILL_DEFAULTS.VERSION,
|
|
59
57
|
postprocessorId: newId
|
|
60
58
|
});
|
|
61
59
|
}
|
|
@@ -7,7 +7,7 @@ import yaml from "js-yaml";
|
|
|
7
7
|
import PreProcessorApi from '../api/preprocessor.api.service.js';
|
|
8
8
|
import { BASE_URLS } from '../config/constants.js';
|
|
9
9
|
import { loadApiKey } from '../services/auth.js';
|
|
10
|
-
import {
|
|
10
|
+
import { YAML_FORMAT } from '../config/compile.constants.js';
|
|
11
11
|
/**
|
|
12
12
|
* Ensures all detected preprocessors exist in the YAML config with valid IDs.
|
|
13
13
|
*/
|
|
@@ -45,8 +45,7 @@ async function createPreProcessorViaApi(preprocessor, config, existingPreProcess
|
|
|
45
45
|
throw new Error("No agent ID found in lua.skill.yaml. Run 'lua init' first.");
|
|
46
46
|
const payload = {
|
|
47
47
|
name: preprocessor.name,
|
|
48
|
-
description: preprocessor.description || `A Lua preprocessor for ${preprocessor.name}
|
|
49
|
-
context: preprocessor.context || ''
|
|
48
|
+
description: preprocessor.description || `A Lua preprocessor for ${preprocessor.name}`
|
|
50
49
|
};
|
|
51
50
|
const api = new PreProcessorApi(BASE_URLS.API, apiKey, agentId);
|
|
52
51
|
const result = await api.createPreProcessor(payload);
|
|
@@ -55,7 +54,6 @@ async function createPreProcessorViaApi(preprocessor, config, existingPreProcess
|
|
|
55
54
|
if (!existingPreProcessor) {
|
|
56
55
|
existingPreProcessors.push({
|
|
57
56
|
name: preprocessor.name || '',
|
|
58
|
-
version: preprocessor.version || SKILL_DEFAULTS.VERSION,
|
|
59
57
|
preprocessorId: newId
|
|
60
58
|
});
|
|
61
59
|
}
|
package/dist/utils/sandbox.js
CHANGED
|
@@ -11,6 +11,7 @@ import OrderApiService from "../api/order.api.service.js";
|
|
|
11
11
|
import CustomDataApiService from "../api/custom.data.api.service.js";
|
|
12
12
|
import WebhookApi from "../api/webhook.api.service.js";
|
|
13
13
|
import JobApi from "../api/job.api.service.js";
|
|
14
|
+
import WhatsAppTemplatesApiService from "../api/whatsapp-templates.api.service.js";
|
|
14
15
|
import { BasketStatus } from "../interfaces/baskets.js";
|
|
15
16
|
import { OrderStatus } from "../interfaces/orders.js";
|
|
16
17
|
import { compressCode } from "./compile.js";
|
|
@@ -88,6 +89,7 @@ export function createSandbox(options) {
|
|
|
88
89
|
const orderService = new OrderApiService(BASE_URLS.API, apiKey, agentId);
|
|
89
90
|
const webhookService = new WebhookApi(BASE_URLS.API, apiKey, agentId);
|
|
90
91
|
const jobService = new JobApi(BASE_URLS.API, apiKey, agentId);
|
|
92
|
+
const whatsAppTemplatesService = new WhatsAppTemplatesApiService(BASE_URLS.API, apiKey, agentId);
|
|
91
93
|
// Override User service methods if needed
|
|
92
94
|
// Example: Override the update method
|
|
93
95
|
// const originalUpdate = userService.update.bind(userService);
|
|
@@ -224,6 +226,10 @@ export function createSandbox(options) {
|
|
|
224
226
|
Baskets: basketsService,
|
|
225
227
|
compressCode: compressCode,
|
|
226
228
|
Orders: orderService,
|
|
229
|
+
// Templates API with namespaces for different template types
|
|
230
|
+
Templates: {
|
|
231
|
+
whatsapp: whatsAppTemplatesService
|
|
232
|
+
},
|
|
227
233
|
// Jobs API
|
|
228
234
|
Jobs: {
|
|
229
235
|
create: async (config) => {
|
|
@@ -235,7 +241,6 @@ export function createSandbox(options) {
|
|
|
235
241
|
return await jobService.createJobInstance({
|
|
236
242
|
name: config.name + '_' + Date.now(),
|
|
237
243
|
description: config.description,
|
|
238
|
-
context: config.description || '',
|
|
239
244
|
schedule: config.schedule,
|
|
240
245
|
timeout: config.timeout,
|
|
241
246
|
retry: config.retry,
|
|
@@ -244,7 +249,6 @@ export function createSandbox(options) {
|
|
|
244
249
|
version: {
|
|
245
250
|
version: '1.0.0',
|
|
246
251
|
description: config.description,
|
|
247
|
-
context: config.description || '',
|
|
248
252
|
code: '',
|
|
249
253
|
executeFunction: executeString,
|
|
250
254
|
timeout: config.timeout,
|
|
@@ -254,7 +258,7 @@ export function createSandbox(options) {
|
|
|
254
258
|
activate: config.activate ?? true
|
|
255
259
|
});
|
|
256
260
|
},
|
|
257
|
-
|
|
261
|
+
getJob: async (jobId) => jobService.getJob(jobId)
|
|
258
262
|
},
|
|
259
263
|
// Environment variables function
|
|
260
264
|
env: (key) => envVars[key],
|
|
@@ -345,9 +349,9 @@ export async function executeWebhook(options) {
|
|
|
345
349
|
const executeFunction = ${webhookCode};
|
|
346
350
|
|
|
347
351
|
// Export the function for testing
|
|
348
|
-
module.exports = async (
|
|
352
|
+
module.exports = async (event) => {
|
|
349
353
|
try{
|
|
350
|
-
return await executeFunction(
|
|
354
|
+
return await executeFunction(event);
|
|
351
355
|
}catch(e){
|
|
352
356
|
console.error(e);
|
|
353
357
|
return { status: 'error', error: e.message };
|
|
@@ -373,9 +377,15 @@ try{
|
|
|
373
377
|
}
|
|
374
378
|
`, context);
|
|
375
379
|
vm.runInContext(commonJsWrapper, context);
|
|
376
|
-
// Get the exported function and execute with
|
|
380
|
+
// Get the exported function and execute with unified event object
|
|
377
381
|
const executeFunction = context.module.exports;
|
|
378
|
-
|
|
382
|
+
const event = {
|
|
383
|
+
query: query ?? {},
|
|
384
|
+
headers: headers ?? {},
|
|
385
|
+
body,
|
|
386
|
+
timestamp: new Date().toISOString()
|
|
387
|
+
};
|
|
388
|
+
return await executeFunction(event);
|
|
379
389
|
}
|
|
380
390
|
/**
|
|
381
391
|
* Executes a job in a sandboxed environment.
|
|
@@ -81,8 +81,7 @@ async function createWebhookViaApi(webhook, config, existingWebhooks, existingWe
|
|
|
81
81
|
// Create webhook via API
|
|
82
82
|
const webhookPayload = {
|
|
83
83
|
name: webhook.name,
|
|
84
|
-
description: webhook.description || `A Lua webhook for ${webhook.name}
|
|
85
|
-
context: webhook.context || ''
|
|
84
|
+
description: webhook.description || `A Lua webhook for ${webhook.name}`
|
|
86
85
|
};
|
|
87
86
|
const webhookApi = new WebhookApi(BASE_URLS.API, apiKey, agentId);
|
|
88
87
|
const result = await webhookApi.createWebhook(webhookPayload);
|
|
@@ -92,7 +91,6 @@ async function createWebhookViaApi(webhook, config, existingWebhooks, existingWe
|
|
|
92
91
|
if (!existingWebhook) {
|
|
93
92
|
existingWebhooks.push({
|
|
94
93
|
name: webhook.name || '',
|
|
95
|
-
version: webhook.version || SKILL_DEFAULTS.VERSION,
|
|
96
94
|
webhookId: newWebhookId
|
|
97
95
|
});
|
|
98
96
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lua-cli",
|
|
3
|
-
"version": "3.1.0-alpha.
|
|
3
|
+
"version": "3.1.0-alpha.4",
|
|
4
4
|
"description": "Build, test, and deploy AI agents with custom tools, webhooks, and scheduled jobs. Features LuaAgent unified configuration, streaming chat, and batch deployment.",
|
|
5
5
|
"readmeFilename": "README.md",
|
|
6
6
|
"main": "dist/api-exports.js",
|
package/template/QUICKSTART.md
CHANGED
|
@@ -102,7 +102,6 @@ The `LuaAgent` is the **central configuration** for your AI agent. It's defined
|
|
|
102
102
|
export const agent = new LuaAgent({
|
|
103
103
|
name: 'my-assistant',
|
|
104
104
|
persona: 'You are a helpful AI assistant...',
|
|
105
|
-
welcomeMessage: 'Hello! How can I help you today?',
|
|
106
105
|
skills: [generalSkill, userSkill, productSkill],
|
|
107
106
|
webhooks: [paymentWebhook],
|
|
108
107
|
jobs: [dailyCleanupJob],
|
|
@@ -130,15 +129,6 @@ You're helpful, patient, and always prioritize customer satisfaction.
|
|
|
130
129
|
Use a warm, professional tone and offer solutions proactively.`
|
|
131
130
|
```
|
|
132
131
|
|
|
133
|
-
#### `welcomeMessage` (string, optional)
|
|
134
|
-
- First message users see when starting a chat
|
|
135
|
-
- Should be welcoming and set expectations
|
|
136
|
-
|
|
137
|
-
**Example:**
|
|
138
|
-
```typescript
|
|
139
|
-
welcomeMessage: "Hi! I'm Emma from Acme Corp. How can I assist you today?"
|
|
140
|
-
```
|
|
141
|
-
|
|
142
132
|
#### `skills` (array of LuaSkill)
|
|
143
133
|
- Collections of tools grouped by functionality
|
|
144
134
|
- Each skill contains multiple related tools
|
|
@@ -407,7 +397,6 @@ import { LuaJob, User } from "lua-cli";
|
|
|
407
397
|
|
|
408
398
|
export default new LuaJob({
|
|
409
399
|
name: "daily-report",
|
|
410
|
-
version: "1.0.0",
|
|
411
400
|
description: "Send daily summary to admin",
|
|
412
401
|
|
|
413
402
|
schedule: {
|
|
@@ -451,7 +440,6 @@ import { z } from "zod";
|
|
|
451
440
|
|
|
452
441
|
export default new LuaWebhook({
|
|
453
442
|
name: "order-notification",
|
|
454
|
-
version: "1.0.0",
|
|
455
443
|
description: "Receive order updates from external systems",
|
|
456
444
|
|
|
457
445
|
bodySchema: z.object({
|
|
@@ -655,7 +643,6 @@ import { z } from "zod";
|
|
|
655
643
|
|
|
656
644
|
export default new LuaWebhook({
|
|
657
645
|
name: "order-received",
|
|
658
|
-
version: "1.0.0",
|
|
659
646
|
description: "Handle new order notifications",
|
|
660
647
|
|
|
661
648
|
bodySchema: z.object({
|
package/template/README.md
CHANGED
|
@@ -81,7 +81,6 @@ Your agent is configured in `src/index.ts`:
|
|
|
81
81
|
export const agent = new LuaAgent({
|
|
82
82
|
name: 'your-agent-name',
|
|
83
83
|
persona: 'Your agent personality and behavior...',
|
|
84
|
-
welcomeMessage: 'First message users see',
|
|
85
84
|
|
|
86
85
|
skills: [
|
|
87
86
|
generalSkill, // Weather, posts, utils
|
|
@@ -282,8 +281,6 @@ export const agent = new LuaAgent({
|
|
|
282
281
|
|
|
283
282
|
persona: `You are Sarah, a friendly customer support agent...`, // ✏️ Customize
|
|
284
283
|
|
|
285
|
-
welcomeMessage: 'Hi! I\'m Sarah. How can I help you today?', // ✏️ Personalize
|
|
286
|
-
|
|
287
284
|
// ...
|
|
288
285
|
});
|
|
289
286
|
```
|
|
@@ -342,9 +339,10 @@ export const agent = new LuaAgent({
|
|
|
342
339
|
});
|
|
343
340
|
```
|
|
344
341
|
|
|
345
|
-
Get your webhook
|
|
342
|
+
Get your webhook URLs after deployment:
|
|
346
343
|
```
|
|
347
|
-
https://webhook.heylua.ai/{agentId}/{webhookId}
|
|
344
|
+
https://webhook.heylua.ai/{agentId}/{webhookId} // default
|
|
345
|
+
https://webhook.heylua.ai/{agentId}/{webhook-name} // friendly alias
|
|
348
346
|
```
|
|
349
347
|
|
|
350
348
|
### 4. Schedule Jobs
|
|
@@ -501,7 +499,7 @@ lua deploy
|
|
|
501
499
|
|
|
502
500
|
The CLI automatically keeps your `lua.skill.yaml` and `LuaAgent` in sync:
|
|
503
501
|
|
|
504
|
-
- **Run `lua init`** → Syncs agent name
|
|
502
|
+
- **Run `lua init`** → Syncs agent name and persona to both files
|
|
505
503
|
- **Run `lua compile`** → Syncs LuaAgent changes back to YAML
|
|
506
504
|
- **Manual edit YAML** → Re-run `lua compile` to rebuild
|
|
507
505
|
|
|
@@ -644,7 +642,8 @@ Use webhooks to receive events:
|
|
|
644
642
|
// Receive events from Stripe, Shopify, etc.
|
|
645
643
|
export default new LuaWebhook({
|
|
646
644
|
name: "shopify-order",
|
|
647
|
-
execute: async (
|
|
645
|
+
execute: async (event) => {
|
|
646
|
+
const { body } = event;
|
|
648
647
|
// Process Shopify order
|
|
649
648
|
// Update your system
|
|
650
649
|
// Notify customer
|
|
@@ -16,10 +16,7 @@ import { LuaJob, Data, Baskets } from "lua-cli";
|
|
|
16
16
|
|
|
17
17
|
const abandonedBasketProcessorJob = new LuaJob({
|
|
18
18
|
name: "process-basket-reminders",
|
|
19
|
-
version: "1.0.0",
|
|
20
19
|
description: "Processes abandoned basket reminders",
|
|
21
|
-
context: "Runs every 15 minutes to check for abandoned baskets and send recovery emails. " +
|
|
22
|
-
"Works with basket creation tools that schedule reminders.",
|
|
23
20
|
|
|
24
21
|
// Run every 15 minutes
|
|
25
22
|
schedule: {
|
|
@@ -9,10 +9,7 @@ import { LuaJob, Data } from "lua-cli";
|
|
|
9
9
|
|
|
10
10
|
const dailyCleanupJob = new LuaJob({
|
|
11
11
|
name: "daily-cleanup",
|
|
12
|
-
version: "1.0.0",
|
|
13
12
|
description: "Daily database cleanup and maintenance",
|
|
14
|
-
context: "Runs at 2 AM EST daily to remove old logs, expired sessions, and optimize data collections. " +
|
|
15
|
-
"This job helps maintain database performance and storage costs.",
|
|
16
13
|
|
|
17
14
|
// Cron schedule: Every day at 2 AM EST
|
|
18
15
|
schedule: {
|
|
@@ -9,10 +9,7 @@ import { LuaJob, Data } from "lua-cli";
|
|
|
9
9
|
|
|
10
10
|
const dataMigrationJob = new LuaJob({
|
|
11
11
|
name: "migrate-user-schema",
|
|
12
|
-
version: "1.0.0",
|
|
13
12
|
description: "One-time migration to new user event schema",
|
|
14
|
-
context: "Scheduled one-time task to migrate user events from old schema to new schema. " +
|
|
15
|
-
"Runs once at the specified time and then automatically deactivates.",
|
|
16
13
|
|
|
17
14
|
// One-time schedule: Run at specific date/time
|
|
18
15
|
schedule: {
|
|
@@ -9,10 +9,7 @@ import { LuaJob, Data, Products } from "lua-cli";
|
|
|
9
9
|
|
|
10
10
|
const healthCheckJob = new LuaJob({
|
|
11
11
|
name: "health-check",
|
|
12
|
-
version: "1.0.0",
|
|
13
12
|
description: "System health monitoring",
|
|
14
|
-
context: "Runs every 5 minutes to check API health, database connectivity, and service availability. " +
|
|
15
|
-
"Logs health metrics and can trigger alerts if issues are detected.",
|
|
16
13
|
|
|
17
14
|
// Interval schedule: Every 5 minutes
|
|
18
15
|
schedule: {
|
|
@@ -4,7 +4,6 @@ import { ChatMessage, PostProcessor, UserDataInstance } from "lua-cli";
|
|
|
4
4
|
const modifyResponsePostProcessor = new PostProcessor({
|
|
5
5
|
name: "modify-response",
|
|
6
6
|
description: "Modifies the response to the user",
|
|
7
|
-
context: "Modifies the response to the user",
|
|
8
7
|
execute: async (user: UserDataInstance, message: string, response: string, channel: string) => {
|
|
9
8
|
console.log("Modify response post processor", user, message, response, channel);
|
|
10
9
|
console.log("User data", await user.data);
|
|
@@ -1,21 +1,34 @@
|
|
|
1
|
-
import { ChatMessage, PreProcessor, UserDataInstance } from "lua-cli";
|
|
1
|
+
import { ChatMessage, PreProcessor, PreProcessorResult, UserDataInstance } from "lua-cli";
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
const messageMatchingPreProcessor = new PreProcessor({
|
|
5
5
|
name: "message-matching",
|
|
6
6
|
description: "Matches the message to the appropriate skill",
|
|
7
|
-
|
|
8
|
-
execute: async (user: UserDataInstance, messages: ChatMessage[], channel: string) => {
|
|
7
|
+
execute: async (user: UserDataInstance, messages: ChatMessage[], channel: string): Promise<PreProcessorResult> => {
|
|
9
8
|
console.log("Message matching pre processor", user, messages, channel);
|
|
10
9
|
console.log("User data", await user.data);
|
|
11
10
|
console.log("Messages", messages);
|
|
12
11
|
console.log("Channel", channel);
|
|
12
|
+
|
|
13
13
|
//check if message type text contains test and return the message
|
|
14
14
|
const testMessage = messages.find((message) => message.type === "text" && message.text.includes("test"));
|
|
15
15
|
if (testMessage) {
|
|
16
|
-
return
|
|
16
|
+
return {
|
|
17
|
+
action: 'proceed',
|
|
18
|
+
modifiedMessage: [{ type: "text", text: "Tell the user that you got their test message and nothing else" }]
|
|
19
|
+
};
|
|
17
20
|
}
|
|
18
|
-
|
|
21
|
+
|
|
22
|
+
// Example blocking logic
|
|
23
|
+
const shouldBlock = messages.some((message) => message.type === "text" && message.text.includes("block"));
|
|
24
|
+
if (shouldBlock) {
|
|
25
|
+
return {
|
|
26
|
+
action: 'block',
|
|
27
|
+
response: "Message blocked by preprocessor"
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return { action: 'proceed' };
|
|
19
32
|
}
|
|
20
33
|
});
|
|
21
34
|
|
|
@@ -3,7 +3,6 @@ import { CreateBasketTool, GetBasketByIdTool, UpdateBasketStatusTool, UpdateBask
|
|
|
3
3
|
|
|
4
4
|
const basketSkill = new LuaSkill({
|
|
5
5
|
name: "basket-skill",
|
|
6
|
-
version: "1.0.0",
|
|
7
6
|
description: "Basket management skill",
|
|
8
7
|
context: "Basket management skill",
|
|
9
8
|
tools: [new CreateBasketTool(), new GetBasketByIdTool(), new UpdateBasketStatusTool(), new UpdateBasketMetadataTool(), new CheckoutBasketTool(), new GetBasketsTool(), new AddItemToBasketTool(), new RemoveItemFromBasketTool(), new ClearBasketTool()],
|
|
@@ -4,7 +4,6 @@ import { SearchProductsTool, CreateProductTool, UpdateProductTool, GetAllProduct
|
|
|
4
4
|
|
|
5
5
|
const productSkill = new LuaSkill({
|
|
6
6
|
name: "product-skill",
|
|
7
|
-
version: "1.0.0",
|
|
8
7
|
description: "Product management skill",
|
|
9
8
|
context: "Product management skill",
|
|
10
9
|
tools: [new SearchProductsTool(), new CreateProductTool(), new UpdateProductTool(), new GetAllProductsTool(), new GetProductByIdTool(), new DeleteProductTool()],
|
|
@@ -4,7 +4,6 @@ import { CreateInlineJobTool, GetUserDataTool, UpdateUserDataTool, WritePoemTool
|
|
|
4
4
|
|
|
5
5
|
const userSkill = new LuaSkill({
|
|
6
6
|
name: "user-skill",
|
|
7
|
-
version: "1.0.0",
|
|
8
7
|
description: "User management skill",
|
|
9
8
|
context: "User management skill",
|
|
10
9
|
tools: [new GetUserDataTool(), new UpdateUserDataTool(), new WritePoemTool(), new CreateInlineJobTool()],
|
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
* It validates signatures, processes payment events, and updates order status.
|
|
6
6
|
*
|
|
7
7
|
* Common use case: Stripe webhook for payment confirmations
|
|
8
|
+
*
|
|
9
|
+
* Webhook URLs:
|
|
10
|
+
* https://webhook.heylua.ai/{agentId}/{webhookId}
|
|
11
|
+
* https://webhook.heylua.ai/{agentId}/{webhook-name}
|
|
8
12
|
*/
|
|
9
13
|
|
|
10
14
|
import { LuaWebhook, Orders, Data } from "lua-cli";
|
|
@@ -12,10 +16,7 @@ import { z } from "zod";
|
|
|
12
16
|
|
|
13
17
|
const paymentWebhook = new LuaWebhook({
|
|
14
18
|
name: "payment-notifications",
|
|
15
|
-
version: "1.0.0",
|
|
16
19
|
description: "Receives payment notifications from payment providers",
|
|
17
|
-
context: "This webhook processes payment confirmation events from Stripe or other providers. " +
|
|
18
|
-
"It validates the payment, updates order status, and logs the transaction.",
|
|
19
20
|
|
|
20
21
|
// Headers typically include webhook signature for verification
|
|
21
22
|
headerSchema: z.object({
|
|
@@ -40,16 +41,18 @@ const paymentWebhook = new LuaWebhook({
|
|
|
40
41
|
})
|
|
41
42
|
}),
|
|
42
43
|
|
|
43
|
-
execute: async (
|
|
44
|
-
|
|
44
|
+
execute: async (event: any) => {
|
|
45
|
+
const { headers, body } = event;
|
|
46
|
+
console.log(`💳 Payment event received:`, body?.type);
|
|
45
47
|
|
|
46
|
-
// In production: Verify Stripe signature
|
|
48
|
+
// In production: Verify Stripe signature manually in your execute function
|
|
47
49
|
// const signature = headers['stripe-signature'];
|
|
48
|
-
// const
|
|
50
|
+
// const secret = env('STRIPE_WEBHOOK_SECRET');
|
|
51
|
+
// const isValid = verifyStripeSignature(body, signature, secret);
|
|
49
52
|
// if (!isValid) throw new Error('Invalid signature');
|
|
50
53
|
|
|
51
|
-
const payment = body
|
|
52
|
-
const eventType = body
|
|
54
|
+
const payment = body?.data?.object;
|
|
55
|
+
const eventType = body?.type;
|
|
53
56
|
|
|
54
57
|
// Handle payment success
|
|
55
58
|
if (eventType === 'payment_intent.succeeded') {
|