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.
- package/dist/api/job.api.service.d.ts +16 -7
- package/dist/api/job.api.service.js +21 -5
- package/dist/api/postprocessor.api.service.d.ts +61 -1
- package/dist/api/postprocessor.api.service.js +35 -0
- package/dist/api/preprocessor.api.service.d.ts +61 -1
- package/dist/api/preprocessor.api.service.js +35 -0
- package/dist/api-exports.d.ts +26 -6
- package/dist/api-exports.js +42 -29
- package/dist/cli/command-definitions.js +13 -6
- package/dist/commands/chat.js +32 -5
- package/dist/commands/compile.js +16 -2
- package/dist/commands/dev.js +23 -2
- package/dist/commands/push.d.ts +6 -2
- package/dist/commands/push.js +412 -6
- package/dist/commands/test.js +18 -2
- package/dist/common/job.instance.d.ts +3 -0
- package/dist/common/job.instance.js +8 -0
- package/dist/config/constants.d.ts +6 -5
- package/dist/config/constants.js +12 -10
- package/dist/interfaces/chat.d.ts +30 -1
- package/dist/interfaces/jobs.d.ts +21 -0
- package/dist/types/skill.d.ts +75 -56
- package/dist/types/skill.js +53 -59
- package/dist/utils/bundling.d.ts +13 -4
- package/dist/utils/bundling.js +83 -26
- package/dist/utils/compile.js +27 -6
- package/dist/utils/dev-api.d.ts +42 -2
- package/dist/utils/dev-api.js +177 -4
- package/dist/utils/dev-server.d.ts +1 -1
- package/dist/utils/dev-server.js +4 -4
- package/dist/utils/dynamic-job-bundler.d.ts +17 -0
- package/dist/utils/dynamic-job-bundler.js +143 -0
- package/dist/utils/pre-bundle-jobs.d.ts +26 -0
- package/dist/utils/pre-bundle-jobs.js +176 -0
- package/dist/utils/sandbox-storage.d.ts +48 -0
- package/dist/utils/sandbox-storage.js +114 -0
- package/dist/utils/sandbox.d.ts +2 -2
- package/dist/utils/sandbox.js +23 -7
- package/package.json +1 -1
- package/template/lua.skill.yaml +47 -0
- package/template/package-lock.json +10505 -0
- package/template/package.json +2 -1
- package/template/src/index.ts +65 -3
- package/template/src/tools/CreateInlineJob.ts +42 -0
- package/API_REFERENCE.md +0 -1408
- package/CHANGELOG.md +0 -236
- package/CLI_REFERENCE.md +0 -908
- package/GETTING_STARTED.md +0 -1040
- package/INSTANCE_TYPES.md +0 -1158
- package/README.md +0 -865
- package/TEMPLATE_GUIDE.md +0 -1398
- package/USER_DATA_INSTANCE.md +0 -621
- package/template/AGENT_CONFIGURATION.md +0 -251
- package/template/COMPLEX_JOB_EXAMPLES.md +0 -795
- package/template/DYNAMIC_JOB_CREATION.md +0 -371
- package/template/TOOL_EXAMPLES.md +0 -655
- package/template/WEBHOOKS_JOBS_QUICKSTART.md +0 -318
- package/template/WEBHOOK_JOB_EXAMPLES.md +0 -817
- package/template/src/index-agent-example.ts +0 -201
- package/template/src/postprocessors/ResponseFormatter.ts +0 -151
- package/template/src/preprocessors/MessageFilter.ts +0 -91
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
// /**
|
|
2
|
-
// * LuaAgent Example - Simplified Agent Configuration
|
|
3
|
-
// *
|
|
4
|
-
// * This example shows the NEW, RECOMMENDED way to define your agent using LuaAgent.
|
|
5
|
-
// * Instead of exporting individual skills, webhooks, jobs, and processors,
|
|
6
|
-
// * you create one unified LuaAgent object that contains everything.
|
|
7
|
-
// *
|
|
8
|
-
// * Benefits:
|
|
9
|
-
// * - Simpler, cleaner code
|
|
10
|
-
// * - All configuration in one place
|
|
11
|
-
// * - Easier to understand and maintain
|
|
12
|
-
// * - Agent persona is synced with lua.skill.yaml automatically
|
|
13
|
-
// */
|
|
14
|
-
|
|
15
|
-
// import { LuaAgent, LuaSkill } from "lua-cli";
|
|
16
|
-
// import GetWeatherTool from "./tools/GetWeatherTool";
|
|
17
|
-
// import { GetUserDataTool, UpdateUserDataTool } from "./tools/UserDataTool";
|
|
18
|
-
// import CreatePostTool from "./tools/CreatePostTool";
|
|
19
|
-
// import { SearchProductsTool, CreateProductTool, UpdateProductTool, GetAllProductsTool, GetProductByIdTool, DeleteProductTool } from "./tools/ProductsTool";
|
|
20
|
-
// import { CreateBasketTool, GetBasketsTool, AddItemToBasketTool, RemoveItemFromBasketTool, ClearBasketTool, UpdateBasketStatusTool, UpdateBasketMetadataTool, CheckoutBasketTool, GetBasketByIdTool } from "./tools/BasketTool";
|
|
21
|
-
// import { CreateOrderTool, UpdateOrderStatusTool, GetOrderByIdTool, GetUserOrdersTool } from "./tools/OrderTool";
|
|
22
|
-
// import { CreateMovieTool, GetMoviesTool, GetMovieByIdTool, UpdateMovieTool, SearchMoviesTool, DeleteMovieTool } from "./tools/CustomDataTool";
|
|
23
|
-
|
|
24
|
-
// // ============================================================================
|
|
25
|
-
// // WEBHOOK EXAMPLES (Uncomment to enable)
|
|
26
|
-
// // ============================================================================
|
|
27
|
-
// // import userEventWebhook from "./webhooks/UserEventWebhook";
|
|
28
|
-
// // import paymentWebhook from "./webhooks/PaymentWebhook";
|
|
29
|
-
|
|
30
|
-
// // ============================================================================
|
|
31
|
-
// // JOB EXAMPLES (Uncomment to enable)
|
|
32
|
-
// // ============================================================================
|
|
33
|
-
// // import dailyCleanupJob from "./jobs/DailyCleanupJob";
|
|
34
|
-
// // import healthCheckJob from "./jobs/HealthCheckJob";
|
|
35
|
-
|
|
36
|
-
// // ============================================================================
|
|
37
|
-
// // PREPROCESSOR/POSTPROCESSOR EXAMPLES
|
|
38
|
-
// // ============================================================================
|
|
39
|
-
// import messageFilter from "./preprocessors/MessageFilter";
|
|
40
|
-
// import responseFormatter from "./postprocessors/ResponseFormatter";
|
|
41
|
-
|
|
42
|
-
// // ============================================================================
|
|
43
|
-
// // SKILLS
|
|
44
|
-
// // ============================================================================
|
|
45
|
-
|
|
46
|
-
// // Skills can be defined separately for better organization
|
|
47
|
-
// const generalSkill = new LuaSkill({
|
|
48
|
-
// name: "general-skill",
|
|
49
|
-
// version: "1.0.0",
|
|
50
|
-
// description: "General utilities including weather and post creation",
|
|
51
|
-
// context: "This skill provides weather information and post creation capabilities.",
|
|
52
|
-
// tools: [
|
|
53
|
-
// new GetWeatherTool(),
|
|
54
|
-
// new CreatePostTool()
|
|
55
|
-
// ]
|
|
56
|
-
// });
|
|
57
|
-
|
|
58
|
-
// const userDataSkill = new LuaSkill({
|
|
59
|
-
// name: "user-data-skill",
|
|
60
|
-
// version: "1.0.0",
|
|
61
|
-
// description: "User data management",
|
|
62
|
-
// context: "This skill provides user data retrieval and update capabilities.",
|
|
63
|
-
// tools: [
|
|
64
|
-
// new GetUserDataTool(),
|
|
65
|
-
// new UpdateUserDataTool()
|
|
66
|
-
// ]
|
|
67
|
-
// });
|
|
68
|
-
|
|
69
|
-
// const productSkill = new LuaSkill({
|
|
70
|
-
// name: "product-skill",
|
|
71
|
-
// version: "1.0.0",
|
|
72
|
-
// description: "Product catalog management",
|
|
73
|
-
// context: "This skill provides comprehensive product management capabilities.",
|
|
74
|
-
// tools: [
|
|
75
|
-
// new SearchProductsTool(),
|
|
76
|
-
// new GetAllProductsTool(),
|
|
77
|
-
// new CreateProductTool(),
|
|
78
|
-
// new UpdateProductTool(),
|
|
79
|
-
// new GetProductByIdTool(),
|
|
80
|
-
// new DeleteProductTool()
|
|
81
|
-
// ]
|
|
82
|
-
// });
|
|
83
|
-
|
|
84
|
-
// const basketSkill = new LuaSkill({
|
|
85
|
-
// name: "basket-skill",
|
|
86
|
-
// version: "1.0.0",
|
|
87
|
-
// description: "Shopping basket management",
|
|
88
|
-
// context: "This skill provides shopping basket operations.",
|
|
89
|
-
// tools: [
|
|
90
|
-
// new CreateBasketTool(),
|
|
91
|
-
// new GetBasketsTool(),
|
|
92
|
-
// new AddItemToBasketTool(),
|
|
93
|
-
// new RemoveItemFromBasketTool(),
|
|
94
|
-
// new ClearBasketTool(),
|
|
95
|
-
// new UpdateBasketStatusTool(),
|
|
96
|
-
// new UpdateBasketMetadataTool(),
|
|
97
|
-
// new CheckoutBasketTool(),
|
|
98
|
-
// new GetBasketByIdTool()
|
|
99
|
-
// ]
|
|
100
|
-
// });
|
|
101
|
-
|
|
102
|
-
// const orderSkill = new LuaSkill({
|
|
103
|
-
// name: "order-skill",
|
|
104
|
-
// version: "1.0.0",
|
|
105
|
-
// description: "Order management",
|
|
106
|
-
// context: "This skill provides order management capabilities.",
|
|
107
|
-
// tools: [
|
|
108
|
-
// new CreateOrderTool(),
|
|
109
|
-
// new UpdateOrderStatusTool(),
|
|
110
|
-
// new GetOrderByIdTool(),
|
|
111
|
-
// new GetUserOrdersTool()
|
|
112
|
-
// ]
|
|
113
|
-
// });
|
|
114
|
-
|
|
115
|
-
// const customDataSkill = new LuaSkill({
|
|
116
|
-
// name: "custom-data-skill",
|
|
117
|
-
// version: "1.0.0",
|
|
118
|
-
// description: "Custom data management for movies",
|
|
119
|
-
// context: "This skill provides custom data storage and retrieval for movies.",
|
|
120
|
-
// tools: [
|
|
121
|
-
// new CreateMovieTool(),
|
|
122
|
-
// new GetMoviesTool(),
|
|
123
|
-
// new GetMovieByIdTool(),
|
|
124
|
-
// new UpdateMovieTool(),
|
|
125
|
-
// new SearchMoviesTool(),
|
|
126
|
-
// new DeleteMovieTool()
|
|
127
|
-
// ]
|
|
128
|
-
// });
|
|
129
|
-
|
|
130
|
-
// // ============================================================================
|
|
131
|
-
// // AGENT CONFIGURATION (NEW APPROACH)
|
|
132
|
-
// // ============================================================================
|
|
133
|
-
|
|
134
|
-
// /**
|
|
135
|
-
// * This is the main agent configuration.
|
|
136
|
-
// * The LuaAgent consolidates everything in one place:
|
|
137
|
-
// * - Agent persona (behavior and personality)
|
|
138
|
-
// * - Skills (collections of tools)
|
|
139
|
-
// * - Webhooks (HTTP endpoints)
|
|
140
|
-
// * - Jobs (scheduled tasks)
|
|
141
|
-
// * - PreProcessors (run before messages reach agent)
|
|
142
|
-
// * - PostProcessors (run after agent generates responses)
|
|
143
|
-
// *
|
|
144
|
-
// * The compiler will:
|
|
145
|
-
// * 1. Detect this LuaAgent
|
|
146
|
-
// * 2. Extract all components (skills, webhooks, jobs, processors)
|
|
147
|
-
// * 3. Sync the persona with lua.skill.yaml
|
|
148
|
-
// * 4. Deploy everything to the Lua platform
|
|
149
|
-
// */
|
|
150
|
-
// export const agent = new LuaAgent({
|
|
151
|
-
// name: "my-assistant",
|
|
152
|
-
// persona: `You are a helpful e-commerce assistant that can help users with:
|
|
153
|
-
// - Weather information
|
|
154
|
-
// - User account management
|
|
155
|
-
// - Product browsing and search
|
|
156
|
-
// - Shopping basket operations
|
|
157
|
-
// - Order management
|
|
158
|
-
// - Movie database management
|
|
159
|
-
|
|
160
|
-
// You are friendly, helpful, and provide clear responses. When users ask about products,
|
|
161
|
-
// help them search and find what they need. When they want to purchase, guide them through
|
|
162
|
-
// the basket and checkout process.`,
|
|
163
|
-
|
|
164
|
-
// welcomeMessage: "Hello! I'm your e-commerce assistant. I can help you find products, manage your basket, and track orders. How can I help you today?",
|
|
165
|
-
|
|
166
|
-
// // Add all your skills here
|
|
167
|
-
// skills: [
|
|
168
|
-
// generalSkill,
|
|
169
|
-
// userDataSkill,
|
|
170
|
-
// productSkill,
|
|
171
|
-
// basketSkill,
|
|
172
|
-
// orderSkill,
|
|
173
|
-
// customDataSkill
|
|
174
|
-
// ],
|
|
175
|
-
|
|
176
|
-
// // Uncomment to add webhooks
|
|
177
|
-
// // webhooks: [
|
|
178
|
-
// // userEventWebhook,
|
|
179
|
-
// // paymentWebhook
|
|
180
|
-
// // ],
|
|
181
|
-
|
|
182
|
-
// // Uncomment to add scheduled jobs
|
|
183
|
-
// // jobs: [
|
|
184
|
-
// // dailyCleanupJob,
|
|
185
|
-
// // healthCheckJob
|
|
186
|
-
// // ],
|
|
187
|
-
|
|
188
|
-
// // Message preprocessors (filter spam, add context, etc.)
|
|
189
|
-
// preProcessors: [
|
|
190
|
-
// messageFilter
|
|
191
|
-
// ],
|
|
192
|
-
|
|
193
|
-
// // Response postprocessors (format output, add branding, etc.)
|
|
194
|
-
// postProcessors: [
|
|
195
|
-
// responseFormatter
|
|
196
|
-
// ]
|
|
197
|
-
// });
|
|
198
|
-
|
|
199
|
-
// // That's it! The compiler will detect this LuaAgent and deploy everything.
|
|
200
|
-
// // No need to export individual skills, webhooks, jobs, etc.
|
|
201
|
-
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Response Formatter PostProcessor
|
|
3
|
-
*
|
|
4
|
-
* PostProcessors run AFTER the AI agent generates a response.
|
|
5
|
-
* They can:
|
|
6
|
-
* - Format or beautify responses
|
|
7
|
-
* - Add branding or signatures
|
|
8
|
-
* - Translate responses
|
|
9
|
-
* - Add disclaimers
|
|
10
|
-
* - Filter sensitive information
|
|
11
|
-
* - Adapt tone or style
|
|
12
|
-
*
|
|
13
|
-
* The execute function receives:
|
|
14
|
-
* - user: UserDataInstance (current user info)
|
|
15
|
-
* - message: string (the user's original message)
|
|
16
|
-
* - response: string (the agent's generated response)
|
|
17
|
-
* - channel: string (where the response will be sent)
|
|
18
|
-
*
|
|
19
|
-
* Returns: The formatted response that will be sent to the user
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
import { PostProcessor } from "lua-cli";
|
|
23
|
-
|
|
24
|
-
const responseFormatter = new PostProcessor({
|
|
25
|
-
name: "response-formatter",
|
|
26
|
-
version: "1.0.0",
|
|
27
|
-
description: "Formats and enhances agent responses before sending to users",
|
|
28
|
-
context: "This postprocessor adds branding, formats responses for different channels, and ensures consistency.",
|
|
29
|
-
|
|
30
|
-
execute: async (user, message, response, channel) => {
|
|
31
|
-
console.log(`[ResponseFormatter] Formatting response for user ${user.id} via ${channel}`);
|
|
32
|
-
|
|
33
|
-
let formattedResponse = response;
|
|
34
|
-
|
|
35
|
-
// Example 1: Add personalized greeting for first-time users
|
|
36
|
-
if (user.metadata?.isFirstMessage) {
|
|
37
|
-
formattedResponse = `š Welcome, ${user.name || 'there'}! ${formattedResponse}`;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Example 2: Format based on channel
|
|
41
|
-
switch (channel.toLowerCase()) {
|
|
42
|
-
case 'sms':
|
|
43
|
-
// SMS: Keep it short, remove emojis, add link to full response
|
|
44
|
-
formattedResponse = formattedResponse
|
|
45
|
-
.replace(/[^\w\s.,!?-]/g, '') // Remove special chars
|
|
46
|
-
.substring(0, 160); // SMS limit
|
|
47
|
-
if (response.length > 160) {
|
|
48
|
-
formattedResponse += '... (continued at app.example.com)';
|
|
49
|
-
}
|
|
50
|
-
break;
|
|
51
|
-
|
|
52
|
-
case 'email':
|
|
53
|
-
// Email: Add proper formatting and signature
|
|
54
|
-
formattedResponse = `
|
|
55
|
-
<html>
|
|
56
|
-
<body style="font-family: Arial, sans-serif; line-height: 1.6;">
|
|
57
|
-
<p>Hi ${user.name || 'there'},</p>
|
|
58
|
-
<p>${formattedResponse.replace(/\n/g, '<br>')}</p>
|
|
59
|
-
<br>
|
|
60
|
-
<p>Best regards,<br>
|
|
61
|
-
<strong>Zara</strong><br>
|
|
62
|
-
<em>Your E-commerce Assistant</em></p>
|
|
63
|
-
<hr>
|
|
64
|
-
<p style="font-size: 0.8em; color: #666;">
|
|
65
|
-
This is an automated response. Reply to this email if you need further assistance.
|
|
66
|
-
</p>
|
|
67
|
-
</body>
|
|
68
|
-
</html>`;
|
|
69
|
-
break;
|
|
70
|
-
|
|
71
|
-
case 'slack':
|
|
72
|
-
case 'discord':
|
|
73
|
-
// Chat platforms: Add markdown formatting
|
|
74
|
-
formattedResponse = formattedResponse
|
|
75
|
-
.replace(/\*\*(.*?)\*\*/g, '*$1*') // Bold
|
|
76
|
-
.replace(/__(.*?)__/g, '_$1_'); // Italic
|
|
77
|
-
break;
|
|
78
|
-
|
|
79
|
-
default:
|
|
80
|
-
// Default: Clean formatting
|
|
81
|
-
break;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Example 3: Add product links automatically
|
|
85
|
-
// Detect when products are mentioned and add quick links
|
|
86
|
-
const productMentionPattern = /(?:product|item|sku)[\s:]+(\w+)/gi;
|
|
87
|
-
const matches = formattedResponse.matchAll(productMentionPattern);
|
|
88
|
-
|
|
89
|
-
for (const match of matches) {
|
|
90
|
-
const productId = match[1];
|
|
91
|
-
// You could look up actual product URLs here
|
|
92
|
-
formattedResponse = formattedResponse.replace(
|
|
93
|
-
match[0],
|
|
94
|
-
`${match[0]} [View](https://example.com/products/${productId})`
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Example 4: Add helpful footer based on context
|
|
99
|
-
const hasOrderMention = /order|purchase|buy/i.test(message);
|
|
100
|
-
const hasBasketMention = /basket|cart|checkout/i.test(message);
|
|
101
|
-
|
|
102
|
-
if (hasOrderMention) {
|
|
103
|
-
formattedResponse += '\n\nš” Tip: You can track your orders anytime by asking "show my orders"';
|
|
104
|
-
} else if (hasBasketMention) {
|
|
105
|
-
formattedResponse += '\n\nš Need help? Just ask me to "show my basket" or "checkout"';
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// Example 5: Filter sensitive information
|
|
109
|
-
// Remove any accidentally exposed sensitive data
|
|
110
|
-
formattedResponse = formattedResponse
|
|
111
|
-
.replace(/\b\d{16}\b/g, '****-****-****-****') // Credit card numbers
|
|
112
|
-
.replace(/\b\d{3}-\d{2}-\d{4}\b/g, '***-**-****') // SSN
|
|
113
|
-
.replace(/password[:\s]+\S+/gi, 'password: [REDACTED]'); // Passwords
|
|
114
|
-
|
|
115
|
-
// Example 6: Add emoji based on sentiment (simple version)
|
|
116
|
-
if (/thank|great|awesome|love|perfect/i.test(message)) {
|
|
117
|
-
formattedResponse = `š ${formattedResponse}`;
|
|
118
|
-
} else if (/problem|issue|error|wrong|broken/i.test(message)) {
|
|
119
|
-
formattedResponse = `š§ ${formattedResponse}`;
|
|
120
|
-
} else if (/help|how|what|where/i.test(message)) {
|
|
121
|
-
formattedResponse = `š” ${formattedResponse}`;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Example 7: Add timestamp for long responses
|
|
125
|
-
if (formattedResponse.length > 500) {
|
|
126
|
-
const timestamp = new Date().toLocaleTimeString();
|
|
127
|
-
formattedResponse += `\n\n_Response generated at ${timestamp}_`;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Example 8: Add disclaimer for legal/financial advice
|
|
131
|
-
const needsDisclaimer = /legal|law|lawsuit|sue|invest|stock|crypto|tax/i.test(message);
|
|
132
|
-
if (needsDisclaimer) {
|
|
133
|
-
formattedResponse += '\n\nā ļø _Disclaimer: This information is for general guidance only and should not be considered professional legal or financial advice. Please consult with a qualified professional for your specific situation._';
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Example 9: Ensure proper length
|
|
137
|
-
const MAX_LENGTH = 4000; // Most platforms have limits
|
|
138
|
-
if (formattedResponse.length > MAX_LENGTH) {
|
|
139
|
-
formattedResponse = formattedResponse.substring(0, MAX_LENGTH - 50) +
|
|
140
|
-
'...\n\n_Response truncated. Please ask for more specific information._';
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
console.log(`[ResponseFormatter] Original length: ${response.length} chars`);
|
|
144
|
-
console.log(`[ResponseFormatter] Formatted length: ${formattedResponse.length} chars`);
|
|
145
|
-
|
|
146
|
-
return formattedResponse;
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
export default responseFormatter;
|
|
151
|
-
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Message Filter PreProcessor
|
|
3
|
-
*
|
|
4
|
-
* PreProcessors run BEFORE messages reach the AI agent.
|
|
5
|
-
* They can:
|
|
6
|
-
* - Filter out spam or inappropriate content
|
|
7
|
-
* - Translate messages
|
|
8
|
-
* - Add context to messages
|
|
9
|
-
* - Modify user input
|
|
10
|
-
* - Block certain types of requests
|
|
11
|
-
*
|
|
12
|
-
* The execute function receives:
|
|
13
|
-
* - user: UserDataInstance (current user info)
|
|
14
|
-
* - message: string (the user's message)
|
|
15
|
-
* - channel: string (where the message came from)
|
|
16
|
-
*
|
|
17
|
-
* Returns: The potentially modified message that will be sent to the agent
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
import { PreProcessor } from "lua-cli";
|
|
21
|
-
|
|
22
|
-
const messageFilter = new PreProcessor({
|
|
23
|
-
name: "message-filter",
|
|
24
|
-
version: "1.0.0",
|
|
25
|
-
description: "Filters and preprocesses user messages before they reach the agent",
|
|
26
|
-
context: "This preprocessor removes spam, blocks inappropriate content, and adds helpful context to user messages.",
|
|
27
|
-
|
|
28
|
-
execute: async (user, message, channel) => {
|
|
29
|
-
console.log(`[MessageFilter] Processing message from user ${user.id} via ${channel}`);
|
|
30
|
-
|
|
31
|
-
// Example 1: Block spam patterns
|
|
32
|
-
const spamPatterns = [
|
|
33
|
-
/buy now/i,
|
|
34
|
-
/click here/i,
|
|
35
|
-
/free money/i,
|
|
36
|
-
/\b(viagra|cialis)\b/i
|
|
37
|
-
];
|
|
38
|
-
|
|
39
|
-
for (const pattern of spamPatterns) {
|
|
40
|
-
if (pattern.test(message)) {
|
|
41
|
-
console.log('[MessageFilter] Spam detected, blocking message');
|
|
42
|
-
return "[This message was blocked by spam filter]";
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Example 2: Remove excessive punctuation
|
|
47
|
-
let filteredMessage = message.replace(/([!?.]){3,}/g, '$1$1'); // Reduce !!!!! to !!
|
|
48
|
-
|
|
49
|
-
// Example 3: Normalize whitespace
|
|
50
|
-
filteredMessage = filteredMessage.trim().replace(/\s+/g, ' ');
|
|
51
|
-
|
|
52
|
-
// Example 4: Add user context for the agent
|
|
53
|
-
// This helps the agent understand who they're talking to
|
|
54
|
-
if (user.name && !filteredMessage.toLowerCase().includes('my name')) {
|
|
55
|
-
// Agent will have context about user's name without being intrusive
|
|
56
|
-
filteredMessage = `[User: ${user.name}] ${filteredMessage}`;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Example 5: Detect and flag urgent messages
|
|
60
|
-
const urgentKeywords = ['urgent', 'emergency', 'asap', 'immediately', 'help'];
|
|
61
|
-
const isUrgent = urgentKeywords.some(keyword =>
|
|
62
|
-
filteredMessage.toLowerCase().includes(keyword)
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
if (isUrgent) {
|
|
66
|
-
filteredMessage = `[URGENT] ${filteredMessage}`;
|
|
67
|
-
console.log('[MessageFilter] Urgent message flagged');
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Example 6: Add channel context
|
|
71
|
-
// This helps the agent adapt its response based on the channel
|
|
72
|
-
if (channel && channel !== 'default') {
|
|
73
|
-
filteredMessage = `[Via ${channel}] ${filteredMessage}`;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Example 7: Language detection hint (optional)
|
|
77
|
-
// You could integrate with a language detection library here
|
|
78
|
-
const hasNonEnglish = /[^\u0000-\u007F]/.test(message);
|
|
79
|
-
if (hasNonEnglish) {
|
|
80
|
-
filteredMessage = `[Contains non-ASCII characters] ${filteredMessage}`;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
console.log(`[MessageFilter] Original: "${message}"`);
|
|
84
|
-
console.log(`[MessageFilter] Filtered: "${filteredMessage}"`);
|
|
85
|
-
|
|
86
|
-
return filteredMessage;
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
export default messageFilter;
|
|
91
|
-
|