-
Notifications
You must be signed in to change notification settings - Fork 2.6k
fix: parse gpt-oss special token format in LM Studio responses #6740
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- 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
There was a problem hiding this 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 |
There was a problem hiding this comment.
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") |
There was a problem hiding this comment.
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?
| 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) { |
There was a problem hiding this comment.
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", () => { |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
|
The model is hallucinating a format and looping, closing for now |
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:
Solution
parseGptOssFormatmethod that:<|message|>token if presentTesting
Fixes #6739
Important
Fixes gpt-oss model response parsing in LM Studio by adding special token format handling in
LmStudioHandler.LmStudioHandlernow detects gpt-oss models and parses special token formats usingparseGptOssFormat().<|message|>token or removes special tokens and function patterns if not present.lmstudio.spec.tsfor gpt-oss format parsing with and without<|message|>token.This description was created by
for 93dc32d. You can customize this summary. It will automatically update as commits are pushed.