Skip to content

Conversation

@roomote
Copy link
Contributor

@roomote roomote bot commented Aug 5, 2025

This PR fixes the issue where gpt-oss models output responses in a special token format that was being displayed raw instead of being parsed properly.

Problem

When using LM Studio with gpt-oss-20b model, responses were appearing in this format:

<|start|>assistant<|channel|>commentary to=read_file <|constrain|>json<|message|>{"args":[{"file":{"path":"documentation/program_analysis.md"}}]}

Solution

  • Added detection for gpt-oss models in the LmStudioHandler
  • Implemented a parseGptOssFormat method that:
    • Extracts content after the <|message|> token if present
    • Otherwise removes all special tokens and function patterns
    • Returns clean, usable content
  • Added comprehensive tests to ensure the parsing works correctly

Testing

  • Added 3 new test cases covering different scenarios
  • All existing tests continue to pass
  • The parsing only applies to models with "gpt-oss" in their name, so other models are unaffected

Fixes #6739


Important

Fixes gpt-oss model response parsing in LM Studio by adding special token format handling in LmStudioHandler.

  • Behavior:
    • LmStudioHandler now detects gpt-oss models and parses special token formats using parseGptOssFormat().
    • Extracts content after <|message|> token or removes special tokens and function patterns if not present.
    • Parsing only applies to models with "gpt-oss" in their name.
  • Testing:
    • Added tests in lmstudio.spec.ts for gpt-oss format parsing with and without <|message|> token.
    • Ensures non-gpt-oss models are unaffected by parsing.
  • Misc:

This description was created by Ellipsis for 93dc32d. You can customize this summary. It will automatically update as commits are pushed.

- Add detection for gpt-oss models in LmStudioHandler
- Implement parseGptOssFormat method to extract actual content from special token format
- Add comprehensive tests for the new parsing logic
- Fixes #6739
@roomote roomote bot requested review from cte, jr and mrubens as code owners August 5, 2025 20:41
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. bug Something isn't working labels Aug 5, 2025
Copy link
Contributor Author

@roomote roomote bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewing my own code is like debugging in a mirror - everything looks backwards but the bugs are still mine.

private parseGptOssFormat(content: string): string {
// Remove all special tokens and extract the actual message
// Pattern: <|token|> where token can be any word
const specialTokenPattern = /<\|[^|]+\|>/g
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex pattern /<\|[^|]+\|>/g might not handle edge cases correctly. What happens if the token content itself contains a pipe character? Consider using a more robust parsing approach or documenting this limitation.

for (const processedChunk of matcher.update(delta.content)) {
yield processedChunk
// Check if this is a gpt-oss model with special token format
const isGptOss = this.getModel().id?.toLowerCase().includes("gpt-oss")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Performance consideration: Since the model doesn't change during streaming, could we move this gpt-oss check outside the loop to avoid repeated string operations on every chunk?

Suggested change
const isGptOss = this.getModel().id?.toLowerCase().includes("gpt-oss")
// Check if this is a gpt-oss model with special token format
const isGptOss = this.getModel().id?.toLowerCase().includes("gpt-oss")
for await (const chunk of results) {
const delta = chunk.choices[0]?.delta
if (delta?.content) {
if (isGptOss && delta.content.includes("<|") && delta.content.includes("|>")) {

// Parse gpt-oss special token format
// Format: <|start|>assistant<|channel|>commentary to=read_file <|constrain|>json<|message|>{"args":[...]}
const cleanedContent = this.parseGptOssFormat(delta.content)
if (cleanedContent) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When cleanedContent is empty or falsy after parsing, we silently skip it. Should we consider logging a warning to help with debugging unexpected formats?

})
})

describe("gpt-oss special token parsing", () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding test cases for edge scenarios:

  • Multiple <|message|> tokens in a single chunk
  • Malformed special tokens (e.g., unclosed tokens like <|start)
  • Very large JSON payloads after the message token
  • Mixed content with both special tokens and regular text

const cleaned = content.replace(specialTokenPattern, " ").trim()

// Also clean up any "to=function_name" patterns that might remain
const functionPattern = /\s*to=\w+\s*/g
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function pattern /\s*to=\w+\s*/g only matches word characters. Is this intentional? Function names might contain hyphens or underscores. Consider using /\s*to=[\w-]+\s*/g if you want to support kebab-case function names.

@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Aug 5, 2025
@daniel-lxs
Copy link
Member

The model is hallucinating a format and looping, closing for now

@daniel-lxs daniel-lxs closed this Aug 5, 2025
@github-project-automation github-project-automation bot moved this from Triage to Done in Roo Code Roadmap Aug 5, 2025
@github-project-automation github-project-automation bot moved this from New to Done in Roo Code Roadmap Aug 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. size:L This PR changes 100-499 lines, ignoring generated files.

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Strange formatted replies when using with LMStudio and gpt-oss

4 participants