Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .repository-projection.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
"projection": "deixic-code",
"projectionSchemaVersion": 1,
"sourceRepository": "dx-corp/mono",
"sourceSha": "f85ea3e433c29ca965a8940cefa8efbb7f46c2d8",
"sourceSha": "72cf6301da0c563c2873f00cc255dfa1acaa62b4",
"destinationRepository": "dx-corp/code",
"priorProjectedBase": "f273f9064fc052632b76f0a74be6fbdd1ad11f57",
"priorProjectedBase": "05c509f1dc8da64b61c29f2fedb78a366ab4eac6",
"definitionDigest": "82936441c776e3e8edb5d215a75007ec9714a233f489d460075d79d5ef5ba32f",
"toolDigest": "c244d99199a7ae3eb8ff644a99462163c23b0bb6a83ef50af01efbdca0b81d04",
"contentDigest": "489cfe5065a3880db2d45cf3cf981f2a55c119abf49fefedc69410f30176ce7b",
"contentDigest": "b57dd8c902329ff02da9f15d8fca063f8a71533f15e6bcdda4fe4fe996345777",
"publicationEligible": true
}
41 changes: 41 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
resolver = "2"
exclude = ["examples/hooks/wasm-plugin", "vendor/*", "vendor/dex-loop"]
members = [
"packages/codemode-rs",
"packages/maestro-rs",
"packages/runtime-rs",
"packages/runtime-contracts-rs",
Expand Down Expand Up @@ -29,6 +30,7 @@ members = [
]

[workspace.dependencies]
agent-codemode = { path = "packages/codemode-rs" }
textwrap = "0.16"
anyhow = "1"
http = "1.4"
Expand Down
29 changes: 29 additions & 0 deletions packages/codemode-rs/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")

CODEMODE_SRCS = glob(["src/**/*.rs"])
CODEMODE_DEPS = [
"@crates//rquickjs",
"@crates//serde",
"@crates//serde_json",
"@crates//tokio",
"@crates//tokio-util",
]

rust_library(
name = "agent_codemode",
crate_name = "agent_codemode",
crate_root = "src/lib.rs",
edition = "2021",
srcs = CODEMODE_SRCS,
visibility = ["//visibility:public"],
deps = CODEMODE_DEPS,
)

rust_test(
name = "tests",
crate_name = "agent_codemode_tests",
crate_root = "src/lib.rs",
edition = "2021",
srcs = CODEMODE_SRCS,
deps = CODEMODE_DEPS,
)
16 changes: 16 additions & 0 deletions packages/codemode-rs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "agent-codemode"
version = "0.1.0"
edition = "2021"
license = "MIT"
description = "Bounded native script orchestration over caller-owned tool dispatch"

[dependencies]
rquickjs = { version = "=0.13.0", default-features = false }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tokio = { version = "1", features = ["sync"] }
tokio-util = { version = "0.7", features = ["rt"] }

[dev-dependencies]
tokio = { version = "1", features = ["macros", "rt", "time"] }
70 changes: 70 additions & 0 deletions packages/codemode-rs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Code mode

`agent-codemode` provides native script orchestration for Maestro and Dex.
It brings the composition and context-filtering behavior described in
[Pi's code-mode documentation](https://github.com/earendil-works/pi/blob/9fba660cf1caca0ade5bea72269352416e595a19/packages/coding-agent/docs/codemode.md)
to the existing Rust tool boundaries. It does not own tool permissions,
credentials, effect admission, approvals, or durable receipts.

The model calls `codemode` with a `code` string containing the body of an async
JavaScript function. Independent reads can run in one wave; their results can
feed subsequent calls without another model request. Only `text()` output and
the returned value enter the model's tool-result context.

```javascript
const matches = ALL_TOOLS.filter(tool => /search/.test(tool.name));
text(matches.map(tool => ({name: tool.name, schema: tool.schema})));
```

```javascript
const results = await Promise.allSettled([
tools.read({path: "Cargo.toml"}),
tools.read({path: "README.md"})
]);
text(results.map(result => result.status === "fulfilled"
? {status: result.status, characters: result.value.length}
: {status: result.status, error: result.reason.message}));
```

Tool names and available arguments come from the admitted catalog, not from
script-supplied metadata. Names containing punctuation also have an identifier
alias, such as `tools.read_rows` for `read.rows`. Ambiguous aliases fail closed.
The catalog records the identifier on each entry. Dex exposes its ordinary
core or already-discovered tools; Maestro preserves its allowed-tool set and
profile restrictions. Conversational questions and confirmations use direct
tool calls. Recursive scripts are unavailable.

Each script gets a fresh QuickJS VM embedded in the native binary. There is no
Node/Bun subprocess, host filesystem, network, module loader, process API, or
timer API. The host bridge emits tool requests; the composing agent applies
its normal authorization and execution path to each request. Permitted reads
run concurrently, while effects retain their existing ordered execution and
effect receipts. A script cannot authorize its own nested calls.

The VM has a 32 MiB heap, a 256 KiB stack, a maximum of 64 nested calls,
64 KiB of output, and a hard 60-second deadline. Existing host deadlines and
cancellation may stop it sooner. Output-limit violations remain failures even
when the script catches the exception. A promise with no pending tool call
fails immediately. Unawaited requests are discarded when the script finishes.

Failed tool calls reject their JavaScript promises. A script failure preserves
partial output; completed effects are not undone. Each composing agent retains
the underlying call evidence separately from the script's model-facing summary.
Restart handling preserves the existing refusal to replay an uncertain effect.

The VM has no durable store. Script-local variables cover dependencies within
one call; existing agent journals remain the owners of execution state. This
change does not import Pi's provider transports, model-running helpers, or
session-storage format.

The native engine is pinned to `rquickjs` 0.13.0, published September 8, 2026,
to retain the repository's fourteen-day dependency cooling period. Independent
archive review verified the three package checksums in both Cargo locks.
The exact `rquickjs-sys` build-script admission expires October 17, 2026.
With default features disabled, native builds compile the vendored QuickJS C
sources through `cc` and use bundled bindings. The optional WASI SDK downloader,
bindgen, and dynamic loader are outside this native integration.
The reviewed sys archive SHA-256 is
`53d0aaff245bed1c6f3c39e477fb6b98d710d9d298bfec7c8dfc589bed0e5cef`;
its build script SHA-256 is
`d1e3edaaa8d404a6fe311b9128063594f84ad17bf4b0fc742aad750cae95731b`.
Loading
Loading