fix(coding-agent): harden clipboard copy

closes #3639
This commit is contained in:
Mario Zechner
2026-04-24 12:52:32 +02:00
parent 9fdb12f985
commit 1e33492525
24 changed files with 561 additions and 108 deletions

View File

@@ -526,6 +526,11 @@ function buildParams(
enable_thinking: !!options?.reasoningEffort,
preserve_thinking: true,
};
} else if (compat.thinkingFormat === "deepseek" && model.reasoning) {
(params as any).thinking = { type: options?.reasoningEffort ? "enabled" : "disabled" };
if (options?.reasoningEffort) {
(params as any).reasoning_effort = mapReasoningEffort(options.reasoningEffort, compat.reasoningEffortMap);
}
} else if (compat.thinkingFormat === "openrouter" && model.reasoning) {
// OpenRouter normalizes reasoning across providers via a nested reasoning object.
const openRouterParams = params as typeof params & { reasoning?: { effort?: string } };
@@ -831,6 +836,13 @@ export function convertMessages(
(assistantMsg as any).reasoning_details = reasoningDetails;
}
}
if (
compat.requiresReasoningContentOnAssistantMessages &&
model.reasoning &&
(assistantMsg as { reasoning_content?: string }).reasoning_content === undefined
) {
(assistantMsg as { reasoning_content?: string }).reasoning_content = "";
}
// Skip assistant messages that have no content and no tool calls.
// Some providers require "either content or tool_calls, but not none".
// Other providers also don't accept empty assistant messages.
@@ -1021,10 +1033,18 @@ function detectCompat(model: Model<"openai-completions">): ResolvedOpenAIComplet
const isGrok = provider === "xai" || baseUrl.includes("api.x.ai");
const isGroq = provider === "groq" || baseUrl.includes("groq.com");
const isDeepSeek = provider === "deepseek" || baseUrl.includes("deepseek.com");
const cacheControlFormat = provider === "openrouter" && model.id.startsWith("anthropic/") ? "anthropic" : undefined;
const reasoningEffortMap =
isGroq && model.id === "qwen/qwen3-32b"
const reasoningEffortMap = isDeepSeek
? {
minimal: "high",
low: "high",
medium: "high",
high: "high",
xhigh: "max",
}
: isGroq && model.id === "qwen/qwen3-32b"
? {
minimal: "default",
low: "default",
@@ -1043,11 +1063,14 @@ function detectCompat(model: Model<"openai-completions">): ResolvedOpenAIComplet
requiresToolResultName: false,
requiresAssistantAfterToolResult: false,
requiresThinkingAsText: false,
thinkingFormat: isZai
? "zai"
: provider === "openrouter" || baseUrl.includes("openrouter.ai")
? "openrouter"
: "openai",
requiresReasoningContentOnAssistantMessages: isDeepSeek,
thinkingFormat: isDeepSeek
? "deepseek"
: isZai
? "zai"
: provider === "openrouter" || baseUrl.includes("openrouter.ai")
? "openrouter"
: "openai",
openRouterRouting: {},
vercelGatewayRouting: {},
zaiToolStream: false,
@@ -1077,6 +1100,9 @@ function getCompat(model: Model<"openai-completions">): ResolvedOpenAICompletion
requiresAssistantAfterToolResult:
model.compat.requiresAssistantAfterToolResult ?? detected.requiresAssistantAfterToolResult,
requiresThinkingAsText: model.compat.requiresThinkingAsText ?? detected.requiresThinkingAsText,
requiresReasoningContentOnAssistantMessages:
model.compat.requiresReasoningContentOnAssistantMessages ??
detected.requiresReasoningContentOnAssistantMessages,
thinkingFormat: model.compat.thinkingFormat ?? detected.thinkingFormat,
openRouterRouting: model.compat.openRouterRouting ?? {},
vercelGatewayRouting: model.compat.vercelGatewayRouting ?? detected.vercelGatewayRouting,