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:
1 parent
719370c8f7
commit
6081e3e325
1743 files changed
+205459
-131704
No files matched your search
+79
-68
@@ -1,7 +1,7 @@
|
||||
import { Type } from "typebox";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { stream as streamOpenAIResponses } from "../src/api/openai-responses.ts";
|
||||
import { getModel } from "../src/compat.ts";
|
||||
import { getModel, normalizeContext } from "../src/compat.ts";
|
||||
import type { Model } from "../src/types.ts";
|
||||
|
||||
type CapturedHeaders = Headers | string[][] | Record<string, string | readonly string[]> | undefined;
|
||||
@@ -53,11 +53,11 @@ async function captureOpenAIResponseHeaders(
|
||||
|
||||
const stream = streamOpenAIResponses(
|
||||
model,
|
||||
{
|
||||
normalizeContext({
|
||||
systemPrompt: "sys",
|
||||
messages: [{ role: "user", content: "hi", timestamp: Date.now() }],
|
||||
},
|
||||
{ apiKey: "test-key", ...options },
|
||||
}),
|
||||
{ apiKey: "sk-test-key", ...options },
|
||||
);
|
||||
|
||||
for await (const event of stream) {
|
||||
@@ -85,12 +85,12 @@ describe("openai-responses provider defaults", () => {
|
||||
|
||||
const stream = streamOpenAIResponses(
|
||||
model,
|
||||
{
|
||||
normalizeContext({
|
||||
systemPrompt: "sys",
|
||||
messages: [{ role: "user", content: "hi", timestamp: Date.now() }],
|
||||
},
|
||||
}),
|
||||
{
|
||||
apiKey: "test-key",
|
||||
apiKey: "sk-test-key",
|
||||
onPayload: (payload) => {
|
||||
capturedPayload = payload;
|
||||
},
|
||||
@@ -119,7 +119,7 @@ describe("openai-responses provider defaults", () => {
|
||||
|
||||
const stream = streamOpenAIResponses(
|
||||
getModel("openai", "gpt-5.4"),
|
||||
{
|
||||
normalizeContext({
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
@@ -134,9 +134,9 @@ describe("openai-responses provider defaults", () => {
|
||||
parameters: Type.Object({ value: Type.String() }),
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
{
|
||||
apiKey: "test-key",
|
||||
apiKey: "sk-test-key",
|
||||
toolChoice: "required",
|
||||
onPayload: (payload) => {
|
||||
capturedPayload = payload;
|
||||
@@ -167,7 +167,7 @@ describe("openai-responses provider defaults", () => {
|
||||
|
||||
const stream = streamOpenAIResponses(
|
||||
model,
|
||||
{
|
||||
normalizeContext({
|
||||
messages: [{ role: "user", content: "Use a tool.", timestamp: Date.now() }],
|
||||
tools: [
|
||||
{
|
||||
@@ -185,9 +185,9 @@ describe("openai-responses provider defaults", () => {
|
||||
constrainedSampling: { type: "json_schema", strict: "prefer" },
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
{
|
||||
apiKey: "test-key",
|
||||
apiKey: "sk-test-key",
|
||||
onPayload: (payload) => {
|
||||
capturedPayload = payload as CapturedResponsesPayload;
|
||||
},
|
||||
@@ -216,6 +216,8 @@ describe("openai-responses provider defaults", () => {
|
||||
"gpt-5.6-sol",
|
||||
"gpt-5.6-terra",
|
||||
"gpt-5.6-luna",
|
||||
"gpt-6-sol",
|
||||
"gpt-6-luna",
|
||||
] as const)("sends none reasoning effort for OpenAI %s when no reasoning is requested", async (modelId) => {
|
||||
const model = getModel("openai", modelId);
|
||||
let capturedPayload: unknown;
|
||||
@@ -229,12 +231,12 @@ describe("openai-responses provider defaults", () => {
|
||||
|
||||
const stream = streamOpenAIResponses(
|
||||
model,
|
||||
{
|
||||
normalizeContext({
|
||||
systemPrompt: "sys",
|
||||
messages: [{ role: "user", content: "hi", timestamp: Date.now() }],
|
||||
},
|
||||
}),
|
||||
{
|
||||
apiKey: "test-key",
|
||||
apiKey: "sk-test-key",
|
||||
onPayload: (payload) => {
|
||||
capturedPayload = payload;
|
||||
},
|
||||
@@ -265,12 +267,12 @@ describe("openai-responses provider defaults", () => {
|
||||
|
||||
const stream = streamOpenAIResponses(
|
||||
model,
|
||||
{
|
||||
normalizeContext({
|
||||
systemPrompt: "sys",
|
||||
messages: [{ role: "user", content: "hi", timestamp: Date.now() }],
|
||||
},
|
||||
}),
|
||||
{
|
||||
apiKey: "test-key",
|
||||
apiKey: "sk-test-key",
|
||||
onPayload: (payload) => {
|
||||
capturedPayload = payload;
|
||||
},
|
||||
@@ -306,12 +308,12 @@ describe("openai-responses provider defaults", () => {
|
||||
|
||||
const stream = streamOpenAIResponses(
|
||||
getModel("openai", "gpt-5.4"),
|
||||
{
|
||||
normalizeContext({
|
||||
systemPrompt: "sys",
|
||||
messages: [{ role: "user", content: "hi", timestamp: Date.now() }],
|
||||
},
|
||||
}),
|
||||
{
|
||||
apiKey: "test-key",
|
||||
apiKey: "sk-test-key",
|
||||
sessionId,
|
||||
onPayload: (payload) => {
|
||||
capturedPayload = payload as Pick<CapturedResponsesPayload, "prompt_cache_key">;
|
||||
@@ -476,51 +478,60 @@ describe("openai-responses provider defaults", () => {
|
||||
});
|
||||
|
||||
it.each([
|
||||
["gpt-5.4", "priority", 2],
|
||||
["gpt-5.5", "priority", 2.5],
|
||||
["gpt-5.5", "flex", 0.5],
|
||||
] as const)("applies %s %s service-tier cost multiplier", async (modelId, serviceTier, multiplier) => {
|
||||
const model = getModel("openai", modelId);
|
||||
const tokenCount = 100_000;
|
||||
const tokenScale = tokenCount / 1_000_000;
|
||||
const sse = `${[
|
||||
`data: ${JSON.stringify({
|
||||
type: "response.completed",
|
||||
response: {
|
||||
status: "completed",
|
||||
service_tier: serviceTier,
|
||||
usage: {
|
||||
input_tokens: tokenCount,
|
||||
output_tokens: tokenCount,
|
||||
total_tokens: tokenCount * 2,
|
||||
input_tokens_details: { cached_tokens: 0 },
|
||||
["gpt-5.4", "priority", "priority", 2],
|
||||
["gpt-5.5", "priority", "priority", 2.5],
|
||||
["gpt-5.5", "flex", "flex", 0.5],
|
||||
// GPT-6 models report Fast mode as "fast" even when "priority" is requested (#10034)
|
||||
["gpt-6-luna", "priority", "fast", 2],
|
||||
["gpt-6-luna", "fast", "fast", 2],
|
||||
] as const)(
|
||||
"applies %s cost multiplier for requested %s and returned %s service tier",
|
||||
async (modelId, serviceTier, responseServiceTier, multiplier) => {
|
||||
const model = getModel("openai", modelId);
|
||||
const tokenCount = 100_000;
|
||||
const tokenScale = tokenCount / 1_000_000;
|
||||
const sse = `${[
|
||||
`data: ${JSON.stringify({
|
||||
type: "response.completed",
|
||||
response: {
|
||||
status: "completed",
|
||||
service_tier: responseServiceTier,
|
||||
usage: {
|
||||
input_tokens: tokenCount,
|
||||
output_tokens: tokenCount,
|
||||
total_tokens: tokenCount * 2,
|
||||
input_tokens_details: { cached_tokens: 0 },
|
||||
},
|
||||
},
|
||||
},
|
||||
})}`,
|
||||
].join("\n\n")}\n\n`;
|
||||
})}`,
|
||||
].join("\n\n")}\n\n`;
|
||||
|
||||
vi.spyOn(globalThis, "fetch").mockResolvedValue(
|
||||
new Response(sse, {
|
||||
status: 200,
|
||||
headers: { "content-type": "text/event-stream" },
|
||||
}),
|
||||
);
|
||||
vi.spyOn(globalThis, "fetch").mockResolvedValue(
|
||||
new Response(sse, {
|
||||
status: 200,
|
||||
headers: { "content-type": "text/event-stream" },
|
||||
}),
|
||||
);
|
||||
|
||||
const stream = streamOpenAIResponses(
|
||||
model,
|
||||
{
|
||||
systemPrompt: "sys",
|
||||
messages: [{ role: "user", content: "hi", timestamp: Date.now() }],
|
||||
},
|
||||
{ apiKey: "test-key", serviceTier },
|
||||
);
|
||||
const stream = streamOpenAIResponses(
|
||||
model,
|
||||
normalizeContext({
|
||||
systemPrompt: "sys",
|
||||
messages: [{ role: "user", content: "hi", timestamp: Date.now() }],
|
||||
}),
|
||||
{ apiKey: "sk-test-key", serviceTier },
|
||||
);
|
||||
|
||||
const result = await stream.result();
|
||||
const result = await stream.result();
|
||||
|
||||
expect(result.usage.cost.input).toBe(model.cost.input * multiplier * tokenScale);
|
||||
expect(result.usage.cost.output).toBe(model.cost.output * multiplier * tokenScale);
|
||||
expect(result.usage.cost.total).toBe((model.cost.input + model.cost.output) * multiplier * tokenScale);
|
||||
});
|
||||
expect(result.usage.cost.input).toBeCloseTo(model.cost.input * multiplier * tokenScale, 12);
|
||||
expect(result.usage.cost.output).toBeCloseTo(model.cost.output * multiplier * tokenScale, 12);
|
||||
expect(result.usage.cost.total).toBeCloseTo(
|
||||
(model.cost.input + model.cost.output) * multiplier * tokenScale,
|
||||
12,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe("openai-responses max_output_tokens compat", () => {
|
||||
@@ -540,12 +551,12 @@ describe("openai-responses max_output_tokens compat", () => {
|
||||
|
||||
const stream = streamOpenAIResponses(
|
||||
getModel("openai", "gpt-5.4"),
|
||||
{
|
||||
normalizeContext({
|
||||
systemPrompt: "sys",
|
||||
messages: [{ role: "user", content: "hi", timestamp: Date.now() }],
|
||||
},
|
||||
}),
|
||||
{
|
||||
apiKey: "test-key",
|
||||
apiKey: "sk-test-key",
|
||||
maxTokens: 1024,
|
||||
onPayload: (payload) => {
|
||||
capturedPayload = payload as { max_output_tokens?: number };
|
||||
@@ -577,12 +588,12 @@ describe("openai-responses max_output_tokens compat", () => {
|
||||
|
||||
const stream = streamOpenAIResponses(
|
||||
model,
|
||||
{
|
||||
normalizeContext({
|
||||
systemPrompt: "sys",
|
||||
messages: [{ role: "user", content: "hi", timestamp: Date.now() }],
|
||||
},
|
||||
}),
|
||||
{
|
||||
apiKey: "test-key",
|
||||
apiKey: "sk-test-key",
|
||||
maxTokens: 1024,
|
||||
onPayload: (payload) => {
|
||||
capturedPayload = payload as { max_output_tokens?: number };
|
||||
|
||||
Reference in new issue
Block a user