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
Supported Classes
The following Vizra ADK classes support macros:
Class Access Description AgentManagerAgent facadeCentral agent management AgentBuilderFluent builder Agent configuration and registration WorkflowManagerWorkflow facadeWorkflow orchestration
Basic Usage
Registering a Macro
Register macros in your AppServiceProvider::boot() method:
app/Providers/AppServiceProvider.php
<? php
namespace App\Providers ;
use Vizra\VizraADK\Services\ AgentBuilder ;
use Vizra\VizraADK\Facades\ Agent ;
use Illuminate\Database\Eloquent\ Model ;
use Illuminate\Support\ ServiceProvider ;
class AppServiceProvider extends ServiceProvider
{
public function boot () : void
{
// Add a tracking macro for analytics
AgentBuilder :: macro ( 'track' , function ( Model $model ) {
$this -> trackedModel = $model ;
return $this ; // Return $this for method chaining
});
}
}
Using Your Macro
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.
Real-World Examples
Analytics Tracking
Track which models are using AI features:
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 ();
Conditional Execution
Add conditional logic to your builder:
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 ();
Add metadata for logging or debugging:
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 ();
Cost Tracking
Track estimated costs for budget monitoring:
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 ();
Using Mixins
Mixins allow you to add multiple macros at once by grouping related functionality in a class:
app/Mixins/AnalyticsMixin.php
<? php
namespace App\Mixins ;
use Illuminate\Database\Eloquent\ Model ;
class AnalyticsMixin
{
public function track ()
{
return function ( Model $model ) {
$this -> 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
use Vizra\VizraADK\Services\ AgentBuilder ;
use App\Mixins\ AnalyticsMixin ;
public function boot () : void
{
AgentBuilder :: mixin ( new AnalyticsMixin ());
}
Now use all the mixed-in methods:
$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.
Advanced Patterns
Integration with Events
Combine macros with Laravel events for powerful side effects:
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 ;
});
Dynamic Configuration
Load configuration dynamically from your models:
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 ();
Workflow Macros
Add custom workflow types using the WorkflowManager:
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 ();
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
Testing Macros
Test your macros using Pest or PHPUnit:
tests/Feature/MacroTest.php
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.
Learn More