PHP code example of heiner / agent-graph
1. Go to this page and download the library: Download heiner/agent-graph library . Choose the download type require .
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
heiner / agent-graph example snippets
use Heiner\AgentGraph\Contracts\Node;
use Heiner\AgentGraph\Facades\AgentGraph;
use Heiner\AgentGraph\Graph\StateGraph;
use Heiner\AgentGraph\Runtime\NodeContext;
use Heiner\AgentGraph\Runtime\NodeResult;
final class ClassifyTicket implements Node
{
public function __invoke(NodeContext $context): NodeResult
{
return NodeResult::write(['category' => 'billing']);
}
}
AgentGraph::define(
StateGraph::make('support_triage')
->state([
'input' => 'string',
'category' => 'string|null',
'answer' => 'string|null',
])
->node('classify', ClassifyTicket::class)
->edge(StateGraph::START, 'classify')
->edge('classify', StateGraph::END)
);
$run = AgentGraph::graph('support_triage')
->thread($conversationId)
->input(['input' => $message])
->run();
return NodeResult::interrupt('approval', [
'title' => 'Approve CRM update',
'summary' => 'The agent wants to update the customer plan.',
]);
$run = AgentGraph::resume($runId, [
'interrupt_id' => $interruptId,
'approved' => true,
]);
if ($context->hasResumePayload()) {
$payload = $context->resumePayload();
$interruptId = $context->interruptId();
}
$run = AgentGraph::resumeWithStateEdit(
runId: $runId,
interruptId: $interruptId,
statePatch: ['answer' => 'Corrected answer'],
resolvedBy: (string) $user->id,
);
$snapshot = AgentGraph::inspect($runId, withHistory: true, withTraces: true);
$snapshot->status(); // completed, interrupted, delayed, failed, cancelled
$snapshot->state(); // latest checkpoint state
$snapshot->checkpoint(); // latest checkpoint
$snapshot->checkpoints(); // populated when withHistory is true
$snapshot->writes(); // persisted checkpoint writes
$snapshot->interrupt(); // current pending interrupt, if any
$snapshot->traces(); // populated when withTraces is true
$timeline = AgentGraph::timeline($runId,
$step->nodeId();
$step->status(); // completed, interrupted, delayed, failed, skipped
$step->writes();
$step->interrupt();
$step->stateDiff();
}
use Heiner\AgentGraph\Runtime\RunEvent;
$run = AgentGraph::graph('support_triage')
->thread($conversationId)
->input(['input' => $message])
->onEvent(function (RunEvent $event): void {
logger()->debug('agent-graph.event', $event->toArray());
})
->collectEvents()
->run();
$run->events(); // array<RunEvent>
$interruptedRuns = AgentGraph::runs([
'status' => 'interrupted',
'thread_id' => $conversationId,
], limit: 25);
$tasks = AgentGraph::tasks([
'run_id' => $runId,
'status' => 'completed',
], limit: 25);
$child = AgentGraph::graph('support_triage')
->thread($conversationId)
->input(['input' => $delegatedRequest])
->meta(['tenant' => 'acme'])
->parent($parentRunId, $parentCheckpointId, 'delegate', relationship: 'tool')
->run();
$child->meta()['parent'];
AgentGraph::inspect($child->runId())->parent();
AgentGraph::childRuns($parentRunId, limit: 25);
use Heiner\AgentGraph\Runtime\Send;
return NodeResult::sendMany([
Send::to('summarize_item', ['item' => $itemA]),
Send::to('summarize_item', ['item' => $itemB]),
]);
StateGraph::make('summaries')
->state(['items' => 'array', 'summaries' => 'array'])
->reducer('summaries', 'append');
StateGraph::make('support')
->node('call_api', CallApiNode::class)
->edge(StateGraph::START, 'call_api')
->edge('call_api', StateGraph::END)
->retry('call_api', maxAttempts: 3, delayMs: 100, backoff: 2.0, maxDelayMs: 1000);
StateGraph::make('support')
->node('call_api', CallApiNode::class)
->timeout('call_api', seconds: 10)
->concurrency('call_api', limit: 1, key: 'support-api');
$run = AgentGraph::resumeStrict($runId, [
'interrupt_id' => $interruptId,
'approved' => true,
]);
use Heiner\AgentGraph\Graph\InterruptPolicy;
return NodeResult::interrupt('approval', ['prompt' => 'Approve?'])
->withInterruptPolicy(InterruptPolicy::expiresAfter(600));
AgentGraph::expireInterrupts();
use Heiner\AgentGraph\Runtime\SubgraphNode;
StateGraph::make('parent')
->state(['message' => 'string', 'answer' => 'string'])
->node('delegate', SubgraphNode::make('delegate', 'child_graph')
->mapped(
input: fn (array $state) => ['child_input' => $state['message']],
output: fn (array $childState) => ['answer' => $childState['child_answer']],
))
->edge(StateGraph::START, 'delegate');
$checkpoint = AgentGraph::checkpoint($checkpointId, withWrites: true);
$checkpoint->state();
$checkpoint->stateBefore(); // parent checkpoint state, or null
$checkpoint->stateAfter(); // alias for this checkpoint's state
$checkpoint->nextNodes();
$checkpoint->writes();
$replayed = AgentGraph::replay(
checkpointId: $checkpointId,
threadId: $conversationId,
meta: ['reason' => 'support_recheck'],
);
$forked = AgentGraph::fork(
checkpointId: $checkpointId,
statePatch: ['category' => 'technical'],
asNode: 'classify',
meta: ['reason' => 'manual_branch'],
);
$branches = AgentGraph::timeTravelChildren($checkpointId, limit: 25);
use Heiner\AgentGraph\LaravelAi\AgentNode;
AgentNode::make('answer')
->agent(App\Ai\SupportAgent::class)
->prompt(fn (array $state) => $state['input'])
->writeTextTo('answer')
->writeUsageTo('usage');
AgentNode::make('answer')
->agent(App\Ai\SupportAgent::class)
->prompt(fn (array $state) => $state['input'])
->stream()
->onTextDelta(fn (string $delta) => broadcast(new AgentDelta($delta)))
->writeTextTo('answer');
AgentNode::make('answer')
->agent(App\Ai\SupportAgent::class)
->prompt(fn (array $state) => $state['input'])
->writeTextTo('answer')
->writeStructuredTo('structured')
->writeToolCallsTo('tool_calls')
->writeToolResultsTo('tool_results')
->writeStepsTo('steps')
->writeStreamEventsTo('stream_events');
public function tools(): iterable
{
return [
AgentGraph::tool('support_triage')
->name('run_support_triage')
->description('Run or resume the durable support workflow.')
->thread(fn ($request) => $request['thread_id'])
->input(fn ($request) => $request['input'] ?? [])
->meta(fn ($request) => ['source' => 'laravel-ai-tool']),
];
}
$run = AgentGraph::session('support_triage', $conversationId)
->run(['input' => $message]);
$status = AgentGraph::session('support_triage', $conversationId)->status();
AgentGraph::durableTool('support_triage')
->description('Start, inspect, resume, or cancel the active support workflow.');
use Heiner\AgentGraph\Memory\MemoryScope;
$scope = MemoryScope::thread($conversationId, tenantId: $tenantId);
AgentGraph::memory()->writeExtracted($scope, 'profile', $text, ['source' => 'chat']);
AgentGraph::memory()->export($scope, 'profile');
AgentGraph::memory()->deleteNamespace($scope, 'profile');
bash
composer agent-graph:install
php artisan migrate