Skip to main content

soothe-nano

PyPI version Ask DeepWiki

A ready-to-run coding agent you can drop into a script, CLI, or app.

Built on soothe-deepagents (filesystem, shell, subagents, skills, MCP). Nano adds the pieces you usually wire yourself: workspace safety, progressive tools/skills, research subagents, and a config-driven factory.

Vision

Give builders a production-shaped SootheNanoAgent in a few lines of Python.

  • Start small — chat, tools, or full composition
  • Stay portable — embed in notebooks, CLIs, or your own service
  • Compose what you need — tools, memory, subagents, skills, and MCP via config

Architecture

soothe-deepagents   agent harness (FS, shell, memory, skills base)
        ↓
soothe-sdk          shared contracts (protocols, events)
        ↓
soothe-nano         SootheNanoAgent + toolkits + subagents + MCP
create_nano_agent(config)
        │
        ├─ model + middleware stack
        ├─ tools (builtin groups + yours)
        ├─ subagents (planner, research, browser, …)
        ├─ skills (progressive discovery)
        └─ MCP (on-demand activation)

Features

Area What nano provides
Tools Builtin groups: shell, file ops, HTTP, search, data, image, …
Subagents Ready: plan, deep/academic research, browser
Skills / tools in context Progressive loading — activate what the turn needs
Workspace Scoped workspace + security defaults
Config YAML / SootheConfig factory
Memory Optional long-term memory via protocols
MCP Registry and on-demand adapters

vs deepagents

deepagents soothe-nano
What you get Opinionated harness Harness plus coding product defaults
Tools Bring your own Builtin groups out of the box
Subagents You define them Ready plan / research / browser
Skills / tools in context Base support Progressive loading
Workspace Pluggable backends Scoped workspace + security defaults
Config Code-first YAML / SootheConfig factory

Use deepagents when you want a minimal harness and full control.
Use nano when you want a coding agent that already knows how to work in a repo.

When to use nano

Scenario Fit
Coding assistant in a repo ✅ Files, shell, plan out of the box
Research / browsing agent ✅ Deep research, academic, browser subagents
Embed in your product ✅ Library API, no daemon required
One-shot / headless CLI ✅ See fj-ai
Plugin / toolkit author ✅ Depends on nano only
Simple Q&A chat ✅ Strip tools/subagents as needed

Install

uv add soothe-nano

Quick start

from soothe_nano import create_nano_agent
from soothe_nano.config import SootheConfig

agent = create_nano_agent(SootheConfig())
# agent.ainvoke / streaming — see examples/

Library examples live in examples/:

  1. Pure model (no tools)
  2. With tools
  3. With memory
  4. With subagents
  5. Full composition
python packages/soothe-nano/examples/01_pure_nano_example.py

Productive CLI (reference: fj-ai)

fj-ai is a production one-shot coding CLI built only on soothe-nano (no soothe daemon). Use it as the integration blueprint:

pip install fj-ai   # or: uv tool install fj-ai
fj explain this repo
fj -f what did we decide last time?

Integration pattern

A headless CLI typically does four things on top of nano:

  1. Load config~/.soothe/config/nano.yml, or zero-config from OPENAI_API_KEY / ANTHROPIC_API_KEY
  2. Force SQLite for standalone runs (threads survive across process exits)
  3. Build the agent with create_nano_agent, pin workspace, attach a checkpointer
  4. Stream agent.astream(...) and close the aiosqlite connection on exit

Minimal sketch (same shape as fj_ai/agent.py):

from __future__ import annotations

import asyncio
from contextlib import asynccontextmanager
from pathlib import Path
from typing import Any, AsyncIterator

from soothe_nano import SootheNanoAgent, create_nano_agent
from soothe_nano.config import SOOTHE_HOME, SootheConfig
from soothe_nano.resolve import resolve_checkpointer


def load_config(path: Path | None = None) -> SootheConfig:
    cfg = path or (SOOTHE_HOME / "config" / "nano.yml")
    if cfg.is_file():
        return SootheConfig.from_yaml_file(str(cfg))
    return SootheConfig()  # OPENAI_API_KEY / ANTHROPIC_API_KEY


def apply_cli_defaults(config: SootheConfig) -> SootheConfig:
    durability = config.agent.protocols.durability.model_copy(
        update={"backend": "sqlite", "checkpointer": "sqlite"}
    )
    protocols = config.agent.protocols.model_copy(update={"durability": durability})
    agent = config.agent.model_copy(update={"protocols": protocols})
    persistence = config.persistence.model_copy(update={"default_backend": "sqlite"})
    return config.model_copy(update={"agent": agent, "persistence": persistence})


@asynccontextmanager
async def open_sqlite_checkpointer(config: SootheConfig) -> AsyncIterator[Any | None]:
    result = resolve_checkpointer(apply_cli_defaults(config))
    db_path = result[1] if isinstance(result, tuple) and isinstance(result[1], str) else None
    if not db_path:
        yield None
        return

    import aiosqlite
    from langgraph.checkpoint.sqlite.aio import AsyncSqliteSaver
    from soothe_sdk.utils.serde import create_soothe_serde

    Path(db_path).parent.mkdir(parents=True, exist_ok=True)
    conn = await aiosqlite.connect(db_path)
    checkpointer = AsyncSqliteSaver(conn, serde=create_soothe_serde())
    await checkpointer.setup()
    try:
        yield checkpointer
    finally:
        await conn.close()  # required — aiosqlite uses a non-daemon thread


async def build_agent(
    config: SootheConfig,
    *,
    checkpointer: Any | None = None,
) -> SootheNanoAgent:
    agent = create_nano_agent(apply_cli_defaults(config))
    if checkpointer is not None:
        agent.graph.checkpointer = checkpointer
    return agent


async def run_once(query: str, *, thread_id: str) -> None:
    config = load_config()
    async with open_sqlite_checkpointer(config) as checkpointer:
        agent = await build_agent(config, checkpointer=checkpointer)
        async for chunk in agent.astream(
            query,
            config={"configurable": {"thread_id": thread_id}},
            stream_mode=["messages", "updates", "custom"],
        ):
            # render tokens / tool progress to stdout (see fj_ai/stream.py)
            _ = chunk


if __name__ == "__main__":
    asyncio.run(run_once("summarize this repo", thread_id="cli-demo"))

What fj adds on top of nano

Concern fj-ai approach
UX One-shot fj <query…>; -f / -t resume threads; -l list
Persistence SQLite checkpointer under $SOOTHE_DATA_DIR
Skills Package builtin_skills/ via register_builtin_skill_root
Workspace SOOTHE_WORKSPACE / cwd for file + shell tools
Streaming Quiet progress line + full final answer (stream.py)
Setup fj setup writes ~/.soothe/config/nano.yml

For a full TUI / StrangeLoop host on the same stack, see mirasoth/soothe. For the slim CLI product, clone caesar0301/fj-ai.

Package layout

soothe_nano/
  agent/       SootheNanoAgent, create_nano_agent
  config/      SootheConfig
  toolkits/    Builtin tool groups
  subagents/   plan, research, browser, …
  middleware/  Progressive tools/skills, workspace, policy
  skills/      Catalog + progressive search
  mcp/         MCP registry / adapters
  backends/    Persistence helpers

Development

From packages/soothe-nano/:

make help              # list targets
make sync-dev          # sync deps
make format lint       # format + lint
make test-unit         # unit tests
make test-integration  # integration tests (--run-integration)
make examples          # run examples
make build             # build dist/

Download files

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

Source Distribution

soothe_nano-1.2.0.tar.gz (537.0 kB view details)

Uploaded Source

Built Distribution

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

soothe_nano-1.2.0-py3-none-any.whl (704.5 kB view details)

Uploaded Python 3

File details

Details for the file soothe_nano-1.2.0.tar.gz.

File metadata

  • Download URL: soothe_nano-1.2.0.tar.gz
  • Upload date:
  • Size: 537.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for soothe_nano-1.2.0.tar.gz
Algorithm Hash digest
SHA256 5c4cc049701c915649f281d13c3a3c36a9bf1ed872dde16d6436834998b61a00
MD5 1801654fc8ad53c1f01cbfa09cf2e8cd
BLAKE2b-256 072e092ecd169b257c43543aa73fb4da1b3222935085c7cb670ce6f14555dead

See more details on using hashes here.

File details

Details for the file soothe_nano-1.2.0-py3-none-any.whl.

File metadata

  • Download URL: soothe_nano-1.2.0-py3-none-any.whl
  • Upload date:
  • Size: 704.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for soothe_nano-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ee2a3a0bf43161dfc5dc91e3e69914c72f367dac195133c834f03829ffa54fdd
MD5 a0e28245e16c89ff749d967a649896c2
BLAKE2b-256 15f02a5ca272e02c9492ee87bd70f6769ffc4c547720f93b440c4a1827985075

See more details on using hashes here.

Release history Release notifications | RSS feed

1.2.28

2 files

1.2.27

2 files

1.2.26

2 files

1.2.25

2 files

1.2.24

2 files

1.2.23

2 files

1.2.22

2 files

1.2.21

2 files

1.2.20

2 files

1.2.19

2 files

1.2.18

2 files

1.2.17

2 files

1.2.16

2 files

1.2.15

2 files

1.2.14

2 files

1.2.13

2 files

1.2.12

2 files

1.2.10

2 files

1.2.9

2 files

1.2.8

2 files

1.2.7

2 files

1.2.6

2 files

1.2.5

2 files

1.2.4

2 files

1.2.3

2 files

1.2.2

2 files

1.2.1

2 files

This release

1.2.0 This release

2 files

1.1.19

2 files

1.1.17

2 files

1.1.16

2 files

1.1.15

2 files

1.1.14

2 files

1.1.13

2 files

1.1.12

2 files

1.1.11

2 files

1.1.10

2 files

1.1.9

2 files

1.1.8

2 files

1.1.7

2 files

1.1.6

2 files

1.1.5

2 files

1.1.4

2 files

1.1.2

2 files

1.1.1

2 files

1.1.0

2 files

1.0.15

2 files

1.0.14

2 files

1.0.13

2 files

1.0.12

2 files

1.0.11

2 files

1.0.10

2 files

1.0.8

2 files

1.0.7

2 files

1.0.6

2 files

1.0.5

2 files

1.0.4

2 files

1.0.3

2 files

1.0.2

2 files

1.0.1

2 files

1.0.0

2 files

0.9.11

2 files

0.9.9

2 files

0.9.8

2 files

0.9.7

2 files

0.9.6

2 files

0.9.5

2 files

0.9.4

2 files

0.9.2

2 files

0.9.1

2 files

0.9.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page