@arcgis/ai-components 5.2.0-next.78 → 5.2.0-next.79
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/agentic-workflow/jsonTypes.d.ts +2 -12
- package/dist/agentic-workflow/nodes/AgentNode.d.ts +2 -3
- package/dist/agents/tools/search/findRelevantFields/adapter.d.ts +8 -0
- package/dist/agents/tools/search/findRelevantFields/adapter.js +57 -0
- package/dist/agents/tools/search/findRelevantLayers/adapter.d.ts +8 -0
- package/dist/agents/tools/search/findRelevantLayers/adapter.js +38 -0
- package/dist/cdn/{ERNYKCUJ.js → 4AGGYAWS.js} +1 -1
- package/dist/cdn/{YWULKUQV.js → 6ADMWEVE.js} +1 -1
- package/dist/cdn/7BCQMK6D.js +2 -0
- package/dist/cdn/7QOC7FQE.js +2 -0
- package/dist/cdn/{IIIUSDQR.js → EAOKCWED.js} +6 -6
- package/dist/cdn/IBZ2NEAO.js +2 -0
- package/dist/cdn/{PKJY7FBV.js → KP2FWABJ.js} +1 -1
- package/dist/cdn/LM2IGECE.js +2 -0
- package/dist/cdn/{PBMQI4MV.js → MAPKEX67.js} +1 -1
- package/dist/cdn/{J7OJABFU.js → MYH43WYG.js} +1 -1
- package/dist/cdn/{GAPKW32H.js → NPBXE4EQ.js} +1 -1
- package/dist/cdn/{BGD2CCRJ.js → NZJ6LLYY.js} +1 -1
- package/dist/cdn/RHYNE5OE.js +2 -0
- package/dist/cdn/W7OT3KRG.js +18 -0
- package/dist/cdn/XCNN7BQ3.js +2 -0
- package/dist/cdn/agent-utils/index.js +1 -1
- package/dist/cdn/index.js +1 -1
- package/dist/chunks/adapter.js +14 -14
- package/dist/chunks/dataExplorationGraph.js +121 -195
- package/dist/chunks/fieldStatistics.js +79 -0
- package/dist/chunks/layerStylingGraph.js +9 -9
- package/dist/components/arcgis-assistant-agent/customElement.js +152 -184
- package/dist/docs/api.json +1 -1
- package/dist/docs/docs.json +1 -1
- package/dist/docs/web-types.json +1 -1
- package/package.json +7 -5
- package/dist/agentic-workflow/nodes/support/Prompt.d.ts +0 -20
- package/dist/cdn/BS3HNSXX.js +0 -2
- package/dist/cdn/BWLXDT75.js +0 -2
- package/dist/cdn/I7KCB7KE.js +0 -18
- package/dist/cdn/YYSRYOHL.js +0 -2
- /package/dist/cdn/{3ORURUNE.js → J4R7KYJ3.js} +0 -0
|
@@ -1,302 +1,228 @@
|
|
|
1
1
|
/* COPYRIGHT Esri - https://js.arcgis.com/5.2/LICENSE.txt */
|
|
2
|
-
import { StateGraph as
|
|
3
|
-
import { g as
|
|
2
|
+
import { StateGraph as R, START as F, END as y } from "@langchain/langgraph/web";
|
|
3
|
+
import { g as x, j as w, t as v, k as C, r as N, D as T, l as b } from "./adapter.js";
|
|
4
4
|
import "@arcgis/core/identity/IdentityManager.js";
|
|
5
5
|
import "@arcgis/core/portal/Portal.js";
|
|
6
6
|
import "@arcgis/core/request.js";
|
|
7
7
|
import "@arcgis/toolkit/string";
|
|
8
|
-
import { h as
|
|
9
|
-
import { AIMessage as
|
|
10
|
-
import { s
|
|
8
|
+
import { h as M, e as A } from "./generateLayerDescriptions.js";
|
|
9
|
+
import { AIMessage as _ } from "@langchain/core/messages";
|
|
10
|
+
import { s } from "./index.js";
|
|
11
11
|
import "@langchain/openai";
|
|
12
12
|
import "@arcgis/core/config.js";
|
|
13
13
|
import "@arcgis/core/core/reactiveUtils.js";
|
|
14
14
|
import "@arcgis/core/layers/FeatureLayer.js";
|
|
15
15
|
import "@langchain/core/prompts";
|
|
16
|
-
import { h as
|
|
17
|
-
import { b as
|
|
18
|
-
import { ToolNode as
|
|
19
|
-
import
|
|
20
|
-
import
|
|
21
|
-
import { f as
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const d = await T("data_explore_filter_prompt");
|
|
16
|
+
import { h as L } from "./toolCallResponse.js";
|
|
17
|
+
import { b as q } from "./formatFeatureAttributes.js";
|
|
18
|
+
import { ToolNode as k } from "@langchain/langgraph/prebuilt";
|
|
19
|
+
import { b as $ } from "./fieldStatistics.js";
|
|
20
|
+
import { f as D } from "./fetchAgentContext.js";
|
|
21
|
+
import { f as m } from "./fetchService.js";
|
|
22
|
+
const I = async (t, e) => (await s({ text: "Exiting Data Exploration agent" }, e), t), z = async (t, e) => {
|
|
23
|
+
await s({ text: "Requesting LLM for layer filter results" }, e);
|
|
24
|
+
const l = await x("data_explore_filter_prompt");
|
|
26
25
|
if (!e?.configurable)
|
|
27
26
|
throw new Error("config.configurable is required for layer filter tools");
|
|
28
|
-
const { userTimezone:
|
|
27
|
+
const { userTimezone: d, userTimezoneOffset: r } = q(), o = {
|
|
29
28
|
layerFieldInfo: t.layerFieldInfo,
|
|
30
|
-
userTimezone:
|
|
31
|
-
userTimezoneOffset:
|
|
29
|
+
userTimezone: d,
|
|
30
|
+
userTimezoneOffset: r,
|
|
32
31
|
queryResponse: t.queryResponse,
|
|
33
32
|
assignedTask: t.agentExecutionContext.assignedTask,
|
|
34
33
|
userRequest: t.agentExecutionContext.userRequest,
|
|
35
34
|
priorSteps: t.agentExecutionContext.priorSteps
|
|
36
|
-
},
|
|
37
|
-
promptText:
|
|
35
|
+
}, i = await M({
|
|
36
|
+
promptText: l,
|
|
38
37
|
modelTier: "advanced",
|
|
39
38
|
config: e,
|
|
40
39
|
messages: t.dataExplorationMessages,
|
|
41
|
-
inputVariables:
|
|
42
|
-
tools:
|
|
43
|
-
}),
|
|
44
|
-
if (!((
|
|
45
|
-
return await
|
|
40
|
+
inputVariables: o,
|
|
41
|
+
tools: w
|
|
42
|
+
}), n = [...t.dataExplorationMessages, i];
|
|
43
|
+
if (!((i.tool_calls?.length ?? 0) > 0))
|
|
44
|
+
return await s({ text: "LLM determined no filter changes needed" }, e), {
|
|
46
45
|
...t,
|
|
47
|
-
dataExplorationMessages:
|
|
46
|
+
dataExplorationMessages: n
|
|
48
47
|
// Don't overwrite outputMessage if query already set it
|
|
49
48
|
};
|
|
50
|
-
const
|
|
51
|
-
return await
|
|
52
|
-
},
|
|
53
|
-
await
|
|
54
|
-
const
|
|
49
|
+
const u = n, p = i.content.toString();
|
|
50
|
+
return await L(i, e), { ...t, dataExplorationMessages: u, outputMessage: p };
|
|
51
|
+
}, Q = async (t, e) => {
|
|
52
|
+
await s({ text: "Requesting LLM for layer query results" }, e);
|
|
53
|
+
const l = await x("data_explore_query_prompt");
|
|
55
54
|
if (!e?.configurable)
|
|
56
55
|
throw new Error("config.configurable is required for layer query tools");
|
|
57
|
-
const { userTimezone:
|
|
56
|
+
const { userTimezone: d, userTimezoneOffset: r } = q(), o = t.agentExecutionContext.sharedState, i = o.lastNavigatedFeatures?.value, n = o.lastResolvedLocation?.value;
|
|
58
57
|
let c = "none";
|
|
59
|
-
if (
|
|
58
|
+
if (i != null)
|
|
60
59
|
try {
|
|
61
|
-
c = JSON.stringify(
|
|
60
|
+
c = JSON.stringify(i);
|
|
62
61
|
} catch {
|
|
63
62
|
c = "none";
|
|
64
63
|
}
|
|
65
|
-
let
|
|
66
|
-
if (
|
|
64
|
+
let u = "none";
|
|
65
|
+
if (n != null)
|
|
67
66
|
try {
|
|
68
|
-
|
|
69
|
-
address:
|
|
70
|
-
location:
|
|
67
|
+
u = JSON.stringify({
|
|
68
|
+
address: n.address,
|
|
69
|
+
location: n.location
|
|
71
70
|
});
|
|
72
71
|
} catch {
|
|
73
|
-
|
|
72
|
+
u = "none";
|
|
74
73
|
}
|
|
75
|
-
const
|
|
74
|
+
const p = {
|
|
76
75
|
layerFieldInfo: t.layerFieldInfo,
|
|
77
|
-
userTimezone:
|
|
78
|
-
userTimezoneOffset:
|
|
76
|
+
userTimezone: d,
|
|
77
|
+
userTimezoneOffset: r,
|
|
79
78
|
assignedTask: t.agentExecutionContext.assignedTask,
|
|
80
79
|
userRequest: t.agentExecutionContext.userRequest,
|
|
81
80
|
priorSteps: t.agentExecutionContext.priorSteps,
|
|
82
81
|
lastNavigatedFeatures: c,
|
|
83
|
-
lastResolvedLocation:
|
|
84
|
-
},
|
|
85
|
-
promptText:
|
|
82
|
+
lastResolvedLocation: u
|
|
83
|
+
}, g = await M({
|
|
84
|
+
promptText: l,
|
|
86
85
|
modelTier: "advanced",
|
|
87
86
|
config: e,
|
|
88
87
|
messages: t.dataExplorationMessages,
|
|
89
|
-
inputVariables:
|
|
90
|
-
tools:
|
|
91
|
-
}),
|
|
92
|
-
return await
|
|
88
|
+
inputVariables: p,
|
|
89
|
+
tools: C
|
|
90
|
+
}), f = (g.tool_calls?.length ?? 0) > 0, h = g.content.toString();
|
|
91
|
+
return await L(g, e), {
|
|
93
92
|
...t,
|
|
94
|
-
dataExplorationMessages: [...t.dataExplorationMessages,
|
|
93
|
+
dataExplorationMessages: [...t.dataExplorationMessages, g],
|
|
95
94
|
// Only emit output here when no tools are being called.
|
|
96
95
|
// For tool-calling flows, downstream summarizer nodes provide the final user-facing message.
|
|
97
|
-
...
|
|
96
|
+
...f ? {} : { outputMessage: h },
|
|
98
97
|
status: "success",
|
|
99
|
-
summary:
|
|
98
|
+
summary: h && !f ? v(h) : "Query planning completed."
|
|
100
99
|
};
|
|
101
|
-
},
|
|
100
|
+
}, V = async (t, e) => {
|
|
102
101
|
try {
|
|
103
|
-
await
|
|
104
|
-
const
|
|
102
|
+
await s({ text: "Requesting LLM for summary on query results" }, e);
|
|
103
|
+
const l = await x("summarize_query_response_prompt"), d = {
|
|
105
104
|
queryResponse: t.queryResponse,
|
|
106
105
|
assignedTask: t.agentExecutionContext.assignedTask,
|
|
107
106
|
userRequest: t.agentExecutionContext.userRequest,
|
|
108
107
|
priorSteps: t.agentExecutionContext.priorSteps
|
|
109
|
-
},
|
|
110
|
-
promptText:
|
|
108
|
+
}, r = await A({
|
|
109
|
+
promptText: l,
|
|
111
110
|
modelTier: "fast",
|
|
112
111
|
config: e,
|
|
113
112
|
messages: t.dataExplorationMessages,
|
|
114
|
-
inputVariables:
|
|
115
|
-
}),
|
|
116
|
-
await
|
|
117
|
-
const
|
|
113
|
+
inputVariables: d
|
|
114
|
+
}), o = typeof r == "string" ? r : r.content, i = new _(o);
|
|
115
|
+
await s({ text: `Received response from LLM: ${o}` }, e);
|
|
116
|
+
const n = o;
|
|
118
117
|
return {
|
|
119
118
|
...t,
|
|
120
|
-
outputMessage:
|
|
119
|
+
outputMessage: n,
|
|
121
120
|
status: "success",
|
|
122
|
-
summary:
|
|
123
|
-
dataExplorationMessages: [...t.dataExplorationMessages,
|
|
121
|
+
summary: n ? v(n) : "Summary generated.",
|
|
122
|
+
dataExplorationMessages: [...t.dataExplorationMessages, i]
|
|
124
123
|
};
|
|
125
124
|
} catch (a) {
|
|
126
|
-
throw await
|
|
125
|
+
throw await s({ text: "Error during filter LLM request" }, e), new Error(`Error during filter LLM request: ${a instanceof Error ? a.message : String(a)}`);
|
|
127
126
|
}
|
|
128
127
|
};
|
|
129
|
-
async function
|
|
130
|
-
if ((t.queryResponse ?? []).some((
|
|
131
|
-
const
|
|
132
|
-
return typeof
|
|
128
|
+
async function O(t, e) {
|
|
129
|
+
if ((t.queryResponse ?? []).some((r) => {
|
|
130
|
+
const o = r.details;
|
|
131
|
+
return typeof o == "object" && o !== null && "error" in o;
|
|
133
132
|
}))
|
|
134
|
-
return await
|
|
135
|
-
const
|
|
133
|
+
return await s({ text: "Skipping layer filter tool because query response contains an error." }, e), { ...t };
|
|
134
|
+
const d = await new k(w, { handleToolErrors: !1 }).invoke(
|
|
136
135
|
{
|
|
137
136
|
messages: t.dataExplorationMessages
|
|
138
137
|
},
|
|
139
138
|
e
|
|
140
139
|
);
|
|
141
|
-
return await
|
|
142
|
-
{ text: `Finished executing layer filter tool: ${
|
|
140
|
+
return await s(
|
|
141
|
+
{ text: `Finished executing layer filter tool: ${d.messages.map((r) => r.content).join(", ")}` },
|
|
143
142
|
e
|
|
144
143
|
), { ...t };
|
|
145
144
|
}
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if (e.type !== "geometry" && e.type !== "oid" && e.type !== "global-id") {
|
|
150
|
-
a && (l = await j({ layer: t, field: e.name }));
|
|
151
|
-
const r = e.domain?.type === "coded-value" ? e.domain : null;
|
|
152
|
-
d && (Y.includes(e.type) || r) && (s = (await G({ layer: t, field: e.name })).uniqueValueInfos.sort((o, i) => i.count - o.count).slice(0, X), r && (s = s.map((o) => ({
|
|
153
|
-
...o,
|
|
154
|
-
value: r.getName(o.value) ?? o.value
|
|
155
|
-
}))));
|
|
156
|
-
}
|
|
157
|
-
} catch (r) {
|
|
158
|
-
console.error(`Error fetching statistics for field ${e.name}:`, r);
|
|
159
|
-
}
|
|
160
|
-
return {
|
|
161
|
-
summaryStatistics: l,
|
|
162
|
-
uniqueValues: s
|
|
163
|
-
};
|
|
164
|
-
};
|
|
165
|
-
function ee(t, e) {
|
|
166
|
-
return ["string", "small-integer", "integer"].includes(t) || e === "coded-value";
|
|
145
|
+
const E = /\b(average|avg|mean|median|max(?:imum)?|min(?:imum)?|sum|total|count|std(?:dev|\s*deviation)|variance|null\s*count|missing\s*values?|range)\b/iu;
|
|
146
|
+
function P(t, e) {
|
|
147
|
+
return E.test(t) || E.test(e);
|
|
167
148
|
}
|
|
168
|
-
async
|
|
169
|
-
const l = [], s = [], r = [];
|
|
170
|
-
for (const o of t) {
|
|
171
|
-
let i = function(p) {
|
|
172
|
-
const u = e.get(p)?.layerItem;
|
|
173
|
-
return u ? [
|
|
174
|
-
u.name && `Name: ${u.name}`,
|
|
175
|
-
u.title && `Title: ${u.title}`,
|
|
176
|
-
u.description && `Description: ${u.description}`
|
|
177
|
-
].filter(Boolean).join(" | ") : p;
|
|
178
|
-
};
|
|
179
|
-
const { layerId: c, results: m } = o, g = a.map?.allLayers.find((p) => p.id === c), y = e.get(c)?.fieldRegistry;
|
|
180
|
-
if (!y)
|
|
181
|
-
continue;
|
|
182
|
-
let h = l.find((p) => p.layerId === c);
|
|
183
|
-
h || (h = {
|
|
184
|
-
layerId: c,
|
|
185
|
-
layerSummary: i(c),
|
|
186
|
-
fieldInfos: []
|
|
187
|
-
}, l.push(h));
|
|
188
|
-
for (const p of m) {
|
|
189
|
-
const u = y.get(p.name);
|
|
190
|
-
if (!u)
|
|
191
|
-
continue;
|
|
192
|
-
const x = u.statistics, E = d && !x?.summaryStatistics, w = ee(u.type, u.domain?.type) && !x?.uniqueValues, q = E || w;
|
|
193
|
-
if (r.push({
|
|
194
|
-
layerId: c,
|
|
195
|
-
fieldName: u.name,
|
|
196
|
-
didFetchStatistics: q
|
|
197
|
-
}), q) {
|
|
198
|
-
const $ = Z(g, u, {
|
|
199
|
-
includeSummaryStatistics: E,
|
|
200
|
-
includeUniqueValues: w
|
|
201
|
-
}).then((F) => {
|
|
202
|
-
const S = {
|
|
203
|
-
summaryStatistics: x?.summaryStatistics ?? null,
|
|
204
|
-
uniqueValues: x?.uniqueValues ?? null
|
|
205
|
-
};
|
|
206
|
-
E && (S.summaryStatistics = F.summaryStatistics), w && (S.uniqueValues = F.uniqueValues), y.set(u.name, { ...u, statistics: S }), u.statistics = S;
|
|
207
|
-
});
|
|
208
|
-
s.push($);
|
|
209
|
-
}
|
|
210
|
-
h.fieldInfos.push(u);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
return await Promise.all(s), {
|
|
214
|
-
layerFieldInfo: l,
|
|
215
|
-
didFetchStatistics: s.length > 0,
|
|
216
|
-
fieldStatisticsFetchStatus: r
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
const L = /\b(average|avg|mean|median|max(?:imum)?|min(?:imum)?|sum|total|count|std(?:dev|\s*deviation)|variance|null\s*count|missing\s*values?|range)\b/iu;
|
|
220
|
-
function ae(t, e) {
|
|
221
|
-
return L.test(t) || L.test(e);
|
|
222
|
-
}
|
|
223
|
-
const se = async (t, e) => {
|
|
149
|
+
const j = async (t, e) => {
|
|
224
150
|
try {
|
|
225
|
-
await
|
|
226
|
-
const a =
|
|
151
|
+
await s({ text: "Preparing field information for vector search results" }, e);
|
|
152
|
+
const a = m(e, "layersAndFieldsRegistry"), { mapView: l } = D(e, ["mapView"]), { assignedTask: d, userRequest: r } = t.agentExecutionContext, o = P(d, r), { layerFieldInfo: i, didFetchStatistics: n, fieldStatisticsFetchStatus: c } = await $(
|
|
227
153
|
t.vectorSearchFieldResults,
|
|
228
154
|
a,
|
|
229
|
-
|
|
230
|
-
|
|
155
|
+
l,
|
|
156
|
+
o
|
|
231
157
|
);
|
|
232
|
-
|
|
233
|
-
for (const
|
|
234
|
-
await
|
|
158
|
+
n ? await s({ text: "Statistics fetched" }, e) : await s({ text: "Statistics skipped" }, e);
|
|
159
|
+
for (const u of c)
|
|
160
|
+
await s(
|
|
235
161
|
{
|
|
236
|
-
text: ` - ${
|
|
162
|
+
text: ` - ${u.fieldName} - stats ${u.didFetchStatistics ? "fetched" : "skipped"}`
|
|
237
163
|
},
|
|
238
164
|
e
|
|
239
165
|
);
|
|
240
|
-
return await
|
|
166
|
+
return await s({ text: "Field information prepared" }, e), { ...t, layerFieldInfo: i };
|
|
241
167
|
} catch (a) {
|
|
242
|
-
throw await
|
|
168
|
+
throw await s({ text: "Error during fetching statistics" }, e), new Error(`Error during fetching statistics: ${a instanceof Error ? a.message : String(a)}`);
|
|
243
169
|
}
|
|
244
|
-
},
|
|
170
|
+
}, S = 0.7, G = 10, W = async (t, e) => {
|
|
245
171
|
try {
|
|
246
|
-
await
|
|
247
|
-
const a =
|
|
172
|
+
await s({ text: "Similarity search to find fields" }, e);
|
|
173
|
+
const a = m(e, "fieldSearch"), l = m(e, "layersAndFieldsRegistry"), d = m(e, "embeddingCache"), r = await a.searchFields({
|
|
248
174
|
text: t.agentExecutionContext.assignedTask,
|
|
249
175
|
layerIds: t.vectorSearchLayerIds,
|
|
250
|
-
minScore:
|
|
251
|
-
topResults:
|
|
252
|
-
embeddingCache:
|
|
253
|
-
}),
|
|
254
|
-
const
|
|
176
|
+
minScore: S,
|
|
177
|
+
topResults: G,
|
|
178
|
+
embeddingCache: d
|
|
179
|
+
}), o = r.map(({ layerId: n, results: c }) => {
|
|
180
|
+
const u = c.map((p) => ` - ${p.name} (${p.score.toFixed(2)})`).join(`
|
|
255
181
|
`);
|
|
256
|
-
return `${
|
|
257
|
-
${
|
|
182
|
+
return `${l.get(n)?.layerItem.name ?? n}:
|
|
183
|
+
${u}`;
|
|
258
184
|
}).join(`
|
|
259
185
|
`);
|
|
260
|
-
let
|
|
261
|
-
return
|
|
262
|
-
${
|
|
186
|
+
let i;
|
|
187
|
+
return r.length > 0 ? i = `Vector search completed. Matching layers and fields with scores:
|
|
188
|
+
${o}` : i = `No vector search results found for score over ${S}.`, await s({ text: i }, e), {
|
|
263
189
|
...t,
|
|
264
|
-
vectorSearchFieldResults:
|
|
190
|
+
vectorSearchFieldResults: r
|
|
265
191
|
};
|
|
266
192
|
} catch (a) {
|
|
267
|
-
throw await
|
|
193
|
+
throw await s(
|
|
268
194
|
{ text: `Error during vector search: ${a instanceof Error ? a.message : String(a)}` },
|
|
269
195
|
e
|
|
270
196
|
), new Error(`Vector search failed: ${a instanceof Error ? a.message : String(a)}`);
|
|
271
197
|
}
|
|
272
|
-
},
|
|
198
|
+
}, H = 0.7, J = async (t, e) => {
|
|
273
199
|
try {
|
|
274
|
-
await
|
|
200
|
+
await s(
|
|
275
201
|
{ text: `Similarity search to find layers: ${t.agentExecutionContext.assignedTask}` },
|
|
276
202
|
e
|
|
277
203
|
);
|
|
278
|
-
const a =
|
|
204
|
+
const a = m(e, "layerSearch"), l = m(e, "layersAndFieldsRegistry"), d = m(e, "embeddingCache"), r = await a.searchLayers({
|
|
279
205
|
text: t.agentExecutionContext.assignedTask,
|
|
280
|
-
minScore:
|
|
281
|
-
embeddingCache:
|
|
282
|
-
}),
|
|
206
|
+
minScore: H,
|
|
207
|
+
embeddingCache: d
|
|
208
|
+
}), o = r.map((c) => c.id), i = r.map(({ id: c, score: u }) => `${l.get(c)?.layerItem.name ?? c} (${u.toFixed(2)})`).join(`
|
|
283
209
|
`);
|
|
284
|
-
let
|
|
285
|
-
return
|
|
286
|
-
${
|
|
210
|
+
let n;
|
|
211
|
+
return o.length > 0 ? n = `Vector search completed. Matching layers with scores:
|
|
212
|
+
${i}` : n = "Vector search completed. No matching layers found.", await s({ text: n }, e), {
|
|
287
213
|
...t,
|
|
288
|
-
vectorSearchLayerIds:
|
|
214
|
+
vectorSearchLayerIds: o
|
|
289
215
|
};
|
|
290
216
|
} catch (a) {
|
|
291
|
-
throw await
|
|
217
|
+
throw await s(
|
|
292
218
|
{ text: `Error during vector search: ${a instanceof Error ? a.message : String(a)}` },
|
|
293
219
|
e
|
|
294
220
|
), new Error(`Vector search failed: ${a instanceof Error ? a.message : String(a)}`);
|
|
295
221
|
}
|
|
296
|
-
},
|
|
222
|
+
}, U = (t, e) => N(["layerSearch", "fieldSearch", "layersAndFieldsRegistry"], "Data Exploration Agent")(
|
|
297
223
|
t,
|
|
298
224
|
e
|
|
299
|
-
),
|
|
225
|
+
), B = () => new R(T).addNode("requireDataExplorationServices", U).addNode("vectorSearchLayers", J).addNode("vectorSearchFields", W).addNode("fieldStatistics", j).addNode("queryAgent", Q).addNode("queryTools", b).addNode("summarizeQueryResponseLLM", V).addNode("filterAgent", z).addNode("filterTools", O).addNode("earlyExit", I).addEdge(F, "requireDataExplorationServices").addEdge("requireDataExplorationServices", "vectorSearchLayers").addConditionalEdges(
|
|
300
226
|
"vectorSearchLayers",
|
|
301
227
|
(e) => e.vectorSearchLayerIds.length ? "vectorSearchFields" : "earlyExit"
|
|
302
228
|
).addConditionalEdges(
|
|
@@ -305,7 +231,7 @@ ${o}` : i = "Vector search completed. No matching layers found.", await n({ text
|
|
|
305
231
|
).addEdge("fieldStatistics", "queryAgent").addConditionalEdges("queryAgent", (e) => (e.dataExplorationMessages[e.dataExplorationMessages.length - 1]?.tool_calls?.length ?? 0) > 0 ? "queryTools" : "filterAgent").addConditionalEdges(
|
|
306
232
|
"queryTools",
|
|
307
233
|
(e) => e.queryResponse.length ? "summarizeQueryResponseLLM" : "filterAgent"
|
|
308
|
-
).addEdge("summarizeQueryResponseLLM", "filterAgent").addConditionalEdges("filterAgent", (e) => (e.dataExplorationMessages[e.dataExplorationMessages.length - 1]?.tool_calls?.length ?? 0) > 0 ? "filterTools" :
|
|
234
|
+
).addEdge("summarizeQueryResponseLLM", "filterAgent").addConditionalEdges("filterAgent", (e) => (e.dataExplorationMessages[e.dataExplorationMessages.length - 1]?.tool_calls?.length ?? 0) > 0 ? "filterTools" : y).addEdge("filterTools", y).addEdge("earlyExit", y), K = 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).
|
|
309
235
|
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.
|
|
310
236
|
_Example: “Only show stations where Brand is Shell”_
|
|
311
237
|
_Example: “Make Shell stations stand out on the map”_
|
|
@@ -315,13 +241,13 @@ ${o}` : i = "Vector search completed. No matching layers found.", await n({ text
|
|
|
315
241
|
_Example: “What’s the average population?”_
|
|
316
242
|
_Example: “Which values are in the status field?”_
|
|
317
243
|
|
|
318
|
-
This agent does NOT handle help/metadata requests such as listing available layers, listing field names/columns/attributes for a layer, or capability guidance.`,
|
|
244
|
+
This agent does NOT handle help/metadata requests such as listing available layers, listing field names/columns/attributes for a layer, or capability guidance.`, xe = {
|
|
319
245
|
id: "dataExploration",
|
|
320
246
|
name: "Data Exploration Agent",
|
|
321
|
-
description:
|
|
322
|
-
createGraph:
|
|
323
|
-
workspace:
|
|
247
|
+
description: K,
|
|
248
|
+
createGraph: B,
|
|
249
|
+
workspace: T
|
|
324
250
|
};
|
|
325
251
|
export {
|
|
326
|
-
|
|
252
|
+
xe as D
|
|
327
253
|
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/* COPYRIGHT Esri - https://js.arcgis.com/5.2/LICENSE.txt */
|
|
2
|
+
import v from "@arcgis/core/smartMapping/statistics/summaryStatistics.js";
|
|
3
|
+
import L from "@arcgis/core/smartMapping/statistics/uniqueValues.js";
|
|
4
|
+
const $ = 10, b = ["string", "small-integer", "integer"], w = async (u, e, { includeSummaryStatistics: d = !0, includeUniqueValues: y = !0 } = {}) => {
|
|
5
|
+
let r = null, s = null;
|
|
6
|
+
try {
|
|
7
|
+
if (e.type !== "geometry" && e.type !== "oid" && e.type !== "global-id") {
|
|
8
|
+
d && (r = await v({ layer: u, field: e.name }));
|
|
9
|
+
const i = e.domain?.type === "coded-value" ? e.domain : null;
|
|
10
|
+
y && (b.includes(e.type) || i) && (s = (await L({ layer: u, field: e.name })).uniqueValueInfos.sort((n, f) => f.count - n.count).slice(0, $), i && (s = s.map((n) => ({
|
|
11
|
+
...n,
|
|
12
|
+
value: i.getName(n.value) ?? n.value
|
|
13
|
+
}))));
|
|
14
|
+
}
|
|
15
|
+
} catch (i) {
|
|
16
|
+
console.error(`Error fetching statistics for field ${e.name}:`, i);
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
summaryStatistics: r,
|
|
20
|
+
uniqueValues: s
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
function N(u, e) {
|
|
24
|
+
return ["string", "small-integer", "integer"].includes(u) || e === "coded-value";
|
|
25
|
+
}
|
|
26
|
+
async function x(u, e, d, y = !0) {
|
|
27
|
+
const r = [], s = [], i = [];
|
|
28
|
+
for (const n of u) {
|
|
29
|
+
let f = function(a) {
|
|
30
|
+
const t = e.get(a)?.layerItem;
|
|
31
|
+
return t ? [
|
|
32
|
+
t.name && `Name: ${t.name}`,
|
|
33
|
+
t.title && `Title: ${t.title}`,
|
|
34
|
+
t.description && `Description: ${t.description}`
|
|
35
|
+
].filter(Boolean).join(" | ") : a;
|
|
36
|
+
};
|
|
37
|
+
const { layerId: c, results: q } = n, I = d.map?.allLayers.find((a) => a.id === c), S = e.get(c)?.fieldRegistry;
|
|
38
|
+
if (!S)
|
|
39
|
+
continue;
|
|
40
|
+
let l = r.find((a) => a.layerId === c);
|
|
41
|
+
l || (l = {
|
|
42
|
+
layerId: c,
|
|
43
|
+
layerSummary: f(c),
|
|
44
|
+
fieldInfos: []
|
|
45
|
+
}, r.push(l));
|
|
46
|
+
for (const a of q) {
|
|
47
|
+
const t = S.get(a.name);
|
|
48
|
+
if (!t)
|
|
49
|
+
continue;
|
|
50
|
+
const o = t.statistics, p = y && !o?.summaryStatistics, g = N(t.type, t.domain?.type) && !o?.uniqueValues, h = p || g;
|
|
51
|
+
if (i.push({
|
|
52
|
+
layerId: c,
|
|
53
|
+
fieldName: t.name,
|
|
54
|
+
didFetchStatistics: h
|
|
55
|
+
}), h) {
|
|
56
|
+
const F = w(I, t, {
|
|
57
|
+
includeSummaryStatistics: p,
|
|
58
|
+
includeUniqueValues: g
|
|
59
|
+
}).then((V) => {
|
|
60
|
+
const m = {
|
|
61
|
+
summaryStatistics: o?.summaryStatistics ?? null,
|
|
62
|
+
uniqueValues: o?.uniqueValues ?? null
|
|
63
|
+
};
|
|
64
|
+
p && (m.summaryStatistics = V.summaryStatistics), g && (m.uniqueValues = V.uniqueValues), S.set(t.name, { ...t, statistics: m }), t.statistics = m;
|
|
65
|
+
});
|
|
66
|
+
s.push(F);
|
|
67
|
+
}
|
|
68
|
+
l.fieldInfos.push(t);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return await Promise.all(s), {
|
|
72
|
+
layerFieldInfo: r,
|
|
73
|
+
didFetchStatistics: s.length > 0,
|
|
74
|
+
fieldStatisticsFetchStatus: i
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export {
|
|
78
|
+
x as b
|
|
79
|
+
};
|
|
@@ -13,17 +13,17 @@ import "@arcgis/core/core/reactiveUtils.js";
|
|
|
13
13
|
import "@arcgis/core/layers/FeatureLayer.js";
|
|
14
14
|
import "@langchain/core/prompts";
|
|
15
15
|
import { f as g } from "./fetchService.js";
|
|
16
|
-
import {
|
|
17
|
-
import { h as
|
|
18
|
-
import { ToolNode as
|
|
19
|
-
const h = 0.7,
|
|
16
|
+
import { m as I, n as T, o as R, p as F, u as C, v as A, w as $, x as N, y as b, z as q, A as _, g as M, r as k, L as S } from "./adapter.js";
|
|
17
|
+
import { h as V } from "./toolCallResponse.js";
|
|
18
|
+
import { ToolNode as j } from "@langchain/langgraph/prebuilt";
|
|
19
|
+
const h = 0.7, z = 10, P = async (t, e) => {
|
|
20
20
|
try {
|
|
21
21
|
await i({ text: "Similarity search to find fields" }, e);
|
|
22
22
|
const r = g(e, "fieldSearch"), a = g(e, "layersAndFieldsRegistry"), o = g(e, "embeddingCache"), n = await r.searchFields({
|
|
23
23
|
text: t.agentExecutionContext.assignedTask,
|
|
24
24
|
layerIds: t.vectorSearchLayerIds,
|
|
25
25
|
minScore: h,
|
|
26
|
-
topResults:
|
|
26
|
+
topResults: z,
|
|
27
27
|
embeddingCache: o
|
|
28
28
|
}), c = n.map(({ layerId: d, results: p }) => {
|
|
29
29
|
const y = p.map((s) => ` - ${s.name} (${s.score.toFixed(2)})`).join(`
|
|
@@ -73,8 +73,8 @@ ${c}` : l = "Vector search completed. No matching layers found.", await i({ text
|
|
|
73
73
|
R,
|
|
74
74
|
F,
|
|
75
75
|
C,
|
|
76
|
-
$,
|
|
77
76
|
A,
|
|
77
|
+
$,
|
|
78
78
|
N,
|
|
79
79
|
b,
|
|
80
80
|
q,
|
|
@@ -100,7 +100,7 @@ ${c}` : l = "Vector search completed. No matching layers found.", await i({ text
|
|
|
100
100
|
inputVariables: a,
|
|
101
101
|
tools: f
|
|
102
102
|
});
|
|
103
|
-
return await
|
|
103
|
+
return await V(o, e), {
|
|
104
104
|
...t,
|
|
105
105
|
agentExecutionContext: {
|
|
106
106
|
...t.agentExecutionContext,
|
|
@@ -109,7 +109,7 @@ ${c}` : l = "Vector search completed. No matching layers found.", await i({ text
|
|
|
109
109
|
};
|
|
110
110
|
};
|
|
111
111
|
async function U(t, e) {
|
|
112
|
-
const a = await new
|
|
112
|
+
const a = await new j(f, { handleToolErrors: !1 }).invoke(
|
|
113
113
|
{
|
|
114
114
|
messages: x(t.agentExecutionContext.messages)
|
|
115
115
|
},
|
|
@@ -172,7 +172,7 @@ const B = async (t, e) => (await i({ text: "Exiting Layer Styling agent" }, e),
|
|
|
172
172
|
...t,
|
|
173
173
|
selectedLayerId: o ?? t.vectorSearchLayerIds[0]
|
|
174
174
|
};
|
|
175
|
-
}, K = (t, e) => k(["layerSearch", "fieldSearch", "layersAndFieldsRegistry"], "Layer Styling Agent")(t, e), Q = () => new L(S).addNode("requireLayerStylingServices", K).addNode("vectorSearchLayers", H).addNode("layerSelectionHITL", J).addNode("vectorSearchFields",
|
|
175
|
+
}, K = (t, e) => k(["layerSearch", "fieldSearch", "layersAndFieldsRegistry"], "Layer Styling Agent")(t, e), Q = () => new L(S).addNode("requireLayerStylingServices", K).addNode("vectorSearchLayers", H).addNode("layerSelectionHITL", J).addNode("vectorSearchFields", P).addNode("populateLayerFieldInfo", O).addNode("agent", G).addNode("tools", U).addNode("earlyExit", B).addEdge(E, "requireLayerStylingServices").addEdge("requireLayerStylingServices", "vectorSearchLayers").addConditionalEdges(
|
|
176
176
|
"layerSelectionHITL",
|
|
177
177
|
(e) => e.vectorSearchLayerIds.length ? "vectorSearchFields" : "earlyExit"
|
|
178
178
|
).addConditionalEdges(
|