Refactor assistant message parsing: rename classes and simplify method names

- Moved StreamingParser to DirectiveStreamingParser in assistant-message/
- Renamed directives/ to parsers/
- Created new parser classes with updated names: TextContentParser, ToolUseParser, ParameterParser
- Simplified method names to parse() and finalize()
- Updated documentation in README.md
This commit is contained in:
Steven T. Cramer 2025-06-14 17:16:11 +07:00
parent 47c1dd78d5
commit 9e70691ef7
7 changed files with 26 additions and 31 deletions

View file

@ -1,9 +1,9 @@
import { Directive, ParsingState } from "./types"
import { TextContentHandler } from "./TextContentHandler"
import { ToolUseHandler } from "./ToolUseHandler"
import { ParameterHandler } from "./ParameterHandler"
import { Directive, ParsingState } from "./parsers/types"
import { TextContentParser } from "./parsers/TextContentParser"
import { ToolUseParser } from "./parsers/ToolUseParser"
import { ParameterParser } from "./parsers/ParameterParser"
export class StreamingParser {
export class DirectiveStreamingParser {
static parse(assistantMessage: string): Directive[] {
const state: ParsingState = {
contentBlocks: [],
@ -21,18 +21,18 @@ export class StreamingParser {
state.accumulator += char
// There should not be a param without a tool use.
if (ParameterHandler.handleParameter(state)) {
if (ParameterParser.parse(state)) {
continue
}
// No currentParamName.
if (ToolUseHandler.handleToolUse(state)) {
if (ToolUseParser.parse(state)) {
continue
}
// No currentToolUse.
const didStartToolUse = ToolUseHandler.checkForToolStart(state)
TextContentHandler.handleTextContent(state, i, didStartToolUse)
const didStartToolUse = ToolUseParser.checkForToolStart(state)
TextContentParser.parse(state, i, didStartToolUse)
}
// Handle remaining partial content

View file

@ -1,5 +0,0 @@
export { StreamingParser } from "./StreamingParser"
export { TextContentHandler } from "./TextContentHandler"
export { ToolUseHandler } from "./ToolUseHandler"
export { ParameterHandler } from "./ParameterHandler"
export type { TextDirective, ToolDirective, Directive, ParsingState } from "./types"

View file

@ -1,12 +1,12 @@
import { StreamingParser } from "./directives/StreamingParser"
import type { Directive } from "./directives"
import { DirectiveStreamingParser } from "./DirectiveStreamingParser"
import type { Directive } from "./parsers/types"
// Re-export types for backward compatibility
export type { TextDirective, ToolDirective, Directive } from "./directives"
export type { TextDirective, ToolDirective, Directive } from "./parsers/types"
// Backward compatibility alias
export type AssistantMessageContent = Directive
export function parseAssistantMessage(assistantMessage: string): Directive[] {
return StreamingParser.parse(assistantMessage)
return DirectiveStreamingParser.parse(assistantMessage)
}

View file

@ -1,7 +1,7 @@
import { ParsingState } from "./types"
export class ParameterHandler {
static handleParameter(state: ParsingState): boolean {
export class ParameterParser {
static parse(state: ParsingState): boolean {
if (!state.currentToolUse || !state.currentParamName) return false
const currentParamValue = state.accumulator.slice(state.currentParamValueStartIndex)

View file

@ -1,7 +1,7 @@
import { ParsingState } from "./types"
export class TextContentHandler {
static handleTextContent(state: ParsingState, currentIndex: number, didStartToolUse: boolean): void {
export class TextContentParser {
static parse(state: ParsingState, currentIndex: number, didStartToolUse: boolean): void {
if (!didStartToolUse) {
// No tool use, so it must be text either at the beginning or between tools.
if (state.currentTextContent === undefined) {
@ -16,7 +16,7 @@ export class TextContentHandler {
}
}
static finalizeTextContent(state: ParsingState, toolUseOpeningTag: string): void {
static finalize(state: ParsingState, toolUseOpeningTag: string): void {
if (state.currentTextContent) {
state.currentTextContent.partial = false

View file

@ -1,9 +1,9 @@
import { type ToolName, toolNames } from "@roo-code/types"
import { ToolParamName, toolParamNames } from "../../../shared/tools"
import { ParsingState } from "./types"
import { TextContentHandler } from "./TextContentHandler"
import { TextContentParser } from "./TextContentParser"
export class ToolUseHandler {
export class ToolUseParser {
static checkForToolStart(state: ParsingState): boolean {
let didStartToolUse = false
const possibleToolUseOpeningTags = toolNames.map((name) => `<${name}>`)
@ -21,7 +21,7 @@ export class ToolUseHandler {
state.currentToolUseStartIndex = state.accumulator.length
// This also indicates the end of the current text content.
TextContentHandler.finalizeTextContent(state, toolUseOpeningTag)
TextContentParser.finalize(state, toolUseOpeningTag)
didStartToolUse = true
break
@ -31,7 +31,7 @@ export class ToolUseHandler {
return didStartToolUse
}
static handleToolUse(state: ParsingState): boolean {
static parse(state: ParsingState): boolean {
if (!state.currentToolUse) return false
const currentToolValue = state.accumulator.slice(state.currentToolUseStartIndex)
@ -44,13 +44,13 @@ export class ToolUseHandler {
state.currentToolUse = undefined
return true
} else {
this.handleParameterParsing(state)
this.handleSpecialCases(state)
this.parseParameter(state)
this.parseSpecialCases(state)
return true // Continue processing
}
}
private static handleParameterParsing(state: ParsingState): void {
private static parseParameter(state: ParsingState): void {
const possibleParamOpeningTags = toolParamNames.map((name) => `<${name}>`)
for (const paramOpeningTag of possibleParamOpeningTags) {
if (state.accumulator.endsWith(paramOpeningTag)) {
@ -62,7 +62,7 @@ export class ToolUseHandler {
}
}
private static handleSpecialCases(state: ParsingState): void {
private static parseSpecialCases(state: ParsingState): void {
if (!state.currentToolUse) return
// Special case for write_to_file where file contents could