vibesurf 0.1.22__tar.gz → 0.1.24__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.
- {vibesurf-0.1.22 → vibesurf-0.1.24}/PKG-INFO +2 -1
- {vibesurf-0.1.22 → vibesurf-0.1.24}/pyproject.toml +1 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/tests/test_agents.py +51 -44
- {vibesurf-0.1.22 → vibesurf-0.1.24}/tests/test_browser.py +25 -2
- {vibesurf-0.1.22 → vibesurf-0.1.24}/tests/test_tools.py +12 -1
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/_version.py +3 -3
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/agents/prompts/vibe_surf_prompt.py +10 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/agents/vibe_surf_agent.py +13 -2
- vibesurf-0.1.24/vibe_surf/backend/api/agent.py +38 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/api/config.py +3 -1
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/api/task.py +1 -1
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/main.py +2 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/utils/llm_factory.py +2 -1
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/browser/agent_browser_session.py +5 -5
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/scripts/api-client.js +5 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/scripts/main.js +1 -1
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/scripts/ui-manager.js +397 -20
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/sidepanel.html +13 -1
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/styles/input.css +115 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/llm/openai_compatible.py +35 -10
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/tools/browser_use_tools.py +0 -90
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/tools/file_system.py +2 -2
- vibesurf-0.1.24/vibe_surf/tools/finance_tools.py +586 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/tools/report_writer_tools.py +2 -1
- vibesurf-0.1.24/vibe_surf/tools/vibesurf_registry.py +52 -0
- vibesurf-0.1.24/vibe_surf/tools/vibesurf_tools.py +1697 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/tools/views.py +93 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibesurf.egg-info/PKG-INFO +2 -1
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibesurf.egg-info/SOURCES.txt +6 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibesurf.egg-info/requires.txt +1 -0
- vibesurf-0.1.22/vibe_surf/tools/vibesurf_tools.py +0 -659
- {vibesurf-0.1.22 → vibesurf-0.1.24}/.env.example +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/.github/workflows/publish.yml +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/.gitignore +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/.python-version +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/LICENSE +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/MANIFEST.in +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/README.md +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/docs/EXECUTABLE_BUILD.md +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/docs/PYPI_SETUP.md +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/scripts/build-local.bat +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/scripts/build-local.sh +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/setup.cfg +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/tests/test_backend_api.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/tests/test_voice_api.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/__init__.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/agents/__init__.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/agents/browser_use_agent.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/agents/prompts/__init__.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/agents/prompts/report_writer_prompt.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/agents/report_writer_agent.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/agents/views.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/__init__.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/api/__init__.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/api/activity.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/api/browser.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/api/files.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/api/models.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/api/voices.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/database/__init__.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/database/manager.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/database/migrations/v001_initial_schema.sql +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/database/migrations/v002_add_agent_mode.sql +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/database/migrations/v003_fix_task_status_case.sql +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/database/migrations/v004_add_voice_profiles.sql +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/database/models.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/database/queries.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/database/schemas.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/llm_config.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/shared_state.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/utils/__init__.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/utils/encryption.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/backend/voice_model_config.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/browser/__init__.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/browser/agen_browser_profile.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/browser/browser_manager.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/browser/utils.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/browser/watchdogs/__init__.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/browser/watchdogs/action_watchdog.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/browser/watchdogs/dom_watchdog.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/background.js +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/config.js +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/content.js +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/dev-reload.js +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/icons/logo.icns +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/icons/logo.png +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/manifest.json +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/permission-iframe.html +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/permission-request.html +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/popup.html +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/scripts/file-manager.js +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/scripts/history-manager.js +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/scripts/markdown-it.min.js +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/scripts/modal-manager.js +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/scripts/permission-iframe-request.js +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/scripts/permission-request.js +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/scripts/session-manager.js +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/scripts/settings-manager.js +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/scripts/user-settings-storage.js +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/scripts/voice-recorder.js +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/styles/activity.css +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/styles/animations.css +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/styles/base.css +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/styles/components.css +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/styles/history-modal.css +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/styles/layout.css +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/styles/responsive.css +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/styles/settings-environment.css +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/styles/settings-forms.css +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/styles/settings-modal.css +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/styles/settings-profiles.css +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/styles/settings-responsive.css +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/styles/settings-utilities.css +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/chrome_extension/styles/variables.css +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/cli.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/common.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/llm/__init__.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/logger.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/tools/__init__.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/tools/mcp_client.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibe_surf/tools/voice_asr.py +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibesurf.egg-info/dependency_links.txt +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibesurf.egg-info/entry_points.txt +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibesurf.egg-info/top_level.txt +0 -0
- {vibesurf-0.1.22 → vibesurf-0.1.24}/vibesurf.spec +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vibesurf
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.24
|
|
4
4
|
Summary: VibeSurf: A powerful browser assistant for vibe surfing
|
|
5
5
|
Author: Shao Warm
|
|
6
6
|
License: Apache-2.0
|
|
@@ -43,6 +43,7 @@ Requires-Dist: nanoid>=2.0.0
|
|
|
43
43
|
Requires-Dist: markdownify>=1.2.0
|
|
44
44
|
Requires-Dist: pathvalidate>=3.3.1
|
|
45
45
|
Requires-Dist: dashscope>=1.24.5
|
|
46
|
+
Requires-Dist: yfinance>=0.2.66
|
|
46
47
|
Dynamic: license-file
|
|
47
48
|
|
|
48
49
|
# VibeSurf: A powerful browser assistant for vibe surfing
|
|
@@ -18,9 +18,11 @@ from vibe_surf.browser.agen_browser_profile import AgentBrowserProfile
|
|
|
18
18
|
from vibe_surf.tools.browser_use_tools import BrowserUseTools
|
|
19
19
|
from vibe_surf.tools.vibesurf_tools import VibeSurfTools
|
|
20
20
|
from vibe_surf.llm.openai_compatible import ChatOpenAICompatible
|
|
21
|
+
from browser_use.llm.deepseek.chat import ChatDeepSeek
|
|
21
22
|
from vibe_surf.agents.browser_use_agent import BrowserUseAgent
|
|
22
23
|
from vibe_surf.agents.vibe_surf_agent import VibeSurfAgent
|
|
23
24
|
|
|
25
|
+
|
|
24
26
|
async def run_single_bu_agent():
|
|
25
27
|
import platform
|
|
26
28
|
if platform.system() != "Darwin":
|
|
@@ -46,9 +48,13 @@ async def run_single_bu_agent():
|
|
|
46
48
|
# base_url=os.getenv("ALIBABA_ENDPOINT"),
|
|
47
49
|
# api_key=os.getenv("ALIBABA_API_KEY"))
|
|
48
50
|
|
|
49
|
-
llm = ChatOpenAICompatible(model='kimi-k2-turbo-preview',
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
# llm = ChatOpenAICompatible(model='kimi-k2-turbo-preview',
|
|
52
|
+
# base_url=os.getenv("MOONSHOT_ENDPOINT"),
|
|
53
|
+
# api_key=os.getenv("MOONSHOT_API_KEY"))
|
|
54
|
+
|
|
55
|
+
llm = ChatOpenAICompatible(model='deepseek-reasoner',
|
|
56
|
+
base_url=os.getenv("DEEPSEEK_ENDPOINT"),
|
|
57
|
+
api_key=os.getenv("DEEPSEEK_API_KEY"))
|
|
52
58
|
|
|
53
59
|
task = "Search Google for 'Elon Mask' and tell me the top 3 results"
|
|
54
60
|
|
|
@@ -159,20 +165,22 @@ async def test_vibe_surf_agent():
|
|
|
159
165
|
await main_browser_session.start()
|
|
160
166
|
vs_tools = VibeSurfTools()
|
|
161
167
|
browser_manager = BrowserManager(main_browser_session=main_browser_session)
|
|
162
|
-
llm = ChatOpenAICompatible(model='gemini-2.5-flash',
|
|
163
|
-
|
|
164
|
-
|
|
168
|
+
# llm = ChatOpenAICompatible(model='gemini-2.5-flash',
|
|
169
|
+
# base_url=os.getenv("OPENAI_ENDPOINT"),
|
|
170
|
+
# api_key=os.getenv("OPENAI_API_KEY"))
|
|
171
|
+
|
|
172
|
+
llm = ChatOpenAICompatible(model='deepseek-chat',
|
|
173
|
+
base_url=os.getenv("DEEPSEEK_ENDPOINT"),
|
|
174
|
+
api_key=os.getenv("DEEPSEEK_API_KEY"))
|
|
165
175
|
|
|
166
|
-
|
|
167
176
|
# Create VibeSurfAgent
|
|
168
177
|
agent = VibeSurfAgent(
|
|
169
178
|
llm=llm,
|
|
170
179
|
browser_manager=browser_manager,
|
|
171
180
|
tools=vs_tools,
|
|
172
|
-
workspace_dir=os.path.abspath("./tmp/vibesurf_tests")
|
|
173
|
-
calculate_token_cost=True
|
|
181
|
+
workspace_dir=os.path.abspath("./tmp/vibesurf_tests")
|
|
174
182
|
)
|
|
175
|
-
|
|
183
|
+
|
|
176
184
|
try:
|
|
177
185
|
# Test 1: Simple task (should not require browser)
|
|
178
186
|
print("🧪 Testing simple task...")
|
|
@@ -200,16 +208,16 @@ async def test_vibe_surf_agent():
|
|
|
200
208
|
# print("🎉 All VibeSurfAgent tests passed!")
|
|
201
209
|
|
|
202
210
|
# Test 4: Browser parallel task
|
|
203
|
-
print("🧪 Testing browser parallel tasks...")
|
|
204
|
-
browser_task = "Search for Dify, n8n, browser-use and click into their own homepage, take screenshot and save"
|
|
205
|
-
result4 = await agent.run(browser_task)
|
|
206
|
-
print(f"✅ Browser task result:")
|
|
207
|
-
pprint.pprint(result4)
|
|
208
|
-
with open("./tmp/vibesurf_tests/parallel_test.md", "w", encoding='utf-8') as fw:
|
|
209
|
-
|
|
210
|
-
assert result4 is not None and len(result4) > 0
|
|
211
|
+
# print("🧪 Testing browser parallel tasks...")
|
|
212
|
+
# browser_task = "Search for Dify, n8n, browser-use and click into their own homepage, take screenshot and save"
|
|
213
|
+
# result4 = await agent.run(browser_task)
|
|
214
|
+
# print(f"✅ Browser task result:")
|
|
215
|
+
# pprint.pprint(result4)
|
|
216
|
+
# with open("./tmp/vibesurf_tests/parallel_test.md", "w", encoding='utf-8') as fw:
|
|
217
|
+
# fw.write(result4)
|
|
218
|
+
# assert result4 is not None and len(result4) > 0
|
|
211
219
|
print("🎉 All VibeSurfAgent tests passed!")
|
|
212
|
-
|
|
220
|
+
|
|
213
221
|
except Exception as e:
|
|
214
222
|
print(f"❌ VibeSurfAgent test failed: {e}")
|
|
215
223
|
raise e
|
|
@@ -240,7 +248,6 @@ async def test_vibe_surf_agent_control():
|
|
|
240
248
|
llm = ChatOpenAICompatible(model='gemini-2.5-pro',
|
|
241
249
|
base_url=os.getenv("OPENAI_ENDPOINT"),
|
|
242
250
|
api_key=os.getenv("OPENAI_API_KEY"))
|
|
243
|
-
|
|
244
251
|
|
|
245
252
|
# Create VibeSurfAgent
|
|
246
253
|
agent = VibeSurfAgent(
|
|
@@ -253,69 +260,69 @@ async def test_vibe_surf_agent_control():
|
|
|
253
260
|
|
|
254
261
|
try:
|
|
255
262
|
print("🧪 Testing VibeSurfAgent control functionality...")
|
|
256
|
-
|
|
263
|
+
|
|
257
264
|
# Test 1: Status check when idle
|
|
258
265
|
print("📊 Testing initial status...")
|
|
259
266
|
status = agent.get_status()
|
|
260
267
|
print(f"Initial status: {status.overall_status}")
|
|
261
268
|
assert status.overall_status == "idle"
|
|
262
|
-
|
|
269
|
+
|
|
263
270
|
# Test 2: Start a long-running browser task
|
|
264
271
|
print("🚀 Starting long-running browser task...")
|
|
265
272
|
browser_task = "Search for Dify, n8n, langflow and gather relative information, and generate a detailed report for comparison"
|
|
266
|
-
|
|
273
|
+
|
|
267
274
|
# Start task in background
|
|
268
275
|
async def run_task():
|
|
269
276
|
return await agent.run(browser_task)
|
|
270
|
-
|
|
277
|
+
|
|
271
278
|
task_coroutine = asyncio.create_task(run_task())
|
|
272
|
-
|
|
279
|
+
|
|
273
280
|
# Wait a bit for task to start
|
|
274
281
|
await asyncio.sleep(10)
|
|
275
|
-
|
|
282
|
+
|
|
276
283
|
# Test 3: Check status during execution
|
|
277
284
|
print("📊 Checking status during execution...")
|
|
278
285
|
status = agent.get_status()
|
|
279
286
|
print(f"Running status: {status.overall_status}")
|
|
280
287
|
print(f"Progress: {status.progress}")
|
|
281
288
|
print(f"Active agents: {len(status.agent_statuses)}")
|
|
282
|
-
|
|
289
|
+
|
|
283
290
|
# Test 4: Pause execution
|
|
284
291
|
print("⏸️ Testing pause functionality...")
|
|
285
292
|
pause_result = await agent.pause("Testing pause functionality")
|
|
286
293
|
print(f"Pause result: {pause_result.success} - {pause_result.message}")
|
|
287
294
|
assert pause_result.success
|
|
288
|
-
|
|
295
|
+
|
|
289
296
|
# Check status after pause
|
|
290
297
|
await asyncio.sleep(1)
|
|
291
298
|
status = agent.get_status()
|
|
292
299
|
print(f"Paused status: {status.overall_status}")
|
|
293
300
|
assert status.overall_status == "paused"
|
|
294
|
-
|
|
301
|
+
|
|
295
302
|
# Test 5: Resume execution
|
|
296
303
|
print("▶️ Testing resume functionality...")
|
|
297
304
|
resume_result = await agent.resume("Testing resume functionality")
|
|
298
305
|
print(f"Resume result: {resume_result.success} - {resume_result.message}")
|
|
299
306
|
assert resume_result.success
|
|
300
|
-
|
|
307
|
+
|
|
301
308
|
# Check status after resume
|
|
302
309
|
await asyncio.sleep(1)
|
|
303
310
|
status = agent.get_status()
|
|
304
311
|
print(f"Resumed status: {status.overall_status}")
|
|
305
|
-
|
|
312
|
+
|
|
306
313
|
# Let it run a bit more
|
|
307
314
|
await asyncio.sleep(50)
|
|
308
|
-
|
|
315
|
+
|
|
309
316
|
# Test 6: Stop execution
|
|
310
317
|
print("🛑 Testing stop functionality...")
|
|
311
318
|
stop_result = await agent.stop("Testing stop functionality")
|
|
312
319
|
print(f"Stop result: {stop_result.success} - {stop_result.message}")
|
|
313
|
-
|
|
320
|
+
|
|
314
321
|
# Check status after stop (should be stopped even if stop had issues)
|
|
315
322
|
await asyncio.sleep(1)
|
|
316
323
|
status = agent.get_status()
|
|
317
324
|
print(f"Stopped status: {status.overall_status}")
|
|
318
|
-
|
|
325
|
+
|
|
319
326
|
# Wait for task to complete (it should be cancelled)
|
|
320
327
|
try:
|
|
321
328
|
result = await asyncio.wait_for(task_coroutine, timeout=3)
|
|
@@ -329,38 +336,38 @@ async def test_vibe_surf_agent_control():
|
|
|
329
336
|
pass
|
|
330
337
|
except asyncio.CancelledError:
|
|
331
338
|
print("✅ Task was cancelled as expected")
|
|
332
|
-
|
|
339
|
+
|
|
333
340
|
# Verify stop worked (may have timed out but should still be effective)
|
|
334
341
|
if stop_result.success:
|
|
335
342
|
assert status.overall_status == "idle"
|
|
336
343
|
else:
|
|
337
344
|
print(f"⚠️ Stop operation had issues but continuing: {stop_result.message}")
|
|
338
|
-
|
|
345
|
+
|
|
339
346
|
# Test 7: Test simple task control (should work quickly)
|
|
340
347
|
print("🔄 Testing control on simple task...")
|
|
341
348
|
simple_task = "Find out who is the founder of Browser-Use."
|
|
342
|
-
|
|
349
|
+
|
|
343
350
|
async def run_simple_task():
|
|
344
351
|
return await agent.run(simple_task)
|
|
345
|
-
|
|
352
|
+
|
|
346
353
|
simple_task_coroutine = asyncio.create_task(run_simple_task())
|
|
347
|
-
|
|
354
|
+
|
|
348
355
|
# Pause quickly
|
|
349
356
|
await asyncio.sleep(0.5)
|
|
350
357
|
pause_result = await agent.pause("Testing simple task pause")
|
|
351
358
|
print(f"Simple task pause: {pause_result.success}")
|
|
352
|
-
|
|
359
|
+
|
|
353
360
|
# Resume
|
|
354
361
|
await asyncio.sleep(0.5)
|
|
355
362
|
resume_result = await agent.resume("Testing simple task resume")
|
|
356
363
|
print(f"Simple task resume: {resume_result.success}")
|
|
357
|
-
|
|
364
|
+
|
|
358
365
|
# Let it complete
|
|
359
366
|
simple_result = await simple_task_coroutine
|
|
360
367
|
print(f"Simple task completed: {len(simple_result) > 0}")
|
|
361
368
|
print(simple_result)
|
|
362
369
|
print("🎉 All VibeSurfAgent control tests passed!")
|
|
363
|
-
|
|
370
|
+
|
|
364
371
|
except Exception as e:
|
|
365
372
|
print(f"❌ VibeSurfAgent control test failed: {e}")
|
|
366
373
|
import traceback
|
|
@@ -377,7 +384,7 @@ async def test_vibe_surf_agent_control():
|
|
|
377
384
|
|
|
378
385
|
|
|
379
386
|
if __name__ == "__main__":
|
|
380
|
-
asyncio.run(run_single_bu_agent())
|
|
387
|
+
# asyncio.run(run_single_bu_agent())
|
|
381
388
|
# asyncio.run(run_multi_bu_agents())
|
|
382
|
-
|
|
389
|
+
asyncio.run(test_vibe_surf_agent())
|
|
383
390
|
# asyncio.run(test_vibe_surf_agent_control())
|
|
@@ -117,7 +117,6 @@ async def test_browser_state_capture(manager: BrowserManager):
|
|
|
117
117
|
# f"🔍 DIAGNOSIS: {agent_name} navigation completed at {task_end - start_time:.3f}s (duration: {task_end - task_start:.3f}s)")
|
|
118
118
|
# return None
|
|
119
119
|
|
|
120
|
-
|
|
121
120
|
# Navigate to different pages
|
|
122
121
|
await asyncio.gather(
|
|
123
122
|
navigate_with_timing(agent1, "https://www.python.org", "agent1"),
|
|
@@ -240,6 +239,29 @@ async def test_browser_state_capture(manager: BrowserManager):
|
|
|
240
239
|
print(main_tabs)
|
|
241
240
|
|
|
242
241
|
|
|
242
|
+
async def get_all_css_selector(browser_session: AgentBrowserSession):
|
|
243
|
+
target_id = await browser_session.navigate_to_url("https://github.com/", new_tab=True)
|
|
244
|
+
result = await browser_session.cdp_client.send.Target.attachToTarget({'targetId': target_id, 'flatten': True})
|
|
245
|
+
session_id = result['sessionId']
|
|
246
|
+
doc_result = await browser_session.cdp_client.send.DOM.getDocument(session_id=session_id)
|
|
247
|
+
document_node_id = doc_result['root']['nodeId']
|
|
248
|
+
from browser_use.dom.service import DomService
|
|
249
|
+
dom_service = DomService(browser_session)
|
|
250
|
+
pdb.set_trace()
|
|
251
|
+
# Query selector all
|
|
252
|
+
query_params = {'nodeId': document_node_id}
|
|
253
|
+
result = await browser_session.cdp_client.send.DOM.querySelectorAll(query_params, session_id=session_id)
|
|
254
|
+
|
|
255
|
+
elements = []
|
|
256
|
+
|
|
257
|
+
# Convert node IDs to backend node IDs
|
|
258
|
+
for node_id in result['nodeIds']:
|
|
259
|
+
# Get backend node ID
|
|
260
|
+
describe_params = {'nodeId': node_id}
|
|
261
|
+
node_result = await browser_session.cdp_client.send.DOM.describeNode(describe_params, session_id=session_id)
|
|
262
|
+
pdb.set_trace()
|
|
263
|
+
|
|
264
|
+
|
|
243
265
|
async def main():
|
|
244
266
|
"""
|
|
245
267
|
Main function to run all browser session tests.
|
|
@@ -273,7 +295,8 @@ async def main():
|
|
|
273
295
|
# await test_manual_page_assignment(manager)
|
|
274
296
|
# await test_agent_cleanup(manager)
|
|
275
297
|
# await test_agent_tab_isolation(manager)
|
|
276
|
-
await test_browser_state_capture(manager)
|
|
298
|
+
# await test_browser_state_capture(manager)
|
|
299
|
+
await get_all_css_selector(main_browser_session)
|
|
277
300
|
|
|
278
301
|
except Exception as e:
|
|
279
302
|
logging.error(f"An error occurred during tests: {e}", exc_info=True)
|
|
@@ -116,8 +116,19 @@ async def test_vibesurf_tools():
|
|
|
116
116
|
print(tools.registry.registry.actions.keys())
|
|
117
117
|
|
|
118
118
|
|
|
119
|
+
async def test_finance_tools():
|
|
120
|
+
from vibe_surf.tools.finance_tools import FinanceDataRetriever
|
|
121
|
+
|
|
122
|
+
retriever = FinanceDataRetriever('TSLA')
|
|
123
|
+
|
|
124
|
+
result = retriever.get_finance_data(["get_news"])
|
|
125
|
+
|
|
126
|
+
pdb.set_trace()
|
|
127
|
+
|
|
128
|
+
|
|
119
129
|
if __name__ == '__main__':
|
|
120
130
|
# asyncio.run(test_tools_with_mcp())
|
|
121
131
|
# asyncio.run(test_filesystem())
|
|
122
132
|
# asyncio.run(test_bu_tools())
|
|
123
|
-
asyncio.run(test_vibesurf_tools())
|
|
133
|
+
# asyncio.run(test_vibesurf_tools())
|
|
134
|
+
asyncio.run(test_finance_tools())
|
|
@@ -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.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 1,
|
|
31
|
+
__version__ = version = '0.1.24'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 1, 24)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'gebf62a182'
|
|
@@ -65,6 +65,15 @@ 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
|
+
## Skills Command Processing
|
|
69
|
+
- When users input commands in `/skill_name` format, please use the corresponding skill action:
|
|
70
|
+
- **Tab Targeting[Optional]**: Such as `/crawl @1234` → Execute `skill_crawl` with tab_id "1234"
|
|
71
|
+
- **Parameter Processing**: Sometimes user provide uncompleted or simple prompt, please convert it to correct and optimized params. Such as convert natural language to valid JavaScript for code skill
|
|
72
|
+
- **Special Cases**: `skill_deep_research` only returns guidelines only, then follow guidelines to conduct actual research
|
|
73
|
+
- **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.
|
|
74
|
+
- **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.
|
|
75
|
+
- 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.
|
|
76
|
+
|
|
68
77
|
## Language Adaptability
|
|
69
78
|
|
|
70
79
|
**Critical**: Your output language must match the user's request language. If the user communicates in Chinese, respond in Chinese. If in English, respond in English. Maintain consistency throughout the interaction.
|
|
@@ -77,6 +86,7 @@ Before executing any action:
|
|
|
77
86
|
3. **Plan Resource Usage**: Consider tab management and session optimization
|
|
78
87
|
4. **Validate Completeness**: Ensure all user requirements are addressed
|
|
79
88
|
|
|
89
|
+
|
|
80
90
|
Execute with precision, leverage concurrent capabilities for efficiency, and deliver professional results that exceed expectations.
|
|
81
91
|
"""
|
|
82
92
|
|
|
@@ -479,6 +479,16 @@ 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 in ["skill_search", "skill_crawl", "skill_summary", "skill_finance"]:
|
|
483
|
+
state.current_step = "END"
|
|
484
|
+
# Format final response
|
|
485
|
+
final_response = f"{result.extracted_content}"
|
|
486
|
+
await log_agent_activity(state, agent_name, "result", final_response)
|
|
487
|
+
state.final_response = final_response
|
|
488
|
+
logger.debug(final_response)
|
|
489
|
+
state.is_complete = True
|
|
490
|
+
return state
|
|
491
|
+
|
|
482
492
|
state.current_step = "vibesurf_agent"
|
|
483
493
|
if result.extracted_content:
|
|
484
494
|
vibesurf_agent.message_history.append(
|
|
@@ -1479,8 +1489,9 @@ Please continue with your assigned work, incorporating this guidance only if it'
|
|
|
1479
1489
|
"""
|
|
1480
1490
|
activity_entry = {
|
|
1481
1491
|
"agent_name": 'user',
|
|
1482
|
-
"agent_status": '
|
|
1483
|
-
"agent_msg": f"{new_task}"
|
|
1492
|
+
"agent_status": 'additional_request', # working, result, error
|
|
1493
|
+
"agent_msg": f"{new_task}",
|
|
1494
|
+
"timestamp": datetime.now().isoformat()
|
|
1484
1495
|
}
|
|
1485
1496
|
self.activity_logs.append(activity_entry)
|
|
1486
1497
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Agent API endpoints
|
|
3
|
+
"""
|
|
4
|
+
from typing import List
|
|
5
|
+
from fastapi import APIRouter, HTTPException
|
|
6
|
+
|
|
7
|
+
from vibe_surf.logger import get_logger
|
|
8
|
+
|
|
9
|
+
logger = get_logger(__name__)
|
|
10
|
+
|
|
11
|
+
router = APIRouter(prefix="/agent", tags=["agent"])
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@router.get("/get_all_skills", response_model=List[str])
|
|
15
|
+
async def get_all_skills():
|
|
16
|
+
"""
|
|
17
|
+
Get all available skill names from the VibeSurf tools registry.
|
|
18
|
+
Returns skill names with the 'skill_' prefix removed.
|
|
19
|
+
"""
|
|
20
|
+
try:
|
|
21
|
+
from ..shared_state import vibesurf_tools
|
|
22
|
+
if not vibesurf_tools:
|
|
23
|
+
raise HTTPException(status_code=500, detail="VibeSurf tools not initialized")
|
|
24
|
+
|
|
25
|
+
# Get all action names from the registry
|
|
26
|
+
all_actions = vibesurf_tools.registry.registry.actions.keys()
|
|
27
|
+
|
|
28
|
+
# Filter for actions that start with 'skill_' and remove the prefix
|
|
29
|
+
skill_names = [
|
|
30
|
+
action_name.replace('skill_', '')
|
|
31
|
+
for action_name in all_actions
|
|
32
|
+
if action_name.startswith('skill_')
|
|
33
|
+
]
|
|
34
|
+
logger.info(skill_names)
|
|
35
|
+
return skill_names
|
|
36
|
+
|
|
37
|
+
except Exception as e:
|
|
38
|
+
raise HTTPException(status_code=500, detail=f"Failed to get skills: {str(e)}")
|
|
@@ -234,7 +234,9 @@ async def update_llm_profile(
|
|
|
234
234
|
|
|
235
235
|
# Return updated profile
|
|
236
236
|
updated_profile = await LLMProfileQueries.get_profile(db, profile_name)
|
|
237
|
-
|
|
237
|
+
from ..shared_state import current_llm_profile_name
|
|
238
|
+
if current_llm_profile_name != profile_name:
|
|
239
|
+
current_llm_profile_name = None
|
|
238
240
|
# Use safe extraction to avoid greenlet issues
|
|
239
241
|
return LLMProfileResponse(**_profile_to_response_dict(updated_profile))
|
|
240
242
|
|
|
@@ -21,6 +21,7 @@ from .api.activity import router as activity_router
|
|
|
21
21
|
from .api.config import router as config_router
|
|
22
22
|
from .api.browser import router as browser_router
|
|
23
23
|
from .api.voices import router as voices_router
|
|
24
|
+
from .api.agent import router as agent_router
|
|
24
25
|
|
|
25
26
|
# Import shared state
|
|
26
27
|
from . import shared_state
|
|
@@ -53,6 +54,7 @@ app.include_router(activity_router, prefix="/api", tags=["activity"])
|
|
|
53
54
|
app.include_router(config_router, prefix="/api", tags=["config"])
|
|
54
55
|
app.include_router(browser_router, prefix="/api", tags=["browser"])
|
|
55
56
|
app.include_router(voices_router, prefix="/api", tags=["voices"])
|
|
57
|
+
app.include_router(agent_router, prefix="/api", tags=["agent"])
|
|
56
58
|
|
|
57
59
|
# Global variable to control browser monitoring task
|
|
58
60
|
browser_monitor_task = None
|
|
@@ -142,8 +142,9 @@ def create_llm_from_profile(llm_profile) -> BaseChatModel:
|
|
|
142
142
|
)
|
|
143
143
|
|
|
144
144
|
elif provider == "deepseek":
|
|
145
|
-
return
|
|
145
|
+
return ChatOpenAICompatible(
|
|
146
146
|
model=model,
|
|
147
|
+
base_url="https://api.deepseek.com",
|
|
147
148
|
api_key=api_key,
|
|
148
149
|
**common_params
|
|
149
150
|
)
|
|
@@ -407,11 +407,11 @@ class AgentBrowserSession(BrowserSession):
|
|
|
407
407
|
self.logger.info('🚫 VibeSurfBrowserSession: AboutBlankWatchdog disabled - no DVD animation will be shown')
|
|
408
408
|
|
|
409
409
|
# Initialize DownloadsWatchdog
|
|
410
|
-
DownloadsWatchdog.model_rebuild()
|
|
411
|
-
self._downloads_watchdog = DownloadsWatchdog(event_bus=self.event_bus, browser_session=self)
|
|
412
|
-
self._downloads_watchdog.attach_to_session()
|
|
413
|
-
if self.browser_profile.auto_download_pdfs:
|
|
414
|
-
|
|
410
|
+
# DownloadsWatchdog.model_rebuild()
|
|
411
|
+
# self._downloads_watchdog = DownloadsWatchdog(event_bus=self.event_bus, browser_session=self)
|
|
412
|
+
# self._downloads_watchdog.attach_to_session()
|
|
413
|
+
# if self.browser_profile.auto_download_pdfs:
|
|
414
|
+
# self.logger.info('📄 PDF auto-download enabled for this session')
|
|
415
415
|
|
|
416
416
|
# Initialize LocalBrowserWatchdog
|
|
417
417
|
LocalBrowserWatchdog.model_rebuild()
|
|
@@ -498,6 +498,11 @@ class VibeSurfAPIClient {
|
|
|
498
498
|
return this.get('/browser/all-tabs');
|
|
499
499
|
}
|
|
500
500
|
|
|
501
|
+
// Agent APIs - Get available skills
|
|
502
|
+
async getAllSkills() {
|
|
503
|
+
return this.get('/agent/get_all_skills');
|
|
504
|
+
}
|
|
505
|
+
|
|
501
506
|
// Utility methods
|
|
502
507
|
delay(ms) {
|
|
503
508
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
@@ -340,7 +340,7 @@ class VibeSurfApp {
|
|
|
340
340
|
<div class="input-container">
|
|
341
341
|
<div class="input-main">
|
|
342
342
|
<div class="textarea-container">
|
|
343
|
-
<textarea id="task-input" class="task-input" placeholder="
|
|
343
|
+
<textarea id="task-input" class="task-input" placeholder="Ask anything (/ for skills, @ to specify tab)" rows="3"></textarea>
|
|
344
344
|
<div class="input-actions">
|
|
345
345
|
<button id="attach-file-btn" class="action-btn attach-btn" title="Attach Files">
|
|
346
346
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|