Skip to content

v0.3.0

Choose a tag to compare

@ggoodman ggoodman released this 23 Jul 02:45
bcd9c7d

Write ordinary ESM programs

Code-mode programs are now normal TypeScript-flavoured ECMAScript modules. Static imports work naturally, and the program default-exports the function the runtime should invoke:

import { inspect } from "node:util";

export default async function ({ codemode, console }: AgentProgramScope) {
  const result = await codemode.lookup({ query: "example" });
  console.log(inspect(result));
}

This replaces the previous single-expression source format. Code mode strips erasable TypeScript in place without adding a wrapper or prepending source, so runtime stack traces preserve the submitted line and column coordinates.

The runner passes both codemode and console in the scope. Programs can use either, both, or neither. Only this supplied console is captured; ambient and imported consoles remain ordinary runtime behavior. Captured output is deliberately text with explicit provenance:

{
  stream: "stdout" | "stderr";
  text: string;
}

Keep runtimes alive across executions

The public runtime is now an already-connected, async-disposable client/server session:

import { createClient } from "@torkbot/code-mode";
import { createHostNodeRuntime } from "@torkbot/code-mode/host-node";

const runtime = await createHostNodeRuntime(
  {
    nodePath: process.execPath,
    cwd: process.cwd(),
  },
  bootSignal,
);

try {
  const client = createClient({ runtime, toolbox });
  await client.run(source, { signal: executionSignal });
} finally {
  await runtime[Symbol.asyncDispose]();
}

The built-in Host Node runtime uses one persistent Node.js 24 process and multiplexes independent executions over it. The boot signal governs startup through runner readiness and then detaches; each execution has its own cancellation signal.

Every execution evaluates a fresh root module. Imported dependencies retain the execution platform's normal module-cache behavior.

Build runtime drivers around one small connection contract

Runtime integrations now implement RuntimeDriver<Options> and expose their user-facing factory with createRuntimeFactory(driver). A driver boots its environment, installs or evaluates the supplied version-matched runner, and returns a raw full-duplex byte connection:

const createMyRuntime = createRuntimeFactory({
  description: "My runtime",
  loadTypeDefinitionFiles,
  async connect(options, { runnerSource, signal }) {
    return {
      channel: {
        readable,
        writable,
      },
      finished,
      async [Symbol.asyncDispose]() {
        await closeRuntime();
      },
    };
  },
});

Code mode owns runner readiness, the wire protocol, tool routing, output, cancellation, and opaque execution correlation. Drivers only own placement, transport, module evaluation, scheduling, environment declarations, and resource lifecycle.

The reusable runner ships both as @torkbot/code-mode/runner and as self-contained ESM source through @torkbot/code-mode/runner/source. The factory supplies that flattened source to connect() automatically, so ordinary runtime consumers never need to plumb it.

Migrating from v0.2.0

This is an intentionally breaking release with no compatibility layer:

  • Replace expression-shaped programs with ESM containing a callable default export.
  • Read tools and captured output from the default export's { codemode, console } argument.
  • Replace Runtime.start(), RuntimeInstance, payload launch objects, and termination methods with a connected Runtime and async disposal.
  • Replace the removed @torkbot/code-mode/node entry point with @torkbot/code-mode/host-node.
  • Replace structured console telemetry with program-output events containing stream and text.
  • For custom substrates, implement RuntimeDriver.connect() and return RuntimeConnection; do not implement or interpret the internal protocol.
  • Ensure tool inputs and outputs crossing the runtime boundary are JSON-compatible.
  • Run the exported testRuntime() suite against every runtime implementation. It observes only the public Runtime and Client contracts.

Reliability

The runtime now rejects post-cancellation tool calls before they can become orphaned, cleans up raw connections even when runtime construction fails, and reports non-JSON tool outputs as failed telemetry instead of briefly reporting success. Program errors are bounded so one execution cannot collapse a shared runtime with an oversized failure frame.

Install this release with:

npm install @torkbot/code-mode@0.3.0