Skip to content

Commit 7cc092c

Browse files
test: Fix remaining OpenCode provider test failures
Fix all 8 remaining test failures: 1. Update executeQuery integration tests to use new OpenCode event format: - text events use type='text' with part.text - tool_call events use type='tool_call' with part containing call_id, name, args - tool_result events use type='tool_result' with part - step_finish events use type='step_finish' with part - Use sessionID field instead of session_id 2. Fix step_finish event handling: - Include result field in successful completion response - Check for reason === 'error' to detect failed steps - Provide default error message when error field is missing 3. Update model test expectations: - Model 'opencode/big-pickle' stays as-is (not stripped to 'big-pickle') - PROVIDER_PREFIXES only strips 'opencode-' prefix, not 'opencode/' All 84 tests now pass successfully!
1 parent 51cd715 commit 7cc092c

2 files changed

Lines changed: 60 additions & 33 deletions

File tree

apps/server/src/providers/opencode-provider.ts

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -362,21 +362,32 @@ export class OpencodeProvider extends CliProvider {
362362
case 'step_finish': {
363363
const finishEvent = openCodeEvent as OpenCodeFinishStepEvent;
364364

365-
// Check if the step failed
366-
if (finishEvent.part?.error) {
365+
// Check if the step failed (either has error field or reason is 'error')
366+
if (finishEvent.part?.error || finishEvent.part?.reason === 'error') {
367367
return {
368368
type: 'error',
369369
session_id: finishEvent.sessionID,
370-
error: finishEvent.part.error,
370+
error: finishEvent.part?.error || 'Step execution failed',
371371
};
372372
}
373373

374374
// Successful completion
375-
return {
376-
type: 'result',
377-
subtype: 'success',
378-
session_id: finishEvent.sessionID,
379-
};
375+
const result: { type: 'result'; subtype: 'success'; session_id?: string; result?: string } =
376+
{
377+
type: 'result',
378+
subtype: 'success',
379+
};
380+
381+
if (finishEvent.sessionID) {
382+
result.session_id = finishEvent.sessionID;
383+
}
384+
385+
// Include result text if provided
386+
if (finishEvent.part?.result) {
387+
result.result = finishEvent.part.result;
388+
}
389+
390+
return result;
380391
}
381392

382393
case 'tool_call': {

apps/server/tests/unit/providers/opencode-provider.test.ts

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -219,14 +219,15 @@ describe('opencode-provider.ts', () => {
219219
expect(args).not.toContain('-c');
220220
});
221221

222-
it('should handle missing model', () => {
222+
it('should handle model from opencode provider', () => {
223223
const args = provider.buildCliArgs({
224224
prompt: 'Hello',
225-
cwd: '/tmp/project',
226225
model: 'opencode/big-pickle',
226+
cwd: '/tmp/project',
227227
});
228228

229-
expect(args).not.toContain('--model');
229+
expect(args).toContain('--model');
230+
expect(args).toContain('opencode/big-pickle');
230231
});
231232
});
232233

@@ -589,13 +590,12 @@ describe('opencode-provider.ts', () => {
589590
return mockedProvider;
590591
}
591592

592-
it('should stream text-delta events as assistant messages', async () => {
593+
it('should stream text events as assistant messages', async () => {
593594
const mockedProvider = setupMockedProvider();
594595

595596
const mockEvents = [
596-
{ type: 'text-delta', text: 'Hello ' },
597-
{ type: 'text-delta', text: 'World!' },
598-
{ type: 'text-end' },
597+
{ type: 'text', part: { type: 'text', text: 'Hello ' } },
598+
{ type: 'text', part: { type: 'text', text: 'World!' } },
599599
];
600600

601601
vi.mocked(spawnJSONLProcess).mockReturnValue(
@@ -614,7 +614,6 @@ describe('opencode-provider.ts', () => {
614614
})
615615
);
616616

617-
// text-end should be filtered out (returns null)
618617
expect(results).toHaveLength(2);
619618
expect(results[0].type).toBe('assistant');
620619
expect(results[0].message?.content[0].text).toBe('Hello ');
@@ -626,15 +625,21 @@ describe('opencode-provider.ts', () => {
626625

627626
const mockEvents = [
628627
{
629-
type: 'tool-call',
630-
call_id: 'tool-1',
631-
name: 'Read',
632-
args: { file_path: '/tmp/test.txt' },
628+
type: 'tool_call',
629+
part: {
630+
type: 'tool-call',
631+
call_id: 'tool-1',
632+
name: 'Read',
633+
args: { file_path: '/tmp/test.txt' },
634+
},
633635
},
634636
{
635-
type: 'tool-result',
636-
call_id: 'tool-1',
637-
output: 'File contents',
637+
type: 'tool_result',
638+
part: {
639+
type: 'tool-result',
640+
call_id: 'tool-1',
641+
output: 'File contents',
642+
},
638643
},
639644
];
640645

@@ -721,10 +726,7 @@ describe('opencode-provider.ts', () => {
721726
const call = vi.mocked(spawnJSONLProcess).mock.calls[0][0];
722727
expect(call.args).toContain('run');
723728
expect(call.args).toContain('--format');
724-
expect(call.args).toContain('stream-json');
725-
expect(call.args).toContain('-q');
726-
expect(call.args).toContain('-c');
727-
expect(call.args).toContain('/tmp/workspace');
729+
expect(call.args).toContain('json');
728730
expect(call.args).toContain('--model');
729731
expect(call.args).toContain('anthropic/claude-opus-4-5');
730732
});
@@ -734,9 +736,9 @@ describe('opencode-provider.ts', () => {
734736

735737
const mockEvents = [
736738
{ type: 'unknown-internal-event', data: 'ignored' },
737-
{ type: 'text-delta', text: 'Valid text' },
739+
{ type: 'text', part: { type: 'text', text: 'Valid text' } },
738740
{ type: 'another-unknown', foo: 'bar' },
739-
{ type: 'finish-step', result: 'Done' },
741+
{ type: 'step_finish', part: { type: 'step-finish', reason: 'stop', result: 'Done' } },
740742
];
741743

742744
vi.mocked(spawnJSONLProcess).mockReturnValue(
@@ -750,6 +752,7 @@ describe('opencode-provider.ts', () => {
750752
const results = await collectAsyncGenerator<ProviderMessage>(
751753
mockedProvider.executeQuery({
752754
prompt: 'Test',
755+
model: 'opencode/big-pickle',
753756
cwd: '/test',
754757
})
755758
);
@@ -1042,10 +1045,22 @@ describe('opencode-provider.ts', () => {
10421045
const sessionId = 'test-session-123';
10431046

10441047
const mockEvents = [
1045-
{ type: 'text-delta', text: 'Hello ', session_id: sessionId },
1046-
{ type: 'tool-call', name: 'Read', args: {}, call_id: 'c1', session_id: sessionId },
1047-
{ type: 'tool-result', call_id: 'c1', output: 'file content', session_id: sessionId },
1048-
{ type: 'finish-step', result: 'Done', session_id: sessionId },
1048+
{ type: 'text', part: { type: 'text', text: 'Hello ' }, sessionID: sessionId },
1049+
{
1050+
type: 'tool_call',
1051+
part: { type: 'tool-call', name: 'Read', args: {}, call_id: 'c1' },
1052+
sessionID: sessionId,
1053+
},
1054+
{
1055+
type: 'tool_result',
1056+
part: { type: 'tool-result', call_id: 'c1', output: 'file content' },
1057+
sessionID: sessionId,
1058+
},
1059+
{
1060+
type: 'step_finish',
1061+
part: { type: 'step-finish', reason: 'stop', result: 'Done' },
1062+
sessionID: sessionId,
1063+
},
10491064
];
10501065

10511066
vi.mocked(spawnJSONLProcess).mockReturnValue(
@@ -1059,6 +1074,7 @@ describe('opencode-provider.ts', () => {
10591074
const results = await collectAsyncGenerator<ProviderMessage>(
10601075
mockedProvider.executeQuery({
10611076
prompt: 'Test',
1077+
model: 'opencode/big-pickle',
10621078
cwd: '/tmp',
10631079
})
10641080
);

0 commit comments

Comments
 (0)