lua-cli 3.0.0-alpha.1 → 3.0.0-alpha.5

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 (61) hide show
  1. package/dist/api/job.api.service.d.ts +16 -7
  2. package/dist/api/job.api.service.js +21 -5
  3. package/dist/api/postprocessor.api.service.d.ts +61 -1
  4. package/dist/api/postprocessor.api.service.js +35 -0
  5. package/dist/api/preprocessor.api.service.d.ts +61 -1
  6. package/dist/api/preprocessor.api.service.js +35 -0
  7. package/dist/api-exports.d.ts +26 -6
  8. package/dist/api-exports.js +42 -29
  9. package/dist/cli/command-definitions.js +13 -6
  10. package/dist/commands/chat.js +32 -5
  11. package/dist/commands/compile.js +16 -2
  12. package/dist/commands/dev.js +23 -2
  13. package/dist/commands/push.d.ts +6 -2
  14. package/dist/commands/push.js +412 -6
  15. package/dist/commands/test.js +18 -2
  16. package/dist/common/job.instance.d.ts +3 -0
  17. package/dist/common/job.instance.js +8 -0
  18. package/dist/config/constants.d.ts +6 -5
  19. package/dist/config/constants.js +12 -10
  20. package/dist/interfaces/chat.d.ts +30 -1
  21. package/dist/interfaces/jobs.d.ts +21 -0
  22. package/dist/types/skill.d.ts +75 -56
  23. package/dist/types/skill.js +53 -59
  24. package/dist/utils/bundling.d.ts +13 -4
  25. package/dist/utils/bundling.js +83 -26
  26. package/dist/utils/compile.js +27 -6
  27. package/dist/utils/dev-api.d.ts +42 -2
  28. package/dist/utils/dev-api.js +177 -4
  29. package/dist/utils/dev-server.d.ts +1 -1
  30. package/dist/utils/dev-server.js +4 -4
  31. package/dist/utils/dynamic-job-bundler.d.ts +17 -0
  32. package/dist/utils/dynamic-job-bundler.js +143 -0
  33. package/dist/utils/pre-bundle-jobs.d.ts +26 -0
  34. package/dist/utils/pre-bundle-jobs.js +176 -0
  35. package/dist/utils/sandbox-storage.d.ts +48 -0
  36. package/dist/utils/sandbox-storage.js +114 -0
  37. package/dist/utils/sandbox.d.ts +2 -2
  38. package/dist/utils/sandbox.js +23 -7
  39. package/package.json +1 -1
  40. package/template/lua.skill.yaml +47 -0
  41. package/template/package-lock.json +10505 -0
  42. package/template/package.json +2 -1
  43. package/template/src/index.ts +65 -3
  44. package/template/src/tools/CreateInlineJob.ts +42 -0
  45. package/API_REFERENCE.md +0 -1408
  46. package/CHANGELOG.md +0 -236
  47. package/CLI_REFERENCE.md +0 -908
  48. package/GETTING_STARTED.md +0 -1040
  49. package/INSTANCE_TYPES.md +0 -1158
  50. package/README.md +0 -865
  51. package/TEMPLATE_GUIDE.md +0 -1398
  52. package/USER_DATA_INSTANCE.md +0 -621
  53. package/template/AGENT_CONFIGURATION.md +0 -251
  54. package/template/COMPLEX_JOB_EXAMPLES.md +0 -795
  55. package/template/DYNAMIC_JOB_CREATION.md +0 -371
  56. package/template/TOOL_EXAMPLES.md +0 -655
  57. package/template/WEBHOOKS_JOBS_QUICKSTART.md +0 -318
  58. package/template/WEBHOOK_JOB_EXAMPLES.md +0 -817
  59. package/template/src/index-agent-example.ts +0 -201
  60. package/template/src/postprocessors/ResponseFormatter.ts +0 -151
  61. package/template/src/preprocessors/MessageFilter.ts +0 -91
@@ -1,371 +0,0 @@
1
- # Dynamic Job Creation from Tools
2
-
3
- **Question:** Why doesn't the SmartBasketTool actually create a job?
4
-
5
- **Answer:** There are **two approaches** for scheduling future tasks from tools. The example shows both!
6
-
7
- ---
8
-
9
- ## 🎯 Two Approaches Explained
10
-
11
- ### **Approach 1: Data-Based Scheduling** ✅ (Currently Implemented)
12
-
13
- **How it works:**
14
- 1. Tool stores reminder data in custom data collection
15
- 2. A recurring job checks for due reminders
16
- 3. When time comes, job processes the reminder
17
-
18
- **Pros:**
19
- - ✅ Simple to implement
20
- - ✅ No dynamic job creation needed
21
- - ✅ Works now (no backend changes required)
22
- - ✅ Easy to manage (single recurring job)
23
-
24
- **Cons:**
25
- - ⚠️ Requires a recurring job to run frequently
26
- - ⚠️ Less precise timing (depends on job interval)
27
- - ⚠️ More database queries
28
-
29
- **Code:**
30
- ```typescript
31
- // In the tool:
32
- await Data.create('basket-reminders', {
33
- basketId: basket.id,
34
- scheduledFor: checkTime.toISOString(),
35
- status: 'pending'
36
- });
37
-
38
- // Separate recurring job (every 15 minutes):
39
- const reminders = await Data.get('basket-reminders', {});
40
- for (const reminder of reminders) {
41
- if (new Date(reminder.scheduledFor) <= now) {
42
- // Process reminder
43
- }
44
- }
45
- ```
46
-
47
- ---
48
-
49
- ### **Approach 2: Dynamic Job Creation** 🚀 (Advanced - Commented Out)
50
-
51
- **How it works:**
52
- 1. Tool creates a one-time job via API
53
- 2. Backend scheduler runs the job at exact time
54
- 3. Job executes once and auto-deactivates
55
-
56
- **Pros:**
57
- - ✅ Precise timing (exact execution time)
58
- - ✅ No polling/recurring job needed
59
- - ✅ Each task is isolated
60
- - ✅ Auto-cleanup after execution
61
-
62
- **Cons:**
63
- - ⚠️ Requires backend API support (create jobs endpoint)
64
- - ⚠️ More complex implementation
65
- - ⚠️ More jobs in system (one per basket)
66
-
67
- **Code (when backend supports it):**
68
- ```typescript
69
- // Create job dynamically
70
- const jobPayload = {
71
- name: `check-basket-${basket.id}`,
72
- schedule: {
73
- type: 'once',
74
- executeAt: checkTime.toISOString()
75
- },
76
- executeFunction: `
77
- async () => {
78
- const basket = await Baskets.getById('${basket.id}');
79
- if (basket.status === 'active') {
80
- // Send reminder
81
- }
82
- }
83
- `
84
- };
85
-
86
- await fetch('/developer/jobs/{agentId}', {
87
- method: 'POST',
88
- body: JSON.stringify(jobPayload)
89
- });
90
- ```
91
-
92
- ---
93
-
94
- ## 📊 Comparison
95
-
96
- | Feature | Approach 1 (Data-Based) | Approach 2 (Dynamic Jobs) |
97
- |---------|------------------------|---------------------------|
98
- | **Complexity** | ⭐ Simple | ⭐⭐⭐ Complex |
99
- | **Timing Precision** | ~15 minutes | Exact |
100
- | **Backend Support** | ✅ Available now | ⏳ Coming soon |
101
- | **Jobs Created** | 1 recurring | 1 per basket |
102
- | **Database Queries** | High | Low |
103
- | **Best For** | Most use cases | High-precision timing |
104
-
105
- ---
106
-
107
- ## 🎯 When to Use Each Approach
108
-
109
- ### Use Approach 1 (Data-Based) When:
110
- - ✅ Timing doesn't need to be exact (±15 minutes is fine)
111
- - ✅ You have many similar scheduled tasks
112
- - ✅ You want simpler code
113
- - ✅ Backend doesn't support dynamic job creation yet
114
-
115
- **Examples:**
116
- - Abandoned cart reminders (3 hours ± 15 min is fine)
117
- - Follow-up emails (24 hours ± 15 min is fine)
118
- - Subscription renewals (checking daily is fine)
119
-
120
- ### Use Approach 2 (Dynamic Jobs) When:
121
- - ✅ Timing must be exact
122
- - ✅ Each task is unique
123
- - ✅ You want isolated execution
124
- - ✅ Backend supports job creation API
125
-
126
- **Examples:**
127
- - Scheduled content publishing (must be exact time)
128
- - Billing cycles (must be precise)
129
- - Auction endings (exact second matters)
130
- - Appointment reminders (exact timing important)
131
-
132
- ---
133
-
134
- ## 🔧 Implementation Details
135
-
136
- ### Approach 1: Complete Flow
137
-
138
- **Step 1 - Tool stores reminder:**
139
- ```typescript
140
- // SmartBasketTool.ts
141
- await Data.create('basket-reminders', {
142
- basketId: basket.id,
143
- scheduledFor: new Date(Date.now() + 3 * 60 * 60 * 1000).toISOString(),
144
- status: 'pending'
145
- });
146
- ```
147
-
148
- **Step 2 - Recurring job processes reminders:**
149
- ```typescript
150
- // AbandonedBasketProcessorJob.ts
151
- const job = new LuaJob({
152
- name: "process-basket-reminders",
153
- schedule: {
154
- type: 'interval',
155
- seconds: 900 // Every 15 minutes
156
- },
157
- execute: async () => {
158
- const reminders = await Data.get('basket-reminders', {});
159
- const now = new Date();
160
-
161
- for (const reminder of reminders) {
162
- if (new Date(reminder.scheduledFor) <= now && reminder.status === 'pending') {
163
- // Check basket and send reminder if abandoned
164
- const basket = await Baskets.getById(reminder.basketId);
165
-
166
- if (basket.status === 'active') {
167
- // Send reminder
168
- console.log(`📧 Sending reminder for basket ${basket.id}`);
169
- }
170
-
171
- // Mark as processed
172
- await Data.update('basket-reminders', reminder.id, { status: 'completed' });
173
- }
174
- }
175
- }
176
- });
177
- ```
178
-
179
- ---
180
-
181
- ### Approach 2: Complete Flow (When Available)
182
-
183
- **Step 1 - Tool creates job via API:**
184
- ```typescript
185
- // SmartBasketTool.ts
186
- const jobPayload = {
187
- name: `check-basket-${basket.id}`,
188
- description: `Check basket ${basket.id}`,
189
- schedule: {
190
- type: 'once',
191
- executeAt: new Date(Date.now() + 3 * 60 * 60 * 1000).toISOString()
192
- },
193
- executeFunction: `
194
- async () => {
195
- const basket = await Baskets.getById('${basket.id}');
196
- if (basket.status === 'active') {
197
- await Data.create('abandoned-baskets', { basketId: '${basket.id}' });
198
- // Send reminder
199
- }
200
- return { checked: true };
201
- }
202
- `
203
- };
204
-
205
- // Create job
206
- const response = await fetch(`/developer/jobs/{agentId}`, {
207
- method: 'POST',
208
- headers: { 'Authorization': `Bearer ${apiKey}` },
209
- body: JSON.stringify(jobPayload)
210
- });
211
-
212
- const job = await response.json();
213
-
214
- // Push version to activate it
215
- await fetch(`/developer/jobs/{agentId}/${job.id}/version`, {
216
- method: 'POST',
217
- body: JSON.stringify({ ...jobPayload, version: '1.0.0', jobId: job.id })
218
- });
219
- ```
220
-
221
- **Step 2 - Backend scheduler:**
222
- - Job is created and scheduled
223
- - At exactly 3 hours later, job executes
224
- - Job runs once and auto-deactivates
225
- - Result is logged in execution history
226
-
227
- ---
228
-
229
- ## 🚀 Current Implementation (Approach 1)
230
-
231
- The `SmartBasketTool` currently uses **Approach 1** because:
232
-
233
- 1. ✅ **Works immediately** - No backend changes needed
234
- 2. ✅ **Simple** - Easy to understand and maintain
235
- 3. ✅ **Sufficient** - 15-minute precision is fine for cart reminders
236
- 4. ✅ **Scalable** - One job handles all baskets
237
-
238
- **Files involved:**
239
- - `src/tools/SmartBasketTool.ts` - Creates basket + stores reminder
240
- - `src/jobs/AbandonedBasketProcessorJob.ts` - Processes reminders every 15 min
241
-
242
- **To enable:**
243
- ```typescript
244
- // In src/index.ts
245
- import { CreateSmartBasketTool } from "./tools/SmartBasketTool";
246
- import abandonedBasketProcessorJob from "./jobs/AbandonedBasketProcessorJob";
247
-
248
- const basketSkill = new LuaSkill({
249
- tools: [new CreateSmartBasketTool()]
250
- });
251
- ```
252
-
253
- ---
254
-
255
- ## 🔮 Future: Approach 2 (When Backend Ready)
256
-
257
- When the backend implements dynamic job creation API, you can:
258
-
259
- 1. **Uncomment Approach 2** in `SmartBasketTool.ts`
260
- 2. **Remove the data-based reminder** code
261
- 3. **Remove the recurring processor job** (no longer needed)
262
-
263
- **Benefits:**
264
- - Jobs execute at **exact** 3-hour mark
265
- - No recurring job needed
266
- - Each basket gets its own isolated job
267
- - Automatic cleanup after execution
268
-
269
- ---
270
-
271
- ## 💡 Hybrid Approach (Best of Both Worlds)
272
-
273
- You can also combine both approaches:
274
-
275
- ```typescript
276
- async execute(input: { currency: string }) {
277
- const basket = await Baskets.create({ currency: input.currency });
278
-
279
- // Approach 1: Quick fallback (works now)
280
- await Data.create('basket-reminders', {
281
- basketId: basket.id,
282
- scheduledFor: checkTime.toISOString()
283
- });
284
-
285
- // Approach 2: Try dynamic job (if backend supports it)
286
- try {
287
- const jobResponse = await createDynamicJob(basket.id, checkTime);
288
- if (jobResponse.ok) {
289
- // Dynamic job created - mark data reminder as redundant
290
- await Data.update('basket-reminders', reminder.id, {
291
- status: 'delegated-to-job'
292
- });
293
- }
294
- } catch (error) {
295
- // Fall back to approach 1 (already stored)
296
- console.log('Using data-based reminder (dynamic jobs not available)');
297
- }
298
-
299
- return { success: true, basket };
300
- }
301
- ```
302
-
303
- ---
304
-
305
- ## 📋 Summary
306
-
307
- ### Current State ✅
308
- - ✅ **SmartBasketTool** stores reminders in data
309
- - ✅ **AbandonedBasketProcessorJob** processes them every 15 minutes
310
- - ✅ **Works perfectly** for abandoned cart recovery
311
- - ✅ **No backend changes needed**
312
-
313
- ### Why No Real Job Created?
314
- Because **Approach 1 is simpler and sufficient** for most use cases!
315
-
316
- ### When Will Approach 2 Work?
317
- When backend implements:
318
- - `POST /developer/jobs/{agentId}` - Create job endpoint
319
- - `POST /developer/jobs/{agentId}/{jobId}/version` - Push job version
320
-
321
- Then you can uncomment the code in lines 65-134 of `SmartBasketTool.ts`!
322
-
323
- ---
324
-
325
- ## 🎓 Teaching Point
326
-
327
- This example teaches an important pattern:
328
-
329
- > **"Not every future task needs a separate job!"**
330
-
331
- Sometimes storing data and processing it with a recurring job is:
332
- - Simpler
333
- - More efficient
334
- - Easier to manage
335
- - Perfectly adequate
336
-
337
- **Use dynamic job creation when you truly need precision timing.**
338
-
339
- ---
340
-
341
- ## 🚀 Try It Out
342
-
343
- ```bash
344
- # 1. Enable the example
345
- # Uncomment in src/index.ts:
346
- # - CreateSmartBasketTool
347
- # - AbandonedBasketProcessorJob
348
-
349
- # 2. Compile
350
- lua compile
351
-
352
- # 3. Test the tool
353
- lua test skill
354
- # Select: create_smart_basket
355
- # See: Basket created + reminder stored
356
-
357
- # 4. Test the processor job
358
- lua test job
359
- # Select: process-basket-reminders
360
- # See: Reminders checked and processed
361
-
362
- # 5. Deploy both
363
- lua push skill
364
- lua push job
365
- lua jobs production # Activate processor job
366
- ```
367
-
368
- ---
369
-
370
- **The system is designed to work today, with an upgrade path to dynamic jobs in the future!** 🎯
371
-