Micro-agent runner for task automation using markdown definitions
Project description
tsugite
Tsugite (継ぎ手) is an agent framework where you define AI agents as markdown files and run them from the CLI, a web UI, or through scheduled tasks.
I built it because none of the existing agent frameworks did what I wanted. I needed something self-hosted, model-agnostic, and simple enough that an agent is just a text file I can edit and version control.
Originally it was meant to be a framework for micro-agents inspired by ESA, but has grown a lot since that goal.
What an agent looks like
A simple "hello world" agent looks like:
---
name: morning-brief
model: anthropic:claude-sonnet-4-20250514
tools: [web_search, fetch_text, write_file, final_answer]
---
You are a morning briefing assistant.
Current date: {{ now() }}
User location: {{ env("LOCATION", "unknown") }}
Check the weather, scan top news, and write a short briefing.
Use final_answer() to return the result.
YAML frontmatter for config, markdown body for instructions, Jinja for dynamic context. Run it with:
tsu run +morning-brief "what's happening today"
Key ideas
- Agents are markdown. A basic agent is just markdown with yaml frontmatter. Advanced agents are still just markdown but can use jinja templating and a special
<!--tsu -->syntax. - Code execution over tool-calling. Inspired by smolagents. Instead of using native tool calling, LLMs write python code. Tools are exposed as python functions.
- Any LLM. Plugin interface to add support for additional LLM providers. Built-in we have openai-compatible apis, ollama, anthropic, and claude code.
- Workspaces. Each workspace is a persistent directory with agents, skills, memory files, and config. The agent runs inside its workspace and can read/write files, spawn sub-agents, manage schedules, and persist state across conversations. Workspaces are entirely optional.
- CLI and/or Daemon with a Web UI Use
tsu runcommands for cli-only, or runtsu daemonfor a daemon that supports scheduled tasks, a web ui, and some other neat things.
Install
uv tool install tsugite-cli # recommended
pipx install tsugite-cli # alternative
pip install tsugite-cli # or plain pip
The package is tsugite-cli, the command is tsugite (or tsu for short).
Quick start
# Initialize a workspace
tsu init my-workspace
cd my-workspace
# Run the built-in default agent
tsu run +default "summarize the files in this directory"
# Run an agent file directly
tsu run my-agent.md "do the thing"
# Start the daemon (web UI, Discord/Telegram bots)
tsu daemon
Features
- Multi-step workflows with
<!-- tsu:step -->to chain steps and pass data between them - Scheduling built-in cron for recurring agent tasks (daily summaries, monitoring, etc.)
- Web UI for conversations, with Discord as an alternative interface
- Sub-agents that can spawn other agents for specific subtasks
- Skills directory-based knowledge modules (mostly) following the agentskills.io SKILL.md format
- Hooks that fire shell commands on lifecycle events (post-tool, pre-message, pre/post-compact)
- Sandbox (linux only) via bubblewrap with filesystem and network isolation
Agents in more detail
Agents support YAML frontmatter for configuration:
---
name: code-reviewer
model: anthropic:claude-sonnet-4-20250514
max_turns: 15
tools: [read_file, list_files, web_search, final_answer]
auto_load_skills: [coding-standards]
---
You can restrict which tools an agent has access to, set turn limits, auto-load skills, attach context files, and extend other agents. TODO: See docs/ for the full spec.
Multi-step agents use <!--tsu --> comments as directives:
<!-- tsu:step name="research" model="openai:gpt-4o" -->
Research the topic and save findings to a variable.
<!-- tsu:step name="write" -->
Using the research from the previous step, write a summary.
The variable `research` is available as a Python variable.
For a complete example, check the built-in default agent.
Sandbox
On Linux only (for now), agent code runs inside a bubblewrap sandbox when you pass --sandbox:
tsu run +default "task" --sandbox --allow-domain "github.com"
tsu run +default "task" --sandbox --no-network
Filesystem access is limited to the workspace. Network goes through a filtering proxy that only allows domains you specify.
Config and Data Directories
All paths follow XDG Base Directory conventions and can be overridden with the standard environment variables.
| Path | Default | Contents |
|---|---|---|
$XDG_CONFIG_HOME/tsugite/ |
~/.config/tsugite/ |
config.json, daemon.yaml |
$XDG_DATA_HOME/tsugite/history/ |
~/.local/share/tsugite/history/ |
Session history (JSONL per session) |
$XDG_DATA_HOME/tsugite/daemon/ |
~/.local/share/tsugite/daemon/ |
Daemon state |
$XDG_DATA_HOME/tsugite/secrets/ |
~/.local/share/tsugite/secrets/ |
Encrypted secrets (secrets.db) |
$XDG_DATA_HOME/tsugite/usage/ |
~/.local/share/tsugite/usage/ |
Usage (cost and token) tracking (usage.db) |
$XDG_DATA_HOME/tsugite/workspaces/ |
~/.local/share/tsugite/workspaces/ |
Workspace directories |
$XDG_CACHE_HOME/tsugite/attachments/ |
~/.cache/tsugite/attachments/ |
Attachment cache |
Development
git clone https://github.com/justyns/tsugite.git
cd tsugite
uv sync --dev
Status
This is a personal project I use daily. It works for my use cases but isn't polished for general consumption yet. Issues and PRs welcome, but set expectations accordingly. Documentation is very sparse because I keep changing things.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tsugite_cli-0.13.0.tar.gz.
File metadata
- Download URL: tsugite_cli-0.13.0.tar.gz
- Upload date:
- Size: 961.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9549dcc3560c4c995591f346aeea359dd41399f43219d506102be4ab6a3a0d04
|
|
| MD5 |
e79017b82eb76aa3a31a01199ab6b488
|
|
| BLAKE2b-256 |
4c07672a0128ba43ccea740ecb9e0ecee5f65c0c11a68c86904730e522857e77
|
Provenance
The following attestation bundles were made for tsugite_cli-0.13.0.tar.gz:
Publisher:
pypi-publish.yml on justyns/tsugite
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tsugite_cli-0.13.0.tar.gz -
Subject digest:
9549dcc3560c4c995591f346aeea359dd41399f43219d506102be4ab6a3a0d04 - Sigstore transparency entry: 1415916046
- Sigstore integration time:
-
Permalink:
justyns/tsugite@bdcfb901d44acb2f60ecad0d18223980006e84b1 -
Branch / Tag:
refs/tags/v0.13.0 - Owner: https://github.com/justyns
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@bdcfb901d44acb2f60ecad0d18223980006e84b1 -
Trigger Event:
push
-
Statement type:
File details
Details for the file tsugite_cli-0.13.0-py3-none-any.whl.
File metadata
- Download URL: tsugite_cli-0.13.0-py3-none-any.whl
- Upload date:
- Size: 599.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3fb650378be91f3f3859daef2fe0e2fd2ffef7d2b4be4e9f1e4b295cc13daeb4
|
|
| MD5 |
52a57d0c9bdd5a76ac9cc4bdbdbb276f
|
|
| BLAKE2b-256 |
06d411ef3b2faa0739de043166062c255e7974f5fdccb6497e302c26a91a8a37
|
Provenance
The following attestation bundles were made for tsugite_cli-0.13.0-py3-none-any.whl:
Publisher:
pypi-publish.yml on justyns/tsugite
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tsugite_cli-0.13.0-py3-none-any.whl -
Subject digest:
3fb650378be91f3f3859daef2fe0e2fd2ffef7d2b4be4e9f1e4b295cc13daeb4 - Sigstore transparency entry: 1415916146
- Sigstore integration time:
-
Permalink:
justyns/tsugite@bdcfb901d44acb2f60ecad0d18223980006e84b1 -
Branch / Tag:
refs/tags/v0.13.0 - Owner: https://github.com/justyns
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish.yml@bdcfb901d44acb2f60ecad0d18223980006e84b1 -
Trigger Event:
push
-
Statement type: