@ema.co/mcp-toolkit 1.5.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of @ema.co/mcp-toolkit might be problematic. Click here for more details.
- package/dist/mcp/handlers-consolidated.js +400 -14
- package/dist/mcp/prompts.js +80 -123
- package/dist/mcp/server.js +134 -209
- package/dist/mcp/tools-consolidated.js +212 -150
- package/dist/sdk/action-registry.js +128 -0
- package/dist/sdk/client.js +58 -90
- package/dist/sdk/demo-generator.js +978 -0
- package/dist/sdk/generated/api-types.js +11 -0
- package/dist/sdk/index.js +15 -1
- package/dist/sdk/knowledge.js +38 -8
- package/dist/sdk/quality-gates.js +386 -0
- package/dist/sdk/structural-rules.js +290 -0
- package/dist/sdk/workflow-generator.js +187 -39
- package/dist/sdk/workflow-intent.js +246 -24
- package/dist/sdk/workflow-optimizer.js +665 -0
- package/dist/sdk/workflow-tracer.js +648 -0
- package/dist/sdk/workflow-transformer.js +10 -0
- package/dist/sdk/workflow-validator.js +391 -0
- package/docs/.temp/datasource-attach.har +198369 -0
- package/docs/.temp/grpcweb.gar +1 -0
- package/docs/local-generation.md +508 -0
- package/docs/mcp-flow-diagram.md +135 -0
- package/docs/mcp-tools-guide.md +163 -197
- package/docs/openapi.json +8000 -0
- package/docs/release-process.md +153 -0
- package/docs/test-persona-creation.md +196 -0
- package/docs/tool-consolidation-proposal.md +166 -378
- package/package.json +3 -1
- package/resources/templates/demo-scenarios/README.md +63 -0
package/dist/mcp/server.js
CHANGED
|
@@ -2613,13 +2613,6 @@ const toolHandlers = {
|
|
|
2613
2613
|
preserveExistingNodes: false, // Replace with incoming structure
|
|
2614
2614
|
forceReplace: false, // Don't force if there are conflicts
|
|
2615
2615
|
});
|
|
2616
|
-
// #region agent log
|
|
2617
|
-
// Log brownfield merge result
|
|
2618
|
-
try {
|
|
2619
|
-
fetch('http://127.0.0.1:7245/ingest/c9b6768a-494d-4365-bd46-bf6c43dc1e22', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ location: 'src/mcp/server.ts:deploy_workflow:brownfieldMerge', message: 'Brownfield merge result', data: { success: mergeResult.success, description: mergeResult.description, diff: { nodesAdded: mergeResult.diff.nodesAdded, nodesRemoved: mergeResult.diff.nodesRemoved, nodesModified: mergeResult.diff.nodesModified, enumsAdded: mergeResult.diff.enumsAdded, enumsModified: mergeResult.diff.enumsModified, hasHitlNodes: mergeResult.diff.hasHitlNodes, conflictCount: mergeResult.diff.conflicts.length }, warnings: mergeResult.warnings, errors: mergeResult.errors, requiresAutobuilder: mergeResult.requiresAutobuilder }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'brownfield-merge', hypothesisId: 'H12' }) }).catch(() => { });
|
|
2620
|
-
}
|
|
2621
|
-
catch { }
|
|
2622
|
-
// #endregion agent log
|
|
2623
2616
|
if (!mergeResult.success) {
|
|
2624
2617
|
// Merge failed due to conflicts - return the errors
|
|
2625
2618
|
return {
|
|
@@ -2639,12 +2632,6 @@ const toolHandlers = {
|
|
|
2639
2632
|
// Validate the merged workflow structure
|
|
2640
2633
|
const mergeValidation = validateMergedWorkflow(workflowDef);
|
|
2641
2634
|
if (!mergeValidation.valid) {
|
|
2642
|
-
// #region agent log
|
|
2643
|
-
try {
|
|
2644
|
-
fetch('http://127.0.0.1:7245/ingest/c9b6768a-494d-4365-bd46-bf6c43dc1e22', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ location: 'src/mcp/server.ts:deploy_workflow:mergeValidationFailed', message: 'Merged workflow validation failed', data: { issues: mergeValidation.issues }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'brownfield-merge', hypothesisId: 'H12' }) }).catch(() => { });
|
|
2645
|
-
}
|
|
2646
|
-
catch { }
|
|
2647
|
-
// #endregion agent log
|
|
2648
2635
|
return {
|
|
2649
2636
|
environment: client["env"].name,
|
|
2650
2637
|
success: false,
|
|
@@ -2660,12 +2647,6 @@ const toolHandlers = {
|
|
|
2660
2647
|
// If HITL nodes are involved, force Autobuilder deployment
|
|
2661
2648
|
// (Direct API doesn't support HITL workflow changes)
|
|
2662
2649
|
if (mergeResult.requiresAutobuilder) {
|
|
2663
|
-
// #region agent log
|
|
2664
|
-
try {
|
|
2665
|
-
fetch('http://127.0.0.1:7245/ingest/c9b6768a-494d-4365-bd46-bf6c43dc1e22', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ location: 'src/mcp/server.ts:deploy_workflow:hitlRequiresAutobuilder', message: 'HITL workflow requires Autobuilder', data: { hasHitlNodes: mergeResult.diff.hasHitlNodes, nodesAdded: mergeResult.diff.nodesAdded }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'brownfield-merge', hypothesisId: 'H11' }) }).catch(() => { });
|
|
2666
|
-
}
|
|
2667
|
-
catch { }
|
|
2668
|
-
// #endregion agent log
|
|
2669
2650
|
deploymentMethod = "autobuilder";
|
|
2670
2651
|
}
|
|
2671
2652
|
}
|
|
@@ -2824,14 +2805,6 @@ const toolHandlers = {
|
|
|
2824
2805
|
actionOutputField.output = "hitl_status";
|
|
2825
2806
|
inlineRhsField.enumValue = correctedEnumVal;
|
|
2826
2807
|
hitlFixCount++;
|
|
2827
|
-
// #region agent log
|
|
2828
|
-
try {
|
|
2829
|
-
if (process.env.EMA_MCP_DEBUG_LOGS === "1") {
|
|
2830
|
-
fetch('http://127.0.0.1:7245/ingest/c9b6768a-494d-4365-bd46-bf6c43dc1e22', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ location: 'src/mcp/server.ts:deploy_workflow:hitlAutoFix', message: 'Auto-fixed malformed HITL runIf', data: { nodeName: String(action.name), originalOutput: outputStr, correctedOutput: 'hitl_status', correctedEnumValue: correctedEnumVal }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'hitl-fix', hypothesisId: 'H1' }) }).catch(() => { });
|
|
2831
|
-
}
|
|
2832
|
-
}
|
|
2833
|
-
catch { }
|
|
2834
|
-
// #endregion agent log
|
|
2835
2808
|
}
|
|
2836
2809
|
}
|
|
2837
2810
|
}
|
|
@@ -2842,57 +2815,6 @@ const toolHandlers = {
|
|
|
2842
2815
|
proto_config: mergedProtoConfig,
|
|
2843
2816
|
workflow: workflowDef,
|
|
2844
2817
|
};
|
|
2845
|
-
// #region agent log
|
|
2846
|
-
// H1/H2: confirm what we're attempting to deploy (structure only).
|
|
2847
|
-
try {
|
|
2848
|
-
if (process.env.EMA_MCP_DEBUG_LOGS !== "1") {
|
|
2849
|
-
// disabled
|
|
2850
|
-
}
|
|
2851
|
-
else {
|
|
2852
|
-
const wf = workflowDef ?? {};
|
|
2853
|
-
const actions = wf.actions ?? [];
|
|
2854
|
-
const actionNames = actions.map((a) => String(a.name ?? "")).filter(Boolean);
|
|
2855
|
-
const actionTypeNames = actions
|
|
2856
|
-
.map((a) => {
|
|
2857
|
-
const an = a.action;
|
|
2858
|
-
return String(an?.name?.name ?? "");
|
|
2859
|
-
})
|
|
2860
|
-
.filter(Boolean);
|
|
2861
|
-
const hasHitl = actionTypeNames.some((t) => t.toLowerCase().includes("hitl")) || actionNames.some((n) => n.toLowerCase().includes("hitl"));
|
|
2862
|
-
const hasTriggerWhen = actions.some((a) => {
|
|
2863
|
-
const inputs = a.inputs;
|
|
2864
|
-
return !!inputs && Object.prototype.hasOwnProperty.call(inputs, "trigger_when");
|
|
2865
|
-
});
|
|
2866
|
-
const runIfCount = actions.reduce((acc, a) => acc + (a.runIf ? 1 : 0), 0);
|
|
2867
|
-
const wfName = wf.workflowName ?? {};
|
|
2868
|
-
fetch('http://127.0.0.1:7245/ingest/c9b6768a-494d-4365-bd46-bf6c43dc1e22', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ location: 'src/mcp/server.ts:deploy_workflow:preDeploy', message: 'Deploy workflow request summary', data: { env: client["env"].name, personaId, validateFirst, autoFix, actionCount: actions.length, runIfCount, hasHitl, hasTriggerWhen, workflowName: wfName }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'pre-fix', hypothesisId: 'H1' }) }).catch(() => { });
|
|
2869
|
-
// H1: Detect malformed HITL runIf patterns
|
|
2870
|
-
const malformedHitlPatterns = [];
|
|
2871
|
-
for (const action of actions) {
|
|
2872
|
-
const runIf = action.runIf;
|
|
2873
|
-
if (!runIf)
|
|
2874
|
-
continue;
|
|
2875
|
-
const lhs = runIf.lhs;
|
|
2876
|
-
if (!lhs?.actionOutput)
|
|
2877
|
-
continue;
|
|
2878
|
-
const actionOutput = lhs.actionOutput;
|
|
2879
|
-
const output = String(actionOutput.output ?? "");
|
|
2880
|
-
// Malformed pattern: output contains both field name AND enum value like "hitl_status_HITL Success"
|
|
2881
|
-
if (output.includes("hitl_status_HITL") || output.includes("hitl_status HITL")) {
|
|
2882
|
-
malformedHitlPatterns.push({
|
|
2883
|
-
nodeName: String(action.name),
|
|
2884
|
-
output,
|
|
2885
|
-
issue: `Should be output="hitl_status" with enumValue="${output.replace(/hitl_status[_\s]?/i, "")}"`
|
|
2886
|
-
});
|
|
2887
|
-
}
|
|
2888
|
-
}
|
|
2889
|
-
if (malformedHitlPatterns.length > 0) {
|
|
2890
|
-
fetch('http://127.0.0.1:7245/ingest/c9b6768a-494d-4365-bd46-bf6c43dc1e22', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ location: 'src/mcp/server.ts:deploy_workflow:malformedHitl', message: 'DETECTED malformed HITL runIf patterns', data: { env: client["env"].name, personaId, malformedCount: malformedHitlPatterns.length, patterns: malformedHitlPatterns }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'debug-hitl', hypothesisId: 'H1' }) }).catch(() => { });
|
|
2891
|
-
}
|
|
2892
|
-
}
|
|
2893
|
-
}
|
|
2894
|
-
catch { }
|
|
2895
|
-
// #endregion agent log
|
|
2896
2818
|
// Deployment attempt with automatic fallback
|
|
2897
2819
|
let deployedVia = "direct_api";
|
|
2898
2820
|
let autobuilderResult;
|
|
@@ -2902,50 +2824,6 @@ const toolHandlers = {
|
|
|
2902
2824
|
}
|
|
2903
2825
|
catch (err) {
|
|
2904
2826
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
2905
|
-
// #region agent log
|
|
2906
|
-
// H1/H2: capture top-level failure classification (do not log secrets).
|
|
2907
|
-
try {
|
|
2908
|
-
if (process.env.EMA_MCP_DEBUG_LOGS !== "1") {
|
|
2909
|
-
// disabled
|
|
2910
|
-
}
|
|
2911
|
-
else {
|
|
2912
|
-
fetch('http://127.0.0.1:7245/ingest/c9b6768a-494d-4365-bd46-bf6c43dc1e22', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ location: 'src/mcp/server.ts:deploy_workflow:directApiError', message: 'Direct deploy failed', data: { env: client["env"].name, personaId, errorMessage }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'pre-fix', hypothesisId: 'H2' }) }).catch(() => { });
|
|
2913
|
-
}
|
|
2914
|
-
}
|
|
2915
|
-
catch { }
|
|
2916
|
-
// #endregion agent log
|
|
2917
|
-
// H5: When update_persona returns a generic 500, attempt CheckWorkflow to extract structured validation errors.
|
|
2918
|
-
// This is best-effort and only runs when debug logs are enabled to minimize extra traffic.
|
|
2919
|
-
try {
|
|
2920
|
-
if (process.env.EMA_MCP_DEBUG_LOGS === "1" && workflowDef && errorMessage.toLowerCase().includes("internal server error")) {
|
|
2921
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2922
|
-
const check = await client.checkWorkflow(workflowDef);
|
|
2923
|
-
const checkJson = JSON.stringify(check);
|
|
2924
|
-
const snippet = checkJson.length > 3000 ? `${checkJson.slice(0, 3000)}…(truncated)` : checkJson;
|
|
2925
|
-
fetch('http://127.0.0.1:7245/ingest/c9b6768a-494d-4365-bd46-bf6c43dc1e22', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ location: 'src/mcp/server.ts:deploy_workflow:checkWorkflow', message: 'CheckWorkflow output (post-500)', data: { env: client["env"].name, personaId, checkSnippet: snippet }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'pre-fix', hypothesisId: 'H5' }) }).catch(() => { });
|
|
2926
|
-
}
|
|
2927
|
-
}
|
|
2928
|
-
catch (checkErr) {
|
|
2929
|
-
try {
|
|
2930
|
-
if (process.env.EMA_MCP_DEBUG_LOGS === "1") {
|
|
2931
|
-
const m = checkErr instanceof Error ? checkErr.message : String(checkErr);
|
|
2932
|
-
fetch('http://127.0.0.1:7245/ingest/c9b6768a-494d-4365-bd46-bf6c43dc1e22', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ location: 'src/mcp/server.ts:deploy_workflow:checkWorkflowError', message: 'CheckWorkflow failed (post-500)', data: { env: client["env"].name, personaId, error: m }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'pre-fix', hypothesisId: 'H5' }) }).catch(() => { });
|
|
2933
|
-
}
|
|
2934
|
-
}
|
|
2935
|
-
catch { }
|
|
2936
|
-
}
|
|
2937
|
-
// #region agent log
|
|
2938
|
-
// H2: Log fallback decision path for 500 errors
|
|
2939
|
-
try {
|
|
2940
|
-
if (process.env.EMA_MCP_DEBUG_LOGS === "1") {
|
|
2941
|
-
const isNoExistingWorkflow = errorMessage.includes("Cannot set persona workflow without existing workflow");
|
|
2942
|
-
const isNameMismatch = errorMessage.includes("Workflow name does not match");
|
|
2943
|
-
const is500Error = errorMessage.toLowerCase().includes("internal server error") || errorMessage.includes("500");
|
|
2944
|
-
fetch('http://127.0.0.1:7245/ingest/c9b6768a-494d-4365-bd46-bf6c43dc1e22', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ location: 'src/mcp/server.ts:deploy_workflow:fallbackDecision', message: 'Evaluating fallback path', data: { env: client["env"].name, personaId, errorMessage, isNoExistingWorkflow, isNameMismatch, is500Error, hasWorkflowDef: !!workflowDef, willFallbackToAutobuilder: isNoExistingWorkflow || is500Error }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'debug-fallback', hypothesisId: 'H2' }) }).catch(() => { });
|
|
2945
|
-
}
|
|
2946
|
-
}
|
|
2947
|
-
catch { }
|
|
2948
|
-
// #endregion agent log
|
|
2949
2827
|
// If direct API fails due to "no existing workflow", try Auto Builder
|
|
2950
2828
|
if (errorMessage.includes("Cannot set persona workflow without existing workflow") && workflowDef) {
|
|
2951
2829
|
deploymentMethod = "autobuilder";
|
|
@@ -2957,15 +2835,7 @@ const toolHandlers = {
|
|
|
2957
2835
|
`(Technical: ${errorMessage})`);
|
|
2958
2836
|
}
|
|
2959
2837
|
else if ((errorMessage.toLowerCase().includes("internal server error") || errorMessage.includes("500")) && workflowDef) {
|
|
2960
|
-
//
|
|
2961
|
-
// H2: 500 error - attempt Autobuilder fallback instead of throwing
|
|
2962
|
-
try {
|
|
2963
|
-
if (process.env.EMA_MCP_DEBUG_LOGS === "1") {
|
|
2964
|
-
fetch('http://127.0.0.1:7245/ingest/c9b6768a-494d-4365-bd46-bf6c43dc1e22', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ location: 'src/mcp/server.ts:deploy_workflow:500Fallback', message: '500 error - attempting Autobuilder fallback', data: { env: client["env"].name, personaId, errorMessage }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'debug-fallback', hypothesisId: 'H2' }) }).catch(() => { });
|
|
2965
|
-
}
|
|
2966
|
-
}
|
|
2967
|
-
catch { }
|
|
2968
|
-
// #endregion agent log
|
|
2838
|
+
// 500 error - attempt Autobuilder fallback
|
|
2969
2839
|
deploymentMethod = "autobuilder";
|
|
2970
2840
|
}
|
|
2971
2841
|
else {
|
|
@@ -4843,7 +4713,12 @@ const toolHandlers = {
|
|
|
4843
4713
|
// Consolidated workflow handler (replaces legacy inline handler)
|
|
4844
4714
|
workflow: async (args) => {
|
|
4845
4715
|
const client = createClient(args.env);
|
|
4846
|
-
|
|
4716
|
+
const DEFAULT_TEMPLATES = {
|
|
4717
|
+
voice: "00000000-0000-0000-0000-00000000001e", // Voice AI template
|
|
4718
|
+
chat: "00000000-0000-0000-0000-000000000004", // Chat AI template
|
|
4719
|
+
dashboard: "00000000-0000-0000-0000-000000000002", // Dashboard AI template
|
|
4720
|
+
};
|
|
4721
|
+
return handleWorkflow(args, client, (type) => DEFAULT_TEMPLATES[type]);
|
|
4847
4722
|
},
|
|
4848
4723
|
action: async (args) => {
|
|
4849
4724
|
const client = createClient(args.env);
|
|
@@ -4901,14 +4776,16 @@ toolHandlers.workflow = async (args) => {
|
|
|
4901
4776
|
const rawMode = normalizedArgs.mode ? String(normalizedArgs.mode) : undefined;
|
|
4902
4777
|
const mode = rawMode === "improve" ? "optimize" : rawMode;
|
|
4903
4778
|
// Default mode selection:
|
|
4904
|
-
// - persona_id +
|
|
4779
|
+
// - persona_id + workflow_def → deploy (direct deployment, no input needed)
|
|
4780
|
+
// - persona_id + input → modify (BROWNFIELD: generate new workflow from input)
|
|
4905
4781
|
// - persona_id only or workflow_def → analyze (inspect)
|
|
4906
4782
|
// - input only → generate (GREENFIELD: create from scratch)
|
|
4907
4783
|
// - Otherwise → generate (and prompt for missing info)
|
|
4908
4784
|
const effectiveMode = mode ??
|
|
4909
|
-
(personaId &&
|
|
4910
|
-
|
|
4911
|
-
"
|
|
4785
|
+
(personaId && workflowDef ? "deploy" : // Direct deployment (no input required)
|
|
4786
|
+
personaId && inputProvided ? "modify" : // BROWNFIELD: existing persona + new requirements
|
|
4787
|
+
workflowDef || personaId ? "analyze" : // Inspect existing
|
|
4788
|
+
"generate"); // GREENFIELD: new workflow
|
|
4912
4789
|
switch (effectiveMode) {
|
|
4913
4790
|
case "generate": {
|
|
4914
4791
|
const result = await legacyWorkflowTool({ ...normalizedArgs, mode: "generate" });
|
|
@@ -5137,11 +5014,131 @@ toolHandlers.sync = async (args) => {
|
|
|
5137
5014
|
include_status: normalizedArgs.include_status,
|
|
5138
5015
|
});
|
|
5139
5016
|
};
|
|
5140
|
-
// Consolidated demo tool: consolidate | generate | validate | template
|
|
5017
|
+
// Consolidated demo tool: kit | validate_kit | scenarios | consolidate | generate | validate | template
|
|
5141
5018
|
toolHandlers.demo = async (args) => {
|
|
5142
5019
|
const normalizedArgs = { ...(args ?? {}) };
|
|
5143
5020
|
const mode = normalizedArgs.mode ? String(normalizedArgs.mode) : "template";
|
|
5144
5021
|
switch (mode) {
|
|
5022
|
+
case "kit": {
|
|
5023
|
+
// Generate complete demo kit for a persona
|
|
5024
|
+
const personaId = String(normalizedArgs.persona_id ?? "");
|
|
5025
|
+
const scenarioId = String(normalizedArgs.scenario ?? "sales-sdr");
|
|
5026
|
+
if (!personaId) {
|
|
5027
|
+
throw new Error('demo(mode="kit") requires: persona_id');
|
|
5028
|
+
}
|
|
5029
|
+
// Import demo generator
|
|
5030
|
+
const { generateDemoKit, DEMO_SCENARIOS, generateDemoScriptMarkdown, validateDemoKit } = await import("../sdk/demo-generator.js");
|
|
5031
|
+
// Get scenario
|
|
5032
|
+
const scenario = DEMO_SCENARIOS[scenarioId];
|
|
5033
|
+
if (!scenario) {
|
|
5034
|
+
throw new Error(`Unknown scenario: ${scenarioId}. Available: ${Object.keys(DEMO_SCENARIOS).join(", ")}`);
|
|
5035
|
+
}
|
|
5036
|
+
// Get persona and workflow
|
|
5037
|
+
const client = await createClient(normalizedArgs.env);
|
|
5038
|
+
const persona = await client.getPersonaById(personaId);
|
|
5039
|
+
if (!persona) {
|
|
5040
|
+
throw new Error(`Persona not found: ${personaId}`);
|
|
5041
|
+
}
|
|
5042
|
+
const workflowDef = persona.workflow_def || {};
|
|
5043
|
+
const customQA = normalizedArgs.custom_qa;
|
|
5044
|
+
// Generate kit
|
|
5045
|
+
const kit = generateDemoKit(personaId, persona.name || personaId, workflowDef, scenario, customQA);
|
|
5046
|
+
// Generate markdown script
|
|
5047
|
+
const demoScript = generateDemoScriptMarkdown(kit);
|
|
5048
|
+
// Validate
|
|
5049
|
+
const validation = validateDemoKit(kit);
|
|
5050
|
+
return {
|
|
5051
|
+
success: true,
|
|
5052
|
+
persona_id: personaId,
|
|
5053
|
+
persona_name: persona.name,
|
|
5054
|
+
scenario: scenarioId,
|
|
5055
|
+
kit_summary: {
|
|
5056
|
+
kb_documents: kit.kb_documents.length,
|
|
5057
|
+
demo_questions: kit.demo_script.length,
|
|
5058
|
+
fixed_responses: kit.fixed_responses.length,
|
|
5059
|
+
validation_queries: kit.validation_queries.length,
|
|
5060
|
+
},
|
|
5061
|
+
validation,
|
|
5062
|
+
demo_script_preview: demoScript.slice(0, 2000) + (demoScript.length > 2000 ? "\n\n... (truncated)" : ""),
|
|
5063
|
+
kit,
|
|
5064
|
+
instructions: [
|
|
5065
|
+
"1. Upload KB documents to the persona's knowledge base",
|
|
5066
|
+
"2. Review the demo script and practice the questions",
|
|
5067
|
+
"3. Optionally apply fixed_responses for guaranteed fallbacks",
|
|
5068
|
+
"4. Run validation queries to verify demo readiness",
|
|
5069
|
+
"5. Conduct the demo with confidence!",
|
|
5070
|
+
],
|
|
5071
|
+
};
|
|
5072
|
+
}
|
|
5073
|
+
case "validate_kit": {
|
|
5074
|
+
// Validate a persona's demo readiness
|
|
5075
|
+
const personaId = String(normalizedArgs.persona_id ?? "");
|
|
5076
|
+
if (!personaId) {
|
|
5077
|
+
throw new Error('demo(mode="validate_kit") requires: persona_id');
|
|
5078
|
+
}
|
|
5079
|
+
const { analyzeWorkflowForDemo, DEMO_SCENARIOS } = await import("../sdk/demo-generator.js");
|
|
5080
|
+
const client = await createClient(normalizedArgs.env);
|
|
5081
|
+
const persona = await client.getPersonaById(personaId);
|
|
5082
|
+
if (!persona) {
|
|
5083
|
+
throw new Error(`Persona not found: ${personaId}`);
|
|
5084
|
+
}
|
|
5085
|
+
const analysis = analyzeWorkflowForDemo(persona.workflow_def || {});
|
|
5086
|
+
// Check data sources
|
|
5087
|
+
const dataSourcesResult = await client.listDataSourceFiles(personaId);
|
|
5088
|
+
const dataSources = dataSourcesResult.files || [];
|
|
5089
|
+
const hasKnowledgeBase = dataSources.length > 0;
|
|
5090
|
+
const issues = [];
|
|
5091
|
+
if (!hasKnowledgeBase) {
|
|
5092
|
+
issues.push("No knowledge base documents uploaded - RAG search will fail");
|
|
5093
|
+
}
|
|
5094
|
+
if (analysis.intents.length === 0) {
|
|
5095
|
+
issues.push("No categorizer intents detected - workflow may not route correctly");
|
|
5096
|
+
}
|
|
5097
|
+
if (!analysis.has_search) {
|
|
5098
|
+
issues.push("No search nodes detected - cannot retrieve KB data");
|
|
5099
|
+
}
|
|
5100
|
+
// Suggest best scenario
|
|
5101
|
+
let suggestedScenario = "sales-sdr";
|
|
5102
|
+
for (const [id, scenario] of Object.entries(DEMO_SCENARIOS)) {
|
|
5103
|
+
const intentOverlap = scenario.intents.filter(i => analysis.intents.some(ai => ai.toLowerCase().includes(i.name.toLowerCase()))).length;
|
|
5104
|
+
if (intentOverlap > 0) {
|
|
5105
|
+
suggestedScenario = id;
|
|
5106
|
+
break;
|
|
5107
|
+
}
|
|
5108
|
+
}
|
|
5109
|
+
return {
|
|
5110
|
+
persona_id: personaId,
|
|
5111
|
+
persona_name: persona.name,
|
|
5112
|
+
ready: issues.length === 0,
|
|
5113
|
+
issues,
|
|
5114
|
+
workflow_analysis: analysis,
|
|
5115
|
+
knowledge_base: {
|
|
5116
|
+
has_documents: hasKnowledgeBase,
|
|
5117
|
+
document_count: dataSources.length,
|
|
5118
|
+
},
|
|
5119
|
+
suggested_scenario: suggestedScenario,
|
|
5120
|
+
next_steps: issues.length > 0
|
|
5121
|
+
? issues.map((issue, i) => `${i + 1}. Fix: ${issue}`)
|
|
5122
|
+
: [`Generate demo kit: demo(mode="kit", persona_id="${personaId}", scenario="${suggestedScenario}")`],
|
|
5123
|
+
};
|
|
5124
|
+
}
|
|
5125
|
+
case "scenarios": {
|
|
5126
|
+
// List available demo scenarios
|
|
5127
|
+
const { DEMO_SCENARIOS } = await import("../sdk/demo-generator.js");
|
|
5128
|
+
return {
|
|
5129
|
+
scenarios: Object.entries(DEMO_SCENARIOS).map(([id, scenario]) => ({
|
|
5130
|
+
id,
|
|
5131
|
+
name: scenario.name,
|
|
5132
|
+
description: scenario.description,
|
|
5133
|
+
persona_types: scenario.persona_types,
|
|
5134
|
+
tags: scenario.tags,
|
|
5135
|
+
intent_count: scenario.intents.length,
|
|
5136
|
+
qa_count: scenario.qa_pairs.length,
|
|
5137
|
+
entity_types: scenario.entities.map(e => e.type),
|
|
5138
|
+
})),
|
|
5139
|
+
usage: 'demo(mode="kit", persona_id="...", scenario="<scenario_id>")',
|
|
5140
|
+
};
|
|
5141
|
+
}
|
|
5145
5142
|
case "consolidate": {
|
|
5146
5143
|
const source = String(normalizedArgs.source ?? "");
|
|
5147
5144
|
const output = String(normalizedArgs.output ?? "");
|
|
@@ -5281,34 +5278,6 @@ function generateEntityDocument(entityType, entity, related, tags) {
|
|
|
5281
5278
|
const promptRegistry = new PromptRegistry();
|
|
5282
5279
|
const resourceRegistry = new ResourceRegistry();
|
|
5283
5280
|
export async function startMcpServer() {
|
|
5284
|
-
// #region agent log
|
|
5285
|
-
// H6: confirm which server instance is running (cwd/version/env).
|
|
5286
|
-
try {
|
|
5287
|
-
if (process.env.EMA_MCP_DEBUG_LOGS === "1") {
|
|
5288
|
-
fetch("http://127.0.0.1:7245/ingest/c9b6768a-494d-4365-bd46-bf6c43dc1e22", {
|
|
5289
|
-
method: "POST",
|
|
5290
|
-
headers: { "Content-Type": "application/json" },
|
|
5291
|
-
body: JSON.stringify({
|
|
5292
|
-
location: "src/mcp/server.ts:startMcpServer:startup",
|
|
5293
|
-
message: "MCP server starting",
|
|
5294
|
-
data: {
|
|
5295
|
-
cwd: process.cwd(),
|
|
5296
|
-
argv0to5: process.argv.slice(0, 6),
|
|
5297
|
-
nodeEnv: process.env.NODE_ENV ?? null,
|
|
5298
|
-
emaEnvName: process.env.EMA_ENV_NAME ?? null,
|
|
5299
|
-
codeDir: process.env.EMA_MCP_CODE_DIR ?? null,
|
|
5300
|
-
debugLogs: process.env.EMA_MCP_DEBUG_LOGS ?? null,
|
|
5301
|
-
},
|
|
5302
|
-
timestamp: Date.now(),
|
|
5303
|
-
sessionId: "debug-session",
|
|
5304
|
-
runId: "pre-fix",
|
|
5305
|
-
hypothesisId: "H6",
|
|
5306
|
-
}),
|
|
5307
|
-
}).catch(() => { });
|
|
5308
|
-
}
|
|
5309
|
-
}
|
|
5310
|
-
catch { }
|
|
5311
|
-
// #endregion agent log
|
|
5312
5281
|
const server = new Server({ name: "ema", version: "1.0.0" }, {
|
|
5313
5282
|
capabilities: {
|
|
5314
5283
|
tools: {},
|
|
@@ -5323,28 +5292,6 @@ export async function startMcpServer() {
|
|
|
5323
5292
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
5324
5293
|
const { name, arguments: args } = request.params;
|
|
5325
5294
|
const handler = toolHandlers[name];
|
|
5326
|
-
// #region agent log
|
|
5327
|
-
// H6: prove which tool is invoked and with which top-level keys (no secrets).
|
|
5328
|
-
try {
|
|
5329
|
-
if (process.env.EMA_MCP_DEBUG_LOGS === "1") {
|
|
5330
|
-
const argKeys = args && typeof args === "object" ? Object.keys(args) : [];
|
|
5331
|
-
fetch("http://127.0.0.1:7245/ingest/c9b6768a-494d-4365-bd46-bf6c43dc1e22", {
|
|
5332
|
-
method: "POST",
|
|
5333
|
-
headers: { "Content-Type": "application/json" },
|
|
5334
|
-
body: JSON.stringify({
|
|
5335
|
-
location: "src/mcp/server.ts:CallToolRequestSchema:entry",
|
|
5336
|
-
message: "MCP tool invoked",
|
|
5337
|
-
data: { toolName: name, argKeys },
|
|
5338
|
-
timestamp: Date.now(),
|
|
5339
|
-
sessionId: "debug-session",
|
|
5340
|
-
runId: "pre-fix",
|
|
5341
|
-
hypothesisId: "H6",
|
|
5342
|
-
}),
|
|
5343
|
-
}).catch(() => { });
|
|
5344
|
-
}
|
|
5345
|
-
}
|
|
5346
|
-
catch { }
|
|
5347
|
-
// #endregion agent log
|
|
5348
5295
|
if (!handler) {
|
|
5349
5296
|
return {
|
|
5350
5297
|
content: [{ type: "text", text: JSON.stringify({ error: `Unknown tool: ${name}` }) }],
|
|
@@ -5358,28 +5305,6 @@ export async function startMcpServer() {
|
|
|
5358
5305
|
};
|
|
5359
5306
|
}
|
|
5360
5307
|
catch (error) {
|
|
5361
|
-
// #region agent log
|
|
5362
|
-
// H6: capture top-level handler exception message.
|
|
5363
|
-
try {
|
|
5364
|
-
if (process.env.EMA_MCP_DEBUG_LOGS === "1") {
|
|
5365
|
-
const msg = error instanceof Error ? error.message : String(error);
|
|
5366
|
-
fetch("http://127.0.0.1:7245/ingest/c9b6768a-494d-4365-bd46-bf6c43dc1e22", {
|
|
5367
|
-
method: "POST",
|
|
5368
|
-
headers: { "Content-Type": "application/json" },
|
|
5369
|
-
body: JSON.stringify({
|
|
5370
|
-
location: "src/mcp/server.ts:CallToolRequestSchema:error",
|
|
5371
|
-
message: "Tool handler threw",
|
|
5372
|
-
data: { toolName: name, errorMessage: msg },
|
|
5373
|
-
timestamp: Date.now(),
|
|
5374
|
-
sessionId: "debug-session",
|
|
5375
|
-
runId: "pre-fix",
|
|
5376
|
-
hypothesisId: "H6",
|
|
5377
|
-
}),
|
|
5378
|
-
}).catch(() => { });
|
|
5379
|
-
}
|
|
5380
|
-
}
|
|
5381
|
-
catch { }
|
|
5382
|
-
// #endregion agent log
|
|
5383
5308
|
return {
|
|
5384
5309
|
content: [{ type: "text", text: JSON.stringify({ error: error instanceof Error ? error.message : String(error) }) }],
|
|
5385
5310
|
isError: true,
|