# QuiverAI Provider

QuiverAI provides SVG generation and raster-to-SVG vectorization through the Go-AI image model interface.

## Setup

```go
import "github.com/digitallysavvy/go-ai/pkg/providers/quiverai"

qprovider := quiverai.New(quiverai.Config{
    APIKey: "your-api-key",
})
```

`APIKey` defaults to `QUIVERAI_API_KEY`. `BaseURL` defaults to `https://api.quiver.ai/v1` and can be overridden with `QUIVERAI_BASE_URL`.

## SVG Generation

```go
model, _ := qprovider.ImageModel(quiverai.ModelArrow11)

result, err := model.DoGenerate(ctx, &provider.ImageGenerateOptions{
    Prompt: "minimal rocket logo",
})
```

Generated images are returned as SVG bytes, use `image/svg+xml` as the MIME type, and include token usage when QuiverAI reports it.

## Vectorization

```go
result, err := model.DoGenerate(ctx, &provider.ImageGenerateOptions{
    Files: []provider.ImageFile{{
        Type: "url",
        URL:  "https://example.com/logo.png",
    }},
    ProviderOptions: map[string]interface{}{
        "quiverai": map[string]interface{}{
            "operation":  quiverai.OperationVectorize,
            "autoCrop":   true,
            "targetSize": 512,
        },
    },
})
```

## Provider Options

| Option | Type | Description |
| --- | --- | --- |
| `operation` | `generate` or `vectorize` | Selects text-to-SVG generation or raster vectorization. |
| `instructions` | string | Extra style guidance for generation. |
| `temperature` | number | Sampling temperature. |
| `topP` | number | Nucleus sampling value. |
| `presencePenalty` | number | Presence penalty. |
| `maxOutputTokens` | number | Maximum output tokens. |
| `autoCrop` | bool | Vectorization-only auto-crop setting. |
| `targetSize` | number | Vectorization-only target canvas size in pixels. |

## Language Models

The Arrow 2 / Arrow 2 Telos models are available through the standard
language model interface, reusing the Open Responses transport with
QuiverAI's own request policy layered on top:

```go
model, _ := qprovider.LanguageModel(quiverai.ModelArrow2) // or quiverai.ModelArrow2Telos

result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
    Model:  model,
    Prompt: "Suggest a minimal color palette for a weather app icon set.",
    ProviderOptions: map[string]interface{}{
        "quiverai": map[string]interface{}{
            "reasoningEffort":  "medium", // low | medium | high | xhigh
            "reasoningSummary": "auto",
        },
    },
})
```

QuiverAI also supports a caller-executed "custom" tool (`ProviderID:
"quiverai.custom"`), whose input the model streams as raw text (e.g. SVG
markup) instead of JSON function arguments. Build one with
`qprovider.Tools().CustomTool(...)`:

```go
import "github.com/digitallysavvy/go-ai/pkg/providers/openresponses"

svgTool := qprovider.Tools().CustomTool("write_svg", openresponses.CustomToolOptions{
    Description: "Return raw SVG markup for the requested icon.",
    Format:      &openresponses.CustomToolFormat{Type: "text"},
})
```

See [`examples/providers/quiverai`](https://github.com/digitallysavvy/go-ai/tree/main/examples/providers/quiverai) for
full runnable examples.

## Workflow Serialization

QuiverAI image models can cross a workflow boundary with
`provider.SerializeImageModel` / `DeserializeImageModel` (Open Responses
language models can too, via `providerutils.SerializeModel` /
`DeserializeModel`, gated by `provider.SerializableModelStrict` and refused
when extensions are registered). See
[Provider Serialization](https://goaisdk.com/docs/agents/workflow-agent.md#provider-serialization)
for the mechanism.
