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 +170 -6
- package/actions/events.mjs +105 -22
- package/actions/index.mjs +4 -0
- package/actions/session.d.mts +14 -2
- package/actions/session.mjs +24 -1
- package/actions/turn.d.mts +22 -3
- package/actions/turn.mjs +10 -0
- package/browser/Agent.d.mts +5 -5
- package/browser/Agent.mjs +31 -6
- package/browser/host.mjs +51 -7
- package/browser/index.d.mts +5 -0
- package/index.d.mts +5 -0
- package/internal.mjs +237 -21
- package/node/Agent.d.mts +3 -7
- package/node/Agent.mjs +48 -8
- package/node/host.mjs +78 -13
- package/node/index.d.mts +5 -0
- package/package.json +3 -3
- package/pkg-node/nanocodex.d.ts +84 -29
- package/pkg-node/nanocodex.js +221 -63
- package/pkg-node/nanocodex_bg.wasm +0 -0
- package/pkg-node/nanocodex_bg.wasm.d.ts +10 -2
- package/pkg-web/nanocodex.d.ts +94 -31
- package/pkg-web/nanocodex.js +220 -63
- package/pkg-web/nanocodex_bg.wasm +0 -0
- package/pkg-web/nanocodex_bg.wasm.d.ts +10 -2
- package/runtime/code-runtime.mjs +35 -12
- package/types.d.mts +67 -2
- package/scripts/check-package.mjs +0 -38
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
|
-
|
|
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
|
-
|
|
21
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
|
package/actions/events.mjs
CHANGED
|
@@ -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)
|
|
11
|
-
|
|
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 () =>
|
|
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(() =>
|
|
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
|
|
50
|
-
let
|
|
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 (
|
|
55
|
-
if (pending) {
|
|
56
|
-
const resolve = pending;
|
|
57
|
-
pending
|
|
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
|
-
|
|
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 (
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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)
|
|
73
|
-
|
|
74
|
-
|
|
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: {
|
package/actions/session.d.mts
CHANGED
|
@@ -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
|
-
/**
|
|
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>;
|
package/actions/session.mjs
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
import {
|
|
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
|
+
}
|
package/actions/turn.d.mts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import type {
|
|
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
|
|
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 =
|
|
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
|
}
|
package/browser/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,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
|
|
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
|
-
|
|
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({
|
|
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, {
|
|
70
|
+
return createAgentClient(runtime, {
|
|
71
|
+
thinking,
|
|
72
|
+
reasoningMode,
|
|
73
|
+
fastMode,
|
|
74
|
+
instructions,
|
|
75
|
+
sessionId,
|
|
76
|
+
workspace,
|
|
77
|
+
resume,
|
|
78
|
+
});
|
|
54
79
|
}
|