| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- import { describe, expect } from "bun:test"
- import { Effect } from "effect"
- import { LLM, LLMEvent, Message } from "../../src/index.js"
- import { configure } from "../../src/providers/openai-compatible-responses.js"
- import { OpenAI } from "../../src/providers.js"
- import { OpenResponses } from "../../src/protocols/open-responses.js"
- import { OpenAICompatibleResponses } from "../../src/protocols/openai-compatible-responses.js"
- import { OpenAIResponses } from "../../src/protocols/openai-responses.js"
- import { LLMClient } from "../../src/route.js"
- import { compileRequest } from "../../src/route/client.js"
- import { it } from "../lib/effect.js"
- import { fixedResponse } from "../lib/http.js"
- import { sseEvents } from "../lib/sse.js"
- describe("Open Responses-compatible route", () => {
- it.effect("uses the Open Responses baseline for a configured deployment", () =>
- Effect.gen(function* () {
- expect(OpenAICompatibleResponses.route.body).toBe(OpenResponses.protocol.body)
- expect(OpenAICompatibleResponses.route.transport).toBe(OpenResponses.httpTransport)
- expect(OpenAICompatibleResponses.route.body).not.toBe(OpenAIResponses.protocol.body)
- const model = configure({
- apiKey: "test-key",
- baseURL: "https://responses.example.test/v1",
- provider: "example",
- }).model("example-model")
- const prepared = yield* compileRequest(
- LLM.request({
- model,
- system: "You are concise.",
- prompt: "Say hello.",
- }),
- )
- expect(prepared.route).toBe("openai-compatible-responses")
- expect(prepared.protocol).toBe("open-responses")
- expect(prepared.model).toMatchObject({
- id: "example-model",
- provider: "example",
- route: {
- id: "openai-compatible-responses",
- endpoint: {
- baseURL: "https://responses.example.test/v1",
- path: "/responses",
- },
- },
- })
- expect(prepared.body).toEqual({
- model: "example-model",
- input: [
- { role: "system", content: "You are concise." },
- { role: "user", content: [{ type: "input_text", text: "Say hello." }] },
- ],
- stream: true,
- })
- }),
- )
- it.effect("rejects OpenAI-native tools", () =>
- Effect.gen(function* () {
- const model = configure({
- apiKey: "test-key",
- baseURL: "https://responses.example.test/v1",
- }).model("example-model")
- const error = yield* compileRequest(
- LLM.request({ model, prompt: "Draw.", tools: [OpenAI.imageGeneration()] }),
- ).pipe(Effect.flip)
- expect(error.reason._tag).toBe("InvalidRequest")
- expect(error.message).toContain("Open Responses does not support provider-native tool image_generation")
- }),
- )
- it.effect("omits OpenAI-only nullable phases from the Open Responses baseline", () =>
- Effect.gen(function* () {
- const model = configure({
- apiKey: "test-key",
- baseURL: "https://responses.example.test/v1",
- }).model("example-model")
- const prepared = yield* compileRequest(
- LLM.request({
- model,
- messages: [
- Message.assistant({
- type: "text",
- text: "Unclassified.",
- providerMetadata: { openresponses: { phase: null } },
- }),
- ],
- }),
- )
- expect(prepared.body).toMatchObject({
- input: [{ role: "assistant", content: [{ type: "output_text", text: "Unclassified." }] }],
- })
- }),
- )
- it.effect("reads standard options from the Open Responses namespace", () =>
- Effect.gen(function* () {
- const model = configure({
- apiKey: "test-key",
- baseURL: "https://responses.example.test/v1",
- providerOptions: { openresponses: { reasoningEffort: "low", store: true } },
- }).model("example-model")
- const prepared = yield* compileRequest(LLM.request({ model, prompt: "Think." }))
- expect(prepared.body).toMatchObject({
- reasoning: { effort: "low" },
- store: true,
- })
- }),
- )
- it.effect("does not interpret OpenAI hosted-tool items", () =>
- Effect.gen(function* () {
- const model = configure({
- apiKey: "test-key",
- baseURL: "https://responses.example.test/v1",
- provider: "example",
- }).model("example-model")
- const response = yield* LLMClient.generate(LLM.request({ model, prompt: "Search." })).pipe(
- Effect.provide(
- fixedResponse(
- sseEvents(
- {
- type: "response.output_item.done",
- item: { type: "web_search_call", id: "ws_1", status: "completed", action: { query: "news" } },
- },
- { type: "response.completed", response: { id: "resp_1" } },
- ),
- ),
- ),
- )
- expect(response.toolCalls).toEqual([])
- expect(response.events.find(LLMEvent.is.finish)).toMatchObject({
- providerMetadata: { openresponses: { responseId: "resp_1" } },
- })
- }),
- )
- })
|