dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
A WebGIS plugin that lets LLMs truly see the geographic world. Built on DeepSeek Harness (DSH), it embeds a full GIS workbench into an AI conversation: models can load map data, understand maps, and run spatial analysis through dialogue. Its long-term goal is genuine 3D spatial understanding.
Author: Frank Wang · Feedback: cywanghn@gmail.com
0.2.1 (built and tested against 0.2.1-rc.2). This release is not compatible with earlier harness versions. If you are on an older DSH, upgrade the harness before updating this plugin.webServer service. The official Desktop transport is not yet supported.npx --yes @deepseek-ai/dsh plugin --profile web add dsh-webgisapprove-builds step: DuckDB ships as the official Node Neo package (@duckdb/node-api) with a platform-specific prebuilt binding through optional dependencies. A normal pnpm install is sufficient. The platform still has to be one DuckDB Node Neo supports, and packages must be fetchable from the npm registry.Retargeted at DSH 0.2.1-rc.2. All harness APIs this plugin uses are unchanged (slot registry, shell.overlay / settings.plugins.tab / conversation.session.header.actions, ctx.tools.*, ctx.slots.*, webServer.register, session-list lookup); only dependency ranges moved. @deepseek-ai/dsh-invariants was dropped — it was never used by this plugin and has no 0.2.1 release.
conversation.session.header.actions (the title / view / export / collapse row).dialog / menu layers, hides itself while they are open, and the overlay layer is lowered below host chrome.webgis_move_layer tool moves a layer up / down / top / bottom from dialogue. Order is persisted in the session layer registry and re-applied after every rebuild.webgis_set_layer_thematic now supports user-defined numeric intervals (method: "manual" with breaks + colors), e.g. breaks: [0, 100, 500, 1000] → five classes.allCategories: true confirms full colouring.This release retargets the plugin at DSH 0.2.0. No source changes were needed — every harness API this plugin depends on is unchanged from 0.1.7: the slot registry and its dispatch, the shell.overlay and settings.plugins.tab slots, the client module-loader protocol that lazy chunks use, the host DOM the GIS layout measures, and the session-list lookup behind the 0.1.5 fix below.
The upgrade was verified by installing both harness versions side by side and diffing their type declarations and client bundles file by file, then confirming typecheck, build, and the full test suite against 0.2.0.
@deepseek-ai/cordis is now ^4.0.4, matching the peer range the 0.2.0 packages declare. (The previous ^4.0.1 allowed the 4.0.2 we had pinned, so npm never raised it.)Three harness APIs changed in 0.1.7; all three are adapted here.
SessionListState.current. On 0.1.7 the previous lookup silently returned nothing, so the browser half could not tell the host which conversation it was in. The two sides then wrote to different state buckets, and every tool that waits for the browser to answer — webgis_get_pick, webgis_export_basemap, webgis_export_map — timed out, while the map itself kept rendering, picking and navigating normally. Resolved through the harness's own retainedBy.mainView rule.settings.plugin.item slot was removed — that page is now a read-only inventory of the plugins a deployment ships. The WebGIS card is registered as a tab through settings.plugins.tab instead.'plugin' message-source kind was removed from the harness vocabulary; the plugin now declares its own kind, which is how the harness documents producers extending that union.Behaviour note: now that the browser half resolves a real session id, the GIS / traditional mode choice is stored per conversation again — it had been collapsing into a single shared slot. Each conversation is selected once.
webgis_load_dataset, covering GeoJSON, CSV, shapefile (.zip / .shp) and GDAL-readable vectors (.gdb / .gpkg / .kml / .tab / .mif / .dgn). CSV options: lonField, latField, geometryColumn, sourceCrs, filter, limit; local *.csv wildcards and SSRF-protected remote CSV downloads are supported.filter defines the layer's real subset — rendering and later analysis both follow it. limit caps displayed rows without discarding data: small files take the first N rows in source order (repeatable), large files sample N at random. Above 100k rows the map renders the complete data by zoom level, and the tool message says so rather than claiming to show N rows.| Previous call | Replacement |
|---|---|
webgis_load_csv({path, ...}) | webgis_load_dataset({url, ...}) |
webgis_set_layer_color({layer, color}) | webgis_set_layer_style({layer, color}) |
webgis_set_attribute({...}) | webgis_edit_field({action: "set", ...}) |
webgis_add_column({...}) | webgis_edit_field({action: "add", ...}) |
webgis_add_sequence({...}) | webgis_edit_field({action: "sequence", ...}) |
The previous names are no longer registered. webgis_feature_summary returns one requested field statistic; webgis_layer_stats returns a count/distribution overview — both over the complete layer, independent of the display sample. Geometry-dependent operations still need the DuckDB spatial extension on the full-table path.
Scope: small workloads still execute synchronously on the host thread. Workload thresholds do not guarantee that every complex geometry runs off-thread; this release does not promise universally non-blocking execution. Worker payload encoding and result decoding also require host-thread work.
Compatibility: this release targets the DSH Web profile and requires the host's webServer service. The official Desktop transport is not yet supported. That release's DSH 0.1.5-rc1 baseline was superseded in 0.1.5 — see Compatibility.
@duckdb/node-api). Installing the plugin no longer requires compiling the legacy duckdb native module, pnpm approve-builds, or pnpm rebuild duckdb.{ lon, lat } JavaScript objects.0.1.5-rc1: retargeted the new shell layout (the conversation moved into the host main slot) and migrated to the 0.1.5 package set.The plugin uses DuckDB's official Node Neo package (@duckdb/node-api). It installs a platform-specific prebuilt binding through optional dependencies, so pnpm ≥ 10 does not need pnpm approve-builds or pnpm rebuild duckdb. A normal pnpm install is sufficient. The target platform must still be supported by DuckDB Node Neo and be able to download packages from the npm registry.
Once data is loaded, tell the AI something like “show this as a hex density heatmap” or “which points fall inside this polygon?”. 56 tools can be chained behind the scenes:
manual + breaks/colors), or one colour per category. Fields with >50 distinct values ask for confirmation before colouringwebgis_move_layer), inspect layer details, and view feature statisticsEvery result becomes a new live layer that the next tool can continue to process, forming a complete analysis chain.
Indices ask before computing. Statistical tools follow an inspect → confirm → compute loop: a Moran's I request first reports numeric fields, missing-value counts, and the geometry family, then waits for confirmation. If a required parameter is missing, the tool explains what it needs instead of guessing.
Vector basemaps contain real feature data: waterways, roads, buildings, parks, land use, boundaries, points of interest, and place names. The plugin can extract features from tiles in the current view into normal layers:
- “Export the map data in the current view” → three layers: points / lines / polygons
- “Export the rivers in this view” → one layer, with same-named segments merged into one feature
The extracted layers behave like any imported data: measure, buffer, and analyse them. This turns visible map content into layers; it is not bulk extraction. Vector tiles are cut by zoom level, so farther zoom levels expose fewer layers, and POIs/buildings generally appear only at city or street zoom. For bulk data, use Geofabrik or Overpass and import a file.
.shp / .zip), CSV, or GeoJSON; CSV automatically detects a WKT geometry column and otherwise tries longitude/latitude columns{bbox-epsg-3857} templateFrom hundreds of rows to millions, the UI should remain responsive. The core idea is “count first, render in tiers, materialize on demand”, rather than pushing everything to the browser at once.
Huge local CSV files (DuckDB):
PostGIS databases:
count is issued first to decide whether and how to load resultsST_Transform; EWKB geometries are converted to GeoJSON for displaystatement_timeout and read-only transactions prevent slow or misdirected queries from blocking the conversationSampling is always transparent: when a large layer displays only a sample, it is labelled “N rows total (sampled)”, and statistics derived from the sample are flagged as such. The AI should never mistake a sample for the full dataset.
Combined with deck.gl's GPU-driven 3D rendering — hex columns, wall extrusions, and OD arcs — hundreds of thousands of rows remain smooth to zoom, filter, and analyse.
Requirements: DSH 0.2.1 with the web profile, plus pnpm on your PATH. (0.2.1 is not compatible with earlier harness versions — see Compatibility.)
dsh plugin --profile web add dsh-webgis
# After installation restart with: dsh web
# Then start a new conversation and select GIS mode.
Optional configuration (Settings → Plugins → the WebGIS tab, or the plugin configuration file cordis.patch.yml):
- “Load this
xxx.shponto the map”- “Are these points spatially clustered? Show them as a hex heatmap”
- “Filter the points from
dataset Athat fall insideregion B”- “Export the map data in the current view”
- “Is the population of these counties clustered, or random?” (runs Moran's I)
- “Where is this place?” (the AI captures a screenshot and analyses it)
Long-term vision: not merely describing a picture, but giving the model spatial cognition that understands the 3D world behind the map.
Note: DeepSeek vision models are still evolving quickly, and vision-related features have not yet received extensive deep testing.