Skip to main content

Universal TUI agent for autonomous research and writing, powered by llama.cpp

Project description

Scribe

๐ŸŒ English ยท ็ฎ€ไฝ“ไธญๆ–‡

CI Python 3.10+ License: MIT

Local-first chat + research + coding agent. Connects to any OpenAI-compatible server (llama.cpp, Ollama, LM Studio, or a cloud API key) and uses web search, RAG and semantic memory to research, write, and remember โ€” across sessions. Runs comfortably on a 12 GB VRAM machine with Gemma 4 12B at 128k context.

Why Scribe

Three properties that hold by construction, not by prompt-tuning:

  1. The tool call cannot break. On a llama.cpp server Scribe enforces tool calls with a GBNF grammar generated from the tool schemas โ€” a malformed call is grammatically impossible, and a model that fumbles is re-asked under the grammar. (scribe/grammar.py)
  2. Answers cite their sources, or say they can't. Grounded Q&A maps every claim to a numbered source [n], tags [CONTRADICTION] when sources disagree, and refuses to answer outside the sources. (scribe/prompts.py)
  3. Grounding is measured, not asserted. scribe bench reports a deterministic Source-Presence Index (SPI) over a checksum-locked held-out suite โ€” on Gemma 4 12B it scores SPI 1.00. (scribe/evolve/spi.py)

Honest scope: GBNF and constrained decoding aren't new โ€” llama.cpp added grammars in 2023, and the same idea ships elsewhere as "structured outputs". Scribe's contribution is the integration: auto-generating the grammar from your tool schemas and wiring it as an automatic tool-call safety net for small local models. Guarantees 1โ€“3 hold on llama.cpp; other backends degrade to a best-effort text parser. The grammar guarantees a call's form, not the model's judgment (it can still pick the wrong tool โ€” it just can't emit a malformed one).

๐Ÿ“– Full overview on the project site.

Features

  • Universal LLM Adapter โ€” llama.cpp, Ollama, LM Studio, or any OpenAI-compatible cloud API (OpenRouter, Groq, ...) โ€” see docs/providers.md
  • GBNF Tool Enforcement โ€” grammar-constrained tool calls on llama.cpp; auto-repair when a model emits a malformed call
  • Grounded Q&A โ€” hybrid retrieval (FTS5 + vectors, RRF) with mandatory citations and contradiction tagging
  • Quality Gate โ€” scribe bench runs a judge-scored fitness suite and the deterministic SPI grounding metric
  • Safe Code Mode โ€” /code with a destructive-command gate, Python AST gate, bubblewrap sandbox, and git checkpoint/rollback
  • Internet Research โ€” web_search + web_fetch tools; DuckDuckGo out of the box, Brave with a key
  • Writing Agent โ€” deep-research and writer skills for books, papers and reports, with sandboxed workspace file tools
  • Book Studio (web) โ€” dark, VSCode-style web editor: three resizable panes, an integrated terminal, model-drafted table of contents, chapter-by-chapter writing, and Markdown / EPUB / PDF export
  • Open Knowledge Format โ€” scribe wiki distill curates sessions into portable OKF markdown (YAML frontmatter + index.md/log.md + links); SME/RAG are derived indexes over the files
  • Persistent Self โ€” a WorldModel persona injected into every prompt, plus pulse heartbeat and nightly diary
  • Observability โ€” ORORO session traces and a machine-readable scribe status --json contract
  • Project Vaults โ€” scribe init gives a directory its own isolated RAG/SME stores
  • Model Discovery & Blind Compare โ€” auto-find local servers; A/B two models without bias
  • Cross-Session Memory โ€” SME (Semantic Memory Engine) for seamless session continuity
  • Email Bridge โ€” get results by email and send commands from one approved address (stdlib only)
  • Language games โ€” explicit command vocabularies (Wittgenstein-inspired) for stable LLM behavior

Installation

From PyPI

pip install scribe-llm       # provides the `scribe` command

The PyPI distribution is named scribe-llm (the import package and CLI stay scribe).

From source (๐Ÿง Linux / ๐ŸŽ macOS)

# Clone the repository
git clone https://github.com/pedjaurosevic/scribe-ai.git
cd scribe-ai

# Run the install script: installs the package (editable), creates the
# config, and scaffolds ~/scribe-workspace.
./scripts/install.sh

๐ŸชŸ Windows (WSL)

scribe chat and the scribe web Book Studio run on native Windows too; only the web UI's integrated terminal needs a POSIX PTY (it degrades gracefully without one). For the full experience, run Scribe via WSL (Windows Subsystem for Linux).

  1. Open your WSL terminal (e.g., Ubuntu).
  2. Run the Linux installation commands shown above.
  3. To configure Scribe to work with Ollama (either running natively on Windows or inside WSL), check out the WSL & Ollama Integration Guide.

Or install by hand (skip the script):

pip install -e .

Requires Python 3.10+. The install is editable, so git pull updates Scribe in place.

Quick Start

  1. Start your llama-server:
./scripts/start-server.sh
  1. Start Scribe:
scribe chat
  1. Scribe will automatically recall your last session and ask if you want to continue.

Configuration

Edit ~/.config/scribe/config.toml:

[scribe]
base_url = "http://127.0.0.1:18083/v1"   # llama.cpp / Ollama / LM Studio / cloud
model = "default"                         # auto-detects the loaded model
api_key = "not-needed"                    # set a real key for cloud providers

Or use environment variables:

export SCRIBE_BASE_URL=http://localhost:11434/v1   # e.g. Ollama
export SCRIBE_MODEL=gemma4:12b
export SCRIBE_API_KEY=sk-...                       # cloud providers only

Full provider guide โ€” llama.cpp, Ollama, LM Studio, OpenRouter/Groq, plus a recipe for Gemma 4 12B with 128k context on a 12 GB GPU: docs/providers.md.

Web search needs no setup (DuckDuckGo). For Brave Search, set BRAVE_API_KEY or brave_api_key under [scribe].

CLI Commands

scribe chat                    # Interactive TUI chat (streaming by default)
scribe chat --textual          # Full-screen Textual UI (experimental)
scribe chat --resume TAG       # Resume a past session (no TAG = last one)
scribe web                     # Book Studio web UI at http://localhost:8765 (localhost-only by default)
scribe web --host 0.0.0.0      # Expose on the network (prints a warning โ€” the UI has a shell terminal)

scribe memory recall "query"  # Recall from semantic memory
scribe rag search "query"     # Hybrid search (FTS5 + vectors); --semantic-only to opt out
scribe rag ask "question"     # Grounded Q&A โ€” answers cite sources or refuse
scribe rag reindex             # Rebuild the lexical (FTS5) index
scribe session last            # Show last session
scribe session list            # List all sessions
scribe session search "query" # Full-text search across all session transcripts

scribe init [DIR]              # Create a project-local vault (config + ./.scribe)
scribe discover [--tailscale]  # Find OpenAI-compatible model servers
scribe compare "q" --a M1 --b M2  # Blind A/B two models on one prompt
scribe bench [--fitness|--spi] # Quality gate: judge fitness + SPI grounding
scribe trace [ID] [--json]     # Show a session's ORORO trace

scribe pulse                   # Record one heartbeat (wire to a systemd timer)
scribe diary                   # Reflect on today's sessions
scribe remember "fact"        # Add a durable fact to the WorldModel

scribe config show             # Show current config
scribe status [--json]         # System status (--json = machine-readable contract)
scribe evolve eval             # Run the held-out fitness suite (Phase 0)

scribe mail send "Subj" "Body" # Email yourself a notification
scribe mail watch              # Accept commands by email (see below)

Email bridge

Scribe can email you results and accept commands by email โ€” using only the Python standard library (no extra dependencies).

[scribe.email]
enabled = true
address = "you@gmail.com"
approved_sender = "you@gmail.com"   # the ONLY address allowed to command Scribe
secret = "pick-a-token"             # must appear in command subjects
export SCRIBE_EMAIL_PASSWORD="your-gmail-app-password"   # never in the config file

scribe mail send "Done" "The report is ready."   # send a notification
scribe mail watch                                 # poll inbox, run commands, reply

To run a command, email yourself with the secret in the subject:

Subject: [scribe:pick-a-token] summarize the notes in research/

Scribe runs it with the sandboxed workspace tools (read/write/list files, no shell) and replies with the answer.

Security: commands are accepted only when both the sender matches approved_sender and the subject carries [scribe:secret]. Since From: headers can be spoofed, the secret is the real gate โ€” leave it empty to keep command intake off (sending still works). Gmail requires an App Password (with 2-Step Verification enabled).

Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚              SCRIBE TUI                  โ”‚
โ”‚           (Rich-based interface)          โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚              CORE KERNEL                 โ”‚
โ”‚  Session Manager โ”‚ Skills โ”‚ Config       โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚           LLM ADAPTER LAYER              โ”‚
โ”‚    OpenAI-compatible (llama.cpp)         โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚             MEMORY LAYER                 โ”‚
โ”‚  SME (cross-session) โ”‚ RAG (documents)  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚              TOOLS LAYER                 โ”‚
โ”‚   web_search โ”‚ web_fetch โ”‚ bash         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Philosophy

Language games (Wittgenstein-inspired). Each command word has a fixed, explicit meaning, so the model knows exactly what each action means. Reasoning, when enabled, stays in a <think> block and never leaks into the answer; by default Scribe answers directly.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

scribe_llm-0.5.0.tar.gz (189.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

scribe_llm-0.5.0-py3-none-any.whl (146.7 kB view details)

Uploaded Python 3

File details

Details for the file scribe_llm-0.5.0.tar.gz.

File metadata

  • Download URL: scribe_llm-0.5.0.tar.gz
  • Upload date:
  • Size: 189.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for scribe_llm-0.5.0.tar.gz
Algorithm Hash digest
SHA256 73685e2e9d904941e8fa42f25bcb3dc2e391742612577509cd7f90562965f076
MD5 2ad1b3da270424f4b6eaae31820436c3
BLAKE2b-256 a0423ce7da4531df2c1eeb42e5f0b073f8f6cf8678c63fb4ba724910f49c601c

See more details on using hashes here.

Provenance

The following attestation bundles were made for scribe_llm-0.5.0.tar.gz:

Publisher: publish.yml on pedjaurosevic/scribe-ai

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file scribe_llm-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: scribe_llm-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 146.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for scribe_llm-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b4b0b2003ec8cc81d64e3769d08ded338de04d83ac2d66fecae50dd433437e6e
MD5 b25fc5d39de9ffb41ca92bc1fbd3e26d
BLAKE2b-256 87702664d5a5a4a9f909ba6094851659d310c4f7d14de4e5acb051e0633f54ca

See more details on using hashes here.

Provenance

The following attestation bundles were made for scribe_llm-0.5.0-py3-none-any.whl:

Publisher: publish.yml on pedjaurosevic/scribe-ai

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page