@ema.co/mcp-toolkit 2026.1.24 → 2026.1.26-3
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/README.md +10 -2
- package/dist/mcp/handlers/action/index.js +3 -18
- package/dist/mcp/handlers/data/index.js +385 -41
- package/dist/mcp/handlers/data/templates.js +107 -0
- package/dist/mcp/handlers/deprecation.js +50 -0
- package/dist/mcp/handlers/env/index.js +8 -4
- package/dist/mcp/handlers/knowledge/index.js +44 -237
- package/dist/mcp/handlers/persona/create.js +5 -11
- package/dist/mcp/handlers/persona/index.js +5 -1
- package/dist/mcp/handlers/persona/version.js +234 -0
- package/dist/mcp/handlers/reference/index.js +101 -1
- package/dist/mcp/handlers/sync/index.js +3 -18
- package/dist/mcp/handlers/template/index.js +75 -10
- package/dist/mcp/handlers/workflow/analyze.js +171 -0
- package/dist/mcp/handlers/workflow/compare.js +70 -0
- package/dist/mcp/handlers/workflow/compile.js +39 -0
- package/dist/mcp/handlers/workflow/deploy.js +73 -0
- package/dist/mcp/handlers/workflow/generate.js +350 -0
- package/dist/mcp/handlers/workflow/index.js +136 -0
- package/dist/mcp/handlers/workflow/modify.js +456 -0
- package/dist/mcp/handlers/workflow/optimize.js +136 -0
- package/dist/mcp/handlers/workflow/types.js +4 -0
- package/dist/mcp/handlers/workflow/utils.js +132 -0
- package/dist/mcp/handlers-consolidated.js +62 -2691
- package/dist/mcp/prompts.js +13 -14
- package/dist/mcp/resources.js +55 -54
- package/dist/mcp/server.js +93 -124
- package/dist/mcp/{tools-v2.js → tools.js} +1 -1
- package/dist/mcp/workflow-operations.js +2 -2
- package/dist/sdk/client-adapter.js +267 -32
- package/dist/sdk/client.js +31 -15
- package/dist/sdk/ema-client.js +183 -0
- package/dist/sdk/generated/template-fallbacks.js +123 -0
- package/dist/sdk/guidance.js +65 -11
- package/dist/sdk/index.js +3 -1
- package/dist/sdk/knowledge.js +16 -86
- package/dist/sdk/workflow-intent.js +27 -0
- package/dist/sdk/workflow-transformer.js +0 -342
- package/docs/DEBUG-ANALYSIS-unused-category-type-mismatch.md +481 -0
- package/docs/TODO-fix-analyzer-and-modify.md +182 -0
- package/package.json +9 -4
- package/dist/mcp/tools-consolidated.js +0 -866
- package/dist/mcp/tools-legacy.js +0 -736
- package/docs/CODEBASE-ANALYSIS-2026-01-23.md +0 -936
- package/docs/CODEBASE-ANALYSIS-PRIORITIZED.md +0 -774
- package/docs/api-contracts.md +0 -216
- package/docs/auto-builder-analysis.md +0 -271
- package/docs/blog/mcp-tool-design-lessons.md +0 -309
- package/docs/data-architecture.md +0 -166
- package/docs/ema-auto-builder-guide.html +0 -394
- package/docs/lessons-learned.md +0 -209
- package/docs/llm-native-workflow-design.md +0 -252
- package/docs/local-generation.md +0 -508
- package/docs/mcp-flow-diagram.md +0 -135
- package/docs/migration/action-composition-migration.md +0 -270
- package/docs/naming-conventions.md +0 -278
- package/docs/proposals/HANDOFF-tool-restructure.md +0 -526
- package/docs/proposals/action-composition.md +0 -490
- package/docs/proposals/explicit-method-restructure.md +0 -328
- package/docs/proposals/mcp-tool-restructure-2026-01.md +0 -366
- package/docs/proposals/self-contained-guidance.md +0 -427
- package/docs/proto-sdk-generation.md +0 -242
- package/docs/release-impact.md +0 -102
- package/docs/release-process.md +0 -157
- package/docs/staging.RULE.md +0 -142
- package/docs/test-persona-creation.md +0 -196
- package/docs/tool-consolidation-v2.md +0 -225
- package/docs/tool-response-standards.md +0 -256
- package/resources/docs/getting-started.md +0 -97
- package/resources/templates/auto-builder-rules.md +0 -224
- package/resources/templates/chat-ai/README.md +0 -119
- package/resources/templates/chat-ai/persona-config.json +0 -111
- package/resources/templates/dashboard-ai/README.md +0 -156
- package/resources/templates/dashboard-ai/persona-config.json +0 -180
- package/resources/templates/demo-scenarios/README.md +0 -63
- package/resources/templates/demo-scenarios/test-published-package.md +0 -116
- package/resources/templates/document-gen-ai/README.md +0 -132
- package/resources/templates/document-gen-ai/persona-config.json +0 -316
- package/resources/templates/voice-ai/README.md +0 -123
- package/resources/templates/voice-ai/persona-config.json +0 -74
- package/resources/templates/voice-ai/workflow-prompt.md +0 -121
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-generated fallback templates from proto definitions.
|
|
3
|
+
*
|
|
4
|
+
* These are used ONLY when the API is unavailable.
|
|
5
|
+
* The API templates (getPersonaTemplates()) are the source of truth.
|
|
6
|
+
*
|
|
7
|
+
* Generated at: 2026-01-25T21:51:05.018Z
|
|
8
|
+
*
|
|
9
|
+
* DO NOT EDIT MANUALLY - regenerate with: npm run generate:templates
|
|
10
|
+
*/
|
|
11
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
12
|
+
/**
|
|
13
|
+
* Voice AI persona config template (fallback).
|
|
14
|
+
*
|
|
15
|
+
* Fields derived from proto definitions:
|
|
16
|
+
* - VoicebotConversationSettingsWidget
|
|
17
|
+
* - VoicebotVoiceSettingsWidget
|
|
18
|
+
* - VoicebotCallSettingsWidget
|
|
19
|
+
* - VoicebotVADSettingsWidget
|
|
20
|
+
* - VoicebotDataStorageSettingsWidget
|
|
21
|
+
*/
|
|
22
|
+
export const VOICE_TEMPLATE_FALLBACK = {
|
|
23
|
+
"conversationSettings": {
|
|
24
|
+
"name": "{AI Name}",
|
|
25
|
+
"welcomeMessage": "Hello, thank you for calling {Company}. This is {AI Name}. How can I help you today?",
|
|
26
|
+
"speechCharacteristics": "Keep tone friendly and concise. Use brief pauses between sentences.",
|
|
27
|
+
"identityAndPurpose": "You are {AI Name}, an AI assistant for {Company}. Your responsibilities: 1) {Task 1} 2) {Task 2}",
|
|
28
|
+
"hangupInstructions": "End the call when: The caller explicitly says goodbye, or confirms they have no more questions.",
|
|
29
|
+
"takeActionInstructions": "</Case 1>\\n{Action Name}\\n\\nTrigger When: {Condition}\\n\\nIntent for tool call: \"{Intent}\"\\n\\nRequired parameters: { \"{param}\": \"\" }\\n</Case 1>",
|
|
30
|
+
"systemPrompt": "Tool Calling Instructions: Always collect required parameters before calling tools. Confirm with caller before executing.",
|
|
31
|
+
"waitMessage": "One moment while I look that up for you...",
|
|
32
|
+
"formFillingInstructions": "When collecting information, ask one question at a time. Confirm values before proceeding.",
|
|
33
|
+
"transferCallInstructions": "Transfer when: The caller explicitly requests a human agent, or the issue is beyond AI capabilities."
|
|
34
|
+
},
|
|
35
|
+
"voiceSettings": {
|
|
36
|
+
"languageHints": [
|
|
37
|
+
"en-US"
|
|
38
|
+
],
|
|
39
|
+
"voiceModel": "default"
|
|
40
|
+
},
|
|
41
|
+
"callSettings": {
|
|
42
|
+
"enableCallForwarding": false,
|
|
43
|
+
"callForwardingNumber": "",
|
|
44
|
+
"enableSpamCallPrevention": true,
|
|
45
|
+
"enableDisconnectCall": false
|
|
46
|
+
},
|
|
47
|
+
"vadSettings": {
|
|
48
|
+
"turnTimeout": 3,
|
|
49
|
+
"silenceEndCallTimeout": 30,
|
|
50
|
+
"maxConversationDuration": 600
|
|
51
|
+
},
|
|
52
|
+
"dataStorageSettings": {
|
|
53
|
+
"storeAudioRecording": true,
|
|
54
|
+
"storeTranscripts": true,
|
|
55
|
+
"storeAgentTranscript": true
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Field documentation for LLM consumption.
|
|
60
|
+
* Use this when generating prompts about config structure.
|
|
61
|
+
*/
|
|
62
|
+
export const VOICE_TEMPLATE_FIELD_DOCS = `
|
|
63
|
+
## Voice AI Persona Configuration Fields
|
|
64
|
+
|
|
65
|
+
### Conversation Settings
|
|
66
|
+
- name: Name for the Voicebot Agent that will be spoken
|
|
67
|
+
- welcomeMessage: Message spoken when call connects
|
|
68
|
+
- speechCharacteristics: Instructions on how voicebot should speak
|
|
69
|
+
- identityAndPurpose: What the voicebot is for and tools it has access to
|
|
70
|
+
- hangupInstructions: When to end the call
|
|
71
|
+
- takeActionInstructions: Instructions on what actions takeAction can perform
|
|
72
|
+
- systemPrompt: Instructions on how to respond to user, handle tools
|
|
73
|
+
- waitMessage: Message when tool is taking time to execute
|
|
74
|
+
- formFillingInstructions: How to collect form data conversationally
|
|
75
|
+
- transferCallInstructions: When to transfer to human agent
|
|
76
|
+
|
|
77
|
+
### Voice Settings
|
|
78
|
+
- languageHints: BCP47 language codes for speech recognition
|
|
79
|
+
- voiceModel: Voice model ID
|
|
80
|
+
|
|
81
|
+
### Call Settings
|
|
82
|
+
- enableCallForwarding: Enable call forwarding
|
|
83
|
+
- callForwardingNumber: Number to forward calls to
|
|
84
|
+
- enableSpamCallPrevention: Enable spam call prevention
|
|
85
|
+
- enableDisconnectCall: Enable disconnect call
|
|
86
|
+
|
|
87
|
+
### VAD Settings
|
|
88
|
+
- turnTimeout: Seconds to wait for caller to finish speaking
|
|
89
|
+
- silenceEndCallTimeout: Seconds of silence before ending call
|
|
90
|
+
- maxConversationDuration: Maximum call length in seconds
|
|
91
|
+
|
|
92
|
+
### Data Storage Settings
|
|
93
|
+
- storeAudioRecording: Store audio recordings
|
|
94
|
+
- storeTranscripts: Store call transcripts
|
|
95
|
+
- storeAgentTranscript: Store agent transcript
|
|
96
|
+
`;
|
|
97
|
+
/**
|
|
98
|
+
* Get template fallback by type.
|
|
99
|
+
* Returns undefined if type is not supported.
|
|
100
|
+
*/
|
|
101
|
+
export function getTemplateFallback(type) {
|
|
102
|
+
switch (type) {
|
|
103
|
+
case "voice":
|
|
104
|
+
return { ...VOICE_TEMPLATE_FALLBACK };
|
|
105
|
+
case "chat":
|
|
106
|
+
// TODO: Generate from chat proto definitions
|
|
107
|
+
return undefined;
|
|
108
|
+
case "dashboard":
|
|
109
|
+
// TODO: Generate from dashboard proto definitions
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get field documentation by type.
|
|
115
|
+
*/
|
|
116
|
+
export function getTemplateFieldDocs(type) {
|
|
117
|
+
switch (type) {
|
|
118
|
+
case "voice":
|
|
119
|
+
return VOICE_TEMPLATE_FIELD_DOCS;
|
|
120
|
+
default:
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
}
|
package/dist/sdk/guidance.js
CHANGED
|
@@ -82,8 +82,10 @@ await persona({ id: "abc", update: { workflow_spec: spec } }); // Then deploy`,
|
|
|
82
82
|
do: "For content changes: 1) Get workflow with persona(include_workflow=true), " +
|
|
83
83
|
"2) Edit the node's stringValue in the JSON, 3) Deploy with workflow(mode='deploy', workflow_def={...})",
|
|
84
84
|
dont: "Use workflow(mode='modify') for content changes - it will silently return 0 changes.",
|
|
85
|
-
example: `// STRUCTURAL change (supported)
|
|
86
|
-
|
|
85
|
+
example: `// STRUCTURAL change (supported via structured operations)
|
|
86
|
+
persona({ mode: "modify", id: "abc", operations: [
|
|
87
|
+
{ type: "insert", insert: { action_type: "hitl", insert_before: "send_email" }}
|
|
88
|
+
]})
|
|
87
89
|
|
|
88
90
|
// CONTENT change (requires manual edit)
|
|
89
91
|
const p = await persona({ id: "abc", include_workflow: true });
|
|
@@ -92,8 +94,42 @@ const wf = p.workflow_def;
|
|
|
92
94
|
wf.actions[2].inputs.data.stringValue = JSON.stringify(newData);
|
|
93
95
|
await workflow({ mode: "deploy", persona_id: "abc", workflow_def: wf });`,
|
|
94
96
|
antiExample: `// This will silently fail - content change via modify
|
|
95
|
-
|
|
96
|
-
related: ["workflow-spec-not-def"],
|
|
97
|
+
persona({ mode: "modify", id: "abc", operations: [...] }) // for content changes`,
|
|
98
|
+
related: ["workflow-spec-not-def", "llm-driven-modifications"],
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
id: "llm-driven-modifications",
|
|
102
|
+
level: "critical",
|
|
103
|
+
category: "workflow",
|
|
104
|
+
title: "LLM-Driven Workflow Modifications",
|
|
105
|
+
applies: "When modifying workflows structurally",
|
|
106
|
+
description: "The MCP does NOT parse natural language for modifications. YOU (the Agent/LLM) must build structured operations. " +
|
|
107
|
+
"Call persona(mode='modify') first to get workflow context, then build operations array.",
|
|
108
|
+
do: "1) Get context: persona(mode='modify', id='...') returns current_nodes, available_actions, example_operations. " +
|
|
109
|
+
"2) Build structured operations array. 3) Execute: persona(mode='modify', id='...', operations=[...])",
|
|
110
|
+
dont: "Pass natural language strings expecting MCP to parse them into operations.",
|
|
111
|
+
example: `// Step 1: Get context (returns current_nodes, available_actions, examples)
|
|
112
|
+
const ctx = await persona({ mode: "modify", id: "abc" });
|
|
113
|
+
|
|
114
|
+
// Step 2: YOU build structured operations based on user intent
|
|
115
|
+
const operations = [
|
|
116
|
+
{
|
|
117
|
+
type: "insert",
|
|
118
|
+
insert: {
|
|
119
|
+
action_type: "hitl",
|
|
120
|
+
display_name: "Email Approval",
|
|
121
|
+
insert_before: "send_email_node",
|
|
122
|
+
add_runif_to_downstream: true
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
];
|
|
126
|
+
|
|
127
|
+
// Step 3: Execute
|
|
128
|
+
await persona({ mode: "modify", id: "abc", operations });`,
|
|
129
|
+
antiExample: `// DON'T: Pass natural language expecting MCP to understand it
|
|
130
|
+
await persona({ mode: "modify", id: "abc", input: "add approval before email" })
|
|
131
|
+
// The MCP will NOT parse this - it returns context instead`,
|
|
132
|
+
related: ["workflow-modification-scope", "analyze-before-modify"],
|
|
97
133
|
},
|
|
98
134
|
// ─────────────────────────────────────────────────────────────────────────
|
|
99
135
|
// Important: Should Follow
|
|
@@ -162,7 +198,7 @@ const details = await persona({ id: list.personas[0].id });`,
|
|
|
162
198
|
example: `// Useful resources:
|
|
163
199
|
// ema://catalog/agents-summary - Action catalog
|
|
164
200
|
// ema://rules/anti-patterns - Common mistakes
|
|
165
|
-
// ema://
|
|
201
|
+
// ema://catalog/persona-templates - Live API templates
|
|
166
202
|
// ema://docs/usage-guide - Comprehensive guide`,
|
|
167
203
|
},
|
|
168
204
|
// ─────────────────────────────────────────────────────────────────────────
|
|
@@ -186,7 +222,7 @@ persona({ id: "abc", env: "prod" }) // production`,
|
|
|
186
222
|
export const TOOL_GUIDANCE = {
|
|
187
223
|
persona: {
|
|
188
224
|
toolName: "persona",
|
|
189
|
-
quickTip: "Use analyze=true before modifying. Use preview=true before deploying.",
|
|
225
|
+
quickTip: "Use analyze=true before modifying. Use preview=true before deploying. Build structured operations for modify.",
|
|
190
226
|
operations: [
|
|
191
227
|
{
|
|
192
228
|
name: "List all",
|
|
@@ -204,9 +240,14 @@ export const TOOL_GUIDANCE = {
|
|
|
204
240
|
example: 'persona(id="abc", analyze=true)',
|
|
205
241
|
},
|
|
206
242
|
{
|
|
207
|
-
name: "
|
|
208
|
-
description: "
|
|
209
|
-
example: 'persona(
|
|
243
|
+
name: "Get modify context",
|
|
244
|
+
description: "Get current_nodes, available_actions for building operations",
|
|
245
|
+
example: 'persona(mode="modify", id="abc")',
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
name: "Execute modify",
|
|
249
|
+
description: "Apply structured operations (insert/remove/rewire)",
|
|
250
|
+
example: 'persona(mode="modify", id="abc", operations=[...])',
|
|
210
251
|
},
|
|
211
252
|
{
|
|
212
253
|
name: "Create",
|
|
@@ -218,11 +259,13 @@ export const TOOL_GUIDANCE = {
|
|
|
218
259
|
list: "Get details: persona(id='<id>')",
|
|
219
260
|
get: "Analyze: persona(id='...', analyze=true)",
|
|
220
261
|
analyze: "Review issues, build workflow_spec, then update",
|
|
221
|
-
|
|
262
|
+
modify_context: "Build operations array, then execute with operations=[...]",
|
|
263
|
+
modify_execute: "Verify: persona(id='...') to confirm changes",
|
|
222
264
|
create: "Configure: persona(id='<new_id>', update={...})",
|
|
223
265
|
},
|
|
224
266
|
commonMistakes: [
|
|
225
|
-
"
|
|
267
|
+
"Passing natural language to modify mode (MCP doesn't parse NL)",
|
|
268
|
+
"Modifying without getting context first",
|
|
226
269
|
"Deploying without preview",
|
|
227
270
|
"Using raw workflow_def instead of workflow_spec",
|
|
228
271
|
"Forgetting Fallback in categorizers",
|
|
@@ -231,6 +274,7 @@ export const TOOL_GUIDANCE = {
|
|
|
231
274
|
"analyze-before-modify",
|
|
232
275
|
"preview-before-deploy",
|
|
233
276
|
"workflow-spec-not-def",
|
|
277
|
+
"llm-driven-modifications",
|
|
234
278
|
],
|
|
235
279
|
},
|
|
236
280
|
catalog: {
|
|
@@ -361,6 +405,16 @@ ${critical.map((r) => `- **${r.title}**: ${r.do}`).join("\n")}
|
|
|
361
405
|
## Important
|
|
362
406
|
${important.map((r) => `- **${r.title}**: ${r.do}`).join("\n")}
|
|
363
407
|
|
|
408
|
+
## LLM-Driven Architecture (CRITICAL)
|
|
409
|
+
The MCP does NOT parse natural language for workflow modifications.
|
|
410
|
+
**YOU (the Agent) must build structured operations:**
|
|
411
|
+
|
|
412
|
+
1. Get context: \`persona(mode="modify", id="...")\` → returns current_nodes, available_actions
|
|
413
|
+
2. Build operations array based on user intent
|
|
414
|
+
3. Execute: \`persona(mode="modify", id="...", operations=[...])\`
|
|
415
|
+
|
|
416
|
+
Example operations: insert, remove, rewire, update_config
|
|
417
|
+
|
|
364
418
|
## Resources
|
|
365
419
|
- \`ema://docs/usage-guide\` - Complete guide
|
|
366
420
|
- \`ema://catalog/agents-summary\` - Action catalog
|
package/dist/sdk/index.js
CHANGED
|
@@ -22,7 +22,9 @@ export { StateStore } from "./state.js";
|
|
|
22
22
|
// Auto Builder Knowledge Base
|
|
23
23
|
export {
|
|
24
24
|
// Catalogs & References
|
|
25
|
-
AGENT_CATALOG, WIDGET_CATALOG, WORKFLOW_PATTERNS, QUALIFYING_QUESTIONS, PLATFORM_CONCEPTS, WORKFLOW_EXECUTION_MODEL, COMMON_MISTAKES, DEBUG_CHECKLIST, GUIDANCE_TOPICS,
|
|
25
|
+
AGENT_CATALOG, WIDGET_CATALOG, WORKFLOW_PATTERNS, QUALIFYING_QUESTIONS, PLATFORM_CONCEPTS, WORKFLOW_EXECUTION_MODEL, COMMON_MISTAKES, DEBUG_CHECKLIST, GUIDANCE_TOPICS,
|
|
26
|
+
// VOICE_PERSONA_TEMPLATE removed - use getTemplateFallback("voice") from generated/template-fallbacks.ts
|
|
27
|
+
PROJECT_TYPES,
|
|
26
28
|
// Helper Functions
|
|
27
29
|
getAgentsByCategory, getAgentByName, getWidgetsForPersonaType, checkTypeCompatibility, getQualifyingQuestionsByCategory, getRequiredQualifyingQuestions, getConceptByTerm, suggestAgentsForUseCase, validateWorkflowPrompt,
|
|
28
30
|
// Workflow Analysis Functions
|
package/dist/sdk/knowledge.js
CHANGED
|
@@ -920,90 +920,15 @@ export const QUALIFYING_QUESTIONS = [
|
|
|
920
920
|
{ category: "Guardrails", question: "Are there compliance requirements? (regulations, policies)", whyItMatters: "May need response_validator or compliance_document_analyzer", required: false },
|
|
921
921
|
];
|
|
922
922
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
923
|
-
// Voice AI Templates
|
|
923
|
+
// Voice AI Templates - REMOVED
|
|
924
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
925
|
+
// VOICE_PERSONA_TEMPLATE has been removed.
|
|
926
|
+
// Use the API-first approach instead:
|
|
927
|
+
// 1. client.getPersonaTemplates() - source of truth from API
|
|
928
|
+
// 2. getTemplateFallback("voice") from src/sdk/generated/template-fallbacks.ts
|
|
929
|
+
//
|
|
930
|
+
// See: scripts/generate-templates.ts for how fallbacks are generated from protos.
|
|
924
931
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
925
|
-
export const VOICE_PERSONA_TEMPLATE = {
|
|
926
|
-
welcomeMessage: "Hello, thank you for calling {Company}. This is {AI Name}. How can I help you today?",
|
|
927
|
-
identityAndPurpose: `You are {AI Name}, a Voice AI assistant for {Company}.
|
|
928
|
-
|
|
929
|
-
Primary responsibility: {Main purpose}
|
|
930
|
-
|
|
931
|
-
Your responsibilities:
|
|
932
|
-
1. {Responsibility 1}
|
|
933
|
-
2. {Responsibility 2}
|
|
934
|
-
3. {Responsibility 3}
|
|
935
|
-
|
|
936
|
-
Rules:
|
|
937
|
-
- {Rule 1}
|
|
938
|
-
- {Rule 2}
|
|
939
|
-
- Always be professional and helpful
|
|
940
|
-
- Never provide information you're not certain about`,
|
|
941
|
-
takeActionInstructions: `</Case 1>
|
|
942
|
-
{Action 1 Name}
|
|
943
|
-
|
|
944
|
-
Trigger When:
|
|
945
|
-
{Condition that triggers this action}
|
|
946
|
-
|
|
947
|
-
Intent for tool call: "{Tool Intent Name}"
|
|
948
|
-
|
|
949
|
-
Required parameters:
|
|
950
|
-
{ "{param1}": "", "{param2}": "" }
|
|
951
|
-
</Case 1>
|
|
952
|
-
|
|
953
|
-
</Case 2>
|
|
954
|
-
{Action 2 Name}
|
|
955
|
-
|
|
956
|
-
Trigger When:
|
|
957
|
-
{Condition that triggers this action}
|
|
958
|
-
|
|
959
|
-
Intent for tool call: "{Tool Intent Name}"
|
|
960
|
-
|
|
961
|
-
Required parameters:
|
|
962
|
-
{ "{param1}": "" }
|
|
963
|
-
</Case 2>`,
|
|
964
|
-
hangupInstructions: `End the call when:
|
|
965
|
-
- The caller explicitly says goodbye or asks to hang up
|
|
966
|
-
- The caller confirms they have no more questions
|
|
967
|
-
- {Additional hangup conditions}
|
|
968
|
-
|
|
969
|
-
Before ending:
|
|
970
|
-
- Confirm all issues are resolved
|
|
971
|
-
- Offer any follow-up information
|
|
972
|
-
- Thank the caller`,
|
|
973
|
-
transferCallInstructions: `Transfer the call when:
|
|
974
|
-
- The caller explicitly requests a human agent
|
|
975
|
-
- The issue is beyond AI capabilities
|
|
976
|
-
- {Complex scenario requiring human}
|
|
977
|
-
|
|
978
|
-
Before transferring:
|
|
979
|
-
- Inform the caller you're transferring them
|
|
980
|
-
- Summarize the issue for the human agent`,
|
|
981
|
-
speechCharacteristics: `**Conversational Style:**
|
|
982
|
-
- Keep responses brief (2-3 sentences per turn)
|
|
983
|
-
- Use warm, professional tone
|
|
984
|
-
- Speak clearly at moderate pace
|
|
985
|
-
|
|
986
|
-
**Natural Speech:**
|
|
987
|
-
- Use brief pauses between sentences
|
|
988
|
-
- Acknowledge with 'I understand', 'Of course', 'Certainly'
|
|
989
|
-
- Avoid robotic language
|
|
990
|
-
|
|
991
|
-
**TTS Pronunciation Rules:**
|
|
992
|
-
- Spell out IDs: 'A-B-C-1-2-3'
|
|
993
|
-
- Pause between numbers: 'Your code is... 1... 2... 3... 4'
|
|
994
|
-
- {Domain-specific pronunciation rules}`,
|
|
995
|
-
systemPrompt: `Tool Calling Instructions:
|
|
996
|
-
|
|
997
|
-
1. Always collect ALL required parameters before calling a tool
|
|
998
|
-
2. Confirm parameter values with the caller before executing
|
|
999
|
-
3. Wait for tool response before calling another tool
|
|
1000
|
-
4. NEVER mention tool names to the user
|
|
1001
|
-
5. NEVER guess parameter values - always ask
|
|
1002
|
-
6. Use plain language: "Let me look that up" not "Calling the API"
|
|
1003
|
-
7. Handle delays with wait message: "One moment while I check..."
|
|
1004
|
-
8. Handle errors gracefully, offer alternatives`,
|
|
1005
|
-
waitMessage: "One moment while I look that up for you...",
|
|
1006
|
-
};
|
|
1007
932
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1008
933
|
// Common Mistakes & Debugging
|
|
1009
934
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -2592,13 +2517,18 @@ function detectUnusedCategories(nodes, workflowDef) {
|
|
|
2592
2517
|
const categorizers = nodes.filter(n => n.action_name === "chat_categorizer" ||
|
|
2593
2518
|
n.action_name === "intent_classifier");
|
|
2594
2519
|
for (const categorizer of categorizers) {
|
|
2595
|
-
// Find the enumType for this categorizer
|
|
2596
|
-
|
|
2520
|
+
// Find the enumType for this categorizer using typeArguments reference (robust)
|
|
2521
|
+
// The action's typeArguments.categories.enumType points to the correct enumType
|
|
2522
|
+
const categorizerAction = actions.find(a => a.name === categorizer.id);
|
|
2523
|
+
const typeArgs = categorizerAction?.typeArguments;
|
|
2524
|
+
const enumTypeRefName = typeArgs?.categories?.enumType?.name?.name;
|
|
2597
2525
|
const enumType = enumTypes.find(e => {
|
|
2598
2526
|
const name = e.name;
|
|
2599
2527
|
const innerName = name?.name;
|
|
2600
2528
|
const nameStr = String(innerName?.name ?? name?.name ?? "");
|
|
2601
|
-
|
|
2529
|
+
// Match by typeArguments reference (preferred) or by categorizer ID (fallback)
|
|
2530
|
+
// DO NOT use generic "enumType" fallback - that causes cross-categorizer pollution
|
|
2531
|
+
return (enumTypeRefName && nameStr === enumTypeRefName) || nameStr.includes(categorizer.id);
|
|
2602
2532
|
});
|
|
2603
2533
|
if (!enumType)
|
|
2604
2534
|
continue;
|
|
@@ -528,7 +528,25 @@ const PERSONA_TYPE_PATTERNS = [
|
|
|
528
528
|
{ pattern: /voice|call|phone/i, type: "voice" },
|
|
529
529
|
{ pattern: /document|batch|upload/i, type: "dashboard" },
|
|
530
530
|
];
|
|
531
|
+
/**
|
|
532
|
+
* @deprecated Use LLM-based intent extraction instead of regex parsing.
|
|
533
|
+
*
|
|
534
|
+
* This function uses regex patterns to parse natural language, which is an
|
|
535
|
+
* anti-pattern. The LLM (Agent) should understand user intent naturally
|
|
536
|
+
* and provide structured data directly.
|
|
537
|
+
*
|
|
538
|
+
* For greenfield workflow generation, consider using:
|
|
539
|
+
* - Intent Architect for complex requirements analysis
|
|
540
|
+
* - Direct structured input (WorkflowSpec) from the Agent
|
|
541
|
+
*
|
|
542
|
+
* This function is retained for backward compatibility but should not be
|
|
543
|
+
* used in new code paths.
|
|
544
|
+
*
|
|
545
|
+
* @see src/mcp/AGENTS.md for the LLM-driven architecture guidelines
|
|
546
|
+
*/
|
|
531
547
|
export function parseNaturalLanguage(text) {
|
|
548
|
+
console.warn("[DEPRECATED] parseNaturalLanguage() uses regex parsing which is an anti-pattern. " +
|
|
549
|
+
"Consider using LLM-based intent extraction or structured input instead.");
|
|
532
550
|
// Detect persona type (default: chat)
|
|
533
551
|
let personaType = "chat";
|
|
534
552
|
for (const { pattern, type } of PERSONA_TYPE_PATTERNS) {
|
|
@@ -1457,11 +1475,20 @@ export function intentToSpec(intent) {
|
|
|
1457
1475
|
...(intent.persona_type === "chat" && { chatConfig: { name: intent.name } }),
|
|
1458
1476
|
};
|
|
1459
1477
|
}
|
|
1478
|
+
/**
|
|
1479
|
+
* Parse input and extract workflow intent.
|
|
1480
|
+
*
|
|
1481
|
+
* Note: The "natural_language" path uses deprecated regex-based parsing.
|
|
1482
|
+
* For new code, prefer providing structured input (partial_spec or full_spec)
|
|
1483
|
+
* directly from the Agent, which understands user intent naturally.
|
|
1484
|
+
*/
|
|
1460
1485
|
export function parseInput(input) {
|
|
1461
1486
|
const inputType = detectInputType(input);
|
|
1462
1487
|
let intent;
|
|
1463
1488
|
switch (inputType) {
|
|
1464
1489
|
case "natural_language":
|
|
1490
|
+
// DEPRECATED: This path uses regex-based parsing.
|
|
1491
|
+
// Prefer structured input from the Agent instead.
|
|
1465
1492
|
intent = parseNaturalLanguage(String(input));
|
|
1466
1493
|
break;
|
|
1467
1494
|
case "partial_spec":
|