swisnl/ag-ui-server
Composer 安装命令:
composer require swisnl/ag-ui-server
包简介
PHP server integration for AG-UI - standardized AI agent frontend communication via Server-Sent Events
README 文档
README
A PHP server integration package for AG-UI - standardized AI agent frontend communication via Server-Sent Events and other transport methods.
AG-UI provides a real-time, event-driven protocol for streaming AI agent responses, tool calls, and state updates to frontends. This package makes it easy to integrate AG-UI into your PHP AI projects.
Features
- Complete AG-UI Event Support - All event types: messages, tool calls, lifecycle, state management
- Flexible Message API - Simple one-shot messages or streaming with closures/iterables
- Pluggable Transporters - SSE included, easily extend with WebSocket, polling, etc.
- Adaptive Delta Buffering - Optimized streaming performance
- PSR-14 Compatible - Interoperable with existing event systems
- Type Safe - PHPStan types for better developer experience
- Framework Agnostic - Works with Laravel, Symfony, or any PHP application
Installation
composer require swis/ag-ui-server
Quick Start
<?php use Swis\AgUiServer\AgUiState; use Swis\AgUiServer\Transporter\SseTransporter; // Initialize state $state = new AgUiState(); // Start a conversation run $threadId = 'thread_' . uniqid(); $runId = 'run_' . uniqid(); $state->startRun($threadId, $runId); // Simple message $state->addMessage('Hello! How can I help you?'); // Streaming message from LLM $state->addMessage(function() { return $this->llm->streamCompletion($prompt); // Returns iterable }); // Tool call $state->addToolCall('web_search', '{"query": "weather today"}'); // Finish the run $state->finishRun();
Core Concepts
AG-UI Events
The package supports all AG-UI event types:
- Lifecycle:
RunStarted,RunFinished,RunError,StepStarted,StepFinished - Messages:
TextMessageStart,TextMessageContent,TextMessageEnd - Reasoning:
ReasoningStart,TextReasoningMessageStart,TextReasoningMessageContent,TextReasoningMessageEnd,TextReasoningEnd - Tool Calls:
ToolCallStart,ToolCallArgs,ToolCallEnd - State:
StateSnapshot,StateDelta,MessagesSnapshot - Special:
Raw,Custom
Flexible Message API
// String content - sent as single message $state->addMessage('Complete response here'); // Closure returning string $state->addMessage(function() { return $this->llm->complete($prompt); }); // Closure returning iterable - streamed as deltas $state->addMessage(function() { return $this->llm->streamCompletion($prompt); }; // Direct iterable $state->addMessage(['Hello ', 'world', '!']); // Manual control for complex scenarios $messageId = $state->startMessage(); foreach ($complexStream as $chunk) { $state->addMessageContent($messageId, $chunk); } $state->finishMessage($messageId);
Transporters
Easily swap transport methods:
// Server-Sent Events (default) $transporter = new SseTransporter(); $transporter->initialize(); // Sends headers // Custom headers $transporter = new SseTransporter([ 'Access-Control-Allow-Origin' => 'https://yourapp.com', 'Cache-Control' => 'no-cache', ]); $transporter->initialize(); // Sends headers // Future: WebSocket support // $transporter = new WebSocketTransporter($connection);
RAG Integration Example
public function handleChatRequest(Request $request) { $userMessage = $request->input('message'); $threadId = $request->input('threadId') ?? 'thread_' . uniqid(); $runId = 'run_' . uniqid(); $state = new AgUiState(); $state->startRun($threadId, $runId); try { // Step 1: Analyze query $state->startStep('analyzing_query'); // ... analysis logic ... $state->finishStep(); // Step 2: Retrieve context $state->startStep('retrieving_context'); $state->addToolCall(null, 'vector_search', json_encode([ 'query' => $userMessage, 'top_k' => 5 ])); $documents = $this->vectorSearch($userMessage); $state->finishStep(); // Step 3: Generate response $state->startStep('generating_response'); $state->addMessage(null, function() use ($userMessage, $documents) { return $this->llm->streamWithContext($userMessage, $documents); }, 'assistant'); $state->finishStep(); $state->finishRun(); } catch (\Exception $e) { $state->errorRun($e->getMessage()); } }
Advanced Features
Manual Event Triggering
While AgUiState provides a convenient high-level API for typical AI workflows, you can also trigger events manually for complete control over your application's behavior:
use Swis\AgUiServer\Events\TextMessageStartEvent; use Swis\AgUiServer\Events\TextMessageContentEvent; use Swis\AgUiServer\Events\TextMessageEndEvent; use Swis\AgUiServer\Transporter\SseTransporter; use Psr\EventDispatcher\EventDispatcherInterface; // Set up event dispatcher and transporter $dispatcher = $container->get(EventDispatcherInterface::class); $transporter = new SseTransporter(); $transporter->initialize(); // Sends headers $transporter->setEventDispatcher($dispatcher); // Now trigger events from your application $messageId = 'msg_' . uniqid(); // The transporter will automatically listen for these events and send them $dispatcher->dispatch(new TextMessageStartEvent( messageId: $messageId, role: 'assistant' )); $dispatcher->dispatch(new TextMessageContentEvent( messageId: $messageId, content: 'Hello from my custom application!' )); $dispatcher->dispatch(new TextMessageEndEvent( messageId: $messageId ));
Direct Event Dispatching (Without PSR-14)
If you prefer not to use PSR-14, you can send events directly:
$transporter = new SseTransporter(); $transporter->initialize(); // Send events directly $event = new TextMessageStartEvent( messageId: 'msg_123', role: 'assistant' ); $transporter->send($event); $transporter->close();
When to Use Manual Events vs AgUiState
- Use
AgUiStatefor typical AI agent workflows with automatic state management, message streaming, and tool calls - Use manual events when you need:
- Complete control over event timing and data
- Integration with existing event-driven architectures
- Custom event flows that don't fit the standard AI agent pattern
- Building your own higher-level abstractions
Adaptive Delta Buffering
Delta buffering is optional and can be enabled to optimize streaming performance:
// Without delta buffering (default) $state = new AgUiState(); // With delta buffering for optimized streaming $state = (new AgUiState())->withDeltaBuffering( deltaBufferThreshold: 150, // chars deltaFlushInterval: 0.3 // seconds );
PSR-14 Event Integration
All AG-UI events implement PSR-14 interfaces:
use Psr\EventDispatcher\EventDispatcherInterface; // Your existing PSR-14 dispatcher $dispatcher = $container->get(EventDispatcherInterface::class); // Listen to AG-UI events $dispatcher->addListener(TextMessageStartEvent::class, function($event) { // Log message start $this->logger->info('Message started', ['messageId' => $event->messageId]); });
Custom Transporters
Implement your own transport:
class WebSocketTransporter implements TransporterInterface { public function __construct(private $connection) {} public function initialize(): void { // Setup WebSocket connection } public function send(AgUiEvent $event): void { $this->connection->send($event->toJson()); } public function sendComment(string $comment): void { // WebSocket doesn't need comments } public function close(): void { $this->connection->close(); } }
Event Types Reference
Message Events
TextMessageStart- Begin streaming a messageTextMessageContent- Content chunk (delta)TextMessageEnd- Message complete
Reasoning Events
ReasoningStart- Begin reasoning state (optional)ReasoningMessageStart- Begin streaming a reasoning messageReasoningMessageContent- Content chunk (delta)ReasoningMessageEnd- Reasoning message completeReasoningStart- End reasoning state (optional)
Tool Call Events
ToolCallStart- Begin tool executionToolCallArgs- Tool arguments (can be streamed)ToolCallEnd- Tool execution completeToolCallResult- Results of a Tool execution
Lifecycle Events
RunStarted- Agent run beginsRunFinished- Agent run completes successfullyRunError- Agent run failedStepStarted- Processing step beginsStepFinished- Processing step completes
State Events
StateSnapshot- Complete stateStateDelta- State changes (JSON Patch)MessagesSnapshot- All conversation messages
Changelog
Please see CHANGELOG for more information on what has changed recently.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
This package is open-sourced software licensed under the MIT license.
This package is Treeware. If you use it in production, then we ask that you buy the world a tree to thank us for our work. By contributing to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats.
SWIS ❤️ Open Source
SWIS is a web agency from Leiden, the Netherlands. We love working with open source software.
swisnl/ag-ui-server 适用场景与选型建议
swisnl/ag-ui-server 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 7.31k 次下载、GitHub Stars 达 2, 最近一次更新时间为 2025 年 10 月 24 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「swisnl」 「ag-ui」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 swisnl/ag-ui-server 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 swisnl/ag-ui-server 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 swisnl/ag-ui-server 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Fixture handler for Guzzle 6+
Model Context Protocol client implementation in PHP
NDW Melvin API client
Laravel lti provider
Integrates spatie/laravel-activitylog with Filament
Geometry form field for Filament PHP
统计信息
- 总下载量: 7.31k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 2
- 点击次数: 11
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-10-24