lua-cli 2.5.8 â 3.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/job.api.service.d.ts +210 -0
- package/dist/api/job.api.service.js +200 -0
- package/dist/api/lazy-instances.d.ts +24 -0
- package/dist/api/lazy-instances.js +48 -0
- package/dist/api/postprocessor.api.service.d.ts +98 -0
- package/dist/api/postprocessor.api.service.js +76 -0
- package/dist/api/preprocessor.api.service.d.ts +98 -0
- package/dist/api/preprocessor.api.service.js +76 -0
- package/dist/api/user.data.api.service.d.ts +13 -0
- package/dist/api/user.data.api.service.js +20 -0
- package/dist/api/webhook.api.service.d.ts +151 -0
- package/dist/api/webhook.api.service.js +134 -0
- package/dist/api-exports.d.ts +156 -41
- package/dist/api-exports.js +182 -21
- package/dist/cli/command-definitions.js +75 -5
- package/dist/commands/compile.js +124 -5
- package/dist/commands/index.d.ts +4 -0
- package/dist/commands/index.js +4 -0
- package/dist/commands/init.js +53 -7
- package/dist/commands/jobs.d.ts +20 -0
- package/dist/commands/jobs.js +533 -0
- package/dist/commands/logs.js +2 -5
- package/dist/commands/postprocessors.d.ts +8 -0
- package/dist/commands/postprocessors.js +431 -0
- package/dist/commands/preprocessors.d.ts +8 -0
- package/dist/commands/preprocessors.js +431 -0
- package/dist/commands/push.js +684 -5
- package/dist/commands/test.d.ts +9 -18
- package/dist/commands/test.js +558 -82
- package/dist/commands/webhooks.d.ts +18 -0
- package/dist/commands/webhooks.js +424 -0
- package/dist/common/job.instance.d.ts +77 -0
- package/dist/common/job.instance.js +108 -0
- package/dist/common/user.instance.d.ts +1 -0
- package/dist/common/user.instance.js +9 -0
- package/dist/config/constants.d.ts +2 -2
- package/dist/config/constants.js +4 -4
- package/dist/interfaces/agent.d.ts +2 -1
- package/dist/interfaces/chat.d.ts +22 -0
- package/dist/interfaces/index.d.ts +10 -0
- package/dist/interfaces/index.js +7 -0
- package/dist/interfaces/jobs.d.ts +172 -0
- package/dist/interfaces/jobs.js +5 -0
- package/dist/interfaces/postprocessors.d.ts +35 -0
- package/dist/interfaces/postprocessors.js +4 -0
- package/dist/interfaces/preprocessors.d.ts +35 -0
- package/dist/interfaces/preprocessors.js +4 -0
- package/dist/interfaces/webhooks.d.ts +104 -0
- package/dist/interfaces/webhooks.js +5 -0
- package/dist/types/api-contracts.d.ts +5 -0
- package/dist/types/compile.types.d.ts +49 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +1 -1
- package/dist/types/skill.d.ts +502 -0
- package/dist/types/skill.js +477 -0
- package/dist/utils/agent-management.d.ts +25 -0
- package/dist/utils/agent-management.js +67 -0
- package/dist/utils/bundling.d.ts +31 -1
- package/dist/utils/bundling.js +653 -10
- package/dist/utils/compile.d.ts +63 -0
- package/dist/utils/compile.js +691 -36
- package/dist/utils/deployment.d.ts +2 -1
- package/dist/utils/deployment.js +16 -2
- package/dist/utils/init-agent.d.ts +3 -1
- package/dist/utils/init-agent.js +6 -4
- package/dist/utils/init-prompts.d.ts +2 -1
- package/dist/utils/init-prompts.js +14 -9
- package/dist/utils/job-management.d.ts +24 -0
- package/dist/utils/job-management.js +264 -0
- package/dist/utils/postprocessor-management.d.ts +9 -0
- package/dist/utils/postprocessor-management.js +118 -0
- package/dist/utils/preprocessor-management.d.ts +9 -0
- package/dist/utils/preprocessor-management.js +118 -0
- package/dist/utils/sandbox.d.ts +61 -1
- package/dist/utils/sandbox.js +283 -72
- package/dist/utils/tool-detection.d.ts +3 -2
- package/dist/utils/tool-detection.js +18 -4
- package/dist/utils/webhook-management.d.ts +24 -0
- package/dist/utils/webhook-management.js +256 -0
- package/package.json +1 -1
- package/template/AGENT_CONFIGURATION.md +251 -0
- package/template/COMPLEX_JOB_EXAMPLES.md +795 -0
- package/template/DYNAMIC_JOB_CREATION.md +371 -0
- package/template/README.md +30 -2
- package/template/WEBHOOKS_JOBS_QUICKSTART.md +318 -0
- package/template/WEBHOOK_JOB_EXAMPLES.md +817 -0
- package/template/src/index-agent-example.ts +201 -0
- package/template/src/index.ts +39 -0
- package/template/src/jobs/AbandonedBasketProcessorJob.ts +139 -0
- package/template/src/jobs/DailyCleanupJob.ts +100 -0
- package/template/src/jobs/DataMigrationJob.ts +133 -0
- package/template/src/jobs/HealthCheckJob.ts +87 -0
- package/template/src/postprocessors/ResponseFormatter.ts +151 -0
- package/template/src/preprocessors/MessageFilter.ts +91 -0
- package/template/src/tools/GameScoreTrackerTool.ts +356 -0
- package/template/src/tools/SmartBasketTool.ts +188 -0
- package/template/src/webhooks/PaymentWebhook.ts +113 -0
- package/template/src/webhooks/UserEventWebhook.ts +77 -0
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook Management Utilities
|
|
3
|
+
* Handles webhook creation via API and YAML configuration management
|
|
4
|
+
*/
|
|
5
|
+
import fs from "fs";
|
|
6
|
+
import path from "path";
|
|
7
|
+
import yaml from "js-yaml";
|
|
8
|
+
import WebhookApi from '../api/webhook.api.service.js';
|
|
9
|
+
import { BASE_URLS } from '../config/constants.js';
|
|
10
|
+
import { loadApiKey } from '../services/auth.js';
|
|
11
|
+
import { COMPILE_FILES, SKILL_DEFAULTS, YAML_FORMAT, } from '../config/compile.constants.js';
|
|
12
|
+
/**
|
|
13
|
+
* Ensures all detected webhooks exist in the YAML config with valid webhook IDs.
|
|
14
|
+
* If a webhook doesn't exist or has no ID, creates it via the API.
|
|
15
|
+
*
|
|
16
|
+
* @param webhooksArray - Array of webhooks detected from source code
|
|
17
|
+
* @param config - The skill configuration from lua.skill.yaml
|
|
18
|
+
* @returns Updated webhooks array with valid webhook IDs
|
|
19
|
+
*/
|
|
20
|
+
export async function ensureWebhooksExistInYaml(webhooksArray, config) {
|
|
21
|
+
const updatedWebhooksArray = [];
|
|
22
|
+
let yamlUpdated = false;
|
|
23
|
+
const existingWebhooks = config?.webhooks || [];
|
|
24
|
+
const existingWebhooksMap = createWebhooksMap(existingWebhooks);
|
|
25
|
+
// Process each detected webhook
|
|
26
|
+
for (const webhook of webhooksArray) {
|
|
27
|
+
const existingWebhook = existingWebhooksMap.get(webhook.name);
|
|
28
|
+
if (existingWebhook && existingWebhook.webhookId && existingWebhook.webhookId !== '') {
|
|
29
|
+
// Webhook exists with valid webhookId - reuse it
|
|
30
|
+
updatedWebhooksArray.push({
|
|
31
|
+
...webhook,
|
|
32
|
+
webhookId: existingWebhook.webhookId
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
// Webhook doesn't exist or missing webhookId - create via API
|
|
37
|
+
const createdWebhook = await createWebhookViaApi(webhook, config, existingWebhooks, existingWebhook);
|
|
38
|
+
updatedWebhooksArray.push(createdWebhook);
|
|
39
|
+
yamlUpdated = true;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Update YAML file if any changes were made
|
|
43
|
+
if (yamlUpdated) {
|
|
44
|
+
await updateYamlWithWebhooks(config);
|
|
45
|
+
}
|
|
46
|
+
return updatedWebhooksArray;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Creates a map of existing webhooks for quick lookup by name.
|
|
50
|
+
*
|
|
51
|
+
* @param existingWebhooks - Array of webhooks from YAML config
|
|
52
|
+
* @returns Map of webhook names to webhook objects
|
|
53
|
+
*/
|
|
54
|
+
function createWebhooksMap(existingWebhooks) {
|
|
55
|
+
const map = new Map();
|
|
56
|
+
existingWebhooks.forEach((webhook) => {
|
|
57
|
+
map.set(webhook.name, webhook);
|
|
58
|
+
});
|
|
59
|
+
return map;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Creates a new webhook via the Lua API and updates the config.
|
|
63
|
+
*
|
|
64
|
+
* @param webhook - The webhook to create
|
|
65
|
+
* @param config - The skill configuration
|
|
66
|
+
* @param existingWebhooks - Array of existing webhooks (mutated)
|
|
67
|
+
* @param existingWebhook - The existing webhook entry if one exists (may be without ID)
|
|
68
|
+
* @returns The webhook with its new ID
|
|
69
|
+
*/
|
|
70
|
+
async function createWebhookViaApi(webhook, config, existingWebhooks, existingWebhook) {
|
|
71
|
+
try {
|
|
72
|
+
// Validate prerequisites
|
|
73
|
+
const apiKey = await loadApiKey();
|
|
74
|
+
if (!apiKey) {
|
|
75
|
+
throw new Error("No API key found. Run 'lua auth configure' first.");
|
|
76
|
+
}
|
|
77
|
+
const agentId = config?.agent?.agentId;
|
|
78
|
+
if (!agentId) {
|
|
79
|
+
throw new Error("No agent ID found in lua.skill.yaml. Run 'lua init' first.");
|
|
80
|
+
}
|
|
81
|
+
// Create webhook via API
|
|
82
|
+
const webhookPayload = {
|
|
83
|
+
name: webhook.name,
|
|
84
|
+
description: webhook.description || `A Lua webhook for ${webhook.name}`,
|
|
85
|
+
context: webhook.context || ''
|
|
86
|
+
};
|
|
87
|
+
const webhookApi = new WebhookApi(BASE_URLS.API, apiKey, agentId);
|
|
88
|
+
const result = await webhookApi.createWebhook(webhookPayload);
|
|
89
|
+
if (result.success && result.data && result.data.id) {
|
|
90
|
+
const newWebhookId = result.data.id;
|
|
91
|
+
// Update YAML config with new webhook ID
|
|
92
|
+
if (!existingWebhook) {
|
|
93
|
+
existingWebhooks.push({
|
|
94
|
+
name: webhook.name || '',
|
|
95
|
+
version: webhook.version || SKILL_DEFAULTS.VERSION,
|
|
96
|
+
webhookId: newWebhookId
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
existingWebhook.webhookId = newWebhookId;
|
|
101
|
+
}
|
|
102
|
+
// Add webhooks to config if not already present
|
|
103
|
+
if (!config.webhooks) {
|
|
104
|
+
config.webhooks = existingWebhooks;
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
...webhook,
|
|
108
|
+
webhookId: newWebhookId
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
console.error(`â Failed to create webhook ${webhook.name}:`, result.error);
|
|
113
|
+
throw new Error(result.error?.message || 'Failed to create webhook - no ID returned from API');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
console.error(`â Failed to create webhook ${webhook.name}:`, error);
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Updates the lua.skill.yaml file with the current webhooks array.
|
|
123
|
+
* Ensures no undefined values are written to the YAML file.
|
|
124
|
+
*
|
|
125
|
+
* @param config - Current skill configuration to merge with
|
|
126
|
+
*/
|
|
127
|
+
async function updateYamlWithWebhooks(config) {
|
|
128
|
+
const webhooks = config?.webhooks || [];
|
|
129
|
+
// Clean webhooks array to ensure no undefined values
|
|
130
|
+
const cleanedWebhooks = webhooks.map(webhook => ({
|
|
131
|
+
name: webhook.name || '',
|
|
132
|
+
version: webhook.version || SKILL_DEFAULTS.VERSION,
|
|
133
|
+
webhookId: webhook.webhookId || ''
|
|
134
|
+
}));
|
|
135
|
+
// Update config with cleaned webhooks array
|
|
136
|
+
const updatedConfig = {
|
|
137
|
+
...config,
|
|
138
|
+
webhooks: cleanedWebhooks
|
|
139
|
+
};
|
|
140
|
+
// Write updated YAML with consistent formatting
|
|
141
|
+
const yamlPath = path.join(process.cwd(), COMPILE_FILES.LUA_SKILL_YAML);
|
|
142
|
+
const yamlContent = yaml.dump(updatedConfig, {
|
|
143
|
+
indent: YAML_FORMAT.INDENT,
|
|
144
|
+
lineWidth: YAML_FORMAT.LINE_WIDTH,
|
|
145
|
+
noRefs: YAML_FORMAT.NO_REFS,
|
|
146
|
+
replacer: (key, value) => {
|
|
147
|
+
// Replace undefined values with empty strings
|
|
148
|
+
return value === undefined ? '' : value;
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
fs.writeFileSync(yamlPath, yamlContent);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Syncs the server webhooks with the YAML configuration.
|
|
155
|
+
* Performs a two-way sync:
|
|
156
|
+
* 1. Deletes/deactivates webhooks from server that aren't in YAML
|
|
157
|
+
* 2. Updates YAML with active version numbers from server
|
|
158
|
+
*
|
|
159
|
+
* @param config - The skill configuration from lua.skill.yaml
|
|
160
|
+
* @returns Array of messages about sync operations
|
|
161
|
+
*/
|
|
162
|
+
export async function syncServerWebhooksWithYaml(config) {
|
|
163
|
+
const messages = [];
|
|
164
|
+
let yamlNeedsUpdate = false;
|
|
165
|
+
try {
|
|
166
|
+
// Validate prerequisites
|
|
167
|
+
const apiKey = await loadApiKey();
|
|
168
|
+
if (!apiKey) {
|
|
169
|
+
console.warn("â ī¸ No API key found. Skipping server webhook sync.");
|
|
170
|
+
return messages;
|
|
171
|
+
}
|
|
172
|
+
const agentId = config?.agent?.agentId;
|
|
173
|
+
if (!agentId) {
|
|
174
|
+
console.warn("â ī¸ No agent ID found in lua.skill.yaml. Skipping server webhook sync.");
|
|
175
|
+
return messages;
|
|
176
|
+
}
|
|
177
|
+
// Get webhooks from server
|
|
178
|
+
const webhookApi = new WebhookApi(BASE_URLS.API, apiKey, agentId);
|
|
179
|
+
const serverWebhooksResponse = await webhookApi.getWebhooks();
|
|
180
|
+
if (!serverWebhooksResponse.success || !serverWebhooksResponse.data?.webhooks) {
|
|
181
|
+
console.warn("â ī¸ Could not retrieve server webhooks. Skipping server webhook sync.");
|
|
182
|
+
return messages;
|
|
183
|
+
}
|
|
184
|
+
const serverWebhooks = serverWebhooksResponse.data.webhooks;
|
|
185
|
+
const yamlWebhooks = config?.webhooks || [];
|
|
186
|
+
// Create maps for efficient lookup
|
|
187
|
+
const yamlWebhooksMap = new Map(yamlWebhooks
|
|
188
|
+
.filter((webhook) => webhook.webhookId)
|
|
189
|
+
.map((webhook) => [webhook.webhookId, webhook]));
|
|
190
|
+
const serverWebhooksMap = new Map(serverWebhooks.map(webhook => [webhook.id, webhook]));
|
|
191
|
+
// Part 1: Delete webhooks from server that aren't in YAML
|
|
192
|
+
const webhooksToDelete = serverWebhooks.filter(serverWebhook => !yamlWebhooksMap.has(serverWebhook.id));
|
|
193
|
+
for (const webhook of webhooksToDelete) {
|
|
194
|
+
try {
|
|
195
|
+
const deleteResponse = await webhookApi.deleteWebhook(webhook.id);
|
|
196
|
+
if (deleteResponse.success && deleteResponse.data) {
|
|
197
|
+
if (deleteResponse.data.deleted) {
|
|
198
|
+
const msg = `â
Deleted webhook "${webhook.name}" from server`;
|
|
199
|
+
messages.push(msg);
|
|
200
|
+
console.log(msg);
|
|
201
|
+
}
|
|
202
|
+
else if (deleteResponse.data.deactivated) {
|
|
203
|
+
const msg = `â ī¸ Webhook "${webhook.name}" has versions and cannot be deleted. It has been deactivated instead.`;
|
|
204
|
+
messages.push(msg);
|
|
205
|
+
console.warn(msg);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
const msg = `â Failed to delete webhook "${webhook.name}": ${deleteResponse.error?.message || 'Unknown error'}`;
|
|
210
|
+
messages.push(msg);
|
|
211
|
+
console.error(msg);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
catch (error) {
|
|
215
|
+
const msg = `â Error deleting webhook "${webhook.name}": ${error}`;
|
|
216
|
+
messages.push(msg);
|
|
217
|
+
console.error(msg);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
// Part 2: Sync version numbers from server to YAML
|
|
221
|
+
const updatedYamlWebhooks = yamlWebhooks.map((yamlWebhook) => {
|
|
222
|
+
const serverWebhook = serverWebhooksMap.get(yamlWebhook.webhookId);
|
|
223
|
+
if (serverWebhook && serverWebhook.versions && serverWebhook.versions.length > 0) {
|
|
224
|
+
// Find the active version on the server
|
|
225
|
+
const activeVersion = serverWebhook.versions.find((v) => v.isActive);
|
|
226
|
+
if (activeVersion && activeVersion.version !== yamlWebhook.version) {
|
|
227
|
+
const msg = `đ Updated "${yamlWebhook.name}" webhook version in YAML: ${yamlWebhook.version} â ${activeVersion.version}`;
|
|
228
|
+
messages.push(msg);
|
|
229
|
+
console.log(msg);
|
|
230
|
+
yamlNeedsUpdate = true;
|
|
231
|
+
return {
|
|
232
|
+
...yamlWebhook,
|
|
233
|
+
version: activeVersion.version
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return yamlWebhook;
|
|
238
|
+
});
|
|
239
|
+
// Update YAML file if versions changed
|
|
240
|
+
if (yamlNeedsUpdate) {
|
|
241
|
+
const updatedConfig = {
|
|
242
|
+
...config,
|
|
243
|
+
webhooks: updatedYamlWebhooks
|
|
244
|
+
};
|
|
245
|
+
await updateYamlWithWebhooks(updatedConfig);
|
|
246
|
+
console.log("â
YAML webhook versions synced with server");
|
|
247
|
+
}
|
|
248
|
+
if (webhooksToDelete.length === 0 && !yamlNeedsUpdate) {
|
|
249
|
+
console.log("â
Server webhooks and YAML are fully in sync");
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
console.error("â Error syncing server webhooks:", error);
|
|
254
|
+
}
|
|
255
|
+
return messages;
|
|
256
|
+
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# Agent Configuration Guide
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
There are two ways to configure your Lua agent:
|
|
6
|
+
|
|
7
|
+
1. **LuaAgent (Recommended)** - Unified, simple approach
|
|
8
|
+
2. **Individual Components (Legacy)** - Separate exports for each component
|
|
9
|
+
|
|
10
|
+
Both approaches are fully supported and backward compatible.
|
|
11
|
+
|
|
12
|
+
## Approach 1: LuaAgent (Recommended)
|
|
13
|
+
|
|
14
|
+
The `LuaAgent` provides a simplified, unified way to configure your agent. All components (skills, webhooks, jobs, processors) are defined in one place.
|
|
15
|
+
|
|
16
|
+
### Benefits
|
|
17
|
+
|
|
18
|
+
- **Simpler**: One object contains everything
|
|
19
|
+
- **Clearer**: Easy to see all components at a glance
|
|
20
|
+
- **Persona Sync**: Agent persona automatically syncs with `lua.skill.yaml`
|
|
21
|
+
- **Better Organization**: Natural hierarchy of components
|
|
22
|
+
- **Less Boilerplate**: No need to export multiple separate items
|
|
23
|
+
|
|
24
|
+
### Example
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { LuaAgent, LuaSkill } from 'lua-cli';
|
|
28
|
+
import { weatherSkill } from './skills/weather';
|
|
29
|
+
import { userSkill } from './skills/user';
|
|
30
|
+
import { healthCheckJob } from './jobs/health-check';
|
|
31
|
+
import { userWebhook } from './webhooks/user';
|
|
32
|
+
|
|
33
|
+
// Define your agent with all components in one place
|
|
34
|
+
export const agent = new LuaAgent({
|
|
35
|
+
name: 'my-assistant',
|
|
36
|
+
|
|
37
|
+
// Agent personality and behavior
|
|
38
|
+
persona: `You are a helpful assistant that can provide weather information
|
|
39
|
+
and manage user accounts. Be friendly and concise.`,
|
|
40
|
+
|
|
41
|
+
// Welcome message shown to new users
|
|
42
|
+
welcomeMessage: 'Hello! How can I help you today?',
|
|
43
|
+
|
|
44
|
+
// Skills - collections of tools
|
|
45
|
+
skills: [weatherSkill, userSkill],
|
|
46
|
+
|
|
47
|
+
// Webhooks - HTTP endpoints for external events
|
|
48
|
+
webhooks: [userWebhook],
|
|
49
|
+
|
|
50
|
+
// Jobs - scheduled tasks
|
|
51
|
+
jobs: [healthCheckJob],
|
|
52
|
+
|
|
53
|
+
// Preprocessors - modify messages before they reach the agent
|
|
54
|
+
preProcessors: [],
|
|
55
|
+
|
|
56
|
+
// Postprocessors - modify responses before they reach the user
|
|
57
|
+
postProcessors: []
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### File Structure
|
|
62
|
+
|
|
63
|
+
When using `LuaAgent`, organize your code like this:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
src/
|
|
67
|
+
âââ index.ts # Main agent configuration
|
|
68
|
+
âââ skills/
|
|
69
|
+
â âââ weather-skill.ts # Weather skill with tools
|
|
70
|
+
â âââ user-skill.ts # User management skill
|
|
71
|
+
âââ tools/
|
|
72
|
+
â âââ WeatherTool.ts # Individual tool classes
|
|
73
|
+
â âââ UserTool.ts
|
|
74
|
+
âââ webhooks/
|
|
75
|
+
â âââ UserWebhook.ts # Webhook handlers
|
|
76
|
+
âââ jobs/
|
|
77
|
+
â âââ HealthCheckJob.ts # Scheduled jobs
|
|
78
|
+
âââ processors/
|
|
79
|
+
âââ MessageFilter.ts # Preprocessors
|
|
80
|
+
âââ ResponseFormatter.ts # Postprocessors
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Compilation
|
|
84
|
+
|
|
85
|
+
When you run `lua compile`, the compiler will:
|
|
86
|
+
|
|
87
|
+
1. Detect the `LuaAgent` in `index.ts`
|
|
88
|
+
2. Extract the agent's persona and welcome message
|
|
89
|
+
3. Sync them with `lua.skill.yaml`
|
|
90
|
+
4. Extract all skills, webhooks, jobs, and processors
|
|
91
|
+
5. Bundle and deploy everything
|
|
92
|
+
|
|
93
|
+
Output during compilation:
|
|
94
|
+
```
|
|
95
|
+
⨠Found LuaAgent: my-assistant
|
|
96
|
+
Using new unified agent configuration approach
|
|
97
|
+
â
Synced agent persona to lua.skill.yaml
|
|
98
|
+
đĻ Agent contains: 2 skill(s), 1 webhook(s), 1 job(s), 0 preprocessor(s), 0 postprocessor(s)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Approach 2: Individual Components (Legacy)
|
|
102
|
+
|
|
103
|
+
The legacy approach exports each component type separately. This is still fully supported for backward compatibility.
|
|
104
|
+
|
|
105
|
+
### Example
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
import { LuaSkill, LuaJob, LuaWebhook } from 'lua-cli';
|
|
109
|
+
|
|
110
|
+
// Export skills individually
|
|
111
|
+
export const weatherSkill = new LuaSkill({
|
|
112
|
+
name: 'weather-skill',
|
|
113
|
+
version: '1.0.0',
|
|
114
|
+
description: 'Weather information',
|
|
115
|
+
context: 'Provides current weather data',
|
|
116
|
+
tools: [new GetWeatherTool()]
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
export const userSkill = new LuaSkill({
|
|
120
|
+
name: 'user-skill',
|
|
121
|
+
version: '1.0.0',
|
|
122
|
+
description: 'User management',
|
|
123
|
+
context: 'Manages user accounts',
|
|
124
|
+
tools: [new GetUserTool()]
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// Export jobs individually
|
|
128
|
+
export const healthCheckJob = new LuaJob({
|
|
129
|
+
name: 'health-check',
|
|
130
|
+
version: '1.0.0',
|
|
131
|
+
description: 'System health check',
|
|
132
|
+
context: 'Monitors system status',
|
|
133
|
+
schedule: { type: 'interval', seconds: 300 },
|
|
134
|
+
execute: async () => {
|
|
135
|
+
return { status: 'healthy' };
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// Export webhooks individually
|
|
140
|
+
export const userWebhook = new LuaWebhook({
|
|
141
|
+
name: 'user-webhook',
|
|
142
|
+
version: '1.0.0',
|
|
143
|
+
description: 'User event handler',
|
|
144
|
+
context: 'Processes user events',
|
|
145
|
+
execute: async ({ body }) => {
|
|
146
|
+
return { received: true };
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Compilation
|
|
152
|
+
|
|
153
|
+
When you run `lua compile`, the compiler will:
|
|
154
|
+
|
|
155
|
+
1. Scan for individual `LuaSkill`, `LuaJob`, `LuaWebhook`, etc.
|
|
156
|
+
2. Extract each component separately
|
|
157
|
+
3. Bundle and deploy everything
|
|
158
|
+
|
|
159
|
+
Output during compilation:
|
|
160
|
+
```
|
|
161
|
+
âšī¸ No LuaAgent found, using legacy detection for individual components
|
|
162
|
+
đĻ Found 2 skill(s)...
|
|
163
|
+
đĻ Found 1 webhook(s)...
|
|
164
|
+
đĻ Found 1 job(s)...
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Comparison
|
|
168
|
+
|
|
169
|
+
| Feature | LuaAgent | Individual Components |
|
|
170
|
+
|---------|----------|----------------------|
|
|
171
|
+
| **Configuration Style** | Single unified object | Multiple separate exports |
|
|
172
|
+
| **Persona Management** | Auto-synced with YAML | Manual YAML editing |
|
|
173
|
+
| **Code Organization** | Hierarchical | Flat |
|
|
174
|
+
| **Ease of Use** | âââââ | âââ |
|
|
175
|
+
| **Backward Compatible** | â
| â
|
|
|
176
|
+
| **Use Case** | New projects, simple setup | Existing projects, gradual migration |
|
|
177
|
+
|
|
178
|
+
## When to Use Each Approach
|
|
179
|
+
|
|
180
|
+
### Use LuaAgent when:
|
|
181
|
+
|
|
182
|
+
- â
Starting a new project
|
|
183
|
+
- â
You want a simple, unified configuration
|
|
184
|
+
- â
You want automatic persona synchronization
|
|
185
|
+
- â
You prefer a clear hierarchy of components
|
|
186
|
+
|
|
187
|
+
### Use Individual Components when:
|
|
188
|
+
|
|
189
|
+
- â
Maintaining an existing project
|
|
190
|
+
- â
Gradually migrating to the new approach
|
|
191
|
+
- â
You prefer more granular control
|
|
192
|
+
- â
Working with a legacy codebase
|
|
193
|
+
|
|
194
|
+
## Migration Guide
|
|
195
|
+
|
|
196
|
+
If you have an existing project using individual components, you can migrate to `LuaAgent` gradually:
|
|
197
|
+
|
|
198
|
+
### Step 1: Keep Your Existing Files
|
|
199
|
+
|
|
200
|
+
Don't change your skill/webhook/job definitions. They can stay in separate files.
|
|
201
|
+
|
|
202
|
+
### Step 2: Create LuaAgent
|
|
203
|
+
|
|
204
|
+
In your `index.ts`, import all components and create a `LuaAgent`:
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
// Import existing components
|
|
208
|
+
import { weatherSkill } from './skills/weather';
|
|
209
|
+
import { userSkill } from './skills/user';
|
|
210
|
+
import { healthCheckJob } from './jobs/health-check';
|
|
211
|
+
|
|
212
|
+
// Create LuaAgent that references them
|
|
213
|
+
export const agent = new LuaAgent({
|
|
214
|
+
name: 'my-assistant',
|
|
215
|
+
persona: 'Your agent persona here',
|
|
216
|
+
skills: [weatherSkill, userSkill],
|
|
217
|
+
jobs: [healthCheckJob]
|
|
218
|
+
});
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Step 3: Remove Individual Exports
|
|
222
|
+
|
|
223
|
+
Remove any `export` keywords from your skill/webhook/job files, or keep them for testing.
|
|
224
|
+
|
|
225
|
+
### Step 4: Test
|
|
226
|
+
|
|
227
|
+
Run `lua compile` to verify everything works:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
lua compile
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
You should see:
|
|
234
|
+
```
|
|
235
|
+
⨠Found LuaAgent: my-assistant
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Examples
|
|
239
|
+
|
|
240
|
+
See the following files for complete examples:
|
|
241
|
+
|
|
242
|
+
- `src/index-agent-example.ts` - LuaAgent approach (recommended)
|
|
243
|
+
- `src/index.ts` - Individual components approach (legacy)
|
|
244
|
+
|
|
245
|
+
## Questions?
|
|
246
|
+
|
|
247
|
+
- Check the main README.md for more information
|
|
248
|
+
- See QUICKSTART.md for getting started
|
|
249
|
+
- View WEBHOOK_JOB_EXAMPLES.md for webhook and job examples
|
|
250
|
+
- Read COMPLEX_JOB_EXAMPLES.md for advanced job patterns
|
|
251
|
+
|