mindroot 9.22.0__py3-none-any.whl → 10.14.0__py3-none-any.whl

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 (331) hide show
  1. mindroot/coreplugins/admin/static/js/agent-form.js +26 -1
  2. mindroot/coreplugins/admin/static/js/persona-editor.js +14 -1
  3. mindroot/coreplugins/agent/agent.py +59 -18
  4. mindroot/coreplugins/agent/agent.py.bak +507 -0
  5. mindroot/coreplugins/agent/buagentz1.py +540 -0
  6. mindroot/coreplugins/agent/speech_to_speech.py +77 -0
  7. mindroot/coreplugins/agent/speech_to_speech.py.backup +46 -0
  8. mindroot/coreplugins/chat/buservices.py +625 -0
  9. mindroot/coreplugins/chat/buwidget_routes.py +287 -0
  10. mindroot/coreplugins/chat/commands.py +4 -0
  11. mindroot/coreplugins/chat/services.py +178 -8
  12. mindroot/coreplugins/chat/static/css/dark.css +90 -1
  13. mindroot/coreplugins/chat/static/css/default.css +90 -1
  14. mindroot/coreplugins/chat/static/css/light.css +724 -0
  15. mindroot/coreplugins/chat/static/css/mobile.css +37 -0
  16. mindroot/coreplugins/chat/static/js/chat.js +150 -89
  17. mindroot/coreplugins/chat/static/js/chatform.js +1 -1
  18. mindroot/coreplugins/chat/static/js/throttle.js +4 -2
  19. mindroot/coreplugins/chat/templates/chat.jinja2 +9 -1
  20. mindroot/coreplugins/chat/widget_routes.py +54 -10
  21. mindroot/coreplugins/check_list/helpers.py +221 -0
  22. mindroot/coreplugins/check_list/mod.py +435 -126
  23. mindroot/coreplugins/check_list/mod.py.backup +378 -0
  24. mindroot/coreplugins/check_list/mod.py.backup2 +506 -0
  25. mindroot/coreplugins/check_list/mod.py.backup3 +506 -0
  26. mindroot/coreplugins/check_list/mod_create_checklist_lol.py +756 -0
  27. mindroot/coreplugins/check_list/plugin_info.json +15 -0
  28. mindroot/coreplugins/jwt_auth/middleware.py +1 -1
  29. mindroot/docs/.env +1 -0
  30. mindroot/docs/.gitignore +1 -0
  31. mindroot/docs/_build/doctrees/chat_with_assistant.doctree +0 -0
  32. mindroot/docs/_build/doctrees/developer_documentation.doctree +0 -0
  33. mindroot/docs/_build/doctrees/embed_chat.doctree +0 -0
  34. mindroot/docs/_build/doctrees/environment.pickle +0 -0
  35. mindroot/docs/_build/doctrees/getting_started.doctree +0 -0
  36. mindroot/docs/_build/doctrees/index.doctree +0 -0
  37. mindroot/docs/_build/doctrees/install_plugins_with_tools.doctree +0 -0
  38. mindroot/docs/_build/doctrees/installation.doctree +0 -0
  39. mindroot/docs/_build/doctrees/llm_api_key.doctree +0 -0
  40. mindroot/docs/_build/doctrees/llm_plugin_installation.doctree +0 -0
  41. mindroot/docs/_build/doctrees/programming_task.doctree +0 -0
  42. mindroot/docs/_build/doctrees/source/ahp.doctree +0 -0
  43. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.admin.doctree +0 -0
  44. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.api_keys.doctree +0 -0
  45. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.chat.doctree +0 -0
  46. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.chat_avatar.doctree +0 -0
  47. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.check_list.doctree +0 -0
  48. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.credits.doctree +0 -0
  49. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.doctree +0 -0
  50. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.email.doctree +0 -0
  51. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.env_manager.doctree +0 -0
  52. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.events.doctree +0 -0
  53. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.index.doctree +0 -0
  54. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.index.handlers.doctree +0 -0
  55. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.jwt_auth.doctree +0 -0
  56. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.l8n.doctree +0 -0
  57. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.mcp_.doctree +0 -0
  58. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.persona.doctree +0 -0
  59. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.startup.doctree +0 -0
  60. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.subscriptions.doctree +0 -0
  61. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.usage.doctree +0 -0
  62. mindroot/docs/_build/doctrees/source/mindroot.coreplugins.user_service.doctree +0 -0
  63. mindroot/docs/_build/doctrees/source/mindroot.doctree +0 -0
  64. mindroot/docs/_build/doctrees/source/mindroot.lib.auth.doctree +0 -0
  65. mindroot/docs/_build/doctrees/source/mindroot.lib.doctree +0 -0
  66. mindroot/docs/_build/doctrees/source/mindroot.lib.json_str_block.doctree +0 -0
  67. mindroot/docs/_build/doctrees/source/mindroot.lib.plugins.doctree +0 -0
  68. mindroot/docs/_build/doctrees/source/mindroot.lib.providers.backup.doctree +0 -0
  69. mindroot/docs/_build/doctrees/source/mindroot.lib.providers.doctree +0 -0
  70. mindroot/docs/_build/doctrees/source/mindroot.registry.doctree +0 -0
  71. mindroot/docs/_build/doctrees/source/modules.doctree +0 -0
  72. mindroot/docs/_build/doctrees/source/mr_agent_expert_instr.doctree +0 -0
  73. mindroot/docs/_build/doctrees/starting_mindroot.doctree +0 -0
  74. mindroot/docs/_build/doctrees/user_documentation.doctree +0 -0
  75. mindroot/docs/_build/html/_images/apikey.png +0 -0
  76. mindroot/docs/_build/html/_images/chatwidgetx.png +0 -0
  77. mindroot/docs/_build/html/_images/disablechatavatar.png +0 -0
  78. mindroot/docs/_build/html/_images/widgetform.png +0 -0
  79. mindroot/docs/_build/html/_images/widgetonpage.png +0 -0
  80. mindroot/docs/_build/html/_modules/index.html +1 -0
  81. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/agent_importer.html +282 -86
  82. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/agent_router.html +281 -88
  83. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/asset_manager.html +280 -84
  84. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/command_router.html +281 -88
  85. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/mcp_catalog_routes.html +279 -86
  86. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/mcp_publish_routes.html +284 -91
  87. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/mcp_registry_routes.html +284 -91
  88. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/mcp_routes.html +281 -88
  89. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/mod.html +280 -84
  90. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/oauth_callback_router.html +280 -87
  91. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/persona_handler.html +282 -86
  92. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/persona_router.html +285 -89
  93. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/plugin_manager.html +281 -88
  94. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/plugin_router.html +280 -87
  95. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/plugin_routes.html +280 -87
  96. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/registry_settings_routes.html +280 -87
  97. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/router.html +281 -88
  98. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/server_router.html +280 -84
  99. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/service_models.html +280 -87
  100. mindroot/docs/_build/html/_modules/mindroot/coreplugins/admin/settings_router.html +288 -89
  101. mindroot/docs/_build/html/_modules/mindroot/coreplugins/api_keys/api_key_manager.html +280 -87
  102. mindroot/docs/_build/html/_modules/mindroot/coreplugins/api_keys/mod.html +279 -86
  103. mindroot/docs/_build/html/_modules/mindroot/coreplugins/api_keys/router.html +280 -87
  104. mindroot/docs/_build/html/_modules/mindroot/coreplugins/chat/commands.html +281 -88
  105. mindroot/docs/_build/html/_modules/mindroot/coreplugins/chat/mod.html +279 -86
  106. mindroot/docs/_build/html/_modules/mindroot/coreplugins/chat/models.html +280 -87
  107. mindroot/docs/_build/html/_modules/mindroot/coreplugins/chat/router.html +281 -88
  108. mindroot/docs/_build/html/_modules/mindroot/coreplugins/chat/services.html +283 -90
  109. mindroot/docs/_build/html/_modules/mindroot/coreplugins/chat/widget_manager.html +279 -86
  110. mindroot/docs/_build/html/_modules/mindroot/coreplugins/chat/widget_routes.html +279 -86
  111. mindroot/docs/_build/html/_modules/mindroot/coreplugins/check_list/mod.html +669 -213
  112. mindroot/docs/_build/html/_modules/mindroot/coreplugins/credits/conversion.html +280 -87
  113. mindroot/docs/_build/html/_modules/mindroot/coreplugins/credits/ledger.html +281 -88
  114. mindroot/docs/_build/html/_modules/mindroot/coreplugins/credits/mod.html +281 -88
  115. mindroot/docs/_build/html/_modules/mindroot/coreplugins/credits/models.html +279 -86
  116. mindroot/docs/_build/html/_modules/mindroot/coreplugins/credits/router.html +279 -86
  117. mindroot/docs/_build/html/_modules/mindroot/coreplugins/credits/storage.html +279 -86
  118. mindroot/docs/_build/html/_modules/mindroot/coreplugins/email/email_provider.html +280 -87
  119. mindroot/docs/_build/html/_modules/mindroot/coreplugins/email/imap_handler.html +284 -91
  120. mindroot/docs/_build/html/_modules/mindroot/coreplugins/email/mod.html +280 -87
  121. mindroot/docs/_build/html/_modules/mindroot/coreplugins/email/services.html +280 -87
  122. mindroot/docs/_build/html/_modules/mindroot/coreplugins/email/smtp_handler.html +280 -87
  123. mindroot/docs/_build/html/_modules/mindroot/coreplugins/email/test_email_service.html +280 -87
  124. mindroot/docs/_build/html/_modules/mindroot/coreplugins/env_manager/mod.html +281 -88
  125. mindroot/docs/_build/html/_modules/mindroot/coreplugins/env_manager/router.html +280 -87
  126. mindroot/docs/_build/html/_modules/mindroot/coreplugins/events/router.html +280 -87
  127. mindroot/docs/_build/html/_modules/mindroot/coreplugins/index/handlers/agent_ops.html +280 -87
  128. mindroot/docs/_build/html/_modules/mindroot/coreplugins/index/handlers/index_ops.html +280 -87
  129. mindroot/docs/_build/html/_modules/mindroot/coreplugins/index/handlers/plugin_ops.html +284 -91
  130. mindroot/docs/_build/html/_modules/mindroot/coreplugins/index/handlers/publish.html +281 -88
  131. mindroot/docs/_build/html/_modules/mindroot/coreplugins/index/mod.html +279 -86
  132. mindroot/docs/_build/html/_modules/mindroot/coreplugins/index/models.html +282 -86
  133. mindroot/docs/_build/html/_modules/mindroot/coreplugins/index/router.html +284 -91
  134. mindroot/docs/_build/html/_modules/mindroot/coreplugins/index/utils.html +282 -86
  135. mindroot/docs/_build/html/_modules/mindroot/coreplugins/jwt_auth/middleware.html +282 -89
  136. mindroot/docs/_build/html/_modules/mindroot/coreplugins/jwt_auth/mod.html +279 -86
  137. mindroot/docs/_build/html/_modules/mindroot/coreplugins/jwt_auth/router.html +280 -87
  138. mindroot/docs/_build/html/_modules/mindroot/coreplugins/l8n/language_detection.html +280 -84
  139. mindroot/docs/_build/html/_modules/mindroot/coreplugins/l8n/middleware.html +280 -84
  140. mindroot/docs/_build/html/_modules/mindroot/coreplugins/l8n/mod.html +282 -86
  141. mindroot/docs/_build/html/_modules/mindroot/coreplugins/l8n/test_enhanced.html +280 -84
  142. mindroot/docs/_build/html/_modules/mindroot/coreplugins/l8n/test_l8n_standalone.html +282 -86
  143. mindroot/docs/_build/html/_modules/mindroot/coreplugins/l8n/test_middleware.html +282 -86
  144. mindroot/docs/_build/html/_modules/mindroot/coreplugins/l8n/utils.html +280 -84
  145. mindroot/docs/_build/html/_modules/mindroot/coreplugins/mcp_/catalog_commands.html +282 -86
  146. mindroot/docs/_build/html/_modules/mindroot/coreplugins/mcp_/catalog_manager.html +280 -84
  147. mindroot/docs/_build/html/_modules/mindroot/coreplugins/mcp_/dynamic_commands.html +280 -84
  148. mindroot/docs/_build/html/_modules/mindroot/coreplugins/mcp_/mcp_manager.html +282 -86
  149. mindroot/docs/_build/html/_modules/mindroot/coreplugins/mcp_/mod.html +282 -86
  150. mindroot/docs/_build/html/_modules/mindroot/coreplugins/mcp_/oauth_storage.html +280 -84
  151. mindroot/docs/_build/html/_modules/mindroot/coreplugins/mcp_/server_installer.html +282 -86
  152. mindroot/docs/_build/html/_modules/mindroot/coreplugins/mcp_/testmcpclient.html +285 -89
  153. mindroot/docs/_build/html/_modules/mindroot/coreplugins/persona/init_persona.html +280 -84
  154. mindroot/docs/_build/html/_modules/mindroot/coreplugins/persona/mod.html +282 -86
  155. mindroot/docs/_build/html/_modules/mindroot/coreplugins/startup/mod.html +282 -86
  156. mindroot/docs/_build/html/_modules/mindroot/coreplugins/subscriptions/credit_integration.html +280 -84
  157. mindroot/docs/_build/html/_modules/mindroot/coreplugins/subscriptions/mod.html +282 -86
  158. mindroot/docs/_build/html/_modules/mindroot/coreplugins/subscriptions/models.html +280 -84
  159. mindroot/docs/_build/html/_modules/mindroot/coreplugins/subscriptions/router.html +285 -89
  160. mindroot/docs/_build/html/_modules/mindroot/coreplugins/subscriptions/storage.html +282 -86
  161. mindroot/docs/_build/html/_modules/mindroot/coreplugins/subscriptions/stripe_integration.html +280 -84
  162. mindroot/docs/_build/html/_modules/mindroot/coreplugins/subscriptions/subscription_manager.html +280 -84
  163. mindroot/docs/_build/html/_modules/mindroot/coreplugins/subscriptions/webhook_handler.html +280 -84
  164. mindroot/docs/_build/html/_modules/mindroot/coreplugins/usage/handlers.html +282 -86
  165. mindroot/docs/_build/html/_modules/mindroot/coreplugins/usage/mod.html +282 -86
  166. mindroot/docs/_build/html/_modules/mindroot/coreplugins/usage/models.html +282 -86
  167. mindroot/docs/_build/html/_modules/mindroot/coreplugins/usage/reporting.html +282 -86
  168. mindroot/docs/_build/html/_modules/mindroot/coreplugins/usage/router.html +282 -86
  169. mindroot/docs/_build/html/_modules/mindroot/coreplugins/usage/storage.html +285 -89
  170. mindroot/docs/_build/html/_modules/mindroot/coreplugins/user_service/admin_init.html +282 -86
  171. mindroot/docs/_build/html/_modules/mindroot/coreplugins/user_service/email_service.html +282 -86
  172. mindroot/docs/_build/html/_modules/mindroot/coreplugins/user_service/mod.html +280 -84
  173. mindroot/docs/_build/html/_modules/mindroot/coreplugins/user_service/models.html +282 -86
  174. mindroot/docs/_build/html/_modules/mindroot/coreplugins/user_service/password_reset_service.html +282 -86
  175. mindroot/docs/_build/html/_modules/mindroot/coreplugins/user_service/role_service.html +282 -86
  176. mindroot/docs/_build/html/_modules/mindroot/coreplugins/user_service/router.html +282 -86
  177. mindroot/docs/_build/html/_modules/mindroot/lib/auth/api_key.html +280 -84
  178. mindroot/docs/_build/html/_modules/mindroot/lib/auth/auth.html +282 -86
  179. mindroot/docs/_build/html/_modules/mindroot/lib/buchatlog.html +285 -89
  180. mindroot/docs/_build/html/_modules/mindroot/lib/buchatlog2.html +282 -86
  181. mindroot/docs/_build/html/_modules/mindroot/lib/butemplates.html +282 -86
  182. mindroot/docs/_build/html/_modules/mindroot/lib/chatcontext.html +285 -89
  183. mindroot/docs/_build/html/_modules/mindroot/lib/chatlog.html +440 -91
  184. mindroot/docs/_build/html/_modules/mindroot/lib/chatlog_optimized.html +282 -86
  185. mindroot/docs/_build/html/_modules/mindroot/lib/json_escape.html +280 -84
  186. mindroot/docs/_build/html/_modules/mindroot/lib/json_str_block/json_str_block.html +282 -86
  187. mindroot/docs/_build/html/_modules/mindroot/lib/parent_templates.html +282 -86
  188. mindroot/docs/_build/html/_modules/mindroot/lib/plugins/installation.html +280 -84
  189. mindroot/docs/_build/html/_modules/mindroot/lib/plugins/l8n_static_handler.html +280 -84
  190. mindroot/docs/_build/html/_modules/mindroot/lib/plugins/loader.html +282 -86
  191. mindroot/docs/_build/html/_modules/mindroot/lib/plugins/loader_with_l8n.html +282 -86
  192. mindroot/docs/_build/html/_modules/mindroot/lib/plugins/manifest.html +282 -86
  193. mindroot/docs/_build/html/_modules/mindroot/lib/plugins/mapping.html +280 -84
  194. mindroot/docs/_build/html/_modules/mindroot/lib/plugins/paths.html +282 -86
  195. mindroot/docs/_build/html/_modules/mindroot/lib/plugins_install.html +282 -86
  196. mindroot/docs/_build/html/_modules/mindroot/lib/providers/commands.html +282 -87
  197. mindroot/docs/_build/html/_modules/mindroot/lib/providers/hooks.html +280 -85
  198. mindroot/docs/_build/html/_modules/mindroot/lib/providers/missing.html +282 -87
  199. mindroot/docs/_build/html/_modules/mindroot/lib/providers/model_preferences_v2.html +294 -91
  200. mindroot/docs/_build/html/_modules/mindroot/lib/providers/services.html +282 -87
  201. mindroot/docs/_build/html/_modules/mindroot/lib/providers.html +285 -89
  202. mindroot/docs/_build/html/_modules/mindroot/lib/route_decorators.html +282 -86
  203. mindroot/docs/_build/html/_modules/mindroot/lib/session_files.html +282 -86
  204. mindroot/docs/_build/html/_modules/mindroot/lib/streamcmd.html +282 -86
  205. mindroot/docs/_build/html/_modules/mindroot/lib/templates.html +343 -98
  206. mindroot/docs/_build/html/_modules/mindroot/lib/token_counter.html +280 -84
  207. mindroot/docs/_build/html/_modules/mindroot/migrate.html +282 -86
  208. mindroot/docs/_build/html/_modules/mindroot/registry/component_manager.html +282 -86
  209. mindroot/docs/_build/html/_modules/mindroot/registry/data_access.html +285 -89
  210. mindroot/docs/_build/html/_modules/mindroot/server.html +292 -87
  211. mindroot/docs/_build/html/_modules/mindroot/server_missing_normal_args.html +282 -86
  212. mindroot/docs/_build/html/_modules/mindroot/server_prev.html +282 -86
  213. mindroot/docs/_build/html/_sources/developer_documentation.rst.txt +21 -1
  214. mindroot/docs/_build/html/_sources/embed_chat.rst.txt +54 -0
  215. mindroot/docs/_build/html/_sources/user_documentation.rst.txt +6 -1
  216. mindroot/docs/_build/html/chat_with_assistant.html +1 -0
  217. mindroot/docs/_build/html/developer_documentation.html +45 -4
  218. mindroot/docs/_build/html/embed_chat.html +381 -0
  219. mindroot/docs/_build/html/genindex.html +9 -2
  220. mindroot/docs/_build/html/getting_started.html +19 -15
  221. mindroot/docs/_build/html/index.html +3 -0
  222. mindroot/docs/_build/html/install_plugins_with_tools.html +1 -0
  223. mindroot/docs/_build/html/installation.html +1 -0
  224. mindroot/docs/_build/html/llm_api_key.html +1 -0
  225. mindroot/docs/_build/html/llm_plugin_installation.html +1 -0
  226. mindroot/docs/_build/html/objects.inv +0 -0
  227. mindroot/docs/_build/html/programming_task.html +4 -3
  228. mindroot/docs/_build/html/py-modindex.html +2 -1
  229. mindroot/docs/_build/html/search.html +1 -0
  230. mindroot/docs/_build/html/searchindex.js +1 -1
  231. mindroot/docs/_build/html/source/ahp.html +1 -0
  232. mindroot/docs/_build/html/source/mindroot.coreplugins.admin.html +1 -0
  233. mindroot/docs/_build/html/source/mindroot.coreplugins.api_keys.html +16 -2
  234. mindroot/docs/_build/html/source/mindroot.coreplugins.chat.html +1 -0
  235. mindroot/docs/_build/html/source/mindroot.coreplugins.chat_avatar.html +16 -2
  236. mindroot/docs/_build/html/source/mindroot.coreplugins.check_list.html +91 -47
  237. mindroot/docs/_build/html/source/mindroot.coreplugins.credits.html +16 -2
  238. mindroot/docs/_build/html/source/mindroot.coreplugins.email.html +1 -0
  239. mindroot/docs/_build/html/source/mindroot.coreplugins.env_manager.html +16 -2
  240. mindroot/docs/_build/html/source/mindroot.coreplugins.events.html +16 -2
  241. mindroot/docs/_build/html/source/mindroot.coreplugins.html +3 -0
  242. mindroot/docs/_build/html/source/mindroot.coreplugins.index.handlers.html +16 -2
  243. mindroot/docs/_build/html/source/mindroot.coreplugins.index.html +16 -2
  244. mindroot/docs/_build/html/source/mindroot.coreplugins.jwt_auth.html +1 -0
  245. mindroot/docs/_build/html/source/mindroot.coreplugins.l8n.html +1 -0
  246. mindroot/docs/_build/html/source/mindroot.coreplugins.mcp_.html +1 -0
  247. mindroot/docs/_build/html/source/mindroot.coreplugins.persona.html +16 -2
  248. mindroot/docs/_build/html/source/mindroot.coreplugins.startup.html +16 -2
  249. mindroot/docs/_build/html/source/mindroot.coreplugins.subscriptions.html +16 -2
  250. mindroot/docs/_build/html/source/mindroot.coreplugins.usage.html +16 -2
  251. mindroot/docs/_build/html/source/mindroot.coreplugins.user_service.html +16 -2
  252. mindroot/docs/_build/html/source/mindroot.html +2 -0
  253. mindroot/docs/_build/html/source/mindroot.lib.auth.html +16 -2
  254. mindroot/docs/_build/html/source/mindroot.lib.html +36 -4
  255. mindroot/docs/_build/html/source/mindroot.lib.json_str_block.html +16 -2
  256. mindroot/docs/_build/html/source/mindroot.lib.plugins.html +16 -2
  257. mindroot/docs/_build/html/source/mindroot.lib.providers.backup.html +1 -0
  258. mindroot/docs/_build/html/source/mindroot.lib.providers.html +1 -0
  259. mindroot/docs/_build/html/source/mindroot.registry.html +16 -2
  260. mindroot/docs/_build/html/source/modules.html +16 -2
  261. mindroot/docs/_build/html/source/mr_agent_expert_instr.html +1 -0
  262. mindroot/docs/_build/html/starting_mindroot.html +1 -0
  263. mindroot/docs/_build/html/user_documentation.html +9 -0
  264. mindroot/docs/apikey.png +0 -0
  265. mindroot/docs/chatwidget1.png +0 -0
  266. mindroot/docs/chatwidgetx.png +0 -0
  267. mindroot/docs/developer_documentation.rst +21 -1
  268. mindroot/docs/disablechatavatar.png +0 -0
  269. mindroot/docs/embed_chat.rst +54 -0
  270. mindroot/docs/user_documentation.rst +6 -1
  271. mindroot/docs/widgetform.png +0 -0
  272. mindroot/docs/widgetonpage.png +0 -0
  273. mindroot/lib/buchatlog3.py +592 -0
  274. mindroot/lib/chatcontext.py +1 -0
  275. mindroot/lib/chatlog.py +195 -5
  276. mindroot/lib/logging/logfiles.py +1 -0
  277. {mindroot-9.22.0.dist-info → mindroot-10.14.0.dist-info}/METADATA +1 -1
  278. {mindroot-9.22.0.dist-info → mindroot-10.14.0.dist-info}/RECORD +282 -300
  279. mindroot/docs/_build/html/.buildinfo.bak +0 -4
  280. mindroot/docs/_build/html/_static/_sphinx_javascript_frameworks_compat.js +0 -123
  281. mindroot/docs/_build/html/_static/css/badge_only.css +0 -1
  282. mindroot/docs/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff +0 -0
  283. mindroot/docs/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff2 +0 -0
  284. mindroot/docs/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff +0 -0
  285. mindroot/docs/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff2 +0 -0
  286. mindroot/docs/_build/html/_static/css/fonts/fontawesome-webfont.eot +0 -0
  287. mindroot/docs/_build/html/_static/css/fonts/fontawesome-webfont.svg +0 -2671
  288. mindroot/docs/_build/html/_static/css/fonts/fontawesome-webfont.ttf +0 -0
  289. mindroot/docs/_build/html/_static/css/fonts/fontawesome-webfont.woff +0 -0
  290. mindroot/docs/_build/html/_static/css/fonts/fontawesome-webfont.woff2 +0 -0
  291. mindroot/docs/_build/html/_static/css/fonts/lato-bold-italic.woff +0 -0
  292. mindroot/docs/_build/html/_static/css/fonts/lato-bold-italic.woff2 +0 -0
  293. mindroot/docs/_build/html/_static/css/fonts/lato-bold.woff +0 -0
  294. mindroot/docs/_build/html/_static/css/fonts/lato-bold.woff2 +0 -0
  295. mindroot/docs/_build/html/_static/css/fonts/lato-normal-italic.woff +0 -0
  296. mindroot/docs/_build/html/_static/css/fonts/lato-normal-italic.woff2 +0 -0
  297. mindroot/docs/_build/html/_static/css/fonts/lato-normal.woff +0 -0
  298. mindroot/docs/_build/html/_static/css/fonts/lato-normal.woff2 +0 -0
  299. mindroot/docs/_build/html/_static/css/theme.css +0 -4
  300. mindroot/docs/_build/html/_static/fonts/Lato/lato-bold.eot +0 -0
  301. mindroot/docs/_build/html/_static/fonts/Lato/lato-bold.ttf +0 -0
  302. mindroot/docs/_build/html/_static/fonts/Lato/lato-bold.woff +0 -0
  303. mindroot/docs/_build/html/_static/fonts/Lato/lato-bold.woff2 +0 -0
  304. mindroot/docs/_build/html/_static/fonts/Lato/lato-bolditalic.eot +0 -0
  305. mindroot/docs/_build/html/_static/fonts/Lato/lato-bolditalic.ttf +0 -0
  306. mindroot/docs/_build/html/_static/fonts/Lato/lato-bolditalic.woff +0 -0
  307. mindroot/docs/_build/html/_static/fonts/Lato/lato-bolditalic.woff2 +0 -0
  308. mindroot/docs/_build/html/_static/fonts/Lato/lato-italic.eot +0 -0
  309. mindroot/docs/_build/html/_static/fonts/Lato/lato-italic.ttf +0 -0
  310. mindroot/docs/_build/html/_static/fonts/Lato/lato-italic.woff +0 -0
  311. mindroot/docs/_build/html/_static/fonts/Lato/lato-italic.woff2 +0 -0
  312. mindroot/docs/_build/html/_static/fonts/Lato/lato-regular.eot +0 -0
  313. mindroot/docs/_build/html/_static/fonts/Lato/lato-regular.ttf +0 -0
  314. mindroot/docs/_build/html/_static/fonts/Lato/lato-regular.woff +0 -0
  315. mindroot/docs/_build/html/_static/fonts/Lato/lato-regular.woff2 +0 -0
  316. mindroot/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot +0 -0
  317. mindroot/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf +0 -0
  318. mindroot/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff +0 -0
  319. mindroot/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 +0 -0
  320. mindroot/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot +0 -0
  321. mindroot/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf +0 -0
  322. mindroot/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff +0 -0
  323. mindroot/docs/_build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 +0 -0
  324. mindroot/docs/_build/html/_static/jquery.js +0 -2
  325. mindroot/docs/_build/html/_static/js/badge_only.js +0 -1
  326. mindroot/docs/_build/html/_static/js/theme.js +0 -1
  327. mindroot/docs/_build/html/_static/js/versions.js +0 -228
  328. {mindroot-9.22.0.dist-info → mindroot-10.14.0.dist-info}/WHEEL +0 -0
  329. {mindroot-9.22.0.dist-info → mindroot-10.14.0.dist-info}/entry_points.txt +0 -0
  330. {mindroot-9.22.0.dist-info → mindroot-10.14.0.dist-info}/licenses/LICENSE +0 -0
  331. {mindroot-9.22.0.dist-info → mindroot-10.14.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,540 @@
1
+ import asyncio
2
+ import json
3
+ import os
4
+ import re
5
+ import json
6
+ from json import JSONDecodeError
7
+ from jinja2 import Template
8
+ from lib.providers.commands import command_manager, command
9
+ from lib.providers.hooks import hook_manager
10
+ from lib.pipelines.pipe import pipeline_manager
11
+ from lib.providers.services import service
12
+ from lib.providers.services import service_manager
13
+ from lib.json_str_block import replace_raw_blocks
14
+ import sys
15
+ from lib.utils.check_args import *
16
+ from .command_parser import parse_streaming_commands, invalid_start_format
17
+ from datetime import datetime
18
+ import pytz
19
+ import traceback
20
+ from lib.logging.logfiles import logger
21
+ from lib.utils.debug import debug_box
22
+ from .init_models import *
23
+ from lib.chatcontext import ChatContext
24
+ from .cmd_start_example import *
25
+ from lib.templates import render
26
+
27
+
28
+ error_result = """
29
+ [SYSTEM]: ERROR, invalid response format.
30
+
31
+ Your response does not appear to adhere to the command list format.
32
+
33
+ Common causes:
34
+
35
+ - replied with JSON inside of fenced code blocks instead of JSON or RAW string format as below
36
+
37
+ - ONLY if your model supports this, for complex multiline string arguments, use the RAW format described in system instructions, e.g.:
38
+
39
+ ...
40
+
41
+ { "json_encoded_md": { "markdown": START_RAW
42
+ The moon, so bright
43
+ It's shining light
44
+ Like a pizza pie
45
+ In the sky
46
+ END_RAW
47
+ } }
48
+
49
+ ...
50
+
51
+ - iF your model does not support RAW format or it is not a complex multiline string like code, you MUST properly escape JSON strings!
52
+ - remember newlines, double quotes, etc. must be escaped (but not double escaped)!
53
+
54
+ - plain text response before JSON.
55
+
56
+ - some JSON args with unescaped newlines, etc.
57
+
58
+ - multiple command lists. Only one command list response is allowed!
59
+ - This is a frequent cause of parse errors.
60
+
61
+ - some characters escaped that did not need to be/invalid
62
+
63
+ Please adhere to the system JSON command list response format carefully.
64
+ """
65
+
66
+ @service()
67
+ async def get_agent_data(agent_name, context=None):
68
+ logger.info("Agent name: {agent_name}", agent_name=agent_name)
69
+
70
+ agent_path = os.path.join('data/agents', 'local', agent_name)
71
+
72
+ if not os.path.exists(agent_path):
73
+ agent_path = os.path.join('data/agents', 'shared', agent_name)
74
+ if not os.path.exists(agent_path):
75
+ return {}
76
+ agent_file = os.path.join(agent_path, 'agent.json')
77
+ if not os.path.exists(agent_file):
78
+ return {}
79
+ with open(agent_file, 'r') as f:
80
+ agent_data = json.load(f)
81
+
82
+ # Ensure required_plugins is present
83
+ if 'required_plugins' not in agent_data:
84
+ agent_data['required_plugins'] = []
85
+
86
+ try:
87
+ agent_data["persona"] = await service_manager.get_persona_data(agent_data["persona"])
88
+ except Exception as e:
89
+ logger.error("Error getting persona data", extra={"error": str(e)})
90
+ raise e
91
+
92
+ agent_data["flags"] = agent_data["flags"]
93
+ agent_data["flags"] = list(dict.fromkeys(agent_data["flags"]))
94
+ return agent_data
95
+
96
+
97
+
98
+ def find_new_substring(s1, s2):
99
+ if s1 in s2:
100
+ return s2.replace(s1, '', 1)
101
+ return s2
102
+
103
+ class Agent:
104
+
105
+ def __init__(self, model=None, sys_core_template=None, agent=None, clear_model=False, commands=[], context=None):
106
+ if model is None:
107
+ if os.environ.get('AH_DEFAULT_LLM'):
108
+ self.model = os.environ.get('AH_DEFAULT_LLM')
109
+ else:
110
+ self.model = 'llama3'
111
+ else:
112
+ self.model = model
113
+
114
+ self.agent = agent
115
+
116
+ #if sys_core_template is None:
117
+ # system_template_path = os.path.join(os.path.dirname(__file__), "system.j2")
118
+ # with open(system_template_path, "r") as f:
119
+ # self.sys_core_template = f.read()
120
+ #else:
121
+ # self.sys_core_template = sys_core_template
122
+
123
+ #self.sys_template = Template(self.sys_core_template)
124
+
125
+ self.cmd_handler = {}
126
+ self.context = context
127
+
128
+ #if clear_model:
129
+ # logger.debug("Unloading model")
130
+ # asyncio.create_task(use_ollama.unload(self.model))
131
+
132
+ def use_model(self, model_id, local=True):
133
+ self.current_model = model_id
134
+
135
+ async def set_cmd_handler(self, cmd_name, callback):
136
+ self.cmd_handler[cmd_name] = callback
137
+ logger.info("Recorded handler for command: {command}", command=cmd_name)
138
+
139
+ async def unload_llm_if_needed(self):
140
+ logger.info("Not unloading LLM")
141
+ #await use_ollama.unload(self.model)
142
+ #await asyncio.sleep(1)
143
+
144
+ async def handle_cmds(self, cmd_name, cmd_args, json_cmd=None, context=None):
145
+ # Check both permanent finish and temporary cancellation
146
+ if context.data.get('finished_conversation') or context.data.get('cancel_current_turn'):
147
+ logger.warning("Conversation is finished, not executing command")
148
+ print("\033[91mConversation is finished, not executing command\033[0m")
149
+ return None
150
+
151
+ logger.info("Command execution: {command}", command=cmd_name)
152
+ logger.debug("Command details: {details}", details={
153
+ "command": cmd_name,
154
+ "arguments": cmd_args,
155
+ "context": str(context)
156
+ })
157
+ context.chat_log.add_message({"role": "assistant", "content": [{"type": "text",
158
+ "text": '['+json_cmd+']' }]})
159
+ command_manager.context = context
160
+
161
+ if cmd_name == "reasoning":
162
+ return None
163
+
164
+ # cmd_args might be a single arg like integer or string, or it may be an array, or an object/dict with named args
165
+ try:
166
+ if isinstance(cmd_args, list):
167
+ #filter out empty strings
168
+ cmd_args = [x for x in cmd_args if x != '']
169
+ logger.debug("Executing command with list arguments", extra={"step": 1})
170
+ await context.running_command(cmd_name, cmd_args)
171
+ logger.debug("Executing command with list arguments", extra={"step": 2})
172
+ return await command_manager.execute(cmd_name, *cmd_args)
173
+ elif isinstance(cmd_args, dict):
174
+ logger.debug("Executing command with dict arguments", extra={"step": 1})
175
+ await context.running_command(cmd_name, cmd_args)
176
+ logger.debug("Executing command with dict arguments", extra={"step": 2})
177
+ return await command_manager.execute(cmd_name, **cmd_args)
178
+ else:
179
+ logger.debug("Executing command with single argument", extra={"step": 1})
180
+ await context.running_command(cmd_name, cmd_args)
181
+ logger.debug("Executing command with single argument", extra={"step": 2})
182
+ return await command_manager.execute(cmd_name, cmd_args)
183
+
184
+ except Exception as e:
185
+ trace = traceback.format_exc()
186
+ print("\033[96mError in handle_cmds: " + str(e) + "\033[0m")
187
+ print("\033[96m" + trace + "\033[0m")
188
+ logger.error("Error in handle_cmds", extra={
189
+ "error": str(e),
190
+ "command": cmd_name,
191
+ "arguments": cmd_args,
192
+ "traceback": trace
193
+ })
194
+
195
+ return {"error": str(e)}
196
+
197
+ def remove_braces(self, buffer):
198
+ if buffer.endswith("\n"):
199
+ buffer = buffer[:-1]
200
+ if buffer.startswith('[ '):
201
+ buffer = buffer[2:]
202
+ if buffer.startswith(' ['):
203
+ buffer = buffer[2:]
204
+ if buffer.endswith(','):
205
+ buffer = buffer[:-1]
206
+ if buffer.endswith(']'):
207
+ buffer = buffer[:-1]
208
+ if buffer.startswith('['):
209
+ buffer = buffer[1:]
210
+ if buffer.endswith('},'):
211
+ buffer = buffer[:-1]
212
+ return buffer
213
+
214
+ async def parse_single_cmd(self, json_str, context, buffer, match=None):
215
+ cmd_name = '?'
216
+ try:
217
+ cmd_obj = json.loads(json_str)
218
+ cmd_name = next(iter(cmd_obj))
219
+ if isinstance(cmd_obj, list):
220
+ cmd_obj = cmd_obj[0]
221
+ cmd_name = next(iter(cmd_obj))
222
+
223
+ cmd_args = cmd_obj[cmd_name]
224
+ # make sure that cmd_name is in self.agent["commands"]
225
+ if cmd_name not in self.agent["commands"]:
226
+ logger.warning("Command not found in agent commands", extra={"command": cmd_name})
227
+ return None, buffer
228
+ if check_empty_args(cmd_args):
229
+ logger.info("Empty arguments for command", extra={"command": cmd_name})
230
+ return None, buffer
231
+ else:
232
+ logger.info("Non-empty arguments for command", extra={"command": cmd_name, "arguments": cmd_args})
233
+ # Handle the full command
234
+ result = await self.handle_cmds(cmd_name, cmd_args, json_cmd=json_str, context=context)
235
+ await context.command_result(cmd_name, result)
236
+
237
+ cmd = {"cmd": cmd_name, "result": result}
238
+ # Remove the processed JSON object from the buffer
239
+ if match is not None:
240
+ buffer = buffer[match.end():]
241
+ buffer = buffer.lstrip(',').rstrip(',')
242
+ return [cmd], buffer
243
+ except Exception as e:
244
+ trace = traceback.format_exc()
245
+ logger.error("Error processing command", extra={"error": str(e) + "\n\n" + trace})
246
+
247
+ json_str = '[' + json_str + ']'
248
+
249
+ return None, buffer
250
+
251
+
252
+ async def parse_cmd_stream(self, stream, context):
253
+ buffer = ""
254
+ results = []
255
+ full_cmds = []
256
+
257
+ num_processed = 0
258
+ parse_failed = False
259
+ debug_box("Parsing command stream")
260
+ debug_box(str(context))
261
+ original_buffer = ""
262
+
263
+ async for part in stream:
264
+ buffer += part
265
+ original_buffer += part
266
+
267
+ logger.debug(f"Current buffer: ||{buffer}||")
268
+
269
+ if invalid_start_format(buffer):
270
+ print("Found invalid start to buffer", buffer)
271
+ context.chat_log.add_message({"role": "assistant", "content": buffer})
272
+ started_with = f"Your invalid command started with: {buffer[0:20]}"
273
+ results.append({"cmd": "UNKNOWN", "args": { "invalid": "(" }, "result": error_result + "\n\n" + started_with})
274
+ return results, full_cmds
275
+
276
+ if len(buffer) > 0 and buffer[0] == '{':
277
+ buffer = "[" + buffer
278
+
279
+ # happened with Qwen 3 for some reason
280
+ buffer = buffer.replace('}] <>\n\n[{','}, {')
281
+ buffer = buffer.replace('}] <>\n[{','}, {')
282
+
283
+ commands, partial_cmd = parse_streaming_commands(buffer)
284
+
285
+ if isinstance(commands, int):
286
+ continue
287
+
288
+ if not isinstance(commands, list):
289
+ commands = [commands]
290
+
291
+ try:
292
+ if len(commands) == 1 and 'commands' in commands[0]:
293
+ commands = commands[0]['commands']
294
+ except Exception as e:
295
+ continue
296
+
297
+ logger.debug(f"commands: {commands}, partial_cmd: {partial_cmd}")
298
+
299
+ # Check for cancellation (either permanent or current turn)
300
+ if context.data.get('finished_conversation') or context.data.get('cancel_current_turn'):
301
+ # Clear the temporary cancel flag so next turn can proceed
302
+ if 'cancel_current_turn' in context.data:
303
+ del context.data['cancel_current_turn']
304
+ logger.warning("Conversation is finished or halted, exiting stream parsing")
305
+ debug_box(f"""Conversation is finished or halted, exiting stream""")
306
+ debug_box(str(context))
307
+ # stream is actually a generator
308
+ if partial_cmd is not None:
309
+ cmd_name = next(iter(partial_cmd))
310
+ if cmd_name in ["say", "json_encoded_md", "think"]:
311
+ context.chat_log.add_message({"role": "assistant", "content": str(partial_cmd[cmd_name])})
312
+ else:
313
+ context.chat_log.add_message({"role": "assistant", "content": str(partial_cmd) + "(Interrupted)"})
314
+ try:
315
+ stream.close()
316
+ except Exception as e:
317
+ print("\033[91mError closing stream\033[0m")
318
+
319
+ return results, full_cmds
320
+
321
+
322
+ if len(commands) > num_processed:
323
+ logger.debug("New command(s) found")
324
+ logger.debug(f"Commands: {commands}")
325
+ for i in range(num_processed, len(commands)):
326
+ try:
327
+ cmd = commands[i]
328
+ try:
329
+ cmd_name = next(iter(cmd))
330
+ except Exception as e:
331
+ print("next iter failed. cmd is")
332
+ print(cmd)
333
+ break
334
+ if isinstance(cmd, str):
335
+ print("\033[91m" + "Invalid command format, expected object, trying to parse anyway" + "\033[0m")
336
+ print("\033[91m" + str(cmd) + "\033[0m")
337
+ cmd = json.loads(cmd)
338
+ cmd_name = next(iter(cmd))
339
+ cmd_args = cmd[cmd_name]
340
+ logger.debug(f"Processing command: {cmd}")
341
+ await context.partial_command(cmd_name, json.dumps(cmd_args), cmd_args)
342
+
343
+ self.handle_cmds(cmd_name, cmd_args, json_cmd=json.dumps(cmd), context=context)
344
+
345
+ cmd_task = asyncio.create_task(
346
+ self.handle_cmds(cmd_name, cmd_args, json_cmd=json.dumps(cmd), context=context)
347
+ )
348
+ context.data['active_command_task'] = cmd_task
349
+ try:
350
+ result = await cmd_task
351
+ finally:
352
+ # Clear the task from context once it's done or cancelled
353
+ if context.data.get('active_command_task') == cmd_task:
354
+ del context.data['active_command_task']
355
+
356
+ await context.command_result(cmd_name, result)
357
+ sys_header = "Note: tool command results follow, not user replies"
358
+ sys_header = ""
359
+
360
+ if result == "SYSTEM: WARNING - Command interrupted!\n\n":
361
+ logger.warning("Command was interrupted. Skipping any extra commands in list.")
362
+ await context.chat_log.drop_last('assistant')
363
+ return results, full_cmds
364
+ break
365
+
366
+
367
+ full_cmds.append({ "SYSTEM": sys_header, "cmd": cmd_name, "args": cmd_args, "result": result})
368
+ if result is not None:
369
+ results.append({"SYSTEM": sys_header, "cmd": cmd_name, "args": { "omitted": "(see command msg.)"}, "result": result})
370
+
371
+ num_processed = len(commands)
372
+ except Exception as e:
373
+ trace = traceback.format_exc()
374
+ logger.error(f"Error processing command: {e} \n{trace}")
375
+ logger.error(str(e))
376
+ pass
377
+ else:
378
+ logger.debug("No new commands found")
379
+ # sometimes partial_cmd is actually a string for some reason
380
+ # definitely skip that
381
+ # check if partial_cmd is a string
382
+ is_string = isinstance(partial_cmd, str)
383
+ if partial_cmd is not None and partial_cmd != {} and not is_string:
384
+ logger.debug(f"Partial command {partial_cmd}")
385
+ try:
386
+ cmd_name = next(iter(partial_cmd))
387
+ cmd_args = partial_cmd[cmd_name]
388
+ logger.debug(f"Partial command detected: {partial_cmd}")
389
+ await context.partial_command(cmd_name, json.dumps(cmd_args), cmd_args)
390
+ except Exception as de:
391
+ logger.error("Failed to parse partial command")
392
+ logger.error(str(de))
393
+ pass
394
+
395
+ #print("\033[92m" + str(full_cmds) + "\033[0m")
396
+ # getting false positive on this check
397
+ reasonOnly = False
398
+ try:
399
+ cmd_name = next(iter(full_cmds[0]))
400
+ if cmd_name == 'reasoning':
401
+ reasonOnly = True
402
+ for cmd in full_cmds:
403
+ if cmd_name != 'reasoning':
404
+ reasonOnly = False
405
+ break
406
+ except Exception as e:
407
+ pass
408
+ if len(full_cmds) == 0 or reasonOnly:
409
+ print("\033[91m" + "No results and parse failed" + "\033[0m")
410
+ try:
411
+ buffer = replace_raw_blocks(buffer)
412
+ parse_ok = json.loads(buffer)
413
+ parse_fail_reason = ""
414
+ tried_to_parse = ""
415
+ except JSONDecodeError as e:
416
+ print("final parse fail")
417
+ print(buffer)
418
+ parse_fail_reason = str(e)
419
+ context.chat_log.add_message({"role": "assistant", "content": buffer})
420
+ print(parse_fail_reason)
421
+ await asyncio.sleep(1)
422
+ tried_to_parse = f"\n\nTried to parse the following input: {original_buffer}"
423
+ results.append({"cmd": "UNKNOWN", "args": { "invalid": "("}, "result": error_result + '\n\nJSON parse error was: ' + parse_fail_reason +
424
+ tried_to_parse })
425
+
426
+ return results, full_cmds
427
+
428
+ async def render_system_msg(self):
429
+ logger.debug("Docstrings:")
430
+ logger.debug(command_manager.get_some_docstrings(self.agent["commands"]))
431
+ now = datetime.now()
432
+
433
+ formatted_time = now.strftime("~ %Y-%m-%d %I %p %Z%z")
434
+
435
+ data = {
436
+ "command_docs": command_manager.get_some_docstrings(self.agent["commands"]),
437
+ "agent": self.agent,
438
+ "persona": self.agent['persona'],
439
+ "formatted_datetime": formatted_time,
440
+ "context_data": self.context.data
441
+ }
442
+ # is say in the command_manager
443
+ if 'say' in command_manager.functions.keys():
444
+ print("I found say! in the functions!")
445
+ else:
446
+ print("Say is not in the functions!")
447
+ if 'say' in data['command_docs'].keys():
448
+ print("I found say in the command docs!")
449
+
450
+ # we need to be doubly sure to remove anything from command_docs that is not in command_manager.functions.keys()
451
+ for cmd in data['command_docs']:
452
+ if cmd not in command_manager.functions.keys():
453
+ print("Removing " + cmd + " from command_docs")
454
+ del data['command_docs'][cmd]
455
+
456
+ #self.system_message = self.sys_template.render(data)
457
+ self.system_message = await render('system', data)
458
+
459
+ additional_instructions = await hook_manager.add_instructions(self.context)
460
+
461
+ for instruction in additional_instructions:
462
+ self.system_message += instruction + "\n\n"
463
+
464
+ return self.system_message
465
+
466
+
467
+ async def chat_commands(self, model, context,
468
+ temperature=0, max_tokens=4000, messages=[]):
469
+
470
+ self.context = context
471
+ content = [ { "type": "text", "text": await self.render_system_msg() } ]
472
+ messages = [{"role": "system", "content": content }] + demo_boot_msgs() + messages
473
+
474
+ #logger.info("Messages for chat", extra={"messages": messages})
475
+
476
+ json_messages = json.dumps(messages)
477
+ new_messages = json.loads(json_messages)
478
+
479
+ if os.environ.get("AH_DEFAULT_MAX_TOKENS"):
480
+ max_tokens = int(os.environ.get("AH_DEFAULT_MAX_TOKENS"))
481
+ try:
482
+ tmp_data = { "messages": new_messages }
483
+ debug_box("Filtering messages")
484
+ #debug_box(tmp_data)
485
+
486
+ tmp_data = await pipeline_manager.filter_messages(tmp_data, context=context)
487
+ new_messages = tmp_data['messages']
488
+ except Exception as e:
489
+ logger.error("Error filtering messages")
490
+ logger.error(str(e))
491
+
492
+ if new_messages[0]['role'] != 'system':
493
+ logger.error("First message is not a system message")
494
+ print("\033[91mFirst message is not a system message\033[0m")
495
+ return None, None
496
+
497
+ if not isinstance(context.agent, dict):
498
+ context.agent = await get_agent_data(context.agent, context=context)
499
+
500
+ if 'max_tokens' in context.agent and context.agent['max_tokens'] is not None and context.agent['max_tokens'] != '':
501
+ logger.info(f"Using agent max tokens {max_tokens}")
502
+ max_tokens = context.agent['max_tokens']
503
+ else:
504
+ logger.info(f"Using default max tokens {max_tokens}")
505
+
506
+ if model is None:
507
+ if 'service_models' in context.agent and context.agent['service_models'] is not None:
508
+ if context.agent['service_models'].get('stream_chat', None) is None:
509
+ model = os.environ.get("DEFAULT_LLM_MODEL")
510
+
511
+ # we need to be able to abort this task if necessary
512
+ stream = await context.stream_chat(model,
513
+ temperature=temperature,
514
+ max_tokens=max_tokens,
515
+ messages=new_messages,
516
+ context=context)
517
+
518
+ ret, full_cmds = await self.parse_cmd_stream(stream, context)
519
+ logger.debug("System message was:")
520
+ logger.debug(await self.render_system_msg())
521
+
522
+ # use green text
523
+ print("\033[92m" + "Just after stream chat, last two messages in chat log:")
524
+ print("------------------------------------")
525
+ print(context.chat_log.messages[-1])
526
+ print(context.chat_log.messages[-2])
527
+ # switch back to normal text
528
+ print("\033[0m")
529
+
530
+ return ret, full_cmds
531
+
532
+ @service()
533
+ async def run_command(cmd_name, cmd_args, context=None):
534
+ if context is None:
535
+ raise Exception("run_command: No context provided")
536
+
537
+ agent = Agent(agent=context.agent)
538
+ json_cmd = json.dumps({cmd_name: cmd_args})
539
+ asyncio.create_task(agent.handle_cmds(cmd_name, cmd_args, json_cmd, context=context))
540
+
@@ -0,0 +1,77 @@
1
+ from .agent import Agent, get_agent_data
2
+ import traceback
3
+ import json
4
+
5
+ class SpeechToSpeechAgent(Agent):
6
+
7
+ def __init__(self, agent_name=None, context=None):
8
+ super().__init__(context)
9
+ self.context = context
10
+ if agent_name:
11
+ self.agent_name = agent_name
12
+ self.on_sip_call = False # Track if we're on a SIP call
13
+
14
+ async def on_audio_chunk_callback(self, audio_bytes: bytes, context=None):
15
+ """Route audio output to SIP if on a call."""
16
+ if self.on_sip_call:
17
+ try:
18
+ # Send audio to active SIP session
19
+ from lib.providers.services import service_manager
20
+ await service_manager.sip_audio_out_chunk(
21
+ audio_chunk=audio_bytes,
22
+ context=self.context
23
+ )
24
+ except Exception as e:
25
+ print(f"Error routing audio to SIP: {e}")
26
+ # If not on call, audio plays locally (handled by ah_openai)
27
+
28
+ async def handle_s2s_cmd(self, cmd:dict, context=None):
29
+ try:
30
+ print('Received S2S command:')
31
+ print(json.dumps(cmd, indent=2))
32
+
33
+ # Track call state for audio routing
34
+ if 'call' in cmd:
35
+ self.on_sip_call = True
36
+ elif 'hangup' in cmd:
37
+ self.on_sip_call = False
38
+
39
+ json_str = json.dumps(cmd)
40
+ buffer = ''
41
+ results = await self.parse_single_cmd(json_str, self.context, buffer)
42
+ print()
43
+ print()
44
+ print('#########################################')
45
+ print(results)
46
+ await self.send_message([{
47
+ "type": "text",
48
+ "text": f"[SYSTEM: Command executed successfully]\n{json.dumps(str(results))}"
49
+ }])
50
+ except Exception as e:
51
+ trace = traceback.format_exc()
52
+ print(f"Error executing S2S command: {e}")
53
+ await self.send_message([{
54
+ "type": "text",
55
+ "text": f"[SYSTEM: Error executing command: {str(e)}\n{str(trace)}]"
56
+ }])
57
+
58
+ async def connect(self):
59
+ self.agent = await get_agent_data(self.context.agent_name)
60
+ sys_msg = await self.render_system_msg()
61
+
62
+ # Pass audio callback to route output to SIP when on call
63
+ await self.context.start_s2s(
64
+ self.model,
65
+ sys_msg,
66
+ self.handle_s2s_cmd,
67
+ play_local=False,
68
+ on_audio_chunk=self.on_audio_chunk_callback,
69
+ context=self.context
70
+ )
71
+
72
+ async def send_message(self, content, context=None):
73
+ msg = { "role": "user", "content": content }
74
+ print("calling send_s2s_message", msg)
75
+ await self.context.send_s2s_message(msg)
76
+
77
+
@@ -0,0 +1,46 @@
1
+ from .agent import Agent, get_agent_data
2
+ import traceback
3
+ import json
4
+
5
+ class SpeechToSpeechAgent(Agent):
6
+
7
+ def __init__(self, agent_name=None, context=None):
8
+ super().__init__(context)
9
+ self.context = context
10
+ if agent_name:
11
+ self.agent_name = agent_name
12
+
13
+ async def handle_s2s_cmd(self, cmd:dict, context=None):
14
+ try:
15
+ print('Received S2S command:')
16
+ print(json.dumps(cmd, indent=2))
17
+ json_str = json.dumps(cmd)
18
+ buffer = ''
19
+ results = await self.parse_single_cmd(json_str, self.context, buffer)
20
+ print()
21
+ print()
22
+ print('#########################################')
23
+ print(results)
24
+ await self.send_message([{
25
+ "type": "text",
26
+ "text": f"[SYSTEM: Command executed successfully]\n{json.dumps(str(results))}"
27
+ }])
28
+ except Exception as e:
29
+ trace = traceback.format_exc()
30
+ print(f"Error executing S2S command: {e}")
31
+ await self.send_message([{
32
+ "type": "text",
33
+ "text": f"[SYSTEM: Error executing command: {str(e)}\n{str(trace)}]"
34
+ }])
35
+
36
+ async def connect(self):
37
+ self.agent = await get_agent_data(self.context.agent_name)
38
+ sys_msg = await self.render_system_msg()
39
+
40
+ await self.context.start_s2s(self.model, sys_msg, self.handle_s2s_cmd, context=self.context)
41
+
42
+ async def send_message(self, content, context=None):
43
+ msg = { "role": "user", "content": content }
44
+ print("calling send_s2s_message", msg)
45
+ await self.context.send_s2s_message(msg)
46
+