nanocodex 0.2.0 → 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 +72 -13
- package/actions/events.mjs +105 -22
- package/actions/index.mjs +2 -0
- package/actions/session.d.mts +7 -1
- package/actions/session.mjs +10 -0
- package/actions/turn.d.mts +18 -5
- package/actions/turn.mjs +7 -2
- package/browser/Agent.d.mts +0 -3
- package/browser/Agent.mjs +12 -2
- package/browser/host.mjs +11 -7
- package/browser/index.d.mts +4 -0
- package/index.d.mts +4 -0
- package/internal.mjs +225 -24
- package/node/Agent.d.mts +0 -5
- package/node/Agent.mjs +9 -2
- package/node/host.mjs +33 -12
- package/node/index.d.mts +4 -0
- package/package.json +3 -3
- package/pkg-node/nanocodex.d.ts +69 -38
- package/pkg-node/nanocodex.js +193 -89
- package/pkg-node/nanocodex_bg.wasm +0 -0
- package/pkg-node/nanocodex_bg.wasm.d.ts +7 -2
- package/pkg-web/nanocodex.d.ts +76 -40
- package/pkg-web/nanocodex.js +191 -88
- package/pkg-web/nanocodex_bg.wasm +0 -0
- package/pkg-web/nanocodex_bg.wasm.d.ts +7 -2
- package/runtime/code-runtime.mjs +29 -12
- package/types.d.mts +38 -3
- package/scripts/check-package.mjs +0 -38
package/README.md
CHANGED
|
@@ -9,22 +9,36 @@ 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
27
|
await agent.session.setThinking("high");
|
|
21
28
|
await agent.session.setFastMode(true);
|
|
29
|
+
await agent.session.compact();
|
|
22
30
|
|
|
23
|
-
const branch = await agent.session.fork({ at:
|
|
24
|
-
|
|
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);
|
|
25
36
|
|
|
26
37
|
const followOn = Actions.turn.prompt(agent, { input: "Now explain it." });
|
|
27
|
-
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();
|
|
28
42
|
```
|
|
29
43
|
|
|
30
44
|
Node and browser applications can instead pay through MPP without an OpenAI
|
|
@@ -77,13 +91,30 @@ const events = agent.events.watch();
|
|
|
77
91
|
const unwatch = events.onEvent((event) => {
|
|
78
92
|
process.stdout.write(`${JSON.stringify(event)}\n`);
|
|
79
93
|
});
|
|
94
|
+
let turn;
|
|
80
95
|
try {
|
|
81
|
-
|
|
96
|
+
turn = agent.turn.prompt({ input: "Build the thing." });
|
|
97
|
+
const result = await turn.result();
|
|
98
|
+
console.error(result.finalMessage);
|
|
82
99
|
} finally {
|
|
83
|
-
|
|
100
|
+
turn?.dispose();
|
|
84
101
|
unwatch();
|
|
85
102
|
events.off();
|
|
86
|
-
|
|
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
|
+
}
|
|
87
118
|
}
|
|
88
119
|
```
|
|
89
120
|
|
|
@@ -93,17 +124,19 @@ across agents, and supply mppx `channelStore` for reuse after a process or page
|
|
|
93
124
|
restart. Nanocodex never closes a caller-owned MPP session. `apiKey` and `mpp`
|
|
94
125
|
are mutually exclusive.
|
|
95
126
|
|
|
96
|
-
Completed
|
|
127
|
+
Completed results can be persisted and resumed by a fresh Node or browser
|
|
128
|
+
agent:
|
|
97
129
|
|
|
98
130
|
```js
|
|
99
|
-
const snapshot =
|
|
100
|
-
agent.
|
|
131
|
+
const snapshot = result.snapshot;
|
|
132
|
+
await agent.session.shutdown();
|
|
101
133
|
|
|
102
134
|
const resumed = await Agent.create({
|
|
103
135
|
apiKey: process.env.OPENAI_API_KEY,
|
|
104
136
|
resume: snapshot,
|
|
105
137
|
tools,
|
|
106
138
|
});
|
|
139
|
+
await resumed.session.shutdown();
|
|
107
140
|
```
|
|
108
141
|
|
|
109
142
|
The snapshot contains authoritative typed history but no provider response ID,
|
|
@@ -130,13 +163,28 @@ context, and typed history.
|
|
|
130
163
|
an owned client decorated with matching domain actions:
|
|
131
164
|
|
|
132
165
|
- `agent.turn.prompt(...)` / `Actions.turn.prompt(agent, ...)`
|
|
133
|
-
- `turn.
|
|
166
|
+
- `turn.result()` / `Actions.turn.getResult(turn)`
|
|
167
|
+
- `result.snapshot` / `Actions.turn.getSnapshot(result)`
|
|
168
|
+
- `result.usage` / `Actions.turn.getUsage(result)`
|
|
134
169
|
- `agent.session.fork(...)` / `Actions.session.fork(agent, ...)`
|
|
170
|
+
- `agent.session.compact()` / `Actions.session.compact(agent)`
|
|
135
171
|
- `agent.session.setThinking(...)` / `Actions.session.setThinking(agent, ...)`
|
|
136
172
|
- `agent.session.setFastMode(...)` / `Actions.session.setFastMode(agent, ...)`
|
|
173
|
+
- `agent.session.shutdown()` / `Actions.session.shutdown(agent)`
|
|
137
174
|
- `agent.session.spawn()` / `Actions.session.spawn(agent)`
|
|
138
175
|
- `agent.events.watch(...)` / `Actions.events.watch(agent, ...)`
|
|
139
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
|
+
|
|
140
188
|
Every action owns its types, for example `Actions.turn.prompt.Options`,
|
|
141
189
|
`Actions.turn.prompt.ReturnType`, and `Actions.events.watch.Watcher`.
|
|
142
190
|
|
|
@@ -150,6 +198,10 @@ unlisten();
|
|
|
150
198
|
watch.off();
|
|
151
199
|
```
|
|
152
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
|
+
|
|
153
205
|
The same watcher can instead be consumed as an ordered async iterable; breaking
|
|
154
206
|
the loop releases that iterator, while `watch.off()` terminates the whole watch.
|
|
155
207
|
|
|
@@ -195,9 +247,16 @@ manager or build step:
|
|
|
195
247
|
|
|
196
248
|
```html
|
|
197
249
|
<script type="module">
|
|
198
|
-
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";
|
|
199
251
|
const agent = await Agent.create({ websocketUrl: "/api/responses" });
|
|
200
|
-
|
|
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
|
+
}
|
|
201
260
|
</script>
|
|
202
261
|
```
|
|
203
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,9 +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),
|
|
14
15
|
setFastMode: (enabled) => session.setFastMode(agent, enabled),
|
|
15
16
|
setThinking: (thinking) => session.setThinking(agent, thinking),
|
|
17
|
+
shutdown: () => session.shutdown(agent),
|
|
16
18
|
spawn: () => session.spawn(agent),
|
|
17
19
|
},
|
|
18
20
|
turn: {
|
package/actions/session.d.mts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
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;
|
|
@@ -18,3 +21,6 @@ export function setThinking(agent: Agent<object>, thinking: Thinking): Promise<v
|
|
|
18
21
|
|
|
19
22
|
/** Enables or disables priority processing for subsequently accepted turns. */
|
|
20
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,10 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
|
+
compact as compactAgent,
|
|
2
3
|
fork as forkAgent,
|
|
3
4
|
setFastMode as setAgentFastMode,
|
|
4
5
|
setThinking as setAgentThinking,
|
|
6
|
+
shutdown as shutdownAgent,
|
|
5
7
|
spawn as spawnAgent,
|
|
6
8
|
} from "../internal.mjs";
|
|
7
9
|
|
|
10
|
+
export function compact(agent) {
|
|
11
|
+
return compactAgent(agent);
|
|
12
|
+
}
|
|
13
|
+
|
|
8
14
|
export function fork(agent, options = {}) {
|
|
9
15
|
return forkAgent(agent, options);
|
|
10
16
|
}
|
|
@@ -20,3 +26,7 @@ export function setThinking(agent, thinking) {
|
|
|
20
26
|
export function setFastMode(agent, enabled) {
|
|
21
27
|
return setAgentFastMode(agent, enabled);
|
|
22
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,18 +17,24 @@ 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;
|
|
17
24
|
}
|
|
18
25
|
|
|
19
|
-
/**
|
|
20
|
-
export function getSnapshot(
|
|
26
|
+
/** Returns a completed result's serializable session snapshot. */
|
|
27
|
+
export function getSnapshot(result: TurnResult): getSnapshot.ReturnType;
|
|
21
28
|
export declare namespace getSnapshot {
|
|
22
29
|
type ReturnType = SessionSnapshot;
|
|
23
30
|
}
|
|
24
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;
|
|
36
|
+
}
|
|
37
|
+
|
|
25
38
|
/** Adds input to an active Turn. */
|
|
26
39
|
export function steer(turn: Turn, options: steer.Options): Promise<void>;
|
|
27
40
|
export declare namespace steer {
|
package/actions/turn.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
cancel as cancelTurn,
|
|
3
3
|
getTurnResult,
|
|
4
4
|
getTurnSnapshot,
|
|
5
|
+
getTurnUsage,
|
|
5
6
|
prompt as promptTurn,
|
|
6
7
|
steer as steerTurn,
|
|
7
8
|
} from "../internal.mjs";
|
|
@@ -14,8 +15,12 @@ export function getResult(turn) {
|
|
|
14
15
|
return getTurnResult(turn);
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
export function getSnapshot(
|
|
18
|
-
return getTurnSnapshot(
|
|
18
|
+
export function getSnapshot(result) {
|
|
19
|
+
return getTurnSnapshot(result);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function getUsage(result) {
|
|
23
|
+
return getTurnUsage(result);
|
|
19
24
|
}
|
|
20
25
|
|
|
21
26
|
export function steer(turn, options) {
|
package/browser/Agent.d.mts
CHANGED
|
@@ -17,9 +17,6 @@ export declare namespace create {
|
|
|
17
17
|
WebSocketImpl?: typeof WebSocket | undefined;
|
|
18
18
|
apiBaseUrl?: string | undefined;
|
|
19
19
|
createWebSocket?(endpoint: string, sessionId: string): WebSocket;
|
|
20
|
-
maxBufferedSendBytes?: number | undefined;
|
|
21
|
-
maxQueuedBytes?: number | undefined;
|
|
22
|
-
maxQueuedMessages?: number | undefined;
|
|
23
20
|
module?: unknown;
|
|
24
21
|
tools?: ToolMap | undefined;
|
|
25
22
|
websocketUrl?: string | undefined;
|
package/browser/Agent.mjs
CHANGED
|
@@ -26,14 +26,23 @@ export function create(options = {}) {
|
|
|
26
26
|
fastMode,
|
|
27
27
|
instructions,
|
|
28
28
|
sessionId,
|
|
29
|
+
workspace,
|
|
29
30
|
resume,
|
|
30
|
-
|
|
31
|
+
WebSocketImpl,
|
|
32
|
+
createWebSocket,
|
|
33
|
+
tools,
|
|
31
34
|
} = options;
|
|
32
35
|
if (mpp !== undefined && apiKey !== undefined) {
|
|
33
36
|
throw new TypeError("apiKey and mpp are mutually exclusive");
|
|
34
37
|
}
|
|
35
38
|
const events = createEventChannel();
|
|
36
|
-
const host = createBrowserHost({
|
|
39
|
+
const host = createBrowserHost({
|
|
40
|
+
WebSocketImpl,
|
|
41
|
+
createWebSocket,
|
|
42
|
+
mpp,
|
|
43
|
+
onEvent: events.emit,
|
|
44
|
+
tools,
|
|
45
|
+
});
|
|
37
46
|
activateHost(host);
|
|
38
47
|
const runtime = defineRuntime({
|
|
39
48
|
key: "browser-wasm",
|
|
@@ -64,6 +73,7 @@ export function create(options = {}) {
|
|
|
64
73
|
fastMode,
|
|
65
74
|
instructions,
|
|
66
75
|
sessionId,
|
|
76
|
+
workspace,
|
|
67
77
|
resume,
|
|
68
78
|
});
|
|
69
79
|
}
|
package/browser/host.mjs
CHANGED
|
@@ -3,26 +3,30 @@ import { createCodeRuntime } from "../runtime/code-runtime.mjs";
|
|
|
3
3
|
const DEFAULT_MAX_QUEUED_MESSAGES = 4_096;
|
|
4
4
|
const DEFAULT_MAX_QUEUED_BYTES = 32 * 1024 * 1024;
|
|
5
5
|
const DEFAULT_MAX_BUFFERED_SEND_BYTES = 16 * 1024 * 1024;
|
|
6
|
+
const WEBSOCKET_OPEN = 1;
|
|
6
7
|
|
|
7
8
|
export function createBrowserHost(options = {}) {
|
|
8
|
-
const WebSocketImpl = options.WebSocketImpl
|
|
9
|
-
|
|
9
|
+
const WebSocketImpl = options.WebSocketImpl ?? globalThis.WebSocket;
|
|
10
|
+
const createWebSocket = options.createWebSocket
|
|
11
|
+
?? (WebSocketImpl && ((endpoint) => new WebSocketImpl(endpoint)));
|
|
12
|
+
if (!options.mpp && !createWebSocket) {
|
|
13
|
+
throw new Error("WebSocket is unavailable in this runtime");
|
|
14
|
+
}
|
|
10
15
|
const connections = new Map();
|
|
11
16
|
const code = createCodeRuntime(options.tools);
|
|
12
17
|
const onEvent = options.onEvent || (() => {});
|
|
13
|
-
const createWebSocket = options.createWebSocket || ((endpoint) => new WebSocketImpl(endpoint));
|
|
14
18
|
const maxQueuedMessages = options.maxQueuedMessages ?? DEFAULT_MAX_QUEUED_MESSAGES;
|
|
15
19
|
const maxQueuedBytes = options.maxQueuedBytes ?? DEFAULT_MAX_QUEUED_BYTES;
|
|
16
20
|
const maxBufferedSendBytes = options.maxBufferedSendBytes ?? DEFAULT_MAX_BUFFERED_SEND_BYTES;
|
|
17
21
|
const encoder = new TextEncoder();
|
|
18
22
|
let nextHandle = 1;
|
|
19
23
|
|
|
20
|
-
function connect(endpoint, _apiKey, sessionId) {
|
|
24
|
+
function connect(endpoint, _apiKey, sessionId, metadata = {}) {
|
|
21
25
|
if (options.mpp) return connectMpp(endpoint);
|
|
22
26
|
return new Promise((resolve, reject) => {
|
|
23
27
|
let settled = false;
|
|
24
28
|
const handle = nextHandle++;
|
|
25
|
-
const socket = createWebSocket(endpoint, sessionId);
|
|
29
|
+
const socket = createWebSocket(endpoint, sessionId, metadata);
|
|
26
30
|
const connection = {
|
|
27
31
|
socket,
|
|
28
32
|
queue: [],
|
|
@@ -97,7 +101,7 @@ export function createBrowserHost(options = {}) {
|
|
|
97
101
|
|
|
98
102
|
function send(handle, message) {
|
|
99
103
|
const connection = connections.get(handle);
|
|
100
|
-
if (!connection || connection.socket.readyState !==
|
|
104
|
+
if (!connection || connection.socket.readyState !== WEBSOCKET_OPEN) {
|
|
101
105
|
return Promise.resolve(JSON.stringify({
|
|
102
106
|
ok: false,
|
|
103
107
|
reconnectable: true,
|
|
@@ -123,7 +127,7 @@ export function createBrowserHost(options = {}) {
|
|
|
123
127
|
} catch (error) {
|
|
124
128
|
return Promise.resolve(JSON.stringify({
|
|
125
129
|
ok: false,
|
|
126
|
-
reconnectable: connection.socket.readyState !==
|
|
130
|
+
reconnectable: connection.socket.readyState !== WEBSOCKET_OPEN,
|
|
127
131
|
error: error instanceof Error ? error.message : String(error),
|
|
128
132
|
}));
|
|
129
133
|
}
|
package/browser/index.d.mts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { Actions } from "../index.mjs";
|
|
2
2
|
export type {
|
|
3
3
|
AgentEvent,
|
|
4
|
+
CostStatus,
|
|
5
|
+
EstimatedUsdCost,
|
|
4
6
|
PromptInput,
|
|
5
7
|
PromptItem,
|
|
6
8
|
ReasoningMode,
|
|
@@ -10,5 +12,7 @@ export type {
|
|
|
10
12
|
ToolContext,
|
|
11
13
|
ToolMap,
|
|
12
14
|
Turn,
|
|
15
|
+
TurnResult,
|
|
16
|
+
TurnUsage,
|
|
13
17
|
} from "../types.mjs";
|
|
14
18
|
export * as Agent from "./Agent.mjs";
|
package/index.d.mts
CHANGED
|
@@ -4,8 +4,10 @@ export type {
|
|
|
4
4
|
AgentActions,
|
|
5
5
|
AgentEvent,
|
|
6
6
|
AgentOptions,
|
|
7
|
+
CostStatus,
|
|
7
8
|
DefaultAgent,
|
|
8
9
|
EventWatcher,
|
|
10
|
+
EstimatedUsdCost,
|
|
9
11
|
ForkOptions,
|
|
10
12
|
PromptInput,
|
|
11
13
|
PromptItem,
|
|
@@ -16,5 +18,7 @@ export type {
|
|
|
16
18
|
ToolContext,
|
|
17
19
|
ToolMap,
|
|
18
20
|
Turn,
|
|
21
|
+
TurnResult,
|
|
22
|
+
TurnUsage,
|
|
19
23
|
WatchEventsOptions,
|
|
20
24
|
} from "./types.mjs";
|