SDK Surface
Understand the Agent SDK public surface in everyday, advanced, and framework-integration layers
SDK Surface
@downcity/agent exports Agent and Session execution APIs. Workspace, Plugin, and transport ownership
belongs to @downcity/city.
Layer 1: everyday core
Most local applications need only:
Workspace: create the project resource and security boundary and receive Shell.Agent: compose identity, model, instructions, Tools, and Sessions.City: own Workspaces, unique Plugin instances, Agent/Group collections, and transports.agent.sessions.create({ workspace })/get(): create or restore a Session in the current scope.session.prompt(): start one Turn.turn.finished: await the final result.agent.dispose(): release the Agent's Sessions and detach it from its current City.
const workspace = new Workspace({ id: workspace_id, path, shell });
const agent = new Agent({ id, model });
// Session 在创建时选择 Workspace。
try {
const session = await agent.sessions.create({ workspace });
const turn = await session.prompt({ query: "Inspect the project" });
const result = await turn.finished;
} finally {
await agent.dispose();
}The local SDK is session-first: Agent performs composition, while Session owns interaction and execution state.
Layer 2: common advanced APIs
Agent and Workspace
agent.set_instruction(): update static Agent instructions.city.plugins: add or remove Plugin instances and call host-management Actions.city.plugins.scope({ agent_id: agent.id, workspace_id: workspace.id }): inspect or call Plugins in an explicit Agent/Workspace execution scope.workspace.get_env()/set_env()/patch_env(): manage the project execution environment.agent.get_logger(): access Agent-level logs; Shell is read from the selected Workspace.
Session
get_info(): read Session state.subscribe(): subscribe to live Mutations.messages(): load message snapshots.stop(): stop the current execution.system(): load the current system.interactions()/respond(): handle approvals, questions, and other user interactions.fork(): branch from an existing Session.snapshot()/syncshot(): manage local Session system snapshots.set({ model }): override the model for one local Session.
For a live UI, load initial Session and Message snapshots before calling subscribe(). Reload snapshots after reconnecting; the event stream is not a complete database.
Layer 3: framework integration
Use these capabilities only when building plugins, servers, or custom runtime components:
CityRuntimefrom@downcity/type: the minimal cross-package City contract used when embedding Agent in a custom composition root. The concreteCityalready implements it.PluginContext: the restricted City projection for the current Agent/Workspace/Session/Turn, exported by@downcity/city/plugin.SessionTurnContext: the execution context that coordinates identity, lifecycle, steps, input, and output for one Turn; plugins receive only its read-onlyPluginExecutionContextprojection.create_session_turn_context(...): the standard factory used by custom executors or runtime components to create that Turn Context.SessionExecutorandSessionExecutorPort: the default executor for model requests and the tool loop, plus the portSessionLoopaccepts when you inject your own.- Interfaces such as
AgentSession: replace or extend default implementations. - RPC/HTTP types: implement a custom transport or protocol integration.
Network server implementations belong to @downcity/agent. Local Agent does not listen on ports or manage transport lifecycle.
Local and remote
| Capability | Local Agent | RemoteAgent |
|---|---|---|
| Create, get, and list Sessions | Yes | Yes |
| Prompt, subscribe, messages, stop, approvals, and fork | Yes | Yes |
| Inject Workspace, Shell, and Tools | Yes | No |
| Bind Plugins through City | Yes | Server-owned |
| Set the Agent default model | Yes | No |
session.set({ model }) | Yes | No |
session.set({ security }) / session.status() | Yes | Yes |
snapshot() / syncshot() | Yes | No |
| Manage the server transport | Not responsible | Connects only |
The server host always owns the model and system persistence policy for a remote Session.
Lifecycle rules
one Agent → multiple `agent.sessions.create({ workspace })` Sessions → one agent.dispose()- Agent is not bound to one Workspace; one Agent can enter multiple Workspaces.
AgentSessionsowns the Agent's Sessions. Each Session receives its own Workspace context and Plugin projection.agent.dispose()releases Session resources and its current City binding; City closes shared Plugin instances and lifecycle.RemoteAgent.close()closes only the client connection, not the server-side Agent.
Continue with the Agent API and Sessions overview.