Skip to content
View source

Agent protocol

AI is the creator. Any language, any model, any CLI creates through one open protocol, under the same authority rules as the CLI and the Player: Kernels are prepared before they are published, publication is atomic and checked against a generation, a rejected change leaves the running version alive, and state commits only when a whole evaluation succeeds.

终端窗口
entelechy serve examples/life/scene.esn
Door Opened by Carries
stdin entelechy serve <scene.esn>, or entelechy-player --serve <scene.esn> request lines on standard input, answer lines on standard output; quit ends the process
socket --listen <host:port> (127.0.0.1:7788; port 0 for any free port, named on stderr as listening on ...) the same lines over each TCP connection; every connection served by the one session; quit ends that connection
WebSocket the same --listen address, by HTTP upgrade text messages, one request a message (see bridges/web)
in process the C function entelechy_request (entelechy.h) one line in, its answer out; beside C functions that evaluate and read Fields in place

Served from the Player, evaluate answers with the window’s next frame (the person’s pointer and keys) and read returns the frame the window shows.

A request is one JSON object a line, with an op and an optional id echoed back. An answer is {"id", "ok": …} or {"id", "error": {"message", "line"?, "column"?, …}}.

An error carries what acts on it as data: an unknown op the operations, an unknown help name the similar ones, a failed evaluation its node (a migration’s also port and migration), and where one mends it a fix (an item to hand back to compose). A field of the wrong type, one not taken, or one missing answers fields, field and expected. Every part is in Class reference · Session.

Group Operations
Inspect status, kernels, kernel, graph, document, history, help
Structure compose, sync
Kernels prepare, publish, retire
Parameters param
Running evaluate, read, pause, trace, pin, unpin
State write, reset, snapshot, restore
Session quit

A real transcript of entelechy serve scene.esn on the first scene (long lines cut; ← marks comments):

→ {"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...", ...}} ← a PNG, base64
→ {"id":6,"op":"param","name":"count","value":3} ← count is the node's own value, not a graph param
← {"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}

Step 6: the error says not only why, but what to do next. Step 8’s compose changed only the bytes of count = 8.0;; every other byte of the file (comments, blank lines) stayed.

compose is the one door for structure. It takes a whole text, or edits of the document on disk:

{"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}
]}
  • An edit names one statement by kind and name (node, output, param, input, kernel, struct, type, fn, or use with its path) or, with member, one member of a node’s block; text: null removes it.
  • What exists is replaced; what does not is added after the last of its kind. Only those bytes change.
  • path names another document under the scene’s directory; documents changes several at once (a new Kernel document, the scene’s use of it, the node that runs it and the output it feeds), checked together, all written or none.
  • expect is the document’s version digest: it writes only if the document is still that version, else answers the current one. Composing an old text against the standing version rolls back.
  • compose writes .replay files too — an agent can write tests for its own changes.

prepare only validates; publish changes the running world (not a file). With expect it is optimistic concurrency (real output):

{"id":1,"ok":{"generation":3,"id":"demo.tint@1"}}
{"error":{"message":"cannot replace demo.tint@1 g2: the registry holds g3"},"id":2}

A Kernel published over the protocol belongs to no document; keep it by compose-ing it into a document the scene uses, or with the whole world by snapshot.

Answers to sync, compose, param and others carry events, whose kind comes from entelechy_documents::Event: preparing, published, rejected, retired, scene_loaded, scene_rejected, routed, large, idle, unrun, wrote, removed, renamed, write_refused and more. All of them: Session signals.

A saved edit is read and compiled on another thread: sync reports preparing, and published or rejected on a later sync; evaluate runs the previous version meanwhile. compose and publish answer with their outcome (scene landed or refused, Kernel published or refused), while frames go on and other connections are answered. One change is made at a time.

终端窗口
entelechy help window --json

or {"op":"help","name":"window"}. help is gathered from the tables the implementation executes: the compiler’s types, builtins and forms, the parser’s reserved words, the ABI’s capabilities, the session’s packages, the protocol’s operations and fields, the replayer’s lines. This site’s class reference is generated from those tables.

bridges/ in the repository holds a DCC-tool bridge (socket), an external host-app client, a web client (a WebSocket page) and c (entelechy.h). See each directory’s README for its state.