Skip to content

Commit 59c6bf3

Browse files
qdaxbdaniel-lxs
authored andcommitted
code refactor of AssistantMessageParser
1 parent 8c8c410 commit 59c6bf3

File tree

2 files changed

+28
-21
lines changed

2 files changed

+28
-21
lines changed

src/core/assistant-message/AssistantMessageParser.ts

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,7 @@ export class AssistantMessageParser {
7676
} else {
7777
// Partial param value is accumulating.
7878
// Write the currently accumulated param content in real time
79-
const partialValue = currentParamValue
80-
this.currentToolUse.params[this.currentParamName] =
81-
this.currentParamName === "content"
82-
? partialValue.replace(/^\n/, "").replace(/\n$/, "")
83-
: partialValue.trim()
79+
this.currentToolUse.params[this.currentParamName] = currentParamValue
8480
continue
8581
}
8682
}
@@ -167,6 +163,8 @@ export class AssistantMessageParser {
167163
.slice(0, -toolUseOpeningTag.slice(0, -1).length)
168164
.trim()
169165

166+
this.currentTextContent.content = this.currentTextContent.content.trim()
167+
170168
// No need to push, currentTextContent is already in contentBlocks
171169
this.currentTextContent = undefined
172170
}
@@ -193,7 +191,7 @@ export class AssistantMessageParser {
193191
// Create a new text content block and add it to contentBlocks
194192
this.currentTextContent = {
195193
type: "text",
196-
content: this.accumulator.slice(this.currentTextContentStartIndex).trim(),
194+
content: this.accumulator.slice(this.currentTextContentStartIndex),
197195
partial: true,
198196
}
199197

@@ -202,7 +200,7 @@ export class AssistantMessageParser {
202200
this.contentBlocks.push(this.currentTextContent)
203201
} else {
204202
// Update the existing text content
205-
this.currentTextContent.content = this.accumulator.slice(this.currentTextContentStartIndex).trim()
203+
this.currentTextContent.content = this.accumulator.slice(this.currentTextContentStartIndex)
206204
}
207205
}
208206
}
@@ -222,16 +220,9 @@ export class AssistantMessageParser {
222220
if (block.partial) {
223221
block.partial = false
224222
}
223+
if (block.type === "text" && typeof block.content === "string") {
224+
block.content = block.content.trim()
225+
}
225226
}
226227
}
227-
228-
/**
229-
* Process a complete message and return the parsed content blocks.
230-
* @param message The complete message to parse.
231-
* @returns The parsed content blocks.
232-
*/
233-
public parseCompleteMessage(message: string): AssistantMessageContent[] {
234-
this.reset()
235-
return this.processChunk(message)
236-
}
237228
}

src/core/assistant-message/__tests__/AssistantMessageParser.spec.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import { describe, it, expect, beforeEach } from "vitest"
44
import { AssistantMessageParser } from "../AssistantMessageParser"
5+
import { AssistantMessageContent } from "../parseAssistantMessage"
56
import { TextContent, ToolUse } from "../../../shared/tools"
67
import { toolNames } from "@roo-code/types"
78

@@ -11,17 +12,32 @@ import { toolNames } from "@roo-code/types"
1112
const isEmptyTextContent = (block: any) => block.type === "text" && (block as TextContent).content === ""
1213

1314
/**
14-
* Helper to simulate streaming by feeding the parser random-sized chunks (1-10 chars).
15+
* Helper to simulate streaming by feeding the parser deterministic "random"-sized chunks (1-10 chars).
16+
* Uses a seeded pseudo-random number generator for deterministic chunking.
1517
*/
18+
19+
// Simple linear congruential generator (LCG) for deterministic pseudo-random numbers
20+
function createSeededRandom(seed: number) {
21+
let state = seed
22+
return {
23+
next: () => {
24+
// LCG parameters from Numerical Recipes
25+
state = (state * 1664525 + 1013904223) % 0x100000000
26+
return state / 0x100000000
27+
},
28+
}
29+
}
30+
1631
function streamChunks(
1732
parser: AssistantMessageParser,
1833
message: string,
1934
): ReturnType<AssistantMessageParser["getContentBlocks"]> {
20-
let result: any[] = []
35+
let result: AssistantMessageContent[] = []
2136
let i = 0
37+
const rng = createSeededRandom(42) // Fixed seed for deterministic tests
2238
while (i < message.length) {
23-
// Random chunk size between 1 and 10, but not exceeding message length
24-
const chunkSize = Math.min(message.length - i, Math.floor(Math.random() * 10) + 1)
39+
// Deterministic chunk size between 1 and 10, but not exceeding message length
40+
const chunkSize = Math.min(message.length - i, Math.floor(rng.next() * 10) + 1)
2541
const chunk = message.slice(i, i + chunkSize)
2642
result = parser.processChunk(chunk)
2743
i += chunkSize

0 commit comments

Comments
 (0)