Skip to content

[2026.01.16] - 2026-01-16#113

Merged
OEvortex merged 11 commits intomainfrom
feature/search
Jan 16, 2026
Merged

[2026.01.16] - 2026-01-16#113
OEvortex merged 11 commits intomainfrom
feature/search

Conversation

@OEvortex
Copy link
Owner

This pull request introduces major new functionality and improvements centered around Brave search engine support across multiple modalities, including videos, news, images, and suggestions. It also adds a new AI search provider, refines CLI output, and improves documentation. The most important changes are grouped by theme below.

Brave Search Engine Integration

  • Added new engines: BraveVideos, BraveNews, BraveSuggestions, and BraveImages, each capable of parsing HTML or API responses to extract rich results (videos, news articles, suggestions, images) with metadata and pagination support. ([changelog.mdR5-R31](https://github.com/OEvortex/Webscout/pull/113/files#diff-3bd14d078188074c410028847113ceae68865d0ad5b844a27183ef87fbe2fcc3R5-R31))
  • Implemented and unified these engines in BraveSearch interface, enabling seamless access to all Brave search types. ([changelog.mdR5-R31](https://github.com/OEvortex/Webscout/pull/113/files#diff-3bd14d078188074c410028847113ceae68865d0ad5b844a27183ef87fbe2fcc3R5-R31))

CLI and UI Improvements

  • Refactored webscout/cli.py to introduce specialized print functions for videos, news, suggestions, and images, improving result formatting and user experience. Helper functions for formatting and truncation were also added. ([changelog.mdR5-R31](https://github.com/OEvortex/Webscout/pull/113/files#diff-3bd14d078188074c410028847113ceae68865d0ad5b844a27183ef87fbe2fcc3R5-R31))

Provider and API Enhancements

  • Added BraveAI.py provider for AI-powered search and deep research, supporting both streaming and non-streaming modes. Updated exports and documentation for the new provider. ([changelog.mdR5-R31](https://github.com/OEvortex/Webscout/pull/113/files#diff-3bd14d078188074c410028847113ceae68865d0ad5b844a27183ef87fbe2fcc3R5-R31))

Testing and Quality Assurance

  • Added comprehensive unit and integration tests for BraveImages in tests/providers/test_brave_images.py, covering initialization, payload building, pagination, result extraction, and real web searches. ([tests/providers/test_brave_images.pyR1-R215](https://github.com/OEvortex/Webscout/pull/113/files#diff-b33b8220d17bb1b75eff4d256e0d0c7af22c83c7821a2da48b5b62d47b380efdR1-R215))
  • Added a demo script lol.py to exercise all new Brave engines and display their results using rich formatting. ([lol.pyR1-R63](https://github.com/OEvortex/Webscout/pull/113/files#diff-ee804a83ab10a6e0c63438659b6c7f76c9a7cf5dbcf4805424c65d8bb7a0240cR1-R63))

Documentation Updates

  • Updated CLI help text and endpoint documentation to reflect new Brave features and improved parameter handling. ([changelog.mdR5-R31](https://github.com/OEvortex/Webscout/pull/113/files#diff-3bd14d078188074c410028847113ceae68865d0ad5b844a27183ef87fbe2fcc3R5-R31))

These changes collectively provide robust Brave search capabilities, improved developer experience, and higher code quality across the project.

…I capabilities; remove unused ChatZAI provider and line counter script; introduce docstring and reverse engineering agents

Signed-off-by: OEvortex <[email protected]>
…tor Brave engine; update documentation and usage instructions

Signed-off-by: OEvortex <[email protected]>
…d parsing

- Updated the unified web search endpoint to include video search capabilities and enhanced suggestions handling.
- Added Brave search engines for text, images, news, suggestions, and videos with comprehensive parsing logic.
- Implemented unit tests for Brave text search parsing to ensure accuracy and reliability.
- Introduced a new BraveSearch class to unify search functionalities across different media types.
- Enhanced error handling in search engines to manage varying method signatures and improve robustness.

Signed-off-by: OEvortex <[email protected]>
Copilot AI review requested due to automatic review settings January 16, 2026 17:59
@OEvortex OEvortex merged commit c6bde57 into main Jan 16, 2026
2 checks passed
@OEvortex OEvortex deleted the feature/search branch January 16, 2026 18:01
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request introduces comprehensive Brave search engine support across multiple modalities (videos, news, images, suggestions) and adds a new BraveAI search provider. The implementation follows a consistent architecture pattern with a base class and specialized search engines for each content type, along with enhanced CLI formatting capabilities and server-side improvements.

Changes:

  • Added five new Brave search engines: BraveTextSearch, BraveVideos, BraveNews, BraveImages, and BraveSuggestions, each with HTML/API parsing capabilities
  • Introduced BraveAI provider for AI-powered search with streaming support
  • Enhanced CLI with specialized formatting functions for videos, news, suggestions, and images
  • Updated server routes with improved suggestions parameter handling

Reviewed changes

Copilot reviewed 38 out of 38 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
webscout/search/engines/brave/base.py New base class for all Brave search implementations with session management
webscout/search/engines/brave/videos.py Complete video search implementation with view count parsing and metadata extraction
webscout/search/engines/brave/news.py News search with date detection and thumbnail handling
webscout/search/engines/brave/suggestions.py Autocomplete API with rich entity support
webscout/search/engines/brave/images.py Image search with base64 URL extraction
webscout/search/engines/brave/text.py Text search with fallback retry logic
webscout/Provider/AISEARCH/brave_search.py New AI search provider with async support
webscout/cli.py Added specialized print functions and formatting utilities
webscout/server/routes.py Improved suggestions endpoint parameter handling
tests/providers/test_brave_images.py Comprehensive unit and integration tests
tests/providers/test_brave_text.py Text search parsing tests
Multiple files Removed # type: ignore comments (type checking cleanup)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


Uses server-rendered HTML and parses result containers with CSS selectors.
"""
from typing import cast
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cast import is imported but never used in this method. This import should be removed or moved to the top of the file if it's needed elsewhere.

Copilot uses AI. Check for mistakes.
self.country = country
self.ui_lang = ui_lang
self.geoloc = geoloc
self.last_response = {}
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The last_response attribute is initialized as an empty dict but later assigned SearchResponse objects (line 248, 279). This inconsistent typing could cause issues. Consider initializing as self.last_response: Optional[SearchResponse] = None or self.last_response: Union[SearchResponse, Dict] = SearchResponse("") for type consistency.

Suggested change
self.last_response = {}
self.last_response: Optional[SearchResponse] = None

Copilot uses AI. Check for mistakes.
Comment on lines +549 to +554
# Suggestions method might have different signature
try:
results = method(q, region=region, max_results=max_results)
except TypeError:
# Fallback for engines that don't accept region
results = method(q, max_results=max_results)
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bare except TypeError catches any TypeError, not just parameter-related ones. This could mask other TypeErrors from within the method call. Consider catching more specific exceptions or logging the error details to distinguish between parameter signature mismatches and other issues.

Copilot uses AI. Check for mistakes.
Comment on lines +272 to +281
first_item = data[0]

# Handle dataclass objects by converting to dict
if hasattr(first_item, "__dataclass_fields__"):
# Convert dataclass to dict for each item
data = [
{k: getattr(item, k, "") for k in first_item.__dataclass_fields__}
for item in data
]
first_item = data[0]
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dataclass-to-dict conversion uses getattr(item, k, "") which defaults to an empty string for missing fields. This could hide actual missing attributes. Consider using getattr(item, k) without a default, or use dataclasses.asdict() for more robust conversion that will raise AttributeError for truly missing fields.

Copilot uses AI. Check for mistakes.
Comment on lines +289 to +298
if __name__ == "__main__":
ai = BraveAI()
res = ai.search("What is Python?", stream=True, enable_research=True)
from collections.abc import Iterable

if isinstance(res, Iterable):
for chunk in res:
print(chunk, end="", flush=True)
else:
print(res)
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import from collections.abc import Iterable is placed inside the if __name__ == "__main__" block after usage. While this works, it's unconventional. Move the import to the top of the block (line 290) for better readability: from collections.abc import Iterable before creating the ai instance.

Copilot uses AI. Check for mistakes.
from __future__ import annotations

from time import sleep
from typing import List, Optional
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Import of 'Optional' is not used.

Copilot uses AI. Check for mistakes.
Comment on lines +128 to +133
except (ValueError, IndexError):
pass
if "--height:" in style:
try:
height = int(style.split("--height:")[1].split(";")[0].strip())
except (ValueError, IndexError):
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'except' clause does nothing but pass and there is no explanatory comment.

Suggested change
except (ValueError, IndexError):
pass
if "--height:" in style:
try:
height = int(style.split("--height:")[1].split(";")[0].strip())
except (ValueError, IndexError):
except (ValueError, IndexError):
# Ignore malformed or missing width value; default width=0 is acceptable.
pass
if "--height:" in style:
try:
height = int(style.split("--height:")[1].split(";")[0].strip())
except (ValueError, IndexError):
# Ignore malformed or missing height value; default height=0 is acceptable.

Copilot uses AI. Check for mistakes.
if "--height:" in style:
try:
height = int(style.split("--height:")[1].split(";")[0].strip())
except (ValueError, IndexError):
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'except' clause does nothing but pass and there is no explanatory comment.

Copilot uses AI. Check for mistakes.
decoded = base64.b64decode(normalized).decode("utf-8", errors="ignore")
if decoded.startswith("http"):
return decoded
except Exception:
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'except' clause does nothing but pass and there is no explanatory comment.

Copilot uses AI. Check for mistakes.
sib = fn("div", class_="snippet")
if sib:
candidates.append(sib.select_one(".generic-snippet"))
except Exception:
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'except' clause does nothing but pass and there is no explanatory comment.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant