test(pi): wire packaged confirmation delay

This commit is contained in:
2026-08-26 07:50:23 +08:00
parent 26d616c9b6
commit f5e6a04c7d
2 changed files with 19 additions and 1 deletions

View File

@@ -125,6 +125,7 @@ export interface PiWorkerProcessAdapter {
subscribeInvalidation(listener: (error: PiProcessError) => void): () => void;
stop(reason: PiWorkerStopReason): Promise<PiWorkerStopResult>;
injectFailureForProof?(failure: PiWorkerProofFailure): Promise<void>;
delayNextResponseForProof?(commandType: string, delayMs: number): void;
}
export interface PiManagedProviderInput {
@@ -193,6 +194,13 @@ class ManagedPiConversationWorker implements PiConversationWorker {
}
await this.process.injectFailureForProof(failure);
}
delayNextResponseForProof(commandType: string, delayMs: number): void {
if (!this.process.delayNextResponseForProof) {
throw new Error('Managed Pi process does not support proof response delay');
}
this.process.delayNextResponseForProof(commandType, delayMs);
}
}
export function createPiManagedWorkerOpener(

View File

@@ -34,6 +34,7 @@ const NOW = '2026-08-22T16:00:00.000Z';
class OpenerFakeProcess implements PiWorkerProcessAdapter {
readonly generation = 1;
readonly proofResponseDelays: Array<{ commandType: string; delayMs: number }> = [];
constructor(
private readonly sessionId: string,
private readonly options: PiWorkerProcessOptions,
@@ -60,6 +61,9 @@ class OpenerFakeProcess implements PiWorkerProcessAdapter {
subscribe(_listener: (event: PiRpcEvent) => void): () => void { return () => undefined; }
subscribeInvalidation(_listener: (error: PiProcessError) => void): () => void { return () => undefined; }
delayNextResponseForProof(commandType: string, delayMs: number): void {
this.proofResponseDelays.push({ commandType, delayMs });
}
async stop() { return { mode: 'stdin-close' as const, code: 0, signal: null }; }
}
@@ -120,6 +124,7 @@ describe('managed Pi worker opener', () => {
updatedAt: NOW,
};
const processOptions: PiWorkerProcessOptions[] = [];
const processes: OpenerFakeProcess[] = [];
const telemetry: PiRuntimeTelemetryEvent[] = [];
const registry = new PiSessionRegistry({ projectStore });
const extensionHost = new PiManagedExtensionHost();
@@ -140,7 +145,9 @@ describe('managed Pi worker opener', () => {
createProcess: (options) => {
processOptions.push(options);
const sessionIndex = options.additionalArgs?.indexOf('--session-id') ?? -1;
return new OpenerFakeProcess(options.additionalArgs?.[sessionIndex + 1] ?? '', options);
const process = new OpenerFakeProcess(options.additionalArgs?.[sessionIndex + 1] ?? '', options);
processes.push(process);
return process;
},
});
const opener = createOpener(registry);
@@ -200,6 +207,9 @@ describe('managed Pi worker opener', () => {
expect(JSON.stringify(telemetry)).not.toContain(created.id);
expect(JSON.stringify(telemetry)).not.toContain('PRIVATE MANAGED PROMPT');
expect(JSON.stringify(telemetry)).not.toContain('provider-secret-value');
expect(first.worker.delayNextResponseForProof).toBeTypeOf('function');
first.worker.delayNextResponseForProof?.('prompt', 12_000);
expect(processes[0]?.proofResponseDelays).toEqual([{ commandType: 'prompt', delayMs: 12_000 }]);
await first.worker.stop('test_injection');
await reopened.worker.stop('test_injection');
await restarted.worker.stop('test_injection');