robopark 3.1.2 → 3.2.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 (312) hide show
  1. package/README.md +15 -5
  2. package/dist/robopark/frontend-service.js +80 -0
  3. package/dist/robopark/serve.js +2 -2
  4. package/dist/robopark/standalone.js +30 -8
  5. package/package.json +34 -3
  6. package/ui/ROBOVOICE_BUILD.json +9 -0
  7. package/ui/standalone/.next/BUILD_ID +1 -0
  8. package/ui/standalone/.next/app-build-manifest.json +391 -0
  9. package/ui/standalone/.next/app-path-routes-manifest.json +55 -0
  10. package/ui/standalone/.next/build-manifest.json +33 -0
  11. package/ui/standalone/.next/package.json +1 -0
  12. package/ui/standalone/.next/prerender-manifest.json +41 -0
  13. package/ui/standalone/.next/react-loadable-manifest.json +14 -0
  14. package/ui/standalone/.next/required-server-files.json +362 -0
  15. package/ui/standalone/.next/routes-manifest.json +246 -0
  16. package/ui/standalone/.next/server/app/(app)/opengraph-image-xg4ifa/route.js +1 -0
  17. package/ui/standalone/.next/server/app/(app)/opengraph-image-xg4ifa/route.js.nft.json +1 -0
  18. package/ui/standalone/.next/server/app/(app)/opengraph-image-xg4ifa/route_client-reference-manifest.js +1 -0
  19. package/ui/standalone/.next/server/app/(app)/page.js +2 -0
  20. package/ui/standalone/.next/server/app/(app)/page.js.nft.json +1 -0
  21. package/ui/standalone/.next/server/app/(app)/page_client-reference-manifest.js +1 -0
  22. package/ui/standalone/.next/server/app/(app)/voice/page.js +12 -0
  23. package/ui/standalone/.next/server/app/(app)/voice/page.js.nft.json +1 -0
  24. package/ui/standalone/.next/server/app/(app)/voice/page_client-reference-manifest.js +1 -0
  25. package/ui/standalone/.next/server/app/_not-found/page.js +12 -0
  26. package/ui/standalone/.next/server/app/_not-found/page.js.nft.json +1 -0
  27. package/ui/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
  28. package/ui/standalone/.next/server/app/api/connection-details/route.js +1 -0
  29. package/ui/standalone/.next/server/app/api/connection-details/route.js.nft.json +1 -0
  30. package/ui/standalone/.next/server/app/api/connection-details/route_client-reference-manifest.js +1 -0
  31. package/ui/standalone/.next/server/app/api/device-character/route.js +1 -0
  32. package/ui/standalone/.next/server/app/api/device-character/route.js.nft.json +1 -0
  33. package/ui/standalone/.next/server/app/api/device-character/route_client-reference-manifest.js +1 -0
  34. package/ui/standalone/.next/server/app/api/download-piper-model/route.js +1 -0
  35. package/ui/standalone/.next/server/app/api/download-piper-model/route.js.nft.json +1 -0
  36. package/ui/standalone/.next/server/app/api/download-piper-model/route_client-reference-manifest.js +1 -0
  37. package/ui/standalone/.next/server/app/api/model-status/route.js +1 -0
  38. package/ui/standalone/.next/server/app/api/model-status/route.js.nft.json +1 -0
  39. package/ui/standalone/.next/server/app/api/model-status/route_client-reference-manifest.js +1 -0
  40. package/ui/standalone/.next/server/app/api/models/route.js +1 -0
  41. package/ui/standalone/.next/server/app/api/models/route.js.nft.json +1 -0
  42. package/ui/standalone/.next/server/app/api/models/route_client-reference-manifest.js +1 -0
  43. package/ui/standalone/.next/server/app/api/prewarm/route.js +1 -0
  44. package/ui/standalone/.next/server/app/api/prewarm/route.js.nft.json +1 -0
  45. package/ui/standalone/.next/server/app/api/prewarm/route_client-reference-manifest.js +1 -0
  46. package/ui/standalone/.next/server/app/api/prompt/route.js +1 -0
  47. package/ui/standalone/.next/server/app/api/prompt/route.js.nft.json +1 -0
  48. package/ui/standalone/.next/server/app/api/prompt/route_client-reference-manifest.js +1 -0
  49. package/ui/standalone/.next/server/app/api/reload-tools/route.js +1 -0
  50. package/ui/standalone/.next/server/app/api/reload-tools/route.js.nft.json +1 -0
  51. package/ui/standalone/.next/server/app/api/reload-tools/route_client-reference-manifest.js +1 -0
  52. package/ui/standalone/.next/server/app/api/robopark/camera-token/route.js +1 -0
  53. package/ui/standalone/.next/server/app/api/robopark/camera-token/route.js.nft.json +1 -0
  54. package/ui/standalone/.next/server/app/api/robopark/camera-token/route_client-reference-manifest.js +1 -0
  55. package/ui/standalone/.next/server/app/api/robopark/character-ai/route.js +1 -0
  56. package/ui/standalone/.next/server/app/api/robopark/character-ai/route.js.nft.json +1 -0
  57. package/ui/standalone/.next/server/app/api/robopark/character-ai/route_client-reference-manifest.js +1 -0
  58. package/ui/standalone/.next/server/app/api/robopark/device-access/route.js +1 -0
  59. package/ui/standalone/.next/server/app/api/robopark/device-access/route.js.nft.json +1 -0
  60. package/ui/standalone/.next/server/app/api/robopark/device-access/route_client-reference-manifest.js +1 -0
  61. package/ui/standalone/.next/server/app/api/robopark/devices/[deviceId]/control/route.js +1 -0
  62. package/ui/standalone/.next/server/app/api/robopark/devices/[deviceId]/control/route.js.nft.json +1 -0
  63. package/ui/standalone/.next/server/app/api/robopark/devices/[deviceId]/control/route_client-reference-manifest.js +1 -0
  64. package/ui/standalone/.next/server/app/api/robopark/live-rooms/route.js +1 -0
  65. package/ui/standalone/.next/server/app/api/robopark/live-rooms/route.js.nft.json +1 -0
  66. package/ui/standalone/.next/server/app/api/robopark/live-rooms/route_client-reference-manifest.js +1 -0
  67. package/ui/standalone/.next/server/app/api/robopark/monitor-token/route.js +1 -0
  68. package/ui/standalone/.next/server/app/api/robopark/monitor-token/route.js.nft.json +1 -0
  69. package/ui/standalone/.next/server/app/api/robopark/monitor-token/route_client-reference-manifest.js +1 -0
  70. package/ui/standalone/.next/server/app/api/robopark/robots/[robotId]/operations/route.js +1 -0
  71. package/ui/standalone/.next/server/app/api/robopark/robots/[robotId]/operations/route.js.nft.json +1 -0
  72. package/ui/standalone/.next/server/app/api/robopark/robots/[robotId]/operations/route_client-reference-manifest.js +1 -0
  73. package/ui/standalone/.next/server/app/api/robopark/robots/[robotId]/voice-engine/route.js +1 -0
  74. package/ui/standalone/.next/server/app/api/robopark/robots/[robotId]/voice-engine/route.js.nft.json +1 -0
  75. package/ui/standalone/.next/server/app/api/robopark/robots/[robotId]/voice-engine/route_client-reference-manifest.js +1 -0
  76. package/ui/standalone/.next/server/app/api/robopark/robots/route.js +1 -0
  77. package/ui/standalone/.next/server/app/api/robopark/robots/route.js.nft.json +1 -0
  78. package/ui/standalone/.next/server/app/api/robopark/robots/route_client-reference-manifest.js +1 -0
  79. package/ui/standalone/.next/server/app/api/robopark/servers/[serverId]/metrics/route.js +1 -0
  80. package/ui/standalone/.next/server/app/api/robopark/servers/[serverId]/metrics/route.js.nft.json +1 -0
  81. package/ui/standalone/.next/server/app/api/robopark/servers/[serverId]/metrics/route_client-reference-manifest.js +1 -0
  82. package/ui/standalone/.next/server/app/api/robopark/servers/[serverId]/route.js +1 -0
  83. package/ui/standalone/.next/server/app/api/robopark/servers/[serverId]/route.js.nft.json +1 -0
  84. package/ui/standalone/.next/server/app/api/robopark/servers/[serverId]/route_client-reference-manifest.js +1 -0
  85. package/ui/standalone/.next/server/app/api/robopark/servers/route.js +1 -0
  86. package/ui/standalone/.next/server/app/api/robopark/servers/route.js.nft.json +1 -0
  87. package/ui/standalone/.next/server/app/api/robopark/servers/route_client-reference-manifest.js +1 -0
  88. package/ui/standalone/.next/server/app/api/robopark/sessions/[sessionId]/end/route.js +1 -0
  89. package/ui/standalone/.next/server/app/api/robopark/sessions/[sessionId]/end/route.js.nft.json +1 -0
  90. package/ui/standalone/.next/server/app/api/robopark/sessions/[sessionId]/end/route_client-reference-manifest.js +1 -0
  91. package/ui/standalone/.next/server/app/api/robopark/sessions/route.js +1 -0
  92. package/ui/standalone/.next/server/app/api/robopark/sessions/route.js.nft.json +1 -0
  93. package/ui/standalone/.next/server/app/api/robopark/sessions/route_client-reference-manifest.js +1 -0
  94. package/ui/standalone/.next/server/app/api/robopark/transcripts/[sessionId]/route.js +1 -0
  95. package/ui/standalone/.next/server/app/api/robopark/transcripts/[sessionId]/route.js.nft.json +1 -0
  96. package/ui/standalone/.next/server/app/api/robopark/transcripts/[sessionId]/route_client-reference-manifest.js +1 -0
  97. package/ui/standalone/.next/server/app/api/robopark/transcripts/route.js +1 -0
  98. package/ui/standalone/.next/server/app/api/robopark/transcripts/route.js.nft.json +1 -0
  99. package/ui/standalone/.next/server/app/api/robopark/transcripts/route_client-reference-manifest.js +1 -0
  100. package/ui/standalone/.next/server/app/api/robovoice/robots/[robotId]/media-health/route.js +1 -0
  101. package/ui/standalone/.next/server/app/api/robovoice/robots/[robotId]/media-health/route.js.nft.json +1 -0
  102. package/ui/standalone/.next/server/app/api/robovoice/robots/[robotId]/media-health/route_client-reference-manifest.js +1 -0
  103. package/ui/standalone/.next/server/app/api/settings/route.js +1 -0
  104. package/ui/standalone/.next/server/app/api/settings/route.js.nft.json +1 -0
  105. package/ui/standalone/.next/server/app/api/settings/route_client-reference-manifest.js +1 -0
  106. package/ui/standalone/.next/server/app/api/setup/complete/route.js +1 -0
  107. package/ui/standalone/.next/server/app/api/setup/complete/route.js.nft.json +1 -0
  108. package/ui/standalone/.next/server/app/api/setup/complete/route_client-reference-manifest.js +1 -0
  109. package/ui/standalone/.next/server/app/api/setup/status/route.js +1 -0
  110. package/ui/standalone/.next/server/app/api/setup/status/route.js.nft.json +1 -0
  111. package/ui/standalone/.next/server/app/api/setup/status/route_client-reference-manifest.js +1 -0
  112. package/ui/standalone/.next/server/app/api/setup/test-groq/route.js +1 -0
  113. package/ui/standalone/.next/server/app/api/setup/test-groq/route.js.nft.json +1 -0
  114. package/ui/standalone/.next/server/app/api/setup/test-groq/route_client-reference-manifest.js +1 -0
  115. package/ui/standalone/.next/server/app/api/setup/test-hass/route.js +1 -0
  116. package/ui/standalone/.next/server/app/api/setup/test-hass/route.js.nft.json +1 -0
  117. package/ui/standalone/.next/server/app/api/setup/test-hass/route_client-reference-manifest.js +1 -0
  118. package/ui/standalone/.next/server/app/api/setup/test-n8n/route.js +1 -0
  119. package/ui/standalone/.next/server/app/api/setup/test-n8n/route.js.nft.json +1 -0
  120. package/ui/standalone/.next/server/app/api/setup/test-n8n/route_client-reference-manifest.js +1 -0
  121. package/ui/standalone/.next/server/app/api/setup/test-ollama/route.js +1 -0
  122. package/ui/standalone/.next/server/app/api/setup/test-ollama/route.js.nft.json +1 -0
  123. package/ui/standalone/.next/server/app/api/setup/test-ollama/route_client-reference-manifest.js +1 -0
  124. package/ui/standalone/.next/server/app/api/test-tts/route.js +1 -0
  125. package/ui/standalone/.next/server/app/api/test-tts/route.js.nft.json +1 -0
  126. package/ui/standalone/.next/server/app/api/test-tts/route_client-reference-manifest.js +1 -0
  127. package/ui/standalone/.next/server/app/api/turn-credentials/route.js +1 -0
  128. package/ui/standalone/.next/server/app/api/turn-credentials/route.js.nft.json +1 -0
  129. package/ui/standalone/.next/server/app/api/turn-credentials/route_client-reference-manifest.js +1 -0
  130. package/ui/standalone/.next/server/app/api/voices/route.js +1 -0
  131. package/ui/standalone/.next/server/app/api/voices/route.js.nft.json +1 -0
  132. package/ui/standalone/.next/server/app/api/voices/route_client-reference-manifest.js +1 -0
  133. package/ui/standalone/.next/server/app/api/wake/route.js +1 -0
  134. package/ui/standalone/.next/server/app/api/wake/route.js.nft.json +1 -0
  135. package/ui/standalone/.next/server/app/api/wake/route_client-reference-manifest.js +1 -0
  136. package/ui/standalone/.next/server/app/api/wake-word/models/route.js +1 -0
  137. package/ui/standalone/.next/server/app/api/wake-word/models/route.js.nft.json +1 -0
  138. package/ui/standalone/.next/server/app/api/wake-word/models/route_client-reference-manifest.js +1 -0
  139. package/ui/standalone/.next/server/app/api/wake-word/status/route.js +1 -0
  140. package/ui/standalone/.next/server/app/api/wake-word/status/route.js.nft.json +1 -0
  141. package/ui/standalone/.next/server/app/api/wake-word/status/route_client-reference-manifest.js +1 -0
  142. package/ui/standalone/.next/server/app/api/wake-word/upload/route.js +1 -0
  143. package/ui/standalone/.next/server/app/api/wake-word/upload/route.js.nft.json +1 -0
  144. package/ui/standalone/.next/server/app/api/wake-word/upload/route_client-reference-manifest.js +1 -0
  145. package/ui/standalone/.next/server/app/favicon.ico/route.js +1 -0
  146. package/ui/standalone/.next/server/app/favicon.ico/route.js.nft.json +1 -0
  147. package/ui/standalone/.next/server/app/favicon.ico.body +0 -0
  148. package/ui/standalone/.next/server/app/favicon.ico.meta +1 -0
  149. package/ui/standalone/.next/server/app/fed/[...path]/route.js +4 -0
  150. package/ui/standalone/.next/server/app/fed/[...path]/route.js.nft.json +1 -0
  151. package/ui/standalone/.next/server/app/fed/[...path]/route_client-reference-manifest.js +1 -0
  152. package/ui/standalone/.next/server/app/fed/media/robots/[robotId]/video_feed/route.js +1 -0
  153. package/ui/standalone/.next/server/app/fed/media/robots/[robotId]/video_feed/route.js.nft.json +1 -0
  154. package/ui/standalone/.next/server/app/fed/media/robots/[robotId]/video_feed/route_client-reference-manifest.js +1 -0
  155. package/ui/standalone/.next/server/app/robopark/[...path]/route.js +1 -0
  156. package/ui/standalone/.next/server/app/robopark/[...path]/route.js.nft.json +1 -0
  157. package/ui/standalone/.next/server/app/robopark/[...path]/route_client-reference-manifest.js +1 -0
  158. package/ui/standalone/.next/server/app/robopark/api/[...path]/route.js +1 -0
  159. package/ui/standalone/.next/server/app/robopark/api/[...path]/route.js.nft.json +1 -0
  160. package/ui/standalone/.next/server/app/robopark/api/[...path]/route_client-reference-manifest.js +1 -0
  161. package/ui/standalone/.next/server/app/robopark/api/robots/[robotId]/stream/route.js +1 -0
  162. package/ui/standalone/.next/server/app/robopark/api/robots/[robotId]/stream/route.js.nft.json +1 -0
  163. package/ui/standalone/.next/server/app/robopark/api/robots/[robotId]/stream/route_client-reference-manifest.js +1 -0
  164. package/ui/standalone/.next/server/app/robopark/page.js +2 -0
  165. package/ui/standalone/.next/server/app/robopark/page.js.nft.json +1 -0
  166. package/ui/standalone/.next/server/app/robopark/page_client-reference-manifest.js +1 -0
  167. package/ui/standalone/.next/server/app/tailnet/route.js +1 -0
  168. package/ui/standalone/.next/server/app/tailnet/route.js.nft.json +1 -0
  169. package/ui/standalone/.next/server/app/tailnet/route_client-reference-manifest.js +1 -0
  170. package/ui/standalone/.next/server/app/vendor/livekit-client.umd.js/route.js +1 -0
  171. package/ui/standalone/.next/server/app/vendor/livekit-client.umd.js/route.js.nft.json +1 -0
  172. package/ui/standalone/.next/server/app/vendor/livekit-client.umd.js/route_client-reference-manifest.js +1 -0
  173. package/ui/standalone/.next/server/app/voice-tester/page.js +2 -0
  174. package/ui/standalone/.next/server/app/voice-tester/page.js.nft.json +1 -0
  175. package/ui/standalone/.next/server/app/voice-tester/page_client-reference-manifest.js +1 -0
  176. package/ui/standalone/.next/server/app-paths-manifest.json +55 -0
  177. package/ui/standalone/.next/server/chunks/1428.js +1 -0
  178. package/ui/standalone/.next/server/chunks/1692.js +1 -0
  179. package/ui/standalone/.next/server/chunks/37.js +1 -0
  180. package/ui/standalone/.next/server/chunks/4876.js +1 -0
  181. package/ui/standalone/.next/server/chunks/5232.js +9 -0
  182. package/ui/standalone/.next/server/chunks/5455.js +11 -0
  183. package/ui/standalone/.next/server/chunks/5611.js +6 -0
  184. package/ui/standalone/.next/server/chunks/5873.js +22 -0
  185. package/ui/standalone/.next/server/chunks/6018.js +1 -0
  186. package/ui/standalone/.next/server/chunks/8755.js +1 -0
  187. package/ui/standalone/.next/server/chunks/9077.js +11 -0
  188. package/ui/standalone/.next/server/functions-config-manifest.json +9 -0
  189. package/ui/standalone/.next/server/middleware-build-manifest.js +1 -0
  190. package/ui/standalone/.next/server/middleware-manifest.json +6 -0
  191. package/ui/standalone/.next/server/middleware-react-loadable-manifest.js +1 -0
  192. package/ui/standalone/.next/server/next-font-manifest.js +1 -0
  193. package/ui/standalone/.next/server/next-font-manifest.json +1 -0
  194. package/ui/standalone/.next/server/pages/500.html +1 -0
  195. package/ui/standalone/.next/server/pages/_app.js +1 -0
  196. package/ui/standalone/.next/server/pages/_app.js.nft.json +1 -0
  197. package/ui/standalone/.next/server/pages/_document.js +1 -0
  198. package/ui/standalone/.next/server/pages/_document.js.nft.json +1 -0
  199. package/ui/standalone/.next/server/pages/_error.js +19 -0
  200. package/ui/standalone/.next/server/pages/_error.js.nft.json +1 -0
  201. package/ui/standalone/.next/server/pages-manifest.json +5 -0
  202. package/ui/standalone/.next/server/server-reference-manifest.js +1 -0
  203. package/ui/standalone/.next/server/server-reference-manifest.json +1 -0
  204. package/ui/standalone/.next/server/webpack-runtime.js +1 -0
  205. package/ui/standalone/.next/static/T3eGaQUuZNb6rhEStcouc/_buildManifest.js +1 -0
  206. package/ui/standalone/.next/static/T3eGaQUuZNb6rhEStcouc/_ssgManifest.js +1 -0
  207. package/ui/standalone/.next/static/chunks/1255-404bb8de49c90395.js +1 -0
  208. package/ui/standalone/.next/static/chunks/144d3bae-bd5d150c0cab972e.js +1 -0
  209. package/ui/standalone/.next/static/chunks/1646.9123ee47220ed70b.js +1 -0
  210. package/ui/standalone/.next/static/chunks/2333-43c39acb531f7d4e.js +3 -0
  211. package/ui/standalone/.next/static/chunks/4bd1b696-f785427dddbba9fb.js +1 -0
  212. package/ui/standalone/.next/static/chunks/5139.c5e46d26064a85db.js +1 -0
  213. package/ui/standalone/.next/static/chunks/76e8f37e-2ae0e3fe7b44d874.js +1 -0
  214. package/ui/standalone/.next/static/chunks/9880-53262785284464cc.js +1 -0
  215. package/ui/standalone/.next/static/chunks/adfb71a7-625c1b5ebd039b6a.js +1 -0
  216. package/ui/standalone/.next/static/chunks/app/(app)/layout-5f312b128a0caf75.js +1 -0
  217. package/ui/standalone/.next/static/chunks/app/(app)/opengraph-image-xg4ifa/route-5f312b128a0caf75.js +1 -0
  218. package/ui/standalone/.next/static/chunks/app/(app)/page-5f312b128a0caf75.js +1 -0
  219. package/ui/standalone/.next/static/chunks/app/(app)/voice/page-72d72d9a70d9c1d4.js +1 -0
  220. package/ui/standalone/.next/static/chunks/app/_not-found/page-cfd7daa82d71540c.js +1 -0
  221. package/ui/standalone/.next/static/chunks/app/api/connection-details/route-5f312b128a0caf75.js +1 -0
  222. package/ui/standalone/.next/static/chunks/app/api/device-character/route-5f312b128a0caf75.js +1 -0
  223. package/ui/standalone/.next/static/chunks/app/api/download-piper-model/route-5f312b128a0caf75.js +1 -0
  224. package/ui/standalone/.next/static/chunks/app/api/model-status/route-5f312b128a0caf75.js +1 -0
  225. package/ui/standalone/.next/static/chunks/app/api/models/route-5f312b128a0caf75.js +1 -0
  226. package/ui/standalone/.next/static/chunks/app/api/prewarm/route-5f312b128a0caf75.js +1 -0
  227. package/ui/standalone/.next/static/chunks/app/api/prompt/route-5f312b128a0caf75.js +1 -0
  228. package/ui/standalone/.next/static/chunks/app/api/reload-tools/route-5f312b128a0caf75.js +1 -0
  229. package/ui/standalone/.next/static/chunks/app/api/robopark/camera-token/route-5f312b128a0caf75.js +1 -0
  230. package/ui/standalone/.next/static/chunks/app/api/robopark/character-ai/route-5f312b128a0caf75.js +1 -0
  231. package/ui/standalone/.next/static/chunks/app/api/robopark/device-access/route-5f312b128a0caf75.js +1 -0
  232. package/ui/standalone/.next/static/chunks/app/api/robopark/devices/[deviceId]/control/route-5f312b128a0caf75.js +1 -0
  233. package/ui/standalone/.next/static/chunks/app/api/robopark/live-rooms/route-5f312b128a0caf75.js +1 -0
  234. package/ui/standalone/.next/static/chunks/app/api/robopark/monitor-token/route-5f312b128a0caf75.js +1 -0
  235. package/ui/standalone/.next/static/chunks/app/api/robopark/robots/[robotId]/operations/route-5f312b128a0caf75.js +1 -0
  236. package/ui/standalone/.next/static/chunks/app/api/robopark/robots/[robotId]/voice-engine/route-5f312b128a0caf75.js +1 -0
  237. package/ui/standalone/.next/static/chunks/app/api/robopark/robots/route-5f312b128a0caf75.js +1 -0
  238. package/ui/standalone/.next/static/chunks/app/api/robopark/servers/[serverId]/metrics/route-5f312b128a0caf75.js +1 -0
  239. package/ui/standalone/.next/static/chunks/app/api/robopark/servers/[serverId]/route-5f312b128a0caf75.js +1 -0
  240. package/ui/standalone/.next/static/chunks/app/api/robopark/servers/route-5f312b128a0caf75.js +1 -0
  241. package/ui/standalone/.next/static/chunks/app/api/robopark/sessions/[sessionId]/end/route-5f312b128a0caf75.js +1 -0
  242. package/ui/standalone/.next/static/chunks/app/api/robopark/sessions/route-5f312b128a0caf75.js +1 -0
  243. package/ui/standalone/.next/static/chunks/app/api/robopark/transcripts/[sessionId]/route-5f312b128a0caf75.js +1 -0
  244. package/ui/standalone/.next/static/chunks/app/api/robopark/transcripts/route-5f312b128a0caf75.js +1 -0
  245. package/ui/standalone/.next/static/chunks/app/api/robovoice/robots/[robotId]/media-health/route-5f312b128a0caf75.js +1 -0
  246. package/ui/standalone/.next/static/chunks/app/api/settings/route-5f312b128a0caf75.js +1 -0
  247. package/ui/standalone/.next/static/chunks/app/api/setup/complete/route-5f312b128a0caf75.js +1 -0
  248. package/ui/standalone/.next/static/chunks/app/api/setup/status/route-5f312b128a0caf75.js +1 -0
  249. package/ui/standalone/.next/static/chunks/app/api/setup/test-groq/route-5f312b128a0caf75.js +1 -0
  250. package/ui/standalone/.next/static/chunks/app/api/setup/test-hass/route-5f312b128a0caf75.js +1 -0
  251. package/ui/standalone/.next/static/chunks/app/api/setup/test-n8n/route-5f312b128a0caf75.js +1 -0
  252. package/ui/standalone/.next/static/chunks/app/api/setup/test-ollama/route-5f312b128a0caf75.js +1 -0
  253. package/ui/standalone/.next/static/chunks/app/api/test-tts/route-5f312b128a0caf75.js +1 -0
  254. package/ui/standalone/.next/static/chunks/app/api/turn-credentials/route-5f312b128a0caf75.js +1 -0
  255. package/ui/standalone/.next/static/chunks/app/api/voices/route-5f312b128a0caf75.js +1 -0
  256. package/ui/standalone/.next/static/chunks/app/api/wake/route-5f312b128a0caf75.js +1 -0
  257. package/ui/standalone/.next/static/chunks/app/api/wake-word/models/route-5f312b128a0caf75.js +1 -0
  258. package/ui/standalone/.next/static/chunks/app/api/wake-word/status/route-5f312b128a0caf75.js +1 -0
  259. package/ui/standalone/.next/static/chunks/app/api/wake-word/upload/route-5f312b128a0caf75.js +1 -0
  260. package/ui/standalone/.next/static/chunks/app/fed/[...path]/route-5f312b128a0caf75.js +1 -0
  261. package/ui/standalone/.next/static/chunks/app/fed/media/robots/[robotId]/video_feed/route-5f312b128a0caf75.js +1 -0
  262. package/ui/standalone/.next/static/chunks/app/layout-fcce963da1d8220f.js +1 -0
  263. package/ui/standalone/.next/static/chunks/app/robopark/[...path]/route-5f312b128a0caf75.js +1 -0
  264. package/ui/standalone/.next/static/chunks/app/robopark/api/[...path]/route-5f312b128a0caf75.js +1 -0
  265. package/ui/standalone/.next/static/chunks/app/robopark/api/robots/[robotId]/stream/route-5f312b128a0caf75.js +1 -0
  266. package/ui/standalone/.next/static/chunks/app/robopark/page-5f312b128a0caf75.js +1 -0
  267. package/ui/standalone/.next/static/chunks/app/tailnet/route-5f312b128a0caf75.js +1 -0
  268. package/ui/standalone/.next/static/chunks/app/vendor/livekit-client.umd.js/route-5f312b128a0caf75.js +1 -0
  269. package/ui/standalone/.next/static/chunks/app/voice-tester/page-ae699e048e0eb834.js +1 -0
  270. package/ui/standalone/.next/static/chunks/framework-e60c938074ff7136.js +1 -0
  271. package/ui/standalone/.next/static/chunks/main-9e24e8708ff075fc.js +1 -0
  272. package/ui/standalone/.next/static/chunks/main-app-a1f59168303c7f84.js +1 -0
  273. package/ui/standalone/.next/static/chunks/pages/_app-131c90850aef965b.js +1 -0
  274. package/ui/standalone/.next/static/chunks/pages/_error-e4ba546eb376bdf4.js +1 -0
  275. package/ui/standalone/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  276. package/ui/standalone/.next/static/chunks/webpack-5252e5254da079b5.js +1 -0
  277. package/ui/standalone/.next/static/css/3f478a573f9be82e.css +1 -0
  278. package/ui/standalone/.next/static/css/51560c4af1d5a21f.css +1 -0
  279. package/ui/standalone/.next/static/media/27fe93087559d480-s.p.otf +0 -0
  280. package/ui/standalone/.next/static/media/4d3869dd8a56345a-s.p.otf +0 -0
  281. package/ui/standalone/.next/static/media/63f3bb9ce29e22d5-s.p.otf +0 -0
  282. package/ui/standalone/.next/static/media/79e1c5d0f2fe9f68-s.p.otf +0 -0
  283. package/ui/standalone/.next/static/media/8bf7b2ceda89477b-s.p.woff2 +0 -0
  284. package/ui/standalone/.next/static/media/98baa4a7809fbf72-s.woff2 +0 -0
  285. package/ui/standalone/.next/static/media/f7650dfaa438c37c-s.woff2 +0 -0
  286. package/ui/standalone/package.json +57 -0
  287. package/ui/standalone/public/caal-logo.svg +3 -0
  288. package/ui/standalone/public/commit-mono-400-regular.woff +0 -0
  289. package/ui/standalone/public/cwl-logo-round.png +0 -0
  290. package/ui/standalone/public/everett-light.woff +0 -0
  291. package/ui/standalone/public/hey_cal.ppn +0 -0
  292. package/ui/standalone/public/install-robot-kiosk.sh +242 -0
  293. package/ui/standalone/public/lk-logo-dark.svg +18 -0
  294. package/ui/standalone/public/lk-logo.svg +18 -0
  295. package/ui/standalone/public/lk-wordmark.svg +12 -0
  296. package/ui/standalone/public/opengraph-image-bg.png +0 -0
  297. package/ui/standalone/public/porcupine_params.pv +0 -0
  298. package/ui/standalone/public/robopark-control.html +9200 -0
  299. package/ui/standalone/public/static/robopark/barracuda.png +0 -0
  300. package/ui/standalone/public/static/robopark/bmw.png +0 -0
  301. package/ui/standalone/public/static/robopark/jaguar.png +0 -0
  302. package/ui/standalone/public/static/robopark/magnus.jpg +0 -0
  303. package/ui/standalone/public/static/robopark/panda.png +0 -0
  304. package/ui/standalone/public/static/robopark/tesla.png +0 -0
  305. package/ui/standalone/public/static/robopark/titan.jpg +0 -0
  306. package/ui/standalone/public/static/robopark/volt.png +0 -0
  307. package/ui/standalone/public/tailnet/index.html +8995 -0
  308. package/ui/standalone/public/transcript-analytics.html +72 -0
  309. package/ui/standalone/public/vendor/elevenlabs-client.iife.js +24200 -0
  310. package/ui/standalone/public/vendor/livekit-client.umd.js +2 -0
  311. package/ui/standalone/public/voice-join.html +89 -0
  312. package/ui/standalone/server.js +38 -0
@@ -0,0 +1,89 @@
1
+ <!doctype html>
2
+ <html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
3
+ <meta name="theme-color" content="#080704"><meta name="robopark-voice-join-build" content="production-native-microphone-20260725-8">
4
+ <title>RoboPark Character Conversation</title>
5
+ <style>
6
+ .deployment{display:grid;gap:8px;margin:14px 0}.deployment-row{display:grid;grid-template-columns:minmax(150px,1fr) 2fr auto;gap:9px;align-items:center;padding:.7rem;border:1px solid var(--line);border-radius:12px;background:rgba(255,255,255,.025)}.deployment-row b{font:.62rem var(--mono);color:var(--pale)}.deployment-row span{font:.54rem var(--mono);color:var(--muted)}.deployment-row .ready{color:var(--ok)}.deployment-actions{display:flex;flex-wrap:wrap;gap:5px}.deployment-actions button{border:1px solid var(--line);border-radius:8px;background:rgba(244,207,114,.09);color:var(--gold);padding:.38rem .5rem;font:.5rem var(--mono);cursor:pointer}
7
+ .audio-controls,.call-controls{position:relative;width:min(440px,94%);margin-top:12px;border:1px solid var(--line);border-radius:14px;background:rgba(0,0,0,.3);text-align:left}.audio-controls summary,.call-controls summary{padding:.65rem .8rem;cursor:pointer;color:var(--gold);font:600 .58rem var(--mono);letter-spacing:.07em;text-transform:uppercase}.audio-controls summary::marker,.call-controls summary::marker{color:var(--gold)}.audio-panel,.call-panel{display:grid;gap:.75rem;padding:0 .85rem .85rem}.audio-row{display:grid;grid-template-columns:105px 1fr 45px;gap:.55rem;align-items:center}.audio-row label,.audio-value,.call-row label{font:600 .54rem var(--mono);color:var(--muted)}.audio-value{text-align:right;color:var(--pale)}.audio-row input[type=range]{width:100%;accent-color:var(--gold)}.audio-note,.call-note{margin:0;color:#7e755f;font:.5rem/1.45 var(--mono)}.call-row{display:grid;gap:.3rem}.call-row select{width:100%;min-width:0;border:1px solid var(--line);border-radius:9px;background:#090805;color:var(--ink);padding:.52rem;font:600 .55rem var(--mono)}.call-actions{display:grid;grid-template-columns:1fr 1fr;gap:7px}.call-actions button{border:1px solid var(--line);border-radius:9px;background:rgba(244,207,114,.1);color:var(--gold);padding:.52rem;font:600 .52rem var(--mono);cursor:pointer}.call-actions button.primary{background:linear-gradient(135deg,#f5d77f,#b87b1d);color:#171005}.call-status.ok{color:var(--ok)}.call-status.bad{color:var(--bad)}.mode-badge{display:inline-flex;align-items:center;gap:.35rem;padding:.28rem .48rem;border:1px solid var(--line);border-radius:999px;color:var(--muted);font:600 .5rem var(--mono)}.mode-badge.production{color:var(--ok);border-color:rgba(100,223,160,.4)}
8
+ :root{--bg:#080704;--panel:rgba(20,17,11,.88);--line:rgba(247,211,116,.22);--gold:#f4cf72;--pale:#fff0bd;--ink:#f7f1df;--muted:#a99e84;--ok:#64dfa0;--warn:#f0bd55;--bad:#ff776c;--mono:"JetBrains Mono","Cascadia Code",monospace;--display:Georgia,"Times New Roman",serif}*{box-sizing:border-box}html,body{margin:0;min-height:100%;background:radial-gradient(circle at 50% 8%,#332510 0,#100d08 35%,#050403 78%);color:var(--ink);font-family:Verdana,Geneva,sans-serif}body:before{content:"";position:fixed;inset:0;pointer-events:none;background:linear-gradient(115deg,transparent 0 48%,rgba(244,207,114,.025) 49% 50%,transparent 51%),repeating-linear-gradient(0deg,transparent 0 34px,rgba(255,255,255,.012) 35px)}button,input{font:inherit}.shell{width:min(1120px,100%);min-height:100vh;margin:auto;padding:clamp(14px,3vw,34px);display:grid;grid-template-rows:auto 1fr auto;gap:18px}.top{display:flex;align-items:center;justify-content:space-between;gap:16px}.brand{font:700 .65rem var(--mono);letter-spacing:.18em;text-transform:uppercase;color:var(--gold)}.ops-toggle{border:1px solid var(--line);border-radius:999px;background:rgba(0,0,0,.35);color:var(--muted);padding:.55rem .8rem;cursor:pointer}.ops-toggle.on{color:var(--pale);border-color:var(--gold)}.stage{position:relative;min-height:620px;display:grid;grid-template-columns:minmax(0,1.3fr) minmax(280px,.7fr);overflow:hidden;border:1px solid var(--line);border-radius:28px;background:linear-gradient(145deg,rgba(34,27,14,.82),rgba(8,7,5,.92));box-shadow:0 28px 90px rgba(0,0,0,.45)}.hero{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:34px;text-align:center;overflow:hidden}.hero:before{content:"";position:absolute;width:500px;height:500px;border:1px solid rgba(244,207,114,.1);border-radius:50%;box-shadow:0 0 0 55px rgba(244,207,114,.018),0 0 0 120px rgba(244,207,114,.012)}.avatar-wrap{position:relative;width:min(330px,72vw);aspect-ratio:1;display:grid;place-items:center;border:1px solid rgba(244,207,114,.3);border-radius:50%;background:radial-gradient(circle,rgba(244,207,114,.16),rgba(8,7,5,.62) 58%,#050403 74%);box-shadow:0 0 90px rgba(214,164,55,.16)}.avatar-wrap.live{animation:breathe 2.2s ease-in-out infinite}.avatar-wrap.speaking{box-shadow:0 0 110px rgba(244,207,114,.42);border-color:var(--pale)}@keyframes breathe{50%{transform:scale(1.018)}}.avatar{position:relative;z-index:2;width:78%;height:78%;object-fit:contain;filter:drop-shadow(0 20px 28px rgba(0,0,0,.58))}.fallback{position:absolute;font:700 4rem var(--display);color:var(--gold)}h1{position:relative;margin:22px 0 5px;font:700 clamp(2rem,5vw,3.5rem) var(--display);color:var(--pale)}.subtitle{position:relative;color:var(--muted);font-size:.8rem}.state{position:relative;margin-top:14px;font:600 .68rem var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--gold)}.join{position:relative;margin-top:22px;min-width:210px;border:1px solid var(--gold);border-radius:999px;padding:.9rem 1.25rem;background:linear-gradient(135deg,#f5d77f,#b87b1d);color:#171005;font-weight:800;cursor:pointer;box-shadow:0 12px 30px rgba(184,123,29,.24)}.join:disabled{opacity:.48;cursor:not-allowed}.end{position:relative;margin-top:10px;border:0;background:transparent;color:var(--muted);cursor:pointer}.side{position:relative;border-left:1px solid var(--line);padding:25px;display:flex;flex-direction:column;gap:14px;background:rgba(0,0,0,.2)}.vision{position:relative;aspect-ratio:16/10;border:1px solid var(--line);border-radius:17px;overflow:hidden;background:#050403}.vision img{width:100%;height:100%;object-fit:cover}.vision .label{position:absolute;left:9px;top:9px;padding:.32rem .45rem;border-radius:7px;background:rgba(0,0,0,.7);font:600 .5rem var(--mono);color:var(--gold)}.transcript{flex:1;min-height:220px;max-height:360px;overflow:auto;padding:.65rem;border:1px solid var(--line);border-radius:15px;background:rgba(0,0,0,.22)}.turn{margin:.45rem 0;padding:.55rem .65rem;border-radius:11px;font-size:.75rem;line-height:1.45}.turn.user{margin-left:13%;background:rgba(244,207,114,.12);border:1px solid rgba(244,207,114,.18)}.turn.assistant{margin-right:13%;background:rgba(255,255,255,.045)}.compose{display:flex;gap:8px}.compose input{min-width:0;flex:1;border:1px solid var(--line);border-radius:11px;background:#090805;color:var(--ink);padding:.7rem}.compose button{border:1px solid var(--line);border-radius:11px;background:rgba(244,207,114,.12);color:var(--gold);padding:.7rem;cursor:pointer}.ops{display:none;position:absolute;inset:12px;z-index:8;padding:16px;border:1px solid rgba(244,207,114,.35);border-radius:18px;background:rgba(5,4,3,.94);backdrop-filter:blur(16px);overflow:auto}.ops.open{display:block}.ops-head{display:flex;align-items:center;justify-content:space-between}.ops h2{margin:0;font:700 1.2rem var(--display);color:var(--pale)}.close{border:1px solid var(--line);border-radius:9px;background:transparent;color:var(--muted);padding:.4rem .55rem;cursor:pointer}.facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:8px;margin:14px 0}.fact{padding:.7rem;border:1px solid var(--line);border-radius:12px;background:rgba(255,255,255,.025)}.fact span{display:block;color:var(--muted);font:500 .49rem var(--mono);text-transform:uppercase;letter-spacing:.11em}.fact b{display:block;margin-top:.3rem;color:var(--ink);font:600 .64rem var(--mono);word-break:break-all}.pipeline{display:grid;grid-template-columns:repeat(5,1fr);gap:7px;margin:15px 0}.step{padding:.65rem .3rem;border:1px solid var(--line);border-radius:11px;text-align:center;color:var(--muted);font:600 .52rem var(--mono);text-transform:uppercase}.step.done{color:var(--ok);border-color:rgba(100,223,160,.4)}.step.live{color:#171005;border-color:var(--gold);background:var(--gold);box-shadow:0 0 24px rgba(244,207,114,.25)}.step.bad{color:var(--bad);border-color:rgba(255,119,108,.5)}.events{display:grid;gap:7px}.event{display:grid;grid-template-columns:95px 70px 1fr;gap:8px;padding:.6rem;border-bottom:1px solid var(--line);font:500 .55rem var(--mono)}.event .ok{color:var(--ok)}.event .error,.event .failed{color:var(--bad)}.foot{text-align:center;color:#716956;font:500 .52rem var(--mono);letter-spacing:.08em}.error-box{display:none;margin-top:12px;color:var(--bad);font:.65rem var(--mono)}@media(max-width:780px){.shell{padding:10px}.stage{grid-template-columns:1fr;min-height:0}.hero{min-height:600px;padding:24px 15px}.side{border-left:0;border-top:1px solid var(--line)}.pipeline{grid-template-columns:1fr 1fr}.top{padding:4px}.event{grid-template-columns:75px 55px 1fr}}
9
+ </style></head><body><main class="shell"><header class="top"><div class="brand">RoboPark / managed character channel</div><div><button class="ops-toggle on" id="always-on" aria-pressed="true" hidden>Always on: ON</button> <button class="ops-toggle" id="ops-toggle">Operations</button></div></header><section class="stage"><div class="hero"><div class="avatar-wrap" id="avatar-wrap"><div class="fallback" id="fallback">RP</div><img class="avatar" id="avatar" alt=""></div><h1 id="character-name">Loading character...</h1><div class="subtitle" id="subtitle">Secure ElevenLabs conversation managed by RoboPark</div><div class="state" id="state">validating link</div><button class="join" id="join" disabled>Join conversation</button><button class="end" id="end" hidden>End conversation</button><div class="error-box" id="error"></div></div><aside class="side"><div class="vision" id="vision" hidden><img id="robot-video" alt="Live robot camera"><span class="label">LIVE ROBOT VISION</span></div><div class="transcript" id="transcript"><div class="turn assistant">The transcript will appear here when the conversation begins.</div></div><form class="compose" id="compose"><input id="message" placeholder="Type a message" disabled><button id="send" disabled>Send</button></form></aside><section class="ops" id="ops"><div class="ops-head"><h2>Live management overlay</h2><button class="close" id="ops-close">Close</button></div><div class="facts"><div class="fact"><span>Session</span><b id="f-session">not started</b></div><div class="fact"><span>Character</span><b id="f-character">--</b></div><div class="fact"><span>Agent</span><b id="f-agent">--</b></div><div class="fact"><span>Branch</span><b id="f-branch">default</b></div><div class="fact"><span>Robot</span><b id="f-robot">operator only</b></div><div class="fact"><span>Share link</span><b id="f-share">--</b></div></div><div class="pipeline" id="pipeline"><div class="step live" data-stage="configured">configured</div><div class="step" data-stage="permission">permission</div><div class="step" data-stage="signed_session">signed</div><div class="step" data-stage="connected">connected</div><div class="step" data-stage="conversation">conversation</div></div><div class="events" id="events"><div class="event"><span>waiting</span><span>info</span><span>Session telemetry will stream here.</span></div></div></section></section><footer class="foot">No API credentials are stored in this link. Each visit creates an isolated signed session.</footer></main><script src="/vendor/elevenlabs-client.iife.js"></script><script>
10
+ (function(){
11
+ var deployment=document.createElement('div');deployment.id='deployment';deployment.className='deployment';deployment.innerHTML='<div class="deployment-row"><b>Character hardware</b><span>Loading registered voice, vision, and motor nodes...</span><span></span></div>';document.getElementById('pipeline').before(deployment);
12
+ var audioControls=document.createElement('details');audioControls.id='audio-controls';audioControls.className='audio-controls';audioControls.innerHTML='<summary>Audio levels</summary><div class="audio-panel"><div class="audio-row"><label for="speaker-volume">Speaker</label><input id="speaker-volume" type="range" min="0" max="100" step="1"><output class="audio-value" id="speaker-value"></output></div><div class="audio-row"><label for="mic-sensitivity">Microphone</label><input id="mic-sensitivity" type="range" min="0" max="100" step="1"><output class="audio-value" id="mic-value"></output></div><p class="audio-note">Changes apply immediately and stay on this browser.</p></div>';document.getElementById('error').after(audioControls);
13
+ var callControls=document.createElement('details');callControls.id='call-controls';callControls.className='call-controls';callControls.open=true;callControls.innerHTML='<summary>Microphone and speaker</summary><div class=call-panel id=call-panel></div>';audioControls.open=true;audioControls.after(callControls);
14
+ var q=new URLSearchParams(location.search),character=q.get('character')||'',agent=q.get('agent_id')||'',branch=q.get('branch_id')||'',mode=q.get('mode')==='production'?'production':'test',robot=mode==='production'?(q.get('robot')||character):'',stack=q.get('stack')||'',share=q.get('share_id')||'',session=null,eventToken=null,conversation=null,conversationId=null,keepalive=null,poller=null,retryTimer=null,cameraPublishRetry=null,ending=false,desired=false,alwaysOn=false,connecting=false,generation=0,retryAttempt=0,lastProviderError=null,history=[],seen={},micPipelines=[],micAudioContext=null,localVideoStream=null,activeCameraDevice=null,cameraRoom=null,cameraSdkPromise=null,speakerVolume=storedNumber('robopark.voice.speaker',100,0,100),micSensitivity=storedNumber('robopark.voice.micSensitivity',100,0,100),inputDeviceId='',cameraDeviceId='',outputDeviceId='';
15
+ (function(){var old=document.getElementById('robot-video'),video=document.createElement('video');video.id='robot-video';video.autoplay=true;video.muted=true;video.playsInline=true;if(old&&old.parentNode)old.parentNode.replaceChild(video,old)})();
16
+ function storedNumber(key,fallback,min,max){try{var raw=localStorage.getItem(key);if(raw===null)return fallback;var value=Number(raw);return Number.isFinite(value)?Math.max(min,Math.min(max,value)):fallback}catch(_){return fallback}}
17
+ function persistNumber(key,value){try{localStorage.setItem(key,String(value))}catch(_){}}
18
+ function applySpeakerVolume(){if(conversation&&typeof conversation.setVolume==='function')try{conversation.setVolume({volume:speakerVolume/100})}catch(_){}}
19
+ function setMicSensitivity(value){var level=Number(value);micSensitivity=Math.max(0,Math.min(100,Number.isFinite(level)?level:100));micPipelines.slice().forEach(function(pipe){try{pipe.gain.gain.setTargetAtTime(micSensitivity/100,pipe.context.currentTime,.015)}catch(_){}})}
20
+ function ensureMicAudioContext(){var AudioCtor=window.AudioContext||window.webkitAudioContext;if(!AudioCtor)return null;if(!micAudioContext||micAudioContext.state==='closed')micAudioContext=new AudioCtor();if(micAudioContext.state==='suspended')micAudioContext.resume().catch(function(){});return micAudioContext}
21
+ function processMicrophone(stream){if(!stream||!stream.getAudioTracks||!stream.getAudioTracks().length)return stream;try{var context=ensureMicAudioContext();if(!context)return stream;var source=context.createMediaStreamSource(stream),gain=context.createGain(),destination=context.createMediaStreamDestination(),pipe={context:context,source:source,gain:gain,destination:destination};gain.gain.value=micSensitivity/100;source.connect(gain);gain.connect(destination);micPipelines.push(pipe);var outputTrack=destination.stream.getAudioTracks()[0],nativeStop=outputTrack.stop.bind(outputTrack),closed=false;outputTrack.stop=function(){if(closed)return;closed=true;nativeStop();stream.getTracks().forEach(function(track){try{track.stop()}catch(_){}});try{source.disconnect();gain.disconnect()}catch(_){};micPipelines=micPipelines.filter(function(item){return item!==pipe})};stream.getAudioTracks().forEach(function(track){track.addEventListener('ended',function(){try{outputTrack.stop()}catch(_){}})});return new MediaStream(stream.getVideoTracks().concat([outputTrack]))}catch(_){return stream}}
22
+ function createSilentTestMicrophone(){var AudioCtor=window.AudioContext||window.webkitAudioContext;if(!AudioCtor)throw new Error('This browser has no usable microphone or Web Audio support.');var context=new AudioCtor(),oscillator=context.createOscillator(),gain=context.createGain(),destination=context.createMediaStreamDestination();gain.gain.value=0;oscillator.connect(gain);gain.connect(destination);oscillator.start();var track=destination.stream.getAudioTracks()[0],nativeStop=track.stop.bind(track),closed=false;track.stop=function(){if(closed)return;closed=true;try{oscillator.stop()}catch(_){}nativeStop();context.close().catch(function(){})};var subtitle=document.getElementById('subtitle');if(subtitle)subtitle.textContent='No local microphone attached · agent audio and typed test enabled';return new MediaStream([track])}
23
+ function installMicrophoneRecovery(){
24
+ var media=navigator.mediaDevices;if(!media||!media.getUserMedia||media.__roboparkRecovered)return;var nativeGetUserMedia=media.getUserMedia.bind(media);media.__roboparkRecovered=true;
25
+ media.getUserMedia=function(constraints){return nativeGetUserMedia(constraints).catch(function(error){var audio=constraints&&constraints.audio,recoverable=error&&['NotFoundError','DevicesNotFoundError','OverconstrainedError'].includes(error.name);if(!audio||!recoverable)throw error;var fallback=audio===true?{echoCancellation:true,noiseSuppression:true,autoGainControl:true}:Object.assign({},audio);delete fallback.deviceId;delete fallback.groupId;delete fallback.sampleRate;delete fallback.voiceIsolation;return media.enumerateDevices().then(function(devices){var inputs=devices.filter(function(device){return device.kind==='audioinput'&&device.deviceId}),input=inputs.find(function(device){return device.deviceId!=='default'&&device.deviceId!=='communications'})||inputs[0];if(!input){if(mode==='test')return createSilentTestMicrophone();throw new Error('No browser microphone is currently attached. Connect or enable a microphone, then retry.')}fallback.deviceId={exact:input.deviceId};return nativeGetUserMedia({audio:fallback})}).catch(function(secondError){if(secondError&&String(secondError.message||'').indexOf('No browser microphone')===0)throw secondError;if(mode==='test'&&secondError&&['NotFoundError','DevicesNotFoundError','OverconstrainedError'].includes(secondError.name))return createSilentTestMicrophone();delete fallback.deviceId;return nativeGetUserMedia({audio:fallback})})}).then(function(stream){return constraints&&constraints.audio&&mode==='test'?processMicrophone(stream):stream})};
26
+ }
27
+ installMicrophoneRecovery();
28
+ function ensureElevenLabsClient(){if(window.ElevenLabsClient&&window.ElevenLabsClient.Conversation)return Promise.resolve(window.ElevenLabsClient);return new Promise(function(resolve,reject){var script=document.createElement('script');script.src='/vendor/elevenlabs-client.iife.js';script.onload=function(){if(window.ElevenLabsClient&&window.ElevenLabsClient.Conversation)resolve(window.ElevenLabsClient);else reject(new Error('ElevenLabs browser SDK loaded without a Conversation client.'))};script.onerror=function(){reject(new Error('ElevenLabs browser SDK is unavailable. Check the RoboPark control service build.'))};document.head.appendChild(script)})}
29
+ function el(id){return document.getElementById(id)}function text(id,value){var node=el(id);if(node)node.textContent=value==null?'--':String(value)}function fail(message){text('state','unable to connect');el('error').style.display='block';text('error',message);el('join').disabled=false;stage('configured','bad')}
30
+ var callPanel=el('call-panel');
31
+ callPanel.insertAdjacentHTML('beforeend','<div class=call-row hidden><label for=call-mode>Call mode</label><select id=call-mode><option value=test>Test call · browser only</option><option value=production>Production on-site · robot video and tools</option></select></div>');
32
+ callPanel.insertAdjacentHTML('beforeend','<div class=call-row id=robot-row hidden><label for=call-robot>Production robot</label><select id=call-robot><option value=none>Select a registered robot...</option></select></div>');
33
+ callPanel.insertAdjacentHTML('beforeend','<div class=call-row><label for=call-microphone>Microphone</label><select id=call-microphone><option value=default>System default microphone</option></select></div>');
34
+ callPanel.insertAdjacentHTML('beforeend','<div class=call-row hidden><label for=call-camera>Camera</label><select id=call-camera><option value=default>System default camera</option></select></div>');
35
+ callPanel.insertAdjacentHTML('beforeend','<div class=call-row><label for=call-speaker>Speaker output</label><select id=call-speaker><option value=default>System default speaker</option></select></div>');
36
+ callPanel.insertAdjacentHTML('beforeend','<div class=call-actions hidden><button class=primary id=request-hardware type=button>Request all media</button><button id=refresh-hardware type=button>Refresh devices</button></div>');
37
+ callPanel.insertAdjacentHTML('beforeend','<p class="call-note call-status" id=hardware-status>Grant browser media access to reveal device names.</p><span class=mode-badge id=mode-badge hidden>TEST ? BROWSER ONLY</span>');
38
+ function setHardwareStatus(message,state){text('hardware-status',message);el('hardware-status').className='call-note call-status '+(state||'')}
39
+ function fillHardwareSelect(id,devices,kind,label){var select=el(id),current=select.value;select.innerHTML='<option value=default>System default '+label+'</option>';devices.filter(function(device){return device.kind===kind&&device.deviceId&&device.deviceId!=='default';}).forEach(function(device,index){var option=document.createElement('option');option.value=device.deviceId;option.textContent=device.label||(label+' '+(index+1));select.appendChild(option)});if(current&&Array.from(select.options).some(function(option){return option.value===current}))select.value=current}
40
+ function refreshHardware(requestPermission){if(!navigator.mediaDevices||!navigator.mediaDevices.enumerateDevices){setHardwareStatus('Media device selection is unavailable in this browser.','bad');return Promise.reject(new Error('media devices unavailable'))}var permission=Promise.resolve();if(requestPermission){permission=navigator.mediaDevices.getUserMedia({audio:true,video:true}).catch(function(){return navigator.mediaDevices.getUserMedia({audio:true})}).then(function(stream){stream.getTracks().forEach(function(track){track.stop()})})}setHardwareStatus(requestPermission?'Requesting browser media access...':'Scanning browser hardware...','');return permission.then(function(){return navigator.mediaDevices.enumerateDevices()}).then(function(devices){fillHardwareSelect('call-microphone',devices,'audioinput','microphone');fillHardwareSelect('call-camera',devices,'videoinput','camera');fillHardwareSelect('call-speaker',devices,'audiooutput','speaker');var mic=devices.filter(function(device){return device.kind==='audioinput'}).length,cam=devices.filter(function(device){return device.kind==='videoinput'}).length,out=devices.filter(function(device){return device.kind==='audiooutput'}).length;setHardwareStatus('Ready: '+mic+' microphone(s), '+cam+' camera(s), '+out+' speaker output(s).','ok');return devices}).catch(function(error){setHardwareStatus(error&&error.message||String(error),'bad');throw error})}
41
+ function ensureCameraSdk(){if(window.LivekitClient)return Promise.resolve(window.LivekitClient);if(cameraSdkPromise)return cameraSdkPromise;cameraSdkPromise=new Promise(function(resolve,reject){var script=document.createElement('script');script.src='/vendor/livekit-client.umd.js';script.onload=function(){window.LivekitClient?resolve(window.LivekitClient):reject(new Error('LiveKit camera SDK unavailable'))};script.onerror=function(){reject(new Error('LiveKit camera SDK failed to load'))};document.head.appendChild(script)});return cameraSdkPromise}
42
+ function scheduleCameraPublishRetry(){if(cameraPublishRetry||ending||!localVideoStream)return;cameraPublishRetry=setTimeout(function(){cameraPublishRetry=null;publishLocalVideo().catch(function(){})},3000)}
43
+ function publishLocalVideo(){if(!localVideoStream||!localVideoStream.getVideoTracks().length)return Promise.resolve();if(cameraRoom)return Promise.resolve();return Promise.all([ensureCameraSdk(),fetch('/api/robopark/camera-token',{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify({character_id:character,robot_id:robot||null})}).then(function(response){if(!response.ok)throw new Error('camera token '+response.status);return response.json()})]).then(function(parts){var LK=parts[0],info=parts[1],room=new LK.Room();cameraRoom=room;room.on(LK.RoomEvent.Disconnected,function(){if(cameraRoom===room){cameraRoom=null;scheduleCameraPublishRetry()}});return room.connect(info.url,info.token).then(function(){return room.localParticipant.publishTrack(localVideoStream.getVideoTracks()[0],{name:'camera',source:LK.Track.Source.Camera})}).then(function(){if(cameraPublishRetry){clearTimeout(cameraPublishRetry);cameraPublishRetry=null}event('camera_published','ok','Camera relay live',{})})}).catch(function(error){cameraRoom=null;event('camera_published','failed',error.message,{});scheduleCameraPublishRetry();throw error})}
44
+ function startLocalVideo(){if(!navigator.mediaDevices||!navigator.mediaDevices.getUserMedia)return Promise.resolve();if(localVideoStream&&activeCameraDevice===cameraDeviceId)return publishLocalVideo();if(localVideoStream)localVideoStream.getTracks().forEach(function(track){track.stop()});if(cameraRoom){cameraRoom.disconnect();cameraRoom=null}var video=cameraDeviceId?{deviceId:{exact:cameraDeviceId}}:true;return navigator.mediaDevices.getUserMedia({video:video,audio:false}).then(function(stream){localVideoStream=stream;activeCameraDevice=cameraDeviceId;el('robot-video').srcObject=stream;el('vision').hidden=false;return publishLocalVideo().catch(function(){})}).catch(function(error){localVideoStream=null;activeCameraDevice=null;el('robot-video').srcObject=null;el('vision').hidden=true;throw error})}
45
+ function showRobotVideo(){return startLocalVideo().catch(function(){})}
46
+ function applyCallMode(){mode=el('call-mode').value==='production'?'production':'test';el('robot-row').style.display=mode==='production'?'grid':'none';el('mode-badge').textContent=mode==='production'?'PRODUCTION ? ROBOT VIDEO + TOOLS':'TEST ? BROWSER ONLY';el('mode-badge').className='mode-badge '+(mode==='production'?'production':'');if(mode==='test')robot='';else robot=el('call-robot').value==='none'?'':el('call-robot').value;text('f-mode',mode);text('f-robot',mode==='production'?(robot||'missing robot'):'not requested');showRobotVideo()}
47
+ function loadProductionRobots(){return Promise.all([fetch('/robopark/api/character-presets',{cache:'no-store'}).then(function(r){if(!r.ok)throw new Error('character inventory '+r.status);return r.json()}),fetch('/robopark/api/devices',{cache:'no-store'}).then(function(r){if(!r.ok)throw new Error('device inventory '+r.status);return r.json()})]).then(function(data){var characters=Array.isArray(data[0])?data[0]:(data[0]&&data[0].presets)||[],devices=Array.isArray(data[1])?data[1]:(data[1]&&data[1].devices)||[],select=el('call-robot'),seen={};select.innerHTML='<option value=none>Select a character...</option>';characters.forEach(function(c){var cid=String(c.id||c.preset_id||c.character_id||'');if(!cid||seen[cid.toLowerCase()])return;seen[cid.toLowerCase()]=1;var matches=devices.filter(function(d){return String(d.character_id||'').toLowerCase()===cid.toLowerCase()});matches.sort(function(a,b){var ar=String(a.device_role||'combined'),br=String(b.device_role||'combined'),ap=ar==='voice_vision'?3:ar==='combined'?2:0,bp=br==='voice_vision'?3:br==='combined'?2:0;return bp-ap||Date.parse(b.last_heartbeat||b.enrolled_at||0)-Date.parse(a.last_heartbeat||a.enrolled_at||0)});var voice=matches[0],id=voice&&(voice.id||voice.device_id)||cid,option=document.createElement('option');option.value=id;option.textContent=String(c.name||cid)+' / '+(voice?(String(voice.device_role||'combined')+' '+(voice.status||'registered')):'awaiting voice/video PC');select.appendChild(option)});if(robot&&Array.from(select.options).some(function(option){return option.value===robot}))select.value=robot;else if(character){var match=Array.from(select.options).find(function(option){return option.textContent.toLowerCase().indexOf(character.toLowerCase()+' /')===0||option.value.toLowerCase()===character.toLowerCase()});if(match){select.value=match.value;robot=match.value}}applyCallMode();return characters}).catch(function(error){setHardwareStatus('Character deployment inventory unavailable: '+error.message,'bad');return []})}
48
+ el('call-mode').value=mode;el('call-robot').value=robot||'none';
49
+ el('call-mode').onchange=function(){if(desired||conversation||connecting)end('mode_changed');applyCallMode()};
50
+ el('call-robot').onchange=function(){robot=this.value==='none'?'':this.value;showRobotVideo();text('f-robot',robot||'missing robot')};
51
+ el('call-microphone').onchange=function(){inputDeviceId=this.value==='default'?'':this.value};
52
+ el('call-camera').onchange=function(){cameraDeviceId=this.value==='default'?'':this.value;startLocalVideo().catch(function(){})};
53
+ el('call-speaker').onchange=function(){outputDeviceId=this.value==='default'?'':this.value};
54
+ el('request-hardware').onclick=function(){refreshHardware(true).catch(function(){})};
55
+ el('refresh-hardware').onclick=function(){refreshHardware(false).catch(function(){})};
56
+ applyCallMode();loadProductionRobots();refreshHardware(false).catch(function(){});
57
+ function installElevenLabsHardwareRouting(){var sdk=window.ElevenLabsClient;if(!sdk||!sdk.Conversation)return false;if(sdk.Conversation.__roboparkHardware)return true;var nativeStart=sdk.Conversation.startSession.bind(sdk.Conversation);sdk.Conversation.startSession=function(options){return nativeStart(Object.assign({},options||{},{inputDeviceId:inputDeviceId||undefined,outputDeviceId:outputDeviceId||undefined}))};sdk.Conversation.__roboparkHardware=true;return true}
58
+ installElevenLabsHardwareRouting();
59
+ var hardwarePatchTimer=setInterval(function(){if(installElevenLabsHardwareRouting())clearInterval(hardwarePatchTimer)},500);
60
+ function stage(name,status){var order=['configured','permission','signed_session','connected','conversation'],index=order.indexOf(name);document.querySelectorAll('.step').forEach(function(node,i){node.className='step '+(status==='bad'&&i===index?'bad':i<index?'done':i===index?'live':'')})}
61
+ function headers(){return {'content-type':'application/json','X-RoboPark-Session-Token':eventToken||''}}
62
+ function api(path,options){options=options||{};if(path==='/api/sessions/voice-call'&&options.body){var payload=JSON.parse(options.body);payload.call_mode=mode;payload.robot_id=mode==='production'?(robot||null):null;options.body=JSON.stringify(payload)}return fetch('/robopark'+path,Object.assign({cache:'no-store'},options)).then(function(response){if(!response.ok)return response.text().then(function(body){throw new Error(body||('request '+response.status))});return response.json()})}
63
+ function append(role,message){message=String(message||'').trim();if(!message)return;var key=role+'|'+message;if(seen[key])return;seen[key]=1;var node=document.createElement('div');node.className='turn '+role;node.textContent=message;el('transcript').appendChild(node);el('transcript').scrollTop=el('transcript').scrollHeight}
64
+ function management(path,body){if(!session||!eventToken)return Promise.resolve();return api('/api/sessions/'+encodeURIComponent(session)+path,{method:'POST',headers:headers(),body:JSON.stringify(body||{})}).catch(function(){})}
65
+ function event(stageName,status,message,details){var row=document.createElement('div');row.className='event';row.innerHTML='<span>'+String(stageName||'event').replace(/[<>]/g,'')+'</span><span class="'+String(status||'ok').replace(/[<>]/g,'')+'">'+String(status||'ok').replace(/[<>]/g,'')+'</span><span>'+String(message||'').replace(/[<>]/g,'')+'</span>';var host=el('events');if(host){host.prepend(row);while(host.children.length>9)host.lastElementChild.remove()}return Promise.resolve()}
66
+ function saveTurn(role,message){message=String(message||'').trim();if(!message)return Promise.resolve();return management('/transcript',{role:role,text:message,is_final:true,sequence:Object.keys(seen).length,source:'public_join'})}
67
+ function renderDetail(detail){var events=(detail&&detail.pipeline_events)||[],latest=events.length?events[events.length-1]:null;if(latest&&latest.status==='failed')stage('conversation','bad');el('events').innerHTML=events.slice(-9).reverse().map(function(item){return '<div class="event"><span>'+String(item.stage||'event').replace(/[<>]/g,'')+'</span><span class="'+String(item.status||'')+'">'+String(item.status||'')+'</span><span>'+String(item.message||'').replace(/[<>]/g,'')+'</span></div>'}).join('')||'<div class="event"><span>connected</span><span class="ok">ok</span><span>Waiting for conversation events.</span></div>'}
68
+ function pollDetail(){applySpeakerVolume()}
69
+ function plainDetails(value){try{return JSON.parse(JSON.stringify(value||{}))}catch(_){return {raw:String(value||'')}}}
70
+ function closeManaged(reason,details){var oldSession=session,oldToken=eventToken;if(!oldSession||!oldToken)return Promise.resolve();return api('/api/sessions/'+encodeURIComponent(oldSession)+'/end?reason='+encodeURIComponent(reason),{method:'POST',headers:{'content-type':'application/json','X-RoboPark-Session-Token':oldToken},body:JSON.stringify({details:plainDetails(details),source:'public_join'})}).catch(function(){})}
71
+ function stopTimers(){if(retryTimer){clearTimeout(retryTimer);retryTimer=null}if(keepalive){clearInterval(keepalive);keepalive=null}if(poller){clearInterval(poller);poller=null}}
72
+ function scheduleReconnect(){if(!desired||!alwaysOn||ending)return;connecting=false;conversation=null;conversationId=null;var attempt=++retryAttempt,delay=Math.min(30000,Math.round(750*Math.pow(2,Math.min(attempt-1,6))+Math.random()*500));text('state','reconnecting in '+Math.ceil(delay/1000)+'s');stage('connected');el('avatar-wrap').classList.remove('speaking');if(retryTimer)clearTimeout(retryTimer);retryTimer=setTimeout(function(){retryTimer=null;connectAttempt('reconnect')},delay)}
73
+ function recover(myGeneration,details){if(myGeneration!==generation||ending||!desired)return;var captured=plainDetails(details);captured.last_provider_error=lastProviderError;event('provider_error','failed','ElevenLabs disconnected; visitor may reconnect manually',captured);closeManaged('provider_disconnected',captured);stopTimers();session=null;eventToken=null;conversation=null;conversationId=null;desired=false;connecting=false;retryAttempt=0;el('avatar-wrap').classList.remove('live','speaking');text('state','conversation ended - start again when ready');stage('conversation','bad');el('join').hidden=false;el('join').disabled=false;el('join').textContent='Start conversation';el('end').hidden=true;el('message').disabled=true;el('send').disabled=true}
74
+ function end(reason){if(ending)return;ending=true;desired=false;generation++;stopTimers();var active=conversation,details={manual:true,reason:reason||'visitor'};if(active)try{active.endSession()}catch(_){};if(cameraRoom){cameraRoom.disconnect();cameraRoom=null}if(localVideoStream){localVideoStream.getTracks().forEach(function(track){track.stop()});localVideoStream=null}closeManaged(reason||'visitor',details);session=null;eventToken=null;conversation=null;conversationId=null;connecting=false;retryAttempt=0;stage('conversation','done');text('state','manually disconnected - supervisor stopped');el('avatar-wrap').classList.remove('live','speaking');el('join').hidden=false;el('join').disabled=false;el('join').textContent='Start conversation';el('end').hidden=true;el('message').disabled=true;el('send').disabled=true;ending=false}
75
+ function callPayload(){return {character_preset_id:character,voice_stack_id:stack||null,client_name:'Public character link',engine:'elevenlabs',agent_id:agent,branch_id:branch||null,robot_id:robot||null,join_link_id:share||null}}
76
+ function connectAttempt(kind){if(!desired||ending||connecting||conversation)return;connecting=true;var myGeneration=++generation;text('state',kind==='reconnect'?'obtaining fresh voice session':'connecting');stage('signed_session');api('/api/sessions/voice-call',{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify(callPayload())}).then(function(call){if(myGeneration!==generation||!desired)throw new Error('connection superseded');session=call.session_id;eventToken=call.event_token;text('f-session',session);text('f-agent',call.agent_id);text('f-branch',call.branch_id||'default');text('f-robot',call.robot_id||'operator only');if(call.robot_video_ref&&robot){el('vision').hidden=false;el('robot-video').src='/fed/media/robots/'+encodeURIComponent(call.robot_video_ref)+'/video_feed'}stage('connected');event('signed_session','ok','Fresh signed ElevenLabs session created',{join_link_id:share,robot_id:robot,reconnect_attempt:retryAttempt});return ensureElevenLabsClient().then(function(SDK){return SDK.Conversation.startSession({signedUrl:call.signed_url,connectionType:'websocket',useWakeLock:true,onConnect:function(info){if(myGeneration!==generation)return;conversationId=info.conversationId;lastProviderError=null;retryAttempt=0;text('state','listening');el('error').style.display='none';el('avatar-wrap').classList.add('live');stage('conversation');management('/joined',{conversation_id:conversationId,connection_type:'websocket',engine:'elevenlabs',robot_id:robot,join_link_id:share,source:'public_join'});event('provider_connected','ok','ElevenLabs conversation connected',{conversation_id:conversationId,supervised:true})},onDisconnect:function(info){recover(myGeneration,info||{reason:'provider_disconnected'})},onError:function(message,context){if(myGeneration!==generation)return;lastProviderError={message:String(message||'Provider error'),context:plainDetails(context)};event('provider_error','failed',lastProviderError.message,lastProviderError);text('state','provider error')},onStatusChange:function(info){if(myGeneration===generation)event('provider_status',info&&info.status==='disconnected'?'warning':'ok',info&&info.status||'unknown',{})},onMessage:function(info){if(myGeneration!==generation)return;var message=String(info&&info.message||'').trim(),role=info&&info.role==='user'?'user':'assistant';append(role,message);if(message){history.push({role:role,text:message});history=history.slice(-20)}saveTurn(role,message)},onModeChange:function(info){if(myGeneration!==generation)return;var speaking=info.mode==='speaking';el('avatar-wrap').classList.toggle('speaking',speaking);text('state',speaking?'speaking':'listening');event('mode','ok',info.mode,{})},onInterruption:function(info){event('interruption','ok','Agent interrupted',info||{})},onMCPToolCall:function(info){event('mcp_tool','running','Tool call',info||{})}})})}).then(function(active){connecting=false;if(myGeneration!==generation||!desired){try{active.endSession()}catch(_){}return}conversation=active;el('join').hidden=true;el('end').hidden=false;el('message').disabled=false;el('send').disabled=false;pollDetail()}).catch(function(error){connecting=false;if(myGeneration!==generation||!desired)return;var details={message:error&&error.message||String(error),last_provider_error:lastProviderError};event('provider_error','failed','Voice connection attempt failed',details);closeManaged('connection_failed',details);session=null;eventToken=null;conversation=null;conversationId=null;fail(details.message)})}
77
+ function start(){if(desired||conversation||connecting)return;if(mode==='production'&&!robot){fail('Select a registered production robot first.');return}if(mode==='test')ensureMicAudioContext();desired=true;retryAttempt=0;el('join').disabled=true;text('state','requesting microphone permission');stage('permission');var audio=inputDeviceId?{deviceId:{exact:inputDeviceId}}:true;navigator.mediaDevices.getUserMedia({audio:audio}).then(function(stream){stream.getTracks().forEach(function(track){track.stop()});return startLocalVideo()}).then(function(){connectAttempt('initial')}).catch(function(error){desired=false;fail(error&&error.message||String(error))})}
78
+ el('always-on').onclick=function(){alwaysOn=!alwaysOn;this.classList.toggle('on',alwaysOn);this.setAttribute('aria-pressed',String(alwaysOn));this.textContent='Always on: '+(alwaysOn?'ON':'OFF');if(!alwaysOn&&retryTimer){clearTimeout(retryTimer);retryTimer=null;text('state','disconnected - automatic recovery paused')}else if(alwaysOn&&desired&&!conversation&&!connecting){scheduleReconnect()}};
79
+ function pollDetail(){applySpeakerVolume()}
80
+ function deploymentRequest(path,options){var token=q.get('token')||'',suffix=token?(path.indexOf('?')>=0?'&':'?')+'token='+encodeURIComponent(token):'';return fetch('/robopark'+path+suffix,Object.assign({cache:'no-store'},options||{})).then(function(response){if(!response.ok)throw new Error('request '+response.status);return response.json()})}
81
+ function renderDeployment(data){var token=q.get('token')||'',rows=[];[['voice_vision_boxes','Windows voice + vision',['vision','conversation']],['motor_nodes','Pi motor server',['motor']]].forEach(function(group){var devices=data[group[0]]||[];if(!devices.length){rows.push('<div class="deployment-row"><b>'+group[1]+'</b><span>not registered</span><span></span></div>');return}devices.forEach(function(device){var seen=Date.parse(device.last_heartbeat||''),live=isFinite(seen)&&Date.now()-seen<90000,buttons=token?group[2].map(function(service){return '<button data-device="'+device.id+'" data-service="'+service+'" data-action="start">Start '+service+'</button><button data-device="'+device.id+'" data-service="'+service+'" data-action="restart">Restart</button><button data-device="'+device.id+'" data-service="'+service+'" data-action="stop">Stop</button>'}).join(''):'management token required for controls';rows.push('<div class="deployment-row"><b>'+group[1]+'</b><span class="'+(live?'ready':'')+'">'+String(device.name||device.id)+' / '+(live?'online':'stale')+'</span><div class="deployment-actions">'+buttons+'</div></div>')})});deployment.innerHTML=rows.join('');deployment.querySelectorAll('button[data-action]').forEach(function(button){button.onclick=function(){var action=button.getAttribute('data-action'),service=button.getAttribute('data-service'),device=button.getAttribute('data-device');if((action==='stop'||action==='restart')&&!confirm(action+' '+service+'?'))return;button.disabled=true;deploymentRequest('/api/devices/'+encodeURIComponent(device)+'/services/'+encodeURIComponent(service)+'/'+action,{method:'POST',headers:{'content-type':'application/json'}}).then(function(){button.textContent='queued'}).catch(function(error){button.textContent='failed';fail(error.message)}).then(function(){setTimeout(function(){button.disabled=false},1800)})}})}
82
+ function loadDeployment(){deploymentRequest('/api/characters/'+encodeURIComponent(character)+'/deployment').then(renderDeployment).catch(function(){deployment.innerHTML='<div class="deployment-row"><b>Character hardware</b><span>deployment status unavailable</span><span></span></div>'})}
83
+ el('speaker-volume').value=String(speakerVolume);text('speaker-value',speakerVolume+'%');el('mic-sensitivity').value=String(micSensitivity);text('mic-value',micSensitivity+'%');el('speaker-volume').oninput=function(){speakerVolume=Math.max(0,Math.min(100,Number(this.value)||0));text('speaker-value',speakerVolume+'%');persistNumber('robopark.voice.speaker',speakerVolume);applySpeakerVolume()};el('mic-sensitivity').oninput=function(){setMicSensitivity(this.value);text('mic-value',micSensitivity+'%');persistNumber('robopark.voice.micSensitivity',micSensitivity)};
84
+ el('ops-toggle').onclick=function(){el('ops').classList.toggle('open');this.classList.toggle('on',el('ops').classList.contains('open'))};el('ops-close').onclick=function(){el('ops').classList.remove('open');el('ops-toggle').classList.remove('on')};el('join').onclick=start;el('end').onclick=function(){end('visitor')};el('compose').onsubmit=function(e){e.preventDefault();var message=el('message').value.trim();if(message&&conversation){conversation.sendUserMessage(message);el('message').value=''}};
85
+ text('f-mode',mode);text('f-character',character);text('f-agent',agent);text('f-branch',branch||'default');text('f-robot',mode==='production'?(robot||'missing robot'):'not requested');text('f-share',share||'untracked');
86
+ if(character)loadDeployment();
87
+ if(!character||!agent){fail('This join link is incomplete. Ask the operator for a new character link.');return}if(mode==='production'&&!robot){fail('This production link has no registered robot. Ask the operator for a corrected link.');return}api('/api/character-presets/'+encodeURIComponent(character)).then(function(preset){text('character-name',preset.name||preset.id);text('subtitle',(mode==='test'?'Browser-only test call · ':'Production on-site call · ')+(preset.description||'Secure ElevenLabs conversation managed by RoboPark'));text('f-character',preset.name||preset.id);text('fallback',String(preset.name||preset.id).slice(0,2).toUpperCase());if(preset.img){el('avatar').src=preset.img;el('avatar').onload=function(){el('fallback').style.display='none'}};text('state','ready to connect');el('join').disabled=false}).catch(function(){fail('Character configuration is unavailable.')});
88
+ })();
89
+ </script></body></html>
@@ -0,0 +1,38 @@
1
+ const path = require('path')
2
+
3
+ const dir = path.join(__dirname)
4
+
5
+ process.env.NODE_ENV = 'production'
6
+ process.chdir(__dirname)
7
+
8
+ const currentPort = parseInt(process.env.PORT, 10) || 3000
9
+ const hostname = process.env.HOSTNAME || '0.0.0.0'
10
+
11
+ let keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10)
12
+ const nextConfig = {"env":{},"webpack":null,"eslint":{"ignoreDuringBuilds":true},"typescript":{"ignoreBuildErrors":false,"tsconfigPath":"tsconfig.json"},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[16,32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":60,"formats":["image/webp"],"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","remotePatterns":[],"unoptimized":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"amp":{"canonicalBase":""},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"serverRuntimeConfig":{},"publicRuntimeConfig":{},"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"C:\\Users\\yunge\\OneDrive\\Desktop\\ROBOVOICE-main\\frontend","experimental":{"useSkewCookie":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":4294967294}},"cacheHandlers":{},"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"serverSourceMaps":false,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"clientSegmentCache":false,"clientParamParsing":false,"dynamicOnHover":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","middlewarePrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":15,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"viewTransition":false,"routerBFCache":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"cacheComponents":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"devtoolSegmentExplorer":true,"browserDebugInfoInTerminal":false,"optimizeRouterScrolling":false,"middlewareClientMaxBodySize":10485760,"optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","turbopack":{"root":"C:\\Users\\yunge\\OneDrive\\Desktop\\ROBOVOICE-main\\frontend"},"_originalRewrites":{"beforeFiles":[],"afterFiles":[{"source":"/api/announce","destination":"http://agent:8889/announce"},{"source":"/api/reload-tools","destination":"http://agent:8889/reload-tools"},{"source":"/api/wake","destination":"http://agent:8889/wake"},{"source":"/api/health","destination":"http://agent:8889/health"},{"source":"/api/prompt","destination":"http://agent:8889/prompt"},{"source":"/api/voices","destination":"http://agent:8889/voices"},{"source":"/api/models","destination":"http://agent:8889/models"},{"source":"/api/wake-word/:path*","destination":"http://agent:8889/wake-word/:path*"},{"source":"/api/metrics","destination":"http://agent:8889/metrics"}],"fallback":[]}}
13
+
14
+ process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
15
+
16
+ require('next')
17
+ const { startServer } = require('next/dist/server/lib/start-server')
18
+
19
+ if (
20
+ Number.isNaN(keepAliveTimeout) ||
21
+ !Number.isFinite(keepAliveTimeout) ||
22
+ keepAliveTimeout < 0
23
+ ) {
24
+ keepAliveTimeout = undefined
25
+ }
26
+
27
+ startServer({
28
+ dir,
29
+ isDev: false,
30
+ config: nextConfig,
31
+ hostname,
32
+ port: currentPort,
33
+ allowRetry: false,
34
+ keepAliveTimeout,
35
+ }).catch((err) => {
36
+ console.error(err);
37
+ process.exit(1);
38
+ });