opencode/packages/ai/test/provider/openai-responses-phase.recorded.test.ts
2026-07-24 16:40:01 -05:00

89 lines
3.4 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { describe, expect } from "bun:test"
import { Effect } from "effect"
import { LLM, Message } from "../../src"
import { configure } from "../../src/providers/openai"
import { OpenAIResponses } from "../../src/protocols/openai-responses"
import { LLMClient } from "../../src/route"
import { weatherTool } from "../recorded-scenarios"
import { recordedTests } from "../recorded-test"
const model = configure({
apiKey: process.env.OPENAI_API_KEY ?? "fixture",
}).responses("gpt-5.6-sol")
const recorded = recordedTests({
prefix: "openai-responses-phase",
provider: "openai",
protocol: "openai-responses",
requires: ["OPENAI_API_KEY"],
})
describe("OpenAI Responses phase recorded", () => {
recorded.effect.with("round-trips commentary into a final answer", { tags: ["phase", "tool"] }, () =>
Effect.gen(function* () {
const user = Message.user("What is the weather in Paris?")
const first = yield* LLMClient.generate(
LLM.request({
model,
system:
"Before calling get_weather, briefly tell the user you are checking. Then call get_weather exactly once. Do not provide the final answer until its result is available.",
messages: [user],
tools: [weatherTool],
generation: { maxTokens: 100 },
}),
)
const call = first.toolCalls[0]
if (!call) throw new Error("OpenAI Responses did not return the expected weather tool call")
expect(call).toMatchObject({ name: "get_weather", input: { city: "Paris" } })
const commentary = first.message.content.find(
(part) => part.type === "text" && part.providerMetadata?.openai?.phase === "commentary",
)
if (!commentary || commentary.type !== "text") throw new Error("OpenAI Responses did not return commentary text")
const itemID = commentary.providerMetadata?.openai?.itemId
if (typeof itemID !== "string") throw new Error("OpenAI Responses commentary did not include an item ID")
expect(commentary).toEqual({
type: "text",
text: "Ill check the current weather in Paris.",
providerMetadata: {
openai: { itemId: itemID, phase: "commentary", status: "completed", annotations: [] },
},
})
const continuation = LLM.request({
model,
system:
"Before calling get_weather, briefly tell the user you are checking. Then call get_weather exactly once. After its result, answer exactly: Paris is sunny.",
messages: [
user,
first.message,
Message.tool({
id: call.id,
name: call.name,
result: { temperature: 22, condition: "sunny" },
}),
],
tools: [weatherTool],
generation: { maxTokens: 100 },
})
const prepared = yield* LLMClient.prepare<OpenAIResponses.OpenAIResponsesBody>(continuation)
expect(prepared.body.input).toContainEqual({
type: "message",
id: itemID,
status: "completed",
role: "assistant",
content: [{ type: "output_text", text: commentary.text, annotations: [] }],
phase: "commentary",
})
const second = yield* LLMClient.generate(continuation)
expect(second.text.trim()).toBe("Paris is sunny.")
expect(
second.message.content.some(
(part) => part.type === "text" && part.providerMetadata?.openai?.phase === "final_answer",
),
).toBeTrue()
}),
)
})