block / block/buzz

Remote agents: support long-lived hosts alongside ephemeral substrates (and let the model picker see them)

Open
#5,282 2 comments 1 reaction 0 assignees View on GitHub
Dominant language
Rust
Stars
32.7k
Forks
4.3k
Avg merge
1d 13h
Merged PRs (30d)
253

Description

Duplicate search: nothing found covering persistent-host remote agents. Closest related work I could find is #4289 (Kubernetes backend plugin, merged), #3748 (remote agent spec), and open PRs #5088 (harden Kubernetes persistence) and #5084 (discover remote channel agents). Happy to be pointed elsewhere if this belongs on one of those.

## Summary

`VISION_REMOTE_AGENTS.md` frames the agent body as disposable:

> workspace files, checkouts, and session-local state are part of the body, not the agent, and they go when it goes unless the substrate supplies persistence

That is the right default, and the Kubernetes path fits it well. This issue is about the case it does not serve: **a project whose working directory is not incidental to the agent, but is the thing the agent works on.**

## The case

I run several projects across a small fleet — a VPS, a home server, a workstation. Some of those projects live on exactly one machine and cannot meaningfully move:

- the repository and its supporting files are there,
- the machine has network reachability the project depends on (private services, other daemons, credentials scoped to that host),
- the tree is large enough that cloning it per-session is not a sane per-invocation cost.

For those, "fresh compute, same agent" is not equivalent. If the brain of the project is on one host, the session belongs there too. Cloning a large tree onto a disposable pod that cannot reach what it needs is not a substitute for running where the project already is.

This is not an argument against ephemerality — it is an argument that **which machine** should be a per-agent choice rather than a property of the deployment mechanism.

## What works today, and what does not

I run remote agents by defining a custom harness whose command is `ssh … opencode acp`, with a small wrapper on the remote host that reads env vars forwarded over ssh. That works: the agent runs on the right machine, in the right directory, with the right tools.

Two rough edges:

**1. Model discovery is local-only.** `discover_agent_models` resolves the agent binary against the local filesystem and PATH (`resolve_command` → `path.exists()` / local PATH scan) and spawns it locally to enumerate models. For a harness whose command is `ssh`, there is no local binary to interrogate, so the model picker comes up empty and no model can be selected in the UI.

Execution is already transport-agnostic here — only discovery assumes locality. Running discovery through the same command the harness uses would close the gap.

Workaround: opencode reads `opencode.json` from its working directory, so the model, MCP servers and plugins can be supplied by the project directory instead of the picker. Verified: an MCP server defined in a directory's `opencode.json` is listed when opencode runs from that directory and not otherwise. It works, but it means the UI shows nothing where a user would reasonably expect to choose.

**2. Working directory is not first-class.** Nothing in the agent model expresses "run in this directory on this host", so I pass it as an env var (`ACP_FORCE_CWD`) forwarded over ssh and interpreted by my wrapper. Each new variable needs both a `SendEnv` in the harness and an `AcceptEnv` on the target host, so the mechanism does not generalise well.

Note that kind:30179's `PrivateConfig` already carries `env_vars` and `agent_args` as first-class fields, so much of this may fall out naturally — this issue is partly asking whether that is the intended path.

## What I am asking

1. Is a **persistent-host substrate** in scope for the remote-agent design — an agent pinned to a machine, in a directory, rather than deployed to disposable compute? If so I would like to help build it.
2. Should **model discovery run through the harness command** rather than resolving locally? That looks like a contained fix and would make any remote harness usable from the UI.
3. Is **working directory** intended to become first-class via kind:30179's `env_vars`, or is something else planned?

## Prior art I can contribute

I built a session manager (Nexus OCS) that composes what I think of as an agent's *makeup*: which harness variant, which model or model roster, which MCP servers, which plugins, and which directory on which host. It writes a project directory containing an `opencode.json` plus a manifest, then launches into it — so the makeup travels with the directory rather than living in a command line, which is what makes the same session reproducible from Buzz.

Three things fell out of building it that may be useful input regardless of what you decide here:

- **The makeup is a directory, not a command line.** The launch command is nearly empty (`opencode --model X`); everything meaningful is the project config it runs against. That composes well with anything that can set a working directory.
- **Multi-model rosters are a real shape.** Different harness variants support different numbers of concurrently-configured models (one, a main plus a small/cheap tier, or a larger roster). "One agent, one model" is a limiting assumption for the roster case.
- **Sessions outlive clients.** A registry of what a session *was* is useful independently of which app launched it.

It is a personal tool and not currently public. If any of it is interesting I am happy to open it up, extract the parts that are useful, or just describe the design in more detail — whichever is most helpful.

## Environment

Windows 11 desktop; remote hosts are Linux (a VPS and a home server) reached over ssh with a self-hosted relay.

Contributor guide

Open the contributing guide

Research direction

Read VISION_REMOTE_AGENTS.md and trace discover_agent_models through resolve_command, including the local PATH and filesystem assumptions described here. Review kind:30179's PrivateConfig fields and related issues or pull requests #4289, #5088, and #5084 before deciding the scope. Done should mean an agreed design and acceptance criteria for persistent hosts, remote model discovery, and first-class working directories.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend-api-design, devtools
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.