mojulo 0.0.0 → 0.1.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.
- package/README.md +53 -4
- package/lib/audit-logger-new.js +11 -0
- package/lib/auth/gate.js +25 -0
- package/lib/auth/service.js +17 -0
- package/lib/auth/session.js +63 -0
- package/lib/builder/chat-processor.js +607 -0
- package/lib/builder/composer-bridge.js +82 -0
- package/lib/builder/evaluator.js +159 -0
- package/lib/builder/executor.js +252 -0
- package/lib/builder/index.js +48 -0
- package/lib/builder/session.js +248 -0
- package/lib/builder/system-prompt.js +422 -0
- package/lib/builder/tone-presets.js +75 -0
- package/lib/builder/tool-executors.js +1418 -0
- package/lib/builder/tools.js +338 -0
- package/lib/builder/validators.js +239 -0
- package/lib/composer/composer.js +225 -0
- package/lib/composer/index.js +40 -0
- package/lib/composer/protocols/00_base.txt +19 -0
- package/lib/composer/protocols/01_knowledge.txt +9 -0
- package/lib/composer/protocols/02_form-gathering.txt +32 -0
- package/lib/composer/protocols/03_appointments.txt +16 -0
- package/lib/composer/protocols/04_triage.txt +15 -0
- package/lib/composer/protocols/05_optical-read.txt +22 -0
- package/lib/composer/response-builder.js +98 -0
- package/lib/config-builder.js +650 -0
- package/lib/db/ids.js +10 -0
- package/lib/db/index.js +179 -0
- package/lib/db/repositories/apiKeys.js +72 -0
- package/lib/db/repositories/auditLogs.js +12 -0
- package/lib/db/repositories/botSpaces.js +12 -0
- package/lib/db/repositories/builderSessions.js +312 -0
- package/lib/db/repositories/deploymentEvents.js +12 -0
- package/lib/db/repositories/deployments.js +385 -0
- package/lib/db/repositories/documents.js +68 -0
- package/lib/db/repositories/mcpJobs.js +84 -0
- package/lib/deployers/bot-fleet.js +110 -0
- package/lib/deployers/bot-proxy.js +72 -0
- package/lib/deployers/build.js +89 -0
- package/lib/deployers/cloud-deploy.js +310 -0
- package/lib/deployers/docker.js +439 -0
- package/lib/deployers/fly.js +432 -0
- package/lib/deployers/index.js +38 -0
- package/lib/deployment-auth.js +36 -0
- package/lib/document-parser.js +171 -0
- package/lib/embedder/chunker.js +93 -0
- package/lib/embedder/local.js +101 -0
- package/lib/embedder/preview-rag.js +93 -0
- package/lib/envelope-schema.js +54 -0
- package/lib/fleet/scoped-sql.js +342 -0
- package/lib/form-schema-config/base.js +135 -0
- package/lib/form-schema-config/index.js +286 -0
- package/lib/form-schema-config/locales/af-ZA.js +153 -0
- package/lib/form-schema-config/locales/ar-AE.js +142 -0
- package/lib/form-schema-config/locales/ar-SA.js +164 -0
- package/lib/form-schema-config/locales/de-DE.js +152 -0
- package/lib/form-schema-config/locales/en-AU.js +161 -0
- package/lib/form-schema-config/locales/en-CA.js +115 -0
- package/lib/form-schema-config/locales/en-GB.js +132 -0
- package/lib/form-schema-config/locales/en-IN.js +219 -0
- package/lib/form-schema-config/locales/en-MY.js +171 -0
- package/lib/form-schema-config/locales/en-NG.js +198 -0
- package/lib/form-schema-config/locales/en-PH.js +186 -0
- package/lib/form-schema-config/locales/en-SG.js +153 -0
- package/lib/form-schema-config/locales/en-US.js +138 -0
- package/lib/form-schema-config/locales/es-ES.js +171 -0
- package/lib/form-schema-config/locales/es-MX.js +193 -0
- package/lib/form-schema-config/locales/fr-CA.js +138 -0
- package/lib/form-schema-config/locales/fr-FR.js +155 -0
- package/lib/form-schema-config/locales/hi-IN.js +219 -0
- package/lib/form-schema-config/locales/it-IT.js +157 -0
- package/lib/form-schema-config/locales/ja-JP.js +169 -0
- package/lib/form-schema-config/locales/ko-KR.js +140 -0
- package/lib/form-schema-config/locales/nl-NL.js +149 -0
- package/lib/form-schema-config/locales/pt-BR.js +168 -0
- package/lib/form-schema-config/locales/zh-CN.js +172 -0
- package/lib/form-schema-config/locales/zh-HK.js +142 -0
- package/lib/form-structure-schema.js +191 -0
- package/lib/llm-providers.js +828 -0
- package/lib/markdown.js +197 -0
- package/lib/mcp/catalysts/appointment-to-calendar.md +84 -0
- package/lib/mcp/catalysts/conversations-to-channel-digest.md +104 -0
- package/lib/mcp/catalysts/document-extract-to-store.md +92 -0
- package/lib/mcp/catalysts/knowledge-gap-miner.md +96 -0
- package/lib/mcp/catalysts/loader.js +144 -0
- package/lib/mcp/catalysts/qualify-lead-to-crm.md +83 -0
- package/lib/mcp/catalysts/scan-conversations-for-signal.md +92 -0
- package/lib/mcp/catalysts/submission-to-ticket.md +83 -0
- package/lib/mcp/catalysts/submissions-to-warehouse.md +103 -0
- package/lib/mcp/catalysts/weekly-submissions-digest.md +82 -0
- package/lib/mcp/jobs.js +64 -0
- package/lib/mcp/server.js +184 -0
- package/lib/mcp/session-binding.js +130 -0
- package/lib/mcp/tools/build.js +123 -0
- package/lib/mcp/tools/catalysts.js +477 -0
- package/lib/mcp/tools/context.js +325 -0
- package/lib/mcp/tools/fleet.js +391 -0
- package/lib/mcp/tools/jobs-tools.js +240 -0
- package/lib/mcp/tools/operate.js +314 -0
- package/lib/preview/build-preview-config.js +136 -0
- package/lib/rate-limiter.js +11 -0
- package/lib/resolve-api-key.js +142 -0
- package/lib/storage/index.js +40 -0
- package/messages/de.json +2136 -0
- package/messages/en.json +2136 -0
- package/messages/es.json +2136 -0
- package/messages/fr.json +2136 -0
- package/messages/it.json +2136 -0
- package/messages/ja.json +2136 -0
- package/messages/ko.json +2136 -0
- package/messages/nl.json +2136 -0
- package/messages/pl.json +2136 -0
- package/messages/pt.json +2136 -0
- package/messages/ru.json +2136 -0
- package/messages/uk.json +2136 -0
- package/messages/zh.json +2136 -0
- package/package.json +61 -5
- package/scripts/mcp-config.mjs +162 -0
- package/scripts/mcp-stdio-loader.mjs +42 -0
- package/scripts/mcp-stdio.mjs +108 -0
- package/scripts/mojulo-paths.mjs +48 -0
|
@@ -0,0 +1,607 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat Processor for Modular Bot Creation
|
|
3
|
+
*
|
|
4
|
+
* Processes user messages and generates contextual responses.
|
|
5
|
+
* Uses rule-based intent detection with optional LLM enhancement.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
toggleProtocol,
|
|
10
|
+
saveCoreConfig,
|
|
11
|
+
saveIdentityConfig,
|
|
12
|
+
saveProtocolConfig,
|
|
13
|
+
} from './index.js';
|
|
14
|
+
|
|
15
|
+
// Message types
|
|
16
|
+
const MESSAGE_TYPES = {
|
|
17
|
+
BOT_TEXT: 'bot_text',
|
|
18
|
+
BOT_QUESTION: 'bot_question',
|
|
19
|
+
BOT_STEP_CARD: 'bot_step_card',
|
|
20
|
+
BOT_CONFIRMATION: 'bot_confirmation',
|
|
21
|
+
BOT_SUCCESS: 'bot_success',
|
|
22
|
+
BOT_ERROR: 'bot_error',
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// Intent patterns
|
|
26
|
+
const INTENT_PATTERNS = {
|
|
27
|
+
// Protocol mentions
|
|
28
|
+
knowledge: [/knowledge/i, /rag/i, /document/i, /faq/i, /answer.*question/i, /search/i],
|
|
29
|
+
formGathering: [/form/i, /collect/i, /gather/i, /information/i, /lead/i, /contact/i],
|
|
30
|
+
appointments: [/appointment/i, /book/i, /schedule/i, /calendar/i, /meeting/i],
|
|
31
|
+
|
|
32
|
+
// Action intents
|
|
33
|
+
deploy: [/deploy/i, /launch/i, /publish/i, /go live/i, /start/i, /create bot/i],
|
|
34
|
+
confirm: [/^yes$/i, /confirm/i, /correct/i, /right/i, /looks? good/i, /^ok$/i, /^yep$/i],
|
|
35
|
+
deny: [/^no$/i, /cancel/i, /wrong/i, /change/i, /redo/i, /different/i],
|
|
36
|
+
|
|
37
|
+
// Setup intents
|
|
38
|
+
setup_core: [/provider/i, /model/i, /name.*bot/i, /bot.*name/i, /core.*config/i],
|
|
39
|
+
setup_identity: [/identity/i, /personality/i, /objective/i, /first message/i, /greeting/i],
|
|
40
|
+
setup_protocols: [/capabilities/i, /protocols/i, /what.*can.*do/i, /choose.*features/i],
|
|
41
|
+
setup_knowledge: [/configure.*knowledge/i, /setup.*knowledge/i, /knowledge.*config/i, /rag.*config/i],
|
|
42
|
+
setup_forms: [/configure.*form/i, /setup.*form/i, /form.*config/i, /form.*collection/i],
|
|
43
|
+
setup_appointments: [/configure.*appointment/i, /setup.*appointment/i, /appointment.*config/i, /calendar.*config/i],
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Protocol descriptions
|
|
47
|
+
const PROTOCOL_INFO = {
|
|
48
|
+
knowledge: {
|
|
49
|
+
name: 'Knowledge Base',
|
|
50
|
+
description: 'Answer questions from your documents using RAG',
|
|
51
|
+
},
|
|
52
|
+
formGathering: {
|
|
53
|
+
name: 'Form Collection',
|
|
54
|
+
description: 'Gather information through conversational forms',
|
|
55
|
+
},
|
|
56
|
+
appointments: {
|
|
57
|
+
name: 'Appointments',
|
|
58
|
+
description: 'Allow users to book calendar appointments',
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Process a chat message and generate response
|
|
64
|
+
* @param {Object} params - Processing parameters
|
|
65
|
+
* @param {Object} params.session - Current session
|
|
66
|
+
* @param {string} params.userId - User ID
|
|
67
|
+
* @param {string} params.message - User message
|
|
68
|
+
* @param {string} params.messageType - Message type (text, selection, confirmation)
|
|
69
|
+
* @param {Object} params.context - Additional context
|
|
70
|
+
* @returns {Promise<{ messages: Array, sessionUpdate?: Object }>}
|
|
71
|
+
*/
|
|
72
|
+
export async function processChatMessage({
|
|
73
|
+
session,
|
|
74
|
+
userId,
|
|
75
|
+
message,
|
|
76
|
+
messageType,
|
|
77
|
+
context,
|
|
78
|
+
}) {
|
|
79
|
+
const messages = [];
|
|
80
|
+
let sessionUpdate = null;
|
|
81
|
+
|
|
82
|
+
// Detect intent
|
|
83
|
+
const intent = detectIntent(message);
|
|
84
|
+
const protocols = detectProtocols(message);
|
|
85
|
+
|
|
86
|
+
// Handle based on message type and intent
|
|
87
|
+
if (messageType === 'confirmation') {
|
|
88
|
+
return handleConfirmation(message, session, userId, context);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (messageType === 'selection') {
|
|
92
|
+
return handleSelection(message, session, userId, context);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Handle protocol detection
|
|
96
|
+
if (protocols.length > 0) {
|
|
97
|
+
return handleProtocolDetection(protocols, session, userId, message);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Handle specific intents
|
|
101
|
+
if (intent === 'deploy') {
|
|
102
|
+
return handleDeployIntent(session, userId);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (intent === 'setup_core') {
|
|
106
|
+
return handleCoreSetupIntent(session);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (intent === 'setup_identity') {
|
|
110
|
+
return handleIdentitySetupIntent(session);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (intent === 'setup_protocols') {
|
|
114
|
+
return handleProtocolsSetupIntent(session);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (intent === 'setup_knowledge') {
|
|
118
|
+
return handleKnowledgeSetupIntent(session);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (intent === 'setup_forms') {
|
|
122
|
+
return handleFormsSetupIntent(session);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (intent === 'setup_appointments') {
|
|
126
|
+
return handleAppointmentsSetupIntent(session);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Default: Analyze message and suggest next step
|
|
130
|
+
return suggestNextStep(session, message);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Detect protocols mentioned in message
|
|
135
|
+
*/
|
|
136
|
+
function detectProtocols(message) {
|
|
137
|
+
const detected = [];
|
|
138
|
+
|
|
139
|
+
for (const [protocol, patterns] of Object.entries(INTENT_PATTERNS)) {
|
|
140
|
+
if (['knowledge', 'formGathering', 'appointments'].includes(protocol)) {
|
|
141
|
+
for (const pattern of patterns) {
|
|
142
|
+
if (pattern.test(message)) {
|
|
143
|
+
detected.push(protocol);
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return [...new Set(detected)];
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Detect user intent
|
|
155
|
+
*/
|
|
156
|
+
function detectIntent(message) {
|
|
157
|
+
for (const [intent, patterns] of Object.entries(INTENT_PATTERNS)) {
|
|
158
|
+
if (!['knowledge', 'formGathering', 'appointments'].includes(intent)) {
|
|
159
|
+
for (const pattern of patterns) {
|
|
160
|
+
if (pattern.test(message)) {
|
|
161
|
+
return intent;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Handle protocol detection
|
|
171
|
+
*/
|
|
172
|
+
async function handleProtocolDetection(protocols, session, userId, message) {
|
|
173
|
+
const messages = [];
|
|
174
|
+
const enabledProtocols = session.enabledProtocols || {};
|
|
175
|
+
|
|
176
|
+
// Build protocol description
|
|
177
|
+
const protocolList = protocols
|
|
178
|
+
.map((p) => `**${PROTOCOL_INFO[p]?.name || p}**: ${PROTOCOL_INFO[p]?.description || ''}`)
|
|
179
|
+
.join('\n');
|
|
180
|
+
|
|
181
|
+
messages.push({
|
|
182
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
183
|
+
content: `I'll set up your bot with these capabilities:\n\n${protocolList}`,
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// Show protocol selection card for confirmation
|
|
187
|
+
messages.push({
|
|
188
|
+
type: MESSAGE_TYPES.BOT_STEP_CARD,
|
|
189
|
+
content: null,
|
|
190
|
+
data: {
|
|
191
|
+
step: 'protocols',
|
|
192
|
+
knowledge: protocols.includes('knowledge'),
|
|
193
|
+
formGathering: protocols.includes('formGathering'),
|
|
194
|
+
appointments: protocols.includes('appointments'),
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
return { messages };
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Handle confirmation responses
|
|
203
|
+
*/
|
|
204
|
+
async function handleConfirmation(message, session, userId, context) {
|
|
205
|
+
const isConfirmed = /^(yes|confirm|correct|right|ok|yep)/i.test(message);
|
|
206
|
+
|
|
207
|
+
if (isConfirmed) {
|
|
208
|
+
// Move to next step based on current state
|
|
209
|
+
return suggestNextStep(session, 'Confirmed! Let\'s continue.');
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return {
|
|
213
|
+
messages: [
|
|
214
|
+
{
|
|
215
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
216
|
+
content: "No problem! What would you like to change?",
|
|
217
|
+
},
|
|
218
|
+
],
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Handle selection responses
|
|
224
|
+
*/
|
|
225
|
+
async function handleSelection(selection, session, userId, context) {
|
|
226
|
+
// Just acknowledge and continue
|
|
227
|
+
return suggestNextStep(session, selection);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Handle deploy intent
|
|
232
|
+
*/
|
|
233
|
+
async function handleDeployIntent(session, userId) {
|
|
234
|
+
const messages = [];
|
|
235
|
+
const enabledProtocols = session.enabledProtocols || {};
|
|
236
|
+
const protocolConfigs = session.protocolConfigs || {};
|
|
237
|
+
|
|
238
|
+
// Check if ready to deploy
|
|
239
|
+
if (!session.coreConfig?.botName) {
|
|
240
|
+
messages.push({
|
|
241
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
242
|
+
content: "Before deploying, we need to set up some basics. Let's start with the core configuration.",
|
|
243
|
+
});
|
|
244
|
+
messages.push({
|
|
245
|
+
type: MESSAGE_TYPES.BOT_STEP_CARD,
|
|
246
|
+
content: null,
|
|
247
|
+
data: { step: 'core' },
|
|
248
|
+
});
|
|
249
|
+
return { messages };
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Check if any protocols are enabled
|
|
253
|
+
const hasProtocols = Object.values(enabledProtocols).some((v) => v);
|
|
254
|
+
if (!hasProtocols) {
|
|
255
|
+
messages.push({
|
|
256
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
257
|
+
content: "Before deploying, we need to choose what your bot can do.",
|
|
258
|
+
});
|
|
259
|
+
messages.push({
|
|
260
|
+
type: MESSAGE_TYPES.BOT_STEP_CARD,
|
|
261
|
+
content: null,
|
|
262
|
+
data: { step: 'protocols' },
|
|
263
|
+
});
|
|
264
|
+
return { messages };
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (!session.identityConfig?.objective) {
|
|
268
|
+
messages.push({
|
|
269
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
270
|
+
content: "We need to define your bot's identity before deploying.",
|
|
271
|
+
});
|
|
272
|
+
messages.push({
|
|
273
|
+
type: MESSAGE_TYPES.BOT_STEP_CARD,
|
|
274
|
+
content: null,
|
|
275
|
+
data: { step: 'identity' },
|
|
276
|
+
});
|
|
277
|
+
return { messages };
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Check if any enabled protocols need configuration
|
|
281
|
+
if (enabledProtocols.knowledge && !protocolConfigs.knowledge) {
|
|
282
|
+
messages.push({
|
|
283
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
284
|
+
content: "Before deploying, let's configure the Knowledge Base.",
|
|
285
|
+
});
|
|
286
|
+
messages.push({
|
|
287
|
+
type: MESSAGE_TYPES.BOT_STEP_CARD,
|
|
288
|
+
content: null,
|
|
289
|
+
data: { step: 'knowledge' },
|
|
290
|
+
});
|
|
291
|
+
return { messages };
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (enabledProtocols.formGathering && !protocolConfigs.formGathering) {
|
|
295
|
+
messages.push({
|
|
296
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
297
|
+
content: "Before deploying, let's set up Form Collection.",
|
|
298
|
+
});
|
|
299
|
+
messages.push({
|
|
300
|
+
type: MESSAGE_TYPES.BOT_STEP_CARD,
|
|
301
|
+
content: null,
|
|
302
|
+
data: { step: 'formGathering' },
|
|
303
|
+
});
|
|
304
|
+
return { messages };
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
if (enabledProtocols.appointments && !protocolConfigs.appointments) {
|
|
308
|
+
messages.push({
|
|
309
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
310
|
+
content: "Before deploying, let's configure Appointments.",
|
|
311
|
+
});
|
|
312
|
+
messages.push({
|
|
313
|
+
type: MESSAGE_TYPES.BOT_STEP_CARD,
|
|
314
|
+
content: null,
|
|
315
|
+
data: { step: 'appointments' },
|
|
316
|
+
});
|
|
317
|
+
return { messages };
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Ready to deploy
|
|
321
|
+
const protocolNames = Object.entries(enabledProtocols)
|
|
322
|
+
.filter(([_, enabled]) => enabled)
|
|
323
|
+
.map(([name]) => PROTOCOL_INFO[name]?.name || name);
|
|
324
|
+
|
|
325
|
+
messages.push({
|
|
326
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
327
|
+
content: "Everything looks ready! Here's a summary of your bot:",
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
messages.push({
|
|
331
|
+
type: MESSAGE_TYPES.BOT_STEP_CARD,
|
|
332
|
+
content: null,
|
|
333
|
+
data: {
|
|
334
|
+
step: 'deploy',
|
|
335
|
+
botName: session.coreConfig.botName,
|
|
336
|
+
protocols: protocolNames,
|
|
337
|
+
provider: session.coreConfig.provider || 'Anthropic',
|
|
338
|
+
model: session.coreConfig.model,
|
|
339
|
+
},
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
return { messages };
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Handle core setup intent
|
|
347
|
+
*/
|
|
348
|
+
async function handleCoreSetupIntent(session) {
|
|
349
|
+
return {
|
|
350
|
+
messages: [
|
|
351
|
+
{
|
|
352
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
353
|
+
content: "Let's configure the core settings for your bot.",
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
type: MESSAGE_TYPES.BOT_STEP_CARD,
|
|
357
|
+
content: null,
|
|
358
|
+
data: {
|
|
359
|
+
step: 'core',
|
|
360
|
+
provider: session.coreConfig?.provider,
|
|
361
|
+
model: session.coreConfig?.model,
|
|
362
|
+
botName: session.coreConfig?.botName,
|
|
363
|
+
},
|
|
364
|
+
},
|
|
365
|
+
],
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Handle identity setup intent
|
|
371
|
+
*/
|
|
372
|
+
async function handleIdentitySetupIntent(session) {
|
|
373
|
+
return {
|
|
374
|
+
messages: [
|
|
375
|
+
{
|
|
376
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
377
|
+
content: "Let's define your bot's personality and behavior.",
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
type: MESSAGE_TYPES.BOT_STEP_CARD,
|
|
381
|
+
content: null,
|
|
382
|
+
data: {
|
|
383
|
+
step: 'identity',
|
|
384
|
+
objective: session.identityConfig?.objective,
|
|
385
|
+
firstMessage: session.identityConfig?.firstMessage,
|
|
386
|
+
displayName: session.identityConfig?.displayName,
|
|
387
|
+
},
|
|
388
|
+
},
|
|
389
|
+
],
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Handle protocols setup intent
|
|
395
|
+
*/
|
|
396
|
+
async function handleProtocolsSetupIntent(session) {
|
|
397
|
+
const enabledProtocols = session.enabledProtocols || {};
|
|
398
|
+
return {
|
|
399
|
+
messages: [
|
|
400
|
+
{
|
|
401
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
402
|
+
content: "Let's choose what capabilities your bot should have.",
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
type: MESSAGE_TYPES.BOT_STEP_CARD,
|
|
406
|
+
content: null,
|
|
407
|
+
data: {
|
|
408
|
+
step: 'protocols',
|
|
409
|
+
knowledge: enabledProtocols.knowledge || false,
|
|
410
|
+
formGathering: enabledProtocols.formGathering || false,
|
|
411
|
+
appointments: enabledProtocols.appointments || false,
|
|
412
|
+
},
|
|
413
|
+
},
|
|
414
|
+
],
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Handle knowledge base setup intent
|
|
420
|
+
*/
|
|
421
|
+
async function handleKnowledgeSetupIntent(session) {
|
|
422
|
+
const config = session.protocolConfigs?.knowledge || {};
|
|
423
|
+
return {
|
|
424
|
+
messages: [
|
|
425
|
+
{
|
|
426
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
427
|
+
content: "Let's configure the Knowledge Base for your bot.",
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
type: MESSAGE_TYPES.BOT_STEP_CARD,
|
|
431
|
+
content: null,
|
|
432
|
+
data: {
|
|
433
|
+
step: 'knowledge',
|
|
434
|
+
...config,
|
|
435
|
+
},
|
|
436
|
+
},
|
|
437
|
+
],
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Handle form collection setup intent
|
|
443
|
+
*/
|
|
444
|
+
async function handleFormsSetupIntent(session) {
|
|
445
|
+
const config = session.protocolConfigs?.formGathering || {};
|
|
446
|
+
return {
|
|
447
|
+
messages: [
|
|
448
|
+
{
|
|
449
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
450
|
+
content: "Let's set up Form Collection for your bot.",
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
type: MESSAGE_TYPES.BOT_STEP_CARD,
|
|
454
|
+
content: null,
|
|
455
|
+
data: {
|
|
456
|
+
step: 'formGathering',
|
|
457
|
+
...config,
|
|
458
|
+
},
|
|
459
|
+
},
|
|
460
|
+
],
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Handle appointments setup intent
|
|
466
|
+
*/
|
|
467
|
+
async function handleAppointmentsSetupIntent(session) {
|
|
468
|
+
const config = session.protocolConfigs?.appointments || {};
|
|
469
|
+
return {
|
|
470
|
+
messages: [
|
|
471
|
+
{
|
|
472
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
473
|
+
content: "Let's configure Appointments for your bot.",
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
type: MESSAGE_TYPES.BOT_STEP_CARD,
|
|
477
|
+
content: null,
|
|
478
|
+
data: {
|
|
479
|
+
step: 'appointments',
|
|
480
|
+
...config,
|
|
481
|
+
},
|
|
482
|
+
},
|
|
483
|
+
],
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Suggest next step based on session state
|
|
489
|
+
*/
|
|
490
|
+
function suggestNextStep(session, userMessage = '') {
|
|
491
|
+
const messages = [];
|
|
492
|
+
|
|
493
|
+
// Check what's missing and suggest
|
|
494
|
+
if (!session.coreConfig?.botName) {
|
|
495
|
+
messages.push({
|
|
496
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
497
|
+
content: "Great! Let's start by setting up the basics for your bot. Choose a provider, model, and give your bot a name.",
|
|
498
|
+
});
|
|
499
|
+
messages.push({
|
|
500
|
+
type: MESSAGE_TYPES.BOT_STEP_CARD,
|
|
501
|
+
content: null,
|
|
502
|
+
data: { step: 'core' },
|
|
503
|
+
});
|
|
504
|
+
return { messages };
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// Check if any protocols are enabled
|
|
508
|
+
const enabledProtocols = session.enabledProtocols || {};
|
|
509
|
+
const protocolConfigs = session.protocolConfigs || {};
|
|
510
|
+
const hasProtocols = Object.values(enabledProtocols).some((v) => v);
|
|
511
|
+
|
|
512
|
+
if (!hasProtocols) {
|
|
513
|
+
messages.push({
|
|
514
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
515
|
+
content: "Now let's choose what your bot can do. What capabilities would you like to enable?",
|
|
516
|
+
});
|
|
517
|
+
messages.push({
|
|
518
|
+
type: MESSAGE_TYPES.BOT_STEP_CARD,
|
|
519
|
+
content: null,
|
|
520
|
+
data: { step: 'protocols' },
|
|
521
|
+
});
|
|
522
|
+
return { messages };
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
if (!session.identityConfig?.objective) {
|
|
526
|
+
messages.push({
|
|
527
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
528
|
+
content: "Now let's define your bot's personality. What's its main objective and how should it greet users?",
|
|
529
|
+
});
|
|
530
|
+
messages.push({
|
|
531
|
+
type: MESSAGE_TYPES.BOT_STEP_CARD,
|
|
532
|
+
content: null,
|
|
533
|
+
data: {
|
|
534
|
+
step: 'identity',
|
|
535
|
+
displayName: session.coreConfig?.botName,
|
|
536
|
+
},
|
|
537
|
+
});
|
|
538
|
+
return { messages };
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// Check if any enabled protocols need configuration
|
|
542
|
+
// Knowledge base config
|
|
543
|
+
if (enabledProtocols.knowledge && !protocolConfigs.knowledge) {
|
|
544
|
+
messages.push({
|
|
545
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
546
|
+
content: "Let's configure the Knowledge Base. This allows your bot to answer questions from your documents.",
|
|
547
|
+
});
|
|
548
|
+
messages.push({
|
|
549
|
+
type: MESSAGE_TYPES.BOT_STEP_CARD,
|
|
550
|
+
content: null,
|
|
551
|
+
data: { step: 'knowledge' },
|
|
552
|
+
});
|
|
553
|
+
return { messages };
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// Form gathering config
|
|
557
|
+
if (enabledProtocols.formGathering && !protocolConfigs.formGathering) {
|
|
558
|
+
messages.push({
|
|
559
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
560
|
+
content: "Let's set up Form Collection. This allows your bot to gather information from users.",
|
|
561
|
+
});
|
|
562
|
+
messages.push({
|
|
563
|
+
type: MESSAGE_TYPES.BOT_STEP_CARD,
|
|
564
|
+
content: null,
|
|
565
|
+
data: { step: 'formGathering' },
|
|
566
|
+
});
|
|
567
|
+
return { messages };
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
// Appointments config
|
|
571
|
+
if (enabledProtocols.appointments && !protocolConfigs.appointments) {
|
|
572
|
+
messages.push({
|
|
573
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
574
|
+
content: "Let's configure Appointments. This allows your bot to help users book appointments.",
|
|
575
|
+
});
|
|
576
|
+
messages.push({
|
|
577
|
+
type: MESSAGE_TYPES.BOT_STEP_CARD,
|
|
578
|
+
content: null,
|
|
579
|
+
data: { step: 'appointments' },
|
|
580
|
+
});
|
|
581
|
+
return { messages };
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// All basics and protocol configs done - suggest deploy
|
|
585
|
+
const protocolNames = Object.entries(enabledProtocols)
|
|
586
|
+
.filter(([_, enabled]) => enabled)
|
|
587
|
+
.map(([name]) => PROTOCOL_INFO[name]?.name || name);
|
|
588
|
+
|
|
589
|
+
messages.push({
|
|
590
|
+
type: MESSAGE_TYPES.BOT_TEXT,
|
|
591
|
+
content: `Your bot "${session.coreConfig.botName}" is ready to deploy! It has ${protocolNames.join(', ')} capabilities.`,
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
messages.push({
|
|
595
|
+
type: MESSAGE_TYPES.BOT_STEP_CARD,
|
|
596
|
+
content: null,
|
|
597
|
+
data: {
|
|
598
|
+
step: 'deploy',
|
|
599
|
+
botName: session.coreConfig.botName,
|
|
600
|
+
protocols: protocolNames,
|
|
601
|
+
provider: session.coreConfig.provider || 'Anthropic',
|
|
602
|
+
model: session.coreConfig.model,
|
|
603
|
+
},
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
return { messages };
|
|
607
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composer Bridge for Builder Flow
|
|
3
|
+
*
|
|
4
|
+
* Bridges builder session data to the lib/composer system for instruction composition.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { composeInstructions, getEnabledProtocolNames } from '../composer/composer.js';
|
|
8
|
+
import { buildResponseFormatSection } from '../composer/response-builder.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Compose instructions from a builder session
|
|
12
|
+
*
|
|
13
|
+
* @param {Object} session - The builder session object
|
|
14
|
+
* @returns {Promise<{ instructions: string, responseFormat: string, protocolsIncluded: string[] }>}
|
|
15
|
+
*/
|
|
16
|
+
export async function composeFromSession(session) {
|
|
17
|
+
const { enabledProtocols, identityConfig, protocolData } = session;
|
|
18
|
+
|
|
19
|
+
// Build protocol data object for composer
|
|
20
|
+
const composerProtocolData = {};
|
|
21
|
+
|
|
22
|
+
if (enabledProtocols.formGathering && protocolData.formGathering) {
|
|
23
|
+
composerProtocolData.formStructure = protocolData.formGathering.generatedFormJson;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (enabledProtocols.appointments && protocolData.appointments) {
|
|
27
|
+
composerProtocolData.appointments = protocolData.appointments.destinations;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (enabledProtocols.triage && protocolData.triage) {
|
|
31
|
+
composerProtocolData.triage = protocolData.triage.routes;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Optical Read: tool executor stores fields under generatedConfigs.opticalRead.
|
|
35
|
+
// Honor protocolData first for symmetry with the wizard-side path, then fall
|
|
36
|
+
// back to generatedConfigs for the chat-builder path.
|
|
37
|
+
if (enabledProtocols.opticalRead) {
|
|
38
|
+
const fields =
|
|
39
|
+
protocolData.opticalRead?.fields ||
|
|
40
|
+
session.generatedConfigs?.opticalRead?.fields ||
|
|
41
|
+
[];
|
|
42
|
+
if (fields.length > 0) {
|
|
43
|
+
composerProtocolData.opticalRead = { fields };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Call composer
|
|
48
|
+
const instructions = await composeInstructions({
|
|
49
|
+
objective: identityConfig?.objective || '',
|
|
50
|
+
enabledProtocols,
|
|
51
|
+
protocolData: composerProtocolData,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Build response format (already included in instructions, but provide separately for reference)
|
|
55
|
+
const responseFormat = await buildResponseFormatSection(enabledProtocols);
|
|
56
|
+
|
|
57
|
+
// Get list of included protocols
|
|
58
|
+
const protocolsIncluded = getEnabledProtocolNames(enabledProtocols);
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
instructions,
|
|
62
|
+
responseFormat,
|
|
63
|
+
protocolsIncluded,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Preview composition without caching
|
|
69
|
+
*
|
|
70
|
+
* @param {Object} session - The modular session object
|
|
71
|
+
* @returns {Promise<Object>} - Composition preview with instructions and metadata
|
|
72
|
+
*/
|
|
73
|
+
export async function previewComposition(session) {
|
|
74
|
+
const result = await composeFromSession(session);
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
...result,
|
|
78
|
+
isCached: false,
|
|
79
|
+
previewedAt: new Date().toISOString(),
|
|
80
|
+
sessionId: session.id,
|
|
81
|
+
};
|
|
82
|
+
}
|