@arcgis/portal-components 5.2.0-next.86 → 5.2.0-next.88
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/cdn/2TQ4B2LU.js +2 -0
- package/dist/cdn/4GRTJ7XT.js +2 -0
- package/dist/cdn/{ZAB6B2B6.js → 5EMPEJ65.js} +1 -1
- package/dist/cdn/5RYUVYNA.js +2 -0
- package/dist/cdn/{6BALICUQ.js → CGB3PBCS.js} +72 -72
- package/dist/cdn/DC37QXXI.js +2 -0
- package/dist/cdn/{DHWAQSKG.js → F3LFFR3K.js} +1 -1
- package/dist/cdn/F3M3R7X2.js +2 -0
- package/dist/cdn/{CD2GV5YW.js → F76RXJ66.js} +1 -1
- package/dist/cdn/FQTFZLHT.js +2 -0
- package/dist/cdn/KYNL256E.js +2 -0
- package/dist/cdn/{NASFEWDT.js → LDYOCDG6.js} +1 -1
- package/dist/cdn/{LRADZ46B.js → NQQLTGIK.js} +1 -1
- package/dist/cdn/{BBVFGC6Y.js → OFAEJ3GS.js} +1 -1
- package/dist/cdn/{R5MGNFM2.js → PMQCCLS5.js} +1 -1
- package/dist/cdn/QTKBB22S.js +2 -0
- package/dist/cdn/{2Q3FIPE2.js → RJPGQVI2.js} +1 -1
- package/dist/cdn/{LDIZD36E.js → S47JWYSF.js} +1 -1
- package/dist/cdn/SYDYG3CL.js +2 -0
- package/dist/cdn/{TUBYAQ6R.js → X5B4PAML.js} +1 -1
- package/dist/cdn/{ECA5GSSU.js → X6XTK2TE.js} +1 -1
- package/dist/cdn/YBWCEZJP.js +2 -0
- package/dist/cdn/assets/portal-account-switcher/t9n/messages.en.json +1 -1
- package/dist/cdn/index.js +1 -1
- package/dist/chunks/fieldAddDelete.js +1 -1
- package/dist/chunks/groups2.js +1 -1
- package/dist/chunks/item2.js +1 -1
- package/dist/chunks/portal-account-switcher.js +3 -3
- package/dist/chunks/portal-browser-filter-date.js +63 -0
- package/dist/chunks/portal.js +2 -2
- package/dist/chunks/portal2.js +1 -1
- package/dist/chunks/request.js +1 -1
- package/dist/chunks/services.js +17 -0
- package/dist/chunks/user.js +1 -1
- package/dist/chunks/utils.js +4 -4
- package/dist/components/arcgis-portal-account-switcher/customElement.d.ts +22 -2
- package/dist/components/arcgis-portal-account-switcher/customElement.js +211 -207
- package/dist/components/arcgis-portal-account-switcher/index.js +1 -3
- package/dist/components/arcgis-portal-account-switcher/types.d.ts +6 -0
- package/dist/components/arcgis-portal-account-switcher-accounts/customElement.d.ts +20 -2
- package/dist/components/arcgis-portal-account-switcher-accounts/customElement.js +5 -5
- package/dist/components/arcgis-portal-account-switcher-list/customElement.d.ts +22 -4
- package/dist/components/arcgis-portal-account-switcher-list/customElement.js +58 -37
- package/dist/components/arcgis-portal-account-switcher-list/index.js +2 -3
- package/dist/components/arcgis-portal-ai-assistant/agents/portalRouteKeys.d.ts +25 -16
- package/dist/components/arcgis-portal-ai-assistant/agents/types.d.ts +4 -4
- package/dist/components/arcgis-portal-ai-assistant/customElement.d.ts +6 -0
- package/dist/components/arcgis-portal-ai-assistant/customElement.js +762 -751
- package/dist/components/arcgis-portal-field-delete/customElement.js +1 -1
- package/dist/components/arcgis-portal-group-browser/customElement.d.ts +3 -1
- package/dist/components/arcgis-portal-group-browser/customElement.js +385 -142
- package/dist/components/arcgis-portal-group-browser/types.d.ts +5 -0
- package/dist/components/arcgis-portal-group-thumbnail/customElement.js +1 -1
- package/dist/components/arcgis-portal-navigation/customElement.js +75 -76
- package/dist/components/arcgis-portal-user-avatar/customElement.js +25 -36
- package/dist/components/arcgis-portal-user-popup/customElement.js +27 -27
- package/dist/components/portal-browser/components/portal-browser-filter-date/customElement.js +6 -56
- package/dist/components/portal-group-browser-filters/customElement.js +1 -1
- package/dist/docs/api.json +1 -1
- package/dist/docs/docs.json +1 -1
- package/dist/docs/vscode.html-custom-data.json +1 -1
- package/dist/docs/web-types.json +1 -1
- package/dist/loader.js +6 -6
- package/dist/types/lumina.d.ts +4 -4
- package/dist/types/preact.d.ts +4 -4
- package/dist/types/react.d.ts +4 -4
- package/dist/types/stencil.d.ts +4 -4
- package/dist/types/user.d.ts +1 -1
- package/package.json +7 -7
- package/dist/cdn/5MVBQWW3.js +0 -2
- package/dist/cdn/76A6NXMY.js +0 -2
- package/dist/cdn/E4D3U6ZA.js +0 -2
- package/dist/cdn/GADH24KO.js +0 -2
- package/dist/cdn/J57ZXL3U.js +0 -2
- package/dist/cdn/OAKVCMNN.js +0 -2
- package/dist/cdn/QREMLELA.js +0 -2
- package/dist/cdn/SOJ5KMMZ.js +0 -2
- package/dist/cdn/V6N5BWDA.js +0 -2
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
/* COPYRIGHT Esri - https://js.arcgis.com/5.2/LICENSE.txt */
|
|
2
|
-
import { c as
|
|
3
|
-
import { LitElement as
|
|
4
|
-
import { css as
|
|
5
|
-
import { createRef as
|
|
6
|
-
import { u as
|
|
7
|
-
import { NodeInterrupt as
|
|
8
|
-
import { sendTraceMessage as
|
|
2
|
+
import { c as Ue } from "../../chunks/runtime.js";
|
|
3
|
+
import { LitElement as Fe, createEvent as Oe } from "@arcgis/lumina";
|
|
4
|
+
import { css as Le, render as je, html as v } from "lit";
|
|
5
|
+
import { createRef as E, ref as k } from "lit/directives/ref.js";
|
|
6
|
+
import { u as Ve } from "../../chunks/useT9n.js";
|
|
7
|
+
import { NodeInterrupt as ve, Annotation as h, StateGraph as N, START as G, END as w } from "@langchain/langgraph/web";
|
|
8
|
+
import { sendTraceMessage as g, invokeStructuredPrompt as b, sendUXSuggestion as J, createAgentRuntimeStateWithSharedState as P, createChatModel as _, getEmbeddings as Be } from "@arcgis/ai-components/utils/index.js";
|
|
9
9
|
import s from "zod";
|
|
10
|
-
import { a as
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import { a as
|
|
14
|
-
import { ChatPromptTemplate as
|
|
15
|
-
import { tool as
|
|
16
|
-
import { s as
|
|
17
|
-
import { g as
|
|
18
|
-
import
|
|
19
|
-
const
|
|
20
|
-
const { portal:
|
|
21
|
-
return !!
|
|
10
|
+
import { a as Ke, c as Qe, q as We } from "../../chunks/groups2.js";
|
|
11
|
+
import Z from "@arcgis/core/identity/IdentityManager.js";
|
|
12
|
+
import ee from "@arcgis/core/request.js";
|
|
13
|
+
import { a as U, t as Je, b as Q } from "../../chunks/functionalities.js";
|
|
14
|
+
import { ChatPromptTemplate as Y } from "@langchain/core/prompts";
|
|
15
|
+
import { tool as be } from "@langchain/core/tools";
|
|
16
|
+
import { s as _e, a as Ye } from "../../chunks/item.js";
|
|
17
|
+
import { g as He, e as Xe, i as Ze, c as et, a as tt } from "../../chunks/groups.js";
|
|
18
|
+
import at from "@arcgis/core/portal/Portal.js";
|
|
19
|
+
const Ie = (e) => {
|
|
20
|
+
const { portal: t, user: a } = e ?? {};
|
|
21
|
+
return !!e && !!t && !!a;
|
|
22
22
|
};
|
|
23
|
-
function
|
|
24
|
-
if (!
|
|
23
|
+
function x(e) {
|
|
24
|
+
if (!Ie(e))
|
|
25
25
|
throw new Error("Invalid context: PortalAssistantContext with portal and user is required.");
|
|
26
26
|
}
|
|
27
|
-
const
|
|
27
|
+
const nt = `
|
|
28
28
|
Write a concise, friendly success message for adding members to a group.
|
|
29
29
|
|
|
30
30
|
Rules:
|
|
@@ -39,21 +39,21 @@ Added members:
|
|
|
39
39
|
|
|
40
40
|
Not added members:
|
|
41
41
|
{notAddedMembers}
|
|
42
|
-
`,
|
|
42
|
+
`, ot = (e) => e.map((t) => `"${t}"`).join(", "), rt = s.object({
|
|
43
43
|
successMessage: s.string().default("")
|
|
44
|
-
}),
|
|
45
|
-
if (
|
|
44
|
+
}), te = "portal-group-creation", ae = "approveAddMembers", st = async (e, t) => {
|
|
45
|
+
if (e.intentParams.intent !== "addMembers")
|
|
46
46
|
return {
|
|
47
47
|
status: "success",
|
|
48
48
|
outputMessage: "Use @mention usernames for the members you want to add."
|
|
49
49
|
};
|
|
50
|
-
const a =
|
|
50
|
+
const a = e.agentExecutionContext.sharedState.createdGroupId?.value;
|
|
51
51
|
if (!a)
|
|
52
52
|
return {
|
|
53
53
|
status: "success",
|
|
54
54
|
outputMessage: "Create a group first, then add members using @mention usernames."
|
|
55
55
|
};
|
|
56
|
-
const n =
|
|
56
|
+
const n = e.intentParams.memberInfo.memberIdentifiers.map((m) => m.trim()).filter(Boolean);
|
|
57
57
|
if (!n.length)
|
|
58
58
|
return {
|
|
59
59
|
status: "success",
|
|
@@ -61,14 +61,14 @@ Not added members:
|
|
|
61
61
|
};
|
|
62
62
|
const r = `The following member(s) will be added to the newly created group:
|
|
63
63
|
|
|
64
|
-
${n.map((
|
|
64
|
+
${n.map((m) => `- **@${m}**`).join(`
|
|
65
65
|
`)}
|
|
66
66
|
|
|
67
|
-
Do you want to continue?`, { hitlResponse:
|
|
68
|
-
if (
|
|
69
|
-
const
|
|
70
|
-
agentId:
|
|
71
|
-
id:
|
|
67
|
+
Do you want to continue?`, { hitlResponse: i } = t?.configurable ?? {};
|
|
68
|
+
if (i?.agentId !== te || i.id !== ae) {
|
|
69
|
+
const m = {
|
|
70
|
+
agentId: te,
|
|
71
|
+
id: ae,
|
|
72
72
|
kind: "booleanChoice",
|
|
73
73
|
message: r,
|
|
74
74
|
metadata: {
|
|
@@ -77,45 +77,45 @@ Do you want to continue?`, { hitlResponse: c } = e?.configurable ?? {};
|
|
|
77
77
|
members: [...n]
|
|
78
78
|
}
|
|
79
79
|
};
|
|
80
|
-
throw new
|
|
80
|
+
throw new ve(m);
|
|
81
81
|
}
|
|
82
|
-
if (
|
|
82
|
+
if (i.payload !== !0)
|
|
83
83
|
return {
|
|
84
84
|
status: "success",
|
|
85
85
|
outputMessage: "Okay, I cancelled adding members to the group."
|
|
86
86
|
};
|
|
87
|
-
await
|
|
88
|
-
{ text: `Adding members ${
|
|
89
|
-
|
|
87
|
+
await g(
|
|
88
|
+
{ text: `Adding members ${ot(n)}...`, agentName: "group-creation" },
|
|
89
|
+
t
|
|
90
90
|
);
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
const { result:
|
|
94
|
-
if (
|
|
91
|
+
const c = t?.configurable?.context;
|
|
92
|
+
x(c);
|
|
93
|
+
const { result: u, error: d } = await Ke(c.portal, a, n);
|
|
94
|
+
if (d || !u)
|
|
95
95
|
return {
|
|
96
96
|
status: "success",
|
|
97
97
|
outputMessage: "I could not add members to that group. Please confirm group access and user accounts, then try again."
|
|
98
98
|
};
|
|
99
|
-
const { addedUsernames:
|
|
99
|
+
const { addedUsernames: l, notAddedUsers: p } = u;
|
|
100
100
|
try {
|
|
101
101
|
const f = (await b({
|
|
102
|
-
promptText:
|
|
103
|
-
schema:
|
|
102
|
+
promptText: nt,
|
|
103
|
+
schema: rt,
|
|
104
104
|
modelTier: "fast",
|
|
105
105
|
inputVariables: {
|
|
106
|
-
addedMembers:
|
|
106
|
+
addedMembers: l.join(", "),
|
|
107
107
|
notAddedMembers: JSON.stringify(
|
|
108
|
-
|
|
108
|
+
p.map((y) => ({ username: y.username, reason: y.error.message }))
|
|
109
109
|
)
|
|
110
110
|
}
|
|
111
111
|
})).successMessage;
|
|
112
112
|
if (f)
|
|
113
113
|
return { status: "success", outputMessage: f };
|
|
114
|
-
} catch (
|
|
115
|
-
console.error("Error generating add-members success message:",
|
|
114
|
+
} catch (m) {
|
|
115
|
+
console.error("Error generating add-members success message:", m);
|
|
116
116
|
}
|
|
117
117
|
return {};
|
|
118
|
-
},
|
|
118
|
+
}, it = `
|
|
119
119
|
Write a concise, friendly success message after creating a portal group.
|
|
120
120
|
|
|
121
121
|
Rules:
|
|
@@ -126,7 +126,7 @@ Rules:
|
|
|
126
126
|
|
|
127
127
|
Group title:
|
|
128
128
|
{groupTitle}
|
|
129
|
-
`,
|
|
129
|
+
`, ct = `
|
|
130
130
|
Write a concise, friendly failure message after an attempt to create a portal group.
|
|
131
131
|
|
|
132
132
|
Rules:
|
|
@@ -141,27 +141,27 @@ Group title:
|
|
|
141
141
|
|
|
142
142
|
Failure reason:
|
|
143
143
|
{failureReason}
|
|
144
|
-
`,
|
|
144
|
+
`, ne = "portal-group-creation", oe = "approveCreateGroup", ut = s.object({
|
|
145
145
|
successMessage: s.string().default("")
|
|
146
|
-
}),
|
|
146
|
+
}), lt = s.object({
|
|
147
147
|
failureMessage: s.string().default("")
|
|
148
|
-
}),
|
|
149
|
-
if (
|
|
148
|
+
}), dt = async (e, t) => {
|
|
149
|
+
if (e.intentParams.intent !== "create")
|
|
150
150
|
return {
|
|
151
151
|
status: "success",
|
|
152
152
|
outputMessage: "Tell me the group title you want to use."
|
|
153
153
|
};
|
|
154
|
-
const a =
|
|
154
|
+
const a = e.intentParams.title.trim();
|
|
155
155
|
if (!a)
|
|
156
156
|
return {
|
|
157
157
|
status: "success",
|
|
158
158
|
outputMessage: "What title would you like for the new group?"
|
|
159
159
|
};
|
|
160
|
-
const n = `A group with the title **${a}** will be created. Do you want to continue?`, { hitlResponse: o } =
|
|
161
|
-
if (o?.agentId !==
|
|
162
|
-
const
|
|
163
|
-
agentId:
|
|
164
|
-
id:
|
|
160
|
+
const n = `A group with the title **${a}** will be created. Do you want to continue?`, { hitlResponse: o } = t?.configurable;
|
|
161
|
+
if (o?.agentId !== ne || o.id !== oe) {
|
|
162
|
+
const d = {
|
|
163
|
+
agentId: ne,
|
|
164
|
+
id: oe,
|
|
165
165
|
kind: "booleanChoice",
|
|
166
166
|
message: n,
|
|
167
167
|
metadata: {
|
|
@@ -170,69 +170,69 @@ Failure reason:
|
|
|
170
170
|
access: "private"
|
|
171
171
|
}
|
|
172
172
|
};
|
|
173
|
-
throw new
|
|
173
|
+
throw new ve(d);
|
|
174
174
|
}
|
|
175
175
|
if (o.payload !== !0)
|
|
176
176
|
return {
|
|
177
177
|
status: "success",
|
|
178
178
|
outputMessage: `Okay, I cancelled creating **${a}**.`
|
|
179
179
|
};
|
|
180
|
-
await
|
|
181
|
-
const r =
|
|
182
|
-
|
|
183
|
-
const { result:
|
|
180
|
+
await g({ text: `Creating group "${a}"...`, agentName: "group-creation" }, t);
|
|
181
|
+
const r = t?.configurable?.context;
|
|
182
|
+
x(r);
|
|
183
|
+
const { result: i, error: c } = await Qe(r.portal, {
|
|
184
184
|
title: a,
|
|
185
185
|
access: "private"
|
|
186
186
|
});
|
|
187
|
-
if (
|
|
188
|
-
const
|
|
187
|
+
if (c || !i) {
|
|
188
|
+
const d = c?.message?.trim() || "No additional details were provided.";
|
|
189
189
|
try {
|
|
190
|
-
const
|
|
191
|
-
promptText:
|
|
192
|
-
schema:
|
|
190
|
+
const p = (await b({
|
|
191
|
+
promptText: ct,
|
|
192
|
+
schema: lt,
|
|
193
193
|
modelTier: "fast",
|
|
194
194
|
inputVariables: {
|
|
195
195
|
groupTitle: a,
|
|
196
|
-
failureReason:
|
|
196
|
+
failureReason: d
|
|
197
197
|
}
|
|
198
198
|
})).failureMessage.trim();
|
|
199
|
-
if (
|
|
199
|
+
if (p)
|
|
200
200
|
return {
|
|
201
201
|
status: "success",
|
|
202
|
-
outputMessage:
|
|
202
|
+
outputMessage: p
|
|
203
203
|
};
|
|
204
|
-
} catch (
|
|
205
|
-
console.error("Error generating create-group failure message:",
|
|
204
|
+
} catch (l) {
|
|
205
|
+
console.error("Error generating create-group failure message:", l);
|
|
206
206
|
}
|
|
207
207
|
return {
|
|
208
208
|
status: "success",
|
|
209
209
|
outputMessage: "I could not create that group. Please confirm your permissions and try again with the group title."
|
|
210
210
|
};
|
|
211
211
|
}
|
|
212
|
-
const
|
|
212
|
+
const u = i.id;
|
|
213
213
|
try {
|
|
214
|
-
const
|
|
215
|
-
promptText:
|
|
216
|
-
schema:
|
|
214
|
+
const l = (await b({
|
|
215
|
+
promptText: it,
|
|
216
|
+
schema: ut,
|
|
217
217
|
modelTier: "fast",
|
|
218
218
|
inputVariables: {
|
|
219
219
|
groupTitle: a
|
|
220
220
|
}
|
|
221
221
|
})).successMessage.trim();
|
|
222
|
-
if (
|
|
222
|
+
if (l)
|
|
223
223
|
return {
|
|
224
224
|
status: "success",
|
|
225
|
-
outputMessage:
|
|
226
|
-
sharedStatePatch: { createdGroupId: { value:
|
|
227
|
-
createdGroupId:
|
|
225
|
+
outputMessage: l,
|
|
226
|
+
sharedStatePatch: { createdGroupId: { value: u } },
|
|
227
|
+
createdGroupId: u
|
|
228
228
|
};
|
|
229
|
-
} catch (
|
|
230
|
-
console.error("Error generating create-group success message:",
|
|
229
|
+
} catch (d) {
|
|
230
|
+
console.error("Error generating create-group success message:", d);
|
|
231
231
|
}
|
|
232
232
|
return {};
|
|
233
|
-
}, I = (
|
|
234
|
-
for (let
|
|
235
|
-
const a = t
|
|
233
|
+
}, I = (e) => {
|
|
234
|
+
for (let t = e.length - 1; t >= 0; t -= 1) {
|
|
235
|
+
const a = e[t];
|
|
236
236
|
if (a.type !== "human")
|
|
237
237
|
continue;
|
|
238
238
|
const n = a.content;
|
|
@@ -244,7 +244,7 @@ Failure reason:
|
|
|
244
244
|
).join(" ").trim();
|
|
245
245
|
}
|
|
246
246
|
return "";
|
|
247
|
-
},
|
|
247
|
+
}, pt = `
|
|
248
248
|
You classify whether a user is asking to create a new ArcGIS Portal group or add members to an existing group.
|
|
249
249
|
|
|
250
250
|
Rules:
|
|
@@ -270,96 +270,106 @@ Examples:
|
|
|
270
270
|
|
|
271
271
|
User message:
|
|
272
272
|
{userMessage}
|
|
273
|
-
`,
|
|
273
|
+
`, mt = s.object({
|
|
274
274
|
intent: s.enum(["clarify", "create", "addMembers"]).default("clarify"),
|
|
275
275
|
title: s.string().default(""),
|
|
276
276
|
memberIdentifiers: s.array(s.string()).default([]),
|
|
277
277
|
clarifyMessage: s.string().default("")
|
|
278
|
-
}),
|
|
279
|
-
await
|
|
280
|
-
const a = I(
|
|
281
|
-
promptText:
|
|
282
|
-
schema:
|
|
278
|
+
}), gt = async (e, t) => {
|
|
279
|
+
await g({ text: "Thinking about groups...", agentName: "group-creation" }, t);
|
|
280
|
+
const a = I(e.agentExecutionContext.messages).trim(), n = await b({
|
|
281
|
+
promptText: pt,
|
|
282
|
+
schema: mt,
|
|
283
283
|
modelTier: "default",
|
|
284
284
|
inputVariables: { userMessage: a }
|
|
285
|
-
}), o = n.title.trim(), r = n.memberIdentifiers.filter(Boolean),
|
|
285
|
+
}), o = n.title.trim(), r = n.memberIdentifiers.filter(Boolean), i = n.clarifyMessage.trim(), c = n.intent === "create" && !!o, u = n.intent === "addMembers" && r.length > 0;
|
|
286
286
|
return {
|
|
287
|
-
intentParams:
|
|
287
|
+
intentParams: c ? { intent: "create", title: o } : u ? { intent: "addMembers", memberInfo: { memberIdentifiers: r } } : { intent: "clarify" },
|
|
288
288
|
status: "success",
|
|
289
|
-
outputMessage: !
|
|
289
|
+
outputMessage: !c && !u ? i : ""
|
|
290
290
|
};
|
|
291
|
-
},
|
|
292
|
-
"
|
|
293
|
-
"
|
|
294
|
-
"
|
|
295
|
-
"
|
|
296
|
-
"
|
|
297
|
-
"
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
291
|
+
}, ht = [
|
|
292
|
+
"general",
|
|
293
|
+
"about",
|
|
294
|
+
"homePage",
|
|
295
|
+
"gallery",
|
|
296
|
+
"aiAssistants",
|
|
297
|
+
"map",
|
|
298
|
+
"items",
|
|
299
|
+
"groups",
|
|
300
|
+
"webhooks",
|
|
301
|
+
"utilityServices",
|
|
302
|
+
"agol",
|
|
303
|
+
"esriContent",
|
|
304
|
+
"livingAtlas",
|
|
305
|
+
"servers",
|
|
306
|
+
"memberRoles",
|
|
307
|
+
"newMemberDefaults",
|
|
308
|
+
"marketplace",
|
|
309
|
+
"collaborations",
|
|
310
|
+
"credits",
|
|
311
|
+
"security",
|
|
312
|
+
"openData",
|
|
313
|
+
"hub",
|
|
314
|
+
"orgExtensions"
|
|
315
|
+
], ft = ["newItem", "createLayer", "developerCredentials"], yt = ["favorites", "group", "living-atlas", "org"], wt = ["featured", "my", "organization"], vt = ["licenses", "members", "overview", "reports", "settings", "status"], bt = s.object({
|
|
306
316
|
destinationType: s.literal("portal-content"),
|
|
307
|
-
hash: s.enum(
|
|
317
|
+
hash: s.enum(yt).optional(),
|
|
308
318
|
queryParams: s.object({
|
|
309
|
-
newItem: s.enum(
|
|
319
|
+
newItem: s.enum(ft).optional()
|
|
310
320
|
}).optional()
|
|
311
|
-
}),
|
|
321
|
+
}), It = s.object({
|
|
312
322
|
destinationType: s.literal("portal-groups"),
|
|
313
|
-
hash: s.enum(
|
|
314
|
-
}),
|
|
323
|
+
hash: s.enum(wt).optional()
|
|
324
|
+
}), St = s.object({
|
|
315
325
|
destinationType: s.literal("portal-org"),
|
|
316
|
-
hash: s.enum(
|
|
326
|
+
hash: s.enum(vt).optional(),
|
|
317
327
|
queryParams: s.object({
|
|
318
|
-
tab: s.
|
|
319
|
-
section: s.
|
|
320
|
-
subsection: s.
|
|
328
|
+
tab: s.enum(ht).optional(),
|
|
329
|
+
section: s.string().optional(),
|
|
330
|
+
subsection: s.string().optional(),
|
|
321
331
|
period: s.string().optional(),
|
|
322
332
|
startTime: s.string().optional(),
|
|
323
333
|
endTime: s.string().optional()
|
|
324
334
|
}).optional()
|
|
325
|
-
}),
|
|
335
|
+
}), xt = s.object({
|
|
326
336
|
destinationType: s.literal("portal-item"),
|
|
327
337
|
itemId: s.string().trim().min(1)
|
|
328
|
-
}),
|
|
338
|
+
}), Tt = s.object({
|
|
329
339
|
destinationType: s.literal("portal-group"),
|
|
330
340
|
groupId: s.string().trim().min(1)
|
|
331
|
-
}),
|
|
341
|
+
}), Mt = s.object({
|
|
332
342
|
destinationType: s.union([
|
|
333
343
|
s.literal("portal-gallery"),
|
|
334
344
|
s.literal("portal-map-viewer"),
|
|
335
345
|
s.literal("portal-notebooks"),
|
|
336
346
|
s.literal("portal-scene-viewer")
|
|
337
347
|
])
|
|
338
|
-
}),
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
]),
|
|
346
|
-
const a =
|
|
347
|
-
!
|
|
348
|
-
},
|
|
349
|
-
const a =
|
|
350
|
-
return a ? (await
|
|
351
|
-
},
|
|
352
|
-
...
|
|
348
|
+
}), Ct = s.union([
|
|
349
|
+
bt,
|
|
350
|
+
It,
|
|
351
|
+
St,
|
|
352
|
+
xt,
|
|
353
|
+
Tt,
|
|
354
|
+
Mt
|
|
355
|
+
]), Se = "portal-navigation", F = async (e, t) => {
|
|
356
|
+
const a = t?.configurable?.context;
|
|
357
|
+
!Ie(a) || !a.navigationTargetMap?.[e.destinationType] || await J({ type: Se, data: { ...e } }, t);
|
|
358
|
+
}, At = async (e, t) => {
|
|
359
|
+
const a = e.createdGroupId ?? e.agentExecutionContext.sharedState.createdGroupId?.value;
|
|
360
|
+
return a ? (await g({ text: "Preparing navigation...", agentName: "group-creation" }, t), await F({ destinationType: "portal-group", groupId: a }, t), {}) : {};
|
|
361
|
+
}, re = (e, t) => t ?? e, xe = h.Root({
|
|
362
|
+
...P(),
|
|
353
363
|
// * Shared state between nodes (but not persisted to the agent execution context)
|
|
354
364
|
/** Parameters related to the user's intent for group creation actions */
|
|
355
|
-
intentParams: h({ reducer:
|
|
365
|
+
intentParams: h({ reducer: re, default: () => ({ intent: "clarify" }) }),
|
|
356
366
|
/** The ID of the group that was created
|
|
357
367
|
* even though we already have this in the shared state
|
|
358
368
|
* we still need it here to also share between nodes
|
|
359
369
|
*/
|
|
360
|
-
createdGroupId: h({ reducer:
|
|
361
|
-
}),
|
|
362
|
-
switch (
|
|
370
|
+
createdGroupId: h({ reducer: re, default: () => "" })
|
|
371
|
+
}), Nt = () => new N(xe).addNode("detectGroupCreationIntent", gt).addNode("createPortalGroup", dt).addNode("addMembersToPortalGroup", st).addNode("suggestCreatedGroupNavigation", At).addEdge(G, "detectGroupCreationIntent").addConditionalEdges("detectGroupCreationIntent", (t) => {
|
|
372
|
+
switch (t.intentParams.intent) {
|
|
363
373
|
case "create":
|
|
364
374
|
return "createPortalGroup";
|
|
365
375
|
case "addMembers":
|
|
@@ -367,108 +377,110 @@ User message:
|
|
|
367
377
|
default:
|
|
368
378
|
return w;
|
|
369
379
|
}
|
|
370
|
-
}).addEdge("createPortalGroup", "suggestCreatedGroupNavigation").addEdge("addMembersToPortalGroup", "suggestCreatedGroupNavigation").addEdge("suggestCreatedGroupNavigation", w),
|
|
380
|
+
}).addEdge("createPortalGroup", "suggestCreatedGroupNavigation").addEdge("addMembersToPortalGroup", "suggestCreatedGroupNavigation").addEdge("suggestCreatedGroupNavigation", w), Gt = String.raw`- **portal-group-creation** - Portal group creation assistant:
|
|
371
381
|
- creates a new ArcGIS Portal group for the signed-in user
|
|
372
382
|
- adds users to the newly created group using @mention usernames
|
|
373
|
-
`,
|
|
383
|
+
`, Pt = {
|
|
374
384
|
id: "portal-group-creation",
|
|
375
385
|
name: "Portal Group Creation",
|
|
376
|
-
description:
|
|
377
|
-
createGraph:
|
|
378
|
-
workspace:
|
|
379
|
-
},
|
|
380
|
-
const
|
|
381
|
-
if (!
|
|
382
|
-
return
|
|
383
|
-
const a =
|
|
386
|
+
description: Gt,
|
|
387
|
+
createGraph: Nt,
|
|
388
|
+
workspace: xe
|
|
389
|
+
}, Te = "portalDocAssistantMemory", qt = () => ({ conversationId: "" }), Et = (e) => {
|
|
390
|
+
const t = e?.[Te]?.value;
|
|
391
|
+
if (!t || typeof t != "object")
|
|
392
|
+
return qt();
|
|
393
|
+
const a = t;
|
|
384
394
|
return {
|
|
385
395
|
conversationId: typeof a.conversationId == "string" ? a.conversationId : ""
|
|
386
396
|
};
|
|
387
|
-
},
|
|
388
|
-
[
|
|
389
|
-
}),
|
|
397
|
+
}, kt = (e) => ({
|
|
398
|
+
[Te]: { value: e }
|
|
399
|
+
}), zt = {
|
|
390
400
|
pipeline: {
|
|
391
401
|
follow_up: { allow: !1 }
|
|
392
402
|
}
|
|
393
403
|
};
|
|
394
|
-
function
|
|
404
|
+
function $t(e) {
|
|
395
405
|
return {
|
|
396
406
|
kind: "DocAIAssistantRequest",
|
|
397
407
|
filters: {
|
|
398
|
-
...
|
|
399
|
-
persona: { persona:
|
|
408
|
+
...zt,
|
|
409
|
+
persona: { persona: e }
|
|
400
410
|
}
|
|
401
411
|
};
|
|
402
412
|
}
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
413
|
+
const Dt = "https://www.arcgis.com/sharing/rest";
|
|
414
|
+
async function Rt({
|
|
415
|
+
portal: e,
|
|
416
|
+
question: t,
|
|
406
417
|
persona: a,
|
|
407
418
|
previousConversationId: n,
|
|
408
|
-
|
|
409
|
-
|
|
419
|
+
useProdDocAssistant: o,
|
|
420
|
+
signal: r,
|
|
421
|
+
skillId: i
|
|
410
422
|
}) {
|
|
411
|
-
|
|
412
|
-
const c =
|
|
413
|
-
portal:
|
|
414
|
-
skillId:
|
|
415
|
-
message:
|
|
416
|
-
options: { context: c, previousConversationId: n,
|
|
423
|
+
i ??= "doc_ai_assistant";
|
|
424
|
+
const c = $t(a), u = await Ut({
|
|
425
|
+
portal: e,
|
|
426
|
+
skillId: i,
|
|
427
|
+
message: t,
|
|
428
|
+
options: { context: c, previousConversationId: n, useProdDocAssistant: o, signal: r }
|
|
417
429
|
});
|
|
418
430
|
return {
|
|
419
|
-
reply:
|
|
420
|
-
conversationId:
|
|
431
|
+
reply: Ft(u, i),
|
|
432
|
+
conversationId: u[0]?.conversationId ?? ""
|
|
421
433
|
};
|
|
422
434
|
}
|
|
423
|
-
async function
|
|
424
|
-
portal:
|
|
425
|
-
skillId:
|
|
435
|
+
async function Ut({
|
|
436
|
+
portal: e,
|
|
437
|
+
skillId: t,
|
|
426
438
|
message: a,
|
|
427
439
|
options: n
|
|
428
440
|
}) {
|
|
429
|
-
const
|
|
441
|
+
const o = e.helperServices.aiAssistantServices.url, i = `${n.useProdDocAssistant ? "https://aiservices-beta.arcgis.com" : o}/skills/${t}/chat`, u = {
|
|
430
442
|
"Content-Type": "application/json",
|
|
431
|
-
token:
|
|
432
|
-
},
|
|
443
|
+
token: n.useProdDocAssistant ? (await Z.getCredential(Dt, { oAuthPopupConfirmation: !1 })).token : Z.findCredential(e.url)?.token ?? ""
|
|
444
|
+
}, d = await ee(i, {
|
|
433
445
|
method: "post",
|
|
434
446
|
body: JSON.stringify({
|
|
435
447
|
message: a,
|
|
436
448
|
context: n.context,
|
|
437
449
|
conversationId: n.previousConversationId
|
|
438
450
|
}),
|
|
439
|
-
headers:
|
|
451
|
+
headers: u,
|
|
440
452
|
signal: n.signal
|
|
441
453
|
});
|
|
442
|
-
if (
|
|
443
|
-
throw new Error(`Doc assistant chat failed (${
|
|
444
|
-
cause:
|
|
454
|
+
if (d.httpStatus !== 200)
|
|
455
|
+
throw new Error(`Doc assistant chat failed (${d.httpStatus})`, {
|
|
456
|
+
cause: d.data
|
|
445
457
|
});
|
|
446
|
-
const l =
|
|
447
|
-
if (!
|
|
458
|
+
const l = d.data, p = [l], { conversationId: m, inquiryId: f } = l, y = async (M, q) => {
|
|
459
|
+
if (!q)
|
|
448
460
|
return;
|
|
449
|
-
await
|
|
450
|
-
const
|
|
461
|
+
await Je(500);
|
|
462
|
+
const T = await ee(i, {
|
|
451
463
|
method: "post",
|
|
452
|
-
body: JSON.stringify({ conversationId:
|
|
453
|
-
headers:
|
|
464
|
+
body: JSON.stringify({ conversationId: m, inquiryId: f, ackSequenceNumber: M }),
|
|
465
|
+
headers: u,
|
|
454
466
|
signal: n.signal
|
|
455
467
|
});
|
|
456
|
-
if (
|
|
457
|
-
throw new Error(`Doc assistant poll failed (${
|
|
458
|
-
cause:
|
|
468
|
+
if (T.httpStatus !== 200)
|
|
469
|
+
throw new Error(`Doc assistant poll failed (${T.httpStatus})`, {
|
|
470
|
+
cause: T.data
|
|
459
471
|
});
|
|
460
|
-
const C =
|
|
461
|
-
|
|
472
|
+
const C = T.data;
|
|
473
|
+
p.push(C), await y(C.sequenceNumber, C.hasMore);
|
|
462
474
|
};
|
|
463
|
-
return l.hasMore && await
|
|
475
|
+
return l.hasMore && await y(l.sequenceNumber, l.hasMore), p;
|
|
464
476
|
}
|
|
465
|
-
function
|
|
466
|
-
switch (
|
|
477
|
+
function Ft(e, t) {
|
|
478
|
+
switch (t) {
|
|
467
479
|
case "doc_chat":
|
|
468
|
-
return
|
|
480
|
+
return e.find((a) => a.message != null)?.message ?? "";
|
|
469
481
|
case "doc_ai_assistant":
|
|
470
|
-
for (let a =
|
|
471
|
-
const n =
|
|
482
|
+
for (let a = e.length - 1; a >= 0; a -= 1) {
|
|
483
|
+
const n = e[a];
|
|
472
484
|
if (n.context?.kind === "DocAIAssistantContext") {
|
|
473
485
|
const o = n.context.results?.[0]?.reply;
|
|
474
486
|
if (o)
|
|
@@ -477,42 +489,43 @@ function Oe(t, e) {
|
|
|
477
489
|
}
|
|
478
490
|
return "";
|
|
479
491
|
default:
|
|
480
|
-
return
|
|
492
|
+
return U(t);
|
|
481
493
|
}
|
|
482
494
|
}
|
|
483
|
-
const
|
|
484
|
-
await
|
|
485
|
-
const a = I(
|
|
495
|
+
const Ot = async (e, t) => {
|
|
496
|
+
await g({ text: "Asking documentation assistant...", agentName: "doc-assistant" }, t);
|
|
497
|
+
const a = I(e.agentExecutionContext.messages).trim();
|
|
486
498
|
if (!a)
|
|
487
499
|
return {
|
|
488
500
|
status: "success",
|
|
489
501
|
outputMessage: "Please share your question and I can help with ArcGIS and Portal documentation."
|
|
490
502
|
};
|
|
491
|
-
const n =
|
|
492
|
-
|
|
493
|
-
const o =
|
|
503
|
+
const n = t?.configurable?.context;
|
|
504
|
+
x(n);
|
|
505
|
+
const o = Et(e.agentExecutionContext.sharedState), { reply: r, conversationId: i } = await Rt({
|
|
494
506
|
portal: n.portal,
|
|
495
507
|
question: a,
|
|
496
508
|
previousConversationId: o.conversationId || void 0,
|
|
497
509
|
skillId: "doc_ai_assistant",
|
|
498
|
-
persona: "doc-online"
|
|
510
|
+
persona: "doc-online",
|
|
511
|
+
useProdDocAssistant: n.useProdDocAssistant
|
|
499
512
|
});
|
|
500
513
|
return {
|
|
501
514
|
status: "success",
|
|
502
515
|
outputMessage: r.trim() || "I could not retrieve a response from the documentation assistant.",
|
|
503
|
-
sharedStatePatch:
|
|
504
|
-
conversationId:
|
|
516
|
+
sharedStatePatch: kt({
|
|
517
|
+
conversationId: i || o.conversationId
|
|
505
518
|
})
|
|
506
519
|
};
|
|
507
|
-
},
|
|
508
|
-
async ({ groupTitle:
|
|
509
|
-
const a =
|
|
520
|
+
}, Me = be(
|
|
521
|
+
async ({ groupTitle: e }, t) => {
|
|
522
|
+
const a = e.trim();
|
|
510
523
|
if (!a)
|
|
511
524
|
return null;
|
|
512
|
-
const n =
|
|
513
|
-
|
|
525
|
+
const n = t?.configurable?.context;
|
|
526
|
+
x(n);
|
|
514
527
|
try {
|
|
515
|
-
return (await
|
|
528
|
+
return (await We(n.portal, { query: `title:${a}`, num: 1 }))?.results[0]?.id || null;
|
|
516
529
|
} catch (o) {
|
|
517
530
|
return console.error("Error searching for portal group by title:", o), null;
|
|
518
531
|
}
|
|
@@ -524,14 +537,14 @@ const Le = async (t, e) => {
|
|
|
524
537
|
groupTitle: s.string().describe("The portal group title to resolve to a group id.")
|
|
525
538
|
})
|
|
526
539
|
}
|
|
527
|
-
),
|
|
528
|
-
async ({ itemTitle:
|
|
529
|
-
const a =
|
|
540
|
+
), Ce = be(
|
|
541
|
+
async ({ itemTitle: e }, t) => {
|
|
542
|
+
const a = e.trim();
|
|
530
543
|
if (!a)
|
|
531
544
|
return null;
|
|
532
|
-
const n =
|
|
533
|
-
|
|
534
|
-
const { result: o, error: r } = await
|
|
545
|
+
const n = t?.configurable?.context;
|
|
546
|
+
x(n);
|
|
547
|
+
const { result: o, error: r } = await _e(n.portal, a, { num: 1 });
|
|
535
548
|
return r && console.error("Error searching for portal item by title:", r), o?.results[0]?.id || null;
|
|
536
549
|
},
|
|
537
550
|
{
|
|
@@ -542,34 +555,34 @@ const Le = async (t, e) => {
|
|
|
542
555
|
})
|
|
543
556
|
}
|
|
544
557
|
);
|
|
545
|
-
function
|
|
546
|
-
const a =
|
|
558
|
+
function A(e, t = "#") {
|
|
559
|
+
const a = e.match(new RegExp(`\\${t}"([^"]+)"`, "u"));
|
|
547
560
|
if (a?.[1])
|
|
548
561
|
return a[1].trim();
|
|
549
|
-
const n =
|
|
562
|
+
const n = e.match(new RegExp(`\\${t}([^\\s"']+)`, "u"));
|
|
550
563
|
return n?.[1] ? n[1].trim() : null;
|
|
551
564
|
}
|
|
552
|
-
function
|
|
553
|
-
const
|
|
554
|
-
const n = a, o =
|
|
565
|
+
function Lt(e) {
|
|
566
|
+
const t = Q(e).flatMap((a) => {
|
|
567
|
+
const n = a, o = e[a], r = [
|
|
555
568
|
n,
|
|
556
569
|
{
|
|
557
570
|
description: o.description,
|
|
558
571
|
hints: o.hints
|
|
559
572
|
}
|
|
560
|
-
],
|
|
561
|
-
const
|
|
562
|
-
return [`${n}-${
|
|
573
|
+
], i = o.sections ? Q(o.sections).map((c) => {
|
|
574
|
+
const u = o.sections?.[c];
|
|
575
|
+
return [`${n}-${c}`, u];
|
|
563
576
|
}) : [];
|
|
564
|
-
return [r, ...
|
|
577
|
+
return [r, ...i];
|
|
565
578
|
});
|
|
566
|
-
return Object.fromEntries(
|
|
579
|
+
return Object.fromEntries(t);
|
|
567
580
|
}
|
|
568
|
-
function
|
|
569
|
-
return Object.entries(
|
|
581
|
+
function jt(e) {
|
|
582
|
+
return Object.entries(e).map(([t, { description: a, hints: n }]) => ` - ${t}: ${a} (hints: ${n.join(", ")})`).join(`
|
|
570
583
|
`);
|
|
571
584
|
}
|
|
572
|
-
const
|
|
585
|
+
const Vt = {
|
|
573
586
|
// Example prompt: "Take me to my content"
|
|
574
587
|
"portal-content": {
|
|
575
588
|
description: "The main content page of the portal.",
|
|
@@ -703,13 +716,13 @@ const Be = {
|
|
|
703
716
|
}
|
|
704
717
|
}
|
|
705
718
|
}
|
|
706
|
-
},
|
|
719
|
+
}, Ae = Lt(Vt), Bt = Q(Ae), Kt = jt(Ae), Qt = `
|
|
707
720
|
You decide whether the assistant response should include a navigation action to ArcGIS Portal.
|
|
708
721
|
|
|
709
722
|
Given the user question and assistant response:
|
|
710
723
|
- Decide if a navigation action would help the user complete the task.
|
|
711
724
|
- If yes, choose one destinationType:
|
|
712
|
-
${
|
|
725
|
+
${Kt}
|
|
713
726
|
|
|
714
727
|
Rules:
|
|
715
728
|
- Only suggest navigation when you are highly confident the destination will help complete the user's task.
|
|
@@ -732,47 +745,47 @@ User question:
|
|
|
732
745
|
|
|
733
746
|
Assistant response:
|
|
734
747
|
{response}
|
|
735
|
-
`,
|
|
748
|
+
`, se = s.object({
|
|
736
749
|
shouldSuggestNavigation: s.boolean().default(!1),
|
|
737
|
-
destinationType: s.enum(["none", ...
|
|
750
|
+
destinationType: s.enum(["none", ...Bt]).default("none"),
|
|
738
751
|
itemId: s.string().default(""),
|
|
739
752
|
groupId: s.string().default(""),
|
|
740
753
|
confidence: s.number().min(0).max(1).default(0)
|
|
741
|
-
}),
|
|
742
|
-
await
|
|
743
|
-
const a =
|
|
754
|
+
}), Wt = async (e, t) => {
|
|
755
|
+
await g({ text: "Extracting navigation intent...", agentName: "doc-assistant" }, t);
|
|
756
|
+
const a = e.outputMessage.trim();
|
|
744
757
|
if (!a)
|
|
745
758
|
return {};
|
|
746
|
-
const n = I(
|
|
759
|
+
const n = I(e.agentExecutionContext.messages).trim(), o = await Y.fromTemplate(Qt).format({
|
|
747
760
|
question: n,
|
|
748
761
|
response: a
|
|
749
|
-
}),
|
|
750
|
-
if (!
|
|
762
|
+
}), i = (await _({ modelTier: "fast" })).withStructuredOutput(se), c = se.parse(await i.invoke(o));
|
|
763
|
+
if (!c.shouldSuggestNavigation || c.destinationType === "none")
|
|
751
764
|
return {};
|
|
752
|
-
if (
|
|
753
|
-
const
|
|
754
|
-
|
|
765
|
+
if (c.destinationType === "portal-item" && !c.itemId) {
|
|
766
|
+
const d = A(n, "#");
|
|
767
|
+
d && (c.itemId = await Ce.invoke({ itemTitle: d }, t) ?? "");
|
|
755
768
|
}
|
|
756
|
-
if (
|
|
757
|
-
const
|
|
758
|
-
|
|
769
|
+
if (c.destinationType === "portal-group" && !c.groupId) {
|
|
770
|
+
const d = A(n, "$") ?? A(n, "#");
|
|
771
|
+
d && (c.groupId = await Me.invoke({ groupTitle: d }, t) ?? "");
|
|
759
772
|
}
|
|
760
|
-
const
|
|
761
|
-
return
|
|
773
|
+
const u = Jt(c);
|
|
774
|
+
return u ? (await F(u, t), {}) : {};
|
|
762
775
|
};
|
|
763
|
-
function
|
|
764
|
-
destinationType:
|
|
765
|
-
itemId:
|
|
776
|
+
function Jt({
|
|
777
|
+
destinationType: e,
|
|
778
|
+
itemId: t,
|
|
766
779
|
groupId: a
|
|
767
780
|
}) {
|
|
768
|
-
switch (
|
|
781
|
+
switch (e) {
|
|
769
782
|
case "portal-content":
|
|
770
783
|
case "portal-gallery":
|
|
771
784
|
case "portal-groups":
|
|
772
785
|
case "portal-map-viewer":
|
|
773
786
|
case "portal-notebooks":
|
|
774
787
|
case "portal-scene-viewer":
|
|
775
|
-
return { destinationType:
|
|
788
|
+
return { destinationType: e };
|
|
776
789
|
case "portal-org-security":
|
|
777
790
|
return {
|
|
778
791
|
destinationType: "portal-org",
|
|
@@ -786,7 +799,7 @@ function _e({
|
|
|
786
799
|
case "portal-content-new-item-developer-credentials":
|
|
787
800
|
return {
|
|
788
801
|
queryParams: {
|
|
789
|
-
newItem:
|
|
802
|
+
newItem: _t[e]
|
|
790
803
|
},
|
|
791
804
|
destinationType: "portal-content"
|
|
792
805
|
};
|
|
@@ -794,82 +807,80 @@ function _e({
|
|
|
794
807
|
case "portal-content-group":
|
|
795
808
|
case "portal-content-living-atlas":
|
|
796
809
|
case "portal-content-organization":
|
|
797
|
-
return { destinationType: "portal-content", hash:
|
|
810
|
+
return { destinationType: "portal-content", hash: Yt[e] };
|
|
798
811
|
case "portal-groups-featured":
|
|
799
812
|
case "portal-groups-my":
|
|
800
813
|
case "portal-groups-organization":
|
|
801
|
-
return { destinationType: "portal-groups", hash:
|
|
814
|
+
return { destinationType: "portal-groups", hash: Ht[e] };
|
|
802
815
|
case "portal-org-security-custom-sign-in":
|
|
803
816
|
case "portal-org-security-logins":
|
|
804
817
|
case "portal-org-security-change-login-provider":
|
|
805
818
|
case "portal-org-security-multifactor-auth":
|
|
806
819
|
case "portal-org-security-multifactor-enforcement":
|
|
807
820
|
case "portal-org-security-multifactor-designated-admins":
|
|
808
|
-
const n = Ze[t];
|
|
809
821
|
return {
|
|
810
822
|
destinationType: "portal-org",
|
|
811
823
|
hash: "settings",
|
|
812
824
|
queryParams: {
|
|
813
825
|
tab: "security",
|
|
814
|
-
|
|
815
|
-
subsection: n
|
|
826
|
+
subsection: Xt[e]
|
|
816
827
|
}
|
|
817
828
|
};
|
|
818
829
|
case "portal-item":
|
|
819
|
-
return
|
|
830
|
+
return t ? { destinationType: e, itemId: t } : null;
|
|
820
831
|
case "portal-group":
|
|
821
|
-
return a ? { destinationType:
|
|
832
|
+
return a ? { destinationType: e, groupId: a } : null;
|
|
822
833
|
case "none":
|
|
823
834
|
return null;
|
|
824
835
|
default:
|
|
825
|
-
return
|
|
836
|
+
return U(e);
|
|
826
837
|
}
|
|
827
838
|
}
|
|
828
|
-
const
|
|
839
|
+
const _t = {
|
|
829
840
|
"portal-content-new-item": "newItem",
|
|
830
841
|
"portal-content-new-item-feature-layer": "createLayer",
|
|
831
842
|
"portal-content-new-item-developer-credentials": "developerCredentials"
|
|
832
|
-
},
|
|
843
|
+
}, Yt = {
|
|
833
844
|
"portal-content-favorites": "favorites",
|
|
834
845
|
"portal-content-group": "group",
|
|
835
846
|
"portal-content-living-atlas": "living-atlas",
|
|
836
847
|
"portal-content-organization": "org"
|
|
837
|
-
},
|
|
848
|
+
}, Ht = {
|
|
838
849
|
"portal-groups-featured": "featured",
|
|
839
850
|
"portal-groups-my": "my",
|
|
840
851
|
"portal-groups-organization": "organization"
|
|
841
|
-
},
|
|
852
|
+
}, Xt = {
|
|
842
853
|
"portal-org-security-custom-sign-in": "customSignInSection",
|
|
843
854
|
"portal-org-security-logins": "loginsSection",
|
|
844
855
|
"portal-org-security-change-login-provider": "changeLoginProviderSection",
|
|
845
856
|
"portal-org-security-multifactor-auth": "multiFactorAuthSection",
|
|
846
857
|
"portal-org-security-multifactor-enforcement": "multifactorEnforcementSection",
|
|
847
858
|
"portal-org-security-multifactor-designated-admins": "multifactorDesignatedAdminsSection"
|
|
848
|
-
},
|
|
849
|
-
...
|
|
850
|
-
}),
|
|
859
|
+
}, Ne = h.Root({
|
|
860
|
+
...P()
|
|
861
|
+
}), Zt = () => new N(Ne).addNode("answerDocQuestion", Ot).addNode("extractNavigationIntent", Wt).addEdge(G, "answerDocQuestion").addEdge("answerDocQuestion", "extractNavigationIntent").addEdge("extractNavigationIntent", w), ea = String.raw`- **portal-doc-assistant** - General ArcGIS documentation and Portal help assistant:
|
|
851
862
|
- answers general ArcGIS, Portal, Enterprise, and JavaScript SDK questions
|
|
852
863
|
- acts as a fallback when specialized agents are not applicable
|
|
853
|
-
`,
|
|
864
|
+
`, ta = {
|
|
854
865
|
id: "portal-doc-assistant",
|
|
855
866
|
name: "Portal Doc Assistant",
|
|
856
867
|
description: ea,
|
|
857
|
-
createGraph:
|
|
858
|
-
workspace:
|
|
859
|
-
},
|
|
860
|
-
const
|
|
861
|
-
return
|
|
862
|
-
},
|
|
868
|
+
createGraph: Zt,
|
|
869
|
+
workspace: Ne
|
|
870
|
+
}, aa = () => ({ latestGroupId: null, memory: {} }), O = (e) => {
|
|
871
|
+
const t = e?.agentExecutionContext.sharedState.portalGroupSummaryMemory?.value;
|
|
872
|
+
return t ? { latestGroupId: t.latestGroupId, memory: t.memory } : aa();
|
|
873
|
+
}, Ge = `
|
|
863
874
|
Shared markdown formatting rules:
|
|
864
875
|
- Use clear markdown headings (##) to separate sections.
|
|
865
876
|
- Use concise bullet points for lists of facts, counts, or signals.
|
|
866
877
|
- Emphasize key metrics with bold labels (for example: **Recent items:** 4).
|
|
867
878
|
- Keep wording direct and analytical; avoid filler language but make sure the language is friendly.
|
|
868
879
|
- Do not include raw internal IDs unless explicitly requested.
|
|
869
|
-
`,
|
|
880
|
+
`, na = `
|
|
870
881
|
You answer follow-up questions about ArcGIS group analytics.
|
|
871
882
|
|
|
872
|
-
${
|
|
883
|
+
${Ge}
|
|
873
884
|
|
|
874
885
|
Ground your answer in the provided group analytics summary and context.
|
|
875
886
|
If the answer is not available from the provided context, state that clearly and suggest what to check next.
|
|
@@ -891,14 +902,14 @@ Group full context:
|
|
|
891
902
|
|
|
892
903
|
Question:
|
|
893
904
|
{question}
|
|
894
|
-
`,
|
|
895
|
-
await
|
|
896
|
-
const a =
|
|
905
|
+
`, oa = async (e, t) => {
|
|
906
|
+
await g({ text: "Answering group follow-up...", agentName: "group-analytics" }, t);
|
|
907
|
+
const a = O(e), n = e.groupSummaryGroupId ?? a.latestGroupId, o = n ? a.memory[n] : void 0, r = e.groupSummaryQuestion || I(e.agentExecutionContext.messages);
|
|
897
908
|
return o ? {
|
|
898
909
|
status: "success",
|
|
899
910
|
outputMessage: (await b({
|
|
900
|
-
promptText:
|
|
901
|
-
schema:
|
|
911
|
+
promptText: na,
|
|
912
|
+
schema: ra,
|
|
902
913
|
modelTier: "default",
|
|
903
914
|
inputVariables: {
|
|
904
915
|
summary: o.summary,
|
|
@@ -910,10 +921,10 @@ Question:
|
|
|
910
921
|
status: "success",
|
|
911
922
|
outputMessage: "I do not have group analytics context yet. Ask me to analyze a group first with analyze group <group id>."
|
|
912
923
|
};
|
|
913
|
-
},
|
|
924
|
+
}, ra = s.object({
|
|
914
925
|
answer: s.string(),
|
|
915
926
|
isRelevant: s.boolean()
|
|
916
|
-
}),
|
|
927
|
+
}), sa = `
|
|
917
928
|
Classify the user's request for ArcGIS Portal group analytics.
|
|
918
929
|
|
|
919
930
|
Rules:
|
|
@@ -942,121 +953,121 @@ hasAnalyticsContext:
|
|
|
942
953
|
|
|
943
954
|
User message:
|
|
944
955
|
{userMessage}
|
|
945
|
-
`,
|
|
946
|
-
await
|
|
947
|
-
const a = I(
|
|
956
|
+
`, ia = async (e, t) => {
|
|
957
|
+
await g({ text: "Analyzing group-analytics intent...", agentName: "group-analytics" }, t);
|
|
958
|
+
const a = I(e.agentExecutionContext.messages), n = !!O(e).latestGroupId, o = await Y.fromTemplate(sa).format({
|
|
948
959
|
userMessage: a,
|
|
949
960
|
hasAnalyticsContext: String(n)
|
|
950
|
-
}),
|
|
951
|
-
let
|
|
952
|
-
if ((
|
|
953
|
-
const y =
|
|
954
|
-
y && (
|
|
961
|
+
}), i = (await _({ modelTier: "fast" })).withStructuredOutput(ie), c = ie.parse(await i.invoke(o));
|
|
962
|
+
let u = c.groupId;
|
|
963
|
+
if ((c.intent === "summarize" || c.intent === "navigation") && !u) {
|
|
964
|
+
const y = A(a, "$");
|
|
965
|
+
y && (u = await Me.invoke({ groupTitle: y }, t) ?? "");
|
|
955
966
|
}
|
|
956
|
-
const { intent:
|
|
967
|
+
const { intent: d, question: l } = c, p = d === "summarize" && !u, m = d === "followUp" && !(l ?? "").trim(), f = d === "clarify" || p || m;
|
|
957
968
|
return {
|
|
958
|
-
groupSummaryIntent: f ? "clarify" :
|
|
959
|
-
groupSummaryGroupId:
|
|
960
|
-
groupSummaryQuestion:
|
|
969
|
+
groupSummaryIntent: f ? "clarify" : d,
|
|
970
|
+
groupSummaryGroupId: u || null,
|
|
971
|
+
groupSummaryQuestion: l || "",
|
|
961
972
|
status: "success",
|
|
962
973
|
outputMessage: f ? "Please clarify with a group id or title" : ""
|
|
963
974
|
};
|
|
964
|
-
},
|
|
975
|
+
}, ie = s.object({
|
|
965
976
|
intent: s.enum(["summarize", "followUp", "navigation", "clarify"]),
|
|
966
977
|
groupId: s.string().default(""),
|
|
967
978
|
question: s.string().default("")
|
|
968
|
-
}),
|
|
969
|
-
const a =
|
|
970
|
-
return await
|
|
979
|
+
}), ca = async (e, t) => {
|
|
980
|
+
const a = O(e), n = e.groupSummaryGroupId ?? a.latestGroupId;
|
|
981
|
+
return await g({ text: "Preparing navigation...", agentName: "group-analytics" }, t), await F(
|
|
971
982
|
n ? { destinationType: "portal-group", groupId: n } : { destinationType: "portal-groups" },
|
|
972
|
-
|
|
983
|
+
t
|
|
973
984
|
), { status: "success" };
|
|
974
985
|
};
|
|
975
|
-
function
|
|
976
|
-
return
|
|
986
|
+
function Pe({ timestamp: e, now: t, windowMs: a }) {
|
|
987
|
+
return e ? t - e <= a : !1;
|
|
977
988
|
}
|
|
978
|
-
const
|
|
979
|
-
function
|
|
980
|
-
const
|
|
989
|
+
const ua = 720 * 60 * 60 * 1e3;
|
|
990
|
+
function la(e) {
|
|
991
|
+
const t = He(e);
|
|
981
992
|
return {
|
|
982
|
-
id:
|
|
983
|
-
title:
|
|
984
|
-
description:
|
|
985
|
-
snippet:
|
|
986
|
-
access:
|
|
987
|
-
owner:
|
|
988
|
-
tags:
|
|
989
|
-
created:
|
|
990
|
-
modified:
|
|
991
|
-
isInvitationOnly:
|
|
993
|
+
id: e.id ?? "",
|
|
994
|
+
title: e.title ?? "",
|
|
995
|
+
description: e.description ?? "",
|
|
996
|
+
snippet: e.snippet ?? "",
|
|
997
|
+
access: e.access ?? null,
|
|
998
|
+
owner: e.owner ?? "",
|
|
999
|
+
tags: e.tags ?? [],
|
|
1000
|
+
created: e.created?.getTime(),
|
|
1001
|
+
modified: e.modified?.getTime(),
|
|
1002
|
+
isInvitationOnly: e.isInvitationOnly,
|
|
992
1003
|
sourceSignals: {
|
|
993
|
-
capabilities:
|
|
994
|
-
membershipAccess:
|
|
995
|
-
isOpenData:
|
|
996
|
-
isDistributedCollaborationGroup:
|
|
997
|
-
orgId:
|
|
998
|
-
hiddenMembers:
|
|
999
|
-
isViewOnly:
|
|
1000
|
-
isReadOnly:
|
|
1001
|
-
leavingDisallowed:
|
|
1004
|
+
capabilities: tt(e),
|
|
1005
|
+
membershipAccess: et(e),
|
|
1006
|
+
isOpenData: Ze(e),
|
|
1007
|
+
isDistributedCollaborationGroup: Xe(e),
|
|
1008
|
+
orgId: t.orgId,
|
|
1009
|
+
hiddenMembers: t.hiddenMembers,
|
|
1010
|
+
isViewOnly: t.isViewOnly,
|
|
1011
|
+
isReadOnly: t.isReadOnly,
|
|
1012
|
+
leavingDisallowed: t.leavingDisallowed
|
|
1002
1013
|
}
|
|
1003
1014
|
};
|
|
1004
1015
|
}
|
|
1005
|
-
async function
|
|
1006
|
-
const
|
|
1016
|
+
async function da(e) {
|
|
1017
|
+
const t = { owner: e.owner ?? "", admins: [], users: [] };
|
|
1007
1018
|
try {
|
|
1008
|
-
return await
|
|
1019
|
+
return await e.fetchMembers();
|
|
1009
1020
|
} catch (a) {
|
|
1010
|
-
return console.warn("Unable to fetch group members for analytics context", a),
|
|
1021
|
+
return console.warn("Unable to fetch group members for analytics context", a), t;
|
|
1011
1022
|
}
|
|
1012
1023
|
}
|
|
1013
|
-
function
|
|
1014
|
-
return
|
|
1015
|
-
id:
|
|
1016
|
-
title:
|
|
1017
|
-
type:
|
|
1018
|
-
owner:
|
|
1019
|
-
created:
|
|
1020
|
-
modified:
|
|
1024
|
+
function pa(e) {
|
|
1025
|
+
return e.map((t) => ({
|
|
1026
|
+
id: t.id ?? "",
|
|
1027
|
+
title: t.title ?? "Untitled",
|
|
1028
|
+
type: t.type ?? "Unknown",
|
|
1029
|
+
owner: t.owner ?? "",
|
|
1030
|
+
created: t.created?.getTime(),
|
|
1031
|
+
modified: t.modified?.getTime()
|
|
1021
1032
|
}));
|
|
1022
1033
|
}
|
|
1023
|
-
function
|
|
1024
|
-
return
|
|
1025
|
-
(a) => a.modified ?
|
|
1034
|
+
function ma(e, t) {
|
|
1035
|
+
return e.filter(
|
|
1036
|
+
(a) => a.modified ? Pe({ timestamp: a.modified, now: t, windowMs: ua }) : !1
|
|
1026
1037
|
);
|
|
1027
1038
|
}
|
|
1028
|
-
function
|
|
1029
|
-
const
|
|
1030
|
-
for (const a of
|
|
1031
|
-
|
|
1032
|
-
return [...
|
|
1039
|
+
function ga(e) {
|
|
1040
|
+
const t = /* @__PURE__ */ new Map();
|
|
1041
|
+
for (const a of e)
|
|
1042
|
+
t.set(a.type, (t.get(a.type) ?? 0) + 1);
|
|
1043
|
+
return [...t.entries()].sort((a, n) => n[1] - a[1] || a[0].localeCompare(n[0])).slice(0, 6).map(([a, n]) => ({ type: a, count: n }));
|
|
1033
1044
|
}
|
|
1034
|
-
async function
|
|
1035
|
-
const
|
|
1045
|
+
async function ha(e) {
|
|
1046
|
+
const t = await e.queryItems({ num: 20, sortField: "modified", sortOrder: "desc" }), a = pa(t.results), n = Date.now();
|
|
1036
1047
|
return {
|
|
1037
|
-
total:
|
|
1048
|
+
total: t.total,
|
|
1038
1049
|
topItems: a,
|
|
1039
|
-
recentlyModifiedItems:
|
|
1040
|
-
topItemTypes:
|
|
1050
|
+
recentlyModifiedItems: ma(a, n),
|
|
1051
|
+
topItemTypes: ga(a)
|
|
1041
1052
|
};
|
|
1042
1053
|
}
|
|
1043
|
-
async function
|
|
1044
|
-
if (!
|
|
1054
|
+
async function fa(e, t) {
|
|
1055
|
+
if (!t)
|
|
1045
1056
|
return { error: { code: "missingGroupId", message: "Group id is required." } };
|
|
1046
1057
|
try {
|
|
1047
|
-
const n = (await
|
|
1058
|
+
const n = (await e.queryGroups({ query: `id:${t}`, num: 1 })).results[0];
|
|
1048
1059
|
if (!n)
|
|
1049
|
-
return { error: { code: "groupNotFound", message: `No group found for id: ${
|
|
1050
|
-
const o =
|
|
1051
|
-
return { result: { group: o, members: r, items:
|
|
1060
|
+
return { error: { code: "groupNotFound", message: `No group found for id: ${t}` } };
|
|
1061
|
+
const o = la(n), r = await da(n), i = await ha(n);
|
|
1062
|
+
return { result: { group: o, members: r, items: i } };
|
|
1052
1063
|
} catch (a) {
|
|
1053
1064
|
return console.error("Error fetching portal group analytics context:", a), { error: { code: "unhandledError" } };
|
|
1054
1065
|
}
|
|
1055
1066
|
}
|
|
1056
|
-
const
|
|
1067
|
+
const ya = `
|
|
1057
1068
|
You summarize ArcGIS Portal groups based on structured context and deterministic activity signals.
|
|
1058
1069
|
|
|
1059
|
-
${
|
|
1070
|
+
${Ge}
|
|
1060
1071
|
|
|
1061
1072
|
Output format requirements:
|
|
1062
1073
|
- Return concise markdown with clear sections in this order:
|
|
@@ -1092,82 +1103,82 @@ Group context:
|
|
|
1092
1103
|
|
|
1093
1104
|
Deterministic signals:
|
|
1094
1105
|
{deterministicSignals}
|
|
1095
|
-
`,
|
|
1096
|
-
const a =
|
|
1106
|
+
`, wa = 2160 * 60 * 60 * 1e3, va = async (e, t) => {
|
|
1107
|
+
const a = e.groupSummaryGroupId;
|
|
1097
1108
|
if (!a)
|
|
1098
1109
|
return {
|
|
1099
1110
|
status: "success",
|
|
1100
1111
|
outputMessage: 'Please clarify with analyze group <group id>, analyze group $<title>, or analyze group $"<title with spaces>".'
|
|
1101
1112
|
};
|
|
1102
|
-
await
|
|
1103
|
-
const n =
|
|
1104
|
-
|
|
1105
|
-
const { result: o, error: r } = await
|
|
1113
|
+
await g({ text: `Analyzing group ${a}...`, agentName: "group-analytics" }, t);
|
|
1114
|
+
const n = t?.configurable?.context;
|
|
1115
|
+
x(n);
|
|
1116
|
+
const { result: o, error: r } = await fa(n.portal, a);
|
|
1106
1117
|
if (r || !o)
|
|
1107
|
-
return await
|
|
1118
|
+
return await g({ text: "Failed to fetch group context", agentName: "group-analytics" }, t), {
|
|
1108
1119
|
status: "success",
|
|
1109
1120
|
outputMessage: "Unable to retrieve group context for analytics."
|
|
1110
1121
|
};
|
|
1111
|
-
const { group:
|
|
1112
|
-
promptText:
|
|
1113
|
-
schema:
|
|
1122
|
+
const { group: i, items: c } = o, u = Date.now(), d = i.modified, l = d ? Pe({ timestamp: d, now: u, windowMs: wa }) : !1, p = c.recentlyModifiedItems.length, m = p > 0, f = l || m, y = await b({
|
|
1123
|
+
promptText: ya,
|
|
1124
|
+
schema: ba,
|
|
1114
1125
|
modelTier: "default",
|
|
1115
1126
|
inputVariables: {
|
|
1116
1127
|
context: JSON.stringify(o),
|
|
1117
1128
|
deterministicSignals: JSON.stringify({
|
|
1118
1129
|
isGroupActive: f,
|
|
1119
|
-
isGroupRecentlyModified:
|
|
1120
|
-
hasRecentlyAddedOrUpdatedContent:
|
|
1121
|
-
recentItemCount:
|
|
1130
|
+
isGroupRecentlyModified: l,
|
|
1131
|
+
hasRecentlyAddedOrUpdatedContent: m,
|
|
1132
|
+
recentItemCount: p
|
|
1122
1133
|
})
|
|
1123
1134
|
}
|
|
1124
|
-
}), { followUpQuestions:
|
|
1135
|
+
}), { followUpQuestions: M, summary: q } = y, T = O(e), C = {
|
|
1125
1136
|
latestGroupId: a,
|
|
1126
1137
|
memory: {
|
|
1127
|
-
|
|
1128
|
-
[a]: { summary:
|
|
1138
|
+
...T.memory,
|
|
1139
|
+
[a]: { summary: q, followUpQuestions: M, fullContext: o }
|
|
1129
1140
|
}
|
|
1130
1141
|
};
|
|
1131
|
-
return
|
|
1142
|
+
return M.length && await J({ type: "suggested-prompts", data: { prompts: M } }, t), {
|
|
1132
1143
|
status: "success",
|
|
1133
|
-
outputMessage:
|
|
1134
|
-
sharedStatePatch: { portalGroupSummaryMemory: { value:
|
|
1144
|
+
outputMessage: q,
|
|
1145
|
+
sharedStatePatch: { portalGroupSummaryMemory: { value: C } }
|
|
1135
1146
|
};
|
|
1136
|
-
},
|
|
1147
|
+
}, ba = s.object({
|
|
1137
1148
|
summary: s.string(),
|
|
1138
1149
|
followUpQuestions: s.array(s.string()).default([])
|
|
1139
|
-
}),
|
|
1140
|
-
...
|
|
1150
|
+
}), L = (e, t) => t ?? e, qe = h.Root({
|
|
1151
|
+
...P(),
|
|
1141
1152
|
groupSummaryIntent: h({
|
|
1142
|
-
reducer:
|
|
1153
|
+
reducer: L,
|
|
1143
1154
|
default: () => "clarify"
|
|
1144
1155
|
}),
|
|
1145
1156
|
groupSummaryGroupId: h({
|
|
1146
|
-
reducer:
|
|
1157
|
+
reducer: L,
|
|
1147
1158
|
default: () => null
|
|
1148
1159
|
}),
|
|
1149
1160
|
groupSummaryQuestion: h({
|
|
1150
|
-
reducer:
|
|
1161
|
+
reducer: L,
|
|
1151
1162
|
default: () => ""
|
|
1152
1163
|
})
|
|
1153
|
-
}),
|
|
1164
|
+
}), Ia = () => new N(qe).addNode("detectGroupSummaryIntent", ia).addNode("summarizePortalGroup", va).addNode("answerGroupSummaryFollowUp", oa).addNode("suggestGroupSummaryNavigation", ca).addEdge(G, "detectGroupSummaryIntent").addConditionalEdges("detectGroupSummaryIntent", (t) => t.groupSummaryIntent === "summarize" ? "summarizePortalGroup" : t.groupSummaryIntent === "followUp" ? "answerGroupSummaryFollowUp" : t.groupSummaryIntent === "navigation" ? "suggestGroupSummaryNavigation" : w).addEdge("summarizePortalGroup", w).addEdge("answerGroupSummaryFollowUp", w).addEdge("suggestGroupSummaryNavigation", w), Sa = String.raw`- **portal-group-analytics** - Portal group analytics assistant:
|
|
1154
1165
|
- summarizes ArcGIS portal groups from group context and sourceJSON details
|
|
1155
1166
|
- answers follow-up questions grounded in the summarized group
|
|
1156
1167
|
- suggests navigation to groups when relevant
|
|
1157
|
-
`,
|
|
1168
|
+
`, xa = {
|
|
1158
1169
|
id: "portal-group-analytics",
|
|
1159
1170
|
name: "Portal Group Analytics",
|
|
1160
|
-
description:
|
|
1161
|
-
createGraph:
|
|
1162
|
-
workspace:
|
|
1163
|
-
},
|
|
1164
|
-
const
|
|
1165
|
-
return
|
|
1166
|
-
},
|
|
1171
|
+
description: Sa,
|
|
1172
|
+
createGraph: Ia,
|
|
1173
|
+
workspace: qe
|
|
1174
|
+
}, Ta = () => ({ latestItemId: null, memory: {} }), H = (e) => {
|
|
1175
|
+
const t = e?.agentExecutionContext.sharedState.portalItemAnalyticsSummaryMemory?.value;
|
|
1176
|
+
return t ? { latestItemId: t.latestItemId, memory: t.memory } : Ta();
|
|
1177
|
+
}, ce = s.object({
|
|
1167
1178
|
intent: s.enum(["summarize", "followUp", "clarify"]),
|
|
1168
1179
|
itemId: s.string().default(""),
|
|
1169
1180
|
question: s.string().default("")
|
|
1170
|
-
}), Ma = s.object({ summary: s.string(), followUpQuestions: s.array(s.string()).default([]) }),
|
|
1181
|
+
}), Ma = s.object({ summary: s.string(), followUpQuestions: s.array(s.string()).default([]) }), Ca = s.object({ answer: s.string(), isRelevant: s.boolean() }), Aa = `
|
|
1171
1182
|
You answer follow-up questions about an ArcGIS item.
|
|
1172
1183
|
|
|
1173
1184
|
Ground your answer in the provided item context.
|
|
@@ -1187,14 +1198,14 @@ Item full context
|
|
|
1187
1198
|
|
|
1188
1199
|
Question:
|
|
1189
1200
|
{question}
|
|
1190
|
-
`,
|
|
1191
|
-
await
|
|
1192
|
-
const a =
|
|
1201
|
+
`, Na = async (e, t) => {
|
|
1202
|
+
await g({ text: "Answering follow-up...", agentName: "analytics" }, t);
|
|
1203
|
+
const a = H(e), n = e.analyticsItemId ?? a.latestItemId, o = n ? a.memory[n] : void 0, r = e.analyticsQuestion || I(e.agentExecutionContext.messages);
|
|
1193
1204
|
return o ? {
|
|
1194
1205
|
status: "success",
|
|
1195
1206
|
outputMessage: (await b({
|
|
1196
|
-
promptText:
|
|
1197
|
-
schema:
|
|
1207
|
+
promptText: Aa,
|
|
1208
|
+
schema: Ca,
|
|
1198
1209
|
modelTier: "default",
|
|
1199
1210
|
inputVariables: {
|
|
1200
1211
|
summary: o.summary,
|
|
@@ -1206,7 +1217,7 @@ Question:
|
|
|
1206
1217
|
status: "success",
|
|
1207
1218
|
outputMessage: "I don't have enough information yet. Please ask me to summarize the item first using summarize item <item id>."
|
|
1208
1219
|
};
|
|
1209
|
-
},
|
|
1220
|
+
}, Ga = `
|
|
1210
1221
|
Classify the user analytics request.
|
|
1211
1222
|
|
|
1212
1223
|
Rules:
|
|
@@ -1236,27 +1247,27 @@ hasSummaryContext:
|
|
|
1236
1247
|
|
|
1237
1248
|
User message:
|
|
1238
1249
|
{userMessage}
|
|
1239
|
-
`,
|
|
1240
|
-
await
|
|
1241
|
-
const a = I(
|
|
1250
|
+
`, Pa = async (e, t) => {
|
|
1251
|
+
await g({ text: "Analyzing intent...", agentName: "analytics" }, t);
|
|
1252
|
+
const a = I(e.agentExecutionContext.messages), n = !!H(e).latestItemId, o = await Y.fromTemplate(Ga).format({
|
|
1242
1253
|
userMessage: a,
|
|
1243
1254
|
hasSummaryContext: String(n)
|
|
1244
|
-
}),
|
|
1245
|
-
let
|
|
1246
|
-
if (
|
|
1247
|
-
const y =
|
|
1248
|
-
y && (
|
|
1255
|
+
}), i = (await _({ modelTier: "fast" })).withStructuredOutput(ce), c = ce.parse(await i.invoke(o));
|
|
1256
|
+
let u = c.itemId;
|
|
1257
|
+
if (c.intent === "summarize" && !u) {
|
|
1258
|
+
const y = A(a, "#");
|
|
1259
|
+
y && (u = await Ce.invoke({ itemTitle: y }, t) ?? "");
|
|
1249
1260
|
}
|
|
1250
|
-
const { intent:
|
|
1261
|
+
const { intent: d, question: l } = c, f = d === "clarify" || d === "summarize" && !u || d === "followUp" && !l;
|
|
1251
1262
|
return {
|
|
1252
|
-
agentExecutionContext: { ...
|
|
1253
|
-
analyticsIntent: f ? "clarify" :
|
|
1254
|
-
analyticsItemId:
|
|
1255
|
-
analyticsQuestion:
|
|
1263
|
+
agentExecutionContext: { ...e.agentExecutionContext },
|
|
1264
|
+
analyticsIntent: f ? "clarify" : d,
|
|
1265
|
+
analyticsItemId: u || null,
|
|
1266
|
+
analyticsQuestion: l || "",
|
|
1256
1267
|
status: "success",
|
|
1257
1268
|
outputMessage: f ? 'Please clarify with summarize item <item id>, summarize item #<title>, or summarize item #"<title with spaces>".' : ""
|
|
1258
1269
|
};
|
|
1259
|
-
},
|
|
1270
|
+
}, qa = `
|
|
1260
1271
|
You are a item summary tool for ArcGIS. Your job is to summarize an item's info based on the provided context.
|
|
1261
1272
|
Summary rules:
|
|
1262
1273
|
- The summary should be concise markdown, make sure to format the output nicely so it's easy to read.
|
|
@@ -1271,66 +1282,66 @@ Do not include internal identifiers.
|
|
|
1271
1282
|
If the user asks for a detailed summary, you may expand the response up to 300 words.
|
|
1272
1283
|
Item context:
|
|
1273
1284
|
{context}
|
|
1274
|
-
`,
|
|
1275
|
-
const a =
|
|
1285
|
+
`, Ea = async (e, t) => {
|
|
1286
|
+
const a = e.analyticsItemId;
|
|
1276
1287
|
if (!a)
|
|
1277
1288
|
return {
|
|
1278
1289
|
status: "success",
|
|
1279
1290
|
outputMessage: 'Please clarify with summarize item <item id>, summarize item #<title>, or summarize item #"<title with spaces>".'
|
|
1280
1291
|
};
|
|
1281
|
-
await
|
|
1282
|
-
const n =
|
|
1283
|
-
|
|
1284
|
-
const { portal: o, user: r } = n, { result:
|
|
1285
|
-
if (
|
|
1286
|
-
return await
|
|
1292
|
+
await g({ text: `Summarizing item ${a}...`, agentName: "analytics" }, t);
|
|
1293
|
+
const n = t?.configurable?.context;
|
|
1294
|
+
x(n);
|
|
1295
|
+
const { portal: o, user: r } = n, { result: i, error: c } = await Ye(r, o, a);
|
|
1296
|
+
if (c || !i)
|
|
1297
|
+
return await g({ text: "Failed to get item context for summarization", agentName: "analytics" }, t), {
|
|
1287
1298
|
status: "success",
|
|
1288
1299
|
outputMessage: "Unable to retrieve item context for summarization."
|
|
1289
1300
|
};
|
|
1290
|
-
const { context:
|
|
1291
|
-
promptText:
|
|
1301
|
+
const { context: u } = i, d = await b({
|
|
1302
|
+
promptText: qa,
|
|
1292
1303
|
schema: Ma,
|
|
1293
1304
|
modelTier: "default",
|
|
1294
|
-
inputVariables: { context: JSON.stringify(
|
|
1295
|
-
}), { followUpQuestions:
|
|
1305
|
+
inputVariables: { context: JSON.stringify(u) }
|
|
1306
|
+
}), { followUpQuestions: l, summary: p } = d, m = H(e), f = {
|
|
1296
1307
|
latestItemId: a,
|
|
1297
1308
|
memory: {
|
|
1298
|
-
...
|
|
1299
|
-
[a]: { summary:
|
|
1309
|
+
...m.memory,
|
|
1310
|
+
[a]: { summary: p, followUpQuestions: l, fullContext: u }
|
|
1300
1311
|
}
|
|
1301
1312
|
};
|
|
1302
|
-
return
|
|
1313
|
+
return l.length && await J({ type: "suggested-prompts", data: { prompts: l } }, t), {
|
|
1303
1314
|
status: "success",
|
|
1304
|
-
outputMessage:
|
|
1315
|
+
outputMessage: p,
|
|
1305
1316
|
sharedStatePatch: { portalItemAnalyticsSummaryMemory: { value: f } }
|
|
1306
1317
|
};
|
|
1307
|
-
},
|
|
1308
|
-
...
|
|
1318
|
+
}, j = (e, t) => t ?? e, Ee = h.Root({
|
|
1319
|
+
...P(),
|
|
1309
1320
|
// States shared only across nodes in the graph, not between invocations
|
|
1310
1321
|
analyticsIntent: h({
|
|
1311
|
-
reducer:
|
|
1322
|
+
reducer: j,
|
|
1312
1323
|
default: () => "clarify"
|
|
1313
1324
|
}),
|
|
1314
1325
|
analyticsItemId: h({
|
|
1315
|
-
reducer:
|
|
1326
|
+
reducer: j,
|
|
1316
1327
|
default: () => null
|
|
1317
1328
|
}),
|
|
1318
1329
|
analyticsQuestion: h({
|
|
1319
|
-
reducer:
|
|
1330
|
+
reducer: j,
|
|
1320
1331
|
default: () => ""
|
|
1321
1332
|
})
|
|
1322
|
-
}), ka = () => new
|
|
1333
|
+
}), ka = () => new N(Ee).addNode("detectAnalyticsIntent", Pa).addNode("summarizePortalItem", Ea).addNode("answerAnalyticsFollowUp", Na).addEdge(G, "detectAnalyticsIntent").addConditionalEdges("detectAnalyticsIntent", (t) => t.analyticsIntent === "summarize" ? "summarizePortalItem" : t.analyticsIntent === "followUp" ? "answerAnalyticsFollowUp" : w).addEdge("summarizePortalItem", w).addEdge("answerAnalyticsFollowUp", w), za = String.raw`- **portal-item-analytics** - Portal item analytics assistant:
|
|
1323
1334
|
- answers questions about one specific ArcGIS portal item when item context is present
|
|
1324
1335
|
- summarizes item details, metadata, and context grounded in that item
|
|
1325
1336
|
- suggests follow-up prompts grounded in the same item
|
|
1326
1337
|
- use for item-specific requests, not for gallery browsing, featured content, or opening Map Viewer
|
|
1327
|
-
`,
|
|
1338
|
+
`, $a = {
|
|
1328
1339
|
id: "portal-item-analytics",
|
|
1329
1340
|
name: "Portal Item Analytics",
|
|
1330
|
-
description:
|
|
1341
|
+
description: za,
|
|
1331
1342
|
createGraph: ka,
|
|
1332
|
-
workspace:
|
|
1333
|
-
},
|
|
1343
|
+
workspace: Ee
|
|
1344
|
+
}, Da = {
|
|
1334
1345
|
schemaVersion: "1.0",
|
|
1335
1346
|
capabilities: [
|
|
1336
1347
|
{
|
|
@@ -1370,7 +1381,7 @@ Item context:
|
|
|
1370
1381
|
}
|
|
1371
1382
|
}
|
|
1372
1383
|
]
|
|
1373
|
-
},
|
|
1384
|
+
}, Ra = {
|
|
1374
1385
|
schemaVersion: "1.0",
|
|
1375
1386
|
capabilities: [
|
|
1376
1387
|
{
|
|
@@ -1424,7 +1435,7 @@ Item context:
|
|
|
1424
1435
|
}
|
|
1425
1436
|
}
|
|
1426
1437
|
]
|
|
1427
|
-
},
|
|
1438
|
+
}, Ua = {
|
|
1428
1439
|
schemaVersion: "1.0",
|
|
1429
1440
|
capabilities: [
|
|
1430
1441
|
{
|
|
@@ -1444,34 +1455,34 @@ Item context:
|
|
|
1444
1455
|
}
|
|
1445
1456
|
}
|
|
1446
1457
|
]
|
|
1447
|
-
},
|
|
1448
|
-
"contentRouteRegistry.ts":
|
|
1449
|
-
"groupsRouteRegistry.ts":
|
|
1450
|
-
"orgSettingsRouteRegistry.ts":
|
|
1458
|
+
}, Fa = {
|
|
1459
|
+
"contentRouteRegistry.ts": Da,
|
|
1460
|
+
"groupsRouteRegistry.ts": Ra,
|
|
1461
|
+
"orgSettingsRouteRegistry.ts": Ua
|
|
1451
1462
|
};
|
|
1452
|
-
function
|
|
1453
|
-
const
|
|
1454
|
-
for (const [n, o] of Object.entries(
|
|
1463
|
+
function ue(e) {
|
|
1464
|
+
const t = [], a = /* @__PURE__ */ new Set();
|
|
1465
|
+
for (const [n, o] of Object.entries(e))
|
|
1455
1466
|
for (const r of o.capabilities) {
|
|
1456
1467
|
if (a.has(r.id))
|
|
1457
1468
|
throw new Error(`${n}: duplicate capability id "${r.id}" across registries`);
|
|
1458
|
-
a.add(r.id),
|
|
1469
|
+
a.add(r.id), t.push(r);
|
|
1459
1470
|
}
|
|
1460
|
-
return
|
|
1471
|
+
return t;
|
|
1461
1472
|
}
|
|
1462
|
-
let
|
|
1463
|
-
function
|
|
1464
|
-
return
|
|
1473
|
+
let z;
|
|
1474
|
+
function S(e) {
|
|
1475
|
+
return e ? z = ue({ customCapabilities: e }) : z || (z = ue(Fa)), z;
|
|
1465
1476
|
}
|
|
1466
|
-
const
|
|
1467
|
-
function
|
|
1468
|
-
return
|
|
1477
|
+
const Oa = /^(?:take me to|navigate to|go to|show me|open)\s+(?:the\s+)?/u;
|
|
1478
|
+
function R(e) {
|
|
1479
|
+
return e.toLowerCase().replace(/[^a-z0-9]+/gu, " ").trim().replace(Oa, "").trim();
|
|
1469
1480
|
}
|
|
1470
|
-
const
|
|
1481
|
+
const La = s.object({
|
|
1471
1482
|
capabilityIds: s.array(s.string()).default([]),
|
|
1472
1483
|
confidence: s.number().min(0).max(1).default(0),
|
|
1473
1484
|
reason: s.string().default("")
|
|
1474
|
-
}),
|
|
1485
|
+
}), le = 0.8, ja = String.raw`You select Portal navigation capabilities for a user's request.
|
|
1475
1486
|
|
|
1476
1487
|
Select only capability IDs from the supplied candidates. Return an empty array when none fit.
|
|
1477
1488
|
A named surface is required: do not select a capability on another Portal surface.
|
|
@@ -1481,45 +1492,45 @@ User request:
|
|
|
1481
1492
|
{userRequest}
|
|
1482
1493
|
|
|
1483
1494
|
Candidates:
|
|
1484
|
-
{candidates}`,
|
|
1485
|
-
if (
|
|
1495
|
+
{candidates}`, Va = async (e, t) => {
|
|
1496
|
+
if (e.outputMessage || e.targets.length === 0)
|
|
1486
1497
|
return {};
|
|
1487
|
-
const a = I(
|
|
1498
|
+
const a = I(e.agentExecutionContext.messages).trim(), n = Ba(a, e);
|
|
1488
1499
|
if (n.length === 1)
|
|
1489
1500
|
return console.info("[arcgis-portal-ai-assistant] navigation capability selection:", {
|
|
1490
1501
|
method: "exact-match",
|
|
1491
1502
|
request: a,
|
|
1492
1503
|
selectedCapabilityIds: n
|
|
1493
1504
|
}), { chosenCapabilityIds: n };
|
|
1494
|
-
await
|
|
1505
|
+
await g({ text: "Choosing a navigation destination...", agentName: "navigation" }, t);
|
|
1495
1506
|
const o = JSON.stringify(
|
|
1496
|
-
|
|
1507
|
+
e.targets.map(({ capability: r, keywordScore: i, semanticScore: c }) => ({
|
|
1497
1508
|
id: r.id,
|
|
1498
1509
|
title: r.title,
|
|
1499
1510
|
description: r.description,
|
|
1500
1511
|
route: r.resolutions.navigate,
|
|
1501
|
-
keywordScore:
|
|
1502
|
-
semanticScore:
|
|
1512
|
+
keywordScore: i,
|
|
1513
|
+
semanticScore: c
|
|
1503
1514
|
}))
|
|
1504
1515
|
);
|
|
1505
1516
|
try {
|
|
1506
1517
|
const r = await b({
|
|
1507
|
-
promptText:
|
|
1508
|
-
schema:
|
|
1518
|
+
promptText: ja,
|
|
1519
|
+
schema: La,
|
|
1509
1520
|
modelTier: "fast",
|
|
1510
1521
|
inputVariables: { candidates: o, userRequest: a }
|
|
1511
|
-
}),
|
|
1522
|
+
}), i = new Set(e.targets.map(({ capability: u }) => u.id)), c = r.capabilityIds.filter((u) => i.has(u));
|
|
1512
1523
|
return console.info("[arcgis-portal-ai-assistant] navigation capability selection:", {
|
|
1513
1524
|
confidence: r.confidence,
|
|
1514
1525
|
method: "structured-model",
|
|
1515
1526
|
reason: r.reason,
|
|
1516
1527
|
request: a,
|
|
1517
|
-
selectedCapabilityIds:
|
|
1518
|
-
}), r.confidence <
|
|
1528
|
+
selectedCapabilityIds: c
|
|
1529
|
+
}), r.confidence < le ? {
|
|
1519
1530
|
chosenCapabilityIds: [],
|
|
1520
1531
|
status: "failed",
|
|
1521
|
-
summary: `Navigation selection confidence ${r.confidence} is below the required ${
|
|
1522
|
-
} : { chosenCapabilityIds:
|
|
1532
|
+
summary: `Navigation selection confidence ${r.confidence} is below the required ${le}; defer to the Portal Doc Assistant.`
|
|
1533
|
+
} : { chosenCapabilityIds: c };
|
|
1523
1534
|
} catch {
|
|
1524
1535
|
return console.info("[arcgis-portal-ai-assistant] navigation capability selection:", {
|
|
1525
1536
|
method: "structured-model-unavailable",
|
|
@@ -1528,19 +1539,19 @@ Candidates:
|
|
|
1528
1539
|
}), { chosenCapabilityIds: [] };
|
|
1529
1540
|
}
|
|
1530
1541
|
};
|
|
1531
|
-
function
|
|
1532
|
-
const a =
|
|
1533
|
-
return
|
|
1542
|
+
function Ba(e, t) {
|
|
1543
|
+
const a = R(e);
|
|
1544
|
+
return t.targets.filter(
|
|
1534
1545
|
({ capability: n }) => [n.title, ...n.hints].some(
|
|
1535
|
-
(o) =>
|
|
1546
|
+
(o) => R(o) === a
|
|
1536
1547
|
)
|
|
1537
1548
|
).map(({ capability: n }) => n.id);
|
|
1538
1549
|
}
|
|
1539
|
-
const
|
|
1550
|
+
const ke = /* @__PURE__ */ new Set(["1d", "7d", "14d", "30d", "3m", "6m"]), Ka = s.object({
|
|
1540
1551
|
period: s.string(),
|
|
1541
1552
|
startTime: s.string(),
|
|
1542
1553
|
endTime: s.string()
|
|
1543
|
-
}),
|
|
1554
|
+
}), Qa = String.raw`Extract temporal filters for an ArcGIS storage-credits query.
|
|
1544
1555
|
|
|
1545
1556
|
Return JSON only with these optional string fields:
|
|
1546
1557
|
- period
|
|
@@ -1566,39 +1577,39 @@ Now UTC:
|
|
|
1566
1577
|
|
|
1567
1578
|
User request:
|
|
1568
1579
|
{userRequest}`;
|
|
1569
|
-
async function
|
|
1570
|
-
const a =
|
|
1580
|
+
async function Wa(e, t = /* @__PURE__ */ new Date()) {
|
|
1581
|
+
const a = e.trim();
|
|
1571
1582
|
if (!a)
|
|
1572
1583
|
return {};
|
|
1573
1584
|
try {
|
|
1574
1585
|
const n = await b({
|
|
1575
|
-
promptText:
|
|
1576
|
-
schema:
|
|
1586
|
+
promptText: Qa,
|
|
1587
|
+
schema: Ka,
|
|
1577
1588
|
modelTier: "fast",
|
|
1578
1589
|
inputVariables: {
|
|
1579
|
-
nowEpochMs: String(
|
|
1580
|
-
nowIso:
|
|
1590
|
+
nowEpochMs: String(t.getTime()),
|
|
1591
|
+
nowIso: t.toISOString(),
|
|
1581
1592
|
userRequest: a
|
|
1582
1593
|
}
|
|
1583
1594
|
});
|
|
1584
|
-
return
|
|
1595
|
+
return Ja(n, t);
|
|
1585
1596
|
} catch (n) {
|
|
1586
1597
|
return console.error(n), {};
|
|
1587
1598
|
}
|
|
1588
1599
|
}
|
|
1589
|
-
function
|
|
1590
|
-
const a =
|
|
1600
|
+
function Ja(e, t = /* @__PURE__ */ new Date()) {
|
|
1601
|
+
const a = de(e.startTime), n = de(e.endTime), o = _a(e.period);
|
|
1591
1602
|
if (o) {
|
|
1592
1603
|
if (a !== void 0 && n !== void 0 && a < n)
|
|
1593
1604
|
return { period: o, startTime: String(a), endTime: String(n) };
|
|
1594
|
-
const r =
|
|
1595
|
-
if (!r || n !== void 0 && !
|
|
1596
|
-
const
|
|
1597
|
-
if (
|
|
1605
|
+
const r = ke.has(o);
|
|
1606
|
+
if (!r || n !== void 0 && !Ha(n, t.getTime())) {
|
|
1607
|
+
const c = n ?? t.getTime(), u = Ya(o, new Date(c));
|
|
1608
|
+
if (u !== void 0)
|
|
1598
1609
|
return {
|
|
1599
1610
|
period: o,
|
|
1600
|
-
startTime: String(
|
|
1601
|
-
endTime: String(
|
|
1611
|
+
startTime: String(u),
|
|
1612
|
+
endTime: String(c)
|
|
1602
1613
|
};
|
|
1603
1614
|
}
|
|
1604
1615
|
return r ? {
|
|
@@ -1607,25 +1618,25 @@ function _a(t, e = /* @__PURE__ */ new Date()) {
|
|
|
1607
1618
|
...n !== void 0 ? { endTime: String(n) } : {}
|
|
1608
1619
|
} : { period: o };
|
|
1609
1620
|
}
|
|
1610
|
-
return a !== void 0 && n !== void 0 && a < n ? { startTime: String(a), endTime: String(n) } : a !== void 0 ? { startTime: String(a), endTime: String(
|
|
1621
|
+
return a !== void 0 && n !== void 0 && a < n ? { startTime: String(a), endTime: String(n) } : a !== void 0 ? { startTime: String(a), endTime: String(t.getTime()) } : {};
|
|
1611
1622
|
}
|
|
1612
|
-
function
|
|
1613
|
-
const
|
|
1614
|
-
if (!
|
|
1623
|
+
function _a(e) {
|
|
1624
|
+
const t = e?.trim().match(/^(\d+)\s*([dwm])$/iu);
|
|
1625
|
+
if (!t)
|
|
1615
1626
|
return;
|
|
1616
|
-
const a = Number.parseInt(
|
|
1627
|
+
const a = Number.parseInt(t[1], 10);
|
|
1617
1628
|
if (!Number.isFinite(a) || a <= 0)
|
|
1618
1629
|
return;
|
|
1619
|
-
const n =
|
|
1630
|
+
const n = t[2].toLowerCase();
|
|
1620
1631
|
if (n === "w") {
|
|
1621
1632
|
const o = a * 7;
|
|
1622
|
-
if (
|
|
1633
|
+
if (ke.has(`${o}d`))
|
|
1623
1634
|
return `${o}d`;
|
|
1624
1635
|
}
|
|
1625
1636
|
return `${a}${n}`;
|
|
1626
1637
|
}
|
|
1627
|
-
function
|
|
1628
|
-
const a =
|
|
1638
|
+
function Ya(e, t) {
|
|
1639
|
+
const a = e.match(/^(\d+)([dwm])$/u);
|
|
1629
1640
|
if (!a)
|
|
1630
1641
|
return;
|
|
1631
1642
|
const n = Number.parseInt(a[1], 10);
|
|
@@ -1633,35 +1644,35 @@ function Ha(t, e) {
|
|
|
1633
1644
|
return;
|
|
1634
1645
|
const o = a[2];
|
|
1635
1646
|
if (o === "d")
|
|
1636
|
-
return
|
|
1647
|
+
return t.getTime() - n * 24 * 60 * 60 * 1e3;
|
|
1637
1648
|
if (o === "w")
|
|
1638
|
-
return
|
|
1639
|
-
const r = new Date(
|
|
1649
|
+
return t.getTime() - n * 7 * 24 * 60 * 60 * 1e3;
|
|
1650
|
+
const r = new Date(t.getTime());
|
|
1640
1651
|
return r.setUTCMonth(r.getUTCMonth() - n), r.getTime();
|
|
1641
1652
|
}
|
|
1642
|
-
function
|
|
1643
|
-
if (!
|
|
1653
|
+
function de(e) {
|
|
1654
|
+
if (!e)
|
|
1644
1655
|
return;
|
|
1645
|
-
const
|
|
1646
|
-
if (!(!Number.isFinite(
|
|
1647
|
-
return
|
|
1656
|
+
const t = Number.parseInt(e, 10);
|
|
1657
|
+
if (!(!Number.isFinite(t) || t <= 0))
|
|
1658
|
+
return t;
|
|
1648
1659
|
}
|
|
1649
|
-
function
|
|
1650
|
-
const a = new Date(
|
|
1660
|
+
function Ha(e, t) {
|
|
1661
|
+
const a = new Date(e), n = new Date(t);
|
|
1651
1662
|
return a.getUTCFullYear() === n.getUTCFullYear() && a.getUTCMonth() === n.getUTCMonth() && a.getUTCDate() === n.getUTCDate();
|
|
1652
1663
|
}
|
|
1653
|
-
async function
|
|
1654
|
-
const n =
|
|
1664
|
+
async function Xa(e, t, a) {
|
|
1665
|
+
const n = S().find((r) => r.id === e);
|
|
1655
1666
|
if (!n)
|
|
1656
1667
|
return;
|
|
1657
|
-
const o = await en(
|
|
1658
|
-
return o &&
|
|
1668
|
+
const o = await en(Za(n), a);
|
|
1669
|
+
return o && an(o, t) ? { capability: n, target: o } : void 0;
|
|
1659
1670
|
}
|
|
1660
|
-
function
|
|
1661
|
-
const { hash:
|
|
1671
|
+
function Za(e) {
|
|
1672
|
+
const { hash: t, queryParams: a, routeKey: n } = e.resolutions.navigate;
|
|
1662
1673
|
switch (n) {
|
|
1663
1674
|
case "content":
|
|
1664
|
-
switch (
|
|
1675
|
+
switch (e.id) {
|
|
1665
1676
|
case "my-content":
|
|
1666
1677
|
return { destinationType: "portal-content" };
|
|
1667
1678
|
case "create-feature-layer":
|
|
@@ -1672,11 +1683,11 @@ function tn(t) {
|
|
|
1672
1683
|
return { destinationType: "portal-content" };
|
|
1673
1684
|
}
|
|
1674
1685
|
case "groups":
|
|
1675
|
-
if (
|
|
1686
|
+
if (t === "featured")
|
|
1676
1687
|
return { destinationType: "portal-groups", hash: "featured" };
|
|
1677
|
-
if (
|
|
1688
|
+
if (t === "organization")
|
|
1678
1689
|
return { destinationType: "portal-groups", hash: "organization" };
|
|
1679
|
-
switch (
|
|
1690
|
+
switch (e.id) {
|
|
1680
1691
|
case "my groups":
|
|
1681
1692
|
return { destinationType: "portal-groups", hash: "my" };
|
|
1682
1693
|
case "create-group":
|
|
@@ -1687,50 +1698,50 @@ function tn(t) {
|
|
|
1687
1698
|
case "organization":
|
|
1688
1699
|
return {
|
|
1689
1700
|
destinationType: "portal-org",
|
|
1690
|
-
hash:
|
|
1701
|
+
hash: t,
|
|
1691
1702
|
queryParams: a,
|
|
1692
|
-
buttonLabel:
|
|
1703
|
+
buttonLabel: e.buttonLabel
|
|
1693
1704
|
};
|
|
1694
1705
|
default:
|
|
1695
1706
|
return;
|
|
1696
1707
|
}
|
|
1697
1708
|
}
|
|
1698
|
-
async function en(
|
|
1699
|
-
if (!
|
|
1700
|
-
return
|
|
1701
|
-
const a = await
|
|
1709
|
+
async function en(e, t) {
|
|
1710
|
+
if (!e || !t || !tn(e))
|
|
1711
|
+
return e;
|
|
1712
|
+
const a = await Wa(t);
|
|
1702
1713
|
if (!a.period && !a.startTime && !a.endTime)
|
|
1703
|
-
return
|
|
1714
|
+
return e;
|
|
1704
1715
|
const n = {
|
|
1705
|
-
...
|
|
1716
|
+
...e.queryParams ?? {},
|
|
1706
1717
|
...a.period ? { period: a.period } : {},
|
|
1707
1718
|
...a.startTime ? { startTime: a.startTime } : {},
|
|
1708
1719
|
...a.endTime ? { endTime: a.endTime } : {}
|
|
1709
1720
|
};
|
|
1710
|
-
return { ...
|
|
1721
|
+
return { ...e, queryParams: n };
|
|
1711
1722
|
}
|
|
1712
|
-
function
|
|
1713
|
-
return
|
|
1723
|
+
function tn(e) {
|
|
1724
|
+
return e.destinationType === "portal-org" && e.hash === "status";
|
|
1714
1725
|
}
|
|
1715
|
-
function
|
|
1716
|
-
return !
|
|
1726
|
+
function an(e, t) {
|
|
1727
|
+
return !t || !!t[e.destinationType];
|
|
1717
1728
|
}
|
|
1718
|
-
const
|
|
1719
|
-
if (
|
|
1729
|
+
const nn = async (e, t) => {
|
|
1730
|
+
if (e.outputMessage || e.status === "failed")
|
|
1720
1731
|
return {};
|
|
1721
|
-
const a =
|
|
1732
|
+
const a = e.targets.find(({ capability: r }) => e.chosenCapabilityIds.includes(r.id)) ?? e.targets[0];
|
|
1722
1733
|
if (!a)
|
|
1723
1734
|
return {
|
|
1724
1735
|
outputMessage: "I couldn't find a matching Portal page. Try asking to open your content, groups, or organization settings.",
|
|
1725
|
-
sharedStatePatch: { navLastAnsweredRequest: { value:
|
|
1736
|
+
sharedStatePatch: { navLastAnsweredRequest: { value: pe(e) } },
|
|
1726
1737
|
status: "success",
|
|
1727
1738
|
summary: "Navigation could not find a matching capability; route another agent if appropriate."
|
|
1728
1739
|
};
|
|
1729
|
-
const n =
|
|
1730
|
-
return o ? (await
|
|
1731
|
-
outputMessage:
|
|
1740
|
+
const n = pe(e), o = await Xa(a.capability.id, void 0, n);
|
|
1741
|
+
return o ? (await g({ text: "Preparing navigation...", agentName: "navigation" }, t), await F(o.target, t), {
|
|
1742
|
+
outputMessage: e.chosenCapabilityIds.length ? a.capability.description : `The closest place to start is ${a.capability.title}. Click the button below to open it.`,
|
|
1732
1743
|
status: "success",
|
|
1733
|
-
summary: `Navigation suggested ${a.capability.id}${
|
|
1744
|
+
summary: `Navigation suggested ${a.capability.id}${e.retrievalDegraded ? " using keyword-only retrieval" : ""}.`,
|
|
1734
1745
|
sharedStatePatch: { navLastAnsweredRequest: { value: n } }
|
|
1735
1746
|
}) : (console.warn(`Navigation capability ${a.capability.id} was not found in the resolver.`), {
|
|
1736
1747
|
outputMessage: "I found a possible destination, but couldn't resolve a valid Portal navigation target. Try asking to open your content, groups, or organization settings.",
|
|
@@ -1739,87 +1750,87 @@ const on = async (t, e) => {
|
|
|
1739
1750
|
sharedStatePatch: { navLastAnsweredRequest: { value: n } }
|
|
1740
1751
|
});
|
|
1741
1752
|
};
|
|
1742
|
-
function
|
|
1743
|
-
return I(
|
|
1753
|
+
function pe(e) {
|
|
1754
|
+
return I(e.agentExecutionContext.messages) || e.agentExecutionContext.userRequest;
|
|
1744
1755
|
}
|
|
1745
|
-
async function
|
|
1746
|
-
return
|
|
1756
|
+
async function ze(e) {
|
|
1757
|
+
return e.length === 0 ? [] : (await at.getDefault().load(), await Be(e));
|
|
1747
1758
|
}
|
|
1748
|
-
const
|
|
1759
|
+
const on = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1749
1760
|
__proto__: null,
|
|
1750
|
-
generateEmbeddings:
|
|
1761
|
+
generateEmbeddings: ze
|
|
1751
1762
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1752
|
-
function
|
|
1753
|
-
const
|
|
1754
|
-
a.trim().length > 0 &&
|
|
1755
|
-
const n =
|
|
1763
|
+
function rn(e) {
|
|
1764
|
+
const t = [], a = `${e.title}. ${e.description}`;
|
|
1765
|
+
a.trim().length > 0 && t.push({ field: "summary", text: a });
|
|
1766
|
+
const n = e.hints;
|
|
1756
1767
|
if (Array.isArray(n))
|
|
1757
1768
|
for (const o of n)
|
|
1758
|
-
typeof o == "string" && o.trim().length > 0 &&
|
|
1759
|
-
return
|
|
1769
|
+
typeof o == "string" && o.trim().length > 0 && t.push({ field: "hint", text: o });
|
|
1770
|
+
return t;
|
|
1760
1771
|
}
|
|
1761
|
-
let
|
|
1762
|
-
async function
|
|
1763
|
-
const
|
|
1764
|
-
return
|
|
1765
|
-
throw
|
|
1766
|
-
}), await
|
|
1772
|
+
let $, X, D = 0;
|
|
1773
|
+
async function sn(e = {}) {
|
|
1774
|
+
const t = D;
|
|
1775
|
+
return $ ??= un(e.embed ?? ln).then((a) => (t === D && (X = a), a)).catch((a) => {
|
|
1776
|
+
throw t === D && ($ = void 0), a;
|
|
1777
|
+
}), await $;
|
|
1767
1778
|
}
|
|
1768
|
-
function
|
|
1769
|
-
return
|
|
1779
|
+
function cn() {
|
|
1780
|
+
return X;
|
|
1770
1781
|
}
|
|
1771
|
-
function
|
|
1772
|
-
|
|
1782
|
+
function me() {
|
|
1783
|
+
D += 1, X = void 0, $ = void 0;
|
|
1773
1784
|
}
|
|
1774
|
-
async function
|
|
1775
|
-
const
|
|
1776
|
-
if (a.length !==
|
|
1777
|
-
throw new Error(`Expected ${
|
|
1778
|
-
return
|
|
1785
|
+
async function un(e) {
|
|
1786
|
+
const t = dn(), a = await e(t.map((n) => n.text));
|
|
1787
|
+
if (a.length !== t.length)
|
|
1788
|
+
throw new Error(`Expected ${t.length} vectors, got ${a.length}`);
|
|
1789
|
+
return t.map((n, o) => ({
|
|
1779
1790
|
...n,
|
|
1780
1791
|
vector: a[o]
|
|
1781
1792
|
}));
|
|
1782
1793
|
}
|
|
1783
|
-
async function
|
|
1784
|
-
const { generateEmbeddings:
|
|
1785
|
-
return await e
|
|
1794
|
+
async function ln(e) {
|
|
1795
|
+
const { generateEmbeddings: t } = await Promise.resolve().then(() => on);
|
|
1796
|
+
return await t(e);
|
|
1786
1797
|
}
|
|
1787
|
-
function
|
|
1788
|
-
return
|
|
1789
|
-
(
|
|
1790
|
-
capabilityId:
|
|
1791
|
-
field:
|
|
1798
|
+
function dn() {
|
|
1799
|
+
return S().flatMap(
|
|
1800
|
+
(e) => rn(e).map(({ field: t, text: a }) => ({
|
|
1801
|
+
capabilityId: e.id,
|
|
1802
|
+
field: t,
|
|
1792
1803
|
text: a
|
|
1793
1804
|
}))
|
|
1794
1805
|
);
|
|
1795
1806
|
}
|
|
1796
|
-
const
|
|
1807
|
+
const ge = 1.2, he = 0.75, pn = 60, mn = 0.65, V = {
|
|
1797
1808
|
description: 1,
|
|
1798
1809
|
hint: 2,
|
|
1799
1810
|
title: 3
|
|
1800
1811
|
};
|
|
1801
|
-
let
|
|
1802
|
-
function
|
|
1803
|
-
|
|
1812
|
+
let W;
|
|
1813
|
+
function gn() {
|
|
1814
|
+
W = void 0;
|
|
1804
1815
|
}
|
|
1805
|
-
async function
|
|
1806
|
-
const a =
|
|
1816
|
+
async function hn(e, t = {}) {
|
|
1817
|
+
const a = vn($e(e));
|
|
1807
1818
|
let n = [], o = !1, r;
|
|
1808
|
-
if (
|
|
1809
|
-
const
|
|
1810
|
-
if (!
|
|
1819
|
+
if (e.trim()) {
|
|
1820
|
+
const i = t.loadEmbeddings, c = cn();
|
|
1821
|
+
if (!i && !c)
|
|
1811
1822
|
o = !0, r = "Capability embeddings are still loading.";
|
|
1812
1823
|
else
|
|
1813
1824
|
try {
|
|
1814
|
-
if (
|
|
1815
|
-
const [
|
|
1816
|
-
(
|
|
1817
|
-
|
|
1825
|
+
if (i) {
|
|
1826
|
+
const [u, d] = await Promise.all([
|
|
1827
|
+
(t.embedQuery ?? ye)(e),
|
|
1828
|
+
i()
|
|
1818
1829
|
]);
|
|
1819
|
-
n =
|
|
1820
|
-
} else if (
|
|
1821
|
-
const
|
|
1822
|
-
n =
|
|
1830
|
+
n = fe(u, d);
|
|
1831
|
+
} else if (c) {
|
|
1832
|
+
const u = await (t.embedQuery ?? ye)(e);
|
|
1833
|
+
n = fe(u, c);
|
|
1823
1834
|
}
|
|
1824
1835
|
} catch {
|
|
1825
1836
|
o = !0, r = "Semantic search is unavailable.";
|
|
@@ -1830,117 +1841,117 @@ async function fn(t, e = {}) {
|
|
|
1830
1841
|
...r ? { degradedReason: r } : {},
|
|
1831
1842
|
// RRF combines ranks rather than raw scores because BM25 and cosine
|
|
1832
1843
|
// similarity are on different scales.
|
|
1833
|
-
matches:
|
|
1844
|
+
matches: In(a, n, t.topN ?? 5)
|
|
1834
1845
|
};
|
|
1835
1846
|
}
|
|
1836
|
-
function
|
|
1837
|
-
return
|
|
1847
|
+
function fn() {
|
|
1848
|
+
return W ??= yn(S()), W;
|
|
1838
1849
|
}
|
|
1839
|
-
function
|
|
1840
|
-
const
|
|
1850
|
+
function yn(e) {
|
|
1851
|
+
const t = /* @__PURE__ */ new Map(), a = e.map((n) => {
|
|
1841
1852
|
const o = /* @__PURE__ */ new Map();
|
|
1842
|
-
|
|
1853
|
+
B(o, n.title, V.title), B(o, n.description, V.description);
|
|
1843
1854
|
for (const r of n.hints)
|
|
1844
|
-
|
|
1855
|
+
B(o, r, V.hint);
|
|
1845
1856
|
for (const r of o.keys())
|
|
1846
|
-
|
|
1857
|
+
t.set(r, (t.get(r) ?? 0) + 1);
|
|
1847
1858
|
return {
|
|
1848
1859
|
capability: n,
|
|
1849
|
-
length:
|
|
1860
|
+
length: wn(o),
|
|
1850
1861
|
termFrequencies: o
|
|
1851
1862
|
};
|
|
1852
1863
|
});
|
|
1853
1864
|
return {
|
|
1854
1865
|
averageDocumentLength: a.length ? a.reduce((n, o) => n + o.length, 0) / a.length : 0,
|
|
1855
|
-
documentFrequency:
|
|
1866
|
+
documentFrequency: t,
|
|
1856
1867
|
documents: a
|
|
1857
1868
|
};
|
|
1858
1869
|
}
|
|
1859
|
-
function
|
|
1860
|
-
for (const n of
|
|
1861
|
-
|
|
1870
|
+
function B(e, t, a) {
|
|
1871
|
+
for (const n of $e(t))
|
|
1872
|
+
e.set(n, (e.get(n) ?? 0) + a);
|
|
1862
1873
|
}
|
|
1863
|
-
function
|
|
1864
|
-
return [...
|
|
1874
|
+
function wn(e) {
|
|
1875
|
+
return [...e.values()].reduce((t, a) => t + a, 0);
|
|
1865
1876
|
}
|
|
1866
|
-
function
|
|
1867
|
-
return
|
|
1877
|
+
function $e(e) {
|
|
1878
|
+
return e.toLowerCase().split(/[^a-z0-9]+/u).filter(Boolean);
|
|
1868
1879
|
}
|
|
1869
|
-
function
|
|
1870
|
-
const
|
|
1871
|
-
return
|
|
1872
|
-
let
|
|
1873
|
-
for (const
|
|
1874
|
-
const
|
|
1875
|
-
if (!
|
|
1880
|
+
function vn(e) {
|
|
1881
|
+
const t = fn(), a = new Set(e), n = t.documents.length;
|
|
1882
|
+
return t.documents.map(({ capability: o, length: r, termFrequencies: i }) => {
|
|
1883
|
+
let c = 0;
|
|
1884
|
+
for (const u of a) {
|
|
1885
|
+
const d = i.get(u), l = t.documentFrequency.get(u);
|
|
1886
|
+
if (!d || !l)
|
|
1876
1887
|
continue;
|
|
1877
|
-
const
|
|
1878
|
-
|
|
1888
|
+
const p = Math.log(1 + (n - l + 0.5) / (l + 0.5)), m = ge * (1 - he + he * (r / t.averageDocumentLength));
|
|
1889
|
+
c += p * (d * (ge + 1) / (d + m));
|
|
1879
1890
|
}
|
|
1880
|
-
return { capability: o, score:
|
|
1881
|
-
}).filter(({ score: o }) => o > 0).sort(
|
|
1891
|
+
return { capability: o, score: c };
|
|
1892
|
+
}).filter(({ score: o }) => o > 0).sort(De);
|
|
1882
1893
|
}
|
|
1883
|
-
function
|
|
1894
|
+
function fe(e, t) {
|
|
1884
1895
|
const a = /* @__PURE__ */ new Map();
|
|
1885
|
-
for (const o of
|
|
1886
|
-
const r =
|
|
1896
|
+
for (const o of t) {
|
|
1897
|
+
const r = bn(e, o.vector);
|
|
1887
1898
|
if (r === void 0)
|
|
1888
1899
|
continue;
|
|
1889
|
-
const
|
|
1890
|
-
(
|
|
1900
|
+
const i = a.get(o.capabilityId);
|
|
1901
|
+
(i === void 0 || r > i) && a.set(o.capabilityId, r);
|
|
1891
1902
|
}
|
|
1892
|
-
const n = new Map(
|
|
1903
|
+
const n = new Map(S().map((o) => [o.id, o]));
|
|
1893
1904
|
return [...a.entries()].flatMap(([o, r]) => {
|
|
1894
|
-
const
|
|
1895
|
-
return
|
|
1896
|
-
}).sort(
|
|
1905
|
+
const i = n.get(o);
|
|
1906
|
+
return i && r >= mn ? [{ capability: i, score: r }] : [];
|
|
1907
|
+
}).sort(De);
|
|
1897
1908
|
}
|
|
1898
|
-
function
|
|
1899
|
-
if (
|
|
1909
|
+
function bn(e, t) {
|
|
1910
|
+
if (e.length === 0 || e.length !== t.length)
|
|
1900
1911
|
return;
|
|
1901
1912
|
let a = 0, n = 0, o = 0;
|
|
1902
|
-
for (let
|
|
1903
|
-
a +=
|
|
1913
|
+
for (let i = 0; i < e.length; i += 1)
|
|
1914
|
+
a += e[i] * t[i], n += e[i] ** 2, o += t[i] ** 2;
|
|
1904
1915
|
const r = Math.sqrt(n) * Math.sqrt(o);
|
|
1905
1916
|
return r === 0 ? void 0 : a / r;
|
|
1906
1917
|
}
|
|
1907
|
-
async function
|
|
1908
|
-
const [
|
|
1909
|
-
if (!
|
|
1918
|
+
async function ye(e) {
|
|
1919
|
+
const [t] = await ze([e]);
|
|
1920
|
+
if (!t)
|
|
1910
1921
|
throw new Error("Expected one query embedding.");
|
|
1911
|
-
return
|
|
1922
|
+
return t;
|
|
1912
1923
|
}
|
|
1913
|
-
function
|
|
1924
|
+
function In(e, t, a) {
|
|
1914
1925
|
const n = /* @__PURE__ */ new Map();
|
|
1915
|
-
return
|
|
1926
|
+
return we(n, e, "keyword"), we(n, t, "semantic"), [...n.values()].sort((o, r) => r.score !== o.score ? r.score - o.score : (r.semanticScore ?? 0) !== (o.semanticScore ?? 0) ? (r.semanticScore ?? 0) - (o.semanticScore ?? 0) : (r.keywordScore ?? 0) !== (o.keywordScore ?? 0) ? (r.keywordScore ?? 0) - (o.keywordScore ?? 0) : o.capability.id.localeCompare(r.capability.id)).slice(0, Math.max(0, a));
|
|
1916
1927
|
}
|
|
1917
|
-
function
|
|
1918
|
-
for (const [n, { capability: o, score: r }] of
|
|
1919
|
-
const
|
|
1920
|
-
|
|
1928
|
+
function we(e, t, a) {
|
|
1929
|
+
for (const [n, { capability: o, score: r }] of t.entries()) {
|
|
1930
|
+
const i = n + 1, c = e.get(o.id) ?? { capability: o, score: 0 };
|
|
1931
|
+
c.score += 1 / (pn + i), a === "keyword" ? (c.keywordRank = i, c.keywordScore = r) : (c.semanticRank = i, c.semanticScore = r), e.set(o.id, c);
|
|
1921
1932
|
}
|
|
1922
1933
|
}
|
|
1923
|
-
function
|
|
1924
|
-
return
|
|
1934
|
+
function De(e, t) {
|
|
1935
|
+
return t.score - e.score || e.capability.id.localeCompare(t.capability.id);
|
|
1925
1936
|
}
|
|
1926
|
-
const
|
|
1927
|
-
await
|
|
1928
|
-
const a = I(
|
|
1937
|
+
const Sn = async (e, t) => {
|
|
1938
|
+
await g({ text: "Finding a place to navigate...", agentName: "navigation" }, t);
|
|
1939
|
+
const a = I(e.agentExecutionContext.messages).trim();
|
|
1929
1940
|
try {
|
|
1930
|
-
const n = await
|
|
1941
|
+
const n = await hn(a, { topN: 5 });
|
|
1931
1942
|
return console.table(
|
|
1932
|
-
n.matches.map(({ capability: o, keywordRank: r, keywordScore:
|
|
1943
|
+
n.matches.map(({ capability: o, keywordRank: r, keywordScore: i, semanticRank: c, semanticScore: u, score: d }) => ({
|
|
1933
1944
|
capability: o.title,
|
|
1934
|
-
fusedScore:
|
|
1945
|
+
fusedScore: d,
|
|
1935
1946
|
keywordRank: r,
|
|
1936
|
-
keywordScore:
|
|
1937
|
-
semanticRank:
|
|
1938
|
-
semanticScore:
|
|
1947
|
+
keywordScore: i,
|
|
1948
|
+
semanticRank: c,
|
|
1949
|
+
semanticScore: u
|
|
1939
1950
|
}))
|
|
1940
1951
|
), n.degradedReason && console.info("[arcgis-portal-ai-assistant] navigation semantic search:", n.degradedReason), {
|
|
1941
1952
|
chosenCapabilityIds: [],
|
|
1942
1953
|
retrievalDegraded: n.degradedReason ?? "",
|
|
1943
|
-
targets:
|
|
1954
|
+
targets: xn(a, n.matches)
|
|
1944
1955
|
};
|
|
1945
1956
|
} catch {
|
|
1946
1957
|
return {
|
|
@@ -1951,78 +1962,78 @@ const xn = async (t, e) => {
|
|
|
1951
1962
|
};
|
|
1952
1963
|
}
|
|
1953
1964
|
};
|
|
1954
|
-
function
|
|
1955
|
-
const a =
|
|
1965
|
+
function xn(e, t) {
|
|
1966
|
+
const a = R(e), n = t.filter(
|
|
1956
1967
|
({ capability: r }) => [r.title, ...r.hints].some(
|
|
1957
|
-
(
|
|
1968
|
+
(i) => R(i) === a
|
|
1958
1969
|
)
|
|
1959
1970
|
);
|
|
1960
1971
|
if (n.length !== 1)
|
|
1961
|
-
return
|
|
1972
|
+
return t;
|
|
1962
1973
|
const [o] = n;
|
|
1963
|
-
return [o, ...
|
|
1974
|
+
return [o, ...t.filter((r) => r !== o)];
|
|
1964
1975
|
}
|
|
1965
|
-
const
|
|
1966
|
-
...
|
|
1967
|
-
chosenCapabilityIds: h({ reducer:
|
|
1976
|
+
const K = (e, t) => t ?? e, Re = h.Root({
|
|
1977
|
+
...P(),
|
|
1978
|
+
chosenCapabilityIds: h({ reducer: K, default: () => [] }),
|
|
1968
1979
|
// Empty when hybrid keyword-and-semantic retrieval succeeds; otherwise
|
|
1969
1980
|
// contains the semantic-search failure reason for response diagnostics.
|
|
1970
|
-
retrievalDegraded: h({ reducer:
|
|
1971
|
-
targets: h({ reducer:
|
|
1972
|
-
}),
|
|
1981
|
+
retrievalDegraded: h({ reducer: K, default: () => "" }),
|
|
1982
|
+
targets: h({ reducer: K, default: () => [] })
|
|
1983
|
+
}), Tn = () => new N(Re).addNode("retrieveNavigationTargets", Sn).addNode("chooseNavigationTargets", Va).addNode("respondWithNavigation", nn).addEdge(G, "retrieveNavigationTargets").addEdge("retrieveNavigationTargets", "chooseNavigationTargets").addEdge("chooseNavigationTargets", "respondWithNavigation").addEdge("respondWithNavigation", w);
|
|
1973
1984
|
function Mn() {
|
|
1974
|
-
const
|
|
1985
|
+
const e = S().map(({ hints: t, title: a }) => t[0] ?? a).join(", ");
|
|
1975
1986
|
return String.raw`- **portal-navigation** - Portal page navigation assistant:
|
|
1976
1987
|
- routes requests to open, show, or navigate to a Portal page, including creation-flow pages
|
|
1977
1988
|
- falls back to the closest Portal page where a workflow starts when another agent cannot perform the action
|
|
1978
1989
|
- handles short navigation follow-ups after asking the user to open a page
|
|
1979
|
-
- capability examples: ${
|
|
1990
|
+
- capability examples: ${e}
|
|
1980
1991
|
- do not use for general "how do I" questions unless the user explicitly asks to reach a page
|
|
1981
1992
|
`;
|
|
1982
1993
|
}
|
|
1983
|
-
const
|
|
1994
|
+
const Cn = {
|
|
1984
1995
|
id: "navigation",
|
|
1985
1996
|
name: "Portal Navigation",
|
|
1986
1997
|
get description() {
|
|
1987
1998
|
return Mn();
|
|
1988
1999
|
},
|
|
1989
|
-
createGraph:
|
|
1990
|
-
workspace:
|
|
1991
|
-
},
|
|
1992
|
-
function
|
|
1993
|
-
if (!
|
|
2000
|
+
createGraph: Tn,
|
|
2001
|
+
workspace: Re
|
|
2002
|
+
}, An = Le`:host{height:100%;border-width:1px;border-style:solid;border-color:var(--calcite-color-border-3);display:block;width:100%;--tw-shadow: 0 1px 6px -1px rgba(0, 0, 0, .16), 0 1px 2px -1px rgba(0, 0, 0, .08);--tw-shadow-colored: 0 1px 6px -1px var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.chat-entry{display:flex;flex-direction:column;gap:.75rem;width:100%}.chat-actions{display:flex;justify-content:flex-end;gap:.5rem}.header-actions{display:flex;gap:.5rem;padding-inline-start:.75rem}.navigation-block{display:flex;flex-direction:column;align-items:stretch;gap:.35rem;margin-top:.5rem}.navigation-button{width:100%;margin-block:.25rem}.navigation-block-description{font-size:.75rem;color:var(--calcite-color-text-3)}`;
|
|
2003
|
+
function Nn(e, t) {
|
|
2004
|
+
if (!t)
|
|
1994
2005
|
return;
|
|
1995
|
-
const { destinationType: a } =
|
|
2006
|
+
const { destinationType: a } = e;
|
|
1996
2007
|
switch (a) {
|
|
1997
2008
|
case "portal-content":
|
|
1998
|
-
return
|
|
2009
|
+
return t[a]?.(e.hash, e.queryParams);
|
|
1999
2010
|
case "portal-groups":
|
|
2000
|
-
return
|
|
2011
|
+
return t[a]?.(e.hash);
|
|
2001
2012
|
case "portal-org":
|
|
2002
|
-
return
|
|
2013
|
+
return t[a]?.(e.hash, e.queryParams);
|
|
2003
2014
|
case "portal-gallery":
|
|
2004
|
-
return
|
|
2015
|
+
return t[a];
|
|
2005
2016
|
case "portal-map-viewer":
|
|
2006
2017
|
case "portal-notebooks":
|
|
2007
2018
|
case "portal-scene-viewer":
|
|
2008
|
-
return
|
|
2019
|
+
return t[a];
|
|
2009
2020
|
case "portal-item":
|
|
2010
|
-
return
|
|
2021
|
+
return t[a]?.(e.itemId);
|
|
2011
2022
|
case "portal-group":
|
|
2012
|
-
return
|
|
2023
|
+
return t[a]?.(e.groupId);
|
|
2013
2024
|
default:
|
|
2014
|
-
return
|
|
2025
|
+
return U(a);
|
|
2015
2026
|
}
|
|
2016
2027
|
}
|
|
2017
|
-
function
|
|
2018
|
-
const
|
|
2019
|
-
return
|
|
2028
|
+
function Gn(e) {
|
|
2029
|
+
const t = Ct.safeParse(e);
|
|
2030
|
+
return t.success ? t.data : void 0;
|
|
2020
2031
|
}
|
|
2021
|
-
function
|
|
2022
|
-
const a =
|
|
2023
|
-
switch (
|
|
2032
|
+
function Pn(e, t) {
|
|
2033
|
+
const a = t.navigation;
|
|
2034
|
+
switch (e.destinationType) {
|
|
2024
2035
|
case "portal-content":
|
|
2025
|
-
switch (
|
|
2036
|
+
switch (e.hash) {
|
|
2026
2037
|
case "favorites":
|
|
2027
2038
|
return a.openContentFavorites;
|
|
2028
2039
|
case "group":
|
|
@@ -2037,7 +2048,7 @@ function qn(t, e) {
|
|
|
2037
2048
|
case "portal-gallery":
|
|
2038
2049
|
return a.openGallery;
|
|
2039
2050
|
case "portal-groups":
|
|
2040
|
-
switch (
|
|
2051
|
+
switch (e.hash) {
|
|
2041
2052
|
case "featured":
|
|
2042
2053
|
return a.openGroupsFeatured;
|
|
2043
2054
|
case "my":
|
|
@@ -2060,111 +2071,111 @@ function qn(t, e) {
|
|
|
2060
2071
|
case "portal-group":
|
|
2061
2072
|
return a.openGroup;
|
|
2062
2073
|
default:
|
|
2063
|
-
return
|
|
2074
|
+
return U(e);
|
|
2064
2075
|
}
|
|
2065
2076
|
}
|
|
2066
|
-
class
|
|
2077
|
+
class qn extends Fe {
|
|
2067
2078
|
constructor() {
|
|
2068
|
-
super(), this.t9n =
|
|
2069
|
-
const a =
|
|
2079
|
+
super(), this.t9n = Ve({ blocking: !0 }), this.assistantEl = E(), this.formEl = E(), this.voiceInputEl = E(), this.inputEl = E(), this.navigationSlotElements = /* @__PURE__ */ new Map(), this.handleSlottableRequest = (t) => {
|
|
2080
|
+
const a = t.detail, n = a.data?.block;
|
|
2070
2081
|
if (!n)
|
|
2071
2082
|
return;
|
|
2072
2083
|
const o = this.getNavigationAction(n);
|
|
2073
2084
|
o && this.upsertNavigationSlotElement(a.slotName, o);
|
|
2074
|
-
}, this.inputText = "", this.showVoiceInput = !0, this.isListening = !1, this.isVoiceInputDisabled = !1, this.interrupt = null, this.autoDestroyDisabled = !1, this.defaultClosed = !1, this.arcgisPortalNavigationRequest =
|
|
2085
|
+
}, this.inputText = "", this.showVoiceInput = !0, this.isListening = !1, this.isVoiceInputDisabled = !1, this.interrupt = null, this.autoDestroyDisabled = !1, this.defaultClosed = !1, this.useProdDocAssistant = !1, this.arcgisPortalNavigationRequest = Oe(), S();
|
|
2075
2086
|
}
|
|
2076
2087
|
static {
|
|
2077
|
-
this.properties = { inputText: 16, showVoiceInput: 16, isListening: 16, isVoiceInputDisabled: 16, interrupt: 16, autoDestroyDisabled: 5, portal: 0, user: 0, config: 0, navigationTargetMap: 0, disabledAgents: 0, defaultClosed: 5, navigationCapabilities: 0 };
|
|
2088
|
+
this.properties = { inputText: 16, showVoiceInput: 16, isListening: 16, isVoiceInputDisabled: 16, interrupt: 16, autoDestroyDisabled: 5, portal: 0, user: 0, config: 0, navigationTargetMap: 0, disabledAgents: 0, defaultClosed: 5, navigationCapabilities: 0, useProdDocAssistant: 5 };
|
|
2078
2089
|
}
|
|
2079
2090
|
static {
|
|
2080
|
-
this.styles =
|
|
2091
|
+
this.styles = An;
|
|
2081
2092
|
}
|
|
2082
2093
|
async load() {
|
|
2083
2094
|
await this.refreshCapabilityEmbeddings();
|
|
2084
2095
|
}
|
|
2085
|
-
willUpdate(
|
|
2086
|
-
!this.hasUpdated || !
|
|
2096
|
+
willUpdate(t) {
|
|
2097
|
+
!this.hasUpdated || !t.has("navigationCapabilities") || this.refreshCapabilityEmbeddings();
|
|
2087
2098
|
}
|
|
2088
2099
|
async clearEmbeddingsCache() {
|
|
2089
|
-
|
|
2100
|
+
me();
|
|
2090
2101
|
}
|
|
2091
|
-
isAgentEnabled(
|
|
2092
|
-
return !this.disabledAgents?.[
|
|
2102
|
+
isAgentEnabled(t) {
|
|
2103
|
+
return !this.disabledAgents?.[t];
|
|
2093
2104
|
}
|
|
2094
2105
|
async refreshCapabilityEmbeddings() {
|
|
2095
2106
|
try {
|
|
2096
|
-
|
|
2097
|
-
} catch (
|
|
2098
|
-
console.warn("[arcgis-portal-ai-assistant] embeddings warm-up failed:",
|
|
2107
|
+
S(this.navigationCapabilities), gn(), me(), await sn();
|
|
2108
|
+
} catch (t) {
|
|
2109
|
+
console.warn("[arcgis-portal-ai-assistant] embeddings warm-up failed:", t);
|
|
2099
2110
|
}
|
|
2100
2111
|
}
|
|
2101
|
-
getNavigationAction(
|
|
2102
|
-
if (
|
|
2112
|
+
getNavigationAction(t) {
|
|
2113
|
+
if (t?.type !== Se)
|
|
2103
2114
|
return;
|
|
2104
|
-
const a =
|
|
2115
|
+
const a = t.data, n = Gn(a);
|
|
2105
2116
|
if (!n)
|
|
2106
2117
|
return;
|
|
2107
|
-
const o =
|
|
2118
|
+
const o = Nn(a, this.navigationTargetMap);
|
|
2108
2119
|
if (o)
|
|
2109
2120
|
return {
|
|
2110
2121
|
href: o,
|
|
2111
2122
|
targetDetail: a,
|
|
2112
|
-
label: a?.buttonLabel ||
|
|
2123
|
+
label: a?.buttonLabel || Pn(n, this.t9n)
|
|
2113
2124
|
};
|
|
2114
2125
|
}
|
|
2115
|
-
upsertNavigationSlotElement(
|
|
2126
|
+
upsertNavigationSlotElement(t, a) {
|
|
2116
2127
|
const n = this.assistantEl.value;
|
|
2117
2128
|
if (!n)
|
|
2118
2129
|
return;
|
|
2119
|
-
const o = `navigation:${
|
|
2130
|
+
const o = `navigation:${t}`;
|
|
2120
2131
|
let r = this.navigationSlotElements.get(o);
|
|
2121
|
-
r || (r = document.createElement("div"), r.slot =
|
|
2122
|
-
|
|
2132
|
+
r || (r = document.createElement("div"), r.slot = t, this.navigationSlotElements.set(o, r), n.append(r)), je(v`<div><calcite-button class="navigation-button" appearance=outline width=full .href=${a.href} icon-end=launch @click=${(i) => {
|
|
2133
|
+
i.preventDefault(), this.arcgisPortalNavigationRequest.emit({
|
|
2123
2134
|
href: a.href,
|
|
2124
2135
|
targetDetail: a.targetDetail
|
|
2125
2136
|
});
|
|
2126
2137
|
}}>${a.label}</calcite-button>${a.description ? v`<div class="navigation-block-description">${a.description}</div>` : null}</div>`, r);
|
|
2127
2138
|
}
|
|
2128
2139
|
render() {
|
|
2129
|
-
const { t9n:
|
|
2130
|
-
return v`<arcgis-assistant log-enabled keep-suggested-prompts .heading=${
|
|
2131
|
-
this.interrupt =
|
|
2140
|
+
const { t9n: t, inputText: a, portal: n, user: o, navigationTargetMap: r, showVoiceInput: i, isListening: c, isVoiceInputDisabled: u, useProdDocAssistant: d } = this;
|
|
2141
|
+
return v`<arcgis-assistant log-enabled keep-suggested-prompts .heading=${t.heading} .entryMessage=${t.entryMessage} @arcgisSlottableRequest=${this.handleSlottableRequest} @arcgisInterrupt=${({ detail: l }) => {
|
|
2142
|
+
this.interrupt = l;
|
|
2132
2143
|
}} @arcgisInterruptCancel=${() => {
|
|
2133
2144
|
this.interrupt = null;
|
|
2134
2145
|
}} @arcgisInterruptSubmit=${() => {
|
|
2135
2146
|
this.interrupt = null;
|
|
2136
|
-
}} @arcgisPromptSelect=${({ detail:
|
|
2137
|
-
this.inputText =
|
|
2147
|
+
}} @arcgisPromptSelect=${({ detail: l }) => {
|
|
2148
|
+
this.inputText = l.prompt, requestAnimationFrame(() => {
|
|
2138
2149
|
this.inputEl.value?.focusTextArea();
|
|
2139
2150
|
});
|
|
2140
|
-
}} ${
|
|
2141
|
-
|
|
2142
|
-
const
|
|
2143
|
-
|
|
2144
|
-
}} ${
|
|
2145
|
-
|
|
2146
|
-
}} @arcgisUserMentionableTextAreaChange=${({ detail:
|
|
2147
|
-
this.inputText =
|
|
2148
|
-
}} ${
|
|
2151
|
+
}} ${k(this.assistantEl)}><div slot=header-actions-start class="header-actions"><calcite-icon icon=effects></calcite-icon></div><form slot=chat-entry class="chat-entry" @submit=${(l) => {
|
|
2152
|
+
l.preventDefault();
|
|
2153
|
+
const p = a.trim();
|
|
2154
|
+
p && (this.assistantEl.value?.submitMessage(p), this.inputText = "");
|
|
2155
|
+
}} ${k(this.formEl)}><arcgis-portal-mentionable-text-area .portal=${n} .user=${o} rows=3 .popoverListLabel=${t.mentionEntities} .placeholder=${t.placeholder} .value=${a} @arcgisUserMentionableTextAreaKeyDown=${({ detail: l }) => {
|
|
2156
|
+
l.key === "Enter" && !l.shiftKey && (l.preventDefault(), this.formEl.value?.requestSubmit());
|
|
2157
|
+
}} @arcgisUserMentionableTextAreaChange=${({ detail: l }) => {
|
|
2158
|
+
this.inputText = l ?? "";
|
|
2159
|
+
}} ${k(this.inputEl)}></arcgis-portal-mentionable-text-area><div class="chat-actions"><arcgis-portal-voice-input @arcgisVoiceInputStart=${() => {
|
|
2149
2160
|
this.isListening = !0, this.isVoiceInputDisabled = !1;
|
|
2150
2161
|
}} @arcgisVoiceInputStop=${() => {
|
|
2151
2162
|
this.isListening = !1, this.isVoiceInputDisabled = !1;
|
|
2152
|
-
}} @arcgisVoiceInputError=${(
|
|
2153
|
-
|
|
2154
|
-
}} @arcgisVoiceInputInterimTranscription=${(
|
|
2155
|
-
this.inputText =
|
|
2156
|
-
}} ${
|
|
2163
|
+
}} @arcgisVoiceInputError=${(l) => {
|
|
2164
|
+
l.detail.errorCode === "not-supported" && (this.showVoiceInput = !1);
|
|
2165
|
+
}} @arcgisVoiceInputInterimTranscription=${(l) => {
|
|
2166
|
+
this.inputText = l.detail.text;
|
|
2167
|
+
}} ${k(this.voiceInputEl)}></arcgis-portal-voice-input>${i && v`<calcite-button icon-start=microphone .label=${t.voiceInput} round .disabled=${u} .appearance=${c ? "solid" : "outline-fill"} @click=${async () => {
|
|
2157
2168
|
this.isVoiceInputDisabled = !0;
|
|
2158
|
-
const
|
|
2159
|
-
|
|
2160
|
-
}}></calcite-button>` || ""}<calcite-button type=submit icon-start=send round .disabled=${!a.trim()} .label=${
|
|
2161
|
-
this.assistantEl.value?.submitInterrupt(
|
|
2169
|
+
const l = this.voiceInputEl.value;
|
|
2170
|
+
c ? await l?.stopListening() : await l?.startListening();
|
|
2171
|
+
}}></calcite-button>` || ""}<calcite-button type=submit icon-start=send round .disabled=${!a.trim()} .label=${t.send}>${t.send}</calcite-button></div></form>${this.isAgentEnabled("itemAnalytics") && v`<arcgis-assistant-agent .agent=${$a} .context=${{ portal: n, user: o, navigationTargetMap: r }}></arcgis-assistant-agent>` || ""}${this.isAgentEnabled("groupCreation") && v`<arcgis-assistant-agent .agent=${Pt} .context=${{ portal: n, user: o, navigationTargetMap: r }}></arcgis-assistant-agent>` || ""}${this.isAgentEnabled("docAssistant") && v`<arcgis-assistant-agent .agent=${ta} .context=${{ portal: n, user: o, navigationTargetMap: r, useProdDocAssistant: d }}></arcgis-assistant-agent>` || ""}${this.isAgentEnabled("groupAnalytics") && v`<arcgis-assistant-agent .agent=${xa} .context=${{ portal: n, user: o, navigationTargetMap: r }}></arcgis-assistant-agent>` || ""}${this.isAgentEnabled("navigation") && v`<arcgis-assistant-agent .agent=${Cn} .context=${{ portal: n, user: o, navigationTargetMap: r }}></arcgis-assistant-agent>` || ""}${this.interrupt && v`<arcgis-portal-ai-assistant-interrupt slot=interrupt .type=${this.interrupt.type} .message=${this.interrupt.message} .options=${this.interrupt.options} @arcgisSubmit=${({ detail: l }) => {
|
|
2172
|
+
this.assistantEl.value?.submitInterrupt(l);
|
|
2162
2173
|
}} @arcgisCancel=${() => {
|
|
2163
2174
|
this.assistantEl.value?.cancelInterrupt();
|
|
2164
2175
|
}}></arcgis-portal-ai-assistant-interrupt>` || ""}</arcgis-assistant>`;
|
|
2165
2176
|
}
|
|
2166
2177
|
}
|
|
2167
|
-
|
|
2178
|
+
Ue("arcgis-portal-ai-assistant", qn);
|
|
2168
2179
|
export {
|
|
2169
|
-
|
|
2180
|
+
qn as ArcgisPortalAiAssistant
|
|
2170
2181
|
};
|