feat: expose bot task progress

This commit is contained in:
zenord
2026-08-17 14:37:51 +08:00
parent 91bf4e7a0c
commit 2795567f8c
13 changed files with 321 additions and 54 deletions
+19 -3
View File
@@ -5,6 +5,8 @@ import { AcpClient } from "./client.js";
export class AcpSessionRestoreError extends Error {}
export type AcpWorkerPhase = "idle" | "initializing" | "processing";
export class AcpWorker {
private child?: ChildProcessWithoutNullStreams;
private client?: AcpClient;
@@ -14,6 +16,9 @@ export class AcpWorker {
private stderrBytes = 0;
nativeSessionId?: string;
lastUsedAt = Date.now();
turnStartedAt?: number;
lastActivityAt?: number;
phase: AcpWorkerPhase = "idle";
inFlight = false;
constructor(
@@ -35,7 +40,11 @@ export class AcpWorker {
this.exited = true;
if (!this.stopping) this.crashed(new Error(`ACP worker exited (code=${code ?? "null"}, signal=${signal ?? "null"})`));
});
this.client = new AcpClient(this.child, { initializeTimeoutMs: this.config.initializeTimeoutMs, policy: this.bot.permissions });
this.client = new AcpClient(this.child, {
initializeTimeoutMs: this.config.initializeTimeoutMs,
policy: this.bot.permissions,
onSessionActivity: () => { this.lastActivityAt = Date.now(); }
});
try {
await this.client.initialize();
if (nativeSessionId) {
@@ -52,11 +61,15 @@ export class AcpWorker {
}
}
async prompt(text: string): Promise<string> {
async prompt(text: string, phase: Exclude<AcpWorkerPhase, "idle"> = "processing"): Promise<string> {
if (!this.client || !this.nativeSessionId || this.exited) throw new Error("ACP worker is not available");
if (this.inFlight) throw new Error("ACP worker already has an in-flight turn");
const now = Date.now();
this.inFlight = true;
this.lastUsedAt = Date.now();
this.phase = phase;
this.turnStartedAt = now;
this.lastActivityAt = now;
this.lastUsedAt = now;
this.abort = new AbortController();
let timeout: NodeJS.Timeout | undefined;
const timeoutPromise = new Promise<never>((_resolve, reject) => {
@@ -72,6 +85,9 @@ export class AcpWorker {
} finally {
if (timeout) clearTimeout(timeout);
this.inFlight = false;
this.phase = "idle";
this.turnStartedAt = undefined;
this.lastActivityAt = undefined;
this.abort = undefined;
this.lastUsedAt = Date.now();
}