AIエージェントとレンダリングサーフェス間の通信のための、トランスポート非依存の双方向プロトコル。ひとつのエージェント、あらゆる画面へ。
AIエージェントはテーブル、フォーム、チャート、ステータスメッセージ、コードブロックといった構造化された出力を生成します。しかし、その出力のレンダリングはトランスポートとフロントエンドフレームワークに密結合されています。Webチャット向けに構築されたエージェントはデスクトップアプリでレンダリングできません。SSEストリームを使うエージェントは、別のプロトコルを期待するモバイルクライアントにサービスを提供できません。
新しいレンダリングサーフェスごとに、カスタムの統合コードが必要になります。
ARPはプロトコルを定義します — フレームワークでも、ライブラリでもありません。Waylandがアプリケーションをディスプレイサーバーからデカップリングしたように、ARPはエージェントをレンダラーからデカップリングします。
エージェントは何を表示するかを決定します。レンダラーはどのように表示するかを決定します。
Agent (backend) Renderer (web, CLI, mobile)
─────────────── ──────────────────────────
Owns surfaces ── render / delta ──► Owns display
Owns UI state ◄── input events ──── Owns input routingheadersとrowsを持つtableのような型付きディスクリプタを送出します。すべてのARPメッセージは、最低限 { v: 1, type: "<type>" } を持つJSONです。
| タイプ | 目的 |
|---|---|
hello | 接続時のケイパビリティハンドシェイク |
delta | インクリメンタルなテキストチャンク |
tool_start | ツール実行開始 |
tool_end | ツール実行完了 |
render | 生成的UIコンポーネント |
patch | インクリメンタルなコンポーネント更新 |
error | エラーイベント |
commit | ストリーム完了 |
| タイプ | 入力タイプ | 目的 |
|---|---|---|
input | text | ユーザーのテキストメッセージ |
input | action | ボタンクリック / UIアクション |
input | form_submit | フォーム送信 |
ARP準拠のレンダラーは最低限 text をサポートしなければなりません。コンポーネントはフォールバックチェーンを宣言します — chart は table にフォールバックし、table は text にフォールバックします。
/_arp/v1import { ArpClient } from '@haira/arp'
const client = new ArpClient('ws://localhost:8080/_arp/v1', {
onDelta: (text) => appendToChat(text),
onRender: (event) => renderComponent(event.component, event.props),
onDone: () => markStreamComplete(),
})
client.connect()
client.sendText('Show me the sales data')import { ArpChat } from '@haira/arp-react'
function App() {
return (
<ArpChat
url="ws://localhost:8080/_arp/v1"
theme="dark"
title="Data Explorer"
/>
)
}Vue 3向けの @haira/arp-vue と、Goバックエンド向けの github.com/haira-lang/arp-go も提供しています。
すべてのHairaサーバーはネイティブでARPを話します。設定は不要です。
import "ui"
tool query_database(query: string) -> any {
"""Executes a SQL query and displays results."""
rows, err = postgres.query(db, query)
if err != nil {
return ui.status_card("error", "Query Failed", conv.to_string(err))
}
return ui.table("Query Results", headers, rows)
}
agent DataExplorer {
provider: OpenAI
tools: [query_database]
ui: ui
}
@webhook("/chat")
workflow Chat(message: string, session_id: string) -> stream {
return DataExplorer.stream(message, session: session_id)
}新しいコンポーネントは、Waylandにインスパイアされた3フェーズのライフサイクルに従います:
x-vendor-names-name| レベル | 必須コンポーネント | ターゲット |
|---|---|---|
| 最小 | text + テキスト入力 | 音声アシスタント、IoT |
| 基本 | text、table、form、confirm、choices | CLIターミナル |
| 標準 | すべてのコアコンポーネント、完全なオブジェクトモデル | Web / デスクトップ |
| フル | 標準 + ストリーミング、マルチサーフェス、ファイルアップロード | リッチWebアプリ |