( systemPrompt: string, messages: Anthropic.Messages.MessageParam[], metadata?: ApiHandlerCreateMessageMetadata, )
| 78 | } |
| 79 | |
| 80 | async *createMessage( |
| 81 | systemPrompt: string, |
| 82 | messages: Anthropic.Messages.MessageParam[], |
| 83 | metadata?: ApiHandlerCreateMessageMetadata, |
| 84 | ): ApiStream { |
| 85 | const cacheControl: CacheControlEphemeral = { type: "ephemeral" } |
| 86 | const { id: modelId, info, maxTokens, temperature } = this.getModel() |
| 87 | |
| 88 | // MiniMax M2 models support prompt caching |
| 89 | const supportsPromptCache = info.supportsPromptCache ?? false |
| 90 | |
| 91 | // Merge environment_details from messages that follow tool_result blocks |
| 92 | // into the tool_result content. This preserves reasoning continuity for |
| 93 | // thinking models by preventing user messages from interrupting the |
| 94 | // reasoning context after tool use (similar to r1-format's mergeToolResultText). |
| 95 | const processedMessages = mergeEnvironmentDetailsForMiniMax(messages) |
| 96 | |
| 97 | // Build the system blocks array |
| 98 | const systemBlocks: Anthropic.Messages.TextBlockParam[] = [ |
| 99 | supportsPromptCache |
| 100 | ? { text: systemPrompt, type: "text", cache_control: cacheControl } |
| 101 | : { text: systemPrompt, type: "text" }, |
| 102 | ] |
| 103 | |
| 104 | // Prepare request parameters |
| 105 | const requestParams: Anthropic.Messages.MessageCreateParams = { |
| 106 | model: modelId, |
| 107 | max_tokens: maxTokens ?? 16_384, |
| 108 | temperature: temperature ?? 1.0, |
| 109 | system: systemBlocks, |
| 110 | messages: supportsPromptCache ? this.addCacheControl(processedMessages, cacheControl) : processedMessages, |
| 111 | stream: true, |
| 112 | tools: convertOpenAIToolsToAnthropic(metadata?.tools ?? []), |
| 113 | tool_choice: convertOpenAIToolChoice(metadata?.tool_choice), |
| 114 | } |
| 115 | |
| 116 | const stream = await this.client.messages.create(requestParams) |
| 117 | |
| 118 | let inputTokens = 0 |
| 119 | let outputTokens = 0 |
| 120 | let cacheWriteTokens = 0 |
| 121 | let cacheReadTokens = 0 |
| 122 | |
| 123 | for await (const chunk of stream) { |
| 124 | switch (chunk.type) { |
| 125 | case "message_start": { |
| 126 | // Tells us cache reads/writes/input/output. |
| 127 | const { |
| 128 | input_tokens = 0, |
| 129 | output_tokens = 0, |
| 130 | cache_creation_input_tokens, |
| 131 | cache_read_input_tokens, |
| 132 | } = chunk.message.usage |
| 133 | |
| 134 | yield { |
| 135 | type: "usage", |
| 136 | inputTokens: input_tokens, |
| 137 | outputTokens: output_tokens, |
nothing calls this directly
no test coverage detected