Skip to content

About

HTTP REST API for Pi AI agent.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

pi-api-facade

English | 中文

HTTP facade that exposes Pi coding agent sessions behind the frozen DAC apiproxy contract, so a DAC manager can run and operate Pi nodes exactly like DSH nodes.

Status: v0.1.0 — accepted 2026-10-03. Verified end to end against a production DAC manager with real deepseek-flash rounds: streaming chat, tool calls, history replay, per-run billing (including continued runs), and per-run git audit commits. Contract details: docs/contract-map.md · operations: docs/runbook.md · release history: CHANGELOG.md.

Architecture

DAC manager ──(frozen apiproxy contract, HTTP/WS)──> pi-api-facade (this repo)
                                                        └── Pi SDK in-process
                                                             └── AgentSession × N
  • Northbound: the same wire contract ohdsh-api-facade (dsh-api-gateway) froze for the manager — API-key auth, fail-closed method whitelist, client-request/server-response envelopes, events.mux WebSocket, respond receipts, per-session sandbox mode.
  • Southbound: the Pi TypeScript SDK (createAgentSession from @earendil-works/pi-coding-agent, version pinned by the DAC version matrix). One facade process hosts all sessions of one node concurrently.

Quick start (Docker, standalone stack)

cp .env.example .env         # fill DEEPSEEK_API_KEY + PI_FACADE_API_KEYS (openssl rand -hex 16)
mkdir -p workspaces
docker compose up -d --build
node scripts/compose-smoke.mjs   # wiring check (needs FACADE_URL/FACADE_KEY env; see script header)

The nginx front door on HTTP_PORT (default 8090, deliberately clear of the DAC production surface) is the only external port; it proxies /api-gw/ and 404s everything else. The facade port is not published. Session workspaces live under ./workspaces (clients pass cwd as /workspace/<name>); the node's Pi home is the agent-home volume. Full walkthrough: docs/runbook.md.

Web demos

examples/demos/compose.demos.yml adds two web demos behind the same nginx front door — KB Studio (/kb/, knowledge-base management with an AI steward pinned to workspace-write) and a Support widget (/cs/, read-only agent grounded in the same knowledge base, which is this repo's own docs). The demo apps are single-sourced in ohdsh-api-facade (the contract's reference implementation); the overlay only re-points them at the Pi facade and swaps in pi personas/doc seeds.

git clone https://github.com/litestartup-com/dsh-api-gateway ../dsh-api-gateway  # or set GATEWAY_DIR in .env
node scripts/sync-demo-docs.mjs
mkdir -p workspaces/kb workspaces/cs
docker compose -f docker-compose.yml -f examples/demos/compose.demos.yml up -d --build
DEMO_BASE=http://127.0.0.1:8090 node scripts/demo-smoke.mjs

Pi-runtime notes vs the DSH stack: question cards ride the ask_user custom tool (the model decides when to ask — cards render in both demos and in the manager); approval cards fire only in the danger tier, so the KB demo's auto-approve policy is a no-op here (the sandbox pin is the real guard).

Quick start (bare process)

npm install
npm start

Requires Node.js >= 22.19.0 (pure ESM; the Pi SDK constraint).

Configuration

All configuration is environment-driven (no config files, no secrets on disk):

Variable Default Purpose
PI_FACADE_HOST 127.0.0.1 Bind interface. Exposing beyond loopback is an ops decision.
PI_FACADE_PORT 3091 HTTP port.
PI_FACADE_PREFIX /api-gw/v1 Route prefix (matches the frozen contract).
PI_FACADE_API_KEYS — Comma-separated API keys for the northbound surface. Empty = every authenticated call is rejected (fail closed).
PI_FACADE_ENGINE — sdk boots the production Pi SDK engine (in-process, multi-session). fake boots the in-memory development engine (loud warning). Unset refuses to boot.
PI_FACADE_MODEL deepseek/deepseek-flash Default model for new sessions, as provider/model.
PI_AGENT_DIR ~/.pi/agent Pi agent home for this node (auth/models/settings/sessions). One directory per node.
PI_FACADE_ALLOW_FULL_ACCESS false Unlock the danger-full-access sandbox tier on this node.
DEEPSEEK_API_KEY — Provider credential, read by Pi at runtime. Never stored by the facade.
OPENAI_API_KEY — Native Pi credential for the built-in openai provider.
PI_OPENAI_BASE_URL — Point the node at any OpenAI-compatible endpoint (OpenAI, OneAPI/new-api proxies, vLLM, SGLang, Ollama, ...). At boot the facade synthesizes a models.json provider entry (api: openai-completions); select it with PI_FACADE_MODEL=<provider>/<model-id>.
PI_OPENAI_API_KEY — Credential for that endpoint, referenced as $PI_OPENAI_API_KEY env interpolation — it never lands on disk. Omit for key-less endpoints (Ollama).
PI_OPENAI_PROVIDER openai Provider id to synthesize. The default overrides the built-in openai endpoint and keeps its catalog model ids; a custom id requires PI_OPENAI_MODELS.
PI_OPENAI_MODELS — Comma-separated model ids the catalog lacks (e.g. vLLM-served aliases); added/replaced on the synthesized provider.

Shared vocabulary with dsh-api-gateway: every PI_OPENAI_* variable above also accepts the neutral name — OPENAI_BASE_URL, OPENAI_API_KEY, OPENAI_PROVIDER, OPENAI_MODELS (plus OPENAI_MODEL as the single-model shorthand) — and PI_FACADE_MODEL accepts FACADE_MODEL. These are the same names the sibling dsh-api-gateway standalone stack uses, so one operator — or one DAC manager wiring layer — feeds a Pi node and a DSH node the same model configuration. On conflict the PI_* name wins. One semantic note: here PI_OPENAI_MODELS adds to the provider's catalog, where the DSH stack's list replaces it — against a custom gateway you list what it serves either way.

Development

npm run check   # eslint + tsc --noEmit + node --test

The whole test suite is offline: unit tests drive a fake engine, integration tests drive the real Pi SDK against a scripted local stub provider (no keys, no external calls). CI: .github/workflows/ci.yml.

Discipline (see AGENTS.md): tests first; npm run check green before every commit; dependencies pinned to exact versions; commit messages in English.

Operation

  • docs/runbook.md — first boot, manager wiring (including the mandatory billing pin), smoke verification, restart/upgrade/rollback, troubleshooting.
  • openapi.yaml — the northbound surface as an OpenAPI 3 document (the mux WebSocket is annotated in the info description).
  • docker/ + docker-compose.yml — the standalone stack (thin runtime image; nginx front door; PI_FACADE_ENGINE=fake mode for wiring tests).
  • scripts/start-facade.ps1 — Windows launcher (per-node agent home, project trust seeding, key handling).
  • deploy/pi-api-facade.service.example — systemd unit for Linux nodes.
  • scripts/smoke-facade.mjs — wire-level smoke against a running facade with a real provider (spends tokens; manual only).
  • scripts/compose-smoke.mjs — fake-engine wiring smoke for the compose stack (no tokens, CI-safe).
  • docs/contract-map.md — the frozen contract, endpoint by endpoint, cited against the manager's consumer code.
  • The cross-implementation conformance kit lives in the gateway repo (conformance/, pinned by commit in CI): one suite both facades must pass — red there means the runtimes drifted apart on the frozen contract.

License

MIT — see LICENSE.

About

HTTP REST API for Pi AI agent.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages