@readymadeit/mcp 0.0.0-stage → 0.1.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 (916) hide show
  1. package/README.md +114 -2
  2. package/bundle/LICENSE +201 -0
  3. package/bundle/boards/aggregator-demo-board.json +54 -0
  4. package/bundle/boards/alpaca-board.json +316 -0
  5. package/bundle/boards/animate-board.json +159 -0
  6. package/bundle/boards/ascii-art-demo-board.json +33 -0
  7. package/bundle/boards/ascii-cam-board.json +184 -0
  8. package/bundle/boards/asset-demo-board.json +54 -0
  9. package/bundle/boards/audio-encode-demo-board.json +153 -0
  10. package/bundle/boards/audiolize-board.json +152 -0
  11. package/bundle/boards/batcher-demo-board.json +43 -0
  12. package/bundle/boards/buffer-demo-board.json +53 -0
  13. package/bundle/boards/cache-demo-board.json +59 -0
  14. package/bundle/boards/camera-demo-board.json +28 -0
  15. package/bundle/boards/canvas-demo-board.json +55 -0
  16. package/bundle/boards/changes-demo-board.json +60 -0
  17. package/bundle/boards/court-booking-browser-demo-board.json +221 -0
  18. package/bundle/boards/court-booking-demo-board.json +218 -0
  19. package/bundle/boards/current-time-board.json +32 -0
  20. package/bundle/boards/debounce-demo-board.json +43 -0
  21. package/bundle/boards/decrypt-demo-board.json +47 -0
  22. package/bundle/boards/delay-demo-board.json +28 -0
  23. package/bundle/boards/detect-demo-board.json +64 -0
  24. package/bundle/boards/document-extract-demo-board.json +55 -0
  25. package/bundle/boards/dropitapp-board.json +138 -0
  26. package/bundle/boards/encode-demo-board.json +39 -0
  27. package/bundle/boards/encrypt-board.json +185 -0
  28. package/bundle/boards/encrypt-demo-board.json +39 -0
  29. package/bundle/boards/face-alert-board.json +181 -0
  30. package/bundle/boards/fetcher-demo-board.json +40 -0
  31. package/bundle/boards/fft-demo-board.json +28 -0
  32. package/bundle/boards/filter-demo-board.json +55 -0
  33. package/bundle/boards/flat-map-demo-board.json +42 -0
  34. package/bundle/boards/frame-limit-test-board.json +130 -0
  35. package/bundle/boards/game-board.json +413 -0
  36. package/bundle/boards/game-of-life-board.json +139 -0
  37. package/bundle/boards/game-of-life-demo-board.json +34 -0
  38. package/bundle/boards/gather-demo-board.json +62 -0
  39. package/bundle/boards/group-by-demo-board.json +62 -0
  40. package/bundle/boards/hacker-demo-board.json +45 -0
  41. package/bundle/boards/hacker-news-board.json +741 -0
  42. package/bundle/boards/hash-demo-board.json +40 -0
  43. package/bundle/boards/health-log-browser-demo-board.json +537 -0
  44. package/bundle/boards/health-log-demo-board.json +498 -0
  45. package/bundle/boards/helloworld-board.json +57 -0
  46. package/bundle/boards/hold-demo-board.json +67 -0
  47. package/bundle/boards/hold-scopes-demo-board.json +141 -0
  48. package/bundle/boards/http-client-browser-demo-board.json +379 -0
  49. package/bundle/boards/http-client-demo-board.json +380 -0
  50. package/bundle/boards/image-picker-demo-board.json +22 -0
  51. package/bundle/boards/imap-email-demo-board.json +35 -0
  52. package/bundle/boards/injector-demo-board.json +55 -0
  53. package/bundle/boards/iterator-demo-board.json +55 -0
  54. package/bundle/boards/limit-demo-board.json +66 -0
  55. package/bundle/boards/link-debugger.json +32 -0
  56. package/bundle/boards/live-location-demo-board.json +93 -0
  57. package/bundle/boards/live-radio-cloud-demo-board.json +216 -0
  58. package/bundle/boards/live-radio-cloud-direct-demo-board.json +311 -0
  59. package/bundle/boards/live-radio-demo-board.json +211 -0
  60. package/bundle/boards/live-radio-members-demo-board.json +314 -0
  61. package/bundle/boards/local-storage-demo-board.json +30 -0
  62. package/bundle/boards/lz-compress-demo-board.json +52 -0
  63. package/bundle/boards/map-demo-board.json +46 -0
  64. package/bundle/boards/match-filter-demo-board.json +43 -0
  65. package/bundle/boards/meeting-poll-browser-demo-board.json +649 -0
  66. package/bundle/boards/meeting-poll-demo-board.json +650 -0
  67. package/bundle/boards/microphone-monitor-demo-board.json +28 -0
  68. package/bundle/boards/microphone-speaker-demo-board.json +86 -0
  69. package/bundle/boards/monitor-demo-board.json +52 -0
  70. package/bundle/boards/mounted-endpoint-demo-board-hkp-rt.json +84 -0
  71. package/bundle/boards/mounted-endpoint-demo-board.json +84 -0
  72. package/bundle/boards/nested-rhythm-demo-board.json +1160 -0
  73. package/bundle/boards/next-bus-board.json +52 -0
  74. package/bundle/boards/next-bus-switch-board.json +79 -0
  75. package/bundle/boards/night-groove-demo-board.json +742 -0
  76. package/bundle/boards/noise-alert-board.json +146 -0
  77. package/bundle/boards/offer-followup-demo-board.json +291 -0
  78. package/bundle/boards/offer-intake-demo-board.json +289 -0
  79. package/bundle/boards/offer-intake-hetzner-demo-board.json +286 -0
  80. package/bundle/boards/offer-intake-imap-demo-board.json +289 -0
  81. package/bundle/boards/offer-intake-imap-hetzner-demo-board.json +354 -0
  82. package/bundle/boards/p2p-receiver-demo-board.json +65 -0
  83. package/bundle/boards/p2p-sender-demo-board.json +94 -0
  84. package/bundle/boards/pad-groove-demo-board.json +644 -0
  85. package/bundle/boards/peer-chat-board.json +109 -0
  86. package/bundle/boards/peer-chat-node-board.json +97 -0
  87. package/bundle/boards/qr-code-demo-board.json +22 -0
  88. package/bundle/boards/queue-demo-board.json +239 -0
  89. package/bundle/boards/reduce-demo-board.json +54 -0
  90. package/bundle/boards/remote-named-demo-board-hkp-rt.json +61 -0
  91. package/bundle/boards/remote-named-demo-board.json +61 -0
  92. package/bundle/boards/rss-demo-board.json +530 -0
  93. package/bundle/boards/rss-radio-board.json +515 -0
  94. package/bundle/boards/rss-radio-brief-one-board.json +237 -0
  95. package/bundle/boards/rss-radio-editor-unit-board.json +555 -0
  96. package/bundle/boards/rss-radio-library-unit-board.json +293 -0
  97. package/bundle/boards/rss-radio-unit-board.json +809 -0
  98. package/bundle/boards/rss-radio-voice-unit-board.json +146 -0
  99. package/bundle/boards/runtime-configs/hold-example.json +41 -0
  100. package/bundle/boards/runtime-configs/injector-example.json +23 -0
  101. package/bundle/boards/runtime-configs/speech-to-text-example.json +35 -0
  102. package/bundle/boards/runtime-configs/text-generation-example.json +31 -0
  103. package/bundle/boards/runtime-configs/text-to-speech-example.json +28 -0
  104. package/bundle/boards/runtime-configs/text-to-speech-inflect-example.json +28 -0
  105. package/bundle/boards/runtime-configs/ws-audio-playback-example.json +23 -0
  106. package/bundle/boards/select-demo-board.json +32 -0
  107. package/bundle/boards/send-ntfy-board.json +52 -0
  108. package/bundle/boards/shared-costs-demo-board.json +361 -0
  109. package/bundle/boards/sign-demo-board.json +41 -0
  110. package/bundle/boards/skill-router-demo-board.json +210 -0
  111. package/bundle/boards/smooth-demo-board.json +91 -0
  112. package/bundle/boards/smtp-email-demo-board.json +34 -0
  113. package/bundle/boards/sort-demo-board.json +55 -0
  114. package/bundle/boards/sound-demo-board.json +65 -0
  115. package/bundle/boards/spectral-modifier-board.json +98 -0
  116. package/bundle/boards/speech-synth-demo-board.json +37 -0
  117. package/bundle/boards/speech-to-text-demo-board.json +146 -0
  118. package/bundle/boards/spotify-board.json +75 -0
  119. package/bundle/boards/spread-demo-board.json +35 -0
  120. package/bundle/boards/sql-demo-board.json +56 -0
  121. package/bundle/boards/sql-explorer-board.json +447 -0
  122. package/bundle/boards/sql-explorer-node-board.json +474 -0
  123. package/bundle/boards/sql-import-board.json +156 -0
  124. package/bundle/boards/state-demo-board.json +65 -0
  125. package/bundle/boards/stopper-demo-board.json +40 -0
  126. package/bundle/boards/storage-demo-board.json +193 -0
  127. package/bundle/boards/store-demo-board.json +63 -0
  128. package/bundle/boards/swimlanes-demo-board.json +197 -0
  129. package/bundle/boards/switch-demo-board.json +51 -0
  130. package/bundle/boards/syn-board.json +19 -0
  131. package/bundle/boards/syn-booking-unit-board.json +998 -0
  132. package/bundle/boards/syn-conversations-anthropic-demo-board.json +925 -0
  133. package/bundle/boards/syn-conversations-demo-board.json +925 -0
  134. package/bundle/boards/syn-hotels-unit-board.json +287 -0
  135. package/bundle/boards/syn-mail-desk-board.json +25 -0
  136. package/bundle/boards/syn-mail-desk-unit-board.json +254 -0
  137. package/bundle/boards/telegram-listener-demo-board.json +31 -0
  138. package/bundle/boards/text-generation-anthropic-demo-board.json +66 -0
  139. package/bundle/boards/text-generation-demo-board.json +51 -0
  140. package/bundle/boards/text-generation-local-demo-board.json +80 -0
  141. package/bundle/boards/text-to-speech-demo-board.json +58 -0
  142. package/bundle/boards/timeline-demo-board.json +477 -0
  143. package/bundle/boards/timer-demo-board.json +35 -0
  144. package/bundle/boards/tracks-demo-board.json +95 -0
  145. package/bundle/boards/trigger-pad-demo-board.json +47 -0
  146. package/bundle/boards/triggerpad-board.json +31 -0
  147. package/bundle/boards/triggerpad-recorder-board.json +56 -0
  148. package/bundle/boards/uuid-generator-demo-board.json +166 -0
  149. package/bundle/boards/voice-assistant-demo-board.json +230 -0
  150. package/bundle/boards/voice-assistant-hkp-rt-demo-board.json +239 -0
  151. package/bundle/boards/voice-assistant-local-demo-board.json +232 -0
  152. package/bundle/boards/voice-assistant-skills-demo-board.json +316 -0
  153. package/bundle/boards/voice-assistant-skills-local-demo-board.json +316 -0
  154. package/bundle/boards/xy-pad-demo-board.json +36 -0
  155. package/bundle/docs/content/board-json.md +277 -0
  156. package/bundle/docs/content/boards/alpaca-board.md +56 -0
  157. package/bundle/docs/content/boards/animate-board.md +40 -0
  158. package/bundle/docs/content/boards/ascii-cam-board.md +37 -0
  159. package/bundle/docs/content/boards/audiolize-board.md +47 -0
  160. package/bundle/docs/content/boards/court-booking-browser-demo-board.md +43 -0
  161. package/bundle/docs/content/boards/court-booking-demo-board.md +120 -0
  162. package/bundle/docs/content/boards/current-time-board.md +32 -0
  163. package/bundle/docs/content/boards/dropitapp-board.md +57 -0
  164. package/bundle/docs/content/boards/encrypt-board.md +36 -0
  165. package/bundle/docs/content/boards/face-alert-board.md +50 -0
  166. package/bundle/docs/content/boards/game-board.md +69 -0
  167. package/bundle/docs/content/boards/game-of-life-board.md +47 -0
  168. package/bundle/docs/content/boards/hacker-news-board.md +76 -0
  169. package/bundle/docs/content/boards/health-log-browser-demo-board.md +56 -0
  170. package/bundle/docs/content/boards/health-log-demo-board.md +138 -0
  171. package/bundle/docs/content/boards/helloworld-board.md +40 -0
  172. package/bundle/docs/content/boards/link-debugger.md +31 -0
  173. package/bundle/docs/content/boards/live-radio-cloud-demo-board.md +70 -0
  174. package/bundle/docs/content/boards/live-radio-cloud-direct-demo-board.md +89 -0
  175. package/bundle/docs/content/boards/live-radio-demo-board.md +102 -0
  176. package/bundle/docs/content/boards/live-radio-members-demo-board.md +91 -0
  177. package/bundle/docs/content/boards/meeting-poll-browser-demo-board.md +45 -0
  178. package/bundle/docs/content/boards/meeting-poll-demo-board.md +121 -0
  179. package/bundle/docs/content/boards/mounted-endpoint-demo-board-hkp-rt.md +50 -0
  180. package/bundle/docs/content/boards/nested-rhythm-demo-board.md +165 -0
  181. package/bundle/docs/content/boards/next-bus-board.md +38 -0
  182. package/bundle/docs/content/boards/next-bus-switch-board.md +44 -0
  183. package/bundle/docs/content/boards/night-groove-demo-board.md +110 -0
  184. package/bundle/docs/content/boards/noise-alert-board.md +44 -0
  185. package/bundle/docs/content/boards/pad-groove-demo-board.md +93 -0
  186. package/bundle/docs/content/boards/peer-chat-board.md +49 -0
  187. package/bundle/docs/content/boards/peer-chat-node-board.md +47 -0
  188. package/bundle/docs/content/boards/rss-radio-board.md +221 -0
  189. package/bundle/docs/content/boards/send-ntfy-board.md +33 -0
  190. package/bundle/docs/content/boards/shared-costs-demo-board.md +65 -0
  191. package/bundle/docs/content/boards/spectral-modifier-board.md +55 -0
  192. package/bundle/docs/content/boards/spotify-board.md +46 -0
  193. package/bundle/docs/content/boards/sql-explorer-board.md +70 -0
  194. package/bundle/docs/content/boards/sql-explorer-node-board.md +76 -0
  195. package/bundle/docs/content/boards/sql-import-board.md +37 -0
  196. package/bundle/docs/content/boards/swimlanes-demo-board.md +148 -0
  197. package/bundle/docs/content/boards/syn-mail-desk-board.md +52 -0
  198. package/bundle/docs/content/boards/timeline-demo-board.md +115 -0
  199. package/bundle/docs/content/boards/triggerpad-board.md +32 -0
  200. package/bundle/docs/content/boards/triggerpad-recorder-board.md +52 -0
  201. package/bundle/docs/content/boards/voice-assistant-demo-board.md +51 -0
  202. package/bundle/docs/content/concepts/assets.md +245 -0
  203. package/bundle/docs/content/concepts/blocks.md +300 -0
  204. package/bundle/docs/content/concepts/board-assistant.md +307 -0
  205. package/bundle/docs/content/concepts/board.md +265 -0
  206. package/bundle/docs/content/concepts/cloud-boards.md +803 -0
  207. package/bundle/docs/content/concepts/coordinator.md +297 -0
  208. package/bundle/docs/content/concepts/logging.md +293 -0
  209. package/bundle/docs/content/concepts/mounts.md +314 -0
  210. package/bundle/docs/content/concepts/presets.md +360 -0
  211. package/bundle/docs/content/concepts/remotes.md +423 -0
  212. package/bundle/docs/content/concepts/runtime.md +664 -0
  213. package/bundle/docs/content/concepts/scopes.md +256 -0
  214. package/bundle/docs/content/concepts/service.md +227 -0
  215. package/bundle/docs/content/concepts/units.md +321 -0
  216. package/bundle/docs/content/introduction.md +163 -0
  217. package/bundle/docs/content/llm/circle-text-board.json +55 -0
  218. package/bundle/docs/content/llm/howto-workflow.md +369 -0
  219. package/bundle/docs/content/repository.md +161 -0
  220. package/bundle/docs/content/services/aggregator.md +76 -0
  221. package/bundle/docs/content/services/analyzer.md +44 -0
  222. package/bundle/docs/content/services/ascii-art.md +58 -0
  223. package/bundle/docs/content/services/asset.md +88 -0
  224. package/bundle/docs/content/services/audio-editor.md +57 -0
  225. package/bundle/docs/content/services/audio-encode.md +115 -0
  226. package/bundle/docs/content/services/audio-io.md +173 -0
  227. package/bundle/docs/content/services/batcher.md +49 -0
  228. package/bundle/docs/content/services/board-service.md +48 -0
  229. package/bundle/docs/content/services/browser-sub-service.md +75 -0
  230. package/bundle/docs/content/services/buffer.md +70 -0
  231. package/bundle/docs/content/services/cache.md +92 -0
  232. package/bundle/docs/content/services/camera.md +85 -0
  233. package/bundle/docs/content/services/canvas.md +196 -0
  234. package/bundle/docs/content/services/changes.md +87 -0
  235. package/bundle/docs/content/services/chunked-file-provider.md +63 -0
  236. package/bundle/docs/content/services/communication-dispatcher.md +190 -0
  237. package/bundle/docs/content/services/configurator.md +66 -0
  238. package/bundle/docs/content/services/conversations.md +244 -0
  239. package/bundle/docs/content/services/debounce.md +45 -0
  240. package/bundle/docs/content/services/decrypt.md +53 -0
  241. package/bundle/docs/content/services/delay.md +55 -0
  242. package/bundle/docs/content/services/detect.md +101 -0
  243. package/bundle/docs/content/services/document-extract.md +174 -0
  244. package/bundle/docs/content/services/download.md +67 -0
  245. package/bundle/docs/content/services/encode.md +63 -0
  246. package/bundle/docs/content/services/encrypt.md +53 -0
  247. package/bundle/docs/content/services/fetcher.md +122 -0
  248. package/bundle/docs/content/services/fft.md +96 -0
  249. package/bundle/docs/content/services/file-source.md +67 -0
  250. package/bundle/docs/content/services/filesystem.md +157 -0
  251. package/bundle/docs/content/services/filter.md +133 -0
  252. package/bundle/docs/content/services/flat-map.md +62 -0
  253. package/bundle/docs/content/services/game-of-life.md +93 -0
  254. package/bundle/docs/content/services/gather.md +135 -0
  255. package/bundle/docs/content/services/gif-encoder.md +56 -0
  256. package/bundle/docs/content/services/github.md +85 -0
  257. package/bundle/docs/content/services/group-by.md +54 -0
  258. package/bundle/docs/content/services/hacker.md +79 -0
  259. package/bundle/docs/content/services/hash.md +59 -0
  260. package/bundle/docs/content/services/hold.md +182 -0
  261. package/bundle/docs/content/services/http-relay-client.md +48 -0
  262. package/bundle/docs/content/services/http-uploader.md +62 -0
  263. package/bundle/docs/content/services/http.md +424 -0
  264. package/bundle/docs/content/services/if.md +79 -0
  265. package/bundle/docs/content/services/ifft.md +46 -0
  266. package/bundle/docs/content/services/image-picker.md +50 -0
  267. package/bundle/docs/content/services/imap-email.md +104 -0
  268. package/bundle/docs/content/services/injector.md +129 -0
  269. package/bundle/docs/content/services/input.md +90 -0
  270. package/bundle/docs/content/services/iterator.md +186 -0
  271. package/bundle/docs/content/services/join.md +153 -0
  272. package/bundle/docs/content/services/limit.md +47 -0
  273. package/bundle/docs/content/services/local-storage.md +47 -0
  274. package/bundle/docs/content/services/looper.md +62 -0
  275. package/bundle/docs/content/services/lz-compress.md +52 -0
  276. package/bundle/docs/content/services/map.md +257 -0
  277. package/bundle/docs/content/services/match-filter.md +38 -0
  278. package/bundle/docs/content/services/microphone-monitor.md +66 -0
  279. package/bundle/docs/content/services/monitor.md +67 -0
  280. package/bundle/docs/content/services/ollama.md +116 -0
  281. package/bundle/docs/content/services/openai-prompt.md +74 -0
  282. package/bundle/docs/content/services/output.md +107 -0
  283. package/bundle/docs/content/services/peer-socket.md +61 -0
  284. package/bundle/docs/content/services/qr-code.md +48 -0
  285. package/bundle/docs/content/services/queue.md +201 -0
  286. package/bundle/docs/content/services/reduce.md +51 -0
  287. package/bundle/docs/content/services/rss.md +232 -0
  288. package/bundle/docs/content/services/select.md +47 -0
  289. package/bundle/docs/content/services/sign.md +53 -0
  290. package/bundle/docs/content/services/skill-router.md +154 -0
  291. package/bundle/docs/content/services/smooth.md +59 -0
  292. package/bundle/docs/content/services/smtp-email.md +129 -0
  293. package/bundle/docs/content/services/sort.md +48 -0
  294. package/bundle/docs/content/services/sound.md +87 -0
  295. package/bundle/docs/content/services/speech-synth.md +46 -0
  296. package/bundle/docs/content/services/speech-to-text.md +172 -0
  297. package/bundle/docs/content/services/spotify.md +77 -0
  298. package/bundle/docs/content/services/spread.md +111 -0
  299. package/bundle/docs/content/services/sql.md +491 -0
  300. package/bundle/docs/content/services/state.md +57 -0
  301. package/bundle/docs/content/services/static.md +47 -0
  302. package/bundle/docs/content/services/stopper.md +55 -0
  303. package/bundle/docs/content/services/storage.md +155 -0
  304. package/bundle/docs/content/services/store.md +255 -0
  305. package/bundle/docs/content/services/sub-service.md +152 -0
  306. package/bundle/docs/content/services/switch.md +67 -0
  307. package/bundle/docs/content/services/telegram-listener.md +76 -0
  308. package/bundle/docs/content/services/text-generation.md +390 -0
  309. package/bundle/docs/content/services/text-to-speech.md +130 -0
  310. package/bundle/docs/content/services/timeline.md +333 -0
  311. package/bundle/docs/content/services/timer.md +113 -0
  312. package/bundle/docs/content/services/tracks.md +207 -0
  313. package/bundle/docs/content/services/trigger-pad.md +68 -0
  314. package/bundle/docs/content/services/uuid-generator.md +48 -0
  315. package/bundle/docs/content/services/wav-reader.md +66 -0
  316. package/bundle/docs/content/services/websocket.md +189 -0
  317. package/bundle/docs/content/services/workflow-board-builder.md +65 -0
  318. package/bundle/docs/content/services/xy-pad.md +60 -0
  319. package/bundle/docs/content/targets.md +434 -0
  320. package/bundle/docs/content/testing.md +263 -0
  321. package/bundle/docs/content/vocabulary.md +171 -0
  322. package/bundle/hkp-frontend/src/runtime/browser/BrowserRegistry.tsx +141 -0
  323. package/bundle/hkp-frontend/src/runtime/browser/BrowserRuntime.tsx +202 -0
  324. package/bundle/hkp-frontend/src/runtime/browser/BrowserRuntimeApi.ts +306 -0
  325. package/bundle/hkp-frontend/src/runtime/browser/BrowserRuntimeApp.ts +310 -0
  326. package/bundle/hkp-frontend/src/runtime/browser/BrowserRuntimeScope.ts +500 -0
  327. package/bundle/hkp-frontend/src/runtime/browser/UIRegistry.ts +150 -0
  328. package/bundle/hkp-frontend/src/runtime/browser/assetResolver.ts +123 -0
  329. package/bundle/hkp-frontend/src/runtime/browser/pipelineNames.ts +65 -0
  330. package/bundle/hkp-frontend/src/runtime/browser/registry/Default.ts +237 -0
  331. package/bundle/hkp-frontend/src/runtime/browser/services/Aggregator.ts +127 -0
  332. package/bundle/hkp-frontend/src/runtime/browser/services/AggregatorUI.tsx +83 -0
  333. package/bundle/hkp-frontend/src/runtime/browser/services/Analyzer.tsx +43 -0
  334. package/bundle/hkp-frontend/src/runtime/browser/services/AnalyzerUI/Bars.tsx +33 -0
  335. package/bundle/hkp-frontend/src/runtime/browser/services/AnalyzerUI/HorizontalSpectrogram.tsx +53 -0
  336. package/bundle/hkp-frontend/src/runtime/browser/services/AnalyzerUI/VerticalSpectogram.tsx +56 -0
  337. package/bundle/hkp-frontend/src/runtime/browser/services/AnalyzerUI/Waveform.tsx +109 -0
  338. package/bundle/hkp-frontend/src/runtime/browser/services/AnalyzerUI/index.tsx +99 -0
  339. package/bundle/hkp-frontend/src/runtime/browser/services/AsciiArt.ts +119 -0
  340. package/bundle/hkp-frontend/src/runtime/browser/services/AsciiArtUI.tsx +131 -0
  341. package/bundle/hkp-frontend/src/runtime/browser/services/Asset.ts +125 -0
  342. package/bundle/hkp-frontend/src/runtime/browser/services/AssetUI.tsx +37 -0
  343. package/bundle/hkp-frontend/src/runtime/browser/services/AudioDeviceSettings.tsx +56 -0
  344. package/bundle/hkp-frontend/src/runtime/browser/services/AudioEditor.ts +129 -0
  345. package/bundle/hkp-frontend/src/runtime/browser/services/AudioEditorUI.tsx +549 -0
  346. package/bundle/hkp-frontend/src/runtime/browser/services/AudioInput.ts +298 -0
  347. package/bundle/hkp-frontend/src/runtime/browser/services/AudioInputUI.tsx +257 -0
  348. package/bundle/hkp-frontend/src/runtime/browser/services/AudioOutput.ts +189 -0
  349. package/bundle/hkp-frontend/src/runtime/browser/services/AudioOutputUI.tsx +63 -0
  350. package/bundle/hkp-frontend/src/runtime/browser/services/Batcher.ts +11 -0
  351. package/bundle/hkp-frontend/src/runtime/browser/services/BoardService.tsx +86 -0
  352. package/bundle/hkp-frontend/src/runtime/browser/services/BoardServiceUI.tsx +410 -0
  353. package/bundle/hkp-frontend/src/runtime/browser/services/BrowserGather.ts +311 -0
  354. package/bundle/hkp-frontend/src/runtime/browser/services/BrowserIterator.ts +167 -0
  355. package/bundle/hkp-frontend/src/runtime/browser/services/BrowserSubService.tsx +583 -0
  356. package/bundle/hkp-frontend/src/runtime/browser/services/BrowserSubServiceUI.tsx +187 -0
  357. package/bundle/hkp-frontend/src/runtime/browser/services/BrowserTracks.tsx +477 -0
  358. package/bundle/hkp-frontend/src/runtime/browser/services/Buffer.ts +11 -0
  359. package/bundle/hkp-frontend/src/runtime/browser/services/Cache.ts +134 -0
  360. package/bundle/hkp-frontend/src/runtime/browser/services/CacheUI.tsx +125 -0
  361. package/bundle/hkp-frontend/src/runtime/browser/services/Camera.ts +90 -0
  362. package/bundle/hkp-frontend/src/runtime/browser/services/CameraUI.tsx +321 -0
  363. package/bundle/hkp-frontend/src/runtime/browser/services/Canvas.ts +139 -0
  364. package/bundle/hkp-frontend/src/runtime/browser/services/CanvasUI/canvasDraw.ts +543 -0
  365. package/bundle/hkp-frontend/src/runtime/browser/services/CanvasUI/canvasUtils.ts +39 -0
  366. package/bundle/hkp-frontend/src/runtime/browser/services/CanvasUI/index.tsx +287 -0
  367. package/bundle/hkp-frontend/src/runtime/browser/services/CanvasUI/tests/canvasDraw.test.ts +355 -0
  368. package/bundle/hkp-frontend/src/runtime/browser/services/CanvasUI/tests/canvasUtils.test.ts +89 -0
  369. package/bundle/hkp-frontend/src/runtime/browser/services/CanvasUI/tests/fullscreen.test.tsx +26 -0
  370. package/bundle/hkp-frontend/src/runtime/browser/services/Changes.ts +201 -0
  371. package/bundle/hkp-frontend/src/runtime/browser/services/ChangesUI.tsx +85 -0
  372. package/bundle/hkp-frontend/src/runtime/browser/services/ChunkedFileProvider.tsx +183 -0
  373. package/bundle/hkp-frontend/src/runtime/browser/services/Configurator.ts +258 -0
  374. package/bundle/hkp-frontend/src/runtime/browser/services/ConfiguratorUI.tsx +83 -0
  375. package/bundle/hkp-frontend/src/runtime/browser/services/ConsideredHacker.tsx +28 -0
  376. package/bundle/hkp-frontend/src/runtime/browser/services/Debounce.ts +75 -0
  377. package/bundle/hkp-frontend/src/runtime/browser/services/DebounceUI.tsx +70 -0
  378. package/bundle/hkp-frontend/src/runtime/browser/services/Decrypt.ts +127 -0
  379. package/bundle/hkp-frontend/src/runtime/browser/services/DecryptUI.tsx +39 -0
  380. package/bundle/hkp-frontend/src/runtime/browser/services/Delay.tsx +110 -0
  381. package/bundle/hkp-frontend/src/runtime/browser/services/Detect.ts +214 -0
  382. package/bundle/hkp-frontend/src/runtime/browser/services/DetectUI.tsx +86 -0
  383. package/bundle/hkp-frontend/src/runtime/browser/services/Download.ts +120 -0
  384. package/bundle/hkp-frontend/src/runtime/browser/services/DownloadUI.tsx +61 -0
  385. package/bundle/hkp-frontend/src/runtime/browser/services/Encode.ts +138 -0
  386. package/bundle/hkp-frontend/src/runtime/browser/services/EncodeUI.tsx +52 -0
  387. package/bundle/hkp-frontend/src/runtime/browser/services/Encrypt.ts +125 -0
  388. package/bundle/hkp-frontend/src/runtime/browser/services/EncryptUI.tsx +39 -0
  389. package/bundle/hkp-frontend/src/runtime/browser/services/FFT.tsx +238 -0
  390. package/bundle/hkp-frontend/src/runtime/browser/services/FFTUI.tsx +112 -0
  391. package/bundle/hkp-frontend/src/runtime/browser/services/FeedbackService.ts +247 -0
  392. package/bundle/hkp-frontend/src/runtime/browser/services/FeedbackServiceUI.tsx +35 -0
  393. package/bundle/hkp-frontend/src/runtime/browser/services/Fetcher.tsx +232 -0
  394. package/bundle/hkp-frontend/src/runtime/browser/services/FetcherUI.tsx +154 -0
  395. package/bundle/hkp-frontend/src/runtime/browser/services/FileSource.tsx +171 -0
  396. package/bundle/hkp-frontend/src/runtime/browser/services/Filter.tsx +18 -0
  397. package/bundle/hkp-frontend/src/runtime/browser/services/FilterUI.tsx +89 -0
  398. package/bundle/hkp-frontend/src/runtime/browser/services/FlatMap.ts +68 -0
  399. package/bundle/hkp-frontend/src/runtime/browser/services/FlatMapUI.tsx +38 -0
  400. package/bundle/hkp-frontend/src/runtime/browser/services/GameOfLife.ts +210 -0
  401. package/bundle/hkp-frontend/src/runtime/browser/services/GameOfLifeRenderer.ts +182 -0
  402. package/bundle/hkp-frontend/src/runtime/browser/services/GameOfLifeRendererUI.tsx +48 -0
  403. package/bundle/hkp-frontend/src/runtime/browser/services/GameOfLifeUI.tsx +58 -0
  404. package/bundle/hkp-frontend/src/runtime/browser/services/GatherUI.tsx +84 -0
  405. package/bundle/hkp-frontend/src/runtime/browser/services/GifEncoder.tsx +651 -0
  406. package/bundle/hkp-frontend/src/runtime/browser/services/GithubAPI.ts +294 -0
  407. package/bundle/hkp-frontend/src/runtime/browser/services/GithubComponents.tsx +389 -0
  408. package/bundle/hkp-frontend/src/runtime/browser/services/GithubSink.tsx +109 -0
  409. package/bundle/hkp-frontend/src/runtime/browser/services/GithubSinkUI.tsx +143 -0
  410. package/bundle/hkp-frontend/src/runtime/browser/services/GithubSource.tsx +86 -0
  411. package/bundle/hkp-frontend/src/runtime/browser/services/GithubSourceUI.tsx +162 -0
  412. package/bundle/hkp-frontend/src/runtime/browser/services/GroupBy.ts +11 -0
  413. package/bundle/hkp-frontend/src/runtime/browser/services/HTTPUploader.ts +102 -0
  414. package/bundle/hkp-frontend/src/runtime/browser/services/Hacker.ts +73 -0
  415. package/bundle/hkp-frontend/src/runtime/browser/services/HackerUI.tsx +134 -0
  416. package/bundle/hkp-frontend/src/runtime/browser/services/Hash.ts +134 -0
  417. package/bundle/hkp-frontend/src/runtime/browser/services/HashUI.tsx +45 -0
  418. package/bundle/hkp-frontend/src/runtime/browser/services/Hold.ts +288 -0
  419. package/bundle/hkp-frontend/src/runtime/browser/services/HoldUI.tsx +43 -0
  420. package/bundle/hkp-frontend/src/runtime/browser/services/HttpClient.ts +558 -0
  421. package/bundle/hkp-frontend/src/runtime/browser/services/HttpClientUI.tsx +212 -0
  422. package/bundle/hkp-frontend/src/runtime/browser/services/HttpUploaderTokenInjector.ts +149 -0
  423. package/bundle/hkp-frontend/src/runtime/browser/services/IfService.ts +231 -0
  424. package/bundle/hkp-frontend/src/runtime/browser/services/IfServiceUI.tsx +50 -0
  425. package/bundle/hkp-frontend/src/runtime/browser/services/ImagePicker.tsx +118 -0
  426. package/bundle/hkp-frontend/src/runtime/browser/services/Injector.ts +61 -0
  427. package/bundle/hkp-frontend/src/runtime/browser/services/InjectorUI.tsx +389 -0
  428. package/bundle/hkp-frontend/src/runtime/browser/services/Input.ts +214 -0
  429. package/bundle/hkp-frontend/src/runtime/browser/services/InputUI.tsx +71 -0
  430. package/bundle/hkp-frontend/src/runtime/browser/services/IteratorUI.tsx +59 -0
  431. package/bundle/hkp-frontend/src/runtime/browser/services/LZCompress.ts +63 -0
  432. package/bundle/hkp-frontend/src/runtime/browser/services/Limit.ts +39 -0
  433. package/bundle/hkp-frontend/src/runtime/browser/services/LimitUI.tsx +41 -0
  434. package/bundle/hkp-frontend/src/runtime/browser/services/LocalStorage.ts +65 -0
  435. package/bundle/hkp-frontend/src/runtime/browser/services/LocalStorageUI.tsx +72 -0
  436. package/bundle/hkp-frontend/src/runtime/browser/services/Map.ts +14 -0
  437. package/bundle/hkp-frontend/src/runtime/browser/services/MapUI.tsx +334 -0
  438. package/bundle/hkp-frontend/src/runtime/browser/services/MapUIModeAssist.tsx +61 -0
  439. package/bundle/hkp-frontend/src/runtime/browser/services/MatchFilter.ts +11 -0
  440. package/bundle/hkp-frontend/src/runtime/browser/services/MicrophoneMonitor.ts +190 -0
  441. package/bundle/hkp-frontend/src/runtime/browser/services/MicrophoneMonitorUI.tsx +94 -0
  442. package/bundle/hkp-frontend/src/runtime/browser/services/Monitor.tsx +15 -0
  443. package/bundle/hkp-frontend/src/runtime/browser/services/MonitorUI.tsx +281 -0
  444. package/bundle/hkp-frontend/src/runtime/browser/services/OllamaPrompt.ts +237 -0
  445. package/bundle/hkp-frontend/src/runtime/browser/services/OllamaPromptUI/BusyIndicator.tsx +18 -0
  446. package/bundle/hkp-frontend/src/runtime/browser/services/OllamaPromptUI/PromptInput.tsx +71 -0
  447. package/bundle/hkp-frontend/src/runtime/browser/services/OllamaPromptUI/StreamingPreview.tsx +24 -0
  448. package/bundle/hkp-frontend/src/runtime/browser/services/OllamaPromptUI/index.tsx +156 -0
  449. package/bundle/hkp-frontend/src/runtime/browser/services/OpenAIPrompt.ts +254 -0
  450. package/bundle/hkp-frontend/src/runtime/browser/services/OpenAIPromptUI.tsx +189 -0
  451. package/bundle/hkp-frontend/src/runtime/browser/services/Output.tsx +145 -0
  452. package/bundle/hkp-frontend/src/runtime/browser/services/OutputUI.tsx +118 -0
  453. package/bundle/hkp-frontend/src/runtime/browser/services/PeerChatTemplate.json +43 -0
  454. package/bundle/hkp-frontend/src/runtime/browser/services/PeerConnection.ts +260 -0
  455. package/bundle/hkp-frontend/src/runtime/browser/services/PeerSocket.tsx +268 -0
  456. package/bundle/hkp-frontend/src/runtime/browser/services/PeerSocketReceiverTemplate.json +29 -0
  457. package/bundle/hkp-frontend/src/runtime/browser/services/PeerSocketUI.tsx +341 -0
  458. package/bundle/hkp-frontend/src/runtime/browser/services/PlaceholderUI.tsx +72 -0
  459. package/bundle/hkp-frontend/src/runtime/browser/services/QrCode.ts +63 -0
  460. package/bundle/hkp-frontend/src/runtime/browser/services/QrCodeUI.tsx +197 -0
  461. package/bundle/hkp-frontend/src/runtime/browser/services/Select.ts +40 -0
  462. package/bundle/hkp-frontend/src/runtime/browser/services/SelectUI.tsx +41 -0
  463. package/bundle/hkp-frontend/src/runtime/browser/services/ServiceBase.ts +50 -0
  464. package/bundle/hkp-frontend/src/runtime/browser/services/SetRuntimeVariable.ts +65 -0
  465. package/bundle/hkp-frontend/src/runtime/browser/services/SetRuntimeVariableUI.tsx +50 -0
  466. package/bundle/hkp-frontend/src/runtime/browser/services/Sign.ts +182 -0
  467. package/bundle/hkp-frontend/src/runtime/browser/services/SignUI.tsx +55 -0
  468. package/bundle/hkp-frontend/src/runtime/browser/services/Smooth.ts +101 -0
  469. package/bundle/hkp-frontend/src/runtime/browser/services/SmoothUI.tsx +50 -0
  470. package/bundle/hkp-frontend/src/runtime/browser/services/Sort.ts +59 -0
  471. package/bundle/hkp-frontend/src/runtime/browser/services/SortUI.tsx +61 -0
  472. package/bundle/hkp-frontend/src/runtime/browser/services/Sound.ts +541 -0
  473. package/bundle/hkp-frontend/src/runtime/browser/services/SoundUI.tsx +183 -0
  474. package/bundle/hkp-frontend/src/runtime/browser/services/SpeechSynth.ts +56 -0
  475. package/bundle/hkp-frontend/src/runtime/browser/services/SpeechSynthUI.tsx +108 -0
  476. package/bundle/hkp-frontend/src/runtime/browser/services/Spotify.tsx +111 -0
  477. package/bundle/hkp-frontend/src/runtime/browser/services/SpotifyAPI.ts +113 -0
  478. package/bundle/hkp-frontend/src/runtime/browser/services/SpotifyComponents.tsx +104 -0
  479. package/bundle/hkp-frontend/src/runtime/browser/services/SpotifyUI.tsx +186 -0
  480. package/bundle/hkp-frontend/src/runtime/browser/services/Spread.ts +117 -0
  481. package/bundle/hkp-frontend/src/runtime/browser/services/SpreadUI.tsx +38 -0
  482. package/bundle/hkp-frontend/src/runtime/browser/services/Sql.ts +448 -0
  483. package/bundle/hkp-frontend/src/runtime/browser/services/SqlInspector.tsx +332 -0
  484. package/bundle/hkp-frontend/src/runtime/browser/services/SqlUI.tsx +226 -0
  485. package/bundle/hkp-frontend/src/runtime/browser/services/State.ts +149 -0
  486. package/bundle/hkp-frontend/src/runtime/browser/services/Stopper.ts +29 -0
  487. package/bundle/hkp-frontend/src/runtime/browser/services/Switch.tsx +419 -0
  488. package/bundle/hkp-frontend/src/runtime/browser/services/SwitchUI.tsx +171 -0
  489. package/bundle/hkp-frontend/src/runtime/browser/services/TickRuleDelta.ts +101 -0
  490. package/bundle/hkp-frontend/src/runtime/browser/services/TickRuleDeltaUI.tsx +56 -0
  491. package/bundle/hkp-frontend/src/runtime/browser/services/Timeline.ts +709 -0
  492. package/bundle/hkp-frontend/src/runtime/browser/services/TimelineUI/TimelinePanel.tsx +79 -0
  493. package/bundle/hkp-frontend/src/runtime/browser/services/TimelineUI/TimelineRows.tsx +574 -0
  494. package/bundle/hkp-frontend/src/runtime/browser/services/TimelineUI/Transport.tsx +141 -0
  495. package/bundle/hkp-frontend/src/runtime/browser/services/TimelineUI/index.tsx +119 -0
  496. package/bundle/hkp-frontend/src/runtime/browser/services/TimelineUI/model.ts +425 -0
  497. package/bundle/hkp-frontend/src/runtime/browser/services/TimelineUI/parts.tsx +708 -0
  498. package/bundle/hkp-frontend/src/runtime/browser/services/Timer.ts +15 -0
  499. package/bundle/hkp-frontend/src/runtime/browser/services/TimerUI.tsx +213 -0
  500. package/bundle/hkp-frontend/src/runtime/browser/services/TracksUI.tsx +81 -0
  501. package/bundle/hkp-frontend/src/runtime/browser/services/TriggerPad.ts +108 -0
  502. package/bundle/hkp-frontend/src/runtime/browser/services/TriggerPadUI.tsx +160 -0
  503. package/bundle/hkp-frontend/src/runtime/browser/services/UuidGenerator.ts +74 -0
  504. package/bundle/hkp-frontend/src/runtime/browser/services/UuidGeneratorUI.tsx +59 -0
  505. package/bundle/hkp-frontend/src/runtime/browser/services/WaveformDisplay.tsx +104 -0
  506. package/bundle/hkp-frontend/src/runtime/browser/services/WebsocketClient.ts +114 -0
  507. package/bundle/hkp-frontend/src/runtime/browser/services/WebsocketClientUI.tsx +42 -0
  508. package/bundle/hkp-frontend/src/runtime/browser/services/WorkflowBoardBuilder.ts +499 -0
  509. package/bundle/hkp-frontend/src/runtime/browser/services/WorkflowBoardBuilderUI.tsx +521 -0
  510. package/bundle/hkp-frontend/src/runtime/browser/services/XYPad.ts +68 -0
  511. package/bundle/hkp-frontend/src/runtime/browser/services/XYPadUI.tsx +274 -0
  512. package/bundle/hkp-frontend/src/runtime/browser/services/audio/audioHelper.ts +36 -0
  513. package/bundle/hkp-frontend/src/runtime/browser/services/base/Batcher.ts +76 -0
  514. package/bundle/hkp-frontend/src/runtime/browser/services/base/Buffer.ts +142 -0
  515. package/bundle/hkp-frontend/src/runtime/browser/services/base/Filter.ts +125 -0
  516. package/bundle/hkp-frontend/src/runtime/browser/services/base/GroupBy.ts +101 -0
  517. package/bundle/hkp-frontend/src/runtime/browser/services/base/Map.ts +543 -0
  518. package/bundle/hkp-frontend/src/runtime/browser/services/base/MatchFilter.ts +49 -0
  519. package/bundle/hkp-frontend/src/runtime/browser/services/base/Monitor.ts +75 -0
  520. package/bundle/hkp-frontend/src/runtime/browser/services/base/Reduce.ts +74 -0
  521. package/bundle/hkp-frontend/src/runtime/browser/services/base/Timer.ts +342 -0
  522. package/bundle/hkp-frontend/src/runtime/browser/services/base/bundle.js +7375 -0
  523. package/bundle/hkp-frontend/src/runtime/browser/services/base/eval.ts +208 -0
  524. package/bundle/hkp-frontend/src/runtime/browser/services/base/expressionEval.ts +223 -0
  525. package/bundle/hkp-frontend/src/runtime/browser/services/base/helpers.ts +10 -0
  526. package/bundle/hkp-frontend/src/runtime/browser/services/base/index.ts +37 -0
  527. package/bundle/hkp-frontend/src/runtime/browser/services/camera/videoCapture.ts +78 -0
  528. package/bundle/hkp-frontend/src/runtime/browser/services/changes-modes.ts +9 -0
  529. package/bundle/hkp-frontend/src/runtime/browser/services/colorpalette.ts +26 -0
  530. package/bundle/hkp-frontend/src/runtime/browser/services/detect/DetectionPreview.tsx +76 -0
  531. package/bundle/hkp-frontend/src/runtime/browser/services/detect/mediapipe.ts +34 -0
  532. package/bundle/hkp-frontend/src/runtime/browser/services/detect/models/README.md +14 -0
  533. package/bundle/hkp-frontend/src/runtime/browser/services/detect/models/blaze_face_short_range.tflite +0 -0
  534. package/bundle/hkp-frontend/src/runtime/browser/services/detect-modes.ts +7 -0
  535. package/bundle/hkp-frontend/src/runtime/browser/services/encode-modes.ts +10 -0
  536. package/bundle/hkp-frontend/src/runtime/browser/services/helpers.ts +300 -0
  537. package/bundle/hkp-frontend/src/runtime/browser/services/http-client-methods.ts +10 -0
  538. package/bundle/hkp-frontend/src/runtime/browser/services/sql-database.ts +594 -0
  539. package/bundle/hkp-frontend/src/runtime/browser/services/sql-dump.ts +192 -0
  540. package/bundle/hkp-frontend/src/runtime/browser/services/sql-inspect.ts +130 -0
  541. package/bundle/hkp-frontend/src/runtime/browser/services/sql-inspector.css +155 -0
  542. package/bundle/hkp-frontend/src/runtime/browser/services/sql-modes.ts +27 -0
  543. package/bundle/hkp-frontend/src/runtime/browser/services/tests/TESTING_APPROACH.md +169 -0
  544. package/bundle/hkp-frontend/src/runtime/browser/services/tests/__snapshots__/service-ui.future-enhancements.test.tsx.snap +5 -0
  545. package/bundle/hkp-frontend/src/runtime/browser/services/tests/audio-input-permissions.test.ts +42 -0
  546. package/bundle/hkp-frontend/src/runtime/browser/services/tests/audiolizeLanes.test.ts +70 -0
  547. package/bundle/hkp-frontend/src/runtime/browser/services/tests/browser-scopes.test.ts +305 -0
  548. package/bundle/hkp-frontend/src/runtime/browser/services/tests/cache-service.test.ts +53 -0
  549. package/bundle/hkp-frontend/src/runtime/browser/services/tests/camera-video-capture.test.ts +24 -0
  550. package/bundle/hkp-frontend/src/runtime/browser/services/tests/changes-service.test.ts +133 -0
  551. package/bundle/hkp-frontend/src/runtime/browser/services/tests/crypto-secrets.test.ts +196 -0
  552. package/bundle/hkp-frontend/src/runtime/browser/services/tests/detect-service.test.ts +119 -0
  553. package/bundle/hkp-frontend/src/runtime/browser/services/tests/download.test.ts +100 -0
  554. package/bundle/hkp-frontend/src/runtime/browser/services/tests/expressionEval.test.ts +117 -0
  555. package/bundle/hkp-frontend/src/runtime/browser/services/tests/fetcher-panel.test.tsx +35 -0
  556. package/bundle/hkp-frontend/src/runtime/browser/services/tests/fetcher-service.test.ts +80 -0
  557. package/bundle/hkp-frontend/src/runtime/browser/services/tests/filter-service.test.ts +37 -0
  558. package/bundle/hkp-frontend/src/runtime/browser/services/tests/github-secrets.test.ts +108 -0
  559. package/bundle/hkp-frontend/src/runtime/browser/services/tests/group-by-board.test.ts +42 -0
  560. package/bundle/hkp-frontend/src/runtime/browser/services/tests/hold-service.test.ts +199 -0
  561. package/bundle/hkp-frontend/src/runtime/browser/services/tests/http-client-service.test.ts +474 -0
  562. package/bundle/hkp-frontend/src/runtime/browser/services/tests/http-uploader-token-injector.test.ts +152 -0
  563. package/bundle/hkp-frontend/src/runtime/browser/services/tests/iterator-gather-service.test.ts +277 -0
  564. package/bundle/hkp-frontend/src/runtime/browser/services/tests/map-service.test.ts +1047 -0
  565. package/bundle/hkp-frontend/src/runtime/browser/services/tests/map-ui.test.tsx +70 -0
  566. package/bundle/hkp-frontend/src/runtime/browser/services/tests/nested-rhythm-board.test.ts +311 -0
  567. package/bundle/hkp-frontend/src/runtime/browser/services/tests/night-groove-board.test.ts +290 -0
  568. package/bundle/hkp-frontend/src/runtime/browser/services/tests/pad-groove-board.test.ts +230 -0
  569. package/bundle/hkp-frontend/src/runtime/browser/services/tests/peer-host-discovery.test.ts +77 -0
  570. package/bundle/hkp-frontend/src/runtime/browser/services/tests/peer-socket-discovery.test.ts +69 -0
  571. package/bundle/hkp-frontend/src/runtime/browser/services/tests/pipeline-names.test.ts +63 -0
  572. package/bundle/hkp-frontend/src/runtime/browser/services/tests/secret-canary.test.ts +121 -0
  573. package/bundle/hkp-frontend/src/runtime/browser/services/tests/service-modules.contract.test.ts +229 -0
  574. package/bundle/hkp-frontend/src/runtime/browser/services/tests/service-ui.advanced.test.tsx +670 -0
  575. package/bundle/hkp-frontend/src/runtime/browser/services/tests/service-ui.future-enhancements.test.tsx +219 -0
  576. package/bundle/hkp-frontend/src/runtime/browser/services/tests/service-ui.integration.test.tsx +432 -0
  577. package/bundle/hkp-frontend/src/runtime/browser/services/tests/service-ui.smoke.test.tsx +140 -0
  578. package/bundle/hkp-frontend/src/runtime/browser/services/tests/sound-service.test.ts +293 -0
  579. package/bundle/hkp-frontend/src/runtime/browser/services/tests/spread-service.test.ts +137 -0
  580. package/bundle/hkp-frontend/src/runtime/browser/services/tests/sql-dump.test.ts +172 -0
  581. package/bundle/hkp-frontend/src/runtime/browser/services/tests/sql-inspect.test.ts +163 -0
  582. package/bundle/hkp-frontend/src/runtime/browser/services/tests/sql-inspector.test.tsx +121 -0
  583. package/bundle/hkp-frontend/src/runtime/browser/services/tests/sql.test.ts +702 -0
  584. package/bundle/hkp-frontend/src/runtime/browser/services/tests/sub-service-in-block.test.tsx +84 -0
  585. package/bundle/hkp-frontend/src/runtime/browser/services/tests/switch-service.test.ts +254 -0
  586. package/bundle/hkp-frontend/src/runtime/browser/services/tests/timeline-board.test.ts +218 -0
  587. package/bundle/hkp-frontend/src/runtime/browser/services/tests/timeline-service.test.ts +1002 -0
  588. package/bundle/hkp-frontend/src/runtime/browser/services/tests/timeline-ui-model.test.ts +230 -0
  589. package/bundle/hkp-frontend/src/runtime/browser/services/tests/timeline-ui.test.tsx +371 -0
  590. package/bundle/hkp-frontend/src/runtime/browser/services/tests/timer-service.test.ts +902 -0
  591. package/bundle/hkp-frontend/src/runtime/browser/services/tests/tracks-service.test.ts +275 -0
  592. package/bundle/hkp-frontend/src/runtime/browser/services/tests/tracks-ui.test.tsx +126 -0
  593. package/bundle/hkp-frontend/src/runtime/browser/services/tests/triggerpad-recorder-board.test.ts +100 -0
  594. package/bundle/hkp-frontend/src/runtime/browser/services/tests/uuid-generator-service.test.ts +214 -0
  595. package/bundle/hkp-frontend/src/runtime/browser/services/timeline-core.ts +410 -0
  596. package/bundle/hkp-frontend/src/runtime/browser/services/workflow-prompt/DefaultWorkflowBoard.ts +90 -0
  597. package/bundle/hkp-frontend/src/runtime/browser/services/workflow-prompt/RefinementSession.ts +121 -0
  598. package/bundle/hkp-frontend/src/runtime/browser/services/workflow-prompt/SystemPromptCatalog.ts +245 -0
  599. package/bundle/hkp-frontend/src/runtime/browser/services/workflow-prompt/catalog/browser-service-specs.json +110 -0
  600. package/bundle/hkp-frontend/src/runtime/browser/services/workflow-prompt/catalog/runtime-capabilities.json +37 -0
  601. package/bundle/hkp-frontend/src/runtime/browser/tests/asset-service.test.ts +73 -0
  602. package/bundle/hkp-frontend/src/runtime/browser/tests/board-persistence.integration.test.tsx +391 -0
  603. package/bundle/hkp-frontend/src/runtime/browser/tests/browser-runtime.identity-binding.test.tsx +81 -0
  604. package/bundle/hkp-frontend/src/runtime/browser/tests/demo-boards.regression.test.tsx +386 -0
  605. package/bundle/hkp-frontend/src/runtime/browser/tests/failed-call-lifecycle.test.ts +56 -0
  606. package/bundle/hkp-frontend/src/runtime/browser/tests/http-client.integration.test.ts +146 -0
  607. package/bundle/hkp-frontend/src/runtime/browser/tests/nested-run.integration.test.ts +415 -0
  608. package/bundle/hkp-frontend/src/runtime/browser/tests/replay-next.test.ts +391 -0
  609. package/bundle/hkp-frontend/src/runtime/browser/tests/rerun.test.ts +71 -0
  610. package/bundle/hkp-frontend/src/runtime/browser/tests/run-no-input.test.ts +72 -0
  611. package/bundle/hkp-frontend/src/runtime/browser/tests/runtime-add.integration.test.tsx +256 -0
  612. package/bundle/hkp-frontend/src/runtime/browser/tests/runtime-operations.integration.test.tsx +310 -0
  613. package/bundle/hkp-frontend/src/runtime/browser/tests/runtime-processing.integration.test.ts +311 -0
  614. package/bundle/hkp-frontend/src/runtime/browser/tests/runtime-removal.integration.test.tsx +454 -0
  615. package/bundle/hkp-frontend/src/runtime/browser/tests/runtime-update.identity.integration.test.tsx +145 -0
  616. package/bundle/hkp-frontend/src/runtime/browser/tests/service-operations.integration.test.tsx +511 -0
  617. package/bundle/hkp-node/src/address.ts +72 -0
  618. package/bundle/hkp-node/src/assets.ts +582 -0
  619. package/bundle/hkp-node/src/auth.ts +369 -0
  620. package/bundle/hkp-node/src/callReport.ts +281 -0
  621. package/bundle/hkp-node/src/coordinator/auth.ts +85 -0
  622. package/bundle/hkp-node/src/coordinator/binaryFrame.ts +189 -0
  623. package/bundle/hkp-node/src/coordinator/boardStore.ts +0 -0
  624. package/bundle/hkp-node/src/coordinator/bridge.ts +242 -0
  625. package/bundle/hkp-node/src/coordinator/bridgeProtocol.ts +200 -0
  626. package/bundle/hkp-node/src/coordinator/coordinator.ts +594 -0
  627. package/bundle/hkp-node/src/coordinator/facadeAccess.ts +426 -0
  628. package/bundle/hkp-node/src/coordinator/fileBoardStore.ts +159 -0
  629. package/bundle/hkp-node/src/coordinator/frameLimits.ts +41 -0
  630. package/bundle/hkp-node/src/coordinator/index.ts +12 -0
  631. package/bundle/hkp-node/src/coordinator/join.ts +62 -0
  632. package/bundle/hkp-node/src/coordinator/logStore.ts +335 -0
  633. package/bundle/hkp-node/src/coordinator/members.ts +133 -0
  634. package/bundle/hkp-node/src/coordinator/mount.ts +124 -0
  635. package/bundle/hkp-node/src/coordinator/participantProtocol.ts +169 -0
  636. package/bundle/hkp-node/src/coordinator/participants.ts +666 -0
  637. package/bundle/hkp-node/src/coordinator/router.ts +416 -0
  638. package/bundle/hkp-node/src/coordinator/session.ts +1610 -0
  639. package/bundle/hkp-node/src/coordinator/types.ts +95 -0
  640. package/bundle/hkp-node/src/coordinatorLinks.ts +712 -0
  641. package/bundle/hkp-node/src/credentialedFetch.ts +122 -0
  642. package/bundle/hkp-node/src/egress.ts +344 -0
  643. package/bundle/hkp-node/src/expressionEval.ts +223 -0
  644. package/bundle/hkp-node/src/index.ts +470 -0
  645. package/bundle/hkp-node/src/instance.ts +172 -0
  646. package/bundle/hkp-node/src/mounts.ts +296 -0
  647. package/bundle/hkp-node/src/origins.ts +201 -0
  648. package/bundle/hkp-node/src/reset.ts +187 -0
  649. package/bundle/hkp-node/src/runtime.ts +1345 -0
  650. package/bundle/hkp-node/src/secrets.ts +292 -0
  651. package/bundle/hkp-node/src/server.ts +2120 -0
  652. package/bundle/hkp-node/src/services/asset.ts +150 -0
  653. package/bundle/hkp-node/src/services/claudeModels.ts +370 -0
  654. package/bundle/hkp-node/src/services/communication-dispatcher.ts +735 -0
  655. package/bundle/hkp-node/src/services/conversations.ts +914 -0
  656. package/bundle/hkp-node/src/services/database.ts +386 -0
  657. package/bundle/hkp-node/src/services/document-extract.ts +575 -0
  658. package/bundle/hkp-node/src/services/expression.ts +417 -0
  659. package/bundle/hkp-node/src/services/fileStore.ts +369 -0
  660. package/bundle/hkp-node/src/services/filesystem.ts +280 -0
  661. package/bundle/hkp-node/src/services/gather.ts +335 -0
  662. package/bundle/hkp-node/src/services/hold.ts +275 -0
  663. package/bundle/hkp-node/src/services/http-client.ts +525 -0
  664. package/bundle/hkp-node/src/services/http-server.ts +1222 -0
  665. package/bundle/hkp-node/src/services/imap-email.ts +627 -0
  666. package/bundle/hkp-node/src/services/injector.ts +135 -0
  667. package/bundle/hkp-node/src/services/iterator.ts +203 -0
  668. package/bundle/hkp-node/src/services/join.ts +226 -0
  669. package/bundle/hkp-node/src/services/map.ts +632 -0
  670. package/bundle/hkp-node/src/services/monitor.ts +128 -0
  671. package/bundle/hkp-node/src/services/nested-pipeline.ts +405 -0
  672. package/bundle/hkp-node/src/services/peer-server.ts +268 -0
  673. package/bundle/hkp-node/src/services/queue-store.ts +301 -0
  674. package/bundle/hkp-node/src/services/queue.ts +316 -0
  675. package/bundle/hkp-node/src/services/recordStore.ts +341 -0
  676. package/bundle/hkp-node/src/services/rss-parse.ts +281 -0
  677. package/bundle/hkp-node/src/services/rss.ts +392 -0
  678. package/bundle/hkp-node/src/services/smtp-email.ts +398 -0
  679. package/bundle/hkp-node/src/services/spread.ts +153 -0
  680. package/bundle/hkp-node/src/services/sql-dump.ts +192 -0
  681. package/bundle/hkp-node/src/services/sql.ts +429 -0
  682. package/bundle/hkp-node/src/services/stopper.ts +69 -0
  683. package/bundle/hkp-node/src/services/storage.ts +332 -0
  684. package/bundle/hkp-node/src/services/store.ts +609 -0
  685. package/bundle/hkp-node/src/services/stream.ts +367 -0
  686. package/bundle/hkp-node/src/services/sub-service.ts +600 -0
  687. package/bundle/hkp-node/src/services/telegram-listener.ts +263 -0
  688. package/bundle/hkp-node/src/services/telegram-sender.ts +136 -0
  689. package/bundle/hkp-node/src/services/text-generation.ts +1249 -0
  690. package/bundle/hkp-node/src/services/timer.ts +273 -0
  691. package/bundle/hkp-node/src/services/tracks.ts +381 -0
  692. package/bundle/hkp-node/src/services/websocket-reader.ts +364 -0
  693. package/bundle/hkp-node/src/types.ts +465 -0
  694. package/bundle/hkp-node/src/wsTickets.ts +77 -0
  695. package/bundle/hkp-node/src/yas.ts +95 -0
  696. package/bundle/hkp-python/src/hkp/__init__.py +1 -0
  697. package/bundle/hkp-python/src/hkp/__main__.py +241 -0
  698. package/bundle/hkp-python/src/hkp/address.py +56 -0
  699. package/bundle/hkp-python/src/hkp/assets.py +439 -0
  700. package/bundle/hkp-python/src/hkp/auth.py +252 -0
  701. package/bundle/hkp-python/src/hkp/binary_frame.py +100 -0
  702. package/bundle/hkp-python/src/hkp/call_report.py +201 -0
  703. package/bundle/hkp-python/src/hkp/coordinator_links.py +667 -0
  704. package/bundle/hkp-python/src/hkp/data.py +118 -0
  705. package/bundle/hkp-python/src/hkp/egress.py +310 -0
  706. package/bundle/hkp-python/src/hkp/mount.py +46 -0
  707. package/bundle/hkp-python/src/hkp/mounts.py +288 -0
  708. package/bundle/hkp-python/src/hkp/origins.py +169 -0
  709. package/bundle/hkp-python/src/hkp/runtime.py +1131 -0
  710. package/bundle/hkp-python/src/hkp/secrets.py +261 -0
  711. package/bundle/hkp-python/src/hkp/server.py +1714 -0
  712. package/bundle/hkp-python/src/hkp/services/__init__.py +0 -0
  713. package/bundle/hkp-python/src/hkp/services/asset.py +123 -0
  714. package/bundle/hkp-python/src/hkp/services/audio_encode.py +190 -0
  715. package/bundle/hkp-python/src/hkp/services/expression.py +942 -0
  716. package/bundle/hkp-python/src/hkp/services/gather.py +266 -0
  717. package/bundle/hkp-python/src/hkp/services/hold.py +246 -0
  718. package/bundle/hkp-python/src/hkp/services/http_client.py +444 -0
  719. package/bundle/hkp-python/src/hkp/services/http_server.py +790 -0
  720. package/bundle/hkp-python/src/hkp/services/iterator.py +141 -0
  721. package/bundle/hkp-python/src/hkp/services/join.py +173 -0
  722. package/bundle/hkp-python/src/hkp/services/map_service.py +452 -0
  723. package/bundle/hkp-python/src/hkp/services/monitor.py +99 -0
  724. package/bundle/hkp-python/src/hkp/services/nested_pipeline.py +278 -0
  725. package/bundle/hkp-python/src/hkp/services/skill_router.py +388 -0
  726. package/bundle/hkp-python/src/hkp/services/speech_to_text.py +186 -0
  727. package/bundle/hkp-python/src/hkp/services/spread.py +114 -0
  728. package/bundle/hkp-python/src/hkp/services/stopper.py +59 -0
  729. package/bundle/hkp-python/src/hkp/services/sub_service.py +417 -0
  730. package/bundle/hkp-python/src/hkp/services/text_generation.py +498 -0
  731. package/bundle/hkp-python/src/hkp/services/text_to_speech.py +237 -0
  732. package/bundle/hkp-python/src/hkp/services/timer.py +267 -0
  733. package/bundle/hkp-python/src/hkp/services/tracks.py +251 -0
  734. package/bundle/hkp-python/src/hkp/types.py +412 -0
  735. package/bundle/hkp-python/src/hkp/ws_tickets.py +54 -0
  736. package/bundle/hkp-python/src/hkp/yas.py +192 -0
  737. package/bundle/hkp-rt/lib/CMakeLists.txt +193 -0
  738. package/bundle/hkp-rt/lib/hkp-bundles/CMakeLists.txt +55 -0
  739. package/bundle/hkp-rt/lib/hkp-bundles/plugin_register.cpp +14 -0
  740. package/bundle/hkp-rt/lib/include/app.h +201 -0
  741. package/bundle/hkp-rt/lib/include/assets.h +239 -0
  742. package/bundle/hkp-rt/lib/include/auth.h +167 -0
  743. package/bundle/hkp-rt/lib/include/call_report.h +197 -0
  744. package/bundle/hkp-rt/lib/include/coordinator_links.h +127 -0
  745. package/bundle/hkp-rt/lib/include/discovery_hooks.h +29 -0
  746. package/bundle/hkp-rt/lib/include/egress.h +379 -0
  747. package/bundle/hkp-rt/lib/include/files.h +275 -0
  748. package/bundle/hkp-rt/lib/include/log_entry.h +131 -0
  749. package/bundle/hkp-rt/lib/include/mounts.h +139 -0
  750. package/bundle/hkp-rt/lib/include/origins.h +363 -0
  751. package/bundle/hkp-rt/lib/include/registry.h +119 -0
  752. package/bundle/hkp-rt/lib/include/secrets.h +414 -0
  753. package/bundle/hkp-rt/lib/include/server.h +122 -0
  754. package/bundle/hkp-rt/lib/include/service.h +190 -0
  755. package/bundle/hkp-rt/lib/include/slot_store.h +41 -0
  756. package/bundle/hkp-rt/lib/include/standalone_config.h +253 -0
  757. package/bundle/hkp-rt/lib/include/types/audio.h +3 -0
  758. package/bundle/hkp-rt/lib/include/types/data.h +152 -0
  759. package/bundle/hkp-rt/lib/include/types/message.h +56 -0
  760. package/bundle/hkp-rt/lib/include/types/models.h +154 -0
  761. package/bundle/hkp-rt/lib/include/types/owns_me.h +19 -0
  762. package/bundle/hkp-rt/lib/include/types/ringbuffer.h +86 -0
  763. package/bundle/hkp-rt/lib/include/types/types.h +33 -0
  764. package/bundle/hkp-rt/lib/include/types/validation.h +205 -0
  765. package/bundle/hkp-rt/lib/src/address.h +88 -0
  766. package/bundle/hkp-rt/lib/src/app.cpp +591 -0
  767. package/bundle/hkp-rt/lib/src/assets.cpp +686 -0
  768. package/bundle/hkp-rt/lib/src/binary_frame.h +154 -0
  769. package/bundle/hkp-rt/lib/src/common/expression.h +1481 -0
  770. package/bundle/hkp-rt/lib/src/common/inja.h +36 -0
  771. package/bundle/hkp-rt/lib/src/common/link_socket.cpp +437 -0
  772. package/bundle/hkp-rt/lib/src/common/link_socket.h +97 -0
  773. package/bundle/hkp-rt/lib/src/common/realtime_wakeup.h +120 -0
  774. package/bundle/hkp-rt/lib/src/common/stream_broadcast.h +250 -0
  775. package/bundle/hkp-rt/lib/src/common/string_util.h +31 -0
  776. package/bundle/hkp-rt/lib/src/common/websocket_client_session.cpp +217 -0
  777. package/bundle/hkp-rt/lib/src/common/websocket_client_session.h +37 -0
  778. package/bundle/hkp-rt/lib/src/common/websocket_config.h +119 -0
  779. package/bundle/hkp-rt/lib/src/common/websocket_protocol.h +32 -0
  780. package/bundle/hkp-rt/lib/src/common/websocket_server.cpp +82 -0
  781. package/bundle/hkp-rt/lib/src/common/websocket_server.h +57 -0
  782. package/bundle/hkp-rt/lib/src/common/websocket_server_listener.cpp +115 -0
  783. package/bundle/hkp-rt/lib/src/common/websocket_server_listener.h +35 -0
  784. package/bundle/hkp-rt/lib/src/common/websocket_server_session.cpp +172 -0
  785. package/bundle/hkp-rt/lib/src/common/websocket_server_session.h +53 -0
  786. package/bundle/hkp-rt/lib/src/common.h +13 -0
  787. package/bundle/hkp-rt/lib/src/coordinator_links.cpp +1142 -0
  788. package/bundle/hkp-rt/lib/src/discovery/discovery.cpp +707 -0
  789. package/bundle/hkp-rt/lib/src/discovery/discovery.h +89 -0
  790. package/bundle/hkp-rt/lib/src/http/auth.cpp +569 -0
  791. package/bundle/hkp-rt/lib/src/http/front_door.cpp +518 -0
  792. package/bundle/hkp-rt/lib/src/http/front_door.h +131 -0
  793. package/bundle/hkp-rt/lib/src/http/server.cpp +1539 -0
  794. package/bundle/hkp-rt/lib/src/http/ws_tickets.h +125 -0
  795. package/bundle/hkp-rt/lib/src/mount.h +63 -0
  796. package/bundle/hkp-rt/lib/src/process_context.h +335 -0
  797. package/bundle/hkp-rt/lib/src/process_depth.h +20 -0
  798. package/bundle/hkp-rt/lib/src/registry.cpp +233 -0
  799. package/bundle/hkp-rt/lib/src/runtime.cpp +986 -0
  800. package/bundle/hkp-rt/lib/src/runtime.h +225 -0
  801. package/bundle/hkp-rt/lib/src/runtime_host.h +180 -0
  802. package/bundle/hkp-rt/lib/src/service.cpp +315 -0
  803. package/bundle/hkp-rt/lib/src/services/asset.h +185 -0
  804. package/bundle/hkp-rt/lib/src/services/audio_encode.cpp +372 -0
  805. package/bundle/hkp-rt/lib/src/services/audio_encode.h +97 -0
  806. package/bundle/hkp-rt/lib/src/services/cache.h +362 -0
  807. package/bundle/hkp-rt/lib/src/services/cache_subservices.h +463 -0
  808. package/bundle/hkp-rt/lib/src/services/core_audio.cpp +384 -0
  809. package/bundle/hkp-rt/lib/src/services/core_audio.h +22 -0
  810. package/bundle/hkp-rt/lib/src/services/core_input.h +337 -0
  811. package/bundle/hkp-rt/lib/src/services/core_output.h +370 -0
  812. package/bundle/hkp-rt/lib/src/services/ffmpeg/detail.cpp +749 -0
  813. package/bundle/hkp-rt/lib/src/services/ffmpeg/detail.h +29 -0
  814. package/bundle/hkp-rt/lib/src/services/ffmpeg/ffmpeg.cpp +193 -0
  815. package/bundle/hkp-rt/lib/src/services/ffmpeg/ffmpeg.h +40 -0
  816. package/bundle/hkp-rt/lib/src/services/ffmpeg/types.h +120 -0
  817. package/bundle/hkp-rt/lib/src/services/fft_service.h +190 -0
  818. package/bundle/hkp-rt/lib/src/services/filesystem.h +309 -0
  819. package/bundle/hkp-rt/lib/src/services/filter.h +208 -0
  820. package/bundle/hkp-rt/lib/src/services/gather.h +272 -0
  821. package/bundle/hkp-rt/lib/src/services/hold.h +304 -0
  822. package/bundle/hkp-rt/lib/src/services/http_client.cpp +347 -0
  823. package/bundle/hkp-rt/lib/src/services/http_client.h +67 -0
  824. package/bundle/hkp-rt/lib/src/services/http_client_impl.h +45 -0
  825. package/bundle/hkp-rt/lib/src/services/http_client_template_examples.md +202 -0
  826. package/bundle/hkp-rt/lib/src/services/http_server/http_listener.cpp +130 -0
  827. package/bundle/hkp-rt/lib/src/services/http_server/http_listener.h +33 -0
  828. package/bundle/hkp-rt/lib/src/services/http_server/http_server.cpp +351 -0
  829. package/bundle/hkp-rt/lib/src/services/http_server/http_server.h +79 -0
  830. package/bundle/hkp-rt/lib/src/services/http_server/http_server_impl.cpp +230 -0
  831. package/bundle/hkp-rt/lib/src/services/http_server/http_server_impl.h +64 -0
  832. package/bundle/hkp-rt/lib/src/services/http_server/http_server_subservices.cpp +950 -0
  833. package/bundle/hkp-rt/lib/src/services/http_server/http_server_subservices.h +253 -0
  834. package/bundle/hkp-rt/lib/src/services/http_server/http_session.cpp +495 -0
  835. package/bundle/hkp-rt/lib/src/services/http_server/http_session.h +169 -0
  836. package/bundle/hkp-rt/lib/src/services/http_server/http_stream_listener.cpp +270 -0
  837. package/bundle/hkp-rt/lib/src/services/http_server/http_stream_listener.h +104 -0
  838. package/bundle/hkp-rt/lib/src/services/http_server/request_decode.h +164 -0
  839. package/bundle/hkp-rt/lib/src/services/if_service.h +210 -0
  840. package/bundle/hkp-rt/lib/src/services/ifft_service.h +198 -0
  841. package/bundle/hkp-rt/lib/src/services/injector.h +162 -0
  842. package/bundle/hkp-rt/lib/src/services/iterator.h +201 -0
  843. package/bundle/hkp-rt/lib/src/services/map.h +641 -0
  844. package/bundle/hkp-rt/lib/src/services/monitor.h +161 -0
  845. package/bundle/hkp-rt/lib/src/services/mp3_frames.h +119 -0
  846. package/bundle/hkp-rt/lib/src/services/mp4_to_wav.cpp +281 -0
  847. package/bundle/hkp-rt/lib/src/services/mp4_to_wav.h +263 -0
  848. package/bundle/hkp-rt/lib/src/services/peer_server/peer_registry.cpp +88 -0
  849. package/bundle/hkp-rt/lib/src/services/peer_server/peer_registry.h +43 -0
  850. package/bundle/hkp-rt/lib/src/services/peer_server/peer_server.h +163 -0
  851. package/bundle/hkp-rt/lib/src/services/peer_server/peer_server_listener.cpp +133 -0
  852. package/bundle/hkp-rt/lib/src/services/peer_server/peer_server_listener.h +46 -0
  853. package/bundle/hkp-rt/lib/src/services/peer_server/peer_server_session.cpp +165 -0
  854. package/bundle/hkp-rt/lib/src/services/peer_server/peer_server_session.h +44 -0
  855. package/bundle/hkp-rt/lib/src/services/peer_server/peer_ws_session.cpp +184 -0
  856. package/bundle/hkp-rt/lib/src/services/peer_server/peer_ws_session.h +55 -0
  857. package/bundle/hkp-rt/lib/src/services/receiver_session.h +172 -0
  858. package/bundle/hkp-rt/lib/src/services/root_certificates.h +3959 -0
  859. package/bundle/hkp-rt/lib/src/services/sha256_openssl.h +49 -0
  860. package/bundle/hkp-rt/lib/src/services/speech_http.h +306 -0
  861. package/bundle/hkp-rt/lib/src/services/speech_to_text.cpp +595 -0
  862. package/bundle/hkp-rt/lib/src/services/speech_to_text.h +69 -0
  863. package/bundle/hkp-rt/lib/src/services/static.cpp +45 -0
  864. package/bundle/hkp-rt/lib/src/services/static.h +41 -0
  865. package/bundle/hkp-rt/lib/src/services/stopper.h +72 -0
  866. package/bundle/hkp-rt/lib/src/services/sub_service.h +286 -0
  867. package/bundle/hkp-rt/lib/src/services/text_generation.cpp +1132 -0
  868. package/bundle/hkp-rt/lib/src/services/text_generation.h +71 -0
  869. package/bundle/hkp-rt/lib/src/services/text_to_speech.cpp +853 -0
  870. package/bundle/hkp-rt/lib/src/services/text_to_speech.h +97 -0
  871. package/bundle/hkp-rt/lib/src/services/timer.h +300 -0
  872. package/bundle/hkp-rt/lib/src/services/tracks.h +397 -0
  873. package/bundle/hkp-rt/lib/src/services/tts_inflect.cpp +149 -0
  874. package/bundle/hkp-rt/lib/src/services/tts_inflect.h +82 -0
  875. package/bundle/hkp-rt/lib/src/services/wav_reader.h +213 -0
  876. package/bundle/hkp-rt/lib/src/services/websocket_client_service.h +182 -0
  877. package/bundle/hkp-rt/lib/src/services/websocket_reader.h +148 -0
  878. package/bundle/hkp-rt/lib/src/services/websocket_server_service.h +196 -0
  879. package/bundle/hkp-rt/lib/src/services/websocket_writer.cpp +641 -0
  880. package/bundle/hkp-rt/lib/src/services/websocket_writer.h +117 -0
  881. package/bundle/hkp-rt/lib/src/sub_runtime.cpp +234 -0
  882. package/bundle/hkp-rt/lib/src/sub_runtime.h +160 -0
  883. package/bundle/hkp-rt/lib/src/types/data.cpp +237 -0
  884. package/bundle/hkp-rt/lib/src/types/message.cpp +148 -0
  885. package/bundle/hkp-rt/lib/src/types/models.cpp +83 -0
  886. package/bundle/hkp-rt/lib/src/types/ringbuffer.cpp +336 -0
  887. package/bundle/hkp-rt/lib/src/uuid.h +12 -0
  888. package/bundle/readymade-mcp-commits.json +5 -0
  889. package/dist/cli.d.ts +3 -0
  890. package/dist/cli.d.ts.map +1 -0
  891. package/dist/cli.js +79 -0
  892. package/dist/git.d.ts +8 -0
  893. package/dist/git.d.ts.map +1 -0
  894. package/dist/git.js +53 -0
  895. package/dist/http.d.ts +17 -0
  896. package/dist/http.d.ts.map +1 -0
  897. package/dist/http.js +130 -0
  898. package/dist/index.d.ts +7 -0
  899. package/dist/index.d.ts.map +1 -0
  900. package/dist/index.js +6 -0
  901. package/dist/repository.d.ts +49 -0
  902. package/dist/repository.d.ts.map +1 -0
  903. package/dist/repository.js +452 -0
  904. package/dist/schemas.d.ts +156 -0
  905. package/dist/schemas.d.ts.map +1 -0
  906. package/dist/schemas.js +43 -0
  907. package/dist/server.d.ts +4 -0
  908. package/dist/server.d.ts.map +1 -0
  909. package/dist/server.js +83 -0
  910. package/dist/types.d.ts +63 -0
  911. package/dist/types.d.ts.map +1 -0
  912. package/dist/types.js +20 -0
  913. package/dist/validation.d.ts +9 -0
  914. package/dist/validation.d.ts.map +1 -0
  915. package/dist/validation.js +101 -0
  916. package/package.json +52 -4
@@ -0,0 +1,1132 @@
1
+ #include "./text_generation.h"
2
+ #include "egress.h"
3
+
4
+ #include <algorithm>
5
+ #include <atomic>
6
+ #include <chrono>
7
+ #include <functional>
8
+ #include <iostream>
9
+ #include <mutex>
10
+ #include <optional>
11
+ #include <string>
12
+ #include <thread>
13
+ #include <vector>
14
+
15
+ #include <boost/beast/core.hpp>
16
+ #include <boost/beast/http.hpp>
17
+ #include <boost/beast/ssl.hpp>
18
+ #include <boost/beast/version.hpp>
19
+ #include <boost/asio/connect.hpp>
20
+ #include <boost/asio/ip/tcp.hpp>
21
+ #include <boost/asio/ssl/error.hpp>
22
+ #include <boost/asio/ssl/stream.hpp>
23
+ #include <boost/url.hpp>
24
+ #include <boost/url/scheme.hpp>
25
+
26
+ #include "./root_certificates.h"
27
+
28
+ #ifdef HKP_LLAMA_ENABLED
29
+ #include <llama.h>
30
+ #endif
31
+
32
+ namespace beast = boost::beast;
33
+ namespace http = beast::http;
34
+ namespace net = boost::asio;
35
+ namespace ssl = net::ssl;
36
+ namespace urls = boost::urls;
37
+ using tcp = net::ip::tcp;
38
+
39
+ namespace hkp {
40
+
41
+ namespace {
42
+
43
+ const std::string kDefaultServerUrl = "http://127.0.0.1:8081";
44
+
45
+ constexpr int kDefaultContextSize = 4096;
46
+ constexpr int kDefaultGpuLayers = -1; // -1 = offload every layer
47
+
48
+ // Sensible generic chat settings; they match the hkp-python service so a board
49
+ // can move a text-generation service between the two runtimes unchanged.
50
+ const std::string kDefaultSystemPrompt = "You are a helpful assistant";
51
+ constexpr double kDefaultTemperature = 0.7;
52
+ constexpr double kDefaultTopP = 0.95;
53
+ constexpr int kDefaultTopK = 20;
54
+ constexpr int kDefaultMaxTokens = 512;
55
+ constexpr double kDefaultTimeoutSec = 300.0;
56
+
57
+ const std::string kThinkOpen = "<think>";
58
+ const std::string kThinkClose = "</think>";
59
+
60
+ // ~20 updates/s is plenty for a live view and keeps the notification socket
61
+ // calm at high token rates.
62
+ constexpr auto kStreamNotifyInterval = std::chrono::milliseconds(50);
63
+
64
+ const std::string kBuildHint =
65
+ "the local backend is not compiled in — rebuild hkp-rt with -DHKP_LLAMA_ENABLED=ON";
66
+
67
+ std::string serverHint(const std::string& serverUrl)
68
+ {
69
+ return "no OpenAI-compatible server reachable at " + serverUrl +
70
+ " — start one, e.g.: llama-server -m model.gguf --port 8081 -ngl 99";
71
+ }
72
+
73
+ std::string expandUser(const std::string& path)
74
+ {
75
+ if (path.rfind("~/", 0) != 0)
76
+ {
77
+ return path;
78
+ }
79
+ const char* home = std::getenv("HOME");
80
+ return home ? home + path.substr(1) : path;
81
+ }
82
+
83
+ std::string trim(const std::string& s)
84
+ {
85
+ auto begin = s.find_first_not_of(" \t\r\n");
86
+ if (begin == std::string::npos)
87
+ {
88
+ return {};
89
+ }
90
+ auto end = s.find_last_not_of(" \t\r\n");
91
+ return s.substr(begin, end - begin + 1);
92
+ }
93
+
94
+ // ── Server backend: OpenAI-compatible chat completions over HTTP ─────────────
95
+
96
+ // Feed a server-sent-event body fragment through the SSE framing and hand each
97
+ // complete `data:` payload to onEvent. Returns false once the `[DONE]`
98
+ // sentinel has been seen. `pending` carries the partial trailing line between
99
+ // calls.
100
+ bool consumeSseFragment(std::string& pending,
101
+ const std::string& fragment,
102
+ const std::function<void(const std::string&)>& onEvent)
103
+ {
104
+ pending += fragment;
105
+ std::size_t newline = 0;
106
+ while ((newline = pending.find('\n')) != std::string::npos)
107
+ {
108
+ auto line = trim(pending.substr(0, newline));
109
+ pending.erase(0, newline + 1);
110
+ if (line.rfind("data:", 0) != 0)
111
+ {
112
+ continue;
113
+ }
114
+ auto payload = trim(line.substr(5));
115
+ if (payload == "[DONE]")
116
+ {
117
+ return false;
118
+ }
119
+ onEvent(payload);
120
+ }
121
+ return true;
122
+ }
123
+
124
+ // An error reported by the server itself, as opposed to a transport failure.
125
+ // Distinct from the boost exceptions (which derive from std::runtime_error) so
126
+ // that the server's own message can be surfaced verbatim while transport
127
+ // failures get the "is a server running?" hint.
128
+ struct ServerError : std::exception
129
+ {
130
+ explicit ServerError(std::string what) : message(std::move(what)) {}
131
+ const char* what() const noexcept override { return message.c_str(); }
132
+ std::string message;
133
+ };
134
+
135
+ // Fold streamed completion chunks into a response of the same shape as a
136
+ // non-streaming call, so both paths share the result extraction.
137
+ json parseStreamChunks(const std::vector<json>& chunks)
138
+ {
139
+ std::string content;
140
+ std::string reasoning;
141
+ std::string model;
142
+ json usage = json::object();
143
+
144
+ for (const auto& chunk : chunks)
145
+ {
146
+ if (!chunk.is_object())
147
+ {
148
+ continue;
149
+ }
150
+ if (chunk.contains("model") && chunk["model"].is_string())
151
+ {
152
+ model = chunk["model"];
153
+ }
154
+ if (chunk.contains("usage") && chunk["usage"].is_object())
155
+ {
156
+ usage = chunk["usage"];
157
+ }
158
+ if (!chunk.contains("choices") || !chunk["choices"].is_array() || chunk["choices"].empty())
159
+ {
160
+ continue;
161
+ }
162
+ const auto& choice = chunk["choices"][0];
163
+ if (!choice.contains("delta") || !choice["delta"].is_object())
164
+ {
165
+ continue;
166
+ }
167
+ const auto& delta = choice["delta"];
168
+ if (delta.contains("reasoning_content") && delta["reasoning_content"].is_string())
169
+ {
170
+ reasoning += delta["reasoning_content"].get<std::string>();
171
+ }
172
+ if (delta.contains("content") && delta["content"].is_string())
173
+ {
174
+ content += delta["content"].get<std::string>();
175
+ }
176
+ }
177
+
178
+ json message = { { "role", "assistant" }, { "content", content } };
179
+ if (!reasoning.empty())
180
+ {
181
+ message["reasoning_content"] = reasoning;
182
+ }
183
+ json response = { { "choices", json::array({ json{ { "message", message } } }) } };
184
+ if (!model.empty())
185
+ {
186
+ response["model"] = model;
187
+ }
188
+ if (!usage.empty())
189
+ {
190
+ response["usage"] = usage;
191
+ }
192
+ return response;
193
+ }
194
+
195
+ // Run one chat-completion request over an already-connected stream. In
196
+ // streaming mode onText receives the growing assistant text; the return value
197
+ // is a non-streaming-shaped response either way. Throws on transport errors.
198
+ template <typename Stream>
199
+ json chatCompletion(Stream& stream,
200
+ const std::string& host,
201
+ const std::string& target,
202
+ const std::string& payload,
203
+ bool streaming,
204
+ const std::function<void(const std::string&)>& onText)
205
+ {
206
+ http::request<http::string_body> req{ http::verb::post, target, 11 };
207
+ req.set(http::field::host, host);
208
+ req.set(http::field::user_agent, "hkp-rt");
209
+ req.set(http::field::content_type, "application/json");
210
+ req.set(http::field::accept, streaming ? "text/event-stream" : "application/json");
211
+ req.body() = payload;
212
+ req.prepare_payload();
213
+ http::write(stream, req);
214
+
215
+ beast::flat_buffer buffer;
216
+ http::response_parser<http::string_body> parser;
217
+ parser.body_limit(boost::none);
218
+ http::read_header(stream, buffer, parser);
219
+
220
+ const auto status = parser.get().result_int();
221
+ if (status >= 400)
222
+ {
223
+ beast::error_code readEc;
224
+ http::read(stream, buffer, parser, readEc);
225
+ auto detail = parser.get().body().substr(0, 200);
226
+ throw ServerError("server returned HTTP " + std::to_string(status) + ": " + detail);
227
+ }
228
+
229
+ if (!streaming)
230
+ {
231
+ http::read(stream, buffer, parser);
232
+ return json::parse(parser.get().body());
233
+ }
234
+
235
+ std::vector<json> chunks;
236
+ std::string pending;
237
+ std::string text;
238
+ auto lastSent = std::chrono::steady_clock::now() - kStreamNotifyInterval;
239
+ bool more = true;
240
+
241
+ auto onEvent = [&](const std::string& data)
242
+ {
243
+ json chunk;
244
+ try
245
+ {
246
+ chunk = json::parse(data);
247
+ }
248
+ catch (const json::parse_error&)
249
+ {
250
+ return;
251
+ }
252
+ chunks.push_back(chunk);
253
+
254
+ // Track the growing text here rather than re-folding all chunks per event.
255
+ if (!chunk.contains("choices") || !chunk["choices"].is_array() || chunk["choices"].empty())
256
+ {
257
+ return;
258
+ }
259
+ const auto& delta = chunk["choices"][0]["delta"];
260
+ if (!delta.is_object() || !delta.contains("content") || !delta["content"].is_string())
261
+ {
262
+ return;
263
+ }
264
+ text += delta["content"].get<std::string>();
265
+ auto now = std::chrono::steady_clock::now();
266
+ if (now - lastSent >= kStreamNotifyInterval)
267
+ {
268
+ lastSent = now;
269
+ onText(text);
270
+ }
271
+ };
272
+
273
+ while (more && !parser.is_done())
274
+ {
275
+ beast::error_code ec;
276
+ http::read_some(stream, buffer, parser, ec);
277
+ if (ec == http::error::need_buffer)
278
+ {
279
+ ec = {};
280
+ }
281
+ if (ec == http::error::end_of_stream || ec == net::error::eof)
282
+ {
283
+ break;
284
+ }
285
+ if (ec)
286
+ {
287
+ throw beast::system_error{ ec };
288
+ }
289
+ auto& body = parser.get().body();
290
+ if (body.empty())
291
+ {
292
+ continue;
293
+ }
294
+ auto fragment = body;
295
+ body.clear();
296
+ more = consumeSseFragment(pending, fragment, onEvent);
297
+ }
298
+
299
+ return parseStreamChunks(chunks);
300
+ }
301
+
302
+ // ── Local backend: in-process llama.cpp ─────────────────────────────────────
303
+
304
+ #ifdef HKP_LLAMA_ENABLED
305
+
306
+ struct ChatMessage
307
+ {
308
+ std::string role;
309
+ std::string content;
310
+ };
311
+
312
+ // Lazy-loading wrapper around an in-process llama.cpp model. Owns the
313
+ // local-backend config (modelPath, contextSize, gpuLayers) and the loaded-model
314
+ // cache, and reloads when any of them change.
315
+ class LocalLlama
316
+ {
317
+ public:
318
+ std::string modelPath;
319
+ int contextSize = kDefaultContextSize;
320
+ int gpuLayers = kDefaultGpuLayers;
321
+
322
+ ~LocalLlama()
323
+ {
324
+ release();
325
+ }
326
+
327
+ // Drop the cached model if its parameters changed; it reloads lazily.
328
+ void invalidateIfStale()
329
+ {
330
+ if (m_model && m_loadedKey != key())
331
+ {
332
+ release();
333
+ }
334
+ }
335
+
336
+ bool isLoaded() const
337
+ {
338
+ return m_model != nullptr;
339
+ }
340
+
341
+ // Returns an empty string on success, the failure reason otherwise.
342
+ std::string ensure()
343
+ {
344
+ if (m_model)
345
+ {
346
+ return {};
347
+ }
348
+
349
+ static std::once_flag backendOnce;
350
+ std::call_once(backendOnce, []
351
+ {
352
+ llama_log_set([](ggml_log_level level, const char* text, void*)
353
+ {
354
+ if (level >= GGML_LOG_LEVEL_ERROR)
355
+ {
356
+ std::cerr << text;
357
+ }
358
+ }, nullptr);
359
+ llama_backend_init();
360
+ });
361
+
362
+ auto modelParams = llama_model_default_params();
363
+ modelParams.n_gpu_layers = gpuLayers;
364
+ m_model = llama_model_load_from_file(modelPath.c_str(), modelParams);
365
+ if (!m_model)
366
+ {
367
+ return "failed to load model '" + modelPath + "'";
368
+ }
369
+
370
+ auto ctxParams = llama_context_default_params();
371
+ ctxParams.n_ctx = static_cast<uint32_t>(contextSize);
372
+ ctxParams.n_batch = static_cast<uint32_t>(contextSize);
373
+ m_ctx = llama_init_from_model(m_model, ctxParams);
374
+ if (!m_ctx)
375
+ {
376
+ release();
377
+ return "failed to create a llama context for '" + modelPath + "'";
378
+ }
379
+
380
+ m_loadedKey = key();
381
+ return {};
382
+ }
383
+
384
+ void release()
385
+ {
386
+ if (m_ctx)
387
+ {
388
+ llama_free(m_ctx);
389
+ m_ctx = nullptr;
390
+ }
391
+ if (m_model)
392
+ {
393
+ llama_model_free(m_model);
394
+ m_model = nullptr;
395
+ }
396
+ m_loadedKey.clear();
397
+ }
398
+
399
+ // Render the conversation with the model's own chat template, leaving the
400
+ // prompt ready for the assistant to continue.
401
+ std::string applyChatTemplate(const std::vector<ChatMessage>& messages) const
402
+ {
403
+ std::vector<llama_chat_message> raw;
404
+ raw.reserve(messages.size());
405
+ for (const auto& message : messages)
406
+ {
407
+ raw.push_back({ message.role.c_str(), message.content.c_str() });
408
+ }
409
+
410
+ const char* tmpl = llama_model_chat_template(m_model, nullptr);
411
+ std::vector<char> buffer(std::max<size_t>(2048, llama_n_ctx(m_ctx)));
412
+ int len = llama_chat_apply_template(tmpl, raw.data(), raw.size(), true, buffer.data(), buffer.size());
413
+ if (len > static_cast<int>(buffer.size()))
414
+ {
415
+ buffer.resize(len);
416
+ len = llama_chat_apply_template(tmpl, raw.data(), raw.size(), true, buffer.data(), buffer.size());
417
+ }
418
+ if (len < 0)
419
+ {
420
+ return {};
421
+ }
422
+ return std::string(buffer.data(), len);
423
+ }
424
+
425
+ struct Generation
426
+ {
427
+ std::string text;
428
+ int promptTokens = 0;
429
+ int completionTokens = 0;
430
+ std::string error;
431
+ };
432
+
433
+ // Generate a completion for `prompt`. Each request starts from an empty KV
434
+ // cache, so the rendered conversation is the whole context — the service is
435
+ // stateless between calls, like its hkp-python counterpart.
436
+ Generation generate(const std::string& prompt,
437
+ double temperature,
438
+ double topP,
439
+ int topK,
440
+ int maxTokens,
441
+ const std::function<void(const std::string&)>& onText)
442
+ {
443
+ Generation result;
444
+
445
+ const llama_vocab* vocab = llama_model_get_vocab(m_model);
446
+ llama_memory_clear(llama_get_memory(m_ctx), true);
447
+
448
+ const int promptTokenCount =
449
+ -llama_tokenize(vocab, prompt.c_str(), prompt.size(), nullptr, 0, true, true);
450
+ std::vector<llama_token> promptTokens(promptTokenCount);
451
+ if (llama_tokenize(vocab, prompt.c_str(), prompt.size(),
452
+ promptTokens.data(), promptTokens.size(), true, true) < 0)
453
+ {
454
+ result.error = "failed to tokenize the prompt";
455
+ return result;
456
+ }
457
+ result.promptTokens = promptTokenCount;
458
+
459
+ llama_sampler* sampler = llama_sampler_chain_init(llama_sampler_chain_default_params());
460
+ if (topK > 0)
461
+ {
462
+ llama_sampler_chain_add(sampler, llama_sampler_init_top_k(topK));
463
+ }
464
+ if (topP > 0.0 && topP < 1.0)
465
+ {
466
+ llama_sampler_chain_add(sampler, llama_sampler_init_top_p(static_cast<float>(topP), 1));
467
+ }
468
+ llama_sampler_chain_add(sampler, llama_sampler_init_temp(static_cast<float>(temperature)));
469
+ llama_sampler_chain_add(sampler, llama_sampler_init_dist(LLAMA_DEFAULT_SEED));
470
+
471
+ auto batch = llama_batch_get_one(promptTokens.data(), promptTokens.size());
472
+ auto lastSent = std::chrono::steady_clock::now() - kStreamNotifyInterval;
473
+ const int contextLimit = static_cast<int>(llama_n_ctx(m_ctx));
474
+
475
+ while (result.completionTokens < maxTokens)
476
+ {
477
+ const int used = llama_memory_seq_pos_max(llama_get_memory(m_ctx), 0) + 1;
478
+ if (used + batch.n_tokens > contextLimit)
479
+ {
480
+ result.error = "context size exceeded";
481
+ break;
482
+ }
483
+ if (llama_decode(m_ctx, batch) != 0)
484
+ {
485
+ result.error = "failed to decode";
486
+ break;
487
+ }
488
+
489
+ llama_token token = llama_sampler_sample(sampler, m_ctx, -1);
490
+ if (llama_vocab_is_eog(vocab, token))
491
+ {
492
+ break;
493
+ }
494
+
495
+ char piece[256];
496
+ const int n = llama_token_to_piece(vocab, token, piece, sizeof(piece), 0, true);
497
+ if (n < 0)
498
+ {
499
+ result.error = "failed to convert a token to text";
500
+ break;
501
+ }
502
+ result.text.append(piece, n);
503
+ result.completionTokens++;
504
+
505
+ if (onText)
506
+ {
507
+ auto now = std::chrono::steady_clock::now();
508
+ if (now - lastSent >= kStreamNotifyInterval)
509
+ {
510
+ lastSent = now;
511
+ onText(result.text);
512
+ }
513
+ }
514
+
515
+ batch = llama_batch_get_one(&token, 1);
516
+ }
517
+
518
+ llama_sampler_free(sampler);
519
+ return result;
520
+ }
521
+
522
+ private:
523
+ std::string key() const
524
+ {
525
+ return modelPath + "|" + std::to_string(contextSize) + "|" + std::to_string(gpuLayers);
526
+ }
527
+
528
+ llama_model* m_model = nullptr;
529
+ llama_context* m_ctx = nullptr;
530
+ std::string m_loadedKey;
531
+ };
532
+
533
+ #endif // HKP_LLAMA_ENABLED
534
+
535
+ // An immutable snapshot of everything a single generation needs, taken on the
536
+ // pipeline thread before the work is handed to the worker. It lets the worker
537
+ // run without touching the service's mutable config, which configure() may
538
+ // change concurrently; only the local model object stays shared (guarded by
539
+ // TextGenerationImpl::localMutex).
540
+ struct GenParams
541
+ {
542
+ std::string backend;
543
+ std::string serverUrl;
544
+ std::string model;
545
+ json messages;
546
+ double temperature = kDefaultTemperature;
547
+ double topP = kDefaultTopP;
548
+ int topK = kDefaultTopK;
549
+ int maxTokens = kDefaultMaxTokens;
550
+ double timeoutSec = kDefaultTimeoutSec;
551
+ std::optional<bool> thinking;
552
+ bool stream = true;
553
+ };
554
+
555
+ } // namespace
556
+
557
+ struct TextGenerationImpl
558
+ {
559
+ std::string backend = "server";
560
+ std::string serverUrl = kDefaultServerUrl;
561
+ std::string model;
562
+ std::string systemPrompt = kDefaultSystemPrompt;
563
+ double temperature = kDefaultTemperature;
564
+ double topP = kDefaultTopP;
565
+ int topK = kDefaultTopK;
566
+ int maxTokens = kDefaultMaxTokens;
567
+ double timeoutSec = kDefaultTimeoutSec;
568
+ // unset = server default; false makes thinking models answer directly, which
569
+ // matters for interactive boards (thinking burns the whole token budget
570
+ // invisibly before the first visible character).
571
+ std::optional<bool> thinking;
572
+ // Stream the completion token by token, notifying the growing text as
573
+ // {streamText} for live UI display. The pipeline output is unaffected: the
574
+ // full result is still emitted once, when generation finishes.
575
+ bool stream = true;
576
+ std::string status = "idle";
577
+
578
+ // Inference is long-running, so process() hands it to this worker instead of
579
+ // blocking the pipeline thread (the App event loop / UI thread). `generating`
580
+ // admits one generation at a time; `localMutex` guards the shared local model
581
+ // so configure() never reloads it while the worker is decoding.
582
+ std::atomic<bool> generating{ false };
583
+ std::thread worker;
584
+ std::mutex localMutex;
585
+
586
+ // Local-backend config lives on LocalLlama when it is compiled in, so that
587
+ // the loaded-model cache is invalidated in lockstep with the values.
588
+ #ifdef HKP_LLAMA_ENABLED
589
+ LocalLlama local;
590
+ #else
591
+ std::string modelPath;
592
+ int contextSize = kDefaultContextSize;
593
+ int gpuLayers = kDefaultGpuLayers;
594
+ #endif
595
+
596
+ std::string& modelPathRef()
597
+ {
598
+ #ifdef HKP_LLAMA_ENABLED
599
+ return local.modelPath;
600
+ #else
601
+ return modelPath;
602
+ #endif
603
+ }
604
+
605
+ int& contextSizeRef()
606
+ {
607
+ #ifdef HKP_LLAMA_ENABLED
608
+ return local.contextSize;
609
+ #else
610
+ return contextSize;
611
+ #endif
612
+ }
613
+
614
+ int& gpuLayersRef()
615
+ {
616
+ #ifdef HKP_LLAMA_ENABLED
617
+ return local.gpuLayers;
618
+ #else
619
+ return gpuLayers;
620
+ #endif
621
+ }
622
+ };
623
+
624
+ TextGeneration::TextGeneration(const std::string& instanceId)
625
+ : Service(instanceId, serviceId())
626
+ , m_impl(std::make_unique<TextGenerationImpl>())
627
+ {
628
+ }
629
+
630
+ TextGeneration::~TextGeneration()
631
+ {
632
+ // Backstop: the host calls shutdown() first (while it is still alive), so this
633
+ // is normally a no-op. Still join here for a service destroyed on its own.
634
+ if (m_impl && m_impl->worker.joinable())
635
+ {
636
+ m_impl->worker.join();
637
+ }
638
+ }
639
+
640
+ void TextGeneration::shutdown()
641
+ {
642
+ // Join any in-flight generation so its emit() runs while the host is still
643
+ // alive. Idempotent — the destructor's join then finds nothing to do.
644
+ if (m_impl && m_impl->worker.joinable())
645
+ {
646
+ m_impl->worker.join();
647
+ }
648
+ }
649
+
650
+ json TextGeneration::configure(Data data)
651
+ {
652
+ auto j = getJSONFromData(data);
653
+ if (j)
654
+ {
655
+ if (j->contains("backend") && (*j)["backend"].is_string())
656
+ {
657
+ auto backend = (*j)["backend"].get<std::string>();
658
+ if (backend == "server" || backend == "local")
659
+ {
660
+ m_impl->backend = backend;
661
+ }
662
+ }
663
+ if (j->contains("serverUrl") && (*j)["serverUrl"].is_string())
664
+ {
665
+ auto url = (*j)["serverUrl"].get<std::string>();
666
+ while (!url.empty() && url.back() == '/')
667
+ {
668
+ url.pop_back();
669
+ }
670
+ if (!url.empty())
671
+ {
672
+ m_impl->serverUrl = url;
673
+ }
674
+ }
675
+ updateIfNeeded(m_impl->model, (*j)["model"]);
676
+ {
677
+ // Mutate the local model's paths and invalidate its cached model together,
678
+ // under the lock the worker holds while decoding, so a reload can never
679
+ // race an in-flight generation (which would free the model out from under
680
+ // it). A configure() arriving mid-generation blocks here until it ends.
681
+ std::lock_guard<std::mutex> lock(m_impl->localMutex);
682
+ if (j->contains("modelPath") && (*j)["modelPath"].is_string())
683
+ {
684
+ m_impl->modelPathRef() = expandUser((*j)["modelPath"].get<std::string>());
685
+ }
686
+ updateIfNeeded(m_impl->contextSizeRef(), (*j)["contextSize"]);
687
+ updateIfNeeded(m_impl->gpuLayersRef(), (*j)["gpuLayers"]);
688
+ #ifdef HKP_LLAMA_ENABLED
689
+ m_impl->local.invalidateIfStale();
690
+ #endif
691
+ }
692
+ updateIfNeeded(m_impl->systemPrompt, (*j)["systemPrompt"]);
693
+ updateIfNeeded(m_impl->temperature, (*j)["temperature"]);
694
+ updateIfNeeded(m_impl->topP, (*j)["topP"]);
695
+ updateIfNeeded(m_impl->topK, (*j)["topK"]);
696
+ updateIfNeeded(m_impl->maxTokens, (*j)["maxTokens"]);
697
+ updateIfNeeded(m_impl->timeoutSec, (*j)["timeoutSec"]);
698
+ if (j->contains("thinking"))
699
+ {
700
+ const auto& thinking = (*j)["thinking"];
701
+ m_impl->thinking = thinking.is_boolean() ? std::optional<bool>(thinking.get<bool>())
702
+ : std::nullopt;
703
+ }
704
+ if (j->contains("stream") && (*j)["stream"].is_boolean())
705
+ {
706
+ m_impl->stream = (*j)["stream"];
707
+ }
708
+ }
709
+ return Service::configure(data);
710
+ }
711
+
712
+ std::string TextGeneration::getServiceId() const
713
+ {
714
+ return serviceId();
715
+ }
716
+
717
+ json TextGeneration::getState() const
718
+ {
719
+ return Service::mergeStateWith(json{
720
+ { "backend", m_impl->backend },
721
+ { "serverUrl", m_impl->serverUrl },
722
+ { "model", m_impl->model },
723
+ { "modelPath", m_impl->modelPathRef() },
724
+ { "contextSize", m_impl->contextSizeRef() },
725
+ { "gpuLayers", m_impl->gpuLayersRef() },
726
+ { "systemPrompt", m_impl->systemPrompt },
727
+ { "temperature", m_impl->temperature },
728
+ { "topP", m_impl->topP },
729
+ { "topK", m_impl->topK },
730
+ { "maxTokens", m_impl->maxTokens },
731
+ { "timeoutSec", m_impl->timeoutSec },
732
+ { "thinking", m_impl->thinking ? json(*m_impl->thinking) : json(nullptr) },
733
+ { "stream", m_impl->stream },
734
+ { "status", m_impl->status }
735
+ });
736
+ }
737
+
738
+ namespace {
739
+
740
+ // Split reasoning from the answer for thinking models. The reasoning arrives
741
+ // either as a separate `reasoning_content` field (llama-server default) or
742
+ // inline as <think>...</think> in the content, depending on the chat-template
743
+ // handling.
744
+ void splitThinking(const json& message, std::string& text, std::string& thinking)
745
+ {
746
+ text = message.value("content", std::string{});
747
+ thinking = message.value("reasoning_content", std::string{});
748
+
749
+ auto close = text.find(kThinkClose);
750
+ if (close != std::string::npos)
751
+ {
752
+ auto inline_ = text.substr(0, close);
753
+ text = text.substr(close + kThinkClose.size());
754
+ auto open = inline_.find(kThinkOpen);
755
+ if (open != std::string::npos)
756
+ {
757
+ inline_.erase(open, kThinkOpen.size());
758
+ }
759
+ inline_ = trim(inline_);
760
+ thinking = thinking.empty() ? inline_ : trim(thinking + "\n" + inline_);
761
+ }
762
+ text = trim(text);
763
+ thinking = trim(thinking);
764
+ }
765
+
766
+ } // namespace
767
+
768
+ Data TextGeneration::process(Data data)
769
+ {
770
+ if (isNull(data) || isUndefined(data))
771
+ {
772
+ return Null();
773
+ }
774
+
775
+ // These close over `this` only, so a copy survives the return of process()
776
+ // and can run on the worker thread. sendNotification marshals onto the App
777
+ // event loop, so it is safe to call from there.
778
+ auto setStatus = [this](const std::string& status, const std::string& detail = {})
779
+ {
780
+ m_impl->status = status;
781
+ json payload = { { "status", status } };
782
+ if (!detail.empty())
783
+ {
784
+ payload["detail"] = detail;
785
+ }
786
+ sendNotification(Data(payload));
787
+ };
788
+
789
+ auto fail = [this, setStatus](const std::string& message) -> Data
790
+ {
791
+ setStatus("error");
792
+ json result = { { "error", message } };
793
+ sendNotification(Data(result));
794
+ return Data(result);
795
+ };
796
+
797
+ auto notifyText = [this](const std::string& text)
798
+ {
799
+ sendNotification(Data(json{ { "streamText", text } }));
800
+ };
801
+
802
+ // ── Build the message list (cheap; stays on the pipeline thread) ────────────
803
+ json messages = json::array();
804
+ std::string prompt;
805
+ if (auto str = getStringFromData(data); str)
806
+ {
807
+ prompt = *str;
808
+ }
809
+ else if (auto j = getJSONFromData(data); j && j->is_object())
810
+ {
811
+ if (j->contains("messages") && (*j)["messages"].is_array())
812
+ {
813
+ messages = (*j)["messages"];
814
+ }
815
+ else
816
+ {
817
+ for (const auto& key : { "prompt", "text" })
818
+ {
819
+ if (j->contains(key) && (*j)[key].is_string())
820
+ {
821
+ prompt = (*j)[key].get<std::string>();
822
+ if (!prompt.empty())
823
+ {
824
+ break;
825
+ }
826
+ }
827
+ }
828
+ }
829
+ }
830
+
831
+ if (messages.empty())
832
+ {
833
+ if (trim(prompt).empty())
834
+ {
835
+ return fail("text-generation expects String input or JSON with 'prompt', 'text', or 'messages'");
836
+ }
837
+ messages.push_back(json{ { "role", "user" }, { "content", prompt } });
838
+ }
839
+
840
+ if (!m_impl->systemPrompt.empty())
841
+ {
842
+ const bool hasSystem = std::any_of(messages.begin(), messages.end(), [](const json& message)
843
+ {
844
+ return message.is_object() && message.value("role", std::string{}) == "system";
845
+ });
846
+ if (!hasSystem)
847
+ {
848
+ messages.insert(messages.begin(), json{ { "role", "system" }, { "content", m_impl->systemPrompt } });
849
+ }
850
+ }
851
+
852
+ // Only one generation may run at a time: the local llama_context is single
853
+ // threaded with a per-call KV cache, and the server backend opens one
854
+ // connection. Reject an overlapping request rather than corrupt that state.
855
+ bool expected = false;
856
+ if (!m_impl->generating.compare_exchange_strong(expected, true))
857
+ {
858
+ setStatus("error", "a generation is already in progress");
859
+ // This invocation owns no worker and therefore cannot borrow the earlier
860
+ // invocation's eventual answer or authority.
861
+ return Null();
862
+ }
863
+
864
+ // Snapshot the config so the worker never reads fields configure() may change
865
+ // underneath it. The local model object itself stays shared, guarded by
866
+ // localMutex.
867
+ GenParams params;
868
+ params.backend = m_impl->backend;
869
+ params.serverUrl = m_impl->serverUrl;
870
+ params.model = m_impl->model;
871
+ params.messages = std::move(messages);
872
+ params.temperature = m_impl->temperature;
873
+ params.topP = m_impl->topP;
874
+ params.topK = m_impl->topK;
875
+ params.maxTokens = m_impl->maxTokens;
876
+ params.timeoutSec = m_impl->timeoutSec;
877
+ params.thinking = m_impl->thinking;
878
+ params.stream = m_impl->stream;
879
+
880
+ // The inference below runs for seconds; doing it here would block the thread
881
+ // that drives the pipeline (the App event loop / UI thread). Compute it in a
882
+ // worker instead and emit() the result when done — the same inversion of
883
+ // control a cache-miss uses — so the services after this one run then.
884
+ auto generate = [this, setStatus, fail, notifyText, params]() -> Data
885
+ {
886
+ const auto started = std::chrono::steady_clock::now();
887
+ json response;
888
+
889
+ if (params.backend == "local")
890
+ {
891
+ #ifdef HKP_LLAMA_ENABLED
892
+ // Held across ensure()+generate() so configure() cannot reload the model
893
+ // mid-decode (see configure()).
894
+ std::unique_lock<std::mutex> lock(m_impl->localMutex);
895
+ if (m_impl->local.modelPath.empty())
896
+ {
897
+ return fail("local backend needs a modelPath pointing to a .gguf file");
898
+ }
899
+
900
+ if (!m_impl->local.isLoaded())
901
+ {
902
+ setStatus("loading", "loading model '" + m_impl->local.modelPath + "'");
903
+ }
904
+ if (auto error = m_impl->local.ensure(); !error.empty())
905
+ {
906
+ return fail(error);
907
+ }
908
+
909
+ std::vector<ChatMessage> chat;
910
+ chat.reserve(params.messages.size());
911
+ for (const auto& message : params.messages)
912
+ {
913
+ chat.push_back({ message.value("role", std::string("user")),
914
+ message.value("content", std::string{}) });
915
+ }
916
+
917
+ auto rendered = m_impl->local.applyChatTemplate(chat);
918
+ if (rendered.empty())
919
+ {
920
+ return fail("failed to apply the model's chat template");
921
+ }
922
+
923
+ setStatus("generating");
924
+ auto generation = m_impl->local.generate(
925
+ rendered,
926
+ params.temperature,
927
+ params.topP,
928
+ params.topK,
929
+ params.maxTokens,
930
+ params.stream ? notifyText : std::function<void(const std::string&)>{}
931
+ );
932
+ const std::string modelId = m_impl->local.modelPath;
933
+ lock.unlock();
934
+
935
+ // A context overrun or decode failure still leaves usable text behind, so
936
+ // only a completely empty generation is treated as an error.
937
+ if (!generation.error.empty() && generation.text.empty())
938
+ {
939
+ return fail("generation failed: " + generation.error);
940
+ }
941
+ if (params.stream)
942
+ {
943
+ sendNotification(Data(json{ { "streamText", generation.text }, { "streamDone", true } }));
944
+ }
945
+
946
+ response = {
947
+ { "choices", json::array({ json{ { "message", json{ { "role", "assistant" },
948
+ { "content", generation.text } } } } }) },
949
+ { "model", modelId },
950
+ { "usage", json{ { "prompt_tokens", generation.promptTokens },
951
+ { "completion_tokens", generation.completionTokens } } }
952
+ };
953
+ #else
954
+ return fail(kBuildHint);
955
+ #endif
956
+ }
957
+ else
958
+ {
959
+ json payload = {
960
+ { "messages", params.messages },
961
+ { "temperature", params.temperature },
962
+ { "top_p", params.topP },
963
+ { "top_k", params.topK },
964
+ { "max_tokens", params.maxTokens },
965
+ { "stream", params.stream }
966
+ };
967
+ if (!params.model.empty())
968
+ {
969
+ payload["model"] = params.model;
970
+ }
971
+ if (params.thinking)
972
+ {
973
+ // llama-server extension (Qwen-style chat templates); only sent when
974
+ // explicitly configured so other backends never see the field.
975
+ payload["chat_template_kwargs"] = json{ { "enable_thinking", *params.thinking } };
976
+ }
977
+
978
+ setStatus("generating");
979
+ try
980
+ {
981
+ auto parsed = urls::parse_uri_reference(params.serverUrl);
982
+ if (parsed.has_error())
983
+ {
984
+ return fail("serverUrl is not a valid URL: " + params.serverUrl);
985
+ }
986
+ const auto url = parsed.value();
987
+ const auto host = std::string(url.encoded_host());
988
+ const bool isHttps = url.scheme_id() == urls::scheme::https;
989
+ auto port = url.port();
990
+ if (port.empty())
991
+ {
992
+ port = isHttps ? "443" : "80";
993
+ }
994
+ const auto target = std::string(url.encoded_path()) + "/v1/chat/completions";
995
+ const auto timeout = std::chrono::milliseconds(static_cast<long long>(params.timeoutSec * 1000));
996
+ const auto body = payload.dump();
997
+
998
+ net::io_context ioc;
999
+ tcp::resolver resolver(ioc);
1000
+ const auto endpoints = ::hkp::egress::resolve(resolver, host, port);
1001
+
1002
+ if (isHttps)
1003
+ {
1004
+ ssl::context ctx(ssl::context::tlsv12_client);
1005
+ load_root_certificates(ctx);
1006
+ ctx.set_verify_mode(ssl::verify_peer);
1007
+
1008
+ beast::ssl_stream<beast::tcp_stream> stream(ioc, ctx);
1009
+ if (!SSL_set_tlsext_host_name(stream.native_handle(), host.c_str()))
1010
+ {
1011
+ beast::error_code ec{ static_cast<int>(::ERR_get_error()), net::error::get_ssl_category() };
1012
+ throw beast::system_error{ ec };
1013
+ }
1014
+ beast::get_lowest_layer(stream).expires_after(timeout);
1015
+ beast::get_lowest_layer(stream).connect(endpoints);
1016
+ stream.handshake(ssl::stream_base::client);
1017
+ response = chatCompletion(stream, host, target, body, params.stream, notifyText);
1018
+
1019
+ beast::error_code ec;
1020
+ stream.shutdown(ec);
1021
+ }
1022
+ else
1023
+ {
1024
+ beast::tcp_stream stream(ioc);
1025
+ stream.expires_after(timeout);
1026
+ stream.connect(endpoints);
1027
+ response = chatCompletion(stream, host, target, body, params.stream, notifyText);
1028
+
1029
+ beast::error_code ec;
1030
+ stream.socket().shutdown(tcp::socket::shutdown_both, ec);
1031
+ }
1032
+ }
1033
+ catch (const ServerError& e)
1034
+ {
1035
+ // The server answered and said no; its message is the useful part.
1036
+ return fail(e.what());
1037
+ }
1038
+ catch (const ::hkp::egress::Refused& e)
1039
+ {
1040
+ // Refused here, not unreachable: telling the person to start a server
1041
+ // would be advice about the wrong problem.
1042
+ return fail(e.what());
1043
+ }
1044
+ catch (const std::exception&)
1045
+ {
1046
+ // Anything else is a transport failure — most often nothing listening.
1047
+ return fail(serverHint(params.serverUrl));
1048
+ }
1049
+
1050
+ if (params.stream)
1051
+ {
1052
+ std::string text;
1053
+ std::string thinking;
1054
+ if (response.contains("choices") && response["choices"].is_array() && !response["choices"].empty())
1055
+ {
1056
+ splitThinking(response["choices"][0]["message"], text, thinking);
1057
+ }
1058
+ sendNotification(Data(json{ { "streamText", text }, { "streamDone", true } }));
1059
+ }
1060
+ }
1061
+
1062
+ // ── Build the result ──────────────────────────────────────────────────────
1063
+ if (!response.contains("choices") || !response["choices"].is_array() || response["choices"].empty()
1064
+ || !response["choices"][0].contains("message"))
1065
+ {
1066
+ return fail("unexpected response shape: " + response.dump().substr(0, 200));
1067
+ }
1068
+
1069
+ std::string text;
1070
+ std::string thinking;
1071
+ splitThinking(response["choices"][0]["message"], text, thinking);
1072
+
1073
+ const auto usage = response.value("usage", json::object());
1074
+ const auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
1075
+ std::chrono::steady_clock::now() - started).count();
1076
+
1077
+ json result = {
1078
+ { "text", text },
1079
+ { "model", response.value("model", params.model) },
1080
+ { "durationMs", elapsed },
1081
+ { "usage", json{ { "promptTokens", usage.value("prompt_tokens", 0) },
1082
+ { "completionTokens", usage.value("completion_tokens", 0) } } }
1083
+ };
1084
+ if (!thinking.empty())
1085
+ {
1086
+ result["thinking"] = thinking;
1087
+ }
1088
+
1089
+ setStatus("idle");
1090
+ sendNotification(Data(result));
1091
+ return Data(result);
1092
+ };
1093
+
1094
+ // A previous worker may have finished but not been joined yet; reap it before
1095
+ // launching the next. The generating CAS above guarantees single ownership of
1096
+ // the thread handle at this point.
1097
+ if (m_impl->worker.joinable())
1098
+ {
1099
+ m_impl->worker.join();
1100
+ }
1101
+ // Capture this invocation before the worker can finish. The resulting token
1102
+ // is one-shot: its first emit() is the answer to this call.
1103
+ Data deferred = deferCompletion();
1104
+ m_impl->worker = std::thread([this, generate]()
1105
+ {
1106
+ try
1107
+ {
1108
+ Data out = generate();
1109
+ if (!isNull(out))
1110
+ {
1111
+ // Drive the services after this one with the finished result. This
1112
+ // starts a fresh pipeline traversal on the event loop.
1113
+ emit(out);
1114
+ }
1115
+ }
1116
+ catch (const std::exception& e)
1117
+ {
1118
+ std::cerr << "text-generation worker failed: " << e.what() << std::endl;
1119
+ }
1120
+ // Nothing to hand on, or it failed: the call is over all the same. Before
1121
+ // the next one may begin, so that it is this call that is ended.
1122
+ endDeferred();
1123
+ m_impl->generating = false;
1124
+ });
1125
+
1126
+ // Stop the synchronous push; the worker emit()s the result when it is ready,
1127
+ // which also closes this service's processing bracket (deferCompletion tells
1128
+ // the runtime to withhold the immediate "call-process-finished").
1129
+ return deferred;
1130
+ }
1131
+
1132
+ }