vibesurf 0.1.30__tar.gz → 0.1.32__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 (140) hide show
  1. {vibesurf-0.1.30 → vibesurf-0.1.32}/PKG-INFO +5 -4
  2. {vibesurf-0.1.30 → vibesurf-0.1.32}/pyproject.toml +4 -3
  3. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/_version.py +3 -3
  4. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/agents/vibe_surf_agent.py +1 -1
  5. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/shared_state.py +2 -1
  6. vibesurf-0.1.32/vibe_surf/backend/utils/utils.py +42 -0
  7. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/cli.py +0 -3
  8. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/browser_use_tools.py +90 -90
  9. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/vibesurf_tools.py +15 -1
  10. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/views.py +2 -1
  11. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/website_api/youtube/client.py +57 -0
  12. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibesurf.egg-info/PKG-INFO +5 -4
  13. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibesurf.egg-info/SOURCES.txt +2 -0
  14. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibesurf.egg-info/requires.txt +2 -1
  15. {vibesurf-0.1.30 → vibesurf-0.1.32}/.env.example +0 -0
  16. {vibesurf-0.1.30 → vibesurf-0.1.32}/.github/workflows/publish.yml +0 -0
  17. {vibesurf-0.1.30 → vibesurf-0.1.32}/.gitignore +0 -0
  18. {vibesurf-0.1.30 → vibesurf-0.1.32}/.python-version +0 -0
  19. {vibesurf-0.1.30 → vibesurf-0.1.32}/LICENSE +0 -0
  20. {vibesurf-0.1.30 → vibesurf-0.1.32}/MANIFEST.in +0 -0
  21. {vibesurf-0.1.30 → vibesurf-0.1.32}/README.md +0 -0
  22. {vibesurf-0.1.30 → vibesurf-0.1.32}/README_zh.md +0 -0
  23. {vibesurf-0.1.30 → vibesurf-0.1.32}/docs/EXECUTABLE_BUILD.md +0 -0
  24. {vibesurf-0.1.30 → vibesurf-0.1.32}/docs/PYPI_SETUP.md +0 -0
  25. {vibesurf-0.1.30 → vibesurf-0.1.32}/scripts/build-local.bat +0 -0
  26. {vibesurf-0.1.30 → vibesurf-0.1.32}/scripts/build-local.sh +0 -0
  27. {vibesurf-0.1.30 → vibesurf-0.1.32}/setup.cfg +0 -0
  28. {vibesurf-0.1.30 → vibesurf-0.1.32}/tests/test_agents.py +0 -0
  29. {vibesurf-0.1.30 → vibesurf-0.1.32}/tests/test_backend_api.py +0 -0
  30. {vibesurf-0.1.30 → vibesurf-0.1.32}/tests/test_browser.py +0 -0
  31. {vibesurf-0.1.30 → vibesurf-0.1.32}/tests/test_tools.py +0 -0
  32. {vibesurf-0.1.30 → vibesurf-0.1.32}/tests/test_voice_api.py +0 -0
  33. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/__init__.py +0 -0
  34. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/agents/__init__.py +0 -0
  35. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/agents/browser_use_agent.py +0 -0
  36. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/agents/prompts/__init__.py +0 -0
  37. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/agents/prompts/report_writer_prompt.py +0 -0
  38. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/agents/prompts/vibe_surf_prompt.py +0 -0
  39. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/agents/report_writer_agent.py +0 -0
  40. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/agents/views.py +0 -0
  41. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/__init__.py +0 -0
  42. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/api/__init__.py +0 -0
  43. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/api/activity.py +0 -0
  44. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/api/agent.py +0 -0
  45. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/api/browser.py +0 -0
  46. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/api/config.py +0 -0
  47. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/api/files.py +0 -0
  48. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/api/models.py +0 -0
  49. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/api/task.py +0 -0
  50. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/api/voices.py +0 -0
  51. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/database/__init__.py +0 -0
  52. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/database/manager.py +0 -0
  53. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/database/migrations/v001_initial_schema.sql +0 -0
  54. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/database/migrations/v002_add_agent_mode.sql +0 -0
  55. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/database/migrations/v003_fix_task_status_case.sql +0 -0
  56. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/database/migrations/v004_add_voice_profiles.sql +0 -0
  57. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/database/models.py +0 -0
  58. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/database/queries.py +0 -0
  59. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/database/schemas.py +0 -0
  60. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/llm_config.py +0 -0
  61. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/main.py +0 -0
  62. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/utils/__init__.py +0 -0
  63. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/utils/encryption.py +0 -0
  64. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/utils/llm_factory.py +0 -0
  65. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/backend/voice_model_config.py +0 -0
  66. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/browser/__init__.py +0 -0
  67. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/browser/agen_browser_profile.py +0 -0
  68. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/browser/agent_browser_session.py +0 -0
  69. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/browser/browser_manager.py +0 -0
  70. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/browser/utils.py +0 -0
  71. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/browser/watchdogs/__init__.py +0 -0
  72. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/browser/watchdogs/action_watchdog.py +0 -0
  73. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/browser/watchdogs/dom_watchdog.py +0 -0
  74. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/background.js +0 -0
  75. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/config.js +0 -0
  76. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/content.js +0 -0
  77. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/dev-reload.js +0 -0
  78. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/icons/logo.icns +0 -0
  79. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/icons/logo.png +0 -0
  80. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/manifest.json +0 -0
  81. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/permission-iframe.html +0 -0
  82. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/permission-request.html +0 -0
  83. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/popup.html +0 -0
  84. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/scripts/api-client.js +0 -0
  85. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/scripts/file-manager.js +0 -0
  86. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/scripts/history-manager.js +0 -0
  87. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/scripts/main.js +0 -0
  88. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/scripts/markdown-it.min.js +0 -0
  89. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/scripts/modal-manager.js +0 -0
  90. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/scripts/permission-iframe-request.js +0 -0
  91. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/scripts/permission-request.js +0 -0
  92. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/scripts/session-manager.js +0 -0
  93. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/scripts/settings-manager.js +0 -0
  94. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/scripts/ui-manager.js +0 -0
  95. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/scripts/user-settings-storage.js +0 -0
  96. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/scripts/voice-recorder.js +0 -0
  97. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/sidepanel.html +0 -0
  98. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/styles/activity.css +0 -0
  99. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/styles/animations.css +0 -0
  100. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/styles/base.css +0 -0
  101. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/styles/components.css +0 -0
  102. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/styles/history-modal.css +0 -0
  103. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/styles/input.css +0 -0
  104. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/styles/layout.css +0 -0
  105. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/styles/responsive.css +0 -0
  106. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/styles/settings-environment.css +0 -0
  107. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/styles/settings-forms.css +0 -0
  108. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/styles/settings-modal.css +0 -0
  109. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/styles/settings-profiles.css +0 -0
  110. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/styles/settings-responsive.css +0 -0
  111. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/styles/settings-utilities.css +0 -0
  112. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/chrome_extension/styles/variables.css +0 -0
  113. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/common.py +0 -0
  114. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/llm/__init__.py +0 -0
  115. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/llm/openai_compatible.py +0 -0
  116. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/logger.py +0 -0
  117. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/__init__.py +0 -0
  118. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/file_system.py +0 -0
  119. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/finance_tools.py +0 -0
  120. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/mcp_client.py +0 -0
  121. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/report_writer_tools.py +0 -0
  122. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/vibesurf_registry.py +0 -0
  123. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/voice_asr.py +0 -0
  124. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/website_api/__init__.py +0 -0
  125. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/website_api/douyin/__init__.py +0 -0
  126. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/website_api/douyin/client.py +0 -0
  127. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/website_api/douyin/douyin.js +0 -0
  128. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/website_api/douyin/helpers.py +0 -0
  129. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/website_api/weibo/__init__.py +0 -0
  130. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/website_api/weibo/client.py +0 -0
  131. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/website_api/weibo/helpers.py +0 -0
  132. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/website_api/xhs/__init__.py +0 -0
  133. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/website_api/xhs/client.py +0 -0
  134. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/website_api/xhs/helpers.py +0 -0
  135. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/website_api/youtube/__init__.py +0 -0
  136. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibe_surf/tools/website_api/youtube/helpers.py +0 -0
  137. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibesurf.egg-info/dependency_links.txt +0 -0
  138. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibesurf.egg-info/entry_points.txt +0 -0
  139. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibesurf.egg-info/top_level.txt +0 -0
  140. {vibesurf-0.1.30 → vibesurf-0.1.32}/vibesurf.spec +0 -0
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vibesurf
3
- Version: 0.1.30
3
+ Version: 0.1.32
4
4
  Summary: VibeSurf: A powerful browser assistant for vibe surfing
5
- Author: Shao Warm
5
+ Author: WarmShao
6
6
  License: Apache-2.0
7
- Project-URL: Repository, https://github.com/vvincent1234/VibeSurf
7
+ Project-URL: Repository, https://github.com/vibesurf-ai/VibeSurf
8
8
  Keywords: browser use,browser automation,browser assistant,agentic browser,vibe surf,AI browser
9
9
  Classifier: Development Status :: 3 - Alpha
10
10
  Classifier: Intended Audience :: Developers
@@ -21,7 +21,7 @@ Requires-Dist: aiofiles>=24.1.0
21
21
  Requires-Dist: anyio>=4.9.0
22
22
  Requires-Dist: psutil>=7.0.0
23
23
  Requires-Dist: pydantic>=2.11.5
24
- Requires-Dist: cdp-use>=1.4.0
24
+ Requires-Dist: cdp-use>=1.4.1
25
25
  Requires-Dist: json-repair>=0.48.0
26
26
  Requires-Dist: aiohttp>=3.12.15
27
27
  Requires-Dist: scikit-image>=0.25.2
@@ -45,6 +45,7 @@ Requires-Dist: pathvalidate>=3.3.1
45
45
  Requires-Dist: dashscope>=1.24.5
46
46
  Requires-Dist: yfinance>=0.2.66
47
47
  Requires-Dist: pyexecjs>=1.5.1
48
+ Requires-Dist: youtube-transcript-api>=1.2.2
48
49
  Dynamic: license-file
49
50
 
50
51
  # VibeSurf: A powerful browser assistant for vibe surfing
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "vibesurf"
3
3
  dynamic = ["version"]
4
- authors = [{ name = "Shao Warm" }]
4
+ authors = [{ name = "WarmShao" }]
5
5
  description = "VibeSurf: A powerful browser assistant for vibe surfing"
6
6
  readme = "README.md"
7
7
  requires-python = ">=3.11"
@@ -22,7 +22,7 @@ dependencies = [
22
22
  "anyio>=4.9.0",
23
23
  "psutil>=7.0.0",
24
24
  "pydantic>=2.11.5",
25
- "cdp-use>=1.4.0",
25
+ "cdp-use>=1.4.1",
26
26
  "json-repair>=0.48.0",
27
27
  "aiohttp>=3.12.15",
28
28
  "scikit-image>=0.25.2",
@@ -46,10 +46,11 @@ dependencies = [
46
46
  "dashscope>=1.24.5",
47
47
  "yfinance>=0.2.66",
48
48
  "pyexecjs>=1.5.1",
49
+ "youtube-transcript-api>=1.2.2",
49
50
  ]
50
51
 
51
52
  [project.urls]
52
- Repository = "https://github.com/vvincent1234/VibeSurf"
53
+ Repository = "https://github.com/vibesurf-ai/VibeSurf"
53
54
 
54
55
  [project.scripts]
55
56
  vibesurf = "vibe_surf.cli:main"
@@ -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.30'
32
- __version_tuple__ = version_tuple = (0, 1, 30)
31
+ __version__ = version = '0.1.32'
32
+ __version_tuple__ = version_tuple = (0, 1, 32)
33
33
 
34
- __commit_id__ = commit_id = 'gc10cb51b5'
34
+ __commit_id__ = commit_id = 'g5ca20a39e'
@@ -479,7 +479,7 @@ async def _vibesurf_agent_node_impl(state: VibeSurfState) -> VibeSurfState:
479
479
  llm=vibesurf_agent.llm,
480
480
  file_system=vibesurf_agent.file_system,
481
481
  )
482
- if action_name.startswith("skill_"):
482
+ if action_name in ['skill_search', 'skill_crawl', 'skill_summary', 'skill_deep_research']:
483
483
  state.current_step = "END"
484
484
  # Format final response
485
485
  final_response = f"{result.extracted_content}" or f"{result.error}"
@@ -24,6 +24,7 @@ from browser_use.browser import BrowserProfile
24
24
  from vibe_surf.llm.openai_compatible import ChatOpenAICompatible
25
25
  from vibe_surf.browser.agent_browser_session import AgentBrowserSession
26
26
  from vibe_surf.browser.agen_browser_profile import AgentBrowserProfile
27
+ from vibe_surf.backend.utils.utils import configure_system_proxies
27
28
 
28
29
  logger = logging.getLogger(__name__)
29
30
 
@@ -330,7 +331,7 @@ async def initialize_vibesurf_components():
330
331
  # Load environment variables
331
332
  workspace_dir = common.get_workspace_dir()
332
333
  logger.info("WorkSpace directory: {}".format(workspace_dir))
333
-
334
+ configure_system_proxies()
334
335
  # Load environment configuration from envs.json
335
336
  envs_file_path = os.path.join(workspace_dir, "envs.json")
336
337
  try:
@@ -0,0 +1,42 @@
1
+ import pdb
2
+ import urllib.request
3
+ import os
4
+ from vibe_surf.logger import get_logger
5
+
6
+ logger = get_logger(__name__)
7
+
8
+ def configure_system_proxies():
9
+ """
10
+ Get system proxy settings using urllib.request.getproxies()
11
+ and set them as HTTP_PROXY and HTTPS_PROXY environment variables.
12
+ """
13
+
14
+ # 1. Get system proxy setting
15
+ try:
16
+ proxies = urllib.request.getproxies()
17
+ logger.info(proxies)
18
+ except Exception as e:
19
+ # Simple error handling
20
+ logger.error(e)
21
+ return
22
+
23
+ if not proxies:
24
+ logger.info("No system proxies detected.")
25
+ return
26
+
27
+ logger.debug(f"Detected system proxies: {proxies}")
28
+
29
+ # 2. Configure HTTP_PROXY
30
+ http_proxy = proxies.get('http')
31
+ if http_proxy:
32
+ os.environ['HTTP_PROXY'] = http_proxy
33
+ logger.info(f"Set HTTP_PROXY to: {http_proxy}")
34
+
35
+ # 3. Configure HTTPS_PROXY
36
+ https_proxy = proxies.get('https')
37
+ if https_proxy:
38
+ os.environ['HTTPS_PROXY'] = https_proxy
39
+ logger.info(f"Set HTTPS_PROXY to: {https_proxy}")
40
+
41
+ if http_proxy or https_proxy:
42
+ os.environ['no_proxy'] = 'localhost,127.0.0.1,::1'
@@ -15,9 +15,6 @@ from pathlib import Path
15
15
  from typing import Optional
16
16
  import os
17
17
 
18
- # In case user has a proxy in localhost
19
- os.environ['no_proxy'] = 'localhost,127.0.0.1,::1'
20
-
21
18
  try:
22
19
  from rich.console import Console
23
20
  from rich.panel import Panel
@@ -594,93 +594,93 @@ class BrowserUseTools(Tools, VibeSurfTools):
594
594
  logger.error(error_msg)
595
595
  return ActionResult(error=error_msg)
596
596
 
597
- async def _detect_file_format(self, url: str, headers: dict, content: bytes) -> str:
598
- """Detect file format from URL, headers, and content"""
599
-
600
- # Try Content-Type header first
601
- content_type = headers.get('content-type', '').lower()
602
- if content_type:
603
- # Common image formats
604
- if 'image/jpeg' in content_type or 'image/jpg' in content_type:
605
- return '.jpg'
606
- elif 'image/png' in content_type:
607
- return '.png'
608
- elif 'image/gif' in content_type:
609
- return '.gif'
610
- elif 'image/webp' in content_type:
611
- return '.webp'
612
- elif 'image/svg' in content_type:
613
- return '.svg'
614
- elif 'image/bmp' in content_type:
615
- return '.bmp'
616
- elif 'image/tiff' in content_type:
617
- return '.tiff'
618
- # Video formats
619
- elif 'video/mp4' in content_type:
620
- return '.mp4'
621
- elif 'video/webm' in content_type:
622
- return '.webm'
623
- elif 'video/avi' in content_type:
624
- return '.avi'
625
- elif 'video/mov' in content_type or 'video/quicktime' in content_type:
626
- return '.mov'
627
- # Audio formats
628
- elif 'audio/mpeg' in content_type or 'audio/mp3' in content_type:
629
- return '.mp3'
630
- elif 'audio/wav' in content_type:
631
- return '.wav'
632
- elif 'audio/ogg' in content_type:
633
- return '.ogg'
634
- elif 'audio/webm' in content_type:
635
- return '.webm'
636
-
637
- # Try magic number detection
638
- if len(content) >= 8:
639
- # JPEG
640
- if content.startswith(b'\xff\xd8\xff'):
641
- return '.jpg'
642
- # PNG
643
- elif content.startswith(b'\x89PNG\r\n\x1a\n'):
644
- return '.png'
645
- # GIF
646
- elif content.startswith(b'GIF87a') or content.startswith(b'GIF89a'):
647
- return '.gif'
648
- # WebP
649
- elif content[8:12] == b'WEBP':
650
- return '.webp'
651
- # BMP
652
- elif content.startswith(b'BM'):
653
- return '.bmp'
654
- # TIFF
655
- elif content.startswith(b'II*\x00') or content.startswith(b'MM\x00*'):
656
- return '.tiff'
657
- # MP4
658
- elif b'ftyp' in content[4:12]:
659
- return '.mp4'
660
- # PDF
661
- elif content.startswith(b'%PDF'):
662
- return '.pdf'
663
-
664
- # Try URL path extension
665
- url_path = urllib.parse.urlparse(url).path
666
- if url_path:
667
- ext = os.path.splitext(url_path)[1].lower()
668
- if ext in ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg', '.bmp', '.tiff',
669
- '.mp4', '.webm', '.avi', '.mov', '.wmv', '.flv',
670
- '.mp3', '.wav', '.ogg', '.aac', '.flac',
671
- '.pdf', '.doc', '.docx', '.txt']:
672
- return ext
673
-
674
- # Default fallback
675
- return '.bin'
676
-
677
- def _format_file_size(self, size_bytes: int) -> str:
678
- """Format file size in human readable format"""
679
- if size_bytes == 0:
680
- return "0 B"
681
- size_names = ["B", "KB", "MB", "GB", "TB"]
682
- i = 0
683
- while size_bytes >= 1024.0 and i < len(size_names) - 1:
684
- size_bytes /= 1024.0
685
- i += 1
686
- return f"{size_bytes:.1f} {size_names[i]}"
597
+ async def _detect_file_format(self, url: str, headers: dict, content: bytes) -> str:
598
+ """Detect file format from URL, headers, and content"""
599
+
600
+ # Try Content-Type header first
601
+ content_type = headers.get('content-type', '').lower()
602
+ if content_type:
603
+ # Common image formats
604
+ if 'image/jpeg' in content_type or 'image/jpg' in content_type:
605
+ return '.jpg'
606
+ elif 'image/png' in content_type:
607
+ return '.png'
608
+ elif 'image/gif' in content_type:
609
+ return '.gif'
610
+ elif 'image/webp' in content_type:
611
+ return '.webp'
612
+ elif 'image/svg' in content_type:
613
+ return '.svg'
614
+ elif 'image/bmp' in content_type:
615
+ return '.bmp'
616
+ elif 'image/tiff' in content_type:
617
+ return '.tiff'
618
+ # Video formats
619
+ elif 'video/mp4' in content_type:
620
+ return '.mp4'
621
+ elif 'video/webm' in content_type:
622
+ return '.webm'
623
+ elif 'video/avi' in content_type:
624
+ return '.avi'
625
+ elif 'video/mov' in content_type or 'video/quicktime' in content_type:
626
+ return '.mov'
627
+ # Audio formats
628
+ elif 'audio/mpeg' in content_type or 'audio/mp3' in content_type:
629
+ return '.mp3'
630
+ elif 'audio/wav' in content_type:
631
+ return '.wav'
632
+ elif 'audio/ogg' in content_type:
633
+ return '.ogg'
634
+ elif 'audio/webm' in content_type:
635
+ return '.webm'
636
+
637
+ # Try magic number detection
638
+ if len(content) >= 8:
639
+ # JPEG
640
+ if content.startswith(b'\xff\xd8\xff'):
641
+ return '.jpg'
642
+ # PNG
643
+ elif content.startswith(b'\x89PNG\r\n\x1a\n'):
644
+ return '.png'
645
+ # GIF
646
+ elif content.startswith(b'GIF87a') or content.startswith(b'GIF89a'):
647
+ return '.gif'
648
+ # WebP
649
+ elif content[8:12] == b'WEBP':
650
+ return '.webp'
651
+ # BMP
652
+ elif content.startswith(b'BM'):
653
+ return '.bmp'
654
+ # TIFF
655
+ elif content.startswith(b'II*\x00') or content.startswith(b'MM\x00*'):
656
+ return '.tiff'
657
+ # MP4
658
+ elif b'ftyp' in content[4:12]:
659
+ return '.mp4'
660
+ # PDF
661
+ elif content.startswith(b'%PDF'):
662
+ return '.pdf'
663
+
664
+ # Try URL path extension
665
+ url_path = urllib.parse.urlparse(url).path
666
+ if url_path:
667
+ ext = os.path.splitext(url_path)[1].lower()
668
+ if ext in ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg', '.bmp', '.tiff',
669
+ '.mp4', '.webm', '.avi', '.mov', '.wmv', '.flv',
670
+ '.mp3', '.wav', '.ogg', '.aac', '.flac',
671
+ '.pdf', '.doc', '.docx', '.txt']:
672
+ return ext
673
+
674
+ # Default fallback
675
+ return '.bin'
676
+
677
+ def _format_file_size(self, size_bytes: int) -> str:
678
+ """Format file size in human readable format"""
679
+ if size_bytes == 0:
680
+ return "0 B"
681
+ size_names = ["B", "KB", "MB", "GB", "TB"]
682
+ i = 0
683
+ while size_bytes >= 1024.0 and i < len(size_names) - 1:
684
+ size_bytes /= 1024.0
685
+ i += 1
686
+ return f"{size_bytes:.1f} {size_names[i]}"
@@ -1263,7 +1263,18 @@ Please generate alternative JavaScript code that avoids this system error:"""
1263
1263
 
1264
1264
 
1265
1265
  @self.registry.action(
1266
- 'Skill: YouTube API - Access YouTube platform data including search, video details, comments, channel info, and trending videos. Methods: search_videos, get_video_details, get_video_comments, get_channel_info, get_channel_videos, get_trending_videos.',
1266
+ """Skill: YouTube API - Access YouTube platform data including search, video details, comments, channel info, trending videos, and video transcripts.
1267
+ Methods:
1268
+ search_videos,
1269
+ get_video_details,
1270
+ get_video_comments,
1271
+ get_channel_info,
1272
+ get_channel_videos,
1273
+ get_trending_videos,
1274
+ get_video_transcript.
1275
+
1276
+ If users want to know the specific content of this video, please use get_video_transcript to get detailed video content first.
1277
+ """,
1267
1278
  param_model=SkillYoutubeAction,
1268
1279
  )
1269
1280
  async def skill_youtube(
@@ -1281,6 +1292,7 @@ Please generate alternative JavaScript code that avoids this system error:"""
1281
1292
  - get_channel_info: Get channel information
1282
1293
  - get_channel_videos: Get videos from specific channel
1283
1294
  - get_trending_videos: Get trending videos
1295
+ - get_video_transcript: Get video transcript in multiple languages
1284
1296
  """
1285
1297
  try:
1286
1298
  from vibe_surf.tools.website_api.youtube.client import YouTubeApiClient
@@ -1311,6 +1323,8 @@ Please generate alternative JavaScript code that avoids this system error:"""
1311
1323
  result = await yt_client.get_channel_videos(**method_params)
1312
1324
  elif params.method == "get_trending_videos":
1313
1325
  result = await yt_client.get_trending_videos()
1326
+ elif params.method == "get_video_transcript":
1327
+ result = await yt_client.get_video_transcript(**method_params)
1314
1328
  else:
1315
1329
  return ActionResult(error=f"Unknown method: {params.method}")
1316
1330
 
@@ -281,7 +281,8 @@ class SkillYoutubeAction(BaseModel):
281
281
  - get_video_comments: Get video comments, params required: {"video_id": "video ID", "max_comments": 200}
282
282
  - get_channel_info: Get channel information, params required: {"channel_id": "channel ID"}
283
283
  - get_channel_videos: Get channel videos, params required: {"channel_id": "channel ID", "max_videos": 20}
284
- - get_trending_videos: Get trending videos, params: {}'''
284
+ - get_trending_videos: Get trending videos, params: {}
285
+ - get_video_transcript: Get video transcript, params required: {"video_id": "video ID", "languages": ["en", "zh-CN"] (optional, defaults to ["en"])}'''
285
286
  )
286
287
  params: str = Field(
287
288
  description='JSON string of method parameters, provide corresponding parameters according to the method parameter. Example: {"query": "tech tutorial", "max_results": 30}'
@@ -10,6 +10,7 @@ from typing import Dict, List, Optional, Callable, Union, Any
10
10
  import httpx
11
11
  from tenacity import retry, stop_after_attempt, wait_fixed
12
12
  from urllib.parse import parse_qs, unquote, urlencode
13
+ from youtube_transcript_api import YouTubeTranscriptApi
13
14
 
14
15
  from vibe_surf.browser.agent_browser_session import AgentBrowserSession
15
16
  from vibe_surf.logger import get_logger
@@ -1170,6 +1171,62 @@ class YouTubeApiClient:
1170
1171
  logger.error(f"Failed to get trending videos: {e}")
1171
1172
  return []
1172
1173
 
1174
+ async def get_video_transcript(self, video_id: str, languages: Optional[List[str]] = None) -> Optional[Dict[str, List[Dict]]]:
1175
+ """
1176
+ Get transcript for a YouTube video
1177
+
1178
+ Args:
1179
+ video_id: YouTube video ID (not the full URL)
1180
+ languages: List of language codes to try (default: ['en'])
1181
+
1182
+ Returns:
1183
+ Dictionary with language codes as keys and transcript raw data as values
1184
+ Returns None if no transcripts are available
1185
+ """
1186
+ try:
1187
+ if languages is None:
1188
+ languages = ['en']
1189
+
1190
+ # Create YouTubeTranscriptApi instance
1191
+ ytt_api = YouTubeTranscriptApi()
1192
+
1193
+ # List available transcripts to check what's available
1194
+ transcript_list = ytt_api.list(video_id)
1195
+ available_languages = [transcript.language_code for transcript in transcript_list]
1196
+
1197
+ logger.info(f"Available transcript languages for video {video_id}: {available_languages}")
1198
+
1199
+ # Filter requested languages to only include available ones
1200
+ valid_languages = [lang for lang in languages if lang in available_languages]
1201
+
1202
+ if not valid_languages:
1203
+ logger.warning(f"None of the requested languages {languages} are available for video {video_id}")
1204
+ return None
1205
+
1206
+ # Fetch transcripts for each valid language
1207
+ result = {}
1208
+ for language in valid_languages:
1209
+ try:
1210
+ # Find transcript for this specific language
1211
+ transcript = transcript_list.find_transcript([language])
1212
+ fetched_transcript = transcript.fetch()
1213
+
1214
+ # Convert to raw data format
1215
+ raw_data = fetched_transcript.to_raw_data()
1216
+ result[language] = raw_data
1217
+
1218
+ logger.info(f"Successfully fetched transcript for video {video_id} in language {language}")
1219
+
1220
+ except Exception as lang_error:
1221
+ logger.warning(f"Failed to fetch transcript for language {language}: {lang_error}")
1222
+ continue
1223
+
1224
+ return result if result else None
1225
+
1226
+ except Exception as e:
1227
+ logger.error(f"Failed to get transcript for video {video_id}: {e}")
1228
+ return None
1229
+
1173
1230
  async def close(self):
1174
1231
  if self.browser_session and self.target_id:
1175
1232
  try:
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vibesurf
3
- Version: 0.1.30
3
+ Version: 0.1.32
4
4
  Summary: VibeSurf: A powerful browser assistant for vibe surfing
5
- Author: Shao Warm
5
+ Author: WarmShao
6
6
  License: Apache-2.0
7
- Project-URL: Repository, https://github.com/vvincent1234/VibeSurf
7
+ Project-URL: Repository, https://github.com/vibesurf-ai/VibeSurf
8
8
  Keywords: browser use,browser automation,browser assistant,agentic browser,vibe surf,AI browser
9
9
  Classifier: Development Status :: 3 - Alpha
10
10
  Classifier: Intended Audience :: Developers
@@ -21,7 +21,7 @@ Requires-Dist: aiofiles>=24.1.0
21
21
  Requires-Dist: anyio>=4.9.0
22
22
  Requires-Dist: psutil>=7.0.0
23
23
  Requires-Dist: pydantic>=2.11.5
24
- Requires-Dist: cdp-use>=1.4.0
24
+ Requires-Dist: cdp-use>=1.4.1
25
25
  Requires-Dist: json-repair>=0.48.0
26
26
  Requires-Dist: aiohttp>=3.12.15
27
27
  Requires-Dist: scikit-image>=0.25.2
@@ -45,6 +45,7 @@ Requires-Dist: pathvalidate>=3.3.1
45
45
  Requires-Dist: dashscope>=1.24.5
46
46
  Requires-Dist: yfinance>=0.2.66
47
47
  Requires-Dist: pyexecjs>=1.5.1
48
+ Requires-Dist: youtube-transcript-api>=1.2.2
48
49
  Dynamic: license-file
49
50
 
50
51
  # VibeSurf: A powerful browser assistant for vibe surfing
@@ -46,6 +46,7 @@ vibesurf.spec
46
46
  ./vibe_surf/backend/utils/__init__.py
47
47
  ./vibe_surf/backend/utils/encryption.py
48
48
  ./vibe_surf/backend/utils/llm_factory.py
49
+ ./vibe_surf/backend/utils/utils.py
49
50
  ./vibe_surf/browser/__init__.py
50
51
  ./vibe_surf/browser/agen_browser_profile.py
51
52
  ./vibe_surf/browser/agent_browser_session.py
@@ -166,6 +167,7 @@ vibe_surf/backend/database/migrations/v004_add_voice_profiles.sql
166
167
  vibe_surf/backend/utils/__init__.py
167
168
  vibe_surf/backend/utils/encryption.py
168
169
  vibe_surf/backend/utils/llm_factory.py
170
+ vibe_surf/backend/utils/utils.py
169
171
  vibe_surf/browser/__init__.py
170
172
  vibe_surf/browser/agen_browser_profile.py
171
173
  vibe_surf/browser/agent_browser_session.py
@@ -3,7 +3,7 @@ aiofiles>=24.1.0
3
3
  anyio>=4.9.0
4
4
  psutil>=7.0.0
5
5
  pydantic>=2.11.5
6
- cdp-use>=1.4.0
6
+ cdp-use>=1.4.1
7
7
  json-repair>=0.48.0
8
8
  aiohttp>=3.12.15
9
9
  scikit-image>=0.25.2
@@ -27,3 +27,4 @@ pathvalidate>=3.3.1
27
27
  dashscope>=1.24.5
28
28
  yfinance>=0.2.66
29
29
  pyexecjs>=1.5.1
30
+ youtube-transcript-api>=1.2.2
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