English | 中文
一对插件加一个 Godot 模式(agent preset),让 AI agent 通过回环 TCP JSON-lines 驱动 Godot 4.x 编辑器:打开/重新加载场景、运行/停止当前或主场景、观察播放错误、检查场景树和脚本、设置项目设置、lint GDScript、列出项目文件以及导出构建。
| 路径 | 内容 | 运行于 |
|---|---|---|
addons/agent_rpc/ |
Godot 编辑器插件(EditorPlugin + EditorDebuggerPlugin)——TCP 客户端、消息分发、播放错误环形缓冲 |
Godot 编辑器进程 |
dsh-godot-tool/ |
DeepSeek Harness 插件(@deepseek-ai/dsh-godot-tool)——回环 TCP 服务端(GodotRpcBridge)+ 27 个 godot_* 面向模型工具 |
DeepSeek Harness |
agent-presets/godot/ |
Godot 模式 agent preset——把两端组装成面向 Godot 开发的精简 agent(persona、shell/fs/jobs、compaction、子代理、goal、plan mode) | DeepSeek Harness |
两端使用同一种线上协议:TCP 127.0.0.1:8765(回退 8765–8774)上的换行分隔 JSON、令牌认证握手、仅回环。Godot 模式 在 harness 侧把这两端组装成开箱即用的 Godot 开发 agent。本文档是唯一参考——先快速开始,再讲线上协议,然后是两端与模式各自的手册。
┌─────────────────────────────┐ ┌──────────────────────────────┐
│ Godot 4.x 编辑器 │ TCP │ DeepSeek Harness │
│ │ JSON-L │ │
│ addons/agent_rpc(客户端) │◄────────►│ dsh-godot-tool(服务端) │
│ EditorPlugin + 调试器 │ 8765 │ GodotRpcBridge + 27 工具 │
└──────────────┬──────────────┘ └──────────────┬───────────────┘
│ 每秒轮询端点文件 │ 发布
▼ ▼
~/.pi/agent/x-agent-godot-rpc.json ~/.dsh/godot/endpoint.json
(插件默认) (harness 插件默认)
Godot 模式(agent-presets/godot/)在 harness 侧把 dsh-godot-tool/ 插件组装成精简的 Godot 开发 agent——见 Godot 模式。
把 addons/agent_rpc/ 复制到 Godot 项目的 addons/ 文件夹,然后在 项目设置 → 插件 中启用 Agent RPC。
两种方式:
- 从本仓库(源码):通过
--patchoverlay 或项目插件行把 Harness 指向dsh-godot-tool/src/index.ts,并在组合中加入dsh-tools。 - 从 harness workspace:如果你在 deepseek-harness 仓库内构建,包位于
packages/extensions/tool-godot(@deepseek-ai/dsh-godot-tool);本副本与其保持同步。
插件每秒轮询端点文件。默认是 ~/.pi/agent/x-agent-godot-rpc.json;harness 插件默认发布 $DSH_HOME/godot/endpoint.json。把一边指向另一边:
- 设置环境变量
AGENT_RPC_ENDPOINT(推荐),或 - 设置 ProjectSettings 键
agent_rpc/endpoint_file,或 - 把 harness 插件的
endpointPath配置为插件的文件路径。
每个 godot_* 工具默认关闭(harness 插件配置中 enabledTools 为空)。显式选择启用:
使用 Godot 模式时无需这一步——
tool-godot一行已包含在预设内 (enabledTools为全部 27 个工具),下面的片段只适用于不启用 agent preset 的裸部署(CLI/TUI、--patch源码安装)。
# dsh cordis.yml
- id: tool-godot
name: '@deepseek-ai/dsh-godot-tool'
config:
enabledTools: ['godot_editor_info', 'godot_run_scene', 'godot_play_errors']然后启动 harness、打开 Godot 项目,agent 就可以驱动编辑器了。
- 桥开始监听后约 1 秒内,插件会在 Godot Output 面板打印
Agent RPC: connected to …。 - 从 agent 一侧调用
godot_editor_info——端到端通路正常时返回{ godotVersion, projectPath, editedScene, playing }。若失败,对照故障排查表检查。
两个进程、一个回环 socket、一个把它们连起来的端点文件:
- 先启动 harness(或先启动 Godot——两种顺序都行)。
dsh-godot-tool插件绑定127.0.0.1:8765(忙时向上尝试至8774),生成 32 位十六进制令牌,并原子写入端点文件{ host, port, token }供插件发现。 - 插件每秒轮询该文件,文件变化或消失时自动重连。文件按
AGENT_RPC_ENDPOINT→agent_rpc/endpoint_file→ 旧默认~/.pi/...的顺序解析。 - 首次 TCP 连接时插件发送
editor_ready,携带令牌和addonVersion;桥认证后记录其projectPath并分配clientId。 - agent 调用
godot_*工具 → 桥校验(白名单、工具闸、参数卫生、跨项目路由)→ 发送 JSON 行请求 → 插件对编辑器执行操作 → 以ok:true/ok:false应答 → 桥解析工具调用结果。 - 播放期间插件推送
play_error事件进入桥的环形缓冲(上限 50);godot_play_errors读取它们。插件绝不会自动停止播放——由 agent 调用godot_stop_scene。
锁定插件 0.6.3、协议世代 1.0 + 1.2 + 1.3(27 个 RPC 方法)。改动任何一半时,请在同一提交内更新本节。
| 属性 | 值 |
|---|---|
| 地址 | 仅回环 —— 127.0.0.1 |
| 端口 | 8765,忙时回退到 8765–8774 |
| 编码 | UTF-8、换行分隔 JSON(每行一个对象,无长度前缀,无二进制) |
| 认证 | 插件在 editor_ready 时出示的 32 位十六进制令牌 |
// 请求 —— 服务端 → 插件
type GodotRpcRequest = {
id: string; // 调用方的 randomUUID
method: string; // 见下方名单
...params // 方法专属参数
};
// 响应 —— 插件 → 服务端(按 id 配对)
type GodotRpcResponse =
| { id: string; ok: true; result: unknown; routedTo?: string }
| { id: string; ok: false; error: string; routedTo?: string };
// 事件 —— 插件 → 服务端(无 id)
type GodotRpcEvent =
| { type: "editor_ready"; godotVersion: string; projectPath: string;
token?: string; addonVersion?: string; clientId?: string }
| { type: "scene_changed"; path: string; clientId?: string }
| { type: "play_error"; severity: string; message: string; clientId?: string }
| { type: "disconnected"; clientId?: string };分帧规则(0.6.3 修复):用 data.has("method") 区分请求与事件,绝不要用 data.has("type")。list_project_files 接受 type 参数用于过滤,同时携带 method 和 type 的请求会被旧启发式静默丢弃。
服务端把 { host, port, token } 发布到插件每秒轮询的 JSON 文件(plugin.gd 中的 _endpoint_config_path());文件变化时插件自动重连。
| 字段 | 类型 | 说明 |
|---|---|---|
host |
string | 复用时必须是 127.0.0.1 或 localhost;其他值被拒绝并重新生成令牌 |
port |
number | 1–65535;超出范围则回退 |
token |
string | 32 位十六进制(/^[0-9a-f]{32}$/i);不匹配则回退 |
version |
number | 线路格式版本;当前 = 1 |
updatedAt |
string | 每次成功监听时写入的 ISO 时间戳 |
文件原子写入(tmp + 重命名),服务端停止时故意不删除,以便下次启动复用令牌、跳过握手抖动。
| 工具(启用时) | RPC 方法 | 协议世代 |
|---|---|---|
godot_editor_info |
get_editor_info |
1.0 |
godot_open_scenes |
get_open_scenes |
1.0 |
godot_edited_scene |
get_edited_scene |
1.0 |
godot_open_scene |
open_scene |
1.0 |
godot_reload_scene |
reload_scene |
1.0 |
godot_run_scene |
run_current_scene(+ wait_ms) |
1.0 |
godot_run_main_scene |
play_main_scene(+ wait_ms,≡ F5) |
1.0 |
godot_import_resources |
import_resources(+ 可选 paths) |
1.0 |
godot_play_errors |
get_play_errors(+ 可选 clear) |
1.0 |
godot_stop_scene |
stop_scene |
1.0 |
godot_get_scene_tree |
get_scene_tree(+ max_depth) |
1.0 |
godot_get_node_properties |
get_node_properties |
1.0 |
godot_get_debugger_state |
get_debugger_state |
1.2 |
godot_set_breakpoint |
set_breakpoint(+ condition?、remove?) |
1.2 |
godot_find_unused_resources |
find_unused_resources(+ root?) |
1.2 |
godot_get_project_setting |
get_project_setting |
1.2 |
godot_set_project_setting |
set_project_setting |
1.2 |
godot_lint_scripts |
lint_scripts |
1.2 |
godot_export_project |
export_project(+ preset、output_dir、debug?) |
1.2 |
godot_list_project_files |
list_project_files(+ type?、pattern?、limit?、cursor?) |
1.3 |
godot_resolve_uid |
resolve_uid(uid? 异或 path?) |
1.3 |
godot_wait_for_import_done |
wait_for_import_done(+ timeout_ms?) |
1.3 |
godot_list_global_classes |
list_global_classes |
1.3 |
godot_find_class_name_conflicts |
find_class_name_conflicts(+ include_addons?) |
1.3 |
godot_inspect_script |
inspect_script |
1.3 |
godot_list_export_presets |
list_export_presets |
1.3 |
godot_check_export_templates |
check_export_templates |
1.3 |
ping 是协议级健康检查,没有对应的用户工具。白名单位于 dsh-godot-tool/src/protocol.ts(GODOT_RPC_ALLOWED_METHODS),工具到方法的门控映射在 GODOT_RPC_METHOD_TOOL;白名单之外的请求在到达桥之前即被拒绝。
| 常量 | 值 | 用途 |
|---|---|---|
GODOT_RPC_DEFAULT_PORT |
8765 | 监听 |
GODOT_RPC_FALLBACK_PORT_END |
8774 | 监听回退 |
GODOT_RPC_DEFAULT_WAIT_MS |
3000 | 播放错误窗口 |
GODOT_RPC_MAX_WAIT_MS |
15000 | 播放错误窗口上限 |
GODOT_RPC_BASE_TIMEOUT_MS |
8000 | 默认请求超时 |
GODOT_RPC_EXPORT_TIMEOUT_MS |
5 × 60 000 | export_project 硬杀 |
GODOT_RPC_EXPORT_GRACE_MS |
15 000 | 导出返回后的宽限 |
GODOT_RPC_GRACE_PERIOD_MS |
8000 | 断连宽限窗口 |
GODOT_LIST_FILES_DEFAULT_LIMIT / MAX_LIMIT |
500 / 5000 | list_project_files 分页 |
GODOT_WAIT_DEFAULT_TIMEOUT_MS / MAX |
30 000 / 60 000 | wait_for_import_done |
run_current_scene / play_main_scene 清空缓冲、开始播放,并在可配置窗口(默认约 3 秒,上限 15 秒)后返回目前捕获到的错误:
{
"started": true,
"playing": true,
"waitMs": 3000,
"playMethod": "play_current_scene",
"errors": [{ "severity": "error", "message": "..." }]
}来源(rpc_debugger.gd):Output 面板的 ERROR / WARN 消息、调试器错误页、断点命中原因。插件绝不会在出错时自动停止播放——调用方必须调用 stop_scene。
| 闸门 | 位置 | 作用 |
|---|---|---|
| 服务端回环绑定 | bridge.ts —— server.listen(port, '127.0.0.1') |
内核拒绝非回环绑定 |
| 令牌握手 | editor_ready —— 32 位十六进制比对 |
失败计为 missing_token(插件 < 0.2.0)/ bad_token(令牌过期) |
| 方法白名单 | protocol.ts —— GODOT_RPC_ALLOWED_METHODS |
白名单之外在到达桥之前即被拒绝 |
| 工具闸(双层) | 注册 + 分发 | 只注册 enabledTools(模型 schema 永不包含被禁用工具),且桥对每个线上方法重新检查门控工具 |
| 参数卫生 | protocol.ts —— checkHygiene |
字符串 ≤ 4096、数组 ≤ 512、嵌套字符串 ≤ 4096 |
set_project_setting 拒绝列表 |
protocol.ts |
禁止 autoload/*、input/*、editor_plugins/enabled、调试日志/警告/形状/颜色、TLS 证书包覆盖、project_settings_override/* |
| 跨项目路由 | bridge.ts |
请求只到达 projectPath 与调用会话 cwd 共享的客户端 |
| 断连拒绝 | bridge.ts |
路由到已断连客户端的在途请求以 client disconnected 失败 |
| English | 中文 | 一句话定义 |
|---|---|---|
| addon | 插件 | Godot 编辑器扩展;位于 <project>/addons/<name>/;在 project.godot [editor_plugins] 中声明 |
EditorPlugin |
编辑器插件基类 | 在编辑器进程中运行的代码所继承的 Godot 基类 |
EditorDebuggerPlugin |
编辑器调试器插件基类 | 钩住 ScriptEditorDebugger 信号,无需派生子进程即可捕获运行时错误 |
EditorInterface |
编辑器接口单例 | 打开场景、控制播放、列出打开场景等的静态访问器 |
ProjectSettings |
项目设置 | Godot 的项目级配置存储;键使用 / 分隔路径,如 autoload/Foo |
| autoload | 自动加载 | 在 autoload/* 键下注册的单例脚本。已列入 set_project_setting 拒绝列表 |
| endpoint file | 端点文件 | 桥发布的 {host, port, token} JSON 文件,插件每秒轮询 |
| handshake | 握手 | 首次 TCP 连接时发送的 editor_ready 事件,携带插件提供的 token 和 addonVersion |
| token | 令牌 | 授权插件与桥通信的 32 位十六进制共享密钥 |
addonVersion |
插件版本 | 插件的 plugin.cfg 版本,在 editor_ready 时上报,便于服务端警告协议不匹配 |
routedTo |
路由目标 | 请求未指定客户端时桥自动路由到的 clientId |
| tool gate | 工具闸 | 双层(注册 + 分发)检查:RPC 被受理前必须启用对应工具 |
| JSON-lines | JSON 行协议 | 每行一个 JSON 对象的 UTF-8 流,以 \n 分隔 |
| play error | 播放期错误 | run_current_scene / play_main_scene 会话期间捕获的运行时错误/警告 |
| ping | 健康检查 | 唯一没有对应用户工具的 RPC 方法 |
| ring buffer | 环形缓冲 | 保存最近 play_error 事件的有界缓冲(上限 50) |
客户端一半——让 AI agent 驱动编辑器的 TCP JSON-lines 桥:仅回环传输、令牌握手、默认关闭的工具闸。
addons/agent_rpc/
plugin.cfg # 插件清单(名称、version="0.6.3"、入口脚本)
plugin.gd # EditorPlugin —— TCP 客户端、消息分发、播放错误环形缓冲
rpc_debugger.gd # EditorDebuggerPlugin —— 钩住 ScriptEditorDebugger output / debug_data / breaked
没有自动加载、没有场景文件——一切都在编辑器进程中运行(@tool)。
- 把
addons/agent_rpc/复制到 Godot 项目的addons/文件夹。 - 在 Godot 中:项目设置 → 插件 → 启用 "Agent RPC"。
- 启动你的 agent(如带
dsh-godot-tool的 DeepSeek Harness)。它监听127.0.0.1:8765,忙时回退到8765–8774,并发布插件轮询的端点文件。 - 插件约 1 秒内连接成功,Godot Output 面板打印
Agent RPC: connected to …。
升级插件后请重新安装,并重新加载项目或重启 Godot。
插件每秒轮询端点文件并自动重连。文件按以下顺序解析:
- 环境变量
AGENT_RPC_ENDPOINT——例如当 DeepSeek Harnessdsh-godot-tool插件发布到$DSH_HOME/godot/endpoint.json时指向该路径。(推荐。) - ProjectSetting 键
agent_rpc/endpoint_file——显式的项目内路径。 - 旧默认值——
~/.pi/agent/x-agent-godot-rpc.json。
环境变量优先;两者都覆盖旧默认值。文件本身必须包含 { "host": "127.0.0.1", "port": 8765, "token": "<32-hex>", "version": 1 }。
首次 TCP 连接时,插件发送携带 token 和 addonVersion 的 editor_ready 事件。复用上一个端点文件的令牌,"先启动 Godot、再启动 agent"约 1 秒即可就绪,无需重新安装任何东西。
| 症状 | 可能原因 | 先查什么 |
|---|---|---|
无连接,握手失败 missing_token |
插件早于 0.2.0(editor_ready 不带令牌) |
plugin.cfg 版本;重装插件 |
无连接,握手失败 bad_token |
插件持有过期令牌;服务端已写入新令牌 | 确认两端读取同一个端点文件;重装插件强制重读 |
run_current_scene 有脚本错误却返回空 errors |
EditorDebuggerPlugin 未钩住 ScriptEditorDebugger(调试器 UI 尚未构建,或 Godot 版本差异) |
打开 Godot 调试器面板,确认插件已激活 |
run_current_scene 后播放卡住 |
wait_ms 已到但插件从不自动停止 |
这是设计行为——调用 stop_scene |
export_project 超过 5 分钟仍挂起 |
无头 Godot 卡在缺失的导出模板或脚本启动 | 桥在导出超时时杀进程;检查 Godot 输出 |
set_project_setting 被拒 "forbidden prefix" |
写入 autoload/*、input/*、editor_plugins/enabled 等 |
安全模型中的拒绝列表是最终的 |
list_project_files 总是超时 |
服务端用了旧的 data.has("type") 分帧启发式 |
分帧规则必须是 data.has("method")——见消息形态 |
| lint 失败时编辑器冻结约 30 秒 | --check-only 在主线程运行 |
使用 plugin.gd 中的线程 worker 模式;_exit_tree 必须等待线程 |
服务端一半——@deepseek-ai/dsh-godot-tool:回环 TCP JSON-lines 服务端外加 27 个 godot_* 面向模型工具。
GodotRpcBridge(src/bridge.ts)——绑定到回环地址的node:net服务端,使用插件协议:换行分隔 JSON、令牌握手(editor_ready)、按连接分配clientId、按 id 关联请求响应,以及捕获play_error/scene_changed事件。- 27 个工具(
src/tools.ts)——每个线上方法一个defineTool,全部通过桥分发。完整名单见方法名单。
插件发布插件每秒轮询的端点文件(默认 $DSH_HOME/godot/endpoint.json,或 Config.endpointPath),因此"先启动 harness,再打开 Godot"大约一秒钟即可就绪,无需重新安装插件。
| 字段 | 默认值 | 含义 |
|---|---|---|
port |
8765 |
首选回环监听端口;桥会向上尝试至 fallbackPortEnd。 |
fallbackPortEnd |
8774 |
报告端口耗尽前尝试的最后一个端口。 |
token |
自动生成的 32 位十六进制 | 插件必须在 editor_ready 时出示的共享密钥。 |
endpointPath |
~/.dsh/godot/endpoint.json |
插件轮询的端点文件;指向与插件读取的相同文件。 |
enabledTools |
[] |
要注册的工具名。默认空——部署选择启用之前,模型看不到任何 godot 工具。 |
端点文件原子写入(tmp + 重命名),并在插件卸载时故意保留:下次启动复用令牌,避免握手抖动。
enabledTools 是参考桌面实现的双层开关,折叠进一个插件:
- 注册层——只注册选择启用的工具,因此模型的功能调用 schema 永远不会包含被禁用的工具。
- 分发层——桥对每个线上方法重新检查门控工具(
GODOT_RPC_METHOD_TOOL),因此即使直接调用桥也无法触达被禁用的方法。
函数/命名空间插件:导出 name / inject / Config / apply,没有 export default。多余的 export default 会经 Loader 的 unwrapExports 折叠模块并丢弃 inject——与 harness postmortem 0001-acp-default-export-drops-inject 记录的同一种失败模式。
工具 schema——模型只看到 Config.enabledTools 中列出的工具对应的 godot_* schema;描述会指明线上方法的参数以及任何上下文大小上限(场景树序列化预算、列表分页)。每个启用工具在每次请求中产生固定 schema 成本;工具集不变时前缀稳定。
工具调用结果——每次成功调用原样返回插件的 result 作为规范 JSON 值(例如 get_editor_info → { godotVersion, projectPath, editedScene, playing })。线上 ok:false 或本地拒绝(方法不允许、工具被禁用、参数卫生、未知客户端、跨项目路由、超时、客户端断连)以 Error: <message> 呈现。结果令牌随插件响应增长,受其序列化预算约束(5000 节点场景树、500/5000 文件分页、50 条错误环形缓冲)。
包携带一个客户端半部(src/client.ts,dsh.client 声明在 package.json),向 DSH web UI 贡献三个可加性槽位:
conversation.composer.dock——输入框上方的紧凑状态条:连接圆点、版本/项目、▶播放中、⚠ N错误徽标;点击开合右侧面板。shell.overlay——唯一的合并面板:状态表(连接/版本/项目/编辑场景/播放/断点等)、播放错误列表、调试动作(检测连接 / 运行当前 / 运行主场景 / 停止播放 / 清空错误)、自检与原始 JSON。打开新对话(空白会话)时自动弹出,会话激活后自动收起。conversation.input.left——输入框工具行的「Godot 检测」一键按钮(hero 阶段也渲染),把检测指令作为下一条消息发送,无需手打。
数据模型:动态 Host 沙箱扣留 ToolRuntime.execute,纯客户端面板无法自行调用 godot_* 工具,因此面板镜像会话内最近的工具结果(godot_editor_info / godot_get_debugger_state / godot_play_errors),调试动作经输入框(inputActions.setDraft + submit)路由给 agent 执行后回流。这也意味着状态反映的是"最近一次工具调用";每次 godot_* 工具运行后面板自动更新。
启用:在 harness 工作区内构建时,包被 web 构建扫描(dsh.client)并打包 src/client.ts;部署挂载 tool-godot 后面板即出现在 web UI。源码形态(--patch 指向 src/)下,web 构建同样以 ./client 导出解析该客户端半部。
模式门控:客户端模块虽被全局发现(host 载体行),但每个座位都校验所绑定会话的 agentPreset——非 godot 预设的会话一律不渲染。配合 tool-godot 移入 Godot模式预设后,UI 与 godot_* 工具都只在用户开启 Godot模式时出现,其他模式目录与界面保持干净。
升级路径:若需免 agent 中转的秒级实时轮询,可在 host 侧把 GodotRpcBridge 暴露为 TypertRemoteService(@Remote 方法返回 getStatus() / getPlayErrors(),客户端经 ctx.remote 直读并订阅 onStatus),并让客户端半部改走该 Remote——桥在进程内,这是面板从镜像转向直连的既有演进方向。
- 线上协议锁定参考插件——27 方法白名单、超时阶梯和拒绝列表镜像
agent_rpc0.6.x;更新的插件协议世代需要同步扩展src/protocol.ts。 - 断点不支持条件表达式——Godot 4 断点 API 忽略条件;
set_breakpoint报告conditionIgnored,模型只能依赖行断点。 play_error捕获依赖编辑器调试器 UI 时序——EditorDebuggerPlugin钩住ScriptEditorDebugger;在部分 Godot 版本上,钩子只在调试器面板构建后挂接。依赖错误收集前请先用真实编辑器验证。- 仅单一活动客户端路由——多个 Godot 实例连接时,未指定的调用路由到第一个认证客户端;
clientId选择尚未暴露为工具参数。
第三半——把上面两端组装成开箱即用的 Godot 开发 agent。仓库内对应两块:agent-presets/godot/(预设本体)与 examples/web-profile.cordis.patch.yml(无 preset 部署的可选 host 接线示例)。
DeepSeek Harness 的 agent preset:preset.yml 声明模式元信息(名称、描述、顺序),agent.cordis.yml 是 agent 平面组合。它把本仓库的两端组装成一个面向 Godot 游戏开发的精简 agent:
- persona——Godot 4.x 开发 agent:GDScript、场景(.tscn)、资源(.tres)、着色器、编辑器插件、导出构建;优先用
godot_*工具驱动编辑器,PowerShell 处理无头运行与编辑器桥之外的事。 - 工具——shell(Windows 上为 pwsh)、文件读写/检索、后台任务(
tool-jobs)、compaction(长会话)、子代理委派、goal、plan mode、web 检索(禁抓取)、todo、ask-user。 - 明确不加载——workflow 编排、ralph 循环、技能加载等重型机制,保持精简。
- 编辑器驱动——
godot_*工具由 preset 内的tool-godot行(对应本仓库dsh-godot-tool/插件)注册。preset 的 standing mount 在进程内只挂载一次,全局仍只有一个桥、一个端点文件(~/.dsh/godot/endpoint.json),Godot 端agent_rpc依然只需轮询一个端点;桥在 Godot模式 首次被使用时启动。工具注册进本 preset 的作用域层,只有 Godot模式 的会话可见——标准/代码等其他模式的目录里没有任何godot_*工具。
- 预设——把
agent-presets/godot/复制到~/.dsh/.agent-presets/godot/(harness 用户预设目录),然后在 GUI 中选择 Godot模式。 - 无需 host 接线——
tool-godot一行已包含在预设内(enabledTools为全部 27 个工具);要收紧工具集就从该列表删项。不要再在 web profile 的cordis.patch.yml里注册tool-godot——回到 host 平面会让godot_*工具对所有模式全局可见。只有不启用 agent preset 的部署(CLI/TUI、--patch源码安装)才按examples/web-profile.cordis.patch.yml手工接线。 - 打开 Godot 项目、启动 harness,agent 即以 Godot 模式驱动编辑器。
- 桥在第一次有会话选择 Godot模式时随 preset 的 standing mount 启动,此后随 harness 进程常驻;把会话切出 Godot模式(或删掉会话)不会停止桥——这是 preset 架构的既定行为(standing mount 常驻)。但工具可见性随作用域走:切换后该会话立即不再看到
godot_*工具,其他模式全程不受影响。 - 不要用 GUI「复制预设」复制本预设当作第二个模式——副本会再挂一个桥,与 Godot模式 的桥抢端口并互相覆盖端点文件。
agent.cordis.yml注释中标注了部署假设(Windows shell、tool-godot由 preset 持有);迁移到其他部署时按注释调整。
addons/agent_rpc/ # Godot 编辑器插件(客户端一半),GDScript
plugin.cfg / plugin.gd / rpc_debugger.gd
dsh-godot-tool/ # Harness 插件(服务端一半),TypeScript
src/bridge.ts # GodotRpcBridge —— 回环 TCP 服务端、握手、路由
src/protocol.ts # 方法白名单、超时阶梯、参数卫生、拒绝列表
src/tools.ts # 27 个 godot_* 工具定义
src/endpoint.ts # 端点文件发布 / 读取 / 删除
src/index.ts # 插件入口(name / inject / Config / apply)
tests/ # vitest 套件(bridge、protocol、tools、loader-composition、preset-scope)
agent-presets/godot/ # Godot 模式 agent preset(preset.yml + agent.cordis.yml)
examples/ # 无 preset 部署的可选 host 接线(web-profile.cordis.patch.yml)
TypeScript 一侧用 vitest 测试;tests/fake-addon.ts 通过真实回环 socket 伪造 Godot 插件,因此套件无需 Godot 编辑器即可覆盖实际线上协议:
cd dsh-godot-tool
pnpm exec vitest run套件:bridge.spec.ts(传输、握手、路由、超时)、protocol.spec.ts(白名单、卫生、拒绝列表、端点 schema)、tools.spec.ts(工具闸)、loader-composition.spec.ts(导出形态)、preset-scope.spec.ts(作用域分层:preset 挂载时 godot_* 工具只进入该作用域层,host 全局目录保持干净)。
.smoke-test/ 是一个最小的一次性 Godot 4 项目(主场景打印 SMOKE_OK from Godot 4.7),自带 addons/ 下安装的插件。它被排除在 git 之外;用于手工验证线上通路:
- 在 Godot 编辑器中打开
.smoke-test/project.godot(该项目的插件已启用)。 - 启动启用了
tool-godot的 harness;桥发布端点文件。 - 运行场景(F6):Output 面板显示
Agent RPC: connected to …和打印行;然后用godot_editor_info/godot_run_scene/godot_play_errors从 agent 侧驱动。
README 把线上协议锁定到插件版本和协议世代。改动任何一半(新方法、超时常量、配置字段)时,请在同一提交内更新:
dsh-godot-tool/src/protocol.ts—— 白名单、超时阶梯、卫生上限、拒绝列表、端点 schema。- 上文方法名单、超时阶梯与安全模型表。
- 插件变化时同步
plugin.gd中的ADDON_VERSION与plugin.cfg的version。 - 改动 Godot 模式时同步 Godot 模式 章节。
插件 0.6.3、harness 插件 0.1.0-rc.5(@deepseek-ai/dsh-godot-tool)、协议世代 1.0 + 1.2 + 1.3(27 个 RPC)。已在 Godot 4.4 stable 和 4.7 stable(Windows)上测试。自本仓库补丁起,插件读取 AGENT_RPC_ENDPOINT / agent_rpc/endpoint_file;旧的 ~/.pi/... 默认值仍可用。新插件版本可能增加方法,但 1.0 集合保持不变。Godot 模式(agent-presets/godot/)与 harness 插件同仓库维护,随上述版本锁定。
MIT —— 见 LICENSE。