Skip to content

tesserine/agentd

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

68 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

agentd

Autonomous AI agent runtime daemon. agentd runs agent sessions in ephemeral Podman containers on infrastructure you control. Each session gets an isolated execution environment — its own identity, credentials, a fresh repository clone, and read-only methodology context — supervised from setup through teardown. agentd prepares and supervises these environments; model inference and MCP transport belong to the agent runtime inside the container.

Why

Running autonomous agents requires infrastructure: isolated environments, credential injection, workspace setup, identity management. Operators building this ad-hoc re-solve the same problems for each agent and each deployment.

agentd is the self-hosted runtime layer. The operator declares what through profile configuration — which image, which credentials, which methodology. agentd owns how — container lifecycle, privilege management, resource cleanup. The agent gets an isolated, ephemeral workspace with exactly what it needs and nothing more.

Status

v0.1.0 — early development.

The session lifecycle works end-to-end: profile configuration, foreground daemon startup, operator-triggered sessions, ephemeral Podman containers, credential injection, execution, and teardown. Startup reconciliation cleans stale resources from prior runs. Structured JSON tracing provides operational visibility. Profiles may now declare a default repository and an optional cron schedule. Manual runs still flow through agentd run, and scheduled runs dispatch through the same daemon socket intake without introducing a separate job type. Profiles may also declare additional bind mounts for host-managed state such as subscription auth directories or persistent audit storage.

Configuration

A profile is a named environment specification: base image, methodology directory, optional additional bind mounts, optional default repo, optional cron schedule, credentials, and runtime command. Define profiles in a TOML config file — start from examples/agentd.toml:

# Static profile registry for agentd.
# A profile can carry its own default repo and optional schedule.

[[profiles]]
# Stable operator-facing profile name used for lookup and container identity.
name = "site-builder"
# Prebuilt image containing the agent runtime and runa.
base_image = "ghcr.io/example/site-builder:latest"
# Methodology directory to mount read-only into the session environment.
methodology_dir = "../groundwork"
# Default repository URL cloned for manual runs when `agentd run` omits a repo,
# and for every scheduled run of this profile.
repo = "https://github.com/pentaxis93/agentd.git"
# Optional five-field cron expression in daemon-local time.
schedule = "*/15 * * * *"
# Static session command executed from the cloned repository. This profile is
# tightly bound to one app, so the session repo is the project being built.
command = [
  "/bin/sh",
  "-lc",
  '''
runa init --methodology /agentd/methodology/manifest.toml
cat > .runa/config.toml <<'EOF'
[agent]
command = ["site-builder", "exec"]
EOF
if [ -n "${AGENTD_WORK_UNIT:-}" ]; then
  exec runa run --work-unit "${AGENTD_WORK_UNIT}"
fi
exec runa run
''',
]
# Optional environment variable name resolved by the daemon for clone-only
# repository authentication. This value does not flow into the agent runtime.
repo_token_source = "SITE_BUILDER_REPO_TOKEN"

#[[profiles.mounts]]
# Additional host bind mounts are declared explicitly per profile.
# `source` must be an absolute host path and must already exist.
# `target` must be an absolute path inside the container and must not
# duplicate or overlap another mount target in the same profile.
# `read_only = true` is appropriate for host-managed auth directories.
#source = "/home/core/.claude"
#target = "/home/site-builder/.claude"
#read_only = true

[[profiles.credentials]]
# Secret name exposed inside the session environment.
name = "GITHUB_TOKEN"
# Environment variable name read from the daemon's own process environment.
source = "AGENTD_GITHUB_TOKEN"

[[profiles]]
# A home-repo review agent that carries its own review configuration and scans
# repositories beyond the repo used to launch the session.
name = "code-reviewer"
base_image = "ghcr.io/example/code-reviewer:latest"
methodology_dir = "../groundwork"
repo = "https://github.com/pentaxis93/agentd.git"
command = [
  "/bin/sh",
  "-lc",
  '''
runa init --methodology /agentd/methodology/manifest.toml
cat > .runa/config.toml <<'EOF'
[agent]
command = ["code-reviewer", "exec"]
EOF
if [ -n "${AGENTD_WORK_UNIT:-}" ]; then
  exec runa run --work-unit "${AGENTD_WORK_UNIT}"
fi
exec runa run
''',
]
repo_token_source = "CODE_REVIEWER_REPO_TOKEN"

[[profiles.credentials]]
name = "GITHUB_TOKEN"
source = "AGENTD_GITHUB_TOKEN"

Credential source fields name environment variables in the daemon's process environment — export them before starting the daemon. Additional mounts entries are bind mounts: source must be an absolute existing host path, target must be an absolute container path, targets must be unique within the profile, and runner-managed targets are reserved: /agentd/methodology, /home/{profile}, and /home/{profile}/repo plus its descendants. Other targets under /home/{profile} remain supported, including read-only auth mounts such as /home/site-builder/.claude. Additional mounts are not relabelled; on SELinux-enabled hosts, operators must ensure each host path already has a container-compatible label. The base image must provide /bin/sh, find, git, useradd, gosu, and whatever binaries the configured session command uses. When a profile declares schedule, it must also declare repo. Schedules are evaluated in daemon-local time and missed fires are not backfilled after downtime.

Running a Session

Build from source with cargo build --release. Requires rootless Podman for container execution.

Start the daemon:

agentd daemon --config /etc/agentd/agentd.toml

agentd with no subcommand is equivalent to agentd daemon.

The daemon runs in the foreground, reconciles stale resources from prior runs, and binds a Unix socket for operator control. Default paths: /run/agentd/agentd.sock and /run/agentd/agentd.pid. On SIGINT or SIGTERM, the daemon stops accepting connections and drains in-flight sessions; a second signal exits immediately. The Unix socket protocol is internal to agentd in v0.1.x: daemon and CLI must be the same build, and operators must restart the daemon after replacing the binary before using agentd run again.

Trigger a session through the running daemon:

agentd run site-builder --work-unit issue-42

agentd run reads the same config file and connects to the socket path defined there. When the profile declares repo, the CLI can omit the positional repo argument; an explicit repo still overrides the configured default:

agentd run site-builder https://github.com/pentaxis93/agentd.git --work-unit issue-42

Both manual and scheduled dispatches use the same daemon socket intake. Inside the container, the agent sees:

  • An unprivileged user with $HOME at /home/site-builder
  • A fresh clone of the repository at /home/site-builder/repo
  • Read-only methodology mount at /agentd/methodology
  • Any operator-declared additional bind mounts, read-only or read-write per profile
  • Credentials injected as environment variables
  • AGENTD_WORK_UNIT when the invocation includes one
  • The configured session command executing from the repo directory

The container is force-removed on completion. No session state persists on the host.

Scheduled Runs

Profiles with schedule run autonomously while the daemon is up. The scheduler evaluates cron expressions in daemon-local time and opens the same Unix-socket client path that agentd run uses. Multiple scheduled profiles may overlap, and their sessions dispatch independently. Session outcomes do not affect later schedule evaluation: the next occurrence runs at its next scheduled time.

Going Deeper

  • ARCHITECTURE.md — session lifecycle phases, container isolation model, credential flow, and workspace crate boundaries. How the system is built and why.
  • AGENTS.md — development discipline, BDD workflow, commit and branch conventions. Read this before contributing.
  • examples/agentd.toml — annotated profile configuration. Starting point for writing your own.

License

MIT

About

Daemon that runs autonomous AI agent sessions in ephemeral Podman containers. The infrastructure layer of the Tesserine ecosystem.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages