feat: post-review backlog hardening (cancel/parser/stall/history/9502)
Five independent items from the post-review backlog. F1: Stop on an external agent task now aborts the running child via a per-task AbortController registry reachable from the cancel route, and finalizes the assistant message as cancelled (fixing two latent bugs — catch blocks left the message streaming, and warm success-paths wrote complete on an aborted turn); warm pools/worktrees are preserved and the native path is unchanged. F2/F3: prune the tool-call parser to its two load-bearing exports (unexport eight zero-caller symbols, add a gate test for the <invoke>-as-text fallback) and route placeholder-rejection logging through pino. F6: a 90s per-chunk stall-timeout wraps native inference's fullStream via AbortSignal.any so a hung stream finalizes the message instead of hanging — no retry (a pure classifyStreamError helper is added). F7: a read-only view_session_history MCP tool (newest-N, chronological). F9: retire the unused apps/coder/web :9502 fallback SPA, keeping every API/WS/health/MCP route.
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { classifyStreamError } from '../inference/stream-error-classifier.js';
|
||||
|
||||
describe('classifyStreamError', () => {
|
||||
it("classifies AbortError as 'stall'", () => {
|
||||
const err = new Error('aborted');
|
||||
err.name = 'AbortError';
|
||||
expect(classifyStreamError(err)).toBe('stall');
|
||||
});
|
||||
|
||||
it("classifies a 503 HTTP error as 'transient'", () => {
|
||||
const err = Object.assign(new Error('Service Unavailable'), { status: 503 });
|
||||
expect(classifyStreamError(err)).toBe('transient');
|
||||
});
|
||||
|
||||
it("classifies a 500 HTTP error as 'transient'", () => {
|
||||
const err = Object.assign(new Error('Internal Server Error'), { status: 500 });
|
||||
expect(classifyStreamError(err)).toBe('transient');
|
||||
});
|
||||
|
||||
it("classifies a 4xx HTTP error as 'non-retryable'", () => {
|
||||
const err = Object.assign(new Error('Bad Request'), { status: 400 });
|
||||
expect(classifyStreamError(err)).toBe('non-retryable');
|
||||
});
|
||||
|
||||
it("classifies a generic Error as 'non-retryable'", () => {
|
||||
expect(classifyStreamError(new Error('something went wrong'))).toBe('non-retryable');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user