v2.2-paseo-providers: Paseo provider stack + v2.2.1 pane-scoped chat fixes
Ship Paseo-equivalent provider snapshot, AgentComposerBar, ACP dispatch rewrite with streaming/persist, permission prompts, and agent commands. Follow-up: pane-scoped chat resolution, CoderMessageList tool timeline, WS user-delta replace, and inference orphan tool_call stripping. Archive openspec v2-2; update CHANGELOG and CURRENT. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
66
apps/coder/src/services/__tests__/acp-tool-snapshot.test.ts
Normal file
66
apps/coder/src/services/__tests__/acp-tool-snapshot.test.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import {
|
||||
mergeToolSnapshot,
|
||||
mapToolLifecycleStatus,
|
||||
snapshotToWireToolCall,
|
||||
synthesizeCanceledSnapshots,
|
||||
} from '../acp-tool-snapshot.js';
|
||||
|
||||
describe('mergeToolSnapshot', () => {
|
||||
it('preserves stable toolCallId across updates', () => {
|
||||
const first = mergeToolSnapshot('tc-1', {
|
||||
toolCallId: 'tc-1',
|
||||
title: 'Read file',
|
||||
kind: 'read',
|
||||
status: 'in_progress',
|
||||
rawInput: { path: 'foo.ts' },
|
||||
});
|
||||
const merged = mergeToolSnapshot(
|
||||
'tc-1',
|
||||
{
|
||||
toolCallId: 'tc-1',
|
||||
title: 'Read file',
|
||||
status: 'completed',
|
||||
rawOutput: { content: 'hello' },
|
||||
},
|
||||
first,
|
||||
);
|
||||
expect(merged.toolCallId).toBe('tc-1');
|
||||
expect(merged.rawInput).toEqual({ path: 'foo.ts' });
|
||||
expect(merged.status).toBe('completed');
|
||||
expect(merged.rawOutput).toEqual({ content: 'hello' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('snapshotToWireToolCall', () => {
|
||||
it('embeds ACP lifecycle meta for UI merge', () => {
|
||||
const wire = snapshotToWireToolCall({
|
||||
toolCallId: 'tc-42',
|
||||
title: 'Edit',
|
||||
kind: 'edit',
|
||||
status: 'completed',
|
||||
rawInput: { path: 'a.ts' },
|
||||
rawOutput: 'ok',
|
||||
});
|
||||
expect(wire.id).toBe('tc-42');
|
||||
expect(wire.name).toBe('edit');
|
||||
expect(wire.args._acp).toMatchObject({ status: 'completed', title: 'Edit', output: 'ok' });
|
||||
});
|
||||
|
||||
it('maps synthesized cancel to canceled lifecycle', () => {
|
||||
const [canceled] = synthesizeCanceledSnapshots([
|
||||
{ toolCallId: 'tc-1', title: 'Run', status: 'in_progress' },
|
||||
]);
|
||||
const wire = snapshotToWireToolCall(canceled!);
|
||||
expect(wire.args._acp).toMatchObject({ status: 'canceled' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('mapToolLifecycleStatus', () => {
|
||||
it('maps ACP statuses to UI lifecycle', () => {
|
||||
expect(mapToolLifecycleStatus('completed')).toBe('completed');
|
||||
expect(mapToolLifecycleStatus('failed')).toBe('failed');
|
||||
expect(mapToolLifecycleStatus('in_progress')).toBe('running');
|
||||
expect(mapToolLifecycleStatus(undefined, 'canceled')).toBe('canceled');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user