nanocodex 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -17,6 +17,9 @@ const agent = await Agent.create({
17
17
  const turn = agent.turn.prompt({ input: "Build the thing." });
18
18
  console.log(await turn.result());
19
19
 
20
+ await agent.session.setThinking("high");
21
+ await agent.session.setFastMode(true);
22
+
20
23
  const branch = await agent.session.fork({ at: turn });
21
24
  console.log(await branch.turn.prompt({ input: "Try another approach." }).result());
22
25
 
@@ -24,11 +27,113 @@ const followOn = Actions.turn.prompt(agent, { input: "Now explain it." });
24
27
  console.log(await Actions.turn.getResult(followOn));
25
28
  ```
26
29
 
30
+ Node and browser applications can instead pay through MPP without an OpenAI
31
+ API key. Pass an MPP session with a `ws(endpoint)` method; an `mppx` Tempo
32
+ session manager has this shape. Nanocodex defaults the socket to
33
+ `wss://openai.mpp.tempo.xyz/v1/responses` when `mpp` is present.
34
+
35
+ ```js
36
+ import { Agent } from "nanocodex/node";
37
+ import { Expiry } from "accounts";
38
+ import { Provider } from "accounts/cli";
39
+ import { tempo } from "mppx/client";
40
+ import { parseUnits } from "viem";
41
+ import { connect } from "viem/experimental/erc7846";
42
+ import WebSocket from "ws";
43
+
44
+ const pathUsd = "0x20c0000000000000000000000000000000000000";
45
+ const provider = Provider.create({ mpp: false });
46
+ if (!provider.store.persist.hasHydrated()) {
47
+ await new Promise((resolve) => provider.store.persist.onFinishHydration(resolve));
48
+ }
49
+ const status = await provider.getAccessKeyStatus();
50
+ if (status === "missing" || status === "expired") {
51
+ await connect(provider.getClient(), {
52
+ capabilities: { authorizeAccessKey: {
53
+ expiry: Expiry.days(1),
54
+ limits: [{ token: pathUsd, limit: parseUnits("25", 6) }],
55
+ } },
56
+ });
57
+ }
58
+ const root = provider.getAccount();
59
+ const account = await provider.store.accessKeys.select({
60
+ account: root.address,
61
+ chainId: provider.getClient().chain.id,
62
+ });
63
+ if (!account) throw new Error("Tempo account has no usable access key");
64
+ console.error(`Tempo access-key signer: ${account.accessKeyAddress}`);
65
+ const mpp = tempo.session.manager({
66
+ account,
67
+ autoSwap: { tokenIn: [pathUsd], slippage: 1 },
68
+ bootstrap: true,
69
+ client: provider.getClient(),
70
+ webSocket: WebSocket,
71
+ maxDeposit: "0.05",
72
+ topUpAmount: "0.05",
73
+ });
74
+
75
+ const agent = await Agent.create({ mpp, thinking: "none", fastMode: true, tools });
76
+ const events = agent.events.watch();
77
+ const unwatch = events.onEvent((event) => {
78
+ process.stdout.write(`${JSON.stringify(event)}\n`);
79
+ });
80
+ try {
81
+ console.error(await agent.turn.prompt({ input: "Build the thing." }).result());
82
+ } finally {
83
+ await mpp.close();
84
+ unwatch();
85
+ events.off();
86
+ agent.dispose();
87
+ }
88
+ ```
89
+
90
+ The application still owns its wallet, deposit policy, persisted payment
91
+ channel store, and final settlement. Keep the manager alive to reuse its channel
92
+ across agents, and supply mppx `channelStore` for reuse after a process or page
93
+ restart. Nanocodex never closes a caller-owned MPP session. `apiKey` and `mpp`
94
+ are mutually exclusive.
95
+
96
+ Completed turns can be persisted and resumed by a fresh Node or browser agent:
97
+
98
+ ```js
99
+ const snapshot = turn.snapshot();
100
+ agent.dispose();
101
+
102
+ const resumed = await Agent.create({
103
+ apiKey: process.env.OPENAI_API_KEY,
104
+ resume: snapshot,
105
+ tools,
106
+ });
107
+ ```
108
+
109
+ The snapshot contains authoritative typed history but no provider response ID,
110
+ so the first resumed request safely replays the committed conversation. Resume
111
+ with the same instructions and tool definitions, and release the original
112
+ agent before handing its snapshot to another writer.
113
+
114
+ Node embedders whose bundler relocates package assets may compile and pass the
115
+ web-target artifact explicitly. The runtime still uses the Node host for
116
+ WebSockets and Code Mode:
117
+
118
+ ```js
119
+ const module = await WebAssembly.compile(await readFile(wasmAssetPath));
120
+ const agent = await Agent.create({ apiKey, module });
121
+ ```
122
+
123
+ A Codex-compatible rollout can also be resumed by materializing its committed
124
+ `response_item` history into a snapshot with no `request_prefix`. Nanocodex
125
+ rebuilds the current prefix from the supplied instructions and JavaScript tools
126
+ while preserving the rollout's workspace, lineage, cache key, canonical user
127
+ context, and typed history.
128
+
27
129
  `Agent` and `Actions` are module namespaces, not classes. `Agent.create` returns
28
130
  an owned client decorated with matching domain actions:
29
131
 
30
132
  - `agent.turn.prompt(...)` / `Actions.turn.prompt(agent, ...)`
133
+ - `turn.snapshot()` / `Actions.turn.getSnapshot(turn)`
31
134
  - `agent.session.fork(...)` / `Actions.session.fork(agent, ...)`
135
+ - `agent.session.setThinking(...)` / `Actions.session.setThinking(agent, ...)`
136
+ - `agent.session.setFastMode(...)` / `Actions.session.setFastMode(agent, ...)`
32
137
  - `agent.session.spawn()` / `Actions.session.spawn(agent)`
33
138
  - `agent.events.watch(...)` / `Actions.events.watch(agent, ...)`
34
139
 
package/actions/index.mjs CHANGED
@@ -11,6 +11,8 @@ export function agentActions() {
11
11
  },
12
12
  session: {
13
13
  fork: (options) => session.fork(agent, options),
14
+ setFastMode: (enabled) => session.setFastMode(agent, enabled),
15
+ setThinking: (thinking) => session.setThinking(agent, thinking),
14
16
  spawn: () => session.spawn(agent),
15
17
  },
16
18
  turn: {
@@ -1,4 +1,4 @@
1
- import type { Agent, DefaultAgent, ForkOptions } from "../types.mjs";
1
+ import type { Agent, DefaultAgent, ForkOptions, Thinking } from "../types.mjs";
2
2
 
3
3
  /** Forks the latest checkpoint, or the exact completed Turn supplied in `options.at`. */
4
4
  export function fork(agent: Agent<object>, options?: fork.Options): Promise<fork.ReturnType>;
@@ -12,3 +12,9 @@ export function spawn(agent: Agent<object>): Promise<spawn.ReturnType>;
12
12
  export declare namespace spawn {
13
13
  type ReturnType = DefaultAgent;
14
14
  }
15
+
16
+ /** Changes the reasoning effort for subsequently accepted turns. */
17
+ export function setThinking(agent: Agent<object>, thinking: Thinking): Promise<void>;
18
+
19
+ /** Enables or disables priority processing for subsequently accepted turns. */
20
+ export function setFastMode(agent: Agent<object>, enabled: boolean): Promise<void>;
@@ -1,4 +1,9 @@
1
- import { fork as forkAgent, spawn as spawnAgent } from "../internal.mjs";
1
+ import {
2
+ fork as forkAgent,
3
+ setFastMode as setAgentFastMode,
4
+ setThinking as setAgentThinking,
5
+ spawn as spawnAgent,
6
+ } from "../internal.mjs";
2
7
 
3
8
  export function fork(agent, options = {}) {
4
9
  return forkAgent(agent, options);
@@ -7,3 +12,11 @@ export function fork(agent, options = {}) {
7
12
  export function spawn(agent) {
8
13
  return spawnAgent(agent);
9
14
  }
15
+
16
+ export function setThinking(agent, thinking) {
17
+ return setAgentThinking(agent, thinking);
18
+ }
19
+
20
+ export function setFastMode(agent, enabled) {
21
+ return setAgentFastMode(agent, enabled);
22
+ }
@@ -1,4 +1,4 @@
1
- import type { Agent, PromptInput, Turn } from "../types.mjs";
1
+ import type { Agent, PromptInput, SessionSnapshot, Turn } from "../types.mjs";
2
2
 
3
3
  /** Accepts a prompt on an owned Agent and returns its independently awaitable Turn. */
4
4
  export function prompt<const agent extends Agent<object>>(
@@ -16,6 +16,12 @@ export declare namespace getResult {
16
16
  type ReturnType = string;
17
17
  }
18
18
 
19
+ /** Copies a completed Turn into a serializable session snapshot. */
20
+ export function getSnapshot(turn: Turn): getSnapshot.ReturnType;
21
+ export declare namespace getSnapshot {
22
+ type ReturnType = SessionSnapshot;
23
+ }
24
+
19
25
  /** Adds input to an active Turn. */
20
26
  export function steer(turn: Turn, options: steer.Options): Promise<void>;
21
27
  export declare namespace steer {
package/actions/turn.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  cancel as cancelTurn,
3
3
  getTurnResult,
4
+ getTurnSnapshot,
4
5
  prompt as promptTurn,
5
6
  steer as steerTurn,
6
7
  } from "../internal.mjs";
@@ -13,6 +14,10 @@ export function getResult(turn) {
13
14
  return getTurnResult(turn);
14
15
  }
15
16
 
17
+ export function getSnapshot(turn) {
18
+ return getTurnSnapshot(turn);
19
+ }
20
+
16
21
  export function steer(turn, options) {
17
22
  return steerTurn(turn, options);
18
23
  }
@@ -1,6 +1,7 @@
1
1
  import type {
2
2
  AgentOptions,
3
3
  DefaultAgent,
4
+ MppSession,
4
5
  ToolMap,
5
6
  } from "../types.mjs";
6
7
 
@@ -9,10 +10,12 @@ export type Agent = DefaultAgent;
9
10
  /** Creates a browser- or Worker-hosted Rust/WASM Agent. */
10
11
  export function create(options?: create.Options): Promise<create.ReturnType>;
11
12
  export declare namespace create {
12
- type Options = AgentOptions & {
13
+ type Options = AgentOptions & (
14
+ | { apiKey?: string | undefined; mpp?: never }
15
+ | { apiKey?: never; mpp: MppSession }
16
+ ) & {
13
17
  WebSocketImpl?: typeof WebSocket | undefined;
14
18
  apiBaseUrl?: string | undefined;
15
- apiKey?: string | undefined;
16
19
  createWebSocket?(endpoint: string, sessionId: string): WebSocket;
17
20
  maxBufferedSendBytes?: number | undefined;
18
21
  maxQueuedBytes?: number | undefined;
package/browser/Agent.mjs CHANGED
@@ -16,18 +16,24 @@ let initialized;
16
16
 
17
17
  export function create(options = {}) {
18
18
  const {
19
- apiKey = "host-managed",
19
+ apiKey,
20
+ mpp,
20
21
  websocketUrl,
21
22
  apiBaseUrl,
22
23
  module,
23
24
  thinking,
24
25
  reasoningMode,
26
+ fastMode,
25
27
  instructions,
26
28
  sessionId,
29
+ resume,
27
30
  ...hostOptions
28
31
  } = options;
32
+ if (mpp !== undefined && apiKey !== undefined) {
33
+ throw new TypeError("apiKey and mpp are mutually exclusive");
34
+ }
29
35
  const events = createEventChannel();
30
- const host = createBrowserHost({ ...hostOptions, onEvent: events.emit });
36
+ const host = createBrowserHost({ ...hostOptions, mpp, onEvent: events.emit });
31
37
  activateHost(host);
32
38
  const runtime = defineRuntime({
33
39
  key: "browser-wasm",
@@ -39,8 +45,10 @@ export function create(options = {}) {
39
45
  await initialized;
40
46
  activateHost(host);
41
47
  return new Nanocodex(JSON.stringify(toWasmConfig({
42
- apiKey,
43
- websocketUrl,
48
+ apiKey: apiKey ?? (mpp === undefined ? "host-managed" : "mpp-managed"),
49
+ websocketUrl: websocketUrl ?? (mpp === undefined
50
+ ? undefined
51
+ : "wss://openai.mpp.tempo.xyz/v1/responses"),
44
52
  apiBaseUrl,
45
53
  ...config,
46
54
  })));
@@ -50,5 +58,12 @@ export function create(options = {}) {
50
58
  release: (raw) => releaseHostSession(host, raw.sessionId),
51
59
  decorate: (agent) => agent.extend(agentActions()),
52
60
  });
53
- return createAgentClient(runtime, { thinking, reasoningMode, instructions, sessionId });
61
+ return createAgentClient(runtime, {
62
+ thinking,
63
+ reasoningMode,
64
+ fastMode,
65
+ instructions,
66
+ sessionId,
67
+ resume,
68
+ });
54
69
  }
package/browser/host.mjs CHANGED
@@ -18,6 +18,7 @@ export function createBrowserHost(options = {}) {
18
18
  let nextHandle = 1;
19
19
 
20
20
  function connect(endpoint, _apiKey, sessionId) {
21
+ if (options.mpp) return connectMpp(endpoint);
21
22
  return new Promise((resolve, reject) => {
22
23
  let settled = false;
23
24
  const handle = nextHandle++;
@@ -59,6 +60,41 @@ export function createBrowserHost(options = {}) {
59
60
  });
60
61
  }
61
62
 
63
+ async function connectMpp(endpoint) {
64
+ if (typeof options.mpp.ws !== "function") {
65
+ throw new TypeError("mpp must provide ws(endpoint)");
66
+ }
67
+ const socket = await options.mpp.ws(endpoint);
68
+ if (!socket || typeof socket.addEventListener !== "function") {
69
+ throw new TypeError("mpp.ws(endpoint) must return a WebSocket");
70
+ }
71
+ const handle = nextHandle++;
72
+ const connection = {
73
+ socket,
74
+ queue: [],
75
+ queuedBytes: 0,
76
+ waiter: undefined,
77
+ intentionallyClosed: false,
78
+ overflowed: false,
79
+ managed: true,
80
+ };
81
+ connections.set(handle, connection);
82
+ socket.addEventListener("message", (event) => {
83
+ enqueue(connection, typeof event.data === "string"
84
+ ? { kind: "text", text: event.data }
85
+ : { kind: "binary" });
86
+ });
87
+ socket.addEventListener("close", (event) => {
88
+ if (!connection.intentionallyClosed && !connection.overflowed) {
89
+ enqueue(connection, { kind: "closed", detail: `with code ${event.code ?? 1000}` });
90
+ }
91
+ });
92
+ socket.addEventListener("error", () => {
93
+ enqueue(connection, { kind: "error", detail: "MPP WebSocket connection failed" });
94
+ });
95
+ return JSON.stringify({ handle, status: 101, reasoning_included: false });
96
+ }
97
+
62
98
  function send(handle, message) {
63
99
  const connection = connections.get(handle);
64
100
  if (!connection || connection.socket.readyState !== WebSocketImpl.OPEN) {
@@ -69,6 +105,10 @@ export function createBrowserHost(options = {}) {
69
105
  }));
70
106
  }
71
107
  try {
108
+ if (connection.managed) {
109
+ connection.socket.send(JSON.stringify({ mpp: "message", data: message }));
110
+ return Promise.resolve(JSON.stringify({ ok: true }));
111
+ }
72
112
  const frameBytes = encoder.encode(message).byteLength;
73
113
  if (frameBytes > maxBufferedSendBytes
74
114
  || connection.socket.bufferedAmount + frameBytes > maxBufferedSendBytes) {
@@ -4,6 +4,7 @@ export type {
4
4
  PromptInput,
5
5
  PromptItem,
6
6
  ReasoningMode,
7
+ SessionSnapshot,
7
8
  Thinking,
8
9
  Tool,
9
10
  ToolContext,
package/index.d.mts CHANGED
@@ -10,6 +10,7 @@ export type {
10
10
  PromptInput,
11
11
  PromptItem,
12
12
  ReasoningMode,
13
+ SessionSnapshot,
13
14
  Thinking,
14
15
  Tool,
15
16
  ToolContext,
package/internal.mjs CHANGED
@@ -45,6 +45,10 @@ export function getTurnResult(turn) {
45
45
  return state.result;
46
46
  }
47
47
 
48
+ export function getTurnSnapshot(turn) {
49
+ return JSON.parse(turnState(turn).raw.snapshot());
50
+ }
51
+
48
52
  export function steer(turn, options) {
49
53
  const state = turnState(turn);
50
54
  const input = actionInput(options);
@@ -71,6 +75,14 @@ export async function spawn(agent) {
71
75
  return createAgent(await state.raw.spawn(), state.runtime);
72
76
  }
73
77
 
78
+ export function setThinking(agent, thinking) {
79
+ return agentState(agent).raw.setThinking(thinking);
80
+ }
81
+
82
+ export function setFastMode(agent, enabled) {
83
+ return agentState(agent).raw.setFastMode(enabled);
84
+ }
85
+
74
86
  export function subscribeAgentEvents(agent, listener, options = {}) {
75
87
  const state = agentState(agent);
76
88
  if (typeof state.runtime.subscribe !== "function") {
@@ -94,10 +106,12 @@ export function toWasmConfig(options = {}) {
94
106
  const config = { api_key: apiKey };
95
107
  copy(config, "thinking", options.thinking);
96
108
  copy(config, "reasoning_mode", options.reasoningMode);
109
+ copy(config, "fast_mode", options.fastMode);
97
110
  copy(config, "websocket_url", options.websocketUrl);
98
111
  copy(config, "api_base_url", options.apiBaseUrl);
99
112
  copy(config, "instructions", options.instructions);
100
113
  copy(config, "session_id", options.sessionId);
114
+ copy(config, "resume", options.resume);
101
115
  return config;
102
116
  }
103
117
 
@@ -250,6 +264,7 @@ function createTurn(raw, agent) {
250
264
  const turn = {
251
265
  get agent() { return state.agent; },
252
266
  result: () => getTurnResult(turn),
267
+ snapshot: () => getTurnSnapshot(turn),
253
268
  steer: (input) => steer(turn, input),
254
269
  cancel: () => cancel(turn),
255
270
  dispose() {
package/node/Agent.d.mts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type {
2
2
  AgentOptions,
3
3
  DefaultAgent,
4
+ MppSession,
4
5
  ToolMap,
5
6
  } from "../types.mjs";
6
7
 
@@ -9,13 +10,13 @@ export type Agent = DefaultAgent;
9
10
  /** Creates a Node-hosted Rust/WASM Agent. */
10
11
  export function create(options: create.Options): Promise<create.ReturnType>;
11
12
  export declare namespace create {
12
- type Options = AgentOptions & {
13
+ type Options = AgentOptions & ({ apiKey: string; mpp?: never } | { apiKey?: never; mpp: MppSession }) & {
13
14
  apiBaseUrl?: string | undefined;
14
- apiKey: string;
15
15
  connectTimeoutMs?: number | undefined;
16
16
  maxFrameBytes?: number | undefined;
17
17
  maxQueuedBytes?: number | undefined;
18
18
  maxQueuedMessages?: number | undefined;
19
+ module?: unknown;
19
20
  sendTimeoutMs?: number | undefined;
20
21
  tools?: ToolMap | undefined;
21
22
  websocketUrl?: string | undefined;
package/node/Agent.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  import { createRequire } from "node:module";
2
+ import initWeb, { Nanocodex as WebNanocodex } from "../pkg-web/nanocodex.js";
2
3
 
3
4
  import { agentActions } from "../actions/index.mjs";
4
5
  import {
@@ -12,32 +13,45 @@ import {
12
13
  } from "../internal.mjs";
13
14
  import { createNodeHost } from "./host.mjs";
14
15
 
15
- const require = createRequire(import.meta.url);
16
- const { Nanocodex } = require("../pkg-node/nanocodex.js");
16
+ let initializedWeb;
17
+ let NodeNanocodex;
17
18
 
18
19
  export function create(options = {}) {
19
20
  const {
20
21
  thinking,
21
22
  reasoningMode,
23
+ fastMode,
22
24
  instructions,
23
25
  sessionId,
26
+ resume,
24
27
  apiKey,
28
+ mpp,
25
29
  websocketUrl,
26
30
  apiBaseUrl,
31
+ module,
27
32
  ...hostOptions
28
33
  } = options;
29
34
  const events = createEventChannel();
30
- const host = createNodeHost({ ...hostOptions, onEvent: events.emit });
35
+ if (mpp !== undefined && apiKey !== undefined) {
36
+ throw new TypeError("apiKey and mpp are mutually exclusive");
37
+ }
38
+ const host = createNodeHost({ ...hostOptions, mpp, onEvent: events.emit });
31
39
  activateHost(host);
32
40
  const runtime = defineRuntime({
33
41
  key: "node-wasm",
34
42
  name: "Nanocodex Node WASM",
35
43
  type: "node",
36
- create(config) {
44
+ async create(config) {
45
+ activateHost(host);
46
+ const Nanocodex = module === undefined
47
+ ? loadNodeNanocodex()
48
+ : await loadWebNanocodex(module);
37
49
  activateHost(host);
38
50
  return new Nanocodex(JSON.stringify(toWasmConfig({
39
- apiKey,
40
- websocketUrl,
51
+ apiKey: apiKey ?? (mpp === undefined ? undefined : "mpp-managed"),
52
+ websocketUrl: websocketUrl ?? (mpp === undefined
53
+ ? undefined
54
+ : "wss://openai.mpp.tempo.xyz/v1/responses"),
41
55
  apiBaseUrl,
42
56
  ...config,
43
57
  })));
@@ -47,5 +61,24 @@ export function create(options = {}) {
47
61
  release: (raw) => releaseHostSession(host, raw.sessionId),
48
62
  decorate: (agent) => agent.extend(agentActions()),
49
63
  });
50
- return createAgentClient(runtime, { thinking, reasoningMode, instructions, sessionId });
64
+ return createAgentClient(runtime, {
65
+ thinking,
66
+ reasoningMode,
67
+ fastMode,
68
+ instructions,
69
+ sessionId,
70
+ resume,
71
+ });
72
+ }
73
+
74
+ function loadNodeNanocodex() {
75
+ const require = createRequire(import.meta.url);
76
+ NodeNanocodex ||= require("../pkg-node/nanocodex.js").Nanocodex;
77
+ return NodeNanocodex;
78
+ }
79
+
80
+ async function loadWebNanocodex(module) {
81
+ initializedWeb ||= initWeb({ module_or_path: module });
82
+ await initializedWeb;
83
+ return WebNanocodex;
51
84
  }
package/node/host.mjs CHANGED
@@ -24,6 +24,7 @@ export function createNodeHost(options = {}) {
24
24
  let nextHandle = 1;
25
25
 
26
26
  function connect(endpoint, apiKey, sessionId) {
27
+ if (options.mpp) return connectMpp(endpoint);
27
28
  return new Promise((resolve, reject) => {
28
29
  let settled = false;
29
30
  let upgradeResponse;
@@ -80,6 +81,35 @@ export function createNodeHost(options = {}) {
80
81
  });
81
82
  }
82
83
 
84
+ async function connectMpp(endpoint) {
85
+ if (typeof options.mpp.ws !== "function") {
86
+ throw new TypeError("mpp must provide ws(endpoint)");
87
+ }
88
+ const socket = await options.mpp.ws(endpoint);
89
+ if (!socket || typeof socket.addEventListener !== "function") {
90
+ throw new TypeError("mpp.ws(endpoint) must return a WebSocket");
91
+ }
92
+ const handle = nextHandle++;
93
+ const connection = queueState(socket);
94
+ connection.managed = true;
95
+ connections.set(handle, connection);
96
+ socket.addEventListener("message", (event) => {
97
+ enqueue(connection, typeof event.data === "string"
98
+ ? { kind: "text", text: event.data }
99
+ : { kind: "binary" });
100
+ });
101
+ socket.addEventListener("close", (event) => {
102
+ if (!connection.intentionallyClosed && !connection.overflowed) {
103
+ const suffix = event.reason ? `: ${event.reason}` : "";
104
+ enqueue(connection, { kind: "closed", detail: `with code ${event.code ?? 1000}${suffix}` });
105
+ }
106
+ });
107
+ socket.addEventListener("error", () => {
108
+ enqueue(connection, { kind: "error", detail: "MPP WebSocket connection failed" });
109
+ });
110
+ return JSON.stringify({ handle, status: 101, reasoning_included: false });
111
+ }
112
+
83
113
  function send(handle, message) {
84
114
  const connection = connections.get(handle);
85
115
  if (!connection || connection.socket.readyState !== WebSocket.OPEN) {
@@ -89,6 +119,18 @@ export function createNodeHost(options = {}) {
89
119
  error: "WebSocket is no longer open",
90
120
  }));
91
121
  }
122
+ if (connection.managed) {
123
+ try {
124
+ connection.socket.send(JSON.stringify({ mpp: "message", data: message }));
125
+ return Promise.resolve(JSON.stringify({ ok: true }));
126
+ } catch (error) {
127
+ return Promise.resolve(JSON.stringify({
128
+ ok: false,
129
+ reconnectable: connection.socket.readyState !== WebSocket.OPEN,
130
+ error: errorMessage(error),
131
+ }));
132
+ }
133
+ }
92
134
  return new Promise((resolve) => {
93
135
  let completed = false;
94
136
  const timer = setTimeout(() => finish({
@@ -159,7 +201,8 @@ export function createNodeHost(options = {}) {
159
201
  detail: `receive queue exceeded ${maxQueuedMessages} messages or ${maxQueuedBytes} bytes`,
160
202
  };
161
203
  connection.queue.push({ message: error, bytes: messageBytes(error) });
162
- connection.socket.terminate();
204
+ if (typeof connection.socket.terminate === "function") connection.socket.terminate();
205
+ else connection.socket.close(1009, "receive queue exceeded configured bounds");
163
206
  return;
164
207
  }
165
208
  connection.queue.push({ message, bytes });
@@ -187,6 +230,7 @@ function queueState(socket) {
187
230
  waiter: undefined,
188
231
  intentionallyClosed: false,
189
232
  overflowed: false,
233
+ managed: false,
190
234
  };
191
235
  }
192
236
 
package/node/index.d.mts CHANGED
@@ -4,6 +4,7 @@ export type {
4
4
  PromptInput,
5
5
  PromptItem,
6
6
  ReasoningMode,
7
+ SessionSnapshot,
7
8
  Thinking,
8
9
  Tool,
9
10
  ToolContext,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nanocodex",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Viem-style Node and browser bindings for the Nanocodex WASM agent",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -49,6 +49,22 @@ export class Nanocodex {
49
49
  * stopped driver.
50
50
  */
51
51
  promptContent(content_json: string): Turn;
52
+ /**
53
+ * Enable or disable priority processing for subsequently accepted turns.
54
+ *
55
+ * # Errors
56
+ *
57
+ * Rejects after the agent driver stops.
58
+ */
59
+ setFastMode(enabled: boolean): Promise<void>;
60
+ /**
61
+ * Change the reasoning effort for subsequently accepted turns.
62
+ *
63
+ * # Errors
64
+ *
65
+ * Rejects an unsupported effort or a stopped agent driver.
66
+ */
67
+ setThinking(thinking: string): Promise<void>;
52
68
  /**
53
69
  * Start a clean sibling with the same configuration and tools.
54
70
  *
@@ -87,6 +103,14 @@ export class Turn {
87
103
  * await the same pending turn concurrently.
88
104
  */
89
105
  result(): Promise<string>;
106
+ /**
107
+ * Serialize this completed turn's resumable session snapshot.
108
+ *
109
+ * # Errors
110
+ *
111
+ * Throws until the turn has completed or if serialization fails.
112
+ */
113
+ snapshot(): string;
90
114
  /**
91
115
  * Inject input at this active turn's next safe model boundary.
92
116
  *
@@ -119,6 +119,34 @@ class Nanocodex {
119
119
  wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
120
120
  }
121
121
  }
122
+ /**
123
+ * Enable or disable priority processing for subsequently accepted turns.
124
+ *
125
+ * # Errors
126
+ *
127
+ * Rejects after the agent driver stops.
128
+ * @param {boolean} enabled
129
+ * @returns {Promise<void>}
130
+ */
131
+ setFastMode(enabled) {
132
+ const ret = wasm.nanocodex_setFastMode(this.__wbg_ptr, enabled);
133
+ return ret;
134
+ }
135
+ /**
136
+ * Change the reasoning effort for subsequently accepted turns.
137
+ *
138
+ * # Errors
139
+ *
140
+ * Rejects an unsupported effort or a stopped agent driver.
141
+ * @param {string} thinking
142
+ * @returns {Promise<void>}
143
+ */
144
+ setThinking(thinking) {
145
+ const ptr0 = passStringToWasm0(thinking, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
146
+ const len0 = WASM_VECTOR_LEN;
147
+ const ret = wasm.nanocodex_setThinking(this.__wbg_ptr, ptr0, len0);
148
+ return ret;
149
+ }
122
150
  /**
123
151
  * Start a clean sibling with the same configuration and tools.
124
152
  *
@@ -180,6 +208,32 @@ class Turn {
180
208
  const ret = wasm.turn_result(this.__wbg_ptr);
181
209
  return ret;
182
210
  }
211
+ /**
212
+ * Serialize this completed turn's resumable session snapshot.
213
+ *
214
+ * # Errors
215
+ *
216
+ * Throws until the turn has completed or if serialization fails.
217
+ * @returns {string}
218
+ */
219
+ snapshot() {
220
+ let deferred2_0;
221
+ let deferred2_1;
222
+ try {
223
+ const ret = wasm.turn_snapshot(this.__wbg_ptr);
224
+ var ptr1 = ret[0];
225
+ var len1 = ret[1];
226
+ if (ret[3]) {
227
+ ptr1 = 0; len1 = 0;
228
+ throw takeFromExternrefTable0(ret[2]);
229
+ }
230
+ deferred2_0 = ptr1;
231
+ deferred2_1 = len1;
232
+ return getStringFromWasm0(ptr1, len1);
233
+ } finally {
234
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
235
+ }
236
+ }
183
237
  /**
184
238
  * Inject input at this active turn's next safe model boundary.
185
239
  *
@@ -252,17 +306,17 @@ function __wbg_get_imports() {
252
306
  const ret = arg0.call(arg1, arg2);
253
307
  return ret;
254
308
  }, arguments); },
255
- __wbg_close_b36455f162d504cf: function(arg0) {
309
+ __wbg_close_fc18ac046d437740: function(arg0) {
256
310
  globalThis.nanocodexHost.close(arg0 >>> 0);
257
311
  },
258
- __wbg_connect_82a82e999c6dad2f: function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
312
+ __wbg_connect_703930fc33e0b1fe: function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
259
313
  const ret = globalThis.nanocodexHost.connect(getStringFromWasm0(arg0, arg1), getStringFromWasm0(arg2, arg3), getStringFromWasm0(arg4, arg5));
260
314
  return ret;
261
315
  }, arguments); },
262
- __wbg_emitEvent_fe69df479c60b4dc: function(arg0, arg1) {
316
+ __wbg_emitEvent_6aeed1b6a9321c6d: function(arg0, arg1) {
263
317
  globalThis.nanocodexHost.emitEvent(getStringFromWasm0(arg0, arg1));
264
318
  },
265
- __wbg_executeCode_1b0871b5adb65342: function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
319
+ __wbg_executeCode_9b60ca31e4917172: function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
266
320
  const ret = globalThis.nanocodexHost.executeCode(getStringFromWasm0(arg0, arg1), getStringFromWasm0(arg2, arg3), getStringFromWasm0(arg4, arg5));
267
321
  return ret;
268
322
  }, arguments); },
@@ -313,7 +367,7 @@ function __wbg_get_imports() {
313
367
  const a = state0.a;
314
368
  state0.a = 0;
315
369
  try {
316
- return wasm_bindgen__convert__closures_____invoke__h179cb8eb2e8755ae(a, state0.b, arg0, arg1);
370
+ return wasm_bindgen_6c97e59ea7837008___convert__closures_____invoke___js_sys_ec93bd22bf926fce___Function_fn_wasm_bindgen_6c97e59ea7837008___JsValue_____wasm_bindgen_6c97e59ea7837008___sys__Undefined___js_sys_ec93bd22bf926fce___Function_fn_wasm_bindgen_6c97e59ea7837008___JsValue_____wasm_bindgen_6c97e59ea7837008___sys__Undefined_______true_(a, state0.b, arg0, arg1);
317
371
  } finally {
318
372
  state0.a = a;
319
373
  }
@@ -324,7 +378,7 @@ function __wbg_get_imports() {
324
378
  state0.a = 0;
325
379
  }
326
380
  },
327
- __wbg_next_9da746b48109347a: function() { return handleError(function (arg0, arg1) {
381
+ __wbg_next_49b0de35982cd4f1: function() { return handleError(function (arg0, arg1) {
328
382
  const ret = globalThis.nanocodexHost.next(arg0 >>> 0, arg1 >>> 0);
329
383
  return ret;
330
384
  }, arguments); },
@@ -355,11 +409,11 @@ function __wbg_get_imports() {
355
409
  const ret = arg0.resolvedOptions();
356
410
  return ret;
357
411
  },
358
- __wbg_send_211e498fb0677de2: function() { return handleError(function (arg0, arg1, arg2) {
412
+ __wbg_send_dcb152f7d2b1f786: function() { return handleError(function (arg0, arg1, arg2) {
359
413
  const ret = globalThis.nanocodexHost.send(arg0 >>> 0, getStringFromWasm0(arg1, arg2));
360
414
  return ret;
361
415
  }, arguments); },
362
- __wbg_sleep_03cdb40ace612b9f: function(arg0) {
416
+ __wbg_sleep_f4e409e87a98636b: function(arg0) {
363
417
  const ret = globalThis.nanocodexHost.sleep(arg0 >>> 0);
364
418
  return ret;
365
419
  },
@@ -387,7 +441,7 @@ function __wbg_get_imports() {
387
441
  const ret = arg0.then(arg1);
388
442
  return ret;
389
443
  },
390
- __wbg_toolDefinitions_976a998d8a17c04c: function(arg0, arg1, arg2) {
444
+ __wbg_toolDefinitions_7280a1e99f843af9: function(arg0, arg1, arg2) {
391
445
  const ret = globalThis.nanocodexHost.toolDefinitions(getStringFromWasm0(arg1, arg2));
392
446
  const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
393
447
  const len1 = WASM_VECTOR_LEN;
@@ -395,8 +449,8 @@ function __wbg_get_imports() {
395
449
  getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
396
450
  },
397
451
  __wbindgen_cast_0000000000000001: function(arg0, arg1) {
398
- // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 57, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
399
- const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h02eb5eea4c10a535);
452
+ // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 58, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
453
+ const ret = makeMutClosure(arg0, arg1, wasm_bindgen_6c97e59ea7837008___convert__closures_____invoke___wasm_bindgen_6c97e59ea7837008___JsValue__core_9b3796e30d99ddb7___result__Result_____wasm_bindgen_6c97e59ea7837008___JsError___true_);
400
454
  return ret;
401
455
  },
402
456
  __wbindgen_cast_0000000000000002: function(arg0, arg1) {
@@ -420,15 +474,15 @@ function __wbg_get_imports() {
420
474
  };
421
475
  }
422
476
 
423
- function wasm_bindgen__convert__closures_____invoke__h02eb5eea4c10a535(arg0, arg1, arg2) {
424
- const ret = wasm.wasm_bindgen__convert__closures_____invoke__h02eb5eea4c10a535(arg0, arg1, arg2);
477
+ function wasm_bindgen_6c97e59ea7837008___convert__closures_____invoke___wasm_bindgen_6c97e59ea7837008___JsValue__core_9b3796e30d99ddb7___result__Result_____wasm_bindgen_6c97e59ea7837008___JsError___true_(arg0, arg1, arg2) {
478
+ const ret = wasm.wasm_bindgen_6c97e59ea7837008___convert__closures_____invoke___wasm_bindgen_6c97e59ea7837008___JsValue__core_9b3796e30d99ddb7___result__Result_____wasm_bindgen_6c97e59ea7837008___JsError___true_(arg0, arg1, arg2);
425
479
  if (ret[1]) {
426
480
  throw takeFromExternrefTable0(ret[0]);
427
481
  }
428
482
  }
429
483
 
430
- function wasm_bindgen__convert__closures_____invoke__h179cb8eb2e8755ae(arg0, arg1, arg2, arg3) {
431
- wasm.wasm_bindgen__convert__closures_____invoke__h179cb8eb2e8755ae(arg0, arg1, arg2, arg3);
484
+ function wasm_bindgen_6c97e59ea7837008___convert__closures_____invoke___js_sys_ec93bd22bf926fce___Function_fn_wasm_bindgen_6c97e59ea7837008___JsValue_____wasm_bindgen_6c97e59ea7837008___sys__Undefined___js_sys_ec93bd22bf926fce___Function_fn_wasm_bindgen_6c97e59ea7837008___JsValue_____wasm_bindgen_6c97e59ea7837008___sys__Undefined_______true_(arg0, arg1, arg2, arg3) {
485
+ wasm.wasm_bindgen_6c97e59ea7837008___convert__closures_____invoke___js_sys_ec93bd22bf926fce___Function_fn_wasm_bindgen_6c97e59ea7837008___JsValue_____wasm_bindgen_6c97e59ea7837008___sys__Undefined___js_sys_ec93bd22bf926fce___Function_fn_wasm_bindgen_6c97e59ea7837008___JsValue_____wasm_bindgen_6c97e59ea7837008___sys__Undefined_______true_(arg0, arg1, arg2, arg3);
432
486
  }
433
487
 
434
488
  const NanocodexFinalization = (typeof FinalizationRegistry === 'undefined')
Binary file
@@ -9,13 +9,16 @@ export const nanocodex_new: (a: number, b: number) => [number, number, number];
9
9
  export const nanocodex_prompt: (a: number, b: number, c: number) => [number, number, number];
10
10
  export const nanocodex_promptContent: (a: number, b: number, c: number) => [number, number, number];
11
11
  export const nanocodex_sessionId: (a: number) => [number, number];
12
+ export const nanocodex_setFastMode: (a: number, b: number) => any;
13
+ export const nanocodex_setThinking: (a: number, b: number, c: number) => any;
12
14
  export const nanocodex_spawn: (a: number) => any;
13
15
  export const turn_cancel: (a: number) => any;
14
16
  export const turn_result: (a: number) => any;
17
+ export const turn_snapshot: (a: number) => [number, number, number, number];
15
18
  export const turn_steer: (a: number, b: number, c: number) => any;
16
19
  export const turn_steerContent: (a: number, b: number, c: number) => any;
17
- export const wasm_bindgen__convert__closures_____invoke__h02eb5eea4c10a535: (a: number, b: number, c: any) => [number, number];
18
- export const wasm_bindgen__convert__closures_____invoke__h179cb8eb2e8755ae: (a: number, b: number, c: any, d: any) => void;
20
+ export const wasm_bindgen_6c97e59ea7837008___convert__closures_____invoke___wasm_bindgen_6c97e59ea7837008___JsValue__core_9b3796e30d99ddb7___result__Result_____wasm_bindgen_6c97e59ea7837008___JsError___true_: (a: number, b: number, c: any) => [number, number];
21
+ export const wasm_bindgen_6c97e59ea7837008___convert__closures_____invoke___js_sys_ec93bd22bf926fce___Function_fn_wasm_bindgen_6c97e59ea7837008___JsValue_____wasm_bindgen_6c97e59ea7837008___sys__Undefined___js_sys_ec93bd22bf926fce___Function_fn_wasm_bindgen_6c97e59ea7837008___JsValue_____wasm_bindgen_6c97e59ea7837008___sys__Undefined_______true_: (a: number, b: number, c: any, d: any) => void;
19
22
  export const __wbindgen_malloc: (a: number, b: number) => number;
20
23
  export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
21
24
  export const __wbindgen_exn_store: (a: number) => void;
@@ -49,6 +49,22 @@ export class Nanocodex {
49
49
  * stopped driver.
50
50
  */
51
51
  promptContent(content_json: string): Turn;
52
+ /**
53
+ * Enable or disable priority processing for subsequently accepted turns.
54
+ *
55
+ * # Errors
56
+ *
57
+ * Rejects after the agent driver stops.
58
+ */
59
+ setFastMode(enabled: boolean): Promise<void>;
60
+ /**
61
+ * Change the reasoning effort for subsequently accepted turns.
62
+ *
63
+ * # Errors
64
+ *
65
+ * Rejects an unsupported effort or a stopped agent driver.
66
+ */
67
+ setThinking(thinking: string): Promise<void>;
52
68
  /**
53
69
  * Start a clean sibling with the same configuration and tools.
54
70
  *
@@ -87,6 +103,14 @@ export class Turn {
87
103
  * await the same pending turn concurrently.
88
104
  */
89
105
  result(): Promise<string>;
106
+ /**
107
+ * Serialize this completed turn's resumable session snapshot.
108
+ *
109
+ * # Errors
110
+ *
111
+ * Throws until the turn has completed or if serialization fails.
112
+ */
113
+ snapshot(): string;
90
114
  /**
91
115
  * Inject input at this active turn's next safe model boundary.
92
116
  *
@@ -120,13 +144,16 @@ export interface InitOutput {
120
144
  readonly nanocodex_prompt: (a: number, b: number, c: number) => [number, number, number];
121
145
  readonly nanocodex_promptContent: (a: number, b: number, c: number) => [number, number, number];
122
146
  readonly nanocodex_sessionId: (a: number) => [number, number];
147
+ readonly nanocodex_setFastMode: (a: number, b: number) => any;
148
+ readonly nanocodex_setThinking: (a: number, b: number, c: number) => any;
123
149
  readonly nanocodex_spawn: (a: number) => any;
124
150
  readonly turn_cancel: (a: number) => any;
125
151
  readonly turn_result: (a: number) => any;
152
+ readonly turn_snapshot: (a: number) => [number, number, number, number];
126
153
  readonly turn_steer: (a: number, b: number, c: number) => any;
127
154
  readonly turn_steerContent: (a: number, b: number, c: number) => any;
128
- readonly wasm_bindgen__convert__closures_____invoke__h02eb5eea4c10a535: (a: number, b: number, c: any) => [number, number];
129
- readonly wasm_bindgen__convert__closures_____invoke__h179cb8eb2e8755ae: (a: number, b: number, c: any, d: any) => void;
155
+ readonly wasm_bindgen_6c97e59ea7837008___convert__closures_____invoke___wasm_bindgen_6c97e59ea7837008___JsValue__core_9b3796e30d99ddb7___result__Result_____wasm_bindgen_6c97e59ea7837008___JsError___true_: (a: number, b: number, c: any) => [number, number];
156
+ readonly wasm_bindgen_6c97e59ea7837008___convert__closures_____invoke___js_sys_ec93bd22bf926fce___Function_fn_wasm_bindgen_6c97e59ea7837008___JsValue_____wasm_bindgen_6c97e59ea7837008___sys__Undefined___js_sys_ec93bd22bf926fce___Function_fn_wasm_bindgen_6c97e59ea7837008___JsValue_____wasm_bindgen_6c97e59ea7837008___sys__Undefined_______true_: (a: number, b: number, c: any, d: any) => void;
130
157
  readonly __wbindgen_malloc: (a: number, b: number) => number;
131
158
  readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
132
159
  readonly __wbindgen_exn_store: (a: number) => void;
@@ -119,6 +119,34 @@ export class Nanocodex {
119
119
  wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
120
120
  }
121
121
  }
122
+ /**
123
+ * Enable or disable priority processing for subsequently accepted turns.
124
+ *
125
+ * # Errors
126
+ *
127
+ * Rejects after the agent driver stops.
128
+ * @param {boolean} enabled
129
+ * @returns {Promise<void>}
130
+ */
131
+ setFastMode(enabled) {
132
+ const ret = wasm.nanocodex_setFastMode(this.__wbg_ptr, enabled);
133
+ return ret;
134
+ }
135
+ /**
136
+ * Change the reasoning effort for subsequently accepted turns.
137
+ *
138
+ * # Errors
139
+ *
140
+ * Rejects an unsupported effort or a stopped agent driver.
141
+ * @param {string} thinking
142
+ * @returns {Promise<void>}
143
+ */
144
+ setThinking(thinking) {
145
+ const ptr0 = passStringToWasm0(thinking, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
146
+ const len0 = WASM_VECTOR_LEN;
147
+ const ret = wasm.nanocodex_setThinking(this.__wbg_ptr, ptr0, len0);
148
+ return ret;
149
+ }
122
150
  /**
123
151
  * Start a clean sibling with the same configuration and tools.
124
152
  *
@@ -179,6 +207,32 @@ export class Turn {
179
207
  const ret = wasm.turn_result(this.__wbg_ptr);
180
208
  return ret;
181
209
  }
210
+ /**
211
+ * Serialize this completed turn's resumable session snapshot.
212
+ *
213
+ * # Errors
214
+ *
215
+ * Throws until the turn has completed or if serialization fails.
216
+ * @returns {string}
217
+ */
218
+ snapshot() {
219
+ let deferred2_0;
220
+ let deferred2_1;
221
+ try {
222
+ const ret = wasm.turn_snapshot(this.__wbg_ptr);
223
+ var ptr1 = ret[0];
224
+ var len1 = ret[1];
225
+ if (ret[3]) {
226
+ ptr1 = 0; len1 = 0;
227
+ throw takeFromExternrefTable0(ret[2]);
228
+ }
229
+ deferred2_0 = ptr1;
230
+ deferred2_1 = len1;
231
+ return getStringFromWasm0(ptr1, len1);
232
+ } finally {
233
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
234
+ }
235
+ }
182
236
  /**
183
237
  * Inject input at this active turn's next safe model boundary.
184
238
  *
@@ -250,17 +304,17 @@ function __wbg_get_imports() {
250
304
  const ret = arg0.call(arg1, arg2);
251
305
  return ret;
252
306
  }, arguments); },
253
- __wbg_close_b36455f162d504cf: function(arg0) {
307
+ __wbg_close_fc18ac046d437740: function(arg0) {
254
308
  globalThis.nanocodexHost.close(arg0 >>> 0);
255
309
  },
256
- __wbg_connect_82a82e999c6dad2f: function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
310
+ __wbg_connect_703930fc33e0b1fe: function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
257
311
  const ret = globalThis.nanocodexHost.connect(getStringFromWasm0(arg0, arg1), getStringFromWasm0(arg2, arg3), getStringFromWasm0(arg4, arg5));
258
312
  return ret;
259
313
  }, arguments); },
260
- __wbg_emitEvent_fe69df479c60b4dc: function(arg0, arg1) {
314
+ __wbg_emitEvent_6aeed1b6a9321c6d: function(arg0, arg1) {
261
315
  globalThis.nanocodexHost.emitEvent(getStringFromWasm0(arg0, arg1));
262
316
  },
263
- __wbg_executeCode_1b0871b5adb65342: function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
317
+ __wbg_executeCode_9b60ca31e4917172: function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
264
318
  const ret = globalThis.nanocodexHost.executeCode(getStringFromWasm0(arg0, arg1), getStringFromWasm0(arg2, arg3), getStringFromWasm0(arg4, arg5));
265
319
  return ret;
266
320
  }, arguments); },
@@ -311,7 +365,7 @@ function __wbg_get_imports() {
311
365
  const a = state0.a;
312
366
  state0.a = 0;
313
367
  try {
314
- return wasm_bindgen__convert__closures_____invoke__h179cb8eb2e8755ae(a, state0.b, arg0, arg1);
368
+ return wasm_bindgen_6c97e59ea7837008___convert__closures_____invoke___js_sys_ec93bd22bf926fce___Function_fn_wasm_bindgen_6c97e59ea7837008___JsValue_____wasm_bindgen_6c97e59ea7837008___sys__Undefined___js_sys_ec93bd22bf926fce___Function_fn_wasm_bindgen_6c97e59ea7837008___JsValue_____wasm_bindgen_6c97e59ea7837008___sys__Undefined_______true_(a, state0.b, arg0, arg1);
315
369
  } finally {
316
370
  state0.a = a;
317
371
  }
@@ -322,7 +376,7 @@ function __wbg_get_imports() {
322
376
  state0.a = 0;
323
377
  }
324
378
  },
325
- __wbg_next_9da746b48109347a: function() { return handleError(function (arg0, arg1) {
379
+ __wbg_next_49b0de35982cd4f1: function() { return handleError(function (arg0, arg1) {
326
380
  const ret = globalThis.nanocodexHost.next(arg0 >>> 0, arg1 >>> 0);
327
381
  return ret;
328
382
  }, arguments); },
@@ -353,11 +407,11 @@ function __wbg_get_imports() {
353
407
  const ret = arg0.resolvedOptions();
354
408
  return ret;
355
409
  },
356
- __wbg_send_211e498fb0677de2: function() { return handleError(function (arg0, arg1, arg2) {
410
+ __wbg_send_dcb152f7d2b1f786: function() { return handleError(function (arg0, arg1, arg2) {
357
411
  const ret = globalThis.nanocodexHost.send(arg0 >>> 0, getStringFromWasm0(arg1, arg2));
358
412
  return ret;
359
413
  }, arguments); },
360
- __wbg_sleep_03cdb40ace612b9f: function(arg0) {
414
+ __wbg_sleep_f4e409e87a98636b: function(arg0) {
361
415
  const ret = globalThis.nanocodexHost.sleep(arg0 >>> 0);
362
416
  return ret;
363
417
  },
@@ -385,7 +439,7 @@ function __wbg_get_imports() {
385
439
  const ret = arg0.then(arg1);
386
440
  return ret;
387
441
  },
388
- __wbg_toolDefinitions_976a998d8a17c04c: function(arg0, arg1, arg2) {
442
+ __wbg_toolDefinitions_7280a1e99f843af9: function(arg0, arg1, arg2) {
389
443
  const ret = globalThis.nanocodexHost.toolDefinitions(getStringFromWasm0(arg1, arg2));
390
444
  const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
391
445
  const len1 = WASM_VECTOR_LEN;
@@ -393,8 +447,8 @@ function __wbg_get_imports() {
393
447
  getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
394
448
  },
395
449
  __wbindgen_cast_0000000000000001: function(arg0, arg1) {
396
- // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 57, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
397
- const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__h02eb5eea4c10a535);
450
+ // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 58, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
451
+ const ret = makeMutClosure(arg0, arg1, wasm_bindgen_6c97e59ea7837008___convert__closures_____invoke___wasm_bindgen_6c97e59ea7837008___JsValue__core_9b3796e30d99ddb7___result__Result_____wasm_bindgen_6c97e59ea7837008___JsError___true_);
398
452
  return ret;
399
453
  },
400
454
  __wbindgen_cast_0000000000000002: function(arg0, arg1) {
@@ -418,15 +472,15 @@ function __wbg_get_imports() {
418
472
  };
419
473
  }
420
474
 
421
- function wasm_bindgen__convert__closures_____invoke__h02eb5eea4c10a535(arg0, arg1, arg2) {
422
- const ret = wasm.wasm_bindgen__convert__closures_____invoke__h02eb5eea4c10a535(arg0, arg1, arg2);
475
+ function wasm_bindgen_6c97e59ea7837008___convert__closures_____invoke___wasm_bindgen_6c97e59ea7837008___JsValue__core_9b3796e30d99ddb7___result__Result_____wasm_bindgen_6c97e59ea7837008___JsError___true_(arg0, arg1, arg2) {
476
+ const ret = wasm.wasm_bindgen_6c97e59ea7837008___convert__closures_____invoke___wasm_bindgen_6c97e59ea7837008___JsValue__core_9b3796e30d99ddb7___result__Result_____wasm_bindgen_6c97e59ea7837008___JsError___true_(arg0, arg1, arg2);
423
477
  if (ret[1]) {
424
478
  throw takeFromExternrefTable0(ret[0]);
425
479
  }
426
480
  }
427
481
 
428
- function wasm_bindgen__convert__closures_____invoke__h179cb8eb2e8755ae(arg0, arg1, arg2, arg3) {
429
- wasm.wasm_bindgen__convert__closures_____invoke__h179cb8eb2e8755ae(arg0, arg1, arg2, arg3);
482
+ function wasm_bindgen_6c97e59ea7837008___convert__closures_____invoke___js_sys_ec93bd22bf926fce___Function_fn_wasm_bindgen_6c97e59ea7837008___JsValue_____wasm_bindgen_6c97e59ea7837008___sys__Undefined___js_sys_ec93bd22bf926fce___Function_fn_wasm_bindgen_6c97e59ea7837008___JsValue_____wasm_bindgen_6c97e59ea7837008___sys__Undefined_______true_(arg0, arg1, arg2, arg3) {
483
+ wasm.wasm_bindgen_6c97e59ea7837008___convert__closures_____invoke___js_sys_ec93bd22bf926fce___Function_fn_wasm_bindgen_6c97e59ea7837008___JsValue_____wasm_bindgen_6c97e59ea7837008___sys__Undefined___js_sys_ec93bd22bf926fce___Function_fn_wasm_bindgen_6c97e59ea7837008___JsValue_____wasm_bindgen_6c97e59ea7837008___sys__Undefined_______true_(arg0, arg1, arg2, arg3);
430
484
  }
431
485
 
432
486
  const NanocodexFinalization = (typeof FinalizationRegistry === 'undefined')
Binary file
@@ -9,13 +9,16 @@ export const nanocodex_new: (a: number, b: number) => [number, number, number];
9
9
  export const nanocodex_prompt: (a: number, b: number, c: number) => [number, number, number];
10
10
  export const nanocodex_promptContent: (a: number, b: number, c: number) => [number, number, number];
11
11
  export const nanocodex_sessionId: (a: number) => [number, number];
12
+ export const nanocodex_setFastMode: (a: number, b: number) => any;
13
+ export const nanocodex_setThinking: (a: number, b: number, c: number) => any;
12
14
  export const nanocodex_spawn: (a: number) => any;
13
15
  export const turn_cancel: (a: number) => any;
14
16
  export const turn_result: (a: number) => any;
17
+ export const turn_snapshot: (a: number) => [number, number, number, number];
15
18
  export const turn_steer: (a: number, b: number, c: number) => any;
16
19
  export const turn_steerContent: (a: number, b: number, c: number) => any;
17
- export const wasm_bindgen__convert__closures_____invoke__h02eb5eea4c10a535: (a: number, b: number, c: any) => [number, number];
18
- export const wasm_bindgen__convert__closures_____invoke__h179cb8eb2e8755ae: (a: number, b: number, c: any, d: any) => void;
20
+ export const wasm_bindgen_6c97e59ea7837008___convert__closures_____invoke___wasm_bindgen_6c97e59ea7837008___JsValue__core_9b3796e30d99ddb7___result__Result_____wasm_bindgen_6c97e59ea7837008___JsError___true_: (a: number, b: number, c: any) => [number, number];
21
+ export const wasm_bindgen_6c97e59ea7837008___convert__closures_____invoke___js_sys_ec93bd22bf926fce___Function_fn_wasm_bindgen_6c97e59ea7837008___JsValue_____wasm_bindgen_6c97e59ea7837008___sys__Undefined___js_sys_ec93bd22bf926fce___Function_fn_wasm_bindgen_6c97e59ea7837008___JsValue_____wasm_bindgen_6c97e59ea7837008___sys__Undefined_______true_: (a: number, b: number, c: any, d: any) => void;
19
22
  export const __wbindgen_malloc: (a: number, b: number) => number;
20
23
  export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
21
24
  export const __wbindgen_exn_store: (a: number) => void;
@@ -31,6 +31,10 @@ export function createCodeRuntime(toolConfiguration = {}, extras = {}) {
31
31
  tools[name] = async (input) => {
32
32
  const callId = `${parentCallId}/code-${nextCallId++}`;
33
33
  const toolStartedAt = performance.now();
34
+ const startedAfterNs = Math.max(
35
+ 0,
36
+ Math.round((toolStartedAt - startedAt) * 1_000_000),
37
+ );
34
38
  try {
35
39
  const result = await tool.handler(input, { sessionId, parentCallId, callId });
36
40
  nestedCalls.push({
@@ -41,6 +45,7 @@ export function createCodeRuntime(toolConfiguration = {}, extras = {}) {
41
45
  input: clone(input) ?? null,
42
46
  output: outputBody(result),
43
47
  success: true,
48
+ started_after_ns: startedAfterNs,
44
49
  duration_ns: elapsedNs(toolStartedAt),
45
50
  });
46
51
  return result;
@@ -51,6 +56,7 @@ export function createCodeRuntime(toolConfiguration = {}, extras = {}) {
51
56
  input: clone(input) ?? null,
52
57
  output: errorMessage(error),
53
58
  success: false,
59
+ started_after_ns: startedAfterNs,
54
60
  duration_ns: elapsedNs(toolStartedAt),
55
61
  });
56
62
  throw error;
package/types.d.mts CHANGED
@@ -19,10 +19,23 @@ export type AgentEvent = {
19
19
  export type AgentOptions = {
20
20
  instructions?: string | undefined;
21
21
  reasoningMode?: ReasoningMode | undefined;
22
+ fastMode?: boolean | undefined;
22
23
  sessionId?: string | undefined;
23
24
  thinking?: Thinking | undefined;
25
+ resume?: SessionSnapshot | undefined;
24
26
  };
25
27
 
28
+ export type SessionSnapshot = Readonly<{
29
+ version: number;
30
+ model: string;
31
+ lineage_id: string;
32
+ prompt_cache_key: string;
33
+ workspace: string;
34
+ request_prefix?: readonly Record<string, unknown>[] | undefined;
35
+ canonical_context: Record<string, unknown>;
36
+ history: readonly Record<string, unknown>[];
37
+ }>;
38
+
26
39
  export type ForkOptions = { at?: Turn | undefined };
27
40
  export type WatchEventsOptions = { includeAllSessions?: boolean | undefined };
28
41
 
@@ -38,6 +51,8 @@ export type AgentActions = {
38
51
  };
39
52
  session: {
40
53
  fork(options?: ForkOptions): Promise<DefaultAgent>;
54
+ setFastMode(enabled: boolean): Promise<void>;
55
+ setThinking(thinking: Thinking): Promise<void>;
41
56
  spawn(): Promise<DefaultAgent>;
42
57
  };
43
58
  turn: {
@@ -62,6 +77,7 @@ export type DefaultAgent = Agent<AgentActions>;
62
77
  export type Turn<agent extends Agent<object> = Agent<object>> = Readonly<{
63
78
  readonly agent: agent;
64
79
  result(): Promise<string>;
80
+ snapshot(): SessionSnapshot;
65
81
  steer(options: { input: PromptInput }): Promise<void>;
66
82
  cancel(): Promise<void>;
67
83
  dispose(): void;
@@ -80,3 +96,17 @@ export type Tool = {
80
96
  };
81
97
 
82
98
  export type ToolMap = Record<string, Tool>;
99
+
100
+ /** A paid WebSocket session, such as an mppx Tempo session manager. */
101
+ export type MppSession = {
102
+ ws(endpoint: string | URL): Promise<MppWebSocket>;
103
+ close?(): unknown | Promise<unknown>;
104
+ };
105
+
106
+ export type MppWebSocket = {
107
+ readonly readyState: number;
108
+ readonly bufferedAmount?: number | undefined;
109
+ addEventListener(type: string, listener: (event: any) => void, options?: unknown): void;
110
+ send(message: string): void;
111
+ close(code?: number, reason?: string): void;
112
+ };