@ema.co/mcp-toolkit 2026.1.25 → 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/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 -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
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generation Templates for data(method="generate")
|
|
3
|
+
*
|
|
4
|
+
* Built-in templates for document/data generation via the Document Generation API.
|
|
5
|
+
* Used by data(method="generate", from="...").
|
|
6
|
+
*/
|
|
7
|
+
export const GENERATION_TEMPLATES = {
|
|
8
|
+
// Reference data
|
|
9
|
+
"countries": {
|
|
10
|
+
description: "ISO 3166-1 countries with code and name",
|
|
11
|
+
category: "reference",
|
|
12
|
+
prompt: "Generate a JSON array of {count} ISO 3166-1 countries with fields: code (2-letter), name. Format: {format}",
|
|
13
|
+
},
|
|
14
|
+
"industries": {
|
|
15
|
+
description: "NAICS industry classifications",
|
|
16
|
+
category: "reference",
|
|
17
|
+
prompt: "Generate a JSON array of {count} NAICS industry classifications with fields: code, name, description. Format: {format}",
|
|
18
|
+
},
|
|
19
|
+
"currencies": {
|
|
20
|
+
description: "ISO 4217 currencies",
|
|
21
|
+
category: "reference",
|
|
22
|
+
prompt: "Generate a JSON array of {count} ISO 4217 currencies with fields: code (3-letter), name, symbol. Format: {format}",
|
|
23
|
+
},
|
|
24
|
+
// Demo kits
|
|
25
|
+
"demo-sales-sdr": {
|
|
26
|
+
description: "Sales SDR demo kit with prospects, products, and Q&A",
|
|
27
|
+
category: "demo",
|
|
28
|
+
prompt: `Generate a comprehensive sales demo kit in {format} format containing:
|
|
29
|
+
1. {count} realistic B2B prospect profiles (company name, contact, role, pain points, budget)
|
|
30
|
+
2. 3-5 product entries with features and pricing
|
|
31
|
+
3. 10 common sales objections with responses
|
|
32
|
+
4. Sample discovery call script`,
|
|
33
|
+
},
|
|
34
|
+
"demo-support": {
|
|
35
|
+
description: "Customer support demo kit with customers, FAQs, and tickets",
|
|
36
|
+
category: "demo",
|
|
37
|
+
prompt: `Generate a customer support demo kit in {format} format containing:
|
|
38
|
+
1. {count} customer profiles (name, company, subscription tier, history)
|
|
39
|
+
2. 10 frequently asked questions with detailed answers
|
|
40
|
+
3. 5 sample support tickets with resolutions
|
|
41
|
+
4. Escalation guidelines`,
|
|
42
|
+
},
|
|
43
|
+
"demo-hr": {
|
|
44
|
+
description: "HR assistant demo kit with employees, policies, and benefits",
|
|
45
|
+
category: "demo",
|
|
46
|
+
prompt: `Generate an HR demo kit in {format} format containing:
|
|
47
|
+
1. {count} employee profiles (name, department, role, start date)
|
|
48
|
+
2. 5 company policies (PTO, remote work, expenses)
|
|
49
|
+
3. 3 benefits descriptions (health, 401k, equity)
|
|
50
|
+
4. Onboarding checklist`,
|
|
51
|
+
},
|
|
52
|
+
// Entity templates
|
|
53
|
+
"customer": {
|
|
54
|
+
description: "B2B customer profile",
|
|
55
|
+
category: "entity",
|
|
56
|
+
prompt: `Generate {count} realistic B2B customer profiles in {format} format with fields:
|
|
57
|
+
- company_name, industry, size (employees), annual_revenue
|
|
58
|
+
- primary_contact (name, title, email, phone)
|
|
59
|
+
- pain_points (array of 2-3 business challenges)
|
|
60
|
+
- current_solutions (what they use today)
|
|
61
|
+
- budget_range, decision_timeline`,
|
|
62
|
+
},
|
|
63
|
+
"product": {
|
|
64
|
+
description: "Product catalog entry with pricing",
|
|
65
|
+
category: "entity",
|
|
66
|
+
prompt: `Generate {count} product catalog entries in {format} format with fields:
|
|
67
|
+
- name, sku, category
|
|
68
|
+
- description (2-3 sentences)
|
|
69
|
+
- features (array of 3-5 key features)
|
|
70
|
+
- pricing (base_price, currency, billing_period)
|
|
71
|
+
- availability (in_stock, lead_time)`,
|
|
72
|
+
},
|
|
73
|
+
"faq": {
|
|
74
|
+
description: "FAQ entries",
|
|
75
|
+
category: "entity",
|
|
76
|
+
prompt: `Generate {count} FAQ entries in {format} format with fields:
|
|
77
|
+
- question (clear, specific question)
|
|
78
|
+
- answer (comprehensive answer, 2-4 sentences)
|
|
79
|
+
- category (e.g., billing, technical, getting-started)
|
|
80
|
+
- related_questions (array of 2-3 related question titles)`,
|
|
81
|
+
},
|
|
82
|
+
"employee": {
|
|
83
|
+
description: "Employee profile for HR systems",
|
|
84
|
+
category: "entity",
|
|
85
|
+
prompt: `Generate {count} employee profiles in {format} format with fields:
|
|
86
|
+
- name, email, employee_id
|
|
87
|
+
- department, title, manager
|
|
88
|
+
- start_date, location (office or remote)
|
|
89
|
+
- skills (array), certifications (array)`,
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Get a generation template by name
|
|
94
|
+
*/
|
|
95
|
+
export function getGenerationTemplate(name) {
|
|
96
|
+
return GENERATION_TEMPLATES[name];
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* List all available generation templates
|
|
100
|
+
*/
|
|
101
|
+
export function listGenerationTemplates() {
|
|
102
|
+
return Object.entries(GENERATION_TEMPLATES).map(([name, t]) => ({
|
|
103
|
+
name,
|
|
104
|
+
description: t.description,
|
|
105
|
+
category: t.category,
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deprecation Tracking - Single Source of Truth
|
|
3
|
+
*
|
|
4
|
+
* Centralized deprecation warnings for parameter names.
|
|
5
|
+
* Used by all handlers to ensure consistent messaging.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Deprecated parameter mappings
|
|
9
|
+
*
|
|
10
|
+
* Key: old parameter name
|
|
11
|
+
* Value: { newName, removeVersion }
|
|
12
|
+
*/
|
|
13
|
+
export const DEPRECATED_PARAMS = {
|
|
14
|
+
identifier: { newName: "id", removeVersion: "2.0.0" },
|
|
15
|
+
clone_from: { newName: "from", removeVersion: "2.0.0" },
|
|
16
|
+
template_id: { newName: "from", removeVersion: "2.0.0" },
|
|
17
|
+
clone_data: { newName: "include_data", removeVersion: "2.0.0" },
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Check args for deprecated params and return warnings.
|
|
21
|
+
*/
|
|
22
|
+
export function checkDeprecatedParams(args) {
|
|
23
|
+
const warnings = [];
|
|
24
|
+
for (const [oldName, { newName, removeVersion }] of Object.entries(DEPRECATED_PARAMS)) {
|
|
25
|
+
if (args[oldName] !== undefined) {
|
|
26
|
+
warnings.push(`'${oldName}' is deprecated, use '${newName}' instead (will be removed in v${removeVersion})`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return warnings;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Add deprecation warnings to a result object.
|
|
33
|
+
*/
|
|
34
|
+
export function addDeprecationWarnings(result, warnings) {
|
|
35
|
+
if (warnings.length > 0) {
|
|
36
|
+
return { ...result, _deprecation_warnings: warnings };
|
|
37
|
+
}
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Log and return deprecation warnings for an args object.
|
|
42
|
+
* Call this at the start of handlers that accept deprecated params.
|
|
43
|
+
*/
|
|
44
|
+
export function handleDeprecatedParams(args, context) {
|
|
45
|
+
const warnings = checkDeprecatedParams(args);
|
|
46
|
+
for (const warning of warnings) {
|
|
47
|
+
console.warn(`[${context}] Deprecation: ${warning}`);
|
|
48
|
+
}
|
|
49
|
+
return warnings;
|
|
50
|
+
}
|
|
@@ -13,6 +13,7 @@ export async function handleEnv(_args, getEnvironments, toolkit) {
|
|
|
13
13
|
const criticalRules = GUIDANCE_RULES
|
|
14
14
|
.filter(r => r.level === "critical")
|
|
15
15
|
.map(r => `• ${r.title}: ${r.do}`);
|
|
16
|
+
const defaultEnv = envs.find(e => e.isDefault)?.name || envs[0]?.name || "demo";
|
|
16
17
|
return {
|
|
17
18
|
environments: envs.map(e => ({
|
|
18
19
|
name: e.name,
|
|
@@ -23,10 +24,10 @@ export async function handleEnv(_args, getEnvironments, toolkit) {
|
|
|
23
24
|
// Onboarding guidance for new sessions
|
|
24
25
|
getting_started: {
|
|
25
26
|
workflow: [
|
|
26
|
-
"1. List personas: persona()",
|
|
27
|
-
"2. Get details: persona(id
|
|
28
|
-
"3. Analyze before modifying: persona(id
|
|
29
|
-
"4. Preview before deploying: update
|
|
27
|
+
"1. List personas: persona(method=\"list\")",
|
|
28
|
+
"2. Get details: persona(method=\"get\", id=\"...\")",
|
|
29
|
+
"3. Analyze before modifying: persona(method=\"get\", id=\"...\", analyze=true)",
|
|
30
|
+
"4. Preview before deploying: persona(method=\"update\", id=\"...\", preview=true, ...)",
|
|
30
31
|
],
|
|
31
32
|
critical_rules: criticalRules,
|
|
32
33
|
resources: [
|
|
@@ -40,5 +41,8 @@ export async function handleEnv(_args, getEnvironments, toolkit) {
|
|
|
40
41
|
"workflow_review - Analyze workflow health",
|
|
41
42
|
],
|
|
42
43
|
},
|
|
44
|
+
// Consistent guidance format
|
|
45
|
+
_tip: `Start by listing personas: persona(method="list", env="${defaultEnv}")`,
|
|
46
|
+
_next_step: `persona(method="list", env="${defaultEnv}")`,
|
|
43
47
|
};
|
|
44
48
|
}
|
|
@@ -1,247 +1,54 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Knowledge Handler
|
|
2
|
+
* Knowledge Handler - DEPRECATED
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* This handler is deprecated. Use the 'data' tool instead.
|
|
5
|
+
* All calls are routed to handleData with a deprecation warning.
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
7
|
+
import { handleData } from "../data/index.js";
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* Mode mapping from knowledge tool to data tool
|
|
10
|
+
*/
|
|
11
|
+
const MODE_MAPPING = {
|
|
12
|
+
list: "list",
|
|
13
|
+
aggregates: "stats",
|
|
14
|
+
upload: "upload",
|
|
15
|
+
delete: "delete",
|
|
16
|
+
status: "embedding",
|
|
17
|
+
toggle: "embedding",
|
|
18
|
+
attach: "attach",
|
|
19
|
+
dashboard_rows: "dashboard_rows",
|
|
20
|
+
dashboard_clone: "copy",
|
|
21
|
+
dashboard_generate: "generate",
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Handle knowledge tool requests
|
|
10
25
|
*
|
|
11
|
-
* @deprecated Use data() tool instead
|
|
26
|
+
* @deprecated Use data() tool instead. This handler routes to handleData.
|
|
12
27
|
*/
|
|
13
|
-
export async function handleKnowledge(args, client, readFile
|
|
14
|
-
|
|
28
|
+
export async function handleKnowledge(args, client, readFile) {
|
|
29
|
+
console.warn("[knowledge] DEPRECATED: Use data() tool instead");
|
|
15
30
|
const mode = args.mode || "list";
|
|
16
|
-
const
|
|
17
|
-
//
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
migration: {
|
|
22
|
-
"knowledge(mode='list')": "data(mode='list')",
|
|
23
|
-
"knowledge(mode='upload')": "data(mode='upload')",
|
|
24
|
-
"knowledge(mode='delete')": "data(mode='delete')",
|
|
25
|
-
"knowledge(mode='status')": "data(mode='embedding')",
|
|
26
|
-
"knowledge(mode='toggle')": "data(mode='embedding', enabled=...)",
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
} : {};
|
|
30
|
-
// Helper to wrap result with deprecation warning
|
|
31
|
-
const withWarning = (result) => {
|
|
32
|
-
if (typeof result === 'object' && result !== null) {
|
|
33
|
-
return { ...deprecationWarning, ...result };
|
|
34
|
-
}
|
|
35
|
-
return result;
|
|
31
|
+
const mappedMode = MODE_MAPPING[mode] || mode;
|
|
32
|
+
// Route to data handler
|
|
33
|
+
const dataArgs = {
|
|
34
|
+
...args,
|
|
35
|
+
mode: mappedMode,
|
|
36
36
|
};
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const widgetName = args.widget_name;
|
|
53
|
-
const agg = await client.getDataSourceAggregates(personaId, widgetName);
|
|
54
|
-
return withWarning({
|
|
55
|
-
persona_id: personaId,
|
|
56
|
-
widget_name: agg.widgetName,
|
|
57
|
-
total_files: agg.total,
|
|
58
|
-
by_status: {
|
|
59
|
-
pending: agg.pending,
|
|
60
|
-
success: agg.success,
|
|
61
|
-
failed: agg.failed,
|
|
62
|
-
},
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
case "upload": {
|
|
66
|
-
const filePath = args.file;
|
|
67
|
-
if (!filePath) {
|
|
68
|
-
return withWarning({ error: "file path required for upload" });
|
|
69
|
-
}
|
|
70
|
-
const content = await readFile(filePath);
|
|
71
|
-
const filename = filePath.split("/").pop() || "file";
|
|
72
|
-
const result = await client.uploadDataSource(personaId, content, filename, { tags: args.tags });
|
|
73
|
-
return withWarning({ success: true, ...result });
|
|
74
|
-
}
|
|
75
|
-
case "delete": {
|
|
76
|
-
const fileId = args.file_id;
|
|
77
|
-
if (!fileId) {
|
|
78
|
-
return withWarning({ error: "file_id required for delete" });
|
|
79
|
-
}
|
|
80
|
-
const result = await client.deleteDataSource(personaId, fileId);
|
|
81
|
-
return withWarning(result);
|
|
82
|
-
}
|
|
83
|
-
case "status": {
|
|
84
|
-
const persona = await client.getPersonaById(personaId);
|
|
85
|
-
if (!persona) {
|
|
86
|
-
return withWarning({ error: `Persona not found: ${personaId}` });
|
|
87
|
-
}
|
|
88
|
-
return withWarning({
|
|
89
|
-
persona_id: personaId,
|
|
90
|
-
embedding_enabled: persona.embedding_enabled,
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
case "toggle": {
|
|
94
|
-
if (args.enabled === undefined) {
|
|
95
|
-
return withWarning({ error: "enabled flag required for toggle" });
|
|
96
|
-
}
|
|
97
|
-
const persona = await client.getPersonaById(personaId);
|
|
98
|
-
if (!persona) {
|
|
99
|
-
return withWarning({ error: `Persona not found: ${personaId}` });
|
|
100
|
-
}
|
|
101
|
-
// IMPORTANT: The Ema API requires workflow to be sent along with proto_config
|
|
102
|
-
// for proto_config changes to persist. This matches what the UI does.
|
|
103
|
-
await client.updateAiEmployee({
|
|
104
|
-
persona_id: personaId,
|
|
105
|
-
embedding_enabled: args.enabled,
|
|
106
|
-
proto_config: persona.proto_config,
|
|
107
|
-
workflow: persona.workflow_def,
|
|
108
|
-
});
|
|
109
|
-
return withWarning({
|
|
110
|
-
success: true,
|
|
111
|
-
persona_id: personaId,
|
|
112
|
-
embedding_enabled: args.enabled,
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
case "attach": {
|
|
116
|
-
// Attach a data source widget to a workflow node's datastore_configs input
|
|
117
|
-
const nodeName = args.node_name;
|
|
118
|
-
const widgetName = args.widget_name || "fileUpload";
|
|
119
|
-
if (!nodeName) {
|
|
120
|
-
return withWarning({ error: "node_name required (e.g., 'knowledge_search_1')" });
|
|
121
|
-
}
|
|
122
|
-
const persona = await client.getPersonaById(personaId);
|
|
123
|
-
if (!persona) {
|
|
124
|
-
return withWarning({ error: `Persona not found: ${personaId}` });
|
|
125
|
-
}
|
|
126
|
-
const workflowDef = persona.workflow_def;
|
|
127
|
-
if (!workflowDef) {
|
|
128
|
-
return withWarning({ error: "Persona has no workflow_def" });
|
|
129
|
-
}
|
|
130
|
-
const actions = workflowDef.actions;
|
|
131
|
-
if (!actions) {
|
|
132
|
-
return withWarning({ error: "Workflow has no actions" });
|
|
133
|
-
}
|
|
134
|
-
// Find the target node
|
|
135
|
-
const nodeIndex = actions.findIndex(a => a.name === nodeName);
|
|
136
|
-
if (nodeIndex < 0) {
|
|
137
|
-
const availableNodes = actions.map(a => a.name).filter(Boolean);
|
|
138
|
-
return withWarning({
|
|
139
|
-
error: `Node '${nodeName}' not found`,
|
|
140
|
-
available_nodes: availableNodes,
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
const node = actions[nodeIndex];
|
|
144
|
-
const inputs = (node.inputs || {});
|
|
145
|
-
// Build the datastore_configs binding with multiBinding
|
|
146
|
-
const datastoreBinding = {
|
|
147
|
-
multiBinding: {
|
|
148
|
-
elements: [
|
|
149
|
-
{
|
|
150
|
-
widgetConfig: { widgetName },
|
|
151
|
-
autoDetectedBinding: false,
|
|
152
|
-
},
|
|
153
|
-
],
|
|
154
|
-
},
|
|
155
|
-
autoDetectedBinding: false,
|
|
156
|
-
};
|
|
157
|
-
// Update the node's inputs
|
|
158
|
-
inputs.datastore_configs = datastoreBinding;
|
|
159
|
-
node.inputs = inputs;
|
|
160
|
-
actions[nodeIndex] = node;
|
|
161
|
-
workflowDef.actions = actions;
|
|
162
|
-
// Update the persona with the modified workflow
|
|
163
|
-
await client.updateAiEmployee({
|
|
164
|
-
persona_id: personaId,
|
|
165
|
-
proto_config: persona.proto_config,
|
|
166
|
-
workflow: workflowDef,
|
|
167
|
-
});
|
|
168
|
-
return withWarning({
|
|
169
|
-
success: true,
|
|
170
|
-
persona_id: personaId,
|
|
171
|
-
node_name: nodeName,
|
|
172
|
-
widget_name: widgetName,
|
|
173
|
-
message: `Data source '${widgetName}' attached to node '${nodeName}'`,
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
case "dashboard_rows": {
|
|
177
|
-
// Get rows from a dashboard persona
|
|
178
|
-
const persona = await client.getPersonaById(personaId);
|
|
179
|
-
if (!persona) {
|
|
180
|
-
return withWarning({ error: `Persona not found: ${personaId}` });
|
|
181
|
-
}
|
|
182
|
-
const dashboardId = persona.workflow_dashboard_id;
|
|
183
|
-
if (!dashboardId) {
|
|
184
|
-
return withWarning({
|
|
185
|
-
error: "This persona has no dashboard. Use dashboard_rows only for Dashboard-type AI Employees.",
|
|
186
|
-
hint: "Check that the persona has trigger_type=DASHBOARD",
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
const limit = args.limit ?? 100;
|
|
190
|
-
const result = await client.getDashboardRows(dashboardId, personaId, { limit });
|
|
191
|
-
// Return schema and rows in a structured format
|
|
192
|
-
return withWarning({
|
|
193
|
-
persona_id: personaId,
|
|
194
|
-
dashboard_id: dashboardId,
|
|
195
|
-
dashboard_name: result.dashboardName,
|
|
196
|
-
total_rows: result.totalCount,
|
|
197
|
-
schema: {
|
|
198
|
-
input_columns: result.schema.columns.filter(c => c.isInput),
|
|
199
|
-
output_columns: result.schema.columns.filter(c => !c.isInput),
|
|
200
|
-
},
|
|
201
|
-
rows: result.rows.map(row => ({
|
|
202
|
-
id: row.id,
|
|
203
|
-
state: row.state,
|
|
204
|
-
created_at: row.dashboardRowMetadata.createdAt,
|
|
205
|
-
input_values: row.columnValues
|
|
206
|
-
.filter(cv => result.schema.columns.find(c => c.columnId === cv.columnId)?.isInput)
|
|
207
|
-
.map(cv => ({
|
|
208
|
-
column: result.schema.columns.find(c => c.columnId === cv.columnId)?.name ?? cv.columnId,
|
|
209
|
-
value: cv.value.stringValue ?? cv.value.documentCellValue?.documentValues?.[0]?.name ?? cv.value.arrayValue?.arrayValues?.[0]?.stringValue ?? "(complex)",
|
|
210
|
-
})),
|
|
211
|
-
})),
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
case "dashboard_clone": {
|
|
215
|
-
// Delegated to extracted handler
|
|
216
|
-
if (hasExtractedDataHandler("dashboard_clone")) {
|
|
217
|
-
const handler = getDataModeHandler("dashboard_clone");
|
|
218
|
-
// Map args to extracted handler format
|
|
219
|
-
const cloneArgs = {
|
|
220
|
-
id: personaId,
|
|
221
|
-
clone_dashboard_from: args.source_persona_id,
|
|
222
|
-
clone_limit: args.limit ?? 100,
|
|
223
|
-
sanitize: args.sanitize,
|
|
224
|
-
sanitize_examples: args.sanitize_examples,
|
|
225
|
-
};
|
|
226
|
-
return withWarning(await handler(cloneArgs, client));
|
|
227
|
-
}
|
|
228
|
-
return withWarning({ error: "dashboard_clone handler not found" });
|
|
229
|
-
}
|
|
230
|
-
case "dashboard_generate": {
|
|
231
|
-
// Delegated to extracted handler
|
|
232
|
-
if (hasExtractedDataHandler("dashboard_generate")) {
|
|
233
|
-
const handler = getDataModeHandler("dashboard_generate");
|
|
234
|
-
// Map args to extracted handler format
|
|
235
|
-
const generateArgs = {
|
|
236
|
-
id: personaId,
|
|
237
|
-
dashboard_generate: args.count ?? args.dashboard_generate ?? 5,
|
|
238
|
-
dashboard_template: args.template ?? args.dashboard_template,
|
|
239
|
-
};
|
|
240
|
-
return withWarning(await handler(generateArgs, client));
|
|
241
|
-
}
|
|
242
|
-
return withWarning({ error: "dashboard_generate handler not found" });
|
|
243
|
-
}
|
|
244
|
-
default:
|
|
245
|
-
return withWarning({ error: `Unknown mode: ${mode}` });
|
|
37
|
+
// Map old param names to new
|
|
38
|
+
if (args.file)
|
|
39
|
+
dataArgs.file_path = args.file;
|
|
40
|
+
if (args.source_persona_id)
|
|
41
|
+
dataArgs.from = args.source_persona_id;
|
|
42
|
+
const result = await handleData(dataArgs, client, readFile);
|
|
43
|
+
// Add deprecation warning to result
|
|
44
|
+
if (typeof result === "object" && result !== null) {
|
|
45
|
+
return {
|
|
46
|
+
_deprecation: {
|
|
47
|
+
message: "The 'knowledge' tool is deprecated. Use 'data' tool instead.",
|
|
48
|
+
migration: `data(method="${mappedMode}", ...)`,
|
|
49
|
+
},
|
|
50
|
+
...result,
|
|
51
|
+
};
|
|
246
52
|
}
|
|
53
|
+
return result;
|
|
247
54
|
}
|
|
@@ -145,21 +145,15 @@ export async function handleCreate(args, client, getTemplateId) {
|
|
|
145
145
|
let workflowError;
|
|
146
146
|
if (workflowDef && newPersonaId) {
|
|
147
147
|
try {
|
|
148
|
-
// Get the newly created persona to get its proto_config
|
|
148
|
+
// Get the newly created persona to get its proto_config
|
|
149
149
|
const newPersona = await client.getPersonaById(newPersonaId);
|
|
150
150
|
const protoConfig = (newPersona?.proto_config ?? {});
|
|
151
|
-
|
|
152
|
-
//
|
|
153
|
-
//
|
|
154
|
-
const existingWfName = existingWorkflow?.workflowName;
|
|
155
|
-
const workflowForDeploy = JSON.parse(JSON.stringify(workflowDef));
|
|
156
|
-
if (existingWfName?.name) {
|
|
157
|
-
// Set/overwrite the workflowName to match the existing one
|
|
158
|
-
workflowForDeploy.workflowName = existingWfName;
|
|
159
|
-
}
|
|
151
|
+
// NOTE: The SDK's updateAiEmployee() handles workflowName namespace automatically.
|
|
152
|
+
// It will copy from existing workflow if present, or generate a valid namespace if not.
|
|
153
|
+
// No need to manually manipulate workflowName here.
|
|
160
154
|
await client.updateAiEmployee({
|
|
161
155
|
persona_id: newPersonaId,
|
|
162
|
-
workflow:
|
|
156
|
+
workflow: workflowDef,
|
|
163
157
|
proto_config: protoConfig, // Required: API needs proto_config alongside workflow
|
|
164
158
|
});
|
|
165
159
|
workflowApplied = true;
|
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
* - analyze: Analyze persona for issues
|
|
18
18
|
* - intent: Direct Intent Architect invocation for qualification
|
|
19
19
|
*
|
|
20
|
-
* Version management modes
|
|
20
|
+
* Version management modes extracted to version.ts:
|
|
21
|
+
* - snapshot/version_create, history/version_list, version_get
|
|
22
|
+
* - version_compare, restore/version_restore, version_policy
|
|
21
23
|
*/
|
|
22
24
|
// Import mode handlers
|
|
23
25
|
import { handleGet } from "./get.js";
|
|
@@ -71,3 +73,5 @@ export { handleDelete } from "./delete.js";
|
|
|
71
73
|
export { handleCreate } from "./create.js";
|
|
72
74
|
export { handleAnalyze } from "./analyze.js";
|
|
73
75
|
export { handleIntent } from "./intent.js";
|
|
76
|
+
// Version management
|
|
77
|
+
export { handleVersion, isVersionMode } from "./version.js";
|