Files
kandev/docs/specs/agents/runtime-updates.md
T
2026-07-27 19:34:13 +01:00

11 KiB

status, created, owner
status created owner
approved 2026-07-26 Kandev

Managed Agent Runtime Updates

Why

Operators need newly released agent capabilities and models without waiting for a Kandev release. They also need normal agent launches to avoid paying an upstream package-resolution cost on every session when a usable npm execution cache is already present.

What

  • Kandev launches the managed npm runtime for Claude, Codex, OpenCode, Copilot, and Gemini by package name without an exact version or an explicit latest tag.
  • Normal launches may reuse npm's execution cache. Cache reuse is best-effort; Kandev does not present it as a durable installed-version guarantee.
  • Each supported installed agent has a compact, accessible update icon action on its Settings > Agents card on desktop and mobile. Update versions, command details, progress, output, and results are not rendered in the card.
  • Opening the update action is read-only. It opens an update dialog that resolves and shows the current runtime version, upstream target version, exact built-in command, host-only scope, capability refresh, and active session behavior before an update can start.
  • The update starts only after the operator approves it in the dialog. The dialog then shows live stdout/stderr, progress, and the terminal success or failure state.
  • A successful package update automatically starts a fresh host capability probe. The returned runtime version, models, modes, configuration options, commands, and capability status replace the previous cached values.
  • An update affects new host probes, utility calls, and sessions. It does not restart or mutate an already-running agent session.
  • Kandev uses the ACP initialization protocol version and advertised capabilities as the compatibility boundary. Kandev does not gate managed npm runtimes by a repository-maintained package-version allowlist.
  • Package update commands are defined by Kandev's built-in agent metadata. Callers cannot submit package names, versions, registry URLs, or shell text.
  • Update jobs for the same agent are idempotent while queued or running. An install and update for the same agent cannot run concurrently.

The initial managed package set is:

Agent Managed runtime package
Claude @agentclientprotocol/claude-agent-acp
Codex @agentclientprotocol/codex-acp
OpenCode opencode-ai
Copilot @github/copilot
Gemini @google/gemini-cli

The managed package is the runtime Kandev uses for ACP capability discovery. Separately configured passthrough commands and native authentication helpers remain outside this update action when they use another package or installer.

Decision: ADR-2026-07-26-user-managed-agent-runtime-updates.

API surface

Agent catalogue

Installed-agent catalogue entries expose optional runtime-management metadata:

{
  "runtime_update": {
    "supported": true,
    "package": "@agentclientprotocol/claude-agent-acp",
    "current_version": "0.62.0"
  }
}

current_version is omitted when no successful capability probe has reported a runtime version. Unmanaged agents omit runtime_update.

Update jobs

  • GET /api/v1/agent-update/:agentName/preview resolves the current and upstream target versions and returns the exact trusted built-in update command without starting an update.
  • POST /api/v1/agent-update/:agentName starts or returns the active update job for a built-in managed agent.
  • GET /api/v1/agent-update/jobs returns active and recently completed update jobs.
  • GET /api/v1/agent-update/jobs/:id returns one retained update job.
  • State-changing update requests use the same Settings interlock as agent installation and profile mutation.

An update job contains:

{
  "job_id": "uuid",
  "agent_name": "claude-acp",
  "status": "resolving",
  "current_version": "0.62.0",
  "target_version": "0.63.0",
  "output": "",
  "error": "",
  "refresh_error": "",
  "started_at": "timestamp",
  "finished_at": "timestamp"
}

current_version, target_version, finished_at, error, and refresh_error are optional until known. The backend emits agent.update.started, agent.update.output, and agent.update.finished notifications with the same job identity and state. Output notifications carry only the appended output chunk.

An update preview contains:

{
  "agent_name": "claude-acp",
  "package": "@agentclientprotocol/claude-agent-acp",
  "current_version": "0.62.0",
  "target_version": "0.63.0",
  "command": [
    "npm",
    "exec",
    "--yes",
    "--prefer-online",
    "--package=@agentclientprotocol/claude-agent-acp",
    "--",
    "node",
    "-e",
    ""
  ],
  "command_string": "npm exec --yes --prefer-online --package=@agentclientprotocol/claude-agent-acp -- node -e \"\""
}

The preview endpoint accepts only the built-in agent name. Package names, versions, registry URLs, and command arguments are not caller-controlled.

State machine

State Trigger Observable behavior
queued The backend accepts an update request. The action is disabled and shows that the update is queued.
resolving A worker starts the job. Kandev discovers the current runtime version and upstream npm target.
updating Version resolution succeeds. Kandev streams package-update output and shows current → target.
refreshing The package update succeeds. Kandev re-probes the host runtime and keeps the action disabled.
succeeded The capability probe succeeds, or the package updated but capability refresh returned a recoverable error. The UI shows the installed target. When refresh succeeded, it replaces model and mode data. A refresh-only error is shown without claiming the package update was rolled back.
failed Registry lookup or package update fails, the command times out, or ACP initialization is incompatible. The UI retains the previous model list and shows the captured error and output.

Jobs are terminal after succeeded or failed. Retrying creates a new job.

Failure modes

  • If npm registry metadata cannot be resolved, the job fails before changing the runtime and retains the prior capability data.
  • If preview version resolution fails, the dialog shows the error and keeps approval disabled. No update job or package command starts.
  • If the package update command fails or times out, the job fails and retains the prior capability data.
  • If the package update succeeds but the capability probe fails because authentication is required or another recoverable probe error occurs, the job reports package-update success plus refresh_error; the previous model list remains visible and the operator can authenticate or retry the refresh.
  • If the updated runtime negotiates an unsupported ACP protocol version or cannot initialize, the job fails visibly. Kandev does not silently fall back to a repository-pinned runtime.
  • Raw process output is bounded using the existing in-memory job output limit. Package-manager credentials and configured registry authentication are never returned as structured fields.
  • Loss of the browser connection does not cancel a running job. Reopening the page recovers retained job progress through the jobs endpoint.

Persistence guarantees

  • Update jobs and capability data are process-local and do not survive a Kandev backend restart.
  • Completed jobs remain queryable for the existing short job-retention window.
  • Settings does not rehydrate retained update jobs after a browser page restart. Update dialog state, output, and results are intentionally page-local and disappear when the page is restarted.
  • npm's host cache may survive Kandev restarts, but Kandev does not own or guarantee that cache.
  • After a backend restart, normal host capability probing reports whichever runtime npm resolves in that environment.

Scenarios

  • GIVEN a managed agent with a cached runtime, WHEN a new session starts without an explicit update, THEN Kandev invokes the unversioned package spec and does not require a repository-maintained version pin.
  • GIVEN Claude reports runtime version 0.62.0 and npm reports 0.63.0, WHEN the operator opens its update action, THEN the dialog shows 0.62.0 → 0.63.0, the exact built-in command, and how the host update affects capabilities and active sessions without starting the command.
  • GIVEN the update dialog has a resolved preview, WHEN the operator approves the update, THEN Kandev starts exactly one update and the dialog streams stdout/stderr until the job is terminal.
  • GIVEN an update succeeds and the new runtime advertises an additional model, WHEN the automatic capability probe completes, THEN the new model appears without a page reload or manual Rescan.
  • GIVEN an update is already queued, resolving, updating, or refreshing, WHEN the operator selects the action again, THEN Kandev returns the existing job and does not run a second update.
  • GIVEN an install is active for an agent, WHEN an update is requested for that agent, THEN Kandev returns the active maintenance job rather than running install and update concurrently.
  • GIVEN npm registry lookup fails while preparing the dialog, WHEN the update action is opened, THEN the dialog shows a retryable preview failure, keeps approval disabled, and starts no update job.
  • GIVEN npm registry lookup succeeds for the preview but fails after approval because the registry changed, WHEN the update job resolves its target again, THEN the dialog shows a retryable update failure and retains the previous models.
  • GIVEN the package update succeeds but the fresh probe requires authentication, WHEN the job finishes, THEN the dialog reports the new package version and refresh error, the previous models remain available, and the card keeps its existing authentication recovery action.
  • GIVEN an agent is unmanaged or native-only, WHEN Settings renders its installed card, THEN no update action is shown.
  • GIVEN an update dialog has shown progress or a terminal result, WHEN the operator restarts the page, THEN the dialog is closed and no prior update details, output, or result appear on the agent card or in a newly opened dialog.
  • GIVEN an update is running on a phone viewport, WHEN the operator views the update surface, THEN current and target versions, the command, progress, output, and retry state are reachable by touch without horizontal page scrolling.
  • GIVEN an agent session is already running, WHEN its host runtime is updated, THEN the existing session continues unchanged and only later probes or launches use the updated runtime.

Out of scope

  • Scheduled or automatic package updates.
  • Exact package-version pins, version allowlists, rollback, or user-selected historical versions.
  • Updating configured remote executors or every running container from the host Settings action.
  • Restarting or hot-swapping active agent sessions.
  • Managing native-only update channels such as Cursor.
  • Updating separately distributed passthrough or authentication helper packages when they are not the managed ACP runtime.
  • Resuming or recovering update dialog state after a browser page restart.