feat(agent): add execution-plan skeleton workflow

This commit is contained in:
2026-04-09 21:11:21 +02:00
parent 29c93eeb35
commit 26d008705f
8 changed files with 708 additions and 98 deletions

View File

@@ -13,9 +13,16 @@ export type AgentOutputDraft = {
body?: string;
};
export type AgentExecutionStep = {
id: string;
title: string;
channel: string;
outputType: string;
};
export type AgentExecutionPlan = {
steps: string[];
outputs: AgentOutputDraft[];
summary: string;
steps: AgentExecutionStep[];
};
export type AgentAnalyzeResult = {
@@ -32,6 +39,53 @@ function trimString(value: unknown): string {
return typeof value === "string" ? value.trim() : "";
}
function normalizeStepId(value: unknown): string {
return trimString(value)
.toLowerCase()
.replace(/[^a-z0-9\s-_]/g, "")
.replace(/\s+/g, "-");
}
export function normalizeAgentExecutionPlan(raw: unknown): AgentExecutionPlan {
const rawRecord =
raw && typeof raw === "object" && !Array.isArray(raw)
? (raw as Record<string, unknown>)
: null;
const rawSteps = Array.isArray(rawRecord?.steps) ? rawRecord.steps : [];
const seenStepIds = new Set<string>();
const steps: AgentExecutionStep[] = [];
for (let index = 0; index < rawSteps.length; index += 1) {
const item = rawSteps[index];
if (!item || typeof item !== "object" || Array.isArray(item)) {
continue;
}
const itemRecord = item as Record<string, unknown>;
const fallbackId = `step-${index + 1}`;
const normalizedCandidateId = normalizeStepId(itemRecord.id) || fallbackId;
let stepId = normalizedCandidateId;
let suffix = 2;
while (seenStepIds.has(stepId)) {
stepId = `${normalizedCandidateId}-${suffix}`;
suffix += 1;
}
seenStepIds.add(stepId);
steps.push({
id: stepId,
title: trimString(itemRecord.title) || SAFE_FALLBACK_TITLE,
channel: trimString(itemRecord.channel) || SAFE_FALLBACK_CHANNEL,
outputType: trimString(itemRecord.outputType) || SAFE_FALLBACK_OUTPUT_TYPE,
});
}
return {
summary: trimString(rawRecord?.summary),
steps,
};
}
export function areClarificationAnswersComplete(
questions: AgentClarificationQuestion[],
answers: AgentClarificationAnswerMap,