vibesurf 0.1.31__tar.gz → 0.1.33__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.

Potentially problematic release.


This version of vibesurf might be problematic. Click here for more details.

Files changed (151) hide show
  1. {vibesurf-0.1.31 → vibesurf-0.1.33}/.env.example +4 -1
  2. {vibesurf-0.1.31 → vibesurf-0.1.33}/PKG-INFO +11 -9
  3. {vibesurf-0.1.31 → vibesurf-0.1.33}/README.md +8 -8
  4. {vibesurf-0.1.31 → vibesurf-0.1.33}/README_zh.md +8 -8
  5. {vibesurf-0.1.31 → vibesurf-0.1.33}/pyproject.toml +2 -0
  6. vibesurf-0.1.33/tests/test_telemetry.py +31 -0
  7. vibesurf-0.1.33/tests/test_tools.py +244 -0
  8. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/_version.py +3 -3
  9. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/agents/browser_use_agent.py +1 -1
  10. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/agents/prompts/vibe_surf_prompt.py +6 -0
  11. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/agents/report_writer_agent.py +50 -0
  12. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/agents/vibe_surf_agent.py +56 -1
  13. vibesurf-0.1.33/vibe_surf/backend/api/composio.py +952 -0
  14. vibesurf-0.1.33/vibe_surf/backend/database/migrations/v005_add_composio_integration.sql +33 -0
  15. vibesurf-0.1.33/vibe_surf/backend/database/migrations/v006_add_credentials_table.sql +26 -0
  16. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/database/models.py +53 -1
  17. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/database/queries.py +312 -2
  18. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/main.py +28 -0
  19. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/shared_state.py +123 -9
  20. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/scripts/api-client.js +32 -0
  21. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/scripts/settings-manager.js +954 -1
  22. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/sidepanel.html +190 -0
  23. vibesurf-0.1.33/vibe_surf/chrome_extension/styles/settings-integrations.css +927 -0
  24. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/styles/settings-modal.css +7 -3
  25. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/styles/settings-responsive.css +37 -5
  26. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/cli.py +98 -3
  27. vibesurf-0.1.33/vibe_surf/telemetry/__init__.py +60 -0
  28. vibesurf-0.1.33/vibe_surf/telemetry/service.py +112 -0
  29. vibesurf-0.1.33/vibe_surf/telemetry/views.py +156 -0
  30. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/browser_use_tools.py +90 -90
  31. vibesurf-0.1.33/vibe_surf/tools/composio_client.py +456 -0
  32. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/mcp_client.py +21 -2
  33. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/vibesurf_tools.py +290 -87
  34. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/views.py +16 -0
  35. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/website_api/youtube/client.py +35 -13
  36. vibesurf-0.1.33/vibe_surf/utils.py +13 -0
  37. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibesurf.egg-info/PKG-INFO +11 -9
  38. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibesurf.egg-info/SOURCES.txt +19 -0
  39. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibesurf.egg-info/requires.txt +2 -0
  40. vibesurf-0.1.31/tests/test_tools.py +0 -134
  41. {vibesurf-0.1.31 → vibesurf-0.1.33}/.github/workflows/publish.yml +0 -0
  42. {vibesurf-0.1.31 → vibesurf-0.1.33}/.gitignore +0 -0
  43. {vibesurf-0.1.31 → vibesurf-0.1.33}/.python-version +0 -0
  44. {vibesurf-0.1.31 → vibesurf-0.1.33}/LICENSE +0 -0
  45. {vibesurf-0.1.31 → vibesurf-0.1.33}/MANIFEST.in +0 -0
  46. {vibesurf-0.1.31 → vibesurf-0.1.33}/docs/EXECUTABLE_BUILD.md +0 -0
  47. {vibesurf-0.1.31 → vibesurf-0.1.33}/docs/PYPI_SETUP.md +0 -0
  48. {vibesurf-0.1.31 → vibesurf-0.1.33}/scripts/build-local.bat +0 -0
  49. {vibesurf-0.1.31 → vibesurf-0.1.33}/scripts/build-local.sh +0 -0
  50. {vibesurf-0.1.31 → vibesurf-0.1.33}/setup.cfg +0 -0
  51. {vibesurf-0.1.31 → vibesurf-0.1.33}/tests/test_agents.py +0 -0
  52. {vibesurf-0.1.31 → vibesurf-0.1.33}/tests/test_backend_api.py +0 -0
  53. {vibesurf-0.1.31 → vibesurf-0.1.33}/tests/test_browser.py +0 -0
  54. {vibesurf-0.1.31 → vibesurf-0.1.33}/tests/test_voice_api.py +0 -0
  55. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/__init__.py +0 -0
  56. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/agents/__init__.py +0 -0
  57. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/agents/prompts/__init__.py +0 -0
  58. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/agents/prompts/report_writer_prompt.py +0 -0
  59. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/agents/views.py +0 -0
  60. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/__init__.py +0 -0
  61. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/api/__init__.py +0 -0
  62. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/api/activity.py +0 -0
  63. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/api/agent.py +0 -0
  64. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/api/browser.py +0 -0
  65. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/api/config.py +0 -0
  66. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/api/files.py +0 -0
  67. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/api/models.py +0 -0
  68. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/api/task.py +0 -0
  69. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/api/voices.py +0 -0
  70. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/database/__init__.py +0 -0
  71. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/database/manager.py +0 -0
  72. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/database/migrations/v001_initial_schema.sql +0 -0
  73. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/database/migrations/v002_add_agent_mode.sql +0 -0
  74. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/database/migrations/v003_fix_task_status_case.sql +0 -0
  75. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/database/migrations/v004_add_voice_profiles.sql +0 -0
  76. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/database/schemas.py +0 -0
  77. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/llm_config.py +0 -0
  78. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/utils/__init__.py +0 -0
  79. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/utils/encryption.py +0 -0
  80. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/utils/llm_factory.py +0 -0
  81. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/utils/utils.py +0 -0
  82. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/backend/voice_model_config.py +0 -0
  83. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/browser/__init__.py +0 -0
  84. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/browser/agen_browser_profile.py +0 -0
  85. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/browser/agent_browser_session.py +0 -0
  86. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/browser/browser_manager.py +0 -0
  87. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/browser/utils.py +0 -0
  88. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/browser/watchdogs/__init__.py +0 -0
  89. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/browser/watchdogs/action_watchdog.py +0 -0
  90. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/browser/watchdogs/dom_watchdog.py +0 -0
  91. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/background.js +0 -0
  92. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/config.js +0 -0
  93. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/content.js +0 -0
  94. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/dev-reload.js +0 -0
  95. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/icons/logo.icns +0 -0
  96. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/icons/logo.png +0 -0
  97. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/manifest.json +0 -0
  98. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/permission-iframe.html +0 -0
  99. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/permission-request.html +0 -0
  100. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/popup.html +0 -0
  101. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/scripts/file-manager.js +0 -0
  102. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/scripts/history-manager.js +0 -0
  103. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/scripts/main.js +0 -0
  104. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/scripts/markdown-it.min.js +0 -0
  105. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/scripts/modal-manager.js +0 -0
  106. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/scripts/permission-iframe-request.js +0 -0
  107. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/scripts/permission-request.js +0 -0
  108. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/scripts/session-manager.js +0 -0
  109. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/scripts/ui-manager.js +0 -0
  110. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/scripts/user-settings-storage.js +0 -0
  111. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/scripts/voice-recorder.js +0 -0
  112. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/styles/activity.css +0 -0
  113. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/styles/animations.css +0 -0
  114. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/styles/base.css +0 -0
  115. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/styles/components.css +0 -0
  116. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/styles/history-modal.css +0 -0
  117. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/styles/input.css +0 -0
  118. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/styles/layout.css +0 -0
  119. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/styles/responsive.css +0 -0
  120. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/styles/settings-environment.css +0 -0
  121. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/styles/settings-forms.css +0 -0
  122. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/styles/settings-profiles.css +0 -0
  123. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/styles/settings-utilities.css +0 -0
  124. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/chrome_extension/styles/variables.css +0 -0
  125. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/common.py +0 -0
  126. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/llm/__init__.py +0 -0
  127. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/llm/openai_compatible.py +0 -0
  128. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/logger.py +0 -0
  129. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/__init__.py +0 -0
  130. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/file_system.py +0 -0
  131. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/finance_tools.py +0 -0
  132. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/report_writer_tools.py +0 -0
  133. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/vibesurf_registry.py +0 -0
  134. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/voice_asr.py +0 -0
  135. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/website_api/__init__.py +0 -0
  136. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/website_api/douyin/__init__.py +0 -0
  137. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/website_api/douyin/client.py +0 -0
  138. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/website_api/douyin/douyin.js +0 -0
  139. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/website_api/douyin/helpers.py +0 -0
  140. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/website_api/weibo/__init__.py +0 -0
  141. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/website_api/weibo/client.py +0 -0
  142. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/website_api/weibo/helpers.py +0 -0
  143. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/website_api/xhs/__init__.py +0 -0
  144. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/website_api/xhs/client.py +0 -0
  145. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/website_api/xhs/helpers.py +0 -0
  146. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/website_api/youtube/__init__.py +0 -0
  147. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibe_surf/tools/website_api/youtube/helpers.py +0 -0
  148. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibesurf.egg-info/dependency_links.txt +0 -0
  149. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibesurf.egg-info/entry_points.txt +0 -0
  150. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibesurf.egg-info/top_level.txt +0 -0
  151. {vibesurf-0.1.31 → vibesurf-0.1.33}/vibesurf.spec +0 -0
@@ -47,6 +47,9 @@ VIBESURF_EXTENSION=
47
47
  VIBESURF_WORKSPACE=
48
48
  VIBESURF_DATABASE_URL=
49
49
  VIBESURF_DEBUG=
50
+ VIBESURF_ANONYMIZED_TELEMETRY=true
50
51
 
51
52
  BROWSER_EXECUTION_PATH=
52
- BROWSER_USER_DATA=
53
+ BROWSER_USER_DATA=
54
+
55
+ COMPOSIO_API_KEY=
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vibesurf
3
- Version: 0.1.31
3
+ Version: 0.1.33
4
4
  Summary: VibeSurf: A powerful browser assistant for vibe surfing
5
5
  Author: WarmShao
6
6
  License: Apache-2.0
@@ -46,10 +46,12 @@ Requires-Dist: dashscope>=1.24.5
46
46
  Requires-Dist: yfinance>=0.2.66
47
47
  Requires-Dist: pyexecjs>=1.5.1
48
48
  Requires-Dist: youtube-transcript-api>=1.2.2
49
+ Requires-Dist: composio>=0.8.20
50
+ Requires-Dist: composio-langchain>=0.8.20
49
51
  Dynamic: license-file
50
52
 
51
53
  # VibeSurf: A powerful browser assistant for vibe surfing
52
- [![Discord](https://img.shields.io/discord/1303749220842340412?color=7289DA&label=Discord&logo=discord&logoColor=white)](https://discord.gg/EZ2YnUXP)
54
+ [![Discord](https://img.shields.io/badge/Discord-join-5865F2?logo=discord&logoColor=white)](https://discord.gg/EZ2YnUXP)
53
55
  [![WarmShao](https://img.shields.io/twitter/follow/warmshao?style=social)](https://x.com/warmshao)
54
56
 
55
57
  VibeSurf is an open-source AI agentic browser that revolutionizes browser automation and research.
@@ -141,16 +143,16 @@ uv run vibesurf
141
143
  We're building VibeSurf to be your ultimate AI browser companion. Here's what's coming next:
142
144
 
143
145
  - [x] **Smart Skills System** - *Completed*
144
- Add `/search` for quick information search and `/crawl` for automatic website data extraction. Integrated native APIs for Xiaohongshu, Douyin, Weibo, and YouTube.
146
+ Add `/search` for quick information search, `/crawl` for automatic website data extraction and `/code` for webpage js code execution. Integrated native APIs for Xiaohongshu, Douyin, Weibo, and YouTube.
145
147
 
146
- - [ ] **Powerful Coding Agent** - *In Progress*
147
- Build a comprehensive coding assistant for data processing and analysis directly in your browser
148
+ - [x] **Third-Party Integrations** - *Completed*
149
+ Connect with hundreds of popular tools including Gmail, Notion, Google Calendar, Slack, Trello, GitHub, and more through Composio integration to combine browsing with powerful automation capabilities
148
150
 
149
- - [ ] **Agentic Browser Workflow** - *Planned*
150
- Create custom drag-and-drop workflows for auto-login, data collection, and complex browser automation tasks
151
+ - [ ] **Agentic Browser Workflow** - *In Progress*
152
+ Create custom drag-and-drop and conversation-based workflows for auto-login, data collection, and complex browser automation tasks
151
153
 
152
- - [ ] **Third-Party Integrations** - *Planned*
153
- Connect with n8n workflows and other tools to combine browsing with automation
154
+ - [ ] **Powerful Coding Agent** - *In Progress*
155
+ Build a comprehensive coding assistant for data processing and analysis directly in your browser
154
156
 
155
157
  - [ ] **Intelligent Memory & Personalization** - *Planned*
156
158
  Transform VibeSurf into a truly human-like companion with persistent memory that learns your preferences, habits, and browsing patterns over time
@@ -1,5 +1,5 @@
1
1
  # VibeSurf: A powerful browser assistant for vibe surfing
2
- [![Discord](https://img.shields.io/discord/1303749220842340412?color=7289DA&label=Discord&logo=discord&logoColor=white)](https://discord.gg/EZ2YnUXP)
2
+ [![Discord](https://img.shields.io/badge/Discord-join-5865F2?logo=discord&logoColor=white)](https://discord.gg/EZ2YnUXP)
3
3
  [![WarmShao](https://img.shields.io/twitter/follow/warmshao?style=social)](https://x.com/warmshao)
4
4
 
5
5
  VibeSurf is an open-source AI agentic browser that revolutionizes browser automation and research.
@@ -91,16 +91,16 @@ uv run vibesurf
91
91
  We're building VibeSurf to be your ultimate AI browser companion. Here's what's coming next:
92
92
 
93
93
  - [x] **Smart Skills System** - *Completed*
94
- Add `/search` for quick information search and `/crawl` for automatic website data extraction. Integrated native APIs for Xiaohongshu, Douyin, Weibo, and YouTube.
94
+ Add `/search` for quick information search, `/crawl` for automatic website data extraction and `/code` for webpage js code execution. Integrated native APIs for Xiaohongshu, Douyin, Weibo, and YouTube.
95
95
 
96
- - [ ] **Powerful Coding Agent** - *In Progress*
97
- Build a comprehensive coding assistant for data processing and analysis directly in your browser
96
+ - [x] **Third-Party Integrations** - *Completed*
97
+ Connect with hundreds of popular tools including Gmail, Notion, Google Calendar, Slack, Trello, GitHub, and more through Composio integration to combine browsing with powerful automation capabilities
98
98
 
99
- - [ ] **Agentic Browser Workflow** - *Planned*
100
- Create custom drag-and-drop workflows for auto-login, data collection, and complex browser automation tasks
99
+ - [ ] **Agentic Browser Workflow** - *In Progress*
100
+ Create custom drag-and-drop and conversation-based workflows for auto-login, data collection, and complex browser automation tasks
101
101
 
102
- - [ ] **Third-Party Integrations** - *Planned*
103
- Connect with n8n workflows and other tools to combine browsing with automation
102
+ - [ ] **Powerful Coding Agent** - *In Progress*
103
+ Build a comprehensive coding assistant for data processing and analysis directly in your browser
104
104
 
105
105
  - [ ] **Intelligent Memory & Personalization** - *Planned*
106
106
  Transform VibeSurf into a truly human-like companion with persistent memory that learns your preferences, habits, and browsing patterns over time
@@ -1,6 +1,6 @@
1
1
  # VibeSurf:强大的浏览器助手,用于氛围冲浪
2
2
 
3
- [![Discord](https://img.shields.io/discord/1303749220842340412?color=7289DA&label=Discord&logo=discord&logoColor=white)](https://discord.gg/EZ2YnUXP)
3
+ [![Discord](https://img.shields.io/badge/Discord-join-5865F2?logo=discord&logoColor=white)](https://discord.gg/EZ2YnUXP)
4
4
  [![WarmShao](https://img.shields.io/twitter/follow/warmshao?style=social)](https://x.com/warmshao)
5
5
 
6
6
  VibeSurf 是一个开源的 AI 代理浏览器,它革新了浏览器自动化和研究。
@@ -93,16 +93,16 @@ uv run vibesurf
93
93
  我们正在构建 VibeSurf,使其成为您终极的 AI 浏览器伴侣。以下是接下来的计划:
94
94
 
95
95
  - [x] **智能技能系统** - *已完成*
96
- 添加 `/search` 用于快速信息搜索,`/crawl` 用于自动网站数据提取。集成了小红书、抖音、微博和 YouTube 的原生 API。
96
+ 添加 `/search` 用于快速信息搜索,`/crawl` 用于自动网站数据提取, `/code`用于页面自动执行js code。集成了小红书、抖音、微博和 YouTube 的原生 API。
97
97
 
98
- - [ ] **强大的编码代理** - *进行中*
99
- 构建一个全面的编码助手,用于在浏览器中直接进行数据处理和分析
98
+ - [x] **第三方集成** - *已完成*
99
+ 通过 Composio 集成连接数百种常用工具,包括 Gmail、Notion、Google Calendar、Slack、Trello、GitHub 等,将浏览与强大的自动化功能相结合
100
100
 
101
- - [ ] **智能浏览器工作流** - *计划中*
102
- 创建自定义拖拽式工作流,用于自动登录、数据收集和复杂的浏览器自动化任务
101
+ - [ ] **智能浏览器工作流** - *进行中*
102
+ 创建自定义拖拽式和对话式工作流,用于自动登录、数据收集和复杂的浏览器自动化任务
103
103
 
104
- - [ ] **第三方集成** - *计划中*
105
- 与 n8n 工作流和其他工具连接,将浏览与自动化结合
104
+ - [ ] **强大的编码代理** - *进行中*
105
+ 构建一个全面的编码助手,用于在浏览器中直接进行数据处理和分析
106
106
 
107
107
  - [ ] **智能记忆与个性化** - *计划中*
108
108
  将 VibeSurf 转变为真正的人性化伴侣,具备持久记忆功能,能够学习您的偏好、习惯和浏览模式
@@ -47,6 +47,8 @@ dependencies = [
47
47
  "yfinance>=0.2.66",
48
48
  "pyexecjs>=1.5.1",
49
49
  "youtube-transcript-api>=1.2.2",
50
+ "composio>=0.8.20",
51
+ "composio-langchain>=0.8.20",
50
52
  ]
51
53
 
52
54
  [project.urls]
@@ -0,0 +1,31 @@
1
+ import pdb
2
+
3
+ import vibe_surf
4
+ from vibe_surf.telemetry.service import ProductTelemetry
5
+ from vibe_surf.telemetry.views import CLITelemetryEvent
6
+
7
+
8
+ def test_cli_telemetry_event():
9
+ """Test CLITelemetryEvent structure."""
10
+ event = CLITelemetryEvent(
11
+ version=str(vibe_surf.__version__),
12
+ action='start',
13
+ mode='interactive',
14
+ model='gpt-4o',
15
+ model_provider='OpenAI',
16
+ duration_seconds=10.5,
17
+ error_message=None,
18
+ )
19
+
20
+ telemetry = ProductTelemetry()
21
+
22
+ # Check that posthog client is created
23
+ assert telemetry._posthog_client is not None
24
+
25
+ telemetry.capture(event)
26
+ telemetry.flush()
27
+ pdb.set_trace()
28
+
29
+
30
+ if __name__ == '__main__':
31
+ test_cli_telemetry_event()
@@ -0,0 +1,244 @@
1
+ import asyncio
2
+ import pdb
3
+ import sys
4
+ import time
5
+ import os
6
+ from typing import Dict
7
+
8
+ sys.path.append(".")
9
+
10
+ from dotenv import load_dotenv
11
+
12
+ load_dotenv()
13
+
14
+
15
+ async def test_tools_with_mcp():
16
+ import os
17
+ from vibe_surf.tools.vibesurf_tools import VibeSurfTools
18
+
19
+ mcp_server_config = {
20
+ "mcpServers": {
21
+ # "markitdown": {
22
+ # "command": "docker",
23
+ # "args": [
24
+ # "run",
25
+ # "--rm",
26
+ # "-i",
27
+ # "markitdown-mcp:latest"
28
+ # ]
29
+ # },
30
+ # "desktop-commander": {
31
+ # "command": "npx",
32
+ # "args": [
33
+ # "-y",
34
+ # "@wonderwhy-er/desktop-commander"
35
+ # ],
36
+ # },
37
+ "filesystem": {
38
+ "command": "npx",
39
+ "args": [
40
+ "-y",
41
+ "@modelcontextprotocol/server-filesystem",
42
+ "E:\\AIBrowser\\VibeSurf\\tmp\\code",
43
+ ]
44
+ },
45
+ }
46
+ }
47
+
48
+ controller = VibeSurfTools(mcp_server_config=mcp_server_config)
49
+ await controller.register_mcp_clients()
50
+ pdb.set_trace()
51
+ # action_name = "mcp.desktop-commander.start_process"
52
+ action_name = "mcp.filesystem.list_directory"
53
+ action_info = controller.registry.registry.actions[action_name]
54
+ param_model = action_info.param_model
55
+ print(param_model.model_json_schema())
56
+ # params = {
57
+ # "command": f"python ./tmp/code/test.py",
58
+ # "timeout_ms": 30000
59
+ # }
60
+ params = {
61
+ "path": r"E:\AIBrowser\VibeSurf\tmp\code",
62
+ }
63
+ validated_params = param_model(**params)
64
+ ActionModel_ = controller.registry.create_action_model()
65
+ # Create ActionModel instance with the validated parameters
66
+ action_model = ActionModel_(**{action_name: validated_params})
67
+ result = await controller.act(action_model)
68
+ result = result.extracted_content
69
+
70
+ # print(result)
71
+ # if result and "Command is still running. Use read_output to get more output." in result and "PID" in \
72
+ # result.split("\n")[0]:
73
+ # pid = int(result.split("\n")[0].split("PID")[-1].strip())
74
+ # pdb.set_trace()
75
+ # action_name = "mcp.desktop-commander.read_process_output"
76
+ # action_info = tools.registry.registry.actions[action_name]
77
+ # param_model = action_info.param_model
78
+ # print(param_model.model_json_schema())
79
+ # params = {"pid": pid}
80
+ # validated_params = param_model(**params)
81
+ # action_model = ActionModel_(**{action_name: validated_params})
82
+ # output_result = ""
83
+ # while True:
84
+ # time.sleep(1)
85
+ # result = await tools.act(action_model)
86
+ # result = result.extracted_content
87
+ # if result:
88
+ # output_result = result
89
+ # break
90
+ # print(output_result)
91
+ await controller.unregister_mcp_clients()
92
+
93
+
94
+ async def test_filesystem():
95
+ from vibe_surf.tools.file_system import CustomFileSystem
96
+
97
+ file_system_path = r"E:\AIBrowser\VibeSurf\tmp\vibesurf_workspace"
98
+ filesystem = CustomFileSystem(file_system_path)
99
+ result = await filesystem.create_file("reports/final_report.html")
100
+ print(result)
101
+ result = filesystem.get_absolute_path("reports/final_report.html")
102
+ print(result)
103
+
104
+
105
+ async def test_bu_tools():
106
+ import os
107
+ from vibe_surf.tools.browser_use_tools import BrowserUseTools
108
+
109
+ tools = BrowserUseTools()
110
+ print(tools.registry.registry.actions.keys())
111
+
112
+
113
+ async def test_vibesurf_tools():
114
+ import os
115
+ from vibe_surf.tools.vibesurf_tools import VibeSurfTools
116
+
117
+ tools = VibeSurfTools()
118
+ print(tools.registry.registry.actions.keys())
119
+
120
+
121
+ async def test_finance_tools():
122
+ from vibe_surf.tools.finance_tools import FinanceDataRetriever
123
+
124
+ retriever = FinanceDataRetriever('TSLA')
125
+
126
+ result = retriever.get_finance_data(["get_news"])
127
+
128
+ pdb.set_trace()
129
+
130
+
131
+ async def test_composio_integrations():
132
+ from composio import Composio
133
+ from langchain_core.tools import Tool
134
+ from composio_langchain import LangchainProvider
135
+
136
+ composio = Composio(
137
+ api_key=os.getenv("COMPOSIO_API_KEY"),
138
+ provider=LangchainProvider()
139
+ )
140
+
141
+ schema = composio.toolkits.get()
142
+ composio_toolkits = []
143
+ for schema_ in schema:
144
+ if 'OAUTH2' in schema_.auth_schemes:
145
+ composio_toolkits.append({
146
+ 'name': schema_.name,
147
+ 'slug': schema_.slug,
148
+ 'description': schema_.meta.description,
149
+ 'logo': schema_.meta.logo,
150
+ 'app_url': schema_.meta.app_url,
151
+ })
152
+
153
+ def configure_tools(entity_id: str, app_name: str, limit: int | None = None) -> Dict:
154
+ if limit is None:
155
+ limit = 999
156
+
157
+ tools = composio.tools.get(user_id=entity_id, toolkits=[app_name.lower()], limit=limit)
158
+ configured_tools = []
159
+ tools_list = []
160
+ for tool in tools:
161
+ tools_list.append({
162
+ 'name': tool.name,
163
+ 'description': getattr(tool, 'description', ''),
164
+ 'parameters': tool.args_schema.model_json_schema() if hasattr(tool, 'args_schema') else {},
165
+ 'enabled': True, # Default enabled
166
+ 'func': tool.func,
167
+ })
168
+ return tools_list
169
+
170
+ def _find_active_connection_for_app(entity_id: str, app_name: str) -> tuple[str, str] | None:
171
+ """Find any ACTIVE connection for this app/user. Returns (connection_id, status) or None."""
172
+ try:
173
+ connection_list = composio.connected_accounts.list(
174
+ user_ids=[entity_id], toolkit_slugs=[app_name.lower()]
175
+ )
176
+
177
+ if connection_list and hasattr(connection_list, "items") and connection_list.items:
178
+ for connection in connection_list.items:
179
+ connection_id = getattr(connection, "id", None)
180
+ connection_status = getattr(connection, "status", None)
181
+ if connection_status == "ACTIVE" and connection_id:
182
+ return connection_id, connection_status
183
+
184
+ except (ValueError, ConnectionError) as e:
185
+ return None
186
+ else:
187
+ return None
188
+
189
+ app_name = "gmail"
190
+ entity_id = "default"
191
+ connected_ret = _find_active_connection_for_app(entity_id=entity_id, app_name=app_name)
192
+ if connected_ret and connected_ret[1] == "ACTIVE":
193
+ tools_list = configure_tools(entity_id=entity_id, app_name=app_name)
194
+ toolkit_tools_dict = {}
195
+ toolkit_tools_dict[app_name] = tools_list
196
+ from vibe_surf.tools.composio_client import ComposioClient
197
+ from vibe_surf.tools.vibesurf_tools import VibeSurfTools
198
+
199
+ tools = VibeSurfTools()
200
+
201
+ # Connect to Composio
202
+ composio_client = ComposioClient(
203
+ composio_instance=composio
204
+ )
205
+
206
+ # Register all Composio tools as VibeSurf actions
207
+ await composio_client.register_to_tools(tools, toolkit_tools_dict)
208
+ for tool_ in tools_list:
209
+ if tool_["name"] == "GMAIL_FETCH_EMAILS":
210
+ break
211
+ result = tool_['func'](include_payload=False)
212
+ pdb.set_trace()
213
+ # result = composio.tools.execute(
214
+ # slug="GMAIL_FETCH_EMAILS",
215
+ # arguments={},
216
+ # user_id=entity_id,
217
+ # )
218
+ else:
219
+ auth_configs = composio.auth_configs.list(toolkit_slug=app_name)
220
+
221
+ if len(auth_configs.items) == 0:
222
+ auth_config_id = composio.auth_configs.create(toolkit=app_name,
223
+ options={"type": "use_composio_managed_auth"})
224
+ auth_config_id = auth_config_id
225
+ else:
226
+ auth_config_id = None
227
+ for auth_config in auth_configs.items:
228
+ if auth_config.auth_scheme == "OAUTH2":
229
+ auth_config_id = auth_config.id
230
+ break
231
+ connection_request = composio.connected_accounts.initiate(
232
+ user_id=entity_id, auth_config_id=auth_config_id, allow_multiple=True
233
+ )
234
+ connected_account = connection_request.wait_for_connection()
235
+ print(connection_request.redirect_url)
236
+ connected_ret = _find_active_connection_for_app(entity_id=entity_id, app_name=app_name)
237
+
238
+ if __name__ == '__main__':
239
+ # asyncio.run(test_tools_with_mcp())
240
+ # asyncio.run(test_filesystem())
241
+ # asyncio.run(test_bu_tools())
242
+ # asyncio.run(test_vibesurf_tools())
243
+ # asyncio.run(test_finance_tools())
244
+ asyncio.run(test_composio_integrations())
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.1.31'
32
- __version_tuple__ = version_tuple = (0, 1, 31)
31
+ __version__ = version = '0.1.33'
32
+ __version_tuple__ = version_tuple = (0, 1, 33)
33
33
 
34
- __commit_id__ = commit_id = 'gf2d6ab8af'
34
+ __commit_id__ = commit_id = 'g31e3b1a9f'
@@ -64,7 +64,6 @@ from browser_use.dom.views import DOMInteractedElement
64
64
  from browser_use.filesystem.file_system import FileSystem
65
65
  from browser_use.observability import observe, observe_debug
66
66
  from browser_use.sync import CloudSync
67
- from browser_use.telemetry.service import ProductTelemetry
68
67
  from browser_use.telemetry.views import AgentTelemetryEvent
69
68
  from browser_use.utils import (
70
69
  _log_pretty_path,
@@ -76,6 +75,7 @@ from browser_use.utils import (
76
75
 
77
76
  from browser_use.agent.service import Agent, AgentHookFunc
78
77
  from vibe_surf.tools.file_system import CustomFileSystem
78
+ from vibe_surf.telemetry.service import ProductTelemetry
79
79
 
80
80
  Context = TypeVar('Context')
81
81
 
@@ -65,6 +65,12 @@ You will receive contextual information including:
65
65
  - Include file references in task descriptions when relevant
66
66
  - All file operations automatically resolve relative to the workspace directory
67
67
 
68
+ ## Composio Tools Usage Guidelines
69
+
70
+ When using Composio tools (those with `cpo.{toolkit_name}.{tool_name}` prefix):
71
+ - **Prioritize Composio Tools**: When available, prefer Composio toolkit tools over browser automation for API-based tasks (e.g., Gmail, GitHub, Slack operations) as they provide much higher efficiency through direct API calls
72
+ - **Parameter Optimization**: Always optimize default parameters to prevent information overload. Use appropriate filters and limits to get only essential information. Such as: Set `include_payload=False` when possible to avoid unnecessary response data.
73
+
68
74
  ## Skills Command Processing
69
75
  - When users input commands in `/skill_name` format, please use the corresponding skill action:
70
76
  - **Tab Targeting[Optional]**: Such as `/crawl @1234` → Execute `skill_crawl` with tab_id "1234"
@@ -16,6 +16,8 @@ from vibe_surf.agents.prompts.report_writer_prompt import REPORT_WRITER_PROMPT
16
16
  from vibe_surf.tools.file_system import CustomFileSystem
17
17
  from vibe_surf.tools.report_writer_tools import ReportWriterTools
18
18
  from vibe_surf.agents.views import CustomAgentOutput
19
+ from vibe_surf.telemetry.service import ProductTelemetry
20
+ from vibe_surf.telemetry.views import ReportWriterTelemetryEvent
19
21
 
20
22
  from vibe_surf.logger import get_logger
21
23
 
@@ -66,6 +68,9 @@ class ReportWriterAgent:
66
68
 
67
69
  # Initialize message history as instance variable
68
70
  self.message_history = []
71
+
72
+ # Initialize telemetry
73
+ self.telemetry = ProductTelemetry()
69
74
 
70
75
  logger.info("📄 ReportWriterAgent initialized with LLM-controlled flow")
71
76
 
@@ -111,6 +116,18 @@ class ReportWriterAgent:
111
116
  ReportTaskResult: Result containing success status, message, and report path
112
117
  """
113
118
  logger.info("📝 Starting LLM-controlled report generation...")
119
+
120
+ # Capture telemetry start event
121
+ start_time = time.time()
122
+ import vibe_surf
123
+ start_event = ReportWriterTelemetryEvent(
124
+ version=vibe_surf.__version__,
125
+ action='start',
126
+ model=getattr(self.llm, 'model_name', None),
127
+ model_provider=getattr(self.llm, 'provider', None),
128
+ report_type='html'
129
+ )
130
+ self.telemetry.capture(start_event)
114
131
 
115
132
  # Get current event loop
116
133
  loop = asyncio.get_event_loop()
@@ -260,6 +277,22 @@ Please analyze the task, determine if you need to read any additional files, the
260
277
  elif task_completed:
261
278
  # Task completed successfully by LLM
262
279
  logger.info(f"✅ Report generated successfully: {report_path}")
280
+
281
+ # Capture telemetry completion event
282
+ end_time = time.time()
283
+ duration = end_time - start_time
284
+ completion_event = ReportWriterTelemetryEvent(
285
+ version=vibe_surf.__version__,
286
+ action='report_completed',
287
+ model=getattr(self.llm, 'model_name', None),
288
+ model_provider=getattr(self.llm, 'provider', None),
289
+ duration_seconds=duration,
290
+ success=True,
291
+ report_type='html'
292
+ )
293
+ self.telemetry.capture(completion_event)
294
+ self.telemetry.flush()
295
+
263
296
  return ReportTaskResult(
264
297
  success=True,
265
298
  msg="Report generated successfully by LLM",
@@ -283,6 +316,23 @@ Please analyze the task, determine if you need to read any additional files, the
283
316
 
284
317
  except Exception as e:
285
318
  logger.error(f"❌ Failed to generate report: {e}")
319
+
320
+ # Capture telemetry error event
321
+ end_time = time.time()
322
+ duration = end_time - start_time
323
+ error_event = ReportWriterTelemetryEvent(
324
+ version=vibe_surf.__version__,
325
+ action='error',
326
+ model=getattr(self.llm, 'model_name', None),
327
+ model_provider=getattr(self.llm, 'provider', None),
328
+ duration_seconds=duration,
329
+ success=False,
330
+ error_message=str(e)[:200], # Limit error message length
331
+ report_type='html'
332
+ )
333
+ self.telemetry.capture(error_event)
334
+ self.telemetry.flush()
335
+
286
336
  # Generate a simple fallback report
287
337
  fallback_path = await self._generate_fallback_report(report_data)
288
338
  return ReportTaskResult(
@@ -40,6 +40,9 @@ from vibe_surf.tools.vibesurf_tools import VibeSurfTools
40
40
  from vibe_surf.tools.file_system import CustomFileSystem
41
41
  from vibe_surf.agents.views import VibeSurfAgentSettings
42
42
 
43
+ from vibe_surf.telemetry.service import ProductTelemetry
44
+ from vibe_surf.telemetry.views import VibeSurfAgentTelemetryEvent
45
+
43
46
  from vibe_surf.logger import get_logger
44
47
 
45
48
  logger = get_logger(__name__)
@@ -479,7 +482,7 @@ async def _vibesurf_agent_node_impl(state: VibeSurfState) -> VibeSurfState:
479
482
  llm=vibesurf_agent.llm,
480
483
  file_system=vibesurf_agent.file_system,
481
484
  )
482
- if action_name.startswith("skill_"):
485
+ if action_name in ['skill_search', 'skill_crawl', 'skill_summary', 'skill_deep_research']:
483
486
  state.current_step = "END"
484
487
  # Format final response
485
488
  final_response = f"{result.extracted_content}" or f"{result.error}"
@@ -1041,6 +1044,9 @@ class VibeSurfAgent:
1041
1044
  self._execution_task: Optional[asyncio.Task] = None
1042
1045
 
1043
1046
  logger.info("🌊 VibeSurf Agent initialized with LangGraph workflow")
1047
+
1048
+ # Initialize telemetry
1049
+ self.telemetry = ProductTelemetry()
1044
1050
 
1045
1051
  def load_message_history(self, session_id: Optional[str] = None) -> list:
1046
1052
  """Load message history for a specific session, or return [] for new sessions"""
@@ -1568,6 +1574,20 @@ Please continue with your assigned work, incorporating this guidance only if it'
1568
1574
  str: Markdown summary of execution results
1569
1575
  """
1570
1576
  logger.info(f"🚀 Starting VibeSurfAgent execution for task: {task}. Powered by LLM model: {self.llm.model_name}")
1577
+
1578
+ # Capture telemetry start event
1579
+ start_time = time.time()
1580
+ import vibe_surf
1581
+ start_event = VibeSurfAgentTelemetryEvent(
1582
+ version=vibe_surf.__version__,
1583
+ action='start',
1584
+ task_description=task if task else None, # Limit task description length
1585
+ model=getattr(self.llm, 'model_name', None),
1586
+ model_provider=getattr(self.llm, 'provider', None),
1587
+ session_id=session_id
1588
+ )
1589
+ self.telemetry.capture(start_event)
1590
+
1571
1591
  try:
1572
1592
  self.settings.agent_mode = agent_mode
1573
1593
  session_id = session_id or self.cur_session_id or uuid7str()
@@ -1642,6 +1662,23 @@ Please continue with your assigned work, incorporating this guidance only if it'
1642
1662
  # Get final result
1643
1663
  result = await self._get_result(final_state)
1644
1664
  logger.info("✅ VibeSurfAgent execution completed")
1665
+
1666
+ # Capture telemetry completion event
1667
+ end_time = time.time()
1668
+ duration = end_time - start_time
1669
+ completion_event = VibeSurfAgentTelemetryEvent(
1670
+ version=vibe_surf.__version__,
1671
+ action='task_completed',
1672
+ task_description=task[:200] if task else None,
1673
+ model=getattr(self.llm, 'model_name', None),
1674
+ model_provider=getattr(self.llm, 'provider', None),
1675
+ duration_seconds=duration,
1676
+ success=True,
1677
+ session_id=session_id
1678
+ )
1679
+ self.telemetry.capture(completion_event)
1680
+ self.telemetry.flush()
1681
+
1645
1682
  return result
1646
1683
 
1647
1684
  except asyncio.CancelledError:
@@ -1659,6 +1696,24 @@ Please continue with your assigned work, incorporating this guidance only if it'
1659
1696
  import traceback
1660
1697
  traceback.print_exc()
1661
1698
  logger.error(f"❌ VibeSurfAgent execution failed: {e}")
1699
+
1700
+ # Capture telemetry error event
1701
+ end_time = time.time()
1702
+ duration = end_time - start_time
1703
+ error_event = VibeSurfAgentTelemetryEvent(
1704
+ version=vibe_surf.__version__,
1705
+ action='error',
1706
+ task_description=BrowserTaskResult if task else None,
1707
+ model=getattr(self.llm, 'model_name', None),
1708
+ model_provider=getattr(self.llm, 'provider', None),
1709
+ duration_seconds=duration,
1710
+ success=False,
1711
+ error_message=str(e), # Limit error message length
1712
+ session_id=session_id
1713
+ )
1714
+ self.telemetry.capture(error_event)
1715
+ self.telemetry.flush()
1716
+
1662
1717
  # Add error activity log
1663
1718
  if self.activity_logs:
1664
1719
  activity_entry = {