Agent SDK

Build local or remote Agents with project files, sandboxed commands, plugins, and persistent Sessions

Agent SDK

@downcity/agent provides a local Agent and a remote RemoteAgent. Both are session-first: Agent composes capabilities, while Session owns a continuous conversation and its execution state.

One-minute mental model

ObjectOwnsDoes not own
WorkspaceProject files, env, Store, Tools, Shell, and SandboxModels, plugins, Session orchestration
AgentModel, instructions, final Tools, plugins, and SessionsHTTP/RPC transports
SessionConversation state, message history, execution order, and approvalsProject resource ownership
PluginContextStable Agent capabilities projected to a PluginA second Agent facade
SessionTurnContextExecution context and lifecycle for one TurnLong-lived Agent state
RemoteAgentAccess to a server-side Agent and its SessionsServer-side model configuration

Choose local or remote

ScenarioUse
Agent and application run in the same Node.js processAgent
The application injects models, Tools, plugins, and Shell directlyAgent
Another process already exposes the Agent over HTTP/RPCRemoteAgent
The client only creates Sessions, sends prompts, and subscribesRemoteAgent

Network serving does not belong to Agent. Use AgentHTTP or AgentRPC from @downcity/server to expose a local Agent.

Shell is the standard entry for project commands and processes. The SDK does not select a platform Sandbox automatically; install and inject the Adapter for the current operating system. This example uses macOS:

import { Agent, Workspace } from "@downcity/agent";
import { MacOsSeatbeltSandbox } from "@downcity/sandbox-macos";
import { Shell } from "@downcity/shell";

const shell = new Shell({
  sandbox: new MacOsSeatbeltSandbox(),
});

const workspace = new Workspace({
  path: process.cwd(),
  shell,
});

const agent = new Agent({
  id: "repo-helper",
  workspace,
  model,
});

try {
  const session = await agent.sessions.create();
  const turn = await session.prompt({ query: "Summarize this repository" });
  const result = await turn.finished;
  console.log(result.text);
} finally {
  await agent.dispose();
}

Remember this primary path:

Workspace + Shell → Agent → Session → prompt() → turn.finished → dispose()

agent.dispose() releases the Agent and its exclusive Workspace, including plugin lifecycle, ActionSchedule, Shell processes, PTYs, and Sandbox resources. Do not dispose the same Workspace again in the normal flow.

Model ownership

In pure SDK embedding, the host owns model instances:

  • Set the default with new Agent({ model }).
  • Or override it for one local Session with await session.set({ model }).

In a Downcity project, the CLI host resolves the model from project configuration and the City AIService catalog. Remote Sessions do not expose client-side model configuration; the server host always owns the model.

  1. Local Agent quickstart
  2. Sessions overview
  3. Shell and Sandbox
  4. Tools and plugins
  5. Remote Agent
  6. SDK Surface
  7. Agent SDK architecture