@ema.co/mcp-toolkit 2026.1.27 → 2026.1.28-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.

Files changed (35) hide show
  1. package/dist/mcp/handlers/data/index.js +3 -0
  2. package/dist/mcp/handlers/persona/create.js +16 -0
  3. package/dist/mcp/handlers/persona/list.js +9 -4
  4. package/dist/mcp/handlers/persona/update.js +24 -2
  5. package/dist/mcp/handlers/workflow/deploy.js +20 -2
  6. package/dist/mcp/handlers/workflow/generate.js +39 -2
  7. package/dist/mcp/handlers/workflow/index.js +8 -3
  8. package/dist/mcp/handlers/workflow/modify.js +34 -7
  9. package/dist/mcp/handlers/workflow/validate.js +85 -0
  10. package/dist/mcp/handlers/workflow/validation.js +160 -0
  11. package/dist/mcp/resources.js +286 -4
  12. package/dist/mcp/server.js +16 -3
  13. package/dist/mcp/tools.js +32 -11
  14. package/dist/sdk/client.js +36 -9
  15. package/dist/sdk/ema-client.js +32 -4
  16. package/dist/sdk/index.js +3 -1
  17. package/dist/sdk/knowledge.js +5 -5
  18. package/dist/sdk/structural-rules.js +498 -0
  19. package/dist/sdk/workflow-generator.js +2 -1
  20. package/dist/sdk/workflow-intent.js +28 -96
  21. package/dist/sdk/workflow-path-enumerator.js +278 -0
  22. package/dist/sdk/workflow-static-validator.js +291 -0
  23. package/dist/sdk/workflow-validation-types.js +7 -0
  24. package/docs/README.md +14 -0
  25. package/docs/go-validator-analysis.md +323 -0
  26. package/docs/rule-format-specification.md +346 -0
  27. package/docs/validation-contract.md +397 -0
  28. package/docs/validation-error-format.md +326 -0
  29. package/package.json +1 -1
  30. package/dist/mcp/workflow-operations.js +0 -100
  31. package/dist/sdk/workflow-fixer.js +0 -48
  32. package/docs/dashboard-operations.md +0 -281
  33. package/docs/ema-user-guide.md +0 -1201
  34. package/docs/email-patterns.md +0 -120
  35. package/docs/mcp-tools-guide.md +0 -575
@@ -1,120 +0,0 @@
1
- # Email Field Extraction Patterns
2
-
3
- ## Problem
4
-
5
- `send_email_agent.to_email` expects a text email address, but `entity_extraction` outputs `extraction_columns` (a JSON object), not individual fields.
6
-
7
- **This does NOT work:**
8
- ```
9
- entity_extraction.extraction_columns → send_email.to_email
10
- ```
11
-
12
- The types are incompatible:
13
- - `extraction_columns` = `WELL_KNOWN_TYPE_ANY` (JSON object)
14
- - `to_email` = `WELL_KNOWN_TYPE_TEXT_WITH_SOURCES` (text)
15
-
16
- ## Solution Pattern
17
-
18
- ```
19
- entity_extraction.extraction_columns
20
- → fixed_response (template: "{{email}}")
21
- → send_email.to_email
22
- ```
23
-
24
- ### Why This Works
25
-
26
- 1. `entity_extraction` extracts structured data into JSON: `{"email": "user@example.com", "name": "John"}`
27
- 2. `fixed_response` with `{{email}}` template extracts the field and outputs plain text
28
- 3. `fixed_response` output type is `WELL_KNOWN_TYPE_TEXT_WITH_SOURCES` - compatible with `to_email`
29
-
30
- ### WorkflowSpec Example
31
-
32
- ```typescript
33
- {
34
- nodes: [
35
- {
36
- id: "extract_entities_abc123",
37
- actionType: "entity_extraction_with_documents",
38
- displayName: "Extract Contact Info",
39
- // outputs: extraction_columns (JSON)
40
- },
41
- {
42
- id: "format_email_def456",
43
- actionType: "fixed_response",
44
- displayName: "Format Email Address",
45
- inputs: {
46
- query: {
47
- type: "action_output",
48
- actionName: "extract_entities_abc123",
49
- output: "extraction_columns"
50
- }
51
- },
52
- config: {
53
- response_template: "{{email}}" // Extracts email field
54
- }
55
- // outputs: response (text)
56
- },
57
- {
58
- id: "send_email_ghi789",
59
- actionType: "send_email_agent",
60
- displayName: "Send Email",
61
- inputs: {
62
- to_email: {
63
- type: "action_output",
64
- actionName: "format_email_def456",
65
- output: "response"
66
- },
67
- // ... other inputs
68
- }
69
- }
70
- ]
71
- }
72
- ```
73
-
74
- ## Alternative: JSON Mapper
75
-
76
- For complex extraction or multiple fields:
77
-
78
- ```
79
- entity_extraction.extraction_columns
80
- → json_mapper (extracts specific fields)
81
- → fixed_response (formats as text)
82
- → send_email.to_email
83
- ```
84
-
85
- **Note:** `json_mapper` is not in the WorkflowSpec compiler's supported action types. Use `applySpecToWorkflow()` for workflows containing `json_mapper`.
86
-
87
- ## Common Mistakes
88
-
89
- ### 1. Direct Wiring
90
- ```
91
- ❌ entity_extraction → send_email.to_email
92
- ```
93
- Type mismatch. JSON object cannot be used as email address.
94
-
95
- ### 2. Assuming `.email_address` Output Exists
96
- ```
97
- ❌ entity_extraction.email_address → send_email.to_email
98
- ```
99
- This output doesn't exist. `entity_extraction` only outputs `extraction_columns`.
100
-
101
- ### 3. Skipping Template Step
102
- ```
103
- ❌ entity_extraction → json_mapper → send_email.to_email
104
- ```
105
- Even `json_mapper` output may not be the right type. Always use `fixed_response` as the final step before `send_email` inputs.
106
-
107
- ## Type Reference
108
-
109
- | Action | Output | Type |
110
- |--------|--------|------|
111
- | `entity_extraction` | `extraction_columns` | `WELL_KNOWN_TYPE_ANY` (JSON) |
112
- | `json_mapper` | varies | depends on mapping |
113
- | `fixed_response` | `response` | `WELL_KNOWN_TYPE_TEXT_WITH_SOURCES` |
114
- | `call_llm` | `response` | `WELL_KNOWN_TYPE_TEXT_WITH_SOURCES` |
115
-
116
- | Input | Expected Type |
117
- |-------|---------------|
118
- | `send_email.to_email` | `WELL_KNOWN_TYPE_TEXT_WITH_SOURCES` |
119
- | `send_email.subject` | `WELL_KNOWN_TYPE_TEXT_WITH_SOURCES` |
120
- | `send_email.body` | `WELL_KNOWN_TYPE_TEXT_WITH_SOURCES` |
@@ -1,575 +0,0 @@
1
- # Ema MCP Tools Guide (Consolidated)
2
-
3
- This MCP server is intentionally designed for **LLM + agent ergonomics**:
4
-
5
- - **Self-contained guidance**: Server instructions, tool tips, and response hints are built-in
6
- - **Few tools, consistent shapes**: a small set of noun-based tools with predictable `mode` / flag patterns
7
- - **Resources-first**: use `ema://...` resources for reference data/templates, then tools for actions
8
- - **Low ambiguity**: defaults are chosen to avoid "which of 5 similar tools?" confusion
9
- - **Explicit mode**: tools with multiple operations require explicit `mode` - they clarify if omitted
10
-
11
- > **Note**: No external configuration files (like Cursor rules) are required. All guidance is embedded in the MCP server and delivered via server instructions, tool descriptions, and response tips.
12
-
13
- ## Tool names in MCP clients
14
-
15
- The server defines **base tool names** like `persona`, `template`.
16
-
17
- Some clients show a **prefixed name** (for example Cursor: `mcp_ema_persona`). Always call **the tool name your client displays**; the semantics are the same.
18
-
19
- ## The tool set (7 active tools)
20
-
21
- | Tool | Purpose | Mode Required? |
22
- |------|---------|----------------|
23
- | `env` | List environments | No (single operation) |
24
- | `persona` | AI Employee management | **YES** |
25
- | `data` | Data management + document generation | **YES** |
26
- | `action` | Actions/agents lookup | No (flag-based) |
27
- | `template` | Patterns, widgets, questions | No (flag-based) |
28
- | `reference` | Envs, actions, templates, patterns, concepts, guidance | No (flag-based) |
29
- | `sync` | Sync across environments | **YES** |
30
-
31
- ### `workflow` tool (get/deploy only)
32
-
33
- | Mode | Purpose |
34
- |------|---------|
35
- | `get` | Returns workflow_def, schema, examples for LLM |
36
- | `deploy` | Deploys LLM-generated workflow_def |
37
-
38
- **LLM does all thinking** (analyze, compare, generate). MCP only provides data and executes.
39
-
40
- ### Deprecated tools (still work, show warnings)
41
-
42
- | Tool | Status | Use Instead |
43
- |------|--------|-------------|
44
- | `knowledge` | Deprecated | `data` |
45
- | `demo` | Deprecated | `data` + `persona` |
46
-
47
- > **Tip**: For new code, use `persona`, `data`, `workflow`, `sync`.
48
-
49
- ## ⚠️ THE KEY INSIGHT: ONE CALL
50
-
51
- Creating an AI Employee should be **ONE `persona()` call**, not multiple calls.
52
-
53
- ```typescript
54
- persona(
55
- input="Voice AI SDR: qualifies leads, identifies use-case, sends follow-up email",
56
- type="voice",
57
- name="Sales SDR",
58
- preview=false
59
- )
60
- ```
61
-
62
- **MCP handles internally:** template selection, config generation, widget formatting, API orchestration.
63
-
64
- ## Start-here flows (LLM-friendly)
65
-
66
- ### Create a new AI Employee (greenfield)
67
-
68
- 1. **Get qualifying questions from MCP**: `template(questions=true)`
69
- 2. **Ask user those questions**
70
- 3. **Create in ONE call**:
71
- ```typescript
72
- persona(
73
- input="<everything from user answers>",
74
- name="My AI Employee",
75
- type="voice",
76
- preview=false
77
- )
78
- ```
79
-
80
- ### Complex Workflows (email, HITL, multi-intent)
81
-
82
- For complex workflows, MCP returns `status: "needs_llm_generation"` with a prompt you send to an LLM:
83
-
84
- ```typescript
85
- // Step 1: Request creation
86
- result = persona(
87
- input="SDR that qualifies leads and sends follow-up emails",
88
- type="voice",
89
- name="Sales SDR",
90
- preview=true
91
- )
92
-
93
- // If result.status === "needs_llm_generation":
94
- // Step 2: Send result.llm_prompt to an LLM (Claude, GPT-4, etc.)
95
- // Step 3: Deploy the LLM's workflow response
96
- persona(
97
- workflow_def=llm_response_json,
98
- name="Sales SDR",
99
- type="voice",
100
- preview=false
101
- )
102
- ```
103
-
104
- **Simple workflows** (basic Q&A, search + respond) deploy directly without this extra step.
105
-
106
- ### Modify an existing AI Employee (brownfield)
107
-
108
- ```typescript
109
- // Optional: Understand what exists first
110
- persona(mode="get", id="abc-123")
111
-
112
- // Modify config in ONE call
113
- persona(mode="update", id="abc-123", config={widgets: [{name: "conversationSettings", conversationSettings: {...}}]})
114
- ```
115
-
116
- ### Get workflow data (for LLM to analyze/modify)
117
-
118
- ```typescript
119
- workflow(mode="get", persona_id="abc-123") // Returns workflow_def, schema, examples
120
- ```
121
-
122
- The LLM then analyzes/modifies the workflow and deploys:
123
-
124
- ```typescript
125
- workflow(mode="deploy", persona_id="abc-123", workflow_def={...}) // Deploy LLM's result
126
- ```
127
-
128
- ### Upload / manage knowledge base documents
129
-
130
- 1. Upload: `data(persona_id="...", mode="upload", file="/path/to/file.pdf")`
131
- 2. Enable embedding: `data(persona_id="...", mode="embedding", enabled=true)`
132
- 3. Verify: `data(persona_id="...", mode="list")`
133
-
134
- ### Clone and sanitize personas for demo
135
-
136
- **Recommended: Use action composition for multi-step operations**
137
-
138
- ```typescript
139
- // Clone with data copy and sanitization (recommended)
140
- persona(
141
- method="create",
142
- from="source-id",
143
- name="Demo Clone",
144
- actions=[
145
- {tool:"data", args:{method:"copy", from:"$source"}},
146
- {tool:"data", args:{method:"sanitize", examples:["Acme Corp", "john@example.com"]}},
147
- {tool:"snapshot", args:{message:"Demo ready"}},
148
- ]
149
- )
150
-
151
- // Or use built-in aliases for common patterns
152
- persona(method="create", from="source-id", name="Demo Clone", actions=["copy-and-sanitize"])
153
- persona(method="create", from="source-id", name="Demo Clone", actions=["standard-demo-setup"])
154
- ```
155
-
156
- **Available aliases:**
157
- - `"copy-data"` - Copy data from source
158
- - `"copy-and-sanitize"` - Copy then sanitize
159
- - `"standard-demo-setup"` - Copy, sanitize, snapshot
160
-
161
- **Context variables:** `$source` (from param), `$target` (created persona ID), `$env` (environment)
162
-
163
- **Legacy syntax (still works):**
164
-
165
- ```typescript
166
- // Clone a persona with all data (files + dashboard rows for dashboard personas)
167
- // Note: Dashboard cloning auto-enables the persona (required for adding rows)
168
- persona(mode="clone", from="source-id", name="Demo Clone", include_data=true)
169
-
170
- // Clone with data sanitization (sanitizes both config and dashboard row data)
171
- persona(mode="clone", from="source-id", name="Demo Clone", include_data=true, sanitize=true)
172
-
173
- // Provide custom examples of sensitive data to sanitize
174
- persona(mode="clone", from="source-id", name="Demo Clone", include_data=true, sanitize=true, sanitize_examples=["Acme Corp", "john@example.com"])
175
- ```
176
-
177
- **Sanitize an existing persona (TWO STEP PROCESS):**
178
-
179
- ```typescript
180
- // Step 1: Preview (identifies PII, returns items_needing_review count)
181
- persona(method="sanitize", id="abc")
182
-
183
- // Step 2: Provide known PII values and apply (only works when items_needing_review=0)
184
- persona(method="sanitize", id="abc", examples=["Acme Corp", "john@example.com"], apply=true)
185
- ```
186
-
187
- **Sanitization Notes:**
188
- - **Two-step process**: First call returns preview with `items_needing_review` count. Changes only apply when `items_needing_review=0` AND `preview=false`
189
- - **Auto-detects**: emails, phones, SSNs, credit cards (by issuer prefix), API keys, JWTs
190
- - **NOT detected by default**: UUIDs (typically system IDs like `template_id`, `persona_id`)
191
- - `sanitize_examples`: for company names, person names, vendor names, custom identifiers - providing these reduces `items_needing_review`
192
- - **Transforms**: pseudonymize (names → fake names), mask (phones → `***-***-1234`), redact (credentials)
193
- - **Allowlist approach**: Only content fields sanitized (description, prompts, fixed_response), system fields preserved
194
- - Dashboard row sanitization: applies to row data during clone
195
-
196
- ### Dashboard data operations (advanced)
197
-
198
- For fine-grained control over dashboard data:
199
-
200
- ```typescript
201
- // List rows from a dashboard
202
- knowledge(persona_id="abc", mode="dashboard_rows")
203
-
204
- // Clone dashboard rows separately (usually not needed - use persona clone_data instead)
205
- knowledge(persona_id="target", mode="dashboard_clone", source_persona_id="source")
206
- ```
207
-
208
- ### Sync between environments
209
-
210
- - Run (single): `sync(id="My Bot", source="demo", target="dev", dry_run=true|false)`
211
- - Run (all tagged): `sync(target="dev", scope="all", dry_run=true|false)`
212
- - Status: `sync(mode="status", id="My Bot", env="dev")`
213
-
214
- ### Version / snapshot AI Employees
215
-
216
- ```typescript
217
- // Before a risky change - create a snapshot
218
- persona(mode="version_create", id="My Bot", message="Before adding HITL")
219
-
220
- // Make changes...
221
- persona(mode="update", id="abc", config={...})
222
-
223
- // If something breaks - restore
224
- persona(mode="version_list", id="My Bot")
225
- persona(mode="version_restore", id="My Bot", version="v3")
226
- ```
227
-
228
- ## Tool reference (high-signal)
229
-
230
- ### `persona` (explicit mode required)
231
-
232
- **Mode is required.** If omitted, the tool will ask for clarification.
233
-
234
- **List/Get:**
235
- ```typescript
236
- persona(mode="list")
237
- persona(mode="list", query="support", status="active")
238
- persona(mode="get", id="abc")
239
- persona(mode="get", id="abc", include_workflow=true)
240
- ```
241
-
242
- **Create:**
243
- ```typescript
244
- persona(mode="create", input="<what it does>", type="voice", name="My Bot", preview=false)
245
- persona(mode="create", from="Voice AI Starter", name="My Bot", input="...", preview=false)
246
- ```
247
-
248
- **Update config:**
249
- ```typescript
250
- persona(mode="update", id="abc", config={widgets: [{...}]})
251
- ```
252
-
253
- **Clone:**
254
- ```typescript
255
- persona(mode="clone", from="source-id", name="My Copy", include_data=true)
256
- ```
257
-
258
- **Sanitize (two-step process):**
259
- ```typescript
260
- persona(id="abc", sanitize=true) // Step 1: Preview - identify PII
261
- persona(id="abc", sanitize=true, sanitize_examples=["Acme"], preview=false) // Step 2: Apply
262
- ```
263
-
264
- **Intent (qualification for complex requests):**
265
- ```typescript
266
- // GREENFIELD: New persona creation
267
- persona(mode="intent", input="Voice AI SDR that qualifies leads", type="voice")
268
-
269
- // BROWNFIELD: Complex modification to existing persona
270
- persona(mode="intent", input="Send emails with discussion items and key points", id="abc-123")
271
-
272
- // Iterative - provide answers to qualify further
273
- persona(mode="intent", input="...", previous_answers={gate1_q1: "inbound"}, iteration=2)
274
- ```
275
-
276
- Intent mode applies to **both greenfield AND brownfield** scenarios. Use it when:
277
- - Creating complex new personas (multi-intent, HITL, email, taxonomy)
278
- - Modifying existing personas with complex changes that may have ripple effects
279
- - Any request where qualification questions help clarify WHY/WHAT/CONSTRAINTS
280
-
281
- Returns:
282
- - `status: "ready"` → `intent_spec` ready for WorkflowSpec transformation
283
- - `status: "needs_qualification"` → `questions` to answer before proceeding
284
- - `status: "needs_llm"` → `llm_prompt` to send to LLM for IntentSpec generation
285
-
286
- For brownfield, use `workflow(mode="get")` to fetch current state, then use intent to qualify the change.
287
-
288
- **Templates:**
289
- ```typescript
290
- persona(mode="templates")
291
- ```
292
-
293
- **Version management:**
294
- ```typescript
295
- persona(mode="version_create", id="abc", message="Before update")
296
- persona(mode="version_list", id="abc")
297
- persona(mode="version_restore", id="abc", version="v2")
298
- persona(mode="version_policy", id="abc", auto_on_deploy=true)
299
- ```
300
-
301
- ### `template`
302
-
303
- **Primary use - Get qualifying questions:**
304
- ```typescript
305
- template(questions=true) // All questions
306
- template(questions=true, category="Voice") // Voice-specific
307
- ```
308
-
309
- **Reference (understand options):**
310
- ```typescript
311
- template(patterns=true)
312
- template(pattern="intent-routing")
313
- template(widgets="voice")
314
- ```
315
-
316
- ### `action`
317
-
318
- ```typescript
319
- action(id="chat_categorizer", include_docs=true) // Get specific
320
- action(all=true) // List all
321
- action(suggest="IT helpdesk with ServiceNow") // Get recommendations
322
- ```
323
-
324
- ### `reference` (v2 expanded)
325
-
326
- **Environments:**
327
- ```typescript
328
- reference(type="envs")
329
- ```
330
-
331
- **Actions (replaces `action` tool):**
332
- ```typescript
333
- reference(type="actions") // List all
334
- reference(type="actions", id="send_email") // Get specific
335
- reference(type="actions", suggest="IT helpdesk") // Recommendations
336
- ```
337
-
338
- **Templates & Patterns:**
339
- ```typescript
340
- reference(type="templates") // Persona templates (dynamic, tenant-specific)
341
- reference(type="patterns") // Workflow patterns
342
- reference(type="patterns", pattern="intent-routing")
343
- reference(type="widgets", persona_type="voice")
344
- ```
345
-
346
- > **Note:** Templates are tenant-specific. Always use `reference(type="templates")` to discover available templates rather than hardcoding template IDs.
347
-
348
- **Concepts & Guidance:**
349
- ```typescript
350
- reference(concept="HITL")
351
- reference(guidance="categorizer-routing")
352
- reference(questions=true) // Qualifying questions
353
- ```
354
-
355
- **Debugging:**
356
- ```typescript
357
- reference(mistakes=true)
358
- reference(checklist=true)
359
- reference(execution=true)
360
- ```
361
-
362
- ### `data` (explicit mode required)
363
-
364
- **Mode is required.** If omitted, the tool will ask for clarification.
365
-
366
- **List files:**
367
- ```typescript
368
- data(persona_id="abc", mode="list")
369
- data(persona_id="abc", mode="list", limit=50)
370
- ```
371
-
372
- **Get specific file:**
373
- ```typescript
374
- data(persona_id="abc", mode="get", file_id="file-123")
375
- ```
376
-
377
- **Upload/Delete:**
378
- ```typescript
379
- data(persona_id="abc", mode="upload", file="/path/to/file.pdf")
380
- data(persona_id="abc", mode="delete", file_id="file-123")
381
- ```
382
-
383
- **Upload to specific widget (Document Generation personas):**
384
- ```typescript
385
- // Document Proposal Manager widget names (verified from template):
386
- data(persona_id="abc", mode="upload", file="/path/to/company.pdf", widget_name="upload") // Content Repository
387
- data(persona_id="abc", mode="upload", file="/path/to/service-line.pdf", widget_name="upload1") // Service Line Documents
388
- data(persona_id="abc", mode="upload", file="/path/to/style-guide.pdf", widget_name="upload2") // Style Guide
389
- ```
390
-
391
- > **Important for Document Generation (Proposal Writer) personas:** Files must be uploaded to the correct widget to appear in the right repository in the UI. Without `widget_name`, files go to the default `fileUpload` widget which may not be visible in the Configuration tab.
392
- >
393
- > **Document Proposal Manager widgets:** `upload` (Content Repository), `upload1` (Service Line Documents), `upload2` (Style Guide)
394
- >
395
- > **For other templates:** Call `persona(id="abc", include_workflow=true)` and inspect `proto_config.widgets[].name` to find the exact widget names.
396
-
397
- **Generate content (via Document Generation API):**
398
- ```typescript
399
- // From a template
400
- data(persona_id="abc", mode="generate", from="customer", count=5)
401
- data(persona_id="abc", mode="generate", from="demo-sales-sdr")
402
-
403
- // From natural language
404
- data(persona_id="abc", mode="generate", input="Generate 5 B2B customer profiles")
405
-
406
- // List available templates
407
- data(mode="templates")
408
- data(mode="templates", template="customer") // Get template details
409
- ```
410
-
411
- **Available templates:** `customer`, `product`, `faq`, `employee`, `demo-sales-sdr`, `demo-support`, `demo-hr`, `countries`, `industries`, `currencies`
412
-
413
- **Sanitize persona data:**
414
- ```typescript
415
- data(persona_id="abc", mode="sanitize")
416
- data(persona_id="abc", mode="sanitize", include_workflow=true)
417
- ```
418
-
419
- **File Stats:**
420
- ```typescript
421
- data(persona_id="abc", mode="stats") // Get file counts
422
- data(persona_id="abc", mode="stats", widget_name="kb") // Filter by widget
423
- // Returns: { total: 50, pending: 5, success: 40, failed: 5 }
424
- ```
425
-
426
- **Replicate (copy by reference - fast, no file transfer):**
427
- ```typescript
428
- // Copy knowledge base from source to target (references S3 objects, no re-upload)
429
- data(persona_id="target-id", mode="replicate", from="source-id")
430
-
431
- // With custom widget mappings
432
- data(persona_id="target-id", mode="replicate", from="source-id",
433
- widget_mappings=[{source_widget: "docs", target_widget: "documents"}])
434
-
435
- // Async (don't wait for completion)
436
- data(persona_id="target-id", mode="replicate", from="source-id", wait=false)
437
- ```
438
-
439
- > **Note:** `replicate` is much faster than copying files. It copies S3 references instead of downloading and re-uploading. Use `mode="copy"` if you need to sanitize data during transfer.
440
-
441
- **Embedding:**
442
- ```typescript
443
- data(persona_id="abc", mode="embedding") // Get status
444
- data(persona_id="abc", mode="embedding", enabled=true) // Toggle
445
- ```
446
-
447
- ## Resources (read-first)
448
-
449
- Start with:
450
-
451
- - `ema://index/all-resources` (index)
452
- - `ema://docs/readme` (toolkit overview)
453
- - `ema://catalog/agents-summary` (quick agent overview)
454
- - `ema://catalog/templates` (persona templates - dynamic)
455
- - `ema://rules/anti-patterns` (what NOT to do)
456
-
457
- ## Workflow Generation (LLM Does the Work)
458
-
459
- **MCP provides data and schema. LLM generates workflow_def.**
460
-
461
- ```typescript
462
- // 1. Get current workflow + schema (includes deprecation_warnings!)
463
- result = workflow(mode="get", persona_id="abc")
464
- // Returns: workflow_def, generation_schema, example_workflow, requirements, deprecation_warnings
465
-
466
- // 2. LLM analyzes and generates new workflow_def
467
- // (LLM uses schema and examples to build valid workflow)
468
- // ⚠️ FIX any deprecated actions FIRST - check deprecation_warnings!
469
-
470
- // 3. Deploy LLM's result (preview first!)
471
- workflow(mode="deploy", persona_id="abc", workflow_def={...}, preview=true)
472
- workflow(mode="deploy", persona_id="abc", workflow_def={...})
473
- ```
474
-
475
- ### ⚠️ CRITICAL: Check Deprecated Actions First
476
-
477
- **BEFORE generating any workflow:**
478
-
479
- 1. Check `deprecation_warnings` in `workflow(mode="get")` response
480
- 2. Use `reference(type="actions")` to verify current versions
481
- 3. **NEVER** copy workflow patterns from existing personas (they may use deprecated actions!)
482
-
483
- **Correct workflow pattern:**
484
- ```
485
- chat_trigger → search/v2 → respond_for_external_actions → WORKFLOW_OUTPUT
486
- ```
487
-
488
- **Deprecated (DO NOT USE):**
489
- ```
490
- search/v0 → Use search/v2
491
- respond_with_sources → Use respond_for_external_actions
492
- call_llm/v0 → Use call_llm/v2
493
- ```
494
-
495
- **Common issues to check when generating:**
496
- - Missing `WORKFLOW_OUTPUT` in results
497
- - Missing Fallback category in categorizers
498
- - Orphan nodes not connected to output
499
- - Type mismatches between connected nodes
500
- - **Using deprecated actions** (check deprecation_warnings!)
501
-
502
- ## HITL (Human-in-the-Loop) Policy
503
-
504
- **HITL is opt-in, not forced by default.**
505
-
506
- | Scenario | Default | How to Add HITL |
507
- |----------|---------|-----------------|
508
- | Send email | ❌ No HITL | `persona(mode="update", id="...", input="add approval before sending")` |
509
- | External API | ❌ No HITL | Request explicitly in input |
510
- | Create records | ❌ No HITL | Request explicitly in input |
511
-
512
- ## Auto Builder Prompt Length Limits
513
-
514
- **⚠️ CRITICAL:** Auto Builder has strict prompt length limits (~2500 chars).
515
-
516
- ### Good Prompt Format
517
- ```text
518
- Voice AI for [use case]. Supports [capabilities].
519
-
520
- Core Capabilities:
521
- 1. Intent A - Brief description
522
- 2. Intent B - Brief description
523
- 3. Fallback - Handle unclear requests
524
-
525
- Rules:
526
- • Rule 1
527
- • Rule 2
528
- ```
529
-
530
- ### Bad Prompt Format (Times Out)
531
- - Narrative descriptions with multiple paragraphs
532
- - Example conversations embedded in prompt
533
- - Prompts > 2500 characters
534
-
535
- ## Deprecated Tools
536
-
537
- ### `workflow` → use `persona`
538
-
539
- ```typescript
540
- // OLD (deprecated)
541
- workflow(input="...", type="voice", name="Bot", preview=false)
542
-
543
- // NEW
544
- persona(input="...", type="voice", name="Bot", preview=false)
545
- ```
546
-
547
- ### `knowledge` → use `data`
548
-
549
- ```typescript
550
- // OLD (deprecated)
551
- knowledge(persona_id="abc", mode="list")
552
- knowledge(persona_id="abc", mode="upload", file="...")
553
- knowledge(persona_id="abc", mode="status")
554
- knowledge(persona_id="abc", mode="toggle", enabled=true)
555
-
556
- // NEW
557
- data(persona_id="abc", mode="list")
558
- data(persona_id="abc", mode="upload", file="...")
559
- data(persona_id="abc", mode="embedding")
560
- data(persona_id="abc", mode="embedding", enabled=true)
561
- ```
562
-
563
- ### `demo` → use `data` + `persona`
564
-
565
- ```typescript
566
- // OLD (deprecated)
567
- demo(mode="generate", entity="customer", data={...})
568
- demo(mode="scenarios")
569
- demo(mode="template", entity="customer")
570
-
571
- // NEW
572
- data(persona_id="abc", mode="generate", from="customer", data={...})
573
- data(mode="templates")
574
- data(mode="templates", template="customer")
575
- ```