Files
dev/third_party/pi/packages/coding-agent/test/interactive-mode-bug-report-hint.test.ts
alexion 6081e3e325 chore(vendor): import pi 1.3.0
Imported as a linear vendor commit so forge rebases do not replay the upstream root tree.

git-subtree-dir: third_party/pi

git-subtree-split: 71023aec1546d6d677a65669c5665c0927ce0dd0
2026-10-15 17:58:48 -04:00

72 lines
2.8 KiB
TypeScript

import { type AssistantMessage, fauxAssistantMessage } from "@earendil-works/pi-ai";
import { describe, expect, test, vi } from "vitest";
import { formatCrashExtensionHint, InteractiveMode } from "../src/modes/interactive/interactive-mode.ts";
type BugReportHintContext = {
suggestBugReport(): void;
maybeShowInstallChangeWarning(): boolean;
};
const maybeSuggestBugReport = Reflect.get(InteractiveMode.prototype, "maybeSuggestBugReport") as (
this: BugReportHintContext,
message: AssistantMessage,
) => void;
function errorMessage(errorMessage: string): AssistantMessage {
return fauxAssistantMessage("", { stopReason: "error", errorMessage });
}
describe("InteractiveMode bug report hints", () => {
test("identifies extensions with frames in a crash stack", () => {
expect(formatCrashExtensionHint(["npm:pi-observational-memory"])).toBe(
"A stack frame came from loaded extension `npm:pi-observational-memory`, which may be involved. Try disabling it with `pi config`, or run `pi -ne` to confirm.",
);
expect(formatCrashExtensionHint(undefined)).toBeUndefined();
});
test("does not suggest reports for retryable provider failures", () => {
const context = { suggestBugReport: vi.fn(), maybeShowInstallChangeWarning: vi.fn(() => false) };
const failures = [
"500 Internal Server Error",
"502 Bad Gateway",
"503 Service Unavailable",
"504 Gateway Timeout",
"429 Too Many Requests",
"Provider overloaded",
"Network connection lost",
"Request timed out",
];
for (const failure of failures) maybeSuggestBugReport.call(context, errorMessage(failure));
expect(context.suggestBugReport).not.toHaveBeenCalled();
});
test("does not suggest reports for cancellations", () => {
const context = { suggestBugReport: vi.fn(), maybeShowInstallChangeWarning: vi.fn(() => false) };
maybeSuggestBugReport.call(context, errorMessage("This operation was aborted"));
maybeSuggestBugReport.call(context, errorMessage("Request cancelled"));
maybeSuggestBugReport.call(context, fauxAssistantMessage("", { stopReason: "aborted" }));
expect(context.suggestBugReport).not.toHaveBeenCalled();
});
test("suggests reports for unexpected errors", () => {
const context = { suggestBugReport: vi.fn(), maybeShowInstallChangeWarning: vi.fn(() => false) };
maybeSuggestBugReport.call(context, errorMessage("Unexpected internal state"));
expect(context.suggestBugReport).toHaveBeenCalledOnce();
});
test("shows the install change warning instead of a bug report hint", () => {
const context = { suggestBugReport: vi.fn(), maybeShowInstallChangeWarning: vi.fn(() => true) };
maybeSuggestBugReport.call(context, errorMessage("Cannot find module './worker.js'"));
expect(context.maybeShowInstallChangeWarning).toHaveBeenCalledOnce();
expect(context.suggestBugReport).not.toHaveBeenCalled();
});
});