Files
deepseek-harness/packages/cordis/tool-cordis/README.md
T

84 lines
5.4 KiB
Markdown
Raw Normal View History

# @deepseek-ai/dsh-tool-cordis
2026-07-19 22:50:49 +08:00
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](../../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md).
## What it does
2026-07-19 14:39:49 +08:00
- `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](../../../docs/tool-catalog.md).
## Trust stance
2026-07-19 22:50:49 +08:00
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. Treat this toolset like bash access; see the [design and trust stance](../../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md).
## Config
| Field | Default | Meaning |
|---|---|---|
| `vmTimeoutMs` | `5000` | Bound on the SYNCHRONOUS portion of mount-code evaluation; an async body escapes it |
## The generated API catalog
2026-07-19 14:39:49 +08:00
`src/api-catalog.ts` is generated by `scripts/gen-cordis-api.ts` from the same AST walk as [docs/cordis-catalog](../../../docs/cordis-catalog/services.md) 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.
## Rendering
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.
## Export shape
Namespace plugin: named exports `name` / `inject` / `Config` / `apply`, no default export ([docs/postmortem/0001](../../../docs/postmortem/0001-acp-default-export-drops-inject.md)).
2026-07-12 02:55:26 +08:00
## Model Experience
### Tool schemas
2026-07-19 18:08:42 +08:00
#### What the model sees
2026-07-19 18:08:42 +08:00
The conversation model sees the generated [`cordis_inspect`, `cordis_mount`, and `cordis_unmount` schemas](../../../docs/tool-catalog.md#deepseek-aidsh-tool-cordis) whenever this plugin is visible.
2026-07-19 18:08:42 +08:00
#### Token effect
Fixed schema cost on every request in that tool view.
#### KV Cache effect
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.
2026-07-19 17:39:50 +08:00
### Tool-call history and results
2026-07-19 18:08:42 +08:00
#### What the model sees
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.
#### Token effect
2026-07-19 18:08:42 +08:00
Inspect output and mount code are data-dependent and resent until compaction; lifecycle acknowledgements are small.
2026-07-19 18:08:42 +08:00
#### KV Cache effect
Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
2026-07-19 17:39:50 +08:00
### Later requests after a mount
2026-07-19 18:08:42 +08:00
#### What the model sees
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.
#### Token effect
Indirect token impact equals the mounted plugin's contributions and lasts only for the mount lifetime.
2026-07-19 18:08:42 +08:00
#### KV Cache effect
2026-07-12 02:55:26 +08:00
2026-07-19 18:08:42 +08:00
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.
2026-07-19 17:39:50 +08:00
## Known Limitations and Deferred Work
- **The sandbox is containment for honest code, not a security boundary** — host-realm helpers on the sandbox global are reachable, so mount code can reach Node; load this plugin as deliberately as you would grant a bash tool (see § Trust stance).
- **The `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.