fix: fix projection to TS when fetching agnet in MCP

This commit is contained in:
Abhishek Kumar 2026-05-23 14:45:50 +05:30
parent 3892b58486
commit bbb4f91a27
12 changed files with 392 additions and 63 deletions

View file

@ -14,9 +14,18 @@ import type {
export function generateCode(
workflow: WireWorkflow,
specs: NodeSpec[],
opts: { workflowName?: string } = {},
opts: { workflowName?: string; edgeFieldNames?: string[] } = {},
): GenerateResult {
const specByName = new Map(specs.map((s) => [s.name, s]));
const edgeFieldNames = new Set(
opts.edgeFieldNames ?? [
"label",
"condition",
"transition_speech",
"transition_speech_type",
"transition_speech_recording_id",
],
);
// Catch unknown node types up-front — otherwise we'd emit an import
// line for a factory that doesn't exist.
@ -97,7 +106,7 @@ export function generateCode(
],
};
}
const cleanedEdge = pickEdgeFields(edge.data);
const cleanedEdge = pickEdgeFields(edge.data, edgeFieldNames);
const edgeOpts = renderObject(cleanedEdge, 0);
lines.push(`wf.edge(${src}, ${tgt}, ${edgeOpts});`);
}
@ -210,22 +219,13 @@ function stripUnknown(
return out;
}
// Edge schema is fixed (no NodeSpec for edges). Mirrors the allowed
// fields on `Workflow.edge(...)` in both SDKs.
const KNOWN_EDGE_FIELDS = new Set([
"label",
"condition",
"transition_speech",
"transition_speech_type",
"transition_speech_recording_id",
]);
function pickEdgeFields(
data: Record<string, unknown>,
knownEdgeFields: Set<string>,
): Record<string, unknown> {
const out: Record<string, unknown> = {};
for (const [k, v] of Object.entries(data)) {
if (KNOWN_EDGE_FIELDS.has(k)) out[k] = v;
if (knownEdgeFields.has(k)) out[k] = v;
}
return out;
}

View file

@ -11,6 +11,7 @@ interface GenerateRequest {
command: "generate";
workflow: WireWorkflow;
specs: NodeSpec[];
edgeFieldNames: string[];
workflowName?: string;
}
@ -18,6 +19,7 @@ interface ParseRequest {
command: "parse";
code: string;
specs: NodeSpec[];
edgeFieldNames: string[];
}
type Request = GenerateRequest | ParseRequest;
@ -49,11 +51,16 @@ async function main(): Promise<void> {
}
if (req.command === "generate") {
writeResult(generateCode(req.workflow, req.specs, { workflowName: req.workflowName }));
writeResult(
generateCode(req.workflow, req.specs, {
workflowName: req.workflowName,
edgeFieldNames: req.edgeFieldNames,
}),
);
return;
}
if (req.command === "parse") {
writeResult(parseCode(req.code, req.specs));
writeResult(parseCode(req.code, req.specs, req.edgeFieldNames));
return;
}
writeResult({

View file

@ -25,8 +25,19 @@ import type {
WireNode,
} from "./types.ts";
export function parseCode(code: string, specs: NodeSpec[]): ParseResult {
export function parseCode(
code: string,
specs: NodeSpec[],
edgeFieldNames: string[] = [
"label",
"condition",
"transition_speech",
"transition_speech_type",
"transition_speech_recording_id",
],
): ParseResult {
const specByName = new Map(specs.map((s) => [s.name, s]));
const allowedEdgeFieldNames = new Set(edgeFieldNames);
const sourceFile = ts.createSourceFile(
"workflow.ts",
code,
@ -335,6 +346,12 @@ export function parseCode(code: string, specs: NodeSpec[]): ParseResult {
addError(stmt, "`edge` requires a non-empty `condition` string.");
return;
}
for (const key of Object.keys(optsObj)) {
if (!allowedEdgeFieldNames.has(key)) {
addError(stmt, `Unknown edge field: \`${key}\`.`);
return;
}
}
edges.push({
id: `${src.id}-${tgt.id}`,
source: src.id,