An A2A protocol-based AI agent that uses Marcus Aurelius' Meditations with RAG (ChromaDB) to provide Stoic philosophy dialogue via Genkit and OpenAI-compatible LLMs.
- 🧠 Stoic Philosophy Integration: Pulls insights from Marcus Aurelius' Meditations
- 🤖 AI Agent Server: A2A protocol-based agent server for conversational reflection
- 🔍 RAG Integration: ChromaDB vector store for semantic search over Meditations text
- 🧩 Genkit Framework: Uses Genkit with OpenAI-compatible LLMs (llama.cpp, vLLM, Ollama)
- 🎨 Minimalist UI: Clean, distraction-free design with dark mode support
- 📝 Markdown Rendering: Supports bold, italic, lists, and blockquotes
- 🔄 Streaming Responses: Real-time updates as the agent generates responses
- 📚 Conversation History: Preserved across messages via A2A task lifecycle
- 🧪 Testable Architecture: Separated client/server with unit tests
client/ ← Frontend (HTML + testable client module)
src/ ← Backend (A2A agent server, Genkit, RAG, ChromaDB)
dist/ ← Built output (gitignored)
npm installnpm run build:server # Compile TypeScript → dist/
npm start # Start agent server on localhost:41242npm run build:client # Run tests + bundle → dist/index.html + dist/client.js
npx serve dist -l 3000 # Serve built assets from dist/ on localhost:3000npm run build # Compiles server + runs client build (tests + bundle)
npm start & # Start server in background
npx serve . -l 3000 # Open browser at localhost:3000Set environment variables before running the server:
| Variable | Default | Description |
|---|---|---|
LLM_BASE_URL |
http://10.106.1.89:8080/v1 |
OpenAI-compatible LLM endpoint |
LLM_API_KEY |
dummy |
API key for the LLM server |
STOIC_AGENT_PORT |
41242 |
Port for the A2A agent server |
LLM_BASE_URL=http://10.106.1.182:8888/v1 LLM_API_KEY=sk-your-key npm run build && npm startThe client lives in client/ and is separated from the server to keep testable logic isolated from Node-only dependencies.
client/
src/client.ts ← Testable module (exports: extractTextFromEvent, isConversationFinished, renderText, processEventStream)
test/client.test.ts ← 12 unit tests (no DOM, no network, no LLM)
index.html ← Source HTML (with placeholder for build)
build.mjs ← Build pipeline: tests → bundle → wire HTML → copy to dist/
npm run build:client # Run tests + bundle (outputs to dist/)
npm test # Run unit tests onlyThe build pipeline:
- Runs unit tests (fails fast if tests don't pass)
- Bundles
client/src/client.ts→dist/client.js(minified ESM) - Wires
client/index.html→dist/index.html(replaces placeholder with app script) - Copies
dist/client.jsanddist/index.htmlto rootdist/for serving
The server lives in src/ and handles the A2A protocol, LLM integration, and RAG:
npm run build:server # Compile TypeScript → dist/
npm start # Run compiled server- Minimalist, colorless UI — clean typography, no distractions
- Supports system dark mode (
prefers-color-scheme: dark) - Markdown rendering for agent responses (bold, italic, lists, blockquotes)
- Conversation history preserved across messages via A2A task lifecycle
- Streaming responses with real-time updates
This project is open source and available under the MIT License.
We welcome contributions! Please see our Contributing Guide for details on how to get started.
Please read our Code of Conduct to help us keep this project open and inclusive.
This project is licensed under the MIT License - see the LICENSE file for details.