Agentic AI Atlasby a5c.ai
OverviewWikiGraphFor AgentsEdgesSearchWorkspace
/
GitHubDocsDiscord
iiRecord
Agentic AI Atlas · Invocation Modes
page:docs-agent-mux-reference-13-invocation-modesa5c.ai
Search record views/
Record · tabs

Available views

II.Record viewspp. 1 - 1
overviewarticlejsongraph
II.
Page JSON

page:docs-agent-mux-reference-13-invocation-modes

Structured · live

Invocation Modes json

Inspect the normalized record payload exactly as the atlas UI reads it.

File · wiki/docs/agent-mux/reference/13-invocation-modes.mdCluster · wiki
Record JSON
{
  "id": "page:docs-agent-mux-reference-13-invocation-modes",
  "_kind": "Page",
  "_file": "wiki/docs/agent-mux/reference/13-invocation-modes.md",
  "_cluster": "wiki",
  "attributes": {
    "nodeKind": "Page",
    "sourcePath": "docs/agent-mux/reference/13-invocation-modes.md",
    "sourceKind": "repo-docs",
    "title": "Invocation Modes",
    "displayName": "Invocation Modes",
    "slug": "docs/agent-mux/reference/13-invocation-modes",
    "articlePath": "wiki/docs/agent-mux/reference/13-invocation-modes.md",
    "article": "\n# Invocation Modes\n\n**Specification v1.0** | `@a5c-ai/agent-mux`\n\n---\n\n## 1. Overview\n\nAn *invocation mode* selects where a harness subprocess runs. The adapter contract is mode-agnostic: `buildSpawnArgs()` returns an abstract `SpawnArgs { command, args, env, cwd, stdin?, shell? }`, and a pure transform — `buildInvocationCommand()` — rewrites it into the concrete host command for the chosen mode.\n\nFour modes are supported:\n\n| `mode` | Host command | Notes |\n|---|---|---|\n| `local` | `SpawnArgs` unchanged | Default. |\n| `docker` | `docker run --rm -i ...` | Mounts `cwd` as `/workspace` by default. |\n| `ssh` | `ssh [opts] host -- 'cd <cwd> && K=V ... cmd args'` | `BatchMode=yes` set to avoid prompts. |\n| `k8s` | `kubectl [--context C] [-n NS] exec -i <pod> -- env ... cmd args` | Pod from `AMUX_K8S_POD` or the agent name. |\n\nSource: `packages/core/src/invocation.ts`, `packages/core/src/spawn-invocation.ts`.\n\n## 2. Types\n\n```ts\nexport type InvocationMode =\n  | LocalInvocation\n  | DockerInvocation\n  | SshInvocation\n  | K8sInvocation;\n\nexport interface LocalInvocation { readonly mode: 'local'; }\n\nexport interface DockerInvocation {\n  readonly mode: 'docker';\n  readonly image?: string;           // default: HARNESS_IMAGE_CATALOG lookup\n  readonly volumes?: string[];       // extra -v flags (host:container)\n  readonly env?: Record<string, string>;\n  readonly network?: string;\n  readonly workdir?: string;         // default: '/workspace'\n}\n\nexport interface SshInvocation {\n  readonly mode: 'ssh';\n  readonly host: string;             // user@host or host\n  readonly port?: number;            // default 22\n  readonly identityFile?: string;\n  readonly remoteDir?: string;       // default: SpawnArgs.cwd\n  readonly autoInstall?: boolean;    // default true (used by `amux remote`)\n}\n\nexport interface K8sInvocation {\n  readonly mode: 'k8s';\n  readonly namespace?: string;\n  readonly image?: string;\n  readonly resources?: { cpu?: string; memory?: string };\n  readonly context?: string;\n  readonly serviceAccount?: string;\n  readonly podStartupTimeoutMs?: number;   // default 120_000\n}\n```\n\n## 3. Harness image catalog\n\n`HARNESS_IMAGE_CATALOG` maps each built-in harness to a default Docker image used when `DockerInvocation.image` is omitted. `lookupHarnessImage(agent)` returns the entry (or `undefined` for unknown harnesses, causing `buildInvocationCommand` to throw).\n\n| Harness | Image |\n|---|---|\n| `claude`, `claude-code` | `ghcr.io/anthropics/claude-code` |\n| `codex` | `ghcr.io/openai/codex` |\n| `gemini` | `ghcr.io/google/gemini-cli` |\n| `copilot` | `ghcr.io/github/copilot-cli` |\n| `cursor` | `ghcr.io/cursor/cursor-agent` |\n| `opencode` | `ghcr.io/anomalyco/opencode` |\n| `pi` | `ghcr.io/a5c-ai/pi` |\n| `omp` | `ghcr.io/a5c-ai/omp` |\n| `openclaw` | `ghcr.io/openclaw/openclaw` |\n| `hermes` | `ghcr.io/a5c-ai/hermes` |\n| `aider` | `paulgauthier/aider` |\n| `goose` | `ghcr.io/block/goose` |\n\n## 4. `buildInvocationCommand(mode, spawnArgs, agent) -> InvocationCommand`\n\nPure function (no side effects, no subprocess). Returns:\n\n```ts\ninterface InvocationCommand {\n  command: string;\n  args: string[];\n  env: Record<string, string>;   // docker/ssh/k8s return {} — env is inlined in args\n  cwd: string;\n  stdin?: string;\n  shell: boolean;\n}\n```\n\nDispatch rules (verbatim from `spawn-invocation.ts`):\n\n- **local** — identity transform; env is merged but otherwise returned as-is.\n- **docker** — `docker run --rm -i -v <cwd>:<workdir> -w <workdir> [-v ...]* [--network N] [-e K=V]* <image> <cmd> <args...>`. `baseEnv` + `DockerInvocation.env` are folded into `-e` flags.\n- **ssh** — `ssh [-p N] [-i key] -o BatchMode=yes <host> -- 'cd <remoteDir> && K=V ... cmd args'`. Arguments and env values are shell-quoted.\n- **k8s** — `kubectl [--context C] [-n NS] exec -i <pod> -- env K=V ... cmd args`. Pod name comes from `process.env.AMUX_K8S_POD` if set, otherwise falls back to the agent name.\n\n## 5. `RunOptions.invocation`\n\n```ts\nclient.run({\n  agent: 'claude-code',\n  prompt: '...',\n  invocation: { mode: 'docker', image: 'ghcr.io/anthropics/claude-code:latest' },\n});\n```\n\nThe spawn loop calls `buildInvocationCommand()` once per attempt, after retry budget accounting. No behaviour change applies to event parsing — the harness inside the container/remote is still writing its native format to stdout/stderr.\n\n## 6. `amux remote` bootstrap\n\n`amux remote install|update <host>` ( `packages/cli/src/commands/remote.ts`) composes a four-step self-install pipeline through `buildInvocationCommand()`:\n\n1. **Probe** — `amux --version` on the target. Skipped steps if already installed (unless `--force` or subcommand is `update`).\n2. **Install amux** — `npm install -g @a5c-ai/agent-mux-cli` (or `npm update` for the update verb).\n3. **Install harness** — `amux install <harness> [--force]` (or `amux update <harness>`).\n4. **Verify** — `amux detect --all --json`.\n\nInvocation mode for remote is picked by `--mode ssh|docker|k8s|local` (default `ssh` when a host is given). `--harness <agent>` controls the harness deployed (default: `claude-code`).\n\n## 7. Security and environment\n\n- **docker** — env vars from `RunOptions.env` and `DockerInvocation.env` become `-e` flags. Callers should avoid placing secrets on the command line if that is a concern; prefer `--env-file` via a custom `volumes` mount.\n- **ssh** — `BatchMode=yes` is always set. SSH agent forwarding and host key policy are the caller's responsibility (via `~/.ssh/config`).\n- **k8s** — two sub-modes, chosen by `K8sInvocation.ephemeral` (defaults to `true` when no `pod` is provided):\n\n  - **Ephemeral** (`ephemeral: true` or `pod` unset): `buildInvocationCommand()` emits\n\n    ```\n    kubectl [--context C] [-n NS] run --rm -i --restart=Never \\\n      --image=<image> <generated-pod-name> \\\n      [--serviceaccount=SA] [--timeout=<podStartupTimeoutMs / 1000>s] \\\n      [--limits=cpu=C,memory=M] \\\n      [--env=K=V]... \\\n      -- <cmd> <args...>\n    ```\n\n    The pod name is generated as `amux-<agent>-<ts>-<seq>-<rand>`. `--rm` handles the happy-path teardown; additionally the invocation carries a `cleanup` hook (`K8sCleanup`) with `kubectl delete pod <name> --grace-period=0 --ignore-not-found=true` which `spawn-runner` fires detached on every exit path (completion, abort, crash) as a safety net in case the local `kubectl` was killed before `--rm` could finish.\n\n  - **Existing pod** (`pod` provided, or `ephemeral: false`, or legacy `AMUX_K8S_POD` env var): `kubectl [--context C] [-n NS] exec -i <pod> -- env K=V... <cmd> <args...>`. No cleanup hook is attached.\n\n  `resources.cpu`, `resources.memory`, `serviceAccount`, and `podStartupTimeoutMs` are consumed only by the ephemeral path.\n",
    "documents": []
  },
  "outgoingEdges": [],
  "incomingEdges": [
    {
      "from": "page:docs-agent-mux-reference",
      "to": "page:docs-agent-mux-reference-13-invocation-modes",
      "kind": "contains_page"
    }
  ]
}

Shortcuts

Back to overview
Open graph tab