@nodetool-ai/runtime 0.7.0-rc.22 → 0.8.1

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 (665) hide show
  1. package/README.md +29 -0
  2. package/dist/.nodetool-build-stamp +1 -0
  3. package/dist/agent-memory.d.ts +118 -0
  4. package/dist/agent-memory.d.ts.map +1 -0
  5. package/dist/agent-memory.js +186 -0
  6. package/dist/agent-memory.js.map +1 -0
  7. package/dist/async-local-storage.d.ts +20 -0
  8. package/dist/async-local-storage.d.ts.map +1 -0
  9. package/dist/async-local-storage.js +28 -0
  10. package/dist/async-local-storage.js.map +1 -0
  11. package/dist/blender-executor.d.ts +93 -0
  12. package/dist/blender-executor.d.ts.map +1 -0
  13. package/dist/blender-executor.js +294 -0
  14. package/dist/blender-executor.js.map +1 -0
  15. package/dist/comfy-executor.d.ts +23 -1
  16. package/dist/comfy-executor.d.ts.map +1 -1
  17. package/dist/comfy-executor.js +234 -55
  18. package/dist/comfy-executor.js.map +1 -1
  19. package/dist/context-packer.d.ts +1 -1
  20. package/dist/context-packer.d.ts.map +1 -1
  21. package/dist/context-packer.js +23 -25
  22. package/dist/context-packer.js.map +1 -1
  23. package/dist/context.d.ts +954 -127
  24. package/dist/context.d.ts.map +1 -1
  25. package/dist/context.js +2424 -513
  26. package/dist/context.js.map +1 -1
  27. package/dist/cost-reconciler.d.ts +32 -0
  28. package/dist/cost-reconciler.d.ts.map +1 -0
  29. package/dist/cost-reconciler.js +21 -0
  30. package/dist/cost-reconciler.js.map +1 -0
  31. package/dist/entities.d.ts +33 -0
  32. package/dist/entities.d.ts.map +1 -0
  33. package/dist/entities.js +43 -0
  34. package/dist/entities.js.map +1 -0
  35. package/dist/external-media-fetch.d.ts +29 -0
  36. package/dist/external-media-fetch.d.ts.map +1 -0
  37. package/dist/external-media-fetch.js +38 -0
  38. package/dist/external-media-fetch.js.map +1 -0
  39. package/dist/generation-receipt.d.ts +86 -0
  40. package/dist/generation-receipt.d.ts.map +1 -0
  41. package/dist/generation-receipt.js +137 -0
  42. package/dist/generation-receipt.js.map +1 -0
  43. package/dist/generation-registry.d.ts +67 -0
  44. package/dist/generation-registry.d.ts.map +1 -0
  45. package/dist/generation-registry.js +126 -0
  46. package/dist/generation-registry.js.map +1 -0
  47. package/dist/google/client.d.ts +196 -0
  48. package/dist/google/client.d.ts.map +1 -0
  49. package/dist/google/client.js +396 -0
  50. package/dist/google/client.js.map +1 -0
  51. package/dist/google/index.d.ts +3 -0
  52. package/dist/google/index.d.ts.map +1 -0
  53. package/dist/google/index.js +3 -0
  54. package/dist/google/index.js.map +1 -0
  55. package/dist/google/token.d.ts +15 -0
  56. package/dist/google/token.d.ts.map +1 -0
  57. package/dist/google/token.js +24 -0
  58. package/dist/google/token.js.map +1 -0
  59. package/dist/host-binaries.d.ts +106 -0
  60. package/dist/host-binaries.d.ts.map +1 -0
  61. package/dist/host-binaries.js +344 -0
  62. package/dist/host-binaries.js.map +1 -0
  63. package/dist/image-codec.d.ts +74 -0
  64. package/dist/image-codec.d.ts.map +1 -0
  65. package/dist/image-codec.js +273 -0
  66. package/dist/image-codec.js.map +1 -0
  67. package/dist/index.d.ts +56 -6
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +43 -4
  70. package/dist/index.js.map +1 -1
  71. package/dist/invocation-account.d.ts +43 -0
  72. package/dist/invocation-account.d.ts.map +1 -0
  73. package/dist/invocation-account.js +60 -0
  74. package/dist/invocation-account.js.map +1 -0
  75. package/dist/media-ref-bytes.d.ts +19 -0
  76. package/dist/media-ref-bytes.d.ts.map +1 -0
  77. package/dist/media-ref-bytes.js +181 -0
  78. package/dist/media-ref-bytes.js.map +1 -0
  79. package/dist/node-executor.d.ts +113 -2
  80. package/dist/node-executor.d.ts.map +1 -1
  81. package/dist/permission-gate.d.ts +152 -0
  82. package/dist/permission-gate.d.ts.map +1 -0
  83. package/dist/permission-gate.js +87 -0
  84. package/dist/permission-gate.js.map +1 -0
  85. package/dist/prefixed-storage-adapter.d.ts +33 -0
  86. package/dist/prefixed-storage-adapter.d.ts.map +1 -0
  87. package/dist/prefixed-storage-adapter.js +70 -0
  88. package/dist/prefixed-storage-adapter.js.map +1 -0
  89. package/dist/prompt-asset-refs.d.ts +222 -0
  90. package/dist/prompt-asset-refs.d.ts.map +1 -0
  91. package/dist/prompt-asset-refs.js +751 -0
  92. package/dist/prompt-asset-refs.js.map +1 -0
  93. package/dist/provider-cache.d.ts +3 -0
  94. package/dist/provider-cache.d.ts.map +1 -0
  95. package/dist/provider-cache.js +8 -0
  96. package/dist/provider-cache.js.map +1 -0
  97. package/dist/providers/aki-provider.d.ts +33 -10
  98. package/dist/providers/aki-provider.d.ts.map +1 -1
  99. package/dist/providers/aki-provider.js +84 -77
  100. package/dist/providers/aki-provider.js.map +1 -1
  101. package/dist/providers/alibaba-provider.d.ts +39 -0
  102. package/dist/providers/alibaba-provider.d.ts.map +1 -0
  103. package/dist/providers/alibaba-provider.js +86 -0
  104. package/dist/providers/alibaba-provider.js.map +1 -0
  105. package/dist/providers/anthropic-provider.d.ts +52 -3
  106. package/dist/providers/anthropic-provider.d.ts.map +1 -1
  107. package/dist/providers/anthropic-provider.js +1020 -338
  108. package/dist/providers/anthropic-provider.js.map +1 -1
  109. package/dist/providers/atlascloud-provider.d.ts +101 -0
  110. package/dist/providers/atlascloud-provider.d.ts.map +1 -0
  111. package/dist/providers/atlascloud-provider.js +1009 -0
  112. package/dist/providers/atlascloud-provider.js.map +1 -0
  113. package/dist/providers/atlascloud-transport.d.ts +100 -0
  114. package/dist/providers/atlascloud-transport.d.ts.map +1 -0
  115. package/dist/providers/atlascloud-transport.js +364 -0
  116. package/dist/providers/atlascloud-transport.js.map +1 -0
  117. package/dist/providers/atlascloud-webhook-registry.d.ts +35 -0
  118. package/dist/providers/atlascloud-webhook-registry.d.ts.map +1 -0
  119. package/dist/providers/atlascloud-webhook-registry.js +104 -0
  120. package/dist/providers/atlascloud-webhook-registry.js.map +1 -0
  121. package/dist/providers/audio-mime.d.ts +11 -0
  122. package/dist/providers/audio-mime.d.ts.map +1 -0
  123. package/dist/providers/audio-mime.js +46 -0
  124. package/dist/providers/audio-mime.js.map +1 -0
  125. package/dist/providers/base-provider.d.ts +481 -24
  126. package/dist/providers/base-provider.d.ts.map +1 -1
  127. package/dist/providers/base-provider.js +1259 -42
  128. package/dist/providers/base-provider.js.map +1 -1
  129. package/dist/providers/cassette-provider.d.ts +217 -0
  130. package/dist/providers/cassette-provider.d.ts.map +1 -0
  131. package/dist/providers/cassette-provider.js +502 -0
  132. package/dist/providers/cassette-provider.js.map +1 -0
  133. package/dist/providers/cerebras-provider.d.ts +6 -12
  134. package/dist/providers/cerebras-provider.d.ts.map +1 -1
  135. package/dist/providers/cerebras-provider.js +8 -33
  136. package/dist/providers/cerebras-provider.js.map +1 -1
  137. package/dist/providers/claude-agent-provider.d.ts +131 -68
  138. package/dist/providers/claude-agent-provider.d.ts.map +1 -1
  139. package/dist/providers/claude-agent-provider.js +1095 -515
  140. package/dist/providers/claude-agent-provider.js.map +1 -1
  141. package/dist/providers/codex-provider.d.ts +82 -0
  142. package/dist/providers/codex-provider.d.ts.map +1 -0
  143. package/dist/providers/codex-provider.js +492 -0
  144. package/dist/providers/codex-provider.js.map +1 -0
  145. package/dist/providers/cohere-provider.d.ts +5 -2
  146. package/dist/providers/cohere-provider.d.ts.map +1 -1
  147. package/dist/providers/cohere-provider.js +9 -2
  148. package/dist/providers/cohere-provider.js.map +1 -1
  149. package/dist/providers/comfy-cloud-provider.d.ts +30 -0
  150. package/dist/providers/comfy-cloud-provider.d.ts.map +1 -0
  151. package/dist/providers/comfy-cloud-provider.js +42 -0
  152. package/dist/providers/comfy-cloud-provider.js.map +1 -0
  153. package/dist/providers/content-filter.d.ts +46 -0
  154. package/dist/providers/content-filter.d.ts.map +1 -0
  155. package/dist/providers/content-filter.js +92 -0
  156. package/dist/providers/content-filter.js.map +1 -0
  157. package/dist/providers/context-exceeded.d.ts +37 -0
  158. package/dist/providers/context-exceeded.d.ts.map +1 -0
  159. package/dist/providers/context-exceeded.js +114 -0
  160. package/dist/providers/context-exceeded.js.map +1 -0
  161. package/dist/providers/context-window.d.ts +44 -0
  162. package/dist/providers/context-window.d.ts.map +1 -0
  163. package/dist/providers/context-window.js +145 -0
  164. package/dist/providers/context-window.js.map +1 -0
  165. package/dist/providers/contract/index.d.ts +4 -0
  166. package/dist/providers/contract/index.d.ts.map +1 -0
  167. package/dist/providers/contract/index.js +4 -0
  168. package/dist/providers/contract/index.js.map +1 -0
  169. package/dist/providers/contract/probe-manifest.d.ts +75 -0
  170. package/dist/providers/contract/probe-manifest.d.ts.map +1 -0
  171. package/dist/providers/contract/probe-manifest.js +379 -0
  172. package/dist/providers/contract/probe-manifest.js.map +1 -0
  173. package/dist/providers/contract/probe-runner.d.ts +57 -0
  174. package/dist/providers/contract/probe-runner.d.ts.map +1 -0
  175. package/dist/providers/contract/probe-runner.js +180 -0
  176. package/dist/providers/contract/probe-runner.js.map +1 -0
  177. package/dist/providers/contract/redact.d.ts +29 -0
  178. package/dist/providers/contract/redact.d.ts.map +1 -0
  179. package/dist/providers/contract/redact.js +113 -0
  180. package/dist/providers/contract/redact.js.map +1 -0
  181. package/dist/providers/core-tools.d.ts +74 -0
  182. package/dist/providers/core-tools.d.ts.map +1 -0
  183. package/dist/providers/core-tools.js +127 -0
  184. package/dist/providers/core-tools.js.map +1 -0
  185. package/dist/providers/cost-calculator.d.ts +69 -50
  186. package/dist/providers/cost-calculator.d.ts.map +1 -1
  187. package/dist/providers/cost-calculator.js +207 -397
  188. package/dist/providers/cost-calculator.js.map +1 -1
  189. package/dist/providers/credential-check.d.ts +45 -0
  190. package/dist/providers/credential-check.d.ts.map +1 -0
  191. package/dist/providers/credential-check.js +159 -0
  192. package/dist/providers/credential-check.js.map +1 -0
  193. package/dist/providers/custom-model-kinds.d.ts +33 -0
  194. package/dist/providers/custom-model-kinds.d.ts.map +1 -0
  195. package/dist/providers/custom-model-kinds.js +96 -0
  196. package/dist/providers/custom-model-kinds.js.map +1 -0
  197. package/dist/providers/custom-openai-provider.d.ts +81 -0
  198. package/dist/providers/custom-openai-provider.d.ts.map +1 -0
  199. package/dist/providers/custom-openai-provider.js +182 -0
  200. package/dist/providers/custom-openai-provider.js.map +1 -0
  201. package/dist/providers/custom-provider-registry.d.ts +19 -0
  202. package/dist/providers/custom-provider-registry.d.ts.map +1 -0
  203. package/dist/providers/custom-provider-registry.js +52 -0
  204. package/dist/providers/custom-provider-registry.js.map +1 -0
  205. package/dist/providers/deepseek-provider.d.ts +8 -14
  206. package/dist/providers/deepseek-provider.d.ts.map +1 -1
  207. package/dist/providers/deepseek-provider.js +6 -35
  208. package/dist/providers/deepseek-provider.js.map +1 -1
  209. package/dist/providers/defaults.d.ts +12 -0
  210. package/dist/providers/defaults.d.ts.map +1 -0
  211. package/dist/providers/defaults.js +12 -0
  212. package/dist/providers/defaults.js.map +1 -0
  213. package/dist/providers/elevenlabs-provider.d.ts +49 -0
  214. package/dist/providers/elevenlabs-provider.d.ts.map +1 -0
  215. package/dist/providers/elevenlabs-provider.js +142 -0
  216. package/dist/providers/elevenlabs-provider.js.map +1 -0
  217. package/dist/providers/entity-references.d.ts +31 -0
  218. package/dist/providers/entity-references.d.ts.map +1 -0
  219. package/dist/providers/entity-references.js +113 -0
  220. package/dist/providers/entity-references.js.map +1 -0
  221. package/dist/providers/evolink-provider.d.ts +38 -0
  222. package/dist/providers/evolink-provider.d.ts.map +1 -0
  223. package/dist/providers/evolink-provider.js +304 -0
  224. package/dist/providers/evolink-provider.js.map +1 -0
  225. package/dist/providers/fake-provider.d.ts +72 -1
  226. package/dist/providers/fake-provider.d.ts.map +1 -1
  227. package/dist/providers/fake-provider.js +203 -1
  228. package/dist/providers/fake-provider.js.map +1 -1
  229. package/dist/providers/fal-generations.d.ts +106 -0
  230. package/dist/providers/fal-generations.d.ts.map +1 -0
  231. package/dist/providers/fal-generations.js +286 -0
  232. package/dist/providers/fal-generations.js.map +1 -0
  233. package/dist/providers/fal-provider.d.ts +171 -7
  234. package/dist/providers/fal-provider.d.ts.map +1 -1
  235. package/dist/providers/fal-provider.js +1369 -64
  236. package/dist/providers/fal-provider.js.map +1 -1
  237. package/dist/providers/fal-queue.d.ts +47 -0
  238. package/dist/providers/fal-queue.d.ts.map +1 -0
  239. package/dist/providers/fal-queue.js +231 -0
  240. package/dist/providers/fal-queue.js.map +1 -0
  241. package/dist/providers/gemini-provider.d.ts +148 -8
  242. package/dist/providers/gemini-provider.d.ts.map +1 -1
  243. package/dist/providers/gemini-provider.js +1500 -316
  244. package/dist/providers/gemini-provider.js.map +1 -1
  245. package/dist/providers/gmi-provider.d.ts +21 -0
  246. package/dist/providers/gmi-provider.d.ts.map +1 -0
  247. package/dist/providers/gmi-provider.js +34 -0
  248. package/dist/providers/gmi-provider.js.map +1 -0
  249. package/dist/providers/gpt-image-size.d.ts +3 -0
  250. package/dist/providers/gpt-image-size.d.ts.map +1 -0
  251. package/dist/providers/gpt-image-size.js +37 -0
  252. package/dist/providers/gpt-image-size.js.map +1 -0
  253. package/dist/providers/groq-provider.d.ts +9 -12
  254. package/dist/providers/groq-provider.d.ts.map +1 -1
  255. package/dist/providers/groq-provider.js +19 -33
  256. package/dist/providers/groq-provider.js.map +1 -1
  257. package/dist/providers/groq-request.d.ts +38 -0
  258. package/dist/providers/groq-request.d.ts.map +1 -0
  259. package/dist/providers/groq-request.js +138 -0
  260. package/dist/providers/groq-request.js.map +1 -0
  261. package/dist/providers/higgsfield-provider.d.ts +30 -0
  262. package/dist/providers/higgsfield-provider.d.ts.map +1 -0
  263. package/dist/providers/higgsfield-provider.js +131 -0
  264. package/dist/providers/higgsfield-provider.js.map +1 -0
  265. package/dist/providers/higgsfield-transport.d.ts +106 -0
  266. package/dist/providers/higgsfield-transport.d.ts.map +1 -0
  267. package/dist/providers/higgsfield-transport.js +182 -0
  268. package/dist/providers/higgsfield-transport.js.map +1 -0
  269. package/dist/providers/http-transport.d.ts +74 -0
  270. package/dist/providers/http-transport.d.ts.map +1 -0
  271. package/dist/providers/http-transport.js +152 -0
  272. package/dist/providers/http-transport.js.map +1 -0
  273. package/dist/providers/huggingface-provider.d.ts +71 -3
  274. package/dist/providers/huggingface-provider.d.ts.map +1 -1
  275. package/dist/providers/huggingface-provider.js +230 -34
  276. package/dist/providers/huggingface-provider.js.map +1 -1
  277. package/dist/providers/image-mime.d.ts +39 -0
  278. package/dist/providers/image-mime.d.ts.map +1 -0
  279. package/dist/providers/image-mime.js +111 -0
  280. package/dist/providers/image-mime.js.map +1 -0
  281. package/dist/providers/image-ref.d.ts +21 -0
  282. package/dist/providers/image-ref.d.ts.map +1 -0
  283. package/dist/providers/image-ref.js +44 -0
  284. package/dist/providers/image-ref.js.map +1 -0
  285. package/dist/providers/index.d.ts +84 -8
  286. package/dist/providers/index.d.ts.map +1 -1
  287. package/dist/providers/index.js +239 -56
  288. package/dist/providers/index.js.map +1 -1
  289. package/dist/providers/jina-provider.d.ts +10 -2
  290. package/dist/providers/jina-provider.d.ts.map +1 -1
  291. package/dist/providers/jina-provider.js +16 -7
  292. package/dist/providers/jina-provider.js.map +1 -1
  293. package/dist/providers/kie-provider.d.ts +170 -9
  294. package/dist/providers/kie-provider.d.ts.map +1 -1
  295. package/dist/providers/kie-provider.js +1176 -228
  296. package/dist/providers/kie-provider.js.map +1 -1
  297. package/dist/providers/kie-webhook-registry.d.ts +28 -0
  298. package/dist/providers/kie-webhook-registry.d.ts.map +1 -0
  299. package/dist/providers/kie-webhook-registry.js +91 -0
  300. package/dist/providers/kie-webhook-registry.js.map +1 -0
  301. package/dist/providers/llama-provider.d.ts +21 -37
  302. package/dist/providers/llama-provider.d.ts.map +1 -1
  303. package/dist/providers/llama-provider.js +43 -354
  304. package/dist/providers/llama-provider.js.map +1 -1
  305. package/dist/providers/lmstudio-provider.d.ts +4 -7
  306. package/dist/providers/lmstudio-provider.d.ts.map +1 -1
  307. package/dist/providers/lmstudio-provider.js +24 -15
  308. package/dist/providers/lmstudio-provider.js.map +1 -1
  309. package/dist/providers/manifest-models.d.ts +341 -1
  310. package/dist/providers/manifest-models.d.ts.map +1 -1
  311. package/dist/providers/manifest-models.js +1106 -22
  312. package/dist/providers/manifest-models.js.map +1 -1
  313. package/dist/providers/media-mime.d.ts +14 -0
  314. package/dist/providers/media-mime.d.ts.map +1 -0
  315. package/dist/providers/media-mime.js +35 -0
  316. package/dist/providers/media-mime.js.map +1 -0
  317. package/dist/providers/meshy-provider.d.ts +14 -1
  318. package/dist/providers/meshy-provider.d.ts.map +1 -1
  319. package/dist/providers/meshy-provider.js +76 -46
  320. package/dist/providers/meshy-provider.js.map +1 -1
  321. package/dist/providers/meta-provider.d.ts +22 -0
  322. package/dist/providers/meta-provider.d.ts.map +1 -0
  323. package/dist/providers/meta-provider.js +54 -0
  324. package/dist/providers/meta-provider.js.map +1 -0
  325. package/dist/providers/minimax-provider.d.ts +25 -18
  326. package/dist/providers/minimax-provider.d.ts.map +1 -1
  327. package/dist/providers/minimax-provider.js +211 -72
  328. package/dist/providers/minimax-provider.js.map +1 -1
  329. package/dist/providers/mistral-provider.d.ts +6 -12
  330. package/dist/providers/mistral-provider.d.ts.map +1 -1
  331. package/dist/providers/mistral-provider.js +10 -34
  332. package/dist/providers/mistral-provider.js.map +1 -1
  333. package/dist/providers/moonshot-provider.d.ts +11 -15
  334. package/dist/providers/moonshot-provider.d.ts.map +1 -1
  335. package/dist/providers/moonshot-provider.js +33 -23
  336. package/dist/providers/moonshot-provider.js.map +1 -1
  337. package/dist/providers/node-llama-cpp-provider.d.ts +98 -0
  338. package/dist/providers/node-llama-cpp-provider.d.ts.map +1 -0
  339. package/dist/providers/node-llama-cpp-provider.js +479 -0
  340. package/dist/providers/node-llama-cpp-provider.js.map +1 -0
  341. package/dist/providers/nodetool-provider.d.ts +49 -0
  342. package/dist/providers/nodetool-provider.d.ts.map +1 -0
  343. package/dist/providers/nodetool-provider.js +224 -0
  344. package/dist/providers/nodetool-provider.js.map +1 -0
  345. package/dist/providers/oauth/browser-launcher.d.ts +23 -0
  346. package/dist/providers/oauth/browser-launcher.d.ts.map +1 -0
  347. package/dist/providers/oauth/browser-launcher.js +45 -0
  348. package/dist/providers/oauth/browser-launcher.js.map +1 -0
  349. package/dist/providers/oauth/claude-code-credentials.d.ts +74 -0
  350. package/dist/providers/oauth/claude-code-credentials.d.ts.map +1 -0
  351. package/dist/providers/oauth/claude-code-credentials.js +133 -0
  352. package/dist/providers/oauth/claude-code-credentials.js.map +1 -0
  353. package/dist/providers/oauth/claude-code-login.d.ts +124 -0
  354. package/dist/providers/oauth/claude-code-login.d.ts.map +1 -0
  355. package/dist/providers/oauth/claude-code-login.js +230 -0
  356. package/dist/providers/oauth/claude-code-login.js.map +1 -0
  357. package/dist/providers/oauth/claude-code-oauth-client.d.ts +111 -0
  358. package/dist/providers/oauth/claude-code-oauth-client.d.ts.map +1 -0
  359. package/dist/providers/oauth/claude-code-oauth-client.js +207 -0
  360. package/dist/providers/oauth/claude-code-oauth-client.js.map +1 -0
  361. package/dist/providers/oauth/errors.d.ts +54 -0
  362. package/dist/providers/oauth/errors.d.ts.map +1 -0
  363. package/dist/providers/oauth/errors.js +79 -0
  364. package/dist/providers/oauth/errors.js.map +1 -0
  365. package/dist/providers/oauth/index.d.ts +105 -0
  366. package/dist/providers/oauth/index.d.ts.map +1 -0
  367. package/dist/providers/oauth/index.js +167 -0
  368. package/dist/providers/oauth/index.js.map +1 -0
  369. package/dist/providers/oauth/jwt-claims.d.ts +23 -0
  370. package/dist/providers/oauth/jwt-claims.d.ts.map +1 -0
  371. package/dist/providers/oauth/jwt-claims.js +67 -0
  372. package/dist/providers/oauth/jwt-claims.js.map +1 -0
  373. package/dist/providers/oauth/local-callback-server.d.ts +60 -0
  374. package/dist/providers/oauth/local-callback-server.d.ts.map +1 -0
  375. package/dist/providers/oauth/local-callback-server.js +148 -0
  376. package/dist/providers/oauth/local-callback-server.js.map +1 -0
  377. package/dist/providers/oauth/oauth-client.d.ts +55 -0
  378. package/dist/providers/oauth/oauth-client.d.ts.map +1 -0
  379. package/dist/providers/oauth/oauth-client.js +161 -0
  380. package/dist/providers/oauth/oauth-client.js.map +1 -0
  381. package/dist/providers/oauth/openai-oauth-provider.d.ts +129 -0
  382. package/dist/providers/oauth/openai-oauth-provider.d.ts.map +1 -0
  383. package/dist/providers/oauth/openai-oauth-provider.js +265 -0
  384. package/dist/providers/oauth/openai-oauth-provider.js.map +1 -0
  385. package/dist/providers/oauth/pkce-helper.d.ts +43 -0
  386. package/dist/providers/oauth/pkce-helper.d.ts.map +1 -0
  387. package/dist/providers/oauth/pkce-helper.js +57 -0
  388. package/dist/providers/oauth/pkce-helper.js.map +1 -0
  389. package/dist/providers/oauth/redaction.d.ts +22 -0
  390. package/dist/providers/oauth/redaction.d.ts.map +1 -0
  391. package/dist/providers/oauth/redaction.js +59 -0
  392. package/dist/providers/oauth/redaction.js.map +1 -0
  393. package/dist/providers/oauth/secure-credential-store.d.ts +67 -0
  394. package/dist/providers/oauth/secure-credential-store.d.ts.map +1 -0
  395. package/dist/providers/oauth/secure-credential-store.js +73 -0
  396. package/dist/providers/oauth/secure-credential-store.js.map +1 -0
  397. package/dist/providers/oauth/token-store.d.ts +53 -0
  398. package/dist/providers/oauth/token-store.d.ts.map +1 -0
  399. package/dist/providers/oauth/token-store.js +78 -0
  400. package/dist/providers/oauth/token-store.js.map +1 -0
  401. package/dist/providers/oauth/types.d.ts +64 -0
  402. package/dist/providers/oauth/types.d.ts.map +1 -0
  403. package/dist/providers/oauth/types.js +12 -0
  404. package/dist/providers/oauth/types.js.map +1 -0
  405. package/dist/providers/object-tracking.d.ts +47 -0
  406. package/dist/providers/object-tracking.d.ts.map +1 -0
  407. package/dist/providers/object-tracking.js +46 -0
  408. package/dist/providers/object-tracking.js.map +1 -0
  409. package/dist/providers/offline-model-index.d.ts +20 -0
  410. package/dist/providers/offline-model-index.d.ts.map +1 -0
  411. package/dist/providers/offline-model-index.js +112 -0
  412. package/dist/providers/offline-model-index.js.map +1 -0
  413. package/dist/providers/ollama-provider.d.ts +28 -1
  414. package/dist/providers/ollama-provider.d.ts.map +1 -1
  415. package/dist/providers/ollama-provider.js +193 -43
  416. package/dist/providers/ollama-provider.js.map +1 -1
  417. package/dist/providers/openai-compat/client.d.ts +57 -0
  418. package/dist/providers/openai-compat/client.d.ts.map +1 -0
  419. package/dist/providers/openai-compat/client.js +157 -0
  420. package/dist/providers/openai-compat/client.js.map +1 -0
  421. package/dist/providers/openai-compat/decode.d.ts +36 -0
  422. package/dist/providers/openai-compat/decode.d.ts.map +1 -0
  423. package/dist/providers/openai-compat/decode.js +55 -0
  424. package/dist/providers/openai-compat/decode.js.map +1 -0
  425. package/dist/providers/openai-compat/errors.d.ts +54 -0
  426. package/dist/providers/openai-compat/errors.d.ts.map +1 -0
  427. package/dist/providers/openai-compat/errors.js +144 -0
  428. package/dist/providers/openai-compat/errors.js.map +1 -0
  429. package/dist/providers/openai-compat/index.d.ts +8 -0
  430. package/dist/providers/openai-compat/index.d.ts.map +1 -0
  431. package/dist/providers/openai-compat/index.js +5 -0
  432. package/dist/providers/openai-compat/index.js.map +1 -0
  433. package/dist/providers/openai-compat/sse.d.ts +14 -0
  434. package/dist/providers/openai-compat/sse.d.ts.map +1 -0
  435. package/dist/providers/openai-compat/sse.js +69 -0
  436. package/dist/providers/openai-compat/sse.js.map +1 -0
  437. package/dist/providers/openai-compat/types.d.ts +75 -0
  438. package/dist/providers/openai-compat/types.d.ts.map +1 -0
  439. package/dist/providers/openai-compat/types.js +9 -0
  440. package/dist/providers/openai-compat/types.js.map +1 -0
  441. package/dist/providers/openai-compat-provider.d.ts +90 -0
  442. package/dist/providers/openai-compat-provider.d.ts.map +1 -0
  443. package/dist/providers/openai-compat-provider.js +282 -0
  444. package/dist/providers/openai-compat-provider.js.map +1 -0
  445. package/dist/providers/openai-provider.d.ts +89 -26
  446. package/dist/providers/openai-provider.d.ts.map +1 -1
  447. package/dist/providers/openai-provider.js +990 -105
  448. package/dist/providers/openai-provider.js.map +1 -1
  449. package/dist/providers/openrouter-provider.d.ts +6 -12
  450. package/dist/providers/openrouter-provider.d.ts.map +1 -1
  451. package/dist/providers/openrouter-provider.js +24 -53
  452. package/dist/providers/openrouter-provider.js.map +1 -1
  453. package/dist/providers/provider-call-failure.d.ts +39 -0
  454. package/dist/providers/provider-call-failure.d.ts.map +1 -0
  455. package/dist/providers/provider-call-failure.js +132 -0
  456. package/dist/providers/provider-call-failure.js.map +1 -0
  457. package/dist/providers/provider-error.d.ts +59 -0
  458. package/dist/providers/provider-error.d.ts.map +1 -0
  459. package/dist/providers/provider-error.js +165 -0
  460. package/dist/providers/provider-error.js.map +1 -0
  461. package/dist/providers/provider-generations.d.ts +99 -0
  462. package/dist/providers/provider-generations.d.ts.map +1 -0
  463. package/dist/providers/provider-generations.js +71 -0
  464. package/dist/providers/provider-generations.js.map +1 -0
  465. package/dist/providers/provider-queue.d.ts +62 -0
  466. package/dist/providers/provider-queue.d.ts.map +1 -0
  467. package/dist/providers/provider-queue.js +28 -0
  468. package/dist/providers/provider-queue.js.map +1 -0
  469. package/dist/providers/provider-registry.d.ts +33 -14
  470. package/dist/providers/provider-registry.d.ts.map +1 -1
  471. package/dist/providers/provider-registry.js +85 -68
  472. package/dist/providers/provider-registry.js.map +1 -1
  473. package/dist/providers/provider-request-log.d.ts +53 -0
  474. package/dist/providers/provider-request-log.d.ts.map +1 -0
  475. package/dist/providers/provider-request-log.js +157 -0
  476. package/dist/providers/provider-request-log.js.map +1 -0
  477. package/dist/providers/provider-session.d.ts +3 -0
  478. package/dist/providers/provider-session.d.ts.map +1 -0
  479. package/dist/providers/provider-session.js +10 -0
  480. package/dist/providers/provider-session.js.map +1 -0
  481. package/dist/providers/provider-transport.d.ts +11 -0
  482. package/dist/providers/provider-transport.d.ts.map +1 -0
  483. package/dist/providers/provider-transport.js +11 -0
  484. package/dist/providers/provider-transport.js.map +1 -0
  485. package/dist/providers/python-provider.d.ts +20 -12
  486. package/dist/providers/python-provider.d.ts.map +1 -1
  487. package/dist/providers/python-provider.js +185 -25
  488. package/dist/providers/python-provider.js.map +1 -1
  489. package/dist/providers/replicate-provider.d.ts +89 -7
  490. package/dist/providers/replicate-provider.d.ts.map +1 -1
  491. package/dist/providers/replicate-provider.js +801 -65
  492. package/dist/providers/replicate-provider.js.map +1 -1
  493. package/dist/providers/replicate-retry.d.ts +30 -0
  494. package/dist/providers/replicate-retry.d.ts.map +1 -0
  495. package/dist/providers/replicate-retry.js +97 -0
  496. package/dist/providers/replicate-retry.js.map +1 -0
  497. package/dist/providers/responses-api.d.ts +27 -0
  498. package/dist/providers/responses-api.d.ts.map +1 -0
  499. package/dist/providers/responses-api.js +297 -0
  500. package/dist/providers/responses-api.js.map +1 -0
  501. package/dist/providers/reve-provider.d.ts +45 -0
  502. package/dist/providers/reve-provider.d.ts.map +1 -0
  503. package/dist/providers/reve-provider.js +159 -0
  504. package/dist/providers/reve-provider.js.map +1 -0
  505. package/dist/providers/rodin-provider.d.ts +23 -1
  506. package/dist/providers/rodin-provider.d.ts.map +1 -1
  507. package/dist/providers/rodin-provider.js +89 -51
  508. package/dist/providers/rodin-provider.js.map +1 -1
  509. package/dist/providers/safe-url.d.ts +70 -0
  510. package/dist/providers/safe-url.d.ts.map +1 -0
  511. package/dist/providers/safe-url.js +277 -0
  512. package/dist/providers/safe-url.js.map +1 -0
  513. package/dist/providers/scripted-provider.d.ts +9 -0
  514. package/dist/providers/scripted-provider.d.ts.map +1 -1
  515. package/dist/providers/scripted-provider.js +86 -10
  516. package/dist/providers/scripted-provider.js.map +1 -1
  517. package/dist/providers/structured-output.d.ts +42 -0
  518. package/dist/providers/structured-output.d.ts.map +1 -0
  519. package/dist/providers/structured-output.js +83 -0
  520. package/dist/providers/structured-output.js.map +1 -0
  521. package/dist/providers/together-provider.d.ts +19 -16
  522. package/dist/providers/together-provider.d.ts.map +1 -1
  523. package/dist/providers/together-provider.js +103 -225
  524. package/dist/providers/together-provider.js.map +1 -1
  525. package/dist/providers/topaz-provider.d.ts +44 -0
  526. package/dist/providers/topaz-provider.d.ts.map +1 -0
  527. package/dist/providers/topaz-provider.js +239 -0
  528. package/dist/providers/topaz-provider.js.map +1 -0
  529. package/dist/providers/types.d.ts +603 -4
  530. package/dist/providers/types.d.ts.map +1 -1
  531. package/dist/providers/types.js +81 -1
  532. package/dist/providers/types.js.map +1 -1
  533. package/dist/providers/useapi-provider.d.ts +27 -0
  534. package/dist/providers/useapi-provider.d.ts.map +1 -0
  535. package/dist/providers/useapi-provider.js +266 -0
  536. package/dist/providers/useapi-provider.js.map +1 -0
  537. package/dist/providers/video-duration.d.ts +6 -0
  538. package/dist/providers/video-duration.d.ts.map +1 -0
  539. package/dist/providers/video-duration.js +63 -0
  540. package/dist/providers/video-duration.js.map +1 -0
  541. package/dist/providers/video-frame-fallback.d.ts +39 -0
  542. package/dist/providers/video-frame-fallback.d.ts.map +1 -0
  543. package/dist/providers/video-frame-fallback.js +155 -0
  544. package/dist/providers/video-frame-fallback.js.map +1 -0
  545. package/dist/providers/video-frames.d.ts +61 -0
  546. package/dist/providers/video-frames.d.ts.map +1 -0
  547. package/dist/providers/video-frames.js +208 -0
  548. package/dist/providers/video-frames.js.map +1 -0
  549. package/dist/providers/video-mime.d.ts +14 -0
  550. package/dist/providers/video-mime.d.ts.map +1 -0
  551. package/dist/providers/video-mime.js +44 -0
  552. package/dist/providers/video-mime.js.map +1 -0
  553. package/dist/providers/video-to-audio.d.ts +34 -0
  554. package/dist/providers/video-to-audio.d.ts.map +1 -0
  555. package/dist/providers/video-to-audio.js +62 -0
  556. package/dist/providers/video-to-audio.js.map +1 -0
  557. package/dist/providers/vllm-provider.d.ts +22 -8
  558. package/dist/providers/vllm-provider.d.ts.map +1 -1
  559. package/dist/providers/vllm-provider.js +48 -23
  560. package/dist/providers/vllm-provider.js.map +1 -1
  561. package/dist/providers/voyage-provider.d.ts +10 -2
  562. package/dist/providers/voyage-provider.d.ts.map +1 -1
  563. package/dist/providers/voyage-provider.js +16 -7
  564. package/dist/providers/voyage-provider.js.map +1 -1
  565. package/dist/providers/xai-provider.d.ts +54 -13
  566. package/dist/providers/xai-provider.d.ts.map +1 -1
  567. package/dist/providers/xai-provider.js +299 -22
  568. package/dist/providers/xai-provider.js.map +1 -1
  569. package/dist/python-bridge-base.d.ts +358 -0
  570. package/dist/python-bridge-base.d.ts.map +1 -0
  571. package/dist/python-bridge-base.js +1557 -0
  572. package/dist/python-bridge-base.js.map +1 -0
  573. package/dist/python-bridge-codec.d.ts +28 -0
  574. package/dist/python-bridge-codec.d.ts.map +1 -0
  575. package/dist/python-bridge-codec.js +39 -0
  576. package/dist/python-bridge-codec.js.map +1 -0
  577. package/dist/python-bridge-factory.d.ts +52 -0
  578. package/dist/python-bridge-factory.d.ts.map +1 -0
  579. package/dist/python-bridge-factory.js +69 -0
  580. package/dist/python-bridge-factory.js.map +1 -0
  581. package/dist/python-bridge-framing.d.ts +68 -0
  582. package/dist/python-bridge-framing.d.ts.map +1 -0
  583. package/dist/python-bridge-framing.js +91 -0
  584. package/dist/python-bridge-framing.js.map +1 -0
  585. package/dist/python-bridge-types.d.ts +545 -2
  586. package/dist/python-bridge-types.d.ts.map +1 -1
  587. package/dist/python-bridge-types.js +49 -1
  588. package/dist/python-bridge-types.js.map +1 -1
  589. package/dist/python-graph-resolver.d.ts +57 -0
  590. package/dist/python-graph-resolver.d.ts.map +1 -0
  591. package/dist/python-graph-resolver.js +79 -0
  592. package/dist/python-graph-resolver.js.map +1 -0
  593. package/dist/python-node-executor.d.ts +36 -4
  594. package/dist/python-node-executor.d.ts.map +1 -1
  595. package/dist/python-node-executor.js +177 -86
  596. package/dist/python-node-executor.js.map +1 -1
  597. package/dist/python-stdio-bridge.d.ts +18 -37
  598. package/dist/python-stdio-bridge.d.ts.map +1 -1
  599. package/dist/python-stdio-bridge.js +148 -475
  600. package/dist/python-stdio-bridge.js.map +1 -1
  601. package/dist/python-websocket-bridge.d.ts +140 -0
  602. package/dist/python-websocket-bridge.d.ts.map +1 -0
  603. package/dist/python-websocket-bridge.js +561 -0
  604. package/dist/python-websocket-bridge.js.map +1 -0
  605. package/dist/python-worker-stderr.d.ts +4 -0
  606. package/dist/python-worker-stderr.d.ts.map +1 -0
  607. package/dist/python-worker-stderr.js +24 -0
  608. package/dist/python-worker-stderr.js.map +1 -0
  609. package/dist/recommended-models.d.ts +2 -2
  610. package/dist/recommended-models.d.ts.map +1 -1
  611. package/dist/recommended-models.js +24 -4
  612. package/dist/recommended-models.js.map +1 -1
  613. package/dist/recoverable-node-error.d.ts +31 -0
  614. package/dist/recoverable-node-error.d.ts.map +1 -0
  615. package/dist/recoverable-node-error.js +37 -0
  616. package/dist/recoverable-node-error.js.map +1 -0
  617. package/dist/redact-params.d.ts +13 -0
  618. package/dist/redact-params.d.ts.map +1 -0
  619. package/dist/redact-params.js +57 -0
  620. package/dist/redact-params.js.map +1 -0
  621. package/dist/sandbox-module-catalog.d.ts +43 -0
  622. package/dist/sandbox-module-catalog.d.ts.map +1 -0
  623. package/dist/sandbox-module-catalog.js +25 -0
  624. package/dist/sandbox-module-catalog.js.map +1 -0
  625. package/dist/storage-workspace.d.ts +59 -0
  626. package/dist/storage-workspace.d.ts.map +1 -0
  627. package/dist/storage-workspace.js +426 -0
  628. package/dist/storage-workspace.js.map +1 -0
  629. package/dist/swappable-python-bridge.d.ts +83 -0
  630. package/dist/swappable-python-bridge.d.ts.map +1 -0
  631. package/dist/swappable-python-bridge.js +246 -0
  632. package/dist/swappable-python-bridge.js.map +1 -0
  633. package/dist/telemetry.d.ts +7 -0
  634. package/dist/telemetry.d.ts.map +1 -1
  635. package/dist/telemetry.js +23 -0
  636. package/dist/telemetry.js.map +1 -1
  637. package/dist/testing.d.ts +81 -0
  638. package/dist/testing.d.ts.map +1 -0
  639. package/dist/testing.js +130 -0
  640. package/dist/testing.js.map +1 -0
  641. package/dist/token-counter.d.ts +30 -0
  642. package/dist/token-counter.d.ts.map +1 -0
  643. package/dist/token-counter.js +156 -0
  644. package/dist/token-counter.js.map +1 -0
  645. package/dist/trace-exporters.d.ts +10 -0
  646. package/dist/trace-exporters.d.ts.map +1 -1
  647. package/dist/trace-exporters.js +59 -20
  648. package/dist/trace-exporters.js.map +1 -1
  649. package/dist/tracing-helpers.d.ts +45 -4
  650. package/dist/tracing-helpers.d.ts.map +1 -1
  651. package/dist/tracing-helpers.js +62 -19
  652. package/dist/tracing-helpers.js.map +1 -1
  653. package/dist/turn-budget.d.ts +278 -0
  654. package/dist/turn-budget.d.ts.map +1 -0
  655. package/dist/turn-budget.js +365 -0
  656. package/dist/turn-budget.js.map +1 -0
  657. package/dist/variable-channel.d.ts +48 -0
  658. package/dist/variable-channel.d.ts.map +1 -0
  659. package/dist/variable-channel.js +110 -0
  660. package/dist/variable-channel.js.map +1 -0
  661. package/dist/workspace.d.ts +119 -0
  662. package/dist/workspace.d.ts.map +1 -0
  663. package/dist/workspace.js +112 -0
  664. package/dist/workspace.js.map +1 -0
  665. package/package.json +107 -19
@@ -8,69 +8,55 @@
8
8
  * Protocol: [4 bytes big-endian length][msgpack payload]
9
9
  * Readiness: "NODETOOL_STDIO_READY" on stderr
10
10
  * Logs: all Python output goes to stderr
11
+ *
12
+ * Transport-agnostic protocol logic lives in PythonBridgeBase; this subclass
13
+ * supplies the stdio transport (subprocess spawn + length-prefixed framing).
11
14
  */
12
- import * as msgpack from "@msgpack/msgpack";
13
- import { randomUUID } from "node:crypto";
14
- import { spawn } from "node:child_process";
15
- import { EventEmitter } from "node:events";
16
- import { existsSync } from "node:fs";
17
- import { homedir } from "node:os";
18
- import { basename, join } from "node:path";
19
- import { createLogger } from "@nodetool-ai/config";
20
- import { BRIDGE_PROTOCOL_VERSION, MIN_NODETOOL_CORE_VERSION } from "@nodetool-ai/protocol/bridge-protocol";
15
+ import { packBridgeMessage, unpackBridgeMessage } from "./python-bridge-codec.js";
16
+ import { getNodeBuiltinSync } from "@nodetool-ai/config";
17
+ // Python bridge is fundamentally Node-only (subprocess + raw FDs).
18
+ // Lazy-load the builtins so the module *graph* loads off-Node;
19
+ // instantiating PythonStdioBridge there throws at construction.
20
+ const nodeCp = getNodeBuiltinSync("node:child_process");
21
+ const nodeFs = getNodeBuiltinSync("node:fs");
22
+ const nodeOs = getNodeBuiltinSync("node:os");
23
+ const nodePath = getNodeBuiltinSync("node:path");
24
+ function notOnNode(api) {
25
+ throw new Error(`${api} requires Node — PythonStdioBridge is Node-only`);
26
+ }
27
+ const spawn = (...args) => nodeCp ? nodeCp.spawn(...args) : notOnNode("node:child_process.spawn");
28
+ const existsSync = (p) => nodeFs ? nodeFs.existsSync(p) : notOnNode("node:fs.existsSync");
29
+ const homedir = () => nodeOs ? nodeOs.homedir() : notOnNode("node:os.homedir");
30
+ const basename = (p) => nodePath ? nodePath.basename(p) : notOnNode("node:path.basename");
31
+ const join = (...parts) => nodePath ? nodePath.join(...parts) : notOnNode("node:path.join");
32
+ import { createLogger, getByteLimitEnv, safeProcessEnv, safeProcessPlatform } from "@nodetool-ai/config";
33
+ import { PythonBridgeBase } from "./python-bridge-base.js";
34
+ import { encodeFrame, FrameDecoder, FrameSizeError } from "./python-bridge-framing.js";
21
35
  const log = createLogger("nodetool.runtime.python-stdio-bridge");
22
- const MAX_BRIDGE_FRAME_SIZE = Number(process.env["NODETOOL_BRIDGE_MAX_FRAME_SIZE"] ?? 256 * 1024 * 1024);
23
- const PYTHON_BRIDGE_ALLOWED_IN_PRODUCTION = process.env["NODETOOL_ALLOW_PYTHON_BRIDGE_IN_PRODUCTION"] === "1";
36
+ const MAX_BRIDGE_FRAME_SIZE = getByteLimitEnv("NODETOOL_BRIDGE_MAX_FRAME_SIZE", 256 * 1024 * 1024);
37
+ const PYTHON_BRIDGE_ALLOWED_IN_PRODUCTION = safeProcessEnv()["NODETOOL_ALLOW_PYTHON_BRIDGE_IN_PRODUCTION"] === "1";
24
38
  function isProductionMode() {
25
- return process.env["NODETOOL_ENV"] === "production";
39
+ return safeProcessEnv()["NODETOOL_ENV"] === "production";
26
40
  }
27
- export class PythonStdioBridge extends EventEmitter {
41
+ export class PythonStdioBridge extends PythonBridgeBase {
28
42
  _process = null;
29
- _nodeMetadata = [];
30
- _loadErrors = [];
31
- _workerStatus = null;
32
- _pending = new Map();
33
- _pendingStream = new Map();
34
- _options;
35
- _connected = false;
36
- _connectPromise = null;
37
- /** Buffered stdout data waiting to be parsed into frames. */
38
- _readBuffer = Buffer.alloc(0);
43
+ /** Incremental length-prefixed frame decoder for stdout. */
44
+ _frameDecoder = new FrameDecoder({
45
+ maxFrameSize: MAX_BRIDGE_FRAME_SIZE
46
+ });
39
47
  /** Recent stderr lines from the worker for diagnostics. */
40
48
  _recentStderr = [];
41
49
  constructor(options = {}) {
42
- super();
43
- this._options = options;
50
+ super(options);
44
51
  }
45
- // ── Connection lifecycle ───────────────────────────────────────────
46
- async connect() {
52
+ // ── Connection guard ───────────────────────────────────────────────
53
+ _assertCanConnect() {
47
54
  if (isProductionMode() && !PYTHON_BRIDGE_ALLOWED_IN_PRODUCTION) {
48
55
  throw new Error("Python bridge is disabled in production. Python workers are a local-only feature.");
49
56
  }
50
- await this._spawnAndConnect();
51
- await this._discover();
52
- try {
53
- await this.getWorkerStatus();
54
- }
55
- catch (err) {
56
- log.warn("Failed to fetch initial Python worker status; load_errors will be unavailable until next status fetch", err);
57
- }
58
57
  }
59
- ensureConnected() {
60
- if (this._connected)
61
- return Promise.resolve();
62
- if (!this._connectPromise) {
63
- this._connectPromise = this.connect().then(() => {
64
- this._connectPromise = null;
65
- }, (err) => {
66
- this._connectPromise = null;
67
- throw err;
68
- });
69
- }
70
- return this._connectPromise;
71
- }
72
- // ── Spawn & stdio setup ────────────────────────────────────────────
73
- async _spawnAndConnect() {
58
+ // ── Transport: spawn & stdio setup ─────────────────────────────────
59
+ async _openTransport() {
74
60
  const candidates = this._getPythonLaunchCandidates();
75
61
  let lastError = null;
76
62
  for (const candidate of candidates) {
@@ -97,7 +83,22 @@ export class PythonStdioBridge extends EventEmitter {
97
83
  ];
98
84
  return new Promise((resolve, reject) => {
99
85
  const proc = spawn(candidate.command, args, {
100
- stdio: ["pipe", "pipe", "pipe"]
86
+ stdio: ["pipe", "pipe", "pipe"],
87
+ env: {
88
+ // Default before the spread so a user-set value still wins. Reduces
89
+ // CUDA allocator fragmentation (the WDDM PCIe-spill on VAE decode);
90
+ // only takes effect when set before torch initializes CUDA, which is
91
+ // why it belongs here rather than in a node's process().
92
+ PYTORCH_CUDA_ALLOC_CONF: "expandable_segments:True",
93
+ // The options object is built before `spawn` runs, so a bare
94
+ // `process.env` here would throw `ReferenceError` off-Node instead
95
+ // of the `notOnNode("node:child_process.spawn")` this file goes out
96
+ // of its way to raise.
97
+ ...safeProcessEnv(),
98
+ TQDM_DISABLE: "1",
99
+ HF_HUB_DISABLE_PROGRESS_BARS: "1",
100
+ TRANSFORMERS_VERBOSITY: "error"
101
+ }
101
102
  });
102
103
  this._process = proc;
103
104
  let ready = false;
@@ -106,13 +107,34 @@ export class PythonStdioBridge extends EventEmitter {
106
107
  const startupTimeoutMs = this._options.startupTimeoutMs ?? 20000;
107
108
  const startupTimer = setTimeout(() => {
108
109
  settleError(new Error(`Python worker did not become ready within ${startupTimeoutMs}ms.` +
109
- (stderrOutput.trim() ? ` Recent stderr: ${stderrOutput.trim()}` : "")));
110
+ (stderrOutput.trim()
111
+ ? ` Recent stderr: ${stderrOutput.trim()}`
112
+ : "")));
110
113
  }, startupTimeoutMs);
111
114
  const settleError = (error) => {
112
115
  if (settled)
113
116
  return;
114
117
  settled = true;
115
118
  clearTimeout(startupTimer);
119
+ // Tear down this candidate so a timed-out or failed spawn doesn't leak:
120
+ // its stdout handler would keep appending to the SHARED frame decoder
121
+ // (desyncing the next candidate's frame stream) and the heavy worker
122
+ // (mid torch/CUDA import) would stay alive forever.
123
+ proc.stdout?.removeAllListeners();
124
+ proc.stderr?.removeAllListeners();
125
+ proc.stdin?.removeAllListeners();
126
+ proc.stdin?.on("error", () => { });
127
+ try {
128
+ proc.kill();
129
+ }
130
+ catch {
131
+ // already dead
132
+ }
133
+ if (this._process === proc) {
134
+ this._process = null;
135
+ this._connected = false;
136
+ }
137
+ this._frameDecoder.reset();
116
138
  reject(error);
117
139
  };
118
140
  const settleSuccess = () => {
@@ -124,8 +146,7 @@ export class PythonStdioBridge extends EventEmitter {
124
146
  };
125
147
  // Stdout is binary protocol data — accumulate and parse frames.
126
148
  proc.stdout.on("data", (chunk) => {
127
- this._readBuffer = Buffer.concat([this._readBuffer, chunk]);
128
- this._drainFrames();
149
+ this._drainFrames(chunk);
129
150
  });
130
151
  // Stderr carries logs and the readiness signal.
131
152
  proc.stderr.on("data", (chunk) => {
@@ -143,6 +164,20 @@ export class PythonStdioBridge extends EventEmitter {
143
164
  if (!ready)
144
165
  settleError(err);
145
166
  });
167
+ // stdin is a separate stream (EventEmitter) from the ChildProcess, so
168
+ // proc.on("error") does NOT cover write failures. Without this listener a
169
+ // broken-pipe write (EPIPE/ECONNRESET while the worker is exiting) emits
170
+ // an unhandled 'error' that crashes the whole Node backend. Fail the
171
+ // in-flight requests instead.
172
+ proc.stdin.on("error", (err) => {
173
+ this._connected = false;
174
+ if (!ready) {
175
+ settleError(err);
176
+ }
177
+ else {
178
+ this._rejectAllPending(new Error(`Python worker stdin error: ${err.message}`));
179
+ }
180
+ });
146
181
  proc.on("exit", (code) => {
147
182
  this._connected = false;
148
183
  if (!ready) {
@@ -177,436 +212,64 @@ export class PythonStdioBridge extends EventEmitter {
177
212
  });
178
213
  }
179
214
  // ── Frame reader ───────────────────────────────────────────────────
180
- /** Extract complete length-prefixed frames from _readBuffer. */
181
- _drainFrames() {
182
- while (this._readBuffer.length >= 4) {
183
- const length = this._readBuffer.readUInt32BE(0);
184
- if (length > MAX_BRIDGE_FRAME_SIZE) {
185
- this.emit("error", new Error(`Incoming Python bridge frame exceeds max size (${length} > ${MAX_BRIDGE_FRAME_SIZE})`));
186
- this.close();
215
+ /** Extract complete length-prefixed frames from a stdout chunk. */
216
+ _drainFrames(chunk) {
217
+ // Dispatch every valid frame as soon as `FrameDecoder.push` extracts it,
218
+ // so frames preceding a corrupt one (a bad length prefix later in the
219
+ // same chunk) still reach `_handleMessage` — only the protocol failure
220
+ // itself is deferred to after dispatch.
221
+ try {
222
+ this._frameDecoder.push(chunk, (payload) => {
223
+ try {
224
+ const msg = unpackBridgeMessage(payload);
225
+ this._handleMessage(msg);
226
+ }
227
+ catch (err) {
228
+ throw new Error(`Failed to decode msgpack frame: ${err}`);
229
+ }
230
+ });
231
+ }
232
+ catch (err) {
233
+ if (err instanceof FrameSizeError) {
234
+ const stderrHint = this.getRecentStderrSummary(6);
235
+ const desyncHint = "This usually means the Python worker wrote non-protocol data to stdout " +
236
+ "(for example a library print/progress bar), desynchronizing the msgpack frame stream.";
237
+ this._failProtocol(new Error(`${err.message}. ${desyncHint}` +
238
+ (stderrHint ? ` Recent stderr: ${stderrHint}` : "")));
187
239
  return;
188
240
  }
189
- if (this._readBuffer.length < 4 + length)
190
- break; // incomplete frame
191
- const payload = this._readBuffer.subarray(4, 4 + length);
192
- this._readBuffer = this._readBuffer.subarray(4 + length);
193
- try {
194
- const msg = msgpack.decode(payload);
195
- this._handleMessage(msg);
196
- }
197
- catch (err) {
198
- this.emit("error", new Error(`Failed to decode msgpack frame: ${err}`));
199
- }
241
+ this._failProtocol(err instanceof Error ? err : new Error(String(err)));
200
242
  }
201
243
  }
244
+ _failProtocol(error) {
245
+ log.error(error.message);
246
+ this._rejectAllPending(error);
247
+ this.close();
248
+ }
202
249
  // ── Send ───────────────────────────────────────────────────────────
203
250
  _send(msg) {
204
251
  if (!this._process?.stdin || !this._connected) {
205
252
  throw new Error("Not connected to Python worker");
206
253
  }
207
- const payload = Buffer.from(msgpack.encode(msg));
254
+ const payload = Buffer.from(packBridgeMessage(msg));
208
255
  if (payload.length > MAX_BRIDGE_FRAME_SIZE) {
209
256
  throw new Error(`Outgoing Python bridge frame exceeds max size (${payload.length} > ${MAX_BRIDGE_FRAME_SIZE})`);
210
257
  }
211
- const header = Buffer.alloc(4);
212
- header.writeUInt32BE(payload.length, 0);
213
- this._process.stdin.write(header);
214
- this._process.stdin.write(payload);
215
- }
216
- // ── Message dispatch ────────────────────────────────────────────────
217
- _handleMessage(msg) {
218
- const type = msg.type;
219
- const requestId = msg.request_id;
220
- if (type === "discover" && requestId) {
221
- const pending = this._pending.get(requestId);
222
- if (pending) {
223
- const data = msg.data;
224
- // Reject the discover promise if the worker's protocol is older
225
- // than what this build of the JS runtime requires. Workers that
226
- // pre-date the protocol_version field are treated as version 1
227
- // (the initial protocol release) — they speak the same wire
228
- // format as v1, they just don't announce it.
229
- const workerVersion = typeof data.protocol_version === "number"
230
- ? data.protocol_version
231
- : 1;
232
- if (workerVersion < BRIDGE_PROTOCOL_VERSION) {
233
- this._pending.delete(requestId);
234
- pending.reject(new Error(`The installed nodetool-core speaks bridge protocol v${workerVersion}, ` +
235
- `but this Nodetool build requires v${BRIDGE_PROTOCOL_VERSION}. ` +
236
- `Please reinstall the Python environment from Settings → Packages ` +
237
- `(Reinstall environment) — it will fetch nodetool-core>=${MIN_NODETOOL_CORE_VERSION}.`));
238
- return;
239
- }
240
- if (workerVersion > BRIDGE_PROTOCOL_VERSION) {
241
- // Forward-compat: a newer worker is expected to keep speaking
242
- // older protocols, so we proceed with a warning.
243
- this.emit("stderr", `[python-bridge] Worker protocol v${workerVersion} is newer than ` +
244
- `JS runtime v${BRIDGE_PROTOCOL_VERSION}; assuming backward compatibility.\n`);
245
- }
246
- this._nodeMetadata = data.nodes;
247
- this._loadErrors = data.load_errors ?? [];
248
- pending.resolve({ outputs: {}, blobs: {} });
249
- }
250
- }
251
- else if (type === "result" && requestId) {
252
- const streamReq = this._pendingStream.get(requestId);
253
- if (streamReq) {
254
- this._pendingStream.delete(requestId);
255
- streamReq.resolve(msg.data);
256
- return;
257
- }
258
- const pending = this._pending.get(requestId);
259
- if (pending) {
260
- this._pending.delete(requestId);
261
- const data = msg.data;
262
- pending.resolve({ outputs: data.outputs, blobs: data.blobs ?? {} });
263
- }
264
- }
265
- else if (type === "error" && requestId) {
266
- const streamReq = this._pendingStream.get(requestId);
267
- if (streamReq) {
268
- this._pendingStream.delete(requestId);
269
- const data = msg.data;
270
- const err = new Error(data.error);
271
- err.traceback = data.traceback;
272
- streamReq.reject(err);
273
- return;
274
- }
275
- const pending = this._pending.get(requestId);
276
- if (pending) {
277
- this._pending.delete(requestId);
278
- const data = msg.data;
279
- const err = new Error(data.error);
280
- err.traceback = data.traceback;
281
- pending.reject(err);
282
- }
283
- }
284
- else if (type === "chunk" && requestId) {
285
- const streamReq = this._pendingStream.get(requestId);
286
- if (streamReq) {
287
- streamReq.onChunk(msg.data);
288
- }
289
- }
290
- else if (type === "progress" && requestId) {
291
- const pending = this._pending.get(requestId);
292
- if (pending?.onProgress) {
293
- const data = msg.data;
294
- pending.onProgress({ request_id: requestId, ...data });
295
- }
296
- this.emit("progress", msg.data);
297
- }
298
- }
299
- // ── Discover ───────────────────────────────────────────────────────
300
- async _discover() {
301
- const requestId = randomUUID();
302
- return new Promise((resolve, reject) => {
303
- this._pending.set(requestId, {
304
- resolve: () => {
305
- this._pending.delete(requestId);
306
- resolve();
307
- },
308
- reject: (err) => {
309
- this._pending.delete(requestId);
310
- reject(err);
311
- }
312
- });
313
- this._send({ type: "discover", request_id: requestId, data: {} });
314
- });
315
- }
316
- // ── Node execution ─────────────────────────────────────────────────
317
- async execute(nodeType, fields, secrets, blobs, onProgress) {
318
- const requestId = randomUUID();
319
- return new Promise((resolve, reject) => {
320
- this._pending.set(requestId, { resolve, reject, onProgress });
321
- this._send({
322
- type: "execute",
323
- request_id: requestId,
324
- data: { node_type: nodeType, fields, secrets, blobs }
325
- });
326
- });
327
- }
328
- async *executeStream(nodeType, fields, secrets, blobs, onProgress) {
329
- const requestId = randomUUID();
330
- const chunks = [];
331
- let done = false;
332
- let error = null;
333
- let finalResult = null;
334
- let emittedCount = 0;
335
- let resolveWait = null;
336
- if (onProgress) {
337
- this._pending.set(requestId, {
338
- resolve: () => undefined,
339
- reject: () => undefined,
340
- onProgress
341
- });
342
- }
343
- const onChunk = (chunk) => {
344
- chunks.push({
345
- outputs: chunk.outputs ?? {},
346
- blobs: chunk.blobs ?? {}
347
- });
348
- if (resolveWait) {
349
- resolveWait();
350
- resolveWait = null;
351
- }
352
- };
353
- const streamPromise = new Promise((resolve, reject) => {
354
- this._pendingStream.set(requestId, { resolve, reject, onChunk });
355
- });
356
- streamPromise
357
- .then((result) => {
358
- finalResult = {
359
- outputs: result.outputs ?? {},
360
- blobs: result.blobs ?? {}
361
- };
362
- done = true;
363
- this._pending.delete(requestId);
364
- if (resolveWait) {
365
- resolveWait();
366
- resolveWait = null;
367
- }
368
- })
369
- .catch((err) => {
370
- error = err;
371
- done = true;
372
- this._pending.delete(requestId);
373
- if (resolveWait) {
374
- resolveWait();
375
- resolveWait = null;
376
- }
377
- });
378
- this._send({
379
- type: "execute.stream",
380
- request_id: requestId,
381
- data: { node_type: nodeType, fields, secrets, blobs }
382
- });
383
- while (true) {
384
- while (chunks.length > 0) {
385
- emittedCount += 1;
386
- yield chunks.shift();
387
- }
388
- if (done)
389
- break;
390
- if (error)
391
- throw error;
392
- await new Promise((resolve) => {
393
- resolveWait = resolve;
394
- });
395
- }
396
- if (error)
397
- throw error;
398
- if (emittedCount === 0 && finalResult) {
399
- yield finalResult;
400
- }
401
- }
402
- cancel(requestId) {
403
- this._send({ type: "cancel", request_id: requestId, data: {} });
404
- }
405
- getNodeMetadata() {
406
- return this._nodeMetadata;
407
- }
408
- getLoadErrors() {
409
- return this._loadErrors;
410
- }
411
- async getWorkerStatus() {
412
- const requestId = randomUUID();
413
- const result = await new Promise((resolve, reject) => {
414
- this._pendingStream.set(requestId, {
415
- resolve,
416
- reject,
417
- onChunk: () => { }
418
- });
419
- this._send({ type: "worker.status", request_id: requestId, data: {} });
420
- });
421
- this._workerStatus =
422
- result;
423
- this._loadErrors = this._workerStatus.load_errors ?? this._loadErrors;
424
- return this._workerStatus;
425
- }
426
- hasNodeType(nodeType) {
427
- return this._nodeMetadata.some((n) => n.node_type === nodeType);
428
- }
429
- get isConnected() {
430
- return this._connected;
431
- }
432
- // ── Provider bridge methods ────────────────────────────────────────
433
- async listProviders() {
434
- const result = await this._providerCall("provider.list", {});
435
- return result.providers;
436
- }
437
- async getProviderModels(providerId, modelType, secrets) {
438
- const result = await this._providerCall("provider.models", {
439
- provider: providerId,
440
- model_type: modelType,
441
- secrets: secrets ?? {}
442
- });
443
- return result.models;
444
- }
445
- async providerGenerate(providerId, messages, model, options) {
446
- const result = await this._providerCall("provider.generate", {
447
- provider: providerId,
448
- messages,
449
- model,
450
- ...options
451
- });
452
- return result.message;
453
- }
454
- async *providerStream(providerId, messages, model, options) {
455
- const requestId = randomUUID();
456
- const chunks = [];
457
- let done = false;
458
- let error = null;
459
- let resolveWait = null;
460
- const onChunk = (chunk) => {
461
- chunks.push(chunk);
462
- if (resolveWait) {
463
- resolveWait();
464
- resolveWait = null;
465
- }
466
- };
467
- const streamPromise = new Promise((resolve, reject) => {
468
- this._pendingStream.set(requestId, { resolve, reject, onChunk });
469
- });
470
- streamPromise
471
- .then(() => {
472
- done = true;
473
- if (resolveWait) {
474
- resolveWait();
475
- resolveWait = null;
476
- }
477
- })
478
- .catch((err) => {
479
- error = err;
480
- done = true;
481
- if (resolveWait) {
482
- resolveWait();
483
- resolveWait = null;
484
- }
485
- });
486
- this._send({
487
- type: "provider.stream",
488
- request_id: requestId,
489
- data: { provider: providerId, messages, model, ...options }
490
- });
491
- while (true) {
492
- while (chunks.length > 0)
493
- yield chunks.shift();
494
- if (done)
495
- break;
496
- if (error)
497
- throw error;
498
- await new Promise((resolve) => {
499
- resolveWait = resolve;
500
- });
258
+ // Writing to a broken pipe can throw synchronously (or emit 'error'); turn
259
+ // it into a rejected request rather than an uncaught exception.
260
+ try {
261
+ this._process.stdin.write(encodeFrame(payload));
501
262
  }
502
- if (error)
503
- throw error;
504
- }
505
- async providerTextToImage(providerId, params, secrets) {
506
- const result = await this._providerCall("provider.text_to_image", {
507
- provider: providerId,
508
- params,
509
- secrets: secrets ?? {}
510
- });
511
- return result.blobs.image;
512
- }
513
- async providerImageToImage(providerId, image, params, secrets) {
514
- const result = await this._providerCall("provider.image_to_image", {
515
- provider: providerId,
516
- image,
517
- params,
518
- secrets: secrets ?? {}
519
- });
520
- return result.blobs.image;
521
- }
522
- async *providerTTS(providerId, text, model, options) {
523
- const requestId = randomUUID();
524
- const chunks = [];
525
- let done = false;
526
- let error = null;
527
- let resolveWait = null;
528
- const onChunk = (chunk) => {
529
- const blobs = chunk.blobs;
530
- if (blobs?.audio)
531
- chunks.push(blobs.audio);
532
- if (resolveWait) {
533
- resolveWait();
534
- resolveWait = null;
535
- }
536
- };
537
- const streamPromise = new Promise((resolve, reject) => {
538
- this._pendingStream.set(requestId, { resolve, reject, onChunk });
539
- });
540
- streamPromise
541
- .then(() => {
542
- done = true;
543
- if (resolveWait) {
544
- resolveWait();
545
- resolveWait = null;
546
- }
547
- })
548
- .catch((err) => {
549
- error = err;
550
- done = true;
551
- if (resolveWait) {
552
- resolveWait();
553
- resolveWait = null;
554
- }
555
- });
556
- this._send({
557
- type: "provider.tts",
558
- request_id: requestId,
559
- data: { provider: providerId, text, model, ...options }
560
- });
561
- while (true) {
562
- while (chunks.length > 0)
563
- yield chunks.shift();
564
- if (done)
565
- break;
566
- if (error)
567
- throw error;
568
- await new Promise((resolve) => {
569
- resolveWait = resolve;
570
- });
263
+ catch (err) {
264
+ this._connected = false;
265
+ throw new Error(`Failed to write to Python worker stdin: ${err instanceof Error ? err.message : String(err)}`);
571
266
  }
572
- if (error)
573
- throw error;
574
- }
575
- async providerASR(providerId, audio, model, options) {
576
- const result = await this._providerCall("provider.asr", {
577
- provider: providerId,
578
- audio,
579
- model,
580
- ...options
581
- });
582
- const r = result;
583
- return {
584
- text: r.text,
585
- chunks: r.chunks
586
- };
587
- }
588
- async providerEmbedding(providerId, text, model, dimensions) {
589
- const result = await this._providerCall("provider.embedding", {
590
- provider: providerId,
591
- text,
592
- model,
593
- dimensions
594
- });
595
- return result.embeddings;
596
- }
597
- async _providerCall(type, data) {
598
- const requestId = randomUUID();
599
- return new Promise((resolve, reject) => {
600
- this._pendingStream.set(requestId, {
601
- resolve,
602
- reject,
603
- onChunk: () => { }
604
- });
605
- this._send({ type, request_id: requestId, data });
606
- });
607
267
  }
608
268
  // ── Shutdown ───────────────────────────────────────────────────────
609
269
  close() {
270
+ if (this._pending.size > 0 || this._pendingStream.size > 0) {
271
+ this._rejectAllPending(new Error("Python bridge closed"));
272
+ }
610
273
  if (this._process) {
611
274
  // Close stdin — the Python side will exit cleanly.
612
275
  this._process.stdin?.end();
@@ -614,6 +277,7 @@ export class PythonStdioBridge extends EventEmitter {
614
277
  this._process = null;
615
278
  }
616
279
  this._connected = false;
280
+ this._frameDecoder.reset();
617
281
  }
618
282
  /** Check if a Python interpreter can be found (without spawning). */
619
283
  hasPython() {
@@ -622,6 +286,14 @@ export class PythonStdioBridge extends EventEmitter {
622
286
  }
623
287
  return this._getPythonLaunchCandidates().length > 0;
624
288
  }
289
+ /**
290
+ * For the stdio transport, availability means a local Python interpreter was
291
+ * found (and the bridge is permitted to run in this environment). Delegates to
292
+ * {@link hasPython}.
293
+ */
294
+ isAvailable() {
295
+ return this.hasPython();
296
+ }
625
297
  getRecentStderrLines(limit = 12) {
626
298
  return this._recentStderr.slice(-limit);
627
299
  }
@@ -647,13 +319,13 @@ export class PythonStdioBridge extends EventEmitter {
647
319
  }
648
320
  // ── Python path detection ───────────────────────────────────────────
649
321
  _getPythonLaunchCandidates() {
650
- const explicitPythonPath = this._options.pythonPath ?? process.env.NODETOOL_PYTHON;
322
+ const explicitPythonPath = this._options.pythonPath ?? safeProcessEnv().NODETOOL_PYTHON;
651
323
  if (explicitPythonPath) {
652
324
  return [{ command: explicitPythonPath, source: "NODETOOL_PYTHON" }];
653
325
  }
654
- const condaPrefix = process.env.CONDA_PREFIX;
326
+ const condaPrefix = safeProcessEnv().CONDA_PREFIX;
655
327
  if (condaPrefix && this._looksLikeNodeToolEnv(condaPrefix)) {
656
- const activeEnvPython = process.platform === "win32"
328
+ const activeEnvPython = safeProcessPlatform() === "win32"
657
329
  ? join(condaPrefix, "python.exe")
658
330
  : join(condaPrefix, "bin", "python");
659
331
  if (existsSync(activeEnvPython)) {
@@ -674,11 +346,12 @@ export class PythonStdioBridge extends EventEmitter {
674
346
  }
675
347
  _getManagedPythonPaths() {
676
348
  const home = homedir();
677
- if (process.platform === "win32") {
349
+ const env = safeProcessEnv();
350
+ if (safeProcessPlatform() === "win32") {
678
351
  return [
679
- process.env.ALLUSERSPROFILE
680
- ? join(process.env.ALLUSERSPROFILE, "nodetool", "conda_env", "python.exe")
681
- : join(process.env.APPDATA ?? join(home, "AppData", "Roaming"), "nodetool", "conda_env", "python.exe"),
352
+ env.ALLUSERSPROFILE
353
+ ? join(env.ALLUSERSPROFILE, "nodetool", "conda_env", "python.exe")
354
+ : join(env.APPDATA ?? join(home, "AppData", "Roaming"), "nodetool", "conda_env", "python.exe"),
682
355
  join(home, "Miniconda3", "envs", "nodetool", "python.exe"),
683
356
  join(home, "miniconda3", "envs", "nodetool", "python.exe"),
684
357
  join(home, "Anaconda3", "envs", "nodetool", "python.exe"),
@@ -686,7 +359,7 @@ export class PythonStdioBridge extends EventEmitter {
686
359
  String.raw `C:\ProgramData\nodetool\conda_env\python.exe`
687
360
  ].filter((c, i, a) => existsSync(c) && a.indexOf(c) === i);
688
361
  }
689
- if (process.platform === "darwin") {
362
+ if (safeProcessPlatform() === "darwin") {
690
363
  return [
691
364
  join(home, "nodetool_env", "bin", "python"),
692
365
  join(home, "miniconda3", "envs", "nodetool", "bin", "python"),