# Table of Contents - [Vizra ADK - Vizra ADK](#vizra-adk-vizra-adk) - [Agent Queuing - Vizra ADK](#agent-queuing-vizra-adk) - [Specialized Agents - Vizra ADK](#specialized-agents-vizra-adk) - [Macros & Mixins - Vizra ADK](#macros-mixins-vizra-adk) - [Image Agent - Vizra ADK](#image-agent-vizra-adk) - [Audio Agent - Vizra ADK](#audio-agent-vizra-adk) - [Laravel Boost Integration - Vizra ADK](#laravel-boost-integration-vizra-adk) - [Requirements Checklist - Vizra ADK](#requirements-checklist-vizra-adk) - [Evaluation Class Reference - Vizra ADK](#evaluation-class-reference-vizra-adk) - [Error Handling - Vizra ADK](#error-handling-vizra-adk) - [Architecture - Vizra ADK](#architecture-vizra-adk) - [Configuration - Vizra ADK](#configuration-vizra-adk) - [Agent Class Reference - Vizra ADK](#agent-class-reference-vizra-adk) - [LLM Providers - Vizra ADK](#llm-providers-vizra-adk) - [Tracing Classes API Reference - Vizra ADK](#tracing-classes-api-reference-vizra-adk) - [Artisan Commands - Vizra ADK](#artisan-commands-vizra-adk) - [Events API Reference - Vizra ADK](#events-api-reference-vizra-adk) - [Workflow Class Reference - Vizra ADK](#workflow-class-reference-vizra-adk) - [MCP Integration - Vizra ADK](#mcp-integration-vizra-adk) - [Web Dashboard - Vizra ADK](#web-dashboard-vizra-adk) - [Getting Started - Vizra ADK](#getting-started-vizra-adk) - [Tracing - Vizra ADK](#tracing-vizra-adk) - [Dynamic Prompts - Vizra ADK](#dynamic-prompts-vizra-adk) - [OpenAI Compatibility - Vizra ADK](#openai-compatibility-vizra-adk) - [Sessions & Memory - Vizra ADK](#sessions-memory-vizra-adk) - [Tool Class Reference - Vizra ADK](#tool-class-reference-vizra-adk) - [Workflows - Vizra ADK](#workflows-vizra-adk) - [Vector Memory & RAG - Vizra ADK](#vector-memory-rag-vizra-adk) - [AI Agents - Vizra ADK](#ai-agents-vizra-adk) - [Tools - Vizra ADK](#tools-vizra-adk) - [Toolbox - Vizra ADK](#toolbox-vizra-adk) - [Structured Output - Vizra ADK](#structured-output-vizra-adk) - [Evaluations - Vizra ADK](#evaluations-vizra-adk) - [Tool Pipelines - Vizra ADK](#tool-pipelines-vizra-adk) --- # Vizra ADK - Vizra ADK [Skip to main content](https://docs.vizra.ai/#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... Ctrl K Search... Navigation Getting Started Vizra ADK [Documentation](https://docs.vizra.ai/) On this page * [Lightning Quick Start](https://docs.vizra.ai/#lightning-quick-start) * [What Makes Vizra ADK Special?](https://docs.vizra.ai/#what-makes-vizra-adk-special) * [Your Learning Adventure](https://docs.vizra.ai/#your-learning-adventure) * [See the Magic in Action](https://docs.vizra.ai/#see-the-magic-in-action) * [Join Our Community](https://docs.vizra.ai/#join-our-community) * [Ready to Build Something Amazing?](https://docs.vizra.ai/#ready-to-build-something-amazing) Welcome to the future of AI development! Build incredible intelligent agents with the most developer-friendly Laravel package on the planet. [​](https://docs.vizra.ai/#lightning-quick-start) Lightning Quick Start -------------------------------------------------------------------------- Get your first AI agent running with these simple commands: Terminal Copy # Install the package composer require vizra/vizra-adk # Set up everything with one command php artisan vizra:install # Create your first agent php artisan vizra:make:agent CustomerSupportAgent [​](https://docs.vizra.ai/#what-makes-vizra-adk-special) What Makes Vizra ADK Special? ----------------------------------------------------------------------------------------- Vizra ADK isn’t just another package - it’s your toolkit for creating intelligent, conversational agents that work in production. Multi-LLM Support ----------------- OpenAI, Anthropic, Google Gemini - use them all! Powerful Tool System -------------------- Give your agents superpowers with custom tools Smart Memory ------------ Vector memory & RAG for intelligent conversations Complex Workflows ----------------- Build multi-step processes that just work Quality Evaluations ------------------- LLM-as-a-Judge for automated testing Debug Tracing ------------- See exactly what your agents are thinking [​](https://docs.vizra.ai/#your-learning-adventure) Your Learning Adventure ------------------------------------------------------------------------------ Pick your path and let’s build something incredible together: [Installation & Setup\ --------------------\ \ Get up and running in minutes! Requirements, installation, and your first agent](https://docs.vizra.ai/installation/getting-started) [Core Concepts\ -------------\ \ Master agents, tools, sessions, and workflows - the building blocks of intelligence](https://docs.vizra.ai/concepts/architecture) [API Reference\ -------------\ \ Complete technical reference - every class, method, and command documented](https://docs.vizra.ai/api-reference/artisan-commands) [Error Handling\ --------------\ \ Handle exceptions gracefully and build resilient agents that recover from failures](https://docs.vizra.ai/api-reference/error-handling) [​](https://docs.vizra.ai/#see-the-magic-in-action) See the Magic in Action ------------------------------------------------------------------------------ Here’s a real agent that can look up orders and process refunds - all in just a few lines of code! app/Agents/CustomerSupportAgent.php Copy onQueue('agents') ->go(); // Returns immediately with job info // [\ // 'job_dispatched' => true,\ // 'job_id' => 'uuid-here',\ // 'queue' => 'agents',\ // 'agent' => 'my_agent'\ // ] ### [​](https://docs.vizra.ai/advanced/agent-queuing#media-agent-queuing) Media Agent Queuing Copy use Vizra\VizraADK\Agents\ImageAgent; // Queue image generation $result = ImageAgent::run('A futuristic cityscape') ->onQueue('media') ->then(fn($image) => $image->storeAs('cityscape.png')) ->go(); // [\ // 'job_dispatched' => true,\ // 'job_id' => 'uuid-here',\ // 'queue' => 'media',\ // 'agent' => 'image_agent',\ // 'prompt' => 'A futuristic cityscape'\ // ] When you specify a queue with `onQueue()`, async mode is automatically enabled - no need to call `async()` separately. [​](https://docs.vizra.ai/advanced/agent-queuing#llm-agent-queuing-2) LLM Agent Queuing ------------------------------------------------------------------------------------------ LLM agents can be queued using the fluent executor API. This is useful for tasks that may take a while to complete, such as complex analysis or multi-step reasoning. ### [​](https://docs.vizra.ai/advanced/agent-queuing#enabling-async-execution) Enabling Async Execution Copy // Method 1: Enable async mode explicitly MyAgent::ask('Process this...') ->async() ->go(); // Method 2: Specify a queue (auto-enables async) MyAgent::ask('Process this...') ->onQueue('agents') ->go(); ### [​](https://docs.vizra.ai/advanced/agent-queuing#queue-configuration-options) Queue Configuration Options | Method | Description | Default | | --- | --- | --- | | `async(bool $enabled = true)` | Enable/disable async execution | `false` | | `onQueue(string $queue)` | Specify queue name (auto-enables async) | `'default'` | | `delay(int $seconds)` | Delay job execution | `null` | | `tries(int $tries)` | Number of retry attempts | `3` | | `timeout(int $seconds)` | Job timeout in seconds | `300` (5 min) | ### [​](https://docs.vizra.ai/advanced/agent-queuing#complete-llm-agent-example) Complete LLM Agent Example Copy use App\Agents\AnalysisAgent; $result = AnalysisAgent::ask('Analyze the quarterly sales data and generate insights') ->forUser($user) // Associate with user ->withSession('analysis-session') // Track with session ID ->withContext([ // Add extra context\ 'report_type' => 'quarterly',\ 'department' => 'sales',\ ]) ->onQueue('analysis') // Use specific queue ->delay(30) // Wait 30 seconds before processing ->tries(5) // Retry up to 5 times ->timeout(600) // 10-minute timeout ->go(); // Store the job ID for tracking $jobId = $result['job_id']; [​](https://docs.vizra.ai/advanced/agent-queuing#media-agent-queuing-2) Media Agent Queuing ---------------------------------------------------------------------------------------------- Media agents (ImageAgent, AudioAgent) support the same queuing options plus additional features like post-generation callbacks and auto-storage. ### [​](https://docs.vizra.ai/advanced/agent-queuing#queue-configuration-options-2) Queue Configuration Options | Method | Description | Default | | --- | --- | --- | | `async(bool $enabled = true)` | Enable/disable async execution | `false` | | `onQueue(string $queue)` | Specify queue name (auto-enables async) | `'default'` | | `delay(int $seconds)` | Delay job execution | `null` | | `tries(int $tries)` | Number of retry attempts | `3` | | `timeout(int $seconds)` | Job timeout in seconds | `120` (2 min) | | `then(Closure $callback)` | Post-generation callback | `null` | | `store(?string $disk)` | Auto-store with generated filename | \- | | `storeAs(string $filename, ?string $disk)` | Auto-store with specific filename | \- | ### [​](https://docs.vizra.ai/advanced/agent-queuing#post-generation-callbacks) Post-Generation Callbacks Use the `then()` method to execute code after generation completes: Copy use Vizra\VizraADK\Agents\ImageAgent; ImageAgent::run('A product photo of a leather bag') ->onQueue('media') ->then(function ($image) { // Store the image $image->storeAs('products/leather-bag.png'); // Update database Product::find(123)->update([\ 'image_path' => $image->path(),\ ]); // Send notification Notification::send($user, new ImageReady($image)); }) ->go(); The `then()` callback must be serializable for queue processing. Avoid using `$this` or non-serializable objects inside the closure. ### [​](https://docs.vizra.ai/advanced/agent-queuing#auto-storage-options) Auto-Storage Options Configure automatic storage directly in the fluent chain: Copy // Store with auto-generated filename (ULID) ImageAgent::run('A landscape photo') ->onQueue('media') ->store() ->go(); // Store with specific filename ImageAgent::run('A portrait photo') ->onQueue('media') ->storeAs('portraits/user-avatar.png') ->go(); // Store to a specific disk ImageAgent::run('A banner image') ->onQueue('media') ->storeAs('banners/hero.png', 's3') ->go(); ### [​](https://docs.vizra.ai/advanced/agent-queuing#complete-media-agent-example) Complete Media Agent Example Copy use Vizra\VizraADK\Agents\ImageAgent; $result = ImageAgent::run('Professional headshot of a business executive') ->forUser($user) ->withSession('avatar-generation') ->using('openai', 'dall-e-3') ->size('1024x1024') ->quality('hd') ->style('natural') ->onQueue('media') ->delay(5) ->tries(3) ->timeout(180) ->then(function ($image) use ($user) { $image->storeAs("avatars/{$user->id}.png"); $user->update(['avatar_path' => $image->path()]); }) ->go(); [​](https://docs.vizra.ai/advanced/agent-queuing#job-response-&-tracking) Job Response & Tracking ---------------------------------------------------------------------------------------------------- When you dispatch an agent to a queue, you receive an immediate response with job information: ### [​](https://docs.vizra.ai/advanced/agent-queuing#llm-agent-response) LLM Agent Response Copy $result = MyAgent::ask('...')->onQueue('agents')->go(); // Returns: [\ 'job_dispatched' => true,\ 'job_id' => '550e8400-e29b-41d4-a716-446655440000',\ 'queue' => 'agents',\ 'agent' => 'my_agent'\ ] ### [​](https://docs.vizra.ai/advanced/agent-queuing#media-agent-response) Media Agent Response Copy $result = ImageAgent::run('...')->onQueue('media')->go(); // Returns: [\ 'job_dispatched' => true,\ 'job_id' => '550e8400-e29b-41d4-a716-446655440000',\ 'queue' => 'media',\ 'agent' => 'image_agent',\ 'prompt' => 'The original prompt...'\ ] ### [​](https://docs.vizra.ai/advanced/agent-queuing#retrieving-results-from-cache) Retrieving Results from Cache Job results are automatically cached for retrieval: Copy // LLM Agent results (cached for 1 hour) $result = cache()->get("agent_job_result:{$jobId}"); $meta = cache()->get("agent_job_meta:{$jobId}"); // Media Agent results (cached for 1 hour) $mediaResult = cache()->get("media_job_result:{$jobId}"); // Check for failures (cached for 24 hours) $failure = cache()->get("agent_job_failure:{$jobId}"); $mediaFailure = cache()->get("media_job_failure:{$jobId}"); ### [​](https://docs.vizra.ai/advanced/agent-queuing#cache-key-reference) Cache Key Reference | Cache Key | TTL | Description | | --- | --- | --- | | `agent_job_result:{jobId}` | 1 hour | LLM agent execution result | | `agent_job_meta:{jobId}` | 1 hour | LLM agent job metadata | | `media_job_result:{jobId}` | 1 hour | Media generation result with URLs/paths | | `agent_job_failure:{jobId}` | 24 hours | LLM agent failure info | | `media_job_failure:{jobId}` | 24 hours | Media generation failure info | [​](https://docs.vizra.ai/advanced/agent-queuing#events) Events ------------------------------------------------------------------ The queuing system dispatches events on job completion and failure, allowing you to react to agent execution status. ### [​](https://docs.vizra.ai/advanced/agent-queuing#llm-agent-events) LLM Agent Events | Event | Description | | --- | --- | | `agent.job.completed` | Fired when any agent job completes successfully | | `agent.{name}.completed` | Agent-specific completion event (e.g., `agent.my_agent.completed`) | | `agent.job.failed` | Fired when any agent job permanently fails | ### [​](https://docs.vizra.ai/advanced/agent-queuing#media-agent-events) Media Agent Events | Event | Description | | --- | --- | | `media.job.completed` | Fired when any media job completes successfully | | `media.{name}.completed` | Agent-specific completion event (e.g., `media.image_agent.completed`) | | `media.job.failed` | Fired when any media job permanently fails | ### [​](https://docs.vizra.ai/advanced/agent-queuing#event-listener-examples) Event Listener Examples Copy use Illuminate\Support\Facades\Event; // Listen for all agent job completions Event::listen('agent.job.completed', function (array $data) { Log::info('Agent job completed', [\ 'job_id' => $data['job_id'],\ 'agent_class' => $data['agent_class'],\ 'result' => $data['result'],\ ]); }); // Listen for a specific agent Event::listen('agent.analysis_agent.completed', function (array $data) { $result = $data['result']; $sessionId = $data['session_id']; // Process the analysis result ProcessAnalysisResult::dispatch($result, $sessionId); }); // Listen for media generation completion Event::listen('media.image_agent.completed', function (array $data) { $response = $data['response']; $jobId = $data['job_id']; Log::info("Image generated: " . $response->url()); }); // Handle failures Event::listen('agent.job.failed', function (array $data) { Log::error('Agent job failed', [\ 'job_id' => $data['job_id'],\ 'agent_class' => $data['agent_class'],\ 'error' => $data['error'],\ ]); // Notify admin or trigger alerting Notification::route('slack', config('services.slack.webhook')) ->notify(new AgentJobFailed($data)); }); Event payloads include the `job_id`, `agent_class`, `session_id`, and the full `result` or `response` object. Use these to update your database, send notifications, or trigger follow-up actions. [​](https://docs.vizra.ai/advanced/agent-queuing#job-tagging) Job Tagging ---------------------------------------------------------------------------- Jobs are automatically tagged for easy filtering and monitoring with tools like Laravel Horizon. ### [​](https://docs.vizra.ai/advanced/agent-queuing#llm-agent-tags) LLM Agent Tags Copy // Tags applied to AgentJob [\ 'vizra:{agent_name}', // e.g., 'vizra:my_agent'\ 'session:{session_id}' // e.g., 'session:user_123_abc'\ ] ### [​](https://docs.vizra.ai/advanced/agent-queuing#media-agent-tags) Media Agent Tags Copy // Tags applied to MediaGenerationJob [\ 'vizra:media',\ 'vizra:{agent_name}', // e.g., 'vizra:image_agent'\ 'session:{session_id}'\ ] ### [​](https://docs.vizra.ai/advanced/agent-queuing#viewing-tags-in-horizon) Viewing Tags in Horizon If you’re using Laravel Horizon, you can filter jobs by these tags: Copy // In your Horizon config, jobs will appear with tags like: // vizra:my_agent, session:user_123_abc // Search for all jobs from a specific agent // Filter: vizra:analysis_agent // Search for all media generation jobs // Filter: vizra:media [​](https://docs.vizra.ai/advanced/agent-queuing#configuration-&-prerequisites) Configuration & Prerequisites ---------------------------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/advanced/agent-queuing#queue-driver-configuration) Queue Driver Configuration Agent queuing uses Laravel’s standard queue system. Configure your preferred driver in `.env`: Copy QUEUE_CONNECTION=redis Supported drivers include `redis`, `database`, `sqs`, `beanstalkd`, and others. ### [​](https://docs.vizra.ai/advanced/agent-queuing#running-queue-workers) Running Queue Workers Process queued jobs with Laravel’s queue worker: Copy # Process all queues php artisan queue:work # Process specific queue php artisan queue:work --queue=agents # Process multiple queues with priority php artisan queue:work --queue=agents,media,default # With Horizon (recommended for production) php artisan horizon ### [​](https://docs.vizra.ai/advanced/agent-queuing#supervisor-configuration) Supervisor Configuration For production, use Supervisor to keep queue workers running: Copy [program:agent-worker] process_name=%(program_name)s_%(process_num)02d command=php /path/to/artisan queue:work --queue=agents,media --sleep=3 --tries=3 --max-time=3600 autostart=true autorestart=true stopasgroup=true killasgroup=true numprocs=4 redirect_stderr=true stdout_logfile=/path/to/logs/agent-worker.log ### [​](https://docs.vizra.ai/advanced/agent-queuing#horizon-configuration) Horizon Configuration For advanced monitoring and management, use Laravel Horizon: config/horizon.php Copy 'environments' => [\ 'production' => [\ 'agent-workers' => [\ 'connection' => 'redis',\ 'queue' => ['agents', 'media'],\ 'balance' => 'auto',\ 'processes' => 4,\ 'tries' => 3,\ 'timeout' => 600,\ ],\ ],\ ], [​](https://docs.vizra.ai/advanced/agent-queuing#best-practices) Best Practices ---------------------------------------------------------------------------------- Use Dedicated Queues -------------------- Separate agent and media jobs from other application jobs using dedicated queues Set Appropriate Timeouts ------------------------ LLM tasks may need longer timeouts (5-10 min), while media generation is typically faster (2 min) Monitor with Horizon -------------------- Use Laravel Horizon for real-time monitoring, metrics, and job management Handle Failures --------------- Always listen for failure events and implement appropriate error handling ### [​](https://docs.vizra.ai/advanced/agent-queuing#recommended-queue-structure) Recommended Queue Structure Copy // Separate queues by workload type ->onQueue('agents') // For LLM agents ->onQueue('media') // For image/audio generation ->onQueue('analysis') // For long-running analysis tasks ### [​](https://docs.vizra.ai/advanced/agent-queuing#timeout-guidelines) Timeout Guidelines | Task Type | Recommended Timeout | | --- | --- | | Simple LLM queries | 60-120 seconds | | Complex reasoning/analysis | 300-600 seconds | | Image generation | 120 seconds | | Audio generation | 180 seconds | | Multi-step workflows | 600+ seconds | [​](https://docs.vizra.ai/advanced/agent-queuing#complete-examples) Complete Examples ---------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/advanced/agent-queuing#background-report-generation) Background Report Generation Copy use App\Agents\ReportAgent; use App\Models\Report; class ReportController extends Controller { public function generate(Request $request) { $report = Report::create([\ 'user_id' => $request->user()->id,\ 'status' => 'processing',\ 'type' => $request->input('type'),\ ]); $result = ReportAgent::ask("Generate a {$request->input('type')} report") ->forUser($request->user()) ->withSession("report-{$report->id}") ->withContext([\ 'report_id' => $report->id,\ 'date_range' => $request->input('date_range'),\ ]) ->onQueue('reports') ->timeout(600) ->go(); $report->update(['job_id' => $result['job_id']]); return response()->json([\ 'message' => 'Report generation started',\ 'report_id' => $report->id,\ 'job_id' => $result['job_id'],\ ]); } } // Event listener for completion Event::listen('agent.report_agent.completed', function ($data) { $sessionId = $data['session_id']; // 'report-123' $reportId = str_replace('report-', '', $sessionId); Report::find($reportId)->update([\ 'status' => 'completed',\ 'content' => $data['result'],\ ]); }); ### [​](https://docs.vizra.ai/advanced/agent-queuing#batch-image-generation) Batch Image Generation Copy use Vizra\VizraADK\Agents\ImageAgent; class ProductImageController extends Controller { public function generateBatch(Request $request) { $products = Product::whereNull('image_path')->get(); $jobs = []; foreach ($products as $product) { $result = ImageAgent::run("Product photo of: {$product->name}") ->forUser($request->user()) ->withSession("product-{$product->id}") ->using('openai', 'dall-e-3') ->square() ->hd() ->style('natural') ->onQueue('media') ->then(function ($image) use ($product) { $path = "products/{$product->id}.png"; $image->storeAs($path); $product->update(['image_path' => $path]); }) ->go(); $jobs[] = [\ 'product_id' => $product->id,\ 'job_id' => $result['job_id'],\ ]; } return response()->json([\ 'message' => count($jobs) . ' image generation jobs queued',\ 'jobs' => $jobs,\ ]); } } [Image Agent\ -----------\ \ Learn about ImageAgent and its queuing features](https://docs.vizra.ai/agents/image-agent) [Audio Agent\ -----------\ \ Learn about AudioAgent and speech generation](https://docs.vizra.ai/agents/audio-agent) Was this page helpful? YesNo [Dynamic Prompts](https://docs.vizra.ai/concepts/dynamic-prompts) [Macros & Mixins](https://docs.vizra.ai/advanced/macros) ⌘I --- # Specialized Agents - Vizra ADK [Skip to main content](https://docs.vizra.ai/agents/overview#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Agents Specialized Agents [Documentation](https://docs.vizra.ai/) Coming soon… Was this page helpful? YesNo [Sessions & Memory](https://docs.vizra.ai/concepts/sessions-memory) [Audio Agent](https://docs.vizra.ai/agents/audio-agent) ⌘I --- # Macros & Mixins - Vizra ADK [Skip to main content](https://docs.vizra.ai/advanced/macros#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Advanced Features Macros & Mixins [Documentation](https://docs.vizra.ai/) On this page * [What are Macros?](https://docs.vizra.ai/advanced/macros#what-are-macros) * [Supported Classes](https://docs.vizra.ai/advanced/macros#supported-classes) * [Basic Usage](https://docs.vizra.ai/advanced/macros#basic-usage) * [Registering a Macro](https://docs.vizra.ai/advanced/macros#registering-a-macro) * [Using Your Macro](https://docs.vizra.ai/advanced/macros#using-your-macro) * [Real-World Examples](https://docs.vizra.ai/advanced/macros#real-world-examples) * [Analytics Tracking](https://docs.vizra.ai/advanced/macros#analytics-tracking) * [Conditional Execution](https://docs.vizra.ai/advanced/macros#conditional-execution) * [Metadata Tagging](https://docs.vizra.ai/advanced/macros#metadata-tagging) * [Cost Tracking](https://docs.vizra.ai/advanced/macros#cost-tracking) * [Using Mixins](https://docs.vizra.ai/advanced/macros#using-mixins) * [Advanced Patterns](https://docs.vizra.ai/advanced/macros#advanced-patterns) * [Integration with Events](https://docs.vizra.ai/advanced/macros#integration-with-events) * [Dynamic Configuration](https://docs.vizra.ai/advanced/macros#dynamic-configuration) * [Workflow Macros](https://docs.vizra.ai/advanced/macros#workflow-macros) * [Best Practices](https://docs.vizra.ai/advanced/macros#best-practices) * [Testing Macros](https://docs.vizra.ai/advanced/macros#testing-macros) * [Learn More](https://docs.vizra.ai/advanced/macros#learn-more) [​](https://docs.vizra.ai/advanced/macros#what-are-macros) What are Macros? ------------------------------------------------------------------------------ Macros allow you to add custom methods to classes at runtime. This is a powerful extensibility pattern borrowed from Laravel that lets you extend Vizra ADK’s functionality without modifying the core code. Custom Tracking --------------- Add analytics and tracking to your agents Third-party Integrations ------------------------ Integrate with external services seamlessly Domain Logic ------------ Add business-specific functionality Reusable Patterns ----------------- Create patterns you can use across your app [​](https://docs.vizra.ai/advanced/macros#supported-classes) Supported Classes --------------------------------------------------------------------------------- The following Vizra ADK classes support macros: | Class | Access | Description | | --- | --- | --- | | `AgentManager` | `Agent` facade | Central agent management | | `AgentBuilder` | Fluent builder | Agent configuration and registration | | `WorkflowManager` | `Workflow` facade | Workflow orchestration | [​](https://docs.vizra.ai/advanced/macros#basic-usage) Basic Usage --------------------------------------------------------------------- ### [​](https://docs.vizra.ai/advanced/macros#registering-a-macro) Registering a Macro Register macros in your `AppServiceProvider::boot()` method: app/Providers/AppServiceProvider.php Copy trackedModel = $model; return $this; // Return $this for method chaining }); } } ### [​](https://docs.vizra.ai/advanced/macros#using-your-macro) Using Your Macro Copy use App\Models\Unit; use Vizra\VizraADK\Facades\Agent; // Step 1: Use the macro when registering the agent Agent::build(CustomerSupportAgent::class) ->track(Unit::find(12)) ->register(); // Step 2: Run the agent using the executor API $response = CustomerSupportAgent::run('User input') ->forUser($user) ->go(); **Always return `$this`** from your macros to maintain the fluent interface and enable method chaining. [​](https://docs.vizra.ai/advanced/macros#real-world-examples) Real-World Examples ------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/advanced/macros#analytics-tracking) Analytics Tracking Track which models are using AI features: Copy use Vizra\VizraADK\Services\AgentBuilder; use Illuminate\Database\Eloquent\Model; AgentBuilder::macro('track', function (Model $model) { $this->trackedModel = $model; $this->trackedModelType = get_class($model); $this->trackedModelId = $model->getKey(); return $this; }); // Usage Agent::build(MyAgent::class) ->track(Unit::find(12)) ->register(); // Then run the agent MyAgent::run('User input') ->forUser($user) ->go(); ### [​](https://docs.vizra.ai/advanced/macros#conditional-execution) Conditional Execution Add conditional logic to your builder: Copy AgentBuilder::macro('whenCondition', function ($condition, callable $callback) { if ($condition) { $callback($this); } return $this; }); // Usage $agentName = Agent::define('conditional-agent') ->whenCondition($user->isPremium(), function ($builder) { $builder->model('gpt-4o'); }) ->whenCondition(!$user->isPremium(), function ($builder) { $builder->model('gpt-4o-mini'); }) ->register(); // Run the defined agent Agent::named($agentName)->run('User input')->go(); ### [​](https://docs.vizra.ai/advanced/macros#metadata-tagging) Metadata Tagging Add metadata for logging or debugging: Copy AgentBuilder::macro('withTags', function (array $tags) { $this->tags = $tags; return $this; }); AgentBuilder::macro('withPriority', function (string $priority) { $this->priority = $priority; return $this; }); // Usage $agentName = Agent::define('support-agent') ->withTags(['customer-facing', 'urgent']) ->withPriority('high') ->register(); // Run the agent Agent::named($agentName)->run('User input')->go(); ### [​](https://docs.vizra.ai/advanced/macros#cost-tracking) Cost Tracking Track estimated costs for budget monitoring: Copy AgentBuilder::macro('trackCost', function (string $costCenter) { $this->costCenter = $costCenter; $this->trackTokenUsage = true; return $this; }); // Usage Agent::build(AnalyticsAgent::class) ->trackCost('DEPT-001') ->register(); // Run the agent AnalyticsAgent::run('User input')->go(); [​](https://docs.vizra.ai/advanced/macros#using-mixins) Using Mixins ----------------------------------------------------------------------- Mixins allow you to add multiple macros at once by grouping related functionality in a class: app/Mixins/AnalyticsMixin.php Copy trackedModel = $model; return $this; }; } public function recordActivity() { return function ($activity) { $this->activityLog[] = $activity; return $this; }; } public function getActivityLog() { return function () { return $this->activityLog ?? []; }; } } Register the mixin in your service provider: app/Providers/AppServiceProvider.php Copy use Vizra\VizraADK\Services\AgentBuilder; use App\Mixins\AnalyticsMixin; public function boot(): void { AgentBuilder::mixin(new AnalyticsMixin()); } Now use all the mixed-in methods: Copy $agentName = Agent::define('analytics-agent') ->track($unit) ->recordActivity('agent_created') ->recordActivity('agent_configured') ->register(); // Run the agent Agent::named($agentName)->run('User input')->go(); Mixins are ideal when you have a group of related macros that logically belong together, such as analytics, auditing, or domain-specific operations. [​](https://docs.vizra.ai/advanced/macros#advanced-patterns) Advanced Patterns --------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/advanced/macros#integration-with-events) Integration with Events Combine macros with Laravel events for powerful side effects: Copy use App\Events\AgentTracked; AgentBuilder::macro('trackWithEvent', function (Model $model) { $this->trackedModel = $model; // Fire an event when the agent is used event(new AgentTracked($model, $this)); return $this; }); ### [​](https://docs.vizra.ai/advanced/macros#dynamic-configuration) Dynamic Configuration Load configuration dynamically from your models: Copy AgentBuilder::macro('configureFor', function (Model $model) { // Load model-specific configuration $config = $model->agentConfiguration ?? []; if (isset($config['model'])) { $this->model($config['model']); } if (isset($config['instructions'])) { $this->instructions($config['instructions']); } return $this; }); // Usage Agent::build(MyAgent::class) ->configureFor($tenant) ->register(); // Run the agent MyAgent::run('User input')->go(); ### [​](https://docs.vizra.ai/advanced/macros#workflow-macros) Workflow Macros Add custom workflow types using the `WorkflowManager`: Copy use Vizra\VizraADK\Facades\Workflow; use Vizra\VizraADK\Services\WorkflowManager; WorkflowManager::macro('retryable', function (string $agentClass, int $maxRetries = 3) { $retries = $maxRetries; return Workflow::loop($agentClass) ->until(function ($result) use (&$retries) { return $result->success || $retries-- <= 0; }); }); // Usage $result = Workflow::retryable(UnreliableAgent::class, 5)->go(); [​](https://docs.vizra.ai/advanced/macros#best-practices) Best Practices --------------------------------------------------------------------------- Return $this ------------ Always return `$this` to maintain the fluent interface Register Early -------------- Register macros in `AppServiceProvider::boot()` Descriptive Names ----------------- Use clear, descriptive names for your macros Document Well ------------- Document macros for other developers on your team Additional tips: * **Consider scope** - Macros are global, so namespace them if needed to avoid conflicts * **Test your macros** - Write tests to ensure macros work as expected * **Group related macros** - Use mixins to organize related functionality [​](https://docs.vizra.ai/advanced/macros#testing-macros) Testing Macros --------------------------------------------------------------------------- Test your macros using Pest or PHPUnit: tests/Feature/MacroTest.php Copy use Vizra\VizraADK\Services\AgentBuilder; use Vizra\VizraADK\Facades\Agent; use App\Models\Unit; it('can track models with macro', function () { AgentBuilder::macro('track', function (Model $model) { $this->trackedModel = $model; return $this; }); $model = Unit::factory()->create(); $builder = Agent::define('test-agent')->track($model); expect($builder->trackedModel)->toBe($model); }); The full test suite for macro support is available at `tests/Feature/MacroSupportTest.php` with 10 comprehensive tests covering all major use cases. [​](https://docs.vizra.ai/advanced/macros#learn-more) Learn More ------------------------------------------------------------------- [Laravel Macros Docs\ -------------------\ \ Official Laravel documentation on macros](https://laravel.com/docs/11.x/helpers#method-macro) [Agent Builder API\ -----------------\ \ Complete AgentBuilder reference](https://docs.vizra.ai/api-reference/agent-class) Was this page helpful? YesNo [Agent Queuing](https://docs.vizra.ai/advanced/agent-queuing) [LLM Providers](https://docs.vizra.ai/integrations/providers) ⌘I --- # Image Agent - Vizra ADK [Skip to main content](https://docs.vizra.ai/agents/image-agent#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Agents Image Agent [Documentation](https://docs.vizra.ai/) On this page * [What is ImageAgent?](https://docs.vizra.ai/agents/image-agent#what-is-imageagent) * [Quick Start](https://docs.vizra.ai/agents/image-agent#quick-start) * [Basic Usage](https://docs.vizra.ai/agents/image-agent#basic-usage) * [Simple Generation](https://docs.vizra.ai/agents/image-agent#simple-generation) * [Storing Images](https://docs.vizra.ai/agents/image-agent#storing-images) * [Auto-Store on Generation](https://docs.vizra.ai/agents/image-agent#auto-store-on-generation) * [Configuration Options](https://docs.vizra.ai/agents/image-agent#configuration-options) * [Image Size](https://docs.vizra.ai/agents/image-agent#image-size) * [Quality](https://docs.vizra.ai/agents/image-agent#quality) * [Style](https://docs.vizra.ai/agents/image-agent#style) * [Provider & Model](https://docs.vizra.ai/agents/image-agent#provider-%26-model) * [Complete Configuration Example](https://docs.vizra.ai/agents/image-agent#complete-configuration-example) * [ImageResponse Class](https://docs.vizra.ai/agents/image-agent#imageresponse-class) * [Accessing Image Data](https://docs.vizra.ai/agents/image-agent#accessing-image-data) * [Metadata](https://docs.vizra.ai/agents/image-agent#metadata) * [Serialization](https://docs.vizra.ai/agents/image-agent#serialization) * [Async & Queue Processing](https://docs.vizra.ai/agents/image-agent#async-%26-queue-processing) * [Basic Async](https://docs.vizra.ai/agents/image-agent#basic-async) * [Queue Configuration](https://docs.vizra.ai/agents/image-agent#queue-configuration) * [Listening for Completion](https://docs.vizra.ai/agents/image-agent#listening-for-completion) * [Using with LLM Agents](https://docs.vizra.ai/agents/image-agent#using-with-llm-agents) * [Setup](https://docs.vizra.ai/agents/image-agent#setup) * [Quick Setup with Factory Method](https://docs.vizra.ai/agents/image-agent#quick-setup-with-factory-method) * [How It Works](https://docs.vizra.ai/agents/image-agent#how-it-works) * [Context & User Tracking](https://docs.vizra.ai/agents/image-agent#context-%26-user-tracking) * [Configuration Reference](https://docs.vizra.ai/agents/image-agent#configuration-reference) * [Environment Variables](https://docs.vizra.ai/agents/image-agent#environment-variables) * [Config File](https://docs.vizra.ai/agents/image-agent#config-file) * [Supported Providers & Models](https://docs.vizra.ai/agents/image-agent#supported-providers-%26-models) * [API Reference](https://docs.vizra.ai/agents/image-agent#api-reference) * [ImageAgent Static Methods](https://docs.vizra.ai/agents/image-agent#imageagent-static-methods) * [MediaAgentExecutor Methods (Fluent API)](https://docs.vizra.ai/agents/image-agent#mediaagentexecutor-methods-fluent-api) * [ImageResponse Methods](https://docs.vizra.ai/agents/image-agent#imageresponse-methods) [​](https://docs.vizra.ai/agents/image-agent#what-is-imageagent) What is ImageAgent? --------------------------------------------------------------------------------------- ImageAgent is a specialized media agent that generates images from text descriptions. It integrates with providers like OpenAI (DALL-E) and Google (Imagen) through Prism PHP, offering a fluent API for configuration, built-in storage, and queue support. Multi-Provider -------------- Works with OpenAI DALL-E, Google Imagen, and other image generation models Fluent API ---------- Chain methods like `size()`, `quality()`, and `style()` for clean configuration Built-in Storage ---------------- Store generated images directly to Laravel’s filesystem with `store()` and `storeAs()` Queue Support ------------- Process image generation asynchronously with Laravel queues [​](https://docs.vizra.ai/agents/image-agent#quick-start) Quick Start ------------------------------------------------------------------------ Generate an image with just a few lines of code: Copy use Vizra\VizraADK\Agents\ImageAgent; // Generate and store an image $image = ImageAgent::run('A sunset over the ocean') ->quality('hd') ->go(); $image->storeAs('sunset.png'); echo $image->url(); // URL to the stored image The `run()` method returns a fluent executor - chain your configuration and call `go()` to execute! [​](https://docs.vizra.ai/agents/image-agent#basic-usage) Basic Usage ------------------------------------------------------------------------ ### [​](https://docs.vizra.ai/agents/image-agent#simple-generation) Simple Generation Copy // Generate with default settings $image = ImageAgent::run('A mountain landscape at dawn')->go(); // Access the image $url = $image->url(); // Storage or provider URL $base64 = $image->base64(); // Base64-encoded data $data = $image->data(); // Raw binary data ### [​](https://docs.vizra.ai/agents/image-agent#storing-images) Storing Images Images can be stored to Laravel’s filesystem: Copy // Store with auto-generated filename (ULID) $image = ImageAgent::run('An oil painting of flowers')->go(); $image->store(); // Stores as e.g., 01HWXYZ123.png $image->store('s3'); // Store to a specific disk // Store with custom filename $image->storeAs('flowers.png'); $image->storeAs('art/flowers.png', 's3'); // Check storage status if ($image->isStored()) { echo $image->path(); // vizra-adk/generated/images/flowers.png echo $image->disk(); // public } Images are stored in the `vizra-adk/generated/images/` directory by default. Configure this in your `vizra-adk.php` config file. ### [​](https://docs.vizra.ai/agents/image-agent#auto-store-on-generation) Auto-Store on Generation Chain storage directly in the fluent API: Copy // Store with auto-generated name $image = ImageAgent::run('A futuristic city') ->store() ->go(); // Store with specific filename $image = ImageAgent::run('A vintage car') ->storeAs('vintage-car.png') ->go(); [​](https://docs.vizra.ai/agents/image-agent#configuration-options) Configuration Options -------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/agents/image-agent#image-size) Image Size Set dimensions using preset methods or custom sizes: Copy // Preset sizes ImageAgent::run('...')->square()->go(); // 1024x1024 ImageAgent::run('...')->portrait()->go(); // 1024x1792 ImageAgent::run('...')->landscape()->go(); // 1792x1024 // Custom size ImageAgent::run('...')->size('512x512')->go(); Available sizes depend on your provider: | Provider | Supported Sizes | | --- | --- | | OpenAI DALL-E 3 | 1024x1024, 1024x1792, 1792x1024 | | OpenAI DALL-E 2 | 256x256, 512x512, 1024x1024 | | Google Imagen | Varies by model | ### [​](https://docs.vizra.ai/agents/image-agent#quality) Quality Control the quality level (OpenAI-specific): Copy // Standard quality (default, faster) ImageAgent::run('...')->quality('standard')->go(); // HD quality (more detail, slower) ImageAgent::run('...')->quality('hd')->go(); ImageAgent::run('...')->hd()->go(); // Shorthand ### [​](https://docs.vizra.ai/agents/image-agent#style) Style Set the visual style (DALL-E 3 specific): Copy // Vivid - hyper-real, dramatic (default) ImageAgent::run('...')->style('vivid')->go(); // Natural - more realistic, less exaggerated ImageAgent::run('...')->style('natural')->go(); ### [​](https://docs.vizra.ai/agents/image-agent#provider-&-model) Provider & Model Override the default provider and model: Copy // Use a specific provider and model ImageAgent::run('A serene lake') ->using('openai', 'dall-e-3') ->go(); // Switch to Google Imagen ImageAgent::run('A colorful abstract pattern') ->using('google', 'imagen-3') ->go(); ### [​](https://docs.vizra.ai/agents/image-agent#complete-configuration-example) Complete Configuration Example Copy $image = ImageAgent::run('An oil painting of flowers') ->using('openai', 'dall-e-3') ->landscape() ->hd() ->style('natural') ->storeAs('flowers.png') ->go(); [​](https://docs.vizra.ai/agents/image-agent#imageresponse-class) ImageResponse Class ---------------------------------------------------------------------------------------- The `ImageResponse` object provides access to all image data and metadata: ### [​](https://docs.vizra.ai/agents/image-agent#accessing-image-data) Accessing Image Data Copy $image = ImageAgent::run('...')->go(); // URLs $url = $image->url(); // Best available URL (stored or provider) $providerUrl = $image->providerUrl(); // Original URL from provider // Binary data $data = $image->data(); // Raw binary content $base64 = $image->base64(); // Base64-encoded string $dataUri = $image->toDataUri(); // data:image/png;base64,... // Storage info (after storing) $path = $image->path(); // Storage path $disk = $image->disk(); // Storage disk name ### [​](https://docs.vizra.ai/agents/image-agent#metadata) Metadata Copy $image = ImageAgent::run('A sunset')->go(); // Access metadata echo $image->prompt(); // "A sunset" echo $image->mimeType(); // "image/png" echo $image->hasImage(); // true echo $image->isStored(); // false (until stored) // Get all metadata as array $metadata = $image->metadata(); // [\ // 'prompt' => 'A sunset',\ // 'provider' => 'openai',\ // 'model' => 'dall-e-3',\ // 'url' => '...',\ // 'provider_url' => '...',\ // 'path' => null,\ // 'disk' => null,\ // 'generated_at' => '2024-01-15T10:30:00.000Z'\ // ] ### [​](https://docs.vizra.ai/agents/image-agent#serialization) Serialization Copy $image = ImageAgent::run('...')->go(); // Convert to array or JSON $array = $image->toArray(); $json = $image->toJson(); // String casting returns URL echo $image; // Outputs the URL [​](https://docs.vizra.ai/agents/image-agent#async-&-queue-processing) Async & Queue Processing -------------------------------------------------------------------------------------------------- For long-running generations, use Laravel queues: ### [​](https://docs.vizra.ai/agents/image-agent#basic-async) Basic Async Copy // Dispatch to default queue $result = ImageAgent::run('A complex scene') ->async() ->go(); // Returns immediately with job info // [\ // 'job_dispatched' => true,\ // 'job_id' => 'uuid-here',\ // 'queue' => 'default',\ // 'agent' => 'image_agent',\ // 'prompt' => 'A complex scene'\ // ] ### [​](https://docs.vizra.ai/agents/image-agent#queue-configuration) Queue Configuration Copy ImageAgent::run('A detailed illustration') ->onQueue('media') // Specific queue name ->delay(60) // Delay execution by 60 seconds ->tries(5) // Retry up to 5 times on failure ->timeout(120) // 2-minute timeout ->then(fn($image) => $image->storeAs('illustration.png')) ->go(); The `then()` callback runs after generation completes - use it to store images or trigger notifications. The callback must be serializable for queue processing. ### [​](https://docs.vizra.ai/agents/image-agent#listening-for-completion) Listening for Completion Listen for media generation events: Copy // In your EventServiceProvider or Listener Event::listen('media.image_agent.completed', function ($event) { $jobId = $event['job_id']; $response = $event['response']; $sessionId = $event['session_id']; // Process the completed image Log::info("Image generated: " . $response->url()); }); // Generic event for all media types Event::listen('media.job.completed', function ($event) { // Handle any media job completion }); [​](https://docs.vizra.ai/agents/image-agent#using-with-llm-agents) Using with LLM Agents -------------------------------------------------------------------------------------------- Allow your LLM agents to generate images using the `DelegateToMediaAgentTool`: ### [​](https://docs.vizra.ai/agents/image-agent#setup) Setup Copy use Vizra\VizraADK\Agents\BaseLlmAgent; use Vizra\VizraADK\Agents\ImageAgent; use Vizra\VizraADK\Tools\DelegateToMediaAgentTool; class CreativeAssistantAgent extends BaseLlmAgent { protected string $name = 'creative_assistant'; protected string $description = 'A creative assistant that can generate images'; protected string $instructions = <<tools[] = DelegateToMediaAgentTool::forImage(); } ### [​](https://docs.vizra.ai/agents/image-agent#how-it-works) How It Works When the LLM decides to generate an image, it calls the `generate_image` tool with these parameters: Copy { "name": "generate_image", "parameters": { "prompt": "Detailed description of the image", "size": "1024x1024", "quality": "hd", "style": "natural" } } The tool automatically: 1. Executes the ImageAgent with the provided parameters 2. Stores the generated image 3. Returns the URL and path to the LLM [​](https://docs.vizra.ai/agents/image-agent#context-&-user-tracking) Context & User Tracking ------------------------------------------------------------------------------------------------ Associate generations with users and sessions: Copy ImageAgent::run('A personalized avatar') ->forUser($user) // Associate with a user model ->withSession('session-123') // Custom session ID ->withContext([ // Additional context data\ 'source' => 'profile_editor',\ 'request_id' => $requestId,\ ]) ->go(); [​](https://docs.vizra.ai/agents/image-agent#configuration-reference) Configuration Reference ------------------------------------------------------------------------------------------------ ### [​](https://docs.vizra.ai/agents/image-agent#environment-variables) Environment Variables | Variable | Description | Default | | --- | --- | --- | | `VIZRA_ADK_MEDIA_ENABLED` | Enable media generation | `true` | | `VIZRA_ADK_MEDIA_DISK` | Storage disk for generated media | `public` | | `VIZRA_ADK_MEDIA_PATH` | Base path for stored media | `vizra-adk/generated` | | `VIZRA_ADK_IMAGE_PROVIDER` | Default image provider | `openai` | | `VIZRA_ADK_IMAGE_MODEL` | Default image model | `dall-e-3` | | `VIZRA_ADK_IMAGE_SIZE` | Default image size | `1024x1024` | | `VIZRA_ADK_IMAGE_QUALITY` | Default quality | `standard` | | `VIZRA_ADK_IMAGE_STYLE` | Default style | `vivid` | | `VIZRA_ADK_IMAGE_FORMAT` | Response format | `url` | ### [​](https://docs.vizra.ai/agents/image-agent#config-file) Config File config/vizra-adk.php Copy 'media' => [\ 'enabled' => env('VIZRA_ADK_MEDIA_ENABLED', true),\ \ 'storage' => [\ 'disk' => env('VIZRA_ADK_MEDIA_DISK', 'public'),\ 'path' => env('VIZRA_ADK_MEDIA_PATH', 'vizra-adk/generated'),\ ],\ \ 'image' => [\ 'provider' => env('VIZRA_ADK_IMAGE_PROVIDER', 'openai'),\ 'model' => env('VIZRA_ADK_IMAGE_MODEL', 'dall-e-3'),\ 'default_size' => env('VIZRA_ADK_IMAGE_SIZE', '1024x1024'),\ 'default_quality' => env('VIZRA_ADK_IMAGE_QUALITY', 'standard'),\ 'default_style' => env('VIZRA_ADK_IMAGE_STYLE', 'vivid'),\ 'response_format' => env('VIZRA_ADK_IMAGE_FORMAT', 'url'),\ ],\ ], ### [​](https://docs.vizra.ai/agents/image-agent#supported-providers-&-models) Supported Providers & Models OpenAI ------ * **dall-e-3** - Latest, highest quality * **dall-e-2** - Faster, more sizes * **gpt-image-1** - Newest model Google ------ * **imagen-3** - High quality generation * **imagen-4** - Latest Imagen model * **gemini-2.0-flash-preview-image-generation** [​](https://docs.vizra.ai/agents/image-agent#api-reference) API Reference ---------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/agents/image-agent#imageagent-static-methods) ImageAgent Static Methods | Method | Description | | --- | --- | | `run(string $prompt)` | Start a fluent generation chain | ### [​](https://docs.vizra.ai/agents/image-agent#mediaagentexecutor-methods-fluent-api) MediaAgentExecutor Methods (Fluent API) | Method | Description | | --- | --- | | `using(string $provider, string $model)` | Override provider and model | | `forUser(Model $user)` | Associate with a user | | `withSession(string $sessionId)` | Set session ID | | `withContext(array $context)` | Add context data | | `size(string $size)` | Set custom dimensions | | `square()` | 1024x1024 | | `portrait()` | 1024x1792 | | `landscape()` | 1792x1024 | | `quality(string $quality)` | Set quality level | | `hd()` | Shorthand for HD quality | | `style(string $style)` | Set visual style | | `store(?string $disk)` | Auto-store with generated name | | `storeAs(string $filename, ?string $disk)` | Auto-store with specific name | | `async(bool $enabled)` | Enable async processing | | `onQueue(string $queue)` | Specify queue name | | `delay(int $seconds)` | Delay execution | | `tries(int $tries)` | Set retry attempts | | `timeout(int $seconds)` | Set timeout | | `then(Closure $callback)` | Post-generation callback | | `go()` | Execute the generation | ### [​](https://docs.vizra.ai/agents/image-agent#imageresponse-methods) ImageResponse Methods | Method | Returns | Description | | --- | --- | --- | | `url()` | `?string` | Best available URL | | `providerUrl()` | `?string` | Original provider URL | | `path()` | `?string` | Storage path | | `disk()` | `?string` | Storage disk | | `base64()` | `string` | Base64-encoded data | | `data()` | `string` | Raw binary data | | `toDataUri()` | `string` | Data URI for embedding | | `prompt()` | `string` | Original prompt | | `mimeType()` | `string` | MIME type | | `metadata()` | `array` | All metadata | | `hasImage()` | `bool` | Has image data | | `isStored()` | `bool` | Has been stored | | `store(?string $disk)` | `static` | Store with auto name | | `storeAs(string $filename, ?string $disk)` | `static` | Store with name | | `toArray()` | `array` | Convert to array | | `toJson()` | `string` | Convert to JSON | [Audio Agent\ -----------\ \ Generate speech and audio with the AudioAgent](https://docs.vizra.ai/agents/audio-agent) [Agent Queuing\ -------------\ \ Learn more about async agent processing](https://docs.vizra.ai/advanced/agent-queuing) Was this page helpful? YesNo [Audio Agent](https://docs.vizra.ai/agents/audio-agent) [Toolbox](https://docs.vizra.ai/tools/toolbox) ⌘I --- # Audio Agent - Vizra ADK [Skip to main content](https://docs.vizra.ai/agents/audio-agent#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Agents Audio Agent [Documentation](https://docs.vizra.ai/) On this page * [Quick Start](https://docs.vizra.ai/agents/audio-agent#quick-start) * [Voice Selection](https://docs.vizra.ai/agents/audio-agent#voice-selection) * [Available Voices](https://docs.vizra.ai/agents/audio-agent#available-voices) * [Audio Formats](https://docs.vizra.ai/agents/audio-agent#audio-formats) * [Supported Formats](https://docs.vizra.ai/agents/audio-agent#supported-formats) * [Speech Speed](https://docs.vizra.ai/agents/audio-agent#speech-speed) * [Model Selection](https://docs.vizra.ai/agents/audio-agent#model-selection) * [Available Models](https://docs.vizra.ai/agents/audio-agent#available-models) * [Storage](https://docs.vizra.ai/agents/audio-agent#storage) * [Auto-store with Custom Filename](https://docs.vizra.ai/agents/audio-agent#auto-store-with-custom-filename) * [Auto-store with Generated Filename](https://docs.vizra.ai/agents/audio-agent#auto-store-with-generated-filename) * [Store to Specific Disk](https://docs.vizra.ai/agents/audio-agent#store-to-specific-disk) * [Manual Storage](https://docs.vizra.ai/agents/audio-agent#manual-storage) * [Working with AudioResponse](https://docs.vizra.ai/agents/audio-agent#working-with-audioresponse) * [Embedding in HTML](https://docs.vizra.ai/agents/audio-agent#embedding-in-html) * [Async/Queued Generation](https://docs.vizra.ai/agents/audio-agent#async%2Fqueued-generation) * [Queue Options](https://docs.vizra.ai/agents/audio-agent#queue-options) * [Async Return Value](https://docs.vizra.ai/agents/audio-agent#async-return-value) * [User Context](https://docs.vizra.ai/agents/audio-agent#user-context) * [Sub-agent Delegation](https://docs.vizra.ai/agents/audio-agent#sub-agent-delegation) * [Configuration](https://docs.vizra.ai/agents/audio-agent#configuration) * [Environment Variables](https://docs.vizra.ai/agents/audio-agent#environment-variables) * [Config File](https://docs.vizra.ai/agents/audio-agent#config-file) * [Complete Example](https://docs.vizra.ai/agents/audio-agent#complete-example) * [Error Handling](https://docs.vizra.ai/agents/audio-agent#error-handling) * [API Reference](https://docs.vizra.ai/agents/audio-agent#api-reference) * [AudioAgent Methods](https://docs.vizra.ai/agents/audio-agent#audioagent-methods) * [MediaAgentExecutor Methods (Fluent Chain)](https://docs.vizra.ai/agents/audio-agent#mediaagentexecutor-methods-fluent-chain) * [AudioResponse Methods](https://docs.vizra.ai/agents/audio-agent#audioresponse-methods) The `AudioAgent` provides text-to-speech (TTS) capabilities using AI models through Prism PHP. Convert any text into natural-sounding speech with multiple voice options and audio formats. [​](https://docs.vizra.ai/agents/audio-agent#quick-start) Quick Start ------------------------------------------------------------------------ Generate speech from text with just a few lines of code: Copy use Vizra\VizraADK\Agents\AudioAgent; // Simple TTS generation $audio = AudioAgent::run('Welcome to our application')->go(); // Save the audio $audio->storeAs('welcome.mp3'); // Get the URL $url = $audio->url(); [​](https://docs.vizra.ai/agents/audio-agent#voice-selection) Voice Selection -------------------------------------------------------------------------------- Choose from six distinct AI voices, each with their own character: Copy // Using the voice() method $audio = AudioAgent::run('Hello world') ->voice('nova') ->go(); // Using voice preset methods $audio = AudioAgent::run('Hello world') ->shimmer() ->go(); ### [​](https://docs.vizra.ai/agents/audio-agent#available-voices) Available Voices | Voice | Description | | --- | --- | | `alloy` | Balanced, neutral voice (default) | | `echo` | Warm, conversational tone | | `fable` | Expressive, storytelling style | | `onyx` | Deep, authoritative voice | | `nova` | Friendly, energetic delivery | | `shimmer` | Clear, professional sound | Each voice has a shortcut method: `alloy()`, `echo()`, `fable()`, `onyx()`, `nova()`, `shimmer()`. [​](https://docs.vizra.ai/agents/audio-agent#audio-formats) Audio Formats ---------------------------------------------------------------------------- Select your preferred output format based on your use case: Copy $audio = AudioAgent::run('Your order has been confirmed') ->format('wav') ->go(); ### [​](https://docs.vizra.ai/agents/audio-agent#supported-formats) Supported Formats | Format | Use Case | | --- | --- | | `mp3` | Web playback, general use (default) | | `wav` | High quality, editing workflows | | `opus` | Streaming, low latency | | `aac` | iOS/Safari compatibility | | `flac` | Lossless archival | [​](https://docs.vizra.ai/agents/audio-agent#speech-speed) Speech Speed -------------------------------------------------------------------------- Adjust the speaking rate between 0.25x and 4.0x: Copy // Slower for accessibility $audio = AudioAgent::run('Important instructions') ->speed(0.8) ->go(); // Faster for summaries $audio = AudioAgent::run('Quick recap of today') ->speed(1.5) ->go(); [​](https://docs.vizra.ai/agents/audio-agent#model-selection) Model Selection -------------------------------------------------------------------------------- Override the default model for different quality/speed tradeoffs: Copy // Use HD model for higher quality $audio = AudioAgent::run('Premium narration content') ->using('openai', 'tts-1-hd') ->go(); // Use mini model for faster generation $audio = AudioAgent::run('Quick notification') ->using('openai', 'gpt-4o-mini-tts') ->go(); ### [​](https://docs.vizra.ai/agents/audio-agent#available-models) Available Models | Model | Description | | --- | --- | | `tts-1` | Standard quality, faster generation (default) | | `tts-1-hd` | Higher quality, slower generation | | `gpt-4o-mini-tts` | Latest model with enhanced capabilities | [​](https://docs.vizra.ai/agents/audio-agent#storage) Storage ---------------------------------------------------------------- ### [​](https://docs.vizra.ai/agents/audio-agent#auto-store-with-custom-filename) Auto-store with Custom Filename Copy $audio = AudioAgent::run('Welcome message') ->voice('nova') ->storeAs('welcome.mp3') ->go(); echo $audio->url(); // Returns the stored file URL echo $audio->path(); // Returns the storage path ### [​](https://docs.vizra.ai/agents/audio-agent#auto-store-with-generated-filename) Auto-store with Generated Filename Copy $audio = AudioAgent::run('Dynamic content') ->store() ->go(); // File stored with ULID filename like: vizra-adk/generated/audio/01HXY...mp3 ### [​](https://docs.vizra.ai/agents/audio-agent#store-to-specific-disk) Store to Specific Disk Copy $audio = AudioAgent::run('Private audio') ->storeAs('private/message.mp3', 's3') ->go(); ### [​](https://docs.vizra.ai/agents/audio-agent#manual-storage) Manual Storage Copy $audio = AudioAgent::run('Hello world')->go(); // Store with custom filename $audio->storeAs('greetings/hello.mp3'); // Or auto-generate filename $audio->store(); [​](https://docs.vizra.ai/agents/audio-agent#working-with-audioresponse) Working with AudioResponse ------------------------------------------------------------------------------------------------------ The `AudioResponse` object provides methods to access and manipulate the generated audio: Copy $audio = AudioAgent::run('Sample text') ->nova() ->format('mp3') ->go(); // Access audio data $audio->data(); // Raw binary audio data $audio->base64(); // Base64-encoded audio $audio->toDataUri(); // Data URI for embedding (data:audio/mpeg;base64,...) // Metadata $audio->text(); // Original input text $audio->voice(); // Voice used (e.g., 'nova') $audio->format(); // Format (e.g., 'mp3') $audio->mimeType(); // MIME type (e.g., 'audio/mpeg') $audio->metadata(); // Full metadata array // Storage status $audio->isStored(); // Check if audio was stored $audio->url(); // Get URL (stored or data URI) $audio->path(); // Get storage path $audio->disk(); // Get storage disk used ### [​](https://docs.vizra.ai/agents/audio-agent#embedding-in-html) Embedding in HTML Copy $audio = AudioAgent::run('Play this message')->go(); // Using data URI (no storage needed) $html = ''; // Using stored URL $audio->store(); $html = ''; [​](https://docs.vizra.ai/agents/audio-agent#async/queued-generation) Async/Queued Generation ------------------------------------------------------------------------------------------------ For long-running generations or batch processing, use Laravel queues: Copy // Basic async generation AudioAgent::run('Long article content here...') ->onQueue('media') ->go(); // With callback after completion AudioAgent::run('Order confirmation for order #12345') ->shimmer() ->format('mp3') ->onQueue('media') ->then(function ($audio) { $audio->storeAs('confirmations/order-12345.mp3'); // Send notification, update database, etc. Notification::send($user, new AudioReadyNotification($audio->url())); }) ->go(); ### [​](https://docs.vizra.ai/agents/audio-agent#queue-options) Queue Options Copy AudioAgent::run('Background audio task') ->onQueue('media') // Specify queue name ->delay(60) // Delay in seconds ->tries(5) // Retry attempts ->timeout(180) // Timeout in seconds ->then(fn($audio) => $audio->store()) ->go(); ### [​](https://docs.vizra.ai/agents/audio-agent#async-return-value) Async Return Value When using async mode, `go()` returns job information instead of the audio: Copy $result = AudioAgent::run('Async generation') ->onQueue('media') ->go(); // $result contains: // [\ // 'job_dispatched' => true,\ // 'job_id' => 'uuid-string',\ // 'queue' => 'media',\ // 'agent' => 'audio_agent',\ // 'prompt' => 'Async generation',\ // ] [​](https://docs.vizra.ai/agents/audio-agent#user-context) User Context -------------------------------------------------------------------------- Associate audio generation with a user for tracking and personalization: Copy AudioAgent::run('Personal greeting') ->forUser($user) ->withSession('session-123') ->go(); [​](https://docs.vizra.ai/agents/audio-agent#sub-agent-delegation) Sub-agent Delegation ------------------------------------------------------------------------------------------ Allow your LLM agents to generate audio by delegating to the AudioAgent: Copy use Vizra\VizraADK\Agents\BaseLlmAgent; use Vizra\VizraADK\Tools\DelegateToMediaAgentTool; class AssistantAgent extends BaseLlmAgent { protected string $name = 'assistant'; protected string $instructions = <<<'PROMPT' You are a helpful assistant. When the user asks you to read something aloud or create audio, use the generate_audio tool to convert text to speech. PROMPT; protected array $tools = [\ DelegateToMediaAgentTool::class,\ ]; protected array $mediaAgents = [\ \Vizra\VizraADK\Agents\AudioAgent::class,\ ]; } Or create the tool directly: Copy use Vizra\VizraADK\Tools\DelegateToMediaAgentTool; class NarratorAgent extends BaseLlmAgent { protected function tools(): array { return [\ DelegateToMediaAgentTool::forAudio(),\ ]; } } When the LLM calls the `generate_audio` tool, it can specify: * `text` (required): The text to convert to speech * `voice` (optional): Voice selection * `format` (optional): Output format [​](https://docs.vizra.ai/agents/audio-agent#configuration) Configuration ---------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/agents/audio-agent#environment-variables) Environment Variables Copy # Provider and model VIZRA_ADK_AUDIO_PROVIDER=openai VIZRA_ADK_AUDIO_MODEL=tts-1 # Defaults VIZRA_ADK_AUDIO_VOICE=alloy VIZRA_ADK_AUDIO_FORMAT=mp3 VIZRA_ADK_AUDIO_SPEED=1.0 ### [​](https://docs.vizra.ai/agents/audio-agent#config-file) Config File In `config/vizra-adk.php`: Copy 'media' => [\ 'audio' => [\ 'provider' => env('VIZRA_ADK_AUDIO_PROVIDER', 'openai'),\ 'model' => env('VIZRA_ADK_AUDIO_MODEL', 'tts-1'),\ 'default_voice' => env('VIZRA_ADK_AUDIO_VOICE', 'alloy'),\ 'default_format' => env('VIZRA_ADK_AUDIO_FORMAT', 'mp3'),\ 'default_speed' => env('VIZRA_ADK_AUDIO_SPEED', 1.0),\ ],\ \ 'storage' => [\ 'disk' => env('VIZRA_ADK_MEDIA_DISK', 'public'),\ 'path' => env('VIZRA_ADK_MEDIA_PATH', 'vizra-adk/generated'),\ ],\ ], [​](https://docs.vizra.ai/agents/audio-agent#complete-example) Complete Example ---------------------------------------------------------------------------------- Here’s a comprehensive example showing common patterns: Copy use Vizra\VizraADK\Agents\AudioAgent; class PodcastService { public function generateIntro(string $episodeTitle): string { $text = "Welcome to today's episode: {$episodeTitle}"; $audio = AudioAgent::run($text) ->using('openai', 'tts-1-hd') ->nova() ->format('mp3') ->speed(1.0) ->storeAs("podcasts/intros/{$this->slug($episodeTitle)}.mp3") ->go(); return $audio->url(); } public function generateChapterAudio(array $chapters): void { foreach ($chapters as $index => $chapter) { AudioAgent::run($chapter['content']) ->onyx() ->format('mp3') ->onQueue('podcast-generation') ->then(function ($audio) use ($chapter) { $audio->storeAs("chapters/{$chapter['id']}.mp3"); Chapter::find($chapter['id'])->update([\ 'audio_url' => $audio->url(),\ 'audio_generated_at' => now(),\ ]); }) ->go(); } } } [​](https://docs.vizra.ai/agents/audio-agent#error-handling) Error Handling ------------------------------------------------------------------------------ Copy try { $audio = AudioAgent::run('Generate this audio') ->nova() ->go(); $audio->store(); } catch (\Exception $e) { Log::error('Audio generation failed', [\ 'error' => $e->getMessage(),\ ]); } [​](https://docs.vizra.ai/agents/audio-agent#api-reference) API Reference ---------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/agents/audio-agent#audioagent-methods) AudioAgent Methods | Method | Description | | --- | --- | | `run(string $text)` | Static method to start fluent chain | | `execute($input, $context)` | Direct execution with context | | `toToolDefinition()` | Get tool schema for sub-agent use | | `executeFromToolCall($args, $context)` | Execute from LLM tool call | ### [​](https://docs.vizra.ai/agents/audio-agent#mediaagentexecutor-methods-fluent-chain) MediaAgentExecutor Methods (Fluent Chain) | Method | Description | | --- | --- | | `voice(string $voice)` | Set voice | | `format(string $format)` | Set output format | | `speed(float $speed)` | Set speech speed (0.25-4.0) | | `alloy()`, `echo()`, etc. | Voice presets | | `using(string $provider, string $model)` | Override provider/model | | `forUser(Model $user)` | Set user context | | `withSession(string $id)` | Set session ID | | `withContext(array $context)` | Add context data | | `store(?string $path, ?string $disk)` | Auto-store with path | | `storeAs(string $filename, ?string $disk)` | Auto-store with filename | | `onQueue(string $queue)` | Enable async on queue | | `delay(int $seconds)` | Delay queue execution | | `tries(int $count)` | Set retry attempts | | `timeout(int $seconds)` | Set timeout | | `then(Closure $callback)` | Callback after completion | | `go()` | Execute and return result | ### [​](https://docs.vizra.ai/agents/audio-agent#audioresponse-methods) AudioResponse Methods | Method | Returns | Description | | --- | --- | --- | | `data()` | `string` | Raw binary audio | | `base64()` | `string` | Base64-encoded audio | | `toDataUri()` | `string` | Data URI for embedding | | `text()` | `string` | Original input text | | `voice()` | `string` | Voice used | | `format()` | `string` | Audio format | | `mimeType()` | `string` | MIME type | | `metadata()` | `array` | Full metadata | | `store(?string $disk)` | `static` | Store with auto filename | | `storeAs(string $filename, ?string $disk)` | `static` | Store with custom filename | | `url()` | `?string` | Get URL | | `path()` | `?string` | Get storage path | | `disk()` | `?string` | Get storage disk | | `isStored()` | `bool` | Check if stored | | `raw()` | `mixed` | Get raw Prism response | | `toArray()` | `array` | Convert to array | | `toJson()` | `string` | Convert to JSON | Was this page helpful? YesNo [Specialized Agents](https://docs.vizra.ai/agents/overview) [Image Agent](https://docs.vizra.ai/agents/image-agent) ⌘I --- # Laravel Boost Integration - Vizra ADK [Skip to main content](https://docs.vizra.ai/integrations/laravel-boost#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Integrations Laravel Boost Integration [Documentation](https://docs.vizra.ai/) On this page * [What is Laravel Boost?](https://docs.vizra.ai/integrations/laravel-boost#what-is-laravel-boost) * [Quick Start](https://docs.vizra.ai/integrations/laravel-boost#quick-start) * [1\. Install Laravel Boost](https://docs.vizra.ai/integrations/laravel-boost#1-install-laravel-boost) * [2\. Install Vizra ADK Guidelines](https://docs.vizra.ai/integrations/laravel-boost#2-install-vizra-adk-guidelines) * [3\. Start Using Boost with Vizra ADK](https://docs.vizra.ai/integrations/laravel-boost#3-start-using-boost-with-vizra-adk) * [Example Usage](https://docs.vizra.ai/integrations/laravel-boost#example-usage) * [Available Guidelines](https://docs.vizra.ai/integrations/laravel-boost#available-guidelines) [​](https://docs.vizra.ai/integrations/laravel-boost#what-is-laravel-boost) What is Laravel Boost? ----------------------------------------------------------------------------------------------------- Laravel Boost is an AI-powered development assistant from the Laravel team that understands your project’s structure and helps you write better code faster. Vizra ADK integrates seamlessly with Boost through a comprehensive guideline system.[Learn more about Laravel Boost\ ------------------------------\ \ GitHub Repository](https://github.com/laravel/boost) [​](https://docs.vizra.ai/integrations/laravel-boost#quick-start) Quick Start -------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/integrations/laravel-boost#1-install-laravel-boost) 1\. Install Laravel Boost First, ensure you have Laravel Boost installed in your project: Terminal Copy composer require laravel/boost --dev ### [​](https://docs.vizra.ai/integrations/laravel-boost#2-install-vizra-adk-guidelines) 2\. Install Vizra ADK Guidelines Run the Boost installation command from your Vizra ADK package: Terminal Copy php artisan vizra:boost:install This command copies the Vizra ADK guidelines to your project’s `resources/boost/guidelines` directory. ### [​](https://docs.vizra.ai/integrations/laravel-boost#3-start-using-boost-with-vizra-adk) 3\. Start Using Boost with Vizra ADK Now Laravel Boost understands your Vizra ADK agents and can help you: * Generate new agents with proper structure and naming * Create tools that implement the correct interface * Build complex workflows with the Workflow facade * Implement memory and context management * Write evaluations and assertions * Debug and troubleshoot common issues [​](https://docs.vizra.ai/integrations/laravel-boost#example-usage) Example Usage ------------------------------------------------------------------------------------ Ask Laravel Boost to help you create a Vizra ADK agent: **Example prompt:**“Create a customer support agent that uses memory to track conversation context and can search our knowledge base” Laravel Boost will generate a complete agent with proper inheritance, tool implementation, and memory configuration based on the Vizra ADK guidelines. [​](https://docs.vizra.ai/integrations/laravel-boost#available-guidelines) Available Guidelines -------------------------------------------------------------------------------------------------- The integration includes comprehensive guidelines for: Core Components --------------- * Agent creation and configuration * Tool implementation * Workflow patterns Advanced Features ----------------- * Memory and context management * Sub-agent delegation * Evaluation framework Laravel Boost works best when you provide clear, specific requirements. The more context you give about your agent’s purpose, the better the generated code will be. Was this page helpful? YesNo [MCP Integration](https://docs.vizra.ai/integrations/mcp) [Evaluations](https://docs.vizra.ai/testing/evaluations) ⌘I --- # Requirements Checklist - Vizra ADK [Skip to main content](https://docs.vizra.ai/installation/requirements#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Getting Started Requirements Checklist [Documentation](https://docs.vizra.ai/) On this page * [System Requirements](https://docs.vizra.ai/installation/requirements#system-requirements) * [Database Requirements](https://docs.vizra.ai/installation/requirements#database-requirements) * [LLM Provider Requirements](https://docs.vizra.ai/installation/requirements#llm-provider-requirements) * [Optional Power-Ups](https://docs.vizra.ai/installation/requirements#optional-power-ups) * [For Vector Memory & RAG](https://docs.vizra.ai/installation/requirements#for-vector-memory-%26-rag) * [For Queue Processing](https://docs.vizra.ai/installation/requirements#for-queue-processing) * [PHP Extensions](https://docs.vizra.ai/installation/requirements#php-extensions) * [Quick Environment Check](https://docs.vizra.ai/installation/requirements#quick-environment-check) * [All Set? Let’s Go!](https://docs.vizra.ai/installation/requirements#all-set-let%E2%80%99s-go) Getting your environment ready is like preparing your workspace before starting a masterpiece! Let’s check off these requirements together to ensure smooth sailing ahead. [​](https://docs.vizra.ai/installation/requirements#system-requirements) System Requirements ----------------------------------------------------------------------------------------------- First things first! Let’s make sure your system has the essentials. These are pretty standard for modern Laravel development. PHP 8.2 or higher We’re using the latest PHP features to give you the best developer experience! Your agents will thank you for the performance boost. Laravel 11.0 or 12.0 Built for the latest Laravel versions! We’re always keeping up with Taylor’s innovations to bring you cutting-edge features. Composer 2.x The package manager that makes installation a breeze! If you’re still on v1, now’s a great time to upgrade. [​](https://docs.vizra.ai/installation/requirements#database-requirements) Database Requirements --------------------------------------------------------------------------------------------------- Your AI agents need a cozy home for their memories! Let’s pick the perfect database for your setup. MySQL 5.7+ / 8.0+ ----------------- Our top pick for production! Fast, reliable, and battle-tested.Recommended PostgreSQL 10+ -------------- Perfect for vector search with pgvector extension!Great for RAG SQLite 3.8.8+ ------------- Lightning-fast for local development and testing!Dev Friendly SQL Server 2017+ ---------------- For teams already in the Microsoft ecosystem.Enterprise Ready SQLite is fantastic for getting started quickly! But when your agents start handling serious workloads or need vector memory features, consider graduating to MySQL or PostgreSQL. Think of it as moving from a studio apartment to a proper house! [​](https://docs.vizra.ai/installation/requirements#llm-provider-requirements) LLM Provider Requirements ----------------------------------------------------------------------------------------------------------- Time to choose the AI brains for your agents! You’ll need at least one API key from these providers. Don’t worry, you can always add more later! OpenAI ------ The OG of AI models! * GPT-4 Turbo * GPT-4 * GPT-3.5 Turbo Anthropic --------- Claude’s got personality! * Claude 3 Opus * Claude 3 Sonnet * Claude 3 Haiku Google ------ Gemini shines bright! * Gemini 1.5 Pro * Gemini 1.5 Flash * Gemini 1.0 Pro [​](https://docs.vizra.ai/installation/requirements#optional-power-ups) Optional Power-Ups --------------------------------------------------------------------------------------------- Want to supercharge your agents? These optional features will take them to the next level! ### [​](https://docs.vizra.ai/installation/requirements#for-vector-memory-&-rag) For Vector Memory & RAG Give your agents photographic memory with semantic search capabilities! Perfect for building knowledge-aware assistants. * Vector Search Engine * Embedding Providers | Engine | Description | | --- | --- | | **Meilisearch 1.0+** | Lightning-fast and easy to set up! | | **PostgreSQL + pgvector** | Keep everything in one database | * OpenAI Embeddings API * Cohere Embed API * Ollama (run locally!) ### [​](https://docs.vizra.ai/installation/requirements#for-queue-processing) For Queue Processing Handle heavy workloads like a pro! Background jobs keep your agents responsive even under pressure. * **Redis 5.0+ (Recommended)** - The speed demon of queue drivers! Your agents will thank you. * **Process Managers** - Supervisor or Laravel Horizon to keep your workers running 24/7 [​](https://docs.vizra.ai/installation/requirements#php-extensions) PHP Extensions ------------------------------------------------------------------------------------- Last but not least! These PHP extensions are the building blocks your agents need. Good news: most of them come pre-installed! BCMath ------ Ctype ----- cURL ---- DOM --- Fileinfo -------- JSON ---- Mbstring -------- OpenSSL ------- PCRE ---- PDO --- Tokenizer --------- XML --- [​](https://docs.vizra.ai/installation/requirements#quick-environment-check) Quick Environment Check ------------------------------------------------------------------------------------------------------- Let’s make sure everything’s in place! Run this handy command to see your setup at a glance. Terminal Copy php artisan about This magical command will show you all the juicy details: Laravel version, PHP version, loaded extensions, and more! It’s like a health check-up for your development environment. [​](https://docs.vizra.ai/installation/requirements#all-set-let%E2%80%99s-go) All Set? Let’s Go! --------------------------------------------------------------------------------------------------- Your environment is ready, and your AI agents are waiting to be born! Time to dive into the exciting world of Vizra ADK.[Continue to Getting Started\ ---------------------------\ \ Install Vizra ADK and create your first AI agent](https://docs.vizra.ai/installation/getting-started) Was this page helpful? YesNo [Getting Started](https://docs.vizra.ai/installation/getting-started) [Configuration](https://docs.vizra.ai/installation/configuration) ⌘I --- # Evaluation Class Reference - Vizra ADK [Skip to main content](https://docs.vizra.ai/api-reference/evaluation-class#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation API Reference Evaluation Class Reference [Documentation](https://docs.vizra.ai/) On this page * [Class Overview](https://docs.vizra.ai/api-reference/evaluation-class#class-overview) * [Properties](https://docs.vizra.ai/api-reference/evaluation-class#properties) * [Abstract Methods](https://docs.vizra.ai/api-reference/evaluation-class#abstract-methods) * [preparePrompt()](https://docs.vizra.ai/api-reference/evaluation-class#prepareprompt) * [evaluateRow()](https://docs.vizra.ai/api-reference/evaluation-class#evaluaterow) * [Content Assertion Methods](https://docs.vizra.ai/api-reference/evaluation-class#content-assertion-methods) * [Text Content Assertions](https://docs.vizra.ai/api-reference/evaluation-class#text-content-assertions) * [Length and Size Assertions](https://docs.vizra.ai/api-reference/evaluation-class#length-and-size-assertions) * [Quality and Safety Assertions](https://docs.vizra.ai/api-reference/evaluation-class#quality-and-safety-assertions) * [Format and Structure Assertions](https://docs.vizra.ai/api-reference/evaluation-class#format-and-structure-assertions) * [JSON Validation](https://docs.vizra.ai/api-reference/evaluation-class#json-validation) * [XML Validation](https://docs.vizra.ai/api-reference/evaluation-class#xml-validation) * [Comparison Assertions](https://docs.vizra.ai/api-reference/evaluation-class#comparison-assertions) * [LLM as Judge](https://docs.vizra.ai/api-reference/evaluation-class#llm-as-judge) * [Pass/Fail Judge](https://docs.vizra.ai/api-reference/evaluation-class#pass%2Ffail-judge) * [Quality Scoring](https://docs.vizra.ai/api-reference/evaluation-class#quality-scoring) * [Multi-dimensional Evaluation](https://docs.vizra.ai/api-reference/evaluation-class#multi-dimensional-evaluation) * [Helper Methods](https://docs.vizra.ai/api-reference/evaluation-class#helper-methods) * [Protected Methods](https://docs.vizra.ai/api-reference/evaluation-class#protected-methods) * [Assertion Results Structure](https://docs.vizra.ai/api-reference/evaluation-class#assertion-results-structure) * [Result Structure](https://docs.vizra.ai/api-reference/evaluation-class#result-structure) * [evaluateRow() Return Format](https://docs.vizra.ai/api-reference/evaluation-class#evaluaterow-return-format) * [Complete Example](https://docs.vizra.ai/api-reference/evaluation-class#complete-example) * [Next Steps](https://docs.vizra.ai/api-reference/evaluation-class#next-steps) [​](https://docs.vizra.ai/api-reference/evaluation-class#class-overview) Class Overview ------------------------------------------------------------------------------------------ Copy namespace Vizra\VizraADK\Evaluations; abstract class BaseEvaluation { // Your evaluation extends this class } [​](https://docs.vizra.ai/api-reference/evaluation-class#properties) Properties ---------------------------------------------------------------------------------- | Property | Type | Required | Description | | --- | --- | --- | --- | | `$agentName` | string | Yes | Agent alias to evaluate (e.g., ‘customer\_support’) | | `$name` | string | Yes | Human-readable evaluation name | | `$description` | string | Yes | Brief description of what this evaluation tests | | `$csvPath` | string | Yes | Path to CSV file relative to base\_path() | | `$promptCsvColumn` | string | No | CSV column containing prompts (default: ‘prompt’) | [​](https://docs.vizra.ai/api-reference/evaluation-class#abstract-methods) Abstract Methods ---------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/api-reference/evaluation-class#prepareprompt) preparePrompt() Copy abstract public function preparePrompt(array $csvRowData): string Prepares the prompt to be sent to the agent based on CSV row data. Copy public function preparePrompt(array $csvRowData): string { // Basic implementation return $csvRowData[$this->getPromptCsvColumn()] ?? ''; // Or with context $prompt = $csvRowData['prompt']; if (isset($csvRowData['context'])) { $prompt = "Context: " . $csvRowData['context'] . "\n\n" . $prompt; } return $prompt; } ### [​](https://docs.vizra.ai/api-reference/evaluation-class#evaluaterow) evaluateRow() Copy abstract public function evaluateRow(array $csvRowData, string $llmResponse): array Evaluates a single row of CSV data against the LLM’s response using assertion methods. Copy public function evaluateRow(array $csvRowData, string $llmResponse): array { // Reset assertions for this row $this->resetAssertionResults(); // Run assertions $this->assertResponseContains($llmResponse, 'expected'); $this->assertResponseHasPositiveSentiment($llmResponse); // Return structured results return [\ 'row_data' => $csvRowData,\ 'llm_response' => $llmResponse,\ 'assertions' => $this->assertionResults,\ 'final_status' => 'pass' // or 'fail'\ ]; } [​](https://docs.vizra.ai/api-reference/evaluation-class#content-assertion-methods) Content Assertion Methods ---------------------------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/api-reference/evaluation-class#text-content-assertions) Text Content Assertions Copy // Check if response contains substring $this->assertResponseContains($response, 'expected text'); // Check if response does NOT contain substring $this->assertResponseDoesNotContain($response, 'unwanted'); // Regex pattern matching $this->assertResponseMatchesRegex($response, '/\d{3}-\d{4}/'); // Check start and end of response $this->assertResponseStartsWith($response, 'Hello'); $this->assertResponseEndsWith($response, '.'); // Check for multiple substrings $this->assertContainsAnyOf($response, ['yes', 'sure', 'okay']); $this->assertContainsAllOf($response, ['thank', 'you']); // Check if response is not empty $this->assertResponseIsNotEmpty($response); ### [​](https://docs.vizra.ai/api-reference/evaluation-class#length-and-size-assertions) Length and Size Assertions Copy // Character length range $this->assertResponseLengthBetween($response, 100, 500); // Word count range $this->assertWordCountBetween($response, 20, 100); ### [​](https://docs.vizra.ai/api-reference/evaluation-class#quality-and-safety-assertions) Quality and Safety Assertions Copy // Sentiment analysis $this->assertResponseHasPositiveSentiment($response); // Grammar and readability $this->assertGrammarCorrect($response); $this->assertReadabilityLevel($response, 12); // Max grade level $this->assertNoRepetition($response, 0.3); // Max repetition ratio // Content safety $this->assertNotToxic($response); $this->assertNotToxic($response, ['custom', 'bad', 'words']); $this->assertNoPII($response); // Spelling conventions $this->assertIsBritishSpelling($response); $this->assertIsAmericanSpelling($response); [​](https://docs.vizra.ai/api-reference/evaluation-class#format-and-structure-assertions) Format and Structure Assertions ---------------------------------------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/api-reference/evaluation-class#json-validation) JSON Validation Copy // Check if response is valid JSON $this->assertResponseIsValidJson($response); // Check if JSON contains specific key $this->assertJsonHasKey($response, 'result'); ### [​](https://docs.vizra.ai/api-reference/evaluation-class#xml-validation) XML Validation Copy // Check if response is valid XML $this->assertResponseIsValidXml($response); // Check if XML contains specific tag $this->assertXmlHasValidTag($response, 'result'); [​](https://docs.vizra.ai/api-reference/evaluation-class#comparison-assertions) Comparison Assertions -------------------------------------------------------------------------------------------------------- Copy // Equality checks $this->assertEquals('expected', $actual); $this->assertTrue($condition); $this->assertFalse($condition); // Numeric comparisons $this->assertGreaterThan(10, $value); $this->assertLessThan(100, $value); [​](https://docs.vizra.ai/api-reference/evaluation-class#llm-as-judge) LLM as Judge -------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/api-reference/evaluation-class#pass/fail-judge) Pass/Fail Judge Copy // Use LLM to evaluate pass/fail $this->judge($response) ->using(PassFailJudgeAgent::class) ->expectPass(); ### [​](https://docs.vizra.ai/api-reference/evaluation-class#quality-scoring) Quality Scoring Copy // Get quality score from LLM (0-10) $this->judge($response) ->using(QualityJudgeAgent::class) ->expectMinimumScore(7.5); ### [​](https://docs.vizra.ai/api-reference/evaluation-class#multi-dimensional-evaluation) Multi-dimensional Evaluation Copy // Evaluate multiple dimensions $this->judge($response) ->using(ComprehensiveJudgeAgent::class) ->expectMinimumScore([\ 'accuracy' => 8,\ 'helpfulness' => 7,\ 'clarity' => 7\ ]); [​](https://docs.vizra.ai/api-reference/evaluation-class#helper-methods) Helper Methods ------------------------------------------------------------------------------------------ ### [​](https://docs.vizra.ai/api-reference/evaluation-class#protected-methods) Protected Methods Copy // Reset assertion results (called automatically) $this->resetAssertionResults(); // Get the CSV column name for prompts $columnName = $this->getPromptCsvColumn(); // Returns 'prompt' by default // Record custom assertion result $this->recordAssertion( 'customCheck', true, // status 'Custom check passed', 'expected', 'actual' ); ### [​](https://docs.vizra.ai/api-reference/evaluation-class#assertion-results-structure) Assertion Results Structure Copy // Each assertion returns an array with: [\ 'assertion_method' => 'assertResponseContains',\ 'status' => 'pass' // or 'fail',\ 'message' => 'Response should contain substring.',\ 'expected' => 'expected text',\ 'actual' => 'actual response...'\ ] [​](https://docs.vizra.ai/api-reference/evaluation-class#result-structure) Result Structure ---------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/api-reference/evaluation-class#evaluaterow-return-format) evaluateRow() Return Format Copy // Your evaluateRow() method should return: [\ 'row_data' => $csvRowData, // Original CSV row\ 'llm_response' => $llmResponse, // Agent's response\ 'assertions' => $this->assertionResults, // Array of assertion results\ 'final_status' => 'pass', // 'pass', 'fail', or 'error'\ 'error' => null // Optional error message\ ] [​](https://docs.vizra.ai/api-reference/evaluation-class#complete-example) Complete Example ---------------------------------------------------------------------------------------------- CustomerSupportEvaluation.php Copy getPromptCsvColumn()] ?? ''; // Add customer context if available if (isset($csvRowData['customer_type'])) { $prompt = "Customer Type: " . $csvRowData['customer_type'] . "\n\n" . $prompt; } return $prompt; } public function evaluateRow(array $csvRowData, string $llmResponse): array { $this->resetAssertionResults(); // Basic quality checks $this->assertResponseIsNotEmpty($llmResponse); $this->assertNotToxic($llmResponse); $this->assertNoPII($llmResponse); // Test-specific assertions based on scenario $scenario = $csvRowData['scenario'] ?? ''; switch ($scenario) { case 'greeting': $this->assertResponseHasPositiveSentiment($llmResponse); $this->assertContainsAnyOf($llmResponse, ['hello', 'hi', 'welcome']); break; case 'complaint': $this->assertResponseContains($llmResponse, 'sorry'); $this->judge($llmResponse) ->using(PassFailJudgeAgent::class) ->expectPass('Response should be empathetic and helpful'); break; case 'technical_support': $this->assertReadabilityLevel($llmResponse, 10); $this->assertGrammarCorrect($llmResponse); break; } // Check for expected content if specified if (isset($csvRowData['must_contain'])) { $requiredTerms = explode(',', $csvRowData['must_contain']); $this->assertContainsAllOf($llmResponse, $requiredTerms); } // Determine overall pass/fail $allPassed = collect($this->assertionResults) ->every(fn($result) => $result['status'] === 'pass'); return [\ 'row_data' => $csvRowData,\ 'llm_response' => $llmResponse,\ 'assertions' => $this->assertionResults,\ 'final_status' => $allPassed ? 'pass' : 'fail',\ ]; } } **CSV File Example:** Copy user_message,scenario,customer_type,must_contain "Hello, I need help",greeting,new,help "My order hasn't arrived",complaint,vip,"sorry,assist" "How do I reset my password?",technical_support,regular,"reset,password" Structure your CSV files with clear columns for prompts, test scenarios, and expected outcomes. [​](https://docs.vizra.ai/api-reference/evaluation-class#next-steps) Next Steps ---------------------------------------------------------------------------------- [Events\ ------\ \ Event reference documentation](https://docs.vizra.ai/api-reference/events) [Evaluation Concepts\ -------------------\ \ Learn more about evaluations](https://docs.vizra.ai/concepts/evaluations) Was this page helpful? YesNo [Workflow Class Reference](https://docs.vizra.ai/api-reference/workflow-class) [Events API Reference](https://docs.vizra.ai/api-reference/events) ⌘I --- # Error Handling - Vizra ADK [Skip to main content](https://docs.vizra.ai/api-reference/error-handling#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation API Reference Error Handling [Documentation](https://docs.vizra.ai/) On this page * [Exception Types](https://docs.vizra.ai/api-reference/error-handling#exception-types) * [AgentNotFoundException](https://docs.vizra.ai/api-reference/error-handling#agentnotfoundexception) * [AgentConfigurationException](https://docs.vizra.ai/api-reference/error-handling#agentconfigurationexception) * [ToolExecutionException](https://docs.vizra.ai/api-reference/error-handling#toolexecutionexception) * [Handling Exceptions in Controllers](https://docs.vizra.ai/api-reference/error-handling#handling-exceptions-in-controllers) * [Error Handling in Commands](https://docs.vizra.ai/api-reference/error-handling#error-handling-in-commands) * [Error Handling in Services](https://docs.vizra.ai/api-reference/error-handling#error-handling-in-services) * [Best Practices](https://docs.vizra.ai/api-reference/error-handling#best-practices) * [1\. Use Specific Exception Types](https://docs.vizra.ai/api-reference/error-handling#1-use-specific-exception-types) * [2\. Provide Meaningful Error Messages](https://docs.vizra.ai/api-reference/error-handling#2-provide-meaningful-error-messages) * [3\. Log Errors with Context](https://docs.vizra.ai/api-reference/error-handling#3-log-errors-with-context) * [4\. Handle Errors at the Right Level](https://docs.vizra.ai/api-reference/error-handling#4-handle-errors-at-the-right-level) * [Creating Custom Exceptions](https://docs.vizra.ai/api-reference/error-handling#creating-custom-exceptions) * [Error Recovery Strategies](https://docs.vizra.ai/api-reference/error-handling#error-recovery-strategies) * [Graceful Degradation](https://docs.vizra.ai/api-reference/error-handling#graceful-degradation) * [Retry Logic](https://docs.vizra.ai/api-reference/error-handling#retry-logic) * [Testing Error Handling](https://docs.vizra.ai/api-reference/error-handling#testing-error-handling) * [Next Steps](https://docs.vizra.ai/api-reference/error-handling#next-steps) [​](https://docs.vizra.ai/api-reference/error-handling#exception-types) Exception Types ------------------------------------------------------------------------------------------ The framework includes three specialized exception classes that extend PHP’s base `\Exception` class: ### [​](https://docs.vizra.ai/api-reference/error-handling#agentnotfoundexception) AgentNotFoundException Thrown when attempting to access or execute an agent that doesn’t exist in the registry. AgentRegistry.php Copy use Vizra\VizraADK\Exceptions\AgentNotFoundException; // Example from AgentRegistry::getAgent() if (!isset($this->registeredAgents[$name])) { throw new AgentNotFoundException("Agent '{$name}' is not registered."); } ### [​](https://docs.vizra.ai/api-reference/error-handling#agentconfigurationexception) AgentConfigurationException Thrown when there are issues with agent configuration, such as invalid settings or missing required parameters. Configuration Validation Copy use Vizra\VizraADK\Exceptions\AgentConfigurationException; // Example usage if (!class_exists($config)) { throw new AgentConfigurationException( "Agent class '{$config}' does not exist." ); } ### [​](https://docs.vizra.ai/api-reference/error-handling#toolexecutionexception) ToolExecutionException Thrown when errors occur during tool execution, including invalid parameters or runtime failures. Tool Execution Copy use Vizra\VizraADK\Exceptions\ToolExecutionException; // Example in tool execution try { $result = $tool->execute($arguments, $context); } catch (\Exception $e) { throw new ToolExecutionException( "Tool '{$toolName}' failed: " . $e->getMessage() ); } [​](https://docs.vizra.ai/api-reference/error-handling#handling-exceptions-in-controllers) Handling Exceptions in Controllers -------------------------------------------------------------------------------------------------------------------------------- The `AgentApiController` demonstrates comprehensive exception handling: AgentApiController.php Copy use Vizra\VizraADK\Facades\Agent; use Vizra\VizraADK\Exceptions\AgentNotFoundException; use Vizra\VizraADK\Exceptions\ToolExecutionException; use Vizra\VizraADK\Exceptions\AgentConfigurationException; class AgentApiController extends Controller { public function handleAgentInteraction(Request $request): JsonResponse { try { // Check if agent exists if (!Agent::hasAgent($agentName)) { return response()->json([\ 'error' => "Agent '{$agentName}' is not registered or found.",\ 'message' => "Please ensure the agent is registered..."\ ], 404); } // Execute agent $response = Agent::run($agentName, $input, $sessionId); return response()->json([\ 'agent_name' => $agentName,\ 'session_id' => $sessionId,\ 'response' => $response,\ ]); } catch (AgentNotFoundException $e) { logger()->error("Agent not found: " . $e->getMessage()); return response()->json([\ 'error' => "Agent '{$agentName}' could not be found or loaded.",\ 'detail' => $e->getMessage()\ ], 404); } catch (ToolExecutionException $e) { logger()->error("Tool execution error for agent {$agentName}: " . $e->getMessage(), [\ 'exception' => $e\ ]); return response()->json([\ 'error' => 'A tool required by the agent failed to execute.',\ 'detail' => $e->getMessage()\ ], 500); } catch (AgentConfigurationException $e) { logger()->error("Agent configuration error for agent {$agentName}: " . $e->getMessage(), [\ 'exception' => $e\ ]); return response()->json([\ 'error' => 'Agent configuration error.',\ 'detail' => $e->getMessage()\ ], 500); } catch (\Throwable $e) { // Catch-all for unexpected errors logger()->error("Error during agent '{$agentName}' execution: " . $e->getMessage(), [\ 'exception' => $e\ ]); return response()->json([\ 'error' => 'An unexpected error occurred while processing your request.',\ 'detail' => $e->getMessage()\ ], 500); } } } [​](https://docs.vizra.ai/api-reference/error-handling#error-handling-in-commands) Error Handling in Commands ---------------------------------------------------------------------------------------------------------------- Artisan commands handle errors gracefully to provide helpful feedback: RunEvalCommand.php Copy // Example from RunEvalCommand try { $evaluation = $this->loadEvaluation($evaluationName); $results = $evaluation->run(); } catch (\Exception $e) { $this->error("Evaluation failed: " . $e->getMessage()); return 1; // Return non-zero exit code } [​](https://docs.vizra.ai/api-reference/error-handling#error-handling-in-services) Error Handling in Services ---------------------------------------------------------------------------------------------------------------- Services like `AgentRegistry` validate configuration and throw appropriate exceptions: AgentRegistry.php Copy public function getAgent(string $name): BaseAgent { if (!isset($this->registeredAgents[$name])) { throw new AgentNotFoundException("Agent '{$name}' is not registered."); } $config = $this->registeredAgents[$name]; if (is_string($config)) { if (!class_exists($config)) { throw new AgentConfigurationException( "Agent class '{$config}' does not exist." ); } $agent = new $config(); if (!$agent instanceof BaseAgent) { throw new AgentConfigurationException( "Agent class '{$config}' must extend BaseAgent." ); } return $agent; } // Handle array configuration... } [​](https://docs.vizra.ai/api-reference/error-handling#best-practices) Best Practices ---------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/api-reference/error-handling#1-use-specific-exception-types) 1\. Use Specific Exception Types Always throw the most specific exception type for the error scenario: Exception Best Practices Copy // Good - specific exception if (!$agent) { throw new AgentNotFoundException("Agent 'chatbot' not found"); } // Avoid - generic exception if (!$agent) { throw new \Exception("Agent not found"); } ### [​](https://docs.vizra.ai/api-reference/error-handling#2-provide-meaningful-error-messages) 2\. Provide Meaningful Error Messages Include context in error messages to help with debugging: Descriptive Error Messages Copy throw new ToolExecutionException( "Weather tool failed for location '{$location}': API key not configured" ); ### [​](https://docs.vizra.ai/api-reference/error-handling#3-log-errors-with-context) 3\. Log Errors with Context Always log errors with relevant context for debugging: Error Logging Copy catch (ToolExecutionException $e) { logger()->error("Tool execution failed", [\ 'agent' => $agentName,\ 'tool' => $e->getToolName(),\ 'session_id' => $sessionId,\ 'exception' => $e\ ]); } ### [​](https://docs.vizra.ai/api-reference/error-handling#4-handle-errors-at-the-right-level) 4\. Handle Errors at the Right Level Let exceptions bubble up to where they can be handled appropriately: Error Handling Layers Copy // In a tool - let exception bubble up public function execute(array $arguments, AgentContext $context): string { if (!isset($arguments['location'])) { throw new ToolExecutionException("Location parameter is required"); } // Tool logic... } // In the controller - handle and return appropriate response try { $result = $agent->run($input); } catch (ToolExecutionException $e) { return response()->json(['error' => $e->getMessage()], 400); } [​](https://docs.vizra.ai/api-reference/error-handling#creating-custom-exceptions) Creating Custom Exceptions ---------------------------------------------------------------------------------------------------------------- You can create custom exceptions for your specific use cases: app/Exceptions/ApiRateLimitException.php Copy service = $service; $this->retryAfter = $retryAfter; parent::__construct( "Rate limit exceeded for {$service}. Retry after {$retryAfter} seconds." ); } public function getRetryAfter(): int { return $this->retryAfter; } } [​](https://docs.vizra.ai/api-reference/error-handling#error-recovery-strategies) Error Recovery Strategies -------------------------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/api-reference/error-handling#graceful-degradation) Graceful Degradation Provide fallback behavior when non-critical operations fail: Fallback Pattern Copy public function execute(array $arguments, AgentContext $context): string { try { // Try to get weather from primary API $weather = $this->primaryApi->getWeather($location); } catch (ToolExecutionException $e) { logger()->warning("Primary weather API failed, using fallback", [\ 'error' => $e->getMessage()\ ]); // Fallback to secondary API try { $weather = $this->fallbackApi->getWeather($location); } catch (ToolExecutionException $e) { // Return cached or default response return json_encode([\ 'error' => 'Weather service temporarily unavailable',\ 'cached' => true,\ 'data' => $this->getCachedWeather($location)\ ]); } } return json_encode($weather); } ### [​](https://docs.vizra.ai/api-reference/error-handling#retry-logic) Retry Logic Implement retry logic for transient failures: Retry with Exponential Backoff Copy use Illuminate\Support\Facades\Http; public function executeWithRetry(callable $operation, int $maxAttempts = 3) { $attempt = 1; while ($attempt <= $maxAttempts) { try { return $operation(); } catch (ToolExecutionException $e) { if ($attempt === $maxAttempts) { throw $e; } logger()->warning("Operation failed, retrying", [\ 'attempt' => $attempt,\ 'max_attempts' => $maxAttempts,\ 'error' => $e->getMessage()\ ]); sleep(pow(2, $attempt)); // Exponential backoff $attempt++; } } } [​](https://docs.vizra.ai/api-reference/error-handling#testing-error-handling) Testing Error Handling -------------------------------------------------------------------------------------------------------- Always test your error handling paths: tests/Feature/ErrorHandlingTest.php Copy use Vizra\VizraADK\Exceptions\AgentNotFoundException; test('throws exception for non-existent agent', function () { $registry = app(AgentRegistry::class); expect(fn() => $registry->getAgent('non-existent')) ->toThrow(AgentNotFoundException::class, "Agent 'non-existent' is not registered."); }); test('handles tool execution failure gracefully', function () { $response = $this->postJson('/api/vizra/interact', [\ 'agent_name' => 'test_agent',\ 'input' => 'trigger tool failure'\ ]); $response->assertStatus(500) ->assertJson([\ 'error' => 'A tool required by the agent failed to execute.'\ ]); }); [​](https://docs.vizra.ai/api-reference/error-handling#next-steps) Next Steps -------------------------------------------------------------------------------- [Agent Class Reference\ ---------------------\ \ Agent class documentation](https://docs.vizra.ai/api-reference/agent-class) [Tool Development\ ----------------\ \ Build custom tools](https://docs.vizra.ai/api-reference/tool-class) [Testing Strategies\ ------------------\ \ Test your agents](https://docs.vizra.ai/best-practices/testing) Was this page helpful? YesNo [Events API Reference](https://docs.vizra.ai/api-reference/events) [Tracing Classes API Reference](https://docs.vizra.ai/api-reference/tracing-class) ⌘I --- # Architecture - Vizra ADK [Skip to main content](https://docs.vizra.ai/concepts/architecture#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Core Concepts Architecture [Documentation](https://docs.vizra.ai/) On this page * [Package Structure](https://docs.vizra.ai/concepts/architecture#package-structure) * [Core Components](https://docs.vizra.ai/concepts/architecture#core-components) * [Agent Hierarchy](https://docs.vizra.ai/concepts/architecture#agent-hierarchy) * [Service Container Bindings](https://docs.vizra.ai/concepts/architecture#service-container-bindings) * [Request Lifecycle](https://docs.vizra.ai/concepts/architecture#request-lifecycle) * [AgentContext](https://docs.vizra.ai/concepts/architecture#agentcontext) * [Tool Execution Flow](https://docs.vizra.ai/concepts/architecture#tool-execution-flow) * [Event System](https://docs.vizra.ai/concepts/architecture#event-system) * [Database Schema](https://docs.vizra.ai/concepts/architecture#database-schema) * [LLM Integration](https://docs.vizra.ai/concepts/architecture#llm-integration) * [Extending the Architecture](https://docs.vizra.ai/concepts/architecture#extending-the-architecture) * [Custom Service Providers](https://docs.vizra.ai/concepts/architecture#custom-service-providers) * [Custom Base Agents](https://docs.vizra.ai/concepts/architecture#custom-base-agents) * [Next Steps](https://docs.vizra.ai/concepts/architecture#next-steps) This page explains the internal architecture of Vizra ADK, helping you understand how the various components interact to power your AI agents. [​](https://docs.vizra.ai/concepts/architecture#package-structure) Package Structure --------------------------------------------------------------------------------------- Copy vizra-adk/src/ ├── Agents/ # Agent base classes and workflows ├── Contracts/ # Interfaces (ToolInterface, etc.) ├── Console/Commands/ # Artisan commands ├── Events/ # Laravel events for agent lifecycle ├── Exceptions/ # Custom exception classes ├── Execution/ # AgentExecutor for fluent execution ├── Facades/ # Agent and Workflow facades ├── Memory/ # Memory management ├── Models/ # Eloquent models (sessions, messages, traces) ├── Providers/ # Service providers and embedding providers ├── Services/ # Core services (Manager, Registry, Tracer) ├── System/ # AgentContext └── Tools/ # Built-in tools and MCP wrapper [​](https://docs.vizra.ai/concepts/architecture#core-components) Core Components ----------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/concepts/architecture#agent-hierarchy) Agent Hierarchy Copy BaseAgent (abstract) ├── BaseLlmAgent (abstract) │ └── GenericLlmAgent (for ad-hoc definitions) │ └── BaseWorkflowAgent (abstract) ├── SequentialWorkflow ├── ParallelWorkflow ├── ConditionalWorkflow └── LoopWorkflow **BaseAgent** defines the core contract - every agent must have a `name`, `description`, and implement `execute()`. **BaseLlmAgent** extends this with LLM-specific features: system prompts, tool registration, model selection, and conversation handling. **BaseWorkflowAgent** provides orchestration capabilities without LLM overhead - pure PHP logic for complex multi-agent coordination. ### [​](https://docs.vizra.ai/concepts/architecture#service-container-bindings) Service Container Bindings Vizra ADK registers these singletons in Laravel’s service container: | Service | Purpose | | --- | --- | | `AgentRegistry` | Stores and retrieves agent class mappings | | `AgentBuilder` | Fluent builder for configuring agents | | `AgentManager` | Central facade for running agents | | `StateManager` | Loads and persists agent context | | `MemoryManager` | Manages conversation history | | `Tracer` | Records execution spans for debugging | Access via dependency injection or the `Agent` facade: Copy use Vizra\VizraADK\Facades\Agent; // Via facade $agent = Agent::named('customer_support'); // Via container $manager = app(AgentManager::class); [​](https://docs.vizra.ai/concepts/architecture#request-lifecycle) Request Lifecycle --------------------------------------------------------------------------------------- When you run an agent, here’s what happens: Copy ┌─────────────────────────────────────────────────────────────────┐ │ 1. AgentExecutor::run($input) │ │ └─> Builds execution configuration (user, session, params) │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 2. AgentExecutor::go() │ │ └─> Resolves session ID, loads/creates AgentContext │ │ └─> Dispatches AgentExecutionStarting event │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 3. AgentManager::run() │ │ └─> Gets agent from AgentRegistry │ │ └─> Calls agent->execute($input, $context) │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 4. BaseLlmAgent::execute() │ │ └─> Builds system prompt │ │ └─> Sends to LLM via Prism PHP │ │ └─> Handles tool calls in a loop │ │ └─> Returns final response │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 5. StateManager::saveContext() │ │ └─> Persists conversation history │ │ └─> Saves state to database │ │ └─> Dispatches AgentExecutionFinished event │ └─────────────────────────────────────────────────────────────────┘ [​](https://docs.vizra.ai/concepts/architecture#agentcontext) AgentContext ----------------------------------------------------------------------------- `AgentContext` is the carrier object that flows through the entire execution: Copy class AgentContext { protected ?string $sessionId; protected mixed $userInput; protected array $state = []; protected Collection $conversationHistory; } It provides: * **Session tracking** - Links conversations across requests * **State storage** - Key-value store for execution data * **Conversation history** - Full message history for context Tools receive the context and can read/write state: Copy public function execute(array $arguments, AgentContext $context, AgentMemory $memory): string { // Read state $userId = $context->getState('user_id'); // Write state $context->setState('last_order_id', $orderId); return json_encode(['success' => true]); } [​](https://docs.vizra.ai/concepts/architecture#tool-execution-flow) Tool Execution Flow ------------------------------------------------------------------------------------------- When an LLM decides to call a tool: Copy ┌──────────────────────────────────────┐ │ LLM Response with tool_calls │ │ [{ name: "lookup_order", args: {}}] │ └──────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────┐ │ ToolCallInitiating Event │ │ (for logging/tracing) │ └──────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────┐ │ Tool::execute($args, $context) │ │ Returns JSON string result │ └──────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────┐ │ ToolCallCompleted Event │ │ Result sent back to LLM │ └──────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────┐ │ Loop continues until LLM │ │ returns final text response │ └──────────────────────────────────────┘ [​](https://docs.vizra.ai/concepts/architecture#event-system) Event System ----------------------------------------------------------------------------- Vizra ADK fires Laravel events at key points: | Event | When Fired | | --- | --- | | `AgentExecutionStarting` | Before agent execution begins | | `AgentExecutionFinished` | After execution completes | | `AgentResponseGenerated` | When final response is ready | | `LlmCallInitiating` | Before each LLM API call | | `LlmResponseReceived` | After LLM responds | | `ToolCallInitiating` | Before tool execution | | `ToolCallCompleted` | After tool returns | | `ToolCallFailed` | When tool throws exception | | `MemoryUpdated` | When memory is modified | | `StateUpdated` | When context state changes | Listen to these events for logging, analytics, or custom behavior: Copy // In EventServiceProvider protected $listen = [\ AgentExecutionFinished::class => [\ LogAgentMetrics::class,\ ],\ ]; [​](https://docs.vizra.ai/concepts/architecture#database-schema) Database Schema ----------------------------------------------------------------------------------- Vizra ADK creates these tables: | Table | Purpose | | --- | --- | | `agent_sessions` | Tracks conversation sessions | | `agent_messages` | Stores message history | | `agent_memories` | Persistent memory storage | | `agent_trace_spans` | Execution traces for debugging | | `agent_vector_memories` | Vector embeddings for RAG | | `agent_prompt_versions` | Prompt versioning | | `agent_prompt_usage` | Tracks which prompt versions are used | [​](https://docs.vizra.ai/concepts/architecture#llm-integration) LLM Integration ----------------------------------------------------------------------------------- Vizra ADK uses [Prism PHP](https://prismphp.org/) for LLM communication: Copy Your Agent │ ▼ Vizra ADK (BaseLlmAgent) │ ▼ Prism PHP │ ├──▶ OpenAI ├──▶ Anthropic ├──▶ Google Gemini └──▶ Ollama Configure providers in `config/vizra-adk.php`: Copy 'providers' => [\ 'openai' => [\ 'api_key' => env('OPENAI_API_KEY'),\ ],\ 'anthropic' => [\ 'api_key' => env('ANTHROPIC_API_KEY'),\ ],\ ], [​](https://docs.vizra.ai/concepts/architecture#extending-the-architecture) Extending the Architecture --------------------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/concepts/architecture#custom-service-providers) Custom Service Providers Register custom services that integrate with Vizra ADK: Copy class MyAgentServiceProvider extends ServiceProvider { public function boot() { // Register custom tools globally Agent::macro('withAnalytics', function ($tracker) { // Custom behavior return $this; }); } } ### [​](https://docs.vizra.ai/concepts/architecture#custom-base-agents) Custom Base Agents Create your own base agent with shared behavior: Copy abstract class MyBaseAgent extends BaseLlmAgent { protected function getSystemPrompt(): string { return "Company-wide instructions...\n\n" . $this->getAgentSpecificPrompt(); } abstract protected function getAgentSpecificPrompt(): string; } [​](https://docs.vizra.ai/concepts/architecture#next-steps) Next Steps ------------------------------------------------------------------------- * [Agents](https://docs.vizra.ai/concepts/agents) - Learn how to build agents * [Tools](https://docs.vizra.ai/concepts/tools) - Give agents capabilities * [Sessions & Memory](https://docs.vizra.ai/concepts/sessions-memory) - Understand persistence Was this page helpful? YesNo [Configuration](https://docs.vizra.ai/installation/configuration) [AI Agents](https://docs.vizra.ai/concepts/agents) ⌘I --- # Configuration - Vizra ADK [Skip to main content](https://docs.vizra.ai/installation/configuration#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Getting Started Configuration [Documentation](https://docs.vizra.ai/) On this page * [Your Configuration Hub](https://docs.vizra.ai/installation/configuration#your-configuration-hub) * [Choose Your AI Provider](https://docs.vizra.ai/installation/configuration#choose-your-ai-provider) * [Pick Your Model](https://docs.vizra.ai/installation/configuration#pick-your-model) * [Fine-Tune Your AI’s Personality](https://docs.vizra.ai/installation/configuration#fine-tune-your-ai%E2%80%99s-personality) * [Your API Keys](https://docs.vizra.ai/installation/configuration#your-api-keys) * [The Complete Configuration Blueprint](https://docs.vizra.ai/installation/configuration#the-complete-configuration-blueprint) * [Agent Teamwork Settings](https://docs.vizra.ai/installation/configuration#agent-teamwork-settings) * [Database Architecture](https://docs.vizra.ai/installation/configuration#database-architecture) * [Debug Like a Detective](https://docs.vizra.ai/installation/configuration#debug-like-a-detective) * [Web Dashboard Settings](https://docs.vizra.ai/installation/configuration#web-dashboard-settings) * [OpenAI API Compatibility](https://docs.vizra.ai/installation/configuration#openai-api-compatibility) * [Model Context Protocol (MCP) Servers](https://docs.vizra.ai/installation/configuration#model-context-protocol-mcp-servers) * [Custom MCP Servers](https://docs.vizra.ai/installation/configuration#custom-mcp-servers) * [The Configuration Priority Game](https://docs.vizra.ai/installation/configuration#the-configuration-priority-game) * [Organize Your Code](https://docs.vizra.ai/installation/configuration#organize-your-code) * [Environment Magic](https://docs.vizra.ai/installation/configuration#environment-magic) * [You’re All Set!](https://docs.vizra.ai/installation/configuration#you%E2%80%99re-all-set) Think of configuration as painting your masterpiece! With Vizra ADK, you have all the colors (options) at your fingertips. Let’s make your AI agents work exactly how you want them to! [​](https://docs.vizra.ai/installation/configuration#your-configuration-hub) Your Configuration Hub ------------------------------------------------------------------------------------------------------ After installing Vizra ADK, your shiny new configuration file lives at: Copy config/vizra-adk.php Haven’t published it yet? No worries! Run this magic command: Terminal Copy php artisan vendor:publish --tag=vizra-adk-config [​](https://docs.vizra.ai/installation/configuration#choose-your-ai-provider) Choose Your AI Provider -------------------------------------------------------------------------------------------------------- Default Provider ---------------- Pick your favorite AI companion! Set it in your `.env` file: .env Copy VIZRA_ADK_DEFAULT_PROVIDER=openai Available Providers ------------------- Choose from these amazing AI providers: * `openai` - GPT models * `anthropic` - Claude models * `gemini` - Google’s finest ### [​](https://docs.vizra.ai/installation/configuration#pick-your-model) Pick Your Model Choose the AI model that powers your agents’ brilliance: .env Copy VIZRA_ADK_DEFAULT_MODEL=gemini-pro * OpenAI Models * Anthropic Models * Google Models * `gpt-4-turbo` * `gpt-3.5-turbo` * `claude-3-opus-20240229` * `claude-3-sonnet-20240229` * `gemini-pro` * `gemini-1.5-pro` ### [​](https://docs.vizra.ai/installation/configuration#fine-tune-your-ai%E2%80%99s-personality) Fine-Tune Your AI’s Personality Adjust these dials to make your AI agents more creative or focused! .env Copy # Default generation parameters VIZRA_ADK_DEFAULT_TEMPERATURE=0.7 # null uses provider default VIZRA_ADK_DEFAULT_MAX_TOKENS=2000 # null uses provider default VIZRA_ADK_DEFAULT_TOP_P=0.9 # null uses provider default | Parameter | Description | | --- | --- | | **Temperature** | Controls creativity: 0 = focused, 1 = wild imagination! | | **Max Tokens** | Maximum response length. More tokens = longer answers! | | **Top P** | Controls diversity. Lower = more focused responses! | ### [​](https://docs.vizra.ai/installation/configuration#your-api-keys) Your API Keys Time to connect to the AI magic! Add your provider API keys: .env Copy # OpenAI OPENAI_API_KEY=your-openai-api-key # Anthropic Claude ANTHROPIC_API_KEY=your-anthropic-api-key # Google Gemini GOOGLE_API_KEY=your-google-api-key **Security First!** Never commit API keys to your repository! Keep them safe in your `.env` file and add it to `.gitignore`. [​](https://docs.vizra.ai/installation/configuration#the-complete-configuration-blueprint) The Complete Configuration Blueprint ---------------------------------------------------------------------------------------------------------------------------------- Here’s your complete configuration file in all its glory! config/vizra-adk.php Copy return [\ /**\ * Default LLM provider to use with Prism-PHP.\ *\ * Supported providers:\ * - 'openai' - OpenAI (GPT-4, GPT-3.5, etc.)\ * - 'anthropic' - Anthropic (Claude models)\ * - 'gemini' or 'google' - Google Gemini\ * - 'deepseek' - DeepSeek AI\ * - 'ollama' - Ollama (local models)\ * - 'mistral' - Mistral AI\ * - 'groq' - Groq (Fast inference)\ * - 'xai' or 'grok' - xAI (Grok models)\ */\ 'default_provider' => env('VIZRA_ADK_DEFAULT_PROVIDER', 'openai'),\ \ /**\ * Default LLM model to use with Prism-PHP.\ */\ 'default_model' => env('VIZRA_ADK_DEFAULT_MODEL', 'gemini-1.5-flash'),\ \ /**\ * Default generation parameters for LLM requests.\ */\ 'default_generation_params' => [\ 'temperature' => env('VIZRA_ADK_DEFAULT_TEMPERATURE', null),\ 'max_tokens' => env('VIZRA_ADK_DEFAULT_MAX_TOKENS', null),\ 'top_p' => env('VIZRA_ADK_DEFAULT_TOP_P', null),\ ],\ \ /**\ * Sub-agent delegation settings.\ */\ 'max_delegation_depth' => env('VIZRA_ADK_MAX_DELEGATION_DEPTH', 5),\ \ /**\ * Database table names used by the package.\ */\ 'tables' => [\ 'agent_sessions' => 'agent_sessions',\ 'agent_messages' => 'agent_messages',\ 'agent_memories' => 'agent_memories',\ 'agent_vector_memories' => 'agent_vector_memories',\ 'agent_trace_spans' => 'agent_trace_spans',\ ],\ \ /**\ * Tracing configuration.\ */\ 'tracing' => [\ 'enabled' => env('VIZRA_ADK_TRACING_ENABLED', true),\ 'cleanup_days' => env('VIZRA_ADK_TRACING_CLEANUP_DAYS', 30),\ ],\ \ /**\ * Namespaces for user-defined classes.\ */\ 'namespaces' => [\ 'agents' => 'App\\Agents',\ 'tools' => 'App\\Tools',\ 'evaluations' => 'App\\Evaluations',\ ],\ \ /**\ * Routes configuration.\ */\ 'routes' => [\ 'enabled' => true,\ 'prefix' => 'api/vizra-adk',\ 'middleware' => ['api'],\ 'web' => [\ 'enabled' => env('VIZRA_ADK_WEB_ENABLED', true),\ 'prefix' => 'vizra',\ 'middleware' => ['web'],\ ],\ ],\ \ /**\ * OpenAI API Compatibility Configuration\ */\ 'openai_model_mapping' => [\ 'gpt-4' => env('VIZRA_ADK_OPENAI_GPT4_AGENT', 'chat_agent'),\ 'gpt-4-turbo' => env('VIZRA_ADK_OPENAI_GPT4_TURBO_AGENT', 'chat_agent'),\ 'gpt-3.5-turbo' => env('VIZRA_ADK_OPENAI_GPT35_AGENT', 'chat_agent'),\ ],\ \ 'default_chat_agent' => env('VIZRA_ADK_DEFAULT_CHAT_AGENT', 'chat_agent'),\ \ /**\ * Model Context Protocol (MCP) Configuration\ */\ 'mcp_servers' => [\ 'filesystem' => [\ 'command' => 'npx',\ 'args' => [\ '@modelcontextprotocol/server-filesystem',\ env('MCP_FILESYSTEM_PATH', storage_path('app')),\ ],\ 'enabled' => env('MCP_FILESYSTEM_ENABLED', false),\ 'timeout' => 30,\ ],\ // ... more servers\ ],\ ]; [​](https://docs.vizra.ai/installation/configuration#agent-teamwork-settings) Agent Teamwork Settings -------------------------------------------------------------------------------------------------------- Let your agents work together! Control how deep the delegation rabbit hole goes: .env Copy # Maximum depth for nested sub-agent delegation VIZRA_ADK_MAX_DELEGATION_DEPTH=5 This clever safety net prevents your agents from playing endless “pass the task” - avoiding infinite loops and keeping your app responsive! [​](https://docs.vizra.ai/installation/configuration#database-architecture) Database Architecture ---------------------------------------------------------------------------------------------------- Vizra ADK organizes your AI data in these neat tables: | Table | Purpose | | --- | --- | | `agent_sessions` | Keeps track of all your conversation sessions | | `agent_messages` | Stores the complete message history | | `agent_memories` | Your agents’ long-term memories live here | | `agent_vector_memories` | Vector embeddings for semantic search | | `agent_trace_spans` | Debug traces for when you need to investigate | Got naming conflicts? No worries! You can customize these table names in your config file. [​](https://docs.vizra.ai/installation/configuration#debug-like-a-detective) Debug Like a Detective ------------------------------------------------------------------------------------------------------ Turn on tracing to see exactly what your agents are thinking! .env Copy # Enable/disable tracing VIZRA_ADK_TRACING_ENABLED=true # Days to keep trace data before cleanup VIZRA_ADK_TRACING_CLEANUP_DAYS=30 Keep your database tidy by removing old traces: Terminal Copy php artisan vizra:trace:cleanup --days=7 [​](https://docs.vizra.ai/installation/configuration#web-dashboard-settings) Web Dashboard Settings ------------------------------------------------------------------------------------------------------ Toggle your beautiful web dashboard on or off: .env Copy # Enable/disable web interface VIZRA_ADK_WEB_ENABLED=true Your dashboard lives at these URLs: | Dashboard | URL | | --- | --- | | Main Dashboard | `/vizra` | | Chat Interface | `/vizra/chat` | | Evaluation Runner | `/vizra/eval` | [​](https://docs.vizra.ai/installation/configuration#openai-api-compatibility) OpenAI API Compatibility ---------------------------------------------------------------------------------------------------------- Make your Vizra agents work seamlessly with OpenAI-compatible clients! Map OpenAI model names to your custom agents: config/vizra-adk.php Copy 'openai_model_mapping' => [\ 'gpt-4' => env('VIZRA_ADK_OPENAI_GPT4_AGENT', 'chat_agent'),\ 'gpt-4-turbo' => env('VIZRA_ADK_OPENAI_GPT4_TURBO_AGENT', 'chat_agent'),\ 'gpt-3.5-turbo' => env('VIZRA_ADK_OPENAI_GPT35_AGENT', 'chat_agent'),\ ], 'default_chat_agent' => env('VIZRA_ADK_DEFAULT_CHAT_AGENT', 'chat_agent'), This lets any OpenAI-compatible application use your Vizra agents! Just point them to your `/api/vizra-adk/chat/completions` endpoint. [​](https://docs.vizra.ai/installation/configuration#model-context-protocol-mcp-servers) Model Context Protocol (MCP) Servers -------------------------------------------------------------------------------------------------------------------------------- Supercharge your agents with MCP servers! These give your agents access to external tools and services: Filesystem Server ----------------- .env Copy MCP_FILESYSTEM_ENABLED=true MCP_FILESYSTEM_PATH=/path/to/allowed/dir Let agents read and write files safely! GitHub Server ------------- .env Copy MCP_GITHUB_ENABLED=true GITHUB_TOKEN=your-github-token Access repos, issues, and PRs! PostgreSQL Server ----------------- .env Copy MCP_POSTGRES_ENABLED=true MCP_POSTGRES_URL=postgresql://... Query and manage databases! Brave Search Server ------------------- .env Copy MCP_BRAVE_SEARCH_ENABLED=true BRAVE_API_KEY=your-brave-api-key Search the web for real-time info! ### [​](https://docs.vizra.ai/installation/configuration#custom-mcp-servers) Custom MCP Servers You can even add your own MCP servers: config/vizra-adk.php Copy 'custom_api' => [\ 'command' => 'python',\ 'args' => ['/path/to/your/mcp-server.py'],\ 'enabled' => true,\ 'timeout' => 60,\ ], [​](https://docs.vizra.ai/installation/configuration#the-configuration-priority-game) The Configuration Priority Game ------------------------------------------------------------------------------------------------------------------------ When multiple configs compete, here’s who takes the crown (from highest to lowest priority): | Priority | Source | Example | | --- | --- | --- | | 1st | Runtime Methods | `$agent->setTemperature(0.2)` | | 2nd | Agent Class Properties | `protected ?float $temperature = 0.7;` | | 3rd | Environment Variables | `VIZRA_ADK_DEFAULT_TEMPERATURE=0.5` | | 4th | Config File Defaults | `config/vizra-adk.php` | [​](https://docs.vizra.ai/installation/configuration#organize-your-code) Organize Your Code ---------------------------------------------------------------------------------------------- Keep your code neat and tidy with these default namespaces: | Type | Namespace | | --- | --- | | Agents | `App\Agents` | | Tools | `App\Tools` | | Evaluations | `App\Evaluations` | **Feeling creative?** You can totally customize these namespaces in your config file to match your project’s vibe! [​](https://docs.vizra.ai/installation/configuration#environment-magic) Environment Magic -------------------------------------------------------------------------------------------- Different settings for different environments? We’ve got you covered! * Local Development * Production .env.local Copy VIZRA_ADK_TRACING_ENABLED=true VIZRA_ADK_DEFAULT_MODEL=gpt-3.5-turbo VIZRA_ADK_WEB_ENABLED=true Debug everything, use cheaper models! .env.production Copy VIZRA_ADK_TRACING_ENABLED=false VIZRA_ADK_DEFAULT_MODEL=gpt-4-turbo VIZRA_ADK_WEB_ENABLED=false Optimized for performance & security! [​](https://docs.vizra.ai/installation/configuration#you%E2%80%99re-all-set) You’re All Set! ----------------------------------------------------------------------------------------------- Congratulations! Your Vizra ADK is now perfectly configured. Time to build some amazing AI agents! [Build Your First Agent\ ----------------------\ \ Learn how to create intelligent agents that can think, remember, and solve problems!](https://docs.vizra.ai/concepts/agents) [Master the CLI\ --------------\ \ Discover powerful Artisan commands to supercharge your development workflow!](https://docs.vizra.ai/api-reference/artisan-commands) Was this page helpful? YesNo [Requirements Checklist](https://docs.vizra.ai/installation/requirements) [Architecture](https://docs.vizra.ai/concepts/architecture) ⌘I --- # Agent Class Reference - Vizra ADK [Skip to main content](https://docs.vizra.ai/api-reference/agent-class#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation API Reference Agent Class Reference [Documentation](https://docs.vizra.ai/) On this page * [The Agent Family Tree](https://docs.vizra.ai/api-reference/agent-class#the-agent-family-tree) * [Agent Properties - Your Agent’s DNA](https://docs.vizra.ai/api-reference/agent-class#agent-properties-your-agent%E2%80%99s-dna) * [Required Properties](https://docs.vizra.ai/api-reference/agent-class#required-properties) * [Optional Properties](https://docs.vizra.ai/api-reference/agent-class#optional-properties) * [Static Method - The Universal Entry Point](https://docs.vizra.ai/api-reference/agent-class#static-method-the-universal-entry-point) * [run()](https://docs.vizra.ai/api-reference/agent-class#run) * [Common Usage Patterns](https://docs.vizra.ai/api-reference/agent-class#common-usage-patterns) * [Conversational Interactions](https://docs.vizra.ai/api-reference/agent-class#conversational-interactions) * [Event Processing](https://docs.vizra.ai/api-reference/agent-class#event-processing) * [Data Analysis](https://docs.vizra.ai/api-reference/agent-class#data-analysis) * [Batch Processing](https://docs.vizra.ai/api-reference/agent-class#batch-processing) * [Monitoring & Alerts](https://docs.vizra.ai/api-reference/agent-class#monitoring-%26-alerts) * [Report Generation](https://docs.vizra.ai/api-reference/agent-class#report-generation) * [Instance Methods (BaseLlmAgent)](https://docs.vizra.ai/api-reference/agent-class#instance-methods-basellmagent) * [Core Methods](https://docs.vizra.ai/api-reference/agent-class#core-methods) * [Configuration Methods](https://docs.vizra.ai/api-reference/agent-class#configuration-methods) * [Dynamic Prompts (via VersionablePrompts trait)](https://docs.vizra.ai/api-reference/agent-class#dynamic-prompts-via-versionableprompts-trait) * [Tool Management](https://docs.vizra.ai/api-reference/agent-class#tool-management) * [Sub-Agent Management](https://docs.vizra.ai/api-reference/agent-class#sub-agent-management) * [Protected Methods (Override in Your Agent)](https://docs.vizra.ai/api-reference/agent-class#protected-methods-override-in-your-agent) * [Sub-Agent Registration](https://docs.vizra.ai/api-reference/agent-class#sub-agent-registration) * [Lifecycle Hooks](https://docs.vizra.ai/api-reference/agent-class#lifecycle-hooks) * [Sub-Agent Delegation Hooks](https://docs.vizra.ai/api-reference/agent-class#sub-agent-delegation-hooks) * [AgentExecutor Methods](https://docs.vizra.ai/api-reference/agent-class#agentexecutor-methods) * [Complete Example](https://docs.vizra.ai/api-reference/agent-class#complete-example) * [Complete Usage Examples](https://docs.vizra.ai/api-reference/agent-class#complete-usage-examples) * [Next Steps](https://docs.vizra.ai/api-reference/agent-class#next-steps) Think of `BaseLlmAgent` as the DNA of your AI agents. Every intelligent behavior, every smart response, every amazing capability starts here. [​](https://docs.vizra.ai/api-reference/agent-class#the-agent-family-tree) The Agent Family Tree --------------------------------------------------------------------------------------------------- Understanding the class hierarchy is like knowing your agent’s family tree. Here’s how everything connects: Agent Class Hierarchy Copy namespace Vizra\VizraADK\Agents; abstract class BaseAgent { // Base contract for all agents } abstract class BaseLlmAgent extends BaseAgent { // LLM-powered agent implementation } [​](https://docs.vizra.ai/api-reference/agent-class#agent-properties-your-agent%E2%80%99s-dna) Agent Properties - Your Agent’s DNA ------------------------------------------------------------------------------------------------------------------------------------- These properties are like your agent’s personality traits. Set them right, and your agent will be amazing. ### [​](https://docs.vizra.ai/api-reference/agent-class#required-properties) Required Properties $name ----- **Type:** `string` (required)Your agent’s unique identifier. Like a superhero name, it should be memorable and descriptive. No two agents can share the same name. Copy protected string $name = 'customer_support'; $description ------------ **Type:** `string` (required)Tell everyone what your agent does. This human-readable description helps you and your team understand the agent’s purpose at a glance. Copy protected string $description = 'Helps customers with support inquiries'; ### [​](https://docs.vizra.ai/api-reference/agent-class#optional-properties) Optional Properties | Property | Type | Default | Description | | --- | --- | --- | --- | | `$instructions` | string | `''` | System prompt for the agent | | `$promptVersion` | ?string | `null` | Default prompt version to use | | `$model` | string | `''` | LLM model to use (e.g., ‘gpt-4o’, ‘claude-3-opus’) | | `$provider` | ?Provider | `null` | LLM provider (OpenAI, Anthropic, Gemini) | | `$temperature` | ?float | `null` | Response creativity (0-1) | | `$maxTokens` | ?int | `null` | Maximum response tokens | | `$topP` | ?float | `null` | Nucleus sampling parameter | | `$streaming` | bool | `false` | Enable streaming responses | | `$tools` | array | `[]` | Array of tool class names | [​](https://docs.vizra.ai/api-reference/agent-class#static-method-the-universal-entry-point) Static Method - The Universal Entry Point ----------------------------------------------------------------------------------------------------------------------------------------- All agents use a single, powerful entry point - the `run()` method. This unified approach keeps things simple and consistent across all your agents. ### [​](https://docs.vizra.ai/api-reference/agent-class#run) run() Method Signature Copy public static function run(mixed $input): AgentExecutor The `run()` method creates a fluent agent executor that you can configure with various options before executing. It’s your Swiss Army knife for all agent interactions. Whether you’re asking questions, processing data, analyzing events, or monitoring systems - it all starts with `run()`. The input you provide and the context you set determine what your agent does. ### [​](https://docs.vizra.ai/api-reference/agent-class#common-usage-patterns) Common Usage Patterns #### [​](https://docs.vizra.ai/api-reference/agent-class#conversational-interactions) Conversational Interactions Perfect for chat-like interactions where you need natural language responses. Copy // Ask a question $response = CustomerSupportAgent::run('Where is my order?') ->forUser($user) ->go(); // Have a conversation with context $response = CustomerSupportAgent::run('I need help with shipping') ->withSession($sessionId) ->withContext(['order_id' => $orderId]) ->go(); #### [​](https://docs.vizra.ai/api-reference/agent-class#event-processing) Event Processing Handle events, webhooks, or triggers from your application. Copy // Process an event $response = NotificationAgent::run($orderCreatedEvent) ->forUser($user) ->go(); // Handle webhook data $response = WebhookAgent::run($webhookPayload) ->withContext(['source' => 'stripe']) ->go(); #### [​](https://docs.vizra.ai/api-reference/agent-class#data-analysis) Data Analysis Analyze data, detect patterns, or generate insights. Copy // Analyze payment data $response = FraudDetectionAgent::run($paymentData) ->withContext(['risk_threshold' => 0.7]) ->go(); // Generate insights $response = AnalyticsAgent::run($salesData) ->withContext(['period' => 'last_quarter']) ->go(); #### [​](https://docs.vizra.ai/api-reference/agent-class#batch-processing) Batch Processing Process large datasets or perform batch operations asynchronously. Copy // Process batch data $response = DataProcessorAgent::run($largeDataset) ->async() ->onQueue('processing') ->go(); // Import data with progress tracking $response = ImportAgent::run($csvFile) ->withContext(['notify_on_complete' => true]) ->async() ->go(); #### [​](https://docs.vizra.ai/api-reference/agent-class#monitoring-&-alerts) Monitoring & Alerts Monitor systems, metrics, or conditions continuously. Copy // Monitor system metrics $response = SystemMonitorAgent::run($metrics) ->onQueue('monitoring') ->withContext(['alert_threshold' => 90]) ->go(); // Health checks $response = HealthCheckAgent::run($serviceEndpoints) ->delay(60) // Check every minute ->go(); #### [​](https://docs.vizra.ai/api-reference/agent-class#report-generation) Report Generation Generate reports, summaries, or formatted outputs. Copy // Generate daily report $response = ReportAgent::run('daily_sales') ->withContext(['date' => today()]) ->go(); // Create summary with specific format $response = SummaryAgent::run($quarterlyData) ->withContext(['format' => 'executive_summary']) ->go(); [​](https://docs.vizra.ai/api-reference/agent-class#instance-methods-basellmagent) Instance Methods (BaseLlmAgent) --------------------------------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/api-reference/agent-class#core-methods) Core Methods Copy // Execute the agent's primary logic (must be implemented) public function run(mixed $input, AgentContext $context): mixed // Get agent properties public function getName(): string public function getDescription(): string ### [​](https://docs.vizra.ai/api-reference/agent-class#configuration-methods) Configuration Methods Copy // Getters public function getModel(): string public function getProvider(): Provider public function getInstructions(): string public function getInstructionsWithMemory(AgentContext $context): string public function getTemperature(): ?float public function getMaxTokens(): ?int public function getTopP(): ?float public function getStreaming(): bool // Setters public function setInstructions(string $instructions): static public function setModel(string $model): static public function setProvider(Provider $provider): static public function setTemperature(?float $temperature): static public function setMaxTokens(?int $maxTokens): static public function setTopP(?float $topP): static public function setStreaming(bool $streaming): static ### [​](https://docs.vizra.ai/api-reference/agent-class#dynamic-prompts-via-versionableprompts-trait) Dynamic Prompts (via VersionablePrompts trait) Copy // Prompt version management public function setPromptVersion(?string $version): static public function getPromptVersion(): ?string public function setPromptOverride(string $prompt): static public function getAvailablePromptVersions(): array ### [​](https://docs.vizra.ai/api-reference/agent-class#tool-management) Tool Management Copy public function loadTools(): void public function getLoadedTools(): array ### [​](https://docs.vizra.ai/api-reference/agent-class#sub-agent-management) Sub-Agent Management Copy public function getSubAgent(string $name): ?BaseLlmAgent public function getLoadedSubAgents(): array [​](https://docs.vizra.ai/api-reference/agent-class#protected-methods-override-in-your-agent) Protected Methods (Override in Your Agent) ------------------------------------------------------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/api-reference/agent-class#sub-agent-registration) Sub-Agent Registration Copy /** * Sub-agents available for delegation. * The framework automatically generates names from class names: * - TechnicalSupportAgent -> technical_support * - BillingSupportAgent -> billing_support * - SalesAgent -> sales */ protected array $subAgents = [\ TechnicalSupportAgent::class,\ BillingSupportAgent::class,\ SalesAgent::class,\ ]; ### [​](https://docs.vizra.ai/api-reference/agent-class#lifecycle-hooks) Lifecycle Hooks Copy // Called before sending messages to LLM public function beforeLlmCall(array $inputMessages, AgentContext $context): array { // Modify messages, start tracing, etc. return $inputMessages; } // Called after receiving LLM response public function afterLlmResponse(Response|Generator $response, AgentContext $context): mixed { // Process response, access token usage, etc. return $response; } // Called before tool execution public function beforeToolCall(string $toolName, array $arguments, AgentContext $context): array { // Modify tool arguments before execution return $arguments; } // Called after tool execution public function afterToolResult(string $toolName, string $result, AgentContext $context): string { // Process tool results return $result; } ### [​](https://docs.vizra.ai/api-reference/agent-class#sub-agent-delegation-hooks) Sub-Agent Delegation Hooks Copy // Called before delegating to sub-agent public function beforeSubAgentDelegation( string $subAgentName, string $taskInput, string $contextSummary, AgentContext $parentContext ): array { // Returns [subAgentName, taskInput, contextSummary] return [$subAgentName, $taskInput, $contextSummary]; } // Called after sub-agent completes public function afterSubAgentDelegation( string $subAgentName, string $taskInput, string $subAgentResult, AgentContext $parentContext, AgentContext $subAgentContext ): string { // Process and return the result return $subAgentResult; } [​](https://docs.vizra.ai/api-reference/agent-class#agentexecutor-methods) AgentExecutor Methods --------------------------------------------------------------------------------------------------- The `AgentExecutor` provides a fluent API for configuring agent execution: Copy // User context public function forUser(?Model $user): self // Session management public function withSession(string $sessionId): self // Context data public function withContext(array $context): self // Prompt versioning public function withPromptVersion(string $version): self // Streaming public function streaming(bool $enabled = true): self // Parameters public function withParameters(array $parameters): self public function temperature(float $temperature): self public function maxTokens(int $maxTokens): self // Async execution public function async(bool $enabled = true): self public function onQueue(string $queue): self public function delay(int $seconds): self public function tries(int $tries): self public function timeout(int $seconds): self // Multimodal support public function withImage(string $path, ?string $mimeType = null): self public function withImageFromBase64(string $base64Data, string $mimeType): self public function withImageFromUrl(string $url): self public function withDocument(string $path, ?string $mimeType = null): self public function withDocumentFromBase64(string $base64Data, string $mimeType): self public function withDocumentFromUrl(string $url): self // Execute the agent public function go(): mixed [​](https://docs.vizra.ai/api-reference/agent-class#complete-example) Complete Example ----------------------------------------------------------------------------------------- CustomerSupportAgent.php Copy > */ protected array $tools = [\ OrderLookupTool::class,\ RefundProcessorTool::class,\ EmailSenderTool::class,\ ]; // Sub-agents available for delegation protected array $subAgents = [\ TechnicalSupportAgent::class, // Becomes: technical_support\ BillingAgent::class, // Becomes: billing\ ]; // Customize LLM call behavior public function beforeLlmCall(array $inputMessages, AgentContext $context): array { // Add customer context to messages if available if ($userId = $context->getState('user_id')) { logger()->info('Processing request for user', ['user_id' => $userId]); } return parent::beforeLlmCall($inputMessages, $context); } // Process response after LLM call public function afterLlmResponse(Response|Generator $response, AgentContext $context): mixed { if ($response instanceof Response) { // Log token usage for monitoring if ($response->usage) { logger()->info('Token usage', [\ 'input_tokens' => $response->usage->inputTokens ?? 0,\ 'output_tokens' => $response->usage->outputTokens ?? 0,\ ]); } } return parent::afterLlmResponse($response, $context); } } [​](https://docs.vizra.ai/api-reference/agent-class#complete-usage-examples) Complete Usage Examples ------------------------------------------------------------------------------------------------------- Let’s see how the unified `run()` method handles all your agent needs. From simple queries to complex multimodal interactions, it’s all here. Real-World Examples Copy // Basic conversation $response = CustomerSupportAgent::run('How do I reset my password?') ->go(); // With user context and session $response = CustomerSupportAgent::run('Show me my recent orders') ->forUser($user) ->withSession($sessionId) ->go(); // Streaming response for real-time output $stream = CustomerSupportAgent::run('Explain our refund policy') ->streaming() ->go(); foreach ($stream as $chunk) { echo $chunk; // Display as it streams } // Async processing for heavy workloads $job = DataProcessorAgent::run($supportTickets) ->async() ->onQueue('support') ->timeout(3600) // 1 hour timeout ->go(); // Multimodal with images $response = ProductAnalysisAgent::run('What\'s wrong with this product?') ->withImage('/path/to/product-photo.jpg') ->go(); // Complex analysis with multiple inputs $response = FinancialAdvisorAgent::run('Analyze my portfolio') ->withDocument('/path/to/portfolio.pdf') ->withContext([\ 'risk_tolerance' => 'moderate',\ 'investment_horizon' => '10_years'\ ]) ->temperature(0.3) // Lower temperature for financial advice ->go(); // Event-driven processing $response = OrderProcessingAgent::run($orderEvent) ->withContext(['priority' => 'high']) ->forUser($customer) ->go(); // Scheduled monitoring $response = SystemHealthAgent::run($systemMetrics) ->onQueue('monitoring') ->delay(300) // Check every 5 minutes ->tries(3) // Retry up to 3 times ->go(); **Agent Best Practices:** * Keep agent instructions focused and clear * Override lifecycle hooks for custom behavior * Use appropriate temperature settings for your use case * Implement error handling for robustness * Test agents thoroughly with evaluations * Monitor token usage and costs [​](https://docs.vizra.ai/api-reference/agent-class#next-steps) Next Steps ----------------------------------------------------------------------------- [Tool Class\ ----------\ \ Tool class reference](https://docs.vizra.ai/api-reference/tool-class) [Agent Concepts\ --------------\ \ Learn more about agents](https://docs.vizra.ai/concepts/agents) Was this page helpful? YesNo [Artisan Commands](https://docs.vizra.ai/api-reference/artisan-commands) [Tool Class Reference](https://docs.vizra.ai/api-reference/tool-class) ⌘I --- # LLM Providers - Vizra ADK [Skip to main content](https://docs.vizra.ai/integrations/providers#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Integrations LLM Providers [Documentation](https://docs.vizra.ai/) On this page * [Quick Setup](https://docs.vizra.ai/integrations/providers#quick-setup) * [1\. Set Your Default Provider](https://docs.vizra.ai/integrations/providers#1-set-your-default-provider) * [2\. Or Configure Per Agent](https://docs.vizra.ai/integrations/providers#2-or-configure-per-agent) * [3\. Or Switch on the Fly](https://docs.vizra.ai/integrations/providers#3-or-switch-on-the-fly) * [Supported Providers](https://docs.vizra.ai/integrations/providers#supported-providers) * [Cool Provider Tricks](https://docs.vizra.ai/integrations/providers#cool-provider-tricks) * [Choosing the Right Provider](https://docs.vizra.ai/integrations/providers#choosing-the-right-provider) * [API Keys Setup](https://docs.vizra.ai/integrations/providers#api-keys-setup) * [Next Steps](https://docs.vizra.ai/integrations/providers#next-steps) Not all AI models are created equal. Some excel at creative writing, others at coding, and some are just blazing fast. With Vizra ADK, you can mix and match providers to give each agent the perfect brain for its job. [​](https://docs.vizra.ai/integrations/providers#quick-setup) Quick Setup ---------------------------------------------------------------------------- Getting started is as easy as 1-2-3. ### [​](https://docs.vizra.ai/integrations/providers#1-set-your-default-provider) 1\. Set Your Default Provider .env Copy VIZRA_ADK_DEFAULT_PROVIDER=openai VIZRA_ADK_DEFAULT_MODEL=gpt-4-turbo # Don't forget your API key! OPENAI_API_KEY=sk-... ### [​](https://docs.vizra.ai/integrations/providers#2-or-configure-per-agent) 2\. Or Configure Per Agent app/Agents/CustomerSupportAgent.php Copy use Prism\Prism\Enums\Provider; class CustomerSupportAgent extends BaseLlmAgent { protected ?Provider $provider = Provider::Anthropic; protected string $model = 'claude-3-opus-20240229'; } ### [​](https://docs.vizra.ai/integrations/providers#3-or-switch-on-the-fly) 3\. Or Switch on the Fly Copy $agent->setProvider('groq') ->setModel('mixtral-8x7b-32768') ->setTemperature(0.7); [​](https://docs.vizra.ai/integrations/providers#supported-providers) Supported Providers -------------------------------------------------------------------------------------------- Vizra ADK supports **10 LLM providers** via Prism PHP. Each brings something special to the table. OpenAI The industry leader - GPT-4 is your Swiss Army knife for any task. | Best For | Popular Models | | --- | --- | | General purpose, creative tasks, code generation | gpt-4-turbo, gpt-3.5-turbo, o1-preview | **Environment Variable:** `OPENAI_API_KEY` Copy protected ?Provider $provider = Provider::OpenAI; protected string $model = 'gpt-4-turbo'; Anthropic (Claude) Claude is thoughtful, careful, and great at complex reasoning. | Best For | Popular Models | | --- | --- | | Analysis, writing, safe & ethical responses | claude-3-opus, claude-3-sonnet | **Environment Variable:** `ANTHROPIC_API_KEY` Copy protected ?Provider $provider = Provider::Anthropic; protected string $model = 'claude-3-opus-20240229'; Google Gemini Multimodal magic - handles text, images, and more. | Best For | Popular Models | | --- | --- | | Multimodal tasks, fast responses, cost efficiency | gemini-1.5-pro, gemini-1.5-flash | **Environment Variable:** `GEMINI_API_KEY` Copy protected ?Provider $provider = Provider::Gemini; protected string $model = 'gemini-1.5-flash'; Groq Speed demon. Insanely fast inference for real-time applications. | Best For | Popular Models | | --- | --- | | Real-time chat, low latency needs | mixtral-8x7b-32768, llama2-70b-4096 | **Environment Variable:** `GROQ_API_KEY` Copy protected ?Provider $provider = Provider::Groq; protected string $model = 'mixtral-8x7b-32768'; Ollama (Local) Run models locally - your data never leaves your machine. | Best For | Popular Models | | --- | --- | | Privacy, offline use, experimentation | llama2, codellama, mistral, phi | Copy protected ?Provider $provider = Provider::Ollama; protected string $model = 'llama2'; Requires Ollama to be installed and running locally. OpenRouter One API, 100+ models - the ultimate flexibility. | Best For | Available Models | | --- | --- | | Model flexibility, A/B testing, cost optimization | GPT-4, Claude, Gemini, Llama, and 100+ more | **Environment Variable:** `OPENROUTER_API_KEY` Copy protected ?Provider $provider = Provider::OpenRouter; protected string $model = 'openai/gpt-4-turbo'; // Or use any model: 'anthropic/claude-3-opus', 'google/gemini-pro', etc. Perfect for testing different models without managing multiple API keys. DeepSeek Specialized models for chat and code generation.**Environment Variable:** `DEEPSEEK_API_KEY` Copy protected ?Provider $provider = Provider::DeepSeek; protected string $model = 'deepseek-coder'; Mistral AI Open-weight models with impressive performance.**Environment Variable:** `MISTRAL_API_KEY` Copy protected ?Provider $provider = Provider::Mistral; protected string $model = 'mistral-large-latest'; xAI (Grok) Grok models from Elon’s xAI team.**Environment Variable:** `XAI_API_KEY` Copy protected ?Provider $provider = Provider::XAI; protected string $model = 'grok-beta'; Voyage AI Embedding specialist for semantic search.**Environment Variable:** `VOYAGEAI_API_KEY` Copy protected ?Provider $provider = Provider::VoyageAI; protected string $model = 'voyage-large-2'; Primarily for embeddings, not text generation. [​](https://docs.vizra.ai/integrations/providers#cool-provider-tricks) Cool Provider Tricks ---------------------------------------------------------------------------------------------- Auto-Detection Magic -------------------- Just set the model name and Vizra figures out the provider. Copy // These auto-detect the provider! protected string $model = 'gpt-4'; // OpenAI protected string $model = 'claude-3-opus'; // Anthropic protected string $model = 'gemini-pro'; // Gemini protected string $model = 'llama2'; // Ollama Runtime Switching ----------------- Change providers on the fly based on user needs. Copy // Premium users get the good stuff! if ($user->isPremium()) { $agent->setProvider('anthropic') ->setModel('claude-3-opus-20240229'); } else { $agent->setProvider('openai') ->setModel('gpt-3.5-turbo'); } [​](https://docs.vizra.ai/integrations/providers#choosing-the-right-provider) Choosing the Right Provider ------------------------------------------------------------------------------------------------------------ Not sure which to pick? Here’s your cheat sheet. | Use Case | Recommended Provider | | --- | --- | | Business Apps | OpenAI GPT-4 or Anthropic Claude - reliable and versatile | | Speed Demons | Groq or Gemini Flash - when milliseconds matter | | Privacy First | Ollama - keep everything local and secure | | Code Generation | DeepSeek Coder or GPT-4 - they speak fluent code | | Long Context | Claude 3 or Gemini 1.5 Pro - handle entire books | | Budget Conscious | GPT-3.5 Turbo or local Ollama models | [​](https://docs.vizra.ai/integrations/providers#api-keys-setup) API Keys Setup ---------------------------------------------------------------------------------- Don’t forget to add your API keys to the `.env` file. .env Copy # OpenAI OPENAI_API_KEY=sk-... # Anthropic ANTHROPIC_API_KEY=sk-ant-... # Google Gemini GEMINI_API_KEY=... # OpenRouter (100+ models!) OPENROUTER_API_KEY=... # Add others as needed! GROQ_API_KEY=... MISTRAL_API_KEY=... # etc... [​](https://docs.vizra.ai/integrations/providers#next-steps) Next Steps -------------------------------------------------------------------------- Now that you’ve picked your provider, let’s create some amazing agents.[Create Your First Agent\ -----------------------\ \ Learn how to build powerful AI agents with your chosen provider.](https://docs.vizra.ai/concepts/agents) Was this page helpful? YesNo [Macros & Mixins](https://docs.vizra.ai/advanced/macros) [OpenAI Compatibility](https://docs.vizra.ai/integrations/openai-compatibility) ⌘I --- # Tracing Classes API Reference - Vizra ADK [Skip to main content](https://docs.vizra.ai/api-reference/tracing-class#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation API Reference Tracing Classes API Reference [Documentation](https://docs.vizra.ai/) On this page * [TraceSpan Model](https://docs.vizra.ai/api-reference/tracing-class#tracespan-model) * [Properties](https://docs.vizra.ai/api-reference/tracing-class#properties) * [Relationships](https://docs.vizra.ai/api-reference/tracing-class#relationships) * [Query Scopes](https://docs.vizra.ai/api-reference/tracing-class#query-scopes) * [Helper Methods](https://docs.vizra.ai/api-reference/tracing-class#helper-methods) * [Tracer Service](https://docs.vizra.ai/api-reference/tracing-class#tracer-service) * [Creating Spans](https://docs.vizra.ai/api-reference/tracing-class#creating-spans) * [Span Types](https://docs.vizra.ai/api-reference/tracing-class#span-types) * [Trace Management](https://docs.vizra.ai/api-reference/tracing-class#trace-management) * [Cleanup Operations](https://docs.vizra.ai/api-reference/tracing-class#cleanup-operations) * [Usage Examples](https://docs.vizra.ai/api-reference/tracing-class#usage-examples) * [Analyzing Trace Performance](https://docs.vizra.ai/api-reference/tracing-class#analyzing-trace-performance) * [Error Analysis](https://docs.vizra.ai/api-reference/tracing-class#error-analysis) * [Building Trace Trees](https://docs.vizra.ai/api-reference/tracing-class#building-trace-trees) * [Next Steps](https://docs.vizra.ai/api-reference/tracing-class#next-steps) This page documents the TraceSpan model and Tracer service that power the observability features in Vizra ADK. [​](https://docs.vizra.ai/api-reference/tracing-class#tracespan-model) TraceSpan Model ----------------------------------------------------------------------------------------- The `TraceSpan` model represents an individual span within an agent execution trace. Copy namespace Vizra\VizraADK\Models; class TraceSpan extends Model { use HasUlids; } ### [​](https://docs.vizra.ai/api-reference/tracing-class#properties) Properties | Property | Type | Description | | --- | --- | --- | | `id` | string (ULID) | Primary key for this span | | `trace_id` | string (ULID) | Identifies the entire agent run trace | | `parent_span_id` | string\|null | Parent span ID for hierarchy | | `span_id` | string (ULID) | Unique ID for this specific span | | `session_id` | string | Session ID from AgentContext | | `agent_name` | string | Name of the agent executing this span | | `type` | string | Operation type: agent\_run, llm\_call, tool\_call, sub\_agent\_delegation | | `name` | string | Specific name (model name, tool name, etc.) | | `input` | array\|null | Input data for the operation | | `output` | array\|null | Result/output of the operation | | `metadata` | array\|null | Additional contextual information | | `status` | string | Execution status: running, success, error | | `error_message` | string\|null | Error message if status is error | | `start_time` | decimal(16,6) | Start timestamp with microseconds | | `end_time` | decimal(16,6)\|null | End timestamp with microseconds | | `duration_ms` | integer\|null | Duration in milliseconds | ### [​](https://docs.vizra.ai/api-reference/tracing-class#relationships) Relationships Copy // Get the parent span $parentSpan = $span->parent(); // Get child spans $childSpans = $span->children(); // Get all spans in the same trace $traceSpans = $span->traceSpans(); ### [​](https://docs.vizra.ai/api-reference/tracing-class#query-scopes) Query Scopes Copy // Filter by trace ID $spans = TraceSpan::forTrace($traceId)->get(); // Filter by session ID $spans = TraceSpan::forSession($sessionId)->get(); // Filter by type $llmCalls = TraceSpan::ofType('llm_call')->get(); // Filter by status $errors = TraceSpan::withStatus('error')->get(); // Get root spans only $rootSpans = TraceSpan::rootSpans()->get(); // Order chronologically $orderedSpans = TraceSpan::chronological()->get(); ### [​](https://docs.vizra.ai/api-reference/tracing-class#helper-methods) Helper Methods Copy // Check if span is completed if ($span->isCompleted()) { echo "Span finished in " . $span->duration_ms . "ms"; } // Check if span has error if ($span->hasError()) { echo "Error: " . $span->error_message; } // Check if root span if ($span->isRoot()) { echo "This is the root span"; } // Get formatted duration echo $span->getFormattedDuration(); // "125ms" or "1.5s" // Get status icon echo $span->getStatusIcon(); // Check, X, or spinner icon // Get type icon echo $span->getTypeIcon(); // Robot, brain, wrench, or users icon // Get summary echo $span->getSummary(); // "llm_call: gpt-4 - 1.2s (success)" [​](https://docs.vizra.ai/api-reference/tracing-class#tracer-service) Tracer Service --------------------------------------------------------------------------------------- The `Tracer` service manages span creation and lifecycle. Copy namespace Vizra\VizraADK\Services; class Tracer { // Service is typically injected via dependency injection } ### [​](https://docs.vizra.ai/api-reference/tracing-class#creating-spans) Creating Spans Copy // Start a new span $spanId = $tracer->startSpan( type: 'tool_call', name: 'database_query', input: ['query' => 'SELECT * FROM users'], metadata: ['database' => 'mysql'] ); // End the span successfully $tracer->endSpan($spanId, [\ 'rows_returned' => 42,\ 'cache_hit' => false\ ]); // Mark span as failed $tracer->failSpan($spanId, $exception); ### [​](https://docs.vizra.ai/api-reference/tracing-class#span-types) Span Types | Type | Description | | --- | --- | | `agent_run` | Root span for agent execution | | `llm_call` | LLM API calls | | `tool_call` | Tool executions | | `sub_agent_delegation` | Sub-agent invocations | ### [​](https://docs.vizra.ai/api-reference/tracing-class#trace-management) Trace Management Copy // Create a new trace $traceId = $tracer->createTrace( sessionId: $context->getSessionId(), agentName: 'customer_support' ); // Set current trace context $tracer->setCurrentTrace($traceId); // Get current trace ID $currentTraceId = $tracer->getCurrentTraceId(); ### [​](https://docs.vizra.ai/api-reference/tracing-class#cleanup-operations) Cleanup Operations Copy // Get count of old traces $count = $tracer->getOldTracesCount(30); // 30 days // Clean up old traces with progress callback $deleted = $tracer->cleanupOldTraces(30, function($batchCount) { echo "Deleted {$batchCount} traces...\n"; }); [​](https://docs.vizra.ai/api-reference/tracing-class#usage-examples) Usage Examples --------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/api-reference/tracing-class#analyzing-trace-performance) Analyzing Trace Performance Copy use Vizra\VizraADK\Models\TraceSpan; // Find slowest operations in a trace $slowestSpans = TraceSpan::forTrace($traceId) ->where('duration_ms', '>', 1000) ->orderBy('duration_ms', 'desc') ->get(); foreach ($slowestSpans as $span) { echo $span->getSummary() . "\n"; } ### [​](https://docs.vizra.ai/api-reference/tracing-class#error-analysis) Error Analysis Copy // Get all errors for a session $errors = TraceSpan::forSession($sessionId) ->withStatus('error') ->with('parent') ->get(); foreach ($errors as $error) { echo "Error in {$error->name}: {$error->error_message}\n"; // Show parent context if ($error->parent) { echo " Parent: {$error->parent->name}\n"; } } ### [​](https://docs.vizra.ai/api-reference/tracing-class#building-trace-trees) Building Trace Trees Copy // Build hierarchical trace tree function buildTraceTree(string $traceId): array { $spans = TraceSpan::forTrace($traceId) ->with('children') ->chronological() ->get(); $tree = []; $spanMap = []; // First pass: create span map foreach ($spans as $span) { $spanMap[$span->span_id] = $span; } // Second pass: build tree foreach ($spans as $span) { if ($span->isRoot()) { $tree[] = $span; } } return $tree; } **Best Practices:** * Always end spans properly to ensure accurate duration tracking * Use descriptive span names for better trace readability * Include relevant metadata for debugging purposes * Fail spans with exceptions to capture error context * Use appropriate span types for automatic categorization * Implement regular cleanup to manage storage [​](https://docs.vizra.ai/api-reference/tracing-class#next-steps) Next Steps ------------------------------------------------------------------------------- [Tracing Concepts\ ----------------\ \ Learn about tracing concepts](https://docs.vizra.ai/concepts/tracing) [API Reference\ -------------\ \ View all API references](https://docs.vizra.ai/api-reference) Was this page helpful? YesNo [Error Handling](https://docs.vizra.ai/api-reference/error-handling) ⌘I --- # Artisan Commands - Vizra ADK [Skip to main content](https://docs.vizra.ai/api-reference/artisan-commands#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation API Reference Artisan Commands [Documentation](https://docs.vizra.ai/) On this page * [Agent Development Commands](https://docs.vizra.ai/api-reference/artisan-commands#agent-development-commands) * [Agent Discovery Commands](https://docs.vizra.ai/api-reference/artisan-commands#agent-discovery-commands) * [Agent Interaction Commands](https://docs.vizra.ai/api-reference/artisan-commands#agent-interaction-commands) * [Evaluation Commands](https://docs.vizra.ai/api-reference/artisan-commands#evaluation-commands) * [Prompt Management Commands](https://docs.vizra.ai/api-reference/artisan-commands#prompt-management-commands) * [Debugging Commands](https://docs.vizra.ai/api-reference/artisan-commands#debugging-commands) * [Vector Memory Commands](https://docs.vizra.ai/api-reference/artisan-commands#vector-memory-commands) * [MCP Commands](https://docs.vizra.ai/api-reference/artisan-commands#mcp-commands) * [Setup Commands](https://docs.vizra.ai/api-reference/artisan-commands#setup-commands) * [Pro Tips](https://docs.vizra.ai/api-reference/artisan-commands#pro-tips) * [Next Steps](https://docs.vizra.ai/api-reference/artisan-commands#next-steps) Vizra’s Artisan commands are your Swiss Army knife for AI agent development. From creating new agents to debugging complex interactions, everything is just a command away. [​](https://docs.vizra.ai/api-reference/artisan-commands#agent-development-commands) Agent Development Commands ------------------------------------------------------------------------------------------------------------------ These commands help you scaffold new agents, tools, and testing components in seconds. vizra:make:agent Create a new AI agent with a single command. This is where the magic begins. Terminal Copy # Create a new agent interactively php artisan vizra:make:agent # The command will prompt for the agent name # Creates: app/Agents/YourAgent.php **What you get:** * Name, description, and instructions properties ready to customize * Model configuration (defaults to the blazing-fast gemini-2.0-flash) * Temperature and max tokens settings pre-configured * Empty tools array ready for your custom capabilities vizra:make:tool Give your agents superpowers. Tools let your agents interact with databases, APIs, and more. Terminal Copy # Create a new tool interactively php artisan vizra:make:tool # The command will prompt for the tool name # Creates: app/Tools/YourTool.php **Smart features:** * Tool names are automatically snake\_cased for consistency * “\_tool” suffix is intelligently removed from the name * Implements ToolInterface with definition() and execute() methods * Includes JSON schema parameter definition for type safety vizra:make:toolbox Group related tools together with shared configuration. Toolboxes provide a clean way to organize tools with common gates, policies, or middleware. Terminal Copy # Create a new toolbox interactively php artisan vizra:make:toolbox # Create with specific options php artisan vizra:make:toolbox --gate=admin --policy=App\\Policies\\ToolPolicy # Create with pre-configured tools php artisan vizra:make:toolbox --tools=SearchTool,DatabaseTool,ApiTool # Creates: app/Toolboxes/YourToolbox.php **Options:** | Option | Description | | --- | --- | | `--gate` | Apply a Laravel gate to all tools in the toolbox | | `--policy` | Apply a policy class for authorization | | `--tools` | Comma-separated list of tools to include | **What you get:** * A toolbox class extending BaseToolbox * Centralized configuration for related tools * Built-in support for gates and policies * Easy tool registration via the `$tools` property vizra:make:eval Quality assurance for your AI. Create evaluations to ensure your agents perform consistently. Terminal Copy # Create a new evaluation interactively php artisan vizra:make:eval # The command will prompt for the evaluation name # Creates: app/Evaluations/YourEvaluation.php vizra:make:assertion Create custom assertions for your evaluations. Assertions define the criteria for pass/fail outcomes. Terminal Copy # Create a new assertion interactively php artisan vizra:make:assertion # The command will prompt for the assertion name # Creates: app/Assertions/YourAssertion.php **What you get:** * An assertion class extending BaseAssertion * The `evaluate()` method ready for your custom logic * Access to the agent response and expected outcome * Integration with the evaluation framework [​](https://docs.vizra.ai/api-reference/artisan-commands#agent-discovery-commands) Agent Discovery Commands -------------------------------------------------------------------------------------------------------------- Explore your AI workforce. These commands help you discover and manage your agents. vizra:discover-agents See all your available agents. This command shows you every agent in your application, whether registered or not. Terminal Copy # Discover all agents php artisan vizra:discover-agents # Clear discovery cache and rediscover php artisan vizra:discover-agents --clear-cache **What you’ll see:** * Complete list of all agents in your `app/Agents` directory * Agent names, class names, and registration status * Automatic discovery of new agents without manual registration * Clear indication of which agents are already registered vs available **Options:** | Option | Description | | --- | --- | | `--clear-cache` | Force rediscovery by clearing the cache | Vizra ADK automatically discovers and registers agents when you use them. You don’t need to manually register agents in your `AppServiceProvider` anymore. Just create an agent and start using it. [​](https://docs.vizra.ai/api-reference/artisan-commands#agent-interaction-commands) Agent Interaction Commands ------------------------------------------------------------------------------------------------------------------ Time to talk. These commands let you interact with your agents directly from the terminal. vizra:chat Have a conversation with your AI agent right in your terminal. Perfect for testing and development. Terminal Copy php artisan vizra:chat {agent_name} # Example: Chat with the weather reporter agent php artisan vizra:chat weather_reporter # Type "exit" or "quit" to end the chat **Features:** * Interactive terminal-based chat interface for instant feedback * Unique session ID for each chat to track conversations * Handles string, array, and object responses gracefully * Comprehensive error handling so nothing breaks [​](https://docs.vizra.ai/api-reference/artisan-commands#evaluation-commands) Evaluation Commands ---------------------------------------------------------------------------------------------------- Test your agents like a pro. Run comprehensive evaluations to ensure quality at scale. vizra:run:eval Put your agents through their paces. Run evaluations to measure performance and catch regressions. Terminal Copy php artisan vizra:run:eval {name} [--output=results.csv] # Example: Run CustomerServiceEvaluation php artisan vizra:run:eval CustomerServiceEvaluation # Save results to CSV file php artisan vizra:run:eval CustomerServiceEvaluation --output=results.csv **Options:** | Option | Description | | --- | --- | | `name` | The evaluation class name (e.g., MyTestEvaluation) | | `--output` | Path to save CSV results for analysis | **What you’ll see:** * Real-time progress bar during evaluation * Summary statistics with pass/fail counts * Detailed results with assertion breakdowns * CSV export with all test data for deeper analysis [​](https://docs.vizra.ai/api-reference/artisan-commands#prompt-management-commands) Prompt Management Commands ------------------------------------------------------------------------------------------------------------------ Master your AI’s voice. Manage prompt versions without touching code. vizra:prompt Your command center for prompt versioning. Create, list, activate, and manage different prompt versions for each agent. Terminal Copy # Create a new prompt version php artisan vizra:prompt create {agent} {version} [--content="..."] # List all prompt versions php artisan vizra:prompt list [agent] # Activate a version (database only) php artisan vizra:prompt activate {agent} {version} # Export prompt to file php artisan vizra:prompt export {agent} {version} [--file=output.txt] # Import prompt from file php artisan vizra:prompt import {agent} {version} --file=input.txt **Examples in action:** Terminal Copy # Create friendly customer support prompt php artisan vizra:prompt create customer_support friendly \ --content="You are a warm and friendly support agent. Use casual language." # List all weather reporter prompts php artisan vizra:prompt list weather_reporter # Switch to professional version in production php artisan vizra:prompt activate customer_support professional # Share prompts between projects php artisan vizra:prompt export my_agent v2 --file=awesome_prompt.txt php artisan vizra:prompt import other_agent v1 --file=awesome_prompt.txt **Prompt versioning features:** * File-based storage by default at `resources/prompts/{agent}/{version}.txt` * Optional database storage for production environments * Runtime version switching without code changes * Perfect for A/B testing and experimentation * Integration with evaluations for systematic testing [​](https://docs.vizra.ai/api-reference/artisan-commands#debugging-commands) Debugging Commands -------------------------------------------------------------------------------------------------- Become a debugging detective. These commands help you understand exactly what your agents are doing. vizra:trace X-ray vision for your agents. See every step of execution in beautiful detail. Terminal Copy php artisan vizra:trace {session_id} [options] # View trace in tree format (default) php artisan vizra:trace abc123 # View specific trace ID php artisan vizra:trace abc123 --trace-id=xyz789 # Show detailed span data php artisan vizra:trace abc123 --show-input --show-output --show-metadata # Show only errors php artisan vizra:trace abc123 --errors-only # Different output formats php artisan vizra:trace abc123 --format=table php artisan vizra:trace abc123 --format=json **Options:** | Option | Description | | --- | --- | | `--trace-id` | Zero in on a specific trace | | `--show-input` | See what went in | | `--show-output` | See what came out | | `--show-metadata` | View all the extra details | | `--errors-only` | Focus on problems | | `--format` | Choose your view: tree, table, or json | vizra:trace:cleanup Keep things tidy. Clean up old trace data to save space and maintain performance. Terminal Copy # Clean up traces older than config value (default: 30 days) php artisan vizra:trace:cleanup # Clean up traces older than 7 days php artisan vizra:trace:cleanup --days=7 # Preview what would be deleted php artisan vizra:trace:cleanup --dry-run # Skip confirmation prompt php artisan vizra:trace:cleanup --force [​](https://docs.vizra.ai/api-reference/artisan-commands#vector-memory-commands) Vector Memory Commands ---------------------------------------------------------------------------------------------------------- Give your agents perfect memory. Store and search through knowledge using advanced vector embeddings. vector:store Feed your agent’s brain. Store documents, manuals, and knowledge for instant recall. Terminal Copy php artisan vector:store {agent} [options] # Store content from a file php artisan vector:store customer_support --file=docs.txt # Store direct content php artisan vector:store customer_support --content="Important product information" # With metadata php artisan vector:store customer_support \ --file=manual.pdf \ --namespace=products \ --source=manual \ --source-id=v2.0 \ --metadata='{"category":"electronics","version":"2.0"}' **Storage options:** | Option | Description | | --- | --- | | `--file` | Path to document or file | | `--content` | Direct text to store | | `--namespace` | Organize your memories | | `--source` | Track where it came from | | `--source-id` | Version or ID tracking | | `--metadata` | Extra context as JSON | vector:search Find anything instantly. Search through your agent’s knowledge with semantic understanding. Terminal Copy php artisan vector:search {agent} {query} [options] # Basic search php artisan vector:search customer_support "refund policy" # Search with custom parameters php artisan vector:search customer_support "shipping rates" \ --limit=10 \ --threshold=0.8 \ --namespace=policies # Generate RAG context php artisan vector:search customer_support "product warranty" --rag # JSON output php artisan vector:search customer_support "user manual" --json **Search options:** | Option | Description | | --- | --- | | `--namespace` | Search specific memory spaces | | `--limit` | How many results to return | | `--threshold` | Similarity score (0.0-1.0) | | `--rag` | Get formatted context for agents | | `--json` | Machine-readable output | vector:stats Monitor your memory usage. Get insights into how your vector storage is performing. Terminal Copy # Global statistics php artisan vector:stats # Agent-specific statistics php artisan vector:stats customer_support # Detailed statistics php artisan vector:stats --detailed # Specific namespace php artisan vector:stats customer_support --namespace=products # JSON output php artisan vector:stats --json [​](https://docs.vizra.ai/api-reference/artisan-commands#mcp-commands) MCP Commands -------------------------------------------------------------------------------------- Manage Model Context Protocol servers. Connect your agents to external tool servers for extended capabilities. vizra:mcp:servers List and test your configured MCP servers. See which external tool servers are available and their connection status. Terminal Copy # List all configured MCP servers php artisan vizra:mcp:servers # Test connectivity to all servers php artisan vizra:mcp:servers --test **Options:** | Option | Description | | --- | --- | | `--test` | Test connectivity to each configured server | **What you’ll see:** * All configured MCP servers from your config * Server names, URLs, and transport types * Connection status when using `--test` * Available tools from each connected server [​](https://docs.vizra.ai/api-reference/artisan-commands#setup-commands) Setup Commands ------------------------------------------------------------------------------------------ Get started quickly. These commands help you set up and configure Vizra ADK. vizra:install One command to rule them all. Install everything you need to start building agents. Terminal Copy php artisan vizra:install # This command: # - Publishes configuration files # - Publishes database migrations # - Shows post-installation information vizra:boost:install Install Vizra ADK guidelines for Laravel Boost integration. This adds AI agent development context to your Boost configuration. Terminal Copy # Install Boost integration php artisan vizra:boost:install # Force overwrite existing configuration php artisan vizra:boost:install --force **Options:** | Option | Description | | --- | --- | | `--force` | Overwrite existing Boost guidelines | **What it does:** * Adds Vizra ADK context to your Laravel Boost setup * Provides AI coding assistants with agent development patterns * Includes tool and evaluation scaffolding guidance vizra:dashboard Access your command center. Launch the web dashboard to test and monitor your agents. Terminal Copy # Display dashboard URL php artisan vizra:dashboard # Open dashboard in browser php artisan vizra:dashboard --open [​](https://docs.vizra.ai/api-reference/artisan-commands#pro-tips) Pro Tips ------------------------------------------------------------------------------ Development Flow ---------------- * Use `vizra:chat` for rapid testing * Create agents and tools with make commands * Debug with traces when things get complex Production Excellence --------------------- * Run evaluations before deploying * Clean up traces to save storage * Monitor vector memory performance [​](https://docs.vizra.ai/api-reference/artisan-commands#next-steps) Next Steps ---------------------------------------------------------------------------------- [Quick Start Guide\ -----------------\ \ Jump back to the basics and get started](https://docs.vizra.ai/getting-started/quick-start) [Full API Reference\ ------------------\ \ Explore all the APIs and capabilities](https://docs.vizra.ai/api-reference) Was this page helpful? YesNo [Web Dashboard](https://docs.vizra.ai/testing/web-dashboard) [Agent Class Reference](https://docs.vizra.ai/api-reference/agent-class) ⌘I --- # Events API Reference - Vizra ADK [Skip to main content](https://docs.vizra.ai/api-reference/events#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation API Reference Events API Reference [Documentation](https://docs.vizra.ai/) On this page * [Event Overview](https://docs.vizra.ai/api-reference/events#event-overview) * [Agent Execution Events](https://docs.vizra.ai/api-reference/events#agent-execution-events) * [LLM Interaction Events](https://docs.vizra.ai/api-reference/events#llm-interaction-events) * [Tool Execution Events](https://docs.vizra.ai/api-reference/events#tool-execution-events) * [State Management Events](https://docs.vizra.ai/api-reference/events#state-management-events) * [Multi-Agent Events](https://docs.vizra.ai/api-reference/events#multi-agent-events) * [Media Generation Events](https://docs.vizra.ai/api-reference/events#media-generation-events) * [Usage Examples](https://docs.vizra.ai/api-reference/events#usage-examples) * [Monitoring Agent Performance](https://docs.vizra.ai/api-reference/events#monitoring-agent-performance) * [Debugging Tool Calls](https://docs.vizra.ai/api-reference/events#debugging-tool-calls) * [Memory Tracking](https://docs.vizra.ai/api-reference/events#memory-tracking) * [Next Steps](https://docs.vizra.ai/api-reference/events#next-steps) [​](https://docs.vizra.ai/api-reference/events#event-overview) Event Overview -------------------------------------------------------------------------------- All class-based events are in the `Vizra\VizraADK\Events` namespace and use Laravel’s event system. Copy use Vizra\VizraADK\Events\AgentExecutionStarting; use Illuminate\Support\Facades\Event; // Listen to an event Event::listen(AgentExecutionStarting::class, function (AgentExecutionStarting $event) { Log::info('Agent starting', [\ 'agent' => $event->agentName,\ 'input' => $event->input\ ]); }); [​](https://docs.vizra.ai/api-reference/events#agent-execution-events) Agent Execution Events ------------------------------------------------------------------------------------------------ AgentExecutionStarting Fired when an agent begins execution. Copy class AgentExecutionStarting { public function __construct( public AgentContext $context, public string $agentName, public mixed $input ) {} } **Properties:** | Property | Description | | --- | --- | | `$context` | The agent execution context | | `$agentName` | Name of the agent being executed | | `$input` | Initial input provided to the agent | AgentExecutionFinished Fired when an agent completes execution. Copy class AgentExecutionFinished { public function __construct( public AgentContext $context, public string $agentName ) {} } **Properties:** | Property | Description | | --- | --- | | `$context` | The agent execution context | | `$agentName` | Name of the agent that finished | AgentResponseGenerated Fired when an agent generates its final response. Copy class AgentResponseGenerated { public function __construct( public AgentContext $context, public string $agentName, public mixed $finalResponse ) {} } **Properties:** | Property | Description | | --- | --- | | `$context` | The agent execution context | | `$agentName` | Name of the agent | | `$finalResponse` | The final response generated by the agent | [​](https://docs.vizra.ai/api-reference/events#llm-interaction-events) LLM Interaction Events ------------------------------------------------------------------------------------------------ LlmCallInitiating Fired before making a call to the LLM. Copy class LlmCallInitiating { public function __construct( public AgentContext $context, public string $agentName, public array $promptMessages ) {} } **Properties:** | Property | Description | | --- | --- | | `$context` | The agent execution context | | `$agentName` | Name of the agent making the call | | `$promptMessages` | Array of messages being sent to the LLM | LlmResponseReceived Fired after receiving a response from the LLM. Copy class LlmResponseReceived { public function __construct( public AgentContext $context, public string $agentName, public mixed $llmResponse, public ?PendingRequest $request = null ) {} } **Properties:** | Property | Description | | --- | --- | | `$context` | The agent execution context | | `$agentName` | Name of the agent | | `$llmResponse` | The response from the LLM | | `$request` | The Prism request object (optional) | LlmCallFailed Fired when an LLM API call fails. Copy class LlmCallFailed { public function __construct( public AgentContext $context, public string $agentName, public Throwable $exception, public ?PendingRequest $request = null ) {} } **Properties:** | Property | Description | | --- | --- | | `$context` | The agent execution context | | `$agentName` | Name of the agent | | `$exception` | The exception that caused the failure | | `$request` | The failed request details (optional) | [​](https://docs.vizra.ai/api-reference/events#tool-execution-events) Tool Execution Events ---------------------------------------------------------------------------------------------- ToolCallInitiating Fired before executing a tool. Copy class ToolCallInitiating { public function __construct( public AgentContext $context, public string $agentName, public string $toolName, public array $arguments ) {} } **Properties:** | Property | Description | | --- | --- | | `$context` | The agent execution context | | `$agentName` | Name of the agent executing the tool | | `$toolName` | Name of the tool being called | | `$arguments` | Arguments passed to the tool | ToolCallCompleted Fired after a tool completes execution. Copy class ToolCallCompleted { public function __construct( public AgentContext $context, public string $agentName, public string $toolName, public string $result // JSON string ) {} } **Properties:** | Property | Description | | --- | --- | | `$context` | The agent execution context | | `$agentName` | Name of the agent | | `$toolName` | Name of the tool that completed | | `$result` | JSON-encoded result from the tool | ToolCallFailed Fired when a tool call encounters an error. Copy class ToolCallFailed { public function __construct( public AgentContext $context, public string $agentName, public string $toolName, public Throwable $exception ) {} } **Properties:** | Property | Description | | --- | --- | | `$context` | The agent execution context | | `$agentName` | Name of the agent | | `$toolName` | Name of the tool that failed | | `$exception` | The exception that caused the failure | [​](https://docs.vizra.ai/api-reference/events#state-management-events) State Management Events -------------------------------------------------------------------------------------------------- StateUpdated Fired when agent state is updated. Copy class StateUpdated { public function __construct( public AgentContext $context, public string $key, public mixed $value ) {} } **Properties:** | Property | Description | | --- | --- | | `$context` | The agent execution context | | `$key` | The state key that was updated | | `$value` | The new value | MemoryUpdated Fired when agent memory is updated. Copy class MemoryUpdated { public function __construct( public AgentMemory $memory, public ?AgentSession $session, public string $updateType ) {} } **Properties:** | Property | Description | | --- | --- | | `$memory` | The agent memory instance | | `$session` | The associated session (optional) | | `$updateType` | Type of update performed | **Update Types:** | Type | Description | | --- | --- | | `'session_completed'` | Session summary extracted | | `'learning_added'` | New learning stored | | `'fact_added'` | New fact stored | [​](https://docs.vizra.ai/api-reference/events#multi-agent-events) Multi-Agent Events ---------------------------------------------------------------------------------------- TaskDelegated Fired when an agent delegates a task to a sub-agent. Copy class TaskDelegated { public function __construct( public AgentContext $parentContext, public AgentContext $subAgentContext, public string $parentAgentName, public string $subAgentName, public string $taskInput, public string $contextSummary, public int $delegationDepth ) {} } **Properties:** | Property | Description | | --- | --- | | `$parentContext` | Context of the delegating agent | | `$subAgentContext` | Context for the sub-agent | | `$parentAgentName` | Name of the parent agent | | `$subAgentName` | Name of the sub-agent receiving the task | | `$taskInput` | The task being delegated | | `$contextSummary` | Summary of context passed to sub-agent | | `$delegationDepth` | Current depth of delegation chain | [​](https://docs.vizra.ai/api-reference/events#media-generation-events) Media Generation Events -------------------------------------------------------------------------------------------------- These are string-based events fired by `MediaGenerationJob` when processing queued media generation tasks (images, audio, etc.). Copy use Illuminate\Support\Facades\Event; // Listen to media events Event::listen('media.job.completed', function (array $payload) { Log::info('Media job completed', [\ 'job_id' => $payload['job_id'],\ 'agent' => $payload['agent_class'],\ ]); }); media.job.completed Fired when any media generation job completes successfully. Copy event('media.job.completed', [\ 'job_id' => $jobId,\ 'agent_class' => $agentClass,\ 'response' => $response, // ImageResponse or AudioResponse\ ]); **Payload:** | Key | Type | Description | | --- | --- | --- | | `job_id` | `string` | Unique identifier for the job | | `agent_class` | `string` | Fully qualified class name of the media agent | | `response` | `ImageResponse\|AudioResponse` | The generated media response object | **Example:** Copy Event::listen('media.job.completed', function (array $payload) { $url = $payload['response']->url(); // Notify user that their image is ready Notification::send($user, new MediaReadyNotification($url)); }); media.{agent\_name}.completed Fired when a specific agent’s media job completes. The event name includes the agent’s name (e.g., `media.image_agent.completed`). Copy event("media.{$agentName}.completed", [\ 'job_id' => $jobId,\ 'response' => $response,\ 'session_id' => $sessionId,\ ]); **Payload:** | Key | Type | Description | | --- | --- | --- | | `job_id` | `string` | Unique identifier for the job | | `response` | `ImageResponse\|AudioResponse` | The generated media response object | | `session_id` | `string` | Session ID associated with the job | **Example:** Copy // Listen specifically for image agent completions Event::listen('media.image_agent.completed', function (array $payload) { $sessionId = $payload['session_id']; $imageUrl = $payload['response']->url(); // Update the session with the generated image broadcast(new ImageGeneratedEvent($sessionId, $imageUrl)); }); // Listen for audio agent completions Event::listen('media.audio_agent.completed', function (array $payload) { // Handle audio-specific logic }); media.job.failed Fired when a media generation job fails after all retry attempts. Copy event('media.job.failed', [\ 'job_id' => $jobId,\ 'agent_class' => $agentClass,\ 'error' => $exception->getMessage(),\ ]); **Payload:** | Key | Type | Description | | --- | --- | --- | | `job_id` | `string` | Unique identifier for the failed job | | `agent_class` | `string` | Fully qualified class name of the media agent | | `error` | `string` | Error message describing the failure | **Example:** Copy Event::listen('media.job.failed', function (array $payload) { Log::error('Media generation failed', [\ 'job_id' => $payload['job_id'],\ 'agent' => $payload['agent_class'],\ 'error' => $payload['error'],\ ]); // Notify user of failure Notification::send($user, new MediaFailedNotification($payload['error'])); }); [​](https://docs.vizra.ai/api-reference/events#usage-examples) Usage Examples -------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/api-reference/events#monitoring-agent-performance) Monitoring Agent Performance Copy use Vizra\VizraADK\Events\{AgentExecutionStarting, AgentExecutionFinished}; use Illuminate\Support\Facades\Event; class AgentPerformanceMonitor { private array $startTimes = []; public function register(): void { Event::listen(AgentExecutionStarting::class, [$this, 'handleStart']); Event::listen(AgentExecutionFinished::class, [$this, 'handleFinish']); } public function handleStart(AgentExecutionStarting $event): void { $this->startTimes[$event->context->getSessionId()] = microtime(true); } public function handleFinish(AgentExecutionFinished $event): void { $sessionId = $event->context->getSessionId(); $duration = microtime(true) - $this->startTimes[$sessionId]; Log::info('Agent execution completed', [\ 'agent' => $event->agentName,\ 'duration' => round($duration, 2) . 's'\ ]); } } ### [​](https://docs.vizra.ai/api-reference/events#debugging-tool-calls) Debugging Tool Calls Copy Event::listen(ToolCallInitiating::class, function (ToolCallInitiating $event) { Log::debug('Tool call starting', [\ 'tool' => $event->toolName,\ 'arguments' => $event->arguments,\ 'session' => $event->context->getSessionId()\ ]); }); Event::listen(ToolCallCompleted::class, function (ToolCallCompleted $event) { $result = json_decode($event->result, true); Log::debug('Tool call completed', [\ 'tool' => $event->toolName,\ 'success' => $result['success'] ?? false\ ]); }); ### [​](https://docs.vizra.ai/api-reference/events#memory-tracking) Memory Tracking Copy Event::listen(MemoryUpdated::class, function (MemoryUpdated $event) { switch ($event->updateType) { case 'learning_added': Log::info('New learning stored', [\ 'agent' => $event->memory->agent_name,\ 'learning' => $event->memory->learnings->last()\ ]); break; case 'fact_added': Log::info('New fact stored', [\ 'agent' => $event->memory->agent_name,\ 'fact' => $event->memory->facts->last()\ ]); break; } }); **Event Best Practices:** * Use event listeners for cross-cutting concerns like logging and monitoring * Keep event handlers lightweight to avoid impacting agent performance * Use queued listeners for heavy processing tasks * Events are synchronous by default - be mindful of execution time * All class-based events include the AgentContext for accessing session state * Tool results are JSON strings - decode them for processing * Media events are string-based and receive array payloads [​](https://docs.vizra.ai/api-reference/events#next-steps) Next Steps ------------------------------------------------------------------------ [Agent Lifecycle\ ---------------\ \ Learn about the agent execution flow](https://docs.vizra.ai/concepts/agent-lifecycle) [API Reference\ -------------\ \ View all API references](https://docs.vizra.ai/api-reference) Was this page helpful? YesNo [Evaluation Class Reference](https://docs.vizra.ai/api-reference/evaluation-class) [Error Handling](https://docs.vizra.ai/api-reference/error-handling) ⌘I --- # Workflow Class Reference - Vizra ADK [Skip to main content](https://docs.vizra.ai/api-reference/workflow-class#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation API Reference Workflow Class Reference [Documentation](https://docs.vizra.ai/) On this page * [Class Overview](https://docs.vizra.ai/api-reference/workflow-class#class-overview) * [BaseWorkflowAgent Properties](https://docs.vizra.ai/api-reference/workflow-class#baseworkflowagent-properties) * [Key Methods](https://docs.vizra.ai/api-reference/workflow-class#key-methods) * [executeWorkflow()](https://docs.vizra.ai/api-reference/workflow-class#executeworkflow) * [addAgent()](https://docs.vizra.ai/api-reference/workflow-class#addagent) * [Workflow Methods](https://docs.vizra.ai/api-reference/workflow-class#workflow-methods) * [Configuration Methods](https://docs.vizra.ai/api-reference/workflow-class#configuration-methods) * [Result Access Methods](https://docs.vizra.ai/api-reference/workflow-class#result-access-methods) * [Workflow Types](https://docs.vizra.ai/api-reference/workflow-class#workflow-types) * [Sequential Workflow](https://docs.vizra.ai/api-reference/workflow-class#sequential-workflow) * [Parallel Workflow](https://docs.vizra.ai/api-reference/workflow-class#parallel-workflow) * [Conditional Workflow](https://docs.vizra.ai/api-reference/workflow-class#conditional-workflow) * [Loop Workflow](https://docs.vizra.ai/api-reference/workflow-class#loop-workflow) * [Step Parameters](https://docs.vizra.ai/api-reference/workflow-class#step-parameters) * [Dynamic Parameters](https://docs.vizra.ai/api-reference/workflow-class#dynamic-parameters) * [Creating Custom Workflows](https://docs.vizra.ai/api-reference/workflow-class#creating-custom-workflows) * [Running Workflows](https://docs.vizra.ai/api-reference/workflow-class#running-workflows) * [Basic Execution](https://docs.vizra.ai/api-reference/workflow-class#basic-execution) * [Using the Workflow Facade](https://docs.vizra.ai/api-reference/workflow-class#using-the-workflow-facade) * [Workflow Results](https://docs.vizra.ai/api-reference/workflow-class#workflow-results) * [Sequential Workflow Results](https://docs.vizra.ai/api-reference/workflow-class#sequential-workflow-results) * [Parallel Workflow Results](https://docs.vizra.ai/api-reference/workflow-class#parallel-workflow-results) * [Error Handling](https://docs.vizra.ai/api-reference/workflow-class#error-handling) * [Complete Example](https://docs.vizra.ai/api-reference/workflow-class#complete-example) * [Next Steps](https://docs.vizra.ai/api-reference/workflow-class#next-steps) [​](https://docs.vizra.ai/api-reference/workflow-class#class-overview) Class Overview ---------------------------------------------------------------------------------------- Copy namespace Vizra\VizraADK\Agents; abstract class BaseWorkflowAgent extends BaseAgent { // Workflow agents extend this class } [​](https://docs.vizra.ai/api-reference/workflow-class#baseworkflowagent-properties) BaseWorkflowAgent Properties -------------------------------------------------------------------------------------------------------------------- | Property | Type | Default | Description | | --- | --- | --- | --- | | `$steps` | array | `[]` | Array of workflow steps | | `$results` | array | `[]` | Step execution results | | `$timeout` | int | `300` | Workflow timeout (seconds) | | `$retryAttempts` | int | `0` | Default retry attempts | | `$retryDelay` | int | `1000` | Retry delay (milliseconds) | [​](https://docs.vizra.ai/api-reference/workflow-class#key-methods) Key Methods ---------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/api-reference/workflow-class#executeworkflow) executeWorkflow() Copy abstract protected function executeWorkflow(mixed $input, AgentContext $context): mixed Each workflow type must implement this method to define its execution logic. ### [​](https://docs.vizra.ai/api-reference/workflow-class#addagent) addAgent() Copy public function addAgent( string $agentClass, mixed $params = null, array $options = [] ): static Add an agent step to the workflow using the agent class name. [​](https://docs.vizra.ai/api-reference/workflow-class#workflow-methods) Workflow Methods -------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/api-reference/workflow-class#configuration-methods) Configuration Methods Copy // Set timeout for the entire workflow $workflow->timeout(300); // 5 minutes // Set retry policy $workflow->retryOnFailure(3, 1000); // 3 attempts, 1s delay // Set callbacks $workflow->onSuccess(function($result, $stepResults) { Log::info('Success!', ['result' => $result]); }); $workflow->onFailure(function(\Throwable $e, $stepResults) { Log::error('Failed: ' . $e->getMessage()); }); $workflow->onComplete(function($result, $success, $stepResults) { // Always runs }); ### [​](https://docs.vizra.ai/api-reference/workflow-class#result-access-methods) Result Access Methods Copy // Get all results $allResults = $workflow->getResults(); // Get specific step result $stepResult = $workflow->getStepResult(DataProcessor::class); // Reset workflow for reuse $workflow->reset(); [​](https://docs.vizra.ai/api-reference/workflow-class#workflow-types) Workflow Types ---------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/api-reference/workflow-class#sequential-workflow) Sequential Workflow Copy use Vizra\VizraADK\Agents\SequentialWorkflow; use App\Agents\AnalyzerAgent; use App\Agents\ProcessorAgent; use App\Agents\ValidatorAgent; use App\Agents\CleanupAgent; $workflow = new SequentialWorkflow(); // Add steps in sequence $workflow ->start(AnalyzerAgent::class, 'Analyze input') ->then(ProcessorAgent::class, fn($prev) => "Process: " . $prev) ->when(ValidatorAgent::class, fn($input, $results) => $results[ProcessorAgent::class]['status'] === 'needs_validation' ) ->finally(CleanupAgent::class); // Always runs // Create context and execute use Vizra\VizraADK\System\AgentContext; $context = new AgentContext('session-123'); $result = $workflow->execute('Input data', $context); ### [​](https://docs.vizra.ai/api-reference/workflow-class#parallel-workflow) Parallel Workflow Copy use Vizra\VizraADK\Agents\ParallelWorkflow; use App\Agents\EmailSender; use App\Agents\SmsSender; use App\Agents\WebhookCaller; $workflow = new ParallelWorkflow(); $workflow ->agents([\ EmailSender::class => 'Send email notification',\ SmsSender::class => 'Send SMS',\ WebhookCaller::class => 'Call webhook'\ ]) ->waitForAll(); // or waitForAny() ### [​](https://docs.vizra.ai/api-reference/workflow-class#conditional-workflow) Conditional Workflow Copy use Vizra\VizraADK\Agents\ConditionalWorkflow; use App\Agents\UrgentHandler; use App\Agents\SupportAgent; use App\Agents\DefaultHandler; $workflow = new ConditionalWorkflow(); $workflow ->when( fn($input) => $input['priority'] === 'high', UrgentHandler::class ) ->when( fn($input) => $input['type'] === 'support', SupportAgent::class ) ->otherwise(DefaultHandler::class); ### [​](https://docs.vizra.ai/api-reference/workflow-class#loop-workflow) Loop Workflow Copy use Vizra\VizraADK\Agents\LoopWorkflow; use App\Agents\ProcessorAgent; use App\Agents\ItemProcessor; // While loop $workflow = new LoopWorkflow(); $workflow->while( ProcessorAgent::class, fn($result) => $result['continue'] === true, 10 // max iterations ); // For each loop $items = ['item1', 'item2', 'item3']; $workflow = new LoopWorkflow(); $workflow->forEach(ItemProcessor::class, $items); [​](https://docs.vizra.ai/api-reference/workflow-class#step-parameters) Step Parameters ------------------------------------------------------------------------------------------ ### [​](https://docs.vizra.ai/api-reference/workflow-class#dynamic-parameters) Dynamic Parameters Copy // Static parameters $workflow->addAgent('agent_name', 'Static input'); // Dynamic parameters with closure $workflow->addAgent( 'processor', fn($input, $results, $context) => [\ 'data' => $results['previous_agent'],\ 'mode' => $context->getState('processing_mode')\ ] ); // Step options $workflow->addAgent('risky_agent', 'Input', [\ 'retries' => 5,\ 'timeout' => 60,\ 'condition' => fn() => config('app.env') === 'production'\ ]); [​](https://docs.vizra.ai/api-reference/workflow-class#creating-custom-workflows) Creating Custom Workflows -------------------------------------------------------------------------------------------------------------- Copy use App\Agents\FirstAgent; class CustomWorkflow extends BaseWorkflowAgent { protected string $name = 'custom_workflow'; protected string $description = 'Custom workflow implementation'; protected function executeWorkflow(mixed $input, AgentContext $context): mixed { // Custom workflow logic $result1 = $this->executeStep([\ 'agent' => 'first_agent',\ 'params' => $input,\ 'retries' => 2\ ], $input, $context); // Access previous results $allResults = $this->getResults(); return [\ 'workflow_type' => 'custom',\ 'results' => $allResults\ ]; } } [​](https://docs.vizra.ai/api-reference/workflow-class#running-workflows) Running Workflows ---------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/api-reference/workflow-class#basic-execution) Basic Execution Copy use Vizra\VizraADK\System\AgentContext; // Workflows are agents, so they run like any agent $workflow = new SequentialWorkflow(); $workflow ->then('agent1') ->then('agent2'); // Create context (required) $context = new AgentContext('session-123'); // Execute with input and context $result = $workflow->execute('Process this data', $context); ### [​](https://docs.vizra.ai/api-reference/workflow-class#using-the-workflow-facade) Using the Workflow Facade Copy use Vizra\VizraADK\Facades\Workflow; use Vizra\VizraADK\System\AgentContext; // Create context $context = new AgentContext('session-123'); // Create and execute in one go $result = Workflow::sequential('agent1', 'agent2', 'agent3') ->execute('Input data', $context); // With callbacks $workflow = Workflow::sequential('agent1', 'agent2') ->onSuccess(function($result) { Log::info('Workflow completed!', ['result' => $result]); }); $result = $workflow->execute('Start', $context); [​](https://docs.vizra.ai/api-reference/workflow-class#workflow-results) Workflow Results -------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/api-reference/workflow-class#sequential-workflow-results) Sequential Workflow Results Copy // Sequential workflow returns { "final_result": "Last agent output", "step_results": { "agent1": "First result", "agent2": "Second result" }, "workflow_type": "sequential" } ### [​](https://docs.vizra.ai/api-reference/workflow-class#parallel-workflow-results) Parallel Workflow Results Copy // Parallel workflow returns { "results": { "agent1": "Result 1", "agent2": "Result 2" }, "completed": ["agent1", "agent2"], "workflow_type": "parallel" } ### [​](https://docs.vizra.ai/api-reference/workflow-class#error-handling) Error Handling Copy // Set retry policy for all steps $workflow->retryOnFailure(3, 1000); // Handle errors with callbacks $workflow->onFailure(function(\Throwable $e, $stepResults) { // Log the error Log::error('Workflow failed', [\ 'error' => $e->getMessage(),\ 'completed_steps' => array_keys($stepResults)\ ]); // Perform cleanup CleanupService::rollback($stepResults); }); [​](https://docs.vizra.ai/api-reference/workflow-class#complete-example) Complete Example -------------------------------------------------------------------------------------------- OrderProcessingWorkflow.php Copy timeout(300) // 5 minutes ->retryOnFailure(2, 2000); // 2 retries, 2s delay // Define the workflow steps $this ->start(OrderValidator::class, fn($input) => [\ 'order_id' => $input['order_id']\ ]) ->then(InventoryChecker::class, fn($prevResult) => $prevResult['items'] ) ->when( PaymentProcessor::class, fn($input, $results) => $results[InventoryChecker::class]['available'] === true, fn($input, $results) => [\ 'amount' => $results[OrderValidator::class]['total'],\ 'payment_method' => $input['payment_method']\ ] ) ->then(ShippingCreator::class) ->then(NotificationSender::class, 'Send order confirmation') ->finally(OrderLogger::class); // Always runs // Set callbacks $this->onSuccess(function($result, $stepResults) { Log::info('Order processed successfully', [\ 'order_id' => $stepResults[OrderValidator::class]['order_id']\ ]); }); $this->onFailure(function(\Throwable $e, $stepResults) { // Rollback any completed steps if (isset($stepResults[PaymentProcessor::class])) { PaymentService::refund( $stepResults[PaymentProcessor::class]['transaction_id'] ); } }); } } **Workflow Best Practices:** * Workflows are agents - they extend BaseWorkflowAgent * Use the appropriate workflow type for your use case * Set reasonable timeouts and retry limits * Leverage callbacks for monitoring and debugging * Pass results between steps using closures * Handle errors at both step and workflow levels * Test workflows with various input scenarios [​](https://docs.vizra.ai/api-reference/workflow-class#next-steps) Next Steps -------------------------------------------------------------------------------- [Evaluation Class\ ----------------\ \ Evaluation class reference](https://docs.vizra.ai/api-reference/evaluation-class) [Workflow Concepts\ -----------------\ \ Learn more about workflows](https://docs.vizra.ai/concepts/workflows) Was this page helpful? YesNo [Tool Class Reference](https://docs.vizra.ai/api-reference/tool-class) [Evaluation Class Reference](https://docs.vizra.ai/api-reference/evaluation-class) ⌘I --- # MCP Integration - Vizra ADK [Skip to main content](https://docs.vizra.ai/integrations/mcp#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Integrations MCP Integration [Documentation](https://docs.vizra.ai/) On this page * [What is MCP?](https://docs.vizra.ai/integrations/mcp#what-is-mcp) * [Quick Start - Add MCP in 60 Seconds](https://docs.vizra.ai/integrations/mcp#quick-start-add-mcp-in-60-seconds) * [1\. Install MCP Server](https://docs.vizra.ai/integrations/mcp#1-install-mcp-server) * [2\. Configure in Vizra](https://docs.vizra.ai/integrations/mcp#2-configure-in-vizra) * [3\. Create MCP-Enabled Agent](https://docs.vizra.ai/integrations/mcp#3-create-mcp-enabled-agent) * [4\. Test It Out!](https://docs.vizra.ai/integrations/mcp#4-test-it-out) * [Available MCP Servers](https://docs.vizra.ai/integrations/mcp#available-mcp-servers) * [Filesystem Server](https://docs.vizra.ai/integrations/mcp#filesystem-server) * [GitHub Server](https://docs.vizra.ai/integrations/mcp#github-server) * [PostgreSQL Server](https://docs.vizra.ai/integrations/mcp#postgresql-server) * [Advanced Configuration](https://docs.vizra.ai/integrations/mcp#advanced-configuration) * [Transport Types](https://docs.vizra.ai/integrations/mcp#transport-types) * [Environment-Based Setup](https://docs.vizra.ai/integrations/mcp#environment-based-setup) * [Multiple Servers per Agent](https://docs.vizra.ai/integrations/mcp#multiple-servers-per-agent) * [Management Commands](https://docs.vizra.ai/integrations/mcp#management-commands) * [Real-World Examples](https://docs.vizra.ai/integrations/mcp#real-world-examples) * [Code Review Assistant](https://docs.vizra.ai/integrations/mcp#code-review-assistant) * [Data Analysis Assistant](https://docs.vizra.ai/integrations/mcp#data-analysis-assistant) * [Security Best Practices](https://docs.vizra.ai/integrations/mcp#security-best-practices) * [Troubleshooting](https://docs.vizra.ai/integrations/mcp#troubleshooting) * [Server Connection Failed](https://docs.vizra.ai/integrations/mcp#server-connection-failed) * [Tools Not Available](https://docs.vizra.ai/integrations/mcp#tools-not-available) * [Permission Denied](https://docs.vizra.ai/integrations/mcp#permission-denied) * [Best Practices](https://docs.vizra.ai/integrations/mcp#best-practices) * [MCP Opens Infinite Possibilities](https://docs.vizra.ai/integrations/mcp#mcp-opens-infinite-possibilities) [​](https://docs.vizra.ai/integrations/mcp#what-is-mcp) What is MCP? ----------------------------------------------------------------------- Model Context Protocol (MCP) is like **“USB-C for AI applications”** - a universal standard that lets your agents connect to external data sources and tools. Instead of building custom integrations for every service, you can use the growing ecosystem of MCP servers! File Systems ------------ Read, write, search files and directories with full filesystem access GitHub Integration ------------------ Create issues, manage repos, read code, and automate workflows Databases --------- Query PostgreSQL, MySQL, and other databases directly from agents Web Search ---------- Search the web with Brave Search for real-time information Team Tools ---------- Integrate with Slack, Discord, and other communication platforms Custom Servers -------------- Build your own MCP servers in any language for specialized needs [​](https://docs.vizra.ai/integrations/mcp#quick-start-add-mcp-in-60-seconds) Quick Start - Add MCP in 60 Seconds -------------------------------------------------------------------------------------------------------------------- Getting MCP working with your agents is incredibly simple. Here’s how: ### [​](https://docs.vizra.ai/integrations/mcp#1-install-mcp-server) 1\. Install MCP Server Terminal Copy npm install -g @modelcontextprotocol/server-filesystem ### [​](https://docs.vizra.ai/integrations/mcp#2-configure-in-vizra) 2\. Configure in Vizra config/vizra-adk.php Copy 'mcp_servers' => [\ 'filesystem' => [\ 'command' => 'npx',\ 'args' => [\ '@modelcontextprotocol/server-filesystem',\ storage_path('app'), // Allow access to storage directory\ ],\ 'enabled' => true,\ ],\ ], ### [​](https://docs.vizra.ai/integrations/mcp#3-create-mcp-enabled-agent) 3\. Create MCP-Enabled Agent app/Agents/FileManagerAgent.php Copy [\ 'command' => 'npx',\ 'args' => ['@modelcontextprotocol/server-filesystem', '/safe/path'],\ 'enabled' => true,\ ], **Available Tools:** * `read_file` - Read file contents * `write_file` - Write to files * `list_directory` - List directory contents * `search_files` - Search for files and content ### [​](https://docs.vizra.ai/integrations/mcp#github-server) GitHub Server Comprehensive GitHub integration for repository management and automation. Installation ------------ Copy npm install -g @modelcontextprotocol/server-github Configuration ------------- Copy 'github' => [\ 'command' => 'npx',\ 'args' => ['@modelcontextprotocol/server-github', '--token', env('GITHUB_TOKEN')],\ 'enabled' => !empty(env('GITHUB_TOKEN')),\ ], **Available Tools:** * `create_issue` - Create GitHub issues * `search_repositories` - Search repos * `get_file_contents` - Read files from repos * `list_issues` - List repository issues ### [​](https://docs.vizra.ai/integrations/mcp#postgresql-server) PostgreSQL Server Direct database access for queries and data manipulation. Installation ------------ Copy npm install -g @modelcontextprotocol/server-postgres Configuration ------------- Copy 'postgres' => [\ 'command' => 'npx',\ 'args' => ['@modelcontextprotocol/server-postgres', '--connection-string', env('DATABASE_URL')],\ 'enabled' => !empty(env('DATABASE_URL')),\ ], **Available Tools:** * `query` - Execute SQL queries * `describe_table` - Get table schema * `list_tables` - List all tables * `get_schema` - Get database schema [​](https://docs.vizra.ai/integrations/mcp#advanced-configuration) Advanced Configuration -------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/integrations/mcp#transport-types) Transport Types Vizra ADK supports two transport types for MCP servers: STDIO Transport (Default) ------------------------- Local MCP servers running as subprocesses. Best for filesystem, local databases, and npm packages. Copy 'filesystem' => [\ 'transport' => 'stdio', // Default\ 'command' => 'npx',\ 'args' => ['@modelcontextprotocol/server-filesystem'],\ 'enabled' => true,\ ], HTTP Transport -------------- Remote MCP servers via HTTP/SSE. Perfect for cloud services, microservices, and shared resources. Copy 'github_remote' => [\ 'transport' => 'http',\ 'url' => 'https://mcp.example.com/api',\ 'api_key' => env('MCP_API_KEY'),\ 'enabled' => true,\ ], ### [​](https://docs.vizra.ai/integrations/mcp#environment-based-setup) Environment-Based Setup Use environment variables to control MCP servers across different environments: .env Copy # Enable/disable servers per environment MCP_FILESYSTEM_ENABLED=true MCP_GITHUB_ENABLED=true MCP_POSTGRES_ENABLED=false # Server-specific configuration GITHUB_TOKEN=your_github_token_here DATABASE_URL=postgresql://user:pass@localhost/db BRAVE_API_KEY=your_brave_search_key MCP_NPX_PATH="/path/to/npx" # Optional: specify npx path if not in PATH config/vizra-adk.php Copy 'mcp_servers' => [\ 'filesystem' => [\ 'command' => 'npx',\ 'args' => ['@modelcontextprotocol/server-filesystem', storage_path('app')],\ 'enabled' => env('MCP_FILESYSTEM_ENABLED', false),\ 'timeout' => 30,\ ],\ \ 'github' => [\ 'command' => 'npx',\ 'args' => ['@modelcontextprotocol/server-github', '--token', env('GITHUB_TOKEN')],\ 'enabled' => env('MCP_GITHUB_ENABLED', false) && !empty(env('GITHUB_TOKEN')),\ 'timeout' => 45,\ ],\ \ 'postgres' => [\ 'command' => 'npx',\ 'args' => ['@modelcontextprotocol/server-postgres', '--connection-string', env('DATABASE_URL')],\ 'enabled' => env('MCP_POSTGRES_ENABLED', false) && !empty(env('DATABASE_URL')),\ 'timeout' => 30,\ ],\ ], ### [​](https://docs.vizra.ai/integrations/mcp#multiple-servers-per-agent) Multiple Servers per Agent Agents can use multiple MCP servers simultaneously: Multi-Server Agent Copy class DeveloperAssistantAgent extends BaseLlmAgent { protected string $name = 'developer_assistant'; protected string $instructions = 'You are a comprehensive development assistant with access to: **File System**: Read, write, and search project files **GitHub**: Manage repositories, issues, and pull requests **Database**: Query and analyze data directly Use these tools together to provide powerful development support!'; protected array $mcpServers = ['filesystem', 'github', 'postgres']; } [​](https://docs.vizra.ai/integrations/mcp#management-commands) Management Commands -------------------------------------------------------------------------------------- Vizra ADK provides helpful commands to manage your MCP integration: Terminal Copy # List configured servers and their status php artisan vizra:mcp:servers # Test connections and show available tools from each server php artisan vizra:mcp:servers --test [​](https://docs.vizra.ai/integrations/mcp#real-world-examples) Real-World Examples -------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/integrations/mcp#code-review-assistant) Code Review Assistant Code Review Agent Copy class CodeReviewAgent extends BaseLlmAgent { protected string $name = 'code_reviewer'; protected string $instructions = 'You are an expert code reviewer. You can: 1. Read code files to understand implementations 2. Search for patterns and potential issues 3. Create GitHub issues for problems found 4. Suggest improvements and best practices Always provide constructive feedback with specific examples.'; protected array $mcpServers = ['filesystem', 'github']; } **Example Conversation:** * **User:** “Review the authentication code in src/Auth/” * **Agent:** “I’ll examine the authentication code for you…” * Uses filesystem tools to read auth files * Analyzes code for security issues * Creates GitHub issue for potential vulnerability * **Agent:** “Found 3 areas for improvement. Created issue #42 for the critical security concern.” ### [​](https://docs.vizra.ai/integrations/mcp#data-analysis-assistant) Data Analysis Assistant Data Analysis Agent Copy class DataAnalystAgent extends BaseLlmAgent { protected string $name = 'data_analyst'; protected string $instructions = 'You are a data analysis expert. You can: 1. Query databases to extract insights 2. Generate reports and save them as files 3. Create data visualizations and charts 4. Identify trends and anomalies in data Always explain your analysis methodology and findings clearly.'; protected array $mcpServers = ['postgres', 'filesystem']; } [​](https://docs.vizra.ai/integrations/mcp#security-best-practices) Security Best Practices ---------------------------------------------------------------------------------------------- **Filesystem Security** * **Limit directory access** - Only allow access to safe directories * **Use storage paths** - Prefer `storage_path()` over system directories * **Validate file operations** - MCP servers should validate all file paths * **Monitor file access** - Log all file operations for audit trails **API Token Security** * **Use environment variables** - Never hardcode tokens in config * **Minimal permissions** - Grant only necessary API permissions * **Rotate tokens regularly** - Set up token rotation schedules * **Monitor usage** - Track API calls and unusual activity **Environment Isolation** * **Separate configs** - Different MCP servers for dev/staging/prod * **Sandbox testing** - Test MCP integrations in isolated environments * **Resource limits** - Set appropriate timeouts and resource constraints * **Error handling** - Graceful degradation when MCP servers are unavailable [​](https://docs.vizra.ai/integrations/mcp#troubleshooting) Troubleshooting ------------------------------------------------------------------------------ ### [​](https://docs.vizra.ai/integrations/mcp#server-connection-failed) Server Connection Failed **Error:** “Failed to start MCP server” * Check that the MCP server package is installed globally * Verify the command path and arguments in config * Run `php artisan vizra:mcp:servers --test` for details ### [​](https://docs.vizra.ai/integrations/mcp#tools-not-available) Tools Not Available **Error:** “Tool not found” or tools not appearing * Ensure the server is enabled in configuration * Check that the mcpServers property includes the server * Clear cache and restart the application ### [​](https://docs.vizra.ai/integrations/mcp#permission-denied) Permission Denied **Error:** “Access denied” or “Insufficient permissions” * Check filesystem permissions for directory access * Verify API tokens have necessary permissions * Ensure environment variables are set correctly [​](https://docs.vizra.ai/integrations/mcp#best-practices) Best Practices ---------------------------------------------------------------------------- Agent Design ------------ * **Single responsibility** - Each agent should have a clear, focused purpose * **Appropriate tools** - Only include MCP servers the agent actually needs * **Clear instructions** - Explain what MCP capabilities the agent has * **Error handling** - Handle MCP failures gracefully in agent instructions Performance ----------- * **Cache wisely** - MCP tool discovery is cached for 5 minutes * **Connection pooling** - MCP clients are reused across requests * **Timeout settings** - Set appropriate timeouts for different server types * **Monitor usage** - Track MCP server performance and availability Development Workflow -------------------- * **Test locally first** - Use `--test` flag to verify servers * **Gradual rollout** - Enable MCP servers incrementally * **Monitor logs** - Watch for MCP-related errors and performance issues * **Documentation** - Document which agents use which MCP servers [​](https://docs.vizra.ai/integrations/mcp#mcp-opens-infinite-possibilities) MCP Opens Infinite Possibilities ---------------------------------------------------------------------------------------------------------------- Your agents can now connect to any data source or service in the MCP ecosystem. [Learn About Tools\ -----------------\ \ Understand how tools work and combine with MCP](https://docs.vizra.ai/concepts/tools) [Build Better Agents\ -------------------\ \ Create more powerful agents with MCP integration](https://docs.vizra.ai/concepts/agents) Was this page helpful? YesNo [OpenAI Compatibility](https://docs.vizra.ai/integrations/openai-compatibility) [Laravel Boost Integration](https://docs.vizra.ai/integrations/laravel-boost) ⌘I --- # Web Dashboard - Vizra ADK [Skip to main content](https://docs.vizra.ai/testing/web-dashboard#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Testing & Observability Web Dashboard [Documentation](https://docs.vizra.ai/) On this page * [What’s the Web Dashboard?](https://docs.vizra.ai/testing/web-dashboard#what%E2%80%99s-the-web-dashboard) * [Accessing the Dashboard](https://docs.vizra.ai/testing/web-dashboard#accessing-the-dashboard) * [Dashboard Components](https://docs.vizra.ai/testing/web-dashboard#dashboard-components) * [Main Dashboard](https://docs.vizra.ai/testing/web-dashboard#main-dashboard) * [Chat Interface](https://docs.vizra.ai/testing/web-dashboard#chat-interface) * [Evaluation Runner](https://docs.vizra.ai/testing/web-dashboard#evaluation-runner) * [Configuration](https://docs.vizra.ai/testing/web-dashboard#configuration) * [Disabling the Dashboard](https://docs.vizra.ai/testing/web-dashboard#disabling-the-dashboard) * [Custom Route Prefix](https://docs.vizra.ai/testing/web-dashboard#custom-route-prefix) * [Adding Authentication](https://docs.vizra.ai/testing/web-dashboard#adding-authentication) * [Dashboard Routes](https://docs.vizra.ai/testing/web-dashboard#dashboard-routes) * [Dashboard Command](https://docs.vizra.ai/testing/web-dashboard#dashboard-command) * [Security Considerations](https://docs.vizra.ai/testing/web-dashboard#security-considerations) * [Ready to Explore?](https://docs.vizra.ai/testing/web-dashboard#ready-to-explore) [​](https://docs.vizra.ai/testing/web-dashboard#what%E2%80%99s-the-web-dashboard) What’s the Web Dashboard? -------------------------------------------------------------------------------------------------------------- The web dashboard is a **Livewire-powered interface** that ships with the Vizra ADK package. It provides real-time monitoring, interactive testing, and management capabilities for your agents - all through your browser! Real-time Monitoring -------------------- Live agent stats, system health, and activity tracking Interactive Testing ------------------- Chat with your agents directly from the browser Evaluation Runner ----------------- Run and visualize evaluation results with ease Quick Commands -------------- Copy-ready artisan commands for rapid development [​](https://docs.vizra.ai/testing/web-dashboard#accessing-the-dashboard) Accessing the Dashboard --------------------------------------------------------------------------------------------------- By default, the web dashboard is accessible at the `/vizra` route of your Laravel application. The dashboard URL will be displayed after running the installation command. [​](https://docs.vizra.ai/testing/web-dashboard#dashboard-components) Dashboard Components --------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/testing/web-dashboard#main-dashboard) Main Dashboard The main dashboard provides an overview of your Vizra ADK installation: ![Web Dashboard](https://mintlify.s3.us-west-1.amazonaws.com/vizra-0d76d98a/img/screenshots/web-dashboard.png) * **Package Information**: Current version and configuration status * **Agent Registry**: Live display of all registered agents * **Quick Commands**: Copy-ready artisan commands for common tasks * **System Status**: Health indicators and configuration checks ### [​](https://docs.vizra.ai/testing/web-dashboard#chat-interface) Chat Interface The chat interface allows interactive testing of your agents: ![Chat Interface](https://mintlify.s3.us-west-1.amazonaws.com/vizra-0d76d98a/img/screenshots/web-chat.png) **Features include:** * Real-time streaming responses * Session management * Message history * Agent selection dropdown ### [​](https://docs.vizra.ai/testing/web-dashboard#evaluation-runner) Evaluation Runner The evaluation runner provides a visual interface for running and monitoring evaluations: ![Evaluation Runner](https://mintlify.s3.us-west-1.amazonaws.com/vizra-0d76d98a/img/screenshots/web-evals.png) [​](https://docs.vizra.ai/testing/web-dashboard#configuration) Configuration ------------------------------------------------------------------------------- The web dashboard can be configured in your `config/vizra.php` file: config/vizra.php Copy 'routes' => [\ 'web' => [\ 'enabled' => env('VIZRA_WEB_ENABLED', true),\ 'prefix' => 'vizra',\ 'middleware' => ['web'],\ ],\ ], ### [​](https://docs.vizra.ai/testing/web-dashboard#disabling-the-dashboard) Disabling the Dashboard To disable the web dashboard in production: .env Copy # Disable web dashboard VIZRA_WEB_ENABLED=false ### [​](https://docs.vizra.ai/testing/web-dashboard#custom-route-prefix) Custom Route Prefix To change the dashboard URL prefix: config/vizra.php Copy 'routes' => [\ 'web' => [\ 'prefix' => 'ai-dashboard', // Now accessible at /ai-dashboard\ ],\ ], ### [​](https://docs.vizra.ai/testing/web-dashboard#adding-authentication) Adding Authentication To protect the dashboard with authentication: config/vizra.php Copy 'routes' => [\ 'web' => [\ 'middleware' => ['web', 'auth'], // Requires authentication\ ],\ ], [​](https://docs.vizra.ai/testing/web-dashboard#dashboard-routes) Dashboard Routes ------------------------------------------------------------------------------------- The web dashboard registers the following routes: | Route | Description | | --- | --- | | `/vizra` | Main dashboard overview | | `/vizra/chat` | Interactive agent testing | | `/vizra/eval` | Evaluation runner interface | [​](https://docs.vizra.ai/testing/web-dashboard#dashboard-command) Dashboard Command --------------------------------------------------------------------------------------- The `vizra:dashboard` command provides quick access: Terminal Copy # Display dashboard URL php artisan vizra:dashboard # Open dashboard in browser php artisan vizra:dashboard --open [​](https://docs.vizra.ai/testing/web-dashboard#security-considerations) Security Considerations --------------------------------------------------------------------------------------------------- **Important Security Notes** * Always protect the dashboard with authentication in production * Consider IP whitelisting for sensitive environments * Disable the dashboard entirely if not needed (`VIZRA_WEB_ENABLED=false`) * Use HTTPS in production environments [​](https://docs.vizra.ai/testing/web-dashboard#ready-to-explore) Ready to Explore? -------------------------------------------------------------------------------------- Now that you understand the web dashboard, dive deeper into: [Learn about Agents\ ------------------\ \ Build your first AI teammates](https://docs.vizra.ai/concepts/agents) [Explore Commands\ ----------------\ \ Master the CLI tools](https://docs.vizra.ai/api/artisan-commands) [Master Evaluations\ ------------------\ \ Test your agents like a pro](https://docs.vizra.ai/concepts/evaluations) Was this page helpful? YesNo [Tracing](https://docs.vizra.ai/testing/tracing) [Artisan Commands](https://docs.vizra.ai/api-reference/artisan-commands) ⌘I --- # Getting Started - Vizra ADK [Skip to main content](https://docs.vizra.ai/installation/getting-started#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Getting Started Getting Started [Documentation](https://docs.vizra.ai/) On this page * [Installation via Composer](https://docs.vizra.ai/installation/getting-started#installation-via-composer) * [Running the Install Command](https://docs.vizra.ai/installation/getting-started#running-the-install-command) * [Setting Up Your AI Provider](https://docs.vizra.ai/installation/getting-started#setting-up-your-ai-provider) * [Which Provider Should I Choose?](https://docs.vizra.ai/installation/getting-started#which-provider-should-i-choose) * [5-Minute Quick Start: Build a Smart Assistant](https://docs.vizra.ai/installation/getting-started#5-minute-quick-start-build-a-smart-assistant) * [Step 1: Create the Agent](https://docs.vizra.ai/installation/getting-started#step-1-create-the-agent) * [Step 2: Configure Your Agent](https://docs.vizra.ai/installation/getting-started#step-2-configure-your-agent) * [Step 3: Test Your Agent](https://docs.vizra.ai/installation/getting-started#step-3-test-your-agent) * [Step 4: Use in Your Application](https://docs.vizra.ai/installation/getting-started#step-4-use-in-your-application) * [Congratulations! You Did It!](https://docs.vizra.ai/installation/getting-started#congratulations-you-did-it) * [Common Issues & Quick Fixes](https://docs.vizra.ai/installation/getting-started#common-issues-%26-quick-fixes) * [”Invalid API Key” or “Unauthorized” Errors](https://docs.vizra.ai/installation/getting-started#%E2%80%9Dinvalid-api-key%E2%80%9D-or-%E2%80%9Cunauthorized%E2%80%9D-errors) * [“Agent Not Found” Errors](https://docs.vizra.ai/installation/getting-started#%E2%80%9Cagent-not-found%E2%80%9D-errors) * [Database/Migration Issues](https://docs.vizra.ai/installation/getting-started#database%2Fmigration-issues) * [Next Steps](https://docs.vizra.ai/installation/getting-started#next-steps) Building AI agents has never been easier! In just a few steps, you’ll have your own intelligent agent up and running. [​](https://docs.vizra.ai/installation/getting-started#installation-via-composer) Installation via Composer -------------------------------------------------------------------------------------------------------------- Let’s kick things off! First, we’ll add Vizra ADK to your Laravel project: Terminal Copy composer require vizra/vizra-adk [​](https://docs.vizra.ai/installation/getting-started#running-the-install-command) Running the Install Command ------------------------------------------------------------------------------------------------------------------ Now let’s set everything up with our magical installation command: Terminal Copy php artisan vizra:install This command publishes config, runs migrations, sets up the web interface, and creates example agents to get you started! [​](https://docs.vizra.ai/installation/getting-started#setting-up-your-ai-provider) Setting Up Your AI Provider ------------------------------------------------------------------------------------------------------------------ Before your agents can start thinking, they need access to an AI provider. Add your preferred AI provider’s API key to your `.env` file: .env Copy # Choose one (or add multiple!) OPENAI_API_KEY=your-openai-api-key-here ANTHROPIC_API_KEY=your-anthropic-api-key-here GEMINI_API_KEY=your-gemini-api-key-here OpenAI ------ GPT-4, GPT-3.5 Turbo[Get API Key](https://platform.openai.com/api-keys) Anthropic --------- Claude 3 Models[Get API Key](https://console.anthropic.com/account/keys) Google ------ Gemini Pro Models[Get API Key](https://makersuite.google.com/app/apikey) ### [​](https://docs.vizra.ai/installation/getting-started#which-provider-should-i-choose) Which Provider Should I Choose? * **OpenAI:** Great all-around choice, GPT-4 for complex tasks, GPT-3.5 for speed * **Anthropic:** Claude excels at analysis, writing, and following instructions * **Google:** Gemini offers great performance and generous free tier Don’t worry - you can switch providers anytime or use different ones for different agents! Vizra ADK supports 10+ AI providers through [Prism PHP](https://github.com/echolabsdev/prism) , including DeepSeek, Mistral, Groq, and more. [See all providers](https://docs.vizra.ai/api-reference/providers) [​](https://docs.vizra.ai/installation/getting-started#5-minute-quick-start-build-a-smart-assistant) 5-Minute Quick Start: Build a Smart Assistant ----------------------------------------------------------------------------------------------------------------------------------------------------- Let’s build something real! In just 5 minutes, you’ll create an intelligent FAQ assistant that can answer questions about your product. ### [​](https://docs.vizra.ai/installation/getting-started#step-1-create-the-agent) Step 1: Create the Agent Terminal Copy php artisan vizra:make:agent ProductAssistant Agent created at `app/Agents/ProductAssistant.php` ### [​](https://docs.vizra.ai/installation/getting-started#step-2-configure-your-agent) Step 2: Configure Your Agent Open the agent file and give it some personality and knowledge: app/Agents/ProductAssistant.php Copy input('message')) ->forUser(auth()->user()) ->go(); Your agent automatically maintains conversation history per user! [​](https://docs.vizra.ai/installation/getting-started#congratulations-you-did-it) Congratulations! You Did It! ------------------------------------------------------------------------------------------------------------------ In just 5 minutes, you’ve created an AI assistant that can answer questions about your product. But this is just the beginning! Your agent can do so much more: * Add **custom tools** to let it search databases, send emails, or call APIs * Delegate tasks to **sub agents** * Enable **vector memory** to give it knowledge from your documentation * Create **workflows** to handle complex multi-step processes * Run **evaluations** to ensure quality at scale [​](https://docs.vizra.ai/installation/getting-started#common-issues-&-quick-fixes) Common Issues & Quick Fixes ------------------------------------------------------------------------------------------------------------------ ### [​](https://docs.vizra.ai/installation/getting-started#%E2%80%9Dinvalid-api-key%E2%80%9D-or-%E2%80%9Cunauthorized%E2%80%9D-errors) ”Invalid API Key” or “Unauthorized” Errors This is the most common issue! Here’s how to fix it: 1. Check your `.env` file has the correct API key (no extra spaces!) 2. Clear config cache: `php artisan config:clear` 3. Verify the API key is active in your provider’s dashboard 4. For OpenAI: Ensure you have billing set up (even for free tier) ### [​](https://docs.vizra.ai/installation/getting-started#%E2%80%9Cagent-not-found%E2%80%9D-errors) “Agent Not Found” Errors * Make sure your agent class extends `BaseLlmAgent` * Agent file must be in `app/Agents/` directory * Class name must match filename (PSR-4 autoloading) * Run `composer dump-autoload` if needed ### [​](https://docs.vizra.ai/installation/getting-started#database/migration-issues) Database/Migration Issues If you see database errors: Terminal Copy # Reset and re-run migrations php artisan migrate:fresh php artisan vizra:install This will reset your database! Use with caution in production. [​](https://docs.vizra.ai/installation/getting-started#next-steps) Next Steps -------------------------------------------------------------------------------- [Configuration\ -------------\ \ Fine-tune Vizra ADK to match your project’s needs perfectly](https://docs.vizra.ai/installation/configuration) [Understanding Agents\ --------------------\ \ Master the art of building intelligent AI agents](https://docs.vizra.ai/concepts/agents) Was this page helpful? YesNo [Vizra ADK](https://docs.vizra.ai/) [Requirements Checklist](https://docs.vizra.ai/installation/requirements) ⌘I --- # Tracing - Vizra ADK [Skip to main content](https://docs.vizra.ai/testing/tracing#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Testing & Observability Tracing [Documentation](https://docs.vizra.ai/) On this page * [What Gets Captured?](https://docs.vizra.ai/testing/tracing#what-gets-captured) * [Viewing Your Traces](https://docs.vizra.ai/testing/tracing#viewing-your-traces) * [Web Interface - The Visual Experience!](https://docs.vizra.ai/testing/tracing#web-interface-the-visual-experience) * [CLI Commands - For the Terminal Warriors!](https://docs.vizra.ai/testing/tracing#cli-commands-for-the-terminal-warriors) * [Understanding Trace Structure](https://docs.vizra.ai/testing/tracing#understanding-trace-structure) * [Programmatic Tracing](https://docs.vizra.ai/testing/tracing#programmatic-tracing) * [Accessing Traces in Code](https://docs.vizra.ai/testing/tracing#accessing-traces-in-code) * [Creating Custom Spans](https://docs.vizra.ai/testing/tracing#creating-custom-spans) * [Analyzing Your Traces](https://docs.vizra.ai/testing/tracing#analyzing-your-traces) * [Performance Analysis](https://docs.vizra.ai/testing/tracing#performance-analysis) * [Error Tracking](https://docs.vizra.ai/testing/tracing#error-tracking) * [Configuring Tracing](https://docs.vizra.ai/testing/tracing#configuring-tracing) * [Configuration Options](https://docs.vizra.ai/testing/tracing#configuration-options) * [Environment Variables](https://docs.vizra.ai/testing/tracing#environment-variables) * [Data Retention & Cleanup](https://docs.vizra.ai/testing/tracing#data-retention-%26-cleanup) * [How Tracing Works Behind the Scenes](https://docs.vizra.ai/testing/tracing#how-tracing-works-behind-the-scenes) * [Automatic Span Creation](https://docs.vizra.ai/testing/tracing#automatic-span-creation) * [Manual Span Creation](https://docs.vizra.ai/testing/tracing#manual-span-creation) * [Debugging Like a Detective](https://docs.vizra.ai/testing/tracing#debugging-like-a-detective) * [Common Issues & Solutions](https://docs.vizra.ai/testing/tracing#common-issues-%26-solutions) * [Tracing Best Practices](https://docs.vizra.ai/testing/tracing#tracing-best-practices) * [You’re Now a Tracing Expert!](https://docs.vizra.ai/testing/tracing#you%E2%80%99re-now-a-tracing-expert) **What is Tracing?** - Think of tracing as having superpowers that let you see through your agent’s execution! Every conversation, every tool call, every decision - it’s all captured in beautiful detail. No more guessing what went wrong or why something is slow! [​](https://docs.vizra.ai/testing/tracing#what-gets-captured) What Gets Captured? ------------------------------------------------------------------------------------ Execution Timeline ------------------ Complete timeline with nested spans showing exactly when each operation happened LLM Interactions ---------------- Every request and response, including prompts, completions, and model details Tool Executions --------------- All tool calls with their parameters, results, and execution time Memory Operations ----------------- Vector searches, context retrieval, and memory storage operations Token Usage ----------- Detailed token counts and costs for every LLM interaction Performance Metrics ------------------- Bottlenecks, slow operations, and optimization opportunities [​](https://docs.vizra.ai/testing/tracing#viewing-your-traces) Viewing Your Traces ------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/testing/tracing#web-interface-the-visual-experience) Web Interface - The Visual Experience! Fire up your browser and navigate to `http://your-app.test/vizra/traces` for the full visual experience! Interactive Timeline -------------------- Zoom, pan, and explore your execution flow visually Span Details ------------ Click any span to see inputs, outputs, and metadata Waterfall Charts ---------------- Visualize performance bottlenecks at a glance Token Analytics --------------- See exactly where your tokens are being spent ### [​](https://docs.vizra.ai/testing/tracing#cli-commands-for-the-terminal-warriors) CLI Commands - For the Terminal Warriors! Prefer the command line? We’ve got you covered with powerful CLI tools! **Pro Tip:** Every agent interaction creates a unique session ID (like `abc123`). Use this session ID to view all the execution traces from that conversation! You can find the session ID in your agent responses or logs. Terminal Copy # View traces for a session php artisan vizra:trace {session_id} # Example: View all traces for session abc123 php artisan vizra:trace abc123 # View trace with additional options php artisan vizra:trace abc123 --format=tree --show-input --show-output # View a specific trace ID instead of all session traces php artisan vizra:trace any-session --trace-id=specific-trace-id # Clean up old traces php artisan vizra:trace:cleanup --days=30 [​](https://docs.vizra.ai/testing/tracing#understanding-trace-structure) Understanding Trace Structure --------------------------------------------------------------------------------------------------------- Traces are organized in a beautiful tree structure, just like a family tree! Each operation has parent and child relationships that show you exactly how your agent thinks. Typical Trace Structure Copy Agent Execution (root span) ├── Session Initialization ├── Memory Retrieval │ ├── Vector Search │ └── Context Building ├── LLM Request │ ├── Prompt Construction │ ├── API Call │ └── Response Processing ├── Tool Execution │ ├── Tool: order_lookup │ └── Tool: send_email └── Memory Storage | Span Type | Description | | --- | --- | | Root Span | The main execution | | Parent Spans | Major operations | | Child Spans | Detailed steps | [​](https://docs.vizra.ai/testing/tracing#programmatic-tracing) Programmatic Tracing --------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/testing/tracing#accessing-traces-in-code) Accessing Traces in Code Want to build your own debugging tools? Access trace data directly in your code! It’s like having a debugger API at your fingertips. TraceAccess.php Copy use Vizra\ADK\Tracing\TraceManager; // Get trace for a session $trace = TraceManager::forSession($sessionId); // Loop through all spans foreach ($trace->spans as $span) { echo $span->name . ': ' . $span->duration . "ms\n"; } // Get performance metrics $metrics = $trace->getMetrics(); echo "Total Duration: " . $metrics['total_duration'] . "ms\n"; echo "Token Usage: " . $metrics['total_tokens'] . "\n"; ### [​](https://docs.vizra.ai/testing/tracing#creating-custom-spans) Creating Custom Spans Add your own spans to trace custom operations! Perfect for tracking database queries, API calls, or any complex logic. CustomTool.php Copy use Vizra\ADK\Tracing\Tracer; class CustomTool extends BaseTool { public function execute(array $parameters): ToolResult { return Tracer::span('custom_operation', function() use ($parameters) { // Add span attributes Tracer::addAttribute('operation.type', 'database'); Tracer::addAttribute('query.complexity', 'high'); // Your operation $result = $this->performOperation($parameters); // Add result to span Tracer::addEvent('operation_completed', [\ 'records_processed' => count($result),\ ]); return ToolResult::success($result); }); } } The `Tracer::span()` method automatically handles timing, error capturing, and span hierarchy. Just wrap your code and let it do the magic! [​](https://docs.vizra.ai/testing/tracing#analyzing-your-traces) Analyzing Your Traces ----------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/testing/tracing#performance-analysis) Performance Analysis Find those pesky bottlenecks and optimize like a pro! Let’s hunt down slow operations and expensive API calls. PerformanceAnalysis.php Copy // Find slow operations $slowSpans = $trace->getSlowSpans(1000); // Spans over 1 second foreach ($slowSpans as $span) { echo "Slow operation: {$span->name} took {$span->duration}ms\n"; } // Analyze token usage $tokenAnalysis = $trace->analyzeTokenUsage(); echo "Most expensive span: " . $tokenAnalysis['most_expensive']->name; echo " used " . $tokenAnalysis['most_expensive']->tokens . " tokens\n"; Quick Wins ---------- Look for operations over 500ms - they’re usually the easiest to optimize! Token Tip --------- High token usage often means verbose prompts - try to be more concise! ### [​](https://docs.vizra.ai/testing/tracing#error-tracking) Error Tracking Errors happen to the best of us! Track them down and squash those bugs with precision. ErrorTracking.php Copy // Find failed spans $errors = $trace->getErrors(); foreach ($errors as $error) { echo "Error in {$error->span->name}: {$error->message}\n"; echo "Stack trace:\n{$error->stackTrace}\n"; } **Error Recovery Tips:** * Check error patterns - repeated errors often have the same root cause * Look at parent spans - context matters! * Review input parameters - bad data in = errors out * Monitor error rates over time to catch regressions early [​](https://docs.vizra.ai/testing/tracing#configuring-tracing) Configuring Tracing ------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/testing/tracing#configuration-options) Configuration Options Fine-tune your tracing setup to match your needs! Control what gets traced, how long to keep data, and more. config/vizra-adk.php Copy 'tracing' => [\ 'enabled' => env('VIZRA_ADK_TRACING_ENABLED', true),\ 'table' => 'agent_trace_spans',\ 'cleanup_days' => env('VIZRA_ADK_TRACING_CLEANUP_DAYS', 30),\ ]; ### [​](https://docs.vizra.ai/testing/tracing#environment-variables) Environment Variables Set these in your `.env` file to control tracing behavior across environments! .env Copy # Enable/disable tracing VIZRA_ADK_TRACING_ENABLED=true # Days to keep trace data before cleanup VIZRA_ADK_TRACING_CLEANUP_DAYS=30 Development Tip --------------- Always enable tracing in development for maximum visibility! Production Tip -------------- Consider sampling in production to balance insights with performance. ### [​](https://docs.vizra.ai/testing/tracing#data-retention-&-cleanup) Data Retention & Cleanup Keep your database lean and mean! Set up automatic cleanup to remove old traces. Terminal Copy # Clean up old traces (uses config value, default 30 days) php artisan vizra:trace:cleanup # Keep last 30 days of traces (delete anything older) php artisan vizra:trace:cleanup --days=30 # Keep last week of traces (delete anything older) php artisan vizra:trace:cleanup --days=7 # Keep only today's traces (delete anything from yesterday or earlier) php artisan vizra:trace:cleanup --days=1 # Delete ALL traces (use with caution!) php artisan vizra:trace:cleanup --days=0 # Dry run to see what would be deleted php artisan vizra:trace:cleanup --days=7 --dry-run # Skip confirmation prompt php artisan vizra:trace:cleanup --days=7 --force **Pro Tip: Schedule It!** - Add this to your Laravel scheduler for automatic cleanup: app/Console/Kernel.php Copy $schedule->command('vizra:trace:cleanup')->daily(); [​](https://docs.vizra.ai/testing/tracing#how-tracing-works-behind-the-scenes) How Tracing Works Behind the Scenes --------------------------------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/testing/tracing#automatic-span-creation) Automatic Span Creation The ADK works its magic by automatically creating spans for key operations. No manual instrumentation needed! Agent Execution --------------- Root span created when agent runs`BaseLlmAgent::handle()` LLM Calls --------- Every AI interaction tracked`BaseLlmAgent::callLlm()` Tool Calls ---------- Tool execution monitoring`BaseLlmAgent::executeTool()` Sub-agent Calls --------------- Delegation trackingWhen delegating to sub-agents ### [​](https://docs.vizra.ai/testing/tracing#manual-span-creation) Manual Span Creation Need more control? Create your own spans for custom operations! Perfect for tracking specific business logic. CustomOperation.php Copy use Vizra\VizraADK\Services\Tracer; class CustomOperation { public function process(Tracer $tracer) { // Start a custom span $spanId = $tracer->startSpan( type: 'custom_operation', name: 'Process Data', input: ['records' => 100], metadata: ['batch_id' => 'abc123'] ); try { // Your operation $result = $this->doWork(); // End span with success $tracer->endSpan($spanId, ['processed' => 100]); } catch (\Throwable $e) { // Mark span as failed $tracer->failSpan($spanId, $e); throw $e; } } } **Span Best Practices:** * Keep span names descriptive and consistent * Add relevant metadata for better filtering * Always handle errors to mark spans as failed * Use nested spans for complex operations [​](https://docs.vizra.ai/testing/tracing#debugging-like-a-detective) Debugging Like a Detective --------------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/testing/tracing#common-issues-&-solutions) Common Issues & Solutions Let’s solve those mysteries! Here are the most common issues and how to track them down. Slow LLM Calls -------------- Check prompt size and model selection**Tip:** Smaller prompts = faster responses! Failed Tool Calls ----------------- Review parameters and error messages**Tip:** Check for missing required params! High Token Usage ---------------- Optimize prompts and context**Tip:** Use system prompts wisely! Memory Misses ------------- Verify vector search configuration**Tip:** Check embedding model consistency! Timeout Errors -------------- Identify bottlenecks in execution**Tip:** Look for sequential operations! Retry Loops ----------- Check for infinite retry patterns**Tip:** Add exponential backoff! [​](https://docs.vizra.ai/testing/tracing#tracing-best-practices) Tracing Best Practices ------------------------------------------------------------------------------------------- Development ----------- * Enable tracing for all requests - visibility is king! * Add custom spans for business logic * Use trace viewer frequently during development Production ---------- * Use sampling to control costs and performance * Set up alerts for anomalies and errors * Regularly clean up old traces **Golden Rules:** 1. **Review traces regularly** - Make it a habit! 2. **Export important traces** - Keep them for post-mortems 3. **Share traces with your team** - Collective debugging is powerful 4. **Learn from patterns** - Similar issues often have similar traces * * * [​](https://docs.vizra.ai/testing/tracing#you%E2%80%99re-now-a-tracing-expert) You’re Now a Tracing Expert! -------------------------------------------------------------------------------------------------------------- With the power of tracing, you can see through your agents like never before. No more mysteries, no more guessing - just pure visibility and control! Remember: Great debugging starts with great tracing. Use it liberally, learn from it constantly, and let it guide you to building amazing AI agents! Was this page helpful? YesNo [Evaluations](https://docs.vizra.ai/testing/evaluations) [Web Dashboard](https://docs.vizra.ai/testing/web-dashboard) ⌘I --- # Dynamic Prompts - Vizra ADK [Skip to main content](https://docs.vizra.ai/concepts/dynamic-prompts#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Advanced Features Dynamic Prompts [Documentation](https://docs.vizra.ai/) On this page * [Why Dynamic Prompts Change Everything](https://docs.vizra.ai/concepts/dynamic-prompts#why-dynamic-prompts-change-everything) * [Versions vs Variants: What’s the Difference?](https://docs.vizra.ai/concepts/dynamic-prompts#versions-vs-variants-what%E2%80%99s-the-difference) * [The Magic: Use Both Together!](https://docs.vizra.ai/concepts/dynamic-prompts#the-magic-use-both-together) * [Getting Started with Dynamic Prompts](https://docs.vizra.ai/concepts/dynamic-prompts#getting-started-with-dynamic-prompts) * [Real-World Example: Customer Support Agent](https://docs.vizra.ai/concepts/dynamic-prompts#real-world-example-customer-support-agent) * [Blade Templates for Dynamic Prompts](https://docs.vizra.ai/concepts/dynamic-prompts#blade-templates-for-dynamic-prompts) * [How It Works](https://docs.vizra.ai/concepts/dynamic-prompts#how-it-works) * [Available Variables](https://docs.vizra.ai/concepts/dynamic-prompts#available-variables) * [Custom Variables](https://docs.vizra.ai/concepts/dynamic-prompts#custom-variables) * [When to Use What](https://docs.vizra.ai/concepts/dynamic-prompts#when-to-use-what) * [Organizing Your Prompts](https://docs.vizra.ai/concepts/dynamic-prompts#organizing-your-prompts) * [CLI Command Mastery](https://docs.vizra.ai/concepts/dynamic-prompts#cli-command-mastery) * [Creating Prompts](https://docs.vizra.ai/concepts/dynamic-prompts#creating-prompts) * [Listing Prompts](https://docs.vizra.ai/concepts/dynamic-prompts#listing-prompts) * [Import & Export](https://docs.vizra.ai/concepts/dynamic-prompts#import-%26-export) * [Runtime Magic](https://docs.vizra.ai/concepts/dynamic-prompts#runtime-magic) * [Setting Default Version in Agent Class](https://docs.vizra.ai/concepts/dynamic-prompts#setting-default-version-in-agent-class) * [Using Blade Templates at Runtime](https://docs.vizra.ai/concepts/dynamic-prompts#using-blade-templates-at-runtime) * [Runtime Version Selection](https://docs.vizra.ai/concepts/dynamic-prompts#runtime-version-selection) * [Advanced Patterns](https://docs.vizra.ai/concepts/dynamic-prompts#advanced-patterns) * [Evaluation Integration](https://docs.vizra.ai/concepts/dynamic-prompts#evaluation-integration) * [CSV-Driven Testing](https://docs.vizra.ai/concepts/dynamic-prompts#csv-driven-testing) * [Configuration Options](https://docs.vizra.ai/concepts/dynamic-prompts#configuration-options) * [Database Storage (Advanced)](https://docs.vizra.ai/concepts/dynamic-prompts#database-storage-advanced) * [Best Practices](https://docs.vizra.ai/concepts/dynamic-prompts#best-practices) * [Troubleshooting](https://docs.vizra.ai/concepts/dynamic-prompts#troubleshooting) * [Prompt Not Loading?](https://docs.vizra.ai/concepts/dynamic-prompts#prompt-not-loading) * [Database Prompts Not Working?](https://docs.vizra.ai/concepts/dynamic-prompts#database-prompts-not-working) * [You’re Now a Dynamic Prompts Pro!](https://docs.vizra.ai/concepts/dynamic-prompts#you%E2%80%99re-now-a-dynamic-prompts-pro) [​](https://docs.vizra.ai/concepts/dynamic-prompts#why-dynamic-prompts-change-everything) Why Dynamic Prompts Change Everything ---------------------------------------------------------------------------------------------------------------------------------- Remember changing code just to tweak your AI’s personality? Those days are OVER! With dynamic prompts, you can experiment, test, and perfect your agent’s responses without deploying a single line of code. A/B Testing ----------- Test different prompts side-by-side Instant Rollback ---------------- Revert to any previous version Track Performance ----------------- See which prompts work best [​](https://docs.vizra.ai/concepts/dynamic-prompts#versions-vs-variants-what%E2%80%99s-the-difference) Versions vs Variants: What’s the Difference? ------------------------------------------------------------------------------------------------------------------------------------------------------ There’s an important distinction between **versions** and **variants**. Vizra ADK supports **BOTH** seamlessly! Versions -------- Track **improvements over time**. Each version builds on the last, getting better and smarter. Copy v1: "You are a helpful assistant" v2: "You are a helpful assistant. Be concise." v3: "You are a helpful assistant. Be concise and cite sources." Use for: A/B testing improvements, safe rollbacks, tracking prompt evolution Variants -------- Different **styles for different contexts**. Same capability, different personality. Copy formal: "I shall assist you with utmost professionalism" casual: "Hey! Happy to help out" technical: "Initiating support protocol. State your query." Use for: User preferences, context-specific responses, brand voices ### [​](https://docs.vizra.ai/concepts/dynamic-prompts#the-magic-use-both-together) The Magic: Use Both Together! **File Structure:** Copy resources/prompts/support_agent/ ├── v1/ │ ├── default.md │ ├── formal.md │ └── casual.md └── v2/ ├── default.md ├── formal.md └── casual.md **Usage Examples:** Copy // Use latest version, default variant SupportAgent::run('Help')->go(); // Use specific variant SupportAgent::run('Help') ->withPromptVersion('formal') ->go(); // Use specific version & variant SupportAgent::run('Help') ->withPromptVersion('v1/casual') ->go(); [​](https://docs.vizra.ai/concepts/dynamic-prompts#getting-started-with-dynamic-prompts) Getting Started with Dynamic Prompts -------------------------------------------------------------------------------------------------------------------------------- When you create an agent using the `vizra:make:agent` command, it automatically creates a prompt blade file for you in `/resources/prompts/YourAgent`. This gives you instant access to dynamic prompts without any additional setup! **Quick Example** Copy // Use a variant MyAgent::run('Hello') ->withPromptVersion('brief') ->go(); // Use a specific version/variant MyAgent::run('Hello') ->withPromptVersion('v2/formal') ->go(); [​](https://docs.vizra.ai/concepts/dynamic-prompts#real-world-example-customer-support-agent) Real-World Example: Customer Support Agent ------------------------------------------------------------------------------------------------------------------------------------------- Let’s see how versions and variants work together in practice. Imagine evolving a customer support agent over time while maintaining different tones for different customers. Usage in Production Copy // A/B test new version with specific users $version = $user->isInTestGroup() ? 'v3' : 'v2'; $variant = $user->preferredTone ?? 'default'; $response = CustomerSupportAgent::run($query) ->withPromptVersion("$version/$variant") ->forUser($user) ->go(); // Or use smart routing based on context $promptVersion = match(true) { $isAngryCustomer => 'v3/empathetic', $isTechnicalIssue => 'v3/technical', $isVipCustomer => 'v3/formal', default => 'v3/default' }; $response = CustomerSupportAgent::run($query) ->withPromptVersion($promptVersion) ->go(); [​](https://docs.vizra.ai/concepts/dynamic-prompts#blade-templates-for-dynamic-prompts) Blade Templates for Dynamic Prompts ------------------------------------------------------------------------------------------------------------------------------ Use Laravel’s Blade templating engine to create dynamic prompts that adapt based on user data, context, and session state. ### [​](https://docs.vizra.ai/concepts/dynamic-prompts#how-it-works) How It Works Save your prompts with a `.blade.php` extension instead of `.md`: resources/prompts/customer\_support/default.blade.php Copy You are {{ $agent['name'] }}, a helpful assistant. @if(isset($user_name)) Hello {{ $user_name }}! How can I help you today? @else Hello! How can I assist you? @endif @if($tools->isNotEmpty()) Available capabilities: @foreach($tools as $tool) - {{ $tool['description'] }} @endforeach @endif ### [​](https://docs.vizra.ai/concepts/dynamic-prompts#available-variables) Available Variables Core Variables -------------- * `$agent` - Agent info (name, model, etc.) * `$context` - Full AgentContext object * `$user_input` - Current user input * `$session_id` - Session identifier User & Memory ------------- * `$user`, `$user_name` - User data * `$memory_context` - Previous interactions * `$tools` - Available tools collection * `$sub_agents` - Sub-agents collection ### [​](https://docs.vizra.ai/concepts/dynamic-prompts#custom-variables) Custom Variables Add your own variables to inject into the blade prompt with `getPromptData()`: Copy class SalesAgent extends BaseLlmAgent { protected function getPromptData(?AgentContext $context): array { return [\ 'company_name' => config('app.company_name'),\ 'promotions' => $this->getActivePromotions(),\ 'business_hours' => '9 AM - 5 PM EST',\ ]; } } ### [​](https://docs.vizra.ai/concepts/dynamic-prompts#when-to-use-what) When to Use What Use Markdown When: ------------------ * Prompts are mostly static * Simple version control needed * No dynamic content required Use Blade When: --------------- * Need user personalization * Conditional logic required * Dynamic content injection Blade templates work seamlessly with the existing versioning system - just use `withPromptVersion('name')` as usual! [​](https://docs.vizra.ai/concepts/dynamic-prompts#organizing-your-prompts) Organizing Your Prompts ------------------------------------------------------------------------------------------------------ Keep your prompts organized with these flexible structures: Simple Structure (Variants Only) -------------------------------- Copy resources/prompts/ ├── weather_reporter/ │ ├── default.md # Standard tone │ ├── detailed.md # Comprehensive │ ├── concise.md # Brief responses │ └── professional.md # Business tone └── customer_support/ ├── default.md ├── friendly.md └── technical.md Versioned Structure (Versions + Variants) ----------------------------------------- Copy resources/prompts/ ├── weather_reporter/ │ ├── v1/ │ │ ├── default.md │ │ └── concise.md │ └── v2/ │ ├── default.md │ ├── concise.md │ └── detailed.md # New in v2 └── customer_support/ ├── v1/ │ └── default.md └── v2/ ├── default.md ├── friendly.md # New variant └── technical.md # New variant Start simple with just variants. Add versioning when you need to track improvements over time! [​](https://docs.vizra.ai/concepts/dynamic-prompts#cli-command-mastery) CLI Command Mastery ---------------------------------------------------------------------------------------------- The `vizra:prompt` command is your Swiss Army knife for prompt management! ### [​](https://docs.vizra.ai/concepts/dynamic-prompts#creating-prompts) Creating Prompts Terminal Copy # Interactive mode - enter multi-line content php artisan vizra:prompt create weather_reporter friendly # Quick mode - inline content php artisan vizra:prompt create weather_reporter v2 --content="You are a helpful weather assistant." ### [​](https://docs.vizra.ai/concepts/dynamic-prompts#listing-prompts) Listing Prompts Terminal Copy # List all prompts php artisan vizra:prompt list # List for specific agent php artisan vizra:prompt list weather_reporter # Example output: # +------------------+----------+--------+--------+---------------------+ # | Agent | Version | Source | Active | Created | # +------------------+----------+--------+--------+---------------------+ # | weather_reporter | default | File | ✓ | 2024-01-15 10:30:00 | # | weather_reporter | detailed | File | | 2024-01-15 11:00:00 | # | weather_reporter | concise | File | | 2024-01-15 11:30:00 | # +------------------+----------+--------+--------+---------------------+ ### [​](https://docs.vizra.ai/concepts/dynamic-prompts#import-&-export) Import & Export Terminal Copy # Export a prompt to file php artisan vizra:prompt export weather_reporter detailed --file=weather_detailed.md # Import from file php artisan vizra:prompt import weather_reporter v3 --file=weather_detailed.md # View prompt content directly php artisan vizra:prompt export weather_reporter detailed [​](https://docs.vizra.ai/concepts/dynamic-prompts#runtime-magic) Runtime Magic ---------------------------------------------------------------------------------- Switch prompt versions on the fly - no redeploys needed! ### [​](https://docs.vizra.ai/concepts/dynamic-prompts#setting-default-version-in-agent-class) Setting Default Version in Agent Class You can define a default prompt version directly in your agent class: Agent with Default Prompt Version Copy class WeatherReporterAgent extends BaseLlmAgent { protected string $name = 'weather_reporter'; // Set default prompt version for this agent protected ?string $promptVersion = 'professional'; // This will be overridden by the professional.md file protected string $instructions = 'You are a weather reporter.'; } // Now all calls use 'professional' by default $response = WeatherReporterAgent::run('What\'s the weather?')->go(); // Override the default when needed $response = WeatherReporterAgent::run('Current temperature?') ->withPromptVersion('concise') ->go(); ### [​](https://docs.vizra.ai/concepts/dynamic-prompts#using-blade-templates-at-runtime) Using Blade Templates at Runtime Blade templates work seamlessly with the existing prompt versioning system: Using Blade Templates with Runtime API Copy // Blade templates work just like markdown versions $response = WeatherReporter::run('What\'s the weather?') ->withPromptVersion('detailed') // Can be detailed.blade.php ->go(); // Mix and match - the system automatically detects the file type // Version 'friendly' could be friendly.md or friendly.blade.php $response = CustomerSupport::run($query) ->withPromptVersion('friendly') ->go(); // Pass additional context for Blade templates $response = SalesAgent::run('Show me pricing') ->withContext([\ 'premium_user' => true,\ 'account_age_days' => 365,\ 'preferred_language' => 'es',\ ]) ->withPromptVersion('personalized') // Uses personalized.blade.php ->go(); // Works with async operations too $job = ReportGenerator::run($data) ->withPromptVersion('executive') // executive.blade.php with dynamic formatting ->async() ->go(); ### [​](https://docs.vizra.ai/concepts/dynamic-prompts#runtime-version-selection) Runtime Version Selection Using Prompt Versions in Code Copy // Using specific version $response = WeatherReporterAgent::run('What\'s the weather?') ->withPromptVersion('detailed') ->go(); // Using Agent Facade $response = Agent::build('weather_reporter') ->withPromptVersion('concise') ->run('Current temperature?') ->go(); // Version from variable (great for A/B testing!) $version = $user->prefers_detailed ? 'detailed' : 'concise'; $response = WeatherReporter::run($query) ->withPromptVersion($version) ->go(); ### [​](https://docs.vizra.ai/concepts/dynamic-prompts#advanced-patterns) Advanced Patterns Advanced Prompt Version Usage Copy // A/B Testing Pattern $versions = ['default', 'friendly', 'professional']; $results = []; foreach ($versions as $version) { $startTime = microtime(true); $response = CustomerSupportAgent::run($testQuery) ->withPromptVersion($version) ->go(); $results[$version] = [\ 'response' => $response,\ 'time' => microtime(true) - $startTime,\ 'length' => strlen($response)\ ]; } // Find the best performer $bestVersion = collect($results)->sortBy('time')->keys()->first(); [​](https://docs.vizra.ai/concepts/dynamic-prompts#evaluation-integration) Evaluation Integration ---------------------------------------------------------------------------------------------------- Test different prompt versions systematically with evaluations! ### [​](https://docs.vizra.ai/concepts/dynamic-prompts#csv-driven-testing) CSV-Driven Testing evaluation\_data.csv Copy location,expected_format,prompt_version "New York",detailed,detailed "London",concise,concise "Tokyo",professional,professional "Paris",friendly,friendly Evaluation Class with Prompt Versions Copy class PromptComparisonEval extends BaseEvaluation { public string $agentName = 'weather_reporter'; // CSV column that specifies prompt version public ?string $promptVersionColumn = 'prompt_version'; // Or set a default for all tests public array $agentConfig = [\ 'prompt_version' => 'detailed',\ 'temperature' => 0.7,\ ]; public function evaluateRow(array $csvRow, string $response): array { // Your evaluation logic here // The correct prompt version is automatically used! } } [​](https://docs.vizra.ai/concepts/dynamic-prompts#configuration-options) Configuration Options -------------------------------------------------------------------------------------------------- Customize prompt versioning behavior in `config/vizra-adk.php`: Prompt Configuration Copy 'prompts' => [\ // Enable database storage (optional)\ 'use_database' => env('VIZRA_ADK_PROMPTS_USE_DATABASE', false),\ \ // Custom storage path\ 'storage_path' => env('VIZRA_ADK_PROMPTS_PATH', resource_path('prompts')),\ \ // Track usage analytics\ 'track_usage' => env('VIZRA_ADK_PROMPTS_TRACK_USAGE', false),\ ], ### [​](https://docs.vizra.ai/concepts/dynamic-prompts#database-storage-advanced) Database Storage (Advanced) For production environments, enable database storage: Terminal Copy # Run migrations php artisan migrate # Update .env VIZRA_ADK_PROMPTS_USE_DATABASE=true # Activate a version php artisan vizra:prompt activate weather_reporter v2 [​](https://docs.vizra.ai/concepts/dynamic-prompts#best-practices) Best Practices ------------------------------------------------------------------------------------ Naming Conventions ------------------ * `default` - Always have one! * `friendly` - Descriptive names * `2024_01_15_improved` - Date versions * ~`v2`~ - Too vague! Testing Strategy ---------------- * Start with file-based prompts * Test with evaluations * A/B test in production * Move winners to database [​](https://docs.vizra.ai/concepts/dynamic-prompts#troubleshooting) Troubleshooting -------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/concepts/dynamic-prompts#prompt-not-loading) Prompt Not Loading? 1. Check file exists: `resources/prompts/{agent_name}/{version}.md` 2. Verify file permissions are readable 3. Clear cache: `php artisan cache:clear` 4. Check agent name matches directory name ### [​](https://docs.vizra.ai/concepts/dynamic-prompts#database-prompts-not-working) Database Prompts Not Working? 1. Ensure `use_database` is `true` in config 2. Run migrations: `php artisan migrate` 3. Check prompt exists: `php artisan vizra:prompt list` 4. Verify database connection is working * * * [​](https://docs.vizra.ai/concepts/dynamic-prompts#you%E2%80%99re-now-a-dynamic-prompts-pro) You’re Now a Dynamic Prompts Pro! --------------------------------------------------------------------------------------------------------------------------------- With dynamic prompts, your AI agents can evolve and improve without touching code. Test freely, roll back instantly, and find the perfect voice for every agent. The future of AI development is here! Was this page helpful? YesNo [Vector Memory & RAG](https://docs.vizra.ai/concepts/vector-rag) [Agent Queuing](https://docs.vizra.ai/advanced/agent-queuing) ⌘I --- # OpenAI Compatibility - Vizra ADK [Skip to main content](https://docs.vizra.ai/integrations/openai-compatibility#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Integrations OpenAI Compatibility [Documentation](https://docs.vizra.ai/) On this page * [Why OpenAI Compatibility?](https://docs.vizra.ai/integrations/openai-compatibility#why-openai-compatibility) * [API Endpoint](https://docs.vizra.ai/integrations/openai-compatibility#api-endpoint) * [Quick Start](https://docs.vizra.ai/integrations/openai-compatibility#quick-start) * [Using with Existing Libraries](https://docs.vizra.ai/integrations/openai-compatibility#using-with-existing-libraries) * [Configuration](https://docs.vizra.ai/integrations/openai-compatibility#configuration) * [Streaming Support](https://docs.vizra.ai/integrations/openai-compatibility#streaming-support) * [Supported Parameters](https://docs.vizra.ai/integrations/openai-compatibility#supported-parameters) * [Response Format](https://docs.vizra.ai/integrations/openai-compatibility#response-format) * [Standard Response](https://docs.vizra.ai/integrations/openai-compatibility#standard-response) * [Streaming Response](https://docs.vizra.ai/integrations/openai-compatibility#streaming-response) * [Error Handling](https://docs.vizra.ai/integrations/openai-compatibility#error-handling) * [Tips & Best Practices](https://docs.vizra.ai/integrations/openai-compatibility#tips-%26-best-practices) * [Next Steps](https://docs.vizra.ai/integrations/openai-compatibility#next-steps) [​](https://docs.vizra.ai/integrations/openai-compatibility#why-openai-compatibility) Why OpenAI Compatibility? ------------------------------------------------------------------------------------------------------------------ The OpenAI Chat Completions API has become the de facto standard for AI applications. By implementing this same interface, Vizra ADK instantly becomes compatible with **thousands of existing tools, libraries, and workflows** without any code changes. Existing Tools -------------- Use with LangChain, LlamaIndex, Vercel AI SDK, and countless other libraries Client Apps ----------- Works with ChatGPT clients, mobile apps, browser extensions, and desktop tools Zero Migration -------------- Just change the base URL - everything else works exactly the same [​](https://docs.vizra.ai/integrations/openai-compatibility#api-endpoint) API Endpoint ----------------------------------------------------------------------------------------- OpenAI Compatible Endpoint Copy POST /api/vizra-adk/chat/completions This endpoint accepts the exact same request format as OpenAI’s Chat Completions API. [​](https://docs.vizra.ai/integrations/openai-compatibility#quick-start) Quick Start --------------------------------------------------------------------------------------- Ready to try it? Here are examples in different languages: * cURL * Laravel Http * JavaScript * Python Terminal Copy curl -X POST http://your-app.com/api/vizra-adk/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "your-agent-name", "messages": [\ {"role": "user", "content": "Hello! Tell me about yourself."}\ ], "temperature": 0.7, "max_tokens": 500 }' Copy use Illuminate\Support\Facades\Http; $response = Http::post('http://your-app.com/api/vizra-adk/chat/completions', [\ 'model' => 'your-agent-name',\ 'messages' => [\ ['role' => 'user', 'content' => 'Hello! Tell me about yourself.']\ ],\ 'temperature' => 0.7,\ 'max_tokens' => 500\ ]); $result = $response->json(); echo $result['choices'][0]['message']['content']; Copy const response = await fetch('http://your-app.com/api/vizra-adk/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ model: 'your-agent-name', messages: [\ { role: 'user', content: 'Hello! Tell me about yourself.' }\ ], temperature: 0.7, max_tokens: 500 }) }); const data = await response.json(); console.log(data.choices[0].message.content); Copy import requests response = requests.post( 'http://your-app.com/api/vizra-adk/chat/completions', json={ 'model': 'your-agent-name', 'messages': [\ {'role': 'user', 'content': 'Hello! Tell me about yourself.'}\ ], 'temperature': 0.7, 'max_tokens': 500 } ) result = response.json() print(result['choices'][0]['message']['content']) [​](https://docs.vizra.ai/integrations/openai-compatibility#using-with-existing-libraries) Using with Existing Libraries --------------------------------------------------------------------------------------------------------------------------- * OpenAI SDK (Python) * LangChain Copy from openai import OpenAI # Just change the base_url to point to your Vizra ADK instance client = OpenAI( api_key="not-needed", # Vizra ADK doesn't require API keys base_url="http://your-app.com/api/vizra-adk" ) response = client.chat.completions.create( model="your-agent-name", messages=[\ {"role": "user", "content": "What can you help me with?"}\ ] ) print(response.choices[0].message.content) Copy from langchain_openai import ChatOpenAI # Use your Vizra agents with LangChain llm = ChatOpenAI( model="your-agent-name", openai_api_key="not-needed", openai_api_base="http://your-app.com/api/vizra-adk", temperature=0.7 ) response = llm.invoke("What's the weather like today?") print(response.content) [​](https://docs.vizra.ai/integrations/openai-compatibility#configuration) Configuration ------------------------------------------------------------------------------------------- Configure model-to-agent mapping to make your agents accessible via familiar OpenAI model names: config/vizra-adk.php Copy return [\ // ... other config\ \ /**\ * OpenAI API Compatibility Configuration\ * Maps OpenAI model names to your agent names\ */\ 'openai_model_mapping' => [\ // Default mappings for OpenAI models\ 'gpt-4' => env('VIZRA_ADK_OPENAI_GPT4_AGENT', 'chat_agent'),\ 'gpt-4-turbo' => env('VIZRA_ADK_OPENAI_GPT4_TURBO_AGENT', 'chat_agent'),\ 'gpt-3.5-turbo' => env('VIZRA_ADK_OPENAI_GPT35_AGENT', 'chat_agent'),\ 'gpt-4o' => env('VIZRA_ADK_OPENAI_GPT4O_AGENT', 'chat_agent'),\ 'gpt-4o-mini' => env('VIZRA_ADK_OPENAI_GPT4O_MINI_AGENT', 'chat_agent'),\ \ // Add your own custom mappings here\ // 'my-custom-model' => 'my_specialized_agent',\ // 'claude-3-opus' => 'advanced_reasoning_agent',\ // 'gpt-4-vision' => 'image_analysis_agent',\ ],\ \ /**\ * Default agent when no mapping is found\ * Used for unmapped OpenAI models (gpt-*)\ */\ 'default_chat_agent' => env('VIZRA_ADK_DEFAULT_CHAT_AGENT', 'chat_agent'),\ ]; **How Model Resolution Works:** 1. First checks for exact match in `openai_model_mapping` 2. If model starts with `gpt-`, uses `default_chat_agent` 3. Otherwise, treats the model name as the agent name directly This means you can use `model: "your_agent_name"` directly without any mapping. You can customize mappings via environment variables or by publishing the config file with `php artisan vendor:publish --tag=vizra-adk-config`. [​](https://docs.vizra.ai/integrations/openai-compatibility#streaming-support) Streaming Support --------------------------------------------------------------------------------------------------- Enable real-time streaming responses by setting `"stream": true` in your request: * JavaScript * Python Copy async function streamResponse() { const response = await fetch('/api/vizra-adk/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ model: 'my-agent', messages: [{ role: 'user', content: 'Tell me a long story' }], stream: true, temperature: 0.8 }) }); const reader = response.body.getReader(); const decoder = new TextDecoder(); while (true) { const { done, value } = await reader.read(); if (done) break; const chunk = decoder.decode(value); const lines = chunk.split('\n'); for (const line of lines) { if (line.startsWith('data: ')) { const data = line.slice(6); if (data === '[DONE]') return; try { const parsed = JSON.parse(data); const content = parsed.choices[0]?.delta?.content; if (content) { process.stdout.write(content); // Stream to console // Or update your UI in real-time } } catch (e) { // Handle parsing errors } } } } } streamResponse(); Copy import requests import json def stream_completion(): response = requests.post( 'http://your-app.com/api/vizra-adk/chat/completions', json={ 'model': 'my-agent', 'messages': [{'role': 'user', 'content': 'Write a poem'}], 'stream': True, 'temperature': 0.7 }, stream=True ) for line in response.iter_lines(): if line.startswith(b'data: '): data = line[6:].decode('utf-8') if data == '[DONE]': break try: chunk = json.loads(data) content = chunk['choices'][0]['delta'].get('content') if content: print(content, end='', flush=True) except json.JSONDecodeError: continue stream_completion() [​](https://docs.vizra.ai/integrations/openai-compatibility#supported-parameters) Supported Parameters --------------------------------------------------------------------------------------------------------- The OpenAI compatibility layer supports all major ChatGPT parameters: | Parameter | Description | | --- | --- | | `model` | Agent name or mapped model name | | `messages` | Array of conversation messages | | `stream` | Enable streaming responses | | `temperature` | Creativity level (0.0 - 2.0) | | `max_tokens` | Maximum response length | | `top_p` | Nucleus sampling parameter | | `user` | User identifier for sessions | [​](https://docs.vizra.ai/integrations/openai-compatibility#response-format) Response Format ----------------------------------------------------------------------------------------------- Responses match OpenAI’s format exactly, ensuring perfect compatibility: ### [​](https://docs.vizra.ai/integrations/openai-compatibility#standard-response) Standard Response Non-streaming Response Copy { "id": "chatcmpl-AbCdEfGhIjKlMnOpQrStUvWxYz", "object": "chat.completion", "created": 1677858242, "model": "your-agent-name", "system_fingerprint": null, "choices": [\ {\ "index": 0,\ "message": {\ "role": "assistant",\ "content": "Hello! I'm your Vizra agent, ready to help!"\ },\ "finish_reason": "stop"\ }\ ], "usage": { "prompt_tokens": 12, "completion_tokens": 15, "total_tokens": 27 } } ### [​](https://docs.vizra.ai/integrations/openai-compatibility#streaming-response) Streaming Response Server-Sent Events Format Copy data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1677858242,"model":"your-agent","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]} data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1677858242,"model":"your-agent","choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]} data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1677858242,"model":"your-agent","choices":[{"index":0,"delta":{"content":"!"},"finish_reason":null}]} data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1677858242,"model":"your-agent","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]} data: [DONE] [​](https://docs.vizra.ai/integrations/openai-compatibility#error-handling) Error Handling --------------------------------------------------------------------------------------------- Error responses also match OpenAI’s format for seamless compatibility: Error Response Format Copy { "error": { "message": "The model 'unknown-agent' does not exist or you do not have access to it.", "type": "not_found_error", "code": "model_not_found" } } | Status Code | Description | | --- | --- | | 400 - Bad Request | Invalid request format or missing required fields | | 404 - Not Found | Agent/model not found or not registered | | 500 - Server Error | Internal error during agent execution | [​](https://docs.vizra.ai/integrations/openai-compatibility#tips-&-best-practices) Tips & Best Practices ----------------------------------------------------------------------------------------------------------- Agent Naming Strategy --------------------- Map commonly used OpenAI model names to your best agents to make migration seamless. For example, map `gpt-4` to your most advanced agent. Performance Optimization ------------------------ Use the `user` parameter to maintain persistent sessions and memory across conversations for more personalized responses. Development Workflow -------------------- Test your OpenAI compatibility with existing tools during development. Most AI applications allow changing the base URL for easy integration testing. Direct Agent Access ------------------- You can use `model: "your_agent_name"` directly without any mapping configuration. [​](https://docs.vizra.ai/integrations/openai-compatibility#next-steps) Next Steps ------------------------------------------------------------------------------------- [Get Started\ -----------\ \ Create your first agent and try the OpenAI endpoint](https://docs.vizra.ai/getting-started/quick-start) [Learn About Agents\ ------------------\ \ Understand how to create powerful AI agents](https://docs.vizra.ai/concepts/agents) Was this page helpful? YesNo [LLM Providers](https://docs.vizra.ai/integrations/providers) [MCP Integration](https://docs.vizra.ai/integrations/mcp) ⌘I --- # Sessions & Memory - Vizra ADK [Skip to main content](https://docs.vizra.ai/concepts/sessions-memory#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Core Concepts Sessions & Memory [Documentation](https://docs.vizra.ai/) On this page * [Understanding Sessions](https://docs.vizra.ai/concepts/sessions-memory#understanding-sessions) * [Creating and Managing Sessions](https://docs.vizra.ai/concepts/sessions-memory#creating-and-managing-sessions) * [Using Sessions with Agents](https://docs.vizra.ai/concepts/sessions-memory#using-sessions-with-agents) * [Session Models](https://docs.vizra.ai/concepts/sessions-memory#session-models) * [AgentContext Magic](https://docs.vizra.ai/concepts/sessions-memory#agentcontext-magic) * [Memory System](https://docs.vizra.ai/concepts/sessions-memory#memory-system) * [Using Persistent Memory](https://docs.vizra.ai/concepts/sessions-memory#using-persistent-memory) * [Agent Memory API](https://docs.vizra.ai/concepts/sessions-memory#agent-memory-api) * [Memory Methods](https://docs.vizra.ai/concepts/sessions-memory#memory-methods) * [Memory Manager Service](https://docs.vizra.ai/concepts/sessions-memory#memory-manager-service) * [Using Memory Tool](https://docs.vizra.ai/concepts/sessions-memory#using-memory-tool) * [Memory Context in Instructions](https://docs.vizra.ai/concepts/sessions-memory#memory-context-in-instructions) * [Memory Model Structure](https://docs.vizra.ai/concepts/sessions-memory#memory-model-structure) * [Memory Properties](https://docs.vizra.ai/concepts/sessions-memory#memory-properties) * [Accessing Memory Data](https://docs.vizra.ai/concepts/sessions-memory#accessing-memory-data) * [Session and Memory Integration](https://docs.vizra.ai/concepts/sessions-memory#session-and-memory-integration) * [Automatic Memory Updates](https://docs.vizra.ai/concepts/sessions-memory#automatic-memory-updates) * [Memory Extraction](https://docs.vizra.ai/concepts/sessions-memory#memory-extraction) * [Memory Lifecycle](https://docs.vizra.ai/concepts/sessions-memory#memory-lifecycle) * [Session Summarization](https://docs.vizra.ai/concepts/sessions-memory#session-summarization) * [Memory Cleanup](https://docs.vizra.ai/concepts/sessions-memory#memory-cleanup) * [Implementation Examples](https://docs.vizra.ai/concepts/sessions-memory#implementation-examples) * [Customer Support Agent](https://docs.vizra.ai/concepts/sessions-memory#customer-support-agent) * [Educational Tutor Agent](https://docs.vizra.ai/concepts/sessions-memory#educational-tutor-agent) * [Memory-Aware Agent Base Class](https://docs.vizra.ai/concepts/sessions-memory#memory-aware-agent-base-class) * [Session State Management](https://docs.vizra.ai/concepts/sessions-memory#session-state-management) * [Memory Best Practices](https://docs.vizra.ai/concepts/sessions-memory#memory-best-practices) **Sessions** provide conversation context while **memory** enables long-term knowledge retention. Together, they create intelligent, personalized agent interactions that improve over time! [​](https://docs.vizra.ai/concepts/sessions-memory#understanding-sessions) Understanding Sessions ---------------------------------------------------------------------------------------------------- Think of sessions as your agent’s short-term memory during a conversation! Conversation History -------------------- Every message between your agent and user is tracked Context Preservation -------------------- State persists across multiple interactions State Storage ------------- Keep track of important conversation data Memory Links ------------ Connect to long-term agent memory [​](https://docs.vizra.ai/concepts/sessions-memory#creating-and-managing-sessions) Creating and Managing Sessions -------------------------------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/concepts/sessions-memory#using-sessions-with-agents) Using Sessions with Agents Let’s see how easy it is to maintain conversations across multiple interactions! app/Http/Controllers/ChatController.php Copy use App\Agents\CustomerSupportAgent; // Start a conversation with a session $response = CustomerSupportAgent::run('I need help with my order') ->forUser($user) ->withSession($sessionId) ->go(); // Continue in the same session - agent remembers! $response2 = CustomerSupportAgent::run('The order number is #12345') ->forUser($user) ->withSession($sessionId) ->go(); ### [​](https://docs.vizra.ai/concepts/sessions-memory#session-models) Session Models Sessions are first-class citizens in Vizra, stored safely in your database! Copy use Vizra\VizraADK\Models\AgentSession; use Vizra\VizraADK\Models\AgentMessage; // Sessions are stored in the database $session = AgentSession::where('session_id', $sessionId)->first(); // Access session messages $messages = $session->messages()->get(); // Access session state $stateData = $session->state_data; ### [​](https://docs.vizra.ai/concepts/sessions-memory#agentcontext-magic) AgentContext Magic The `AgentContext` is your Swiss Army knife for session management! app/Agents/MyAgent.php Copy // AgentContext provides session state management public function run(string $input, AgentContext $context): mixed { // Get session ID $sessionId = $context->getSessionId(); // Store state in session $context->setState('order_id', '#12345'); // Retrieve state $orderId = $context->getState('order_id'); // Get conversation history $history = $context->getConversationHistory(); } [​](https://docs.vizra.ai/concepts/sessions-memory#memory-system) Memory System ---------------------------------------------------------------------------------- Give your agents the gift of memory! Vizra provides persistent memory across sessions through the powerful `AgentMemory` model and `MemoryManager` service: Session State ------------- Short-term context stored in AgentContext during a conversation - like working memory! Agent Memory ------------ Long-term memory with learnings, facts, and session summaries - like permanent storage! [​](https://docs.vizra.ai/concepts/sessions-memory#using-persistent-memory) Using Persistent Memory ------------------------------------------------------------------------------------------------------ ### [​](https://docs.vizra.ai/concepts/sessions-memory#agent-memory-api) Agent Memory API Every agent now has a built-in memory system that’s super easy to use! app/Agents/SupportAgent.php Copy class SupportAgent extends BaseLlmAgent { protected string $name = 'support_agent'; public function afterLlmResponse(Response|Generator $response, AgentContext $context): mixed { // Extract insights from the conversation if (str_contains($response, 'prefer email')) { $this->memory()->addLearning('User prefers email communication'); } // Store facts if ($this->detectAccountType($response)) { $this->memory()->addFact('Customer has premium account', 0.9); } // Add preferences $this->memory()->addPreference('Email notifications', 'communication'); // Update summary periodically if ($this->shouldUpdateSummary()) { $this->memory()->updateSummary( 'Premium customer who prefers email, interested in API features' ); } return $response; } protected function buildSystemPrompt(): string { // Automatically include memory context in prompts! $memoryContext = $this->memory()->getContext(1000); return $this->instructions . "\n\nUser Context:\n" . $memoryContext; } } ### [​](https://docs.vizra.ai/concepts/sessions-memory#memory-methods) Memory Methods The agent memory API provides specialized methods for different types of information: Copy // Inside any agent method, access memory via $this->memory() // Learnings - Insights gained from interactions $this->memory()->addLearning('User works in healthcare', [\ 'confidence' => 'high',\ 'source' => 'direct_mention'\ ]); // Facts - Immutable truths about the user $this->memory()->addFact('Located in New York', 1.0); // confidence score // Preferences - User likes and dislikes $this->memory()->addPreference('Detailed explanations', 'communication_style'); // Summary - Overall user profile (replaces previous) $this->memory()->updateSummary('Tech-savvy healthcare professional in NYC'); // Recall - Search through memories $learnings = $this->memory()->getLearnings(); $facts = $this->memory()->getFacts(); $preferences = $this->memory()->getPreferences('communication_style'); $summary = $this->memory()->getSummary(); // Context - Get formatted memory for prompts $context = $this->memory()->getContext(1500); // max tokens ### [​](https://docs.vizra.ai/concepts/sessions-memory#memory-manager-service) Memory Manager Service For advanced use cases, you can still access the Memory Manager directly: app/Services/AgentService.php Copy use Vizra\VizraADK\Services\MemoryManager; // Get or create memory for an agent $memory = $memoryManager->getOrCreateMemory('support_agent', $userId); // Add a learning $memoryManager->addLearning( 'support_agent', 'User prefers email communication', $userId ); // Add a fact $memoryManager->addFact( 'support_agent', 'preferred_contact', 'email', $userId ); // Update memory summary $memoryManager->updateSummary( 'support_agent', 'Customer is a premium member who prefers email contact', $userId ); ### [​](https://docs.vizra.ai/concepts/sessions-memory#using-memory-tool) Using Memory Tool Agents can manage their own memory - how cool is that? app/Agents/SupportAgent.php Copy // Agents can use the MemoryTool to manage their own memory class SupportAgent extends BaseLlmAgent { protected array $tools = [\ MemoryTool::class,\ ]; protected string $instructions = '... Use the manage_memory tool to: - Add important learnings about the user - Store facts for future reference - Retrieve context from previous conversations '; } ### [​](https://docs.vizra.ai/concepts/sessions-memory#memory-context-in-instructions) Memory Context in Instructions Inject past memories into your agent’s instructions for truly personalized interactions! Copy // Get memory context to include in agent instructions $memoryContext = $memoryManager->getMemoryContext( 'support_agent', $userId, 1000 // max length ); // Memory context includes: // - Previous Knowledge (summary) // - Key Learnings (last 5) // - Important Facts (up to 10) [​](https://docs.vizra.ai/concepts/sessions-memory#memory-model-structure) Memory Model Structure ---------------------------------------------------------------------------------------------------- Let’s peek under the hood! The `AgentMemory` model is beautifully organized: ### [​](https://docs.vizra.ai/concepts/sessions-memory#memory-properties) Memory Properties database/agent\_memories table Copy // AgentMemory model structure { "agent_name": "support_agent", "user_id": 123, "memory_summary": "Previous conversation summaries", "memory_data": { // Facts stored as key-value pairs "preferred_contact": "email", "account_type": "premium" }, "key_learnings": [ // Array of learnings with timestamps\ {\ "learning": "User prefers detailed explanations",\ "learned_at": "2024-01-15T10:30:00Z"\ }\ ], "total_sessions": 42, "last_session_at": "2024-01-15T10:30:00Z" } ### [​](https://docs.vizra.ai/concepts/sessions-memory#accessing-memory-data) Accessing Memory Data Working with memory data is a breeze! Check out these handy methods: Copy use Vizra\VizraADK\Models\AgentMemory; // Find memory for agent and user $memory = AgentMemory::where('agent_name', 'support_agent') ->where('user_id', $userId) ->first(); // Get context summary for agent instructions $contextSummary = $memory->getContextSummary(1000); // Add a learning $memory->addLearning('User works in healthcare industry'); // Update memory data $memory->updateMemoryData([\ 'industry' => 'healthcare',\ 'timezone' => 'EST'\ ]); // Record a new session $memory->recordSession(); [​](https://docs.vizra.ai/concepts/sessions-memory#session-and-memory-integration) Session and Memory Integration -------------------------------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/concepts/sessions-memory#automatic-memory-updates) Automatic Memory Updates The magic happens automatically! Sessions and memory work together seamlessly: Copy // Sessions automatically link to memory $session = AgentSession::find($id); $memory = $session->getOrCreateMemory(); // Update memory from session $session->updateMemory([\ 'learnings' => [\ 'User is interested in API integration',\ 'Prefers Python code examples'\ ],\ 'facts' => [\ 'programming_language' => 'Python',\ 'api_experience' => 'intermediate'\ ]\ ]); ### [​](https://docs.vizra.ai/concepts/sessions-memory#memory-extraction) Memory Extraction Watch as Vizra intelligently extracts insights from conversations! Copy // MemoryManager automatically extracts insights from sessions $memoryManager->updateMemoryFromSession($session); // This automatically: // - Records the session in memory // - Extracts preferences ("I like/prefer...") // - Extracts personal info ("My name is...") // - Updates session count and timestamps [​](https://docs.vizra.ai/concepts/sessions-memory#memory-lifecycle) Memory Lifecycle ---------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/concepts/sessions-memory#session-summarization) Session Summarization Keep memories fresh and relevant with intelligent summarization! Copy // Summarize recent sessions into memory $memoryManager->summarizeMemory( $memory, 10 // Number of recent sessions to summarize ); // Get recent conversations $recentConversations = $memoryManager->getRecentConversations( 'support_agent', $userId, 5 // Limit ); ### [​](https://docs.vizra.ai/concepts/sessions-memory#memory-cleanup) Memory Cleanup Keep your database tidy with smart cleanup strategies! Copy // Clean up old memories $deletedCount = $memoryManager->cleanupOldMemories( 90, // Days old 1000 // Max sessions ); // Clean up old sessions while preserving memory $deletedSessions = $memoryManager->cleanupOldSessions( 'support_agent', 30 // Days old ); [​](https://docs.vizra.ai/concepts/sessions-memory#implementation-examples) Implementation Examples ------------------------------------------------------------------------------------------------------ ### [​](https://docs.vizra.ai/concepts/sessions-memory#customer-support-agent) Customer Support Agent A complete example of a memory-aware support agent that learns and adapts! app/Agents/CustomerSupportAgent.php Copy class CustomerSupportAgent extends BaseLlmAgent { protected string $name = 'customer_support'; protected string $instructions = 'You are a helpful customer support agent...'; public function afterLlmResponse(Response|Generator $response, AgentContext $context): mixed { $responseText = $response instanceof Response ? $response->text : ''; // Extract and store contact preferences if (preg_match('/prefer.*(email|phone|chat)/i', $responseText, $matches)) { $this->memory()->addPreference( "Prefers {$matches[1]} communication", 'contact' ); } // Detect product interests if (str_contains($responseText, 'API') || str_contains($responseText, 'integration')) { $this->memory()->addLearning('Interested in API/integration features'); } // Store important facts if (preg_match('/order\s*#?(\d+)/i', $responseText, $matches)) { $this->memory()->addFact("Recent order: #{$matches[1]}", 1.0); } return $response; } protected function buildSystemPrompt(): string { // Include all relevant memory context $memory = $this->memory(); $summary = $memory->getSummary(); $preferences = $memory->getPreferences('contact'); $recentFacts = $memory->getFacts()->take(5); $prompt = $this->instructions; if ($summary) { $prompt .= "\n\nCustomer Profile: " . $summary; } if ($preferences->isNotEmpty()) { $prompt .= "\n\nCommunication Preferences:"; foreach ($preferences as $pref) { $prompt .= "\n- " . $pref->content; } } if ($recentFacts->isNotEmpty()) { $prompt .= "\n\nRecent Information:"; foreach ($recentFacts as $fact) { $prompt .= "\n- " . $fact->content; } } return $prompt; } } ### [​](https://docs.vizra.ai/concepts/sessions-memory#educational-tutor-agent) Educational Tutor Agent An agent that tracks learning progress and adapts teaching style! app/Agents/TutorAgent.php Copy class TutorAgent extends BaseLlmAgent { protected string $name = 'tutor_agent'; public function afterLlmResponse(Response|Generator $response, AgentContext $context): mixed { // Track topics covered if ($topic = $this->extractTopic($response)) { $this->memory()->addLearning("Studied topic: {$topic}", [\ 'timestamp' => now()->toIso8601String(),\ 'session_id' => $context->getSessionId()\ ]); } // Detect learning style preferences $this->detectLearningStyle($response, $context); // Update progress summary $learnings = $this->memory()->getLearnings(); if ($learnings->count() % 5 === 0) { // Every 5 learnings $topics = $learnings->pluck('content')->take(10)->implode(', '); $this->memory()->updateSummary( "Student has covered: {$topics}. Shows strong interest in practical examples." ); } return $response; } private function detectLearningStyle($response, $context): void { $userInput = $context->getLastUserMessage(); if (str_contains($userInput, 'example') || str_contains($userInput, 'show me')) { $this->memory()->addPreference('Prefers examples', 'learning_style'); } if (str_contains($userInput, 'why') || str_contains($userInput, 'explain')) { $this->memory()->addPreference('Likes detailed explanations', 'learning_style'); } if (str_contains($userInput, 'quick') || str_contains($userInput, 'summary')) { $this->memory()->addPreference('Prefers concise answers', 'learning_style'); } } } ### [​](https://docs.vizra.ai/concepts/sessions-memory#memory-aware-agent-base-class) Memory-Aware Agent Base Class Create a reusable base class for all memory-aware agents: app/Agents/MemoryAwareAgent.php Copy abstract class MemoryAwareAgent extends BaseLlmAgent { protected bool $autoExtractPreferences = true; protected bool $includeMemoryInPrompt = true; protected function buildSystemPrompt(): string { $prompt = $this->instructions; if ($this->includeMemoryInPrompt) { $memoryContext = $this->memory()->getContext(800); if ($memoryContext) { $prompt .= "\n\nUser Context:\n" . $memoryContext; } } return $prompt; } public function afterLlmResponse(Response|Generator $response, AgentContext $context): mixed { if ($this->autoExtractPreferences) { $this->extractPreferences($response, $context); } // Let child classes add their own memory logic $this->updateMemory($response, $context); return $response; } /** * Override this in child classes to add custom memory updates */ protected function updateMemory(Response|Generator $response, AgentContext $context): void { // Child classes implement their specific memory logic } private function extractPreferences($response, $context): void { $text = $response instanceof Response ? $response->text : ''; $userInput = $context->getLastUserMessage(); // Common preference patterns $patterns = [\ '/I (?:prefer|like|want|need) (.+?)(?:\.|,|$)/i' => 'general',\ '/(?:call|email|text|message) me/i' => 'contact',\ '/I (?:work in|am in|from) (.+?)(?:\.|,|$)/i' => 'location',\ '/my (?:job|role|position) is (.+?)(?:\.|,|$)/i' => 'occupation'\ ]; foreach ($patterns as $pattern => $category) { if (preg_match($pattern, $userInput, $matches)) { $preference = isset($matches[1]) ? $matches[1] : $matches[0]; $this->memory()->addPreference(trim($preference), $category); } } } } ### [​](https://docs.vizra.ai/concepts/sessions-memory#session-state-management) Session State Management Store complex data structures in session state - it’s that flexible! Copy // Store complex state in sessions $context->setState('cart_items', [\ ['id' => 123, 'quantity' => 2],\ ['id' => 456, 'quantity' => 1]\ ]); // Load all state $allState = $context->getAllState(); // Merge new state $context->loadState([\ 'preferences' => $userPreferences,\ 'settings' => $userSettings\ ]); [​](https://docs.vizra.ai/concepts/sessions-memory#memory-best-practices) Memory Best Practices -------------------------------------------------------------------------------------------------- Short-term Memory ----------------- Use AgentContext for session state Long-term Memory ---------------- Store important facts in AgentMemory Auto-summarization ------------------ Let MemoryManager handle summaries Agent Control ------------- Use MemoryTool for self-management Cleanup Strategy ---------------- Implement cleanup for old sessions Context Injection ----------------- Include memory in instructions [Next: Workflows\ ---------------\ \ Learn about agent workflows and multi-step processes](https://docs.vizra.ai/concepts/workflows) [Next: Dynamic Prompts\ ---------------------\ \ Learn about dynamic prompt versioning and variants](https://docs.vizra.ai/concepts/dynamic-prompts) Was this page helpful? YesNo [Tools](https://docs.vizra.ai/concepts/tools) [Specialized Agents](https://docs.vizra.ai/agents/overview) ⌘I --- # Tool Class Reference - Vizra ADK [Skip to main content](https://docs.vizra.ai/api-reference/tool-class#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation API Reference Tool Class Reference [Documentation](https://docs.vizra.ai/) On this page * [The Simple Yet Powerful Interface](https://docs.vizra.ai/api-reference/tool-class#the-simple-yet-powerful-interface) * [The Two Magical Methods](https://docs.vizra.ai/api-reference/tool-class#the-two-magical-methods) * [definition() - Teaching AI How to Use Your Tool](https://docs.vizra.ai/api-reference/tool-class#definition-teaching-ai-how-to-use-your-tool) * [execute()](https://docs.vizra.ai/api-reference/tool-class#execute) * [Parameter Schema Examples](https://docs.vizra.ai/api-reference/tool-class#parameter-schema-examples) * [Basic Parameter Types](https://docs.vizra.ai/api-reference/tool-class#basic-parameter-types) * [Complex Parameter Types](https://docs.vizra.ai/api-reference/tool-class#complex-parameter-types) * [Return Value Format](https://docs.vizra.ai/api-reference/tool-class#return-value-format) * [Working with AgentContext](https://docs.vizra.ai/api-reference/tool-class#working-with-agentcontext) * [Advanced Features](https://docs.vizra.ai/api-reference/tool-class#advanced-features) * [Tool with User Context](https://docs.vizra.ai/api-reference/tool-class#tool-with-user-context) * [Tool with Session Context](https://docs.vizra.ai/api-reference/tool-class#tool-with-session-context) * [Tool with File Handling](https://docs.vizra.ai/api-reference/tool-class#tool-with-file-handling) * [Complete Example](https://docs.vizra.ai/api-reference/tool-class#complete-example) * [Next Steps](https://docs.vizra.ai/api-reference/tool-class#next-steps) Think of the `ToolInterface` as your agent’s superhero training academy. Every tool you build expands what your agents can do - from simple calculations to complex integrations. [​](https://docs.vizra.ai/api-reference/tool-class#the-simple-yet-powerful-interface) The Simple Yet Powerful Interface -------------------------------------------------------------------------------------------------------------------------- The beauty of Vizra tools lies in their simplicity. Just two methods to implement, and your agent gains a whole new superpower. Here’s the elegant contract: The ToolInterface Contract Copy namespace Vizra\VizraADK\Contracts; use Vizra\VizraADK\System\AgentContext; use Vizra\VizraADK\Memory\AgentMemory; interface ToolInterface { public function definition(): array; public function execute(array $arguments, AgentContext $context, AgentMemory $memory): string; } [​](https://docs.vizra.ai/api-reference/tool-class#the-two-magical-methods) The Two Magical Methods ------------------------------------------------------------------------------------------------------ Just two methods stand between you and tool mastery. Each serves a crucial purpose in making your agent interactions seamless and powerful. definition() ------------ **The blueprint method.** Tell the AI exactly how to use your tool with a JSON Schema definition. It’s like writing a user manual that AI can understand perfectly. Copy public function definition(): array execute() --------- **The action hero.** This is where the magic happens - take the AI’s parameters and make something amazing occur. Database queries, API calls, calculations - you name it. Copy public function execute(array $arguments, AgentContext $context, AgentMemory $memory): string ### [​](https://docs.vizra.ai/api-reference/tool-class#definition-teaching-ai-how-to-use-your-tool) definition() - Teaching AI How to Use Your Tool This method returns a JSON Schema that’s like a detailed instruction manual for AI. Here’s how to write one that makes your tool shine: Perfect Tool Definition Copy public function definition(): array { return [\ 'name' => 'order_lookup',\ 'description' => 'Look up order information by ID',\ 'parameters' => [\ 'type' => 'object',\ 'properties' => [\ 'order_id' => [\ 'type' => 'string',\ 'description' => 'The order ID to look up',\ ],\ 'include_items' => [\ 'type' => 'boolean',\ 'description' => 'Include order items in response',\ ],\ ],\ 'required' => ['order_id'],\ ],\ ]; } ### [​](https://docs.vizra.ai/api-reference/tool-class#execute) execute() Copy public function execute(array $arguments, AgentContext $context, AgentMemory $memory): string Execute the tool with provided arguments, context, and agent memory. Must return a JSON-encoded string. Copy public function execute(array $arguments, AgentContext $context): string { $order = Order::find($arguments['order_id']); if (!$order) { return json_encode([\ 'status' => 'error',\ 'message' => 'Order not found',\ ]); } return json_encode([\ 'status' => 'success',\ 'order' => $order->toArray(),\ ]); } [​](https://docs.vizra.ai/api-reference/tool-class#parameter-schema-examples) Parameter Schema Examples ---------------------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/api-reference/tool-class#basic-parameter-types) Basic Parameter Types Copy 'parameters' => [\ 'type' => 'object',\ 'properties' => [\ 'name' => [\ 'type' => 'string',\ 'description' => 'User name',\ ],\ 'age' => [\ 'type' => 'integer',\ 'description' => 'User age',\ 'minimum' => 0,\ 'maximum' => 150,\ ],\ 'active' => [\ 'type' => 'boolean',\ 'description' => 'Whether user is active',\ ],\ 'price' => [\ 'type' => 'number',\ 'description' => 'Product price',\ 'minimum' => 0,\ ],\ ],\ 'required' => ['name'],\ ] ### [​](https://docs.vizra.ai/api-reference/tool-class#complex-parameter-types) Complex Parameter Types Copy 'parameters' => [\ 'type' => 'object',\ 'properties' => [\ 'status' => [\ 'type' => 'string',\ 'enum' => ['pending', 'processing', 'completed'],\ 'description' => 'Order status',\ ],\ 'tags' => [\ 'type' => 'array',\ 'description' => 'List of tags',\ 'items' => [\ 'type' => 'string',\ ],\ ],\ 'address' => [\ 'type' => 'object',\ 'description' => 'User address',\ 'properties' => [\ 'street' => ['type' => 'string'],\ 'city' => ['type' => 'string'],\ 'zip' => ['type' => 'string'],\ ],\ ],\ ],\ 'required' => [],\ ] [​](https://docs.vizra.ai/api-reference/tool-class#return-value-format) Return Value Format ---------------------------------------------------------------------------------------------- Tools must return a JSON-encoded string. Common patterns include: Copy // Success response return json_encode([\ 'status' => 'success',\ 'data' => $resultData,\ 'message' => 'Operation completed successfully',\ ]); // Error response return json_encode([\ 'status' => 'error',\ 'message' => 'Detailed error message',\ 'error_code' => 'SPECIFIC_ERROR',\ ]); [​](https://docs.vizra.ai/api-reference/tool-class#working-with-agentcontext) Working with AgentContext ---------------------------------------------------------------------------------------------------------- The `AgentContext` parameter provides access to session state and conversation history: Copy public function execute(array $arguments, AgentContext $context): string { // Get session ID $sessionId = $context->getSessionId(); // Access state $previousValue = $context->getState('last_order_id'); // Store state for future use $context->setState('last_order_id', $orderId); // Access user information if available $userId = $context->getState('user_id'); return json_encode(['status' => 'success']); } [​](https://docs.vizra.ai/api-reference/tool-class#advanced-features) Advanced Features ------------------------------------------------------------------------------------------ ### [​](https://docs.vizra.ai/api-reference/tool-class#tool-with-user-context) Tool with User Context Copy class UserOrdersTool implements ToolInterface { public function execute(array $arguments, AgentContext $context): string { // Get user ID from context $userId = $context->getState('user_id'); if (!$userId) { return json_encode([\ 'status' => 'error',\ 'message' => 'User authentication required',\ ]); } $user = User::find($userId); $orders = $user->orders() ->latest() ->limit($arguments['limit'] ?? 10) ->get(); return json_encode([\ 'status' => 'success',\ 'orders' => $orders->toArray(),\ ]); } } ### [​](https://docs.vizra.ai/api-reference/tool-class#tool-with-session-context) Tool with Session Context Copy public function execute(array $arguments, AgentContext $context): string { // Access session context $previousOrder = $context->getState('last_order_discussed'); // Store data in session $context->setState('current_order', $order->id); return json_encode([\ 'status' => 'success',\ 'order' => $order->toArray(),\ ]); } ### [​](https://docs.vizra.ai/api-reference/tool-class#tool-with-file-handling) Tool with File Handling Copy class FileProcessorTool implements ToolInterface { public function definition(): array { return [\ 'name' => 'file_processor',\ 'description' => 'Process uploaded files',\ 'parameters' => [\ 'type' => 'object',\ 'properties' => [\ 'file_content' => [\ 'type' => 'string',\ 'description' => 'Base64 encoded content',\ ],\ 'filename' => [\ 'type' => 'string',\ ],\ ],\ 'required' => ['file_content', 'filename'],\ ],\ ]; } public function execute(array $arguments, AgentContext $context): string { $content = base64_decode($arguments['file_content']); $path = Storage::put('uploads/' . $arguments['filename'], $content); return json_encode([\ 'status' => 'success',\ 'path' => $path,\ 'size' => strlen($content),\ ]); } } [​](https://docs.vizra.ai/api-reference/tool-class#complete-example) Complete Example ---------------------------------------------------------------------------------------- RefundProcessorTool.php Copy 'process_refund',\ 'description' => 'Process a refund for an order',\ 'parameters' => [\ 'type' => 'object',\ 'properties' => [\ 'order_id' => [\ 'type' => 'string',\ 'description' => 'The order ID to refund',\ ],\ 'amount' => [\ 'type' => 'number',\ 'description' => 'Refund amount (optional for partial refunds)',\ 'minimum' => 0,\ ],\ 'reason' => [\ 'type' => 'string',\ 'description' => 'Reason for refund',\ ],\ ],\ 'required' => ['order_id', 'reason'],\ ],\ ]; } public function execute(array $arguments, AgentContext $context): string { // Validate inputs $validator = Validator::make($arguments, [\ 'order_id' => 'required|string',\ 'amount' => 'nullable|numeric|min:0',\ 'reason' => 'required|string',\ ]); if ($validator->fails()) { return json_encode([\ 'status' => 'error',\ 'message' => 'Validation failed: ' . $validator->errors()->first(),\ ]); } // Check user authorization $userId = $context->getState('user_id'); if (!$userId) { return json_encode([\ 'status' => 'error',\ 'message' => 'User authentication required',\ ]); } try { $order = Order::findOrFail($arguments['order_id']); // Verify order belongs to user if ($order->user_id !== $userId) { return json_encode([\ 'status' => 'error',\ 'message' => 'Order not found',\ ]); } $refund = $this->refunds->process( $order, $arguments['amount'] ?? $order->total, $arguments['reason'] ); return json_encode([\ 'status' => 'success',\ 'refund_id' => $refund->id,\ 'amount' => $refund->amount,\ 'refund_status' => $refund->status,\ 'message' => 'Refund processed successfully',\ ]); } catch (\Exception $e) { return json_encode([\ 'status' => 'error',\ 'message' => 'Failed to process refund: ' . $e->getMessage(),\ ]); } } } **Tool Best Practices:** * Keep tools focused on a single action * Implement the ToolInterface, not extend a base class * Use descriptive names and descriptions * Return JSON-encoded strings from execute() * Use AgentContext for session state management * Validate parameters thoroughly * Handle errors gracefully * Return clear success/error messages [​](https://docs.vizra.ai/api-reference/tool-class#next-steps) Next Steps ---------------------------------------------------------------------------- [Workflow Class\ --------------\ \ Workflow class reference](https://docs.vizra.ai/api-reference/workflow-class) [Tool Concepts\ -------------\ \ Learn more about tools](https://docs.vizra.ai/concepts/tools) Was this page helpful? YesNo [Agent Class Reference](https://docs.vizra.ai/api-reference/agent-class) [Workflow Class Reference](https://docs.vizra.ai/api-reference/workflow-class) ⌘I --- # Workflows - Vizra ADK [Skip to main content](https://docs.vizra.ai/concepts/workflows#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Advanced Features Workflows [Documentation](https://docs.vizra.ai/) On this page * [Understanding Workflows](https://docs.vizra.ai/concepts/workflows#understanding-workflows) * [Workflow Patterns](https://docs.vizra.ai/concepts/workflows#workflow-patterns) * [Creating Your First Workflow](https://docs.vizra.ai/concepts/workflows#creating-your-first-workflow) * [Using the Workflow Facade](https://docs.vizra.ai/concepts/workflows#using-the-workflow-facade) * [Sequential Workflow Class](https://docs.vizra.ai/concepts/workflows#sequential-workflow-class) * [Workflow Types in Action](https://docs.vizra.ai/concepts/workflows#workflow-types-in-action) * [Parallel Workflows](https://docs.vizra.ai/concepts/workflows#parallel-workflows) * [Conditional Workflows](https://docs.vizra.ai/concepts/workflows#conditional-workflows) * [Loop Workflows](https://docs.vizra.ai/concepts/workflows#loop-workflows) * [Running Your Workflows](https://docs.vizra.ai/concepts/workflows#running-your-workflows) * [Basic Execution](https://docs.vizra.ai/concepts/workflows#basic-execution) * [Understanding Workflow Results](https://docs.vizra.ai/concepts/workflows#understanding-workflow-results) * [Advanced Workflow Features](https://docs.vizra.ai/concepts/workflows#advanced-workflow-features) * [Error Handling and Retries](https://docs.vizra.ai/concepts/workflows#error-handling-and-retries) * [Callbacks for Workflow Events](https://docs.vizra.ai/concepts/workflows#callbacks-for-workflow-events) * [Dynamic Parameters](https://docs.vizra.ai/concepts/workflows#dynamic-parameters) * [Workflow State Management](https://docs.vizra.ai/concepts/workflows#workflow-state-management) * [Creating Workflows from Arrays](https://docs.vizra.ai/concepts/workflows#creating-workflows-from-arrays) * [Array Definition](https://docs.vizra.ai/concepts/workflows#array-definition) * [Complex Array Definitions](https://docs.vizra.ai/concepts/workflows#complex-array-definitions) * [Workflow Best Practices](https://docs.vizra.ai/concepts/workflows#workflow-best-practices) **Agent Orchestration Made Simple** - Workflows are special agents that conduct other agents like a symphony! They orchestrate multiple agents in sequential, parallel, conditional, or loop patterns - all without requiring LLM control for the workflow logic itself. Think of them as your agent choreographer! [​](https://docs.vizra.ai/concepts/workflows#understanding-workflows) Understanding Workflows ------------------------------------------------------------------------------------------------ Workflows are the conductors of your agent orchestra! They’re special agent types that bring order to complexity: Built on Solid Foundation ------------------------- Extend `BaseWorkflowAgent` which extends `BaseAgent` No LLM Overhead --------------- Orchestrate agents without using LLMs for flow control Multiple Patterns ----------------- Support sequential, parallel, conditional, and loop execution Smart Data Flow --------------- Pass results between steps automatically [​](https://docs.vizra.ai/concepts/workflows#workflow-patterns) Workflow Patterns ------------------------------------------------------------------------------------ Sequential ---------- Steps execute one after another in perfect order Parallel -------- Multiple agents work simultaneously Conditional ----------- Choose paths based on conditions Loops ----- Repeat operations with while, times, or forEach [​](https://docs.vizra.ai/concepts/workflows#creating-your-first-workflow) Creating Your First Workflow ---------------------------------------------------------------------------------------------------------- Let’s build your first workflow! It’s as easy as chaining methods together. ### [​](https://docs.vizra.ai/concepts/workflows#using-the-workflow-facade) Using the Workflow Facade app/Workflows/DataProcessingWorkflow.php Copy use Vizra\VizraADK\Facades\Workflow; use App\Agents\DataCollectorAgent; use App\Agents\DataProcessorAgent; use App\Agents\ReportGeneratorAgent; $workflow = Workflow::sequential() ->then(DataCollectorAgent::class) ->then(DataProcessorAgent::class) ->then(ReportGeneratorAgent::class); ### [​](https://docs.vizra.ai/concepts/workflows#sequential-workflow-class) Sequential Workflow Class Copy use Vizra\VizraADK\Agents\SequentialWorkflow; use App\Agents\AnalysisAgent; use App\Agents\SummaryAgent; use App\Agents\CleanupAgent; $workflow = new SequentialWorkflow(); $workflow ->start(AnalysisAgent::class, 'Analyze the data') ->then(SummaryAgent::class, fn($previousResult) => "Summarize this: " . $previousResult ) ->finally(CleanupAgent::class); // Always runs $result = $workflow->execute('Initial input'); [​](https://docs.vizra.ai/concepts/workflows#workflow-types-in-action) Workflow Types in Action -------------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/concepts/workflows#parallel-workflows) Parallel Workflows Need to notify multiple channels at once? Run data processing in parallel? This is your power tool! Copy // Using the facade use App\Agents\EmailAgent; use App\Agents\SmsAgent; use App\Agents\SlackAgent; $workflow = Workflow::parallel([\ EmailAgent::class,\ SmsAgent::class,\ SlackAgent::class\ ])->waitForAll(); ### [​](https://docs.vizra.ai/concepts/workflows#conditional-workflows) Conditional Workflows Make smart decisions in your workflow! Route to different agents based on conditions. Copy use Vizra\VizraADK\Agents\ConditionalWorkflow; use App\Agents\PremiumAgent; use App\Agents\UrgentHandler; use App\Agents\StandardAgent; $workflow = Workflow::conditional() ->when( 'score > 80', PremiumAgent::class, 'Handle premium customer' ) ->when( fn($input) => $input['type'] === 'urgent', UrgentHandler::class ) ->otherwise( StandardAgent::class, 'Handle standard request' ); ### [​](https://docs.vizra.ai/concepts/workflows#loop-workflows) Loop Workflows Process lists, retry until success, or repeat operations - loops make it easy! Copy use App\Agents\ProcessingAgent; use App\Agents\BatchProcessor; use App\Agents\ItemProcessor; // While loop $workflow = Workflow::while( ProcessingAgent::class, fn($result) => $result['continue'] === true, 10 // max iterations ); // Times loop $workflow = Workflow::times(BatchProcessor::class, 5); // ForEach loop $items = ['item1', 'item2', 'item3']; $workflow = Workflow::forEach(ItemProcessor::class, $items); [​](https://docs.vizra.ai/concepts/workflows#running-your-workflows) Running Your Workflows ---------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/concepts/workflows#basic-execution) Basic Execution Copy use Vizra\VizraADK\Facades\Workflow; use Vizra\VizraADK\System\AgentContext; use App\Agents\FirstAgent; use App\Agents\SecondAgent; // Workflows are agents, so they run like any agent $workflow = Workflow::sequential(FirstAgent::class, SecondAgent::class); // Create an agent context (required) $context = new AgentContext('session-123'); // Execute with input and context $result = $workflow->execute('Process this data', $context); ### [​](https://docs.vizra.ai/concepts/workflows#understanding-workflow-results) Understanding Workflow Results Each workflow type returns structured results so you always know what happened! Copy // Sequential workflow returns { 'final_result': 'Last agent output', 'step_results': { 'App\\Agents\\FirstAgent': 'First result', 'App\\Agents\\SecondAgent': 'Second result' }, 'workflow_type': 'sequential' } // Parallel workflow returns { 'results': { 'App\\Agents\\AgentOne': 'Result 1', 'App\\Agents\\AgentTwo': 'Result 2' }, 'completed': ['App\\Agents\\AgentOne', 'App\\Agents\\AgentTwo'], 'workflow_type': 'parallel' } [​](https://docs.vizra.ai/concepts/workflows#advanced-workflow-features) Advanced Workflow Features ------------------------------------------------------------------------------------------------------ Take your workflows to the next level with advanced error handling, callbacks, and dynamic parameters! ### [​](https://docs.vizra.ai/concepts/workflows#error-handling-and-retries) Error Handling and Retries Copy use App\Agents\RiskyAgent; $workflow = new SequentialWorkflow(); $workflow ->retryOnFailure(3, 1000) // 3 retries, 1 second delay ->timeout(300) // 5 minute timeout ->then(RiskyAgent::class, 'Process risky operation', [\ 'retries' => 5, // Override for this step\ 'timeout' => 60\ ]); ### [​](https://docs.vizra.ai/concepts/workflows#callbacks-for-workflow-events) Callbacks for Workflow Events Copy use App\Agents\FirstAgent; use App\Agents\SecondAgent; $workflow = Workflow::sequential(FirstAgent::class, SecondAgent::class) ->onSuccess(function($result, $stepResults) { Log::info('Workflow succeeded', [\ 'final' => $result,\ 'steps' => $stepResults\ ]); }) ->onFailure(function(\Throwable $e, $stepResults) { Log::error('Workflow failed: ' . $e->getMessage()); }) ->onComplete(function($result, $success, $stepResults) { // Always runs, regardless of success/failure }); ### [​](https://docs.vizra.ai/concepts/workflows#dynamic-parameters) Dynamic Parameters Pass data between steps dynamically based on results and context! Copy use App\Agents\DataFetcher; use App\Agents\Processor; $workflow = new SequentialWorkflow(); $workflow ->then(DataFetcher::class) ->then( Processor::class, // Dynamic params based on previous results fn($input, $results, $context) => [\ 'data' => $results[DataFetcher::class],\ 'mode' => $context->getState('processing_mode')\ ] ); [​](https://docs.vizra.ai/concepts/workflows#workflow-state-management) Workflow State Management ---------------------------------------------------------------------------------------------------- Access results from any step and manage state throughout your workflow! Copy use App\Agents\Collector; use App\Agents\Analyzer; // Access results from previous steps $workflow = new SequentialWorkflow(); $workflow ->then(Collector::class, 'Collect data') ->then(Analyzer::class, function($input, $results) { // Access previous step result $collectedData = $results[Collector::class]; return "Analyze: " . json_encode($collectedData); }); // After execution, get specific results $result = $workflow->execute('Start'); $analyzerResult = $workflow->getStepResult(Analyzer::class); $allResults = $workflow->getResults(); [​](https://docs.vizra.ai/concepts/workflows#creating-workflows-from-arrays) Creating Workflows from Arrays -------------------------------------------------------------------------------------------------------------- Define workflows using simple arrays - perfect for dynamic or configuration-based workflows! ### [​](https://docs.vizra.ai/concepts/workflows#array-definition) Array Definition Copy use App\Agents\DataCollector; use App\Agents\Validator; $definition = [\ 'type' => 'sequential',\ 'steps' => [\ [\ 'agent' => DataCollector::class,\ 'params' => 'Collect user data'\ ],\ [\ 'agent' => Validator::class,\ 'options' => ['retries' => 3]\ ]\ ]\ ]; $workflow = Workflow::fromArray($definition); ### [​](https://docs.vizra.ai/concepts/workflows#complex-array-definitions) Complex Array Definitions Copy use App\Agents\UrgentHandler; use App\Agents\SupportAgent; use App\Agents\StandardHandler; // Conditional workflow from array $definition = [\ 'type' => 'conditional',\ 'conditions' => [\ [\ 'condition' => 'input.priority == "high"',\ 'agent' => UrgentHandler::class\ ],\ [\ 'condition' => 'input.type == "support"',\ 'agent' => SupportAgent::class\ ]\ ],\ 'default' => [\ 'agent' => StandardHandler::class\ ]\ ]; [​](https://docs.vizra.ai/concepts/workflows#workflow-best-practices) Workflow Best Practices ------------------------------------------------------------------------------------------------ Design Tips ----------- * **Remember the Foundation** - Workflows are agents - they extend BaseWorkflowAgent * **Choose the Right Pattern** - Use the appropriate workflow type for your use case * **Set Smart Limits** - Configure reasonable timeouts and retry limits Development Tips ---------------- * **Monitor Everything** - Leverage callbacks for monitoring and debugging * **Smart Data Flow** - Pass results between steps using closures * **Test Thoroughly** - Test workflows with various input scenarios [Next: Vector & RAG\ ------------------\ \ Learn about vector memory and retrieval augmented generation!](https://docs.vizra.ai/concepts/vector-rag) [Workflow API Reference\ ----------------------\ \ Deep dive into workflow class documentation](https://docs.vizra.ai/api/workflow-class) Was this page helpful? YesNo [Structured Output](https://docs.vizra.ai/tools/structured-output) [Vector Memory & RAG](https://docs.vizra.ai/concepts/vector-rag) ⌘I --- # Vector Memory & RAG - Vizra ADK [Skip to main content](https://docs.vizra.ai/concepts/vector-rag#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Advanced Features Vector Memory & RAG [Documentation](https://docs.vizra.ai/) On this page * [Understanding Vector Memory](https://docs.vizra.ai/concepts/vector-rag#understanding-vector-memory) * [Setting Up Vector Memory](https://docs.vizra.ai/concepts/vector-rag#setting-up-vector-memory) * [Quick Setup with Meilisearch](https://docs.vizra.ai/concepts/vector-rag#quick-setup-with-meilisearch) * [Database Setup](https://docs.vizra.ai/concepts/vector-rag#database-setup) * [Using Vector Memory in Agents](https://docs.vizra.ai/concepts/vector-rag#using-vector-memory-in-agents) * [Storing Documents in Your Agent](https://docs.vizra.ai/concepts/vector-rag#storing-documents-in-your-agent) * [Direct VectorMemoryManager Access](https://docs.vizra.ai/concepts/vector-rag#direct-vectormemorymanager-access) * [Progressive Disclosure API](https://docs.vizra.ai/concepts/vector-rag#progressive-disclosure-api) * [Document Chunking Configuration](https://docs.vizra.ai/concepts/vector-rag#document-chunking-configuration) * [Searching Vector Memory](https://docs.vizra.ai/concepts/vector-rag#searching-vector-memory) * [Semantic Search in Agents](https://docs.vizra.ai/concepts/vector-rag#semantic-search-in-agents) * [RAG Context Generation](https://docs.vizra.ai/concepts/vector-rag#rag-context-generation) * [Building RAG-Powered Agents](https://docs.vizra.ai/concepts/vector-rag#building-rag-powered-agents) * [Complete RAG Agent Example](https://docs.vizra.ai/concepts/vector-rag#complete-rag-agent-example) * [RAG Configuration](https://docs.vizra.ai/concepts/vector-rag#rag-configuration) * [Embedding Providers](https://docs.vizra.ai/concepts/vector-rag#embedding-providers) * [Vector Memory Management](https://docs.vizra.ai/concepts/vector-rag#vector-memory-management) * [Managing Memories](https://docs.vizra.ai/concepts/vector-rag#managing-memories) * [Creating Tools for Vector Operations](https://docs.vizra.ai/concepts/vector-rag#creating-tools-for-vector-operations) * [Using the VectorMemory Model](https://docs.vizra.ai/concepts/vector-rag#using-the-vectormemory-model) * [Vector Storage Drivers](https://docs.vizra.ai/concepts/vector-rag#vector-storage-drivers) * [Complete Configuration Reference](https://docs.vizra.ai/concepts/vector-rag#complete-configuration-reference) * [Console Commands](https://docs.vizra.ai/concepts/vector-rag#console-commands) * [Available Commands](https://docs.vizra.ai/concepts/vector-rag#available-commands) * [Vector Memory Best Practices](https://docs.vizra.ai/concepts/vector-rag#vector-memory-best-practices) [​](https://docs.vizra.ai/concepts/vector-rag#understanding-vector-memory) Understanding Vector Memory --------------------------------------------------------------------------------------------------------- Think of vector memory as your agent’s superpower! It transforms text into mathematical representations that capture meaning, enabling your agent to find semantically similar content even when the exact words don’t match. **Flexible & Powerful:** Choose from multiple storage providers (Meilisearch, PostgreSQL + pgvector) and embedding providers (OpenAI, Gemini, Cohere, Ollama) to fit your needs! Semantic Search --------------- Find content by meaning, not just keywords Efficient Retrieval ------------------- Lightning-fast similarity searches at scale Multiple Providers ------------------ Support for various storage and embedding providers Context Augmentation -------------------- Enhance responses with relevant knowledge [​](https://docs.vizra.ai/concepts/vector-rag#setting-up-vector-memory) Setting Up Vector Memory --------------------------------------------------------------------------------------------------- Let’s get your vector memory up and running with Meilisearch! It’s the perfect balance of speed, simplicity, and power. ### [​](https://docs.vizra.ai/concepts/vector-rag#quick-setup-with-meilisearch) Quick Setup with Meilisearch Configure vector memory with Meilisearch in your `.env` file: .env Copy # Vector Memory with Meilisearch (recommended for most use cases) VIZRA_ADK_VECTOR_DRIVER=meilisearch # Choose your embedding provider VIZRA_ADK_EMBEDDING_PROVIDER=gemini # or openai, cohere, ollama # Gemini for embeddings (recommended) GEMINI_API_KEY=your-gemini-api-key # Meilisearch configuration MEILISEARCH_HOST=http://localhost:7700 MEILISEARCH_KEY=your-master-key MEILISEARCH_PREFIX=agent_vectors_ # Alternative: OpenAI embeddings # VIZRA_ADK_EMBEDDING_PROVIDER=openai # OPENAI_API_KEY=your-openai-key **Alternative option:** You can also use PostgreSQL + pgvector for production-scale vector similarity search. See the complete configuration reference below for setup details. ### [​](https://docs.vizra.ai/concepts/vector-rag#database-setup) Database Setup Terminal Copy # Run migrations for vector memory tables php artisan migrate # For PostgreSQL, ensure pgvector extension is installed CREATE EXTENSION IF NOT EXISTS vector; [​](https://docs.vizra.ai/concepts/vector-rag#using-vector-memory-in-agents) Using Vector Memory in Agents ------------------------------------------------------------------------------------------------------------- Your agents now have built-in access to vector memory! Use the convenient `$this->vector()` or `$this->rag()` methods directly within your agent.**New!** These methods are now **public**, so you can also access them externally for testing: `$agent->vector()->addDocument(...)` ### [​](https://docs.vizra.ai/concepts/vector-rag#storing-documents-in-your-agent) Storing Documents in Your Agent Using Vector Memory in an Agent Copy class DocumentationAgent extends BaseLlmAgent { protected string $name = 'documentation_agent'; public function storeKnowledge(string $content, array $metadata = []): void { // Simple string content with optional metadata $this->vector()->addDocument($content, $metadata); // Or use array format for full control $this->vector()->addDocument([\ 'content' => $content,\ 'metadata' => $metadata,\ 'namespace' => 'docs',\ 'source' => 'user-upload'\ ]); } public function searchKnowledge(string $query): array { // Simple search with default settings return $this->rag()->search($query); // Or with custom limit return $this->rag()->search($query, 10); // Or full control with array return $this->rag()->search([\ 'query' => $query,\ 'limit' => 5,\ 'threshold' => 0.7,\ 'namespace' => 'docs'\ ]); } } Both `$this->vector()` and `$this->rag()` return a proxy that automatically injects your agent class. No need to pass agent names anymore!**Simplified API:** Use simple strings for basic operations, or arrays for full control with progressive disclosure! ### [​](https://docs.vizra.ai/concepts/vector-rag#direct-vectormemorymanager-access) Direct VectorMemoryManager Access For advanced use cases outside of agent contexts, you can still use the VectorMemoryManager directly: Direct VectorMemoryManager Usage Copy use Vizra\VizraADK\Services\VectorMemoryManager; use App\Agents\DocumentationAgent; $vectorManager = app(VectorMemoryManager::class); // Simple usage with agent class $memories = $vectorManager->addDocument( DocumentationAgent::class, 'Vizra ADK is a Laravel package for building AI agents...', ['category' => 'overview'] ); // Or with full options $memories = $vectorManager->addDocument( DocumentationAgent::class, [\ 'content' => 'Vizra ADK is a Laravel package...',\ 'metadata' => [\ 'category' => 'overview',\ 'version' => '1.0'\ ],\ 'namespace' => 'docs',\ 'source' => 'overview-page'\ ] ); ### [​](https://docs.vizra.ai/concepts/vector-rag#progressive-disclosure-api) Progressive Disclosure API **Smart API Design:** Start simple, add complexity only when needed! Progressive API Examples Copy class KnowledgeAgent extends BaseLlmAgent { public function demonstrateAPI(): void { // 1. SIMPLE: Just content (perfect for quick prototyping) $this->vector()->addChunk('Laravel is awesome!'); // 2. COMMON: Content + metadata (most typical usage) $this->vector()->addChunk( 'Eloquent is Laravel\'s ORM', ['category' => 'database', 'difficulty' => 'beginner'] ); // 3. ADVANCED: Full control with array (when you need everything) $this->vector()->addChunk([\ 'content' => 'Advanced Laravel patterns and practices',\ 'metadata' => ['category' => 'advanced', 'priority' => 'high'],\ 'namespace' => 'tutorials',\ 'source' => 'expert-guide',\ 'source_id' => 'guide-123',\ 'chunk_index' => 0\ ]); } public function searchExamples(): void { // Simple search $results = $this->rag()->search('Laravel ORM'); // With limit $results = $this->rag()->search('Laravel patterns', 10); // Full control $results = $this->rag()->search([\ 'query' => 'advanced Laravel',\ 'namespace' => 'tutorials',\ 'limit' => 5,\ 'threshold' => 0.8\ ]); } } ### [​](https://docs.vizra.ai/concepts/vector-rag#document-chunking-configuration) Document Chunking Configuration **Pro tip:** Adjust chunk sizes based on your content type. Smaller chunks for FAQs, larger for narrative content! config/vizra-adk.php Copy // Configure chunking in config/vizra-adk.php 'vector_memory' => [\ 'chunking' => [\ 'size' => 1000, // Characters per chunk\ 'overlap' => 100, // Overlap between chunks\ 'separators' => ["\n\n", "\n", ". ", ", ", " "],\ 'keep_separators' => true,\ ],\ ]; [​](https://docs.vizra.ai/concepts/vector-rag#searching-vector-memory) Searching Vector Memory ------------------------------------------------------------------------------------------------- Here’s where the magic happens! Watch your agent find exactly what it needs, even when users ask questions in completely different words. ### [​](https://docs.vizra.ai/concepts/vector-rag#semantic-search-in-agents) Semantic Search in Agents Semantic Search in Agent Copy class SmartAssistant extends BaseLlmAgent { protected string $name = 'smart_assistant'; public function findRelevantInfo(string $query): string { // Simple search - uses defaults $results = $this->rag()->search($query); // Or with custom limit $results = $this->rag()->search($query, 10); // Or full control $results = $this->rag()->search([\ 'query' => $query,\ 'limit' => 5,\ 'threshold' => 0.7,\ 'namespace' => 'knowledge'\ ]); // Format results for response $relevant = []; foreach ($results as $result) { $relevant[] = $result->content; } return implode("\n\n", $relevant); } } ### [​](https://docs.vizra.ai/concepts/vector-rag#rag-context-generation) RAG Context Generation RAG (Retrieval-Augmented Generation) combines the power of vector search with LLM generation for incredibly accurate responses! Generate RAG Context in Agent Copy class RAGEnabledAgent extends BaseLlmAgent { protected string $name = 'rag_agent'; public function run(mixed $input, AgentContext $context): mixed { // Simple: just pass the query (uses intelligent defaults) $ragContext = $this->rag()->generateRagContext($input); // Common: with a few key options $ragContext = $this->rag()->generateRagContext($input, [\ 'namespace' => 'knowledge',\ 'limit' => 5\ ]); // Advanced: full control over retrieval $ragContext = $this->rag()->generateRagContext($input, [\ 'namespace' => 'knowledge',\ 'limit' => 5,\ 'threshold' => 0.7,\ 'include_metadata' => true\ ]); // Only augment if we found relevant content if ($ragContext['total_results'] > 0) { $augmentedInput = "Based on the following context:\n" . $ragContext['context'] . "\n\nUser Question: " . $input; } else { $augmentedInput = $input; // No relevant context found } return parent::run($augmentedInput, $context); } } [​](https://docs.vizra.ai/concepts/vector-rag#building-rag-powered-agents) Building RAG-Powered Agents --------------------------------------------------------------------------------------------------------- Transform your agents into knowledge powerhouses! Here’s a complete example of a RAG-enabled documentation assistant. ### [​](https://docs.vizra.ai/concepts/vector-rag#complete-rag-agent-example) Complete RAG Agent Example Documentation Assistant with RAG Copy class DocumentationAssistant extends BaseLlmAgent { protected string $name = 'doc_assistant'; protected string $description = 'AI assistant with access to documentation'; protected string $instructions = 'You are a helpful documentation assistant. Use the provided context to answer questions accurately.'; /** * Load documentation into vector memory */ public function loadDocumentation(string $filePath): void { $content = file_get_contents($filePath); // Simple with metadata $this->vector()->addDocument($content, [\ 'source' => basename($filePath),\ 'type' => 'documentation'\ ]); // Or with full control $this->vector()->addDocument([\ 'content' => $content,\ 'metadata' => [\ 'source' => basename($filePath),\ 'type' => 'documentation'\ ],\ 'namespace' => 'docs',\ 'source' => 'documentation',\ 'source_id' => md5($filePath)\ ]); } /** * Process user questions with RAG */ public function run(mixed $input, AgentContext $context): mixed { // Search for relevant documentation with array options $ragContext = $this->rag()->generateRagContext($input, [\ 'namespace' => 'docs',\ 'limit' => 5,\ 'threshold' => 0.7\ ]); // Only augment if we found relevant content if ($ragContext['total_results'] > 0) { $augmentedInput = "Relevant Documentation:\n" . $ragContext['context'] . "\n\nUser Question: " . $input . "\n\nPlease answer based on the documentation provided."; } else { $augmentedInput = $input . "\n\n(No relevant documentation found)"; } return parent::run($augmentedInput, $context); } /** * Get statistics about loaded documentation */ public function getDocStats(): array { // Default namespace return $this->vector()->getStatistics(); // Or specific namespace return $this->vector()->getStatistics('docs'); // Or with array return $this->vector()->getStatistics(['namespace' => 'docs']); } } ### [​](https://docs.vizra.ai/concepts/vector-rag#rag-configuration) RAG Configuration config/vizra-adk.php Copy // Configure RAG in config/vizra-adk.php 'vector_memory' => [\ 'rag' => [\ 'context_template' => "Based on the following context:\n{context}\n\nAnswer this question: {query}",\ 'max_context_length' => 4000,\ 'include_metadata' => true,\ ],\ ], [​](https://docs.vizra.ai/concepts/vector-rag#embedding-providers) Embedding Providers ----------------------------------------------------------------------------------------- OpenAI (Default) ---------------- .env Copy OPENAI_API_KEY=your-api-key # In config/vizra-adk.php 'embedding_models' => [\ 'openai' => 'text-embedding-3-small'\ ] Supported Models ---------------- * text-embedding-3-small (1536 dims) * text-embedding-3-large (3072 dims) * text-embedding-ada-002 (1536 dims) Custom Provider --------------- Implement `EmbeddingProviderInterface` to add custom embedding providers [​](https://docs.vizra.ai/concepts/vector-rag#vector-memory-management) Vector Memory Management --------------------------------------------------------------------------------------------------- Keep your vector memory clean and efficient! Here’s how to manage, monitor, and optimize your knowledge base. ### [​](https://docs.vizra.ai/concepts/vector-rag#managing-memories) Managing Memories Memory Management in Agents Copy class ManagedKnowledgeAgent extends BaseLlmAgent { protected string $name = 'managed_agent'; /** * Clear all memories in a namespace */ public function clearNamespace(string $namespace = 'default'): int { // Simple: just the namespace name return $this->vector()->deleteMemories($namespace); // Advanced: with array for consistency return $this->vector()->deleteMemories(['namespace' => $namespace]); } /** * Remove memories from a specific source */ public function removeSource(string $source, string $namespace = 'default'): int { // Simple: source only (uses default namespace) return $this->vector()->deleteMemoriesBySource($source); // Common: source with namespace return $this->vector()->deleteMemoriesBySource($source, $namespace); // Advanced: full array control return $this->vector()->deleteMemoriesBySource([\ 'source' => $source,\ 'namespace' => $namespace\ ]); } /** * Get memory usage statistics */ public function getMemoryStats(string $namespace = 'default'): array { // Simple: default namespace $stats = $this->vector()->getStatistics(); // Specific namespace $stats = $this->vector()->getStatistics($namespace); // Advanced: with array $stats = $this->vector()->getStatistics(['namespace' => $namespace]); return $stats; } /** * Example: External testing access (new public methods!) */ public function demonstrateExternalAccess(): void { // These methods are now PUBLIC - can be called externally! // Perfect for Tinkerwell testing: $agent = Agent::named('managed_agent'); $result = $agent->vector()->addDocument('Test content'); $search = $agent->rag()->search('test query'); } } ### [​](https://docs.vizra.ai/concepts/vector-rag#creating-tools-for-vector-operations) Creating Tools for Vector Operations Vector Memory Tools Copy class SearchKnowledgeTool implements ToolInterface { public function definition(): array { return [\ 'name' => 'search_knowledge',\ 'description' => 'Search the knowledge base for relevant information',\ 'parameters' => [\ 'type' => 'object',\ 'properties' => [\ 'query' => [\ 'type' => 'string',\ 'description' => 'The search query'\ ],\ 'namespace' => [\ 'type' => 'string',\ 'description' => 'Knowledge namespace to search',\ 'default' => 'default'\ ],\ 'limit' => [\ 'type' => 'integer',\ 'description' => 'Maximum results to return',\ 'default' => 5\ ]\ ],\ 'required' => ['query']\ ]\ ]; } public function execute(array $arguments, AgentContext $context, AgentMemory $memory): string { // Get agent from context $agentClass = $context->getState('agent_class'); $agent = new $agentClass(); // Use the simplified API - proxy handles agent class injection $results = $agent->rag()->search([\ 'query' => $arguments['query'],\ 'namespace' => $arguments['namespace'] ?? 'default',\ 'limit' => $arguments['limit'] ?? 5\ ]); return json_encode([\ 'success' => true,\ 'results' => $results->map(fn($r) => [\ 'content' => $r->content,\ 'similarity' => round($r->similarity, 3),\ 'metadata' => $r->metadata,\ 'source' => $r->source\ ])->toArray(),\ 'total_found' => $results->count()\ ]); } } ### [​](https://docs.vizra.ai/concepts/vector-rag#using-the-vectormemory-model) Using the VectorMemory Model Direct Model Access Copy use Vizra\VizraADK\Models\VectorMemory; // Query memories directly $memories = VectorMemory::forAgent('my_agent') ->inNamespace('default') ->fromSource('docs') ->get(); // Calculate similarity (for non-pgvector) $similarity = $memory->cosineSimilarity($queryEmbedding); [​](https://docs.vizra.ai/concepts/vector-rag#vector-storage-drivers) Vector Storage Drivers ----------------------------------------------------------------------------------------------- PostgreSQL with pgvector ------------------------ High-performance vector similarity search with native PostgreSQL integration. Setup Copy # Install pgvector extension CREATE EXTENSION IF NOT EXISTS vector; # Configure in .env VIZRA_ADK_VECTOR_DRIVER=pgvector DB_CONNECTION=pgsql Meilisearch ----------- Lightning-fast, typo-tolerant search engine with built-in vector support. Setup Copy # Configure for Meilisearch VIZRA_ADK_VECTOR_DRIVER=meilisearch MEILISEARCH_HOST=http://localhost:7700 MEILISEARCH_KEY=your-master-key MEILISEARCH_PREFIX=agent_vectors_ **Fallback Behavior** - When neither pgvector nor Meilisearch are available, Vizra ADK automatically falls back to cosine similarity calculation using your database. This works with any driver but is best for development or small datasets. [​](https://docs.vizra.ai/concepts/vector-rag#complete-configuration-reference) Complete Configuration Reference ------------------------------------------------------------------------------------------------------------------- Here’s a complete reference for all vector memory configuration options available in Vizra ADK! config/vizra-adk.php Copy // Complete vector memory configuration 'vector_memory' => [\ // Enable/disable vector memory\ 'enabled' => env('VIZRA_ADK_VECTOR_ENABLED', true),\ \ // Storage driver: pgvector, meilisearch\ 'driver' => env('VIZRA_ADK_VECTOR_DRIVER', 'pgvector'),\ \ // Embedding provider: openai, cohere, ollama, gemini\ 'embedding_provider' => env('VIZRA_ADK_EMBEDDING_PROVIDER', 'openai'),\ \ // Model configuration per provider\ 'embedding_models' => [\ 'openai' => env('VIZRA_ADK_OPENAI_EMBEDDING_MODEL', 'text-embedding-3-small'),\ 'cohere' => env('VIZRA_ADK_COHERE_EMBEDDING_MODEL', 'embed-english-v3.0'),\ 'ollama' => env('VIZRA_ADK_OLLAMA_EMBEDDING_MODEL', 'nomic-embed-text'),\ 'gemini' => env('VIZRA_ADK_GEMINI_EMBEDDING_MODEL', 'text-embedding-004'),\ ],\ \ // Driver-specific settings\ 'drivers' => [\ 'meilisearch' => [\ 'host' => env('MEILISEARCH_HOST', 'http://localhost:7700'),\ 'api_key' => env('MEILISEARCH_KEY'),\ 'index_prefix' => env('MEILISEARCH_PREFIX', 'agent_vectors_'),\ ],\ // ... other drivers\ ],\ \ // Document chunking\ 'chunking' => [\ 'strategy' => env('VIZRA_ADK_CHUNK_STRATEGY', 'sentence'),\ 'chunk_size' => env('VIZRA_ADK_CHUNK_SIZE', 1000),\ 'overlap' => env('VIZRA_ADK_CHUNK_OVERLAP', 200),\ ],\ \ // RAG settings\ 'rag' => [\ 'max_context_length' => env('VIZRA_ADK_RAG_MAX_CONTEXT', 4000),\ 'include_metadata' => env('VIZRA_ADK_RAG_INCLUDE_METADATA', true),\ ],\ ] [​](https://docs.vizra.ai/concepts/vector-rag#console-commands) Console Commands ----------------------------------------------------------------------------------- Powerful CLI tools to manage your vector memory right from the terminal! ### [​](https://docs.vizra.ai/concepts/vector-rag#available-commands) Available Commands Terminal Copy # Store content from a file php artisan vector:store my_agent /path/to/document.txt # Search vector memory php artisan vector:search my_agent "search query" # Get statistics php artisan vector:stats my_agent [​](https://docs.vizra.ai/concepts/vector-rag#vector-memory-best-practices) Vector Memory Best Practices ----------------------------------------------------------------------------------------------------------- Organization ------------ * Use namespaces to organize content * Include descriptive metadata * Use content hashing to avoid duplicates Optimization ------------ * Choose appropriate chunk sizes * Monitor token counts for costs * Use pgvector for production Strategy -------- * Match chunking to content type * Select models for your use case * Clean up old memories regularly Remember -------- * Test similarity thresholds * Balance context size vs accuracy * Consider hybrid search approaches [Next: Evaluations\ -----------------\ \ Learn about testing and evaluating agents](https://docs.vizra.ai/concepts/evaluations) [Sessions & Memory\ -----------------\ \ Review memory management](https://docs.vizra.ai/concepts/sessions-memory) Was this page helpful? YesNo [Workflows](https://docs.vizra.ai/concepts/workflows) [Dynamic Prompts](https://docs.vizra.ai/concepts/dynamic-prompts) ⌘I --- # AI Agents - Vizra ADK [Skip to main content](https://docs.vizra.ai/concepts/agents#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Core Concepts AI Agents [Documentation](https://docs.vizra.ai/) On this page * [What’s an Agent?](https://docs.vizra.ai/concepts/agents#what%E2%80%99s-an-agent) * [Creating Your First Agent](https://docs.vizra.ai/concepts/agents#creating-your-first-agent) * [Quick Start with Artisan](https://docs.vizra.ai/concepts/agents#quick-start-with-artisan) * [The Agent Blueprint](https://docs.vizra.ai/concepts/agents#the-agent-blueprint) * [Agent Configuration Options](https://docs.vizra.ai/concepts/agents#agent-configuration-options) * [Unleashing Your Agent’s Powers](https://docs.vizra.ai/concepts/agents#unleashing-your-agent%E2%80%99s-powers) * [Let’s Chat! Using the Fluent API](https://docs.vizra.ai/concepts/agents#let%E2%80%99s-chat-using-the-fluent-api) * [Real-time Magic with Streaming](https://docs.vizra.ai/concepts/agents#real-time-magic-with-streaming) * [Managing Conversation History](https://docs.vizra.ai/concepts/agents#managing-conversation-history) * [Customizing Agent Behavior](https://docs.vizra.ai/concepts/agents#customizing-agent-behavior) * [Available Hooks](https://docs.vizra.ai/concepts/agents#available-hooks) * [Dynamic Prompts](https://docs.vizra.ai/concepts/agents#dynamic-prompts) * [Dynamic Prompts with Blade Templates](https://docs.vizra.ai/concepts/agents#dynamic-prompts-with-blade-templates) * [Quick Example](https://docs.vizra.ai/concepts/agents#quick-example) * [Adding Custom Variables](https://docs.vizra.ai/concepts/agents#adding-custom-variables) * [SubAgents: Building Agent Teams](https://docs.vizra.ai/concepts/agents#subagents-building-agent-teams) * [What Are SubAgents?](https://docs.vizra.ai/concepts/agents#what-are-subagents) * [How SubAgent Delegation Works](https://docs.vizra.ai/concepts/agents#how-subagent-delegation-works) * [Creating Specialized SubAgents](https://docs.vizra.ai/concepts/agents#creating-specialized-subagents) * [SubAgent Benefits](https://docs.vizra.ai/concepts/agents#subagent-benefits) * [Advanced Agent Techniques](https://docs.vizra.ai/concepts/agents#advanced-agent-techniques) * [Vector Memory & RAG](https://docs.vizra.ai/concepts/agents#vector-memory-%26-rag) * [Background Processing with Async](https://docs.vizra.ai/concepts/agents#background-processing-with-async) * [Vision & Multimodal Magic](https://docs.vizra.ai/concepts/agents#vision-%26-multimodal-magic) * [Fine-Tune on the Fly](https://docs.vizra.ai/concepts/agents#fine-tune-on-the-fly) * [Memory That Actually Remembers](https://docs.vizra.ai/concepts/agents#memory-that-actually-remembers) * [Understanding the Agent Lifecycle](https://docs.vizra.ai/concepts/agents#understanding-the-agent-lifecycle) * [The Request Journey](https://docs.vizra.ai/concepts/agents#the-request-journey) * [Lifecycle Hooks - Your Power Points](https://docs.vizra.ai/concepts/agents#lifecycle-hooks-your-power-points) * [beforeLlmCall() - Pre-Processing](https://docs.vizra.ai/concepts/agents#beforellmcall-pre-processing) * [afterLlmResponse() - Post-Processing](https://docs.vizra.ai/concepts/agents#afterllmresponse-post-processing) * [Tool Execution Hooks](https://docs.vizra.ai/concepts/agents#tool-execution-hooks) * [Lifecycle Events](https://docs.vizra.ai/concepts/agents#lifecycle-events) * [Pro Tips from the Trenches](https://docs.vizra.ai/concepts/agents#pro-tips-from-the-trenches) * [Ready to Build Something Amazing?](https://docs.vizra.ai/concepts/agents#ready-to-build-something-amazing) [​](https://docs.vizra.ai/concepts/agents#what%E2%80%99s-an-agent) What’s an Agent? -------------------------------------------------------------------------------------- Think of agents as your **smart AI assistants** that can handle complex tasks, remember conversations, and even work with other agents. They’re not just chatbots - they’re intelligent systems that can analyze data, make decisions, and take actions. Smart & Contextual ------------------ Remembers conversations, understands context, and learns from interactions Tool-Powered ------------ Uses custom tools to access databases, APIs, and perform real actions Multi-Model Support ------------------- Works with OpenAI, Anthropic Claude, and Google Gemini models Team Players ------------ Agents can delegate tasks to other specialized agents Vector Memory ------------- Built-in semantic search and RAG capabilities with public API access Testing Friendly ---------------- Public methods make testing and experimentation a breeze [​](https://docs.vizra.ai/concepts/agents#creating-your-first-agent) Creating Your First Agent ------------------------------------------------------------------------------------------------- Ready to build your first AI agent? It’s easier than you think! Let’s create a helpful customer support agent that can answer questions and solve problems. ### [​](https://docs.vizra.ai/concepts/agents#quick-start-with-artisan) Quick Start with Artisan Fire up your terminal and run this magical command: Terminal Copy php artisan vizra:make:agent CustomerSupportAgent **Boom!** You’ve just created your first agent! Let’s peek inside and see what makes it tick: ### [​](https://docs.vizra.ai/concepts/agents#the-agent-blueprint) The Agent Blueprint app/Agents/CustomerSupportAgent.php Copy go(); // With user context $response = CustomerSupportAgent::run('Show me my recent orders') ->forUser($user) ->go(); // With session for conversation continuity $response = CustomerSupportAgent::run('What was my previous question?') ->withSession($sessionId) ->go(); // Event-driven execution OrderProcessingAgent::run($orderCreatedEvent) ->async() ->go(); // Data analysis with context $insights = AnalyticsAgent::run($salesData) ->withContext(['period' => 'last_quarter']) ->go(); // Process large datasets asynchronously DataProcessorAgent::run($largeDataset) ->async() ->onQueue('processing') ->go(); // Monitor system health with thresholds SystemMonitorAgent::run($metrics) ->withContext(['threshold' => 0.95]) ->go(); // Generate reports with specific formats $report = ReportAgent::run('weekly_summary') ->withContext(['format' => 'pdf']) ->go(); ### [​](https://docs.vizra.ai/concepts/agents#real-time-magic-with-streaming) Real-time Magic with Streaming Want to see your agent think in real-time? Enable streaming for that ChatGPT-like experience: Copy // Enable streaming for real-time responses $stream = StorytellerAgent::run('Tell me a story') ->streaming() ->go(); foreach ($stream as $chunk) { echo $chunk; flush(); } ### [​](https://docs.vizra.ai/concepts/agents#managing-conversation-history) Managing Conversation History **Important:** All messages are always saved to the database for session continuity. These settings only control what previous messages are sent to the LLM for context. By default, agents don’t send conversation history to the LLM (for better performance and lower costs). But for chat agents, you’ll want context! Here’s how to control what history gets sent to the LLM: Copy // Enable history for conversational agents class ChatAgent extends BaseLlmAgent { protected bool $includeConversationHistory = true; // Send history to LLM protected string $contextStrategy = 'recent'; // 'none', 'recent', 'full' protected int $historyLimit = 10; // last 10 messages (for 'recent' strategy) } // Override at runtime $context->setState('include_history', true); $context->setState('history_depth', 5); [​](https://docs.vizra.ai/concepts/agents#customizing-agent-behavior) Customizing Agent Behavior --------------------------------------------------------------------------------------------------- Want to add your own special sauce? Agents come with powerful lifecycle hooks that let you customize exactly how they work. It’s like having backstage passes to your agent’s brain! ### [​](https://docs.vizra.ai/concepts/agents#available-hooks) Available Hooks * **beforeLlmCall** - Tweak messages before they hit the AI * **afterLlmResponse** - Process AI responses your way * **beforeToolCall** - Modify tool inputs on the fly * **afterToolResult** - Transform tool outputs * **onToolException** - Handle tool execution errors Here’s how to use these superpowers: Copy class CustomAgent extends BaseLlmAgent { public function beforeLlmCall(array $inputMessages, AgentContext $context): array { // Modify messages before sending to LLM // This is also where tracing starts return $inputMessages; } public function afterLlmResponse(Response|Generator $response, AgentContext $context, ?PendingRequest $request = null): mixed { // Process the LLM response // Access token usage: $response->usage // Access original request: $request return $response; } public function beforeToolCall(string $toolName, array $arguments, AgentContext $context): array { // Modify tool arguments before execution return $arguments; } public function afterToolResult(string $toolName, string $result, AgentContext $context): string { // Process tool results return $result; } public function onToolException(string $toolName, Throwable $e, AgentContext $context): void { // Handle tool execution errors // Log errors, send alerts, or implement recovery strategies } } [​](https://docs.vizra.ai/concepts/agents#dynamic-prompts) Dynamic Prompts ----------------------------------------------------------------------------- Want to test different personalities without changing code? Prompt versioning lets you A/B test, switch between tones, and evolve your agent’s voice on the fly! **Switch Prompts at Runtime** - No more hardcoding prompts! Store different versions and switch between them instantly. Copy // Use a specific prompt version $response = CustomerSupportAgent::run('Help me with my order') ->withPromptVersion('friendly') ->go(); // A/B test different tones $version = rand(0, 1) ? 'professional' : 'casual'; $response = CustomerSupportAgent::run($query) ->withPromptVersion($version) ->go(); Store prompts as `.md` files in `resources/prompts/{agent_name}/` for easy version control! [Learn more about Dynamic Prompts](https://docs.vizra.ai/concepts/dynamic-prompts) [​](https://docs.vizra.ai/concepts/agents#dynamic-prompts-with-blade-templates) Dynamic Prompts with Blade Templates ----------------------------------------------------------------------------------------------------------------------- Create **dynamic, context-aware prompts** using Laravel’s Blade templating engine. Your prompts can adapt based on user data, session state, and custom variables. ### [​](https://docs.vizra.ai/concepts/agents#quick-example) Quick Example Save your prompt as `.blade.php` to enable dynamic content: resources/prompts/agent\_name/default.blade.php Copy You are {{ $agent['name'] }}, a helpful assistant. @if(isset($user_name)) Hello {{ $user_name }}! How can I help you today? @else Hello! How can I assist you? @endif @if($context && $context->getState('premium_user')) Premium support mode activated @endif @if($tools->isNotEmpty()) I can help you with: {{ $tools->pluck('description')->join(', ') }} @endif ### [​](https://docs.vizra.ai/concepts/agents#adding-custom-variables) Adding Custom Variables Inject your own data by implementing `getPromptData()` in your agent: Copy class CustomerSupportAgent extends BaseLlmAgent { protected function getPromptData(AgentContext $context): array { return [\ 'company_name' => config('app.company_name'),\ 'support_hours' => '9 AM - 5 PM EST',\ 'ticket_count' => $this->getUserTicketCount($context),\ ]; } } Then use them in your template: Copy Welcome to {{ $company_name }} support! Our hours: {{ $support_hours }} @if($ticket_count > 0) You have {{ $ticket_count }} open tickets. @endif [Learn more about Blade Templates & Advanced Features](https://docs.vizra.ai/concepts/dynamic-prompts) [​](https://docs.vizra.ai/concepts/agents#subagents-building-agent-teams) SubAgents: Building Agent Teams ------------------------------------------------------------------------------------------------------------ Why have one agent when you can have a whole team? **SubAgents** let you create specialized agents that work together, with a manager agent delegating tasks to the right specialist. Think of it as building your own AI company! ### [​](https://docs.vizra.ai/concepts/agents#what-are-subagents) What Are SubAgents? SubAgents are specialized agents that a parent agent can delegate tasks to. When you define subAgents on an agent, Vizra ADK automatically adds the `DelegateToSubAgentTool` - allowing your manager agent to intelligently route requests to the right specialist. Copy class CustomerServiceManager extends BaseLlmAgent { protected string $name = 'customer_service_manager'; protected string $instructions = "You are a customer service manager. Route technical questions to the technical support agent. Route billing questions to the billing agent. Handle general inquiries yourself."; protected array $subAgents = [\ TechnicalSupportAgent::class,\ BillingSupportAgent::class,\ SalesAgent::class,\ ]; } ### [​](https://docs.vizra.ai/concepts/agents#how-subagent-delegation-works) How SubAgent Delegation Works When a user asks a question, the manager agent decides whether to handle it directly or delegate: Copy User: "My payment failed" ↓ Manager Agent analyzes the request ↓ Decides: "This is a billing issue" ↓ Delegates to BillingSupportAgent ↓ BillingSupportAgent handles the request ↓ Response returned to user ### [​](https://docs.vizra.ai/concepts/agents#creating-specialized-subagents) Creating Specialized SubAgents Each subAgent should be focused on a specific domain: Copy class TechnicalSupportAgent extends BaseLlmAgent { protected string $name = 'technical_support'; protected string $description = 'Handles technical issues, bugs, and integration problems'; protected string $instructions = "You are a technical support specialist. Help users with technical issues, debugging, and integration problems. Be patient and thorough in your explanations."; protected array $tools = [\ LogLookupTool::class,\ SystemStatusTool::class,\ ]; } class BillingSupportAgent extends BaseLlmAgent { protected string $name = 'billing_support'; protected string $description = 'Handles billing, payments, and subscription questions'; protected string $instructions = "You are a billing specialist. Help users with payment issues, invoices, and subscription management."; protected array $tools = [\ InvoiceLookupTool::class,\ RefundProcessorTool::class,\ ]; } **Pro Tip:** Write clear `description` properties on your subAgents - the manager agent uses these to decide which specialist to delegate to! ### [​](https://docs.vizra.ai/concepts/agents#subagent-benefits) SubAgent Benefits Separation of Concerns ---------------------- Each agent focuses on what it does best Specialized Tools ----------------- SubAgents can have their own unique tools Different Models ---------------- Use GPT-4 for complex tasks, GPT-3.5 for simple ones Easier Testing -------------- Test each specialist agent independently [​](https://docs.vizra.ai/concepts/agents#advanced-agent-techniques) Advanced Agent Techniques ------------------------------------------------------------------------------------------------- Ready to level up? Here are some pro tips and advanced features that’ll make your agents work harder and smarter! ### [​](https://docs.vizra.ai/concepts/agents#vector-memory-&-rag) Vector Memory & RAG Give your agents superpowers with built-in semantic search and knowledge retrieval! Perfect for building documentation assistants, knowledge bases, and intelligent Q&A systems. Agent with Vector Memory Copy class DocumentationAgent extends BaseLlmAgent { protected string $name = 'docs_agent'; public function loadKnowledge(string $content): void { // Simple: just add content $this->vector()->addDocument($content); // Advanced: with full metadata and organization $this->vector()->addDocument([\ 'content' => $content,\ 'metadata' => ['type' => 'docs', 'version' => '2.0'],\ 'namespace' => 'knowledge_base',\ 'source' => 'user_upload'\ ]); } public function answerQuestion(string $question, AgentContext $context): mixed { // Generate contextual answer using RAG $ragContext = $this->rag()->generateRagContext($question, [\ 'namespace' => 'knowledge_base',\ 'limit' => 5,\ 'threshold' => 0.7\ ]); if ($ragContext['total_results'] > 0) { $contextualInput = "Based on this knowledge:\n" . $ragContext['context'] . "\n\nAnswer: " . $question; } else { $contextualInput = $question; } return parent::run($contextualInput, $context); } } // Public access means you can test directly: $agent = Agent::named('docs_agent'); $agent->vector()->addDocument('Laravel is awesome!'); $results = $agent->vector()->search('framework'); **Vector Memory Pro Tips** * Use progressive API: simple strings for prototypes, arrays for production * Public methods make testing in Tinkerwell super easy * Organize with namespaces: ‘docs’, ‘faqs’, ‘policies’, etc. * Perfect for building chatbots that remember context ### [​](https://docs.vizra.ai/concepts/agents#background-processing-with-async) Background Processing with Async Got heavy lifting to do? Send your agents to work in the background: Copy // Execute agent asynchronously via queue $job = DataProcessorAgent::run($largeDataset) ->async() ->onQueue('processing') ->go(); // With delay and retries $job = ReportAgent::run('quarterly_report') ->delay(300) // 5 minutes ->tries(3) ->timeout(600) // 10 minutes ->go(); ### [​](https://docs.vizra.ai/concepts/agents#vision-&-multimodal-magic) Vision & Multimodal Magic Your agents aren’t just text wizards - they have **eyes** too! Send images, documents, and watch the magic happen: Copy // Send images with your request $response = VisionAgent::run('What\'s in this image?') ->withImage('/path/to/image.jpg') ->go(); // Multiple images and documents $response = DocumentAnalyzer::run('Summarize these documents') ->withDocument('/path/to/report.pdf') ->withImage('/path/to/chart.png') ->withImageFromUrl('https://example.com/diagram.jpg') ->go(); ### [​](https://docs.vizra.ai/concepts/agents#fine-tune-on-the-fly) Fine-Tune on the Fly Need more creativity? Want faster responses? **Override any parameter** at runtime: Copy // Override agent parameters at runtime $response = CreativeWriterAgent::run('Write a poem') ->temperature(0.9) // More creative ->maxTokens(500) ->go(); // Set multiple parameters $response = AnalyticalAgent::run($data) ->withParameters([\ 'temperature' => 0.2,\ 'max_tokens' => 2000,\ 'top_p' => 0.95\ ]) ->go(); [​](https://docs.vizra.ai/concepts/agents#memory-that-actually-remembers) Memory That Actually Remembers ----------------------------------------------------------------------------------------------------------- Unlike that friend who forgets your birthday every year, your agents have **perfect memory**! They remember everything important about your conversations and context. Conversation History -------------------- Every message in the session Tool Results ------------ What tools did and returned User Context ------------ Who they’re talking to Custom Data ----------- Any context you provide Copy // Add custom context $response = ShoppingAssistant::run('Find me a laptop') ->withContext([\ 'budget' => 1500,\ 'preferences' => ['brand' => 'Apple'],\ 'location' => 'New York'\ ]) ->go(); [​](https://docs.vizra.ai/concepts/agents#understanding-the-agent-lifecycle) Understanding the Agent Lifecycle ----------------------------------------------------------------------------------------------------------------- When you ask an agent to do something, it goes through a **carefully orchestrated lifecycle**. Understanding this flow helps you build more powerful agents and debug issues faster! ### [​](https://docs.vizra.ai/concepts/agents#the-request-journey) The Request Journey Copy 1. Your Code → AgentExecutor (Fluent API) 2. AgentExecutor → AgentManager (Orchestration) 3. AgentManager → Agent Instance (Your Logic) 4. Agent → LLM Provider (AI Processing) 5. LLM → Tools (If Needed) 6. Response → Back Through the Chain ### [​](https://docs.vizra.ai/concepts/agents#lifecycle-hooks-your-power-points) Lifecycle Hooks - Your Power Points Agents provide strategic hooks where you can intercept and modify behavior. These are your **control points** for customization: #### [​](https://docs.vizra.ai/concepts/agents#beforellmcall-pre-processing) beforeLlmCall() - Pre-Processing Called before sending messages to the AI. Perfect for adding context, filtering messages, or injecting system prompts. Copy public function beforeLlmCall(array $messages, AgentContext $context): array { // Add user preferences to system message $messages[0]['content'] .= "\nUser prefers formal tone."; return $messages; } #### [​](https://docs.vizra.ai/concepts/agents#afterllmresponse-post-processing) afterLlmResponse() - Post-Processing Called after receiving the AI’s response. Transform responses, extract insights, or trigger side effects. Now includes the original request for complete logging. Copy public function afterLlmResponse(Response $response, AgentContext $context, ?PendingRequest $request): mixed { // Log token usage and request details for monitoring Log::info('LLM call completed', [\ 'model' => $request?->model(),\ 'usage' => $response->usage\ ]); return $response; } #### [​](https://docs.vizra.ai/concepts/agents#tool-execution-hooks) Tool Execution Hooks Control tool execution with beforeToolCall() and afterToolResult() hooks. Copy public function beforeToolCall(string $toolName, array $arguments, AgentContext $context): array { // Add API keys or validate permissions if ($toolName === 'weather_api') { $arguments['api_key'] = config('services.weather.key'); } return $arguments; } ### [​](https://docs.vizra.ai/concepts/agents#lifecycle-events) Lifecycle Events As your agent works, it broadcasts events you can listen to for monitoring, logging, or triggering other actions: | Event | Description | | --- | --- | | `AgentExecutionStarting` | When execution begins | | `LlmCallInitiating` | Before calling the AI | | `ToolCallInitiating` | Before using a tool | | `ToolCallCompleted` | After tool finishes | | `LlmResponseReceived` | AI response received | | `AgentExecutionFinished` | All done! | [​](https://docs.vizra.ai/concepts/agents#pro-tips-from-the-trenches) Pro Tips from the Trenches --------------------------------------------------------------------------------------------------- Want to build agents that users **actually love**? Here’s the wisdom we’ve gathered from building hundreds of agents: Crystal Clear Instructions -------------------------- Write instructions like you’re explaining to a smart friend. Be specific about what you want! Right Model for the Job ----------------------- GPT-4 for complex reasoning, GPT-3.5 for quick tasks. Don’t use a Ferrari to go to the corner store! Hook Into Everything -------------------- Use lifecycle hooks for debugging and monitoring. You’ll thank yourself later! Delegate Like a Boss -------------------- Complex workflows? Use sub-agents! Let specialists handle what they do best. Stream for the Win ------------------ Enable streaming for long responses. Users love seeing agents “think” in real-time! [​](https://docs.vizra.ai/concepts/agents#ready-to-build-something-amazing) Ready to Build Something Amazing? ---------------------------------------------------------------------------------------------------------------- You’ve got the knowledge, now let’s put it to work! [Power Up with Tools\ -------------------\ \ Give your agents superpowers with custom tools](https://docs.vizra.ai/concepts/tools) [Deep Dive API Docs\ ------------------\ \ Every method, property, and secret revealed](https://docs.vizra.ai/api/agent-class) Was this page helpful? YesNo [Architecture](https://docs.vizra.ai/concepts/architecture) [Tools](https://docs.vizra.ai/concepts/tools) ⌘I --- # Tools - Vizra ADK [Skip to main content](https://docs.vizra.ai/concepts/tools#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Core Concepts Tools [Documentation](https://docs.vizra.ai/) On this page * [What Makes Tools Awesome?](https://docs.vizra.ai/concepts/tools#what-makes-tools-awesome) * [Understanding Tools](https://docs.vizra.ai/concepts/tools#understanding-tools) * [Creating Your First Tool](https://docs.vizra.ai/concepts/tools#creating-your-first-tool) * [Tool Structure](https://docs.vizra.ai/concepts/tools#tool-structure) * [Tool Interface Methods](https://docs.vizra.ai/concepts/tools#tool-interface-methods) * [The definition() Method](https://docs.vizra.ai/concepts/tools#the-definition-method) * [The execute() Method](https://docs.vizra.ai/concepts/tools#the-execute-method) * [Working with AgentContext](https://docs.vizra.ai/concepts/tools#working-with-agentcontext) * [Connecting Tools to Agents](https://docs.vizra.ai/concepts/tools#connecting-tools-to-agents) * [Advanced Tool Features](https://docs.vizra.ai/concepts/tools#advanced-tool-features) * [Database Queries](https://docs.vizra.ai/concepts/tools#database-queries) * [API Integration](https://docs.vizra.ai/concepts/tools#api-integration) * [File Operations](https://docs.vizra.ai/concepts/tools#file-operations) * [Error Handling & Validation](https://docs.vizra.ai/concepts/tools#error-handling-%26-validation) * [Input Validation](https://docs.vizra.ai/concepts/tools#input-validation) * [User Context Access](https://docs.vizra.ai/concepts/tools#user-context-access) * [Tools with Memory Access](https://docs.vizra.ai/concepts/tools#tools-with-memory-access) * [Testing Your Tools](https://docs.vizra.ai/concepts/tools#testing-your-tools) * [Complete Example: Refund Processor](https://docs.vizra.ai/concepts/tools#complete-example-refund-processor) * [Tool Best Practices](https://docs.vizra.ai/concepts/tools#tool-best-practices) [​](https://docs.vizra.ai/concepts/tools#what-makes-tools-awesome) What Makes Tools Awesome? ----------------------------------------------------------------------------------------------- Think of tools as your agent’s superpowers! While agents are great at conversation, tools let them actually **do things** - like looking up orders, sending emails, or integrating with your favorite APIs. It’s like giving your AI a Swiss Army knife! [​](https://docs.vizra.ai/concepts/tools#understanding-tools) Understanding Tools ------------------------------------------------------------------------------------ Here’s what makes Vizra tools special: Simple PHP Classes ------------------ Just implement the `ToolInterface` and you’re ready to roll! Self-Describing --------------- JSON Schema definitions help LLMs understand exactly how to use your tools Auto-Integration ---------------- Prism automatically connects your tools to the LLM’s function calling Context-Aware ------------- Access the full `AgentContext` for stateful operations [​](https://docs.vizra.ai/concepts/tools#creating-your-first-tool) Creating Your First Tool ---------------------------------------------------------------------------------------------- **Quick Start with Artisan** - The easiest way to create a tool? Let Artisan do the heavy lifting! Terminal Copy php artisan vizra:make:tool OrderLookupTool This creates a fully-functional tool template in `app/Tools/` ready for your custom logic! ### [​](https://docs.vizra.ai/concepts/tools#tool-structure) Tool Structure Every tool follows a simple pattern - implement the `ToolInterface` and define two key methods: app/Tools/OrderLookupTool.php Copy 'order_lookup',\ 'description' => 'Look up order information by order ID',\ 'parameters' => [\ 'type' => 'object',\ 'properties' => [\ 'order_id' => [\ 'type' => 'string',\ 'description' => 'The order ID to look up',\ ],\ ],\ 'required' => ['order_id'],\ ],\ ]; } public function execute(array $arguments, AgentContext $context, AgentMemory $memory): string { $orderId = $arguments['order_id'] ?? null; if (!$orderId) { return json_encode([\ 'status' => 'error',\ 'message' => 'Order ID is required',\ ]); } // Look up the order in your database $order = Order::find($orderId); if (!$order) { return json_encode([\ 'status' => 'error',\ 'message' => "Order {$orderId} not found",\ ]); } // Store this interaction in memory $memory->addFact("Recent order lookup: #{$orderId}", 1.0); $memory->addLearning("User inquired about order #{$orderId}"); return json_encode([\ 'status' => 'success',\ 'order_id' => $order->id,\ 'status' => $order->status,\ 'total' => $order->total,\ 'created_at' => $order->created_at->toDateTimeString(),\ ]); } } [​](https://docs.vizra.ai/concepts/tools#tool-interface-methods) Tool Interface Methods ------------------------------------------------------------------------------------------ ### [​](https://docs.vizra.ai/concepts/tools#the-definition-method) The definition() Method This is where you tell the LLM exactly what your tool does and what parameters it needs. Think of it as your tool’s instruction manual! Tool Definition Example Copy public function definition(): array { return [\ 'name' => 'weather_tool',\ 'description' => 'Get current weather information',\ 'parameters' => [\ 'type' => 'object',\ 'properties' => [\ 'location' => [\ 'type' => 'string',\ 'description' => 'The city and state, e.g. San Francisco, CA',\ ],\ 'units' => [\ 'type' => 'string',\ 'enum' => ['celsius', 'fahrenheit'],\ 'description' => 'Temperature units',\ ],\ ],\ 'required' => ['location'],\ ],\ ]; } Clear Names ----------- Use descriptive names that tell the LLM exactly what your tool does Good Descriptions ----------------- Help the LLM understand when and how to use your tool Type Safety ----------- Define parameter types to ensure correct usage ### [​](https://docs.vizra.ai/concepts/tools#the-execute-method) The execute() Method This is where the magic happens! Your tool receives arguments from the LLM and the current context, then returns results as JSON. Tool Execution Example Copy public function execute(array $arguments, AgentContext $context): string { // Access arguments $location = $arguments['location'] ?? null; // Access context $sessionId = $context->getSessionId(); $previousValue = $context->getState('some_key'); // Implement tool logic $result = [\ 'status' => 'success',\ 'temperature' => 25,\ 'condition' => 'sunny',\ 'location' => $location,\ ]; // Must return JSON string return json_encode($result); } **Remember:** Always return a JSON-encoded string! The LLM expects structured data it can understand. [​](https://docs.vizra.ai/concepts/tools#working-with-agentcontext) Working with AgentContext ------------------------------------------------------------------------------------------------ The `AgentContext` is your tool’s memory bank! It lets you access session info, store state between calls, and maintain context across conversations. Using AgentContext Copy public function execute(array $arguments, AgentContext $context): string { // Get session ID $sessionId = $context->getSessionId(); // Access state $previousOrder = $context->getState('last_order_id'); // Store state for future use $context->setState('last_order_id', $orderId); // Access user information if available $userId = $context->getState('user_id'); $userEmail = $context->getState('user_email'); // Your tool logic here... return json_encode(['status' => 'success']); } Reading State ------------- Use `getState()` to retrieve previously stored values Writing State ------------- Use `setState()` to persist data for future tool calls [​](https://docs.vizra.ai/concepts/tools#connecting-tools-to-agents) Connecting Tools to Agents -------------------------------------------------------------------------------------------------- Ready to give your agent superpowers? Just add your tools to the agent’s `$tools` array and watch the magic happen! app/Agents/CustomerSupportAgent.php Copy class CustomerSupportAgent extends BaseLlmAgent { /** @var array> */ protected array $tools = [\ OrderLookupTool::class,\ RefundProcessorTool::class,\ TicketCreatorTool::class,\ EmailSenderTool::class,\ ]; } Tools are automatically instantiated and made available to the LLM. Just list them and Vizra handles the rest! [​](https://docs.vizra.ai/concepts/tools#advanced-tool-features) Advanced Tool Features ------------------------------------------------------------------------------------------ Let’s explore some powerful patterns for building sophisticated tools! ### [​](https://docs.vizra.ai/concepts/tools#database-queries) Database Queries Connect your tools directly to your database for powerful data operations: Database Search Tool Copy class CustomerSearchTool implements ToolInterface { public function execute(array $arguments, AgentContext $context): string { $customers = Customer::query() ->where('name', 'like', "%{$arguments['query']}%") ->orWhere('email', 'like', "%{$arguments['query']}%") ->limit(10) ->get(); return json_encode([\ 'status' => 'success',\ 'customers' => $customers->map(fn($c) => [\ 'id' => $c->id,\ 'name' => $c->name,\ 'email' => $c->email,\ ])->toArray(),\ ]); } } ### [​](https://docs.vizra.ai/concepts/tools#api-integration) API Integration Connect to external APIs and bring real-world data into your conversations: External API Tool Copy class WeatherApiTool implements ToolInterface { public function execute(array $arguments, AgentContext $context): string { try { $response = Http::get('https://api.weather.com/v1/current', [\ 'location' => $arguments['location'],\ 'api_key' => config('services.weather.key'),\ ]); return json_encode([\ 'status' => 'success',\ 'weather' => $response->json(),\ ]); } catch (Exception $e) { return json_encode([\ 'status' => 'error',\ 'message' => 'Failed to fetch weather: ' . $e->getMessage(),\ ]); } } } ### [​](https://docs.vizra.ai/concepts/tools#file-operations) File Operations Handle file uploads, downloads, and processing with ease: File Handler Tool Copy class FileUploaderTool implements ToolInterface { public function definition(): array { return [\ 'name' => 'file_uploader',\ 'description' => 'Upload a file from base64 content',\ 'parameters' => [\ 'type' => 'object',\ 'properties' => [\ 'file_content' => [\ 'type' => 'string',\ 'description' => 'Base64 encoded file content',\ ],\ 'filename' => [\ 'type' => 'string',\ 'description' => 'Name for the file',\ ],\ ],\ 'required' => ['file_content', 'filename'],\ ],\ ]; } public function execute(array $arguments, AgentContext $context): string { $content = base64_decode($arguments['file_content']); $path = Storage::put('uploads/' . $arguments['filename'], $content); return json_encode([\ 'status' => 'success',\ 'file_path' => $path,\ 'size' => strlen($content),\ ]); } } [​](https://docs.vizra.ai/concepts/tools#error-handling-&-validation) Error Handling & Validation ---------------------------------------------------------------------------------------------------- Build bulletproof tools with proper validation and error handling! Your agents will thank you. ### [​](https://docs.vizra.ai/concepts/tools#input-validation) Input Validation Always validate your inputs - it’s the first line of defense against errors: Input Validation Example Copy public function execute(array $arguments, AgentContext $context, AgentMemory $memory): string { // Validate inputs $validator = Validator::make($arguments, [\ 'email' => 'required|email',\ 'amount' => 'required|numeric|min:0|max:10000',\ ]); if ($validator->fails()) { return json_encode([\ 'status' => 'error',\ 'message' => 'Invalid parameters: ' . $validator->errors()->first(),\ ]); } // Store validated information $memory->addFact("User email: {$arguments['email']}", 1.0); $memory->addLearning("User requested transaction of amount: {$arguments['amount']}"); // Proceed with validated data return json_encode(['status' => 'success']); } ### [​](https://docs.vizra.ai/concepts/tools#user-context-access) User Context Access Check for user authentication and access user-specific data safely: User Context Validation Copy public function execute(array $arguments, AgentContext $context, AgentMemory $memory): string { // Check if user context is available $userId = $context->getState('user_id'); if (!$userId) { return json_encode([\ 'status' => 'error',\ 'message' => 'User authentication required',\ ]); } // Get user data from context $userData = $context->getState('user_data'); $userEmail = $context->getState('user_email'); // Store user-specific information if ($userEmail && !$memory->getFacts()->contains('content', "User email: {$userEmail}")) { $memory->addFact("User email: {$userEmail}", 1.0); } // Process with user context return json_encode(['status' => 'success']); } [​](https://docs.vizra.ai/concepts/tools#tools-with-memory-access) Tools with Memory Access ---------------------------------------------------------------------------------------------- **Every Tool Gets Memory Access!** - All tools now receive the agent’s memory as a third parameter. Build personalized experiences by reading and writing to memory! The `execute` method now includes `AgentMemory`: app/Tools/UserProfileTool.php Copy 'manage_user_profile',\ 'description' => 'Update or retrieve user profile information from memory',\ 'parameters' => [\ 'type' => 'object',\ 'properties' => [\ 'action' => [\ 'type' => 'string',\ 'description' => 'Action to perform',\ 'enum' => ['update_fact', 'add_preference', 'get_profile']\ ],\ 'key' => ['type' => 'string'],\ 'value' => ['type' => 'string']\ ],\ 'required' => ['action']\ ]\ ]; } public function execute( array $arguments, AgentContext $context, AgentMemory $memory // Now included in all tools! ): string { switch ($arguments['action']) { case 'update_fact': $memory->addFact( "{$arguments['key']}: {$arguments['value']}", 1.0 ); return json_encode(['success' => true]); case 'add_preference': $memory->addPreference( $arguments['value'], $arguments['key'] ?? 'general' ); return json_encode(['success' => true]); case 'get_profile': return json_encode([\ 'summary' => $memory->getSummary(),\ 'facts' => $memory->getFacts()->pluck('content'),\ 'preferences' => $memory->getPreferences()\ ]); } } } Memory Methods Available ------------------------ * `addFact()` - Store immutable facts * `addLearning()` - Track insights * `addPreference()` - Store preferences * `updateSummary()` - Update user profile Use Cases --------- * Update user preferences from form submissions * Store discovered facts during conversations * Build comprehensive user profiles over time * Sync memory across different tools **Pro Tip: Simple Memory Usage** - Every tool automatically receives the agent’s memory! Use it to store learnings, facts, and preferences. The memory persists across sessions, enabling truly personalized experiences. [​](https://docs.vizra.ai/concepts/tools#testing-your-tools) Testing Your Tools ---------------------------------------------------------------------------------- Great tools deserve great tests! Here’s how to ensure your tools work perfectly every time: tests/Tools/OrderLookupToolTest.php Copy class OrderLookupToolTest extends TestCase { public function test_finds_existing_order() { $order = Order::factory()->create(); $tool = new OrderLookupTool(); $context = new AgentContext('test-session'); $result = $tool->execute( ['order_id' => $order->id], $context ); $data = json_decode($result, true); $this->assertEquals('success', $data['status']); $this->assertEquals($order->id, $data['order_id']); } public function test_handles_missing_order() { $tool = new OrderLookupTool(); $context = new AgentContext('test-session'); $result = $tool->execute( ['order_id' => 'invalid'], $context ); $data = json_decode($result, true); $this->assertEquals('error', $data['status']); $this->assertStringContainsString('not found', $data['message']); } } **Testing tip:** Test both success paths and error conditions. Your future self will appreciate it! [​](https://docs.vizra.ai/concepts/tools#complete-example-refund-processor) Complete Example: Refund Processor ----------------------------------------------------------------------------------------------------------------- Let’s put it all together with a real-world example that shows validation, error handling, and business logic! app/Tools/RefundProcessorTool.php Copy 'process_refund',\ 'description' => 'Process a refund for an order',\ 'parameters' => [\ 'type' => 'object',\ 'properties' => [\ 'order_id' => [\ 'type' => 'string',\ 'description' => 'The order ID to refund',\ ],\ 'amount' => [\ 'type' => 'number',\ 'description' => 'Refund amount (optional for partial refunds)',\ 'minimum' => 0,\ ],\ 'reason' => [\ 'type' => 'string',\ 'description' => 'Reason for refund',\ ],\ ],\ 'required' => ['order_id', 'reason'],\ ],\ ]; } public function execute(array $arguments, AgentContext $context): string { // Validate inputs $validator = Validator::make($arguments, [\ 'order_id' => 'required|string',\ 'amount' => 'nullable|numeric|min:0',\ 'reason' => 'required|string',\ ]); if ($validator->fails()) { return json_encode([\ 'status' => 'error',\ 'message' => 'Validation failed: ' . $validator->errors()->first(),\ ]); } // Check user authorization $userId = $context->getState('user_id'); if (!$userId) { return json_encode([\ 'status' => 'error',\ 'message' => 'User authentication required',\ ]); } try { $order = Order::findOrFail($arguments['order_id']); // Verify order belongs to user if ($order->user_id !== $userId) { return json_encode([\ 'status' => 'error',\ 'message' => 'Order not found',\ ]); } $refund = $this->refunds->process( $order, $arguments['amount'] ?? $order->total, $arguments['reason'] ); return json_encode([\ 'status' => 'success',\ 'refund_id' => $refund->id,\ 'amount' => $refund->amount,\ 'refund_status' => $refund->status,\ 'message' => 'Refund processed successfully',\ ]); } catch (\Exception $e) { return json_encode([\ 'status' => 'error',\ 'message' => 'Failed to process refund: ' . $e->getMessage(),\ ]); } } } [​](https://docs.vizra.ai/concepts/tools#tool-best-practices) Tool Best Practices ------------------------------------------------------------------------------------ Do's ---- * **Single Responsibility** - Each tool should do one thing and do it well * **Input Validation** - Always validate parameters before processing * **Clear Error Messages** - Help the LLM understand what went wrong * **Descriptive Naming** - Use names that clearly describe the tool’s purpose More Do's --------- * **Error Handling** - Gracefully handle exceptions and edge cases * **Rate Limiting** - Protect expensive operations from abuse * **Thorough Testing** - Test success paths and error conditions * **JSON Responses** - Always return properly formatted JSON strings [Sessions & Memory\ -----------------\ \ Learn about context management and persistent state](https://docs.vizra.ai/concepts/sessions-memory) [Tool API Reference\ ------------------\ \ Detailed tool class documentation and methods](https://docs.vizra.ai/api/tool-class) Was this page helpful? YesNo [AI Agents](https://docs.vizra.ai/concepts/agents) [Sessions & Memory](https://docs.vizra.ai/concepts/sessions-memory) ⌘I --- # Toolbox - Vizra ADK [Skip to main content](https://docs.vizra.ai/tools/toolbox#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Tools Toolbox [Documentation](https://docs.vizra.ai/) On this page * [What Are Toolboxes?](https://docs.vizra.ai/tools/toolbox#what-are-toolboxes) * [Using Toolboxes in Agents](https://docs.vizra.ai/tools/toolbox#using-toolboxes-in-agents) * [Runtime Toolbox Management](https://docs.vizra.ai/tools/toolbox#runtime-toolbox-management) * [Checking Toolbox Status](https://docs.vizra.ai/tools/toolbox#checking-toolbox-status) * [Creating Your First Toolbox](https://docs.vizra.ai/tools/toolbox#creating-your-first-toolbox) * [Basic Toolbox Structure](https://docs.vizra.ai/tools/toolbox#basic-toolbox-structure) * [Authorization](https://docs.vizra.ai/tools/toolbox#authorization) * [Toolbox-Level Gates](https://docs.vizra.ai/tools/toolbox#toolbox-level-gates) * [Toolbox-Level Policies](https://docs.vizra.ai/tools/toolbox#toolbox-level-policies) * [Per-Tool Gates](https://docs.vizra.ai/tools/toolbox#per-tool-gates) * [Per-Tool Policies](https://docs.vizra.ai/tools/toolbox#per-tool-policies) * [Conditional Tool Inclusion](https://docs.vizra.ai/tools/toolbox#conditional-tool-inclusion) * [Real-World Examples](https://docs.vizra.ai/tools/toolbox#real-world-examples) * [Admin Toolbox with Gate](https://docs.vizra.ai/tools/toolbox#admin-toolbox-with-gate) * [Multi-Tenant Toolbox](https://docs.vizra.ai/tools/toolbox#multi-tenant-toolbox) * [Feature-Flagged Toolbox](https://docs.vizra.ai/tools/toolbox#feature-flagged-toolbox) * [Best Practices](https://docs.vizra.ai/tools/toolbox#best-practices) * [API Reference](https://docs.vizra.ai/tools/toolbox#api-reference) * [BaseToolbox Properties](https://docs.vizra.ai/tools/toolbox#basetoolbox-properties) * [BaseToolbox Methods](https://docs.vizra.ai/tools/toolbox#basetoolbox-methods) * [Agent Toolbox Methods](https://docs.vizra.ai/tools/toolbox#agent-toolbox-methods) * [Artisan Command](https://docs.vizra.ai/tools/toolbox#artisan-command) [​](https://docs.vizra.ai/tools/toolbox#what-are-toolboxes) What Are Toolboxes? ---------------------------------------------------------------------------------- Toolboxes let you group related tools into logical collections with built-in authorization support. Think of them as “tool bundles” that can be enabled or disabled based on user permissions, subscription tiers, or any other context. Organized Tools --------------- Group related tools together for cleaner agent definitions Built-in Authorization ---------------------- Use Laravel Gates and Policies at both toolbox and tool levels Dynamic Loading --------------- Tools are loaded on-demand based on user context Runtime Flexibility ------------------- Add or remove toolboxes at runtime based on conditions [​](https://docs.vizra.ai/tools/toolbox#using-toolboxes-in-agents) Using Toolboxes in Agents ----------------------------------------------------------------------------------------------- The easiest way to use toolboxes is to declare them in your agent’s `$toolboxes` property: app/Agents/CustomerAgent.php Copy isPremium()) { $agent->addToolbox(PremiumFeaturesToolbox::class); } // Remove a toolbox if certain conditions aren't met if (!$user->hasVerifiedEmail()) { $agent->removeToolbox(SensitiveOperationsToolbox::class); } // Force reload tools after changes $agent->forceReloadTools(); ### [​](https://docs.vizra.ai/tools/toolbox#checking-toolbox-status) Checking Toolbox Status Toolbox Inspection Methods Copy // Check if a toolbox is registered if ($agent->hasToolbox(AdminToolbox::class)) { // ... } // Get all registered toolbox classes $toolboxClasses = $agent->getToolboxes(); // Get loaded toolbox instances (after agent initialization) $loadedToolboxes = $agent->getLoadedToolboxes(); [​](https://docs.vizra.ai/tools/toolbox#creating-your-first-toolbox) Creating Your First Toolbox --------------------------------------------------------------------------------------------------- Generate a new toolbox using the Artisan command: Copy php artisan vizra:make:toolbox CustomerSupportToolbox You can also specify options during generation: Copy # With a Laravel Gate php artisan vizra:make:toolbox AdminToolbox --gate=admin-access # With a Laravel Policy php artisan vizra:make:toolbox PremiumToolbox --policy="App\Policies\SubscriptionPolicy" # With initial tools php artisan vizra:make:toolbox OrderToolbox --tools="App\Tools\CreateOrderTool,App\Tools\CancelOrderTool" ### [​](https://docs.vizra.ai/tools/toolbox#basic-toolbox-structure) Basic Toolbox Structure app/Toolboxes/CustomerSupportToolbox.php Copy hasRole('admin'); }); } ### [​](https://docs.vizra.ai/tools/toolbox#toolbox-level-policies) Toolbox-Level Policies For more complex authorization logic, use a Policy: app/Toolboxes/PremiumToolbox.php Copy subscription?->tier === 'premium' && $user->subscription->isActive(); } } When both a `$gate` and `$policy` are defined, the policy takes precedence. Only one authorization method is checked. ### [​](https://docs.vizra.ai/tools/toolbox#per-tool-gates) Per-Tool Gates You can apply fine-grained authorization to individual tools within a toolbox: app/Toolboxes/FinanceToolbox.php Copy 'process-refunds',\ DeleteTransactionTool::class => 'delete-transactions',\ ]; } ### [​](https://docs.vizra.ai/tools/toolbox#per-tool-policies) Per-Tool Policies For even more control, use policies on individual tools: Per-Tool Policy Configuration Copy protected array $toolPolicies = [\ DeleteTransactionTool::class => [TransactionPolicy::class, 'delete'],\ ArchiveRecordsTool::class => [RecordPolicy::class, 'archive'],\ ]; The authorization hierarchy is: 1. **Toolbox gate/policy** - Must pass to see any tools 2. **Per-tool gate** - Additional check for specific tools 3. **Per-tool policy** - Alternative to per-tool gates 4. **`shouldIncludeTool()`** - Final conditional logic [​](https://docs.vizra.ai/tools/toolbox#conditional-tool-inclusion) Conditional Tool Inclusion ------------------------------------------------------------------------------------------------- For dynamic logic that goes beyond gates and policies, override the `shouldIncludeTool()` method: app/Toolboxes/ContextAwareToolbox.php Copy getState('user_tier') === 'power_user'; } // Include beta features only for users in the beta program if ($toolClass === BetaFeatureTool::class) { return $context->getState('beta_tester') === true; } // Include all other tools by default return true; } } Authorized tools are cached per session ID for performance. If context changes mid-session and you need tools to be re-evaluated, call `$toolbox->clearCache()` or `$agent->forceReloadTools()`. [​](https://docs.vizra.ai/tools/toolbox#real-world-examples) Real-World Examples ----------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/tools/toolbox#admin-toolbox-with-gate) Admin Toolbox with Gate app/Toolboxes/AdminToolbox.php Copy 'database-access',\ ]; } ### [​](https://docs.vizra.ai/tools/toolbox#multi-tenant-toolbox) Multi-Tenant Toolbox app/Toolboxes/TenantToolbox.php Copy getState('managed_tenant_ids', []); return count($tenantIds) > 1; } return true; } } ### [​](https://docs.vizra.ai/tools/toolbox#feature-flagged-toolbox) Feature-Flagged Toolbox app/Toolboxes/ExperimentalToolbox.php Copy 'ai-summary',\ VoiceInputTool::class => 'voice-input',\ ImageAnalysisTool::class => 'image-analysis',\ ]; $flag = $featureFlags[$toolClass] ?? null; if ($flag === null) { return true; } // Use Laravel Pennant or similar feature flag system $userId = $context->getState('user_id'); return Feature::for($userId)->active($flag); } } [​](https://docs.vizra.ai/tools/toolbox#best-practices) Best Practices ------------------------------------------------------------------------- Group by Domain --------------- Organize tools by business domain (orders, payments, support) rather than technical function Use Gates for Simple Checks --------------------------- Gates are perfect for role-based checks. Use policies for complex business logic Keep Toolboxes Focused ---------------------- A toolbox should have 3-8 related tools. Split large toolboxes into smaller ones Prefer Toolbox Auth ------------------- Use toolbox-level authorization when possible. Per-tool auth adds complexity **Naming Convention**: Use descriptive names ending in `Toolbox` - e.g., `CustomerSupportToolbox`, `PaymentProcessingToolbox`, `AdminToolbox`. [​](https://docs.vizra.ai/tools/toolbox#api-reference) API Reference ----------------------------------------------------------------------- ### [​](https://docs.vizra.ai/tools/toolbox#basetoolbox-properties) BaseToolbox Properties | Property | Type | Description | | --- | --- | --- | | `$name` | `string` | Unique identifier for the toolbox | | `$description` | `string` | Human-readable description | | `$tools` | `array` | Array of tool class names | | `$gate` | `?string` | Laravel Gate name for toolbox auth | | `$policy` | `?string` | Laravel Policy class for toolbox auth | | `$policyAbility` | `?string` | Policy ability to check (default: `'use'`) | | `$toolGates` | `array` | Per-tool gate mappings | | `$toolPolicies` | `array` | Per-tool policy mappings | ### [​](https://docs.vizra.ai/tools/toolbox#basetoolbox-methods) BaseToolbox Methods | Method | Description | | --- | --- | | `name(): string` | Get the toolbox name | | `description(): string` | Get the toolbox description | | `tools(): array` | Get the array of tool class names | | `authorize(AgentContext $context): bool` | Check toolbox-level authorization | | `authorizedTools(AgentContext $context): array` | Get instantiated, authorized tools | | `getGate(): ?string` | Get the configured gate name | | `getPolicy(): ?string` | Get the configured policy class | | `getToolGates(): array` | Get per-tool gate mappings | | `clearCache(): void` | Clear the authorized tools cache | ### [​](https://docs.vizra.ai/tools/toolbox#agent-toolbox-methods) Agent Toolbox Methods | Method | Description | | --- | --- | | `addToolbox(string $toolboxClass): static` | Add a toolbox at runtime | | `removeToolbox(string $toolboxClass): static` | Remove a toolbox | | `getToolboxes(): array` | Get registered toolbox class names | | `hasToolbox(string $toolboxClass): bool` | Check if toolbox is registered | | `getLoadedToolboxes(): array` | Get loaded toolbox instances | | `forceReloadTools(): void` | Clear cache and reload all tools | ### [​](https://docs.vizra.ai/tools/toolbox#artisan-command) Artisan Command Copy php artisan vizra:make:toolbox {name} [options] Options: -g, --gate=GATE Laravel Gate name for authorization -p, --policy=POLICY Laravel Policy class for authorization -t, --tools=TOOLS Comma-separated tool class names * * * [Tools\ -----\ \ Learn the basics of creating tools](https://docs.vizra.ai/tools/tools) [Tool Pipelines\ --------------\ \ Chain tools together for sequential workflows](https://docs.vizra.ai/tools/tool-pipelines) Was this page helpful? YesNo [Image Agent](https://docs.vizra.ai/agents/image-agent) [Tool Pipelines](https://docs.vizra.ai/tools/tool-pipelines) ⌘I --- # Structured Output - Vizra ADK [Skip to main content](https://docs.vizra.ai/tools/structured-output#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Tools Structured Output [Documentation](https://docs.vizra.ai/) On this page * [What Is Structured Output?](https://docs.vizra.ai/tools/structured-output#what-is-structured-output) * [Quick Start](https://docs.vizra.ai/tools/structured-output#quick-start) * [Available Schema Types](https://docs.vizra.ai/tools/structured-output#available-schema-types) * [StringSchema](https://docs.vizra.ai/tools/structured-output#stringschema) * [NumberSchema](https://docs.vizra.ai/tools/structured-output#numberschema) * [BooleanSchema](https://docs.vizra.ai/tools/structured-output#booleanschema) * [EnumSchema](https://docs.vizra.ai/tools/structured-output#enumschema) * [ArraySchema](https://docs.vizra.ai/tools/structured-output#arrayschema) * [ObjectSchema](https://docs.vizra.ai/tools/structured-output#objectschema) * [AnyOfSchema](https://docs.vizra.ai/tools/structured-output#anyofschema) * [Real-World Examples](https://docs.vizra.ai/tools/structured-output#real-world-examples) * [Data Extraction Agent](https://docs.vizra.ai/tools/structured-output#data-extraction-agent) * [Sentiment Analysis Agent](https://docs.vizra.ai/tools/structured-output#sentiment-analysis-agent) * [Content Classification Agent](https://docs.vizra.ai/tools/structured-output#content-classification-agent) * [Nullable Fields](https://docs.vizra.ai/tools/structured-output#nullable-fields) * [Nested Schemas](https://docs.vizra.ai/tools/structured-output#nested-schemas) * [Combining With Tools](https://docs.vizra.ai/tools/structured-output#combining-with-tools) * [Provider Considerations](https://docs.vizra.ai/tools/structured-output#provider-considerations) * [OpenAI Strict Mode](https://docs.vizra.ai/tools/structured-output#openai-strict-mode) * [Anthropic Tool Calling Mode](https://docs.vizra.ai/tools/structured-output#anthropic-tool-calling-mode) * [Best Practices](https://docs.vizra.ai/tools/structured-output#best-practices) * [API Reference](https://docs.vizra.ai/tools/structured-output#api-reference) * [Schema Types](https://docs.vizra.ai/tools/structured-output#schema-types) * [Agent Method](https://docs.vizra.ai/tools/structured-output#agent-method) * [ObjectSchema Parameters](https://docs.vizra.ai/tools/structured-output#objectschema-parameters) [​](https://docs.vizra.ai/tools/structured-output#what-is-structured-output) What Is Structured Output? ---------------------------------------------------------------------------------------------------------- Structured output lets you define exactly how you want your AI responses formatted. Instead of parsing free-form text, you get clean, predictable data structures that are ready to use in your application. Type-Safe Responses ------------------- Define schemas and get responses that match your expected structure No Parsing Required ------------------- Skip the regex and string parsing - data comes pre-formatted Provider Validation ------------------- Providers like OpenAI enforce schema compliance at generation time Works With Tools ---------------- Combine structured output with tool calls for powerful workflows [​](https://docs.vizra.ai/tools/structured-output#quick-start) Quick Start ----------------------------------------------------------------------------- To enable structured output, override the `getSchema()` method in your agent: app/Agents/MovieReviewAgent.php Copy run('Review the movie Inception', $context); // The response text contains the JSON, but you can also access it structured // via the underlying Prism response when using afterLlmResponse hook [​](https://docs.vizra.ai/tools/structured-output#available-schema-types) Available Schema Types --------------------------------------------------------------------------------------------------- Vizra ADK uses Prism PHP’s schema system. Here are all available types: ### [​](https://docs.vizra.ai/tools/structured-output#stringschema) StringSchema For text values of any length. Copy use Prism\Prism\Schema\StringSchema; new StringSchema( name: 'description', description: 'A detailed product description' ) ### [​](https://docs.vizra.ai/tools/structured-output#numberschema) NumberSchema For integers and floating-point numbers. Copy use Prism\Prism\Schema\NumberSchema; new NumberSchema( name: 'price', description: 'Product price in USD' ) ### [​](https://docs.vizra.ai/tools/structured-output#booleanschema) BooleanSchema For true/false values. Copy use Prism\Prism\Schema\BooleanSchema; new BooleanSchema( name: 'in_stock', description: 'Whether the product is available' ) ### [​](https://docs.vizra.ai/tools/structured-output#enumschema) EnumSchema For values restricted to a specific set of options. Copy use Prism\Prism\Schema\EnumSchema; new EnumSchema( name: 'priority', description: 'Task priority level', options: ['low', 'medium', 'high', 'critical'] ) ### [​](https://docs.vizra.ai/tools/structured-output#arrayschema) ArraySchema For lists of items following a specific schema. Copy use Prism\Prism\Schema\ArraySchema; use Prism\Prism\Schema\StringSchema; new ArraySchema( name: 'tags', description: 'List of relevant tags', items: new StringSchema('tag', 'A single tag') ) ### [​](https://docs.vizra.ai/tools/structured-output#objectschema) ObjectSchema For complex nested structures. This should be your root schema. Copy use Prism\Prism\Schema\ObjectSchema; use Prism\Prism\Schema\StringSchema; use Prism\Prism\Schema\NumberSchema; new ObjectSchema( name: 'product', description: 'Product information', properties: [\ new StringSchema('name', 'Product name'),\ new NumberSchema('price', 'Price in USD'),\ new StringSchema('category', 'Product category'),\ ], requiredFields: ['name', 'price'] ) ### [​](https://docs.vizra.ai/tools/structured-output#anyofschema) AnyOfSchema For flexible data that can match one of several schemas. Copy use Prism\Prism\Schema\AnyOfSchema; use Prism\Prism\Schema\StringSchema; use Prism\Prism\Schema\NumberSchema; new AnyOfSchema( schemas: [\ new StringSchema('text', 'A text value'),\ new NumberSchema('number', 'A numeric value'),\ ], name: 'flexible_value', description: 'Can be either text or a number' ) **Provider Compatibility**: `AnyOfSchema` works with OpenAI and Gemini, but is not supported by Anthropic. Design alternative schema patterns when targeting Anthropic. [​](https://docs.vizra.ai/tools/structured-output#real-world-examples) Real-World Examples --------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/tools/structured-output#data-extraction-agent) Data Extraction Agent Extract structured data from unstructured text: app/Agents/ContactExtractorAgent.php Copy withProviderOptions([\ 'schema' => [\ 'strict' => true\ ]\ ]); } ### [​](https://docs.vizra.ai/tools/structured-output#anthropic-tool-calling-mode) Anthropic Tool Calling Mode For Anthropic, use tool calling mode for more reliable structured output: Anthropic Tool Calling Copy protected function buildPrismRequest(AgentContext $context, array $messages): TextPendingRequest|StructuredPendingRequest { $request = parent::buildPrismRequest($context, $messages); // Use tool calling for more reliable parsing with Anthropic return $request->withProviderOptions([\ 'use_tool_calling' => true\ ]); } [​](https://docs.vizra.ai/tools/structured-output#best-practices) Best Practices ----------------------------------------------------------------------------------- Use ObjectSchema as Root ------------------------ Always use ObjectSchema as your top-level schema. Providers like OpenAI require this in strict mode Write Clear Descriptions ------------------------ Descriptive field descriptions help the LLM understand what data to provide Mark Optional Fields Nullable ----------------------------- Use `nullable: true` for fields that might not have values Validate Responses ------------------ Even with structured output, validate the response in your application **Schema Limitations**: While structured output provides schema enforcement at generation time, it doesn’t guarantee semantic correctness. Always validate that the data makes sense for your use case. [​](https://docs.vizra.ai/tools/structured-output#api-reference) API Reference --------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/tools/structured-output#schema-types) Schema Types | Schema | Purpose | Key Parameters | | --- | --- | --- | | `StringSchema` | Text values | `name`, `description`, `nullable` | | `NumberSchema` | Numeric values | `name`, `description`, `nullable` | | `BooleanSchema` | True/false | `name`, `description`, `nullable` | | `EnumSchema` | Fixed options | `name`, `description`, `options`, `nullable` | | `ArraySchema` | Lists | `name`, `description`, `items`, `nullable` | | `ObjectSchema` | Complex objects | `name`, `description`, `properties`, `requiredFields`, `nullable` | | `AnyOfSchema` | Union types | `schemas`, `name`, `description`, `nullable` | ### [​](https://docs.vizra.ai/tools/structured-output#agent-method) Agent Method | Method | Return Type | Description | | --- | --- | --- | | `getSchema()` | `?Schema` | Override to return your schema. Return `null` for standard text output | ### [​](https://docs.vizra.ai/tools/structured-output#objectschema-parameters) ObjectSchema Parameters | Parameter | Type | Description | | --- | --- | --- | | `name` | `string` | Schema identifier | | `description` | `string` | Human-readable description | | `properties` | `array` | Array of child schemas | | `requiredFields` | `array` | Field names that must be present | | `nullable` | `bool` | Whether the entire object can be null | * * * [Tools\ -----\ \ Learn how to create tools for your agents](https://docs.vizra.ai/tools/tools) [Agents\ ------\ \ Understanding agent architecture](https://docs.vizra.ai/concepts/agents) Was this page helpful? YesNo [Tool Pipelines](https://docs.vizra.ai/tools/tool-pipelines) [Workflows](https://docs.vizra.ai/concepts/workflows) ⌘I --- # Evaluations - Vizra ADK [Skip to main content](https://docs.vizra.ai/testing/evaluations#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Testing & Observability Evaluations [Documentation](https://docs.vizra.ai/) On this page * [What Are Evaluations?](https://docs.vizra.ai/testing/evaluations#what-are-evaluations) * [Creating Your First Evaluation](https://docs.vizra.ai/testing/evaluations#creating-your-first-evaluation) * [Step 1: Generate the Evaluation Class](https://docs.vizra.ai/testing/evaluations#step-1-generate-the-evaluation-class) * [Step 2: Add Your Test Data](https://docs.vizra.ai/testing/evaluations#step-2-add-your-test-data) * [Your Assertion Toolbox](https://docs.vizra.ai/testing/evaluations#your-assertion-toolbox) * [Content Assertions](https://docs.vizra.ai/testing/evaluations#content-assertions) * [Length & Structure](https://docs.vizra.ai/testing/evaluations#length-%26-structure) * [Quality Checks](https://docs.vizra.ai/testing/evaluations#quality-checks) * [Safety & Security](https://docs.vizra.ai/testing/evaluations#safety-%26-security) * [LLM as Judge - The Ultimate Quality Check](https://docs.vizra.ai/testing/evaluations#llm-as-judge-the-ultimate-quality-check) * [Using LLM Judge Assertions](https://docs.vizra.ai/testing/evaluations#using-llm-judge-assertions) * [Three Judge Patterns](https://docs.vizra.ai/testing/evaluations#three-judge-patterns) * [Running Your Evaluations](https://docs.vizra.ai/testing/evaluations#running-your-evaluations) * [Running from CLI](https://docs.vizra.ai/testing/evaluations#running-from-cli) * [What You’ll See](https://docs.vizra.ai/testing/evaluations#what-you%E2%80%99ll-see) * [Advanced Example - Putting It All Together](https://docs.vizra.ai/testing/evaluations#advanced-example-putting-it-all-together) * [Analyzing Your Results](https://docs.vizra.ai/testing/evaluations#analyzing-your-results) * [CSV Output Structure](https://docs.vizra.ai/testing/evaluations#csv-output-structure) * [Creating Custom Assertions](https://docs.vizra.ai/testing/evaluations#creating-custom-assertions) * [Simple Example: Product Name Assertion](https://docs.vizra.ai/testing/evaluations#simple-example-product-name-assertion) * [Using Your Custom Assertion](https://docs.vizra.ai/testing/evaluations#using-your-custom-assertion) * [Generate Assertion Classes with Artisan](https://docs.vizra.ai/testing/evaluations#generate-assertion-classes-with-artisan) * [Built-in Custom Assertions](https://docs.vizra.ai/testing/evaluations#built-in-custom-assertions) * [CI/CD Integration](https://docs.vizra.ai/testing/evaluations#ci%2Fcd-integration) * [Best Practices for Awesome Evaluations](https://docs.vizra.ai/testing/evaluations#best-practices-for-awesome-evaluations) * [You’re Ready to Test Like a Pro!](https://docs.vizra.ai/testing/evaluations#you%E2%80%99re-ready-to-test-like-a-pro) **Why Testing Matters** - Just like you wouldn’t ship code without tests, don’t deploy AI agents without evaluations! **Evaluations give you confidence** that your agents will handle real-world scenarios gracefully, consistently, and professionally. [​](https://docs.vizra.ai/testing/evaluations#what-are-evaluations) What Are Evaluations? -------------------------------------------------------------------------------------------- Think of evaluations as **unit tests for your AI agents**! They help you: CSV-Based Testing ----------------- Define test cases in simple CSV files - no complex setup required! Automated Validation -------------------- Run hundreds of tests automatically with built-in assertions LLM-as-Judge ------------ Use AI to evaluate subjective qualities like helpfulness Result Tracking --------------- Export results to CSV for analysis and CI/CD integration [​](https://docs.vizra.ai/testing/evaluations#creating-your-first-evaluation) Creating Your First Evaluation --------------------------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/testing/evaluations#step-1-generate-the-evaluation-class) Step 1: Generate the Evaluation Class Let’s create an evaluation to test a customer support agent! Run this magical command: Terminal Copy php artisan vizra:make:eval CustomerSupportEvaluation **Double Magic! What Gets Created** - This single command creates **two files** for you: * `app/Evaluations/CustomerSupportEvaluation.php` - Your evaluation class * `app/Evaluations/data/customer_support_evaluation.csv` - Empty CSV with headers ready for test data No need to manually create the CSV file - it’s all set up and ready for you to add test cases! **Boom!** This creates your evaluation class in `app/Evaluations/CustomerSupportEvaluation.php`: app/Evaluations/CustomerSupportEvaluation.php Copy getPromptCsvColumn()] ?? ''; } public function evaluateRow(array $csvRowData, string $llmResponse): array { // Reset assertions for this row $this->resetAssertionResults(); // Run assertions based on test type if ($csvRowData['test_type'] === 'greeting') { $this->assertResponseContains($llmResponse, 'help'); $this->assertResponseHasPositiveSentiment($llmResponse); } // Return evaluation results $allPassed = collect($this->assertionResults) ->every(fn($r) => $r['status'] === 'pass'); return [\ 'row_data' => $csvRowData,\ 'llm_response' => $llmResponse,\ 'assertions' => $this->assertionResults,\ 'final_status' => $allPassed ? 'pass' : 'fail',\ ]; } } ### [​](https://docs.vizra.ai/testing/evaluations#step-2-add-your-test-data) Step 2: Add Your Test Data Now for the fun part - adding test scenarios! The CSV file was automatically created with standard headers. Let’s populate it with different customer interactions: app/Evaluations/data/customer\_support\_evaluation.csv Copy prompt,expected_response,description "Hello, I need help",help,"Greeting test - should offer assistance" "Where is my order #12345?",order,"Order inquiry - should help track order" "I want to return this product",return,"Return request - should explain process" "This is terrible service!",sorry,"Complaint - should be empathetic" **Pro Tip: Customize Your CSV Structure!** - The auto-generated CSV starts with standard headers, but you can customize it for your needs: * `prompt` - The input to send to your agent (required) * `expected_response` - What you expect in the response * `description` - Human-readable test description * `test_type` - Add this to categorize tests for different assertion logic * `context` - Add background information for the test * Add any custom columns you need! The command creates the basic structure - feel free to add more columns as your evaluation needs grow! [​](https://docs.vizra.ai/testing/evaluations#your-assertion-toolbox) Your Assertion Toolbox ----------------------------------------------------------------------------------------------- Vizra ADK provides a **rich collection of assertions** to validate every aspect of your agent’s responses! ### [​](https://docs.vizra.ai/testing/evaluations#content-assertions) Content Assertions Copy // Check if response contains text $this->assertResponseContains($llmResponse, 'expected text'); $this->assertResponseDoesNotContain($llmResponse, 'unwanted'); // Pattern matching $this->assertResponseMatchesRegex($llmResponse, '/pattern/'); // Position checks $this->assertResponseStartsWith($llmResponse, 'Hello'); $this->assertResponseEndsWith($llmResponse, '.'); // Multiple checks $this->assertContainsAnyOf($llmResponse, ['yes', 'sure', 'okay']); $this->assertContainsAllOf($llmResponse, ['thank', 'you']); ### [​](https://docs.vizra.ai/testing/evaluations#length-&-structure) Length & Structure Copy // Response length $this->assertResponseLengthBetween($llmResponse, 50, 500); // Word count $this->assertWordCountBetween($llmResponse, 10, 100); // Format validation $this->assertResponseIsValidJson($llmResponse); $this->assertJsonHasKey($llmResponse, 'result'); $this->assertResponseIsValidXml($llmResponse); ### [​](https://docs.vizra.ai/testing/evaluations#quality-checks) Quality Checks Copy // Sentiment analysis $this->assertResponseHasPositiveSentiment($llmResponse); // Writing quality $this->assertGrammarCorrect($llmResponse); $this->assertReadabilityLevel($llmResponse, 12); $this->assertNoRepetition($llmResponse, 0.3); ### [​](https://docs.vizra.ai/testing/evaluations#safety-&-security) Safety & Security Copy // Content safety $this->assertNotToxic($llmResponse); // Privacy protection $this->assertNoPII($llmResponse); // General safety $this->assertResponseIsNotEmpty($llmResponse); [​](https://docs.vizra.ai/testing/evaluations#llm-as-judge-the-ultimate-quality-check) LLM as Judge - The Ultimate Quality Check ----------------------------------------------------------------------------------------------------------------------------------- Sometimes you need another AI to evaluate subjective qualities. That’s where **LLM-as-Judge** comes in! **When to Use LLM Judge?** - Perfect for evaluating: * Helpfulness and professionalism * Empathy and emotional intelligence * Creativity and originality * Accuracy of complex responses * Overall response quality ### [​](https://docs.vizra.ai/testing/evaluations#using-llm-judge-assertions) Using LLM Judge Assertions **New Fluent Judge Interface!** - We’ve introduced a cleaner, more intuitive syntax for judge assertions: app/Evaluations/CustomerSupportEvaluation.php Copy public function evaluateRow(array $csvRowData, string $llmResponse): array { $this->resetAssertionResults(); // Simple pass/fail evaluation $this->judge($llmResponse) ->using(PassFailJudgeAgent::class) ->expectPass(); // Quality score evaluation $this->judge($llmResponse) ->using(QualityJudgeAgent::class) ->expectMinimumScore(7.5); // Multi-dimensional evaluation $this->judge($llmResponse) ->using(ComprehensiveJudgeAgent::class) ->expectMinimumScore([\ 'accuracy' => 8,\ 'helpfulness' => 7,\ 'clarity' => 7\ ]); // Return results... } ### [​](https://docs.vizra.ai/testing/evaluations#three-judge-patterns) Three Judge Patterns **1\. Pass/Fail Judge** For binary decisions - returns `{"pass": true/false, "reasoning": "..."}` Copy $this->judge($response) ->using(PassFailJudgeAgent::class) ->expectPass(); **2\. Quality Score Judge** For numeric ratings - returns `{"score": 8.5, "reasoning": "..."}` Copy $this->judge($response) ->using(QualityJudgeAgent::class) ->expectMinimumScore(7.0); **3\. Comprehensive Judge** For multi-dimensional evaluation - returns `{"scores": {...}, "reasoning": "..."}` Copy $this->judge($response) ->using(ComprehensiveJudgeAgent::class) ->expectMinimumScore([\ 'accuracy' => 8,\ 'helpfulness' => 7,\ 'clarity' => 7\ ]); [​](https://docs.vizra.ai/testing/evaluations#running-your-evaluations) Running Your Evaluations --------------------------------------------------------------------------------------------------- Time to put your agent to the test! Let’s see how it performs! ### [​](https://docs.vizra.ai/testing/evaluations#running-from-cli) Running from CLI Terminal Copy # Run evaluation by class name php artisan vizra:run:eval CustomerSupportEvaluation # Save results to CSV for analysis php artisan vizra:run:eval CustomerSupportEvaluation --output=results.csv # Results are saved to storage/app/evaluations/ by default ### [​](https://docs.vizra.ai/testing/evaluations#what-you%E2%80%99ll-see) What You’ll See Watch the magic happen with a beautiful progress bar and detailed results! Console Output Copy Running evaluation: customer_support_eval Description: Evaluate customer support agent responses Processing 4 rows from CSV using agent 'customer_support'... ████████████████████████████████████████ 4/4 Evaluation processing complete. ┌─────┬──────────────┬──────────────────────────┬─────────────────┬───────┐ │ Row │ Final Status │ LLM Response Summary │ Assertions Count│ Error │ ├─────┼──────────────┼──────────────────────────┼─────────────────┼───────┤ │ 1 │ ✅ pass │ Hello! I'd be happy to...│ 2 │ │ │ 2 │ ✅ pass │ I can help you track... │ 1 │ │ │ 3 │ ❌ fail │ Sure, let me assist... │ 2 │ │ │ 4 │ ✅ pass │ I understand your... │ 3 │ │ └─────┴──────────────┴──────────────────────────┴─────────────────┴───────┘ Summary: Total Rows: 4, Passed: 3 (75%), Failed: 1 (25%), Errors: 0 [​](https://docs.vizra.ai/testing/evaluations#advanced-example-putting-it-all-together) Advanced Example - Putting It All Together ------------------------------------------------------------------------------------------------------------------------------------- Ready for the full experience? Here’s a **complete evaluation implementation** that showcases all the techniques! app/Evaluations/CustomerSupportEvaluation.php Copy getPromptCsvColumn()] ?? ''; // Add context if available if (isset($csvRowData['context'])) { $prompt = "Context: " . $csvRowData['context'] . "\n\n" . $prompt; } return $prompt; } public function evaluateRow(array $csvRowData, string $llmResponse): array { $this->resetAssertionResults(); // Basic content checks if (isset($csvRowData['expected_contains'])) { $this->assertResponseContains( $llmResponse, $csvRowData['expected_contains'] ); } // Test type specific assertions switch ($csvRowData['test_type'] ?? '') { case 'greeting': $this->assertResponseHasPositiveSentiment($llmResponse); $this->assertWordCountBetween($llmResponse, 10, 50); break; case 'complaint': $this->assertResponseContains($llmResponse, 'sorry'); $this->assertNotToxic($llmResponse); $this->assertLlmJudge( $llmResponse, 'Is this response empathetic and de-escalating?', 'llm_judge', 'pass' ); break; case 'technical': $this->assertReadabilityLevel($llmResponse, 12); $this->assertGrammarCorrect($llmResponse); break; } // General quality checks $this->assertResponseIsNotEmpty($llmResponse); $this->assertNoPII($llmResponse); // Determine final status $allPassed = collect($this->assertionResults) ->every(fn($r) => $r['status'] === 'pass'); return [\ 'row_data' => $csvRowData,\ 'llm_response' => $llmResponse,\ 'assertions' => $this->assertionResults,\ 'final_status' => $allPassed ? 'pass' : 'fail',\ ]; } } [​](https://docs.vizra.ai/testing/evaluations#analyzing-your-results) Analyzing Your Results ----------------------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/testing/evaluations#csv-output-structure) CSV Output Structure When you export results with `--output`, you get a comprehensive CSV report! **CSV Columns Explained:** * **Evaluation Name** - The name of your evaluation * **Row Index** - Which test case from your CSV * **Final Status** - pass, fail, or error * **LLM Response** - What your agent actually said * **Assertions (JSON)** - Detailed results of each check [​](https://docs.vizra.ai/testing/evaluations#creating-custom-assertions) Creating Custom Assertions ------------------------------------------------------------------------------------------------------- Need something specific? Create your own reusable assertion classes! ### [​](https://docs.vizra.ai/testing/evaluations#simple-example-product-name-assertion) Simple Example: Product Name Assertion Let’s create a simple assertion that checks if a product name is mentioned: app/Evaluations/Assertions/ContainsProductAssertion.php Copy result(false, 'Product name parameter is required'); } $contains = stripos($response, $productName) !== false; return $this->result( $contains, "Response should mention the product '{$productName}'", "contains '{$productName}'", $contains ? "found '{$productName}'" : "product not mentioned" ); } } ### [​](https://docs.vizra.ai/testing/evaluations#using-your-custom-assertion) Using Your Custom Assertion app/Evaluations/ProductReviewEvaluation.php Copy use App\Evaluations\Assertions\ContainsProductAssertion; class ProductReviewEvaluation extends BaseEvaluation { private ContainsProductAssertion $productAssertion; public function __construct() { parent::__construct(); $this->productAssertion = new ContainsProductAssertion(); } public function evaluateRow(array $csvRowData, string $llmResponse): array { $this->resetAssertionResults(); // Use your custom assertion $this->assertCustom(ContainsProductAssertion::class, $llmResponse, 'MacBook Pro'); // Mix with built-in assertions $this->assertWordCountBetween($llmResponse, 50, 200); // Determine final status $allPassed = collect($this->assertionResults) ->every(fn($r) => $r['status'] === 'pass'); return [\ 'assertions' => $this->assertionResults,\ 'final_status' => $allPassed ? 'pass' : 'fail',\ ]; } } **Pro Tip: CSV-Driven Custom Assertions!** - You can even specify custom assertions in your CSV files: Copy prompt,assertion_class,assertion_params "Tell me about the new iPhone",ContainsProductAssertion,"[\"iPhone\"]" "Describe the MacBook features",ContainsProductAssertion,"[\"MacBook\"]" Then use them dynamically in your evaluation: Copy if (isset($csvRowData['assertion_class'])) { $params = json_decode($csvRowData['assertion_params'] ?? '[]', true); $this->assertCustom($csvRowData['assertion_class'], $llmResponse, ...$params); } ### [​](https://docs.vizra.ai/testing/evaluations#generate-assertion-classes-with-artisan) Generate Assertion Classes with Artisan Creating new assertions is super easy with our generator command! Terminal Copy php artisan vizra:make:assertion EmailValidationAssertion This creates a ready-to-use assertion class with helpful boilerplate! ### [​](https://docs.vizra.ai/testing/evaluations#built-in-custom-assertions) Built-in Custom Assertions Vizra ADK comes with several ready-to-use custom assertions: ContainsProductAssertion ------------------------ Check if a product name is mentioned JsonSchemaAssertion ------------------- Validate JSON structure against a schema PriceFormatAssertion -------------------- Verify price formatting in any currency EmailFormatAssertion -------------------- Check for valid email addresses [​](https://docs.vizra.ai/testing/evaluations#ci/cd-integration) CI/CD Integration ------------------------------------------------------------------------------------- Make testing automatic! Here’s how to add evaluations to your CI/CD pipeline! .github/workflows/evaluate.yml Copy # Evaluate agents on every push name: Evaluate Agents on: [push, pull_request] jobs: evaluate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Setup PHP & Dependencies uses: shivammathur/setup-php@v2 with: php-version: '8.2' - name: Install Dependencies run: composer install - name: Run Evaluations env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} run: | php artisan vizra:run:eval CustomerSupportEvaluation --output=results.csv - name: Check Results run: | # Add your own pass/fail logic based on CSV results php artisan app:check-eval-results storage/app/evaluations/results.csv - name: Upload Results uses: actions/upload-artifact@v2 with: name: evaluation-results path: storage/app/evaluations/ [​](https://docs.vizra.ai/testing/evaluations#best-practices-for-awesome-evaluations) Best Practices for Awesome Evaluations ------------------------------------------------------------------------------------------------------------------------------- Organization ------------ * **CSV Organization** - Use clear test types and descriptive columns * **Thorough Testing** - Combine multiple assertion types * **LLM Judge** - Use for subjective quality checks * **CI/CD Integration** - Run evaluations on every push Quality ------- * **Track Progress** - Monitor performance over time * **Real Data** - Include actual user queries * **Edge Cases** - Test error scenarios too * **Consistency** - Use the same criteria across agents * * * [​](https://docs.vizra.ai/testing/evaluations#you%E2%80%99re-ready-to-test-like-a-pro) You’re Ready to Test Like a Pro! -------------------------------------------------------------------------------------------------------------------------- With evaluations, you can ship AI agents with confidence! Your agents will be tested, validated, and ready for real-world challenges. Happy testing! [Next: Tracing\ -------------\ \ Learn about debugging with traces](https://docs.vizra.ai/concepts/tracing) [Evaluation API Reference\ ------------------------\ \ Detailed evaluation class documentation](https://docs.vizra.ai/api/evaluation-class) Was this page helpful? YesNo [Laravel Boost Integration](https://docs.vizra.ai/integrations/laravel-boost) [Tracing](https://docs.vizra.ai/testing/tracing) ⌘I --- # Tool Pipelines - Vizra ADK [Skip to main content](https://docs.vizra.ai/tools/tool-pipelines#content-area) [Vizra ADK home page![light logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)![dark logo](https://mintcdn.com/vizra-0d76d98a/T5c9SAAJJAnuxzCU/images/logo.svg?fit=max&auto=format&n=T5c9SAAJJAnuxzCU&q=85&s=6681bd5ed6d6b379ca0f4a4b36cdca6e)](https://vizra.ai/) Search... ⌘K Search... Navigation Tools Tool Pipelines [Documentation](https://docs.vizra.ai/) On this page * [What Are Tool Pipelines?](https://docs.vizra.ai/tools/tool-pipelines#what-are-tool-pipelines) * [Using Pipelines in Agents](https://docs.vizra.ai/tools/tool-pipelines#using-pipelines-in-agents) * [Composite Tool Pattern](https://docs.vizra.ai/tools/tool-pipelines#composite-tool-pattern) * [Pipeline in Agent Methods](https://docs.vizra.ai/tools/tool-pipelines#pipeline-in-agent-methods) * [Creating Your First Pipeline](https://docs.vizra.ai/tools/tool-pipelines#creating-your-first-pipeline) * [Named Pipelines](https://docs.vizra.ai/tools/tool-pipelines#named-pipelines) * [Step Types](https://docs.vizra.ai/tools/tool-pipelines#step-types) * [pipe() - Execute Tools](https://docs.vizra.ai/tools/tool-pipelines#pipe-execute-tools) * [transform() - Transform Data](https://docs.vizra.ai/tools/tool-pipelines#transform-transform-data) * [when() - Conditional Execution](https://docs.vizra.ai/tools/tool-pipelines#when-conditional-execution) * [tap() - Side Effects](https://docs.vizra.ai/tools/tool-pipelines#tap-side-effects) * [Argument Mappers](https://docs.vizra.ai/tools/tool-pipelines#argument-mappers) * [Error Handling](https://docs.vizra.ai/tools/tool-pipelines#error-handling) * [Default Behavior (Stop on Error)](https://docs.vizra.ai/tools/tool-pipelines#default-behavior-stop-on-error) * [Continue on Error](https://docs.vizra.ai/tools/tool-pipelines#continue-on-error) * [Throwing Errors](https://docs.vizra.ai/tools/tool-pipelines#throwing-errors) * [Lifecycle Callbacks](https://docs.vizra.ai/tools/tool-pipelines#lifecycle-callbacks) * [Working with Results](https://docs.vizra.ai/tools/tool-pipelines#working-with-results) * [Basic Result Access](https://docs.vizra.ai/tools/tool-pipelines#basic-result-access) * [Step-by-Step Results](https://docs.vizra.ai/tools/tool-pipelines#step-by-step-results) * [Timing Information](https://docs.vizra.ai/tools/tool-pipelines#timing-information) * [Export Results](https://docs.vizra.ai/tools/tool-pipelines#export-results) * [Chainable Tools](https://docs.vizra.ai/tools/tool-pipelines#chainable-tools) * [The ChainableToolInterface](https://docs.vizra.ai/tools/tool-pipelines#the-chainabletoolinterface) * [Using the ChainableTool Trait](https://docs.vizra.ai/tools/tool-pipelines#using-the-chainabletool-trait) * [Real-World Example](https://docs.vizra.ai/tools/tool-pipelines#real-world-example) * [Best Practices](https://docs.vizra.ai/tools/tool-pipelines#best-practices) * [API Reference](https://docs.vizra.ai/tools/tool-pipelines#api-reference) * [ToolChain Methods](https://docs.vizra.ai/tools/tool-pipelines#toolchain-methods) * [ToolChainResult Methods](https://docs.vizra.ai/tools/tool-pipelines#toolchainresult-methods) * [Callback Signatures](https://docs.vizra.ai/tools/tool-pipelines#callback-signatures) [​](https://docs.vizra.ai/tools/tool-pipelines#what-are-tool-pipelines) What Are Tool Pipelines? --------------------------------------------------------------------------------------------------- Tool Pipelines let you compose multiple tools into a sequential workflow where the output of one tool flows into the next. Think of it like Unix pipes for your AI tools - powerful, composable, and elegant! Sequential Execution -------------------- Tools execute in order, each building on the previous result Data Transformation ------------------- Transform data between steps with custom mappers Conditional Logic ----------------- Skip steps or branch based on intermediate results Built-in Tracing ---------------- Automatic tracing for debugging and monitoring [​](https://docs.vizra.ai/tools/tool-pipelines#using-pipelines-in-agents) Using Pipelines in Agents ------------------------------------------------------------------------------------------------------ The most common way to use pipelines is within a tool that orchestrates other tools. This “composite tool” pattern lets you expose a single capability to your agent while handling complex multi-step logic internally. ### [​](https://docs.vizra.ai/tools/tool-pipelines#composite-tool-pattern) Composite Tool Pattern Create a tool that chains multiple tools together: app/Tools/ProcessOrderTool.php Copy 'process_order',\ 'description' => 'Validates, charges, and fulfills an order in one step',\ 'parameters' => [\ 'type' => 'object',\ 'properties' => [\ 'order_id' => [\ 'type' => 'string',\ 'description' => 'The order ID to process',\ ],\ ],\ 'required' => ['order_id'],\ ],\ ]; } public function execute(array $arguments, AgentContext $context, AgentMemory $memory): string { $result = ToolChain::create('process-order') ->pipe(ValidateOrderTool::class) ->transform(fn($result) => json_decode($result, true)) ->when(fn($data) => $data['valid'] === true) ->pipe(ChargePaymentTool::class) ->transform(fn($result) => json_decode($result, true)) ->pipe(FulfillOrderTool::class) ->execute($arguments, $context, $memory); if ($result->failed()) { return json_encode([\ 'status' => 'error',\ 'message' => $result->getFirstError()?->getMessage(),\ ]); } return json_encode([\ 'status' => 'success',\ 'result' => $result->value(),\ ]); } } Then add it to your agent like any other tool: app/Agents/OrderAgent.php Copy class OrderAgent extends BaseLlmAgent { protected string $name = 'order_agent'; protected string $description = 'Handles order operations'; protected array $tools = [\ ProcessOrderTool::class, // The pipeline runs when the LLM calls this tool\ CheckOrderStatusTool::class,\ RefundOrderTool::class,\ ]; } The composite tool pattern keeps your agent’s tool list clean while hiding complex orchestration logic. The LLM sees one simple tool, but behind the scenes a full pipeline executes. ### [​](https://docs.vizra.ai/tools/tool-pipelines#pipeline-in-agent-methods) Pipeline in Agent Methods You can also use pipelines directly in custom agent methods: app/Agents/OnboardingAgent.php Copy pipe(CreateUserTool::class) ->transform(fn($result) => json_decode($result, true)) ->pipe(SetupDefaultsTool::class) ->pipe(SendWelcomeEmailTool::class) ->tap(fn($result) => $this->memory->addFact("Onboarded user: {$email}")) ->execute( ['email' => $email], $this->context, $this->memory ); return $result->toArray(); } } [​](https://docs.vizra.ai/tools/tool-pipelines#creating-your-first-pipeline) Creating Your First Pipeline ------------------------------------------------------------------------------------------------------------ Pipelines are created using the `ToolChain` class. Here’s a simple example: Basic Pipeline Copy use Vizra\VizraADK\Tools\Chaining\ToolChain; $result = ToolChain::create() ->pipe(FetchUserTool::class) ->pipe(EnrichUserTool::class) ->pipe(ValidateUserTool::class) ->execute(['user_id' => 123], $context, $memory); // Access the final result $userData = $result->value(); ### [​](https://docs.vizra.ai/tools/tool-pipelines#named-pipelines) Named Pipelines Give your pipeline a name for better debugging and tracing: Named Pipeline Copy $result = ToolChain::create('user-onboarding') ->pipe(CreateUserTool::class) ->pipe(SendWelcomeEmailTool::class) ->pipe(SetupDefaultsTool::class) ->execute(['email' => 'user@example.com'], $context, $memory); // The name appears in traces and error messages echo $result->getChainName(); // "user-onboarding" [​](https://docs.vizra.ai/tools/tool-pipelines#step-types) Step Types ------------------------------------------------------------------------ Pipelines support four types of steps, each serving a specific purpose. ### [​](https://docs.vizra.ai/tools/tool-pipelines#pipe-execute-tools) pipe() - Execute Tools The `pipe()` method adds a tool to the pipeline. Each tool receives the output from the previous step: Using pipe() Copy ToolChain::create() ->pipe(FetchOrderTool::class) ->pipe(CalculateTaxTool::class) ->pipe(ProcessPaymentTool::class) ->execute(['order_id' => 'ORD-123'], $context, $memory); You can pass a tool class name or an instance: Tool Instance Copy $customTool = new MyTool($dependency); ToolChain::create() ->pipe($customTool) ->pipe(AnotherTool::class) ->execute($args, $context, $memory); ### [​](https://docs.vizra.ai/tools/tool-pipelines#transform-transform-data) transform() - Transform Data Use `transform()` to modify data between tools without executing a full tool: Using transform() Copy ToolChain::create() ->pipe(FetchUserTool::class) ->transform(fn($result) => json_decode($result, true)) ->transform(fn($data) => [\ 'user_id' => $data['id'],\ 'full_name' => $data['first_name'] . ' ' . $data['last_name'],\ ]) ->pipe(CreateProfileTool::class) ->execute(['user_id' => 123], $context, $memory); Transforms are perfect for reshaping data, extracting specific fields, or converting between formats. ### [​](https://docs.vizra.ai/tools/tool-pipelines#when-conditional-execution) when() - Conditional Execution Add conditional logic to your pipeline with `when()`. If the condition returns `false`, remaining steps are skipped: Using when() Copy ToolChain::create() ->pipe(FetchUserTool::class) ->transform(fn($result) => json_decode($result, true)) ->when(fn($user) => $user['is_premium'] === true) ->pipe(ApplyPremiumDiscountTool::class) ->pipe(SendPremiumEmailTool::class) ->execute(['user_id' => 123], $context, $memory); You can provide an `otherwise` callback for when the condition is false: Conditional with Otherwise Copy ToolChain::create() ->pipe(CheckInventoryTool::class) ->transform(fn($result) => json_decode($result, true)) ->when( condition: fn($inventory) => $inventory['available'] > 0, otherwise: fn($inventory) => [\ 'status' => 'out_of_stock',\ 'message' => 'Item is currently unavailable',\ ] ) ->pipe(ProcessOrderTool::class) ->execute(['product_id' => 'SKU-456'], $context, $memory); ### [​](https://docs.vizra.ai/tools/tool-pipelines#tap-side-effects) tap() - Side Effects The `tap()` method executes a callback without modifying the result. Use it for logging, debugging, or triggering side effects: Using tap() Copy ToolChain::create() ->pipe(FetchOrderTool::class) ->tap(fn($result, $index) => Log::info("Step {$index} completed", [\ 'result' => $result,\ ])) ->pipe(ProcessOrderTool::class) ->tap(fn($result, $index) => event(new OrderProcessed($result))) ->execute(['order_id' => 'ORD-123'], $context, $memory); The tap callback receives the current result and step index. The return value is ignored - the pipeline continues with the unchanged result. [​](https://docs.vizra.ai/tools/tool-pipelines#argument-mappers) Argument Mappers ------------------------------------------------------------------------------------ When tools need different argument structures, use argument mappers to transform the previous output: Custom Argument Mapping Copy ToolChain::create() ->pipe(FetchUserTool::class) ->transform(fn($result) => json_decode($result, true)) ->pipe( EnrichUserTool::class, fn($user, $initialArgs) => [\ 'user_id' => $user['id'],\ 'include_history' => true,\ ] ) ->pipe( SendNotificationTool::class, fn($enrichedUser, $initialArgs) => [\ 'recipient' => $enrichedUser['email'],\ 'template' => 'welcome',\ ] ) ->execute(['user_id' => 123], $context, $memory); The argument mapper receives two parameters: * `$previousResult` - The output from the previous step * `$initialArgs` - The original arguments passed to `execute()` [​](https://docs.vizra.ai/tools/tool-pipelines#error-handling) Error Handling -------------------------------------------------------------------------------- ### [​](https://docs.vizra.ai/tools/tool-pipelines#default-behavior-stop-on-error) Default Behavior (Stop on Error) By default, pipelines stop execution when a step throws an exception: Default Error Behavior Copy $result = ToolChain::create() ->pipe(FetchDataTool::class) ->pipe(ProcessDataTool::class) // If this fails... ->pipe(SaveDataTool::class) // ...this won't run ->execute($args, $context, $memory); if ($result->failed()) { $error = $result->getFirstError(); Log::error('Pipeline failed', ['error' => $error->getMessage()]); } ### [​](https://docs.vizra.ai/tools/tool-pipelines#continue-on-error) Continue on Error Use `continueOnError()` to keep the pipeline running even when steps fail: Continue on Error Copy $result = ToolChain::create() ->continueOnError() ->pipe(SendEmailTool::class) // Might fail ->pipe(SendSmsTool::class) // Continues anyway ->pipe(SendPushTool::class) // Continues anyway ->execute(['user_id' => 123], $context, $memory); // Check what failed if ($result->hasErrors()) { foreach ($result->getErrors() as $index => $errorInfo) { Log::warning("Step {$index} failed", [\ 'step' => $errorInfo['step']->describe(),\ 'error' => $errorInfo['error']->getMessage(),\ ]); } } ### [​](https://docs.vizra.ai/tools/tool-pipelines#throwing-errors) Throwing Errors Use `throw()` or `valueOrThrow()` for exception-based error handling: Throwing Errors Copy // Option 1: Throw if failed $result = ToolChain::create() ->pipe(CriticalOperationTool::class) ->execute($args, $context, $memory); $result->throw(); // Throws the first error if failed // Option 2: Get value or throw $value = ToolChain::create() ->pipe(ImportantTool::class) ->execute($args, $context, $memory) ->valueOrThrow(); // Returns value or throws [​](https://docs.vizra.ai/tools/tool-pipelines#lifecycle-callbacks) Lifecycle Callbacks ------------------------------------------------------------------------------------------ Hook into the pipeline execution with before and after callbacks: Lifecycle Callbacks Copy ToolChain::create('order-processing') ->beforeEachStep(function (ToolChainStep $step, int $index, mixed $currentValue) { Log::debug("Starting step {$index}", [\ 'step' => $step->describe(),\ 'input' => $currentValue,\ ]); }) ->afterEachStep(function (ToolChainStep $step, int $index, mixed $result) { Log::debug("Completed step {$index}", [\ 'step' => $step->describe(),\ 'output' => $result,\ ]); }) ->pipe(ValidateOrderTool::class) ->pipe(ProcessPaymentTool::class) ->pipe(FulfillOrderTool::class) ->execute(['order_id' => 'ORD-123'], $context, $memory); [​](https://docs.vizra.ai/tools/tool-pipelines#working-with-results) Working with Results -------------------------------------------------------------------------------------------- The `ToolChainResult` class provides rich access to execution details. ### [​](https://docs.vizra.ai/tools/tool-pipelines#basic-result-access) Basic Result Access Accessing Results Copy $result = ToolChain::create() ->pipe(MyTool::class) ->execute($args, $context, $memory); // Get the final value $value = $result->value(); // or $value = $result->getFinalValue(); // Check status if ($result->successful()) { // All steps completed without errors } if ($result->failed()) { // At least one step threw an exception } ### [​](https://docs.vizra.ai/tools/tool-pipelines#step-by-step-results) Step-by-Step Results Inspecting Steps Copy $result = ToolChain::create() ->pipe(Step1Tool::class) ->pipe(Step2Tool::class) ->pipe(Step3Tool::class) ->execute($args, $context, $memory); // Get all step results $allSteps = $result->getStepResults(); // Get a specific step's result (0-indexed) $step2Result = $result->getStepResult(1); $step2Value = $result->getStepValue(1); // Count executed vs skipped steps echo "Executed: " . $result->getExecutedStepCount(); echo "Skipped: " . $result->getSkippedStepCount(); ### [​](https://docs.vizra.ai/tools/tool-pipelines#timing-information) Timing Information Timing Data Copy $result = ToolChain::create() ->pipe(SlowTool::class) ->execute($args, $context, $memory); // Total execution time echo $result->getDuration() . " seconds"; echo $result->getDurationMs() . " milliseconds"; ### [​](https://docs.vizra.ai/tools/tool-pipelines#export-results) Export Results Exporting Results Copy $result = ToolChain::create('my-pipeline') ->pipe(MyTool::class) ->execute($args, $context, $memory); // As array $data = $result->toArray(); // Returns: [\ // 'chain_name' => 'my-pipeline',\ // 'successful' => true,\ // 'final_value' => ...,\ // 'duration_ms' => 150.5,\ // 'executed_steps' => 1,\ // 'skipped_steps' => 0,\ // 'errors' => [],\ // 'steps' => [...],\ // ] // As JSON $json = $result->toJson(JSON_PRETTY_PRINT); [​](https://docs.vizra.ai/tools/tool-pipelines#chainable-tools) Chainable Tools ---------------------------------------------------------------------------------- While any tool implementing `ToolInterface` works in pipelines, you can create tools specifically designed for chaining by implementing `ChainableToolInterface`. ### [​](https://docs.vizra.ai/tools/tool-pipelines#the-chainabletoolinterface) The ChainableToolInterface app/Tools/ChainableUserFetchTool.php Copy 'fetch_user',\ 'description' => 'Fetch user data by ID',\ 'parameters' => [\ 'type' => 'object',\ 'properties' => [\ 'user_id' => [\ 'type' => 'integer',\ 'description' => 'The user ID to fetch',\ ],\ ],\ 'required' => ['user_id'],\ ],\ ]; } public function execute(array $arguments, AgentContext $context, AgentMemory $memory): string { $user = User::find($arguments['user_id']); return json_encode([\ 'id' => $user->id,\ 'name' => $user->name,\ 'email' => $user->email,\ ]); } /** * Describe the expected input when used in a chain. */ public function getInputSchema(): array { return [\ 'type' => 'object',\ 'properties' => [\ 'user_id' => ['type' => 'integer'],\ ],\ 'required' => ['user_id'],\ ]; } /** * Describe the output format. */ public function getOutputSchema(): array { return [\ 'type' => 'object',\ 'properties' => [\ 'id' => ['type' => 'integer'],\ 'name' => ['type' => 'string'],\ 'email' => ['type' => 'string'],\ ],\ ]; } /** * Transform raw JSON output for the next tool. */ public function transformOutputForChain(string $rawOutput): mixed { return json_decode($rawOutput, true); } /** * Accept input from the previous tool. */ public function acceptChainInput(mixed $previousOutput, array $initialArguments): array { // Merge previous output with initial args if (is_array($previousOutput)) { return array_merge($initialArguments, $previousOutput); } return $initialArguments; } } ### [​](https://docs.vizra.ai/tools/tool-pipelines#using-the-chainabletool-trait) Using the ChainableTool Trait For simpler cases, use the `ChainableTool` trait for sensible defaults: app/Tools/SimpleChainableTool.php Copy 'simple_tool',\ 'description' => 'A simple chainable tool',\ 'parameters' => [\ 'type' => 'object',\ 'properties' => [\ 'input' => ['type' => 'string'],\ ],\ ],\ ]; } public function execute(array $arguments, AgentContext $context, AgentMemory $memory): string { return json_encode(['processed' => true, 'data' => $arguments['input']]); } // Override specific methods as needed public function getOutputSchema(): array { return [\ 'type' => 'object',\ 'properties' => [\ 'processed' => ['type' => 'boolean'],\ 'data' => ['type' => 'string'],\ ],\ ]; } } The `ChainableTool` trait provides these defaults: * `getInputSchema()` - Returns `['type' => 'object']` * `getOutputSchema()` - Returns `['type' => 'string']` * `transformOutputForChain()` - Auto JSON decodes or returns raw string * `acceptChainInput()` - Merges previous output with initial arguments [​](https://docs.vizra.ai/tools/tool-pipelines#real-world-example) Real-World Example ---------------------------------------------------------------------------------------- Here’s a complete example of an order processing pipeline: app/Services/OrderPipeline.php Copy beforeEachStep(fn($step, $i, $val) => Log::info("Order {$orderId}: Starting {$step->describe()}") ) // Validate the order ->pipe(ValidateOrderTool::class) ->transform(fn($result) => json_decode($result, true)) // Check inventory - skip if validation failed ->when(fn($order) => $order['valid'] === true) ->pipe(CheckInventoryTool::class) ->transform(fn($result) => json_decode($result, true)) // Only apply discounts if inventory is available ->when( condition: fn($data) => $data['in_stock'] === true, otherwise: fn($data) => array_merge($data, [\ 'status' => 'failed',\ 'reason' => 'out_of_stock',\ ]) ) ->pipe( ApplyDiscountsTool::class, fn($data, $initial) => [\ 'order_id' => $initial['order_id'],\ 'subtotal' => $data['subtotal'],\ ] ) ->transform(fn($result) => json_decode($result, true)) // Process payment ->pipe( ProcessPaymentTool::class, fn($data, $initial) => [\ 'order_id' => $initial['order_id'],\ 'amount' => $data['final_total'],\ ] ) ->transform(fn($result) => json_decode($result, true)) // Fulfill order - log the outcome ->pipe(FulfillOrderTool::class) ->tap(fn($result) => Log::info("Order {$orderId} fulfilled", [\ 'result' => $result,\ ])) // Send confirmation (continue even if this fails) ->pipe(SendConfirmationTool::class) ->execute(['order_id' => $orderId], $context, $memory); if ($result->failed()) { Log::error("Order {$orderId} pipeline failed", [\ 'error' => $result->getFirstError()?->getMessage(),\ 'duration_ms' => $result->getDurationMs(),\ ]); return [\ 'success' => false,\ 'error' => $result->getFirstError()?->getMessage(),\ ]; } return [\ 'success' => true,\ 'result' => $result->value(),\ 'duration_ms' => $result->getDurationMs(),\ 'steps_executed' => $result->getExecutedStepCount(),\ ]; } } [​](https://docs.vizra.ai/tools/tool-pipelines#best-practices) Best Practices -------------------------------------------------------------------------------- Name Your Pipelines ------------------- Always use `ToolChain::create('name')` for easier debugging and tracing Transform Early --------------- Parse JSON responses with `transform()` immediately after tools for cleaner data flow Use Argument Mappers -------------------- When tools have different argument structures, use argument mappers rather than modifying tools Handle Errors Gracefully ------------------------ Check `$result->failed()` and handle errors appropriately **Avoid side effects in transforms** - Use `tap()` for logging, metrics, or events. Keep `transform()` pure for data transformation only. [​](https://docs.vizra.ai/tools/tool-pipelines#api-reference) API Reference ------------------------------------------------------------------------------ ### [​](https://docs.vizra.ai/tools/tool-pipelines#toolchain-methods) ToolChain Methods | Method | Description | | --- | --- | | `create(?string $name)` | Create a new pipeline, optionally named | | `pipe(string\|ToolInterface $tool, ?Closure $mapper)` | Add a tool step | | `transform(Closure $fn)` | Add a data transformation step | | `when(Closure $condition, ?Closure $otherwise)` | Add conditional logic | | `tap(Closure $callback)` | Add a side-effect step | | `stopOnError(bool $stop = true)` | Stop pipeline on first error (default) | | `continueOnError()` | Continue execution even if steps fail | | `beforeEachStep(Closure $callback)` | Hook before each step | | `afterEachStep(Closure $callback)` | Hook after each step | | `execute(array $args, AgentContext $context, AgentMemory $memory)` | Run the pipeline | | `getSteps()` | Get all pipeline steps | | `getName()` | Get pipeline name | | `isEmpty()` | Check if pipeline has no steps | | `count()` | Get number of steps | ### [​](https://docs.vizra.ai/tools/tool-pipelines#toolchainresult-methods) ToolChainResult Methods | Method | Description | | --- | --- | | `value()` / `getFinalValue()` | Get the final output value | | `successful()` / `failed()` | Check execution status | | `hasErrors()` | Check if any errors occurred | | `getErrors()` | Get all errors with step info | | `getFirstError()` | Get the first Throwable | | `getStepResults()` | Get all step results | | `getStepResult(int $index)` | Get a specific step’s result | | `getStepValue(int $index)` | Get a specific step’s value | | `getDuration()` | Get total duration in seconds | | `getDurationMs()` | Get total duration in milliseconds | | `getExecutedStepCount()` | Count of executed steps | | `getSkippedStepCount()` | Count of skipped steps | | `getChainName()` | Get the pipeline name | | `toArray()` | Export as array | | `toJson(int $options)` | Export as JSON | | `throw()` | Throw first error if failed | | `valueOrThrow()` | Get value or throw on failure | ### [​](https://docs.vizra.ai/tools/tool-pipelines#callback-signatures) Callback Signatures | Callback | Signature | | --- | --- | | Argument Mapper | `fn(mixed $previousResult, array $initialArgs): array` | | Transformer | `fn(mixed $previousResult): mixed` | | Condition | `fn(mixed $previousResult): bool` | | Otherwise | `fn(mixed $currentValue): mixed` | | Tap Callback | `fn(mixed $currentResult, int $stepIndex): void` | | Before Step | `fn(ToolChainStep $step, int $index, mixed $currentValue): void` | | After Step | `fn(ToolChainStep $step, int $index, mixed $result): void` | * * * [Tools\ -----\ \ Learn the basics of creating tools](https://docs.vizra.ai/concepts/tools) [Tracing\ -------\ \ Debug pipelines with execution traces](https://docs.vizra.ai/testing/tracing) Was this page helpful? YesNo [Toolbox](https://docs.vizra.ai/tools/toolbox) [Structured Output](https://docs.vizra.ai/tools/structured-output) ⌘I ---