# FAL Provider

FAL provides ultra-fast inference for image and video generation models. Known for speed optimization and support for latest models including FLUX, Stable Diffusion, and video generation.

## Setup

### Installation

```go
import (
    "github.com/digitallysavvy/go-ai/pkg/ai"
    "github.com/digitallysavvy/go-ai/pkg/providers/fal"
)
```

### Configuration

```go
provider := fal.New(fal.Config{
    APIKey:  os.Getenv("FAL_API_KEY"),
    Headers: map[string]string{"X-Custom": "value"},
})

model, err := provider.ImageModel("fal-ai/flux-pro")
```

`fal.Config.APIKey` falls back to the `FAL_API_KEY` environment variable,
then to `FAL_KEY`, if left empty. `fal.Config.Headers` are sent on every
request across image, video, speech, and transcription models.

> **Breaking change:** the default base URL is now `https://fal.run` (was
> `https://fal.run/fal-ai`, which doubled the path for fully-qualified model
> IDs and broke default-config requests). Always pass fully-qualified model
> IDs like `fal-ai/fast-sdxl`, not `fast-sdxl`. The image and video default
> models are `fal-ai/fast-sdxl` and `fal-ai/luma-ray`.

### Get API Key

```bash
export FAL_API_KEY=...
```

## Available Models

### Image Generation

| Model ID | Quality | Speed | Price | Best For |
|----------|---------|-------|-------|----------|
| fal-ai/flux-pro | Excellent | Fast | $0.05/image | High quality |
| fal-ai/flux-schnell | Good | Very Fast | $0.003/image | Speed |
| fal-ai/stable-diffusion-xl | High | Fast | $0.03/image | General |

### Video Generation

| Model ID | Quality | Speed | Price | Best For |
|----------|---------|-------|-------|----------|
| fal-ai/stable-video-diffusion | Medium | Medium | $0.10/video | Video from image |
| fal-ai/runway-gen3 | High | Slow | $0.50/video | High quality video |

## Provider-Specific Features

### Ultra-Fast Inference

FAL optimizes for speed:

```go
start := time.Now()
result, err := ai.GenerateImage(ctx, ai.GenerateImageOptions{
    Model:  model,
    Prompt: "A sunset over mountains",
})
elapsed := time.Since(start)
fmt.Printf("Generated in %v\n", elapsed) // ~1-2 seconds
```

### Video Generation

Create videos from text or images:

```go
videoModel, err := provider.VideoModel("fal-ai/stable-video-diffusion")

// Generate from image
initImage, _ := os.ReadFile("frame.png")

fps := 10
result, err := ai.GenerateVideo(ctx, ai.GenerateVideoOptions{
    Model: videoModel,
    Prompt: ai.VideoPrompt{
        Image: &ai.VideoPromptImage{Data: initImage},
    },
    FPS: &fps,
    ProviderOptions: map[string]interface{}{
        "fal": map[string]interface{}{
            "frames": 25,
        },
    },
})

os.WriteFile("output.mp4", result.Video.Data, 0644)
```

### Async Video And Webhooks

`fal.VideoModel` implements `provider.VideoModelStarter` /
`VideoModelStatusChecker`, so it also works with `ai.ExperimentalStartVideo`
/ `ai.ExperimentalGetVideoStatus`, and can complete via a webhook instead of
polling:

```go
started, err := ai.ExperimentalStartVideo(ctx, ai.StartVideoOptions{
    Model:      videoModel,
    Prompt:     ai.VideoPrompt{Text: "A cat playing piano"},
    WebhookURL: "https://example.com/fal-webhook",
})
```

### Speech and Transcription

```go
speechModel, err := provider.SpeechModel("fal-ai/minimax/speech-02-hd")
if err != nil {
    log.Fatal(err)
}

result, err := ai.GenerateSpeech(ctx, ai.GenerateSpeechOptions{
    Model: speechModel,
    Text:  "Hello from Fal.",
})
```

```go
transcriptionModel, err := provider.TranscriptionModel("fal-ai/wizper")
if err != nil {
    log.Fatal(err)
}

transcript, err := ai.Transcribe(ctx, ai.TranscribeOptions{
    Model: transcriptionModel,
    Audio: audioBytes,
})
```

Fal does not support reranking — `provider.RerankingModel` returns an error.

## Examples

### Basic Image Generation

```go
package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "time"

    "github.com/digitallysavvy/go-ai/pkg/ai"
    "github.com/digitallysavvy/go-ai/pkg/providers/fal"
)

func main() {
    provider := fal.New(fal.Config{
        APIKey: os.Getenv("FAL_KEY"),
    })

    model, err := provider.ImageModel("fal-ai/flux-schnell")
    if err != nil {
        log.Fatal(err)
    }

    start := time.Now()
    result, err := ai.GenerateImage(context.Background(), ai.GenerateImageOptions{
        Model:  model,
        Prompt: "A peaceful zen garden",
    })
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Generated in %v\n", time.Since(start))
    os.WriteFile("garden.png", result.Images[0].Data, 0644)
}
```

### Fast Batch Generation

```go
prompts := []string{
    "A red apple",
    "A green apple",
    "A yellow apple",
}

// Parallel generation
var wg sync.WaitGroup
for i, prompt := range prompts {
    wg.Add(1)
    go func(idx int, p string) {
        defer wg.Done()

        result, err := ai.GenerateImage(context.Background(), ai.GenerateImageOptions{
            Model:  model,
            Prompt: p,
        })
        if err != nil {
            return
        }

        filename := fmt.Sprintf("apple_%d.png", idx)
        os.WriteFile(filename, result.Images[0].Data, 0644)
    }(i, prompt)
}
wg.Wait()
```

## Best Practices

1. **Speed Optimization**
   - Use flux-schnell for rapid iteration
   - Parallel requests for batches
   - Leverage fast inference for real-time apps

2. **Quality vs Speed**
   - Use schnell for previews
   - Use pro for finals
   - Balance based on use case

3. **Cost Management**
   - Schnell is very cost-effective
   - Cache results
   - Use for high-volume applications

## Rate Limits & Pricing

Check dashboard for current limits and pricing.

## Workflow Serialization

Fal image, speech, and transcription models can cross a workflow boundary
with `provider.SerializeImageModel` / `DeserializeImageModel`,
`provider.SerializeSpeechModel` / `DeserializeSpeechModel`, and
`provider.SerializeTranscriptionModel` / `DeserializeTranscriptionModel`. See
[Provider Serialization](https://goaisdk.com/docs/agents/workflow-agent.md#provider-serialization)
for the mechanism; video models are not yet serializable.

## See Also

- [API Reference: GenerateImage](https://goaisdk.com/docs/reference/ai/generate-image.md)
- [FAL Documentation](https://fal.ai/docs)
