> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Amazon Bedrock driver for Laravel AI SDK

> An Amazon Bedrock driver for Laravel AI SDK. Supports text generation, streaming, tool use, structured output, file attachments, conversation history, embeddings, image generation, audio (TTS), and reranking.

## Overview

[revolution/laravel-amazon-bedrock](https://github.com/invokable/laravel-amazon-bedrock) is a driver that lets you use Amazon Bedrock through the [Laravel AI SDK](https://laravel.com/docs/ai-sdk). You can access multiple Bedrock models through one Laravel AI SDK interface.

| Feature                     | Available with Bedrock API key only | Supported models / services                                                                                  |
| --------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| Text generation / streaming | ✅                                   | Anthropic Claude, Amazon Nova, and most Bedrock models (all via Converse API)                                |
| Tool use (Function Calling) | ✅                                   |                                                                                                              |
| Structured output           | ✅                                   |                                                                                                              |
| File attachments            | ✅                                   | Image, document, audio, and video attachments via Converse API (model support varies)                        |
| Image generation            | ✅                                   | Stability AI (default), Amazon Nova Canvas (deprecated)                                                      |
| Audio (TTS)                 | ⚠️                                  | Amazon Polly (generative, neural, long-form, standard engines)                                               |
| Transcription (STT)         | ❌                                   | Not supported                                                                                                |
| Embeddings                  | ✅                                   | Amazon Titan Embeddings V2 (default), Cohere Embed English/Multilingual V3, Cohere Embed V4 (batch support). |
| Reranking                   | ⚠️                                  | Cohere Rerank 3.5, Amazon Rerank 1.0                                                                         |
| Files                       | ✅                                   | Local file attachments supported via text generation; server-side upload and `fromId()` not supported        |

<Info>
  `⚠️` in this table means the feature is not available with only a Bedrock API key. It does not mean the feature itself is unsupported.
</Info>

<Info>
  Laravel AI SDK v0.6.3 added official Bedrock support for Text, Image, and Embeddings using a Bedrock API key. This package continues to be published because it also supports Audio (TTS via Amazon Polly) and Reranking — features not available through the official integration.
</Info>

Key characteristics:

* **Authentication**: Bedrock API key, AWS IAM credentials (SigV4), or default AWS credential chain (IAM roles, instance profiles, etc.).
* **Failover**: Supports the AI SDK's multi-provider failover. Rate limit (429), overload (503, 529), and credit errors are mapped to failoverable exceptions.
* **Cache control**: Ephemeral cache is always enabled on system prompts via the [Bedrock Converse API](https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference.html).
* **Unified API**: All models — Anthropic Claude, Amazon Nova, Meta Llama, Mistral, and more — are routed through the Bedrock Converse API for a consistent interface.

## Requirements

* PHP >= 8.3
* Laravel >= 12.x

## Installation

<Steps>
  <Step title="Install the package">
    ```bash theme={null}
    composer require revolution/laravel-amazon-bedrock
    ```
  </Step>

  <Step title="Publish AI SDK configuration">
    ```bash theme={null}
    php artisan vendor:publish --provider="Laravel\Ai\AiServiceProvider"
    ```
  </Step>
</Steps>

## Configuration

Add the `amazon-bedrock` provider to `config/ai.php`. Switch your default providers to Bedrock if needed.

```php theme={null}
'default' => 'amazon-bedrock',
'default_for_images' => 'amazon-bedrock',
'default_for_audio' => 'amazon-bedrock',
'default_for_embeddings' => 'amazon-bedrock',
'default_for_reranking' => 'amazon-bedrock',
```

### Option 1: Bedrock API key

```php theme={null}
'providers' => [
    'amazon-bedrock' => [
        'driver' => 'amazon-bedrock',
        'key'    => env('AWS_BEDROCK_API_KEY', ''),
        'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
    ],
],
```

```dotenv theme={null}
AWS_BEDROCK_API_KEY=your_api_key
AWS_DEFAULT_REGION=us-east-1
```

The Bedrock API key is obtained from the AWS Management Console.

<Warning>
  A Bedrock API key only works for the Bedrock Runtime API. It does not work with reranking (`bedrock-agent-runtime`) or Amazon Polly (TTS). Use SigV4 or the default AWS credential chain for those features.
</Warning>

### Option 2: AWS IAM credentials (SigV4)

Use an AWS access key and secret key signed with [Signature Version 4](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html).

```php theme={null}
'providers' => [
    'amazon-bedrock' => [
        'driver' => 'amazon-bedrock',
        'key'    => env('AWS_ACCESS_KEY_ID'),
        'secret' => env('AWS_SECRET_ACCESS_KEY'),
        'token'  => env('AWS_SESSION_TOKEN'),
        'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
    ],
],
```

```dotenv theme={null}
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=wJalr...
AWS_SESSION_TOKEN= # optional, for STS temporary credentials
AWS_DEFAULT_REGION=us-east-1
```

<Info>
  Set `AWS_SESSION_TOKEN` only when you use temporary credentials (STS).
</Info>

### Option 3: Default AWS credential chain (IAM roles)

For EC2 instances, ECS tasks, Lambda functions, or any environment with IAM roles — omit `key` and `secret` to use the [default AWS credential provider chain](https://docs.aws.amazon.com/sdkref/latest/guide/standardized-credentials.html).

```php theme={null}
'providers' => [
    'amazon-bedrock' => [
        'driver' => 'amazon-bedrock',
        'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
    ],
],
```

```dotenv theme={null}
AWS_DEFAULT_REGION=us-east-1
```

The default credential chain automatically resolves credentials from environment variables, shared credentials files (`~/.aws/credentials`), ECS task roles, EC2 instance profiles, and more.

### Optional config keys

| Key                            | Description                     | Default                                           |
| ------------------------------ | ------------------------------- | ------------------------------------------------- |
| `secret`                       | AWS secret access key (SigV4)   | —                                                 |
| `token`                        | AWS session token (SigV4)       | —                                                 |
| `timeout`                      | HTTP request timeout in seconds | 30                                                |
| `max_tokens`                   | Default max tokens per request  | 8096                                              |
| `models.text.default`          | Default text model              | `global.anthropic.claude-sonnet-4-6`              |
| `models.text.cheapest`         | Cheapest text model             | `global.anthropic.claude-haiku-4-5-20251001-v1:0` |
| `models.text.smartest`         | Smartest text model             | `global.anthropic.claude-opus-4-7`                |
| `models.embeddings.default`    | Default embeddings model        | `amazon.titan-embed-text-v2:0`                    |
| `models.embeddings.dimensions` | Default embedding dimensions    | `1024`                                            |
| `models.image.default`         | Default image model             | `stability.stable-image-core-v1:1`                |
| `models.audio.default`         | Default audio (TTS) engine      | `generative`                                      |
| `models.reranking.default`     | Default reranking model         | `cohere.rerank-v3-5:0`                            |

## Text generation

### Agent class

Create an agent class using the Artisan command.

```bash theme={null}
php artisan make:agent BedrockAgent
```

```php theme={null}
<?php

namespace App\Ai\Agents;

use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Promptable;

class BedrockAgent implements Agent
{
    use Promptable;

    public function instructions(): string
    {
        return 'You are an expert at software development.';
    }
}
```

```php theme={null}
use App\Ai\Agents\BedrockAgent;

$response = (new BedrockAgent)->prompt('Tell me about Laravel');

echo $response->text;
```

### Anonymous Agent

For quick interactions without a dedicated class, use the `agent()` helper.

```php theme={null}
use function Laravel\Ai\agent;

$response = agent(
    instructions: 'You are an expert at software development.',
)->prompt('Tell me about Laravel');

echo $response->text;
```

### Streaming

```php theme={null}
use App\Ai\Agents\BedrockAgent;
use Illuminate\Support\Facades\Route;

Route::get('/stream', function () {
    return (new BedrockAgent)->stream('Tell me about Laravel');
});
```

Or iterate through the events manually.

```php theme={null}
use Laravel\Ai\Streaming\Events\TextDelta;

use function Laravel\Ai\agent;

$stream = agent(
    instructions: 'You are an expert at software development.',
)->stream('Tell me about Laravel');

foreach ($stream as $event) {
    if ($event instanceof TextDelta) {
        echo $event->delta;
    }
}
```

### Tool use (Function Calling)

Define tools the model can invoke during generation.

```php theme={null}
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Ai\Contracts\Tool;
use Laravel\Ai\Tools\Request;

class GetWeather implements Tool
{
    public function description(): string
    {
        return 'Get current weather for a city.';
    }

    public function schema(JsonSchema $schema): array
    {
        return [
            'city' => $schema->string()->required()->description('The city name.'),
        ];
    }

    public function handle(Request $request): string
    {
        // Call your weather API here
        return json_encode(['temperature' => 22, 'condition' => 'sunny']);
    }
}
```

Use the tool from an agent.

```php theme={null}
use App\Ai\Tools\GetWeather;
use Laravel\Ai\Attributes\MaxSteps;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasTools;
use Laravel\Ai\Promptable;

#[MaxSteps(5)]
class WeatherAgent implements Agent, HasTools
{
    use Promptable;

    public function tools(): array
    {
        return [new GetWeather];
    }

    public function instructions(): string
    {
        return 'You are a helpful weather assistant.';
    }
}

$response = (new WeatherAgent)->prompt('What is the weather in Tokyo?');
echo $response->text;
```

Or with an anonymous agent.

```php theme={null}
use function Laravel\Ai\agent;

$response = agent(
    instructions: 'You are a helpful weather assistant.',
    tools: [new GetWeather],
    maxSteps: 5,
)->prompt('What is the weather in Tokyo?');
```

Tool calls also work with streaming — the SDK automatically executes tool calls and continues the conversation until the model produces a final text response.

### File attachments

Attach images, documents, audio, and video files to your prompts using the `attachments` parameter. The Bedrock Converse API handles the attachment blocks — actual format support varies by model (e.g., Anthropic Claude supports images and documents only).

```php theme={null}
use Laravel\Ai\Files\Document;
use Laravel\Ai\Files\Image;

use function Laravel\Ai\agent;

// Attach an image from a local path
$response = agent(
    instructions: 'You are a helpful assistant.',
)->prompt('Describe this image.', attachments: [
    Image::fromPath('/path/to/photo.jpg'),
]);

// Attach a document from a URL
$response = agent(
    instructions: 'You are a helpful assistant.',
)->prompt('Summarize this document.', attachments: [
    Document::fromUrl('https://example.com/report.pdf'),
]);

// Attach a document from a string (with explicit format)
$response = agent(
    instructions: 'You are a helpful assistant.',
)->prompt('Analyze this text.', attachments: [
    Document::fromString($csvContent, 'text/csv')->as('data.csv'),
]);
```

Supported attachment types: `Image`, `Document`, and `Audio` (via `Laravel\Ai\Files\*`). Video attachments are supported through `Illuminate\Http\UploadedFile`.

<Info>
  Server-side file upload (`Document::fromPath()->put()`) and reuse by ID (`Document::fromId()`) are not supported on Bedrock.
</Info>

### Conversation history

Maintain multi-turn conversations by implementing the `Conversational` interface in your agent class. The `messages()` method returns the previous conversation messages, which are automatically included in each prompt.

```php theme={null}
<?php

namespace App\Ai\Agents;

use App\Models\ChatHistory;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\Conversational;
use Laravel\Ai\Messages\Message;
use Laravel\Ai\Promptable;

class ChatAgent implements Agent, Conversational
{
    use Promptable;

    public function __construct(public int $userId) {}

    public function instructions(): string
    {
        return 'You are a helpful assistant.';
    }

    public function messages(): iterable
    {
        return ChatHistory::where('user_id', $this->userId)
            ->latest()
            ->limit(20)
            ->get()
            ->reverse()
            ->map(fn ($m) => new Message($m->role, $m->content))
            ->all();
    }
}
```

```php theme={null}
$response = (new ChatAgent(auth()->id()))->prompt('What did we discuss earlier?');
```

#### Automatic conversation storage with `RemembersConversations`

For fully automatic conversation persistence (no manual `messages()` implementation needed), use the `RemembersConversations` trait. This requires the AI SDK database tables — run `php artisan vendor:publish --provider="Laravel\Ai\AiServiceProvider" && php artisan migrate` first.

```php theme={null}
<?php

namespace App\Ai\Agents;

use Laravel\Ai\Concerns\RemembersConversations;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\Conversational;
use Laravel\Ai\Promptable;

class ChatAgent implements Agent, Conversational
{
    use Promptable, RemembersConversations;

    public function instructions(): string
    {
        return 'You are a helpful assistant.';
    }
}
```

Start a new conversation for a user.

```php theme={null}
$response = (new ChatAgent)->forUser($user)->prompt('Hello!');

$conversationId = $response->conversationId;
```

Continue an existing conversation.

```php theme={null}
$response = (new ChatAgent)
    ->continue($conversationId, as: $user)
    ->prompt('Tell me more about that.');
```

The Bedrock driver automatically includes conversation history in Bedrock Converse API requests, so all supported models benefit from multi-turn conversation context.

### Structured output

Get structured (typed) responses from the model using the `HasStructuredOutput` interface.

```php theme={null}
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasStructuredOutput;
use Laravel\Ai\Promptable;

class ExtractPerson implements Agent, HasStructuredOutput
{
    use Promptable;

    public function instructions(): string
    {
        return 'Extract person information from the given text.';
    }

    public function schema(JsonSchema $schema): array
    {
        return [
            'name' => $schema->string()->description('The person\'s full name'),
            'age' => $schema->integer()->description('The person\'s age'),
            'occupation' => $schema->string()->description('The person\'s occupation'),
        ];
    }
}

$response = (new ExtractPerson)->prompt('John is a 30-year-old software engineer.');

echo $response['name'];       // "John"
echo $response['age'];        // 30
echo $response['occupation']; // "software engineer"
```

Or with an anonymous structured agent.

```php theme={null}
use function Laravel\Ai\agent;

$response = agent(
    instructions: 'Extract person information from the given text.',
    schema: fn (JsonSchema $schema) => [
        'name' => $schema->string()->description('The person\'s full name'),
        'age' => $schema->integer()->description('The person\'s age'),
    ],
)->prompt('Alice is 25 years old.');

echo $response['name']; // "Alice"
echo $response['age'];  // 25
```

Under the hood, the driver creates a synthetic tool (`output_structured_data`) that forces the model to return data matching your schema. This approach is compatible with all models on Bedrock via the Converse API.

### Converse API (all models)

All text generation and streaming is routed through the [Bedrock Converse API](https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference.html), including Anthropic Claude models. This gives a unified interface to Anthropic Claude, Amazon Nova, Meta Llama, Mistral, Cohere, DeepSeek, and other models available on Bedrock.

```php theme={null}
use function Laravel\Ai\agent;

// Anthropic Claude (uses Converse API)
$response = agent(
    instructions: 'You are an expert at software development.',
    model: 'global.anthropic.claude-sonnet-4-6',
)->prompt('Tell me about Laravel.');

// Amazon Nova
$response = agent(
    instructions: 'You are a helpful assistant.',
    model: 'amazon.nova-pro-v1:0',
)->prompt('Tell me about AWS.');

// Meta Llama
$response = agent(
    instructions: 'You are a helpful assistant.',
    model: 'meta.llama3-1-70b-instruct-v1:0',
)->prompt('Explain quantum computing.');

// Mistral
$response = agent(
    instructions: 'You are a helpful assistant.',
    model: 'mistral.mistral-large-2402-v1:0',
)->prompt('Write a haiku about coding.');

// Cohere Command R+
$response = agent(
    instructions: 'You are a helpful assistant.',
    model: 'cohere.command-r-plus-v1:0',
)->prompt('Summarize this text.');

// DeepSeek R1
$response = agent(
    instructions: 'You are a helpful assistant.',
    model: 'deepseek.r1-v1:0',
)->prompt('Solve this math problem.');
```

Streaming, tool use, structured output, and file attachments work with models that support those features. See the [Bedrock supported models table](https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference-supported-models-features.html) for feature availability per model.

### Provider options

To pass Bedrock-specific options such as `anthropic_version`, implement `HasProviderOptions`.

```php theme={null}
<?php

namespace App\Ai\Agents;

use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasProviderOptions;
use Laravel\Ai\Enums\Lab;
use Laravel\Ai\Promptable;

class BedrockAgent implements Agent, HasProviderOptions
{
    use Promptable;

    public function instructions(): string
    {
        return 'You are an expert at software development.';
    }

    public function providerOptions(Lab|string $provider): array
    {
        return [
            'top_p' => 0.9,
        ];
    }
}
```

Supported provider options:

| Option                         | Description                              | Default |
| ------------------------------ | ---------------------------------------- | ------- |
| `top_k`                        | Top-K sampling parameter                 | —       |
| `top_p`                        | Top-P (nucleus) sampling parameter       | —       |
| `additionalModelRequestFields` | Converse API additional model parameters | —       |

### Agent configuration attributes

Configure text generation options using PHP attributes.

```php theme={null}
use Laravel\Ai\Attributes\MaxTokens;
use Laravel\Ai\Attributes\Temperature;
use Laravel\Ai\Attributes\Timeout;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Promptable;

#[MaxTokens(4096)]
#[Temperature(0.7)]
#[Timeout(120)]
class BedrockAgent implements Agent
{
    use Promptable;

    // ...
}
```

## Image generation

Generate images using Stability AI models (default) or Amazon Nova Canvas.

```php theme={null}
use Laravel\Ai\Image;
use Revolution\Amazon\Bedrock\Bedrock;

// Uses Stability AI Stable Image Core by default
$response = Image::of('A cute steampunk robot')->generate(provider: Bedrock::KEY);

// Get the first image
$image = $response->firstImage();

// Store image to disk
$response->store('images', 's3');

// Render as HTML <img> tag
echo $response->toHtml('Steampunk robot');
```

Available Stability AI models (all require `us-west-2` region):

```php theme={null}
// Stable Image Core — fast and affordable (default)
$response = Image::of('A landscape')
    ->generate(provider: Bedrock::KEY, model: 'stability.stable-image-core-v1:1');

// Stable Diffusion 3.5 Large — high quality, high quantity
$response = Image::of('A portrait')
    ->generate(provider: Bedrock::KEY, model: 'stability.sd3-5-large-v1:0');

// Stable Image Ultra — ultra-realistic, highest quality
$response = Image::of('A luxury product')
    ->generate(provider: Bedrock::KEY, model: 'stability.stable-image-ultra-v1:1');
```

<Info>
  All Stability AI image models are available in `us-west-2` only. Configure `AWS_DEFAULT_REGION=us-west-2` when using these models.
</Info>

### Image editing with Stability AI

Stability AI Image Services editing models are also supported via the `attachments()` method. Pass an input image and use an editing model to transform it.

```php theme={null}
use Laravel\Ai\Files\Image as ImageFile;
use Laravel\Ai\Image;
use Revolution\Amazon\Bedrock\Bedrock;

$inputImage = ImageFile::fromPath('/path/to/photo.jpg');

// Inpaint — fill in or replace areas using a mask or alpha channel
$response = Image::of('Replace the background with a forest')
    ->attachments([$inputImage])
    ->generate(provider: Bedrock::KEY, model: 'stability.stable-image-inpaint-v1:0');

// Erase — remove unwanted elements from an image
$response = Image::of('')
    ->attachments([$inputImage])
    ->generate(provider: Bedrock::KEY, model: 'stability.stable-image-erase-object-v1:0');

// Remove background — isolate the subject
$response = Image::of('')
    ->attachments([$inputImage])
    ->generate(provider: Bedrock::KEY, model: 'stability.stable-image-remove-background-v1:0');

// Search and replace — replace an object described in the prompt
$response = Image::of('a cat')
    ->attachments([$inputImage])
    ->generate(provider: Bedrock::KEY, model: 'stability.stable-image-search-replace-v1:0');

// Style transfer — apply a style from the prompt
$response = Image::of('Oil painting style')
    ->attachments([$inputImage])
    ->generate(provider: Bedrock::KEY, model: 'stability.stable-style-transfer-v1:0');
```

Available Stability AI editing models (all available in `us-east-1`, `us-east-2`, `us-west-2`):

| Model ID                                        | Description                                      |
| ----------------------------------------------- | ------------------------------------------------ |
| `stability.stable-image-inpaint-v1:0`           | Inpaint — fill/replace selected areas            |
| `stability.stable-outpaint-v1:0`                | Outpaint — expand the image beyond its borders   |
| `stability.stable-image-erase-object-v1:0`      | Erase — remove objects from an image             |
| `stability.stable-image-remove-background-v1:0` | Remove background                                |
| `stability.stable-image-search-replace-v1:0`    | Search and Replace — replace a described object  |
| `stability.stable-image-search-recolor-v1:0`    | Search and Recolor — change an object's color    |
| `stability.stable-image-style-guide-v1:0`       | Style Guide — apply a style reference image      |
| `stability.stable-style-transfer-v1:0`          | Style Transfer — transfer an art style           |
| `stability.stable-image-control-sketch-v1:0`    | Control Sketch — generate from a sketch          |
| `stability.stable-image-control-structure-v1:0` | Control Structure — follow a structural guide    |
| `stability.stable-creative-upscale-v1:0`        | Creative Upscale — upscale with reimagining      |
| `stability.stable-conservative-upscale-v1:0`    | Conservative Upscale — upscale preserving detail |
| `stability.stable-fast-upscale-v1:0`            | Fast Upscale — lightweight 4× upscaling          |

Amazon Nova Canvas is also supported but is being deprecated by AWS.

```php theme={null}
// Nova Canvas (deprecated — available in us-east-1, ap-northeast-1, eu-west-1)
$response = Image::of('A sunset')
    ->size('3:2')           // '1:1', '3:2', or '2:3'
    ->quality('high')       // 'low', 'medium', or 'high' (Nova Canvas only)
    ->generate(provider: Bedrock::KEY, model: 'amazon.nova-canvas-v1:0');
```

## Audio (TTS)

Generate speech audio from text using [Amazon Polly](https://docs.aws.amazon.com/polly/latest/dg/what-is.html).

```php theme={null}
use Laravel\Ai\Audio;
use Revolution\Amazon\Bedrock\Bedrock;

$response = Audio::of('I love coding with Laravel.')->generate(provider: Bedrock::KEY);

$rawContent = (string) $response;
```

Pick a male or female voice.

```php theme={null}
$response = Audio::of('I love coding with Laravel.')
    ->female()
    ->generate(provider: 'bedrock');

$response = Audio::of('I love coding with Laravel.')
    ->male()
    ->generate(provider: Bedrock::KEY);
```

Use a specific [Polly voice](https://docs.aws.amazon.com/polly/latest/dg/voicelist.html).

```php theme={null}
$response = Audio::of('I love coding with Laravel.')
    ->voice('Joanna')
    ->generate(provider: Bedrock::KEY);
```

Store the generated audio.

```php theme={null}
$response = Audio::of('I love coding with Laravel.')->generate(provider: Bedrock::KEY);

$path = $response->store();
$path = $response->storeAs('audio.mp3');
```

Specify a different engine (model).

```php theme={null}
// Available engines: generative (default), neural, long-form, standard
$response = Audio::of('I love coding with Laravel.')
    ->generate(provider: Bedrock::KEY, model: 'neural');
```

**Default voices:** `default-female` → Ruth, `default-male` → Matthew (both support the generative engine).

<Warning>
  Amazon Polly is a separate AWS service from Bedrock. The Bedrock API key (bearer token) cannot be used with Polly. Use AWS IAM credentials (SigV4) or the default AWS credential chain instead.
</Warning>

## Embeddings

Generate vector embeddings using Amazon Titan Embeddings V2.

```php theme={null}
use Laravel\Ai\Embeddings;
use Revolution\Amazon\Bedrock\Bedrock;

$response = Embeddings::for(['Hello world', 'Foo bar'])->generate(provider: Bedrock::KEY);

// Access first embedding vector
$vector = $response->first();

// Iterate all embeddings
foreach ($response as $embedding) {
    // $embedding is an array of float values
}

echo $response->tokens; // total token count
```

Specify custom dimensions (256, 512, or 1024 for Titan Embeddings V2).

```php theme={null}
$response = Embeddings::for(['Hello world'])->dimensions(512)->generate(provider: Bedrock::KEY);
```

Use a custom model.

```php theme={null}
$response = Embeddings::for(['Hello world'])
    ->dimensions(1024)
    ->generate(provider: Bedrock::KEY, model: 'amazon.titan-embed-text-v2:0');
```

### Cohere Embed models

Cohere Embed models are automatically detected and use a batch API — all inputs are sent in a single request instead of one request per input, making them more efficient for multiple texts.

```php theme={null}
// Cohere Embed English V3
$response = Embeddings::for(['Hello world', 'Foo bar'])
    ->dimensions(1024)
    ->generate(provider: Bedrock::KEY, model: 'cohere.embed-english-v3');

// Cohere Embed Multilingual V3
$response = Embeddings::for(['Hello', 'こんにちは'])
    ->dimensions(1024)
    ->generate(provider: Bedrock::KEY, model: 'cohere.embed-multilingual-v3');

// Cohere Embed V4 (supports configurable output dimensions 256–1536)
$response = Embeddings::for(['Hello world'])
    ->dimensions(512)
    ->generate(provider: Bedrock::KEY, model: 'cohere.embed-v4');
```

<Info>
  Cohere Embed models do not return token counts — `$response->tokens` will always be `0`.
</Info>

## Reranking

Rerank documents by relevance to a query using Cohere Rerank 3.5 or Amazon Rerank 1.0.

```php theme={null}
use Laravel\Ai\Reranking;
use Revolution\Amazon\Bedrock\Bedrock;

$response = Reranking::of([
    'Laravel is a PHP web framework.',
    'Python is a programming language.',
    'Laravel provides elegant syntax for web development.',
])->rerank(query: 'What is Laravel?', provider: Bedrock::KEY);

// Get the top-ranked document
echo $response->first()->document; // "Laravel is a PHP web framework."
echo $response->first()->score;    // 0.95

// Get all documents in reranked order
foreach ($response as $result) {
    echo "{$result->index}: {$result->document} ({$result->score})\n";
}

// Limit the number of results
$response = Reranking::of([...])
    ->limit(2)
    ->rerank(query: 'What is Laravel?', provider: Bedrock::KEY);
```

Use a custom model.

```php theme={null}
$response = Reranking::of([...])
    ->rerank(query: 'Search query', provider: Bedrock::KEY, model: 'amazon.rerank-v1:0');
```

<Info>
  The reranking API uses the `bedrock-agent-runtime` endpoint (not `bedrock-runtime`). Amazon Rerank 1.0 is not available in `us-east-1` — use Cohere Rerank 3.5 in that region.
</Info>

## Testing

The package supports the standard testing features of the AI SDK.

Although not mentioned in the official documentation, when you use the `agent()` helper you can mock it with `AnonymousAgent::fake()` (or `StructuredAnonymousAgent::fake()` for structured output).

```php theme={null}
use Laravel\Ai\AnonymousAgent;
use Laravel\Ai\Prompts\AgentPrompt;

use function Laravel\Ai\agent;

it('can generate text', function () {
    AnonymousAgent::fake();

    $response = agent(
        instructions: 'You are an expert at software development.',
    )->prompt('Tell me about Laravel');

    AnonymousAgent::assertPrompted(function (AgentPrompt $prompt) {
        return $prompt->contains('Laravel');
    });
});
```

<Info>
  For the latest updates, see the [GitHub repository](https://github.com/invokable/laravel-amazon-bedrock).
</Info>
