takt: github-issue-238-fix-opencode (#240)

This commit is contained in:
nrs 2026-02-11 15:26:12 +09:00 committed by GitHub
parent 4fb058aa6a
commit 9f1c7e6aff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 72 additions and 6 deletions

View File

@ -218,7 +218,7 @@ describe('OpenCodeClient stream cleanup', () => {
); );
}); });
it('should fail fast when question.asked is received without handler', async () => { it('should reject question.asked without handler and continue processing', async () => {
const { OpenCodeClient } = await import('../infra/opencode/client.js'); const { OpenCodeClient } = await import('../infra/opencode/client.js');
const stream = new MockEventStream([ const stream = new MockEventStream([
{ {
@ -235,6 +235,17 @@ describe('OpenCodeClient stream cleanup', () => {
], ],
}, },
}, },
{
type: 'message.part.updated',
properties: {
part: { id: 'p-q1', type: 'text', text: 'continued response' },
delta: 'continued response',
},
},
{
type: 'session.idle',
properties: { sessionID: 'session-4' },
},
]); ]);
const promptAsync = vi.fn().mockResolvedValue(undefined); const promptAsync = vi.fn().mockResolvedValue(undefined);
@ -260,8 +271,8 @@ describe('OpenCodeClient stream cleanup', () => {
model: 'opencode/big-pickle', model: 'opencode/big-pickle',
}); });
expect(result.status).toBe('error'); expect(result.status).toBe('done');
expect(result.content).toContain('no question handler'); expect(result.content).toBe('continued response');
expect(questionReject).toHaveBeenCalledWith( expect(questionReject).toHaveBeenCalledWith(
{ {
requestID: 'q-1', requestID: 'q-1',

View File

@ -12,6 +12,7 @@ import {
emitToolResult, emitToolResult,
emitResult, emitResult,
handlePartUpdated, handlePartUpdated,
type OpenCodeStreamEvent,
type OpenCodeTextPart, type OpenCodeTextPart,
type OpenCodeReasoningPart, type OpenCodeReasoningPart,
type OpenCodeToolPart, type OpenCodeToolPart,
@ -351,3 +352,35 @@ describe('handlePartUpdated', () => {
handlePartUpdated(part, 'Hello', undefined, state); handlePartUpdated(part, 'Hello', undefined, state);
}); });
}); });
describe('OpenCodeStreamEvent typing', () => {
it('should accept message.completed event shape', () => {
const event: OpenCodeStreamEvent = {
type: 'message.completed',
properties: {
info: {
sessionID: 'session-1',
role: 'assistant',
error: undefined,
},
},
};
expect(event.type).toBe('message.completed');
});
it('should accept message.failed event shape', () => {
const event: OpenCodeStreamEvent = {
type: 'message.failed',
properties: {
info: {
sessionID: 'session-2',
role: 'assistant',
error: { message: 'failed' },
},
},
};
expect(event.type).toBe('message.failed');
});
});

View File

@ -75,6 +75,28 @@ export interface OpenCodeMessageUpdatedEvent {
}; };
} }
export interface OpenCodeMessageCompletedEvent {
type: 'message.completed';
properties: {
info: {
sessionID: string;
role: 'assistant' | 'user';
error?: unknown;
};
};
}
export interface OpenCodeMessageFailedEvent {
type: 'message.failed';
properties: {
info: {
sessionID: string;
role: 'assistant' | 'user';
error?: unknown;
};
};
}
export interface OpenCodePermissionAskedEvent { export interface OpenCodePermissionAskedEvent {
type: 'permission.asked'; type: 'permission.asked';
properties: { properties: {
@ -107,6 +129,8 @@ export interface OpenCodeQuestionAskedEvent {
export type OpenCodeStreamEvent = export type OpenCodeStreamEvent =
| OpenCodeMessagePartUpdatedEvent | OpenCodeMessagePartUpdatedEvent
| OpenCodeMessageUpdatedEvent | OpenCodeMessageUpdatedEvent
| OpenCodeMessageCompletedEvent
| OpenCodeMessageFailedEvent
| OpenCodeSessionStatusEvent | OpenCodeSessionStatusEvent
| OpenCodeSessionIdleEvent | OpenCodeSessionIdleEvent
| OpenCodeSessionErrorEvent | OpenCodeSessionErrorEvent

View File

@ -411,9 +411,7 @@ export class OpenCodeClient {
OPENCODE_INTERACTION_TIMEOUT_MS, OPENCODE_INTERACTION_TIMEOUT_MS,
'OpenCode question reject timed out', 'OpenCode question reject timed out',
); );
success = false; continue;
failureMessage = 'OpenCode asked a question, but no question handler is configured';
break;
} }
try { try {