Skip to main content

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

Project description

slife

Terminal-based AI agent — a function-calling loop with minimum harness. Chat with an LLM that can execute shell commands, load on-demand skills, and connect to MCP servers.

Quick Start

# Install
uv sync

# Configure
cp slife.json5.example slife.json5
# Edit slife.json5 — set your API keys via ${ENV_VAR} references

# Run
uv run slife

Configuration

Edit slife.json5. Key sections:

{
  models: {
    providers: {
      deepseek: {
        base_url: "https://api.deepseek.com",
        api_key: "${DEEPSEEK_API_KEY}",
        models: [
          { model: "deepseek-v4-flash", name: "DeepSeek V4 Flash" },
          { model: "deepseek-v4-pro", name: "DeepSeek V4 Pro", reasoning: true },
        ],
      },
    },
  },
  active_model: "deepseek/deepseek-v4-pro",
  agent: { max_iterations: 10 },
  tools: [
    { type: "platform" },
    { type: "shell", timeout: 30 },
    { type: "skill", skills_dir: "skills" },
  ],

  // MCP integration (optional)
  mcp: {
    // wrapper.url — slife probes this first, falls back to child process
    wrapper: {
      url: "http://127.0.0.1:9876/mcp",
    },
    servers: {
      "filesystem": {
        command: "npx",
        args: ["-y", "@modelcontextprotocol/server-filesystem", "/allowed/path"],
      },
    },
  },
}

API keys use ${ENV_VAR} syntax — set them in your environment, not in the config file.

Tools

Tool Config Type What it does
execute_shell shell Run shell commands on the host machine
get_shell_command platform Translate intent into OS-correct shell syntax
list_skills skill List available skill plugins
use_skill skill Load a skill's documentation into context

Add or remove tools from the tools[] list to control what the agent can do.

Additional tool types (e.g. serper for web search) are registered in slife/tools/factory.py and can be enabled with a matching implementation.

MCP Integration

slife uses tools from any MCP-compatible server via slife-mcp — an independent MCP proxy that manages persistent connections:

slife agent ←→ slife-mcp ←→ external MCP servers

Two ways to run slife-mcp:

Mode How Description
Child process Auto-started by slife No setup needed — slife spawns it via stdio
Standalone slife-mcp Independent HTTP service, share across clients

Standalone usage:

pip install slife-mcp

# Run (auto-detects HTTP/stdio mode)
slife-mcp                      # TTY + slife.json5 → HTTP
slife-mcp --port 8888          # Custom port
slife-mcp --host 0.0.0.0       # Listen on all interfaces

When the wrapper is running standalone, slife probes mcp.wrapper.url on startup and connects via HTTP instead of spawning a child process. If nothing is listening, it falls back to spawning its own.

See DESIGN.md for architecture details.

Skills

Skills are on-demand documentation plugins. The agent loads them only when needed, keeping the context lean.

skills/baidu-search/
  SKILL.md              # Instructions the agent reads
  scripts/search.py     # Supporting code

Flow: the agent calls list_skills → sees what's available → calls use_skill("baidu-search") to load full instructions.

To add a skill, create a directory under skills/ with a SKILL.md file.

Tips

  • /file image.png — attach an image for vision models
  • Ctrl+L — clear the conversation
  • Ctrl+C — quit
  • Esc — focus the input field

Design

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

The system prompt is intentionally lean. It only contains project-specific information not in the LLM's training data.

See DESIGN.md for the full design rationale.

Project Structure

slife/
  agent/               # Core agent loop, LLM client, conversation
    loop.py            #   Function-calling while-loop with streaming
    llm_client.py      #   OpenAI-compatible streaming client
    conversation.py    #   Message history (OpenAI format)
    service.py         #   Wiring: client + tools + loop + MCP
    system_prompt.py   #   Jinja2 template rendering
    multimodal.py      #   Image encoding, /file attachment parsing
  tools/               # Extensible tool system
    base.py            #   Tool ABC with __init_subclass__ validation
    registry.py        #   Name → Tool lookup & execution
    factory.py         #   Config type → Tool instances (TOOL_BUILDERS)
    shell.py           #   execute_shell (subprocess with timeout)
    shell_command.py   #   get_shell_command (platform-aware)
    skill.py           #   list_skills / use_skill
  mcp/                 # MCP client (slife side)
    client.py          #   stdio/HTTP client with asyncio.Queue adapters
    tool_adapter.py    #   MCP → slife Tool adapter (MCPProxyTool)
    process.py         #   Child process lifecycle manager
  ui/                  # Textual TUI (Claude Code CLI style)
    app.py             #   Main application
    chat.py            #   Message widgets
    handler.py         #   Streaming event → UI bridge
    tool_display.py    #   Tool call rendering (expandable widgets)
  config.py            # JSON5 config loading (ModelConfig, MCPConfig, Config)
  env.py               # ${ENV_VAR} and ${ENV_VAR:-default} resolution
  platform.py          # OS detection, shell syntax (Windows/Unix)
slife_mcp/             # Independent MCP proxy service (publishable package)
  server.py            #   FastMCP server with management tools
  connection.py        #   asyncio JSON-RPC connection pool
  pyproject.toml       #   Standalone package config (pip install slife-mcp)
skills/                # Skill plugins (on-demand documentation)
tests/                 # pytest suite (331 tests, asyncio_mode=strict)

Requirements

  • Python ≥ 3.13
  • uv (Python package manager)
  • Node.js (only if using npx-based MCP servers)

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.1.1.tar.gz (155.4 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.1.1-py3-none-any.whl (48.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: slife-0.1.1.tar.gz
  • Upload date:
  • Size: 155.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.5

File hashes

Hashes for slife-0.1.1.tar.gz
Algorithm Hash digest
SHA256 87679c814ea5cb9c97f5bf059aed11c4a1cf57c8f8578f823398205c6eac1441
MD5 5ab56c3ff03674477fc1470e8a54285d
BLAKE2b-256 64ff34f197be81a2884f400a631d1362048d709b809e39ade394bf0d049d6f46

See more details on using hashes here.

File details

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

File metadata

  • Download URL: slife-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 48.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.5

File hashes

Hashes for slife-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 82e92f3ba44b008b0921fbfd36fb6d863f1e519564c168d4a45cebd0f77c9c7d
MD5 d35da7a19ffe976feb56c7f293124981
BLAKE2b-256 8e1582a65756323c0391b2c69e9b83d0925d6d54e0da6cb178313a9698c2a1c0

See more details on using hashes here.

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