@ema.co/mcp-toolkit 1.5.1 → 1.5.2
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.
Potentially problematic release.
This version of @ema.co/mcp-toolkit might be problematic. Click here for more details.
- package/dist/mcp/handlers-consolidated.js +163 -8
- package/dist/mcp/prompts.js +80 -123
- package/dist/mcp/server.js +133 -6
- package/dist/mcp/tools-consolidated.js +89 -73
- package/dist/sdk/demo-generator.js +978 -0
- package/dist/sdk/workflow-generator.js +119 -25
- package/dist/sdk/workflow-intent.js +9 -0
- package/docs/mcp-tools-guide.md +27 -15
- package/docs/test-persona-creation.md +196 -0
- package/package.json +1 -1
- package/resources/templates/demo-scenarios/README.md +63 -0
|
@@ -18,18 +18,38 @@ const ACTION_NAMESPACES = {
|
|
|
18
18
|
document_trigger: ["triggers", "emainternal"],
|
|
19
19
|
chat_categorizer: ["routing", "emainternal"],
|
|
20
20
|
text_categorizer: ["routing", "emainternal"],
|
|
21
|
-
search: ["
|
|
22
|
-
live_web_search: ["
|
|
23
|
-
respond_with_sources: ["
|
|
24
|
-
call_llm: ["
|
|
25
|
-
fixed_response: ["
|
|
26
|
-
external_action_caller: ["
|
|
27
|
-
general_hitl: ["
|
|
28
|
-
send_email_agent: ["
|
|
29
|
-
conversation_to_search_query: ["
|
|
30
|
-
entity_extraction: ["
|
|
31
|
-
combine_search_results: ["
|
|
32
|
-
response_validator: ["
|
|
21
|
+
search: ["actions", "emainternal"], // Must be "actions" not "search"
|
|
22
|
+
live_web_search: ["actions", "emainternal"],
|
|
23
|
+
respond_with_sources: ["actions", "emainternal"], // Must be "actions" not "generation"
|
|
24
|
+
call_llm: ["actions", "emainternal"],
|
|
25
|
+
fixed_response: ["actions", "emainternal"],
|
|
26
|
+
external_action_caller: ["actions", "emainternal"],
|
|
27
|
+
general_hitl: ["actions", "emainternal"],
|
|
28
|
+
send_email_agent: ["actions", "emainternal"],
|
|
29
|
+
conversation_to_search_query: ["actions", "emainternal"],
|
|
30
|
+
entity_extraction: ["actions", "emainternal"],
|
|
31
|
+
combine_search_results: ["actions", "emainternal"],
|
|
32
|
+
response_validator: ["actions", "emainternal"],
|
|
33
|
+
};
|
|
34
|
+
// Version mapping for actions
|
|
35
|
+
const ACTION_VERSIONS = {
|
|
36
|
+
chat_trigger: "v1",
|
|
37
|
+
voice_trigger: "v1",
|
|
38
|
+
document_trigger: "v1",
|
|
39
|
+
chat_categorizer: "v1",
|
|
40
|
+
text_categorizer: "v1",
|
|
41
|
+
search: "v2",
|
|
42
|
+
live_web_search: "v1",
|
|
43
|
+
respond_with_sources: "v1",
|
|
44
|
+
call_llm: "v1",
|
|
45
|
+
fixed_response: "v1",
|
|
46
|
+
external_action_caller: "v1",
|
|
47
|
+
general_hitl: "v1",
|
|
48
|
+
send_email_agent: "v1",
|
|
49
|
+
conversation_to_search_query: "v1",
|
|
50
|
+
entity_extraction: "v1",
|
|
51
|
+
combine_search_results: "v1",
|
|
52
|
+
response_validator: "v1",
|
|
33
53
|
};
|
|
34
54
|
const OPERATOR_MAP = {
|
|
35
55
|
eq: 1,
|
|
@@ -93,31 +113,42 @@ export function compileWorkflow(spec) {
|
|
|
93
113
|
workflowName: {
|
|
94
114
|
name: {
|
|
95
115
|
namespaces: ["ema", "workflows"],
|
|
96
|
-
name: spec.name.toLowerCase().replace(/\s+/g, "_"),
|
|
116
|
+
name: spec.name.toLowerCase().replace(/\s+/g, "_").slice(0, 50), // Limit name length
|
|
97
117
|
},
|
|
98
118
|
},
|
|
99
119
|
actions,
|
|
120
|
+
enumTypes: validEnumTypes.length > 0 ? validEnumTypes : [], // Always include, even if empty
|
|
121
|
+
workflowInputs: {},
|
|
100
122
|
results,
|
|
123
|
+
namedResults: {},
|
|
124
|
+
displayName: spec.name,
|
|
125
|
+
description: spec.description || "",
|
|
126
|
+
namedResultsEditable: false,
|
|
127
|
+
namedResultsEnabled: false,
|
|
101
128
|
};
|
|
102
|
-
// Only add enumTypes if there are valid ones
|
|
103
|
-
if (validEnumTypes.length > 0) {
|
|
104
|
-
workflowDef.enumTypes = validEnumTypes;
|
|
105
|
-
}
|
|
106
129
|
// Build proto_config
|
|
107
130
|
const protoConfig = buildProtoConfig(spec);
|
|
108
131
|
return { workflow_def: workflowDef, proto_config: protoConfig };
|
|
109
132
|
}
|
|
110
133
|
function buildAction(node, enumTypeName) {
|
|
111
|
-
const namespaces = ACTION_NAMESPACES[node.actionType] ?? ["
|
|
134
|
+
const namespaces = ACTION_NAMESPACES[node.actionType] ?? ["actions", "emainternal"];
|
|
135
|
+
const version = ACTION_VERSIONS[node.actionType] ?? "v1";
|
|
112
136
|
const action = {
|
|
113
137
|
// CRITICAL: Use "name" not "actionName" - this is the node identifier in the workflow
|
|
114
138
|
name: node.id,
|
|
115
|
-
actionDisplayName: node.displayName,
|
|
116
|
-
actionDescription: node.description ?? "",
|
|
117
139
|
action: {
|
|
118
140
|
name: { namespaces, name: node.actionType },
|
|
141
|
+
version,
|
|
119
142
|
},
|
|
120
143
|
inputs: {},
|
|
144
|
+
displaySettings: {
|
|
145
|
+
displayName: node.displayName ?? "",
|
|
146
|
+
description: node.description ?? "",
|
|
147
|
+
coordinates: { x: 800, y: 200 }, // Default position
|
|
148
|
+
showConfig: 0,
|
|
149
|
+
},
|
|
150
|
+
typeArguments: {},
|
|
151
|
+
tools: [],
|
|
121
152
|
disableHumanInteraction: node.disableHitl ?? false,
|
|
122
153
|
};
|
|
123
154
|
// Build inputs
|
|
@@ -219,17 +250,80 @@ function buildInputBinding(binding) {
|
|
|
219
250
|
}
|
|
220
251
|
function buildProtoConfig(spec) {
|
|
221
252
|
const projectType = spec.personaType === "voice" ? 5 : spec.personaType === "chat" ? 4 : 2;
|
|
253
|
+
// Widget format expected by Ema API:
|
|
254
|
+
// { name: "widgetName", type: <type_id>, widgetName: { ...config... } }
|
|
255
|
+
// The config is stored under a key matching the widget's name
|
|
222
256
|
const widgets = [
|
|
223
|
-
{
|
|
224
|
-
|
|
257
|
+
{
|
|
258
|
+
name: "fusionModel",
|
|
259
|
+
type: 6,
|
|
260
|
+
fusionModel: { selectedModels: ["gpt-4.1"] }
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
name: "dataProtection",
|
|
264
|
+
type: 8,
|
|
265
|
+
dataProtection: { enabled: true }
|
|
266
|
+
},
|
|
225
267
|
];
|
|
226
268
|
if (spec.personaType === "voice") {
|
|
227
|
-
|
|
269
|
+
// Build voice settings from spec.voiceConfig with sensible defaults
|
|
270
|
+
const vc = spec.voiceConfig ?? {};
|
|
271
|
+
const defaultIdentity = `You are ${spec.name}. ${spec.description}`;
|
|
272
|
+
widgets.push({
|
|
273
|
+
name: "voiceSettings",
|
|
274
|
+
type: 38,
|
|
275
|
+
voiceSettings: {
|
|
276
|
+
languageHints: vc.languageHints ?? ["en-US"],
|
|
277
|
+
voiceModel: "default"
|
|
278
|
+
}
|
|
279
|
+
}, {
|
|
280
|
+
name: "conversationSettings",
|
|
281
|
+
type: 39,
|
|
282
|
+
conversationSettings: {
|
|
283
|
+
welcomeMessage: vc.welcomeMessage ?? `Hello, this is ${spec.name}. How can I help you today?`,
|
|
284
|
+
identityAndPurpose: vc.identityAndPurpose ?? defaultIdentity,
|
|
285
|
+
takeActionInstructions: vc.takeActionInstructions ?? "Take appropriate actions based on the user's request. Always confirm before making changes.",
|
|
286
|
+
hangupInstructions: vc.hangupInstructions ?? "End the call politely when the user's request is complete or they ask to hang up.",
|
|
287
|
+
transferCallInstructions: vc.transferInstructions ?? "",
|
|
288
|
+
speechCharacteristics: vc.speechCharacteristics ?? "Professional, friendly, and helpful",
|
|
289
|
+
systemPrompt: vc.systemPrompt ?? "",
|
|
290
|
+
waitMessage: vc.waitMessage ?? "One moment please while I look that up...",
|
|
291
|
+
}
|
|
292
|
+
}, {
|
|
293
|
+
name: "vadSettings",
|
|
294
|
+
type: 43,
|
|
295
|
+
vadSettings: {
|
|
296
|
+
turnTimeout: 5,
|
|
297
|
+
silenceEndCallTimeout: 30,
|
|
298
|
+
maxConversationDuration: 300
|
|
299
|
+
}
|
|
300
|
+
});
|
|
228
301
|
}
|
|
229
302
|
if (spec.personaType === "chat") {
|
|
230
|
-
|
|
303
|
+
// Build chat settings from spec.chatConfig with sensible defaults
|
|
304
|
+
const cc = spec.chatConfig ?? {};
|
|
305
|
+
widgets.push({
|
|
306
|
+
name: "chatbotSdkConfig",
|
|
307
|
+
type: 28,
|
|
308
|
+
chatbotSdkConfig: {
|
|
309
|
+
name: cc.name ?? spec.name,
|
|
310
|
+
theme: { primaryColor: cc.primaryColor ?? "#0066cc" },
|
|
311
|
+
allowedDomains: cc.allowedDomains ?? ["*"]
|
|
312
|
+
}
|
|
313
|
+
}, {
|
|
314
|
+
name: "feedbackMessage",
|
|
315
|
+
type: 33,
|
|
316
|
+
feedbackMessage: {
|
|
317
|
+
message: { question: cc.feedbackQuestion ?? "Was this response helpful?" },
|
|
318
|
+
feedbackFrequency: "always"
|
|
319
|
+
}
|
|
320
|
+
});
|
|
231
321
|
}
|
|
232
|
-
widgets.push({
|
|
322
|
+
widgets.push({
|
|
323
|
+
name: "fileUpload",
|
|
324
|
+
type: 3,
|
|
325
|
+
fileUpload: { useChunking: true }
|
|
326
|
+
});
|
|
233
327
|
return {
|
|
234
328
|
project_type: projectType,
|
|
235
329
|
name: spec.name,
|
|
@@ -1433,12 +1433,21 @@ export function intentToSpec(intent) {
|
|
|
1433
1433
|
nodeId: respondId,
|
|
1434
1434
|
output: searchId ? "response_with_sources" : "response_with_sources",
|
|
1435
1435
|
});
|
|
1436
|
+
// Build voiceConfig from intent.voice_config
|
|
1437
|
+
const voiceConfig = intent.persona_type === "voice" ? {
|
|
1438
|
+
welcomeMessage: intent.voice_config?.welcome_message,
|
|
1439
|
+
identityAndPurpose: intent.voice_config?.identity ?? intent.description,
|
|
1440
|
+
hangupInstructions: intent.voice_config?.hangup_instructions,
|
|
1441
|
+
// Additional fields can be extracted from intent description in the future
|
|
1442
|
+
} : undefined;
|
|
1436
1443
|
return {
|
|
1437
1444
|
name: intent.name,
|
|
1438
1445
|
description: intent.description,
|
|
1439
1446
|
personaType: intent.persona_type,
|
|
1440
1447
|
nodes,
|
|
1441
1448
|
resultMappings,
|
|
1449
|
+
...(voiceConfig && { voiceConfig }),
|
|
1450
|
+
...(intent.persona_type === "chat" && { chatConfig: { name: intent.name } }),
|
|
1442
1451
|
};
|
|
1443
1452
|
}
|
|
1444
1453
|
export function parseInput(input) {
|
package/docs/mcp-tools-guide.md
CHANGED
|
@@ -30,19 +30,29 @@ Some clients show a **prefixed name** (for example Cursor: `mcp_ema_workflow`).
|
|
|
30
30
|
|
|
31
31
|
### Create a new AI Employee (greenfield)
|
|
32
32
|
|
|
33
|
+
**Architecture**: Creates persona from template, configures settings. Template provides valid workflow.
|
|
34
|
+
|
|
33
35
|
1. **Requirements**: `template(questions=true)` (and `template(questions=true, category="Voice")` for voice)
|
|
34
36
|
2. **Pick agents/pattern**: `action(suggest="<use case>")`
|
|
35
|
-
3. **
|
|
36
|
-
4. **Generate workflow** (preview by default):
|
|
37
|
+
3. **Create and configure in one step**:
|
|
37
38
|
```typescript
|
|
38
|
-
workflow(
|
|
39
|
+
workflow(
|
|
40
|
+
input="<description of what it does>",
|
|
41
|
+
name="My AI Employee",
|
|
42
|
+
type="voice|chat|dashboard",
|
|
43
|
+
preview=false
|
|
44
|
+
)
|
|
39
45
|
```
|
|
40
|
-
|
|
41
|
-
|
|
46
|
+
This creates the persona from template and configures proto_config (voice settings, welcome message, etc.)
|
|
47
|
+
|
|
48
|
+
4. **Customize workflow** (if needed - AFTER creation):
|
|
42
49
|
```typescript
|
|
43
|
-
workflow(
|
|
50
|
+
workflow(persona_id="<id>", input="add search node before responding")
|
|
44
51
|
```
|
|
45
|
-
|
|
52
|
+
|
|
53
|
+
5. **Review**: `workflow(persona_id="<id>")` to analyze
|
|
54
|
+
|
|
55
|
+
**Key insight**: Don't try to generate and deploy a custom workflow in greenfield. Create from template first, then modify.
|
|
46
56
|
|
|
47
57
|
### Extend an existing AI Employee (brownfield)
|
|
48
58
|
|
|
@@ -129,10 +139,11 @@ persona(id="My Bot", mode="version_policy", auto_on_deploy=true)
|
|
|
129
139
|
|
|
130
140
|
All modification modes default to `preview=true` for safety. Use `preview=false` to deploy.
|
|
131
141
|
|
|
132
|
-
- **
|
|
142
|
+
- **Create (greenfield)**: Create new persona from template with configured settings
|
|
133
143
|
```typescript
|
|
134
|
-
workflow(input="IT helpdesk
|
|
135
|
-
|
|
144
|
+
workflow(input="IT helpdesk chatbot", name="IT Helper", type="chat", preview=false)
|
|
145
|
+
// Creates persona from template, configures proto_config
|
|
146
|
+
// Template workflow is preserved - customize later via modify
|
|
136
147
|
```
|
|
137
148
|
|
|
138
149
|
- **Extend (brownfield)**: Modify existing workflow with natural language
|
|
@@ -299,12 +310,13 @@ The MCP automatically condenses long prompts via `condensePromptForAutobuilder()
|
|
|
299
310
|
|
|
300
311
|
## Workflow Generation Strategy
|
|
301
312
|
|
|
302
|
-
|
|
|
303
|
-
|
|
304
|
-
| **
|
|
305
|
-
| **
|
|
313
|
+
| Scenario | Approach | How |
|
|
314
|
+
|----------|----------|-----|
|
|
315
|
+
| **New persona** (greenfield) | Create from template | `workflow(input="...", name="...", type="...", preview=false)` |
|
|
316
|
+
| **Modify existing** (brownfield) | LLM-native transform | `workflow(persona_id="...", input="add X")` |
|
|
317
|
+
| **Complex workflows** | Auto Builder | May time out with long prompts (>2500 chars) |
|
|
306
318
|
|
|
307
|
-
|
|
319
|
+
**DO NOT** try to compile custom workflows for new personas. The template provides a valid workflow structure - customize it after creation via brownfield/modify mode.
|
|
308
320
|
|
|
309
321
|
## Legacy tools (migration only)
|
|
310
322
|
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# Persona Creation Test Guide
|
|
2
|
+
|
|
3
|
+
This guide tests the workflow tool's ability to create and configure AI Employees (personas).
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
### Greenfield (New Personas)
|
|
8
|
+
1. **Create** persona from template (provides valid workflow structure)
|
|
9
|
+
2. **Fetch** the created persona (get template's structure)
|
|
10
|
+
3. **Update** proto_config only (voice settings, welcome message, etc.)
|
|
11
|
+
4. **Customize workflow later** via modify mode if needed
|
|
12
|
+
|
|
13
|
+
### Brownfield (Existing Personas)
|
|
14
|
+
1. **Fetch** existing persona and workflow
|
|
15
|
+
2. **Decompile** workflow_def → WorkflowSpec (typed representation)
|
|
16
|
+
3. **Transform** spec based on user intent (LLM-native)
|
|
17
|
+
4. **Compile** back to workflow_def
|
|
18
|
+
5. **Update** persona with transformed workflow
|
|
19
|
+
|
|
20
|
+
## Prerequisites
|
|
21
|
+
|
|
22
|
+
1. **Rebuild the code**:
|
|
23
|
+
```bash
|
|
24
|
+
cd /path/to/ema-mcp-toolkit
|
|
25
|
+
npm run build
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
2. **Restart the MCP server** (Cursor caches code):
|
|
29
|
+
- `Cmd+Shift+P` → "Developer: Reload Window"
|
|
30
|
+
|
|
31
|
+
3. Access to Ema dev environment
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Test Cases
|
|
36
|
+
|
|
37
|
+
### Test 1: Create Voice AI Employee (Greenfield)
|
|
38
|
+
|
|
39
|
+
**Goal:** Create a new Voice AI persona from template with configured settings.
|
|
40
|
+
|
|
41
|
+
**Command:**
|
|
42
|
+
```
|
|
43
|
+
workflow(
|
|
44
|
+
input="Voice AI sales development representative for Ema. Handles discovery calls, qualifies prospects, explains value propositions.",
|
|
45
|
+
name="SP-TEST-VOICE-GREENFIELD",
|
|
46
|
+
type="voice",
|
|
47
|
+
preview=false,
|
|
48
|
+
env="dev"
|
|
49
|
+
)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Expected Result:**
|
|
53
|
+
- `status: "deployed"`
|
|
54
|
+
- `deployed_to.created: true`
|
|
55
|
+
- `deployed_to.persona_id` returned
|
|
56
|
+
- `next_steps` explains how to customize workflow
|
|
57
|
+
|
|
58
|
+
**Verify:**
|
|
59
|
+
```
|
|
60
|
+
persona(id="<persona_id>", include_workflow=true, env="dev")
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Check:**
|
|
64
|
+
- [ ] Persona exists with correct name
|
|
65
|
+
- [ ] `proto_config.widgets` contains `conversationSettings` with:
|
|
66
|
+
- [ ] `welcomeMessage` - generated greeting
|
|
67
|
+
- [ ] `identityAndPurpose` - from description
|
|
68
|
+
- [ ] `workflow_def` has template workflow (trigger node + possibly more from template)
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
### Test 2: Create Chat AI Employee (Greenfield)
|
|
73
|
+
|
|
74
|
+
**Command:**
|
|
75
|
+
```
|
|
76
|
+
workflow(
|
|
77
|
+
input="IT helpdesk chatbot that answers employee questions about password resets, VPN setup, and software installation.",
|
|
78
|
+
name="SP-TEST-CHAT-GREENFIELD",
|
|
79
|
+
type="chat",
|
|
80
|
+
preview=false,
|
|
81
|
+
env="dev"
|
|
82
|
+
)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Expected Result:**
|
|
86
|
+
- `status: "deployed"`
|
|
87
|
+
- `deployed_to.created: true`
|
|
88
|
+
|
|
89
|
+
**Verify:**
|
|
90
|
+
```
|
|
91
|
+
persona(id="<persona_id>", include_workflow=true, env="dev")
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
### Test 3: Modify Existing Workflow (Brownfield)
|
|
97
|
+
|
|
98
|
+
**Prerequisites:** Create a persona first (Test 1 or 2).
|
|
99
|
+
|
|
100
|
+
**Goal:** Add functionality to an existing persona's workflow.
|
|
101
|
+
|
|
102
|
+
**Command:**
|
|
103
|
+
```
|
|
104
|
+
workflow(
|
|
105
|
+
persona_id="<persona_id_from_test_1>",
|
|
106
|
+
input="add a search node that queries the knowledge base before responding",
|
|
107
|
+
preview=true,
|
|
108
|
+
env="dev"
|
|
109
|
+
)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Expected Result:**
|
|
113
|
+
- `mode: "modify"`
|
|
114
|
+
- Shows proposed changes
|
|
115
|
+
- `modified_workflow` with new nodes
|
|
116
|
+
|
|
117
|
+
**Deploy the changes:**
|
|
118
|
+
```
|
|
119
|
+
workflow(
|
|
120
|
+
persona_id="<persona_id>",
|
|
121
|
+
input="add a search node that queries the knowledge base before responding",
|
|
122
|
+
preview=false,
|
|
123
|
+
env="dev"
|
|
124
|
+
)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
### Test 4: Analyze Workflow
|
|
130
|
+
|
|
131
|
+
**Command:**
|
|
132
|
+
```
|
|
133
|
+
workflow(persona_id="<persona_id>", env="dev")
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Expected Result:**
|
|
137
|
+
- `mode: "analyze"`
|
|
138
|
+
- `issues` array (may be empty if healthy)
|
|
139
|
+
- `metrics` with node_count, edge_count
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
### Test 5: Preview Only (No Deploy)
|
|
144
|
+
|
|
145
|
+
**Goal:** Verify preview mode returns workflow without deploying.
|
|
146
|
+
|
|
147
|
+
**Command:**
|
|
148
|
+
```
|
|
149
|
+
workflow(
|
|
150
|
+
input="Customer support voice AI that handles billing inquiries",
|
|
151
|
+
type="voice"
|
|
152
|
+
)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Expected Result:**
|
|
156
|
+
- `status: "preview"`
|
|
157
|
+
- `workflow_def` returned
|
|
158
|
+
- `proto_config` with voice settings populated
|
|
159
|
+
- NO persona created
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Cleanup
|
|
164
|
+
|
|
165
|
+
After testing, delete test personas via the Ema UI or leave them for inspection.
|
|
166
|
+
|
|
167
|
+
Test persona names:
|
|
168
|
+
- SP-TEST-VOICE-GREENFIELD
|
|
169
|
+
- SP-TEST-CHAT-GREENFIELD
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Troubleshooting
|
|
174
|
+
|
|
175
|
+
### "Internal Server Error"
|
|
176
|
+
- Usually means workflow format is wrong
|
|
177
|
+
- Check if MCP server has latest code (restart Cursor)
|
|
178
|
+
|
|
179
|
+
### "Widget name is empty"
|
|
180
|
+
- Old code issue - restart MCP server
|
|
181
|
+
|
|
182
|
+
### "Workflow name does not match"
|
|
183
|
+
- Old code tried to replace workflow - now we don't touch workflow in greenfield
|
|
184
|
+
|
|
185
|
+
### proto_config not updated
|
|
186
|
+
- Check that greenfield flow only updates proto_config, not workflow
|
|
187
|
+
- Widget merging should preserve template structure
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Key Code Locations
|
|
192
|
+
|
|
193
|
+
- **Greenfield flow**: `src/mcp/handlers-consolidated.ts` (search for "GREENFIELD")
|
|
194
|
+
- **Brownfield/modify flow**: `src/mcp/handlers-consolidated.ts` (search for "modify")
|
|
195
|
+
- **Workflow transformer**: `src/sdk/workflow-transformer.ts` (decompile/compile)
|
|
196
|
+
- **Proto config generation**: `src/sdk/workflow-generator.ts` (buildProtoConfig)
|
package/package.json
CHANGED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Demo Scenarios
|
|
2
|
+
|
|
3
|
+
Pre-built demo data scenarios for reliable AI Employee demonstrations.
|
|
4
|
+
|
|
5
|
+
## Available Scenarios
|
|
6
|
+
|
|
7
|
+
| Scenario | Use Case | Persona Types |
|
|
8
|
+
|----------|----------|---------------|
|
|
9
|
+
| `sales-sdr` | Sales Development Representative | Voice, Chat |
|
|
10
|
+
| `support-tier1` | Customer Support Tier 1 | Voice, Chat |
|
|
11
|
+
| `hr-assistant` | HR Policy & Benefits Assistant | Chat, Voice |
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
Generate a demo kit:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
demo(mode="kit", persona_id="...", scenario="sales-sdr")
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Validate demo readiness:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
demo(mode="validate_kit", persona_id="...")
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## What's Generated
|
|
28
|
+
|
|
29
|
+
Each demo kit includes:
|
|
30
|
+
|
|
31
|
+
1. **KB Documents** - Markdown files for the knowledge base with demo-ready data
|
|
32
|
+
2. **Demo Script** - Questions to ask with expected answers
|
|
33
|
+
3. **Fixed Response Fallbacks** - Workflow nodes for guaranteed responses
|
|
34
|
+
4. **Validation Queries** - Test queries to verify before the demo
|
|
35
|
+
|
|
36
|
+
## Customization
|
|
37
|
+
|
|
38
|
+
Add custom Q&A pairs:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
demo(mode="kit", persona_id="...", scenario="sales-sdr", custom_qa=[
|
|
42
|
+
{"question": "Tell me about feature X", "answer": "Feature X does..."}
|
|
43
|
+
])
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Creating Custom Scenarios
|
|
47
|
+
|
|
48
|
+
Create a JSON file in this directory with the following structure:
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"id": "my-scenario",
|
|
53
|
+
"name": "My Custom Scenario",
|
|
54
|
+
"description": "Description",
|
|
55
|
+
"persona_types": ["voice", "chat"],
|
|
56
|
+
"tags": ["tag1", "tag2"],
|
|
57
|
+
"intents": [...],
|
|
58
|
+
"entities": [...],
|
|
59
|
+
"qa_pairs": [...]
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
See existing scenarios for complete examples.
|