This commit is contained in:
Aiden Cline
2026-01-16 19:17:54 -06:00
parent 578239e0d0
commit 8a3bc89b3e
5 changed files with 44 additions and 26 deletions

1
ai Submodule

Submodule ai added at 6414c01078

1
codex Submodule

Submodule codex added at c26fe64539

View File

@@ -1006,6 +1006,26 @@ export namespace Provider {
})
}
// Wrap fetch for @ai-sdk/openai to strip "id" from reasoning blocks
// Strip openai itemId metadata following what codex does
if (model.api.npm === "@ai-sdk/openai") {
const wrappedFetch = options["fetch"]
options["fetch"] = async (url: any, init?: BunFetchRequestInit) => {
if (init?.body && init.method === "POST") {
const body = JSON.parse(init.body as string)
if (Array.isArray(body.input)) {
for (const item of body.input) {
if (item.type === "reasoning" && "id" in item) {
delete item.id
}
}
}
init = { ...init, body: JSON.stringify(body) }
}
return wrappedFetch(url, init)
}
}
// Special case: google-vertex-anthropic uses a subpath import
const bundledKey =
model.providerID === "google-vertex-anthropic" ? "@ai-sdk/google-vertex/anthropic" : model.api.npm

View File

@@ -21,28 +21,27 @@ export namespace ProviderTransform {
model: Provider.Model,
options: Record<string, unknown>,
): ModelMessage[] {
// Strip openai itemId metadata following what codex does
if (model.api.npm === "@ai-sdk/openai" || options.store === false) {
msgs = msgs.map((msg) => {
if (msg.providerOptions) {
for (const options of Object.values(msg.providerOptions)) {
delete options["itemId"]
}
}
if (!Array.isArray(msg.content)) {
return msg
}
const content = msg.content.map((part) => {
if (part.providerOptions) {
for (const options of Object.values(part.providerOptions)) {
delete options["itemId"]
}
}
return part
})
return { ...msg, content } as typeof msg
})
}
// if (model.api.npm === "@ai-sdk/openai" || options.store === false) {
// msgs = msgs.map((msg) => {
// if (msg.providerOptions) {
// for (const options of Object.values(msg.providerOptions)) {
// delete options["itemId"]
// }
// }
// if (!Array.isArray(msg.content)) {
// return msg
// }
// const content = msg.content.map((part) => {
// if (part.providerOptions) {
// for (const options of Object.values(part.providerOptions)) {
// delete options["itemId"]
// }
// }
// return part
// })
// return { ...msg, content } as typeof msg
// })
// }
// Anthropic rejects messages with empty content - filter out empty string messages
// and remove empty text/reasoning parts from array content

View File

@@ -478,10 +478,7 @@ export namespace MessageV2 {
if (msg.info.role === "assistant") {
if (
msg.info.error &&
!(
MessageV2.AbortedError.isInstance(msg.info.error) &&
msg.parts.some((part) => part.type !== "step-start" && part.type !== "reasoning")
)
!(MessageV2.AbortedError.isInstance(msg.info.error) && msg.parts.some((part) => part.type !== "step-start"))
) {
continue
}