English | 中文
The self-referential cordis toolset: three model-facing tools over the live runtime the agent runs inside. Design home — sandbox semantics, mount lifecycle, cross-mount composition, the generated API catalog, standing decisions: the toolset Agent Note.
cordis_inspect — read-only report over the runtime: services, the loaded-plugin list, registered tools, the dynamic-mount table, and the catalog-backed api / events references. An exact name with what: "api" or what: "events" narrows the report and adds the original source JSDoc.cordis_mount — evaluates model-written JavaScript (the body of an async function) in a node:vm sandbox; the code must return a cordis plugin, which is mounted under the cordis-dynamic group fiber and tracked as dyn-<n>.cordis_unmount — disposes one mount by id, returning only after quiescence.Exact model-facing schemas: the generated tool catalog.
Canonical successes are the inspection string, mount { id, pluginName, state, provides, waitingFor }, and unmount { id, pluginName }. Native renderers preserve the existing prose, so programs can use mounted.id while ordinary function calling still sees mounted dyn-1 (...).
The sandbox isolates globals but is not a security boundary. Node globals are absent or redirect to Cordis services such as ctx.fs, ctx.web, and ctx.bash, and writes to globalThis stay local, but host-realm helpers make escape possible. Mounted plugins receive a façade without framework internals, yet its allowed services affect the live runtime. Dynamic tool schemas and annotations cross the realm through iterative JSON cloning and schema normalization, so valid deep declarations are memory-bounded rather than call-stack-bounded; records with JSON-invisible keys and subclassed or decorated schema arrays reject before normalization. Treat this toolset like bash access; see the design and trust stance.
| Field | Default | Meaning |
|---|---|---|
vmTimeoutMs |
5000 |
Bound on the SYNCHRONOUS portion of mount-code evaluation; an async body escapes it |
src/api-catalog.ts is generated by scripts/gen-cordis-api.ts from the same AST walk as docs/cordis-catalog and freshness-gated by pnpm run verify-cordis-api (in doc-sync) — never edit it by hand. cordis_inspect intersects it with the live service store at call time. Broad api / events reports render summaries and signatures only; an exact name opts into the retained method/event JSDoc, and unknown or non-running service targets fail loud.
All three tools render generic cards (read / execute / delete); cordis_mount carries the mount code as rawInput. Presenters are pure functions of the args; results keep the default text rendering.
Namespace plugin: named exports name / inject / Config / apply, no default export (docs/postmortem/0001).
The conversation model sees the generated cordis_inspect, cordis_mount, and cordis_unmount schemas whenever this plugin is visible.
Fixed schema cost on every request in that tool view.
Prefix-stable while this tool view is unchanged. Scoping or plugin lifecycle changes that hide these definitions may invalidate reuse from the first changed schema token.
Inspect joins selected sections exactly as ## <section> then a newline and the data-dependent body, with one blank line between sections. Its broad API/event reports omit JSDoc; name with what: "api" or what: "events" returns one exact target with its original JSDoc. Mount returns mounted <id> (plugin "<name>", state: <state>), optionally inserting — waiting for service(s): <names> (activates when provided) before the closing parenthesis. Unmount returns unmounted <id> (plugin "<name>"); an unknown id becomes Error: no dynamic plugin with id "<id>" (list mounts with cordis_inspect what:"dynamic"). The submitted mount program remains in the assistant tool-call history.
Inspect output and mount code are data-dependent and resent until compaction; lifecycle acknowledgements are small.
Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
A mounted plugin may register tools, prompt contributions, or listeners that change later requests for the scopes it targets; unmount removes those contributions after quiescence.
Indirect token impact equals the mounted plugin's contributions and lasts only for the mount lifetime.
Mounting or unmounting a prompt or tool contribution changes later request prefixes and may invalidate reuse from the first changed contribution; an unchanged mount set remains prefix-stable.
ctx façade exposes no effect() — mount code cannot register a bespoke disposer; on/provide/tools.register cover every mount seen so far, and a guarded effect waits on a real need (FIXME(sandbox-effect)).vmTimeoutMs bounds only synchronous evaluation — an async mount body escapes it; there is no async budget on mount code.