mirror of
https://github.com/stablyai/orca.git
synced 2026-11-13 17:37:40 +00:00
* fix(i18n): localize Orca's agent output and Kimi failure messages in AI text generation * fix(i18n): keep Kimi option connectives inside the translated sentence * fix(i18n): narrow Kimi empty-input diagnosis without an undefined case --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
86 lines
3.0 KiB
TypeScript
86 lines
3.0 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import { parseOpenCodeGenerationOutput } from './opencode-generation-output'
|
|
|
|
const frame = (type: string, text: string, id = 'answer'): string =>
|
|
JSON.stringify({ type, part: { id, text } })
|
|
|
|
describe('OpenCode generation event output', () => {
|
|
it('uses the final answer after a tool step', () => {
|
|
const output = [
|
|
frame('step_start', ''),
|
|
frame('text', 'I will inspect the staged diff.'),
|
|
frame('tool_use', 'git diff'),
|
|
frame('step_finish', 'tool-calls'),
|
|
frame('step_start', ''),
|
|
frame('text', 'fix: parse the final answer')
|
|
].join('\n')
|
|
expect(parseOpenCodeGenerationOutput(output)).toEqual({
|
|
ok: true,
|
|
text: 'fix: parse the final answer'
|
|
})
|
|
})
|
|
it('keeps assistant text and ignores tool, reasoning, progress and warning events', () => {
|
|
const output = [
|
|
frame('step_start', 'starting'),
|
|
frame('reasoning', 'reasoning'),
|
|
frame('tool_use', 'git diff output'),
|
|
JSON.stringify({ type: 'warning', message: 'notice' }),
|
|
frame('text', 'fix: generate messages'),
|
|
frame('step_finish', 'done')
|
|
].join('\n')
|
|
expect(parseOpenCodeGenerationOutput(output)).toEqual({
|
|
ok: true,
|
|
text: 'fix: generate messages'
|
|
})
|
|
})
|
|
|
|
it('replaces repeated parts and preserves multiple answer parts', () => {
|
|
expect(
|
|
parseOpenCodeGenerationOutput(
|
|
[frame('text', 'partial'), frame('text', 'subject'), frame('text', 'body', 'body')].join(
|
|
'\r\n'
|
|
)
|
|
)
|
|
).toEqual({ ok: true, text: 'subject\nbody' })
|
|
})
|
|
|
|
it.each([
|
|
{ name: 'UnknownError', data: { message: 'Model unavailable' } },
|
|
{ type: 'provider.no-route', message: 'Unsupported package' }
|
|
])('reports errors instead of accepting a partial answer', (error) => {
|
|
const output = `${frame('text', 'partial')}\n${JSON.stringify({ type: 'error', error })}`
|
|
expect(parseOpenCodeGenerationOutput(output)).toEqual({
|
|
ok: false,
|
|
error: error.message ?? error.data?.message
|
|
})
|
|
})
|
|
|
|
it.each([
|
|
{ error: { name: 'MessageOutputLengthError', data: {} }, expected: 'MessageOutputLengthError' },
|
|
{
|
|
error: { name: 'ProviderError', data: { retryable: false } },
|
|
expected: 'ProviderError'
|
|
},
|
|
{
|
|
error: { name: 'ProviderError', message: 'Provider rejected the request', data: {} },
|
|
expected: 'Provider rejected the request'
|
|
}
|
|
])('reports named errors without a data message', ({ error, expected }) => {
|
|
const output = `${frame('text', 'partial')}\n${JSON.stringify({ type: 'error', error })}`
|
|
expect(parseOpenCodeGenerationOutput(output)).toEqual({ ok: false, error: expected })
|
|
})
|
|
|
|
it.each([
|
|
'{broken',
|
|
'{"title":"not an event"}',
|
|
'null',
|
|
JSON.stringify({ type: 'error', error: { name: 'ProviderError', data: { message: 42 } } })
|
|
])('rejects malformed events %s', (output) => {
|
|
expect(parseOpenCodeGenerationOutput(output)).toEqual({
|
|
ok: false,
|
|
error: 'OpenCode returned invalid JSON events.',
|
|
errorCode: 'openCodeInvalidEvents'
|
|
})
|
|
})
|
|
})
|