vibesurf 0.1.9a6__tar.gz → 0.1.10__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.9a6 → vibesurf-0.1.10}/PKG-INFO +18 -2
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/README.md +17 -1
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/_version.py +3 -3
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/agents/vibe_surf_agent.py +25 -15
- vibesurf-0.1.10/vibe_surf/backend/api/browser.py +66 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/backend/api/task.py +2 -1
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/backend/main.py +76 -1
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/backend/shared_state.py +2 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/browser/agent_browser_session.py +312 -62
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/browser/browser_manager.py +57 -92
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/browser/watchdogs/dom_watchdog.py +43 -43
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/chrome_extension/background.js +84 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/chrome_extension/manifest.json +3 -1
- vibesurf-0.1.10/vibe_surf/chrome_extension/scripts/file-manager.js +526 -0
- vibesurf-0.1.10/vibe_surf/chrome_extension/scripts/history-manager.js +658 -0
- vibesurf-0.1.10/vibe_surf/chrome_extension/scripts/modal-manager.js +487 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/chrome_extension/scripts/session-manager.js +31 -8
- vibesurf-0.1.10/vibe_surf/chrome_extension/scripts/settings-manager.js +1214 -0
- vibesurf-0.1.10/vibe_surf/chrome_extension/scripts/ui-manager.js +1414 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/chrome_extension/sidepanel.html +27 -4
- vibesurf-0.1.10/vibe_surf/chrome_extension/styles/activity.css +574 -0
- vibesurf-0.1.10/vibe_surf/chrome_extension/styles/base.css +76 -0
- vibesurf-0.1.10/vibe_surf/chrome_extension/styles/history-modal.css +791 -0
- vibesurf-0.1.10/vibe_surf/chrome_extension/styles/input.css +429 -0
- vibesurf-0.1.10/vibe_surf/chrome_extension/styles/layout.css +186 -0
- vibesurf-0.1.10/vibe_surf/chrome_extension/styles/responsive.css +454 -0
- vibesurf-0.1.10/vibe_surf/chrome_extension/styles/settings-environment.css +165 -0
- vibesurf-0.1.10/vibe_surf/chrome_extension/styles/settings-forms.css +389 -0
- vibesurf-0.1.10/vibe_surf/chrome_extension/styles/settings-modal.css +141 -0
- vibesurf-0.1.10/vibe_surf/chrome_extension/styles/settings-profiles.css +244 -0
- vibesurf-0.1.10/vibe_surf/chrome_extension/styles/settings-responsive.css +144 -0
- vibesurf-0.1.10/vibe_surf/chrome_extension/styles/settings-utilities.css +25 -0
- vibesurf-0.1.10/vibe_surf/chrome_extension/styles/variables.css +54 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/cli.py +1 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/controller/vibesurf_tools.py +0 -2
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibesurf.egg-info/PKG-INFO +18 -2
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibesurf.egg-info/SOURCES.txt +38 -6
- vibesurf-0.1.9a6/vibe_surf/chrome_extension/scripts/ui-manager.js +0 -3830
- vibesurf-0.1.9a6/vibe_surf/chrome_extension/styles/main.css +0 -2338
- vibesurf-0.1.9a6/vibe_surf/chrome_extension/styles/settings.css +0 -1100
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/.env.example +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/.github/workflows/publish.yml +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/.gitignore +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/.python-version +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/LICENSE +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/MANIFEST.in +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/docs/EXECUTABLE_BUILD.md +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/docs/PYPI_SETUP.md +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/pyproject.toml +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10/scripts}/build-local.bat +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10/scripts}/build-local.sh +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/setup.cfg +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/tests/test_agents.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/tests/test_backend_api.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/tests/test_browser.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/tests/test_controller.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/__init__.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/agents/__init__.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/agents/browser_use_agent.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/agents/prompts/__init__.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/agents/prompts/vibe_surf_prompt.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/agents/report_writer_agent.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/backend/__init__.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/backend/api/__init__.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/backend/api/activity.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/backend/api/config.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/backend/api/files.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/backend/api/models.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/backend/database/__init__.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/backend/database/manager.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/backend/database/models.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/backend/database/queries.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/backend/database/schemas.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/backend/llm_config.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/backend/migrations/__init__.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/backend/migrations/init_db.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/backend/migrations/seed_data.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/backend/utils/__init__.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/backend/utils/encryption.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/backend/utils/llm_factory.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/browser/__init__.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/browser/agen_browser_profile.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/browser/utils.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/browser/watchdogs/__init__.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/browser/watchdogs/action_watchdog.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/chrome_extension/config.js +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/chrome_extension/content.js +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/chrome_extension/dev-reload.js +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/chrome_extension/icons/convert-svg.js +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/chrome_extension/icons/logo-preview.html +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/chrome_extension/icons/logo.icns +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/chrome_extension/icons/logo.png +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/chrome_extension/popup.html +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/chrome_extension/scripts/api-client.js +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/chrome_extension/scripts/main.js +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/chrome_extension/scripts/markdown-it.min.js +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/chrome_extension/styles/animations.css +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/chrome_extension/styles/components.css +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/controller/__init__.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/controller/file_system.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/controller/mcp_client.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/controller/views.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/llm/__init__.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibe_surf/llm/openai_compatible.py +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibesurf.egg-info/dependency_links.txt +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibesurf.egg-info/entry_points.txt +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibesurf.egg-info/requires.txt +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/vibesurf.egg-info/top_level.txt +0 -0
- {vibesurf-0.1.9a6 → vibesurf-0.1.10}/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.10
|
|
4
4
|
Summary: VibeSurf: A powerful browser assistant for vibe surfing
|
|
5
5
|
Author: Shao Warm
|
|
6
6
|
License: Apache-2.0
|
|
@@ -81,9 +81,25 @@ uv pip install vibesurf -U
|
|
|
81
81
|
|
|
82
82
|
### Step 3: Launch
|
|
83
83
|
```bash
|
|
84
|
-
vibesurf
|
|
84
|
+
uv run vibesurf
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
+
## 🗺️ Roadmap
|
|
88
|
+
|
|
89
|
+
### 🤖 Agent Enhancements
|
|
90
|
+
|
|
91
|
+
- **VibeSurf Agent Refactoring**: Remove LangGraph framework dependency to make the agent more flexible and powerful
|
|
92
|
+
- **Advanced Coding Agent**: Design a powerful coding agent capable of handling and analyzing complex data, generating charts and visualizations. Combined with VibeSurf agent, this will create a "local Manus" experience
|
|
93
|
+
- **Enhanced Report Writer Agent**: Optimize the report writer to generate more visually appealing reports with rich graphics and illustrations
|
|
94
|
+
- **Global Memory System**: Implement global memory capabilities to make VibeSurf understand and adapt to user preferences better
|
|
95
|
+
|
|
96
|
+
### 🧩 Extension Features
|
|
97
|
+
|
|
98
|
+
- **Enhanced Tab Management**: Add @specific tab handling with `/research` and `/deep_research` specialized task commands
|
|
99
|
+
- **Smart Text Processing**: Implement word/paragraph translation, summarization, and explanation features for selected content
|
|
100
|
+
- **Local Credential Management**: Add secure credential configuration system to keep your privacy data stored locally
|
|
101
|
+
|
|
102
|
+
|
|
87
103
|
## 🎬 Demo
|
|
88
104
|
|
|
89
105
|
### How to use?
|
|
@@ -39,9 +39,25 @@ uv pip install vibesurf -U
|
|
|
39
39
|
|
|
40
40
|
### Step 3: Launch
|
|
41
41
|
```bash
|
|
42
|
-
vibesurf
|
|
42
|
+
uv run vibesurf
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
+
## 🗺️ Roadmap
|
|
46
|
+
|
|
47
|
+
### 🤖 Agent Enhancements
|
|
48
|
+
|
|
49
|
+
- **VibeSurf Agent Refactoring**: Remove LangGraph framework dependency to make the agent more flexible and powerful
|
|
50
|
+
- **Advanced Coding Agent**: Design a powerful coding agent capable of handling and analyzing complex data, generating charts and visualizations. Combined with VibeSurf agent, this will create a "local Manus" experience
|
|
51
|
+
- **Enhanced Report Writer Agent**: Optimize the report writer to generate more visually appealing reports with rich graphics and illustrations
|
|
52
|
+
- **Global Memory System**: Implement global memory capabilities to make VibeSurf understand and adapt to user preferences better
|
|
53
|
+
|
|
54
|
+
### 🧩 Extension Features
|
|
55
|
+
|
|
56
|
+
- **Enhanced Tab Management**: Add @specific tab handling with `/research` and `/deep_research` specialized task commands
|
|
57
|
+
- **Smart Text Processing**: Implement word/paragraph translation, summarization, and explanation features for selected content
|
|
58
|
+
- **Local Credential Management**: Add secure credential configuration system to keep your privacy data stored locally
|
|
59
|
+
|
|
60
|
+
|
|
45
61
|
## 🎬 Demo
|
|
46
62
|
|
|
47
63
|
### How to use?
|
|
@@ -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.10'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 1, 10)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'g3e1f64f34'
|
|
@@ -473,7 +473,12 @@ async def _supervisor_agent_node_impl(state: VibeSurfState) -> VibeSurfState:
|
|
|
473
473
|
browser_tabs_md = format_browser_tabs(browser_tabs)
|
|
474
474
|
if browser_tabs_md:
|
|
475
475
|
supervisor_message_history.append(UserMessage(
|
|
476
|
-
content=f"Available Browser Tabs:\n{browser_tabs_md}"))
|
|
476
|
+
content=f"Available Browser Tabs:\n{browser_tabs_md}\n"))
|
|
477
|
+
active_browser_tab = await state.browser_manager.get_activate_tab()
|
|
478
|
+
if active_browser_tab:
|
|
479
|
+
active_tab_md = f"Page Title: {active_browser_tab.title}, Page Url: {active_browser_tab.url}, Page ID: {active_browser_tab.target_id}"
|
|
480
|
+
supervisor_message_history.append(UserMessage(
|
|
481
|
+
content=f"Current Active Browser Tab:\n{active_tab_md}\n"))
|
|
477
482
|
|
|
478
483
|
# Reset prev_browser_results
|
|
479
484
|
state.prev_browser_results = []
|
|
@@ -536,23 +541,28 @@ async def _supervisor_agent_node_impl(state: VibeSurfState) -> VibeSurfState:
|
|
|
536
541
|
if tasks_to_execute:
|
|
537
542
|
tasks_to_execute_new = []
|
|
538
543
|
todo_indices = [] # Track which todo items are being executed
|
|
539
|
-
|
|
540
544
|
for task_item in tasks_to_execute:
|
|
541
545
|
if isinstance(task_item, list):
|
|
542
546
|
# Format: [page_index, todo_index]
|
|
543
547
|
page_index, todo_index = task_item
|
|
544
|
-
if todo_index
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
+
if isinstance(todo_index, int):
|
|
549
|
+
if todo_index < len(state.todo_list):
|
|
550
|
+
task_description = state.todo_list[todo_index].task
|
|
551
|
+
tasks_to_execute_new.append([browser_tabs[page_index].target_id, task_description])
|
|
552
|
+
todo_indices.append(todo_index)
|
|
553
|
+
elif isinstance(todo_index, str):
|
|
554
|
+
tasks_to_execute_new.append([browser_tabs[page_index].target_id, todo_index])
|
|
548
555
|
else:
|
|
549
556
|
# Format: todo_index
|
|
550
557
|
todo_index = task_item
|
|
551
|
-
if todo_index
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
558
|
+
if isinstance(todo_index, int):
|
|
559
|
+
if todo_index < len(state.todo_list):
|
|
560
|
+
task_description = state.todo_list[todo_index].task
|
|
561
|
+
tasks_to_execute_new.append(task_description)
|
|
562
|
+
todo_indices.append(todo_index)
|
|
563
|
+
elif isinstance(todo_index, str):
|
|
564
|
+
tasks_to_execute_new.append(todo_index)
|
|
565
|
+
logger.info(f"tasks_to_execute: {tasks_to_execute}")
|
|
556
566
|
state.execution_mode = ExecutionMode(
|
|
557
567
|
mode=task_type,
|
|
558
568
|
reason=reasoning
|
|
@@ -795,7 +805,7 @@ async def execute_parallel_browser_tasks(state: VibeSurfState) -> List[BrowserTa
|
|
|
795
805
|
browser_session=agent_browser_sessions[i],
|
|
796
806
|
controller=state.vibesurf_controller,
|
|
797
807
|
task_id=f"{state.task_id}-{i + 1}",
|
|
798
|
-
file_system_path=state.task_dir,
|
|
808
|
+
file_system_path=os.path.join(state.task_dir, f"{state.task_id}-{i + 1}"),
|
|
799
809
|
register_new_step_callback=step_callback,
|
|
800
810
|
extend_system_message="Please make sure the language of your output in JSON value should remain the same as the user's request or task.",
|
|
801
811
|
)
|
|
@@ -867,17 +877,17 @@ async def execute_single_browser_tasks(state: VibeSurfState) -> List[BrowserTask
|
|
|
867
877
|
for i, task in enumerate(state.pending_tasks):
|
|
868
878
|
if isinstance(task, list):
|
|
869
879
|
target_id, task_description = task
|
|
880
|
+
await state.browser_manager.main_browser_session.get_or_create_cdp_session(target_id, focus=True)
|
|
870
881
|
else:
|
|
871
882
|
task_description = task
|
|
883
|
+
await state.browser_manager.get_activate_tab()
|
|
872
884
|
logger.info(f"🔄 Executing task ({i + 1}/{len(state.pending_tasks)}): {task_description}")
|
|
873
885
|
|
|
874
886
|
agent_id = f"agent-single-{state.task_id[-4:]}-{i}"
|
|
875
887
|
|
|
876
888
|
# Log agent activity
|
|
877
889
|
log_agent_activity(state, f"browser_use_agent-{state.task_id[-4:]}", "working", f"{task_description}")
|
|
878
|
-
|
|
879
890
|
try:
|
|
880
|
-
await state.browser_manager._get_active_target()
|
|
881
891
|
if state.upload_files:
|
|
882
892
|
upload_files_md = format_upload_files_list(state.upload_files)
|
|
883
893
|
bu_task = task_description + f"\nAvailable user uploaded files:\n{upload_files_md}\n"
|
|
@@ -893,7 +903,7 @@ async def execute_single_browser_tasks(state: VibeSurfState) -> List[BrowserTask
|
|
|
893
903
|
browser_session=state.browser_manager.main_browser_session,
|
|
894
904
|
controller=state.vibesurf_controller,
|
|
895
905
|
task_id=f"{state.task_id}-{i}",
|
|
896
|
-
file_system_path=state.task_dir,
|
|
906
|
+
file_system_path=os.path.join(state.task_dir, f"{state.task_id}-{i}"),
|
|
897
907
|
register_new_step_callback=step_callback,
|
|
898
908
|
extend_system_message="Please make sure the language of your output in JSON values should remain the same as the user's request or task."
|
|
899
909
|
)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Browser Tabs Router
|
|
3
|
+
|
|
4
|
+
Handles retrieval of browser tab information including active tab and all tabs.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from fastapi import APIRouter, HTTPException
|
|
8
|
+
from typing import Dict, Any, Optional
|
|
9
|
+
import logging
|
|
10
|
+
|
|
11
|
+
# Import global variables from shared_state
|
|
12
|
+
from ..shared_state import browser_manager
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
router = APIRouter(prefix="/browser", tags=["browser"])
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@router.get("/active-tab")
|
|
20
|
+
async def get_active_tab() -> Dict[str, Dict[str, str]]:
|
|
21
|
+
"""Get the current active tab information"""
|
|
22
|
+
if not browser_manager:
|
|
23
|
+
raise HTTPException(status_code=503, detail="Browser manager not initialized")
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
# Get active tab info using browser manager
|
|
27
|
+
active_tab_info = await browser_manager.get_activate_tab()
|
|
28
|
+
|
|
29
|
+
if not active_tab_info:
|
|
30
|
+
return {}
|
|
31
|
+
|
|
32
|
+
# Return dict format: {tab_id: {url: , title: }}
|
|
33
|
+
return {
|
|
34
|
+
active_tab_info.target_id: {
|
|
35
|
+
"url": active_tab_info.url,
|
|
36
|
+
"title": active_tab_info.title
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
except Exception as e:
|
|
41
|
+
logger.error(f"Failed to get active tab: {e}")
|
|
42
|
+
raise HTTPException(status_code=500, detail=f"Failed to get active tab: {str(e)}")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@router.get("/all-tabs")
|
|
46
|
+
async def get_all_tabs() -> Dict[str, Dict[str, str]]:
|
|
47
|
+
"""Get all browser tabs information"""
|
|
48
|
+
if not browser_manager:
|
|
49
|
+
raise HTTPException(status_code=503, detail="Browser manager not initialized")
|
|
50
|
+
|
|
51
|
+
try:
|
|
52
|
+
all_tab_infos = await browser_manager.get_all_tabs()
|
|
53
|
+
|
|
54
|
+
# Filter only page targets and build result dict
|
|
55
|
+
result = {}
|
|
56
|
+
for tab_info in all_tab_infos:
|
|
57
|
+
result[tab_info.target_id] = {
|
|
58
|
+
"url": tab_info.url,
|
|
59
|
+
"title": tab_info.title
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return result
|
|
63
|
+
|
|
64
|
+
except Exception as e:
|
|
65
|
+
logger.error(f"Failed to get all tabs: {e}")
|
|
66
|
+
raise HTTPException(status_code=500, detail=f"Failed to get all tabs: {str(e)}")
|
|
@@ -11,6 +11,7 @@ from fastapi.middleware.cors import CORSMiddleware
|
|
|
11
11
|
import logging
|
|
12
12
|
import argparse
|
|
13
13
|
import os
|
|
14
|
+
import asyncio
|
|
14
15
|
from datetime import datetime
|
|
15
16
|
|
|
16
17
|
# Import routers
|
|
@@ -18,6 +19,7 @@ from .api.task import router as agents_router
|
|
|
18
19
|
from .api.files import router as files_router
|
|
19
20
|
from .api.activity import router as activity_router
|
|
20
21
|
from .api.config import router as config_router
|
|
22
|
+
from .api.browser import router as browser_router
|
|
21
23
|
|
|
22
24
|
# Import shared state
|
|
23
25
|
from . import shared_state
|
|
@@ -46,18 +48,86 @@ app.include_router(agents_router, prefix="/api", tags=["tasks"])
|
|
|
46
48
|
app.include_router(files_router, prefix="/api", tags=["files"])
|
|
47
49
|
app.include_router(activity_router, prefix="/api", tags=["activity"])
|
|
48
50
|
app.include_router(config_router, prefix="/api", tags=["config"])
|
|
51
|
+
app.include_router(browser_router, prefix="/api", tags=["browser"])
|
|
52
|
+
|
|
53
|
+
# Global variable to control browser monitoring task
|
|
54
|
+
browser_monitor_task = None
|
|
55
|
+
|
|
56
|
+
async def monitor_browser_connection():
|
|
57
|
+
"""Background task to monitor browser connection"""
|
|
58
|
+
while True:
|
|
59
|
+
try:
|
|
60
|
+
await asyncio.sleep(2) # Check every 1 second
|
|
61
|
+
|
|
62
|
+
if shared_state.browser_manager:
|
|
63
|
+
is_connected = await shared_state.browser_manager.check_browser_connected()
|
|
64
|
+
if not is_connected:
|
|
65
|
+
logger.error("No Available Browser, Exiting...")
|
|
66
|
+
|
|
67
|
+
# Schedule a graceful shutdown using os.kill in a separate thread
|
|
68
|
+
import threading
|
|
69
|
+
import signal
|
|
70
|
+
import os
|
|
71
|
+
|
|
72
|
+
def trigger_shutdown():
|
|
73
|
+
try:
|
|
74
|
+
# Give a brief moment for any cleanup
|
|
75
|
+
import time
|
|
76
|
+
time.sleep(0.5)
|
|
77
|
+
# Send SIGTERM to current process for graceful shutdown
|
|
78
|
+
os.kill(os.getpid(), signal.SIGTERM)
|
|
79
|
+
except Exception as e:
|
|
80
|
+
logger.error(f"Error during shutdown trigger: {e}")
|
|
81
|
+
# Fallback to SIGKILL if SIGTERM doesn't work
|
|
82
|
+
try:
|
|
83
|
+
os.kill(os.getpid(), signal.SIGKILL)
|
|
84
|
+
except:
|
|
85
|
+
pass
|
|
86
|
+
|
|
87
|
+
# Start shutdown in a separate thread to avoid blocking the async loop
|
|
88
|
+
shutdown_thread = threading.Thread(target=trigger_shutdown)
|
|
89
|
+
shutdown_thread.daemon = True
|
|
90
|
+
shutdown_thread.start()
|
|
91
|
+
|
|
92
|
+
# Exit the monitoring loop
|
|
93
|
+
break
|
|
94
|
+
|
|
95
|
+
except asyncio.CancelledError:
|
|
96
|
+
logger.info("Browser monitor task cancelled")
|
|
97
|
+
break
|
|
98
|
+
except Exception as e:
|
|
99
|
+
logger.warning(f"Browser monitor error: {e}")
|
|
100
|
+
# Continue monitoring even if there's an error
|
|
49
101
|
|
|
50
102
|
@app.on_event("startup")
|
|
51
103
|
async def startup_event():
|
|
52
104
|
"""Initialize database and VibeSurf components on startup"""
|
|
105
|
+
global browser_monitor_task
|
|
106
|
+
|
|
53
107
|
# Initialize VibeSurf components and update shared state
|
|
54
108
|
await shared_state.initialize_vibesurf_components()
|
|
55
109
|
|
|
110
|
+
# Start browser monitoring task
|
|
111
|
+
browser_monitor_task = asyncio.create_task(monitor_browser_connection())
|
|
112
|
+
logger.info("🔍 Started browser connection monitor")
|
|
113
|
+
|
|
56
114
|
logger.info("🚀 VibeSurf Backend API started with single-task execution model")
|
|
57
115
|
|
|
58
116
|
@app.on_event("shutdown")
|
|
59
117
|
async def shutdown_event():
|
|
60
118
|
"""Cleanup on shutdown"""
|
|
119
|
+
global browser_monitor_task
|
|
120
|
+
|
|
121
|
+
logger.info("🛑 Starting graceful shutdown...")
|
|
122
|
+
|
|
123
|
+
# Cancel browser monitor task
|
|
124
|
+
if browser_monitor_task and not browser_monitor_task.done():
|
|
125
|
+
browser_monitor_task.cancel()
|
|
126
|
+
try:
|
|
127
|
+
await asyncio.wait_for(browser_monitor_task, timeout=2.0)
|
|
128
|
+
except (asyncio.CancelledError, asyncio.TimeoutError):
|
|
129
|
+
pass
|
|
130
|
+
logger.info("✅ Browser monitor task stopped")
|
|
61
131
|
|
|
62
132
|
# Cleanup VibeSurf components
|
|
63
133
|
if shared_state.browser_manager:
|
|
@@ -70,7 +140,12 @@ async def shutdown_event():
|
|
|
70
140
|
|
|
71
141
|
# Close database
|
|
72
142
|
if shared_state.db_manager:
|
|
73
|
-
|
|
143
|
+
try:
|
|
144
|
+
await shared_state.db_manager.close()
|
|
145
|
+
logger.info("✅ Database manager closed")
|
|
146
|
+
except Exception as e:
|
|
147
|
+
logger.error(f"❌ Error closing database manager: {e}")
|
|
148
|
+
|
|
74
149
|
logger.info("🛑 VibeSurf Backend API stopped")
|
|
75
150
|
|
|
76
151
|
# Health check endpoint
|
|
@@ -422,6 +422,8 @@ async def initialize_vibesurf_components():
|
|
|
422
422
|
user_data_dir=browser_user_data,
|
|
423
423
|
headless=False,
|
|
424
424
|
keep_alive=True,
|
|
425
|
+
auto_download_pdfs=False,
|
|
426
|
+
highlight_elements=True,
|
|
425
427
|
custom_extensions=[envs["VIBESURF_EXTENSION"]],
|
|
426
428
|
window_size={"width": primary_monitor.width, "height": primary_monitor.height}
|
|
427
429
|
)
|