Backup #367

ID367
Dateipfad/var/www/dev.campus.systemische-tools.de/src/UseCases/Task/ExecuteAITaskUseCase.php
Version1
Typ modified
Größe4.5 KB
Hash08024671574d2670c63d28b8838e5b71ed746b699c5a8c863955589f1d746952
Datum2025-12-22 08:24:37
Geändert vonclaude-code-hook
GrundClaude Code Pre-Hook Backup vor Edit-Operation
Datei existiert Ja

Dateiinhalt

<?php

namespace UseCases\Task;

use Domain\Entity\Task;
use Domain\Entity\TaskResult;
use Domain\ValueObject\AssigneeType;
use Domain\ValueObject\TaskStatus;
use Infrastructure\AI\AIClientInterface;
use Infrastructure\AI\AnthropicClient;
use Infrastructure\AI\OllamaClient;
use Infrastructure\Persistence\TaskRepository;

class ExecuteAITaskUseCase
{
    private TaskRepository $taskRepository;
    private SaveTaskResultUseCase $saveResultUseCase;
    private UpdateTaskStatusUseCase $updateStatusUseCase;

    public function __construct(
        ?TaskRepository $taskRepository = null,
        ?SaveTaskResultUseCase $saveResultUseCase = null,
        ?UpdateTaskStatusUseCase $updateStatusUseCase = null
    ) {
        $this->taskRepository = $taskRepository ?? new TaskRepository();
        $this->saveResultUseCase = $saveResultUseCase ?? new SaveTaskResultUseCase();
        $this->updateStatusUseCase = $updateStatusUseCase ?? new UpdateTaskStatusUseCase();
    }

    public function execute(int $taskId, array $options = []): TaskResult
    {
        $task = $this->taskRepository->find($taskId);
        if ($task === null) {
            throw new \InvalidArgumentException("Task {$taskId} not found");
        }

        $executorType = AssigneeType::from($options['executor_type'] ?? 'ollama');
        $client = $this->getClient($executorType, $options);

        if (!$client->isAvailable()) {
            throw new \RuntimeException("{$executorType->label()} is not available");
        }

        if ($task->getStatus() === TaskStatus::PENDING) {
            $this->updateStatusUseCase->startTask($taskId, $client->getClientName(), 'ai');
        }

        $prompt = $this->buildPrompt($task, $options);
        $response = $client->execute($prompt, $options);

        $resultData = [
            'executor' => $client->getClientName(),
            'executor_type' => $executorType->value,
            'model_name' => $response->getModel() !== '' ? $response->getModel() : $client->getModelName(),
            'request' => $prompt,
            'response' => $response->getContent(),
            'tokens_input' => $response->getTokensInput(),
            'tokens_output' => $response->getTokensOutput(),
            'duration_ms' => $response->getDurationMs(),
            'status' => $response->isSuccess() ? 'success' : 'error',
        ];

        if (!$response->isSuccess()) {
            $resultData['error_message'] = $response->getErrorMessage();
        }

        $metadata = $response->getMetadata();
        if (isset($metadata['cost_usd'])) {
            $resultData['cost_usd'] = $metadata['cost_usd'];
        }

        if (isset($options['assignment_id'])) {
            $resultData['assignment_id'] = $options['assignment_id'];
        }

        $result = $this->saveResultUseCase->execute($taskId, $resultData);

        if ($response->isSuccess() && ($options['auto_complete'] ?? false)) {
            $this->updateStatusUseCase->completeTask($taskId, $client->getClientName(), 'ai');
        }

        return $result;
    }

    private function getClient(AssigneeType $type, array $options): AIClientInterface
    {
        return match ($type) {
            AssigneeType::OLLAMA => new OllamaClient(
                'http://localhost:11434',
                $options['model'] ?? 'mistral'
            ),
            AssigneeType::ANTHROPIC_API => new AnthropicClient(
                $options['api_key'] ?? '',
                $options['model'] ?? 'claude-sonnet-4-20250514'
            ),
            default => throw new \InvalidArgumentException("Unsupported executor type: {$type->value}")
        };
    }

    private function buildPrompt(Task $task, array $options): string
    {
        $prompt = $task->getTitle();

        if ($task->getDescription() !== null) {
            $prompt .= "\n\n" . $task->getDescription();
        }

        if (isset($options['additional_context'])) {
            $prompt .= "\n\n" . $options['additional_context'];
        }

        return $prompt;
    }

    public function executeWithOllama(int $taskId, string $model = 'mistral', array $options = []): TaskResult
    {
        return $this->execute($taskId, array_merge($options, [
            'executor_type' => 'ollama',
            'model' => $model,
        ]));
    }

    public function executeWithAnthropic(int $taskId, string $model = 'claude-sonnet-4-20250514', array $options = []): TaskResult
    {
        return $this->execute($taskId, array_merge($options, [
            'executor_type' => 'anthropic_api',
            'model' => $model,
        ]));
    }
}

Vollständig herunterladen

Aktionen

Herunterladen

Andere Versionen dieser Datei

ID Version Typ Größe Datum
831 4 modified 4.7 KB 2025-12-23 08:15
712 3 modified 4.6 KB 2025-12-23 07:55
368 2 modified 4.6 KB 2025-12-22 08:24
367 1 modified 4.5 KB 2025-12-22 08:24

← Zurück zur Übersicht