visionclaw 0.1.193 → 0.1.194-dev.feat-backup-progress-reporting.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (352) hide show
  1. package/dist/agent/backup-uploader.d.ts +44 -0
  2. package/dist/agent/backup-uploader.d.ts.map +1 -0
  3. package/dist/agent/backup-uploader.js +83 -0
  4. package/dist/agent/backup-uploader.js.map +1 -0
  5. package/dist/agent/backup.d.ts +7 -1
  6. package/dist/agent/backup.d.ts.map +1 -1
  7. package/dist/agent/backup.js +337 -52
  8. package/dist/agent/backup.js.map +1 -1
  9. package/dist/agent/command-handlers.d.ts +2 -0
  10. package/dist/agent/command-handlers.d.ts.map +1 -1
  11. package/dist/agent/command-handlers.js +29 -3
  12. package/dist/agent/command-handlers.js.map +1 -1
  13. package/dist/agent/context.d.ts +2 -0
  14. package/dist/agent/context.d.ts.map +1 -1
  15. package/dist/agent/context.js +11 -1
  16. package/dist/agent/context.js.map +1 -1
  17. package/dist/agent/data-collector.d.ts.map +1 -1
  18. package/dist/agent/data-collector.js +23 -38
  19. package/dist/agent/data-collector.js.map +1 -1
  20. package/dist/agent/loop.d.ts +3 -0
  21. package/dist/agent/loop.d.ts.map +1 -1
  22. package/dist/agent/loop.js +48 -0
  23. package/dist/agent/loop.js.map +1 -1
  24. package/dist/agent/message-format.d.ts.map +1 -1
  25. package/dist/agent/message-format.js +3 -0
  26. package/dist/agent/message-format.js.map +1 -1
  27. package/dist/agent/status.d.ts.map +1 -1
  28. package/dist/agent/status.js +2 -1
  29. package/dist/agent/status.js.map +1 -1
  30. package/dist/backup.d.ts +4 -1
  31. package/dist/backup.d.ts.map +1 -1
  32. package/dist/backup.js +86 -3
  33. package/dist/backup.js.map +1 -1
  34. package/dist/calendar/google-calendar.d.ts +2 -0
  35. package/dist/calendar/google-calendar.d.ts.map +1 -1
  36. package/dist/calendar/google-calendar.js +3 -0
  37. package/dist/calendar/google-calendar.js.map +1 -1
  38. package/dist/channels/interface.d.ts +9 -0
  39. package/dist/channels/interface.d.ts.map +1 -1
  40. package/dist/channels/manager.d.ts +7 -1
  41. package/dist/channels/manager.d.ts.map +1 -1
  42. package/dist/channels/manager.js +12 -0
  43. package/dist/channels/manager.js.map +1 -1
  44. package/dist/channels/telegram.d.ts.map +1 -1
  45. package/dist/channels/telegram.js +5 -0
  46. package/dist/channels/telegram.js.map +1 -1
  47. package/dist/cli/index.d.ts +1 -0
  48. package/dist/cli/index.d.ts.map +1 -1
  49. package/dist/cli/index.js +42 -2
  50. package/dist/cli/index.js.map +1 -1
  51. package/dist/config/types.d.ts +9 -0
  52. package/dist/config/types.d.ts.map +1 -1
  53. package/dist/config/types.js +6 -0
  54. package/dist/config/types.js.map +1 -1
  55. package/dist/drive/google-drive.d.ts +1 -0
  56. package/dist/drive/google-drive.d.ts.map +1 -1
  57. package/dist/drive/google-drive.js +5 -0
  58. package/dist/drive/google-drive.js.map +1 -1
  59. package/dist/i18n/messages.d.ts +4 -0
  60. package/dist/i18n/messages.d.ts.map +1 -1
  61. package/dist/i18n/messages.js +7 -2
  62. package/dist/i18n/messages.js.map +1 -1
  63. package/dist/index.js.map +1 -1
  64. package/dist/obs/server.d.ts +7 -0
  65. package/dist/obs/server.d.ts.map +1 -1
  66. package/dist/obs/server.js +22 -0
  67. package/dist/obs/server.js.map +1 -1
  68. package/dist/onboarding/bot-profile.d.ts.map +1 -1
  69. package/dist/onboarding/bot-profile.js +1 -0
  70. package/dist/onboarding/bot-profile.js.map +1 -1
  71. package/dist/onboarding/index.d.ts.map +1 -1
  72. package/dist/onboarding/index.js +5 -0
  73. package/dist/onboarding/index.js.map +1 -1
  74. package/dist/onboarding/prepare-mac.d.ts +1 -0
  75. package/dist/onboarding/prepare-mac.d.ts.map +1 -1
  76. package/dist/onboarding/prepare-mac.js +32 -15
  77. package/dist/onboarding/prepare-mac.js.map +1 -1
  78. package/dist/onboarding/setup-shared.d.ts.map +1 -1
  79. package/dist/onboarding/setup-shared.js +6 -0
  80. package/dist/onboarding/setup-shared.js.map +1 -1
  81. package/dist/onboarding/setup-steps.d.ts.map +1 -1
  82. package/dist/onboarding/setup-steps.js +8 -0
  83. package/dist/onboarding/setup-steps.js.map +1 -1
  84. package/dist/realtime/agent-bridge.d.ts +7 -0
  85. package/dist/realtime/agent-bridge.d.ts.map +1 -0
  86. package/dist/realtime/agent-bridge.js +31 -0
  87. package/dist/realtime/agent-bridge.js.map +1 -0
  88. package/dist/realtime/assets/index.html +1058 -0
  89. package/dist/realtime/assets/samples/alloy.mp3 +0 -0
  90. package/dist/realtime/assets/samples/ash.mp3 +0 -0
  91. package/dist/realtime/assets/samples/ballad.mp3 +0 -0
  92. package/dist/realtime/assets/samples/cedar.mp3 +0 -0
  93. package/dist/realtime/assets/samples/coral.mp3 +0 -0
  94. package/dist/realtime/assets/samples/echo.mp3 +0 -0
  95. package/dist/realtime/assets/samples/marin.mp3 +0 -0
  96. package/dist/realtime/assets/samples/sage.mp3 +0 -0
  97. package/dist/realtime/assets/samples/shimmer.mp3 +0 -0
  98. package/dist/realtime/assets/samples/verse.mp3 +0 -0
  99. package/dist/realtime/context.d.ts +14 -0
  100. package/dist/realtime/context.d.ts.map +1 -0
  101. package/dist/realtime/context.js +153 -0
  102. package/dist/realtime/context.js.map +1 -0
  103. package/dist/realtime/http-helpers.d.ts +5 -0
  104. package/dist/realtime/http-helpers.d.ts.map +1 -0
  105. package/dist/realtime/http-helpers.js +29 -0
  106. package/dist/realtime/http-helpers.js.map +1 -0
  107. package/dist/realtime/index.d.ts +62 -0
  108. package/dist/realtime/index.d.ts.map +1 -0
  109. package/dist/realtime/index.js +94 -0
  110. package/dist/realtime/index.js.map +1 -0
  111. package/dist/realtime/server.d.ts +6 -0
  112. package/dist/realtime/server.d.ts.map +1 -0
  113. package/dist/realtime/server.js +476 -0
  114. package/dist/realtime/server.js.map +1 -0
  115. package/dist/realtime/telegram-auth.d.ts +2 -0
  116. package/dist/realtime/telegram-auth.d.ts.map +1 -0
  117. package/dist/realtime/telegram-auth.js +24 -0
  118. package/dist/realtime/telegram-auth.js.map +1 -0
  119. package/dist/realtime/tools.d.ts +829 -0
  120. package/dist/realtime/tools.d.ts.map +1 -0
  121. package/dist/realtime/tools.js +630 -0
  122. package/dist/realtime/tools.js.map +1 -0
  123. package/dist/realtime/types.d.ts +62 -0
  124. package/dist/realtime/types.d.ts.map +1 -0
  125. package/dist/realtime/types.js +3 -0
  126. package/dist/realtime/types.js.map +1 -0
  127. package/dist/realtime/voice-summarizer.d.ts +4 -0
  128. package/dist/realtime/voice-summarizer.d.ts.map +1 -0
  129. package/dist/realtime/voice-summarizer.js +129 -0
  130. package/dist/realtime/voice-summarizer.js.map +1 -0
  131. package/dist/restore.d.ts +5 -0
  132. package/dist/restore.d.ts.map +1 -1
  133. package/dist/restore.js +132 -16
  134. package/dist/restore.js.map +1 -1
  135. package/dist/tools/email.d.ts +1 -1
  136. package/dist/tools/memory.d.ts +13 -0
  137. package/dist/tools/memory.d.ts.map +1 -1
  138. package/dist/tools/memory.js +43 -43
  139. package/dist/tools/memory.js.map +1 -1
  140. package/dist/tools/stock-data.d.ts +16 -0
  141. package/dist/tools/stock-data.d.ts.map +1 -1
  142. package/dist/tools/stock-data.js +36 -38
  143. package/dist/tools/stock-data.js.map +1 -1
  144. package/dist/tools/web-fetch.d.ts +4 -0
  145. package/dist/tools/web-fetch.d.ts.map +1 -1
  146. package/dist/tools/web-fetch.js +95 -23
  147. package/dist/tools/web-fetch.js.map +1 -1
  148. package/dist/tos-storage.d.ts +45 -0
  149. package/dist/tos-storage.d.ts.map +1 -0
  150. package/dist/tos-storage.js +134 -0
  151. package/dist/tos-storage.js.map +1 -0
  152. package/dist-agent/bundle.cjs +170934 -167547
  153. package/package.json +3 -2
  154. package/dist/agent/applied-credential-signature.d.ts +0 -53
  155. package/dist/agent/applied-credential-signature.d.ts.map +0 -1
  156. package/dist/agent/applied-credential-signature.js +0 -137
  157. package/dist/agent/applied-credential-signature.js.map +0 -1
  158. package/dist/agent/engines/claude/cli-resolver.d.ts +0 -16
  159. package/dist/agent/engines/claude/cli-resolver.d.ts.map +0 -1
  160. package/dist/agent/engines/claude/cli-resolver.js +0 -83
  161. package/dist/agent/engines/claude/cli-resolver.js.map +0 -1
  162. package/dist/agent/engines/claude/session-browser-policy.d.ts +0 -9
  163. package/dist/agent/engines/claude/session-browser-policy.d.ts.map +0 -1
  164. package/dist/agent/engines/claude/session-browser-policy.js +0 -49
  165. package/dist/agent/engines/claude/session-browser-policy.js.map +0 -1
  166. package/dist/agent/engines/claude/session.d.ts +0 -291
  167. package/dist/agent/engines/claude/session.d.ts.map +0 -1
  168. package/dist/agent/engines/claude/session.js +0 -1177
  169. package/dist/agent/engines/claude/session.js.map +0 -1
  170. package/dist/agent/engines/client-factory.d.ts +0 -63
  171. package/dist/agent/engines/client-factory.d.ts.map +0 -1
  172. package/dist/agent/engines/client-factory.js +0 -382
  173. package/dist/agent/engines/client-factory.js.map +0 -1
  174. package/dist/agent/engines/engine.d.ts +0 -8
  175. package/dist/agent/engines/engine.d.ts.map +0 -1
  176. package/dist/agent/engines/engine.js +0 -15
  177. package/dist/agent/engines/engine.js.map +0 -1
  178. package/dist/agent/engines/openai/file-session.d.ts +0 -49
  179. package/dist/agent/engines/openai/file-session.d.ts.map +0 -1
  180. package/dist/agent/engines/openai/file-session.js +0 -108
  181. package/dist/agent/engines/openai/file-session.js.map +0 -1
  182. package/dist/agent/engines/openai/file-tools.d.ts +0 -35
  183. package/dist/agent/engines/openai/file-tools.d.ts.map +0 -1
  184. package/dist/agent/engines/openai/file-tools.js +0 -194
  185. package/dist/agent/engines/openai/file-tools.js.map +0 -1
  186. package/dist/agent/engines/openai/session.d.ts +0 -190
  187. package/dist/agent/engines/openai/session.d.ts.map +0 -1
  188. package/dist/agent/engines/openai/session.js +0 -1066
  189. package/dist/agent/engines/openai/session.js.map +0 -1
  190. package/dist/agent/engines/openai/tools.d.ts +0 -13
  191. package/dist/agent/engines/openai/tools.d.ts.map +0 -1
  192. package/dist/agent/engines/openai/tools.js +0 -248
  193. package/dist/agent/engines/openai/tools.js.map +0 -1
  194. package/dist/agent/engines/session-types.d.ts +0 -146
  195. package/dist/agent/engines/session-types.d.ts.map +0 -1
  196. package/dist/agent/engines/session-types.js +0 -2
  197. package/dist/agent/engines/session-types.js.map +0 -1
  198. package/dist/agent/engines/system-prompt-log.d.ts +0 -9
  199. package/dist/agent/engines/system-prompt-log.d.ts.map +0 -1
  200. package/dist/agent/engines/system-prompt-log.js +0 -46
  201. package/dist/agent/engines/system-prompt-log.js.map +0 -1
  202. package/dist/agent/transcript/transcript-backfill.d.ts +0 -54
  203. package/dist/agent/transcript/transcript-backfill.d.ts.map +0 -1
  204. package/dist/agent/transcript/transcript-backfill.js +0 -604
  205. package/dist/agent/transcript/transcript-backfill.js.map +0 -1
  206. package/dist/agent/transcript/transcript-indexer.d.ts +0 -273
  207. package/dist/agent/transcript/transcript-indexer.d.ts.map +0 -1
  208. package/dist/agent/transcript/transcript-indexer.js +0 -1217
  209. package/dist/agent/transcript/transcript-indexer.js.map +0 -1
  210. package/dist/agent/transcript/transcript-memory-migrations.d.ts +0 -25
  211. package/dist/agent/transcript/transcript-memory-migrations.d.ts.map +0 -1
  212. package/dist/agent/transcript/transcript-memory-migrations.js +0 -87
  213. package/dist/agent/transcript/transcript-memory-migrations.js.map +0 -1
  214. package/dist/agent/transcript-memory-migrations.d.ts +0 -25
  215. package/dist/agent/transcript-memory-migrations.d.ts.map +0 -1
  216. package/dist/agent/transcript-memory-migrations.js +0 -87
  217. package/dist/agent/transcript-memory-migrations.js.map +0 -1
  218. package/dist/agent/tunnel-credential-handler.d.ts +0 -90
  219. package/dist/agent/tunnel-credential-handler.d.ts.map +0 -1
  220. package/dist/agent/tunnel-credential-handler.js +0 -162
  221. package/dist/agent/tunnel-credential-handler.js.map +0 -1
  222. package/dist/agent/usage/usage-backfill-handler.d.ts +0 -18
  223. package/dist/agent/usage/usage-backfill-handler.d.ts.map +0 -1
  224. package/dist/agent/usage/usage-backfill-handler.js +0 -69
  225. package/dist/agent/usage/usage-backfill-handler.js.map +0 -1
  226. package/dist/agent/usage/usage-gate.d.ts +0 -25
  227. package/dist/agent/usage/usage-gate.d.ts.map +0 -1
  228. package/dist/agent/usage/usage-gate.js +0 -83
  229. package/dist/agent/usage/usage-gate.js.map +0 -1
  230. package/dist/agent/usage/usage-handler.d.ts +0 -7
  231. package/dist/agent/usage/usage-handler.d.ts.map +0 -1
  232. package/dist/agent/usage/usage-handler.js +0 -28
  233. package/dist/agent/usage/usage-handler.js.map +0 -1
  234. package/dist/agent/usage/usage-report-builder.d.ts +0 -26
  235. package/dist/agent/usage/usage-report-builder.d.ts.map +0 -1
  236. package/dist/agent/usage/usage-report-builder.js +0 -80
  237. package/dist/agent/usage/usage-report-builder.js.map +0 -1
  238. package/dist/agent/usage/usage-report-queue.d.ts +0 -26
  239. package/dist/agent/usage/usage-report-queue.d.ts.map +0 -1
  240. package/dist/agent/usage/usage-report-queue.js +0 -199
  241. package/dist/agent/usage/usage-report-queue.js.map +0 -1
  242. package/dist/agent/usage/usage-report-types.d.ts +0 -41
  243. package/dist/agent/usage/usage-report-types.d.ts.map +0 -1
  244. package/dist/agent/usage/usage-report-types.js +0 -2
  245. package/dist/agent/usage/usage-report-types.js.map +0 -1
  246. package/dist/agent/usage/usage-reporter.d.ts +0 -31
  247. package/dist/agent/usage/usage-reporter.d.ts.map +0 -1
  248. package/dist/agent/usage/usage-reporter.js +0 -102
  249. package/dist/agent/usage/usage-reporter.js.map +0 -1
  250. package/dist/agent/usage-backfill-handler.d.ts +0 -18
  251. package/dist/agent/usage-backfill-handler.d.ts.map +0 -1
  252. package/dist/agent/usage-backfill-handler.js +0 -69
  253. package/dist/agent/usage-backfill-handler.js.map +0 -1
  254. package/dist/agent/usage-gate.d.ts +0 -25
  255. package/dist/agent/usage-gate.d.ts.map +0 -1
  256. package/dist/agent/usage-gate.js +0 -83
  257. package/dist/agent/usage-gate.js.map +0 -1
  258. package/dist/agent/usage-report-builder.d.ts +0 -26
  259. package/dist/agent/usage-report-builder.d.ts.map +0 -1
  260. package/dist/agent/usage-report-builder.js +0 -80
  261. package/dist/agent/usage-report-builder.js.map +0 -1
  262. package/dist/agent/usage-report-queue.d.ts +0 -26
  263. package/dist/agent/usage-report-queue.d.ts.map +0 -1
  264. package/dist/agent/usage-report-queue.js +0 -199
  265. package/dist/agent/usage-report-queue.js.map +0 -1
  266. package/dist/agent/usage-report-types.d.ts +0 -41
  267. package/dist/agent/usage-report-types.d.ts.map +0 -1
  268. package/dist/agent/usage-report-types.js +0 -2
  269. package/dist/agent/usage-report-types.js.map +0 -1
  270. package/dist/agent/usage-reporter.d.ts +0 -31
  271. package/dist/agent/usage-reporter.d.ts.map +0 -1
  272. package/dist/agent/usage-reporter.js +0 -102
  273. package/dist/agent/usage-reporter.js.map +0 -1
  274. package/dist/agent/wake-cycle-tool-tracker.d.ts +0 -39
  275. package/dist/agent/wake-cycle-tool-tracker.d.ts.map +0 -1
  276. package/dist/agent/wake-cycle-tool-tracker.js +0 -72
  277. package/dist/agent/wake-cycle-tool-tracker.js.map +0 -1
  278. package/dist/billing/payg-handler.d.ts +0 -29
  279. package/dist/billing/payg-handler.d.ts.map +0 -1
  280. package/dist/billing/payg-handler.js +0 -92
  281. package/dist/billing/payg-handler.js.map +0 -1
  282. package/dist/billing/payment-handler.d.ts +0 -24
  283. package/dist/billing/payment-handler.d.ts.map +0 -1
  284. package/dist/billing/payment-handler.js +0 -101
  285. package/dist/billing/payment-handler.js.map +0 -1
  286. package/dist/builtin-skills/catalog/phone-adb-automation/SKILL.md +0 -412
  287. package/dist/builtin-skills/catalog/phone-adb-automation/phone_input.sh +0 -132
  288. package/dist/builtin-skills/catalog/phone-adb-automation/phone_launch.sh +0 -166
  289. package/dist/builtin-skills/catalog/phone-adb-automation/phone_screenshot.sh +0 -87
  290. package/dist/builtin-skills/catalog/phone-adb-automation/phone_security_kbd.py +0 -174
  291. package/dist/builtin-skills/catalog/phone-adb-automation/phone_setup.sh +0 -274
  292. package/dist/builtin-skills/catalog/phone-adb-automation/phone_swipe.sh +0 -111
  293. package/dist/builtin-skills/catalog/phone-adb-automation/phone_tap.sh +0 -87
  294. package/dist/builtin-skills/catalog/phone-adb-automation/phone_ui_parse.py +0 -176
  295. package/dist/builtin-skills/catalog/phone-adb-automation/phone_wake_unlock.sh +0 -67
  296. package/dist/builtin-skills/transcribe-audio/SKILL.md +0 -122
  297. package/dist/data-processing/convert-demo-cli.d.ts +0 -7
  298. package/dist/data-processing/convert-demo-cli.d.ts.map +0 -1
  299. package/dist/data-processing/convert-demo-cli.js +0 -30
  300. package/dist/data-processing/convert-demo-cli.js.map +0 -1
  301. package/dist/data-processing/convert-demo.d.ts +0 -26
  302. package/dist/data-processing/convert-demo.d.ts.map +0 -1
  303. package/dist/data-processing/convert-demo.js +0 -233
  304. package/dist/data-processing/convert-demo.js.map +0 -1
  305. package/dist/obs/rdp/icons/icons/app_windows.svg +0 -4
  306. package/dist/obs/rdp/icons/icons/clip_get.svg +0 -4
  307. package/dist/obs/rdp/icons/icons/clip_send.svg +0 -4
  308. package/dist/obs/rdp/icons/icons/clip_shared.svg +0 -4
  309. package/dist/obs/rdp/icons/icons/clipboard.svg +0 -4
  310. package/dist/obs/rdp/icons/icons/clipboard_shared.svg +0 -4
  311. package/dist/obs/rdp/icons/icons/control.svg +0 -4
  312. package/dist/obs/rdp/icons/icons/desktop.svg +0 -4
  313. package/dist/obs/rdp/icons/icons/display.svg +0 -4
  314. package/dist/obs/rdp/icons/icons/launchpad.svg +0 -4
  315. package/dist/obs/rdp/icons/icons/mission_control.svg +0 -4
  316. package/dist/obs/rdp/icons/icons/screenshot.svg +0 -4
  317. package/dist/obs/rdp/icons/icons/zoom_actual.svg +0 -4
  318. package/dist/obs/rdp/icons/icons/zoom_fit.svg +0 -4
  319. package/dist/obs/rdp/icons/icons/zoom_in.svg +0 -4
  320. package/dist/obs/rdp/icons/icons/zoom_out.svg +0 -4
  321. package/dist/obs/tunnel-telemetry.d.ts +0 -46
  322. package/dist/obs/tunnel-telemetry.d.ts.map +0 -1
  323. package/dist/obs/tunnel-telemetry.js +0 -70
  324. package/dist/obs/tunnel-telemetry.js.map +0 -1
  325. package/dist/onboarding/cloudflared-cert.d.ts +0 -15
  326. package/dist/onboarding/cloudflared-cert.d.ts.map +0 -1
  327. package/dist/onboarding/cloudflared-cert.js +0 -57
  328. package/dist/onboarding/cloudflared-cert.js.map +0 -1
  329. package/dist/onboarding/playwriter-extension.d.ts +0 -19
  330. package/dist/onboarding/playwriter-extension.d.ts.map +0 -1
  331. package/dist/onboarding/playwriter-extension.js +0 -246
  332. package/dist/onboarding/playwriter-extension.js.map +0 -1
  333. package/dist/service/gbox-tun.d.ts +0 -14
  334. package/dist/service/gbox-tun.d.ts.map +0 -1
  335. package/dist/service/gbox-tun.js +0 -315
  336. package/dist/service/gbox-tun.js.map +0 -1
  337. package/dist/skills/installed.d.ts +0 -11
  338. package/dist/skills/installed.d.ts.map +0 -1
  339. package/dist/skills/installed.js +0 -35
  340. package/dist/skills/installed.js.map +0 -1
  341. package/dist/tools/coordinate-resolver.d.ts +0 -30
  342. package/dist/tools/coordinate-resolver.d.ts.map +0 -1
  343. package/dist/tools/coordinate-resolver.js +0 -104
  344. package/dist/tools/coordinate-resolver.js.map +0 -1
  345. package/dist/utils/playwriter-relay.d.ts +0 -9
  346. package/dist/utils/playwriter-relay.d.ts.map +0 -1
  347. package/dist/utils/playwriter-relay.js +0 -77
  348. package/dist/utils/playwriter-relay.js.map +0 -1
  349. package/dist/utils/wechat-monitor.d.ts +0 -21
  350. package/dist/utils/wechat-monitor.d.ts.map +0 -1
  351. package/dist/utils/wechat-monitor.js +0 -88
  352. package/dist/utils/wechat-monitor.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/realtime/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,630 @@
1
+ /* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
2
+ /* eslint-disable @typescript-eslint/explicit-function-return-type */
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+ import { logger } from "../logger.js";
6
+ import { getConfigDir } from "../config/index.js";
7
+ import { GoogleCalendarClient } from "../calendar/google-calendar.js";
8
+ import { GmailEmailClient } from "../email/gmail-email.js";
9
+ import { queryStockData } from "../tools/stock-data.js";
10
+ import { executeMemoryCommand } from "../tools/memory.js";
11
+ import { resolveSerpApiKey } from "../serpapi-credentials.js";
12
+ export const TOOLS = [
13
+ {
14
+ type: "function",
15
+ name: "manage_calendar",
16
+ description: "Manage Google Calendar with one consolidated tool: list, create, update, delete events, and find free time. Confirm with the owner before creating, updating, or deleting events.",
17
+ parameters: {
18
+ type: "object",
19
+ properties: {
20
+ action: { type: "string", enum: ["list_events", "create_event", "update_event", "delete_event", "find_free_time"], description: "Calendar action to perform." },
21
+ event_id: { type: "string", description: "Event ID for update_event or delete_event." },
22
+ summary: { type: "string", description: "Event title/summary for create_event or update_event." },
23
+ description: { type: "string", description: "Event description." },
24
+ location: { type: "string", description: "Event location." },
25
+ start: { type: "string", description: "Start datetime in ISO 8601 format with timezone offset." },
26
+ end: { type: "string", description: "End datetime in ISO 8601 format with timezone offset." },
27
+ recurrence: { type: "string", description: "RRULE recurrence string for create_event." },
28
+ attendees: { type: "array", items: { type: "string" }, description: "Attendee email addresses." },
29
+ max_results: { type: "number", description: "Maximum events/free slots to return, clamped to 1-10." },
30
+ },
31
+ required: ["action"],
32
+ },
33
+ },
34
+ {
35
+ type: "function",
36
+ name: "web_search",
37
+ description: "General Google web search. Use for general questions, weather, sports scores, places, facts, definitions, people, or anything you do not have a more specific category for. Returns answer_box / knowledge_graph / top organic results.",
38
+ parameters: {
39
+ type: "object",
40
+ properties: {
41
+ query: { type: "string", description: "The search query." },
42
+ num: { type: "number", description: "Number of organic results to return, clamped to 1-5. Defaults to 3." },
43
+ },
44
+ required: ["query"],
45
+ },
46
+ },
47
+ {
48
+ type: "function",
49
+ name: "news_search",
50
+ description: "Google News search. Use for recent news, current events, and time-sensitive headlines. Returns top news items with title, source, date, and snippet.",
51
+ parameters: {
52
+ type: "object",
53
+ properties: {
54
+ query: { type: "string", description: "The news search query." },
55
+ num: { type: "number", description: "Number of news results, clamped to 1-5. Defaults to 3." },
56
+ },
57
+ required: ["query"],
58
+ },
59
+ },
60
+ {
61
+ type: "function",
62
+ name: "hotel_search",
63
+ description: "Google Hotels search via SerpAPI. Use for hotel availability, prices, and ratings on specific dates. Requires destination plus check-in and check-out dates.",
64
+ parameters: {
65
+ type: "object",
66
+ properties: {
67
+ query: { type: "string", description: "Destination, e.g. 'Tokyo', 'Hyatt Regency San Francisco', 'hotels near Eiffel Tower'." },
68
+ check_in_date: { type: "string", description: "Check-in date in YYYY-MM-DD format." },
69
+ check_out_date: { type: "string", description: "Check-out date in YYYY-MM-DD format." },
70
+ adults: { type: "number", description: "Number of adults, clamped to 1-10. Defaults to 2." },
71
+ currency: { type: "string", description: "ISO 4217 currency code, e.g. USD, CNY, JPY. Defaults to USD." },
72
+ num: { type: "number", description: "Number of hotel results to return, clamped to 1-5. Defaults to 5." },
73
+ },
74
+ required: ["query", "check_in_date", "check_out_date"],
75
+ },
76
+ },
77
+ {
78
+ type: "function",
79
+ name: "flight_search",
80
+ description: "Google Flights search via SerpAPI. Use for flight availability and prices between two airports. Use IATA codes for departure_id and arrival_id (e.g. SFO, JFK, PEK). Return type defaults to one-way.",
81
+ parameters: {
82
+ type: "object",
83
+ properties: {
84
+ departure_id: { type: "string", description: "Departure airport IATA code, e.g. SFO, JFK, PEK." },
85
+ arrival_id: { type: "string", description: "Arrival airport IATA code, e.g. NRT, LAX, SHA." },
86
+ outbound_date: { type: "string", description: "Outbound date in YYYY-MM-DD format." },
87
+ return_date: { type: "string", description: "Return date in YYYY-MM-DD format. Required for round-trip." },
88
+ trip_type: { type: "string", enum: ["one_way", "round_trip"], description: "Trip type. Defaults to one_way." },
89
+ adults: { type: "number", description: "Number of adults, clamped to 1-9. Defaults to 1." },
90
+ currency: { type: "string", description: "ISO 4217 currency code. Defaults to USD." },
91
+ num: { type: "number", description: "Number of flight options to return, clamped to 1-5. Defaults to 5." },
92
+ },
93
+ required: ["departure_id", "arrival_id", "outbound_date"],
94
+ },
95
+ },
96
+ {
97
+ type: "function",
98
+ name: "finance_search",
99
+ description: "Google Finance lookup via SerpAPI. Use for indices, currencies, crypto, or when get_stock_quote does not cover the market. The query must be a SerpAPI Finance ticker, e.g. 'AAPL:NASDAQ', '600519:SHA', '.INX:INDEXSP', 'BTC-USD'.",
100
+ parameters: {
101
+ type: "object",
102
+ properties: {
103
+ query: { type: "string", description: "SerpAPI Finance ticker. Format <symbol>:<exchange>, e.g. AAPL:NASDAQ, MSFT:NASDAQ, 600519:SHA, .INX:INDEXSP." },
104
+ },
105
+ required: ["query"],
106
+ },
107
+ },
108
+ {
109
+ type: "function",
110
+ name: "local_search",
111
+ description: "Search nearby points of interest on Google (restaurants, banks, ATMs, cafes, hospitals, gas stations, hotels nearby, etc.). Returns the local 3-pack-style results with name, type, address, rating, reviews, phone, and hours. Always ask the owner for a location if you do not already know it.",
112
+ parameters: {
113
+ type: "object",
114
+ properties: {
115
+ query: { type: "string", description: "What to look for, e.g. 'ramen', 'ATM', 'pediatrician', 'gas station'." },
116
+ location: { type: "string", description: "Free-text location for the search, e.g. 'Austin, Texas, United States' or 'Shibuya, Tokyo'. Required." },
117
+ num: { type: "number", description: "Number of local results to return, clamped to 1-5. Defaults to 3." },
118
+ },
119
+ required: ["query", "location"],
120
+ },
121
+ },
122
+ {
123
+ type: "function",
124
+ name: "manage_email",
125
+ description: "Minimal Gmail tool for voice: list recent inbox emails (titles + snippets only) or send a plain-text email. Always confirm with the owner before sending.",
126
+ parameters: {
127
+ type: "object",
128
+ properties: {
129
+ action: { type: "string", enum: ["list", "send"], description: "Email action: list recent inbox messages, or send a new plain-text email." },
130
+ unread_only: { type: "boolean", description: "For list: only include unread emails. Defaults to false." },
131
+ num: { type: "number", description: "For list: number of recent messages to return, clamped to 1-10. Defaults to 5." },
132
+ to: { type: "string", description: "For send: recipient email address." },
133
+ subject: { type: "string", description: "For send: email subject." },
134
+ body: { type: "string", description: "For send: plain-text email body." },
135
+ },
136
+ required: ["action"],
137
+ },
138
+ },
139
+ {
140
+ type: "function",
141
+ name: "memory",
142
+ description: "Persistent memory storage under /memories. Use to view, create, edit, rename, or delete memory files. Confirm with the owner before creating, editing, renaming, or deleting memories.",
143
+ parameters: {
144
+ type: "object",
145
+ properties: {
146
+ command: { type: "string", enum: ["view", "create", "str_replace", "insert", "delete", "rename"], description: "Memory command to execute." },
147
+ path: { type: "string", description: "Path starting with /memories, e.g. /memories/notes.txt." },
148
+ file_text: { type: "string", description: "File content for create." },
149
+ old_str: { type: "string", description: "Text to find for str_replace." },
150
+ new_str: { type: "string", description: "Replacement text for str_replace." },
151
+ insert_line: { type: "number", description: "0-indexed line number for insert." },
152
+ insert_text: { type: "string", description: "Text to insert." },
153
+ view_range: { type: "array", items: { type: "number" }, minItems: 2, maxItems: 2, description: "Line range [start, end], -1 for end of file." },
154
+ old_path: { type: "string", description: "Source path for rename." },
155
+ new_path: { type: "string", description: "Destination path for rename." },
156
+ },
157
+ required: ["command"],
158
+ },
159
+ },
160
+ {
161
+ type: "function",
162
+ name: "get_stock_quote",
163
+ description: "Get a real-time stock quote for one or more tickers across A-shares, HK, and US markets. Returns current price, change, and percent change only — no history or fundamentals. Use finance_search if you need richer Google Finance data (e.g. crypto, indices, FX).",
164
+ parameters: {
165
+ type: "object",
166
+ properties: {
167
+ symbols: { type: "string", description: "One ticker or a comma-separated list. Examples: 'AAPL', '600519', '0700.HK', 'AAPL,TSLA'." },
168
+ },
169
+ required: ["symbols"],
170
+ },
171
+ },
172
+ {
173
+ type: "function",
174
+ name: "send_telegram_message",
175
+ description: "Send a Telegram message to the owner. Use when the owner asks to send a text, note, or reminder to themselves or to notify them about something.",
176
+ parameters: { type: "object", properties: { message: { type: "string" } }, required: ["message"] },
177
+ },
178
+ {
179
+ type: "function",
180
+ name: "set_reminder",
181
+ description: "Set a quick reminder by creating a calendar event at the specified timezone-aware ISO 8601 time.",
182
+ parameters: { type: "object", properties: { reminder: { type: "string" }, time: { type: "string", description: "Absolute reminder time in ISO 8601 format with timezone offset." } }, required: ["reminder", "time"] },
183
+ },
184
+ ];
185
+ let _calendarClient = null;
186
+ function getCalendarClient(config) {
187
+ if (!_calendarClient)
188
+ _calendarClient = new GoogleCalendarClient(config);
189
+ return _calendarClient;
190
+ }
191
+ let _emailClient = null;
192
+ function getEmailClient(config) {
193
+ if (!_emailClient)
194
+ _emailClient = new GmailEmailClient(config);
195
+ return _emailClient;
196
+ }
197
+ function clampInt(value, min, max, fallback) {
198
+ const parsed = typeof value === "number" ? value : Number(value);
199
+ if (!Number.isFinite(parsed))
200
+ return fallback;
201
+ return Math.min(max, Math.max(min, Math.trunc(parsed)));
202
+ }
203
+ function requireIsoDateTime(value, field) {
204
+ if (!value || !/^\d{4}-\d{2}-\d{2}T/.test(value) || !/(Z|[+-]\d{2}:\d{2})$/.test(value)) {
205
+ throw new Error(`${field} must be an ISO 8601 datetime with timezone offset`);
206
+ }
207
+ const parsed = new Date(value);
208
+ if (Number.isNaN(parsed.getTime())) {
209
+ throw new Error(`${field} is not a valid datetime`);
210
+ }
211
+ return parsed;
212
+ }
213
+ const SENSITIVE_FIELDS = new Set(["body", "html_body", "message", "to", "cc", "bcc", "subject", "snippet", "file_text", "old_str", "new_str", "insert_text"]);
214
+ const SENSITIVE_TOOLS = new Set(["manage_email", "send_telegram_message", "memory"]);
215
+ export function redactRealtimeToolPayload(toolName, value) {
216
+ if (value === null || value === undefined)
217
+ return value;
218
+ if (typeof value !== "object")
219
+ return SENSITIVE_TOOLS.has(toolName) ? "[redacted]" : value;
220
+ if (Array.isArray(value))
221
+ return value.map((item) => redactRealtimeToolPayload(toolName, item));
222
+ const out = {};
223
+ for (const [key, child] of Object.entries(value)) {
224
+ if (SENSITIVE_TOOLS.has(toolName) || SENSITIVE_FIELDS.has(key)) {
225
+ out[key] = typeof child === "string" ? `[redacted:${child.length} chars]` : "[redacted]";
226
+ }
227
+ else {
228
+ out[key] = redactRealtimeToolPayload(toolName, child);
229
+ }
230
+ }
231
+ return out;
232
+ }
233
+ async function manageCalendar(config, args) {
234
+ const cal = getCalendarClient(config);
235
+ const action = args.action ?? "list_events";
236
+ switch (action) {
237
+ case "list_events": {
238
+ const timeMin = args.start ? requireIsoDateTime(args.start, "start") : new Date();
239
+ const timeMax = args.end ? requireIsoDateTime(args.end, "end") : new Date(timeMin.getTime() + 7 * 86400000);
240
+ const maxResults = clampInt(args.max_results, 1, 10, 5);
241
+ const events = await cal.listUpcomingEvents(timeMin, timeMax, maxResults);
242
+ return events.map((e) => ({
243
+ id: e.id,
244
+ summary: e.summary,
245
+ start: e.start?.dateTime || e.start?.date,
246
+ end: e.end?.dateTime || e.end?.date,
247
+ location: e.location || null,
248
+ description: e.description || null,
249
+ }));
250
+ }
251
+ case "create_event": {
252
+ if (!args.summary || !args.start || !args.end)
253
+ return { error: "summary, start, and end are required for create_event" };
254
+ const event = await cal.createEvent({
255
+ summary: args.summary,
256
+ description: args.description || "",
257
+ location: args.location || undefined,
258
+ start: requireIsoDateTime(args.start, "start"),
259
+ end: requireIsoDateTime(args.end, "end"),
260
+ recurrence: args.recurrence ? [args.recurrence] : undefined,
261
+ attendees: args.attendees,
262
+ });
263
+ return { id: event.id, summary: event.summary, start: event.start?.dateTime, end: event.end?.dateTime, location: event.location, htmlLink: event.htmlLink };
264
+ }
265
+ case "update_event": {
266
+ if (!args.event_id)
267
+ return { error: "event_id is required for update_event" };
268
+ const updates = {};
269
+ if (args.summary)
270
+ updates.summary = args.summary;
271
+ if (args.description)
272
+ updates.description = args.description;
273
+ if (args.location)
274
+ updates.location = args.location;
275
+ if (args.start)
276
+ updates.start = requireIsoDateTime(args.start, "start");
277
+ if (args.end)
278
+ updates.end = requireIsoDateTime(args.end, "end");
279
+ if (args.attendees)
280
+ updates.attendees = args.attendees;
281
+ const event = await cal.updateEvent(args.event_id, updates);
282
+ return { id: event.id, summary: event.summary, start: event.start?.dateTime || event.start?.date, end: event.end?.dateTime || event.end?.date, location: event.location, updated: true };
283
+ }
284
+ case "delete_event": {
285
+ if (!args.event_id)
286
+ return { error: "event_id is required for delete_event" };
287
+ await cal.deleteEvent(args.event_id);
288
+ return { deleted: true, eventId: args.event_id };
289
+ }
290
+ case "find_free_time": {
291
+ const timeMin = args.start ? requireIsoDateTime(args.start, "start") : new Date();
292
+ const timeMax = args.end ? requireIsoDateTime(args.end, "end") : new Date(timeMin.getTime() + 86400000);
293
+ return (await cal.findFreeTime(timeMin, timeMax)).slice(0, clampInt(args.max_results, 1, 10, 5));
294
+ }
295
+ default:
296
+ return { error: `Unknown calendar action: ${action}` };
297
+ }
298
+ }
299
+ async function manageEmail(config, args) {
300
+ const email = getEmailClient(config);
301
+ const action = args.action ?? "list";
302
+ switch (action) {
303
+ case "list": {
304
+ const maxResults = clampInt(args.num, 1, 10, 5);
305
+ const messages = await email.listEmails({ label: "INBOX", unreadOnly: args.unread_only ?? false, maxResults });
306
+ return messages.map((m) => ({ from: m.from, subject: m.subject, date: m.date, unread: m.labels?.includes("UNREAD") ?? false, snippet: m.snippet }));
307
+ }
308
+ case "send": {
309
+ if (!args.to || !args.subject || !args.body)
310
+ return { error: "to, subject, and body are required for send" };
311
+ const result = await email.sendEmail({ to: args.to, subject: args.subject, body: args.body });
312
+ return { sent: true, messageId: result.id, to: args.to, subject: args.subject };
313
+ }
314
+ default:
315
+ return { error: `Unknown email action: ${action}` };
316
+ }
317
+ }
318
+ function memory(args) {
319
+ const result = executeMemoryCommand(args);
320
+ const text = result.content.filter((item) => item.type === "text").map((item) => item.text).join("\n");
321
+ return result.isError ? { error: text } : { result: text };
322
+ }
323
+ /**
324
+ * Pick the SerpAPI HTTP base URL based on the shape of the key. Mirrors the
325
+ * routing in `src/agent/runtime-surface.ts#buildSerpApiMcpUrl` but for the
326
+ * REST `/search` endpoint instead of the MCP endpoint:
327
+ *
328
+ * - 32 lowercase hex chars: per-agent APIM key, served by Azure APIM
329
+ * (`https://visionclaw-serpapi.azure-api.net/search`).
330
+ * - Otherwise: a direct serpapi.com key (legacy / shared / BYO), served by
331
+ * SerpAPI itself (`https://serpapi.com/search`).
332
+ */
333
+ function buildSerpApiSearchBaseUrl(apiKey) {
334
+ if (/^[0-9a-f]{32}$/.test(apiKey)) {
335
+ return "https://visionclaw-serpapi.azure-api.net/search";
336
+ }
337
+ return "https://serpapi.com/search";
338
+ }
339
+ function stringifyError(value) {
340
+ if (typeof value === "string")
341
+ return value;
342
+ if (value && typeof value === "object") {
343
+ try {
344
+ return JSON.stringify(value);
345
+ }
346
+ catch {
347
+ return "Unknown error";
348
+ }
349
+ }
350
+ return String(value);
351
+ }
352
+ async function callSerpApi(serpApiKey, params) {
353
+ const baseUrl = buildSerpApiSearchBaseUrl(serpApiKey);
354
+ const usp = new URLSearchParams({ ...params, api_key: serpApiKey });
355
+ const res = await fetch(`${baseUrl}?${usp.toString()}`, { headers: { Accept: "application/json" } });
356
+ if (!res.ok)
357
+ throw new Error(`SerpAPI error: ${res.status} ${await res.text()}`);
358
+ return await res.json();
359
+ }
360
+ export async function webSearch(serpApiKey, args) {
361
+ const num = clampInt(args.num, 1, 5, 3);
362
+ const data = await callSerpApi(serpApiKey, { engine: "google", q: args.query, num: String(num) });
363
+ const results = [];
364
+ if (data.answer_box) {
365
+ const ab = data.answer_box;
366
+ results.push({ answer: ab.answer || ab.snippet || ab.result, title: ab.title });
367
+ }
368
+ if (data.knowledge_graph) {
369
+ const kg = data.knowledge_graph;
370
+ results.push({ entity: kg.title, description: kg.description });
371
+ }
372
+ const organic = (data.organic_results ?? [])
373
+ .slice(0, num)
374
+ .map((r) => ({ title: r.title, snippet: r.snippet, link: r.link }));
375
+ if (organic.length)
376
+ results.push(...organic);
377
+ if (data.weather_result) {
378
+ const w = data.weather_result;
379
+ results.push({ weather: true, location: w.location, temperature: w.temperature, unit: w.unit, description: w.description, humidity: w.humidity, wind: w.wind });
380
+ }
381
+ if (data.sports_results)
382
+ results.push({ sports: true, ...data.sports_results });
383
+ return results.length ? results : { message: "No results found" };
384
+ }
385
+ export async function newsSearch(serpApiKey, args) {
386
+ const num = clampInt(args.num, 1, 5, 3);
387
+ const data = await callSerpApi(serpApiKey, { engine: "google_news", q: args.query });
388
+ const items = (data.news_results ?? [])
389
+ .slice(0, num)
390
+ .map((n) => ({
391
+ title: n.title,
392
+ source: n.source?.name ?? n.source,
393
+ date: n.date,
394
+ snippet: n.snippet,
395
+ link: n.link,
396
+ }));
397
+ return items.length ? items : { message: "No news results found" };
398
+ }
399
+ export async function hotelSearch(serpApiKey, args) {
400
+ const num = clampInt(args.num, 1, 5, 5);
401
+ const adults = clampInt(args.adults, 1, 10, 2);
402
+ const data = await callSerpApi(serpApiKey, {
403
+ engine: "google_hotels",
404
+ q: args.query,
405
+ check_in_date: args.check_in_date,
406
+ check_out_date: args.check_out_date,
407
+ adults: String(adults),
408
+ currency: args.currency || "USD",
409
+ });
410
+ if (data.error)
411
+ return { error: stringifyError(data.error) };
412
+ const properties = (data.properties ?? [])
413
+ .slice(0, num)
414
+ .map((p) => ({
415
+ name: p.name,
416
+ type: p.type,
417
+ rate_per_night: p.rate_per_night?.lowest,
418
+ total_rate: p.total_rate?.lowest,
419
+ currency: p.rate_per_night?.currency,
420
+ overall_rating: p.overall_rating,
421
+ reviews: p.reviews,
422
+ check_in_time: p.check_in_time,
423
+ check_out_time: p.check_out_time,
424
+ link: p.link,
425
+ }));
426
+ return properties.length ? properties : { message: "No hotels found" };
427
+ }
428
+ export async function flightSearch(serpApiKey, args) {
429
+ const num = clampInt(args.num, 1, 5, 5);
430
+ const adults = clampInt(args.adults, 1, 9, 1);
431
+ const tripType = args.trip_type === "round_trip" ? "1" : "2"; // 1 = round-trip, 2 = one-way in SerpAPI
432
+ if (args.trip_type === "round_trip" && !args.return_date) {
433
+ return { error: "return_date is required when trip_type is round_trip" };
434
+ }
435
+ const params = {
436
+ engine: "google_flights",
437
+ departure_id: args.departure_id,
438
+ arrival_id: args.arrival_id,
439
+ outbound_date: args.outbound_date,
440
+ adults: String(adults),
441
+ currency: args.currency || "USD",
442
+ type: tripType,
443
+ };
444
+ if (args.return_date)
445
+ params.return_date = args.return_date;
446
+ const data = await callSerpApi(serpApiKey, params);
447
+ if (data.error)
448
+ return { error: stringifyError(data.error) };
449
+ const best = data.best_flights ?? [];
450
+ const other = data.other_flights ?? [];
451
+ const all = [...best, ...other].slice(0, num).map((opt) => {
452
+ const legs = (opt.flights ?? []).map((leg) => ({
453
+ airline: leg.airline,
454
+ flight_number: leg.flight_number,
455
+ departure_airport: leg.departure_airport?.id,
456
+ departure_time: leg.departure_airport?.time,
457
+ arrival_airport: leg.arrival_airport?.id,
458
+ arrival_time: leg.arrival_airport?.time,
459
+ duration_min: leg.duration,
460
+ }));
461
+ return {
462
+ price: opt.price,
463
+ total_duration_min: opt.total_duration,
464
+ stops: Math.max(0, legs.length - 1),
465
+ legs,
466
+ };
467
+ });
468
+ return all.length ? all : { message: "No flights found" };
469
+ }
470
+ export async function localSearch(serpApiKey, args) {
471
+ if (!args.location?.trim())
472
+ return { error: "location is required" };
473
+ const num = clampInt(args.num, 1, 5, 3);
474
+ const data = await callSerpApi(serpApiKey, {
475
+ engine: "google_local",
476
+ q: args.query,
477
+ location: args.location,
478
+ });
479
+ if (data.error)
480
+ return { error: stringifyError(data.error) };
481
+ // `local_results` is sometimes an array, sometimes { places: [...] } — handle both.
482
+ const lrRaw = data.local_results;
483
+ const list = Array.isArray(lrRaw)
484
+ ? lrRaw
485
+ : Array.isArray(lrRaw?.places)
486
+ ? (lrRaw.places)
487
+ : [];
488
+ const items = list.slice(0, num).map((p) => ({
489
+ title: p.title,
490
+ type: p.type,
491
+ address: p.address,
492
+ rating: p.rating,
493
+ reviews: p.reviews,
494
+ price: p.price,
495
+ phone: p.phone,
496
+ hours: p.hours,
497
+ description: p.description,
498
+ gps_coordinates: p.gps_coordinates,
499
+ link: p.links ?? p.website,
500
+ }));
501
+ return items.length ? items : { message: "No local results found" };
502
+ }
503
+ export async function financeSearch(serpApiKey, args) {
504
+ const data = await callSerpApi(serpApiKey, { engine: "google_finance", q: args.query });
505
+ if (data.error)
506
+ return { message: stringifyError(data.error) };
507
+ const summary = data.summary;
508
+ const news = (data.news_results ?? []).slice(0, 3).map((n) => ({
509
+ title: n.title,
510
+ source: n.source?.name ?? n.source,
511
+ date: n.date,
512
+ link: n.link,
513
+ }));
514
+ return {
515
+ ticker: summary?.title,
516
+ stock: summary?.stock,
517
+ exchange: summary?.exchange,
518
+ price: summary?.price,
519
+ currency: summary?.currency,
520
+ price_movement: summary?.price_movement,
521
+ date: summary?.date,
522
+ market: summary?.market,
523
+ news,
524
+ };
525
+ }
526
+ async function getStockQuote(args) {
527
+ if (!args.symbols?.trim())
528
+ return { error: "symbols is required, e.g. 'AAPL' or 'AAPL,TSLA'" };
529
+ const result = await queryStockData({ action: "quote", symbols: args.symbols, market: "auto" });
530
+ const text = result.content
531
+ .filter((item) => item.type === "text")
532
+ .map((item) => item.text)
533
+ .join("\n");
534
+ if (result.isError)
535
+ return { error: text };
536
+ let parsed;
537
+ try {
538
+ parsed = JSON.parse(text);
539
+ }
540
+ catch {
541
+ return { result: text };
542
+ }
543
+ // queryStockData("quote") returns { quotes: [...], timestamp }.
544
+ // For voice we only return the essentials per quote.
545
+ const quotes = parsed?.quotes;
546
+ if (!Array.isArray(quotes))
547
+ return parsed;
548
+ return quotes.map((q) => {
549
+ const r = q;
550
+ return {
551
+ symbol: r.symbol,
552
+ name: r.name,
553
+ market: r.market,
554
+ price: r.price,
555
+ change: r.change,
556
+ change_pct: r.change_pct,
557
+ prev_close: r.prev_close,
558
+ };
559
+ });
560
+ }
561
+ async function sendTelegramMessage(botToken, chatId, args) {
562
+ const res = await fetch(`https://api.telegram.org/bot${botToken}/sendMessage`, {
563
+ method: "POST",
564
+ headers: { "Content-Type": "application/json" },
565
+ body: JSON.stringify({ chat_id: chatId, text: args.message }),
566
+ });
567
+ if (!res.ok)
568
+ throw new Error(`Telegram API error: ${res.status} ${await res.text()}`);
569
+ return { sent: true, message: args.message };
570
+ }
571
+ async function setReminder(config, args) {
572
+ const start = requireIsoDateTime(args.time, "time");
573
+ const endTime = new Date(start.getTime() + 15 * 60 * 1000).toISOString();
574
+ return await manageCalendar(config, { action: "create_event", summary: `Reminder: ${args.reminder}`, start: args.time, end: endTime, description: `Voice reminder set: ${args.reminder}` });
575
+ }
576
+ export async function executeTool(config, name, args) {
577
+ logger.system(`[Realtime] Executing tool: ${name}`);
578
+ try {
579
+ switch (name) {
580
+ case "manage_calendar": return await manageCalendar(config, args);
581
+ case "web_search":
582
+ case "news_search":
583
+ case "hotel_search":
584
+ case "flight_search":
585
+ case "finance_search":
586
+ case "local_search": {
587
+ const serpKey = resolveSerpApiKey(config);
588
+ if (!serpKey)
589
+ return { error: "SerpAPI key not configured" };
590
+ switch (name) {
591
+ case "web_search": return await webSearch(serpKey, args);
592
+ case "news_search": return await newsSearch(serpKey, args);
593
+ case "hotel_search": return await hotelSearch(serpKey, args);
594
+ case "flight_search": return await flightSearch(serpKey, args);
595
+ case "finance_search": return await financeSearch(serpKey, args);
596
+ case "local_search": return await localSearch(serpKey, args);
597
+ default: return { error: `Unknown search tool: ${String(name)}` };
598
+ }
599
+ }
600
+ case "manage_email": return await manageEmail(config, args);
601
+ case "memory": return memory(args);
602
+ case "get_stock_quote": return await getStockQuote(args);
603
+ case "send_telegram_message": {
604
+ const bt = config.channels.telegram?.botToken;
605
+ let chatId = config.channels.telegram?.chatId;
606
+ if (!chatId) {
607
+ try {
608
+ const ownerPath = path.join(getConfigDir(), "owner.json");
609
+ if (fs.existsSync(ownerPath)) {
610
+ const ownerChatId = JSON.parse(fs.readFileSync(ownerPath, "utf-8")).telegramChatId;
611
+ chatId = typeof ownerChatId === "number" || typeof ownerChatId === "string" ? String(ownerChatId) : "";
612
+ }
613
+ }
614
+ catch { /* ignore */ }
615
+ }
616
+ if (!bt || !chatId)
617
+ return { error: "Telegram not configured" };
618
+ return await sendTelegramMessage(bt, chatId, args);
619
+ }
620
+ case "set_reminder": return await setReminder(config, args);
621
+ default: return { error: `Unknown tool: ${name}` };
622
+ }
623
+ }
624
+ catch (err) {
625
+ const msg = err instanceof Error ? err.message : String(err);
626
+ logger.warn(`[Realtime] Tool error (${name}): ${msg}`);
627
+ return { error: msg };
628
+ }
629
+ }
630
+ //# sourceMappingURL=tools.js.map