chore: version up to 2.80.38 and package with refined recovery
This commit is contained in:
@@ -2,6 +2,7 @@ import {
|
||||
extractVisibleFinal,
|
||||
shouldFinalOnlyRetry,
|
||||
shouldAutoContinue,
|
||||
looksCutOff,
|
||||
mergeContinuationParts,
|
||||
buildContinuationUserPrompt,
|
||||
} from '../src/core/responseRecovery';
|
||||
@@ -74,14 +75,46 @@ describe('responseRecovery.extractVisibleFinal — thought quarantine', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('responseRecovery.looksCutOff', () => {
|
||||
it('flags answers that plainly end mid-sentence / mid-structure', () => {
|
||||
expect(looksCutOff('당신은 복잡한 아이디어나 목표를 구체적인 실행 계획과 체계적인 문서화로')).toBe(true); // ends with the particle "로"
|
||||
expect(looksCutOff('우리는 이 문제를 해결하기 위해 다음과 같은 단계를')).toBe(true); // ends with object marker "를"
|
||||
expect(looksCutOff('the implementation is not yet complete and we need to')).toBe(true); // mid-English
|
||||
expect(looksCutOff('the items are: foo, bar,')).toBe(true); // trailing comma
|
||||
expect(looksCutOff('here is the code:\n```python\nprint("hi")')).toBe(true); // unclosed fence
|
||||
expect(looksCutOff('정리하면 다음 항목들이 중요합니다:\n- 첫 번째 항목\n- 두 번째 항목\n- ')).toBe(true); // dangling bullet
|
||||
});
|
||||
it('does NOT flag complete-looking answers', () => {
|
||||
expect(looksCutOff('이것은 완전히 끝난 답변이고 마침표도 붙어 있습니다.')).toBe(false);
|
||||
expect(looksCutOff('이것은 마침표 없이 끝나는 한국어 문장입니다')).toBe(false); // ends with "다" — valid
|
||||
expect(looksCutOff('네, 그렇게 하면 됩니다')).toBe(false);
|
||||
expect(looksCutOff('done.')).toBe(false);
|
||||
expect(looksCutOff('짧음')).toBe(false); // too short to judge
|
||||
});
|
||||
});
|
||||
|
||||
describe('responseRecovery.shouldAutoContinue', () => {
|
||||
it('continues only when output-limit AND a real visible answer AND near the cap', () => {
|
||||
it('continues when the engine reports the output cap was hit', () => {
|
||||
expect(shouldAutoContinue('output-limit', 'x'.repeat(200), 3500, 4096)).toBe(true);
|
||||
expect(shouldAutoContinue('output-limit', 'short', 4000, 4096)).toBe(false); // no real answer
|
||||
expect(shouldAutoContinue('output-limit', 'x'.repeat(200), 100, 4096)).toBe(false); // didn't actually hit the cap
|
||||
expect(shouldAutoContinue('complete', 'x'.repeat(200), 4000, 4096)).toBe(false);
|
||||
expect(shouldAutoContinue('output-limit', 'x'.repeat(200), 50, 4096)).toBe(true); // engine said so → trust it
|
||||
});
|
||||
it('continues when generation reached ~the cap even if the engine said "complete"', () => {
|
||||
expect(shouldAutoContinue('complete', 'x'.repeat(200), 4000, 4096)).toBe(true);
|
||||
});
|
||||
it('continues when the answer plainly ends mid-sentence (engine reason unclear)', () => {
|
||||
expect(shouldAutoContinue('unknown', '당신은 복잡한 아이디어나 목표를 구체적인 실행 계획과 체계적인 문서화로', 60, 4096)).toBe(true);
|
||||
expect(shouldAutoContinue('complete', 'the implementation continues here and we still need to', 100, 4096)).toBe(true);
|
||||
});
|
||||
it('does NOT continue from a tiny fragment or a complete-looking answer', () => {
|
||||
expect(shouldAutoContinue('output-limit', 'short', 4000, 4096)).toBe(false); // < 24 chars
|
||||
expect(shouldAutoContinue('complete', '이것은 완전히 끝난 답변이고 마침표도 붙어 있습니다.', 100, 4096)).toBe(false);
|
||||
expect(shouldAutoContinue('unknown', '이것은 마침표 없이 끝나는 한국어 문장이고 충분히 길다고 본다', 100, 4096)).toBe(false);
|
||||
});
|
||||
it('does NOT continue on stop reasons that more text cannot fix', () => {
|
||||
expect(shouldAutoContinue('context-overflow', 'x'.repeat(200), 4000, 4096)).toBe(false);
|
||||
expect(shouldAutoContinue('error', 'x'.repeat(200), 4000, 4096)).toBe(false);
|
||||
expect(shouldAutoContinue('user-stopped', 'x'.repeat(200), 4000, 4096)).toBe(false);
|
||||
expect(shouldAutoContinue('tool-calls', 'x'.repeat(200), 4000, 4096)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user