# Roovy SDK

A Python SDK for generating WhatsApp Flows using LLMs. Generate valid,
schema-compliant WhatsApp Flow JSON from natural language descriptions.

## Features

- 🚀 **Simple API** - Generate WhatsApp Flows with a single function call
- ✅ **Schema Validation** - Built-in Pydantic models ensure valid output
- 🔄 **Auto-Retry** - Automatic retries with error feedback for better results
- 📡 **Streaming Support** - Stream responses for real-time feedback
- 🔌 **Provider Agnostic** - Works with OpenAI, Groq, Ollama, or any
  OpenAI-compatible API
- 📝 **Type Safe** - Full type hints and Pydantic models

## Installation

```bash
pip install roovy-sdk
```

## Quick Start

```python
from roovy_sdk import RoovyClient

# Initialize with your preferred provider
client = RoovyClient(
    api_key="your-api-key",
    base_url="https://api.openai.com/v1",  # or any OpenAI-compatible endpoint
    model="gpt-4o",
)

# Generate a WhatsApp Flow from natural language
flow = client.generate(
    "Create a customer feedback form with name, email, rating (1-5 stars), and comments"
)

# Access the validated flow
print(flow.model_dump_json(indent=2, by_alias=True))
```

## Configuration

### Using Environment Variables

```python
import os
from roovy_sdk import RoovyClient

# Set environment variables
os.environ["ROOVY_API_KEY"] = "your-api-key"
os.environ["ROOVY_BASE_URL"] = "https://api.openai.com/v1"
os.environ["ROOVY_MODEL"] = "gpt-4o"

# Client will use environment variables automatically
client = RoovyClient()
```

### Provider Examples

**OpenAI:**

```python
client = RoovyClient(
    api_key="sk-...",
    base_url="https://api.openai.com/v1",
    model="gpt-4o",
)
```

**Groq:**

```python
client = RoovyClient(
    api_key="gsk_...",
    base_url="https://api.groq.com/openai/v1",
    model="llama-3.3-70b-versatile",
)
```

**Ollama (local):**

```python
client = RoovyClient(
    api_key="ollama",  # any non-empty string
    base_url="http://localhost:11434/v1",
    model="llama3.2",
)
```

## Advanced Usage

### Streaming Generation

```python
def on_chunk(chunk: str):
    print(chunk, end="", flush=True)

flow = client.generate_stream(
    "Create a booking form for a concert",
    on_chunk=on_chunk,
)
```

### Custom Retry Settings

```python
flow = client.generate(
    "Create a survey form",
    max_retries=5,
    temperature=0.3,
)
```

### Custom System Prompt

```python
flow = client.generate(
    "Create a registration form",
    system_prompt="You are a WhatsApp Flows expert...",
)
```

### Direct Schema Access

```python
from roovy_sdk.schema import (
    WhatsAppFlow,
    Screen,
    TextInput,
    Footer,
    validate_flow,
)

# Build flows programmatically
screen = Screen(
    id="WELCOME",
    title="Welcome",
    layout=SingleColumnLayout(
        type="SingleColumnLayout",
        children=[
            TextHeading(type="TextHeading", text="Hello!"),
        ]
    )
)

# Validate any JSON against the schema
result = validate_flow({"version": "7.2", "screens": [...]})
if result["success"]:
    flow = result["data"]
```

## Schema Reference

The SDK includes complete Pydantic models for all WhatsApp Flow components:

### Text Components

- `TextHeading` - Main headings
- `TextSubheading` - Subheadings
- `TextBody` - Body text
- `TextCaption` - Small captions

### Input Components

- `TextInput` - Single-line text input
- `TextArea` - Multi-line text input
- `Dropdown` - Dropdown selector
- `RadioButtonsGroup` - Radio button selection
- `ChipsSelector` - Multi-select chips
- `CheckboxGroup` - Checkbox group
- `OptIn` - Opt-in checkbox

### Date/Media Components

- `CalendarPicker` - Calendar date picker
- `DatePicker` - Simple date picker
- `PhotoPicker` - Photo upload
- `DocumentPicker` - Document upload
- `Image` - Display images

### Navigation Components

- `Footer` - Screen footer with action
- `Button` - Action button
- `EmbeddedLink` - Inline link

### Conditional Components

- `If` - Conditional rendering
- `Switch` - Switch/case rendering

### Container Components

- `Form` - Form container
- `SingleColumnLayout` - Screen layout

## API Reference

### `RoovyClient`

```python
RoovyClient(
    api_key: str | None = None,      # API key (or ROOVY_API_KEY env var)
    base_url: str | None = None,     # Base URL (or ROOVY_BASE_URL env var)
    model: str | None = None,        # Model name (or ROOVY_MODEL env var)
)
```

### `client.generate()`

```python
client.generate(
    prompt: str,                     # Natural language description
    *,
    max_retries: int = 3,           # Number of retry attempts
    temperature: float = 0.2,        # LLM temperature
    system_prompt: str | None = None, # Custom system prompt
) -> WhatsAppFlow
```

### `client.generate_stream()`

```python
client.generate_stream(
    prompt: str,                     # Natural language description
    on_chunk: Callable[[str], None] | None = None,  # Chunk callback
    *,
    temperature: float = 0.2,        # LLM temperature
    system_prompt: str | None = None, # Custom system prompt
) -> WhatsAppFlow
```

### `validate_flow()`

```python
from roovy_sdk import validate_flow

result = validate_flow(flow_dict)
# Returns: {"success": True, "data": WhatsAppFlow} or {"success": False, "error": ValidationError}
```

## License

MIT License - see [LICENSE](LICENSE) for details.
