vibesurf 0.1.23__tar.gz → 0.1.25__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.23 → vibesurf-0.1.25}/PKG-INFO +2 -1
- {vibesurf-0.1.23 → vibesurf-0.1.25}/pyproject.toml +1 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/tests/test_agents.py +51 -44
- {vibesurf-0.1.23 → vibesurf-0.1.25}/tests/test_tools.py +12 -1
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/_version.py +3 -3
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/agents/vibe_surf_agent.py +1 -1
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/api/config.py +3 -1
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/utils/llm_factory.py +2 -1
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/llm/openai_compatible.py +34 -10
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/tools/file_system.py +2 -2
- vibesurf-0.1.25/vibe_surf/tools/finance_tools.py +629 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/tools/report_writer_tools.py +2 -1
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/tools/vibesurf_tools.py +348 -29
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/tools/views.py +33 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibesurf.egg-info/PKG-INFO +2 -1
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibesurf.egg-info/SOURCES.txt +2 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibesurf.egg-info/requires.txt +1 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/.env.example +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/.github/workflows/publish.yml +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/.gitignore +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/.python-version +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/LICENSE +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/MANIFEST.in +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/README.md +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/docs/EXECUTABLE_BUILD.md +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/docs/PYPI_SETUP.md +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/scripts/build-local.bat +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/scripts/build-local.sh +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/setup.cfg +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/tests/test_backend_api.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/tests/test_browser.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/tests/test_voice_api.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/__init__.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/agents/__init__.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/agents/browser_use_agent.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/agents/prompts/__init__.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/agents/prompts/report_writer_prompt.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/agents/prompts/vibe_surf_prompt.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/agents/report_writer_agent.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/agents/views.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/__init__.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/api/__init__.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/api/activity.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/api/agent.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/api/browser.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/api/files.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/api/models.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/api/task.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/api/voices.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/database/__init__.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/database/manager.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/database/migrations/v001_initial_schema.sql +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/database/migrations/v002_add_agent_mode.sql +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/database/migrations/v003_fix_task_status_case.sql +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/database/migrations/v004_add_voice_profiles.sql +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/database/models.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/database/queries.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/database/schemas.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/llm_config.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/main.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/shared_state.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/utils/__init__.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/utils/encryption.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/backend/voice_model_config.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/browser/__init__.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/browser/agen_browser_profile.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/browser/agent_browser_session.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/browser/browser_manager.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/browser/utils.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/browser/watchdogs/__init__.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/browser/watchdogs/action_watchdog.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/browser/watchdogs/dom_watchdog.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/background.js +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/config.js +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/content.js +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/dev-reload.js +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/icons/logo.icns +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/icons/logo.png +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/manifest.json +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/permission-iframe.html +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/permission-request.html +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/popup.html +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/scripts/api-client.js +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/scripts/file-manager.js +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/scripts/history-manager.js +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/scripts/main.js +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/scripts/markdown-it.min.js +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/scripts/modal-manager.js +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/scripts/permission-iframe-request.js +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/scripts/permission-request.js +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/scripts/session-manager.js +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/scripts/settings-manager.js +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/scripts/ui-manager.js +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/scripts/user-settings-storage.js +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/scripts/voice-recorder.js +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/sidepanel.html +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/styles/activity.css +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/styles/animations.css +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/styles/base.css +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/styles/components.css +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/styles/history-modal.css +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/styles/input.css +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/styles/layout.css +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/styles/responsive.css +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/styles/settings-environment.css +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/styles/settings-forms.css +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/styles/settings-modal.css +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/styles/settings-profiles.css +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/styles/settings-responsive.css +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/styles/settings-utilities.css +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/chrome_extension/styles/variables.css +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/cli.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/common.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/llm/__init__.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/logger.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/tools/__init__.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/tools/browser_use_tools.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/tools/mcp_client.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/tools/vibesurf_registry.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibe_surf/tools/voice_asr.py +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibesurf.egg-info/dependency_links.txt +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibesurf.egg-info/entry_points.txt +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/vibesurf.egg-info/top_level.txt +0 -0
- {vibesurf-0.1.23 → vibesurf-0.1.25}/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.25
|
|
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())
|
|
@@ -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.25'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 1, 25)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'gb2d55c9c9'
|
|
@@ -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 "skill_search"
|
|
482
|
+
if action_name in ["skill_search", "skill_crawl", "skill_summary", "skill_finance"]:
|
|
483
483
|
state.current_step = "END"
|
|
484
484
|
# Format final response
|
|
485
485
|
final_response = f"{result.extracted_content}"
|
|
@@ -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
|
|
|
@@ -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
|
)
|
|
@@ -51,6 +51,8 @@ from browser_use.llm.openai.serializer import OpenAIMessageSerializer
|
|
|
51
51
|
from browser_use.llm.schema import SchemaOptimizer
|
|
52
52
|
from browser_use.llm.views import ChatInvokeCompletion, ChatInvokeUsage
|
|
53
53
|
|
|
54
|
+
from json_repair import repair_json
|
|
55
|
+
|
|
54
56
|
T = TypeVar('T', bound=BaseModel)
|
|
55
57
|
|
|
56
58
|
from vibe_surf.logger import get_logger
|
|
@@ -74,6 +76,8 @@ class ChatOpenAICompatible(ChatOpenAI):
|
|
|
74
76
|
The class automatically detects the model type and applies appropriate fixes.
|
|
75
77
|
"""
|
|
76
78
|
|
|
79
|
+
max_completion_tokens: int | None = 16000
|
|
80
|
+
|
|
77
81
|
def _is_gemini_model(self) -> bool:
|
|
78
82
|
"""Check if the current model is a Gemini model."""
|
|
79
83
|
return str(self.model).lower().startswith('gemini')
|
|
@@ -82,6 +86,11 @@ class ChatOpenAICompatible(ChatOpenAI):
|
|
|
82
86
|
"""Check if the current model is a Kimi/Moonshot model."""
|
|
83
87
|
model_str = str(self.model).lower()
|
|
84
88
|
return 'kimi' in model_str or 'moonshot' in model_str
|
|
89
|
+
|
|
90
|
+
def _is_deepseek_model(self) -> bool:
|
|
91
|
+
"""Check if the current model is a Kimi/Moonshot model."""
|
|
92
|
+
model_str = str(self.model).lower()
|
|
93
|
+
return 'deepseek' in model_str
|
|
85
94
|
|
|
86
95
|
def _is_qwen_model(self) -> bool:
|
|
87
96
|
"""Check if the current model is a Qwen model."""
|
|
@@ -223,10 +232,10 @@ class ChatOpenAICompatible(ChatOpenAI):
|
|
|
223
232
|
"""
|
|
224
233
|
# If this is not a special model or no structured output is requested,
|
|
225
234
|
# use the parent implementation directly
|
|
226
|
-
if self._is_qwen_model() or self._is_kimi_model():
|
|
235
|
+
if self._is_qwen_model() or self._is_kimi_model() or self._is_deepseek_model() :
|
|
227
236
|
self.add_schema_to_system_prompt = True
|
|
228
237
|
|
|
229
|
-
if not (self._is_gemini_model() or self._is_kimi_model() or self._is_qwen_model()) or output_format is None:
|
|
238
|
+
if not (self._is_gemini_model() or self._is_kimi_model() or self._is_qwen_model() or self._is_deepseek_model()) or output_format is None:
|
|
230
239
|
return await super().ainvoke(messages, output_format)
|
|
231
240
|
openai_messages = OpenAIMessageSerializer.serialize_messages(messages)
|
|
232
241
|
|
|
@@ -241,6 +250,7 @@ class ChatOpenAICompatible(ChatOpenAI):
|
|
|
241
250
|
|
|
242
251
|
if self.max_completion_tokens is not None:
|
|
243
252
|
model_params['max_completion_tokens'] = self.max_completion_tokens
|
|
253
|
+
model_params['max_tokens'] = self.max_completion_tokens
|
|
244
254
|
|
|
245
255
|
if self.top_p is not None:
|
|
246
256
|
model_params['top_p'] = self.top_p
|
|
@@ -298,12 +308,22 @@ class ChatOpenAICompatible(ChatOpenAI):
|
|
|
298
308
|
]
|
|
299
309
|
|
|
300
310
|
# Return structured response
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
311
|
+
if self.add_schema_to_system_prompt:
|
|
312
|
+
response = await self.get_client().chat.completions.create(
|
|
313
|
+
model=self.model,
|
|
314
|
+
messages=openai_messages,
|
|
315
|
+
response_format={
|
|
316
|
+
'type': 'json_object'
|
|
317
|
+
},
|
|
318
|
+
**model_params,
|
|
319
|
+
)
|
|
320
|
+
else:
|
|
321
|
+
response = await self.get_client().chat.completions.create(
|
|
322
|
+
model=self.model,
|
|
323
|
+
messages=openai_messages,
|
|
324
|
+
response_format=ResponseFormatJSONSchema(json_schema=response_format, type='json_schema'),
|
|
325
|
+
**model_params,
|
|
326
|
+
)
|
|
307
327
|
|
|
308
328
|
if response.choices[0].message.content is None:
|
|
309
329
|
raise ModelProviderError(
|
|
@@ -313,8 +333,12 @@ class ChatOpenAICompatible(ChatOpenAI):
|
|
|
313
333
|
)
|
|
314
334
|
|
|
315
335
|
usage = self._get_usage(response)
|
|
316
|
-
|
|
317
|
-
|
|
336
|
+
output_content = response.choices[0].message.content
|
|
337
|
+
try:
|
|
338
|
+
parsed = output_format.model_validate_json(output_content)
|
|
339
|
+
except Exception as e:
|
|
340
|
+
repair_content = repair_json(output_content)
|
|
341
|
+
parsed = output_format.model_validate_json(repair_content)
|
|
318
342
|
|
|
319
343
|
return ChatInvokeCompletion(
|
|
320
344
|
completion=parsed,
|
|
@@ -224,9 +224,9 @@ class CustomFileSystem(FileSystem):
|
|
|
224
224
|
def _is_valid_filename(self, file_name: str) -> bool:
|
|
225
225
|
"""Check if filename matches the required pattern: name.extension"""
|
|
226
226
|
# Build extensions pattern from _file_types
|
|
227
|
-
file_name = os.path.
|
|
227
|
+
file_name = os.path.splitext(file_name)[1]
|
|
228
228
|
extensions = '|'.join(self._file_types.keys())
|
|
229
|
-
pattern = rf'
|
|
229
|
+
pattern = rf'\.({extensions})$'
|
|
230
230
|
return bool(re.match(pattern, file_name))
|
|
231
231
|
|
|
232
232
|
async def append_file(self, full_filename: str, content: str) -> str:
|