<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Spryker Documentation</title>
        <description>Spryker documentation center.</description>
        <link>https://docs.spryker.com/</link>
        <atom:link href="https://docs.spryker.com/feed.xml" rel="self" type="application/rss+xml"/>
        <lastBuildDate>Tue, 05 May 2026 12:19:18 +0000</lastBuildDate>
        <generator>Jekyll v4.2.2</generator>
        
        
        <item>
            <title>Resource Schemas</title>
            <description>This document explains how to define API Platform resource schemas in Spryker.

## Schema file structure

API Platform uses YAML files to define resource schemas. Resource schemas describe the structure, operations, and behavior of your API resources.

### Schema location

Resource schemas must be placed in the `resources/api/{api-type}/` directory within your module:

```MARKDOWN
src/
├── Spryker/
│   └── {Module}/
│       └── resources/
│           └── api/
│               ├── storefront/
│               │   └── resource-name.resource.yml
│               └── backend/
│                   └── resource-name.resource.yml
├── SprykerFeature/
│   └── {Feature}/
│       └── resources/
│           └── api/
│               └── backend/
│                   └── resource-name.resource.yml
└── Pyz/
    └── Glue/
        └── {Module}/
            └── resources/
                └── api/
                    └── backend/
                        └── resource-name.resource.yml
```

## CodeBucket resources

API Platform supports CodeBucket-specific resource variants that are resolved at runtime based on the `APPLICATION_CODE_BUCKET` environment constant. This enables Code Bucket-specific API resources without requiring separate container compilations.

### CodeBucket schema file naming

Resource schemas follow the pattern: `{resource-name}.resource.yml`
Validation schemas follow the pattern: `{resource-name}.validation.yml`

CodeBuckets are specified inside the schema files, not in the filename.

```MARKDOWN
src/Pyz/Glue/Store/resources/api/backend/
├── stores.resource.yml              # Resource schema (CodeBucket variants defined inside)
└── stores.validation.yml            # Validation schema (CodeBucket variants defined inside)
```

### Generated class naming

The generator creates classes following the pattern: `{ResourceName}{CodeBucket}{ApiType}Resource`

| Schema File | CodeBucket (defined in file) | Generated Class | CODE_BUCKET Constant |
|-------------|------------------------------|----------------|---------------------|
| `stores.resource.yml` | None (base) | `StoresBackendResource` | Not present (base resource) |
| `stores.resource.yml` | EU | `StoresEUBackendResource` | `&apos;EU&apos;` |
| `stores.resource.yml` | AT | `StoresATBackendResource` | `&apos;AT&apos;` |

### How CodeBucket resolution works

1. **Schema definition**: Define CodeBucket variants inside schema files using `codeBucket: EU`
2. **Constant generation**: Generator adds `public const string CODE_BUCKET = &apos;EU&apos;;` to variant classes
3. **Runtime resolution**: System reads `APPLICATION_CODE_BUCKET` and selects matching resource class
4. **Graceful fallback**: If no matching variant exists, base resource is used

### URL consistency

All CodeBucket variants share the same URL path, with the Code Bucket defined in the domain:

- EU variant: `glue-backend.eu.spryker.local/stores` → `StoresEUBackendResource`
- AT variant: `glue-backend.at.spryker.local/stores` → `StoresATBackendResource`
- DE variant: `glue-backend.de.spryker.local/stores` → `StoresBackendResource` (or `StoresDEBackendResource` if variant exists)

The URL path is identical (`/stores`), but the Code Bucket in the domain determines which resource variant is used. Only properties, validations, and business logic differ between variants.

### When to use CodeBucket resources

Use CodeBucket variants when you need:
- Code Bucket-specific properties (EU GDPR fields, tax rates)
- Code Bucket-specific validation rules
- Country-specific business logic
- Feature variations per Code Bucket

For a comprehensive guide including implementation examples, see [CodeBucket Support](/docs/dg/dev/architecture/api-platform/code-buckets.html).

## Resource schema syntax

### Minimal example

```yaml
resource:
  name: Products
  shortName: Product
  description: &quot;Product resource&quot;

  operations:
    - type: Get
    - type: GetCollection

  properties:
    id:
      type: integer
      writable: false
      identifier: true

    name:
      type: string
```

### Complete example with all options

```yaml
# yaml-language-server: $schema=../../../../SprykerSdk/Api/resources/schemas/api-resource-schema-v1.json

resource:
  # Resource identification
  name: Customers                    # Internal name (used for schema merging)
  shortName: Customer                # URL name (becomes /customers)
  description: &quot;Customer resource&quot;   # OpenAPI description

  # State providers and processors
  provider: &quot;Pyz\\Glue\\Customer\\Api\\Backend\\Provider\\CustomerBackendProvider&quot;
  processor: &quot;Pyz\\Glue\\Customer\\Api\\Backend\\Processor\\CustomerBackendProcessor&quot;

  # Pagination configuration
  paginationEnabled: true
  paginationItemsPerPage: 10
  paginationMaximumItemsPerPage: 100
  paginationClientEnabled: true
  paginationClientItemsPerPage: true

  # Security
  security: &quot;is_granted(&apos;ROLE_ADMIN&apos;)&quot;
  securityPostDenormalize: &quot;is_granted(&apos;EDIT&apos;, object)&quot;

  # Operations
  operations:
    - type: Post                     # Create new resource
    - type: Get                      # Get single resource
    - type: GetCollection            # Get collection with pagination
    - type: Put                      # Replace entire resource
    - type: Patch                    # Update partial resource
    - type: Delete                   # Delete resource

  # Properties
  properties:
    idCustomer:
      type: integer
      description: &quot;The unique identifier of the customer.&quot;
      writable: false                # Read-only property
      readable: true                 # Include in responses (default: true)

    email:
      type: string
      description: &quot;The email address.&quot;
      required: true                 # Required for all operations
      openapiContext:
        example: &quot;john@example.com&quot;
        format: &quot;email&quot;

    firstName:
      type: string
      description: &quot;First name.&quot;
      openapiContext:
        example: &quot;John&quot;
        minLength: 1
        maxLength: 100

    status:
      type: string
      description: &quot;Customer status.&quot;
      openapiContext:
        example: &quot;active&quot;
        schema:
          enum: [&quot;active&quot;, &quot;inactive&quot;, &quot;pending&quot;]

    customerReference:
      type: string
      description: &quot;Unique customer reference.&quot;
      writable: false
      identifier: true               # Use as URL identifier instead of @id

    dateOfBirth:
      type: string
      description: &quot;Date of birth.&quot;
      openapiContext:
        format: &quot;date&quot;
        example: &quot;1990-01-01&quot;

    isActive:
      type: boolean
      description: &quot;Active status.&quot;
      default: true

    creditLimit:
      type: number
      description: &quot;Credit limit.&quot;
      openapiContext:
        format: &quot;float&quot;
        example: 5000.00
```

## Property types

### Supported types

| Type | PHP Type | Example | Description |
|------|----------|---------|-------------|
| `string` | `string` | `&quot;John&quot;` | Text values |
| `integer` | `int` | `42` | Whole numbers |
| `number` | `float` | `3.14` | Decimal numbers |
| `boolean` | `bool` | `true` | True/false values |
| `array` | `array` | `[&quot;a&quot;, &quot;b&quot;]` | Lists of values |
| `object` | `object` | `{&quot;key&quot;: &quot;value&quot;}` | Strictly typed nested objects |
| `map` | `array` | `{&quot;key&quot;: &quot;value&quot;}` | Free-shape associative payloads documented via `openapiContext`. Stored as PHP `array` and rendered as `type: object` in the OpenAPI specification. |
| `mixed` | `mixed` | any | Use only when the payload genuinely has no fixed shape and cannot be described via `openapiContext`. |

Use `map` when the payload is a structured JSON object whose schema you want to describe via
`openapiContext` rather than a strongly typed PHP class. This is the recommended type whenever a
request or response body is a JSON object with a known shape but no dedicated DTO class — it
keeps the property typed as a simple `array` in PHP while still producing rich OpenAPI metadata
and a working &quot;Try Out&quot; body in Swagger UI. See
[Documenting nested properties for OpenAPI and Swagger UI](#documenting-nested-properties-for-openapi-and-swagger-ui)
for the full pattern.

### Property attributes

#### writable

Controls if property can be sent in requests (POST/PUT/PATCH):

```yaml
password:
  type: string
  writable: true    # Can be sent in requests
  readable: false   # Not included in responses
```

#### readable

Controls if property is included in responses:

```yaml
idCustomer:
  type: integer
  writable: false   # Cannot be modified
  readable: true    # Included in responses
```

#### identifier

Marks property as URL identifier:

```yaml
customerReference:
  type: string
  identifier: true  # URL becomes /customers/{customerReference}
```

#### required

Makes property mandatory (use validation schemas for detailed rules):

```yaml
email:
  type: string
  required: true    # Must be present
```

#### default

Sets default value:

```yaml
isActive:
  type: boolean
  default: true     # Defaults to true if not provided
```

## Documenting nested properties for OpenAPI and Swagger UI

Many endpoints accept or return structured JSON payloads — for example, a payment initialization
request that takes `payment`, `quote`, and `customer` sub-objects. Without explicit metadata,
those payloads appear as opaque `object` entries in the OpenAPI document, which means:

- The generated OpenAPI specification does not describe the child fields, their types, or which
  ones are required.
- The Swagger UI &quot;Try Out&quot; button shows an empty request body, forcing consumers to read code or
  external documentation to discover the expected shape.

The `map` property type combined with nested `openapiContext` entries closes both gaps.

### When to use this pattern

Use this pattern when the request or response body is a structured JSON object whose schema you
want to publish through OpenAPI, but you do not want to introduce a dedicated typed PHP class
for it. Typical cases are:

- Request payloads that aggregate fields from multiple transfer objects (for example, payment
  selection plus quote context).
- PSP- or provider-specific response payloads whose shape varies by configuration.

For payloads with a stable, strongly typed shape, prefer `type: object` so the generated PHP
class enforces the structure at the language level.

### Pattern

Combine `type: map` on the property with the following entries inside `openapiContext`:

| Entry | Purpose |
|-------|---------|
| `properties` | Declares each child field with its own `type`, `description`, `format`, and `example`. Used by Swagger UI to render the field-by-field schema. |
| `required` | Lists the child fields that must be present on a request. Drives the &quot;required&quot; markers in Swagger UI and the OpenAPI specification. |
| `example` | A complete sample payload. This is the value Swagger UI prefills into the &quot;Try Out&quot; body, so consumers can execute the request immediately. |

When the property is a `map`, the generator merges `&apos;type&apos; =&gt; &apos;object&apos;` into the emitted
`openapiContext`, so the property appears as an object — with the documented schema — in the
OpenAPI document while staying as a plain PHP `array` in the generated resource class.

### Worked example

The following extract is taken from
`src/Spryker/PaymentsRestApi/resources/api/storefront/payments.resource.yml`. It shows three
common shapes: a flat request object (`payment`), a request object with nested object children
(`quote`), and a response-only object whose contents vary at runtime (`preOrderPaymentData`).

```yaml
properties:
    payment:
        type: map
        writable: true
        readable: false
        required: true
        description: &apos;Payment selection for the pre-order initialization&apos;
        openapiContext:
            required: [&apos;paymentProviderName&apos;, &apos;paymentMethodName&apos;, &apos;amount&apos;]
            properties:
                paymentProviderName:
                    type: string
                    example: &apos;DummyPayment&apos;
                paymentMethodName:
                    type: string
                    example: &apos;Invoice&apos;
                amount:
                    type: integer
                    description: &apos;Amount in minor units (cents)&apos;
                    example: 9999
            example:
                paymentProviderName: &apos;DummyPayment&apos;
                paymentMethodName: &apos;Invoice&apos;
                amount: 9999

    quote:
        type: map
        writable: true
        readable: false
        required: true
        description: &apos;Quote context required to initialize the payment&apos;
        openapiContext:
            required: [&apos;customer&apos;, &apos;billingAddress&apos;, &apos;currency&apos;]
            properties:
                customer:
                    type: object
                    required: [&apos;firstName&apos;, &apos;lastName&apos;, &apos;email&apos;]
                    properties:
                        firstName: { type: string, example: &apos;Sonia&apos; }
                        lastName: { type: string, example: &apos;Wagner&apos; }
                        email: { type: string, format: email, example: &apos;sonia@acme.com&apos; }
                billingAddress:
                    type: object
                    required: [&apos;iso2Code&apos;]
                    properties:
                        iso2Code: { type: string, example: &apos;DE&apos; }
                currency:
                    type: object
                    required: [&apos;code&apos;]
                    properties:
                        code: { type: string, example: &apos;EUR&apos; }
            example:
                customer:
                    firstName: &apos;Sonia&apos;
                    lastName: &apos;Wagner&apos;
                    email: &apos;sonia@acme.com&apos;
                billingAddress:
                    iso2Code: &apos;DE&apos;
                currency:
                    code: &apos;EUR&apos;

    preOrderPaymentData:
        type: map
        writable: false
        readable: true
        required: false
        description: &apos;PSP-specific response payload returned by the payment provider&apos;
        openapiContext:
            example:
                transactionId: &apos;tx_abc123&apos;
                redirectUrl: &apos;https://psp.example.com/pay/tx_abc123&apos;
```

### Read-only versus write-only payloads

- **Write-only request payloads** (`writable: true`, `readable: false`) should declare
  `properties`, `required`, and `example`. The first two drive request validation and the
  generated OpenAPI schema; `example` makes the Swagger UI &quot;Try Out&quot; body usable without
  edits.
- **Read-only response payloads** (`writable: false`, `readable: true`) only need
  `openapiContext.example` when the response shape is dynamic. If the response shape is fixed,
  prefer declaring `properties` (and optionally `required`) so consumers see the full schema.

### Validation note

`openapiContext.required` controls only the OpenAPI documentation. If a request field must be
enforced at runtime, add the matching constraint to the resource&apos;s validation schema — see
[Validation Schemas](/docs/dg/dev/architecture/api-platform/validation-schemas.html).

## Operations

Define which HTTP operations are available for the resource:

```yaml
operations:
  - type: Get                      # GET /customers/{id}
  - type: GetCollection            # GET /customers
  - type: Post                     # POST /customers
  - type: Put                      # PUT /customers/{id}
  - type: Patch                    # PATCH /customers/{id}
  - type: Delete                   # DELETE /customers/{id}
```

The operation names map to HTTP methods:
- `post` → POST (create)
- `get` → GET (single resource)
- `getCollection` → GET (collection)
- `put` → PUT (replace)
- `patch` → PATCH (update)
- `delete` → DELETE (remove)

## Pagination

API Platform provides built-in pagination for collection endpoints (`GetCollection`). You can configure pagination behavior per resource using YAML schema options.

### Pagination options

| Option | Type | Description |
|--------|------|-------------|
| `paginationEnabled` | `boolean` | Enables or disables pagination for this resource. When `false`, `GetCollection` returns all results without pagination. Default: inherits from global configuration. |
| `paginationItemsPerPage` | `integer` | Number of items returned per page. Overrides the global default. |
| `paginationMaximumItemsPerPage` | `integer` | Maximum number of items a client can request per page via `itemsPerPage` query parameter. Prevents clients from requesting excessively large pages. |
| `paginationClientEnabled` | `boolean` | Allows clients to enable or disable pagination via the `pagination` query parameter (for example, `?pagination=false`). |
| `paginationClientItemsPerPage` | `boolean` | Allows clients to set the number of items per page via the `itemsPerPage` query parameter (for example, `?itemsPerPage=50`). |

The global default for `paginationItemsPerPage` is defined in the project&apos;s `api_platform.php` configuration file. To override it for a specific resource, set `paginationItemsPerPage` in the resource schema.

### Minimal pagination example

```yaml
resource:
  name: Products
  shortName: products

  paginationEnabled: true
  paginationItemsPerPage: 10

  operations:
    - type: GetCollection
```

### Full pagination example

```yaml
resource:
  name: Products
  shortName: products

  paginationEnabled: true
  paginationItemsPerPage: 20
  paginationMaximumItemsPerPage: 100
  paginationClientEnabled: true
  paginationClientItemsPerPage: true

  operations:
    - type: GetCollection
    - type: Get
```

With this configuration, clients can use the following query parameters:

```bash
# Default pagination (20 items per page)
GET /products

# Navigate to page 3
GET /products?page=3

# Request 50 items per page (up to maximum of 100)
GET /products?itemsPerPage=50

# Disable pagination to get all results
GET /products?pagination=false
```

### Generated output

The pagination options are rendered as named parameters in the `#[ApiResource]` attribute:

```php
#[ApiResource(
    operations: [new GetCollection(), new Get()],
    shortName: &apos;products&apos;,
    provider: ProductsBackendProvider::class,
    paginationItemsPerPage: 20,
    paginationEnabled: true,
    paginationMaximumItemsPerPage: 100,
    paginationClientEnabled: true,
    paginationClientItemsPerPage: true
)]
```

### Provider requirements

For pagination to work, your Provider must return a `TraversablePaginator` instance for collection operations:

```php
use ApiPlatform\State\Pagination\TraversablePaginator;

return new TraversablePaginator(
    new \ArrayObject($resources),
    $currentPage,
    $itemsPerPage,
    $totalItems
);
```

If `paginationEnabled` is `true` but the Provider returns a plain array, API Platform wraps the result in a `PartialPaginatorInterface`, which may not include total count or page metadata.

### Global pagination defaults

Global pagination defaults can be configured in the application configuration file. Per-resource settings override the global defaults. See [API Platform Configuration](/docs/dg/dev/architecture/api-platform/configuration.html) for details.

## Relationships

Define relationships between resources to enable including related resources via the `?include=` query parameter.

### includes section

Declares what relationships this resource can include:

```yaml
includes:
  - relationshipName: addresses
    targetResource: CustomersAddresses
    uriVariableMappings:
      customerReference: customerReference
```

**Properties:**
- `relationshipName`: Name used in `?include=` parameter
- `targetResource`: Name of the resource to include
- `uriVariableMappings`: Maps properties from parent to child provider

### includableIn section

Declares where this resource can be included:

```yaml
includableIn:
  - resource: Customers
    relationshipName: addresses
    uriVariableMappings:
      customerReference: customerReference
```

Both declarations must match for validation to pass.

For detailed information about relationships, see [Relationships](/docs/dg/dev/architecture/api-platform/relationships.html).

## Resource generation process

### Generation workflow

The resource generation process is organized into distinct phases, each producing result objects for comprehensive error tracking and reporting:

```MARKDOWN
1. Preparation Phase
   ↓
2. Schema Parsing Phase → ParseResult
   - Load validation schemas
   - Parse validation rules
   - Load resource schemas
   - Parse resource definitions
   ↓
3. Schema Merging Phase → MergeResult
   - Merge schemas (Core → Feature → Project)
   - Track contributing source files
   ↓
4. Validation Phase → ValidationResult
   - Validate merged schemas
   - Apply validation rules
   ↓
5. Code Generation Phase
   - Generate PHP resource classes
   - Write files to output directory
   ↓
6. Cache Update
```

### Result objects

Each phase produces result objects that encapsulate both successful outcomes and failures:

- **ParseResult**: Contains grouped schemas and tracks failed validation files and schema files that could not be parsed
- **MergeResult**: Contains successfully merged schemas and tracks resources that failed to merge
- **ValidationResult**: Contains validated schemas and tracks resources that failed validation with detailed error messages

This structured approach ensures that errors in one resource do not block the generation of other valid resources, and provides clear feedback about what succeeded and what failed.

### Multi-layer schema merging

Spryker automatically merges schemas from multiple layers:

**Core layer** (lowest priority):

**vendor/spryker/customer/resources/api/backend/customer.resource.yml**

```yaml
resource:
  name: Customers
  properties:
    email:
      type: string
    firstName:
      type: string
```

**Feature layer** (medium priority):

**src/SprykerFeature/CRM/resources/api/backend/customer.resource.yml**

```yaml
resource:
  name: Customers
  properties:
    phone:
      type: string      # Added property
```

**Project layer** (highest priority):

**src/Pyz/Glue/Customer/resources/api/backend/customer.resource.yml**

```yaml
resource:
  name: Customers
  properties:
    email:
      required: true    # Override core definition
    customField:
      type: string      # Project-specific field
```

**Merged result:**

```yaml
resource:
  name: Customers
  properties:
    email:
      type: string
      required: true    # From project layer
    firstName:
      type: string      # From core layer
    phone:
      type: string      # From feature layer
    customField:
      type: string      # From project layer
```

### Generated resource class

The generator creates a complete PHP class with API Platform attributes:

```php
&lt;?php

declare(strict_types=1);
namespace Generated\Api\Backend;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\ApiProperty;
use Symfony\Component\Validator\Constraints as Assert;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Delete;

#[ApiResource(
    operations: [new Post(), new Get(), new GetCollection(), new Patch(), new Delete()],
    shortName: &apos;Customer&apos;,
    provider: CustomerBackendProvider::class,
    processor: CustomerBackendProcessor::class,
    paginationItemsPerPage: 10,
    paginationEnabled: true,
    paginationMaximumItemsPerPage: 100,
    paginationClientEnabled: true,
    paginationClientItemsPerPage: true
)]
final class CustomersBackendResource
{
    #[ApiProperty(writable: false)]
    public ?int $idCustomer = null;

    #[ApiProperty(openapiContext: [&apos;example&apos; =&gt; &apos;john@example.com&apos;])]
    #[Assert\NotBlank(groups: [&apos;customers:create&apos;])]
    #[Assert\Email(groups: [&apos;customers:create&apos;])]
    public ?string $email = null;

    #[ApiProperty(identifier: true, writable: false)]
    public ?string $customerReference = null;

    public ?bool $isActive = true;

    // Getters, setters, toArray(), fromArray() methods...
}
```

## Debugging schemas

### Debug commands

```bash
# List all resources
docker/sdk cli GLUE_APPLICATION=GLUE_BACKEND glue api:debug --list

# Show specific resource
docker/sdk cli GLUE_APPLICATION=GLUE_BACKEND glue api:debug customers --api-type=backend

# Show merged schema
docker/sdk cli GLUE_APPLICATION=GLUE_BACKEND glue api:debug customers --api-type=backend --show-merged

# Show contributing source files
docker/sdk cli GLUE_APPLICATION=GLUE_BACKEND glue api:debug customers --api-type=backend --show-sources

# Validate schemas without generating
docker/sdk cli GLUE_APPLICATION=GLUE_BACKEND glue api:generate --validate-only
```

### Common schema errors

The generator validates schemas and provides detailed error messages:

```bash
# Missing required fields
Error: Resource &quot;customers&quot; is missing required field &quot;name&quot;

# Invalid operation type
Error: Invalid operation type &quot;INVALID&quot;. Must be one of: Get, Post, Put, Patch, Delete, GetCollection

# Invalid property type
Error: Property &quot;age&quot; has invalid type &quot;int&quot;. Must be one of: string, integer, number, boolean, array, object

# Provider class not found
Error: Provider class &quot;Pyz\Glue\Customer\Api\Backend\Provider\MissingProvider&quot; does not exist
```

## Advanced schema features

### Custom URL paths

Operations support `uriTemplate` and `uriVariables` to define custom URL paths, including sub-resource URLs like `/customers/{customerReference}/addresses`.

#### Sub-resource with full CRUD

Define a child resource with nested URLs by adding `uriTemplate` and `uriVariables` to each operation:

**customers-addresses.resource.yml**

```yaml
resource:
  name: CustomersAddresses
  shortName: customers-addresses

  operations:
    - type: GetCollection
      uriTemplate: &apos;/customers/{customerReference}/addresses&apos;
      uriVariables:
        customerReference:
          toProperty: &apos;customer&apos;
          fromClass: CustomersStorefrontResource

    - type: Get
      uriTemplate: &apos;/customers/{customerReference}/addresses/{uuid}&apos;
      uriVariables:
        customerReference:
          toProperty: &apos;customer&apos;
          fromClass: CustomersStorefrontResource
        uuid:
          fromClass: CustomersAddressesStorefrontResource

    - type: Post
      uriTemplate: &apos;/customers/{customerReference}/addresses&apos;
      uriVariables:
        customerReference:
          toProperty: &apos;customer&apos;
          fromClass: CustomersStorefrontResource
```

**`uriVariables` properties:**
- `fromClass`: The generated resource class the variable originates from
- `toProperty`: The property on the current resource that links to the parent resource

#### Action-style sub-resource

For single-action endpoints nested under a parent resource:

**customers-confirm-registration.resource.yml**

```yaml
resource:
  name: CustomersConfirmRegistration
  shortName: customers-confirm-registration

  operations:
    - type: Post
      uriTemplate: /customers/{customerReference}/confirm-registration
```

For more details on `uriTemplate`, `uriVariables`, and sub-resource patterns, see the [API Platform sub-resources documentation](https://api-platform.com/docs/core/subresources/).

### Security expressions

Security expressions protect resources and operations using [Symfony&apos;s ExpressionLanguage](https://symfony.com/doc/current/security/expressions.html). They require the SecurityBundle to be configured. See [How to integrate API Platform Security](/docs/dg/dev/upgrade-and-migrate/integrate-api-platform-security.html) for setup instructions.

{% info_block infoBox &quot;Where roles come from&quot; %}

Roles like `ROLE_CUSTOMER` in security expressions come from OAuth scopes that are automatically mapped to Symfony roles. The mapping convention is as follows: a scope name is uppercased and prefixed with `ROLE_`. For example, the `customer` scope becomes `ROLE_CUSTOMER`.

Scopes are provided by scope provider plugins registered in `OauthDependencyProvider::getScopeProviderPlugins()`. The following table lists the out-of-the-box scope provider plugins and the scopes they provide:

| Plugin | Scopes |
|--------|--------|
| `CustomerOauthScopeProviderPlugin` | `customer` |
| `CompanyUserOauthScopeProviderPlugin` | `company_user` |
| `AgentOauthScopeProviderPlugin` | `agent` |
| `CustomerImpersonationOauthScopeProviderPlugin` | `customer_impersonation`, `customer` |
| `UserOauthScopeProviderPlugin` | `user`, plus UserType sub-plugins |
| `WarehouseOauthScopeProviderPlugin` | `warehouse` |

For details on how the mapping works, see [Security — Roles and OAuth scope mapping](/docs/dg/dev/architecture/api-platform/security.html). For instructions on setting up scopes, see [Integrate the authorization scopes](/docs/integrations/spryker-glue-api/backend-api/integrate-backend-api/integrate-the-authorization-scopes.html).

{% endinfo_block %}

Three types of security expressions are supported:

| Expression | Evaluated | Use case | When to use |
|-----------|-----------|----------|-------------|
| `security` | Before the request is processed | Check user roles or authentication status | For role or authentication checks that do not depend on the request body. |
| `securityPostDenormalize` | After the request body is deserialized | Check authorization based on submitted data | When authorization depends on the deserialized resource `object`, for example, to verify the user owns the resource being modified. |
| `securityPostValidation` | After validation passes | Check authorization based on validated data | When authorization depends on validated data, for example, to verify a value is within the user&apos;s authorized limit after validation confirms the data is structurally correct. |

#### Resource-level security

Applies to all operations on the resource:

```yaml
resource:
  name: Customers
  shortName: customers
  security: &quot;is_granted(&apos;ROLE_USER&apos;)&quot;
```

#### Operation-level security

Applies to a specific operation, overriding resource-level security:

```yaml
resource:
  name: Customers
  shortName: customers

  operations:
    - type: Post
      # No security — public registration

    - type: Get
      security: &quot;is_granted(&apos;ROLE_USER&apos;)&quot;

    - type: Patch
      security: &quot;is_granted(&apos;ROLE_USER&apos;)&quot;
```

#### Post-denormalize security

Evaluated after the request body has been deserialized. The `object` variable contains the resource instance:

```yaml
resource:
  name: Orders
  shortName: orders
  security: &quot;is_granted(&apos;ROLE_USER&apos;)&quot;
  securityPostDenormalize: &quot;is_granted(&apos;EDIT&apos;, object)&quot;
```

{% info_block infoBox &quot;Custom voter attributes&quot; %}

`EDIT` in the example is a **custom voter attribute** — it is an application-defined string, not a built-in Symfony or Spryker constant. For `is_granted(&apos;EDIT&apos;, object)` to work, you must register a custom Symfony [Voter](https://symfony.com/doc/current/security/voters.html) that supports the `EDIT` attribute and implements the authorization logic, for example, checking that the authenticated user owns the resource.

Use `securityPostDenormalize` when the authorization decision depends on the **submitted request data** (the deserialized `object`), such as verifying resource ownership.

{% endinfo_block %}

#### Post-validation security

Evaluated after validation has passed:

```yaml
resource:
  name: Payments
  shortName: payments
  securityPostValidation: &quot;is_granted(&apos;PROCESS&apos;, object)&quot;
```

{% info_block infoBox &quot;Custom voter attributes&quot; %}

`PROCESS` in the example is a **custom voter attribute** — it is an application-defined string, not a built-in Symfony or Spryker constant. For `is_granted(&apos;PROCESS&apos;, object)` to work, you must register a custom Symfony [Voter](https://symfony.com/doc/current/security/voters.html) that supports the `PROCESS` attribute.

Use `securityPostValidation` when the authorization decision depends on **validated data**, for example, to verify a payment amount is within the user&apos;s authorized limit after validation confirms the data is structurally correct.

{% endinfo_block %}

For detailed information about the authentication flow, role mapping, and accessing the authenticated user in providers, see [Security](/docs/dg/dev/architecture/api-platform/security.html).

## Generation commands

### Basic generation

```bash
# Generate all configured API types
docker/sdk cli GLUE_APPLICATION=GLUE_BACKEND glue api:generate

# Generate specific API type
docker/sdk cli GLUE_APPLICATION=GLUE_BACKEND glue api:generate backend
docker/sdk cli GLUE_APPLICATION=GLUE_STOREFRONT glue api:generate storefront

# Generate with options
docker/sdk cli GLUE_APPLICATION=GLUE_BACKEND glue api:generate --dry-run           # Preview without writing
docker/sdk cli GLUE_APPLICATION=GLUE_BACKEND glue api:generate --validate-only     # Only validate schemas
docker/sdk cli GLUE_APPLICATION=GLUE_BACKEND glue api:generate --resource=customers  # Generate single resource
```

### Output

```bash
Generating API resources for ApiType: backend

Discovering schema files...
Validating schemas... OK
Merging schemas... OK

Generating resources:
 10/10 [============================] 100%

Generated: 10 file(s)
Cache updated

Done!
```

## Schema validation rules

The generator enforces these rules:

### Required fields

Every resource must have:
- `name` - Internal resource name
- `shortName` - URL-friendly name
- At least one `operation`
- At least one `property`

### Valid operation types

Only these operation types are allowed:
- `Get` - Retrieve single resource
- `GetCollection` - Retrieve collection
- `Post` - Create resource
- `Put` - Replace entire resource
- `Patch` - Update partial resource
- `Delete` - Delete resource

### Valid property types

Only these property types are allowed:
- `string`
- `integer`
- `number`
- `boolean`
- `array`
- `object`
- `map`
- `mixed`

### Provider/Processor validation

- Provider/Processor classes must exist
- Classes must implement correct interfaces
- Namespaces must be valid PHP namespaces

## Best practices

### 1. Use semantic naming

```yaml
# ✅ Good
resource:
  name: Customers
  shortName: Customer

# ❌ Bad
resource:
  name: CustomerData
  shortName: cust
```

### 2. Document all properties

```yaml
# ✅ Good
email:
  type: string
  description: &quot;The customer&apos;s email address used for login and notifications&quot;

# ❌ Bad
email:
  type: string
```

### 3. Leverage schema merging

Core — define base properties:

**src/Spryker/Customer/resources/api/backend/customer.resource.yml**

```yaml
resource:
  name: Customers
  properties:
    email:
      type: string
```

Project — only override what is needed:

**src/Pyz/Glue/Customer/resources/api/backend/customer.resource.yml**

```yaml
resource:
  name: Customers
  properties:
    email:
      required: true  # ← Only the difference
```

### 4. Use readable/writable correctly

```yaml
# Read-only fields (IDs, timestamps)
idCustomer:
  type: integer
  writable: false

# Write-only fields (passwords)
password:
  type: string
  readable: false

# Read-write fields (normal data)
email:
  type: string
  writable: true
  readable: true
```

## Next steps

- [API Platform](/docs/dg/dev/architecture/api-platform.html) - Architecture overview
- [Validation Schemas](/docs/dg/dev/architecture/api-platform/validation-schemas.html) - Define validation rules
- [CodeBucket Support](/docs/dg/dev/architecture/api-platform/code-buckets.html) - Code Bucket-specific resources
- [API Platform Enablement](/docs/dg/dev/architecture/api-platform/enablement.html) - Creating resources
- [API Platform Testing](/docs/dg/dev/architecture/api-platform/testing.html) - Writing and running tests
- [Troubleshooting](/docs/dg/dev/architecture/api-platform/troubleshooting.html) - Common issues
- [API Platform Documentation](https://api-platform.com/docs/) - Official API Platform docs
</description>
            <pubDate>Tue, 05 May 2026 07:54:35 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/architecture/api-platform/resource-schemas.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/architecture/api-platform/resource-schemas.html</guid>
            
            
        </item>
        
        <item>
            <title>Migration status - Glue API to API Platform</title>
            <description>This document tracks Spryker&apos;s migration of API-providing modules to the **API Platform** (built on Symfony and the API Platform library). Use it to plan upgrades and check the current status of every module.

{% info_block infoBox &quot;Looking for the integration guide?&quot; %}

This page does **not** describe how to integrate API Platform into your project. For step-by-step integration instructions, see:

- [Migrate to API Platform](/docs/dg/dev/upgrade-and-migrate/migrate-to-api-platform.html)
- [Integrate API Platform](/docs/dg/dev/upgrade-and-migrate/integrate-api-platform.html)
- [Integrate API Platform security](/docs/dg/dev/upgrade-and-migrate/integrate-api-platform-security.html)
- [API Platform architecture](/docs/dg/dev/architecture/api-platform.html)

{% endinfo_block %}

## Why Spryker is moving to API Platform

API Platform replaces Spryker-specific patterns for routing, authentication, and resource definition with industry-standard Symfony conventions, automatic OpenAPI schema generation, and a clean separation between resource schema, provider, and validation.

| Aspect | Previous infrastructure | API Platform |
|---|---|---|
| Bootstrap | Spryker-specific application bootstrap | Symfony Kernel-based routing |
| Resource registration | Manual plugin registration in `GlueApplicationDependencyProvider` | Declarative YAML resource definitions (`*.resource.yml`) |
| Authentication | Custom flows per module | Standard OAuth2 / Symfony Security |
| Coupling | Tight coupling between resource and routing logic | Clean separation: provider + resource schema + validation |
| Testability | Complex to test and extend | Symfony-native, testable with standard PHPUnit patterns |
| OpenAPI | Manual / partial | Automatic OpenAPI schema generation |

## General migration workflow

For any module marked **Migrated**, projects upgrade in three high-level steps. Detailed instructions are in the linked integration guides above.

1. **Update the module to the API Platform-enabled version**

   Pull the new module version that ships the `*.resource.yml` schema and Provider class:

    ```bash
    composer update spryker/&lt;module-name&gt;
    ```

2. **Remove the previous resource plugins**

   In your project&apos;s `GlueApplicationDependencyProvider`, remove the previous plugin registrations for the migrated module - typically a `ResourceRoutePlugin` (and any related `ResourceRelationshipPlugin` / expander plugins) registered in `getResourceRoutePlugins()`.

   For **extension-only** modules, remove or replace the corresponding plugin wiring in the parent module&apos;s dependency provider as indicated in the module&apos;s release notes.

3. **Clear caches and verify**

    ```bash
    vendor/bin/glue cache:clear
    vendor/bin/glue api:generate
    ```

   Confirm the endpoint is served by API Platform by hitting it against your local Glue host - the response is now produced by the new Symfony-based stack.

{% info_block infoBox &quot;Parallel operation&quot; %}

The previous API stack and API Platform run **side by side** during the transition. You can migrate modules incrementally; modules that have not been migrated continue to be served by the previous stack.

{% endinfo_block %}

### Status legend

| Status | Meaning |
|---|---|
| Migrated | Module is available on API Platform and production-ready. |
| Planned | Module is scheduled or queued for migration to API Platform. |

## Storefront API modules

All StorefrontAPI and Extension-only StorefrontAPI modules. Migrated modules are listed first.

| Module | Category | Status | Key endpoints |
|---|---|---|---|
| ContentProductAbstractListsRestApi | StorefrontAPI | Migrated | GET /content-product-abstract-lists/{id}&lt;br&gt;GET /content-product-abstract-lists/{id}/abstract-products |
| MerchantProductOffersRestApi | StorefrontAPI | Migrated | GET /concrete-products/{id}/product-offers&lt;br&gt;GET /product-offers/{id} |
| PaymentsRestApi | StorefrontAPI | Migrated | POST /payments&lt;br&gt;POST /payment-cancellations&lt;br&gt;POST /payment-customers |
| ProductAvailabilitiesRestApi | StorefrontAPI | Migrated | GET /abstract-products/{id}/abstract-product-availabilities&lt;br&gt;GET /concrete-products/{id}/concrete-product-availabilities |
| ProductOfferAvailabilitiesRestApi | StorefrontAPI | Migrated | GET /product-offers/{id}/product-offer-availabilities |
| ProductOfferPricesRestApi | StorefrontAPI | Migrated | GET /product-offers/{id}/product-offer-prices |
| ProductPricesRestApi | StorefrontAPI | Migrated | GET /abstract-products/{id}/abstract-product-prices&lt;br&gt;GET /concrete-products/{id}/concrete-product-prices |
| ProductTaxSetsRestApi | StorefrontAPI | Migrated | GET /abstract-products/{id}/product-tax-sets |
| ProductsRestApi | StorefrontAPI | Migrated | GET /abstract-products/{id}&lt;br&gt;GET /concrete-products/{id} |
| StoresApi | StorefrontAPI | Migrated | GET /stores |
| AgentAuthRestApi | StorefrontAPI | Planned | POST /agent-access-tokens&lt;br&gt;POST /agent-customer-impersonation-access-tokens&lt;br&gt;GET /agent-customer-search |
| AlternativeProductsRestApi | StorefrontAPI | Planned | GET /abstract-products/{id}/related-products&lt;br&gt;GET /concrete-products/{id}/abstract-alternative-products&lt;br&gt;GET /concrete-products/{id}/concrete-alternative-products |
| AuthRestApi | StorefrontAPI | Planned | POST /token&lt;br&gt;POST /access-tokens&lt;br&gt;POST /refresh-tokens&lt;br&gt;DELETE /refresh-tokens/{id} |
| AvailabilityNotificationsRestApi | StorefrontAPI | Planned | POST /availability-notifications&lt;br&gt;DELETE /availability-notifications/{id}&lt;br&gt;GET /my-availability-notifications&lt;br&gt;GET /customers/{id}/availability-notifications |
| CartCodesRestApi | StorefrontAPI | Planned | POST /carts/{id}/cart-codes&lt;br&gt;DELETE /carts/{id}/cart-codes/{id}&lt;br&gt;POST /guest-carts/{id}/cart-codes&lt;br&gt;DELETE /guest-carts/{id}/cart-codes/{id} |
| CartPermissionGroupsRestApi | StorefrontAPI | Planned | GET /cart-permission-groups&lt;br&gt;GET /cart-permission-groups/{id} |
| CartReorderRestApi | StorefrontAPI | Planned | POST /cart-reorder |
| CartsRestApi | StorefrontAPI | Planned | GET,POST /carts&lt;br&gt;GET,PATCH,DELETE /carts/{id}&lt;br&gt;POST /carts/{id}/items&lt;br&gt;PATCH,DELETE /carts/{id}/items/{id}&lt;br&gt;GET /guest-carts&lt;br&gt;GET,PATCH /guest-carts/{id}&lt;br&gt;POST /guest-carts/{id}/guest-cart-items&lt;br&gt;PATCH,DELETE /guest-carts/{id}/guest-cart-items/{id}&lt;br&gt;GET /customers/{id}/carts |
| CatalogSearchRestApi | StorefrontAPI | Planned | GET /catalog-search&lt;br&gt;GET /catalog-search-suggestions |
| CategoriesRestApi | StorefrontAPI | Planned | GET /category-trees&lt;br&gt;GET /category-nodes/{id} |
| CheckoutRestApi | StorefrontAPI | Planned | POST /checkout-data&lt;br&gt;POST /checkout |
| CmsPagesRestApi | StorefrontAPI | Planned | GET /cms-pages&lt;br&gt;GET /cms-pages/{id} |
| CompaniesRestApi | StorefrontAPI | Planned | GET /companies&lt;br&gt;GET /companies/{id} |
| CompanyBusinessUnitAddressesRestApi | StorefrontAPI | Planned | GET /company-business-unit-addresses&lt;br&gt;GET /company-business-unit-addresses/{id} |
| CompanyBusinessUnitsRestApi | StorefrontAPI | Planned | GET /company-business-units&lt;br&gt;GET /company-business-units/{id} |
| CompanyRolesRestApi | StorefrontAPI | Planned | GET /company-roles&lt;br&gt;GET /company-roles/{id} |
| CompanyUserAuthRestApi | StorefrontAPI | Planned | POST /company-user-access-tokens |
| CompanyUsersRestApi | StorefrontAPI | Planned | GET /company-users&lt;br&gt;GET /company-users/{id} |
| ConfigurableBundleCartsRestApi | StorefrontAPI | Planned | POST /carts/{id}/configured-bundles&lt;br&gt;PATCH,DELETE /carts/{id}/configured-bundles/{id}&lt;br&gt;POST,PATCH,DELETE /guest-carts/{id}/guest-configured-bundles/{id} |
| ConfigurableBundlesRestApi | StorefrontAPI | Planned | GET /configurable-bundle-templates&lt;br&gt;GET /configurable-bundle-templates/{id} |
| ContentBannersRestApi | StorefrontAPI | Planned | GET /content-banners/{id} |
| CustomerAccessRestApi | StorefrontAPI | Planned | GET /customer-access |
| CustomersRestApi | StorefrontAPI | Planned | GET,POST /customers&lt;br&gt;GET,PATCH,DELETE /customers/{id}&lt;br&gt;GET,POST /customers/{id}/addresses&lt;br&gt;GET,PATCH,DELETE /customers/{id}/addresses/{id}&lt;br&gt;POST /customer-forgotten-password&lt;br&gt;PATCH /customer-restore-password/{id}&lt;br&gt;PATCH /customer-password/{id}&lt;br&gt;POST /customer-confirmation |
| DiscountPromotionsRestApi | Extension-Only-StorefrontAPI | Planned | CartsRestApi, CartCodesRestApi |
| DiscountsRestApi | StorefrontAPI | Planned | POST /carts/{id}/vouchers&lt;br&gt;DELETE /carts/{id}/vouchers/{id}&lt;br&gt;POST /guest-carts/{id}/vouchers&lt;br&gt;DELETE /guest-carts/{id}/vouchers/{id} |
| EntityTagsRestApi | Extension-only StorefrontAPI | Planned | GlueApplication |
| GiftCardsRestApi | Extension-only StorefrontAPI | Planned | GlueApplication |
| MerchantCategoriesRestApi | Extension-only StorefrontAPI | Planned | MerchantsRestApi |
| MerchantOpeningHoursRestApi | StorefrontAPI | Planned | GET /merchants/{id}/merchant-opening-hours |
| MerchantProductOfferServicePointAvailabilitiesRestApi | Extension-only StorefrontAPI | Planned | (transfer-only) |
| MerchantProductOfferShoppingListsRestApi | Extension-only StorefrontAPI | Planned | (transfer-only) |
| MerchantProductOfferWishlistRestApi | Extension-only StorefrontAPI | Planned | WishlistsRestApi |
| MerchantProductShoppingListsRestApi | Extension-only StorefrontAPI | Planned | (transfer-only) |
| MerchantProductsRestApi | Extension-only StorefrontAPI | Planned | CartsRestApi |
| MerchantRelationshipProductListsRestApi | Extension-only StorefrontAPI | Planned | CustomersRestApi |
| MerchantSalesReturnsRestApi | Extension-only StorefrontAPI | Planned | (transfer-only) |
| MerchantShipmentsRestApi | Extension-only StorefrontAPI | Planned | ShipmentsRestApi |
| MerchantsRestApi | StorefrontAPI | Planned | GET /merchants&lt;br&gt;GET /merchants/{id}&lt;br&gt;GET /merchants/{id}/merchant-addresses |
| MultiCartsRestApi | Extension-only StorefrontAPI | Planned | CartsRestApi |
| NavigationsRestApi | StorefrontAPI | Planned | GET /navigations/{id} |
| OauthApi | StorefrontAPI | Planned | POST /token |
| OmsRestApi | Extension-only StorefrontAPI | Planned | OrdersRestApi |
| OrderAmendmentsRestApi | Extension-only StorefrontAPI | Planned | OrdersRestApi, CartsRestApi, CartReorderRestApi |
| OrderPaymentsRestApi | StorefrontAPI | Planned | POST /order-payments |
| OrdersRestApi | StorefrontAPI | Planned | GET /orders&lt;br&gt;GET /orders/{id}&lt;br&gt;GET /customers/{id}/orders |
| PriceProductOfferVolumesRestApi | Extension-only StorefrontAPI | Planned | ProductOfferPricesRestApi |
| PriceProductVolumesRestApi | Extension-only StorefrontAPI | Planned | ProductPricesRestApi |
| ProductAttributesRestApi | StorefrontAPI | Planned | GET /product-management-attributes&lt;br&gt;GET /product-management-attributes/{id} |
| ProductBundleCartsRestApi | Extension-only StorefrontAPI | Planned | CartsRestApi, ShipmentsRestApi |
| ProductBundlesRestApi | StorefrontAPI | Planned | GET /concrete-products/{id}/bundled-products |
| ProductConfigurationShoppingListsRestApi | Extension-only StorefrontAPI | Planned | ShoppingListsRestApi |
| ProductConfigurationWishlistsRestApi | Extension-only StorefrontAPI | Planned | WishlistsRestApi |
| ProductConfigurationsPriceProductVolumesRestApi | Extension-only StorefrontAPI | Planned | ProductConfigurationsRestApi, ProductConfigurationShoppingListsRestApi, ProductConfigurationWishlistsRestApi |
| ProductConfigurationsRestApi | Extension-only StorefrontAPI | Planned | ProductsRestApi, CartsRestApi, OrdersRestApi |
| ProductDiscontinuedRestApi | Extension-only StorefrontAPI | Planned | ProductsRestApi |
| ProductImageSetsRestApi | StorefrontAPI | Planned | GET /abstract-products/{id}/abstract-product-image-sets&lt;br&gt;GET /concrete-products/{id}/concrete-product-image-sets |
| ProductLabelsRestApi | StorefrontAPI | Planned | GET /product-labels/{id} |
| ProductMeasurementUnitsRestApi | StorefrontAPI | Planned | GET /product-measurement-units/{id}&lt;br&gt;GET /concrete-products/{id}/sales-units |
| ProductOfferSalesRestApi | Extension-only StorefrontAPI | Planned | (transfer-only) |
| ProductOfferServicePointAvailabilitiesRestApi | StorefrontAPI | Planned | POST /product-offer-service-point-availabilities |
| ProductOfferShoppingListsRestApi | Extension-only StorefrontAPI | Planned | (transfer-only) |
| ProductOffersRestApi | Extension-only StorefrontAPI | Planned | ProductsRestApi |
| ProductOptionsRestApi | Extension-only StorefrontAPI | Planned | CartsRestApi, OrdersRestApi, ProductsRestApi, QuoteRequestsRestApi |
| ProductReviewsRestApi | StorefrontAPI | Planned | GET,POST /abstract-products/{id}/product-reviews&lt;br&gt;GET /abstract-products/{id}/product-reviews/{id} |
| QuoteRequestAgentsRestApi | StorefrontAPI | Planned | GET,POST /agent-quote-requests&lt;br&gt;GET,PATCH /agent-quote-requests/{id}&lt;br&gt;POST /agent-quote-requests/{id}/agent-quote-request-cancel&lt;br&gt;POST /agent-quote-requests/{id}/agent-quote-request-revise&lt;br&gt;POST /agent-quote-requests/{id}/agent-quote-request-send-to-customer |
| QuoteRequestsRestApi | StorefrontAPI | Planned | GET,POST /quote-requests&lt;br&gt;GET,PATCH /quote-requests/{id}&lt;br&gt;POST /quote-requests/{id}/quote-request-cancel&lt;br&gt;POST /quote-requests/{id}/quote-request-revise&lt;br&gt;POST /quote-requests/{id}/quote-request-send-to-user&lt;br&gt;POST /quote-requests/{id}/quote-request-convert-to-quote |
| RelatedProductsRestApi | StorefrontAPI | Planned | GET /abstract-products/{id}/related-products |
| SalesOrderThresholdsRestApi | Extension-only StorefrontAPI | Planned | CartsRestApi, CheckoutRestApi |
| SalesReturnsRestApi | StorefrontAPI | Planned | GET /return-reasons&lt;br&gt;GET,POST /returns&lt;br&gt;GET /returns/{id} |
| SecurityBlockerRestApi | Extension-only StorefrontAPI | Planned | GlueApplication |
| ServicePointCartsRestApi | Extension-only StorefrontAPI | Planned | CheckoutRestApi |
| ServicePointsRestApi | StorefrontAPI | Planned | GET /service-points&lt;br&gt;GET /service-points/{id}&lt;br&gt;GET /service-points/{id}/service-point-addresses/{id} |
| SharedCartsRestApi | StorefrontAPI | Planned | POST /carts/{id}/shared-carts&lt;br&gt;PATCH,DELETE /shared-carts/{id} |
| ShipmentTypeProductOfferServicePointAvailabilitiesRestApi | Extension-only StorefrontAPI | Planned | ProductOfferServicePointAvailabilitiesRestApi |
| ShipmentTypeServicePointsRestApi | Extension-only StorefrontAPI | Planned | CheckoutRestApi, ShipmentsRestApi, ShipmentTypesRestApi |
| ShipmentTypesRestApi | StorefrontAPI | Planned | GET /shipment-types&lt;br&gt;GET /shipment-types/{id} |
| ShipmentsRestApi | Extension-only StorefrontAPI | Planned | CheckoutRestApi, OrdersRestApi, QuoteRequestsRestApi |
| ShoppingListsRestApi | StorefrontAPI | Planned | GET,POST /shopping-lists&lt;br&gt;GET,PATCH,DELETE /shopping-lists/{id}&lt;br&gt;POST /shopping-lists/{id}/shopping-list-items&lt;br&gt;PATCH,DELETE /shopping-lists/{id}/shopping-list-items/{id} |
| TaxAppRestApi | StorefrontAPI | Planned | POST /tax-id-validate |
| UpSellingProductsRestApi | StorefrontAPI | Planned | GET /carts/{id}/up-selling-products&lt;br&gt;GET /guest-carts/{id}/up-selling-products |
| UrlsRestApi | StorefrontAPI | Planned | GET /url-resolver |
| WishlistsRestApi | StorefrontAPI | Planned | GET,POST /wishlists&lt;br&gt;GET,PATCH,DELETE /wishlists/{id}&lt;br&gt;POST /wishlists/{id}/wishlist-items&lt;br&gt;PATCH,DELETE /wishlists/{id}/wishlist-items/{id} |

## Backend API modules

All BackendAPI modules tracked in the migration scope.

| Module | Category | Status | Key endpoints |
|---|---|---|---|
| CartNotesBackendApi | Extension-Only BackendAPI | Planned | SalesOrdersBackendApi |
| CategoriesBackendApi | BackendAPI | Planned | GET,POST /categories&lt;br&gt;GET,PATCH /categories/{id} |
| DynamicEntityBackendApi | BackendAPI | Planned | GET,POST,PATCH,PUT /dynamic-entity/{entity-name} (~62 auto-generated entity endpoints) |
| OauthBackendApi | BackendAPI | Planned | POST /token |
| PickingListsBackendApi | BackendAPI | Planned | GET /picking-lists&lt;br&gt;GET /picking-lists/{id}&lt;br&gt;PATCH /picking-lists/{id}/picking-list-items/{id}&lt;br&gt;POST /start-picking |
| PickingListsUsersBackendApi | Extension-Only BackendAPI | Planned | PickingListsBackendApi |
| PickingListsWarehousesBackendApi | Extension-Only BackendAPI | Planned | PickingListsBackendApi |
| ProductAttributesBackendApi | BackendAPI | Planned | GET,POST /product-attributes&lt;br&gt;GET,PATCH /product-attributes/{id} |
| ProductImageSetsBackendApi | BackendAPI | Planned | GET /concrete-product-image-sets |
| ProductPackagingUnitsBackendApi | Extension-Only BackendAPI | Planned | PickingListsBackendApi |
| ProductsBackendApi | BackendAPI | Planned | GET,POST /product-abstract&lt;br&gt;DELETE,GET,PATCH /product-abstract/{id} |
| PushNotificationsBackendApi | BackendAPI | Planned | GET,POST /push-notification-providers&lt;br&gt;PATCH,DELETE /push-notification-providers/{id}&lt;br&gt;POST /push-notification-subscriptions |
| SalesOrdersBackendApi | BackendAPI | Planned | GET /sales-orders |
| ServicePointsBackendApi | BackendAPI | Planned | GET,POST /service-points&lt;br&gt;GET,PATCH /service-points/{id}&lt;br&gt;GET,POST /service-point-addresses&lt;br&gt;PATCH /service-points/{id}/service-point-addresses/{id}&lt;br&gt;GET,POST /service-types&lt;br&gt;GET,PATCH /service-types/{id}&lt;br&gt;GET,POST /services&lt;br&gt;GET,PATCH /services/{id} |
| ShipmentTypesBackendApi | BackendAPI | Planned | GET,POST /shipment-types&lt;br&gt;GET,PATCH /shipment-types/{id} |
| ShipmentsBackendApi | BackendAPI | Planned | GET /sales-shipments |
| StoresBackendApi | BackendAPI | Planned | GET,POST,PATCH /stores |
| UsersBackendApi | BackendAPI | Planned | GET /users |
| WarehouseOauthBackendApi | BackendAPI | Planned | POST /warehouse-tokens |
| WarehouseUsersBackendApi | BackendAPI | Planned | GET,POST /warehouse-user-assignments&lt;br&gt;GET,PATCH,DELETE /warehouse-user-assignments/{id} |
| WarehousesBackendApi | BackendAPI | Planned | GET /warehouses |
</description>
            <pubDate>Tue, 05 May 2026 07:29:46 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/architecture/api-platform/migrate-to-api-platform-status.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/architecture/api-platform/migrate-to-api-platform-status.html</guid>
            
            
        </item>
        
        <item>
            <title>AiFoundation module Overview</title>
            <description>&lt;p&gt;This document describes how to integrate and use the AiFoundation module to interact with various AI providers in your Spryker application. The AiFoundation module provides a unified interface for working with multiple AI providers, such as OpenAI, Anthropic Claude, AWS Bedrock, and others.&lt;/p&gt;
&lt;p&gt;The AiFoundation module uses a Zed-backed architecture where the client provides a simple interface that delegates all processing to the Zed facade. This design enables centralized management of AI configurations, conversation history persistence, and tool execution.&lt;/p&gt;
&lt;h2 id=&quot;architecture&quot;&gt;Architecture&lt;/h2&gt;
&lt;p&gt;The AiFoundation module uses a two-layer architecture:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Client Layer&lt;/strong&gt;: Provides a simple &lt;code&gt;AiFoundationClientInterface&lt;/code&gt; that serves as the entry point for AI interactions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zed Layer&lt;/strong&gt;: Contains the &lt;code&gt;AiFoundationFacade&lt;/code&gt; that handles all business logic including:
&lt;ul&gt;
&lt;li&gt;AI configuration resolution&lt;/li&gt;
&lt;li&gt;Vendor adapter plugin delegation&lt;/li&gt;
&lt;li&gt;Conversation history persistence and retrieval&lt;/li&gt;
&lt;li&gt;Tool execution and invocation tracking&lt;/li&gt;
&lt;li&gt;Structured response validation and mapping&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The client delegates all processing to the Zed facade through a request stub, ensuring centralized management of AI operations and database persistence.&lt;/p&gt;
&lt;h2 id=&quot;install-the-aifoundation-module&quot;&gt;Install the AiFoundation module&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Require the package:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;composer require spryker/ai-foundation
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Generate transfers:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;console transfer:generate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;configure-ai-providers&quot;&gt;Configure AI providers&lt;/h2&gt;
&lt;p&gt;Configure AI providers in a dedicated configuration file. The module uses the &lt;code&gt;AI_CONFIGURATIONS&lt;/code&gt; constant to define one or more AI configurations.&lt;/p&gt;
&lt;section class=&apos;info-block &apos;&gt;&lt;i class=&apos;info-block__icon icon-info&apos;&gt;&lt;/i&gt;&lt;div class=&apos;info-block__content&apos;&gt;&lt;div class=&quot;info-block__title&quot;&gt;Best practice&lt;/div&gt;
&lt;p&gt;Create a separate configuration file for AI settings to keep your configuration organized and maintainable.&lt;/p&gt;
&lt;/div&gt;&lt;/section&gt;
&lt;section class=&apos;info-block info-block--warning&apos;&gt;&lt;i class=&apos;info-block__icon icon-warning&apos;&gt;&lt;/i&gt;&lt;div class=&apos;info-block__content&apos;&gt;&lt;div class=&quot;info-block__title&quot;&gt;Security&lt;/div&gt;
&lt;p&gt;Store API keys as environment variables, not in configuration files. For Spryker Cloud, use the parameter store to manage sensitive credentials. For details, see &lt;a href=&quot;/docs/ca/dev/add-variables-in-the-parameter-store.html&quot;&gt;Add variables in the parameter store&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;&lt;/section&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a new configuration file &lt;code&gt;config/Shared/config_ai.php&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Spryker\Shared\AiFoundation\AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// AI provider configurations&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;AI_CONFIGURATIONS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Your AI configurations will be defined here&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Include the AI configuration file in your main configuration file (for example, &lt;code&gt;config/Shared/config_default.php&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;config_ai.php&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Alternatively, you can define AI configurations directly in &lt;code&gt;config/Shared/config_default.php&lt;/code&gt; if you prefer a single configuration file approach.&lt;/p&gt;
&lt;h3 id=&quot;configuration-structure&quot;&gt;Configuration structure&lt;/h3&gt;
&lt;p&gt;Each AI configuration requires:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;provider_name&lt;/code&gt;: The AI provider identifier (required)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;provider_config&lt;/code&gt;: Provider-specific configuration (required)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;system_prompt&lt;/code&gt;: Default system prompt for the AI provider&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;default-configuration&quot;&gt;Default configuration&lt;/h3&gt;
&lt;p&gt;The module automatically uses the configuration named &lt;code&gt;AI_CONFIGURATION_DEFAULT&lt;/code&gt; when you do not specify a configuration in the &lt;code&gt;PromptRequest&lt;/code&gt;. Define at least one default configuration:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Spryker\Shared\AiFoundation\AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;AI_CONFIGURATIONS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;AI_CONFIGURATION_DEFAULT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;provider_name&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PROVIDER_OPENAI&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;provider_config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;key&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;getenv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;OPENAI_API_KEY&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;model&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;gpt-4o&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Resolved at runtime from Configuration Management&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;system_prompt&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;CONFIGURATION_REFERENCE_PREFIX&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;ai_commerce:backoffice_assistant:general:system_prompt&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Any string value prefixed with &lt;code&gt;configuration::&lt;/code&gt; (&lt;code&gt;AiFoundationConstants::CONFIGURATION_REFERENCE_PREFIX&lt;/code&gt;) is resolved at runtime via the &lt;a href=&quot;/docs/dg/dev/backend-development/configuration-management.html&quot;&gt;Configuration Management&lt;/a&gt; module.
This lets admin users update AI settings—model, API key, system prompt—from the Back Office without a code deployment.&lt;/p&gt;
&lt;h2 id=&quot;provider-configuration-examples&quot;&gt;Provider configuration examples&lt;/h2&gt;
&lt;h3 id=&quot;openai&quot;&gt;OpenAI&lt;/h3&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s1&quot;&gt;&apos;openai-config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_name&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PROVIDER_OPENAI&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;key&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;getenv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;OPENAI_API_KEY&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;model&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;gpt-4o&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;parameters&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// optional&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;httpOptions&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// optional&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;timeout&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;connectTimeout&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;headers&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;system_prompt&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;You are a helpful assistant.&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// optional&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;anthropic-claude&quot;&gt;Anthropic Claude&lt;/h3&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s1&quot;&gt;&apos;anthropic-config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_name&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PROVIDER_ANTHROPIC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;key&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;getenv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;ANTHROPIC_API_KEY&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;model&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;claude-sonnet-4-20250514&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;version&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;2023-06-01&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// optional&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;max_tokens&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8192&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// optional&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;parameters&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// optional&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;httpOptions&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// optional&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;timeout&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;aws-bedrock&quot;&gt;AWS Bedrock&lt;/h3&gt;
&lt;p&gt;AWS Bedrock requires a &lt;code&gt;system_prompt&lt;/code&gt; configuration. AWS credentials are automatically loaded from environment variables: &lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt;, &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt;, and &lt;code&gt;AWS_SESSION_TOKEN&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s1&quot;&gt;&apos;bedrock-config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_name&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PROVIDER_BEDROCK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;model&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;eu.anthropic.claude-sonnet-4-20250514-v1:0&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;bedrockRuntimeClient&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;region&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;eu-west-1&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;version&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;latest&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// optional&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;system_prompt&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;You are a helpful assistant.&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required for Bedrock&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;ollama-localself-hosted&quot;&gt;Ollama (local/self-hosted)&lt;/h3&gt;
&lt;p&gt;If Ollama runs outside the Docker SDK on macOS, use &lt;code&gt;http://host.docker.internal:11434/api&lt;/code&gt; as the URL to access the host machine from within Docker containers.&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s1&quot;&gt;&apos;ollama-config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_name&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PROVIDER_OLLAMA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;url&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;http://host.docker.internal:11434/api&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required - use host.docker.internal for Mac when Ollama runs outside Docker&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;model&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;llama3.2&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;parameters&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// optional&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;httpOptions&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// optional&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;timeout&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;connectTimeout&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h4 id=&quot;run-ollama-with-docker-sdk&quot;&gt;Run Ollama with Docker SDK&lt;/h4&gt;
&lt;p&gt;To run Ollama as a service within the Spryker Docker SDK:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create an &lt;code&gt;ollama.yml&lt;/code&gt; file in your project root:&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;3.8&apos;&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;ollama&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ollama/ollama:latest&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;OLLAMA_HOST&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;0.0.0.0:11435&quot;&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;./data/tmp/ollama_data:/root/.ollama&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;private&lt;/span&gt;
            &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;public&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Reference the Ollama compose file in your &lt;code&gt;deploy.dev.yml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;compose&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;yamls&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;./ollama.yml&apos;&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update your AI configuration to use the Ollama service URL:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s1&quot;&gt;&apos;ollama-config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_name&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PROVIDER_OLLAMA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;url&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;http://ollama:11435/api&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// use service name when running inside Docker SDK&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;model&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;llama3.2&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Deploy the changes:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker/sdk boot deploy.dev.yml
docker/sdk up
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pull the required Ollama model:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker/sdk cli &lt;span class=&quot;nb&quot;&gt;exec&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; ollama ollama pull llama3.2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The Ollama data is stored in the &lt;code&gt;./data/tmp/ollama_data&lt;/code&gt; directory, which you should exclude from version control (.gitignore or .dockerignore).&lt;/p&gt;
&lt;h3 id=&quot;google-gemini&quot;&gt;Google Gemini&lt;/h3&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s1&quot;&gt;&apos;gemini-config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_name&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PROVIDER_GEMINI&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;key&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;getenv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;GEMINI_API_KEY&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;model&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;gemini-2.0-flash&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;parameters&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// optional&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;deepseek&quot;&gt;Deepseek&lt;/h3&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s1&quot;&gt;&apos;deepseek-config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_name&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PROVIDER_DEEPSEEK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;key&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;getenv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;DEEPSEEK_API_KEY&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;model&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;deepseek-chat&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;parameters&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// optional&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;huggingface&quot;&gt;HuggingFace&lt;/h3&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s1&quot;&gt;&apos;huggingface-config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_name&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PROVIDER_HUGGINGFACE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;key&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;getenv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;HUGGINGFACE_API_KEY&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;model&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;meta-llama/Llama-3.3-70B-Instruct&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;parameters&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// optional&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;mistral-ai&quot;&gt;Mistral AI&lt;/h3&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s1&quot;&gt;&apos;mistral-config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_name&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PROVIDER_MISTRAL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;key&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;getenv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;MISTRAL_API_KEY&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;model&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;mistral-large-latest&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;parameters&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// optional&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;xai-grok&quot;&gt;xAI Grok&lt;/h3&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s1&quot;&gt;&apos;grok-config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_name&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PROVIDER_GROK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;key&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;getenv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;XAI_API_KEY&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;model&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;grok-2-latest&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;parameters&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// optional&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;azure-openai&quot;&gt;Azure OpenAI&lt;/h3&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s1&quot;&gt;&apos;azure-openai-config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_name&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PROVIDER_AZURE_OPEN_AI&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;provider_config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;key&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;getenv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;AZURE_OPENAI_API_KEY&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;endpoint&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;https://your-resource.openai.azure.com&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;model&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;your-deployment-name&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// required&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;version&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;2024-02-01&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// optional&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;parameters&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// optional&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;use-the-aifoundation-facade&quot;&gt;Use the AiFoundation facade&lt;/h2&gt;
&lt;h3 id=&quot;basic-usage&quot;&gt;Basic usage&lt;/h3&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Pyz\Zed\YourModule\Business&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Generated\Shared\Transfer\PromptMessageTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Generated\Shared\Transfer\PromptRequestTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Spryker\Zed\AiFoundation\Business\AiFoundationFacadeInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;YourBusinessModel&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;AiFoundationFacadeInterface&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$aiFoundationFacade&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;generateContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$userMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$promptRequest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PromptRequestTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setPromptMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PromptMessageTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$userMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aiFoundationFacade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;prompt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$promptRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;using-a-specific-configuration&quot;&gt;Using a specific configuration&lt;/h3&gt;
&lt;p&gt;Specify a configuration name to use a configuration other than the default:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$promptRequest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PromptRequestTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setAiConfigurationName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;anthropic-config&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setPromptMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PromptMessageTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;Explain Spryker modules&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aiFoundationFacade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;prompt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$promptRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;multiple-configurations-example&quot;&gt;Multiple configurations example&lt;/h3&gt;
&lt;p&gt;Configure multiple AI providers for different use cases in your application:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Spryker\Shared\AiFoundation\AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;AI_CONFIGURATIONS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;AI_CONFIGURATION_DEFAULT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;provider_name&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PROVIDER_OPENAI&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;provider_config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;key&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;getenv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;OPENAI_API_KEY&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;model&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;gpt-4o&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;fast-responses&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;provider_name&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PROVIDER_OPENAI&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;provider_config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;key&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;getenv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;OPENAI_API_KEY&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;model&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;gpt-4o-mini&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;system_prompt&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Provide concise, brief responses.&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;available-provider-constants&quot;&gt;Available provider constants&lt;/h2&gt;
&lt;p&gt;The module provides the following provider constants in &lt;code&gt;AiFoundationConstants&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;PROVIDER_OPENAI&lt;/code&gt; - OpenAI (ChatGPT)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PROVIDER_ANTHROPIC&lt;/code&gt; - Anthropic Claude&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PROVIDER_BEDROCK&lt;/code&gt; - AWS Bedrock Runtime&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PROVIDER_GEMINI&lt;/code&gt; - Google Gemini&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PROVIDER_DEEPSEEK&lt;/code&gt; - Deepseek AI&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PROVIDER_HUGGINGFACE&lt;/code&gt; - HuggingFace&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PROVIDER_MISTRAL&lt;/code&gt; - Mistral AI&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PROVIDER_OLLAMA&lt;/code&gt; - Ollama (local/self-hosted)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PROVIDER_GROK&lt;/code&gt; - xAI Grok&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PROVIDER_AZURE_OPEN_AI&lt;/code&gt; - Azure OpenAI&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;transfer-objects&quot;&gt;Transfer objects&lt;/h2&gt;
&lt;h3 id=&quot;promptrequest&quot;&gt;PromptRequest&lt;/h3&gt;
&lt;p&gt;This transfer contains the request data for AI interaction:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;promptMessage&lt;/code&gt; (PromptMessage, required): The message to send to the AI&lt;/li&gt;
&lt;li&gt;&lt;code&gt;aiConfigurationName&lt;/code&gt; (string, optional): The configuration name to use. If not provided, uses &lt;code&gt;AI_CONFIGURATION_DEFAULT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;structuredMessage&lt;/code&gt; (object, optional): A Transfer object that defines the expected response structure for structured responses&lt;/li&gt;
&lt;li&gt;&lt;code&gt;toolSetName&lt;/code&gt; (string[], optional): Array of tool set names to make available to the AI. For details, see &lt;a href=&quot;/docs/dg/dev/ai/ai-foundation/ai-foundation-tool-support.html&quot;&gt;Use AI tools with the AiFoundation module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;conversationReference&lt;/code&gt; (string, optional): Unique identifier for multi-turn conversations. When provided, the message is persisted in conversation history and previous messages are automatically included in the request context. For details, see &lt;a href=&quot;/docs/dg/dev/ai/ai-foundation/ai-foundation-conversation-history.html&quot;&gt;Manage conversation history with the AiFoundation module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;maxRetries&lt;/code&gt; (int, optional): Maximum number of retry attempts for failed requests. Default is 0&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;promptmessage&quot;&gt;PromptMessage&lt;/h3&gt;
&lt;p&gt;This transfer represents a message in the conversation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;content&lt;/code&gt; (string): The text content of the message&lt;/li&gt;
&lt;li&gt;&lt;code&gt;contentData&lt;/code&gt; (array, optional): Additional structured data&lt;/li&gt;
&lt;li&gt;&lt;code&gt;attachments&lt;/code&gt; (Attachment[], optional): File or image attachments&lt;/li&gt;
&lt;li&gt;&lt;code&gt;reasoning&lt;/code&gt; (string, optional): Model chain-of-thought reasoning returned alongside the response. Only populated when the provider returns reasoning blocks (for example, Anthropic extended thinking). &lt;code&gt;null&lt;/code&gt; when the provider does not return reasoning.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;promptresponse&quot;&gt;PromptResponse&lt;/h3&gt;
&lt;p&gt;This transfer contains the AI response:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;message&lt;/code&gt; (PromptMessage): The AI’s response message&lt;/li&gt;
&lt;li&gt;&lt;code&gt;isSuccessful&lt;/code&gt; (bool): Whether the request was successful&lt;/li&gt;
&lt;li&gt;&lt;code&gt;errors&lt;/code&gt; (array, optional): Array of error messages if the request failed&lt;/li&gt;
&lt;li&gt;&lt;code&gt;toolInvocations&lt;/code&gt; (ToolInvocation[], optional): Array of tool invocations made by the AI during response generation&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;attachment&quot;&gt;Attachment&lt;/h3&gt;
&lt;p&gt;This transfer represents a file or image attachment:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;type&lt;/code&gt; (string): Type of attachment (use &lt;code&gt;AiFoundationConstants::ATTACHMENT_TYPE_IMAGE&lt;/code&gt; or &lt;code&gt;ATTACHMENT_TYPE_DOCUMENT&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;content&lt;/code&gt; (string): The content—URL, Base64-encoded data, or a provider-hosted file ID&lt;/li&gt;
&lt;li&gt;&lt;code&gt;contentType&lt;/code&gt; (string): Content type format: &lt;code&gt;ATTACHMENT_CONTENT_TYPE_URL&lt;/code&gt;, &lt;code&gt;ATTACHMENT_CONTENT_TYPE_BASE64&lt;/code&gt;, or &lt;code&gt;ATTACHMENT_CONTENT_TYPE_ID&lt;/code&gt; (for provider-hosted file references such as OpenAI or Anthropic Files API IDs)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mediaType&lt;/code&gt; (string): MIME type (for example, &lt;code&gt;image/png&lt;/code&gt;, &lt;code&gt;application/pdf&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;filename&lt;/code&gt; (string, optional): Original filename for document attachments. Only set when the type is &lt;code&gt;document&lt;/code&gt; and the caller provides it.&lt;/li&gt;
&lt;/ul&gt;
&lt;section class=&apos;info-block info-block--warning&apos;&gt;&lt;i class=&apos;info-block__icon icon-warning&apos;&gt;&lt;/i&gt;&lt;div class=&apos;info-block__content&apos;&gt;&lt;div class=&quot;info-block__title&quot;&gt;AWS Bedrock limitation&lt;/div&gt;
&lt;p&gt;AWS Bedrock does not support URL-based attachments. When using AWS Bedrock as the provider, use &lt;code&gt;ATTACHMENT_CONTENT_TYPE_BASE64&lt;/code&gt; to pass image or document content as Base64-encoded data instead of a URL.&lt;/p&gt;
&lt;/div&gt;&lt;/section&gt;
&lt;h3 id=&quot;toolinvocation&quot;&gt;ToolInvocation&lt;/h3&gt;
&lt;p&gt;This transfer contains information about a tool invocation made by the AI:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;name&lt;/code&gt; (string): The name of the tool that was invoked&lt;/li&gt;
&lt;li&gt;&lt;code&gt;arguments&lt;/code&gt; (array): The arguments passed to the tool&lt;/li&gt;
&lt;li&gt;&lt;code&gt;result&lt;/code&gt; (string): The result returned by the tool execution&lt;/li&gt;
&lt;li&gt;&lt;code&gt;content&lt;/code&gt; (string, optional): Assistant text emitted alongside the tool call (for example, “I will use the calculator now.”). &lt;code&gt;null&lt;/code&gt; when the model did not produce accompanying text.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;reasoning&lt;/code&gt; (string, optional): Model chain-of-thought reasoning emitted alongside the tool call. &lt;code&gt;null&lt;/code&gt; when the provider does not return reasoning blocks.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;structuredmessage&quot;&gt;StructuredMessage&lt;/h3&gt;
&lt;p&gt;Define the expected structure (&lt;code&gt;structuredMessage&lt;/code&gt; property) of the AI response for structured responses. This is a Spryker Transfer object that you can customize based on your requirements.&lt;/p&gt;
&lt;h3 id=&quot;conversation-history&quot;&gt;Conversation History&lt;/h3&gt;
&lt;p&gt;Conversation history is created by &lt;code&gt;conversationReference&lt;/code&gt; and persisted in the database using the &lt;code&gt;spy_ai_conversation_history&lt;/code&gt; table. When you provide a &lt;code&gt;conversationReference&lt;/code&gt; in a prompt request, all messages are automatically stored and previous messages are retrieved to maintain conversation context. For complete details, see &lt;a href=&quot;/docs/dg/dev/ai/ai-foundation/ai-foundation-conversation-history.html&quot;&gt;Manage conversation history with the AiFoundation module&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;about-neuronai-framework&quot;&gt;About NeuronAI framework&lt;/h2&gt;
&lt;p&gt;The AiFoundation module uses the &lt;a href=&quot;https://docs.neuron-ai.dev/&quot;&gt;NeuronAI PHP agentic framework&lt;/a&gt; under the hood. NeuronAI provides the foundational infrastructure for AI provider integrations.&lt;/p&gt;
&lt;p&gt;The Spryker AiFoundation client is designed for simple use cases where you need to send prompts to AI providers and receive responses. This covers most common AI integration scenarios in e-commerce applications.&lt;/p&gt;
&lt;p&gt;For advanced agentic solutions that require complex workflows, multi-agent systems, or custom AI behaviors, you can use the &lt;a href=&quot;https://docs.neuron-ai.dev/&quot;&gt;NeuronAI framework&lt;/a&gt; directly in your project code. However, note that Spryker does not officially support direct usage of NeuronAI APIs outside of the AiFoundation module. If you choose to use NeuronAI directly, you are responsible for maintenance and compatibility with future versions.&lt;/p&gt;
</description>
            <pubDate>Tue, 05 May 2026 06:12:49 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/ai/ai-foundation/ai-foundation-module.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/ai/ai-foundation/ai-foundation-module.html</guid>
            
            
        </item>
        
        <item>
            <title>Install the Product Attribute Visibility feature</title>
            <description>This document describes how to install the [Product Attribute Visibility feature](/docs/pbc/all/product-information-management/latest/base-shop/feature-overviews/product-feature-overview/product-attribute-visibility-overview.html).

## Prerequisites

### Install the required features

| NAME | VERSION | INSTALLATION GUIDE |
| --- | --- | --- |
| Spryker Core | {{page.release_tag}} | [Install the Spryker Core feature](/docs/pbc/all/miscellaneous/latest/install-and-upgrade/install-features/install-the-spryker-core-feature.html) |
| Product | {{page.release_tag}} | [Install the Product feature](/docs/pbc/all/product-information-management/latest/base-shop/install-and-upgrade/install-features/install-the-product-feature.html) |

### Install the required packages

| PACKAGE | VERSION |
| --- | --- |
| spryker-feature/product-experience-management | ^2.2.0 |
| spryker/product-attribute | ^1.20.0 |
| spryker/product-attribute-extension | ^1.2.0 |
| spryker/product-attribute-gui | ^2.3.0 |
| spryker/product-attribute-gui-extension | ^1.0.0 |
| spryker/product-management | ^0.20.8 |
| spryker-shop/cart-page | ^3.58.0 |
| spryker-shop/catalog-page | ^1.36.0 |
| spryker-shop/product-detail-page | ^3.31.0 |
| spryker-shop/product-widget | ^1.6.0 |
| spryker-shop/shop-ui | ^1.106.0 |

```bash
composer require spryker/product-attribute:&quot;^1.20.0&quot; spryker/product-attribute-extension:&quot;^1.2.0&quot; spryker/product-attribute-gui:&quot;^2.3.0&quot; spryker/product-attribute-gui-extension:&quot;^1.0.0&quot; spryker-feature/product-experience-management:&quot;^2.2.0&quot; spryker/product-management:&quot;^0.20.8&quot; spryker-shop/cart-page:&quot;^3.58.0&quot; spryker-shop/catalog-page:&quot;^1.36.0&quot; spryker-shop/product-detail-page:&quot;^3.31.0&quot; spryker-shop/product-widget:&quot;^1.6.0&quot; spryker-shop/shop-ui:&quot;^1.106.0&quot; --update-with-dependencies --ignore-platform-req=ext-grpc
```

## 1) Set up configuration

Set up RabbitMQ and Symfony Messenger configuration for the publish and sync queues.

**src/Pyz/Client/RabbitMq/RabbitMqConfig.php**

```php
&lt;?php

namespace Pyz\Client\RabbitMq;

use SprykerFeature\Shared\ProductExperienceManagement\ProductExperienceManagementConfig;

class RabbitMqConfig extends SprykerRabbitMqConfig
{
    /**
     * @return list&lt;mixed&gt;
     */
    protected function getPublishQueueConfiguration(): array
    {
        return [
            ProductExperienceManagementConfig::PUBLISH_PRODUCT_ATTRIBUTE,
        ];
    }

    /**
     * @return list&lt;string&gt;
     */
    protected function getSynchronizationQueueConfiguration(): array
    {
        return [
            ProductExperienceManagementConfig::PRODUCT_ATTRIBUTE_SYNC_STORAGE_QUEUE,
        ];
    }
}
```

**src/Pyz/Zed/Queue/QueueDependencyProvider.php**

```php
&lt;?php

namespace Pyz\Zed\Queue;

use SprykerFeature\Shared\ProductExperienceManagement\ProductExperienceManagementConfig;
use Spryker\Zed\Event\Communication\Plugin\Queue\EventQueueMessageProcessorPlugin;
use Spryker\Zed\Queue\QueueDependencyProvider as SprykerQueueDependencyProvider;
use Spryker\Zed\Synchronization\Communication\Plugin\Queue\SynchronizationStorageQueueMessageProcessorPlugin;

class QueueDependencyProvider extends SprykerQueueDependencyProvider
{
    /**
     * @return array&lt;string, \Spryker\Zed\Queue\Dependency\Plugin\QueueMessageProcessorPluginInterface&gt;
     */
    protected function getProcessorMessagePlugins(): array
    {
        return [
            ProductExperienceManagementConfig::PUBLISH_PRODUCT_ATTRIBUTE =&gt; new EventQueueMessageProcessorPlugin(),
            ProductExperienceManagementConfig::PRODUCT_ATTRIBUTE_SYNC_STORAGE_QUEUE =&gt; new SynchronizationStorageQueueMessageProcessorPlugin(),
        ];
    }
}
```

**src/Pyz/Client/SymfonyMessenger/SymfonyMessengerConfig.php**

```php
&lt;?php

namespace Pyz\Client\SymfonyMessenger;

use SprykerFeature\Shared\ProductExperienceManagement\ProductExperienceManagementConfig;

class SymfonyMessengerConfig extends SprykerSymfonyMessengerConfig
{
    /**
     * @return list&lt;mixed&gt;
     */
    protected function getPublishQueueConfiguration(): array
    {
        return [
            ProductExperienceManagementConfig::PUBLISH_PRODUCT_ATTRIBUTE,
        ];
    }

    /**
     * @return list&lt;string&gt;
     */
    protected function getSynchronizationQueueConfiguration(): array
    {
        return [
            ProductExperienceManagementConfig::PRODUCT_ATTRIBUTE_SYNC_STORAGE_QUEUE,
        ];
    }
}
```

### Optional: Extend visibility types

By default, the feature provides three visibility types: `PDP`, `PLP`, and `Cart`. To add project-specific visibility types, extend `ProductExperienceManagementConfig` at the project level and override the `getAvailableVisibilityTypes()` method.

**src/Pyz/Shared/ProductExperienceManagement/ProductExperienceManagementConfig.php**

```php
&lt;?php

namespace Pyz\Shared\ProductExperienceManagement;

use SprykerFeature\Shared\ProductExperienceManagement\ProductExperienceManagementConfig as SprykerProductExperienceManagementConfig;

class ProductExperienceManagementConfig extends SprykerProductExperienceManagementConfig
{
    /**
     * @var string
     */
    public const string VISIBILITY_TYPE_WISHLIST = &apos;Wishlist&apos;;

    /**
     * @return array&lt;string&gt;
     */
    public function getAvailableVisibilityTypes(): array
    {
        return array_merge(parent::getAvailableVisibilityTypes(), [
            static::VISIBILITY_TYPE_WISHLIST,
        ]);
    }
}
```

After adding a custom visibility type, implement the corresponding widget or template logic in your Yves layer to render the attribute on the relevant page.

## 2) Set up the database schema and transfer objects

1. Create the following schema file to enable event-driven publishing for product management attributes:

**src/Pyz/Zed/ProductAttribute/Persistence/Propel/Schema/spy_product_management_attribute.schema.xml**

```xml
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;database xmlns=&quot;spryker:schema-01&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; name=&quot;zed&quot; xsi:schemaLocation=&quot;spryker:schema-01 https://static.spryker.com/schema-01.xsd&quot; namespace=&quot;Orm\Zed\ProductAttribute\Persistence&quot; package=&quot;src.Orm.Zed.ProductAttribute.Persistence&quot;&gt;

    &lt;table name=&quot;spy_product_management_attribute&quot;&gt;
        &lt;behavior name=&quot;event&quot;&gt;
            &lt;parameter name=&quot;spy_product_management_attribute_all&quot; column=&quot;*&quot;/&gt;
        &lt;/behavior&gt;
    &lt;/table&gt;

&lt;/database&gt;
```

2. Apply database changes and generate entity and transfer changes:

```bash
console propel:install
console transfer:generate
```

{% info_block warningBox &quot;Verification&quot; %}

Make sure that the following changes have been applied in the database:

| DATABASE ENTITY | TYPE | EVENT |
| --- | --- | --- |
| spy_product_management_attribute.visibility | column | created |
| spy_product_attribute_storage | table | created |

Make sure the following transfer objects have been generated:

| TRANSFER | TYPE | EVENT |
| --- | --- | --- |
| ProductAttributeStorage | class | created |
| ProductAttributeStorage.key | property | created |
| ProductAttributeStorage.inputType | property | created |
| ProductAttributeStorage.isSuper | property | created |
| ProductAttributeStorage.visibilityTypes | property | created |
| ProductManagementAttribute.visibility | property | created |
| ProductManagementAttribute.visibilityTypes | property | created |
| ProductManagementAttributeCollection | class | created |
| ProductManagementAttributeCriteria | class | created |
| ProductManagementAttributeConditions.productManagementAttributeIds | property | created |
| ProductAttributeTableCriteria | class | created |
| ProductAttributeTableCriteria.visibilityTypes | property | created |
| ProductAttributeTableCriteria.withColumns | property | created |
| ProductAttributeTableCriteria.queryConditions | property | created |
| ProductAttributeTableCriteria.conditionCombineOperator | property | created |
| ProductAttributeTableQueryCondition | class | created |
| ProductAttributeQueryCriteria | class | created |
| ProductAttributeQueryCriteria.withColumns | property | created |

{% endinfo_block %}

## 3) Set up behavior

### Set up publisher and synchronization plugins

Register the publisher and synchronization plugins:

| PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |
| --- | --- | --- | --- |
| ProductAttributePublisherTriggerPlugin | Triggers a full publish of product attribute data. | | SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\Publisher |
| ProductAttributeWritePublisherPlugin | Handles create and update events for product attributes and writes data to storage. | | SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\Publisher |
| ProductAttributeSynchronizationDataBulkRepositoryPlugin | Provides product attribute storage data for the synchronization process. | | SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\Synchronization |

**src/Pyz/Zed/Publisher/PublisherDependencyProvider.php**

```php
&lt;?php

namespace Pyz\Zed\Publisher;

use SprykerFeature\Shared\ProductExperienceManagement\ProductExperienceManagementConfig;
use SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\Publisher\ProductAttributePublisherTriggerPlugin;
use SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\Publisher\ProductAttributeWritePublisherPlugin;
use Spryker\Zed\Publisher\PublisherDependencyProvider as SprykerPublisherDependencyProvider;

class PublisherDependencyProvider extends SprykerPublisherDependencyProvider
{
    /**
     * @return array&lt;string, list&lt;\Spryker\Zed\PublisherExtension\Dependency\Plugin\PublisherPluginInterface&gt;&gt;
     */
    protected function getPublisherPlugins(): array
    {
        return array_merge(
            parent::getPublisherPlugins(),
            $this-&gt;getProductAttributeStoragePlugins(),
        );
    }

    /**
     * @return list&lt;\Spryker\Zed\PublisherExtension\Dependency\Plugin\PublisherTriggerPluginInterface&gt;
     */
    protected function getPublisherTriggerPlugins(): array
    {
        return [
            new ProductAttributePublisherTriggerPlugin(),
        ];
    }

    /**
     * @return list&lt;\Spryker\Zed\PublisherExtension\Dependency\Plugin\PublisherPluginInterface&gt;
     */
    protected function getProductAttributeStoragePlugins(): array
    {
        return [
            ProductExperienceManagementConfig::PUBLISH_PRODUCT_ATTRIBUTE =&gt; [
                new ProductAttributeWritePublisherPlugin(),
            ],
        ];
    }
}
```

**src/Pyz/Zed/Synchronization/SynchronizationDependencyProvider.php**

```php
&lt;?php

namespace Pyz\Zed\Synchronization;

use SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\Synchronization\ProductAttributeSynchronizationDataBulkRepositoryPlugin;
use Spryker\Zed\Synchronization\SynchronizationDependencyProvider as SprykerSynchronizationDependencyProvider;

class SynchronizationDependencyProvider extends SprykerSynchronizationDependencyProvider
{
    /**
     * @return list&lt;\Spryker\Zed\SynchronizationExtension\Dependency\Plugin\SynchronizationDataPluginInterface&gt;
     */
    protected function getSynchronizationDataStorePlugins(): array
    {
        return [
            new ProductAttributeSynchronizationDataBulkRepositoryPlugin(),
        ];
    }
}
```

{% info_block warningBox &quot;Verification&quot; %}

Make sure that when you create or update a product attribute in the Back Office, the attribute data is published and synchronized to the `spy_product_attribute_storage` table:

1. In the Back Office, go to **Catalog &gt; Attributes**.
2. Edit an attribute and change its **Display At** value.
3. Click **Save**.
4. Check that the `spy_product_attribute_storage` table contains the updated attribute data.

{% endinfo_block %}

### Set up product attribute query expander

Register the query expander plugin:

| PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |
| --- | --- | --- | --- |
| VisibilityProductAttributeQueryExpanderPlugin | Expands the product attribute query with the visibility column. | | SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttribute |
| VisibilitySuggestKeysQueryExpanderPlugin | Expands the suggest keys query with visibility filtering. | | SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttribute |
| VisibilitySuggestKeysExpanderPlugin | Expands the suggest keys result with visibility data. | | SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttribute |

**src/Pyz/Zed/ProductAttribute/ProductAttributeDependencyProvider.php**

```php
&lt;?php

namespace Pyz\Zed\ProductAttribute;

use Spryker\Zed\ProductAttribute\ProductAttributeDependencyProvider as SprykerProductAttributeDependencyProvider;
use SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttribute\VisibilityProductAttributeQueryExpanderPlugin;
use SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttribute\VisibilitySuggestKeysExpanderPlugin;
use SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttribute\VisibilitySuggestKeysQueryExpanderPlugin;

class ProductAttributeDependencyProvider extends SprykerProductAttributeDependencyProvider
{
    /**
     * @return list&lt;\Spryker\Zed\ProductAttributeExtension\Dependency\Plugin\ProductAttributeQueryExpanderPluginInterface&gt;
     */
    protected function getProductAttributeQueryExpanderPlugins(): array
    {
        return [
            new VisibilityProductAttributeQueryExpanderPlugin(),
        ];
    }

    /**
     * @return list&lt;\Spryker\Zed\ProductAttributeExtension\Dependency\Plugin\SuggestKeysQueryExpanderPluginInterface&gt;
     */
    protected function getSuggestKeysQueryExpanderPlugins(): array
    {
        return [
            new VisibilitySuggestKeysQueryExpanderPlugin(),
        ];
    }

    /**
     * @return list&lt;\Spryker\Zed\ProductAttributeExtension\Dependency\Plugin\SuggestKeysExpanderPluginInterface&gt;
     */
    protected function getSuggestKeysExpanderPlugins(): array
    {
        return [
            new VisibilitySuggestKeysExpanderPlugin(),
        ];
    }
}
```

### Set up Back Office attribute form and table plugins

Register the Back Office plugins for the attribute management UI:

| PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |
| --- | --- | --- | --- |
| VisibilityAttributeTableConfigExpanderPlugin | Expands the attribute table configuration with the visibility column. | | SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttributeGui |
| VisibilityAttributeTableHeaderExpanderPlugin | Adds the Display At header to the attribute table. | | SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttributeGui |
| VisibilityAttributeTableDataExpanderPlugin | Renders visibility badges in attribute table rows. | | SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttributeGui |
| VisibilityAttributeTableCriteriaExpanderPlugin | Adds visibility filter conditions to the attribute table query. | | SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttributeGui |
| VisibilityAttributeFormExpanderPlugin | Adds the visibility types select field to the attribute form. | | SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttributeGui |
| VisibilityAttributeFormDataProviderExpanderPlugin | Populates the attribute form with existing visibility data. | | SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttributeGui |
| VisibilityAttributeFormTransferMapperExpanderPlugin | Maps visibility types from the form to the attribute transfer object. | | SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttributeGui |
| VisibilityAttributeTableFilterFormExpanderPlugin | Adds a visibility type filter to the attribute table. | | SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttributeGui |

**src/Pyz/Zed/ProductAttributeGui/ProductAttributeGuiDependencyProvider.php**

```php
&lt;?php

namespace Pyz\Zed\ProductAttributeGui;

use Spryker\Zed\ProductAttributeGui\ProductAttributeGuiDependencyProvider as SprykerProductAttributeGuiDependencyProvider;
use SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttributeGui\VisibilityAttributeFormDataProviderExpanderPlugin;
use SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttributeGui\VisibilityAttributeFormExpanderPlugin;
use SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttributeGui\VisibilityAttributeFormTransferMapperExpanderPlugin;
use SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttributeGui\VisibilityAttributeTableCriteriaExpanderPlugin;
use SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttributeGui\VisibilityAttributeTableConfigExpanderPlugin;
use SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttributeGui\VisibilityAttributeTableDataExpanderPlugin;
use SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttributeGui\VisibilityAttributeTableFilterFormExpanderPlugin;
use SprykerFeature\Zed\ProductExperienceManagement\Communication\Plugin\ProductAttributeGui\VisibilityAttributeTableHeaderExpanderPlugin;

class ProductAttributeGuiDependencyProvider extends SprykerProductAttributeGuiDependencyProvider
{
    /**
     * @return array&lt;\Spryker\Zed\ProductAttributeGuiExtension\Dependency\Plugin\AttributeTableConfigExpanderPluginInterface&gt;
     */
    protected function getAttributeTableConfigExpanderPlugins(): array
    {
        return [
            new VisibilityAttributeTableConfigExpanderPlugin(),
        ];
    }

    /**
     * @return array&lt;\Spryker\Zed\ProductAttributeGuiExtension\Dependency\Plugin\AttributeTableHeaderExpanderPluginInterface&gt;
     */
    protected function getAttributeTableHeaderExpanderPlugins(): array
    {
        return [
            new VisibilityAttributeTableHeaderExpanderPlugin(),
        ];
    }

    /**
     * @return array&lt;\Spryker\Zed\ProductAttributeGuiExtension\Dependency\Plugin\AttributeTableDataExpanderPluginInterface&gt;
     */
    protected function getAttributeTableDataExpanderPlugins(): array
    {
        return [
            new VisibilityAttributeTableDataExpanderPlugin(),
        ];
    }

    /**
     * @return array&lt;\Spryker\Zed\ProductAttributeGuiExtension\Dependency\Plugin\AttributeTableCriteriaExpanderPluginInterface&gt;
     */
    protected function getAttributeTableCriteriaExpanderPlugins(): array
    {
        return [
            new VisibilityAttributeTableCriteriaExpanderPlugin(),
        ];
    }

    /**
     * @return array&lt;\Spryker\Zed\ProductAttributeGuiExtension\Dependency\Plugin\AttributeFormExpanderPluginInterface&gt;
     */
    protected function getAttributeFormExpanderPlugins(): array
    {
        return [
            new VisibilityAttributeFormExpanderPlugin(),
        ];
    }

    /**
     * @return array&lt;\Spryker\Zed\ProductAttributeGuiExtension\Dependency\Plugin\AttributeFormDataProviderExpanderPluginInterface&gt;
     */
    protected function getAttributeFormDataProviderExpanderPlugins(): array
    {
        return [
            new VisibilityAttributeFormDataProviderExpanderPlugin(),
        ];
    }

    /**
     * @return array&lt;\Spryker\Zed\ProductAttributeGuiExtension\Dependency\Plugin\AttributeFormTransferMapperExpanderPluginInterface&gt;
     */
    protected function getAttributeFormTransferMapperExpanderPlugins(): array
    {
        return [
            new VisibilityAttributeFormTransferMapperExpanderPlugin(),
        ];
    }

    /**
     * @return array&lt;\Spryker\Zed\ProductAttributeGuiExtension\Dependency\Plugin\AttributeTableFilterFormExpanderPluginInterface&gt;
     */
    protected function getAttributeTableFilterFormExpanderPlugins(): array
    {
        return [
            new VisibilityAttributeTableFilterFormExpanderPlugin(),
        ];
    }
}
```

{% info_block warningBox &quot;Verification&quot; %}

Make sure that the attribute management UI in the Back Office includes the visibility features:

1. In the Back Office, go to **Catalog &gt; Attributes**.
2. Verify that the attribute table has a **Display At** column with visibility badges.
3. Verify that you can filter the table by visibility type using the filter dropdown.
4. Click **Edit** next to an attribute.
5. Verify that the attribute form includes a **Display At** field where you can select one or more visibility types.

{% endinfo_block %}

## 4) Set up widgets

Register the following global widgets:

| WIDGET | DESCRIPTION | NAMESPACE |
| --- | --- | --- |
| ProductAttributeVisibilityPdpWidget | Displays product attributes configured for PDP visibility with schema.org structured data. | SprykerFeature\Yves\ProductExperienceManagement\Widget |
| ProductAttributeVisibilityPlpWidget | Displays product attributes configured for PLP visibility as badges. | SprykerFeature\Yves\ProductExperienceManagement\Widget |
| ProductAttributeVisibilityCartWidget | Displays product attributes configured for Cart visibility as badges. | SprykerFeature\Yves\ProductExperienceManagement\Widget |

**src/Pyz/Yves/ShopApplication/ShopApplicationDependencyProvider.php**

```php
&lt;?php

namespace Pyz\Yves\ShopApplication;

use SprykerFeature\Yves\ProductExperienceManagement\Widget\ProductAttributeVisibilityCartWidget;
use SprykerFeature\Yves\ProductExperienceManagement\Widget\ProductAttributeVisibilityPdpWidget;
use SprykerFeature\Yves\ProductExperienceManagement\Widget\ProductAttributeVisibilityPlpWidget;
use SprykerShop\Yves\ShopApplication\ShopApplicationDependencyProvider as SprykerShopApplicationDependencyProvider;

class ShopApplicationDependencyProvider extends SprykerShopApplicationDependencyProvider
{
    /**
     * @return list&lt;string&gt;
     */
    protected function getGlobalWidgets(): array
    {
        return [
            ProductAttributeVisibilityPdpWidget::class,
            ProductAttributeVisibilityPlpWidget::class,
            ProductAttributeVisibilityCartWidget::class,
        ];
    }
}
```

## 5) Set up Yves templates

If you have overridden the default Twig templates at the project level, add the following widget calls to display product attributes on the Storefront.

### Product Detail Page (PDP)

**src/Pyz/Yves/ProductDetailPage/Theme/default/components/molecules/product-detail/product-detail.twig**

{% raw %}

```twig
{% widget &apos;ProductAttributeVisibilityPdpWidget&apos; args [data.product.idProductAbstract, data.product.idProductConcrete | default(null),] only %}
{% nowidget %}
{% endwidget %}
```

{% endraw %}

### Product Listing Page (PLP)

**src/Pyz/Yves/ProductWidget/Theme/default/components/molecules/catalog-product/catalog-product.twig**

{% raw %}

```twig
{% widget &apos;ProductAttributeVisibilityPlpWidget&apos; args [data.products, data.product.idProductAbstract] only %}
{% nowidget %}
{% endwidget %}
```

{% endraw %}

If you have overridden `Yves/CatalogPage/Theme/default/templates/page-layout-catalog/page-layout-catalog.twig` at the project level, update the `CatalogPageProductWidget` call to pass `data.products` as an additional argument:

**src/Pyz/Yves/CatalogPage/Theme/default/templates/page-layout-catalog/page-layout-catalog.twig**

{% raw %}

```twig
{% widget &apos;CatalogPageProductWidget&apos; args [product, data.viewMode, data.products] with {
```

{% endraw %}

If you have overridden `Yves/ShopUi/Theme/default/components/molecules/product-item/product-item.twig` or `Yves/ShopUi/Theme/default/components/molecules/product-item-list/product-item-list.twig` at the project level, add the following block to each template in the location where the widget should be rendered:

**src/Pyz/Yves/ShopUi/Theme/default/components/molecules/product-item/product-item.twig**
**src/Pyz/Yves/ShopUi/Theme/default/components/molecules/product-item-list/product-item-list.twig**

{% raw %}

```twig
{% block productAttributeVisibility %}{% endblock %}
```

{% endraw %}

### Cart

**src/Pyz/Yves/CartPage/Theme/default/components/molecules/product-cart-item/product-cart-item.twig**

{% raw %}

```twig
{% widget &apos;ProductAttributeVisibilityCartWidget&apos; args [data.cart is iterable ? null : data.cart, data.product.idProductAbstract, data.product.idProductConcrete] only %}
{% nowidget %}
{% endwidget %}
```

{% endraw %}

{% info_block warningBox &quot;Verification&quot; %}

Make sure the product attributes are displayed on the Storefront based on their visibility configuration:

1. In the Back Office, configure an attribute with **PDP** visibility.
2. On the Storefront, open the product detail page and verify the attribute is displayed.
3. Configure an attribute with **PLP** visibility and verify it appears as a badge on the product listing page.
4. Configure an attribute with **Cart** visibility and add the product to the cart. Verify the attribute badge is displayed in the cart.

{% endinfo_block %}

## 6) Set up data import

### Add facade dependencies

Register the required facade dependencies in the data import module.

**src/Pyz/Zed/DataImport/DataImportDependencyProvider.php**

```php
&lt;?php

namespace Pyz\Zed\DataImport;

use Spryker\Zed\DataImport\DataImportDependencyProvider as SprykerDataImportDependencyProvider;
use Spryker\Zed\Kernel\Container;

class DataImportDependencyProvider extends SprykerDataImportDependencyProvider
{
    /**
     * @var string
     */
    public const FACADE_PRODUCT_EXPERIENCE_MANAGEMENT = &apos;FACADE_PRODUCT_EXPERIENCE_MANAGEMENT&apos;;

    public function provideBusinessLayerDependencies(Container $container): Container
    {
        $container = parent::provideBusinessLayerDependencies($container);
        $container = $this-&gt;addProductExperienceManagementFacade($container);

        return $container;
    }

    protected function addProductExperienceManagementFacade(Container $container): Container
    {
        $container-&gt;set(static::FACADE_PRODUCT_EXPERIENCE_MANAGEMENT, function (Container $container) {
            return $container-&gt;getLocator()-&gt;productExperienceManagement()-&gt;facade();
        });

        return $container;
    }
}
```

### Update the product management attribute writer

Extend `ProductManagementAttributeWriter` to handle the `visibility` column during import. The writer saves the visibility value to the `spy_product_management_attribute` table, triggers a publish event, and validates visibility types against the allowed values.

**src/Pyz/Zed/DataImport/Business/Model/ProductManagementAttribute/ProductManagementAttributeWriter.php**

```php
&lt;?php

namespace Pyz\Zed\DataImport\Business\Model\ProductManagementAttribute;

use Spryker\Zed\DataImport\Business\Exception\DataImportException;
use Spryker\Zed\DataImport\Business\Model\DataImportStep\PublishAwareStep;
use Spryker\Zed\DataImport\Business\Model\DataSet\DataSetInterface;
use SprykerFeature\Shared\ProductExperienceManagement\ProductExperienceManagementConfig;
use SprykerFeature\Zed\ProductExperienceManagement\Business\ProductExperienceManagementFacadeInterface;

class ProductManagementAttributeWriter extends PublishAwareStep implements DataImportStepInterface
{
    protected const string KEY_VISIBILITY = &apos;visibility&apos;;

    public function __construct(
        protected readonly ProductExperienceManagementFacadeInterface $productExperienceManagementFacade,
    ) {
    }

    public function execute(DataSetInterface $dataSet): void
    {
        // ... existing logic for finding or creating entity ...

        $visibility = (string)$dataSet[static::KEY_VISIBILITY] ?? &apos;&apos;;

        if ($visibility !== &apos;&apos;) {
            $visibility = $this-&gt;normalizeVisibility($visibility, $dataSet[&apos;key&apos;]);
        }

        $productManagementAttributeEntity
            -&gt;setAllowInput($dataSet[&apos;allow_input&apos;])
            -&gt;setInputType($dataSet[&apos;input_type&apos;])
            -&gt;setVisibility($visibility);

        $productManagementAttributeEntity-&gt;save();

        $this-&gt;addPublishEvents(
            ProductExperienceManagementConfig::PRODUCT_ATTRIBUTE_PUBLISH,
            $productManagementAttributeEntity-&gt;getIdProductManagementAttribute(),
        );

        // ... existing logic for attribute values ...
    }

    protected function normalizeVisibility(string $visibility, string $attributeKey): string
    {
        $visibilityTypes = array_map(&apos;trim&apos;, explode(&apos;,&apos;, $visibility));
        $allowedVisibilityTypes = $this-&gt;productExperienceManagementFacade-&gt;getAvailableVisibilityTypes();
        $allowedVisibilityTypesMap = array_combine(
            array_map(&apos;strtolower&apos;, $allowedVisibilityTypes),
            $allowedVisibilityTypes,
        );

        $normalized = [];

        foreach ($visibilityTypes as $visibilityType) {
            $canonical = $allowedVisibilityTypesMap[strtolower($visibilityType)] ?? null;
            if ($canonical === null) {
                throw new DataImportException(
                    sprintf(
                        &apos;Invalid visibility type &quot;%s&quot; for attribute &quot;%s&quot;. Allowed: %s (or empty).&apos;,
                        $visibilityType,
                        $attributeKey,
                        implode(&apos;, &apos;, $allowedVisibilityTypes),
                    ),
                );
            }

            $normalized[] = $canonical;
        }

        return implode(&apos;,&apos;, $normalized);
    }
}
```

Wire the facade into the writer via the business factory.

**src/Pyz/Zed/DataImport/Business/DataImportBusinessFactory.php**

```php
&lt;?php

namespace Pyz\Zed\DataImport\Business;

use Pyz\Zed\DataImport\Business\Model\ProductManagementAttribute\ProductManagementAttributeWriter;
use Pyz\Zed\DataImport\DataImportDependencyProvider;
use Spryker\Zed\DataImport\Business\DataImportBusinessFactory as SprykerDataImportBusinessFactory;
use SprykerFeature\Zed\ProductExperienceManagement\Business\ProductExperienceManagementFacadeInterface;

class DataImportBusinessFactory extends SprykerDataImportBusinessFactory
{
    // In createProductManagementAttributeImporter(), replace:
    //     -&gt;addStep(new ProductManagementAttributeWriter());
    // with:
    //     -&gt;addStep(new ProductManagementAttributeWriter(
    //         $this-&gt;getProductExperienceManagementFacade(),
    //     ));

    protected function getProductExperienceManagementFacade(): ProductExperienceManagementFacadeInterface
    {
        return $this-&gt;getProvidedDependency(DataImportDependencyProvider::FACADE_PRODUCT_EXPERIENCE_MANAGEMENT);
    }
}
```

### Prepare and import data

1. Add the `visibility` column to the existing `product_management_attribute.csv` file.

   File: **data/import/common/common/product_management_attribute.csv**

```csv
key,input_type,allow_input,is_multiple,values,key_translation.en_US,key_translation.de_DE,value_translations.en_US,value_translations.de_DE,visibility
storage_capacity,text,no,no,&quot;16 GB, 32 GB, 64 GB, 128 GB&quot;,Storage Capacity,Speichergröße,,,PDP
color,text,no,yes,&quot;white, black, grey&quot;,Color,Farbe,&quot;white, black, grey&quot;,&quot;weiß, schwarz, grau&quot;,&quot;PDP,PLP,Cart&quot;
brand,text,yes,no,,Brand,Marke,,,PDP
internal_sku,text,yes,no,,Internal SKU,Interne SKU,,,,
```

| COLUMN | REQUIRED | DATA TYPE | DATA EXAMPLE | DATA EXPLANATION |
| --- | --- | --- | --- | --- |
| key | ✓ | string | color | Unique attribute key. |
| input_type | ✓ | string | text | Input type for the attribute. |
| allow_input | ✓ | string | no | Whether custom input is allowed. |
| is_multiple | ✓ | string | no | Whether multiple values are supported. |
| values | | string | &quot;white, black, grey&quot; | Predefined attribute values. |
| visibility | | string | &quot;PDP,PLP,Cart&quot; | Comma-separated list of visibility types. Valid values: `PDP`, `PLP`, `Cart`. Leave empty for internal-only attributes. |

2. Import data:

```bash
console data:import product-management-attribute
```

{% info_block warningBox &quot;Verification&quot; %}

Make sure that the product attribute visibility data is imported correctly:

1. In the Back Office, go to **Catalog &gt; Attributes**.
2. Verify that each attribute displays the correct visibility types in the **Display At** column.
3. Check that the `spy_product_management_attribute` table contains the correct `visibility` values.

{% endinfo_block %}
</description>
            <pubDate>Mon, 04 May 2026 15:00:02 +0000</pubDate>
            <link>https://docs.spryker.com/docs/pbc/all/product-information-management/latest/base-shop/install-and-upgrade/install-features/install-the-product-attribute-visibility-feature.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/pbc/all/product-information-management/latest/base-shop/install-and-upgrade/install-features/install-the-product-attribute-visibility-feature.html</guid>
            
            
        </item>
        
        <item>
            <title>Release notes 202604.0</title>
            <description>Spryker Cloud Commerce OS is an end-to-end solution for digital commerce. This document contains a business-level description of new features and improvements.

For information about installing Spryker, see [Getting started guide](/docs/dg/dev/development-getting-started-guide).

## B2B Business-Ready Commerce Experiences

### Back Office Configuration Framework is now Generally Available {% include badge.html type=&quot;feature&quot; %}

Spryker has made the Back Office Configuration Framework generally available, delivering key enterprise‑readiness improvements. The release enhances governance, discoverability, and usability for managing business‑relevant configuration directly in the Back Office. Configuration changes are now easier to understand, control, and audit.

{% include carousel.html
images=&quot;
https://spryker.s3.eu-central-1.amazonaws.com/docs/About/Releases/release-notes-202604/backoffice_framework.png||&quot;
%}

**Key capabilities:**
- Audit logging for configuration changes
- Improved search and discoverability of configuration options
- UX enhancements for a more reliable configuration experience
- CLI-based import support for faster setup and operational workflows
- Clear visibility into conflicts between code-based and Back Office configuration

**Business benefits:**
- Reduces time-to-change by enabling operations teams to adjust configuration without developer involvement, backed by a full audit trail.
- Minimizes the risk of costly production disruptions through better validation and conflict visibility before changes go live.
- Supports broader enterprise adoption with stronger governance and operability.

**Documentation:**
- [Back Office Configuration Framework](/docs/pbc/all/back-office/latest/base-shop/backoffice-configuration-framework.html)
- [Developer Guide Configuration Management](/docs/dg/dev/backend-development/configuration-management)
- [Install the Back Office Configuration Framework feature](/docs/dg/dev/integrate-and-configure/integrate-confguration-feature.html)

### Basic Shop Theming {% include badge.html type=&quot;feature&quot; %}

Business users can now manage core branding settings directly in the Back Office without code changes or deployments. This provides a standardized way to apply basic theming across Storefront, the Back Office, and Merchant Portal.

{% include carousel.html
images=&quot;
https://spryker.s3.eu-central-1.amazonaws.com/docs/About/Releases/release-notes-202604/theming_1.png||::
https://spryker.s3.eu-central-1.amazonaws.com/docs/About/Releases/release-notes-202604/theming_2.png||&quot;
%}

**Key capabilities:**
- Supports theme management with global and store-specific scope.
- Lets users upload and manage logos for Storefront, the Back Office, and Merchant Portal.
- Provides configuration for core brand colors, button styles and text colors.
- Uses a standardized Back Office configuration experience for theme administration.

**Business benefits:**
- Speeds up demo preparation, POCs, and early customer activation through instant, self-service branding configuration.
- Shop operators can now apply and adjust their brand CI across all Spryker touchpoints at any time directly in the Back Office, without developer involvement or redeployment.

**Documentation:**
- [Feature Overview](/docs/pbc/all/cart-and-checkout/latest/base-shop/feature-overviews/purchasing-control-feature-overview.html)
- [Installation Guide](/docs/pbc/all/cart-and-checkout/latest/base-shop/install-and-upgrade/install-features/install-the-purchasing-control-feature.html)

### Budget &amp; Cost Centers {% include badge.html type=&quot;feature,early-access&quot; %}

We introduced an Early Access version of budgets and cost centers to support policy-driven purchasing in B2B procurement. The release covers core budget enforcement and its integration with approval workflows.

**Key capabilities:**
- Lets companies create and manage cost centers and assign buyers to them.
- Supports budget creation with configurable enforcement rules such as block, warn, or require approval.
- Adds cost center selection and budget validation during checkout.
- Integrates budget-triggered approvals with Spryker&apos;s existing Approval Process.
- Tracks budget consumption and restoration as orders progress.

**Business benefits:**
- Improves financial control and purchasing compliance.
- Reduces overspending risk with enforceable budget rules.
- Aligns procurement workflows with departmental or project-based spending structures.
- Provides an early demoable foundation for customer and partner conversations.

**Documentation:**
- [Purchasing Control Feature Overview](/docs/pbc/all/cart-and-checkout/latest/base-shop/feature-overviews/purchasing-control-feature-overview)
- [Install Purchasing Control Feature Overview](/docs/pbc/all/cart-and-checkout/latest/base-shop/install-and-upgrade/install-features/install-the-purchasing-control-feature)

### Back Office Product Import &amp; Export {% include badge.html type=&quot;feature,early-access&quot; %}

Spryker now offers product import and export via the Back Office, reducing reliance on developer‑driven CLI tooling. Business users can prepare and update catalogs faster during onboarding, launches, and routine maintenance. This improves operational speed and gives teams more control over their product data processes.

{% include carousel.html
images=&quot;
https://spryker.s3.eu-central-1.amazonaws.com/docs/About/Releases/release-notes-202604/bo_import_export_1.png||::
https://spryker.s3.eu-central-1.amazonaws.com/docs/About/Releases/release-notes-202604/bo_import_export_2.png||::
https://spryker.s3.eu-central-1.amazonaws.com/docs/About/Releases/release-notes-202604/bo_import_export_3.png||&quot;
%}

**Key capabilities:**
- Import and export product data directly from the Back Office
- Single‑file product import, replacing multiple CLI‑required files
- CSV‑based jobs with reusable job/run concepts and clear validation feedback

**Business benefits:**
- Significantly simplifies adding products to the catalog, replacing multi‑file CLI imports with a single, business‑friendly file
- Accelerates catalog preparation for new launches and environment migrations
- Empowers business users with self‑service error resolution, minimizing developer involvement

**Documentation:**
- [Product Experience Management](/docs/pbc/all/product-experience-management/latest/product-experience-management.html)
- [Install the Product Experience Management feature](/docs/pbc/all/product-experience-management/latest/install-the-product-experience-management-feature.html)

### Product attribute display types {% include badge.html type=&quot;feature&quot; %}

You can now control where product attributes are visible without project-specific customization. This helps keep internal operational data hidden while displaying only relevant information to buyers.

**Key capabilities:**
- Adds visibility types for product attributes.
- Supports internal-only attributes as well as attributes shown on PDP, PLP, and cart-related experiences.
- Provides native configuration for attribute visibility management.

**Business benefits:**
- Shop operators can now control which attributes are displayed where across the storefront, making it easier to surface the right product information at the right place to support buyer decision-making and product discovery.
- Internal attributes can be managed separately to support operational or process-related needs without ever being exposed to buyers.

**Documentation:**
- [Product Attribute Display Types](/docs/pbc/all/product-information-management/latest/base-shop/feature-overviews/product-feature-overview/product-attribute-visibility-overview)
- [Install Product Attribute Visibility Feature](/docs/pbc/all/product-information-management/latest/base-shop/install-and-upgrade/install-features/install-the-product-attribute-visibility-feature)

### Spryker Storefront Design System Foundation {% include badge.html type=&quot;feature&quot; %}

Building storefronts without a common foundation meant repeated work, slower delivery, and experiences that looked and felt different every time. This release introduces a unified design system with shared foundations and reusable components, so teams work from common building blocks. The result is faster implementation, easier adoption, and the ability to scale storefront delivery without scaling complexity.

**Key capabilities:**
- Defines the design system foundation with shared tokens and naming conventions.
- Introduces token-driven implementation patterns for new storefront components.
- Adds composite component patterns built from core UI elements.
- Covers common structures such as cards, buttons, input fields, headers, search and more.

**Business benefits:**
- Improves consistency across storefront experiences.
- Reduces duplicate design and frontend implementation effort.
- Accelerates feature delivery with reusable UI patterns.
- Creates a stronger foundation for future storefront evolution.

**Documentation:**
- [How to use design system tokens](/docs/dg/dev/frontend-development/latest/design-tokens#how-it-works)

### Back Office support for merchant product ownership {% include badge.html type=&quot;improvement&quot; %}

Marketplace operators can now manage merchant ownership of products directly in the Back Office, without relying on the Merchant Portal. This makes it easier to maintain accurate product data in centrally managed or hybrid marketplace models. The result is smoother operations and clearer accountability across the catalog.

**Key capabilities:**
- Assign or update merchant ownership for any product directly in Back Office workflows.
- See merchant ownership instantly within product management views.
- Maintain merchant‑related product data as part of your standard PIM processes.

**Business benefits:**
- Strengthens support for centrally managed catalogs and hybrid marketplace models, giving operators more flexibility in how they run their marketplace.
- Improves transparency and control, making ownership clear, consistent, and auditable.
- Reduces reliance on workarounds and custom tooling, lowering operational overhead.
- Supports more flexible marketplace operations, enabling teams to scale product management with confidence.

**Documentation:**
- [Marketplace Create Abstract Products](/docs/pbc/all/product-information-management/latest/marketplace/manage-in-the-back-office/products/abstract-products/create-abstract-products#defining-general-settings)

### Back Office Frontend Modernisation {% include badge.html type=&quot;improvement&quot; %}

We delivered the first phase of the Back Office theme modernisation to improve clarity, consistency, and responsiveness. This update creates a more usable and scalable visual foundation without changing the overall information architecture.

**Key capabilities:**
- Improves visual hierarchy and component consistency across the Back Office.
- Reduces UX debt introduced by legacy Inspinia defaults.
- Enhances spacing, density, emphasis, and table presentation.
- Provides a more stable foundation for future Back Office UX improvements.

**Business benefits:**
- Improves daily usability for Back Office users.
- Makes the Back Office more credible and demo-ready.
- Reduces the need for one-off CSS customizations.
- Establishes a better base for future product evolution.

### Streamlined Login and Session Recovery Experience {% include badge.html type=&quot;improvement&quot; %}

Logging in should feel like picking up where you left off, not starting over. With this release, users across the Back Office, Storefront, and Marketplace are presented with a meaningful dashboard featuring quick actions for common tasks, including viewing orders, adding products, and checking returns. After a session timeout, users are redirected back to the page they were on so they do not lose track of what they were doing.

**Key capabilities:**
- Redirects Back Office users to the dashboard instead of a blank technical page after login.
- Adds action-oriented quick actions to the Back Office dashboard for common tasks such as viewing orders, adding products, opening the catalog, and checking returns.
- Restores the last visited page after session timeout across the Back Office, Storefront, and Marketplace.
- Reopens create and edit pages after re-login, while unsaved data is not preserved.

**Business benefits:**
- Reduces onboarding friction for new users.
- Helps operational users continue workflows faster after session expiration.
- Improves usability and perceived product maturity across core daily journeys.
- Makes demos and first-touch product experiences more intuitive.

## Connected, and AI-Enabled Platform

### Spryker Now Ships with AI Foundation and Smart Product Enrichment {% include badge.html type=&quot;improvement,early-access&quot; %}

Spryker now includes the AI Foundation and Smart PIM out of the box, allowing merchants to adopt AI‑assisted catalog enrichment with minimal setup. Product content can be improved, translated, and enriched directly in the Back Office using AI, reducing manual work and improving content quality. Customers only need to connect their preferred AI provider to start benefiting from AI‑powered product enhancements, with governance automatically handled through AI Foundation.

**Key capabilities**
- Enhances and translates product names and descriptions using AI
- Generates alt‑text for product images and suggests suitable product categories
- Delivered by default in Spryker, requiring only AI provider configuration

**Business benefits**
- Reduces manual effort in creating and refining product content across the catalog
- Makes AI adoption easier by providing a pre‑configured integration layer with built‑in governance and provider flexibility
- Speeds up catalog enrichment and localization for merchants operating across multiple markets

**Documentation**
- [AI Foundation Overview](/docs/dg/dev/ai/ai-foundation/ai-foundation-module)
- [Smart PIM](/docs/pbc/all/ai-commerce/latest/smart-pim)

### Smart Back Office Assistant {% include badge.html type=&quot;feature,early-access&quot; %}

Spryker introduces the Smart Back Office Assistant, enabling operators to perform Back Office tasks through natural language instead of relying solely on manual navigation. Operators can get guidance on where to find features, ask operational and order‑related questions, and create discounts directly through chat. This makes Back Office work faster, more intuitive, and easier for all user types.

{% include carousel.html
images=&quot;
https://spryker.s3.eu-central-1.amazonaws.com/docs/About/Releases/release-notes-202604/bo_ai_assistant.png||&quot;
%}

**Key capabilities**
- Provides navigation and operational guidance to help users quickly find functions and understand Back Office workflows
- Answers order‑related questions, including order status and operational details
- Assists to complete forms, for example, by enabling discount creation directly through chat.

**Business benefits**
- Reduces time spent searching for pages and completing repetitive tasks
- Improves usability for operators who are less familiar with Back Office structure or workflows
- Helps prevent errors by guiding operators through correctly structured inputs and actions

**Documentation**
- [Back Office Assistant](/docs/dg/dev/ai/ai-commerce/ai-commerce-overview.html)
- [Install Back Office Assistant](/docs/dg/dev/ai/ai-commerce/backoffice-assistant/install-backoffice-assistant.html)

### AI Foundation Visibility &amp; Governance Enhancements {% include badge.html type=&quot;feature,early-access&quot; %}

Spryker introduces comprehensive visibility into AI activity through new Back Office views for both AI interactions and AI workflow execution. Teams can now inspect prompts, responses, metadata, and workflow states in a single place, improving transparency and control over AI‑driven processes. These enhancements strengthen governance, streamline troubleshooting, and make AI operations easier to understand and monitor.

{% include carousel.html
images=&quot;
https://spryker.s3.eu-central-1.amazonaws.com/docs/About/Releases/release-notes-202604/bo_ai_auditlogs_1.png||::
https://spryker.s3.eu-central-1.amazonaws.com/docs/About/Releases/release-notes-202604/bo_ai_auditlogs_2.png||&quot;
%}

**Key capabilities:**
- Back Office audit logs for reviewing prompts, responses, metadata, and model details
- Workflow execution views with list, detail, state history, and visualized transitions
- Filtering, sorting, and inline inspection tools for efficient debugging and analysis

**Business benefits:**
- Improves governance and traceability across all AI‑powered processes
- Simplifies troubleshooting by making AI interactions and workflow states fully transparent
- Gives operators greater control over AI‑driven actions with clear visibility into execution paths

**Documentation:**
- [AI Foundation Audit Logs](/docs/dg/dev/ai/ai-foundation/ai-foundation-audit-logs.html)
- [AI Foundation Workflows](/docs/dg/dev/ai/ai-foundation/ai-foundation-workflow-state-machine)

### Smart Visual Product Search &amp; Ordering {% include badge.html type=&quot;improvement,early-access&quot; %}

Spryker now enables buyers to identify products and start orders simply by uploading or capturing an image. Whether it&apos;s a technical part, a field-site photo, or a handwritten note, the system can recognize products and quantities and help buyers move directly from identification to ordering. The entire capability now runs on the Spryker AI Foundation, offering provider flexibility, improved reliability, and easier long‑term adoption.

**Key capabilities**
- Helps buyers identify relevant or visually similar products by uploading or capturing an image
- Prefills the quick order form with products and quantities extracted from photos, screenshots, or handwritten notes
- Uses Spryker AI Foundation for multi‑provider support (OpenAI, Azure, Bedrock) and centralized AI governance

**Business benefits**
- Speeds up product identification and ordering, especially for technical and spare‑parts workflows
- Reduces manual entry and ordering errors by interpreting product information directly from images
- Supports mobile and field‑based buying scenarios where buyers capture photos instead of searching by name or SKU

**Documentation**
- [Search by Image](/docs/pbc/all/ai-commerce/latest/search-by-image)
- [Visual Add to Cart](/docs/pbc/all/ai-commerce/latest/visual-add-to-cart)
- [Install Search by Image](/docs/dg/dev/ai/ai-commerce/search-by-image/install-search-by-image)
- [Install Visual Add to Cart](/docs/dg/dev/ai/ai-commerce/visual-add-to-cart/install-visual-add-to-cart)

### AI Dev Tooling for Coding Agents {% include badge.html type=&quot;feature,early-access&quot; %}

Spryker now provides ready-to-use new AI Dev tooling to help development teams work more effectively with coding agents in Spryker projects. The update provides ready-to-use agent instruction files and reusable Spryker-specific skill examples.

**Key capabilities:**
- Generates a project‑ready agent configuration file (AGENTS.md)
- Generates a set of rules for AI agent based on Spryker coding conventions and architectural guidelines
- Provides reusable skill examples covering testing, data import, schema conventions, validation, and frontend development
- Includes a setup command that generates agent configuration file, rules and skills for supported coding agents

**Business benefits:**
- Speeds up onboarding for developers who are new to Spryker by giving AI coding agents the right context from day one
- Improves code quality and consistency through pre‑written, Spryker‑aligned development rules
- Helps teams deliver features faster by reducing back‑and‑forth with AI tools and minimizing incorrect code generation

**Documentation:**
- [AI Dev SDK](/docs/dg/dev/ai/ai-dev/ai-dev-overview)

### API Platform is now Generally Available {% include badge.html type=&quot;feature&quot; %}

Spryker made API Platform generally available as the foundation for modern API development and migration. Existing APIs have been migrated to API Platform internally while keeping external contracts backward-compatible. This enables faster API delivery, easier extensibility, and more standardized API development.

![API Platform](https://spryker.s3.eu-central-1.amazonaws.com/docs/About/Releases/release-notes-202512/api-platform-2.6-api.png)

**Key capabilities:**
- Declarative API development using YAML schemas
- API generation with validation, pagination, serialization, and operation-specific rules
- Interactive and always up-to-date OpenAPI documentation
- Backward-compatible migration of existing APIs to API Platform infrastructure
- Cleaner separation of read and write logic through providers and processors

**Business benefits:**
- Reduces development effort for new and existing APIs
- Improves consistency and maintainability of API implementations
- Accelerates delivery of integrations and future API capabilities

**Documentation:**
- [API Platform](/docs/dg/dev/architecture/api-platform.html)
- [Migration Status of out-of-the-box API Endpoints](/docs/dg/dev/architecture/api-platform/migrate-to-api-platform-status.html)

### Algolia configuration in the Back Office {% include badge.html type=&quot;improvement&quot; %}

Spryker updated the Algolia integration settings in the Back Office to replace the legacy ACP-based configuration experience. The new page uses the Back Office Configuration Framework and provides a more consistent and user-friendly way to manage Algolia credentials. This helps reduce setup effort and simplifies validation during implementation.

**Key capabilities:**
- New configuration section in **Back Office &gt; Configuration &gt; Integrations &gt; Algolia**
- Manage Algolia credentials, including:
  - Application ID
  - Search-only API key
  - Admin API key
- Validate credentials directly via API calls
- Align Algolia setup with the current Spryker-native integration approach

**Business benefits:**
- Simplifies Algolia setup and maintenance in the Back Office
- Reduces implementation time and configuration errors
- Replaces legacy ACP-era fields with a clearer configuration experience

**Documentation:**
- [Integrate Algolia](/docs/pbc/all/search/latest/base-shop/third-party-integrations/algolia/integrate-algolia)

### Mollie PSP Integration {% include badge.html type=&quot;feature&quot; %}

Spryker introduces a new native integration with Mollie, a leading European payment service provider, enabling seamless B2B and B2C payment experiences across key European markets. The integration allows merchants to quickly enable a wide range of local and international payment methods with minimal development effort. It is delivered in collaboration with Spryker Solution Partner KPS.

**Key capabilities:**
- Native integration with Mollie
- Support for a wide range of local European and international payment methods
- Plug-and-play setup with minimal custom development

**Business benefits:**
- Faster time-to-market for European commerce use cases
- Improved conversion through localized payment experiences
- Reduced implementation complexity and maintenance overhead

**Documentation:**
- [Mollie integration](https://github.com/mollie/spryker)

### OAuth SSO readiness for Spryker applications {% include badge.html type=&quot;feature&quot; %}

Spryker introduced a standardized and reusable approach for OAuth 2.0 and OpenID Connect single sign-on across key applications. The release establishes a consistent integration pattern for identity providers such as Keycloak, Azure AD, and Okta for the Back Office, Storefront, and Merchant Portal. This makes identity integrations more predictable and reduces the need for project-specific implementations.

**Key capabilities:**
- Standardized SSO approach for:
  - the Back Office
  - Storefront
  - Merchant Portal
- Support for OAuth Authorization Code flow with PKCE
- Provider-agnostic integration based on configurable OAuth providers
- Persistent identity linking between external providers and Spryker users
- Reference implementation, templates, configuration patterns, and rollout guidance
- Backward compatibility with existing form-based login

**Business benefits:**
- Reduces time and cost for enterprise identity integrations
- Improves implementation predictability across projects
- Creates a reusable foundation for federated authentication across Spryker entry points

**Documentation:**
- [Federated Authentication via OAuth2/OIDC](/docs/pbc/all/oauth/latest/federated-authentication.html)

### Native PunchOut Gateway for cXML and OCI {% include badge.html type=&quot;feature,early-access&quot; %}

Spryker introduced native PunchOut Gateway capabilities for cXML and OCI to reduce bespoke integration work in procurement-driven B2B commerce. The release adds reusable building blocks for common PunchOut flows, including session start, shopping, cart updates, and cart return. This strengthens support for enterprise procurement environments, especially SAP-centric setups.

**Key capabilities:**
- Native compatibility for cXML and OCI PunchOut scenarios
- Support for basic PunchOut requisition and cart flows
- Standard OCI parameter handling
- OCI cart return support with line items
- Reusable message handling and implementation guidance

**Business benefits:**
- Reduces custom development effort for PunchOut implementations
- Speeds up procurement-channel enablement and time-to-revenue
- Improves repeatability and maintainability across B2B integration projects

**Documentation:**
- [PunchOut Gateway](/docs/pbc/all/punchout-gateway/punchout-gateway)

### New Stripe Integration {% include badge.html type=&quot;improvement&quot; %}

Spryker introduced a new Stripe integration that replaces the legacy ACP-based app with a more extensible Spryker-native implementation. The release also adds a dedicated configuration page in the Back Office for managing Stripe settings. This gives customers and partners more control over Stripe-based payment flows and reduces dependency on legacy integration boundaries.

**Key capabilities:**
- New installable Stripe Eco module without ACP runtime dependency
- Support for checkout payment method selection
- Support for payment initialization, authorization, capture, refund, and cancel flows
- New configuration section in **Back Office &gt; Configuration &gt; Integrations &gt; Stripe**
- Validation of Stripe keys and webhook configuration
- Storage of Stripe settings in configuration storage

**Business benefits:**
- Improves flexibility for extending and customizing Stripe payment flows
- Reduces implementation risk and legacy dependency overhead
- Lowers long-term maintenance effort and supports faster payment innovation

**Documentation:**
- [New Stripe Integration](https://github.com/spryker-eco/stripe/releases/tag/1.0.0)

### New Vertex Integration {% include badge.html type=&quot;improvement&quot; %}

Spryker introduced a new Vertex integration to replace the legacy ACP-based approach for tax calculation scenarios. The new integration is designed to provide more flexibility and reduce legacy constraints when adapting tax-related processes. This supports more maintainable and extensible tax integrations over time.

**Key capabilities:**
- New Spryker-native Vertex integration
- Reduced reliance on legacy ACP-based architecture
- Improved extensibility for tax calculation and related scenarios

**Business benefits:**
- Supports more adaptable tax integrations for changing business needs
- Reduces integration friction and project-specific patching
- Lowers total cost of ownership through improved maintainability

**Documentation:**
- [Integrate Vertex](/docs/pbc/all/tax-management/latest/base-shop/third-party-integrations/vertex/install-vertex/integrate-vertex)

### Data import performance and stability enhancements {% include badge.html type=&quot;improvement&quot; %}

We improved the data import experience and robustness for large data volumes. Data imports now provide better execution visibility through a progress bar, and memory usage has been optimized to better support very large imports, including merchant price imports with up to 1 million records.

**Key capabilities:**
- Added a progress bar for data import console commands to show execution progress.
- Reduced memory consumption in data import flows to prevent out-of-memory issues during large imports.
- Improved reliability for high-volume imports across data import entities.

**Business benefits:**
- Helps operators better monitor long-running imports.
- Reduces failures caused by memory exhaustion during large imports.
- Improves operational efficiency for bulk data onboarding.

**Documentation:**
- [Data import (memory usage)](/docs/dg/dev/guidelines/performance-guidelines/keeping-dependencies-updated.html#data-import-memory-usage)
- [Data import Progress bar](/docs/dg/dev/data-import/latest/data-import-optimization-guidelines.html#progress-bar)

### Performance and security improvements {% include badge.html type=&quot;improvement&quot; %}

We made your Spryker Commerce OS faster, more secure, and more stable.

**Key capabilities:**
- Non-buffered log streaming presents the logs immediately.
- Lower latency and response times in storefront with optimized widgets.
- Lower latency and response times in the Back Office and Merchant Portal.
- Higher stability and throughput of Publish &amp; Synchronize workers. The update introduces dynamic waiting behavior, better control over parallel job execution, and compatibility improvements for Symfony Messenger resource-aware workers.

**Documentation:**
- [Non-buffered log streaming](https://api.release.spryker.com/release-group/6411)
- [Yves widget performance best practices](/docs/dg/dev/guidelines/performance-guidelines/yves-performance-best-practice.html)
- [Split Publish &amp; Synchronize queues for performance](/docs/dg/dev/guidelines/performance-guidelines/split-queues-performance.html)
- [Merchant Portal and Back Office performance with ACL rules](/docs/dg/dev/guidelines/performance-guidelines/keeping-dependencies-updated.html#merchant-portal-and-back-office-performance-with-acl-rules)
- [Order details page performance guidance](/docs/pbc/all/order-management-system/latest/base-shop/order-management-feature-overview/order-details-page-performance-overview.html)

## Efficient and Flexible Cloud Foundation

### Spryker Monitoring Integration: logs forwarding {% include badge.html type=&quot;improvement&quot; %}

Spryker expanded cloud observability by enabling log forwarding through [SMI](/docs/ca/dev/monitoring/spryker-monitoring-integration/spryker-monitoring-integration.html) to third-party monitoring platforms of your choice. This allows teams to correlate logs with traces, create alerts based on log data, and use their preferred monitoring tooling beyond AWS CloudWatch.

{% include carousel.html
images=&quot;
https://spryker.s3.eu-central-1.amazonaws.com/docs/About/Releases/release-notes-202604/SMI-dynatrace-logs.png||::
https://spryker.s3.eu-central-1.amazonaws.com/docs/About/Releases/release-notes-202604/SMI-dynatrace-traces.png||&quot;
%}

**Key capabilities:**
- Inspect logs from Spryker Platform in your monitoring tool
- Correlate logs with traces using trace and span identifiers
- Configure log verbosity to control emitted log volume

**Business benefits:**
- Improved troubleshooting through unified logs and traces
- Better alerting capabilities based on application and infrastructure log events

**Documentation:**
- [Spryker Monitoring Integration Logs](/docs/ca/dev/monitoring/spryker-monitoring-integration/opentelemetry-instrumentation#smi-logs-integration)

### Single Sign-On (SSO) for Cloud services {% include badge.html type=&quot;feature&quot; %}

Spryker introduced centralized access management for cloud services, including SSO support for customer identity providers such as Okta and OneLogin. This update reduces manual access handling, improves security, and simplifies onboarding and offboarding for users. It also includes rollout, production-readiness, and IAM cleanup measures to standardize and harden access controls.

&lt;figure class=&quot;video_container&quot;&gt;
    &lt;video width=&quot;100%&quot; height=&quot;auto&quot; controls&gt;
    &lt;source src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/About/Releases/release-notes-202604/2026-Cloud-Hub-SSO-Lofi.mp4&quot; type=&quot;video/mp4&quot;&gt;
  &lt;/video&gt;
&lt;/figure&gt;

**Key capabilities:**
- Connect your own identity provider for SSO access to cloud services
- Centralize user access management for services such as Jenkins, RabbitMQ, and others
- Reduce manual access management effort through self-service-oriented processes

**Business benefits:**
- Faster and more secure user onboarding and offboarding
- Reduced operational effort for access requests and changes
- TLS-encrypted communication to Jenkins and RabbitMQ over internal environment network

**Documentation:**
- [Spryker Cloud SSO Access](/docs/ca/dev/access/sso-access.html)

### Bastion security hardening {% include badge.html type=&quot;improvement&quot; %}

Spryker improved Bastion host security and maintainability by upgrading the operating system, isolating workloads from the host, and enforcing SSO and MFA for human access. This change modernizes the setup while keeping customer impact minimal and preserving SFTP access for integrations.

**Key capabilities:**
- Upgrade Bastion hosts to a current LTS operating system
- Enforce SSO and MFA for human access, deprecate direct SSH access for human users

**Business benefits:**
- Improved security posture for administrative access

### Maintenance and service updates {% include badge.html type=&quot;improvement&quot; %}

Spryker delivered maintenance updates across cloud services and application tooling to keep the platform secure, supported, and maintainable.

**Key capabilities:**
- RabbitMQ 4.2 is now supported in Docker SDK for local development environments.
- Node.js 24 introduces V8 v13.6 and npm 11, which results in noticeably faster `frontend:yves:build` and `frontend:zed:build` runs.

**Business benefits:**
- Reduced security and operational risk from outdated components

**Documentation:**
- [RabbitMQ 4.2 in Docker SDK](/docs/dg/dev/sdks/the-docker-sdk/the-docker-sdk.html)
- [Upgrade Node.js and npm](/docs/dg/dev/upgrade-and-migrate/upgrade-nodejs.html#prerequisites)

</description>
            <pubDate>Mon, 04 May 2026 14:12:48 +0000</pubDate>
            <link>https://docs.spryker.com/docs/about/all/releases/release-notes-202604.0.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/about/all/releases/release-notes-202604.0.html</guid>
            
            
        </item>
        
        <item>
            <title>Enable Dynamic Multistore</title>
            <description>&lt;p&gt;This document describes how to enable &lt;a href=&quot;/docs/pbc/all/dynamic-multistore/latest/base-shop/dynamic-multistore-feature-overview.html&quot;&gt;Dynamic Multistore&lt;/a&gt; (DMS).&lt;/p&gt;
&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;If your project version is below 202307.0, &lt;a href=&quot;/docs/pbc/all/dynamic-multistore/latest/base-shop/install-and-upgrade/install-features/install-dynamic-multistore.html&quot;&gt;Install Dynamic Multistore&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;enable-dynamic-multistore&quot;&gt;Enable Dynamic Multistore&lt;/h3&gt;
&lt;section class=&apos;info-block info-block--warning&apos;&gt;&lt;i class=&apos;info-block__icon icon-warning&apos;&gt;&lt;/i&gt;&lt;div class=&apos;info-block__content&apos;&gt;&lt;div class=&quot;info-block__title&quot;&gt;Staging environment&lt;/div&gt;
To avoid unexpected downtime and data loss, perform and test *all* of the following steps in a staging environment first.
&lt;/div&gt;&lt;/section&gt;
&lt;ol&gt;
&lt;li&gt;Replace &lt;code&gt;StoreClient::getCurrentStore()&lt;/code&gt; and &lt;code&gt;StoreFacade::getCurrentStore()&lt;/code&gt; methods with &lt;code&gt;StoreStorageClient:getStoreNames()&lt;/code&gt;, &lt;code&gt;StoreStorageClient::findStoreByName()&lt;/code&gt;, or &lt;code&gt;StoreFacade::getStoreCollection()&lt;/code&gt; in the following:&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Back Office&lt;/li&gt;
&lt;li&gt;Merchant Portal&lt;/li&gt;
&lt;li&gt;Console Commands&lt;/li&gt;
&lt;li&gt;Gateway&lt;/li&gt;
&lt;li&gt;BackendAPI&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Update custom console commands to meet the following rules:&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Store(Facade|Client)::getCurrentStore()&lt;/code&gt; isn’t used in the code a console command executes.&lt;/li&gt;
&lt;li&gt;All store-aware commands implement &lt;code&gt;Spryker\Zed\Kernel\Communication\Console\StoreAwareConsole&lt;/code&gt; and execute actions for a specific store if a store parameter is provided; if not provided, actions are executed for all the stores in the region.&lt;/li&gt;
&lt;li&gt;Optional: We recommend using the &lt;code&gt;--store&lt;/code&gt; parameter instead of &lt;code&gt;APPLICATION_STORE&lt;/code&gt; env variable; both methods are supported.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;
&lt;p&gt;After enabling DMS, the basic domain structure must change from store to region for all the applications. For example, &lt;code&gt;https://yves.de.mysprykershop.com&lt;/code&gt; will change to &lt;code&gt;https://yves.eu.mysprykershop.com&lt;/code&gt;. To prevent negative SEO effects, set up the needed redirects. If your target domain doesn’t change, for example it doesn’t contain a region name - yves.mysprykershop.com - you may skip this step.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a support case and provide the deploy.yml file that contains the dynamic multistore setup. For example: “We have added the dynamic multistore setup to our deploy.yml and would like it to be activated.”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DMS changes the structure of RabbitMQ messages. When you’re ready for the migration, wait for all the remaining messages in the queue to be processed. When the queue is empty, enable the maintenance mode.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The downtime associated with the maintenance mode is limited to the deployment time, which usually takes up to an hour.&lt;/p&gt;
&lt;ol start=&quot;6&quot;&gt;
&lt;li&gt;Update AWS deployment files to DMS mode using the example:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Original environment variables section:&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;SPRYKER_HOOK_BEFORE_DEPLOY&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;vendor/bin/install&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-r&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;pre-deploy.dynamic-store-off&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-vvv&apos;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;SPRYKER_HOOK_AFTER_DEPLOY&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;true&apos;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;SPRYKER_HOOK_INSTALL&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;vendor/bin/install&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-r&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;production.dynamic-store-off&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;--no-ansi&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-vvv&apos;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;SPRYKER_HOOK_DESTRUCTIVE_INSTALL&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;vendor/bin/install&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-r&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;destructive.dynamic-store-off&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;--no-ansi&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-vvv&apos;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;SPRYKER_YVES_HOST_DE&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;de.&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;SPRYKER_YVES_HOST_AT&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;at.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Updated environment variables section:&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;SPRYKER_HOOK_BEFORE_DEPLOY&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;vendor/bin/install&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-r&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;pre-deploy&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-vvv&apos;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;SPRYKER_HOOK_AFTER_DEPLOY&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;true&apos;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;SPRYKER_HOOK_INSTALL&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;vendor/bin/install&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-r&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;dynamic-store&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;--no-ansi&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-vvv&apos;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;SPRYKER_HOOK_DESTRUCTIVE_INSTALL&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;vendor/bin/install&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-r&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;destructive&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;--no-ansi&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-vvv&apos;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;SPRYKER_DYNAMIC_STORE_MODE&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;SPRYKER_YVES_HOST_EU&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;yves.eu.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Original regions section:&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;regions&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;stores&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;DE&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;broker&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;de_queue&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;key_value_store&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;de_search&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;AT&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;broker&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;at_queue&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;key_value_store&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;at_search&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Updated regions section:&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;regions&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;broker&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;eu-docker&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;key_value_store&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;eu_search&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ol start=&quot;7&quot;&gt;
&lt;li&gt;Run a normal deploy for your server pipeline.&lt;/li&gt;
&lt;/ol&gt;
&lt;section class=&apos;info-block info-block--warning&apos;&gt;&lt;i class=&apos;info-block__icon icon-warning&apos;&gt;&lt;/i&gt;&lt;div class=&apos;info-block__content&apos;&gt;&lt;div class=&quot;info-block__title&quot;&gt;Verification&lt;/div&gt;
- Make sure your store is available at `https://yves.eu.mysprykershop.com` or `https://backoffice.eu.mysprykershop.com`.
- Make sure the store switcher is displayed on the Storefront.
&lt;/div&gt;&lt;/section&gt;
&lt;p&gt;Your shop is now running in DMS mode.&lt;/p&gt;
&lt;h3 id=&quot;check-if-dynamic-multistore-is-enabled&quot;&gt;Check if Dynamic Multistore is enabled&lt;/h3&gt;
&lt;p&gt;DMS is enabled if at least one of the following applies:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Using environment: If the value of &lt;code&gt;SPRYKER_DYNAMIC_STORE_MODE&lt;/code&gt; environment variable is &lt;code&gt;true&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Using interface: In the Back Office &amp;gt; &lt;strong&gt;Administration&lt;/strong&gt; &amp;gt; &lt;strong&gt;Stores&lt;/strong&gt;, an &lt;strong&gt;Edit&lt;/strong&gt; button is displayed next to each store.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;disable-dynamic-multistore&quot;&gt;Disable Dynamic Multistore&lt;/h2&gt;
&lt;section class=&apos;info-block info-block--warning&apos;&gt;&lt;i class=&apos;info-block__icon icon-warning&apos;&gt;&lt;/i&gt;&lt;div class=&apos;info-block__content&apos;&gt;&lt;div class=&quot;info-block__title&quot;&gt;Staging environment&lt;/div&gt;
To avoid unexpected downtime and data loss, perform and test *all* of the following steps in a staging environment first.
&lt;/div&gt;&lt;/section&gt;
&lt;ol&gt;
&lt;li&gt;After disabling DMS, the basic domain structure will change from region to store for all the applications. To prevent negative SEO effects, set up the needed redirects.&lt;/li&gt;
&lt;li&gt;DMS changes the structure of RabbitMQ messages. When you’re ready for the migration, wait for all the remaining messages in the queue to be processed. When the queue is empty, enable the maintenance mode.
(Expected downtime is limited to the deployment time, normally it takes less than 1hr)&lt;/li&gt;
&lt;li&gt;Revert changes in deploy files to disable DMS:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Original environment variables section:&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;SPRYKER_HOOK_BEFORE_DEPLOY&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;vendor/bin/install&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-r&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;pre-deploy&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-vvv&apos;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;SPRYKER_HOOK_AFTER_DEPLOY&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;true&apos;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;SPRYKER_HOOK_INSTALL&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;vendor/bin/install&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-r&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;dynamic-store&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;--no-ansi&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-vvv&apos;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;SPRYKER_HOOK_DESTRUCTIVE_INSTALL&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;vendor/bin/install&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-r&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;destructive&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;--no-ansi&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-vvv&apos;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;SPRYKER_DYNAMIC_STORE_MODE&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;SPRYKER_YVES_HOST_EU&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;yves.eu.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Updated environment variables section:&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;SPRYKER_HOOK_BEFORE_DEPLOY&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;vendor/bin/install&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-r&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;pre-deploy.dynamic-store-off&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-vvv&apos;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;SPRYKER_HOOK_AFTER_DEPLOY&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;true&apos;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;SPRYKER_HOOK_INSTALL&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;vendor/bin/install&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-r&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;production.dynamic-store-off&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;--no-ansi&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-vvv&apos;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;SPRYKER_HOOK_DESTRUCTIVE_INSTALL&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;vendor/bin/install&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-r&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;destructive.dynamic-store-off&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;--no-ansi&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;-vvv&apos;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;SPRYKER_YVES_HOST_DE&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;de.&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;SPRYKER_YVES_HOST_AT&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;at.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Original regions section:&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;regions&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;broker&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;eu-docker&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;key_value_store&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;eu_search&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Updated regions section:&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;regions&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;stores&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;DE&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;broker&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;de_queue&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;key_value_store&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;de_search&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;AT&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;broker&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;at_queue&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;key_value_store&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;at_search&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ol start=&quot;6&quot;&gt;
&lt;li&gt;Run a normal deploy for your server pipeline.&lt;/li&gt;
&lt;/ol&gt;
&lt;section class=&apos;info-block info-block--warning&apos;&gt;&lt;i class=&apos;info-block__icon icon-warning&apos;&gt;&lt;/i&gt;&lt;div class=&apos;info-block__content&apos;&gt;&lt;div class=&quot;info-block__title&quot;&gt;Verification&lt;/div&gt;
- Make sure your store is available at `https://yves.de.mysprykershop.com` or `https://backoffice.de.mysprykershop.com`.
- Make sure the store switcher is *not* displayed on the Storefront.
&lt;/div&gt;&lt;/section&gt;
</description>
            <pubDate>Mon, 04 May 2026 13:36:43 +0000</pubDate>
            <link>https://docs.spryker.com/docs/pbc/all/dynamic-multistore/latest/base-shop/enable-dynamic-multistore.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/pbc/all/dynamic-multistore/latest/base-shop/enable-dynamic-multistore.html</guid>
            
            
        </item>
        
        <item>
            <title>Use AI tools with the AiFoundation module</title>
            <description>&lt;p&gt;This document describes how to create and use AI tools with the AiFoundation module to extend AI capabilities by providing custom functions that AI models can invoke during conversations.&lt;/p&gt;
&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;/h2&gt;
&lt;p&gt;AI tool support enables large language models to call custom functions during conversations. Instead of only generating text, AI models can invoke your application’s functionality, retrieve data, perform calculations, or trigger business logic. This creates more powerful and interactive AI-powered features.&lt;/p&gt;
&lt;p&gt;The AI model decides when to call tools based on the conversation context. The Zed facade executes tools with appropriate arguments, receives the results, and incorporates them into the response. The AiFoundation module handles the complete tool execution flow automatically.&lt;/p&gt;
&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;AiFoundation module installed and configured. For details, see &lt;a href=&quot;/docs/dg/dev/ai/ai-foundation/ai-foundation-module.html&quot;&gt;AiFoundation module Overview&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Configured AI provider that supports tool calling (OpenAI, Anthropic Claude)&lt;/li&gt;
&lt;/ul&gt;
&lt;section class=&apos;info-block info-block--warning&apos;&gt;&lt;i class=&apos;info-block__icon icon-warning&apos;&gt;&lt;/i&gt;&lt;div class=&apos;info-block__content&apos;&gt;&lt;div class=&quot;info-block__title&quot;&gt;Provider compatibility&lt;/div&gt;
&lt;p&gt;Not all AI providers support tool calling. Ensure your configured provider supports this feature. OpenAI and Anthropic Claude have native support for function calling.&lt;/p&gt;
&lt;/div&gt;&lt;/section&gt;
&lt;h2 id=&quot;use-cases&quot;&gt;Use cases&lt;/h2&gt;
&lt;p&gt;AI tools are ideal for scenarios where AI needs to interact with your application:&lt;/p&gt;
&lt;h3 id=&quot;data-retrieval&quot;&gt;Data retrieval&lt;/h3&gt;
&lt;p&gt;Enable AI to fetch data from your system:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Spryker\Zed\AiFoundation\Dependency\Tools\ToolPluginInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Spryker\Zed\AiFoundation\Dependency\Tools\ToolParameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// AI can call this tool to get product information&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GetProductInfoTool&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ToolPluginInterface&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;NAME&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;get_product_info&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getDescription&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Retrieves product information by SKU&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getParameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;array&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ToolParameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;sku&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;string&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;The product SKU to retrieve information for&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;isRequired&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;mixed&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$sku&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;sku&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$product&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getProductClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getProductBySku&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$sku&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;name&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$product&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;price&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$product&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getPrice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;availability&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$product&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getAvailability&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;calculations-and-processing&quot;&gt;Calculations and processing&lt;/h3&gt;
&lt;p&gt;Provide specialized calculations:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Spryker\Zed\AiFoundation\Dependency\Tools\ToolPluginInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Spryker\Zed\AiFoundation\Dependency\Tools\ToolParameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// AI can call this tool to calculate shipping costs&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CalculateShippingTool&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ToolPluginInterface&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;NAME&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;calculate_shipping&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ShippingCalculatorInterface&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$shippingCalculator&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getDescription&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Calculates shipping cost based on weight, destination, and shipping method&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getParameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;array&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ToolParameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;weight&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;number&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Package weight in kilograms&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;isRequired&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ToolParameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;destination&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;string&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Destination country code (e.g., US, DE, FR)&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;isRequired&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ToolParameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;method&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;string&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Shipping method: standard, express, or overnight&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;isRequired&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;mixed&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$weight&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;weight&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$destination&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;destination&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$method&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;method&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;standard&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$cost&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shippingCalculator&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;calculate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$weight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$destination&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$cost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;business-logic-execution&quot;&gt;Business logic execution&lt;/h3&gt;
&lt;p&gt;Allow AI to trigger business operations:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Spryker\Zed\AiFoundation\Dependency\Tools\ToolPluginInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Spryker\Zed\AiFoundation\Dependency\Tools\ToolParameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// AI can call this tool to create support tickets&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CreateSupportTicketTool&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ToolPluginInterface&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;NAME&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;create_support_ticket&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;SupportFacadeInterface&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$supportFacade&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getDescription&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Creates a support ticket with title, description, and priority&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getParameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;array&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ToolParameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;title&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;string&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Brief title summarizing the issue&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;isRequired&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ToolParameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;description&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;string&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Detailed description of the issue or request&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;isRequired&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ToolParameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;priority&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;string&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Priority level: high, medium, or low&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;isRequired&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;mixed&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;title&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;description&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$priority&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;priority&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;medium&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$ticketId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;supportFacade&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;createTicket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$priority&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;Ticket created with ID: %s&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$ticketId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;create-tool-sets&quot;&gt;Create tool sets&lt;/h2&gt;
&lt;p&gt;Tool sets group related tools together. Create a tool set class that implements &lt;code&gt;ToolSetPluginInterface&lt;/code&gt;. Tool sets are Zed-layer plugins registered in the Zed &lt;code&gt;AiFoundationDependencyProvider&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Pyz\Zed\YourModule\Communication\Plugin\AiFoundation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Spryker\Zed\AiFoundation\Dependency\Tools\ToolSetPluginInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomerServiceToolSet&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ToolSetPluginInterface&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;NAME&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;customer_service_tools&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getTools&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;array&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GetOrderStatusTool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CreateRefundTool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UpdateCustomerAddressTool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SendNotificationTool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;organizing-tools-into-sets&quot;&gt;Organizing tools into sets&lt;/h3&gt;
&lt;p&gt;Group tools by functional domain:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Product-related tools&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ProductToolSet&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ToolSetPluginInterface&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;NAME&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;product_tools&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getTools&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;array&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SearchProductsTool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GetProductDetailsTool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CheckStockTool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Order-related tools&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;OrderToolSet&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ToolSetPluginInterface&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;NAME&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;order_tools&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getTools&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;array&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CreateOrderTool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GetOrderHistoryTool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CancelOrderTool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;register-tool-sets&quot;&gt;Register tool sets&lt;/h2&gt;
&lt;p&gt;Register tool sets in your Zed &lt;code&gt;AiFoundationDependencyProvider&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Pyz\Zed\AiFoundation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Pyz\Zed\YourModule\Plugin\AiFoundation\CustomerServiceToolSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Pyz\Zed\YourModule\Plugin\AiFoundation\ProductToolSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Pyz\Zed\YourModule\Plugin\AiFoundation\OrderToolSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Spryker\Zed\AiFoundation\AiFoundationDependencyProvider&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SprykerAiFoundationDependencyProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AiFoundationDependencyProvider&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SprykerAiFoundationDependencyProvider&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;cd&quot;&gt;/**
     * @return array&amp;lt;\Spryker\Zed\AiFoundation\Dependency\Tools\ToolSetPluginInterface&amp;gt;
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getAiToolSetPlugins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;array&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomerServiceToolSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ProductToolSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;OrderToolSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;use-tools-in-ai-requests&quot;&gt;Use tools in AI requests&lt;/h2&gt;
&lt;p&gt;Specify which tool sets to make available to the AI by adding tool set names to your prompt request:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Pyz\Zed\YourModule\Business\Assistant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Generated\Shared\Transfer\PromptMessageTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Generated\Shared\Transfer\PromptRequestTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Pyz\Zed\YourModule\Plugin\AiFoundation\CustomerServiceToolSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Pyz\Zed\YourModule\Plugin\AiFoundation\OrderToolSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Spryker\Zed\AiFoundation\Business\AiFoundationFacadeInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomerAssistant&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;AiFoundationFacadeInterface&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$aiFoundationFacade&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;handleCustomerInquiry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$customerMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$promptRequest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PromptRequestTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setAiConfigurationName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;openai&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setPromptMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PromptMessageTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$customerMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;addToolSetName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;CustomerServiceToolSet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;addToolSetName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;OrderToolSet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setMaxRetries&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$promptResponse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aiFoundationFacade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;prompt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$promptRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$promptResponse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getIsSuccessful&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;I apologize, but I encountered an error processing your request.&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$promptResponse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The AI model has access to all tools from all specified tool sets.&lt;/p&gt;
&lt;h3 id=&quot;example-support-ticket-creation-via-ai&quot;&gt;Example: Support ticket creation via AI&lt;/h3&gt;
&lt;p&gt;Here is a complete example showing how the AI can automatically create support tickets using the CreateSupportTicketTool:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Pyz\Zed\YourModule\Business&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Generated\Shared\Transfer\PromptMessageTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Generated\Shared\Transfer\PromptRequestTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Pyz\Zed\YourModule\Plugin\AiFoundation\CustomerServiceToolSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Spryker\Zed\AiFoundation\Business\AiFoundationFacadeInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SupportTicketAssistant&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;AiFoundationFacadeInterface&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$aiFoundationFacade&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;processCustomerMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$customerMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Request AI to process the message with access to support tools&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$promptRequest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PromptRequestTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setPromptMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PromptMessageTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$customerMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;addToolSetName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;CustomerServiceToolSet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Includes CreateSupportTicketTool&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setMaxRetries&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$promptResponse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aiFoundationFacade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;prompt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$promptRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$promptResponse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getIsSuccessful&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;Failed to process customer message&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Check if the AI invoked the create support ticket tool&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$promptResponse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getToolInvocations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$toolInvocation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$toolInvocation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;create_support_ticket&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;nv&quot;&gt;$ticketId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$toolInvocation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;Support ticket created: %s&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$ticketId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Send the AI response to the customer&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$promptResponse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;In this example, when the customer sends a message like “I need to report a critical bug”, the AI can:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Understand the customer’s intent&lt;/li&gt;
&lt;li&gt;Extract the ticket title, description, and priority&lt;/li&gt;
&lt;li&gt;Invoke the &lt;code&gt;create_support_ticket&lt;/code&gt; tool through the facade&lt;/li&gt;
&lt;li&gt;Receive the ticket ID from the tool result&lt;/li&gt;
&lt;li&gt;Incorporate the ticket information into its response to the customer&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;handle-tool-call-results&quot;&gt;Handle tool call results&lt;/h2&gt;
&lt;p&gt;Tool calls are automatically executed and their results are included in the response:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$promptResponse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aiFoundationFacade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;prompt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$promptRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$promptResponse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getIsSuccessful&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Get the final AI response&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$finalMessage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$promptResponse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Access tool invocation information&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$promptResponse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getToolInvocations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$toolInvocation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$toolName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$toolInvocation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$toolArguments&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$toolInvocation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getArguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$toolResult&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$toolInvocation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// content and reasoning are populated when the provider returns them alongside the tool call&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$content&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$toolInvocation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// e.g. &quot;I will search for that now.&quot;&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$reasoning&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$toolInvocation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getReasoning&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// chain-of-thought, when available&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Log or process tool invocations&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;AI invoked tool &quot;%s&quot; with arguments: %s. Result: %s&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$toolName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$toolArguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$toolResult&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;tool-call-flow&quot;&gt;Tool call flow&lt;/h3&gt;
&lt;p&gt;The complete flow when tools are used:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;AI receives the prompt and available tools&lt;/li&gt;
&lt;li&gt;AI decides to call one or more tools&lt;/li&gt;
&lt;li&gt;AiFoundation automatically executes the tools with provided arguments&lt;/li&gt;
&lt;li&gt;Tool results are sent back to the AI&lt;/li&gt;
&lt;li&gt;AI incorporates results and may call additional tools&lt;/li&gt;
&lt;li&gt;Process continues until AI provides final response&lt;/li&gt;
&lt;li&gt;Final response and all tool invocations are returned in &lt;code&gt;ToolInvocationTransfer&lt;/code&gt; objects&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;best-practices&quot;&gt;Best practices&lt;/h2&gt;
&lt;h3 id=&quot;provide-clear-tool-descriptions&quot;&gt;Provide clear tool descriptions&lt;/h3&gt;
&lt;p&gt;Write descriptions that help the AI understand when and how to use tools:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Good: Clear, specific description&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getDescription&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Searches for products by name, category, or SKU. Returns product name, price, and availability status.&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Avoid: Vague description&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getDescription&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Product search&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;design-focused-tools&quot;&gt;Design focused tools&lt;/h3&gt;
&lt;p&gt;Create tools with single, well-defined purposes:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Good: Focused tool&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GetOrderStatusTool&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ToolPluginInterface&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;NAME&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;get_order_status&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Avoid: Tool that does too much&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ManageOrdersTool&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ToolPluginInterface&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;mixed&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$action&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;action&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// create, update, cancel, status...&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Too many responsibilities&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;return-structured-data&quot;&gt;Return structured data&lt;/h3&gt;
&lt;p&gt;Return JSON-encoded data for complex results:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;mixed&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$order&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getOrderDetails&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;order_id&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;order_id&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$order&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getOrderId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;status&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$order&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getStatus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;total&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$order&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getTotal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;items&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$order&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getItems&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;created_at&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$order&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getCreatedAt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;validate-tool-arguments&quot;&gt;Validate tool arguments&lt;/h3&gt;
&lt;p&gt;Always validate arguments before execution:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;mixed&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$orderId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;order_id&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$orderId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;is_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$orderId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;error&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Invalid order_id parameter&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Proceed with execution&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;handle-errors-gracefully&quot;&gt;Handle errors gracefully&lt;/h3&gt;
&lt;p&gt;Return error information in a consistent format:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;mixed&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;performOperation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;success&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;data&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;json_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;success&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;error&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;error_code&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getCode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;security-considerations&quot;&gt;Security considerations&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Validate permissions. Always check user permissions before executing sensitive operations;&lt;/li&gt;
&lt;li&gt;Sanitize inputs. Sanitize all inputs before using them in queries or operations;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;limitations&quot;&gt;Limitations&lt;/h2&gt;
&lt;h3 id=&quot;provider-specific-constraints&quot;&gt;Provider-specific constraints&lt;/h3&gt;
&lt;p&gt;Different AI providers have varying limitations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Maximum number of tools per request&lt;/li&gt;
&lt;li&gt;Maximum tool description length&lt;/li&gt;
&lt;li&gt;Supported parameter types&lt;/li&gt;
&lt;li&gt;Tool execution timeout limits&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;performance-considerations&quot;&gt;Performance considerations&lt;/h3&gt;
&lt;p&gt;Tool execution adds latency to AI requests:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each tool call requires additional round-trip to the AI provider&lt;/li&gt;
&lt;li&gt;Complex tools may take time to execute&lt;/li&gt;
&lt;li&gt;Multiple sequential tool calls increase total response time&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Consider these factors when designing time-sensitive features.&lt;/p&gt;
&lt;h3 id=&quot;token-usage&quot;&gt;Token usage&lt;/h3&gt;
&lt;p&gt;Tool definitions and results consume tokens from your AI provider quota.
Monitor token consumption when using tools extensively.&lt;/p&gt;
&lt;h2 id=&quot;related-documentation&quot;&gt;Related documentation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/docs/dg/dev/ai/ai-foundation/ai-foundation-module.html&quot;&gt;AiFoundation module Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/docs/dg/dev/ai/ai-foundation/ai-foundation-transfer-response.html&quot;&gt;Use structured responses with the AiFoundation module&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
            <pubDate>Wed, 29 Apr 2026 12:02:58 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/ai/ai-foundation/ai-foundation-tool-support.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/ai/ai-foundation/ai-foundation-tool-support.html</guid>
            
            
        </item>
        
        <item>
            <title>Conversation History</title>
            <description>&lt;p&gt;This document describes how to use conversation history with the AiFoundation module to maintain conversation context across multiple interactions, enabling multi-turn conversations where the AI can reference previous messages and provide contextually relevant responses.&lt;/p&gt;
&lt;p&gt;Conversation history is persisted in the database using the &lt;code&gt;spy_ai_conversation_history&lt;/code&gt; table, ensuring conversations are stored durably and can be retrieved at any time.&lt;/p&gt;
&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;/h2&gt;
&lt;p&gt;Conversation history enables you to maintain persistent conversation context across multiple interactions. Instead of sending isolated prompts, you can build conversational experiences where the AI remembers previous messages and maintains state throughout an extended dialogue.&lt;/p&gt;
&lt;p&gt;The conversation history feature automatically persists all messages in a conversation to the database. When you include a conversation reference in your prompt request, all exchanges are stored in the &lt;code&gt;spy_ai_conversation_history&lt;/code&gt; table and automatically included in subsequent requests to maintain context.&lt;/p&gt;
&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;AiFoundation module installed and configured. For details, see &lt;a href=&quot;/docs/dg/dev/ai/ai-foundation/ai-foundation-module.html&quot;&gt;AiFoundation module Overview&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Database configured and migrated to include the &lt;code&gt;spy_ai_conversation_history&lt;/code&gt; table&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;key-concepts&quot;&gt;Key concepts&lt;/h2&gt;
&lt;h3 id=&quot;conversation-reference&quot;&gt;Conversation Reference&lt;/h3&gt;
&lt;p&gt;A unique identifier for a conversation. All messages in a conversation are stored together under this reference. You can use any string as a conversation reference, such as a customer ID, session ID, or custom identifier.&lt;/p&gt;
&lt;h3 id=&quot;context-window&quot;&gt;Context window&lt;/h3&gt;
&lt;p&gt;The maximum number of tokens that can be stored in a conversation. Default is 50000 tokens. When a conversation exceeds this limit, the oldest messages are automatically pruned to maintain the window size.&lt;/p&gt;
&lt;h2 id=&quot;configure-conversation-history&quot;&gt;Configure conversation history&lt;/h2&gt;
&lt;p&gt;Configure the context window for conversation history in your AI configuration.&lt;/p&gt;
&lt;h3 id=&quot;default-configuration&quot;&gt;Default configuration&lt;/h3&gt;
&lt;p&gt;Update your &lt;code&gt;config/Shared/config_ai.php&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Spryker\Shared\AiFoundation\AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;CONVERSATION_HISTORY_CONTEXT_WINDOW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// tokens&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;per-ai-configuration-settings&quot;&gt;Per-AI-configuration settings&lt;/h3&gt;
&lt;p&gt;Configure the context window for specific AI configurations by adding &lt;code&gt;conversation_history&lt;/code&gt; settings within &lt;code&gt;AI_CONFIGURATIONS&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Spryker\Shared\AiFoundation\AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;AI_CONFIGURATIONS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;customer_support&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;provider_name&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;PROVIDER_OPENAI&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;provider_config&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;api_key&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;getenv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;OPENAI_API_KEY&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;model&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;gpt-4&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;system_prompt&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;You are a helpful customer support assistant.&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&apos;conversation_history&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;context_window&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Larger context for complex support cases&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Per-configuration settings take precedence over global defaults. If &lt;code&gt;conversation_history&lt;/code&gt; is not specified for an AI configuration, it falls back to the global &lt;code&gt;CONVERSATION_HISTORY_CONTEXT_WINDOW&lt;/code&gt; value.&lt;/p&gt;
&lt;section class=&apos;info-block &apos;&gt;&lt;i class=&apos;info-block__icon icon-info&apos;&gt;&lt;/i&gt;&lt;div class=&apos;info-block__content&apos;&gt;&lt;div class=&quot;info-block__title&quot;&gt;Best practice&lt;/div&gt;
&lt;p&gt;Adjust context window based on expected conversation length and token limits of your AI provider. Large context windows provide better conversation history but require more tokens for each AI request.&lt;/p&gt;
&lt;/div&gt;&lt;/section&gt;
&lt;h2 id=&quot;use-conversation-history-in-conversations&quot;&gt;Use conversation history in conversations&lt;/h2&gt;
&lt;h3 id=&quot;basic-multi-turn-conversation&quot;&gt;Basic multi-turn conversation&lt;/h3&gt;
&lt;p&gt;To enable conversation history, include a &lt;code&gt;conversationReference&lt;/code&gt; in your &lt;code&gt;PromptRequestTransfer&lt;/code&gt;. All messages are automatically persisted and included in future requests:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Pyz\Zed\YourModule\Business&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Generated\Shared\Transfer\PromptMessageTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Generated\Shared\Transfer\PromptRequestTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Spryker\Zed\AiFoundation\Business\AiFoundationFacadeInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomerSupportAssistant&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;AiFoundationFacadeInterface&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$aiFoundationFacade&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;respondToCustomer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$conversationReference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$userMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Create a new prompt request with conversation reference&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$promptRequest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PromptRequestTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setConversationReference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$conversationReference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Enable conversation history&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setPromptMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PromptMessageTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$userMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// The AI automatically has access to conversation history&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aiFoundationFacade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;prompt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$promptRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getIsSuccessful&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;An error occurred processing your request.&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;manage-conversation-history&quot;&gt;Manage conversation history&lt;/h3&gt;
&lt;p&gt;Access the complete conversation history at any time:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Pyz\Zed\YourModule\Business&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Generated\Shared\Transfer\ConversationHistoryCriteriaTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Generated\Shared\Transfer\ConversationHistoryConditionsTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Spryker\Zed\AiFoundation\Business\AiFoundationFacadeInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ConversationManager&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;AiFoundationFacadeInterface&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$aiFoundationFacade&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getConversationMessages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$conversationReference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;array&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$conversationHistoryCriteriaTransfer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ConversationHistoryCriteriaTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setConversationHistoryConditions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ConversationHistoryConditionsTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
                    &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setConversationReferences&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$conversationReference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$conversationHistoryCollectionTransfer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aiFoundationFacade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getConversationHistoryCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$conversationHistoryCriteriaTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$conversationHistories&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$conversationHistoryCollectionTransfer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getConversationHistories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$conversationHistories&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$conversationHistoryTransfer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$conversationHistories&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;offsetGet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$messages&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$conversationHistoryTransfer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getMessages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$formattedMessages&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$messages&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$formattedMessages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
                &lt;span class=&quot;s1&quot;&gt;&apos;type&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;getType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// &apos;user&apos;, &apos;assistant&apos;, &apos;tool_call&apos;, &apos;tool_result&apos;&lt;/span&gt;
                &lt;span class=&quot;s1&quot;&gt;&apos;content&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
                &lt;span class=&quot;s1&quot;&gt;&apos;reasoning&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getReasoning&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// null when provider does not return reasoning&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$formattedMessages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getMultipleConversations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$conversationReferences&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;array&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$conversationHistoryCriteriaTransfer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ConversationHistoryCriteriaTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setConversationHistoryConditions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ConversationHistoryConditionsTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
                    &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setConversationReferences&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$conversationReferences&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$conversationHistoryCollectionTransfer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aiFoundationFacade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getConversationHistoryCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$conversationHistoryCriteriaTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$conversationHistories&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$conversationHistoryCollectionTransfer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getConversationHistories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$conversationHistories&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$conversationHistory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$conversationHistory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getConversationReference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
                &lt;span class=&quot;s1&quot;&gt;&apos;conversation_reference&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$conversationHistory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getConversationReference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
                &lt;span class=&quot;s1&quot;&gt;&apos;message_count&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$conversationHistory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getMessages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
                &lt;span class=&quot;s1&quot;&gt;&apos;messages&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;array_map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
                        &lt;span class=&quot;s1&quot;&gt;&apos;type&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;getType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
                        &lt;span class=&quot;s1&quot;&gt;&apos;content&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$conversationHistory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getMessages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getArrayCopy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()),&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;api-reference&quot;&gt;API reference&lt;/h2&gt;
&lt;h3 id=&quot;aifoundationfacade&quot;&gt;AiFoundationFacade&lt;/h3&gt;
&lt;h4 id=&quot;prompt&quot;&gt;prompt()&lt;/h4&gt;
&lt;p&gt;Sends a message in a conversation. If &lt;code&gt;conversationReference&lt;/code&gt; is provided, the message is stored in conversation history and previous messages are automatically included in the AI’s context.&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cd&quot;&gt;/**
 * @param \Generated\Shared\Transfer\PromptRequestTransfer $promptRequest
 * @return \Generated\Shared\Transfer\PromptResponseTransfer
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prompt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;PromptRequestTransfer&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$promptRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;PromptResponseTransfer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;PromptRequestTransfer properties for conversation history:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;conversationReference&lt;/code&gt; (string, optional): Enable conversation history by providing a unique conversation identifier&lt;/li&gt;
&lt;li&gt;&lt;code&gt;aiConfigurationName&lt;/code&gt; (string, optional): Configuration name to use, defaults to &lt;code&gt;AI_CONFIGURATION_DEFAULT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;promptMessage&lt;/code&gt; (PromptMessageTransfer, required): The message to send&lt;/li&gt;
&lt;li&gt;&lt;code&gt;maxRetries&lt;/code&gt; (int, optional): Number of retry attempts on failure&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;getconversationhistorycollection&quot;&gt;getConversationHistoryCollection()&lt;/h4&gt;
&lt;p&gt;Retrieves conversation history collection based on criteria. Allows filtering conversations by conversation IDs.&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cd&quot;&gt;/**
 * @param \Generated\Shared\Transfer\ConversationHistoryCriteriaTransfer $conversationHistoryCriteriaTransfer
 * @return \Generated\Shared\Transfer\ConversationHistoryCollectionTransfer
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getConversationHistoryCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;ConversationHistoryCriteriaTransfer&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$conversationHistoryCriteriaTransfer&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;ConversationHistoryCollectionTransfer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;ConversationHistoryCriteriaTransfer properties:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;conversationHistoryConditions&lt;/code&gt; (ConversationHistoryConditionsTransfer): Filter conditions for the query
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;conversationReferences&lt;/code&gt; (string[]): List of conversation references to retrieve (IN operation). If empty, returns empty collection.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Returns:&lt;/strong&gt; ConversationHistoryCollectionTransfer containing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;conversationHistories&lt;/code&gt; (ConversationHistoryTransfer[]): Array of conversation histories matching the criteria
&lt;ul&gt;
&lt;li&gt;Each ConversationHistoryTransfer contains:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;conversationReference&lt;/code&gt; (string): The conversation reference&lt;/li&gt;
&lt;li&gt;&lt;code&gt;messages&lt;/code&gt; (PromptMessageTransfer[]): Array of all messages in the conversation with types (user, assistant, tool_call, tool_result), content, reasoning, and attachments&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;message-types&quot;&gt;Message types&lt;/h2&gt;
&lt;p&gt;Messages stored in conversation history have different types:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;user&lt;/code&gt; - Message sent by the user&lt;/li&gt;
&lt;li&gt;&lt;code&gt;assistant&lt;/code&gt; - Response from the AI&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tool_call&lt;/code&gt; - A tool invocation initiated by the AI&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tool_result&lt;/code&gt; - Result of a tool execution&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tool-related types are only present when using &lt;a href=&quot;/docs/dg/dev/ai/ai-foundation/ai-foundation-tool-support.html&quot;&gt;AI tools&lt;/a&gt; with conversation history.&lt;/p&gt;
&lt;h2 id=&quot;best-practices&quot;&gt;Best practices&lt;/h2&gt;
&lt;h3 id=&quot;use-meaningful-conversation-references&quot;&gt;1. Use meaningful conversation references&lt;/h3&gt;
&lt;p&gt;Choose conversation references that align with your business logic:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Good: Clear relationship to entity&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$conversationReference&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;customer_conversation_&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$customerId&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$timestamp&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$conversationReference&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;support_ticket_&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ticketId&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Avoid: Generic IDs that are hard to track&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$conversationReference&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;conv_123&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;manage-conversation-cleanup&quot;&gt;2. Manage conversation cleanup&lt;/h3&gt;
&lt;p&gt;Implement your own cleanup strategy for old conversations if needed. Unlike Redis-backed storage with automatic expiration, database-persisted conversations remain indefinitely. Consider creating a scheduled task to delete conversations older than a certain date if storage management is important.&lt;/p&gt;
&lt;h3 id=&quot;handle-large-conversations&quot;&gt;3. Handle large conversations&lt;/h3&gt;
&lt;p&gt;Monitor context window usage. If approaching limits, start a new conversation.&lt;/p&gt;
&lt;h3 id=&quot;secure-conversation-access&quot;&gt;4. Secure conversation access&lt;/h3&gt;
&lt;p&gt;Validate that users can only access their own conversations by filtering conversation references based on user permissions:&lt;/p&gt;
&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$conversationHistoryCriteriaTransfer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ConversationHistoryCriteriaTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setConversationHistoryConditions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ConversationHistoryConditionsTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setConversationReferences&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$userAuthorizedConversationReferences&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Only user&apos;s conversations&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$conversationHistoryCollectionTransfer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aiFoundationFacade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getConversationHistoryCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$conversationHistoryCriteriaTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;limitations&quot;&gt;Limitations&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Conversation history is stored in the database and requires the &lt;code&gt;spy_ai_conversation_history&lt;/code&gt; table to be present&lt;/li&gt;
&lt;li&gt;Conversations persist indefinitely in the database; implement your own cleanup strategy if needed&lt;/li&gt;
&lt;li&gt;Very large conversations may approach the context window limit, requiring new conversation references&lt;/li&gt;
&lt;li&gt;Tool invocations and results are included in history and count toward context window&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;debugging&quot;&gt;Debugging&lt;/h2&gt;
&lt;p&gt;Conversation history messages are persisted in the &lt;code&gt;spy_ai_conversation_history&lt;/code&gt; database table. You can query the database directly to inspect stored conversations and messages for debugging purposes.&lt;/p&gt;
</description>
            <pubDate>Wed, 29 Apr 2026 12:02:58 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/ai/ai-foundation/ai-foundation-conversation-history.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/ai/ai-foundation/ai-foundation-conversation-history.html</guid>
            
            
        </item>
        
        <item>
            <title>Packaged Business Capabilities</title>
            <description>Packaged Business Capabilities (PBCs) are capabilities that enclose a certain functionality with the Spryker system. PBCs provide a good foundation for decision makers throughout multiple business entities.

This section is in beta because not all the PBCs are covered. Marketplace functionalities will also be added at a later stage. You are welcome to use the docs that are already here, and we will keep adding the docs for the rest of the PBCs.

## Spryker PBCs

| NAME | DESCRIPTION | BENEFITS |
| --- | --- | --- |
| [AI Foundation](/docs/pbc/all/ai-foundation/{{site.version}}/ai-foundation.html) | Provider agnostic AI layer that connects Spryker Commerce OS to leading AI providers through one common interface. | Accelerates delivery of AI features and keeps freedom to choose and change AI providers and models per use case. |
| [AI Commerce](/docs/pbc/all/ai-commerce/{{site.version}}/ai-commerce.html) | Brings AI assisted capabilities to the Spryker storefront and Backoffice to help buyers and operators complete commerce tasks faster and more consistently, reducing manual effort with human review and enterprise governance. | Speeds up key commerce workflows while improving consistency and reducing errors, enabling scalable adoption of assisted capabilities across teams and markets. |
| [Business Intelligence](/docs/pbc/all/business-intelligence/{{site.version}}/business-intelligence.html) | Analyze data to understand how your shop performs and areas for improvement. | Make informed decisions. |
| [Carrier Management](/docs/pbc/all/carrier-management/{{site.version}}/carrier-management.html) | The Spryker Cloud Commerce OS integrates with several shipping carriers and methods and lets you define their availability, price, and tax set. During the checkout process, customers have the option to select their preferred shipment method and relevant carrier. | Ensures quick and cost-effective delivery. |
| [Cart and Checkout](/docs/pbc/all/cart-and-checkout/{{site.version}}/cart-and-checkout.html) | The online shopping cart and checkout process act as a gateway for customer and order management. It lets your customers organize and manage their purchases, apply vouchers and coupon codes. Based on their roles and permissions, your B2B customers can add or remove products, share the cart, and manage their purchases. | Increases conversion rates and reduces drop-off rates. Offers additional B2B specific, permission-related functionalities. |
| [Content Management System (CMS)](/docs/pbc/all/content-management-system/{{site.version}}/content-management-system.html) | The CMS features let you customize your store, enrich it with information, stories, or other content, and make it easily findable in search engines. Several SEO features enable you to add customized meta information to all your content and create search engine-friendly URLs. | Provides compelling content and stories where your customers need it. |
| [Customer Relationship Management (CRM)](/docs/pbc/all/customer-relationship-management/{{site.version}}/customer-relationship-management.html) | The customer management tool lets B2B and B2C businesses manage customer accounts and efficiently monitor shopping habits. It provides your B2B Customers with a way to map their business hierarchies, permissions, and role management. With the creation of distinctive Business Units, the internal hierarchy can easily be mapped out, and each Unit can operate independently. The Roles and Permissions System lets your customer&apos;s buyers define the purchase and approval process. | Increases conversion rates and average order values with a compact Customer Relationship Management tool. |
| [Data Exchange](/docs/pbc/all/data-exchange/{{site.version}}/data-exchange.html) | You can import your business logic and data, including product information, customer base, categories, and more, into the Spryker Cloud Commerce OS. You can use the out-of-the-box export data functionality as a generic blueprint for any data set that you need to export. | Lets you import and export specific data points quickly and easily. |
| [Discount Management](/docs/pbc/all/discount-management/{{site.version}}/discount-management.html) | You can define several types of discounts based on a brand, the overall cart value, specific product ranges, or unique customer groups. You can also offer discount vouchers or incentivize certain products through coupon codes. | Lets you run effective promotional campaigns to boost conversion rates. |
| [Dynamic Multistore](/docs/pbc/all/dynamic-multistore/{{site.version}}/dynamic-multistore.html) | Manage stores in the Back Office | Make changes to your stores setup quickly and easily. |
| [Emails](/docs/pbc/all/emails/{{site.version}}/emails.html) | You can send automated account e-mails and confirmations or offer different types of newsletter subscriptions. | Keep in touch with your customers. |
| [Gift Cards](/docs/pbc/all/gift-cards/{{site.version}}/gift-cards.html) | Lets your customers purchase and redeem gift cards. Enabling gift card purchases can boost your brand awareness and help you reach new customers. | Lets you acquire new customers through gift card payment options. |
| [Identity Access Management (IAM)](/docs/pbc/all/identity-access-management/{{site.version}}/identity-access-management.html) | Enables the creation of new accounts for end customers and B2B customers. It also allows users to define password settings and utilize multi-login blockers for security purposes. Moreover, a third-party access management function is integrated. | Allows for quick and easy authorization and authentication of customers |
| [Merchant Management](/docs/pbc/all/merchant-management/{{site.version}}/merchant-management.html) | For efficient Merchant Management, two parts are important. One, the overview and management on the Operator side, like approvals, edits, etc. And two, the self-service management of the Merchants, where they can take care of their daily business, like order or product management. | Gives you an overview of all your Merchants&apos; activities. |
| Miscellaneous | This category holds the documents that are not related to any PBC.  |  |
| [Offer Management](/docs/pbc/all/offer-management/{{site.version}}/offer-management.html) | Lets your Merchants create Offers on existing products in your Marketplace. By doing so, duplicates in the product catalog can be avoided and the management of Merchants, Products, and Offers becomes much more convenient. | Saves time because of a good overview of Merchant&apos;s Offers. |
| [Order Management System (OMS)](/docs/pbc/all/order-management-system/{{site.version}}/order-management-system.html) | Helps you keep track of your order processing from your B2B, B2C, or Marketplace, and ensure quick fulfillment. You can manage incoming orders in the Back Office, view and edit orders, track their progress, or contact customers who make open orders directly. With the compact Order Management features, you can keep your order processing running smoothly. | Lets you pProcess orders smoothly to fulfill them quickly. |
| [Payment Service Provider (PSP)](/docs/pbc/all/payment-service-provider/{{site.version}}/payment-service-provider.html) | Provides integration of payment methods. You can integrate multiple payment gateways, define their availability, and customize how they appear on your site. | Lets you provide an excellent shopping experience and integrate your customers&apos; preferred payment methods. |
| [Price Management](/docs/pbc/all/price-management/{{site.version}}/price-management.html) | The Spryker Cloud Commerce OS supports multiple currencies and automatically detects the payment currency based on a customer&apos;s preference. You can manage gross and net prices per product and per country. You can also offer volume discounts to encourage customers to purchase products in larger quantities. | Saves you time by letting you implement your pricing strategy in one place and catering it to your business needs. |
| [Product Information Management (PIM)](/docs/pbc/all/product-information-management/{{site.version}}/product-information-management.html) | Encompasses all functionality that is needed to set up your product catalog. With PIM, you can create and extend the product catalog to match your business needs. | Helps you expand your business by organizing your products in a fast and efficient way. |
| [Product Relationship Management](/docs/pbc/all/product-relationship-management/{{site.version}}/product-relationship-management.html) | Helps you enhance your shop with cross- and up-selling capabilities to increase sales. | Increases average order values with product relations. |
| [Ratings and Reviews](/docs/pbc/all/ratings-reviews/{{site.version}}/ratings-and-reviews.html) | Lets you incorporate user reviews and ratings. You can receive and moderate feedback in the Back Office. The Ratings and Reviews feature also comes with the functionality to add text-free reviews and star ratings. | Inspires trust among customers with ratings and reviews. |
| [Request for Quote (RFQ)](/docs/pbc/all/request-for-quote/{{site.version}}/request-for-quote.html) | Your customers can request a quote for products and services that you sell. The Request for Quote feature supports all functionalities of the price engine and product capabilities, such as Volume Prices, Customer Specific Prices, Measuring and Packaging units, Shipping costs, Product Options, etc. | Enhances customer loyalty and increase conversion rates. |
| [Return Management](/docs/pbc/all/return-management/{{site.version}}/marketplace/marketplace-return-management-feature-overview.html) | Lets you establish a return policy and execute returns. | Increase customer satisfaction and loyalty. |
| [Search](/docs/pbc/all/search/{{site.version}}/base-shop/search-feature-overview/search-feature-overview.html) | The out-of-the-box Elasticsearch technology lets you include full-text search, auto-suggestions, and auto-completion. You can set individual search preferences for multiple stores and categorize your products by adding dynamic filters and facets to help your customers further refine the search results. You can also add more advanced filters that use the product&apos;s metadata or promote a brand&apos;s top-sellers or highly rated products. | Helps you increase conversion rates by providing an excellent Search and Filter experience. |
| [Service Points Management](/docs/pbc/all/service-point-management/{{site.version}}/service-point-management.html) | Set up offline service points where customers can interact with your business. | Creates touch points to connect a shop with offline locations. |
| [Shopping List and Wishlist](/docs/pbc/all/shopping-list-and-wishlist/{{site.version}}/shopping-list-and-wishlist.html) | Your B2B customers can save the products they wish to purchase, in shopping lists. Different roles and permission systems ensure smooth sharing and contribution management amongst company users. This PBC encompasses additional features like printing, barcode generation, and direct-to-cart. Enabling your B2C customers to track and save the products they wish to purchase through a wish list function effectively reduces cart abandonment, boosts your sales, and allows you to keep track of which products are of interest to your customers. | Lets you increase conversion rates and loyalty by offering rich Shopping and B2B Wish Lists. |
| [Tax Management](/docs/pbc/all/tax-management/{{site.version}}/tax-management.html) | Lets you adhere to respective tax regulations in the countries you sell by configuring and managing tax rates for products, shipments, and additional services. You can define tax rates for different countries and apply integrations to manage US taxes. | Lets you comply with fiscal regulations. |
| [User Management](/docs/pbc/all/user-management/{{site.version}}/user-management.html) | Lets the Back Office users manage user access, set rights, and onboard customers. | Ensures high security and compliance through managed user flows. |
| [Warehouse Management System (WMS)](/docs/pbc/all/warehouse-management-system/{{site.version}}/warehouse-management-system.html) | Lets you keep an overview of your stock levels in the Back Office to determine accurate availabilities on your store&apos;s website. Any open orders or reserved items are taken into consideration when stock availabilities are displayed. | Helps you save your time by keeping an eye on your stock levels. |

&lt;!--
| Digital Asset Management (DAM) | The DAM system provides impactful visuals while simultaneously maintaining fast response times, thus helping you reduce your bounce rate effectively and create an enhanced shopping experience. With the DAM, you can add images and videos to any of your pages. | Offers an exceptional brand experience with impactful visuals, banners, and media assets. |
--&gt;


### Application PBCs

| NAME | DESCRIPTION | BENEFITS |
| --- | --- | --- |
| Back Office | The administration interface that allows you to manage all back-office tasks. In the Back Office, you can manage and create customer accounts and define who can access the Back Office. You can also keep track of all your internal processes including the management of your products, orders, customers and many more. | Keeps your back-end processes running efficiently, protects your data and administers all accounts. |
| Storefront | The out-of-the-box online shop application that includes all regular functionalities and workflows. You can use the Storefront as a boilerplate to kick-start your project. | Lets you easily start your online shop from our boilerplate solution. |

## App Composition Platform apps

&lt;div class=&quot;width-100&quot;&gt;

| APP | CATEGORY |
| --- | --- |
| [Vertex](/docs/pbc/all/tax-management/{{site.version}}/base-shop/third-party-integrations/vertex/vertex.html) | Tax compliance. |
| [Algolia](/docs/pbc/all/search/{{site.version}}/base-shop/third-party-integrations/algolia/integrate-algolia.html) | Search engine. |
| [Payone](/docs/pbc/all/payment-service-providers/payone/integrate-payone.html) | Payment service provider. |
| [Bazaarvoice](/docs/pbc/all/ratings-reviews/{{site.version}}/third-party-integrations/integrate-bazaarvoice.html) | Platform for user-generated content. |
| [Stripe](/docs/pbc/all/payment-service-provider/{{site.version}}/base-shop/third-party-integrations/stripe/stripe.html) |  Financial infrastructure platform. |

&lt;/div&gt;
</description>
            <pubDate>Wed, 29 Apr 2026 10:34:52 +0000</pubDate>
            <link>https://docs.spryker.com/docs/pbc/all/pbc.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/pbc/all/pbc.html</guid>
            
            
        </item>
        
        <item>
            <title>AI Commerce</title>
            <description>&lt;p&gt;AI Commerce brings AI-powered capabilities to your Spryker storefront and back office, reducing manual effort for buyers and shop operators, accelerating commerce workflows. Features are built on the &lt;code&gt;AiFoundation&lt;/code&gt; abstraction layer, so the underlying AI model can be swapped or configured per feature without changing application code.&lt;/p&gt;
&lt;h2 id=&quot;features&quot;&gt;Features&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;FEATURE&lt;/th&gt;
&lt;th&gt;DESCRIPTION&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;/docs/pbc/all/ai-commerce/latest/smart-pim.html&quot;&gt;Smart PIM&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Help catalog managers enrich product information directly in the Backoffice PIM. Get guided suggestions to speed up day-to-day catalog work, improve consistency across markets and languages, and keep full control through human review and auditability.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;/docs/pbc/all/ai-commerce/latest/visual-add-to-cart.html&quot;&gt;Visual Add to Cart&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Lets buyers upload a product image on the Quick Order page. AI recognizes the products in the image and pre-fills the order form with matching SKUs and quantities — enabling rapid bulk ordering without manual entry.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;/docs/pbc/all/ai-commerce/latest/backoffice-assistant.html&quot;&gt;Back Office Assistant&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;An AI-powered chat widget embedded in the Back Office. Admin users can ask natural language questions to navigate the Back Office, diagnose order issues, and create or update discounts.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;/docs/pbc/all/ai-commerce/latest/search-by-image.html&quot;&gt;Search by Image&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Lets customers upload a photo to search for products. AI analyzes the image, identifies a search term, and redirects to search results or the first matching product page.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;who-benefits&quot;&gt;Who benefits&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ROLE&lt;/th&gt;
&lt;th&gt;BENEFIT&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;B2B buyers&lt;/td&gt;
&lt;td&gt;Faster reordering from photos of shelves, product lists, or packaging. Find products by uploading a photo instead of searching by name.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Store operators&lt;/td&gt;
&lt;td&gt;Reduced support requests caused by manual order entry errors. Faster Back Office workflows through conversational AI assistance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Developers&lt;/td&gt;
&lt;td&gt;AI provider-agnostic integration — swap or configure models per feature via configuration.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</description>
            <pubDate>Wed, 29 Apr 2026 10:34:52 +0000</pubDate>
            <link>https://docs.spryker.com/docs/pbc/all/ai-commerce/latest/ai-commerce.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/pbc/all/ai-commerce/latest/ai-commerce.html</guid>
            
            
        </item>
        
    </channel>
</rss>
