Tools 和 Powers
给 Agent 配置 Tool,并通过 City 提供 Power
Tool 与 Power 都能参与 Session 执行,但所有权不同:Agent 持有自定义 Tool;City 持有 Power 唯一实例、配置投影与生命周期。
自定义 Tools
本地 Agent 直接接收自定义 Tool:
const agent = new Agent({
id: "repo-helper",
tools: {
my_tool,
},
});这些 Tool 会与当前 Session 所选 Workspace 的 Tool 合并。名称冲突会直接报错,不会静默覆盖。
Workspace 与 Shell
Workspace 默认提供 grep、find、read、write 和 edit。需要命令执行时显式配置 Shell:
import { Agent } from "@downcity/agent";
import { MicrosandboxProvider } from "@downcity/sandbox-microsandbox";
import { Shell, Workspace } from "@downcity/city";
const agent = new Agent({ id: "repo-helper" });
const workspace = new Workspace({
id: "project",
path: "/path/to/project",
shell: new Shell({
sandbox_provider: new MicrosandboxProvider(),
}),
runtime_path: "/path/to/downcity-runtime/project",
});Shell 额外提供 shell_exec 与 shell_session。文件和搜索 Tool 始终受 Workspace 根目录约束;审批与异步问题归属于具体 Session,通过 session.interactions() 和 session.respond(...) 处理。
City 提供 Powers
Agent 构造函数不接收 Power。把 registration 交给 City 后,所有 Agent 会自动获得它:
import { Agent } from "@downcity/agent";
import { City } from "@downcity/city";
import { create_builtin_power_registrations } from "@downcity/powers";
import { Workspace } from "@downcity/city";
const workspace = new Workspace({
id: "project",
path: "/path/to/project",
});
const agent = new Agent({ id: "repo-helper", model });
const city = new City({
workspaces: [workspace],
powers: create_builtin_power_registrations(),
});
city.agents.add(agent);City 会把全部已注册 Power 自动提供给全部 Agent。运行中的 City 可通过
city.powers.add() 与 city.powers.remove() 动态修改 Power 集合。
一个 City 中每个 Power ID 只有一个实例,并且只有 City 级 initialize/dispose 生命周期。
Agent 与 Workspace 只提供每次调用的上下文,不拥有 Power 生命周期。
City 级配置
需要配置的 Power 由宿主提供唯一 Config store。配置不进入 Agent,也不决定 Power 实例数量:
const city = new City({
power_host: {
config: (power_id) => open_power_config_store(power_id),
},
});每个 Power ID 在一个 City 中只有一份配置。多账号结构和选择规则由 Power 自己表达,City 不提供通用命名配置层。配置保存后,Power 负责刷新受影响的长期资源。
调用 Power
宿主从 Agent/Workspace 执行入口调用 Action 或 Hook:
const result = await city.powers.scope({ agent_id: agent.id, workspace_id: workspace.id }).run_action({
power: "memory",
action: "search",
payload: { query: "项目约定" },
});
const enriched = await city.powers.scope({ agent_id: agent.id, workspace_id: workspace.id }).pipeline("chat.enrich_message", input);
await city.powers.scope({ agent_id: agent.id, workspace_id: workspace.id }).guard("review.require_checked", enriched);Power 声明 Action 时,宿主为它推送一个以 Power 名命名的 AgentTool。模型用 { action, args } 调用;省略 action 时返回动作索引及其 schema。Power 的 system() 文本在 session.system_context 检查点贡献。
PowerContext 直接通信
Power 作者 API 从 @downcity/city/power 导入。Action、Hook、System 和 Availability 获得 PowerContext,其中包含受限的 city、agent、workspace、session、turn、config 和 storage 句柄。
context.session 与 context.agent.sessions 都是可直接调用的进程内对象,不需要只保存 session_id 再回查宿主。Workspace 文件使用 context.workspace.files;Power 私有文件使用 context.storage.files。
HTTP
Power 可声明结构化 HTTP route。City 统一挂载、鉴权并注入请求对应的 PowerContext;Power 不创建独立服务器。