@ema.co/mcp-toolkit 0.3.0 → 1.4.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.
package/dist/cli/index.js CHANGED
File without changes
@@ -122,17 +122,32 @@ export async function handlePersona(args, client, getTemplateId, createClientFor
122
122
  if (!persona) {
123
123
  return { error: `Persona not found: ${idOrName}` };
124
124
  }
125
+ // Merge new proto_config with existing, or use existing if not provided
126
+ const existingProtoConfig = persona.proto_config ?? {};
127
+ const newProtoConfig = args.proto_config;
128
+ const mergedProtoConfig = newProtoConfig
129
+ ? { ...existingProtoConfig, ...newProtoConfig } // Merge: new values override existing
130
+ : existingProtoConfig;
131
+ // IMPORTANT: The Ema API requires workflow to be sent along with proto_config
132
+ // for proto_config changes to persist. This matches what the UI does.
133
+ // Get full persona details to include workflow
134
+ const fullPersona = await client.getPersonaById(persona.id);
135
+ const existingWorkflow = fullPersona
136
+ ? (fullPersona.workflow_def ?? fullPersona.workflow)
137
+ : undefined;
125
138
  await client.updateAiEmployee({
126
139
  persona_id: persona.id,
127
140
  name: args.name,
128
141
  description: args.description,
129
- proto_config: persona.proto_config ?? {},
142
+ proto_config: mergedProtoConfig,
143
+ workflow: existingWorkflow, // Include workflow for proto_config to persist
130
144
  enabled_by_user: typeof args.enabled === "boolean" ? args.enabled : undefined,
131
145
  });
132
146
  return {
133
147
  success: true,
134
148
  persona_id: persona.id,
135
149
  updated_fields: Object.keys(args).filter(k => !["id", "identifier", "mode", "env"].includes(k)),
150
+ proto_config_updated: !!newProtoConfig,
136
151
  };
137
152
  }
138
153
  case "compare": {
@@ -562,6 +577,15 @@ export async function handleWorkflow(args, client) {
562
577
  if (!persona) {
563
578
  return { error: `Persona not found: ${personaId}` };
564
579
  }
580
+ // Check persona status - deployment works on disabled personas but we should inform user
581
+ const personaStatus = persona.status?.toLowerCase();
582
+ const isDisabled = personaStatus === "inactive" || personaStatus === "disabled";
583
+ const statusWarnings = [];
584
+ if (isDisabled) {
585
+ statusWarnings.push(`⚠️ Persona "${persona.name}" is currently DISABLED (status: ${persona.status}). ` +
586
+ `Workflow will be deployed but won't be active until enabled. ` +
587
+ `Use persona(mode="update", id="${personaId}", enabled=true) to enable.`);
588
+ }
565
589
  let deployWorkflow = workflowDef || persona.workflow_def;
566
590
  // Validate if requested (default: true)
567
591
  if (args.validate !== false) {
@@ -572,6 +596,7 @@ export async function handleWorkflow(args, client) {
572
596
  error: "Workflow has errors",
573
597
  issues: errors,
574
598
  hint: "Set auto_fix=true to attempt automatic fixes",
599
+ ...(statusWarnings.length > 0 && { status_warnings: statusWarnings }),
575
600
  };
576
601
  }
577
602
  // Auto-fix if enabled
@@ -588,7 +613,13 @@ export async function handleWorkflow(args, client) {
588
613
  return {
589
614
  success: true,
590
615
  persona_id: personaId,
616
+ persona_name: persona.name,
617
+ persona_status: persona.status,
591
618
  deployed: true,
619
+ ...(isDisabled && {
620
+ warning: `Persona is DISABLED - workflow deployed but inactive. Enable with: persona(mode="update", id="${personaId}", enabled=true)`,
621
+ }),
622
+ ...(statusWarnings.length > 0 && { status_warnings: statusWarnings }),
592
623
  };
593
624
  }
594
625
  case "compare": {
@@ -74,9 +74,16 @@ Identify what the user is asking for:
74
74
  | **Data Sources** | ✓/✗ | Knowledge base, web search, APIs? |
75
75
  | **External Tools** | ✓/✗ | ServiceNow, Salesforce, email? |
76
76
  | **Routing Logic** | ✓/✗ | How to handle different intents? |
77
- | **HITL Requirements** | ✓/✗ | When is human approval needed? |
77
+ | **HITL Requirements** | ✓/✗ | DEFAULT: No approval (auto-proceed). Only add if explicitly requested. |
78
78
  | **Fallback Handling** | ✓/✗ | What if no match? |
79
79
 
80
+ #### HITL Policy (Default: Auto-Proceed)
81
+ For external side-effect actions (send_email, create_ticket, update_record):
82
+ - **Default**: Proceed WITHOUT approval gate unless explicitly requested
83
+ - **Add HITL only when**: User says "confirm before", "approval required", "human review"
84
+ - **Skip HITL when**: User says "auto", "directly", "no approval", or specifies direct flow
85
+ - **If ambiguous**: ASK "Should [action] require approval, or auto-proceed?"
86
+
80
87
  #### For BROWNFIELD (extend existing):
81
88
  | Dimension | Status | Missing Info |
82
89
  |-----------|--------|--------------|
@@ -251,7 +258,7 @@ Verify you have answers for:
251
258
  - Intents: ${args.intents || "(to be determined)"}
252
259
  - Data Sources: (ask if not clear from use case)
253
260
  - Actions: (ask if not clear from use case)
254
- - Approvals/HITL: (ask if external actions involved)
261
+ - Approvals/HITL: DEFAULT is no approval (auto-proceed). Only ask if user seems to want approval gates.
255
262
 
256
263
  ### Step 2: Select Pattern + Agents
257
264
  Call \`action(suggest="${args.use_case}")\` to get recommended agents and a suggested workflow pattern.
@@ -1073,6 +1080,8 @@ Where \`<requirements>\` includes:
1073
1080
  ${args.intents ? `- Intents: ${args.intents}` : ""}
1074
1081
  ${args.tools ? `- Tools: ${args.tools}` : ""}
1075
1082
 
1083
+ **HITL Policy**: DEFAULT is no approval gates. Only add HITL if user explicitly requests approval/confirmation before external actions.
1084
+
1076
1085
  If the tool returns \`status="needs_input"\`, ask the missing questions, then call \`workflow(...)\` again with the additional details.
1077
1086
 
1078
1087
  ### Step 2: (Optional) Validate the generated workflow