mirror of
https://github.com/andy-stack/vaultkeeper-ai.git
synced 2026-07-22 16:30:27 +00:00
Introduce separate planning model setting to allow using different models for planning vs execution. Add visual countdown display when rate limits are hit, with improved retry delay parsing across providers (Claude, OpenAI, Gemini). Refactor settings tab into Views directory and enhance mobile layout for input controls.
132 lines
No EOL
4.4 KiB
TypeScript
132 lines
No EOL
4.4 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(),
|
|
this.incompleteSteps().join(",")
|
|
])
|
|
};
|
|
}
|
|
}
|
|
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 completeExecutionPlan(confirmation: boolean): object {
|
|
if (!confirmation) {
|
|
return { error: Copy.ConfirmationFalse };
|
|
}
|
|
if (!this.completed()) {
|
|
return { error: replaceCopy(Copy.IncompleteExecutionAttempt,
|
|
[this.incompleteSteps().join(", ")]) };
|
|
}
|
|
return { message: Copy.PlanExecutionComplete }
|
|
}
|
|
|
|
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 })
|
|
}
|
|
};
|
|
}
|
|
|
|
public incompleteSteps(): number[] {
|
|
const incompleteSteps = [];
|
|
for (const step of this.executionSteps) {
|
|
if (step.status !== ExecutionStatus.Completed) {
|
|
incompleteSteps.push(step.step);
|
|
}
|
|
}
|
|
return incompleteSteps;
|
|
}
|
|
|
|
} |