# RaySurfer Python SDK

Drop-in replacement for Claude Agent SDK with automatic code caching. Same API, 20-30x faster.

## Install

```bash
pip install raysurfer
```

## Quick Start

Swap `ClaudeSDKClient` for `RaysurferClient` - everything else stays the same:

```python
# from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions
from raysurfer import RaysurferClient, RaysurferAgentOptions

options = RaysurferAgentOptions(
    raysurfer_api_key="your-api-key",
    allowed_tools=["Read", "Write", "Bash"],
    model="claude-sonnet-4-20250514",
)

# async with ClaudeSDKClient(options) as client:
async with RaysurferClient(options) as client:
    await client.query("Generate quarterly sales report")
    async for msg in client.receive_response():
        print(msg)
```

That's it. Your agent now automatically:
- Pre-fetches relevant cached code before each task
- Injects proven code snippets into the system prompt
- Stores successful outputs for future reuse

## How It Works

1. **On `query()`**: Retrieves cached code blocks matching your task
2. **Downloads to sandbox**: Files ready for the agent to execute
3. **Injects into prompt**: Agent sees proven code snippets
4. **After success**: New code is cached for next time

**Measured Results:**
- Without RaySurfer: 34.2s, 11 iterations, 2 tool calls
- With RaySurfer: 1.4s, 1 iteration, 0 tool calls
- **Speedup: 24x faster**

## RaysurferAgentOptions

All `ClaudeAgentOptions` fields are supported, plus:

```python
RaysurferAgentOptions(
    # Raysurfer-specific
    raysurfer_api_key="your-api-key",
    prefetch_count=5,           # Code files to pre-fetch
    min_verdict_score=0.3,      # Quality threshold

    # Standard Claude Agent SDK options
    allowed_tools=["Read", "Write", "Bash"],
    model="claude-sonnet-4-20250514",
    system_prompt="You are helpful.",
    permission_mode="acceptEdits",
    # ... all other ClaudeAgentOptions
)
```

## Low-Level API

For direct code block storage and retrieval:

```python
from raysurfer import RaySurfer

rs = RaySurfer(api_key="your-api-key")

# Store a code block
rs.store_code_block(
    name="fetch_weather",
    source="def fetch_weather(city): ...",
    entrypoint="fetch_weather",
    language="python",
)

# Retrieve by task
results = rs.retrieve("get weather data")
for match in results.code_blocks:
    print(f"{match.code_block.name}: {match.score}")
```

## Verdict System

RaySurfer learns which code actually works through thumbs up/down verdicts:
- A technical error can be thumbs up (correct validation)
- A successful run can be thumbs down (useless output)

The system learns usefulness, not just whether code runs.

## Examples

See [examples/](./examples) for complete demos.
