mirror of
https://github.com/anomalyco/opencode.git
synced 2026-10-05 06:56:16 +00:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
31387e1c7a | ||
|
|
dda31fb95c | ||
|
|
65d92ba909 | ||
|
|
d851666401 |
No files matched your search
+11
-1
@@ -1203,12 +1203,22 @@ LLM.request({
|
||||
| ----------------------- | ------------------------------------------------------------------------- |
|
||||
| Anthropic Messages | emits up to 4 `cache_control` markers (4-breakpoint cap enforced) |
|
||||
| Bedrock Converse | emits up to 4 `cachePoint` blocks (4-breakpoint cap enforced) |
|
||||
| OpenRouter | emits up to 4 `cache_control` markers |
|
||||
| OpenRouter | Anthropic/Qwen emit explicit markers; other families use upstream caching |
|
||||
| OpenAI Chat / Responses | no-op (implicit caching above 1024 tokens) |
|
||||
| Gemini | no-op (implicit caching on 2.5+; explicit `CachedContent` is out-of-band) |
|
||||
|
||||
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. All three Responses families share the existing OpenAI-shaped
|
||||
Responses implementation, including namespace tools and hosted-tool events; 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
|
||||
choices can be rejected by the provider.
|
||||
|
||||
## Providers
|
||||
|
||||
Provider facades configure endpoint/auth/deployment details first, then expose model selectors that take only a model or deployment id. The selected model carries the executable route value used at runtime.
|
||||
|
||||
@@ -49,6 +49,7 @@ const RESPECTS_INLINE_HINTS = new Set([
|
||||
"zai-coding-messages",
|
||||
"bedrock-converse",
|
||||
"openrouter",
|
||||
"openrouter-messages",
|
||||
])
|
||||
|
||||
// OpenRouter upstreams other than Anthropic and Alibaba Qwen cache without breakpoints. Gemini uses only the last
|
||||
@@ -168,7 +169,8 @@ const countHints = (request: LLMRequest) =>
|
||||
export const applyCachePolicy = (request: LLMRequest): LLMRequest => {
|
||||
if (!RESPECTS_INLINE_HINTS.has(request.model.route.id)) return request
|
||||
const policy =
|
||||
request.model.route.id === "openrouter" && (request.cache === undefined || request.cache === "auto")
|
||||
(request.model.route.id === "openrouter" || request.model.route.id === "openrouter-messages") &&
|
||||
(request.cache === undefined || request.cache === "auto")
|
||||
? openRouterPolicy(request.model.id)
|
||||
: resolve(request.cache)
|
||||
if (!policy.tools && !policy.system && !policy.messages) return request
|
||||
|
||||
@@ -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 }),
|
||||
@@ -298,18 +298,22 @@ const OpenResponsesBody = Schema.Struct({
|
||||
})
|
||||
export type OpenResponsesBody = Schema.Schema.Type<typeof OpenResponsesBody>
|
||||
|
||||
export const OpenResponsesUsage = Schema.Struct({
|
||||
input_tokens: Schema.optional(Schema.Number),
|
||||
input_tokens_details: optionalNull(
|
||||
Schema.Struct({
|
||||
cached_tokens: Schema.optional(Schema.Number),
|
||||
cache_write_tokens: Schema.optional(Schema.Number),
|
||||
}),
|
||||
),
|
||||
output_tokens: Schema.optional(Schema.Number),
|
||||
output_tokens_details: optionalNull(Schema.Struct({ reasoning_tokens: Schema.optional(Schema.Number) })),
|
||||
total_tokens: Schema.optional(Schema.Number),
|
||||
})
|
||||
// Retain gateway billing extensions in provider metadata without changing normalized token accounting.
|
||||
export const OpenResponsesUsage = Schema.StructWithRest(
|
||||
Schema.Struct({
|
||||
input_tokens: Schema.optional(Schema.Number),
|
||||
input_tokens_details: optionalNull(
|
||||
Schema.Struct({
|
||||
cached_tokens: Schema.optional(Schema.Number),
|
||||
cache_write_tokens: Schema.optional(Schema.Number),
|
||||
}),
|
||||
),
|
||||
output_tokens: Schema.optional(Schema.Number),
|
||||
output_tokens_details: optionalNull(Schema.Struct({ reasoning_tokens: Schema.optional(Schema.Number) })),
|
||||
total_tokens: Schema.optional(Schema.Number),
|
||||
}),
|
||||
[Schema.Record(Schema.String, Schema.Unknown)],
|
||||
)
|
||||
type OpenResponsesUsage = Schema.Schema.Type<typeof OpenResponsesUsage>
|
||||
|
||||
// The spec requires `id` on every output item, but some gateways drop it from
|
||||
|
||||
@@ -124,7 +124,7 @@ const OpenAIResponsesCoreFields = {
|
||||
),
|
||||
}
|
||||
|
||||
const OpenAIResponsesBody = Schema.Struct({
|
||||
export const OpenAIResponsesBody = Schema.Struct({
|
||||
...OpenAIResponsesCoreFields,
|
||||
stream: Schema.Literal(true),
|
||||
})
|
||||
@@ -143,14 +143,19 @@ const adapter = {
|
||||
restoreHostedToolItem: (item: unknown) => (Schema.is(OpenAIResponsesHostedToolItem)(item) ? item : undefined),
|
||||
} satisfies OpenResponses.ProviderAdapter
|
||||
|
||||
// GPT-6 Astra, Sol, and Luna accept `configuration_update` only in standard mode (not `reasoning.mode: "pro"` or
|
||||
// `-pro` slugs), and never alongside automatic `context_management` compaction.
|
||||
// GPT-6 Astra, Sol, Luna, and GPT-6.1 Sol accept `configuration_update` only in standard mode
|
||||
// (not `reasoning.mode: "pro"` or `-pro` slugs), and never alongside automatic `context_management` compaction.
|
||||
const supportsEffortUpdates = (request: LLMRequest) => {
|
||||
if (request.providerOptions?.contextManagement !== undefined) return false
|
||||
if (Schema.is(Schema.Struct({ mode: Schema.Literal("pro") }))(request.http?.body?.reasoning)) return false
|
||||
if (
|
||||
[request.providerOptions?.reasoning, request.http?.body?.reasoning].some(
|
||||
Schema.is(Schema.Struct({ mode: Schema.Literal("pro") })),
|
||||
)
|
||||
)
|
||||
return false
|
||||
const override = request.model.compatibility?.supportsEffortUpdates
|
||||
if (override !== undefined) return override
|
||||
return /(?:^|\/)gpt-6-(?:astra|sol|luna)$/i.test(request.model.id)
|
||||
return /(?:^|\/)(?:gpt-6-(?:astra|sol|luna)|gpt-6\.1-sol)$/i.test(request.model.id)
|
||||
}
|
||||
|
||||
const nativeImageToolInput = (tool: ToolDefinition) => {
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
export * as OpenRouterWire from "./openrouter.js"
|
||||
|
||||
import { Effect, Option, Schema } from "effect"
|
||||
import { LLMRequest, Message, type ContentPart, type ReasoningPart } from "../../schema/index.js"
|
||||
import { OpenAIResponses } from "../openai-responses.js"
|
||||
import { AnthropicMessages } from "../anthropic-messages.js"
|
||||
import { isRecord, ProviderShared } from "../shared.js"
|
||||
|
||||
const ReplayDetail = Schema.Struct({
|
||||
type: Schema.String,
|
||||
text: Schema.optional(Schema.String),
|
||||
signature: Schema.optional(Schema.NullOr(Schema.String)),
|
||||
data: Schema.optional(Schema.String),
|
||||
encrypted: Schema.optional(Schema.String),
|
||||
})
|
||||
const decodeReplayDetail = Schema.decodeUnknownOption(ReplayDetail)
|
||||
|
||||
export const responses = Effect.fn("OpenRouter.responses")(function* (request: LLMRequest) {
|
||||
const { usage: _, ...options } = bodyOptions(request.providerOptions, request.generation?.maxTokens)
|
||||
const body = yield* OpenAIResponses.protocol.body.from(
|
||||
LLMRequest.update(request, {
|
||||
providerOptions: {
|
||||
...request.providerOptions,
|
||||
reasoningEffort: request.providerOptions?.reasoningEffort ?? options.reasoning?.effort,
|
||||
},
|
||||
messages: replayMessages(request, "responses"),
|
||||
}),
|
||||
)
|
||||
return {
|
||||
...options,
|
||||
...body,
|
||||
store: false as const,
|
||||
// The shared lowerer owns the chronological effort baseline, including the model default.
|
||||
...(options.reasoning || body.reasoning
|
||||
? {
|
||||
reasoning: {
|
||||
...options.reasoning,
|
||||
...body.reasoning,
|
||||
effort: body.reasoning?.effort,
|
||||
summary: body.reasoning?.summary ?? options.reasoning?.summary,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
...(options.text || body.text ? { text: { ...options.text, ...body.text } } : {}),
|
||||
}
|
||||
})
|
||||
|
||||
export const messages = Effect.fn("OpenRouter.messages")(function* (request: LLMRequest) {
|
||||
const { reasoning, usage: _, ...options } = bodyOptions(request.providerOptions, request.generation?.maxTokens)
|
||||
const disabled = reasoning?.enabled === false || reasoning?.effort === "none"
|
||||
const body = yield* AnthropicMessages.protocol.body.from(
|
||||
LLMRequest.update(request, {
|
||||
providerOptions: {
|
||||
...request.providerOptions,
|
||||
effort:
|
||||
request.providerOptions?.effort ??
|
||||
(!disabled && typeof reasoning?.effort === "string" ? reasoning.effort : undefined),
|
||||
thinking:
|
||||
request.providerOptions?.thinking ??
|
||||
(() => {
|
||||
if (disabled) return { type: "disabled" }
|
||||
if (typeof reasoning?.max_tokens === "number")
|
||||
return { type: "enabled", budget_tokens: reasoning.max_tokens }
|
||||
if (reasoning?.enabled === true || typeof reasoning?.effort === "string")
|
||||
return { type: "adaptive", ...(reasoning.exclude === true ? { display: "omitted" } : {}) }
|
||||
})(),
|
||||
},
|
||||
messages: replayMessages(request, "messages"),
|
||||
}),
|
||||
)
|
||||
return { ...options, ...body }
|
||||
})
|
||||
|
||||
function replayMessages(request: LLMRequest, format: "responses" | "messages") {
|
||||
return request.messages.map((message) =>
|
||||
message.role !== "assistant"
|
||||
? message
|
||||
: Message.make({
|
||||
...message,
|
||||
content: message.content.flatMap<ContentPart>((part) =>
|
||||
part.type === "reasoning" ? replayReasoning(part, format) : [part],
|
||||
),
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
// Existing Chat histories store signatures in reasoning_details, not native block/item metadata.
|
||||
function replayReasoning(part: ReasoningPart, format: "responses" | "messages"): ReasoningPart[] {
|
||||
const metadata = part.providerMetadata?.openrouter
|
||||
if (!Array.isArray(metadata?.reasoningDetails)) return [part]
|
||||
const details = metadata.reasoningDetails.flatMap((detail) => Option.toArray(decodeReplayDetail(detail)))
|
||||
const withMetadata = (extra: Record<string, unknown>, text = part.text): ReasoningPart => ({
|
||||
...part,
|
||||
text,
|
||||
providerMetadata: { ...part.providerMetadata, openrouter: { ...metadata, ...extra } },
|
||||
})
|
||||
if (format === "responses") {
|
||||
const encrypted = details.find((detail) => detail.type === "reasoning.encrypted" || detail.type === "encrypted")
|
||||
return [
|
||||
withMetadata({
|
||||
reasoningEncryptedContent: metadata.reasoningEncryptedContent ?? encrypted?.data ?? encrypted?.encrypted,
|
||||
}),
|
||||
]
|
||||
}
|
||||
const blocks = details.flatMap<ReasoningPart>((detail) => {
|
||||
if (detail.type === "reasoning.text" && detail.signature)
|
||||
return [withMetadata({ signature: detail.signature }, detail.text ?? part.text)]
|
||||
if (detail.type === "reasoning.encrypted" && detail.data) return [withMetadata({ redactedData: detail.data }, "")]
|
||||
return []
|
||||
})
|
||||
return blocks.length ? blocks : [part]
|
||||
}
|
||||
|
||||
export const bodyOptions = (input: LLMRequest["providerOptions"], maxTokens: number | undefined) => {
|
||||
const {
|
||||
usage,
|
||||
models,
|
||||
provider,
|
||||
plugins,
|
||||
web_search_options,
|
||||
debug,
|
||||
user,
|
||||
reasoning,
|
||||
text,
|
||||
promptCacheKey,
|
||||
...options
|
||||
} = input ?? {}
|
||||
return {
|
||||
...options,
|
||||
...(usage === undefined || usage === true
|
||||
? { usage: { include: true } }
|
||||
: usage === false
|
||||
? { usage: { include: false } }
|
||||
: isRecord(usage)
|
||||
? { usage }
|
||||
: {}),
|
||||
...(Array.isArray(models) ? { models } : {}),
|
||||
...(isRecord(provider) ? { provider } : {}),
|
||||
...(Array.isArray(plugins) ? { plugins } : {}),
|
||||
...(isRecord(web_search_options) ? { web_search_options } : {}),
|
||||
...(isRecord(debug) ? { debug } : {}),
|
||||
...(typeof user === "string" ? { user } : {}),
|
||||
...(isRecord(reasoning) ? { reasoning: fitReasoning(reasoning, maxTokens) } : {}),
|
||||
...(isRecord(text) ? { text } : {}),
|
||||
}
|
||||
}
|
||||
|
||||
// Anthropic and Alibaba require the thinking budget to remain below the output limit.
|
||||
function fitReasoning(reasoning: Record<string, unknown>, maxTokens: number | undefined) {
|
||||
return typeof reasoning.max_tokens === "number"
|
||||
? { ...reasoning, max_tokens: ProviderShared.fitThinkingBudget(reasoning.max_tokens, maxTokens, 1_024) }
|
||||
: reasoning
|
||||
}
|
||||
@@ -7,8 +7,12 @@ 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 { AnthropicMessages } from "../protocols/anthropic-messages.js"
|
||||
import { Framing } from "../route/framing.js"
|
||||
import { JsonObject } from "../protocols/shared.js"
|
||||
import { newBreakpoints, ttlBucket } from "../protocols/utils/cache.js"
|
||||
import { isRecord, ProviderShared } from "../protocols/shared.js"
|
||||
import { OpenRouterWire } from "../protocols/utils/openrouter.js"
|
||||
|
||||
export const id = ProviderID.make("openrouter")
|
||||
const baseURL = "https://openrouter.ai/api/v1"
|
||||
@@ -54,6 +58,7 @@ export interface OpenRouterOptions {
|
||||
readonly plugins?: ReadonlyArray<OpenRouterPlugin>
|
||||
readonly provider?: OpenRouterProviderRouting
|
||||
readonly reasoning?: Readonly<{
|
||||
[key: string]: unknown
|
||||
enabled?: boolean
|
||||
exclude?: boolean
|
||||
effort?: OpenString<"none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max">
|
||||
@@ -95,6 +100,18 @@ const OpenRouterBody = Schema.StructWithRest(Schema.Struct(OpenAIChat.bodyFields
|
||||
])
|
||||
export type OpenRouterBody = Schema.Schema.Type<typeof OpenRouterBody>
|
||||
|
||||
const OpenRouterResponsesBody = Schema.StructWithRest(
|
||||
Schema.Struct({
|
||||
...OpenAIResponses.OpenAIResponsesBody.fields,
|
||||
store: Schema.Literal(false),
|
||||
reasoning: Schema.optional(JsonObject),
|
||||
text: Schema.optional(JsonObject),
|
||||
}),
|
||||
[JsonObject],
|
||||
)
|
||||
const OpenRouterMessagesBody = Schema.StructWithRest(AnthropicMessages.AnthropicMessagesBody, [JsonObject])
|
||||
type OpenRouterMessagesBody = Schema.Schema.Type<typeof OpenRouterMessagesBody>
|
||||
|
||||
export const protocol = Protocol.make({
|
||||
id: "openrouter-chat",
|
||||
body: {
|
||||
@@ -123,7 +140,7 @@ export const protocol = Protocol.make({
|
||||
return {
|
||||
...body,
|
||||
messages,
|
||||
...bodyOptions(request.providerOptions, request.generation?.maxTokens),
|
||||
...OpenRouterWire.bodyOptions(request.providerOptions, request.generation?.maxTokens),
|
||||
} as OpenRouterBody
|
||||
}),
|
||||
),
|
||||
@@ -131,6 +148,28 @@ export const protocol = Protocol.make({
|
||||
stream: OpenAIChat.protocol.stream,
|
||||
})
|
||||
|
||||
const responsesProtocol = Protocol.make({
|
||||
...OpenAIResponses.protocol,
|
||||
id: "openrouter-responses",
|
||||
// The gateway additionally rejects chronological effort updates with automatic truncation.
|
||||
supportsEffortUpdates: (request) =>
|
||||
request.providerOptions?.truncation !== "auto" &&
|
||||
request.http?.body?.truncation !== "auto" &&
|
||||
(OpenAIResponses.protocol.supportsEffortUpdates?.(request) ?? false),
|
||||
body: {
|
||||
schema: OpenRouterResponsesBody,
|
||||
from: OpenRouterWire.responses,
|
||||
},
|
||||
})
|
||||
const messagesProtocol = Protocol.make({
|
||||
...AnthropicMessages.protocol,
|
||||
id: "openrouter-messages",
|
||||
body: {
|
||||
schema: OpenRouterMessagesBody,
|
||||
from: OpenRouterWire.messages,
|
||||
},
|
||||
})
|
||||
|
||||
const cacheControl = () => {
|
||||
const breakpoints = newBreakpoints(4)
|
||||
return (cache: CacheHint | undefined) => {
|
||||
@@ -143,36 +182,6 @@ const cacheControl = () => {
|
||||
}
|
||||
}
|
||||
|
||||
// OpenRouter forwards `reasoning.max_tokens` as the upstream thinking budget. Upstreams such as Anthropic and Alibaba
|
||||
// reject one that is not below the output limit; 1,024 is Anthropic's minimum budget.
|
||||
const fitReasoning = (reasoning: Record<string, unknown>, maxTokens: number | undefined) =>
|
||||
typeof reasoning.max_tokens === "number"
|
||||
? { ...reasoning, max_tokens: ProviderShared.fitThinkingBudget(reasoning.max_tokens, maxTokens, 1_024) }
|
||||
: reasoning
|
||||
|
||||
const bodyOptions = (input: unknown, maxTokens: number | undefined) => {
|
||||
const openrouter = isRecord(input) ? input : {}
|
||||
const { usage, models, provider, plugins, web_search_options, debug, user, reasoning, promptCacheKey, ...options } =
|
||||
openrouter
|
||||
return {
|
||||
...options,
|
||||
...(usage === undefined || usage === true
|
||||
? { usage: { include: true } }
|
||||
: usage === false
|
||||
? { usage: { include: false } }
|
||||
: isRecord(usage)
|
||||
? { usage }
|
||||
: {}),
|
||||
...(Array.isArray(models) ? { models } : {}),
|
||||
...(isRecord(provider) ? { provider } : {}),
|
||||
...(Array.isArray(plugins) ? { plugins } : {}),
|
||||
...(isRecord(web_search_options) ? { web_search_options } : {}),
|
||||
...(isRecord(debug) ? { debug } : {}),
|
||||
...(typeof user === "string" ? { user } : {}),
|
||||
...(isRecord(reasoning) ? { reasoning: fitReasoning(reasoning, maxTokens) } : {}),
|
||||
}
|
||||
}
|
||||
|
||||
export const route = Route.make({
|
||||
id: ADAPTER,
|
||||
provider: id,
|
||||
@@ -182,19 +191,45 @@ export const route = Route.make({
|
||||
framing: OpenAIChat.framing,
|
||||
})
|
||||
|
||||
export const routes = [route]
|
||||
const responsesRoute = Route.make({
|
||||
id: "openrouter-responses",
|
||||
provider: id,
|
||||
providerMetadataKey: "openrouter",
|
||||
protocol: responsesProtocol,
|
||||
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,
|
||||
providerMetadataKey: "openrouter",
|
||||
protocol: messagesProtocol,
|
||||
endpoint: Endpoint.path("/messages", { baseURL }),
|
||||
transport: AnthropicMessages.transport<OpenRouterMessagesBody>(),
|
||||
})
|
||||
|
||||
const configuredRoute = (input: LanguageModelOptions) => {
|
||||
export const routes = [route, responsesRoute, messagesRoute]
|
||||
|
||||
const routeOptions = (input: LanguageModelOptions) => {
|
||||
const { apiKey: _, auth: _auth, baseURL: endpoint, ...rest } = input
|
||||
return route.with({
|
||||
return {
|
||||
...rest,
|
||||
endpoint: { baseURL: endpoint ?? baseURL },
|
||||
auth: AuthOptions.bearer(input, "OPENROUTER_API_KEY"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const configure = (input: LanguageModelOptions = {}) => {
|
||||
const route = configuredRoute(input)
|
||||
const options = routeOptions(input)
|
||||
const chatRoute = route.with(options)
|
||||
const openResponses = responsesRoute.with(options)
|
||||
const anthropicMessages = messagesRoute.with(options)
|
||||
const chat = (modelID: string | ModelID) =>
|
||||
chatRoute.model<OpenRouterProviderOptionsInput>({ id: modelID, compatibility: { supportsPromptCacheKey: true } })
|
||||
const responses = (modelID: string | ModelID) => openResponses.model<OpenRouterProviderOptionsInput>({ id: modelID })
|
||||
const messages = (modelID: string | ModelID) =>
|
||||
anthropicMessages.model<OpenRouterProviderOptionsInput>({ id: modelID })
|
||||
const evaluation = (modelID: string | ModelID) =>
|
||||
SystemOne.model<OpenRouterEvaluationOptions>({
|
||||
id: modelID,
|
||||
@@ -207,14 +242,24 @@ export const configure = (input: LanguageModelOptions = {}) => {
|
||||
})
|
||||
return {
|
||||
id,
|
||||
model: (modelID: string | ModelID) =>
|
||||
route.model<OpenRouterProviderOptionsInput>({ id: modelID, compatibility: { supportsPromptCacheKey: true } }),
|
||||
model: (modelID: string | ModelID) => {
|
||||
const model = String(modelID).replace(/^~/, "")
|
||||
if (model.startsWith("anthropic/")) return messages(modelID)
|
||||
if (["openai/", "x-ai/", "meta/"].some((prefix) => model.startsWith(prefix))) return responses(modelID)
|
||||
return chat(modelID)
|
||||
},
|
||||
chat,
|
||||
responses,
|
||||
messages,
|
||||
experimental: { evaluation },
|
||||
configure,
|
||||
}
|
||||
}
|
||||
|
||||
export const provider = configure()
|
||||
export const chat = provider.chat
|
||||
export const responses = provider.responses
|
||||
export const messages = provider.messages
|
||||
export const experimental = provider.experimental
|
||||
export const model: ProviderPackage.Definition<Settings, OpenRouterProviderOptionsInput>["model"] = (
|
||||
modelID,
|
||||
@@ -227,3 +272,5 @@ export const model: ProviderPackage.Definition<Settings, OpenRouterProviderOptio
|
||||
http: body === undefined ? undefined : { body: { ...body } },
|
||||
providerOptions,
|
||||
}).model(modelID)
|
||||
|
||||
export * as OpenRouter from "./openrouter.js"
|
||||
@@ -375,6 +375,8 @@ describe("OpenAI Responses effort updates", () => {
|
||||
["openai/gpt-6-sol", true],
|
||||
["gpt-6-luna", true],
|
||||
["openai/gpt-6-luna", true],
|
||||
["gpt-6.1-sol", true],
|
||||
["~openai/gpt-6.1-sol", true],
|
||||
["gpt-6-astra-2026-09-01", false],
|
||||
["gpt-6-sol-pro", false],
|
||||
["gpt-6-luna-pro", false],
|
||||
|
||||
-54
@@ -1,54 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"name": "openai-compatible-chat/openrouter-claude-opus-4-7-drives-a-tool-loop",
|
||||
"recordedAt": "2026-05-06T01:35:14.282Z",
|
||||
"tags": [
|
||||
"prefix:openai-compatible-chat",
|
||||
"protocol:openai-compatible-chat",
|
||||
"provider:openrouter",
|
||||
"tool",
|
||||
"tool-loop",
|
||||
"golden",
|
||||
"flagship"
|
||||
]
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"transport": "http",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https://openrouter.ai/api/v1/chat/completions",
|
||||
"headers": {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
"body": "{\"model\":\"anthropic/claude-opus-4.7\",\"messages\":[{\"role\":\"system\",\"content\":\"Use the get_weather tool exactly once, then answer in one short sentence.\"},{\"role\":\"user\",\"content\":\"What is the weather in Paris?\"}],\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"max_tokens\":80,\"temperature\":0}"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"content-type": "text/event-stream"
|
||||
},
|
||||
"body": ": OPENROUTER PROCESSING\n\n: OPENROUTER PROCESSING\n\n: OPENROUTER PROCESSING\n\ndata: {\"id\":\"gen-1778031311-S3NlfYGRwAnOoPoNrThK\",\"object\":\"chat.completion.chunk\",\"created\":1778031311,\"model\":\"anthropic/claude-4.7-opus-20260416\",\"provider\":\"Amazon Bedrock\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"id\":\"toolu_bdrk_01AVRkzbigpMbNJ3zjnuQ6ZE\",\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"arguments\":\"\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031311-S3NlfYGRwAnOoPoNrThK\",\"object\":\"chat.completion.chunk\",\"created\":1778031311,\"model\":\"anthropic/claude-4.7-opus-20260416\",\"provider\":\"Amazon Bedrock\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031311-S3NlfYGRwAnOoPoNrThK\",\"object\":\"chat.completion.chunk\",\"created\":1778031311,\"model\":\"anthropic/claude-4.7-opus-20260416\",\"provider\":\"Amazon Bedrock\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031311-S3NlfYGRwAnOoPoNrThK\",\"object\":\"chat.completion.chunk\",\"created\":1778031311,\"model\":\"anthropic/claude-4.7-opus-20260416\",\"provider\":\"Amazon Bedrock\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"{\\\"city\\\": \\\"P\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031311-S3NlfYGRwAnOoPoNrThK\",\"object\":\"chat.completion.chunk\",\"created\":1778031311,\"model\":\"anthropic/claude-4.7-opus-20260416\",\"provider\":\"Amazon Bedrock\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"ari\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031311-S3NlfYGRwAnOoPoNrThK\",\"object\":\"chat.completion.chunk\",\"created\":1778031311,\"model\":\"anthropic/claude-4.7-opus-20260416\",\"provider\":\"Amazon Bedrock\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"s\\\"}\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031311-S3NlfYGRwAnOoPoNrThK\",\"object\":\"chat.completion.chunk\",\"created\":1778031311,\"model\":\"anthropic/claude-4.7-opus-20260416\",\"provider\":\"Amazon Bedrock\",\"service_tier\":\"standard\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_use\"}]}\n\ndata: {\"id\":\"gen-1778031311-S3NlfYGRwAnOoPoNrThK\",\"object\":\"chat.completion.chunk\",\"created\":1778031311,\"model\":\"anthropic/claude-4.7-opus-20260416\",\"provider\":\"Amazon Bedrock\",\"service_tier\":\"standard\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_use\"}],\"usage\":{\"prompt_tokens\":802,\"completion_tokens\":66,\"total_tokens\":868,\"cost\":0.00566,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00566,\"upstream_inference_prompt_cost\":0.00401,\"upstream_inference_completions_cost\":0.00165},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}\n\ndata: [DONE]\n\n"
|
||||
}
|
||||
},
|
||||
{
|
||||
"transport": "http",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https://openrouter.ai/api/v1/chat/completions",
|
||||
"headers": {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
"body": "{\"model\":\"anthropic/claude-opus-4.7\",\"messages\":[{\"role\":\"system\",\"content\":\"Use the get_weather tool exactly once, then answer in one short sentence.\"},{\"role\":\"user\",\"content\":\"What is the weather in Paris?\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"toolu_bdrk_01AVRkzbigpMbNJ3zjnuQ6ZE\",\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"toolu_bdrk_01AVRkzbigpMbNJ3zjnuQ6ZE\",\"content\":\"{\\\"temperature\\\":22,\\\"condition\\\":\\\"sunny\\\"}\"}],\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"max_tokens\":80,\"temperature\":0}"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"content-type": "text/event-stream"
|
||||
},
|
||||
"body": ": OPENROUTER PROCESSING\n\ndata: {\"id\":\"gen-1778031313-XM4XZGmFyt6jg3GZ772w\",\"object\":\"chat.completion.chunk\",\"created\":1778031313,\"model\":\"anthropic/claude-4.7-opus-20260416\",\"provider\":\"Amazon Bedrock\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"It\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031313-XM4XZGmFyt6jg3GZ772w\",\"object\":\"chat.completion.chunk\",\"created\":1778031313,\"model\":\"anthropic/claude-4.7-opus-20260416\",\"provider\":\"Amazon Bedrock\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"'s sunny and\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031313-XM4XZGmFyt6jg3GZ772w\",\"object\":\"chat.completion.chunk\",\"created\":1778031313,\"model\":\"anthropic/claude-4.7-opus-20260416\",\"provider\":\"Amazon Bedrock\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" 22°C in\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031313-XM4XZGmFyt6jg3GZ772w\",\"object\":\"chat.completion.chunk\",\"created\":1778031313,\"model\":\"anthropic/claude-4.7-opus-20260416\",\"provider\":\"Amazon Bedrock\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" Paris.\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031313-XM4XZGmFyt6jg3GZ772w\",\"object\":\"chat.completion.chunk\",\"created\":1778031313,\"model\":\"anthropic/claude-4.7-opus-20260416\",\"provider\":\"Amazon Bedrock\",\"service_tier\":\"standard\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"stop\",\"native_finish_reason\":\"end_turn\"}]}\n\ndata: {\"id\":\"gen-1778031313-XM4XZGmFyt6jg3GZ772w\",\"object\":\"chat.completion.chunk\",\"created\":1778031313,\"model\":\"anthropic/claude-4.7-opus-20260416\",\"provider\":\"Amazon Bedrock\",\"service_tier\":\"standard\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"stop\",\"native_finish_reason\":\"end_turn\"}],\"usage\":{\"prompt_tokens\":899,\"completion_tokens\":19,\"total_tokens\":918,\"cost\":0.00497,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00497,\"upstream_inference_prompt_cost\":0.004495,\"upstream_inference_completions_cost\":0.000475},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}\n\ndata: [DONE]\n\n"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"name": "openai-compatible-chat/openrouter-gpt-4o-mini-drives-a-tool-loop",
|
||||
"recordedAt": "2026-05-06T01:35:08.922Z",
|
||||
"tags": [
|
||||
"prefix:openai-compatible-chat",
|
||||
"protocol:openai-compatible-chat",
|
||||
"provider:openrouter",
|
||||
"tool",
|
||||
"tool-loop",
|
||||
"golden"
|
||||
]
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"transport": "http",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https://openrouter.ai/api/v1/chat/completions",
|
||||
"headers": {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
"body": "{\"model\":\"openai/gpt-4o-mini\",\"messages\":[{\"role\":\"system\",\"content\":\"Use the get_weather tool exactly once, then answer in one short sentence.\"},{\"role\":\"user\",\"content\":\"What is the weather in Paris?\"}],\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"max_tokens\":80,\"temperature\":0}"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"content-type": "text/event-stream"
|
||||
},
|
||||
"body": ": OPENROUTER PROCESSING\n\ndata: {\"id\":\"gen-1778031307-FcHCDYW9unDVyRRL841T\",\"object\":\"chat.completion.chunk\",\"created\":1778031307,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"id\":\"call_S63bjYITINemSHZ4Uqns7PIu\",\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"arguments\":\"\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031307-FcHCDYW9unDVyRRL841T\",\"object\":\"chat.completion.chunk\",\"created\":1778031307,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031307-FcHCDYW9unDVyRRL841T\",\"object\":\"chat.completion.chunk\",\"created\":1778031307,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"{\\\"\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031307-FcHCDYW9unDVyRRL841T\",\"object\":\"chat.completion.chunk\",\"created\":1778031307,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031307-FcHCDYW9unDVyRRL841T\",\"object\":\"chat.completion.chunk\",\"created\":1778031307,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"\\\":\\\"\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031307-FcHCDYW9unDVyRRL841T\",\"object\":\"chat.completion.chunk\",\"created\":1778031307,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Paris\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031307-FcHCDYW9unDVyRRL841T\",\"object\":\"chat.completion.chunk\",\"created\":1778031307,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"\\\"}\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031307-FcHCDYW9unDVyRRL841T\",\"object\":\"chat.completion.chunk\",\"created\":1778031307,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\"}]}\n\ndata: {\"id\":\"gen-1778031307-FcHCDYW9unDVyRRL841T\",\"object\":\"chat.completion.chunk\",\"created\":1778031307,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_calls\"}],\"usage\":{\"prompt_tokens\":66,\"completion_tokens\":14,\"total_tokens\":80,\"cost\":0.0000183,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.0000183,\"upstream_inference_prompt_cost\":0.0000099,\"upstream_inference_completions_cost\":0.0000084},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}\n\ndata: [DONE]\n\n"
|
||||
}
|
||||
},
|
||||
{
|
||||
"transport": "http",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https://openrouter.ai/api/v1/chat/completions",
|
||||
"headers": {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
"body": "{\"model\":\"openai/gpt-4o-mini\",\"messages\":[{\"role\":\"system\",\"content\":\"Use the get_weather tool exactly once, then answer in one short sentence.\"},{\"role\":\"user\",\"content\":\"What is the weather in Paris?\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"call_S63bjYITINemSHZ4Uqns7PIu\",\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"call_S63bjYITINemSHZ4Uqns7PIu\",\"content\":\"{\\\"temperature\\\":22,\\\"condition\\\":\\\"sunny\\\"}\"}],\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"max_tokens\":80,\"temperature\":0}"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"content-type": "text/event-stream"
|
||||
},
|
||||
"body": ": OPENROUTER PROCESSING\n\ndata: {\"id\":\"gen-1778031308-uNHYY6MdDXOs0BYMXXVb\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"The\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031308-uNHYY6MdDXOs0BYMXXVb\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" weather\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031308-uNHYY6MdDXOs0BYMXXVb\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" in\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031308-uNHYY6MdDXOs0BYMXXVb\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" Paris\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031308-uNHYY6MdDXOs0BYMXXVb\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031308-uNHYY6MdDXOs0BYMXXVb\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031308-uNHYY6MdDXOs0BYMXXVb\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" with\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031308-uNHYY6MdDXOs0BYMXXVb\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" a\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031308-uNHYY6MdDXOs0BYMXXVb\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" temperature\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031308-uNHYY6MdDXOs0BYMXXVb\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" of\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031308-uNHYY6MdDXOs0BYMXXVb\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031308-uNHYY6MdDXOs0BYMXXVb\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"22\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031308-uNHYY6MdDXOs0BYMXXVb\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031308-uNHYY6MdDXOs0BYMXXVb\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_7e69b4ef44\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"idLine truncated
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
-54
@@ -1,54 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"name": "openai-compatible-chat/openrouter-gpt-5-5-drives-a-tool-loop",
|
||||
"recordedAt": "2026-05-06T01:35:11.662Z",
|
||||
"tags": [
|
||||
"prefix:openai-compatible-chat",
|
||||
"protocol:openai-compatible-chat",
|
||||
"provider:openrouter",
|
||||
"tool",
|
||||
"tool-loop",
|
||||
"golden",
|
||||
"flagship"
|
||||
]
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"transport": "http",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https://openrouter.ai/api/v1/chat/completions",
|
||||
"headers": {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
"body": "{\"model\":\"openai/gpt-5.5\",\"messages\":[{\"role\":\"system\",\"content\":\"Use the get_weather tool exactly once, then answer in one short sentence.\"},{\"role\":\"user\",\"content\":\"What is the weather in Paris?\"}],\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"max_tokens\":80,\"temperature\":0}"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"content-type": "text/event-stream"
|
||||
},
|
||||
"body": ": OPENROUTER PROCESSING\n\n: OPENROUTER PROCESSING\n\ndata: {\"id\":\"gen-1778031308-dVa9axcHcOlG9GcilZkz\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-5.5-20260423\",\"provider\":\"OpenAI\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"id\":\"call_4A7V7UN36HXCUUn8qAOQaKGw\",\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"arguments\":\"\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031308-dVa9axcHcOlG9GcilZkz\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-5.5-20260423\",\"provider\":\"OpenAI\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031308-dVa9axcHcOlG9GcilZkz\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-5.5-20260423\",\"provider\":\"OpenAI\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"{\\\"\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031308-dVa9axcHcOlG9GcilZkz\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-5.5-20260423\",\"provider\":\"OpenAI\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031308-dVa9axcHcOlG9GcilZkz\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-5.5-20260423\",\"provider\":\"OpenAI\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"\\\":\\\"\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031308-dVa9axcHcOlG9GcilZkz\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-5.5-20260423\",\"provider\":\"OpenAI\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Paris\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031308-dVa9axcHcOlG9GcilZkz\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-5.5-20260423\",\"provider\":\"OpenAI\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"\\\"}\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031308-dVa9axcHcOlG9GcilZkz\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-5.5-20260423\",\"provider\":\"OpenAI\",\"service_tier\":\"default\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"completed\"}]}\n\ndata: {\"id\":\"gen-1778031308-dVa9axcHcOlG9GcilZkz\",\"object\":\"chat.completion.chunk\",\"created\":1778031308,\"model\":\"openai/gpt-5.5-20260423\",\"provider\":\"OpenAI\",\"service_tier\":\"default\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"completed\"}],\"usage\":{\"prompt_tokens\":69,\"completion_tokens\":18,\"total_tokens\":87,\"cost\":0.000885,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.000885,\"upstream_inference_prompt_cost\":0.000345,\"upstream_inference_completions_cost\":0.00054},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}\n\ndata: [DONE]\n\n"
|
||||
}
|
||||
},
|
||||
{
|
||||
"transport": "http",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https://openrouter.ai/api/v1/chat/completions",
|
||||
"headers": {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
"body": "{\"model\":\"openai/gpt-5.5\",\"messages\":[{\"role\":\"system\",\"content\":\"Use the get_weather tool exactly once, then answer in one short sentence.\"},{\"role\":\"user\",\"content\":\"What is the weather in Paris?\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"call_4A7V7UN36HXCUUn8qAOQaKGw\",\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"}}]},{\"role\":\"tool\",\"tool_call_id\":\"call_4A7V7UN36HXCUUn8qAOQaKGw\",\"content\":\"{\\\"temperature\\\":22,\\\"condition\\\":\\\"sunny\\\"}\"}],\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"max_tokens\":80,\"temperature\":0}"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"content-type": "text/event-stream"
|
||||
},
|
||||
"body": ": OPENROUTER PROCESSING\n\n: OPENROUTER PROCESSING\n\ndata: {\"id\":\"gen-1778031310-JUYfFzDbun699uUYoA4N\",\"object\":\"chat.completion.chunk\",\"created\":1778031310,\"model\":\"openai/gpt-5.5-20260423\",\"provider\":\"OpenAI\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Paris\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031310-JUYfFzDbun699uUYoA4N\",\"object\":\"chat.completion.chunk\",\"created\":1778031310,\"model\":\"openai/gpt-5.5-20260423\",\"provider\":\"OpenAI\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031310-JUYfFzDbun699uUYoA4N\",\"object\":\"chat.completion.chunk\",\"created\":1778031310,\"model\":\"openai/gpt-5.5-20260423\",\"provider\":\"OpenAI\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" sunny\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031310-JUYfFzDbun699uUYoA4N\",\"object\":\"chat.completion.chunk\",\"created\":1778031310,\"model\":\"openai/gpt-5.5-20260423\",\"provider\":\"OpenAI\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" and\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031310-JUYfFzDbun699uUYoA4N\",\"object\":\"chat.completion.chunk\",\"created\":1778031310,\"model\":\"openai/gpt-5.5-20260423\",\"provider\":\"OpenAI\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" \",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031310-JUYfFzDbun699uUYoA4N\",\"object\":\"chat.completion.chunk\",\"created\":1778031310,\"model\":\"openai/gpt-5.5-20260423\",\"provider\":\"OpenAI\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"22\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031310-JUYfFzDbun699uUYoA4N\",\"object\":\"chat.completion.chunk\",\"created\":1778031310,\"model\":\"openai/gpt-5.5-20260423\",\"provider\":\"OpenAI\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"°C\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031310-JUYfFzDbun699uUYoA4N\",\"object\":\"chat.completion.chunk\",\"created\":1778031310,\"model\":\"openai/gpt-5.5-20260423\",\"provider\":\"OpenAI\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\".\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031310-JUYfFzDbun699uUYoA4N\",\"object\":\"chat.completion.chunk\",\"created\":1778031310,\"model\":\"openai/gpt-5.5-20260423\",\"provider\":\"OpenAI\",\"service_tier\":\"default\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"stop\",\"native_finish_reason\":\"completed\"}]}\n\ndata: {\"id\":\"gen-1778031310-JUYfFzDbun699uUYoA4N\",\"object\":\"chat.completion.chunk\",\"created\":1778031310,\"model\":\"openai/gpt-5.5-20260423\",\"provider\":\"OpenAI\",\"service_tier\":\"default\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"stop\",\"native_finish_reason\":\"completed\"}],\"usage\":{\"prompt_tokens\":108,\"completion_tokens\":12,\"total_tokens\":120,\"cost\":0.0009,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.0009,\"upstream_inference_prompt_cost\":0.00054,\"upstream_inference_completions_cost\":0.00036},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}\n\ndata: [DONE]\n\n"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"name": "openai-compatible-chat/openrouter-streams-text",
|
||||
"recordedAt": "2026-05-06T01:35:06.767Z",
|
||||
"tags": ["prefix:openai-compatible-chat", "protocol:openai-compatible-chat", "provider:openrouter"]
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"transport": "http",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https://openrouter.ai/api/v1/chat/completions",
|
||||
"headers": {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
"body": "{\"model\":\"openai/gpt-4o-mini\",\"messages\":[{\"role\":\"system\",\"content\":\"You are concise.\"},{\"role\":\"user\",\"content\":\"Reply with exactly: Hello!\"}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"max_tokens\":20,\"temperature\":0}"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"content-type": "text/event-stream"
|
||||
},
|
||||
"body": ": OPENROUTER PROCESSING\n\ndata: {\"id\":\"gen-1778031306-UD7bR0I1JNCsPvVzlXat\",\"object\":\"chat.completion.chunk\",\"created\":1778031306,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"Azure\",\"system_fingerprint\":\"fp_eb37e061ec\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Hello\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031306-UD7bR0I1JNCsPvVzlXat\",\"object\":\"chat.completion.chunk\",\"created\":1778031306,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"Azure\",\"system_fingerprint\":\"fp_eb37e061ec\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"!\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031306-UD7bR0I1JNCsPvVzlXat\",\"object\":\"chat.completion.chunk\",\"created\":1778031306,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"Azure\",\"system_fingerprint\":\"fp_eb37e061ec\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\"}]}\n\ndata: {\"id\":\"gen-1778031306-UD7bR0I1JNCsPvVzlXat\",\"object\":\"chat.completion.chunk\",\"created\":1778031306,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"Azure\",\"system_fingerprint\":\"fp_eb37e061ec\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"stop\",\"native_finish_reason\":\"stop\"}],\"usage\":{\"prompt_tokens\":21,\"completion_tokens\":3,\"total_tokens\":24,\"cost\":0.00000495,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00000495,\"upstream_inference_prompt_cost\":0.00000315,\"upstream_inference_completions_cost\":0.0000018},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}\n\ndata: [DONE]\n\n"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
-28
@@ -1,28 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"name": "openai-compatible-chat/openrouter-streams-tool-call",
|
||||
"recordedAt": "2026-05-06T01:35:07.466Z",
|
||||
"tags": ["prefix:openai-compatible-chat", "protocol:openai-compatible-chat", "provider:openrouter", "tool"]
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"transport": "http",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https://openrouter.ai/api/v1/chat/completions",
|
||||
"headers": {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
"body": "{\"model\":\"openai/gpt-4o-mini\",\"messages\":[{\"role\":\"system\",\"content\":\"Call tools exactly as requested.\"},{\"role\":\"user\",\"content\":\"Call get_weather with city exactly Paris.\"}],\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}}],\"tool_choice\":{\"type\":\"function\",\"function\":{\"name\":\"get_weather\"}},\"stream\":true,\"stream_options\":{\"include_usage\":true},\"max_tokens\":80,\"temperature\":0}"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"content-type": "text/event-stream"
|
||||
},
|
||||
"body": ": OPENROUTER PROCESSING\n\ndata: {\"id\":\"gen-1778031306-HYzOq04JIk1hZQ4iaNjD\",\"object\":\"chat.completion.chunk\",\"created\":1778031306,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_b6580bbee1\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"id\":\"call_L7mHMq49ZSUTBHjLJfBIP2eT\",\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"arguments\":\"\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031306-HYzOq04JIk1hZQ4iaNjD\",\"object\":\"chat.completion.chunk\",\"created\":1778031306,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_b6580bbee1\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031306-HYzOq04JIk1hZQ4iaNjD\",\"object\":\"chat.completion.chunk\",\"created\":1778031306,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_b6580bbee1\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"{\\\"\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031306-HYzOq04JIk1hZQ4iaNjD\",\"object\":\"chat.completion.chunk\",\"created\":1778031306,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_b6580bbee1\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"city\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031306-HYzOq04JIk1hZQ4iaNjD\",\"object\":\"chat.completion.chunk\",\"created\":1778031306,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_b6580bbee1\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"\\\":\\\"\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031306-HYzOq04JIk1hZQ4iaNjD\",\"object\":\"chat.completion.chunk\",\"created\":1778031306,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_b6580bbee1\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"Paris\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031306-HYzOq04JIk1hZQ4iaNjD\",\"object\":\"chat.completion.chunk\",\"created\":1778031306,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_b6580bbee1\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"\\\"}\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1778031306-HYzOq04JIk1hZQ4iaNjD\",\"object\":\"chat.completion.chunk\",\"created\":1778031306,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_b6580bbee1\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"stop\"}]}\n\ndata: {\"id\":\"gen-1778031306-HYzOq04JIk1hZQ4iaNjD\",\"object\":\"chat.completion.chunk\",\"created\":1778031306,\"model\":\"openai/gpt-4o-mini\",\"provider\":\"OpenAI\",\"system_fingerprint\":\"fp_b6580bbee1\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"stop\"}],\"usage\":{\"prompt_tokens\":67,\"completion_tokens\":5,\"total_tokens\":72,\"cost\":0.00001305,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.00001305,\"upstream_inference_prompt_cost\":0.00001005,\"upstream_inference_completions_cost\":0.000003},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}\n\ndata: [DONE]\n\n"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+57
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"provider": "openrouter",
|
||||
"route": "openrouter-messages",
|
||||
"transport": "http",
|
||||
"model": "anthropic/claude-opus-4.7",
|
||||
"tags": [
|
||||
"prefix:openrouter-messages",
|
||||
"provider:openrouter",
|
||||
"flagship",
|
||||
"tool",
|
||||
"tool-loop",
|
||||
"golden"
|
||||
],
|
||||
"name": "openrouter-messages/openrouter-claude-opus-4-7-tool-loop",
|
||||
"recordedAt": "2026-09-30T03:26:16.603Z"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"transport": "http",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https://openrouter.ai/api/v1/messages",
|
||||
"headers": {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
"body": "{\"model\":\"anthropic/claude-opus-4.7\",\"system\":[{\"type\":\"text\",\"text\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\"}],\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"What is the weather in Paris?\"}]}],\"tools\":[{\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"input_schema\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"stream\":true,\"max_tokens\":80,\"temperature\":0}"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"content-type": "text/event-stream"
|
||||
},
|
||||
"body": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"id\":\"gen-1790738774-LwBI9xYpi0PJ3zyXvhBe\",\"type\":\"message\",\"role\":\"assistant\",\"container\":null,\"content\":[],\"model\":\"anthropic/claude-opus-4.7\",\"stop_reason\":null,\"stop_details\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":812,\"output_tokens\":1,\"output_tokens_details\":null,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"inference_geo\":\"global\",\"server_tool_use\":null,\"service_tier\":\"standard\",\"speed\":\"standard\"},\"provider\":\"Claude Platform on AWS\"}}\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01SvA3dpQ3bwgAKjQB1d9rL5\",\"caller\":{\"type\":\"direct\"},\"name\":\"get_weather\",\"input\":{}}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"city\\\": \\\"Paris\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"}}\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"container\":null,\"stop_details\":null,\"stop_reason\":\"tool_use\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":812,\"output_tokens\":66,\"output_tokens_details\":{\"thinking_tokens\":0},\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"server_tool_use\":null,\"service_tier\":\"standard\",\"speed\":\"standard\",\"cost\":0.00571,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.00571,\"upstream_inference_prompt_cost\":0.00406,\"upstream_inference_completions_cost\":0.00165}},\"context_management\":null}\n\nevent: message_stop\ndata: {\"type\":\"message_stop\"}\n\nevent: data\ndata: [DONE]\n\n"
|
||||
}
|
||||
},
|
||||
{
|
||||
"transport": "http",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https://openrouter.ai/api/v1/messages",
|
||||
"headers": {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
"body": "{\"model\":\"anthropic/claude-opus-4.7\",\"system\":[{\"type\":\"text\",\"text\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\"}],\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"What is the weather in Paris?\"}]},{\"role\":\"assistant\",\"content\":[{\"type\":\"tool_use\",\"id\":\"toolu_01SvA3dpQ3bwgAKjQB1d9rL5\",\"name\":\"get_weather\",\"input\":{\"city\":\"Paris\"}}]},{\"role\":\"user\",\"content\":[{\"type\":\"tool_result\",\"tool_use_id\":\"toolu_01SvA3dpQ3bwgAKjQB1d9rL5\",\"content\":\"{\\\"temperature\\\":22,\\\"condition\\\":\\\"sunny\\\"}\"}]}],\"tools\":[{\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"input_schema\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false}}],\"stream\":true,\"max_tokens\":80,\"temperature\":0}"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"content-type": "text/event-stream"
|
||||
},
|
||||
"body": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"id\":\"gen-1790738775-mOcJ0PIOdQqPcuWboQoJ\",\"type\":\"message\",\"role\":\"assistant\",\"container\":null,\"content\":[],\"model\":\"anthropic/claude-opus-4.7\",\"stop_reason\":null,\"stop_details\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":909,\"output_tokens\":9,\"output_tokens_details\":null,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"inference_geo\":\"global\",\"server_tool_use\":null,\"service_tier\":\"standard\",\"speed\":\"standard\"},\"provider\":\"Claude Platform on AWS\"}}\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\",\"citations\":[]}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Paris is sunny.\"}}\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"container\":null,\"stop_details\":null,\"stop_reason\":\"end_turn\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":909,\"output_tokens\":12,\"output_tokens_details\":{\"thinking_tokens\":0},\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"server_tool_use\":null,\"service_tier\":\"standard\",\"speed\":\"standard\",\"cost\":0.004845,\"is_byok\":false,\"cost_details\":{\"upstream_inference_cost\":0.004845,\"upstream_inference_prompt_cost\":0.004545,\"upstream_inference_completions_cost\":0.0003}},\"context_management\":null}\n\nevent: message_stop\ndata: {\"type\":\"message_stop\"}\n\nevent: data\ndata: [DONE]\n\n"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
"tool-loop"
|
||||
],
|
||||
"name": "openrouter-reasoning-tool-loop",
|
||||
"recordedAt": "2026-07-18T18:02:15.859Z"
|
||||
"recordedAt": "2026-09-30T03:26:06.234Z"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
@@ -23,14 +23,14 @@
|
||||
"headers": {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
"body": "{\"model\":\"anthropic/claude-sonnet-4.6\",\"messages\":[{\"role\":\"system\",\"content\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\"},{\"role\":\"user\",\"content\":\"What is the weather in Paris?\"}],\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false},\"strict\":false}}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning\":{\"max_tokens\":1024},\"max_completion_tokens\":1536,\"store\":false,\"usage\":{\"include\":true}}"
|
||||
"body": "{\"model\":\"anthropic/claude-sonnet-4.6\",\"messages\":[{\"role\":\"system\",\"content\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\"},{\"role\":\"user\",\"content\":\"What is the weather in Paris?\"}],\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false},\"strict\":false}}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"store\":false,\"max_completion_tokens\":1536,\"usage\":{\"include\":true},\"reasoning\":{\"max_tokens\":1024}}"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"content-type": "text/event-stream"
|
||||
},
|
||||
"body": ": OPENROUTER PROCESSING\n\n: OPENROUTER PROCESSING\n\ndata: {\"id\":\"gen-1784397732-OaggEWvVIDtBtcPF4n0O\",\"object\":\"chat.completion.chunk\",\"created\":1784397732,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Anthropic\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning\":\"The user wants\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"The user wants\",\"format\":\"anthropic-claude-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\n: OPENROUTER PROCESSING\n\ndata: {\"id\":\"gen-1784397732-OaggEWvVIDtBtcPF4n0O\",\"object\":\"chat.completion.chunk\",\"created\":1784397732,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Anthropic\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning\":\" to know the weather in Paris. I'll use the get_weather tool.\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\" to know the weather in Paris. I'll use the get_weather tool.\",\"format\":\"anthropic-claude-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1784397732-OaggEWvVIDtBtcPF4n0O\",\"object\":\"chat.completion.chunk\",\"created\":1784397732,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Anthropic\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"signature\":\"ErkCCosBCA8YAipAjKnRKpxkZ4eHrMPJ63IWEOYPSzb+XSHyG+vLK+2ks2O9T4N9M37Xn2kausQSH1rfsrdmKxgUlBg6yUFRgMVR7DIRY2xhdWRlLXNvbm5ldC00LTY4AEIIdGhpbmtpbmdaJDRjMGYwNDZmLTI1ZmQtNDVmYi1iZmIzLWEwOGE4ZTI0OWNhNxIMNFb5O6pb4nX0HojdGgyL5h+CAIpsxpdM1QgiMGm/i3ST6F5mAhxB+Uez0Cm95ra9yvQkrzHaA/AmWoXpdmPlczSn1S1RDk2IqeA57Spbf7JT44jygtLQt6yZmGzoTBHn3VkwaNZsuuAtbdo4B5QJXooa/AoKKs54QZ2kfS640vsv5flQVCg7CoQCFuLKjIeLMO7MnxVyuskXJr1DgesTa7I0ScF53U9JGhgB\",\"format\":\"anthropic-claude-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1784397732-OaggEWvVIDtBtcPF4n0O\",\"object\":\"chat.completion.chunk\",\"created\":1784397732,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Anthropic\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Sure! Let me check the weather in Paris for you right now!\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1784397732-OaggEWvVIDtBtcPF4n0O\",\"object\":\"chat.completion.chunk\",\"created\":1784397732,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Anthropic\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"id\":\"toolu_01PaChhcyw3yu2P2bDS2bgAA\",\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"arguments\":\"\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1784397732-OaggEWvVIDtBtcPF4n0O\",\"object\":\"chat.completion.chunk\",\"created\":1784397732,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Anthropic\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1784397732-OaggEWvVIDtBtcPF4n0O\",\"object\":\"chat.completion.chunk\",\"created\":1784397732,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Anthropic\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"{\\\"city\\\": \\\"Paris\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1784397732-OaggEWvVIDtBtcPF4n0O\",\"object\":\"chat.completion.chunk\",\"created\":1784397732,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Anthropic\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"\\\"}\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1784397732-OaggEWvVIDtBtcPF4n0O\",\"object\":\"chat.completion.chunk\",\"created\":1784397732,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Anthropic\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning\":null},\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_use\"}]}\n\ndata: {\"id\":\"gen-1784397732-OaggEWvVIDtBtcPF4n0O\",\"object\":\"chat.completion.chunk\",\"created\":1784397732,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Anthropic\",\"service_tier\":\"default\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_use\"}],\"usage\":{\"prompt_tokens\":623,\"completion_tokens\":95,\"total_tokens\":718,\"cost\":0.003294,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":Line truncated
|
||||
"body": "data: {\"id\":\"gen-1790738763-cLmF3upylLrqz58qLiQ2\",\"object\":\"chat.completion.chunk\",\"created\":1790738763,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning\":\"The user wants\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"The user wants\",\"format\":\"anthropic-claude-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\n: OPENROUTER PROCESSING\n\ndata: {\"id\":\"gen-1790738763-cLmF3upylLrqz58qLiQ2\",\"object\":\"chat.completion.chunk\",\"created\":1790738763,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning\":\" to know the weather in Paris. I'll use the get_weather tool.\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\" to know the weather in Paris. I'll use the get_weather tool.\",\"format\":\"anthropic-claude-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1790738763-cLmF3upylLrqz58qLiQ2\",\"object\":\"chat.completion.chunk\",\"created\":1790738763,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"signature\":\"EvYCCsgBCBIYAipAjKnRKpxkZ4eHrMPJ63IWEOYPSzb+XSHyG+vLK+2ks2O9T4N9M37Xn2kausQSH1rfsrdmKxgUlBg6yUFRgMVR7DIRY2xhdWRlLXNvbm5ldC00LTY4AEIIdGhpbmtpbmdaJDRjMGYwNDZmLTI1ZmQtNDVmYi1iZmIzLWEwOGE4ZTI0OWNhN3oedXByb2ZfMDExQ2VkSE1TN0tEcTM4Z2JkUkp0bXN3mgETChFjbGF1ZGUtc29ubmV0LTQtNqgBzILy1QYSDFwo5I55U6b4oC6oohoMKH0vEsGP035p9LPZIjAmgXOfpb58HYr3aEwAj9NvsqYcq2mL4QiqZ8gcOZ8QlXuGvbNJ56OIq6ZDadLUEh4qW3v0JxLk6mONdlQM0m76mT1Xrt/l5ZXl9fV9T04g9PBkl7ukDGmuEsRW/6zg2YtkljJwo7Qo0LWE8Z4pkuaCRklq4xjuIdLX/F/+wyFHV+yDCU5PeK6yAWxm0EoYAQ==.eyJlbmRwb2ludF9zbHVnIjoiYW50aHJvcGljL2NsYXVkZS00LjYtc29ubmV0LTIwMjYwMjE3fGNsYXVkZS1vbi1hd3MifQ\",\"format\":\"anthropic-claude-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1790738763-cLmF3upylLrqz58qLiQ2\",\"object\":\"chat.completion.chunk\",\"created\":1790738763,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Sure! Let me check the current weather in Paris for you!\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1790738763-cLmF3upylLrqz58qLiQ2\",\"object\":\"chat.completion.chunk\",\"created\":1790738763,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"id\":\"toolu_01VJ6V9mVwph96Kbn2DnkCc9\",\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"arguments\":\"\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1790738763-cLmF3upylLrqz58qLiQ2\",\"object\":\"chat.completion.chunk\",\"created\":1790738763,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1790738763-cLmF3upylLrqz58qLiQ2\",\"object\":\"chat.completion.chunk\",\"created\":1790738763,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"{\\\"city\\\": \\\"Paris\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1790738763-cLmF3upylLrqz58qLiQ2\",\"object\":\"chat.completion.chunk\",\"created\":1790738763,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":null,\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":\"\\\"}\"}}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1790738763-cLmF3upylLrqz58qLiQ2\",\"object\":\"chat.completion.chunk\",\"created\":1790738763,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning\":null},\"finish_reason\":\"tool_calls\",\"native_finish_reason\":\"tool_use\"}]}\n\ndata: {\"id\":\"gen-1790738763-cLmF3upylLrqz58qLiQ2\",\"object\":\"chat.completion.chunk\",\"created\":1790738763,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"service_tier\":\"default\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"tool_calls\",\"native_fLine truncated
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -41,14 +41,14 @@
|
||||
"headers": {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
"body": "{\"model\":\"anthropic/claude-sonnet-4.6\",\"messages\":[{\"role\":\"system\",\"content\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\"},{\"role\":\"user\",\"content\":\"What is the weather in Paris?\"},{\"role\":\"assistant\",\"content\":\"Sure! Let me check the weather in Paris for you right now!\",\"tool_calls\":[{\"id\":\"toolu_01PaChhcyw3yu2P2bDS2bgAA\",\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"}}],\"reasoning\":\"The user wants to know the weather in Paris. I'll use the get_weather tool.\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"The user wants to know the weather in Paris. I'll use the get_weather tool.\",\"format\":\"anthropic-claude-v1\",\"index\":0,\"signature\":\"ErkCCosBCA8YAipAjKnRKpxkZ4eHrMPJ63IWEOYPSzb+XSHyG+vLK+2ks2O9T4N9M37Xn2kausQSH1rfsrdmKxgUlBg6yUFRgMVR7DIRY2xhdWRlLXNvbm5ldC00LTY4AEIIdGhpbmtpbmdaJDRjMGYwNDZmLTI1ZmQtNDVmYi1iZmIzLWEwOGE4ZTI0OWNhNxIMNFb5O6pb4nX0HojdGgyL5h+CAIpsxpdM1QgiMGm/i3ST6F5mAhxB+Uez0Cm95ra9yvQkrzHaA/AmWoXpdmPlczSn1S1RDk2IqeA57Spbf7JT44jygtLQt6yZmGzoTBHn3VkwaNZsuuAtbdo4B5QJXooa/AoKKs54QZ2kfS640vsv5flQVCg7CoQCFuLKjIeLMO7MnxVyuskXJr1DgesTa7I0ScF53U9JGhgB\"}]},{\"role\":\"tool\",\"tool_call_id\":\"toolu_01PaChhcyw3yu2P2bDS2bgAA\",\"content\":\"{\\\"temperature\\\":22,\\\"condition\\\":\\\"sunny\\\"}\"}],\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false},\"strict\":false}}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning\":{\"max_tokens\":1024},\"max_completion_tokens\":1536,\"store\":false,\"usage\":{\"include\":true}}"
|
||||
"body": "{\"model\":\"anthropic/claude-sonnet-4.6\",\"messages\":[{\"role\":\"system\",\"content\":\"Use the get_weather tool exactly once. After the tool result, reply exactly: Paris is sunny.\"},{\"role\":\"user\",\"content\":\"What is the weather in Paris?\"},{\"role\":\"assistant\",\"content\":\"Sure! Let me check the current weather in Paris for you!\",\"tool_calls\":[{\"id\":\"toolu_01VJ6V9mVwph96Kbn2DnkCc9\",\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"}}],\"reasoning\":\"The user wants to know the weather in Paris. I'll use the get_weather tool.\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"The user wants to know the weather in Paris. I'll use the get_weather tool.\",\"format\":\"anthropic-claude-v1\",\"index\":0,\"signature\":\"EvYCCsgBCBIYAipAjKnRKpxkZ4eHrMPJ63IWEOYPSzb+XSHyG+vLK+2ks2O9T4N9M37Xn2kausQSH1rfsrdmKxgUlBg6yUFRgMVR7DIRY2xhdWRlLXNvbm5ldC00LTY4AEIIdGhpbmtpbmdaJDRjMGYwNDZmLTI1ZmQtNDVmYi1iZmIzLWEwOGE4ZTI0OWNhN3oedXByb2ZfMDExQ2VkSE1TN0tEcTM4Z2JkUkp0bXN3mgETChFjbGF1ZGUtc29ubmV0LTQtNqgBzILy1QYSDFwo5I55U6b4oC6oohoMKH0vEsGP035p9LPZIjAmgXOfpb58HYr3aEwAj9NvsqYcq2mL4QiqZ8gcOZ8QlXuGvbNJ56OIq6ZDadLUEh4qW3v0JxLk6mONdlQM0m76mT1Xrt/l5ZXl9fV9T04g9PBkl7ukDGmuEsRW/6zg2YtkljJwo7Qo0LWE8Z4pkuaCRklq4xjuIdLX/F/+wyFHV+yDCU5PeK6yAWxm0EoYAQ==.eyJlbmRwb2ludF9zbHVnIjoiYW50aHJvcGljL2NsYXVkZS00LjYtc29ubmV0LTIwMjYwMjE3fGNsYXVkZS1vbi1hd3MifQ\"}]},{\"role\":\"tool\",\"tool_call_id\":\"toolu_01VJ6V9mVwph96Kbn2DnkCc9\",\"content\":\"{\\\"temperature\\\":22,\\\"condition\\\":\\\"sunny\\\"}\"}],\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"description\":\"Get current weather for a city.\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\"}},\"required\":[\"city\"],\"additionalProperties\":false},\"strict\":false}}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"store\":false,\"max_completion_tokens\":1536,\"usage\":{\"include\":true},\"reasoning\":{\"max_tokens\":1024}}"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"content-type": "text/event-stream"
|
||||
},
|
||||
"body": ": OPENROUTER PROCESSING\n\n: OPENROUTER PROCESSING\n\ndata: {\"id\":\"gen-1784397734-HY78YkUzZ8xIXuimN9bb\",\"object\":\"chat.completion.chunk\",\"created\":1784397734,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Anthropic\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Paris\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1784397734-HY78YkUzZ8xIXuimN9bb\",\"object\":\"chat.completion.chunk\",\"created\":1784397734,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Anthropic\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is sunny.\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1784397734-HY78YkUzZ8xIXuimN9bb\",\"object\":\"chat.completion.chunk\",\"created\":1784397734,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Anthropic\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"stop\",\"native_finish_reason\":\"end_turn\"}]}\n\ndata: {\"id\":\"gen-1784397734-HY78YkUzZ8xIXuimN9bb\",\"object\":\"chat.completion.chunk\",\"created\":1784397734,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Anthropic\",\"service_tier\":\"default\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"stop\",\"native_finish_reason\":\"end_turn\"}],\"usage\":{\"prompt_tokens\":739,\"completion_tokens\":7,\"total_tokens\":746,\"cost\":0.002322,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.002322,\"upstream_inference_prompt_cost\":0.002217,\"upstream_inference_completions_cost\":0.000105},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}\n\ndata: [DONE]\n\n"
|
||||
"body": "data: {\"id\":\"gen-1790738765-bupRgL3ALE5BNhkJadtZ\",\"object\":\"chat.completion.chunk\",\"created\":1790738765,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Paris\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1790738765-bupRgL3ALE5BNhkJadtZ\",\"object\":\"chat.completion.chunk\",\"created\":1790738765,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" is sunny.\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1790738765-bupRgL3ALE5BNhkJadtZ\",\"object\":\"chat.completion.chunk\",\"created\":1790738765,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"stop\",\"native_finish_reason\":\"end_turn\"}]}\n\ndata: {\"id\":\"gen-1790738765-bupRgL3ALE5BNhkJadtZ\",\"object\":\"chat.completion.chunk\",\"created\":1790738765,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"service_tier\":\"default\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"stop\",\"native_finish_reason\":\"end_turn\"}],\"usage\":{\"prompt_tokens\":738,\"completion_tokens\":7,\"total_tokens\":745,\"cost\":0.002319,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.002319,\"upstream_inference_prompt_cost\":0.002214,\"upstream_inference_completions_cost\":0.000105},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"image_tokens\":0,\"audio_tokens\":0}}}\n\ndata: [DONE]\n\n"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"model": "anthropic/claude-sonnet-4.6",
|
||||
"tags": ["prefix:openai-compatible-chat", "provider:openrouter", "protocol:openai-chat", "reasoning"],
|
||||
"tags": [
|
||||
"prefix:openai-compatible-chat",
|
||||
"provider:openrouter",
|
||||
"protocol:openai-chat",
|
||||
"reasoning"
|
||||
],
|
||||
"name": "openrouter-reasoning",
|
||||
"recordedAt": "2026-09-29T16:19:02.835Z"
|
||||
"recordedAt": "2026-09-30T03:26:02.917Z"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
@@ -22,7 +27,7 @@
|
||||
"headers": {
|
||||
"content-type": "text/event-stream"
|
||||
},
|
||||
"body": "data: {\"id\":\"gen-1790698739-Acm5E9n2uVTO14sqrick\",\"object\":\"chat.completion.chunk\",\"created\":1790698739,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning\":\"173\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"173\",\"format\":\"anthropic-claude-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\n: OPENROUTER PROCESSING\n\ndata: {\"id\":\"gen-1790698739-Acm5E9n2uVTO14sqrick\",\"object\":\"chat.completion.chunk\",\"created\":1790698739,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning\":\" × 219\\n\\n173 × 200 = 34,600\\n173 × 19 = 173 × 20 - 173 = 3,460 - 173 = 3,287\\n\\n34,600 + 3,287 = 37,887\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\" × 219\\n\\n173 × 200 = 34,600\\n173 × 19 = 173 × 20 - 173 = 3,460 - 173 = 3,287\\n\\n34,600 + 3,287 = 37,887\",\"format\":\"anthropic-claude-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1790698739-Acm5E9n2uVTO14sqrick\",\"object\":\"chat.completion.chunk\",\"created\":1790698739,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"signature\":\"Ev8CCrIBCBIYAipA0W4viH3kgBs43Cl5ewwVBPXTQElvzfbA2TLF4iSbKy9ZZDCSDjjAlF3Bs4ELEnP3vrrTuTioC6OB380lXQdyIDIRY2xhdWRlLXNvbm5ldC00LTY4AEIIdGhpbmtpbmdaJDRjMGYwNDZmLTI1ZmQtNDVmYi1iZmIzLWEwOGE4ZTI0OWNhN3oedXByb2ZfMDExQ2VkSE1TN0tEcTM4Z2JkUkp0bXN3qAH2ye/VBhIMhjcPOnE2wLhs0P05GgwA3z9luwbhnSyRMSQiMDYeIIThirdkJb/n2s2TxUk5EOMrSc1xejAb0RN7BIl66P5KhtwXvcZTiyCkBS8+7Cp6MOinWi+I8U7DhWskSA0pHZqaAncbV7qCIHkoZ5aT8jiPWplAOnlciDo2tLkGsLnzXrnfhI11GTF0kcfyhbrt3tjEDSiPstBbT2u19LJ5IqwV2VKl0pWVdl4PTsDwC09ClbnJj1y0A3AM9gEh4B9mEo4BvT0XVEncux4YAQ==.eyJlbmRwb2ludF9zbHVnIjoiYW50aHJvcGljL2NsYXVkZS00LjYtc29ubmV0LTIwMjYwMjE3fGNsYXVkZS1vbi1hd3MifQ\",\"format\":\"anthropic-claude-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1790698739-Acm5E9n2uVTO14sqrick\",\"object\":\"chat.completion.chunk\",\"created\":1790698739,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"37\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1790698739-Acm5E9n2uVTO14sqrick\",\"object\":\"chat.completion.chunk\",\"created\":1790698739,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"887\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1790698739-Acm5E9n2uVTO14sqrick\",\"object\":\"chat.completion.chunk\",\"created\":1790698739,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning\":null},\"finish_reason\":\"stop\",\"native_finish_reason\":\"end_turn\"}]}\n\ndata: {\"id\":\"gen-1790698739-Acm5E9n2uVTO14sqrick\",\"object\":\"chat.completion.chunk\",\"created\":1790698739,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"service_tier\":\"default\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"stop\",\"native_finish_reason\":\"end_turn\"}],\"usage\":{\"prompt_tokens\":61,\"completion_tokens\":80,\"total_tokens\":141,\"cost\":0.001383,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.001383,\"upstream_inference_prompt_cost\":0.000183,\"upstream_inference_completions_cost\":0.0012},\"completion_tokens_details\":{\"reasoning_tokens\":73,\"image_tokens\":0,\"audio_tokens\":0}}}\n\ndata: [DONE]\n\n"
|
||||
"body": "data: {\"id\":\"gen-1790738761-YbCA1TN8srf01M309CrM\",\"object\":\"chat.completion.chunk\",\"created\":1790738761,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning\":\"173\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"173\",\"format\":\"anthropic-claude-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1790738761-YbCA1TN8srf01M309CrM\",\"object\":\"chat.completion.chunk\",\"created\":1790738761,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning\":\" × 219\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\" × 219\",\"format\":\"anthropic-claude-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\n: OPENROUTER PROCESSING\n\ndata: {\"id\":\"gen-1790738761-YbCA1TN8srf01M309CrM\",\"object\":\"chat.completion.chunk\",\"created\":1790738761,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning\":\"\\n\\n173 × 200 = 34,600\\n173 × 19 = 173 × 20 - 173 = 3,460 - 173 = 3,287\\n\\n34,600 + 3,287 = 37,887\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"text\":\"\\n\\n173 × 200 = 34,600\\n173 × 19 = 173 × 20 - 173 = 3,460 - 173 = 3,287\\n\\n34,600 + 3,287 = 37,887\",\"format\":\"anthropic-claude-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1790738761-YbCA1TN8srf01M309CrM\",\"object\":\"chat.completion.chunk\",\"created\":1790738761,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_details\":[{\"type\":\"reasoning.text\",\"signature\":\"EpUDCsgBCBIYAipA0W4viH3kgBs43Cl5ewwVBPXTQElvzfbA2TLF4iSbKy9ZZDCSDjjAlF3Bs4ELEnP3vrrTuTioC6OB380lXQdyIDIRY2xhdWRlLXNvbm5ldC00LTY4AEIIdGhpbmtpbmdaJDRjMGYwNDZmLTI1ZmQtNDVmYi1iZmIzLWEwOGE4ZTI0OWNhN3oedXByb2ZfMDExQ2VkSE1TN0tEcTM4Z2JkUkp0bXN3mgETChFjbGF1ZGUtc29ubmV0LTQtNqgByoLy1QYSDPcyAL64+muA2ku9uxoM4jS27X6iJtqcbymQIjCyOPIBbqmb8CRfcLBCI42CRACGhf+ApKDRPkGhPEDctIGeeo2QaGy8WGT6kEX2zYsqeuExYES4JaCt7xyC+1GYlUhbEFMRVPeV0gdkE72yBcl9rhbnK3S9Zs3u1pETV9E50s3tGIF+AP2UShvzdbsB7qDfr2xaUyE6/LgyGndMsxZprhW/nZqxt0YtXzJa4n5+pMMxJW+uv9BrleRRHdmyqpGGEduiZW2WQ4WgGAE=.eyJlbmRwb2ludF9zbHVnIjoiYW50aHJvcGljL2NsYXVkZS00LjYtc29ubmV0LTIwMjYwMjE3fGNsYXVkZS1vbi1hd3MifQ\",\"format\":\"anthropic-claude-v1\",\"index\":0}]},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1790738761-YbCA1TN8srf01M309CrM\",\"object\":\"chat.completion.chunk\",\"created\":1790738761,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"37887\",\"role\":\"assistant\"},\"finish_reason\":null,\"native_finish_reason\":null}]}\n\ndata: {\"id\":\"gen-1790738761-YbCA1TN8srf01M309CrM\",\"object\":\"chat.completion.chunk\",\"created\":1790738761,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning\":null},\"finish_reason\":\"stop\",\"native_finish_reason\":\"end_turn\"}]}\n\ndata: {\"id\":\"gen-1790738761-YbCA1TN8srf01M309CrM\",\"object\":\"chat.completion.chunk\",\"created\":1790738761,\"model\":\"anthropic/claude-sonnet-4.6\",\"provider\":\"Claude Platform on AWS\",\"service_tier\":\"default\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":\"stop\",\"native_finish_reason\":\"end_turn\"}],\"usage\":{\"prompt_tokens\":61,\"completion_tokens\":80,\"total_tokens\":141,\"cost\":0.001383,\"is_byok\":false,\"prompt_tokens_details\":{\"cached_tokens\":0,\"cache_write_tokens\":0,\"audio_tokens\":0,\"video_tokens\":0},\"cost_details\":{\"upstream_inference_cost\":0.001383,\"upstream_inference_prompt_cost\":0.000183,\"upstream_inference_completions_cost\":0.0012},\"completion_tokens_details\":{\"reasoning_tokens\":73,\"image_tokens\":0,\"audio_tokens\":0}}}\n\ndata: [DONE]\n\n"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"provider": "openrouter",
|
||||
"route": "openrouter-responses",
|
||||
"transport": "http",
|
||||
"model": "openai/gpt-4o-mini",
|
||||
"tags": [
|
||||
"prefix:openrouter-responses",
|
||||
"provider:openrouter",
|
||||
"text",
|
||||
"golden"
|
||||
],
|
||||
"name": "openrouter-responses/openrouter-gpt-4o-mini-text",
|
||||
"recordedAt": "2026-09-30T16:23:26.190Z"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"transport": "http",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https://openrouter.ai/api/v1/responses",
|
||||
"headers": {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
"body": "{\"model\":\"openai/gpt-4o-mini\",\"input\":[{\"type\":\"message\",\"role\":\"user\",\"content\":[{\"type\":\"input_text\",\"text\":\"Reply exactly with: Hello!\"}]}],\"instructions\":\"You are concise.\",\"store\":false,\"include\":[\"reasoning.encrypted_content\"],\"max_output_tokens\":40,\"temperature\":0,\"stream\":true}"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"content-type": "text/event-stream"
|
||||
},
|
||||
"body": "data: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790785405-TibUw8IxcUdeh1aIMexG\",\"object\":\"response\",\"created_at\":1790785405,\"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-1790785405-TibUw8IxcUdeh1aIMexG\",\"object\":\"response\",\"created_at\":1790785405,\"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_2aq1aouoqhw\",\"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_2aq1aouoqhw\",\"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_2aq1aouoqhw\",\"content_index\":0,\"delta\":\"Hello\",\"logprobs\":[],\"sequence_number\":4}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_2aq1aouoqhw\",\"content_index\":0,\"delta\":\"!\",\"logprobs\":[],\"sequence_number\":5}\n\ndata: {\"type\":\"response.output_text.done\",\"output_index\":0,\"item_id\":\"msg_tmp_2aq1aouoqhw\",\"content_index\":0,\"text\":\"Hello!\",\"logprobs\":[],\"sequence_number\":6}\n\ndata: {\"type\":\"response.content_part.done\",\"output_index\":0,\"item_id\":\"msg_tmp_2aq1aouoqhw\",\"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_2aq1aouoqhw\",\"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-1790785405-TibUw8IxcUdeh1aIMexG\",\"object\":\"response\",\"created_at\":1790785405,\"model\":\"openai/gpt-4o-mini\",\"status\":\"completed\",\"completed_at\":1790785406,\"output\":[{\"id\":\"msg_tmp_2aq1aouoqhw\",\"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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+38
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"provider": "openrouter",
|
||||
"route": "openrouter-responses",
|
||||
"transport": "http",
|
||||
"model": "openai/gpt-4o-mini",
|
||||
"tags": [
|
||||
"prefix:openrouter-responses",
|
||||
"provider:openrouter",
|
||||
"tool",
|
||||
"tool-call",
|
||||
"golden"
|
||||
],
|
||||
"name": "openrouter-responses/openrouter-gpt-4o-mini-tool-call",
|
||||
"recordedAt": "2026-09-30T16:23:26.840Z"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"transport": "http",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https://openrouter.ai/api/v1/responses",
|
||||
"headers": {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
"body": "{\"model\":\"openai/gpt-4o-mini\",\"input\":[{\"type\":\"message\",\"role\":\"user\",\"content\":[{\"type\":\"input_text\",\"text\":\"Call get_weather with city exactly Paris.\"}]}],\"instructions\":\"Call tools exactly as requested.\",\"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}],\"tool_choice\":{\"type\":\"function\",\"name\":\"get_weather\"},\"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-1790785406-YRp9TEkqlahVqXkJJHeX\",\"object\":\"response\",\"created_at\":1790785406,\"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-1790785406-YRp9TEkqlahVqXkJJHeX\",\"object\":\"response\",\"created_at\":1790785406,\"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_mumt1zk6h6p\",\"type\":\"function_call\",\"status\":\"in_progress\",\"call_id\":\"call_XK2Bdj78v8s3dW48fhSJAlT6\",\"name\":\"get_weather\",\"arguments\":\"\"},\"sequence_number\":2}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_mumt1zk6h6p\",\"delta\":\"{\\\"\",\"sequence_number\":3}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_mumt1zk6h6p\",\"delta\":\"city\",\"sequence_number\":4}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_mumt1zk6h6p\",\"delta\":\"\\\":\\\"\",\"sequence_number\":5}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_mumt1zk6h6p\",\"delta\":\"Paris\",\"sequence_number\":6}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_mumt1zk6h6p\",\"delta\":\"\\\"}\",\"sequence_number\":7}\n\ndata: {\"type\":\"response.function_call_arguments.done\",\"output_index\":0,\"item_id\":\"fc_tmp_mumt1zk6h6p\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\",\"sequence_number\":8}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"fc_tmp_mumt1zk6h6p\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_XK2Bdj78v8s3dW48fhSJAlT6\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},\"sequence_number\":9}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790785406-YRp9TEkqlahVqXkJJHeX\",\"object\":\"response\",\"created_at\":1790785406,\"model\":\"openai/gpt-4o-mini\",\"status\":\"completed\",\"completed_at\":1790785406,\"output\":[{\"id\":\"fc_tmp_mumt1zk6h6p\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_XK2Bdj78v8s3dW48fhSJAlT6\",\"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,\"preLine truncated
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+56
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"provider": "openrouter",
|
||||
"route": "openrouter-responses",
|
||||
"transport": "http",
|
||||
"model": "openai/gpt-4o-mini",
|
||||
"tags": [
|
||||
"prefix:openrouter-responses",
|
||||
"provider:openrouter",
|
||||
"tool",
|
||||
"tool-loop",
|
||||
"golden"
|
||||
],
|
||||
"name": "openrouter-responses/openrouter-gpt-4o-mini-tool-loop",
|
||||
"recordedAt": "2026-09-30T16:23:28.269Z"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"transport": "http",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https://openrouter.ai/api/v1/responses",
|
||||
"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?\"}]}],\"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-1790785406-ABGEk8CdTXhfL3hEYDWM\",\"object\":\"response\",\"created_at\":1790785406,\"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-1790785406-ABGEk8CdTXhfL3hEYDWM\",\"object\":\"response\",\"created_at\":1790785406,\"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_hgt0s8hlqsa\",\"type\":\"function_call\",\"status\":\"in_progress\",\"call_id\":\"call_lvGkIhJoXscAOT3UfLkVKowx\",\"name\":\"get_weather\",\"arguments\":\"\"},\"sequence_number\":2}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_hgt0s8hlqsa\",\"delta\":\"{\\\"\",\"sequence_number\":3}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_hgt0s8hlqsa\",\"delta\":\"city\",\"sequence_number\":4}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_hgt0s8hlqsa\",\"delta\":\"\\\":\\\"\",\"sequence_number\":5}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_hgt0s8hlqsa\",\"delta\":\"Paris\",\"sequence_number\":6}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_hgt0s8hlqsa\",\"delta\":\"\\\"}\",\"sequence_number\":7}\n\ndata: {\"type\":\"response.function_call_arguments.done\",\"output_index\":0,\"item_id\":\"fc_tmp_hgt0s8hlqsa\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\",\"sequence_number\":8}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"fc_tmp_hgt0s8hlqsa\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_lvGkIhJoXscAOT3UfLkVKowx\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},\"sequence_number\":9}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790785406-ABGEk8CdTXhfL3hEYDWM\",\"object\":\"response\",\"created_at\":1790785406,\"model\":\"openai/gpt-4o-mini\",\"status\":\"completed\",\"completed_at\":1790785407,\"output\":[{\"id\":\"fc_tmp_hgt0s8hlqsa\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_lvGkIhJoXscAOT3UfLkVKowx\",\"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,\"preLine truncated
|
||||
}
|
||||
},
|
||||
{
|
||||
"transport": "http",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https://openrouter.ai/api/v1/responses",
|
||||
"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_hgt0s8hlqsa\",\"call_id\":\"call_lvGkIhJoXscAOT3UfLkVKowx\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},{\"type\":\"function_call_output\",\"call_id\":\"call_lvGkIhJoXscAOT3UfLkVKowx\",\"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-1790785407-jHq6bt1PSx3ET9x6hiWK\",\"object\":\"response\",\"created_at\":1790785407,\"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-1790785407-jHq6bt1PSx3ET9x6hiWK\",\"object\":\"response\",\"created_at\":1790785407,\"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_rrjxmels5k\",\"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_rrjxmels5k\",\"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_rrjxmels5k\",\"content_index\":0,\"delta\":\"Paris\",\"logprobs\":[],\"sequence_number\":4}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_rrjxmels5k\",\"content_index\":0,\"delta\":\" is\",\"logprobs\":[],\"sequence_number\":5}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_rrjxmels5k\",\"content_index\":0,\"delta\":\" sunny\",\"logprobs\":[],\"sequence_number\":6}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_rrjxmels5k\",\"content_index\":0,\"delta\":\".\",\"logprobs\":[],\"sequence_number\":7}\n\ndata: {\"type\":\"response.output_text.done\",\"output_index\":0,\"item_id\":\"msg_tmp_rrjxmels5k\",\"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_rrjxmels5k\",\"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_rrjxmels5k\",\"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-1790785407-jHq6bt1PSx3ET9x6hiWK\",\"object\":\"response\",\"created_at\":1790785407,\"model\":\"openai/gpt-4o-mini\",\"status\":\"completed\",\"completed_at\":1790785408,\"output\":[{\"id\":\"msg_tmp_rrjxmels5k\",\"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\",\"propLine truncated
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+57
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"provider": "openrouter",
|
||||
"route": "openrouter-responses",
|
||||
"transport": "http",
|
||||
"model": "openai/gpt-5.5",
|
||||
"tags": [
|
||||
"prefix:openrouter-responses",
|
||||
"provider:openrouter",
|
||||
"flagship",
|
||||
"tool",
|
||||
"tool-loop",
|
||||
"golden"
|
||||
],
|
||||
"name": "openrouter-responses/openrouter-gpt-5-5-tool-loop",
|
||||
"recordedAt": "2026-09-30T16:23:40.874Z"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"transport": "http",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https://openrouter.ai/api/v1/responses",
|
||||
"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?\"}]}],\"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": ": \n\n: \n\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790785408-P7WTOJJIqq20Fmtefin3\",\"object\":\"response\",\"created_at\":1790785408,\"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-1790785408-P7WTOJJIqq20Fmtefin3\",\"object\":\"response\",\"created_at\":1790785408,\"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_kfmcjqs0pta\",\"type\":\"function_call\",\"status\":\"in_progress\",\"call_id\":\"call_0hH2I7anIhRzJVMaXGgZsSAZ\",\"name\":\"get_weather\",\"arguments\":\"\"},\"sequence_number\":2}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_kfmcjqs0pta\",\"delta\":\"{\\\"\",\"sequence_number\":3}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_kfmcjqs0pta\",\"delta\":\"city\",\"sequence_number\":4}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_kfmcjqs0pta\",\"delta\":\"\\\":\\\"\",\"sequence_number\":5}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_kfmcjqs0pta\",\"delta\":\"Paris\",\"sequence_number\":6}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_kfmcjqs0pta\",\"delta\":\"\\\"}\",\"sequence_number\":7}\n\ndata: {\"type\":\"response.function_call_arguments.done\",\"output_index\":0,\"item_id\":\"fc_tmp_kfmcjqs0pta\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\",\"sequence_number\":8}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"fc_tmp_kfmcjqs0pta\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_0hH2I7anIhRzJVMaXGgZsSAZ\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},\"sequence_number\":9}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790785408-P7WTOJJIqq20Fmtefin3\",\"object\":\"response\",\"created_at\":1790785408,\"model\":\"openai/gpt-5.5\",\"status\":\"completed\",\"completed_at\":1790785419,\"output\":[{\"id\":\"fc_tmp_kfmcjqs0pta\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call_0hH2I7anIhRzJVMaXGgZsSAZ\",\"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,\"preLine truncated
|
||||
}
|
||||
},
|
||||
{
|
||||
"transport": "http",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https://openrouter.ai/api/v1/responses",
|
||||
"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_kfmcjqs0pta\",\"call_id\":\"call_0hH2I7anIhRzJVMaXGgZsSAZ\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},{\"type\":\"function_call_output\",\"call_id\":\"call_0hH2I7anIhRzJVMaXGgZsSAZ\",\"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": ": \n\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790785419-vw658CTigRImCOdrgeoo\",\"object\":\"response\",\"created_at\":1790785419,\"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-1790785419-vw658CTigRImCOdrgeoo\",\"object\":\"response\",\"created_at\":1790785419,\"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_vz5cc3fsxu\",\"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_vz5cc3fsxu\",\"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_vz5cc3fsxu\",\"content_index\":0,\"delta\":\"Paris\",\"logprobs\":[],\"sequence_number\":4}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_vz5cc3fsxu\",\"content_index\":0,\"delta\":\" is\",\"logprobs\":[],\"sequence_number\":5}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_vz5cc3fsxu\",\"content_index\":0,\"delta\":\" sunny\",\"logprobs\":[],\"sequence_number\":6}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_vz5cc3fsxu\",\"content_index\":0,\"delta\":\".\",\"logprobs\":[],\"sequence_number\":7}\n\ndata: {\"type\":\"response.output_text.done\",\"output_index\":0,\"item_id\":\"msg_tmp_vz5cc3fsxu\",\"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_vz5cc3fsxu\",\"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_vz5cc3fsxu\",\"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-1790785419-vw658CTigRImCOdrgeoo\",\"object\":\"response\",\"created_at\":1790785419,\"model\":\"openai/gpt-5.5\",\"status\":\"completed\",\"completed_at\":1790785420,\"output\":[{\"id\":\"msg_tmp_vz5cc3fsxu\",\"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 weatheLine truncated
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+56
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"provider": "openrouter",
|
||||
"route": "openrouter-responses",
|
||||
"transport": "http",
|
||||
"model": "x-ai/grok-4.3",
|
||||
"tags": [
|
||||
"prefix:openrouter-responses",
|
||||
"provider:openrouter",
|
||||
"tool",
|
||||
"tool-loop",
|
||||
"golden"
|
||||
],
|
||||
"name": "openrouter-responses/openrouter-grok-4-3-tool-loop",
|
||||
"recordedAt": "2026-09-30T16:23:43.264Z"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"transport": "http",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https://openrouter.ai/api/v1/responses",
|
||||
"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?\"}]}],\"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": ": \n\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790785420-a3oY2v6sUg0ehNSThKNZ\",\"object\":\"response\",\"created_at\":1790785420,\"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-1790785420-a3oY2v6sUg0ehNSThKNZ\",\"object\":\"response\",\"created_at\":1790785420,\"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_rbl2s0gjqna\",\"type\":\"function_call\",\"status\":\"in_progress\",\"call_id\":\"call-b8fc2f91-196a-424e-806c-809d8210716c-0\",\"name\":\"get_weather\",\"arguments\":\"\"},\"sequence_number\":2}\n\ndata: {\"type\":\"response.function_call_arguments.delta\",\"output_index\":0,\"item_id\":\"fc_tmp_rbl2s0gjqna\",\"delta\":\"{\\\"city\\\":\\\"Paris\\\"}\",\"sequence_number\":3}\n\ndata: {\"type\":\"response.function_call_arguments.done\",\"output_index\":0,\"item_id\":\"fc_tmp_rbl2s0gjqna\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\",\"sequence_number\":4}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"fc_tmp_rbl2s0gjqna\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call-b8fc2f91-196a-424e-806c-809d8210716c-0\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},\"sequence_number\":5}\n\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"gen-1790785420-a3oY2v6sUg0ehNSThKNZ\",\"object\":\"response\",\"created_at\":1790785420,\"model\":\"x-ai/grok-4.3\",\"status\":\"completed\",\"completed_at\":1790785422,\"output\":[{\"id\":\"fc_tmp_rbl2s0gjqna\",\"type\":\"function_call\",\"status\":\"completed\",\"call_id\":\"call-b8fc2f91-196a-424e-806c-809d8210716c-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},\"Line truncated
|
||||
}
|
||||
},
|
||||
{
|
||||
"transport": "http",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https://openrouter.ai/api/v1/responses",
|
||||
"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_rbl2s0gjqna\",\"call_id\":\"call-b8fc2f91-196a-424e-806c-809d8210716c-0\",\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"},{\"type\":\"function_call_output\",\"call_id\":\"call-b8fc2f91-196a-424e-806c-809d8210716c-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": ": \n\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790785422-Zue6MgjVTcuWAjhEmP4R\",\"object\":\"response\",\"created_at\":1790785422,\"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-1790785422-Zue6MgjVTcuWAjhEmP4R\",\"object\":\"response\",\"created_at\":1790785422,\"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_lcfnzrpthhm\",\"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_lcfnzrpthhm\",\"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_lcfnzrpthhm\",\"content_index\":0,\"delta\":\"Paris\",\"logprobs\":[],\"sequence_number\":4}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_lcfnzrpthhm\",\"content_index\":0,\"delta\":\" is\",\"logprobs\":[],\"sequence_number\":5}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_lcfnzrpthhm\",\"content_index\":0,\"delta\":\" sunny\",\"logprobs\":[],\"sequence_number\":6}\n\ndata: {\"type\":\"response.output_text.delta\",\"output_index\":0,\"item_id\":\"msg_tmp_lcfnzrpthhm\",\"content_index\":0,\"delta\":\".\",\"logprobs\":[],\"sequence_number\":7}\n\ndata: {\"type\":\"response.output_text.done\",\"output_index\":0,\"item_id\":\"msg_tmp_lcfnzrpthhm\",\"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_lcfnzrpthhm\",\"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_lcfnzrpthhm\",\"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-1790785422-Zue6MgjVTcuWAjhEmP4R\",\"object\":\"response\",\"created_at\":1790785422,\"model\":\"x-ai/grok-4.3\",\"status\":\"completed\",\"completed_at\":1790785423,\"output\":[{\"id\":\"msg_tmp_lcfnzrpthhm\",\"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,\"paramLine truncated
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+52
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"tags": [
|
||||
"prefix:openrouter-responses",
|
||||
"provider:openrouter",
|
||||
"protocol:openrouter-responses",
|
||||
"reasoning",
|
||||
"tool-loop"
|
||||
],
|
||||
"name": "openrouter-responses/openrouter-muse-spark-1-3-tool-loop",
|
||||
"recordedAt": "2026-09-30T16:23:20.933Z"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"transport": "http",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https://openrouter.ai/api/v1/responses",
|
||||
"headers": {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
"body": "{\"model\":\"meta/muse-spark-1.3\",\"input\":[{\"type\":\"message\",\"role\":\"user\",\"content\":[{\"type\":\"input_text\",\"text\":\"Call only crm.lookup once with query ping. Do not call inventory.lookup. Wait for the result.\"}]}],\"tools\":[{\"type\":\"namespace\",\"name\":\"crm\",\"description\":\"Tools in the crm namespace.\",\"tools\":[{\"type\":\"function\",\"name\":\"lookup\",\"description\":\"Look up a reference value\",\"parameters\":{\"type\":\"object\",\"properties\":{\"query\":{\"type\":\"string\"}},\"required\":[\"query\"]},\"strict\":false}]},{\"type\":\"namespace\",\"name\":\"inventory\",\"description\":\"Tools in the inventory namespace.\",\"tools\":[{\"type\":\"function\",\"name\":\"lookup\",\"description\":\"Look up a reference value\",\"parameters\":{\"type\":\"object\",\"properties\":{\"query\":{\"type\":\"string\"}},\"required\":[\"query\"]},\"strict\":false}]}],\"store\":false,\"include\":[\"reasoning.encrypted_content\"],\"reasoning\":{\"effort\":\"minimal\"},\"max_output_tokens\":1536,\"stream\":true}"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"content-type": "text/event-stream"
|
||||
},
|
||||
"body": ": \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\n: \n\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790785364-VktAhM6ZJXQP6x3mVw7T\",\"object\":\"response\",\"created_at\":1790785364,\"model\":\"meta/muse-spark-1.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"namespace\",\"name\":\"crm\",\"description\":\"Tools in the crm namespace.\",\"tools\":[{\"type\":\"function\",\"name\":\"lookup\",\"description\":\"Look up a reference value\",\"parameters\":{\"type\":\"object\",\"properties\":{\"query\":{\"type\":\"string\"}},\"required\":[\"query\"]},\"strict\":false}]},{\"type\":\"namespace\",\"name\":\"inventory\",\"description\":\"Tools in the inventory namespace.\",\"tools\":[{\"type\":\"function\",\"name\":\"lookup\",\"description\":\"Look up a reference value\",\"parameters\":{\"type\":\"object\",\"properties\":{\"query\":{\"type\":\"string\"}},\"required\":[\"query\"]},\"strict\":false}]}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":1536,\"temperature\":1,\"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\":null,\"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-1790785364-VktAhM6ZJXQP6x3mVw7T\",\"object\":\"response\",\"created_at\":1790785364,\"model\":\"meta/muse-spark-1.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"namespace\",\"name\":\"crm\",\"description\":\"Tools in the crm namespace.\",\"tools\":[{\"type\":\"function\",\"name\":\"lookup\",\"description\":\"Look up a reference value\",\"parameters\":{\"type\":\"object\",\"properties\":{\"query\":{\"type\":\"string\"}},\"required\":[\"query\"]},\"strict\":false}]},{\"type\":\"namespace\",\"name\":\"inventory\",\"description\":\"Tools in the inventory namespace.\",\"tools\":[{\"type\":\"function\",\"name\":\"lookup\",\"description\":\"Look up a reference value\",\"parameters\":{\"type\":\"object\",\"properties\":{\"query\":{\"type\":\"string\"}},\"required\":[\"query\"]},\"strict\":false}]}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":1536,\"temperature\":1,\"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\":null,\"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_6abd3776fff29bd8da44468c:rs_01a0f320a8c9714fa24f527f40c24748\",\"type\":\"reasoning\",\"status\":\"in_progress\",\"summary\":[]},\"sequence_number\":2}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"rs_6abd3776fff29bd8da44468c:rs_01a0f320a8c9714fa24f527f40c24748\",\"type\":\"reasoning\",\"status\":\"completed\",\"summary\":[],\"encrypted_content\":\"Q-PaDgHY_3PI-JeCW7Y8MkHRD9BwIrxUwGzuBlkizQgaR9cB6NITAxPRcBFZxhvP1Acf2GPKrtSVIz4MUZktp1JKC6aGBB8Nsamp6Os43QZAYJ5n8wrSXDEBrKZNK8ldwitW50CF4Hx_GmUt2SHaZOraBaaaAZqa0COdRMJTFV099j3KENOY9TlpOMIEQBBU3If_hwVYQzhHA9kucHpICDohVNl5wdgAT8Z_lvg-cr2jor6NDwEIrdBrQXkNpphfVfP_o4zibO8vmCao5lo5obWxH8pPx8UrZ4qZKSf5sULJWmMpMUEBD7vK_G1b_QeugBCer1S4iBaQo1pUkFVyySNisd-ceytgeEdGT9KsxLYgaOcK9DRCtGJ0fFB2NKIV1LW9nbXlkKQcfDv2agRk__7sWciz-XIGaSMo55kTbASDTIwO9EEKkqFNby0WU5KcZUBAOFncAfDax--ptoqViPW5ReE1xrGPkb0FNmfr7VREcqtzZe5lSAbwx1jK8ojUgk6iJzDVkjRgYLbaFV2avI7pvMF76r4rjgr1jJG71vDtQ8_rKQfiCzaSb5OEJ5IxTobS7HjNAYQkiyrxOm68pbRSZkxn8jUz8unT8UGI3FFAEujpaldteLwta-s2TgI_tCeySlXM9oF1w8GkGSjPzvtrQ6yzYCEiOqWXMrjQxw6TFWtO8oCockU8oz8uFbDcduY8KKEZXgh7iXvohMw4BH58fKEfqmhi6PubDCLgTHu5R-PEvYuVNXduOJfW4XBUJjua-Ux6zIvETdhKgZHmWXg1PjFYfJuEgK800_wkSJYSPkbH01RzPJ4rBRTnS3bJiymA6MjdgMtDk0utCgFr0_Y-vrE1dfDs9nWaFs69cydN06u85VArK6HLdn1uHG69Zt6mVMMEy1m96T1YLl07hq1jePUhe9xOuDnmii6LI1nzaPE-GGenJXGERhX6KnVbTJEgleh5ycLWvQvFXuS9sbK59DdEvdSizGj5taqzQgmPmjWJErJ1GNVTzn8AzX90z6ORTy4MNn0dMu14BDbrbDeBfhoj9pGKUyvsrNeeykpUX2Y6Ms3DWVSj0Z-o59M3_kfzo9GiEq1js0d27pMXC7V-ioLine truncated
|
||||
}
|
||||
},
|
||||
{
|
||||
"transport": "http",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https://openrouter.ai/api/v1/responses",
|
||||
"headers": {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
"body": "{\"model\":\"meta/muse-spark-1.3\",\"input\":[{\"type\":\"message\",\"role\":\"user\",\"content\":[{\"type\":\"input_text\",\"text\":\"Call only crm.lookup once with query ping. Do not call inventory.lookup. Wait for the result.\"}]},{\"type\":\"reasoning\",\"id\":\"rs_6abd3776fff29bd8da44468c:rs_01a0f320a8c9714fa24f527f40c24748\",\"summary\":[],\"encrypted_content\":\"Q-PaDgHY_3PI-JeCW7Y8MkHRD9BwIrxUwGzuBlkizQgaR9cB6NITAxPRcBFZxhvP1Acf2GPKrtSVIz4MUZktp1JKC6aGBB8Nsamp6Os43QZAYJ5n8wrSXDEBrKZNK8ldwitW50CF4Hx_GmUt2SHaZOraBaaaAZqa0COdRMJTFV099j3KENOY9TlpOMIEQBBU3If_hwVYQzhHA9kucHpICDohVNl5wdgAT8Z_lvg-cr2jor6NDwEIrdBrQXkNpphfVfP_o4zibO8vmCao5lo5obWxH8pPx8UrZ4qZKSf5sULJWmMpMUEBD7vK_G1b_QeugBCer1S4iBaQo1pUkFVyySNisd-ceytgeEdGT9KsxLYgaOcK9DRCtGJ0fFB2NKIV1LW9nbXlkKQcfDv2agRk__7sWciz-XIGaSMo55kTbASDTIwO9EEKkqFNby0WU5KcZUBAOFncAfDax--ptoqViPW5ReE1xrGPkb0FNmfr7VREcqtzZe5lSAbwx1jK8ojUgk6iJzDVkjRgYLbaFV2avI7pvMF76r4rjgr1jJG71vDtQ8_rKQfiCzaSb5OEJ5IxTobS7HjNAYQkiyrxOm68pbRSZkxn8jUz8unT8UGI3FFAEujpaldteLwta-s2TgI_tCeySlXM9oF1w8GkGSjPzvtrQ6yzYCEiOqWXMrjQxw6TFWtO8oCockU8oz8uFbDcduY8KKEZXgh7iXvohMw4BH58fKEfqmhi6PubDCLgTHu5R-PEvYuVNXduOJfW4XBUJjua-Ux6zIvETdhKgZHmWXg1PjFYfJuEgK800_wkSJYSPkbH01RzPJ4rBRTnS3bJiymA6MjdgMtDk0utCgFr0_Y-vrE1dfDs9nWaFs69cydN06u85VArK6HLdn1uHG69Zt6mVMMEy1m96T1YLl07hq1jePUhe9xOuDnmii6LI1nzaPE-GGenJXGERhX6KnVbTJEgleh5ycLWvQvFXuS9sbK59DdEvdSizGj5taqzQgmPmjWJErJ1GNVTzn8AzX90z6ORTy4MNn0dMu14BDbrbDeBfhoj9pGKUyvsrNeeykpUX2Y6Ms3DWVSj0Z-o59M3_kfzo9GiEq1js0d27pMXC7V-ioTuX3EOTRGeILgPtp97aQumzy_3cg6i0chgUn5xBVPpp-98EO7xjB_eTBgtTn9Rv1lCJOdsHJwtizNTbXkeijaF06fKfc08kAxdG30o55Mh4-sFGEsK5F8bTZmvaul_QUxbqsioMYzOL2BOkp_THWjNSZ6CO1O3LEjpWvzAA_26W16AApzD-XN6GHCuMZbMf5j7Q1Rm0w3MX4r0Vl7q1yvSkoMXVFoirE15CBfWWI16Wt-ku0-ATe1fsXu0zo3v8tOaBJ5MrgcC_ad9odqlwFbYEeH65mQGKdLz7WRG7BpdV0sW9X8c8RWtDA.eyJlbmRwb2ludF9zbHVnIjoibWV0YS9tdXNlLXNwYXJrLTEuMy0yMDI2MDkwMnxtZXRhIn0\"},{\"type\":\"message\",\"id\":\"msg_tmp_el0yxdghgbv\",\"role\":\"assistant\",\"content\":[{\"type\":\"output_text\",\"text\":\"I'll run that single lookup now.\"}],\"phase\":\"commentary\",\"status\":\"completed\"},{\"type\":\"function_call\",\"id\":\"fc_tmp_lhl1yjbxd7\",\"call_id\":\"call_01a0f320ab507055864d9277288849b3\",\"name\":\"lookup\",\"namespace\":\"crm\",\"arguments\":\"{\\\"query\\\":\\\"ping\\\"}\"},{\"type\":\"function_call_output\",\"call_id\":\"call_01a0f320ab507055864d9277288849b3\",\"output\":\"\\\"pong\\\"\"},{\"type\":\"message\",\"role\":\"user\",\"content\":[{\"type\":\"input_text\",\"text\":\"Do not call tools again. Reply exactly pong.\"}]}],\"tools\":[{\"type\":\"namespace\",\"name\":\"crm\",\"description\":\"Tools in the crm namespace.\",\"tools\":[{\"type\":\"function\",\"name\":\"lookup\",\"description\":\"Look up a reference value\",\"parameters\":{\"type\":\"object\",\"properties\":{\"query\":{\"type\":\"string\"}},\"required\":[\"query\"]},\"strict\":false}]},{\"type\":\"namespace\",\"name\":\"inventory\",\"description\":\"Tools in the inventory namespace.\",\"tools\":[{\"type\":\"function\",\"name\":\"lookup\",\"description\":\"Look up a reference value\",\"parameters\":{\"type\":\"object\",\"properties\":{\"query\":{\"type\":\"string\"}},\"required\":[\"query\"]},\"strict\":false}]}],\"store\":false,\"include\":[\"reasoning.encrypted_content\"],\"reasoning\":{\"effort\":\"minimal\"},\"max_output_tokens\":1536,\"stream\":true}"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"content-type": "text/event-stream"
|
||||
},
|
||||
"body": "data: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790785400-WslI9z4mjOwRslPnpsbE\",\"object\":\"response\",\"created_at\":1790785400,\"model\":\"meta/muse-spark-1.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"namespace\",\"name\":\"crm\",\"description\":\"Tools in the crm namespace.\",\"tools\":[{\"type\":\"function\",\"name\":\"lookup\",\"description\":\"Look up a reference value\",\"parameters\":{\"type\":\"object\",\"properties\":{\"query\":{\"type\":\"string\"}},\"required\":[\"query\"]},\"strict\":false}]},{\"type\":\"namespace\",\"name\":\"inventory\",\"description\":\"Tools in the inventory namespace.\",\"tools\":[{\"type\":\"function\",\"name\":\"lookup\",\"description\":\"Look up a reference value\",\"parameters\":{\"type\":\"object\",\"properties\":{\"query\":{\"type\":\"string\"}},\"required\":[\"query\"]},\"strict\":false}]}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":1536,\"temperature\":1,\"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\":null,\"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-1790785400-WslI9z4mjOwRslPnpsbE\",\"object\":\"response\",\"created_at\":1790785400,\"model\":\"meta/muse-spark-1.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"namespace\",\"name\":\"crm\",\"description\":\"Tools in the crm namespace.\",\"tools\":[{\"type\":\"function\",\"name\":\"lookup\",\"description\":\"Look up a reference value\",\"parameters\":{\"type\":\"object\",\"properties\":{\"query\":{\"type\":\"string\"}},\"required\":[\"query\"]},\"strict\":false}]},{\"type\":\"namespace\",\"name\":\"inventory\",\"description\":\"Tools in the inventory namespace.\",\"tools\":[{\"type\":\"function\",\"name\":\"lookup\",\"description\":\"Look up a reference value\",\"parameters\":{\"type\":\"object\",\"properties\":{\"query\":{\"type\":\"string\"}},\"required\":[\"query\"]},\"strict\":false}]}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":1536,\"temperature\":1,\"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\":null,\"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_6abd37783b11e27402574811:rs_01a0f320af0f77f3ac543044f0ee8973\",\"type\":\"reasoning\",\"status\":\"in_progress\",\"summary\":[]},\"sequence_number\":2}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"rs_6abd37783b11e27402574811:rs_01a0f320af0f77f3ac543044f0ee8973\",\"type\":\"reasoning\",\"status\":\"completed\",\"summary\":[],\"encrypted_content\":\"Q-PaDgHxXN6Xr-m7QIGh92Ruts8MDG5vvrRhPk3-vT8rBvlyo-BV6kYDL0K59-goz0VqH-g4BJgnduTp4BnpRwcDwbNM2HkrcHeDguUx1GmBSNzlO3KPMmfXWBdL3E4Os0f2rLNwfrzsHgozq-nK_yUDVLg1Fzu-uG9M63aL-zU7QenjztdCTc8QkfEiRebRwZqMLqHvc00DYViboCzckusLPWoEiTAUtWEX-5ye80TZ1MJmwUTzokeU24bYa-d9FGgJIs-CFKUvxubYzHJ-re4bDwqDd40i8zgvHtV3J6q1JhmDrcoJyEG2_qUfRNO2u7GLPnjC45cEwfd-lvMOEQ61Iv_bpWpQ72vD12EeWgIQf_DAPBKBLg64Hha6A0CJewsK0eyDRi1VX3DSfpl3Hi2CBBmOptBZhhnzOIrWkSdXcXOywfFdOEDtVD4znM5c3B6UEu5q97wv9rIGo1pEZhJHlH7hs2fe79jFKHHQD4dWariEhiYZV8Fh8lRMBjohN7Up_cPSOLuCky0txrCVxWR0JCCAfsRjlFKCw1uQryck2bBguCViHuj94LqO7ZHAY_eaAeYKFrLCgDY-EM0u7CY9YwabsegY5kHZujlwSg7Vjo8LFcUiLMjx5Vi_UTM-zONMrA0qKAcGfwroTkDyRYln2IYDbgYLeI8KX2KKMndMLg9OEUh5jReTJbuYAOSpTqPWcWKasRN53Y3x5NKtLMe4bHL3fhUaoVU2ccSiSdH4srZ7yFaS959hqdpPdV0o1s1xp5vsQmw8ECyUAeQfQZzliGT_96irxoBIHoPdY4yIky5SggcyJRi5G0RFh2pGRgB74jB0Wr5lPdBwzygZKQbSuVqFAc5bG6MqHzNZMjoD92SDOt5j2jOgb1wDZtsbopzSAhzH9X7QaHae3295J0WeX5I23PEeQJ6m3S7zmhlUaj-wUequMpvICvyvv7SngrUrVCh4fe7fHzFNmXO0t6qOu4jBNJQC_2ibtDJ0L9LcwtZzjnCOXF8M6MLydkL2pdJ9JZ3FSug_HtIc9Ylze8tCCdXp7BbjeCX1wHoNYrjCM6WtWbkchwVT12NITZ6eG2etBqnDcNaPdzEkPs3c3r0iMK-S0BvFNADFFmVqU9dBLqcwNs27SX-WaeXya-2DBMc3P_NWXPRXBaO0QEwcKSBIF05zLtxw9nycnfsFx0OJk67W91VeDBFcj-93pkkQGDut_vivpqV6IRImxtDl6sH_75h2-lhxJPj5DLwhr5nmKbO9npGGYP04FPT_IftnmrBwUUM4YLJqG4YYCttCOc97BxNuiPS-SDwAaNkm2Dh30EVIL-D4okZmhJ6ZxHC5guYODGDvKbgpZIxFFbZTOI1WxIzz348QD_VC2NLOVvyZpnsnsAamH2Jk7twFnO48uA6ary8itqjbfoO_Fw.eyJlbmRwb2ludF9zbHVnIjoibWV0YS9tdXNLine truncated
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
packages/ai/test/fixtures/recordings/openrouter-responses/preserves-native-hosted-search-events.json
Vendored
+32
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"tags": [
|
||||
"prefix:openrouter-responses",
|
||||
"provider:openrouter",
|
||||
"protocol:openrouter-responses"
|
||||
],
|
||||
"name": "openrouter-responses/preserves-native-hosted-search-events",
|
||||
"recordedAt": "2026-09-30T16:23:24.820Z"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"transport": "http",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "https://openrouter.ai/api/v1/responses",
|
||||
"headers": {
|
||||
"content-type": "application/json"
|
||||
},
|
||||
"body": "{\"model\":\"x-ai/grok-4.3\",\"input\":[{\"type\":\"message\",\"role\":\"user\",\"content\":[{\"type\":\"input_text\",\"text\":\"Use web search once to find the official OpenRouter Responses API documentation. Reply with its URL.\"}]}],\"store\":false,\"include\":[\"reasoning.encrypted_content\"],\"reasoning\":{\"effort\":\"low\"},\"max_output_tokens\":1536,\"stream\":true,\"tools\":[{\"type\":\"web_search_preview\",\"engine\":\"native\",\"max_uses\":1}],\"max_tool_calls\":1}"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"headers": {
|
||||
"content-type": "text/event-stream"
|
||||
},
|
||||
"body": ": \n\n: \n\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"gen-1790785401-4rHQLRdt9DarcnvBnIFk\",\"object\":\"response\",\"created_at\":1790785401,\"model\":\"x-ai/grok-4.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"web_search_preview\",\"engine\":\"native\",\"max_uses\":1}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":1536,\"temperature\":1,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":1,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":null,\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"low\"},\"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-1790785401-4rHQLRdt9DarcnvBnIFk\",\"object\":\"response\",\"created_at\":1790785401,\"model\":\"x-ai/grok-4.3\",\"status\":\"in_progress\",\"completed_at\":null,\"output\":[],\"error\":null,\"incomplete_details\":null,\"tools\":[{\"type\":\"web_search_preview\",\"engine\":\"native\",\"max_uses\":1}],\"tool_choice\":\"auto\",\"parallel_tool_calls\":true,\"max_output_tokens\":1536,\"temperature\":1,\"top_p\":1,\"presence_penalty\":0,\"frequency_penalty\":0,\"top_logprobs\":0,\"max_tool_calls\":1,\"metadata\":{},\"background\":false,\"previous_response_id\":null,\"service_tier\":\"auto\",\"truncation\":\"disabled\",\"store\":false,\"instructions\":null,\"text\":{\"format\":{\"type\":\"text\"}},\"reasoning\":{\"effort\":\"low\"},\"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_7bc4fd07-6624-997e-b8de-0b3aaa3e5931\",\"type\":\"reasoning\",\"status\":\"in_progress\",\"summary\":[]},\"sequence_number\":2}\n\ndata: {\"type\":\"response.reasoning_summary_part.added\",\"output_index\":0,\"item_id\":\"rs_7bc4fd07-6624-997e-b8de-0b3aaa3e5931\",\"summary_index\":0,\"part\":{\"type\":\"summary_text\",\"text\":\"\"},\"sequence_number\":3}\n\ndata: {\"type\":\"response.reasoning_summary_text.delta\",\"output_index\":0,\"item_id\":\"rs_7bc4fd07-6624-997e-b8de-0b3aaa3e5931\",\"summary_index\":0,\"delta\":\"I will search for the official OpenRouter Responses API documentation.\",\"sequence_number\":4}\n\ndata: {\"type\":\"response.reasoning_summary_text.done\",\"output_index\":0,\"item_id\":\"rs_7bc4fd07-6624-997e-b8de-0b3aaa3e5931\",\"summary_index\":0,\"text\":\"I will search for the official OpenRouter Responses API documentation.\",\"sequence_number\":5}\n\ndata: {\"type\":\"response.reasoning_summary_part.done\",\"output_index\":0,\"item_id\":\"rs_7bc4fd07-6624-997e-b8de-0b3aaa3e5931\",\"summary_index\":0,\"part\":{\"type\":\"summary_text\",\"text\":\"I will search for the official OpenRouter Responses API documentation.\"},\"sequence_number\":6}\n\ndata: {\"type\":\"response.output_item.done\",\"output_index\":0,\"item\":{\"id\":\"rs_7bc4fd07-6624-997e-b8de-0b3aaa3e5931\",\"type\":\"reasoning\",\"status\":\"completed\",\"summary\":[{\"type\":\"summary_text\",\"text\":\"I will search for the official OpenRouter Responses API documentation.\"}],\"encrypted_content\":\"tNPIeYfeRXKbTG9pT7+LPJGI4uZb0hqxDQJ68MySq6Un6zHCEQS5RxmS4rY5CusaE5QiFqfGp8YaDoNpXUlljzMpFNMAuknqGXNSsdW3TiO0qHq/+0Z7ZZEa7ePmb7LeDVirxysjWWsFKN6iI+M/wQCGD5jW9ZlZnfmt17/p/VIUNSf3V4xevGDA055pTneBkiGOsl2YM/Pskkrj2dyWDHfzpidNGDYMnaxdiAwWn+IwyIxvPqwKfitdrbfhZjxT3QLPjHDRzY8ATOAj5M+KCicnKFjmUtXGk2G/38U2pXAlL9m0KEM5wxOP0+86n0Nnab6PNyvdZc+UBz+SnRO6Z4PPQvSO62oL/oVqUJ4FwK8fCA+8H+ECXY0yvXHyPaUiMYJBxh1ciaPouaK4l4K85wGXcCB36RXw3bv4De8EN+zrP/J/KwSdVh4W0z7HZwPsPWikuHGUEkl5vG+ontofnBmE+2rA64pXL5JJ8jvnjEffeGUBbovkNpavNkTHW3BCA0xnxAJMNtlWvQ4hVZwE5iEoIf6W8qVV.eyJlbmRwb2ludF9zbHVnIjoieC1haS9ncm9rLTQuMy0yMDI2MDQzMHx4YWkifQ\",\"format\":\"xai-responses-v1\"},\"sequence_number\":9}\n\ndata: {\"type\":\"response.output_item.added\",\"output_index\":1,\"item\":{\"id\":\"ws_7bc4fd07-6624-997e-b8de-0b3aaa3e5931_call-7cfcb560-a663-4788-a631-7274e773df1d-0\",\"type\":\"web_search_call\",\"status\":\"in_progress\",\"action\":{\"type\":\"search\",\"query\":\"\"}},\"sequence_number\":7}\n\ndata: {\"type\":\"response.web_search_call.in_progress\",\"output_index\":1,\"item_id\":\"ws_7bc4fd07-6624-997e-b8de-0b3aaa3e5931_call-7cfcb560-a663-4788-a631-7274e773df1d-0\",\"sequence_number\":8}\n\ndata: {\"type\":\"response.web_search_call.searching\",\"output_index\":1,\"item_id\":\"ws_7bc4fd07-6624-997e-b8de-0b3aaa3e5931_call-7cfcb560-a663-4788-a631-7274e773df1d-0\",\"sequence_number\":10}\n\ndata: {\"type\":\"response.web_search_call.completed\",\"output_index\":1,\"item_id\":\"ws_7bc4fd07-6624-997e-b8de-0b3aaa3e5931_call-7cfcb560-a663Line truncated
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -263,14 +263,14 @@ describeRecordedGoldenScenarios([
|
||||
},
|
||||
{
|
||||
name: "OpenRouter gpt-4o-mini",
|
||||
prefix: "openai-compatible-chat",
|
||||
prefix: "openrouter-responses",
|
||||
model: openrouter,
|
||||
requires: ["OPENROUTER_API_KEY"],
|
||||
scenarios: ["text", "tool-call", "tool-loop"],
|
||||
},
|
||||
{
|
||||
name: "OpenRouter gpt-5.5",
|
||||
prefix: "openai-compatible-chat",
|
||||
prefix: "openrouter-responses",
|
||||
model: openrouterGpt55,
|
||||
requires: ["OPENROUTER_API_KEY"],
|
||||
tags: ["flagship"],
|
||||
@@ -278,10 +278,20 @@ describeRecordedGoldenScenarios([
|
||||
},
|
||||
{
|
||||
name: "OpenRouter Claude Opus 4.7",
|
||||
prefix: "openai-compatible-chat",
|
||||
prefix: "openrouter-messages",
|
||||
model: openrouterOpus,
|
||||
requires: ["OPENROUTER_API_KEY"],
|
||||
tags: ["flagship"],
|
||||
scenarios: ["tool-loop"],
|
||||
},
|
||||
{
|
||||
name: "OpenRouter Grok 4.3",
|
||||
prefix: "openrouter-responses",
|
||||
model: OpenRouter.configure({
|
||||
apiKey: process.env.OPENROUTER_API_KEY ?? "fixture",
|
||||
providerOptions: { reasoning: { effort: "none" } },
|
||||
}).model("x-ai/grok-4.3"),
|
||||
requires: ["OPENROUTER_API_KEY"],
|
||||
scenarios: ["tool-loop"],
|
||||
},
|
||||
])
|
||||
@@ -16,7 +16,7 @@ const cases = [
|
||||
OpenRouter.configure({
|
||||
apiKey: process.env.OPENROUTER_API_KEY ?? "fixture",
|
||||
providerOptions: { reasoning: { max_tokens: 1024 } },
|
||||
}).model("anthropic/claude-sonnet-4.6"),
|
||||
}).chat("anthropic/claude-sonnet-4.6"),
|
||||
{ compatibility: { reasoningField: "reasoning" } },
|
||||
),
|
||||
requires: ["OPENROUTER_API_KEY"],
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import { expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { LLM, LLMRequest, Message } from "../../src/index.js"
|
||||
import { OpenRouter } from "../../src/providers/openrouter.js"
|
||||
import { LLMClient } from "../../src/route.js"
|
||||
import { recordedTests } from "../recorded-test.js"
|
||||
|
||||
const recorded = recordedTests({
|
||||
prefix: "openrouter-responses",
|
||||
provider: "openrouter",
|
||||
protocol: "openrouter-responses",
|
||||
requires: ["OPENROUTER_API_KEY"],
|
||||
})
|
||||
|
||||
recorded.effect.with(
|
||||
"continues Meta reasoning through a namespaced tool loop",
|
||||
{ cassette: "openrouter-responses/openrouter-muse-spark-1-3-tool-loop", tags: ["reasoning", "tool-loop"] },
|
||||
() =>
|
||||
Effect.gen(function* () {
|
||||
const tool = {
|
||||
name: "lookup",
|
||||
description: "Look up a reference value",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: { query: { type: "string" } },
|
||||
required: ["query"],
|
||||
},
|
||||
}
|
||||
const request = LLM.request({
|
||||
model: OpenRouter.configure({
|
||||
apiKey: process.env.OPENROUTER_API_KEY ?? "fixture",
|
||||
providerOptions: { reasoning: { effort: "minimal" } },
|
||||
}).model("meta/muse-spark-1.3"),
|
||||
prompt: "Call only crm.lookup once with query ping. Do not call inventory.lookup. Wait for the result.",
|
||||
tools: ["crm", "inventory"].map((name) => ({ type: "namespace", name, tools: [tool] })),
|
||||
generation: { maxTokens: 1536 },
|
||||
})
|
||||
const first = yield* LLMClient.generate(request)
|
||||
expect(first.toolCalls).toMatchObject([{ name: "lookup", namespace: "crm", input: { query: "ping" } }])
|
||||
const call = first.toolCalls[0]
|
||||
if (!call) throw new Error("Expected a namespaced tool call")
|
||||
const second = yield* LLMClient.generate(
|
||||
LLMRequest.update(request, {
|
||||
messages: [
|
||||
...request.messages,
|
||||
first.message,
|
||||
Message.tool({ id: call.id, name: call.name, namespace: call.namespace, result: "pong" }),
|
||||
Message.user("Do not call tools again. Reply exactly pong."),
|
||||
],
|
||||
}),
|
||||
)
|
||||
|
||||
expect(second.toolCalls).toHaveLength(0)
|
||||
expect(second.text.trim()).toBe("pong")
|
||||
}),
|
||||
60_000,
|
||||
)
|
||||
|
||||
recorded.effect(
|
||||
"preserves native hosted-search events",
|
||||
() =>
|
||||
Effect.gen(function* () {
|
||||
const response = yield* LLMClient.generate(
|
||||
LLM.request({
|
||||
model: OpenRouter.configure({
|
||||
apiKey: process.env.OPENROUTER_API_KEY ?? "fixture",
|
||||
providerOptions: { reasoning: { effort: "low" } },
|
||||
}).model("x-ai/grok-4.3"),
|
||||
prompt:
|
||||
"Use web search once to find the official OpenRouter Responses API documentation. Reply with its URL.",
|
||||
generation: { maxTokens: 1536 },
|
||||
http: { body: { tools: [{ type: "web_search_preview", engine: "native", max_uses: 1 }], max_tool_calls: 1 } },
|
||||
}),
|
||||
)
|
||||
|
||||
expect(response.toolCalls).toContainEqual(expect.objectContaining({ name: "web_search", providerExecuted: true }))
|
||||
expect(response.message.content).toContainEqual(
|
||||
expect.objectContaining({ type: "tool-result", name: "web_search", providerExecuted: true }),
|
||||
)
|
||||
expect(response.text.trim().length).toBeGreaterThan(0)
|
||||
}),
|
||||
60_000,
|
||||
)
|
||||
@@ -3,32 +3,79 @@ import { Effect } from "effect"
|
||||
import { CacheHint, LLM, Message } from "../../src/index.js"
|
||||
import { LLMClient } from "../../src/route.js"
|
||||
import { compileRequest } from "../../src/route/client.js"
|
||||
import * as OpenRouter from "../../src/providers/openrouter.js"
|
||||
import { OpenRouter } from "../../src/providers/openrouter.js"
|
||||
import { it } from "../lib/effect.js"
|
||||
import { fixedResponse } from "../lib/http.js"
|
||||
import { sseEvents } from "../lib/sse.js"
|
||||
|
||||
describe("OpenRouter", () => {
|
||||
it.effect("prepares OpenRouter models through the OpenAI-compatible Chat route", () =>
|
||||
it.effect("routes OpenAI, xAI, and Meta models through the same namespace-aware 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, summary: "detailed" },
|
||||
text: { verbosity: "low", format: { type: "json_schema", name: "result", schema: { type: "object" } } },
|
||||
provider: { allow_fallbacks: false },
|
||||
},
|
||||
}).model(id)
|
||||
const prepared = yield* compileRequest(
|
||||
LLM.request({
|
||||
model,
|
||||
prompt: "Say hello.",
|
||||
tools: [
|
||||
{
|
||||
type: "namespace",
|
||||
name: "crm",
|
||||
tools: [
|
||||
{
|
||||
type: "namespace",
|
||||
name: "contacts",
|
||||
tools: [
|
||||
{
|
||||
name: "lookup",
|
||||
description: "Look up a contact",
|
||||
inputSchema: { type: "object", properties: {} },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}),
|
||||
)
|
||||
|
||||
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, summary: "detailed" },
|
||||
text: { verbosity: "low", format: { type: "json_schema", name: "result", schema: { type: "object" } } },
|
||||
tools: [{ type: "namespace", name: "crm", tools: [{ type: "function", name: "contacts_lookup" }] }],
|
||||
provider: { allow_fallbacks: false },
|
||||
})
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
||||
it.effect("exposes exactly three API routes and leaves other families on Chat", () =>
|
||||
Effect.gen(function* () {
|
||||
const model = OpenRouter.configure({ apiKey: "test-key" }).model("openai/gpt-4o-mini")
|
||||
|
||||
expect(model).toMatchObject({
|
||||
id: "openai/gpt-4o-mini",
|
||||
provider: "openrouter",
|
||||
route: { id: "openrouter" },
|
||||
})
|
||||
expect(model.route.endpoint.baseURL).toBe("https://openrouter.ai/api/v1")
|
||||
|
||||
const prepared = yield* compileRequest(LLM.request({ model, prompt: "Say hello." }))
|
||||
|
||||
expect(prepared.route).toBe("openrouter")
|
||||
expect(prepared.body).toMatchObject({
|
||||
model: "openai/gpt-4o-mini",
|
||||
messages: [{ role: "user", content: "Say hello." }],
|
||||
stream: true,
|
||||
usage: { include: true },
|
||||
})
|
||||
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")
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -51,23 +98,148 @@ describe("OpenRouter", () => {
|
||||
)
|
||||
|
||||
expect(prepared.body.tools?.map((tool) => tool.cache_control)).toEqual([undefined, { type: "ephemeral" }])
|
||||
expect(prepared.route).toBe("openrouter-messages")
|
||||
expect(prepared.body.system).toMatchObject([
|
||||
{ text: "Base agent", cache_control: { type: "ephemeral" } },
|
||||
{ text: "Model details" },
|
||||
{ text: "Project instructions", cache_control: { type: "ephemeral" } },
|
||||
])
|
||||
expect(prepared.body.messages).toMatchObject([
|
||||
{
|
||||
role: "system",
|
||||
content: [
|
||||
{ text: "Base agent", cache_control: { type: "ephemeral" } },
|
||||
{ text: "Model details" },
|
||||
{ text: "Project instructions", cache_control: { type: "ephemeral" } },
|
||||
],
|
||||
},
|
||||
{ role: "user", content: [{ text: "Hello", cache_control: { type: "ephemeral" } }] },
|
||||
])
|
||||
expect(prepared.body.messages[0]?.content).not.toContainEqual(
|
||||
expect(prepared.body.system).not.toContainEqual(
|
||||
expect.objectContaining({ text: "Model details", cache_control: expect.anything() }),
|
||||
)
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("preserves gateway routing and lowers native effort updates without changing the baseline", () =>
|
||||
Effect.gen(function* () {
|
||||
const openrouter = OpenRouter.configure({
|
||||
apiKey: "test-key",
|
||||
providerOptions: { provider: { allow_fallbacks: false }, reasoning: { effort: "low", summary: "detailed" } },
|
||||
})
|
||||
const messages = [Message.effort({ previous: "high", effort: "low" }), Message.user("Hello")]
|
||||
const response = yield* compileRequest(LLM.request({ model: openrouter.model("openai/gpt-6.1-sol"), messages }))
|
||||
const message = yield* compileRequest(
|
||||
LLM.request({ model: openrouter.model("anthropic/claude-fable-5.1"), messages }),
|
||||
)
|
||||
|
||||
expect(response.body).toMatchObject({
|
||||
provider: { allow_fallbacks: false },
|
||||
reasoning: { effort: "high", summary: "detailed" },
|
||||
input: [{ type: "configuration_update", reasoning: { effort: "low" } }, { role: "user" }],
|
||||
})
|
||||
expect(message.body).toMatchObject({
|
||||
provider: { allow_fallbacks: false },
|
||||
output_config: { effort: "high" },
|
||||
thinking: { type: "adaptive", block_binding: { prefix_mismatch_behavior: "drop_block" } },
|
||||
messages: [{ role: "system", content: [], output_config: { effort: "low" } }, { role: "user" }],
|
||||
})
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("inherits OpenAI effort support and applies the gateway's truncation restriction", () =>
|
||||
Effect.forEach(
|
||||
[
|
||||
{ id: "~openai/gpt-6.1-sol", supported: true },
|
||||
{ id: "x-ai/grok-4.3", supported: false },
|
||||
{ id: "meta/muse-spark-1.3", supported: false },
|
||||
{ id: "openai/gpt-6-luna", supported: false, providerOptions: { reasoning: { mode: "pro" } } },
|
||||
{ id: "openai/gpt-6-luna", supported: false, http: { body: { reasoning: { mode: "pro" } } } },
|
||||
{ id: "openai/gpt-6-luna", supported: false, providerOptions: { contextManagement: [{ type: "compaction" }] } },
|
||||
{ id: "openai/gpt-6-luna", supported: false, providerOptions: { truncation: "auto" } },
|
||||
{ id: "openai/gpt-6-luna", supported: false, http: { body: { truncation: "auto" } } },
|
||||
],
|
||||
(input) =>
|
||||
Effect.gen(function* () {
|
||||
const prepared = yield* compileRequest(
|
||||
LLM.request({
|
||||
model: OpenRouter.configure({
|
||||
apiKey: "test-key",
|
||||
providerOptions: { reasoning: { effort: "low" } },
|
||||
}).responses(input.id),
|
||||
messages: [
|
||||
Message.user("Before"),
|
||||
Message.effort({ previous: "high", effort: "low" }),
|
||||
Message.user("After"),
|
||||
],
|
||||
providerOptions: input.providerOptions,
|
||||
http: input.http,
|
||||
}),
|
||||
)
|
||||
|
||||
expect(
|
||||
prepared.body.input.filter((item) => "type" in item && item.type === "configuration_update"),
|
||||
).toHaveLength(input.supported ? 1 : 0)
|
||||
expect(prepared.body.reasoning?.effort).toBe(input.supported ? "high" : "low")
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
||||
it.effect("does not restore the current effort over a model-default history baseline", () =>
|
||||
Effect.gen(function* () {
|
||||
const prepared = yield* compileRequest(
|
||||
LLM.request({
|
||||
model: OpenRouter.configure({
|
||||
apiKey: "test-key",
|
||||
providerOptions: { reasoning: { effort: "low", exclude: true } },
|
||||
}).responses("openai/gpt-6-luna"),
|
||||
messages: [Message.user("Before"), Message.effort({ effort: "low" }), Message.user("After")],
|
||||
}),
|
||||
)
|
||||
|
||||
expect(prepared.body.reasoning?.effort).toBeUndefined()
|
||||
expect(prepared.body.reasoning?.exclude).toBe(true)
|
||||
expect(prepared.body.input).toContainEqual({ type: "configuration_update", reasoning: { effort: "low" } })
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("replays saved Chat reasoning details through the native APIs", () =>
|
||||
Effect.gen(function* () {
|
||||
const openrouter = OpenRouter.configure({ apiKey: "test-key" })
|
||||
const message = yield* compileRequest(
|
||||
LLM.request({
|
||||
model: openrouter.model("anthropic/claude-sonnet-4.6"),
|
||||
messages: [
|
||||
Message.assistant({
|
||||
type: "reasoning",
|
||||
text: "AB",
|
||||
providerMetadata: {
|
||||
openrouter: {
|
||||
reasoningDetails: [
|
||||
{ type: "reasoning.text", text: "A", signature: "first" },
|
||||
{ type: "reasoning.text", text: "B", signature: "second" },
|
||||
{ type: "reasoning.encrypted", data: "redacted" },
|
||||
],
|
||||
},
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
)
|
||||
const response = yield* compileRequest(
|
||||
LLM.request({
|
||||
model: openrouter.model("meta/muse-spark-1.3"),
|
||||
messages: [
|
||||
Message.assistant({
|
||||
type: "reasoning",
|
||||
text: "Summary",
|
||||
providerMetadata: { openrouter: { reasoningDetails: [{ type: "reasoning.encrypted", data: "opaque" }] } },
|
||||
}),
|
||||
],
|
||||
}),
|
||||
)
|
||||
|
||||
expect(message.body.messages[0]?.content).toMatchObject([
|
||||
{ type: "thinking", thinking: "A", signature: "first" },
|
||||
{ type: "thinking", thinking: "B", signature: "second" },
|
||||
{ type: "redacted_thinking", data: "redacted" },
|
||||
])
|
||||
expect(response.body.input[0]).toMatchObject({ type: "reasoning", encrypted_content: "opaque" })
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("places default cache breakpoints on OpenRouter latest-model aliases", () =>
|
||||
Effect.gen(function* () {
|
||||
const prepared = yield* compileRequest(
|
||||
@@ -80,8 +252,8 @@ describe("OpenRouter", () => {
|
||||
)
|
||||
|
||||
expect(prepared.body.tools?.[0]?.cache_control).toEqual({ type: "ephemeral" })
|
||||
expect(prepared.body.system).toMatchObject([{ text: "Base agent", cache_control: { type: "ephemeral" } }])
|
||||
expect(prepared.body.messages).toMatchObject([
|
||||
{ role: "system", content: [{ text: "Base agent", cache_control: { type: "ephemeral" } }] },
|
||||
{ role: "user", content: [{ text: "Hello", cache_control: { type: "ephemeral" } }] },
|
||||
])
|
||||
}),
|
||||
@@ -143,10 +315,7 @@ describe("OpenRouter", () => {
|
||||
|
||||
bodies.forEach((body) => {
|
||||
expect(body.tools?.[0]?.cache_control).toBeUndefined()
|
||||
expect(body.messages).toMatchObject([
|
||||
{ role: "system", content: "Base agent" },
|
||||
{ role: "user", content: "Hello" },
|
||||
])
|
||||
expect(JSON.stringify(body)).not.toContain("cache_control")
|
||||
})
|
||||
}),
|
||||
)
|
||||
@@ -168,14 +337,11 @@ describe("OpenRouter", () => {
|
||||
|
||||
expect(prepared.body).toMatchObject({
|
||||
tools: [{ cache_control: { type: "ephemeral" } }],
|
||||
system: [
|
||||
{ text: "Base agent", cache_control: { type: "ephemeral", ttl: "1h" } },
|
||||
{ text: "Project instructions", cache_control: { type: "ephemeral" } },
|
||||
],
|
||||
messages: [
|
||||
{
|
||||
role: "system",
|
||||
content: [
|
||||
{ text: "Base agent", cache_control: { type: "ephemeral", ttl: "1h" } },
|
||||
{ text: "Project instructions", cache_control: { type: "ephemeral" } },
|
||||
],
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
content: [{ text: "Hello", cache_control: { type: "ephemeral" } }],
|
||||
@@ -189,7 +355,7 @@ describe("OpenRouter", () => {
|
||||
Effect.gen(function* () {
|
||||
const prepared = yield* compileRequest(
|
||||
LLM.request({
|
||||
model: OpenRouter.configure({ apiKey: "test-key" }).model("anthropic/claude-sonnet-4.6"),
|
||||
model: OpenRouter.configure({ apiKey: "test-key" }).chat("anthropic/claude-sonnet-4.6"),
|
||||
cache: "none",
|
||||
messages: [
|
||||
Message.user("Call the tool"),
|
||||
@@ -238,13 +404,7 @@ describe("OpenRouter", () => {
|
||||
}),
|
||||
)
|
||||
|
||||
const system = prepared.body.messages[0]
|
||||
expect(system?.role).toBe("system")
|
||||
expect(
|
||||
system && Array.isArray(system.content)
|
||||
? system.content.filter((part) => "cache_control" in part && part.cache_control !== undefined)
|
||||
: [],
|
||||
).toHaveLength(4)
|
||||
expect(prepared.body.system?.filter((part) => part.cache_control !== undefined)).toHaveLength(4)
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -252,7 +412,7 @@ describe("OpenRouter", () => {
|
||||
Effect.gen(function* () {
|
||||
const prepared = yield* compileRequest(
|
||||
LLM.request({
|
||||
model: OpenRouter.configure({ apiKey: "test-key" }).model("anthropic/claude-sonnet-4.6"),
|
||||
model: OpenRouter.configure({ apiKey: "test-key" }).chat("anthropic/claude-sonnet-4.6"),
|
||||
cache: { messages: "latest-assistant" },
|
||||
messages: [Message.user("Think"), Message.assistant([{ type: "reasoning", text: "Reasoning" }])],
|
||||
}),
|
||||
@@ -270,7 +430,7 @@ describe("OpenRouter", () => {
|
||||
Effect.gen(function* () {
|
||||
const prepared = yield* compileRequest(
|
||||
LLM.request({
|
||||
model: OpenRouter.configure({ apiKey: "test-key" }).model("anthropic/claude-sonnet-4.6"),
|
||||
model: OpenRouter.configure({ apiKey: "test-key" }).chat("anthropic/claude-sonnet-4.6"),
|
||||
system: [
|
||||
{ type: "text", text: "Base agent" },
|
||||
{ type: "text", text: "Project instructions" },
|
||||
@@ -302,7 +462,7 @@ describe("OpenRouter", () => {
|
||||
model: OpenRouter.configure({
|
||||
apiKey: "test-key",
|
||||
providerOptions: { usage: false },
|
||||
}).model("openai/gpt-4o-mini"),
|
||||
}).chat("openai/gpt-4o-mini"),
|
||||
cache: "none",
|
||||
prompt: "Hello",
|
||||
}),
|
||||
@@ -350,7 +510,7 @@ describe("OpenRouter", () => {
|
||||
user: "user_123",
|
||||
future_option: { enabled: true },
|
||||
},
|
||||
}).model("anthropic/claude-3.7-sonnet:thinking"),
|
||||
}).chat("anthropic/claude-3.7-sonnet:thinking"),
|
||||
prompt: "Think briefly.",
|
||||
promptCacheKey: "session_123",
|
||||
}),
|
||||
@@ -425,7 +585,7 @@ describe("OpenRouter", () => {
|
||||
|
||||
it.effect("preserves the upstream provider finish reason", () =>
|
||||
Effect.gen(function* () {
|
||||
const model = OpenRouter.configure({ apiKey: "test-key" }).model("anthropic/claude-sonnet-4.6")
|
||||
const model = OpenRouter.configure({ apiKey: "test-key" }).chat("anthropic/claude-sonnet-4.6")
|
||||
const response = yield* LLMClient.generate(LLM.request({ model, prompt: "Say hello." })).pipe(
|
||||
Effect.provide(
|
||||
fixedResponse(
|
||||
@@ -442,7 +602,7 @@ describe("OpenRouter", () => {
|
||||
|
||||
it.effect("fails on a mid-stream provider error", () =>
|
||||
Effect.gen(function* () {
|
||||
const model = OpenRouter.configure({ apiKey: "test-key" }).model("openai/gpt-4o-mini")
|
||||
const model = OpenRouter.configure({ apiKey: "test-key" }).chat("openai/gpt-4o-mini")
|
||||
const error = yield* LLMClient.generate(LLM.request({ model, prompt: "Say hello." })).pipe(
|
||||
Effect.provide(
|
||||
fixedResponse(
|
||||
@@ -469,7 +629,7 @@ describe("OpenRouter", () => {
|
||||
]
|
||||
const prepared = yield* compileRequest(
|
||||
LLM.request({
|
||||
model: OpenRouter.configure({ apiKey: "test-key" }).model("anthropic/claude-sonnet-4.6"),
|
||||
model: OpenRouter.configure({ apiKey: "test-key" }).chat("anthropic/claude-sonnet-4.6"),
|
||||
cache: "none",
|
||||
messages: [
|
||||
Message.assistant([
|
||||
@@ -504,7 +664,7 @@ describe("OpenRouter", () => {
|
||||
]
|
||||
const prepared = yield* compileRequest(
|
||||
LLM.request({
|
||||
model: OpenRouter.configure({ apiKey: "test-key" }).model("anthropic/claude-sonnet-4.6"),
|
||||
model: OpenRouter.configure({ apiKey: "test-key" }).chat("anthropic/claude-sonnet-4.6"),
|
||||
cache: "none",
|
||||
messages: [
|
||||
Message.assistant({
|
||||
@@ -545,7 +705,7 @@ describe("OpenRouter", () => {
|
||||
]
|
||||
const prepared = yield* compileRequest(
|
||||
LLM.request({
|
||||
model: OpenRouter.configure({ apiKey: "test-key" }).model("anthropic/claude-sonnet-4.6"),
|
||||
model: OpenRouter.configure({ apiKey: "test-key" }).chat("anthropic/claude-sonnet-4.6"),
|
||||
cache: "none",
|
||||
messages: [
|
||||
Message.assistant({
|
||||
@@ -574,7 +734,7 @@ describe("OpenRouter", () => {
|
||||
Effect.gen(function* () {
|
||||
const prepared = yield* compileRequest(
|
||||
LLM.request({
|
||||
model: OpenRouter.configure({ apiKey: "test-key" }).model("anthropic/claude-sonnet-4.6"),
|
||||
model: OpenRouter.configure({ apiKey: "test-key" }).chat("anthropic/claude-sonnet-4.6"),
|
||||
cache: "none",
|
||||
messages: [Message.assistant({ type: "reasoning", text: "Thinking" })],
|
||||
}),
|
||||
|
||||
Reference in new issue
Block a user