AI-augmented IT ops workbench — spec-driven, multi-provider, multi-user, local-first
中文版:README.zh-CN.md
OpsPilot turns raw IT work items — incidents, service requests, tasks — into structured, KB-cited suggestions through a playbook-driven AI pipeline, and closes the loop with the tools you already use: it polls new tickets straight from Jira Service Management and posts the suggestion back as a comment, and files a Telegram message as a work item with a single command. It runs fully local with Ollama or against any major cloud provider, and every run leaves an auditable trail: PII is redacted before anything reaches a model, output is validated against a strict JSON Schema, and each session archives a content-addressed artifact plus an append-only trace.
AI is reshaping the IT-support industry. OpsPilot is a working answer to a concrete question: given what today's LLMs can actually do, what does a practical work-assistance layer for IT support look like?
- Today's models are already good enough to draft incident summaries, decompose work into routable tasks, and pull up the right runbook — if every claim is grounded in a knowledge base and every run is auditable. That grounding and auditability are exactly what OpsPilot builds.
- Model capability keeps compounding, and OpsPilot is built to ride that curve rather than chase it: playbooks pin model versions, a regression harness gates every upgrade, and the spec-driven contracts make adopting a stronger model a config change, not a rewrite.
- The human stays in charge: OpsPilot suggests severities, tiers, and actions; your system of record — and your engineers — make the decisions.
- Multi-provider — Anthropic Claude, OpenAI, OpenRouter, Gemini, xAI Grok, or local Ollama; playbooks declare a primary model plus selectable alternates (down to a local Gemma), switchable per-run from the UI or set as a team default in the admin module, with automatic fallback when a provider errors. Admins can curate the selectable list itself — remove or upgrade models — from the admin module, editing the playbook in place. Embeddings default to OpenAI, with local Ollama a one-variable switch away for teams that keep them in-house. Playbooks can route by complexity, sending the easy majority to a cheap tier and escalating only what needs it
- Work-item intake — pull tickets straight from Jira Service Management
on a JQL scope and post the AI suggestion back as a comment on the ticket:
polling-only (no public endpoint), comment-only (no field is ever touched),
restart-safe state, and a
--replaymode that demos the whole loop offline; intake can run on a cheaper model than interactive use, and remote deployments can push instead viaPOST /api/intake - KB retrieval with citations — hybrid vector (LanceDB) + full-text
(SQLite FTS5) search fused with RRF;
toolmode (ReAct) for strong models,prefetchinjection for weak local ones - Asset inventory — procurement-to-retirement tracking for the devices your team manages, and the one domain OpsPilot owns rather than mirrors: small teams have no CMDB, so CSV import/export is the migration path in and out. Eight free-set statuses (no state machine — real inventories are full of corrections), an append-only event log whose actor comes from the authenticated caller, and a fulfillment playbook that drafts Assets straight from a Service Request
- Runtime Skills — reusable
SKILL.mdpackages the assistant loads on demand: it sees a compact catalog of triggers and pulls in the full procedure when a problem matches, with retrieval-injection fallback for models too weak to call tools. Admins can have one drafted from a problem description and edit it before saving - Redaction first — PII stripped before any content reaches a model or the KB
- Auditable sessions — content-addressed artifacts, append-only traces, schema-validated output, browsable history. Who acted is taken from the authenticated caller, never from what the caller claims
- Sandboxed actions — AI-proposed shell actions run in hardened Docker (L2) or gVisor (L3, fail-closed) containers; an approval gate flags risky patterns for human sign-off
- Compounding wiki — session insights distilled into lint-checked, lifecycle-managed wiki pages on top of the long-term KB
- MCP client — tools from any Model Context Protocol server (stdio/HTTP) injected into the ReAct loop, with per-server allow/denylists
- Interfaces & channels — CLI, REPL terminal UI (Textual, slash
commands), tabbed web UI (Svelte 5) with KB-augmented chat, FastAPI
backend; a Telegram channel brings the KB chat into your messenger and
files work items with
/intake; WeCom connects both ways — a group robot pushes intake suggestions (notify), and a self-built app answers KB questions in chat (assist) - Multi-user & SSO — login-gated web UI with three roles
(viewer / operator / admin); authenticate against local accounts,
LDAP / Active Directory, or OIDC SSO, with group→role mapping and an
admin module for users, roles, provider status, and audit. Machine
callers (channels, intake) use a Service token; secrets stay in the
environment, never the database. Ships as an all-in-one Docker image —
one
docker runis a complete, login-gated workbench - Observability — Prometheus
/metrics, OTel-compatible JSON logs,/health - Rust hot paths — chunker (~10×) and tokenizer (~45×) compiled via PyO3/maturin, with a transparent Python fallback; CI enforces ≥5×
The web UI — dark-first, sidebar-navigated, every answer cited back to the KB:
The terminal UI — a REPL with slash commands over the same backend:
- Python 3.12+
- An
OPENAI_API_KEYfor embeddings, or Ollama to keep them local (see Embeddings) - Node.js 18+ and pnpm (for the web UI)
git clone https://github.com/vicenteliu/OpsPilot.git
cd OpsPilot
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"Optional but recommended — Rust extensions (~10–45× faster chunker/tokenizer; requires rustup):
make rust-devSkip this if you are using cloud models with OpenAI embeddings.
ollama pull nomic-embed-text-v2-moe # embeddings; needs OPSPILOT_EMBED_PROVIDER=ollama
ollama pull gemma4:e4b # local chat model (optional fallback)cp .env.example .env
# Edit .env — two independent choices:
# Chat ANTHROPIC_API_KEY (or another cloud key). No cloud key? Pick the
# local Gemma model from the UI dropdown — retrieval switches to
# prefetch automatically so weak models still cite the KB.
# Embedding OPENAI_API_KEY, used by default. To keep embeddings local
# instead, set OPSPILOT_EMBED_PROVIDER=ollama (step 2).Step 4 needs a working embedder: with neither an OpenAI key nor a reachable Ollama, ingest fails and says so.
# Sample English KB (SOPs and runbooks) shipped with the repo:
opspilot ingest examples/sample_data_en/kb/
# Or point it at your own directory of markdown and PDF documents.Markdown and PDF work out of the box. DOCX, PPTX, and XLSX are routed to
markitdown but need its matching extras, which this repo does not pin
(markitdown[pdf]) — without them the ingest fails with a converter error.
opspilot tui # terminal UI workbench
opspilot serve --reload --with-ui # API + web UI → http://localhost:5173Then see the whole intake loop offline — no ticket system needed:
opspilot source jsm --replay tests/fixtures/jsm_replay/
cat intake_comments/IT-101.md # the suggestion a real ticket would getFrom here: submit a work item on the Run tab, ask the KB a question on
the Chat tab, connect a Telegram channel to chat
with your KB (or file a work item with /intake) from your phone, or point
intake at your Jira Service Management project — a
free-tier site connects in about ten minutes — so new tickets get summarised
and commented automatically.
The image bundles the built web UI, so a single container is a complete, login-gated workbench (docs/deployment.md):
docker build -t opspilot:latest .
docker run -p 8000:8000 \
-e OPSPILOT_API_TOKEN="$(openssl rand -hex 32)" \
-e OPSPILOT_BOOTSTRAP_ADMIN=admin -e OPSPILOT_BOOTSTRAP_PASSWORD='<strong-pw>' \
-e ANTHROPIC_API_KEY=sk-ant-... \
-e OPENAI_API_KEY=sk-... \
-v opspilot-data:/home/opspilot/.opspilot \
opspilot:latest serve --host 0.0.0.0 --port 8000
# → http://localhost:8000, sign in as the bootstrap adminThe container needs no Ollama: ANTHROPIC_API_KEY answers chat and
OPENAI_API_KEY embeds. To use a host Ollama instead, add
-e OPSPILOT_EMBED_PROVIDER=ollama -e OPSPILOT_OLLAMA_BASE_URL=http://host.docker.internal:11434.
For a multi-service deployment (nginx TLS termination, JSM intake, optional Ollama), see Docker Compose.
Every run: redact → retrieve → generate → validate against JSON Schema → archive. See docs/architecture.md for the full request flow, the six-layer system design, provider routing, and retrieval modes.
| Document | Contents |
|---|---|
| docs/architecture.md | Request flow, layer design, provider routing, retrieval modes |
| docs/cli.md | TUI, harness, sandbox, MCP, and wiki command reference |
| docs/deployment.md | Docker Compose, systemd, observability, configuration |
| docs/channels.md | Messaging channels — Telegram setup: KB chat + /intake |
| docs/sources.md | Work-item intake — JSM setup, replay mode, state and reruns |
| docs/inventory.md | Asset model, statuses, event log, CSV migration, REST surface |
| docs/verification.md | Post-deployment checks for LDAP, OIDC, WeCom and the all-in-one image |
| docs/specs/ | Spec contracts: schemas + templates (loaded at runtime) |
| docs/adr/ | Architecture decision records |
| CONTEXT.md | Domain glossary — the canonical name for every concept above |
| ROADMAP.md | What is shipped, what is open, what is deferred |
| CONTRIBUTING.md | Dev setup, quality gates, PR conventions |
| SECURITY.md | Deployment model, threat model, reporting vulnerabilities |
- Multi-user with three roles (viewer / operator / admin) via local accounts, LDAP/AD, or OIDC SSO. Loopback dev stays friction-free; remote binding is fail-closed on a token, with TLS in front; machine callers use a Service token (ADR-0020, ADR-0011, SECURITY.md)
- Secrets stay in the environment — cloud API keys and LDAP/OIDC credentials are read from env vars, never committed and never stored in the database; the admin module shows status, not secrets
- The redaction layer strips PII from structured work items, but always sanitize manually before pasting content into any model or tool
- Session traces and all state stay local under
~/.opspilot/



