feat(coding-runtime): add managed Pi extension host

This commit is contained in:
2026-08-23 09:39:12 +08:00
parent 47159b3cbd
commit 3861c3286a
22 changed files with 1673 additions and 16 deletions

View File

@@ -77,6 +77,10 @@ class RuntimeFakeWorker implements PiConversationWorker {
};
}
async send(command: PiRpcCommand): Promise<void> {
this.requests.push(structuredClone(command));
}
setSessionData(input: { state?: unknown; entries?: unknown; stats?: unknown }): void {
if (input.state !== undefined) this.stateData = structuredClone(input.state);
if (input.entries !== undefined) this.entriesData = structuredClone(input.entries);
@@ -240,6 +244,25 @@ describe('Pi Conversation runtime', () => {
status: 'complete',
}));
expect(JSON.stringify(streamed.nodes)).toContain('Implemented');
workers.get(left.id)!.emit({
type: 'extension_ui_request',
id: 'question-runtime',
method: 'select',
title: 'Choose implementation',
options: ['Small seam', 'Large seam'],
});
await expect.poll(async () => (await runtime.getSnapshot(left.id)).pendingInteractions)
.toContainEqual(expect.objectContaining({ id: 'question-runtime', status: 'pending' }));
await runtime.respondInteraction(left.id, {
interactionId: 'question-runtime',
optionId: 'question-runtime:option:0',
});
expect(workers.get(left.id)!.requests.at(-1)).toEqual({
type: 'extension_ui_response', id: 'question-runtime', value: 'Small seam',
});
expect((await runtime.getSnapshot(left.id)).pendingInteractions).toContainEqual(
expect.objectContaining({ id: 'question-runtime', status: 'answered' }),
);
const durable = {
state: {
sessionId: `session-${left.id}`,