@arcgis/portal-components 5.2.0-next.87 → 5.2.0-next.89
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/5RYUVYNA.js +2 -0
- package/dist/cdn/{Y56BS6IQ.js → 6WGPYUA4.js} +76 -76
- package/dist/cdn/DC37QXXI.js +2 -0
- package/dist/cdn/{BBVFGC6Y.js → OFAEJ3GS.js} +1 -1
- package/dist/cdn/{2Q3FIPE2.js → RJPGQVI2.js} +1 -1
- package/dist/cdn/{LDIZD36E.js → S47JWYSF.js} +1 -1
- package/dist/cdn/index.js +1 -1
- package/dist/chunks/portal-browser-filter-date.js +63 -0
- package/dist/components/arcgis-portal-ai-assistant/customElement.d.ts +6 -0
- package/dist/components/arcgis-portal-ai-assistant/customElement.js +501 -498
- 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-navigation/customElement.js +74 -74
- 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 +2 -2
- package/dist/types/lumina.d.ts +2 -2
- package/dist/types/preact.d.ts +2 -2
- package/dist/types/react.d.ts +2 -2
- package/dist/types/stencil.d.ts +2 -2
- package/package.json +5 -5
- package/dist/cdn/25KISBCS.js +0 -2
- package/dist/cdn/C7XKSVMU.js +0 -2
|
@@ -1,27 +1,27 @@
|
|
|
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
|
|
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
16
|
import { s as _e, a as Ye } from "../../chunks/item.js";
|
|
17
17
|
import { g as He, e as Xe, i as Ze, c as et, a as tt } from "../../chunks/groups.js";
|
|
18
18
|
import at from "@arcgis/core/portal/Portal.js";
|
|
19
|
-
const
|
|
19
|
+
const Ie = (e) => {
|
|
20
20
|
const { portal: t, user: a } = e ?? {};
|
|
21
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
27
|
const nt = `
|
|
@@ -41,7 +41,7 @@ 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
|
-
}),
|
|
44
|
+
}), te = "portal-group-creation", ae = "approveAddMembers", st = async (e, t) => {
|
|
45
45
|
if (e.intentParams.intent !== "addMembers")
|
|
46
46
|
return {
|
|
47
47
|
status: "success",
|
|
@@ -53,7 +53,7 @@ Not added members:
|
|
|
53
53
|
status: "success",
|
|
54
54
|
outputMessage: "Create a group first, then add members using @mention usernames."
|
|
55
55
|
};
|
|
56
|
-
const n = e.intentParams.memberInfo.memberIdentifiers.map((
|
|
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,42 +77,42 @@ Do you want to continue?`, { hitlResponse: c } = t?.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
|
|
87
|
+
await g(
|
|
88
88
|
{ text: `Adding members ${ot(n)}...`, agentName: "group-creation" },
|
|
89
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
|
-
const f = (await
|
|
101
|
+
const f = (await b({
|
|
102
102
|
promptText: nt,
|
|
103
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 = `
|
|
@@ -141,7 +141,7 @@ 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("")
|
|
@@ -158,10 +158,10 @@ Failure reason:
|
|
|
158
158
|
outputMessage: "What title would you like for the new group?"
|
|
159
159
|
};
|
|
160
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 !==
|
|
162
|
-
const
|
|
163
|
-
agentId:
|
|
164
|
-
id:
|
|
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,48 +170,48 @@ 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
|
|
180
|
+
await g({ text: `Creating group "${a}"...`, agentName: "group-creation" }, t);
|
|
181
181
|
const r = t?.configurable?.context;
|
|
182
|
-
|
|
183
|
-
const { result:
|
|
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
|
|
190
|
+
const p = (await b({
|
|
191
191
|
promptText: ct,
|
|
192
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
|
|
214
|
+
const l = (await b({
|
|
215
215
|
promptText: it,
|
|
216
216
|
schema: ut,
|
|
217
217
|
modelTier: "fast",
|
|
@@ -219,15 +219,15 @@ Failure reason:
|
|
|
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
233
|
}, I = (e) => {
|
|
@@ -276,17 +276,17 @@ User message:
|
|
|
276
276
|
memberIdentifiers: s.array(s.string()).default([]),
|
|
277
277
|
clarifyMessage: s.string().default("")
|
|
278
278
|
}), gt = async (e, t) => {
|
|
279
|
-
await
|
|
280
|
-
const a = I(e.agentExecutionContext.messages).trim(), n = await
|
|
279
|
+
await g({ text: "Thinking about groups...", agentName: "group-creation" }, t);
|
|
280
|
+
const a = I(e.agentExecutionContext.messages).trim(), n = await b({
|
|
281
281
|
promptText: pt,
|
|
282
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
291
|
}, ht = [
|
|
292
292
|
"general",
|
|
@@ -312,7 +312,7 @@ User message:
|
|
|
312
312
|
"openData",
|
|
313
313
|
"hub",
|
|
314
314
|
"orgExtensions"
|
|
315
|
-
], ft = ["newItem", "createLayer", "developerCredentials"], yt = ["favorites", "group", "living-atlas", "org"], wt = ["featured", "my", "organization"],
|
|
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({
|
|
316
316
|
destinationType: s.literal("portal-content"),
|
|
317
317
|
hash: s.enum(yt).optional(),
|
|
318
318
|
queryParams: s.object({
|
|
@@ -323,7 +323,7 @@ User message:
|
|
|
323
323
|
hash: s.enum(wt).optional()
|
|
324
324
|
}), St = s.object({
|
|
325
325
|
destinationType: s.literal("portal-org"),
|
|
326
|
-
hash: s.enum(
|
|
326
|
+
hash: s.enum(vt).optional(),
|
|
327
327
|
queryParams: s.object({
|
|
328
328
|
tab: s.enum(ht).optional(),
|
|
329
329
|
section: s.string().optional(),
|
|
@@ -346,29 +346,29 @@ User message:
|
|
|
346
346
|
s.literal("portal-scene-viewer")
|
|
347
347
|
])
|
|
348
348
|
}), Ct = s.union([
|
|
349
|
-
|
|
349
|
+
bt,
|
|
350
350
|
It,
|
|
351
351
|
St,
|
|
352
352
|
xt,
|
|
353
353
|
Tt,
|
|
354
354
|
Mt
|
|
355
|
-
]),
|
|
355
|
+
]), Se = "portal-navigation", F = async (e, t) => {
|
|
356
356
|
const a = t?.configurable?.context;
|
|
357
|
-
!
|
|
357
|
+
!Ie(a) || !a.navigationTargetMap?.[e.destinationType] || await J({ type: Se, data: { ...e } }, t);
|
|
358
358
|
}, At = async (e, t) => {
|
|
359
359
|
const a = e.createdGroupId ?? e.agentExecutionContext.sharedState.createdGroupId?.value;
|
|
360
|
-
return a ? (await
|
|
361
|
-
},
|
|
362
|
-
...
|
|
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(),
|
|
363
363
|
// * Shared state between nodes (but not persisted to the agent execution context)
|
|
364
364
|
/** Parameters related to the user's intent for group creation actions */
|
|
365
|
-
intentParams: h({ reducer:
|
|
365
|
+
intentParams: h({ reducer: re, default: () => ({ intent: "clarify" }) }),
|
|
366
366
|
/** The ID of the group that was created
|
|
367
367
|
* even though we already have this in the shared state
|
|
368
368
|
* we still need it here to also share between nodes
|
|
369
369
|
*/
|
|
370
|
-
createdGroupId: h({ reducer:
|
|
371
|
-
}), Nt = () => new
|
|
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
372
|
switch (t.intentParams.intent) {
|
|
373
373
|
case "create":
|
|
374
374
|
return "createPortalGroup";
|
|
@@ -385,9 +385,9 @@ User message:
|
|
|
385
385
|
name: "Portal Group Creation",
|
|
386
386
|
description: Gt,
|
|
387
387
|
createGraph: Nt,
|
|
388
|
-
workspace:
|
|
389
|
-
},
|
|
390
|
-
const t = e?.[
|
|
388
|
+
workspace: xe
|
|
389
|
+
}, Te = "portalDocAssistantMemory", qt = () => ({ conversationId: "" }), Et = (e) => {
|
|
390
|
+
const t = e?.[Te]?.value;
|
|
391
391
|
if (!t || typeof t != "object")
|
|
392
392
|
return qt();
|
|
393
393
|
const a = t;
|
|
@@ -395,7 +395,7 @@ User message:
|
|
|
395
395
|
conversationId: typeof a.conversationId == "string" ? a.conversationId : ""
|
|
396
396
|
};
|
|
397
397
|
}, kt = (e) => ({
|
|
398
|
-
[
|
|
398
|
+
[Te]: { value: e }
|
|
399
399
|
}), zt = {
|
|
400
400
|
pipeline: {
|
|
401
401
|
follow_up: { allow: !1 }
|
|
@@ -410,69 +410,71 @@ function $t(e) {
|
|
|
410
410
|
}
|
|
411
411
|
};
|
|
412
412
|
}
|
|
413
|
+
const Dt = "https://www.arcgis.com/sharing/rest";
|
|
413
414
|
async function Rt({
|
|
414
415
|
portal: e,
|
|
415
416
|
question: t,
|
|
416
417
|
persona: a,
|
|
417
418
|
previousConversationId: n,
|
|
418
|
-
|
|
419
|
-
|
|
419
|
+
useProdDocAssistant: o,
|
|
420
|
+
signal: r,
|
|
421
|
+
skillId: i
|
|
420
422
|
}) {
|
|
421
|
-
|
|
422
|
-
const c = $t(a),
|
|
423
|
+
i ??= "doc_ai_assistant";
|
|
424
|
+
const c = $t(a), u = await Ut({
|
|
423
425
|
portal: e,
|
|
424
|
-
skillId:
|
|
426
|
+
skillId: i,
|
|
425
427
|
message: t,
|
|
426
|
-
options: { context: c, previousConversationId: n,
|
|
428
|
+
options: { context: c, previousConversationId: n, useProdDocAssistant: o, signal: r }
|
|
427
429
|
});
|
|
428
430
|
return {
|
|
429
|
-
reply:
|
|
430
|
-
conversationId:
|
|
431
|
+
reply: Ft(u, i),
|
|
432
|
+
conversationId: u[0]?.conversationId ?? ""
|
|
431
433
|
};
|
|
432
434
|
}
|
|
433
|
-
async function
|
|
435
|
+
async function Ut({
|
|
434
436
|
portal: e,
|
|
435
437
|
skillId: t,
|
|
436
438
|
message: a,
|
|
437
439
|
options: n
|
|
438
440
|
}) {
|
|
439
|
-
const
|
|
441
|
+
const o = e.helperServices.aiAssistantServices.url, i = `${n.useProdDocAssistant ? "https://aiservices-beta.arcgis.com" : o}/skills/${t}/chat`, u = {
|
|
440
442
|
"Content-Type": "application/json",
|
|
441
|
-
token:
|
|
442
|
-
},
|
|
443
|
+
token: n.useProdDocAssistant ? (await Z.getCredential(Dt, { oAuthPopupConfirmation: !1 })).token : Z.findCredential(e.url)?.token ?? ""
|
|
444
|
+
}, d = await ee(i, {
|
|
443
445
|
method: "post",
|
|
444
446
|
body: JSON.stringify({
|
|
445
447
|
message: a,
|
|
446
448
|
context: n.context,
|
|
447
449
|
conversationId: n.previousConversationId
|
|
448
450
|
}),
|
|
449
|
-
headers:
|
|
451
|
+
headers: u,
|
|
450
452
|
signal: n.signal
|
|
451
453
|
});
|
|
452
|
-
if (
|
|
453
|
-
throw new Error(`Doc assistant chat failed (${
|
|
454
|
-
cause:
|
|
454
|
+
if (d.httpStatus !== 200)
|
|
455
|
+
throw new Error(`Doc assistant chat failed (${d.httpStatus})`, {
|
|
456
|
+
cause: d.data
|
|
455
457
|
});
|
|
456
|
-
const l =
|
|
457
|
-
if (!
|
|
458
|
+
const l = d.data, p = [l], { conversationId: m, inquiryId: f } = l, y = async (M, q) => {
|
|
459
|
+
if (!q)
|
|
458
460
|
return;
|
|
459
461
|
await Je(500);
|
|
460
|
-
const
|
|
462
|
+
const T = await ee(i, {
|
|
461
463
|
method: "post",
|
|
462
|
-
body: JSON.stringify({ conversationId:
|
|
463
|
-
headers:
|
|
464
|
+
body: JSON.stringify({ conversationId: m, inquiryId: f, ackSequenceNumber: M }),
|
|
465
|
+
headers: u,
|
|
464
466
|
signal: n.signal
|
|
465
467
|
});
|
|
466
|
-
if (
|
|
467
|
-
throw new Error(`Doc assistant poll failed (${
|
|
468
|
-
cause:
|
|
468
|
+
if (T.httpStatus !== 200)
|
|
469
|
+
throw new Error(`Doc assistant poll failed (${T.httpStatus})`, {
|
|
470
|
+
cause: T.data
|
|
469
471
|
});
|
|
470
|
-
const
|
|
471
|
-
|
|
472
|
+
const C = T.data;
|
|
473
|
+
p.push(C), await y(C.sequenceNumber, C.hasMore);
|
|
472
474
|
};
|
|
473
|
-
return l.hasMore && await
|
|
475
|
+
return l.hasMore && await y(l.sequenceNumber, l.hasMore), p;
|
|
474
476
|
}
|
|
475
|
-
function
|
|
477
|
+
function Ft(e, t) {
|
|
476
478
|
switch (t) {
|
|
477
479
|
case "doc_chat":
|
|
478
480
|
return e.find((a) => a.message != null)?.message ?? "";
|
|
@@ -487,11 +489,11 @@ function Ut(e, t) {
|
|
|
487
489
|
}
|
|
488
490
|
return "";
|
|
489
491
|
default:
|
|
490
|
-
return
|
|
492
|
+
return U(t);
|
|
491
493
|
}
|
|
492
494
|
}
|
|
493
|
-
const
|
|
494
|
-
await
|
|
495
|
+
const Ot = async (e, t) => {
|
|
496
|
+
await g({ text: "Asking documentation assistant...", agentName: "doc-assistant" }, t);
|
|
495
497
|
const a = I(e.agentExecutionContext.messages).trim();
|
|
496
498
|
if (!a)
|
|
497
499
|
return {
|
|
@@ -499,30 +501,31 @@ const Ft = async (e, t) => {
|
|
|
499
501
|
outputMessage: "Please share your question and I can help with ArcGIS and Portal documentation."
|
|
500
502
|
};
|
|
501
503
|
const n = t?.configurable?.context;
|
|
502
|
-
|
|
503
|
-
const o = Et(e.agentExecutionContext.sharedState), { reply: r, conversationId:
|
|
504
|
+
x(n);
|
|
505
|
+
const o = Et(e.agentExecutionContext.sharedState), { reply: r, conversationId: i } = await Rt({
|
|
504
506
|
portal: n.portal,
|
|
505
507
|
question: a,
|
|
506
508
|
previousConversationId: o.conversationId || void 0,
|
|
507
509
|
skillId: "doc_ai_assistant",
|
|
508
|
-
persona: "doc-online"
|
|
510
|
+
persona: "doc-online",
|
|
511
|
+
useProdDocAssistant: n.useProdDocAssistant
|
|
509
512
|
});
|
|
510
513
|
return {
|
|
511
514
|
status: "success",
|
|
512
515
|
outputMessage: r.trim() || "I could not retrieve a response from the documentation assistant.",
|
|
513
516
|
sharedStatePatch: kt({
|
|
514
|
-
conversationId:
|
|
517
|
+
conversationId: i || o.conversationId
|
|
515
518
|
})
|
|
516
519
|
};
|
|
517
|
-
},
|
|
520
|
+
}, Me = be(
|
|
518
521
|
async ({ groupTitle: e }, t) => {
|
|
519
522
|
const a = e.trim();
|
|
520
523
|
if (!a)
|
|
521
524
|
return null;
|
|
522
525
|
const n = t?.configurable?.context;
|
|
523
|
-
|
|
526
|
+
x(n);
|
|
524
527
|
try {
|
|
525
|
-
return (await
|
|
528
|
+
return (await We(n.portal, { query: `title:${a}`, num: 1 }))?.results[0]?.id || null;
|
|
526
529
|
} catch (o) {
|
|
527
530
|
return console.error("Error searching for portal group by title:", o), null;
|
|
528
531
|
}
|
|
@@ -534,13 +537,13 @@ const Ft = async (e, t) => {
|
|
|
534
537
|
groupTitle: s.string().describe("The portal group title to resolve to a group id.")
|
|
535
538
|
})
|
|
536
539
|
}
|
|
537
|
-
),
|
|
540
|
+
), Ce = be(
|
|
538
541
|
async ({ itemTitle: e }, t) => {
|
|
539
542
|
const a = e.trim();
|
|
540
543
|
if (!a)
|
|
541
544
|
return null;
|
|
542
545
|
const n = t?.configurable?.context;
|
|
543
|
-
|
|
546
|
+
x(n);
|
|
544
547
|
const { result: o, error: r } = await _e(n.portal, a, { num: 1 });
|
|
545
548
|
return r && console.error("Error searching for portal item by title:", r), o?.results[0]?.id || null;
|
|
546
549
|
},
|
|
@@ -552,34 +555,34 @@ const Ft = async (e, t) => {
|
|
|
552
555
|
})
|
|
553
556
|
}
|
|
554
557
|
);
|
|
555
|
-
function
|
|
558
|
+
function A(e, t = "#") {
|
|
556
559
|
const a = e.match(new RegExp(`\\${t}"([^"]+)"`, "u"));
|
|
557
560
|
if (a?.[1])
|
|
558
561
|
return a[1].trim();
|
|
559
562
|
const n = e.match(new RegExp(`\\${t}([^\\s"']+)`, "u"));
|
|
560
563
|
return n?.[1] ? n[1].trim() : null;
|
|
561
564
|
}
|
|
562
|
-
function
|
|
563
|
-
const t =
|
|
565
|
+
function Lt(e) {
|
|
566
|
+
const t = Q(e).flatMap((a) => {
|
|
564
567
|
const n = a, o = e[a], r = [
|
|
565
568
|
n,
|
|
566
569
|
{
|
|
567
570
|
description: o.description,
|
|
568
571
|
hints: o.hints
|
|
569
572
|
}
|
|
570
|
-
],
|
|
571
|
-
const
|
|
572
|
-
return [`${n}-${
|
|
573
|
+
], i = o.sections ? Q(o.sections).map((c) => {
|
|
574
|
+
const u = o.sections?.[c];
|
|
575
|
+
return [`${n}-${c}`, u];
|
|
573
576
|
}) : [];
|
|
574
|
-
return [r, ...
|
|
577
|
+
return [r, ...i];
|
|
575
578
|
});
|
|
576
579
|
return Object.fromEntries(t);
|
|
577
580
|
}
|
|
578
|
-
function
|
|
581
|
+
function jt(e) {
|
|
579
582
|
return Object.entries(e).map(([t, { description: a, hints: n }]) => ` - ${t}: ${a} (hints: ${n.join(", ")})`).join(`
|
|
580
583
|
`);
|
|
581
584
|
}
|
|
582
|
-
const
|
|
585
|
+
const Vt = {
|
|
583
586
|
// Example prompt: "Take me to my content"
|
|
584
587
|
"portal-content": {
|
|
585
588
|
description: "The main content page of the portal.",
|
|
@@ -713,13 +716,13 @@ const jt = {
|
|
|
713
716
|
}
|
|
714
717
|
}
|
|
715
718
|
}
|
|
716
|
-
},
|
|
719
|
+
}, Ae = Lt(Vt), Bt = Q(Ae), Kt = jt(Ae), Qt = `
|
|
717
720
|
You decide whether the assistant response should include a navigation action to ArcGIS Portal.
|
|
718
721
|
|
|
719
722
|
Given the user question and assistant response:
|
|
720
723
|
- Decide if a navigation action would help the user complete the task.
|
|
721
724
|
- If yes, choose one destinationType:
|
|
722
|
-
${
|
|
725
|
+
${Kt}
|
|
723
726
|
|
|
724
727
|
Rules:
|
|
725
728
|
- Only suggest navigation when you are highly confident the destination will help complete the user's task.
|
|
@@ -742,35 +745,35 @@ User question:
|
|
|
742
745
|
|
|
743
746
|
Assistant response:
|
|
744
747
|
{response}
|
|
745
|
-
`,
|
|
748
|
+
`, se = s.object({
|
|
746
749
|
shouldSuggestNavigation: s.boolean().default(!1),
|
|
747
|
-
destinationType: s.enum(["none", ...
|
|
750
|
+
destinationType: s.enum(["none", ...Bt]).default("none"),
|
|
748
751
|
itemId: s.string().default(""),
|
|
749
752
|
groupId: s.string().default(""),
|
|
750
753
|
confidence: s.number().min(0).max(1).default(0)
|
|
751
|
-
}),
|
|
752
|
-
await
|
|
754
|
+
}), Wt = async (e, t) => {
|
|
755
|
+
await g({ text: "Extracting navigation intent...", agentName: "doc-assistant" }, t);
|
|
753
756
|
const a = e.outputMessage.trim();
|
|
754
757
|
if (!a)
|
|
755
758
|
return {};
|
|
756
|
-
const n = I(e.agentExecutionContext.messages).trim(), o = await
|
|
759
|
+
const n = I(e.agentExecutionContext.messages).trim(), o = await Y.fromTemplate(Qt).format({
|
|
757
760
|
question: n,
|
|
758
761
|
response: a
|
|
759
|
-
}),
|
|
760
|
-
if (!
|
|
762
|
+
}), i = (await _({ modelTier: "fast" })).withStructuredOutput(se), c = se.parse(await i.invoke(o));
|
|
763
|
+
if (!c.shouldSuggestNavigation || c.destinationType === "none")
|
|
761
764
|
return {};
|
|
762
|
-
if (
|
|
763
|
-
const
|
|
764
|
-
|
|
765
|
+
if (c.destinationType === "portal-item" && !c.itemId) {
|
|
766
|
+
const d = A(n, "#");
|
|
767
|
+
d && (c.itemId = await Ce.invoke({ itemTitle: d }, t) ?? "");
|
|
765
768
|
}
|
|
766
|
-
if (
|
|
767
|
-
const
|
|
768
|
-
|
|
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) ?? "");
|
|
769
772
|
}
|
|
770
|
-
const
|
|
771
|
-
return
|
|
773
|
+
const u = Jt(c);
|
|
774
|
+
return u ? (await F(u, t), {}) : {};
|
|
772
775
|
};
|
|
773
|
-
function
|
|
776
|
+
function Jt({
|
|
774
777
|
destinationType: e,
|
|
775
778
|
itemId: t,
|
|
776
779
|
groupId: a
|
|
@@ -796,7 +799,7 @@ function Wt({
|
|
|
796
799
|
case "portal-content-new-item-developer-credentials":
|
|
797
800
|
return {
|
|
798
801
|
queryParams: {
|
|
799
|
-
newItem:
|
|
802
|
+
newItem: _t[e]
|
|
800
803
|
},
|
|
801
804
|
destinationType: "portal-content"
|
|
802
805
|
};
|
|
@@ -804,11 +807,11 @@ function Wt({
|
|
|
804
807
|
case "portal-content-group":
|
|
805
808
|
case "portal-content-living-atlas":
|
|
806
809
|
case "portal-content-organization":
|
|
807
|
-
return { destinationType: "portal-content", hash:
|
|
810
|
+
return { destinationType: "portal-content", hash: Yt[e] };
|
|
808
811
|
case "portal-groups-featured":
|
|
809
812
|
case "portal-groups-my":
|
|
810
813
|
case "portal-groups-organization":
|
|
811
|
-
return { destinationType: "portal-groups", hash:
|
|
814
|
+
return { destinationType: "portal-groups", hash: Ht[e] };
|
|
812
815
|
case "portal-org-security-custom-sign-in":
|
|
813
816
|
case "portal-org-security-logins":
|
|
814
817
|
case "portal-org-security-change-login-provider":
|
|
@@ -820,7 +823,7 @@ function Wt({
|
|
|
820
823
|
hash: "settings",
|
|
821
824
|
queryParams: {
|
|
822
825
|
tab: "security",
|
|
823
|
-
subsection:
|
|
826
|
+
subsection: Xt[e]
|
|
824
827
|
}
|
|
825
828
|
};
|
|
826
829
|
case "portal-item":
|
|
@@ -830,54 +833,54 @@ function Wt({
|
|
|
830
833
|
case "none":
|
|
831
834
|
return null;
|
|
832
835
|
default:
|
|
833
|
-
return
|
|
836
|
+
return U(e);
|
|
834
837
|
}
|
|
835
838
|
}
|
|
836
|
-
const
|
|
839
|
+
const _t = {
|
|
837
840
|
"portal-content-new-item": "newItem",
|
|
838
841
|
"portal-content-new-item-feature-layer": "createLayer",
|
|
839
842
|
"portal-content-new-item-developer-credentials": "developerCredentials"
|
|
840
|
-
},
|
|
843
|
+
}, Yt = {
|
|
841
844
|
"portal-content-favorites": "favorites",
|
|
842
845
|
"portal-content-group": "group",
|
|
843
846
|
"portal-content-living-atlas": "living-atlas",
|
|
844
847
|
"portal-content-organization": "org"
|
|
845
|
-
},
|
|
848
|
+
}, Ht = {
|
|
846
849
|
"portal-groups-featured": "featured",
|
|
847
850
|
"portal-groups-my": "my",
|
|
848
851
|
"portal-groups-organization": "organization"
|
|
849
|
-
},
|
|
852
|
+
}, Xt = {
|
|
850
853
|
"portal-org-security-custom-sign-in": "customSignInSection",
|
|
851
854
|
"portal-org-security-logins": "loginsSection",
|
|
852
855
|
"portal-org-security-change-login-provider": "changeLoginProviderSection",
|
|
853
856
|
"portal-org-security-multifactor-auth": "multiFactorAuthSection",
|
|
854
857
|
"portal-org-security-multifactor-enforcement": "multifactorEnforcementSection",
|
|
855
858
|
"portal-org-security-multifactor-designated-admins": "multifactorDesignatedAdminsSection"
|
|
856
|
-
},
|
|
857
|
-
...
|
|
858
|
-
}),
|
|
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:
|
|
859
862
|
- answers general ArcGIS, Portal, Enterprise, and JavaScript SDK questions
|
|
860
863
|
- acts as a fallback when specialized agents are not applicable
|
|
861
|
-
`,
|
|
864
|
+
`, ta = {
|
|
862
865
|
id: "portal-doc-assistant",
|
|
863
866
|
name: "Portal Doc Assistant",
|
|
864
|
-
description:
|
|
865
|
-
createGraph:
|
|
866
|
-
workspace:
|
|
867
|
-
},
|
|
867
|
+
description: ea,
|
|
868
|
+
createGraph: Zt,
|
|
869
|
+
workspace: Ne
|
|
870
|
+
}, aa = () => ({ latestGroupId: null, memory: {} }), O = (e) => {
|
|
868
871
|
const t = e?.agentExecutionContext.sharedState.portalGroupSummaryMemory?.value;
|
|
869
|
-
return t ? { latestGroupId: t.latestGroupId, memory: t.memory } :
|
|
870
|
-
},
|
|
872
|
+
return t ? { latestGroupId: t.latestGroupId, memory: t.memory } : aa();
|
|
873
|
+
}, Ge = `
|
|
871
874
|
Shared markdown formatting rules:
|
|
872
875
|
- Use clear markdown headings (##) to separate sections.
|
|
873
876
|
- Use concise bullet points for lists of facts, counts, or signals.
|
|
874
877
|
- Emphasize key metrics with bold labels (for example: **Recent items:** 4).
|
|
875
878
|
- Keep wording direct and analytical; avoid filler language but make sure the language is friendly.
|
|
876
879
|
- Do not include raw internal IDs unless explicitly requested.
|
|
877
|
-
`,
|
|
880
|
+
`, na = `
|
|
878
881
|
You answer follow-up questions about ArcGIS group analytics.
|
|
879
882
|
|
|
880
|
-
${
|
|
883
|
+
${Ge}
|
|
881
884
|
|
|
882
885
|
Ground your answer in the provided group analytics summary and context.
|
|
883
886
|
If the answer is not available from the provided context, state that clearly and suggest what to check next.
|
|
@@ -899,14 +902,14 @@ Group full context:
|
|
|
899
902
|
|
|
900
903
|
Question:
|
|
901
904
|
{question}
|
|
902
|
-
`,
|
|
903
|
-
await
|
|
904
|
-
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);
|
|
905
908
|
return o ? {
|
|
906
909
|
status: "success",
|
|
907
|
-
outputMessage: (await
|
|
908
|
-
promptText:
|
|
909
|
-
schema:
|
|
910
|
+
outputMessage: (await b({
|
|
911
|
+
promptText: na,
|
|
912
|
+
schema: ra,
|
|
910
913
|
modelTier: "default",
|
|
911
914
|
inputVariables: {
|
|
912
915
|
summary: o.summary,
|
|
@@ -918,10 +921,10 @@ Question:
|
|
|
918
921
|
status: "success",
|
|
919
922
|
outputMessage: "I do not have group analytics context yet. Ask me to analyze a group first with analyze group <group id>."
|
|
920
923
|
};
|
|
921
|
-
},
|
|
924
|
+
}, ra = s.object({
|
|
922
925
|
answer: s.string(),
|
|
923
926
|
isRelevant: s.boolean()
|
|
924
|
-
}),
|
|
927
|
+
}), sa = `
|
|
925
928
|
Classify the user's request for ArcGIS Portal group analytics.
|
|
926
929
|
|
|
927
930
|
Rules:
|
|
@@ -950,41 +953,41 @@ hasAnalyticsContext:
|
|
|
950
953
|
|
|
951
954
|
User message:
|
|
952
955
|
{userMessage}
|
|
953
|
-
`,
|
|
954
|
-
await
|
|
955
|
-
const a = I(e.agentExecutionContext.messages), n = !!
|
|
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({
|
|
956
959
|
userMessage: a,
|
|
957
960
|
hasAnalyticsContext: String(n)
|
|
958
|
-
}),
|
|
959
|
-
let
|
|
960
|
-
if ((
|
|
961
|
-
const y =
|
|
962
|
-
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) ?? "");
|
|
963
966
|
}
|
|
964
|
-
const { intent:
|
|
967
|
+
const { intent: d, question: l } = c, p = d === "summarize" && !u, m = d === "followUp" && !(l ?? "").trim(), f = d === "clarify" || p || m;
|
|
965
968
|
return {
|
|
966
|
-
groupSummaryIntent: f ? "clarify" :
|
|
967
|
-
groupSummaryGroupId:
|
|
968
|
-
groupSummaryQuestion:
|
|
969
|
+
groupSummaryIntent: f ? "clarify" : d,
|
|
970
|
+
groupSummaryGroupId: u || null,
|
|
971
|
+
groupSummaryQuestion: l || "",
|
|
969
972
|
status: "success",
|
|
970
973
|
outputMessage: f ? "Please clarify with a group id or title" : ""
|
|
971
974
|
};
|
|
972
|
-
},
|
|
975
|
+
}, ie = s.object({
|
|
973
976
|
intent: s.enum(["summarize", "followUp", "navigation", "clarify"]),
|
|
974
977
|
groupId: s.string().default(""),
|
|
975
978
|
question: s.string().default("")
|
|
976
|
-
}),
|
|
977
|
-
const a =
|
|
978
|
-
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(
|
|
979
982
|
n ? { destinationType: "portal-group", groupId: n } : { destinationType: "portal-groups" },
|
|
980
983
|
t
|
|
981
984
|
), { status: "success" };
|
|
982
985
|
};
|
|
983
|
-
function
|
|
986
|
+
function Pe({ timestamp: e, now: t, windowMs: a }) {
|
|
984
987
|
return e ? t - e <= a : !1;
|
|
985
988
|
}
|
|
986
|
-
const
|
|
987
|
-
function
|
|
989
|
+
const ua = 720 * 60 * 60 * 1e3;
|
|
990
|
+
function la(e) {
|
|
988
991
|
const t = He(e);
|
|
989
992
|
return {
|
|
990
993
|
id: e.id ?? "",
|
|
@@ -1010,7 +1013,7 @@ function ua(e) {
|
|
|
1010
1013
|
}
|
|
1011
1014
|
};
|
|
1012
1015
|
}
|
|
1013
|
-
async function
|
|
1016
|
+
async function da(e) {
|
|
1014
1017
|
const t = { owner: e.owner ?? "", admins: [], users: [] };
|
|
1015
1018
|
try {
|
|
1016
1019
|
return await e.fetchMembers();
|
|
@@ -1018,7 +1021,7 @@ async function la(e) {
|
|
|
1018
1021
|
return console.warn("Unable to fetch group members for analytics context", a), t;
|
|
1019
1022
|
}
|
|
1020
1023
|
}
|
|
1021
|
-
function
|
|
1024
|
+
function pa(e) {
|
|
1022
1025
|
return e.map((t) => ({
|
|
1023
1026
|
id: t.id ?? "",
|
|
1024
1027
|
title: t.title ?? "Untitled",
|
|
@@ -1028,43 +1031,43 @@ function da(e) {
|
|
|
1028
1031
|
modified: t.modified?.getTime()
|
|
1029
1032
|
}));
|
|
1030
1033
|
}
|
|
1031
|
-
function
|
|
1034
|
+
function ma(e, t) {
|
|
1032
1035
|
return e.filter(
|
|
1033
|
-
(a) => a.modified ?
|
|
1036
|
+
(a) => a.modified ? Pe({ timestamp: a.modified, now: t, windowMs: ua }) : !1
|
|
1034
1037
|
);
|
|
1035
1038
|
}
|
|
1036
|
-
function
|
|
1039
|
+
function ga(e) {
|
|
1037
1040
|
const t = /* @__PURE__ */ new Map();
|
|
1038
1041
|
for (const a of e)
|
|
1039
1042
|
t.set(a.type, (t.get(a.type) ?? 0) + 1);
|
|
1040
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 }));
|
|
1041
1044
|
}
|
|
1042
|
-
async function
|
|
1043
|
-
const t = await e.queryItems({ num: 20, sortField: "modified", sortOrder: "desc" }), a =
|
|
1045
|
+
async function ha(e) {
|
|
1046
|
+
const t = await e.queryItems({ num: 20, sortField: "modified", sortOrder: "desc" }), a = pa(t.results), n = Date.now();
|
|
1044
1047
|
return {
|
|
1045
1048
|
total: t.total,
|
|
1046
1049
|
topItems: a,
|
|
1047
|
-
recentlyModifiedItems:
|
|
1048
|
-
topItemTypes:
|
|
1050
|
+
recentlyModifiedItems: ma(a, n),
|
|
1051
|
+
topItemTypes: ga(a)
|
|
1049
1052
|
};
|
|
1050
1053
|
}
|
|
1051
|
-
async function
|
|
1054
|
+
async function fa(e, t) {
|
|
1052
1055
|
if (!t)
|
|
1053
1056
|
return { error: { code: "missingGroupId", message: "Group id is required." } };
|
|
1054
1057
|
try {
|
|
1055
1058
|
const n = (await e.queryGroups({ query: `id:${t}`, num: 1 })).results[0];
|
|
1056
1059
|
if (!n)
|
|
1057
1060
|
return { error: { code: "groupNotFound", message: `No group found for id: ${t}` } };
|
|
1058
|
-
const o =
|
|
1059
|
-
return { result: { group: o, members: r, items:
|
|
1061
|
+
const o = la(n), r = await da(n), i = await ha(n);
|
|
1062
|
+
return { result: { group: o, members: r, items: i } };
|
|
1060
1063
|
} catch (a) {
|
|
1061
1064
|
return console.error("Error fetching portal group analytics context:", a), { error: { code: "unhandledError" } };
|
|
1062
1065
|
}
|
|
1063
1066
|
}
|
|
1064
|
-
const
|
|
1067
|
+
const ya = `
|
|
1065
1068
|
You summarize ArcGIS Portal groups based on structured context and deterministic activity signals.
|
|
1066
1069
|
|
|
1067
|
-
${
|
|
1070
|
+
${Ge}
|
|
1068
1071
|
|
|
1069
1072
|
Output format requirements:
|
|
1070
1073
|
- Return concise markdown with clear sections in this order:
|
|
@@ -1100,82 +1103,82 @@ Group context:
|
|
|
1100
1103
|
|
|
1101
1104
|
Deterministic signals:
|
|
1102
1105
|
{deterministicSignals}
|
|
1103
|
-
`,
|
|
1106
|
+
`, wa = 2160 * 60 * 60 * 1e3, va = async (e, t) => {
|
|
1104
1107
|
const a = e.groupSummaryGroupId;
|
|
1105
1108
|
if (!a)
|
|
1106
1109
|
return {
|
|
1107
1110
|
status: "success",
|
|
1108
1111
|
outputMessage: 'Please clarify with analyze group <group id>, analyze group $<title>, or analyze group $"<title with spaces>".'
|
|
1109
1112
|
};
|
|
1110
|
-
await
|
|
1113
|
+
await g({ text: `Analyzing group ${a}...`, agentName: "group-analytics" }, t);
|
|
1111
1114
|
const n = t?.configurable?.context;
|
|
1112
|
-
|
|
1113
|
-
const { result: o, error: r } = await
|
|
1115
|
+
x(n);
|
|
1116
|
+
const { result: o, error: r } = await fa(n.portal, a);
|
|
1114
1117
|
if (r || !o)
|
|
1115
|
-
return await
|
|
1118
|
+
return await g({ text: "Failed to fetch group context", agentName: "group-analytics" }, t), {
|
|
1116
1119
|
status: "success",
|
|
1117
1120
|
outputMessage: "Unable to retrieve group context for analytics."
|
|
1118
1121
|
};
|
|
1119
|
-
const { group:
|
|
1120
|
-
promptText:
|
|
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,
|
|
1121
1124
|
schema: ba,
|
|
1122
1125
|
modelTier: "default",
|
|
1123
1126
|
inputVariables: {
|
|
1124
1127
|
context: JSON.stringify(o),
|
|
1125
1128
|
deterministicSignals: JSON.stringify({
|
|
1126
1129
|
isGroupActive: f,
|
|
1127
|
-
isGroupRecentlyModified:
|
|
1128
|
-
hasRecentlyAddedOrUpdatedContent:
|
|
1129
|
-
recentItemCount:
|
|
1130
|
+
isGroupRecentlyModified: l,
|
|
1131
|
+
hasRecentlyAddedOrUpdatedContent: m,
|
|
1132
|
+
recentItemCount: p
|
|
1130
1133
|
})
|
|
1131
1134
|
}
|
|
1132
|
-
}), { followUpQuestions:
|
|
1135
|
+
}), { followUpQuestions: M, summary: q } = y, T = O(e), C = {
|
|
1133
1136
|
latestGroupId: a,
|
|
1134
1137
|
memory: {
|
|
1135
|
-
|
|
1136
|
-
[a]: { summary:
|
|
1138
|
+
...T.memory,
|
|
1139
|
+
[a]: { summary: q, followUpQuestions: M, fullContext: o }
|
|
1137
1140
|
}
|
|
1138
1141
|
};
|
|
1139
|
-
return
|
|
1142
|
+
return M.length && await J({ type: "suggested-prompts", data: { prompts: M } }, t), {
|
|
1140
1143
|
status: "success",
|
|
1141
|
-
outputMessage:
|
|
1142
|
-
sharedStatePatch: { portalGroupSummaryMemory: { value:
|
|
1144
|
+
outputMessage: q,
|
|
1145
|
+
sharedStatePatch: { portalGroupSummaryMemory: { value: C } }
|
|
1143
1146
|
};
|
|
1144
1147
|
}, ba = s.object({
|
|
1145
1148
|
summary: s.string(),
|
|
1146
1149
|
followUpQuestions: s.array(s.string()).default([])
|
|
1147
|
-
}),
|
|
1148
|
-
...
|
|
1150
|
+
}), L = (e, t) => t ?? e, qe = h.Root({
|
|
1151
|
+
...P(),
|
|
1149
1152
|
groupSummaryIntent: h({
|
|
1150
|
-
reducer:
|
|
1153
|
+
reducer: L,
|
|
1151
1154
|
default: () => "clarify"
|
|
1152
1155
|
}),
|
|
1153
1156
|
groupSummaryGroupId: h({
|
|
1154
|
-
reducer:
|
|
1157
|
+
reducer: L,
|
|
1155
1158
|
default: () => null
|
|
1156
1159
|
}),
|
|
1157
1160
|
groupSummaryQuestion: h({
|
|
1158
|
-
reducer:
|
|
1161
|
+
reducer: L,
|
|
1159
1162
|
default: () => ""
|
|
1160
1163
|
})
|
|
1161
|
-
}),
|
|
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:
|
|
1162
1165
|
- summarizes ArcGIS portal groups from group context and sourceJSON details
|
|
1163
1166
|
- answers follow-up questions grounded in the summarized group
|
|
1164
1167
|
- suggests navigation to groups when relevant
|
|
1165
|
-
`,
|
|
1168
|
+
`, xa = {
|
|
1166
1169
|
id: "portal-group-analytics",
|
|
1167
1170
|
name: "Portal Group Analytics",
|
|
1168
|
-
description:
|
|
1169
|
-
createGraph:
|
|
1170
|
-
workspace:
|
|
1171
|
-
},
|
|
1171
|
+
description: Sa,
|
|
1172
|
+
createGraph: Ia,
|
|
1173
|
+
workspace: qe
|
|
1174
|
+
}, Ta = () => ({ latestItemId: null, memory: {} }), H = (e) => {
|
|
1172
1175
|
const t = e?.agentExecutionContext.sharedState.portalItemAnalyticsSummaryMemory?.value;
|
|
1173
|
-
return t ? { latestItemId: t.latestItemId, memory: t.memory } :
|
|
1174
|
-
},
|
|
1176
|
+
return t ? { latestItemId: t.latestItemId, memory: t.memory } : Ta();
|
|
1177
|
+
}, ce = s.object({
|
|
1175
1178
|
intent: s.enum(["summarize", "followUp", "clarify"]),
|
|
1176
1179
|
itemId: s.string().default(""),
|
|
1177
1180
|
question: s.string().default("")
|
|
1178
|
-
}),
|
|
1181
|
+
}), Ma = s.object({ summary: s.string(), followUpQuestions: s.array(s.string()).default([]) }), Ca = s.object({ answer: s.string(), isRelevant: s.boolean() }), Aa = `
|
|
1179
1182
|
You answer follow-up questions about an ArcGIS item.
|
|
1180
1183
|
|
|
1181
1184
|
Ground your answer in the provided item context.
|
|
@@ -1195,14 +1198,14 @@ Item full context
|
|
|
1195
1198
|
|
|
1196
1199
|
Question:
|
|
1197
1200
|
{question}
|
|
1198
|
-
`,
|
|
1199
|
-
await
|
|
1200
|
-
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);
|
|
1201
1204
|
return o ? {
|
|
1202
1205
|
status: "success",
|
|
1203
|
-
outputMessage: (await
|
|
1204
|
-
promptText:
|
|
1205
|
-
schema:
|
|
1206
|
+
outputMessage: (await b({
|
|
1207
|
+
promptText: Aa,
|
|
1208
|
+
schema: Ca,
|
|
1206
1209
|
modelTier: "default",
|
|
1207
1210
|
inputVariables: {
|
|
1208
1211
|
summary: o.summary,
|
|
@@ -1214,7 +1217,7 @@ Question:
|
|
|
1214
1217
|
status: "success",
|
|
1215
1218
|
outputMessage: "I don't have enough information yet. Please ask me to summarize the item first using summarize item <item id>."
|
|
1216
1219
|
};
|
|
1217
|
-
},
|
|
1220
|
+
}, Ga = `
|
|
1218
1221
|
Classify the user analytics request.
|
|
1219
1222
|
|
|
1220
1223
|
Rules:
|
|
@@ -1244,27 +1247,27 @@ hasSummaryContext:
|
|
|
1244
1247
|
|
|
1245
1248
|
User message:
|
|
1246
1249
|
{userMessage}
|
|
1247
|
-
`,
|
|
1248
|
-
await
|
|
1249
|
-
const a = I(e.agentExecutionContext.messages), n = !!
|
|
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({
|
|
1250
1253
|
userMessage: a,
|
|
1251
1254
|
hasSummaryContext: String(n)
|
|
1252
|
-
}),
|
|
1253
|
-
let
|
|
1254
|
-
if (
|
|
1255
|
-
const y =
|
|
1256
|
-
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) ?? "");
|
|
1257
1260
|
}
|
|
1258
|
-
const { intent:
|
|
1261
|
+
const { intent: d, question: l } = c, f = d === "clarify" || d === "summarize" && !u || d === "followUp" && !l;
|
|
1259
1262
|
return {
|
|
1260
1263
|
agentExecutionContext: { ...e.agentExecutionContext },
|
|
1261
|
-
analyticsIntent: f ? "clarify" :
|
|
1262
|
-
analyticsItemId:
|
|
1263
|
-
analyticsQuestion:
|
|
1264
|
+
analyticsIntent: f ? "clarify" : d,
|
|
1265
|
+
analyticsItemId: u || null,
|
|
1266
|
+
analyticsQuestion: l || "",
|
|
1264
1267
|
status: "success",
|
|
1265
1268
|
outputMessage: f ? 'Please clarify with summarize item <item id>, summarize item #<title>, or summarize item #"<title with spaces>".' : ""
|
|
1266
1269
|
};
|
|
1267
|
-
},
|
|
1270
|
+
}, qa = `
|
|
1268
1271
|
You are a item summary tool for ArcGIS. Your job is to summarize an item's info based on the provided context.
|
|
1269
1272
|
Summary rules:
|
|
1270
1273
|
- The summary should be concise markdown, make sure to format the output nicely so it's easy to read.
|
|
@@ -1279,66 +1282,66 @@ Do not include internal identifiers.
|
|
|
1279
1282
|
If the user asks for a detailed summary, you may expand the response up to 300 words.
|
|
1280
1283
|
Item context:
|
|
1281
1284
|
{context}
|
|
1282
|
-
`,
|
|
1285
|
+
`, Ea = async (e, t) => {
|
|
1283
1286
|
const a = e.analyticsItemId;
|
|
1284
1287
|
if (!a)
|
|
1285
1288
|
return {
|
|
1286
1289
|
status: "success",
|
|
1287
1290
|
outputMessage: 'Please clarify with summarize item <item id>, summarize item #<title>, or summarize item #"<title with spaces>".'
|
|
1288
1291
|
};
|
|
1289
|
-
await
|
|
1292
|
+
await g({ text: `Summarizing item ${a}...`, agentName: "analytics" }, t);
|
|
1290
1293
|
const n = t?.configurable?.context;
|
|
1291
|
-
|
|
1292
|
-
const { portal: o, user: r } = n, { result:
|
|
1293
|
-
if (
|
|
1294
|
-
return await
|
|
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), {
|
|
1295
1298
|
status: "success",
|
|
1296
1299
|
outputMessage: "Unable to retrieve item context for summarization."
|
|
1297
1300
|
};
|
|
1298
|
-
const { context:
|
|
1299
|
-
promptText:
|
|
1300
|
-
schema:
|
|
1301
|
+
const { context: u } = i, d = await b({
|
|
1302
|
+
promptText: qa,
|
|
1303
|
+
schema: Ma,
|
|
1301
1304
|
modelTier: "default",
|
|
1302
|
-
inputVariables: { context: JSON.stringify(
|
|
1303
|
-
}), { followUpQuestions:
|
|
1305
|
+
inputVariables: { context: JSON.stringify(u) }
|
|
1306
|
+
}), { followUpQuestions: l, summary: p } = d, m = H(e), f = {
|
|
1304
1307
|
latestItemId: a,
|
|
1305
1308
|
memory: {
|
|
1306
|
-
...
|
|
1307
|
-
[a]: { summary:
|
|
1309
|
+
...m.memory,
|
|
1310
|
+
[a]: { summary: p, followUpQuestions: l, fullContext: u }
|
|
1308
1311
|
}
|
|
1309
1312
|
};
|
|
1310
|
-
return
|
|
1313
|
+
return l.length && await J({ type: "suggested-prompts", data: { prompts: l } }, t), {
|
|
1311
1314
|
status: "success",
|
|
1312
|
-
outputMessage:
|
|
1315
|
+
outputMessage: p,
|
|
1313
1316
|
sharedStatePatch: { portalItemAnalyticsSummaryMemory: { value: f } }
|
|
1314
1317
|
};
|
|
1315
|
-
},
|
|
1316
|
-
...
|
|
1318
|
+
}, j = (e, t) => t ?? e, Ee = h.Root({
|
|
1319
|
+
...P(),
|
|
1317
1320
|
// States shared only across nodes in the graph, not between invocations
|
|
1318
1321
|
analyticsIntent: h({
|
|
1319
|
-
reducer:
|
|
1322
|
+
reducer: j,
|
|
1320
1323
|
default: () => "clarify"
|
|
1321
1324
|
}),
|
|
1322
1325
|
analyticsItemId: h({
|
|
1323
|
-
reducer:
|
|
1326
|
+
reducer: j,
|
|
1324
1327
|
default: () => null
|
|
1325
1328
|
}),
|
|
1326
1329
|
analyticsQuestion: h({
|
|
1327
|
-
reducer:
|
|
1330
|
+
reducer: j,
|
|
1328
1331
|
default: () => ""
|
|
1329
1332
|
})
|
|
1330
|
-
}),
|
|
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:
|
|
1331
1334
|
- answers questions about one specific ArcGIS portal item when item context is present
|
|
1332
1335
|
- summarizes item details, metadata, and context grounded in that item
|
|
1333
1336
|
- suggests follow-up prompts grounded in the same item
|
|
1334
1337
|
- use for item-specific requests, not for gallery browsing, featured content, or opening Map Viewer
|
|
1335
|
-
`,
|
|
1338
|
+
`, $a = {
|
|
1336
1339
|
id: "portal-item-analytics",
|
|
1337
1340
|
name: "Portal Item Analytics",
|
|
1338
|
-
description:
|
|
1339
|
-
createGraph:
|
|
1340
|
-
workspace:
|
|
1341
|
-
},
|
|
1341
|
+
description: za,
|
|
1342
|
+
createGraph: ka,
|
|
1343
|
+
workspace: Ee
|
|
1344
|
+
}, Da = {
|
|
1342
1345
|
schemaVersion: "1.0",
|
|
1343
1346
|
capabilities: [
|
|
1344
1347
|
{
|
|
@@ -1432,7 +1435,7 @@ Item context:
|
|
|
1432
1435
|
}
|
|
1433
1436
|
}
|
|
1434
1437
|
]
|
|
1435
|
-
},
|
|
1438
|
+
}, Ua = {
|
|
1436
1439
|
schemaVersion: "1.0",
|
|
1437
1440
|
capabilities: [
|
|
1438
1441
|
{
|
|
@@ -1452,12 +1455,12 @@ Item context:
|
|
|
1452
1455
|
}
|
|
1453
1456
|
}
|
|
1454
1457
|
]
|
|
1455
|
-
},
|
|
1456
|
-
"contentRouteRegistry.ts":
|
|
1458
|
+
}, Fa = {
|
|
1459
|
+
"contentRouteRegistry.ts": Da,
|
|
1457
1460
|
"groupsRouteRegistry.ts": Ra,
|
|
1458
|
-
"orgSettingsRouteRegistry.ts":
|
|
1461
|
+
"orgSettingsRouteRegistry.ts": Ua
|
|
1459
1462
|
};
|
|
1460
|
-
function
|
|
1463
|
+
function ue(e) {
|
|
1461
1464
|
const t = [], a = /* @__PURE__ */ new Set();
|
|
1462
1465
|
for (const [n, o] of Object.entries(e))
|
|
1463
1466
|
for (const r of o.capabilities) {
|
|
@@ -1467,19 +1470,19 @@ function se(e) {
|
|
|
1467
1470
|
}
|
|
1468
1471
|
return t;
|
|
1469
1472
|
}
|
|
1470
|
-
let
|
|
1471
|
-
function
|
|
1472
|
-
return e ?
|
|
1473
|
+
let z;
|
|
1474
|
+
function S(e) {
|
|
1475
|
+
return e ? z = ue({ customCapabilities: e }) : z || (z = ue(Fa)), z;
|
|
1473
1476
|
}
|
|
1474
|
-
const
|
|
1475
|
-
function
|
|
1476
|
-
return e.toLowerCase().replace(/[^a-z0-9]+/gu, " ").trim().replace(
|
|
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();
|
|
1477
1480
|
}
|
|
1478
|
-
const
|
|
1481
|
+
const La = s.object({
|
|
1479
1482
|
capabilityIds: s.array(s.string()).default([]),
|
|
1480
1483
|
confidence: s.number().min(0).max(1).default(0),
|
|
1481
1484
|
reason: s.string().default("")
|
|
1482
|
-
}),
|
|
1485
|
+
}), le = 0.8, ja = String.raw`You select Portal navigation capabilities for a user's request.
|
|
1483
1486
|
|
|
1484
1487
|
Select only capability IDs from the supplied candidates. Return an empty array when none fit.
|
|
1485
1488
|
A named surface is required: do not select a capability on another Portal surface.
|
|
@@ -1489,45 +1492,45 @@ User request:
|
|
|
1489
1492
|
{userRequest}
|
|
1490
1493
|
|
|
1491
1494
|
Candidates:
|
|
1492
|
-
{candidates}`,
|
|
1495
|
+
{candidates}`, Va = async (e, t) => {
|
|
1493
1496
|
if (e.outputMessage || e.targets.length === 0)
|
|
1494
1497
|
return {};
|
|
1495
|
-
const a = I(e.agentExecutionContext.messages).trim(), n =
|
|
1498
|
+
const a = I(e.agentExecutionContext.messages).trim(), n = Ba(a, e);
|
|
1496
1499
|
if (n.length === 1)
|
|
1497
1500
|
return console.info("[arcgis-portal-ai-assistant] navigation capability selection:", {
|
|
1498
1501
|
method: "exact-match",
|
|
1499
1502
|
request: a,
|
|
1500
1503
|
selectedCapabilityIds: n
|
|
1501
1504
|
}), { chosenCapabilityIds: n };
|
|
1502
|
-
await
|
|
1505
|
+
await g({ text: "Choosing a navigation destination...", agentName: "navigation" }, t);
|
|
1503
1506
|
const o = JSON.stringify(
|
|
1504
|
-
e.targets.map(({ capability: r, keywordScore:
|
|
1507
|
+
e.targets.map(({ capability: r, keywordScore: i, semanticScore: c }) => ({
|
|
1505
1508
|
id: r.id,
|
|
1506
1509
|
title: r.title,
|
|
1507
1510
|
description: r.description,
|
|
1508
1511
|
route: r.resolutions.navigate,
|
|
1509
|
-
keywordScore:
|
|
1510
|
-
semanticScore:
|
|
1512
|
+
keywordScore: i,
|
|
1513
|
+
semanticScore: c
|
|
1511
1514
|
}))
|
|
1512
1515
|
);
|
|
1513
1516
|
try {
|
|
1514
|
-
const r = await
|
|
1515
|
-
promptText:
|
|
1516
|
-
schema:
|
|
1517
|
+
const r = await b({
|
|
1518
|
+
promptText: ja,
|
|
1519
|
+
schema: La,
|
|
1517
1520
|
modelTier: "fast",
|
|
1518
1521
|
inputVariables: { candidates: o, userRequest: a }
|
|
1519
|
-
}),
|
|
1522
|
+
}), i = new Set(e.targets.map(({ capability: u }) => u.id)), c = r.capabilityIds.filter((u) => i.has(u));
|
|
1520
1523
|
return console.info("[arcgis-portal-ai-assistant] navigation capability selection:", {
|
|
1521
1524
|
confidence: r.confidence,
|
|
1522
1525
|
method: "structured-model",
|
|
1523
1526
|
reason: r.reason,
|
|
1524
1527
|
request: a,
|
|
1525
|
-
selectedCapabilityIds:
|
|
1526
|
-
}), r.confidence <
|
|
1528
|
+
selectedCapabilityIds: c
|
|
1529
|
+
}), r.confidence < le ? {
|
|
1527
1530
|
chosenCapabilityIds: [],
|
|
1528
1531
|
status: "failed",
|
|
1529
|
-
summary: `Navigation selection confidence ${r.confidence} is below the required ${
|
|
1530
|
-
} : { chosenCapabilityIds:
|
|
1532
|
+
summary: `Navigation selection confidence ${r.confidence} is below the required ${le}; defer to the Portal Doc Assistant.`
|
|
1533
|
+
} : { chosenCapabilityIds: c };
|
|
1531
1534
|
} catch {
|
|
1532
1535
|
return console.info("[arcgis-portal-ai-assistant] navigation capability selection:", {
|
|
1533
1536
|
method: "structured-model-unavailable",
|
|
@@ -1536,19 +1539,19 @@ Candidates:
|
|
|
1536
1539
|
}), { chosenCapabilityIds: [] };
|
|
1537
1540
|
}
|
|
1538
1541
|
};
|
|
1539
|
-
function
|
|
1540
|
-
const a =
|
|
1542
|
+
function Ba(e, t) {
|
|
1543
|
+
const a = R(e);
|
|
1541
1544
|
return t.targets.filter(
|
|
1542
1545
|
({ capability: n }) => [n.title, ...n.hints].some(
|
|
1543
|
-
(o) =>
|
|
1546
|
+
(o) => R(o) === a
|
|
1544
1547
|
)
|
|
1545
1548
|
).map(({ capability: n }) => n.id);
|
|
1546
1549
|
}
|
|
1547
|
-
const
|
|
1550
|
+
const ke = /* @__PURE__ */ new Set(["1d", "7d", "14d", "30d", "3m", "6m"]), Ka = s.object({
|
|
1548
1551
|
period: s.string(),
|
|
1549
1552
|
startTime: s.string(),
|
|
1550
1553
|
endTime: s.string()
|
|
1551
|
-
}),
|
|
1554
|
+
}), Qa = String.raw`Extract temporal filters for an ArcGIS storage-credits query.
|
|
1552
1555
|
|
|
1553
1556
|
Return JSON only with these optional string fields:
|
|
1554
1557
|
- period
|
|
@@ -1574,14 +1577,14 @@ Now UTC:
|
|
|
1574
1577
|
|
|
1575
1578
|
User request:
|
|
1576
1579
|
{userRequest}`;
|
|
1577
|
-
async function
|
|
1580
|
+
async function Wa(e, t = /* @__PURE__ */ new Date()) {
|
|
1578
1581
|
const a = e.trim();
|
|
1579
1582
|
if (!a)
|
|
1580
1583
|
return {};
|
|
1581
1584
|
try {
|
|
1582
|
-
const n = await
|
|
1583
|
-
promptText:
|
|
1584
|
-
schema:
|
|
1585
|
+
const n = await b({
|
|
1586
|
+
promptText: Qa,
|
|
1587
|
+
schema: Ka,
|
|
1585
1588
|
modelTier: "fast",
|
|
1586
1589
|
inputVariables: {
|
|
1587
1590
|
nowEpochMs: String(t.getTime()),
|
|
@@ -1589,24 +1592,24 @@ async function Qa(e, t = /* @__PURE__ */ new Date()) {
|
|
|
1589
1592
|
userRequest: a
|
|
1590
1593
|
}
|
|
1591
1594
|
});
|
|
1592
|
-
return
|
|
1595
|
+
return Ja(n, t);
|
|
1593
1596
|
} catch (n) {
|
|
1594
1597
|
return console.error(n), {};
|
|
1595
1598
|
}
|
|
1596
1599
|
}
|
|
1597
|
-
function
|
|
1598
|
-
const a =
|
|
1600
|
+
function Ja(e, t = /* @__PURE__ */ new Date()) {
|
|
1601
|
+
const a = de(e.startTime), n = de(e.endTime), o = _a(e.period);
|
|
1599
1602
|
if (o) {
|
|
1600
1603
|
if (a !== void 0 && n !== void 0 && a < n)
|
|
1601
1604
|
return { period: o, startTime: String(a), endTime: String(n) };
|
|
1602
|
-
const r =
|
|
1603
|
-
if (!r || n !== void 0 && !
|
|
1604
|
-
const
|
|
1605
|
-
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)
|
|
1606
1609
|
return {
|
|
1607
1610
|
period: o,
|
|
1608
|
-
startTime: String(
|
|
1609
|
-
endTime: String(
|
|
1611
|
+
startTime: String(u),
|
|
1612
|
+
endTime: String(c)
|
|
1610
1613
|
};
|
|
1611
1614
|
}
|
|
1612
1615
|
return r ? {
|
|
@@ -1617,7 +1620,7 @@ function Wa(e, t = /* @__PURE__ */ new Date()) {
|
|
|
1617
1620
|
}
|
|
1618
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()) } : {};
|
|
1619
1622
|
}
|
|
1620
|
-
function
|
|
1623
|
+
function _a(e) {
|
|
1621
1624
|
const t = e?.trim().match(/^(\d+)\s*([dwm])$/iu);
|
|
1622
1625
|
if (!t)
|
|
1623
1626
|
return;
|
|
@@ -1627,12 +1630,12 @@ function Ja(e) {
|
|
|
1627
1630
|
const n = t[2].toLowerCase();
|
|
1628
1631
|
if (n === "w") {
|
|
1629
1632
|
const o = a * 7;
|
|
1630
|
-
if (
|
|
1633
|
+
if (ke.has(`${o}d`))
|
|
1631
1634
|
return `${o}d`;
|
|
1632
1635
|
}
|
|
1633
1636
|
return `${a}${n}`;
|
|
1634
1637
|
}
|
|
1635
|
-
function
|
|
1638
|
+
function Ya(e, t) {
|
|
1636
1639
|
const a = e.match(/^(\d+)([dwm])$/u);
|
|
1637
1640
|
if (!a)
|
|
1638
1641
|
return;
|
|
@@ -1647,25 +1650,25 @@ function _a(e, t) {
|
|
|
1647
1650
|
const r = new Date(t.getTime());
|
|
1648
1651
|
return r.setUTCMonth(r.getUTCMonth() - n), r.getTime();
|
|
1649
1652
|
}
|
|
1650
|
-
function
|
|
1653
|
+
function de(e) {
|
|
1651
1654
|
if (!e)
|
|
1652
1655
|
return;
|
|
1653
1656
|
const t = Number.parseInt(e, 10);
|
|
1654
1657
|
if (!(!Number.isFinite(t) || t <= 0))
|
|
1655
1658
|
return t;
|
|
1656
1659
|
}
|
|
1657
|
-
function
|
|
1660
|
+
function Ha(e, t) {
|
|
1658
1661
|
const a = new Date(e), n = new Date(t);
|
|
1659
1662
|
return a.getUTCFullYear() === n.getUTCFullYear() && a.getUTCMonth() === n.getUTCMonth() && a.getUTCDate() === n.getUTCDate();
|
|
1660
1663
|
}
|
|
1661
|
-
async function
|
|
1662
|
-
const n =
|
|
1664
|
+
async function Xa(e, t, a) {
|
|
1665
|
+
const n = S().find((r) => r.id === e);
|
|
1663
1666
|
if (!n)
|
|
1664
1667
|
return;
|
|
1665
|
-
const o = await Za(
|
|
1666
|
-
return o &&
|
|
1668
|
+
const o = await en(Za(n), a);
|
|
1669
|
+
return o && an(o, t) ? { capability: n, target: o } : void 0;
|
|
1667
1670
|
}
|
|
1668
|
-
function
|
|
1671
|
+
function Za(e) {
|
|
1669
1672
|
const { hash: t, queryParams: a, routeKey: n } = e.resolutions.navigate;
|
|
1670
1673
|
switch (n) {
|
|
1671
1674
|
case "content":
|
|
@@ -1703,10 +1706,10 @@ function Xa(e) {
|
|
|
1703
1706
|
return;
|
|
1704
1707
|
}
|
|
1705
1708
|
}
|
|
1706
|
-
async function
|
|
1707
|
-
if (!e || !t || !
|
|
1709
|
+
async function en(e, t) {
|
|
1710
|
+
if (!e || !t || !tn(e))
|
|
1708
1711
|
return e;
|
|
1709
|
-
const a = await
|
|
1712
|
+
const a = await Wa(t);
|
|
1710
1713
|
if (!a.period && !a.startTime && !a.endTime)
|
|
1711
1714
|
return e;
|
|
1712
1715
|
const n = {
|
|
@@ -1717,25 +1720,25 @@ async function Za(e, t) {
|
|
|
1717
1720
|
};
|
|
1718
1721
|
return { ...e, queryParams: n };
|
|
1719
1722
|
}
|
|
1720
|
-
function
|
|
1723
|
+
function tn(e) {
|
|
1721
1724
|
return e.destinationType === "portal-org" && e.hash === "status";
|
|
1722
1725
|
}
|
|
1723
|
-
function
|
|
1726
|
+
function an(e, t) {
|
|
1724
1727
|
return !t || !!t[e.destinationType];
|
|
1725
1728
|
}
|
|
1726
|
-
const
|
|
1729
|
+
const nn = async (e, t) => {
|
|
1727
1730
|
if (e.outputMessage || e.status === "failed")
|
|
1728
1731
|
return {};
|
|
1729
1732
|
const a = e.targets.find(({ capability: r }) => e.chosenCapabilityIds.includes(r.id)) ?? e.targets[0];
|
|
1730
1733
|
if (!a)
|
|
1731
1734
|
return {
|
|
1732
1735
|
outputMessage: "I couldn't find a matching Portal page. Try asking to open your content, groups, or organization settings.",
|
|
1733
|
-
sharedStatePatch: { navLastAnsweredRequest: { value:
|
|
1736
|
+
sharedStatePatch: { navLastAnsweredRequest: { value: pe(e) } },
|
|
1734
1737
|
status: "success",
|
|
1735
1738
|
summary: "Navigation could not find a matching capability; route another agent if appropriate."
|
|
1736
1739
|
};
|
|
1737
|
-
const n =
|
|
1738
|
-
return o ? (await
|
|
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), {
|
|
1739
1742
|
outputMessage: e.chosenCapabilityIds.length ? a.capability.description : `The closest place to start is ${a.capability.title}. Click the button below to open it.`,
|
|
1740
1743
|
status: "success",
|
|
1741
1744
|
summary: `Navigation suggested ${a.capability.id}${e.retrievalDegraded ? " using keyword-only retrieval" : ""}.`,
|
|
@@ -1747,17 +1750,17 @@ const an = async (e, t) => {
|
|
|
1747
1750
|
sharedStatePatch: { navLastAnsweredRequest: { value: n } }
|
|
1748
1751
|
});
|
|
1749
1752
|
};
|
|
1750
|
-
function
|
|
1753
|
+
function pe(e) {
|
|
1751
1754
|
return I(e.agentExecutionContext.messages) || e.agentExecutionContext.userRequest;
|
|
1752
1755
|
}
|
|
1753
|
-
async function
|
|
1754
|
-
return e.length === 0 ? [] : (await at.getDefault().load(), await
|
|
1756
|
+
async function ze(e) {
|
|
1757
|
+
return e.length === 0 ? [] : (await at.getDefault().load(), await Be(e));
|
|
1755
1758
|
}
|
|
1756
|
-
const
|
|
1759
|
+
const on = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1757
1760
|
__proto__: null,
|
|
1758
|
-
generateEmbeddings:
|
|
1761
|
+
generateEmbeddings: ze
|
|
1759
1762
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1760
|
-
function
|
|
1763
|
+
function rn(e) {
|
|
1761
1764
|
const t = [], a = `${e.title}. ${e.description}`;
|
|
1762
1765
|
a.trim().length > 0 && t.push({ field: "summary", text: a });
|
|
1763
1766
|
const n = e.hints;
|
|
@@ -1766,21 +1769,21 @@ function on(e) {
|
|
|
1766
1769
|
typeof o == "string" && o.trim().length > 0 && t.push({ field: "hint", text: o });
|
|
1767
1770
|
return t;
|
|
1768
1771
|
}
|
|
1769
|
-
let
|
|
1770
|
-
async function
|
|
1771
|
-
const t =
|
|
1772
|
-
return
|
|
1773
|
-
throw t ===
|
|
1774
|
-
}), 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 $;
|
|
1775
1778
|
}
|
|
1776
|
-
function
|
|
1777
|
-
return
|
|
1779
|
+
function cn() {
|
|
1780
|
+
return X;
|
|
1778
1781
|
}
|
|
1779
|
-
function
|
|
1780
|
-
|
|
1782
|
+
function me() {
|
|
1783
|
+
D += 1, X = void 0, $ = void 0;
|
|
1781
1784
|
}
|
|
1782
|
-
async function
|
|
1783
|
-
const t =
|
|
1785
|
+
async function un(e) {
|
|
1786
|
+
const t = dn(), a = await e(t.map((n) => n.text));
|
|
1784
1787
|
if (a.length !== t.length)
|
|
1785
1788
|
throw new Error(`Expected ${t.length} vectors, got ${a.length}`);
|
|
1786
1789
|
return t.map((n, o) => ({
|
|
@@ -1788,46 +1791,46 @@ async function cn(e) {
|
|
|
1788
1791
|
vector: a[o]
|
|
1789
1792
|
}));
|
|
1790
1793
|
}
|
|
1791
|
-
async function
|
|
1792
|
-
const { generateEmbeddings: t } = await Promise.resolve().then(() =>
|
|
1794
|
+
async function ln(e) {
|
|
1795
|
+
const { generateEmbeddings: t } = await Promise.resolve().then(() => on);
|
|
1793
1796
|
return await t(e);
|
|
1794
1797
|
}
|
|
1795
|
-
function
|
|
1796
|
-
return
|
|
1797
|
-
(e) =>
|
|
1798
|
+
function dn() {
|
|
1799
|
+
return S().flatMap(
|
|
1800
|
+
(e) => rn(e).map(({ field: t, text: a }) => ({
|
|
1798
1801
|
capabilityId: e.id,
|
|
1799
1802
|
field: t,
|
|
1800
1803
|
text: a
|
|
1801
1804
|
}))
|
|
1802
1805
|
);
|
|
1803
1806
|
}
|
|
1804
|
-
const
|
|
1807
|
+
const ge = 1.2, he = 0.75, pn = 60, mn = 0.65, V = {
|
|
1805
1808
|
description: 1,
|
|
1806
1809
|
hint: 2,
|
|
1807
1810
|
title: 3
|
|
1808
1811
|
};
|
|
1809
|
-
let
|
|
1810
|
-
function
|
|
1811
|
-
|
|
1812
|
+
let W;
|
|
1813
|
+
function gn() {
|
|
1814
|
+
W = void 0;
|
|
1812
1815
|
}
|
|
1813
|
-
async function
|
|
1814
|
-
const a =
|
|
1816
|
+
async function hn(e, t = {}) {
|
|
1817
|
+
const a = vn($e(e));
|
|
1815
1818
|
let n = [], o = !1, r;
|
|
1816
1819
|
if (e.trim()) {
|
|
1817
|
-
const
|
|
1818
|
-
if (!
|
|
1820
|
+
const i = t.loadEmbeddings, c = cn();
|
|
1821
|
+
if (!i && !c)
|
|
1819
1822
|
o = !0, r = "Capability embeddings are still loading.";
|
|
1820
1823
|
else
|
|
1821
1824
|
try {
|
|
1822
|
-
if (
|
|
1823
|
-
const [
|
|
1824
|
-
(t.embedQuery ??
|
|
1825
|
-
|
|
1825
|
+
if (i) {
|
|
1826
|
+
const [u, d] = await Promise.all([
|
|
1827
|
+
(t.embedQuery ?? ye)(e),
|
|
1828
|
+
i()
|
|
1826
1829
|
]);
|
|
1827
|
-
n =
|
|
1828
|
-
} else if (
|
|
1829
|
-
const
|
|
1830
|
-
n =
|
|
1830
|
+
n = fe(u, d);
|
|
1831
|
+
} else if (c) {
|
|
1832
|
+
const u = await (t.embedQuery ?? ye)(e);
|
|
1833
|
+
n = fe(u, c);
|
|
1831
1834
|
}
|
|
1832
1835
|
} catch {
|
|
1833
1836
|
o = !0, r = "Semantic search is unavailable.";
|
|
@@ -1838,23 +1841,23 @@ async function gn(e, t = {}) {
|
|
|
1838
1841
|
...r ? { degradedReason: r } : {},
|
|
1839
1842
|
// RRF combines ranks rather than raw scores because BM25 and cosine
|
|
1840
1843
|
// similarity are on different scales.
|
|
1841
|
-
matches:
|
|
1844
|
+
matches: In(a, n, t.topN ?? 5)
|
|
1842
1845
|
};
|
|
1843
1846
|
}
|
|
1844
|
-
function
|
|
1845
|
-
return
|
|
1847
|
+
function fn() {
|
|
1848
|
+
return W ??= yn(S()), W;
|
|
1846
1849
|
}
|
|
1847
|
-
function
|
|
1850
|
+
function yn(e) {
|
|
1848
1851
|
const t = /* @__PURE__ */ new Map(), a = e.map((n) => {
|
|
1849
1852
|
const o = /* @__PURE__ */ new Map();
|
|
1850
|
-
|
|
1853
|
+
B(o, n.title, V.title), B(o, n.description, V.description);
|
|
1851
1854
|
for (const r of n.hints)
|
|
1852
|
-
|
|
1855
|
+
B(o, r, V.hint);
|
|
1853
1856
|
for (const r of o.keys())
|
|
1854
1857
|
t.set(r, (t.get(r) ?? 0) + 1);
|
|
1855
1858
|
return {
|
|
1856
1859
|
capability: n,
|
|
1857
|
-
length:
|
|
1860
|
+
length: wn(o),
|
|
1858
1861
|
termFrequencies: o
|
|
1859
1862
|
};
|
|
1860
1863
|
});
|
|
@@ -1864,91 +1867,91 @@ function fn(e) {
|
|
|
1864
1867
|
documents: a
|
|
1865
1868
|
};
|
|
1866
1869
|
}
|
|
1867
|
-
function
|
|
1868
|
-
for (const n of
|
|
1870
|
+
function B(e, t, a) {
|
|
1871
|
+
for (const n of $e(t))
|
|
1869
1872
|
e.set(n, (e.get(n) ?? 0) + a);
|
|
1870
1873
|
}
|
|
1871
|
-
function
|
|
1874
|
+
function wn(e) {
|
|
1872
1875
|
return [...e.values()].reduce((t, a) => t + a, 0);
|
|
1873
1876
|
}
|
|
1874
|
-
function
|
|
1877
|
+
function $e(e) {
|
|
1875
1878
|
return e.toLowerCase().split(/[^a-z0-9]+/u).filter(Boolean);
|
|
1876
1879
|
}
|
|
1877
|
-
function
|
|
1878
|
-
const t =
|
|
1879
|
-
return t.documents.map(({ capability: o, length: r, termFrequencies:
|
|
1880
|
-
let
|
|
1881
|
-
for (const
|
|
1882
|
-
const
|
|
1883
|
-
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)
|
|
1884
1887
|
continue;
|
|
1885
|
-
const
|
|
1886
|
-
|
|
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));
|
|
1887
1890
|
}
|
|
1888
|
-
return { capability: o, score:
|
|
1889
|
-
}).filter(({ score: o }) => o > 0).sort(
|
|
1891
|
+
return { capability: o, score: c };
|
|
1892
|
+
}).filter(({ score: o }) => o > 0).sort(De);
|
|
1890
1893
|
}
|
|
1891
|
-
function
|
|
1894
|
+
function fe(e, t) {
|
|
1892
1895
|
const a = /* @__PURE__ */ new Map();
|
|
1893
1896
|
for (const o of t) {
|
|
1894
1897
|
const r = bn(e, o.vector);
|
|
1895
1898
|
if (r === void 0)
|
|
1896
1899
|
continue;
|
|
1897
|
-
const
|
|
1898
|
-
(
|
|
1900
|
+
const i = a.get(o.capabilityId);
|
|
1901
|
+
(i === void 0 || r > i) && a.set(o.capabilityId, r);
|
|
1899
1902
|
}
|
|
1900
|
-
const n = new Map(
|
|
1903
|
+
const n = new Map(S().map((o) => [o.id, o]));
|
|
1901
1904
|
return [...a.entries()].flatMap(([o, r]) => {
|
|
1902
|
-
const
|
|
1903
|
-
return
|
|
1904
|
-
}).sort(
|
|
1905
|
+
const i = n.get(o);
|
|
1906
|
+
return i && r >= mn ? [{ capability: i, score: r }] : [];
|
|
1907
|
+
}).sort(De);
|
|
1905
1908
|
}
|
|
1906
1909
|
function bn(e, t) {
|
|
1907
1910
|
if (e.length === 0 || e.length !== t.length)
|
|
1908
1911
|
return;
|
|
1909
1912
|
let a = 0, n = 0, o = 0;
|
|
1910
|
-
for (let
|
|
1911
|
-
a += e[
|
|
1913
|
+
for (let i = 0; i < e.length; i += 1)
|
|
1914
|
+
a += e[i] * t[i], n += e[i] ** 2, o += t[i] ** 2;
|
|
1912
1915
|
const r = Math.sqrt(n) * Math.sqrt(o);
|
|
1913
1916
|
return r === 0 ? void 0 : a / r;
|
|
1914
1917
|
}
|
|
1915
|
-
async function
|
|
1916
|
-
const [t] = await
|
|
1918
|
+
async function ye(e) {
|
|
1919
|
+
const [t] = await ze([e]);
|
|
1917
1920
|
if (!t)
|
|
1918
1921
|
throw new Error("Expected one query embedding.");
|
|
1919
1922
|
return t;
|
|
1920
1923
|
}
|
|
1921
|
-
function
|
|
1924
|
+
function In(e, t, a) {
|
|
1922
1925
|
const n = /* @__PURE__ */ new Map();
|
|
1923
|
-
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));
|
|
1924
1927
|
}
|
|
1925
|
-
function
|
|
1928
|
+
function we(e, t, a) {
|
|
1926
1929
|
for (const [n, { capability: o, score: r }] of t.entries()) {
|
|
1927
|
-
const
|
|
1928
|
-
|
|
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);
|
|
1929
1932
|
}
|
|
1930
1933
|
}
|
|
1931
|
-
function
|
|
1934
|
+
function De(e, t) {
|
|
1932
1935
|
return t.score - e.score || e.capability.id.localeCompare(t.capability.id);
|
|
1933
1936
|
}
|
|
1934
|
-
const
|
|
1935
|
-
await
|
|
1937
|
+
const Sn = async (e, t) => {
|
|
1938
|
+
await g({ text: "Finding a place to navigate...", agentName: "navigation" }, t);
|
|
1936
1939
|
const a = I(e.agentExecutionContext.messages).trim();
|
|
1937
1940
|
try {
|
|
1938
|
-
const n = await
|
|
1941
|
+
const n = await hn(a, { topN: 5 });
|
|
1939
1942
|
return console.table(
|
|
1940
|
-
n.matches.map(({ capability: o, keywordRank: r, keywordScore:
|
|
1943
|
+
n.matches.map(({ capability: o, keywordRank: r, keywordScore: i, semanticRank: c, semanticScore: u, score: d }) => ({
|
|
1941
1944
|
capability: o.title,
|
|
1942
|
-
fusedScore:
|
|
1945
|
+
fusedScore: d,
|
|
1943
1946
|
keywordRank: r,
|
|
1944
|
-
keywordScore:
|
|
1945
|
-
semanticRank:
|
|
1946
|
-
semanticScore:
|
|
1947
|
+
keywordScore: i,
|
|
1948
|
+
semanticRank: c,
|
|
1949
|
+
semanticScore: u
|
|
1947
1950
|
}))
|
|
1948
1951
|
), n.degradedReason && console.info("[arcgis-portal-ai-assistant] navigation semantic search:", n.degradedReason), {
|
|
1949
1952
|
chosenCapabilityIds: [],
|
|
1950
1953
|
retrievalDegraded: n.degradedReason ?? "",
|
|
1951
|
-
targets:
|
|
1954
|
+
targets: xn(a, n.matches)
|
|
1952
1955
|
};
|
|
1953
1956
|
} catch {
|
|
1954
1957
|
return {
|
|
@@ -1959,10 +1962,10 @@ const In = async (e, t) => {
|
|
|
1959
1962
|
};
|
|
1960
1963
|
}
|
|
1961
1964
|
};
|
|
1962
|
-
function
|
|
1963
|
-
const a =
|
|
1965
|
+
function xn(e, t) {
|
|
1966
|
+
const a = R(e), n = t.filter(
|
|
1964
1967
|
({ capability: r }) => [r.title, ...r.hints].some(
|
|
1965
|
-
(
|
|
1968
|
+
(i) => R(i) === a
|
|
1966
1969
|
)
|
|
1967
1970
|
);
|
|
1968
1971
|
if (n.length !== 1)
|
|
@@ -1970,16 +1973,16 @@ function Sn(e, t) {
|
|
|
1970
1973
|
const [o] = n;
|
|
1971
1974
|
return [o, ...t.filter((r) => r !== o)];
|
|
1972
1975
|
}
|
|
1973
|
-
const
|
|
1974
|
-
...
|
|
1975
|
-
chosenCapabilityIds: h({ reducer:
|
|
1976
|
+
const K = (e, t) => t ?? e, Re = h.Root({
|
|
1977
|
+
...P(),
|
|
1978
|
+
chosenCapabilityIds: h({ reducer: K, default: () => [] }),
|
|
1976
1979
|
// Empty when hybrid keyword-and-semantic retrieval succeeds; otherwise
|
|
1977
1980
|
// contains the semantic-search failure reason for response diagnostics.
|
|
1978
|
-
retrievalDegraded: h({ reducer:
|
|
1979
|
-
targets: h({ reducer:
|
|
1980
|
-
}),
|
|
1981
|
-
function
|
|
1982
|
-
const e =
|
|
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);
|
|
1984
|
+
function Mn() {
|
|
1985
|
+
const e = S().map(({ hints: t, title: a }) => t[0] ?? a).join(", ");
|
|
1983
1986
|
return String.raw`- **portal-navigation** - Portal page navigation assistant:
|
|
1984
1987
|
- routes requests to open, show, or navigate to a Portal page, including creation-flow pages
|
|
1985
1988
|
- falls back to the closest Portal page where a workflow starts when another agent cannot perform the action
|
|
@@ -1988,16 +1991,16 @@ function Tn() {
|
|
|
1988
1991
|
- do not use for general "how do I" questions unless the user explicitly asks to reach a page
|
|
1989
1992
|
`;
|
|
1990
1993
|
}
|
|
1991
|
-
const
|
|
1994
|
+
const Cn = {
|
|
1992
1995
|
id: "navigation",
|
|
1993
1996
|
name: "Portal Navigation",
|
|
1994
1997
|
get description() {
|
|
1995
|
-
return
|
|
1998
|
+
return Mn();
|
|
1996
1999
|
},
|
|
1997
|
-
createGraph:
|
|
1998
|
-
workspace:
|
|
1999
|
-
},
|
|
2000
|
-
function
|
|
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) {
|
|
2001
2004
|
if (!t)
|
|
2002
2005
|
return;
|
|
2003
2006
|
const { destinationType: a } = e;
|
|
@@ -2019,14 +2022,14 @@ function An(e, t) {
|
|
|
2019
2022
|
case "portal-group":
|
|
2020
2023
|
return t[a]?.(e.groupId);
|
|
2021
2024
|
default:
|
|
2022
|
-
return
|
|
2025
|
+
return U(a);
|
|
2023
2026
|
}
|
|
2024
2027
|
}
|
|
2025
|
-
function
|
|
2028
|
+
function Gn(e) {
|
|
2026
2029
|
const t = Ct.safeParse(e);
|
|
2027
2030
|
return t.success ? t.data : void 0;
|
|
2028
2031
|
}
|
|
2029
|
-
function
|
|
2032
|
+
function Pn(e, t) {
|
|
2030
2033
|
const a = t.navigation;
|
|
2031
2034
|
switch (e.destinationType) {
|
|
2032
2035
|
case "portal-content":
|
|
@@ -2068,24 +2071,24 @@ function Gn(e, t) {
|
|
|
2068
2071
|
case "portal-group":
|
|
2069
2072
|
return a.openGroup;
|
|
2070
2073
|
default:
|
|
2071
|
-
return
|
|
2074
|
+
return U(e);
|
|
2072
2075
|
}
|
|
2073
2076
|
}
|
|
2074
|
-
class
|
|
2077
|
+
class qn extends Fe {
|
|
2075
2078
|
constructor() {
|
|
2076
|
-
super(), this.t9n =
|
|
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) => {
|
|
2077
2080
|
const a = t.detail, n = a.data?.block;
|
|
2078
2081
|
if (!n)
|
|
2079
2082
|
return;
|
|
2080
2083
|
const o = this.getNavigationAction(n);
|
|
2081
2084
|
o && this.upsertNavigationSlotElement(a.slotName, o);
|
|
2082
|
-
}, 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();
|
|
2083
2086
|
}
|
|
2084
2087
|
static {
|
|
2085
|
-
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 };
|
|
2086
2089
|
}
|
|
2087
2090
|
static {
|
|
2088
|
-
this.styles =
|
|
2091
|
+
this.styles = An;
|
|
2089
2092
|
}
|
|
2090
2093
|
async load() {
|
|
2091
2094
|
await this.refreshCapabilityEmbeddings();
|
|
@@ -2094,30 +2097,30 @@ class Pn extends Ue {
|
|
|
2094
2097
|
!this.hasUpdated || !t.has("navigationCapabilities") || this.refreshCapabilityEmbeddings();
|
|
2095
2098
|
}
|
|
2096
2099
|
async clearEmbeddingsCache() {
|
|
2097
|
-
|
|
2100
|
+
me();
|
|
2098
2101
|
}
|
|
2099
2102
|
isAgentEnabled(t) {
|
|
2100
2103
|
return !this.disabledAgents?.[t];
|
|
2101
2104
|
}
|
|
2102
2105
|
async refreshCapabilityEmbeddings() {
|
|
2103
2106
|
try {
|
|
2104
|
-
|
|
2107
|
+
S(this.navigationCapabilities), gn(), me(), await sn();
|
|
2105
2108
|
} catch (t) {
|
|
2106
2109
|
console.warn("[arcgis-portal-ai-assistant] embeddings warm-up failed:", t);
|
|
2107
2110
|
}
|
|
2108
2111
|
}
|
|
2109
2112
|
getNavigationAction(t) {
|
|
2110
|
-
if (t?.type !==
|
|
2113
|
+
if (t?.type !== Se)
|
|
2111
2114
|
return;
|
|
2112
|
-
const a = t.data, n =
|
|
2115
|
+
const a = t.data, n = Gn(a);
|
|
2113
2116
|
if (!n)
|
|
2114
2117
|
return;
|
|
2115
|
-
const o =
|
|
2118
|
+
const o = Nn(a, this.navigationTargetMap);
|
|
2116
2119
|
if (o)
|
|
2117
2120
|
return {
|
|
2118
2121
|
href: o,
|
|
2119
2122
|
targetDetail: a,
|
|
2120
|
-
label: a?.buttonLabel ||
|
|
2123
|
+
label: a?.buttonLabel || Pn(n, this.t9n)
|
|
2121
2124
|
};
|
|
2122
2125
|
}
|
|
2123
2126
|
upsertNavigationSlotElement(t, a) {
|
|
@@ -2126,53 +2129,53 @@ class Pn extends Ue {
|
|
|
2126
2129
|
return;
|
|
2127
2130
|
const o = `navigation:${t}`;
|
|
2128
2131
|
let r = this.navigationSlotElements.get(o);
|
|
2129
|
-
r || (r = document.createElement("div"), r.slot = t, this.navigationSlotElements.set(o, r), n.append(r)),
|
|
2130
|
-
|
|
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({
|
|
2131
2134
|
href: a.href,
|
|
2132
2135
|
targetDetail: a.targetDetail
|
|
2133
2136
|
});
|
|
2134
|
-
}}>${a.label}</calcite-button>${a.description ?
|
|
2137
|
+
}}>${a.label}</calcite-button>${a.description ? v`<div class="navigation-block-description">${a.description}</div>` : null}</div>`, r);
|
|
2135
2138
|
}
|
|
2136
2139
|
render() {
|
|
2137
|
-
const { t9n: t, inputText: a, portal: n, user: o, navigationTargetMap: r, showVoiceInput:
|
|
2138
|
-
return
|
|
2139
|
-
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;
|
|
2140
2143
|
}} @arcgisInterruptCancel=${() => {
|
|
2141
2144
|
this.interrupt = null;
|
|
2142
2145
|
}} @arcgisInterruptSubmit=${() => {
|
|
2143
2146
|
this.interrupt = null;
|
|
2144
|
-
}} @arcgisPromptSelect=${({ detail:
|
|
2145
|
-
this.inputText =
|
|
2147
|
+
}} @arcgisPromptSelect=${({ detail: l }) => {
|
|
2148
|
+
this.inputText = l.prompt, requestAnimationFrame(() => {
|
|
2146
2149
|
this.inputEl.value?.focusTextArea();
|
|
2147
2150
|
});
|
|
2148
|
-
}} ${
|
|
2149
|
-
|
|
2150
|
-
const
|
|
2151
|
-
|
|
2152
|
-
}} ${
|
|
2153
|
-
|
|
2154
|
-
}} @arcgisUserMentionableTextAreaChange=${({ detail:
|
|
2155
|
-
this.inputText =
|
|
2156
|
-
}} ${
|
|
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=${() => {
|
|
2157
2160
|
this.isListening = !0, this.isVoiceInputDisabled = !1;
|
|
2158
2161
|
}} @arcgisVoiceInputStop=${() => {
|
|
2159
2162
|
this.isListening = !1, this.isVoiceInputDisabled = !1;
|
|
2160
|
-
}} @arcgisVoiceInputError=${(
|
|
2161
|
-
|
|
2162
|
-
}} @arcgisVoiceInputInterimTranscription=${(
|
|
2163
|
-
this.inputText =
|
|
2164
|
-
}} ${
|
|
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 () => {
|
|
2165
2168
|
this.isVoiceInputDisabled = !0;
|
|
2166
|
-
const
|
|
2167
|
-
|
|
2168
|
-
}}></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") &&
|
|
2169
|
-
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);
|
|
2170
2173
|
}} @arcgisCancel=${() => {
|
|
2171
2174
|
this.assistantEl.value?.cancelInterrupt();
|
|
2172
2175
|
}}></arcgis-portal-ai-assistant-interrupt>` || ""}</arcgis-assistant>`;
|
|
2173
2176
|
}
|
|
2174
2177
|
}
|
|
2175
|
-
|
|
2178
|
+
Ue("arcgis-portal-ai-assistant", qn);
|
|
2176
2179
|
export {
|
|
2177
|
-
|
|
2180
|
+
qn as ArcgisPortalAiAssistant
|
|
2178
2181
|
};
|