Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ public/
modules/arrow-layers/
modules/basemap-props/
*.json
*.txt
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ public/
.cache/
modules/arrow-layers/
modules/basemap-props/
*.txt
94 changes: 94 additions & 0 deletions modules/ai-skills/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# @deck.gl-community/ai-skills

AI agent helpers for building deck.gl visualizations. Supports two complementary patterns:

**Pattern A — Native TypeScript** (recommended for LLM code generation)
Typed factory functions that return correct props with sensible defaults, backed by full TypeScript types. LLMs write native code; `llms.txt` provides the reference.

**Pattern B — JSON descriptors** (for serializable configs and low-code UIs)
Fully JSON-serializable layer descriptors with dot-path accessors, pre-flight validation, and a hydration step that converts them to runtime functions. Safe to store, transmit, or emit from an LLM to a server.

## Installation

```bash
npm install @deck.gl-community/ai-skills
# peer deps
npm install @deck.gl/core @deck.gl/layers
```

## Quick start

See [`llms.txt`](./llms.txt) for the complete agent-facing reference with worked examples for both patterns.

### Pattern A — factory functions

```ts
import {ScatterplotLayer} from '@deck.gl/layers';
import {scatterplotLayer, fitViewport} from '@deck.gl-community/ai-skills';

const layer = new ScatterplotLayer(
scatterplotLayer({
data: cities,
getPosition: (d) => d.coordinates,
getRadius: (d) => d.population,
getFillColor: [255, 140, 0],
radiusScale: 0.00003
})
);
const viewState = fitViewport(cities.map((c) => c.coordinates));
```

### Pattern B — JSON descriptors

```ts
import {
createDescriptor,
validateDescriptor,
hydrateDescriptor
} from '@deck.gl-community/ai-skills';
import {ScatterplotLayer} from '@deck.gl/layers';

const desc = createDescriptor('ScatterplotLayer', {
data: cities,
getPosition: 'coordinates', // dot-path string, resolved at hydration
getFillColor: [255, 140, 0]
});
const {valid, errors} = validateDescriptor(desc);
const layer = new ScatterplotLayer(hydrateDescriptor(desc));
```

## API

| Export | Description |
| ------------------------------------------ | ---------------------------------------------------------------- |
| `scatterplotLayer(options)` | Factory for ScatterplotLayer props |
| `pathLayer(options)` | Factory for PathLayer props |
| `polygonLayer(options)` | Factory for PolygonLayer props |
| `textLayer(options)` | Factory for TextLayer props |
| `arcLayer(options)` | Factory for ArcLayer props |
| `heatmapLayer(options)` | Factory for HeatmapLayer props |
| `createDescriptor(type, props, id?)` | Build a JSON-serializable layer descriptor |
| `validateDescriptor(desc)` | Pre-flight validation returning `{valid, errors}` |
| `hydrateDescriptor(desc)` | Resolve dot-path accessors to runtime functions |
| `DeckBuilder` | Fluent builder composing layers + view state into a `DeckConfig` |
| `fitViewport(positions, w?, h?, padding?)` | Fit Web Mercator viewport to a set of coordinates |
| `getBoundingBox(positions)` | Get `[minLng, minLat, maxLng, maxLat]` |
| `createViewState(lng, lat, zoom, opts?)` | Convenience view state constructor |

## For AI agents

This module ships `llms.txt` at its package root — a single clean reference file covering both patterns, all layer types, and a decision guide. Point your agent at it:

```
https://unpkg.com/@deck.gl-community/ai-skills/llms.txt
```

Or read it locally after install:

```
node_modules/@deck.gl-community/ai-skills/llms.txt
```

## License

MIT © vis.gl contributors
215 changes: 215 additions & 0 deletions modules/ai-skills/llms.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
# @deck.gl-community/ai-skills

AI agent reference for deck.gl visualizations.

This module supports two patterns. Pick the one that fits your context.

---

## Pattern A — Native TypeScript (recommended for code generation)

Write TypeScript directly. Use the typed factory functions to get correct props
with sensible defaults, then pass them to standard deck.gl layer constructors.

**Install:**
```
npm install @deck.gl/core @deck.gl/layers @deck.gl-community/ai-skills
```

**Basic map with scatterplot:**
```ts
import {Deck} from '@deck.gl/core';
import {ScatterplotLayer} from '@deck.gl/layers';
import {scatterplotLayer, fitViewport} from '@deck.gl-community/ai-skills';

const cities = [
{name: 'New York', coordinates: [-74.006, 40.7128], population: 8_300_000},
{name: 'Los Angeles', coordinates: [-118.2437, 34.0522], population: 3_900_000},
{name: 'Chicago', coordinates: [-87.6298, 41.8781], population: 2_700_000}
];

const layer = new ScatterplotLayer(
scatterplotLayer({
data: cities,
getPosition: d => d.coordinates,
getRadius: d => d.population,
getFillColor: [255, 140, 0],
radiusScale: 0.00003,
id: 'cities'
})
);

const viewState = fitViewport(cities.map(c => c.coordinates));

new Deck({initialViewState: viewState, layers: [layer], ...});
```

**Arc layer (origin→destination flows):**
```ts
import {ArcLayer} from '@deck.gl/layers';
import {arcLayer} from '@deck.gl-community/ai-skills';

const flights = [{source: [-74, 40.7], target: [-118.2, 34.1], value: 1200}];

const layer = new ArcLayer(
arcLayer({
data: flights,
getSourcePosition: d => d.source,
getTargetPosition: d => d.target,
getSourceColor: [0, 128, 200],
getTargetColor: [200, 0, 80],
getWidth: d => Math.sqrt(d.value)
})
);
```

**Heatmap:**
```ts
import {HeatmapLayer} from '@deck.gl/aggregation-layers';
import {heatmapLayer} from '@deck.gl-community/ai-skills';

const layer = new HeatmapLayer(
heatmapLayer({
data: events,
getPosition: d => [d.lng, d.lat],
getWeight: d => d.intensity,
radiusPixels: 40
})
);
```

---

## Pattern B — JSON descriptors (for serializable configs / low-code UI)

Produce pure JSON that is safe to store, transmit, or emit from an LLM to a
server. Accessor props are dot-path strings resolved at hydration time.

**Produce a descriptor:**
```ts
import {createDescriptor, validateDescriptor, hydrateDescriptor} from '@deck.gl-community/ai-skills';
import {ScatterplotLayer} from '@deck.gl/layers';

// Agent or UI emits this as plain JSON — no callbacks, no runtime execution
const desc = createDescriptor('ScatterplotLayer', {
data: cities,
getPosition: 'coordinates', // resolved to d => d.coordinates
getRadius: 'population', // resolved to d => d.population
getFillColor: [255, 140, 0],
radiusScale: 0.00003
});

// Validate before use
const {valid, errors} = validateDescriptor(desc);
if (!valid) throw new Error(errors.join(', '));

// Hydrate and render
const layer = new ScatterplotLayer(hydrateDescriptor(desc));
```

**Compose with DeckBuilder:**
```ts
import {DeckBuilder, createDescriptor, fitViewport} from '@deck.gl-community/ai-skills';

const config = new DeckBuilder()
.addLayer(createDescriptor('ScatterplotLayer', {
data: cities,
getPosition: 'coordinates',
getFillColor: [255, 140, 0]
}))
.addLayer(createDescriptor('TextLayer', {
data: cities,
getPosition: 'coordinates',
getText: 'name',
getSize: 14
}))
.setViewState(fitViewport(cities.map(c => c.coordinates)))
.setMapStyle('https://basemaps.cartocdn.com/gl/positron-gl-style/style.json')
.build();
// config is a plain JSON object — safe to store/transmit
```

---

## Layer reference

All layers accept `id` (string), `data` (array or URL), `pickable` (boolean),
`opacity` (0–1). Accessor props (prefixed with `get`) accept functions or, in
descriptor mode, dot-path strings.

### ScatterplotLayer
Required: `data`, `getPosition`
Key props: `getRadius`, `getFillColor`, `radiusScale`, `radiusUnits` ('meters'|'pixels'), `stroked`, `getLineColor`, `getLineWidth`

### PathLayer
Required: `data`, `getPath`
Key props: `getColor`, `getWidth`, `widthUnits` ('meters'|'pixels')

### PolygonLayer
Required: `data`, `getPolygon`
Key props: `getFillColor`, `getLineColor`, `extruded`, `getElevation`

### TextLayer
Required: `data`, `getText`, `getPosition`
Key props: `getColor`, `getSize`, `sizeUnits`, `getTextAnchor`, `getAlignmentBaseline`

### ArcLayer
Required: `data`, `getSourcePosition`, `getTargetPosition`
Key props: `getSourceColor`, `getTargetColor`, `getWidth`

### HeatmapLayer
Required: `data`, `getPosition`
Key props: `getWeight`, `radiusPixels`, `intensity`, `threshold`, `colorRange`

### GeoJsonLayer
Required: `data` (GeoJSON FeatureCollection or URL)
Key props: `getFillColor`, `getLineColor`, `getLineWidth`, `extruded`, `getElevation`

---

## Viewport helpers

```ts
import {fitViewport, getBoundingBox, createViewState} from '@deck.gl-community/ai-skills';

// Fit viewport to a set of [lng, lat] positions
const vs = fitViewport(positions); // auto zoom
const vs = fitViewport(positions, 1280, 720, 0.05); // custom viewport + padding

// Just bounding box: [minLng, minLat, maxLng, maxLat]
const bbox = getBoundingBox(positions);

// Explicit view state
const vs = createViewState(-74.006, 40.7128, 12, {pitch: 45});
```

---

## Color conventions

Colors are `[R, G, B]` or `[R, G, B, A]` with values 0–255.

```ts
const red: ColorRGBA = [255, 0, 0];
const semiTransparentBlue: ColorRGBA = [0, 0, 255, 180];
```

---

## Decision guide

| Situation | Use |
|-----------|-----|
| LLM writing TypeScript code directly | Pattern A — factories + native constructors |
| LLM emitting config to a server/API | Pattern B — descriptors |
| Low-code drag-and-drop UI | Pattern B — descriptors |
| UNDO history / saved dashboards | Pattern B — descriptors |
| Need full deck.gl prop surface | Pattern A — factories are a starting point; add extra props directly |

---

## Further reading

- deck.gl layer catalog: https://deck.gl/docs/api-reference/layers
- deck.gl/json module (runtime JSON rendering): https://deck.gl/docs/api-reference/json/json-converter
- vis.gl community modules: https://github.com/visgl/deck.gl-community
46 changes: 46 additions & 0 deletions modules/ai-skills/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "@deck.gl-community/ai-skills",
"version": "9.2.8",
"description": "AI agent helpers for deck.gl — typed factories, JSON descriptors, and llms.txt reference docs",
"license": "MIT",
"_publishConfig": {
"access": "public"
},
"keywords": [
"webgl",
"visualization",
"deck.gl",
"ai",
"llm",
"agents"
],
"repository": {
"type": "git",
"url": "https://github.com/visgl/deck.gl-community.git"
},
"type": "module",
"sideEffects": false,
"types": "./dist/index.d.ts",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"exports": {
".": {
"types": "./dist/index.d.ts",
"require": "./dist/index.cjs",
"import": "./dist/index.js"
}
},
"files": [
"dist",
"src",
"llms.txt"
],
"scripts": {
"test": "vitest run",
"test-watch": "vitest"
},
"peerDependencies": {
"@deck.gl/core": "~9.2.0",
"@deck.gl/layers": "~9.2.0"
}
}
Loading