Implement WebSearch and WebOpen with Playwright and DDGS integration#15
Implement WebSearch and WebOpen with Playwright and DDGS integration#15
Conversation
morisil
left a comment
There was a problem hiding this comment.
I left my initial comments, there is much more, but I think we should start by drafting the architecture together first. Let's have a meeting focused on that, and then we can proceed with the implementation.
e62486d to
7111ead
Compare
|
Change 1: New SearchProvider Interface New file: interface SearchProvider {
suspend fun search(
query: String,
page: Int = 1,
pageSize: Int = 10,
region: String = "us-en",
safeSearch: String = "moderate",
timeLimit: String? = null
): String
}Original Web interface combined two distinct responsibilities:
By enforcing interface segregation:
Change 2: renamed What changed: Before: suspend fun open(url: String): StringAfter: val MarkdownContentType = ContentType("text", "markdown")
suspend fun fetch(url: String, accept: ContentType = MarkdownContentType): StringRemoved from Web interface: suspend fun openInSession(sessionId: String, url: String): String
suspend fun closeSession(sessionId: String)
Change 3: search provider map injection Before: override suspend fun search(..., provider: String?, ...): String {
return when (provider) {
"anthropic" -> throw UnsupportedOperationException(...)
"ddgs", null -> searchWithDdgs(...)
else -> throw IllegalArgumentException(...)
}
}After: class DefaultWeb(
private val searchProviders: Map<String?, SearchProvider>,
private val httpClient: HttpClient,
...
) : Web {
override suspend fun search(..., provider: String?, ...): String =
searchProviders[provider]?.search(...)
?: throw IllegalArgumentException("Unknown search provider: $provider")
}By removing hardcoded web search provider logic, we remove the need to modify Change 4: new New class DdgsSearchProvider(
httpClient: HttpClient,
ddgsServiceUrl: String = "http://localhost:8001"
) : SearchProvider {
override suspend fun search(...): String { ... }
}Before: After: Golem is supposed to have a modular architecture, allowing for easy composition of custom Golem distributions tailored to specific needs of specific clients. DDGS-specific code now lives in its own module with its own dependencies, projects that don't need DDGS can exclude this module entirely, DDGS integration tests can run in isolation, module clearly encapsulates everything DDGS-related. Change 5: New file: class AnthropicSearchProvider : SearchProvider {
override suspend fun search(...): String {
TODO("Not yet implemented")
}
}Why this is needed: Anthropic-specific code belongs in the Anthropic cognizer module, since this module already depends on Other minor changes:
|
Pull Request Review: Web Search and Web Browsing IntegrationSummaryThis is a well-structured PR that adds comprehensive web search and browsing capabilities to Golem XIV. The implementation demonstrates good architectural decisions, thorough testing, and attention to operational concerns. 🟢 StrengthsArchitecture & Design
Code Quality
Documentation
🟡 Areas for ImprovementSecurity Concerns
|
Ad security concernsAd 1. Missing URL validation in
|

This PR adds new web searching and improved web browsing capabilities for Golem:
Web searching
Minimal Python/FastAPI wrapper for DDGS (Dux Distributed Global Search) metasearch library
Endpoints:
GET /health- health checkGET /search- web search with full parameter controlGradle tasks:
./gradlew createVenv- create Python venv./gradlew installDdgsDeps- install Python dependencies./gradlew runDdgsSearch- start the service onlocalhost:8001, invokescreateVenvandinstallDdgsDeps, if the user didn't runcreateVenvandinstallDdgsDepsfirstWeb browsing
--chromium-pathCLI optionDefaultWebBrowseris created if Playwright succeedsDefaultWebwith optional browser intoGolemScriptDependencyProviderHTML to markdown conversion:
keepPagesOpen=false: default, fresh page per request, closed after usekeepPagesOpen=true: reuses page for debugging with--show-browserWebInterfaceWebBrowserInterfaceCLI options:
--show-browser: run chromium in non-headless mode (window visible)--chromium-path=/path/to/chromium: use chromium installed in non-standard pathUsage in GolemScript
Tests
Unit tests (mocked)
DefaultWebTest.kt:open()with Playwright success/failure scenariosopen()fallback to jina.aiopenInSession()behaviorsearch()with DDGS serviceDefaultWebBrowserTest.kt:Integration tests
DefaultWebIntegrationTest.kt:DefaultWebBrowserIntegrationTest.kt:Integration tests are tagged with
@Tag("integration")and skip gracefully when required services are unavailableDependencies
Pythond dependencies
JVM dependencies
How to run it
Open 4 terminals
Terminal #1 - start Neo4j
Terminal #2 - start DDGS service
Terminal #3 - start Golem
export ANTHROPIC_API_KEY=your_key ./gradlew runOptionally, if you want to see the web browser used by Playwright:
If you want to specify chromium binary located in non-standard path:
Terminal #4 - web UI
Running tests
More
I would like to take it further and let Golem see the web by making screenshots and allowing it to click on elements and to login in to websites, fill the forms etc. I am wondering about extending/improving markanywhere, to use it as HTML to markown converter, but I am not sure about that yet.