( systemPrompt: string, messages: Anthropic.Messages.MessageParam[], metadata?: ApiHandlerCreateMessageMetadata, )
| 48 | } |
| 49 | |
| 50 | override async *createMessage( |
| 51 | systemPrompt: string, |
| 52 | messages: Anthropic.Messages.MessageParam[], |
| 53 | metadata?: ApiHandlerCreateMessageMetadata, |
| 54 | ): ApiStream { |
| 55 | const { id, info } = this.getModel() |
| 56 | const languageModel = this.poe(id) |
| 57 | |
| 58 | const aiSdkMessages = convertToAiSdkMessages(messages) |
| 59 | const openAiTools = this.convertToolsForOpenAI(metadata?.tools) |
| 60 | const aiSdkTools = convertToolsForAiSdk(openAiTools) as ToolSet | undefined |
| 61 | |
| 62 | const useBudget = shouldUseReasoningBudget({ model: info, settings: this.options }) |
| 63 | const useEffort = !useBudget && shouldUseReasoningEffort({ model: info, settings: this.options }) |
| 64 | |
| 65 | // Only pass temperature when the user explicitly configured it. |
| 66 | let temperature: number | undefined = this.options.modelTemperature ?? undefined |
| 67 | let maxOutputTokens: number | undefined |
| 68 | const providerOptions: NonNullable<Parameters<typeof streamText>[0]["providerOptions"]> & { |
| 69 | poe?: PoeScopedProviderOptions |
| 70 | } = {} |
| 71 | |
| 72 | if (useBudget) { |
| 73 | const requestedBudget = this.options.modelMaxThinkingTokens ?? DEFAULT_THINKING_BUDGET |
| 74 | // maxOutputTokens is the text-only budget; reasoningBudgetTokens is |
| 75 | // separate, so total output = maxOutputTokens + reasoningBudgetTokens. |
| 76 | maxOutputTokens = this.options.modelMaxTokens ?? Math.max(0, (info.maxTokens ?? 0) - requestedBudget) |
| 77 | providerOptions.poe = { |
| 78 | reasoningBudgetTokens: requestedBudget, |
| 79 | } |
| 80 | temperature = 1.0 |
| 81 | } else if (useEffort) { |
| 82 | let effort = (this.options.reasoningEffort ?? info.reasoningEffort ?? "medium") as ReasoningEffortExtended |
| 83 | // Validate that the effort level is actually supported by the current model |
| 84 | const supportedEfforts = info.supportsReasoningEffort |
| 85 | if (Array.isArray(supportedEfforts) && !supportedEfforts.includes(effort as any)) { |
| 86 | effort = (info.reasoningEffort as ReasoningEffortExtended) ?? "medium" |
| 87 | } |
| 88 | providerOptions.poe = { |
| 89 | reasoningEffort: effort, |
| 90 | reasoningSummary: "auto", |
| 91 | } |
| 92 | if (this.options.modelMaxTokens) { |
| 93 | maxOutputTokens = this.options.modelMaxTokens |
| 94 | } |
| 95 | } |
| 96 | |
| 97 | let result |
| 98 | try { |
| 99 | result = streamText({ |
| 100 | model: languageModel, |
| 101 | system: systemPrompt, |
| 102 | messages: aiSdkMessages, |
| 103 | temperature, |
| 104 | maxOutputTokens, |
| 105 | tools: aiSdkTools, |
| 106 | toolChoice: mapToolChoice(metadata?.tool_choice as any), |
| 107 | ...(Object.keys(providerOptions).length > 0 && { providerOptions }), |
nothing calls this directly
no test coverage detected