lua-cli 3.0.0-alpha.9 → 3.0.0

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 (40) hide show
  1. package/README.md +850 -0
  2. package/dist/api/chat.api.service.d.ts +8 -0
  3. package/dist/api/chat.api.service.js +55 -0
  4. package/dist/api/products.api.service.d.ts +2 -1
  5. package/dist/api/products.api.service.js +11 -10
  6. package/dist/api-exports.d.ts +1 -1
  7. package/dist/api-exports.js +6 -1
  8. package/dist/commands/chat.js +35 -32
  9. package/dist/commands/init.js +10 -2
  10. package/dist/index.js +2 -2
  11. package/dist/interfaces/message.d.ts +2 -2
  12. package/dist/utils/agent-management.d.ts +1 -1
  13. package/dist/utils/agent-management.js +5 -3
  14. package/dist/utils/init-helpers.d.ts +10 -1
  15. package/dist/utils/init-helpers.js +44 -1
  16. package/dist/utils/pre-bundle-jobs.js +9 -9
  17. package/dist/utils/sandbox.js +1 -2
  18. package/package.json +3 -3
  19. package/template/QUICKSTART.md +693 -191
  20. package/template/README.md +673 -802
  21. package/template/package.json +1 -1
  22. package/template/src/index.ts +18 -252
  23. package/template/src/postprocessors/modifyResponse.ts +21 -0
  24. package/template/src/preprocessors/messageMatching.ts +22 -0
  25. package/template/src/skills/basket.skill.ts +12 -0
  26. package/template/src/skills/product.skill.ts +13 -0
  27. package/template/src/{tools → skills/tools}/ProductsTool.ts +2 -1
  28. package/template/src/skills/tools/UserDataTool.ts +75 -0
  29. package/template/src/skills/user.skill.ts +13 -0
  30. package/template/src/seed.ts +0 -46
  31. package/template/src/tools/UserDataTool.ts +0 -33
  32. /package/template/src/{tools → skills/tools}/BasketTool.ts +0 -0
  33. /package/template/src/{tools → skills/tools}/CreateInlineJob.ts +0 -0
  34. /package/template/src/{tools → skills/tools}/CreatePostTool.ts +0 -0
  35. /package/template/src/{tools → skills/tools}/CustomDataTool.ts +0 -0
  36. /package/template/src/{tools → skills/tools}/GameScoreTrackerTool.ts +0 -0
  37. /package/template/src/{tools → skills/tools}/GetWeatherTool.ts +0 -0
  38. /package/template/src/{tools → skills/tools}/OrderTool.ts +0 -0
  39. /package/template/src/{tools → skills/tools}/PaymentTool.ts +0 -0
  40. /package/template/src/{tools → skills/tools}/SmartBasketTool.ts +0 -0
@@ -20,7 +20,7 @@
20
20
  "inquirer": "^12.9.6",
21
21
  "stripe": "^17.5.0",
22
22
  "js-yaml": "^4.1.0",
23
- "lua-cli": "file:..",
23
+ "lua-cli": "^3.0.0",
24
24
  "openai": "^5.23.0",
25
25
  "uuid": "^13.0.0",
26
26
  "zod": "^3.24.1"
@@ -1,260 +1,26 @@
1
- import { LuaSkill, User, Products, Orders, Data, Baskets, LuaJob, JobInstance, LuaWebhook, Jobs } from "lua-cli";
2
- import GetWeatherTool from "./tools/GetWeatherTool";
3
- import { GetUserDataTool, UpdateUserDataTool } from "./tools/UserDataTool";
4
- import CreatePostTool from "./tools/CreatePostTool";
5
- import { SearchProductsTool, CreateProductTool, UpdateProductTool, GetAllProductsTool, GetProductByIdTool, DeleteProductTool } from "./tools/ProductsTool";
6
- import CreatePaymentLinkTool from "./tools/PaymentTool";
7
- import { CreateBasketTool, GetBasketsTool, AddItemToBasketTool, RemoveItemFromBasketTool, ClearBasketTool, UpdateBasketStatusTool, UpdateBasketMetadataTool, CheckoutBasketTool, GetBasketByIdTool } from "./tools/BasketTool";
8
- import { CreateOrderTool, UpdateOrderStatusTool, GetOrderByIdTool, GetUserOrdersTool } from "./tools/OrderTool";
9
- import { CreateMovieTool, GetMoviesTool, GetMovieByIdTool, UpdateMovieTool, SearchMoviesTool, DeleteMovieTool } from "./tools/CustomDataTool";
10
- import CreateInlineJobTool from "./tools/CreateInlineJob";
11
- import { v4 } from 'uuid';
12
-
13
- // ============================================================================
14
- // WEBHOOK EXAMPLES (Uncomment to enable)
15
- // ============================================================================
16
- // Webhooks receive HTTP requests from external systems
17
- // See: WEBHOOK_JOB_EXAMPLES.md for detailed explanations
18
-
19
- // import userEventWebhook from "./webhooks/UserEventWebhook";
20
- // import paymentWebhook from "./webhooks/PaymentWebhook";
21
-
22
- // ============================================================================
23
- // JOB EXAMPLES (Uncomment to enable)
24
- // ============================================================================
25
- // Jobs are scheduled tasks that run at specific times or intervals
26
- // See: WEBHOOK_JOB_EXAMPLES.md for detailed explanations
27
-
28
- import dailyCleanupJob from "./jobs/DailyCleanupJob";
29
- // import healthCheckJob from "./jobs/HealthCheckJob";
30
- // import dataMigrationJob from "./jobs/DataMigrationJob";
31
- // import abandonedBasketProcessorJob from "./jobs/AbandonedBasketProcessorJob";
32
-
33
- // ============================================================================
34
- // SMART BASKET TOOL (Uncomment to enable)
35
- // ============================================================================
36
- // This tool creates baskets with automatic abandoned cart reminders
37
- // Uses Jobs.create() to schedule one-time check 3 hours after creation
38
-
39
- // import { CreateSmartBasketTool, CheckAbandonedBasketsTool } from "./tools/SmartBasketTool";
40
-
41
- // ============================================================================
42
- // GAME SCORE TRACKER (Uncomment to enable) - ADVANCED EXAMPLE
43
- // ============================================================================
44
- // Complex example showing:
45
- // - Interval jobs that start at specific time
46
- // - Jobs that stop themselves when condition is met
47
- // - Real-time monitoring with external API integration
48
- // See: COMPLEX_JOB_EXAMPLES.md for detailed explanation
49
-
50
- // import { TrackGameScoresTool, GetGameScoresTool, StopGameTrackingTool } from "./tools/GameScoreTrackerTool";
51
-
52
-
53
- // Initialize skill with tools
54
- const generalSkill = new LuaSkill({
55
- name: "general-skill",
56
- version: "0.0.2",
57
- description: "A comprehensive Lua skill with weather, user data, post creation, and mathematical tools",
58
- context: "This skill provides various utilities including weather information, user data retrieval, post creation, basic calculator operations, and advanced mathematical functions. Use get_weather to fetch current weather conditions for any city, get_user_data to retrieve user information, create_post to publish new posts, calculator for basic arithmetic operations, and advanced_math for complex mathematical computations like factorials, prime checking, fibonacci sequences, and greatest common divisor calculations.",
59
- tools: [
60
- new GetWeatherTool(),
61
- new CreatePostTool(),
62
- new CreateInlineJobTool()
63
- ]
64
- });
65
-
66
- const userDataSkill = new LuaSkill({
67
- name: "user-data-skill",
68
- version: "0.0.1",
69
- description: "A specific Lua skill with user data",
70
- context: "This skill provides various utilities including user data retrieval, creation, and updating.",
71
- tools: [
72
- new GetUserDataTool(),
73
- new UpdateUserDataTool()
74
- ]
75
- });
76
-
77
-
78
- const productSkill = new LuaSkill({
79
- name: "product-skill",
80
- version: "0.0.1",
81
- description: "A specific Lua skill with products",
82
- context: "This skill provides various utilities including products.",
83
- tools: [
84
- new SearchProductsTool(),
85
- new GetAllProductsTool(),
86
- new CreateProductTool(),
87
- new UpdateProductTool(),
88
- new GetProductByIdTool(),
89
- new DeleteProductTool()
90
- ]
91
- });
92
-
93
-
94
- const basketSkill = new LuaSkill({
95
- name: "basket-skill",
96
- version: "0.0.1",
97
- description: "A specific Lua skill with baskets",
98
- context: "This skill provides various utilities including baskets.",
99
- tools: [
100
- new CreateBasketTool(),
101
- new GetBasketsTool(),
102
- new AddItemToBasketTool(),
103
- new RemoveItemFromBasketTool(),
104
- new ClearBasketTool(),
105
- new UpdateBasketStatusTool(),
106
- new UpdateBasketMetadataTool(),
107
- new CheckoutBasketTool(),
108
- new GetBasketByIdTool()
109
- ]
110
- });
111
-
112
-
113
- const orderSkill = new LuaSkill({
114
- name: "order-skill",
115
- version: "0.0.1",
116
- description: "A specific Lua skill with orders",
117
- context: "This skill provides various utilities including orders.",
118
- tools: [
119
- new CreateOrderTool(),
120
- new UpdateOrderStatusTool(),
121
- new GetOrderByIdTool(),
122
- new GetUserOrdersTool()
123
- ]
1
+ import { LuaAgent } from "lua-cli";
2
+ import userSkill from "./skills/user.skill";
3
+ import productSkill from "./skills/product.skill";
4
+ import basketSkill from "./skills/basket.skill";
5
+ import userEventWebhook from "./webhooks/UserEventWebhook";
6
+ import healthCheckJob from "./jobs/HealthCheckJob";
7
+ import messageMatchingPreProcessor from "./preprocessors/messageMatching";
8
+ import modifyResponsePostProcessor from "./postprocessors/modifyResponse";
9
+
10
+ const agent = new LuaAgent({
11
+ name: ``,
12
+ persona: ``,
13
+ skills: [ userSkill, productSkill, basketSkill ],
14
+ webhooks: [ userEventWebhook ],
15
+ jobs: [ healthCheckJob ],
16
+ preProcessors: [ messageMatchingPreProcessor ],
17
+ postProcessors: [ modifyResponsePostProcessor ]
124
18
  });
125
19
 
126
- const customDataSkill = new LuaSkill({
127
- name: "custom-data-skill",
128
- version: "0.0.1",
129
- description: "A specific Lua skill with custom data",
130
- context: "This skill provides various utilities including custom data.",
131
- tools: [
132
- new CreateMovieTool(),
133
- new GetMoviesTool(),
134
- new GetMovieByIdTool(),
135
- new UpdateMovieTool(),
136
- new SearchMoviesTool(),
137
- new DeleteMovieTool()
138
- ]
139
- });
140
-
141
- const paymentSkill = new LuaSkill({
142
- name: "payment-skill",
143
- version: "0.0.1",
144
- description: "A specific Lua skill with payments",
145
- context: "This skill provides various utilities including payments.",
146
- tools: [
147
- new CreatePaymentLinkTool()
148
- ]
149
- });
150
-
151
- // Test cases
152
- const testCases = [
153
- { tool: "get_weather", city: "London" },
154
- { tool: "get_user_data", userId: "user123" },
155
- { tool: "create_post", title: "Test Post", content: "This is a test post content" },
156
- { tool: "calculator", operation: "add", a: 5, b: 3 },
157
- { tool: "advanced_math", operation: "factorial", numbers: [5] },
158
- { tool: "advanced_math", operation: "is_prime", numbers: [17] },
159
- { tool: "advanced_math", operation: "fibonacci", numbers: [10] },
160
- { tool: "advanced_math", operation: "gcd", numbers: [48, 18] },
161
- // This should fail - wrong property name
162
- { tool: "get_weather", cityLong: "London", apiKey: "123" }
163
- ];
164
-
165
- const job = new LuaJob({
166
- description: "Test job",
167
- context: "Test job context",
168
- name: "test-job",
169
- schedule: {
170
- type: "once",
171
- executeAt: new Date(Date.now() + 1000).toISOString()
172
- },
173
- metadata: {
174
- test: "test"
175
- },
176
- execute: async (job: JobInstance) => {
177
- console.log("Job executed");
178
- return { success: true, message: "Job executed successfully" };
179
- }
180
- });
181
-
182
- //create webhook
183
- const webhook = new LuaWebhook({
184
- description: "Test webhook",
185
- context: "Test webhook context",
186
- name: "test-webhook",
187
- execute: async (query: any, headers: any, body: any) => {
188
- console.log("Webhook executed");
189
- return { success: true, message: "Webhook executed successfully" };
190
- }
191
- });
192
-
193
- const newJob = new LuaJob({
194
- description: "Test job",
195
- context: "Test job context",
196
- name: "test-job",
197
- schedule: {
198
- type: "once",
199
- executeAt: new Date(Date.now() + 1000).toISOString()
200
- },
201
- execute: async (job: JobInstance) => {
202
- console.log("Job executed", job);
203
- const realtimeJob = await Jobs.create({
204
- name: `realtime-job-new-this-again`,
205
- description: "Realtime job",
206
- schedule: {
207
- type: "once",
208
- executeAt: new Date(Date.now() + 1000).toISOString()
209
- },
210
- execute: async (job: JobInstance) => {
211
- // console.log("Executing realtime job", job.data);
212
- console.log("Realtime job metadata", job.metadata);
213
- console.log("Realtime job user", job.user);
214
- return { success: true, message: "Realtime job executed successfully" };
215
- }
216
- });
217
- return { success: true, message: "Job executed successfully" };
218
- }
219
- });
220
-
221
-
222
- console.log("Job created:", job);
223
-
224
- async function runTests() {
225
- // await seedProducts();
226
- console.log("🧪 Running tool tests...\n");
227
-
228
- const user = await User.get();
229
- console.log("✅ Success:", user);
230
- const products = await Products.get();
231
- console.log("✅ Success:", products);
232
- const orders = await Orders.get();
233
- console.log("✅ Success:", orders);
234
- const data = await Data.get("movies");
235
- console.log("✅ Success:", data);
236
- const baskets = await Baskets.get();
237
- console.log("✅ Success:", baskets);
238
-
239
- for (const [index, testCase] of testCases.entries()) {
240
- try {
241
- // console.log(`Test ${index + 1}: ${testCase.tool}`);
242
- // const resultGeneral = await generalSkill.run(testCase);
243
- // console.log("✅ Success:", resultGeneral);
244
- // const resultUserData = await userDataSkill.run(testCase);
245
- // console.log("✅ Success:", resultUserData);
246
- // const resultEccomerce = await eccomerceSkill.run(testCase);
247
- // console.log("✅ Success:", resultEccomerce);
248
- } catch (error: any) {
249
- console.log("❌ Error:", error.message);
250
- }
251
- console.log(""); // Empty line for readability
252
- }
253
- }
254
20
 
255
21
  async function main() {
256
22
  try {
257
- await runTests();
23
+
258
24
  } catch (error) {
259
25
  console.error("💥 Unexpected error:", error);
260
26
  process.exit(1);
@@ -0,0 +1,21 @@
1
+ import { ChatMessage, PostProcessor, UserDataInstance } from "lua-cli";
2
+
3
+
4
+ const modifyResponsePostProcessor = new PostProcessor({
5
+ name: "modify-response",
6
+ description: "Modifies the response to the user",
7
+ context: "Modifies the response to the user",
8
+ execute: async (user: UserDataInstance, message: string, response: string, channel: string) => {
9
+ console.log("Modify response post processor", user, message, response, channel);
10
+ console.log("User data", await user.data);
11
+ console.log("Message", message);
12
+ console.log("Response", response);
13
+ console.log("Channel", channel);
14
+ if (response.includes("test")) {
15
+ return message.toUpperCase();
16
+ }
17
+ return response;
18
+ }
19
+ });
20
+
21
+ export default modifyResponsePostProcessor;
@@ -0,0 +1,22 @@
1
+ import { ChatMessage, PreProcessor, UserDataInstance } from "lua-cli";
2
+
3
+
4
+ const messageMatchingPreProcessor = new PreProcessor({
5
+ name: "message-matching",
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) => {
9
+ console.log("Message matching pre processor", user, messages, channel);
10
+ console.log("User data", await user.data);
11
+ console.log("Messages", messages);
12
+ console.log("Channel", channel);
13
+ //check if message type text contains test and return the message
14
+ const testMessage = messages.find((message) => message.type === "text" && message.text.includes("test"));
15
+ if (testMessage) {
16
+ return [{ type: "text", text: "Tell the user that you got their test message and nothing else" }];
17
+ }
18
+ return messages;
19
+ }
20
+ });
21
+
22
+ export default messageMatchingPreProcessor;
@@ -0,0 +1,12 @@
1
+ import { LuaSkill } from "lua-cli";
2
+ import { CreateBasketTool, GetBasketByIdTool, UpdateBasketStatusTool, UpdateBasketMetadataTool, CheckoutBasketTool, GetBasketsTool, ClearBasketTool, RemoveItemFromBasketTool, AddItemToBasketTool } from "./tools/BasketTool";
3
+
4
+ const basketSkill = new LuaSkill({
5
+ name: "basket-skill",
6
+ version: "1.0.0",
7
+ description: "Basket management skill",
8
+ context: "Basket management skill",
9
+ tools: [new CreateBasketTool(), new GetBasketByIdTool(), new UpdateBasketStatusTool(), new UpdateBasketMetadataTool(), new CheckoutBasketTool(), new GetBasketsTool(), new AddItemToBasketTool(), new RemoveItemFromBasketTool(), new ClearBasketTool()],
10
+ });
11
+
12
+ export default basketSkill;
@@ -0,0 +1,13 @@
1
+ import { LuaSkill } from "lua-cli";
2
+ import { SearchProductsTool, CreateProductTool, UpdateProductTool, GetAllProductsTool, GetProductByIdTool, DeleteProductTool } from "./tools/ProductsTool";
3
+
4
+
5
+ const productSkill = new LuaSkill({
6
+ name: "product-skill",
7
+ version: "1.0.0",
8
+ description: "Product management skill",
9
+ context: "Product management skill",
10
+ tools: [new SearchProductsTool(), new CreateProductTool(), new UpdateProductTool(), new GetAllProductsTool(), new GetProductByIdTool(), new DeleteProductTool()],
11
+ });
12
+
13
+ export default productSkill;
@@ -58,7 +58,8 @@ export class UpdateProductTool implements LuaTool {
58
58
  });
59
59
 
60
60
  async execute(input: z.infer<typeof this.inputSchema>) {
61
- return Products.update({ ...input.product }, input.product.id);
61
+ const product = await Products.getById(input.product.id);
62
+ return product.update({ ...input.product });
62
63
  }
63
64
  }
64
65
 
@@ -0,0 +1,75 @@
1
+ import { AI, LuaTool, User, Jobs, JobInstance } from "lua-cli";
2
+ import { z } from "zod";
3
+
4
+
5
+ export class GetUserDataTool implements LuaTool {
6
+ name = "get_user_data";
7
+ description = "Get the user data for a given user id";
8
+ inputSchema = z.object({ });
9
+
10
+ constructor() {}
11
+
12
+ async execute(input: z.infer<typeof this.inputSchema>) {
13
+ return User.get();
14
+ }
15
+ }
16
+
17
+ export class UpdateUserDataTool implements LuaTool {
18
+ name = "update_user_data";
19
+ description = "Update the user data for a given user id";
20
+ inputSchema = z.object({
21
+ data: z.object({
22
+ name: z.string().optional(),
23
+ age: z.number().optional()
24
+ })
25
+ });
26
+
27
+ constructor() {}
28
+
29
+ async execute(input: z.infer<typeof this.inputSchema>) {
30
+ const user = await User.get(); //get instance of user
31
+ await user.send([{ type: "text", text: "Hello, how are you?" }]);
32
+ return await user.update(input.data);
33
+ }
34
+ }
35
+
36
+ export class WritePoemTool implements LuaTool {
37
+ name = "write_poem";
38
+ description = "Write a poem about a given topic";
39
+ inputSchema = z.object({
40
+ topic: z.string()
41
+ });
42
+ async execute(input: z.infer<typeof this.inputSchema>) {
43
+ return await AI.generate("Write a poem about the following topic:", [{ type: "text", text: input.topic }]);
44
+ }
45
+ }
46
+
47
+ export class CreateInlineJobTool implements LuaTool {
48
+ name = "create-job-to-notify-user";
49
+ description = "Create a new job to notify the user";
50
+ inputSchema = z.object({
51
+ message: z.string()
52
+ });
53
+ async execute(input: z.infer<typeof this.inputSchema>) {
54
+ //create a job to notify the user in exactly 20 seconds
55
+ const job = await Jobs.create({
56
+ name: "notify-user-new",
57
+ description: "Notify the user",
58
+ schedule: {
59
+ type: "once",
60
+ executeAt: new Date(Date.now() + 0)
61
+ },
62
+ metadata: {
63
+ message: input.message
64
+ },
65
+ execute: async (jobInstance: JobInstance) => {
66
+ const user = await jobInstance.user();
67
+ const metadata = jobInstance.metadata; //we do this to access runtime variables in the job when the job is executed
68
+ console.log("Metadata", metadata);
69
+ await user.send([{ type: "text", text: metadata.message }]);
70
+ return { success: true, message: "User notified" };
71
+ }
72
+ });
73
+ return { success: true, job: job };
74
+ }
75
+ }
@@ -0,0 +1,13 @@
1
+ import { LuaSkill } from "lua-cli";
2
+ import { CreateInlineJobTool, GetUserDataTool, UpdateUserDataTool, WritePoemTool } from "./tools/UserDataTool";
3
+
4
+
5
+ const userSkill = new LuaSkill({
6
+ name: "user-skill",
7
+ version: "1.0.0",
8
+ description: "User management skill",
9
+ context: "User management skill",
10
+ tools: [new GetUserDataTool(), new UpdateUserDataTool(), new WritePoemTool(), new CreateInlineJobTool()],
11
+ });
12
+
13
+ export default userSkill;
@@ -1,46 +0,0 @@
1
- import fetch from "node-fetch";
2
- import OpenAI from "openai";
3
- import { Pinecone } from "@pinecone-database/pinecone";
4
- import { env } from "lua-cli/skill";
5
-
6
- const openai = new OpenAI({ apiKey: env("OPENAI_API_KEY") || "" });
7
- const pinecone = new Pinecone({ apiKey: env("PINECONE_API_KEY") || "" });
8
- const indexName = "products-demo";
9
-
10
- async function embed(text: string) {
11
- const res = await openai.embeddings.create({
12
- model: "text-embedding-3-small",
13
- input: text,
14
- });
15
- return res.data[0].embedding;
16
- }
17
-
18
- export default async function seedProducts() {
19
- const index = pinecone.Index(indexName);
20
-
21
- // Example: Fake Store API
22
- const response = await fetch("https://fakestoreapi.com/products");
23
- const products = await response.json() as any[];
24
-
25
- const vectors = await Promise.all(
26
- products.map(async (product) => {
27
- const embedding = await embed(`${product.title}. ${product.description}`);
28
- return {
29
- id: product.id.toString(),
30
- values: embedding,
31
- metadata: {
32
- title: product.title,
33
- description: product.description,
34
- category: product.category,
35
- price: product.price,
36
- image: product.image,
37
- },
38
- };
39
- })
40
- );
41
-
42
- await index.upsert(vectors);
43
- console.log("Dummy products inserted!");
44
- }
45
-
46
- seedProducts().catch(console.error);
@@ -1,33 +0,0 @@
1
- import { LuaTool, User } from "lua-cli";
2
- import { z } from "zod";
3
-
4
-
5
- export class GetUserDataTool implements LuaTool {
6
- name = "get_user_data";
7
- description = "Get the user data for a given user id";
8
- inputSchema = z.object({ });
9
-
10
- constructor() {}
11
-
12
- async execute(input: z.infer<typeof this.inputSchema>) {
13
- return User.get();
14
- }
15
- }
16
-
17
- export class UpdateUserDataTool implements LuaTool {
18
- name = "update_user_data";
19
- description = "Update the user data for a given user id";
20
- inputSchema = z.object({
21
- data: z.object({
22
- name: z.string().optional(),
23
- age: z.number().optional()
24
- })
25
- });
26
-
27
- constructor() {}
28
-
29
- async execute(input: z.infer<typeof this.inputSchema>) {
30
- const user = await User.get(); //get instance of user
31
- return await user.update(input.data);
32
- }
33
- }