@ema.co/mcp-toolkit 2026.1.25 → 2026.1.26-4
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 +47 -18
- package/dist/mcp/handlers/persona/index.js +14 -11
- package/dist/mcp/handlers/persona/update.js +4 -2
- package/dist/mcp/handlers/persona/version.js +234 -0
- 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/deploy.js +73 -0
- package/dist/mcp/handlers/workflow/generate.js +350 -0
- package/dist/mcp/handlers/workflow/index.js +294 -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 +30 -0
- package/dist/mcp/handlers-consolidated.js +73 -2696
- package/dist/mcp/prompts.js +83 -43
- package/dist/mcp/resources.js +382 -57
- package/dist/mcp/server.js +199 -391
- package/dist/mcp/{tools-v2.js → tools.js} +20 -54
- package/dist/mcp/workflow-operations.js +2 -2
- package/dist/sdk/client-adapter.js +267 -32
- package/dist/sdk/client.js +45 -16
- package/dist/sdk/ema-client.js +183 -0
- package/dist/sdk/generated/deprecated-actions.js +171 -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 +139 -86
- package/dist/sdk/workflow-intent.js +27 -0
- package/dist/sdk/workflow-transformer.js +0 -342
- package/docs/mcp-tools-guide.md +37 -45
- package/package.json +10 -4
- package/dist/mcp/handlers/persona/analyze.js +0 -275
- package/dist/mcp/handlers/persona/compare.js +0 -32
- package/dist/mcp/tools-consolidated.js +0 -875
- 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/demos/ap-invoice-generation.md +0 -347
- package/docs/demos/ap-invoice-processing.md +0 -271
- 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/demo-kits/README.md +0 -175
- package/resources/demo-kits/finance-ap/manifest.json +0 -150
- package/resources/demo-kits/tags.json +0 -91
- 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
package/dist/sdk/ema-client.js
CHANGED
|
@@ -166,6 +166,17 @@ export class EmaClientV2 {
|
|
|
166
166
|
// Copy namespace from existing workflow
|
|
167
167
|
workflow = { ...workflow, workflowName: existingWfName };
|
|
168
168
|
}
|
|
169
|
+
else {
|
|
170
|
+
// Generate a valid namespace for personas without existing workflows
|
|
171
|
+
// Format: ["ema", "personas", "<persona_id>"] with name "workflow"
|
|
172
|
+
const generatedWfName = {
|
|
173
|
+
name: {
|
|
174
|
+
namespaces: ["ema", "personas", personaId],
|
|
175
|
+
name: "workflow",
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
workflow = { ...workflow, workflowName: generatedWfName };
|
|
179
|
+
}
|
|
169
180
|
}
|
|
170
181
|
const result = await api.updatePersona({
|
|
171
182
|
client: this.restClient,
|
|
@@ -287,6 +298,178 @@ export class EmaClientV2 {
|
|
|
287
298
|
const personas = await this.listPersonas();
|
|
288
299
|
return personas.filter(p => this.getSyncMetadata(p) !== null);
|
|
289
300
|
}
|
|
301
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
302
|
+
// File Upload/Delete - REST API (not yet in OpenAPI spec)
|
|
303
|
+
// These are hand-written until the OpenAPI spec is updated
|
|
304
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
305
|
+
/**
|
|
306
|
+
* Upload a file to an AI Employee's knowledge base.
|
|
307
|
+
* API endpoint: POST /api/v2/upload/files (multipart/form-data)
|
|
308
|
+
*/
|
|
309
|
+
async uploadDataSource(personaId, fileContent, filename, opts) {
|
|
310
|
+
const widgetName = opts?.widgetName ?? "fileUpload";
|
|
311
|
+
const tags = opts?.tags ?? widgetName;
|
|
312
|
+
const mimeType = opts?.mimeType ?? this.detectMimeType(filename);
|
|
313
|
+
// Build multipart form data manually
|
|
314
|
+
const boundary = `----EmaUploadBoundary${Date.now()}`;
|
|
315
|
+
const parts = [];
|
|
316
|
+
// persona_id field
|
|
317
|
+
parts.push(`--${boundary}\r\nContent-Disposition: form-data; name="persona_id"\r\n\r\n${personaId}`);
|
|
318
|
+
// widget_name field
|
|
319
|
+
parts.push(`--${boundary}\r\nContent-Disposition: form-data; name="widget_name"\r\n\r\n${widgetName}`);
|
|
320
|
+
// tags field (required by API, defaults to widget_name)
|
|
321
|
+
parts.push(`--${boundary}\r\nContent-Disposition: form-data; name="tags"\r\n\r\n${tags}`);
|
|
322
|
+
// Build the file part
|
|
323
|
+
const filePart = [
|
|
324
|
+
`--${boundary}`,
|
|
325
|
+
`Content-Disposition: form-data; name="file"; filename="${filename}"`,
|
|
326
|
+
`Content-Type: ${mimeType}`,
|
|
327
|
+
"",
|
|
328
|
+
"", // Content will be appended as binary
|
|
329
|
+
].join("\r\n");
|
|
330
|
+
// Combine everything
|
|
331
|
+
const headerBuffer = Buffer.from(parts.join("\r\n") + "\r\n" + filePart);
|
|
332
|
+
const fileBuffer = Buffer.isBuffer(fileContent) ? fileContent : Buffer.from(fileContent);
|
|
333
|
+
const footerBuffer = Buffer.from(`\r\n--${boundary}--\r\n`);
|
|
334
|
+
const bodyBuffer = Buffer.concat([headerBuffer, fileBuffer, footerBuffer]);
|
|
335
|
+
const controller = new AbortController();
|
|
336
|
+
const timeoutId = setTimeout(() => controller.abort(), 60_000);
|
|
337
|
+
try {
|
|
338
|
+
const resp = await fetch(`${this.env.baseUrl.replace(/\/$/, "")}/api/v2/upload/files`, {
|
|
339
|
+
method: "POST",
|
|
340
|
+
headers: {
|
|
341
|
+
Authorization: `Bearer ${this.env.bearerToken}`,
|
|
342
|
+
"Content-Type": `multipart/form-data; boundary=${boundary}`,
|
|
343
|
+
"X-Persona-Id": personaId,
|
|
344
|
+
},
|
|
345
|
+
body: bodyBuffer,
|
|
346
|
+
signal: controller.signal,
|
|
347
|
+
});
|
|
348
|
+
if (!resp.ok) {
|
|
349
|
+
const errorBody = await resp.text();
|
|
350
|
+
throw new EmaApiError({
|
|
351
|
+
statusCode: resp.status,
|
|
352
|
+
body: errorBody,
|
|
353
|
+
message: `uploadDataSource failed (${this.env.name})`,
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
const result = await resp.json();
|
|
357
|
+
return {
|
|
358
|
+
fileId: result.file_id ?? result.id ?? "",
|
|
359
|
+
status: result.status ?? "uploaded",
|
|
360
|
+
filename: filename,
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
finally {
|
|
364
|
+
clearTimeout(timeoutId);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Delete a data source file from an AI Employee's knowledge base.
|
|
369
|
+
* API endpoint: DELETE /api/v2/upload/files/{file_id}
|
|
370
|
+
*/
|
|
371
|
+
async deleteDataSource(personaId, fileId) {
|
|
372
|
+
const controller = new AbortController();
|
|
373
|
+
const timeoutId = setTimeout(() => controller.abort(), 30_000);
|
|
374
|
+
try {
|
|
375
|
+
const resp = await fetch(`${this.env.baseUrl.replace(/\/$/, "")}/api/v2/upload/files/${fileId}?persona_id=${personaId}`, {
|
|
376
|
+
method: "DELETE",
|
|
377
|
+
headers: {
|
|
378
|
+
Authorization: `Bearer ${this.env.bearerToken}`,
|
|
379
|
+
"X-Persona-Id": personaId,
|
|
380
|
+
},
|
|
381
|
+
signal: controller.signal,
|
|
382
|
+
});
|
|
383
|
+
if (!resp.ok && resp.status !== 404) {
|
|
384
|
+
const errorBody = await resp.text();
|
|
385
|
+
throw new EmaApiError({
|
|
386
|
+
statusCode: resp.status,
|
|
387
|
+
body: errorBody,
|
|
388
|
+
message: `deleteDataSource failed (${this.env.name})`,
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
return { success: true, fileId };
|
|
392
|
+
}
|
|
393
|
+
finally {
|
|
394
|
+
clearTimeout(timeoutId);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Delete a persona
|
|
399
|
+
* API endpoint: DELETE /api/personas/{persona_id}
|
|
400
|
+
*/
|
|
401
|
+
async deletePersona(personaId) {
|
|
402
|
+
const controller = new AbortController();
|
|
403
|
+
const timeoutId = setTimeout(() => controller.abort(), 30_000);
|
|
404
|
+
try {
|
|
405
|
+
const resp = await fetch(`${this.env.baseUrl.replace(/\/$/, "")}/api/personas/${personaId}`, {
|
|
406
|
+
method: "DELETE",
|
|
407
|
+
headers: {
|
|
408
|
+
Authorization: `Bearer ${this.env.bearerToken}`,
|
|
409
|
+
},
|
|
410
|
+
signal: controller.signal,
|
|
411
|
+
});
|
|
412
|
+
if (!resp.ok) {
|
|
413
|
+
const errorBody = await resp.text();
|
|
414
|
+
throw new EmaApiError({
|
|
415
|
+
statusCode: resp.status,
|
|
416
|
+
body: errorBody,
|
|
417
|
+
message: `deletePersona failed (${this.env.name})`,
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
return { success: true };
|
|
421
|
+
}
|
|
422
|
+
finally {
|
|
423
|
+
clearTimeout(timeoutId);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Wait for data replication to complete (polling helper)
|
|
428
|
+
*/
|
|
429
|
+
async waitForReplication(requestId, personaId, opts) {
|
|
430
|
+
const timeout = opts?.timeoutMs ?? 60_000;
|
|
431
|
+
const interval = opts?.pollIntervalMs ?? 2_000;
|
|
432
|
+
const start = Date.now();
|
|
433
|
+
while (Date.now() - start < timeout) {
|
|
434
|
+
const result = await this.getReplicationStatus(requestId);
|
|
435
|
+
if (result.status === 2 /* COMPLETED */) {
|
|
436
|
+
return { status: "completed" };
|
|
437
|
+
}
|
|
438
|
+
if (result.status === 3 /* FAILED */) {
|
|
439
|
+
return {
|
|
440
|
+
status: "failed",
|
|
441
|
+
failedReason: result.failedReason || "Unknown error"
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
await new Promise(resolve => setTimeout(resolve, interval));
|
|
445
|
+
}
|
|
446
|
+
return { status: "timeout" };
|
|
447
|
+
}
|
|
448
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
449
|
+
// Private Helpers
|
|
450
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
451
|
+
/** Detect MIME type from filename extension */
|
|
452
|
+
detectMimeType(filename) {
|
|
453
|
+
const ext = filename.split('.').pop()?.toLowerCase() ?? '';
|
|
454
|
+
const mimeTypes = {
|
|
455
|
+
'pdf': 'application/pdf',
|
|
456
|
+
'txt': 'text/plain',
|
|
457
|
+
'csv': 'text/csv',
|
|
458
|
+
'json': 'application/json',
|
|
459
|
+
'xml': 'application/xml',
|
|
460
|
+
'html': 'text/html',
|
|
461
|
+
'md': 'text/markdown',
|
|
462
|
+
'doc': 'application/msword',
|
|
463
|
+
'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
464
|
+
'xls': 'application/vnd.ms-excel',
|
|
465
|
+
'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
466
|
+
'png': 'image/png',
|
|
467
|
+
'jpg': 'image/jpeg',
|
|
468
|
+
'jpeg': 'image/jpeg',
|
|
469
|
+
'gif': 'image/gif',
|
|
470
|
+
};
|
|
471
|
+
return mimeTypes[ext] ?? 'application/octet-stream';
|
|
472
|
+
}
|
|
290
473
|
}
|
|
291
474
|
// Default export for convenience
|
|
292
475
|
export default EmaClientV2;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-generated deprecated actions list from ema repository.
|
|
3
|
+
*
|
|
4
|
+
* PRIMARY SOURCE: API via client.listActions() where deprecated === true
|
|
5
|
+
* This file is FALLBACK only when API is unavailable.
|
|
6
|
+
*
|
|
7
|
+
* Generated at: 2026-01-26T00:00:00.000Z
|
|
8
|
+
* Source: manual (pending first GH Actions sync)
|
|
9
|
+
*
|
|
10
|
+
* DO NOT EDIT MANUALLY - regenerate with: npm run generate:deprecated-actions
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Deprecated actions with known replacements.
|
|
14
|
+
* Use the replacement action instead.
|
|
15
|
+
*/
|
|
16
|
+
export const DEPRECATED_ACTIONS_WITH_REPLACEMENT = [
|
|
17
|
+
{
|
|
18
|
+
action: "search",
|
|
19
|
+
version: "v0",
|
|
20
|
+
replacement: "search",
|
|
21
|
+
replacementVersion: "v2",
|
|
22
|
+
migrationNotes: "v2 requires datastore_configs input (mandatory)",
|
|
23
|
+
source: "registered_actions.py",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
action: "web_search",
|
|
27
|
+
version: "v0",
|
|
28
|
+
replacement: "live_web_search or ai_web_search",
|
|
29
|
+
migrationNotes: "Split into two specialized actions",
|
|
30
|
+
source: "registered_actions.py",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
action: "call_llm",
|
|
34
|
+
version: "v0",
|
|
35
|
+
replacement: "call_llm",
|
|
36
|
+
replacementVersion: "v2",
|
|
37
|
+
migrationNotes: "v2 uses meta_respond_v2",
|
|
38
|
+
source: "registered_actions.py",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
action: "combine_external_action_and_search_results",
|
|
42
|
+
version: "v0",
|
|
43
|
+
replacement: "respond_for_external_actions",
|
|
44
|
+
migrationNotes: "Migration in progress",
|
|
45
|
+
source: "registered_actions.py",
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
action: "human_collaboration",
|
|
49
|
+
version: "v0",
|
|
50
|
+
replacement: "general_hitl",
|
|
51
|
+
migrationNotes: "More flexible HITL patterns",
|
|
52
|
+
source: "registered_actions.py",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
action: "fixed_response",
|
|
56
|
+
version: "v0",
|
|
57
|
+
replacement: "fixed_response",
|
|
58
|
+
replacementVersion: "v1",
|
|
59
|
+
source: "registered_actions.py",
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
action: "custom_agent",
|
|
63
|
+
version: "v0",
|
|
64
|
+
replacement: "custom_agent",
|
|
65
|
+
replacementVersion: "v1",
|
|
66
|
+
source: "registered_actions.py",
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
action: "json_mapper",
|
|
70
|
+
version: "v0",
|
|
71
|
+
replacement: "json_mapper",
|
|
72
|
+
replacementVersion: "v1",
|
|
73
|
+
source: "registered_actions.py",
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
action: "rule_validation_with_documents",
|
|
77
|
+
version: "v0",
|
|
78
|
+
replacement: "rule_validation_with_documents",
|
|
79
|
+
replacementVersion: "v1",
|
|
80
|
+
source: "registered_actions.py",
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
action: "text_categorizer",
|
|
84
|
+
version: "v0",
|
|
85
|
+
replacement: "text_categorizer",
|
|
86
|
+
replacementVersion: "v1",
|
|
87
|
+
source: "registered_actions.py",
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
action: "respond_with_sources",
|
|
91
|
+
version: "v0",
|
|
92
|
+
replacement: "respond_for_external_actions",
|
|
93
|
+
migrationNotes: "Better tool result handling",
|
|
94
|
+
source: "registered_actions.py",
|
|
95
|
+
},
|
|
96
|
+
];
|
|
97
|
+
/**
|
|
98
|
+
* Deprecated actions without documented replacements.
|
|
99
|
+
* These are typically internal actions or superseded functionality.
|
|
100
|
+
*/
|
|
101
|
+
export const DEPRECATED_ACTIONS_NO_REPLACEMENT = [
|
|
102
|
+
{ action: "meta_respond", version: "all", environment: "all", migrationNotes: "Internal LLM response - do not use directly", source: "system_agents" },
|
|
103
|
+
{ action: "meta_respond_v2", version: "all", environment: "all", migrationNotes: "Internal LLM response - do not use directly", source: "system_agents" },
|
|
104
|
+
{ action: "ticket_respond_with_sources", version: "all", environment: "all", source: "system_agents" },
|
|
105
|
+
{ action: "text_with_sources_translation", version: "all", environment: "all", source: "system_agents" },
|
|
106
|
+
{ action: "document_categorizer", version: "all", environment: "all", source: "system_agents" },
|
|
107
|
+
{ action: "document_metasearch", version: "all", environment: "all", source: "system_agents" },
|
|
108
|
+
{ action: "combine_search_results", version: "all", environment: "all", source: "system_agents" },
|
|
109
|
+
{ action: "combine_text_with_sources", version: "all", environment: "all", source: "system_agents" },
|
|
110
|
+
{ action: "develop_outline", version: "all", environment: "all", source: "system_agents" },
|
|
111
|
+
{ action: "generate_document_using_outline", version: "all", environment: "all", source: "system_agents" },
|
|
112
|
+
{ action: "write_document", version: "all", environment: "all", source: "system_agents" },
|
|
113
|
+
{ action: "external_action_caller_v1", version: "all", environment: "dev", migrationNotes: "Use external_action_caller v0", source: "system_agents" },
|
|
114
|
+
{ action: "ticket_thread_sink", version: "all", environment: "dev", source: "system_agents" },
|
|
115
|
+
{ action: "call_llm_v1", version: "all", environment: "all", migrationNotes: "Use call_llm v2", source: "system_agents" },
|
|
116
|
+
];
|
|
117
|
+
/**
|
|
118
|
+
* All deprecated actions combined.
|
|
119
|
+
*/
|
|
120
|
+
export const ALL_DEPRECATED_ACTIONS = [
|
|
121
|
+
...DEPRECATED_ACTIONS_WITH_REPLACEMENT,
|
|
122
|
+
...DEPRECATED_ACTIONS_NO_REPLACEMENT,
|
|
123
|
+
];
|
|
124
|
+
/**
|
|
125
|
+
* Deprecated agent types (legacy).
|
|
126
|
+
*/
|
|
127
|
+
export const DEPRECATED_AGENT_TYPES = [
|
|
128
|
+
"VISUALIZE_DATA",
|
|
129
|
+
"VISUALIZE_DATA_FOLLOWUP",
|
|
130
|
+
"PARSE_DELIMITED_FILES",
|
|
131
|
+
"GITHUB_DEMO",
|
|
132
|
+
"GITHUB_FOLLOWUP",
|
|
133
|
+
"RULES_VALIDATOR_AGENT",
|
|
134
|
+
"SUBJECT_RULE_VALIDATOR_AGENT",
|
|
135
|
+
"PRIOR_AUTHORISATION_AGENT",
|
|
136
|
+
"CHATBOT_AGENT",
|
|
137
|
+
"DEMO_PROPOSAL_MANAGEMENT_AGENT",
|
|
138
|
+
"GENERALISED_RULE_VALIDATION_AGENT",
|
|
139
|
+
];
|
|
140
|
+
/**
|
|
141
|
+
* Quick lookup map: "action/version" -> replacement info
|
|
142
|
+
*/
|
|
143
|
+
export const DEPRECATED_ACTIONS_MAP = {
|
|
144
|
+
"search/v0": { replacement: "search/v2", notes: "v2 requires datastore_configs input (mandatory)" },
|
|
145
|
+
"web_search/v0": { replacement: "live_web_search or ai_web_search", notes: "Split into two specialized actions" },
|
|
146
|
+
"call_llm/v0": { replacement: "call_llm/v2", notes: "v2 uses meta_respond_v2" },
|
|
147
|
+
"combine_external_action_and_search_results/v0": { replacement: "respond_for_external_actions", notes: "Migration in progress" },
|
|
148
|
+
"human_collaboration/v0": { replacement: "general_hitl", notes: "More flexible HITL patterns" },
|
|
149
|
+
"fixed_response/v0": { replacement: "fixed_response/v1" },
|
|
150
|
+
"custom_agent/v0": { replacement: "custom_agent/v1" },
|
|
151
|
+
"json_mapper/v0": { replacement: "json_mapper/v1" },
|
|
152
|
+
"rule_validation_with_documents/v0": { replacement: "rule_validation_with_documents/v1" },
|
|
153
|
+
"text_categorizer/v0": { replacement: "text_categorizer/v1" },
|
|
154
|
+
"respond_with_sources/v0": { replacement: "respond_for_external_actions", notes: "Better tool result handling" },
|
|
155
|
+
"meta_respond/all": { notes: "Internal LLM response - do not use directly" },
|
|
156
|
+
"meta_respond_v2/all": { notes: "Internal LLM response - do not use directly" },
|
|
157
|
+
"external_action_caller_v1/all": { notes: "Use external_action_caller v0" },
|
|
158
|
+
"call_llm_v1/all": { notes: "Use call_llm v2" },
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* Check if an action is deprecated.
|
|
162
|
+
*/
|
|
163
|
+
export function isActionDeprecated(actionName, version = "v0") {
|
|
164
|
+
return `${actionName}/${version}` in DEPRECATED_ACTIONS_MAP;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Get replacement for a deprecated action.
|
|
168
|
+
*/
|
|
169
|
+
export function getActionReplacement(actionName, version = "v0") {
|
|
170
|
+
return DEPRECATED_ACTIONS_MAP[`${actionName}/${version}`];
|
|
171
|
+
}
|
|
@@ -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
|