04463e9af3
Keep provider thinking on a separate channel so process talk is not billed as the spoken reply (BUG-359). Co-authored-by: Cursor <cursoragent@cursor.com>
66 lines
2.3 KiB
TypeScript
66 lines
2.3 KiB
TypeScript
/**
|
|
* Spoken-answer generation settings shared by consultation and rectification.
|
|
*
|
|
* DeepSeek hidden reasoning and visible content can share one `max_tokens`
|
|
* cap. The spoken budget stays 16384; when provider thinking is on, the
|
|
* output cap is spoken + thinking so CoT cannot pinch the user-facing reply.
|
|
* Reasoning must travel on `reasoning-delta` / `thinking.delta`, never on
|
|
* `answer.delta`.
|
|
*/
|
|
export const AGENT_ANSWER_OUTPUT_TOKENS = 16_384;
|
|
export const AGENT_THINKING_OUTPUT_TOKENS = 8_192;
|
|
export const AGENT_SLICE_ANSWER_OUTPUT_TOKENS = 8_192;
|
|
export const AGENT_SLICE_THINKING_OUTPUT_TOKENS = 2_048;
|
|
/** @deprecated Use AGENT_ANSWER_OUTPUT_TOKENS; kept as the compose-budget alias. */
|
|
export const AGENT_MAX_OUTPUT_TOKENS = AGENT_ANSWER_OUTPUT_TOKENS;
|
|
|
|
export type ThinkingMode = "enabled" | "disabled";
|
|
export type ReasoningEffort = "low" | "medium" | "high";
|
|
|
|
export function agentOutputTokenBudget(
|
|
thinking: ThinkingMode,
|
|
options: { answerTokens?: number; thinkingTokens?: number } = {},
|
|
): number {
|
|
const answerTokens = options.answerTokens ?? AGENT_ANSWER_OUTPUT_TOKENS;
|
|
if (thinking !== "enabled") return answerTokens;
|
|
return answerTokens + (options.thinkingTokens ?? AGENT_THINKING_OUTPUT_TOKENS);
|
|
}
|
|
|
|
export function agentGenerationSettings(
|
|
model?: unknown,
|
|
options: {
|
|
thinking?: ThinkingMode;
|
|
answerTokens?: number;
|
|
thinkingTokens?: number;
|
|
reasoningEffort?: ReasoningEffort;
|
|
} = {},
|
|
) {
|
|
const thinkingMode: ThinkingMode = options.thinking ?? "disabled";
|
|
const thinking = {
|
|
thinking: {
|
|
type: thinkingMode,
|
|
...(thinkingMode === "enabled" && options.reasoningEffort
|
|
? { reasoningEffort: options.reasoningEffort }
|
|
: {}),
|
|
},
|
|
};
|
|
const providerId = typeof model === "string"
|
|
? model
|
|
: model && typeof model === "object" && "providerId" in model && typeof model.providerId === "string"
|
|
? model.providerId
|
|
: undefined;
|
|
const providerOptions: Record<string, typeof thinking> = {
|
|
openai: thinking,
|
|
};
|
|
if (providerId) providerOptions[providerId] = thinking;
|
|
return {
|
|
modelSettings: {
|
|
maxOutputTokens: agentOutputTokenBudget(thinkingMode, {
|
|
answerTokens: options.answerTokens,
|
|
thinkingTokens: options.thinkingTokens,
|
|
}),
|
|
},
|
|
providerOptions,
|
|
};
|
|
}
|