Reference·Eval and the layerIndex

Eval and the layer

The eval tool, its helpers, and how a definition is kept, held, skipped, inspected and undone.

.mdllms.txt

Arguments

eval evaluates Common Lisp forms in the running image.

ArgumentTypeDoes
formstring, requiredOne or more forms, evaluated in order.
yield_time_msintegerMilliseconds to wait before the form continues in the background. Default 10000. Maximum 600000.
stringsobject of stringsNamed literal texts. Read one inside the form with ($ "name").

A multi-line cell may leave parens open. Its indentation closes them. A one-line cell must close its own.

Use strings for text with backslashes, double quotes or newlines. In a Lisp string, "\n" reads as n.

(edit "src/app.py" ($ "old") ($ "new"))

Helpers

Helpers are functions inside eval. Calling one as its own tool is refused with a repair hint.

FormDoes
(sh "cmd")Runs the command through sh -c in the session's folder. Returns stdout and stderr merged. Adds [exit N] when the status is not 0.
(sh "cmd" :directory "dir")Runs it in dir.
(sh (list "git" "status"))Runs an argv list with no shell.
(edit path old new)Replaces the one occurrence of old in the file. Zero or several occurrences is an error.
(write-file path text)Writes the whole file. Creates parent folders.
(patch name old new)Changes one subform of a kept definition. Evaluates the result. Keeps it. Write name, old and new unquoted.
(look path)Attaches an image file to the turn. The model sees it at the next round.
($ "name")Reads one entry of strings, exact.
(help)Lists the functions and topics. (help :eval) and (help :layer) have the detail.
LimitValue
sh stdinEmpty.
sh output capture1,000,000 characters. Past that the command is killed.
look formatsPNG, JPEG, GIF, WebP
look file size5 MiB
Relative pathsResolved against the session's folder.

On Windows, sh uses the sh.exe from Git for Windows.

Result

RuleDetail
Cap32,000 characters per result.
ValuesOne => line per form. Only the last value prints in full.
FailureThe result names the failing form: ERROR in form i of n. Earlier forms stand.
Compiler warningsA [warning: ...] line leads the result. The form still ran.
NoteA cell's leading ;; line is its note. Eviction stubs keep it.

In the next cell, * is the last value of the previous cell. / is the list of its values.

Linux only: a cell's last form is watched when it only reads. It runs again after each later cell. A change shows as [watched FORM: OLD -> NEW].

Background evals

A form still running after yield_time_ms continues in the background. It is never killed by the timeout.

The call answers:

~/.nodecode/config.jsonc
{"status":"running","eval_id":N}

The harness reads the exit for the model. It does so in the same turn, or in a new turn that wakes the session.

FormDoes
(list-evals)Lists this image's background evals.
(eval-status N)Returns the output since the last look. Adds the value and exit code once exited.
(eval-await N)Waits for new output or the exit. Waits at most the calling cell's yield_time_ms.
(eval-await N :until-exit t)Waits for the exit only.
(eval-interrupt N)Aborts the eval.
(eval-interrupt N :force t)Terminates its thread. Use when the form traps the abort.

Background output is live only. The exit result is stored in the log.

Kept definitions

EVALLIVEYOUR LAYER~/.nodecode/cells/<you>/KEPTNEXT BOOTTHE SHIPPED SOURCE
Defining is keeping. A definition runs in the image first. It is then saved as one source file in your folder and committed with the session id. At the next boot the folder loads over the shipped source, in every process.

The layer is the set of definitions the agent wrote and kept.

A defining form that evaluates successfully as a top-level form is kept. No confirmation is asked.

KindKept operators
Functionsdefun, defmacro, defgeneric, defmethod, defsetf
Variablesdefvar, defparameter, defconstant
Typesdefclass, defstruct, deftype, defpackage
Otherdefine, and any define-* form such as define-hook

A definition inside a top-level progn or eval-when is kept as its own file.

FactValue
Folder~/.nodecode/cells/<name>/
<name>git config user.name, else $USER, else you. Lowercased. Other characters become -.
FilesOne .lisp file per definition, plus a generated .asd.
GitOne commit per write. The message names the definitions and the session id.
LogOne organism.definition_recorded event.
Result line[layer: kept NAME]
LoadFrom source at every boot, in every process, after all other cells.
Compile cache~/.cache/nodecode/layers/<image-stamp>/

Not kept:

FormDo this
setfWrite a defparameter.
A defining form built as a string and evaluated inside another formEvaluate the defining form itself.
A definition of a kernel nameSee the kernel lock below.

Hooks

FormDoesKept
(define-hook name "key" (next &rest args) ...)Runs the body around every call of name.Yes
(hook 'name "key" fn)The same advice, live only.No
(unhook 'name "key")Removes the hook. Deletes its layer file.

A hook survives an upstream change to the function's body. A redefinition of a shipped function may be skipped at boot after an update.

Kernel lock

The kernel is the package nodecode.kernel, nickname nlk. It is locked at boot. The boot records an organism.floor_engaged event.

ActionResult
Redefine a kernel name while lockedError.
Define a kernel name in a cellNever written to the layer. The result says [layer: NAME is floor material; ...].
Advise a kernel function with define-hookAllowed. Kept.

The agent can lower the lock itself:

(lower-floor :session-id "s-..." :requested-by "who asked" :reason "why")

All three arguments are required. An organism.floor_lowered event is recorded before the unlock.

Held definitions

A redefinition is held when its name is running on the stack of the calling cell. The turn loop, agent-loop, always is.

  1. The new definition goes live at once.
  2. It is written to the layer after it has been entered and has returned once.
  3. If that first run signals an error, the old definition is restored.
  4. The session is woken with the error.

A cancelled turn does not count as a failed first run.

FormDoes
(held-definitions)Lists what waits for a first run.
(revert 'name)Puts back the displaced definition, or the one this image booted with.

revert changes the image only. It leaves the layer file as it is.

Skipped files

At boot a layer file is skipped in two cases:

CaseExample
The shipped text it overrides has changed or is goneAn update rewrote the function.
It names a function or variable that nothing definesAn update removed a helper.

The shipped definition stands. The boot line and (cells) name the file and the reason. Other files still load.

The gateway then submits the skipped files to a session named layer. The agent redefines or forgets each one. Each skipped file is handed once. This turn spends tokens.

Source edits

edit or write-file on a file this image loads from evaluates the changed definitions at once. This covers the shipped source, cell folders and the layer.

Receipt lineMeaning
live here: ...Already running in this process.
not live until a relaunch: ...Needs a relaunch: a struct, a class, a package, a constant.

Inspect and undo

Form or commandDoes
(cells) or /cellsReports each folder: definitions, overrides, collisions, skipped files, failures.
(definition-text 'name)Reads the live definition.
(definition-location 'name)Names where it lives: the layer file and the shipped file.
(held-definitions)Lists held definitions.
(revert 'name)Restores the previous function in the image.

Forget a definition with a top-level form. The name leaves the image. Its file is deleted. The commit reads forgot NAME.

(fmakunbound 'name)
(makunbound '*name*)
(unhook 'name "key")
(remove-method ...)
(unintern 'name)

A forgetting form computed inside another form is not seen.

Undo a whole change:

a shell
cd ~/.nodecode/cells/<name>
git revert <commit>

Then restart Nodecode.

Esc

    Loading the index…

    ↑↓ moveEnter openEsc close