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
This commit is contained in:
2026-10-15 17:58:48 -04:00
parent 719370c8f7
commit 6081e3e325
1743 changed files with 205460 additions and 131705 deletions

View File

@@ -3,18 +3,12 @@ import { describe, expect, it } from "vitest";
import { streamSimple as streamSimpleGoogle } from "../src/api/google-generative-ai.ts";
import { resolveGoogleThinkingLevel } from "../src/api/google-shared.ts";
import { streamSimple as streamSimpleVertex } from "../src/api/google-vertex.ts";
import type {
Context,
Model,
ModelThinkingLevel,
ThinkingBudgets,
ThinkingLevel,
ThinkingLevelMap,
} from "../src/types.ts";
import type { Model, ThinkingBudgets, ThinkingLevel, ThinkingLevelMap } from "../src/types.ts";
import { normalizeContext } from "../src/utils/transcript.ts";
const context: Context = {
const context = normalizeContext({
messages: [{ role: "user", content: "Hello", timestamp: 0 }],
};
});
function googleModel(id: string, thinkingLevelMap: ThinkingLevelMap): Model<"google-generative-ai"> {
return {
@@ -50,7 +44,7 @@ function vertexModel(id: string, thinkingLevelMap: ThinkingLevelMap): Model<"goo
async function captureGooglePayload(
model: Model<"google-generative-ai">,
reasoning: ThinkingLevel,
reasoning?: ThinkingLevel,
thinkingBudgets?: ThinkingBudgets,
): Promise<GenerateContentParameters> {
let payload: GenerateContentParameters | undefined;
@@ -71,7 +65,7 @@ async function captureGooglePayload(
async function captureVertexPayload(
model: Model<"google-vertex">,
reasoning: ThinkingLevel,
reasoning?: ThinkingLevel,
thinkingBudgets?: ThinkingBudgets,
): Promise<GenerateContentParameters> {
let payload: GenerateContentParameters | undefined;
@@ -90,19 +84,29 @@ async function captureVertexPayload(
return payload;
}
const googleAdapters = [
{
name: "Google Generative AI",
capture: (id: string, thinkingLevelMap: ThinkingLevelMap, reasoning?: ThinkingLevel) =>
captureGooglePayload(googleModel(id, thinkingLevelMap), reasoning),
},
{
name: "Google Vertex",
capture: (id: string, thinkingLevelMap: ThinkingLevelMap, reasoning?: ThinkingLevel) =>
captureVertexPayload(vertexModel(id, thinkingLevelMap), reasoning),
},
] as const;
describe("Google thinking level maps", () => {
it("exhaustively resolves supported logical levels and mapping values", () => {
const defaultExpectations = {
off: "high",
minimal: "minimal",
low: "low",
medium: "medium",
high: "high",
} as const satisfies Partial<Record<ModelThinkingLevel, ThinkingLevel>>;
} as const satisfies Partial<Record<ThinkingLevel, ThinkingLevel>>;
for (const [level, expected] of Object.entries(defaultExpectations)) {
expect(resolveGoogleThinkingLevel(googleModel("gemini-3.7-flash", {}), level as ModelThinkingLevel)).toBe(
expected,
);
expect(resolveGoogleThinkingLevel(googleModel("gemini-3.7-flash", {}), level as ThinkingLevel)).toBe(expected);
}
const mappedExpectations = {
@@ -131,6 +135,44 @@ describe("Google thinking level maps", () => {
);
});
// Regression test for https://github.com/earendil-works/pi/issues/9455
it.each(googleAdapters)("uses the lowest supported $name level when reasoning is omitted", async ({ capture }) => {
const payload = await capture("gemini-3.8-flash", {
off: null,
minimal: null,
low: "low",
medium: "medium",
high: "high",
xhigh: null,
max: null,
});
expect(payload.config?.thinkingConfig).toEqual({ thinkingLevel: "LOW" });
});
it.each(googleAdapters)("preserves native medium effort for Gemini 3.1 Pro on $name", async ({ capture }) => {
const payload = await capture(
"gemini-3.1-pro-preview",
{ off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: null, max: null },
"medium",
);
expect(payload.config?.thinkingConfig).toEqual({ includeThoughts: true, thinkingLevel: "MEDIUM" });
});
it.each(googleAdapters)("disables Gemini 2.5 thinking when reasoning is omitted on $name", async ({ capture }) => {
const payload = await capture("gemini-2.5-flash", {});
expect(payload.config?.thinkingConfig).toEqual({ thinkingBudget: 0 });
});
// Regression test for https://github.com/earendil-works/pi/issues/10890
it.each(googleAdapters)("uses thinking levels for Gemini 4 models on $name", async ({ capture }) => {
const payload = await capture("gemini-4-argon", {}, "medium");
expect(payload.config?.thinkingConfig).toEqual({ includeThoughts: true, thinkingLevel: "MEDIUM" });
});
it.each(["xhigh", "max"] as const)("maps Google Generative AI %s to a supported level", async (reasoning) => {
const payload = await captureGooglePayload(
googleModel("gemini-3.7-flash", { xhigh: "high", max: "high" }),