@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/sdk/client.js
CHANGED
|
@@ -100,80 +100,22 @@ export class EmaClient {
|
|
|
100
100
|
const controller = new AbortController();
|
|
101
101
|
const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
102
102
|
const fullUrl = `${this.env.baseUrl.replace(/\/$/, "")}${path}`;
|
|
103
|
-
//
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
const jsonAny = opts?.json;
|
|
112
|
-
const workflowAny = jsonAny?.workflow ?? jsonAny?.workflow_def;
|
|
113
|
-
const actions = workflowAny?.actions ?? [];
|
|
114
|
-
const actionNames = Array.isArray(actions)
|
|
115
|
-
? actions
|
|
116
|
-
.slice(0, 50)
|
|
117
|
-
.map((a) => a?.name)
|
|
118
|
-
.filter((n) => typeof n === "string")
|
|
119
|
-
: [];
|
|
120
|
-
const containsHitl = actionNames.some((n) => n.toLowerCase().includes("hitl")) || JSON.stringify(actionNames).toLowerCase().includes("hitl");
|
|
121
|
-
const jsonSize = opts?.json !== undefined ? JSON.stringify(opts.json).length : 0;
|
|
122
|
-
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/sdk/client.ts:requestWithRetries:pre', message: 'HTTP request', data: { env: this.env.name, codeDir: process.env.EMA_MCP_CODE_DIR ?? null, cwd: process.cwd(), method, path, isUpdatePersona, attempt, retries, hasJson: opts?.json !== undefined, jsonSize, hasWorkflow: !!workflowAny, actionCount: Array.isArray(actions) ? actions.length : 0, containsHitl }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'pre-fix', hypothesisId: 'H3' }) }).catch(() => { });
|
|
123
|
-
}
|
|
103
|
+
// gRPC-Connect endpoints need Connect-Protocol-Version header
|
|
104
|
+
const isGrpcConnect = path.includes(".v1.") || path.includes(".v2.");
|
|
105
|
+
const headers = {
|
|
106
|
+
Authorization: `Bearer ${this.env.bearerToken}`,
|
|
107
|
+
"Content-Type": "application/json",
|
|
108
|
+
};
|
|
109
|
+
if (isGrpcConnect) {
|
|
110
|
+
headers["Connect-Protocol-Version"] = "1";
|
|
124
111
|
}
|
|
125
|
-
catch { }
|
|
126
|
-
// #endregion agent log
|
|
127
112
|
const response = await fetch(fullUrl, {
|
|
128
113
|
method,
|
|
129
|
-
headers
|
|
130
|
-
Authorization: `Bearer ${this.env.bearerToken}`,
|
|
131
|
-
"Content-Type": "application/json",
|
|
132
|
-
},
|
|
114
|
+
headers,
|
|
133
115
|
body: opts?.json !== undefined ? JSON.stringify(opts.json) : undefined,
|
|
134
116
|
signal: controller.signal,
|
|
135
117
|
});
|
|
136
118
|
clearTimeout(timeoutId);
|
|
137
|
-
// #region agent log
|
|
138
|
-
// H1/H2/H4: capture response status + request id for correlation (no secrets).
|
|
139
|
-
try {
|
|
140
|
-
if (process.env.EMA_MCP_DEBUG_LOGS !== "1") {
|
|
141
|
-
// disabled
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
const reqId = response.headers.get("x-request-id") ?? response.headers.get("x-correlation-id") ?? response.headers.get("x-amzn-trace-id");
|
|
145
|
-
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/sdk/client.ts:requestWithRetries:post', message: 'HTTP response', data: { env: this.env.name, method, path, status: response.status, ok: response.ok, attempt, durationMs: Date.now() - startedAt, reqId }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'pre-fix', hypothesisId: 'H1' }) }).catch(() => { });
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
catch { }
|
|
149
|
-
// #endregion agent log
|
|
150
|
-
// #region agent log
|
|
151
|
-
// H1/H2: for update_persona failures, log first part of error body (redacted/truncated).
|
|
152
|
-
try {
|
|
153
|
-
if (process.env.EMA_MCP_DEBUG_LOGS !== "1") {
|
|
154
|
-
// disabled
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
157
|
-
const isUpdatePersona = path.includes("/api/personas/update_persona");
|
|
158
|
-
if (isUpdatePersona && !response.ok) {
|
|
159
|
-
const cloned = response.clone();
|
|
160
|
-
const txt = await cloned.text();
|
|
161
|
-
const snippet = txt.length > 1200 ? `${txt.slice(0, 1200)}…(truncated)` : txt;
|
|
162
|
-
let parsedDetail;
|
|
163
|
-
let hasGweIssues = false;
|
|
164
|
-
try {
|
|
165
|
-
const j = JSON.parse(txt);
|
|
166
|
-
const detail = j.detail ?? j.message ?? j.error;
|
|
167
|
-
parsedDetail = typeof detail === "string" ? detail : undefined;
|
|
168
|
-
hasGweIssues = Array.isArray(j.gwe_issues);
|
|
169
|
-
}
|
|
170
|
-
catch { }
|
|
171
|
-
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/sdk/client.ts:requestWithRetries:errorBody', message: 'HTTP error body (update_persona)', data: { env: this.env.name, method, path, status: response.status, parsedDetail, hasGweIssues, bodySnippet: snippet }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'pre-fix', hypothesisId: 'H2' }) }).catch(() => { });
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
catch { }
|
|
176
|
-
// #endregion agent log
|
|
177
119
|
// Handle 401 - attempt token refresh once
|
|
178
120
|
if (response.status === 401 && !hasAttemptedRefresh && this.tokenRefreshConfig?.refreshCallback) {
|
|
179
121
|
hasAttemptedRefresh = true;
|
|
@@ -324,15 +266,6 @@ export class EmaClient {
|
|
|
324
266
|
});
|
|
325
267
|
if (!resp.ok) {
|
|
326
268
|
const body = await resp.text();
|
|
327
|
-
// #region agent log
|
|
328
|
-
try {
|
|
329
|
-
if (this.debugLogsEnabled) {
|
|
330
|
-
const snippet = body.length > 2000 ? `${body.slice(0, 2000)}…(truncated)` : body;
|
|
331
|
-
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/sdk/client.ts:checkWorkflow:error', message: 'CheckWorkflow failed', data: { env: this.env.name, status: resp.status, bodySnippet: snippet }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'pre-fix', hypothesisId: 'H5' }) }).catch(() => { });
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
catch { }
|
|
335
|
-
// #endregion agent log
|
|
336
269
|
throw new EmaApiError({
|
|
337
270
|
statusCode: resp.status,
|
|
338
271
|
body,
|
|
@@ -340,35 +273,70 @@ export class EmaClient {
|
|
|
340
273
|
});
|
|
341
274
|
}
|
|
342
275
|
const data = (await resp.json());
|
|
343
|
-
// #region agent log
|
|
344
|
-
try {
|
|
345
|
-
if (this.debugLogsEnabled) {
|
|
346
|
-
const keys = Object.keys(data);
|
|
347
|
-
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/sdk/client.ts:checkWorkflow:ok', message: 'CheckWorkflow ok', data: { env: this.env.name, keys }, timestamp: Date.now(), sessionId: 'debug-session', runId: 'pre-fix', hypothesisId: 'H5' }) }).catch(() => { });
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
catch { }
|
|
351
|
-
// #endregion agent log
|
|
352
276
|
return data;
|
|
353
277
|
}
|
|
354
278
|
async updateAiEmployee(req, opts) {
|
|
355
279
|
// Use /api/personas/update_persona - same endpoint as Ema frontend
|
|
280
|
+
// Debug logging for troubleshooting
|
|
281
|
+
if (opts?.verbose || process.env.EMA_DEBUG) {
|
|
282
|
+
console.error("[EmaClient] updateAiEmployee request:", JSON.stringify({
|
|
283
|
+
persona_id: req.persona_id,
|
|
284
|
+
has_workflow: !!req.workflow,
|
|
285
|
+
workflow_actions: req.workflow ? req.workflow.actions : undefined,
|
|
286
|
+
has_proto_config: !!req.proto_config,
|
|
287
|
+
}, null, 2));
|
|
288
|
+
}
|
|
356
289
|
const resp = await this.requestWithRetries("POST", "/api/personas/update_persona", {
|
|
357
290
|
json: req,
|
|
358
291
|
});
|
|
359
292
|
if (!resp.ok) {
|
|
360
293
|
const body = await resp.text();
|
|
294
|
+
// Debug logging for errors
|
|
295
|
+
if (opts?.verbose || process.env.EMA_DEBUG) {
|
|
296
|
+
console.error("[EmaClient] updateAiEmployee FAILED:", resp.status, body);
|
|
297
|
+
console.error("[EmaClient] Request that failed:", JSON.stringify(req, null, 2).slice(0, 5000));
|
|
298
|
+
}
|
|
361
299
|
// Try to parse error body for better error messages
|
|
362
300
|
let errorDetail = "";
|
|
363
301
|
try {
|
|
364
302
|
const errorJson = JSON.parse(body);
|
|
365
303
|
// Ema API returns InvalidPersonaResponse with 'detail' field
|
|
366
304
|
errorDetail = errorJson.detail ?? errorJson.message ?? errorJson.error ?? "";
|
|
367
|
-
//
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
305
|
+
// Parse GWE (workflow) issues - it's an object, not an array
|
|
306
|
+
// See WorkflowIssues schema in OpenAPI spec
|
|
307
|
+
if (errorJson.gwe_issues && typeof errorJson.gwe_issues === "object") {
|
|
308
|
+
const gwe = errorJson.gwe_issues;
|
|
309
|
+
const issuesParts = [];
|
|
310
|
+
if (gwe.detail) {
|
|
311
|
+
issuesParts.push(`Detail: ${gwe.detail}`);
|
|
312
|
+
}
|
|
313
|
+
if (Array.isArray(gwe.missing_widgets) && gwe.missing_widgets.length > 0) {
|
|
314
|
+
issuesParts.push(`Missing widgets: ${gwe.missing_widgets.join(", ")}`);
|
|
315
|
+
}
|
|
316
|
+
if (Array.isArray(gwe.unready_widgets) && gwe.unready_widgets.length > 0) {
|
|
317
|
+
const unready = gwe.unready_widgets.map((w) => `${w.widget_name}: ${w.message}`);
|
|
318
|
+
issuesParts.push(`Unready widgets: ${unready.join("; ")}`);
|
|
319
|
+
}
|
|
320
|
+
if (Array.isArray(gwe.missing_inputs) && gwe.missing_inputs.length > 0) {
|
|
321
|
+
const missing = gwe.missing_inputs.map((i) => `${i.action_name}.${i.input_name}`);
|
|
322
|
+
issuesParts.push(`Missing inputs: ${missing.join(", ")}`);
|
|
323
|
+
}
|
|
324
|
+
if (Array.isArray(gwe.mismatched_inputs) && gwe.mismatched_inputs.length > 0) {
|
|
325
|
+
const mismatched = gwe.mismatched_inputs.map((i) => `${i.action_name}.${i.input_name}`);
|
|
326
|
+
issuesParts.push(`Mismatched inputs: ${mismatched.join(", ")}`);
|
|
327
|
+
}
|
|
328
|
+
if (Array.isArray(gwe.named_result_errors) && gwe.named_result_errors.length > 0) {
|
|
329
|
+
const resultErrs = gwe.named_result_errors.map((e) => `${e.named_result_key}: ${e.error_description}`);
|
|
330
|
+
issuesParts.push(`Result errors: ${resultErrs.join("; ")}`);
|
|
331
|
+
}
|
|
332
|
+
if (gwe.has_cycles) {
|
|
333
|
+
issuesParts.push("Workflow has cycles");
|
|
334
|
+
}
|
|
335
|
+
if (gwe.has_no_outputs) {
|
|
336
|
+
issuesParts.push("Workflow has no outputs");
|
|
337
|
+
}
|
|
338
|
+
if (issuesParts.length > 0) {
|
|
339
|
+
errorDetail += ` [GWE Issues: ${issuesParts.join(" | ")}]`;
|
|
372
340
|
}
|
|
373
341
|
}
|
|
374
342
|
}
|