Skip to content

Commit 1bf14f6

Browse files
committed
feat: add debug output for API streaming operations
error: mistral only works with stream = true?
1 parent fdecd03 commit 1bf14f6

File tree

3 files changed

+43
-14
lines changed

3 files changed

+43
-14
lines changed

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,11 @@
274274
"type": "boolean",
275275
"default": false,
276276
"description": "Enable debug output channel for Mistral API interactions"
277+
},
278+
"roo-cline.enableApiStreamDebugOutput": {
279+
"type": "boolean",
280+
"default": false,
281+
"description": "Enable debug output for API streaming operations"
277282
}
278283
}
279284
}

src/api/providers/mistral.ts

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,7 @@
11
import { Anthropic } from "@anthropic-ai/sdk"
22
import { Mistral } from "@mistralai/mistralai"
33
import { ApiHandler } from "../"
4-
import {
5-
ApiHandlerOptions,
6-
mistralDefaultModelId,
7-
MistralModelId,
8-
mistralModels,
9-
ModelInfo,
10-
openAiNativeDefaultModelId,
11-
OpenAiNativeModelId,
12-
openAiNativeModels,
13-
} from "../../shared/api"
4+
import { ApiHandlerOptions, mistralDefaultModelId, MistralModelId, mistralModels, ModelInfo } from "../../shared/api"
145
import { convertToMistralMessages } from "../transform/mistral-format"
156
import { ApiStream } from "../transform/stream"
167
import * as vscode from "vscode"
@@ -55,7 +46,12 @@ export class MistralHandler implements ApiHandler {
5546
? {
5647
group: (message: string) => this.logDebug(`[Mistral Group] ${message}`),
5748
groupEnd: () => this.logDebug(`[Mistral GroupEnd]`),
58-
log: (...args: any[]) => this.logDebug(`[Mistral Log] ${args.join(" ")}`),
49+
log: (...args: any[]) =>
50+
this.logDebug(
51+
`[Mistral Log] ${args
52+
.map((arg) => (typeof arg === "object" ? JSON.stringify(arg, null, 2) : arg))
53+
.join(" ")}`,
54+
),
5955
}
6056
: undefined
6157

@@ -66,9 +62,10 @@ export class MistralHandler implements ApiHandler {
6662
})
6763
}
6864

69-
private logDebug(message: string) {
65+
private logDebug(message: string | object) {
7066
if (this.enableDebugOutput && this.outputChannel) {
71-
this.outputChannel.appendLine(`[Roo Code] ${message}`)
67+
const formattedMessage = typeof message === "object" ? JSON.stringify(message, null, 2) : message
68+
this.outputChannel.appendLine(`[Roo Code] ${formattedMessage}`)
7269
}
7370
}
7471

@@ -85,9 +82,10 @@ export class MistralHandler implements ApiHandler {
8582
this.logDebug(`Creating message with system prompt: ${systemPrompt}`)
8683
const response = await this.client.chat.stream({
8784
model: this.options.apiModelId || mistralDefaultModelId,
85+
maxTokens: this.options.includeMaxTokens ? this.getModel().info.maxTokens : undefined,
8886
messages: [{ role: "system", content: systemPrompt }, ...convertToMistralMessages(messages)],
8987
temperature: this.options.modelTemperature ?? MISTRAL_DEFAULT_TEMPERATURE,
90-
stream: this.options.mistralModelStreamingEnabled,
88+
stream: this.options.mistralModelStreamingEnabled ?? undefined,
9189
})
9290

9391
let completeContent = ""

src/core/Cline.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ type UserContent = Array<
7474
>
7575

7676
export class Cline {
77+
private static readonly outputChannelName = "Roo Code Stream Output"
78+
private static sharedOutputChannel: vscode.OutputChannel | undefined
79+
private readonly enableStreamDebug: boolean
80+
private readonly outputChannel?: vscode.OutputChannel
81+
7782
readonly taskId: string
7883
api: ApiHandler
7984
private terminalManager: TerminalManager
@@ -130,6 +135,16 @@ export class Cline {
130135
historyItem?: HistoryItem | undefined,
131136
experiments?: Record<string, boolean>,
132137
) {
138+
const config = vscode.workspace.getConfiguration("roo-cline")
139+
this.enableStreamDebug = config.get<boolean>("enableApiStreamDebugOutput", false)
140+
141+
if (this.enableStreamDebug) {
142+
if (!Cline.sharedOutputChannel) {
143+
Cline.sharedOutputChannel = vscode.window.createOutputChannel(Cline.outputChannelName)
144+
}
145+
this.outputChannel = Cline.sharedOutputChannel
146+
}
147+
133148
if (!task && !images && !historyItem) {
134149
throw new Error("Either historyItem or task/images must be provided")
135150
}
@@ -160,6 +175,12 @@ export class Cline {
160175
}
161176
}
162177

178+
private logStreamDebug(message: string) {
179+
if (this.enableStreamDebug && this.outputChannel) {
180+
this.outputChannel.appendLine(`[Stream Debug] ${message}`)
181+
}
182+
}
183+
163184
// Add method to update diffStrategy
164185
async updateDiffStrategy(experimentalDiffStrategy?: boolean) {
165186
// If not provided, get from current state
@@ -965,12 +986,17 @@ export class Cline {
965986
const iterator = stream[Symbol.asyncIterator]()
966987

967988
try {
989+
this.logStreamDebug(
990+
`Starting API request - Previous index: ${previousApiReqIndex}, Retry attempt: ${retryAttempt}`,
991+
)
968992
// awaiting first chunk to see if it will throw an error
969993
this.isWaitingForFirstChunk = true
970994
const firstChunk = await iterator.next()
995+
this.logStreamDebug(`Received first chunk: ${JSON.stringify(firstChunk.value)}`)
971996
yield firstChunk.value
972997
this.isWaitingForFirstChunk = false
973998
} catch (error) {
999+
this.logStreamDebug(`Error on first chunk: ${error}`)
9741000
// note that this api_req_failed ask is unique in that we only present this option if the api hasn't streamed any content yet (ie it fails on the first chunk due), as it would allow them to hit a retry button. However if the api failed mid-stream, it could be in any arbitrary state where some tools may have executed, so that error is handled differently and requires cancelling the task entirely.
9751001
if (alwaysApproveResubmit) {
9761002
const errorMsg = error.message ?? "Unknown error"

0 commit comments

Comments
 (0)