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:
alexion committed 2026-10-15 17:58:48 -04:00
1 parent 719370c8f7
commit 6081e3e325
1743 files changed
+205459 -131704

No files matched your search

+83 -10
View File
@@ -2,9 +2,9 @@ import { afterEach, beforeEach, describe, expect, it } from "vitest";
import { stream as streamAnthropic } from "../src/api/anthropic-messages.ts";
import { stream as streamOpenAICompletions } from "../src/api/openai-completions.ts";
import { stream as streamOpenAIResponses } from "../src/api/openai-responses.ts";
import { getModel, stream } from "../src/compat.ts";
import { getModel, normalizeContext, stream } from "../src/compat.ts";
import { MODELS } from "../src/models.generated.ts";
import type { Context, Model } from "../src/types.ts";
import type { Model } from "../src/types.ts";
class PayloadCaptured extends Error {
constructor() {
@@ -44,10 +44,10 @@ describe("Cache Retention (PI_CACHE_RETENTION)", () => {
}
});
const context: Context = {
const context = normalizeContext({
systemPrompt: "You are a helpful assistant.",
messages: [{ role: "user", content: "Hello", timestamp: Date.now() }],
};
});
describe("Anthropic Provider", () => {
it.skipIf(!process.env.ANTHROPIC_API_KEY)(
@@ -240,6 +240,13 @@ describe("Cache Retention (PI_CACHE_RETENTION)", () => {
});
describe("OpenAI Responses Provider", () => {
it.each(["gpt-5.6-luna", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-6-astra", "gpt-6-luna", "gpt-6-sol"] as const)(
"does not enable cache warming from the documented TTL alone for %s",
(modelId) => {
expect(getModel("openai", modelId).promptCache).toBeUndefined();
},
);
it.skipIf(!process.env.OPENAI_API_KEY)(
"should not set prompt_cache_retention when PI_CACHE_RETENTION is not set",
async () => {
@@ -299,7 +306,7 @@ describe("Cache Retention (PI_CACHE_RETENTION)", () => {
try {
const s = streamOpenAIResponses(proxyModel, context, {
apiKey: "fake-key",
apiKey: "sk-fake-key",
onPayload: stopAfterPayload((payload) => {
capturedPayload = payload;
}),
@@ -326,7 +333,7 @@ describe("Cache Retention (PI_CACHE_RETENTION)", () => {
try {
const s = streamOpenAIResponses(model, context, {
apiKey: "fake-key",
apiKey: "sk-fake-key",
cacheRetention: "long",
sessionId: "session-compat-false",
onPayload: stopAfterPayload((payload) => {
@@ -351,7 +358,7 @@ describe("Cache Retention (PI_CACHE_RETENTION)", () => {
try {
const s = streamOpenAIResponses(model, context, {
apiKey: "fake-key",
apiKey: "sk-fake-key",
cacheRetention: "none",
sessionId: "session-1",
onPayload: stopAfterPayload<OpenAIResponsesCachePayload>((payload) => {
@@ -378,7 +385,7 @@ describe("Cache Retention (PI_CACHE_RETENTION)", () => {
try {
const s = streamOpenAIResponses(model, context, {
apiKey: "fake-key",
apiKey: "sk-fake-key",
cacheRetention: "none",
sessionId: "session-1",
onPayload: stopAfterPayload<OpenAIResponsesCachePayload>((payload) => {
@@ -401,13 +408,15 @@ describe("Cache Retention (PI_CACHE_RETENTION)", () => {
it.each([
["gpt-4o-mini", "24h", undefined],
["gpt-6-astra", undefined, { ttl: "30m" }],
["gpt-6-sol", undefined, { ttl: "30m" }],
["gpt-6-luna", undefined, { ttl: "30m" }],
] as const)("should use the supported long cache field for %s", async (modelId, retention, cacheOptions) => {
const model = getModel("openai", modelId);
let capturedPayload: OpenAIResponsesCachePayload | undefined;
try {
const s = streamOpenAIResponses(model, context, {
apiKey: "fake-key",
apiKey: "sk-fake-key",
cacheRetention: "long",
sessionId: "session-2",
onPayload: stopAfterPayload<OpenAIResponsesCachePayload>((payload) => {
@@ -501,7 +510,6 @@ describe("Cache Retention (PI_CACHE_RETENTION)", () => {
MODELS.opencode["kimi-k2.5"],
MODELS.opencode["kimi-k2.6"],
MODELS.opencode["minimax-m2.7"],
MODELS["opencode-go"]["kimi-k2.6"],
] as const)("should omit long cache retention for $provider/$id", async (metadata) => {
const model = metadata as Model<"openai-completions">;
let capturedPayload: OpenAICompletionsCachePayload | undefined;
@@ -528,5 +536,70 @@ describe("Cache Retention (PI_CACHE_RETENTION)", () => {
expect(capturedPayload?.prompt_cache_key).toBeUndefined();
expect(capturedPayload?.prompt_cache_retention).toBeUndefined();
});
it.each([MODELS.cerebras["gpt-oss-120b"], MODELS.cerebras["qwen-3.8-27b"]] as const)(
"should omit strict field on tools for cerebras/$id",
async (metadata) => {
const model = metadata as Model<"openai-completions">;
const contextWithTools = {
messages: [
{
role: "system" as const,
content: "test",
toolsAdded: [
{
name: "t1",
description: "strict tool",
parameters: {
type: "object" as const,
properties: { x: { type: "string" } },
required: ["x"],
},
constrainedSampling: { type: "json_schema" as const },
},
{
name: "t2",
description: "non-strict tool",
parameters: {
type: "object" as const,
properties: { y: { type: "string" } },
required: ["y"],
},
},
],
timestamp: 0,
},
{ role: "user" as const, content: "hello", timestamp: 1 },
],
};
let capturedPayload: any;
try {
const s = streamOpenAICompletions(model, contextWithTools as any, {
apiKey: "fake-key",
sessionId: "test",
onPayload: stopAfterPayload((payload: any) => {
capturedPayload = payload;
}),
});
for await (const event of s) {
if (event.type === "error") break;
}
} catch {
// Expected to fail
}
expect(model.compat?.supportsStrictMode).toBeUndefined();
expect(capturedPayload).toBeDefined();
const tools = capturedPayload?.tools as any[] | undefined;
expect(tools).toBeDefined();
for (const tool of tools!) {
expect(tool.function).not.toHaveProperty("strict");
}
},
);
});
});