API Reference - Technical Details
This reference is aimed at developers who want to extend the plugin or integrate it into their own applications.
๐ Plugin Architectureโ
Overviewโ
The plugin is based on the OpenAI Responses API (no longer on Assistants API) and stores all agent configurations locally in Shopware.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Frontend/Backend โ
โ (Chat Components) โ
โโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ OpenAIChatService โ
โ (Main Logic for Conversations) โ
โโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโดโโโโโโโโโโ
โผ โผ
โโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโ
โ Responses โ โ Function โ
โ Service โ โ Calling Service โ
โ (OpenAI API) โ โ (Tools) โ
โโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ OpenAI Responses API โ
โ (platform.openai.com) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ฆ Database Structureโ
Table: fel_agentsโ
Agent configurations are stored locally.
| Column | Type | Description |
|---|---|---|
id | BINARY(16) | Primary key (UUID) |
technical_name | VARCHAR(255) | Technical name (unique) |
display_name | VARCHAR(255) | Display name |
description | LONGTEXT | Description |
model | VARCHAR(100) | OpenAI model (e.g., gpt-4o-mini) |
response_format | VARCHAR(100) | auto, json_object, json_schema |
agent_config | JSON | Configuration (Temperature, etc.) |
instructions_system | LONGTEXT | System Instructions |
instructions_init | LONGTEXT | Init Instructions |
instructions_fallback | LONGTEXT | Fallback Instructions |
tool_config | JSON | Enabled tools |
tool_resources | JSON | Vector Store IDs, File Bundles |
metadata | JSON | Additional metadata |
is_active | BOOLEAN | Active? |
is_default | BOOLEAN | Default agent? |
sales_channel_id | BINARY(16) | Sales channel (NULL = all) |
created_at | DATETIME | Creation date |
updated_at | DATETIME | Last modified |
Example agent_config JSON:
{
"temperature": 0.7,
"top_p": 1.0,
"max_output_tokens": 500,
"reasoning_effort": "medium",
"verbosity": 1.0
}
Example tool_config JSON:
{
"product_search": true,
"get_product_details": true,
"search_logs": true,
"get_order_status": false
}
Table: fel_assistant_logsโ
Knowledge database / FAQ entries.
| Column | Type | Description |
|---|---|---|
id | BINARY(16) | Primary key |
question | LONGTEXT | Question |
answer | LONGTEXT | Answer |
context | LONGTEXT | Additional context |
meta_info | JSON | Metadata (tags, etc.) |
sales_channel_id | BINARY(16) | Sales channel |
created_at | DATETIME | Creation date |
updated_at | DATETIME | Last modified |
Example meta_info JSON:
{
"tags": ["shipping", "delivery"],
"source": "manual",
"agent_id": "abc123..."
}
Table: fel_assistant_chat_messageโ
Thread messages (conversation history).
| Column | Type | Description |
|---|---|---|
id | BINARY(16) | Primary key |
thread_id | VARCHAR(255) | Thread ID |
role | VARCHAR(50) | user, assistant, tool |
content | LONGTEXT | Message content |
tool_calls | JSON | Tool calls (if any) |
tool_call_id | VARCHAR(255) | Tool Call ID |
name | VARCHAR(255) | Tool name (for role=tool) |
token_usage | JSON | Token statistics |
agent_id | BINARY(16) | Reference to agent |
sales_channel_id | BINARY(16) | Sales channel |
created_at | DATETIME | Timestamp |
Example tool_calls JSON:
[
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "product_search",
"arguments": "{\"query\":\"red jacket\",\"limit\":10}"
}
}
]
Example token_usage JSON:
{
"input_tokens": 1500,
"output_tokens": 300,
"cached_tokens": 1200,
"reasoning_tokens": 0,
"total_tokens": 3000
}
Table: fel_assistant_tagsโ
Tag definitions.
| Column | Type | Description |
|---|---|---|
id | BINARY(16) | Primary key |
name | VARCHAR(255) | Tag name (e.g., "shipping") |
description | TEXT | Description |
created_at | DATETIME | Creation date |
Table: fel_assistant_tag_usageโ
Link between logs and tags (Many-to-Many).
| Column | Type | Description |
|---|---|---|
log_id | BINARY(16) | Reference to fel_assistant_logs |
tag_id | BINARY(16) | Reference to fel_assistant_tags |
๐ง Service Classesโ
OpenAIChatServiceโ
Namespace: FelOAIAssistantsManager\Service\OpenAI\OpenAIChatService
Main Methods:
createThread(array $metadata = []): arrayโ
Creates a new thread (conversation).
Parameters:
$metadata(optional): Additional metadata
Returns:
[
'id' => 'thread_abc123',
'object' => 'thread',
'created_at' => 1640000000
]
sendMessage(string $threadId, string $content, ?string $agentId = null): arrayโ
Sends a message to a thread and receives response from agent.
Parameters:
$threadId: Thread ID$content: Message content$agentId(optional): Agent ID (if NULL: default agent)
Returns:
[
'role' => 'assistant',
'content' => 'Hello! How can I help?',
'tool_calls' => [...],
'usage' => [
'input_tokens' => 1500,
'output_tokens' => 300,
'cached_tokens' => 1200
]
]
getAgent(string $agentId): ?AgentEntityโ
Loads agent configuration from database.
Parameters:
$agentId: Agent ID
Returns:
AgentEntityornull
OpenAIResponsesServiceโ
Namespace: FelOAIAssistantsManager\Service\OpenAI\OpenAIResponsesService
Main Methods:
createResponse(array $body): arrayโ
Sends a request to the OpenAI Responses API.
Parameters:
$body = [
'model' => 'gpt-4o-mini',
'messages' => [
['role' => 'user', 'content' => 'Hello']
],
'temperature' => 0.7,
'tools' => [...]
];
Returns:
[
'id' => 'resp_abc123',
'choices' => [
[
'message' => [
'role' => 'assistant',
'content' => 'Hello! How can I help?'
],
'finish_reason' => 'stop'
]
],
'usage' => [
'prompt_tokens' => 1500,
'completion_tokens' => 300,
'total_tokens' => 1800
]
]
FunctionCallingServiceโ
Namespace: FelOAIAssistantsManager\Service\FunctionCalling\FunctionCallingService
Main Methods:
executeFunction(string $functionName, array $arguments, Context $context): arrayโ
Executes a tool function.
Parameters:
$functionName: Tool name (e.g.,product_search)$arguments: Arguments as array$context: Shopware Context
Returns:
[
'success' => true,
'data' => [...],
'error' => null
]
getToolDefinitions(array $enabledTools): arrayโ
Generates tool definitions for OpenAI.
Parameters:
$enabledTools: Array with enabled tool names
Returns:
[
[
'type' => 'function',
'function' => [
'name' => 'product_search',
'description' => 'Searches for products...',
'parameters' => [
'type' => 'object',
'properties' => [
'query' => [
'type' => 'string',
'description' => 'Search term'
],
'limit' => [
'type' => 'integer',
'description' => 'Max. number'
]
],
'required' => ['query']
]
]
]
]
๐ REST API Endpointsโ
Agent Managementโ
POST /api/fel-oai/agentโ
Creates a new agent.
Request Body:
{
"technicalName": "my_agent",
"displayName": "My Agent",
"model": "gpt-4o-mini",
"instructionsSystem": "You are a helpful assistant",
"agentConfig": {
"temperature": 0.7,
"max_output_tokens": 500
},
"toolConfig": {
"product_search": true,
"search_logs": true
}
}
Response:
{
"success": true,
"data": {
"id": "abc123...",
"technicalName": "my_agent",
...
}
}
PATCH /api/fel-oai/agent/{agentId}โ
Updates an agent.
Request Body:
{
"displayName": "New Name",
"agentConfig": {
"temperature": 0.5
}
}
DELETE /api/fel-oai/agent/{agentId}โ
Deletes an agent.
Response:
{
"success": true
}
Chat Interactionโ
POST /api/fel-oai/chat/threadโ
Creates a new thread.
Request Body:
{
"metadata": {
"user_id": "user123",
"source": "storefront"
}
}
Response:
{
"threadId": "thread_abc123"
}
POST /api/fel-oai/chat/messageโ
Sends a message.
Request Body:
{
"threadId": "thread_abc123",
"content": "I'm looking for a jacket",
"agentId": "agent_xyz"
}
Response:
{
"role": "assistant",
"content": "I'd be happy to help! What color?",
"toolCalls": [],
"usage": {
"inputTokens": 1500,
"outputTokens": 120,
"cachedTokens": 800
}
}
Log Managementโ
GET /api/fel-oai/logsโ
Retrieves logs.
Query Parameters:
limit(optional): Max. number (default: 50)offset(optional): Offset for paginationfromDate(optional): From date (ISO 8601)toDate(optional): To dateagentId(optional): Filter by agenttags(optional): Filter by tags (comma-separated)
Response:
{
"data": [
{
"id": "log123",
"question": "How long does shipping take?",
"answer": "2-3 business days",
"createdAt": "2025-12-29T10:30:00Z",
"tags": ["shipping"]
}
],
"total": 150
}
POST /api/fel-oai/logsโ
Creates log entry (FAQ).
Request Body:
{
"question": "Can I pay by invoice?",
"answer": "Yes, from $50 minimum order value",
"context": "Payment methods invoice",
"tags": ["payment", "invoice"]
}
๐จ Eventsโ
The plugin dispatches various events that you can use for your own extensions.
ResponseCreatedEventโ
Triggered: After every successful OpenAI Response
Event Class: FelOAIAssistantsManager\Event\ResponseCreatedEvent
Available Data:
$event->getResponse(); // OpenAI Response
$event->getRequest(); // Original Request Body
$event->getAgentId(); // Agent ID
$event->getThreadId(); // Thread ID
Example Subscriber:
use FelOAIAssistantsManager\Event\ResponseCreatedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class MyCustomSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
ResponseCreatedEvent::NAME => 'onResponseCreated'
];
}
public function onResponseCreated(ResponseCreatedEvent $event): void
{
$response = $event->getResponse();
// Your logic here (e.g., Analytics, Logging)
}
}
ToolExecutedEventโ
Triggered: After every tool execution
Event Class: FelOAIAssistantsManager\Event\ToolExecutedEvent
Available Data:
$event->getToolName(); // Tool name
$event->getArguments(); // Passed arguments
$event->getResult(); // Tool result
$event->getExecutionTime(); // Execution time in ms
ThreadCreatedEventโ
Triggered: When creating a new thread
Event Class: FelOAIAssistantsManager\Event\ThreadCreatedEvent
Available Data:
$event->getThreadId();
$event->getMetadata();
$event->getSalesChannelId();
๐ ๏ธ Adding Custom Toolsโ
You can add your own tools (functions).
Step 1: Tool Definitionโ
Create a class in src/Service/FunctionCalling/Functions/:
namespace FelOAIAssistantsManager\Service\FunctionCalling\Functions;
use Shopware\Core\Framework\Context;
class MyCustomTool implements FunctionInterface
{
public function getName(): string
{
return 'my_custom_tool';
}
public function getDescription(): string
{
return 'Description of what the tool does';
}
public function getParameters(): array
{
return [
'type' => 'object',
'properties' => [
'param1' => [
'type' => 'string',
'description' => 'First parameter'
],
'param2' => [
'type' => 'integer',
'description' => 'Second parameter'
]
],
'required' => ['param1']
];
}
public function execute(array $arguments, Context $context): array
{
$param1 = $arguments['param1'] ?? null;
$param2 = $arguments['param2'] ?? 10;
// Your logic here
$result = $this->doSomething($param1, $param2);
return [
'success' => true,
'data' => $result
];
}
private function doSomething(string $param1, int $param2): mixed
{
// Implementation
return ['result' => 'something'];
}
}
Step 2: Register Toolโ
In src/Resources/config/services.xml:
<service id="FelOAIAssistantsManager\Service\FunctionCalling\Functions\MyCustomTool">
<tag name="fel_oai.function"/>
</service>
Step 3: Activate Tool in Agentโ
The tool is now available in the agent configuration and can be activated.
๐ Configuration (config.xml)โ
OpenAI API Keyโ
<input-field type="password">
<name>apiKey</name>
<label>OpenAI API Key</label>
<helpText>Your secret API key from platform.openai.com</helpText>
</input-field>
Access in Code:
$apiKey = $this->systemConfigService->get('FelOAIAssistantsManager.config.apiKey');
Logging Optionsโ
<input-field type="bool">
<name>enableThreadLogging</name>
<label>Enable Thread Logging</label>
<defaultValue>true</defaultValue>
</input-field>
<input-field type="bool">
<name>enableUsageCounter</name>
<label>Track Token Usage</label>
<defaultValue>true</defaultValue>
</input-field>
๐ Securityโ
API Key Protectionโ
The API key is stored encrypted in the database:
- Type:
password(not in plain text) - Access only via backend/API with admin rights
Rate Limitingโ
Recommendation: Implement your own rate limiting for public endpoints:
use Symfony\Component\RateLimiter\RateLimiterFactory;
class ChatController
{
public function __construct(
private RateLimiterFactory $chatLimiter
) {}
public function sendMessage(Request $request): JsonResponse
{
$limiter = $this->chatLimiter->create($request->getClientIp());
if (!$limiter->consume(1)->isAccepted()) {
throw new TooManyRequestsHttpException();
}
// Normal processing...
}
}
CORSโ
For frontend integrations you need to configure CORS:
# config/packages/nelmio_cors.yaml
nelmio_cors:
paths:
'^/api/fel-oai':
allow_origin: ['https://your-domain.com']
allow_methods: ['GET', 'POST', 'PATCH', 'DELETE']
allow_headers: ['Content-Type', 'Authorization']
๐งช Testingโ
Unit Testsโ
use PHPUnit\Framework\TestCase;
use FelOAIAssistantsManager\Service\OpenAI\OpenAIChatService;
class OpenAIChatServiceTest extends TestCase
{
public function testCreateThread(): void
{
$service = $this->createMock(OpenAIChatService::class);
$service->method('createThread')
->willReturn(['id' => 'thread_123']);
$result = $service->createThread();
$this->assertArrayHasKey('id', $result);
$this->assertStringStartsWith('thread_', $result['id']);
}
}
Integration Testsโ
use Shopware\Core\Test\TestDefaults;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
class ChatIntegrationTest extends KernelTestCase
{
public function testSendMessage(): void
{
$chatService = $this->getContainer()->get(OpenAIChatService::class);
$thread = $chatService->createThread();
$response = $chatService->sendMessage(
$thread['id'],
'Hello',
'agent_test_id'
);
$this->assertArrayHasKey('content', $response);
$this->assertNotEmpty($response['content']);
}
}
๐ Additional Resourcesโ
OpenAI Documentationโ
- Responses API: platform.openai.com/docs/api-reference/chat
- Function Calling: platform.openai.com/docs/guides/function-calling
- Models: platform.openai.com/docs/models
Shopware Documentationโ
- Plugin Development: developer.shopware.com/docs/guides/plugins
- Data Abstraction Layer: developer.shopware.com/docs/guides/plugins/plugins/framework/data-handling
- Store API: developer.shopware.com/docs/concepts/api/store-api
๐ Migration from v1.x to v2.xโ
Most Important Changesโ
| v1.x (Assistants API) | v2.x (Responses API) |
|---|---|
| Assistants stored on OpenAI | Agents locally in Shopware |
assistant_id | agent_id |
| OpenAI Threads | Local thread management |
RunService | ResponsesService |
| Tools via Assistant API | Tools via Function Calling |
Perform Migrationโ
Back up data:
mysqldump shopware fel_assistant_* > backup.sqlUpdate plugin:
composer require fel/oai-assistants-manager:^2.0
bin/console plugin:update FelOAIAssistantsManagerMigrate agents:
- Export old Assistants from OpenAI (manually)
- Create new Agents in Shopware
- Transfer instructions and tools
Adjust API calls:
// Old (v1.x)
$assistant = $service->getAssistant($assistantId);
// New (v2.x)
$agent = $service->getAgent($agentId);
๐ Support for Developersโ
Technical Support:
Documentation:
- Plugin Docs: This document
- OpenAI Docs: platform.openai.com/docs
- Shopware Docs: developer.shopware.com
Next Stepsโ
You now have access to all technical details!
โก๏ธ Glossary - Look up terms
โก๏ธ Troubleshooting - Solve problems
โก๏ธ Back to Main Documentation