Agent SDK 架构

City、Agent、Workspace、Session、Power 与 Shell 的职责和组合关系

Downcity 将执行主体、项目资源与扩展运行时分开。Agent 拥有身份、指令、模型、自定义 Tool 和 Session;Workspace 拥有项目资源与 Shell;City 持有 Power 唯一实例、生命周期与 Agent 集合。

import { Agent } from "@downcity/agent";
import { City } from "@downcity/city";
import { create_builtin_power_registrations } from "@downcity/powers";
import { Shell, Workspace } from "@downcity/city";

const agent = new Agent({ id, model, instruction });
const workspace = new Workspace({ id: "project", path, shell });
const city = new City({
  workspaces: [workspace],
  powers: create_builtin_power_registrations(),
});
city.agents.add(agent);
// Session 在创建时选择 Workspace。
const session = await agent.sessions.create({ workspace });

职责模型

依赖方向保持明确:

  • @downcity/agent 只依赖 @downcity/type 中的中立资源协议。
  • @downcity/city 依赖 Agent,并通过 Agent 内部绑定注入 Workspace、Tool 与 SessionHooks;Agent 不反向依赖 City。
  • 宿主在构造每个 Shell 时选择 Sandbox Provider;City 不理解具体后端。
  • Edge Adapter 使用 @downcity/type/workspace,不会加载 Node.js 本地实现。

Agent 是主体

一个 Agent 可以跨项目复用,不能在配置中永久绑定单一 Workspace。

const agent = new Agent({
  id: "repo-helper",
  model,
  instruction: "维护当前项目。",
  tools: { company_search: company_search_tool },
});

city.agents.add(agent);

const frontend = await agent.sessions.create({ workspace: frontend_workspace });
const backend = await agent.sessions.create({ workspace: backend_workspace });

Agent 不持有 Power。City 按 Power ID 持有唯一实例,并把全部能力投影到 Agent/Workspace execution entry。每次 Power Action 都获得当前 PowerContext,可以直接使用受限的 Agent、 Workspace、Session 与 Turn 句柄。Power 只有 City 级 initialize/dispose 生命周期; Agent/Workspace 只定义当前调用范围。

Workspace 是资源边界

Workspace 拥有:

  • 稳定的 Workspace ID 与规范化项目路径。
  • Rooted 项目文件能力和 File/Search 工具。
  • Workspace 环境变量。
  • 可选 Shell 及其 Sandbox Adapter。

Workspace 不创建 SessionStore,不理解 Agent ID,不注册 Power,不调用模型,也不创建 Storage。 构造参数中没有运行时数据根目录。

Shell 属于 Workspace,因为命令执行作用于 Workspace 资源。公开入口是:

import { Shell, Workspace } from "@downcity/city";

不再存在独立的 @downcity/shell 包。各平台 Sandbox 仍是独立安装的 package,由宿主注入 Shell。

Session 是执行边界

agent.sessions.create({ workspace }) 组合 Agent 与 Workspace,但不混合它们的所有权。Agent、Session 与 City 执行投影共同提供:

  • Workspace Tool、Agent 自定义 Tool 与 Power 桥接 Tool 组成的最终工具集合。
  • AgentSessions 与 Agent 领域的 LocalSessionStore。
  • 带当前 Agent/Workspace/Session/Turn 的 PowerContext 与 execution lease。
  • 日志、Power 调度任务和 Shell 绑定。

不同来源的 Tool 同名时直接失败,不会静默覆盖。同一个 Agent 可以持有绑定不同 Workspace 的多个 Session。Workspace 可以登记在 City 内,也可以由宿主在 City 外管理。

私有存储

City 注入本地持久化 Storage 时,运行状态集中保存在项目目录之外:

~/.downcity/
└── agents/
    └── <agent_id>/
        ├── sessions/
        ├── powers/
        ├── logs/
        └── schedule.jsonl

City Storage 只是底层文件或数据库能力。Agent 解释 agents/<agent_id>/ 业务作用域,并在其中 创建 Session 与 Power Store。项目 File/Search 工具使用另一套 rooted FileSystem,无法读取或 修改 Session 历史、Power 状态与运行时数据。

环境变量与检查点

环境变量描述项目执行环境,因此属于 Workspace:

<workspace>/.env < WorkspaceOptions.env

set_env() 与 patch_env() 更新 Workspace 快照并同步 Shell。已有 Session 会在下一个 Step 检查点提交新环境,避免模型调用执行到一半时上下文发生变化。

Power registry 更新、Session model 更新和 compact 也遵循相同的检查点规则。

生命周期

city.close() 会停止 Agent 与 Session,释放 City 内 Workspace、Storage 和 transport。City 外的 Workspace 仍由宿主负责释放。

Package 边界

Package拥有不拥有
@downcity/type跨 package 的中立资源协议具体资源实现与生命周期
@downcity/agentAgent、AgentSessions、Session、Store、SessionHooks、模型 Tool LoopCity 组合、Power 生命周期、项目资源实现、平台 Sandbox
@downcity/cityCity、Workspace/Shell 实现、Power SDK/runtime、Hook 调度、RemoteAgent、HTTP/RPC transport、本地宿主数据Agent 执行内核、具体内建 Power
Sandbox packages单个平台的原生进程隔离Workspace、Agent、Session 或 Power 业务

继续阅读:运行时架构。