Skip to content

bbrowning/harmony-format-fixer

Repository files navigation

Harmony Format Fixer

Automatic repair for malformed Harmony format token sequences from gpt-oss models.

Overview

Harmony Format Fixer is a Python library that provides a drop-in replacement for openai-harmony's StreamableParser. It automatically detects and repairs common malformed token sequences, particularly the missing <|message|> token issue documented in openai/harmony#80.

Features

  • Zero overhead for valid input - Pass-through delegation when tokens are well-formed
  • Automatic error recovery - Detects and repairs malformed token sequences mid-stream
  • Drop-in replacement - Compatible with StreamableParser API
  • Multiple repair strategies - Includes repairs for missing <|message|> tokens and special tokens in headers
  • Extensible repair strategies - Add custom repair logic for new error patterns
  • Minimal dependencies - Only requires openai-harmony and pytest (dev)
  • Comprehensive test suite - Documents all known edge cases and validates correct handling of valid inputs
  • API conformance - Full compatibility with StreamableParser interface

Installation

From Source (Development)

git clone https://github.com/your-org/harmony-format-fixer.git
cd harmony-format-fixer
pip install -e .

From PyPI (Coming Soon)

pip install harmony-format-fixer

Quick Start

Replace your existing StreamableParser with RetryingParser:

from openai_harmony import load_harmony_encoding, HarmonyEncodingName, Role
from harmony_format_fixer import RetryingParser

# Load Harmony encoding
encoding = load_harmony_encoding(HarmonyEncodingName.HARMONY_GPT_OSS)

# Create retrying parser (drop-in replacement for StreamableParser)
parser = RetryingParser(encoding, role=Role.ASSISTANT)

# Process tokens - repairs applied automatically
for token in tokens:
    parser.process(token)  # Malformed sequences repaired automatically

# Access content
print(parser.current_content)

# Check if repairs were needed
if parser.repair_count > 0:
    print(f"Applied {parser.repair_count} repair(s)")

Problem Statement

gpt-oss models sometimes generate token sequences that violate the Harmony format specification. The most common case is refusal responses that omit the required <|message|> token, causing parsing to fail with "unexpected tokens remaining in message header" errors.

Before (Using StreamableParser)

from openai_harmony import StreamableParser, HarmonyError

parser = StreamableParser(encoding, role=Role.ASSISTANT)

try:
    for token in malformed_tokens:  # Missing <|message|> token
        parser.process(token)  # Raises HarmonyError
except HarmonyError as e:
    print(f"Parsing failed: {e}")

After (Using RetryingParser)

from harmony_format_fixer import RetryingParser

parser = RetryingParser(encoding, role=Role.ASSISTANT)

for token in malformed_tokens:  # Same malformed tokens
    parser.process(token)  # Works! Repair applied automatically

print(parser.current_content)  # "I'm sorry, I cannot..."

Requirements

  • Python 3.9 or higher
  • openai-harmony (PyPI)
  • pytest (dev dependency for testing)

Project Structure

harmony_format_fixer/
├── __init__.py              # Package initialization and public API
├── retrying_parser.py       # Main RetryingParser wrapper class
└── repair_strategies.py     # Repair strategy implementations

tests/
├── conftest.py              # Shared test fixtures and configuration
├── test_retrying_parser.py  # Core parser tests
├── test_repair_strategies.py # Repair strategy tests
├── test_edge_cases.py       # Integration tests for edge cases
├── test_api_conformance.py  # API compatibility tests
├── test_helpers.py          # Test helper utilities
└── test_valid_inputs.py     # Valid input test coverage

Development

Setup Development Environment

# Clone repository
git clone https://github.com/your-org/harmony-format-fixer.git
cd harmony-format-fixer

# Install in editable mode with dev dependencies
pip install -e .[dev]

# Run tests
pytest tests/

# Run with coverage
pytest --cov=harmony_format_fixer tests/

Running Tests

# All tests
pytest tests/

# Specific test file
pytest tests/test_retrying_parser.py

# Verbose output
pytest -v tests/

# With coverage report
pytest --cov=harmony_format_fixer --cov-report=html tests/

Type Checking

This project uses mypy for static type checking with strict settings. All library and test code includes complete type annotations.

Installation

Type checking dependencies are included in the dev dependencies:

pip install -e ".[dev]"

Running Type Checks

Check all library and test code:

mypy harmony_format_fixer tests

Expected output when passing:

Success: no issues found in 11 source files

Type Checking in Your Workflow

Before committing changes, run all quality checks:

# Run all quality gates
pytest                          # All tests must pass
ruff check .                    # Linting must pass
mypy harmony_format_fixer tests # Type checking must pass

IDE Integration

Modern IDEs automatically detect mypy configuration and show type hints:

  • VSCode: Install Python extension with Pylance for full type inference
  • PyCharm: Built-in mypy support and type checking

When using the library, your IDE will show complete type information:

from harmony_format_fixer import RetryingParser

parser = RetryingParser(encoding, role)
# IDE shows: process(token: int) -> None
parser.process(token)

Common Type Errors

"Cannot find implementation or library stub" Third-party library lacks type stubs. Already configured in pyproject.toml for openai_harmony.

"Incompatible types in assignment"

# Wrong
count: int = "42"

# Right
count: int = 42

"Need type annotation" Mypy can't infer the type. Add an explicit annotation:

# Wrong
items = []  # What type of items?

# Right
from typing import List
items: List[str] = []

For more details, see specs/008-add-type-checking/quickstart.md.

Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure all tests pass
  5. Submit a pull request

License

MIT License - See LICENSE file for details

Acknowledgments

Known Edge Cases

The test suite documents all known failure patterns and their repairs:

Missing <|message|> Token (Issue #80)

  • Pattern: "unexpected tokens remaining in message header"
  • Cause: gpt-oss models omit required <|message|> token in refusal responses
  • Repair: Prepend <|message|> token (ID computed from harmony encoding)
  • Test: tests/test_edge_cases.py::test_issue_80_missing_message_token
  • Reference: openai/harmony#80

Special Tokens in Header Fields

  • Pattern: "special tokens in header fields"
  • Cause: Text appears before <|message|> token, causing parser to misinterpret special token strings (like "<|end|>" or "<|start|>") in header metadata fields
  • Repair: Prepend <|message|> token to convert header text into message content
  • Test: tests/test_edge_cases.py::test_hard_refusal_example
  • Strategy: SpecialTokenInHeaderStrategy (priority 2)

Multiple Errors in Sequence

  • Pattern: Multiple different errors occur during one token stream
  • Repair: Each error is detected and repaired independently
  • Test: tests/test_edge_cases.py::test_multiple_errors_in_sequence

Completely Unparseable Input

  • Pattern: Garbage tokens that no strategy can repair
  • Behavior: Original HarmonyError is re-raised after all strategies fail
  • Test: tests/test_edge_cases.py::test_completely_unparseable_input

Empty Token Sequence

  • Pattern: No tokens provided before EOS
  • Behavior: Handled gracefully without errors
  • Test: tests/test_edge_cases.py::test_empty_token_sequence

Repair Introduces New Error

  • Pattern: A repair strategy introduces tokens that cause a different parsing error
  • Behavior: Handled with retry limits to prevent infinite loops
  • Test: tests/test_edge_cases.py::test_repair_introduces_new_error

Long Sequence with Late Error

  • Pattern: Errors occurring after many successful tokens
  • Behavior: O(N) space complexity with reasonable replay performance, no memory issues
  • Test: tests/test_edge_cases.py::test_long_sequence_with_late_error

Input Validation

  • Invalid Input: Negative token IDs, non-integer tokens
  • Behavior: Immediate TypeError or ValueError raised
  • Tests:
    • tests/test_retrying_parser.py::test_negative_token_id
    • tests/test_retrying_parser.py::test_non_integer_token

For the complete list of edge cases and their behaviors, see the test suite in tests/.

Support

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •