Skip to main content

Long-running task management plugin for Hermes Agent

Project description

SagTask

A Hermes Agent standalone user plugin for long-running, multi-phase tasks with structured methodology execution, subagent orchestration, and cross-session recovery. Each task gets its own Git repository with full version control.

SagTask is NOT a memory provider. It coexists with any memory system and injects task context via the pre_llm_call hook.

Multi-Agent Collaboration

Hermes supports multiple profiles (agents) that share the same ~/.hermes/sag_tasks/ directory — all agents collaborate on the same pool of tasks. But each agent tracks its own active task independently:

~/.hermes/
├── plugins/sagtask/              ← Default profile plugin
├── profiles/
│   ├── hbuilder/plugins/sagtask/ ← Profile "hbuilder" plugin
│   └── hexpert/plugins/sagtask/  ← Profile "hexpert" plugin
└── sag_tasks/                    ← Shared task pool (all agents)
    ├── .active_tasks.json        ← Per-profile active task tracking
    ├── my-project/               ← Task Git repo (shared)
    └── another-task/             ← Task Git repo (shared)

.active_tasks.json tracks which task each agent is working on:

{
  "default": "my-project",
  "hbuilder": "sagtask-devop",
  "hexpert": null
}

How it works:

  • Each profile's SagTaskPlugin derives its profile ID from the _hermes_home path (~/.hermes/profiles/<name>)
  • _active_task_id is a @property that transparently reads/writes the correct entry in the dict
  • Zero changes needed in handlers or hooks — the property abstraction handles everything
  • Legacy .active_task files are auto-migrated on first read

Installation: install.sh and /sagtask update automatically install the plugin to all profiles:

curl -fsSL https://raw.githubusercontent.com/ethanchen669/sagtask/main/install.sh | bash
# Installs to ~/.hermes/plugins/sagtask/ + every ~/.hermes/profiles/*/plugins/sagtask/

Quick Install

curl -fsSL https://raw.githubusercontent.com/ethanchen669/sagtask/main/install.sh | bash

Or manually:

git clone https://github.com/ethanchen669/sagtask.git ~/.hermes/plugins/sagtask
# Restart your Hermes gateway to load the plugin

Self-Update

SagTask has a built-in /sagtask slash command:

/sagtask update    → Check GitHub releases, download + install to all profiles
/sagtask version   → Show current installed version
/sagtask help      → Show usage

Tools (20)

Task Lifecycle

Tool Description
sag_task_create Create task with phased steps/gates, init Git + GitHub repo
sag_task_status Show current phase/step/pending gates
sag_task_advance Move to next step/phase (blocks if verification fails)
sag_task_pause Snapshot execution context for later resume
sag_task_resume Restore from most recent paused execution
sag_task_approve Submit approval decision for a pending gate
sag_task_list List all tasks with status

Planning & Execution

Tool Description
sag_task_plan Generate structured subtask plan for the current step
sag_task_plan_update Update subtask status (done/failed), sync progress
sag_task_dispatch Build subagent context for a subtask, optional worktree isolation
sag_task_verify Run verification commands, record pass/fail
sag_task_review Build structured review prompt (step/phase/full scope)

Methodology

Tool Description
sag_task_brainstorm Design exploration → option selection workflow
sag_task_debug Systematic debugging: reproduce → diagnose → fix
sag_task_metrics Query verification stats, coverage trends, throughput

Rules

Tool Description
sag_task_rules Manage development rules: list/add/update/remove/toggle

12 built-in rules auto-loaded on task creation. Smart context injection selects relevant rules based on methodology and phase. See Development Rules System for details.

Git Operations

Tool Description
sag_task_commit Stage all + commit with message
sag_task_branch Create + push new branch
sag_task_git_log Show recent commit history
sag_task_relate Link two tasks as cross-pollination partners

Architecture

src/sagtask/
├── __init__.py          ← register(), re-exports
├── plugin.py            ← SagTaskPlugin class, layered context injection
├── hooks.py             ← pre_llm_call, on_session_start
├── schemas.py           ← 20 tool JSON schemas
├── _utils.py            ← constants, shared helpers
├── rules.py             ← 12 default rules, CRUD, smart context selection
└── handlers/
    ├── __init__.py      ← _tool_handlers dispatch dict
    ├── _lifecycle.py    ← create, status, advance, pause, resume, approve, list
    ├── _plan.py         ← plan, plan_update, verify, brainstorm, debug
    ├── _orchestration.py← dispatch, review, context builders
    ├── _metrics.py      ← metrics query handler
    └── _git.py          ← commit, branch, git_log, relate

Plugin Registration

register(ctx)
    ├── ctx.register_tool("sag_task_*", ...) × 20
    ├── ctx.register_hook("pre_llm_call", ...)    # layered context injection
    └── ctx.register_hook("on_session_start", ...) # restore active task

Context Injection — Layered System

SagTask injects a compact, adaptive context block before each LLM call. The system minimizes token usage by only including information that has changed or is urgently needed.

Layer Content Frequency
L0 [SagTask] task=X status=active phase=P step=S Every turn
L1 Phase/step names, pending gates On change + blocking gates
L1.5 Artifacts summary On change
L2 Methodology phase, plan progress, failures On change
L2.5 Selected development rules (smart filtering) On change + first turn
L3 Verification status, metrics (pass rate, coverage) On change + blocking
L4a Related tasks hint ("2 tasks available") When relationships exist
L4b Related task details First turn, step switch, user intent

Cache: Per-session per-task cache with context hashing. Stable state → single L0 line (~50 tokens). Changed state → relevant layers expand.


Methodology System

Each step can declare a methodology that guides execution:

Type Workflow
tdd RED → GREEN → REFACTOR cycle, auto-transitions on verify
brainstorm Generate 3+ options → user selects → implement
debug Reproduce → diagnose (hypothesis) → fix
plan-execute Plan subtasks → execute sequentially → verify each
none No methodology constraint (default)

Development Rules System

12 built-in rules guide agent behavior across all tasks. Rules use a global defaults + per-task overrides pattern.

Storage

  • Global rules: ~/.hermes/sag_tasks/.rules.json — shared across all tasks
  • Per-task overrides: .sag_task_state.jsonrules field — task-specific additions/toggles

The 12 Rules

# Rule Category
1 Think Before Editing. State assumptions explicitly; ask when uncertain; present options when ambiguous. thinking
2 Simplicity first. Minimum code that solves the problem. No speculative design, no unrequested features. thinking
3 Surgical changes. Touch only necessary code; don't refactor unrequested parts; match existing style. process
4 Goal-driven. Define verification criteria and loop until met, don't follow rigid step sequences. process
5 LLM for judgment only. Use LLM for classification, drafting, summarization, extraction. Use code for routing, retries, deterministic transforms. quality
6 Manage Context Deliberately. Treat context as a limited resource. For long tasks, maintain compact checkpoints: objective, files changed, commands run, artifacts produced, unresolved assumptions, next step. Load targeted files first; avoid broad dumps. Never skip required reading or verification to save context. quality
7 Surface conflicts, don't average them. When patterns contradict, pick one and explain; flag the other for cleanup. thinking
8 Read Before Writing. Check exports, callers, shared utilities before adding code. Ask when unclear. process
9 Tests encode intent. Tests should encode why behavior matters, not just pass when business logic changes. quality
10 Checkpoint every step. Summarize progress, verify state, list remaining work. Stop and restate position when lost. process
11 Match codebase conventions. Consistency over personal preference. Raise disagreements explicitly, don't silently change style. style
12 Fail loudly. Skipping tests and saying 'tests pass' is misleading. Surface uncertainty by default. quality

Smart Context Injection

Rules are injected into pre_llm_call context at L2.5, filtered by current state:

Trigger Rules Injected
methodology = tdd rule-9 (tests encode intent)
methodology = brainstorm rule-1 (think first), rule-7 (surface conflicts)
methodology = debug rule-12 (fail loudly), rule-4 (goal-driven)
Pending gates rule-3 (surgical changes), rule-10 (checkpoint)
First turn All 12 rules
No special state rule-1, rule-2, rule-12 (core three)

Managing Rules

# List current task's rules
sag_task_rules action: list

# Add a custom rule (task-level)
sag_task_rules action: add content: "Use type hints on all functions" task_id: "my-project" category: "quality"

# Add a global rule
sag_task_rules action: add content: "All PRs need 2 approvals" category: "process"

# Toggle a rule on/off
sag_task_rules action: toggle rule_id: "rule-6" task_id: "my-project"

# Remove a custom rule
sag_task_rules action: remove rule_id: "rule-custom-abc123" task_id: "my-project"

Orchestration

sag_task_plan          → Generate subtasks from step description
sag_task_dispatch      → Build subagent context, optional git worktree
  └─ subagent executes → sag_task_plan_update(status="done")
sag_task_review        → Spec compliance + quality review context
sag_task_verify        → Run commands, record results to metrics
sag_task_advance       → Move to next step (blocks if must_pass fails)

Metrics

Append-only event log (.sag_metrics.jsonl) tracks:

  • Verification runs (pass/fail, exit codes, coverage)
  • Subtask completions
  • Step advances, dispatches, pauses/resumes

Query with sag_task_metrics for pass rates, coverage trends, and subtask throughput.


Storage Layout

~/.hermes/sag_tasks/
├── .active_tasks.json           ← Per-profile active task tracking
├── .rules.json                  ← Global development rules (shared)
└── <task_id>/
    ├── .git/                        ← Task Git repo
    ├── .gitignore
    ├── .sag_task_state.json         ← Machine-readable state (git-ignored)
    ├── .sag_plans/                  ← Subtask plans (git-tracked)
    │   └── <step_id>.json
    ├── .sag_metrics.jsonl           ← Metrics event log (git-ignored)
    ├── .sag_artifacts/              ← Generated artifacts (git-ignored)
    ├── .sag_executions/             ← Pause snapshots (git-ignored)
    ├── .sag_worktrees/              ← Isolated subtask worktrees (git-ignored)
    └── src/, tests/, docs/          ← User code (git-tracked)

Development

# Run tests
python -m pytest tests/ -v

# Run with coverage
python -m pytest tests/ --cov=src/sagtask --cov-report=term-missing

# Install for local Hermes dev
./dev-install.sh

# Build release tarball
bash scripts/build-release.sh 2.0.0

# Bump version across all files
bash scripts/bump-version.sh 2.1.0

Release Process

bash scripts/bump-version.sh X.Y.Z
# Update CHANGELOG.md
git add -A && git commit -m "chore: release vX.Y.Z"
git tag vX.Y.Z && git push origin main --tags
# GitHub Actions builds artifact + creates release automatically

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

sagtask-2.2.1.tar.gz (46.9 kB view details)

Uploaded Source

Built Distribution

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

sagtask-2.2.1-py3-none-any.whl (55.1 kB view details)

Uploaded Python 3

File details

Details for the file sagtask-2.2.1.tar.gz.

File metadata

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

File hashes

Hashes for sagtask-2.2.1.tar.gz
Algorithm Hash digest
SHA256 1d25932936b464ecfa56ebf6e3820cd9f1abfdf1b79dde3d8daf959c796c7e13
MD5 0b8d3e1c87d9905e5ada967352b64151
BLAKE2b-256 b61af1892fb811cd345affdaf294c46e3eb4be464fdd180363cd348e39ddb177

See more details on using hashes here.

Provenance

The following attestation bundles were made for sagtask-2.2.1.tar.gz:

Publisher: release.yml on ethanchen669/sagtask

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

File details

Details for the file sagtask-2.2.1-py3-none-any.whl.

File metadata

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

File hashes

Hashes for sagtask-2.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e824610e1d6e90acd18ba644f860c0c5a2a12085547765ef90538e04891dcd5d
MD5 a97ee7985a32577123519d9814035423
BLAKE2b-256 e43073bffe9ecf3faaa20cfa61144575ff1630cad95122cc7f15bb72354009ba

See more details on using hashes here.

Provenance

The following attestation bundles were made for sagtask-2.2.1-py3-none-any.whl:

Publisher: release.yml on ethanchen669/sagtask

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