swisnl/ag-ui-server 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

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

PHP from Packagist Latest Version on Packagist Software License Buy us a tree Build Status Made by SWIS

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 AgUiState for 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 message
  • TextMessageContent - Content chunk (delta)
  • TextMessageEnd - Message complete

Reasoning Events

  • ReasoningStart - Begin reasoning state (optional)
  • ReasoningMessageStart - Begin streaming a reasoning message
  • ReasoningMessageContent - Content chunk (delta)
  • ReasoningMessageEnd - Reasoning message complete
  • ReasoningStart - End reasoning state (optional)

Tool Call Events

  • ToolCallStart - Begin tool execution
  • ToolCallArgs - Tool arguments (can be streamed)
  • ToolCallEnd - Tool execution complete
  • ToolCallResult - Results of a Tool execution

Lifecycle Events

  • RunStarted - Agent run begins
  • RunFinished - Agent run completes successfully
  • RunError - Agent run failed
  • StepStarted - Processing step begins
  • StepFinished - Processing step completes

State Events

  • StateSnapshot - Complete state
  • StateDelta - 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 我们能提供哪些服务?
定制开发 / 二次开发

基于 swisnl/ag-ui-server 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 7.31k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 2
  • 点击次数: 11
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 2
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-10-24