Pi chat agent UI template on Svelte/SvelteKit, ready for plugging with knowledge and tools.
- TypeScript 71.3%
- Svelte 21.5%
- Just 4.3%
- JavaScript 2.3%
- HTML 0.6%
|
|
||
|---|---|---|
| src | ||
| static | ||
| .gitignore | ||
| .npmrc | ||
| .prettierignore | ||
| .prettierrc | ||
| bun.lock | ||
| eslint.config.js | ||
| justfile | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| vite.config.ts | ||
barechat
A web chat UI that connects to @earendil-works/pi-agent-core Agent backend — a modern web alternative to the @earendil-works/pi-tui terminal experience.
Architecture
- SvelteKit (app shell + API routes)
- SSE (server→client event stream)
- JSONL (server-side session persistence)
- pi-agent-core (Agent runtime, model inference)
Each SSE connection owns one Agent. Sessions are permanent threads with JSONL history replay on reconnect.
Project Structure
src/
├── lib/
│ ├── agent/
│ │ ├── manager.ts # Session CRUD, JSONL read/write, listSessions()
│ │ ├── run.ts # Agent init, prompt handling, SSE event forwarding
│ │ └── types.ts # SSEEvent interface
│ ├── components/
│ │ └── SessionSidebar.svelte # Session list sidebar
│ ├── stores/
│ │ ├── sessions.ts # LocalStorage-backed session list
│ │ ├── currentSession.ts # Active session store
│ │ └── events.ts # SSE event state store
│ └── vitest-examples/ # SvelteKit scaffold examples
├── routes/
│ ├── +layout.svelte # App layout (favicon, Svelte head)
│ ├── +page.svelte # Chat page (placeholder — Phase 3)
│ └── api/sessions/
│ ├── +server.ts # POST create, DELETE
│ └── [sessionId]/
│ ├── +server.ts # DELETE (moved from parent)
│ ├── prompt/
│ │ └── +server.ts # POST prompt
│ └── sse/
│ └── +server.ts # GET SSE stream
├── test/
│ ├── index.ts # Barrel export
│ ├── fixtures/
│ │ ├── messages.ts # userMessage(), fullAssistantMessage(), toolResultMessage()
│ │ ├── messages.test.ts # 4 tests — message builders
│ │ ├── jsonl.ts # readJsonl(), writeJsonl(), appendJsonl()
│ │ ├── jsonl.test.ts # 2 tests — JSONL roundtrip
│ │ ├── session.ts # createTestSession(), deleteTestSession(), listTestSessions()
│ │ └── session.test.ts # 5 tests — session CRUD
│ ├── mock-agent.ts # FakeAgent — event emitter for unit tests
│ ├── mock-agent.test.ts # 5 tests — lifecycle, subscribe, abort
│ ├── sse.ts # collectSSEEvents(), extractEventTypes()
│ └── sse.test.ts # 2 tests — SSE collection + event extraction
└── app.d.ts / app.html
API Endpoints
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/sessions |
Create session → { sessionId, createdAt } (201) |
DELETE |
/api/sessions/:sessionId |
Delete session → { deleted: true } (200) |
GET |
/api/sessions/:sessionId/sse |
Open SSE stream (replay history + live events) |
POST |
/api/sessions/:sessionId/prompt |
Send prompt → { accepted: true } (202) |
SSE Event Types
| Event | Payload |
|---|---|
agent_start |
{} |
turn_start |
{} |
message_start |
{ message, type? } |
message_update |
{ contentIndex, delta, type: "text_delta"|"thinking_delta" } |
message_end |
{ message } |
tool_execution_start |
{ toolCallId, toolName, args } |
tool_execution_end |
{ toolCallId, toolName, result, isError } |
turn_end |
{ message, toolResults } |
agent_end |
{ messages } |
error |
{ errorMessage } |
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
SYSTEM_PROMPT |
Yes | — | System prompt for the Agent |
MODEL |
Yes | — | provider/modelId (e.g. anthropic/claude-sonnet-4-20250514) |
OPENAI_BASE_URL |
conditional | — | Base URL for OpenAI-compatible endpoints |
OPENAI_API_KEY |
conditional | — | API key for OpenAI-compatible endpoints |
SESSION_DIR |
No | ./data/sessions |
Directory for JSONL session files |
The MODEL variable supports either provider/modelId format or a bare model ID (defaults to openai provider). When using OpenAI-compatible endpoints (vLLM, Ollama, etc.), set OPENAI_BASE_URL and OPENAI_API_KEY.
Development
Prerequisites
Quick Start
# Install dependencies
just install-deps # or: bun install
# Copy and configure environment
cp .env.local .env # edit with your MODEL, OPENAI_BASE_URL, etc.
# Run tests
just test
# Start dev server
just dev
Commands
| Command | Description |
|---|---|
just dev |
Start Vite dev server |
just build |
Build for production |
just preview |
Preview production build |
just lint |
Prettier check + ESLint |
just format / just fmt |
Format with Prettier |
just check |
Full type check (svelte-check) |
just check-watch |
Type check in watch mode |
just test |
Server tests (unit + integration) |
just test-all |
All tests including Playwright client tests |
just sync |
Regenerate SvelteKit generated files |
just ci |
lint + check + test |
Implementation Status
✅ Phase 1: Backend Foundation
- Session CRUD (create, delete, list) with uuidv7 IDs
- JSONL read/write persistence
- Agent initialization & prompt handling
- SSE event streaming (fine-grained, live)
- JSONL replay on reconnect
- Agent polling loop (detects prompts between runs)
- Full end-to-end curl tested
✅ Phase 2: Frontend Skeleton
src/lib/stores/sessions.ts— LocalStorage-backed session listsrc/lib/stores/currentSession.ts— active session storesrc/lib/stores/events.ts— SSE event state storeSessionSidebar.svelte— session list with create/delete+layout.svelte— sidebar + chat area layout+page.svelte— wire up session creation & SSE connection- Added
GET /api/sessionsendpoint for listing sessions
📋 Phase 3: Chat UI Components
InputBox.svelte— auto-growing textarea (Enter=send)MessageList.svelte— renders message arrayMessageBubble.svelte— individual message renderingThinkingBlock.svelte— collapsible thinkingToolBlock.svelte— collapsible tool executionErrorBlock.svelte— inline error displayMarkdownContent.svelte—marked+ highlight.js renderer
📋 Phase 4: Integration & Polish
- Replay logic (SSE history → UI build)
- Reconnect flow (session ID → SSE → replay)
- Loading states during prompt execution
- Message timestamps
- Style polish (colors, spacing, transitions)
- Error handling (network, agent, SSE disconnect)
- Mobile responsive layout
Test Module
The src/test/ module provides utilities for backend testing:
- Message fixtures:
userMessage(),fullAssistantMessage(),toolResultMessage() - JSONL helpers:
readJsonl(),writeJsonl(),appendJsonl() - Session fixtures:
createTestSession(),deleteTestSession(),listTestSessions(),clearTestSessions()(uses isolateddata/sessions-test/directory) - SSE collector:
collectSSEEvents()— captures SSE events from a URL - FakeAgent: lightweight mock Agent for unit tests — emits events, supports
prompt(),subscribe(),abort()
19 tests passing across fixtures, mock agent, and SSE utilities.