@arcgis/portal-components 5.2.0-next.65 → 5.2.0-next.67
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/2BUE3JLM.js +2 -0
- package/dist/cdn/{Y7FCEDRU.js → 2OU5PLGU.js} +1 -1
- package/dist/cdn/2WI5FBDF.js +2 -0
- package/dist/cdn/3VHBMKYX.js +2 -0
- package/dist/cdn/64DIXKV3.js +2 -0
- package/dist/cdn/6KVA4AKM.js +2 -0
- package/dist/cdn/6TO2BYXU.js +2 -0
- package/dist/cdn/AR6YIWRX.js +2 -0
- package/dist/cdn/CYCKQHLO.js +2 -0
- package/dist/cdn/{ZV4GLQQG.js → D4VYYWA6.js} +1 -1
- package/dist/cdn/DEOAKHYN.js +2 -0
- package/dist/cdn/FKVT4PNP.js +2 -0
- package/dist/cdn/GC6YLNZF.js +2 -0
- package/dist/cdn/{VD6VGWCQ.js → JMEXULSL.js} +1 -1
- package/dist/cdn/KTBQ26TD.js +2 -0
- package/dist/cdn/LRADZ46B.js +2 -0
- package/dist/cdn/NWT7EITA.js +2 -0
- package/dist/cdn/{EE7XFMJG.js → O5AP2PN5.js} +1 -1
- package/dist/cdn/OUNIRHWU.js +2 -0
- package/dist/cdn/{XW42SAEJ.js → QFI3ZPNB.js} +1 -1
- package/dist/cdn/QMFRNHQJ.js +2 -0
- package/dist/cdn/QNA62UMC.js +2 -0
- package/dist/cdn/{6RLJVPF6.js → QWMWVF47.js} +1 -1
- package/dist/cdn/RWQL7W3X.js +2 -0
- package/dist/cdn/T6Z7IFG2.js +2 -0
- package/dist/cdn/USQ4RJYL.js +2 -0
- package/dist/cdn/{Q7SDLUZ6.js → V257KGGO.js} +1 -1
- package/dist/cdn/XSUV6RLR.js +2 -0
- package/dist/cdn/XTTOOMCY.js +66 -0
- package/dist/cdn/{CG4WYBHN.js → XUIVR4NX.js} +1 -1
- package/dist/cdn/{7YQTBSDS.js → YQV3M6JO.js} +109 -84
- package/dist/cdn/{SOJU4OFZ.js → ZMTS73PF.js} +1 -1
- package/dist/cdn/ZSNLY6QY.js +2 -0
- package/dist/cdn/assets/portal-item-badges/t9n/messages.en.json +1 -0
- package/dist/cdn/assets/portal-item-card/t9n/messages.en.json +1 -0
- package/dist/cdn/assets/portal-item-favorite/t9n/messages.en.json +1 -0
- package/dist/cdn/assets/portal-item-type/icons/applicationtheme16.svg +1 -0
- package/dist/cdn/assets/portal-item-type/icons/applicationtheme32.svg +1 -0
- package/dist/cdn/assets/portal-item-type/icons/layout16.svg +1 -0
- package/dist/cdn/assets/portal-item-type/icons/layout32.svg +1 -0
- package/dist/cdn/index.js +1 -1
- package/dist/cdn/main.css +1 -1
- package/dist/chunks/fieldAddDelete.js +1 -1
- package/dist/chunks/info.js +179 -0
- package/dist/chunks/item.js +8 -8
- package/dist/chunks/items.js +16 -0
- package/dist/chunks/portal-item-badge.js +346 -0
- package/dist/chunks/portal.js +3 -3
- package/dist/chunks/portal2.js +3 -3
- package/dist/chunks/query.js +4 -4
- package/dist/chunks/string.js +2 -2
- package/dist/chunks/users.js +7 -0
- package/dist/chunks/utils.js +75 -636
- package/dist/chunks/utils2.js +653 -0
- package/dist/chunks/verified.js +40 -0
- package/dist/components/arcgis-portal-account-switcher/customElement.js +58 -72
- package/dist/components/arcgis-portal-account-switcher-list/customElement.js +6 -6
- package/dist/components/arcgis-portal-ai-assistant/customElement.d.ts +9 -7
- package/dist/components/arcgis-portal-ai-assistant/customElement.js +944 -775
- package/dist/components/arcgis-portal-field-delete/customElement.js +2 -1
- package/dist/components/arcgis-portal-group-browser/customElement.js +3 -3
- package/dist/components/arcgis-portal-group-browser/types.d.ts +6 -2
- package/dist/components/arcgis-portal-group-browser-preview/customElement.d.ts +9 -9
- package/dist/components/arcgis-portal-group-browser-preview/customElement.js +16 -16
- package/dist/components/arcgis-portal-group-browser-preview-card/customElement.d.ts +18 -18
- package/dist/components/arcgis-portal-group-browser-preview-card/customElement.js +31 -30
- package/dist/components/arcgis-portal-group-card/customElement.d.ts +25 -25
- package/dist/components/arcgis-portal-group-card/customElement.js +7 -7
- package/dist/components/arcgis-portal-item-actions/customElement.d.ts +74 -0
- package/dist/components/arcgis-portal-item-actions/customElement.js +89 -0
- package/dist/components/arcgis-portal-item-actions/index.d.ts +1 -0
- package/dist/components/arcgis-portal-item-actions/index.js +5 -0
- package/dist/components/arcgis-portal-item-badge/customElement.d.ts +260 -0
- package/dist/components/arcgis-portal-item-badge/customElement.js +9 -0
- package/dist/components/arcgis-portal-item-badge/index.d.ts +1 -0
- package/dist/components/arcgis-portal-item-badge/index.js +5 -0
- package/dist/components/arcgis-portal-item-badges/customElement.d.ts +48 -0
- package/dist/components/arcgis-portal-item-badges/customElement.js +35 -0
- package/dist/components/arcgis-portal-item-badges/index.d.ts +1 -0
- package/dist/components/arcgis-portal-item-badges/index.js +2 -0
- package/dist/components/arcgis-portal-item-badges/types.d.ts +1 -0
- package/dist/components/arcgis-portal-item-card/customElement.d.ts +215 -0
- package/dist/components/arcgis-portal-item-card/customElement.js +190 -0
- package/dist/components/arcgis-portal-item-card/index.d.ts +1 -0
- package/dist/components/arcgis-portal-item-card/index.js +10 -0
- package/dist/components/arcgis-portal-item-favorite/customElement.d.ts +36 -0
- package/dist/components/arcgis-portal-item-favorite/customElement.js +66 -0
- package/dist/components/arcgis-portal-item-favorite/index.d.ts +1 -0
- package/dist/components/arcgis-portal-item-favorite/index.js +3 -0
- package/dist/components/arcgis-portal-item-favorite/utils.d.ts +4 -0
- package/dist/components/arcgis-portal-item-type/customElement.js +1 -1
- package/dist/components/arcgis-portal-navigation/customElement.js +40 -40
- package/dist/components/arcgis-portal-replacement-item-redirect/customElement.js +42 -214
- package/dist/components/arcgis-portal-user-popup/customElement.js +66 -100
- package/dist/components/portal-group-browser-filters/customElement.js +71 -73
- 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/index.d.ts +38 -0
- package/dist/loader.js +9 -4
- package/dist/types/item.d.ts +5 -1
- package/dist/types/lumina.d.ts +38 -4
- package/dist/types/preact.d.ts +43 -4
- package/dist/types/react.d.ts +48 -4
- package/dist/types/stencil.d.ts +38 -4
- package/package.json +6 -6
- package/dist/cdn/332KSPIN.js +0 -2
- package/dist/cdn/7PPA7V23.js +0 -2
- package/dist/cdn/DML7662F.js +0 -2
- package/dist/cdn/FF24VDOG.js +0 -65
- package/dist/cdn/G2NXASJO.js +0 -2
- package/dist/cdn/JZTBGLFH.js +0 -2
- package/dist/cdn/PP7GTURX.js +0 -2
- package/dist/cdn/QQ432AB6.js +0 -2
- package/dist/cdn/RKWOBE3M.js +0 -2
- package/dist/cdn/V4IAC7WR.js +0 -2
- package/dist/cdn/WEJQVIN4.js +0 -2
- package/dist/cdn/ZK2VXTNX.js +0 -2
- package/dist/components/portal-browser/components/portal-browser-filter-date/portal-browser-filter-date.d.ts +0 -122
|
@@ -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 P, ref as
|
|
6
|
-
import { u as
|
|
7
|
-
import { NodeInterrupt as
|
|
8
|
-
import { sendTraceMessage as
|
|
9
|
-
import
|
|
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 !!
|
|
2
|
+
import { c as Ue } from "../../chunks/runtime.js";
|
|
3
|
+
import { LitElement as Fe, createEvent as Oe } from "@arcgis/lumina";
|
|
4
|
+
import { css as Ke, render as Ve, html as b } from "lit";
|
|
5
|
+
import { createRef as P, ref as q } from "lit/directives/ref.js";
|
|
6
|
+
import { u as je } from "../../chunks/useT9n.js";
|
|
7
|
+
import { NodeInterrupt as fe, Annotation as h, StateGraph as G, START as A, END as w } from "@langchain/langgraph/web";
|
|
8
|
+
import { sendTraceMessage as m, invokeStructuredPrompt as v, sendUXSuggestion as B, createAgentRuntimeStateWithSharedState as N, createChatModel as Q, getEmbeddings as Le } from "@arcgis/ai-components/utils/index.js";
|
|
9
|
+
import s from "zod";
|
|
10
|
+
import { a as Be, c as Qe, q as We } from "../../chunks/groups.js";
|
|
11
|
+
import Je from "@arcgis/core/identity/IdentityManager.js";
|
|
12
|
+
import Y from "@arcgis/core/request.js";
|
|
13
|
+
import { a as R, t as _e, b as Ye } from "../../chunks/functionalities.js";
|
|
14
|
+
import { ChatPromptTemplate as W } from "@langchain/core/prompts";
|
|
15
|
+
import { tool as ye } from "@langchain/core/tools";
|
|
16
|
+
import { s as He, a as Xe } from "../../chunks/item2.js";
|
|
17
|
+
import { g as Ze, e as et, i as tt, c as at, a as nt } from "../../chunks/groups2.js";
|
|
18
|
+
import rt from "@arcgis/core/portal/Portal.js";
|
|
19
|
+
const we = (e) => {
|
|
20
|
+
const { portal: t, user: a } = e ?? {};
|
|
21
|
+
return !!e && !!t && !!a;
|
|
22
22
|
};
|
|
23
|
-
function
|
|
24
|
-
if (!
|
|
23
|
+
function T(e) {
|
|
24
|
+
if (!we(e))
|
|
25
25
|
throw new Error("Invalid context: PortalAssistantContext with portal and user is required.");
|
|
26
26
|
}
|
|
27
|
-
const
|
|
27
|
+
const ot = `
|
|
28
28
|
Write a concise, friendly success message for adding members to a group.
|
|
29
29
|
|
|
30
30
|
Rules:
|
|
@@ -39,73 +39,73 @@ Added members:
|
|
|
39
39
|
|
|
40
40
|
Not added members:
|
|
41
41
|
{notAddedMembers}
|
|
42
|
-
`,
|
|
43
|
-
successMessage:
|
|
44
|
-
}),
|
|
45
|
-
if (
|
|
42
|
+
`, st = (e) => e.map((t) => `"${t}"`).join(", "), it = s.object({
|
|
43
|
+
successMessage: s.string().default("")
|
|
44
|
+
}), H = "portal-group-creation", X = "approveAddMembers", ut = 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((p) => p.trim()).filter(Boolean);
|
|
57
57
|
if (!n.length)
|
|
58
58
|
return {
|
|
59
59
|
status: "success",
|
|
60
60
|
outputMessage: "Use @mention usernames for the members you want to add."
|
|
61
61
|
};
|
|
62
|
-
const
|
|
62
|
+
const o = `The following member(s) will be added to the newly created group:
|
|
63
63
|
|
|
64
64
|
${n.map((p) => `- **@${p}**`).join(`
|
|
65
65
|
`)}
|
|
66
66
|
|
|
67
|
-
Do you want to continue?`, { hitlResponse:
|
|
68
|
-
if (
|
|
67
|
+
Do you want to continue?`, { hitlResponse: u } = t?.configurable ?? {};
|
|
68
|
+
if (u?.agentId !== H || u.id !== X) {
|
|
69
69
|
const p = {
|
|
70
|
-
agentId:
|
|
71
|
-
id:
|
|
70
|
+
agentId: H,
|
|
71
|
+
id: X,
|
|
72
72
|
kind: "booleanChoice",
|
|
73
|
-
message:
|
|
73
|
+
message: o,
|
|
74
74
|
metadata: {
|
|
75
75
|
action: "addMembers",
|
|
76
76
|
groupId: a,
|
|
77
77
|
members: [...n]
|
|
78
78
|
}
|
|
79
79
|
};
|
|
80
|
-
throw new
|
|
80
|
+
throw new fe(p);
|
|
81
81
|
}
|
|
82
|
-
if (
|
|
82
|
+
if (u.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 m(
|
|
88
|
+
{ text: `Adding members ${st(n)}...`, agentName: "group-creation" },
|
|
89
|
+
t
|
|
90
90
|
);
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
const { result:
|
|
94
|
-
if (
|
|
91
|
+
const i = t?.configurable?.context;
|
|
92
|
+
T(i);
|
|
93
|
+
const { result: l, error: c } = await Be(i.portal, a, n);
|
|
94
|
+
if (c || !l)
|
|
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: d, notAddedUsers: g } = l;
|
|
100
100
|
try {
|
|
101
101
|
const f = (await v({
|
|
102
|
-
promptText:
|
|
103
|
-
schema:
|
|
102
|
+
promptText: ot,
|
|
103
|
+
schema: it,
|
|
104
104
|
modelTier: "fast",
|
|
105
105
|
inputVariables: {
|
|
106
|
-
addedMembers:
|
|
106
|
+
addedMembers: d.join(", "),
|
|
107
107
|
notAddedMembers: JSON.stringify(
|
|
108
|
-
|
|
108
|
+
g.map((y) => ({ username: y.username, reason: y.error.message }))
|
|
109
109
|
)
|
|
110
110
|
}
|
|
111
111
|
})).successMessage;
|
|
@@ -115,7 +115,7 @@ Do you want to continue?`, { hitlResponse: i } = e?.configurable ?? {};
|
|
|
115
115
|
console.error("Error generating add-members success message:", p);
|
|
116
116
|
}
|
|
117
117
|
return {};
|
|
118
|
-
},
|
|
118
|
+
}, ct = `
|
|
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
|
+
`, lt = `
|
|
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
|
-
`,
|
|
145
|
-
successMessage:
|
|
146
|
-
}),
|
|
147
|
-
failureMessage:
|
|
148
|
-
}),
|
|
149
|
-
if (
|
|
144
|
+
`, Z = "portal-group-creation", ee = "approveCreateGroup", dt = s.object({
|
|
145
|
+
successMessage: s.string().default("")
|
|
146
|
+
}), pt = s.object({
|
|
147
|
+
failureMessage: s.string().default("")
|
|
148
|
+
}), mt = 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:
|
|
161
|
-
if (
|
|
162
|
-
const
|
|
163
|
-
agentId:
|
|
164
|
-
id:
|
|
160
|
+
const n = `A group with the title **${a}** will be created. Do you want to continue?`, { hitlResponse: r } = t?.configurable;
|
|
161
|
+
if (r?.agentId !== Z || r.id !== ee) {
|
|
162
|
+
const c = {
|
|
163
|
+
agentId: Z,
|
|
164
|
+
id: ee,
|
|
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 fe(c);
|
|
174
174
|
}
|
|
175
|
-
if (
|
|
175
|
+
if (r.payload !== !0)
|
|
176
176
|
return {
|
|
177
177
|
status: "success",
|
|
178
178
|
outputMessage: `Okay, I cancelled creating **${a}**.`
|
|
179
179
|
};
|
|
180
|
-
await
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
const { result:
|
|
180
|
+
await m({ text: `Creating group "${a}"...`, agentName: "group-creation" }, t);
|
|
181
|
+
const o = t?.configurable?.context;
|
|
182
|
+
T(o);
|
|
183
|
+
const { result: u, error: i } = await Qe(o.portal, {
|
|
184
184
|
title: a,
|
|
185
185
|
access: "private"
|
|
186
186
|
});
|
|
187
|
-
if (
|
|
188
|
-
const
|
|
187
|
+
if (i || !u) {
|
|
188
|
+
const c = i?.message?.trim() || "No additional details were provided.";
|
|
189
189
|
try {
|
|
190
|
-
const
|
|
191
|
-
promptText:
|
|
192
|
-
schema:
|
|
190
|
+
const g = (await v({
|
|
191
|
+
promptText: lt,
|
|
192
|
+
schema: pt,
|
|
193
193
|
modelTier: "fast",
|
|
194
194
|
inputVariables: {
|
|
195
195
|
groupTitle: a,
|
|
196
|
-
failureReason:
|
|
196
|
+
failureReason: c
|
|
197
197
|
}
|
|
198
198
|
})).failureMessage.trim();
|
|
199
|
-
if (
|
|
199
|
+
if (g)
|
|
200
200
|
return {
|
|
201
201
|
status: "success",
|
|
202
|
-
outputMessage:
|
|
202
|
+
outputMessage: g
|
|
203
203
|
};
|
|
204
|
-
} catch (
|
|
205
|
-
console.error("Error generating create-group failure message:",
|
|
204
|
+
} catch (d) {
|
|
205
|
+
console.error("Error generating create-group failure message:", d);
|
|
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 l = u.id;
|
|
213
213
|
try {
|
|
214
|
-
const
|
|
215
|
-
promptText:
|
|
216
|
-
schema:
|
|
214
|
+
const d = (await v({
|
|
215
|
+
promptText: ct,
|
|
216
|
+
schema: dt,
|
|
217
217
|
modelTier: "fast",
|
|
218
218
|
inputVariables: {
|
|
219
219
|
groupTitle: a
|
|
220
220
|
}
|
|
221
221
|
})).successMessage.trim();
|
|
222
|
-
if (
|
|
222
|
+
if (d)
|
|
223
223
|
return {
|
|
224
224
|
status: "success",
|
|
225
|
-
outputMessage:
|
|
226
|
-
sharedStatePatch: { createdGroupId: { value:
|
|
227
|
-
createdGroupId:
|
|
225
|
+
outputMessage: d,
|
|
226
|
+
sharedStatePatch: { createdGroupId: { value: l } },
|
|
227
|
+
createdGroupId: l
|
|
228
228
|
};
|
|
229
|
-
} catch (
|
|
230
|
-
console.error("Error generating create-group success message:",
|
|
229
|
+
} catch (c) {
|
|
230
|
+
console.error("Error generating create-group success message:", c);
|
|
231
231
|
}
|
|
232
232
|
return {};
|
|
233
|
-
},
|
|
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;
|
|
@@ -240,11 +240,11 @@ Failure reason:
|
|
|
240
240
|
return n;
|
|
241
241
|
if (Array.isArray(n))
|
|
242
242
|
return n.map(
|
|
243
|
-
(
|
|
243
|
+
(r) => typeof r == "string" ? r : "text" in r && typeof r.text == "string" ? r.text : ""
|
|
244
244
|
).join(" ").trim();
|
|
245
245
|
}
|
|
246
246
|
return "";
|
|
247
|
-
},
|
|
247
|
+
}, gt = `
|
|
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,77 +270,77 @@ Examples:
|
|
|
270
270
|
|
|
271
271
|
User message:
|
|
272
272
|
{userMessage}
|
|
273
|
-
`,
|
|
274
|
-
intent:
|
|
275
|
-
title:
|
|
276
|
-
memberIdentifiers:
|
|
277
|
-
clarifyMessage:
|
|
278
|
-
}),
|
|
279
|
-
await
|
|
280
|
-
const a =
|
|
281
|
-
promptText:
|
|
282
|
-
schema:
|
|
273
|
+
`, ht = s.object({
|
|
274
|
+
intent: s.enum(["clarify", "create", "addMembers"]).default("clarify"),
|
|
275
|
+
title: s.string().default(""),
|
|
276
|
+
memberIdentifiers: s.array(s.string()).default([]),
|
|
277
|
+
clarifyMessage: s.string().default("")
|
|
278
|
+
}), ft = async (e, t) => {
|
|
279
|
+
await m({ text: "Thinking about groups...", agentName: "group-creation" }, t);
|
|
280
|
+
const a = I(e.agentExecutionContext.messages).trim(), n = await v({
|
|
281
|
+
promptText: gt,
|
|
282
|
+
schema: ht,
|
|
283
283
|
modelTier: "default",
|
|
284
284
|
inputVariables: { userMessage: a }
|
|
285
|
-
}),
|
|
285
|
+
}), r = n.title.trim(), o = n.memberIdentifiers.filter(Boolean), u = n.clarifyMessage.trim(), i = n.intent === "create" && !!r, l = n.intent === "addMembers" && o.length > 0;
|
|
286
286
|
return {
|
|
287
|
-
intentParams:
|
|
287
|
+
intentParams: i ? { intent: "create", title: r } : l ? { intent: "addMembers", memberInfo: { memberIdentifiers: o } } : { intent: "clarify" },
|
|
288
288
|
status: "success",
|
|
289
|
-
outputMessage: !
|
|
289
|
+
outputMessage: !i && !l ? u : ""
|
|
290
290
|
};
|
|
291
|
-
},
|
|
292
|
-
destinationType:
|
|
293
|
-
hash:
|
|
294
|
-
t9nKey:
|
|
295
|
-
}),
|
|
296
|
-
destinationType:
|
|
297
|
-
hash:
|
|
298
|
-
t9nKey:
|
|
299
|
-
}),
|
|
300
|
-
destinationType:
|
|
301
|
-
hash:
|
|
302
|
-
t9nKey:
|
|
303
|
-
}),
|
|
304
|
-
destinationType:
|
|
305
|
-
itemId:
|
|
306
|
-
t9nKey:
|
|
307
|
-
}),
|
|
308
|
-
destinationType:
|
|
309
|
-
groupId:
|
|
310
|
-
t9nKey:
|
|
311
|
-
}),
|
|
312
|
-
destinationType:
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
291
|
+
}, yt = ["favorites", "group", "living-atlas", "org"], wt = ["featured", "my", "organization"], bt = ["licenses", "members", "overview", "reports", "settings", "status"], vt = s.object({
|
|
292
|
+
destinationType: s.literal("portal-content"),
|
|
293
|
+
hash: s.enum(yt).optional(),
|
|
294
|
+
t9nKey: s.string().min(1).optional()
|
|
295
|
+
}), It = s.object({
|
|
296
|
+
destinationType: s.literal("portal-groups"),
|
|
297
|
+
hash: s.enum(wt).optional(),
|
|
298
|
+
t9nKey: s.string().min(1).optional()
|
|
299
|
+
}), xt = s.object({
|
|
300
|
+
destinationType: s.literal("portal-org"),
|
|
301
|
+
hash: s.enum(bt).optional(),
|
|
302
|
+
t9nKey: s.string().min(1).optional()
|
|
303
|
+
}), St = s.object({
|
|
304
|
+
destinationType: s.literal("portal-item"),
|
|
305
|
+
itemId: s.string().trim().min(1),
|
|
306
|
+
t9nKey: s.string().min(1).optional()
|
|
307
|
+
}), Tt = s.object({
|
|
308
|
+
destinationType: s.literal("portal-group"),
|
|
309
|
+
groupId: s.string().trim().min(1),
|
|
310
|
+
t9nKey: s.string().min(1).optional()
|
|
311
|
+
}), Mt = s.object({
|
|
312
|
+
destinationType: s.union([
|
|
313
|
+
s.literal("portal-gallery"),
|
|
314
|
+
s.literal("portal-map-viewer"),
|
|
315
|
+
s.literal("portal-notebooks"),
|
|
316
|
+
s.literal("portal-scene-viewer")
|
|
317
317
|
]),
|
|
318
|
-
t9nKey:
|
|
319
|
-
}),
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
]),
|
|
327
|
-
const a =
|
|
328
|
-
!
|
|
329
|
-
},
|
|
330
|
-
const a =
|
|
331
|
-
return a ? (await
|
|
332
|
-
},
|
|
333
|
-
...
|
|
318
|
+
t9nKey: s.string().min(1).optional()
|
|
319
|
+
}), Ct = s.union([
|
|
320
|
+
vt,
|
|
321
|
+
It,
|
|
322
|
+
xt,
|
|
323
|
+
St,
|
|
324
|
+
Tt,
|
|
325
|
+
Mt
|
|
326
|
+
]), be = "portal-navigation", D = async (e, t) => {
|
|
327
|
+
const a = t?.configurable?.context;
|
|
328
|
+
!we(a) || !a.navigationTargetMap?.[e.destinationType] || await B({ type: be, data: { ...e } }, t);
|
|
329
|
+
}, Gt = async (e, t) => {
|
|
330
|
+
const a = e.createdGroupId ?? e.agentExecutionContext.sharedState.createdGroupId?.value;
|
|
331
|
+
return a ? (await m({ text: "Preparing navigation...", agentName: "group-creation" }, t), await D({ destinationType: "portal-group", groupId: a }, t), {}) : {};
|
|
332
|
+
}, te = (e, t) => t ?? e, ve = h.Root({
|
|
333
|
+
...N(),
|
|
334
334
|
// * Shared state between nodes (but not persisted to the agent execution context)
|
|
335
335
|
/** Parameters related to the user's intent for group creation actions */
|
|
336
|
-
intentParams: h({ reducer:
|
|
336
|
+
intentParams: h({ reducer: te, default: () => ({ intent: "clarify" }) }),
|
|
337
337
|
/** The ID of the group that was created
|
|
338
338
|
* even though we already have this in the shared state
|
|
339
339
|
* we still need it here to also share between nodes
|
|
340
340
|
*/
|
|
341
|
-
createdGroupId: h({ reducer:
|
|
342
|
-
}),
|
|
343
|
-
switch (
|
|
341
|
+
createdGroupId: h({ reducer: te, default: () => "" })
|
|
342
|
+
}), At = () => new G(ve).addNode("detectGroupCreationIntent", ft).addNode("createPortalGroup", mt).addNode("addMembersToPortalGroup", ut).addNode("suggestCreatedGroupNavigation", Gt).addEdge(A, "detectGroupCreationIntent").addConditionalEdges("detectGroupCreationIntent", (t) => {
|
|
343
|
+
switch (t.intentParams.intent) {
|
|
344
344
|
case "create":
|
|
345
345
|
return "createPortalGroup";
|
|
346
346
|
case "addMembers":
|
|
@@ -348,189 +348,189 @@ User message:
|
|
|
348
348
|
default:
|
|
349
349
|
return w;
|
|
350
350
|
}
|
|
351
|
-
}).addEdge("createPortalGroup", "suggestCreatedGroupNavigation").addEdge("addMembersToPortalGroup", "suggestCreatedGroupNavigation").addEdge("suggestCreatedGroupNavigation", w),
|
|
351
|
+
}).addEdge("createPortalGroup", "suggestCreatedGroupNavigation").addEdge("addMembersToPortalGroup", "suggestCreatedGroupNavigation").addEdge("suggestCreatedGroupNavigation", w), Nt = String.raw`- **portal-group-creation** - Portal group creation assistant:
|
|
352
352
|
- creates a new ArcGIS Portal group for the signed-in user
|
|
353
353
|
- adds users to the newly created group using @mention usernames
|
|
354
|
-
`,
|
|
354
|
+
`, Pt = {
|
|
355
355
|
id: "portal-group-creation",
|
|
356
356
|
name: "Portal Group Creation",
|
|
357
|
-
description:
|
|
358
|
-
createGraph:
|
|
359
|
-
workspace:
|
|
360
|
-
},
|
|
361
|
-
const
|
|
362
|
-
if (!
|
|
363
|
-
return
|
|
364
|
-
const a =
|
|
357
|
+
description: Nt,
|
|
358
|
+
createGraph: At,
|
|
359
|
+
workspace: ve
|
|
360
|
+
}, Ie = "portalDocAssistantMemory", qt = () => ({ conversationId: "" }), Et = (e) => {
|
|
361
|
+
const t = e?.[Ie]?.value;
|
|
362
|
+
if (!t || typeof t != "object")
|
|
363
|
+
return qt();
|
|
364
|
+
const a = t;
|
|
365
365
|
return {
|
|
366
366
|
conversationId: typeof a.conversationId == "string" ? a.conversationId : ""
|
|
367
367
|
};
|
|
368
|
-
},
|
|
369
|
-
[
|
|
370
|
-
}),
|
|
368
|
+
}, kt = (e) => ({
|
|
369
|
+
[Ie]: { value: e }
|
|
370
|
+
}), zt = {
|
|
371
371
|
pipeline: {
|
|
372
372
|
follow_up: { allow: !1 }
|
|
373
373
|
}
|
|
374
374
|
};
|
|
375
|
-
function
|
|
375
|
+
function $t(e) {
|
|
376
376
|
return {
|
|
377
377
|
kind: "DocAIAssistantRequest",
|
|
378
378
|
filters: {
|
|
379
|
-
...
|
|
380
|
-
persona: { persona:
|
|
379
|
+
...zt,
|
|
380
|
+
persona: { persona: e }
|
|
381
381
|
}
|
|
382
382
|
};
|
|
383
383
|
}
|
|
384
|
-
async function
|
|
385
|
-
portal:
|
|
386
|
-
question:
|
|
384
|
+
async function Rt({
|
|
385
|
+
portal: e,
|
|
386
|
+
question: t,
|
|
387
387
|
persona: a,
|
|
388
388
|
previousConversationId: n,
|
|
389
|
-
signal:
|
|
390
|
-
skillId:
|
|
389
|
+
signal: r,
|
|
390
|
+
skillId: o
|
|
391
391
|
}) {
|
|
392
|
-
|
|
393
|
-
const
|
|
394
|
-
portal:
|
|
395
|
-
skillId:
|
|
396
|
-
message:
|
|
397
|
-
options: { context:
|
|
392
|
+
o ??= "doc_ai_assistant";
|
|
393
|
+
const u = $t(a), i = await Dt({
|
|
394
|
+
portal: e,
|
|
395
|
+
skillId: o,
|
|
396
|
+
message: t,
|
|
397
|
+
options: { context: u, previousConversationId: n, signal: r }
|
|
398
398
|
});
|
|
399
399
|
return {
|
|
400
|
-
reply:
|
|
401
|
-
conversationId:
|
|
400
|
+
reply: Ut(i, o),
|
|
401
|
+
conversationId: i[0]?.conversationId ?? ""
|
|
402
402
|
};
|
|
403
403
|
}
|
|
404
|
-
async function
|
|
405
|
-
portal:
|
|
406
|
-
skillId:
|
|
404
|
+
async function Dt({
|
|
405
|
+
portal: e,
|
|
406
|
+
skillId: t,
|
|
407
407
|
message: a,
|
|
408
408
|
options: n
|
|
409
409
|
}) {
|
|
410
|
-
const
|
|
410
|
+
const o = `${e.helperServices.aiAssistantServices.url}/skills/${t}/chat`, u = {
|
|
411
411
|
"Content-Type": "application/json",
|
|
412
|
-
token:
|
|
413
|
-
},
|
|
412
|
+
token: Je.findCredential(e.url)?.token ?? ""
|
|
413
|
+
}, i = await Y(o, {
|
|
414
414
|
method: "post",
|
|
415
415
|
body: JSON.stringify({
|
|
416
416
|
message: a,
|
|
417
417
|
context: n.context,
|
|
418
418
|
conversationId: n.previousConversationId
|
|
419
419
|
}),
|
|
420
|
-
headers:
|
|
420
|
+
headers: u,
|
|
421
421
|
signal: n.signal
|
|
422
422
|
});
|
|
423
|
-
if (
|
|
424
|
-
throw new Error(`Doc assistant chat failed (${
|
|
425
|
-
cause:
|
|
423
|
+
if (i.httpStatus !== 200)
|
|
424
|
+
throw new Error(`Doc assistant chat failed (${i.httpStatus})`, {
|
|
425
|
+
cause: i.data
|
|
426
426
|
});
|
|
427
|
-
const
|
|
427
|
+
const l = i.data, c = [l], { conversationId: d, inquiryId: g } = l, p = async (f, y) => {
|
|
428
428
|
if (!y)
|
|
429
429
|
return;
|
|
430
|
-
await
|
|
431
|
-
const
|
|
430
|
+
await _e(500);
|
|
431
|
+
const x = await Y(o, {
|
|
432
432
|
method: "post",
|
|
433
|
-
body: JSON.stringify({ conversationId:
|
|
434
|
-
headers:
|
|
433
|
+
body: JSON.stringify({ conversationId: d, inquiryId: g, ackSequenceNumber: f }),
|
|
434
|
+
headers: u,
|
|
435
435
|
signal: n.signal
|
|
436
436
|
});
|
|
437
|
-
if (
|
|
438
|
-
throw new Error(`Doc assistant poll failed (${
|
|
439
|
-
cause:
|
|
437
|
+
if (x.httpStatus !== 200)
|
|
438
|
+
throw new Error(`Doc assistant poll failed (${x.httpStatus})`, {
|
|
439
|
+
cause: x.data
|
|
440
440
|
});
|
|
441
|
-
const M =
|
|
442
|
-
|
|
441
|
+
const M = x.data;
|
|
442
|
+
c.push(M), await p(M.sequenceNumber, M.hasMore);
|
|
443
443
|
};
|
|
444
|
-
return
|
|
444
|
+
return l.hasMore && await p(l.sequenceNumber, l.hasMore), c;
|
|
445
445
|
}
|
|
446
|
-
function
|
|
447
|
-
switch (
|
|
446
|
+
function Ut(e, t) {
|
|
447
|
+
switch (t) {
|
|
448
448
|
case "doc_chat":
|
|
449
|
-
return
|
|
449
|
+
return e.find((a) => a.message != null)?.message ?? "";
|
|
450
450
|
case "doc_ai_assistant":
|
|
451
|
-
for (let a =
|
|
452
|
-
const n =
|
|
451
|
+
for (let a = e.length - 1; a >= 0; a -= 1) {
|
|
452
|
+
const n = e[a];
|
|
453
453
|
if (n.context?.kind === "DocAIAssistantContext") {
|
|
454
|
-
const
|
|
455
|
-
if (
|
|
456
|
-
return
|
|
454
|
+
const r = n.context.results?.[0]?.reply;
|
|
455
|
+
if (r)
|
|
456
|
+
return r;
|
|
457
457
|
}
|
|
458
458
|
}
|
|
459
459
|
return "";
|
|
460
460
|
default:
|
|
461
|
-
return
|
|
461
|
+
return R(t);
|
|
462
462
|
}
|
|
463
463
|
}
|
|
464
|
-
const
|
|
465
|
-
await
|
|
466
|
-
const a =
|
|
464
|
+
const Ft = async (e, t) => {
|
|
465
|
+
await m({ text: "Asking documentation assistant...", agentName: "doc-assistant" }, t);
|
|
466
|
+
const a = I(e.agentExecutionContext.messages).trim();
|
|
467
467
|
if (!a)
|
|
468
468
|
return {
|
|
469
469
|
status: "success",
|
|
470
470
|
outputMessage: "Please share your question and I can help with ArcGIS and Portal documentation."
|
|
471
471
|
};
|
|
472
|
-
const n =
|
|
473
|
-
|
|
474
|
-
const
|
|
472
|
+
const n = t?.configurable?.context;
|
|
473
|
+
T(n);
|
|
474
|
+
const r = Et(e.agentExecutionContext.sharedState), { reply: o, conversationId: u } = await Rt({
|
|
475
475
|
portal: n.portal,
|
|
476
476
|
question: a,
|
|
477
|
-
previousConversationId:
|
|
477
|
+
previousConversationId: r.conversationId || void 0,
|
|
478
478
|
skillId: "doc_ai_assistant",
|
|
479
479
|
persona: "doc-online"
|
|
480
480
|
});
|
|
481
481
|
return {
|
|
482
482
|
status: "success",
|
|
483
|
-
outputMessage:
|
|
484
|
-
sharedStatePatch:
|
|
485
|
-
conversationId:
|
|
483
|
+
outputMessage: o.trim() || "I could not retrieve a response from the documentation assistant.",
|
|
484
|
+
sharedStatePatch: kt({
|
|
485
|
+
conversationId: u || r.conversationId
|
|
486
486
|
})
|
|
487
487
|
};
|
|
488
|
-
},
|
|
489
|
-
async ({ groupTitle:
|
|
490
|
-
const a =
|
|
488
|
+
}, xe = ye(
|
|
489
|
+
async ({ groupTitle: e }, t) => {
|
|
490
|
+
const a = e.trim();
|
|
491
491
|
if (!a)
|
|
492
492
|
return null;
|
|
493
|
-
const n =
|
|
494
|
-
|
|
493
|
+
const n = t?.configurable?.context;
|
|
494
|
+
T(n);
|
|
495
495
|
try {
|
|
496
|
-
return (await
|
|
497
|
-
} catch (
|
|
498
|
-
return console.error("Error searching for portal group by title:",
|
|
496
|
+
return (await We(n.portal, { query: `title:${a}`, num: 1 }))?.results[0]?.id || null;
|
|
497
|
+
} catch (r) {
|
|
498
|
+
return console.error("Error searching for portal group by title:", r), null;
|
|
499
499
|
}
|
|
500
500
|
},
|
|
501
501
|
{
|
|
502
502
|
name: "resolvePortalGroupIdByTitle",
|
|
503
503
|
description: "Resolves an ArcGIS Portal group title to the best-match group id. Use this when a user references a group by title instead of an explicit group id.",
|
|
504
|
-
schema:
|
|
505
|
-
groupTitle:
|
|
504
|
+
schema: s.object({
|
|
505
|
+
groupTitle: s.string().describe("The portal group title to resolve to a group id.")
|
|
506
506
|
})
|
|
507
507
|
}
|
|
508
|
-
),
|
|
509
|
-
async ({ itemTitle:
|
|
510
|
-
const a =
|
|
508
|
+
), Se = ye(
|
|
509
|
+
async ({ itemTitle: e }, t) => {
|
|
510
|
+
const a = e.trim();
|
|
511
511
|
if (!a)
|
|
512
512
|
return null;
|
|
513
|
-
const n =
|
|
514
|
-
|
|
515
|
-
const { result:
|
|
516
|
-
return
|
|
513
|
+
const n = t?.configurable?.context;
|
|
514
|
+
T(n);
|
|
515
|
+
const { result: r, error: o } = await He(n.portal, a, { num: 1 });
|
|
516
|
+
return o && console.error("Error searching for portal item by title:", o), r?.results[0]?.id || null;
|
|
517
517
|
},
|
|
518
518
|
{
|
|
519
519
|
name: "resolvePortalItemIdByTitle",
|
|
520
520
|
description: 'Resolves an ArcGIS Portal item title to the best-match item id. Use this when a user references an item by title (including hash mentions like #title or #"title with spaces") instead of an explicit item id.',
|
|
521
|
-
schema:
|
|
522
|
-
itemTitle:
|
|
521
|
+
schema: s.object({
|
|
522
|
+
itemTitle: s.string().describe("The portal item title to resolve to an item id.")
|
|
523
523
|
})
|
|
524
524
|
}
|
|
525
525
|
);
|
|
526
|
-
function
|
|
527
|
-
const a =
|
|
526
|
+
function C(e, t = "#") {
|
|
527
|
+
const a = e.match(new RegExp(`\\${t}"([^"]+)"`, "u"));
|
|
528
528
|
if (a?.[1])
|
|
529
529
|
return a[1].trim();
|
|
530
|
-
const n =
|
|
530
|
+
const n = e.match(new RegExp(`\\${t}([^\\s"']+)`, "u"));
|
|
531
531
|
return n?.[1] ? n[1].trim() : null;
|
|
532
532
|
}
|
|
533
|
-
const
|
|
533
|
+
const Te = {
|
|
534
534
|
"portal-content": {
|
|
535
535
|
description: "The main content page of the portal.",
|
|
536
536
|
hints: ["My content", "Content"]
|
|
@@ -595,14 +595,14 @@ const bt = {
|
|
|
595
595
|
description: "The Organization > Settings > Security page of the portal.",
|
|
596
596
|
hints: ["Organization settings", "Security", "Organization > Settings > Security"]
|
|
597
597
|
}
|
|
598
|
-
},
|
|
599
|
-
`),
|
|
598
|
+
}, Ot = Ye(Te), Kt = Object.entries(Te).map(([e, { description: t, hints: a }]) => ` - ${e}: ${t} (hints: ${a.join(", ")})`).join(`
|
|
599
|
+
`), Vt = `
|
|
600
600
|
You decide whether the assistant response should include a navigation action to ArcGIS Portal.
|
|
601
601
|
|
|
602
602
|
Given the user question and assistant response:
|
|
603
603
|
- Decide if a navigation action would help the user complete the task.
|
|
604
604
|
- If yes, choose one destinationType:
|
|
605
|
-
${
|
|
605
|
+
${Kt}
|
|
606
606
|
|
|
607
607
|
Rules:
|
|
608
608
|
- Only suggest navigation when you are highly confident the destination will help complete the user's task.
|
|
@@ -625,47 +625,47 @@ User question:
|
|
|
625
625
|
|
|
626
626
|
Assistant response:
|
|
627
627
|
{response}
|
|
628
|
-
`,
|
|
629
|
-
shouldSuggestNavigation:
|
|
630
|
-
destinationType:
|
|
631
|
-
itemId:
|
|
632
|
-
groupId:
|
|
633
|
-
confidence:
|
|
634
|
-
}),
|
|
635
|
-
await
|
|
636
|
-
const a =
|
|
628
|
+
`, ae = s.object({
|
|
629
|
+
shouldSuggestNavigation: s.boolean().default(!1),
|
|
630
|
+
destinationType: s.enum(["none", ...Ot]).default("none"),
|
|
631
|
+
itemId: s.string().default(""),
|
|
632
|
+
groupId: s.string().default(""),
|
|
633
|
+
confidence: s.number().min(0).max(1).default(0)
|
|
634
|
+
}), jt = async (e, t) => {
|
|
635
|
+
await m({ text: "Extracting navigation intent...", agentName: "doc-assistant" }, t);
|
|
636
|
+
const a = e.outputMessage.trim();
|
|
637
637
|
if (!a)
|
|
638
638
|
return {};
|
|
639
|
-
const n =
|
|
639
|
+
const n = I(e.agentExecutionContext.messages).trim(), r = await W.fromTemplate(Vt).format({
|
|
640
640
|
question: n,
|
|
641
641
|
response: a
|
|
642
|
-
}),
|
|
643
|
-
if (!
|
|
642
|
+
}), u = (await Q({ modelTier: "fast" })).withStructuredOutput(ae), i = ae.parse(await u.invoke(r));
|
|
643
|
+
if (!i.shouldSuggestNavigation || i.destinationType === "none")
|
|
644
644
|
return {};
|
|
645
|
-
if (
|
|
646
|
-
const
|
|
647
|
-
|
|
645
|
+
if (i.destinationType === "portal-item" && !i.itemId) {
|
|
646
|
+
const c = C(n, "#");
|
|
647
|
+
c && (i.itemId = await Se.invoke({ itemTitle: c }, t) ?? "");
|
|
648
648
|
}
|
|
649
|
-
if (
|
|
650
|
-
const
|
|
651
|
-
|
|
649
|
+
if (i.destinationType === "portal-group" && !i.groupId) {
|
|
650
|
+
const c = C(n, "$") ?? C(n, "#");
|
|
651
|
+
c && (i.groupId = await xe.invoke({ groupTitle: c }, t) ?? "");
|
|
652
652
|
}
|
|
653
|
-
const
|
|
654
|
-
return
|
|
653
|
+
const l = Lt(i);
|
|
654
|
+
return l ? (await D(l, t), {}) : {};
|
|
655
655
|
};
|
|
656
|
-
function
|
|
657
|
-
destinationType:
|
|
658
|
-
itemId:
|
|
656
|
+
function Lt({
|
|
657
|
+
destinationType: e,
|
|
658
|
+
itemId: t,
|
|
659
659
|
groupId: a
|
|
660
660
|
}) {
|
|
661
|
-
switch (
|
|
661
|
+
switch (e) {
|
|
662
662
|
case "portal-content":
|
|
663
663
|
case "portal-gallery":
|
|
664
664
|
case "portal-groups":
|
|
665
665
|
case "portal-map-viewer":
|
|
666
666
|
case "portal-notebooks":
|
|
667
667
|
case "portal-scene-viewer":
|
|
668
|
-
return { destinationType:
|
|
668
|
+
return { destinationType: e };
|
|
669
669
|
case "portal-org-security":
|
|
670
670
|
return { destinationType: "portal-org", hash: "settings" };
|
|
671
671
|
case "portal-content-favorites":
|
|
@@ -683,40 +683,40 @@ function Fe({
|
|
|
683
683
|
case "portal-groups-organization":
|
|
684
684
|
return { destinationType: "portal-groups", hash: "organization" };
|
|
685
685
|
case "portal-item":
|
|
686
|
-
return
|
|
686
|
+
return t ? { destinationType: e, itemId: t } : null;
|
|
687
687
|
case "portal-group":
|
|
688
|
-
return a ? { destinationType:
|
|
688
|
+
return a ? { destinationType: e, groupId: a } : null;
|
|
689
689
|
case "none":
|
|
690
690
|
return null;
|
|
691
691
|
default:
|
|
692
|
-
return
|
|
692
|
+
return R(e);
|
|
693
693
|
}
|
|
694
694
|
}
|
|
695
|
-
const
|
|
696
|
-
...
|
|
697
|
-
}),
|
|
695
|
+
const Me = h.Root({
|
|
696
|
+
...N()
|
|
697
|
+
}), Bt = () => new G(Me).addNode("answerDocQuestion", Ft).addNode("extractNavigationIntent", jt).addEdge(A, "answerDocQuestion").addEdge("answerDocQuestion", "extractNavigationIntent").addEdge("extractNavigationIntent", w), Qt = String.raw`- **portal-doc-assistant** - General ArcGIS documentation and Portal help assistant:
|
|
698
698
|
- answers general ArcGIS, Portal, Enterprise, and JavaScript SDK questions
|
|
699
699
|
- acts as a fallback when specialized agents are not applicable
|
|
700
|
-
`,
|
|
700
|
+
`, Wt = {
|
|
701
701
|
id: "portal-doc-assistant",
|
|
702
702
|
name: "Portal Doc Assistant",
|
|
703
|
-
description:
|
|
704
|
-
createGraph:
|
|
705
|
-
workspace:
|
|
706
|
-
},
|
|
707
|
-
const
|
|
708
|
-
return
|
|
709
|
-
},
|
|
703
|
+
description: Qt,
|
|
704
|
+
createGraph: Bt,
|
|
705
|
+
workspace: Me
|
|
706
|
+
}, Jt = () => ({ latestGroupId: null, memory: {} }), U = (e) => {
|
|
707
|
+
const t = e?.agentExecutionContext.sharedState.portalGroupSummaryMemory?.value;
|
|
708
|
+
return t ? { latestGroupId: t.latestGroupId, memory: t.memory } : Jt();
|
|
709
|
+
}, Ce = `
|
|
710
710
|
Shared markdown formatting rules:
|
|
711
711
|
- Use clear markdown headings (##) to separate sections.
|
|
712
712
|
- Use concise bullet points for lists of facts, counts, or signals.
|
|
713
713
|
- Emphasize key metrics with bold labels (for example: **Recent items:** 4).
|
|
714
714
|
- Keep wording direct and analytical; avoid filler language but make sure the language is friendly.
|
|
715
715
|
- Do not include raw internal IDs unless explicitly requested.
|
|
716
|
-
`,
|
|
716
|
+
`, _t = `
|
|
717
717
|
You answer follow-up questions about ArcGIS group analytics.
|
|
718
718
|
|
|
719
|
-
${
|
|
719
|
+
${Ce}
|
|
720
720
|
|
|
721
721
|
Ground your answer in the provided group analytics summary and context.
|
|
722
722
|
If the answer is not available from the provided context, state that clearly and suggest what to check next.
|
|
@@ -738,29 +738,29 @@ Group full context:
|
|
|
738
738
|
|
|
739
739
|
Question:
|
|
740
740
|
{question}
|
|
741
|
-
`,
|
|
742
|
-
await
|
|
743
|
-
const a =
|
|
744
|
-
return
|
|
741
|
+
`, Yt = async (e, t) => {
|
|
742
|
+
await m({ text: "Answering group follow-up...", agentName: "group-analytics" }, t);
|
|
743
|
+
const a = U(e), n = e.groupSummaryGroupId ?? a.latestGroupId, r = n ? a.memory[n] : void 0, o = e.groupSummaryQuestion || I(e.agentExecutionContext.messages);
|
|
744
|
+
return r ? {
|
|
745
745
|
status: "success",
|
|
746
746
|
outputMessage: (await v({
|
|
747
|
-
promptText:
|
|
748
|
-
schema:
|
|
747
|
+
promptText: _t,
|
|
748
|
+
schema: Ht,
|
|
749
749
|
modelTier: "default",
|
|
750
750
|
inputVariables: {
|
|
751
|
-
summary:
|
|
752
|
-
question:
|
|
753
|
-
fullContext: JSON.stringify(
|
|
751
|
+
summary: r.summary,
|
|
752
|
+
question: o,
|
|
753
|
+
fullContext: JSON.stringify(r.fullContext)
|
|
754
754
|
}
|
|
755
755
|
})).answer
|
|
756
756
|
} : {
|
|
757
757
|
status: "success",
|
|
758
758
|
outputMessage: "I do not have group analytics context yet. Ask me to analyze a group first with analyze group <group id>."
|
|
759
759
|
};
|
|
760
|
-
},
|
|
761
|
-
answer:
|
|
762
|
-
isRelevant:
|
|
763
|
-
}),
|
|
760
|
+
}, Ht = s.object({
|
|
761
|
+
answer: s.string(),
|
|
762
|
+
isRelevant: s.boolean()
|
|
763
|
+
}), Xt = `
|
|
764
764
|
Classify the user's request for ArcGIS Portal group analytics.
|
|
765
765
|
|
|
766
766
|
Rules:
|
|
@@ -789,121 +789,121 @@ hasAnalyticsContext:
|
|
|
789
789
|
|
|
790
790
|
User message:
|
|
791
791
|
{userMessage}
|
|
792
|
-
`,
|
|
793
|
-
await
|
|
794
|
-
const a =
|
|
792
|
+
`, Zt = async (e, t) => {
|
|
793
|
+
await m({ text: "Analyzing group-analytics intent...", agentName: "group-analytics" }, t);
|
|
794
|
+
const a = I(e.agentExecutionContext.messages), n = !!U(e).latestGroupId, r = await W.fromTemplate(Xt).format({
|
|
795
795
|
userMessage: a,
|
|
796
796
|
hasAnalyticsContext: String(n)
|
|
797
|
-
}),
|
|
798
|
-
let
|
|
799
|
-
if ((
|
|
800
|
-
const y =
|
|
801
|
-
y && (
|
|
797
|
+
}), u = (await Q({ modelTier: "fast" })).withStructuredOutput(ne), i = ne.parse(await u.invoke(r));
|
|
798
|
+
let l = i.groupId;
|
|
799
|
+
if ((i.intent === "summarize" || i.intent === "navigation") && !l) {
|
|
800
|
+
const y = C(a, "$");
|
|
801
|
+
y && (l = await xe.invoke({ groupTitle: y }, t) ?? "");
|
|
802
802
|
}
|
|
803
|
-
const { intent:
|
|
803
|
+
const { intent: c, question: d } = i, g = c === "summarize" && !l, p = c === "followUp" && !(d ?? "").trim(), f = c === "clarify" || g || p;
|
|
804
804
|
return {
|
|
805
|
-
groupSummaryIntent: f ? "clarify" :
|
|
806
|
-
groupSummaryGroupId:
|
|
807
|
-
groupSummaryQuestion:
|
|
805
|
+
groupSummaryIntent: f ? "clarify" : c,
|
|
806
|
+
groupSummaryGroupId: l || null,
|
|
807
|
+
groupSummaryQuestion: d || "",
|
|
808
808
|
status: "success",
|
|
809
809
|
outputMessage: f ? "Please clarify with a group id or title" : ""
|
|
810
810
|
};
|
|
811
|
-
},
|
|
812
|
-
intent:
|
|
813
|
-
groupId:
|
|
814
|
-
question:
|
|
815
|
-
}),
|
|
816
|
-
const a =
|
|
817
|
-
return await
|
|
811
|
+
}, ne = s.object({
|
|
812
|
+
intent: s.enum(["summarize", "followUp", "navigation", "clarify"]),
|
|
813
|
+
groupId: s.string().default(""),
|
|
814
|
+
question: s.string().default("")
|
|
815
|
+
}), ea = async (e, t) => {
|
|
816
|
+
const a = U(e), n = e.groupSummaryGroupId ?? a.latestGroupId;
|
|
817
|
+
return await m({ text: "Preparing navigation...", agentName: "group-analytics" }, t), await D(
|
|
818
818
|
n ? { destinationType: "portal-group", groupId: n } : { destinationType: "portal-groups" },
|
|
819
|
-
|
|
819
|
+
t
|
|
820
820
|
), { status: "success" };
|
|
821
821
|
};
|
|
822
|
-
function
|
|
823
|
-
return
|
|
822
|
+
function Ge({ timestamp: e, now: t, windowMs: a }) {
|
|
823
|
+
return e ? t - e <= a : !1;
|
|
824
824
|
}
|
|
825
|
-
const
|
|
826
|
-
function
|
|
827
|
-
const
|
|
825
|
+
const ta = 720 * 60 * 60 * 1e3;
|
|
826
|
+
function aa(e) {
|
|
827
|
+
const t = Ze(e);
|
|
828
828
|
return {
|
|
829
|
-
id:
|
|
830
|
-
title:
|
|
831
|
-
description:
|
|
832
|
-
snippet:
|
|
833
|
-
access:
|
|
834
|
-
owner:
|
|
835
|
-
tags:
|
|
836
|
-
created:
|
|
837
|
-
modified:
|
|
838
|
-
isInvitationOnly:
|
|
829
|
+
id: e.id ?? "",
|
|
830
|
+
title: e.title ?? "",
|
|
831
|
+
description: e.description ?? "",
|
|
832
|
+
snippet: e.snippet ?? "",
|
|
833
|
+
access: e.access ?? null,
|
|
834
|
+
owner: e.owner ?? "",
|
|
835
|
+
tags: e.tags ?? [],
|
|
836
|
+
created: e.created?.getTime(),
|
|
837
|
+
modified: e.modified?.getTime(),
|
|
838
|
+
isInvitationOnly: e.isInvitationOnly,
|
|
839
839
|
sourceSignals: {
|
|
840
|
-
capabilities:
|
|
841
|
-
membershipAccess:
|
|
842
|
-
isOpenData:
|
|
843
|
-
isDistributedCollaborationGroup:
|
|
844
|
-
orgId:
|
|
845
|
-
hiddenMembers:
|
|
846
|
-
isViewOnly:
|
|
847
|
-
isReadOnly:
|
|
848
|
-
leavingDisallowed:
|
|
840
|
+
capabilities: nt(e),
|
|
841
|
+
membershipAccess: at(e),
|
|
842
|
+
isOpenData: tt(e),
|
|
843
|
+
isDistributedCollaborationGroup: et(e),
|
|
844
|
+
orgId: t.orgId,
|
|
845
|
+
hiddenMembers: t.hiddenMembers,
|
|
846
|
+
isViewOnly: t.isViewOnly,
|
|
847
|
+
isReadOnly: t.isReadOnly,
|
|
848
|
+
leavingDisallowed: t.leavingDisallowed
|
|
849
849
|
}
|
|
850
850
|
};
|
|
851
851
|
}
|
|
852
|
-
async function
|
|
853
|
-
const
|
|
852
|
+
async function na(e) {
|
|
853
|
+
const t = { owner: e.owner ?? "", admins: [], users: [] };
|
|
854
854
|
try {
|
|
855
|
-
return await
|
|
855
|
+
return await e.fetchMembers();
|
|
856
856
|
} catch (a) {
|
|
857
|
-
return console.warn("Unable to fetch group members for analytics context", a),
|
|
857
|
+
return console.warn("Unable to fetch group members for analytics context", a), t;
|
|
858
858
|
}
|
|
859
859
|
}
|
|
860
|
-
function
|
|
861
|
-
return
|
|
862
|
-
id:
|
|
863
|
-
title:
|
|
864
|
-
type:
|
|
865
|
-
owner:
|
|
866
|
-
created:
|
|
867
|
-
modified:
|
|
860
|
+
function ra(e) {
|
|
861
|
+
return e.map((t) => ({
|
|
862
|
+
id: t.id ?? "",
|
|
863
|
+
title: t.title ?? "Untitled",
|
|
864
|
+
type: t.type ?? "Unknown",
|
|
865
|
+
owner: t.owner ?? "",
|
|
866
|
+
created: t.created?.getTime(),
|
|
867
|
+
modified: t.modified?.getTime()
|
|
868
868
|
}));
|
|
869
869
|
}
|
|
870
|
-
function
|
|
871
|
-
return
|
|
872
|
-
(a) => a.modified ?
|
|
870
|
+
function oa(e, t) {
|
|
871
|
+
return e.filter(
|
|
872
|
+
(a) => a.modified ? Ge({ timestamp: a.modified, now: t, windowMs: ta }) : !1
|
|
873
873
|
);
|
|
874
874
|
}
|
|
875
|
-
function
|
|
876
|
-
const
|
|
877
|
-
for (const a of
|
|
878
|
-
|
|
879
|
-
return [...
|
|
875
|
+
function sa(e) {
|
|
876
|
+
const t = /* @__PURE__ */ new Map();
|
|
877
|
+
for (const a of e)
|
|
878
|
+
t.set(a.type, (t.get(a.type) ?? 0) + 1);
|
|
879
|
+
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 }));
|
|
880
880
|
}
|
|
881
|
-
async function
|
|
882
|
-
const
|
|
881
|
+
async function ia(e) {
|
|
882
|
+
const t = await e.queryItems({ num: 20, sortField: "modified", sortOrder: "desc" }), a = ra(t.results), n = Date.now();
|
|
883
883
|
return {
|
|
884
|
-
total:
|
|
884
|
+
total: t.total,
|
|
885
885
|
topItems: a,
|
|
886
|
-
recentlyModifiedItems:
|
|
887
|
-
topItemTypes:
|
|
886
|
+
recentlyModifiedItems: oa(a, n),
|
|
887
|
+
topItemTypes: sa(a)
|
|
888
888
|
};
|
|
889
889
|
}
|
|
890
|
-
async function
|
|
891
|
-
if (!
|
|
890
|
+
async function ua(e, t) {
|
|
891
|
+
if (!t)
|
|
892
892
|
return { error: { code: "missingGroupId", message: "Group id is required." } };
|
|
893
893
|
try {
|
|
894
|
-
const n = (await
|
|
894
|
+
const n = (await e.queryGroups({ query: `id:${t}`, num: 1 })).results[0];
|
|
895
895
|
if (!n)
|
|
896
|
-
return { error: { code: "groupNotFound", message: `No group found for id: ${
|
|
897
|
-
const
|
|
898
|
-
return { result: { group:
|
|
896
|
+
return { error: { code: "groupNotFound", message: `No group found for id: ${t}` } };
|
|
897
|
+
const r = aa(n), o = await na(n), u = await ia(n);
|
|
898
|
+
return { result: { group: r, members: o, items: u } };
|
|
899
899
|
} catch (a) {
|
|
900
900
|
return console.error("Error fetching portal group analytics context:", a), { error: { code: "unhandledError" } };
|
|
901
901
|
}
|
|
902
902
|
}
|
|
903
|
-
const
|
|
903
|
+
const ca = `
|
|
904
904
|
You summarize ArcGIS Portal groups based on structured context and deterministic activity signals.
|
|
905
905
|
|
|
906
|
-
${
|
|
906
|
+
${Ce}
|
|
907
907
|
|
|
908
908
|
Output format requirements:
|
|
909
909
|
- Return concise markdown with clear sections in this order:
|
|
@@ -939,82 +939,82 @@ Group context:
|
|
|
939
939
|
|
|
940
940
|
Deterministic signals:
|
|
941
941
|
{deterministicSignals}
|
|
942
|
-
`,
|
|
943
|
-
const a =
|
|
942
|
+
`, la = 2160 * 60 * 60 * 1e3, da = async (e, t) => {
|
|
943
|
+
const a = e.groupSummaryGroupId;
|
|
944
944
|
if (!a)
|
|
945
945
|
return {
|
|
946
946
|
status: "success",
|
|
947
947
|
outputMessage: 'Please clarify with analyze group <group id>, analyze group $<title>, or analyze group $"<title with spaces>".'
|
|
948
948
|
};
|
|
949
|
-
await
|
|
950
|
-
const n =
|
|
951
|
-
|
|
952
|
-
const { result:
|
|
953
|
-
if (
|
|
954
|
-
return await
|
|
949
|
+
await m({ text: `Analyzing group ${a}...`, agentName: "group-analytics" }, t);
|
|
950
|
+
const n = t?.configurable?.context;
|
|
951
|
+
T(n);
|
|
952
|
+
const { result: r, error: o } = await ua(n.portal, a);
|
|
953
|
+
if (o || !r)
|
|
954
|
+
return await m({ text: "Failed to fetch group context", agentName: "group-analytics" }, t), {
|
|
955
955
|
status: "success",
|
|
956
956
|
outputMessage: "Unable to retrieve group context for analytics."
|
|
957
957
|
};
|
|
958
|
-
const { group:
|
|
959
|
-
promptText:
|
|
960
|
-
schema:
|
|
958
|
+
const { group: u, items: i } = r, l = Date.now(), c = u.modified, d = c ? Ge({ timestamp: c, now: l, windowMs: la }) : !1, g = i.recentlyModifiedItems.length, p = g > 0, f = d || p, y = await v({
|
|
959
|
+
promptText: ca,
|
|
960
|
+
schema: pa,
|
|
961
961
|
modelTier: "default",
|
|
962
962
|
inputVariables: {
|
|
963
|
-
context: JSON.stringify(
|
|
963
|
+
context: JSON.stringify(r),
|
|
964
964
|
deterministicSignals: JSON.stringify({
|
|
965
965
|
isGroupActive: f,
|
|
966
|
-
isGroupRecentlyModified:
|
|
966
|
+
isGroupRecentlyModified: d,
|
|
967
967
|
hasRecentlyAddedOrUpdatedContent: p,
|
|
968
|
-
recentItemCount:
|
|
968
|
+
recentItemCount: g
|
|
969
969
|
})
|
|
970
970
|
}
|
|
971
|
-
}), { followUpQuestions:
|
|
971
|
+
}), { followUpQuestions: x, summary: M } = y, Re = U(e), De = {
|
|
972
972
|
latestGroupId: a,
|
|
973
973
|
memory: {
|
|
974
|
-
...
|
|
975
|
-
[a]: { summary: M, followUpQuestions:
|
|
974
|
+
...Re.memory,
|
|
975
|
+
[a]: { summary: M, followUpQuestions: x, fullContext: r }
|
|
976
976
|
}
|
|
977
977
|
};
|
|
978
|
-
return
|
|
978
|
+
return x.length && await B({ type: "suggested-prompts", data: { prompts: x } }, t), {
|
|
979
979
|
status: "success",
|
|
980
980
|
outputMessage: M,
|
|
981
|
-
sharedStatePatch: { portalGroupSummaryMemory: { value:
|
|
981
|
+
sharedStatePatch: { portalGroupSummaryMemory: { value: De } }
|
|
982
982
|
};
|
|
983
|
-
},
|
|
984
|
-
summary:
|
|
985
|
-
followUpQuestions:
|
|
986
|
-
}),
|
|
987
|
-
...
|
|
983
|
+
}, pa = s.object({
|
|
984
|
+
summary: s.string(),
|
|
985
|
+
followUpQuestions: s.array(s.string()).default([])
|
|
986
|
+
}), F = (e, t) => t ?? e, Ae = h.Root({
|
|
987
|
+
...N(),
|
|
988
988
|
groupSummaryIntent: h({
|
|
989
|
-
reducer:
|
|
989
|
+
reducer: F,
|
|
990
990
|
default: () => "clarify"
|
|
991
991
|
}),
|
|
992
992
|
groupSummaryGroupId: h({
|
|
993
|
-
reducer:
|
|
993
|
+
reducer: F,
|
|
994
994
|
default: () => null
|
|
995
995
|
}),
|
|
996
996
|
groupSummaryQuestion: h({
|
|
997
|
-
reducer:
|
|
997
|
+
reducer: F,
|
|
998
998
|
default: () => ""
|
|
999
999
|
})
|
|
1000
|
-
}),
|
|
1000
|
+
}), ma = () => new G(Ae).addNode("detectGroupSummaryIntent", Zt).addNode("summarizePortalGroup", da).addNode("answerGroupSummaryFollowUp", Yt).addNode("suggestGroupSummaryNavigation", ea).addEdge(A, "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), ga = String.raw`- **portal-group-analytics** - Portal group analytics assistant:
|
|
1001
1001
|
- summarizes ArcGIS portal groups from group context and sourceJSON details
|
|
1002
1002
|
- answers follow-up questions grounded in the summarized group
|
|
1003
1003
|
- suggests navigation to groups when relevant
|
|
1004
|
-
`,
|
|
1004
|
+
`, ha = {
|
|
1005
1005
|
id: "portal-group-analytics",
|
|
1006
1006
|
name: "Portal Group Analytics",
|
|
1007
|
-
description:
|
|
1008
|
-
createGraph:
|
|
1009
|
-
workspace:
|
|
1010
|
-
},
|
|
1011
|
-
const
|
|
1012
|
-
return
|
|
1013
|
-
},
|
|
1014
|
-
intent:
|
|
1015
|
-
itemId:
|
|
1016
|
-
question:
|
|
1017
|
-
}),
|
|
1007
|
+
description: ga,
|
|
1008
|
+
createGraph: ma,
|
|
1009
|
+
workspace: Ae
|
|
1010
|
+
}, fa = () => ({ latestItemId: null, memory: {} }), J = (e) => {
|
|
1011
|
+
const t = e?.agentExecutionContext.sharedState.portalItemAnalyticsSummaryMemory?.value;
|
|
1012
|
+
return t ? { latestItemId: t.latestItemId, memory: t.memory } : fa();
|
|
1013
|
+
}, re = s.object({
|
|
1014
|
+
intent: s.enum(["summarize", "followUp", "clarify"]),
|
|
1015
|
+
itemId: s.string().default(""),
|
|
1016
|
+
question: s.string().default("")
|
|
1017
|
+
}), ya = s.object({ summary: s.string(), followUpQuestions: s.array(s.string()).default([]) }), wa = s.object({ answer: s.string(), isRelevant: s.boolean() }), ba = `
|
|
1018
1018
|
You answer follow-up questions about an ArcGIS item.
|
|
1019
1019
|
|
|
1020
1020
|
Ground your answer in the provided item context.
|
|
@@ -1034,26 +1034,26 @@ Item full context
|
|
|
1034
1034
|
|
|
1035
1035
|
Question:
|
|
1036
1036
|
{question}
|
|
1037
|
-
`,
|
|
1038
|
-
await
|
|
1039
|
-
const a =
|
|
1040
|
-
return
|
|
1037
|
+
`, va = async (e, t) => {
|
|
1038
|
+
await m({ text: "Answering follow-up...", agentName: "analytics" }, t);
|
|
1039
|
+
const a = J(e), n = e.analyticsItemId ?? a.latestItemId, r = n ? a.memory[n] : void 0, o = e.analyticsQuestion || I(e.agentExecutionContext.messages);
|
|
1040
|
+
return r ? {
|
|
1041
1041
|
status: "success",
|
|
1042
1042
|
outputMessage: (await v({
|
|
1043
|
-
promptText:
|
|
1044
|
-
schema:
|
|
1043
|
+
promptText: ba,
|
|
1044
|
+
schema: wa,
|
|
1045
1045
|
modelTier: "default",
|
|
1046
1046
|
inputVariables: {
|
|
1047
|
-
summary:
|
|
1048
|
-
question:
|
|
1049
|
-
fullContext: JSON.stringify(
|
|
1047
|
+
summary: r.summary,
|
|
1048
|
+
question: o,
|
|
1049
|
+
fullContext: JSON.stringify(r.fullContext)
|
|
1050
1050
|
}
|
|
1051
1051
|
})).answer
|
|
1052
1052
|
} : {
|
|
1053
1053
|
status: "success",
|
|
1054
1054
|
outputMessage: "I don't have enough information yet. Please ask me to summarize the item first using summarize item <item id>."
|
|
1055
1055
|
};
|
|
1056
|
-
},
|
|
1056
|
+
}, Ia = `
|
|
1057
1057
|
Classify the user analytics request.
|
|
1058
1058
|
|
|
1059
1059
|
Rules:
|
|
@@ -1083,27 +1083,27 @@ hasSummaryContext:
|
|
|
1083
1083
|
|
|
1084
1084
|
User message:
|
|
1085
1085
|
{userMessage}
|
|
1086
|
-
`,
|
|
1087
|
-
await
|
|
1088
|
-
const a =
|
|
1086
|
+
`, xa = async (e, t) => {
|
|
1087
|
+
await m({ text: "Analyzing intent...", agentName: "analytics" }, t);
|
|
1088
|
+
const a = I(e.agentExecutionContext.messages), n = !!J(e).latestItemId, r = await W.fromTemplate(Ia).format({
|
|
1089
1089
|
userMessage: a,
|
|
1090
1090
|
hasSummaryContext: String(n)
|
|
1091
|
-
}),
|
|
1092
|
-
let
|
|
1093
|
-
if (
|
|
1094
|
-
const y =
|
|
1095
|
-
y && (
|
|
1091
|
+
}), u = (await Q({ modelTier: "fast" })).withStructuredOutput(re), i = re.parse(await u.invoke(r));
|
|
1092
|
+
let l = i.itemId;
|
|
1093
|
+
if (i.intent === "summarize" && !l) {
|
|
1094
|
+
const y = C(a, "#");
|
|
1095
|
+
y && (l = await Se.invoke({ itemTitle: y }, t) ?? "");
|
|
1096
1096
|
}
|
|
1097
|
-
const { intent:
|
|
1097
|
+
const { intent: c, question: d } = i, f = c === "clarify" || c === "summarize" && !l || c === "followUp" && !d;
|
|
1098
1098
|
return {
|
|
1099
|
-
agentExecutionContext: { ...
|
|
1100
|
-
analyticsIntent: f ? "clarify" :
|
|
1101
|
-
analyticsItemId:
|
|
1102
|
-
analyticsQuestion:
|
|
1099
|
+
agentExecutionContext: { ...e.agentExecutionContext },
|
|
1100
|
+
analyticsIntent: f ? "clarify" : c,
|
|
1101
|
+
analyticsItemId: l || null,
|
|
1102
|
+
analyticsQuestion: d || "",
|
|
1103
1103
|
status: "success",
|
|
1104
1104
|
outputMessage: f ? 'Please clarify with summarize item <item id>, summarize item #<title>, or summarize item #"<title with spaces>".' : ""
|
|
1105
1105
|
};
|
|
1106
|
-
},
|
|
1106
|
+
}, Sa = `
|
|
1107
1107
|
You are a item summary tool for ArcGIS. Your job is to summarize an item's info based on the provided context.
|
|
1108
1108
|
Summary rules:
|
|
1109
1109
|
- The summary should be concise markdown, make sure to format the output nicely so it's easy to read.
|
|
@@ -1118,66 +1118,66 @@ Do not include internal identifiers.
|
|
|
1118
1118
|
If the user asks for a detailed summary, you may expand the response up to 300 words.
|
|
1119
1119
|
Item context:
|
|
1120
1120
|
{context}
|
|
1121
|
-
`,
|
|
1122
|
-
const a =
|
|
1121
|
+
`, Ta = async (e, t) => {
|
|
1122
|
+
const a = e.analyticsItemId;
|
|
1123
1123
|
if (!a)
|
|
1124
1124
|
return {
|
|
1125
1125
|
status: "success",
|
|
1126
1126
|
outputMessage: 'Please clarify with summarize item <item id>, summarize item #<title>, or summarize item #"<title with spaces>".'
|
|
1127
1127
|
};
|
|
1128
|
-
await
|
|
1129
|
-
const n =
|
|
1130
|
-
|
|
1131
|
-
const { portal:
|
|
1132
|
-
if (
|
|
1133
|
-
return await
|
|
1128
|
+
await m({ text: `Summarizing item ${a}...`, agentName: "analytics" }, t);
|
|
1129
|
+
const n = t?.configurable?.context;
|
|
1130
|
+
T(n);
|
|
1131
|
+
const { portal: r, user: o } = n, { result: u, error: i } = await Xe(o, r, a);
|
|
1132
|
+
if (i || !u)
|
|
1133
|
+
return await m({ text: "Failed to get item context for summarization", agentName: "analytics" }, t), {
|
|
1134
1134
|
status: "success",
|
|
1135
1135
|
outputMessage: "Unable to retrieve item context for summarization."
|
|
1136
1136
|
};
|
|
1137
|
-
const { context:
|
|
1138
|
-
promptText:
|
|
1139
|
-
schema:
|
|
1137
|
+
const { context: l } = u, c = await v({
|
|
1138
|
+
promptText: Sa,
|
|
1139
|
+
schema: ya,
|
|
1140
1140
|
modelTier: "default",
|
|
1141
|
-
inputVariables: { context: JSON.stringify(
|
|
1142
|
-
}), { followUpQuestions:
|
|
1141
|
+
inputVariables: { context: JSON.stringify(l) }
|
|
1142
|
+
}), { followUpQuestions: d, summary: g } = c, p = J(e), f = {
|
|
1143
1143
|
latestItemId: a,
|
|
1144
1144
|
memory: {
|
|
1145
1145
|
...p.memory,
|
|
1146
|
-
[a]: { summary:
|
|
1146
|
+
[a]: { summary: g, followUpQuestions: d, fullContext: l }
|
|
1147
1147
|
}
|
|
1148
1148
|
};
|
|
1149
|
-
return
|
|
1149
|
+
return d.length && await B({ type: "suggested-prompts", data: { prompts: d } }, t), {
|
|
1150
1150
|
status: "success",
|
|
1151
|
-
outputMessage:
|
|
1151
|
+
outputMessage: g,
|
|
1152
1152
|
sharedStatePatch: { portalItemAnalyticsSummaryMemory: { value: f } }
|
|
1153
1153
|
};
|
|
1154
|
-
},
|
|
1155
|
-
...
|
|
1154
|
+
}, O = (e, t) => t ?? e, Ne = h.Root({
|
|
1155
|
+
...N(),
|
|
1156
1156
|
// States shared only across nodes in the graph, not between invocations
|
|
1157
1157
|
analyticsIntent: h({
|
|
1158
|
-
reducer:
|
|
1158
|
+
reducer: O,
|
|
1159
1159
|
default: () => "clarify"
|
|
1160
1160
|
}),
|
|
1161
1161
|
analyticsItemId: h({
|
|
1162
|
-
reducer:
|
|
1162
|
+
reducer: O,
|
|
1163
1163
|
default: () => null
|
|
1164
1164
|
}),
|
|
1165
1165
|
analyticsQuestion: h({
|
|
1166
|
-
reducer:
|
|
1166
|
+
reducer: O,
|
|
1167
1167
|
default: () => ""
|
|
1168
1168
|
})
|
|
1169
|
-
}),
|
|
1169
|
+
}), Ma = () => new G(Ne).addNode("detectAnalyticsIntent", xa).addNode("summarizePortalItem", Ta).addNode("answerAnalyticsFollowUp", va).addEdge(A, "detectAnalyticsIntent").addConditionalEdges("detectAnalyticsIntent", (t) => t.analyticsIntent === "summarize" ? "summarizePortalItem" : t.analyticsIntent === "followUp" ? "answerAnalyticsFollowUp" : w).addEdge("summarizePortalItem", w).addEdge("answerAnalyticsFollowUp", w), Ca = String.raw`- **portal-item-analytics** - Portal item analytics assistant:
|
|
1170
1170
|
- answers questions about one specific ArcGIS portal item when item context is present
|
|
1171
1171
|
- summarizes item details, metadata, and context grounded in that item
|
|
1172
1172
|
- suggests follow-up prompts grounded in the same item
|
|
1173
1173
|
- use for item-specific requests, not for gallery browsing, featured content, or opening Map Viewer
|
|
1174
|
-
`,
|
|
1174
|
+
`, Ga = {
|
|
1175
1175
|
id: "portal-item-analytics",
|
|
1176
1176
|
name: "Portal Item Analytics",
|
|
1177
|
-
description:
|
|
1178
|
-
createGraph:
|
|
1179
|
-
workspace:
|
|
1180
|
-
},
|
|
1177
|
+
description: Ca,
|
|
1178
|
+
createGraph: Ma,
|
|
1179
|
+
workspace: Ne
|
|
1180
|
+
}, Aa = {
|
|
1181
1181
|
schemaVersion: "1.0",
|
|
1182
1182
|
capabilities: [
|
|
1183
1183
|
{
|
|
@@ -1217,7 +1217,7 @@ Item context:
|
|
|
1217
1217
|
}
|
|
1218
1218
|
}
|
|
1219
1219
|
]
|
|
1220
|
-
},
|
|
1220
|
+
}, Na = {
|
|
1221
1221
|
schemaVersion: "1.0",
|
|
1222
1222
|
capabilities: [
|
|
1223
1223
|
{
|
|
@@ -1271,40 +1271,54 @@ Item context:
|
|
|
1271
1271
|
}
|
|
1272
1272
|
}
|
|
1273
1273
|
]
|
|
1274
|
-
},
|
|
1274
|
+
}, Pa = {
|
|
1275
1275
|
schemaVersion: "1.0",
|
|
1276
|
-
capabilities: [
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1276
|
+
capabilities: [
|
|
1277
|
+
{
|
|
1278
|
+
id: "org-config-mfa",
|
|
1279
|
+
title: "Multifactor Authentication (MFA)",
|
|
1280
|
+
description: "Configure organization-level multifactor authentication (MFA) settings. Administrators can enable MFA for ArcGIS logins, allow recovery codes for members, view MFA adoption status, enforce MFA requirements for all members, manage the MFA exemption list, and designate administrators who can troubleshoot MFA issues.",
|
|
1281
|
+
hints: ["config MFA", "set up MFA"],
|
|
1282
|
+
platforms: ["online", "enterprise"],
|
|
1283
|
+
resolutions: {
|
|
1284
|
+
navigate: {
|
|
1285
|
+
routeKey: "organization",
|
|
1286
|
+
queryParams: {
|
|
1287
|
+
tab: "security"
|
|
1288
|
+
},
|
|
1289
|
+
hash: "settings"
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
]
|
|
1294
|
+
}, qa = {
|
|
1295
|
+
"contentRouteRegistry.ts": Aa,
|
|
1296
|
+
"groupsRouteRegistry.ts": Na,
|
|
1297
|
+
"orgSettingsRouteRegistry.ts": Pa
|
|
1281
1298
|
};
|
|
1282
|
-
function
|
|
1283
|
-
const
|
|
1284
|
-
for (const [n,
|
|
1285
|
-
for (const
|
|
1286
|
-
if (a.has(
|
|
1287
|
-
throw new Error(`${n}: duplicate capability id "${
|
|
1288
|
-
a.add(
|
|
1299
|
+
function oe(e) {
|
|
1300
|
+
const t = [], a = /* @__PURE__ */ new Set();
|
|
1301
|
+
for (const [n, r] of Object.entries(e))
|
|
1302
|
+
for (const o of r.capabilities) {
|
|
1303
|
+
if (a.has(o.id))
|
|
1304
|
+
throw new Error(`${n}: duplicate capability id "${o.id}" across registries`);
|
|
1305
|
+
a.add(o.id), t.push(o);
|
|
1289
1306
|
}
|
|
1290
|
-
return
|
|
1307
|
+
return t;
|
|
1291
1308
|
}
|
|
1292
|
-
let
|
|
1293
|
-
function
|
|
1294
|
-
return (
|
|
1295
|
-
...Ga,
|
|
1296
|
-
...t ? { customCapabilities: t } : {}
|
|
1297
|
-
})), U;
|
|
1309
|
+
let E;
|
|
1310
|
+
function S(e) {
|
|
1311
|
+
return e ? E = oe({ customCapabilities: e }) : E || (E = oe(qa)), E;
|
|
1298
1312
|
}
|
|
1299
|
-
const
|
|
1300
|
-
function
|
|
1301
|
-
return
|
|
1313
|
+
const Ea = /^(?:take me to|navigate to|go to|show me|open)\s+(?:the\s+)?/u;
|
|
1314
|
+
function $(e) {
|
|
1315
|
+
return e.toLowerCase().replace(/[^a-z0-9]+/gu, " ").trim().replace(Ea, "").trim();
|
|
1302
1316
|
}
|
|
1303
|
-
const
|
|
1304
|
-
capabilityIds:
|
|
1305
|
-
confidence:
|
|
1306
|
-
reason:
|
|
1307
|
-
}),
|
|
1317
|
+
const ka = s.object({
|
|
1318
|
+
capabilityIds: s.array(s.string()).default([]),
|
|
1319
|
+
confidence: s.number().min(0).max(1).default(0),
|
|
1320
|
+
reason: s.string().default("")
|
|
1321
|
+
}), se = 0.8, za = String.raw`You select Portal navigation capabilities for a user's request.
|
|
1308
1322
|
|
|
1309
1323
|
Select only capability IDs from the supplied candidates. Return an empty array when none fit.
|
|
1310
1324
|
A named surface is required: do not select a capability on another Portal surface.
|
|
@@ -1314,45 +1328,45 @@ User request:
|
|
|
1314
1328
|
{userRequest}
|
|
1315
1329
|
|
|
1316
1330
|
Candidates:
|
|
1317
|
-
{candidates}`,
|
|
1318
|
-
if (
|
|
1331
|
+
{candidates}`, $a = async (e, t) => {
|
|
1332
|
+
if (e.outputMessage || e.targets.length === 0)
|
|
1319
1333
|
return {};
|
|
1320
|
-
const a =
|
|
1334
|
+
const a = I(e.agentExecutionContext.messages).trim(), n = Ra(a, e);
|
|
1321
1335
|
if (n.length === 1)
|
|
1322
1336
|
return console.info("[arcgis-portal-ai-assistant] navigation capability selection:", {
|
|
1323
1337
|
method: "exact-match",
|
|
1324
1338
|
request: a,
|
|
1325
1339
|
selectedCapabilityIds: n
|
|
1326
1340
|
}), { chosenCapabilityIds: n };
|
|
1327
|
-
await
|
|
1328
|
-
const
|
|
1329
|
-
|
|
1330
|
-
id:
|
|
1331
|
-
title:
|
|
1332
|
-
description:
|
|
1333
|
-
route:
|
|
1334
|
-
keywordScore:
|
|
1335
|
-
semanticScore:
|
|
1341
|
+
await m({ text: "Choosing a navigation destination...", agentName: "navigation" }, t);
|
|
1342
|
+
const r = JSON.stringify(
|
|
1343
|
+
e.targets.map(({ capability: o, keywordScore: u, semanticScore: i }) => ({
|
|
1344
|
+
id: o.id,
|
|
1345
|
+
title: o.title,
|
|
1346
|
+
description: o.description,
|
|
1347
|
+
route: o.resolutions.navigate,
|
|
1348
|
+
keywordScore: u,
|
|
1349
|
+
semanticScore: i
|
|
1336
1350
|
}))
|
|
1337
1351
|
);
|
|
1338
1352
|
try {
|
|
1339
|
-
const
|
|
1340
|
-
promptText:
|
|
1341
|
-
schema:
|
|
1353
|
+
const o = await v({
|
|
1354
|
+
promptText: za,
|
|
1355
|
+
schema: ka,
|
|
1342
1356
|
modelTier: "fast",
|
|
1343
|
-
inputVariables: { candidates:
|
|
1344
|
-
}),
|
|
1357
|
+
inputVariables: { candidates: r, userRequest: a }
|
|
1358
|
+
}), u = new Set(e.targets.map(({ capability: l }) => l.id)), i = o.capabilityIds.filter((l) => u.has(l));
|
|
1345
1359
|
return console.info("[arcgis-portal-ai-assistant] navigation capability selection:", {
|
|
1346
|
-
confidence:
|
|
1360
|
+
confidence: o.confidence,
|
|
1347
1361
|
method: "structured-model",
|
|
1348
|
-
reason:
|
|
1362
|
+
reason: o.reason,
|
|
1349
1363
|
request: a,
|
|
1350
|
-
selectedCapabilityIds:
|
|
1351
|
-
}),
|
|
1364
|
+
selectedCapabilityIds: i
|
|
1365
|
+
}), o.confidence < se ? {
|
|
1352
1366
|
chosenCapabilityIds: [],
|
|
1353
1367
|
status: "failed",
|
|
1354
|
-
summary: `Navigation selection confidence ${
|
|
1355
|
-
} : { chosenCapabilityIds:
|
|
1368
|
+
summary: `Navigation selection confidence ${o.confidence} is below the required ${se}; defer to the Portal Doc Assistant.`
|
|
1369
|
+
} : { chosenCapabilityIds: i };
|
|
1356
1370
|
} catch {
|
|
1357
1371
|
return console.info("[arcgis-portal-ai-assistant] navigation capability selection:", {
|
|
1358
1372
|
method: "structured-model-unavailable",
|
|
@@ -1361,28 +1375,140 @@ Candidates:
|
|
|
1361
1375
|
}), { chosenCapabilityIds: [] };
|
|
1362
1376
|
}
|
|
1363
1377
|
};
|
|
1364
|
-
function
|
|
1365
|
-
const a =
|
|
1366
|
-
return
|
|
1378
|
+
function Ra(e, t) {
|
|
1379
|
+
const a = $(e);
|
|
1380
|
+
return t.targets.filter(
|
|
1367
1381
|
({ capability: n }) => [n.title, ...n.hints].some(
|
|
1368
|
-
(
|
|
1382
|
+
(r) => $(r) === a
|
|
1369
1383
|
)
|
|
1370
1384
|
).map(({ capability: n }) => n.id);
|
|
1371
1385
|
}
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1386
|
+
const Pe = /* @__PURE__ */ new Set(["1d", "7d", "14d", "30d", "3m", "6m"]), Da = s.object({
|
|
1387
|
+
period: s.string(),
|
|
1388
|
+
startTime: s.string(),
|
|
1389
|
+
endTime: s.string()
|
|
1390
|
+
}), Ua = String.raw`Extract temporal filters for an ArcGIS storage-credits query.
|
|
1391
|
+
|
|
1392
|
+
Return JSON only with these optional string fields:
|
|
1393
|
+
- period
|
|
1394
|
+
- startTime
|
|
1395
|
+
- endTime
|
|
1396
|
+
|
|
1397
|
+
Rules:
|
|
1398
|
+
- period must use <integer><unit> with unit in d,w,m (examples: 7d, 2w, 3m).
|
|
1399
|
+
- If the request is a relative range and period can be determined, always include period.
|
|
1400
|
+
- For "last quarter" or "previous quarter", use calendar-quarter boundaries and include period as 3m with both startTime and endTime.
|
|
1401
|
+
- For "last quarter" or "previous quarter", endTime must be the UTC end of the previous quarter, not "now".
|
|
1402
|
+
- If period matches one of these supported periods and the range ends today, period alone is sufficient:
|
|
1403
|
+
1d, 7d, 14d, 30d, 3m, 6m.
|
|
1404
|
+
- If the request implies a range not supported as period (for example 2m or 10d), include startTime and endTime.
|
|
1405
|
+
- For custom date ranges (for example "last december"), provide startTime and endTime.
|
|
1406
|
+
- startTime and endTime must be epoch milliseconds as strings.
|
|
1407
|
+
- If the end of range is "now", set endTime to {nowEpochMs}.
|
|
1408
|
+
- If temporal intent is unclear, return empty strings for all fields.
|
|
1409
|
+
|
|
1410
|
+
Now UTC:
|
|
1411
|
+
- ISO: {nowIso}
|
|
1412
|
+
- Epoch ms: {nowEpochMs}
|
|
1413
|
+
|
|
1414
|
+
User request:
|
|
1415
|
+
{userRequest}`;
|
|
1416
|
+
async function Fa(e, t = /* @__PURE__ */ new Date()) {
|
|
1417
|
+
const a = e.trim();
|
|
1418
|
+
if (!a)
|
|
1419
|
+
return {};
|
|
1420
|
+
try {
|
|
1421
|
+
const n = await v({
|
|
1422
|
+
promptText: Ua,
|
|
1423
|
+
schema: Da,
|
|
1424
|
+
modelTier: "fast",
|
|
1425
|
+
inputVariables: {
|
|
1426
|
+
nowEpochMs: String(t.getTime()),
|
|
1427
|
+
nowIso: t.toISOString(),
|
|
1428
|
+
userRequest: a
|
|
1429
|
+
}
|
|
1430
|
+
});
|
|
1431
|
+
return Oa(n, t);
|
|
1432
|
+
} catch (n) {
|
|
1433
|
+
return console.error(n), {};
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
function Oa(e, t = /* @__PURE__ */ new Date()) {
|
|
1437
|
+
const a = ie(e.startTime), n = ie(e.endTime), r = Ka(e.period);
|
|
1438
|
+
if (r) {
|
|
1439
|
+
if (a !== void 0 && n !== void 0 && a < n)
|
|
1440
|
+
return { period: r, startTime: String(a), endTime: String(n) };
|
|
1441
|
+
const o = Pe.has(r);
|
|
1442
|
+
if (!o || n !== void 0 && !ja(n, t.getTime())) {
|
|
1443
|
+
const i = n ?? t.getTime(), l = Va(r, new Date(i));
|
|
1444
|
+
if (l !== void 0)
|
|
1445
|
+
return {
|
|
1446
|
+
period: r,
|
|
1447
|
+
startTime: String(l),
|
|
1448
|
+
endTime: String(i)
|
|
1449
|
+
};
|
|
1450
|
+
}
|
|
1451
|
+
return o ? {
|
|
1452
|
+
period: r,
|
|
1453
|
+
...a !== void 0 ? { startTime: String(a) } : {},
|
|
1454
|
+
...n !== void 0 ? { endTime: String(n) } : {}
|
|
1455
|
+
} : { period: r };
|
|
1456
|
+
}
|
|
1457
|
+
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()) } : {};
|
|
1458
|
+
}
|
|
1459
|
+
function Ka(e) {
|
|
1460
|
+
const t = e?.trim().match(/^(\d+)\s*([dwm])$/iu);
|
|
1461
|
+
if (!t)
|
|
1462
|
+
return;
|
|
1463
|
+
const a = Number.parseInt(t[1], 10);
|
|
1464
|
+
if (!Number.isFinite(a) || a <= 0)
|
|
1465
|
+
return;
|
|
1466
|
+
const n = t[2].toLowerCase();
|
|
1467
|
+
if (n === "w") {
|
|
1468
|
+
const r = a * 7;
|
|
1469
|
+
if (Pe.has(`${r}d`))
|
|
1470
|
+
return `${r}d`;
|
|
1471
|
+
}
|
|
1472
|
+
return `${a}${n}`;
|
|
1473
|
+
}
|
|
1474
|
+
function Va(e, t) {
|
|
1475
|
+
const a = e.match(/^(\d+)([dwm])$/u);
|
|
1476
|
+
if (!a)
|
|
1477
|
+
return;
|
|
1478
|
+
const n = Number.parseInt(a[1], 10);
|
|
1479
|
+
if (!Number.isFinite(n) || n <= 0)
|
|
1480
|
+
return;
|
|
1481
|
+
const r = a[2];
|
|
1482
|
+
if (r === "d")
|
|
1483
|
+
return t.getTime() - n * 24 * 60 * 60 * 1e3;
|
|
1484
|
+
if (r === "w")
|
|
1485
|
+
return t.getTime() - n * 7 * 24 * 60 * 60 * 1e3;
|
|
1486
|
+
const o = new Date(t.getTime());
|
|
1487
|
+
return o.setUTCMonth(o.getUTCMonth() - n), o.getTime();
|
|
1488
|
+
}
|
|
1489
|
+
function ie(e) {
|
|
1490
|
+
if (!e)
|
|
1491
|
+
return;
|
|
1492
|
+
const t = Number.parseInt(e, 10);
|
|
1493
|
+
if (!(!Number.isFinite(t) || t <= 0))
|
|
1494
|
+
return t;
|
|
1377
1495
|
}
|
|
1378
|
-
function
|
|
1379
|
-
|
|
1496
|
+
function ja(e, t) {
|
|
1497
|
+
const a = new Date(e), n = new Date(t);
|
|
1498
|
+
return a.getUTCFullYear() === n.getUTCFullYear() && a.getUTCMonth() === n.getUTCMonth() && a.getUTCDate() === n.getUTCDate();
|
|
1380
1499
|
}
|
|
1381
|
-
function
|
|
1382
|
-
const
|
|
1500
|
+
async function La(e, t, a) {
|
|
1501
|
+
const n = S().find((o) => o.id === e);
|
|
1502
|
+
if (!n)
|
|
1503
|
+
return;
|
|
1504
|
+
const r = await Qa(Ba(n), a);
|
|
1505
|
+
return r && Ja(r, t) ? { capability: n, target: r } : void 0;
|
|
1506
|
+
}
|
|
1507
|
+
function Ba(e) {
|
|
1508
|
+
const { hash: t, queryParams: a, routeKey: n } = e.resolutions.navigate;
|
|
1383
1509
|
switch (n) {
|
|
1384
1510
|
case "content":
|
|
1385
|
-
switch (
|
|
1511
|
+
switch (e.id) {
|
|
1386
1512
|
case "my-content":
|
|
1387
1513
|
return { destinationType: "portal-content", t9nKey: "myContent" };
|
|
1388
1514
|
case "create-feature-layer":
|
|
@@ -1393,11 +1519,11 @@ function $a(t) {
|
|
|
1393
1519
|
return { destinationType: "portal-content" };
|
|
1394
1520
|
}
|
|
1395
1521
|
case "groups":
|
|
1396
|
-
if (
|
|
1522
|
+
if (t === "featured")
|
|
1397
1523
|
return { destinationType: "portal-groups", hash: "featured", t9nKey: "featuredGroups" };
|
|
1398
|
-
if (
|
|
1524
|
+
if (t === "organization")
|
|
1399
1525
|
return { destinationType: "portal-groups", hash: "organization", t9nKey: "organizationGroups" };
|
|
1400
|
-
switch (
|
|
1526
|
+
switch (e.id) {
|
|
1401
1527
|
case "my groups":
|
|
1402
1528
|
return { destinationType: "portal-groups", hash: "my", t9nKey: "myGroups" };
|
|
1403
1529
|
case "create-group":
|
|
@@ -1408,236 +1534,260 @@ function $a(t) {
|
|
|
1408
1534
|
case "organization":
|
|
1409
1535
|
return {
|
|
1410
1536
|
destinationType: "portal-org",
|
|
1411
|
-
hash:
|
|
1537
|
+
hash: t,
|
|
1412
1538
|
queryParams: a,
|
|
1413
|
-
buttonLabel:
|
|
1539
|
+
buttonLabel: e.buttonLabel
|
|
1414
1540
|
};
|
|
1415
1541
|
default:
|
|
1416
1542
|
return;
|
|
1417
1543
|
}
|
|
1418
1544
|
}
|
|
1419
|
-
function
|
|
1420
|
-
|
|
1545
|
+
async function Qa(e, t) {
|
|
1546
|
+
if (!e || !t || !Wa(e))
|
|
1547
|
+
return e;
|
|
1548
|
+
const a = await Fa(t);
|
|
1549
|
+
if (!a.period && !a.startTime && !a.endTime)
|
|
1550
|
+
return e;
|
|
1551
|
+
const n = {
|
|
1552
|
+
...e.queryParams,
|
|
1553
|
+
...a.period ? { period: a.period } : {},
|
|
1554
|
+
...a.startTime ? { startTime: a.startTime } : {},
|
|
1555
|
+
...a.endTime ? { endTime: a.endTime } : {}
|
|
1556
|
+
};
|
|
1557
|
+
return { ...e, queryParams: n };
|
|
1558
|
+
}
|
|
1559
|
+
function Wa(e) {
|
|
1560
|
+
return e.destinationType === "portal-org" && e.hash === "status";
|
|
1421
1561
|
}
|
|
1422
|
-
|
|
1423
|
-
|
|
1562
|
+
function Ja(e, t) {
|
|
1563
|
+
return !t || !!t[e.destinationType];
|
|
1564
|
+
}
|
|
1565
|
+
const _a = async (e, t) => {
|
|
1566
|
+
if (e.outputMessage || e.status === "failed")
|
|
1424
1567
|
return {};
|
|
1425
|
-
const a =
|
|
1568
|
+
const a = e.targets.find(({ capability: o }) => e.chosenCapabilityIds.includes(o.id)) ?? e.targets[0];
|
|
1426
1569
|
if (!a)
|
|
1427
1570
|
return {
|
|
1428
1571
|
outputMessage: "I couldn't find a matching Portal page. Try asking to open your content, groups, or organization settings.",
|
|
1429
|
-
sharedStatePatch: { navLastAnsweredRequest: { value:
|
|
1572
|
+
sharedStatePatch: { navLastAnsweredRequest: { value: ue(e) } },
|
|
1430
1573
|
status: "success",
|
|
1431
1574
|
summary: "Navigation could not find a matching capability; route another agent if appropriate."
|
|
1432
1575
|
};
|
|
1433
|
-
const n =
|
|
1434
|
-
return
|
|
1435
|
-
outputMessage:
|
|
1576
|
+
const n = ue(e), r = await La(a.capability.id, void 0, n);
|
|
1577
|
+
return r ? (await m({ text: "Preparing navigation...", agentName: "navigation" }, t), await D(r.target, t), {
|
|
1578
|
+
outputMessage: e.chosenCapabilityIds.length ? a.capability.description : `The closest place to start is ${a.capability.title}. Click the button below to open it.`,
|
|
1436
1579
|
status: "success",
|
|
1437
|
-
summary: `Navigation suggested ${a.capability.id}${
|
|
1438
|
-
sharedStatePatch: { navLastAnsweredRequest: { value:
|
|
1580
|
+
summary: `Navigation suggested ${a.capability.id}${e.retrievalDegraded ? " using keyword-only retrieval" : ""}.`,
|
|
1581
|
+
sharedStatePatch: { navLastAnsweredRequest: { value: n } }
|
|
1439
1582
|
}) : (console.warn(`Navigation capability ${a.capability.id} was not found in the resolver.`), {
|
|
1440
1583
|
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.",
|
|
1441
1584
|
status: "success",
|
|
1442
1585
|
summary: `Navigation resolver could not map ${a.capability.id}.`,
|
|
1443
|
-
sharedStatePatch: { navLastAnsweredRequest: { value:
|
|
1586
|
+
sharedStatePatch: { navLastAnsweredRequest: { value: n } }
|
|
1444
1587
|
});
|
|
1445
1588
|
};
|
|
1446
|
-
function
|
|
1447
|
-
return
|
|
1589
|
+
function ue(e) {
|
|
1590
|
+
return I(e.agentExecutionContext.messages) || e.agentExecutionContext.userRequest;
|
|
1448
1591
|
}
|
|
1449
|
-
async function
|
|
1450
|
-
return
|
|
1592
|
+
async function qe(e) {
|
|
1593
|
+
return e.length === 0 ? [] : (await rt.getDefault().load(), await Le(e));
|
|
1451
1594
|
}
|
|
1452
|
-
const
|
|
1595
|
+
const Ya = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
1453
1596
|
__proto__: null,
|
|
1454
|
-
generateEmbeddings:
|
|
1597
|
+
generateEmbeddings: qe
|
|
1455
1598
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
1456
|
-
function
|
|
1457
|
-
const
|
|
1458
|
-
a.trim().length > 0 &&
|
|
1459
|
-
const n =
|
|
1599
|
+
function Ha(e) {
|
|
1600
|
+
const t = [], a = `${e.title}. ${e.description}`;
|
|
1601
|
+
a.trim().length > 0 && t.push({ field: "summary", text: a });
|
|
1602
|
+
const n = e.hints;
|
|
1460
1603
|
if (Array.isArray(n))
|
|
1461
|
-
for (const
|
|
1462
|
-
typeof
|
|
1463
|
-
return
|
|
1604
|
+
for (const r of n)
|
|
1605
|
+
typeof r == "string" && r.trim().length > 0 && t.push({ field: "hint", text: r });
|
|
1606
|
+
return t;
|
|
1607
|
+
}
|
|
1608
|
+
let k, _, z = 0;
|
|
1609
|
+
async function Xa(e = {}) {
|
|
1610
|
+
const t = z;
|
|
1611
|
+
return k ??= en(e.embed ?? tn).then((a) => (t === z && (_ = a), a)).catch((a) => {
|
|
1612
|
+
throw t === z && (k = void 0), a;
|
|
1613
|
+
}), await k;
|
|
1464
1614
|
}
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
return O ??= Va(t.embed ?? ja).then((e) => (Gt = e, e)).catch((e) => {
|
|
1468
|
-
throw O = void 0, e;
|
|
1469
|
-
}), await O;
|
|
1615
|
+
function Za() {
|
|
1616
|
+
return _;
|
|
1470
1617
|
}
|
|
1471
|
-
function
|
|
1472
|
-
|
|
1618
|
+
function ce() {
|
|
1619
|
+
z += 1, _ = void 0, k = void 0;
|
|
1473
1620
|
}
|
|
1474
|
-
async function
|
|
1475
|
-
const
|
|
1476
|
-
if (a.length !==
|
|
1477
|
-
throw new Error(`Expected ${
|
|
1478
|
-
return
|
|
1621
|
+
async function en(e) {
|
|
1622
|
+
const t = an(), a = await e(t.map((n) => n.text));
|
|
1623
|
+
if (a.length !== t.length)
|
|
1624
|
+
throw new Error(`Expected ${t.length} vectors, got ${a.length}`);
|
|
1625
|
+
return t.map((n, r) => ({
|
|
1479
1626
|
...n,
|
|
1480
|
-
vector: a[
|
|
1627
|
+
vector: a[r]
|
|
1481
1628
|
}));
|
|
1482
1629
|
}
|
|
1483
|
-
async function
|
|
1484
|
-
const { generateEmbeddings:
|
|
1485
|
-
return await e
|
|
1630
|
+
async function tn(e) {
|
|
1631
|
+
const { generateEmbeddings: t } = await Promise.resolve().then(() => Ya);
|
|
1632
|
+
return await t(e);
|
|
1486
1633
|
}
|
|
1487
|
-
function
|
|
1488
|
-
return
|
|
1489
|
-
(
|
|
1490
|
-
capabilityId:
|
|
1491
|
-
field:
|
|
1634
|
+
function an() {
|
|
1635
|
+
return S().flatMap(
|
|
1636
|
+
(e) => Ha(e).map(({ field: t, text: a }) => ({
|
|
1637
|
+
capabilityId: e.id,
|
|
1638
|
+
field: t,
|
|
1492
1639
|
text: a
|
|
1493
1640
|
}))
|
|
1494
1641
|
);
|
|
1495
1642
|
}
|
|
1496
|
-
const
|
|
1643
|
+
const le = 1.2, de = 0.75, nn = 60, rn = 0.65, K = {
|
|
1497
1644
|
description: 1,
|
|
1498
1645
|
hint: 2,
|
|
1499
1646
|
title: 3
|
|
1500
1647
|
};
|
|
1501
|
-
let
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1648
|
+
let L;
|
|
1649
|
+
function on() {
|
|
1650
|
+
L = void 0;
|
|
1651
|
+
}
|
|
1652
|
+
async function sn(e, t = {}) {
|
|
1653
|
+
const a = dn(Ee(e));
|
|
1654
|
+
let n = [], r = !1, o;
|
|
1655
|
+
if (e.trim()) {
|
|
1656
|
+
const u = t.loadEmbeddings, i = Za();
|
|
1657
|
+
if (!u && !i)
|
|
1658
|
+
r = !0, o = "Capability embeddings are still loading.";
|
|
1509
1659
|
else
|
|
1510
1660
|
try {
|
|
1511
|
-
if (
|
|
1512
|
-
const [
|
|
1513
|
-
(
|
|
1514
|
-
|
|
1661
|
+
if (u) {
|
|
1662
|
+
const [l, c] = await Promise.all([
|
|
1663
|
+
(t.embedQuery ?? me)(e),
|
|
1664
|
+
u()
|
|
1515
1665
|
]);
|
|
1516
|
-
n =
|
|
1517
|
-
} else if (
|
|
1518
|
-
const
|
|
1519
|
-
n =
|
|
1666
|
+
n = pe(l, c);
|
|
1667
|
+
} else if (i) {
|
|
1668
|
+
const l = await (t.embedQuery ?? me)(e);
|
|
1669
|
+
n = pe(l, i);
|
|
1520
1670
|
}
|
|
1521
1671
|
} catch {
|
|
1522
|
-
|
|
1672
|
+
r = !0, o = "Semantic search is unavailable.";
|
|
1523
1673
|
}
|
|
1524
1674
|
}
|
|
1525
1675
|
return {
|
|
1526
|
-
degraded:
|
|
1527
|
-
...
|
|
1676
|
+
degraded: r,
|
|
1677
|
+
...o ? { degradedReason: o } : {},
|
|
1528
1678
|
// RRF combines ranks rather than raw scores because BM25 and cosine
|
|
1529
1679
|
// similarity are on different scales.
|
|
1530
|
-
matches:
|
|
1680
|
+
matches: mn(a, n, t.topN ?? 5)
|
|
1531
1681
|
};
|
|
1532
1682
|
}
|
|
1533
|
-
function
|
|
1534
|
-
return
|
|
1683
|
+
function un() {
|
|
1684
|
+
return L ??= cn(S()), L;
|
|
1535
1685
|
}
|
|
1536
|
-
function
|
|
1537
|
-
const
|
|
1538
|
-
const
|
|
1539
|
-
V(
|
|
1540
|
-
for (const
|
|
1541
|
-
V(
|
|
1542
|
-
for (const
|
|
1543
|
-
|
|
1686
|
+
function cn(e) {
|
|
1687
|
+
const t = /* @__PURE__ */ new Map(), a = e.map((n) => {
|
|
1688
|
+
const r = /* @__PURE__ */ new Map();
|
|
1689
|
+
V(r, n.title, K.title), V(r, n.description, K.description);
|
|
1690
|
+
for (const o of n.hints)
|
|
1691
|
+
V(r, o, K.hint);
|
|
1692
|
+
for (const o of r.keys())
|
|
1693
|
+
t.set(o, (t.get(o) ?? 0) + 1);
|
|
1544
1694
|
return {
|
|
1545
1695
|
capability: n,
|
|
1546
|
-
length:
|
|
1547
|
-
termFrequencies:
|
|
1696
|
+
length: ln(r),
|
|
1697
|
+
termFrequencies: r
|
|
1548
1698
|
};
|
|
1549
1699
|
});
|
|
1550
1700
|
return {
|
|
1551
|
-
averageDocumentLength: a.length ? a.reduce((n,
|
|
1552
|
-
documentFrequency:
|
|
1701
|
+
averageDocumentLength: a.length ? a.reduce((n, r) => n + r.length, 0) / a.length : 0,
|
|
1702
|
+
documentFrequency: t,
|
|
1553
1703
|
documents: a
|
|
1554
1704
|
};
|
|
1555
1705
|
}
|
|
1556
|
-
function V(
|
|
1557
|
-
for (const n of
|
|
1558
|
-
|
|
1706
|
+
function V(e, t, a) {
|
|
1707
|
+
for (const n of Ee(t))
|
|
1708
|
+
e.set(n, (e.get(n) ?? 0) + a);
|
|
1559
1709
|
}
|
|
1560
|
-
function
|
|
1561
|
-
return [...
|
|
1710
|
+
function ln(e) {
|
|
1711
|
+
return [...e.values()].reduce((t, a) => t + a, 0);
|
|
1562
1712
|
}
|
|
1563
|
-
function
|
|
1564
|
-
return
|
|
1713
|
+
function Ee(e) {
|
|
1714
|
+
return e.toLowerCase().split(/[^a-z0-9]+/u).filter(Boolean);
|
|
1565
1715
|
}
|
|
1566
|
-
function
|
|
1567
|
-
const
|
|
1568
|
-
return
|
|
1569
|
-
let
|
|
1570
|
-
for (const
|
|
1571
|
-
const
|
|
1572
|
-
if (!
|
|
1716
|
+
function dn(e) {
|
|
1717
|
+
const t = un(), a = new Set(e), n = t.documents.length;
|
|
1718
|
+
return t.documents.map(({ capability: r, length: o, termFrequencies: u }) => {
|
|
1719
|
+
let i = 0;
|
|
1720
|
+
for (const l of a) {
|
|
1721
|
+
const c = u.get(l), d = t.documentFrequency.get(l);
|
|
1722
|
+
if (!c || !d)
|
|
1573
1723
|
continue;
|
|
1574
|
-
const
|
|
1575
|
-
|
|
1724
|
+
const g = Math.log(1 + (n - d + 0.5) / (d + 0.5)), p = le * (1 - de + de * (o / t.averageDocumentLength));
|
|
1725
|
+
i += g * (c * (le + 1) / (c + p));
|
|
1576
1726
|
}
|
|
1577
|
-
return { capability:
|
|
1578
|
-
}).filter(({ score:
|
|
1727
|
+
return { capability: r, score: i };
|
|
1728
|
+
}).filter(({ score: r }) => r > 0).sort(ke);
|
|
1579
1729
|
}
|
|
1580
|
-
function
|
|
1730
|
+
function pe(e, t) {
|
|
1581
1731
|
const a = /* @__PURE__ */ new Map();
|
|
1582
|
-
for (const
|
|
1583
|
-
const
|
|
1584
|
-
if (
|
|
1732
|
+
for (const r of t) {
|
|
1733
|
+
const o = pn(e, r.vector);
|
|
1734
|
+
if (o === void 0)
|
|
1585
1735
|
continue;
|
|
1586
|
-
const
|
|
1587
|
-
(
|
|
1736
|
+
const u = a.get(r.capabilityId);
|
|
1737
|
+
(u === void 0 || o > u) && a.set(r.capabilityId, o);
|
|
1588
1738
|
}
|
|
1589
|
-
const n = new Map(
|
|
1590
|
-
return [...a.entries()].flatMap(([
|
|
1591
|
-
const
|
|
1592
|
-
return
|
|
1593
|
-
}).sort(
|
|
1739
|
+
const n = new Map(S().map((r) => [r.id, r]));
|
|
1740
|
+
return [...a.entries()].flatMap(([r, o]) => {
|
|
1741
|
+
const u = n.get(r);
|
|
1742
|
+
return u && o >= rn ? [{ capability: u, score: o }] : [];
|
|
1743
|
+
}).sort(ke);
|
|
1594
1744
|
}
|
|
1595
|
-
function
|
|
1596
|
-
if (
|
|
1745
|
+
function pn(e, t) {
|
|
1746
|
+
if (e.length === 0 || e.length !== t.length)
|
|
1597
1747
|
return;
|
|
1598
|
-
let a = 0, n = 0,
|
|
1599
|
-
for (let
|
|
1600
|
-
a +=
|
|
1601
|
-
const
|
|
1602
|
-
return
|
|
1748
|
+
let a = 0, n = 0, r = 0;
|
|
1749
|
+
for (let u = 0; u < e.length; u += 1)
|
|
1750
|
+
a += e[u] * t[u], n += e[u] ** 2, r += t[u] ** 2;
|
|
1751
|
+
const o = Math.sqrt(n) * Math.sqrt(r);
|
|
1752
|
+
return o === 0 ? void 0 : a / o;
|
|
1603
1753
|
}
|
|
1604
|
-
async function
|
|
1605
|
-
const [
|
|
1606
|
-
if (!
|
|
1754
|
+
async function me(e) {
|
|
1755
|
+
const [t] = await qe([e]);
|
|
1756
|
+
if (!t)
|
|
1607
1757
|
throw new Error("Expected one query embedding.");
|
|
1608
|
-
return
|
|
1758
|
+
return t;
|
|
1609
1759
|
}
|
|
1610
|
-
function
|
|
1760
|
+
function mn(e, t, a) {
|
|
1611
1761
|
const n = /* @__PURE__ */ new Map();
|
|
1612
|
-
return
|
|
1762
|
+
return ge(n, e, "keyword"), ge(n, t, "semantic"), [...n.values()].sort((r, o) => o.score !== r.score ? o.score - r.score : (o.semanticScore ?? 0) !== (r.semanticScore ?? 0) ? (o.semanticScore ?? 0) - (r.semanticScore ?? 0) : (o.keywordScore ?? 0) !== (r.keywordScore ?? 0) ? (o.keywordScore ?? 0) - (r.keywordScore ?? 0) : r.capability.id.localeCompare(o.capability.id)).slice(0, Math.max(0, a));
|
|
1613
1763
|
}
|
|
1614
|
-
function
|
|
1615
|
-
for (const [n, { capability:
|
|
1616
|
-
const
|
|
1617
|
-
|
|
1764
|
+
function ge(e, t, a) {
|
|
1765
|
+
for (const [n, { capability: r, score: o }] of t.entries()) {
|
|
1766
|
+
const u = n + 1, i = e.get(r.id) ?? { capability: r, score: 0 };
|
|
1767
|
+
i.score += 1 / (nn + u), a === "keyword" ? (i.keywordRank = u, i.keywordScore = o) : (i.semanticRank = u, i.semanticScore = o), e.set(r.id, i);
|
|
1618
1768
|
}
|
|
1619
1769
|
}
|
|
1620
|
-
function
|
|
1621
|
-
return
|
|
1770
|
+
function ke(e, t) {
|
|
1771
|
+
return t.score - e.score || e.capability.id.localeCompare(t.capability.id);
|
|
1622
1772
|
}
|
|
1623
|
-
const
|
|
1624
|
-
await
|
|
1625
|
-
const a =
|
|
1773
|
+
const gn = async (e, t) => {
|
|
1774
|
+
await m({ text: "Finding a place to navigate...", agentName: "navigation" }, t);
|
|
1775
|
+
const a = I(e.agentExecutionContext.messages).trim();
|
|
1626
1776
|
try {
|
|
1627
|
-
const n = await
|
|
1777
|
+
const n = await sn(a, { topN: 5 });
|
|
1628
1778
|
return console.table(
|
|
1629
|
-
n.matches.map(({ capability:
|
|
1630
|
-
capability:
|
|
1631
|
-
fusedScore:
|
|
1632
|
-
keywordRank:
|
|
1633
|
-
keywordScore:
|
|
1634
|
-
semanticRank:
|
|
1635
|
-
semanticScore:
|
|
1779
|
+
n.matches.map(({ capability: r, keywordRank: o, keywordScore: u, semanticRank: i, semanticScore: l, score: c }) => ({
|
|
1780
|
+
capability: r.title,
|
|
1781
|
+
fusedScore: c,
|
|
1782
|
+
keywordRank: o,
|
|
1783
|
+
keywordScore: u,
|
|
1784
|
+
semanticRank: i,
|
|
1785
|
+
semanticScore: l
|
|
1636
1786
|
}))
|
|
1637
1787
|
), n.degradedReason && console.info("[arcgis-portal-ai-assistant] navigation semantic search:", n.degradedReason), {
|
|
1638
1788
|
chosenCapabilityIds: [],
|
|
1639
1789
|
retrievalDegraded: n.degradedReason ?? "",
|
|
1640
|
-
targets:
|
|
1790
|
+
targets: hn(a, n.matches)
|
|
1641
1791
|
};
|
|
1642
1792
|
} catch {
|
|
1643
1793
|
return {
|
|
@@ -1648,77 +1798,84 @@ const tn = async (t, e) => {
|
|
|
1648
1798
|
};
|
|
1649
1799
|
}
|
|
1650
1800
|
};
|
|
1651
|
-
function
|
|
1652
|
-
const a =
|
|
1653
|
-
({ capability:
|
|
1654
|
-
(
|
|
1801
|
+
function hn(e, t) {
|
|
1802
|
+
const a = $(e), n = t.filter(
|
|
1803
|
+
({ capability: o }) => [o.title, ...o.hints].some(
|
|
1804
|
+
(u) => $(u) === a
|
|
1655
1805
|
)
|
|
1656
1806
|
);
|
|
1657
1807
|
if (n.length !== 1)
|
|
1658
|
-
return
|
|
1659
|
-
const [
|
|
1660
|
-
return [
|
|
1808
|
+
return t;
|
|
1809
|
+
const [r] = n;
|
|
1810
|
+
return [r, ...t.filter((o) => o !== r)];
|
|
1661
1811
|
}
|
|
1662
|
-
const j = (
|
|
1663
|
-
...
|
|
1812
|
+
const j = (e, t) => t ?? e, ze = h.Root({
|
|
1813
|
+
...N(),
|
|
1664
1814
|
chosenCapabilityIds: h({ reducer: j, default: () => [] }),
|
|
1665
1815
|
// Empty when hybrid keyword-and-semantic retrieval succeeds; otherwise
|
|
1666
1816
|
// contains the semantic-search failure reason for response diagnostics.
|
|
1667
1817
|
retrievalDegraded: h({ reducer: j, default: () => "" }),
|
|
1668
1818
|
targets: h({ reducer: j, default: () => [] })
|
|
1669
|
-
}),
|
|
1819
|
+
}), fn = () => new G(ze).addNode("retrieveNavigationTargets", gn).addNode("chooseNavigationTargets", $a).addNode("respondWithNavigation", _a).addEdge(A, "retrieveNavigationTargets").addEdge("retrieveNavigationTargets", "chooseNavigationTargets").addEdge("chooseNavigationTargets", "respondWithNavigation").addEdge("respondWithNavigation", w);
|
|
1820
|
+
function yn() {
|
|
1821
|
+
const e = S().map(({ hints: t, title: a }) => t[0] ?? a).join(", ");
|
|
1822
|
+
return String.raw`- **portal-navigation** - Portal page navigation assistant:
|
|
1670
1823
|
- routes requests to open, show, or navigate to a Portal page, including creation-flow pages
|
|
1671
1824
|
- falls back to the closest Portal page where a workflow starts when another agent cannot perform the action
|
|
1672
1825
|
- handles short navigation follow-ups after asking the user to open a page
|
|
1673
|
-
- capability examples: ${
|
|
1826
|
+
- capability examples: ${e}
|
|
1674
1827
|
- do not use for general "how do I" questions unless the user explicitly asks to reach a page
|
|
1675
|
-
|
|
1828
|
+
`;
|
|
1829
|
+
}
|
|
1830
|
+
const wn = {
|
|
1676
1831
|
id: "navigation",
|
|
1677
1832
|
name: "Portal Navigation",
|
|
1678
|
-
description
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1833
|
+
get description() {
|
|
1834
|
+
return yn();
|
|
1835
|
+
},
|
|
1836
|
+
createGraph: fn,
|
|
1837
|
+
workspace: ze
|
|
1838
|
+
}, bn = Ke`: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)}`;
|
|
1839
|
+
function vn(e, t) {
|
|
1840
|
+
if (!t)
|
|
1684
1841
|
return;
|
|
1685
|
-
const { destinationType: a } =
|
|
1842
|
+
const { destinationType: a } = e;
|
|
1686
1843
|
switch (a) {
|
|
1687
1844
|
case "portal-content":
|
|
1688
|
-
return
|
|
1845
|
+
return t[a]?.(e.hash);
|
|
1689
1846
|
case "portal-groups":
|
|
1690
|
-
return
|
|
1847
|
+
return t[a]?.(e.hash);
|
|
1691
1848
|
case "portal-org":
|
|
1692
|
-
return
|
|
1849
|
+
return t[a]?.(e.hash, e.queryParams);
|
|
1693
1850
|
case "portal-gallery":
|
|
1694
|
-
return
|
|
1851
|
+
return t[a];
|
|
1695
1852
|
case "portal-map-viewer":
|
|
1696
1853
|
case "portal-notebooks":
|
|
1697
1854
|
case "portal-scene-viewer":
|
|
1698
|
-
return
|
|
1855
|
+
return t[a];
|
|
1699
1856
|
case "portal-item":
|
|
1700
|
-
return
|
|
1857
|
+
return t[a]?.(e.itemId);
|
|
1701
1858
|
case "portal-group":
|
|
1702
|
-
return
|
|
1859
|
+
return t[a]?.(e.groupId);
|
|
1703
1860
|
default:
|
|
1704
|
-
return
|
|
1861
|
+
return R(a);
|
|
1705
1862
|
}
|
|
1706
1863
|
}
|
|
1707
|
-
function
|
|
1708
|
-
const
|
|
1709
|
-
return
|
|
1864
|
+
function In(e) {
|
|
1865
|
+
const t = Ct.safeParse(e);
|
|
1866
|
+
return t.success ? t.data : void 0;
|
|
1710
1867
|
}
|
|
1711
|
-
const
|
|
1712
|
-
navigationTargets:
|
|
1868
|
+
const xn = { myContent: "My content", createFeatureLayer: "Create feature layer", createFolder: "Create folder", myGroups: "My groups", createGroup: "Create group", featuredGroups: "Featured groups", organizationGroups: "Organization groups", configureMultifactorAuthentication: "Configure multifactor authentication" }, $e = {
|
|
1869
|
+
navigationTargets: xn
|
|
1713
1870
|
};
|
|
1714
|
-
function
|
|
1715
|
-
const a =
|
|
1871
|
+
function Sn(e, t) {
|
|
1872
|
+
const a = he(e.t9nKey, t.navigationTargets) ?? he(e.t9nKey, $e.navigationTargets);
|
|
1716
1873
|
if (a)
|
|
1717
1874
|
return a;
|
|
1718
|
-
const n =
|
|
1719
|
-
switch (
|
|
1875
|
+
const n = t.navigation;
|
|
1876
|
+
switch (e.destinationType) {
|
|
1720
1877
|
case "portal-content":
|
|
1721
|
-
switch (
|
|
1878
|
+
switch (e.hash) {
|
|
1722
1879
|
case "favorites":
|
|
1723
1880
|
return n.openContentFavorites;
|
|
1724
1881
|
case "group":
|
|
@@ -1733,7 +1890,7 @@ function dn(t, e) {
|
|
|
1733
1890
|
case "portal-gallery":
|
|
1734
1891
|
return n.openGallery;
|
|
1735
1892
|
case "portal-groups":
|
|
1736
|
-
switch (
|
|
1893
|
+
switch (e.hash) {
|
|
1737
1894
|
case "featured":
|
|
1738
1895
|
return n.openGroupsFeatured;
|
|
1739
1896
|
case "my":
|
|
@@ -1756,106 +1913,118 @@ function dn(t, e) {
|
|
|
1756
1913
|
case "portal-group":
|
|
1757
1914
|
return n.openGroup;
|
|
1758
1915
|
default:
|
|
1759
|
-
return
|
|
1916
|
+
return R(e);
|
|
1760
1917
|
}
|
|
1761
1918
|
}
|
|
1762
|
-
function
|
|
1763
|
-
if (!(!
|
|
1764
|
-
return e
|
|
1919
|
+
function he(e, t) {
|
|
1920
|
+
if (!(!e || !t || !Tn(e)))
|
|
1921
|
+
return t[e];
|
|
1765
1922
|
}
|
|
1766
|
-
function
|
|
1767
|
-
return
|
|
1923
|
+
function Tn(e) {
|
|
1924
|
+
return e in $e.navigationTargets;
|
|
1768
1925
|
}
|
|
1769
|
-
class
|
|
1926
|
+
class Mn extends Fe {
|
|
1770
1927
|
constructor() {
|
|
1771
|
-
super(), this.t9n =
|
|
1772
|
-
const a =
|
|
1928
|
+
super(), this.t9n = je({ blocking: !0 }), this.assistantEl = P(), this.formEl = P(), this.voiceInputEl = P(), this.inputEl = P(), this.navigationSlotElements = /* @__PURE__ */ new Map(), this.handleSlottableRequest = (t) => {
|
|
1929
|
+
const a = t.detail, n = a.data?.block;
|
|
1773
1930
|
if (!n)
|
|
1774
1931
|
return;
|
|
1775
|
-
const
|
|
1776
|
-
|
|
1777
|
-
}, this.inputText = "", this.showVoiceInput = !0, this.isListening = !1, this.isVoiceInputDisabled = !1, this.interrupt = null, this.autoDestroyDisabled = !1, this.
|
|
1932
|
+
const r = this.getNavigationAction(n);
|
|
1933
|
+
r && this.upsertNavigationSlotElement(a.slotName, r);
|
|
1934
|
+
}, this.inputText = "", this.showVoiceInput = !0, this.isListening = !1, this.isVoiceInputDisabled = !1, this.interrupt = null, this.autoDestroyDisabled = !1, this.defaultClosed = !1, this.arcgisPortalNavigationRequest = Oe(), S();
|
|
1778
1935
|
}
|
|
1779
1936
|
static {
|
|
1780
|
-
this.properties = { inputText: 16, showVoiceInput: 16, isListening: 16, isVoiceInputDisabled: 16, interrupt: 16, autoDestroyDisabled: 5, portal: 0, user: 0, config: 0, navigationTargetMap: 0,
|
|
1937
|
+
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 };
|
|
1781
1938
|
}
|
|
1782
1939
|
static {
|
|
1783
|
-
this.styles =
|
|
1940
|
+
this.styles = bn;
|
|
1784
1941
|
}
|
|
1785
1942
|
async load() {
|
|
1943
|
+
await this.refreshCapabilityEmbeddings();
|
|
1944
|
+
}
|
|
1945
|
+
willUpdate(t) {
|
|
1946
|
+
!this.hasUpdated || !t.has("navigationCapabilities") || this.refreshCapabilityEmbeddings();
|
|
1947
|
+
}
|
|
1948
|
+
async clearEmbeddingsCache() {
|
|
1949
|
+
ce();
|
|
1950
|
+
}
|
|
1951
|
+
isAgentEnabled(t) {
|
|
1952
|
+
return !this.disabledAgents?.[t];
|
|
1953
|
+
}
|
|
1954
|
+
async refreshCapabilityEmbeddings() {
|
|
1786
1955
|
try {
|
|
1787
|
-
|
|
1788
|
-
} catch (
|
|
1789
|
-
console.warn("[arcgis-portal-ai-assistant] embeddings warm-up failed:",
|
|
1956
|
+
S(this.navigationCapabilities), on(), ce(), await Xa();
|
|
1957
|
+
} catch (t) {
|
|
1958
|
+
console.warn("[arcgis-portal-ai-assistant] embeddings warm-up failed:", t);
|
|
1790
1959
|
}
|
|
1791
1960
|
}
|
|
1792
|
-
getNavigationAction(
|
|
1793
|
-
if (
|
|
1961
|
+
getNavigationAction(t) {
|
|
1962
|
+
if (t?.type !== be)
|
|
1794
1963
|
return;
|
|
1795
|
-
const a =
|
|
1964
|
+
const a = t.data, n = In(a);
|
|
1796
1965
|
if (!n)
|
|
1797
1966
|
return;
|
|
1798
|
-
const
|
|
1799
|
-
if (
|
|
1967
|
+
const r = vn(a, this.navigationTargetMap);
|
|
1968
|
+
if (r)
|
|
1800
1969
|
return {
|
|
1801
|
-
href:
|
|
1970
|
+
href: r,
|
|
1802
1971
|
targetDetail: a,
|
|
1803
|
-
label: a?.buttonLabel ||
|
|
1972
|
+
label: a?.buttonLabel || Sn(n, this.t9n)
|
|
1804
1973
|
};
|
|
1805
1974
|
}
|
|
1806
|
-
upsertNavigationSlotElement(
|
|
1975
|
+
upsertNavigationSlotElement(t, a) {
|
|
1807
1976
|
const n = this.assistantEl.value;
|
|
1808
1977
|
if (!n)
|
|
1809
1978
|
return;
|
|
1810
|
-
const
|
|
1811
|
-
let
|
|
1812
|
-
|
|
1813
|
-
|
|
1979
|
+
const r = `navigation:${t}`;
|
|
1980
|
+
let o = this.navigationSlotElements.get(r);
|
|
1981
|
+
o || (o = document.createElement("div"), o.slot = t, this.navigationSlotElements.set(r, o), n.append(o)), Ve(b`<div><calcite-button class="navigation-button" appearance=outline width=full .href=${a.href} icon-end=launch @click=${(u) => {
|
|
1982
|
+
u.preventDefault(), this.arcgisPortalNavigationRequest.emit({
|
|
1814
1983
|
href: a.href,
|
|
1815
1984
|
targetDetail: a.targetDetail
|
|
1816
1985
|
});
|
|
1817
|
-
}}>${a.label}</calcite-button>${a.description ?
|
|
1986
|
+
}}>${a.label}</calcite-button>${a.description ? b`<div class="navigation-block-description">${a.description}</div>` : null}</div>`, o);
|
|
1818
1987
|
}
|
|
1819
1988
|
render() {
|
|
1820
|
-
const { t9n:
|
|
1821
|
-
return
|
|
1822
|
-
this.interrupt =
|
|
1989
|
+
const { t9n: t, inputText: a, portal: n, user: r, navigationTargetMap: o, showVoiceInput: u, isListening: i, isVoiceInputDisabled: l } = this;
|
|
1990
|
+
return b`<arcgis-assistant log-enabled keep-suggested-prompts .heading=${t.heading} .entryMessage=${t.entryMessage} @arcgisSlottableRequest=${this.handleSlottableRequest} @arcgisInterrupt=${({ detail: c }) => {
|
|
1991
|
+
this.interrupt = c;
|
|
1823
1992
|
}} @arcgisInterruptCancel=${() => {
|
|
1824
1993
|
this.interrupt = null;
|
|
1825
1994
|
}} @arcgisInterruptSubmit=${() => {
|
|
1826
1995
|
this.interrupt = null;
|
|
1827
|
-
}} @arcgisPromptSelect=${({ detail:
|
|
1828
|
-
this.inputText =
|
|
1996
|
+
}} @arcgisPromptSelect=${({ detail: c }) => {
|
|
1997
|
+
this.inputText = c.prompt, requestAnimationFrame(() => {
|
|
1829
1998
|
this.inputEl.value?.focusTextArea();
|
|
1830
1999
|
});
|
|
1831
|
-
}} ${
|
|
1832
|
-
|
|
1833
|
-
const
|
|
1834
|
-
|
|
1835
|
-
}} ${
|
|
1836
|
-
|
|
1837
|
-
}} @arcgisUserMentionableTextAreaChange=${({ detail:
|
|
1838
|
-
this.inputText =
|
|
1839
|
-
}} ${
|
|
2000
|
+
}} ${q(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=${(c) => {
|
|
2001
|
+
c.preventDefault();
|
|
2002
|
+
const d = a.trim();
|
|
2003
|
+
d && (this.assistantEl.value?.submitMessage(d), this.inputText = "");
|
|
2004
|
+
}} ${q(this.formEl)}><arcgis-portal-mentionable-text-area .portal=${n} .user=${r} rows=3 .popoverListLabel=${t.mentionEntities} .placeholder=${t.placeholder} .value=${a} @arcgisUserMentionableTextAreaKeyDown=${({ detail: c }) => {
|
|
2005
|
+
c.key === "Enter" && !c.shiftKey && (c.preventDefault(), this.formEl.value?.requestSubmit());
|
|
2006
|
+
}} @arcgisUserMentionableTextAreaChange=${({ detail: c }) => {
|
|
2007
|
+
this.inputText = c ?? "";
|
|
2008
|
+
}} ${q(this.inputEl)}></arcgis-portal-mentionable-text-area><div class="chat-actions"><arcgis-portal-voice-input @arcgisVoiceInputStart=${() => {
|
|
1840
2009
|
this.isListening = !0, this.isVoiceInputDisabled = !1;
|
|
1841
2010
|
}} @arcgisVoiceInputStop=${() => {
|
|
1842
2011
|
this.isListening = !1, this.isVoiceInputDisabled = !1;
|
|
1843
|
-
}} @arcgisVoiceInputError=${(
|
|
1844
|
-
|
|
1845
|
-
}} @arcgisVoiceInputInterimTranscription=${(
|
|
1846
|
-
this.inputText =
|
|
1847
|
-
}} ${
|
|
2012
|
+
}} @arcgisVoiceInputError=${(c) => {
|
|
2013
|
+
c.detail.errorCode === "not-supported" && (this.showVoiceInput = !1);
|
|
2014
|
+
}} @arcgisVoiceInputInterimTranscription=${(c) => {
|
|
2015
|
+
this.inputText = c.detail.text;
|
|
2016
|
+
}} ${q(this.voiceInputEl)}></arcgis-portal-voice-input>${u && b`<calcite-button icon-start=microphone .label=${t.voiceInput} round .disabled=${l} .appearance=${i ? "solid" : "outline-fill"} @click=${async () => {
|
|
1848
2017
|
this.isVoiceInputDisabled = !0;
|
|
1849
|
-
const
|
|
1850
|
-
|
|
1851
|
-
}}></calcite-button>` || ""}<calcite-button type=submit icon-start=send round .disabled=${!a.trim()} .label=${
|
|
1852
|
-
this.assistantEl.value?.submitInterrupt(
|
|
2018
|
+
const c = this.voiceInputEl.value;
|
|
2019
|
+
i ? await c?.stopListening() : await c?.startListening();
|
|
2020
|
+
}}></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") && b`<arcgis-assistant-agent .agent=${Ga} .context=${{ portal: n, user: r, navigationTargetMap: o }}></arcgis-assistant-agent>` || ""}${this.isAgentEnabled("groupCreation") && b`<arcgis-assistant-agent .agent=${Pt} .context=${{ portal: n, user: r, navigationTargetMap: o }}></arcgis-assistant-agent>` || ""}${this.isAgentEnabled("docAssistant") && b`<arcgis-assistant-agent .agent=${Wt} .context=${{ portal: n, user: r, navigationTargetMap: o }}></arcgis-assistant-agent>` || ""}${this.isAgentEnabled("groupAnalytics") && b`<arcgis-assistant-agent .agent=${ha} .context=${{ portal: n, user: r, navigationTargetMap: o }}></arcgis-assistant-agent>` || ""}${this.isAgentEnabled("navigation") && b`<arcgis-assistant-agent .agent=${wn} .context=${{ portal: n, user: r, navigationTargetMap: o }}></arcgis-assistant-agent>` || ""}${this.interrupt && b`<arcgis-portal-ai-assistant-interrupt slot=interrupt .type=${this.interrupt.type} .message=${this.interrupt.message} .options=${this.interrupt.options} @arcgisSubmit=${({ detail: c }) => {
|
|
2021
|
+
this.assistantEl.value?.submitInterrupt(c);
|
|
1853
2022
|
}} @arcgisCancel=${() => {
|
|
1854
2023
|
this.assistantEl.value?.cancelInterrupt();
|
|
1855
2024
|
}}></arcgis-portal-ai-assistant-interrupt>` || ""}</arcgis-assistant>`;
|
|
1856
2025
|
}
|
|
1857
2026
|
}
|
|
1858
|
-
|
|
2027
|
+
Ue("arcgis-portal-ai-assistant", Mn);
|
|
1859
2028
|
export {
|
|
1860
|
-
|
|
2029
|
+
Mn as ArcgisPortalAiAssistant
|
|
1861
2030
|
};
|