( systemPrompt: string, messages: Anthropic.Messages.MessageParam[], metadata?: ApiHandlerCreateMessageMetadata, )
| 73 | } |
| 74 | |
| 75 | override async *createMessage( |
| 76 | systemPrompt: string, |
| 77 | messages: Anthropic.Messages.MessageParam[], |
| 78 | metadata?: ApiHandlerCreateMessageMetadata, |
| 79 | ): ApiStream { |
| 80 | const { id: model, info, maxTokens, temperature } = this.getModel() |
| 81 | |
| 82 | // Build request options |
| 83 | const requestOptions: { |
| 84 | model: string |
| 85 | messages: ReturnType<typeof convertToMistralMessages> |
| 86 | maxTokens: number |
| 87 | temperature: number |
| 88 | tools?: MistralTool[] |
| 89 | toolChoice?: "auto" | "none" | "any" | "required" | { type: "function"; function: { name: string } } |
| 90 | } = { |
| 91 | model, |
| 92 | messages: [{ role: "system", content: systemPrompt }, ...convertToMistralMessages(messages)], |
| 93 | maxTokens: maxTokens ?? info.maxTokens, |
| 94 | temperature, |
| 95 | } |
| 96 | |
| 97 | requestOptions.tools = this.convertToolsForMistral(metadata?.tools ?? []) |
| 98 | // Always use "any" to require tool use |
| 99 | requestOptions.toolChoice = "any" |
| 100 | |
| 101 | // Temporary debug log for QA |
| 102 | // console.log("[MISTRAL DEBUG] Raw API request body:", requestOptions) |
| 103 | |
| 104 | let response |
| 105 | try { |
| 106 | response = await this.client.chat.stream(requestOptions) |
| 107 | } catch (error) { |
| 108 | const errorMessage = error instanceof Error ? error.message : String(error) |
| 109 | const apiError = new ApiProviderError(errorMessage, this.providerName, model, "createMessage") |
| 110 | TelemetryService.instance.captureException(apiError) |
| 111 | throw new Error(`Mistral completion error: ${errorMessage}`) |
| 112 | } |
| 113 | |
| 114 | for await (const event of response) { |
| 115 | const delta = event.data.choices[0]?.delta |
| 116 | |
| 117 | if (delta?.content) { |
| 118 | if (typeof delta.content === "string") { |
| 119 | // Handle string content as text |
| 120 | yield { type: "text", text: delta.content } |
| 121 | } else if (Array.isArray(delta.content)) { |
| 122 | // Handle array of content chunks |
| 123 | // The SDK v1.9.18 supports ThinkChunk with type "thinking" |
| 124 | for (const chunk of delta.content as ContentChunkWithThinking[]) { |
| 125 | if (chunk.type === "thinking" && chunk.thinking) { |
| 126 | // Handle thinking content as reasoning chunks |
| 127 | // ThinkChunk has a 'thinking' property that contains an array of text/reference chunks |
| 128 | for (const thinkingPart of chunk.thinking) { |
| 129 | if (thinkingPart.type === "text" && thinkingPart.text) { |
| 130 | yield { type: "reasoning", text: thinkingPart.text } |
| 131 | } |
| 132 | } |
nothing calls this directly
no test coverage detected