vibesurf 0.1.37__tar.gz → 0.1.39__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.37 → vibesurf-0.1.39}/PKG-INFO +1 -1
  2. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/_version.py +3 -3
  3. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/agents/prompts/vibe_surf_prompt.py +1 -1
  4. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/agents/report_writer_agent.py +5 -5
  5. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/agents/vibe_surf_agent.py +8 -6
  6. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/llm_config.py +17 -3
  7. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/utils/llm_factory.py +8 -0
  8. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/browser/agent_browser_session.py +73 -1
  9. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibesurf.egg-info/PKG-INFO +1 -1
  10. {vibesurf-0.1.37 → vibesurf-0.1.39}/.env.example +0 -0
  11. {vibesurf-0.1.37 → vibesurf-0.1.39}/.github/workflows/publish.yml +0 -0
  12. {vibesurf-0.1.37 → vibesurf-0.1.39}/.gitignore +0 -0
  13. {vibesurf-0.1.37 → vibesurf-0.1.39}/.python-version +0 -0
  14. {vibesurf-0.1.37 → vibesurf-0.1.39}/LICENSE +0 -0
  15. {vibesurf-0.1.37 → vibesurf-0.1.39}/MANIFEST.in +0 -0
  16. {vibesurf-0.1.37 → vibesurf-0.1.39}/README.md +0 -0
  17. {vibesurf-0.1.37 → vibesurf-0.1.39}/README_zh.md +0 -0
  18. {vibesurf-0.1.37 → vibesurf-0.1.39}/docs/EXECUTABLE_BUILD.md +0 -0
  19. {vibesurf-0.1.37 → vibesurf-0.1.39}/docs/PYPI_SETUP.md +0 -0
  20. {vibesurf-0.1.37 → vibesurf-0.1.39}/pyproject.toml +0 -0
  21. {vibesurf-0.1.37 → vibesurf-0.1.39}/scripts/build-local.bat +0 -0
  22. {vibesurf-0.1.37 → vibesurf-0.1.39}/scripts/build-local.sh +0 -0
  23. {vibesurf-0.1.37 → vibesurf-0.1.39}/setup.cfg +0 -0
  24. {vibesurf-0.1.37 → vibesurf-0.1.39}/tests/test_agents.py +0 -0
  25. {vibesurf-0.1.37 → vibesurf-0.1.39}/tests/test_backend_api.py +0 -0
  26. {vibesurf-0.1.37 → vibesurf-0.1.39}/tests/test_browser.py +0 -0
  27. {vibesurf-0.1.37 → vibesurf-0.1.39}/tests/test_telemetry.py +0 -0
  28. {vibesurf-0.1.37 → vibesurf-0.1.39}/tests/test_tools.py +0 -0
  29. {vibesurf-0.1.37 → vibesurf-0.1.39}/tests/test_voice_api.py +0 -0
  30. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/__init__.py +0 -0
  31. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/agents/__init__.py +0 -0
  32. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/agents/browser_use_agent.py +0 -0
  33. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/agents/prompts/__init__.py +0 -0
  34. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/agents/prompts/report_writer_prompt.py +0 -0
  35. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/agents/views.py +0 -0
  36. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/__init__.py +0 -0
  37. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/api/__init__.py +0 -0
  38. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/api/activity.py +0 -0
  39. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/api/agent.py +0 -0
  40. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/api/browser.py +0 -0
  41. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/api/composio.py +0 -0
  42. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/api/config.py +0 -0
  43. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/api/files.py +0 -0
  44. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/api/models.py +0 -0
  45. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/api/task.py +0 -0
  46. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/api/voices.py +0 -0
  47. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/database/__init__.py +0 -0
  48. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/database/manager.py +0 -0
  49. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/database/migrations/v001_initial_schema.sql +0 -0
  50. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/database/migrations/v002_add_agent_mode.sql +0 -0
  51. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/database/migrations/v003_fix_task_status_case.sql +0 -0
  52. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/database/migrations/v004_add_voice_profiles.sql +0 -0
  53. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/database/migrations/v005_add_composio_integration.sql +0 -0
  54. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/database/migrations/v006_add_credentials_table.sql +0 -0
  55. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/database/models.py +0 -0
  56. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/database/queries.py +0 -0
  57. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/database/schemas.py +0 -0
  58. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/main.py +0 -0
  59. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/shared_state.py +0 -0
  60. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/utils/__init__.py +0 -0
  61. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/utils/encryption.py +0 -0
  62. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/utils/utils.py +0 -0
  63. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/backend/voice_model_config.py +0 -0
  64. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/browser/__init__.py +0 -0
  65. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/browser/agen_browser_profile.py +0 -0
  66. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/browser/browser_manager.py +0 -0
  67. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/browser/utils.py +0 -0
  68. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/browser/watchdogs/__init__.py +0 -0
  69. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/browser/watchdogs/action_watchdog.py +0 -0
  70. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/browser/watchdogs/dom_watchdog.py +0 -0
  71. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/background.js +0 -0
  72. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/config.js +0 -0
  73. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/content.js +0 -0
  74. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/dev-reload.js +0 -0
  75. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/icons/logo.icns +0 -0
  76. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/icons/logo.png +0 -0
  77. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/manifest.json +0 -0
  78. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/permission-iframe.html +0 -0
  79. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/permission-request.html +0 -0
  80. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/popup.html +0 -0
  81. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/scripts/api-client.js +0 -0
  82. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/scripts/file-manager.js +0 -0
  83. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/scripts/history-manager.js +0 -0
  84. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/scripts/main.js +0 -0
  85. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/scripts/markdown-it.min.js +0 -0
  86. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/scripts/modal-manager.js +0 -0
  87. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/scripts/permission-iframe-request.js +0 -0
  88. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/scripts/permission-request.js +0 -0
  89. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/scripts/session-manager.js +0 -0
  90. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/scripts/settings-manager.js +0 -0
  91. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/scripts/ui-manager.js +0 -0
  92. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/scripts/user-settings-storage.js +0 -0
  93. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/scripts/voice-recorder.js +0 -0
  94. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/sidepanel.html +0 -0
  95. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/styles/activity.css +0 -0
  96. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/styles/animations.css +0 -0
  97. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/styles/base.css +0 -0
  98. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/styles/components.css +0 -0
  99. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/styles/history-modal.css +0 -0
  100. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/styles/input.css +0 -0
  101. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/styles/layout.css +0 -0
  102. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/styles/responsive.css +0 -0
  103. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/styles/settings-environment.css +0 -0
  104. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/styles/settings-forms.css +0 -0
  105. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/styles/settings-integrations.css +0 -0
  106. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/styles/settings-modal.css +0 -0
  107. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/styles/settings-profiles.css +0 -0
  108. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/styles/settings-responsive.css +0 -0
  109. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/styles/settings-utilities.css +0 -0
  110. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/chrome_extension/styles/variables.css +0 -0
  111. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/cli.py +0 -0
  112. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/common.py +0 -0
  113. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/llm/__init__.py +0 -0
  114. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/llm/openai_compatible.py +0 -0
  115. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/logger.py +0 -0
  116. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/telemetry/__init__.py +0 -0
  117. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/telemetry/service.py +0 -0
  118. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/telemetry/views.py +0 -0
  119. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/__init__.py +0 -0
  120. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/browser_use_tools.py +0 -0
  121. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/composio_client.py +0 -0
  122. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/file_system.py +0 -0
  123. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/finance_tools.py +0 -0
  124. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/mcp_client.py +0 -0
  125. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/report_writer_tools.py +0 -0
  126. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/utils.py +0 -0
  127. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/vibesurf_registry.py +0 -0
  128. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/vibesurf_tools.py +0 -0
  129. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/views.py +0 -0
  130. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/voice_asr.py +0 -0
  131. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/website_api/__init__.py +0 -0
  132. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/website_api/douyin/__init__.py +0 -0
  133. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/website_api/douyin/client.py +0 -0
  134. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/website_api/douyin/douyin.js +0 -0
  135. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/website_api/douyin/helpers.py +0 -0
  136. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/website_api/weibo/__init__.py +0 -0
  137. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/website_api/weibo/client.py +0 -0
  138. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/website_api/weibo/helpers.py +0 -0
  139. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/website_api/xhs/__init__.py +0 -0
  140. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/website_api/xhs/client.py +0 -0
  141. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/website_api/xhs/helpers.py +0 -0
  142. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/website_api/youtube/__init__.py +0 -0
  143. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/website_api/youtube/client.py +0 -0
  144. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/tools/website_api/youtube/helpers.py +0 -0
  145. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibe_surf/utils.py +0 -0
  146. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibesurf.egg-info/SOURCES.txt +0 -0
  147. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibesurf.egg-info/dependency_links.txt +0 -0
  148. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibesurf.egg-info/entry_points.txt +0 -0
  149. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibesurf.egg-info/requires.txt +0 -0
  150. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibesurf.egg-info/top_level.txt +0 -0
  151. {vibesurf-0.1.37 → vibesurf-0.1.39}/vibesurf.spec +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vibesurf
3
- Version: 0.1.37
3
+ Version: 0.1.39
4
4
  Summary: VibeSurf: A powerful browser assistant for vibe surfing
5
5
  Author: WarmShao
6
6
  License: Apache-2.0
@@ -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.37'
32
- __version_tuple__ = version_tuple = (0, 1, 37)
31
+ __version__ = version = '0.1.39'
32
+ __version_tuple__ = version_tuple = (0, 1, 39)
33
33
 
34
- __commit_id__ = commit_id = 'g8865ef13e'
34
+ __commit_id__ = commit_id = 'g60f699d0a'
@@ -78,7 +78,7 @@ When using Composio tools (those with `cpo.{toolkit_name}.{tool_name}` prefix):
78
78
  - **Special Cases**: `skill_deep_research` only returns guidelines only, then follow guidelines to conduct actual research
79
79
  - **Execution Policy**: Skill actions execute only once (no need to retry if errors occur), and all results - whether successful or failed - should be presented to users in structured markdown format.
80
80
  - **Follow-up Operations**: When users input skill operations without specifying additional tasks, do not automatically perform subsequent operations. Only perform additional tool operations when users specifically request actions like saving results to files or writing reports.
81
- - After `/search` completion, NEVER use browser agent to deeply investigate search result (unless explicitly emphasized by the user). The user usually only need the search results. Just return the search results.
81
+ - **Search Skill Usage**: `/skill_search` should ONLY be used when users want to quickly obtain specific information or news and user specify `/skill_search` in request. Please analyze user intent carefully - if the request contains other browser tasks or requires more complex web operations, you should generally execute browser tasks instead of using skill search.
82
82
 
83
83
  ## Language Adaptability
84
84
 
@@ -163,19 +163,19 @@ class ReportWriterAgent:
163
163
  You must ALWAYS respond with a valid JSON in this exact format:
164
164
  {{
165
165
  "thinking": "A structured <think>-style reasoning.",
166
- "action":[{{"task_done": {{ }}, // ... more actions in sequence]
166
+ "action":[{{"<action_name>": {{<action_params>}}]
167
167
  }}
168
168
 
169
- Action list should NEVER be empty.
169
+ Action list should NEVER be empty and Each step can only output one action. If multiple actions are output, only the first one will be executed.
170
170
  """
171
171
  else:
172
172
  report_system_prompt += """
173
173
  You must ALWAYS respond with a valid JSON in this exact format:
174
174
  {{
175
- "action":[{{"task_done": {{ }}, // ... more actions in sequence]
175
+ "action":[{{"<action_name>": {{<action_params>}}]
176
176
  }}
177
177
 
178
- Action list should NEVER be empty.
178
+ Action list should NEVER be empty and Each step can only output one action. If multiple actions are output, only the first one will be executed.
179
179
  """
180
180
  self.message_history.append(SystemMessage(content=report_system_prompt))
181
181
 
@@ -234,7 +234,7 @@ Please analyze the task, determine if you need to read any additional files, the
234
234
  results = []
235
235
  time_start = time.time()
236
236
 
237
- for i, action in enumerate(actions):
237
+ for i, action in enumerate(actions[:1]):
238
238
  action_data = action.model_dump(exclude_unset=True)
239
239
  action_name = next(iter(action_data.keys())) if action_data else 'unknown'
240
240
  logger.info(f"🛠️ Executing action {i + 1}/{len(actions)}: {action_name}")
@@ -393,6 +393,8 @@ async def _vibesurf_agent_node_impl(state: VibeSurfState) -> VibeSurfState:
393
393
  context_info.append(f"Generated Report: ❌ Failed - {state.generated_report_result.msg}\nPath: {state.generated_report_result.report_path}\n")
394
394
 
395
395
  context_str = "\n".join(context_info) if context_info else "No additional context available."
396
+ logger.debug("VibeSurf State Message:\n")
397
+ logger.debug(context_str)
396
398
  vibesurf_agent.message_history.append(UserMessage(content=context_str))
397
399
 
398
400
  try:
@@ -427,7 +429,7 @@ async def _vibesurf_agent_node_impl(state: VibeSurfState) -> VibeSurfState:
427
429
  if hasattr(parsed, 'thinking') and parsed.thinking:
428
430
  await log_agent_activity(state, agent_name, "thinking", parsed.thinking)
429
431
 
430
- for i, action in enumerate(actions):
432
+ for i, action in enumerate(actions[:1]):
431
433
  action_data = action.model_dump(exclude_unset=True)
432
434
  action_name = next(iter(action_data.keys())) if action_data else 'unknown'
433
435
  logger.info(f"🛠️ Processing VibeSurf action {i + 1}/{len(actions)}: {action_name}")
@@ -1651,19 +1653,19 @@ Please continue with your assigned work, incorporating this guidance only if it'
1651
1653
  You must ALWAYS respond with a valid JSON in this exact format:
1652
1654
  {{
1653
1655
  "thinking": "A structured <think>-style reasoning.",
1654
- "action":[{{"task_done": {{ }}, // ... more actions in sequence]
1656
+ "action":[{{"<action_name>": {{<action_params>}}]
1655
1657
  }}
1656
1658
 
1657
- Action list should NEVER be empty.
1659
+ Action list should NEVER be empty and Each step can only output one action. If multiple actions are output, only the first one will be executed.
1658
1660
  """
1659
1661
  else:
1660
1662
  vibesurf_system_prompt += """
1661
1663
  You must ALWAYS respond with a valid JSON in this exact format:
1662
1664
  {{
1663
- "action":[{{"task_done": {{ }}, // ... more actions in sequence]
1665
+ "action":[{{"<action_name>": {{<action_params>}}]
1664
1666
  }}
1665
1667
 
1666
- Action list should NEVER be empty.
1668
+ Action list should NEVER be empty and Each step can only output one action. If multiple actions are output, only the first one will be executed.
1667
1669
  """
1668
1670
  self.message_history.append(SystemMessage(content=vibesurf_system_prompt))
1669
1671
 
@@ -1728,7 +1730,7 @@ Action list should NEVER be empty.
1728
1730
  completion_event = VibeSurfAgentTelemetryEvent(
1729
1731
  version=vibe_surf.__version__,
1730
1732
  action='task_completed',
1731
- task_description=task[:200] if task else None,
1733
+ task_description=task if task else None,
1732
1734
  model=getattr(self.llm, 'model_name', None),
1733
1735
  model_provider=getattr(self.llm, 'provider', None),
1734
1736
  duration_seconds=duration,
@@ -69,6 +69,12 @@ LLM_PROVIDERS = {
69
69
  "anthropic_bedrock": [
70
70
  ],
71
71
  "openai_compatible": [
72
+ ],
73
+ "lm_studio":[
74
+ "qwen/qwen3-vl-8b",
75
+ "qwen/qwen3-vl-30b",
76
+ "qwen/qwen3-14b",
77
+ "openai/gpt-oss-20b"
72
78
  ]
73
79
  }
74
80
 
@@ -167,15 +173,23 @@ PROVIDER_METADATA = {
167
173
  "qwen": {
168
174
  "display_name": "Qwen",
169
175
  "requires_api_key": True,
170
- "requires_base_url": True,
176
+ "requires_base_url": False,
171
177
  "supports_tools": True,
172
- "supports_vision": True,
178
+ "supports_vision": False,
173
179
  "default_model": ""
174
180
  },
175
181
  "kimi": {
176
182
  "display_name": "Kimi",
177
183
  "requires_api_key": True,
178
- "requires_base_url": True,
184
+ "requires_base_url": False,
185
+ "supports_tools": True,
186
+ "supports_vision": False,
187
+ "default_model": ""
188
+ },
189
+ "lm_studio": {
190
+ "display_name": "LM Studio",
191
+ "requires_api_key": False,
192
+ "requires_base_url": False,
179
193
  "supports_tools": True,
180
194
  "supports_vision": True,
181
195
  "default_model": ""
@@ -193,6 +193,14 @@ def create_llm_from_profile(llm_profile) -> BaseChatModel:
193
193
  **common_params
194
194
  )
195
195
 
196
+ elif provider == "lm_studio":
197
+ return ChatOpenAI(
198
+ model=model,
199
+ base_url="http://localhost:1234/v1" or base_url,
200
+ api_key="lm_studio",
201
+ **common_params
202
+ )
203
+
196
204
  elif provider == "openai_compatible":
197
205
  if not base_url:
198
206
  raise ValueError("OpenAI Compatible provider requires base_url")
@@ -5,7 +5,7 @@ import os
5
5
  import pdb
6
6
  from pathlib import Path
7
7
  from typing import TYPE_CHECKING, Any, Literal, Self, Union, cast, Optional
8
-
8
+ from cdp_use.cdp.target import AttachedToTargetEvent, SessionID, TargetID
9
9
  from browser_use.browser.session import BrowserSession, CDPSession
10
10
  from pydantic import Field
11
11
  from browser_use.browser.events import (
@@ -717,6 +717,78 @@ class AgentBrowserSession(BrowserSession):
717
717
  self.logger.error(f'Concurrent screenshot failed: {type(e).__name__}: {e}')
718
718
  raise
719
719
 
720
+ async def get_or_create_cdp_session(
721
+ self, target_id: TargetID | None = None, focus: bool = True, new_socket: bool | None = None
722
+ ) -> CDPSession:
723
+ """Get or create a CDP session for a target.
724
+
725
+ Args:
726
+ target_id: Target ID to get session for. If None, uses current agent focus.
727
+ focus: If True, switches agent focus to this target. If False, just returns session without changing focus.
728
+ new_socket: If True, create a dedicated WebSocket connection. If None (default), creates new socket for new targets only.
729
+
730
+ Returns:
731
+ CDPSession for the specified target.
732
+ """
733
+ assert self.cdp_url is not None, 'CDP URL not set - browser may not be configured or launched yet'
734
+ assert self._cdp_client_root is not None, 'Root CDP client not initialized - browser may not be connected yet'
735
+ assert self.agent_focus is not None, 'CDP session not initialized - browser may not be connected yet'
736
+
737
+ # If no target_id specified, use the current target_id
738
+ if target_id is None:
739
+ target_id = self.agent_focus.target_id
740
+
741
+ # Check if we already have a session for this target in the pool
742
+ if target_id in self._cdp_session_pool:
743
+ session = self._cdp_session_pool[target_id]
744
+ if focus and self.agent_focus.target_id != target_id:
745
+ self.logger.debug(
746
+ f'[get_or_create_cdp_session] Switching agent focus from {self.agent_focus.target_id} to {target_id}'
747
+ )
748
+ self.agent_focus = session
749
+ if focus:
750
+ await session.cdp_client.send.Target.activateTarget(params={'targetId': session.target_id})
751
+ await session.cdp_client.send.Runtime.runIfWaitingForDebugger(session_id=session.session_id)
752
+ # else:
753
+ # self.logger.debug(f'[get_or_create_cdp_session] Reusing existing session for {target_id} (focus={focus})')
754
+ return session
755
+
756
+ # If it's the current focus target, return that session
757
+ if self.agent_focus.target_id == target_id:
758
+ self._cdp_session_pool[target_id] = self.agent_focus
759
+ return self.agent_focus
760
+
761
+ # Create new session for this target
762
+ # Default to True for new sessions (each new target gets its own WebSocket)
763
+ should_use_new_socket = True if new_socket is None else new_socket
764
+ self.logger.debug(
765
+ f'[get_or_create_cdp_session] Creating new CDP session for target {target_id} (new_socket={should_use_new_socket})'
766
+ )
767
+ session = await CDPSession.for_target(
768
+ self._cdp_client_root,
769
+ target_id,
770
+ new_socket=should_use_new_socket,
771
+ cdp_url=self.cdp_url if should_use_new_socket else None,
772
+ )
773
+ self._cdp_session_pool[target_id] = session
774
+ # log length of _cdp_session_pool
775
+ self.logger.debug(f'[get_or_create_cdp_session] new _cdp_session_pool length: {len(self._cdp_session_pool)}')
776
+
777
+ # Only change agent focus if requested
778
+ if focus:
779
+ self.logger.debug(
780
+ f'[get_or_create_cdp_session] Switching agent focus from {self.agent_focus.target_id} to {target_id}'
781
+ )
782
+ self.agent_focus = session
783
+ await session.cdp_client.send.Target.activateTarget(params={'targetId': session.target_id})
784
+ await session.cdp_client.send.Runtime.runIfWaitingForDebugger(session_id=session.session_id)
785
+ else:
786
+ self.logger.debug(
787
+ f'[get_or_create_cdp_session] Created session for {target_id} without changing focus (still on {self.agent_focus.target_id})'
788
+ )
789
+
790
+ return session
791
+
720
792
  async def get_html_content(self, target_id: Optional[str] = None) -> str:
721
793
  """
722
794
  Get html content of current page
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vibesurf
3
- Version: 0.1.37
3
+ Version: 0.1.39
4
4
  Summary: VibeSurf: A powerful browser assistant for vibe surfing
5
5
  Author: WarmShao
6
6
  License: Apache-2.0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes