feat: add browser MapLibre agent factory and WebSocket runtime#83
Merged
Conversation
Adds a `for_browser_maplibre` factory, browser-bound MapLibre tools, and a FastAPI WebSocket backend (`geoagent browser`) so a GeoAgent can drive a live MapLibre map embedded in a browser web app.
|
🚀 Deployed on https://6a009e46af93bae36ba2d9f5--opengeos.netlify.app |
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new “browser MapLibre” integration path so GeoAgent can control a live MapLibre map in a browser via a FastAPI WebSocket backend, and exposes this via a new geoagent browser CLI command.
Changes:
- Introduces
for_browser_maplibrefactory and MapLibre browser tool surface (browser_maplibre_tools). - Adds a browser runtime bridge (
BrowserMapSession) plus a FastAPI/uvicorn WebSocket server (geoagent browser). - Adds the
GeoAgent[browser]optional dependency group and new tests for the factory/tool surface.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_geoagent_factory.py | Adds coverage that the new factory registers expected tools + metadata. |
| tests/test_browser_maplibre_tools.py | Adds tool surface/payload/confirmation-gating tests for browser MapLibre tools. |
| pyproject.toml | Adds browser extra (FastAPI + uvicorn) and includes it in all. |
| geoagent/tools/browser_maplibre.py | Implements MapLibre browser tool wrappers calling into a session broker. |
| geoagent/core/factory.py | Adds for_browser_maplibre factory and its system prompt. |
| geoagent/cli.py | Adds geoagent browser CLI subcommand wiring to the server runner. |
| geoagent/browser/session.py | Implements synchronous-to-async WebSocket command broker for tools. |
| geoagent/browser/server.py | Implements FastAPI WebSocket backend to run chat turns and bridge map commands/results. |
| geoagent/browser/init.py | Exposes browser runtime helpers via package exports. |
| geoagent/init.py | Exports for_browser_maplibre at the top-level package API. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- session.py: pick the per-call timeout via explicit ``None`` check so callers can pass ``0.0`` (or any falsy float) to force an immediate timeout instead of silently inheriting ``self.timeout_seconds``. - server.py: accept an optional ``history`` payload on incoming chat messages and route it through ``build_prompt_with_context`` so multi-turn follow-ups have the same recent-transcript context the Solara UI and QGIS chat dock already provide. - server.py: drop the ``active_chat.cancel()`` call on disconnect/error. The chat work runs inside ``asyncio.to_thread``, so cancelling the wrapping task does not actually stop the worker; let the task finish quietly and just clear the local reference instead. - tests: add ``tests/test_browser_session.py`` covering the concurrency behaviors of ``BrowserMapSession`` (timeout raises ``BrowserMapTimeoutError``, ``resolve_result`` unblocks pending callers, ``fail_all`` releases every waiter, and an explicit ``timeout_seconds=0.0`` does not fall back to the default).
- Implemented a new TypeScript example for a browser-based map using MapLibre GL. - Created a WebSocket connection to handle chat interactions and map commands. - Added styles for the map interface and chat panel. - Introduced TypeScript configuration for strict type checking. - Enhanced the Python server to support streaming chat responses and tool execution. - Updated CLI to set a default model provider. - Added tests for WebSocket connection and chat streaming functionality.
- Added support for executing arbitrary JavaScript code in the browser using the `run_maplibre_script` tool. - Updated README with prompt examples for new features including map navigation and layer management. - Introduced `maplibre-gl-layer-control` for improved layer management in the MapLibre interface. - Enhanced the main TypeScript file to include layer control and GeoAgent UI elements. - Implemented new functions for handling GeoJSON overlays and layer definitions. - Updated server and CLI to support new flags for allowing browser code execution and auto-approving browser tools. - Added tests to ensure the new JavaScript execution feature is opt-in and confirmation gated.
- session.py: treat ``timeout_seconds`` as a total deadline shared between the send and response phases of ``BrowserMapSession.call``. Previously ``future.result(timeout=wait_timeout)`` and ``event.wait(wait_timeout)`` each consumed the full budget, so a slow send could let the overall call block for up to ``2 * wait_timeout``. Now the response wait uses the remaining time until ``deadline`` so a caller-provided timeout means a single, total deadline. - tests: add ``test_call_timeout_is_total_deadline`` to lock in the shared budget behavior and prevent regressions back to per-phase doubling.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
for_browser_maplibrefactory that binds a GeoAgent to a live MapLibre map running in a browser session, registering safe browser map tools.geoagent browser, plus aBrowserMapSessionbroker that bridges synchronous Strands tools to the async browser channel.GeoAgent[browser]and add tests for the factory and browser tools.Test plan
pytest tests/test_browser_maplibre_tools.py tests/test_geoagent_factory.py -qpre-commit run --all-filesgeoagent browserand connect a MapLibre client over WebSocket