nanocodex 0.2.0 → 0.4.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 +111 -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 +14 -6
- package/browser/Agent.mjs +21 -2
- package/browser/host.d.mts +33 -1
- package/browser/host.mjs +53 -11
- package/browser/index.d.mts +4 -0
- package/index.d.mts +4 -0
- package/internal.mjs +233 -24
- package/node/Agent.d.mts +1 -5
- package/node/Agent.mjs +13 -2
- package/node/host.mjs +39 -12
- package/node/index.d.mts +4 -0
- package/package.json +8 -3
- package/pkg-node/nanocodex.d.ts +69 -38
- package/pkg-node/nanocodex.js +203 -88
- 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 +201 -87
- package/pkg-web/nanocodex_bg.wasm +0 -0
- package/pkg-web/nanocodex_bg.wasm.d.ts +7 -2
- package/runtime/code-runtime.mjs +58 -12
- package/types.d.mts +40 -3
- package/wasm.d.mts +4 -0
- package/scripts/check-package.mjs +0 -38
package/README.md
CHANGED
|
@@ -9,22 +9,37 @@ import { Actions, Agent } from "nanocodex/node";
|
|
|
9
9
|
|
|
10
10
|
const agent = await Agent.create({
|
|
11
11
|
apiKey: process.env.OPENAI_API_KEY,
|
|
12
|
+
model: "gpt-5.6-luna",
|
|
13
|
+
instructions: "You are a Rust coding agent. Preserve unrelated work and run relevant tests.",
|
|
12
14
|
reasoningMode: "pro",
|
|
13
15
|
thinking: "high",
|
|
14
16
|
tools,
|
|
17
|
+
workspace: process.cwd(),
|
|
15
18
|
});
|
|
16
19
|
|
|
17
20
|
const turn = agent.turn.prompt({ input: "Build the thing." });
|
|
18
|
-
|
|
21
|
+
const result = await turn.result();
|
|
22
|
+
turn.dispose();
|
|
23
|
+
console.log(result.finalMessage);
|
|
24
|
+
console.log(result.usage);
|
|
25
|
+
console.log(result.usage.estimated_cost?.usd);
|
|
26
|
+
console.log(result.usage.cost_status);
|
|
19
27
|
|
|
20
28
|
await agent.session.setThinking("high");
|
|
21
29
|
await agent.session.setFastMode(true);
|
|
30
|
+
await agent.session.compact();
|
|
22
31
|
|
|
23
|
-
const branch = await agent.session.fork({ at:
|
|
24
|
-
|
|
32
|
+
const branch = await agent.session.fork({ at: result });
|
|
33
|
+
const branchTurn = branch.turn.prompt({ input: "Try another approach." });
|
|
34
|
+
const branchResult = await branchTurn.result();
|
|
35
|
+
branchTurn.dispose();
|
|
36
|
+
console.log(branchResult.finalMessage);
|
|
25
37
|
|
|
26
38
|
const followOn = Actions.turn.prompt(agent, { input: "Now explain it." });
|
|
27
|
-
console.log(await Actions.turn.getResult(followOn));
|
|
39
|
+
console.log((await Actions.turn.getResult(followOn)).finalMessage);
|
|
40
|
+
followOn.dispose();
|
|
41
|
+
await branch.session.shutdown();
|
|
42
|
+
await agent.session.shutdown();
|
|
28
43
|
```
|
|
29
44
|
|
|
30
45
|
Node and browser applications can instead pay through MPP without an OpenAI
|
|
@@ -77,13 +92,30 @@ const events = agent.events.watch();
|
|
|
77
92
|
const unwatch = events.onEvent((event) => {
|
|
78
93
|
process.stdout.write(`${JSON.stringify(event)}\n`);
|
|
79
94
|
});
|
|
95
|
+
let turn;
|
|
80
96
|
try {
|
|
81
|
-
|
|
97
|
+
turn = agent.turn.prompt({ input: "Build the thing." });
|
|
98
|
+
const result = await turn.result();
|
|
99
|
+
console.error(result.finalMessage);
|
|
82
100
|
} finally {
|
|
83
|
-
|
|
101
|
+
turn?.dispose();
|
|
84
102
|
unwatch();
|
|
85
103
|
events.off();
|
|
86
|
-
|
|
104
|
+
const cleanupErrors = [];
|
|
105
|
+
try {
|
|
106
|
+
await agent.session.shutdown();
|
|
107
|
+
} catch (error) {
|
|
108
|
+
cleanupErrors.push(error);
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
await mpp.close();
|
|
112
|
+
} catch (error) {
|
|
113
|
+
cleanupErrors.push(error);
|
|
114
|
+
}
|
|
115
|
+
if (cleanupErrors.length === 1) throw cleanupErrors[0];
|
|
116
|
+
if (cleanupErrors.length > 1) {
|
|
117
|
+
throw new AggregateError(cleanupErrors, "agent shutdown and MPP settlement both failed");
|
|
118
|
+
}
|
|
87
119
|
}
|
|
88
120
|
```
|
|
89
121
|
|
|
@@ -93,17 +125,19 @@ across agents, and supply mppx `channelStore` for reuse after a process or page
|
|
|
93
125
|
restart. Nanocodex never closes a caller-owned MPP session. `apiKey` and `mpp`
|
|
94
126
|
are mutually exclusive.
|
|
95
127
|
|
|
96
|
-
Completed
|
|
128
|
+
Completed results can be persisted and resumed by a fresh Node or browser
|
|
129
|
+
agent:
|
|
97
130
|
|
|
98
131
|
```js
|
|
99
|
-
const snapshot =
|
|
100
|
-
agent.
|
|
132
|
+
const snapshot = result.snapshot;
|
|
133
|
+
await agent.session.shutdown();
|
|
101
134
|
|
|
102
135
|
const resumed = await Agent.create({
|
|
103
136
|
apiKey: process.env.OPENAI_API_KEY,
|
|
104
137
|
resume: snapshot,
|
|
105
138
|
tools,
|
|
106
139
|
});
|
|
140
|
+
await resumed.session.shutdown();
|
|
107
141
|
```
|
|
108
142
|
|
|
109
143
|
The snapshot contains authoritative typed history but no provider response ID,
|
|
@@ -130,13 +164,28 @@ context, and typed history.
|
|
|
130
164
|
an owned client decorated with matching domain actions:
|
|
131
165
|
|
|
132
166
|
- `agent.turn.prompt(...)` / `Actions.turn.prompt(agent, ...)`
|
|
133
|
-
- `turn.
|
|
167
|
+
- `turn.result()` / `Actions.turn.getResult(turn)`
|
|
168
|
+
- `result.snapshot` / `Actions.turn.getSnapshot(result)`
|
|
169
|
+
- `result.usage` / `Actions.turn.getUsage(result)`
|
|
134
170
|
- `agent.session.fork(...)` / `Actions.session.fork(agent, ...)`
|
|
171
|
+
- `agent.session.compact()` / `Actions.session.compact(agent)`
|
|
135
172
|
- `agent.session.setThinking(...)` / `Actions.session.setThinking(agent, ...)`
|
|
136
173
|
- `agent.session.setFastMode(...)` / `Actions.session.setFastMode(agent, ...)`
|
|
174
|
+
- `agent.session.shutdown()` / `Actions.session.shutdown(agent)`
|
|
137
175
|
- `agent.session.spawn()` / `Actions.session.spawn(agent)`
|
|
138
176
|
- `agent.events.watch(...)` / `Actions.events.watch(agent, ...)`
|
|
139
177
|
|
|
178
|
+
`turn.result()` resolves to a frozen completed `TurnResult`. Its
|
|
179
|
+
`finalMessage` is eager; `usage` and `snapshot` cross the WASM boundary lazily
|
|
180
|
+
once and are then cached. Historical `fork({ at })` accepts this completed
|
|
181
|
+
result, never an unfinished turn or a provider response ID.
|
|
182
|
+
|
|
183
|
+
`turn.dispose()` only releases the JavaScript/WASM handle; like dropping the
|
|
184
|
+
Rust `Turn`, it does not cancel accepted work. Await `turn.cancel()` before
|
|
185
|
+
disposing unfinished work. At an application or session boundary,
|
|
186
|
+
`agent.session.shutdown()` cancels unfinished turns and joins driver, model,
|
|
187
|
+
tool, and transport cleanup.
|
|
188
|
+
|
|
140
189
|
Every action owns its types, for example `Actions.turn.prompt.Options`,
|
|
141
190
|
`Actions.turn.prompt.ReturnType`, and `Actions.events.watch.Watcher`.
|
|
142
191
|
|
|
@@ -150,6 +199,10 @@ unlisten();
|
|
|
150
199
|
watch.off();
|
|
151
200
|
```
|
|
152
201
|
|
|
202
|
+
A throwing callback is reported through the host's `reportError` hook (or
|
|
203
|
+
`console.error` when that hook is unavailable) without interrupting later
|
|
204
|
+
listeners or the owned agent lifecycle.
|
|
205
|
+
|
|
153
206
|
The same watcher can instead be consumed as an ordered async iterable; breaking
|
|
154
207
|
the loop releases that iterator, while `watch.off()` terminates the whole watch.
|
|
155
208
|
|
|
@@ -190,14 +243,59 @@ const agent = await Agent.create({
|
|
|
190
243
|
});
|
|
191
244
|
```
|
|
192
245
|
|
|
246
|
+
Server-side Worker runtimes can await a `fetch()`-based WebSocket upgrade. The
|
|
247
|
+
third callback argument is a discriminated authorization request plus connection
|
|
248
|
+
metadata. With `apiKey`, `authorization` is `"bearer"` and `bearerToken` is
|
|
249
|
+
present. With `hostAuth: true`, it is `"host_managed"`; the host must resolve
|
|
250
|
+
credentials without exposing them to WASM. Do not retain or log bearer tokens.
|
|
251
|
+
Return the socket alone or a descriptor containing response metadata:
|
|
252
|
+
|
|
253
|
+
```js
|
|
254
|
+
import { Agent } from "nanocodex/browser";
|
|
255
|
+
import module from "nanocodex/wasm";
|
|
256
|
+
|
|
257
|
+
const agent = await Agent.create({
|
|
258
|
+
apiKey,
|
|
259
|
+
module,
|
|
260
|
+
async createWebSocket(endpoint, sessionId, request) {
|
|
261
|
+
if (request.authorization !== "bearer") {
|
|
262
|
+
throw new Error("this host requires Nanocodex bearer authorization");
|
|
263
|
+
}
|
|
264
|
+
const response = await fetch(endpoint.replace("wss:", "https:"), {
|
|
265
|
+
headers: {
|
|
266
|
+
Authorization: `Bearer ${request.bearerToken}`,
|
|
267
|
+
Upgrade: "websocket",
|
|
268
|
+
"session-id": sessionId,
|
|
269
|
+
},
|
|
270
|
+
});
|
|
271
|
+
if (!response.webSocket) throw new Error(`upgrade failed: ${response.status}`);
|
|
272
|
+
response.webSocket.accept();
|
|
273
|
+
return { socket: response.webSocket, status: response.status };
|
|
274
|
+
},
|
|
275
|
+
});
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
`hostAuth` is useful when the embedding runtime owns rotating credentials. The
|
|
279
|
+
callback can acquire a fresh token, attempt the upgrade, and refresh-and-retry
|
|
280
|
+
on 401. Bound and reject upgrade work in the callback: until it returns a
|
|
281
|
+
socket, there is no connection handle for Nanocodex to close. `apiKey`,
|
|
282
|
+
`hostAuth`, and `mpp` are mutually exclusive.
|
|
283
|
+
|
|
193
284
|
After publication, a browser can load the same entrypoint without a package
|
|
194
285
|
manager or build step:
|
|
195
286
|
|
|
196
287
|
```html
|
|
197
288
|
<script type="module">
|
|
198
|
-
import { Agent } from "https://cdn.jsdelivr.net/npm/nanocodex@0.
|
|
289
|
+
import { Agent } from "https://cdn.jsdelivr.net/npm/nanocodex@0.4.0/browser/index.mjs";
|
|
199
290
|
const agent = await Agent.create({ websocketUrl: "/api/responses" });
|
|
200
|
-
|
|
291
|
+
const turn = agent.turn.prompt({ input: "Hello." });
|
|
292
|
+
try {
|
|
293
|
+
const result = await turn.result();
|
|
294
|
+
console.log(result.finalMessage);
|
|
295
|
+
} finally {
|
|
296
|
+
turn.dispose();
|
|
297
|
+
await agent.session.shutdown();
|
|
298
|
+
}
|
|
201
299
|
</script>
|
|
202
300
|
```
|
|
203
301
|
|
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
|
@@ -4,6 +4,10 @@ import type {
|
|
|
4
4
|
MppSession,
|
|
5
5
|
ToolMap,
|
|
6
6
|
} from "../types.mjs";
|
|
7
|
+
import type {
|
|
8
|
+
BrowserWebSocketConnection,
|
|
9
|
+
BrowserWebSocketRequest,
|
|
10
|
+
} from "./host.mjs";
|
|
7
11
|
|
|
8
12
|
export type Agent = DefaultAgent;
|
|
9
13
|
|
|
@@ -11,17 +15,21 @@ export type Agent = DefaultAgent;
|
|
|
11
15
|
export function create(options?: create.Options): Promise<create.ReturnType>;
|
|
12
16
|
export declare namespace create {
|
|
13
17
|
type Options = AgentOptions & (
|
|
14
|
-
| { apiKey?: string | undefined; mpp?: never }
|
|
15
|
-
| { apiKey?: never; mpp
|
|
18
|
+
| { apiKey?: string | undefined; hostAuth?: never; mpp?: never }
|
|
19
|
+
| { apiKey?: never; hostAuth?: true; mpp?: never }
|
|
20
|
+
| { apiKey?: never; hostAuth?: never; mpp: MppSession }
|
|
16
21
|
) & {
|
|
17
22
|
WebSocketImpl?: typeof WebSocket | undefined;
|
|
18
23
|
apiBaseUrl?: string | undefined;
|
|
19
|
-
createWebSocket?(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
createWebSocket?(
|
|
25
|
+
endpoint: string,
|
|
26
|
+
sessionId: string,
|
|
27
|
+
request: BrowserWebSocketRequest,
|
|
28
|
+
): WebSocket | BrowserWebSocketConnection | Promise<WebSocket | BrowserWebSocketConnection>;
|
|
23
29
|
module?: unknown;
|
|
24
30
|
tools?: ToolMap | undefined;
|
|
31
|
+
/** Direct dispatch is CSP-safe; Code Mode requires dynamic JavaScript evaluation. */
|
|
32
|
+
toolMode?: "code" | "direct" | undefined;
|
|
25
33
|
websocketUrl?: string | undefined;
|
|
26
34
|
};
|
|
27
35
|
type ReturnType = Agent;
|
package/browser/Agent.mjs
CHANGED
|
@@ -17,23 +17,40 @@ let initialized;
|
|
|
17
17
|
export function create(options = {}) {
|
|
18
18
|
const {
|
|
19
19
|
apiKey,
|
|
20
|
+
hostAuth,
|
|
20
21
|
mpp,
|
|
21
22
|
websocketUrl,
|
|
22
23
|
apiBaseUrl,
|
|
23
24
|
module,
|
|
25
|
+
model,
|
|
24
26
|
thinking,
|
|
25
27
|
reasoningMode,
|
|
26
28
|
fastMode,
|
|
27
29
|
instructions,
|
|
28
30
|
sessionId,
|
|
31
|
+
workspace,
|
|
29
32
|
resume,
|
|
30
|
-
|
|
33
|
+
WebSocketImpl,
|
|
34
|
+
createWebSocket,
|
|
35
|
+
tools,
|
|
36
|
+
toolMode,
|
|
31
37
|
} = options;
|
|
32
38
|
if (mpp !== undefined && apiKey !== undefined) {
|
|
33
39
|
throw new TypeError("apiKey and mpp are mutually exclusive");
|
|
34
40
|
}
|
|
41
|
+
if (hostAuth && (apiKey !== undefined || mpp !== undefined)) {
|
|
42
|
+
throw new TypeError("hostAuth is mutually exclusive with apiKey and mpp");
|
|
43
|
+
}
|
|
35
44
|
const events = createEventChannel();
|
|
36
|
-
const host = createBrowserHost({
|
|
45
|
+
const host = createBrowserHost({
|
|
46
|
+
WebSocketImpl,
|
|
47
|
+
createWebSocket,
|
|
48
|
+
hostAuth: hostAuth === true || (apiKey === undefined && mpp === undefined),
|
|
49
|
+
mpp,
|
|
50
|
+
onEvent: events.emit,
|
|
51
|
+
tools,
|
|
52
|
+
toolMode,
|
|
53
|
+
});
|
|
37
54
|
activateHost(host);
|
|
38
55
|
const runtime = defineRuntime({
|
|
39
56
|
key: "browser-wasm",
|
|
@@ -59,11 +76,13 @@ export function create(options = {}) {
|
|
|
59
76
|
decorate: (agent) => agent.extend(agentActions()),
|
|
60
77
|
});
|
|
61
78
|
return createAgentClient(runtime, {
|
|
79
|
+
model,
|
|
62
80
|
thinking,
|
|
63
81
|
reasoningMode,
|
|
64
82
|
fastMode,
|
|
65
83
|
instructions,
|
|
66
84
|
sessionId,
|
|
85
|
+
workspace,
|
|
67
86
|
resume,
|
|
68
87
|
});
|
|
69
88
|
}
|
package/browser/host.d.mts
CHANGED
|
@@ -9,9 +9,41 @@ export type BrowserTool = {
|
|
|
9
9
|
|
|
10
10
|
export type BrowserToolMap = Record<string, BrowserTool>;
|
|
11
11
|
|
|
12
|
+
type BrowserWebSocketMetadata = {
|
|
13
|
+
accountId?: string | undefined;
|
|
14
|
+
fedramp?: boolean | undefined;
|
|
15
|
+
turnState?: string | undefined;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type BrowserWebSocketRequest = BrowserWebSocketMetadata & (
|
|
19
|
+
| {
|
|
20
|
+
authorization: "bearer";
|
|
21
|
+
/** Resolved credential for this handshake. Do not retain or log it. */
|
|
22
|
+
bearerToken: string;
|
|
23
|
+
}
|
|
24
|
+
| {
|
|
25
|
+
authorization: "host_managed";
|
|
26
|
+
bearerToken?: never;
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
export type BrowserWebSocketConnection = {
|
|
31
|
+
socket: WebSocket;
|
|
32
|
+
status?: number | undefined;
|
|
33
|
+
requestId?: string | undefined;
|
|
34
|
+
serverModel?: string | undefined;
|
|
35
|
+
reasoningIncluded?: boolean | undefined;
|
|
36
|
+
turnState?: string | undefined;
|
|
37
|
+
};
|
|
38
|
+
|
|
12
39
|
export function createBrowserHost(options?: {
|
|
13
40
|
WebSocketImpl?: typeof WebSocket;
|
|
14
|
-
|
|
41
|
+
hostAuth?: boolean;
|
|
42
|
+
createWebSocket?: (
|
|
43
|
+
endpoint: string,
|
|
44
|
+
sessionId: string,
|
|
45
|
+
request: BrowserWebSocketRequest,
|
|
46
|
+
) => WebSocket | BrowserWebSocketConnection | Promise<WebSocket | BrowserWebSocketConnection>;
|
|
15
47
|
onEvent?: (eventJson: string) => void;
|
|
16
48
|
tools?: BrowserToolMap;
|
|
17
49
|
maxQueuedMessages?: number;
|