@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.
Files changed (276) hide show
  1. package/LICENSE +65 -0
  2. package/NOTICE +2 -0
  3. package/README.md +182 -0
  4. package/THIRD_PARTY_NOTICES.md +29 -0
  5. package/cordis.patch.yml +52 -0
  6. package/dist/index.d.ts +435 -0
  7. package/dist/index.js +3405 -0
  8. package/dist/standard-preset.d.ts +7 -0
  9. package/dist/standard-preset.js +25 -0
  10. package/engine-release.json +14 -0
  11. package/package.json +119 -0
  12. package/presets/standard/agent.cordis.yml +6 -0
  13. package/presets/standard/preset.yml +2 -0
  14. package/vendor/nanocodex/README.md +1344 -0
  15. package/vendor/nanocodex/actions/events.d.mts +10 -0
  16. package/vendor/nanocodex/actions/events.mjs +163 -0
  17. package/vendor/nanocodex/actions/index.d.mts +13 -0
  18. package/vendor/nanocodex/actions/index.mjs +35 -0
  19. package/vendor/nanocodex/actions/session.d.mts +66 -0
  20. package/vendor/nanocodex/actions/session.mjs +59 -0
  21. package/vendor/nanocodex/actions/turn.d.mts +59 -0
  22. package/vendor/nanocodex/actions/turn.mjs +37 -0
  23. package/vendor/nanocodex/actions/voice.d.mts +22 -0
  24. package/vendor/nanocodex/actions/voice.mjs +50 -0
  25. package/vendor/nanocodex/browser/Agent.d.mts +55 -0
  26. package/vendor/nanocodex/browser/Agent.mjs +11 -0
  27. package/vendor/nanocodex/browser/ChatGptSubscription.d.mts +7 -0
  28. package/vendor/nanocodex/browser/ChatGptSubscription.mjs +19 -0
  29. package/vendor/nanocodex/browser/InlineAgent.mjs +266 -0
  30. package/vendor/nanocodex/browser/Transport.d.mts +74 -0
  31. package/vendor/nanocodex/browser/Transport.mjs +61 -0
  32. package/vendor/nanocodex/browser/Voice.d.mts +71 -0
  33. package/vendor/nanocodex/browser/Voice.mjs +291 -0
  34. package/vendor/nanocodex/browser/VoiceSession.mjs +688 -0
  35. package/vendor/nanocodex/browser/WorkerAgent.d.mts +65 -0
  36. package/vendor/nanocodex/browser/WorkerAgent.mjs +1472 -0
  37. package/vendor/nanocodex/browser/agent.worker.mjs +3 -0
  38. package/vendor/nanocodex/browser/config.d.mts +36 -0
  39. package/vendor/nanocodex/browser/config.mjs +439 -0
  40. package/vendor/nanocodex/browser/engine.mjs +13 -0
  41. package/vendor/nanocodex/browser/harness.mjs +55 -0
  42. package/vendor/nanocodex/browser/host.d.mts +83 -0
  43. package/vendor/nanocodex/browser/host.mjs +555 -0
  44. package/vendor/nanocodex/browser/hostManagedWebSocket.d.mts +14 -0
  45. package/vendor/nanocodex/browser/hostManagedWebSocket.mjs +110 -0
  46. package/vendor/nanocodex/browser/index.d.mts +92 -0
  47. package/vendor/nanocodex/browser/index.mjs +23 -0
  48. package/vendor/nanocodex/browser/indexeddb-durability-store.mjs +197 -0
  49. package/vendor/nanocodex/browser/workspace.d.mts +16 -0
  50. package/vendor/nanocodex/browser/workspace.mjs +107 -0
  51. package/vendor/nanocodex/cloud/Client.d.mts +83 -0
  52. package/vendor/nanocodex/cloud/Client.mjs +231 -0
  53. package/vendor/nanocodex/cloud/Decorator.d.mts +31 -0
  54. package/vendor/nanocodex/cloud/Decorator.mjs +37 -0
  55. package/vendor/nanocodex/cloud/Dialog.d.mts +113 -0
  56. package/vendor/nanocodex/cloud/Dialog.mjs +366 -0
  57. package/vendor/nanocodex/cloud/Errors.d.mts +22 -0
  58. package/vendor/nanocodex/cloud/Errors.mjs +39 -0
  59. package/vendor/nanocodex/cloud/Principal.d.mts +26 -0
  60. package/vendor/nanocodex/cloud/Principal.mjs +88 -0
  61. package/vendor/nanocodex/cloud/RemoteProvider.mjs +88 -0
  62. package/vendor/nanocodex/cloud/Transport.d.mts +47 -0
  63. package/vendor/nanocodex/cloud/Transport.mjs +454 -0
  64. package/vendor/nanocodex/cloud/actions/account.d.mts +9 -0
  65. package/vendor/nanocodex/cloud/actions/account.mjs +19 -0
  66. package/vendor/nanocodex/cloud/actions/agent.d.mts +18 -0
  67. package/vendor/nanocodex/cloud/actions/agent.mjs +428 -0
  68. package/vendor/nanocodex/cloud/actions/connection.d.mts +133 -0
  69. package/vendor/nanocodex/cloud/actions/connection.mjs +580 -0
  70. package/vendor/nanocodex/cloud/actions/grant.d.mts +10 -0
  71. package/vendor/nanocodex/cloud/actions/grant.mjs +12 -0
  72. package/vendor/nanocodex/cloud/actions/index.d.mts +7 -0
  73. package/vendor/nanocodex/cloud/actions/index.mjs +7 -0
  74. package/vendor/nanocodex/cloud/actions/machineUsd.d.mts +23 -0
  75. package/vendor/nanocodex/cloud/actions/machineUsd.mjs +37 -0
  76. package/vendor/nanocodex/cloud/actions/model.d.mts +12 -0
  77. package/vendor/nanocodex/cloud/actions/model.mjs +50 -0
  78. package/vendor/nanocodex/cloud/actions/mpp.d.mts +28 -0
  79. package/vendor/nanocodex/cloud/actions/mpp.mjs +39 -0
  80. package/vendor/nanocodex/cloud/index.d.mts +30 -0
  81. package/vendor/nanocodex/cloud/index.mjs +9 -0
  82. package/vendor/nanocodex/cloud/internal.mjs +533 -0
  83. package/vendor/nanocodex/cloud/mercator.mjs +108 -0
  84. package/vendor/nanocodex/cloud/server/HostPrincipal.d.mts +34 -0
  85. package/vendor/nanocodex/cloud/server/HostPrincipal.mjs +202 -0
  86. package/vendor/nanocodex/cloud/server/index.d.mts +1 -0
  87. package/vendor/nanocodex/cloud/server/index.mjs +1 -0
  88. package/vendor/nanocodex/cloud/types.d.mts +211 -0
  89. package/vendor/nanocodex/cloudflare/Agent.d.mts +133 -0
  90. package/vendor/nanocodex/cloudflare/Agent.mjs +811 -0
  91. package/vendor/nanocodex/cloudflare/egress-subject.mjs +19 -0
  92. package/vendor/nanocodex/cloudflare/egress.d.mts +41 -0
  93. package/vendor/nanocodex/cloudflare/egress.mjs +119 -0
  94. package/vendor/nanocodex/cloudflare/event-socket.mjs +316 -0
  95. package/vendor/nanocodex/cloudflare/index.d.mts +7 -0
  96. package/vendor/nanocodex/cloudflare/index.mjs +6 -0
  97. package/vendor/nanocodex/host/Agent.d.mts +55 -0
  98. package/vendor/nanocodex/host/Agent.mjs +1 -0
  99. package/vendor/nanocodex/host/index.d.mts +82 -0
  100. package/vendor/nanocodex/host/index.mjs +10 -0
  101. package/vendor/nanocodex/index.d.mts +81 -0
  102. package/vendor/nanocodex/index.mjs +12 -0
  103. package/vendor/nanocodex/internal.mjs +1275 -0
  104. package/vendor/nanocodex/managed/Agent.d.mts +380 -0
  105. package/vendor/nanocodex/managed/Agent.mjs +1694 -0
  106. package/vendor/nanocodex/managed/ManagedError.d.mts +9 -0
  107. package/vendor/nanocodex/managed/ManagedError.mjs +8 -0
  108. package/vendor/nanocodex/managed/README.md +241 -0
  109. package/vendor/nanocodex/managed/Voice.mjs +202 -0
  110. package/vendor/nanocodex/managed/index.d.mts +20 -0
  111. package/vendor/nanocodex/managed/index.mjs +2 -0
  112. package/vendor/nanocodex/managed/internal.mjs +119 -0
  113. package/vendor/nanocodex/node/Agent.d.mts +50 -0
  114. package/vendor/nanocodex/node/Agent.mjs +203 -0
  115. package/vendor/nanocodex/node/ChatGptSubscription.d.mts +9 -0
  116. package/vendor/nanocodex/node/ChatGptSubscription.mjs +17 -0
  117. package/vendor/nanocodex/node/Transport.d.mts +44 -0
  118. package/vendor/nanocodex/node/Transport.mjs +46 -0
  119. package/vendor/nanocodex/node/host.mjs +731 -0
  120. package/vendor/nanocodex/node/index.d.mts +73 -0
  121. package/vendor/nanocodex/node/index.mjs +17 -0
  122. package/vendor/nanocodex/node/workspace.d.mts +10 -0
  123. package/vendor/nanocodex/node/workspace.mjs +198 -0
  124. package/vendor/nanocodex/package.json +200 -0
  125. package/vendor/nanocodex/pkg-node/nanocodex.d.ts +675 -0
  126. package/vendor/nanocodex/pkg-node/nanocodex.js +2628 -0
  127. package/vendor/nanocodex/pkg-node/nanocodex_bg.wasm.d.ts +105 -0
  128. package/vendor/nanocodex/pkg-node/package.json +1 -0
  129. package/vendor/nanocodex/pkg-web/.nanocodex-bindgen-stamp +6 -0
  130. package/vendor/nanocodex/pkg-web/nanocodex-build.json +1 -0
  131. package/vendor/nanocodex/pkg-web/nanocodex.d.ts +805 -0
  132. package/vendor/nanocodex/pkg-web/nanocodex.js +2714 -0
  133. package/vendor/nanocodex/pkg-web/nanocodex_bg.js +2615 -0
  134. package/vendor/nanocodex/pkg-web/nanocodex_bg.wasm +0 -0
  135. package/vendor/nanocodex/pkg-web/nanocodex_bg.wasm.d.ts +105 -0
  136. package/vendor/nanocodex/pkg-web/nanocodex_worker.js +9 -0
  137. package/vendor/nanocodex/pkg-web/package.json +1 -0
  138. package/vendor/nanocodex/runtime/chatgpt-subscription.mjs +212 -0
  139. package/vendor/nanocodex/runtime/cloudflare-durability-store.d.mts +26 -0
  140. package/vendor/nanocodex/runtime/cloudflare-durability-store.mjs +168 -0
  141. package/vendor/nanocodex/runtime/code-evaluator.worker.mjs +137 -0
  142. package/vendor/nanocodex/runtime/code-runtime.mjs +1 -0
  143. package/vendor/nanocodex/runtime/durability-store.d.mts +85 -0
  144. package/vendor/nanocodex/runtime/durability-store.mjs +631 -0
  145. package/vendor/nanocodex/runtime/durability.mjs +153 -0
  146. package/vendor/nanocodex/runtime/managed-transport.mjs +460 -0
  147. package/vendor/nanocodex/runtime/mcp-runtime.mjs +534 -0
  148. package/vendor/nanocodex/runtime/postgres-durability-store.d.mts +64 -0
  149. package/vendor/nanocodex/runtime/postgres-durability-store.mjs +532 -0
  150. package/vendor/nanocodex/runtime/quickjs-evaluator.d.mts +17 -0
  151. package/vendor/nanocodex/runtime/quickjs-evaluator.mjs +236 -0
  152. package/vendor/nanocodex/runtime/responses-transport.mjs +22 -0
  153. package/vendor/nanocodex/runtime/subagents.d.mts +107 -0
  154. package/vendor/nanocodex/runtime/subagents.mjs +54 -0
  155. package/vendor/nanocodex/runtime/subscription-store.d.mts +8 -0
  156. package/vendor/nanocodex/runtime/subscription-store.mjs +42 -0
  157. package/vendor/nanocodex/runtime/tempo-provider.d.mts +125 -0
  158. package/vendor/nanocodex/runtime/tempo-provider.mjs +264 -0
  159. package/vendor/nanocodex/runtime/tool-configuration.mjs +1 -0
  160. package/vendor/nanocodex/runtime/tool-router.mjs +1 -0
  161. package/vendor/nanocodex/runtime/utf8.mjs +1 -0
  162. package/vendor/nanocodex/runtime/worker-evaluator.mjs +162 -0
  163. package/vendor/nanocodex/runtime/workspace.d.mts +1 -0
  164. package/vendor/nanocodex/runtime/workspace.mjs +1 -0
  165. package/vendor/nanocodex/tools/Tools.d.mts +56 -0
  166. package/vendor/nanocodex/tools/Tools.mjs +136 -0
  167. package/vendor/nanocodex/tools/artifact.d.mts +1 -0
  168. package/vendor/nanocodex/tools/artifact.mjs +1 -0
  169. package/vendor/nanocodex/tools/attachment.mjs +1 -0
  170. package/vendor/nanocodex/tools/bash.d.mts +1 -0
  171. package/vendor/nanocodex/tools/bash.mjs +1 -0
  172. package/vendor/nanocodex/tools/browser/accountInfo.mjs +795 -0
  173. package/vendor/nanocodex/tools/browser/browserBuffer.mjs +18 -0
  174. package/vendor/nanocodex/tools/browser/browserCompiler.mjs +155 -0
  175. package/vendor/nanocodex/tools/browser/browserEgress.mjs +161 -0
  176. package/vendor/nanocodex/tools/browser/browserPython.mjs +133 -0
  177. package/vendor/nanocodex/tools/browser/browserShell.mjs +1075 -0
  178. package/vendor/nanocodex/tools/browser/browserSprintf.mjs +4 -0
  179. package/vendor/nanocodex/tools/browser/browserSsh.mjs +201 -0
  180. package/vendor/nanocodex/tools/browser/browserZlib.mjs +136 -0
  181. package/vendor/nanocodex/tools/browser/compiler.worker.mjs +160 -0
  182. package/vendor/nanocodex/tools/browser/devTunnelsSshBrowser.mjs +13 -0
  183. package/vendor/nanocodex/tools/browser/index.d.mts +209 -0
  184. package/vendor/nanocodex/tools/browser/index.mjs +174 -0
  185. package/vendor/nanocodex/tools/browser/opfsGit.mjs +248 -0
  186. package/vendor/nanocodex/tools/browser/python.worker.mjs +114 -0
  187. package/vendor/nanocodex/tools/browser/threadGit.mjs +197 -0
  188. package/vendor/nanocodex/tools/browser/unsupportedNodeRsa.mjs +5 -0
  189. package/vendor/nanocodex/tools/browser/workspace.mjs +83 -0
  190. package/vendor/nanocodex/tools/dataset.d.mts +1 -0
  191. package/vendor/nanocodex/tools/dataset.mjs +1 -0
  192. package/vendor/nanocodex/tools/datasetContract.mjs +1 -0
  193. package/vendor/nanocodex/tools/datasetEngine.mjs +1 -0
  194. package/vendor/nanocodex/tools/hostedCatalog.d.mts +1 -0
  195. package/vendor/nanocodex/tools/hostedCatalog.mjs +1 -0
  196. package/vendor/nanocodex/tools/index.d.mts +49 -0
  197. package/vendor/nanocodex/tools/index.mjs +19 -0
  198. package/vendor/nanocodex/tools/namedTool.mjs +1 -0
  199. package/vendor/nanocodex/tools/repository-workspace.d.mts +1 -0
  200. package/vendor/nanocodex/tools/repository-workspace.mjs +1 -0
  201. package/vendor/nanocodex/tools/ssh.d.mts +1 -0
  202. package/vendor/nanocodex/tools/ssh.mjs +1 -0
  203. package/vendor/nanocodex/tools/standard.mjs +1 -0
  204. package/vendor/nanocodex/tools/standardDescriptions.mjs +1 -0
  205. package/vendor/nanocodex/types.d.mts +663 -0
  206. package/vendor/nanocodex/wasm.d.mts +4 -0
  207. package/vendor/nanocodex/worker/ChatGptSubscription.d.mts +9 -0
  208. package/vendor/nanocodex/worker/ChatGptSubscription.mjs +29 -0
  209. package/vendor/nanocodex/worker/index.d.mts +18 -0
  210. package/vendor/nanocodex/worker/index.mjs +5 -0
  211. package/vendor/nanocodex-tools/README.md +65 -0
  212. package/vendor/nanocodex-tools/dist/hosted/app-tool-catalog.d.ts +7 -0
  213. package/vendor/nanocodex-tools/dist/hosted/app-tool-catalog.js +14 -0
  214. package/vendor/nanocodex-tools/dist/hosted/broker-core.d.ts +172 -0
  215. package/vendor/nanocodex-tools/dist/hosted/broker-core.js +1278 -0
  216. package/vendor/nanocodex-tools/dist/hosted/index.d.ts +3 -0
  217. package/vendor/nanocodex-tools/dist/hosted/index.js +3 -0
  218. package/vendor/nanocodex-tools/dist/hosted/protocol.d.ts +120 -0
  219. package/vendor/nanocodex-tools/dist/hosted/protocol.js +415 -0
  220. package/vendor/nanocodex-tools/dist/index.d.ts +19 -0
  221. package/vendor/nanocodex-tools/dist/index.js +14 -0
  222. package/vendor/nanocodex-tools/dist/memory.d.ts +204 -0
  223. package/vendor/nanocodex-tools/dist/memory.js +411 -0
  224. package/vendor/nanocodex-tools/dist/namespace.d.ts +87 -0
  225. package/vendor/nanocodex-tools/dist/namespace.js +338 -0
  226. package/vendor/nanocodex-tools/dist/repository-archive.d.ts +4 -0
  227. package/vendor/nanocodex-tools/dist/repository-archive.js +104 -0
  228. package/vendor/nanocodex-tools/dist/runtime.d.ts +30 -0
  229. package/vendor/nanocodex-tools/dist/runtime.js +37 -0
  230. package/vendor/nanocodex-tools/dist/session.d.ts +167 -0
  231. package/vendor/nanocodex-tools/dist/session.js +286 -0
  232. package/vendor/nanocodex-tools/dist/shell.d.ts +51 -0
  233. package/vendor/nanocodex-tools/dist/shell.js +553 -0
  234. package/vendor/nanocodex-tools/dist/ssh.d.ts +29 -0
  235. package/vendor/nanocodex-tools/dist/ssh.js +66 -0
  236. package/vendor/nanocodex-tools/dist/workspace.d.ts +45 -0
  237. package/vendor/nanocodex-tools/dist/workspace.js +237 -0
  238. package/vendor/nanocodex-tools/package.json +122 -0
  239. package/vendor/nanocodex-tools/runtime/code-runtime.mjs +817 -0
  240. package/vendor/nanocodex-tools/runtime/tool-configuration.mjs +50 -0
  241. package/vendor/nanocodex-tools/runtime/tool-router.mjs +730 -0
  242. package/vendor/nanocodex-tools/runtime/utf8.d.mts +2 -0
  243. package/vendor/nanocodex-tools/runtime/utf8.mjs +25 -0
  244. package/vendor/nanocodex-tools/tools/artifact.d.mts +69 -0
  245. package/vendor/nanocodex-tools/tools/artifact.mjs +270 -0
  246. package/vendor/nanocodex-tools/tools/attachment.mjs +603 -0
  247. package/vendor/nanocodex-tools/tools/bash.d.mts +90 -0
  248. package/vendor/nanocodex-tools/tools/bash.mjs +742 -0
  249. package/vendor/nanocodex-tools/tools/dataset.d.mts +9 -0
  250. package/vendor/nanocodex-tools/tools/dataset.mjs +47 -0
  251. package/vendor/nanocodex-tools/tools/datasetContract.mjs +54 -0
  252. package/vendor/nanocodex-tools/tools/datasetEngine.mjs +1167 -0
  253. package/vendor/nanocodex-tools/tools/execution-contract.d.mts +5 -0
  254. package/vendor/nanocodex-tools/tools/execution-contract.mjs +63 -0
  255. package/vendor/nanocodex-tools/tools/hostedCatalog.d.mts +20 -0
  256. package/vendor/nanocodex-tools/tools/hostedCatalog.mjs +67 -0
  257. package/vendor/nanocodex-tools/tools/hostedMachine.d.mts +10 -0
  258. package/vendor/nanocodex-tools/tools/hostedMachine.mjs +56 -0
  259. package/vendor/nanocodex-tools/tools/just-bash-browser.d.mts +1 -0
  260. package/vendor/nanocodex-tools/tools/just-bash-browser.mjs +1 -0
  261. package/vendor/nanocodex-tools/tools/namedTool.d.mts +3 -0
  262. package/vendor/nanocodex-tools/tools/namedTool.mjs +3 -0
  263. package/vendor/nanocodex-tools/tools/nodeProcess.d.mts +10 -0
  264. package/vendor/nanocodex-tools/tools/nodeProcess.mjs +314 -0
  265. package/vendor/nanocodex-tools/tools/processOutput.mjs +56 -0
  266. package/vendor/nanocodex-tools/tools/repository-workspace.d.mts +55 -0
  267. package/vendor/nanocodex-tools/tools/repository-workspace.mjs +397 -0
  268. package/vendor/nanocodex-tools/tools/ssh.d.mts +56 -0
  269. package/vendor/nanocodex-tools/tools/ssh.mjs +503 -0
  270. package/vendor/nanocodex-tools/tools/standard.mjs +458 -0
  271. package/vendor/nanocodex-tools/tools/standardDescriptions.mjs +3 -0
  272. package/vendor/nanocodex-tools/tools/types.d.mts +83 -0
  273. package/vendor/nanocodex-tools/tools/workspace.d.mts +25 -0
  274. package/vendor/nanocodex-tools/tools/workspace.mjs +282 -0
  275. package/vendor/nanocodex-tools/tools/x.d.mts +30 -0
  276. package/vendor/nanocodex-tools/tools/x.mjs +91 -0
@@ -0,0 +1,153 @@
1
+ const hosts = new Map();
2
+ let nextRouteId = 1n;
3
+
4
+ export function own(host, store, stateId) {
5
+ if ((store === undefined) !== (stateId === undefined)) {
6
+ throw new TypeError("durability and durabilityId must be supplied together");
7
+ }
8
+ const routeId = `durability-route-${nextRouteId++}`;
9
+ hosts.set(routeId, { host, store, stateId, references: 0 });
10
+ return Object.freeze({
11
+ id: routeId,
12
+ abandon: () => abandon(host, routeId),
13
+ retain: () => retain(host, routeId),
14
+ release: () => release(host, routeId),
15
+ });
16
+ }
17
+
18
+ export function retain(host, routeId) {
19
+ const ownership = hosts.get(routeId);
20
+ if (!ownership || ownership.host !== host) {
21
+ throw new Error(`Nanocodex durability route is not bound to this host: ${routeId}`);
22
+ }
23
+ ownership.references += 1;
24
+ }
25
+
26
+ export function release(host, routeId) {
27
+ const ownership = hosts.get(routeId);
28
+ if (!ownership || ownership.host !== host) return;
29
+ if (ownership.references > 0) ownership.references -= 1;
30
+ if (ownership.references === 0) hosts.delete(routeId);
31
+ }
32
+
33
+ export function abandon(host, routeId) {
34
+ const ownership = hosts.get(routeId);
35
+ if (ownership?.host === host && ownership.references === 0) hosts.delete(routeId);
36
+ }
37
+
38
+ export async function acquire(routeId, stateId, ownerId) {
39
+ const stored = await requiredRoute(routeId).store.acquire(stateId, { ownerId });
40
+ if (!stored || typeof stored !== "object" || Array.isArray(stored)) {
41
+ throw new TypeError("durability.acquire() must return an acquired state object");
42
+ }
43
+ exactKeys(stored, ["ownerId", "fence", "revision", "payload"], "durability acquired state");
44
+ const acquiredOwnerId = nonempty(stored.ownerId, "durability owner ID");
45
+ if (acquiredOwnerId !== ownerId) {
46
+ throw new TypeError("durability.acquire() must return the requested owner ID");
47
+ }
48
+ const retainedRevision = uint64(stored.revision, "durability state revision");
49
+ const payload = stored.payload === null
50
+ ? null
51
+ : string(stored.payload, "durability state payload");
52
+ if ((retainedRevision === "0") !== (payload === null)) {
53
+ throw new TypeError("durability.acquire() returned inconsistent revision and payload");
54
+ }
55
+ // Cross the WASM boundary as fields. Wrapping a large legacy payload in
56
+ // another JSON string duplicates it in both JS and WASM during cold recovery.
57
+ return Object.freeze({
58
+ owner_id: acquiredOwnerId,
59
+ fence: uint64(stored.fence, "durability owner fence"),
60
+ revision: retainedRevision,
61
+ // wasm-bindgen's string conversion can reserve three times a large
62
+ // Unicode string's length. UTF-8 bytes cross with one exact allocation.
63
+ payload: payload === null ? null : new TextEncoder().encode(payload),
64
+ });
65
+ }
66
+
67
+ export async function replace(
68
+ routeId,
69
+ stateId,
70
+ ownerId,
71
+ fence,
72
+ expectedRevision,
73
+ payload,
74
+ ) {
75
+ const result = await requiredRoute(routeId).store.replace(stateId, {
76
+ ownerId,
77
+ fence,
78
+ expectedRevision,
79
+ payload,
80
+ });
81
+ if (result?.status === "replaced") {
82
+ exactKeys(result, ["status", "revision"], "durability replaced result");
83
+ return JSON.stringify({
84
+ status: "replaced",
85
+ revision: uint64(result.revision, "durability replace revision"),
86
+ });
87
+ }
88
+ if (result?.status === "conflict") {
89
+ exactKeys(result, ["status", "actualRevision"], "durability conflict result");
90
+ return JSON.stringify({
91
+ status: "conflict",
92
+ actual_revision: uint64(result.actualRevision, "durability conflict revision"),
93
+ });
94
+ }
95
+ if (result?.status === "not_committed") {
96
+ exactKeys(result, ["status", "message"], "durability not-committed result");
97
+ return JSON.stringify({
98
+ status: "not_committed",
99
+ message: nonempty(result.message, "durability not-committed message"),
100
+ });
101
+ }
102
+ if (result?.status === "fenced") {
103
+ exactKeys(result, ["status"], "durability fenced result");
104
+ return JSON.stringify({ status: "fenced" });
105
+ }
106
+ throw new TypeError(
107
+ "durability.replace() must return a replaced, conflict, fenced, or not_committed result",
108
+ );
109
+ }
110
+
111
+ function requiredRoute(routeId) {
112
+ const route = hosts.get(routeId);
113
+ if (!route) throw new Error(`no Nanocodex host owns durability route: ${routeId}`);
114
+ const store = route.store;
115
+ if (!store || typeof store.acquire !== "function" || typeof store.replace !== "function") {
116
+ throw new TypeError("the selected Nanocodex host must define a durability state store");
117
+ }
118
+ return route;
119
+ }
120
+
121
+ function uint64(value, name) {
122
+ if (
123
+ typeof value !== "string"
124
+ || !/^(0|[1-9][0-9]*)$/.test(value)
125
+ || BigInt(value) > 18_446_744_073_709_551_615n
126
+ ) {
127
+ throw new TypeError(`${name} must be an unsigned 64-bit decimal string`);
128
+ }
129
+ return value;
130
+ }
131
+
132
+ function string(value, name) {
133
+ if (typeof value !== "string") throw new TypeError(`${name} must be a string`);
134
+ return value;
135
+ }
136
+
137
+ function nonempty(value, name) {
138
+ if (typeof value !== "string" || !value.trim()) {
139
+ throw new TypeError(`${name} must be a non-empty string`);
140
+ }
141
+ return value;
142
+ }
143
+
144
+ function exactKeys(value, expected, name) {
145
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
146
+ throw new TypeError(`${name} must be an object`);
147
+ }
148
+ const actual = Object.keys(value).sort();
149
+ const required = [...expected].sort();
150
+ if (actual.length !== required.length || actual.some((key, index) => key !== required[index])) {
151
+ throw new TypeError(`${name} must contain exactly ${required.join(", ")}`);
152
+ }
153
+ }
@@ -0,0 +1,460 @@
1
+ import * as ManagedAgent from "../managed/Agent.mjs";
2
+ import { registerManagedAgentAlias } from "../managed/internal.mjs";
3
+ import { reportError } from "../internal.mjs";
4
+ import { AttachmentRejectedError } from "../tools/attachment.mjs";
5
+ import {
6
+ toolRouterBrand,
7
+ toolRuntimeLifecycle,
8
+ } from "./tool-router.mjs";
9
+
10
+ const MANAGED_AGENT_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
11
+ const TRANSPORT_OPTIONS = new Set(["agent", "apiKey", "baseUrl", "fetch", "toolsTransport"]);
12
+ const CREATE_OPTIONS = new Set(["tools", "transport"]);
13
+ const ATTACHMENT_BACKOFF_MS = [250, 500, 1_000, 2_000, 5_000];
14
+ const managedTransports = new WeakMap();
15
+ let nextManagedAgent = 1;
16
+
17
+ /** Defines an account-authenticated durable Agent transport without exposing its credentials. */
18
+ export function createManagedTransport(options) {
19
+ validateTransportOptions(options);
20
+ const identity = Object.hasOwn(options.agent, "create")
21
+ ? Object.freeze({ kind: "create" })
22
+ : Object.freeze({ kind: "open", id: options.agent.id });
23
+ const transport = Object.freeze({});
24
+ const client = { ...options };
25
+ delete client.agent;
26
+ managedTransports.set(transport, Object.freeze({
27
+ identity,
28
+ client: Object.freeze(client),
29
+ }));
30
+ return transport;
31
+ }
32
+
33
+ export function managedTransportOptions(transport) {
34
+ return transport && typeof transport === "object"
35
+ ? managedTransports.get(transport)
36
+ : undefined;
37
+ }
38
+
39
+ /** Creates the common Agent lifecycle over an account-owned durable Agent. */
40
+ export async function createManagedAgent(options) {
41
+ validateCreateOptions(options);
42
+ const setup = managedTransportOptions(options.transport);
43
+ if (!setup) throw new TypeError("Agent.create requires a managed transport");
44
+ const tools = options.tools;
45
+ if (tools !== undefined
46
+ && (!tools?.[toolRouterBrand] || typeof tools.attach !== "function")) {
47
+ throw new TypeError("managed Agent tools must be created by createTools()");
48
+ }
49
+ tools?.[toolRuntimeLifecycle].available();
50
+ const managed = setup.identity.kind === "create"
51
+ ? await ManagedAgent.create(setup.client)
52
+ : ManagedAgent.open(setup.identity.id, setup.client);
53
+ const managedState = await managed.state();
54
+ if (managedState.agent_id !== managed.id
55
+ || typeof managedState.session_id !== "string"
56
+ || !MANAGED_AGENT_ID.test(managedState.session_id)) {
57
+ throw new Error("managed Agent state returned inconsistent agent or session identity");
58
+ }
59
+ tools?.[toolRuntimeLifecycle].claim();
60
+ return managedAgentView(managed, managedState.agent_id, managedState.session_id, tools);
61
+ }
62
+
63
+ function managedAgentView(managed, agentId, sessionId, tools) {
64
+ const state = {
65
+ managed,
66
+ tools,
67
+ connector: undefined,
68
+ attachmentAbort: new AbortController(),
69
+ attachmentSupervisor: undefined,
70
+ closed: false,
71
+ closing: undefined,
72
+ agentId,
73
+ sessionId,
74
+ turns: new Set(),
75
+ uid: `managed-agent-${nextManagedAgent++}`,
76
+ watchers: new Set(),
77
+ };
78
+ const agent = agentView(state, {});
79
+ registerManagedAgentAlias(agent, managed);
80
+ if (tools) {
81
+ state.attachmentSupervisor = superviseAttachment(state).catch((error) => {
82
+ if (!state.closed) reportError(error);
83
+ });
84
+ }
85
+ return agent;
86
+ }
87
+
88
+ async function superviseAttachment(state) {
89
+ const target = state.managed.toolsTarget();
90
+ for (let attempt = 0; ; attempt += 1) {
91
+ if (state.attachmentAbort.signal.aborted) return;
92
+ const connector = state.tools.attach(target);
93
+ state.connector = connector;
94
+ try {
95
+ await connector.connect();
96
+ return;
97
+ } catch (error) {
98
+ connector.close();
99
+ if (state.connector === connector) state.connector = undefined;
100
+ if (error instanceof AttachmentRejectedError) throw error;
101
+ if (state.attachmentAbort.signal.aborted) return;
102
+ if (attempt === ATTACHMENT_BACKOFF_MS.length - 1) {
103
+ reportError(new Error(
104
+ "managed tool attachment remains unavailable; cloud tools continue while retrying",
105
+ ));
106
+ }
107
+ await attachmentBackoff(
108
+ ATTACHMENT_BACKOFF_MS[Math.min(attempt, ATTACHMENT_BACKOFF_MS.length - 1)],
109
+ state.attachmentAbort.signal,
110
+ );
111
+ }
112
+ }
113
+ }
114
+
115
+ function attachmentBackoff(milliseconds, signal) {
116
+ if (signal.aborted) return Promise.resolve();
117
+ return new Promise((resolve) => {
118
+ const timer = setTimeout(done, milliseconds);
119
+ signal.addEventListener("abort", done, { once: true });
120
+ function done() {
121
+ clearTimeout(timer);
122
+ signal.removeEventListener("abort", done);
123
+ resolve();
124
+ }
125
+ });
126
+ }
127
+
128
+ function agentView(state, extensions) {
129
+ let agent;
130
+ const base = {
131
+ uid: state.uid,
132
+ key: "managed-durable",
133
+ name: "Nanocodex Managed Durable Agent",
134
+ type: "managed",
135
+ get agentId() { return state.agentId; },
136
+ get sessionId() { return state.sessionId; },
137
+ extend(decorator) {
138
+ if (typeof decorator !== "function") throw new TypeError("agent.extend requires a decorator function");
139
+ const value = decorator(agent);
140
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
141
+ throw new TypeError("an agent decorator must return an object");
142
+ }
143
+ const extension = { ...value };
144
+ for (const key of Object.keys(base)) delete extension[key];
145
+ return agentView(state, mergeExtensions(extensions, extension));
146
+ },
147
+ dispose() {
148
+ if (state.closed) return;
149
+ closeManagedAgent(state);
150
+ },
151
+ };
152
+ const lifecycle = {
153
+ events: {
154
+ watch: (options) => {
155
+ requireOpen(state);
156
+ const watcher = managedEventWatcher(
157
+ state.managed,
158
+ state.sessionId,
159
+ options,
160
+ () => state.watchers.delete(watcher),
161
+ );
162
+ state.watchers.add(watcher);
163
+ return watcher;
164
+ },
165
+ },
166
+ session: {
167
+ shutdown: () => shutdownManagedAgent(state),
168
+ },
169
+ turn: {
170
+ prompt: (options) => {
171
+ requireOpen(state);
172
+ const controller = new AbortController();
173
+ const active = { controller, turn: undefined };
174
+ const turn = state.managed.turn.prompt({
175
+ ...promptOptions(options),
176
+ signal: controller.signal,
177
+ });
178
+ active.turn = turn;
179
+ state.turns.add(active);
180
+ return managedTurn(agent, turn, () => state.turns.delete(active));
181
+ },
182
+ },
183
+ };
184
+ agent = Object.assign(base, mergeExtensions(lifecycle, extensions));
185
+ return agent;
186
+ }
187
+
188
+ function managedTurn(agent, turn, settled) {
189
+ let result;
190
+ return Object.freeze({
191
+ agent,
192
+ accepted: async () => {
193
+ await turn.accepted();
194
+ return turn.idempotencyKey;
195
+ },
196
+ result: () => result ??= turn.result()
197
+ .then((completed) => managedTurnResult(completed))
198
+ .finally(settled),
199
+ steer: async (options) => { await turn.steer(options); },
200
+ cancel: async () => { await turn.cancel(); },
201
+ dispose() {},
202
+ });
203
+ }
204
+
205
+ function managedTurnResult(result) {
206
+ let disposed = false;
207
+ return Object.freeze({
208
+ finalMessage: result.finalMessage,
209
+ usage: () => disposed
210
+ ? Promise.reject(new Error("the Nanocodex turn result has been disposed"))
211
+ : Promise.resolve(result.usage),
212
+ dispose() { disposed = true; },
213
+ });
214
+ }
215
+
216
+ function managedEventWatcher(managed, sessionId, options = {}, onClose) {
217
+ if (!options || typeof options !== "object" || Array.isArray(options)) {
218
+ throw new TypeError("managed Agent event options must be an object");
219
+ }
220
+ const unsupported = Object.keys(options).find((key) => key !== "includeAllSessions");
221
+ if (unsupported) throw new TypeError(`managed Agent events do not accept ${unsupported}`);
222
+ const listeners = new Set();
223
+ const readers = new Set();
224
+ let observation;
225
+ let stream;
226
+ let pumping;
227
+ let closed = false;
228
+
229
+ const start = () => {
230
+ if (closed || pumping) return;
231
+ const controller = new AbortController();
232
+ const activeStream = managed.events.watch({ cursor: "latest", signal: controller.signal });
233
+ observation = controller;
234
+ stream = activeStream;
235
+ pumping = (async () => {
236
+ try {
237
+ for await (const envelope of activeStream) {
238
+ if (closed) return;
239
+ const event = projectManagedEvent(envelope, sessionId);
240
+ for (const listener of listeners) {
241
+ try { listener(event); } catch (error) { reportError(error); }
242
+ }
243
+ for (const reader of readers) reader.push(event);
244
+ }
245
+ for (const reader of readers) reader.end();
246
+ } catch (error) {
247
+ if (closed || controller.signal.aborted) return;
248
+ for (const reader of readers) reader.fail(error);
249
+ reportError(error);
250
+ } finally {
251
+ if (stream === activeStream) {
252
+ observation = undefined;
253
+ stream = undefined;
254
+ pumping = undefined;
255
+ }
256
+ }
257
+ })();
258
+ };
259
+ const stop = () => {
260
+ observation?.abort();
261
+ observation = undefined;
262
+ void stream?.return?.();
263
+ stream = undefined;
264
+ pumping = undefined;
265
+ };
266
+ const stopIfIdle = () => {
267
+ if (!listeners.size && !readers.size) stop();
268
+ };
269
+ const watcher = {
270
+ onEvent(listener) {
271
+ if (typeof listener !== "function") throw new TypeError("events.watch.onEvent requires a listener");
272
+ if (closed) return () => {};
273
+ listeners.add(listener);
274
+ start();
275
+ return () => {
276
+ listeners.delete(listener);
277
+ stopIfIdle();
278
+ };
279
+ },
280
+ off() {
281
+ if (closed) return;
282
+ closed = true;
283
+ stop();
284
+ listeners.clear();
285
+ for (const reader of readers) reader.end();
286
+ readers.clear();
287
+ onClose();
288
+ },
289
+ [Symbol.asyncIterator]() {
290
+ if (closed) return emptyIterator();
291
+ const reader = eventReader(() => {
292
+ readers.delete(reader);
293
+ stopIfIdle();
294
+ });
295
+ readers.add(reader);
296
+ start();
297
+ return reader;
298
+ },
299
+ };
300
+ return Object.freeze(watcher);
301
+ }
302
+
303
+ function eventReader(onClose) {
304
+ const queue = [];
305
+ const pending = [];
306
+ let ended = false;
307
+ let failure;
308
+ const reader = {
309
+ push(value) {
310
+ if (ended || failure) return;
311
+ const waiter = pending.shift();
312
+ if (waiter) waiter.resolve({ done: false, value });
313
+ else if (queue.length >= 4_096) reader.fail(new RangeError("managed event iterator exceeded 4096 buffered events"));
314
+ else queue.push(value);
315
+ },
316
+ fail(error) {
317
+ if (ended || failure) return;
318
+ failure = error;
319
+ for (const waiter of pending.splice(0)) waiter.reject(error);
320
+ onClose();
321
+ },
322
+ end() {
323
+ if (ended) return;
324
+ ended = true;
325
+ for (const entry of pending.splice(0)) entry.resolve({ done: true, value: undefined });
326
+ queue.length = 0;
327
+ onClose();
328
+ },
329
+ next() {
330
+ if (queue.length) return Promise.resolve({ done: false, value: queue.shift() });
331
+ if (failure) return Promise.reject(failure);
332
+ if (ended) return Promise.resolve({ done: true, value: undefined });
333
+ return new Promise((resolve, reject) => pending.push({ resolve, reject }));
334
+ },
335
+ return() { reader.end(); return Promise.resolve({ done: true, value: undefined }); },
336
+ [Symbol.asyncIterator]() { return this; },
337
+ };
338
+ return reader;
339
+ }
340
+
341
+ function projectManagedEvent(envelope, sessionId) {
342
+ const observed = envelope.data?.type === "event" ? envelope.data.event : undefined;
343
+ if (observed && typeof observed === "object" && !Array.isArray(observed)
344
+ && typeof observed.type === "string" && observed.payload
345
+ && typeof observed.payload === "object" && !Array.isArray(observed.payload)) {
346
+ return Object.freeze({
347
+ ...observed,
348
+ request_id: sessionId,
349
+ seq: eventSequence(envelope.cursor, observed.seq),
350
+ payload: Object.freeze({ ...observed.payload }),
351
+ });
352
+ }
353
+ return Object.freeze({
354
+ protocol_version: 1,
355
+ request_id: sessionId,
356
+ seq: eventSequence(envelope.cursor),
357
+ type: `managed.${envelope.data?.type ?? envelope.type ?? "event"}`,
358
+ payload: Object.freeze({ ...(envelope.data ?? {}) }),
359
+ });
360
+ }
361
+
362
+ function eventSequence(cursor, fallback = 0) {
363
+ const parsed = Number(cursor);
364
+ return Number.isSafeInteger(parsed) && parsed >= 0
365
+ ? parsed
366
+ : Number.isSafeInteger(fallback) && fallback >= 0 ? fallback : 0;
367
+ }
368
+
369
+ function emptyIterator() {
370
+ return {
371
+ next: () => Promise.resolve({ done: true, value: undefined }),
372
+ return: () => Promise.resolve({ done: true, value: undefined }),
373
+ [Symbol.asyncIterator]() { return this; },
374
+ };
375
+ }
376
+
377
+ function promptOptions(options) {
378
+ if (!options || typeof options !== "object" || Array.isArray(options)) {
379
+ throw new TypeError("Agent prompt options must be an object");
380
+ }
381
+ const unsupported = Object.keys(options).find((key) => key !== "id" && key !== "input");
382
+ if (unsupported) throw new TypeError(`managed Agent prompts do not accept ${unsupported}`);
383
+ return options.id === undefined
384
+ ? { input: options.input }
385
+ : { idempotencyKey: options.id, input: options.input };
386
+ }
387
+
388
+ function closeManagedAgent(state) {
389
+ state.closed = true;
390
+ for (const watcher of [...state.watchers]) watcher.off();
391
+ state.watchers.clear();
392
+ state.attachmentAbort.abort();
393
+ for (const active of state.turns) active.controller.abort(new Error("managed Agent disposed"));
394
+ state.turns.clear();
395
+ state.connector?.close();
396
+ if (state.tools) void state.tools.close().catch(reportError);
397
+ }
398
+
399
+ function shutdownManagedAgent(state) {
400
+ if (state.closing) return state.closing;
401
+ if (state.closed) return Promise.resolve();
402
+ state.closed = true;
403
+ for (const watcher of [...state.watchers]) watcher.off();
404
+ state.watchers.clear();
405
+ state.attachmentAbort.abort();
406
+ state.connector?.close();
407
+ state.closing = (async () => {
408
+ const activeTurns = [...state.turns];
409
+ await Promise.allSettled(activeTurns.map(async (active) => {
410
+ try { await active.turn.cancel(); }
411
+ finally { active.controller.abort(new Error("managed Agent shut down")); }
412
+ }));
413
+ for (const active of activeTurns) state.turns.delete(active);
414
+ await state.attachmentSupervisor;
415
+ await state.tools?.close();
416
+ })();
417
+ return state.closing;
418
+ }
419
+
420
+ function requireOpen(state) {
421
+ if (state.closed) throw new Error("the Nanocodex agent has been disposed");
422
+ }
423
+
424
+ function validateTransportOptions(options) {
425
+ if (!options || typeof options !== "object" || Array.isArray(options)) {
426
+ throw new TypeError("managed transport options must be an object");
427
+ }
428
+ const unsupported = Object.keys(options).find((key) => !TRANSPORT_OPTIONS.has(key));
429
+ if (unsupported) throw new TypeError(`managed transport does not accept ${unsupported}`);
430
+ const identity = options.agent;
431
+ if (!identity || typeof identity !== "object" || Array.isArray(identity)) {
432
+ throw new TypeError("managed transport requires agent: { create: true } or agent: { id }");
433
+ }
434
+ const keys = Object.keys(identity);
435
+ if (keys.length !== 1) {
436
+ throw new TypeError("managed transport requires exactly one explicit create or existing agent identity");
437
+ }
438
+ if (keys[0] === "create" && identity.create === true) return;
439
+ if (keys[0] === "id" && typeof identity.id === "string" && MANAGED_AGENT_ID.test(identity.id)) return;
440
+ throw new TypeError("managed transport requires agent: { create: true } or agent: { id: uuidV7 }");
441
+ }
442
+
443
+ function validateCreateOptions(options) {
444
+ if (!options || typeof options !== "object" || Array.isArray(options)) {
445
+ throw new TypeError("Agent.create options must be an object");
446
+ }
447
+ const unsupported = Object.keys(options).find((key) => !CREATE_OPTIONS.has(key));
448
+ if (unsupported) throw new TypeError(`managed Agent.create does not accept ${unsupported}`);
449
+ }
450
+
451
+ function mergeExtensions(left, right) {
452
+ const merged = { ...left };
453
+ for (const [key, value] of Object.entries(right)) {
454
+ merged[key] = value && typeof value === "object" && !Array.isArray(value)
455
+ && merged[key] && typeof merged[key] === "object" && !Array.isArray(merged[key])
456
+ ? mergeExtensions(merged[key], value)
457
+ : value;
458
+ }
459
+ return merged;
460
+ }