@arcgis/ai-agents 5.0.0 → 5.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1365 -1353
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,48 +1,48 @@
|
|
|
1
|
-
import { Annotation as g, messagesStateReducer as z, StateGraph as _, START as j, END as R, NodeInterrupt as
|
|
2
|
-
import { invokeToolPrompt as M, sendTraceMessage as
|
|
3
|
-
import { tool as
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import { addressToLocations as
|
|
9
|
-
import
|
|
10
|
-
import
|
|
1
|
+
import { Annotation as g, messagesStateReducer as z, StateGraph as _, START as j, END as R, NodeInterrupt as lt } from "@langchain/langgraph/web";
|
|
2
|
+
import { invokeToolPrompt as M, sendTraceMessage as m, invokeStructuredPrompt as ke, invokeTextPrompt as ie, sendUXSuggestion as L } from "@arcgis/ai-orchestrator";
|
|
3
|
+
import { tool as b } from "@langchain/core/tools";
|
|
4
|
+
import ct from "@arcgis/core/Graphic.js";
|
|
5
|
+
import le from "@arcgis/core/geometry/Point.js";
|
|
6
|
+
import Ne from "@arcgis/core/geometry/Extent.js";
|
|
7
|
+
import dt from "@arcgis/core/symbols/PictureMarkerSymbol.js";
|
|
8
|
+
import { addressToLocations as ut } from "@arcgis/core/rest/locator.js";
|
|
9
|
+
import O from "@arcgis/core/portal/Portal.js";
|
|
10
|
+
import ne from "@arcgis/core/config.js";
|
|
11
11
|
import s, { z as k } from "zod";
|
|
12
|
-
import { HumanMessage as
|
|
12
|
+
import { HumanMessage as ze, AIMessage as K } from "@langchain/core/messages";
|
|
13
13
|
import { ToolNode as P } from "@langchain/langgraph/prebuilt";
|
|
14
|
-
import
|
|
15
|
-
import
|
|
16
|
-
import * as
|
|
17
|
-
import
|
|
18
|
-
import
|
|
19
|
-
import
|
|
20
|
-
import
|
|
21
|
-
import * as
|
|
22
|
-
import
|
|
14
|
+
import _e from "@arcgis/core/layers/support/FeatureEffect.js";
|
|
15
|
+
import U from "@arcgis/core/layers/support/FeatureFilter.js";
|
|
16
|
+
import * as ce from "@arcgis/core/geometry/operators/unionOperator.js";
|
|
17
|
+
import de from "@arcgis/core/smartMapping/statistics/summaryStatistics.js";
|
|
18
|
+
import ue from "@arcgis/core/smartMapping/statistics/uniqueValues.js";
|
|
19
|
+
import je from "@arcgis/core/rest/support/TopFeaturesQuery.js";
|
|
20
|
+
import Me from "@arcgis/core/rest/support/TopFilter.js";
|
|
21
|
+
import * as ht from "@arcgis/core/geometry/operators/bufferOperator.js";
|
|
22
|
+
import mt from "@arcgis/core/rest/support/Query.js";
|
|
23
23
|
import { createRenderer as pt } from "@arcgis/core/smartMapping/renderers/pieChart.js";
|
|
24
|
-
import { getSchemesByTag as
|
|
25
|
-
import { getBackgroundColorTheme as
|
|
26
|
-
import { createAgeRenderer as
|
|
27
|
-
import { getSchemesByTag as
|
|
28
|
-
import { createContinuousRenderer as
|
|
29
|
-
import { createRenderer as
|
|
30
|
-
import { getSchemesByTag as
|
|
31
|
-
import { createRenderer as
|
|
32
|
-
import { getSchemesByTag as
|
|
33
|
-
import { createRenderer as
|
|
34
|
-
import { getSchemesByTag as
|
|
35
|
-
import { createRenderer as
|
|
36
|
-
import { getSchemesByTag as
|
|
37
|
-
import { createAgeRenderer as
|
|
38
|
-
import { createRenderer as
|
|
39
|
-
import { getSchemesByTag as
|
|
40
|
-
import
|
|
41
|
-
import
|
|
42
|
-
import
|
|
43
|
-
import { executeQueryStreaming as
|
|
44
|
-
import
|
|
45
|
-
const
|
|
24
|
+
import { getSchemesByTag as yt, getSchemes as ft } from "@arcgis/core/smartMapping/symbology/pieChart.js";
|
|
25
|
+
import { getBackgroundColorTheme as xe } from "@arcgis/core/views/support/colorUtils.js";
|
|
26
|
+
import { createAgeRenderer as gt, createContinuousRenderer as wt } from "@arcgis/core/smartMapping/renderers/color.js";
|
|
27
|
+
import { getSchemesByTag as he } from "@arcgis/core/smartMapping/symbology/color.js";
|
|
28
|
+
import { createContinuousRenderer as bt } from "@arcgis/core/smartMapping/renderers/univariateColorSize.js";
|
|
29
|
+
import { createRenderer as St } from "@arcgis/core/smartMapping/renderers/dotDensity.js";
|
|
30
|
+
import { getSchemesByTag as vt } from "@arcgis/core/smartMapping/symbology/dotDensity.js";
|
|
31
|
+
import { createRenderer as Tt } from "@arcgis/core/smartMapping/renderers/heatmap.js";
|
|
32
|
+
import { getSchemesByTag as xt } from "@arcgis/core/smartMapping/symbology/heatmap.js";
|
|
33
|
+
import { createRenderer as Et } from "@arcgis/core/smartMapping/renderers/predominance.js";
|
|
34
|
+
import { getSchemesByTag as $t } from "@arcgis/core/smartMapping/symbology/predominance.js";
|
|
35
|
+
import { createRenderer as Ft } from "@arcgis/core/smartMapping/renderers/relationship.js";
|
|
36
|
+
import { getSchemesByTag as Rt } from "@arcgis/core/smartMapping/symbology/relationship.js";
|
|
37
|
+
import { createAgeRenderer as Lt, createContinuousRenderer as It } from "@arcgis/core/smartMapping/renderers/size.js";
|
|
38
|
+
import { createRenderer as qt } from "@arcgis/core/smartMapping/renderers/type.js";
|
|
39
|
+
import { getSchemesByTag as Ct } from "@arcgis/core/smartMapping/symbology/type.js";
|
|
40
|
+
import Pe from "@arcgis/core/rest/knowledgeGraph/GraphQueryStreaming.js";
|
|
41
|
+
import Ee from "@arcgis/core/request.js";
|
|
42
|
+
import $e from "@arcgis/core/identity/IdentityManager.js";
|
|
43
|
+
import { executeQueryStreaming as At } from "@arcgis/core/rest/knowledgeGraphService.js";
|
|
44
|
+
import kt from "@arcgis/core/WebLinkChart.js";
|
|
45
|
+
const De = g.Root({
|
|
46
46
|
// messages: comes from global chat history.
|
|
47
47
|
// It is safe to append new messages locally, but existing message objects
|
|
48
48
|
// must be treated as read-only and never mutated.
|
|
@@ -55,88 +55,88 @@ const Pe = g.Root({
|
|
|
55
55
|
// This avoids duplicate output when tool nodes and final LLM nodes
|
|
56
56
|
// emit the same text during a single agent turn.
|
|
57
57
|
outputMessage: g({
|
|
58
|
-
reducer: (e = "",
|
|
59
|
-
const
|
|
60
|
-
if (!
|
|
58
|
+
reducer: (e = "", t) => {
|
|
59
|
+
const r = typeof t == "string" ? t.trim() : "";
|
|
60
|
+
if (!r)
|
|
61
61
|
return e;
|
|
62
62
|
const a = e.trim();
|
|
63
63
|
if (!a)
|
|
64
|
-
return
|
|
65
|
-
if (a ===
|
|
64
|
+
return r;
|
|
65
|
+
if (a === r)
|
|
66
66
|
return e;
|
|
67
67
|
const o = a.split(`
|
|
68
68
|
|
|
69
69
|
`);
|
|
70
|
-
return o[o.length - 1]?.trim() ===
|
|
70
|
+
return o[o.length - 1]?.trim() === r ? e : `${e}
|
|
71
71
|
|
|
72
|
-
${
|
|
72
|
+
${r}`;
|
|
73
73
|
},
|
|
74
74
|
default: () => ""
|
|
75
75
|
}),
|
|
76
76
|
intent: g({
|
|
77
|
-
reducer: (e,
|
|
77
|
+
reducer: (e, t) => t
|
|
78
78
|
}),
|
|
79
79
|
vectorSearchLayerResults: g({
|
|
80
|
-
reducer: (e,
|
|
80
|
+
reducer: (e, t) => t,
|
|
81
81
|
default: () => []
|
|
82
82
|
}),
|
|
83
83
|
vectorSearchFieldResults: g({
|
|
84
|
-
reducer: (e,
|
|
84
|
+
reducer: (e, t) => t
|
|
85
85
|
})
|
|
86
86
|
});
|
|
87
|
-
async function
|
|
88
|
-
const o =
|
|
87
|
+
async function Nt(e, t) {
|
|
88
|
+
const o = O.getDefault().helperServices.geocode.find((Q) => Q.name === "ArcGIS World Geocoding Service");
|
|
89
89
|
if (!o)
|
|
90
90
|
throw new Error("ArcGIS World Geocoding Service not found in helperServices.");
|
|
91
|
-
const n = o.url, i = `${
|
|
91
|
+
const n = o.url, i = `${ne.assetsPath?.endsWith("/") ? ne.assetsPath : `${ne.assetsPath}/`}esri/images/search/search-symbol-32.png`, c = (await ut(n, {
|
|
92
92
|
address: { SingleLine: e },
|
|
93
93
|
outFields: ["Match_addr"]
|
|
94
94
|
}))?.[0];
|
|
95
95
|
if (!c?.extent)
|
|
96
96
|
throw new Error(`Could not find location for: ${e}`);
|
|
97
|
-
const { xmin: d, ymin: u, xmax: h, ymax:
|
|
97
|
+
const { xmin: d, ymin: u, xmax: h, ymax: p, spatialReference: f } = c.extent, T = new Ne({
|
|
98
98
|
xmin: d,
|
|
99
99
|
ymin: u,
|
|
100
100
|
xmax: h,
|
|
101
|
-
ymax:
|
|
101
|
+
ymax: p,
|
|
102
102
|
spatialReference: f
|
|
103
|
-
}), y = (d + h) / 2,
|
|
103
|
+
}), y = (d + h) / 2, w = (u + p) / 2, E = new le({
|
|
104
104
|
x: y,
|
|
105
|
-
y:
|
|
105
|
+
y: w,
|
|
106
106
|
spatialReference: f
|
|
107
|
-
}), $ = new
|
|
107
|
+
}), $ = new dt({
|
|
108
108
|
url: i,
|
|
109
109
|
width: 24,
|
|
110
110
|
height: 24
|
|
111
|
-
}), v = new
|
|
111
|
+
}), v = new ct({
|
|
112
112
|
geometry: E,
|
|
113
113
|
symbol: $
|
|
114
114
|
});
|
|
115
|
-
return
|
|
115
|
+
return t.graphics.removeAll(), t.graphics.add(v), await t.goTo(T), `Successfully zoomed to: ${e}. Location coordinates: x=${y}, y=${w}, wkid=${f.wkid}`;
|
|
116
116
|
}
|
|
117
|
-
const
|
|
117
|
+
const zt = ["mapView"];
|
|
118
118
|
function I(e) {
|
|
119
|
-
const
|
|
120
|
-
if (!
|
|
119
|
+
const r = e?.configurable?.context;
|
|
120
|
+
if (!r || typeof r != "object")
|
|
121
121
|
throw new Error("NavigationAgent context missing");
|
|
122
|
-
const a =
|
|
122
|
+
const a = zt.filter((o) => !(o in r));
|
|
123
123
|
if (a.length)
|
|
124
124
|
throw new Error(`NavigationAgent context missing: ${a.join(", ")}`);
|
|
125
|
-
return
|
|
125
|
+
return r;
|
|
126
126
|
}
|
|
127
|
-
async function
|
|
128
|
-
const { mapView:
|
|
129
|
-
return await
|
|
127
|
+
async function _t({ address: e }, t) {
|
|
128
|
+
const { mapView: r } = I(t);
|
|
129
|
+
return await Nt(e, r);
|
|
130
130
|
}
|
|
131
|
-
const
|
|
131
|
+
const jt = s.object({
|
|
132
132
|
address: s.string().describe("The full address or place name to locate.")
|
|
133
|
-
}),
|
|
133
|
+
}), Mt = b(_t, {
|
|
134
134
|
name: "goToAddress",
|
|
135
135
|
description: "Geocodes an address using Esri's World Geocoding Service and zooms the map to that location.",
|
|
136
|
-
schema:
|
|
136
|
+
schema: jt
|
|
137
137
|
});
|
|
138
|
-
async function
|
|
139
|
-
const a =
|
|
138
|
+
async function Pt(e, t) {
|
|
139
|
+
const a = t.map.bookmarks;
|
|
140
140
|
if (!a || a.length === 0)
|
|
141
141
|
throw new Error("No bookmarks found in the map.");
|
|
142
142
|
const o = a.find((i) => i.name === e);
|
|
@@ -145,31 +145,31 @@ async function Mt(e, r) {
|
|
|
145
145
|
const n = o.viewpoint;
|
|
146
146
|
if (!n)
|
|
147
147
|
throw new Error(`Bookmark with name "${e}" does not have a valid viewpoint.`);
|
|
148
|
-
return await
|
|
148
|
+
return await t.goTo(n), `Navigated to bookmark: ${e}`;
|
|
149
149
|
}
|
|
150
|
-
async function
|
|
151
|
-
const { mapView:
|
|
152
|
-
return await Promise.resolve(
|
|
150
|
+
async function Dt({ bookmarkName: e }, t) {
|
|
151
|
+
const { mapView: r } = I(t);
|
|
152
|
+
return await Promise.resolve(Pt(e, r));
|
|
153
153
|
}
|
|
154
|
-
const
|
|
154
|
+
const Gt = k.object({
|
|
155
155
|
bookmarkName: k.string().describe("The name of the bookmark to navigate to.")
|
|
156
|
-
}),
|
|
156
|
+
}), Ot = b(Dt, {
|
|
157
157
|
name: "goToBookmark",
|
|
158
158
|
description: "Go to the extent of the bookmark with the given name.",
|
|
159
|
-
schema:
|
|
159
|
+
schema: Gt
|
|
160
160
|
});
|
|
161
|
-
async function
|
|
162
|
-
const a =
|
|
161
|
+
async function Qt(e, t, r) {
|
|
162
|
+
const a = r.map?.allLayers.find((n) => n.id === e);
|
|
163
163
|
if (!a)
|
|
164
164
|
return `Error: Layer with id ${e} not found`;
|
|
165
165
|
const o = a.createQuery();
|
|
166
|
-
o.where =
|
|
166
|
+
o.where = t ?? "1=1";
|
|
167
167
|
try {
|
|
168
168
|
const { extent: n, count: i } = await a.queryExtent(o);
|
|
169
169
|
if (i === 0)
|
|
170
|
-
return `No features found in ${a.title} matching: ${
|
|
170
|
+
return `No features found in ${a.title} matching: ${t}`;
|
|
171
171
|
if (n)
|
|
172
|
-
await
|
|
172
|
+
await r.goTo(n);
|
|
173
173
|
else
|
|
174
174
|
return `Error: Unable to determine extent for ${a.title}`;
|
|
175
175
|
return `Successfully zoomed to ${i} feature(s) in ${a.title}`;
|
|
@@ -177,145 +177,145 @@ async function Ot(e, r, t) {
|
|
|
177
177
|
return console.error("Error in goToFeatures:", n), `Error: ${n instanceof Error ? n.message : "Unknown error"}`;
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
|
-
async function
|
|
181
|
-
const { mapView: a } = I(
|
|
182
|
-
return await
|
|
180
|
+
async function Vt({ layerId: e, where: t }, r) {
|
|
181
|
+
const { mapView: a } = I(r);
|
|
182
|
+
return await Qt(e, t, a);
|
|
183
183
|
}
|
|
184
|
-
const
|
|
184
|
+
const Wt = k.object({
|
|
185
185
|
layerId: k.string().describe("The layerId of the layer to zoom to."),
|
|
186
186
|
where: k.string().describe("The sql-92 where clause used to query features to zoom to")
|
|
187
|
-
}),
|
|
187
|
+
}), Bt = b(Vt, {
|
|
188
188
|
name: "goToFeatures",
|
|
189
189
|
description: "Go to the features that match the given filter related to the given layerId.",
|
|
190
|
-
schema:
|
|
190
|
+
schema: Wt
|
|
191
191
|
});
|
|
192
|
-
async function
|
|
193
|
-
const
|
|
192
|
+
async function Kt(e) {
|
|
193
|
+
const r = new Ne({
|
|
194
194
|
xmin: -180,
|
|
195
195
|
ymin: -90,
|
|
196
196
|
xmax: 180,
|
|
197
197
|
ymax: 90,
|
|
198
198
|
spatialReference: { wkid: 4326 }
|
|
199
199
|
}).expand(0.7);
|
|
200
|
-
return await e.goTo(
|
|
200
|
+
return await e.goTo(r), "Successfully zoomed to world extent";
|
|
201
201
|
}
|
|
202
|
-
async function
|
|
203
|
-
const { mapView:
|
|
204
|
-
return await
|
|
202
|
+
async function Ut(e, t) {
|
|
203
|
+
const { mapView: r } = I(t);
|
|
204
|
+
return await Kt(r);
|
|
205
205
|
}
|
|
206
|
-
const
|
|
206
|
+
const Ht = k.object({}), Zt = b(Ut, {
|
|
207
207
|
name: "goToFullExtent",
|
|
208
208
|
description: "Zooms the map to the full world extent using Esri's Geocoding Service.",
|
|
209
|
-
schema:
|
|
209
|
+
schema: Ht
|
|
210
210
|
});
|
|
211
|
-
async function
|
|
212
|
-
const
|
|
213
|
-
if (
|
|
214
|
-
await e.goTo(
|
|
211
|
+
async function Jt(e) {
|
|
212
|
+
const r = e.map.initialViewProperties?.viewpoint?.targetGeometry;
|
|
213
|
+
if (r)
|
|
214
|
+
await e.goTo(r);
|
|
215
215
|
else
|
|
216
216
|
throw new Error("Initial extent is undefined");
|
|
217
217
|
return "Successfully zoomed to home extent";
|
|
218
218
|
}
|
|
219
|
-
async function
|
|
220
|
-
const { mapView:
|
|
221
|
-
return await
|
|
219
|
+
async function Yt(e, t) {
|
|
220
|
+
const { mapView: r } = I(t);
|
|
221
|
+
return await Jt(r);
|
|
222
222
|
}
|
|
223
|
-
const
|
|
223
|
+
const Xt = s.object({}), er = b(Yt, {
|
|
224
224
|
name: "goToHomeExtent",
|
|
225
225
|
description: "Go to the initial web map view extent",
|
|
226
|
-
schema:
|
|
226
|
+
schema: Xt
|
|
227
227
|
});
|
|
228
|
-
async function
|
|
229
|
-
await
|
|
230
|
-
const
|
|
231
|
-
if (!
|
|
228
|
+
async function tr(e, t) {
|
|
229
|
+
await t.when();
|
|
230
|
+
const r = t.map?.allLayers.find((o) => o.id === e);
|
|
231
|
+
if (!r)
|
|
232
232
|
return console.warn(`[goToLayer] No matching FeatureLayer found for: ${e}`), `Could not find layer for: ${e}`;
|
|
233
233
|
let a;
|
|
234
|
-
return (
|
|
234
|
+
return (r.type === "link-chart" || r.type === "knowledge-graph-sublayer") && t.map?.activeLinkChartLayer ? a = t.map.diagramNodesExtent : a = r.fullExtent, a ? (await t.goTo(a), r.visible = !0, `Successfully zoomed to: ${r.title ?? ""}`) : "Layer has no defined extent. Cannot zoom to layer.";
|
|
235
235
|
}
|
|
236
|
-
async function
|
|
237
|
-
const { mapView:
|
|
238
|
-
return await
|
|
236
|
+
async function rr({ layerId: e }, t) {
|
|
237
|
+
const { mapView: r } = I(t);
|
|
238
|
+
return await tr(e, r);
|
|
239
239
|
}
|
|
240
|
-
const
|
|
240
|
+
const ar = k.object({
|
|
241
241
|
layerId: k.string().describe("The id of the layer to navigate to")
|
|
242
|
-
}),
|
|
242
|
+
}), or = b(rr, {
|
|
243
243
|
name: "goToLayer",
|
|
244
244
|
description: "Zooms the map view to the full extent of the top matching layer.",
|
|
245
|
-
schema:
|
|
245
|
+
schema: ar
|
|
246
246
|
});
|
|
247
|
-
async function
|
|
248
|
-
return await
|
|
247
|
+
async function nr(e, t) {
|
|
248
|
+
return await t.goTo({ scale: e }), `Successfully zoomed to: ${e}`;
|
|
249
249
|
}
|
|
250
|
-
async function
|
|
251
|
-
const { mapView:
|
|
252
|
-
return await
|
|
250
|
+
async function sr({ scale: e }, t) {
|
|
251
|
+
const { mapView: r } = I(t);
|
|
252
|
+
return await nr(e, r);
|
|
253
253
|
}
|
|
254
|
-
const
|
|
254
|
+
const ir = s.object({
|
|
255
255
|
scale: s.number().describe("The map scale of the view to go to.")
|
|
256
|
-
}),
|
|
256
|
+
}), lr = b(sr, {
|
|
257
257
|
name: "goToScale",
|
|
258
258
|
description: "Go to the specified view scale.",
|
|
259
|
-
schema:
|
|
259
|
+
schema: ir
|
|
260
260
|
});
|
|
261
|
-
async function
|
|
261
|
+
async function cr(e, t, r) {
|
|
262
262
|
const o = {
|
|
263
|
-
target: new
|
|
263
|
+
target: new le({
|
|
264
264
|
longitude: e.longitude,
|
|
265
265
|
latitude: e.latitude,
|
|
266
266
|
spatialReference: { wkid: 4326 }
|
|
267
267
|
})
|
|
268
268
|
};
|
|
269
|
-
return
|
|
269
|
+
return r?.zoom !== void 0 && (o.zoom = r.zoom), r?.scale !== void 0 && (o.scale = r.scale), await t.goTo(o), `Successfully navigated to: ${[
|
|
270
270
|
`(${e.latitude}°, ${e.longitude}°)`,
|
|
271
|
-
|
|
272
|
-
|
|
271
|
+
r?.zoom !== void 0 ? `zoom ${r.zoom}` : "",
|
|
272
|
+
r?.scale !== void 0 ? `scale 1:${r.scale}` : ""
|
|
273
273
|
].filter(Boolean).join(", ")}`;
|
|
274
274
|
}
|
|
275
|
-
async function
|
|
275
|
+
async function dr({
|
|
276
276
|
center: e,
|
|
277
|
-
zoom:
|
|
278
|
-
scale:
|
|
277
|
+
zoom: t,
|
|
278
|
+
scale: r
|
|
279
279
|
}, a) {
|
|
280
280
|
const { mapView: o } = I(a);
|
|
281
|
-
return await
|
|
281
|
+
return await cr(e, o, { zoom: t, scale: r });
|
|
282
282
|
}
|
|
283
|
-
const
|
|
283
|
+
const ur = s.object({
|
|
284
284
|
center: s.object({
|
|
285
285
|
longitude: s.number().describe("The longitude (x-coordinate) of the point to navigate to."),
|
|
286
286
|
latitude: s.number().describe("The latitude (y-coordinate) of the point to navigate to.")
|
|
287
287
|
}),
|
|
288
288
|
zoom: s.number().optional().describe("The zoom level. Higher values = more zoomed in."),
|
|
289
289
|
scale: s.number().optional().describe("The map scale. Alternative to zoom. Smaller numbers = more zoomed in.")
|
|
290
|
-
}),
|
|
290
|
+
}), hr = b(dr, {
|
|
291
291
|
name: "goToViewpoint",
|
|
292
292
|
description: "Go to the specified viewpoint. This can contain a combination of scale, center, zoom, etc.",
|
|
293
|
-
schema:
|
|
293
|
+
schema: ur
|
|
294
294
|
});
|
|
295
|
-
async function
|
|
296
|
-
return await
|
|
295
|
+
async function mr(e, t) {
|
|
296
|
+
return await t.goTo({ zoom: e }), `Successfully zoomed to: ${e}`;
|
|
297
297
|
}
|
|
298
|
-
async function pr({ zoom: e },
|
|
299
|
-
const { mapView:
|
|
300
|
-
return await
|
|
298
|
+
async function pr({ zoom: e }, t) {
|
|
299
|
+
const { mapView: r } = I(t);
|
|
300
|
+
return await mr(e, r);
|
|
301
301
|
}
|
|
302
|
-
const
|
|
302
|
+
const yr = s.object({
|
|
303
303
|
zoom: s.number().min(1).max(20).describe("The zoom level of the view to go to.")
|
|
304
|
-
}),
|
|
304
|
+
}), fr = b(pr, {
|
|
305
305
|
name: "goToZoom",
|
|
306
306
|
description: 'Go to the specified zoom level. If input is generic (e.g. "zoom in", then only zoom to the next appropriate level - increase level for zooming in and decrease for zooming out.).',
|
|
307
|
-
schema:
|
|
308
|
-
}),
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
],
|
|
307
|
+
schema: yr
|
|
308
|
+
}), me = [
|
|
309
|
+
Mt,
|
|
310
|
+
Ot,
|
|
311
|
+
Bt,
|
|
312
|
+
Zt,
|
|
313
|
+
er,
|
|
314
|
+
or,
|
|
315
|
+
lr,
|
|
316
|
+
hr,
|
|
317
|
+
fr
|
|
318
|
+
], Fe = /* @__PURE__ */ Object.assign({
|
|
319
319
|
"../agents/arcgisKnowledge/prompts/arcgis_knowledge_current_lc_context.md": () => import("./arcgis_knowledge_current_lc_context-BIA49RO2.js").then((e) => e.default),
|
|
320
320
|
"../agents/arcgisKnowledge/prompts/arcgis_knowledge_intent_prompt.md": () => import("./arcgis_knowledge_intent_prompt-AaXBzNVW.js").then((e) => e.default),
|
|
321
321
|
"../agents/arcgisKnowledge/prompts/arcgis_knowledge_tool_prompt.md": () => import("./arcgis_knowledge_tool_prompt-459P6qrK.js").then((e) => e.default),
|
|
@@ -331,24 +331,24 @@ const mr = s.object({
|
|
|
331
331
|
"../agents/navigation/prompts/navigation_tool_prompt.md": () => import("./navigation_tool_prompt-C2jIBkeu.js").then((e) => e.default)
|
|
332
332
|
});
|
|
333
333
|
async function F(e) {
|
|
334
|
-
const
|
|
335
|
-
if (!
|
|
334
|
+
const t = Object.entries(Fe).find(([r]) => r.endsWith(`/${e}.md`));
|
|
335
|
+
if (!t)
|
|
336
336
|
throw new Error(`Prompt not found: ${e}
|
|
337
337
|
Available prompts:
|
|
338
|
-
${Object.keys(
|
|
338
|
+
${Object.keys(Fe).join(`
|
|
339
339
|
`)}`);
|
|
340
|
-
return await
|
|
340
|
+
return await t[1]();
|
|
341
341
|
}
|
|
342
|
-
const
|
|
343
|
-
const
|
|
344
|
-
if (
|
|
342
|
+
const gr = (e, t = 3) => e.filter((r) => r instanceof ze).slice(-t), x = (e, t = 3) => {
|
|
343
|
+
const r = e.map((o, n) => o instanceof ze ? n : -1).filter((o) => o !== -1);
|
|
344
|
+
if (r.length === 0)
|
|
345
345
|
return [];
|
|
346
|
-
const a =
|
|
346
|
+
const a = r.length > t ? r[r.length - t] : r[0];
|
|
347
347
|
return e.slice(a);
|
|
348
|
-
}, C = (e,
|
|
349
|
-
async function
|
|
350
|
-
const
|
|
351
|
-
(y,
|
|
348
|
+
}, C = (e, t = " ") => gr(e).map((o) => o.content).join(t).trim();
|
|
349
|
+
async function wr(e, t) {
|
|
350
|
+
const r = await F("navigation_tool_prompt"), { mapView: a } = I(t), o = a.map, n = e.vectorSearchLayerResults?.length > 0 ? e.vectorSearchLayerResults.map(
|
|
351
|
+
(y, w) => `${w + 1}. layerId=${y.id} | title=${y.title ?? ""} | name=${y.name ?? ""} | score=${y.score.toFixed(2)}`
|
|
352
352
|
).join(`
|
|
353
353
|
`) : "", i = e.vectorSearchFieldResults?.length > 0 ? JSON.stringify(e.vectorSearchFieldResults, null, 2) : "", l = e.intent === "goToBookmark" && o.bookmarks?.length ? `Available bookmarks:
|
|
354
354
|
${JSON.stringify(o.bookmarks, null, 2)}` : "", c = (e.intent === "goToLayer" || e.intent === "goToFeatures") && e.vectorSearchLayerResults?.length ? `Candidate layers:
|
|
@@ -360,59 +360,59 @@ ${i}` : "", u = {
|
|
|
360
360
|
fieldsSection: d,
|
|
361
361
|
currentZoom: a.zoom
|
|
362
362
|
}, h = await M({
|
|
363
|
-
promptText:
|
|
363
|
+
promptText: r,
|
|
364
364
|
modelTier: "advanced",
|
|
365
365
|
messages: x(e.messages),
|
|
366
366
|
inputVariables: u,
|
|
367
|
-
tools:
|
|
368
|
-
}),
|
|
367
|
+
tools: me
|
|
368
|
+
}), p = [...e.messages, h], T = (h.tool_calls?.length ?? 0) > 0 ? [...p] : [...p, h];
|
|
369
369
|
return { ...e, messages: T };
|
|
370
370
|
}
|
|
371
|
-
async function
|
|
372
|
-
const a = await new P(
|
|
371
|
+
async function br(e, t) {
|
|
372
|
+
const a = await new P(me).invoke(
|
|
373
373
|
{
|
|
374
374
|
messages: x(e.messages)
|
|
375
375
|
},
|
|
376
|
-
|
|
376
|
+
t
|
|
377
377
|
), o = a.messages.map((l) => l.text).join(`
|
|
378
378
|
`);
|
|
379
|
-
await
|
|
379
|
+
await m({ text: `Finished executing navigation tool: ${o}` }, t);
|
|
380
380
|
const n = [...e.messages, ...a.messages], i = a.messages.map((l) => l.text).join(`
|
|
381
381
|
`);
|
|
382
382
|
return { ...e, messages: n, outputMessage: i };
|
|
383
383
|
}
|
|
384
|
-
async function
|
|
385
|
-
const
|
|
384
|
+
async function Sr(e, t) {
|
|
385
|
+
const r = await F("navigation_intent_prompt"), { mapView: a } = I(t), o = me.map((h) => ({
|
|
386
386
|
name: h.name,
|
|
387
387
|
description: h.description,
|
|
388
388
|
schema: h.schema
|
|
389
389
|
})), n = a.map, i = n.bookmarks?.length ? `Available bookmarks:
|
|
390
390
|
${JSON.stringify(n.bookmarks, null, 2)}` : "", l = {
|
|
391
|
-
tools: o.map(({ name: h, description:
|
|
391
|
+
tools: o.map(({ name: h, description: p, schema: f }) => `${h}: ${p}, ${JSON.stringify(f)}`).join(`
|
|
392
392
|
`),
|
|
393
393
|
bookmarks: i
|
|
394
394
|
}, c = s.object({
|
|
395
395
|
intent: s.string()
|
|
396
|
-
}), d = await
|
|
397
|
-
promptText:
|
|
396
|
+
}), d = await ke({
|
|
397
|
+
promptText: r,
|
|
398
398
|
messages: x(e.messages),
|
|
399
399
|
inputVariables: l,
|
|
400
400
|
schema: c
|
|
401
401
|
}), u = typeof d.intent == "string" ? d.intent.trim().replace(/^"|"$/gu, "") : "";
|
|
402
402
|
return { ...e, intent: u || "" };
|
|
403
403
|
}
|
|
404
|
-
const S = (e,
|
|
405
|
-
const a = e?.configurable?.services?.[
|
|
404
|
+
const S = (e, t) => {
|
|
405
|
+
const a = e?.configurable?.services?.[t];
|
|
406
406
|
if (a == null)
|
|
407
|
-
throw new Error(`${
|
|
407
|
+
throw new Error(`${t} missing in config.configurable.services`);
|
|
408
408
|
return a;
|
|
409
|
-
},
|
|
409
|
+
}, vr = 0.7, Tr = async (e, t) => {
|
|
410
410
|
try {
|
|
411
|
-
const
|
|
412
|
-
await
|
|
413
|
-
const a = S(
|
|
414
|
-
text:
|
|
415
|
-
minScore:
|
|
411
|
+
const r = C(e.messages);
|
|
412
|
+
await m({ text: `Similarity search to find layers: ${r}` }, t);
|
|
413
|
+
const a = S(t, "layerSearch"), o = S(t, "layersAndFieldsRegistry"), n = S(t, "embeddingCache"), l = (await a.searchLayers({
|
|
414
|
+
text: r,
|
|
415
|
+
minScore: vr,
|
|
416
416
|
embeddingCache: n
|
|
417
417
|
})).map(({ id: d, score: u }) => {
|
|
418
418
|
const h = o.get(d)?.layerItem;
|
|
@@ -426,36 +426,36 @@ const S = (e, r) => {
|
|
|
426
426
|
let c;
|
|
427
427
|
return l.length > 0 ? c = `Vector search completed. Matching layers:
|
|
428
428
|
${l.map((d) => `- layerId=${d.id} | title=${d.title ?? ""} | name=${d.name ?? ""} | score=${d.score.toFixed(2)}`).join(`
|
|
429
|
-
`)}` : c = "Vector search completed. No matching layers found.", await
|
|
429
|
+
`)}` : c = "Vector search completed. No matching layers found.", await m({ text: c }, t), {
|
|
430
430
|
...e,
|
|
431
431
|
vectorSearchLayerResults: l
|
|
432
432
|
};
|
|
433
|
-
} catch (
|
|
434
|
-
throw await
|
|
435
|
-
{ text: `Error during vector search layers: ${
|
|
436
|
-
|
|
437
|
-
),
|
|
433
|
+
} catch (r) {
|
|
434
|
+
throw await m(
|
|
435
|
+
{ text: `Error during vector search layers: ${r instanceof Error ? r.message : String(r)}` },
|
|
436
|
+
t
|
|
437
|
+
), r;
|
|
438
438
|
}
|
|
439
|
-
},
|
|
439
|
+
}, Re = 0.7, xr = 10, Er = async (e, t) => {
|
|
440
440
|
try {
|
|
441
|
-
const
|
|
442
|
-
await
|
|
443
|
-
const a = S(
|
|
441
|
+
const r = C(e.messages);
|
|
442
|
+
await m({ text: "Similarity search to find fields" }, t);
|
|
443
|
+
const a = S(t, "fieldSearch"), o = S(t, "layersAndFieldsRegistry"), n = S(t, "embeddingCache"), i = e.vectorSearchLayerResults?.map((u) => u.id) ?? [];
|
|
444
444
|
if (i.length === 0)
|
|
445
|
-
return await
|
|
445
|
+
return await m({ text: "No candidate layers for field search" }, t), e;
|
|
446
446
|
const c = (await a.searchFields({
|
|
447
|
-
text:
|
|
447
|
+
text: r,
|
|
448
448
|
layerIds: i,
|
|
449
|
-
minScore:
|
|
450
|
-
topResults:
|
|
449
|
+
minScore: Re,
|
|
450
|
+
topResults: xr,
|
|
451
451
|
embeddingCache: n
|
|
452
452
|
})).map(({ layerId: u, results: h }) => {
|
|
453
|
-
const
|
|
453
|
+
const p = o.get(u)?.fieldRegistry;
|
|
454
454
|
return {
|
|
455
455
|
layerId: u,
|
|
456
456
|
layerName: o.get(u)?.layerItem.name,
|
|
457
457
|
results: h.map((f) => {
|
|
458
|
-
const T =
|
|
458
|
+
const T = p?.get(f.name);
|
|
459
459
|
return {
|
|
460
460
|
name: f.name,
|
|
461
461
|
score: f.score,
|
|
@@ -474,37 +474,37 @@ ${c.map(
|
|
|
474
474
|
${u.results.map((h) => ` - ${h.name} (${h.score.toFixed(2)})`).join(`
|
|
475
475
|
`)}`
|
|
476
476
|
).join(`
|
|
477
|
-
`)}` : d = `No vector search field results found for score over ${
|
|
477
|
+
`)}` : d = `No vector search field results found for score over ${Re}.`, await m({ text: d }, t), {
|
|
478
478
|
...e,
|
|
479
479
|
vectorSearchFieldResults: c
|
|
480
480
|
};
|
|
481
|
-
} catch (
|
|
482
|
-
throw await
|
|
483
|
-
{ text: `Error during vector search fields: ${
|
|
484
|
-
|
|
485
|
-
),
|
|
481
|
+
} catch (r) {
|
|
482
|
+
throw await m(
|
|
483
|
+
{ text: `Error during vector search fields: ${r instanceof Error ? r.message : String(r)}` },
|
|
484
|
+
t
|
|
485
|
+
), r;
|
|
486
486
|
}
|
|
487
|
-
}, D = (e,
|
|
487
|
+
}, D = (e, t) => (r, a) => {
|
|
488
488
|
const o = a?.configurable?.services;
|
|
489
489
|
for (const n of e)
|
|
490
490
|
if (!o?.[n])
|
|
491
|
-
throw new Error(`${
|
|
492
|
-
return
|
|
493
|
-
},
|
|
491
|
+
throw new Error(`${t} requires services.${n} to be available.`);
|
|
492
|
+
return r;
|
|
493
|
+
}, $r = (e, t) => D(["layerSearch", "layersAndFieldsRegistry"], "Navigation Agent")(e, t), Fr = () => new _(De).addNode("requireNavigationServices", $r).addNode("intentLLM", Sr).addNode("vectorSearchLayers", Tr).addNode("vectorSearchFields", Er).addNode("agent", wr).addNode("tools", br).addEdge(j, "requireNavigationServices").addEdge("requireNavigationServices", "intentLLM").addConditionalEdges(
|
|
494
494
|
"intentLLM",
|
|
495
|
-
(
|
|
495
|
+
(t) => t.intent === "goToLayer" || t.intent === "goToFeatures" ? "vectorSearchLayers" : "agent",
|
|
496
496
|
{
|
|
497
497
|
vectorSearchLayers: "vectorSearchLayers",
|
|
498
498
|
agent: "agent"
|
|
499
499
|
}
|
|
500
500
|
).addConditionalEdges(
|
|
501
501
|
"vectorSearchLayers",
|
|
502
|
-
(
|
|
502
|
+
(t) => t.intent === "goToFeatures" ? "vectorSearchFields" : "agent",
|
|
503
503
|
{
|
|
504
504
|
vectorSearchFields: "vectorSearchFields",
|
|
505
505
|
agent: "agent"
|
|
506
506
|
}
|
|
507
|
-
).addEdge("vectorSearchFields", "agent").addEdge("agent", "tools").addEdge("tools", R),
|
|
507
|
+
).addEdge("vectorSearchFields", "agent").addEdge("agent", "tools").addEdge("tools", R), Rr = String.raw`- **navigation** — Enables users to interact with the map by navigating to specific locations, layers, features, or extents.
|
|
508
508
|
This includes zooming, panning, centering, or geocoding based on user input. The agent is designed to handle explicit map movement requests. NOTE: DO NOT call this agent if the user asks "show me...", that is meant to be handled by another agent. If the query is about where a certain address is, call this agent.
|
|
509
509
|
|
|
510
510
|
Supported actions:
|
|
@@ -523,13 +523,13 @@ ${u.results.map((h) => ` - ${h.name} (${h.score.toFixed(2)})`).join(`
|
|
|
523
523
|
_Example: “Center the map on San Francisco at scale 50000”_
|
|
524
524
|
_Example: “Zoom to the features in the schools layer where city = 'Austin'”_
|
|
525
525
|
_Example: “Go to the Downtown bookmark”_
|
|
526
|
-
_Example: “Where is Mount Rainier?”_`,
|
|
526
|
+
_Example: “Where is Mount Rainier?”_`, Ii = {
|
|
527
527
|
id: "navigation",
|
|
528
528
|
name: "Navigation Agent",
|
|
529
|
-
description:
|
|
530
|
-
createGraph:
|
|
531
|
-
workspace:
|
|
532
|
-
},
|
|
529
|
+
description: Rr,
|
|
530
|
+
createGraph: Fr,
|
|
531
|
+
workspace: De
|
|
532
|
+
}, Ge = g.Root({
|
|
533
533
|
// Inputs coming from global context
|
|
534
534
|
messages: g({
|
|
535
535
|
reducer: z,
|
|
@@ -540,21 +540,21 @@ ${u.results.map((h) => ` - ${h.name} (${h.score.toFixed(2)})`).join(`
|
|
|
540
540
|
// This avoids duplicate output when tool nodes and final LLM nodes
|
|
541
541
|
// emit the same text during a single agent turn.
|
|
542
542
|
outputMessage: g({
|
|
543
|
-
reducer: (e = "",
|
|
544
|
-
const
|
|
545
|
-
if (!
|
|
543
|
+
reducer: (e = "", t) => {
|
|
544
|
+
const r = typeof t == "string" ? t.trim() : "";
|
|
545
|
+
if (!r)
|
|
546
546
|
return e;
|
|
547
547
|
const a = e.trim();
|
|
548
548
|
if (!a)
|
|
549
|
-
return
|
|
550
|
-
if (a ===
|
|
549
|
+
return r;
|
|
550
|
+
if (a === r)
|
|
551
551
|
return e;
|
|
552
552
|
const o = a.split(`
|
|
553
553
|
|
|
554
554
|
`);
|
|
555
|
-
return o[o.length - 1]?.trim() ===
|
|
555
|
+
return o[o.length - 1]?.trim() === r ? e : `${e}
|
|
556
556
|
|
|
557
|
-
${
|
|
557
|
+
${r}`;
|
|
558
558
|
},
|
|
559
559
|
default: () => ""
|
|
560
560
|
}),
|
|
@@ -562,85 +562,85 @@ ${t}`;
|
|
|
562
562
|
vectorSearchFieldResults: g(),
|
|
563
563
|
layerFieldInfo: g(),
|
|
564
564
|
queryResponse: g()
|
|
565
|
-
}),
|
|
566
|
-
const
|
|
567
|
-
if (
|
|
568
|
-
await
|
|
565
|
+
}), Lr = async (e, t) => (await m({ text: "Exiting Data Exploration agent" }, t), e), H = async (e, t) => {
|
|
566
|
+
const r = e.tool_calls ?? [];
|
|
567
|
+
if (r.length === 0) {
|
|
568
|
+
await m({ text: `LLM did not request any tool calls: ${String(e?.content)}` }, t);
|
|
569
569
|
return;
|
|
570
570
|
}
|
|
571
571
|
await Promise.all(
|
|
572
|
-
|
|
573
|
-
async (a) => await
|
|
572
|
+
r.map(
|
|
573
|
+
async (a) => await m(
|
|
574
574
|
{ text: `LLM invoked ${a.name} tool with arguments: ${JSON.stringify(a.args, null, 2)}` },
|
|
575
|
-
|
|
575
|
+
t
|
|
576
576
|
)
|
|
577
577
|
)
|
|
578
578
|
);
|
|
579
|
-
},
|
|
579
|
+
}, Ir = ["mapView"];
|
|
580
580
|
function N(e) {
|
|
581
|
-
const
|
|
582
|
-
if (!
|
|
581
|
+
const r = e?.configurable?.context;
|
|
582
|
+
if (!r || typeof r != "object")
|
|
583
583
|
throw new Error("DataExplorationAgent context missing");
|
|
584
|
-
const a =
|
|
584
|
+
const a = Ir.filter((o) => !(o in r));
|
|
585
585
|
if (a.length)
|
|
586
586
|
throw new Error(`DataExplorationAgent context missing: ${a.join(", ")}`);
|
|
587
|
-
return
|
|
587
|
+
return r;
|
|
588
588
|
}
|
|
589
|
-
const
|
|
590
|
-
const
|
|
591
|
-
let
|
|
592
|
-
return
|
|
589
|
+
const qr = (e) => {
|
|
590
|
+
const t = e.map?.allLayers.filter((a) => a.type === "feature");
|
|
591
|
+
let r = 0;
|
|
592
|
+
return t?.forEach((a) => {
|
|
593
593
|
const o = a;
|
|
594
|
-
o.featureEffect && (o.featureEffect = null,
|
|
595
|
-
}),
|
|
596
|
-
},
|
|
597
|
-
const { mapView:
|
|
598
|
-
return
|
|
599
|
-
},
|
|
594
|
+
o.featureEffect && (o.featureEffect = null, r++);
|
|
595
|
+
}), r > 0 ? `Cleared filters from ${r} layer(s). View unchanged.` : "No active filters to clear. View unchanged.";
|
|
596
|
+
}, Cr = async (e, t) => {
|
|
597
|
+
const { mapView: r } = N(t);
|
|
598
|
+
return qr(r);
|
|
599
|
+
}, Ar = b(Cr, {
|
|
600
600
|
name: "clearFilters",
|
|
601
601
|
description: "Clears all feature effects/filters from the map but does NOT change the current view. Use when user says 'clear filters', 'reset filters', 'remove filters', 'show all features', or wants to remove emphasis without navigating anywhere.",
|
|
602
602
|
schema: s.object({})
|
|
603
|
-
}),
|
|
603
|
+
}), kr = async (e) => {
|
|
604
604
|
e.map?.allLayers.filter((o) => o.type === "feature")?.forEach((o) => {
|
|
605
605
|
const n = o;
|
|
606
606
|
n.featureEffect && (n.featureEffect = null);
|
|
607
607
|
});
|
|
608
608
|
const a = e.map.initialViewProperties?.viewpoint?.targetGeometry;
|
|
609
609
|
return a ? (await e.goTo(a), "Cleared all filters and returned to home extent.") : "Cleared all filters. Could not determine home extent.";
|
|
610
|
-
},
|
|
611
|
-
const { mapView:
|
|
612
|
-
return await
|
|
613
|
-
},
|
|
610
|
+
}, Nr = async (e, t) => {
|
|
611
|
+
const { mapView: r } = N(t);
|
|
612
|
+
return await kr(r);
|
|
613
|
+
}, zr = b(Nr, {
|
|
614
614
|
name: "resetMap",
|
|
615
615
|
description: "Clears all feature effects/filters from the map AND zooms to the home extent (initial map view). Use when user says 'reset map', 'reset the map', 'start over', or wants to both clear filters and return to the initial view.",
|
|
616
616
|
schema: s.object({})
|
|
617
617
|
});
|
|
618
|
-
function
|
|
618
|
+
function X(e) {
|
|
619
619
|
return "point" in e && e.point !== void 0;
|
|
620
620
|
}
|
|
621
|
-
function
|
|
621
|
+
function W(e) {
|
|
622
622
|
return "layerId" in e && e.layerId !== void 0;
|
|
623
623
|
}
|
|
624
|
-
const
|
|
625
|
-
if (
|
|
626
|
-
const { point:
|
|
627
|
-
return { geometry: new
|
|
628
|
-
x:
|
|
629
|
-
y:
|
|
630
|
-
spatialReference:
|
|
624
|
+
const re = async (e, t) => {
|
|
625
|
+
if (X(e)) {
|
|
626
|
+
const { point: r } = e;
|
|
627
|
+
return { geometry: new le({
|
|
628
|
+
x: r.x,
|
|
629
|
+
y: r.y,
|
|
630
|
+
spatialReference: r.spatialReference ? { wkid: r.spatialReference.wkid } : t.spatialReference
|
|
631
631
|
}) };
|
|
632
632
|
}
|
|
633
|
-
if (
|
|
634
|
-
const
|
|
633
|
+
if (W(e)) {
|
|
634
|
+
const r = t.map?.allLayers.find(
|
|
635
635
|
(a) => a.id === e.layerId
|
|
636
636
|
);
|
|
637
|
-
if (!
|
|
637
|
+
if (!r)
|
|
638
638
|
return { error: `Could not find geometry layer with ID: ${e.layerId}` };
|
|
639
639
|
try {
|
|
640
|
-
const a = await
|
|
640
|
+
const a = await r.queryFeatures({
|
|
641
641
|
where: e.where,
|
|
642
642
|
returnGeometry: !0,
|
|
643
|
-
outSpatialReference:
|
|
643
|
+
outSpatialReference: t.spatialReference
|
|
644
644
|
});
|
|
645
645
|
if (!a.features.length)
|
|
646
646
|
return {
|
|
@@ -653,23 +653,23 @@ const ee = async (e, r) => {
|
|
|
653
653
|
return { error: "The geometry of the first feature is undefined or null." };
|
|
654
654
|
o = n;
|
|
655
655
|
} else {
|
|
656
|
-
const n = a.features.map((l) => l.geometry), i =
|
|
656
|
+
const n = a.features.map((l) => l.geometry), i = ce.executeMany(n);
|
|
657
657
|
if (!i)
|
|
658
658
|
return { error: "Failed to create a combined geometry." };
|
|
659
659
|
o = i;
|
|
660
660
|
}
|
|
661
|
-
return o.spatialReference || (o.spatialReference =
|
|
661
|
+
return o.spatialReference || (o.spatialReference = t.spatialReference), { geometry: o };
|
|
662
662
|
} catch (a) {
|
|
663
663
|
return { error: `Failed to query geometry: ${String(a)}` };
|
|
664
664
|
}
|
|
665
665
|
}
|
|
666
666
|
return { error: "Invalid geometry configuration provided" };
|
|
667
|
-
},
|
|
668
|
-
const i = e.map?.allLayers.find((c) => c.id ===
|
|
667
|
+
}, _r = async (e, t, r, a, o, n) => {
|
|
668
|
+
const i = e.map?.allLayers.find((c) => c.id === t);
|
|
669
669
|
if (!i)
|
|
670
|
-
return { success: !1, error: `Layer '${
|
|
670
|
+
return { success: !1, error: `Layer '${t}' not found.` };
|
|
671
671
|
const l = i.createQuery();
|
|
672
|
-
l.where =
|
|
672
|
+
l.where = r ?? "1=1", a && (l.geometry = a, l.spatialRelationship = "intersects", o && (l.distance = o), n && (l.units = n));
|
|
673
673
|
try {
|
|
674
674
|
const { extent: c, count: d } = await i.queryExtent(l);
|
|
675
675
|
return !c || d === 0 ? {
|
|
@@ -682,33 +682,33 @@ const ee = async (e, r) => {
|
|
|
682
682
|
error: c instanceof Error ? c.message : String(c)
|
|
683
683
|
};
|
|
684
684
|
}
|
|
685
|
-
},
|
|
686
|
-
const i =
|
|
685
|
+
}, jr = async (e, t, r, a, o, n) => {
|
|
686
|
+
const i = t.map?.allLayers.find(
|
|
687
687
|
(u) => u.id === e.layerId
|
|
688
688
|
);
|
|
689
689
|
if (!i)
|
|
690
690
|
return `Could not find target layer with ID: ${e.layerId}`;
|
|
691
691
|
let l;
|
|
692
692
|
if (o) {
|
|
693
|
-
const u = await
|
|
693
|
+
const u = await re(o, t);
|
|
694
694
|
if ("error" in u)
|
|
695
695
|
return u.error;
|
|
696
696
|
l = u.geometry;
|
|
697
697
|
}
|
|
698
|
-
if (i.featureEffect = null, i.featureEffect = new
|
|
699
|
-
filter: new
|
|
698
|
+
if (i.featureEffect = null, i.featureEffect = new _e({
|
|
699
|
+
filter: new U({
|
|
700
700
|
where: e.where,
|
|
701
701
|
geometry: l,
|
|
702
702
|
spatialRelationship: "intersects",
|
|
703
703
|
distance: o?.distance,
|
|
704
704
|
units: o?.units
|
|
705
705
|
}),
|
|
706
|
-
includedEffect:
|
|
706
|
+
includedEffect: r,
|
|
707
707
|
excludedEffect: a
|
|
708
708
|
}), i.visible = !0, n)
|
|
709
709
|
return `Applied feature effects to "${i.title ?? e.layerId}" within current map extent.`;
|
|
710
|
-
const c = await
|
|
711
|
-
|
|
710
|
+
const c = await _r(
|
|
711
|
+
t,
|
|
712
712
|
e.layerId,
|
|
713
713
|
e.where,
|
|
714
714
|
l,
|
|
@@ -716,21 +716,21 @@ const ee = async (e, r) => {
|
|
|
716
716
|
o?.units
|
|
717
717
|
), d = i.title ?? e.layerId;
|
|
718
718
|
return c.success ? `Applied feature effects to target layer "${i.title ?? e.layerId}"${o && "layerId" in o ? ` using geometry from layer "${o.layerId}"` : ""}.` : `Applied filter to "${d}" but no features matched. ${c.error}`;
|
|
719
|
-
},
|
|
719
|
+
}, Mr = ["feet", "kilometers", "meters", "miles", "nautical-miles", "us-nautical-miles"], A = s.enum(Mr), Pr = async ({
|
|
720
720
|
targetLayer: e,
|
|
721
|
-
geometryFilter:
|
|
722
|
-
useCurrentExtent:
|
|
721
|
+
geometryFilter: t,
|
|
722
|
+
useCurrentExtent: r,
|
|
723
723
|
includedEffect: a = "drop-shadow(2px, 2px, 2px, gray)",
|
|
724
724
|
excludedEffect: o = "grayscale(100%) opacity(60%) blur(2px)"
|
|
725
725
|
}, n) => {
|
|
726
726
|
const { mapView: i } = N(n);
|
|
727
|
-
return await
|
|
728
|
-
},
|
|
727
|
+
return await jr(e, i, a, o, t, r);
|
|
728
|
+
}, Dr = s.object({
|
|
729
729
|
layerId: s.string().describe("The layerId of the layer containing the geometry by which to filter."),
|
|
730
730
|
where: s.string().describe("The SQL-92 where clause representing the features from which to filter."),
|
|
731
731
|
distance: s.number().optional().describe("The buffer distance around the geometry."),
|
|
732
732
|
units: A.optional().describe("The units for the distance buffer.")
|
|
733
|
-
}),
|
|
733
|
+
}), Gr = s.object({
|
|
734
734
|
point: s.object({
|
|
735
735
|
x: s.number().describe("X coordinate (longitude) from navigation result"),
|
|
736
736
|
y: s.number().describe("Y coordinate (latitude) from navigation result"),
|
|
@@ -740,12 +740,12 @@ const ee = async (e, r) => {
|
|
|
740
740
|
}).describe("Point coordinates from a previous navigation/geocoding result"),
|
|
741
741
|
distance: s.number().optional().describe("Optional buffer distance around the point."),
|
|
742
742
|
units: A.optional().describe("The units for the distance buffer.")
|
|
743
|
-
}),
|
|
743
|
+
}), Or = s.object({
|
|
744
744
|
targetLayer: s.object({
|
|
745
745
|
layerId: s.string().describe("The layerId of the layer on which to set a feature effect."),
|
|
746
746
|
where: s.string().describe("The SQL-92 where clause representing the features to emphasize.")
|
|
747
747
|
}),
|
|
748
|
-
geometryFilter: s.union([
|
|
748
|
+
geometryFilter: s.union([Dr, Gr]).optional().describe("Optional geometry-based filtering parameters for spatial queries."),
|
|
749
749
|
useCurrentExtent: s.boolean().optional().describe(
|
|
750
750
|
"Set to true when the previous query used the current map extent as a spatial filter. This ensures the feature effect applies only to features visible in the current view. Default is false."
|
|
751
751
|
),
|
|
@@ -755,88 +755,88 @@ const ee = async (e, r) => {
|
|
|
755
755
|
excludedEffect: s.string().default("grayscale(100%) opacity(60%) blur(2px)").describe(
|
|
756
756
|
"The effect applied to features that do not meet the filter requirements. Valid effects include: bloom, blur, brightness, contrast, drop-shadow, grayscale, hue-rotate, invert, opacity, saturate, and sepia. Prefer default unless specified."
|
|
757
757
|
)
|
|
758
|
-
}),
|
|
758
|
+
}), Qr = b(Pr, {
|
|
759
759
|
name: "setFeatureEffect",
|
|
760
760
|
description: "Sets a feature effect on a given layer with given filter parameters and feature effects to emphasize certain features that meet a filter requirement. If no feature effect information is provided, then use the default effect provided.",
|
|
761
|
-
schema:
|
|
762
|
-
}),
|
|
761
|
+
schema: Or
|
|
762
|
+
}), ee = (e, t, r) => {
|
|
763
763
|
if (e && typeof e != "function") {
|
|
764
|
-
const a = "getField" in
|
|
764
|
+
const a = "getField" in r && r.getField?.(e), o = a && "getFieldDomain" in r && r.getFieldDomain ? r.getFieldDomain(a.name) : null;
|
|
765
765
|
if (o?.type === "coded-value") {
|
|
766
|
-
const i = o.codedValues.find((l) => l.code ===
|
|
766
|
+
const i = o.codedValues.find((l) => l.code === t);
|
|
767
767
|
return i ? i.name : null;
|
|
768
768
|
}
|
|
769
769
|
}
|
|
770
770
|
return null;
|
|
771
|
-
},
|
|
771
|
+
}, Vr = (e, t, r) => {
|
|
772
772
|
const a = e.createQuery();
|
|
773
|
-
return a.outFields = [
|
|
774
|
-
},
|
|
775
|
-
const o = a.map?.allLayers.find((h) => h.id === e), n =
|
|
773
|
+
return a.outFields = [t], a.where = r || "1=1", a.num = 1, a;
|
|
774
|
+
}, Wr = async (e, t, r, a) => {
|
|
775
|
+
const o = a.map?.allLayers.find((h) => h.id === e), n = Vr(o, t, r.where), l = (await o.queryFeatures(n)).features[0], c = l ? l.attributes[t] : null, d = ee(t, c, o) || c;
|
|
776
776
|
return {
|
|
777
777
|
tool: "getAttribute",
|
|
778
778
|
layerName: o.title ?? e,
|
|
779
|
-
summary: `${
|
|
779
|
+
summary: `${t} = ${d}`,
|
|
780
780
|
details: {
|
|
781
|
-
fieldName:
|
|
781
|
+
fieldName: t,
|
|
782
782
|
value: d,
|
|
783
|
-
where:
|
|
783
|
+
where: r.where
|
|
784
784
|
}
|
|
785
785
|
};
|
|
786
786
|
};
|
|
787
|
-
async function
|
|
788
|
-
const { mapView: o } = N(a), n = await
|
|
787
|
+
async function Br({ layerId: e, fieldName: t, query: r }, a) {
|
|
788
|
+
const { mapView: o } = N(a), n = await Wr(e, t, r, o);
|
|
789
789
|
return JSON.stringify(n, null, 2);
|
|
790
790
|
}
|
|
791
|
-
const
|
|
791
|
+
const Kr = s.object({
|
|
792
792
|
layerId: s.string().describe("The layerId of the layer containing the field from which to get a value."),
|
|
793
793
|
fieldName: s.string().describe("The name of the field/attribute from which to get a field value."),
|
|
794
794
|
query: s.object({
|
|
795
795
|
where: s.string().describe("The SQL-92 where clause representing the feature from which to get an attribute value.")
|
|
796
796
|
})
|
|
797
|
-
}),
|
|
797
|
+
}), Ur = b(Br, {
|
|
798
798
|
name: "getAttribute",
|
|
799
799
|
description: "Returns an attribute value for a given feature.",
|
|
800
|
-
schema:
|
|
801
|
-
}), pe = (e,
|
|
802
|
-
function
|
|
803
|
-
let
|
|
804
|
-
return
|
|
805
|
-
}
|
|
806
|
-
const
|
|
807
|
-
const { targetLayer:
|
|
800
|
+
schema: Kr
|
|
801
|
+
}), pe = (e, t, r) => r ? e.hasAllFeaturesInView && e.availableFields === t : e.hasAllFeatures && e.availableFields === t;
|
|
802
|
+
function te(e, t) {
|
|
803
|
+
let r = e ?? "";
|
|
804
|
+
return t != null && t && (r = r ? `(${r}) AND (${t})` : t), r || null;
|
|
805
|
+
}
|
|
806
|
+
const Hr = async (e) => {
|
|
807
|
+
const { targetLayer: t, fieldName: r, statisticType: a, mapView: o, layersAndFieldsRegistry: n, geometryFilter: i } = e, l = o.map?.allLayers.find((v) => v.id === t.layerId);
|
|
808
808
|
if (!l)
|
|
809
|
-
throw new Error(`Layer '${
|
|
810
|
-
const c = await o.whenLayerView(l), u = n.get(
|
|
809
|
+
throw new Error(`Layer '${t.layerId}' not found.`);
|
|
810
|
+
const c = await o.whenLayerView(l), u = n.get(t.layerId)?.fieldRegistry.get(r), h = u?.alias;
|
|
811
811
|
if (!u)
|
|
812
|
-
throw new Error(`Field '${
|
|
813
|
-
let
|
|
812
|
+
throw new Error(`Field '${r}' not found.`);
|
|
813
|
+
let p, f;
|
|
814
814
|
if (i) {
|
|
815
|
-
const v = await
|
|
815
|
+
const v = await re(i, o);
|
|
816
816
|
if ("error" in v)
|
|
817
817
|
throw new Error(v.error);
|
|
818
818
|
if (!v.geometry)
|
|
819
|
-
throw
|
|
820
|
-
|
|
819
|
+
throw W(i) ? new Error(`No features found matching: ${i.where}`) : new Error("Failed to create geometry");
|
|
820
|
+
W(i) ? p = {
|
|
821
821
|
geometryLayerId: i.layerId,
|
|
822
822
|
geometryWhere: i.where,
|
|
823
823
|
distance: i.distance,
|
|
824
824
|
units: i.units,
|
|
825
825
|
applied: !0
|
|
826
|
-
} :
|
|
826
|
+
} : X(i) && (p = {
|
|
827
827
|
point: i.point,
|
|
828
828
|
distance: i.distance,
|
|
829
829
|
units: i.units,
|
|
830
830
|
applied: !0
|
|
831
|
-
}), f = new
|
|
831
|
+
}), f = new U({
|
|
832
832
|
geometry: v.geometry,
|
|
833
833
|
distance: i.distance,
|
|
834
834
|
units: i.units,
|
|
835
835
|
spatialRelationship: "intersects"
|
|
836
836
|
});
|
|
837
837
|
}
|
|
838
|
-
const T = pe(c, [
|
|
839
|
-
let y = null,
|
|
838
|
+
const T = pe(c, [r], !1);
|
|
839
|
+
let y = null, w = null;
|
|
840
840
|
const E = 10;
|
|
841
841
|
if (u.type !== "geometry" && u.type !== "oid" && u.type !== "global-id")
|
|
842
842
|
try {
|
|
@@ -844,60 +844,65 @@ const Ur = async (e) => {
|
|
|
844
844
|
layer: l,
|
|
845
845
|
useFeaturesInView: T,
|
|
846
846
|
view: T ? o : void 0,
|
|
847
|
-
field:
|
|
848
|
-
sqlWhere:
|
|
847
|
+
field: r,
|
|
848
|
+
sqlWhere: te(l.definitionExpression, t.where),
|
|
849
849
|
...f && { filter: f },
|
|
850
850
|
outStatisticTypes: { include: [a] }
|
|
851
851
|
};
|
|
852
|
-
y = await
|
|
852
|
+
y = await de(v);
|
|
853
|
+
const Q = ["string", "small-integer", "integer"], V = u.domain?.type === "coded-value" ? u.domain : null;
|
|
854
|
+
(Q.includes(u.type) || V) && (w = (await ue({
|
|
853
855
|
layer: l,
|
|
854
856
|
useFeaturesInView: T,
|
|
855
857
|
view: T ? o : void 0,
|
|
856
|
-
field:
|
|
857
|
-
sqlWhere:
|
|
858
|
+
field: r,
|
|
859
|
+
sqlWhere: te(l.definitionExpression, t.where),
|
|
858
860
|
...f && { filter: f }
|
|
859
|
-
})).uniqueValueInfos.sort((
|
|
861
|
+
})).uniqueValueInfos.sort((G, it) => it.count - G.count).slice(0, E)), w && u.domain?.type === "coded-value" && (w = w.map((G) => ({
|
|
862
|
+
...G,
|
|
863
|
+
value: V ? V.getName(G.value) ?? G.value : G.value
|
|
864
|
+
})));
|
|
860
865
|
} catch (v) {
|
|
861
866
|
console.error("Statistics error:", v);
|
|
862
867
|
}
|
|
863
868
|
return {
|
|
864
869
|
tool: "getStatistics",
|
|
865
|
-
layerName: l.title ??
|
|
870
|
+
layerName: l.title ?? t.layerId,
|
|
866
871
|
summary: `${a} = ${typeof y?.[a] == "number" ? y[a] : "N/A"}`,
|
|
867
872
|
details: {
|
|
868
|
-
fieldName:
|
|
873
|
+
fieldName: r,
|
|
869
874
|
fieldAlias: h,
|
|
870
875
|
statisticType: a,
|
|
871
876
|
statistic: y?.[a] ?? null,
|
|
872
877
|
summaryStatistics: y,
|
|
873
|
-
uniqueValues:
|
|
874
|
-
where:
|
|
875
|
-
spatialFilterInfo:
|
|
878
|
+
uniqueValues: w,
|
|
879
|
+
where: t.where,
|
|
880
|
+
spatialFilterInfo: p
|
|
876
881
|
}
|
|
877
882
|
};
|
|
878
883
|
};
|
|
879
|
-
async function
|
|
884
|
+
async function Zr({
|
|
880
885
|
targetLayer: e,
|
|
881
|
-
fieldName:
|
|
882
|
-
statisticType:
|
|
886
|
+
fieldName: t,
|
|
887
|
+
statisticType: r,
|
|
883
888
|
geometryFilter: a
|
|
884
889
|
}, o) {
|
|
885
|
-
const n = S(o, "layersAndFieldsRegistry"), { mapView: i } = N(o), l = await
|
|
890
|
+
const n = S(o, "layersAndFieldsRegistry"), { mapView: i } = N(o), l = await Hr({
|
|
886
891
|
targetLayer: e,
|
|
887
|
-
fieldName:
|
|
888
|
-
statisticType:
|
|
892
|
+
fieldName: t,
|
|
893
|
+
statisticType: r,
|
|
889
894
|
mapView: i,
|
|
890
895
|
layersAndFieldsRegistry: n,
|
|
891
896
|
geometryFilter: a
|
|
892
897
|
});
|
|
893
898
|
return JSON.stringify(l, null, 2);
|
|
894
899
|
}
|
|
895
|
-
const
|
|
900
|
+
const Jr = s.object({
|
|
896
901
|
layerId: s.string().describe("The layerId of the layer containing the geometry by which to filter."),
|
|
897
902
|
where: s.string().describe("The SQL-92 where clause representing the features from which to filter."),
|
|
898
903
|
distance: s.number().optional().describe("The buffer distance around the geometry."),
|
|
899
904
|
units: A.optional().describe("The units for the distance buffer.")
|
|
900
|
-
}),
|
|
905
|
+
}), Yr = s.object({
|
|
901
906
|
point: s.object({
|
|
902
907
|
x: s.number().describe("X coordinate (longitude) from navigation result"),
|
|
903
908
|
y: s.number().describe("Y coordinate (latitude) from navigation result"),
|
|
@@ -907,17 +912,17 @@ const Zr = s.object({
|
|
|
907
912
|
}).describe("Point coordinates from a previous navigation/geocoding result"),
|
|
908
913
|
distance: s.number().optional().describe("Optional buffer distance around the point."),
|
|
909
914
|
units: A.optional().describe("The units for the distance buffer.")
|
|
910
|
-
}),
|
|
915
|
+
}), Xr = s.object({
|
|
911
916
|
targetLayer: s.object({
|
|
912
917
|
layerId: s.string().describe("The layerId of the layer containing the field from which to get a value."),
|
|
913
918
|
where: s.string().describe("The SQL-92 where clause representing the feature from which to get an attribute value.")
|
|
914
919
|
}),
|
|
915
|
-
geometryFilter: s.union([
|
|
920
|
+
geometryFilter: s.union([Jr, Yr]).optional().describe(
|
|
916
921
|
"Geometry filter for spatial queries. Use 'point' option with x/y coordinates from navigation results to find features at that location (point-in-polygon). Use 'layerId/where' option to filter by features from another layer."
|
|
917
922
|
),
|
|
918
923
|
fieldName: s.string().describe("The name of the field for which to get statistics. STRICTLY DO NOT use OBJECTID. Use any other field"),
|
|
919
924
|
statisticType: s.enum(["avg", "max", "median", "min", "stddev", "sum", "variance", "nullcount", "count"]).describe("The statistic type to calculate.")
|
|
920
|
-
}),
|
|
925
|
+
}), ea = b(Zr, {
|
|
921
926
|
name: "getStatistics",
|
|
922
927
|
description: `Computes a single aggregate statistic (max, min, avg, sum, median, stddev, variance) for a numeric field across matching features. Also returns frequency analysis for categorical fields.
|
|
923
928
|
|
|
@@ -932,20 +937,20 @@ DO NOT USE FOR:
|
|
|
932
937
|
- Simple counts of features matching a condition — use queryFeatures instead
|
|
933
938
|
|
|
934
939
|
Only call this tool when the answer requires computing an aggregate (avg, max, min, sum, median, stddev) over a field's values, not just counting or listing features.`,
|
|
935
|
-
schema:
|
|
936
|
-
}),
|
|
937
|
-
const n =
|
|
940
|
+
schema: Xr
|
|
941
|
+
}), ta = async (e, t, r, a, o) => {
|
|
942
|
+
const n = r.map?.allLayers.find((p) => p.id === e.layerId), i = await r.whenLayerView(n), l = n.title ?? e.layerId;
|
|
938
943
|
let c;
|
|
939
944
|
if (a) {
|
|
940
|
-
const
|
|
941
|
-
if ("error" in
|
|
945
|
+
const p = await re(a, r);
|
|
946
|
+
if ("error" in p)
|
|
942
947
|
return {
|
|
943
948
|
tool: "getTopFeatures",
|
|
944
949
|
layerName: l,
|
|
945
950
|
summary: "Geometry lookup failed",
|
|
946
|
-
details: { error:
|
|
951
|
+
details: { error: p.error }
|
|
947
952
|
};
|
|
948
|
-
if (!
|
|
953
|
+
if (!p.geometry)
|
|
949
954
|
return {
|
|
950
955
|
tool: "getTopFeatures",
|
|
951
956
|
layerName: l,
|
|
@@ -954,14 +959,14 @@ Only call this tool when the answer requires computing an aggregate (avg, max, m
|
|
|
954
959
|
error: `No features found matching: ${"where" in a ? a.where : "unknown criteria"}`
|
|
955
960
|
}
|
|
956
961
|
};
|
|
957
|
-
c =
|
|
958
|
-
} else o && (c =
|
|
959
|
-
const d =
|
|
962
|
+
c = p.geometry;
|
|
963
|
+
} else o && (c = r.extent.clone());
|
|
964
|
+
const d = t.groupByFields && t.groupByFields.length > 0, u = n.objectIdField, h = e.outFields.length > 2 ? e.outFields : ["*"];
|
|
960
965
|
!h.includes("*") && !h.includes(u) && h.push(u);
|
|
961
966
|
try {
|
|
962
|
-
let
|
|
967
|
+
let p;
|
|
963
968
|
if (d) {
|
|
964
|
-
const y = new
|
|
969
|
+
const y = new je({
|
|
965
970
|
where: e.where || "1=1",
|
|
966
971
|
outFields: h,
|
|
967
972
|
orderByFields: e.orderByFields,
|
|
@@ -969,70 +974,70 @@ Only call this tool when the answer requires computing an aggregate (avg, max, m
|
|
|
969
974
|
spatialRelationship: c ? "intersects" : void 0,
|
|
970
975
|
distance: a?.distance,
|
|
971
976
|
units: a?.units,
|
|
972
|
-
topFilter: new
|
|
973
|
-
topCount:
|
|
974
|
-
groupByFields:
|
|
975
|
-
orderByFields:
|
|
977
|
+
topFilter: new Me({
|
|
978
|
+
topCount: t.topCount,
|
|
979
|
+
groupByFields: t.groupByFields,
|
|
980
|
+
orderByFields: t.orderByFields
|
|
976
981
|
})
|
|
977
982
|
});
|
|
978
|
-
|
|
983
|
+
p = await n.queryTopFeatures(y);
|
|
979
984
|
} else {
|
|
980
985
|
const y = n.createQuery();
|
|
981
|
-
y.where =
|
|
982
|
-
const
|
|
986
|
+
y.where = te(n.definitionExpression, e.where || "1=1"), y.outFields = h, y.orderByFields = t.orderByFields, y.num = t.topCount, c && (y.geometry = c, y.spatialRelationship = "intersects"), a?.distance && (y.distance = a.distance), a?.units && (y.units = a.units), y.outSpatialReference = r.spatialReference;
|
|
987
|
+
const w = pe(i, e.outFields, o ?? !1);
|
|
983
988
|
try {
|
|
984
|
-
|
|
989
|
+
p = w ? await i.queryFeatures(y) : await n.queryFeatures(y);
|
|
985
990
|
} catch (E) {
|
|
986
|
-
console.warn("Client-side query failed, falling back to server:", E),
|
|
991
|
+
console.warn("Client-side query failed, falling back to server:", E), p = await n.queryFeatures(y);
|
|
987
992
|
}
|
|
988
993
|
}
|
|
989
|
-
const f =
|
|
990
|
-
const
|
|
994
|
+
const f = p.features.map((y) => y.attributes[u]), T = p.features.map((y) => {
|
|
995
|
+
const w = y.attributes, E = {};
|
|
991
996
|
return n.fields.forEach(($) => {
|
|
992
997
|
if ($.name === n.objectIdField) {
|
|
993
|
-
E[$.name] =
|
|
998
|
+
E[$.name] = w[$.name];
|
|
994
999
|
return;
|
|
995
1000
|
}
|
|
996
|
-
const v =
|
|
997
|
-
E[
|
|
1001
|
+
const v = w[$.name], Q = ee($.name, v, n), V = $.alias || $.name;
|
|
1002
|
+
E[V] = Q ?? v;
|
|
998
1003
|
}), E;
|
|
999
1004
|
});
|
|
1000
1005
|
return {
|
|
1001
1006
|
tool: "getTopFeatures",
|
|
1002
1007
|
layerName: l,
|
|
1003
|
-
summary: `Top ${
|
|
1008
|
+
summary: `Top ${t.topCount} features extracted`,
|
|
1004
1009
|
details: {
|
|
1005
|
-
topCount:
|
|
1010
|
+
topCount: t.topCount,
|
|
1006
1011
|
attributes: T,
|
|
1007
1012
|
objectIds: f,
|
|
1008
1013
|
objectIdField: u,
|
|
1009
1014
|
where: e.where,
|
|
1010
|
-
orderByFields:
|
|
1011
|
-
...d && { groupByFields:
|
|
1015
|
+
orderByFields: t.orderByFields,
|
|
1016
|
+
...d && { groupByFields: t.groupByFields }
|
|
1012
1017
|
}
|
|
1013
1018
|
};
|
|
1014
|
-
} catch (
|
|
1019
|
+
} catch (p) {
|
|
1015
1020
|
return {
|
|
1016
1021
|
tool: "getTopFeatures",
|
|
1017
1022
|
layerName: l,
|
|
1018
1023
|
summary: "Query failed",
|
|
1019
|
-
details: { error:
|
|
1024
|
+
details: { error: p instanceof Error ? p.message : String(p) }
|
|
1020
1025
|
};
|
|
1021
1026
|
}
|
|
1022
|
-
},
|
|
1027
|
+
}, ra = async ({
|
|
1023
1028
|
targetLayer: e,
|
|
1024
|
-
topFilter:
|
|
1025
|
-
geometryFilter:
|
|
1029
|
+
topFilter: t,
|
|
1030
|
+
geometryFilter: r,
|
|
1026
1031
|
useCurrentExtent: a
|
|
1027
1032
|
}, o) => {
|
|
1028
|
-
const { mapView: n } = N(o), i = await
|
|
1033
|
+
const { mapView: n } = N(o), i = await ta(e, t, n, r, a);
|
|
1029
1034
|
return JSON.stringify(i, null, 2);
|
|
1030
|
-
},
|
|
1035
|
+
}, aa = s.object({
|
|
1031
1036
|
layerId: s.string().describe("The layerId of the layer containing the geometry by which to filter."),
|
|
1032
1037
|
where: s.string().describe("The SQL-92 where clause representing the features from which to filter."),
|
|
1033
1038
|
distance: s.number().optional().describe("The buffer distance around the geometry."),
|
|
1034
1039
|
units: A.optional().describe("The units for the distance buffer.")
|
|
1035
|
-
}),
|
|
1040
|
+
}), oa = s.object({
|
|
1036
1041
|
point: s.object({
|
|
1037
1042
|
x: s.number().describe("X coordinate (longitude) from navigation result"),
|
|
1038
1043
|
y: s.number().describe("Y coordinate (latitude) from navigation result"),
|
|
@@ -1042,7 +1047,7 @@ Only call this tool when the answer requires computing an aggregate (avg, max, m
|
|
|
1042
1047
|
}).describe("Point coordinates from a previous navigation/geocoding result"),
|
|
1043
1048
|
distance: s.number().optional().describe("Optional buffer distance around the point."),
|
|
1044
1049
|
units: A.optional().describe("The units for the distance buffer.")
|
|
1045
|
-
}),
|
|
1050
|
+
}), na = s.object({
|
|
1046
1051
|
targetLayer: s.object({
|
|
1047
1052
|
layerId: s.string().describe("The layerId of the layer containing the field from which to get a value."),
|
|
1048
1053
|
where: s.string().describe("The SQL-92 where clause representing the feature from which to get an attribute value."),
|
|
@@ -1053,7 +1058,7 @@ Only call this tool when the answer requires computing an aggregate (avg, max, m
|
|
|
1053
1058
|
).default("*")
|
|
1054
1059
|
)
|
|
1055
1060
|
}),
|
|
1056
|
-
geometryFilter: s.union([
|
|
1061
|
+
geometryFilter: s.union([aa, oa]).optional().describe(
|
|
1057
1062
|
"Geometry filter for spatial queries. Use 'point' option with x/y coordinates from navigation results to find features at that location (point-in-polygon). Use 'layerId/where' option to filter by features from another layer."
|
|
1058
1063
|
),
|
|
1059
1064
|
topFilter: s.object({
|
|
@@ -1066,55 +1071,55 @@ Only call this tool when the answer requires computing an aggregate (avg, max, m
|
|
|
1066
1071
|
useCurrentExtent: s.boolean().optional().describe(
|
|
1067
1072
|
"Set to true ONLY when user explicitly asks about features 'in my view', 'on my map', 'I am looking at'. Default is false (queries entire layer)."
|
|
1068
1073
|
)
|
|
1069
|
-
}),
|
|
1074
|
+
}), sa = b(ra, {
|
|
1070
1075
|
name: "getTopFeatures",
|
|
1071
1076
|
description: 'Returns top N features ranked by an existing field value. Use for "highest", "lowest", "top N" questions where ranking is based on a field that already exists in the data (e.g., population, value, date, depth). orderByFields must be actual field names with ASC/DESC. Do NOT use aggregate functions like COUNT(), SUM(), AVG() - those require getStatistics.',
|
|
1072
|
-
schema:
|
|
1073
|
-
}),
|
|
1074
|
-
const o =
|
|
1077
|
+
schema: na
|
|
1078
|
+
}), se = 25, ia = async (e, t, r, a) => {
|
|
1079
|
+
const o = t.map?.allLayers.find((y) => y.id === e.layerId), n = await t.whenLayerView(o), i = o.title ?? e.layerId;
|
|
1075
1080
|
let l;
|
|
1076
|
-
if (
|
|
1077
|
-
const y = await
|
|
1081
|
+
if (r) {
|
|
1082
|
+
const y = await re(r, t);
|
|
1078
1083
|
if ("error" in y) {
|
|
1079
|
-
const
|
|
1080
|
-
return
|
|
1084
|
+
const w = { error: y.error };
|
|
1085
|
+
return W(r) ? (w.geometryLayerId = r.layerId, w.geometryWhere = r.where) : X(r) && (w.point = r.point), {
|
|
1081
1086
|
tool: "queryFeatures",
|
|
1082
1087
|
layerName: i,
|
|
1083
1088
|
summary: "Geometry lookup failed",
|
|
1084
|
-
details:
|
|
1089
|
+
details: w
|
|
1085
1090
|
};
|
|
1086
1091
|
}
|
|
1087
1092
|
if (!y.geometry) {
|
|
1088
|
-
const
|
|
1089
|
-
return
|
|
1093
|
+
const w = {};
|
|
1094
|
+
return W(r) ? (w.error = `No features found matching: ${r.where}`, w.geometryLayerId = r.layerId, w.geometryWhere = r.where) : X(r) && (w.error = "Failed to create point geometry", w.point = r.point), {
|
|
1090
1095
|
tool: "queryFeatures",
|
|
1091
1096
|
layerName: i,
|
|
1092
1097
|
summary: "No features found for geometry filter",
|
|
1093
|
-
details:
|
|
1098
|
+
details: w
|
|
1094
1099
|
};
|
|
1095
1100
|
}
|
|
1096
1101
|
l = y.geometry;
|
|
1097
|
-
} else a && (l =
|
|
1102
|
+
} else a && (l = t.extent.clone());
|
|
1098
1103
|
const c = pe(n, e.outFields, a ?? !1), d = o.createQuery();
|
|
1099
|
-
d.where =
|
|
1104
|
+
d.where = te(o.definitionExpression, e.where || "1=1"), d.outFields = e.outFields.length ? e.outFields : ["*"], d.orderByFields = e.orderByFields, l && (d.geometry = l, d.spatialRelationship = "intersects"), r?.distance && (d.distance = r.distance), r?.units && (d.units = r.units), d.outSpatialReference = t.spatialReference;
|
|
1100
1105
|
let u, h;
|
|
1101
1106
|
try {
|
|
1102
|
-
u = c ? await n.queryFeatureCount(d) : await o.queryFeatureCount(d), u > 0 && u <=
|
|
1103
|
-
const
|
|
1107
|
+
u = c ? await n.queryFeatureCount(d) : await o.queryFeatureCount(d), u > 0 && u <= se && (h = c ? await n.queryFeatures(d) : await o.queryFeatures(d), h && h.features.forEach((y) => {
|
|
1108
|
+
const w = y.attributes;
|
|
1104
1109
|
o.fields.forEach((E) => {
|
|
1105
|
-
const $ =
|
|
1106
|
-
v && (
|
|
1110
|
+
const $ = w[E.name], v = ee(E.name, $, o);
|
|
1111
|
+
v && (w[E.name] = v);
|
|
1107
1112
|
});
|
|
1108
1113
|
}));
|
|
1109
1114
|
} catch (y) {
|
|
1110
|
-
console.warn("Client-side query failed, falling back to server:", y), u = await o.queryFeatureCount(d), u > 0 && u <=
|
|
1115
|
+
console.warn("Client-side query failed, falling back to server:", y), u = await o.queryFeatureCount(d), u > 0 && u <= se && (h = await o.queryFeatures(d), h && h.features.forEach((w) => {
|
|
1111
1116
|
o.fields.forEach((E) => {
|
|
1112
|
-
const $ =
|
|
1113
|
-
v && (
|
|
1117
|
+
const $ = w.attributes[E.name], v = ee(E.name, $, o);
|
|
1118
|
+
v && (w.attributes[E.name] = v);
|
|
1114
1119
|
});
|
|
1115
1120
|
}));
|
|
1116
1121
|
}
|
|
1117
|
-
const
|
|
1122
|
+
const p = o.objectIdField, f = h?.features.map((y) => y.attributes[p]), T = h?.features.map((y) => y.attributes);
|
|
1118
1123
|
return {
|
|
1119
1124
|
tool: "queryFeatures",
|
|
1120
1125
|
layerName: i,
|
|
@@ -1124,28 +1129,28 @@ Only call this tool when the answer requires computing an aggregate (avg, max, m
|
|
|
1124
1129
|
where: e.where,
|
|
1125
1130
|
orderByFields: e.orderByFields,
|
|
1126
1131
|
outFields: e.outFields,
|
|
1127
|
-
...f && { objectIds: f, objectIdField:
|
|
1132
|
+
...f && { objectIds: f, objectIdField: p },
|
|
1128
1133
|
...T && { attributes: T },
|
|
1129
|
-
...u >
|
|
1134
|
+
...u > se && {
|
|
1130
1135
|
note: `${u} features found.`
|
|
1131
1136
|
}
|
|
1132
1137
|
}
|
|
1133
1138
|
};
|
|
1134
1139
|
};
|
|
1135
|
-
async function
|
|
1140
|
+
async function la({
|
|
1136
1141
|
targetLayer: e,
|
|
1137
|
-
geometryFilter:
|
|
1138
|
-
useCurrentExtent:
|
|
1142
|
+
geometryFilter: t,
|
|
1143
|
+
useCurrentExtent: r
|
|
1139
1144
|
}, a) {
|
|
1140
|
-
const { mapView: o } = N(a), n = await
|
|
1145
|
+
const { mapView: o } = N(a), n = await ia(e, o, t, r);
|
|
1141
1146
|
return JSON.stringify(n, null, 2);
|
|
1142
1147
|
}
|
|
1143
|
-
const
|
|
1148
|
+
const ca = s.object({
|
|
1144
1149
|
layerId: s.string().describe("The layerId of the layer containing the geometry by which to filter."),
|
|
1145
1150
|
where: s.string().describe("The SQL-92 where clause representing the features from which to filter."),
|
|
1146
1151
|
distance: s.number().optional().describe("The buffer distance around the geometry."),
|
|
1147
1152
|
units: A.optional().describe("The units for the distance buffer.")
|
|
1148
|
-
}),
|
|
1153
|
+
}), da = s.object({
|
|
1149
1154
|
point: s.object({
|
|
1150
1155
|
x: s.number().describe("X coordinate (longitude) from navigation result"),
|
|
1151
1156
|
y: s.number().describe("Y coordinate (latitude) from navigation result"),
|
|
@@ -1155,7 +1160,7 @@ const la = s.object({
|
|
|
1155
1160
|
}).describe("Point coordinates from a previous navigation/geocoding result"),
|
|
1156
1161
|
distance: s.number().optional().describe("Optional buffer distance around the point."),
|
|
1157
1162
|
units: A.optional().describe("The units for the distance buffer.")
|
|
1158
|
-
}),
|
|
1163
|
+
}), ua = s.object({
|
|
1159
1164
|
targetLayer: s.object({
|
|
1160
1165
|
layerId: s.string().describe("The layerId of the layer containing the field from which to get a value."),
|
|
1161
1166
|
where: s.string().describe(
|
|
@@ -1168,13 +1173,13 @@ const la = s.object({
|
|
|
1168
1173
|
).default("*")
|
|
1169
1174
|
)
|
|
1170
1175
|
}),
|
|
1171
|
-
geometryFilter: s.union([
|
|
1176
|
+
geometryFilter: s.union([ca, da]).optional().describe(
|
|
1172
1177
|
"Geometry filter for spatial queries. Use 'point' option with x/y coordinates from navigation results to find features at that location (point-in-polygon). Use 'layerId/where' option to filter by features from another layer."
|
|
1173
1178
|
),
|
|
1174
1179
|
useCurrentExtent: s.boolean().optional().describe(
|
|
1175
1180
|
"Set to true ONLY when user explicitly asks about features 'in my view', 'on my map', 'I am looking at'. Default is false (queries entire layer)."
|
|
1176
1181
|
)
|
|
1177
|
-
}),
|
|
1182
|
+
}), ha = b(la, {
|
|
1178
1183
|
name: "queryFeatures",
|
|
1179
1184
|
description: `Queries features from a layer. Returns the total count of matching features, plus individual feature attributes if ≤25 features match.
|
|
1180
1185
|
|
|
@@ -1186,16 +1191,16 @@ USE THIS TOOL FOR:
|
|
|
1186
1191
|
- Any question where the user wants to SEE or COUNT matching features
|
|
1187
1192
|
|
|
1188
1193
|
This is the DEFAULT tool for most queries. When in doubt, use this tool.`,
|
|
1189
|
-
schema:
|
|
1190
|
-
}),
|
|
1191
|
-
const e = (/* @__PURE__ */ new Date()).getTimezoneOffset(),
|
|
1194
|
+
schema: ua
|
|
1195
|
+
}), Oe = [Ur, ea, sa, ha], Qe = [Qr, zr, Ar], ae = () => {
|
|
1196
|
+
const e = (/* @__PURE__ */ new Date()).getTimezoneOffset(), t = e <= 0 ? "+" : "-", r = Math.floor(Math.abs(e) / 60).toString().padStart(2, "0"), a = (Math.abs(e) % 60).toString().padStart(2, "0"), o = `${t}${r}:${a}`;
|
|
1192
1197
|
return { userTimezone: Intl.DateTimeFormat().resolvedOptions().timeZone, userTimezoneOffset: o };
|
|
1193
|
-
},
|
|
1194
|
-
await
|
|
1198
|
+
}, ma = async (e, t) => {
|
|
1199
|
+
await m({ text: "Requesting LLM for layer filter results" }, t);
|
|
1195
1200
|
const a = await F("data_explore_filter_prompt");
|
|
1196
|
-
if (!
|
|
1201
|
+
if (!t?.configurable)
|
|
1197
1202
|
throw new Error("config.configurable is required for layer filter tools");
|
|
1198
|
-
const { userTimezone: o, userTimezoneOffset: n } =
|
|
1203
|
+
const { userTimezone: o, userTimezoneOffset: n } = ae(), i = {
|
|
1199
1204
|
layerFieldInfo: e.layerFieldInfo,
|
|
1200
1205
|
userTimezone: o,
|
|
1201
1206
|
userTimezoneOffset: n,
|
|
@@ -1205,22 +1210,22 @@ This is the DEFAULT tool for most queries. When in doubt, use this tool.`,
|
|
|
1205
1210
|
modelTier: "advanced",
|
|
1206
1211
|
messages: x(e.messages),
|
|
1207
1212
|
inputVariables: i,
|
|
1208
|
-
tools:
|
|
1213
|
+
tools: Qe
|
|
1209
1214
|
}), c = [...e.messages, l];
|
|
1210
1215
|
if (!((l.tool_calls?.length ?? 0) > 0))
|
|
1211
|
-
return await
|
|
1216
|
+
return await m({ text: "LLM determined no filter changes needed" }, t), {
|
|
1212
1217
|
...e,
|
|
1213
1218
|
messages: c
|
|
1214
1219
|
// Don't overwrite outputMessage if query already set it
|
|
1215
1220
|
};
|
|
1216
1221
|
const u = [...c, l], h = l.content.toString();
|
|
1217
|
-
return await
|
|
1218
|
-
}, pa = async (e,
|
|
1219
|
-
await
|
|
1222
|
+
return await H(l, t), { ...e, messages: u, outputMessage: h };
|
|
1223
|
+
}, pa = async (e, t) => {
|
|
1224
|
+
await m({ text: "Requesting LLM for layer query results" }, t);
|
|
1220
1225
|
const a = await F("data_explore_query_prompt");
|
|
1221
|
-
if (!
|
|
1226
|
+
if (!t?.configurable)
|
|
1222
1227
|
throw new Error("config.configurable is required for layer query tools");
|
|
1223
|
-
const { userTimezone: o, userTimezoneOffset: n } =
|
|
1228
|
+
const { userTimezone: o, userTimezoneOffset: n } = ae(), i = {
|
|
1224
1229
|
layerFieldInfo: e.layerFieldInfo,
|
|
1225
1230
|
userTimezone: o,
|
|
1226
1231
|
userTimezoneOffset: n
|
|
@@ -1229,52 +1234,52 @@ This is the DEFAULT tool for most queries. When in doubt, use this tool.`,
|
|
|
1229
1234
|
modelTier: "advanced",
|
|
1230
1235
|
messages: x(e.messages),
|
|
1231
1236
|
inputVariables: i,
|
|
1232
|
-
tools:
|
|
1237
|
+
tools: Oe
|
|
1233
1238
|
}), c = [...e.messages, l], d = l.content.toString();
|
|
1234
|
-
return await
|
|
1235
|
-
},
|
|
1239
|
+
return await H(l, t), { ...e, messages: c, outputMessage: d };
|
|
1240
|
+
}, ya = async (e, t) => {
|
|
1236
1241
|
try {
|
|
1237
|
-
await
|
|
1242
|
+
await m({ text: "Requesting LLM for summary on query results" }, t);
|
|
1238
1243
|
const a = await F("summarize_query_response_prompt"), o = {
|
|
1239
1244
|
queryResponse: e.queryResponse
|
|
1240
|
-
}, n = await
|
|
1245
|
+
}, n = await ie({
|
|
1241
1246
|
promptText: a,
|
|
1242
1247
|
messages: x(e.messages),
|
|
1243
1248
|
inputVariables: o
|
|
1244
|
-
}), i = typeof n == "string" ? n : n.content, l = new
|
|
1245
|
-
return await
|
|
1249
|
+
}), i = typeof n == "string" ? n : n.content, l = new K(i);
|
|
1250
|
+
return await m({ text: `Received response from LLM: ${i}` }, t), {
|
|
1246
1251
|
...e,
|
|
1247
1252
|
outputMessage: i,
|
|
1248
1253
|
messages: [...e.messages, l]
|
|
1249
1254
|
};
|
|
1250
|
-
} catch (
|
|
1251
|
-
throw await
|
|
1255
|
+
} catch (r) {
|
|
1256
|
+
throw await m({ text: "Error during filter LLM request" }, t), new Error(`Error during filter LLM request: ${r instanceof Error ? r.message : String(r)}`);
|
|
1252
1257
|
}
|
|
1253
1258
|
};
|
|
1254
|
-
async function
|
|
1255
|
-
const a = await new P(
|
|
1259
|
+
async function fa(e, t) {
|
|
1260
|
+
const a = await new P(Qe).invoke(
|
|
1256
1261
|
{
|
|
1257
1262
|
messages: x(e.messages)
|
|
1258
1263
|
},
|
|
1259
|
-
|
|
1264
|
+
t
|
|
1260
1265
|
), o = [...e.messages, ...a.messages], n = a.messages.map(
|
|
1261
|
-
(l) => new
|
|
1266
|
+
(l) => new K({
|
|
1262
1267
|
content: l.content,
|
|
1263
1268
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1264
1269
|
additional_kwargs: l.additional_kwargs
|
|
1265
1270
|
})
|
|
1266
1271
|
);
|
|
1267
|
-
await
|
|
1272
|
+
await m(
|
|
1268
1273
|
{ text: `Finished executing layer filter tool: ${a.messages.map((l) => l.content).join(", ")}` },
|
|
1269
|
-
|
|
1274
|
+
t
|
|
1270
1275
|
);
|
|
1271
1276
|
const i = [...o, ...n];
|
|
1272
1277
|
return { ...e, messages: i };
|
|
1273
1278
|
}
|
|
1274
|
-
const
|
|
1275
|
-
async function
|
|
1276
|
-
const { messages:
|
|
1277
|
-
for (const i of
|
|
1279
|
+
const ga = new P(Oe);
|
|
1280
|
+
async function wa(e, t) {
|
|
1281
|
+
const { messages: r } = await ga.invoke({ messages: x(e.messages) }, t), a = [], o = [];
|
|
1282
|
+
for (const i of r) {
|
|
1278
1283
|
const l = i.content;
|
|
1279
1284
|
let c;
|
|
1280
1285
|
typeof l != "string" && (c = {
|
|
@@ -1300,52 +1305,59 @@ async function ga(e, r) {
|
|
|
1300
1305
|
}
|
|
1301
1306
|
a.push(c), c.details && typeof c.details == "object" && "error" in c.details ? o.push(`- ${c.tool}: Error - ${String(c.details.error)}`) : o.push(`- ${c.layerName}: ${c.summary}`);
|
|
1302
1307
|
}
|
|
1303
|
-
const n = [...e.messages, ...
|
|
1304
|
-
return await
|
|
1308
|
+
const n = [...e.messages, ...r];
|
|
1309
|
+
return await m({ text: `Finished executing layer query tool: ${o.join(", ")}` }, t), {
|
|
1305
1310
|
...e,
|
|
1306
1311
|
messages: n,
|
|
1307
1312
|
queryResponse: a
|
|
1308
1313
|
};
|
|
1309
1314
|
}
|
|
1310
|
-
const
|
|
1311
|
-
let
|
|
1315
|
+
const ba = 10, Sa = ["string", "small-integer", "integer"], va = async (e, t) => {
|
|
1316
|
+
let r = null, a = null;
|
|
1312
1317
|
try {
|
|
1313
|
-
|
|
1318
|
+
if (t.type !== "geometry" && t.type !== "oid" && t.type !== "global-id") {
|
|
1319
|
+
r = await de({ layer: e, field: t.name });
|
|
1320
|
+
const o = t.domain?.type === "coded-value" ? t.domain : null;
|
|
1321
|
+
(Sa.includes(t.type) || o) && (a = (await ue({ layer: e, field: t.name })).uniqueValueInfos.sort((n, i) => i.count - n.count).slice(0, ba), o && (a = a.map((n) => ({
|
|
1322
|
+
...n,
|
|
1323
|
+
value: o.getName(n.value) ?? n.value
|
|
1324
|
+
}))));
|
|
1325
|
+
}
|
|
1314
1326
|
} catch (o) {
|
|
1315
|
-
console.error(`Error fetching statistics for field ${
|
|
1327
|
+
console.error(`Error fetching statistics for field ${t.name}:`, o);
|
|
1316
1328
|
}
|
|
1317
1329
|
return {
|
|
1318
|
-
summaryStatistics:
|
|
1330
|
+
summaryStatistics: r,
|
|
1319
1331
|
uniqueValues: a
|
|
1320
1332
|
};
|
|
1321
1333
|
};
|
|
1322
|
-
async function
|
|
1334
|
+
async function ye(e, t, r) {
|
|
1323
1335
|
const a = [], o = [];
|
|
1324
1336
|
for (const n of e) {
|
|
1325
|
-
let i = function(
|
|
1326
|
-
const f =
|
|
1337
|
+
let i = function(p) {
|
|
1338
|
+
const f = t.get(p)?.layerItem;
|
|
1327
1339
|
return f ? [
|
|
1328
1340
|
f.name && `Name: ${f.name}`,
|
|
1329
1341
|
f.title && `Title: ${f.title}`,
|
|
1330
1342
|
f.description && `Description: ${f.description}`
|
|
1331
|
-
].filter(Boolean).join(" | ") :
|
|
1343
|
+
].filter(Boolean).join(" | ") : p;
|
|
1332
1344
|
};
|
|
1333
|
-
const { layerId: l, results: c } = n, d =
|
|
1345
|
+
const { layerId: l, results: c } = n, d = r.map?.allLayers.find((p) => p.id === l), u = t.get(l)?.fieldRegistry;
|
|
1334
1346
|
if (!u)
|
|
1335
1347
|
continue;
|
|
1336
|
-
let h = a.find((
|
|
1348
|
+
let h = a.find((p) => p.layerId === l);
|
|
1337
1349
|
h || (h = {
|
|
1338
1350
|
layerId: l,
|
|
1339
1351
|
layerSummary: i(l),
|
|
1340
1352
|
fieldInfos: []
|
|
1341
1353
|
}, a.push(h));
|
|
1342
|
-
for (const
|
|
1343
|
-
const f = u.get(
|
|
1354
|
+
for (const p of c) {
|
|
1355
|
+
const f = u.get(p.name);
|
|
1344
1356
|
if (!f)
|
|
1345
1357
|
continue;
|
|
1346
1358
|
if (!f.statistics) {
|
|
1347
|
-
const y =
|
|
1348
|
-
u.set(f.name, { ...f, statistics:
|
|
1359
|
+
const y = va(d, f).then((w) => {
|
|
1360
|
+
u.set(f.name, { ...f, statistics: w }), f.statistics = w;
|
|
1349
1361
|
});
|
|
1350
1362
|
o.push(y);
|
|
1351
1363
|
}
|
|
@@ -1354,26 +1366,26 @@ async function me(e, r, t) {
|
|
|
1354
1366
|
}
|
|
1355
1367
|
return await Promise.all(o), a;
|
|
1356
1368
|
}
|
|
1357
|
-
const
|
|
1369
|
+
const Ta = async (e, t) => {
|
|
1358
1370
|
try {
|
|
1359
|
-
await
|
|
1360
|
-
const
|
|
1361
|
-
return await
|
|
1362
|
-
} catch (
|
|
1363
|
-
throw await
|
|
1371
|
+
await m({ text: "Getting statistics for vector search results" }, t);
|
|
1372
|
+
const r = S(t, "layersAndFieldsRegistry"), { mapView: a } = N(t), o = await ye(e.vectorSearchFieldResults, r, a);
|
|
1373
|
+
return await m({ text: "Statistics retrieved" }, t), { ...e, layerFieldInfo: o };
|
|
1374
|
+
} catch (r) {
|
|
1375
|
+
throw await m({ text: "Error during fetching statistics" }, t), new Error(`Error during fetching statistics: ${r instanceof Error ? r.message : String(r)}`);
|
|
1364
1376
|
}
|
|
1365
|
-
},
|
|
1377
|
+
}, Le = 0.7, xa = 10, Ea = async (e, t) => {
|
|
1366
1378
|
try {
|
|
1367
|
-
const
|
|
1368
|
-
await
|
|
1369
|
-
const a = S(
|
|
1370
|
-
text:
|
|
1379
|
+
const r = C(e.messages);
|
|
1380
|
+
await m({ text: "Similarity search to find fields" }, t);
|
|
1381
|
+
const a = S(t, "fieldSearch"), o = S(t, "layersAndFieldsRegistry"), n = S(t, "embeddingCache"), i = await a.searchFields({
|
|
1382
|
+
text: r,
|
|
1371
1383
|
layerIds: e.vectorSearchLayerIds,
|
|
1372
|
-
minScore:
|
|
1373
|
-
topResults:
|
|
1384
|
+
minScore: Le,
|
|
1385
|
+
topResults: xa,
|
|
1374
1386
|
embeddingCache: n
|
|
1375
1387
|
}), l = i.map(({ layerId: d, results: u }) => {
|
|
1376
|
-
const h = u.map((
|
|
1388
|
+
const h = u.map((p) => ` - ${p.name} (${p.score.toFixed(2)})`).join(`
|
|
1377
1389
|
`);
|
|
1378
1390
|
return `${o.get(d)?.layerItem.name ?? d}:
|
|
1379
1391
|
${h}`;
|
|
@@ -1381,51 +1393,51 @@ ${h}`;
|
|
|
1381
1393
|
`);
|
|
1382
1394
|
let c;
|
|
1383
1395
|
return i.length > 0 ? c = `Vector search completed. Matching layers and fields with scores:
|
|
1384
|
-
${l}` : c = `No vector search results found for score over ${
|
|
1396
|
+
${l}` : c = `No vector search results found for score over ${Le}.`, await m({ text: c }, t), {
|
|
1385
1397
|
...e,
|
|
1386
1398
|
vectorSearchFieldResults: i
|
|
1387
1399
|
};
|
|
1388
|
-
} catch (
|
|
1389
|
-
throw await
|
|
1390
|
-
{ text: `Error during vector search: ${
|
|
1391
|
-
|
|
1392
|
-
), new Error(`Vector search failed: ${
|
|
1400
|
+
} catch (r) {
|
|
1401
|
+
throw await m(
|
|
1402
|
+
{ text: `Error during vector search: ${r instanceof Error ? r.message : String(r)}` },
|
|
1403
|
+
t
|
|
1404
|
+
), new Error(`Vector search failed: ${r instanceof Error ? r.message : String(r)}`);
|
|
1393
1405
|
}
|
|
1394
|
-
},
|
|
1406
|
+
}, $a = 0.7, Fa = async (e, t) => {
|
|
1395
1407
|
try {
|
|
1396
|
-
const
|
|
1397
|
-
await
|
|
1398
|
-
const a = S(
|
|
1399
|
-
text:
|
|
1400
|
-
minScore:
|
|
1408
|
+
const r = C(e.messages);
|
|
1409
|
+
await m({ text: `Similarity search to find layers: ${r}` }, t);
|
|
1410
|
+
const a = S(t, "layerSearch"), o = S(t, "layersAndFieldsRegistry"), n = S(t, "embeddingCache"), i = await a.searchLayers({
|
|
1411
|
+
text: r,
|
|
1412
|
+
minScore: $a,
|
|
1401
1413
|
embeddingCache: n
|
|
1402
1414
|
}), l = i.map((u) => u.id), c = i.map(({ id: u, score: h }) => `${o.get(u)?.layerItem.name ?? u} (${h.toFixed(2)})`).join(`
|
|
1403
1415
|
`);
|
|
1404
1416
|
let d;
|
|
1405
1417
|
return l.length > 0 ? d = `Vector search completed. Matching layers with scores:
|
|
1406
|
-
${c}` : d = "Vector search completed. No matching layers found.", await
|
|
1418
|
+
${c}` : d = "Vector search completed. No matching layers found.", await m({ text: d }, t), {
|
|
1407
1419
|
...e,
|
|
1408
1420
|
vectorSearchLayerIds: l
|
|
1409
1421
|
};
|
|
1410
|
-
} catch (
|
|
1411
|
-
throw await
|
|
1412
|
-
{ text: `Error during vector search: ${
|
|
1413
|
-
|
|
1414
|
-
), new Error(`Vector search failed: ${
|
|
1422
|
+
} catch (r) {
|
|
1423
|
+
throw await m(
|
|
1424
|
+
{ text: `Error during vector search: ${r instanceof Error ? r.message : String(r)}` },
|
|
1425
|
+
t
|
|
1426
|
+
), new Error(`Vector search failed: ${r instanceof Error ? r.message : String(r)}`);
|
|
1415
1427
|
}
|
|
1416
|
-
},
|
|
1428
|
+
}, Ra = (e, t) => D(["layerSearch", "fieldSearch", "layersAndFieldsRegistry"], "Data Exploration Agent")(
|
|
1417
1429
|
e,
|
|
1418
|
-
|
|
1419
|
-
),
|
|
1430
|
+
t
|
|
1431
|
+
), La = () => new _(Ge).addNode("requireDataExplorationServices", Ra).addNode("vectorSearchLayers", Fa).addNode("vectorSearchFields", Ea).addNode("fieldStatistics", Ta).addNode("queryAgent", pa).addNode("queryTools", wa).addNode("summarizeQueryResponseLLM", ya).addNode("filterAgent", ma).addNode("filterTools", fa).addNode("earlyExit", Lr).addEdge(j, "requireDataExplorationServices").addEdge("requireDataExplorationServices", "vectorSearchLayers").addConditionalEdges(
|
|
1420
1432
|
"vectorSearchLayers",
|
|
1421
|
-
(
|
|
1433
|
+
(t) => t.vectorSearchLayerIds.length ? "vectorSearchFields" : "earlyExit"
|
|
1422
1434
|
).addConditionalEdges(
|
|
1423
1435
|
"vectorSearchFields",
|
|
1424
|
-
(
|
|
1425
|
-
).addEdge("fieldStatistics", "queryAgent").addConditionalEdges("queryAgent", (
|
|
1436
|
+
(t) => t.vectorSearchFieldResults.length ? "fieldStatistics" : "earlyExit"
|
|
1437
|
+
).addEdge("fieldStatistics", "queryAgent").addConditionalEdges("queryAgent", (t) => (t.messages[t.messages.length - 1]?.tool_calls?.length ?? 0) > 0 ? "queryTools" : "filterAgent").addConditionalEdges(
|
|
1426
1438
|
"queryTools",
|
|
1427
|
-
(
|
|
1428
|
-
).addEdge("summarizeQueryResponseLLM", "filterAgent").addConditionalEdges("filterAgent", (
|
|
1439
|
+
(t) => t.queryResponse.length ? "summarizeQueryResponseLLM" : "filterAgent"
|
|
1440
|
+
).addEdge("summarizeQueryResponseLLM", "filterAgent").addConditionalEdges("filterAgent", (t) => (t.messages[t.messages.length - 1]?.tool_calls?.length ?? 0) > 0 ? "filterTools" : R).addEdge("filterTools", R).addEdge("earlyExit", R), Ia = String.raw`- **data exploration** — User is asking about the feature layer’s data (e.g. counts, summaries, statistics, field values), either for all features, a subset based on a condition, or for a subset based on the current view. And/Or user wants to include or exclude features based on field values, or visually style features differently (e.g., highlight or deemphasize them).
|
|
1429
1441
|
The Data Exploration Agent will automatically zoom to the affected features for action taken by this agent. In this case, no need to call navigation tool separately.
|
|
1430
1442
|
_Example: “Only show stations where Brand is Shell”_
|
|
1431
1443
|
_Example: “Make Shell stations stand out on the map”_
|
|
@@ -1433,24 +1445,24 @@ ${c}` : d = "Vector search completed. No matching layers found.", await p({ text
|
|
|
1433
1445
|
This also includes questions that ask which feature meets a given condition or where a particular feature in the data is located (e.g., “Where is the spring with the highest elevation?”). However, this agent does not handle addresses.
|
|
1434
1446
|
_Example: “How many features are there?”_
|
|
1435
1447
|
_Example: “What’s the average population?”_
|
|
1436
|
-
_Example: “Which values are in the status field?”_`,
|
|
1448
|
+
_Example: “Which values are in the status field?”_`, qi = {
|
|
1437
1449
|
id: "dataExploration",
|
|
1438
1450
|
name: "Data Exploration Agent",
|
|
1439
|
-
description:
|
|
1440
|
-
createGraph:
|
|
1441
|
-
workspace:
|
|
1442
|
-
},
|
|
1451
|
+
description: Ia,
|
|
1452
|
+
createGraph: La,
|
|
1453
|
+
workspace: Ge
|
|
1454
|
+
}, Ie = 0.7, qa = 10, Ca = async (e, t) => {
|
|
1443
1455
|
try {
|
|
1444
|
-
const
|
|
1445
|
-
await
|
|
1446
|
-
const a = S(
|
|
1447
|
-
text:
|
|
1456
|
+
const r = C(e.messages);
|
|
1457
|
+
await m({ text: "Similarity search to find fields" }, t);
|
|
1458
|
+
const a = S(t, "fieldSearch"), o = S(t, "layersAndFieldsRegistry"), n = S(t, "embeddingCache"), i = await a.searchFields({
|
|
1459
|
+
text: r,
|
|
1448
1460
|
layerIds: e.vectorSearchLayerIds,
|
|
1449
|
-
minScore:
|
|
1450
|
-
topResults:
|
|
1461
|
+
minScore: Ie,
|
|
1462
|
+
topResults: qa,
|
|
1451
1463
|
embeddingCache: n
|
|
1452
1464
|
}), l = i.map(({ layerId: d, results: u }) => {
|
|
1453
|
-
const h = u.map((
|
|
1465
|
+
const h = u.map((p) => ` - ${p.name} (${p.score.toFixed(2)})`).join(`
|
|
1454
1466
|
`);
|
|
1455
1467
|
return `${o.get(d)?.layerItem.name ?? d}:
|
|
1456
1468
|
${h}`;
|
|
@@ -1458,64 +1470,64 @@ ${h}`;
|
|
|
1458
1470
|
`);
|
|
1459
1471
|
let c;
|
|
1460
1472
|
return i.length > 0 ? c = `Vector search completed. Matching layers and fields with scores:
|
|
1461
|
-
${l}` : c = `No vector search results found for score over ${
|
|
1473
|
+
${l}` : c = `No vector search results found for score over ${Ie}.`, await m({ text: c }, t), {
|
|
1462
1474
|
...e,
|
|
1463
1475
|
vectorSearchFieldResults: i
|
|
1464
1476
|
};
|
|
1465
|
-
} catch (
|
|
1466
|
-
throw await
|
|
1467
|
-
{ text: `Error during vector search: ${
|
|
1468
|
-
|
|
1469
|
-
), new Error(`Vector search failed: ${
|
|
1477
|
+
} catch (r) {
|
|
1478
|
+
throw await m(
|
|
1479
|
+
{ text: `Error during vector search: ${r instanceof Error ? r.message : String(r)}` },
|
|
1480
|
+
t
|
|
1481
|
+
), new Error(`Vector search failed: ${r instanceof Error ? r.message : String(r)}`);
|
|
1470
1482
|
}
|
|
1471
|
-
},
|
|
1483
|
+
}, Aa = 0.7, ka = async (e, t) => {
|
|
1472
1484
|
try {
|
|
1473
|
-
const
|
|
1474
|
-
await
|
|
1475
|
-
const a = S(
|
|
1485
|
+
const r = C(e.messages);
|
|
1486
|
+
await m({ text: `Similarity search to find layers: ${r}` }, t);
|
|
1487
|
+
const a = S(t, "layerSearch"), o = S(t, "layersAndFieldsRegistry"), n = await a.searchLayers({ text: r, minScore: Aa }), i = n.map((d) => d.id), l = n.map(({ id: d, score: u }) => `${o.get(d)?.layerItem.name ?? d} (${u.toFixed(2)})`).join(`
|
|
1476
1488
|
`);
|
|
1477
1489
|
let c;
|
|
1478
1490
|
return i.length > 0 ? c = `Vector search completed. Matching layers with scores:
|
|
1479
|
-
${l}` : c = "Vector search completed. No matching layers found.", await
|
|
1491
|
+
${l}` : c = "Vector search completed. No matching layers found.", await m({ text: c }, t), {
|
|
1480
1492
|
...e,
|
|
1481
1493
|
vectorSearchLayerIds: i
|
|
1482
1494
|
};
|
|
1483
|
-
} catch (
|
|
1484
|
-
throw await
|
|
1485
|
-
{ text: `Error during vector search: ${
|
|
1486
|
-
|
|
1487
|
-
), new Error(`Vector search failed: ${
|
|
1495
|
+
} catch (r) {
|
|
1496
|
+
throw await m(
|
|
1497
|
+
{ text: `Error during vector search: ${r instanceof Error ? r.message : String(r)}` },
|
|
1498
|
+
t
|
|
1499
|
+
), new Error(`Vector search failed: ${r instanceof Error ? r.message : String(r)}`);
|
|
1488
1500
|
}
|
|
1489
|
-
},
|
|
1490
|
-
function
|
|
1491
|
-
const
|
|
1492
|
-
if (!
|
|
1501
|
+
}, Ve = ["mapView"];
|
|
1502
|
+
function fe(e) {
|
|
1503
|
+
const r = e?.configurable?.context;
|
|
1504
|
+
if (!r || typeof r != "object")
|
|
1493
1505
|
throw new Error("LayerFilterAgent context missing");
|
|
1494
|
-
const a =
|
|
1506
|
+
const a = Ve.filter((o) => !(o in r));
|
|
1495
1507
|
if (a.length)
|
|
1496
1508
|
throw new Error(`LayerFilterAgent context missing: ${a.join(", ")}`);
|
|
1497
|
-
return
|
|
1509
|
+
return r;
|
|
1498
1510
|
}
|
|
1499
|
-
const
|
|
1511
|
+
const Na = async (e, t) => {
|
|
1500
1512
|
try {
|
|
1501
|
-
await
|
|
1502
|
-
const
|
|
1503
|
-
return await
|
|
1504
|
-
} catch (
|
|
1505
|
-
throw await
|
|
1513
|
+
await m({ text: "Getting statistics for vector search results" }, t);
|
|
1514
|
+
const r = S(t, "layersAndFieldsRegistry"), { mapView: a } = fe(t), o = await ye(e.vectorSearchFieldResults, r, a);
|
|
1515
|
+
return await m({ text: "Statistics retrieved" }, t), { ...e, layerFieldInfo: o };
|
|
1516
|
+
} catch (r) {
|
|
1517
|
+
throw await m({ text: "Error during fetching statistics" }, t), new Error(`Error during fetching statistics: ${r instanceof Error ? r.message : String(r)}`);
|
|
1506
1518
|
}
|
|
1507
|
-
},
|
|
1508
|
-
const a = e.map?.allLayers.find((i) => i.id ===
|
|
1509
|
-
o.where =
|
|
1519
|
+
}, We = async (e, t, r) => {
|
|
1520
|
+
const a = e.map?.allLayers.find((i) => i.id === t), o = a.createQuery();
|
|
1521
|
+
o.where = r ?? "1=1";
|
|
1510
1522
|
const { features: n } = await a.queryFeatures(o);
|
|
1511
1523
|
e.goTo(n);
|
|
1512
|
-
},
|
|
1513
|
-
const
|
|
1524
|
+
}, Be = async (e, t) => {
|
|
1525
|
+
const r = t.map?.allLayers.find(
|
|
1514
1526
|
(n) => n.id === e.layerId
|
|
1515
1527
|
);
|
|
1516
|
-
if (!
|
|
1528
|
+
if (!r)
|
|
1517
1529
|
return { error: `Could not find geometry layer with ID: ${e.layerId}` };
|
|
1518
|
-
const a = await
|
|
1530
|
+
const a = await r.queryFeatures({
|
|
1519
1531
|
where: e.where,
|
|
1520
1532
|
returnGeometry: !0
|
|
1521
1533
|
});
|
|
@@ -1528,49 +1540,49 @@ const Aa = async (e, r) => {
|
|
|
1528
1540
|
return { error: "The geometry of the first feature is undefined or null." };
|
|
1529
1541
|
o = n;
|
|
1530
1542
|
} else {
|
|
1531
|
-
const n = a.features.map((l) => l.geometry), i =
|
|
1543
|
+
const n = a.features.map((l) => l.geometry), i = ce.executeMany(n);
|
|
1532
1544
|
if (!i)
|
|
1533
1545
|
return { error: "Failed to create a combined geometry." };
|
|
1534
1546
|
o = i;
|
|
1535
1547
|
}
|
|
1536
1548
|
return { geometry: o };
|
|
1537
|
-
},
|
|
1538
|
-
const n =
|
|
1549
|
+
}, za = async (e, t, r, a, o) => {
|
|
1550
|
+
const n = t.map?.allLayers.find(
|
|
1539
1551
|
(l) => l.id === e.layerId
|
|
1540
1552
|
);
|
|
1541
1553
|
if (!n)
|
|
1542
1554
|
return `Could not find target layer with ID: ${e.layerId}`;
|
|
1543
1555
|
let i;
|
|
1544
1556
|
if (o) {
|
|
1545
|
-
const l = await
|
|
1557
|
+
const l = await Be(o, t);
|
|
1546
1558
|
if ("error" in l)
|
|
1547
1559
|
return l.error;
|
|
1548
1560
|
i = l.geometry;
|
|
1549
1561
|
}
|
|
1550
|
-
return n.featureEffect = new
|
|
1551
|
-
filter: new
|
|
1562
|
+
return n.featureEffect = new _e({
|
|
1563
|
+
filter: new U({
|
|
1552
1564
|
where: e.where,
|
|
1553
1565
|
geometry: i,
|
|
1554
1566
|
spatialRelationship: "intersects",
|
|
1555
1567
|
distance: o?.distance,
|
|
1556
1568
|
units: o?.units
|
|
1557
1569
|
}),
|
|
1558
|
-
includedEffect:
|
|
1570
|
+
includedEffect: r,
|
|
1559
1571
|
excludedEffect: a
|
|
1560
|
-
}), n.visible = !0, n.refresh(),
|
|
1561
|
-
|
|
1572
|
+
}), n.visible = !0, n.refresh(), We(
|
|
1573
|
+
t,
|
|
1562
1574
|
o ? o.layerId : e.layerId,
|
|
1563
1575
|
o ? o.where : e.where
|
|
1564
1576
|
), `Applied feature effects to target layer "${n.title ?? e.layerId}"${o ? ` using geometry from layer "${o.layerId}"` : ""}.`;
|
|
1565
|
-
},
|
|
1577
|
+
}, _a = ["feet", "kilometers", "meters", "miles", "nautical-miles", "us-nautical-miles"], Ke = s.enum(_a), ja = async ({
|
|
1566
1578
|
targetLayer: e,
|
|
1567
|
-
geometryLayer:
|
|
1568
|
-
includedEffect:
|
|
1579
|
+
geometryLayer: t,
|
|
1580
|
+
includedEffect: r = "drop-shadow(2px, 2px, 2px, gray)",
|
|
1569
1581
|
excludedEffect: a = "grayscale(100%) opacity(60%) blur(2px)"
|
|
1570
1582
|
}, o) => {
|
|
1571
|
-
const { mapView: n } =
|
|
1572
|
-
return await
|
|
1573
|
-
},
|
|
1583
|
+
const { mapView: n } = fe(o);
|
|
1584
|
+
return await za(e, n, r, a, t);
|
|
1585
|
+
}, Ma = s.object({
|
|
1574
1586
|
targetLayer: s.object({
|
|
1575
1587
|
layerId: s.string().describe("The layerId of the layer on which to set a feature effect."),
|
|
1576
1588
|
where: s.string().describe("The SQL-92 where clause representing the features to emphasize.")
|
|
@@ -1581,7 +1593,7 @@ const Aa = async (e, r) => {
|
|
|
1581
1593
|
"The SQL-92 where clause representing the features from which to filter features from the targetLayer by geometry."
|
|
1582
1594
|
),
|
|
1583
1595
|
distance: s.number().describe("The distance by which to filter the input geometry."),
|
|
1584
|
-
units:
|
|
1596
|
+
units: Ke.describe("The units used to filter by geometry and distance.")
|
|
1585
1597
|
}).optional().describe("Optional geometry-based filtering parameters for spatial queries."),
|
|
1586
1598
|
includedEffect: s.string().optional().default("drop-shadow(2px, 2px, 2px, gray)").describe(
|
|
1587
1599
|
"The effect applied to features that meet the filter requirements. Valid effects include: bloom, blur, brightness, contrast, drop-shadow, grayscale, hue-rotate, invert, opacity, saturate, and sepia. Prefer default unless specified."
|
|
@@ -1589,42 +1601,42 @@ const Aa = async (e, r) => {
|
|
|
1589
1601
|
excludedEffect: s.string().optional().default("grayscale(100%) opacity(60%) blur(2px)").describe(
|
|
1590
1602
|
"The effect applied to features that do not meet the filter requirements. Valid effects include: bloom, blur, brightness, contrast, drop-shadow, grayscale, hue-rotate, invert, opacity, saturate, and sepia. Prefer default unless specified."
|
|
1591
1603
|
)
|
|
1592
|
-
}),
|
|
1604
|
+
}), Pa = b(ja, {
|
|
1593
1605
|
name: "setFeatureEffect",
|
|
1594
1606
|
description: "Sets a feature effect on a given layer with given filter parameters and feature effects to emphasize certain features that meet a filter requirement. If no feature effect information is provided, then use the default effect provided.",
|
|
1595
|
-
schema:
|
|
1596
|
-
}),
|
|
1597
|
-
const a =
|
|
1607
|
+
schema: Ma
|
|
1608
|
+
}), Da = async (e, t, r) => {
|
|
1609
|
+
const a = t.map?.allLayers.find(
|
|
1598
1610
|
(i) => i.id === e.layerId
|
|
1599
1611
|
);
|
|
1600
1612
|
if (!a)
|
|
1601
1613
|
return `Could not find target layer with ID: ${e.layerId}`;
|
|
1602
1614
|
let o;
|
|
1603
|
-
if (
|
|
1604
|
-
const i = await
|
|
1615
|
+
if (r) {
|
|
1616
|
+
const i = await Be(r, t);
|
|
1605
1617
|
if ("error" in i)
|
|
1606
1618
|
return i.error;
|
|
1607
1619
|
o = i.geometry;
|
|
1608
1620
|
}
|
|
1609
|
-
const n = await
|
|
1610
|
-
return n.filter = new
|
|
1621
|
+
const n = await t.whenLayerView(a);
|
|
1622
|
+
return n.filter = new U({
|
|
1611
1623
|
where: e.where,
|
|
1612
1624
|
geometry: o,
|
|
1613
1625
|
spatialRelationship: "intersects",
|
|
1614
|
-
distance:
|
|
1615
|
-
units:
|
|
1616
|
-
}), a.visible = !0,
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
), `Applied feature filter to layer "${a.title ?? e.layerId}"${
|
|
1621
|
-
},
|
|
1626
|
+
distance: r?.distance,
|
|
1627
|
+
units: r?.units
|
|
1628
|
+
}), a.visible = !0, We(
|
|
1629
|
+
t,
|
|
1630
|
+
r ? r.layerId : e.layerId,
|
|
1631
|
+
r ? r.where : e.where
|
|
1632
|
+
), `Applied feature filter to layer "${a.title ?? e.layerId}"${r ? ` using geometry from layer "${r.layerId}"` : ""}.`;
|
|
1633
|
+
}, Ga = async ({
|
|
1622
1634
|
targetLayer: e,
|
|
1623
|
-
geometryLayer:
|
|
1624
|
-
},
|
|
1625
|
-
const { mapView: a } =
|
|
1626
|
-
return await
|
|
1627
|
-
},
|
|
1635
|
+
geometryLayer: t
|
|
1636
|
+
}, r) => {
|
|
1637
|
+
const { mapView: a } = fe(r);
|
|
1638
|
+
return await Da(e, a, t);
|
|
1639
|
+
}, Oa = s.object({
|
|
1628
1640
|
targetLayer: s.object({
|
|
1629
1641
|
layerId: s.string().describe("The layerId of the layer on which to set a filter."),
|
|
1630
1642
|
where: s.string().describe("The SQL-92 where clause representing the features to display.")
|
|
@@ -1635,18 +1647,18 @@ const Aa = async (e, r) => {
|
|
|
1635
1647
|
"The SQL-92 where clause representing the features from which to filter features from the targetLayer by geometry."
|
|
1636
1648
|
),
|
|
1637
1649
|
distance: s.number().describe("The distance by which to filter the input geometry."),
|
|
1638
|
-
units:
|
|
1650
|
+
units: Ke.describe("The units used to filter by geometry and distance.")
|
|
1639
1651
|
}).optional().describe("Optional geometry-based filtering parameters for spatial queries.")
|
|
1640
|
-
}),
|
|
1652
|
+
}), Qa = b(Ga, {
|
|
1641
1653
|
name: "setFeatureFilter",
|
|
1642
1654
|
description: "Sets a client-side filter using a where clause, geometry filter, or both on a target layer. This filters features at the client level in the view.",
|
|
1643
|
-
schema:
|
|
1644
|
-
}),
|
|
1645
|
-
await
|
|
1655
|
+
schema: Oa
|
|
1656
|
+
}), Ue = [Pa, Qa], Va = async (e, t) => {
|
|
1657
|
+
await m({ text: "Requesting LLM for layer filter results" }, t);
|
|
1646
1658
|
const a = await F("layer_filter_prompt");
|
|
1647
|
-
if (!
|
|
1659
|
+
if (!t?.configurable)
|
|
1648
1660
|
throw new Error("config.configurable is required for layer filter tools");
|
|
1649
|
-
const { userTimezone: o, userTimezoneOffset: n } =
|
|
1661
|
+
const { userTimezone: o, userTimezoneOffset: n } = ae(), i = {
|
|
1650
1662
|
layerFieldInfo: e.layerFieldInfo,
|
|
1651
1663
|
userTimezone: o,
|
|
1652
1664
|
userTimezoneOffset: n
|
|
@@ -1655,24 +1667,24 @@ const Aa = async (e, r) => {
|
|
|
1655
1667
|
modelTier: "advanced",
|
|
1656
1668
|
messages: x(e.messages),
|
|
1657
1669
|
inputVariables: i,
|
|
1658
|
-
tools:
|
|
1670
|
+
tools: Ue
|
|
1659
1671
|
}), c = l.content.toString();
|
|
1660
|
-
return await
|
|
1672
|
+
return await H(l, t), { ...e, messages: [...e.messages, l], outputMessage: c };
|
|
1661
1673
|
};
|
|
1662
|
-
async function
|
|
1663
|
-
const a = await new P(
|
|
1674
|
+
async function Wa(e, t) {
|
|
1675
|
+
const a = await new P(Ue).invoke(
|
|
1664
1676
|
{
|
|
1665
1677
|
messages: x(e.messages)
|
|
1666
1678
|
},
|
|
1667
|
-
|
|
1679
|
+
t
|
|
1668
1680
|
), o = a.messages.map((l) => l.text).join(`
|
|
1669
1681
|
`);
|
|
1670
|
-
await
|
|
1682
|
+
await m({ text: `Finished executing layer filter tool: ${o}` }, t);
|
|
1671
1683
|
const n = [...e.messages, ...a.messages], i = a.messages.map((l) => l.text).join(`
|
|
1672
1684
|
`);
|
|
1673
1685
|
return { ...e, outputMessage: i, messages: n };
|
|
1674
1686
|
}
|
|
1675
|
-
const
|
|
1687
|
+
const He = g.Root({
|
|
1676
1688
|
// Inputs coming from global context
|
|
1677
1689
|
messages: g({
|
|
1678
1690
|
reducer: z,
|
|
@@ -1683,44 +1695,44 @@ const Ue = g.Root({
|
|
|
1683
1695
|
// This avoids duplicate output when tool nodes and final LLM nodes
|
|
1684
1696
|
// emit the same text during a single agent turn.
|
|
1685
1697
|
outputMessage: g({
|
|
1686
|
-
reducer: (e = "",
|
|
1687
|
-
const
|
|
1688
|
-
if (!
|
|
1698
|
+
reducer: (e = "", t) => {
|
|
1699
|
+
const r = typeof t == "string" ? t.trim() : "";
|
|
1700
|
+
if (!r)
|
|
1689
1701
|
return e;
|
|
1690
1702
|
const a = e.trim();
|
|
1691
1703
|
if (!a)
|
|
1692
|
-
return
|
|
1693
|
-
if (a ===
|
|
1704
|
+
return r;
|
|
1705
|
+
if (a === r)
|
|
1694
1706
|
return e;
|
|
1695
1707
|
const o = a.split(`
|
|
1696
1708
|
|
|
1697
1709
|
`);
|
|
1698
|
-
return o[o.length - 1]?.trim() ===
|
|
1710
|
+
return o[o.length - 1]?.trim() === r ? e : `${e}
|
|
1699
1711
|
|
|
1700
|
-
${
|
|
1712
|
+
${r}`;
|
|
1701
1713
|
},
|
|
1702
1714
|
default: () => ""
|
|
1703
1715
|
}),
|
|
1704
1716
|
vectorSearchLayerIds: g(),
|
|
1705
1717
|
vectorSearchFieldResults: g(),
|
|
1706
1718
|
layerFieldInfo: g()
|
|
1707
|
-
}),
|
|
1719
|
+
}), Ba = async (e, t) => (await m({ text: "Exiting Layer Filter agent" }, t), e), Ka = (e, t) => D(["layerSearch", "fieldSearch", "layersAndFieldsRegistry"], "Layer Filter Agent")(e, t), Ua = () => new _(He).addNode("requireLayerFilterServices", Ka).addNode("vectorSearchLayers", ka).addNode("vectorSearchFields", Ca).addNode("fieldStatistics", Na).addNode("agent", Va).addNode("tools", Wa).addNode("earlyExit", Ba).addEdge(j, "requireLayerFilterServices").addEdge("requireLayerFilterServices", "vectorSearchLayers").addConditionalEdges(
|
|
1708
1720
|
"vectorSearchLayers",
|
|
1709
|
-
(
|
|
1721
|
+
(t) => t.vectorSearchLayerIds.length ? "vectorSearchFields" : "earlyExit"
|
|
1710
1722
|
).addConditionalEdges(
|
|
1711
1723
|
"vectorSearchFields",
|
|
1712
|
-
(
|
|
1713
|
-
).addEdge("fieldStatistics", "agent").addConditionalEdges("agent", (
|
|
1724
|
+
(t) => t.vectorSearchFieldResults.length ? "fieldStatistics" : "earlyExit"
|
|
1725
|
+
).addEdge("fieldStatistics", "agent").addConditionalEdges("agent", (t) => (t.messages[t.messages.length - 1]?.tool_calls?.length ?? 0) > 0 ? "tools" : "earlyExit").addEdge("tools", "earlyExit").addEdge("earlyExit", R), Ha = String.raw`- **layer filter** — User wants to include or exclude features based on field values, or visually style features differently (e.g., highlight or deemphasize them).
|
|
1714
1726
|
The Layer Filter Agent will automatically zoom to the affected features for action taken by this agent. In this case, no need to call navigation tool separately.
|
|
1715
1727
|
_Example: “Only show stations where Brand is Shell”_
|
|
1716
1728
|
_Example: “Make Shell stations stand out on the map”_
|
|
1717
|
-
_Example: “Gray out all stations that aren’t Shell”_`,
|
|
1729
|
+
_Example: “Gray out all stations that aren’t Shell”_`, Ci = {
|
|
1718
1730
|
id: "layerFilter",
|
|
1719
1731
|
name: "Layer Filter Agent",
|
|
1720
|
-
description:
|
|
1721
|
-
createGraph:
|
|
1722
|
-
workspace:
|
|
1723
|
-
},
|
|
1732
|
+
description: Ha,
|
|
1733
|
+
createGraph: Ua,
|
|
1734
|
+
workspace: He
|
|
1735
|
+
}, Ze = g.Root({
|
|
1724
1736
|
// Inputs coming from global context
|
|
1725
1737
|
messages: g({
|
|
1726
1738
|
reducer: z,
|
|
@@ -1731,21 +1743,21 @@ ${t}`;
|
|
|
1731
1743
|
// This avoids duplicate output when tool nodes and final LLM nodes
|
|
1732
1744
|
// emit the same text during a single agent turn.
|
|
1733
1745
|
outputMessage: g({
|
|
1734
|
-
reducer: (e = "",
|
|
1735
|
-
const
|
|
1736
|
-
if (!
|
|
1746
|
+
reducer: (e = "", t) => {
|
|
1747
|
+
const r = typeof t == "string" ? t.trim() : "";
|
|
1748
|
+
if (!r)
|
|
1737
1749
|
return e;
|
|
1738
1750
|
const a = e.trim();
|
|
1739
1751
|
if (!a)
|
|
1740
|
-
return
|
|
1741
|
-
if (a ===
|
|
1752
|
+
return r;
|
|
1753
|
+
if (a === r)
|
|
1742
1754
|
return e;
|
|
1743
1755
|
const o = a.split(`
|
|
1744
1756
|
|
|
1745
1757
|
`);
|
|
1746
|
-
return o[o.length - 1]?.trim() ===
|
|
1758
|
+
return o[o.length - 1]?.trim() === r ? e : `${e}
|
|
1747
1759
|
|
|
1748
|
-
${
|
|
1760
|
+
${r}`;
|
|
1749
1761
|
},
|
|
1750
1762
|
default: () => ""
|
|
1751
1763
|
}),
|
|
@@ -1753,36 +1765,36 @@ ${t}`;
|
|
|
1753
1765
|
vectorSearchFieldResults: g(),
|
|
1754
1766
|
layerFieldInfo: g(),
|
|
1755
1767
|
queryResponses: g()
|
|
1756
|
-
}),
|
|
1757
|
-
function
|
|
1758
|
-
const
|
|
1759
|
-
if (!
|
|
1768
|
+
}), Za = async (e, t) => (await m({ text: "Exiting Layer Query agent" }, t), e);
|
|
1769
|
+
function Z(e) {
|
|
1770
|
+
const r = e?.configurable?.context;
|
|
1771
|
+
if (!r || typeof r != "object")
|
|
1760
1772
|
throw new Error("LayerQueryAgent context missing");
|
|
1761
|
-
const a =
|
|
1773
|
+
const a = Ve.filter((o) => !(o in r));
|
|
1762
1774
|
if (a.length)
|
|
1763
1775
|
throw new Error(`LayerQueryAgent context missing: ${a.join(", ")}`);
|
|
1764
|
-
return
|
|
1776
|
+
return r;
|
|
1765
1777
|
}
|
|
1766
|
-
const
|
|
1778
|
+
const Ja = async (e, t) => {
|
|
1767
1779
|
try {
|
|
1768
|
-
await
|
|
1769
|
-
const
|
|
1770
|
-
return await
|
|
1771
|
-
} catch (
|
|
1772
|
-
throw await
|
|
1780
|
+
await m({ text: "Getting statistics for vector search results" }, t);
|
|
1781
|
+
const r = S(t, "layersAndFieldsRegistry"), { mapView: a } = Z(t), o = await ye(e.vectorSearchFieldResults, r, a);
|
|
1782
|
+
return await m({ text: "Statistics retrieved" }, t), { ...e, layerFieldInfo: o };
|
|
1783
|
+
} catch (r) {
|
|
1784
|
+
throw await m({ text: "Error during fetching statistics" }, t), new Error(`Error during fetching statistics: ${r instanceof Error ? r.message : String(r)}`);
|
|
1773
1785
|
}
|
|
1774
|
-
},
|
|
1786
|
+
}, qe = 0.7, Ya = 10, Xa = async (e, t) => {
|
|
1775
1787
|
try {
|
|
1776
|
-
const
|
|
1777
|
-
await
|
|
1778
|
-
const a = S(
|
|
1779
|
-
text:
|
|
1788
|
+
const r = C(e.messages);
|
|
1789
|
+
await m({ text: "Similarity search to find fields" }, t);
|
|
1790
|
+
const a = S(t, "fieldSearch"), o = S(t, "layersAndFieldsRegistry"), n = S(t, "embeddingCache"), i = await a.searchFields({
|
|
1791
|
+
text: r,
|
|
1780
1792
|
layerIds: e.vectorSearchLayerIds,
|
|
1781
|
-
minScore:
|
|
1782
|
-
topResults:
|
|
1793
|
+
minScore: qe,
|
|
1794
|
+
topResults: Ya,
|
|
1783
1795
|
embeddingCache: n
|
|
1784
1796
|
}), l = i.map(({ layerId: d, results: u }) => {
|
|
1785
|
-
const h = u.map((
|
|
1797
|
+
const h = u.map((p) => ` - ${p.name} (${p.score.toFixed(2)})`).join(`
|
|
1786
1798
|
`);
|
|
1787
1799
|
return `${o.get(d)?.layerItem.name ?? d}:
|
|
1788
1800
|
${h}`;
|
|
@@ -1790,74 +1802,74 @@ ${h}`;
|
|
|
1790
1802
|
`);
|
|
1791
1803
|
let c;
|
|
1792
1804
|
return i.length > 0 ? c = `Vector search completed. Matching layers and fields with scores:
|
|
1793
|
-
${l}` : c = `No vector search results found for score over ${
|
|
1805
|
+
${l}` : c = `No vector search results found for score over ${qe}.`, await m({ text: c }, t), {
|
|
1794
1806
|
...e,
|
|
1795
1807
|
vectorSearchFieldResults: i
|
|
1796
1808
|
};
|
|
1797
|
-
} catch (
|
|
1798
|
-
throw await
|
|
1799
|
-
{ text: `Error during vector search: ${
|
|
1800
|
-
|
|
1801
|
-
), new Error(`Vector search failed: ${
|
|
1809
|
+
} catch (r) {
|
|
1810
|
+
throw await m(
|
|
1811
|
+
{ text: `Error during vector search: ${r instanceof Error ? r.message : String(r)}` },
|
|
1812
|
+
t
|
|
1813
|
+
), new Error(`Vector search failed: ${r instanceof Error ? r.message : String(r)}`);
|
|
1802
1814
|
}
|
|
1803
|
-
},
|
|
1815
|
+
}, eo = 0.7, to = async (e, t) => {
|
|
1804
1816
|
try {
|
|
1805
|
-
const
|
|
1806
|
-
await
|
|
1807
|
-
const a = S(
|
|
1808
|
-
text:
|
|
1809
|
-
minScore:
|
|
1817
|
+
const r = C(e.messages);
|
|
1818
|
+
await m({ text: `Similarity search to find layers: ${r}` }, t);
|
|
1819
|
+
const a = S(t, "layerSearch"), o = S(t, "layersAndFieldsRegistry"), n = await a.searchLayers({
|
|
1820
|
+
text: r,
|
|
1821
|
+
minScore: eo
|
|
1810
1822
|
}), i = n.map((d) => d.id), l = n.map(({ id: d, score: u }) => `${o.get(d)?.layerItem.name ?? d} (${u.toFixed(2)})`).join(`
|
|
1811
1823
|
`);
|
|
1812
1824
|
let c;
|
|
1813
1825
|
return i.length > 0 ? c = `Vector search completed. Matching layers with scores:
|
|
1814
|
-
${l}` : c = "Vector search completed. No matching layers found.", await
|
|
1826
|
+
${l}` : c = "Vector search completed. No matching layers found.", await m({ text: c }, t), {
|
|
1815
1827
|
...e,
|
|
1816
1828
|
vectorSearchLayerIds: i
|
|
1817
1829
|
};
|
|
1818
|
-
} catch (
|
|
1819
|
-
throw await
|
|
1820
|
-
{ text: `Error during vector search: ${
|
|
1821
|
-
|
|
1822
|
-
), new Error(`Vector search failed: ${
|
|
1830
|
+
} catch (r) {
|
|
1831
|
+
throw await m(
|
|
1832
|
+
{ text: `Error during vector search: ${r instanceof Error ? r.message : String(r)}` },
|
|
1833
|
+
t
|
|
1834
|
+
), new Error(`Vector search failed: ${r instanceof Error ? r.message : String(r)}`);
|
|
1823
1835
|
}
|
|
1824
|
-
},
|
|
1836
|
+
}, ro = (e, t, r) => {
|
|
1825
1837
|
const a = e.createQuery();
|
|
1826
|
-
return a.outFields = [
|
|
1827
|
-
},
|
|
1828
|
-
const o = a.map?.allLayers.find((u) => u.id === e), n =
|
|
1838
|
+
return a.outFields = [t], a.where = r || "1=1", a.num = 1, a;
|
|
1839
|
+
}, ao = async (e, t, r, a) => {
|
|
1840
|
+
const o = a.map?.allLayers.find((u) => u.id === e), n = ro(o, t, r.where), l = (await o.queryFeatures(n)).features[0], c = l ? l.attributes[t] : null;
|
|
1829
1841
|
return {
|
|
1830
1842
|
tool: "getAttribute",
|
|
1831
1843
|
layerName: o.title ?? e,
|
|
1832
|
-
summary: `${
|
|
1844
|
+
summary: `${t} = ${c}`,
|
|
1833
1845
|
details: {
|
|
1834
|
-
fieldName:
|
|
1846
|
+
fieldName: t,
|
|
1835
1847
|
value: c,
|
|
1836
|
-
where:
|
|
1848
|
+
where: r.where
|
|
1837
1849
|
}
|
|
1838
1850
|
};
|
|
1839
1851
|
};
|
|
1840
|
-
async function
|
|
1841
|
-
const { mapView: o } =
|
|
1852
|
+
async function oo({ layerId: e, fieldName: t, query: r }, a) {
|
|
1853
|
+
const { mapView: o } = Z(a), n = await ao(e, t, r, o);
|
|
1842
1854
|
return JSON.stringify(n, null, 2);
|
|
1843
1855
|
}
|
|
1844
|
-
const
|
|
1856
|
+
const no = s.object({
|
|
1845
1857
|
layerId: s.string().describe("The layerId of the layer containing the field from which to get a value."),
|
|
1846
1858
|
fieldName: s.string().describe("The name of the field/attribute from which to get a field value."),
|
|
1847
1859
|
query: s.object({
|
|
1848
1860
|
where: s.string().describe("The SQL-92 where clause representing the feature from which to get an attribute value.")
|
|
1849
1861
|
})
|
|
1850
|
-
}),
|
|
1862
|
+
}), so = b(oo, {
|
|
1851
1863
|
name: "getAttribute",
|
|
1852
1864
|
description: "Returns an attribute value for a given feature.",
|
|
1853
|
-
schema:
|
|
1854
|
-
}),
|
|
1855
|
-
const
|
|
1865
|
+
schema: no
|
|
1866
|
+
}), ge = async (e, t) => {
|
|
1867
|
+
const r = t.map?.allLayers.find(
|
|
1856
1868
|
(n) => n.id === e.layerId
|
|
1857
1869
|
);
|
|
1858
|
-
if (!
|
|
1870
|
+
if (!r)
|
|
1859
1871
|
return { error: `Could not find geometry layer with ID: ${e.layerId}` };
|
|
1860
|
-
const a = await
|
|
1872
|
+
const a = await r.queryFeatures({
|
|
1861
1873
|
where: e.where,
|
|
1862
1874
|
returnGeometry: !0
|
|
1863
1875
|
});
|
|
@@ -1870,48 +1882,48 @@ const ao = s.object({
|
|
|
1870
1882
|
return { error: "The geometry of the first feature is undefined or null." };
|
|
1871
1883
|
o = n;
|
|
1872
1884
|
} else {
|
|
1873
|
-
const n = a.features.map((l) => l.geometry), i =
|
|
1885
|
+
const n = a.features.map((l) => l.geometry), i = ce.executeMany(n);
|
|
1874
1886
|
if (!i)
|
|
1875
1887
|
return { error: "Failed to create a combined geometry." };
|
|
1876
1888
|
o = i;
|
|
1877
1889
|
}
|
|
1878
1890
|
return { geometry: o };
|
|
1879
|
-
},
|
|
1880
|
-
const { targetLayer:
|
|
1891
|
+
}, io = async (e) => {
|
|
1892
|
+
const { targetLayer: t, fieldName: r, statisticType: a, mapView: o, layersAndFieldsRegistry: n, geometryLayer: i } = e, l = o.map?.allLayers.find((y) => y.id === t.layerId);
|
|
1881
1893
|
if (!l)
|
|
1882
|
-
throw new Error(`Layer '${
|
|
1883
|
-
const d = n.get(
|
|
1894
|
+
throw new Error(`Layer '${t.layerId}' not found.`);
|
|
1895
|
+
const d = n.get(t.layerId)?.fieldRegistry.get(r);
|
|
1884
1896
|
if (!d)
|
|
1885
|
-
throw new Error(`Field '${
|
|
1897
|
+
throw new Error(`Field '${r}' not found.`);
|
|
1886
1898
|
let u;
|
|
1887
1899
|
if (i) {
|
|
1888
|
-
const y = await
|
|
1900
|
+
const y = await ge(i, o);
|
|
1889
1901
|
if ("error" in y)
|
|
1890
1902
|
throw new Error(y.error);
|
|
1891
1903
|
if (u = y.geometry, i.distance && i.units) {
|
|
1892
|
-
const
|
|
1904
|
+
const w = ht.execute(u, i.distance, {
|
|
1893
1905
|
unit: i.units === "us-nautical-miles" ? "nautical-miles" : i.units
|
|
1894
1906
|
});
|
|
1895
|
-
|
|
1907
|
+
w && (u = w);
|
|
1896
1908
|
}
|
|
1897
1909
|
} else
|
|
1898
1910
|
u = o.extent.clone();
|
|
1899
|
-
const h = new
|
|
1911
|
+
const h = new U({
|
|
1900
1912
|
geometry: u,
|
|
1901
1913
|
spatialRelationship: "intersects"
|
|
1902
1914
|
});
|
|
1903
|
-
let
|
|
1915
|
+
let p = null, f = null;
|
|
1904
1916
|
try {
|
|
1905
|
-
|
|
1917
|
+
p = await de({
|
|
1906
1918
|
layer: l,
|
|
1907
|
-
field:
|
|
1908
|
-
sqlWhere:
|
|
1919
|
+
field: r,
|
|
1920
|
+
sqlWhere: t.where,
|
|
1909
1921
|
filter: h,
|
|
1910
1922
|
outStatisticTypes: { include: [a] }
|
|
1911
|
-
}), d.type === "string" && (f = (await
|
|
1923
|
+
}), d.type === "string" && (f = (await ue({
|
|
1912
1924
|
layer: l,
|
|
1913
|
-
field:
|
|
1914
|
-
sqlWhere:
|
|
1925
|
+
field: r,
|
|
1926
|
+
sqlWhere: t.where,
|
|
1915
1927
|
filter: h
|
|
1916
1928
|
})).uniqueValueInfos);
|
|
1917
1929
|
} catch (y) {
|
|
@@ -1919,35 +1931,35 @@ const ao = s.object({
|
|
|
1919
1931
|
}
|
|
1920
1932
|
return {
|
|
1921
1933
|
tool: "getStatistics",
|
|
1922
|
-
layerName: l.title ??
|
|
1923
|
-
summary: `${a} = ${typeof
|
|
1934
|
+
layerName: l.title ?? t.layerId,
|
|
1935
|
+
summary: `${a} = ${typeof p?.[a] == "number" ? p[a] : "N/A"}`,
|
|
1924
1936
|
details: {
|
|
1925
|
-
fieldName:
|
|
1937
|
+
fieldName: r,
|
|
1926
1938
|
statisticType: a,
|
|
1927
|
-
statistic:
|
|
1928
|
-
summaryStatistics:
|
|
1939
|
+
statistic: p?.[a] ?? null,
|
|
1940
|
+
summaryStatistics: p,
|
|
1929
1941
|
uniqueValues: f,
|
|
1930
|
-
where:
|
|
1942
|
+
where: t.where
|
|
1931
1943
|
}
|
|
1932
1944
|
};
|
|
1933
|
-
},
|
|
1934
|
-
async function
|
|
1945
|
+
}, lo = ["feet", "kilometers", "meters", "miles", "nautical-miles", "us-nautical-miles"], co = s.enum(lo);
|
|
1946
|
+
async function uo({
|
|
1935
1947
|
targetLayer: e,
|
|
1936
|
-
fieldName:
|
|
1937
|
-
statisticType:
|
|
1948
|
+
fieldName: t,
|
|
1949
|
+
statisticType: r,
|
|
1938
1950
|
geometryLayer: a
|
|
1939
1951
|
}, o) {
|
|
1940
|
-
const n = S(o, "layersAndFieldsRegistry"), { mapView: i } =
|
|
1952
|
+
const n = S(o, "layersAndFieldsRegistry"), { mapView: i } = Z(o), l = await io({
|
|
1941
1953
|
targetLayer: e,
|
|
1942
|
-
fieldName:
|
|
1943
|
-
statisticType:
|
|
1954
|
+
fieldName: t,
|
|
1955
|
+
statisticType: r,
|
|
1944
1956
|
mapView: i,
|
|
1945
1957
|
layersAndFieldsRegistry: n,
|
|
1946
1958
|
geometryLayer: a
|
|
1947
1959
|
});
|
|
1948
1960
|
return JSON.stringify(l, null, 2);
|
|
1949
1961
|
}
|
|
1950
|
-
const
|
|
1962
|
+
const ho = s.object({
|
|
1951
1963
|
targetLayer: s.object({
|
|
1952
1964
|
layerId: s.string().describe("The layerId of the layer containing the field from which to get a value."),
|
|
1953
1965
|
where: s.string().describe("The SQL-92 where clause representing the feature from which to get an attribute value.")
|
|
@@ -1959,19 +1971,19 @@ const co = s.object({
|
|
|
1959
1971
|
"The SQL-92 where clause representing the features from which to filter features from the targetLayer by geometry."
|
|
1960
1972
|
),
|
|
1961
1973
|
distance: s.number().optional().describe("The distance by which to query from the input geometry."),
|
|
1962
|
-
units:
|
|
1974
|
+
units: co.optional().describe("The units used to query by geometry and distance.")
|
|
1963
1975
|
}),
|
|
1964
1976
|
s.object({}).strict()
|
|
1965
1977
|
// <-- Allows `{}` without throwing
|
|
1966
1978
|
]).optional().describe("Optional geometry-based filtering parameters for spatial queries."),
|
|
1967
1979
|
fieldName: s.string().describe("The name of the field for which to get statistics."),
|
|
1968
1980
|
statisticType: s.enum(["avg", "max", "median", "min", "stddev", "sum", "variance", "nullcount", "count"]).describe("The statistic type to calculate.")
|
|
1969
|
-
}),
|
|
1981
|
+
}), mo = b(uo, {
|
|
1970
1982
|
name: "getStatistics",
|
|
1971
1983
|
description: "Returns one or more summary statistics for the given field. Statistic types include: count, maximum, minimum, average, median, standard deviation, variance, mode, sum, nullcount (number of features without a value for a given field), unique values. Statistics can be returned for number, date, and string fields. Only call this tool when the question requires filtering (e.g. a WHERE clause or spatial constraint) that cannot be satisfied by precomputed stats.",
|
|
1972
|
-
schema:
|
|
1973
|
-
}),
|
|
1974
|
-
const o =
|
|
1984
|
+
schema: ho
|
|
1985
|
+
}), po = async (e, t, r, a) => {
|
|
1986
|
+
const o = r.map?.allLayers.find((u) => u.id === e.layerId), n = a ? await ge(a, r) : { geometry: void 0 }, i = "geometry" in n ? n.geometry : void 0, l = new je({
|
|
1975
1987
|
where: e.where || "1=1",
|
|
1976
1988
|
outFields: e.outFields.length ? e.outFields : ["*"],
|
|
1977
1989
|
orderByFields: e.orderByFields,
|
|
@@ -1979,30 +1991,30 @@ const co = s.object({
|
|
|
1979
1991
|
spatialRelationship: i ? "intersects" : void 0,
|
|
1980
1992
|
distance: a?.distance,
|
|
1981
1993
|
units: a?.units,
|
|
1982
|
-
topFilter: new
|
|
1983
|
-
topCount:
|
|
1984
|
-
groupByFields:
|
|
1985
|
-
orderByFields:
|
|
1994
|
+
topFilter: new Me({
|
|
1995
|
+
topCount: t.topCount,
|
|
1996
|
+
groupByFields: t.groupByFields,
|
|
1997
|
+
orderByFields: t.orderByFields
|
|
1986
1998
|
})
|
|
1987
1999
|
}), c = await o.queryTopFeatures(l);
|
|
1988
2000
|
return {
|
|
1989
2001
|
tool: "getTopFeatures",
|
|
1990
2002
|
layerName: o.title ?? e.layerId,
|
|
1991
|
-
summary: `Top ${
|
|
2003
|
+
summary: `Top ${t.topCount} features extracted`,
|
|
1992
2004
|
details: {
|
|
1993
|
-
topCount:
|
|
2005
|
+
topCount: t.topCount,
|
|
1994
2006
|
features: c.features,
|
|
1995
2007
|
where: e.where
|
|
1996
2008
|
}
|
|
1997
2009
|
};
|
|
1998
|
-
},
|
|
2010
|
+
}, yo = async ({
|
|
1999
2011
|
targetLayer: e,
|
|
2000
|
-
topFilter:
|
|
2001
|
-
geometryLayer:
|
|
2012
|
+
topFilter: t,
|
|
2013
|
+
geometryLayer: r
|
|
2002
2014
|
}, a) => {
|
|
2003
|
-
const { mapView: o } =
|
|
2015
|
+
const { mapView: o } = Z(a), n = await po(e, t, o, r);
|
|
2004
2016
|
return JSON.stringify(n, null, 2);
|
|
2005
|
-
},
|
|
2017
|
+
}, fo = s.object({
|
|
2006
2018
|
targetLayer: s.object({
|
|
2007
2019
|
layerId: s.string().describe("The layerId of the layer containing the field from which to get a value."),
|
|
2008
2020
|
where: s.string().describe("The SQL-92 where clause representing the feature from which to get an attribute value."),
|
|
@@ -2026,19 +2038,19 @@ const co = s.object({
|
|
|
2026
2038
|
orderByFields: s.array(s.string().describe("The field(s) and order for which to sort the resulting features.")),
|
|
2027
2039
|
groupByFields: s.array(s.string().describe("The field(s) for which to group by the top features."))
|
|
2028
2040
|
})
|
|
2029
|
-
}),
|
|
2041
|
+
}), go = b(yo, {
|
|
2030
2042
|
name: "getTopFeatures",
|
|
2031
2043
|
description: "Returns the top n features from a layer",
|
|
2032
|
-
schema:
|
|
2033
|
-
}),
|
|
2034
|
-
const a =
|
|
2044
|
+
schema: fo
|
|
2045
|
+
}), wo = async (e, t, r) => {
|
|
2046
|
+
const a = t.map?.allLayers.find((d) => d.id === e.layerId), o = r ? await ge(r, t) : { geometry: void 0 }, n = "geometry" in o ? o.geometry : void 0, i = new mt({
|
|
2035
2047
|
where: e.where || "1=1",
|
|
2036
2048
|
outFields: e.outFields.length ? e.outFields : ["*"],
|
|
2037
2049
|
orderByFields: e.orderByFields,
|
|
2038
2050
|
geometry: n,
|
|
2039
2051
|
spatialRelationship: n ? "intersects" : void 0,
|
|
2040
|
-
distance:
|
|
2041
|
-
units:
|
|
2052
|
+
distance: r?.distance,
|
|
2053
|
+
units: r?.units
|
|
2042
2054
|
}), l = await a.queryFeatures(i);
|
|
2043
2055
|
return {
|
|
2044
2056
|
tool: "queryFeatures",
|
|
@@ -2051,14 +2063,14 @@ const co = s.object({
|
|
|
2051
2063
|
}
|
|
2052
2064
|
};
|
|
2053
2065
|
};
|
|
2054
|
-
async function
|
|
2066
|
+
async function bo({
|
|
2055
2067
|
targetLayer: e,
|
|
2056
|
-
geometryLayer:
|
|
2057
|
-
},
|
|
2058
|
-
const { mapView: a } =
|
|
2068
|
+
geometryLayer: t
|
|
2069
|
+
}, r) {
|
|
2070
|
+
const { mapView: a } = Z(r), o = await wo(e, a, t);
|
|
2059
2071
|
return JSON.stringify(o, null, 2);
|
|
2060
2072
|
}
|
|
2061
|
-
const
|
|
2073
|
+
const So = s.object({
|
|
2062
2074
|
targetLayer: s.object({
|
|
2063
2075
|
layerId: s.string().describe("The layerId of the layer containing the field from which to get a value."),
|
|
2064
2076
|
where: s.string().describe("The SQL-92 where clause representing the feature from which to get an attribute value."),
|
|
@@ -2077,25 +2089,25 @@ const wo = s.object({
|
|
|
2077
2089
|
distance: s.number().describe("The distance by which to query from the input geometry."),
|
|
2078
2090
|
units: A.describe("The units used to query by geometry and distance.")
|
|
2079
2091
|
}).optional().describe("Optional geometry-based filtering parameters for spatial queries.")
|
|
2080
|
-
}),
|
|
2092
|
+
}), vo = b(bo, {
|
|
2081
2093
|
name: "queryFeatures",
|
|
2082
2094
|
description: "Queries for one or more features from a given layer.",
|
|
2083
|
-
schema:
|
|
2084
|
-
}),
|
|
2085
|
-
await
|
|
2086
|
-
const
|
|
2087
|
-
if (!
|
|
2095
|
+
schema: So
|
|
2096
|
+
}), Je = [vo, mo, so, go], To = async (e, t) => {
|
|
2097
|
+
await m({ text: "Requesting LLM for layer query results" }, t);
|
|
2098
|
+
const r = await F("data_query_prompt");
|
|
2099
|
+
if (!t?.configurable)
|
|
2088
2100
|
throw new Error("config.configurable is required for layer query tools");
|
|
2089
|
-
const { userTimezone: a, userTimezoneOffset: o } =
|
|
2101
|
+
const { userTimezone: a, userTimezoneOffset: o } = ae(), n = {
|
|
2090
2102
|
layerFieldInfo: e.layerFieldInfo,
|
|
2091
2103
|
userTimezone: a,
|
|
2092
2104
|
userTimezoneOffset: o
|
|
2093
2105
|
}, i = await M({
|
|
2094
|
-
promptText:
|
|
2106
|
+
promptText: r,
|
|
2095
2107
|
modelTier: "advanced",
|
|
2096
2108
|
messages: x(e.messages),
|
|
2097
2109
|
inputVariables: n,
|
|
2098
|
-
tools:
|
|
2110
|
+
tools: Je
|
|
2099
2111
|
});
|
|
2100
2112
|
if (!(i.tool_calls && Array.isArray(i.tool_calls) && i.tool_calls.length > 0))
|
|
2101
2113
|
return {
|
|
@@ -2103,14 +2115,14 @@ const wo = s.object({
|
|
|
2103
2115
|
messages: [...e.messages, i]
|
|
2104
2116
|
};
|
|
2105
2117
|
const c = i.content.toString() || "LLM requested tool calls.";
|
|
2106
|
-
return await
|
|
2107
|
-
},
|
|
2108
|
-
async function
|
|
2109
|
-
const { messages:
|
|
2118
|
+
return await H(i, t), { ...e, outputMessage: c, messages: [...e.messages, i] };
|
|
2119
|
+
}, xo = new P(Je);
|
|
2120
|
+
async function Eo(e, t) {
|
|
2121
|
+
const { messages: r } = await xo.invoke(
|
|
2110
2122
|
{ messages: x(e.messages) },
|
|
2111
|
-
|
|
2123
|
+
t
|
|
2112
2124
|
), a = [], o = [];
|
|
2113
|
-
for (const l of
|
|
2125
|
+
for (const l of r) {
|
|
2114
2126
|
const c = l.content;
|
|
2115
2127
|
if (typeof c != "string") {
|
|
2116
2128
|
console.warn("Skipping non-string tool output:", c);
|
|
@@ -2127,7 +2139,7 @@ async function To(e, r) {
|
|
|
2127
2139
|
}
|
|
2128
2140
|
if (o.length === 0)
|
|
2129
2141
|
return { ...e, queryResponses: a };
|
|
2130
|
-
const n = new
|
|
2142
|
+
const n = new K({
|
|
2131
2143
|
content: `Query results:
|
|
2132
2144
|
${o.join(`
|
|
2133
2145
|
`)}`
|
|
@@ -2137,52 +2149,52 @@ ${o.join(`
|
|
|
2137
2149
|
return {
|
|
2138
2150
|
...e,
|
|
2139
2151
|
outputMessage: i,
|
|
2140
|
-
messages: [...e.messages, ...
|
|
2152
|
+
messages: [...e.messages, ...r, n],
|
|
2141
2153
|
queryResponses: a
|
|
2142
2154
|
};
|
|
2143
2155
|
}
|
|
2144
|
-
const
|
|
2156
|
+
const $o = async (e, t) => {
|
|
2145
2157
|
try {
|
|
2146
|
-
await
|
|
2158
|
+
await m({ text: "Requesting LLM for summary on query results" }, t);
|
|
2147
2159
|
const a = await F("summarize_query_response_prompt"), o = {
|
|
2148
2160
|
queryResponse: e.queryResponses
|
|
2149
|
-
}, n = await
|
|
2161
|
+
}, n = await ie({
|
|
2150
2162
|
promptText: a,
|
|
2151
2163
|
messages: x(e.messages),
|
|
2152
2164
|
inputVariables: o
|
|
2153
2165
|
}), i = typeof n == "string" ? n : n.content;
|
|
2154
|
-
return e.messages = [...e.messages, new
|
|
2155
|
-
} catch (
|
|
2156
|
-
throw await
|
|
2166
|
+
return e.messages = [...e.messages, new K(i)], e.outputMessage = i, await m({ text: `Received response from LLM: ${i}` }, t), e;
|
|
2167
|
+
} catch (r) {
|
|
2168
|
+
throw await m({ text: "Error during filter LLM request" }, t), new Error(`Error during filter LLM request: ${r instanceof Error ? r.message : String(r)}`);
|
|
2157
2169
|
}
|
|
2158
|
-
},
|
|
2170
|
+
}, Fo = (e, t) => D(["layerSearch", "fieldSearch", "layersAndFieldsRegistry"], "Layer Query Agent")(e, t), Ro = () => new _(Ze).addNode("requireLayerQueryServices", Fo).addNode("vectorSearchLayers", to).addNode("vectorSearchFields", Xa).addNode("fieldStatistics", Ja).addNode("agent", To).addNode("tools", Eo).addNode("summarizeQueryResponseLLM", $o).addNode("earlyExit", Za).addEdge(j, "requireLayerQueryServices").addEdge("requireLayerQueryServices", "vectorSearchLayers").addConditionalEdges(
|
|
2159
2171
|
"vectorSearchLayers",
|
|
2160
|
-
(
|
|
2172
|
+
(t) => t.vectorSearchLayerIds.length ? "vectorSearchFields" : "earlyExit"
|
|
2161
2173
|
).addConditionalEdges(
|
|
2162
2174
|
"vectorSearchFields",
|
|
2163
|
-
(
|
|
2164
|
-
).addEdge("fieldStatistics", "agent").addEdge("agent", "tools").addConditionalEdges("tools", (
|
|
2175
|
+
(t) => t.vectorSearchFieldResults.length ? "fieldStatistics" : "earlyExit"
|
|
2176
|
+
).addEdge("fieldStatistics", "agent").addEdge("agent", "tools").addConditionalEdges("tools", (t) => t.queryResponses.length ? "summarizeQueryResponseLLM" : "earlyExit").addEdge("summarizeQueryResponseLLM", R).addEdge("earlyExit", R), Lo = String.raw`- **layerQuery** — User is asking about the feature layer’s data (e.g. counts, summaries, statistics, field values), either for all features, a subset based on a condition, or for a subset based on the current view. CRITICAL: Always call the Layer Filter Agent after this agent.
|
|
2165
2177
|
This also includes questions that ask which feature meets a given condition or where a particular feature in the data is located (e.g., “Where is the spring with the highest elevation?”).
|
|
2166
2178
|
_Example: “How many features are there?”_
|
|
2167
2179
|
_Example: “What’s the average population?”_
|
|
2168
|
-
_Example: “Which values are in the status field?”_`,
|
|
2180
|
+
_Example: “Which values are in the status field?”_`, Ai = {
|
|
2169
2181
|
id: "layerQuery",
|
|
2170
2182
|
name: "Layer Query Agent",
|
|
2171
|
-
description:
|
|
2172
|
-
createGraph:
|
|
2173
|
-
workspace:
|
|
2174
|
-
},
|
|
2183
|
+
description: Lo,
|
|
2184
|
+
createGraph: Ro,
|
|
2185
|
+
workspace: Ze
|
|
2186
|
+
}, Ce = 0.7, Io = 10, qo = async (e, t) => {
|
|
2175
2187
|
try {
|
|
2176
|
-
const
|
|
2177
|
-
await
|
|
2178
|
-
const a = S(
|
|
2179
|
-
text:
|
|
2188
|
+
const r = C(e.messages);
|
|
2189
|
+
await m({ text: "Similarity search to find fields" }, t);
|
|
2190
|
+
const a = S(t, "fieldSearch"), o = S(t, "layersAndFieldsRegistry"), n = S(t, "embeddingCache"), i = await a.searchFields({
|
|
2191
|
+
text: r,
|
|
2180
2192
|
layerIds: e.vectorSearchLayerIds,
|
|
2181
|
-
minScore:
|
|
2182
|
-
topResults:
|
|
2193
|
+
minScore: Ce,
|
|
2194
|
+
topResults: Io,
|
|
2183
2195
|
embeddingCache: n
|
|
2184
2196
|
}), l = i.map(({ layerId: d, results: u }) => {
|
|
2185
|
-
const h = u.map((
|
|
2197
|
+
const h = u.map((p) => ` - ${p.name} (${p.score.toFixed(2)})`).join(`
|
|
2186
2198
|
`);
|
|
2187
2199
|
return `${o.get(d)?.layerItem.name ?? d}:
|
|
2188
2200
|
${h}`;
|
|
@@ -2190,56 +2202,56 @@ ${h}`;
|
|
|
2190
2202
|
`);
|
|
2191
2203
|
let c;
|
|
2192
2204
|
return i.length > 0 ? c = `Vector search completed. Matching layers and fields with scores:
|
|
2193
|
-
${l}` : c = `No vector search results found for score over ${
|
|
2205
|
+
${l}` : c = `No vector search results found for score over ${Ce}.`, await m({ text: c }, t), {
|
|
2194
2206
|
...e,
|
|
2195
2207
|
vectorSearchFieldResults: i
|
|
2196
2208
|
};
|
|
2197
|
-
} catch (
|
|
2198
|
-
throw await
|
|
2199
|
-
{ text: `Error during vector search: ${
|
|
2200
|
-
|
|
2201
|
-
), new Error(`Vector search failed: ${
|
|
2209
|
+
} catch (r) {
|
|
2210
|
+
throw await m(
|
|
2211
|
+
{ text: `Error during vector search: ${r instanceof Error ? r.message : String(r)}` },
|
|
2212
|
+
t
|
|
2213
|
+
), new Error(`Vector search failed: ${r instanceof Error ? r.message : String(r)}`);
|
|
2202
2214
|
}
|
|
2203
|
-
},
|
|
2215
|
+
}, Co = 0.7, Ao = async (e, t) => {
|
|
2204
2216
|
try {
|
|
2205
|
-
const
|
|
2206
|
-
await
|
|
2207
|
-
const a = S(
|
|
2208
|
-
text:
|
|
2209
|
-
minScore:
|
|
2217
|
+
const r = C(e.messages);
|
|
2218
|
+
await m({ text: `Similarity search to find layers: ${r}` }, t);
|
|
2219
|
+
const a = S(t, "layerSearch"), o = S(t, "layersAndFieldsRegistry"), n = await a.searchLayers({
|
|
2220
|
+
text: r,
|
|
2221
|
+
minScore: Co
|
|
2210
2222
|
}), i = n.map((d) => d.id), l = n.map(({ id: d, score: u }) => `${o.get(d)?.layerItem.name ?? d} (${u.toFixed(2)})`).join(`
|
|
2211
2223
|
`);
|
|
2212
2224
|
let c;
|
|
2213
2225
|
return i.length > 0 ? c = `Vector search completed. Matching layers with scores:
|
|
2214
|
-
${l}` : c = "Vector search completed. No matching layers found.", await
|
|
2226
|
+
${l}` : c = "Vector search completed. No matching layers found.", await m({ text: c }, t), {
|
|
2215
2227
|
...e,
|
|
2216
2228
|
vectorSearchLayerIds: i
|
|
2217
2229
|
};
|
|
2218
|
-
} catch (
|
|
2219
|
-
throw await
|
|
2220
|
-
{ text: `Error during vector search: ${
|
|
2221
|
-
|
|
2222
|
-
), new Error(`Vector search failed: ${
|
|
2230
|
+
} catch (r) {
|
|
2231
|
+
throw await m(
|
|
2232
|
+
{ text: `Error during vector search: ${r instanceof Error ? r.message : String(r)}` },
|
|
2233
|
+
t
|
|
2234
|
+
), new Error(`Vector search failed: ${r instanceof Error ? r.message : String(r)}`);
|
|
2223
2235
|
}
|
|
2224
2236
|
};
|
|
2225
|
-
async function
|
|
2226
|
-
const { fields:
|
|
2237
|
+
async function ko(e) {
|
|
2238
|
+
const { fields: t, layer: r, view: a, styleName: o, colorSchemeTags: n } = e;
|
|
2227
2239
|
let i;
|
|
2228
|
-
return n ? i =
|
|
2229
|
-
basemapTheme: await
|
|
2230
|
-
geometryType:
|
|
2240
|
+
return n ? i = yt({
|
|
2241
|
+
basemapTheme: await xe(a),
|
|
2242
|
+
geometryType: r.geometryType,
|
|
2231
2243
|
includedTags: n,
|
|
2232
|
-
numColors: Math.min(
|
|
2233
|
-
})[0] : i =
|
|
2234
|
-
basemapTheme: await
|
|
2235
|
-
geometryType:
|
|
2236
|
-
numColors: Math.min(
|
|
2244
|
+
numColors: Math.min(t.length, 8)
|
|
2245
|
+
})[0] : i = ft({
|
|
2246
|
+
basemapTheme: await xe(a),
|
|
2247
|
+
geometryType: r.geometryType,
|
|
2248
|
+
numColors: Math.min(t.length, 8)
|
|
2237
2249
|
}).primaryScheme, {
|
|
2238
|
-
layer:
|
|
2250
|
+
layer: r,
|
|
2239
2251
|
view: a,
|
|
2240
|
-
attributes:
|
|
2252
|
+
attributes: t.map((l) => ({
|
|
2241
2253
|
field: l,
|
|
2242
|
-
label:
|
|
2254
|
+
label: r.fields.find((c) => c.name === l)?.alias ?? ""
|
|
2243
2255
|
})).slice(0, 8),
|
|
2244
2256
|
outlineOptimizationEnabled: !0,
|
|
2245
2257
|
sizeOptimizationEnabled: !0,
|
|
@@ -2247,20 +2259,20 @@ async function Co(e) {
|
|
|
2247
2259
|
pieChartScheme: i
|
|
2248
2260
|
};
|
|
2249
2261
|
}
|
|
2250
|
-
async function
|
|
2262
|
+
async function No(e) {
|
|
2251
2263
|
return await pt(e);
|
|
2252
2264
|
}
|
|
2253
|
-
async function
|
|
2265
|
+
async function zo({
|
|
2254
2266
|
arcgisMap: e,
|
|
2255
|
-
arcgisMapView:
|
|
2256
|
-
layerId:
|
|
2267
|
+
arcgisMapView: t,
|
|
2268
|
+
layerId: r,
|
|
2257
2269
|
fields: a,
|
|
2258
2270
|
colorSchemes: o,
|
|
2259
2271
|
includeSize: n
|
|
2260
2272
|
}) {
|
|
2261
|
-
const i =
|
|
2273
|
+
const i = t, l = e?.allLayers.find((u) => u.id === r);
|
|
2262
2274
|
if (!l)
|
|
2263
|
-
return `Could not find layer for id: ${
|
|
2275
|
+
return `Could not find layer for id: ${r}`;
|
|
2264
2276
|
const d = {
|
|
2265
2277
|
styleName: n ? "chart-size" : "chart",
|
|
2266
2278
|
fields: a,
|
|
@@ -2269,44 +2281,44 @@ async function ko({
|
|
|
2269
2281
|
colorSchemeTags: o
|
|
2270
2282
|
};
|
|
2271
2283
|
try {
|
|
2272
|
-
const u = await
|
|
2284
|
+
const u = await ko(d), h = await No(u);
|
|
2273
2285
|
return l.renderer = h.renderer, l.visible = !0, `Chart renderer applied to layer: ${l.title ?? l.id} using fields ${a.join(", ")}`;
|
|
2274
2286
|
} catch (u) {
|
|
2275
2287
|
return `Error applying chart renderer: ${u instanceof Error ? u.message : String(u)}`;
|
|
2276
2288
|
}
|
|
2277
2289
|
}
|
|
2278
|
-
const
|
|
2290
|
+
const _o = ["mapView"];
|
|
2279
2291
|
function q(e) {
|
|
2280
|
-
const
|
|
2281
|
-
if (!
|
|
2292
|
+
const r = e?.configurable?.context;
|
|
2293
|
+
if (!r || typeof r != "object")
|
|
2282
2294
|
throw new Error("LayerStylingAgent context missing");
|
|
2283
|
-
const a =
|
|
2295
|
+
const a = _o.filter((o) => !(o in r));
|
|
2284
2296
|
if (a.length)
|
|
2285
2297
|
throw new Error(`LayerStylingAgent context missing: ${a.join(", ")}`);
|
|
2286
|
-
return
|
|
2298
|
+
return r;
|
|
2287
2299
|
}
|
|
2288
|
-
async function
|
|
2300
|
+
async function jo({
|
|
2289
2301
|
layerId: e,
|
|
2290
|
-
fields:
|
|
2291
|
-
colorSchemes:
|
|
2302
|
+
fields: t,
|
|
2303
|
+
colorSchemes: r,
|
|
2292
2304
|
includeSize: a
|
|
2293
2305
|
}, o) {
|
|
2294
2306
|
const { mapView: n } = q(o);
|
|
2295
|
-
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, o), await
|
|
2307
|
+
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, o), await zo({
|
|
2296
2308
|
arcgisMap: n.map,
|
|
2297
2309
|
arcgisMapView: n,
|
|
2298
2310
|
layerId: e,
|
|
2299
|
-
fields:
|
|
2300
|
-
colorSchemes:
|
|
2311
|
+
fields: t,
|
|
2312
|
+
colorSchemes: r,
|
|
2301
2313
|
includeSize: a
|
|
2302
2314
|
});
|
|
2303
2315
|
}
|
|
2304
|
-
const
|
|
2316
|
+
const Mo = s.object({
|
|
2305
2317
|
layerId: s.string().describe("The id of the layer to apply the chart renderer to"),
|
|
2306
2318
|
fields: s.array(s.string()).describe("The fields to use for the chart renderer (multiple numeric fields)"),
|
|
2307
2319
|
colorSchemes: s.array(s.string()).optional().describe("Optional color scheme tags to use"),
|
|
2308
2320
|
includeSize: s.boolean().optional().describe("Whether to vary the chart size (chart-size)")
|
|
2309
|
-
}),
|
|
2321
|
+
}), Po = b(jo, {
|
|
2310
2322
|
name: "chart",
|
|
2311
2323
|
description: `Label: Charts
|
|
2312
2324
|
Description: Show the values of two or more categories as a proportion of the total using a pie chart.
|
|
@@ -2319,17 +2331,17 @@ const _o = s.object({
|
|
|
2319
2331
|
Keywords: pie, chart, all categories, breakdown, proportion, total, amount, how much, sum, graduated size, proportional size
|
|
2320
2332
|
Example: Show the total number of homes built in each decade using a pie chart for each feature and vary the size of each chart based on the total of all categories.
|
|
2321
2333
|
Fields: This style requires 2-8 number fields.`,
|
|
2322
|
-
schema:
|
|
2334
|
+
schema: Mo
|
|
2323
2335
|
});
|
|
2324
|
-
function
|
|
2325
|
-
const { fields:
|
|
2336
|
+
function Do(e) {
|
|
2337
|
+
const { fields: t, layer: r, view: a, theme: o, colorSchemeTags: n } = e, i = t[0];
|
|
2326
2338
|
let l;
|
|
2327
|
-
return n && (l =
|
|
2328
|
-
geometryType:
|
|
2339
|
+
return n && (l = he({
|
|
2340
|
+
geometryType: r.geometryType,
|
|
2329
2341
|
includedTags: n,
|
|
2330
2342
|
theme: o || "high-to-low"
|
|
2331
2343
|
})[0]), {
|
|
2332
|
-
layer:
|
|
2344
|
+
layer: r,
|
|
2333
2345
|
view: a,
|
|
2334
2346
|
startTime: i,
|
|
2335
2347
|
endTime: /* @__PURE__ */ new Date(),
|
|
@@ -2339,20 +2351,20 @@ function Mo(e) {
|
|
|
2339
2351
|
colorScheme: l
|
|
2340
2352
|
};
|
|
2341
2353
|
}
|
|
2342
|
-
async function
|
|
2343
|
-
return await
|
|
2354
|
+
async function Go(e) {
|
|
2355
|
+
return await gt(e);
|
|
2344
2356
|
}
|
|
2345
|
-
async function
|
|
2357
|
+
async function Oo({
|
|
2346
2358
|
arcgisMap: e,
|
|
2347
|
-
arcgisMapView:
|
|
2348
|
-
layerId:
|
|
2359
|
+
arcgisMapView: t,
|
|
2360
|
+
layerId: r,
|
|
2349
2361
|
fields: a,
|
|
2350
2362
|
colorSchemes: o,
|
|
2351
2363
|
theme: n
|
|
2352
2364
|
}) {
|
|
2353
|
-
const i =
|
|
2365
|
+
const i = t, l = e?.allLayers.find((d) => d.id === r);
|
|
2354
2366
|
if (!l)
|
|
2355
|
-
return `Could not find layer for id: ${
|
|
2367
|
+
return `Could not find layer for id: ${r}`;
|
|
2356
2368
|
const c = {
|
|
2357
2369
|
styleName: "color-age",
|
|
2358
2370
|
fields: a,
|
|
@@ -2362,53 +2374,53 @@ async function Do({
|
|
|
2362
2374
|
theme: n
|
|
2363
2375
|
};
|
|
2364
2376
|
try {
|
|
2365
|
-
const d =
|
|
2377
|
+
const d = Do(c), u = await Go(d);
|
|
2366
2378
|
return l.renderer = u.renderer, l.visible = !0, `Color-age renderer applied to layer: ${l.title ?? l.id} using fields ${a.join(", ")}`;
|
|
2367
2379
|
} catch (d) {
|
|
2368
2380
|
return `Error applying color-age renderer: ${d instanceof Error ? d.message : String(d)}`;
|
|
2369
2381
|
}
|
|
2370
2382
|
}
|
|
2371
|
-
async function
|
|
2383
|
+
async function Qo({
|
|
2372
2384
|
layerId: e,
|
|
2373
|
-
fields:
|
|
2374
|
-
colorSchemes:
|
|
2385
|
+
fields: t,
|
|
2386
|
+
colorSchemes: r,
|
|
2375
2387
|
theme: a
|
|
2376
2388
|
}, o) {
|
|
2377
2389
|
const { mapView: n } = q(o);
|
|
2378
|
-
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, o), await
|
|
2390
|
+
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, o), await Oo({
|
|
2379
2391
|
arcgisMap: n.map,
|
|
2380
2392
|
arcgisMapView: n,
|
|
2381
2393
|
layerId: e,
|
|
2382
|
-
fields:
|
|
2383
|
-
colorSchemes:
|
|
2394
|
+
fields: t,
|
|
2395
|
+
colorSchemes: r,
|
|
2384
2396
|
theme: a
|
|
2385
2397
|
});
|
|
2386
2398
|
}
|
|
2387
|
-
const
|
|
2399
|
+
const Vo = s.object({
|
|
2388
2400
|
layerId: s.string().describe("The id of the layer to apply the color-age renderer to"),
|
|
2389
2401
|
fields: s.array(s.string()).describe("The field(s) to use for the color-age renderer (temporal/date data)"),
|
|
2390
2402
|
colorSchemes: s.array(s.string()).optional().describe("Optional color scheme tags to use"),
|
|
2391
2403
|
theme: s.enum(["above-and-below", "above", "below", "centered-on", "extremes", "high-to-low"]).optional().describe("Optional theme for the color ramp")
|
|
2392
|
-
}),
|
|
2404
|
+
}), Wo = b(Qo, {
|
|
2393
2405
|
name: "color-age",
|
|
2394
2406
|
description: `Label: Age (color)
|
|
2395
2407
|
Description: Use colors along a continuous color ramp to represent the age of features. Age reflects the length of time from a start date to an end date.
|
|
2396
2408
|
Keywords: since, age, how old, how long
|
|
2397
2409
|
Example: Show the age of each feature based on its reported date.
|
|
2398
2410
|
Fields: This style requires at least one field with a date type.`,
|
|
2399
|
-
schema:
|
|
2411
|
+
schema: Vo
|
|
2400
2412
|
});
|
|
2401
|
-
function
|
|
2402
|
-
const { fields:
|
|
2403
|
-
let { theme: n } = e, i =
|
|
2404
|
-
const l =
|
|
2413
|
+
function Bo(e) {
|
|
2414
|
+
const { fields: t, layer: r, view: a, colorSchemeTags: o } = e;
|
|
2415
|
+
let { theme: n } = e, i = t[1];
|
|
2416
|
+
const l = t[0];
|
|
2405
2417
|
let c;
|
|
2406
|
-
return o && (c =
|
|
2407
|
-
geometryType:
|
|
2418
|
+
return o && (c = he({
|
|
2419
|
+
geometryType: r.geometryType,
|
|
2408
2420
|
includedTags: o,
|
|
2409
2421
|
theme: n || "high-to-low"
|
|
2410
2422
|
})[0]), {
|
|
2411
|
-
layer:
|
|
2423
|
+
layer: r,
|
|
2412
2424
|
view: a,
|
|
2413
2425
|
field: l,
|
|
2414
2426
|
normalizationField: i,
|
|
@@ -2418,20 +2430,20 @@ function Vo(e) {
|
|
|
2418
2430
|
colorScheme: c
|
|
2419
2431
|
};
|
|
2420
2432
|
}
|
|
2421
|
-
async function
|
|
2422
|
-
return await
|
|
2433
|
+
async function Ko(e) {
|
|
2434
|
+
return await wt(e);
|
|
2423
2435
|
}
|
|
2424
|
-
async function
|
|
2436
|
+
async function Uo({
|
|
2425
2437
|
arcgisMap: e,
|
|
2426
|
-
arcgisMapView:
|
|
2427
|
-
layerId:
|
|
2438
|
+
arcgisMapView: t,
|
|
2439
|
+
layerId: r,
|
|
2428
2440
|
fields: a,
|
|
2429
2441
|
colorSchemes: o,
|
|
2430
2442
|
theme: n
|
|
2431
2443
|
}) {
|
|
2432
|
-
const i =
|
|
2444
|
+
const i = t, l = e?.allLayers.find((d) => d.id === r);
|
|
2433
2445
|
if (!l)
|
|
2434
|
-
return `Could not find layer for id: ${
|
|
2446
|
+
return `Could not find layer for id: ${r}`;
|
|
2435
2447
|
const c = {
|
|
2436
2448
|
styleName: "color",
|
|
2437
2449
|
fields: a,
|
|
@@ -2441,52 +2453,52 @@ async function Bo({
|
|
|
2441
2453
|
theme: n
|
|
2442
2454
|
};
|
|
2443
2455
|
try {
|
|
2444
|
-
const d =
|
|
2456
|
+
const d = Bo(c), u = await Ko(d);
|
|
2445
2457
|
return l.renderer = u.renderer, l.visible = !0, `Color renderer applied to layer: ${l.title ?? l.id} using fields ${a.join(", ")}`;
|
|
2446
2458
|
} catch (d) {
|
|
2447
2459
|
return `Error applying color renderer: ${d instanceof Error ? d.message : String(d)}`;
|
|
2448
2460
|
}
|
|
2449
2461
|
}
|
|
2450
|
-
async function
|
|
2462
|
+
async function Ho({
|
|
2451
2463
|
layerId: e,
|
|
2452
|
-
fields:
|
|
2453
|
-
colorSchemes:
|
|
2464
|
+
fields: t,
|
|
2465
|
+
colorSchemes: r,
|
|
2454
2466
|
theme: a
|
|
2455
2467
|
}, o) {
|
|
2456
2468
|
const { mapView: n } = q(o);
|
|
2457
|
-
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, o), await
|
|
2469
|
+
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, o), await Uo({
|
|
2458
2470
|
arcgisMap: n.map,
|
|
2459
2471
|
arcgisMapView: n,
|
|
2460
2472
|
layerId: e,
|
|
2461
|
-
fields:
|
|
2462
|
-
colorSchemes:
|
|
2473
|
+
fields: t,
|
|
2474
|
+
colorSchemes: r,
|
|
2463
2475
|
theme: a
|
|
2464
2476
|
});
|
|
2465
2477
|
}
|
|
2466
|
-
const
|
|
2478
|
+
const Zo = s.object({
|
|
2467
2479
|
layerId: s.string().describe("The id of the layer to apply the color renderer to"),
|
|
2468
2480
|
fields: s.array(s.string()).describe("The field(s) to use for the color renderer"),
|
|
2469
2481
|
colorSchemes: s.array(s.string()).optional().describe("Optional color scheme tags to use"),
|
|
2470
2482
|
theme: s.enum(["above-and-below", "above", "below", "centered-on", "extremes", "high-to-low"]).optional().describe("Optional theme for the color ramp")
|
|
2471
|
-
}),
|
|
2483
|
+
}), Jo = b(Ho, {
|
|
2472
2484
|
name: "color",
|
|
2473
2485
|
description: `Label: Counts and Amounts (color)
|
|
2474
2486
|
Description: Vary color along a continuous color ramp to represent numeric or ranked data.
|
|
2475
2487
|
Keywords: graduated color, choropleth, continuous color, hue, color, gradation, saturation, lightness, percent, rate, ratio, index, how much, increase, decrease
|
|
2476
2488
|
Example: Color each feature based on the population density.
|
|
2477
2489
|
Fields: This style requires a single field with a number type. A second number field may be specified for normalizing the value of the first field.`,
|
|
2478
|
-
schema:
|
|
2490
|
+
schema: Zo
|
|
2479
2491
|
});
|
|
2480
|
-
function
|
|
2481
|
-
const { fields:
|
|
2492
|
+
function Yo(e) {
|
|
2493
|
+
const { fields: t, layer: r, view: a, colorSchemeTags: o, theme: n } = e;
|
|
2482
2494
|
let i, l;
|
|
2483
|
-
const c =
|
|
2484
|
-
return o && (l =
|
|
2485
|
-
geometryType:
|
|
2495
|
+
const c = t[0];
|
|
2496
|
+
return o && (l = he({
|
|
2497
|
+
geometryType: r.geometryType,
|
|
2486
2498
|
includedTags: o,
|
|
2487
2499
|
theme: n || "high-to-low"
|
|
2488
2500
|
})[0]), {
|
|
2489
|
-
layer:
|
|
2501
|
+
layer: r,
|
|
2490
2502
|
view: a,
|
|
2491
2503
|
field: c,
|
|
2492
2504
|
normalizationField: i,
|
|
@@ -2496,20 +2508,20 @@ function Zo(e) {
|
|
|
2496
2508
|
}
|
|
2497
2509
|
};
|
|
2498
2510
|
}
|
|
2499
|
-
async function
|
|
2500
|
-
return await
|
|
2511
|
+
async function Xo(e) {
|
|
2512
|
+
return await bt(e);
|
|
2501
2513
|
}
|
|
2502
|
-
async function
|
|
2514
|
+
async function en({
|
|
2503
2515
|
arcgisMap: e,
|
|
2504
|
-
arcgisMapView:
|
|
2505
|
-
layerId:
|
|
2516
|
+
arcgisMapView: t,
|
|
2517
|
+
layerId: r,
|
|
2506
2518
|
fields: a,
|
|
2507
2519
|
colorSchemes: o,
|
|
2508
2520
|
theme: n
|
|
2509
2521
|
}) {
|
|
2510
|
-
const i =
|
|
2522
|
+
const i = t, l = e?.allLayers.find((d) => d.id === r);
|
|
2511
2523
|
if (!l)
|
|
2512
|
-
return `Could not find layer for id: ${
|
|
2524
|
+
return `Could not find layer for id: ${r}`;
|
|
2513
2525
|
const c = {
|
|
2514
2526
|
styleName: "color-size-univariate",
|
|
2515
2527
|
fields: a,
|
|
@@ -2519,75 +2531,75 @@ async function Yo({
|
|
|
2519
2531
|
theme: n
|
|
2520
2532
|
};
|
|
2521
2533
|
try {
|
|
2522
|
-
const d =
|
|
2534
|
+
const d = Yo(c), u = await Xo(d);
|
|
2523
2535
|
return l.renderer = u.renderer, l.visible = !0, `Color-size-univariate renderer applied to layer: ${l.title ?? l.id} using fields ${a.join(", ")}`;
|
|
2524
2536
|
} catch (d) {
|
|
2525
2537
|
return `Error applying color-size-univariate renderer: ${d instanceof Error ? d.message : String(d)}`;
|
|
2526
2538
|
}
|
|
2527
2539
|
}
|
|
2528
|
-
async function
|
|
2540
|
+
async function tn({
|
|
2529
2541
|
layerId: e,
|
|
2530
|
-
fields:
|
|
2531
|
-
colorSchemes:
|
|
2542
|
+
fields: t,
|
|
2543
|
+
colorSchemes: r,
|
|
2532
2544
|
theme: a
|
|
2533
2545
|
}, o) {
|
|
2534
2546
|
const { mapView: n } = q(o);
|
|
2535
|
-
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, o), await
|
|
2547
|
+
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, o), await en({
|
|
2536
2548
|
arcgisMap: n.map,
|
|
2537
2549
|
arcgisMapView: n,
|
|
2538
2550
|
layerId: e,
|
|
2539
|
-
fields:
|
|
2540
|
-
colorSchemes:
|
|
2551
|
+
fields: t,
|
|
2552
|
+
colorSchemes: r,
|
|
2541
2553
|
theme: a
|
|
2542
2554
|
});
|
|
2543
2555
|
}
|
|
2544
|
-
const
|
|
2556
|
+
const rn = s.object({
|
|
2545
2557
|
layerId: s.string().describe("The id of the layer to apply the color-size univariate renderer to"),
|
|
2546
2558
|
fields: s.array(s.string()).describe("The fields to use for the color-size univariate renderer"),
|
|
2547
2559
|
colorSchemes: s.array(s.string()).optional().describe("Optional color scheme tags to use"),
|
|
2548
2560
|
theme: s.enum(["above-and-below", "above", "below", "centered-on", "extremes", "high-to-low"]).optional().describe("Optional theme for the color and size ramps")
|
|
2549
|
-
}),
|
|
2561
|
+
}), an = b(tn, {
|
|
2550
2562
|
name: "color-size-univariate",
|
|
2551
2563
|
description: `Label: Color and Size (univariate)
|
|
2552
2564
|
Description: Vary symbol size and color based on the values of two numeric attributes.
|
|
2553
2565
|
Keywords: continuous color, hue, color, size, gradation, saturation, lightness, percent, rate, ratio, index, how much, increase, decrease, amount
|
|
2554
2566
|
Example: Color each feature based on the percentage of the population that owns a home and vary the size of each point based on total population.
|
|
2555
2567
|
Fields: This style requires at least two fields: one determining the color of each feature, the other determining the size of each feature. Each field may be normalized by an additional normalization field.`,
|
|
2556
|
-
schema:
|
|
2568
|
+
schema: rn
|
|
2557
2569
|
});
|
|
2558
|
-
function
|
|
2559
|
-
const { fields:
|
|
2570
|
+
function on(e) {
|
|
2571
|
+
const { fields: t, layer: r, view: a, colorSchemeTags: o } = e;
|
|
2560
2572
|
let n;
|
|
2561
|
-
return o && (n =
|
|
2573
|
+
return o && (n = vt({
|
|
2562
2574
|
includedTags: o,
|
|
2563
|
-
numColors: Math.min(
|
|
2575
|
+
numColors: Math.min(t.length, 8)
|
|
2564
2576
|
})[0]), {
|
|
2565
|
-
layer:
|
|
2577
|
+
layer: r,
|
|
2566
2578
|
view: a,
|
|
2567
2579
|
legendOptions: {
|
|
2568
2580
|
unit: "units"
|
|
2569
2581
|
},
|
|
2570
|
-
attributes:
|
|
2582
|
+
attributes: t.map((i) => ({
|
|
2571
2583
|
field: i,
|
|
2572
|
-
label:
|
|
2584
|
+
label: r.fields.find((l) => l.name === i)?.alias ?? ""
|
|
2573
2585
|
})).slice(0, 8),
|
|
2574
2586
|
outlineOptimizationEnabled: !0,
|
|
2575
2587
|
dotDensityScheme: n
|
|
2576
2588
|
};
|
|
2577
2589
|
}
|
|
2578
|
-
async function
|
|
2579
|
-
return await
|
|
2590
|
+
async function nn(e) {
|
|
2591
|
+
return await St(e);
|
|
2580
2592
|
}
|
|
2581
|
-
async function
|
|
2593
|
+
async function sn({
|
|
2582
2594
|
arcgisMap: e,
|
|
2583
|
-
arcgisMapView:
|
|
2584
|
-
layerId:
|
|
2595
|
+
arcgisMapView: t,
|
|
2596
|
+
layerId: r,
|
|
2585
2597
|
fields: a,
|
|
2586
2598
|
colorSchemes: o
|
|
2587
2599
|
}) {
|
|
2588
|
-
const n =
|
|
2600
|
+
const n = t, i = e?.allLayers.find((c) => c.id === r);
|
|
2589
2601
|
if (!i)
|
|
2590
|
-
return `Could not find layer for id: ${
|
|
2602
|
+
return `Could not find layer for id: ${r}`;
|
|
2591
2603
|
const l = {
|
|
2592
2604
|
styleName: "dot-density",
|
|
2593
2605
|
fields: a,
|
|
@@ -2596,31 +2608,31 @@ async function on({
|
|
|
2596
2608
|
colorSchemeTags: o
|
|
2597
2609
|
};
|
|
2598
2610
|
try {
|
|
2599
|
-
const c =
|
|
2611
|
+
const c = on(l), d = await nn(c);
|
|
2600
2612
|
return i.renderer = d.renderer, i.visible = !0, `Dot Density renderer applied to layer: ${i.title ?? i.id} using fields ${a.join(", ")}`;
|
|
2601
2613
|
} catch (c) {
|
|
2602
2614
|
return `Error applying dot density renderer: ${c instanceof Error ? c.message : String(c)}`;
|
|
2603
2615
|
}
|
|
2604
2616
|
}
|
|
2605
|
-
async function
|
|
2617
|
+
async function ln({
|
|
2606
2618
|
layerId: e,
|
|
2607
|
-
fields:
|
|
2608
|
-
colorSchemes:
|
|
2619
|
+
fields: t,
|
|
2620
|
+
colorSchemes: r
|
|
2609
2621
|
}, a) {
|
|
2610
2622
|
const { mapView: o } = q(a);
|
|
2611
|
-
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, a), await
|
|
2623
|
+
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, a), await sn({
|
|
2612
2624
|
arcgisMap: o.map,
|
|
2613
2625
|
arcgisMapView: o,
|
|
2614
2626
|
layerId: e,
|
|
2615
|
-
fields:
|
|
2616
|
-
colorSchemes:
|
|
2627
|
+
fields: t,
|
|
2628
|
+
colorSchemes: r
|
|
2617
2629
|
});
|
|
2618
2630
|
}
|
|
2619
|
-
const
|
|
2631
|
+
const cn = s.object({
|
|
2620
2632
|
layerId: s.string().describe("The id of the layer to apply the dot density renderer to"),
|
|
2621
2633
|
fields: s.array(s.string()).describe("The field(s) to use for the dot density renderer (population or count data)"),
|
|
2622
2634
|
colorSchemes: s.array(s.string()).optional().describe("Optional color scheme tags to use")
|
|
2623
|
-
}),
|
|
2635
|
+
}), dn = b(ln, {
|
|
2624
2636
|
name: "dot-density",
|
|
2625
2637
|
description: `Dot Density
|
|
2626
2638
|
Use dot density to visualize the distribution of one attribute or compare the density of multiple attributes. This is only valid for polygon layers.
|
|
@@ -2634,35 +2646,35 @@ const sn = s.object({
|
|
|
2634
2646
|
- Display demographic patterns within census tracts
|
|
2635
2647
|
**Fields:** Requires 2-8 number fields.
|
|
2636
2648
|
**Keywords:** density, how much, how many, total, number, amount`,
|
|
2637
|
-
schema:
|
|
2649
|
+
schema: cn
|
|
2638
2650
|
});
|
|
2639
|
-
function
|
|
2640
|
-
const { fields:
|
|
2651
|
+
function un(e) {
|
|
2652
|
+
const { fields: t, layer: r, view: a, colorSchemeTags: o } = e;
|
|
2641
2653
|
let n;
|
|
2642
|
-
const i =
|
|
2643
|
-
return o && (n =
|
|
2654
|
+
const i = t[0];
|
|
2655
|
+
return o && (n = xt({
|
|
2644
2656
|
includedTags: o,
|
|
2645
2657
|
basemap: a.map?.basemap || "topo"
|
|
2646
2658
|
})[0]), {
|
|
2647
|
-
layer:
|
|
2659
|
+
layer: r,
|
|
2648
2660
|
view: a,
|
|
2649
2661
|
field: i,
|
|
2650
2662
|
heatmapScheme: n
|
|
2651
2663
|
};
|
|
2652
2664
|
}
|
|
2653
|
-
async function
|
|
2654
|
-
return await
|
|
2665
|
+
async function hn(e) {
|
|
2666
|
+
return await Tt(e);
|
|
2655
2667
|
}
|
|
2656
|
-
async function
|
|
2668
|
+
async function mn({
|
|
2657
2669
|
arcgisMap: e,
|
|
2658
|
-
arcgisMapView:
|
|
2659
|
-
layerId:
|
|
2670
|
+
arcgisMapView: t,
|
|
2671
|
+
layerId: r,
|
|
2660
2672
|
fields: a,
|
|
2661
2673
|
colorSchemes: o
|
|
2662
2674
|
}) {
|
|
2663
|
-
const n =
|
|
2675
|
+
const n = t, i = e?.allLayers.find((c) => c.id === r);
|
|
2664
2676
|
if (!i)
|
|
2665
|
-
return `Could not find layer for id: ${
|
|
2677
|
+
return `Could not find layer for id: ${r}`;
|
|
2666
2678
|
const l = {
|
|
2667
2679
|
styleName: "heatmap",
|
|
2668
2680
|
fields: a,
|
|
@@ -2671,70 +2683,70 @@ async function un({
|
|
|
2671
2683
|
colorSchemeTags: o
|
|
2672
2684
|
};
|
|
2673
2685
|
try {
|
|
2674
|
-
const c =
|
|
2686
|
+
const c = un(l), d = await hn(c);
|
|
2675
2687
|
return i.renderer = d.renderer, i.visible = !0, `Heatmap renderer applied to layer: ${i.title ?? i.id} using fields ${a.join(", ")}`;
|
|
2676
2688
|
} catch (c) {
|
|
2677
2689
|
return `Error applying heatmap renderer: ${c instanceof Error ? c.message : String(c)}`;
|
|
2678
2690
|
}
|
|
2679
2691
|
}
|
|
2680
|
-
async function
|
|
2692
|
+
async function pn({
|
|
2681
2693
|
layerId: e,
|
|
2682
|
-
fields:
|
|
2683
|
-
colorSchemes:
|
|
2694
|
+
fields: t,
|
|
2695
|
+
colorSchemes: r
|
|
2684
2696
|
}, a) {
|
|
2685
2697
|
const { mapView: o } = q(a);
|
|
2686
|
-
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, a), await
|
|
2698
|
+
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, a), await mn({
|
|
2687
2699
|
arcgisMap: o.map,
|
|
2688
2700
|
arcgisMapView: o,
|
|
2689
2701
|
layerId: e,
|
|
2690
|
-
fields:
|
|
2691
|
-
colorSchemes:
|
|
2702
|
+
fields: t,
|
|
2703
|
+
colorSchemes: r
|
|
2692
2704
|
});
|
|
2693
2705
|
}
|
|
2694
|
-
const
|
|
2706
|
+
const yn = s.object({
|
|
2695
2707
|
layerId: s.string().describe("The id of the layer to apply the heatmap renderer to"),
|
|
2696
2708
|
fields: s.array(s.string()).describe("The field(s) to use for the heatmap renderer (typically point density)"),
|
|
2697
2709
|
colorSchemes: s.array(s.string()).optional().describe("Optional color scheme tags to use")
|
|
2698
|
-
}),
|
|
2710
|
+
}), fn = b(pn, {
|
|
2699
2711
|
name: "heatmap",
|
|
2700
2712
|
description: `Label: Heat Map
|
|
2701
2713
|
Description: Show areas of high density with colors that appear to glow hotter. This is only valid for point layers.
|
|
2702
2714
|
Keywords: density, heatmap, hot spots, pattern, cluster
|
|
2703
2715
|
Example: Create a heatmap
|
|
2704
2716
|
Fields: This typically requires zero or one field of type number.`,
|
|
2705
|
-
schema:
|
|
2717
|
+
schema: yn
|
|
2706
2718
|
});
|
|
2707
|
-
function
|
|
2708
|
-
const { fields:
|
|
2719
|
+
function gn(e) {
|
|
2720
|
+
const { fields: t, layer: r, view: a, styleName: o, colorSchemeTags: n } = e;
|
|
2709
2721
|
let i;
|
|
2710
|
-
return n && (i =
|
|
2711
|
-
geometryType:
|
|
2722
|
+
return n && (i = $t({
|
|
2723
|
+
geometryType: r.geometryType,
|
|
2712
2724
|
includedTags: n,
|
|
2713
|
-
numColors: Math.min(
|
|
2725
|
+
numColors: Math.min(t.length, 10)
|
|
2714
2726
|
})[0]), {
|
|
2715
|
-
layer:
|
|
2727
|
+
layer: r,
|
|
2716
2728
|
view: a,
|
|
2717
|
-
fields:
|
|
2729
|
+
fields: t.map((l) => ({ name: l })).slice(0, 9),
|
|
2718
2730
|
outlineOptimizationEnabled: !0,
|
|
2719
2731
|
sizeOptimizationEnabled: !0,
|
|
2720
2732
|
includeSizeVariable: o.includes("Size"),
|
|
2721
2733
|
predominanceScheme: i
|
|
2722
2734
|
};
|
|
2723
2735
|
}
|
|
2724
|
-
async function
|
|
2725
|
-
return await
|
|
2736
|
+
async function wn(e) {
|
|
2737
|
+
return await Et(e);
|
|
2726
2738
|
}
|
|
2727
|
-
async function
|
|
2739
|
+
async function bn({
|
|
2728
2740
|
arcgisMap: e,
|
|
2729
|
-
arcgisMapView:
|
|
2730
|
-
layerId:
|
|
2741
|
+
arcgisMapView: t,
|
|
2742
|
+
layerId: r,
|
|
2731
2743
|
fields: a,
|
|
2732
2744
|
colorSchemes: o,
|
|
2733
2745
|
includeSize: n
|
|
2734
2746
|
}) {
|
|
2735
|
-
const i =
|
|
2747
|
+
const i = t, l = e?.allLayers.find((u) => u.id === r);
|
|
2736
2748
|
if (!l)
|
|
2737
|
-
return `Could not find layer for id: ${
|
|
2749
|
+
return `Could not find layer for id: ${r}`;
|
|
2738
2750
|
const d = {
|
|
2739
2751
|
styleName: n ? "predominance-size" : "predominance",
|
|
2740
2752
|
fields: a,
|
|
@@ -2743,34 +2755,34 @@ async function gn({
|
|
|
2743
2755
|
colorSchemeTags: o
|
|
2744
2756
|
};
|
|
2745
2757
|
try {
|
|
2746
|
-
const u =
|
|
2758
|
+
const u = gn(d), h = await wn(u);
|
|
2747
2759
|
return l.renderer = h.renderer, l.visible = !0, `Predominance renderer applied to layer: ${l.title ?? l.id} using fields ${a.join(", ")}`;
|
|
2748
2760
|
} catch (u) {
|
|
2749
2761
|
return `Error applying predominance renderer: ${u instanceof Error ? u.message : String(u)}`;
|
|
2750
2762
|
}
|
|
2751
2763
|
}
|
|
2752
|
-
async function
|
|
2764
|
+
async function Sn({
|
|
2753
2765
|
layerId: e,
|
|
2754
|
-
fields:
|
|
2755
|
-
colorSchemes:
|
|
2766
|
+
fields: t,
|
|
2767
|
+
colorSchemes: r,
|
|
2756
2768
|
includeSize: a
|
|
2757
2769
|
}, o) {
|
|
2758
2770
|
const { mapView: n } = q(o);
|
|
2759
|
-
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, o), await
|
|
2771
|
+
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, o), await bn({
|
|
2760
2772
|
arcgisMap: n.map,
|
|
2761
2773
|
arcgisMapView: n,
|
|
2762
2774
|
layerId: e,
|
|
2763
|
-
fields:
|
|
2764
|
-
colorSchemes:
|
|
2775
|
+
fields: t,
|
|
2776
|
+
colorSchemes: r,
|
|
2765
2777
|
includeSize: a
|
|
2766
2778
|
});
|
|
2767
2779
|
}
|
|
2768
|
-
const
|
|
2780
|
+
const vn = s.object({
|
|
2769
2781
|
layerId: s.string().describe("The id of the layer to apply the predominance renderer to"),
|
|
2770
2782
|
fields: s.array(s.string()).describe("The fields to use for the predominance renderer (competing categories)"),
|
|
2771
2783
|
colorSchemes: s.array(s.string()).optional().describe("Optional color scheme tags to use"),
|
|
2772
2784
|
includeSize: s.boolean().optional().describe("Whether to include size visualization (predominance-size)")
|
|
2773
|
-
}),
|
|
2785
|
+
}), Tn = b(Sn, {
|
|
2774
2786
|
name: "predominance",
|
|
2775
2787
|
description: `Label: Predominant category
|
|
2776
2788
|
Description: Compare attributes that share a common subject and unit of measurement to see which has the highest value.
|
|
@@ -2783,21 +2795,21 @@ const bn = s.object({
|
|
|
2783
2795
|
Keywords: predominant, winner, won, competing, most, most common, most frequent, dominant, prevalent, top, amount, total, how much, proportional size, graduated size, sum
|
|
2784
2796
|
Example: Show the predominant crop in each area and vary the size of each symbol based on the total of all categories.
|
|
2785
2797
|
Fields: This style relies on 2-10 number fields.`,
|
|
2786
|
-
schema:
|
|
2798
|
+
schema: vn
|
|
2787
2799
|
});
|
|
2788
|
-
function
|
|
2789
|
-
const { fields:
|
|
2800
|
+
function xn(e) {
|
|
2801
|
+
const { fields: t, layer: r, view: a, colorSchemeTags: o } = e;
|
|
2790
2802
|
let n;
|
|
2791
2803
|
const i = {
|
|
2792
|
-
field:
|
|
2804
|
+
field: t[0]
|
|
2793
2805
|
}, l = {
|
|
2794
|
-
field:
|
|
2806
|
+
field: t[1]
|
|
2795
2807
|
};
|
|
2796
|
-
return o && (n =
|
|
2797
|
-
geometryType:
|
|
2808
|
+
return o && (n = Rt({
|
|
2809
|
+
geometryType: r.geometryType,
|
|
2798
2810
|
includedTags: o
|
|
2799
2811
|
})[0]), {
|
|
2800
|
-
layer:
|
|
2812
|
+
layer: r,
|
|
2801
2813
|
view: a,
|
|
2802
2814
|
field1: i,
|
|
2803
2815
|
field2: l,
|
|
@@ -2806,19 +2818,19 @@ function vn(e) {
|
|
|
2806
2818
|
relationshipScheme: n
|
|
2807
2819
|
};
|
|
2808
2820
|
}
|
|
2809
|
-
async function
|
|
2810
|
-
return await
|
|
2821
|
+
async function En(e) {
|
|
2822
|
+
return await Ft(e);
|
|
2811
2823
|
}
|
|
2812
|
-
async function
|
|
2824
|
+
async function $n({
|
|
2813
2825
|
arcgisMap: e,
|
|
2814
|
-
arcgisMapView:
|
|
2815
|
-
layerId:
|
|
2826
|
+
arcgisMapView: t,
|
|
2827
|
+
layerId: r,
|
|
2816
2828
|
fields: a,
|
|
2817
2829
|
colorSchemes: o
|
|
2818
2830
|
}) {
|
|
2819
|
-
const n =
|
|
2831
|
+
const n = t, i = e?.allLayers.find((c) => c.id === r);
|
|
2820
2832
|
if (!i)
|
|
2821
|
-
return `Could not find layer for id: ${
|
|
2833
|
+
return `Could not find layer for id: ${r}`;
|
|
2822
2834
|
const l = {
|
|
2823
2835
|
styleName: "relationship",
|
|
2824
2836
|
fields: a,
|
|
@@ -2827,43 +2839,43 @@ async function xn({
|
|
|
2827
2839
|
colorSchemeTags: o
|
|
2828
2840
|
};
|
|
2829
2841
|
try {
|
|
2830
|
-
const c =
|
|
2842
|
+
const c = xn(l), d = await En(c);
|
|
2831
2843
|
return i.renderer = d.renderer, i.visible = !0, `Relationship renderer applied to layer: ${i.title ?? i.id} using fields ${a.join(", ")}`;
|
|
2832
2844
|
} catch (c) {
|
|
2833
2845
|
return `Error applying relationship renderer: ${c instanceof Error ? c.message : String(c)}`;
|
|
2834
2846
|
}
|
|
2835
2847
|
}
|
|
2836
|
-
async function
|
|
2848
|
+
async function Fn({
|
|
2837
2849
|
layerId: e,
|
|
2838
|
-
fields:
|
|
2839
|
-
colorSchemes:
|
|
2850
|
+
fields: t,
|
|
2851
|
+
colorSchemes: r
|
|
2840
2852
|
}, a) {
|
|
2841
2853
|
const { mapView: o } = q(a);
|
|
2842
|
-
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, a), await
|
|
2854
|
+
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, a), await $n({
|
|
2843
2855
|
arcgisMap: o.map,
|
|
2844
2856
|
arcgisMapView: o,
|
|
2845
2857
|
layerId: e,
|
|
2846
|
-
fields:
|
|
2847
|
-
colorSchemes:
|
|
2858
|
+
fields: t,
|
|
2859
|
+
colorSchemes: r
|
|
2848
2860
|
});
|
|
2849
2861
|
}
|
|
2850
|
-
const
|
|
2862
|
+
const Rn = s.object({
|
|
2851
2863
|
layerId: s.string().describe("The id of the layer to apply the relationship renderer to"),
|
|
2852
2864
|
fields: s.array(s.string()).describe("The two fields to use for the relationship renderer (bivariate visualization)"),
|
|
2853
2865
|
colorSchemes: s.array(s.string()).optional().describe("Optional color scheme tags to use")
|
|
2854
|
-
}),
|
|
2866
|
+
}), Ln = b(Fn, {
|
|
2855
2867
|
name: "relationship",
|
|
2856
2868
|
description: `Label: Relationship
|
|
2857
2869
|
Description: Overlays two color ramps to represent the relationship between two numeric attributes.
|
|
2858
2870
|
Keywords: relationship, correlation, compare, related, bivariate choropleth, bivariate color
|
|
2859
2871
|
Example: Show the relationship between tree height and carbon storage
|
|
2860
2872
|
Fields: This style requires two number fields.`,
|
|
2861
|
-
schema:
|
|
2873
|
+
schema: Rn
|
|
2862
2874
|
});
|
|
2863
|
-
function
|
|
2864
|
-
const { fields:
|
|
2875
|
+
function In(e) {
|
|
2876
|
+
const { fields: t, layer: r, view: a, theme: o } = e, n = t[0];
|
|
2865
2877
|
return {
|
|
2866
|
-
layer:
|
|
2878
|
+
layer: r,
|
|
2867
2879
|
view: a,
|
|
2868
2880
|
startTime: n,
|
|
2869
2881
|
endTime: /* @__PURE__ */ new Date(),
|
|
@@ -2872,20 +2884,20 @@ function Rn(e) {
|
|
|
2872
2884
|
outlineOptimizationEnabled: !0
|
|
2873
2885
|
};
|
|
2874
2886
|
}
|
|
2875
|
-
async function
|
|
2876
|
-
return await
|
|
2887
|
+
async function qn(e) {
|
|
2888
|
+
return await Lt(e);
|
|
2877
2889
|
}
|
|
2878
|
-
async function
|
|
2890
|
+
async function Cn({
|
|
2879
2891
|
arcgisMap: e,
|
|
2880
|
-
arcgisMapView:
|
|
2881
|
-
layerId:
|
|
2892
|
+
arcgisMapView: t,
|
|
2893
|
+
layerId: r,
|
|
2882
2894
|
fields: a,
|
|
2883
2895
|
colorSchemes: o,
|
|
2884
2896
|
theme: n
|
|
2885
2897
|
}) {
|
|
2886
|
-
const i =
|
|
2898
|
+
const i = t, l = e?.allLayers.find((d) => d.id === r);
|
|
2887
2899
|
if (!l)
|
|
2888
|
-
return `Could not find layer for id: ${
|
|
2900
|
+
return `Could not find layer for id: ${r}`;
|
|
2889
2901
|
const c = {
|
|
2890
2902
|
styleName: "size-age",
|
|
2891
2903
|
fields: a,
|
|
@@ -2895,48 +2907,48 @@ async function In({
|
|
|
2895
2907
|
theme: n
|
|
2896
2908
|
};
|
|
2897
2909
|
try {
|
|
2898
|
-
const d =
|
|
2910
|
+
const d = In(c), u = await qn(d);
|
|
2899
2911
|
return l.renderer = u.renderer, l.visible = !0, `Size-age renderer applied to layer: ${l.title ?? l.id} using fields ${a.join(", ")}`;
|
|
2900
2912
|
} catch (d) {
|
|
2901
2913
|
return `Error applying size-age renderer: ${d instanceof Error ? d.message : String(d)}`;
|
|
2902
2914
|
}
|
|
2903
2915
|
}
|
|
2904
|
-
async function
|
|
2916
|
+
async function An({
|
|
2905
2917
|
layerId: e,
|
|
2906
|
-
fields:
|
|
2907
|
-
colorSchemes:
|
|
2918
|
+
fields: t,
|
|
2919
|
+
colorSchemes: r,
|
|
2908
2920
|
theme: a
|
|
2909
2921
|
}, o) {
|
|
2910
2922
|
const { mapView: n } = q(o);
|
|
2911
|
-
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, o), await
|
|
2923
|
+
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, o), await Cn({
|
|
2912
2924
|
arcgisMap: n.map,
|
|
2913
2925
|
arcgisMapView: n,
|
|
2914
2926
|
layerId: e,
|
|
2915
|
-
fields:
|
|
2916
|
-
colorSchemes:
|
|
2927
|
+
fields: t,
|
|
2928
|
+
colorSchemes: r,
|
|
2917
2929
|
theme: a
|
|
2918
2930
|
});
|
|
2919
2931
|
}
|
|
2920
|
-
const
|
|
2932
|
+
const kn = s.object({
|
|
2921
2933
|
layerId: s.string().describe("The id of the layer to apply the size-age renderer to"),
|
|
2922
2934
|
fields: s.array(s.string()).describe("The field(s) to use for the size-age renderer (temporal data with size)"),
|
|
2923
2935
|
colorSchemes: s.array(s.string()).optional().describe("Optional color scheme tags to use"),
|
|
2924
2936
|
theme: s.enum(["above-and-below", "above", "below", "centered-on", "extremes", "high-to-low"]).optional().describe("Optional theme for the size ramp")
|
|
2925
|
-
}),
|
|
2937
|
+
}), Nn = b(An, {
|
|
2926
2938
|
name: "size-age",
|
|
2927
2939
|
description: `Label: Age (size)
|
|
2928
2940
|
Description: Vary symbol sizes along a continuous ramp to represent the age of features. Age reflects the length of time from a start date to an end date.
|
|
2929
2941
|
Keywords: since, age, how old, how long
|
|
2930
2942
|
Example: Change the size of features so older features are larger than new features.
|
|
2931
2943
|
Fields: This style requires at least one field with a date type.`,
|
|
2932
|
-
schema:
|
|
2944
|
+
schema: kn
|
|
2933
2945
|
});
|
|
2934
|
-
function
|
|
2935
|
-
const { fields:
|
|
2936
|
-
let { theme: o } = e, n =
|
|
2937
|
-
const i =
|
|
2946
|
+
function zn(e) {
|
|
2947
|
+
const { fields: t, layer: r, view: a } = e;
|
|
2948
|
+
let { theme: o } = e, n = t[1];
|
|
2949
|
+
const i = t[0];
|
|
2938
2950
|
return {
|
|
2939
|
-
layer:
|
|
2951
|
+
layer: r,
|
|
2940
2952
|
view: a,
|
|
2941
2953
|
field: i,
|
|
2942
2954
|
normalizationField: n,
|
|
@@ -2945,20 +2957,20 @@ function kn(e) {
|
|
|
2945
2957
|
outlineOptimizationEnabled: !0
|
|
2946
2958
|
};
|
|
2947
2959
|
}
|
|
2948
|
-
async function
|
|
2949
|
-
return await
|
|
2960
|
+
async function _n(e) {
|
|
2961
|
+
return await It(e);
|
|
2950
2962
|
}
|
|
2951
|
-
async function
|
|
2963
|
+
async function jn({
|
|
2952
2964
|
arcgisMap: e,
|
|
2953
|
-
arcgisMapView:
|
|
2954
|
-
layerId:
|
|
2965
|
+
arcgisMapView: t,
|
|
2966
|
+
layerId: r,
|
|
2955
2967
|
fields: a,
|
|
2956
2968
|
colorSchemes: o,
|
|
2957
2969
|
theme: n
|
|
2958
2970
|
}) {
|
|
2959
|
-
const i =
|
|
2971
|
+
const i = t, l = e?.allLayers.find((d) => d.id === r);
|
|
2960
2972
|
if (!l)
|
|
2961
|
-
return `Could not find layer for id: ${
|
|
2973
|
+
return `Could not find layer for id: ${r}`;
|
|
2962
2974
|
const c = {
|
|
2963
2975
|
styleName: "size",
|
|
2964
2976
|
fields: a,
|
|
@@ -2968,34 +2980,34 @@ async function zn({
|
|
|
2968
2980
|
theme: n
|
|
2969
2981
|
};
|
|
2970
2982
|
try {
|
|
2971
|
-
const d =
|
|
2983
|
+
const d = zn(c), u = await _n(d);
|
|
2972
2984
|
return l.renderer = u.renderer, l.visible = !0, `Size renderer applied to layer: ${l.title ?? l.id} using fields ${a.join(", ")}`;
|
|
2973
2985
|
} catch (d) {
|
|
2974
2986
|
return `Error applying size renderer: ${d instanceof Error ? d.message : String(d)}`;
|
|
2975
2987
|
}
|
|
2976
2988
|
}
|
|
2977
|
-
async function
|
|
2989
|
+
async function Mn({
|
|
2978
2990
|
layerId: e,
|
|
2979
|
-
fields:
|
|
2980
|
-
colorSchemes:
|
|
2991
|
+
fields: t,
|
|
2992
|
+
colorSchemes: r,
|
|
2981
2993
|
theme: a
|
|
2982
2994
|
}, o) {
|
|
2983
2995
|
const { mapView: n } = q(o);
|
|
2984
|
-
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, o), await
|
|
2996
|
+
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, o), await jn({
|
|
2985
2997
|
arcgisMap: n.map,
|
|
2986
2998
|
arcgisMapView: n,
|
|
2987
2999
|
layerId: e,
|
|
2988
|
-
fields:
|
|
2989
|
-
colorSchemes:
|
|
3000
|
+
fields: t,
|
|
3001
|
+
colorSchemes: r,
|
|
2990
3002
|
theme: a
|
|
2991
3003
|
});
|
|
2992
3004
|
}
|
|
2993
|
-
const
|
|
3005
|
+
const Pn = s.object({
|
|
2994
3006
|
layerId: s.string().describe("The id of the layer to apply the size renderer to"),
|
|
2995
3007
|
fields: s.array(s.string()).describe("The field(s) to use for the size renderer (numeric data)"),
|
|
2996
3008
|
colorSchemes: s.array(s.string()).optional().describe("Optional color scheme tags to use"),
|
|
2997
3009
|
theme: s.enum(["above-and-below", "above", "below", "centered-on", "extremes", "high-to-low"]).optional().describe("Optional theme for the size ramp")
|
|
2998
|
-
}),
|
|
3010
|
+
}), Dn = b(Mn, {
|
|
2999
3011
|
name: "size",
|
|
3000
3012
|
description: `Label: Counts and Amounts (size)
|
|
3001
3013
|
Description: Vary symbol sizes along a continuous ramp to represent numeric or ranked data.
|
|
@@ -3008,16 +3020,16 @@ const jn = s.object({
|
|
|
3008
3020
|
Keywords: graduated size, proportional size, classed size, how much, total, number, when
|
|
3009
3021
|
Example: Vary the size of each feature based on the date a ticket was completed.
|
|
3010
3022
|
Fields: This style requires a single field with a date type.`,
|
|
3011
|
-
schema:
|
|
3023
|
+
schema: Pn
|
|
3012
3024
|
});
|
|
3013
|
-
function
|
|
3014
|
-
const { fields:
|
|
3025
|
+
function Gn(e) {
|
|
3026
|
+
const { fields: t, layer: r, view: a, colorSchemeTags: o } = e, n = t[0], i = t[1], l = t[2];
|
|
3015
3027
|
let c;
|
|
3016
|
-
return o && (c =
|
|
3017
|
-
geometryType:
|
|
3028
|
+
return o && (c = Ct({
|
|
3029
|
+
geometryType: r.geometryType,
|
|
3018
3030
|
includedTags: o
|
|
3019
3031
|
})[0]), {
|
|
3020
|
-
layer:
|
|
3032
|
+
layer: r,
|
|
3021
3033
|
view: a,
|
|
3022
3034
|
field: n,
|
|
3023
3035
|
field2: i,
|
|
@@ -3027,20 +3039,20 @@ function Pn(e) {
|
|
|
3027
3039
|
typeScheme: c
|
|
3028
3040
|
};
|
|
3029
3041
|
}
|
|
3030
|
-
async function
|
|
3031
|
-
return await
|
|
3042
|
+
async function On(e) {
|
|
3043
|
+
return await qt(e);
|
|
3032
3044
|
}
|
|
3033
|
-
async function
|
|
3045
|
+
async function Qn({
|
|
3034
3046
|
arcgisMap: e,
|
|
3035
|
-
arcgisMapView:
|
|
3036
|
-
layerId:
|
|
3047
|
+
arcgisMapView: t,
|
|
3048
|
+
layerId: r,
|
|
3037
3049
|
fields: a,
|
|
3038
3050
|
colorSchemes: o,
|
|
3039
3051
|
theme: n
|
|
3040
3052
|
}) {
|
|
3041
|
-
const i =
|
|
3053
|
+
const i = t, l = e?.allLayers.find((d) => d.id === r);
|
|
3042
3054
|
if (!l)
|
|
3043
|
-
return `Could not find layer for id: ${
|
|
3055
|
+
return `Could not find layer for id: ${r}`;
|
|
3044
3056
|
const c = {
|
|
3045
3057
|
styleName: "type",
|
|
3046
3058
|
fields: a,
|
|
@@ -3050,83 +3062,83 @@ async function Gn({
|
|
|
3050
3062
|
theme: n
|
|
3051
3063
|
};
|
|
3052
3064
|
try {
|
|
3053
|
-
const d =
|
|
3065
|
+
const d = Gn(c), u = await On(d);
|
|
3054
3066
|
return l.renderer = u.renderer, l.visible = !0, `Type renderer applied to layer: ${l.title ?? l.id} using fields ${a.join(", ")}`;
|
|
3055
3067
|
} catch (d) {
|
|
3056
3068
|
return `Error applying type renderer: ${d instanceof Error ? d.message : String(d)}`;
|
|
3057
3069
|
}
|
|
3058
3070
|
}
|
|
3059
|
-
async function
|
|
3071
|
+
async function Vn({
|
|
3060
3072
|
layerId: e,
|
|
3061
|
-
fields:
|
|
3062
|
-
colorSchemes:
|
|
3073
|
+
fields: t,
|
|
3074
|
+
colorSchemes: r,
|
|
3063
3075
|
theme: a
|
|
3064
3076
|
}, o) {
|
|
3065
3077
|
const { mapView: n } = q(o);
|
|
3066
|
-
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, o), await
|
|
3078
|
+
return await L({ id: "show-legend", description: "Show Legend", payload: { layerIds: [e] } }, o), await Qn({
|
|
3067
3079
|
arcgisMap: n.map,
|
|
3068
3080
|
arcgisMapView: n,
|
|
3069
3081
|
layerId: e,
|
|
3070
|
-
fields:
|
|
3071
|
-
colorSchemes:
|
|
3082
|
+
fields: t,
|
|
3083
|
+
colorSchemes: r,
|
|
3072
3084
|
theme: a
|
|
3073
3085
|
});
|
|
3074
3086
|
}
|
|
3075
|
-
const
|
|
3087
|
+
const Wn = s.object({
|
|
3076
3088
|
layerId: s.string().describe("The id of the layer to apply the type renderer to"),
|
|
3077
3089
|
fields: s.array(s.string()).describe("The field(s) to use for the type renderer (categorical data)"),
|
|
3078
3090
|
colorSchemes: s.array(s.string()).optional().describe("Optional color scheme tags to use"),
|
|
3079
3091
|
theme: s.enum(["above-and-below", "above", "below", "centered-on", "extremes", "high-to-low"]).optional().describe("Optional theme for the color scheme")
|
|
3080
|
-
}),
|
|
3092
|
+
}), Bn = b(Vn, {
|
|
3081
3093
|
name: "type",
|
|
3082
3094
|
description: `Label: Types (unique symbols)
|
|
3083
3095
|
Description: Represent features as categories with different symbol colors or shapes. Examples include type of tree, road class, or province name.
|
|
3084
3096
|
Keywords: categorical, category, type, unique, discrete, point of interest, region, group
|
|
3085
3097
|
Example: Color each feature based on the region it belongs to
|
|
3086
3098
|
Fields: This style requires a single field which may be a string, number, or date type. It is usually a string.`,
|
|
3087
|
-
schema:
|
|
3088
|
-
}),
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
],
|
|
3101
|
-
await
|
|
3102
|
-
const
|
|
3103
|
-
if (!
|
|
3099
|
+
schema: Wn
|
|
3100
|
+
}), Ye = [
|
|
3101
|
+
Po,
|
|
3102
|
+
Wo,
|
|
3103
|
+
Jo,
|
|
3104
|
+
an,
|
|
3105
|
+
dn,
|
|
3106
|
+
fn,
|
|
3107
|
+
Tn,
|
|
3108
|
+
Ln,
|
|
3109
|
+
Nn,
|
|
3110
|
+
Dn,
|
|
3111
|
+
Bn
|
|
3112
|
+
], Kn = async (e, t) => {
|
|
3113
|
+
await m({ text: "Requesting LLM for layer query results" }, t);
|
|
3114
|
+
const r = await F("navigation_intent_prompt");
|
|
3115
|
+
if (!t?.configurable)
|
|
3104
3116
|
throw new Error("config.configurable is required for layer query tools");
|
|
3105
3117
|
const a = {
|
|
3106
3118
|
layerFieldInfo: e.layerFieldInfo
|
|
3107
3119
|
}, o = await M({
|
|
3108
|
-
promptText:
|
|
3120
|
+
promptText: r,
|
|
3109
3121
|
modelTier: "advanced",
|
|
3110
3122
|
messages: x(e.messages),
|
|
3111
3123
|
inputVariables: a,
|
|
3112
|
-
tools:
|
|
3124
|
+
tools: Ye
|
|
3113
3125
|
});
|
|
3114
|
-
return await
|
|
3126
|
+
return await H(o, t), { ...e, messages: [...e.messages, o] };
|
|
3115
3127
|
};
|
|
3116
|
-
async function
|
|
3117
|
-
const a = await new P(
|
|
3128
|
+
async function Un(e, t) {
|
|
3129
|
+
const a = await new P(Ye).invoke(
|
|
3118
3130
|
{
|
|
3119
3131
|
messages: x(e.messages)
|
|
3120
3132
|
},
|
|
3121
|
-
|
|
3133
|
+
t
|
|
3122
3134
|
), o = a.messages.map((i) => i.text).join(`
|
|
3123
3135
|
`);
|
|
3124
|
-
await
|
|
3136
|
+
await m({ text: `Finished executing layer filter tool: ${o}` }, t);
|
|
3125
3137
|
const n = a.messages.map((i) => i.text).join(`
|
|
3126
3138
|
`);
|
|
3127
3139
|
return { ...e, outputMessage: n };
|
|
3128
3140
|
}
|
|
3129
|
-
const
|
|
3141
|
+
const Xe = g.Root({
|
|
3130
3142
|
// Inputs coming from global context
|
|
3131
3143
|
messages: g({
|
|
3132
3144
|
reducer: z,
|
|
@@ -3137,21 +3149,21 @@ const Ye = g.Root({
|
|
|
3137
3149
|
// This avoids duplicate output when tool nodes and final LLM nodes
|
|
3138
3150
|
// emit the same text during a single agent turn.
|
|
3139
3151
|
outputMessage: g({
|
|
3140
|
-
reducer: (e = "",
|
|
3141
|
-
const
|
|
3142
|
-
if (!
|
|
3152
|
+
reducer: (e = "", t) => {
|
|
3153
|
+
const r = typeof t == "string" ? t.trim() : "";
|
|
3154
|
+
if (!r)
|
|
3143
3155
|
return e;
|
|
3144
3156
|
const a = e.trim();
|
|
3145
3157
|
if (!a)
|
|
3146
|
-
return
|
|
3147
|
-
if (a ===
|
|
3158
|
+
return r;
|
|
3159
|
+
if (a === r)
|
|
3148
3160
|
return e;
|
|
3149
3161
|
const o = a.split(`
|
|
3150
3162
|
|
|
3151
3163
|
`);
|
|
3152
|
-
return o[o.length - 1]?.trim() ===
|
|
3164
|
+
return o[o.length - 1]?.trim() === r ? e : `${e}
|
|
3153
3165
|
|
|
3154
|
-
${
|
|
3166
|
+
${r}`;
|
|
3155
3167
|
},
|
|
3156
3168
|
default: () => ""
|
|
3157
3169
|
}),
|
|
@@ -3159,10 +3171,10 @@ ${t}`;
|
|
|
3159
3171
|
vectorSearchFieldResults: g(),
|
|
3160
3172
|
layerFieldInfo: g(),
|
|
3161
3173
|
selectedLayerId: g()
|
|
3162
|
-
}),
|
|
3174
|
+
}), Hn = async (e, t) => (await m({ text: "Exiting Layer Styling agent" }, t), e), Zn = async (e, t) => {
|
|
3163
3175
|
try {
|
|
3164
|
-
await
|
|
3165
|
-
const
|
|
3176
|
+
await m({ text: "Populating layer and field info" }, t);
|
|
3177
|
+
const r = [];
|
|
3166
3178
|
for (const a of e.vectorSearchFieldResults) {
|
|
3167
3179
|
let o = function(u) {
|
|
3168
3180
|
const h = l.get(u)?.layerItem;
|
|
@@ -3172,61 +3184,61 @@ ${t}`;
|
|
|
3172
3184
|
h.description && `Description: ${h.description}`
|
|
3173
3185
|
].filter(Boolean).join(" | ") : u;
|
|
3174
3186
|
};
|
|
3175
|
-
const { layerId: n, results: i } = a, l = S(
|
|
3187
|
+
const { layerId: n, results: i } = a, l = S(t, "layersAndFieldsRegistry"), c = l.get(n)?.fieldRegistry;
|
|
3176
3188
|
if (!c)
|
|
3177
3189
|
continue;
|
|
3178
|
-
let d =
|
|
3190
|
+
let d = r.find((u) => u.layerId === n);
|
|
3179
3191
|
d || (d = {
|
|
3180
3192
|
layerId: n,
|
|
3181
3193
|
layerSummary: o(n),
|
|
3182
3194
|
fieldInfos: []
|
|
3183
|
-
},
|
|
3195
|
+
}, r.push(d));
|
|
3184
3196
|
for (const u of i) {
|
|
3185
3197
|
const h = c.get(u.name);
|
|
3186
3198
|
h && d.fieldInfos.push(h);
|
|
3187
3199
|
}
|
|
3188
3200
|
}
|
|
3189
|
-
return await
|
|
3190
|
-
} catch (
|
|
3191
|
-
throw await
|
|
3201
|
+
return await m({ text: "Populated layerFieldInfo" }, t), { ...e, layerFieldInfo: r };
|
|
3202
|
+
} catch (r) {
|
|
3203
|
+
throw await m({ text: "Error populating layerFieldInfo" }, t), new Error(`Error populating layerFieldInfo: ${r instanceof Error ? r.message : String(r)}`);
|
|
3192
3204
|
}
|
|
3193
|
-
},
|
|
3194
|
-
const
|
|
3195
|
-
if (
|
|
3205
|
+
}, Jn = (e, t) => {
|
|
3206
|
+
const r = e.vectorSearchLayerIds ?? [];
|
|
3207
|
+
if (r.length <= 1)
|
|
3196
3208
|
return { ...e, selectedLayerId: e.vectorSearchLayerIds[0] };
|
|
3197
|
-
const { hitlResponse: a } =
|
|
3198
|
-
if (!a || a.agentId !==
|
|
3209
|
+
const { hitlResponse: a } = t.configurable;
|
|
3210
|
+
if (!a || a.agentId !== Ae.id || a.id !== "reviewLayerSelection") {
|
|
3199
3211
|
const n = {
|
|
3200
|
-
agentId:
|
|
3212
|
+
agentId: Ae.id,
|
|
3201
3213
|
id: "reviewLayerSelection",
|
|
3202
3214
|
kind: "singleSelection",
|
|
3203
3215
|
message: "Choose a layer to apply the styles.",
|
|
3204
|
-
metadata: [...
|
|
3216
|
+
metadata: [...r]
|
|
3205
3217
|
};
|
|
3206
|
-
throw new
|
|
3218
|
+
throw new lt(n);
|
|
3207
3219
|
}
|
|
3208
3220
|
let o = null;
|
|
3209
3221
|
return Array.isArray(a.payload) && a.payload.length > 0 && (o = a.payload[0]), {
|
|
3210
3222
|
...e,
|
|
3211
3223
|
selectedLayerId: o ?? e.vectorSearchLayerIds[0]
|
|
3212
3224
|
};
|
|
3213
|
-
},
|
|
3225
|
+
}, Yn = (e, t) => D(["layerSearch", "fieldSearch", "layersAndFieldsRegistry"], "Layer Styling Agent")(e, t), Xn = () => new _(Xe).addNode("requireLayerStylingServices", Yn).addNode("vectorSearchLayers", Ao).addNode("layerSelectionHITL", Jn).addNode("vectorSearchFields", qo).addNode("populateLayerFieldInfo", Zn).addNode("agent", Kn).addNode("tools", Un).addNode("earlyExit", Hn).addEdge(j, "requireLayerStylingServices").addEdge("requireLayerStylingServices", "vectorSearchLayers").addConditionalEdges(
|
|
3214
3226
|
"layerSelectionHITL",
|
|
3215
|
-
(
|
|
3227
|
+
(t) => t.vectorSearchLayerIds.length ? "vectorSearchFields" : "earlyExit"
|
|
3216
3228
|
).addConditionalEdges(
|
|
3217
3229
|
"vectorSearchFields",
|
|
3218
|
-
(
|
|
3219
|
-
).addEdge("populateLayerFieldInfo", "agent").addEdge("agent", "tools").addEdge("tools", R).addEdge("earlyExit", R),
|
|
3230
|
+
(t) => t.vectorSearchFieldResults.length ? "populateLayerFieldInfo" : "earlyExit"
|
|
3231
|
+
).addEdge("populateLayerFieldInfo", "agent").addEdge("agent", "tools").addEdge("tools", R).addEdge("earlyExit", R), es = String.raw`- **layerStyling** — User wants to change how features are drawn or styled on the map based on their data, such as applying color, size, transparency, symbols, or charts according to field values.
|
|
3220
3232
|
_Example: “Color points by sales amount”_
|
|
3221
3233
|
_Example: “Show population density with a color gradient”_
|
|
3222
3234
|
_Example: “Create a relationship map between height and depth”_
|
|
3223
|
-
_Example: “Vary circle sizes according to population”_`,
|
|
3235
|
+
_Example: “Vary circle sizes according to population”_`, Ae = {
|
|
3224
3236
|
id: "layerStyling",
|
|
3225
3237
|
name: "Layer Styling Agent",
|
|
3226
|
-
description:
|
|
3227
|
-
createGraph:
|
|
3228
|
-
workspace:
|
|
3229
|
-
},
|
|
3238
|
+
description: es,
|
|
3239
|
+
createGraph: Xn,
|
|
3240
|
+
workspace: Xe
|
|
3241
|
+
}, et = g.Root({
|
|
3230
3242
|
// messages: comes from global chat history.
|
|
3231
3243
|
// It is safe to append new messages locally, but existing message objects
|
|
3232
3244
|
// must be treated as read-only and never mutated.
|
|
@@ -3239,51 +3251,51 @@ ${t}`;
|
|
|
3239
3251
|
// This avoids duplicate output when tool nodes and final LLM nodes
|
|
3240
3252
|
// emit the same text during a single agent turn.
|
|
3241
3253
|
outputMessage: g({
|
|
3242
|
-
reducer: (e = "",
|
|
3243
|
-
const
|
|
3244
|
-
if (!
|
|
3254
|
+
reducer: (e = "", t) => {
|
|
3255
|
+
const r = typeof t == "string" ? t.trim() : "";
|
|
3256
|
+
if (!r)
|
|
3245
3257
|
return e;
|
|
3246
3258
|
const a = e.trim();
|
|
3247
3259
|
if (!a)
|
|
3248
|
-
return
|
|
3249
|
-
if (a ===
|
|
3260
|
+
return r;
|
|
3261
|
+
if (a === r)
|
|
3250
3262
|
return e;
|
|
3251
3263
|
const o = a.split(`
|
|
3252
3264
|
|
|
3253
3265
|
`);
|
|
3254
|
-
return o[o.length - 1]?.trim() ===
|
|
3266
|
+
return o[o.length - 1]?.trim() === r ? e : `${e}
|
|
3255
3267
|
|
|
3256
|
-
${
|
|
3268
|
+
${r}`;
|
|
3257
3269
|
},
|
|
3258
3270
|
default: () => ""
|
|
3259
3271
|
})
|
|
3260
|
-
}),
|
|
3272
|
+
}), ts = (e) => {
|
|
3261
3273
|
if (!e || e.size === 0)
|
|
3262
3274
|
return "No layers available in this map.";
|
|
3263
|
-
const
|
|
3275
|
+
const t = Array.from(e.values()).map(({ layerItem: r, fieldRegistry: a }, o) => {
|
|
3264
3276
|
const n = Array.from(a.values()).map((l) => l.name).slice(0, 10).join(", "), i = a.size > 10 ? ` (and ${a.size - 10} more)` : "";
|
|
3265
|
-
return `${o + 1}. "${
|
|
3277
|
+
return `${o + 1}. "${r.title}". Description: ${r.description}
|
|
3266
3278
|
Fields: ${n}${i}`;
|
|
3267
3279
|
}).join(`
|
|
3268
3280
|
|
|
3269
3281
|
`);
|
|
3270
3282
|
return `This map contains ${e.size} layer(s):
|
|
3271
3283
|
|
|
3272
|
-
${
|
|
3273
|
-
},
|
|
3274
|
-
const
|
|
3275
|
-
return
|
|
3284
|
+
${t}`;
|
|
3285
|
+
}, rs = (e) => {
|
|
3286
|
+
const t = e?.list() ?? [];
|
|
3287
|
+
return t.length ? t.map((r) => `- ${r.agent.name}: ${r.agent.description}`).join(`
|
|
3276
3288
|
`) : "No agents currently available.";
|
|
3277
3289
|
};
|
|
3278
|
-
async function
|
|
3279
|
-
const
|
|
3280
|
-
layerSummary:
|
|
3281
|
-
agents:
|
|
3282
|
-
}, i = await
|
|
3283
|
-
promptText:
|
|
3290
|
+
async function as(e, t) {
|
|
3291
|
+
const r = await F("help_prompt"), a = S(t, "layersAndFieldsRegistry"), o = S(t, "agentRegistry"), n = {
|
|
3292
|
+
layerSummary: ts(a),
|
|
3293
|
+
agents: rs(o)
|
|
3294
|
+
}, i = await ie({
|
|
3295
|
+
promptText: r,
|
|
3284
3296
|
messages: x(e.messages),
|
|
3285
3297
|
inputVariables: n
|
|
3286
|
-
}), l = new
|
|
3298
|
+
}), l = new K(i), c = [...e.messages, l], d = `${e.outputMessage}
|
|
3287
3299
|
|
|
3288
3300
|
${i}`.trim();
|
|
3289
3301
|
return {
|
|
@@ -3292,7 +3304,7 @@ ${i}`.trim();
|
|
|
3292
3304
|
outputMessage: d
|
|
3293
3305
|
};
|
|
3294
3306
|
}
|
|
3295
|
-
const
|
|
3307
|
+
const os = (e, t) => D(["agentRegistry"], "Help Agent")(e, t), ns = () => new _(et).addNode("requireHelpServices", os).addNode("agent", as).addEdge(j, "requireHelpServices").addEdge("requireHelpServices", "agent").addEdge("agent", R), ss = String.raw`- **help** — Enables users to ask questions about the map, layers, fields, and it's capabilities.
|
|
3296
3308
|
|
|
3297
3309
|
_Example: “Tell me about this map”_
|
|
3298
3310
|
_Example: “List all layers in this map”_
|
|
@@ -3305,13 +3317,13 @@ const rs = (e, r) => D(["agentRegistry"], "Help Agent")(e, r), as = () => new _(
|
|
|
3305
3317
|
|
|
3306
3318
|
IF the user asks map related queries, but those that are not performed by any of the agents, call this agent so we can respond accordingly.
|
|
3307
3319
|
_Example: "Create a chart"_
|
|
3308
|
-
_Example: "Create a table"_`,
|
|
3320
|
+
_Example: "Create a table"_`, ki = {
|
|
3309
3321
|
id: "help",
|
|
3310
3322
|
name: "Help Agent",
|
|
3311
|
-
description:
|
|
3312
|
-
createGraph:
|
|
3313
|
-
workspace:
|
|
3314
|
-
},
|
|
3323
|
+
description: ss,
|
|
3324
|
+
createGraph: ns,
|
|
3325
|
+
workspace: et
|
|
3326
|
+
}, tt = g.Root({
|
|
3315
3327
|
// messages: comes from global chat history.
|
|
3316
3328
|
// It is safe to append new messages locally, but existing message objects
|
|
3317
3329
|
// must be treated as read-only and never mutated.
|
|
@@ -3324,54 +3336,54 @@ const rs = (e, r) => D(["agentRegistry"], "Help Agent")(e, r), as = () => new _(
|
|
|
3324
3336
|
// This avoids duplicate output when tool nodes and final LLM nodes
|
|
3325
3337
|
// emit the same text during a single agent turn.
|
|
3326
3338
|
outputMessage: g({
|
|
3327
|
-
reducer: (e = "",
|
|
3328
|
-
const
|
|
3329
|
-
if (!
|
|
3339
|
+
reducer: (e = "", t) => {
|
|
3340
|
+
const r = typeof t == "string" ? t.trim() : "";
|
|
3341
|
+
if (!r)
|
|
3330
3342
|
return e;
|
|
3331
3343
|
const a = e.trim();
|
|
3332
3344
|
if (!a)
|
|
3333
|
-
return
|
|
3334
|
-
if (a ===
|
|
3345
|
+
return r;
|
|
3346
|
+
if (a === r)
|
|
3335
3347
|
return e;
|
|
3336
3348
|
const o = a.split(`
|
|
3337
3349
|
|
|
3338
3350
|
`);
|
|
3339
|
-
return o[o.length - 1]?.trim() ===
|
|
3351
|
+
return o[o.length - 1]?.trim() === r ? e : `${e}
|
|
3340
3352
|
|
|
3341
|
-
${
|
|
3353
|
+
${r}`;
|
|
3342
3354
|
},
|
|
3343
3355
|
default: () => ""
|
|
3344
3356
|
}),
|
|
3345
3357
|
intent: g({
|
|
3346
|
-
reducer: (e,
|
|
3358
|
+
reducer: (e, t) => t
|
|
3347
3359
|
})
|
|
3348
|
-
}),
|
|
3360
|
+
}), J = {
|
|
3349
3361
|
conversationId: ""
|
|
3350
|
-
},
|
|
3351
|
-
function
|
|
3352
|
-
const
|
|
3353
|
-
if (!
|
|
3362
|
+
}, is = ["linkChartView"], ls = ["knowledgeGraph"];
|
|
3363
|
+
function oe(e) {
|
|
3364
|
+
const r = e?.configurable?.context;
|
|
3365
|
+
if (!r || typeof r != "object")
|
|
3354
3366
|
throw new Error("ArcgisKnowledgeAgent context missing");
|
|
3355
|
-
const a =
|
|
3367
|
+
const a = is.filter((o) => !(o in r));
|
|
3356
3368
|
if (a.length)
|
|
3357
3369
|
throw new Error(`Link Chart context missing: ${a.join(", ")}`);
|
|
3358
|
-
return
|
|
3370
|
+
return r;
|
|
3359
3371
|
}
|
|
3360
|
-
function
|
|
3361
|
-
const
|
|
3362
|
-
if (!
|
|
3372
|
+
function we(e) {
|
|
3373
|
+
const r = e?.configurable?.context;
|
|
3374
|
+
if (!r || typeof r != "object")
|
|
3363
3375
|
throw new Error("ArcgisKnowledgeAgent context missing");
|
|
3364
|
-
const a =
|
|
3376
|
+
const a = ls.filter((o) => !(o in r));
|
|
3365
3377
|
if (a.length)
|
|
3366
3378
|
throw new Error(`Knowledge Graph context missing: ${a.join(", ")}`);
|
|
3367
|
-
return
|
|
3379
|
+
return r;
|
|
3368
3380
|
}
|
|
3369
|
-
class
|
|
3370
|
-
constructor(
|
|
3371
|
-
this.dataModel =
|
|
3381
|
+
class cs {
|
|
3382
|
+
constructor(t) {
|
|
3383
|
+
this.dataModel = t, this.kind = "GraphQueryGenerationRequest", this.explainQuery = !0, this.schemaInformation = be.fromDataModel(t);
|
|
3372
3384
|
}
|
|
3373
3385
|
}
|
|
3374
|
-
class
|
|
3386
|
+
class be {
|
|
3375
3387
|
constructor() {
|
|
3376
3388
|
this.schemaType = "ArcgisGraphSchema", this.entityTypes = [], this.relationshipTypes = [], this.identifierInfo = {
|
|
3377
3389
|
mappingInfo: {
|
|
@@ -3380,62 +3392,62 @@ class we {
|
|
|
3380
3392
|
}
|
|
3381
3393
|
};
|
|
3382
3394
|
}
|
|
3383
|
-
static fromDataModel(
|
|
3384
|
-
const
|
|
3385
|
-
for (const a of
|
|
3386
|
-
|
|
3387
|
-
for (const a of
|
|
3388
|
-
|
|
3389
|
-
return
|
|
3395
|
+
static fromDataModel(t) {
|
|
3396
|
+
const r = new be();
|
|
3397
|
+
for (const a of t.entityTypes)
|
|
3398
|
+
r.entityTypes.push(B.fromEntityType(a));
|
|
3399
|
+
for (const a of t.relationshipTypes)
|
|
3400
|
+
r.relationshipTypes.push(ds.fromRelationshipType(a));
|
|
3401
|
+
return r.identifierInfo = {
|
|
3390
3402
|
mappingInfo: {
|
|
3391
|
-
identifierMapsTo:
|
|
3392
|
-
|
|
3403
|
+
identifierMapsTo: us(
|
|
3404
|
+
t.identifierInfo.identifierMappingInfo.identifierInfoType
|
|
3393
3405
|
),
|
|
3394
|
-
identifierPropertyName:
|
|
3406
|
+
identifierPropertyName: t.identifierInfo.identifierMappingInfo.uniformPropertyIdentifier.identifierPropertyName
|
|
3395
3407
|
}
|
|
3396
|
-
},
|
|
3408
|
+
}, r.spatialReference = JSON.parse(JSON.stringify(t.spatialReference)), r;
|
|
3397
3409
|
}
|
|
3398
3410
|
}
|
|
3399
|
-
class
|
|
3411
|
+
class B {
|
|
3400
3412
|
constructor() {
|
|
3401
3413
|
this.name = "", this.properties = [];
|
|
3402
3414
|
}
|
|
3403
|
-
static fromEntityType(
|
|
3404
|
-
const
|
|
3405
|
-
|
|
3406
|
-
for (const a of
|
|
3415
|
+
static fromEntityType(t) {
|
|
3416
|
+
const r = new B();
|
|
3417
|
+
r.name = t.name, r.alias = t.alias ? t.alias : void 0, r.role = hs(t.role);
|
|
3418
|
+
for (const a of t.properties) {
|
|
3407
3419
|
const o = {
|
|
3408
3420
|
name: a.name,
|
|
3409
3421
|
alias: a.alias ? a.alias : void 0,
|
|
3410
3422
|
fieldType: a.fieldType,
|
|
3411
|
-
role:
|
|
3423
|
+
role: ms(a.role),
|
|
3412
3424
|
geometryDef: a.fieldType === "esriFieldTypeGeometry" ? {
|
|
3413
3425
|
geometryType: a.geometryType ?? "esriGeometryAny",
|
|
3414
3426
|
hasM: a.hasM ? a.hasM : void 0,
|
|
3415
3427
|
hasZ: a.hasZ ? a.hasZ : void 0
|
|
3416
3428
|
} : void 0
|
|
3417
3429
|
};
|
|
3418
|
-
|
|
3430
|
+
r.properties.push(o);
|
|
3419
3431
|
}
|
|
3420
|
-
return
|
|
3432
|
+
return r;
|
|
3421
3433
|
}
|
|
3422
3434
|
}
|
|
3423
|
-
class
|
|
3435
|
+
class ds extends B {
|
|
3424
3436
|
constructor() {
|
|
3425
3437
|
super(...arguments), this.observedEndPoints = [];
|
|
3426
3438
|
}
|
|
3427
|
-
static fromRelationshipType(
|
|
3428
|
-
const
|
|
3429
|
-
|
|
3430
|
-
for (const a of
|
|
3431
|
-
|
|
3439
|
+
static fromRelationshipType(t) {
|
|
3440
|
+
const r = B.fromEntityType(t);
|
|
3441
|
+
r.observedEndPoints = [];
|
|
3442
|
+
for (const a of t.endPoints)
|
|
3443
|
+
r.observedEndPoints.push({
|
|
3432
3444
|
originEntityType: a.originEntityType,
|
|
3433
3445
|
destinationEntityType: a.destinationEntityType
|
|
3434
3446
|
});
|
|
3435
|
-
return
|
|
3447
|
+
return r;
|
|
3436
3448
|
}
|
|
3437
3449
|
}
|
|
3438
|
-
const
|
|
3450
|
+
const us = (e) => {
|
|
3439
3451
|
switch (e) {
|
|
3440
3452
|
case "esriIdentifierInfoTypeUNSPECIFIED":
|
|
3441
3453
|
return "UNSPECIFIED";
|
|
@@ -3446,7 +3458,7 @@ const cs = (e) => {
|
|
|
3446
3458
|
default:
|
|
3447
3459
|
return e;
|
|
3448
3460
|
}
|
|
3449
|
-
},
|
|
3461
|
+
}, hs = (e) => {
|
|
3450
3462
|
switch (e) {
|
|
3451
3463
|
case "Regular":
|
|
3452
3464
|
return "esriGraphNamedObjectRegular";
|
|
@@ -3458,7 +3470,7 @@ const cs = (e) => {
|
|
|
3458
3470
|
return e;
|
|
3459
3471
|
}
|
|
3460
3472
|
};
|
|
3461
|
-
function
|
|
3473
|
+
function ms(e) {
|
|
3462
3474
|
switch (e) {
|
|
3463
3475
|
case "esriGraphPropertyRegular":
|
|
3464
3476
|
return "Regular";
|
|
@@ -3496,41 +3508,41 @@ function us(e) {
|
|
|
3496
3508
|
return "Regular";
|
|
3497
3509
|
}
|
|
3498
3510
|
}
|
|
3499
|
-
async function
|
|
3500
|
-
const { graphQuery: o, explanation: n } = await
|
|
3511
|
+
async function ps(e, t, r, a) {
|
|
3512
|
+
const { graphQuery: o, explanation: n } = await Se(e, t, r, a);
|
|
3501
3513
|
return `Generated Graph Query:
|
|
3502
3514
|
${o}
|
|
3503
3515
|
|
|
3504
3516
|
Explanation: ${n}`;
|
|
3505
3517
|
}
|
|
3506
|
-
async function
|
|
3518
|
+
async function Se(e, t, r, a) {
|
|
3507
3519
|
const o = {
|
|
3508
3520
|
message: e,
|
|
3509
|
-
context: new
|
|
3521
|
+
context: new cs(t)
|
|
3510
3522
|
};
|
|
3511
|
-
|
|
3512
|
-
const n = await
|
|
3523
|
+
J.conversationId && (o.conversationId = J.conversationId), await m({ text: "Attempting to generate a cypher query from your prompt..." }, a);
|
|
3524
|
+
const n = await Ee(`${r}/chat`, {
|
|
3513
3525
|
method: "post",
|
|
3514
3526
|
body: JSON.stringify(o),
|
|
3515
3527
|
headers: {
|
|
3516
3528
|
"Content-Type": "application/json",
|
|
3517
|
-
token:
|
|
3529
|
+
token: $e.findCredential(O.getDefault().url)?.token ?? ""
|
|
3518
3530
|
}
|
|
3519
3531
|
});
|
|
3520
3532
|
if (n.httpStatus !== 200)
|
|
3521
3533
|
throw new Error(`Graph query service returned an error: ${n.httpStatus}`, {
|
|
3522
3534
|
cause: n.data
|
|
3523
3535
|
});
|
|
3524
|
-
|
|
3536
|
+
J.conversationId || (J.conversationId = n.data.conversationId);
|
|
3525
3537
|
let i = !1;
|
|
3526
3538
|
const l = Date.now();
|
|
3527
3539
|
let c = n.data.sequenceNumber, d = "", u = "", h = 1;
|
|
3528
3540
|
for (; !i; ) {
|
|
3529
|
-
await new Promise((f) => setTimeout(f, 1e3)), await
|
|
3541
|
+
await new Promise((f) => setTimeout(f, 1e3)), await m(
|
|
3530
3542
|
{ text: `Periodically requesting status of job from ArcGIS AI Services${"...".substring(0, h)}` },
|
|
3531
3543
|
a
|
|
3532
3544
|
), h = h % 3 + 1;
|
|
3533
|
-
const
|
|
3545
|
+
const p = await Ee(`${r}/chat`, {
|
|
3534
3546
|
method: "post",
|
|
3535
3547
|
body: JSON.stringify({
|
|
3536
3548
|
conversationId: n.data.conversationId,
|
|
@@ -3539,90 +3551,90 @@ async function be(e, r, t, a) {
|
|
|
3539
3551
|
}),
|
|
3540
3552
|
headers: {
|
|
3541
3553
|
"Content-Type": "application/json",
|
|
3542
|
-
token:
|
|
3554
|
+
token: $e.findCredential(O.getDefault().url)?.token ?? ""
|
|
3543
3555
|
}
|
|
3544
3556
|
});
|
|
3545
|
-
if (
|
|
3546
|
-
throw new Error(`Graph query service polling returned an error: ${
|
|
3547
|
-
cause:
|
|
3557
|
+
if (p.httpStatus !== 200)
|
|
3558
|
+
throw new Error(`Graph query service polling returned an error: ${p.httpStatus}`, {
|
|
3559
|
+
cause: p.data
|
|
3548
3560
|
});
|
|
3549
|
-
if (
|
|
3550
|
-
d =
|
|
3551
|
-
else if (!
|
|
3561
|
+
if (p.data.context)
|
|
3562
|
+
d = p.data.context.graphQuery, u = p.data.message || "";
|
|
3563
|
+
else if (!p.data.hasMore)
|
|
3552
3564
|
i = !0;
|
|
3553
3565
|
else if (Date.now() - l > 6e4)
|
|
3554
3566
|
throw new Error("Graph query service polling timed out after 1 minute.");
|
|
3555
|
-
c =
|
|
3567
|
+
c = p.data.sequenceNumber;
|
|
3556
3568
|
}
|
|
3557
3569
|
return { graphQuery: d, explanation: u };
|
|
3558
3570
|
}
|
|
3559
|
-
function
|
|
3571
|
+
function Y(e, t) {
|
|
3560
3572
|
if (!(!e || typeof e != "object")) {
|
|
3561
|
-
if (
|
|
3562
|
-
for (const
|
|
3563
|
-
|
|
3564
|
-
else if (ps(e))
|
|
3565
|
-
r.set(`${e.typeName}__${e.id}`, { id: e.id, typeName: e.typeName });
|
|
3566
|
-
else if (Array.isArray(e))
|
|
3567
|
-
for (const t of e)
|
|
3568
|
-
Z(t, r);
|
|
3573
|
+
if (fs(e))
|
|
3574
|
+
for (const r of e.path)
|
|
3575
|
+
Y(r, t);
|
|
3569
3576
|
else if (ys(e))
|
|
3570
|
-
|
|
3571
|
-
|
|
3577
|
+
t.set(`${e.typeName}__${e.id}`, { id: e.id, typeName: e.typeName });
|
|
3578
|
+
else if (Array.isArray(e))
|
|
3579
|
+
for (const r of e)
|
|
3580
|
+
Y(r, t);
|
|
3581
|
+
else if (gs(e))
|
|
3582
|
+
for (const r of Object.values(e.properties ?? {}))
|
|
3583
|
+
Y(r, t);
|
|
3572
3584
|
}
|
|
3573
3585
|
}
|
|
3574
|
-
function
|
|
3586
|
+
function ys(e) {
|
|
3575
3587
|
return !e || typeof e != "object" || Array.isArray(e) ? !1 : "id" in e && "typeName" in e;
|
|
3576
3588
|
}
|
|
3577
|
-
function
|
|
3589
|
+
function fs(e) {
|
|
3578
3590
|
return !e || typeof e != "object" || Array.isArray(e) ? !1 : e && "path" in e && Array.isArray(e.path);
|
|
3579
3591
|
}
|
|
3580
|
-
function
|
|
3592
|
+
function gs(e) {
|
|
3581
3593
|
return !e || typeof e != "object" || Array.isArray(e) || "id" in e ? !1 : "properties" in e && typeof e.properties == "object";
|
|
3582
3594
|
}
|
|
3583
|
-
function
|
|
3584
|
-
const
|
|
3585
|
-
for (const a of [...
|
|
3595
|
+
function ws(e, t) {
|
|
3596
|
+
const r = [];
|
|
3597
|
+
for (const a of [...t.dataModel.entityTypes, ...t.dataModel.relationshipTypes]) {
|
|
3586
3598
|
const o = e.getMemberIdsByType(a.name);
|
|
3587
3599
|
for (const n of o)
|
|
3588
|
-
|
|
3600
|
+
r.push({ id: n, typeName: a.name });
|
|
3589
3601
|
}
|
|
3590
|
-
return
|
|
3602
|
+
return r;
|
|
3591
3603
|
}
|
|
3592
|
-
const
|
|
3593
|
-
const
|
|
3604
|
+
const bs = async (e) => {
|
|
3605
|
+
const t = /* @__PURE__ */ new Map(), r = e.resultRowsStream.getReader();
|
|
3594
3606
|
for (; ; ) {
|
|
3595
|
-
const { done: a, value: o } = await
|
|
3607
|
+
const { done: a, value: o } = await r.read();
|
|
3596
3608
|
if (a)
|
|
3597
3609
|
break;
|
|
3598
3610
|
for (const n of o)
|
|
3599
3611
|
for (const i of n)
|
|
3600
|
-
|
|
3612
|
+
Y(i, t);
|
|
3601
3613
|
}
|
|
3602
|
-
return Array.from(
|
|
3614
|
+
return Array.from(t.values());
|
|
3603
3615
|
};
|
|
3604
|
-
async function
|
|
3605
|
-
const { graphQuery: n, explanation: i } = await
|
|
3616
|
+
async function Ss(e, t, r, a, o) {
|
|
3617
|
+
const { graphQuery: n, explanation: i } = await Se(
|
|
3606
3618
|
e,
|
|
3607
|
-
|
|
3608
|
-
|
|
3619
|
+
t.dataModel,
|
|
3620
|
+
r,
|
|
3609
3621
|
o
|
|
3610
3622
|
);
|
|
3611
|
-
await
|
|
3623
|
+
await m(
|
|
3612
3624
|
{ text: `Attempting to execute query: ${n.substring(0, 500)}${n.length > 500 ? "..." : ""}` },
|
|
3613
3625
|
o
|
|
3614
3626
|
);
|
|
3615
|
-
const l = await
|
|
3616
|
-
|
|
3617
|
-
new
|
|
3627
|
+
const l = await At(
|
|
3628
|
+
t,
|
|
3629
|
+
new Pe({
|
|
3618
3630
|
openCypherQuery: n
|
|
3619
3631
|
}),
|
|
3620
3632
|
{
|
|
3621
3633
|
signal: o?.signal,
|
|
3622
3634
|
timeout: o?.timeout
|
|
3623
3635
|
}
|
|
3624
|
-
), c = await
|
|
3625
|
-
return await
|
|
3636
|
+
), c = await bs(l);
|
|
3637
|
+
return await m(
|
|
3626
3638
|
{
|
|
3627
3639
|
text: `Query Results parsed into ${c.length} unique relationships and entities. Atempting to add to link chart...`
|
|
3628
3640
|
},
|
|
@@ -3632,33 +3644,33 @@ ${n}
|
|
|
3632
3644
|
|
|
3633
3645
|
Explanation: ${i}`;
|
|
3634
3646
|
}
|
|
3635
|
-
async function
|
|
3636
|
-
const { knowledgeGraph:
|
|
3647
|
+
async function rt({ prompt: e }, t) {
|
|
3648
|
+
const { knowledgeGraph: r } = we(t), { linkChartView: a } = oe(t), n = O.getDefault().helperServices, i = await F("arcgis_knowledge_current_lc_context"), l = ws(a.map, r), c = `${e}
|
|
3637
3649
|
|
|
3638
3650
|
${i}${JSON.stringify(l)}`;
|
|
3639
|
-
return await
|
|
3651
|
+
return await Ss(
|
|
3640
3652
|
c,
|
|
3641
|
-
|
|
3653
|
+
r,
|
|
3642
3654
|
`${n.aiAssistantServices.url}${n.aiAssistantServices.graphQueryAssistant}`,
|
|
3643
3655
|
a,
|
|
3644
|
-
|
|
3656
|
+
t
|
|
3645
3657
|
);
|
|
3646
3658
|
}
|
|
3647
|
-
const
|
|
3659
|
+
const vs = s.object({
|
|
3648
3660
|
prompt: s.string().describe("The user's inquiry into the knowledge graph that needs to be run.")
|
|
3649
|
-
}),
|
|
3661
|
+
}), at = b(rt, {
|
|
3650
3662
|
name: "addRecords",
|
|
3651
3663
|
description: "Adds records (entities or relationships) to the current link chart visualization from an inquiry into the knowledge graph data. The inquiry will retrieve data from the graph database that will serve as the basis for the records to be added to the link chart. The user should have explicitly requested to add records to the current link chart from their prompt.",
|
|
3652
|
-
schema:
|
|
3664
|
+
schema: vs
|
|
3653
3665
|
});
|
|
3654
|
-
async function
|
|
3655
|
-
return await
|
|
3666
|
+
async function Ts(e, t) {
|
|
3667
|
+
return await t.map.applyLayout(e), `Successfully applied layout: ${e}.`;
|
|
3656
3668
|
}
|
|
3657
|
-
async function
|
|
3658
|
-
const { linkChartView:
|
|
3659
|
-
return await
|
|
3669
|
+
async function xs({ layout: e }, t) {
|
|
3670
|
+
const { linkChartView: r } = oe(t);
|
|
3671
|
+
return await Ts(e, r);
|
|
3660
3672
|
}
|
|
3661
|
-
const
|
|
3673
|
+
const Es = s.object({
|
|
3662
3674
|
layout: s.enum([
|
|
3663
3675
|
"organic-standard",
|
|
3664
3676
|
"organic-community",
|
|
@@ -3672,112 +3684,112 @@ const Ts = s.object({
|
|
|
3672
3684
|
]).describe(
|
|
3673
3685
|
"The layout mode to apply to the link chart. The value must be one of the following: organic-standard, organic-community, basic-grid, hierarchical-bottom-to-top, radial-root-centric, tree-left-to-right, geographic-organic-standard, chronological-mono-timeline, chronological-multi-timeline"
|
|
3674
3686
|
)
|
|
3675
|
-
}),
|
|
3687
|
+
}), $s = b(xs, {
|
|
3676
3688
|
name: "applyLayout",
|
|
3677
3689
|
description: "Apply a diagram layout to the link chart",
|
|
3678
|
-
schema:
|
|
3690
|
+
schema: Es
|
|
3679
3691
|
});
|
|
3680
|
-
function
|
|
3681
|
-
return
|
|
3692
|
+
function Fs(e, t) {
|
|
3693
|
+
return t.map.changeNonspatialDataDisplay(e), `Successfully applied nonspatial visibility setting: ${e}.`;
|
|
3682
3694
|
}
|
|
3683
|
-
function
|
|
3684
|
-
const { linkChartView:
|
|
3685
|
-
return
|
|
3695
|
+
function Rs({ setting: e }, t) {
|
|
3696
|
+
const { linkChartView: r } = oe(t);
|
|
3697
|
+
return Fs(e, r);
|
|
3686
3698
|
}
|
|
3687
|
-
const
|
|
3699
|
+
const Ls = s.object({
|
|
3688
3700
|
setting: s.enum(["hidden", "visible"]).describe("The setting of nonspatial visibility")
|
|
3689
|
-
}),
|
|
3701
|
+
}), Is = b(Rs, {
|
|
3690
3702
|
name: "changeNonspatialVisibility",
|
|
3691
3703
|
description: "Change whether or not nonspatial data is visible in the link chart. The value must be either 'hidden' or 'visible'.",
|
|
3692
|
-
schema:
|
|
3704
|
+
schema: Ls
|
|
3693
3705
|
});
|
|
3694
|
-
async function
|
|
3695
|
-
const { graphQuery: n, explanation: i } = await
|
|
3706
|
+
async function qs(e, t, r, a, o) {
|
|
3707
|
+
const { graphQuery: n, explanation: i } = await Se(
|
|
3696
3708
|
e,
|
|
3697
|
-
|
|
3698
|
-
|
|
3709
|
+
t.dataModel,
|
|
3710
|
+
r,
|
|
3699
3711
|
o
|
|
3700
3712
|
);
|
|
3701
|
-
await
|
|
3702
|
-
const l = await
|
|
3703
|
-
|
|
3704
|
-
new
|
|
3713
|
+
await m({ text: `Attempting to create link chart from derived query: ${n}` }, o);
|
|
3714
|
+
const l = await kt.fromCypherQuery(
|
|
3715
|
+
t,
|
|
3716
|
+
new Pe({
|
|
3705
3717
|
openCypherQuery: n
|
|
3706
3718
|
})
|
|
3707
3719
|
);
|
|
3708
|
-
return await
|
|
3720
|
+
return await m({ text: "Link chart created successfully, loading..." }, o), a.map = l, await l.load(), await a.when(), `Link chart created successfully. Cypher Query used to create the link chart:
|
|
3709
3721
|
${n}
|
|
3710
3722
|
|
|
3711
3723
|
Explanation: ${i}`;
|
|
3712
3724
|
}
|
|
3713
|
-
async function
|
|
3714
|
-
const { knowledgeGraph:
|
|
3715
|
-
return await
|
|
3725
|
+
async function ot({ prompt: e }, t) {
|
|
3726
|
+
const { knowledgeGraph: r } = we(t), { linkChartView: a } = oe(t), n = O.getDefault().helperServices;
|
|
3727
|
+
return await qs(
|
|
3716
3728
|
e,
|
|
3717
|
-
|
|
3729
|
+
r,
|
|
3718
3730
|
`${n.aiAssistantServices.url}${n.aiAssistantServices.graphQueryAssistant}`,
|
|
3719
3731
|
a,
|
|
3720
|
-
|
|
3732
|
+
t
|
|
3721
3733
|
);
|
|
3722
3734
|
}
|
|
3723
|
-
const
|
|
3735
|
+
const Cs = s.object({
|
|
3724
3736
|
prompt: s.string().describe(
|
|
3725
3737
|
"The user's inquiry into the knowledge graph that needs to be transformed into a link chart visualization."
|
|
3726
3738
|
)
|
|
3727
|
-
}),
|
|
3739
|
+
}), nt = b(ot, {
|
|
3728
3740
|
name: "createLinkChart",
|
|
3729
3741
|
description: "Creates a new link chart visualization from an inquiry into the knowledge graph data. The inquiry will retrieve data from the graph database that will serve as the basis for the new link chart. The user should have explicitly requested the creation of a new link chart from their prompt.",
|
|
3730
|
-
schema:
|
|
3742
|
+
schema: Cs
|
|
3731
3743
|
});
|
|
3732
|
-
async function
|
|
3733
|
-
const { knowledgeGraph:
|
|
3734
|
-
return await
|
|
3744
|
+
async function st({ prompt: e }, t) {
|
|
3745
|
+
const { knowledgeGraph: r } = we(t), o = O.getDefault().helperServices;
|
|
3746
|
+
return await ps(
|
|
3735
3747
|
e,
|
|
3736
|
-
|
|
3748
|
+
r.dataModel,
|
|
3737
3749
|
`${o.aiAssistantServices.url}${o.aiAssistantServices.graphQueryAssistant}`,
|
|
3738
|
-
|
|
3750
|
+
t
|
|
3739
3751
|
);
|
|
3740
3752
|
}
|
|
3741
|
-
const
|
|
3753
|
+
const As = s.object({
|
|
3742
3754
|
prompt: s.string().describe("The user's inquiry into the knowledge graph that needs to be translated into a cypher query.")
|
|
3743
|
-
}),
|
|
3755
|
+
}), ve = b(st, {
|
|
3744
3756
|
name: "generateCypher",
|
|
3745
3757
|
description: "Generates an Open Cypher query based on the user's prompt which represents an inquiry into the data of the knowledge service and its graph database, attempting to filter based on certain conditions and traverse specified relationships. The generated query should be syntactically correct and optimized for performance.",
|
|
3746
|
-
schema:
|
|
3747
|
-
}),
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
],
|
|
3754
|
-
async function
|
|
3755
|
-
const
|
|
3758
|
+
schema: As
|
|
3759
|
+
}), Te = [
|
|
3760
|
+
$s,
|
|
3761
|
+
Is,
|
|
3762
|
+
ve,
|
|
3763
|
+
nt,
|
|
3764
|
+
at
|
|
3765
|
+
], ks = [ve, nt, at];
|
|
3766
|
+
async function Ns(e, t) {
|
|
3767
|
+
const r = await F("arcgis_knowledge_tool_prompt"), a = {
|
|
3756
3768
|
intent: e.intent
|
|
3757
3769
|
}, o = await M({
|
|
3758
|
-
promptText:
|
|
3770
|
+
promptText: r,
|
|
3759
3771
|
messages: x(e.messages),
|
|
3760
3772
|
inputVariables: a,
|
|
3761
|
-
tools:
|
|
3773
|
+
tools: Te
|
|
3762
3774
|
}), n = [...e.messages, o], l = (o.tool_calls?.length ?? 0) > 0 ? [...n] : [...n, o];
|
|
3763
3775
|
return { ...e, messages: l };
|
|
3764
3776
|
}
|
|
3765
|
-
async function
|
|
3766
|
-
const a = await new P(
|
|
3777
|
+
async function zs(e, t) {
|
|
3778
|
+
const a = await new P(Te).invoke(
|
|
3767
3779
|
{
|
|
3768
3780
|
messages: x(e.messages)
|
|
3769
3781
|
},
|
|
3770
|
-
|
|
3782
|
+
t
|
|
3771
3783
|
), o = a.messages.map((l) => l.text).join(`
|
|
3772
3784
|
`);
|
|
3773
|
-
await
|
|
3785
|
+
await m({ text: `Finished executing arcgisKnowledge tool: ${o}` }, t);
|
|
3774
3786
|
const n = [...e.messages, ...a.messages], i = a.messages.map((l) => l.text).join(`
|
|
3775
3787
|
`);
|
|
3776
3788
|
return { ...e, messages: n, outputMessage: i };
|
|
3777
3789
|
}
|
|
3778
|
-
async function
|
|
3779
|
-
const
|
|
3780
|
-
tools:
|
|
3790
|
+
async function _s(e) {
|
|
3791
|
+
const t = await F("arcgis_knowledge_intent_prompt"), a = {
|
|
3792
|
+
tools: Te.map((l) => ({
|
|
3781
3793
|
name: l.name,
|
|
3782
3794
|
description: l.description,
|
|
3783
3795
|
schema: l.schema
|
|
@@ -3785,43 +3797,43 @@ async function Ns(e) {
|
|
|
3785
3797
|
`)
|
|
3786
3798
|
}, o = s.object({
|
|
3787
3799
|
intent: s.string()
|
|
3788
|
-
}), n = await
|
|
3789
|
-
promptText:
|
|
3800
|
+
}), n = await ke({
|
|
3801
|
+
promptText: t,
|
|
3790
3802
|
messages: x(e.messages),
|
|
3791
3803
|
inputVariables: a,
|
|
3792
3804
|
schema: o
|
|
3793
3805
|
}), i = typeof n.intent == "string" ? n.intent.trim().replace(/^"|"$/gu, "") : "";
|
|
3794
3806
|
return { ...e, intent: i || "" };
|
|
3795
3807
|
}
|
|
3796
|
-
const
|
|
3808
|
+
const js = (e, t) => (
|
|
3797
3809
|
//agent services (ex: embeddingsWorker) would go in the array below, if required.
|
|
3798
|
-
D([], "ArcgisKnowledge Agent")(e,
|
|
3810
|
+
D([], "ArcgisKnowledge Agent")(e, t)
|
|
3799
3811
|
);
|
|
3800
|
-
async function
|
|
3801
|
-
const
|
|
3812
|
+
async function Ms(e, t) {
|
|
3813
|
+
const r = e.messages[e.messages.length - 1].content;
|
|
3802
3814
|
let a;
|
|
3803
|
-
if (typeof
|
|
3815
|
+
if (typeof r != "string")
|
|
3804
3816
|
throw new Error("The original message content must be a string to process server skills.");
|
|
3805
|
-
if (e.intent ===
|
|
3806
|
-
a = await
|
|
3817
|
+
if (e.intent === ve.name)
|
|
3818
|
+
a = await st({ prompt: r }, t);
|
|
3807
3819
|
else if (e.intent === "createLinkChart")
|
|
3808
|
-
a = await
|
|
3820
|
+
a = await ot({ prompt: r }, t);
|
|
3809
3821
|
else if (e.intent === "addRecords")
|
|
3810
|
-
a = await
|
|
3822
|
+
a = await rt({ prompt: r }, t);
|
|
3811
3823
|
else
|
|
3812
3824
|
throw new Error(`No server skills were successfully invoked matching the name: ${e.intent}`);
|
|
3813
3825
|
return { ...e, messages: [...e.messages], outputMessage: a };
|
|
3814
3826
|
}
|
|
3815
|
-
const
|
|
3827
|
+
const Ps = () => new _(tt).addNode("requireArcgisKnowledgeServices", js).addNode("intentLLM", _s).addNode("agent", Ns).addNode("serverSkill", Ms).addNode("tools", zs).addEdge(j, "requireArcgisKnowledgeServices").addEdge("requireArcgisKnowledgeServices", "intentLLM").addConditionalEdges(
|
|
3816
3828
|
"intentLLM",
|
|
3817
|
-
(
|
|
3829
|
+
(t) => (
|
|
3818
3830
|
// ts/lint are getting confused here about the type, and the cast resolves it. Without it, there is a ts error
|
|
3819
|
-
|
|
3831
|
+
ks.map((r) => r.name).includes(t.intent) ? "serverSkill" : "agent"
|
|
3820
3832
|
)
|
|
3821
|
-
).addConditionalEdges("agent", (
|
|
3822
|
-
const
|
|
3823
|
-
return
|
|
3824
|
-
}).addEdge("tools", R),
|
|
3833
|
+
).addConditionalEdges("agent", (t) => {
|
|
3834
|
+
const r = t.messages[t.messages.length - 1];
|
|
3835
|
+
return r?.getType() === "ai" && "tool_calls" in r && Array.isArray(r.tool_calls) && r.tool_calls.length > 0 ? "tools" : R;
|
|
3836
|
+
}).addEdge("tools", R), Ds = String.raw`The purpose of this agent is to work with Knowledge Graph data, a graph database technology that represents and stores data as interconnected entities (nodes) and relationships (edges).
|
|
3825
3837
|
This agent has two categories of skills: those that work with an active link chart visualization of a subset of the data in the knowledge graph, and those that work with the knowledge graph data more generally against the entire dataset in the service and database.
|
|
3826
3838
|
For link charts, the agent enables users to interact with a link chart by adding new entities (also called nodes) or relationships (also called edges), removing existing entities or relationships,
|
|
3827
3839
|
expanding the graph from particular entities, finding relationships between specified entities on the link chart and adding them to the link chart, finding all relationships
|
|
@@ -3853,19 +3865,19 @@ _example: "Find all the products supplied by Supplier X and add them to my visua
|
|
|
3853
3865
|
_example: "Expand the link chart from 'Entity D' to show its direct connections"_
|
|
3854
3866
|
_example: "Find all the cars and then add everything up to two hops away from them on the link chart"_
|
|
3855
3867
|
_example: "Connect Emma and Rob on the link chart if there is a relationship between them"
|
|
3856
|
-
_example: "Discover and add all the relationships originating at 'Entity E' to the link chart"_`,
|
|
3868
|
+
_example: "Discover and add all the relationships originating at 'Entity E' to the link chart"_`, Ni = {
|
|
3857
3869
|
id: "arcgisKnowledge",
|
|
3858
3870
|
name: "ArcgisKnowledge Agent",
|
|
3859
|
-
description:
|
|
3860
|
-
createGraph:
|
|
3861
|
-
workspace:
|
|
3871
|
+
description: Ds,
|
|
3872
|
+
createGraph: Ps,
|
|
3873
|
+
workspace: tt
|
|
3862
3874
|
};
|
|
3863
3875
|
export {
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3876
|
+
Ni as ArcgisKnowledgeAgent,
|
|
3877
|
+
qi as DataExplorationAgent,
|
|
3878
|
+
ki as HelpAgent,
|
|
3879
|
+
Ci as LayerFilterAgent,
|
|
3880
|
+
Ai as LayerQueryAgent,
|
|
3881
|
+
Ae as LayerStylingAgent,
|
|
3882
|
+
Ii as NavigationAgent
|
|
3871
3883
|
};
|