nanocodex 0.1.1 → 0.3.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
@@ -9,29 +9,182 @@ import { Actions, Agent } from "nanocodex/node";
9
9
 
10
10
  const agent = await Agent.create({
11
11
  apiKey: process.env.OPENAI_API_KEY,
12
+ instructions: "You are a Rust coding agent. Preserve unrelated work and run relevant tests.",
12
13
  reasoningMode: "pro",
13
14
  thinking: "high",
14
15
  tools,
16
+ workspace: process.cwd(),
15
17
  });
16
18
 
17
19
  const turn = agent.turn.prompt({ input: "Build the thing." });
18
- console.log(await turn.result());
20
+ const result = await turn.result();
21
+ turn.dispose();
22
+ console.log(result.finalMessage);
23
+ console.log(result.usage);
24
+ console.log(result.usage.estimated_cost?.usd);
25
+ console.log(result.usage.cost_status);
19
26
 
20
- const branch = await agent.session.fork({ at: turn });
21
- console.log(await branch.turn.prompt({ input: "Try another approach." }).result());
27
+ await agent.session.setThinking("high");
28
+ await agent.session.setFastMode(true);
29
+ await agent.session.compact();
30
+
31
+ const branch = await agent.session.fork({ at: result });
32
+ const branchTurn = branch.turn.prompt({ input: "Try another approach." });
33
+ const branchResult = await branchTurn.result();
34
+ branchTurn.dispose();
35
+ console.log(branchResult.finalMessage);
22
36
 
23
37
  const followOn = Actions.turn.prompt(agent, { input: "Now explain it." });
24
- console.log(await Actions.turn.getResult(followOn));
38
+ console.log((await Actions.turn.getResult(followOn)).finalMessage);
39
+ followOn.dispose();
40
+ await branch.session.shutdown();
41
+ await agent.session.shutdown();
42
+ ```
43
+
44
+ Node and browser applications can instead pay through MPP without an OpenAI
45
+ API key. Pass an MPP session with a `ws(endpoint)` method; an `mppx` Tempo
46
+ session manager has this shape. Nanocodex defaults the socket to
47
+ `wss://openai.mpp.tempo.xyz/v1/responses` when `mpp` is present.
48
+
49
+ ```js
50
+ import { Agent } from "nanocodex/node";
51
+ import { Expiry } from "accounts";
52
+ import { Provider } from "accounts/cli";
53
+ import { tempo } from "mppx/client";
54
+ import { parseUnits } from "viem";
55
+ import { connect } from "viem/experimental/erc7846";
56
+ import WebSocket from "ws";
57
+
58
+ const pathUsd = "0x20c0000000000000000000000000000000000000";
59
+ const provider = Provider.create({ mpp: false });
60
+ if (!provider.store.persist.hasHydrated()) {
61
+ await new Promise((resolve) => provider.store.persist.onFinishHydration(resolve));
62
+ }
63
+ const status = await provider.getAccessKeyStatus();
64
+ if (status === "missing" || status === "expired") {
65
+ await connect(provider.getClient(), {
66
+ capabilities: { authorizeAccessKey: {
67
+ expiry: Expiry.days(1),
68
+ limits: [{ token: pathUsd, limit: parseUnits("25", 6) }],
69
+ } },
70
+ });
71
+ }
72
+ const root = provider.getAccount();
73
+ const account = await provider.store.accessKeys.select({
74
+ account: root.address,
75
+ chainId: provider.getClient().chain.id,
76
+ });
77
+ if (!account) throw new Error("Tempo account has no usable access key");
78
+ console.error(`Tempo access-key signer: ${account.accessKeyAddress}`);
79
+ const mpp = tempo.session.manager({
80
+ account,
81
+ autoSwap: { tokenIn: [pathUsd], slippage: 1 },
82
+ bootstrap: true,
83
+ client: provider.getClient(),
84
+ webSocket: WebSocket,
85
+ maxDeposit: "0.05",
86
+ topUpAmount: "0.05",
87
+ });
88
+
89
+ const agent = await Agent.create({ mpp, thinking: "none", fastMode: true, tools });
90
+ const events = agent.events.watch();
91
+ const unwatch = events.onEvent((event) => {
92
+ process.stdout.write(`${JSON.stringify(event)}\n`);
93
+ });
94
+ let turn;
95
+ try {
96
+ turn = agent.turn.prompt({ input: "Build the thing." });
97
+ const result = await turn.result();
98
+ console.error(result.finalMessage);
99
+ } finally {
100
+ turn?.dispose();
101
+ unwatch();
102
+ events.off();
103
+ const cleanupErrors = [];
104
+ try {
105
+ await agent.session.shutdown();
106
+ } catch (error) {
107
+ cleanupErrors.push(error);
108
+ }
109
+ try {
110
+ await mpp.close();
111
+ } catch (error) {
112
+ cleanupErrors.push(error);
113
+ }
114
+ if (cleanupErrors.length === 1) throw cleanupErrors[0];
115
+ if (cleanupErrors.length > 1) {
116
+ throw new AggregateError(cleanupErrors, "agent shutdown and MPP settlement both failed");
117
+ }
118
+ }
25
119
  ```
26
120
 
121
+ The application still owns its wallet, deposit policy, persisted payment
122
+ channel store, and final settlement. Keep the manager alive to reuse its channel
123
+ across agents, and supply mppx `channelStore` for reuse after a process or page
124
+ restart. Nanocodex never closes a caller-owned MPP session. `apiKey` and `mpp`
125
+ are mutually exclusive.
126
+
127
+ Completed results can be persisted and resumed by a fresh Node or browser
128
+ agent:
129
+
130
+ ```js
131
+ const snapshot = result.snapshot;
132
+ await agent.session.shutdown();
133
+
134
+ const resumed = await Agent.create({
135
+ apiKey: process.env.OPENAI_API_KEY,
136
+ resume: snapshot,
137
+ tools,
138
+ });
139
+ await resumed.session.shutdown();
140
+ ```
141
+
142
+ The snapshot contains authoritative typed history but no provider response ID,
143
+ so the first resumed request safely replays the committed conversation. Resume
144
+ with the same instructions and tool definitions, and release the original
145
+ agent before handing its snapshot to another writer.
146
+
147
+ Node embedders whose bundler relocates package assets may compile and pass the
148
+ web-target artifact explicitly. The runtime still uses the Node host for
149
+ WebSockets and Code Mode:
150
+
151
+ ```js
152
+ const module = await WebAssembly.compile(await readFile(wasmAssetPath));
153
+ const agent = await Agent.create({ apiKey, module });
154
+ ```
155
+
156
+ A Codex-compatible rollout can also be resumed by materializing its committed
157
+ `response_item` history into a snapshot with no `request_prefix`. Nanocodex
158
+ rebuilds the current prefix from the supplied instructions and JavaScript tools
159
+ while preserving the rollout's workspace, lineage, cache key, canonical user
160
+ context, and typed history.
161
+
27
162
  `Agent` and `Actions` are module namespaces, not classes. `Agent.create` returns
28
163
  an owned client decorated with matching domain actions:
29
164
 
30
165
  - `agent.turn.prompt(...)` / `Actions.turn.prompt(agent, ...)`
166
+ - `turn.result()` / `Actions.turn.getResult(turn)`
167
+ - `result.snapshot` / `Actions.turn.getSnapshot(result)`
168
+ - `result.usage` / `Actions.turn.getUsage(result)`
31
169
  - `agent.session.fork(...)` / `Actions.session.fork(agent, ...)`
170
+ - `agent.session.compact()` / `Actions.session.compact(agent)`
171
+ - `agent.session.setThinking(...)` / `Actions.session.setThinking(agent, ...)`
172
+ - `agent.session.setFastMode(...)` / `Actions.session.setFastMode(agent, ...)`
173
+ - `agent.session.shutdown()` / `Actions.session.shutdown(agent)`
32
174
  - `agent.session.spawn()` / `Actions.session.spawn(agent)`
33
175
  - `agent.events.watch(...)` / `Actions.events.watch(agent, ...)`
34
176
 
177
+ `turn.result()` resolves to a frozen completed `TurnResult`. Its
178
+ `finalMessage` is eager; `usage` and `snapshot` cross the WASM boundary lazily
179
+ once and are then cached. Historical `fork({ at })` accepts this completed
180
+ result, never an unfinished turn or a provider response ID.
181
+
182
+ `turn.dispose()` only releases the JavaScript/WASM handle; like dropping the
183
+ Rust `Turn`, it does not cancel accepted work. Await `turn.cancel()` before
184
+ disposing unfinished work. At an application or session boundary,
185
+ `agent.session.shutdown()` cancels unfinished turns and joins driver, model,
186
+ tool, and transport cleanup.
187
+
35
188
  Every action owns its types, for example `Actions.turn.prompt.Options`,
36
189
  `Actions.turn.prompt.ReturnType`, and `Actions.events.watch.Watcher`.
37
190
 
@@ -45,6 +198,10 @@ unlisten();
45
198
  watch.off();
46
199
  ```
47
200
 
201
+ A throwing callback is reported through the host's `reportError` hook (or
202
+ `console.error` when that hook is unavailable) without interrupting later
203
+ listeners or the owned agent lifecycle.
204
+
48
205
  The same watcher can instead be consumed as an ordered async iterable; breaking
49
206
  the loop releases that iterator, while `watch.off()` terminates the whole watch.
50
207
 
@@ -90,9 +247,16 @@ manager or build step:
90
247
 
91
248
  ```html
92
249
  <script type="module">
93
- import { Agent } from "https://cdn.jsdelivr.net/npm/nanocodex@0.1.0/browser/index.mjs";
250
+ import { Agent } from "https://cdn.jsdelivr.net/npm/nanocodex@0.3.0/browser/index.mjs";
94
251
  const agent = await Agent.create({ websocketUrl: "/api/responses" });
95
- console.log(await agent.turn.prompt({ input: "Hello." }).result());
252
+ const turn = agent.turn.prompt({ input: "Hello." });
253
+ try {
254
+ const result = await turn.result();
255
+ console.log(result.finalMessage);
256
+ } finally {
257
+ turn.dispose();
258
+ await agent.session.shutdown();
259
+ }
96
260
  </script>
97
261
  ```
98
262
 
@@ -1,19 +1,34 @@
1
1
  import { subscribeAgentEvents } from "../internal.mjs";
2
2
 
3
+ const MAX_BUFFERED_EVENTS = 4_096;
4
+ const MAX_BUFFERED_EVENT_CHARACTERS = 32 * 1024 * 1024;
5
+
3
6
  export function watch(agent, options = {}) {
4
7
  const listeners = new Set();
5
8
  const iterators = new Set();
6
9
  let unsubscribe;
7
10
  let closed = false;
8
11
 
9
- const emit = (event) => {
10
- for (const listener of listeners) listener(event);
11
- for (const iterator of iterators) iterator.push(event);
12
+ const emit = (event, encodedLength) => {
13
+ for (const listener of listeners) {
14
+ try {
15
+ listener(event);
16
+ } catch (error) {
17
+ reportListenerError(error);
18
+ }
19
+ }
20
+ for (const iterator of iterators) iterator.push(event, encodedLength);
12
21
  };
13
22
 
14
23
  const start = () => {
15
24
  if (closed || unsubscribe) return;
16
- unsubscribe = subscribeAgentEvents(agent, emit, options);
25
+ unsubscribe = subscribeAgentEvents(agent, emit, options, () => watcher.off());
26
+ };
27
+
28
+ const stopIfIdle = () => {
29
+ if (listeners.size || iterators.size) return;
30
+ unsubscribe?.();
31
+ unsubscribe = undefined;
17
32
  };
18
33
 
19
34
  const watcher = {
@@ -22,7 +37,10 @@ export function watch(agent, options = {}) {
22
37
  if (closed) return () => {};
23
38
  listeners.add(listener);
24
39
  start();
25
- return () => listeners.delete(listener);
40
+ return () => {
41
+ listeners.delete(listener);
42
+ stopIfIdle();
43
+ };
26
44
  },
27
45
  off() {
28
46
  if (closed) return;
@@ -35,7 +53,10 @@ export function watch(agent, options = {}) {
35
53
  },
36
54
  [Symbol.asyncIterator]() {
37
55
  if (closed) return emptyIterator();
38
- const iterator = eventIterator(() => iterators.delete(iterator));
56
+ const iterator = eventIterator(() => {
57
+ iterators.delete(iterator);
58
+ stopIfIdle();
59
+ });
39
60
  iterators.add(iterator);
40
61
  start();
41
62
  return iterator;
@@ -46,32 +67,82 @@ export function watch(agent, options = {}) {
46
67
 
47
68
  function eventIterator(onEnd) {
48
69
  const queue = [];
49
- let pending;
50
- let done = false;
70
+ let head = 0;
71
+ let bufferedCharacters = 0;
72
+ const pending = [];
73
+ let pendingHead = 0;
74
+ let ended = false;
75
+ let failure;
76
+ let failureReported = false;
77
+ let detached = false;
78
+
79
+ const detach = () => {
80
+ if (detached) return;
81
+ detached = true;
82
+ onEnd();
83
+ };
51
84
 
52
85
  const iterator = {
53
- push(event) {
54
- if (done) return;
55
- if (pending) {
56
- const resolve = pending;
57
- pending = undefined;
86
+ push(event, encodedLength) {
87
+ if (ended || failure) return;
88
+ if (pendingHead < pending.length) {
89
+ const resolve = pending[pendingHead++];
90
+ if (pendingHead === pending.length) {
91
+ pending.length = 0;
92
+ pendingHead = 0;
93
+ }
58
94
  resolve({ done: false, value: event });
59
95
  } else {
60
- queue.push(event);
96
+ const characters = encodedLength ?? JSON.stringify(event).length;
97
+ if (
98
+ queue.length - head >= MAX_BUFFERED_EVENTS
99
+ || bufferedCharacters + characters > MAX_BUFFERED_EVENT_CHARACTERS
100
+ ) {
101
+ failure = new RangeError(
102
+ `event iterator exceeded its private buffer of ${MAX_BUFFERED_EVENTS} events or `
103
+ + `${MAX_BUFFERED_EVENT_CHARACTERS} serialized characters`,
104
+ );
105
+ detach();
106
+ return;
107
+ }
108
+ queue.push({ characters, event });
109
+ bufferedCharacters += characters;
61
110
  }
62
111
  },
63
112
  end() {
64
- if (done) return;
65
- done = true;
66
- onEnd();
67
- pending?.({ done: true, value: undefined });
68
- pending = undefined;
113
+ if (ended) return;
114
+ ended = true;
115
+ detach();
116
+ while (pendingHead < pending.length) {
117
+ pending[pendingHead++]({ done: true, value: undefined });
118
+ }
119
+ pending.length = 0;
120
+ pendingHead = 0;
69
121
  queue.length = 0;
122
+ head = 0;
123
+ bufferedCharacters = 0;
70
124
  },
71
125
  next() {
72
- if (queue.length) return Promise.resolve({ done: false, value: queue.shift() });
73
- if (done) return Promise.resolve({ done: true, value: undefined });
74
- return new Promise((resolve) => { pending = resolve; });
126
+ if (head < queue.length) {
127
+ const entry = queue[head++];
128
+ bufferedCharacters -= entry.characters;
129
+ if (head === queue.length) {
130
+ queue.length = 0;
131
+ head = 0;
132
+ }
133
+ return Promise.resolve({ done: false, value: entry.event });
134
+ }
135
+ if (failure && !failureReported) {
136
+ failureReported = true;
137
+ return Promise.reject(failure);
138
+ }
139
+ if (ended || failure) return Promise.resolve({ done: true, value: undefined });
140
+ if (pending.length - pendingHead >= MAX_BUFFERED_EVENTS) {
141
+ return Promise.reject(new RangeError(
142
+ `event iterator exceeded its private buffer of ${MAX_BUFFERED_EVENTS} pending reads`,
143
+ ));
144
+ }
145
+ return new Promise((resolve) => { pending.push(resolve); });
75
146
  },
76
147
  return() {
77
148
  iterator.end();
@@ -89,3 +160,15 @@ function emptyIterator() {
89
160
  [Symbol.asyncIterator]() { return this; },
90
161
  };
91
162
  }
163
+
164
+ function reportListenerError(error) {
165
+ try {
166
+ if (typeof globalThis.reportError === "function") {
167
+ globalThis.reportError(error);
168
+ return;
169
+ }
170
+ } catch {}
171
+ try {
172
+ globalThis.console?.error?.("Nanocodex event listener failed", error);
173
+ } catch {}
174
+ }
package/actions/index.mjs CHANGED
@@ -10,7 +10,11 @@ export function agentActions() {
10
10
  watch: (options) => events.watch(agent, options),
11
11
  },
12
12
  session: {
13
+ compact: () => session.compact(agent),
13
14
  fork: (options) => session.fork(agent, options),
15
+ setFastMode: (enabled) => session.setFastMode(agent, enabled),
16
+ setThinking: (thinking) => session.setThinking(agent, thinking),
17
+ shutdown: () => session.shutdown(agent),
14
18
  spawn: () => session.spawn(agent),
15
19
  },
16
20
  turn: {
@@ -1,6 +1,9 @@
1
- import type { Agent, DefaultAgent, ForkOptions } from "../types.mjs";
1
+ import type { Agent, DefaultAgent, ForkOptions, Thinking } from "../types.mjs";
2
2
 
3
- /** Forks the latest checkpoint, or the exact completed Turn supplied in `options.at`. */
3
+ /** Compacts retained history immediately without fabricating a user prompt. */
4
+ export function compact(agent: Agent<object>): Promise<void>;
5
+
6
+ /** Forks the latest checkpoint, or the exact completed result supplied in `options.at`. */
4
7
  export function fork(agent: Agent<object>, options?: fork.Options): Promise<fork.ReturnType>;
5
8
  export declare namespace fork {
6
9
  type Options = ForkOptions;
@@ -12,3 +15,12 @@ export function spawn(agent: Agent<object>): Promise<spawn.ReturnType>;
12
15
  export declare namespace spawn {
13
16
  type ReturnType = DefaultAgent;
14
17
  }
18
+
19
+ /** Changes the reasoning effort for subsequently accepted turns. */
20
+ export function setThinking(agent: Agent<object>, thinking: Thinking): Promise<void>;
21
+
22
+ /** Enables or disables priority processing for subsequently accepted turns. */
23
+ export function setFastMode(agent: Agent<object>, enabled: boolean): Promise<void>;
24
+
25
+ /** Stops the driver and joins every resource owned by this Agent. */
26
+ export function shutdown(agent: Agent<object>): Promise<void>;
@@ -1,4 +1,15 @@
1
- import { fork as forkAgent, spawn as spawnAgent } from "../internal.mjs";
1
+ import {
2
+ compact as compactAgent,
3
+ fork as forkAgent,
4
+ setFastMode as setAgentFastMode,
5
+ setThinking as setAgentThinking,
6
+ shutdown as shutdownAgent,
7
+ spawn as spawnAgent,
8
+ } from "../internal.mjs";
9
+
10
+ export function compact(agent) {
11
+ return compactAgent(agent);
12
+ }
2
13
 
3
14
  export function fork(agent, options = {}) {
4
15
  return forkAgent(agent, options);
@@ -7,3 +18,15 @@ export function fork(agent, options = {}) {
7
18
  export function spawn(agent) {
8
19
  return spawnAgent(agent);
9
20
  }
21
+
22
+ export function setThinking(agent, thinking) {
23
+ return setAgentThinking(agent, thinking);
24
+ }
25
+
26
+ export function setFastMode(agent, enabled) {
27
+ return setAgentFastMode(agent, enabled);
28
+ }
29
+
30
+ export function shutdown(agent) {
31
+ return shutdownAgent(agent);
32
+ }
@@ -1,4 +1,11 @@
1
- import type { Agent, PromptInput, Turn } from "../types.mjs";
1
+ import type {
2
+ Agent,
3
+ PromptInput,
4
+ SessionSnapshot,
5
+ Turn,
6
+ TurnResult,
7
+ TurnUsage,
8
+ } from "../types.mjs";
2
9
 
3
10
  /** Accepts a prompt on an owned Agent and returns its independently awaitable Turn. */
4
11
  export function prompt<const agent extends Agent<object>>(
@@ -10,10 +17,22 @@ export declare namespace prompt {
10
17
  type ReturnType<agent extends Agent<object> = Agent<object>> = Turn<agent>;
11
18
  }
12
19
 
13
- /** Waits for a Turn's final assistant message. */
20
+ /** Waits for a Turn's typed completed result. */
14
21
  export function getResult(turn: Turn): Promise<getResult.ReturnType>;
15
22
  export declare namespace getResult {
16
- type ReturnType = string;
23
+ type ReturnType = TurnResult;
24
+ }
25
+
26
+ /** Returns a completed result's serializable session snapshot. */
27
+ export function getSnapshot(result: TurnResult): getSnapshot.ReturnType;
28
+ export declare namespace getSnapshot {
29
+ type ReturnType = SessionSnapshot;
30
+ }
31
+
32
+ /** Returns exact aggregate token usage from a completed result. */
33
+ export function getUsage(result: TurnResult): getUsage.ReturnType;
34
+ export declare namespace getUsage {
35
+ type ReturnType = TurnUsage;
17
36
  }
18
37
 
19
38
  /** Adds input to an active Turn. */
package/actions/turn.mjs CHANGED
@@ -1,6 +1,8 @@
1
1
  import {
2
2
  cancel as cancelTurn,
3
3
  getTurnResult,
4
+ getTurnSnapshot,
5
+ getTurnUsage,
4
6
  prompt as promptTurn,
5
7
  steer as steerTurn,
6
8
  } from "../internal.mjs";
@@ -13,6 +15,14 @@ export function getResult(turn) {
13
15
  return getTurnResult(turn);
14
16
  }
15
17
 
18
+ export function getSnapshot(result) {
19
+ return getTurnSnapshot(result);
20
+ }
21
+
22
+ export function getUsage(result) {
23
+ return getTurnUsage(result);
24
+ }
25
+
16
26
  export function steer(turn, options) {
17
27
  return steerTurn(turn, options);
18
28
  }
@@ -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,14 +10,13 @@ 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
- maxBufferedSendBytes?: number | undefined;
18
- maxQueuedBytes?: number | undefined;
19
- maxQueuedMessages?: number | undefined;
20
20
  module?: unknown;
21
21
  tools?: ToolMap | undefined;
22
22
  websocketUrl?: string | undefined;
package/browser/Agent.mjs CHANGED
@@ -16,18 +16,33 @@ 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,
27
- ...hostOptions
29
+ workspace,
30
+ resume,
31
+ WebSocketImpl,
32
+ createWebSocket,
33
+ tools,
28
34
  } = options;
35
+ if (mpp !== undefined && apiKey !== undefined) {
36
+ throw new TypeError("apiKey and mpp are mutually exclusive");
37
+ }
29
38
  const events = createEventChannel();
30
- const host = createBrowserHost({ ...hostOptions, onEvent: events.emit });
39
+ const host = createBrowserHost({
40
+ WebSocketImpl,
41
+ createWebSocket,
42
+ mpp,
43
+ onEvent: events.emit,
44
+ tools,
45
+ });
31
46
  activateHost(host);
32
47
  const runtime = defineRuntime({
33
48
  key: "browser-wasm",
@@ -39,8 +54,10 @@ export function create(options = {}) {
39
54
  await initialized;
40
55
  activateHost(host);
41
56
  return new Nanocodex(JSON.stringify(toWasmConfig({
42
- apiKey,
43
- websocketUrl,
57
+ apiKey: apiKey ?? (mpp === undefined ? "host-managed" : "mpp-managed"),
58
+ websocketUrl: websocketUrl ?? (mpp === undefined
59
+ ? undefined
60
+ : "wss://openai.mpp.tempo.xyz/v1/responses"),
44
61
  apiBaseUrl,
45
62
  ...config,
46
63
  })));
@@ -50,5 +67,13 @@ export function create(options = {}) {
50
67
  release: (raw) => releaseHostSession(host, raw.sessionId),
51
68
  decorate: (agent) => agent.extend(agentActions()),
52
69
  });
53
- return createAgentClient(runtime, { thinking, reasoningMode, instructions, sessionId });
70
+ return createAgentClient(runtime, {
71
+ thinking,
72
+ reasoningMode,
73
+ fastMode,
74
+ instructions,
75
+ sessionId,
76
+ workspace,
77
+ resume,
78
+ });
54
79
  }