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.
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/PKG-INFO +1 -1
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/pyproject.toml +1 -1
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/agent.py +53 -116
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/websocket.py +12 -27
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/cli.py +4 -3
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/bot_creation_service.py +83 -260
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/message_processor.py +2 -4
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/name_generator.py +34 -143
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/.dockerignore +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/.github/workflows/dev.yml +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/.github/workflows/publish.yml +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/.gitignore +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/CLAUDE.md +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/CONTRIBUTING.md +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/Dockerfile +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/LICENSE +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/README.md +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/cachibot.example.toml +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/docker-compose.yml +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/.dockerignore +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/.gitignore +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/Dockerfile +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/eslint.config.js +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/index.html +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/package-lock.json +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/package.json +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/postcss.config.js +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/public/favicon.svg +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/App.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/api/auth.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/api/client.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/api/connections.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/api/contacts.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/api/index.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/api/knowledge.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/api/models.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/api/skills.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/api/websocket.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/auth/LoginPage.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/auth/ProtectedRoute.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/auth/SetupPage.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/chat/ChatPanel.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/chat/InputArea.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/chat/MessageList.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/chat/ThinkingIndicator.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/chat/ToolCallList.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/chat/UsageDisplay.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/BotIconRenderer.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/Button.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/Dialog/Dialog.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/Dialog/DialogContent.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/Dialog/DialogFooter.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/Dialog/DialogHeader.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/Dialog/DialogStepper.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/Dialog/index.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/MarkdownRenderer.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/ModelSelect.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/Spinner.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/common/ToolIconRenderer.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/ApprovalDialog.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotDialog.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/index.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/AppearanceStep.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/CapabilitiesStep.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/ConfirmStep.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/DetailsStep.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/ImportStep.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/MethodSelectStep.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/NamePickerStep.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/PersonalityStep.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/PreviewStep.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/PromptReviewStep.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/PurposeStep.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/CreateBotWizard/steps/TemplateSelectStep.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/SettingsDialog.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/dialogs/ToolConfigDialog.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/knowledge/DocumentList.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/knowledge/DocumentUploader.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/knowledge/InstructionsEditor.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/knowledge/index.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/layout/BotRail.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/layout/BotSidebar.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/layout/Header.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/layout/MainLayout.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/layout/Sidebar.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/marketplace/BotCard.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/marketplace/BotDetailDialog.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/marketplace/MarketplaceBrowser.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/marketplace/index.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/settings/BotConnectionsPanel.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/settings/ContactsPanel.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/AppSettingsView.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/ChatView.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/ConnectionsView.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/DashboardView.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/JobsView.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/ModelsView.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/SchedulesView.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/SettingsView.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/TasksView.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/ToolsView.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/UsersView.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/WorkView.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/components/views/index.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/hooks/useCommands.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/hooks/useWebSocket.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/index.css +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/lib/language-detector.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/lib/prompt-generator.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/lib/utils.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/main.tsx +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/auth.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/bots.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/config.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/connections.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/contacts.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/creation-flow.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/creation.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/index.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/knowledge.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/models.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/stores/ui.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/types/index.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/src/vite-env.d.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/tailwind.config.js +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/tsconfig.json +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/tsconfig.tsbuildinfo +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/frontend/vite.config.ts +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/__init__.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/__init__.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/auth.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/__init__.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/auth.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/bots.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/chat.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/chats.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/config.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/connections.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/contacts.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/creation.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/documents.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/health.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/instructions.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/marketplace.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/models.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/skills.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/routes/work.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/api/server.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/config.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/data/marketplace_templates.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/__init__.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/auth.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/bot.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/capabilities.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/chat.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/chat_model.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/command.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/config.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/connection.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/job.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/knowledge.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/skill.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/websocket.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/models/work.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/__init__.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/adapters/__init__.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/adapters/base.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/adapters/discord.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/adapters/telegram.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/auth_service.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/command_processor.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/context_builder.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/document_processor.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/platform_manager.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/skills.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/services/vector_store.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/storage/__init__.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/storage/database.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/storage/repository.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/storage/user_repository.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/storage/work_repository.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/utils/__init__.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/src/cachibot/utils/markdown.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/tests/__init__.py +0 -0
- {cachibot-0.2.6.dev1 → cachibot-0.2.6.dev2}/tests/test_cachibot.py +0 -0
|
@@ -10,7 +10,7 @@ from pathlib import Path
|
|
|
10
10
|
from typing import Any
|
|
11
11
|
|
|
12
12
|
from prompture import (
|
|
13
|
-
|
|
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
|
-
|
|
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
|
-
|
|
450
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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:
|
|
346
|
-
#
|
|
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
|
|
392
|
-
|
|
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:
|