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
+35
-6
@@ -3,6 +3,7 @@ import type { AddressInfo } from "node:net";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { type PiMessagesOptions, stream, streamSimple } from "../src/api/pi-messages.ts";
|
||||
import type { Api, AssistantMessageEvent, Context, Model, StopReason } from "../src/types.ts";
|
||||
import { normalizeContext } from "../src/utils/transcript.ts";
|
||||
|
||||
type RecordedRequest = {
|
||||
url: string;
|
||||
@@ -123,7 +124,7 @@ describe("pi-messages", () => {
|
||||
|
||||
const events: AssistantMessageEvent[] = [];
|
||||
const partialStopReasons: StopReason[] = [];
|
||||
const eventStream = stream(model, context, {
|
||||
const eventStream = stream(model, normalizeContext(context), {
|
||||
apiKey: "test-key",
|
||||
sessionId: "session-1",
|
||||
toolChoice: "auto",
|
||||
@@ -164,6 +165,34 @@ describe("pi-messages", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("forwards parsed wire events in order before converting them", async () => {
|
||||
const wireEvents = [
|
||||
{ type: "start" },
|
||||
{ type: "text_start", contentIndex: 0 },
|
||||
{ type: "text_delta", contentIndex: 0, delta: "Hello", gatewayField: "upstream-value" },
|
||||
{ type: "text_end", contentIndex: 0, content: "Hello" },
|
||||
{ type: "done", reason: "stop", usage, responseId: "resp_1" },
|
||||
];
|
||||
const { baseUrl } = await startServer({ events: wireEvents });
|
||||
const model = createModel(baseUrl);
|
||||
const received: unknown[] = [];
|
||||
const eventModels: Model<Api>[] = [];
|
||||
const message = await streamSimple(model, normalizeContext(context), {
|
||||
apiKey: "test-key",
|
||||
onProviderStreamEvent: async (event, eventModel) => {
|
||||
await Promise.resolve();
|
||||
received.push(event);
|
||||
eventModels.push(eventModel);
|
||||
},
|
||||
}).result();
|
||||
|
||||
expect(received).toEqual(wireEvents);
|
||||
expect(eventModels).toEqual(wireEvents.map(() => model));
|
||||
expect(message.stopReason).toBe("stop");
|
||||
expect(message.responseId).toBe("resp_1");
|
||||
expect(message.content).toEqual([{ type: "text", text: "Hello", textSignature: undefined }]);
|
||||
});
|
||||
|
||||
it("appends debug=1 and reports response headers via onResponse", async () => {
|
||||
const { baseUrl, requests } = await startServer({
|
||||
headers: { "x-pi-gateway-upstream-provider": "anthropic" },
|
||||
@@ -179,7 +208,7 @@ describe("pi-messages", () => {
|
||||
observedHeaders = response.headers;
|
||||
},
|
||||
} satisfies PiMessagesOptions;
|
||||
const message = await streamSimple(model, context, options).result();
|
||||
const message = await streamSimple(model, normalizeContext(context), options).result();
|
||||
|
||||
expect(message.stopReason).toBe("stop");
|
||||
expect(requests[0].url).toBe("/v1/messages?debug=1");
|
||||
@@ -193,7 +222,7 @@ describe("pi-messages", () => {
|
||||
});
|
||||
const model = createModel(baseUrl);
|
||||
|
||||
const message = await stream(model, context, { apiKey: "stale" }).result();
|
||||
const message = await stream(model, normalizeContext(context), { apiKey: "stale" }).result();
|
||||
|
||||
expect(message.stopReason).toBe("error");
|
||||
expect(message.errorMessage).toContain("401");
|
||||
@@ -209,7 +238,7 @@ describe("pi-messages", () => {
|
||||
});
|
||||
const model = createModel(baseUrl);
|
||||
|
||||
const message = await stream(model, context, { apiKey: "test-key" }).result();
|
||||
const message = await stream(model, normalizeContext(context), { apiKey: "test-key" }).result();
|
||||
|
||||
expect(message.stopReason).toBe("error");
|
||||
expect(message.errorMessage).toBe("Upstream failed");
|
||||
@@ -219,7 +248,7 @@ describe("pi-messages", () => {
|
||||
it("errors when no API key is provided", async () => {
|
||||
const model = createModel("http://127.0.0.1:1/v1");
|
||||
|
||||
const message = await stream(model, context).result();
|
||||
const message = await stream(model, normalizeContext(context)).result();
|
||||
|
||||
expect(message.stopReason).toBe("error");
|
||||
expect(message.errorMessage).toContain("No API key provided");
|
||||
@@ -235,7 +264,7 @@ describe("pi-messages", () => {
|
||||
});
|
||||
const model = createModel(baseUrl);
|
||||
|
||||
const message = await stream(model, context, { apiKey: "test-key" }).result();
|
||||
const message = await stream(model, normalizeContext(context), { apiKey: "test-key" }).result();
|
||||
|
||||
expect(message.stopReason).toBe("error");
|
||||
expect(message.errorMessage).toContain("stream ended without a terminal event");
|
||||
|
||||
Reference in new issue
Block a user