@@ -9307,7 +9307,7 @@ export const MODELS = {
|
||||
cacheRead: 0,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
contextWindow: 204800,
|
||||
contextWindow: 262144,
|
||||
maxTokens: 8192,
|
||||
} satisfies Model<"openai-completions">,
|
||||
"minimax/minimax-m2.7": {
|
||||
@@ -11915,13 +11915,13 @@ export const MODELS = {
|
||||
reasoning: true,
|
||||
input: ["text"],
|
||||
cost: {
|
||||
input: 0.06599999999999999,
|
||||
output: 0.26,
|
||||
cacheRead: 0.029,
|
||||
input: 0.063,
|
||||
output: 0.21,
|
||||
cacheRead: 0.020999999999999998,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
contextWindow: 262144,
|
||||
maxTokens: 262144,
|
||||
maxTokens: 4096,
|
||||
} satisfies Model<"openai-completions">,
|
||||
"thedrummer/rocinante-12b": {
|
||||
id: "thedrummer/rocinante-12b",
|
||||
|
||||
@@ -177,6 +177,7 @@ function getAnthropicCompat(
|
||||
sendSessionAffinityHeaders:
|
||||
model.compat?.sendSessionAffinityHeaders ?? !!(isFireworks || isCloudflareAiGatewayAnthropic),
|
||||
supportsCacheControlOnTools: model.compat?.supportsCacheControlOnTools ?? !isFireworks,
|
||||
allowEmptySignature: model.compat?.allowEmptySignature ?? false,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -895,7 +896,13 @@ function buildParams(
|
||||
const { cacheControl } = getCacheControl(model, options?.cacheRetention);
|
||||
const params: MessageCreateParamsStreaming = {
|
||||
model: model.id,
|
||||
messages: convertMessages(context.messages, model, isOAuthToken, cacheControl),
|
||||
messages: convertMessages(
|
||||
context.messages,
|
||||
model,
|
||||
isOAuthToken,
|
||||
cacheControl,
|
||||
getAnthropicCompat(model).allowEmptySignature,
|
||||
),
|
||||
max_tokens: options?.maxTokens ?? model.maxTokens,
|
||||
stream: true,
|
||||
};
|
||||
@@ -1001,6 +1008,7 @@ function convertMessages(
|
||||
model: Model<"anthropic-messages">,
|
||||
isOAuthToken: boolean,
|
||||
cacheControl?: CacheControlEphemeral,
|
||||
allowEmptySignature = false,
|
||||
): MessageParam[] {
|
||||
const params: MessageParam[] = [];
|
||||
|
||||
@@ -1069,13 +1077,21 @@ function convertMessages(
|
||||
}
|
||||
if (block.thinking.trim().length === 0) continue;
|
||||
// If thinking signature is missing/empty (e.g., from aborted stream),
|
||||
// convert to plain text block without <thinking> tags to avoid API rejection
|
||||
// and prevent Claude from mimicking the tags in responses
|
||||
// convert to plain text for Anthropic. Some compatible providers emit
|
||||
// and accept empty signatures, so let marked models preserve the block.
|
||||
if (!block.thinkingSignature || block.thinkingSignature.trim().length === 0) {
|
||||
blocks.push({
|
||||
type: "text",
|
||||
text: sanitizeSurrogates(block.thinking),
|
||||
});
|
||||
blocks.push(
|
||||
allowEmptySignature
|
||||
? {
|
||||
type: "thinking",
|
||||
thinking: sanitizeSurrogates(block.thinking),
|
||||
signature: "",
|
||||
}
|
||||
: {
|
||||
type: "text",
|
||||
text: sanitizeSurrogates(block.thinking),
|
||||
},
|
||||
);
|
||||
} else {
|
||||
blocks.push({
|
||||
type: "thinking",
|
||||
|
||||
@@ -451,6 +451,8 @@ export interface AnthropicMessagesCompat {
|
||||
* Default: false.
|
||||
*/
|
||||
forceAdaptiveThinking?: boolean;
|
||||
/** Whether to replay empty thinking signatures as `signature: ""` instead of converting thinking to text. Default: false. */
|
||||
allowEmptySignature?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user