<?php
namespace App\AI\SymfonyAiExtend\Processor; use Symfony\AI\Agent\Input; use Symfony\AI\Agent\InputProcessorInterface; class OpenAiRouterInputProcessor implements InputProcessorInterface { private ?\stdClass $lastReqObj = null; private ?\stdClass $lastRespObj = null; public function __construct( private readonly \App\AI\Contexts\ContextManager $contextManager, private readonly int $idTopic, private readonly string $userMessage = '', ) { } public function processInput(Input $input): void { if (!str_starts_with($input->getModel(), 'gpt-')) { return; } $requests = []; if ($this->idTopic) { $listObj = new \App\EntityList\AiChatRequestList(); $listObj->setColumns(['idTopic', 'request', 'response', 'idAddUser', 'addTime']); $listObj->setFilter('idTopic', '=', $this->idTopic); $listObj->setOrderBy('id', 'DESC'); $listObj->setLimit(1); $requests = $listObj->exportRecords(); } if ($requests) { $lastRequest = end($requests); $this->lastReqObj = json_decode($lastRequest['request']); $this->lastRespObj = json_decode($lastRequest['response']); } $schema = [ 'model' => null, 'instructions' => null, 'input' => null, 'tools' => null, 'tool_choice' => null, 'user' => null, 'metadata' => null, ]; $options = $input->getOptions(); $bodyStdObj = $this->generateRouterRequestBody($input->getModel(), $this->lastReqObj, $this->lastRespObj, $this->userMessage); $options = array_merge($schema, json_decode(json_encode($bodyStdObj), true)); $options = array_filter($options, fn($v) => $v !== null); $input->setOptions($options); } private function generateRouterRequestBody(string $model, ?\stdClass $prevReqObj, ?\stdClass $prevRespObj, string $searchTerm): \App\AI\Api\ChatGpt\Responses\Body { $bodyStdObj = new \App\AI\Api\ChatGpt\Responses\Body(); $bodyStdObj->model = $model; if (!$prevReqObj) { $inputObj = new \App\AI\Api\ChatGpt\Responses\Input(); $inputObj->type = "message"; $inputObj->role = "system"; $inputObj->content = $this->contextManager->generateSystemPrompt(); $bodyStdObj->addInput($inputObj); $inputObj = new \App\AI\Api\ChatGpt\Responses\Input(); $inputObj->type = "message"; $inputObj->role = "user"; $inputObj->content = $searchTerm; $bodyStdObj->addInput($inputObj); } if ($prevReqObj) { if (isset($prevReqObj->input)) { foreach ($prevReqObj->input as $inputObj) { $copyInputObj = new \App\AI\Api\ChatGpt\Responses\Input(); $copyInputObj->type = $inputObj->type ?? null; $copyInputObj->role = $inputObj->role ?? null; $copyInputObj->content = $inputObj->content ?? null; $copyInputObj->arguments = $inputObj->arguments ?? null; $copyInputObj->call_id = $inputObj->call_id ?? null; $copyInputObj->name = $inputObj->name ?? null; $copyInputObj->output = $inputObj->output ?? null; $bodyStdObj->addInput($copyInputObj); } } $inputObj = new \App\AI\Api\ChatGpt\Responses\Input(); $inputObj->type = "message"; $inputObj->role = "user"; $inputObj->content = $searchTerm; $bodyStdObj->addInput($inputObj); } $availableContexts = []; foreach ($this->contextManager->getContextsCfg() as $contextName => $context) { if (isset($context['functions']) && is_array($context['functions'])) { $functionNames = []; foreach ($context['functions'] as $function) { $functionNames[] = $function['name']; } $availableContexts[$contextName] = $functionNames; } } $descriptions = []; foreach ($this->contextManager->getContextsCfg() as $contextClass => $contextFunctions) { foreach ($contextFunctions['functions'] as $functionDef) { $descriptions[] = "`" . $functionDef['name'] . "`: " . $functionDef['description']; } } $funcObj = new \App\AI\Api\ChatGpt\Responses\ToolFunction( 'additional_available_contexts', "Additional available contexts. ".implode("; ", $descriptions), true ); $metricsObj = new \App\AI\Api\ChatGpt\Responses\Property(); $metricsObj->type = "array"; $itemsObj = new \App\AI\Api\ChatGpt\Responses\Items(); $itemsObj->type = "string"; $itemsObj->enum = []; foreach ($availableContexts as $contextName=>$contextFunctions) { foreach ($contextFunctions as $functionName) { $itemsObj->enum[] = $functionName; } } $metricsObj->items = $itemsObj; $metricsObj->description = "Available tools to add in the context."; $funcObj->parameters->addProperty("add_contexts", $metricsObj); $funcObj->parameters->required = ["add_contexts"]; $bodyStdObj->addTool($funcObj); $bodyStdObj->tool_choice = "required"; unset($bodyStdObj->metadata); return $bodyStdObj; } }