From 25d302d02c1a718c003418931e6acf6e672589bc Mon Sep 17 00:00:00 2001 From: Aiden Cline Date: Tue, 29 Sep 2026 23:50:21 -0500 Subject: [PATCH] refactor(ai): share OpenRouter Responses protocol --- packages/ai/README.md | 6 +- packages/ai/src/protocols/meta-responses.ts | 2 +- packages/ai/src/protocols/open-responses.ts | 2 +- packages/ai/src/protocols/openai-responses.ts | 2 +- packages/ai/src/protocols/utils/openrouter.ts | 22 ++++- packages/ai/src/protocols/xai-responses.ts | 2 +- packages/ai/src/providers/openrouter.ts | 91 +++++-------------- .../openrouter-gpt-4o-mini-text.json | 4 +- .../openrouter-gpt-4o-mini-tool-call.json | 4 +- .../openrouter-gpt-4o-mini-tool-loop.json | 8 +- .../openrouter-gpt-5-5-tool-loop.json | 8 +- .../openrouter-grok-4-3-tool-loop.json | 10 +- .../openrouter-muse-spark-1-3-tool-loop.json | 10 +- .../openrouter-native.recorded.test.ts | 2 +- packages/ai/test/provider/openrouter.test.ts | 62 ++++++++----- 15 files changed, 112 insertions(+), 123 deletions(-) diff --git a/packages/ai/README.md b/packages/ai/README.md index 1bcc9ffeb46..b2d54a86a56 100644 --- a/packages/ai/README.md +++ b/packages/ai/README.md @@ -1210,8 +1210,10 @@ LLM.request({ Normalized cache usage is read back into `response.usage.cacheReadInputTokens` and `cacheWriteInputTokens` across every provider. OpenRouter selects its wire API by model family: `openai/*`, `x-ai/*`, and `meta/*` use Responses; `anthropic/*` uses -Anthropic Messages; other families use Chat Completions. Leading-`~` model aliases follow the same routing. Explicit -`openrouter.chat(id)`, `.responses(id)`, and `.messages(id)` selectors are available for API-specific integrations. +Anthropic Messages; other families use Chat Completions. All three Responses families share the provider-neutral +Responses serializer and stream parser; there are no per-vendor OpenRouter protocols. Leading-`~` model aliases follow +the same routing. Explicit `openrouter.chat(id)`, `.responses(id)`, and `.messages(id)` selectors are available for +API-specific integrations. Qwen retains Chat's explicit system/conversation cache markers, while Claude uses native Messages cache blocks. OpenRouter Responses is stateless (`store: false`); every request includes full history, not `previous_response_id`. Meta currently accepts only automatic tool selection on both its Chat and Responses upstreams; forced/disabled tool diff --git a/packages/ai/src/protocols/meta-responses.ts b/packages/ai/src/protocols/meta-responses.ts index 32e42b23b47..79827fa3178 100644 --- a/packages/ai/src/protocols/meta-responses.ts +++ b/packages/ai/src/protocols/meta-responses.ts @@ -44,7 +44,7 @@ const ImageItem = Schema.Struct({ error: Schema.optional(Schema.Unknown), }) -export const Body = Schema.Struct({ +const Body = Schema.Struct({ ...OpenResponses.coreFields, input: Schema.Array(Schema.Union([OpenResponses.InputItem, ImageItem])), tools: optionalArray(Schema.Union([OpenResponses.Tool, NativeTool])), diff --git a/packages/ai/src/protocols/open-responses.ts b/packages/ai/src/protocols/open-responses.ts index e2210f9a626..121e2239795 100644 --- a/packages/ai/src/protocols/open-responses.ts +++ b/packages/ai/src/protocols/open-responses.ts @@ -163,7 +163,7 @@ export const CompactionItem = Schema.Struct({ encrypted_content: Schema.String, }) -// Kept out of the baseline `InputItem` union: only the OpenAI extension accepts it. +// Kept out of the baseline `InputItem` union; extensions such as OpenAI and OpenRouter opt in. export const ConfigurationUpdate = Schema.Struct({ type: Schema.Literal("configuration_update"), reasoning: Schema.Struct({ effort: OpenResponsesOptions.ReasoningEffort }), diff --git a/packages/ai/src/protocols/openai-responses.ts b/packages/ai/src/protocols/openai-responses.ts index babb2fc70d2..e36496954b9 100644 --- a/packages/ai/src/protocols/openai-responses.ts +++ b/packages/ai/src/protocols/openai-responses.ts @@ -124,7 +124,7 @@ const OpenAIResponsesCoreFields = { ), } -export const OpenAIResponsesBody = Schema.Struct({ +const OpenAIResponsesBody = Schema.Struct({ ...OpenAIResponsesCoreFields, stream: Schema.Literal(true), }) diff --git a/packages/ai/src/protocols/utils/openrouter.ts b/packages/ai/src/protocols/utils/openrouter.ts index b95de8dfb80..e114902710d 100644 --- a/packages/ai/src/protocols/utils/openrouter.ts +++ b/packages/ai/src/protocols/utils/openrouter.ts @@ -2,7 +2,9 @@ export * as OpenRouterWire from "./openrouter.js" import { Option, Schema } from "effect" import { LLMRequest, Message, type ContentPart, type ReasoningPart } from "../../schema/index.js" +import { resolveEffortUpdates } from "../../effort-updates.js" import type { OpenResponses } from "../open-responses.js" +import { OpenResponsesOptions } from "./open-responses-options.js" import { isRecord, ProviderShared } from "../shared.js" const ReplayDetail = Schema.Struct({ @@ -14,19 +16,33 @@ const ReplayDetail = Schema.Struct({ }) const decodeReplayDetail = Schema.decodeUnknownOption(ReplayDetail) +// OpenRouter's generic Responses API supports chronological effort updates only on eligible models. +export function supportsEffortUpdates(request: LLMRequest) { + if (request.providerOptions?.truncation === "auto" || request.http?.body?.truncation === "auto") return false + if (Schema.is(Schema.Struct({ mode: Schema.Literal("pro") }))(request.providerOptions?.reasoning)) return false + if (Schema.is(Schema.Struct({ mode: Schema.Literal("pro") }))(request.http?.body?.reasoning)) return false + return ( + request.model.compatibility?.supportsEffortUpdates ?? /^~?openai\/gpt-6-(?:astra|sol|luna)$/i.test(request.model.id) + ) +} + export function nativeRequest(request: LLMRequest, format: "responses" | "messages") { const options = request.providerOptions ?? {} const reasoning = isRecord(options.reasoning) ? fitReasoning(options.reasoning, request.generation?.maxTokens) : undefined const disabled = reasoning?.enabled === false || reasoning?.effort === "none" + const updates = resolveEffortUpdates( + request, + OpenResponsesOptions.resolve(request).reasoningEffort ?? + (typeof reasoning?.effort === "string" ? reasoning.effort : undefined), + ) return LLMRequest.update(request, { providerOptions: format === "responses" ? { ...options, - reasoningEffort: - options.reasoningEffort ?? (typeof reasoning?.effort === "string" ? reasoning.effort : undefined), + reasoningEffort: updates.effort, } : { ...options, @@ -42,7 +58,7 @@ export function nativeRequest(request: LLMRequest, format: "responses" | "messag return { type: "adaptive", ...(reasoning.exclude === true ? { display: "omitted" } : {}) } })(), }, - messages: request.messages.map((message) => { + messages: (format === "responses" ? updates.request : request).messages.map((message) => { if ( !message.content.some( (part) => part.type === "reasoning" && part.providerMetadata?.openrouter?.reasoningDetails !== undefined, diff --git a/packages/ai/src/protocols/xai-responses.ts b/packages/ai/src/protocols/xai-responses.ts index 68ea661f31b..bb19ebd843a 100644 --- a/packages/ai/src/protocols/xai-responses.ts +++ b/packages/ai/src/protocols/xai-responses.ts @@ -31,7 +31,7 @@ const XAIResponsesHostedToolItem = Schema.Union([ ), ]) -export const XAIResponsesBody = Schema.Struct({ +const XAIResponsesBody = Schema.Struct({ ...OpenResponses.coreFields, input: Schema.Array(Schema.Union([OpenResponses.InputItem, XAIResponsesHostedToolItem])), stream: Schema.Literal(true), diff --git a/packages/ai/src/providers/openrouter.ts b/packages/ai/src/providers/openrouter.ts index dd8c4186a99..f92acab7af1 100644 --- a/packages/ai/src/providers/openrouter.ts +++ b/packages/ai/src/providers/openrouter.ts @@ -7,11 +7,10 @@ import { HttpOptions, ProviderID, type CacheHint, type ModelID, type OpenString import type { ProviderPackage } from "../provider-package.js" import { SystemOne } from "../experimental/system-one.js" import { OpenAIChat } from "../protocols/openai-chat.js" -import { OpenAIResponses } from "../protocols/openai-responses.js" -import { XAIResponses } from "../protocols/xai-responses.js" -import { MetaResponses } from "../protocols/meta-responses.js" +import { OpenResponses } from "../protocols/open-responses.js" import { AnthropicMessages } from "../protocols/anthropic-messages.js" import { Framing } from "../route/framing.js" +import { ProviderShared } from "../protocols/shared.js" import { newBreakpoints, ttlBucket } from "../protocols/utils/cache.js" import { OpenRouterWire } from "../protocols/utils/openrouter.js" @@ -110,20 +109,14 @@ const ResponsesReasoning = Schema.StructWithRest( }), [Schema.Record(Schema.String, Schema.Unknown)], ) -const responsesFields = { - store: Schema.Literal(false), - reasoning: Schema.optional(ResponsesReasoning), -} const OpenRouterResponsesBody = Schema.StructWithRest( - Schema.Struct({ ...OpenAIResponses.OpenAIResponsesBody.fields, ...responsesFields }), - [Schema.Record(Schema.String, Schema.Unknown)], -) -const OpenRouterXAIResponsesBody = Schema.StructWithRest( - Schema.Struct({ ...XAIResponses.XAIResponsesBody.fields, ...responsesFields }), - [Schema.Record(Schema.String, Schema.Unknown)], -) -const OpenRouterMetaResponsesBody = Schema.StructWithRest( - Schema.Struct({ ...MetaResponses.Body.fields, ...responsesFields }), + Schema.Struct({ + ...OpenResponses.coreFields, + input: Schema.Array(Schema.Union([OpenResponses.InputItem, OpenResponses.ConfigurationUpdate])), + stream: Schema.Literal(true), + store: Schema.Literal(false), + reasoning: Schema.optional(ResponsesReasoning), + }), [Schema.Record(Schema.String, Schema.Unknown)], ) const OpenRouterMessagesBody = Schema.StructWithRest(AnthropicMessages.AnthropicMessagesBody, [ @@ -168,36 +161,19 @@ export const protocol = Protocol.make({ }) const responsesProtocol = Protocol.make({ - ...OpenAIResponses.protocol, + ...OpenResponses.protocol, id: "openrouter-responses", + supportsEffortUpdates: OpenRouterWire.supportsEffortUpdates, body: { schema: OpenRouterResponsesBody, from: (request) => - OpenAIResponses.protocol.body - .from(OpenRouterWire.nativeRequest(request, "responses")) - .pipe(Effect.map((body) => OpenRouterWire.responsesOptions(request, body))), - }, -}) -const xaiProtocol = Protocol.make({ - ...XAIResponses.protocol, - id: "openrouter-xai-responses", - body: { - schema: OpenRouterXAIResponsesBody, - from: (request) => - XAIResponses.protocol.body - .from(OpenRouterWire.nativeRequest(request, "responses")) - .pipe(Effect.map((body) => OpenRouterWire.responsesOptions(request, body))), - }, -}) -const metaProtocol = Protocol.make({ - ...MetaResponses.protocol, - id: "openrouter-meta-responses", - body: { - schema: OpenRouterMetaResponsesBody, - from: (request) => - MetaResponses.protocol.body - .from(OpenRouterWire.nativeRequest(request, "responses")) - .pipe(Effect.map((body) => OpenRouterWire.responsesOptions(request, body))), + OpenResponses.fromRequestWithAdapter(OpenRouterWire.nativeRequest(request, "responses"), { + id: "openrouter-responses", + name: "OpenRouter Responses", + }).pipe( + Effect.map((body) => OpenRouterWire.responsesOptions(request, body)), + Effect.flatMap(ProviderShared.validateWith(Schema.decodeUnknownEffect(OpenRouterResponsesBody))), + ), }, }) const messagesProtocol = Protocol.make({ @@ -249,24 +225,6 @@ const responsesRoute = Route.make({ framing: Framing.sse, defaults: { providerOptions: { store: false, include: ["reasoning.encrypted_content"] } }, }) -const xaiRoute = Route.make({ - id: "openrouter-xai-responses", - provider: id, - providerMetadataKey: "openrouter", - protocol: xaiProtocol, - endpoint: Endpoint.path("/responses", { baseURL }), - framing: Framing.sse, - defaults: { providerOptions: { store: false, include: ["reasoning.encrypted_content"] } }, -}) -const metaRoute = Route.make({ - id: "openrouter-meta-responses", - provider: id, - providerMetadataKey: "openrouter", - protocol: metaProtocol, - endpoint: Endpoint.path("/responses", { baseURL }), - framing: Framing.sse, - defaults: { providerOptions: { store: false, include: ["reasoning.encrypted_content"] } }, -}) const messagesRoute = Route.make({ id: "openrouter-messages", provider: id, @@ -276,7 +234,7 @@ const messagesRoute = Route.make({ transport: AnthropicMessages.transport(), }) -export const routes = [route, responsesRoute, xaiRoute, metaRoute, messagesRoute] +export const routes = [route, responsesRoute, messagesRoute] const routeOptions = (input: LanguageModelOptions) => { const { apiKey: _, auth: _auth, baseURL: endpoint, ...rest } = input @@ -290,18 +248,11 @@ const routeOptions = (input: LanguageModelOptions) => { export const configure = (input: LanguageModelOptions = {}) => { const options = routeOptions(input) const chatRoute = route.with(options) - const openaiResponses = responsesRoute.with(options) - const xaiResponses = xaiRoute.with(options) - const metaResponses = metaRoute.with(options) + const openResponses = responsesRoute.with(options) const anthropicMessages = messagesRoute.with(options) const chat = (modelID: string | ModelID) => chatRoute.model({ id: modelID, compatibility: { supportsPromptCacheKey: true } }) - const responses = (modelID: string | ModelID) => { - const model = String(modelID).replace(/^~/, "") - return ( - model.startsWith("x-ai/") ? xaiResponses : model.startsWith("meta/") ? metaResponses : openaiResponses - ).model({ id: modelID }) - } + const responses = (modelID: string | ModelID) => openResponses.model({ id: modelID }) const messages = (modelID: string | ModelID) => anthropicMessages.model({ id: modelID }) const evaluation = (modelID: string | ModelID) => diff --git a/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-gpt-4o-mini-text.json b/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-gpt-4o-mini-text.json index cd46b23f2af..899d254c548 100644 --- a/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-gpt-4o-mini-text.json +++ b/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-gpt-4o-mini-text.json @@ -12,7 +12,7 @@ "golden" ], "name": "openrouter-responses/openrouter-gpt-4o-mini-text", - "recordedAt": "2026-09-30T03:26:07.521Z" + "recordedAt": "2026-09-30T04:48:47.207Z" }, "interactions": [ { @@ -30,7 +30,7 @@ "headers": { "content-type": "text/event-stream" }, - "body": "data: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790738766-AxuIaR7Dk36zBth5HcUa\",\"object\":\"response\",\"created_at\":1790738766,\"model\":\"openai/gpt-4o-mini\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":40,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"You are concise.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":0}\n\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"gen-1790738766-AxuIaR7Dk36zBth5HcUa\",\"object\":\"response\",\"created_at\":1790738766,\"model\":\"openai/gpt-4o-mini\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":40,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"You are concise.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":1}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":0,\"item\":{\"id\":\"msg_tmp_qpwvyuytpog\",\"type\":\"message\",\"status\":\"in_progress\",\"role\":\"assistant\",\"content\":[]},\"sequence_number\":2}\n\ndata: {\"type\":\"response.content_part.added\",\"output_index\":0,\"item_id\":\"msg_tmp_qpwvyuytpog\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":3}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_qpwvyuytpog\",\"content_index\":0,\"delta\":\"Hello\",\"logprobs\":[],\"sequence_number\":4}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_qpwvyuytpog\",\"content_index\":0,\"delta\":\"!\",\"logprobs\":[],\"sequence_number\":5}\n\ndata: {\"type\":\"response.output_text.done\",\"output_index\":0,\"item_id\":\"msg_tmp_qpwvyuytpog\",\"content_index\":0,\"text\":\"Hello!\",\"logprobs\":[],\"sequence_number\":6}\n\ndata: {\"type\":\"response.content_part.done\",\"output_index\":0,\"item_id\":\"msg_tmp_qpwvyuytpog\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"Hello!\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":7}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"msg_tmp_qpwvyuytpog\",\"type\":\"message\",\"status\":\"completed\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"Hello!\",\"annotations\":[],\"logprobs\":[]}]},\"sequence_number\":8}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790738766-AxuIaR7Dk36zBth5HcUa\",\"object\":\"response\",\"created_at\":1790738766,\"model\":\"openai/gpt-4o-mini\",\"status\":\"completed\",\"completed_at\":1790738767,\"output\":[{\"id\":\"msg_tmp_qpwvyuytpog\",\"type\":\"message\",\"role\":\"assistant\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"text\":\"Hello!\",\"annotations\":[],\"logprobs\":[]}]}],\"error\":null,\"incomplete_details\":null,\"tools\":[],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":40,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"default\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"You are concise.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":{\"input_tokens\":21,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":2,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":23,\"cost\":0.00000435,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.00000435,\"upstream_inference_input_cost\":0.00000315,\"upstream_inference_output_cost\":0.0000012}}},\"sequence_number\":9}\n\ndata: [DONE]\n\n" + "body": "data: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790743725-CVE8eRBKqzoJqJHXU1ur\",\"object\":\"response\",\"created_at\":1790743725,\"model\":\"openai/gpt-4o-mini\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":40,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"You are concise.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":0}\n\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"gen-1790743725-CVE8eRBKqzoJqJHXU1ur\",\"object\":\"response\",\"created_at\":1790743725,\"model\":\"openai/gpt-4o-mini\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":40,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"You are concise.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":1}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":0,\"item\":{\"id\":\"msg_tmp_ilrlnvtd9l9\",\"type\":\"message\",\"status\":\"in_progress\",\"role\":\"assistant\",\"content\":[]},\"sequence_number\":2}\n\ndata: {\"type\":\"response.content_part.added\",\"output_index\":0,\"item_id\":\"msg_tmp_ilrlnvtd9l9\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":3}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_ilrlnvtd9l9\",\"content_index\":0,\"delta\":\"Hello\",\"logprobs\":[],\"sequence_number\":4}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_ilrlnvtd9l9\",\"content_index\":0,\"delta\":\"!\",\"logprobs\":[],\"sequence_number\":5}\n\ndata: {\"type\":\"response.output_text.done\",\"output_index\":0,\"item_id\":\"msg_tmp_ilrlnvtd9l9\",\"content_index\":0,\"text\":\"Hello!\",\"logprobs\":[],\"sequence_number\":6}\n\ndata: {\"type\":\"response.content_part.done\",\"output_index\":0,\"item_id\":\"msg_tmp_ilrlnvtd9l9\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"Hello!\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":7}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"msg_tmp_ilrlnvtd9l9\",\"type\":\"message\",\"status\":\"completed\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"Hello!\",\"annotations\":[],\"logprobs\":[]}]},\"sequence_number\":8}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790743725-CVE8eRBKqzoJqJHXU1ur\",\"object\":\"response\",\"created_at\":1790743725,\"model\":\"openai/gpt-4o-mini\",\"status\":\"completed\",\"completed_at\":1790743727,\"output\":[{\"id\":\"msg_tmp_ilrlnvtd9l9\",\"type\":\"message\",\"role\":\"assistant\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"text\":\"Hello!\",\"annotations\":[],\"logprobs\":[]}]}],\"error\":null,\"incomplete_details\":null,\"tools\":[],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":40,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"default\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"You are concise.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":{\"input_tokens\":21,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":2,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":23,\"cost\":0.00000435,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.00000435,\"upstream_inference_input_cost\":0.00000315,\"upstream_inference_output_cost\":0.0000012}}},\"sequence_number\":9}\n\ndata: [DONE]\n\n" } } ] diff --git a/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-gpt-4o-mini-tool-call.json b/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-gpt-4o-mini-tool-call.json index 54d3e9158be..4fd4eb9a01b 100644 --- a/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-gpt-4o-mini-tool-call.json +++ b/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-gpt-4o-mini-tool-call.json @@ -13,7 +13,7 @@ "golden" ], "name": "openrouter-responses/openrouter-gpt-4o-mini-tool-call", - "recordedAt": "2026-09-30T03:26:08.090Z" + "recordedAt": "2026-09-30T04:48:49.499Z" }, "interactions": [ { @@ -31,7 +31,7 @@ "headers": { "content-type": "text/event-stream" }, - "body": "data: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790738767-ZOdmRoQoSqcQHhcyPeLU\",\"object\":\"response\",\"created_at\":1790738767,\"model\":\"openai/gpt-4o-mini\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":{\"type\":\"function\",\"name\":\"get_weather\"},\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Call tools exactly as requested.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":0}\n\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"gen-1790738767-ZOdmRoQoSqcQHhcyPeLU\",\"object\":\"response\",\"created_at\":1790738767,\"model\":\"openai/gpt-4o-mini\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":{\"type\":\"function\",\"name\":\"get_weather\"},\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Call tools exactly as requested.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":1}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":0,\"item\":{\"id\":\"fc_tmp_q07i54r5lwk\",\"type\":\"function_call\",\"status\":\"in_progress\",\"call_id\":\"call_jBwikLPUZeXLRZ6ecSAtyy1N\",\"name\":\"get_weather\",\"arguments\":\"\"},\"sequence_number\":2}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_q07i54r5lwk\",\"delta\":\"{\\\"\",\"sequence_number\":3}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_q07i54r5lwk\",\"delta\":\"city\",\"sequence_number\":4}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_q07i54r5lwk\",\"delta\":\"\\\":\\\"\",\"sequence_number\":5}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_q07i54r5lwk\",\"delta\":\"Paris\",\"sequence_number\":6}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_q07i54r5lwk\",\"delta\":\"\\\"}\",\"sequence_number\":7}\n\ndata: {\"type\":\"response.function_call_arguments.done\",\"output_index\":0,\"item_id\":\"fc_tmp_q07i54r5lwk\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\",\"sequence_number\":8}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"fc_tmp_q07i54r5lwk\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_jBwikLPUZeXLRZ6ecSAtyy1N\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},\"sequence_number\":9}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790738767-ZOdmRoQoSqcQHhcyPeLU\",\"object\":\"response\",\"created_at\":1790738767,\"model\":\"openai/gpt-4o-mini\",\"status\":\"completed\",\"completed_at\":1790738768,\"output\":[{\"id\":\"fc_tmp_q07i54r5lwk\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_jBwikLPUZeXLRZ6ecSAtyy1N\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"}],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":{\"type\":\"function\",\"name\":\"get_weather\"},\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"default\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Call tools exactly as requested.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":{\"input_tokens\":67,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":5,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":72,\"cost\":0.00001305,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.00001305,\"upstream_inference_input_cost\":0.00001005,\"upstream_inference_output_cost\":0.000003}}},\"sequence_number\":10}\n\ndata: [DONE]\n\n" + "body": "data: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790743727-bOi6wVr1uZtoku9blJyG\",\"object\":\"response\",\"created_at\":1790743727,\"model\":\"openai/gpt-4o-mini\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":{\"type\":\"function\",\"name\":\"get_weather\"},\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Call tools exactly as requested.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":0}\n\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"gen-1790743727-bOi6wVr1uZtoku9blJyG\",\"object\":\"response\",\"created_at\":1790743727,\"model\":\"openai/gpt-4o-mini\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":{\"type\":\"function\",\"name\":\"get_weather\"},\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Call tools exactly as requested.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":1}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":0,\"item\":{\"id\":\"fc_tmp_heuomwdgjvd\",\"type\":\"function_call\",\"status\":\"in_progress\",\"call_id\":\"call_FbQ1aPeo1cmd2i6savV2SjY6\",\"name\":\"get_weather\",\"arguments\":\"\"},\"sequence_number\":2}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_heuomwdgjvd\",\"delta\":\"{\\\"\",\"sequence_number\":3}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_heuomwdgjvd\",\"delta\":\"city\",\"sequence_number\":4}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_heuomwdgjvd\",\"delta\":\"\\\":\\\"\",\"sequence_number\":5}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_heuomwdgjvd\",\"delta\":\"Paris\",\"sequence_number\":6}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_heuomwdgjvd\",\"delta\":\"\\\"}\",\"sequence_number\":7}\n\ndata: {\"type\":\"response.function_call_arguments.done\",\"output_index\":0,\"item_id\":\"fc_tmp_heuomwdgjvd\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\",\"sequence_number\":8}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"fc_tmp_heuomwdgjvd\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_FbQ1aPeo1cmd2i6savV2SjY6\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},\"sequence_number\":9}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790743727-bOi6wVr1uZtoku9blJyG\",\"object\":\"response\",\"created_at\":1790743727,\"model\":\"openai/gpt-4o-mini\",\"status\":\"completed\",\"completed_at\":1790743729,\"output\":[{\"id\":\"fc_tmp_heuomwdgjvd\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_FbQ1aPeo1cmd2i6savV2SjY6\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"}],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":{\"type\":\"function\",\"name\":\"get_weather\"},\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"default\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Call tools exactly as requested.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":{\"input_tokens\":67,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":5,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":72,\"cost\":0.00001305,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.00001305,\"upstream_inference_input_cost\":0.00001005,\"upstream_inference_output_cost\":0.000003}}},\"sequence_number\":10}\n\ndata: [DONE]\n\n" } } ] diff --git a/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-gpt-4o-mini-tool-loop.json b/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-gpt-4o-mini-tool-loop.json index e45030f8d1f..77b617f14dc 100644 --- a/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-gpt-4o-mini-tool-loop.json +++ b/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-gpt-4o-mini-tool-loop.json @@ -13,7 +13,7 @@ "golden" ], "name": "openrouter-responses/openrouter-gpt-4o-mini-tool-loop", - "recordedAt": "2026-09-30T03:26:11.713Z" + "recordedAt": "2026-09-30T04:48:50.733Z" }, "interactions": [ { @@ -31,7 +31,7 @@ "headers": { "content-type": "text/event-stream" }, - "body": "data: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790738768-ONy5aA1sT3ubmKajS1qb\",\"object\":\"response\",\"created_at\":1790738768,\"model\":\"openai/gpt-4o-mini\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":0}\n\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"gen-1790738768-ONy5aA1sT3ubmKajS1qb\",\"object\":\"response\",\"created_at\":1790738768,\"model\":\"openai/gpt-4o-mini\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":1}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":0,\"item\":{\"id\":\"fc_tmp_ahx3jomvbhm\",\"type\":\"function_call\",\"status\":\"in_progress\",\"call_id\":\"call_Dwe6LpDYOv2JzMFVovVeoc67\",\"name\":\"get_weather\",\"arguments\":\"\"},\"sequence_number\":2}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_ahx3jomvbhm\",\"delta\":\"{\\\"\",\"sequence_number\":3}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_ahx3jomvbhm\",\"delta\":\"city\",\"sequence_number\":4}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_ahx3jomvbhm\",\"delta\":\"\\\":\\\"\",\"sequence_number\":5}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_ahx3jomvbhm\",\"delta\":\"Paris\",\"sequence_number\":6}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_ahx3jomvbhm\",\"delta\":\"\\\"}\",\"sequence_number\":7}\n\ndata: {\"type\":\"response.function_call_arguments.done\",\"output_index\":0,\"item_id\":\"fc_tmp_ahx3jomvbhm\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\",\"sequence_number\":8}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"fc_tmp_ahx3jomvbhm\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_Dwe6LpDYOv2JzMFVovVeoc67\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},\"sequence_number\":9}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790738768-ONy5aA1sT3ubmKajS1qb\",\"object\":\"response\",\"created_at\":1790738768,\"model\":\"openai/gpt-4o-mini\",\"status\":\"completed\",\"completed_at\":1790738769,\"output\":[{\"id\":\"fc_tmp_ahx3jomvbhm\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_Dwe6LpDYOv2JzMFVovVeoc67\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"}],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"default\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":{\"input_tokens\":71,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":14,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":85,\"cost\":0.00001905,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.00001905,\"upstream_inference_input_cost\":0.00001065,\"upstream_inference_output_cost\":0.0000084}}},\"sequence_number\":10}\n\ndata: [DONE]\n\n" + "body": "data: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790743729-bFPsOgVV8INYbpDROpIZ\",\"object\":\"response\",\"created_at\":1790743729,\"model\":\"openai/gpt-4o-mini\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":0}\n\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"gen-1790743729-bFPsOgVV8INYbpDROpIZ\",\"object\":\"response\",\"created_at\":1790743729,\"model\":\"openai/gpt-4o-mini\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":1}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":0,\"item\":{\"id\":\"fc_tmp_dj1l0ujp3vq\",\"type\":\"function_call\",\"status\":\"in_progress\",\"call_id\":\"call_R27c8sJE6vD3hbShIjdVB9C4\",\"name\":\"get_weather\",\"arguments\":\"\"},\"sequence_number\":2}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_dj1l0ujp3vq\",\"delta\":\"{\\\"\",\"sequence_number\":3}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_dj1l0ujp3vq\",\"delta\":\"city\",\"sequence_number\":4}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_dj1l0ujp3vq\",\"delta\":\"\\\":\\\"\",\"sequence_number\":5}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_dj1l0ujp3vq\",\"delta\":\"Paris\",\"sequence_number\":6}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_dj1l0ujp3vq\",\"delta\":\"\\\"}\",\"sequence_number\":7}\n\ndata: {\"type\":\"response.function_call_arguments.done\",\"output_index\":0,\"item_id\":\"fc_tmp_dj1l0ujp3vq\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\",\"sequence_number\":8}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"fc_tmp_dj1l0ujp3vq\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_R27c8sJE6vD3hbShIjdVB9C4\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},\"sequence_number\":9}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790743729-bFPsOgVV8INYbpDROpIZ\",\"object\":\"response\",\"created_at\":1790743729,\"model\":\"openai/gpt-4o-mini\",\"status\":\"completed\",\"completed_at\":1790743730,\"output\":[{\"id\":\"fc_tmp_dj1l0ujp3vq\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_R27c8sJE6vD3hbShIjdVB9C4\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"}],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"default\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":{\"input_tokens\":71,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":14,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":85,\"cost\":0.00001905,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.00001905,\"upstream_inference_input_cost\":0.00001065,\"upstream_inference_output_cost\":0.0000084}}},\"sequence_number\":10}\n\ndata: [DONE]\n\n" } }, { @@ -42,14 +42,14 @@ "headers": { "content-type": "application/json" }, - "body": "{\"model\":\"openai/gpt-4o-mini\",\"input\":[{\"type\":\"message\",\"role\":\"user\",\"content\":[{\"type\":\"input_text\",\"text\":\"What is the weather in Paris?\"}]},{\"type\":\"function_call\",\"id\":\"fc_tmp_ahx3jomvbhm\",\"call_id\":\"call_Dwe6LpDYOv2JzMFVovVeoc67\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},{\"type\":\"function_call_output\",\"call_id\":\"call_Dwe6LpDYOv2JzMFVovVeoc67\",\"output\":\"{\\\"temperature\\\":22,\\\"condition\\\":\\\"sunny\\\"}\"}],\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false},\"strict\":false}],\"store\":false,\"include\":[\"reasoning.encrypted_content\"],\"max_output_tokens\":80,\"temperature\":0,\"stream\":true}" + "body": "{\"model\":\"openai/gpt-4o-mini\",\"input\":[{\"type\":\"message\",\"role\":\"user\",\"content\":[{\"type\":\"input_text\",\"text\":\"What is the weather in Paris?\"}]},{\"type\":\"function_call\",\"id\":\"fc_tmp_dj1l0ujp3vq\",\"call_id\":\"call_R27c8sJE6vD3hbShIjdVB9C4\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},{\"type\":\"function_call_output\",\"call_id\":\"call_R27c8sJE6vD3hbShIjdVB9C4\",\"output\":\"{\\\"temperature\\\":22,\\\"condition\\\":\\\"sunny\\\"}\"}],\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false},\"strict\":false}],\"store\":false,\"include\":[\"reasoning.encrypted_content\"],\"max_output_tokens\":80,\"temperature\":0,\"stream\":true}" }, "response": { "status": 200, "headers": { "content-type": "text/event-stream" }, - "body": "data: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790738769-THBerazTTxHRZacCDnYf\",\"object\":\"response\",\"created_at\":1790738769,\"model\":\"openai/gpt-4o-mini\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":0}\n\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"gen-1790738769-THBerazTTxHRZacCDnYf\",\"object\":\"response\",\"created_at\":1790738769,\"model\":\"openai/gpt-4o-mini\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":1}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":0,\"item\":{\"id\":\"msg_tmp_sk59phnoo7b\",\"type\":\"message\",\"status\":\"in_progress\",\"role\":\"assistant\",\"content\":[]},\"sequence_number\":2}\n\ndata: {\"type\":\"response.content_part.added\",\"output_index\":0,\"item_id\":\"msg_tmp_sk59phnoo7b\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":3}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_sk59phnoo7b\",\"content_index\":0,\"delta\":\"Paris\",\"logprobs\":[],\"sequence_number\":4}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_sk59phnoo7b\",\"content_index\":0,\"delta\":\" is\",\"logprobs\":[],\"sequence_number\":5}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_sk59phnoo7b\",\"content_index\":0,\"delta\":\" sunny\",\"logprobs\":[],\"sequence_number\":6}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_sk59phnoo7b\",\"content_index\":0,\"delta\":\".\",\"logprobs\":[],\"sequence_number\":7}\n\ndata: {\"type\":\"response.output_text.done\",\"output_index\":0,\"item_id\":\"msg_tmp_sk59phnoo7b\",\"content_index\":0,\"text\":\"Paris is sunny.\",\"logprobs\":[],\"sequence_number\":8}\n\ndata: {\"type\":\"response.content_part.done\",\"output_index\":0,\"item_id\":\"msg_tmp_sk59phnoo7b\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":9}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"msg_tmp_sk59phnoo7b\",\"type\":\"message\",\"status\":\"completed\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]}]},\"sequence_number\":10}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790738769-THBerazTTxHRZacCDnYf\",\"object\":\"response\",\"created_at\":1790738769,\"model\":\"openai/gpt-4o-mini\",\"status\":\"completed\",\"completed_at\":1790738771,\"output\":[{\"id\":\"msg_tmp_sk59phnoo7b\",\"type\":\"message\",\"role\":\"assistant\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]}]}],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"default\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":{\"input_tokens\":103,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":5,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":108,\"cost\":0.00001845,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.00001845,\"upstream_inference_input_cost\":0.00001545,\"upstream_inference_output_cost\":0.000003}}},\"sequence_number\":11}\n\ndata: [DONE]\n\n" + "body": "data: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790743730-6RkMGRipdtlGQTL6QNSG\",\"object\":\"response\",\"created_at\":1790743730,\"model\":\"openai/gpt-4o-mini\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":0}\n\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"gen-1790743730-6RkMGRipdtlGQTL6QNSG\",\"object\":\"response\",\"created_at\":1790743730,\"model\":\"openai/gpt-4o-mini\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":1}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":0,\"item\":{\"id\":\"msg_tmp_j7lzfgmkd3\",\"type\":\"message\",\"status\":\"in_progress\",\"role\":\"assistant\",\"content\":[]},\"sequence_number\":2}\n\ndata: {\"type\":\"response.content_part.added\",\"output_index\":0,\"item_id\":\"msg_tmp_j7lzfgmkd3\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":3}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_j7lzfgmkd3\",\"content_index\":0,\"delta\":\"Paris\",\"logprobs\":[],\"sequence_number\":4}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_j7lzfgmkd3\",\"content_index\":0,\"delta\":\" is\",\"logprobs\":[],\"sequence_number\":5}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_j7lzfgmkd3\",\"content_index\":0,\"delta\":\" sunny\",\"logprobs\":[],\"sequence_number\":6}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_j7lzfgmkd3\",\"content_index\":0,\"delta\":\".\",\"logprobs\":[],\"sequence_number\":7}\n\ndata: {\"type\":\"response.output_text.done\",\"output_index\":0,\"item_id\":\"msg_tmp_j7lzfgmkd3\",\"content_index\":0,\"text\":\"Paris is sunny.\",\"logprobs\":[],\"sequence_number\":8}\n\ndata: {\"type\":\"response.content_part.done\",\"output_index\":0,\"item_id\":\"msg_tmp_j7lzfgmkd3\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":9}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"msg_tmp_j7lzfgmkd3\",\"type\":\"message\",\"status\":\"completed\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]}]},\"sequence_number\":10}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790743730-6RkMGRipdtlGQTL6QNSG\",\"object\":\"response\",\"created_at\":1790743730,\"model\":\"openai/gpt-4o-mini\",\"status\":\"completed\",\"completed_at\":1790743730,\"output\":[{\"id\":\"msg_tmp_j7lzfgmkd3\",\"type\":\"message\",\"role\":\"assistant\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]}]}],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"default\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":{\"input_tokens\":103,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":5,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":108,\"cost\":0.00001845,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.00001845,\"upstream_inference_input_cost\":0.00001545,\"upstream_inference_output_cost\":0.000003}}},\"sequence_number\":11}\n\ndata: [DONE]\n\n" } } ] diff --git a/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-gpt-5-5-tool-loop.json b/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-gpt-5-5-tool-loop.json index b66ea019af7..acb0dcdf623 100644 --- a/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-gpt-5-5-tool-loop.json +++ b/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-gpt-5-5-tool-loop.json @@ -14,7 +14,7 @@ "golden" ], "name": "openrouter-responses/openrouter-gpt-5-5-tool-loop", - "recordedAt": "2026-09-30T03:26:13.866Z" + "recordedAt": "2026-09-30T04:48:52.826Z" }, "interactions": [ { @@ -32,7 +32,7 @@ "headers": { "content-type": "text/event-stream" }, - "body": ": \n\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790738771-nM7FTP2v754TB4CQCDp4\",\"object\":\"response\",\"created_at\":1790738771,\"model\":\"openai/gpt-5.5\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":0}\n\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"gen-1790738771-nM7FTP2v754TB4CQCDp4\",\"object\":\"response\",\"created_at\":1790738771,\"model\":\"openai/gpt-5.5\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":1}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":0,\"item\":{\"id\":\"fc_tmp_vof08x1qo6\",\"type\":\"function_call\",\"status\":\"in_progress\",\"call_id\":\"call_F9FNCguEMjWkdTfg342UdEhk\",\"name\":\"get_weather\",\"arguments\":\"\"},\"sequence_number\":2}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_vof08x1qo6\",\"delta\":\"{\\\"\",\"sequence_number\":3}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_vof08x1qo6\",\"delta\":\"city\",\"sequence_number\":4}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_vof08x1qo6\",\"delta\":\"\\\":\\\"\",\"sequence_number\":5}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_vof08x1qo6\",\"delta\":\"Paris\",\"sequence_number\":6}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_vof08x1qo6\",\"delta\":\"\\\"}\",\"sequence_number\":7}\n\ndata: {\"type\":\"response.function_call_arguments.done\",\"output_index\":0,\"item_id\":\"fc_tmp_vof08x1qo6\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\",\"sequence_number\":8}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"fc_tmp_vof08x1qo6\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_F9FNCguEMjWkdTfg342UdEhk\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},\"sequence_number\":9}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790738771-nM7FTP2v754TB4CQCDp4\",\"object\":\"response\",\"created_at\":1790738771,\"model\":\"openai/gpt-5.5\",\"status\":\"completed\",\"completed_at\":1790738772,\"output\":[{\"id\":\"fc_tmp_vof08x1qo6\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_F9FNCguEMjWkdTfg342UdEhk\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"}],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"default\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"context\":\"current_turn\",\"effort\":\"medium\",\"mode\":\"standard\",\"summary\":\"detailed\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":{\"input_tokens\":74,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":18,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":92,\"cost\":0.00091,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.00091,\"upstream_inference_input_cost\":0.00037,\"upstream_inference_output_cost\":0.00054}}},\"sequence_number\":10}\n\ndata: [DONE]\n\n" + "body": ": \n\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790743730-TBsqgDmmlkyaUVNXg5O5\",\"object\":\"response\",\"created_at\":1790743730,\"model\":\"openai/gpt-5.5\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":0}\n\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"gen-1790743730-TBsqgDmmlkyaUVNXg5O5\",\"object\":\"response\",\"created_at\":1790743730,\"model\":\"openai/gpt-5.5\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":1}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":0,\"item\":{\"id\":\"fc_tmp_6ju3xhq3gge\",\"type\":\"function_call\",\"status\":\"in_progress\",\"call_id\":\"call_hC5pYJwmASjovJkP6GbuvfYm\",\"name\":\"get_weather\",\"arguments\":\"\"},\"sequence_number\":2}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_6ju3xhq3gge\",\"delta\":\"{\\\"\",\"sequence_number\":3}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_6ju3xhq3gge\",\"delta\":\"city\",\"sequence_number\":4}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_6ju3xhq3gge\",\"delta\":\"\\\":\\\"\",\"sequence_number\":5}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_6ju3xhq3gge\",\"delta\":\"Paris\",\"sequence_number\":6}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_6ju3xhq3gge\",\"delta\":\"\\\"}\",\"sequence_number\":7}\n\ndata: {\"type\":\"response.function_call_arguments.done\",\"output_index\":0,\"item_id\":\"fc_tmp_6ju3xhq3gge\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\",\"sequence_number\":8}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"fc_tmp_6ju3xhq3gge\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_hC5pYJwmASjovJkP6GbuvfYm\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},\"sequence_number\":9}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790743730-TBsqgDmmlkyaUVNXg5O5\",\"object\":\"response\",\"created_at\":1790743730,\"model\":\"openai/gpt-5.5\",\"status\":\"completed\",\"completed_at\":1790743731,\"output\":[{\"id\":\"fc_tmp_6ju3xhq3gge\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_hC5pYJwmASjovJkP6GbuvfYm\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"}],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"default\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"context\":\"current_turn\",\"effort\":\"medium\",\"mode\":\"standard\",\"summary\":\"detailed\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":{\"input_tokens\":74,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":18,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":92,\"cost\":0.00091,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.00091,\"upstream_inference_input_cost\":0.00037,\"upstream_inference_output_cost\":0.00054}}},\"sequence_number\":10}\n\ndata: [DONE]\n\n" } }, { @@ -43,14 +43,14 @@ "headers": { "content-type": "application/json" }, - "body": "{\"model\":\"openai/gpt-5.5\",\"input\":[{\"type\":\"message\",\"role\":\"user\",\"content\":[{\"type\":\"input_text\",\"text\":\"What is the weather in Paris?\"}]},{\"type\":\"function_call\",\"id\":\"fc_tmp_vof08x1qo6\",\"call_id\":\"call_F9FNCguEMjWkdTfg342UdEhk\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},{\"type\":\"function_call_output\",\"call_id\":\"call_F9FNCguEMjWkdTfg342UdEhk\",\"output\":\"{\\\"temperature\\\":22,\\\"condition\\\":\\\"sunny\\\"}\"}],\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false},\"strict\":false}],\"store\":false,\"include\":[\"reasoning.encrypted_content\"],\"max_output_tokens\":80,\"temperature\":0,\"stream\":true}" + "body": "{\"model\":\"openai/gpt-5.5\",\"input\":[{\"type\":\"message\",\"role\":\"user\",\"content\":[{\"type\":\"input_text\",\"text\":\"What is the weather in Paris?\"}]},{\"type\":\"function_call\",\"id\":\"fc_tmp_6ju3xhq3gge\",\"call_id\":\"call_hC5pYJwmASjovJkP6GbuvfYm\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},{\"type\":\"function_call_output\",\"call_id\":\"call_hC5pYJwmASjovJkP6GbuvfYm\",\"output\":\"{\\\"temperature\\\":22,\\\"condition\\\":\\\"sunny\\\"}\"}],\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false},\"strict\":false}],\"store\":false,\"include\":[\"reasoning.encrypted_content\"],\"max_output_tokens\":80,\"temperature\":0,\"stream\":true}" }, "response": { "status": 200, "headers": { "content-type": "text/event-stream" }, - "body": "data: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790738773-vqzGiRpuR0ffcPCUm7s1\",\"object\":\"response\",\"created_at\":1790738773,\"model\":\"openai/gpt-5.5\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":0}\n\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"gen-1790738773-vqzGiRpuR0ffcPCUm7s1\",\"object\":\"response\",\"created_at\":1790738773,\"model\":\"openai/gpt-5.5\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":1}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":0,\"item\":{\"id\":\"msg_tmp_2322zvyfdvh\",\"type\":\"message\",\"status\":\"in_progress\",\"role\":\"assistant\",\"content\":[],\"phase\":\"final_answer\"},\"sequence_number\":2}\n\ndata: {\"type\":\"response.content_part.added\",\"output_index\":0,\"item_id\":\"msg_tmp_2322zvyfdvh\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":3}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_2322zvyfdvh\",\"content_index\":0,\"delta\":\"Paris\",\"logprobs\":[],\"sequence_number\":4}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_2322zvyfdvh\",\"content_index\":0,\"delta\":\" is\",\"logprobs\":[],\"sequence_number\":5}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_2322zvyfdvh\",\"content_index\":0,\"delta\":\" sunny\",\"logprobs\":[],\"sequence_number\":6}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_2322zvyfdvh\",\"content_index\":0,\"delta\":\".\",\"logprobs\":[],\"sequence_number\":7}\n\ndata: {\"type\":\"response.output_text.done\",\"output_index\":0,\"item_id\":\"msg_tmp_2322zvyfdvh\",\"content_index\":0,\"text\":\"Paris is sunny.\",\"logprobs\":[],\"sequence_number\":8}\n\ndata: {\"type\":\"response.content_part.done\",\"output_index\":0,\"item_id\":\"msg_tmp_2322zvyfdvh\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":9}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"msg_tmp_2322zvyfdvh\",\"type\":\"message\",\"status\":\"completed\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]}],\"phase\":\"final_answer\"},\"sequence_number\":10}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790738773-vqzGiRpuR0ffcPCUm7s1\",\"object\":\"response\",\"created_at\":1790738773,\"model\":\"openai/gpt-5.5\",\"status\":\"completed\",\"completed_at\":1790738773,\"output\":[{\"id\":\"msg_tmp_2322zvyfdvh\",\"type\":\"message\",\"role\":\"assistant\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]}],\"phase\":\"final_answer\"}],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"default\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"context\":\"current_turn\",\"effort\":\"medium\",\"mode\":\"standard\",\"summary\":\"detailed\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":{\"input_tokens\":113,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":8,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":121,\"cost\":0.000805,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.000805,\"upstream_inference_input_cost\":0.000565,\"upstream_inference_output_cost\":0.00024}}},\"sequence_number\":11}\n\ndata: [DONE]\n\n" + "body": "data: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790743731-R9O5oZ5ZNdImLiASD27k\",\"object\":\"response\",\"created_at\":1790743731,\"model\":\"openai/gpt-5.5\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":0}\n\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"gen-1790743731-R9O5oZ5ZNdImLiASD27k\",\"object\":\"response\",\"created_at\":1790743731,\"model\":\"openai/gpt-5.5\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":null,\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":1}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":0,\"item\":{\"id\":\"msg_tmp_8gl1g6eek2n\",\"type\":\"message\",\"status\":\"in_progress\",\"role\":\"assistant\",\"content\":[],\"phase\":\"final_answer\"},\"sequence_number\":2}\n\ndata: {\"type\":\"response.content_part.added\",\"output_index\":0,\"item_id\":\"msg_tmp_8gl1g6eek2n\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":3}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_8gl1g6eek2n\",\"content_index\":0,\"delta\":\"Paris\",\"logprobs\":[],\"sequence_number\":4}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_8gl1g6eek2n\",\"content_index\":0,\"delta\":\" is\",\"logprobs\":[],\"sequence_number\":5}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_8gl1g6eek2n\",\"content_index\":0,\"delta\":\" sunny\",\"logprobs\":[],\"sequence_number\":6}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_8gl1g6eek2n\",\"content_index\":0,\"delta\":\".\",\"logprobs\":[],\"sequence_number\":7}\n\ndata: {\"type\":\"response.output_text.done\",\"output_index\":0,\"item_id\":\"msg_tmp_8gl1g6eek2n\",\"content_index\":0,\"text\":\"Paris is sunny.\",\"logprobs\":[],\"sequence_number\":8}\n\ndata: {\"type\":\"response.content_part.done\",\"output_index\":0,\"item_id\":\"msg_tmp_8gl1g6eek2n\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":9}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"msg_tmp_8gl1g6eek2n\",\"type\":\"message\",\"status\":\"completed\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]}],\"phase\":\"final_answer\"},\"sequence_number\":10}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790743731-R9O5oZ5ZNdImLiASD27k\",\"object\":\"response\",\"created_at\":1790743731,\"model\":\"openai/gpt-5.5\",\"status\":\"completed\",\"completed_at\":1790743732,\"output\":[{\"id\":\"msg_tmp_8gl1g6eek2n\",\"type\":\"message\",\"role\":\"assistant\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]}],\"phase\":\"final_answer\"}],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"default\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"context\":\"current_turn\",\"effort\":\"medium\",\"mode\":\"standard\",\"summary\":\"detailed\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":{\"input_tokens\":113,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":8,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":121,\"cost\":0.000805,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.000805,\"upstream_inference_input_cost\":0.000565,\"upstream_inference_output_cost\":0.00024}}},\"sequence_number\":11}\n\ndata: [DONE]\n\n" } } ] diff --git a/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-grok-4-3-tool-loop.json b/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-grok-4-3-tool-loop.json index 5ee4932cb15..3b1dbabbdbe 100644 --- a/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-grok-4-3-tool-loop.json +++ b/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-grok-4-3-tool-loop.json @@ -2,7 +2,7 @@ "version": 1, "metadata": { "provider": "openrouter", - "route": "openrouter-xai-responses", + "route": "openrouter-responses", "transport": "http", "model": "x-ai/grok-4.3", "tags": [ @@ -13,7 +13,7 @@ "golden" ], "name": "openrouter-responses/openrouter-grok-4-3-tool-loop", - "recordedAt": "2026-09-30T03:26:19.763Z" + "recordedAt": "2026-09-30T04:48:54.082Z" }, "interactions": [ { @@ -31,7 +31,7 @@ "headers": { "content-type": "text/event-stream" }, - "body": "data: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790738776-OaS8zCaMB7MS1nCdaImH\",\"object\":\"response\",\"created_at\":1790738776,\"model\":\"x-ai/grok-4.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"none\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":0}\n\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"gen-1790738776-OaS8zCaMB7MS1nCdaImH\",\"object\":\"response\",\"created_at\":1790738776,\"model\":\"x-ai/grok-4.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"none\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":1}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":0,\"item\":{\"id\":\"fc_tmp_ftf4v8gaphh\",\"type\":\"function_call\",\"status\":\"in_progress\",\"call_id\":\"call-44cd1503-ad11-4c48-891e-f4e38bd5ddcd-0\",\"name\":\"get_weather\",\"arguments\":\"\"},\"sequence_number\":2}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_ftf4v8gaphh\",\"delta\":\"{\\\"city\\\":\\\"Paris\\\"}\",\"sequence_number\":3}\n\ndata: {\"type\":\"response.function_call_arguments.done\",\"output_index\":0,\"item_id\":\"fc_tmp_ftf4v8gaphh\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\",\"sequence_number\":4}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"fc_tmp_ftf4v8gaphh\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call-44cd1503-ad11-4c48-891e-f4e38bd5ddcd-0\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},\"sequence_number\":5}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790738776-OaS8zCaMB7MS1nCdaImH\",\"object\":\"response\",\"created_at\":1790738776,\"model\":\"x-ai/grok-4.3\",\"status\":\"completed\",\"completed_at\":1790738779,\"output\":[{\"id\":\"fc_tmp_ftf4v8gaphh\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call-44cd1503-ad11-4c48-891e-f4e38bd5ddcd-0\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"}],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"default\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"none\",\"summary\":\"none\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":{\"input_tokens\":319,\"input_tokens_details\":{\"cached_tokens\":128},\"output_tokens\":10,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":329,\"cost\":0.00028935,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.00028935,\"upstream_inference_input_cost\":0.00026435,\"upstream_inference_output_cost\":0.000025}}},\"sequence_number\":6}\n\ndata: [DONE]\n\n" + "body": ": \n\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790743732-IVoOq91Eya07dPabKzsA\",\"object\":\"response\",\"created_at\":1790743732,\"model\":\"x-ai/grok-4.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"none\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":0}\n\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"gen-1790743732-IVoOq91Eya07dPabKzsA\",\"object\":\"response\",\"created_at\":1790743732,\"model\":\"x-ai/grok-4.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"none\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":1}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":0,\"item\":{\"id\":\"fc_tmp_pr5t3h6mjlq\",\"type\":\"function_call\",\"status\":\"in_progress\",\"call_id\":\"call-651cf23e-6c63-466e-9909-c1ee3187537b-0\",\"name\":\"get_weather\",\"arguments\":\"\"},\"sequence_number\":2}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_pr5t3h6mjlq\",\"delta\":\"{\\\"city\\\":\\\"Paris\\\"}\",\"sequence_number\":3}\n\ndata: {\"type\":\"response.function_call_arguments.done\",\"output_index\":0,\"item_id\":\"fc_tmp_pr5t3h6mjlq\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\",\"sequence_number\":4}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"fc_tmp_pr5t3h6mjlq\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call-651cf23e-6c63-466e-9909-c1ee3187537b-0\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},\"sequence_number\":5}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790743732-IVoOq91Eya07dPabKzsA\",\"object\":\"response\",\"created_at\":1790743732,\"model\":\"x-ai/grok-4.3\",\"status\":\"completed\",\"completed_at\":1790743733,\"output\":[{\"id\":\"fc_tmp_pr5t3h6mjlq\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call-651cf23e-6c63-466e-9909-c1ee3187537b-0\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"}],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"default\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"none\",\"summary\":\"none\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":{\"input_tokens\":319,\"input_tokens_details\":{\"cached_tokens\":128},\"output_tokens\":10,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":329,\"cost\":0.00028935,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.00028935,\"upstream_inference_input_cost\":0.00026435,\"upstream_inference_output_cost\":0.000025}}},\"sequence_number\":6}\n\ndata: [DONE]\n\n" } }, { @@ -42,14 +42,14 @@ "headers": { "content-type": "application/json" }, - "body": "{\"model\":\"x-ai/grok-4.3\",\"input\":[{\"type\":\"message\",\"role\":\"user\",\"content\":[{\"type\":\"input_text\",\"text\":\"What is the weather in Paris?\"}]},{\"type\":\"function_call\",\"id\":\"fc_tmp_ftf4v8gaphh\",\"call_id\":\"call-44cd1503-ad11-4c48-891e-f4e38bd5ddcd-0\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},{\"type\":\"function_call_output\",\"call_id\":\"call-44cd1503-ad11-4c48-891e-f4e38bd5ddcd-0\",\"output\":\"{\\\"temperature\\\":22,\\\"condition\\\":\\\"sunny\\\"}\"}],\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false},\"strict\":false}],\"store\":false,\"include\":[\"reasoning.encrypted_content\"],\"reasoning\":{\"effort\":\"none\"},\"max_output_tokens\":80,\"temperature\":0,\"stream\":true}" + "body": "{\"model\":\"x-ai/grok-4.3\",\"input\":[{\"type\":\"message\",\"role\":\"user\",\"content\":[{\"type\":\"input_text\",\"text\":\"What is the weather in Paris?\"}]},{\"type\":\"function_call\",\"id\":\"fc_tmp_pr5t3h6mjlq\",\"call_id\":\"call-651cf23e-6c63-466e-9909-c1ee3187537b-0\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},{\"type\":\"function_call_output\",\"call_id\":\"call-651cf23e-6c63-466e-9909-c1ee3187537b-0\",\"output\":\"{\\\"temperature\\\":22,\\\"condition\\\":\\\"sunny\\\"}\"}],\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false},\"strict\":false}],\"store\":false,\"include\":[\"reasoning.encrypted_content\"],\"reasoning\":{\"effort\":\"none\"},\"max_output_tokens\":80,\"temperature\":0,\"stream\":true}" }, "response": { "status": 200, "headers": { "content-type": "text/event-stream" }, - "body": "data: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790738779-ygPkwiCZ8i55I0OU5AXm\",\"object\":\"response\",\"created_at\":1790738779,\"model\":\"x-ai/grok-4.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"none\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":0}\n\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"gen-1790738779-ygPkwiCZ8i55I0OU5AXm\",\"object\":\"response\",\"created_at\":1790738779,\"model\":\"x-ai/grok-4.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"none\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":1}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":0,\"item\":{\"id\":\"msg_tmp_t5a8kv69a6\",\"type\":\"message\",\"status\":\"in_progress\",\"role\":\"assistant\",\"content\":[]},\"sequence_number\":2}\n\ndata: {\"type\":\"response.content_part.added\",\"output_index\":0,\"item_id\":\"msg_tmp_t5a8kv69a6\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":3}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_t5a8kv69a6\",\"content_index\":0,\"delta\":\"Paris\",\"logprobs\":[],\"sequence_number\":4}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_t5a8kv69a6\",\"content_index\":0,\"delta\":\" is\",\"logprobs\":[],\"sequence_number\":5}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_t5a8kv69a6\",\"content_index\":0,\"delta\":\" sunny\",\"logprobs\":[],\"sequence_number\":6}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_t5a8kv69a6\",\"content_index\":0,\"delta\":\".\",\"logprobs\":[],\"sequence_number\":7}\n\ndata: {\"type\":\"response.output_text.done\",\"output_index\":0,\"item_id\":\"msg_tmp_t5a8kv69a6\",\"content_index\":0,\"text\":\"Paris is sunny.\",\"logprobs\":[],\"sequence_number\":8}\n\ndata: {\"type\":\"response.content_part.done\",\"output_index\":0,\"item_id\":\"msg_tmp_t5a8kv69a6\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":9}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"msg_tmp_t5a8kv69a6\",\"type\":\"message\",\"status\":\"completed\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]}]},\"sequence_number\":10}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790738779-ygPkwiCZ8i55I0OU5AXm\",\"object\":\"response\",\"created_at\":1790738779,\"model\":\"x-ai/grok-4.3\",\"status\":\"completed\",\"completed_at\":1790738779,\"output\":[{\"id\":\"msg_tmp_t5a8kv69a6\",\"type\":\"message\",\"role\":\"assistant\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]}]}],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"default\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"none\",\"summary\":\"none\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":{\"input_tokens\":344,\"input_tokens_details\":{\"cached_tokens\":256},\"output_tokens\":4,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":348,\"cost\":0.0001712,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.0001712,\"upstream_inference_input_cost\":0.0001612,\"upstream_inference_output_cost\":0.00001}}},\"sequence_number\":11}\n\ndata: [DONE]\n\n" + "body": "data: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790743733-CAH2sthoK7dycbV0bIpG\",\"object\":\"response\",\"created_at\":1790743733,\"model\":\"x-ai/grok-4.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"none\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":0}\n\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"gen-1790743733-CAH2sthoK7dycbV0bIpG\",\"object\":\"response\",\"created_at\":1790743733,\"model\":\"x-ai/grok-4.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"none\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":1}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":0,\"item\":{\"id\":\"msg_tmp_qd0ajwonyi\",\"type\":\"message\",\"status\":\"in_progress\",\"role\":\"assistant\",\"content\":[]},\"sequence_number\":2}\n\ndata: {\"type\":\"response.content_part.added\",\"output_index\":0,\"item_id\":\"msg_tmp_qd0ajwonyi\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":3}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_qd0ajwonyi\",\"content_index\":0,\"delta\":\"Paris\",\"logprobs\":[],\"sequence_number\":4}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_qd0ajwonyi\",\"content_index\":0,\"delta\":\" is\",\"logprobs\":[],\"sequence_number\":5}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_qd0ajwonyi\",\"content_index\":0,\"delta\":\" sunny\",\"logprobs\":[],\"sequence_number\":6}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_qd0ajwonyi\",\"content_index\":0,\"delta\":\".\",\"logprobs\":[],\"sequence_number\":7}\n\ndata: {\"type\":\"response.output_text.done\",\"output_index\":0,\"item_id\":\"msg_tmp_qd0ajwonyi\",\"content_index\":0,\"text\":\"Paris is sunny.\",\"logprobs\":[],\"sequence_number\":8}\n\ndata: {\"type\":\"response.content_part.done\",\"output_index\":0,\"item_id\":\"msg_tmp_qd0ajwonyi\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":9}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"msg_tmp_qd0ajwonyi\",\"type\":\"message\",\"status\":\"completed\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]}]},\"sequence_number\":10}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790743733-CAH2sthoK7dycbV0bIpG\",\"object\":\"response\",\"created_at\":1790743733,\"model\":\"x-ai/grok-4.3\",\"status\":\"completed\",\"completed_at\":1790743734,\"output\":[{\"id\":\"msg_tmp_qd0ajwonyi\",\"type\":\"message\",\"role\":\"assistant\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]}]}],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":80,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"default\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"none\",\"summary\":\"none\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":{\"input_tokens\":344,\"input_tokens_details\":{\"cached_tokens\":128},\"output_tokens\":4,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":348,\"cost\":0.0003056,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.0003056,\"upstream_inference_input_cost\":0.0002956,\"upstream_inference_output_cost\":0.00001}}},\"sequence_number\":11}\n\ndata: [DONE]\n\n" } } ] diff --git a/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-muse-spark-1-3-tool-loop.json b/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-muse-spark-1-3-tool-loop.json index 259bbb11e30..c8f5bc9d78d 100644 --- a/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-muse-spark-1-3-tool-loop.json +++ b/packages/ai/test/fixtures/recordings/openrouter-responses/openrouter-muse-spark-1-3-tool-loop.json @@ -4,12 +4,12 @@ "tags": [ "prefix:openrouter-responses", "provider:openrouter", - "protocol:openrouter-meta-responses", + "protocol:openrouter-responses", "reasoning", "tool-loop" ], "name": "openrouter-responses/openrouter-muse-spark-1-3-tool-loop", - "recordedAt": "2026-09-30T03:32:53.229Z" + "recordedAt": "2026-09-30T04:48:45.728Z" }, "interactions": [ { @@ -27,7 +27,7 @@ "headers": { "content-type": "text/event-stream" }, - "body": ": \n\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790739168-uSDGksR88nHdEZ2lOExQ\",\"object\":\"response\",\"created_at\":1790739168,\"model\":\"meta/muse-spark-1.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":512,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"minimal\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":0}\n\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"gen-1790739168-uSDGksR88nHdEZ2lOExQ\",\"object\":\"response\",\"created_at\":1790739168,\"model\":\"meta/muse-spark-1.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":512,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"minimal\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":1}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":0,\"item\":{\"id\":\"rs_6abc82e12dc2c1865a434c99:rs_01a0f05f42ee74d58e4ad73c38fdd005\",\"type\":\"reasoning\",\"status\":\"in_progress\",\"summary\":[]},\"sequence_number\":2}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"rs_6abc82e12dc2c1865a434c99:rs_01a0f05f42ee74d58e4ad73c38fdd005\",\"type\":\"reasoning\",\"status\":\"completed\",\"summary\":[],\"encrypted_content\":\"Q-PaDgGvEl142LfYup3S4ihP7G1aAhfJrfmM--SKxDNE4lWnWAjb48UQAQ1J3z0n9BT9I0Qr6LXuYuF2GKPXzq4gzOjTe4ZoKpJzVm5fWNT_KuVlO68UYut5mIHISxXvUjcPCP1c_H0gtcqaCF8Qlj2cSaK1ce-dkQm1gTS2VES5AtfmFmNmb6AFxiCLeuHugxHG28M1TbpfwxkEwUq_iIIFe7GoJnO7_p5_CD3jLOTWlXBVTqIMiUKpR3Dffhi8K16DjGbJqlJ0KCCFlgsqzqhvhq3vWRHIorEI2IdOo3OV6FPpFVgsDGuYdlUaSRt1HOUqVKKrX6jSWYeliOAkBadb_MDf8KVGDQ9_LN-K3vSjetT8ug_TFdogcLUmBzoZe3BGbsiEXN8F10not_aMZErDsmjFBCpRSv2iHJit58AWg1OpeHPJXJ2bRJpsHGoANQT0O0V8PvTOnUc4k5FQA9NDA8517wdaHCOQUYHxOehlINZ1R67k5hhd_MzXw7g2aW6BGOcUoJ_tFZUxD77TmZURsoPukyJXbaPSp7S3bU7olR6-gvBqcBhuYG2FLO9eT0OYBL4JzTJypUIPglZBANrY1c-D5YQchqAskNGN4I0DXYNwE_TEmUMqOqeCVTILZEZYpiWqsxKfVH43LtDxsqzJ7IvoFFJCwc0hP4SSUgxbc6d1g9o8xOSp59wYt34wi1ORMYAWXqToK6RfdnKBDLyZcvh02NuM4JyTb9dd5E3OVNsopLhftCZ1hMXn1RLmjOPmO80aWq8zuVXWRO_itKSRbs4WVH1viviOi6LKFMhtJGVSnxJe1-1Hp61_9hUtlTYjlrZX_Tmfl8BuCdFEtpIRWbnCARpt4AGSIDikoG442sbfbjVZ8RM_AGdzoZtlfpAGcv3zhWGkk1KXZIBYT2vqO6IKdWNHYJ9IC0iL5WU53jMmwM7J1wN4V9-xxFL7mhdjTNAAKwHb26OJ2gzKmRavUsgv8gVr6UvvG3U4Q83mqN62sIF8PJtjeS9dngZDNZ7cmr5F33nCIN6K3uK9g_qz7EiOZac0ff5GstDHUUg67BBQW7i871PAdDyRPK45tjPjVWKwuNNv8XRfaSc_v84zX5pDpB8lgn1uFUJTQv_em2RsG7dxY-_icr3BqzemQ6tIHcryw31iQfiWq4ygbjsJpvV8hxdnqz84BKmTIU-bq5TaohuYhIgmoTkTVFF68uJao2Re43m-lHqeSDNpCOf-KIjP858XUOFRD8EUTOMT_WyCKAVHgd9ePreXlBSelTdca3XPZlZz5gRu3W1-f88AqpuE1t9oKACKGh_UO099Ek5aKPW7qt2kXkccsH19R3HVtOlBwTxuiQBAr8ZopGEaqJ15AZctXBJOUCihJGKCYP5mkk5k6DJvr_kjSn4EgbV4g2_VHn2GpWqqoQ.eyJlbmRwb2ludF9zbHVnIjoibWV0YS9tdXNlLXNwYXJrLTEuMy0yMDI2MDkwMnxtZXRhIn0\",\"format\":\"meta-responses-v1\"},\"sequence_number\":3}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":1,\"item\":{\"id\":\"msg_tmp_zh7615lyb2c\",\"type\":\"message\",\"status\":\"in_progress\",\"role\":\"assistant\",\"content\":[],\"phase\":\"commentary\"},\"sequence_number\":4}\n\ndata: {\"type\":\"response.content_part.added\",\"output_index\":1,\"item_id\":\"msg_tmp_zh7615lyb2c\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":5}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":1,\"item_id\":\"msg_tmp_zh7615lyb2c\",\"content_index\":0,\"delta\":\"I'll check the weather in Paris for you.\",\"logprobs\":[],\"sequence_number\":6}\n\ndata: {\"type\":\"response.output_text.done\",\"output_index\":1,\"item_id\":\"msg_tmp_zh7615lyb2c\",\"content_index\":0,\"text\":\"I'll check the weather in Paris for you.\",\"logprobs\":[],\"sequence_number\":7}\n\ndata: {\"type\":\"response.content_part.done\",\"output_index\":1,\"item_id\":\"msg_tmp_zh7615lyb2c\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"I'll check the weather in Paris for you.\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":8}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":1,\"item\":{\"id\":\"msg_tmp_zh7615lyb2c\",\"type\":\"message\",\"status\":\"completed\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"I'll check the weather in Paris for you.\",\"annotations\":[],\"logprobs\":[]}],\"phase\":\"commentary\"},\"sequence_number\":9}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":2,\"item\":{\"id\":\"fc_tmp_czd2g24z4r\",\"type\":\"function_call\",\"status\":\"in_progress\",\"call_id\":\"call_01a0f05f47dc715eac41131ff82ebcfe\",\"name\":\"get_weather\",\"arguments\":\"\"},\"sequence_number\":10}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":2,\"item_id\":\"fc_tmp_czd2g24z4r\",\"delta\":\"{\\\"city\\\":\\\"Paris\\\"}\",\"sequence_number\":11}\n\ndata: {\"type\":\"response.function_call_arguments.done\",\"output_index\":2,\"item_id\":\"fc_tmp_czd2g24z4r\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\",\"sequence_number\":12}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":2,\"item\":{\"id\":\"fc_tmp_czd2g24z4r\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_01a0f05f47dc715eac41131ff82ebcfe\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},\"sequence_number\":13}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790739168-uSDGksR88nHdEZ2lOExQ\",\"object\":\"response\",\"created_at\":1790739168,\"model\":\"meta/muse-spark-1.3\",\"status\":\"completed\",\"completed_at\":1790739171,\"output\":[{\"id\":\"rs_6abc82e12dc2c1865a434c99:rs_01a0f05f42ee74d58e4ad73c38fdd005\",\"type\":\"reasoning\",\"status\":\"completed\",\"summary\":[],\"encrypted_content\":\"Q-PaDgGvEl142LfYup3S4ihP7G1aAhfJrfmM--SKxDNE4lWnWAjb48UQAQ1J3z0n9BT9I0Qr6LXuYuF2GKPXzq4gzOjTe4ZoKpJzVm5fWNT_KuVlO68UYut5mIHISxXvUjcPCP1c_H0gtcqaCF8Qlj2cSaK1ce-dkQm1gTS2VES5AtfmFmNmb6AFxiCLeuHugxHG28M1TbpfwxkEwUq_iIIFe7GoJnO7_p5_CD3jLOTWlXBVTqIMiUKpR3Dffhi8K16DjGbJqlJ0KCCFlgsqzqhvhq3vWRHIorEI2IdOo3OV6FPpFVgsDGuYdlUaSRt1HOUqVKKrX6jSWYeliOAkBadb_MDf8KVGDQ9_LN-K3vSjetT8ug_TFdogcLUmBzoZe3BGbsiEXN8F10not_aMZErDsmjFBCpRSv2iHJit58AWg1OpeHPJXJ2bRJpsHGoANQT0O0V8PvTOnUc4k5FQA9NDA8517wdaHCOQUYHxOehlINZ1R67k5hhd_MzXw7g2aW6BGOcUoJ_tFZUxD77TmZURsoPukyJXbaPSp7S3bU7olR6-gvBqcBhuYG2FLO9eT0OYBL4JzTJypUIPglZBANrY1c-D5YQchqAskNGN4I0DXYNwE_TEmUMqOqeCVTILZEZYpiWqsxKfVH43LtDxsqzJ7IvoFFJCwc0hP4SSUgxbc6d1g9o8xOSp59wYt34wi1ORMYAWXqToK6RfdnKBDLyZcvh02NuM4JyTb9dd5E3OVNsopLhftCZ1hMXn1RLmjOPmO80aWq8zuVXWRO_itKSRbs4WVH1viviOi6LKFMhtJGVSnxJe1-1Hp61_9hUtlTYjlrZX_Tmfl8BuCdFEtpIRWbnCARpt4AGSIDikoG442sbfbjVZ8RM_AGdzoZtlfpAGcv3zhWGkk1KXZIBYT2vqO6IKdWNHYJ9IC0iL5WU53jMmwM7J1wN4V9-xxFL7mhdjTNAAKwHb26OJ2gzKmRavUsgv8gVr6UvvG3U4Q83mqN62sIF8PJtjeS9dngZDNZ7cmr5F33nCIN6K3uK9g_qz7EiOZac0ff5GstDHUUg67BBQW7i871PAdDyRPK45tjPjVWKwuNNv8XRfaSc_v84zX5pDpB8lgn1uFUJTQv_em2RsG7dxY-_icr3BqzemQ6tIHcryw31iQfiWq4ygbjsJpvV8hxdnqz84BKmTIU-bq5TaohuYhIgmoTkTVFF68uJao2Re43m-lHqeSDNpCOf-KIjP858XUOFRD8EUTOMT_WyCKAVHgd9ePreXlBSelTdca3XPZlZz5gRu3W1-f88AqpuE1t9oKACKGh_UO099Ek5aKPW7qt2kXkccsH19R3HVtOlBwTxuiQBAr8ZopGEaqJ15AZctXBJOUCihJGKCYP5mkk5k6DJvr_kjSn4EgbV4g2_VHn2GpWqqoQ.eyJlbmRwb2ludF9zbHVnIjoibWV0YS9tdXNlLXNwYXJrLTEuMy0yMDI2MDkwMnxtZXRhIn0\",\"format\":\"meta-responses-v1\"},{\"id\":\"msg_tmp_zh7615lyb2c\",\"type\":\"message\",\"role\":\"assistant\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"text\":\"I'll check the weather in Paris for you.\",\"annotations\":[],\"logprobs\":[]}],\"phase\":\"commentary\"},{\"id\":\"fc_tmp_czd2g24z4r\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_01a0f05f47dc715eac41131ff82ebcfe\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"}],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":512,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"minimal\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":{\"input_tokens\":576,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":92,\"output_tokens_details\":{\"reasoning_tokens\":24},\"total_tokens\":668,\"cost\":0.001111,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.001111,\"upstream_inference_input_cost\":0.00072,\"upstream_inference_output_cost\":0.000391}}},\"sequence_number\":14}\n\ndata: [DONE]\n\n" + "body": "data: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790743723-OKwFcQN2fRHIDoTg54A9\",\"object\":\"response\",\"created_at\":1790743723,\"model\":\"meta/muse-spark-1.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":512,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"minimal\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":0}\n\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"gen-1790743723-OKwFcQN2fRHIDoTg54A9\",\"object\":\"response\",\"created_at\":1790743723,\"model\":\"meta/muse-spark-1.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":512,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"minimal\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":1}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":0,\"item\":{\"id\":\"rs_6abc94ac811510dbe9cd499e:rs_01a0f0a4c0987619ba7f345b8b8c2533\",\"type\":\"reasoning\",\"status\":\"in_progress\",\"summary\":[]},\"sequence_number\":2}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"rs_6abc94ac811510dbe9cd499e:rs_01a0f0a4c0987619ba7f345b8b8c2533\",\"type\":\"reasoning\",\"status\":\"completed\",\"summary\":[],\"encrypted_content\":\"Q-PaDgEYAMb2z63CGja44txE6OuW6S9kKYV_-MuZA53bZ9iNm2UyPs_q-dSb-_PvhOnUEvRGYuiKMlhzQF-SMPH37wg9G1SVg3TOFmT6jUJkm0zfA3wLV3Gcv01lGYe39JX4Ze65yeNgvQGW5ClhNSsKFdMn3FTTKHMLFQmlzmWODS4Az-hu4kxBE8MBd3_fTfLul6Eb-wEUSL9xn4BEDMtNauidvHAWXpaT6EKBlTeZ2xZ4EThOhZ9d-kFcyjr4FVsSOSl8I-aPqjToFh58brxa80Bqr0CLekQ9NyR2FA_hSh1IWoMBI6_T5pUUka_PPharMLpWEo35NeYgRHgLpjDaD43DG0bcFWfxyHdrPwZSMycAyXvFXyTfnKHAXdaIGts4_FmW4TZ8XVRCHsmWu8LoCI8PbJDNdNl04uM8s2Zyh6_bJqbcJAzRMC7uGq7VIYzlPF25aT97XMuJFWi8FKUy8GBYynGYE_gPta6fNDDzYWDAii8Yfr91Ju3gOBMYO_xnuVH6_8vgBMcd8l40cxBDyj540feI0V--WLcCk10u1tcTknLljuNEBEujHg6hZKp9ym7OikEmJRml33qY-q5fbW80CsO0wuKR9ScxqR4JfPgIoPJkOgSpeVFVwoiiX3cMjHWBSj7eSVJVVuRyWHc8-2f4HOb4big993TmVKlcAAeYv1HPgWP1C80tRc_CfhkmeMa230LupP7R5tRw2l5jHhJNkIYxeB8C1BQj6xwDw21GXcu8HtAO9u2pZlBIwfLGmFiSjsYf0WwUn4G9iswKc9gmRkczjiXq2psu1wotgucCQ_CbVWA8At78sehpjE-S8rzxvqG71Wb1yRY_IQAMaJXeGrhTN8Sfynlro4YKGdVznq0pRTEAButToZmQmXTLeI0J7-nyFLwzJlnCdDQCbX3ucFpKS7O71mbXoN2TXvlMmQWQrPmwMfNRASY8fWZf88Al5xRzODYn_68pU1eSL7fKkc6XahFGEfEx3-daOQUQbrx4V-JX6tqQDQp8tawHjFk67h-NIs9gNMTs6wEc6eOGmVzEEFg8jTauoJQjbI-sgHcVToDRG3xc3EakCtBKw0wxf6tzVWUjM2IbbrohoiymblizRIRzHX2WmEFlhjadSdO9N-rqodFAdGOi5UcTvmntDJk0JiJtBRQGoWIvq6sBZwdSEkMTWvPD4iXFjkKNcXFGw_6A8nAiI9CXp6j5upxrA-BxaXPBZeB6CPiLQElSv_TI1VsWdwmZut_5CxNjHvtfAF5SQ79LOsRilszSHhtLndJluvxkXSMww3hMThAxwbhjImYYKQQUUIJRy2fxtY3TsUH4xNCxp0JbJ3wWmB7fBh83jFjhrMDBuWCHXK7CuMSEPzAuVzBlOIX_eFkI1v08mfth_soBxDYy_-cn_rP6Ox2-pR6jwg.eyJlbmRwb2ludF9zbHVnIjoibWV0YS9tdXNlLXNwYXJrLTEuMy0yMDI2MDkwMnxtZXRhIn0\",\"format\":\"meta-responses-v1\"},\"sequence_number\":3}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":1,\"item\":{\"id\":\"msg_tmp_qs9pl1gaflr\",\"type\":\"message\",\"status\":\"in_progress\",\"role\":\"assistant\",\"content\":[],\"phase\":\"commentary\"},\"sequence_number\":4}\n\ndata: {\"type\":\"response.content_part.added\",\"output_index\":1,\"item_id\":\"msg_tmp_qs9pl1gaflr\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":5}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":1,\"item_id\":\"msg_tmp_qs9pl1gaflr\",\"content_index\":0,\"delta\":\"I'll check the weather in Paris for you.\",\"logprobs\":[],\"sequence_number\":6}\n\ndata: {\"type\":\"response.output_text.done\",\"output_index\":1,\"item_id\":\"msg_tmp_qs9pl1gaflr\",\"content_index\":0,\"text\":\"I'll check the weather in Paris for you.\",\"logprobs\":[],\"sequence_number\":7}\n\ndata: {\"type\":\"response.content_part.done\",\"output_index\":1,\"item_id\":\"msg_tmp_qs9pl1gaflr\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"I'll check the weather in Paris for you.\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":8}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":1,\"item\":{\"id\":\"msg_tmp_qs9pl1gaflr\",\"type\":\"message\",\"status\":\"completed\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"I'll check the weather in Paris for you.\",\"annotations\":[],\"logprobs\":[]}],\"phase\":\"commentary\"},\"sequence_number\":9}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":2,\"item\":{\"id\":\"fc_tmp_zvz6k6236km\",\"type\":\"function_call\",\"status\":\"in_progress\",\"call_id\":\"call_01a0f0a4c1fe755d9f280fb40b317fc4\",\"name\":\"get_weather\",\"arguments\":\"\"},\"sequence_number\":10}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":2,\"item_id\":\"fc_tmp_zvz6k6236km\",\"delta\":\"{\\\"city\\\":\\\"Paris\\\"}\",\"sequence_number\":11}\n\ndata: {\"type\":\"response.function_call_arguments.done\",\"output_index\":2,\"item_id\":\"fc_tmp_zvz6k6236km\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\",\"sequence_number\":12}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":2,\"item\":{\"id\":\"fc_tmp_zvz6k6236km\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_01a0f0a4c1fe755d9f280fb40b317fc4\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},\"sequence_number\":13}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790743723-OKwFcQN2fRHIDoTg54A9\",\"object\":\"response\",\"created_at\":1790743723,\"model\":\"meta/muse-spark-1.3\",\"status\":\"completed\",\"completed_at\":1790743724,\"output\":[{\"id\":\"rs_6abc94ac811510dbe9cd499e:rs_01a0f0a4c0987619ba7f345b8b8c2533\",\"type\":\"reasoning\",\"status\":\"completed\",\"summary\":[],\"encrypted_content\":\"Q-PaDgEYAMb2z63CGja44txE6OuW6S9kKYV_-MuZA53bZ9iNm2UyPs_q-dSb-_PvhOnUEvRGYuiKMlhzQF-SMPH37wg9G1SVg3TOFmT6jUJkm0zfA3wLV3Gcv01lGYe39JX4Ze65yeNgvQGW5ClhNSsKFdMn3FTTKHMLFQmlzmWODS4Az-hu4kxBE8MBd3_fTfLul6Eb-wEUSL9xn4BEDMtNauidvHAWXpaT6EKBlTeZ2xZ4EThOhZ9d-kFcyjr4FVsSOSl8I-aPqjToFh58brxa80Bqr0CLekQ9NyR2FA_hSh1IWoMBI6_T5pUUka_PPharMLpWEo35NeYgRHgLpjDaD43DG0bcFWfxyHdrPwZSMycAyXvFXyTfnKHAXdaIGts4_FmW4TZ8XVRCHsmWu8LoCI8PbJDNdNl04uM8s2Zyh6_bJqbcJAzRMC7uGq7VIYzlPF25aT97XMuJFWi8FKUy8GBYynGYE_gPta6fNDDzYWDAii8Yfr91Ju3gOBMYO_xnuVH6_8vgBMcd8l40cxBDyj540feI0V--WLcCk10u1tcTknLljuNEBEujHg6hZKp9ym7OikEmJRml33qY-q5fbW80CsO0wuKR9ScxqR4JfPgIoPJkOgSpeVFVwoiiX3cMjHWBSj7eSVJVVuRyWHc8-2f4HOb4big993TmVKlcAAeYv1HPgWP1C80tRc_CfhkmeMa230LupP7R5tRw2l5jHhJNkIYxeB8C1BQj6xwDw21GXcu8HtAO9u2pZlBIwfLGmFiSjsYf0WwUn4G9iswKc9gmRkczjiXq2psu1wotgucCQ_CbVWA8At78sehpjE-S8rzxvqG71Wb1yRY_IQAMaJXeGrhTN8Sfynlro4YKGdVznq0pRTEAButToZmQmXTLeI0J7-nyFLwzJlnCdDQCbX3ucFpKS7O71mbXoN2TXvlMmQWQrPmwMfNRASY8fWZf88Al5xRzODYn_68pU1eSL7fKkc6XahFGEfEx3-daOQUQbrx4V-JX6tqQDQp8tawHjFk67h-NIs9gNMTs6wEc6eOGmVzEEFg8jTauoJQjbI-sgHcVToDRG3xc3EakCtBKw0wxf6tzVWUjM2IbbrohoiymblizRIRzHX2WmEFlhjadSdO9N-rqodFAdGOi5UcTvmntDJk0JiJtBRQGoWIvq6sBZwdSEkMTWvPD4iXFjkKNcXFGw_6A8nAiI9CXp6j5upxrA-BxaXPBZeB6CPiLQElSv_TI1VsWdwmZut_5CxNjHvtfAF5SQ79LOsRilszSHhtLndJluvxkXSMww3hMThAxwbhjImYYKQQUUIJRy2fxtY3TsUH4xNCxp0JbJ3wWmB7fBh83jFjhrMDBuWCHXK7CuMSEPzAuVzBlOIX_eFkI1v08mfth_soBxDYy_-cn_rP6Ox2-pR6jwg.eyJlbmRwb2ludF9zbHVnIjoibWV0YS9tdXNlLXNwYXJrLTEuMy0yMDI2MDkwMnxtZXRhIn0\",\"format\":\"meta-responses-v1\"},{\"id\":\"msg_tmp_qs9pl1gaflr\",\"type\":\"message\",\"role\":\"assistant\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"text\":\"I'll check the weather in Paris for you.\",\"annotations\":[],\"logprobs\":[]}],\"phase\":\"commentary\"},{\"id\":\"fc_tmp_zvz6k6236km\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_01a0f0a4c1fe755d9f280fb40b317fc4\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"}],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":512,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"minimal\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":{\"input_tokens\":576,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":96,\"output_tokens_details\":{\"reasoning_tokens\":28},\"total_tokens\":672,\"cost\":0.001128,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.001128,\"upstream_inference_input_cost\":0.00072,\"upstream_inference_output_cost\":0.000408}}},\"sequence_number\":14}\n\ndata: [DONE]\n\n" } }, { @@ -38,14 +38,14 @@ "headers": { "content-type": "application/json" }, - "body": "{\"model\":\"meta/muse-spark-1.3\",\"input\":[{\"type\":\"message\",\"role\":\"user\",\"content\":[{\"type\":\"input_text\",\"text\":\"What is the weather in Paris?\"}]},{\"type\":\"reasoning\",\"id\":\"rs_6abc82e12dc2c1865a434c99:rs_01a0f05f42ee74d58e4ad73c38fdd005\",\"summary\":[],\"encrypted_content\":\"Q-PaDgGvEl142LfYup3S4ihP7G1aAhfJrfmM--SKxDNE4lWnWAjb48UQAQ1J3z0n9BT9I0Qr6LXuYuF2GKPXzq4gzOjTe4ZoKpJzVm5fWNT_KuVlO68UYut5mIHISxXvUjcPCP1c_H0gtcqaCF8Qlj2cSaK1ce-dkQm1gTS2VES5AtfmFmNmb6AFxiCLeuHugxHG28M1TbpfwxkEwUq_iIIFe7GoJnO7_p5_CD3jLOTWlXBVTqIMiUKpR3Dffhi8K16DjGbJqlJ0KCCFlgsqzqhvhq3vWRHIorEI2IdOo3OV6FPpFVgsDGuYdlUaSRt1HOUqVKKrX6jSWYeliOAkBadb_MDf8KVGDQ9_LN-K3vSjetT8ug_TFdogcLUmBzoZe3BGbsiEXN8F10not_aMZErDsmjFBCpRSv2iHJit58AWg1OpeHPJXJ2bRJpsHGoANQT0O0V8PvTOnUc4k5FQA9NDA8517wdaHCOQUYHxOehlINZ1R67k5hhd_MzXw7g2aW6BGOcUoJ_tFZUxD77TmZURsoPukyJXbaPSp7S3bU7olR6-gvBqcBhuYG2FLO9eT0OYBL4JzTJypUIPglZBANrY1c-D5YQchqAskNGN4I0DXYNwE_TEmUMqOqeCVTILZEZYpiWqsxKfVH43LtDxsqzJ7IvoFFJCwc0hP4SSUgxbc6d1g9o8xOSp59wYt34wi1ORMYAWXqToK6RfdnKBDLyZcvh02NuM4JyTb9dd5E3OVNsopLhftCZ1hMXn1RLmjOPmO80aWq8zuVXWRO_itKSRbs4WVH1viviOi6LKFMhtJGVSnxJe1-1Hp61_9hUtlTYjlrZX_Tmfl8BuCdFEtpIRWbnCARpt4AGSIDikoG442sbfbjVZ8RM_AGdzoZtlfpAGcv3zhWGkk1KXZIBYT2vqO6IKdWNHYJ9IC0iL5WU53jMmwM7J1wN4V9-xxFL7mhdjTNAAKwHb26OJ2gzKmRavUsgv8gVr6UvvG3U4Q83mqN62sIF8PJtjeS9dngZDNZ7cmr5F33nCIN6K3uK9g_qz7EiOZac0ff5GstDHUUg67BBQW7i871PAdDyRPK45tjPjVWKwuNNv8XRfaSc_v84zX5pDpB8lgn1uFUJTQv_em2RsG7dxY-_icr3BqzemQ6tIHcryw31iQfiWq4ygbjsJpvV8hxdnqz84BKmTIU-bq5TaohuYhIgmoTkTVFF68uJao2Re43m-lHqeSDNpCOf-KIjP858XUOFRD8EUTOMT_WyCKAVHgd9ePreXlBSelTdca3XPZlZz5gRu3W1-f88AqpuE1t9oKACKGh_UO099Ek5aKPW7qt2kXkccsH19R3HVtOlBwTxuiQBAr8ZopGEaqJ15AZctXBJOUCihJGKCYP5mkk5k6DJvr_kjSn4EgbV4g2_VHn2GpWqqoQ.eyJlbmRwb2ludF9zbHVnIjoibWV0YS9tdXNlLXNwYXJrLTEuMy0yMDI2MDkwMnxtZXRhIn0\"},{\"type\":\"message\",\"id\":\"msg_tmp_zh7615lyb2c\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"I'll check the weather in Paris for you.\"}],\"phase\":\"commentary\",\"status\":\"completed\"},{\"type\":\"function_call\",\"id\":\"fc_tmp_czd2g24z4r\",\"call_id\":\"call_01a0f05f47dc715eac41131ff82ebcfe\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},{\"type\":\"function_call_output\",\"call_id\":\"call_01a0f05f47dc715eac41131ff82ebcfe\",\"output\":\"{\\\"temperature\\\":22,\\\"condition\\\":\\\"sunny\\\"}\"}],\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false},\"strict\":false}],\"store\":false,\"include\":[\"reasoning.encrypted_content\"],\"reasoning\":{\"effort\":\"minimal\"},\"max_output_tokens\":512,\"temperature\":0,\"stream\":true}" + "body": "{\"model\":\"meta/muse-spark-1.3\",\"input\":[{\"type\":\"message\",\"role\":\"user\",\"content\":[{\"type\":\"input_text\",\"text\":\"What is the weather in Paris?\"}]},{\"type\":\"reasoning\",\"id\":\"rs_6abc94ac811510dbe9cd499e:rs_01a0f0a4c0987619ba7f345b8b8c2533\",\"summary\":[],\"encrypted_content\":\"Q-PaDgEYAMb2z63CGja44txE6OuW6S9kKYV_-MuZA53bZ9iNm2UyPs_q-dSb-_PvhOnUEvRGYuiKMlhzQF-SMPH37wg9G1SVg3TOFmT6jUJkm0zfA3wLV3Gcv01lGYe39JX4Ze65yeNgvQGW5ClhNSsKFdMn3FTTKHMLFQmlzmWODS4Az-hu4kxBE8MBd3_fTfLul6Eb-wEUSL9xn4BEDMtNauidvHAWXpaT6EKBlTeZ2xZ4EThOhZ9d-kFcyjr4FVsSOSl8I-aPqjToFh58brxa80Bqr0CLekQ9NyR2FA_hSh1IWoMBI6_T5pUUka_PPharMLpWEo35NeYgRHgLpjDaD43DG0bcFWfxyHdrPwZSMycAyXvFXyTfnKHAXdaIGts4_FmW4TZ8XVRCHsmWu8LoCI8PbJDNdNl04uM8s2Zyh6_bJqbcJAzRMC7uGq7VIYzlPF25aT97XMuJFWi8FKUy8GBYynGYE_gPta6fNDDzYWDAii8Yfr91Ju3gOBMYO_xnuVH6_8vgBMcd8l40cxBDyj540feI0V--WLcCk10u1tcTknLljuNEBEujHg6hZKp9ym7OikEmJRml33qY-q5fbW80CsO0wuKR9ScxqR4JfPgIoPJkOgSpeVFVwoiiX3cMjHWBSj7eSVJVVuRyWHc8-2f4HOb4big993TmVKlcAAeYv1HPgWP1C80tRc_CfhkmeMa230LupP7R5tRw2l5jHhJNkIYxeB8C1BQj6xwDw21GXcu8HtAO9u2pZlBIwfLGmFiSjsYf0WwUn4G9iswKc9gmRkczjiXq2psu1wotgucCQ_CbVWA8At78sehpjE-S8rzxvqG71Wb1yRY_IQAMaJXeGrhTN8Sfynlro4YKGdVznq0pRTEAButToZmQmXTLeI0J7-nyFLwzJlnCdDQCbX3ucFpKS7O71mbXoN2TXvlMmQWQrPmwMfNRASY8fWZf88Al5xRzODYn_68pU1eSL7fKkc6XahFGEfEx3-daOQUQbrx4V-JX6tqQDQp8tawHjFk67h-NIs9gNMTs6wEc6eOGmVzEEFg8jTauoJQjbI-sgHcVToDRG3xc3EakCtBKw0wxf6tzVWUjM2IbbrohoiymblizRIRzHX2WmEFlhjadSdO9N-rqodFAdGOi5UcTvmntDJk0JiJtBRQGoWIvq6sBZwdSEkMTWvPD4iXFjkKNcXFGw_6A8nAiI9CXp6j5upxrA-BxaXPBZeB6CPiLQElSv_TI1VsWdwmZut_5CxNjHvtfAF5SQ79LOsRilszSHhtLndJluvxkXSMww3hMThAxwbhjImYYKQQUUIJRy2fxtY3TsUH4xNCxp0JbJ3wWmB7fBh83jFjhrMDBuWCHXK7CuMSEPzAuVzBlOIX_eFkI1v08mfth_soBxDYy_-cn_rP6Ox2-pR6jwg.eyJlbmRwb2ludF9zbHVnIjoibWV0YS9tdXNlLXNwYXJrLTEuMy0yMDI2MDkwMnxtZXRhIn0\"},{\"type\":\"message\",\"id\":\"msg_tmp_qs9pl1gaflr\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"I'll check the weather in Paris for you.\"}],\"phase\":\"commentary\",\"status\":\"completed\"},{\"type\":\"function_call\",\"id\":\"fc_tmp_zvz6k6236km\",\"call_id\":\"call_01a0f0a4c1fe755d9f280fb40b317fc4\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},{\"type\":\"function_call_output\",\"call_id\":\"call_01a0f0a4c1fe755d9f280fb40b317fc4\",\"output\":\"{\\\"temperature\\\":22,\\\"condition\\\":\\\"sunny\\\"}\"}],\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false},\"strict\":false}],\"store\":false,\"include\":[\"reasoning.encrypted_content\"],\"reasoning\":{\"effort\":\"minimal\"},\"max_output_tokens\":512,\"temperature\":0,\"stream\":true}" }, "response": { "status": 200, "headers": { "content-type": "text/event-stream" }, - "body": "data: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790739172-Jcq9g3seZEEPkA5mRcYI\",\"object\":\"response\",\"created_at\":1790739172,\"model\":\"meta/muse-spark-1.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":512,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"minimal\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":0}\n\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"gen-1790739172-Jcq9g3seZEEPkA5mRcYI\",\"object\":\"response\",\"created_at\":1790739172,\"model\":\"meta/muse-spark-1.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":512,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"minimal\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":1}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":0,\"item\":{\"id\":\"rs_6abc82e434627da5fb7f4674:rs_01a0f05f4e0a77f5b8bea8e331c0f087\",\"type\":\"reasoning\",\"status\":\"in_progress\",\"summary\":[]},\"sequence_number\":2}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"rs_6abc82e434627da5fb7f4674:rs_01a0f05f4e0a77f5b8bea8e331c0f087\",\"type\":\"reasoning\",\"status\":\"completed\",\"summary\":[],\"encrypted_content\":\"Q-PaDgGjBkQQD6ZJwT16QXOxTpHpyfuQbClnoHW4D9YzAalD82IwDEvox1_VfffCcPKnNLtckDqCfNnYMJApolGpPWLwUiGyFEPofKJKdcEUriQw1J-jsoZ8HfzSBPkmBqKhF2LKN1wnvkletuV9rBm4tgtTdoGEKwEwe2RS9OsKqr-o0TMTPfLuy9j7WgGg4fucBzQBu0IjXML1pH81eRBKnTLy-M6CBRATl9q1SNvUa8vAgcwCpP5wsGxkSlC_5DYQIFA0ONJGJSaA_-s8y-UWcXOavpxIuo32qJL8rK4krXpLwARxtTMFNleHhzrdb_UF9mcnyoVjF32_PF6ZzIA9p2YRjKNG-htnmjwI8-Jfk_o5fbUpzTohg-qwyve3Il5IBbHW5ZVgi6Y5avgDJdX61W7R8qnQMOmISH8QMl77gtkshMC2aybikR6SbDWHjwr2BM64C3o2NThjZnD9puUvO4EFTg4lTH4rTtxNZU1kMEHfHuF7F_zVGzkjxrGEMWo3fFIBigrzKDfrd4NE5hvzW8bpxOpjuHWeu5CwW1pJkdWMXGHM1kI352-Td8KYOMDXeu7_tlvl9uksbI7gMMr-5u9EGSFnjDjV3qmFQDWqFqDSvI4MGAlY-mj3qw1zGMyBGQeGZv9Ek3SpUJ11VS0BHGidpRRmQqLknwoxbcM_Mgdvu_XQX0uQjcJEYC6QhrZEZbmGzDWAEBTyJ8GCVEJOz8xhFs-pGiH4vJYoIvuZDLFlKjJhWkcTlUMRVWD9UJBbdB9D1lYR8S80rqSAMGECiK-L_HDTxGX0tdPjNS6x6kyA2V5DhlqNASA8PByHYACSEdpwAe4d57QuWUQ-6ZoAnmUbsbTPUcrOAJ5InGUx8SryMtP_5moBacjkqp7svnQvJ1W005gcuw4SW_ycfetmzup0Sp76Mlyvu6U7aut5p-XdlGB-eJeeDWHfEGauN46BAHSkMzu9zWZR8gxHpfsJu9lAPbrdKbz7B9XJ5Up3mfmO6Cyzo1SRags12CIrpiN5D6FhwWsdzr99FQZ7Qf91aRa0UdPaWpaRWAWLeKTYqw_0Nth19xvAKsjnnN2zeIoYccE-RAJH9b56ilrqWSpjVSxaM17WWJJnz2UvWxHF06Z9r1OE7J5LWaUrxtw0NqMNmfKLL4tU6vJYMFF3qUIzGNXPt6r5E2GrSg4o5kNMg3lroGpHRY3Mcd3YaIUK7iP63Z-qXDeNQ4pfHtdOI680wOxcsu1WpV4smRc0kPPf4AEF5hf5gGnW5jlakGRmaeHqOnwM71Pv0V6l2xq68NLhpQg4D9kmRS6-8av5ge2Orc9rrFvYFXsxRITJuXatj4OwL43x8fgtlQi9a-uvO9jpaAeyGaOlfZgSBnRvpOWz5vK3UiZAcyo3DBZzmES4K-MkADf-N8vldysp2A.eyJlbmRwb2ludF9zbHVnIjoibWV0YS9tdXNlLXNwYXJrLTEuMy0yMDI2MDkwMnxtZXRhIn0\",\"format\":\"meta-responses-v1\"},\"sequence_number\":3}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":1,\"item\":{\"id\":\"msg_tmp_aloae1twss4\",\"type\":\"message\",\"status\":\"in_progress\",\"role\":\"assistant\",\"content\":[]},\"sequence_number\":4}\n\ndata: {\"type\":\"response.content_part.added\",\"output_index\":1,\"item_id\":\"msg_tmp_aloae1twss4\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":5}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":1,\"item_id\":\"msg_tmp_aloae1twss4\",\"content_index\":0,\"delta\":\"Paris\",\"logprobs\":[],\"sequence_number\":6}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":1,\"item_id\":\"msg_tmp_aloae1twss4\",\"content_index\":0,\"delta\":\" is sunny.\",\"logprobs\":[],\"sequence_number\":7}\n\ndata: {\"type\":\"response.output_text.done\",\"output_index\":1,\"item_id\":\"msg_tmp_aloae1twss4\",\"content_index\":0,\"text\":\"Paris is sunny.\",\"logprobs\":[],\"sequence_number\":8}\n\ndata: {\"type\":\"response.content_part.done\",\"output_index\":1,\"item_id\":\"msg_tmp_aloae1twss4\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":9}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":1,\"item\":{\"id\":\"msg_tmp_aloae1twss4\",\"type\":\"message\",\"status\":\"completed\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]}]},\"sequence_number\":10}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790739172-Jcq9g3seZEEPkA5mRcYI\",\"object\":\"response\",\"created_at\":1790739172,\"model\":\"meta/muse-spark-1.3\",\"status\":\"completed\",\"completed_at\":1790739173,\"output\":[{\"id\":\"rs_6abc82e434627da5fb7f4674:rs_01a0f05f4e0a77f5b8bea8e331c0f087\",\"type\":\"reasoning\",\"status\":\"completed\",\"summary\":[],\"encrypted_content\":\"Q-PaDgGjBkQQD6ZJwT16QXOxTpHpyfuQbClnoHW4D9YzAalD82IwDEvox1_VfffCcPKnNLtckDqCfNnYMJApolGpPWLwUiGyFEPofKJKdcEUriQw1J-jsoZ8HfzSBPkmBqKhF2LKN1wnvkletuV9rBm4tgtTdoGEKwEwe2RS9OsKqr-o0TMTPfLuy9j7WgGg4fucBzQBu0IjXML1pH81eRBKnTLy-M6CBRATl9q1SNvUa8vAgcwCpP5wsGxkSlC_5DYQIFA0ONJGJSaA_-s8y-UWcXOavpxIuo32qJL8rK4krXpLwARxtTMFNleHhzrdb_UF9mcnyoVjF32_PF6ZzIA9p2YRjKNG-htnmjwI8-Jfk_o5fbUpzTohg-qwyve3Il5IBbHW5ZVgi6Y5avgDJdX61W7R8qnQMOmISH8QMl77gtkshMC2aybikR6SbDWHjwr2BM64C3o2NThjZnD9puUvO4EFTg4lTH4rTtxNZU1kMEHfHuF7F_zVGzkjxrGEMWo3fFIBigrzKDfrd4NE5hvzW8bpxOpjuHWeu5CwW1pJkdWMXGHM1kI352-Td8KYOMDXeu7_tlvl9uksbI7gMMr-5u9EGSFnjDjV3qmFQDWqFqDSvI4MGAlY-mj3qw1zGMyBGQeGZv9Ek3SpUJ11VS0BHGidpRRmQqLknwoxbcM_Mgdvu_XQX0uQjcJEYC6QhrZEZbmGzDWAEBTyJ8GCVEJOz8xhFs-pGiH4vJYoIvuZDLFlKjJhWkcTlUMRVWD9UJBbdB9D1lYR8S80rqSAMGECiK-L_HDTxGX0tdPjNS6x6kyA2V5DhlqNASA8PByHYACSEdpwAe4d57QuWUQ-6ZoAnmUbsbTPUcrOAJ5InGUx8SryMtP_5moBacjkqp7svnQvJ1W005gcuw4SW_ycfetmzup0Sp76Mlyvu6U7aut5p-XdlGB-eJeeDWHfEGauN46BAHSkMzu9zWZR8gxHpfsJu9lAPbrdKbz7B9XJ5Up3mfmO6Cyzo1SRags12CIrpiN5D6FhwWsdzr99FQZ7Qf91aRa0UdPaWpaRWAWLeKTYqw_0Nth19xvAKsjnnN2zeIoYccE-RAJH9b56ilrqWSpjVSxaM17WWJJnz2UvWxHF06Z9r1OE7J5LWaUrxtw0NqMNmfKLL4tU6vJYMFF3qUIzGNXPt6r5E2GrSg4o5kNMg3lroGpHRY3Mcd3YaIUK7iP63Z-qXDeNQ4pfHtdOI680wOxcsu1WpV4smRc0kPPf4AEF5hf5gGnW5jlakGRmaeHqOnwM71Pv0V6l2xq68NLhpQg4D9kmRS6-8av5ge2Orc9rrFvYFXsxRITJuXatj4OwL43x8fgtlQi9a-uvO9jpaAeyGaOlfZgSBnRvpOWz5vK3UiZAcyo3DBZzmES4K-MkADf-N8vldysp2A.eyJlbmRwb2ludF9zbHVnIjoibWV0YS9tdXNlLXNwYXJrLTEuMy0yMDI2MDkwMnxtZXRhIn0\",\"format\":\"meta-responses-v1\"},{\"id\":\"msg_tmp_aloae1twss4\",\"type\":\"message\",\"role\":\"assistant\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]}]}],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":512,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"minimal\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":{\"input_tokens\":700,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":22,\"output_tokens_details\":{\"reasoning_tokens\":8},\"total_tokens\":722,\"cost\":0.0009685,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.0009685,\"upstream_inference_input_cost\":0.000875,\"upstream_inference_output_cost\":0.0000935}}},\"sequence_number\":11}\n\ndata: [DONE]\n\n" + "body": "data: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790743724-L7dx7E48PJMwLi5b7Itv\",\"object\":\"response\",\"created_at\":1790743724,\"model\":\"meta/muse-spark-1.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":512,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"minimal\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":0}\n\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"gen-1790743724-L7dx7E48PJMwLi5b7Itv\",\"object\":\"response\",\"created_at\":1790743724,\"model\":\"meta/muse-spark-1.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":512,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"minimal\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":null},\"sequence_number\":1}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":0,\"item\":{\"id\":\"rs_6abc94ada24a2d24b1094e83:rs_01a0f0a4c5a8771985213097a0b77e85\",\"type\":\"reasoning\",\"status\":\"in_progress\",\"summary\":[]},\"sequence_number\":2}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"rs_6abc94ada24a2d24b1094e83:rs_01a0f0a4c5a8771985213097a0b77e85\",\"type\":\"reasoning\",\"status\":\"completed\",\"summary\":[],\"encrypted_content\":\"Q-PaDgHdo7VHKqTApb35TVIHY0chttGUraTfO9GF3-mLdEqjcXD7675lq_Rtp0MeLVCnSAGK2rTzyCO3cJC_DYXtaEs6-zTPxo0ceySh1oZhXLgPcMDEtK5K3e1hBOXymfWu0uOUEMsLQq6wL3qelA_lIdMJpDiTmTgZe593C3tTge1KokSJF6mTzkSnW2VQb9xGDfXhzTB4MUtUhkL5wSovcnh5Fjmvb64GVu3rPWJhPHGUl_0jpcl0gv7TIYQu9BNzlpbAZ4wXniHI-E2prgCS4KdkZGuRBVXAZpggemZoUVGbzItYG2_XC-Zu8a6_B1M4GBe0jLZ8BO2DjCZYC2VJ66ZMLhx9oiwM2upiJ0x04FS0Ts3AAqSib_CP26ZgWz7c5T0YP-ScB_e6cVtffCq6NT5A87EdzR27hmWbwOja6DLW0TSjt3kaAIRKhoacNt-vMEXrefqNP9Fe1wFS22oTUpMitAr1L1NeDWWAhWZuNM9AMA4iuL6ZwTCL5VMtClyZaQHv5bVCuBe2qGkp2RFnNkRoqqJst4VjRb6ZS55q7SRIfSsVNEgxxvbXJspMY9SW7rBlS891cIOIgcLSVYANGauXAfCpX-SLwAQmcPQh0BfzFLETcs3GipItQtCarjEUgUyhBZC3actSAtR1mfpNEOhL8Axftz1QmqdgDXLJMRZkM56-OxX-jG2zu70EWmdjCBjPURFNhKZ6ZOpVdLZXcef64tYMFCi5x8gNMf5w2qq0afZc-3zPK-JvFZVdEray7dD9k_tUWixTsgz_n1g_rGN8MWkn9JPeTZDV5Hf-Paa8qxqpOYvj7LUPeMkpIJRpw62jLMVf-kjQwngciU1fDcLefyL5X0sbN3TtB-frwM5H_U22rF4HXfekqxYwNW6In860iWnF0rNtxi-YR5FN76ulYqhyhm2ym_1QkeEPncS_Km3eCXs5t2nHGO-6uMXWnKaAhxArT5RQkrRoa-QlGn3YspZXUTGpcZxvMvbaaUOiwNzqDqLujSkhPR32IgttDUQ643MtdFb8gMCpj0MJ87rF4vvE6kiiQy9G56FqEGrSRh3B2hckMTEvQxkDus329tv34AOhLaxc4nfipJp8soN-ic2JlSvg_OOwKlOz2xkKl_Gv5_vI28SJoirJmXRKDhOcUxZ8cjyUj20Ayjh5DCl53Vo7Ak2qGbXVFQUsU7Jzt0A7knhz9dnDH2cK9QynNPDtiaaKOfgWKanDRHv2ddL8I5kJl9vJoiWQGtgT4vn1sAtPQRaXArvCgImRb1fQ5dGp4sBRh2Q0yQS2XYoQzotp5Lv3T4xxRX3LuhwyLiXP0hIjb3mMsKfsbfY5494t_RG3_lIYTNw59tGlX7VStaiPmoF7F7haKI5aTl9TisuIL1w1yF6zX95I4zsy3HI9Av_pdLMEYNnREA.eyJlbmRwb2ludF9zbHVnIjoibWV0YS9tdXNlLXNwYXJrLTEuMy0yMDI2MDkwMnxtZXRhIn0\",\"format\":\"meta-responses-v1\"},\"sequence_number\":3}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":1,\"item\":{\"id\":\"msg_tmp_xon0hygprf8\",\"type\":\"message\",\"status\":\"in_progress\",\"role\":\"assistant\",\"content\":[]},\"sequence_number\":4}\n\ndata: {\"type\":\"response.content_part.added\",\"output_index\":1,\"item_id\":\"msg_tmp_xon0hygprf8\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":5}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":1,\"item_id\":\"msg_tmp_xon0hygprf8\",\"content_index\":0,\"delta\":\"Paris\",\"logprobs\":[],\"sequence_number\":6}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":1,\"item_id\":\"msg_tmp_xon0hygprf8\",\"content_index\":0,\"delta\":\" is sunny.\",\"logprobs\":[],\"sequence_number\":7}\n\ndata: {\"type\":\"response.output_text.done\",\"output_index\":1,\"item_id\":\"msg_tmp_xon0hygprf8\",\"content_index\":0,\"text\":\"Paris is sunny.\",\"logprobs\":[],\"sequence_number\":8}\n\ndata: {\"type\":\"response.content_part.done\",\"output_index\":1,\"item_id\":\"msg_tmp_xon0hygprf8\",\"content_index\":0,\"part\":{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]},\"sequence_number\":9}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":1,\"item\":{\"id\":\"msg_tmp_xon0hygprf8\",\"type\":\"message\",\"status\":\"completed\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]}]},\"sequence_number\":10}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790743724-L7dx7E48PJMwLi5b7Itv\",\"object\":\"response\",\"created_at\":1790743724,\"model\":\"meta/muse-spark-1.3\",\"status\":\"completed\",\"completed_at\":1790743725,\"output\":[{\"id\":\"rs_6abc94ada24a2d24b1094e83:rs_01a0f0a4c5a8771985213097a0b77e85\",\"type\":\"reasoning\",\"status\":\"completed\",\"summary\":[],\"encrypted_content\":\"Q-PaDgHdo7VHKqTApb35TVIHY0chttGUraTfO9GF3-mLdEqjcXD7675lq_Rtp0MeLVCnSAGK2rTzyCO3cJC_DYXtaEs6-zTPxo0ceySh1oZhXLgPcMDEtK5K3e1hBOXymfWu0uOUEMsLQq6wL3qelA_lIdMJpDiTmTgZe593C3tTge1KokSJF6mTzkSnW2VQb9xGDfXhzTB4MUtUhkL5wSovcnh5Fjmvb64GVu3rPWJhPHGUl_0jpcl0gv7TIYQu9BNzlpbAZ4wXniHI-E2prgCS4KdkZGuRBVXAZpggemZoUVGbzItYG2_XC-Zu8a6_B1M4GBe0jLZ8BO2DjCZYC2VJ66ZMLhx9oiwM2upiJ0x04FS0Ts3AAqSib_CP26ZgWz7c5T0YP-ScB_e6cVtffCq6NT5A87EdzR27hmWbwOja6DLW0TSjt3kaAIRKhoacNt-vMEXrefqNP9Fe1wFS22oTUpMitAr1L1NeDWWAhWZuNM9AMA4iuL6ZwTCL5VMtClyZaQHv5bVCuBe2qGkp2RFnNkRoqqJst4VjRb6ZS55q7SRIfSsVNEgxxvbXJspMY9SW7rBlS891cIOIgcLSVYANGauXAfCpX-SLwAQmcPQh0BfzFLETcs3GipItQtCarjEUgUyhBZC3actSAtR1mfpNEOhL8Axftz1QmqdgDXLJMRZkM56-OxX-jG2zu70EWmdjCBjPURFNhKZ6ZOpVdLZXcef64tYMFCi5x8gNMf5w2qq0afZc-3zPK-JvFZVdEray7dD9k_tUWixTsgz_n1g_rGN8MWkn9JPeTZDV5Hf-Paa8qxqpOYvj7LUPeMkpIJRpw62jLMVf-kjQwngciU1fDcLefyL5X0sbN3TtB-frwM5H_U22rF4HXfekqxYwNW6In860iWnF0rNtxi-YR5FN76ulYqhyhm2ym_1QkeEPncS_Km3eCXs5t2nHGO-6uMXWnKaAhxArT5RQkrRoa-QlGn3YspZXUTGpcZxvMvbaaUOiwNzqDqLujSkhPR32IgttDUQ643MtdFb8gMCpj0MJ87rF4vvE6kiiQy9G56FqEGrSRh3B2hckMTEvQxkDus329tv34AOhLaxc4nfipJp8soN-ic2JlSvg_OOwKlOz2xkKl_Gv5_vI28SJoirJmXRKDhOcUxZ8cjyUj20Ayjh5DCl53Vo7Ak2qGbXVFQUsU7Jzt0A7knhz9dnDH2cK9QynNPDtiaaKOfgWKanDRHv2ddL8I5kJl9vJoiWQGtgT4vn1sAtPQRaXArvCgImRb1fQ5dGp4sBRh2Q0yQS2XYoQzotp5Lv3T4xxRX3LuhwyLiXP0hIjb3mMsKfsbfY5494t_RG3_lIYTNw59tGlX7VStaiPmoF7F7haKI5aTl9TisuIL1w1yF6zX95I4zsy3HI9Av_pdLMEYNnREA.eyJlbmRwb2ludF9zbHVnIjoibWV0YS9tdXNlLXNwYXJrLTEuMy0yMDI2MDkwMnxtZXRhIn0\",\"format\":\"meta-responses-v1\"},{\"id\":\"msg_tmp_xon0hygprf8\",\"type\":\"message\",\"role\":\"assistant\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"text\":\"Paris is sunny.\",\"annotations\":[],\"logprobs\":[]}]}],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"function\",\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"strict\":false,\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":512,\"temperature\":0,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":null,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\",\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"minimal\"},\"safety_identifier\":null,\"prompt_cache_key\":null,\"prompt_cache_options\":null,\"usage\":{\"input_tokens\":704,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":22,\"output_tokens_details\":{\"reasoning_tokens\":8},\"total_tokens\":726,\"cost\":0.0009735,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.0009735,\"upstream_inference_input_cost\":0.00088,\"upstream_inference_output_cost\":0.0000935}}},\"sequence_number\":11}\n\ndata: [DONE]\n\n" } } ] diff --git a/packages/ai/test/provider/openrouter-native.recorded.test.ts b/packages/ai/test/provider/openrouter-native.recorded.test.ts index f9e405fd640..21ef1ad4b03 100644 --- a/packages/ai/test/provider/openrouter-native.recorded.test.ts +++ b/packages/ai/test/provider/openrouter-native.recorded.test.ts @@ -8,7 +8,7 @@ import { expectWeatherToolLoop, goldenWeatherToolLoopRequest, runWeatherToolLoop const recorded = recordedTests({ prefix: "openrouter-responses", provider: "openrouter", - protocol: "openrouter-meta-responses", + protocol: "openrouter-responses", requires: ["OPENROUTER_API_KEY"], }) diff --git a/packages/ai/test/provider/openrouter.test.ts b/packages/ai/test/provider/openrouter.test.ts index 096c2d452c9..38fd3065592 100644 --- a/packages/ai/test/provider/openrouter.test.ts +++ b/packages/ai/test/provider/openrouter.test.ts @@ -9,31 +9,51 @@ import { fixedResponse } from "../lib/http.js" import { sseEvents } from "../lib/sse.js" describe("OpenRouter", () => { - it.effect("routes OpenAI, xAI, and Meta models through their native Responses protocols", () => - Effect.forEach( - [ - ["openai/gpt-4o-mini", "openrouter-responses"], - ["x-ai/grok-4.3", "openrouter-xai-responses"], - ["meta/muse-spark-1.3", "openrouter-meta-responses"], - ] as const, - ([id, route]) => - Effect.gen(function* () { - const model = OpenRouter.configure({ apiKey: "test-key" }).model(id) - const prepared = yield* compileRequest(LLM.request({ model, prompt: "Say hello." })) + it.effect("routes OpenAI, xAI, and Meta models through the same generic Responses protocol", () => + Effect.forEach(["openai/gpt-4o-mini", "x-ai/grok-4.3", "meta/muse-spark-1.3", "~x-ai/grok-latest"], (id) => + Effect.gen(function* () { + const model = OpenRouter.configure({ + apiKey: "test-key", + providerOptions: { + reasoning: { effort: "low", exclude: true }, + text: { verbosity: "low" }, + provider: { allow_fallbacks: false }, + }, + }).model(id) + const prepared = yield* compileRequest(LLM.request({ model, prompt: "Say hello." })) - expect(model.route.endpoint.baseURL).toBe("https://openrouter.ai/api/v1") - expect(prepared.route).toBe(route) - expect(prepared.body).toMatchObject({ - model: id, - input: [{ role: "user", content: [{ type: "input_text", text: "Say hello." }] }], - stream: true, - store: false, - include: ["reasoning.encrypted_content"], - }) - }), + expect(model.route.endpoint.baseURL).toBe("https://openrouter.ai/api/v1") + expect(prepared.route).toBe("openrouter-responses") + expect(model.route.protocol).toBe(OpenRouter.responses("openai/gpt-4o-mini").route.protocol) + expect(prepared.body).toMatchObject({ + model: id, + input: [{ role: "user", content: [{ type: "input_text", text: "Say hello." }] }], + stream: true, + store: false, + include: ["reasoning.encrypted_content"], + reasoning: { effort: "low", exclude: true }, + text: { verbosity: "low" }, + provider: { allow_fallbacks: false }, + }) + }), ), ) + it.effect("exposes exactly three API routes and leaves other families on Chat", () => + Effect.gen(function* () { + expect(OpenRouter.routes.map((route) => route.endpoint.path)).toEqual([ + "/chat/completions", + "/responses", + "/messages", + ]) + const openrouter = OpenRouter.configure({ apiKey: "test-key" }) + const chat = openrouter.model("meta-llama/llama-3.3-70b-instruct") + expect(chat.route.id).toBe("openrouter") + expect(openrouter.model("qwen/qwen3-coder-plus").route.protocol).toBe(chat.route.protocol) + expect(openrouter.messages("anthropic/claude-sonnet-4.6").route.id).toBe("openrouter-messages") + }), + ) + it.effect("places default cache breakpoints on tools, system boundaries, and the conversation tail", () => Effect.gen(function* () { const prepared = yield* compileRequest(