API-Referenz - Technische Details
Diese Referenz richtet sich an Entwickler, die das Plugin erweitern oder in eigene Anwendungen integrieren möchten.
🔌 Plugin-Architektur
Übersicht
Das Plugin basiert auf der OpenAI Responses API (nicht mehr auf Assistants API) und speichert alle Agent-Konfigurationen lokal in Shopware.
┌─────────────────────────────────────────────────┐
│ Frontend/Backend │
│ (Chat-Komponenten) │
└─────────────────┬───────────────────────────────┘
│
┌─────────────────▼───────────────────────────────┐
│ OpenAIChatService │
│ (Hauptlogik für Konversationen) │
└─────────────────┬───────────────────────────────┘
│
┌─────────┴─────────┐
▼ ▼
┌────────────────┐ ┌────────────────────┐
│ Responses │ │ Function │
│ Service │ │ Calling Service │
│ (OpenAI API) │ │ (Tools) │
└────────────────┘ └────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ OpenAI Responses API │
│ (platform.openai.com) │
└─────────────────────────────────────────────────┘
📦 Datenbank-Struktur
Tabelle: fel_agents
Agent-Konfigurationen werden lokal gespeichert.
| Spalte | Typ | Beschreibung |
|---|---|---|
id | BINARY(16) | Primärschlüssel (UUID) |
technical_name | VARCHAR(255) | Technischer Name (eindeutig) |
display_name | VARCHAR(255) | Anzeigename |
description | LONGTEXT | Beschreibung |
model | VARCHAR(100) | OpenAI-Modell (z.B. gpt-4o-mini) |
response_format | VARCHAR(100) | auto, json_object, json_schema |
agent_config | JSON | Konfiguration (Temperature, etc.) |
instructions_system | LONGTEXT | System Instructions |
instructions_init | LONGTEXT | Init Instructions |
instructions_fallback | LONGTEXT | Fallback Instructions |
tool_config | JSON | Aktivierte Tools |
tool_resources | JSON | Vector Store IDs, File Bundles |
metadata | JSON | Zusätzliche Metadaten |
is_active | BOOLEAN | Aktiviert? |
is_default | BOOLEAN | Standard-Agent? |
sales_channel_id | BINARY(16) | Verkaufskanal (NULL = alle) |
created_at | DATETIME | Erstellungsdatum |
updated_at | DATETIME | Letzte Änderung |
Beispiel agent_config JSON:
{
"temperature": 0.7,
"top_p": 1.0,
"max_output_tokens": 500,
"reasoning_effort": "medium",
"verbosity": 1.0
}
Beispiel tool_config JSON:
{
"product_search": true,
"get_product_details": true,
"search_logs": true,
"get_order_status": false
}
Tabelle: fel_assistant_logs
Wissensdatenbank / FAQ-Einträge.
| Spalte | Typ | Beschreibung |
|---|---|---|
id | BINARY(16) | Primärschlüssel |
question | LONGTEXT | Frage |
answer | LONGTEXT | Antwort |
context | LONGTEXT | Zusätzlicher Kontext |
meta_info | JSON | Metadaten (Tags, etc.) |
sales_channel_id | BINARY(16) | Verkaufskanal |
created_at | DATETIME | Erstellungsdatum |
updated_at | DATETIME | Letzte Änderung |
Beispiel meta_info JSON:
{
"tags": ["versand", "lieferung"],
"source": "manual",
"agent_id": "abc123..."
}
Tabelle: fel_assistant_chat_message
Thread-Nachrichten (Konversationsverlauf).
| Spalte | Typ | Beschreibung |
|---|---|---|
id | BINARY(16) | Primärschlüssel |
thread_id | VARCHAR(255) | Thread-ID |
role | VARCHAR(50) | user, assistant, tool |
content | LONGTEXT | Nachrichteninhalt |
tool_calls | JSON | Tool-Aufrufe (falls vorhanden) |
tool_call_id | VARCHAR(255) | Tool Call ID |
name | VARCHAR(255) | Tool-Name (bei role=tool) |
token_usage | JSON | Token-Statistik |
agent_id | BINARY(16) | Referenz zu Agent |
sales_channel_id | BINARY(16) | Verkaufskanal |
created_at | DATETIME | Zeitstempel |
Beispiel tool_calls JSON:
[
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "product_search",
"arguments": "{\"query\":\"rote Jacke\",\"limit\":10}"
}
}
]
Beispiel token_usage JSON:
{
"input_tokens": 1500,
"output_tokens": 300,
"cached_tokens": 1200,
"reasoning_tokens": 0,
"total_tokens": 3000
}
Tabelle: fel_assistant_tags
Tag-Definitionen.
| Spalte | Typ | Beschreibung |
|---|---|---|
id | BINARY(16) | Primärschlüssel |
name | VARCHAR(255) | Tag-Name (z.B. "versand") |
description | TEXT | Beschreibung |
created_at | DATETIME | Erstellungsdatum |
Tabelle: fel_assistant_tag_usage
Verknüpfung zwischen Logs und Tags (Many-to-Many).
| Spalte | Typ | Beschreibung |
|---|---|---|
log_id | BINARY(16) | Referenz zu fel_assistant_logs |
tag_id | BINARY(16) | Referenz zu fel_assistant_tags |
🔧 Service-Klassen
OpenAIChatService
Namespace: FelOAIAssistantsManager\Service\OpenAI\OpenAIChatService
Hauptmethoden:
createThread(array $metadata = []): array
Erstellt einen neuen Thread (Konversation).
Parameter:
$metadata(optional): Zusätzliche Metadaten
Rückgabe:
[
'id' => 'thread_abc123',
'object' => 'thread',
'created_at' => 1640000000
]
sendMessage(string $threadId, string $content, ?string $agentId = null): array
Sendet eine Nachricht an einen Thread und erhält Antwort vom Agenten.
Parameter:
$threadId: Thread-ID$content: Nachrichteninhalt$agentId(optional): Agent-ID (falls NULL: Standard-Agent)
Rückgabe:
[
'role' => 'assistant',
'content' => 'Hallo! Wie kann ich helfen?',
'tool_calls' => [...],
'usage' => [
'input_tokens' => 1500,
'output_tokens' => 300,
'cached_tokens' => 1200
]
]
getAgent(string $agentId): ?AgentEntity
Lädt Agent-Konfiguration aus der Datenbank.
Parameter:
$agentId: Agent-ID
Rückgabe:
AgentEntityodernull
OpenAIResponsesService
Namespace: FelOAIAssistantsManager\Service\OpenAI\OpenAIResponsesService
Hauptmethoden:
createResponse(array $body): array
Sendet eine Anfrage an die OpenAI Responses API.
Parameter:
$body = [
'model' => 'gpt-4o-mini',
'messages' => [
['role' => 'user', 'content' => 'Hallo']
],
'temperature' => 0.7,
'tools' => [...]
];
Rückgabe:
[
'id' => 'resp_abc123',
'choices' => [
[
'message' => [
'role' => 'assistant',
'content' => 'Hallo! Wie kann ich helfen?'
],
'finish_reason' => 'stop'
]
],
'usage' => [
'prompt_tokens' => 1500,
'completion_tokens' => 300,
'total_tokens' => 1800
]
]
FunctionCallingService
Namespace: FelOAIAssistantsManager\Service\FunctionCalling\FunctionCallingService
Hauptmethoden:
executeFunction(string $functionName, array $arguments, Context $context): array
Führt eine Tool-Funktion aus.
Parameter:
$functionName: Name des Tools (z.B.product_search)$arguments: Argumente als Array$context: Shopware Context
Rückgabe:
[
'success' => true,
'data' => [...],
'error' => null
]
getToolDefinitions(array $enabledTools): array
Generiert Tool-Definitionen für OpenAI.
Parameter:
$enabledTools: Array mit aktivierten Tool-Namen
Rückgabe:
[
[
'type' => 'function',
'function' => [
'name' => 'product_search',
'description' => 'Sucht Produkte...',
'parameters' => [
'type' => 'object',
'properties' => [
'query' => [
'type' => 'string',
'description' => 'Suchbegriff'
],
'limit' => [
'type' => 'integer',
'description' => 'Max. Anzahl'
]
],
'required' => ['query']
]
]
]
]
🌐 REST API Endpoints
Agent-Management
POST /api/fel-oai/agent
Erstellt einen neuen Agenten.
Request Body:
{
"technicalName": "my_agent",
"displayName": "Mein Agent",
"model": "gpt-4o-mini",
"instructionsSystem": "Du bist ein hilfreicher Assistent",
"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}
Aktualisiert einen Agenten.
Request Body:
{
"displayName": "Neuer Name",
"agentConfig": {
"temperature": 0.5
}
}
DELETE /api/fel-oai/agent/{agentId}
Löscht einen Agenten.
Response:
{
"success": true
}
Chat-Interaktion
POST /api/fel-oai/chat/thread
Erstellt einen neuen Thread.
Request Body:
{
"metadata": {
"user_id": "user123",
"source": "storefront"
}
}
Response:
{
"threadId": "thread_abc123"
}
POST /api/fel-oai/chat/message
Sendet eine Nachricht.
Request Body:
{
"threadId": "thread_abc123",
"content": "Ich suche eine Jacke",
"agentId": "agent_xyz"
}
Response:
{
"role": "assistant",
"content": "Gerne helfe ich dir! Welche Farbe?",
"toolCalls": [],
"usage": {
"inputTokens": 1500,
"outputTokens": 120,
"cachedTokens": 800
}
}
Log-Management
GET /api/fel-oai/logs
Ruft Logs ab.
Query Parameters:
limit(optional): Max. Anzahl (default: 50)offset(optional): Offset für PaginationfromDate(optional): Ab Datum (ISO 8601)toDate(optional): Bis DatumagentId(optional): Filter nach Agenttags(optional): Filter nach Tags (Komma-getrennt)
Response:
{
"data": [
{
"id": "log123",
"question": "Wie lange dauert Versand?",
"answer": "2-3 Werktage",
"createdAt": "2025-12-29T10:30:00Z",
"tags": ["versand"]
}
],
"total": 150
}
POST /api/fel-oai/logs
Erstellt Log-Eintrag (FAQ).
Request Body:
{
"question": "Kann ich auf Rechnung zahlen?",
"answer": "Ja, ab 50€ Mindestbestellwert",
"context": "Zahlungsarten Rechnung",
"tags": ["zahlung", "rechnung"]
}
🔨 Events
Das Plugin dispatcht verschiedene Events, die Sie für eigene Erweiterungen nutzen können.
ResponseCreatedEvent
Wird ausgelöst: Nach jeder erfolgreichen OpenAI Response
Event-Klasse: FelOAIAssistantsManager\Event\ResponseCreatedEvent
Verfügbare Daten:
$event->getResponse(); // OpenAI Response
$event->getRequest(); // Original Request Body
$event->getAgentId(); // Agent-ID
$event->getThreadId(); // Thread-ID
Beispiel 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();
// Ihre Logik hier (z.B. Analytics, Logging)
}
}
ToolExecutedEvent
Wird ausgelöst: Nach jeder Tool-Ausführung
Event-Klasse: FelOAIAssistantsManager\Event\ToolExecutedEvent
Verfügbare Daten:
$event->getToolName(); // Name des Tools
$event->getArguments(); // Übergebene Argumente
$event->getResult(); // Tool-Ergebnis
$event->getExecutionTime(); // Ausführungszeit in ms
ThreadCreatedEvent
Wird ausgelöst: Beim Erstellen eines neuen Threads
Event-Klasse: FelOAIAssistantsManager\Event\ThreadCreatedEvent
Verfügbare Daten:
$event->getThreadId();
$event->getMetadata();
$event->getSalesChannelId();
🛠️ Eigene Tools hinzufügen
Sie können eigene Tools (Functions) hinzufügen.
Schritt 1: Tool-Definition
Erstellen Sie eine Klasse 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 'Beschreibung was das Tool macht';
}
public function getParameters(): array
{
return [
'type' => 'object',
'properties' => [
'param1' => [
'type' => 'string',
'description' => 'Erster Parameter'
],
'param2' => [
'type' => 'integer',
'description' => 'Zweiter Parameter'
]
],
'required' => ['param1']
];
}
public function execute(array $arguments, Context $context): array
{
$param1 = $arguments['param1'] ?? null;
$param2 = $arguments['param2'] ?? 10;
// Ihre Logik hier
$result = $this->doSomething($param1, $param2);
return [
'success' => true,
'data' => $result
];
}
private function doSomething(string $param1, int $param2): mixed
{
// Implementierung
return ['result' => 'something'];
}
}
Schritt 2: Tool registrieren
In src/Resources/config/services.xml:
<service id="FelOAIAssistantsManager\Service\FunctionCalling\Functions\MyCustomTool">
<tag name="fel_oai.function"/>
</service>
Schritt 3: Tool in Agent aktivieren
Das Tool steht nun in der Agent-Konfiguration zur Verfügung und kann aktiviert werden.
📊 Konfiguration (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>
Zugriff im Code:
$apiKey = $this->systemConfigService->get('FelOAIAssistantsManager.config.apiKey');
Logging Optionen
<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>
🔐 Sicherheit
API-Schlüssel Schutz
Der API-Schlüssel wird verschlüsselt in der Datenbank gespeichert:
- Typ:
password(nicht im Klartext) - Zugriff nur über Backend/API mit Admin-Rechten
Rate Limiting
Empfehlung: Implementieren Sie eigenes Rate Limiting für öffentliche 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
Für Frontend-Integrationen müssen Sie CORS konfigurieren:
# 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']);
}
}
📚 Weitere Ressourcen
OpenAI Dokumentation
- 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 Dokumentation
- 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 von v1.x zu v2.x
Wichtigste Änderungen
| v1.x (Assistants API) | v2.x (Responses API) |
|---|---|
| Assistants auf OpenAI gespeichert | Agents lokal in Shopware |
assistant_id | agent_id |
| OpenAI Threads | Lokale Thread-Verwaltung |
RunService | ResponsesService |
| Tools via Assistant API | Tools via Function Calling |
Migration durchführen
Daten sichern:
mysqldump shopware fel_assistant_* > backup.sqlPlugin aktualisieren:
composer require fel/oai-assistants-manager:^2.0
bin/console plugin:update FelOAIAssistantsManagerAgenten migrieren:
- Alte Assistants von OpenAI exportieren (manuell)
- Neue Agents in Shopware erstellen
- Instructions und Tools übertragen
API-Aufrufe anpassen:
// Alt (v1.x)
$assistant = $service->getAssistant($assistantId);
// Neu (v2.x)
$agent = $service->getAgent($agentId);
📞 Support für Entwickler
Technischer Support:
Dokumentation:
- Plugin-Docs: Dieses Dokument
- OpenAI-Docs: platform.openai.com/docs
- Shopware-Docs: developer.shopware.com
Nächste Schritte
Sie haben jetzt Zugriff auf alle technischen Details!
➡️ Glossar - Begriffe nachschlagen
➡️ Troubleshooting - Probleme lösen
➡️ Zurück zur Haupt-Dokumentation