Files
dev/third_party/pi/packages/ai/test/mistral-raw-stop-reason.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.2 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { stream as streamMistral } from "../src/api/mistral-conversations.ts";
import { getModel, normalizeContext } from "../src/compat.ts";
import type { FetchFunction } from "../src/types.ts";
import { isRetryableAssistantError } from "../src/utils/retry.ts";
const model = getModel("mistral", "devstral-medium-latest");
const context = normalizeContext({
messages: [{ role: "user", content: "hello", timestamp: Date.now() }],
});
function createFetch(finishReason: string): FetchFunction {
return async () =>
new Response(
`data: ${JSON.stringify({
id: "mistral-response-id",
model: model.id,
choices: [
{
index: 0,
finish_reason: finishReason,
delta: {},
},
],
usage: {
prompt_tokens: 1,
completion_tokens: 0,
total_tokens: 1,
},
})}\n\ndata: [DONE]\n\n`,
{ headers: { "content-type": "text/event-stream" } },
);
}
describe("Mistral raw stop reasons", () => {
it("preserves raw Mistral finish reasons for successful stops", async () => {
const message = await streamMistral(model, context, {
apiKey: "test",
fetch: createFetch("stop"),
}).result();
expect(message.stopReason).toBe("stop");
expect(message.rawStopReason).toBe("stop");
expect(message.errorMessage).toBeUndefined();
});
it("preserves raw Mistral finish reasons for provider error stops", async () => {
const message = await streamMistral(model, context, {
apiKey: "test",
fetch: createFetch("error"),
}).result();
expect(message.stopReason).toBe("error");
expect(message.rawStopReason).toBe("error");
expect(message.errorMessage).toBe("Provider stopped with: error (server error)");
// #10487
expect(isRetryableAssistantError(message)).toBe(true);
});
it("treats unknown Mistral finish reasons as provider error stops", async () => {
const message = await streamMistral(model, context, {
apiKey: "test",
fetch: createFetch("unmapped_error"),
}).result();
expect(message.stopReason).toBe("error");
expect(message.rawStopReason).toBe("unmapped_error");
expect(message.errorMessage).toBe("Provider stopped with: unmapped_error");
expect(isRetryableAssistantError(message)).toBe(false);
});
});