<?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>Fri, 24 Apr 2026 12:52:36 +0000</lastBuildDate>
        <generator>Jekyll v4.2.2</generator>
        
        
        <item>
            <title>Migrate OauthApi to API Platform</title>
            <description>This document describes how to migrate the `OauthApi` Glue module to API Platform. The `OauthApi` module now ships an API Platform `/token` resource in-place — the Processor class and resource schema live inside the `OauthApi` module itself and delegate to the `Authentication` client.

## Prerequisites

Complete the cross-cutting changes described in [Migrate Glue REST API to API Platform](/docs/dg/dev/upgrade-and-migrate/migrate-to-api-platform/migrate-glue-api-to-api-platform.html) before proceeding.

## Overview

The `OauthApi` module provided the `/token` endpoint for the `GlueStorefrontApiApplication`. It registered the resource through the `OauthApiTokenResource` plugin, which routed requests to a legacy controller. This endpoint is now served by API Platform:

| Endpoint | Operation | Legacy plugin |
|---|---|---|
| `POST /token` | OAuth2 token endpoint supporting `password` and `refresh_token` grant types | `OauthApiTokenResource` |

The API Platform `Tokens` resource delegates to `Spryker\Client\Authentication\AuthenticationClient::authenticate()`, which returns an `OauthResponseTransfer` used to populate the response.

{% info_block infoBox &quot;Application scope&quot; %}

This `/token` endpoint is registered only in the `GlueStorefrontApiApplication`. In the legacy Glue application, `/token` is served by the `AuthRestApi` module — see [Migrate AuthRestApi to API Platform](/docs/dg/dev/upgrade-and-migrate/migrate-to-api-platform/migrate-authrestapi.html).

{% endinfo_block %}

## 1. Update module dependencies

```bash
composer require spryker/oauth-api:&quot;^X.Y.Z&quot;
```

{% info_block infoBox &quot;Version&quot; %}

Use the version that ships the API Platform resources. Check the module changelog for the exact version.

{% endinfo_block %}

## 2. Remove OauthApiTokenResource from GlueStorefrontApiApplicationDependencyProvider

In `src/Pyz/Glue/GlueStorefrontApiApplication/GlueStorefrontApiApplicationDependencyProvider.php`, remove the following plugin from `getResourcePlugins()`:

| Plugin to remove | Fully qualified class name |
|---|---|
| `OauthApiTokenResource` | `Spryker\Glue\OauthApi\Plugin\GlueApplication\OauthApiTokenResource` |

Also remove the matching `use` import at the top of the file.

Keep the other `OauthApi` plugins registered in the same file — they continue to wire authentication into the storefront API application:

- `Spryker\Glue\OauthApi\Plugin\AccessTokenValidatorPlugin`
- `Spryker\Glue\OauthApi\Plugin\CustomerRequestBuilderPlugin`
- `Spryker\Glue\OauthApi\Plugin\GlueApplication\CustomerRequestValidatorPlugin`

## 3. Exclude OauthApi from the legacy Glue application

The legacy Glue application serves `/token` through the `AuthRestApi` module. To prevent the `OauthApi` schema from registering a duplicate `/token` route there, exclude it from the legacy Glue application&apos;s generator.

In `config/Glue/packages/spryker_api_platform.php`, add `OauthApi` to the `excludedPathFragments` list:

```php
$sprykerApiPlatform-&gt;excludedPathFragments([
    &apos;src/Spryker/OauthApi/resources/api/&apos;,
    // ...other entries
]);
```

The `GlueStorefrontApiApplication` continues to discover `OauthApi` schemas via `config/GlueStorefront/packages/spryker_api_platform.php` — do not exclude `OauthApi` there.

## 4. Regenerate transfers and API resources

```bash
docker/sdk cli console transfer:generate
docker/sdk cli glue api:generate
docker/sdk cli glue cache:clear
```

## Relationship plugin status

The `OauthApi` module did not register any relationship plugins. No relationship changes are needed.
</description>
            <pubDate>Fri, 24 Apr 2026 12:48:49 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/upgrade-and-migrate/migrate-to-api-platform/migrate-oauthapi.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/upgrade-and-migrate/migrate-to-api-platform/migrate-oauthapi.html</guid>
            
            
        </item>
        
        <item>
            <title>Migrate AuthRestApi to API Platform</title>
            <description>This document describes how to migrate the `AuthRestApi` Glue module to API Platform. The `AuthRestApi` module now ships API Platform resources in-place — the Provider/Processor classes and resource schemas live inside the `AuthRestApi` module itself, reusing the existing `AuthRestApiClient` for OAuth2 token issuance.

## Prerequisites

Complete the cross-cutting changes described in [Migrate Glue REST API to API Platform](/docs/dg/dev/upgrade-and-migrate/migrate-to-api-platform/migrate-glue-api-to-api-platform.html) before proceeding.

## Overview

The `AuthRestApi` module provided the following storefront endpoints on the legacy Glue stack. They are now served by API Platform:

| Endpoint | Operation | Legacy plugin |
|---|---|---|
| `POST /access-tokens` | Create an access token via the password grant | `AccessTokensResourceRoutePlugin` |
| `POST /refresh-tokens` | Exchange a refresh token for a new access token | `RefreshTokensResourceRoutePlugin` |
| `DELETE /refresh-tokens/{refreshToken}` | Revoke a single refresh token or all tokens for the current user | `RefreshTokensResourceRoutePlugin` |
| `POST /token` | OAuth2 token endpoint supporting `password` and `refresh_token` grant types | `TokenResourceRoutePlugin` |

The `/token` endpoint is served by `AuthRestApi` only in the legacy Glue application. In the `GlueStorefrontApiApplication`, `/token` is served by the `OauthApi` module — see [Migrate OauthApi to API Platform](/docs/dg/dev/upgrade-and-migrate/migrate-to-api-platform/migrate-oauthapi.html).

## 1. Update module dependencies

```bash
composer require spryker/auth-rest-api:&quot;^X.Y.Z&quot;
```

{% info_block infoBox &quot;Version&quot; %}

Use the version that ships the API Platform resources. Check the module changelog for the exact version.

{% endinfo_block %}

## 2. Remove route plugins from GlueApplicationDependencyProvider

In `src/Pyz/Glue/GlueApplication/GlueApplicationDependencyProvider.php`, remove the following plugins from `getResourceRoutePlugins()`:

| Plugin to remove | Fully qualified class name |
|---|---|
| `AccessTokensResourceRoutePlugin` | `Spryker\Glue\AuthRestApi\Plugin\AccessTokensResourceRoutePlugin` |
| `RefreshTokensResourceRoutePlugin` | `Spryker\Glue\AuthRestApi\Plugin\RefreshTokensResourceRoutePlugin` |
| `TokenResourceRoutePlugin` | `Spryker\Glue\AuthRestApi\Plugin\GlueApplication\TokenResourceRoutePlugin` |

Also remove the matching `use` imports at the top of the file.

Keep the other `AuthRestApi` plugins registered in the same file — these continue to serve authentication for unmigrated endpoints:

- `Spryker\Glue\AuthRestApi\Plugin\FormatAuthenticationErrorResponseHeadersPlugin`
- `Spryker\Glue\AuthRestApi\Plugin\GlueApplication\AccessTokenRestRequestValidatorPlugin`
- `Spryker\Glue\AuthRestApi\Plugin\GlueApplication\FormattedControllerBeforeActionValidateAccessTokenPlugin`
- `Spryker\Glue\AuthRestApi\Plugin\GlueApplication\SimultaneousAuthenticationRestRequestValidatorPlugin`
- `Spryker\Glue\AuthRestApi\Plugin\RestUserFinderByAccessTokenPlugin`

## 3. Exclude AuthRestApi from the storefront API application

In the `GlueStorefrontApiApplication` (new storefront app), the `/token` endpoint is served by `OauthApi`. To prevent duplicate route definitions, exclude `AuthRestApi` resource schemas from that application&apos;s generator.

In `config/GlueStorefront/packages/spryker_api_platform.php`, add `AuthRestApi` to the `excludedPathFragments` list:

```php
$sprykerApiPlatform-&gt;excludedPathFragments([
    &apos;src/Spryker/AuthRestApi/resources/api/&apos;,
    // ...other entries
]);
```

The legacy Glue application continues to discover `AuthRestApi` schemas via `config/Glue/packages/spryker_api_platform.php` — do not exclude `AuthRestApi` there.

## 4. Regenerate transfers and API resources

```bash
docker/sdk cli console transfer:generate
docker/sdk cli glue api:generate
docker/sdk cli glue cache:clear
```

## Relationship plugin status

The `AuthRestApi` module did not register any relationship plugins. No relationship changes are needed.
</description>
            <pubDate>Fri, 24 Apr 2026 12:48:49 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/upgrade-and-migrate/migrate-to-api-platform/migrate-authrestapi.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/upgrade-and-migrate/migrate-to-api-platform/migrate-authrestapi.html</guid>
            
            
        </item>
        
        <item>
            <title>AI Dev SDK Overview</title>
            <description>&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;Experimental module&lt;/div&gt;
&lt;p&gt;The AiDev module is experimental and not stable. There is no backward compatibility promise for this module. We welcome your feedback and contributions as we continue to develop and improve this module.&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;Prerequisites&lt;/div&gt;
&lt;p&gt;This module requires &lt;code&gt;^1.71.0&lt;/code&gt; version of &lt;code&gt;docker/sdk&lt;/code&gt; for proper usage.
Make sure your development environment is up to date before installing the AiDev module.&lt;/p&gt;
&lt;/div&gt;&lt;/section&gt;
&lt;p&gt;This document describes how to integrate and use the AiDev module to connect your Spryker application to AI development tools through the Model Context Protocol (MCP).&lt;/p&gt;
&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;/h2&gt;
&lt;p&gt;The AiDev module provides an MCP server that enables AI assistants to interact with your Spryker application.
It exposes Spryker-specific information through MCP tools and prompts, allowing AI assistants to better understand and work with your codebase.&lt;/p&gt;
&lt;p&gt;The module includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MCP Server&lt;/strong&gt;: A console command that runs an MCP server to communicate with AI assistants&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Extension Points&lt;/strong&gt;: Plugin interfaces for adding custom MCP tools and prompts&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Built-in Tools&lt;/strong&gt;: Pre-configured tools for accessing Spryker transfers, interfaces, and OMS information&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prompt Generation&lt;/strong&gt;: Automatic generation of context-aware prompts from documentation&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;console-commands&quot;&gt;Console commands&lt;/h2&gt;
&lt;p&gt;The AiDev module provides the following console commands:&lt;/p&gt;
&lt;h3 id=&quot;mcp-server-command&quot;&gt;MCP Server Command&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;ai-dev:mcp-server&lt;/code&gt; command starts an MCP server that allows AI assistants to interact with your Spryker application.&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 console ai-dev:mcp-server &lt;span class=&quot;nt&quot;&gt;-q&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This command:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Starts an MCP server using stdio transport&lt;/li&gt;
&lt;li&gt;Registers all configured MCP tool and prompt plugins&lt;/li&gt;
&lt;li&gt;Automatically generates prompts if they don’t exist&lt;/li&gt;
&lt;li&gt;Listens for requests from AI assistants&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;: This command is typically configured in AI assistant tools (like Claude Desktop) to enable them to access Spryker-specific information.&lt;/p&gt;
&lt;h3 id=&quot;setup-command&quot;&gt;Setup Command&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;ai-dev:setup&lt;/code&gt; command sets up AI tooling for your Spryker project. It generates rules, an agents/context file, and skills — all tailored to the selected AI tool.&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 console ai-dev:setup
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The command automatically detects the AI tool installed in your project and prompts you to confirm or select a different one. It then generates the following for the selected tool:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Rules&lt;/strong&gt;: Coding conventions and architectural guidelines.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agents/context file&lt;/strong&gt;: Project-specific context for AI agents.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skills&lt;/strong&gt;: Reusable task-specific AI skill files.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Output modes&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The command supports two output modes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ready to use&lt;/strong&gt;: Files are generated directly in the tool-specific directories listed in the table below.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Example&lt;/strong&gt;: Files are generated in example directories — for example, &lt;code&gt;.claude/rules-example/&lt;/code&gt; instead of &lt;code&gt;.claude/rules/&lt;/code&gt;. Rename the directories when ready to use.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Output locations by AI tool&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;AI tool&lt;/th&gt;
&lt;th&gt;Rules directory&lt;/th&gt;
&lt;th&gt;Agents/context file&lt;/th&gt;
&lt;th&gt;Skills directory&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.claude/rules/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.claude/skills/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windsurf&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.windsurf/rules/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.windsurfrules&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.windsurf/skills/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Copilot&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.github/instructions/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.github/copilot-instructions.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.github/skills/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cursor&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.cursor/rules/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AGENTS.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.cursor/skills/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenCode&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.opencode/rules/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AGENTS.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.agents/skills/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Codex CLI&lt;/td&gt;
&lt;td&gt;Not supported — see below&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AGENTS.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.agents/skills/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Codex CLI does not have a native rules format. When you select it, the command offers to generate rules in another tool’s format instead and places them in that tool’s rules directory.&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;GitHub Copilot and Docker sync&lt;/div&gt;
&lt;p&gt;If you use Docker sync, the &lt;code&gt;/.git*&lt;/code&gt; entry in &lt;code&gt;.dockersyncignore&lt;/code&gt; also excludes the &lt;code&gt;.github&lt;/code&gt; folder, which prevents Copilot-generated files from being available inside the container. To fix this, add the following line to &lt;code&gt;.dockersyncignore&lt;/code&gt; after the &lt;code&gt;/.git*&lt;/code&gt; entry:&lt;/p&gt;
&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;!/.github
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/section&gt;
&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;: Run this command once when setting up AI tooling for a project.&lt;/p&gt;
&lt;h3 id=&quot;generate-prompts-command&quot;&gt;Generate Prompts Command&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;ai-dev:generate-prompts&lt;/code&gt; command generates MCP prompts from a configured &lt;a href=&quot;https://github.com/spryker-dev/prompt-library&quot;&gt;Prompt Library&lt;/a&gt;.&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 console ai-dev:generate-prompts
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This command:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fetches prompts&lt;/li&gt;
&lt;li&gt;Generates PHP-based prompt classes&lt;/li&gt;
&lt;li&gt;Stores generated prompts in the configured directory&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;: Use this command when you need to regenerate prompts from updated documentation or when initializing the module for the first time.&lt;/p&gt;
&lt;h2 id=&quot;extension-points&quot;&gt;Extension points&lt;/h2&gt;
&lt;p&gt;The AiDev module provides plugin interfaces for extending the MCP server with custom functionality:&lt;/p&gt;
&lt;h3 id=&quot;aidevmcptoolplugininterface&quot;&gt;AiDevMcpToolPluginInterface&lt;/h3&gt;
&lt;p&gt;Implement this interface to add custom MCP tools that AI assistants can use to query or interact with your application.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Interface location&lt;/strong&gt;: &lt;code&gt;SprykerSdk\Zed\AiDev\Dependency\AiDevMcpToolPluginInterface&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Integration&lt;/strong&gt;: Register your tool plugins in &lt;code&gt;AiDevDependencyProvider::getMcpToolPlugins()&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\AiDev&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;SprykerSdk\Zed\AiDev\AiDevDependencyProvider&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SprykerAiDevDependencyProvider&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\AiDev\Communication\Plugins\CustomAiDevMcpToolPlugin&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;AiDevDependencyProvider&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SprykerAiDevDependencyProvider&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;cd&quot;&gt;/**
     * @return array&amp;lt;\SprykerSdk\Zed\AiDev\Dependency\AiDevMcpToolPluginInterface&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;getMcpToolPlugins&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;nb&quot;&gt;array_merge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;parent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getMcpToolPlugins&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;CustomAiDevMcpToolPlugin&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;aidevmcppromptplugininterface&quot;&gt;AiDevMcpPromptPluginInterface&lt;/h3&gt;
&lt;p&gt;Implement this interface to add custom MCP prompts that provide context or instructions to AI assistants.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Interface location&lt;/strong&gt;: &lt;code&gt;SprykerSdk\Zed\AiDev\Dependency\AiDevMcpPromptPluginInterface&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Integration&lt;/strong&gt;: Register your prompt plugins in &lt;code&gt;AiDevDependencyProvider::getMcpPromptPlugins()&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\AiDev&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;SprykerSdk\Zed\AiDev\AiDevDependencyProvider&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SprykerAiDevDependencyProvider&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\AiDev\Communication\Plugins\CustomAiDevMcpPromptPlugin&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;AiDevDependencyProvider&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SprykerAiDevDependencyProvider&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;cd&quot;&gt;/**
     * @return array&amp;lt;\SprykerSdk\Zed\AiDev\Dependency\AiDevMcpPromptPluginInterface&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;getMcpPromptPlugins&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;CustomAiDevMcpPromptPlugin&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;configuration&quot;&gt;Configuration&lt;/h2&gt;
&lt;p&gt;The AiDev module can be configured through the &lt;code&gt;AiDevConfig&lt;/code&gt; class. Key configuration options include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Prompt Directory&lt;/strong&gt;: Set the directory where generated prompts are stored&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Refer to the module’s configuration class for available options and their default values.&lt;/p&gt;
&lt;h2 id=&quot;debugging-the-mcp-server&quot;&gt;Debugging the MCP server&lt;/h2&gt;
&lt;p&gt;Before connecting your MCP server to AI assistants, you can test and debug it using the &lt;a href=&quot;https://modelcontextprotocol.io/docs/tools/inspector&quot;&gt;MCP Inspector&lt;/a&gt; tool. The inspector provides a web interface to interact with your MCP server, test tools, and verify that everything works correctly.&lt;/p&gt;
&lt;h3 id=&quot;using-the-mcp-inspector&quot;&gt;Using the MCP Inspector&lt;/h3&gt;
&lt;p&gt;Navigate to your Spryker project directory and run:&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;npx @modelcontextprotocol/inspector docker/sdk console ai-dev:mcp-server &lt;span class=&quot;nt&quot;&gt;-q&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This command will:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Start the MCP Inspector in your browser&lt;/li&gt;
&lt;li&gt;Connect to your local MCP server&lt;/li&gt;
&lt;li&gt;Display all available tools and prompts&lt;/li&gt;
&lt;li&gt;Allow you to test tool calls interactively&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With Xdebug&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;npx @modelcontextprotocol/inspector docker/sdk cli &lt;span class=&quot;nt&quot;&gt;-x&lt;/span&gt; console ai-dev:mcp-server
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&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;Node.js required&lt;/div&gt;
&lt;p&gt;The MCP Inspector requires Node.js to be installed on your system. The &lt;code&gt;npx&lt;/code&gt; command will automatically download and run the inspector tool without requiring a global installation.&lt;/p&gt;
&lt;/div&gt;&lt;/section&gt;
&lt;p&gt;&lt;img src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/dg/dev/ai-dev/mcp-inspector.png&quot; alt=&quot;MCP Inspector&quot; /&gt;&lt;/p&gt;
</description>
            <pubDate>Thu, 23 Apr 2026 07:22:30 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/ai/ai-dev/ai-dev-overview.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/ai/ai-dev/ai-dev-overview.html</guid>
            
            
        </item>
        
        <item>
            <title>AI Dev SDK</title>
            <description>&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;Warning&lt;/div&gt;
&lt;p&gt;Before you use AI-related tools, consult your legal department.&lt;/p&gt;
&lt;/div&gt;&lt;/section&gt;
&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;/h2&gt;
&lt;p&gt;When you use AI tools to write code, they rely on general patterns, which leads to mistakes and requires you to repeatedly explain your project structure.&lt;/p&gt;
&lt;p&gt;The AI Dev SDK provides an MCP server, which is a console command that your AI tool runs in your project’s Docker container and helps it to increase Spryker-context awareness. MCP (Model Context Protocol) is a standard protocol that lets AI tools request specific information from external sources, similar to how a browser requests data from an API.&lt;/p&gt;
&lt;h2 id=&quot;how-it-works&quot;&gt;How it works&lt;/h2&gt;
&lt;p&gt;After you install the SDK, &lt;a href=&quot;/docs/dg/dev/ai/ai-dev/ai-dev-mcp-server.html&quot;&gt;add a simple configuration&lt;/a&gt; to your AI tool. When your Spryker project is running, your AI tool can access Spryker-specific information and prompts through the MCP server.&lt;/p&gt;
&lt;h2 id=&quot;result&quot;&gt;Result&lt;/h2&gt;
&lt;p&gt;AI generates better code faster and with fewer errors. You spend less time correcting mistakes and explaining Spryker concepts.&lt;/p&gt;
&lt;h2 id=&quot;key-capabilities&quot;&gt;Key capabilities&lt;/h2&gt;
&lt;h3 id=&quot;faster-spryker-specific-answers&quot;&gt;Faster Spryker-specific answers&lt;/h3&gt;
&lt;p&gt;AI can search Spryker documentation instead of requiring you to explain basic concepts or guessing how features work.&lt;/p&gt;
&lt;h3 id=&quot;smarter-code-generation&quot;&gt;Smarter code generation&lt;/h3&gt;
&lt;p&gt;AI can look up your actual transfer objects, module dependencies, and interface methods so that the generated code matches your project structure instead of relying on assumptions.&lt;/p&gt;
&lt;h3 id=&quot;oms-debugging-made-easy&quot;&gt;OMS debugging made easy&lt;/h3&gt;
&lt;p&gt;AI can analyze your OMS flows to find possible next states, transitions, conditions, and timeouts for any order or state. This capability is especially helpful when you work with complex OMS schemas. You no longer need to manually follow arrows in large diagrams.&lt;/p&gt;
&lt;h3 id=&quot;working-with-complex-data-imports&quot;&gt;Working with complex data imports&lt;/h3&gt;
&lt;p&gt;AI can analyze, modify, and transform multi-column CSV files correctly. This task normally requires significant manual effort.&lt;/p&gt;
&lt;h3 id=&quot;sharing-prompts-across-your-team&quot;&gt;Sharing prompts across your team&lt;/h3&gt;
&lt;p&gt;The SDK includes access to the Spryker prompt library, and you can add your own project-specific prompts. This means your team can reuse effective prompts instead of everyone writing their own.&lt;/p&gt;
&lt;h3 id=&quot;database-queries&quot;&gt;Database queries&lt;/h3&gt;
&lt;p&gt;AI can execute read-only database queries to inspect data when debugging issues.&lt;/p&gt;
&lt;h3 id=&quot;extensible-for-your-project&quot;&gt;Extensible for your project&lt;/h3&gt;
&lt;p&gt;You can extend the MCP server by creating custom plugins (to add new tools) and custom prompts.&lt;/p&gt;
&lt;h2 id=&quot;install-the-ai-dev-sdk&quot;&gt;Install the AI Dev SDK&lt;/h2&gt;
&lt;h3 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;/h3&gt;
&lt;p&gt;Ensure that you have a Spryker project with Composer installed.&lt;/p&gt;
&lt;h3 id=&quot;installation-steps&quot;&gt;Installation steps&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Require the package as a development dependency:&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-sdk/ai-dev &lt;span class=&quot;nt&quot;&gt;--dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Generate the transfer objects:&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;li&gt;
&lt;p&gt;Register the console commands in your &lt;code&gt;ConsoleDependencyProvider&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;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SprykerSdk\Zed\AiDev\Communication\Console\AiToolSetupConsole&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;SprykerSdk\Zed\AiDev\Communication\Console\GeneratePromptsConsole&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;SprykerSdk\Zed\AiDev\Communication\Console\McpServerConsole&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;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getConsoleCommands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Container&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$container&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;mf&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;nb&quot;&gt;class_exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;McpServerConsole&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&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;$commands&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;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;McpServerConsole&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;nb&quot;&gt;class_exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;GenerateSkillsConsole&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&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;$commands&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;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AiToolSetupConsole&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;nb&quot;&gt;class_exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;GeneratePromptsConsole&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class&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;$commands&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;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GeneratePromptsConsole&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;mf&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;Connect the AI Dev SDK to your AI agent. For detailed configuration instructions, see &lt;a href=&quot;/docs/dg/dev/ai/ai-dev/ai-dev-mcp-server.html&quot;&gt;Configure the AiDev MCP server&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;next-steps&quot;&gt;Next steps&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/docs/dg/dev/ai/ai-dev/ai-dev-mcp-server.html&quot;&gt;Configure the AiDev MCP server&lt;/a&gt; - Set up the connection to your AI tool&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/docs/dg/dev/ai/ai-dev/ai-dev-overview.html&quot;&gt;AI Dev SDK Overview&lt;/a&gt; - Learn more about the AI Dev SDK features and capabilities&lt;/li&gt;
&lt;/ul&gt;
</description>
            <pubDate>Thu, 23 Apr 2026 07:15:42 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/ai/ai-dev/ai-dev.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/ai/ai-dev/ai-dev.html</guid>
            
            
        </item>
        
        <item>
            <title>Test console commands</title>
            <description>Spryker supports several [test helpers](/docs/dg/dev/guidelines/testing-guidelines/test-helpers/test-helpers.html) to assist you in testing your project. This article provides details of how to test console commands with ConsoleHelper.

To test console commands, do the following:

1. Add `\SprykerTest\Zed\Console\Helper\ConsoleHelper` to the `codeception.yml` file:

```yml
suites:
    Communication:
        path: Communication
        actor: {ModuleName}CommunnicationTester
        modules:
            enabled:
                - \SprykerTest\Zed\Console\Helper\ConsoleHelper
                - ...
```

For more information about the `codeception.yml` file, see [Test framework](/docs/dg/dev/guidelines/testing-guidelines/test-framework.html).

2. Create the test directory `tests/PyzTests/Zed/FooModule/Communication/Plugin/Console/`, if it&apos;s not available yet.
3. Add the test class:

```php
&lt;?php

namespace PyzTest\Zed\FooModule\Communication\Plugin\Console;

use Codeception\Test\Unit;
use PyzTest\Zed\FooModule\FooModuleCommunicationTester;

class MyConsoleCommandTest extends Unit
{
    /**
     * @var \{Organization}Test\Zed\FooModule\FooModuleCommunicationTester
     */
    protected FooModuleCommunicationTester $tester;
}
```

4. Add the test method:

```php
public function testMyConsoleCommand(): void
{
    // You can also use a mocked command or add a mocked facade etc.
    $command = new MyConsoleCommand();
    $commandTester = $this-&gt;tester-&gt;getConsoleTester($command);

    $input = [
        MyConsoleCommand::ARGUMENT_FOO =&gt; &apos;foo-argument&apos;,
        &apos;--&apos; . MyConsoleCommand::OPTION_BAR =&gt; &apos;bar-option&apos;,
    ];

    $commandTester-&gt;execute($input);

    $this-&gt;assertSame(MyConsoleCommand::CODE_SUCCESS, $commandTester-&gt;getStatusCode());

    // When you expect some output from the console command you can assert it with:
    $this-&gt;assertStringContainsString(&apos;My console command output.&apos;, $commandTester-&gt;getDisplay());
}
```

That&apos;s it. You are all set to test the console commands.
</description>
            <pubDate>Wed, 22 Apr 2026 12:15:12 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/guidelines/testing-guidelines/executing-tests/test-console-commands.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/guidelines/testing-guidelines/executing-tests/test-console-commands.html</guid>
            
            
        </item>
        
        <item>
            <title>New Relic transactions grouping by queue names</title>
            <description>By default, the `spryker/monitoring` module groups all New Relic transactions generated from a console command by the command&apos;s name. For example, `ooms:check-timeout`.

This strategy works in most cases, and you can still query the data from a needed queue using [NRQL](https://docs.newrelic.com/docs/query-your-data/nrql-new-relic-query-language/get-started/nrql-syntax-clauses-functions/). But you might want to override this behavior.

For example, you run  multiple commands like `queue:task:start publish.product_abstract` and `queue:task:start sync.storage.url`. With the default naming strategy, all the calls of the command will be grouped together by `queue:task:start`. Transaction data is aggregated under the same name for all types of queue processors.

In New Relic dashboard, this looks as follows:

![Transactions under the same name](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/dev/guidelines/performance-guidelines/elastic-computing/enable-queue-task-flow-in-new-relic.md/transactions-under-the-same-name.png)

## Group transactions by queue name

As queue name usually comes as the first argument of a command, to enable grouping by names, you need to need to enable grouping by the first argument as follows:

1. Integrate the `spryker/monitoring` module.
2. Provide an advanced extendable infrastructure for [New relic monitoring transaction](https://docs.newrelic.com/docs/apm/transactions/intro-transactions/transactions-new-relic-apm/) naming strategies. This lets you implement, configure, and override the default transaction naming behavior.
3. Implement the strategy that enables configured console commands to apply naming that groups transaction by command name and first argument.
4. Enable the new strategy for `queue:task:start` on the project level.

As a result, the transactions are displayed as follows:

![Aggregation of transactions](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/dev/guidelines/performance-guidelines/elastic-computing/enable-queue-task-flow-in-new-relic.md/aggregation-of-transactions.png)

## Integrate New Relic transactions grouping by queue names

For instructions, see [Integrate New Relic transactions grouping by queue names](/docs/dg/dev/integrate-and-configure/integrate-elastic-computing.html#integrate-new-relic-monitoring).

## Implementation details

![New Relic transaction grouping by name implementation details](https://confluence-connect.gliffy.net/embed/image/59eaf32b-df1e-4fb9-a5e7-64b77c8ab870.png?utm_medium=live&amp;utm_source=custom)
</description>
            <pubDate>Wed, 22 Apr 2026 12:15:12 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/guidelines/performance-guidelines/elastic-computing/new-relic-transaction-grouping-by-queue-names.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/guidelines/performance-guidelines/elastic-computing/new-relic-transaction-grouping-by-queue-names.html</guid>
            
            
        </item>
        
        <item>
            <title>E2E Testing with Cypress</title>
            <description>&lt;p&gt;Cypress is an end-to-end testing framework that provides a modern approach to testing web applications. Spryker provides a Cypress boilerplate project with pre-configured setup, best practices, and examples for testing Spryker-based applications.&lt;/p&gt;
&lt;h2 id=&quot;cypress-boilerplate&quot;&gt;Cypress boilerplate&lt;/h2&gt;
&lt;p&gt;For comprehensive information on setting up and using Cypress with Spryker, refer to the &lt;a href=&quot;https://github.com/spryker-projects/cypress-boilerplate&quot;&gt;cypress-boilerplate&lt;/a&gt; repository.&lt;/p&gt;
&lt;p&gt;The boilerplate includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pre-configured Cypress setup optimized for Spryker projects&lt;/li&gt;
&lt;li&gt;Example test cases and patterns&lt;/li&gt;
&lt;li&gt;Documentation and best practices&lt;/li&gt;
&lt;li&gt;Integration guides&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The boilerplate does NOT include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Complete test coverage - you should add and adjust example tests to fit your project&lt;/li&gt;
&lt;li&gt;Correct locators - the locators in the boilerplace are based on Spryker demo shops, adjust the locators in accordance with your project&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;internal-cypress-tests&quot;&gt;Internal Cypress tests&lt;/h2&gt;
&lt;p&gt;Cypress tests are used by Spryker for internal testing of the core Spryker features as well. You should remove the mentions of &lt;code&gt;cypress-tests&lt;/code&gt; from &lt;code&gt;composer.json&lt;/code&gt;. You can re-use and customize these tests for your project, however, Spryker does not guarantee these tests will work on your project, if you keep them. Spryker recommends you use the &lt;a href=&quot;https://github.com/spryker-projects/cypress-boilerplate/wiki&quot;&gt;boilerplate&lt;/a&gt; instead.&lt;/p&gt;
&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Repository&lt;/strong&gt;: &lt;a href=&quot;https://github.com/spryker-projects/cypress-boilerplate&quot;&gt;spryker-projects/cypress-boilerplate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wiki&lt;/strong&gt;: &lt;a href=&quot;https://github.com/spryker-projects/cypress-boilerplate/wiki&quot;&gt;cypress-boilerplate Wiki&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
            <pubDate>Wed, 22 Apr 2026 12:15:12 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/guidelines/testing-guidelines/cypress-testing.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/guidelines/testing-guidelines/cypress-testing.html</guid>
            
            
        </item>
        
        <item>
            <title>Architecture</title>
            <description>&lt;p&gt;One of the main tasks of a commerce platform is the possibility to customize, extend, and integrate it with external services, such as payment providers, order processors, and the like. To provide a clear path for the Spryker Commerce OS development and extension, its architecture is based on strict modularity and separation. These principles are strongly supported by the OS architecture. This architecture guide helps you understand how they are implemented on different levels.&lt;/p&gt;
&lt;p&gt;In this section, you can learn the following topics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Spryker architecture and concepts.&lt;/li&gt;
&lt;li&gt;What technologies we use.&lt;/li&gt;
&lt;li&gt;What applications the Spryker Commerce OS is composed of.&lt;/li&gt;
&lt;li&gt;How we enable the development of high-performance applications and their scalability.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also, this guide is especially useful for developers, architects, and integrators dealing with Spryker Cloud Commerce OS.&lt;/p&gt;
</description>
            <pubDate>Wed, 22 Apr 2026 12:15:12 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/architecture/architecture.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/architecture/architecture.html</guid>
            
            
        </item>
        
        <item>
            <title>Architecture as Code</title>
            <description>&lt;p&gt;Well-documented project architecture enables faster internal and external onboarding, passes audits cleanly and aligns teams on requirements. Without it, your system becomes a black box that only the original developers understand.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Architecture as Code&lt;/strong&gt; treats architecture documentation like code, similarly to the Infrastructure-as-Code concept. Instead of storing architecture in binary formats or external tools (Word, PowerPoint, Visio, Confluence) that become outdated quickly, you store and maintain architecture documentation in version control alongside your implementation.&lt;/p&gt;
&lt;p&gt;Spryker ships the architecture/ folder with a complete Architecture as Code structure with its demoshop codebase. You can refer to &lt;code&gt;architecture/README.md&lt;/code&gt; that describes how to work with it. Below, you find all the general information about the structure and principles. We go into the details of each aspect to help you understand and extend this architecture documentation in your project.&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;Existing projects&lt;/div&gt;
&lt;p&gt;If your project is based on a Spryker release before 202602.0, refer to the &lt;a href=&quot;https://github.com/spryker/b2b-demo-marketplace&quot;&gt;Spryker B2B Demo Marketplace&lt;/a&gt; master branch source code to see how the Architecture as Code structure is implemented and to copy the “architecture/” folder into your project.&lt;/p&gt;
&lt;/div&gt;&lt;/section&gt;
&lt;h2 id=&quot;why-architecture-as-code&quot;&gt;Why Architecture as Code&lt;/h2&gt;
&lt;p&gt;Traditional architecture documentation suffers from several challenges:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Documentation drift&lt;/strong&gt; - Binary formats stored separately from code become outdated quickly&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Version control gaps&lt;/strong&gt; - Specialized tools do not integrate with Git workflows&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Collaboration barriers&lt;/strong&gt; - Requires specialized software and binary file merging&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI limitations&lt;/strong&gt; - AI tools understand code and Markdown effectively but struggle with proprietary formats and binary documents&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Architecture as Code solves these problems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Version controlled&lt;/strong&gt; - Store in Git alongside implementation. Track every change with full history.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI-ready&lt;/strong&gt; - Markdown and diagrams-as-code enable AI assistance, automated validation, and intelligent analysis.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Standard formats&lt;/strong&gt; - Use industry standards (arc42, C4, ADRs, Mermaid) that external teams understand immediately.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Collaborative&lt;/strong&gt; - Review through pull requests. No special tools required — only a text editor.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Living documentation&lt;/strong&gt; - Update during development, not after. Documentation evolves with your system.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;core-principles&quot;&gt;Core Principles&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Standards over invention&lt;/strong&gt; - Use industry-proven formats and standards (arc42, C4, ADRs, Mermaid) instead of custom documentation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Minimal but sufficient&lt;/strong&gt; - Start simple. Prioritize clarity and expansion over completeness on day one.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Architecture is code&lt;/strong&gt; - Write in plain text, store in Git, review through pull requests, deploy automatically.&lt;/p&gt;
&lt;h2 id=&quot;concepts-and-choices&quot;&gt;Concepts and Choices&lt;/h2&gt;
&lt;h3 id=&quot;arc42&quot;&gt;arc42&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://arc42.org/&quot;&gt;arc42&lt;/a&gt; is a proven template for architecture documentation used globally across industries.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why arc42 fits Spryker projects:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Spryker projects vary dramatically in complexity — from simple B2C shops to complex B2B marketplaces with extensive integrations and order management systems. arc42 is flexible enough to cover architecture of any complexity and scales as your Spryker implementation grows. You can start simple with minimal sections and expand as your architecture requires more detail.&lt;/p&gt;
&lt;p&gt;The template includes 12 sections (described below) covering all architectural aspects. Section 4 (Solution Designs) provides RFC-style exploration templates. Section 9 (Architecture Decisions) uses ADRs to document decisions with context and consequences. This workflow — explore with Solution Designs, then document decisions with ADRs — ensures thoughtful architecture evolution.&lt;/p&gt;
&lt;h3 id=&quot;c4-model&quot;&gt;C4 Model&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://c4model.com/&quot;&gt;C4 Model&lt;/a&gt; provides a hierarchical approach to system visualization with four levels of abstraction.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why C4 fits Spryker architecture:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Spryker architecture unfolds naturally through C4 layers — start with the system context, zoom into containers (Yves, Zed, Client, databases, services), then dive deeper into layers and components as needed. This progressive detail matches how Spryker complexity reveals itself. The entire Spryker feature set can be shown using this unfolding approach.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Flexibility advantage:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You control the depth. Start at C1 (context) and continue only as deep as your documentation needs require. Given limited architect time, this flexibility is essential — stop at the level appropriate for your stakeholders and complexity.&lt;/p&gt;
&lt;h3 id=&quot;mermaid-and-plantuml&quot;&gt;Mermaid and PlantUML&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Mermaid&lt;/strong&gt; - Our primary choice for diagramming-as-code:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Renders automatically in GitHub and GitLab, and can be rendered via plugins in popular IDEs&lt;/li&gt;
&lt;li&gt;No proprietary tools required&lt;/li&gt;
&lt;li&gt;Covers 90% of diagram needs: flowcharts, sequences, C4 diagrams&lt;/li&gt;
&lt;li&gt;Online editor at &lt;a href=&quot;https://mermaid.live/&quot;&gt;mermaid.live&lt;/a&gt; for convenient editing and better visualization than most IDEs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;PlantUML&lt;/strong&gt; - For precision when needed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Essential for Entity-Relationship Diagrams where field-level precision matters&lt;/li&gt;
&lt;li&gt;Online editor at &lt;a href=&quot;https://www.plantuml.com/plantuml/&quot;&gt;plantuml.com&lt;/a&gt; for live editing and preview&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;what-comes-out-of-the-box&quot;&gt;What Comes Out of the Box&lt;/h2&gt;
&lt;p&gt;We provide templates with clear structure and minimal context, plus examples of the most common diagram types (C4, data flow, integration, sequence) and documentation patterns (ADRs, Solution Designs). AI tools work most efficiently when they see the methodology (like arc42), understand the structure, and have examples to follow. This approach enables you to generate architecture documentation much faster with AI assistance.&lt;/p&gt;
&lt;p&gt;Templates provide examples and structural guidance — you should adapt content to your project’s context. You do not need to implement all sections immediately; remove or keep unused sections based on your documentation strategy.&lt;/p&gt;
&lt;h3 id=&quot;folder-structure&quot;&gt;Folder Structure&lt;/h3&gt;
&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;architecture/
├── 01-introduction-and-goals.md           # Requirements, quality goals, stakeholders
├── 02-constraints.md                      # Technical, organizational constraints
├── 03-system-scope-and-context.md         # System boundaries, external interfaces
│                                          # Includes: External systems and integration tables
├── 04-solution-designs/                   # RFC-style exploration documents
│   ├── README.md                          # Workflow explanation
│   └── sd-000-template.md                 # Solution design template
├── 05-building-block-view.md              # System decomposition
├── 06-runtime-view.md                     # Behavior and interactions
├── 07-deployment-view.md                  # Infrastructure topology
├── 08-crosscutting-concepts.md            # Patterns spanning components
├── 09-architecture-decisions/             # Architecture decision records
│   ├── README.md                          # ADR workflow and sources
│   └── adr-000-template.md                # ADR template
├── 10-quality-requirements.md             # Performance, scalability, testing
│                                          # Includes: Volume planning, testing strategy
├── 11-risks-and-technical-debt.md         # Known issues and mitigation
├── 12-glossary.md                         # Domain terminology
├── diagrams/
│   ├── c4/
│   │   ├── c1-system-context.mmd          # System context diagram
│   │   ├── c2-spryker-container.mmd       # Container diagram
│   │   └── c3-component-diagram.mmd       # Component diagram
│   ├── data-flow/
│   │   └── product-price-data-flow.mmd    # Price data flow example
│   ├── integration/
│   │   └── product-price-integration.mmd  # Integration overview with protocols
│   ├── sequence/
│   │   ├── api-payment.mmd                # Payment flow
│   │   ├── publish-sync.mmd               # Publish and Sync process
│   │   └── punchout-greenwing-integration.mmd  # PunchOut example
│   └── erd/                               # Entity-relationship diagrams (PlantUML)
└── README.md                              # Quick start and overview
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;diagram-organization-and-best-practices&quot;&gt;Diagram Organization and Best Practices&lt;/h3&gt;
&lt;p&gt;You have two approaches to managing diagrams. Choose based on your documentation use case.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Approach 1: Inline Diagrams&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Write diagram code directly in markdown using code fences:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;&gt;flowchart LR
    A --&amp;gt; B
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; Diagrams are visible immediately; self-contained&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt; Increases file size; duplicates code if reused&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Approach 2: External Diagram Files&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Store diagram code in &lt;code&gt;/diagrams/&lt;/code&gt; folder and reference via links:&lt;/p&gt;
&lt;div class=&quot;language-markdown 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;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;C1 System Context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;diagrams/c4/c1-system-context.mmd&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;&lt;strong&gt;Pros:&lt;/strong&gt; Single source-of-truth; cleaner markdown; scalable&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt; Requires clicking to view (less immediate)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Choosing Your Approach&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This template uses &lt;strong&gt;Approach 2&lt;/strong&gt; for scalability and maintainability, but projects can mix both — use external files for core views, inline for one-off diagrams.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Universal Color Scheme:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;All diagrams use colors optimized for both light and dark modes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Orange &lt;code&gt;#E67E22&lt;/code&gt; - Communication layer&lt;/li&gt;
&lt;li&gt;Blue &lt;code&gt;#2980B9&lt;/code&gt; - Backend services, APIs&lt;/li&gt;
&lt;li&gt;Green &lt;code&gt;#27AE60&lt;/code&gt; - Web apps, external systems&lt;/li&gt;
&lt;li&gt;Purple &lt;code&gt;#9B59B6&lt;/code&gt; - Storage (databases, caches)&lt;/li&gt;
&lt;li&gt;Gray &lt;code&gt;#95A5A6&lt;/code&gt; - Infrastructure&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;templates-and-guidelines&quot;&gt;Templates and Guidelines&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Solution Design Template&lt;/strong&gt; (&lt;code&gt;04-solution-designs/sd-000-template.md&lt;/code&gt;):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metadata section (status, date, stakeholders)&lt;/li&gt;
&lt;li&gt;Problem statement&lt;/li&gt;
&lt;li&gt;Goals and requirements&lt;/li&gt;
&lt;li&gt;Proposed solution with diagrams&lt;/li&gt;
&lt;li&gt;Implementation plan&lt;/li&gt;
&lt;li&gt;Trade-offs and alternatives&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;ADR Template&lt;/strong&gt; (&lt;code&gt;09-architecture-decisions/adr-000-template.md&lt;/code&gt;):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Standard ADR structure&lt;/li&gt;
&lt;li&gt;Status tracking&lt;/li&gt;
&lt;li&gt;Context, decision, consequences&lt;/li&gt;
&lt;li&gt;Links to related decisions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Volume Planning Table&lt;/strong&gt; (Section 10):&lt;/p&gt;
&lt;p&gt;Pre-structured table for capacity planning covering:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Catalog entities (products, categories, prices)&lt;/li&gt;
&lt;li&gt;Cart constraints&lt;/li&gt;
&lt;li&gt;User load projections&lt;/li&gt;
&lt;li&gt;B2B customers structure&lt;/li&gt;
&lt;li&gt;Marketplace metrics&lt;/li&gt;
&lt;li&gt;Internationalization requirements&lt;/li&gt;
&lt;li&gt;Orders and infrastructure&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;getting-help&quot;&gt;Getting Help&lt;/h2&gt;
&lt;h3 id=&quot;resources&quot;&gt;Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;arc42 Documentation&lt;/strong&gt;: &lt;a href=&quot;https://arc42.org/&quot;&gt;https://arc42.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C4 Model Guide&lt;/strong&gt;: &lt;a href=&quot;https://c4model.com/&quot;&gt;https://c4model.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mermaid Syntax&lt;/strong&gt;: &lt;a href=&quot;https://mermaid.js.org/&quot;&gt;https://mermaid.js.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ADR Guidelines&lt;/strong&gt;: &lt;a href=&quot;https://adr.github.io/&quot;&gt;https://adr.github.io/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;common-questions&quot;&gt;Common Questions&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Q: Do I need to fill in every arc42 section?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A: No. Fill in what is relevant for your project. Some sections may remain minimal.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q: Can I add custom sections?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A: First, check all 12 arc42 sections — the standard format covers most architectural concerns. If no existing section fits your content, you can add a custom section. Ensure the section purpose is clear and describe it in the README.md file.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q: How detailed should diagrams be?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A: For C4 diagrams, follow the levels: Context (high-level), Container (more detail), Component (detailed). For other diagram types (data flow, integration, sequence), follow industry standards for that specific notation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q: When should I create an ADR vs Solution Design?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A: Use Solution Design for exploration. Use ADR for documenting the final decision.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q: Can I use different diagram notations?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A: Yes. The choice is yours — we do not limit you to Mermaid or PlantUML. Ensure your notation follows the core principles: viewable by people, understandable by AI tools, and ideally diagrams-as-code (text-based format in version control).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q: Will diagrams-as-code replace whiteboards and visual editing tools?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A: No. The art of creating and drawing diagrams — whether on whiteboards, visual tools, or pen and paper — remains valuable. Diagrams-as-code is for documenting what you have drawn and decided. Use whatever tools help you think and collaborate, then capture the final result as code for version control and documentation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q: Can I use images as diagrams instead of diagrams-as-code?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A: Yes, it is better to have image diagrams than no diagrams at all, but understand the trade-off. Hand-drawn or visually edited diagrams often look more polished than generated ones. However, images are not as understandable or generable by AI (at least currently) and lack version control benefits. You can use both: include beautiful images for presentations and stakeholder communication, alongside diagrams-as-code for AI assistance and documentation processes.&lt;/p&gt;
</description>
            <pubDate>Wed, 22 Apr 2026 12:15:12 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/architecture/architecture-as-code.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/architecture/architecture-as-code.html</guid>
            
            
        </item>
        
        <item>
            <title>AI workflow orchestration with state machines</title>
            <description>&lt;p&gt;This guide shows you how to build multi-step, multi-agent AI workflows using Spryker state machines. By combining state machines with the AiFoundation module, you can orchestrate complex AI processes where agents execute tasks, make decisions based on results, and trigger subsequent steps.&lt;/p&gt;
&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;/h2&gt;
&lt;p&gt;Spryker state machines provide a powerful framework for orchestrating AI workflows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;States&lt;/strong&gt;: Represent stages in your workflow (for example, “analysis_done”, “awaiting_review”)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Events&lt;/strong&gt;: Trigger state transitions (for example, “analyze_agent” executes an AI call)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Commands&lt;/strong&gt;: Execute AI operations, tool calls, or business logic&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Conditions&lt;/strong&gt;: Evaluate workflow item data to decide the next state (for example, “is_successful?”)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Context data&lt;/strong&gt;: Passed through the workflow to accumulate results and drive decisions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This creates a directed graph where &lt;strong&gt;conditions act as edges&lt;/strong&gt; determining the next state based on AI-generated outputs.&lt;/p&gt;
&lt;h2 id=&quot;key-concepts&quot;&gt;Key concepts&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Context data&lt;/strong&gt;: A key-value array that flows through the state machine, allowing commands to read input and write results for conditions to evaluate&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Structured response&lt;/strong&gt;: AI responses converted to structured data, enabling deterministic decision-making&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Command plugins&lt;/strong&gt;: Execute AI calls and update context with results&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Condition plugins&lt;/strong&gt;: Evaluate context data to determine workflow progression&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Process name&lt;/strong&gt;: Links XML definition to PHP configuration and state machine execution&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;create-a-workflow-process-example&quot;&gt;Create a workflow process example&lt;/h2&gt;
&lt;h3 id=&quot;define-the-state-machine-xml&quot;&gt;1. Define the state machine XML&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Example: IntelligentTask01&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Create &lt;code&gt;config/Zed/StateMachine/AiWorkflow/IntelligentTask01.xml&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-xml 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;?xml version=&quot;1.0&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;statemachine&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;spryker:state-machine-01&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xmlns:xsi=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;spryker:state-machine-01 http://static.spryker.com/state-machine-01.xsd&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;nt&quot;&gt;&amp;lt;process&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;IntelligentTask01&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;main=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;states&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;state&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;new&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;state&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;analysis done&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;state&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;analysis successful&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;state&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;analysis failed&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/states&amp;gt;&lt;/span&gt;

        &lt;span class=&quot;nt&quot;&gt;&amp;lt;events&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- onEnter=&quot;true&quot; triggers the command automatically when entering source state --&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;event&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;analyze agent&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;onEnter=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;true&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;command=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;OryxAgent/Analyze&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;event&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;pass&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;onEnter=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;event&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;restart&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;manual=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/events&amp;gt;&lt;/span&gt;

        &lt;span class=&quot;nt&quot;&gt;&amp;lt;transitions&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Initial transition: execute command on entry --&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;transition&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;happy=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;source&amp;gt;&lt;/span&gt;new&lt;span class=&quot;nt&quot;&gt;&amp;lt;/source&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;target&amp;gt;&lt;/span&gt;analysis done&lt;span class=&quot;nt&quot;&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;event&amp;gt;&lt;/span&gt;analyze agent&lt;span class=&quot;nt&quot;&gt;&amp;lt;/event&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;/transition&amp;gt;&lt;/span&gt;

            &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Happy path: condition passes --&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;transition&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;happy=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;true&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;condition=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;OryxAgent/Success&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;source&amp;gt;&lt;/span&gt;analysis done&lt;span class=&quot;nt&quot;&gt;&amp;lt;/source&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;target&amp;gt;&lt;/span&gt;analysis successful&lt;span class=&quot;nt&quot;&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;event&amp;gt;&lt;/span&gt;pass&lt;span class=&quot;nt&quot;&gt;&amp;lt;/event&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;/transition&amp;gt;&lt;/span&gt;

            &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Unhappy path: condition fails (no condition = default) --&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;transition&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;source&amp;gt;&lt;/span&gt;analysis done&lt;span class=&quot;nt&quot;&gt;&amp;lt;/source&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;target&amp;gt;&lt;/span&gt;analysis failed&lt;span class=&quot;nt&quot;&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;event&amp;gt;&lt;/span&gt;pass&lt;span class=&quot;nt&quot;&gt;&amp;lt;/event&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;/transition&amp;gt;&lt;/span&gt;

            &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Recovery: manual restart from failed state --&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;transition&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;source&amp;gt;&lt;/span&gt;analysis failed&lt;span class=&quot;nt&quot;&gt;&amp;lt;/source&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;target&amp;gt;&lt;/span&gt;new&lt;span class=&quot;nt&quot;&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;event&amp;gt;&lt;/span&gt;restart&lt;span class=&quot;nt&quot;&gt;&amp;lt;/event&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;/transition&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/transitions&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/process&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/statemachine&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/dg/dev/ai-foundation/intel-task-01.png&quot; alt=&quot;State machine diagram for the IntelligentTask01 workflow&quot; /&gt;&lt;/p&gt;
&lt;h3 id=&quot;create-command-plugins&quot;&gt;2. Create command plugins&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Command plugin example: Analyze data with Oryx Agent&lt;/strong&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;Generated\Shared\Transfer\AiWorkflowItemCollectionRequestTransfer&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\StateMachineItemTransfer&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\Kernel\Communication\AbstractPlugin&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\StateMachine\Dependency\Plugin\CommandPluginInterface&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;OryxAgentAnalyzeCommandPlugin&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AbstractPlugin&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CommandPluginInterface&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;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;StateMachineItemTransfer&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$stateMachineItemTransfer&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;nv&quot;&gt;$aiWorkflowItemTransfer&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;loadWorkflowItem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$stateMachineItemTransfer&lt;/span&gt;&lt;span class=&quot;p&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;executeAnalysis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$aiWorkflowItemTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$request&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;AiWorkflowItemCollectionRequestTransfer&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;setIsTransactional&lt;/span&gt;&lt;span class=&quot;p&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;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;addAiWorkflowItem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$aiWorkflowItemTransfer&lt;/span&gt;&lt;span class=&quot;p&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;getAiFoundationFacade&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;updateAiWorkflowItemCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$request&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;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loadWorkflowItem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;StateMachineItemTransfer&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$stateMachineItemTransfer&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;AiWorkflowItemTransfer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$idAiWorkflowItem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$stateMachineItemTransfer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getIdentifierOrFail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$aiWorkflowItemConditionsTransfer&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;AiWorkflowItemConditionsTransfer&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;addAiWorkflowItemId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$idAiWorkflowItem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$aiWorkflowItemCriteriaTransfer&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;AiWorkflowItemCriteriaTransfer&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;setAiWorkflowItemConditions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$aiWorkflowItemConditionsTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$aiWorkflowItemCollection&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;getAiFoundationFacade&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;getAiWorkflowItemCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$aiWorkflowItemCriteriaTransfer&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;$aiWorkflowItemCollection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getAiWorkflowItems&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;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;p&quot;&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;executeAnalysis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;AiWorkflowItemTransfer&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$aiWorkflowItemTransfer&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;nv&quot;&gt;$contextData&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$aiWorkflowItemTransfer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getContextData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$promptMessage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$contextData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;prompt&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;Please analyze this data.&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$promptRequestTransfer&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;nv&quot;&gt;$promptMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$promptResponseTransfer&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;getAiFoundationFacade&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;prompt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$promptRequestTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$contextData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;analysis_result&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;nv&quot;&gt;$promptResponseTransfer&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;nv&quot;&gt;$contextData&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;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$promptResponseTransfer&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;nv&quot;&gt;$contextData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;analyzed_at&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;nb&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$aiWorkflowItemTransfer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;setContextData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$contextData&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;create-condition-plugins&quot;&gt;3. Create condition plugins&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Condition plugin example: Check Oryx Agent success flag&lt;/strong&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\Communication\Plugin\StateMachine\Condition&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\StateMachineItemTransfer&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\Kernel\Communication\AbstractPlugin&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\StateMachine\Dependency\Plugin\ConditionPluginInterface&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;OryxAgentSuccessConditionPlugin&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AbstractPlugin&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ConditionPluginInterface&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;check&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;StateMachineItemTransfer&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$stateMachineItemTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Load workflow item&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$aiWorkflowItemTransfer&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;loadWorkflowItem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$stateMachineItemTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Read success flag set by command&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$contextData&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$aiWorkflowItemTransfer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getContextData&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;$contextData&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;p&quot;&gt;]&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;register-plugins-in-aifoundation-dependency-provider&quot;&gt;4. Register plugins in AiFoundation dependency provider&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\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\AiFoundation\Communication\Plugin\StateMachine\Command\OryxAgentAnalyzeCommandPlugin&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\AiFoundation\Communication\Plugin\StateMachine\Condition\OryxAgentSuccessConditionPlugin&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;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;getAiWorkflowCommandPlugins&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;s1&quot;&gt;&apos;OryxAgent/Analyze&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;OryxAgentAnalyzeCommandPlugin&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;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getAiWorkflowConditionPlugins&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;s1&quot;&gt;&apos;OryxAgent/Success&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;OryxAgentSuccessConditionPlugin&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;configure-active-processes&quot;&gt;5. Configure active processes&lt;/h3&gt;
&lt;p&gt;Create or update &lt;code&gt;src/Pyz/Zed/AiFoundation/AiFoundationConfig.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;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;Spryker\Zed\AiFoundation\AiFoundationConfig&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SprykerAiFoundationConfig&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;AiFoundationConfig&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SprykerAiFoundationConfig&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;getAiWorkflowActiveProcesses&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;s1&quot;&gt;&apos;IntelligentTask01&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;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;getAiWorkflowInitialStateMapForProcess&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;s1&quot;&gt;&apos;IntelligentTask01&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;new&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;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;enable-state-machine-handler&quot;&gt;6. Enable state machine handler&lt;/h3&gt;
&lt;p&gt;Update &lt;code&gt;src/Pyz/Zed/StateMachine/StateMachineDependencyProvider.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;Pyz\Zed\StateMachine\Communication\Plugin\StateMachine\AiWorkflowStateMachineHandlerPlugin&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;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getStateMachineHandlerPlugins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Container&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$container&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;AiWorkflowStateMachineHandlerPlugin&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;set-up-cron-jobs-to-process-state-machine-events&quot;&gt;7. Set up cron jobs to process state machine events&lt;/h3&gt;
&lt;p&gt;Update &lt;code&gt;config/Zed/cronjobs/jenkins.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;nv&quot;&gt;$jobs&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;name&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;check-ai-workflow-conditions&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;command&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;$PHP_BIN vendor/bin/console state-machine:check-condition AiWorkflow&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;schedule&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;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;s1&quot;&gt;&apos;enable&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;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$jobs&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;name&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;check-ai-workflow-timeouts&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;command&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;$PHP_BIN vendor/bin/console state-machine:check-timeout AiWorkflow&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;schedule&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;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;s1&quot;&gt;&apos;enable&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;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$jobs&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;name&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;clear-state-machine-locks&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;command&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;$PHP_BIN vendor/bin/console state-machine:clear-locks&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;schedule&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;0 6 * * *&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&apos;enable&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;p&quot;&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;trigger-a-workflow-with-state-machine&quot;&gt;8. Trigger a workflow with state machine&lt;/h3&gt;
&lt;p&gt;To start a workflow, create a workflow item with initial context data and trigger the state machine for it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Create a workflow item and trigger the state machine:&lt;/strong&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;Generated\Shared\Transfer\AiWorkflowItemCollectionRequestTransfer&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\AiWorkflowItemTransfer&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\StateMachineProcessTransfer&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\Shared\AiFoundation\AiFoundationConstants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// 1. Create a workflow item with initial context data&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$request&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;AiWorkflowItemCollectionRequestTransfer&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;setIsTransactional&lt;/span&gt;&lt;span class=&quot;p&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;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;addAiWorkflowItem&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;AiWorkflowItemTransfer&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;setContextData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&apos;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;Analyze this data.&apos;&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;s1&quot;&gt;&apos;initialized&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;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;createAiWorkflowItemCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$workflowItem&lt;/span&gt; &lt;span class=&quot;o&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;getAiWorkflowItems&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;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;c1&quot;&gt;// 2. Trigger the state machine for the newly created item&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$processTransfer&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;StateMachineProcessTransfer&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;setProcessName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;IntelligentTask01&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;setStateMachineName&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_WORKFLOW_STATE_MACHINE_NAME&lt;/span&gt;&lt;span class=&quot;p&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;stateMachineFacade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;triggerForNewStateMachineItem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$processTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$workflowItem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getIdAiWorkflowItem&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;&lt;strong&gt;Trigger a manual event:&lt;/strong&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;Generated\Shared\Transfer\StateMachineItemTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$stateMachineItemTransfer&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;StateMachineItemTransfer&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;setIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$workflowItem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getIdAiWorkflowItem&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;setStateMachineName&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_WORKFLOW_STATE_MACHINE_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;setProcessName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;IntelligentTask01&apos;&lt;/span&gt;&lt;span class=&quot;p&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;stateMachineFacade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;triggerEvent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;restart&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$stateMachineItemTransfer&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;multi-agent-orchestration-patterns&quot;&gt;Multi-agent orchestration patterns&lt;/h2&gt;
&lt;p&gt;There are many possible patterns for multi-agent orchestration. The following are a couple of examples implemented using the Spryker AiWorkflow state machine.&lt;/p&gt;
&lt;h3 id=&quot;multi-agent-routing-workflow&quot;&gt;Multi-agent routing workflow&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/dg/dev/ai-foundation/MultiAgentOrchestration01.png&quot; alt=&quot;Multi-agent routing workflow&quot; /&gt;&lt;/p&gt;
&lt;h3 id=&quot;multi-agent-supervision-workflow&quot;&gt;Multi-agent supervision workflow&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/dg/dev/ai-foundation/SupervisorLoop01.png&quot; alt=&quot;Multi-agent supervision workflow&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;navigation-configuration&quot;&gt;Navigation configuration&lt;/h2&gt;
&lt;p&gt;To enable navigation to the Workflows in the Zed admin panel, add navigation items to your &lt;code&gt;config/Zed/navigation.xml&lt;/code&gt; file.&lt;/p&gt;
&lt;h3 id=&quot;add-navigation-xml&quot;&gt;Add navigation XML&lt;/h3&gt;
&lt;p&gt;Update &lt;code&gt;config/Zed/navigation.xml&lt;/code&gt; to include the Workflows menu:&lt;/p&gt;
&lt;div class=&quot;language-xml 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;nt&quot;&gt;&amp;lt;config&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;ai-foundation&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;label&amp;gt;&lt;/span&gt;Intelligence&lt;span class=&quot;nt&quot;&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Intelligence&lt;span class=&quot;nt&quot;&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;icon&amp;gt;&lt;/span&gt;network_intel_node&lt;span class=&quot;nt&quot;&gt;&amp;lt;/icon&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;pages&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;ai-workflow&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;label&amp;gt;&lt;/span&gt;Workflows&lt;span class=&quot;nt&quot;&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Workflows&lt;span class=&quot;nt&quot;&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;bundle&amp;gt;&lt;/span&gt;ai-foundation&lt;span class=&quot;nt&quot;&gt;&amp;lt;/bundle&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;controller&amp;gt;&lt;/span&gt;ai-workflow&lt;span class=&quot;nt&quot;&gt;&amp;lt;/controller&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;action&amp;gt;&lt;/span&gt;index&lt;span class=&quot;nt&quot;&gt;&amp;lt;/action&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;/ai-workflow&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/pages&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/ai-foundation&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/config&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This navigation configuration:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Adds an &lt;strong&gt;Intelligence&lt;/strong&gt; menu item in the Zed admin panel&lt;/li&gt;
&lt;li&gt;Includes a &lt;strong&gt;Workflows&lt;/strong&gt; submenu to access the workflows monitoring interface&lt;/li&gt;
&lt;li&gt;Sets the icon and labels for improved user experience&lt;/li&gt;
&lt;li&gt;Defines URLs to route to the workflows overview and detail pages&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/dg/dev/ai-foundation/AiWorkflow.png&quot; alt=&quot;AiWorkflow details&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;monitoring&quot;&gt;Monitoring&lt;/h2&gt;
&lt;p&gt;You can monitor AI workflows in the Spryker Zed administration panel. The monitoring interface provides visibility into workflow execution, state transitions, and context data.&lt;/p&gt;
&lt;h3 id=&quot;view-workflow-details&quot;&gt;View workflow details&lt;/h3&gt;
&lt;p&gt;To view detailed information about a specific workflow item, click the &lt;strong&gt;View&lt;/strong&gt; button in the actions column. The detail page displays the following information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Current State&lt;/strong&gt;: Shows the workflow item ID, process name, and current state&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Context Data&lt;/strong&gt;: Displays the JSON context data that flows through the workflow, including input data and results from executed commands&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;State History&lt;/strong&gt;: A table showing all states the workflow item has passed through and the timestamps when each state was entered&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Manual Events&lt;/strong&gt;: If manual events are available for the current state, you can trigger them directly from the admin panel (useful for testing or recovery scenarios)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Process Graph&lt;/strong&gt;: A visual representation of the state machine process with the current state highlighted&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;trigger-manual-events&quot;&gt;Trigger manual events&lt;/h3&gt;
&lt;p&gt;If a workflow is waiting for a manual event or you need to change its course, you can trigger manual events from the workflow detail page. Manual events appear as buttons under the &lt;strong&gt;Manual Events&lt;/strong&gt; section. Only events that are valid for the current state are displayed.&lt;/p&gt;
&lt;h2 id=&quot;best-practices&quot;&gt;Best practices&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Keep context simple&lt;/strong&gt;: Store only the data that conditions need to evaluate the next step and that subsequent commands need to process&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use structured responses&lt;/strong&gt;: Convert AI responses to structured data before storing in context&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Name explicitly&lt;/strong&gt;: Use descriptive command and condition names matching the process name&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Document context schema&lt;/strong&gt;: Define what keys each command and condition expects in context data&lt;/li&gt;
&lt;/ul&gt;
</description>
            <pubDate>Wed, 22 Apr 2026 12:15:12 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/ai/ai-foundation/ai-foundation-workflow-state-machine.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/ai/ai-foundation/ai-foundation-workflow-state-machine.html</guid>
            
            
        </item>
        
    </channel>
</rss>
