Zum Hauptinhalt springen

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.

SpalteTypBeschreibung
idBINARY(16)Primärschlüssel (UUID)
technical_nameVARCHAR(255)Technischer Name (eindeutig)
display_nameVARCHAR(255)Anzeigename
descriptionLONGTEXTBeschreibung
modelVARCHAR(100)OpenAI-Modell (z.B. gpt-4o-mini)
response_formatVARCHAR(100)auto, json_object, json_schema
agent_configJSONKonfiguration (Temperature, etc.)
instructions_systemLONGTEXTSystem Instructions
instructions_initLONGTEXTInit Instructions
instructions_fallbackLONGTEXTFallback Instructions
tool_configJSONAktivierte Tools
tool_resourcesJSONVector Store IDs, File Bundles
metadataJSONZusätzliche Metadaten
is_activeBOOLEANAktiviert?
is_defaultBOOLEANStandard-Agent?
sales_channel_idBINARY(16)Verkaufskanal (NULL = alle)
created_atDATETIMEErstellungsdatum
updated_atDATETIMELetzte Ä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.

SpalteTypBeschreibung
idBINARY(16)Primärschlüssel
questionLONGTEXTFrage
answerLONGTEXTAntwort
contextLONGTEXTZusätzlicher Kontext
meta_infoJSONMetadaten (Tags, etc.)
sales_channel_idBINARY(16)Verkaufskanal
created_atDATETIMEErstellungsdatum
updated_atDATETIMELetzte Änderung

Beispiel meta_info JSON:

{
"tags": ["versand", "lieferung"],
"source": "manual",
"agent_id": "abc123..."
}

Tabelle: fel_assistant_chat_message

Thread-Nachrichten (Konversationsverlauf).

SpalteTypBeschreibung
idBINARY(16)Primärschlüssel
thread_idVARCHAR(255)Thread-ID
roleVARCHAR(50)user, assistant, tool
contentLONGTEXTNachrichteninhalt
tool_callsJSONTool-Aufrufe (falls vorhanden)
tool_call_idVARCHAR(255)Tool Call ID
nameVARCHAR(255)Tool-Name (bei role=tool)
token_usageJSONToken-Statistik
agent_idBINARY(16)Referenz zu Agent
sales_channel_idBINARY(16)Verkaufskanal
created_atDATETIMEZeitstempel

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.

SpalteTypBeschreibung
idBINARY(16)Primärschlüssel
nameVARCHAR(255)Tag-Name (z.B. "versand")
descriptionTEXTBeschreibung
created_atDATETIMEErstellungsdatum

Tabelle: fel_assistant_tag_usage

Verknüpfung zwischen Logs und Tags (Many-to-Many).

SpalteTypBeschreibung
log_idBINARY(16)Referenz zu fel_assistant_logs
tag_idBINARY(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:

  • AgentEntity oder null

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 Pagination
  • fromDate (optional): Ab Datum (ISO 8601)
  • toDate (optional): Bis Datum
  • agentId (optional): Filter nach Agent
  • tags (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

Shopware Dokumentation


🔄 Migration von v1.x zu v2.x

Wichtigste Änderungen

v1.x (Assistants API)v2.x (Responses API)
Assistants auf OpenAI gespeichertAgents lokal in Shopware
assistant_idagent_id
OpenAI ThreadsLokale Thread-Verwaltung
RunServiceResponsesService
Tools via Assistant APITools via Function Calling

Migration durchführen

  1. Daten sichern:

    mysqldump shopware fel_assistant_* > backup.sql
  2. Plugin aktualisieren:

    composer require fel/oai-assistants-manager:^2.0
    bin/console plugin:update FelOAIAssistantsManager
  3. Agenten migrieren:

    • Alte Assistants von OpenAI exportieren (manuell)
    • Neue Agents in Shopware erstellen
    • Instructions und Tools übertragen
  4. API-Aufrufe anpassen:

    // Alt (v1.x)
    $assistant = $service->getAssistant($assistantId);

    // Neu (v2.x)
    $agent = $service->getAgent($agentId);

📞 Support für Entwickler

Technischer Support:

Dokumentation:


Nächste Schritte

Sie haben jetzt Zugriff auf alle technischen Details!

➡️ Glossar - Begriffe nachschlagen

➡️ Troubleshooting - Probleme lösen

➡️ Zurück zur Haupt-Dokumentation