rmh/laravel-openui
Composer 安装命令:
composer require rmh/laravel-openui
包简介
OpenUI Generative UI integration for the Laravel AI SDK - inject OpenUI Lang system prompts, define component libraries, and stream structured UI responses.
README 文档
README
OpenUI Generative UI integration for the Laravel AI SDK.
This package connects OpenUI — the open standard for Generative UI — with the Laravel AI SDK. It handles system prompt injection, component library management, caching, and streaming, so your agents can respond with structured, interactive UI instead of plain text.
How It Works
OpenUI works in four steps:
Component Library → System Prompt → LLM → OpenUI Lang → Frontend Renderer
- You define which React components the LLM is allowed to generate.
- This package injects a system prompt into your agent's instructions describing those components and the OpenUI Lang syntax.
- The LLM responds in OpenUI Lang (a compact, streaming-native format).
- Your frontend's
<Renderer />from@openuidev/react-langparses and renders it live.
Installation
composer require rmh/laravel-openui
Publish the config file:
php artisan vendor:publish --tag=openui
Quick Start
Option 1: Global Middleware (zero-touch, all agents)
Register the middleware once in your AppServiceProvider and every agent will automatically receive the OpenUI system prompt:
// app/Providers/AppServiceProvider.php use RMH\OpenUI\Middleware\InjectOpenUIPrompt; use Laravel\Ai\Facades\Ai; public function boot(): void { Ai::middleware([InjectOpenUIPrompt::class]); }
Your agents need no changes. Stream the response back to your OpenUI frontend:
Route::post('/chat', function (Request $request) { return MyAgent::make() ->stream($request->input('message')) ->usingVercelDataProtocol(); });
Option 2: GeneratesUI Trait (explicit opt-in per agent)
Add the trait to agents that should produce UI. Rename instructions() to agentInstructions():
use RMH\OpenUI\Concerns\GeneratesUI; use Laravel\Ai\Contracts\Agent; use Laravel\Ai\Promptable; class HotelSearchAgent implements Agent { use Promptable, GeneratesUI; protected function agentInstructions(): string { return 'You are a helpful hotel search assistant.'; } }
Toggle UI per call:
// UI enabled (default) HotelSearchAgent::make()->prompt('Find hotels in Paris'); // UI disabled for this call HotelSearchAgent::make()->withoutUI()->prompt('Find hotels in Paris');
Option 3: Per-agent Middleware
Add the middleware only to specific agents:
use RMH\OpenUI\Middleware\InjectOpenUIPrompt; use Laravel\Ai\Contracts\Agent; use Laravel\Ai\Contracts\HasMiddleware; use Laravel\Ai\Promptable; class HotelSearchAgent implements Agent, HasMiddleware { use Promptable; public function instructions(): string { return 'You are a helpful hotel search assistant.'; } public function middleware(): array { return [new InjectOpenUIPrompt]; } }
Option 4: Anonymous Agents / Inline Calls
use RMH\OpenUI\Facades\OpenUI; use function Laravel\Ai\{agent}; $response = agent( instructions: 'You are a travel assistant.' . "\n\n" . OpenUI::systemPrompt(), )->prompt('Find hotels in Paris');
Defining Your Component Library
In config/openui.php
'components' => [ 'Card' => [ 'title' => 'string', 'description' => 'string?', // ? = optional 'imageUrl' => 'string?', 'ctaLabel' => 'string?', ], 'Carousel' => [ 'cards' => 'Card[]', // nested component reference ], 'Table' => [ 'columns' => 'array', 'rows' => 'array', ], 'Alert' => [ 'type' => 'enum:info|success|warning|error', 'title' => 'string', 'message' => 'string?', ], ],
Supported prop types: string, int, float, bool, array, ComponentName[], enum:a|b|c. Append ? to mark any type as optional.
Via the Facade (programmatic / runtime)
use RMH\OpenUI\Facades\OpenUI; // Register one component OpenUI::component('PriceTag', [ 'amount' => 'string', 'currency' => 'string?', ]); // Register many at once OpenUI::library([ 'Chart' => ['type' => 'enum:bar|line|pie', 'data' => 'array'], 'MapPin' => ['lat' => 'float', 'lng' => 'float', 'label' => 'string?'], ]);
The cache is automatically invalidated when you add components via the facade.
Via the Artisan Command
Scaffold a typed component definition class:
php artisan openui:component Card --props="title:string,description:string?,imageUrl:string?"
This generates app/Ai/OpenUI/Components/CardComponent.php. Register it in your service provider:
use RMH\OpenUI\Facades\OpenUI; use App\Ai\OpenUI\Components\CardComponent; OpenUI::component((new CardComponent)->name(), (new CardComponent)->props());
Export for Frontend
Export your component definitions to TypeScript/Zod for your frontend:
php artisan openui:export
This generates resources/js/openui.ts with Zod schemas:
// Auto-generated by laravel-openui import { z } from 'zod'; export const CardSchema = z.object({ title: z.string(), description: z.string().optional(), imageUrl: z.string().optional(), }); export const openUISchema = z.object({ Card: CardSchema, });
Export options:
| Option | Description |
|---|---|
--path=... |
Custom output path (default: resources/js/openui.ts) |
--format=zod|ts|json |
Output format (default: zod) |
--types |
TypeScript types only (shorthand for --format=ts) |
--force |
Overwrite existing file |
Examples:
# Export to custom path php artisan openui:export --path=frontend/src/openui.ts # Export TypeScript types only (no Zod) php artisan openui:export --types # Export as JSON php artisan openui:export --format=json --path=schema.json # Force overwrite php artisan openui:export --force
Configuration Reference
// config/openui.php 'enabled' => env('OPENUI_ENABLED', true), 'design_system' => env('OPENUI_DESIGN_SYSTEM', 'shadcn'), 'stream_protocol' => env('OPENUI_STREAM_PROTOCOL', 'vercel'), 'system_prompt_placement'=> 'append', // 'append' | 'prepend' 'custom_system_prompt' => null, // override the entire generated prompt 'components' => [...], 'allowed_agents' => [], // empty = all agents; list FQCN to restrict 'cache' => [ 'enabled' => env('OPENUI_CACHE_ENABLED', true), 'store' => env('OPENUI_CACHE_STORE', null), 'ttl' => env('OPENUI_CACHE_TTL', 3600), ],
Frontend Integration
Option 1: Use Exported Schema (Recommended)
Export your component definitions and import them directly:
php artisan openui:export
Then in your frontend:
import { Renderer, createLibrary, defineComponent } from '@openuidev/react-lang'; import { CardSchema, CarouselSchema } from './openui'; import { Card, Carousel } from './components'; const components = [ defineComponent({ name: 'Card', props: CardSchema, component: ({ props }) => <Card {...props} />, }), defineComponent({ name: 'Carousel', props: CarouselSchema, component: ({ props }) => <Carousel {...props} />, }), ]; export const library = createLibrary({ root: 'Card', components }); <Renderer library={library} stream={streamFromLaravel} />
Option 2: Manual Schema Definition
Define schemas manually on the frontend:
import { Renderer, createLibrary, defineComponent } from '@openuidev/react-lang'; import { z } from 'zod'; const Card = defineComponent({ name: 'Card', props: z.object({ title: z.string(), description: z.string().optional(), imageUrl: z.string().optional(), ctaLabel: z.string().optional(), }), component: ({ props }) => <YourCardComponent {...props} />, }); export const library = createLibrary({ root: 'Card', components: [Card] }); <Renderer library={library} stream={streamFromLaravel} />
Inspecting the Generated System Prompt
use RMH\OpenUI\Facades\OpenUI; // View what's being injected dd(OpenUI::systemPrompt()); // Flush and regenerate OpenUI::flushCache();
Testing
When writing tests for agents that use OpenUI, you can temporarily disable injection:
config(['openui.enabled' => false]);
Or assert on the generated prompt:
use RMH\OpenUI\Facades\OpenUI; $this->assertStringContainsString('Card', OpenUI::systemPrompt());
Changelog
Please see CHANGELOG.md.
License
MIT — see LICENSE.md.
rmh/laravel-openui 适用场景与选型建议
rmh/laravel-openui 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 0 次下载、GitHub Stars 达 1, 最近一次更新时间为 2026 年 03 月 13 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「streaming」 「laravel」 「Agent」 「ai」 「laravel-ai」 「openui」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 rmh/laravel-openui 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 rmh/laravel-openui 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 rmh/laravel-openui 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Custom laravel monolog logger for datadog logs management, both api and agent ways
A laravel bundle for the OpenTok PHP SDK
Laravel Wrapper for the OpenTok PHP SDK
A robust, configuration-driven ETL and data import framework for Laravel. Handles CSV/Excel streaming, queues, validation, and relationships.
The Message Submission Agent Diagnostics tool (msadiag) facilitates testing the compatibility of third party message submission agents.
Standalone replacement for php's native get_browser() function
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1
- 点击次数: 33
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-03-13