Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Choose an example based on your use case:
- **Want a full-stack TypeScript app?** → [TanStack Chat (ts-react-chat)](#tanstack-chat-ts-react-chat)
- **Need a vanilla JS frontend?** → [Vanilla Chat](#vanilla-chat)
- **Multi-User TypeScript chat app?** → [Group Chat (ts-group-chat)](#group-chat-ts-group-chat)
- **Polyglot AG-UI backends (Go/Rust/PHP/Zig/Bash/Python)?** → [AG-UI Polyglot Echo (ag-ui)](#ag-ui-polyglot-echo-ag-ui)

## TypeScript Examples

Expand Down Expand Up @@ -122,6 +123,45 @@ pnpm start

---

### AG-UI Polyglot Echo (ag-ui)

A React SPA that connects to **Go, Rust, PHP, Zig, Bash, and Python chat servers** over the AG-UI SSE protocol, with each backend streaming OpenAI or Anthropic completions. Toolchain detection writes `public/servers.json`; unavailable backends show setup instructions in the UI.

**Tech Stack:**

- React + Vite (SPA)
- `@tanstack/ai-react` + `@tanstack/ai-react-ui`
- Go chat server (`net/http`, `:8001`)
- Rust chat server (Axum, `:8002`)
- PHP chat server (built-in server + curl, `:8003`)
- Zig chat server (stdlib HTTP, `:8004`)
- Bash chat server (socat + curl + jq, `:8005`)
- Python chat server (stdlib HTTP + urllib, `:8006`)

**Features:**

- ✅ Backend picker (Go | Rust | PHP | Zig | Bash | Python)
- ✅ Toolchain-gated `dev:all` + `servers.json` availability
- ✅ Setup instructions when a runtime is missing (or disabled via `AGUI_DISABLE_SERVERS`)
- ✅ Provider picker (OpenAI | Anthropic)
- ✅ Hand-rolled AG-UI SSE in six languages
- ✅ Streaming LLM responses via env API keys

**Getting Started:**

```bash
cd examples/ag-ui
pnpm install
cp .env.example .env
pnpm dev:all
```

Install whichever backends you want to run locally (Go, Rust, PHP, Zig, Bash, Python) plus provider API keys. The Bash server uses Bash 4+, curl, jq, and socat (`brew install bash jq socat`). To simulate missing runtimes: `AGUI_DISABLE_SERVERS=php,zig,bash,python pnpm dev:all`.

📖 [Full Documentation](ag-ui/README.md)

---

## Architecture Patterns

### Full-Stack TypeScript
Expand Down
10 changes: 10 additions & 0 deletions examples/ag-ui/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# OpenAI
OPENAI_API_KEY=your_openai_api_key_here

# Anthropic
ANTHROPIC_API_KEY=your_anthropic_api_key_here

# Optional: comma-separated backend ids to treat as unavailable even when
# the toolchain is installed (useful for testing setup instructions).
# Example: AGUI_DISABLE_SERVERS=php,zig
AGUI_DISABLE_SERVERS=
8 changes: 8 additions & 0 deletions examples/ag-ui/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
dist
node_modules
servers/rust/target
servers/zig/.zig-cache
servers/zig/zig-out
servers/python/__pycache__

servers/go/go
122 changes: 122 additions & 0 deletions examples/ag-ui/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# AG-UI Polyglot Chat

A React SPA that talks to **Go, Rust, PHP, Zig, Bash, and Python AG-UI backends** over Server-Sent Events (SSE). Each backend streams simple chat completions from **OpenAI** or **Anthropic** — no TanStack packages on the server, just the AG-UI wire protocol.

This example shows that any backend can serve `@tanstack/ai-react` clients as long as it speaks [AG-UI](https://docs.ag-ui.com/): accept `RunAgentInput` via POST, stream AG-UI events as SSE.

## Tech stack

| Layer | Stack |
| ------------- | ------------------------------------------------------------------------ |
| Client | React, Vite, `@tanstack/ai-react`, `@tanstack/ai-react-ui` |
| Go server | `net/http`, hand-rolled AG-UI SSE, OpenAI/Anthropic streaming on `:8001` |
| Rust server | Axum, hand-rolled AG-UI SSE, OpenAI/Anthropic streaming on `:8002` |
| PHP server | Built-in PHP server + curl, hand-rolled AG-UI SSE on `:8003` |
| Zig server | Stdlib HTTP + HTTPS client, hand-rolled AG-UI SSE on `:8004` |
| Bash server | Bash + socat + curl + jq, hand-rolled AG-UI SSE on `:8005` |
| Python server | Stdlib HTTP + urllib, hand-rolled AG-UI SSE on `:8006` |

## Prerequisites

- Node.js + pnpm (from repo root)
- [Go 1.22+](https://go.dev/dl/) (optional — UI shows setup if missing)
- [Rust stable](https://rustup.rs/) (optional)
- [PHP 8.2+ CLI with curl](https://www.php.net/downloads) (optional)
- [Zig](https://ziglang.org/download/) (optional)
- Bash 4+, curl, jq, and socat (`brew install bash jq socat`) (optional)
- [Python 3.9+](https://www.python.org/downloads/) (optional)
- OpenAI and/or Anthropic API keys

Only backends whose toolchains are detected on PATH are started by `pnpm dev:all`. The UI reads `public/servers.json` to show which servers are available and displays setup instructions for missing ones.

## Quick start

From the monorepo root:

```bash
pnpm install
cd examples/ag-ui
cp .env.example .env
# Add OPENAI_API_KEY and/or ANTHROPIC_API_KEY
pnpm dev:all
```

Open [http://localhost:3000](http://localhost:3000), pick a backend tab, choose a provider/model, and chat.

### Simulate missing toolchains

If your machine has every runtime installed but you want to test the setup UI:

```bash
AGUI_DISABLE_SERVERS=php,zig pnpm dev:all
```

PHP and Zig tabs will show install instructions; Go and Rust still connect normally.

### Run pieces separately

```bash
# Terminal 1 — Vite dev server (proxies /api/* and serves servers.json)
pnpm dev

# Terminal 2+ — individual backends
pnpm dev:go
pnpm dev:rust
pnpm dev:php
pnpm dev:zig
pnpm dev:bash
pnpm dev:python
```

`pnpm dev:all` loads `.env`, writes `public/servers.json`, and starts the client plus every detected backend.

Refresh availability without restarting everything:

```bash
pnpm detect-servers
```

## Architecture

```
React SPA (useChat + fetchServerSentEvents)
GET /servers.json ──► generated backend availability
POST /api/go ──► Vite proxy ──► Go :8001 ──► OpenAI / Anthropic
POST /api/rust ──► Vite proxy ──► Rust :8002 ──► OpenAI / Anthropic
POST /api/php ──► Vite proxy ──► PHP :8003 ──► OpenAI / Anthropic
POST /api/zig ──► Vite proxy ──► Zig :8004 ──► OpenAI / Anthropic
POST /api/bash ──► Vite proxy ──► Bash :8005 ──► OpenAI / Anthropic
POST /api/python ──► Vite proxy ──► Python :8006 ──► OpenAI / Anthropic
```

The client sends AG-UI `RunAgentInput` with `forwardedProps: { provider, model }`. Each server converts simple text messages, streams the provider response, and emits:

```
RUN_STARTED
TEXT_MESSAGE_START
TEXT_MESSAGE_CONTENT (streamed)
TEXT_MESSAGE_END
RUN_FINISHED
data: [DONE]
```

## Project layout

```
examples/ag-ui/
├── public/servers.json generated backend availability (fallback committed)
├── scripts/ detect toolchains, write servers.json, dev:all
├── src/ React SPA
├── servers/go/ Go AG-UI + LLM server
├── servers/rust/ Rust AG-UI + LLM server
├── servers/php/ PHP AG-UI + LLM server
├── servers/zig/ Zig AG-UI + LLM server
├── servers/bash/ Bash AG-UI + LLM server
└── servers/python/ Python AG-UI + LLM server
```

## Related docs

- [AG-UI compliance migration](../../docs/migration/ag-ui-compliance.md)
- [Connection adapters](../../docs/chat/connection-adapters.md)
- [Chat architecture](../../packages/ai/docs/chat-architecture.md)
Binary file added examples/ag-ui/bash-server.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions examples/ag-ui/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>TanStack AI - AG-UI</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
39 changes: 39 additions & 0 deletions examples/ag-ui/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "ag-ui",
"private": true,
"type": "module",
"version": "0.0.1",
"scripts": {
"detect-servers": "node scripts/detect-servers.mjs",
"predev": "node scripts/detect-servers.mjs",
"dev": "vite --port 3000",
"dev:go": "go run -C servers/go .",
"dev:rust": "cargo run --manifest-path servers/rust/Cargo.toml",
"dev:php": "php -S 127.0.0.1:8003 -t servers/php servers/php/router.php",
"dev:zig": "zig build run --build-file servers/zig/build.zig",
"dev:bash": "bash servers/bash/server.sh",
"dev:python": "python3 servers/python/server.py",
"dev:all": "node scripts/dev-all.mjs",
"build": "vite build",
"preview": "vite preview",
"test:types": "tsc --noEmit"
},
"dependencies": {
"@tanstack/ai-client": "workspace:*",
"@tanstack/ai-react": "workspace:*",
"@tanstack/ai-react-ui": "workspace:*",
"react": "^19.2.3",
"react-dom": "^19.2.3"
},
"devDependencies": {
"@tailwindcss/vite": "^4.1.18",
"@types/react": "^19.2.7",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.1.2",
"concurrently": "^9.1.2",
"dotenv": "^17.2.3",
"tailwindcss": "^4.1.18",
"typescript": "5.9.3",
"vite": "^7.3.3"
}
}
83 changes: 83 additions & 0 deletions examples/ag-ui/public/servers.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{
"generatedAt": "2026-07-20T00:20:05.964Z",
"servers": [
{
"id": "go",
"label": "Go",
"port": 8001,
"available": true,
"disabledByEnv": false,
"setup": {
"summary": "Install Go 1.22+ and ensure `go` is on PATH.",
"installUrl": "https://go.dev/dl/",
"verify": "go version",
"run": "pnpm dev:go"
}
},
{
"id": "rust",
"label": "Rust",
"port": 8002,
"available": true,
"disabledByEnv": false,
"setup": {
"summary": "Install Rust stable via rustup and ensure `cargo` is on PATH.",
"installUrl": "https://rustup.rs/",
"verify": "cargo --version",
"run": "pnpm dev:rust"
}
},
{
"id": "php",
"label": "PHP",
"port": 8003,
"available": true,
"disabledByEnv": false,
"setup": {
"summary": "Install PHP 8.2+ CLI and ensure `php` is on PATH.",
"installUrl": "https://www.php.net/downloads",
"verify": "php -v",
"run": "pnpm dev:php"
}
},
{
"id": "zig",
"label": "Zig",
"port": 8004,
"available": true,
"disabledByEnv": false,
"setup": {
"summary": "Install Zig and ensure `zig` is on PATH.",
"installUrl": "https://ziglang.org/download/",
"verify": "zig version",
"run": "pnpm dev:zig"
}
},
{
"id": "bash",
"label": "Bash",
"port": 8005,
"available": true,
"disabledByEnv": false,
"setup": {
"summary": "Install Bash 4+, curl, jq, and socat and ensure they are on PATH.",
"installUrl": "https://brew.sh/",
"verify": "bash --version && curl --version && jq --version && socat -V",
"run": "pnpm dev:bash"
}
},
{
"id": "python",
"label": "Python",
"port": 8006,
"available": true,
"disabledByEnv": false,
"setup": {
"summary": "Install Python 3.9+ and ensure `python3` is on PATH.",
"installUrl": "https://www.python.org/downloads/",
"verify": "python3 --version",
"run": "pnpm dev:python"
}
}
]
}
Binary file added examples/ag-ui/python-server.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions examples/ag-ui/scripts/detect-servers.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {
detectServers,
logDetectionSummary,
outputPath,
writeServersJson,
} from './servers.mjs'

const { servers } = writeServersJson()
logDetectionSummary(detectServers())
console.log(`[ag-ui] wrote ${outputPath}`)
Loading
Loading