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,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart Basket Tool Example
|
|
3
|
+
*
|
|
4
|
+
* This tool creates a basket AND schedules a follow-up job to check if it was abandoned.
|
|
5
|
+
* Demonstrates: Dynamic job creation, basket management, and automated follow-ups.
|
|
6
|
+
*
|
|
7
|
+
* Use case: E-commerce abandoned cart recovery
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { LuaTool, Baskets, Jobs, Data } from "lua-cli";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
|
|
13
|
+
export class CreateSmartBasketTool implements LuaTool {
|
|
14
|
+
name = "create_smart_basket";
|
|
15
|
+
description = "Creates a basket with automatic abandoned cart reminder";
|
|
16
|
+
|
|
17
|
+
inputSchema = z.object({
|
|
18
|
+
currency: z.string().default('USD')
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
async execute(input: { currency: string }) {
|
|
22
|
+
console.log('🛒 Creating smart basket with auto-reminder...');
|
|
23
|
+
|
|
24
|
+
// Step 1: Create the basket
|
|
25
|
+
const basketData = {
|
|
26
|
+
currency: input.currency,
|
|
27
|
+
metadata: {
|
|
28
|
+
createdBy: 'smart-basket-tool',
|
|
29
|
+
reminderScheduled: true,
|
|
30
|
+
createdAt: new Date().toISOString()
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const basketInstance = await Baskets.create(basketData);
|
|
35
|
+
const basketInfo = await basketInstance.getData();
|
|
36
|
+
|
|
37
|
+
console.log(`✅ Basket created: ${basketInfo.id}`);
|
|
38
|
+
|
|
39
|
+
// Step 2: Schedule a one-time job to check the basket in 3 hours
|
|
40
|
+
const checkTime = new Date(Date.now() + 3 * 60 * 60 * 1000); // 3 hours from now
|
|
41
|
+
|
|
42
|
+
// Capture basketId in closure for the job
|
|
43
|
+
const basketId = basketInfo.id;
|
|
44
|
+
|
|
45
|
+
// Create a dynamic one-time job using the Jobs API!
|
|
46
|
+
|
|
47
|
+
const job = await Jobs.create({
|
|
48
|
+
name: `check-basket-${basketId}`,
|
|
49
|
+
description: `Check if basket ${basketId} was checked out`,
|
|
50
|
+
|
|
51
|
+
// One-time job that runs in 3 hours
|
|
52
|
+
schedule: {
|
|
53
|
+
type: 'once',
|
|
54
|
+
executeAt: checkTime
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
timeout: 60, // 1 minute timeout
|
|
58
|
+
|
|
59
|
+
// Write normal TypeScript code! It will be compiled automatically
|
|
60
|
+
execute: async () => {
|
|
61
|
+
console.log(`⏰ Checking basket ${basketId}...`);
|
|
62
|
+
|
|
63
|
+
const basketInstance = await Baskets.getById(basketId);
|
|
64
|
+
const basket = await basketInstance.getData();
|
|
65
|
+
|
|
66
|
+
if (basket.status === 'active' || basket.status === 'pending') {
|
|
67
|
+
// Basket is still active - it was abandoned!
|
|
68
|
+
console.log(`🛒 Basket ${basketId} was abandoned`);
|
|
69
|
+
|
|
70
|
+
await Data.create('abandoned-baskets', {
|
|
71
|
+
basketId: basketId,
|
|
72
|
+
currency: basket.currency,
|
|
73
|
+
itemCount: basket.items?.length || 0,
|
|
74
|
+
totalValue: basket.total || 0,
|
|
75
|
+
abandonedAt: new Date().toISOString()
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
console.log('📧 Sending abandoned cart reminder email...');
|
|
79
|
+
// TODO: Integrate with email service
|
|
80
|
+
// await sendEmail({
|
|
81
|
+
// to: userEmail,
|
|
82
|
+
// template: 'abandoned-cart',
|
|
83
|
+
// data: { basket }
|
|
84
|
+
// });
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
abandoned: true,
|
|
88
|
+
basketId: basketId,
|
|
89
|
+
reminderSent: true
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
console.log(`✅ Basket ${basketId} was checked out`);
|
|
94
|
+
return {
|
|
95
|
+
abandoned: false,
|
|
96
|
+
basketId: basketId,
|
|
97
|
+
status: basket.status
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
console.log(`⏰ One-time job created: ${job.jobId}`);
|
|
103
|
+
console.log(`📅 Will execute at: ${checkTime.toLocaleString()}`);
|
|
104
|
+
|
|
105
|
+
// Return basket info with job details
|
|
106
|
+
return {
|
|
107
|
+
success: true,
|
|
108
|
+
basket: {
|
|
109
|
+
id: basketInfo.id,
|
|
110
|
+
currency: basketInfo.currency,
|
|
111
|
+
status: basketInfo.status
|
|
112
|
+
},
|
|
113
|
+
scheduledJob: {
|
|
114
|
+
jobId: job.jobId,
|
|
115
|
+
name: job.name,
|
|
116
|
+
scheduledFor: checkTime.toISOString(),
|
|
117
|
+
message: 'One-time job will check basket in 3 hours'
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Check Abandoned Baskets Tool
|
|
125
|
+
*
|
|
126
|
+
* This tool can be called manually or by a recurring job to check for abandoned baskets.
|
|
127
|
+
*/
|
|
128
|
+
export class CheckAbandonedBasketsTool implements LuaTool {
|
|
129
|
+
name = "check_abandoned_baskets";
|
|
130
|
+
description = "Checks for abandoned baskets and sends reminders";
|
|
131
|
+
|
|
132
|
+
inputSchema = z.object({
|
|
133
|
+
basketId: z.string().optional()
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
async execute(input: { basketId?: string }) {
|
|
137
|
+
console.log('🔍 Checking for abandoned baskets...');
|
|
138
|
+
|
|
139
|
+
// Get all abandoned baskets from data collection
|
|
140
|
+
const abandonedBasketsData = await Data.get('abandoned-baskets', {}, 1, 100);
|
|
141
|
+
const abandonedBaskets = abandonedBasketsData.data || [];
|
|
142
|
+
|
|
143
|
+
if (input.basketId) {
|
|
144
|
+
// Check specific basket
|
|
145
|
+
const specific = abandonedBaskets.find((ab: any) => ab.data.basketId === input.basketId);
|
|
146
|
+
|
|
147
|
+
if (specific) {
|
|
148
|
+
return {
|
|
149
|
+
basketId: input.basketId,
|
|
150
|
+
abandoned: true,
|
|
151
|
+
abandonedAt: specific.data.abandonedAt,
|
|
152
|
+
itemCount: specific.data.itemCount,
|
|
153
|
+
totalValue: specific.data.totalValue
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Not in abandoned list - check current status
|
|
158
|
+
const basketInstance = await Baskets.getById(input.basketId);
|
|
159
|
+
const basket = await basketInstance.getData();
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
basketId: input.basketId,
|
|
163
|
+
abandoned: false,
|
|
164
|
+
status: basket.status,
|
|
165
|
+
itemCount: basket.items?.length || 0
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Return all abandoned baskets summary
|
|
170
|
+
const summary = abandonedBaskets.map((ab: any) => ({
|
|
171
|
+
basketId: ab.data.basketId,
|
|
172
|
+
currency: ab.data.currency,
|
|
173
|
+
itemCount: ab.data.itemCount,
|
|
174
|
+
totalValue: ab.data.totalValue,
|
|
175
|
+
abandonedAt: ab.data.abandonedAt
|
|
176
|
+
}));
|
|
177
|
+
|
|
178
|
+
console.log(`🛒 Found ${abandonedBaskets.length} abandoned baskets`);
|
|
179
|
+
|
|
180
|
+
return {
|
|
181
|
+
success: true,
|
|
182
|
+
abandonedCount: abandonedBaskets.length,
|
|
183
|
+
abandonedBaskets: summary,
|
|
184
|
+
timestamp: new Date().toISOString()
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payment Webhook Example
|
|
3
|
+
*
|
|
4
|
+
* This webhook receives payment notifications from payment providers (Stripe, PayPal, etc.).
|
|
5
|
+
* It validates signatures, processes payment events, and updates order status.
|
|
6
|
+
*
|
|
7
|
+
* Common use case: Stripe webhook for payment confirmations
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { LuaWebhook, Orders, Data } from "lua-cli";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
|
|
13
|
+
const paymentWebhook = new LuaWebhook({
|
|
14
|
+
name: "payment-notifications",
|
|
15
|
+
version: "1.0.0",
|
|
16
|
+
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
|
+
// Headers typically include webhook signature for verification
|
|
21
|
+
headerSchema: z.object({
|
|
22
|
+
'stripe-signature': z.string().optional(),
|
|
23
|
+
'content-type': z.string()
|
|
24
|
+
}),
|
|
25
|
+
|
|
26
|
+
// Payment event body
|
|
27
|
+
bodySchema: z.object({
|
|
28
|
+
type: z.string(), // e.g., 'payment_intent.succeeded'
|
|
29
|
+
data: z.object({
|
|
30
|
+
object: z.object({
|
|
31
|
+
id: z.string(),
|
|
32
|
+
amount: z.number(),
|
|
33
|
+
currency: z.string(),
|
|
34
|
+
status: z.string(),
|
|
35
|
+
metadata: z.object({
|
|
36
|
+
orderId: z.string().optional(),
|
|
37
|
+
customerId: z.string().optional()
|
|
38
|
+
}).optional()
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
}),
|
|
42
|
+
|
|
43
|
+
execute: async ({ headers, body }) => {
|
|
44
|
+
console.log(`💳 Payment event received:`, body.type);
|
|
45
|
+
|
|
46
|
+
// In production: Verify Stripe signature
|
|
47
|
+
// const signature = headers['stripe-signature'];
|
|
48
|
+
// const isValid = verifyStripeSignature(body, signature);
|
|
49
|
+
// if (!isValid) throw new Error('Invalid signature');
|
|
50
|
+
|
|
51
|
+
const payment = body.data.object;
|
|
52
|
+
const eventType = body.type;
|
|
53
|
+
|
|
54
|
+
// Handle payment success
|
|
55
|
+
if (eventType === 'payment_intent.succeeded') {
|
|
56
|
+
console.log(`✅ Payment successful: ${payment.amount} ${payment.currency}`);
|
|
57
|
+
|
|
58
|
+
// Update order if we have orderId in metadata
|
|
59
|
+
if (payment.metadata?.orderId) {
|
|
60
|
+
try {
|
|
61
|
+
await Orders.updateStatus('confirmed', payment.metadata.orderId);
|
|
62
|
+
console.log(`📦 Order ${payment.metadata.orderId} marked as confirmed`);
|
|
63
|
+
} catch (error) {
|
|
64
|
+
console.error('Failed to update order:', error);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Log the transaction
|
|
69
|
+
await Data.create('payment-logs', {
|
|
70
|
+
paymentId: payment.id,
|
|
71
|
+
amount: payment.amount,
|
|
72
|
+
currency: payment.currency,
|
|
73
|
+
orderId: payment.metadata?.orderId,
|
|
74
|
+
customerId: payment.metadata?.customerId,
|
|
75
|
+
status: 'succeeded',
|
|
76
|
+
receivedAt: new Date().toISOString()
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
success: true,
|
|
81
|
+
paymentId: payment.id,
|
|
82
|
+
orderId: payment.metadata?.orderId,
|
|
83
|
+
message: 'Payment processed successfully'
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Handle payment failure
|
|
88
|
+
if (eventType === 'payment_intent.payment_failed') {
|
|
89
|
+
console.log(`❌ Payment failed: ${payment.id}`);
|
|
90
|
+
|
|
91
|
+
await Data.create('payment-logs', {
|
|
92
|
+
paymentId: payment.id,
|
|
93
|
+
status: 'failed',
|
|
94
|
+
receivedAt: new Date().toISOString()
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
success: true,
|
|
99
|
+
paymentId: payment.id,
|
|
100
|
+
message: 'Payment failure logged'
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Other event types
|
|
105
|
+
return {
|
|
106
|
+
success: true,
|
|
107
|
+
message: `Event ${eventType} received`
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
export default paymentWebhook;
|
|
113
|
+
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User Event Webhook Example
|
|
3
|
+
*
|
|
4
|
+
* This webhook receives user events from external systems (e.g., CRM, marketing tools).
|
|
5
|
+
* It validates incoming data and stores events for processing.
|
|
6
|
+
*
|
|
7
|
+
* Webhook URL: {API_URL}/webhooks/{agentId}/{webhookId}
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { LuaWebhook, Data } from "lua-cli";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
|
|
13
|
+
const userEventWebhook = new LuaWebhook({
|
|
14
|
+
name: "user-events",
|
|
15
|
+
version: "1.0.0",
|
|
16
|
+
description: "Receives user events from external systems",
|
|
17
|
+
context: "This webhook handles user registration, profile updates, and deletion events. " +
|
|
18
|
+
"It validates the incoming data, stores events in the database, and can trigger follow-up actions.",
|
|
19
|
+
|
|
20
|
+
// Validate query parameters (optional source tracking)
|
|
21
|
+
querySchema: z.object({
|
|
22
|
+
source: z.string().optional(),
|
|
23
|
+
version: z.string().optional()
|
|
24
|
+
}),
|
|
25
|
+
|
|
26
|
+
// Validate headers (require API key for security)
|
|
27
|
+
headerSchema: z.object({
|
|
28
|
+
'x-api-key': z.string(),
|
|
29
|
+
'content-type': z.string().optional()
|
|
30
|
+
}),
|
|
31
|
+
|
|
32
|
+
// Validate request body
|
|
33
|
+
bodySchema: z.object({
|
|
34
|
+
eventType: z.enum(['signup', 'update', 'delete']),
|
|
35
|
+
userId: z.string(),
|
|
36
|
+
email: z.string().email(),
|
|
37
|
+
name: z.string().optional(),
|
|
38
|
+
metadata: z.record(z.any()).optional(),
|
|
39
|
+
timestamp: z.string()
|
|
40
|
+
}),
|
|
41
|
+
|
|
42
|
+
execute: async ({ query, headers, body }) => {
|
|
43
|
+
console.log(`📥 Received ${body.eventType} event for user:`, body.email);
|
|
44
|
+
console.log(`📍 Source:`, query?.source || 'unknown');
|
|
45
|
+
|
|
46
|
+
// Security: Validate API key (in production, use env variable)
|
|
47
|
+
const expectedKey = process.env.WEBHOOK_API_KEY || 'your-secret-key';
|
|
48
|
+
if (headers['x-api-key'] !== expectedKey) {
|
|
49
|
+
throw new Error('Invalid API key');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Store the event in custom data collection
|
|
53
|
+
const eventData = {
|
|
54
|
+
...body,
|
|
55
|
+
source: query?.source,
|
|
56
|
+
receivedAt: new Date().toISOString(),
|
|
57
|
+
processed: false
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const result = await Data.create('user-events', eventData,
|
|
61
|
+
`${body.eventType} ${body.email} ${body.name || ''}`
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
console.log('✅ Event stored successfully:', result.id);
|
|
65
|
+
|
|
66
|
+
// Return success response
|
|
67
|
+
return {
|
|
68
|
+
success: true,
|
|
69
|
+
eventId: result.id,
|
|
70
|
+
userId: body.userId,
|
|
71
|
+
timestamp: new Date().toISOString()
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
export default userEventWebhook;
|
|
77
|
+
|