Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Symfony Ai Tool Agent Laravel Package

arnaud-delgerie/symfony-ai-tool-agent

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to Begin

  1. Install the Bundle

    composer require arnaud-delgerie/symfony-ai-tool-agent
    

    Register the bundle in config/bundles.php:

    return [
        // ...
        ArnaudDelgerie\AiToolAgentBundle\AiToolAgentBundle::class => ['all' => true],
    ];
    
  2. Configure API Credentials Add your API key (OpenAI, Mistral, or Anthropic) to .env:

    AI_TOOL_AGENT_API_KEY=your_api_key_here
    
  3. Create a Basic Tool Function Manager Implement ToolFunctionManagerInterface for a simple use case (e.g., text summarization):

    namespace App\ToolFunctionManager;
    
    use ArnaudDelgerie\AiToolAgent\DTO\ToolFunction;
    use ArnaudDelgerie\AiToolAgent\Util\ToolResponse;
    use ArnaudDelgerie\AiToolAgent\Interface\ToolFunctionManagerInterface;
    
    class SummarizerToolFunctionManager implements ToolFunctionManagerInterface {
        public static function getName(): string { return 'summarize'; }
    
        public function getToolFunction(array $context): ToolFunction {
            return (new ToolFunction())
                ->setName(self::getName())
                ->setDescription('Summarizes text content')
                ->addProperty('summary', (new ToolFunctionProperty())
                    ->setType(ToolFunctionPropertyTypeEnum::String)
                    ->setDescription('Concise summary of the input text'));
        }
    
        public function execute(array $args, array $context, array $responseContent): ToolResponse {
            // Custom logic (e.g., call an external API or process locally)
            $responseContent['summary'] = $args['summary'];
            return new ToolResponse($responseContent, "", true);
        }
    }
    
  4. First Use Case: Summarize Text Create a service to leverage the tool agent:

    namespace App\Service;
    
    use ArnaudDelgerie\AiToolAgent\Util\ToolAgentProvider;
    use ArnaudDelgerie\AiToolAgent\Util\Config\AgentConfig;
    use ArnaudDelgerie\AiToolAgent\Util\Config\ClientConfig;
    use ArnaudDelgerie\AiToolAgent\Enum\ClientEnum;
    
    class TextSummarizer {
        public function __construct(private ToolAgentProvider $toolAgentProvider) {}
    
        public function summarize(string $text): string {
            $clientConfig = new ClientConfig(ClientEnum::Mistral, $_ENV['AI_TOOL_AGENT_API_KEY'], 'mistral-small-latest', 0.1);
            $systemPrompt = "You are a text summarizer. Use the 'summarize' function to return a concise summary.";
            $agentConfig = new AgentConfig($systemPrompt, ['summarize'], []);
    
            $toolAgent = $this->toolAgentProvider->createToolAgent($clientConfig, $agentConfig);
            $response = $toolAgent->addUserMessage($text)->run();
    
            return $response->content['summarize']['summary'] ?? '';
        }
    }
    

Implementation Patterns

Core Workflows

  1. Tool Function Development

    • Pattern: Follow the Single Responsibility Principle for each ToolFunctionManager.
      • Example: Separate managers for TopicClassification, ContentModeration, and ImageAnalysis.
    • Context Injection: Pass dynamic data (e.g., availableTopics, userId) via the $context array to the getToolFunction() method.
      $context = ['userId' => $user->getId(), 'allowedActions' => ['edit', 'delete']];
      
  2. Agent Configuration

    • Pattern: Centralize system prompts in files (e.g., /prompts/summarizer.txt) and load them dynamically:
      $systemPrompt = file_get_contents($kernelProjectDir . '/prompts/summarizer.txt');
      $agentConfig = new AgentConfig($systemPrompt, ['summarize'], $context);
      
    • Reusability: Define a base AgentConfig class to inherit from for shared configurations (e.g., temperature, model).
  3. Console Integration

    • Pattern: Extend ConsoleToolAgent for interactive CLI tools:
      use ArnaudDelgerie\AiToolAgent\Util\ConsoleToolAgent;
      
      class DebugAgentCommand extends Command {
          protected function execute(InputInterface $input, OutputInterface $output): int {
              $consoleAgent = new ConsoleToolAgent($clientConfig, $agentConfig);
              $response = $consoleAgent->run();
              $output->writeln($response->content);
              return Command::SUCCESS;
          }
      }
      
  4. Dependency Injection

    • Pattern: Register ToolFunctionManager services as lazy services in services.yaml:
      services:
          App\ToolFunctionManager\SummarizerToolFunctionManager:
              tags: ['ai.tool_function_manager']
      
    • Autowiring: Use constructor injection for ToolAgentProvider and ClientConfig in services.
  5. Error Handling

    • Pattern: Wrap agent calls in try-catch blocks to handle API rate limits or invalid responses:
      try {
          $response = $toolAgent->run();
      } catch (ApiException $e) {
          $this->logger->error('AI API Error: ' . $e->getMessage());
          throw new RuntimeException('Failed to process request');
      }
      

Integration Tips

  1. Event-Driven Workflows

    • Trigger AI agents via Symfony events (e.g., post.publish):
      $dispatcher->addListener('post.publish', function (PostEvent $event) {
          $summarizer->summarize($event->getPost()->getContent());
      });
      
  2. Queue Background Jobs

    • Offload AI processing to queues (e.g., Symfony Messenger) to avoid blocking requests:
      $message = new SummarizeTextMessage($text);
      $bus->dispatch($message);
      
  3. Caching Responses

    • Cache tool agent responses (e.g., using Symfony Cache) to reduce API calls:
      $cacheKey = 'summary_' . md5($text);
      if (!$summary = $cache->get($cacheKey)) {
          $summary = $summarizer->summarize($text);
          $cache->set($cacheKey, $summary, '1 hour');
      }
      
  4. Testing

    • Mock ToolAgentProvider and ClientConfig in unit tests:
      $this->mockToolAgentProvider()
          ->expects($this->once())
          ->method('createToolAgent')
          ->willReturn($this->createMockToolAgent());
      

Gotchas and Tips

Pitfalls

  1. API Rate Limits

    • Issue: Third-party APIs (OpenAI/Mistral) throttle requests. Unhandled exceptions can crash your app.
    • Fix: Implement exponential backoff in retries:
      use Symfony\Component\HttpClient\RetryableHttpClient;
      
      $client = new RetryableHttpClient(
          new HttpClient(),
          ['max_retries' => 3, 'delay' => 1000]
      );
      
  2. Context Leakage

    • Issue: Accidentally exposing sensitive data (e.g., user IDs) in $context passed to the AI.
    • Fix: Sanitize context data before passing it:
      $safeContext = array_filter($context, fn($key) => !str_starts_with($key, 'secret_'), ARRAY_FILTER_USE_KEY);
      
  3. Tool Function Naming Collisions

    • Issue: Duplicate tool function names across managers cause conflicts.
    • Fix: Use namespaced function names (e.g., user.topic_classification):
      public static function getName(): string { return 'user.topic_classification'; }
      
  4. Prompt Design Flaws

    • Issue: Poorly designed system prompts lead to incorrect tool function usage.
    • Fix: Iteratively test prompts with edge cases and log misclassifications:
      if ($response->content['topic_classification']['topic'] === 'unknown') {
          $this->logger->warning('Misclassified content: ' . $text);
      }
      
  5. Alpha Software Risks

    • Issue: Breaking changes in the alpha bundle may require refactoring.
    • Fix: Monitor the CHANGELOG.md and wrap bundle calls in version checks:
      if (version_compare(\ArnaudDelgerie\AiToolAgentBundle\AiToolAgentBundle::VERSION, '1.0.0', '<')) {
          // Fallback logic for alpha versions
      }
      

Debugging Tips

  1. Log Agent Responses
    • Enable debug logging for tool agent interactions:
      # config/packages/monolog.yaml
      handlers:
          ai_tool_agent:
              type: stream
              path: "%kernel.logs_dir%/ai_tool_agent.log"
              level: debug
              channels:
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager