mirror of
https://github.com/andy-stack/vaultkeeper-ai.git
synced 2026-07-22 06:42:03 +00:00
Restructure system prompt to enforce mandatory complexity evaluation before action. Replace verbose multi-step planning framework with concise gate-based decision model. Add UI for execution plan visibility. Improve planning/execution separation by blocking execution tools during planning phase. Remove cancellation indicator component. Fix conversation deletion bug preventing saves after delete. Strengthen type safety for AIFunction names. Simplify function summary format for planning agent. Update test mocks for new callback signatures.
111 lines
No EOL
3.7 KiB
TypeScript
111 lines
No EOL
3.7 KiB
TypeScript
import { ExecutionStatus } from "Enums/ExecutionStatus";
|
|
import { ExecutionStep } from "./ExecutionStep";
|
|
import type { SubmitPlanArgs } from "AIClasses/Schemas/AIFunctionSchemas";
|
|
import { Copy, replaceCopy } from "Enums/Copy";
|
|
|
|
export class ExecutionPlan {
|
|
|
|
public readonly executionSteps: ExecutionStep[] = [];
|
|
|
|
public constructor(plan: SubmitPlanArgs) {
|
|
for (const [index, step] of plan.steps.entries()) {
|
|
this.executionSteps.push(new ExecutionStep(
|
|
index + 1,
|
|
step.description,
|
|
step.instruction,
|
|
step.context
|
|
));
|
|
}
|
|
if (this.executionSteps[0]) { // Mark first step as active
|
|
this.executionSteps[0].status = ExecutionStatus.Active;
|
|
}
|
|
}
|
|
|
|
public completed(): boolean {
|
|
return this.executionSteps.every(step => step.status === ExecutionStatus.Completed);
|
|
}
|
|
|
|
public getStatusSummary(): { completed: string[], remaining: string[] } {
|
|
const completed: string[] = [];
|
|
const remaining: string[] = [];
|
|
|
|
for (const step of this.executionSteps) {
|
|
const stepDescription = `${step.step + 1}. ${step.description}`;
|
|
if (step.status === ExecutionStatus.Completed) {
|
|
completed.push(stepDescription);
|
|
} else {
|
|
remaining.push(stepDescription);
|
|
}
|
|
}
|
|
|
|
return { completed, remaining };
|
|
}
|
|
|
|
public completeExecutionStep(stepNumber: number): object {
|
|
const stepIndex = stepNumber - 1;
|
|
|
|
const currentStep = this.executionSteps[stepIndex];
|
|
if (!currentStep) {
|
|
return {
|
|
error: replaceCopy(Copy.StepDoesNotExistError, [
|
|
stepNumber.toString(),
|
|
this.executionSteps.length.toString()
|
|
])
|
|
};
|
|
}
|
|
|
|
for (let i = 0; i < stepIndex; i++) { // Ensure all previous steps are completed
|
|
if (this.executionSteps[i].status !== ExecutionStatus.Completed) {
|
|
return {
|
|
error: replaceCopy(Copy.StepMustBeCompletedInOrderError, [
|
|
stepNumber.toString(),
|
|
`${i + 1}. ${this.executionSteps[i].description}`
|
|
])
|
|
};
|
|
}
|
|
}
|
|
currentStep.status = ExecutionStatus.Completed;
|
|
|
|
const nextStep = this.executionSteps[stepIndex + 1];
|
|
if (nextStep) {
|
|
nextStep.status = ExecutionStatus.Active;
|
|
return {
|
|
message: replaceCopy(Copy.StepCompletedWithNextStep, [
|
|
stepNumber.toString(),
|
|
(stepNumber + 1).toString()
|
|
]),
|
|
step: nextStep.step,
|
|
description: nextStep.description,
|
|
instruction: nextStep.instruction,
|
|
...(nextStep.context && { context: nextStep.context })
|
|
};
|
|
} else {
|
|
return {
|
|
message: replaceCopy(Copy.AllStepsCompleted, [
|
|
stepNumber.toString()
|
|
])
|
|
};
|
|
}
|
|
}
|
|
|
|
public toFunctionResponse(): object {
|
|
if (this.executionSteps.length === 0) {
|
|
return {
|
|
error: Copy.PlanningFailedError
|
|
};
|
|
}
|
|
|
|
const firstStep = this.executionSteps[0];
|
|
|
|
return {
|
|
plan: this.executionSteps.map((step, index) => `${index + 1}. ${step.description}`),
|
|
firstStep: {
|
|
step: firstStep.step,
|
|
description: firstStep.description,
|
|
instruction: firstStep.instruction,
|
|
...(firstStep.context && { context: firstStep.context })
|
|
}
|
|
};
|
|
}
|
|
|
|
} |