Skip to main content

Terminal-based AI agent — a function-calling loop with minimum harness

Project description

Slife

Terminal-based AI agent — chat with an LLM that can execute shell commands, read and write files, search the web, call REST APIs, connect to MCP servers, spawn subagents for parallel work, communicate with other Slife instances over MQTT, and remember everything permanently.

┌────────────────────────────────────────────────────────────┐
│  Terminal UI (Textual)                                     │
│  ─────────────────────────────────────────────────────────  │
│  Agent Service — LLM + Tools + Loop + MCP + A2A + Inbox   │
│  ┌──────────┬─────────────┬──────────┬──────────────────┐  │
│  │ MCP Tool │ A2A + MQTT  │ Subagent │ Built-in Plugins │  │
│  │  Proxy   │ Mesh        │ Workers  │ ┌────┬────┬────┐ │  │
│  │          │             │          │ │MCP │Mem │WX  │ │  │
│  └──────────┴─────────────┴──────────┴─┴────┴────┴────┘─┘  │
│  Permanent Memory — hybrid search (grep + FTS5 + semantic)  │
└────────────────────────────────────────────────────────────┘

Install

Zero prerequisites. The install script auto-installs Python 3.13 and uv if needed — then installs slife in an isolated environment. No git, no Node.js, no C++ compiler required.

Option 1: Install Script (Recommended)

macOS / Linux / WSL:

curl -fsSL https://raw.githubusercontent.com/juzcn/slife/main/install.sh | bash

Windows PowerShell:

powershell -ExecutionPolicy Bypass -Command "irm https://raw.githubusercontent.com/juzcn/slife/main/install.ps1 | iex"

The script checks your Python version, installs uv if needed, downloads the latest slife, and installs it in an isolated environment. Inspect the script before piping if you prefer.

Option 2: uv tool install (requires git)

uv tool install git+https://github.com/juzcn/slife.git

Option 3: pipx (requires git)

pipx install git+https://github.com/juzcn/slife.git

Option 4: Try Before Installing

uvx --from git+https://github.com/juzcn/slife.git slife

No install — downloads, caches, and runs slife in a temporary environment.

After installation, the slife and credstore commands are available globally:

Command Location
slife ~/.local/bin/slife
credstore ~/.local/bin/credstore
Package files ~/.local/share/uv/tools/slife/
User data ~/.slife/ (auto-created on first run)

Uninstall

uv tool uninstall slife

User data (config, memory DB, WeChat sessions, credentials backup) lives in ~/.slife/. In development (when a slife.json5 exists in the current directory), data stays in the project directory for easy debugging. Delete manually if desired:

rm -rf ~/.slife                            # all user data (production)
credstore delete DEEPSEEK_API_KEY          # remove a stored secret
credstore list                             # list all stored credentials

Optional Extras

Slife keeps the default install lean. Add extras when you need them:

Extra Package What it enables
embeddings llama-cpp-python Local GGUF embeddings for semantic memory search (offline, no API cost). Without it, FTS5 keyword search still works.
mqtt paho-mqtt A2A agent mesh via MQTT (--agent <id>). Without it, subagent spawning still works — only remote-agent discovery needs MQTT.
# Install with one or both extras:
uv tool install "slife[embeddings]" --reinstall
uv tool install "slife[mqtt]" --reinstall
uv tool install "slife[embeddings,mqtt]" --reinstall

Setting Up Local Embeddings

After installing slife[embeddings], download a GGUF model and configure it:

# 1. Download a GGUF embedding model (BGE-M3, Q4_K_M quantized, ~300 MiB)
curl -LO https://huggingface.co/ChristianAzinn/bge-m3-gguf/resolve/main/bge-m3-Q4_K_M.gguf

# 2. Launch slife and tell the agent to enable it:
slife
# > enable local embeddings with bge-m3-Q4_K_M.gguf

The agent calls memory_set_embedding which writes the config and reloads the embedder — no restart needed. Verify with:

slife
# > check embedding status

Windows users: llama-cpp-python needs a pre-built wheel (no C++ compiler required). The Vulkan variant works on any GPU and falls back to CPU:

uv tool install "slife[embeddings]" --reinstall
# Then install the platform wheel into the tool's venv:
uv tool run --from slife pip install "llama-cpp-python @ https://github.com/abetlen/llama-cpp-python/releases/download/v0.3.34-vulkan/llama_cpp_python-0.3.34-py3-none-win_amd64.whl"

Alternative CUDA wheels: v0.3.34-cu132, v0.3.34-cu125; AMD: v0.3.34-hip-radeon.

Setting Up the MQTT Mesh

After installing slife[mqtt], run a Mosquitto broker and launch with an agent identity:

# Terminal 1 — start the broker (or use your existing one)
mosquitto -p 1883

# Terminal 2 — launch slife with an agent identity
slife --agent my-agent

Configure broker address in ~/.slife/slife.json5 if not using defaults (localhost:1883):

mqtt: {
  broker: { host: "my-broker.local", port: 1883 },
}

Quick Start

Store your API key and launch:

credstore set-password                # first time only — sets up encrypted backup
credstore set DEEPSEEK_API_KEY        # masked input, no echo
slife

The default config (slife.json5) ships with pre-configured MCP servers (filesystem, web fetch, DuckDuckGo search).

How It Works

Slife is a function-calling loop. You type a message → the LLM decides what tools to call → Slife executes them and returns results → the LLM responds → repeat.

You: "Find all TODO comments and create GitHub issues for them"
  → LLM calls execute_shell("rg TODO")
  → LLM calls github__create_issue(...) for each one
  → LLM: "Created 7 issues. All linked in the description above."

Configuration

Slife uses a two-layer configuration model:

Layer Storage What goes here
Secrets OS keyring (credstore) API keys, tokens, passwords — encrypted at OS level
Config ~/.slife/slife.json5env: ${VAR} references + non-secret values (EDITOR, LANG, etc.)
// slife.json5
env: {
  DEEPSEEK_API_KEY: "${DEEPSEEK_API_KEY}",   // → resolved from keyring at runtime
  EDITOR: "code",                             // → plain value, no secret
}

models: {
  providers: {
    deepseek: {
      base_url: "https://api.deepseek.com",
      api_key: "${DEEPSEEK_API_KEY}",          // ← ${VAR} syntax throughout
      models: [{ model: "deepseek-v4-pro", name: "DeepSeek V4 Pro", reasoning: true }],
    },
  },
},
active_model: "deepseek/deepseek-v4-pro",

${ENV_VAR} and ${ENV_VAR:-default} syntax works everywhere — values resolve at runtime via shell → keyring → config.

Credential Management

Slife ships with credstore — a standalone cross-platform secret manager backed by the OS keyring with AES-encrypted file backup. It has its own full documentation.

Quick reference:

credstore set-password                # first-time setup
credstore set DEEPSEEK_API_KEY        # store (masked atomic dual-write)
credstore get DEEPSEEK_API_KEY        # retrieve, masked output
credstore list                        # list all stored keys
credstore status                      # backend status
Command Description
set-password Init cryptfile, set master key
set KEY Atomic dual-write (cryptfile → keyring, rolls back on failure)
get KEY Retrieve (keyring, masked)
get KEY -p Retrieve (dual-query, plaintext)
delete KEY Remove from both stores
list List all stored keys
reset-keyring Restore keyring from cryptfile backup
reset-backup Sync keyring → cryptfile
status Backend status

See credstore/README.md for disaster recovery, Python API, and advanced usage.

Features

Tools

All tools are unified as OpenAI function definitions — the LLM sees no difference between a native shell command, an MCP tool, or a REST API endpoint.

Category Examples Location
Native execute_shell, run_python_script, get_os_info slife/tools/*.py
MCP / REST filesystem__read_file, fetch__get, serper__search Via slife-mcp proxy
Skills On-demand plugins with list_skills / use_skill skills/ directory
CLI Auto-discovered external commands, persisted with cli_add_tool Runtime registration
A2A 13 protocol tools — discovery, routing, lifecycle, broadcast slife/tools/a2a.py

Memory

Every conversation turn is permanently recorded. Hybrid search (grep + FTS5 + semantic via vec0) lets the LLM recall past work. Memory runs as a built-in plugin (slife/plugins/memory/) — a separate process so crashes never race with writes.

memory_search("ConnectionError")            → exact error trace
memory_search("MCP config", mode="fts5")    → topic search
memory_search("that bug fix", mode="hybrid")→ semantic recall
memory_search(mode="time", since="2026-07") → browse by date

Agent isolation via --agent alice. Each agent gets its own DB (<agent_id>.db) in the data directory. Embedding via local GGUF (offline) or OpenAI-compatible API. See DESIGN.md § Permanent Memory for the full architecture.

Plugins

Three built-in plugins ship with Slife, all using the same MCP stdio protocol:

Plugin Role
slife-mcp Proxy for external MCP servers (stdio + HTTP) — 10 management tools
slife-memory Diary database with hybrid search (FTS5 + vec0 RRF)
slife-wechat Bidirectional WeChat messaging via iLink ClawBot API

Third-party plugins are standard MCP servers configured in slife.json5mcp.servers. They auto-connect on startup and their tools are discovered and registered automatically. Any MCP-compatible server — in Python, Node.js, Go, Rust, or any other language — works as a Slife plugin.

// Example: add a custom MCP server
mcp: {
  servers: {
    "my-plugin": {
      command: "uv", args: ["run", "python", "-m", "my_plugin.server"],
      env: { API_KEY: "${API_KEY}" },
      description: "My custom MCP server."
    },
  },
}

See DESIGN.md § Third-Party Plugins for the full plugin contract and configuration reference.

A2A — Agent-to-Agent

Two transports, one interface: MQTT (remote peers, enable with --agent <id>) and Subagent (local child processes, always available). The unified inbox serializes human keyboard, WeChat, MQTT, and subagent messages through a single queue — only one AgentLoop runs at a time.

Progressive Disclosure

Not all tools are in every LLM request. Three categories use lightweight summaries first:

Category Browse Load
Memory memory_search / memory_list_recent memory_open
Skills list_skills use_skill
MCP mcp_list_servers / mcp_list_tools mcp_set_disclosure("eager")

Shortcuts

Key Action
Ctrl+C (in input) Quit
Ctrl+C (elsewhere) Copy (terminal-native)
Esc Cancel agent loop
Ctrl+L Focus input field
Home / End Scroll to top / bottom
Any key Auto-focus input + type

CLI Flags

Flag Default Description
--agent <id> slife Agent identity — memory isolation key & A2A mesh identity

Requirements

The install script handles everything automatically. Nothing to install beforehand.

Component Status
Python ≥ 3.13 Auto-installed via uv if missing
uv Auto-installed if missing
Node.js Optional — only for npx-based MCP servers
llama-cpp-python Optional — slife[embeddings] for local GGUF embeddings
paho-mqtt Optional — slife[mqtt] for A2A MQTT mesh

Development

Dev mode is detected via pyproject.toml — when [project] name == "slife", data files stay in the project directory for easy debugging. Production installs use ~/.slife/.

git clone https://github.com/juzcn/slife.git
cd slife
uv sync
uv run slife                      # uses ./slife.json5, data stays in ./

For all optional dependencies (embeddings + MQTT):

uv sync --all-extras

Run tests:

uv run pytest

Design

Slife is a minimum-harness agent. The harness only does what the LLM physically cannot: execute tools, maintain conversation state, stream responses, and persist memory. Everything else — reasoning, planning, tool selection, error recovery — is the LLM's job.

See DESIGN.md for the full architecture, component-level documentation, and design rationale.

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

slife-0.3.2.tar.gz (167.9 kB view details)

Uploaded Source

Built Distribution

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

slife-0.3.2-py3-none-any.whl (201.8 kB view details)

Uploaded Python 3

File details

Details for the file slife-0.3.2.tar.gz.

File metadata

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

File hashes

Hashes for slife-0.3.2.tar.gz
Algorithm Hash digest
SHA256 53a35a08df09fa5c4de37e03d02407ff91c5d2d17b5e65c50ea4688ac925baff
MD5 65404a7057f02da445d1ea4b6fa93390
BLAKE2b-256 f05c56f206487d4c49159bfb9a1148152af682a6b1383b2662ac9e765b99bd76

See more details on using hashes here.

Provenance

The following attestation bundles were made for slife-0.3.2.tar.gz:

Publisher: publish.yml on juzcn/slife

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

File details

Details for the file slife-0.3.2-py3-none-any.whl.

File metadata

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

File hashes

Hashes for slife-0.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 7574e0a950c0d0f09ada9929a75d952ea369ed8a0f14b7767deabfcad350461e
MD5 b4a912c9eda5c035863a2c7926ca1364
BLAKE2b-256 aa3f016bf0e58f456d63327bbbe1683ef714e213749eee396ec873fcbe1312c0

See more details on using hashes here.

Provenance

The following attestation bundles were made for slife-0.3.2-py3-none-any.whl:

Publisher: publish.yml on juzcn/slife

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