Agent 创作协议
AI 是创作者。 任何语言、任何模型、任何 CLI 都通过同一个开放协议创作,遵守与 CLI 和 Player 相同的权限规则:Kernel 先准备再发布,发布是原子的并按代数检查,被拒绝的修改让运行中的版本继续活着,状态只在整次求值成功时提交。
entelechy serve examples/life/scene.esn| 门 | 打开方式 | 承载 |
|---|---|---|
| stdin | entelechy serve <scene.esn>,或 entelechy-player --serve <scene.esn> |
标准输入一行一个请求,标准输出一行一个答复;quit 结束进程 |
| socket | --listen <host:port>(如 127.0.0.1:7788;端口 0 表示任意空闲端口,在 stderr 打印 listening on ...) |
每个 TCP 连接上相同的行;所有连接共享一个会话;quit 结束该连接 |
| WebSocket | 同一个 --listen 地址,HTTP upgrade |
文本消息,一条消息一个请求(见 bridges/web) |
| 进程内 | C 函数 entelechy_request(entelechy.h) |
一行进,一行出;旁边还有直接求值、读取 Field 的 C 函数 |
在 Player 中提供协议时,evaluate 用窗口下一帧(人的指针与按键)回答,read 返回窗口显示的帧。
请求:一个 JSON 对象一行,带 op 和可选的 id(原样带回)。答复:{"id", "ok": …} 或 {"id", "error": {"message", "line"?, "column"?, …}}。
错误把可操作的信息作为数据带回:未知操作带 operations,未知 help 名称带 similar,求值失败带 node(迁移失败还有 port 和 migration),可修复时带 fix(一个可以直接交回 compose 的文档项)。类型错误、多余字段、缺少字段都会返回 fields、field 和 expected。完整字段表见类参考 · Session。
24 个操作
Section titled “24 个操作”| 分组 | 操作 |
|---|---|
| 查看 | status、kernels、kernel、graph、document、history、help |
| 结构 | compose、sync |
| Kernel | prepare、publish、retire |
| 参数 | param |
| 运行 | evaluate、read、pause、trace、pin、unpin |
| 状态 | write、reset、snapshot、restore |
| 会话 | quit |
一次真实的会话
Section titled “一次真实的会话”以下是在第一个场景上运行 entelechy serve scene.esn 的真实记录(长行已截断,← 是注释):
→ {"id":1,"op":"status"}← {"id":1,"ok":{"backend":"jit","frame":0,"fusion":true,"grants":["field.read","field.write","time.read","input.read"],"kernels":2,"loaded":true,...,"natives":4,"nodes":2,"refused":null,"revision":3,"scene":"scene.esn","versions":{"api":1,"entelechy":"0.0.2-rc.3","ir":1,"language":3,"package":1},...}}
→ {"id":3,"op":"param","name":"warmth","value":0.9}← {"id":3,"ok":{"events":[],"name":"warmth","value":0.9}}
→ {"id":4,"op":"evaluate","time":0.5}← {"id":4,"ok":{"executed":["rings","tint"],"outputs":[{"height":256,"name":"result","width":256}],"placements":[{"backend":"jit","node":"rings",...},...],"timings":[{"millis":0.541,"node":"rings"},{"millis":0.308,"node":"tint"}],...}}
→ {"id":5,"op":"read","output":"result"}← {"id":5,"ok":{"data":"iVBORw0KGgo...", ...}} ← PNG(base64)
→ {"id":6,"op":"param","name":"count","value":3} ← count 是节点自己的值,不是图参数← {"error":{"message":"`count` is not a param the scene declares; node `rings` sets its own `count`, which is the document's: change it there (over the protocol, `compose` with `edits`, node `rings`, member `count`), or declare a `param` there for the node to name"},"id":6}
→ {"id":8,"op":"compose","edits":[{"node":"rings","member":"count","text":"count = 12.0;"}]}← {"id":8,"ok":{"events":[{"kind":"scene_loaded"}],"path":"scene.esn","version":"6e2f7d12cecaf4c6","written":true}}
→ {"id":10,"op":"frobnicate"}← {"error":{"message":"unknown op `frobnicate`; the operations are status, kernels, kernel, graph, document, history, compose, sync, prepare, publish, retire, param, evaluate, read, write, snapshot, restore, pause, reset, help, trace, pin, unpin, quit","operations":[...]},"id":10}注意第 6 步:错误不仅说明了原因,还告诉 Agent 下一步该怎么做。第 8 步的 compose 只改动了 count = 8.0; 这几个字节,文件中其他内容(注释、空行)全部保留。
修改世界:compose
Section titled “修改世界:compose”compose 是改变结构的唯一入口。它接受整个 text,或对磁盘上文档的 edits:
{"op": "compose", "expect": "<version>", "edits": [ {"node": "castle", "text": "node castle: castle.build@1 { base <- ground.result; }"}, {"node": "view", "member": "voxels", "text": "voxels <- castle.result;"}, {"node": "old", "text": null}]}- 一个编辑按种类和名字指定一条语句(
node、output、param、input、kernel、struct、type、fn或带路径的use),或用member指定节点块中的一个成员;text: null表示删除。 - 已存在的被替换,不存在的追加在同类最后一个之后。只有这些字节改变。
path指定场景目录下的其他文档;documents一次修改多个文档(例如新的 Kernel 文档 + 场景的use+ 运行它的节点 + 它喂的输出),一起检查,要么全写要么一个不写。expect是文档版本摘要:只有文档仍是该版本才写入,否则返回当前版本。用旧文本对当前版本 compose 就是回滚。compose也可以写.replay——Agent 可以为自己的修改写测试。
Kernel 的发布
Section titled “Kernel 的发布”prepare 只校验;publish 改变运行中的世界(不改文件)。带 expect 实现乐观并发(真实输出):
{"id":1,"ok":{"generation":3,"id":"demo.tint@1"}}{"error":{"message":"cannot replace demo.tint@1 g2: the registry holds g3"},"id":2}通过协议发布的 Kernel 不属于任何文档;要保留它,用 compose 把它写进场景使用的文档,或者用 snapshot 连同整个世界一起保存。
sync、compose、param 等的答复带 events,kind 取自 entelechy_documents::Event:preparing、published、rejected、retired、scene_loaded、scene_rejected、routed、large、idle、unrun、wrote、removed、renamed、write_refused 等。完整列表见 Session 的信号。
保存的修改在另一个线程读取和编译:sync 先报告 preparing,之后的 sync 报告 published 或 rejected,期间 evaluate 运行旧版本。compose 和 publish 的答复会等待结果(场景已加载/被拒、Kernel 已发布/被拒),但帧照常继续,其他连接照常得到答复。一次只进行一个修改。
help:自描述
Section titled “help:自描述”entelechy help window --json或协议 {"op":"help","name":"window"}。help 的内容取自实现实际执行的表:编译器的类型、内置函数和语法形式,解析器的保留字,ABI 的能力,会话的包,协议的操作和字段,回放器的行。本站的类参考就是从这些表生成的。
仓库 bridges/ 中有:blender(socket)、godot(Godot 4 的 GDScript 客户端)、web(WebSocket 页面)、c(entelechy.h)。各桥接的状态请查看对应目录的 README。

