mirror of
https://github.com/andy-stack/vaultkeeper-ai.git
synced 2026-07-22 16:30:27 +00:00
- Move prompts from AIClasses to AIPrompts directory - Replace centralized IPrompt injection with direct property setters on IAIClass - Remove allowDestructiveActions parameter from streamRequest methods - Add toolDefinitions, systemPrompt, and userInstruction properties to IAIClass - Refactor AIFunctionDefinitions to static methods with agent-specific tool sets - Add planning agent function definitions (CreatePlan, Replan, CompleteStep, SubmitPlan) - Create AIControllerService to handle agent orchestration - Add execution plan related copy strings and replacement utility - Update all AI providers (Claude, Gemini, OpenAI) to use new architecture
70 lines
No EOL
2 KiB
TypeScript
70 lines
No EOL
2 KiB
TypeScript
// This class is designed to provide a single centralised abort controller
|
|
export class AbortService {
|
|
private abortController: AbortController = new AbortController();
|
|
|
|
public static isAbortError(error: unknown): boolean {
|
|
return error instanceof DOMException && error.name === "AbortError";
|
|
}
|
|
|
|
public reset = () => this.initialiseAbortController(); // semantic alias for initialiseAbortController
|
|
|
|
public initialiseAbortController(): void {
|
|
this.abort();
|
|
this.abortController = new AbortController();
|
|
}
|
|
|
|
public signal(): AbortSignal {
|
|
return this.abortController.signal;
|
|
}
|
|
|
|
public reason(): Error {
|
|
return this.signal().reason instanceof Error ? this.signal().reason as Error : new Error("Aborted");
|
|
}
|
|
|
|
public abort(reason?: string): void {
|
|
this.abortController.abort(
|
|
new DOMException(reason ?? "Aborted", "AbortError")
|
|
);
|
|
}
|
|
|
|
// useful if you need to rethrow the abort error
|
|
public throw(): never {
|
|
throw this.reason();
|
|
}
|
|
|
|
public async abortableOperation<T>(executor: () => Promise<T>): Promise<T> {
|
|
const signal = this.abortController.signal;
|
|
|
|
if (signal.aborted) {
|
|
this.throw();
|
|
}
|
|
|
|
let abortHandler: () => void;
|
|
let abortWon = false;
|
|
|
|
const executorPromise = executor();
|
|
|
|
const abortPromise = new Promise<never>((_, reject) => {
|
|
abortHandler = () => {
|
|
abortWon = true;
|
|
reject(this.reason());
|
|
};
|
|
signal.addEventListener("abort", abortHandler, { once: true });
|
|
});
|
|
|
|
// Suppress AbortErrors from executor once abort has won the race
|
|
executorPromise.catch(error => {
|
|
if (abortWon && AbortService.isAbortError(error)) {
|
|
return;
|
|
}
|
|
});
|
|
|
|
abortPromise.catch(() => {});
|
|
|
|
try {
|
|
return await Promise.race([executorPromise, abortPromise]);
|
|
} finally {
|
|
signal.removeEventListener("abort", abortHandler!);
|
|
}
|
|
}
|
|
} |