lua-cli 3.1.0-alpha.2 → 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.
Files changed (70) hide show
  1. package/README.md +0 -4
  2. package/dist/api/job.api.service.d.ts +23 -100
  3. package/dist/api/job.api.service.js +13 -11
  4. package/dist/api/lazy-instances.d.ts +8 -0
  5. package/dist/api/lazy-instances.js +16 -0
  6. package/dist/api/postprocessor.api.service.d.ts +1 -8
  7. package/dist/api/postprocessor.api.service.js +1 -2
  8. package/dist/api/preprocessor.api.service.d.ts +1 -8
  9. package/dist/api/preprocessor.api.service.js +1 -2
  10. package/dist/api/webhook.api.service.d.ts +1 -3
  11. package/dist/api/webhook.api.service.js +1 -1
  12. package/dist/api/whatsapp-templates.api.service.d.ts +40 -0
  13. package/dist/api/whatsapp-templates.api.service.js +78 -0
  14. package/dist/api-exports.d.ts +81 -2
  15. package/dist/api-exports.js +91 -15
  16. package/dist/commands/chat.js +2 -4
  17. package/dist/commands/init.js +11 -44
  18. package/dist/commands/jobs.js +5 -5
  19. package/dist/commands/push.js +2 -9
  20. package/dist/common/job.instance.d.ts +35 -7
  21. package/dist/common/job.instance.js +46 -19
  22. package/dist/config/constants.d.ts +1 -1
  23. package/dist/config/constants.js +1 -5
  24. package/dist/interfaces/agent.d.ts +0 -3
  25. package/dist/interfaces/index.d.ts +1 -1
  26. package/dist/interfaces/init.d.ts +0 -1
  27. package/dist/interfaces/jobs.d.ts +88 -132
  28. package/dist/interfaces/jobs.js +1 -1
  29. package/dist/interfaces/postprocessors.d.ts +0 -3
  30. package/dist/interfaces/preprocessors.d.ts +0 -3
  31. package/dist/interfaces/webhooks.d.ts +0 -5
  32. package/dist/interfaces/whatsapp-templates.d.ts +104 -0
  33. package/dist/interfaces/whatsapp-templates.js +5 -0
  34. package/dist/types/api-contracts.d.ts +32 -0
  35. package/dist/types/compile.types.d.ts +0 -6
  36. package/dist/types/index.d.ts +1 -1
  37. package/dist/types/skill.d.ts +61 -90
  38. package/dist/types/skill.js +28 -86
  39. package/dist/utils/agent-management.d.ts +3 -5
  40. package/dist/utils/agent-management.js +6 -8
  41. package/dist/utils/bundling.js +5 -6
  42. package/dist/utils/compile.d.ts +0 -1
  43. package/dist/utils/compile.js +1 -51
  44. package/dist/utils/deployment.js +0 -1
  45. package/dist/utils/dev-api.js +0 -2
  46. package/dist/utils/files.d.ts +3 -3
  47. package/dist/utils/files.js +4 -12
  48. package/dist/utils/init-agent.d.ts +1 -2
  49. package/dist/utils/init-agent.js +4 -6
  50. package/dist/utils/init-helpers.d.ts +2 -4
  51. package/dist/utils/init-helpers.js +4 -10
  52. package/dist/utils/job-management.js +0 -2
  53. package/dist/utils/postprocessor-management.js +2 -4
  54. package/dist/utils/preprocessor-management.js +2 -4
  55. package/dist/utils/sandbox.js +17 -7
  56. package/dist/utils/webhook-management.js +1 -3
  57. package/package.json +1 -1
  58. package/template/QUICKSTART.md +0 -13
  59. package/template/README.md +6 -7
  60. package/template/src/jobs/AbandonedBasketProcessorJob.ts +0 -3
  61. package/template/src/jobs/DailyCleanupJob.ts +0 -3
  62. package/template/src/jobs/DataMigrationJob.ts +0 -3
  63. package/template/src/jobs/HealthCheckJob.ts +0 -3
  64. package/template/src/postprocessors/modifyResponse.ts +0 -1
  65. package/template/src/preprocessors/messageMatching.ts +18 -5
  66. package/template/src/skills/basket.skill.ts +0 -1
  67. package/template/src/skills/product.skill.ts +0 -1
  68. package/template/src/skills/user.skill.ts +0 -1
  69. package/template/src/webhooks/PaymentWebhook.ts +12 -9
  70. package/template/src/webhooks/UserEventWebhook.ts +39 -11
@@ -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, welcomeMessage) {
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}${welcomeMessageSection}
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, welcomeMessage) {
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, welcomeMessage) {
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 and welcome message
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
  }>;
@@ -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 and welcome message
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 and welcome message
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, welcomeMessage?: string, agentName?: string): 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, welcomeMessage?: string): void;
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, welcomeMessage, agentName) {
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, welcomeMessage);
33
+ createSkillYaml(agentId, orgId, undefined, undefined, persona);
35
34
  // Update LuaAgent in index.ts with agent configuration
36
- updateLuaAgentInIndexFile(currentDir, agentName, persona, welcomeMessage);
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, welcomeMessage) {
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 { SKILL_DEFAULTS, YAML_FORMAT } from '../config/compile.constants.js';
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 { SKILL_DEFAULTS, YAML_FORMAT } from '../config/compile.constants.js';
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
  }
@@ -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
- get: async (jobId) => jobService.getJob(jobId)
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 (query, headers, body) => {
352
+ module.exports = async (event) => {
349
353
  try{
350
- return await executeFunction(query, headers, body);
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 webhook input structure
380
+ // Get the exported function and execute with unified event object
377
381
  const executeFunction = context.module.exports;
378
- return await executeFunction({ query, headers, body });
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.2",
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",
@@ -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({
@@ -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 URL after deployment:
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, persona, welcomeMessage to both files
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 ({ body }) => {
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
- context: "Matches the message to the appropriate skill",
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 [{ type: "text", text: "Tell the user that you got their test message and nothing else" }];
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
- return messages;
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 ({ headers, body }) => {
44
- console.log(`💳 Payment event received:`, body.type);
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 isValid = verifyStripeSignature(body, signature);
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.data.object;
52
- const eventType = body.type;
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') {