mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-10 22:32:16 +02:00
feat(capabilities): add web.discover schemas and provider seam
This commit is contained in:
parent
a413539f6a
commit
fa1055dd4c
6 changed files with 168 additions and 0 deletions
|
|
@ -0,0 +1,3 @@
|
|||
"""``web.discover`` verb: a query → candidate URLs the agent can feed to ``web.scrape``."""
|
||||
|
||||
from __future__ import annotations
|
||||
40
surfsense_backend/app/capabilities/web/discover/executor.py
Normal file
40
surfsense_backend/app/capabilities/web/discover/executor.py
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
"""``web.discover`` executor: route a query to the first configured search provider."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Sequence
|
||||
|
||||
from app.capabilities.types import Executor
|
||||
from app.capabilities.web.discover.providers.base import DiscoverProvider
|
||||
from app.capabilities.web.discover.schemas import DiscoverInput, DiscoverOutput
|
||||
|
||||
|
||||
class NoDiscoverProviderError(RuntimeError):
|
||||
"""Raised when no search provider is configured (no platform key/host set)."""
|
||||
|
||||
|
||||
def build_discover_executor(
|
||||
providers: Sequence[DiscoverProvider] | None = None,
|
||||
) -> Executor:
|
||||
"""Bind the executor to a provider set (defaults to the real env-keyed providers)."""
|
||||
registry = list(providers) if providers is not None else _default_providers()
|
||||
|
||||
async def execute(payload: DiscoverInput) -> DiscoverOutput:
|
||||
provider = next((p for p in registry if p.is_available()), None)
|
||||
if provider is None:
|
||||
raise NoDiscoverProviderError(
|
||||
"web.discover has no configured search provider "
|
||||
"(set a SearXNG host or a Linkup/Baidu key)."
|
||||
)
|
||||
hits = await provider.search(payload.query, payload.top_k)
|
||||
return DiscoverOutput(hits=hits)
|
||||
|
||||
return execute
|
||||
|
||||
|
||||
def _default_providers() -> list[DiscoverProvider]:
|
||||
from app.capabilities.web.discover.providers.baidu import BaiduProvider
|
||||
from app.capabilities.web.discover.providers.linkup import LinkupProvider
|
||||
from app.capabilities.web.discover.providers.searxng import SearxngProvider
|
||||
|
||||
return [SearxngProvider(), LinkupProvider(), BaiduProvider()]
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
"""``web.discover`` search providers (env-keyed: SearXNG, Linkup, Baidu)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
"""The seam every ``web.discover`` provider implements."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Protocol, runtime_checkable
|
||||
|
||||
from app.capabilities.web.discover.schemas import DiscoverHit
|
||||
|
||||
|
||||
@runtime_checkable
|
||||
class DiscoverProvider(Protocol):
|
||||
"""An env-keyed search backend that suggests candidate URLs for a query."""
|
||||
|
||||
name: str
|
||||
|
||||
def is_available(self) -> bool:
|
||||
"""True when this provider's platform key/host is configured."""
|
||||
...
|
||||
|
||||
async def search(self, query: str, top_k: int) -> list[DiscoverHit]:
|
||||
"""Return up to ``top_k`` candidate hits for ``query``."""
|
||||
...
|
||||
21
surfsense_backend/app/capabilities/web/discover/schemas.py
Normal file
21
surfsense_backend/app/capabilities/web/discover/schemas.py
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
"""``web.discover`` I/O contracts."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class DiscoverInput(BaseModel):
|
||||
query: str
|
||||
top_k: int = 10
|
||||
|
||||
|
||||
class DiscoverHit(BaseModel):
|
||||
url: str
|
||||
title: str
|
||||
snippet: str | None = None
|
||||
provider: str
|
||||
|
||||
|
||||
class DiscoverOutput(BaseModel):
|
||||
hits: list[DiscoverHit]
|
||||
Loading…
Add table
Add a link
Reference in a new issue