simple-agents-healing 0.2.26

Response healing system for SimpleAgents - BAML-inspired JSON parsing and coercion
Documentation
# simple-agents-healing

Response healing system for SimpleAgents - BAML-inspired JSON parsing and type coercion.

## Overview

This crate implements a sophisticated JSON healing system that handles malformed LLM outputs. Instead of failing on broken JSON, it tracks all transformations via a flag system and provides confidence scores, making LLM integrations robust in production.

## Features

### 🔧 Three-Phase Parsing

1. **Strip & Fix**: Quick string transformations
   - Remove markdown code fences (`````json ... ```)
   - Fix trailing commas (`{...,}` → `{...}`)
   - Normalize quotes (`'...'` → `"..."`)
   - Remove BOM and control characters
   - Fix unquoted keys (optional with `regex-support` feature)

2. **Standard Parse**: Fast path using `serde_json`
   - If JSON is valid after Strip & Fix, use standard parser
   - Optimal performance for slightly malformed inputs

3. **Lenient Parse**: State machine for deeply broken JSON
   - Character-by-character parsing
   - Auto-close unclosed structures
   - Handle incomplete streaming responses
   - Truncate to last valid object/array

### 📊 Confidence Scoring

Every parse result includes a confidence score (0.0-1.0):

- **1.0**: Perfect JSON, no healing needed
- **0.95-0.99**: Minor fixes (markdown, trailing commas)
- **0.85-0.94**: Quote normalization or simple fixes
- **0.70-0.84**: Type coercion or truncation
- **<0.70**: Significant healing required

### 🏷️ Transparency via Flags

All transformations are tracked with `CoercionFlag`:

- `StrippedMarkdown` - Removed code fences
- `FixedTrailingComma` - Removed trailing commas
- `FixedQuotes` - Normalized single quotes to double
- `FixedUnquotedKeys` - Added quotes to object keys
- `FixedControlCharacters` - Removed control characters
- `RemovedBom` - Removed byte order mark
- `TruncatedJson` - Truncated incomplete JSON

## Usage

### Basic Example

```rust
use simple_agents_healing::prelude::*;

let parser = JsonishParser::new();

// Parse markdown-wrapped JSON
let malformed = r#"```json
{"name": "Alice", "age": 30,}
```"#;

let result = parser.parse(malformed)?;

// Access parsed value
assert_eq!(result.value["name"], "Alice");
assert_eq!(result.value["age"], 30);

// Check confidence and flags
assert!(result.confidence > 0.85);
assert!(result.flags.contains(&CoercionFlag::StrippedMarkdown));
assert!(result.flags.contains(&CoercionFlag::FixedTrailingComma));
```

### Custom Configuration

```rust
use simple_agents_healing::prelude::*;

let config = ParserConfig {
    strip_markdown: true,
    fix_trailing_commas: true,
    fix_quotes: true,
    fix_unquoted_keys: false,
    fix_control_chars: true,
    remove_bom: true,
    min_confidence: 0.8,  // Reject results below 0.8
};

let parser = JsonishParser::with_config(config);
let result = parser.parse(input)?;
```

### Confidence Thresholds

```rust
use simple_agents_healing::prelude::*;

let strict_config = ParserConfig {
    min_confidence: 0.95,
    ..Default::default()
};

let parser = JsonishParser::with_config(strict_config);

match parser.parse(input) {
    Ok(result) => {
        println!("High confidence: {}", result.confidence);
    }
    Err(SimpleAgentsError::Healing(HealingError::LowConfidence { .. })) => {
        println!("Confidence too low, requires review");
    }
    Err(e) => {
        println!("Parse failed: {}", e);
    }
}
```

## Examples

Run the included examples:

```bash
# Basic healing demonstration
cargo run --example basic_healing
```

## Testing

```bash
# Run all tests
cargo test -p simple-agents-healing

# Run with coverage
cargo test -p simple-agents-healing --all-features

# Run clippy
cargo clippy -p simple-agents-healing -- -D warnings
```

## Architecture

### Parser Components

```
Input String
┌─────────────────────┐
│  Strip & Fix Phase  │ ← Remove markdown, fix commas, quotes
└─────────────────────┘
┌─────────────────────┐
│   Standard Parse    │ ← Try serde_json (fast path)
└─────────────────────┘
    ↓ (if fails)
┌─────────────────────┐
│   Lenient Parse     │ ← State machine for broken JSON
└─────────────────────┘
CoercionResult<Value>
```

### Flag System

Every transformation is tracked:

```rust
pub enum CoercionFlag {
    StrippedMarkdown,
    FixedTrailingComma,
    FixedQuotes,
    FixedUnquotedKeys,
    FixedControlCharacters,
    RemovedBom,
    TruncatedJson,
    // More flags for coercion engine (future)
}
```

### Confidence Calculation

```rust
confidence = 1.0
             * (markdown_stripped ? 0.95 : 1.0)
             * (trailing_comma_fixed ? 0.95 : 1.0)
             * (quotes_fixed ? 0.90 : 1.0)
             * (unquoted_keys_fixed ? 0.85 : 1.0)
             * (truncated ? 0.70 : 1.0)
```

## Future Features

### Week 6 (Planned)

- **Coercion Engine**: Type coercion with schema validation
  - String → Number coercion
  - Fuzzy field matching (case-insensitive, snake_case ↔ camelCase)
  - Union resolution with best-match selection
  - Default value injection

- **Streaming Parser**: Incremental parsing
  - Partial value extraction from incomplete buffers
  - Progressive emission during streaming
  - Annotation support (`stream.not_null`, `stream.done`)

## Performance

- **Fast path**: Standard `serde_json` for valid JSON after Strip & Fix
- **Zero allocations**: In-place string transformations where possible
- **Minimal overhead**: Flags are small enums, confidence is a single f32

## Safety

- **No unsafe code**: 100% safe Rust
- **No panics**: All errors are `Result` types
- **Send + Sync**: Parser can be shared across threads

## Credits

Inspired by [BAML's Jsonish parser](https://github.com/BoundaryML/baml) and coercion system.

## License

MIT OR Apache-2.0