pie-lab
A local-first agent lab that starts from pi, adds 9router operations,
ports Hermes-style learning, and connects agents to web chat, Telegram, and Discord.
pielab.ai · install.sh · docs · chat guide · learning loop
pie-lab is a practical fork-and-integration project for building a personalized Agentic Development Kit.
It starts from the full pi coding-agent source tree, then brings in the most useful operational ideas from 9router, the chat bridge experience from pi-chat, and the learning-loop pattern from hermes-agent.
The operations dashboard inspired by 9router and the chat experience inspired by pi-chat have both been rebuilt as Next.js apps inside this repository, so they can work directly with pie-lab's local server, router, provider settings, and agent bridge.
The result is a single local-first workspace where the CLI agent, model router, provider/account operations, dashboard, persistent memory, automatic skills, and external chat bridges are meant to work together.
Pio is pie-lab's AI Ant Companion.
| Source | Role in pie-lab |
|---|---|
earendil-works/pi |
Base CLI, TUI, agent runtime, tools, extensions, skills, sessions |
decolua/9router |
Router aliases, fallback, provider connections, quota, cooldown, usage/cost accounting, and the operations model rebuilt here as a Next.js dashboard |
earendil-works/pi-chat |
Web chat direction plus Telegram/Discord bridge workflows rebuilt here as a Next.js chat app |
NousResearch/hermes-agent |
Learning loop ideas: persistent memory, automatic skill creation, skill curation, user modeling |
Imported baseline details are tracked in docs/origins.md.
piecoding-agent CLI based on the originalpiworkflow.- Local OpenAI-compatible API server at
apps/server. - Next.js dashboard at
apps/dashboardfor usage, cost, providers, quota, routing policy, proxy, media tests, logs, and Learning Loop operations. - Pie Chat web UI at
apps/chat. - Telegram/Discord bridge extension with
/chat-config,/chat-connect,/chat-spawn-all, and/chat-workers. pie gatewayfor long-running Telegram/Discord messaging plus scheduled cron delivery without keeping a TUI session open.- 9router-style model routing with aliases such as
auto:coding,auto:chat,auto:learning, andauto:memory. - Provider connection storage, account selection, fallback attempts, quota-aware routing, cooldown/model lock handling, and usage/cost records.
- Claude Code local provider path through
claude-code-adk. - Hermes-style Learning Loop:
- local memory in
~/.pie/agent/memories - global agent skills in
~/.pie/agent/skills - project skills in
.pie/skills - background review and proposal records
- skill curator archive/restore + LLM-driven consolidation (umbrella skill merging)
- local memory in
- Scheduler (pie cron):
- IANA timezone-aware cron expressions (
0 9 * * *inAsia/Seoul) - Grace window + missed-run fast-forward (skips stale jobs, not re-runs them)
- Wake-gate: script last line
{"wakeAgent":false}skips LLM call - Separate script/agent timeouts (
scriptTimeoutSeconds+timeoutSeconds) [SILENT]response prefix → skip delivery- Stale running job cleanup on startup
- IANA timezone-aware cron expressions (
- Gateway periodic nudge: per-channel
nudgeIntervalMinutestriggers proactive agent turns on inactivity
| Path | Purpose |
|---|---|
| packages/coding-agent | pie CLI, TUI, sessions, extensions, skills, Learning Loop runtime |
| packages/agent | Agent runtime and tool-calling core |
| packages/ai | Provider abstraction and model adapters |
| packages/router | 9router-derived routing, fallback, quota and policy logic |
| packages/storage | JSON stores for provider connections, usage, quota, and policy state |
| apps/server | Local OpenAI-compatible API and operations API |
| apps/dashboard | Next.js operations dashboard |
| apps/chat | Pie Chat web UI and Telegram/Discord bridge extension |
| .pie/settings.json | Project-local package settings, including the chat bridge extension |
- Node.js
>=22.19.0is required. Older Node 22 builds such as22.12.0can fail duringnpm run build. - npm
- Git
tmuxonly if you use the older/chat-spawn-allworker mode.pie gatewaydoes not require tmux.- At least one model provider credential or local provider path
The repository includes .node-version, so with nvm:
nvm install
nvm use
node -vMake sure node -v prints v22.19.0 or newer before running npm install or npm run build.
The default user install is the npm package, bootstrapped by the GitHub Pages installer:
curl -fsSL https://jikime.github.io/pie-lab/install.sh | sh
pieThe installer checks for Node.js >=22.19.0, checks for npm, then installs:
npm install -g --ignore-scripts @pie-lab/coding-agentFor inspection-first installs, download the script before running it:
curl -fsSLO https://jikime.github.io/pie-lab/install.sh
sh install.shgit clone git@github.com:jikime/pie-lab.git
cd pie-lab
nvm install
nvm use
node -v
npm install
npm run buildnpm run build builds the core packages, server, dashboard, and Pie Chat. The Pie Chat build also type-checks the Telegram/Discord bridge.
For day-to-day local CLI development, run the source CLI directly:
./pie-test.shTo make the local checkout available as a pie command on your PATH, build first and then link the workspace package:
npm run build
npm link --workspace @pie-lab/coding-agent
pieYou can also install the published CLI package directly:
npm install -g --ignore-scripts @pie-lab/coding-agent
pieFor this repository, the source checkout is the recommended path because the dashboard, server, chat bridge, and Learning Loop changes live together.
You need at least one usable provider before the agent or API server can answer model requests.
Common options:
- Use the CLI
/loginflow insidepie. - Add provider connections from the dashboard
Providerspage. - Export API keys such as
OPENAI_API_KEY,ANTHROPIC_API_KEY,GEMINI_API_KEY,OPENROUTER_API_KEY,GROQ_API_KEY, or other provider-specific variables supported bypackages/ai. - Use
claude-code-adk/*models when you want the local Claude Code login/subscription path instead of Anthropic API keys.
Provider connection and usage state is stored under:
~/.pie/agent/CLI and server usage records share ~/.pie/agent/usage.jsonl by default. Set PIE_LAB_USAGE_PATH when you want the dashboard/server to read a different usage file.
You can start the main development stack with:
npm run devBefore starting, this command clears pie-lab's fixed development ports 4873, 4876, and 4877 so stale server, dashboard, or chat processes do not cause EADDRINUSE errors. To skip that cleanup, run npm run dev:start instead or set PIE_DEV_SKIP_PORT_CLEANUP=1.
That starts package watchers plus:
| Service | URL |
|---|---|
| API server | http://127.0.0.1:4873 |
| Dashboard | http://127.0.0.1:4876 |
| Pie Chat web UI | http://127.0.0.1:4877 |
You can also run each app separately:
npm --workspace @pie-lab/server run dev
npm --workspace @pie-lab/dashboard run dev
npm --workspace @pie-lab/pie-chat run devThe dashboard uses NEXT_PUBLIC_PIE_API_BASE_URL when you need a different API server:
NEXT_PUBLIC_PIE_API_BASE_URL=http://127.0.0.1:4873 npm --workspace @pie-lab/dashboard run devPie Chat uses the same variable:
NEXT_PUBLIC_PIE_API_BASE_URL=http://127.0.0.1:4873 npm --workspace @pie-lab/pie-chat run devFrom the repository:
./pie-test.shWith a linked or globally installed CLI:
pieUseful commands inside the TUI:
| Command | Purpose |
|---|---|
/login |
Add provider credentials |
/models |
Select or inspect models |
/config |
Edit runtime settings |
/reload |
Reload settings, extensions, skills, prompts, and themes |
/chat-config |
Configure Telegram/Discord accounts and channels |
/chat-connect |
Connect the current pie session to a chat channel |
/chat-status |
Inspect chat bridge state |
Project settings already register apps/chat as a local package, so running pie from the repository root loads the chat bridge commands automatically.
Start the server:
npm --workspace @pie-lab/server run devExample OpenAI-compatible request:
curl http://127.0.0.1:4873/v1/chat/completions \
-H 'content-type: application/json' \
-d '{
"model": "auto:chat",
"messages": [
{ "role": "user", "content": "Say hello from pie-lab." }
]
}'Useful operational endpoints include:
GET /usageGET /usage/summaryGET /providersGET /provider-connectionsGET /routing-policyGET /learning
The dashboard uses the same local API.
Start:
npm --workspace @pie-lab/dashboard run devOpen:
http://127.0.0.1:4876Main pages:
Overview: router and system summaryProviders: provider status, connection CRUD, OAuth/login flowsUsage: request records, origin/endpoint grouping, cost and token totalsQuota: quota snapshots and account availabilityRouting: aliases, intents, combo policies, route previewsProxy: proxy pools and provider connection bindingsMedia: embeddings, web fetch/search, audio, image endpoint testsLearning: memory, background review proposals, and skill curator operationsLogs: recent operational records
Start the API server first, then the chat app:
npm --workspace @pie-lab/server run dev
npm --workspace @pie-lab/pie-chat run devOpen:
http://127.0.0.1:4877Pie Chat requests are recorded with clientOrigin=pie-chat:web, so the dashboard can separate browser chat usage from CLI and bridge usage.
There are two ways to connect Telegram or Discord.
pie gatewayis the recommended long-running process. It runs without an open TUI session and also ticks scheduled cron jobs.- The bridge extension from
apps/chat/extensionis still available when you want a live localpiesession connected to a channel.
The extension bridge is not the Next.js web server.
Because .pie/settings.json registers ../apps/chat, a normal pie session from the repository root loads the bridge commands:
pieConfigure accounts and channels:
/chat-configConnect the current session to one configured channel:
/chat-connectOr connect directly:
/chat-connect telegram-pio/dm-donghak-kimFor long-running workers:
/chat-spawn-all
/chat-workers
/chat-open-allWorker mode requires tmux and a pie command on PATH because tmux workers launch pie directly. The pie executable comes from @pie-lab/coding-agent; the chat bridge itself is loaded from apps/chat through .pie/settings.json.
If you are using only ./pie-test.sh, link the local CLI first:
npm run build
npm link --workspace @pie-lab/coding-agentFor one-off bridge testing without project settings, load the chat extension explicitly:
pie -e apps/chatChat bridge state is stored in:
~/.pie/agent/chat/More details are in docs/chat-usage.md.
pie gateway is the Hermes-style always-on process for external chat and scheduled automations. It uses the same config file as /chat-config:
~/.pie/agent/chat/config.jsonConfigure channels either from the TUI with /chat-config or from the CLI:
pie gateway setupRun it in the foreground:
pie gateway runCheck or stop it:
pie gateway status
pie gateway stopConfigure OpenAI audio for gateway STT/TTS without exporting keys every time:
pie gateway audio set
pie gateway audio status
pie gateway audio removeInstall it as a user service:
pie gateway install
pie gateway restart
pie gateway uninstallOn macOS this creates a LaunchAgent. On Linux this creates a systemd user service. While the gateway is running, Telegram/Discord messages can start full Pie agent turns with router usage tracking, Learning Loop tools, global/project skills, chat history, file attachments, and cronjob scheduling. Cron jobs that use deliver: "origin" reply back to the chat where they were created.
Periodic nudge: Set nudgeIntervalMinutes on a channel in ~/.pie/agent/chat/config.json to have the gateway automatically trigger a proactive agent turn after that many minutes of user inactivity. The agent can use [SILENT] to suppress delivery if there is nothing useful to say.
Scheduled jobs (pie cron):
pie cron status # shows gateway running state + job summary
pie cron create # --schedule "0 9 * * *" --timezone "Asia/Seoul" ...
pie cron listKey scheduler features:
- IANA timezone support for cron expressions (
--timezone "Asia/Seoul") - Grace window: missed runs are fast-forwarded instead of executed late
- Wake-gate: script can output
{"wakeAgent":false}to skip LLM and deliver stdout directly - Separate timeouts:
scriptTimeoutSeconds(default 120s) andtimeoutSeconds(agent, default 600s) [SILENT]prefix in agent response skips delivery silently
pie-lab includes a Hermes-style Learning Loop adapted to the pie runtime.
The request flow is:
user request
-> local memory + skill index
-> pie agent turn
-> assistant response
-> background learning review
-> memory update / skill proposal or write
-> next turn can reuse itImportant paths:
~/.pie/agent/memories/MEMORY.md
~/.pie/agent/memories/USER.md
~/.pie/agent/skills/<skill>/SKILL.md
.pie/skills/<project-skill>/SKILL.mdThe dashboard Learning page can inspect memory, review records, proposal approve/reject actions, and skill curator runs.
Skill Curator Consolidation: After a configurable interval (default 7 days), the curator runs an LLM pass to identify clusters of narrow skills (e.g. gateway-auth-*), merge them into an umbrella skill, and archive the siblings. Run manually with pie curator consolidate.
| Path | Meaning |
|---|---|
~/.pie/agent/settings.json |
Global CLI settings |
.pie/settings.json |
Project settings for this repository |
~/.pie/agent/auth.json |
Local provider auth storage |
~/.pie/agent/provider-connections.json |
Provider connection/account selection state |
~/.pie/agent/usage.jsonl |
Usage/cost records |
~/.pie/agent/chat/config.json |
Telegram/Discord bridge config |
~/.pie/agent/memories |
Persistent memory files |
~/.pie/agent/skills |
Agent-created global skills |
| Command | What it does |
|---|---|
npm install |
Install workspace dependencies |
npm run build |
Build packages, server, dashboard, and chat |
npm run dev |
Clear fixed dev ports, then run core watchers plus server, dashboard, and chat |
npm run dev:start |
Run the dev stack without clearing existing ports |
npm run dev:clean-ports |
Stop listeners on 4873, 4876, and 4877 |
npm run check |
Format/lint/type-check plus browser smoke check |
npm test |
Run workspace tests |
./test.sh |
Run tests with API credentials hidden |
./pie-test.sh |
Run the source CLI without linking |
npm --workspace @pie-lab/pie-chat run check:bridge |
Type-check Telegram/Discord bridge code |
npm run dev clears the fixed pie-lab ports before starting:
4873 API server
4876 dashboard
4877 Pie ChatIf you started apps separately and only want to clear those ports, run:
npm run dev:clean-portsIf another non-pie process intentionally uses one of those ports, stop it yourself or run the individual app with a different port instead of using the root npm run dev.
Run from the repository root and check that project packages are visible:
pie listYou should see:
Project packages:
../apps/chatIf a pie session was already open, run /reload or restart the session.
Check connection status:
/chat-status
/chat-workersRestart workers:
/chat-spawn-all --restartInspect logs:
find ~/.pie/agent/chat -name channel.jsonl -print
tail -n 80 ~/.pie/agent/chat/accounts/<account>/channels/<channel>/channel.jsonl
tmux lsRemember: messages typed directly into the local terminal only reply in the terminal. To send a reply back to Telegram or Discord, the turn must start from the remote chat.
Clear the Next cache and restart the dashboard:
rm -rf apps/dashboard/.next
npm --workspace @pie-lab/dashboard run devThe dashboard dev script uses webpack mode for a more stable local HMR loop after folder renames.
Add at least one provider credential using /login, dashboard Providers, or environment variables. Then reload the session or restart the server.
- docs/README.md: documentation index
- docs/current-decisions.md: current architecture and decisions
- docs/learning-loop.md: memory, skills, Honcho, curator
- docs/chat-usage.md: Pie Chat and bridge guide
- docs/gateway.md: long-running Telegram/Discord gateway and scheduler delivery
- docs/gateway-audio.md: Hermes-scoped gateway STT/TTS, OpenAI audio key setup, and Discord voice
- docs/discord-gateway-setup.md: Discord bot setup through gateway connection
- docs/chat-e2e-checklist.md: Telegram/Discord verification checklist
- docs/usage-accounting.md: usage and cost records
- docs/deployment.md: npm and GitHub Pages deployment
- docs/origins.md: source origins and imported baselines
pie keeps the original pi spirit, but in this project it expands toward Passive Income Engineering: reusable agents, repeatable workflows, routing discipline, and automation that can keep working after the first manual effort.
The CLI command is pie. The local config root is ~/.pie/agent, and project config lives in .pie/.
MIT