cachibot 0.2.6.dev1__tar.gz → 0.2.6.dev2__tar.gz

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 (185) hide show
  1. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/PKG-INFO +1 -1
  2. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/pyproject.toml +1 -1
  3. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/agent.py +53 -116
  4. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/websocket.py +12 -27
  5. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/cli.py +4 -3
  6. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/bot_creation_service.py +83 -260
  7. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/message_processor.py +2 -4
  8. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/name_generator.py +34 -143
  9. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/.dockerignore +0 -0
  10. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/.github/workflows/dev.yml +0 -0
  11. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/.github/workflows/publish.yml +0 -0
  12. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/.gitignore +0 -0
  13. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/CLAUDE.md +0 -0
  14. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/CONTRIBUTING.md +0 -0
  15. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/Dockerfile +0 -0
  16. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/LICENSE +0 -0
  17. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/README.md +0 -0
  18. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/cachibot.example.toml +0 -0
  19. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/docker-compose.yml +0 -0
  20. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/.dockerignore +0 -0
  21. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/.gitignore +0 -0
  22. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/Dockerfile +0 -0
  23. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/eslint.config.js +0 -0
  24. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/index.html +0 -0
  25. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/package-lock.json +0 -0
  26. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/package.json +0 -0
  27. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/postcss.config.js +0 -0
  28. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/public/favicon.svg +0 -0
  29. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/App.tsx +0 -0
  30. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/api/auth.ts +0 -0
  31. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/api/client.ts +0 -0
  32. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/api/connections.ts +0 -0
  33. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/api/contacts.ts +0 -0
  34. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/api/index.ts +0 -0
  35. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/api/knowledge.ts +0 -0
  36. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/api/models.ts +0 -0
  37. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/api/skills.ts +0 -0
  38. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/api/websocket.ts +0 -0
  39. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/auth/LoginPage.tsx +0 -0
  40. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/auth/ProtectedRoute.tsx +0 -0
  41. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/auth/SetupPage.tsx +0 -0
  42. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/chat/ChatPanel.tsx +0 -0
  43. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/chat/InputArea.tsx +0 -0
  44. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/chat/MessageList.tsx +0 -0
  45. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/chat/ThinkingIndicator.tsx +0 -0
  46. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/chat/ToolCallList.tsx +0 -0
  47. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/chat/UsageDisplay.tsx +0 -0
  48. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/BotIconRenderer.tsx +0 -0
  49. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/Button.tsx +0 -0
  50. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/Dialog/Dialog.tsx +0 -0
  51. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/Dialog/DialogContent.tsx +0 -0
  52. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/Dialog/DialogFooter.tsx +0 -0
  53. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/Dialog/DialogHeader.tsx +0 -0
  54. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/Dialog/DialogStepper.tsx +0 -0
  55. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/Dialog/index.ts +0 -0
  56. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/MarkdownRenderer.tsx +0 -0
  57. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/ModelSelect.tsx +0 -0
  58. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/Spinner.tsx +0 -0
  59. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/ToolIconRenderer.tsx +0 -0
  60. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/ApprovalDialog.tsx +0 -0
  61. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotDialog.tsx +0 -0
  62. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/index.tsx +0 -0
  63. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/AppearanceStep.tsx +0 -0
  64. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/CapabilitiesStep.tsx +0 -0
  65. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/ConfirmStep.tsx +0 -0
  66. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/DetailsStep.tsx +0 -0
  67. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/ImportStep.tsx +0 -0
  68. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/MethodSelectStep.tsx +0 -0
  69. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/NamePickerStep.tsx +0 -0
  70. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/PersonalityStep.tsx +0 -0
  71. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/PreviewStep.tsx +0 -0
  72. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/PromptReviewStep.tsx +0 -0
  73. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/PurposeStep.tsx +0 -0
  74. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/TemplateSelectStep.tsx +0 -0
  75. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/SettingsDialog.tsx +0 -0
  76. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/ToolConfigDialog.tsx +0 -0
  77. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/knowledge/DocumentList.tsx +0 -0
  78. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/knowledge/DocumentUploader.tsx +0 -0
  79. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/knowledge/InstructionsEditor.tsx +0 -0
  80. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/knowledge/index.ts +0 -0
  81. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/layout/BotRail.tsx +0 -0
  82. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/layout/BotSidebar.tsx +0 -0
  83. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/layout/Header.tsx +0 -0
  84. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/layout/MainLayout.tsx +0 -0
  85. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/layout/Sidebar.tsx +0 -0
  86. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/marketplace/BotCard.tsx +0 -0
  87. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/marketplace/BotDetailDialog.tsx +0 -0
  88. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/marketplace/MarketplaceBrowser.tsx +0 -0
  89. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/marketplace/index.ts +0 -0
  90. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/settings/BotConnectionsPanel.tsx +0 -0
  91. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/settings/ContactsPanel.tsx +0 -0
  92. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/AppSettingsView.tsx +0 -0
  93. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/ChatView.tsx +0 -0
  94. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/ConnectionsView.tsx +0 -0
  95. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/DashboardView.tsx +0 -0
  96. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/JobsView.tsx +0 -0
  97. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/ModelsView.tsx +0 -0
  98. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/SchedulesView.tsx +0 -0
  99. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/SettingsView.tsx +0 -0
  100. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/TasksView.tsx +0 -0
  101. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/ToolsView.tsx +0 -0
  102. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/UsersView.tsx +0 -0
  103. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/WorkView.tsx +0 -0
  104. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/index.ts +0 -0
  105. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/hooks/useCommands.ts +0 -0
  106. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/hooks/useWebSocket.ts +0 -0
  107. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/index.css +0 -0
  108. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/lib/language-detector.ts +0 -0
  109. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/lib/prompt-generator.ts +0 -0
  110. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/lib/utils.ts +0 -0
  111. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/main.tsx +0 -0
  112. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/auth.ts +0 -0
  113. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/bots.ts +0 -0
  114. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/config.ts +0 -0
  115. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/connections.ts +0 -0
  116. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/contacts.ts +0 -0
  117. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/creation-flow.ts +0 -0
  118. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/creation.ts +0 -0
  119. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/index.ts +0 -0
  120. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/knowledge.ts +0 -0
  121. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/models.ts +0 -0
  122. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/ui.ts +0 -0
  123. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/types/index.ts +0 -0
  124. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/vite-env.d.ts +0 -0
  125. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/tailwind.config.js +0 -0
  126. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/tsconfig.json +0 -0
  127. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/tsconfig.tsbuildinfo +0 -0
  128. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/vite.config.ts +0 -0
  129. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/__init__.py +0 -0
  130. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/__init__.py +0 -0
  131. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/auth.py +0 -0
  132. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/__init__.py +0 -0
  133. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/auth.py +0 -0
  134. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/bots.py +0 -0
  135. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/chat.py +0 -0
  136. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/chats.py +0 -0
  137. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/config.py +0 -0
  138. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/connections.py +0 -0
  139. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/contacts.py +0 -0
  140. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/creation.py +0 -0
  141. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/documents.py +0 -0
  142. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/health.py +0 -0
  143. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/instructions.py +0 -0
  144. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/marketplace.py +0 -0
  145. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/models.py +0 -0
  146. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/skills.py +0 -0
  147. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/work.py +0 -0
  148. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/server.py +0 -0
  149. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/config.py +0 -0
  150. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/data/marketplace_templates.py +0 -0
  151. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/__init__.py +0 -0
  152. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/auth.py +0 -0
  153. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/bot.py +0 -0
  154. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/capabilities.py +0 -0
  155. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/chat.py +0 -0
  156. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/chat_model.py +0 -0
  157. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/command.py +0 -0
  158. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/config.py +0 -0
  159. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/connection.py +0 -0
  160. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/job.py +0 -0
  161. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/knowledge.py +0 -0
  162. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/skill.py +0 -0
  163. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/websocket.py +0 -0
  164. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/work.py +0 -0
  165. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/__init__.py +0 -0
  166. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/adapters/__init__.py +0 -0
  167. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/adapters/base.py +0 -0
  168. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/adapters/discord.py +0 -0
  169. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/adapters/telegram.py +0 -0
  170. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/auth_service.py +0 -0
  171. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/command_processor.py +0 -0
  172. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/context_builder.py +0 -0
  173. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/document_processor.py +0 -0
  174. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/platform_manager.py +0 -0
  175. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/skills.py +0 -0
  176. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/vector_store.py +0 -0
  177. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/storage/__init__.py +0 -0
  178. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/storage/database.py +0 -0
  179. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/storage/repository.py +0 -0
  180. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/storage/user_repository.py +0 -0
  181. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/storage/work_repository.py +0 -0
  182. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/utils/__init__.py +0 -0
  183. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/utils/markdown.py +0 -0
  184. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/tests/__init__.py +0 -0
  185. {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/tests/test_cachibot.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cachibot
3
- Version: 0.2.6.dev1
3
+ Version: 0.2.6.dev2
4
4
  Summary: The Armored AI Agent. Cross-platform, secure, yours.
5
5
  Project-URL: Homepage, https://cachibot.dev
6
6
  Project-URL: Documentation, https://cachibot.dev/docs
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "cachibot"
7
- version = "0.2.6.dev1"
7
+ version = "0.2.6.dev2"
8
8
  description = "The Armored AI Agent. Cross-platform, secure, yours."
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -10,7 +10,7 @@ from pathlib import Path
10
10
  from typing import Any
11
11
 
12
12
  from prompture import (
13
- Agent as PromptureAgent,
13
+ AsyncAgent as PromptureAgent,
14
14
  )
15
15
  from prompture import (
16
16
  AgentCallbacks,
@@ -25,24 +25,6 @@ from prompture import (
25
25
  from cachibot.config import Config
26
26
 
27
27
 
28
- def create_filtered_registry(full_registry: ToolRegistry, allowed_tools: set[str]) -> ToolRegistry:
29
- """
30
- Create a new registry containing only the allowed tools.
31
-
32
- Args:
33
- full_registry: Complete tool registry with all tools
34
- allowed_tools: Set of tool names to include
35
-
36
- Returns:
37
- New ToolRegistry with only allowed tools
38
- """
39
- filtered = ToolRegistry()
40
- for tool_name in allowed_tools:
41
- if tool := full_registry.get(tool_name):
42
- filtered.add(tool)
43
- return filtered
44
-
45
-
46
28
  @dataclass
47
29
  class CachibotAgent:
48
30
  """
@@ -81,7 +63,9 @@ class CachibotAgent:
81
63
 
82
64
  # Apply tool filtering if specified
83
65
  if self.allowed_tools is not None:
84
- self.registry = create_filtered_registry(self.registry, self.allowed_tools)
66
+ # Only include tools that exist in the registry
67
+ valid_tools = self.allowed_tools & set(self.registry.names)
68
+ self.registry = self.registry.subset(valid_tools)
85
69
 
86
70
  self._create_agent()
87
71
 
@@ -273,7 +257,7 @@ class CachibotAgent:
273
257
  return f"Task completed: {summary}"
274
258
 
275
259
  @self.registry.register
276
- def telegram_send(chat_id: str, message: str) -> str:
260
+ async def telegram_send(chat_id: str, message: str) -> str:
277
261
  """
278
262
  Send a message to a Telegram chat.
279
263
 
@@ -287,10 +271,10 @@ class CachibotAgent:
287
271
  Returns:
288
272
  Success or error message
289
273
  """
290
- return self._send_platform_message("telegram", chat_id, message)
274
+ return await self._send_platform_message("telegram", chat_id, message)
291
275
 
292
276
  @self.registry.register
293
- def discord_send(channel_id: str, message: str) -> str:
277
+ async def discord_send(channel_id: str, message: str) -> str:
294
278
  """
295
279
  Send a message to a Discord channel.
296
280
 
@@ -304,14 +288,14 @@ class CachibotAgent:
304
288
  Returns:
305
289
  Success or error message
306
290
  """
307
- return self._send_platform_message("discord", channel_id, message)
291
+ return await self._send_platform_message("discord", channel_id, message)
308
292
 
309
293
  # =================================================================
310
294
  # WORK MANAGEMENT TOOLS
311
295
  # =================================================================
312
296
 
313
297
  @self.registry.register
314
- def work_create(
298
+ async def work_create(
315
299
  title: str,
316
300
  description: str = "",
317
301
  goal: str = "",
@@ -334,10 +318,10 @@ class CachibotAgent:
334
318
  Returns:
335
319
  JSON with the created work ID and details
336
320
  """
337
- return self._work_create(title, description, goal, priority, tasks)
321
+ return await self._work_create(title, description, goal, priority, tasks)
338
322
 
339
323
  @self.registry.register
340
- def work_list(status: str = "all", limit: int = 10) -> str:
324
+ async def work_list(status: str = "all", limit: int = 10) -> str:
341
325
  """
342
326
  List work items for this bot.
343
327
 
@@ -348,10 +332,10 @@ class CachibotAgent:
348
332
  Returns:
349
333
  JSON list of work items with their status and progress
350
334
  """
351
- return self._work_list(status, limit)
335
+ return await self._work_list(status, limit)
352
336
 
353
337
  @self.registry.register
354
- def work_update(
338
+ async def work_update(
355
339
  work_id: str,
356
340
  status: str | None = None,
357
341
  progress: int | None = None,
@@ -371,10 +355,10 @@ class CachibotAgent:
371
355
  Returns:
372
356
  Updated work details
373
357
  """
374
- return self._work_update(work_id, status, progress, result, error)
358
+ return await self._work_update(work_id, status, progress, result, error)
375
359
 
376
360
  @self.registry.register
377
- def todo_create(
361
+ async def todo_create(
378
362
  title: str,
379
363
  notes: str = "",
380
364
  priority: str = "normal",
@@ -395,10 +379,10 @@ class CachibotAgent:
395
379
  Returns:
396
380
  JSON with the created todo ID and details
397
381
  """
398
- return self._todo_create(title, notes, priority, remind_at)
382
+ return await self._todo_create(title, notes, priority, remind_at)
399
383
 
400
384
  @self.registry.register
401
- def todo_list(status: str = "open", limit: int = 20) -> str:
385
+ async def todo_list(status: str = "open", limit: int = 20) -> str:
402
386
  """
403
387
  List todos for this bot.
404
388
 
@@ -409,10 +393,10 @@ class CachibotAgent:
409
393
  Returns:
410
394
  JSON list of todos
411
395
  """
412
- return self._todo_list(status, limit)
396
+ return await self._todo_list(status, limit)
413
397
 
414
398
  @self.registry.register
415
- def todo_done(todo_id: str) -> str:
399
+ async def todo_done(todo_id: str) -> str:
416
400
  """
417
401
  Mark a todo as done.
418
402
 
@@ -422,12 +406,10 @@ class CachibotAgent:
422
406
  Returns:
423
407
  Confirmation message
424
408
  """
425
- return self._todo_done(todo_id)
409
+ return await self._todo_done(todo_id)
426
410
 
427
- def _send_platform_message(self, platform: str, chat_id: str, message: str) -> str:
411
+ async def _send_platform_message(self, platform: str, chat_id: str, message: str) -> str:
428
412
  """Send a message to a platform (telegram/discord)."""
429
- import asyncio
430
-
431
413
  from cachibot.models.connection import ConnectionPlatform
432
414
  from cachibot.services.platform_manager import get_platform_manager
433
415
 
@@ -446,9 +428,8 @@ class CachibotAgent:
446
428
 
447
429
  manager = get_platform_manager()
448
430
  try:
449
- loop = asyncio.get_event_loop()
450
- success = loop.run_until_complete(
451
- manager.send_to_bot_connection(bot_id, platform_enum, chat_id, message)
431
+ success = await manager.send_to_bot_connection(
432
+ bot_id, platform_enum, chat_id, message
452
433
  )
453
434
  if success:
454
435
  return f"Message sent to {platform.title()} {chat_id}"
@@ -463,7 +444,7 @@ class CachibotAgent:
463
444
  return self.tool_configs["platform_bot_id"]
464
445
  return None
465
446
 
466
- def _work_create(
447
+ async def _work_create(
467
448
  self,
468
449
  title: str,
469
450
  description: str,
@@ -472,7 +453,6 @@ class CachibotAgent:
472
453
  tasks: list[str] | None,
473
454
  ) -> str:
474
455
  """Create a new work item."""
475
- import asyncio
476
456
  import json
477
457
  import uuid
478
458
  from datetime import datetime
@@ -484,11 +464,10 @@ class CachibotAgent:
484
464
  if not bot_id:
485
465
  return "Error: No bot ID configured"
486
466
 
487
- async def create():
467
+ try:
488
468
  work_repo = WorkRepository()
489
469
  task_repo = TaskRepository()
490
470
 
491
- # Create work
492
471
  work = Work(
493
472
  id=str(uuid.uuid4()),
494
473
  bot_id=bot_id,
@@ -504,7 +483,6 @@ class CachibotAgent:
504
483
  )
505
484
  await work_repo.save(work)
506
485
 
507
- # Create tasks if provided
508
486
  created_tasks = []
509
487
  if tasks:
510
488
  for i, task_title in enumerate(tasks):
@@ -524,23 +502,17 @@ class CachibotAgent:
524
502
  await task_repo.save(task)
525
503
  created_tasks.append({"id": task.id, "title": task.title})
526
504
 
527
- return {
505
+ return json.dumps({
528
506
  "id": work.id,
529
507
  "title": work.title,
530
508
  "status": work.status.value,
531
509
  "tasks": created_tasks,
532
- }
533
-
534
- try:
535
- loop = asyncio.get_event_loop()
536
- result = loop.run_until_complete(create())
537
- return json.dumps(result, indent=2)
510
+ }, indent=2)
538
511
  except Exception as e:
539
512
  return f"Error creating work: {e}"
540
513
 
541
- def _work_list(self, status: str, limit: int) -> str:
514
+ async def _work_list(self, status: str, limit: int) -> str:
542
515
  """List work items."""
543
- import asyncio
544
516
  import json
545
517
 
546
518
  from cachibot.models.work import WorkStatus
@@ -550,11 +522,11 @@ class CachibotAgent:
550
522
  if not bot_id:
551
523
  return "Error: No bot ID configured"
552
524
 
553
- async def list_work():
525
+ try:
554
526
  work_repo = WorkRepository()
555
527
  status_filter = None if status == "all" else WorkStatus(status)
556
528
  items = await work_repo.get_by_bot(bot_id, status=status_filter, limit=limit)
557
- return [
529
+ result = [
558
530
  {
559
531
  "id": w.id,
560
532
  "title": w.title,
@@ -565,17 +537,13 @@ class CachibotAgent:
565
537
  }
566
538
  for w in items
567
539
  ]
568
-
569
- try:
570
- loop = asyncio.get_event_loop()
571
- result = loop.run_until_complete(list_work())
572
540
  if not result:
573
541
  return "No work items found"
574
542
  return json.dumps(result, indent=2)
575
543
  except Exception as e:
576
544
  return f"Error listing work: {e}"
577
545
 
578
- def _work_update(
546
+ async def _work_update(
579
547
  self,
580
548
  work_id: str,
581
549
  status: str | None,
@@ -584,7 +552,6 @@ class CachibotAgent:
584
552
  error: str | None,
585
553
  ) -> str:
586
554
  """Update a work item."""
587
- import asyncio
588
555
  import json
589
556
 
590
557
  from cachibot.models.work import WorkStatus
@@ -594,39 +561,30 @@ class CachibotAgent:
594
561
  if not bot_id:
595
562
  return "Error: No bot ID configured"
596
563
 
597
- async def update():
564
+ try:
598
565
  work_repo = WorkRepository()
599
566
 
600
- # Get current work
601
567
  work = await work_repo.get(work_id)
602
568
  if not work:
603
- return {"error": f"Work {work_id} not found"}
569
+ return json.dumps({"error": f"Work {work_id} not found"}, indent=2)
604
570
 
605
- # Update status if provided
606
571
  if status:
607
572
  await work_repo.update_status(work_id, WorkStatus(status), error)
608
573
 
609
- # Update progress if provided
610
574
  if progress is not None:
611
575
  await work_repo.update_progress(work_id, float(progress))
612
576
 
613
- # Fetch updated work
614
577
  updated_work = await work_repo.get(work_id)
615
- return {
578
+ return json.dumps({
616
579
  "id": updated_work.id,
617
580
  "title": updated_work.title,
618
581
  "status": updated_work.status.value,
619
582
  "progress": updated_work.progress,
620
- }
621
-
622
- try:
623
- loop = asyncio.get_event_loop()
624
- result_data = loop.run_until_complete(update())
625
- return json.dumps(result_data, indent=2)
583
+ }, indent=2)
626
584
  except Exception as e:
627
585
  return f"Error updating work: {e}"
628
586
 
629
- def _todo_create(
587
+ async def _todo_create(
630
588
  self,
631
589
  title: str,
632
590
  notes: str,
@@ -634,7 +592,6 @@ class CachibotAgent:
634
592
  remind_at: str | None,
635
593
  ) -> str:
636
594
  """Create a todo."""
637
- import asyncio
638
595
  import json
639
596
  import uuid
640
597
  from datetime import datetime
@@ -646,7 +603,7 @@ class CachibotAgent:
646
603
  if not bot_id:
647
604
  return "Error: No bot ID configured"
648
605
 
649
- async def create():
606
+ try:
650
607
  todo_repo = TodoRepository()
651
608
  remind_datetime = None
652
609
  if remind_at:
@@ -667,23 +624,17 @@ class CachibotAgent:
667
624
  tags=[],
668
625
  )
669
626
  await todo_repo.save(todo)
670
- return {
627
+ return json.dumps({
671
628
  "id": todo.id,
672
629
  "title": todo.title,
673
630
  "priority": todo.priority.value,
674
631
  "remind_at": todo.remind_at.isoformat() if todo.remind_at else None,
675
- }
676
-
677
- try:
678
- loop = asyncio.get_event_loop()
679
- result = loop.run_until_complete(create())
680
- return json.dumps(result, indent=2)
632
+ }, indent=2)
681
633
  except Exception as e:
682
634
  return f"Error creating todo: {e}"
683
635
 
684
- def _todo_list(self, status: str, limit: int) -> str:
636
+ async def _todo_list(self, status: str, limit: int) -> str:
685
637
  """List todos."""
686
- import asyncio
687
638
  import json
688
639
 
689
640
  from cachibot.models.work import TodoStatus
@@ -693,11 +644,11 @@ class CachibotAgent:
693
644
  if not bot_id:
694
645
  return "Error: No bot ID configured"
695
646
 
696
- async def list_todos():
647
+ try:
697
648
  todo_repo = TodoRepository()
698
649
  status_filter = None if status == "all" else TodoStatus(status)
699
650
  items = await todo_repo.get_by_bot(bot_id, status=status_filter, limit=limit)
700
- return [
651
+ result = [
701
652
  {
702
653
  "id": t.id,
703
654
  "title": t.title,
@@ -707,35 +658,24 @@ class CachibotAgent:
707
658
  }
708
659
  for t in items
709
660
  ]
710
-
711
- try:
712
- loop = asyncio.get_event_loop()
713
- result = loop.run_until_complete(list_todos())
714
661
  if not result:
715
662
  return "No todos found"
716
663
  return json.dumps(result, indent=2)
717
664
  except Exception as e:
718
665
  return f"Error listing todos: {e}"
719
666
 
720
- def _todo_done(self, todo_id: str) -> str:
667
+ async def _todo_done(self, todo_id: str) -> str:
721
668
  """Mark a todo as done."""
722
- import asyncio
723
-
724
669
  from cachibot.models.work import TodoStatus
725
670
  from cachibot.storage.work_repository import TodoRepository
726
671
 
727
- async def mark_done():
672
+ try:
728
673
  todo_repo = TodoRepository()
729
- # Get todo first to check it exists and get title
730
674
  todo = await todo_repo.get(todo_id)
731
675
  if not todo:
732
676
  return f"Error: Todo {todo_id} not found"
733
677
  await todo_repo.update_status(todo_id, TodoStatus.DONE)
734
678
  return f"Todo '{todo.title}' marked as done"
735
-
736
- try:
737
- loop = asyncio.get_event_loop()
738
- return loop.run_until_complete(mark_done())
739
679
  except Exception as e:
740
680
  return f"Error marking todo done: {e}"
741
681
 
@@ -754,6 +694,7 @@ class CachibotAgent:
754
694
  on_thinking=self.on_thinking,
755
695
  on_tool_start=self.on_tool_start,
756
696
  on_tool_end=self.on_tool_end,
697
+ on_message=self.on_message,
757
698
  on_approval_needed=self._handle_approval,
758
699
  )
759
700
 
@@ -765,6 +706,7 @@ class CachibotAgent:
765
706
  system_prompt=self._get_system_prompt(),
766
707
  agent_callbacks=callbacks,
767
708
  max_iterations=self.config.agent.max_iterations,
709
+ persistent_conversation=True,
768
710
  )
769
711
 
770
712
  def _get_system_prompt(self) -> str:
@@ -814,7 +756,7 @@ Cachibot was created by Juan Denis (juandenis.com). When asked about your creato
814
756
  return False # Reject by default if no callback
815
757
  return True # Auto-approve if approval not required
816
758
 
817
- def run(self, user_message: str) -> str:
759
+ async def run(self, user_message: str) -> str:
818
760
  """
819
761
  Process a user message and return the response.
820
762
 
@@ -824,19 +766,14 @@ Cachibot was created by Juan Denis (juandenis.com). When asked about your creato
824
766
  Returns:
825
767
  The agent's response message
826
768
  """
827
- result: AgentResult = self._agent.run(user_message)
769
+ result: AgentResult = await self._agent.run(user_message)
828
770
 
829
- # Store result for usage tracking (Prompture Agent doesn't have last_result)
771
+ # Store result for usage tracking
830
772
  self._last_result = result
831
773
 
832
-
833
- # Notify message callback
834
- if self.on_message and result.output_text:
835
- self.on_message(result.output_text)
836
-
837
774
  return result.output_text or "Task completed."
838
775
 
839
- def run_stream(self, user_message: str):
776
+ async def run_stream(self, user_message: str):
840
777
  """
841
778
  Process a user message with streaming output.
842
779
 
@@ -846,7 +783,8 @@ Cachibot was created by Juan Denis (juandenis.com). When asked about your creato
846
783
  Yields:
847
784
  Stream events from the agent
848
785
  """
849
- yield from self._agent.run_stream(user_message)
786
+ async for event in self._agent.run_stream(user_message):
787
+ yield event
850
788
 
851
789
  def get_usage(self) -> dict:
852
790
  """Get token usage and cost information."""
@@ -871,8 +809,7 @@ Cachibot was created by Juan Denis (juandenis.com). When asked about your creato
871
809
 
872
810
  def clear_history(self) -> None:
873
811
  """Clear the conversation history."""
874
- # Recreate the agent to clear history
875
- self._create_agent()
812
+ self._agent.clear_history()
876
813
 
877
814
 
878
815
  # Backwards compatibility alias
@@ -211,13 +211,10 @@ async def websocket_endpoint(
211
211
  # Determine allowed tools based on capabilities and skills
212
212
  allowed_tools = get_allowed_tools(capabilities, enabled_skills)
213
213
 
214
- # Get the current event loop for thread-safe callback scheduling
215
- loop = asyncio.get_running_loop()
216
-
217
214
  # Always create fresh agent with current systemPrompt
218
215
  # (user may switch between bots with different personalities)
219
216
  agent = create_agent_with_callbacks(
220
- config, client_id, loop, enhanced_prompt,
217
+ config, client_id, enhanced_prompt,
221
218
  bot_id, chat_id, allowed_tools, tool_configs
222
219
  )
223
220
 
@@ -256,7 +253,6 @@ async def websocket_endpoint(
256
253
  def create_agent_with_callbacks(
257
254
  config: Config,
258
255
  client_id: str,
259
- loop: asyncio.AbstractEventLoop,
260
256
  system_prompt: str | None = None,
261
257
  bot_id: str | None = None,
262
258
  chat_id: str | None = None,
@@ -268,7 +264,6 @@ def create_agent_with_callbacks(
268
264
  Args:
269
265
  config: Application configuration
270
266
  client_id: WebSocket client ID
271
- loop: The event loop to schedule callbacks on (needed for thread-safe execution)
272
267
  system_prompt: Optional system prompt override
273
268
  bot_id: Bot ID for message history
274
269
  chat_id: Chat ID for message history
@@ -283,32 +278,28 @@ def create_agent_with_callbacks(
283
278
  if bot_id:
284
279
  merged_tool_configs["platform_bot_id"] = bot_id
285
280
 
286
- def schedule_async(coro) -> None:
287
- """Schedule a coroutine to run on the main event loop from a worker thread."""
288
- asyncio.run_coroutine_threadsafe(coro, loop)
289
-
290
281
  def on_thinking(text: str) -> None:
291
282
  """Send thinking event."""
292
- schedule_async(manager.send(client_id, WSMessage.thinking(text)))
283
+ asyncio.ensure_future(manager.send(client_id, WSMessage.thinking(text)))
293
284
 
294
285
  def on_tool_start(name: str, args: dict[str, Any]) -> None:
295
286
  """Send tool start event."""
296
287
  tool_call_counter["count"] += 1
297
288
  tool_id = f"tool_{tool_call_counter['count']}"
298
- schedule_async(
289
+ asyncio.ensure_future(
299
290
  manager.send(client_id, WSMessage.tool_start(tool_id, name, args))
300
291
  )
301
292
 
302
293
  def on_tool_end(name: str, result: Any) -> None:
303
294
  """Send tool end event."""
304
295
  tool_id = f"tool_{tool_call_counter['count']}"
305
- schedule_async(
296
+ asyncio.ensure_future(
306
297
  manager.send(client_id, WSMessage.tool_end(tool_id, str(result)[:1000]))
307
298
  )
308
299
 
309
300
  def on_message(text: str) -> None:
310
301
  """Send assistant message and save to history."""
311
- schedule_async(
302
+ asyncio.ensure_future(
312
303
  manager.send(client_id, WSMessage.message("assistant", text))
313
304
  )
314
305
  # Save assistant message to history
@@ -321,30 +312,25 @@ def create_agent_with_callbacks(
321
312
  content=text,
322
313
  timestamp=datetime.utcnow(),
323
314
  )
324
- schedule_async(repo.save_bot_message(assistant_msg))
315
+ asyncio.ensure_future(repo.save_bot_message(assistant_msg))
325
316
 
326
317
  def on_approval_needed(tool_name: str, action: str, details: dict) -> bool:
327
- """Handle approval request synchronously (blocking)."""
328
- # For WebSocket, we need to use async approval flow
329
- # This will be called in a sync context, so we use a workaround
318
+ """Handle approval request."""
330
319
  approval_id = str(uuid.uuid4())
331
320
 
332
- # Create event for waiting
333
321
  event = asyncio.Event()
334
322
  manager.pending_approvals[approval_id] = event
335
323
  manager.approval_results[approval_id] = False
336
324
 
337
- # Send approval request
338
- schedule_async(
325
+ asyncio.ensure_future(
339
326
  manager.send(
340
327
  client_id,
341
328
  WSMessage.approval_needed(approval_id, tool_name, action, details),
342
329
  )
343
330
  )
344
331
 
345
- # Note: In sync callback context, we can't await
346
- # The approval will be handled in the next iteration
347
- # For now, return the config default
332
+ # Note: on_approval_needed callback is typed as sync (returns bool)
333
+ # in AgentCallbacks, so we can't await here. Return config default.
348
334
  return not config.agent.approve_actions
349
335
 
350
336
  agent = CachibotAgent(
@@ -388,9 +374,8 @@ async def run_agent(
388
374
  )
389
375
  await repo.save_bot_message(user_msg)
390
376
 
391
- # Run agent (this is blocking, so run in executor)
392
- loop = asyncio.get_event_loop()
393
- await loop.run_in_executor(None, agent.run, message)
377
+ # Run async agent directly
378
+ await agent.run(message)
394
379
 
395
380
  # Send usage stats
396
381
  usage = agent.get_usage()
@@ -4,6 +4,7 @@ Cachibot CLI
4
4
  Beautiful command-line interface using Typer and Rich.
5
5
  """
6
6
 
7
+ import asyncio
7
8
  from pathlib import Path
8
9
  from typing import Optional
9
10
 
@@ -225,7 +226,7 @@ def main(
225
226
  if task:
226
227
  try:
227
228
  console.print()
228
- response = agent.run(task)
229
+ response = asyncio.run(agent.run(task))
229
230
  console.print(f"\n[assistant]Cachibot:[/]")
230
231
  console.print(Markdown(response))
231
232
 
@@ -268,7 +269,7 @@ def main(
268
269
 
269
270
  # Run the agent
270
271
  console.print()
271
- response = agent.run(user_input)
272
+ response = asyncio.run(agent.run(user_input))
272
273
 
273
274
  # Print response
274
275
  console.print(f"\n[assistant]Cachibot:[/]")
@@ -304,7 +305,7 @@ def run_task(
304
305
  agent = create_agent_with_callbacks(config)
305
306
 
306
307
  try:
307
- response = agent.run(task)
308
+ response = asyncio.run(agent.run(task))
308
309
  console.print(Markdown(response))
309
310
 
310
311
  if config.display.show_cost: