Files
Sybil-2/server/README.md
T

133 lines
5.0 KiB
Markdown
Raw Normal View History

2026-02-13 22:43:55 -08:00
# Sybil Server
Backend API for:
2026-07-11 14:16:21 -07:00
- LLM multiplexer (OpenAI Responses / Anthropic / xAI Chat Completions-compatible Grok / Gemini / Hermes Agent)
2026-02-13 22:43:55 -08:00
- Personal chat database (chats/messages + LLM call log)
## Stack
- Node.js + TypeScript
- Fastify (HTTP)
- Prisma + SQLite (dev)
## Quick start
```bash
cp .env.example .env
npm run dev
```
2026-02-13 23:15:12 -08:00
Migrations are applied automatically on server startup (`prisma migrate deploy`).
2026-02-13 22:43:55 -08:00
Open docs: `http://localhost:8787/docs`
2026-02-14 21:20:14 -08:00
API contract docs for clients:
- `../docs/api/rest.md`
- `../docs/api/streaming-chat.md`
2026-02-13 23:15:12 -08:00
## Run Modes
- `npm run dev`: runs `src/index.ts` with `tsx` in watch mode (auto-restart on file changes). Use for local development.
- `npm run start`: runs compiled `dist/index.js` with Node.js (no watch mode). Use for production-like runs.
Both modes run startup checks (`predev` / `prestart`) and apply migrations at app boot.
2026-02-13 22:43:55 -08:00
## Auth
Set `ADMIN_TOKEN` and send:
`Authorization: Bearer <ADMIN_TOKEN>`
If `ADMIN_TOKEN` is not set, the server runs in open mode (dev).
## Env
- `OPENAI_API_KEY`
- `ANTHROPIC_API_KEY`
- `XAI_API_KEY`
2026-07-11 14:16:21 -07:00
- `GEMINI_API_KEY`
2026-05-04 21:52:39 -07:00
- `HERMES_AGENT_API_BASE_URL` (`http://127.0.0.1:8642/v1` by default; include the `/v1` suffix)
- `HERMES_AGENT_API_KEY` (enables the Hermes Agent provider; set to Hermes `API_SERVER_KEY`, or any non-empty value if that local server does not require auth)
- `HERMES_AGENT_MODEL` (optional fallback/override model id; defaults client-side to `hermes-agent`)
2026-02-13 23:49:55 -08:00
- `EXA_API_KEY`
2026-07-19 21:35:47 -07:00
- `BRAVE_SEARCH_API_KEY` (required when `CHAT_WEB_SEARCH_ENGINE=brave`)
- `CHAT_WEB_SEARCH_ENGINE` (`exa` by default; `brave` and `searxng` are also supported for chat tool calls only)
2026-05-02 18:14:41 -07:00
- `SEARXNG_BASE_URL` (required when `CHAT_WEB_SEARCH_ENGINE=searxng`; instance must allow `format=json`)
2026-05-02 21:44:32 -07:00
- `CHAT_MAX_TOOL_ROUNDS` (`100` by default; maximum model/tool result cycles per chat completion)
2026-07-11 14:16:21 -07:00
- `CHAT_CODEX_TOOL_ENABLED` (`false` by default; enables the `codex_exec` chat tool for managed-tool providers)
2026-05-02 19:38:15 -07:00
- `CHAT_CODEX_REMOTE_HOST` (required when Codex tool is enabled; SSH host/IP or `user@host`)
- `CHAT_CODEX_REMOTE_USER` (optional SSH user when host does not include one)
- `CHAT_CODEX_REMOTE_PORT` (`22` by default)
- `CHAT_CODEX_REMOTE_WORKDIR` (`/workspace/sybil-codex` by default; created and reused on the devbox)
- `CHAT_CODEX_SSH_KEY_PATH` (recommended: path to a read-only mounted private key)
- `CHAT_CODEX_SSH_PRIVATE_KEY_B64` (optional fallback private key delivery)
- `CHAT_CODEX_EXEC_TIMEOUT_MS` (`600000` by default)
2026-07-11 14:16:21 -07:00
- `CHAT_SHELL_TOOL_ENABLED` (`false` by default; enables the `shell_exec` chat tool for managed-tool providers on the same devbox)
2026-05-02 19:52:09 -07:00
- `CHAT_SHELL_EXEC_TIMEOUT_MS` (`120000` by default)
2026-02-13 22:43:55 -08:00
## API
- `GET /health`
2026-02-13 23:15:12 -08:00
- `GET /v1/auth/session`
2026-02-13 22:43:55 -08:00
- `GET /v1/chats`
- `POST /v1/chats`
- `GET /v1/chats/:chatId`
- `POST /v1/chats/:chatId/messages`
- `POST /v1/chat-completions`
- `POST /v1/chat-completions/stream` (SSE)
2026-02-13 23:49:55 -08:00
- `GET /v1/searches`
- `POST /v1/searches`
- `GET /v1/searches/:searchId`
- `POST /v1/searches/:searchId/run`
2026-02-14 21:20:14 -08:00
- `POST /v1/searches/:searchId/run/stream` (SSE)
2026-02-13 22:43:55 -08:00
2026-02-14 00:14:10 -08:00
Search runs now execute both Exa `searchAndContents` and Exa `answer`, storing:
- ranked search results (for result cards), and
- a top-level answer block + citations.
2026-02-13 23:15:12 -08:00
When `chatId` is provided to completion endpoints, you can send full conversation context. The server now stores only new non-assistant messages to avoid duplicate history rows.
2026-02-13 22:43:55 -08:00
`POST /v1/chat-completions` body example:
```json
{
"chatId": "<optional chat id>",
"provider": "openai",
"model": "gpt-4.1-mini",
"messages": [
{"role":"system","content":"You are helpful."},
{"role":"user","content":"Say hi"}
],
"temperature": 0.2,
"maxTokens": 256
}
```
## Next steps (planned)
- Better streaming protocol compatibility (OpenAI-style chunks + cancellation)
- Tool/function calling normalization
- User accounts + per-device API keys
- Postgres support + migrations for prod
- Attachments + embeddings + semantic search
## Sybil Agent
Configure the backend with:
```dotenv
SYBIL_AGENT_BASE_URL=http://sybil-agent:8788
SYBIL_AGENT_API_KEY=<the Sybil Agent service API key>
```
Use the same `SYBIL_AGENT_API_KEY` value configured on the agent service.
The base URL defaults to `http://sybil-agent:8788` and has no `/v1` suffix. In Docker,
attach Sybil's **server** container and Sybil Agent to the shared `agents` network so that
`sybil-agent` resolves privately. Supply the key through a private server environment
file; it is never a `VITE_*` variable or browser setting. Keep the existing Sybil
`ADMIN_TOKEN` authentication for clients.
The Sybil Agent tab uses `/v1/agent`, `/v1/agent/messages`, and `/v1/agent/ws` to proxy the
same persistent root conversation across devices. Sybil Agent remains the source of
truth for messages and background replies. Sybil stores only the shared,
monotonically increasing read cursor in SQLite through `/v1/agent/read-state`;
its migration is applied automatically at startup. The bundled nginx configuration
forwards WebSocket upgrades. See `docs/api/rest.md` and
`docs/api/streaming-chat.md` at the repository root for the client contracts.