nanocodex 0.4.0 → 0.6.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 +944 -78
- package/actions/events.mjs +14 -25
- package/actions/index.d.mts +1 -0
- package/actions/index.mjs +11 -1
- package/actions/session.d.mts +29 -1
- package/actions/session.mjs +22 -0
- package/actions/turn.d.mts +15 -6
- package/actions/turn.mjs +10 -0
- package/actions/voice.d.mts +26 -0
- package/actions/voice.mjs +54 -0
- package/browser/Agent.d.mts +41 -24
- package/browser/Agent.mjs +7 -84
- package/browser/ChatGptSubscription.d.mts +7 -0
- package/browser/ChatGptSubscription.mjs +19 -0
- package/browser/InlineAgent.mjs +267 -0
- package/browser/Transport.d.mts +80 -0
- package/browser/Transport.mjs +63 -0
- package/browser/Voice.d.mts +86 -0
- package/browser/Voice.mjs +316 -0
- package/browser/VoiceSession.mjs +763 -0
- package/browser/WorkerAgent.d.mts +65 -0
- package/browser/WorkerAgent.mjs +1467 -0
- package/browser/agent.worker.mjs +3 -0
- package/browser/config.d.mts +36 -0
- package/browser/config.mjs +439 -0
- package/browser/engine.mjs +13 -0
- package/browser/harness.mjs +55 -0
- package/browser/host.d.mts +33 -5
- package/browser/host.mjs +320 -26
- package/browser/hostManagedWebSocket.d.mts +14 -0
- package/browser/hostManagedWebSocket.mjs +110 -0
- package/browser/index.d.mts +64 -1
- package/browser/index.mjs +22 -1
- package/browser/indexeddb-durability-store.mjs +210 -0
- package/browser/workspace.d.mts +16 -0
- package/browser/workspace.mjs +107 -0
- package/cloud/Client.d.mts +83 -0
- package/cloud/Client.mjs +231 -0
- package/cloud/Decorator.d.mts +31 -0
- package/cloud/Decorator.mjs +37 -0
- package/cloud/Dialog.d.mts +113 -0
- package/cloud/Dialog.mjs +366 -0
- package/cloud/Errors.d.mts +22 -0
- package/cloud/Errors.mjs +39 -0
- package/cloud/Principal.d.mts +26 -0
- package/cloud/Principal.mjs +88 -0
- package/cloud/RemoteProvider.mjs +88 -0
- package/cloud/Transport.d.mts +47 -0
- package/cloud/Transport.mjs +454 -0
- package/cloud/actions/account.d.mts +9 -0
- package/cloud/actions/account.mjs +19 -0
- package/cloud/actions/agent.d.mts +18 -0
- package/cloud/actions/agent.mjs +429 -0
- package/cloud/actions/connection.d.mts +133 -0
- package/cloud/actions/connection.mjs +580 -0
- package/cloud/actions/grant.d.mts +10 -0
- package/cloud/actions/grant.mjs +12 -0
- package/cloud/actions/index.d.mts +7 -0
- package/cloud/actions/index.mjs +7 -0
- package/cloud/actions/machineUsd.d.mts +23 -0
- package/cloud/actions/machineUsd.mjs +37 -0
- package/cloud/actions/model.d.mts +12 -0
- package/cloud/actions/model.mjs +50 -0
- package/cloud/actions/mpp.d.mts +28 -0
- package/cloud/actions/mpp.mjs +39 -0
- package/cloud/index.d.mts +30 -0
- package/cloud/index.mjs +9 -0
- package/cloud/internal.mjs +533 -0
- package/cloud/mercator.mjs +108 -0
- package/cloud/server/HostPrincipal.d.mts +34 -0
- package/cloud/server/HostPrincipal.mjs +202 -0
- package/cloud/server/index.d.mts +1 -0
- package/cloud/server/index.mjs +1 -0
- package/cloud/types.d.mts +212 -0
- package/cloudflare/Agent.d.mts +136 -0
- package/cloudflare/Agent.mjs +784 -0
- package/cloudflare/egress-subject.mjs +19 -0
- package/cloudflare/egress.d.mts +41 -0
- package/cloudflare/egress.mjs +119 -0
- package/cloudflare/event-socket.mjs +316 -0
- package/cloudflare/index.d.mts +7 -0
- package/cloudflare/index.mjs +6 -0
- package/host/Agent.d.mts +55 -0
- package/host/Agent.mjs +1 -0
- package/host/index.d.mts +71 -0
- package/host/index.mjs +10 -0
- package/index.d.mts +46 -0
- package/index.mjs +11 -0
- package/internal.mjs +673 -61
- package/managed/Agent.d.mts +459 -0
- package/managed/Agent.mjs +1824 -0
- package/managed/ManagedError.d.mts +9 -0
- package/managed/ManagedError.mjs +8 -0
- package/managed/README.md +244 -0
- package/managed/Voice.mjs +209 -0
- package/managed/index.d.mts +22 -0
- package/managed/index.mjs +2 -0
- package/managed/internal.mjs +119 -0
- package/node/Agent.d.mts +35 -8
- package/node/Agent.mjs +116 -25
- package/node/ChatGptSubscription.d.mts +9 -0
- package/node/ChatGptSubscription.mjs +17 -0
- package/node/Transport.d.mts +41 -0
- package/node/Transport.mjs +46 -0
- package/node/host.mjs +99 -17
- package/node/index.d.mts +45 -1
- package/node/index.mjs +16 -1
- package/node/workspace.d.mts +10 -0
- package/node/workspace.mjs +198 -0
- package/package.json +145 -11
- package/pkg-node/nanocodex.d.ts +523 -11
- package/pkg-node/nanocodex.js +2038 -179
- package/pkg-node/nanocodex_bg.wasm.d.ts +100 -29
- package/pkg-web/.nanocodex-bindgen-stamp +6 -0
- package/pkg-web/nanocodex-build.json +1 -0
- package/pkg-web/nanocodex.d.ts +623 -40
- package/pkg-web/nanocodex.js +2031 -178
- package/pkg-web/nanocodex_bg.js +2667 -0
- package/pkg-web/nanocodex_bg.wasm +0 -0
- package/pkg-web/nanocodex_bg.wasm.d.ts +100 -29
- package/pkg-web/nanocodex_worker.js +9 -0
- package/runtime/chatgpt-subscription.mjs +212 -0
- package/runtime/cloudflare-durability-store.d.mts +26 -0
- package/runtime/cloudflare-durability-store.mjs +14 -0
- package/runtime/code-evaluator.worker.mjs +137 -0
- package/runtime/code-runtime.mjs +1 -243
- package/runtime/durability-store.d.mts +85 -0
- package/runtime/durability-store.mjs +752 -0
- package/runtime/durability.mjs +174 -0
- package/runtime/managed-transport.mjs +461 -0
- package/runtime/mcp-runtime.mjs +534 -0
- package/runtime/postgres-durability-store.d.mts +64 -0
- package/runtime/postgres-durability-store.mjs +581 -0
- package/runtime/quickjs-evaluator.d.mts +17 -0
- package/runtime/quickjs-evaluator.mjs +236 -0
- package/runtime/response-controls.mjs +42 -0
- package/runtime/response-lanes.mjs +72 -0
- package/runtime/responses-transport.mjs +22 -0
- package/runtime/subagents.d.mts +107 -0
- package/runtime/subagents.mjs +54 -0
- package/runtime/subscription-store.d.mts +8 -0
- package/runtime/subscription-store.mjs +42 -0
- package/runtime/tempo-provider.d.mts +125 -0
- package/runtime/tempo-provider.mjs +264 -0
- package/runtime/tool-configuration.mjs +1 -0
- package/runtime/tool-router.mjs +1 -0
- package/runtime/utf8.mjs +1 -0
- package/runtime/worker-evaluator.mjs +162 -0
- package/runtime/workspace.d.mts +1 -0
- package/runtime/workspace.mjs +1 -0
- package/tools/Tools.d.mts +56 -0
- package/tools/Tools.mjs +136 -0
- package/tools/artifact.d.mts +1 -0
- package/tools/artifact.mjs +1 -0
- package/tools/attachment.mjs +1 -0
- package/tools/bash.d.mts +1 -0
- package/tools/bash.mjs +1 -0
- package/tools/browser/accountInfo.mjs +795 -0
- package/tools/browser/browserBuffer.mjs +18 -0
- package/tools/browser/browserCompiler.mjs +155 -0
- package/tools/browser/browserEgress.mjs +161 -0
- package/tools/browser/browserPython.mjs +133 -0
- package/tools/browser/browserShell.mjs +1075 -0
- package/tools/browser/browserSprintf.mjs +4 -0
- package/tools/browser/browserSsh.mjs +201 -0
- package/tools/browser/browserZlib.mjs +136 -0
- package/tools/browser/compiler.worker.mjs +160 -0
- package/tools/browser/devTunnelsSshBrowser.mjs +13 -0
- package/tools/browser/index.d.mts +209 -0
- package/tools/browser/index.mjs +174 -0
- package/tools/browser/opfsGit.mjs +248 -0
- package/tools/browser/python.worker.mjs +114 -0
- package/tools/browser/threadGit.mjs +197 -0
- package/tools/browser/unsupportedNodeRsa.mjs +5 -0
- package/tools/browser/workspace.mjs +83 -0
- package/tools/dataset.d.mts +1 -0
- package/tools/dataset.mjs +1 -0
- package/tools/datasetContract.mjs +1 -0
- package/tools/datasetEngine.mjs +1 -0
- package/tools/hostedCatalog.d.mts +1 -0
- package/tools/hostedCatalog.mjs +1 -0
- package/tools/index.d.mts +49 -0
- package/tools/index.mjs +19 -0
- package/tools/namedTool.mjs +1 -0
- package/tools/repository-workspace.d.mts +1 -0
- package/tools/repository-workspace.mjs +1 -0
- package/tools/ssh.d.mts +1 -0
- package/tools/ssh.mjs +1 -0
- package/tools/standard.mjs +1 -0
- package/tools/standardDescriptions.mjs +1 -0
- package/types.d.mts +431 -16
- package/worker/ChatGptSubscription.d.mts +9 -0
- package/worker/ChatGptSubscription.mjs +29 -0
- package/worker/index.d.mts +18 -0
- package/worker/index.mjs +5 -0
- package/pkg-node/nanocodex_bg.wasm +0 -0
package/browser/host.mjs
CHANGED
|
@@ -1,31 +1,161 @@
|
|
|
1
|
-
import { createCodeRuntime } from "../runtime/code-runtime.mjs";
|
|
1
|
+
import { createCodeRuntime, toolResult } from "../runtime/code-runtime.mjs";
|
|
2
|
+
import {
|
|
3
|
+
toolRouterBrand,
|
|
4
|
+
toolRouterRuntime,
|
|
5
|
+
toolRuntimeLifecycle,
|
|
6
|
+
} from "../runtime/tool-router.mjs";
|
|
7
|
+
import { utf8ByteLength } from "../runtime/utf8.mjs";
|
|
8
|
+
import { createWorkerEvaluator } from "../runtime/worker-evaluator.mjs";
|
|
9
|
+
import { openHostManagedWebSocket } from "./hostManagedWebSocket.mjs";
|
|
2
10
|
|
|
3
11
|
const DEFAULT_MAX_QUEUED_MESSAGES = 4_096;
|
|
4
12
|
const DEFAULT_MAX_QUEUED_BYTES = 32 * 1024 * 1024;
|
|
5
13
|
const DEFAULT_MAX_BUFFERED_SEND_BYTES = 16 * 1024 * 1024;
|
|
14
|
+
const MPP_CLIENT_PROTOCOL_ERROR_CLOSE_CODE = 3008;
|
|
6
15
|
const WEBSOCKET_OPEN = 1;
|
|
7
16
|
|
|
8
17
|
export function createBrowserHost(options = {}) {
|
|
18
|
+
const toolMode = options.toolMode ?? "code";
|
|
19
|
+
if (toolMode !== "code" && toolMode !== "direct") {
|
|
20
|
+
throw new TypeError("toolMode must be code or direct");
|
|
21
|
+
}
|
|
22
|
+
const toolsRouter = options.tools?.[toolRouterBrand]
|
|
23
|
+
? options.tools[toolRouterRuntime]
|
|
24
|
+
: undefined;
|
|
25
|
+
const toolsMcp = toolsRouter?.hasSourceKind("mcp") === true;
|
|
26
|
+
if (toolsRouter?.hasSource("workspace") && options.filesystem) {
|
|
27
|
+
throw new TypeError("workspace is already configured in Tools");
|
|
28
|
+
}
|
|
29
|
+
if (toolsMcp && options.mcp) {
|
|
30
|
+
throw new TypeError("MCP is already configured in Tools");
|
|
31
|
+
}
|
|
32
|
+
if ((toolsMcp || options.mcp) && toolMode !== "code") {
|
|
33
|
+
throw new TypeError("remote MCP requires Code Mode");
|
|
34
|
+
}
|
|
35
|
+
const toolsLifecycle = options.tools?.[toolRuntimeLifecycle];
|
|
36
|
+
toolsLifecycle?.available();
|
|
9
37
|
const WebSocketImpl = options.WebSocketImpl ?? globalThis.WebSocket;
|
|
10
38
|
const createWebSocket = options.createWebSocket
|
|
39
|
+
?? (options.hostManagedProtocol && ((endpoint, sessionId, request) =>
|
|
40
|
+
openHostManagedWebSocket(endpoint, sessionId, {
|
|
41
|
+
WebSocketImpl,
|
|
42
|
+
threadId: request.threadId,
|
|
43
|
+
})))
|
|
11
44
|
?? (WebSocketImpl && ((endpoint) => new WebSocketImpl(endpoint)));
|
|
12
45
|
if (!options.mpp && !createWebSocket) {
|
|
13
46
|
throw new Error("WebSocket is unavailable in this runtime");
|
|
14
47
|
}
|
|
15
48
|
const connections = new Map();
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
49
|
+
const openingAttempts = new Set();
|
|
50
|
+
const connectingConnections = new Set();
|
|
51
|
+
const codeEvaluator = options.codeEvaluator
|
|
52
|
+
?? (typeof globalThis.Worker === "function"
|
|
53
|
+
? createWorkerEvaluator()
|
|
54
|
+
: () => Promise.reject(new Error(
|
|
55
|
+
"browser Code Mode requires a child Worker or an explicit codeEvaluator",
|
|
56
|
+
)));
|
|
57
|
+
const code = createCodeRuntime(options.tools, {
|
|
58
|
+
evaluate: codeEvaluator,
|
|
59
|
+
subagentSessions: options.subagentSessions,
|
|
60
|
+
});
|
|
61
|
+
const toolProviders = options.toolProviders ?? [];
|
|
62
|
+
if (!Array.isArray(toolProviders)) {
|
|
63
|
+
throw new TypeError("toolProviders must be an array");
|
|
64
|
+
}
|
|
65
|
+
for (const [index, provider] of toolProviders.entries()) {
|
|
66
|
+
const sourceOptions = {
|
|
67
|
+
id: provider.sourceId ?? `attached:${String(index).padStart(8, "0")}`,
|
|
68
|
+
kind: "attached",
|
|
69
|
+
mode: "attached-over-cloud",
|
|
70
|
+
deferred: true,
|
|
71
|
+
};
|
|
72
|
+
const sourceId = code.addProvider(provider, sourceOptions);
|
|
73
|
+
provider.setCatalogValidator?.((definitions) =>
|
|
74
|
+
code.validateProviderDefinitions(sourceId, definitions, sourceOptions));
|
|
75
|
+
}
|
|
76
|
+
const toolProvidersReady = Promise.all(
|
|
77
|
+
toolProviders.map((provider) => provider.settled?.()),
|
|
78
|
+
);
|
|
79
|
+
if (options.filesystem && options.filesystemTools === false) {
|
|
80
|
+
code.addTools({
|
|
81
|
+
apply_patch: {
|
|
82
|
+
description: "Apply a Rust-verified patch to the browser workspace.",
|
|
83
|
+
parameters: { type: "object", additionalProperties: false },
|
|
84
|
+
async handler(input, context) {
|
|
85
|
+
if (typeof options.applyPatch !== "function") {
|
|
86
|
+
throw new Error("the Rust browser apply_patch planner is unavailable");
|
|
87
|
+
}
|
|
88
|
+
const summary = await options.applyPatch(input, context.sessionId);
|
|
89
|
+
return toolResult(summary, {});
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
});
|
|
20
93
|
}
|
|
94
|
+
const filesystemReady = options.filesystem && options.filesystemTools !== false
|
|
95
|
+
? import("../runtime/workspace.mjs")
|
|
96
|
+
.then(({ tools }) => code.addTools(tools(options.filesystem)))
|
|
97
|
+
: undefined;
|
|
98
|
+
const mcp = options.mcp
|
|
99
|
+
? import("../runtime/mcp-runtime.mjs").then(({ createMcpRuntime }) =>
|
|
100
|
+
createMcpRuntime(options.mcp, { clientName: "nanocodex-browser" }))
|
|
101
|
+
: undefined;
|
|
102
|
+
const mcpInstalled = mcp?.then(async (provider) => {
|
|
103
|
+
if (disposal) return provider.close();
|
|
104
|
+
try { code.addProvider(provider, { id: "mcp", kind: "mcp" }); }
|
|
105
|
+
catch (error) {
|
|
106
|
+
try { await provider.close(); }
|
|
107
|
+
catch (cleanupError) {
|
|
108
|
+
throw new AggregateError([error, cleanupError], "MCP installation and cleanup failed");
|
|
109
|
+
}
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
return provider;
|
|
113
|
+
});
|
|
21
114
|
const onEvent = options.onEvent || (() => {});
|
|
22
115
|
const maxQueuedMessages = options.maxQueuedMessages ?? DEFAULT_MAX_QUEUED_MESSAGES;
|
|
23
116
|
const maxQueuedBytes = options.maxQueuedBytes ?? DEFAULT_MAX_QUEUED_BYTES;
|
|
24
117
|
const maxBufferedSendBytes = options.maxBufferedSendBytes ?? DEFAULT_MAX_BUFFERED_SEND_BYTES;
|
|
25
|
-
const encoder = new TextEncoder();
|
|
26
118
|
let nextHandle = 1;
|
|
119
|
+
let references = 0;
|
|
120
|
+
let disposal;
|
|
121
|
+
let disposalError;
|
|
122
|
+
let preconnected;
|
|
123
|
+
|
|
124
|
+
function preconnect(endpoint, sessionId) {
|
|
125
|
+
if (disposal) return Promise.reject(new Error("Nanocodex host is already disposed"));
|
|
126
|
+
if (preconnected?.endpoint === endpoint && preconnected.sessionId === sessionId) {
|
|
127
|
+
return preconnected.ownership.promise.then(() => undefined);
|
|
128
|
+
}
|
|
129
|
+
void closePreconnected().catch(() => {});
|
|
130
|
+
const ownership = openOwned(() => createWebSocket(endpoint, sessionId, {
|
|
131
|
+
authorization: "preconnect",
|
|
132
|
+
}));
|
|
133
|
+
const entry = { endpoint, sessionId, ownership };
|
|
134
|
+
preconnected = entry;
|
|
135
|
+
void ownership.promise.catch(() => {
|
|
136
|
+
if (preconnected === entry) preconnected = undefined;
|
|
137
|
+
});
|
|
138
|
+
return ownership.promise.then(() => undefined);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function takePreconnected(endpoint, sessionId) {
|
|
142
|
+
if (preconnected?.endpoint !== endpoint || preconnected.sessionId !== sessionId) {
|
|
143
|
+
return undefined;
|
|
144
|
+
}
|
|
145
|
+
const ownership = preconnected.ownership;
|
|
146
|
+
preconnected = undefined;
|
|
147
|
+
return ownership;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function closePreconnected(error = new Error("WebSocket preconnection was closed")) {
|
|
151
|
+
const entry = preconnected;
|
|
152
|
+
preconnected = undefined;
|
|
153
|
+
if (!entry) return Promise.resolve();
|
|
154
|
+
return entry.ownership.dispose(error);
|
|
155
|
+
}
|
|
27
156
|
|
|
28
157
|
async function connect(endpoint, apiKey, sessionId, metadata = {}) {
|
|
158
|
+
if (disposal) throw new Error("Nanocodex host is already disposed");
|
|
29
159
|
if (options.mpp) return connectMpp(endpoint);
|
|
30
160
|
const authorization = options.hostAuth
|
|
31
161
|
? { authorization: "host_managed" }
|
|
@@ -34,7 +164,13 @@ export function createBrowserHost(options = {}) {
|
|
|
34
164
|
delete request.authorization;
|
|
35
165
|
delete request.bearerToken;
|
|
36
166
|
Object.assign(request, authorization);
|
|
37
|
-
const
|
|
167
|
+
const threadId = metadata.threadId ?? sessionId;
|
|
168
|
+
let ownership = threadId === sessionId ? takePreconnected(endpoint, sessionId) : undefined;
|
|
169
|
+
if (ownership === undefined) {
|
|
170
|
+
if (preconnected !== undefined) await closePreconnected();
|
|
171
|
+
ownership = openOwned(() => createWebSocket(endpoint, sessionId, request));
|
|
172
|
+
}
|
|
173
|
+
const opened = await ownership.promise;
|
|
38
174
|
const { socket, ...handshake } = normalizeWebSocketConnection(opened);
|
|
39
175
|
return new Promise((resolve, reject) => {
|
|
40
176
|
let settled = false;
|
|
@@ -46,9 +182,26 @@ export function createBrowserHost(options = {}) {
|
|
|
46
182
|
intentionallyClosed: false,
|
|
47
183
|
overflowed: false,
|
|
48
184
|
};
|
|
185
|
+
const rejectConnection = (error) => {
|
|
186
|
+
if (settled) return;
|
|
187
|
+
settled = true;
|
|
188
|
+
connectingConnections.delete(connection);
|
|
189
|
+
reject(error);
|
|
190
|
+
};
|
|
191
|
+
connection.reject = rejectConnection;
|
|
192
|
+
ownership.transfer();
|
|
193
|
+
connectingConnections.add(connection);
|
|
49
194
|
const resolveOpen = () => {
|
|
50
195
|
if (settled) return;
|
|
196
|
+
if (disposal) {
|
|
197
|
+
connection.intentionallyClosed = true;
|
|
198
|
+
settled = true;
|
|
199
|
+
reject(disposalError);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
51
202
|
settled = true;
|
|
203
|
+
connectingConnections.delete(connection);
|
|
204
|
+
delete connection.reject;
|
|
52
205
|
const handle = nextHandle++;
|
|
53
206
|
connections.set(handle, connection);
|
|
54
207
|
resolve(JSON.stringify({
|
|
@@ -68,33 +221,32 @@ export function createBrowserHost(options = {}) {
|
|
|
68
221
|
});
|
|
69
222
|
socket.addEventListener("close", (event) => {
|
|
70
223
|
if (!settled) {
|
|
71
|
-
|
|
72
|
-
reject(new Error(`WebSocket closed during connection with code ${event.code}`));
|
|
224
|
+
rejectConnection(new Error(`WebSocket closed during connection with code ${event.code}`));
|
|
73
225
|
} else if (!connection.intentionallyClosed && !connection.overflowed) {
|
|
74
226
|
enqueue(connection, { kind: "closed", detail: `with code ${event.code}` });
|
|
75
227
|
}
|
|
76
228
|
});
|
|
77
229
|
socket.addEventListener("error", () => {
|
|
78
230
|
if (!settled) {
|
|
79
|
-
|
|
80
|
-
reject(new Error("WebSocket connection failed"));
|
|
231
|
+
rejectConnection(new Error("WebSocket connection failed"));
|
|
81
232
|
} else {
|
|
82
233
|
enqueue(connection, { kind: "error", detail: "WebSocket connection failed" });
|
|
83
234
|
}
|
|
84
235
|
});
|
|
85
236
|
if (socket.readyState === WEBSOCKET_OPEN) resolveOpen();
|
|
86
237
|
else if (socket.readyState > WEBSOCKET_OPEN) {
|
|
87
|
-
|
|
88
|
-
reject(new Error("WebSocket closed during connection"));
|
|
238
|
+
rejectConnection(new Error("WebSocket closed during connection"));
|
|
89
239
|
}
|
|
90
240
|
});
|
|
91
241
|
}
|
|
92
242
|
|
|
93
243
|
async function connectMpp(endpoint) {
|
|
244
|
+
if (disposal) throw new Error("Nanocodex host is already disposed");
|
|
94
245
|
if (typeof options.mpp.ws !== "function") {
|
|
95
246
|
throw new TypeError("mpp must provide ws(endpoint)");
|
|
96
247
|
}
|
|
97
|
-
const
|
|
248
|
+
const ownership = openOwned(() => options.mpp.ws(endpoint));
|
|
249
|
+
const socket = await ownership.promise;
|
|
98
250
|
if (!socket || typeof socket.addEventListener !== "function") {
|
|
99
251
|
throw new TypeError("mpp.ws(endpoint) must return a WebSocket");
|
|
100
252
|
}
|
|
@@ -108,6 +260,7 @@ export function createBrowserHost(options = {}) {
|
|
|
108
260
|
overflowed: false,
|
|
109
261
|
managed: true,
|
|
110
262
|
};
|
|
263
|
+
ownership.transfer();
|
|
111
264
|
connections.set(handle, connection);
|
|
112
265
|
socket.addEventListener("message", (event) => {
|
|
113
266
|
enqueue(connection, typeof event.data === "string"
|
|
@@ -116,7 +269,15 @@ export function createBrowserHost(options = {}) {
|
|
|
116
269
|
});
|
|
117
270
|
socket.addEventListener("close", (event) => {
|
|
118
271
|
if (!connection.intentionallyClosed && !connection.overflowed) {
|
|
119
|
-
|
|
272
|
+
const code = event.code ?? 1000;
|
|
273
|
+
const suffix = event.reason ? `: ${event.reason}` : "";
|
|
274
|
+
enqueue(connection, code === MPP_CLIENT_PROTOCOL_ERROR_CLOSE_CODE
|
|
275
|
+
? {
|
|
276
|
+
kind: "error",
|
|
277
|
+
detail: `MPP WebSocket payment flow failed with code ${code}${suffix}`,
|
|
278
|
+
reconnectable: false,
|
|
279
|
+
}
|
|
280
|
+
: { kind: "closed", detail: `with code ${code}${suffix}` });
|
|
120
281
|
}
|
|
121
282
|
});
|
|
122
283
|
socket.addEventListener("error", () => {
|
|
@@ -139,7 +300,7 @@ export function createBrowserHost(options = {}) {
|
|
|
139
300
|
connection.socket.send(JSON.stringify({ mpp: "message", data: message }));
|
|
140
301
|
return Promise.resolve(JSON.stringify({ ok: true }));
|
|
141
302
|
}
|
|
142
|
-
const frameBytes =
|
|
303
|
+
const frameBytes = utf8ByteLength(message);
|
|
143
304
|
if (frameBytes > maxBufferedSendBytes
|
|
144
305
|
|| connection.socket.bufferedAmount + frameBytes > maxBufferedSendBytes) {
|
|
145
306
|
return Promise.resolve(JSON.stringify({
|
|
@@ -159,7 +320,7 @@ export function createBrowserHost(options = {}) {
|
|
|
159
320
|
}
|
|
160
321
|
}
|
|
161
322
|
|
|
162
|
-
function next(handle
|
|
323
|
+
function next(handle) {
|
|
163
324
|
const connection = connections.get(handle);
|
|
164
325
|
if (!connection) {
|
|
165
326
|
return Promise.resolve(JSON.stringify({ kind: "closed", detail: "before the next frame" }));
|
|
@@ -171,12 +332,7 @@ export function createBrowserHost(options = {}) {
|
|
|
171
332
|
}
|
|
172
333
|
if (connection.waiter) return Promise.reject(new Error("concurrent reads are unsupported"));
|
|
173
334
|
return new Promise((resolve) => {
|
|
174
|
-
const timer = setTimeout(() => {
|
|
175
|
-
connection.waiter = undefined;
|
|
176
|
-
resolve(JSON.stringify({ kind: "timeout" }));
|
|
177
|
-
}, timeoutMs);
|
|
178
335
|
connection.waiter = (message) => {
|
|
179
|
-
clearTimeout(timer);
|
|
180
336
|
connection.waiter = undefined;
|
|
181
337
|
resolve(JSON.stringify(message));
|
|
182
338
|
};
|
|
@@ -189,7 +345,7 @@ export function createBrowserHost(options = {}) {
|
|
|
189
345
|
connections.delete(handle);
|
|
190
346
|
connection.intentionallyClosed = true;
|
|
191
347
|
connection.waiter?.({ kind: "closed", detail: "by the WASM runtime" });
|
|
192
|
-
connection.socket.close();
|
|
348
|
+
return connection.socket.close();
|
|
193
349
|
}
|
|
194
350
|
|
|
195
351
|
function enqueue(connection, message) {
|
|
@@ -198,7 +354,7 @@ export function createBrowserHost(options = {}) {
|
|
|
198
354
|
connection.waiter(message);
|
|
199
355
|
return;
|
|
200
356
|
}
|
|
201
|
-
const bytes =
|
|
357
|
+
const bytes = utf8ByteLength(message.kind === "text" ? message.text : JSON.stringify(message));
|
|
202
358
|
if (connection.queue.length >= maxQueuedMessages || connection.queuedBytes + bytes > maxQueuedBytes) {
|
|
203
359
|
connection.queue.length = 0;
|
|
204
360
|
connection.queuedBytes = 0;
|
|
@@ -207,7 +363,7 @@ export function createBrowserHost(options = {}) {
|
|
|
207
363
|
kind: "error",
|
|
208
364
|
detail: `receive queue exceeded ${maxQueuedMessages} messages or ${maxQueuedBytes} bytes`,
|
|
209
365
|
};
|
|
210
|
-
const errorBytes =
|
|
366
|
+
const errorBytes = utf8ByteLength(JSON.stringify(error));
|
|
211
367
|
connection.queue.push({ message: error, bytes: errorBytes });
|
|
212
368
|
connection.queuedBytes = errorBytes;
|
|
213
369
|
connection.socket.close(1009, "receive queue exceeded configured bounds");
|
|
@@ -217,18 +373,156 @@ export function createBrowserHost(options = {}) {
|
|
|
217
373
|
connection.queuedBytes += bytes;
|
|
218
374
|
}
|
|
219
375
|
|
|
376
|
+
function dispose() {
|
|
377
|
+
if (disposal) return disposal;
|
|
378
|
+
disposalError = new Error("Nanocodex host was disposed during WebSocket connection");
|
|
379
|
+
disposal = Promise.resolve().then(async () => {
|
|
380
|
+
const cleanups = [];
|
|
381
|
+
const cleanup = (action) => {
|
|
382
|
+
try { cleanups.push(Promise.resolve(action())); }
|
|
383
|
+
catch (failure) { cleanups.push(Promise.reject(failure)); }
|
|
384
|
+
};
|
|
385
|
+
const preconnectedOwnership = preconnected?.ownership;
|
|
386
|
+
for (const attempt of [...openingAttempts]) {
|
|
387
|
+
if (attempt !== preconnectedOwnership) cleanup(() => attempt.dispose(disposalError));
|
|
388
|
+
}
|
|
389
|
+
for (const connection of [...connectingConnections]) {
|
|
390
|
+
connection.intentionallyClosed = true;
|
|
391
|
+
cleanup(() => connection.reject(disposalError));
|
|
392
|
+
cleanup(() => connection.socket.close());
|
|
393
|
+
}
|
|
394
|
+
for (const handle of [...connections.keys()]) cleanup(() => close(handle));
|
|
395
|
+
cleanup(() => closePreconnected(disposalError));
|
|
396
|
+
cleanup(() => code.reset());
|
|
397
|
+
cleanup(() => mcpInstalled?.then(() => {}));
|
|
398
|
+
cleanup(() => toolsLifecycle?.close());
|
|
399
|
+
cleanup(() => options.onDispose?.());
|
|
400
|
+
const settled = await Promise.allSettled(cleanups);
|
|
401
|
+
const errors = settled
|
|
402
|
+
.filter((result) => result.status === "rejected")
|
|
403
|
+
.map((result) => result.reason);
|
|
404
|
+
if (errors.length === 1) throw errors[0];
|
|
405
|
+
if (errors.length > 1) {
|
|
406
|
+
throw new AggregateError(errors, "Nanocodex host disposal failed");
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
return disposal;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
function openOwned(factory) {
|
|
413
|
+
if (disposal) throw new Error("Nanocodex host is already disposed");
|
|
414
|
+
let rejectDisposed;
|
|
415
|
+
const disposed = new Promise((_, reject) => { rejectDisposed = reject; });
|
|
416
|
+
const ownership = {
|
|
417
|
+
disposed: false,
|
|
418
|
+
opened: undefined,
|
|
419
|
+
closePromise: undefined,
|
|
420
|
+
error: undefined,
|
|
421
|
+
dispose(error) {
|
|
422
|
+
if (ownership.disposed) return ownership.closePromise ?? Promise.resolve();
|
|
423
|
+
ownership.disposed = true;
|
|
424
|
+
ownership.error = error;
|
|
425
|
+
openingAttempts.delete(ownership);
|
|
426
|
+
rejectDisposed(error);
|
|
427
|
+
return closeOpened();
|
|
428
|
+
},
|
|
429
|
+
transfer() {
|
|
430
|
+
if (disposal || ownership.disposed) {
|
|
431
|
+
throw disposalError ?? ownership.error
|
|
432
|
+
?? new Error("Nanocodex host was disposed during WebSocket connection");
|
|
433
|
+
}
|
|
434
|
+
openingAttempts.delete(ownership);
|
|
435
|
+
},
|
|
436
|
+
};
|
|
437
|
+
openingAttempts.add(ownership);
|
|
438
|
+
let opening;
|
|
439
|
+
try {
|
|
440
|
+
opening = Promise.resolve(factory());
|
|
441
|
+
} catch (error) {
|
|
442
|
+
opening = Promise.reject(error);
|
|
443
|
+
}
|
|
444
|
+
opening = opening.then((opened) => {
|
|
445
|
+
ownership.opened = opened;
|
|
446
|
+
if (!ownership.disposed) return opened;
|
|
447
|
+
void closeOpened().catch(() => {});
|
|
448
|
+
throw ownership.error;
|
|
449
|
+
});
|
|
450
|
+
ownership.promise = Promise.race([opening, disposed]);
|
|
451
|
+
void ownership.promise.catch(() => {
|
|
452
|
+
openingAttempts.delete(ownership);
|
|
453
|
+
});
|
|
454
|
+
return ownership;
|
|
455
|
+
|
|
456
|
+
function closeOpened() {
|
|
457
|
+
if (ownership.closePromise) return ownership.closePromise;
|
|
458
|
+
if (ownership.opened === undefined) return Promise.resolve();
|
|
459
|
+
try {
|
|
460
|
+
ownership.closePromise = Promise.resolve(
|
|
461
|
+
normalizeWebSocketConnection(ownership.opened).socket.close(),
|
|
462
|
+
);
|
|
463
|
+
} catch (error) {
|
|
464
|
+
ownership.closePromise = Promise.reject(error);
|
|
465
|
+
}
|
|
466
|
+
return ownership.closePromise;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
toolsLifecycle?.claim();
|
|
220
471
|
return Object.freeze({
|
|
472
|
+
ready: async () => {
|
|
473
|
+
await Promise.all([filesystemReady, mcpInstalled, toolProvidersReady]);
|
|
474
|
+
},
|
|
475
|
+
retain() {
|
|
476
|
+
if (disposal) throw new Error("Nanocodex host is already disposed");
|
|
477
|
+
references += 1;
|
|
478
|
+
},
|
|
479
|
+
release() {
|
|
480
|
+
if (references > 0) references -= 1;
|
|
481
|
+
return references === 0 ? dispose() : Promise.resolve();
|
|
482
|
+
},
|
|
221
483
|
connect,
|
|
484
|
+
preconnect,
|
|
222
485
|
send,
|
|
223
486
|
next,
|
|
224
487
|
close,
|
|
225
488
|
sleep: (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)),
|
|
226
|
-
executeCode: code.
|
|
489
|
+
executeCode: code.executeCodeObserved,
|
|
490
|
+
waitCode: code.waitCodeObserved,
|
|
491
|
+
beginCodeTurn: code.beginTurn,
|
|
492
|
+
cancelCodeTurn: code.cancelTurn,
|
|
493
|
+
nextCodeUpdate: code.nextCodeUpdate,
|
|
227
494
|
executeTool: code.executeTool,
|
|
495
|
+
bindSubagentSession: code.bindSubagentSession,
|
|
496
|
+
cancelCode: code.cancel,
|
|
497
|
+
readWorkspaceFile: async (path) => {
|
|
498
|
+
if (!options.filesystem) throw new Error("browser workspace is unavailable");
|
|
499
|
+
const contents = await options.filesystem.readFile(path);
|
|
500
|
+
if (!(contents instanceof Uint8Array)) {
|
|
501
|
+
throw new TypeError("browser workspace readFile() must return Uint8Array");
|
|
502
|
+
}
|
|
503
|
+
return contents;
|
|
504
|
+
},
|
|
505
|
+
listWorkspace: async (path) => {
|
|
506
|
+
if (!options.filesystem) throw new Error("browser workspace is unavailable");
|
|
507
|
+
if (typeof options.filesystem.list !== "function") {
|
|
508
|
+
throw new Error("browser workspace does not expose list()");
|
|
509
|
+
}
|
|
510
|
+
return options.filesystem.list(path, { maxEntries: 2_000 });
|
|
511
|
+
},
|
|
512
|
+
writeWorkspaceFile: async (path, contents) => {
|
|
513
|
+
if (!options.filesystem) throw new Error("browser workspace is unavailable");
|
|
514
|
+
await options.filesystem.writeFile(path, contents);
|
|
515
|
+
},
|
|
516
|
+
removeWorkspaceFile: async (path) => {
|
|
517
|
+
if (!options.filesystem) throw new Error("browser workspace is unavailable");
|
|
518
|
+
await options.filesystem.remove(path);
|
|
519
|
+
},
|
|
228
520
|
toolMode: () => toolMode,
|
|
229
521
|
toolDefinitions: code.toolDefinitions,
|
|
522
|
+
releaseSession: code.releaseSession,
|
|
230
523
|
emitEvent: onEvent,
|
|
231
524
|
reset: code.reset,
|
|
525
|
+
dispose,
|
|
232
526
|
});
|
|
233
527
|
}
|
|
234
528
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type HostManagedWebSocketOptions = Readonly<{
|
|
2
|
+
WebSocketImpl?: typeof WebSocket | undefined;
|
|
3
|
+
timeoutMs?: number | undefined;
|
|
4
|
+
}>;
|
|
5
|
+
|
|
6
|
+
export function openHostManagedWebSocket(
|
|
7
|
+
endpoint: string | URL,
|
|
8
|
+
sessionId: string,
|
|
9
|
+
options?: HostManagedWebSocketOptions,
|
|
10
|
+
): Promise<WebSocket>;
|
|
11
|
+
|
|
12
|
+
export function defaultHostManagedWebSocketUrl(
|
|
13
|
+
location?: Pick<Location, "href">,
|
|
14
|
+
): string;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
const DEFAULT_TIMEOUT_MS = 10_000;
|
|
2
|
+
|
|
3
|
+
/** Open Nanocodex's same-origin Responses proxy and consume its setup frame. */
|
|
4
|
+
export function openHostManagedWebSocket(endpoint, sessionId, options = {}) {
|
|
5
|
+
if (typeof sessionId !== "string" || !sessionId) {
|
|
6
|
+
throw new TypeError("host-managed WebSocket requires a session ID");
|
|
7
|
+
}
|
|
8
|
+
const WebSocketImpl = options.WebSocketImpl ?? globalThis.WebSocket;
|
|
9
|
+
if (typeof WebSocketImpl !== "function") {
|
|
10
|
+
throw new Error("WebSocket is unavailable in this runtime");
|
|
11
|
+
}
|
|
12
|
+
const socketUrl = resolveWebSocketUrl(endpoint);
|
|
13
|
+
socketUrl.searchParams.set("session_id", sessionId);
|
|
14
|
+
socketUrl.searchParams.set("thread_id", options.threadId ?? sessionId);
|
|
15
|
+
return waitForProxyHandshake(
|
|
16
|
+
new WebSocketImpl(socketUrl),
|
|
17
|
+
options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function defaultHostManagedWebSocketUrl(location = globalThis.location) {
|
|
22
|
+
if (!location?.href) {
|
|
23
|
+
throw new Error("host-managed transport requires websocketUrl outside a browser location");
|
|
24
|
+
}
|
|
25
|
+
const url = new URL("/api/responses", location.href);
|
|
26
|
+
url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
|
|
27
|
+
return url.href;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function resolveWebSocketUrl(endpoint) {
|
|
31
|
+
const base = globalThis.location?.href;
|
|
32
|
+
const url = base === undefined ? new URL(endpoint) : new URL(endpoint, base);
|
|
33
|
+
if (url.protocol !== "ws:" && url.protocol !== "wss:") {
|
|
34
|
+
throw new TypeError("host-managed websocketUrl must use ws: or wss:");
|
|
35
|
+
}
|
|
36
|
+
return url;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function waitForProxyHandshake(socket, timeoutMs) {
|
|
40
|
+
if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0) {
|
|
41
|
+
socket.close();
|
|
42
|
+
throw new TypeError("host-managed WebSocket timeout must be a positive integer");
|
|
43
|
+
}
|
|
44
|
+
return new Promise((resolve, reject) => {
|
|
45
|
+
let settled = false;
|
|
46
|
+
const timer = setTimeout(
|
|
47
|
+
() => fail(new Error("Agent connection timed out")),
|
|
48
|
+
timeoutMs,
|
|
49
|
+
);
|
|
50
|
+
const cleanup = () => {
|
|
51
|
+
clearTimeout(timer);
|
|
52
|
+
socket.removeEventListener("message", onMessage);
|
|
53
|
+
socket.removeEventListener("error", onError);
|
|
54
|
+
socket.removeEventListener("close", onClose);
|
|
55
|
+
};
|
|
56
|
+
const fail = (error) => {
|
|
57
|
+
if (settled) return;
|
|
58
|
+
settled = true;
|
|
59
|
+
cleanup();
|
|
60
|
+
socket.close();
|
|
61
|
+
reject(error);
|
|
62
|
+
};
|
|
63
|
+
const onMessage = (event) => {
|
|
64
|
+
const message = parseHandshake(event.data);
|
|
65
|
+
if (message?.type === "nanocodex.proxy.ready") {
|
|
66
|
+
settled = true;
|
|
67
|
+
cleanup();
|
|
68
|
+
resolve(socket);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (message?.type === "nanocodex.proxy.rejected"
|
|
72
|
+
&& Number.isInteger(message.status)
|
|
73
|
+
&& message.status >= 100
|
|
74
|
+
&& message.status <= 599) {
|
|
75
|
+
const status = message.status;
|
|
76
|
+
const body = typeof message.error === "string" ? message.error : `HTTP ${status}`;
|
|
77
|
+
const retryAfter = Number(message.retryAfter);
|
|
78
|
+
fail(Object.assign(
|
|
79
|
+
new Error(`Agent connection rejected with HTTP ${status}: ${body}`),
|
|
80
|
+
{
|
|
81
|
+
status,
|
|
82
|
+
body,
|
|
83
|
+
...(Number.isFinite(retryAfter) && retryAfter >= 0 ? { retryAfter } : {}),
|
|
84
|
+
},
|
|
85
|
+
));
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
fail(new Error("Agent connection returned an invalid handshake"));
|
|
89
|
+
};
|
|
90
|
+
const onError = () => fail(new Error("WebSocket connection failed"));
|
|
91
|
+
const onClose = (event) => fail(
|
|
92
|
+
new Error(`WebSocket closed during connection with code ${event.code}`),
|
|
93
|
+
);
|
|
94
|
+
socket.addEventListener("message", onMessage);
|
|
95
|
+
socket.addEventListener("error", onError);
|
|
96
|
+
socket.addEventListener("close", onClose);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function parseHandshake(data) {
|
|
101
|
+
if (typeof data !== "string") return undefined;
|
|
102
|
+
try {
|
|
103
|
+
const value = JSON.parse(data);
|
|
104
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
105
|
+
? value
|
|
106
|
+
: undefined;
|
|
107
|
+
} catch {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
}
|
package/browser/index.d.mts
CHANGED
|
@@ -1,18 +1,81 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * as Actions from "../actions/index.mjs";
|
|
2
|
+
export {
|
|
3
|
+
createMemoryChatGptSubscriptionStore,
|
|
4
|
+
subscriptionRevision,
|
|
5
|
+
} from "../runtime/subscription-store.mjs";
|
|
6
|
+
export { createQuickJsEvaluator } from "../runtime/quickjs-evaluator.mjs";
|
|
7
|
+
export {
|
|
8
|
+
createTempoProvider,
|
|
9
|
+
createTempoProviderFromAccounts,
|
|
10
|
+
DEFAULT_MERCATOR_MCP_URL,
|
|
11
|
+
} from "../runtime/tempo-provider.mjs";
|
|
12
|
+
export type {
|
|
13
|
+
AccountsTempoProviderOptions,
|
|
14
|
+
AccountsWallet,
|
|
15
|
+
TempoProvider,
|
|
16
|
+
} from "../runtime/tempo-provider.mjs";
|
|
2
17
|
export type {
|
|
3
18
|
AgentEvent,
|
|
19
|
+
AgentLifecycle,
|
|
20
|
+
AgentSessionContext,
|
|
21
|
+
ChatGptCredential,
|
|
22
|
+
ChatGptCredentialSeed,
|
|
23
|
+
ChatGptLoginStatus,
|
|
24
|
+
ChatGptSubscriptionHandle,
|
|
25
|
+
ChatGptSubscriptionOptions,
|
|
26
|
+
ChatGptSubscriptionStore,
|
|
4
27
|
CostStatus,
|
|
28
|
+
CodeEvaluator,
|
|
29
|
+
CodeEvaluatorEnvironment,
|
|
5
30
|
EstimatedUsdCost,
|
|
31
|
+
ExecutionEnvironment,
|
|
6
32
|
PromptInput,
|
|
7
33
|
PromptItem,
|
|
34
|
+
LifecycleTurn,
|
|
35
|
+
LifecycleTurnResult,
|
|
8
36
|
ReasoningMode,
|
|
9
37
|
SessionSnapshot,
|
|
10
38
|
Thinking,
|
|
11
39
|
Tool,
|
|
40
|
+
NamedTool,
|
|
12
41
|
ToolContext,
|
|
42
|
+
SubagentToolContext,
|
|
43
|
+
ToolConfiguration,
|
|
13
44
|
ToolMap,
|
|
14
45
|
Turn,
|
|
15
46
|
TurnResult,
|
|
16
47
|
TurnUsage,
|
|
48
|
+
McpPayment,
|
|
49
|
+
McpServer,
|
|
50
|
+
McpServers,
|
|
51
|
+
MemoryChatGptSubscriptionStore,
|
|
52
|
+
MppSession,
|
|
53
|
+
SubscriptionCommitRequest,
|
|
54
|
+
SubscriptionCommitResult,
|
|
55
|
+
SubscriptionRevision,
|
|
56
|
+
SubscriptionStoredValue,
|
|
17
57
|
} from "../types.mjs";
|
|
18
58
|
export * as Agent from "./Agent.mjs";
|
|
59
|
+
export * as ChatGptSubscription from "./ChatGptSubscription.mjs";
|
|
60
|
+
export * as Subagents from "../runtime/subagents.mjs";
|
|
61
|
+
export * as Transport from "./Transport.mjs";
|
|
62
|
+
export * as Voice from "./Voice.mjs";
|
|
63
|
+
export * as Workspace from "./workspace.mjs";
|
|
64
|
+
export * as Tools from "../tools/index.mjs";
|
|
65
|
+
export {
|
|
66
|
+
createConfig,
|
|
67
|
+
type AgentParameters,
|
|
68
|
+
type AgentSnapshot,
|
|
69
|
+
type AgentStatus,
|
|
70
|
+
type Config,
|
|
71
|
+
type CreateConfigParameters,
|
|
72
|
+
} from "./config.mjs";
|
|
73
|
+
export {
|
|
74
|
+
defaultHostManagedWebSocketUrl,
|
|
75
|
+
openHostManagedWebSocket,
|
|
76
|
+
type HostManagedWebSocketOptions,
|
|
77
|
+
} from "./hostManagedWebSocket.mjs";
|
|
78
|
+
export type {
|
|
79
|
+
BrowserWebSocketConnection,
|
|
80
|
+
BrowserWebSocketRequest,
|
|
81
|
+
} from "./host.mjs";
|