@lamplitisles/dsh-nanocodex 0.1.0-beta.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/LICENSE +65 -0
- package/NOTICE +2 -0
- package/README.md +182 -0
- package/THIRD_PARTY_NOTICES.md +29 -0
- package/cordis.patch.yml +52 -0
- package/dist/index.d.ts +435 -0
- package/dist/index.js +3405 -0
- package/dist/standard-preset.d.ts +7 -0
- package/dist/standard-preset.js +25 -0
- package/engine-release.json +14 -0
- package/package.json +119 -0
- package/presets/standard/agent.cordis.yml +6 -0
- package/presets/standard/preset.yml +2 -0
- package/vendor/nanocodex/README.md +1344 -0
- package/vendor/nanocodex/actions/events.d.mts +10 -0
- package/vendor/nanocodex/actions/events.mjs +163 -0
- package/vendor/nanocodex/actions/index.d.mts +13 -0
- package/vendor/nanocodex/actions/index.mjs +35 -0
- package/vendor/nanocodex/actions/session.d.mts +66 -0
- package/vendor/nanocodex/actions/session.mjs +59 -0
- package/vendor/nanocodex/actions/turn.d.mts +59 -0
- package/vendor/nanocodex/actions/turn.mjs +37 -0
- package/vendor/nanocodex/actions/voice.d.mts +22 -0
- package/vendor/nanocodex/actions/voice.mjs +50 -0
- package/vendor/nanocodex/browser/Agent.d.mts +55 -0
- package/vendor/nanocodex/browser/Agent.mjs +11 -0
- package/vendor/nanocodex/browser/ChatGptSubscription.d.mts +7 -0
- package/vendor/nanocodex/browser/ChatGptSubscription.mjs +19 -0
- package/vendor/nanocodex/browser/InlineAgent.mjs +266 -0
- package/vendor/nanocodex/browser/Transport.d.mts +74 -0
- package/vendor/nanocodex/browser/Transport.mjs +61 -0
- package/vendor/nanocodex/browser/Voice.d.mts +71 -0
- package/vendor/nanocodex/browser/Voice.mjs +291 -0
- package/vendor/nanocodex/browser/VoiceSession.mjs +688 -0
- package/vendor/nanocodex/browser/WorkerAgent.d.mts +65 -0
- package/vendor/nanocodex/browser/WorkerAgent.mjs +1472 -0
- package/vendor/nanocodex/browser/agent.worker.mjs +3 -0
- package/vendor/nanocodex/browser/config.d.mts +36 -0
- package/vendor/nanocodex/browser/config.mjs +439 -0
- package/vendor/nanocodex/browser/engine.mjs +13 -0
- package/vendor/nanocodex/browser/harness.mjs +55 -0
- package/vendor/nanocodex/browser/host.d.mts +83 -0
- package/vendor/nanocodex/browser/host.mjs +555 -0
- package/vendor/nanocodex/browser/hostManagedWebSocket.d.mts +14 -0
- package/vendor/nanocodex/browser/hostManagedWebSocket.mjs +110 -0
- package/vendor/nanocodex/browser/index.d.mts +92 -0
- package/vendor/nanocodex/browser/index.mjs +23 -0
- package/vendor/nanocodex/browser/indexeddb-durability-store.mjs +197 -0
- package/vendor/nanocodex/browser/workspace.d.mts +16 -0
- package/vendor/nanocodex/browser/workspace.mjs +107 -0
- package/vendor/nanocodex/cloud/Client.d.mts +83 -0
- package/vendor/nanocodex/cloud/Client.mjs +231 -0
- package/vendor/nanocodex/cloud/Decorator.d.mts +31 -0
- package/vendor/nanocodex/cloud/Decorator.mjs +37 -0
- package/vendor/nanocodex/cloud/Dialog.d.mts +113 -0
- package/vendor/nanocodex/cloud/Dialog.mjs +366 -0
- package/vendor/nanocodex/cloud/Errors.d.mts +22 -0
- package/vendor/nanocodex/cloud/Errors.mjs +39 -0
- package/vendor/nanocodex/cloud/Principal.d.mts +26 -0
- package/vendor/nanocodex/cloud/Principal.mjs +88 -0
- package/vendor/nanocodex/cloud/RemoteProvider.mjs +88 -0
- package/vendor/nanocodex/cloud/Transport.d.mts +47 -0
- package/vendor/nanocodex/cloud/Transport.mjs +454 -0
- package/vendor/nanocodex/cloud/actions/account.d.mts +9 -0
- package/vendor/nanocodex/cloud/actions/account.mjs +19 -0
- package/vendor/nanocodex/cloud/actions/agent.d.mts +18 -0
- package/vendor/nanocodex/cloud/actions/agent.mjs +428 -0
- package/vendor/nanocodex/cloud/actions/connection.d.mts +133 -0
- package/vendor/nanocodex/cloud/actions/connection.mjs +580 -0
- package/vendor/nanocodex/cloud/actions/grant.d.mts +10 -0
- package/vendor/nanocodex/cloud/actions/grant.mjs +12 -0
- package/vendor/nanocodex/cloud/actions/index.d.mts +7 -0
- package/vendor/nanocodex/cloud/actions/index.mjs +7 -0
- package/vendor/nanocodex/cloud/actions/machineUsd.d.mts +23 -0
- package/vendor/nanocodex/cloud/actions/machineUsd.mjs +37 -0
- package/vendor/nanocodex/cloud/actions/model.d.mts +12 -0
- package/vendor/nanocodex/cloud/actions/model.mjs +50 -0
- package/vendor/nanocodex/cloud/actions/mpp.d.mts +28 -0
- package/vendor/nanocodex/cloud/actions/mpp.mjs +39 -0
- package/vendor/nanocodex/cloud/index.d.mts +30 -0
- package/vendor/nanocodex/cloud/index.mjs +9 -0
- package/vendor/nanocodex/cloud/internal.mjs +533 -0
- package/vendor/nanocodex/cloud/mercator.mjs +108 -0
- package/vendor/nanocodex/cloud/server/HostPrincipal.d.mts +34 -0
- package/vendor/nanocodex/cloud/server/HostPrincipal.mjs +202 -0
- package/vendor/nanocodex/cloud/server/index.d.mts +1 -0
- package/vendor/nanocodex/cloud/server/index.mjs +1 -0
- package/vendor/nanocodex/cloud/types.d.mts +211 -0
- package/vendor/nanocodex/cloudflare/Agent.d.mts +133 -0
- package/vendor/nanocodex/cloudflare/Agent.mjs +811 -0
- package/vendor/nanocodex/cloudflare/egress-subject.mjs +19 -0
- package/vendor/nanocodex/cloudflare/egress.d.mts +41 -0
- package/vendor/nanocodex/cloudflare/egress.mjs +119 -0
- package/vendor/nanocodex/cloudflare/event-socket.mjs +316 -0
- package/vendor/nanocodex/cloudflare/index.d.mts +7 -0
- package/vendor/nanocodex/cloudflare/index.mjs +6 -0
- package/vendor/nanocodex/host/Agent.d.mts +55 -0
- package/vendor/nanocodex/host/Agent.mjs +1 -0
- package/vendor/nanocodex/host/index.d.mts +82 -0
- package/vendor/nanocodex/host/index.mjs +10 -0
- package/vendor/nanocodex/index.d.mts +81 -0
- package/vendor/nanocodex/index.mjs +12 -0
- package/vendor/nanocodex/internal.mjs +1275 -0
- package/vendor/nanocodex/managed/Agent.d.mts +380 -0
- package/vendor/nanocodex/managed/Agent.mjs +1694 -0
- package/vendor/nanocodex/managed/ManagedError.d.mts +9 -0
- package/vendor/nanocodex/managed/ManagedError.mjs +8 -0
- package/vendor/nanocodex/managed/README.md +241 -0
- package/vendor/nanocodex/managed/Voice.mjs +202 -0
- package/vendor/nanocodex/managed/index.d.mts +20 -0
- package/vendor/nanocodex/managed/index.mjs +2 -0
- package/vendor/nanocodex/managed/internal.mjs +119 -0
- package/vendor/nanocodex/node/Agent.d.mts +50 -0
- package/vendor/nanocodex/node/Agent.mjs +203 -0
- package/vendor/nanocodex/node/ChatGptSubscription.d.mts +9 -0
- package/vendor/nanocodex/node/ChatGptSubscription.mjs +17 -0
- package/vendor/nanocodex/node/Transport.d.mts +44 -0
- package/vendor/nanocodex/node/Transport.mjs +46 -0
- package/vendor/nanocodex/node/host.mjs +731 -0
- package/vendor/nanocodex/node/index.d.mts +73 -0
- package/vendor/nanocodex/node/index.mjs +17 -0
- package/vendor/nanocodex/node/workspace.d.mts +10 -0
- package/vendor/nanocodex/node/workspace.mjs +198 -0
- package/vendor/nanocodex/package.json +200 -0
- package/vendor/nanocodex/pkg-node/nanocodex.d.ts +675 -0
- package/vendor/nanocodex/pkg-node/nanocodex.js +2628 -0
- package/vendor/nanocodex/pkg-node/nanocodex_bg.wasm.d.ts +105 -0
- package/vendor/nanocodex/pkg-node/package.json +1 -0
- package/vendor/nanocodex/pkg-web/.nanocodex-bindgen-stamp +6 -0
- package/vendor/nanocodex/pkg-web/nanocodex-build.json +1 -0
- package/vendor/nanocodex/pkg-web/nanocodex.d.ts +805 -0
- package/vendor/nanocodex/pkg-web/nanocodex.js +2714 -0
- package/vendor/nanocodex/pkg-web/nanocodex_bg.js +2615 -0
- package/vendor/nanocodex/pkg-web/nanocodex_bg.wasm +0 -0
- package/vendor/nanocodex/pkg-web/nanocodex_bg.wasm.d.ts +105 -0
- package/vendor/nanocodex/pkg-web/nanocodex_worker.js +9 -0
- package/vendor/nanocodex/pkg-web/package.json +1 -0
- package/vendor/nanocodex/runtime/chatgpt-subscription.mjs +212 -0
- package/vendor/nanocodex/runtime/cloudflare-durability-store.d.mts +26 -0
- package/vendor/nanocodex/runtime/cloudflare-durability-store.mjs +168 -0
- package/vendor/nanocodex/runtime/code-evaluator.worker.mjs +137 -0
- package/vendor/nanocodex/runtime/code-runtime.mjs +1 -0
- package/vendor/nanocodex/runtime/durability-store.d.mts +85 -0
- package/vendor/nanocodex/runtime/durability-store.mjs +631 -0
- package/vendor/nanocodex/runtime/durability.mjs +153 -0
- package/vendor/nanocodex/runtime/managed-transport.mjs +460 -0
- package/vendor/nanocodex/runtime/mcp-runtime.mjs +534 -0
- package/vendor/nanocodex/runtime/postgres-durability-store.d.mts +64 -0
- package/vendor/nanocodex/runtime/postgres-durability-store.mjs +532 -0
- package/vendor/nanocodex/runtime/quickjs-evaluator.d.mts +17 -0
- package/vendor/nanocodex/runtime/quickjs-evaluator.mjs +236 -0
- package/vendor/nanocodex/runtime/responses-transport.mjs +22 -0
- package/vendor/nanocodex/runtime/subagents.d.mts +107 -0
- package/vendor/nanocodex/runtime/subagents.mjs +54 -0
- package/vendor/nanocodex/runtime/subscription-store.d.mts +8 -0
- package/vendor/nanocodex/runtime/subscription-store.mjs +42 -0
- package/vendor/nanocodex/runtime/tempo-provider.d.mts +125 -0
- package/vendor/nanocodex/runtime/tempo-provider.mjs +264 -0
- package/vendor/nanocodex/runtime/tool-configuration.mjs +1 -0
- package/vendor/nanocodex/runtime/tool-router.mjs +1 -0
- package/vendor/nanocodex/runtime/utf8.mjs +1 -0
- package/vendor/nanocodex/runtime/worker-evaluator.mjs +162 -0
- package/vendor/nanocodex/runtime/workspace.d.mts +1 -0
- package/vendor/nanocodex/runtime/workspace.mjs +1 -0
- package/vendor/nanocodex/tools/Tools.d.mts +56 -0
- package/vendor/nanocodex/tools/Tools.mjs +136 -0
- package/vendor/nanocodex/tools/artifact.d.mts +1 -0
- package/vendor/nanocodex/tools/artifact.mjs +1 -0
- package/vendor/nanocodex/tools/attachment.mjs +1 -0
- package/vendor/nanocodex/tools/bash.d.mts +1 -0
- package/vendor/nanocodex/tools/bash.mjs +1 -0
- package/vendor/nanocodex/tools/browser/accountInfo.mjs +795 -0
- package/vendor/nanocodex/tools/browser/browserBuffer.mjs +18 -0
- package/vendor/nanocodex/tools/browser/browserCompiler.mjs +155 -0
- package/vendor/nanocodex/tools/browser/browserEgress.mjs +161 -0
- package/vendor/nanocodex/tools/browser/browserPython.mjs +133 -0
- package/vendor/nanocodex/tools/browser/browserShell.mjs +1075 -0
- package/vendor/nanocodex/tools/browser/browserSprintf.mjs +4 -0
- package/vendor/nanocodex/tools/browser/browserSsh.mjs +201 -0
- package/vendor/nanocodex/tools/browser/browserZlib.mjs +136 -0
- package/vendor/nanocodex/tools/browser/compiler.worker.mjs +160 -0
- package/vendor/nanocodex/tools/browser/devTunnelsSshBrowser.mjs +13 -0
- package/vendor/nanocodex/tools/browser/index.d.mts +209 -0
- package/vendor/nanocodex/tools/browser/index.mjs +174 -0
- package/vendor/nanocodex/tools/browser/opfsGit.mjs +248 -0
- package/vendor/nanocodex/tools/browser/python.worker.mjs +114 -0
- package/vendor/nanocodex/tools/browser/threadGit.mjs +197 -0
- package/vendor/nanocodex/tools/browser/unsupportedNodeRsa.mjs +5 -0
- package/vendor/nanocodex/tools/browser/workspace.mjs +83 -0
- package/vendor/nanocodex/tools/dataset.d.mts +1 -0
- package/vendor/nanocodex/tools/dataset.mjs +1 -0
- package/vendor/nanocodex/tools/datasetContract.mjs +1 -0
- package/vendor/nanocodex/tools/datasetEngine.mjs +1 -0
- package/vendor/nanocodex/tools/hostedCatalog.d.mts +1 -0
- package/vendor/nanocodex/tools/hostedCatalog.mjs +1 -0
- package/vendor/nanocodex/tools/index.d.mts +49 -0
- package/vendor/nanocodex/tools/index.mjs +19 -0
- package/vendor/nanocodex/tools/namedTool.mjs +1 -0
- package/vendor/nanocodex/tools/repository-workspace.d.mts +1 -0
- package/vendor/nanocodex/tools/repository-workspace.mjs +1 -0
- package/vendor/nanocodex/tools/ssh.d.mts +1 -0
- package/vendor/nanocodex/tools/ssh.mjs +1 -0
- package/vendor/nanocodex/tools/standard.mjs +1 -0
- package/vendor/nanocodex/tools/standardDescriptions.mjs +1 -0
- package/vendor/nanocodex/types.d.mts +663 -0
- package/vendor/nanocodex/wasm.d.mts +4 -0
- package/vendor/nanocodex/worker/ChatGptSubscription.d.mts +9 -0
- package/vendor/nanocodex/worker/ChatGptSubscription.mjs +29 -0
- package/vendor/nanocodex/worker/index.d.mts +18 -0
- package/vendor/nanocodex/worker/index.mjs +5 -0
- package/vendor/nanocodex-tools/README.md +65 -0
- package/vendor/nanocodex-tools/dist/hosted/app-tool-catalog.d.ts +7 -0
- package/vendor/nanocodex-tools/dist/hosted/app-tool-catalog.js +14 -0
- package/vendor/nanocodex-tools/dist/hosted/broker-core.d.ts +172 -0
- package/vendor/nanocodex-tools/dist/hosted/broker-core.js +1278 -0
- package/vendor/nanocodex-tools/dist/hosted/index.d.ts +3 -0
- package/vendor/nanocodex-tools/dist/hosted/index.js +3 -0
- package/vendor/nanocodex-tools/dist/hosted/protocol.d.ts +120 -0
- package/vendor/nanocodex-tools/dist/hosted/protocol.js +415 -0
- package/vendor/nanocodex-tools/dist/index.d.ts +19 -0
- package/vendor/nanocodex-tools/dist/index.js +14 -0
- package/vendor/nanocodex-tools/dist/memory.d.ts +204 -0
- package/vendor/nanocodex-tools/dist/memory.js +411 -0
- package/vendor/nanocodex-tools/dist/namespace.d.ts +87 -0
- package/vendor/nanocodex-tools/dist/namespace.js +338 -0
- package/vendor/nanocodex-tools/dist/repository-archive.d.ts +4 -0
- package/vendor/nanocodex-tools/dist/repository-archive.js +104 -0
- package/vendor/nanocodex-tools/dist/runtime.d.ts +30 -0
- package/vendor/nanocodex-tools/dist/runtime.js +37 -0
- package/vendor/nanocodex-tools/dist/session.d.ts +167 -0
- package/vendor/nanocodex-tools/dist/session.js +286 -0
- package/vendor/nanocodex-tools/dist/shell.d.ts +51 -0
- package/vendor/nanocodex-tools/dist/shell.js +553 -0
- package/vendor/nanocodex-tools/dist/ssh.d.ts +29 -0
- package/vendor/nanocodex-tools/dist/ssh.js +66 -0
- package/vendor/nanocodex-tools/dist/workspace.d.ts +45 -0
- package/vendor/nanocodex-tools/dist/workspace.js +237 -0
- package/vendor/nanocodex-tools/package.json +122 -0
- package/vendor/nanocodex-tools/runtime/code-runtime.mjs +817 -0
- package/vendor/nanocodex-tools/runtime/tool-configuration.mjs +50 -0
- package/vendor/nanocodex-tools/runtime/tool-router.mjs +730 -0
- package/vendor/nanocodex-tools/runtime/utf8.d.mts +2 -0
- package/vendor/nanocodex-tools/runtime/utf8.mjs +25 -0
- package/vendor/nanocodex-tools/tools/artifact.d.mts +69 -0
- package/vendor/nanocodex-tools/tools/artifact.mjs +270 -0
- package/vendor/nanocodex-tools/tools/attachment.mjs +603 -0
- package/vendor/nanocodex-tools/tools/bash.d.mts +90 -0
- package/vendor/nanocodex-tools/tools/bash.mjs +742 -0
- package/vendor/nanocodex-tools/tools/dataset.d.mts +9 -0
- package/vendor/nanocodex-tools/tools/dataset.mjs +47 -0
- package/vendor/nanocodex-tools/tools/datasetContract.mjs +54 -0
- package/vendor/nanocodex-tools/tools/datasetEngine.mjs +1167 -0
- package/vendor/nanocodex-tools/tools/execution-contract.d.mts +5 -0
- package/vendor/nanocodex-tools/tools/execution-contract.mjs +63 -0
- package/vendor/nanocodex-tools/tools/hostedCatalog.d.mts +20 -0
- package/vendor/nanocodex-tools/tools/hostedCatalog.mjs +67 -0
- package/vendor/nanocodex-tools/tools/hostedMachine.d.mts +10 -0
- package/vendor/nanocodex-tools/tools/hostedMachine.mjs +56 -0
- package/vendor/nanocodex-tools/tools/just-bash-browser.d.mts +1 -0
- package/vendor/nanocodex-tools/tools/just-bash-browser.mjs +1 -0
- package/vendor/nanocodex-tools/tools/namedTool.d.mts +3 -0
- package/vendor/nanocodex-tools/tools/namedTool.mjs +3 -0
- package/vendor/nanocodex-tools/tools/nodeProcess.d.mts +10 -0
- package/vendor/nanocodex-tools/tools/nodeProcess.mjs +314 -0
- package/vendor/nanocodex-tools/tools/processOutput.mjs +56 -0
- package/vendor/nanocodex-tools/tools/repository-workspace.d.mts +55 -0
- package/vendor/nanocodex-tools/tools/repository-workspace.mjs +397 -0
- package/vendor/nanocodex-tools/tools/ssh.d.mts +56 -0
- package/vendor/nanocodex-tools/tools/ssh.mjs +503 -0
- package/vendor/nanocodex-tools/tools/standard.mjs +458 -0
- package/vendor/nanocodex-tools/tools/standardDescriptions.mjs +3 -0
- package/vendor/nanocodex-tools/tools/types.d.mts +83 -0
- package/vendor/nanocodex-tools/tools/workspace.d.mts +25 -0
- package/vendor/nanocodex-tools/tools/workspace.mjs +282 -0
- package/vendor/nanocodex-tools/tools/x.d.mts +30 -0
- package/vendor/nanocodex-tools/tools/x.mjs +91 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# Managed Nanocodex agents
|
|
2
|
+
|
|
3
|
+
`nanocodex/managed` is the administration and extended control-plane client for
|
|
4
|
+
account-owned Nanocodex agents. Application turns normally use
|
|
5
|
+
`Agent.create({ transport: Transport.managed(...), tools })` from
|
|
6
|
+
`nanocodex/node`, `nanocodex/browser`, or `nanocodex/host`, which returns the
|
|
7
|
+
same lifecycle shape as local OpenAI and host-managed transports.
|
|
8
|
+
|
|
9
|
+
In a browser, authentication uses the current origin's HttpOnly account cookie:
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
import { Agent } from "nanocodex/managed";
|
|
13
|
+
|
|
14
|
+
const agent = await Agent.create();
|
|
15
|
+
const turn = agent.turn.prompt({
|
|
16
|
+
input: "Inspect the repository and summarize it.",
|
|
17
|
+
idempotencyKey: crypto.randomUUID(),
|
|
18
|
+
});
|
|
19
|
+
const result = await turn.result();
|
|
20
|
+
console.log(result.finalMessage);
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
New managed agents may be created with an atomic settings object. Existing
|
|
24
|
+
agents retain their model and reasoning mode after their first accepted turn.
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
const astra = await Agent.create({
|
|
28
|
+
settings: {
|
|
29
|
+
model: "gpt-6-astra",
|
|
30
|
+
thinking: "high",
|
|
31
|
+
reasoningMode: "standard",
|
|
32
|
+
fastMode: false,
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
GPT-6 Astra accepts `low`, `medium`, `high`, `xhigh`, or `max` thinking; it
|
|
38
|
+
rejects `none`. Fast mode is deliberately opt-in and is unavailable for Astra
|
|
39
|
+
when the OpenAI project uses EU data residency.
|
|
40
|
+
|
|
41
|
+
On a server, provide the managed origin and an `ncx_live_...` account API key:
|
|
42
|
+
|
|
43
|
+
```js
|
|
44
|
+
const agent = await Agent.get(process.env.NANOCODEX_AGENT_ID, {
|
|
45
|
+
baseUrl: "https://nanocodex.example",
|
|
46
|
+
apiKey: process.env.NANOCODEX_API_KEY,
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The transport-facing constructor requires an explicit identity and never
|
|
51
|
+
infers creation from a missing ID:
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
import { Agent, Transport } from "nanocodex/node";
|
|
55
|
+
|
|
56
|
+
const created = await Agent.create({
|
|
57
|
+
transport: Transport.managed({
|
|
58
|
+
agent: { create: true },
|
|
59
|
+
baseUrl: "https://nanocodex.example",
|
|
60
|
+
apiKey: process.env.NANOCODEX_API_KEY,
|
|
61
|
+
}),
|
|
62
|
+
});
|
|
63
|
+
const existing = await Agent.create({
|
|
64
|
+
transport: Transport.managed({
|
|
65
|
+
agent: { id: process.env.NANOCODEX_AGENT_ID },
|
|
66
|
+
baseUrl: "https://nanocodex.example",
|
|
67
|
+
apiKey: process.env.NANOCODEX_API_KEY,
|
|
68
|
+
}),
|
|
69
|
+
});
|
|
70
|
+
await existing.session.shutdown(); // closes the client; never deletes the Agent
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The same account client can search all completed managed conversations without
|
|
74
|
+
opening an agent turn:
|
|
75
|
+
|
|
76
|
+
```js
|
|
77
|
+
const found = await Agent.findSessions(
|
|
78
|
+
{ query: "what did we decide about memory?", limit: 8 },
|
|
79
|
+
{ baseUrl: process.env.NANOCODEX_MANAGED_URL, apiKey: process.env.NANOCODEX_API_KEY },
|
|
80
|
+
);
|
|
81
|
+
const session = await Agent.readSession(
|
|
82
|
+
{
|
|
83
|
+
session_id: found.results[0].session_id,
|
|
84
|
+
turn_ids: [found.results[0].turn_id],
|
|
85
|
+
},
|
|
86
|
+
{ baseUrl: process.env.NANOCODEX_MANAGED_URL, apiKey: process.env.NANOCODEX_API_KEY },
|
|
87
|
+
);
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Both methods derive the account scope from the cookie or API key; no scope or user
|
|
91
|
+
identifier is accepted from the caller.
|
|
92
|
+
|
|
93
|
+
Hosted durable memory is account-owned and independent from session history. The
|
|
94
|
+
memory panel can list records and compare-and-swap delete one current key:
|
|
95
|
+
|
|
96
|
+
```js
|
|
97
|
+
const memories = await Agent.listMemories({
|
|
98
|
+
baseUrl: process.env.NANOCODEX_MANAGED_URL,
|
|
99
|
+
apiKey: process.env.NANOCODEX_API_KEY,
|
|
100
|
+
});
|
|
101
|
+
await Agent.deleteMemory(memories[0].key, {
|
|
102
|
+
baseUrl: process.env.NANOCODEX_MANAGED_URL,
|
|
103
|
+
apiKey: process.env.NANOCODEX_API_KEY,
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Managed agents access this same hosted store through their `memory` tool. It is
|
|
108
|
+
never mirrored into a browser, TUI, or other local persistence layer.
|
|
109
|
+
|
|
110
|
+
Account memory uses the same derived organization scope and supports scan, read,
|
|
111
|
+
put, and delete operations. Scan before writing so the service can reject
|
|
112
|
+
duplicates, and retain returned `{ id, version }` keys for compare-and-swap
|
|
113
|
+
updates:
|
|
114
|
+
|
|
115
|
+
```js
|
|
116
|
+
const scanned = await Agent.memory(
|
|
117
|
+
{ operation: "scan", query: "production deploy schedule" },
|
|
118
|
+
{ baseUrl: process.env.NANOCODEX_MANAGED_URL, apiKey: process.env.NANOCODEX_API_KEY },
|
|
119
|
+
);
|
|
120
|
+
const stored = await Agent.memory(
|
|
121
|
+
{ operation: "put", content: "Production deploys happen on Tuesdays." },
|
|
122
|
+
{ baseUrl: process.env.NANOCODEX_MANAGED_URL, apiKey: process.env.NANOCODEX_API_KEY },
|
|
123
|
+
);
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Browser account owners can read and rename their organization:
|
|
127
|
+
|
|
128
|
+
```js
|
|
129
|
+
const organization = await Agent.getOrganization();
|
|
130
|
+
await Agent.updateOrganization({ name: `${organization.name ?? "Personal"} workspace` });
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Memory accepts either account-cookie or API-key authentication. Organization
|
|
134
|
+
metadata and mutation remain subject to the server's principal and owner policy;
|
|
135
|
+
the client sends supplied credentials without weakening that policy.
|
|
136
|
+
|
|
137
|
+
`Agent.list()` returns agent handles, `agent.state()` reads current state, and
|
|
138
|
+
`agent.delete()` removes the agent and its retained state. `agent.events.watch`
|
|
139
|
+
is an async iterator over durable events. Pass its last decimal `cursor` to a
|
|
140
|
+
later watcher to resume strictly after the acknowledged event. Network endings
|
|
141
|
+
reconnect automatically from that cursor. Watchers and independently awaitable
|
|
142
|
+
turn results on one agent handle share one replayable event connection; each
|
|
143
|
+
subscriber keeps its own cursor, so consuming one never steals another's events.
|
|
144
|
+
Rapid `turn.steer()` calls on one turn handle are sent in invocation order.
|
|
145
|
+
`turn.cancel()` bypasses pending steering requests, so Stop can interrupt them.
|
|
146
|
+
Pass `cursor: "latest"` to attach atomically at the durable head without
|
|
147
|
+
replaying retained history; a history page can then hydrate independently.
|
|
148
|
+
|
|
149
|
+
Returning browser clients may use `Agent.open(id)` to construct a retained
|
|
150
|
+
handle without a preliminary state request. The first operation on that handle
|
|
151
|
+
still verifies account ownership at the managed service boundary. Use
|
|
152
|
+
`Agent.get(id)` when an eager existence check is part of the caller's workflow.
|
|
153
|
+
|
|
154
|
+
The managed API never accepts model-provider credentials, egress bindings,
|
|
155
|
+
runtime environment objects, credential grants, or arbitrary request headers.
|
|
156
|
+
|
|
157
|
+
## Cron triggers
|
|
158
|
+
|
|
159
|
+
Schedules belong to an existing managed agent and run without an open client.
|
|
160
|
+
Use a stable trigger ID to create or replace a schedule idempotently:
|
|
161
|
+
|
|
162
|
+
```js
|
|
163
|
+
const agent = await Agent.get(agentId, { baseUrl, apiKey });
|
|
164
|
+
const morning = {
|
|
165
|
+
cron: "0 7 * * MON-FRI",
|
|
166
|
+
timezone: "Europe/Athens",
|
|
167
|
+
input: "Review my running agents and summarize anything that needs attention.",
|
|
168
|
+
};
|
|
169
|
+
await agent.triggers.put("morning-review", morning);
|
|
170
|
+
await agent.triggers.list();
|
|
171
|
+
await agent.triggers.get("morning-review");
|
|
172
|
+
await agent.triggers.put("morning-review", { ...morning, enabled: false }); // pause
|
|
173
|
+
await agent.triggers.put("morning-review", morning); // resume
|
|
174
|
+
await agent.triggers.delete("morning-review");
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
| Method | Route | Result |
|
|
178
|
+
| --- | --- | --- |
|
|
179
|
+
| GET | `/v1/agents/:agent/triggers` | `{ data: [...] }` |
|
|
180
|
+
| GET | `/v1/agents/:agent/triggers/:id` | Trigger or 404 |
|
|
181
|
+
| PUT | `/v1/agents/:agent/triggers/:id` | Create (201) or replace (200) |
|
|
182
|
+
| DELETE | `/v1/agents/:agent/triggers/:id` | Idempotent deletion (204) |
|
|
183
|
+
|
|
184
|
+
The managed-agent web composer also has a **Schedules** button. It opens the
|
|
185
|
+
same account-authenticated API: create or edit a prompt and cron expression,
|
|
186
|
+
choose an IANA time zone, inspect the next dispatch time, pause/resume, or
|
|
187
|
+
delete a schedule. The last-dispatched time is not a completion receipt; read
|
|
188
|
+
the conversation for the result. The ephemeral homepage agent has no schedules.
|
|
189
|
+
|
|
190
|
+
PUT takes `{ cron, input, timezone?, enabled?, session_mode? }`. Expressions have five fields
|
|
191
|
+
(minute, hour, day of month, month, day of week), supporting numeric values,
|
|
192
|
+
lists, ranges, steps, and month/day names. The time zone defaults to UTC and
|
|
193
|
+
accepts IANA names. Local times follow daylight saving transitions. Seconds,
|
|
194
|
+
macros, and random `H` fields are rejected. Inputs are text up to 64 KiB;
|
|
195
|
+
there can be at most 32 triggers per agent. IDs use 1–64 letters, digits,
|
|
196
|
+
underscores, or hyphens. PUT is a full replacement; an identical retry preserves
|
|
197
|
+
the next occurrence. A changed configuration starts from the next matching time.
|
|
198
|
+
|
|
199
|
+
`session_mode: "new"` (the default for new configurations) creates a fresh managed
|
|
200
|
+
session for every occurrence. It copies the source agent's model settings at
|
|
201
|
+
dispatch time, but no conversation history or schedules. Account permissions,
|
|
202
|
+
connectors, and account memory still belong to the same account. Fresh sessions
|
|
203
|
+
run independently even when the source conversation is busy, and appear in the
|
|
204
|
+
normal agent list. Choose **New session each time** in the Schedules dialog.
|
|
205
|
+
|
|
206
|
+
`session_mode: "continue"` submits a turn to the existing conversation, retaining
|
|
207
|
+
its history. Choose **Continue this conversation** in the dialog. Schedules saved
|
|
208
|
+
before modes were introduced retain this behavior. Omitting the mode when
|
|
209
|
+
updating an existing schedule preserves its mode, including for older clients.
|
|
210
|
+
Set `session_mode` explicitly to switch modes.
|
|
211
|
+
|
|
212
|
+
Durable Object alarms dispatch occurrences. Continued turns advance the schedule
|
|
213
|
+
atomically with turn admission. Fresh runs use a durable outbox and deterministic
|
|
214
|
+
session/turn IDs: delivery retries reuse the same session without duplicating
|
|
215
|
+
its turn. Only one undelivered occurrence per schedule is retained. Inspect
|
|
216
|
+
`last_turn_id` on `last_agent_id` through the normal turn and event APIs, or use
|
|
217
|
+
**Open run** in the UI. Times are Unix milliseconds; `last_run_at` is the scheduled
|
|
218
|
+
time of the last accepted occurrence, and `next_run_at` is null while paused.
|
|
219
|
+
Last dispatched does not mean the model response has completed.
|
|
220
|
+
|
|
221
|
+
Missed ticks coalesce; they are not replayed individually. In continue mode,
|
|
222
|
+
unfinished work or a failed event stream causes an occurrence to be skipped and
|
|
223
|
+
recorded in `last_skipped_at`. New-session mode does not skip because the source
|
|
224
|
+
is busy. Pausing or deleting prevents future dispatches; a turn already accepted
|
|
225
|
+
or a fresh session already claimed for delivery still completes. Resume does
|
|
226
|
+
not backfill. Deleting the source removes its schedules and pending deliveries;
|
|
227
|
+
sessions already created remain independent conversations.
|
|
228
|
+
|
|
229
|
+
Read requests require `agents:read`; writes require `agents:write`, and PUT also
|
|
230
|
+
requires `tools:use`. The usual ownership and browser-origin checks apply.
|
|
231
|
+
Triggers are account-owned standing instructions with the creator's capability
|
|
232
|
+
scope, and persist after the creating API key or browser session ends. Connect
|
|
233
|
+
grants and multiplayer rooms cannot create schedules. Delete the trigger to
|
|
234
|
+
revoke its standing instruction. Provider credentials are resolved by the usual
|
|
235
|
+
managed execution path and are never stored in trigger definitions or returned
|
|
236
|
+
by these endpoints.
|
|
237
|
+
|
|
238
|
+
Deleting an agent removes its triggers. Portable durability export currently
|
|
239
|
+
returns `409 cron_triggers_present` while any trigger or pending delivery exists: delete
|
|
240
|
+
triggers and let claimed deliveries finish before transfer, then recreate schedules at the destination. This avoids
|
|
241
|
+
silently dropping schedules or running the same schedule on two agents.
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { ManagedBrowserVoice } from "../pkg-web/nanocodex.js";
|
|
2
|
+
import { initializeBrowserEngine } from "../browser/engine.mjs";
|
|
3
|
+
import {
|
|
4
|
+
cancelManagedTurn,
|
|
5
|
+
prefetchManagedRealtime,
|
|
6
|
+
routeManagedRealtime,
|
|
7
|
+
startManagedRealtime,
|
|
8
|
+
stopManagedRealtime,
|
|
9
|
+
} from "./internal.mjs";
|
|
10
|
+
|
|
11
|
+
/** @internal Adapts the Rust-owned protocol core to one remote managed Agent. */
|
|
12
|
+
export async function createManagedBrowserVoice(agent, voice, options = {}) {
|
|
13
|
+
await initializeBrowserEngine(options);
|
|
14
|
+
const raw = new ManagedBrowserVoice(voice);
|
|
15
|
+
const voiceSessionId = uuidV7();
|
|
16
|
+
const startOperationId = crypto.randomUUID();
|
|
17
|
+
const stopOperationId = crypto.randomUUID();
|
|
18
|
+
const tailOperationId = crypto.randomUUID();
|
|
19
|
+
const delegationOperations = new Map();
|
|
20
|
+
let startedTurnId;
|
|
21
|
+
let activeTurnId;
|
|
22
|
+
let routePending = false;
|
|
23
|
+
let pendingEvents = [];
|
|
24
|
+
let prefetchTimer;
|
|
25
|
+
const prefetchAbort = new AbortController();
|
|
26
|
+
|
|
27
|
+
function observe(value) {
|
|
28
|
+
if (activeTurnId === undefined || value?.turnId !== activeTurnId) return undefined;
|
|
29
|
+
const effects = raw.agentEvent(JSON.stringify(value.event));
|
|
30
|
+
if (isTerminalAgentEvent(value.event)) {
|
|
31
|
+
if (startedTurnId === activeTurnId) startedTurnId = undefined;
|
|
32
|
+
activeTurnId = undefined;
|
|
33
|
+
}
|
|
34
|
+
return effects;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function adoptRoute(routed) {
|
|
38
|
+
if (typeof routed.turn_id !== "string") return [];
|
|
39
|
+
activeTurnId = routed.turn_id;
|
|
40
|
+
if (routed.route === "started") startedTurnId = routed.turn_id;
|
|
41
|
+
const buffered = pendingEvents;
|
|
42
|
+
pendingEvents = [];
|
|
43
|
+
return buffered.map(observe).filter((effects) => effects !== undefined);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
configure: (settings) => raw.configure(settings),
|
|
48
|
+
appendSpeech: (text) => raw.appendSpeech(text),
|
|
49
|
+
appendText: (role, text) => raw.appendText(role, text),
|
|
50
|
+
appendContext: (text) => raw.appendContext(text),
|
|
51
|
+
parallelStartup: true,
|
|
52
|
+
async start() {
|
|
53
|
+
const started = await startManagedRealtime(agent, voiceSessionId, startOperationId);
|
|
54
|
+
raw.start(JSON.stringify(started.context));
|
|
55
|
+
},
|
|
56
|
+
callBody(sdp) {
|
|
57
|
+
const envelope = JSON.parse(raw.callBody(sdp, voiceSessionId));
|
|
58
|
+
envelope.managed_agent_id = agent.id;
|
|
59
|
+
return JSON.stringify(envelope);
|
|
60
|
+
},
|
|
61
|
+
completeCall: (body, location) => raw.completeCall(body, location),
|
|
62
|
+
sidebandUrl(callId) {
|
|
63
|
+
const path = raw.sidebandUrl(callId, voiceSessionId);
|
|
64
|
+
const url = new URL(path, globalThis.location?.href ?? "http://localhost");
|
|
65
|
+
url.searchParams.set("managed_agent_id", agent.id);
|
|
66
|
+
return `${url.pathname}${url.search}`;
|
|
67
|
+
},
|
|
68
|
+
sidebandOpened: () => raw.sidebandOpened(),
|
|
69
|
+
sidebandClosed: (connectedMs) => raw.sidebandClosed(connectedMs),
|
|
70
|
+
framesSent: (count) => raw.framesSent(count),
|
|
71
|
+
requiresAgentAdmission: (payload) => raw.requiresAgentAdmission(payload),
|
|
72
|
+
async realtimeMessage(payload) {
|
|
73
|
+
const update = JSON.parse(raw.realtimeMessage(payload));
|
|
74
|
+
if (update.prefetch) {
|
|
75
|
+
clearTimeout(prefetchTimer);
|
|
76
|
+
prefetchTimer = setTimeout(() => {
|
|
77
|
+
void prefetchManagedRealtime(agent, voiceSessionId, update.prefetch.query,
|
|
78
|
+
AbortSignal.any([prefetchAbort.signal, AbortSignal.timeout(10_000)])).catch(() => {});
|
|
79
|
+
}, update.prefetch.debounce_ms);
|
|
80
|
+
}
|
|
81
|
+
if (typeof update.delegation === "string" && update.delegation.trim()) {
|
|
82
|
+
clearTimeout(prefetchTimer);
|
|
83
|
+
const delegationId = managedDelegationId(payload);
|
|
84
|
+
let operationId = delegationId && delegationOperations.get(delegationId);
|
|
85
|
+
if (!operationId) {
|
|
86
|
+
operationId = crypto.randomUUID();
|
|
87
|
+
if (delegationId) delegationOperations.set(delegationId, operationId);
|
|
88
|
+
}
|
|
89
|
+
routePending = true;
|
|
90
|
+
try {
|
|
91
|
+
const bufferedEffects = adoptRoute(await routeManagedRealtime(
|
|
92
|
+
agent,
|
|
93
|
+
voiceSessionId,
|
|
94
|
+
operationId,
|
|
95
|
+
update.delegation,
|
|
96
|
+
));
|
|
97
|
+
update.effects = mergeVoiceEffects(update.effects, bufferedEffects);
|
|
98
|
+
} finally {
|
|
99
|
+
routePending = false;
|
|
100
|
+
if (activeTurnId === undefined) pendingEvents = [];
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return JSON.stringify(update.effects);
|
|
104
|
+
},
|
|
105
|
+
agentEvent(envelope) {
|
|
106
|
+
const value = typeof envelope === "string" ? JSON.parse(envelope) : envelope;
|
|
107
|
+
if (value?.event?.type === "managed.voice.context") {
|
|
108
|
+
return raw.managedEvent(JSON.stringify(value));
|
|
109
|
+
}
|
|
110
|
+
if (routePending && value?.turnId !== activeTurnId) {
|
|
111
|
+
pendingEvents.push(value);
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
return observe(value);
|
|
115
|
+
},
|
|
116
|
+
flush: (finalChunk) => raw.flush(finalChunk),
|
|
117
|
+
async stop() {
|
|
118
|
+
clearTimeout(prefetchTimer);
|
|
119
|
+
prefetchAbort.abort();
|
|
120
|
+
const update = JSON.parse(raw.stop());
|
|
121
|
+
let routeFailure;
|
|
122
|
+
if (typeof update.delegation === "string" && update.delegation.trim()) {
|
|
123
|
+
try {
|
|
124
|
+
await routeManagedRealtime(
|
|
125
|
+
agent,
|
|
126
|
+
voiceSessionId,
|
|
127
|
+
tailOperationId,
|
|
128
|
+
update.delegation,
|
|
129
|
+
);
|
|
130
|
+
} catch (error) {
|
|
131
|
+
routeFailure = error;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
let stopFailure;
|
|
135
|
+
try {
|
|
136
|
+
await stopManagedRealtime(agent, voiceSessionId, stopOperationId);
|
|
137
|
+
} catch (error) {
|
|
138
|
+
stopFailure = error;
|
|
139
|
+
}
|
|
140
|
+
startedTurnId = undefined;
|
|
141
|
+
activeTurnId = undefined;
|
|
142
|
+
pendingEvents = [];
|
|
143
|
+
if (routeFailure !== undefined) throw routeFailure;
|
|
144
|
+
if (stopFailure !== undefined) throw stopFailure;
|
|
145
|
+
return JSON.stringify(update.effects);
|
|
146
|
+
},
|
|
147
|
+
async cancel() {
|
|
148
|
+
if (!startedTurnId) return false;
|
|
149
|
+
const turnId = startedTurnId;
|
|
150
|
+
await cancelManagedTurn(agent, turnId);
|
|
151
|
+
if (startedTurnId === turnId) startedTurnId = undefined;
|
|
152
|
+
return true;
|
|
153
|
+
},
|
|
154
|
+
preferredPhysicalInput: (current, labels) => raw.preferredPhysicalInput(current, labels),
|
|
155
|
+
free: () => { clearTimeout(prefetchTimer); prefetchAbort.abort(); raw.free(); },
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function uuidV7() {
|
|
160
|
+
if (typeof globalThis.crypto?.getRandomValues !== "function") {
|
|
161
|
+
throw new Error("managed browser voice requires crypto.getRandomValues()");
|
|
162
|
+
}
|
|
163
|
+
const bytes = globalThis.crypto.getRandomValues(new Uint8Array(16));
|
|
164
|
+
let timestamp = Date.now();
|
|
165
|
+
for (let index = 5; index >= 0; index -= 1) {
|
|
166
|
+
bytes[index] = timestamp % 256;
|
|
167
|
+
timestamp = Math.floor(timestamp / 256);
|
|
168
|
+
}
|
|
169
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x70;
|
|
170
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
|
171
|
+
const encoded = [...bytes].map((byte) => byte.toString(16).padStart(2, "0"));
|
|
172
|
+
return `${encoded.slice(0, 4).join("")}-${encoded.slice(4, 6).join("")}-${encoded.slice(6, 8).join("")}-${encoded.slice(8, 10).join("")}-${encoded.slice(10).join("")}`;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function managedDelegationId(payload) {
|
|
176
|
+
try {
|
|
177
|
+
const event = typeof payload === "string" ? JSON.parse(payload) : payload;
|
|
178
|
+
return typeof event?.item?.id === "string" ? event.item.id : undefined;
|
|
179
|
+
} catch {
|
|
180
|
+
return undefined;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function isTerminalAgentEvent(event) {
|
|
185
|
+
return event?.type === "run.completed" || event?.type === "run.failed"
|
|
186
|
+
|| event?.type === "run.cancelled" || event?.type === "turn_failed";
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function mergeVoiceEffects(base, encoded) {
|
|
190
|
+
const effects = [base, ...encoded.map((value) => (
|
|
191
|
+
typeof value === "string" ? JSON.parse(value) : value
|
|
192
|
+
))].filter((value) => value && typeof value === "object");
|
|
193
|
+
if (effects.length === 0) return base;
|
|
194
|
+
return {
|
|
195
|
+
...effects[0],
|
|
196
|
+
playback_enabled: effects.findLast((value) => value.playback_enabled !== undefined)?.playback_enabled,
|
|
197
|
+
acknowledge_frames: effects.some((value) => value.acknowledge_frames),
|
|
198
|
+
frames: effects.flatMap((value) => value.frames ?? []),
|
|
199
|
+
transcripts: effects.flatMap((value) => value.transcripts ?? []),
|
|
200
|
+
schedule_flush: effects.some((value) => value.schedule_flush),
|
|
201
|
+
};
|
|
202
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export * as Agent from "./Agent.mjs";
|
|
2
|
+
export { ManagedError } from "./ManagedError.mjs";
|
|
3
|
+
export type {
|
|
4
|
+
Agent as ManagedAgent,
|
|
5
|
+
CronTrigger as ManagedCronTrigger,
|
|
6
|
+
CronTriggerConfig as ManagedCronTriggerConfig,
|
|
7
|
+
CreateOptions as ManagedCreateOptions,
|
|
8
|
+
CreateSettings as ManagedCreateSettings,
|
|
9
|
+
Event as ManagedEvent,
|
|
10
|
+
EventData as ManagedEventData,
|
|
11
|
+
HistoryCitation as ManagedHistoryCitation,
|
|
12
|
+
FindSessionsResponse as ManagedFindSessionsResponse,
|
|
13
|
+
ReadSessionResponse as ManagedReadSessionResponse,
|
|
14
|
+
MemoryKey as ManagedMemoryKey,
|
|
15
|
+
MemoryRecord as ManagedMemoryRecord,
|
|
16
|
+
MemoryResult as ManagedMemoryResult,
|
|
17
|
+
Organization as ManagedOrganization,
|
|
18
|
+
Turn as ManagedTurn,
|
|
19
|
+
TurnResult as ManagedTurnResult,
|
|
20
|
+
} from "./Agent.mjs";
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
const managedAgents = new WeakMap();
|
|
2
|
+
|
|
3
|
+
/** @internal Retains the authenticated client without exposing it on the public Agent handle. */
|
|
4
|
+
export function registerManagedAgent(agent, client, id, options = {}) {
|
|
5
|
+
managedAgents.set(agent, {
|
|
6
|
+
client,
|
|
7
|
+
eventAgent: agent,
|
|
8
|
+
id,
|
|
9
|
+
...(options.voiceTransport === undefined ? {} : { voiceTransport: options.voiceTransport }),
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** @internal Retains managed lifecycle ownership for a capability-bound Agent projection. */
|
|
14
|
+
export function registerManagedAgentAlias(agent, source, options = {}) {
|
|
15
|
+
const state = managedAgent(source);
|
|
16
|
+
managedAgents.set(agent, {
|
|
17
|
+
...state,
|
|
18
|
+
...(options.voiceTransport === undefined ? {} : { voiceTransport: options.voiceTransport }),
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** @internal Resolves an optional browser media transport owned by an Agent projection. */
|
|
23
|
+
export function managedBrowserVoiceTransport(agent) {
|
|
24
|
+
return managedAgent(agent).voiceTransport;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** @internal Starts the canonical Realtime lifecycle on the selected durable Agent. */
|
|
28
|
+
export function startManagedRealtime(agent, voiceSessionId, operationId) {
|
|
29
|
+
const { client, id } = managedAgent(agent);
|
|
30
|
+
return client.json(`${agentPath(id)}/realtime/start`, {
|
|
31
|
+
method: "POST",
|
|
32
|
+
body: JSON.stringify({
|
|
33
|
+
voice_session_id: voiceSessionId,
|
|
34
|
+
operation_id: operationId,
|
|
35
|
+
}),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** @internal Warms exact-query retrieval without admitting an Agent turn. */
|
|
40
|
+
export function prefetchManagedRealtime(agent, voiceSessionId, query, signal) {
|
|
41
|
+
const { client, id } = managedAgent(agent);
|
|
42
|
+
return client.json(`${agentPath(id)}/realtime/prefetch`, {
|
|
43
|
+
method: "POST", signal,
|
|
44
|
+
body: JSON.stringify({ voice_session_id: voiceSessionId, query }),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** @internal Atomically routes one Rust-formatted voice delegation on the durable Agent. */
|
|
49
|
+
export function routeManagedRealtime(agent, voiceSessionId, operationId, input) {
|
|
50
|
+
const { client, id } = managedAgent(agent);
|
|
51
|
+
return client.json(`${agentPath(id)}/realtime/delegate`, {
|
|
52
|
+
method: "POST",
|
|
53
|
+
body: JSON.stringify({
|
|
54
|
+
voice_session_id: voiceSessionId,
|
|
55
|
+
operation_id: operationId,
|
|
56
|
+
input,
|
|
57
|
+
}),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** @internal Ends the canonical Realtime lifecycle on the selected durable Agent. */
|
|
62
|
+
export function stopManagedRealtime(agent, voiceSessionId, operationId) {
|
|
63
|
+
const { client, id } = managedAgent(agent);
|
|
64
|
+
return client.json(`${agentPath(id)}/realtime/stop`, {
|
|
65
|
+
method: "POST",
|
|
66
|
+
body: JSON.stringify({
|
|
67
|
+
voice_session_id: voiceSessionId,
|
|
68
|
+
operation_id: operationId,
|
|
69
|
+
}),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** @internal Cancels only a managed turn that this voice session started. */
|
|
74
|
+
export function cancelManagedTurn(agent, turnId) {
|
|
75
|
+
const { client, id } = managedAgent(agent);
|
|
76
|
+
return client.json(`${agentPath(id)}/turns/${encodeURIComponent(turnId)}/cancel`, {
|
|
77
|
+
method: "POST",
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** @internal Streams only canonical typed Agent events from the durable envelope log. */
|
|
82
|
+
export function observeManagedAgentEvents(agent, listener) {
|
|
83
|
+
if (typeof listener !== "function") throw new TypeError("managed voice event listener must be a function");
|
|
84
|
+
const controller = new AbortController();
|
|
85
|
+
void (async () => {
|
|
86
|
+
try {
|
|
87
|
+
const { eventAgent } = managedAgent(agent);
|
|
88
|
+
for await (const envelope of eventAgent.events.watch({
|
|
89
|
+
cursor: "latest",
|
|
90
|
+
signal: controller.signal,
|
|
91
|
+
})) {
|
|
92
|
+
if (controller.signal.aborted) return;
|
|
93
|
+
if (envelope.data.type === "event") {
|
|
94
|
+
listener(Object.freeze({ event: envelope.data.event, turnId: envelope.turnId, cursor: envelope.cursor }));
|
|
95
|
+
} else if (envelope.data.type === "turn_failed") {
|
|
96
|
+
listener(Object.freeze({ event: envelope.data, turnId: envelope.turnId, cursor: envelope.cursor }));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
} catch (error) {
|
|
100
|
+
if (!controller.signal.aborted) reportError(error);
|
|
101
|
+
}
|
|
102
|
+
})();
|
|
103
|
+
return () => controller.abort();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function managedAgent(agent) {
|
|
107
|
+
const state = managedAgents.get(agent);
|
|
108
|
+
if (!state) throw new TypeError("voice requires a managed Nanocodex Agent");
|
|
109
|
+
return state;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function agentPath(id) {
|
|
113
|
+
return `/v1/agents/${encodeURIComponent(id)}`;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function reportError(error) {
|
|
117
|
+
if (typeof globalThis.reportError === "function") globalThis.reportError(error);
|
|
118
|
+
else console.error(error);
|
|
119
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AgentLifecycle,
|
|
3
|
+
AgentOptions,
|
|
4
|
+
CodeEvaluator,
|
|
5
|
+
DefaultAgent,
|
|
6
|
+
DurabilityStore,
|
|
7
|
+
McpServers,
|
|
8
|
+
ToolConfiguration,
|
|
9
|
+
} from "../types.mjs";
|
|
10
|
+
import type { ManagedTransport, ResponsesTransport } from "./Transport.mjs";
|
|
11
|
+
import type { Tool as SubagentTool } from "../runtime/subagents.mjs";
|
|
12
|
+
import type { Workspace } from "./workspace.mjs";
|
|
13
|
+
import type { Tools } from "../tools/Tools.mjs";
|
|
14
|
+
|
|
15
|
+
export type Agent = DefaultAgent;
|
|
16
|
+
type ToolExposureOptions =
|
|
17
|
+
| { mcp?: false | undefined; toolMode?: "code" | "direct" | undefined }
|
|
18
|
+
| { mcp: McpServers; toolMode?: "code" | undefined };
|
|
19
|
+
|
|
20
|
+
/** Creates a Node-hosted Rust/WASM Agent. */
|
|
21
|
+
export function create(options: create.ManagedOptions): Promise<AgentLifecycle>;
|
|
22
|
+
export function create(options: create.Options): Promise<create.ReturnType>;
|
|
23
|
+
export declare namespace create {
|
|
24
|
+
type ManagedOptions = Readonly<{
|
|
25
|
+
transport: ManagedTransport;
|
|
26
|
+
tools?: Tools | undefined;
|
|
27
|
+
}>;
|
|
28
|
+
type Options = AgentOptions & ToolExposureOptions & {
|
|
29
|
+
/** Enable built-in subagents (default true). False conflicts with Subagents.create(). */
|
|
30
|
+
subagents?: boolean | undefined;
|
|
31
|
+
codeEvaluator?: CodeEvaluator | undefined;
|
|
32
|
+
/** Caller-owned rooted filesystem mounted through standard workspace tools. */
|
|
33
|
+
filesystem?: Workspace | undefined;
|
|
34
|
+
module?: unknown;
|
|
35
|
+
transport: ResponsesTransport;
|
|
36
|
+
} & (
|
|
37
|
+
| {
|
|
38
|
+
durability?: undefined;
|
|
39
|
+
durabilityId?: undefined;
|
|
40
|
+
tools?: ToolConfiguration<SubagentTool> | undefined;
|
|
41
|
+
}
|
|
42
|
+
| {
|
|
43
|
+
durability: DurabilityStore;
|
|
44
|
+
durabilityId: string;
|
|
45
|
+
/** The root remains durable; clean subagent children are in-memory. */
|
|
46
|
+
tools?: ToolConfiguration<SubagentTool> | undefined;
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
type ReturnType = Agent;
|
|
50
|
+
}
|