@arcgis/portal-components 5.2.0-next.53 → 5.2.0-next.55

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.
@@ -1,151 +1,175 @@
1
1
  /* COPYRIGHT Esri - https://js.arcgis.com/5.2/LICENSE.txt */
2
- import { c as ut } from "../../chunks/runtime.js";
3
- import { LitElement as ct, createEvent as pt } from "@arcgis/lumina";
4
- import { css as dt, render as mt, html as M } from "lit";
5
- import { createRef as G, ref as A } from "lit/directives/ref.js";
6
- import { u as gt } from "../../chunks/useT9n.js";
7
- import { a as T, t as ht, b as ft } from "../../chunks/functionalities.js";
8
- import { NodeInterrupt as J, Annotation as h, StateGraph as C, START as N, END as f } from "@langchain/langgraph/web";
9
- import { sendTraceMessage as g, invokeStructuredPrompt as b, sendUXSuggestion as $, createAgentRuntimeStateWithSharedState as P, createChatModel as E } from "@arcgis/ai-components/utils/index.js";
10
- import r from "zod";
11
- import { a as yt, c as wt, q as bt } from "../../chunks/groups2.js";
12
- import vt from "@arcgis/core/identity/IdentityManager.js";
13
- import O from "@arcgis/core/request.js";
14
- import { ChatPromptTemplate as D } from "@langchain/core/prompts";
15
- import { createAgent as U } from "langchain";
16
- import { tool as W } from "@langchain/core/tools";
17
- import { s as It, a as xt } from "../../chunks/item.js";
18
- import { Annotation as St } from "@langchain/langgraph";
19
- import { c as Mt, d as Gt, i as At, b as Tt, g as Ct } from "../../chunks/groups.js";
20
- const Y = (s) => {
21
- const { portal: t, user: e } = s ?? {};
22
- return !!s && !!t && !!e;
2
+ import { c as pt } from "../../chunks/runtime.js";
3
+ import { LitElement as dt, createEvent as mt } from "@arcgis/lumina";
4
+ import { css as gt, render as ht, html as M } from "lit";
5
+ import { createRef as T, ref as A } from "lit/directives/ref.js";
6
+ import { u as ft } from "../../chunks/useT9n.js";
7
+ import { a as C, t as yt, b as wt } from "../../chunks/functionalities.js";
8
+ import { NodeInterrupt as Y, Annotation as y, StateGraph as N, START as P, END as w } from "@langchain/langgraph/web";
9
+ import { sendTraceMessage as g, invokeStructuredPrompt as v, sendUXSuggestion as E, createAgentRuntimeStateWithSharedState as k, createChatModel as D } from "@arcgis/ai-components/utils/index.js";
10
+ import n from "zod";
11
+ import { a as bt, c as vt, q as It } from "../../chunks/groups2.js";
12
+ import xt from "@arcgis/core/identity/IdentityManager.js";
13
+ import F from "@arcgis/core/request.js";
14
+ import { ChatPromptTemplate as U } from "@langchain/core/prompts";
15
+ import { tool as _ } from "@langchain/core/tools";
16
+ import { s as St, a as Mt } from "../../chunks/item.js";
17
+ import { c as Gt, d as Tt, i as At, b as Ct, g as Nt } from "../../chunks/groups.js";
18
+ const H = (a) => {
19
+ const { portal: t, user: e } = a ?? {};
20
+ return !!a && !!t && !!e;
23
21
  };
24
- function v(s) {
25
- if (!Y(s))
22
+ function I(a) {
23
+ if (!H(a))
26
24
  throw new Error("Invalid context: PortalAssistantContext with portal and user is required.");
27
25
  }
28
- const Nt = (s) => s.map((t) => `"${t}"`).join(", "), Pt = r.object({
29
- successMessage: r.string().default("")
30
- }), V = "portal-group-creation", j = "approveAddMembers", kt = async (s, t) => {
31
- if (s.intentParams.intent !== "addMembers")
26
+ const Pt = `
27
+ Write a concise, friendly success message for adding members to a group.
28
+
29
+ Rules:
30
+ - Keep it to 1-2 short sentences.
31
+ - Use plain text only.
32
+ - If there is no notAddedMembers, confirm that all requested members were added successfully.
33
+ - If there are notAddedMembers, acknowledge that some members could not be added and list the added and not added members separately then mention why based on the context
34
+ - Make sure to bold the usernames
35
+
36
+ Added members:
37
+ {addedMembers}
38
+
39
+ Not added members:
40
+ {notAddedMembers}
41
+ `, kt = (a) => a.map((t) => `"${t}"`).join(", "), zt = n.object({
42
+ successMessage: n.string().default("")
43
+ }), V = "portal-group-creation", j = "approveAddMembers", qt = async (a, t) => {
44
+ if (a.intentParams.intent !== "addMembers")
32
45
  return {
33
46
  status: "success",
34
47
  outputMessage: "Use @mention usernames for the members you want to add."
35
48
  };
36
- const e = s.agentExecutionContext.sharedState.createdGroupId?.value;
49
+ const e = a.agentExecutionContext.sharedState.createdGroupId?.value;
37
50
  if (!e)
38
51
  return {
39
52
  status: "success",
40
53
  outputMessage: "Create a group first, then add members using @mention usernames."
41
54
  };
42
- const a = s.intentParams.memberInfo.memberIdentifiers.map((d) => d.trim()).filter(Boolean);
43
- if (!a.length)
55
+ const s = a.intentParams.memberInfo.memberIdentifiers.map((d) => d.trim()).filter(Boolean);
56
+ if (!s.length)
44
57
  return {
45
58
  status: "success",
46
59
  outputMessage: "Use @mention usernames for the members you want to add."
47
60
  };
48
- const i = `The following member(s) will be added to the newly created group:
61
+ const l = `The following member(s) will be added to the newly created group:
49
62
 
50
- ${a.map((d) => `- **@${d}**`).join(`
63
+ ${s.map((d) => `- **@${d}**`).join(`
51
64
  `)}
52
65
 
53
- Do you want to continue?`, { hitlResponse: u } = t?.configurable ?? {};
54
- if (u?.agentId !== V || u.id !== j) {
66
+ Do you want to continue?`, { hitlResponse: c } = t?.configurable ?? {};
67
+ if (c?.agentId !== V || c.id !== j) {
55
68
  const d = {
56
69
  agentId: V,
57
70
  id: j,
58
71
  kind: "booleanChoice",
59
- message: i,
72
+ message: l,
60
73
  metadata: {
61
74
  action: "addMembers",
62
75
  groupId: e,
63
- members: [...a]
76
+ members: [...s]
64
77
  }
65
78
  };
66
- throw new J(d);
79
+ throw new Y(d);
67
80
  }
68
- if (u.payload !== !0)
81
+ if (c.payload !== !0)
69
82
  return {
70
83
  status: "success",
71
84
  outputMessage: "Okay, I cancelled adding members to the group."
72
85
  };
73
86
  await g(
74
- { text: `Adding members ${Nt(a)}...`, agentName: "group-creation" },
87
+ { text: `Adding members ${kt(s)}...`, agentName: "group-creation" },
75
88
  t
76
89
  );
77
- const l = t?.configurable?.context;
78
- v(l);
79
- const { result: c, error: n } = await yt(l.portal, e, a);
80
- if (n || !c)
90
+ const i = t?.configurable?.context;
91
+ I(i);
92
+ const { result: u, error: r } = await bt(i.portal, e, s);
93
+ if (r || !u)
81
94
  return {
82
95
  status: "success",
83
96
  outputMessage: "I could not add members to that group. Please confirm group access and user accounts, then try again."
84
97
  };
85
- const { addedUsernames: p, notAddedUsers: m } = c;
98
+ const { addedUsernames: p, notAddedUsers: m } = u;
86
99
  try {
87
- const y = (await b({
88
- promptText: qt,
89
- schema: Pt,
100
+ const h = (await v({
101
+ promptText: Pt,
102
+ schema: zt,
90
103
  modelTier: "fast",
91
104
  inputVariables: {
92
105
  addedMembers: p.join(", "),
93
106
  notAddedMembers: JSON.stringify(
94
- m.map((x) => ({ username: x.username, reason: x.error.message }))
107
+ m.map((f) => ({ username: f.username, reason: f.error.message }))
95
108
  )
96
109
  }
97
110
  })).successMessage;
98
- if (y)
99
- return { status: "success", outputMessage: y };
111
+ if (h)
112
+ return { status: "success", outputMessage: h };
100
113
  } catch (d) {
101
114
  console.error("Error generating add-members success message:", d);
102
115
  }
103
116
  return {};
104
- }, qt = `
105
- Write a concise, friendly success message for adding members to a group.
117
+ }, $t = `
118
+ Write a concise, friendly success message after creating a portal group.
119
+
120
+ Rules:
121
+ - Mention that the group was created successfully.
122
+ - Mention that the user can add members by using @mention usernames.
123
+ - Keep it to 1-2 short sentences.
124
+ - Make sure to bold the group title in the message.
125
+
126
+ Group title:
127
+ {groupTitle}
128
+ `, Et = `
129
+ Write a concise, friendly failure message after an attempt to create a portal group.
106
130
 
107
131
  Rules:
108
132
  - Keep it to 1-2 short sentences.
109
133
  - Use plain text only.
110
- - If there is no notAddedMembers, confirm that all requested members were added successfully.
111
- - If there are notAddedMembers, acknowledge that some members could not be added and list the added and not added members separately then mention why based on the context
112
- - Make sure to bold the usernames
134
+ - Mention that group creation failed.
135
+ - Include the failure reason in user-friendly language.
136
+ - End with a clear next step the user can try.
113
137
 
114
- Added members:
115
- {addedMembers}
138
+ Group title:
139
+ {groupTitle}
116
140
 
117
- Not added members:
118
- {notAddedMembers}
119
- `, L = "portal-group-creation", B = "approveCreateGroup", zt = r.object({
120
- successMessage: r.string().default("")
121
- }), $t = r.object({
122
- failureMessage: r.string().default("")
123
- }), Et = async (s, t) => {
124
- if (s.intentParams.intent !== "create")
141
+ Failure reason:
142
+ {failureReason}
143
+ `, L = "portal-group-creation", B = "approveCreateGroup", Dt = n.object({
144
+ successMessage: n.string().default("")
145
+ }), Ut = n.object({
146
+ failureMessage: n.string().default("")
147
+ }), Rt = async (a, t) => {
148
+ if (a.intentParams.intent !== "create")
125
149
  return {
126
150
  status: "success",
127
151
  outputMessage: "Tell me the group title you want to use."
128
152
  };
129
- const e = s.intentParams.title.trim();
153
+ const e = a.intentParams.title.trim();
130
154
  if (!e)
131
155
  return {
132
156
  status: "success",
133
157
  outputMessage: "What title would you like for the new group?"
134
158
  };
135
- const a = `A group with the title **${e}** will be created. Do you want to continue?`, { hitlResponse: o } = t?.configurable;
159
+ const s = `A group with the title **${e}** will be created. Do you want to continue?`, { hitlResponse: o } = t?.configurable;
136
160
  if (o?.agentId !== L || o.id !== B) {
137
- const n = {
161
+ const r = {
138
162
  agentId: L,
139
163
  id: B,
140
164
  kind: "booleanChoice",
141
- message: a,
165
+ message: s,
142
166
  metadata: {
143
167
  action: "createGroup",
144
168
  title: e,
145
169
  access: "private"
146
170
  }
147
171
  };
148
- throw new J(n);
172
+ throw new Y(r);
149
173
  }
150
174
  if (o.payload !== !0)
151
175
  return {
@@ -153,22 +177,22 @@ Not added members:
153
177
  outputMessage: `Okay, I cancelled creating **${e}**.`
154
178
  };
155
179
  await g({ text: `Creating group "${e}"...`, agentName: "group-creation" }, t);
156
- const i = t?.configurable?.context;
157
- v(i);
158
- const { result: u, error: l } = await wt(i.portal, {
180
+ const l = t?.configurable?.context;
181
+ I(l);
182
+ const { result: c, error: i } = await vt(l.portal, {
159
183
  title: e,
160
184
  access: "private"
161
185
  });
162
- if (l || !u) {
163
- const n = l?.message?.trim() || "No additional details were provided.";
186
+ if (i || !c) {
187
+ const r = i?.message?.trim() || "No additional details were provided.";
164
188
  try {
165
- const m = (await b({
166
- promptText: Ut,
167
- schema: $t,
189
+ const m = (await v({
190
+ promptText: Et,
191
+ schema: Ut,
168
192
  modelTier: "fast",
169
193
  inputVariables: {
170
194
  groupTitle: e,
171
- failureReason: n
195
+ failureReason: r
172
196
  }
173
197
  })).failureMessage.trim();
174
198
  if (m)
@@ -184,11 +208,11 @@ Not added members:
184
208
  outputMessage: "I could not create that group. Please confirm your permissions and try again with the group title."
185
209
  };
186
210
  }
187
- const c = u.id;
211
+ const u = c.id;
188
212
  try {
189
- const p = (await b({
190
- promptText: Dt,
191
- schema: zt,
213
+ const p = (await v({
214
+ promptText: $t,
215
+ schema: Dt,
192
216
  modelTier: "fast",
193
217
  inputVariables: {
194
218
  groupTitle: e
@@ -198,71 +222,27 @@ Not added members:
198
222
  return {
199
223
  status: "success",
200
224
  outputMessage: p,
201
- sharedStatePatch: { createdGroupId: { value: c } },
202
- createdGroupId: c
225
+ sharedStatePatch: { createdGroupId: { value: u } },
226
+ createdGroupId: u
203
227
  };
204
- } catch (n) {
205
- console.error("Error generating create-group success message:", n);
228
+ } catch (r) {
229
+ console.error("Error generating create-group success message:", r);
206
230
  }
207
231
  return {};
208
- }, Dt = `
209
- Write a concise, friendly success message after creating a portal group.
210
-
211
- Rules:
212
- - Mention that the group was created successfully.
213
- - Mention that the user can add members by using @mention usernames.
214
- - Keep it to 1-2 short sentences.
215
- - Make sure to bold the group title in the message.
216
-
217
- Group title:
218
- {groupTitle}
219
- `, Ut = `
220
- Write a concise, friendly failure message after an attempt to create a portal group.
221
-
222
- Rules:
223
- - Keep it to 1-2 short sentences.
224
- - Use plain text only.
225
- - Mention that group creation failed.
226
- - Include the failure reason in user-friendly language.
227
- - End with a clear next step the user can try.
228
-
229
- Group title:
230
- {groupTitle}
231
-
232
- Failure reason:
233
- {failureReason}
234
- `, I = (s) => {
235
- for (let t = s.length - 1; t >= 0; t -= 1) {
236
- const e = s[t];
232
+ }, x = (a) => {
233
+ for (let t = a.length - 1; t >= 0; t -= 1) {
234
+ const e = a[t];
237
235
  if (e.type !== "human")
238
236
  continue;
239
- const a = e.content;
240
- if (typeof a == "string")
241
- return a;
242
- if (Array.isArray(a))
243
- return a.map(
237
+ const s = e.content;
238
+ if (typeof s == "string")
239
+ return s;
240
+ if (Array.isArray(s))
241
+ return s.map(
244
242
  (o) => typeof o == "string" ? o : "text" in o && typeof o.text == "string" ? o.text : ""
245
243
  ).join(" ").trim();
246
244
  }
247
245
  return "";
248
- }, Rt = r.object({
249
- intent: r.enum(["clarify", "create", "addMembers"]).default("clarify"),
250
- title: r.string().default(""),
251
- memberIdentifiers: r.array(r.string()).default([]),
252
- clarifyMessage: r.string().default("")
253
- }), Ft = async (s, t) => {
254
- await g({ text: "Thinking about groups...", agentName: "group-creation" }, t);
255
- const e = I(s.agentExecutionContext.messages).trim(), a = await b({
256
- promptText: Ot,
257
- schema: Rt,
258
- modelTier: "default",
259
- inputVariables: { userMessage: e }
260
- }), o = a.title.trim(), i = a.memberIdentifiers.filter(Boolean), u = a.clarifyMessage.trim(), l = a.intent === "create" && !!o, c = a.intent === "addMembers" && i.length > 0;
261
- return {
262
- intentParams: l ? { intent: "create", title: o } : c ? { intent: "addMembers", memberInfo: { memberIdentifiers: i } } : { intent: "clarify" },
263
- status: "success",
264
- outputMessage: !l && !c ? u : ""
265
- };
266
246
  }, Ot = `
267
247
  You classify whether a user is asking to create a new ArcGIS Portal group or add members to an existing group.
268
248
 
@@ -289,7 +269,25 @@ Examples:
289
269
 
290
270
  User message:
291
271
  {userMessage}
292
- `, Vt = r.enum([
272
+ `, Ft = n.object({
273
+ intent: n.enum(["clarify", "create", "addMembers"]).default("clarify"),
274
+ title: n.string().default(""),
275
+ memberIdentifiers: n.array(n.string()).default([]),
276
+ clarifyMessage: n.string().default("")
277
+ }), Vt = async (a, t) => {
278
+ await g({ text: "Thinking about groups...", agentName: "group-creation" }, t);
279
+ const e = x(a.agentExecutionContext.messages).trim(), s = await v({
280
+ promptText: Ot,
281
+ schema: Ft,
282
+ modelTier: "default",
283
+ inputVariables: { userMessage: e }
284
+ }), o = s.title.trim(), l = s.memberIdentifiers.filter(Boolean), c = s.clarifyMessage.trim(), i = s.intent === "create" && !!o, u = s.intent === "addMembers" && l.length > 0;
285
+ return {
286
+ intentParams: i ? { intent: "create", title: o } : u ? { intent: "addMembers", memberInfo: { memberIdentifiers: l } } : { intent: "clarify" },
287
+ status: "success",
288
+ outputMessage: !i && !u ? c : ""
289
+ };
290
+ }, jt = n.enum([
293
291
  "portal-content",
294
292
  "portal-content-favorites",
295
293
  "portal-content-group",
@@ -304,158 +302,158 @@ User message:
304
302
  "portal-notebooks",
305
303
  "portal-scene-viewer",
306
304
  "portal-settings-security"
307
- ]), jt = r.object({
308
- destinationType: Vt
309
- }), Lt = r.union([
310
- jt,
311
- r.object({
312
- destinationType: r.literal("portal-item"),
313
- itemId: r.string().trim().min(1)
305
+ ]), Lt = n.object({
306
+ destinationType: jt
307
+ }), Bt = n.union([
308
+ Lt,
309
+ n.object({
310
+ destinationType: n.literal("portal-item"),
311
+ itemId: n.string().trim().min(1)
314
312
  }),
315
- r.object({
316
- destinationType: r.literal("portal-group"),
317
- groupId: r.string().trim().min(1)
313
+ n.object({
314
+ destinationType: n.literal("portal-group"),
315
+ groupId: n.string().trim().min(1)
318
316
  })
319
- ]), _ = "portal-navigation", R = async (s, t) => {
317
+ ]), X = "portal-navigation", R = async (a, t) => {
320
318
  const e = t?.configurable?.context;
321
- !Y(e) || !e.navigationTargetMap?.[s.destinationType] || await $({ type: _, data: { ...s } }, t);
322
- }, Bt = async (s, t) => {
323
- const e = s.createdGroupId ?? s.agentExecutionContext.sharedState.createdGroupId?.value;
319
+ !H(e) || !e.navigationTargetMap?.[a.destinationType] || await E({ type: X, data: { ...a } }, t);
320
+ }, Qt = async (a, t) => {
321
+ const e = a.createdGroupId ?? a.agentExecutionContext.sharedState.createdGroupId?.value;
324
322
  return e ? (await g({ text: "Preparing navigation...", agentName: "group-creation" }, t), await R({ destinationType: "portal-group", groupId: e }, t), {}) : {};
325
- }, Q = (s, t) => t ?? s, H = h.Root({
326
- ...P(),
323
+ }, Q = (a, t) => t ?? a, Z = y.Root({
324
+ ...k(),
327
325
  // * Shared state between nodes (but not persisted to the agent execution context)
328
326
  /** Parameters related to the user's intent for group creation actions */
329
- intentParams: h({ reducer: Q, default: () => ({ intent: "clarify" }) }),
327
+ intentParams: y({ reducer: Q, default: () => ({ intent: "clarify" }) }),
330
328
  /** The ID of the group that was created
331
329
  * even though we already have this in the shared state
332
330
  * we still need it here to also share between nodes
333
331
  */
334
- createdGroupId: h({ reducer: Q, default: () => "" })
335
- }), Qt = () => new C(H).addNode("detectGroupCreationIntent", Ft).addNode("createPortalGroup", Et).addNode("addMembersToPortalGroup", kt).addNode("suggestCreatedGroupNavigation", Bt).addEdge(N, "detectGroupCreationIntent").addConditionalEdges("detectGroupCreationIntent", (t) => {
332
+ createdGroupId: y({ reducer: Q, default: () => "" })
333
+ }), Kt = () => new N(Z).addNode("detectGroupCreationIntent", Vt).addNode("createPortalGroup", Rt).addNode("addMembersToPortalGroup", qt).addNode("suggestCreatedGroupNavigation", Qt).addEdge(P, "detectGroupCreationIntent").addConditionalEdges("detectGroupCreationIntent", (t) => {
336
334
  switch (t.intentParams.intent) {
337
335
  case "create":
338
336
  return "createPortalGroup";
339
337
  case "addMembers":
340
338
  return "addMembersToPortalGroup";
341
339
  default:
342
- return f;
340
+ return w;
343
341
  }
344
- }).addEdge("createPortalGroup", "suggestCreatedGroupNavigation").addEdge("addMembersToPortalGroup", "suggestCreatedGroupNavigation").addEdge("suggestCreatedGroupNavigation", f), Kt = String.raw`- **portal-group-creation** - Portal group creation assistant:
342
+ }).addEdge("createPortalGroup", "suggestCreatedGroupNavigation").addEdge("addMembersToPortalGroup", "suggestCreatedGroupNavigation").addEdge("suggestCreatedGroupNavigation", w), Jt = String.raw`- **portal-group-creation** - Portal group creation assistant:
345
343
  - creates a new ArcGIS Portal group for the signed-in user
346
344
  - adds users to the newly created group using @mention usernames
347
- `, Jt = {
345
+ `, Wt = {
348
346
  id: "portal-group-creation",
349
347
  name: "Portal Group Creation",
350
- description: Kt,
351
- createGraph: Qt,
352
- workspace: H
353
- }, X = "portalDocAssistantMemory", Wt = () => ({ conversationId: "" }), Yt = (s) => {
354
- const t = s?.[X]?.value;
348
+ description: Jt,
349
+ createGraph: Kt,
350
+ workspace: Z
351
+ }, tt = "portalDocAssistantMemory", Yt = () => ({ conversationId: "" }), _t = (a) => {
352
+ const t = a?.[tt]?.value;
355
353
  if (!t || typeof t != "object")
356
- return Wt();
354
+ return Yt();
357
355
  const e = t;
358
356
  return {
359
357
  conversationId: typeof e.conversationId == "string" ? e.conversationId : ""
360
358
  };
361
- }, _t = (s) => ({
362
- [X]: { value: s }
359
+ }, Ht = (a) => ({
360
+ [tt]: { value: a }
363
361
  });
364
- async function Ht({
365
- portal: s,
362
+ async function Xt({
363
+ portal: a,
366
364
  question: t,
367
365
  persona: e,
368
- previousConversationId: a,
366
+ previousConversationId: s,
369
367
  signal: o,
370
- skillId: i
368
+ skillId: l
371
369
  }) {
372
- i ??= "doc_ai_assistant";
373
- const l = await Xt({
374
- portal: s,
375
- skillId: i,
370
+ l ??= "doc_ai_assistant";
371
+ const i = await Zt({
372
+ portal: a,
373
+ skillId: l,
376
374
  message: t,
377
375
  options: { context: {
378
376
  kind: "DocAIAssistantRequest",
379
377
  filters: { persona: { persona: e } }
380
- }, previousConversationId: a, signal: o }
378
+ }, previousConversationId: s, signal: o }
381
379
  });
382
380
  return {
383
- reply: Zt(l, i),
384
- conversationId: l[0]?.conversationId ?? ""
381
+ reply: te(i, l),
382
+ conversationId: i[0]?.conversationId ?? ""
385
383
  };
386
384
  }
387
- async function Xt({
388
- portal: s,
385
+ async function Zt({
386
+ portal: a,
389
387
  skillId: t,
390
388
  message: e,
391
- options: a
389
+ options: s
392
390
  }) {
393
- const i = `${s.helperServices.aiAssistantServices.url}/skills/${t}/chat`, u = {
391
+ const l = `${a.helperServices.aiAssistantServices.url}/skills/${t}/chat`, c = {
394
392
  "Content-Type": "application/json",
395
- token: vt.findCredential(s.url)?.token ?? ""
396
- }, l = await O(i, {
393
+ token: xt.findCredential(a.url)?.token ?? ""
394
+ }, i = await F(l, {
397
395
  method: "post",
398
396
  body: JSON.stringify({
399
397
  message: e,
400
- context: a.context,
401
- conversationId: a.previousConversationId
398
+ context: s.context,
399
+ conversationId: s.previousConversationId
402
400
  }),
403
- headers: u,
404
- signal: a.signal
401
+ headers: c,
402
+ signal: s.signal
405
403
  });
406
- if (l.httpStatus !== 200)
407
- throw new Error(`Doc assistant chat failed (${l.httpStatus})`, {
408
- cause: l.data
404
+ if (i.httpStatus !== 200)
405
+ throw new Error(`Doc assistant chat failed (${i.httpStatus})`, {
406
+ cause: i.data
409
407
  });
410
- const c = l.data, n = [c], { conversationId: p, inquiryId: m } = c, d = async (y, x) => {
411
- if (!x)
408
+ const u = i.data, r = [u], { conversationId: p, inquiryId: m } = u, d = async (h, f) => {
409
+ if (!f)
412
410
  return;
413
- await ht(1e3);
414
- const w = await O(i, {
411
+ await yt(1e3);
412
+ const b = await F(l, {
415
413
  method: "post",
416
- body: JSON.stringify({ conversationId: p, inquiryId: m, ackSequenceNumber: y }),
417
- headers: u,
418
- signal: a.signal
414
+ body: JSON.stringify({ conversationId: p, inquiryId: m, ackSequenceNumber: h }),
415
+ headers: c,
416
+ signal: s.signal
419
417
  });
420
- if (w.httpStatus !== 200)
421
- throw new Error(`Doc assistant poll failed (${w.httpStatus})`, {
422
- cause: w.data
418
+ if (b.httpStatus !== 200)
419
+ throw new Error(`Doc assistant poll failed (${b.httpStatus})`, {
420
+ cause: b.data
423
421
  });
424
- const S = w.data;
425
- n.push(S), await d(S.sequenceNumber, S.hasMore);
422
+ const S = b.data;
423
+ r.push(S), await d(S.sequenceNumber, S.hasMore);
426
424
  };
427
- return c.hasMore && await d(c.sequenceNumber, c.hasMore), n;
425
+ return u.hasMore && await d(u.sequenceNumber, u.hasMore), r;
428
426
  }
429
- function Zt(s, t) {
427
+ function te(a, t) {
430
428
  switch (t) {
431
429
  case "doc_chat":
432
- return s.find((e) => e.message != null)?.message ?? "";
430
+ return a.find((e) => e.message != null)?.message ?? "";
433
431
  case "doc_ai_assistant":
434
- for (let e = s.length - 1; e >= 0; e -= 1) {
435
- const a = s[e];
436
- if (a.context?.kind === "DocAIAssistantContext") {
437
- const o = a.context.results?.[0]?.reply;
432
+ for (let e = a.length - 1; e >= 0; e -= 1) {
433
+ const s = a[e];
434
+ if (s.context?.kind === "DocAIAssistantContext") {
435
+ const o = s.context.results?.[0]?.reply;
438
436
  if (o)
439
437
  return o;
440
438
  }
441
439
  }
442
440
  return "";
443
441
  default:
444
- return T(t);
442
+ return C(t);
445
443
  }
446
444
  }
447
- const te = async (s, t) => {
445
+ const ee = async (a, t) => {
448
446
  await g({ text: "Asking documentation assistant...", agentName: "doc-assistant" }, t);
449
- const e = I(s.agentExecutionContext.messages).trim();
447
+ const e = x(a.agentExecutionContext.messages).trim();
450
448
  if (!e)
451
449
  return {
452
450
  status: "success",
453
451
  outputMessage: "Please share your question and I can help with ArcGIS and Portal documentation."
454
452
  };
455
- const a = t?.configurable?.context;
456
- v(a);
457
- const o = Yt(s.agentExecutionContext.sharedState), { reply: i, conversationId: u } = await Ht({
458
- portal: a.portal,
453
+ const s = t?.configurable?.context;
454
+ I(s);
455
+ const o = _t(a.agentExecutionContext.sharedState), { reply: l, conversationId: c } = await Xt({
456
+ portal: s.portal,
459
457
  question: e,
460
458
  previousConversationId: o.conversationId || void 0,
461
459
  skillId: "doc_ai_assistant",
@@ -463,20 +461,20 @@ const te = async (s, t) => {
463
461
  });
464
462
  return {
465
463
  status: "success",
466
- outputMessage: i.trim() || "I could not retrieve a response from the documentation assistant.",
467
- sharedStatePatch: _t({
468
- conversationId: u || o.conversationId
464
+ outputMessage: l.trim() || "I could not retrieve a response from the documentation assistant.",
465
+ sharedStatePatch: Ht({
466
+ conversationId: c || o.conversationId
469
467
  })
470
468
  };
471
- }, Z = W(
472
- async ({ groupTitle: s }, t) => {
473
- const e = s.trim();
469
+ }, et = _(
470
+ async ({ groupTitle: a }, t) => {
471
+ const e = a.trim();
474
472
  if (!e)
475
473
  return null;
476
- const a = t?.configurable?.context;
477
- v(a);
474
+ const s = t?.configurable?.context;
475
+ I(s);
478
476
  try {
479
- return (await bt(a.portal, { query: `title:${e}`, num: 1 }))?.results[0]?.id || null;
477
+ return (await It(s.portal, { query: `title:${e}`, num: 1 }))?.results[0]?.id || null;
480
478
  } catch (o) {
481
479
  return console.error("Error searching for portal group by title:", o), null;
482
480
  }
@@ -484,28 +482,36 @@ const te = async (s, t) => {
484
482
  {
485
483
  name: "resolvePortalGroupIdByTitle",
486
484
  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.",
487
- schema: r.object({
488
- groupTitle: r.string().describe("The portal group title to resolve to a group id.")
485
+ schema: n.object({
486
+ groupTitle: n.string().describe("The portal group title to resolve to a group id.")
489
487
  })
490
488
  }
491
- ), tt = W(
492
- async ({ itemTitle: s }, t) => {
493
- const e = s.trim();
489
+ ), at = _(
490
+ async ({ itemTitle: a }, t) => {
491
+ const e = a.trim();
494
492
  if (!e)
495
493
  return null;
496
- const a = t?.configurable?.context;
497
- v(a);
498
- const { result: o, error: i } = await It(a.portal, e, { num: 1 });
499
- return i && console.error("Error searching for portal item by title:", i), o?.results[0]?.id || null;
494
+ const s = t?.configurable?.context;
495
+ I(s);
496
+ const { result: o, error: l } = await St(s.portal, e, { num: 1 });
497
+ return l && console.error("Error searching for portal item by title:", l), o?.results[0]?.id || null;
500
498
  },
501
499
  {
502
500
  name: "resolvePortalItemIdByTitle",
503
501
  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.',
504
- schema: r.object({
505
- itemTitle: r.string().describe("The portal item title to resolve to an item id.")
502
+ schema: n.object({
503
+ itemTitle: n.string().describe("The portal item title to resolve to an item id.")
506
504
  })
507
505
  }
508
- ), et = {
506
+ );
507
+ function G(a, t = "#") {
508
+ const e = a.match(new RegExp(`\\${t}"([^"]+)"`, "u"));
509
+ if (e?.[1])
510
+ return e[1].trim();
511
+ const s = a.match(new RegExp(`\\${t}([^\\s"']+)`, "u"));
512
+ return s?.[1] ? s[1].trim() : null;
513
+ }
514
+ const st = {
509
515
  "portal-content": {
510
516
  description: "The main content page of the portal.",
511
517
  hints: ["My content", "Content"],
@@ -586,10 +592,10 @@ const te = async (s, t) => {
586
592
  hints: ["Organization settings", "Security", "Organization > Settings > Security"],
587
593
  scope: "entity"
588
594
  }
589
- }, ee = ft(et), se = Object.entries(et).map(
590
- ([s, { description: t, hints: e, scope: a }]) => ` - ${s}: ${t} (scope: ${a}; hints: ${e.join(", ")})`
595
+ }, ae = wt(st), se = Object.entries(st).map(
596
+ ([a, { description: t, hints: e, scope: s }]) => ` - ${a}: ${t} (scope: ${s}; hints: ${e.join(", ")})`
591
597
  ).join(`
592
- `), ae = `
598
+ `), oe = `
593
599
  You decide whether the assistant response should include a navigation action to ArcGIS Portal.
594
600
 
595
601
  Given the user question and assistant response:
@@ -618,38 +624,40 @@ User question:
618
624
 
619
625
  Assistant response:
620
626
  {response}
621
- `, K = r.object({
622
- shouldSuggestNavigation: r.boolean().default(!1),
623
- destinationType: r.enum(["none", ...ee]).default("none"),
624
- itemId: r.string().default(""),
625
- groupId: r.string().default(""),
626
- confidence: r.number().min(0).max(1).default(0)
627
- }), oe = async (s, t) => {
627
+ `, K = n.object({
628
+ shouldSuggestNavigation: n.boolean().default(!1),
629
+ destinationType: n.enum(["none", ...ae]).default("none"),
630
+ itemId: n.string().default(""),
631
+ groupId: n.string().default(""),
632
+ confidence: n.number().min(0).max(1).default(0)
633
+ }), re = async (a, t) => {
628
634
  await g({ text: "Extracting navigation intent...", agentName: "doc-assistant" }, t);
629
- const e = s.outputMessage.trim();
635
+ const e = a.outputMessage.trim();
630
636
  if (!e)
631
637
  return {};
632
- const a = I(s.agentExecutionContext.messages).trim(), o = await D.fromTemplate(ae).format({
633
- question: a,
638
+ const s = x(a.agentExecutionContext.messages).trim(), o = await U.fromTemplate(oe).format({
639
+ question: s,
634
640
  response: e
635
- }), u = await U({
636
- model: await E({ modelTier: "default" }),
637
- tools: [tt, Z],
638
- systemPrompt: o,
639
- responseFormat: K,
640
- checkpointer: !0
641
- }).invoke({ messages: s.agentExecutionContext.messages }, t), l = K.parse(u.structuredResponse ?? {});
642
- if (!l.shouldSuggestNavigation || l.destinationType === "none")
641
+ }), c = (await D({ modelTier: "fast" })).withStructuredOutput(K), i = K.parse(await c.invoke(o));
642
+ if (!i.shouldSuggestNavigation || i.destinationType === "none")
643
643
  return {};
644
- const c = re(l);
645
- return c ? (await R(c, t), {}) : {};
644
+ if (i.destinationType === "portal-item" && !i.itemId) {
645
+ const r = G(s, "#");
646
+ r && (i.itemId = await at.invoke({ itemTitle: r }, t) ?? "");
647
+ }
648
+ if (i.destinationType === "portal-group" && !i.groupId) {
649
+ const r = G(s, "$") ?? G(s, "#");
650
+ r && (i.groupId = await et.invoke({ groupTitle: r }, t) ?? "");
651
+ }
652
+ const u = ne(i);
653
+ return u ? (await R(u, t), {}) : {};
646
654
  };
647
- function re({
648
- destinationType: s,
655
+ function ne({
656
+ destinationType: a,
649
657
  itemId: t,
650
658
  groupId: e
651
659
  }) {
652
- switch (s) {
660
+ switch (a) {
653
661
  case "portal-content":
654
662
  case "portal-content-favorites":
655
663
  case "portal-content-group":
@@ -664,7 +672,7 @@ function re({
664
672
  case "portal-notebooks":
665
673
  case "portal-scene-viewer":
666
674
  case "portal-settings-security":
667
- return { destinationType: s };
675
+ return { destinationType: a };
668
676
  case "portal-item":
669
677
  return t ? { destinationType: "portal-item", itemId: t } : null;
670
678
  case "portal-group":
@@ -672,56 +680,34 @@ function re({
672
680
  case "none":
673
681
  return null;
674
682
  default:
675
- return T(s);
683
+ return C(a);
676
684
  }
677
685
  }
678
- const st = St.Root({
679
- ...P()
680
- }), ne = () => new C(st).addNode("answerDocQuestion", te).addNode("extractNavigationIntent", oe).addEdge(N, "answerDocQuestion").addEdge("answerDocQuestion", "extractNavigationIntent").addEdge("extractNavigationIntent", f), ie = String.raw`- **portal-doc-assistant** - General ArcGIS documentation and Portal help assistant:
686
+ const ot = y.Root({
687
+ ...k()
688
+ }), ie = () => new N(ot).addNode("answerDocQuestion", ee).addNode("extractNavigationIntent", re).addEdge(P, "answerDocQuestion").addEdge("answerDocQuestion", "extractNavigationIntent").addEdge("extractNavigationIntent", w), le = String.raw`- **portal-doc-assistant** - General ArcGIS documentation and Portal help assistant:
681
689
  - answers general ArcGIS, Portal, Enterprise, and JavaScript SDK questions
682
690
  - acts as a fallback when specialized agents are not applicable
683
- `, le = {
691
+ `, ue = {
684
692
  id: "portal-doc-assistant",
685
693
  name: "Portal Doc Assistant",
686
- description: ie,
687
- createGraph: ne,
688
- workspace: st
689
- }, at = `
694
+ description: le,
695
+ createGraph: ie,
696
+ workspace: ot
697
+ }, ce = () => ({ latestGroupId: null, memory: {} }), z = (a) => {
698
+ const t = a?.agentExecutionContext.sharedState.portalGroupSummaryMemory?.value;
699
+ return t ? { latestGroupId: t.latestGroupId, memory: t.memory } : ce();
700
+ }, rt = `
690
701
  Shared markdown formatting rules:
691
702
  - Use clear markdown headings (##) to separate sections.
692
703
  - Use concise bullet points for lists of facts, counts, or signals.
693
704
  - Emphasize key metrics with bold labels (for example: **Recent items:** 4).
694
705
  - Keep wording direct and analytical; avoid filler language but make sure the language is friendly.
695
706
  - Do not include raw internal IDs unless explicitly requested.
696
- `, ue = () => ({ latestGroupId: null, memory: {} }), k = (s) => {
697
- const t = s?.agentExecutionContext.sharedState.portalGroupSummaryMemory?.value;
698
- return t ? { latestGroupId: t.latestGroupId, memory: t.memory } : ue();
699
- }, ce = async (s, t) => {
700
- await g({ text: "Answering group follow-up...", agentName: "group-analytics" }, t);
701
- const e = k(s), a = s.groupSummaryGroupId ?? e.latestGroupId, o = a ? e.memory[a] : void 0, i = s.groupSummaryQuestion || I(s.agentExecutionContext.messages);
702
- return o ? {
703
- status: "success",
704
- outputMessage: (await b({
705
- promptText: de,
706
- schema: pe,
707
- modelTier: "default",
708
- inputVariables: {
709
- summary: o.summary,
710
- question: i,
711
- fullContext: JSON.stringify(o.fullContext)
712
- }
713
- })).answer
714
- } : {
715
- status: "success",
716
- outputMessage: "I do not have group analytics context yet. Ask me to analyze a group first with analyze group <group id>."
717
- };
718
- }, pe = r.object({
719
- answer: r.string(),
720
- isRelevant: r.boolean()
721
- }), de = `
707
+ `, pe = `
722
708
  You answer follow-up questions about ArcGIS group analytics.
723
709
 
724
- ${at}
710
+ ${rt}
725
711
 
726
712
  Ground your answer in the provided group analytics summary and context.
727
713
  If the answer is not available from the provided context, state that clearly and suggest what to check next.
@@ -743,30 +729,29 @@ Group full context:
743
729
 
744
730
  Question:
745
731
  {question}
746
- `, me = async (s, t) => {
747
- await g({ text: "Analyzing group-analytics intent...", agentName: "group-analytics" }, t);
748
- const e = I(s.agentExecutionContext.messages), a = !!k(s).latestGroupId, o = await D.fromTemplate(he).format({
749
- userMessage: e,
750
- hasAnalyticsContext: String(a)
751
- }), u = await U({
752
- model: await E({ modelTier: "fast" }),
753
- tools: [Z],
754
- systemPrompt: o,
755
- responseFormat: ge,
756
- checkpointer: !0
757
- }).invoke({ messages: s.agentExecutionContext.messages }, t), { intent: l, groupId: c, question: n } = u.structuredResponse, p = l === "summarize" && !c, m = l === "followUp" && !(n ?? "").trim(), d = l === "clarify" || p || m;
758
- return {
759
- groupSummaryIntent: d ? "clarify" : l,
760
- groupSummaryGroupId: c || null,
761
- groupSummaryQuestion: n || "",
732
+ `, de = async (a, t) => {
733
+ await g({ text: "Answering group follow-up...", agentName: "group-analytics" }, t);
734
+ const e = z(a), s = a.groupSummaryGroupId ?? e.latestGroupId, o = s ? e.memory[s] : void 0, l = a.groupSummaryQuestion || x(a.agentExecutionContext.messages);
735
+ return o ? {
736
+ status: "success",
737
+ outputMessage: (await v({
738
+ promptText: pe,
739
+ schema: me,
740
+ modelTier: "default",
741
+ inputVariables: {
742
+ summary: o.summary,
743
+ question: l,
744
+ fullContext: JSON.stringify(o.fullContext)
745
+ }
746
+ })).answer
747
+ } : {
762
748
  status: "success",
763
- outputMessage: d ? "Please clarify with a group id or title" : ""
749
+ outputMessage: "I do not have group analytics context yet. Ask me to analyze a group first with analyze group <group id>."
764
750
  };
765
- }, ge = r.object({
766
- intent: r.enum(["summarize", "followUp", "navigation", "clarify"]),
767
- groupId: r.string().default(""),
768
- question: r.string().default("")
769
- }), he = `
751
+ }, me = n.object({
752
+ answer: n.string(),
753
+ isRelevant: n.boolean()
754
+ }), ge = `
770
755
  Classify the user's request for ArcGIS Portal group analytics.
771
756
 
772
757
  Rules:
@@ -795,35 +780,58 @@ hasAnalyticsContext:
795
780
 
796
781
  User message:
797
782
  {userMessage}
798
- `, fe = async (s, t) => {
799
- const e = k(s), a = s.groupSummaryGroupId ?? e.latestGroupId;
783
+ `, he = async (a, t) => {
784
+ await g({ text: "Analyzing group-analytics intent...", agentName: "group-analytics" }, t);
785
+ const e = x(a.agentExecutionContext.messages), s = !!z(a).latestGroupId, o = await U.fromTemplate(ge).format({
786
+ userMessage: e,
787
+ hasAnalyticsContext: String(s)
788
+ }), c = (await D({ modelTier: "fast" })).withStructuredOutput(J), i = J.parse(await c.invoke(o));
789
+ let u = i.groupId;
790
+ if ((i.intent === "summarize" || i.intent === "navigation") && !u) {
791
+ const f = G(e, "$");
792
+ f && (u = await et.invoke({ groupTitle: f }, t) ?? "");
793
+ }
794
+ const { intent: r, question: p } = i, m = r === "summarize" && !u, d = r === "followUp" && !(p ?? "").trim(), h = r === "clarify" || m || d;
795
+ return {
796
+ groupSummaryIntent: h ? "clarify" : r,
797
+ groupSummaryGroupId: u || null,
798
+ groupSummaryQuestion: p || "",
799
+ status: "success",
800
+ outputMessage: h ? "Please clarify with a group id or title" : ""
801
+ };
802
+ }, J = n.object({
803
+ intent: n.enum(["summarize", "followUp", "navigation", "clarify"]),
804
+ groupId: n.string().default(""),
805
+ question: n.string().default("")
806
+ }), fe = async (a, t) => {
807
+ const e = z(a), s = a.groupSummaryGroupId ?? e.latestGroupId;
800
808
  return await g({ text: "Preparing navigation...", agentName: "group-analytics" }, t), await R(
801
- a ? { destinationType: "portal-group", groupId: a } : { destinationType: "portal-groups" },
809
+ s ? { destinationType: "portal-group", groupId: s } : { destinationType: "portal-groups" },
802
810
  t
803
811
  ), { status: "success" };
804
812
  };
805
- function ot({ timestamp: s, now: t, windowMs: e }) {
806
- return s ? t - s <= e : !1;
813
+ function nt({ timestamp: a, now: t, windowMs: e }) {
814
+ return a ? t - a <= e : !1;
807
815
  }
808
816
  const ye = 720 * 60 * 60 * 1e3;
809
- function we(s) {
810
- const t = Mt(s);
817
+ function we(a) {
818
+ const t = Gt(a);
811
819
  return {
812
- id: s.id ?? "",
813
- title: s.title ?? "",
814
- description: s.description ?? "",
815
- snippet: s.snippet ?? "",
816
- access: s.access ?? null,
817
- owner: s.owner ?? "",
818
- tags: s.tags ?? [],
819
- created: s.created?.getTime(),
820
- modified: s.modified?.getTime(),
821
- isInvitationOnly: s.isInvitationOnly,
820
+ id: a.id ?? "",
821
+ title: a.title ?? "",
822
+ description: a.description ?? "",
823
+ snippet: a.snippet ?? "",
824
+ access: a.access ?? null,
825
+ owner: a.owner ?? "",
826
+ tags: a.tags ?? [],
827
+ created: a.created?.getTime(),
828
+ modified: a.modified?.getTime(),
829
+ isInvitationOnly: a.isInvitationOnly,
822
830
  sourceSignals: {
823
- capabilities: Ct(s),
824
- membershipAccess: Tt(s),
825
- isOpenData: At(s),
826
- isDistributedCollaborationGroup: Gt(s),
831
+ capabilities: Nt(a),
832
+ membershipAccess: Ct(a),
833
+ isOpenData: At(a),
834
+ isDistributedCollaborationGroup: Tt(a),
827
835
  orgId: t.orgId,
828
836
  hiddenMembers: t.hiddenMembers,
829
837
  isViewOnly: t.isViewOnly,
@@ -832,16 +840,16 @@ function we(s) {
832
840
  }
833
841
  };
834
842
  }
835
- async function be(s) {
836
- const t = { owner: s.owner ?? "", admins: [], users: [] };
843
+ async function be(a) {
844
+ const t = { owner: a.owner ?? "", admins: [], users: [] };
837
845
  try {
838
- return await s.fetchMembers();
846
+ return await a.fetchMembers();
839
847
  } catch (e) {
840
848
  return console.warn("Unable to fetch group members for analytics context", e), t;
841
849
  }
842
850
  }
843
- function ve(s) {
844
- return s.map((t) => ({
851
+ function ve(a) {
852
+ return a.map((t) => ({
845
853
  id: t.id ?? "",
846
854
  title: t.title ?? "Untitled",
847
855
  type: t.type ?? "Unknown",
@@ -850,87 +858,43 @@ function ve(s) {
850
858
  modified: t.modified?.getTime()
851
859
  }));
852
860
  }
853
- function Ie(s, t) {
854
- return s.filter(
855
- (e) => e.modified ? ot({ timestamp: e.modified, now: t, windowMs: ye }) : !1
861
+ function Ie(a, t) {
862
+ return a.filter(
863
+ (e) => e.modified ? nt({ timestamp: e.modified, now: t, windowMs: ye }) : !1
856
864
  );
857
865
  }
858
- function xe(s) {
866
+ function xe(a) {
859
867
  const t = /* @__PURE__ */ new Map();
860
- for (const e of s)
868
+ for (const e of a)
861
869
  t.set(e.type, (t.get(e.type) ?? 0) + 1);
862
- return [...t.entries()].sort((e, a) => a[1] - e[1] || e[0].localeCompare(a[0])).slice(0, 6).map(([e, a]) => ({ type: e, count: a }));
870
+ return [...t.entries()].sort((e, s) => s[1] - e[1] || e[0].localeCompare(s[0])).slice(0, 6).map(([e, s]) => ({ type: e, count: s }));
863
871
  }
864
- async function Se(s) {
865
- const t = await s.queryItems({ num: 20, sortField: "modified", sortOrder: "desc" }), e = ve(t.results), a = Date.now();
872
+ async function Se(a) {
873
+ const t = await a.queryItems({ num: 20, sortField: "modified", sortOrder: "desc" }), e = ve(t.results), s = Date.now();
866
874
  return {
867
875
  total: t.total,
868
876
  topItems: e,
869
- recentlyModifiedItems: Ie(e, a),
877
+ recentlyModifiedItems: Ie(e, s),
870
878
  topItemTypes: xe(e)
871
879
  };
872
880
  }
873
- async function Me(s, t) {
881
+ async function Me(a, t) {
874
882
  if (!t)
875
883
  return { error: { code: "missingGroupId", message: "Group id is required." } };
876
884
  try {
877
- const a = (await s.queryGroups({ query: `id:${t}`, num: 1 })).results[0];
878
- if (!a)
885
+ const s = (await a.queryGroups({ query: `id:${t}`, num: 1 })).results[0];
886
+ if (!s)
879
887
  return { error: { code: "groupNotFound", message: `No group found for id: ${t}` } };
880
- const o = we(a), i = await be(a), u = await Se(a);
881
- return { result: { group: o, members: i, items: u } };
888
+ const o = we(s), l = await be(s), c = await Se(s);
889
+ return { result: { group: o, members: l, items: c } };
882
890
  } catch (e) {
883
891
  return console.error("Error fetching portal group analytics context:", e), { error: { code: "unhandledError" } };
884
892
  }
885
893
  }
886
- const Ge = 2160 * 60 * 60 * 1e3, Ae = async (s, t) => {
887
- const e = s.groupSummaryGroupId;
888
- if (!e)
889
- return {
890
- status: "success",
891
- outputMessage: 'Please clarify with analyze group <group id>, analyze group $<title>, or analyze group $"<title with spaces>".'
892
- };
893
- await g({ text: `Analyzing group ${e}...`, agentName: "group-analytics" }, t);
894
- const a = t?.configurable?.context;
895
- v(a);
896
- const { result: o, error: i } = await Me(a.portal, e);
897
- if (i || !o)
898
- return await g({ text: "Failed to fetch group context", agentName: "group-analytics" }, t), {
899
- status: "success",
900
- outputMessage: "Unable to retrieve group context for analytics."
901
- };
902
- const { group: u, items: l } = o, c = Date.now(), n = u.modified, p = n ? ot({ timestamp: n, now: c, windowMs: Ge }) : !1, m = l.recentlyModifiedItems.length, d = m > 0, y = p || d, x = await b({
903
- promptText: Ce,
904
- schema: Te,
905
- modelTier: "default",
906
- inputVariables: {
907
- context: JSON.stringify(o),
908
- deterministicSignals: JSON.stringify({
909
- isGroupActive: y,
910
- isGroupRecentlyModified: p,
911
- hasRecentlyAddedOrUpdatedContent: d,
912
- recentItemCount: m
913
- })
914
- }
915
- }), { followUpQuestions: w, summary: S } = x, it = k(s), lt = {
916
- latestGroupId: e,
917
- memory: {
918
- ...it.memory,
919
- [e]: { summary: S, followUpQuestions: w, fullContext: o }
920
- }
921
- };
922
- return w.length && await $({ type: "suggested-prompts", data: { prompts: w } }, t), {
923
- status: "success",
924
- outputMessage: S,
925
- sharedStatePatch: { portalGroupSummaryMemory: { value: lt } }
926
- };
927
- }, Te = r.object({
928
- summary: r.string(),
929
- followUpQuestions: r.array(r.string()).default([])
930
- }), Ce = `
894
+ const Ge = `
931
895
  You summarize ArcGIS Portal groups based on structured context and deterministic activity signals.
932
896
 
933
- ${at}
897
+ ${rt}
934
898
 
935
899
  Output format requirements:
936
900
  - Return concise markdown with clear sections in this order:
@@ -966,21 +930,65 @@ Group context:
966
930
 
967
931
  Deterministic signals:
968
932
  {deterministicSignals}
969
- `, q = (s, t) => t ?? s, rt = h.Root({
970
- ...P(),
971
- groupSummaryIntent: h({
933
+ `, Te = 2160 * 60 * 60 * 1e3, Ae = async (a, t) => {
934
+ const e = a.groupSummaryGroupId;
935
+ if (!e)
936
+ return {
937
+ status: "success",
938
+ outputMessage: 'Please clarify with analyze group <group id>, analyze group $<title>, or analyze group $"<title with spaces>".'
939
+ };
940
+ await g({ text: `Analyzing group ${e}...`, agentName: "group-analytics" }, t);
941
+ const s = t?.configurable?.context;
942
+ I(s);
943
+ const { result: o, error: l } = await Me(s.portal, e);
944
+ if (l || !o)
945
+ return await g({ text: "Failed to fetch group context", agentName: "group-analytics" }, t), {
946
+ status: "success",
947
+ outputMessage: "Unable to retrieve group context for analytics."
948
+ };
949
+ const { group: c, items: i } = o, u = Date.now(), r = c.modified, p = r ? nt({ timestamp: r, now: u, windowMs: Te }) : !1, m = i.recentlyModifiedItems.length, d = m > 0, h = p || d, f = await v({
950
+ promptText: Ge,
951
+ schema: Ce,
952
+ modelTier: "default",
953
+ inputVariables: {
954
+ context: JSON.stringify(o),
955
+ deterministicSignals: JSON.stringify({
956
+ isGroupActive: h,
957
+ isGroupRecentlyModified: p,
958
+ hasRecentlyAddedOrUpdatedContent: d,
959
+ recentItemCount: m
960
+ })
961
+ }
962
+ }), { followUpQuestions: b, summary: S } = f, ut = z(a), ct = {
963
+ latestGroupId: e,
964
+ memory: {
965
+ ...ut.memory,
966
+ [e]: { summary: S, followUpQuestions: b, fullContext: o }
967
+ }
968
+ };
969
+ return b.length && await E({ type: "suggested-prompts", data: { prompts: b } }, t), {
970
+ status: "success",
971
+ outputMessage: S,
972
+ sharedStatePatch: { portalGroupSummaryMemory: { value: ct } }
973
+ };
974
+ }, Ce = n.object({
975
+ summary: n.string(),
976
+ followUpQuestions: n.array(n.string()).default([])
977
+ }), q = (a, t) => t ?? a, it = y.Root({
978
+ ...k(),
979
+ groupSummaryIntent: y({
972
980
  reducer: q,
973
981
  default: () => "clarify"
974
982
  }),
975
- groupSummaryGroupId: h({
983
+ groupSummaryGroupId: y({
976
984
  reducer: q,
977
985
  default: () => null
978
986
  }),
979
- groupSummaryQuestion: h({
987
+ groupSummaryQuestion: y({
980
988
  reducer: q,
981
989
  default: () => ""
982
990
  })
983
- }), Ne = () => new C(rt).addNode("detectGroupSummaryIntent", me).addNode("summarizePortalGroup", Ae).addNode("answerGroupSummaryFollowUp", ce).addNode("suggestGroupSummaryNavigation", fe).addEdge(N, "detectGroupSummaryIntent").addConditionalEdges("detectGroupSummaryIntent", (t) => t.groupSummaryIntent === "summarize" ? "summarizePortalGroup" : t.groupSummaryIntent === "followUp" ? "answerGroupSummaryFollowUp" : t.groupSummaryIntent === "navigation" ? "suggestGroupSummaryNavigation" : f).addEdge("summarizePortalGroup", f).addEdge("answerGroupSummaryFollowUp", f).addEdge("suggestGroupSummaryNavigation", f), Pe = String.raw`- **portal-group-analytics** - Portal group analytics assistant:
991
+ }), Ne = () => new N(it).addNode("detectGroupSummaryIntent", he).addNode("summarizePortalGroup", Ae).addNode("answerGroupSummaryFollowUp", de).addNode("suggestGroupSummaryNavigation", fe).addEdge(P, "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), Pe = String.raw`- **portal-group-analytics** - Portal group analytics assistant:
984
992
  - summarizes ArcGIS portal groups from group context and sourceJSON details
985
993
  - answers follow-up questions grounded in the summarized group
986
994
  - suggests navigation to groups when relevant
@@ -989,34 +997,15 @@ Deterministic signals:
989
997
  name: "Portal Group Analytics",
990
998
  description: Pe,
991
999
  createGraph: Ne,
992
- workspace: rt
993
- }, qe = () => ({ latestItemId: null, memory: {} }), F = (s) => {
994
- const t = s?.agentExecutionContext.sharedState.portalItemAnalyticsSummaryMemory?.value;
995
- return t ? { latestItemId: t.latestItemId, memory: t.memory } : qe();
996
- }, ze = r.object({
997
- intent: r.enum(["summarize", "followUp", "clarify"]),
998
- itemId: r.string().default(""),
999
- question: r.string().default("")
1000
- }), $e = r.object({ summary: r.string(), followUpQuestions: r.array(r.string()).default([]) }), Ee = r.object({ answer: r.string(), isRelevant: r.boolean() }), De = async (s, t) => {
1001
- await g({ text: "Answering follow-up...", agentName: "analytics" }, t);
1002
- const e = F(s), a = s.analyticsItemId ?? e.latestItemId, o = a ? e.memory[a] : void 0, i = s.analyticsQuestion || I(s.agentExecutionContext.messages);
1003
- return o ? {
1004
- status: "success",
1005
- outputMessage: (await b({
1006
- promptText: Ue,
1007
- schema: Ee,
1008
- modelTier: "default",
1009
- inputVariables: {
1010
- summary: o.summary,
1011
- question: i,
1012
- fullContext: JSON.stringify(o.fullContext)
1013
- }
1014
- })).answer
1015
- } : {
1016
- status: "success",
1017
- outputMessage: "I don't have enough information yet. Please ask me to summarize the item first using summarize item <item id>."
1018
- };
1019
- }, Ue = `
1000
+ workspace: it
1001
+ }, ze = () => ({ latestItemId: null, memory: {} }), O = (a) => {
1002
+ const t = a?.agentExecutionContext.sharedState.portalItemAnalyticsSummaryMemory?.value;
1003
+ return t ? { latestItemId: t.latestItemId, memory: t.memory } : ze();
1004
+ }, W = n.object({
1005
+ intent: n.enum(["summarize", "followUp", "clarify"]),
1006
+ itemId: n.string().default(""),
1007
+ question: n.string().default("")
1008
+ }), qe = n.object({ summary: n.string(), followUpQuestions: n.array(n.string()).default([]) }), $e = n.object({ answer: n.string(), isRelevant: n.boolean() }), Ee = `
1020
1009
  You answer follow-up questions about an ArcGIS item.
1021
1010
 
1022
1011
  Ground your answer in the provided item context.
@@ -1036,27 +1025,26 @@ Item full context
1036
1025
 
1037
1026
  Question:
1038
1027
  {question}
1039
- `, Re = async (s, t) => {
1040
- await g({ text: "Analyzing intent...", agentName: "analytics" }, t);
1041
- const e = I(s.agentExecutionContext.messages), a = !!F(s).latestItemId, o = await D.fromTemplate(Fe).format({
1042
- userMessage: e,
1043
- hasSummaryContext: String(a)
1044
- }), u = await U({
1045
- model: await E({ modelTier: "fast" }),
1046
- tools: [tt],
1047
- systemPrompt: o,
1048
- responseFormat: ze,
1049
- checkpointer: !0
1050
- }).invoke({ messages: s.agentExecutionContext.messages }, t), { intent: l, itemId: c, question: n } = u.structuredResponse, d = l === "clarify" || l === "summarize" && !c || l === "followUp" && !n;
1051
- return {
1052
- agentExecutionContext: { ...s.agentExecutionContext },
1053
- analyticsIntent: d ? "clarify" : l,
1054
- analyticsItemId: c || null,
1055
- analyticsQuestion: n || "",
1028
+ `, De = async (a, t) => {
1029
+ await g({ text: "Answering follow-up...", agentName: "analytics" }, t);
1030
+ const e = O(a), s = a.analyticsItemId ?? e.latestItemId, o = s ? e.memory[s] : void 0, l = a.analyticsQuestion || x(a.agentExecutionContext.messages);
1031
+ return o ? {
1056
1032
  status: "success",
1057
- outputMessage: d ? 'Please clarify with summarize item <item id>, summarize item #<title>, or summarize item #"<title with spaces>".' : ""
1033
+ outputMessage: (await v({
1034
+ promptText: Ee,
1035
+ schema: $e,
1036
+ modelTier: "default",
1037
+ inputVariables: {
1038
+ summary: o.summary,
1039
+ question: l,
1040
+ fullContext: JSON.stringify(o.fullContext)
1041
+ }
1042
+ })).answer
1043
+ } : {
1044
+ status: "success",
1045
+ outputMessage: "I don't have enough information yet. Please ask me to summarize the item first using summarize item <item id>."
1058
1046
  };
1059
- }, Fe = `
1047
+ }, Ue = `
1060
1048
  Classify the user analytics request.
1061
1049
 
1062
1050
  Rules:
@@ -1086,85 +1074,105 @@ hasSummaryContext:
1086
1074
 
1087
1075
  User message:
1088
1076
  {userMessage}
1089
- `, Oe = async (s, t) => {
1090
- const e = s.analyticsItemId;
1077
+ `, Re = async (a, t) => {
1078
+ await g({ text: "Analyzing intent...", agentName: "analytics" }, t);
1079
+ const e = x(a.agentExecutionContext.messages), s = !!O(a).latestItemId, o = await U.fromTemplate(Ue).format({
1080
+ userMessage: e,
1081
+ hasSummaryContext: String(s)
1082
+ }), c = (await D({ modelTier: "fast" })).withStructuredOutput(W), i = W.parse(await c.invoke(o));
1083
+ let u = i.itemId;
1084
+ if (i.intent === "summarize" && !u) {
1085
+ const f = G(e, "#");
1086
+ f && (u = await at.invoke({ itemTitle: f }, t) ?? "");
1087
+ }
1088
+ const { intent: r, question: p } = i, h = r === "clarify" || r === "summarize" && !u || r === "followUp" && !p;
1089
+ return {
1090
+ agentExecutionContext: { ...a.agentExecutionContext },
1091
+ analyticsIntent: h ? "clarify" : r,
1092
+ analyticsItemId: u || null,
1093
+ analyticsQuestion: p || "",
1094
+ status: "success",
1095
+ outputMessage: h ? 'Please clarify with summarize item <item id>, summarize item #<title>, or summarize item #"<title with spaces>".' : ""
1096
+ };
1097
+ }, Oe = `
1098
+ You are a item summary tool for ArcGIS. Your job is to summarize an item's info based on the provided context.
1099
+ Summary rules:
1100
+ - The summary should be concise markdown, make sure to format the output nicely so it's easy to read.
1101
+ - Target length: 80-150 words.
1102
+ - Provide one short descriptive paragraph.
1103
+ - Also propose 3 concise follow-up questions grounded in the item summary.
1104
+ - Keep follow-up questions specific and actionable.
1105
+ Follow-up questions rules:
1106
+ - These questions should be in the format of a prompt that the user can click on.
1107
+ - Make sure the questions are relevant to the item summary and that you can answer based solely on the provided context.
1108
+ Do not include internal identifiers.
1109
+ If the user asks for a detailed summary, you may expand the response up to 300 words.
1110
+ Item context:
1111
+ {context}
1112
+ `, Fe = async (a, t) => {
1113
+ const e = a.analyticsItemId;
1091
1114
  if (!e)
1092
1115
  return {
1093
1116
  status: "success",
1094
1117
  outputMessage: 'Please clarify with summarize item <item id>, summarize item #<title>, or summarize item #"<title with spaces>".'
1095
1118
  };
1096
1119
  await g({ text: `Summarizing item ${e}...`, agentName: "analytics" }, t);
1097
- const a = t?.configurable?.context;
1098
- v(a);
1099
- const { portal: o, user: i } = a, { result: u, error: l } = await xt(i, o, e);
1100
- if (l || !u)
1120
+ const s = t?.configurable?.context;
1121
+ I(s);
1122
+ const { portal: o, user: l } = s, { result: c, error: i } = await Mt(l, o, e);
1123
+ if (i || !c)
1101
1124
  return await g({ text: "Failed to get item context for summarization", agentName: "analytics" }, t), {
1102
1125
  status: "success",
1103
1126
  outputMessage: "Unable to retrieve item context for summarization."
1104
1127
  };
1105
- const { context: c } = u, n = await b({
1106
- promptText: Ve,
1107
- schema: $e,
1128
+ const { context: u } = c, r = await v({
1129
+ promptText: Oe,
1130
+ schema: qe,
1108
1131
  modelTier: "default",
1109
- inputVariables: { context: JSON.stringify(c) }
1110
- }), { followUpQuestions: p, summary: m } = n, d = F(s), y = {
1132
+ inputVariables: { context: JSON.stringify(u) }
1133
+ }), { followUpQuestions: p, summary: m } = r, d = O(a), h = {
1111
1134
  latestItemId: e,
1112
1135
  memory: {
1113
1136
  ...d.memory,
1114
- [e]: { summary: m, followUpQuestions: p, fullContext: c }
1137
+ [e]: { summary: m, followUpQuestions: p, fullContext: u }
1115
1138
  }
1116
1139
  };
1117
- return p.length && await $({ type: "suggested-prompts", data: { prompts: p } }, t), {
1140
+ return p.length && await E({ type: "suggested-prompts", data: { prompts: p } }, t), {
1118
1141
  status: "success",
1119
1142
  outputMessage: m,
1120
- sharedStatePatch: { portalItemAnalyticsSummaryMemory: { value: y } }
1143
+ sharedStatePatch: { portalItemAnalyticsSummaryMemory: { value: h } }
1121
1144
  };
1122
- }, Ve = `
1123
- You are a item summary tool for ArcGIS. Your job is to summarize an item's info based on the provided context.
1124
- Summary rules:
1125
- - The summary should be concise markdown, make sure to format the output nicely so it's easy to read.
1126
- - Target length: 80-150 words.
1127
- - Provide one short descriptive paragraph.
1128
- - Also propose 3 concise follow-up questions grounded in the item summary.
1129
- - Keep follow-up questions specific and actionable.
1130
- Follow-up questions rules:
1131
- - These questions should be in the format of a prompt that the user can click on.
1132
- - Make sure the questions are relevant to the item summary and that you can answer based solely on the provided context.
1133
- Do not include internal identifiers.
1134
- If the user asks for a detailed summary, you may expand the response up to 300 words.
1135
- Item context:
1136
- {context}
1137
- `, z = (s, t) => t ?? s, nt = h.Root({
1138
- ...P(),
1145
+ }, $ = (a, t) => t ?? a, lt = y.Root({
1146
+ ...k(),
1139
1147
  // States shared only across nodes in the graph, not between invocations
1140
- analyticsIntent: h({
1141
- reducer: z,
1148
+ analyticsIntent: y({
1149
+ reducer: $,
1142
1150
  default: () => "clarify"
1143
1151
  }),
1144
- analyticsItemId: h({
1145
- reducer: z,
1152
+ analyticsItemId: y({
1153
+ reducer: $,
1146
1154
  default: () => null
1147
1155
  }),
1148
- analyticsQuestion: h({
1149
- reducer: z,
1156
+ analyticsQuestion: y({
1157
+ reducer: $,
1150
1158
  default: () => ""
1151
1159
  })
1152
- }), je = () => new C(nt).addNode("detectAnalyticsIntent", Re).addNode("summarizePortalItem", Oe).addNode("answerAnalyticsFollowUp", De).addEdge(N, "detectAnalyticsIntent").addConditionalEdges("detectAnalyticsIntent", (t) => t.analyticsIntent === "summarize" ? "summarizePortalItem" : t.analyticsIntent === "followUp" ? "answerAnalyticsFollowUp" : f).addEdge("summarizePortalItem", f).addEdge("answerAnalyticsFollowUp", f), Le = String.raw`- **portal-item-analytics** - Portal item analytics assistant:
1160
+ }), Ve = () => new N(lt).addNode("detectAnalyticsIntent", Re).addNode("summarizePortalItem", Fe).addNode("answerAnalyticsFollowUp", De).addEdge(P, "detectAnalyticsIntent").addConditionalEdges("detectAnalyticsIntent", (t) => t.analyticsIntent === "summarize" ? "summarizePortalItem" : t.analyticsIntent === "followUp" ? "answerAnalyticsFollowUp" : w).addEdge("summarizePortalItem", w).addEdge("answerAnalyticsFollowUp", w), je = String.raw`- **portal-item-analytics** - Portal item analytics assistant:
1153
1161
  - answers questions about one specific ArcGIS portal item when item context is present
1154
1162
  - summarizes item details, metadata, and context grounded in that item
1155
1163
  - suggests follow-up prompts grounded in the same item
1156
1164
  - use for item-specific requests, not for gallery browsing, featured content, or opening Map Viewer
1157
- `, Be = {
1165
+ `, Le = {
1158
1166
  id: "portal-item-analytics",
1159
1167
  name: "Portal Item Analytics",
1160
- description: Le,
1161
- createGraph: je,
1162
- workspace: nt
1163
- }, Qe = dt`: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)}`;
1164
- function Ke(s, t) {
1168
+ description: je,
1169
+ createGraph: Ve,
1170
+ workspace: lt
1171
+ }, Be = gt`: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)}`;
1172
+ function Qe(a, t) {
1165
1173
  if (!t)
1166
1174
  return;
1167
- const { destinationType: e } = s;
1175
+ const { destinationType: e } = a;
1168
1176
  switch (e) {
1169
1177
  case "portal-content":
1170
1178
  case "portal-content-favorites":
@@ -1182,50 +1190,50 @@ function Ke(s, t) {
1182
1190
  case "portal-settings-security":
1183
1191
  return t[e];
1184
1192
  case "portal-item":
1185
- return t[e]?.(s.itemId);
1193
+ return t[e]?.(a.itemId);
1186
1194
  case "portal-group":
1187
- return t[e]?.(s.groupId);
1195
+ return t[e]?.(a.groupId);
1188
1196
  default:
1189
- return T(e);
1197
+ return C(e);
1190
1198
  }
1191
1199
  }
1192
- function Je(s) {
1193
- const t = Lt.safeParse(s);
1200
+ function Ke(a) {
1201
+ const t = Bt.safeParse(a);
1194
1202
  return t.success ? t.data : void 0;
1195
1203
  }
1196
- class We extends ct {
1204
+ class Je extends dt {
1197
1205
  constructor() {
1198
- super(...arguments), this.t9n = gt({ blocking: !0 }), this.assistantEl = G(), this.formEl = G(), this.voiceInputEl = G(), this.inputEl = G(), this.navigationSlotElements = /* @__PURE__ */ new Map(), this.handleSlottableRequest = (t) => {
1199
- const e = t.detail, a = e.data?.block;
1200
- if (!a)
1206
+ super(...arguments), this.t9n = ft({ blocking: !0 }), this.assistantEl = T(), this.formEl = T(), this.voiceInputEl = T(), this.inputEl = T(), this.navigationSlotElements = /* @__PURE__ */ new Map(), this.handleSlottableRequest = (t) => {
1207
+ const e = t.detail, s = e.data?.block;
1208
+ if (!s)
1201
1209
  return;
1202
- const o = this.getNavigationAction(a);
1210
+ const o = this.getNavigationAction(s);
1203
1211
  o && this.upsertNavigationSlotElement(e.slotName, o);
1204
- }, this.inputText = "", this.showVoiceInput = !0, this.isListening = !1, this.isVoiceInputDisabled = !1, this.interrupt = null, this.autoDestroyDisabled = !1, this.defaultClosed = !1, this.arcgisPortalNavigationRequest = pt();
1212
+ }, this.inputText = "", this.showVoiceInput = !0, this.isListening = !1, this.isVoiceInputDisabled = !1, this.interrupt = null, this.autoDestroyDisabled = !1, this.defaultClosed = !1, this.arcgisPortalNavigationRequest = mt();
1205
1213
  }
1206
1214
  static {
1207
1215
  this.properties = { inputText: 16, showVoiceInput: 16, isListening: 16, isVoiceInputDisabled: 16, interrupt: 16, autoDestroyDisabled: 5, portal: 0, user: 0, config: 0, navigationTargetMap: 0, defaultClosed: 5 };
1208
1216
  }
1209
1217
  static {
1210
- this.styles = Qe;
1218
+ this.styles = Be;
1211
1219
  }
1212
1220
  getNavigationAction(t) {
1213
- if (t?.type !== _)
1221
+ if (t?.type !== X)
1214
1222
  return;
1215
- const e = Je(t.data);
1223
+ const e = Ke(t.data);
1216
1224
  if (!e)
1217
1225
  return;
1218
- const a = Ke(e, this.navigationTargetMap);
1219
- if (a)
1220
- return { href: a, targetDetail: e, label: this.getNavigationText(e.destinationType) };
1226
+ const s = Qe(e, this.navigationTargetMap);
1227
+ if (s)
1228
+ return { href: s, targetDetail: e, label: this.getNavigationText(e.destinationType) };
1221
1229
  }
1222
1230
  upsertNavigationSlotElement(t, e) {
1223
- const a = this.assistantEl.value;
1224
- if (!a)
1231
+ const s = this.assistantEl.value;
1232
+ if (!s)
1225
1233
  return;
1226
1234
  let o = this.navigationSlotElements.get(t);
1227
- o || (o = document.createElement("div"), o.slot = t, this.navigationSlotElements.set(t, o), a.append(o)), mt(M`<div><calcite-button class="navigation-button" appearance=outline width=full .href=${e.href} icon-end=launch @click=${(i) => {
1228
- i.preventDefault(), this.arcgisPortalNavigationRequest.emit({
1235
+ o || (o = document.createElement("div"), o.slot = t, this.navigationSlotElements.set(t, o), s.append(o)), ht(M`<div><calcite-button class="navigation-button" appearance=outline width=full .href=${e.href} icon-end=launch @click=${(l) => {
1236
+ l.preventDefault(), this.arcgisPortalNavigationRequest.emit({
1229
1237
  href: e.href,
1230
1238
  targetDetail: e.targetDetail
1231
1239
  });
@@ -1267,49 +1275,49 @@ class We extends ct {
1267
1275
  case "portal-group":
1268
1276
  return e.openGroup;
1269
1277
  default:
1270
- return T(t);
1278
+ return C(t);
1271
1279
  }
1272
1280
  }
1273
1281
  render() {
1274
- const { t9n: t, inputText: e, portal: a, user: o, navigationTargetMap: i, showVoiceInput: u, isListening: l, isVoiceInputDisabled: c } = this;
1275
- return M`<arcgis-assistant log-enabled keep-suggested-prompts .heading=${t.heading} .entryMessage=${t.entryMessage} @arcgisSlottableRequest=${this.handleSlottableRequest} @arcgisInterrupt=${({ detail: n }) => {
1276
- this.interrupt = n;
1282
+ const { t9n: t, inputText: e, portal: s, user: o, navigationTargetMap: l, showVoiceInput: c, isListening: i, isVoiceInputDisabled: u } = this;
1283
+ return M`<arcgis-assistant log-enabled keep-suggested-prompts .heading=${t.heading} .entryMessage=${t.entryMessage} @arcgisSlottableRequest=${this.handleSlottableRequest} @arcgisInterrupt=${({ detail: r }) => {
1284
+ this.interrupt = r;
1277
1285
  }} @arcgisInterruptCancel=${() => {
1278
1286
  this.interrupt = null;
1279
1287
  }} @arcgisInterruptSubmit=${() => {
1280
1288
  this.interrupt = null;
1281
- }} @arcgisPromptSelect=${({ detail: n }) => {
1282
- this.inputText = n.prompt, requestAnimationFrame(() => {
1289
+ }} @arcgisPromptSelect=${({ detail: r }) => {
1290
+ this.inputText = r.prompt, requestAnimationFrame(() => {
1283
1291
  this.inputEl.value?.focusTextArea();
1284
1292
  });
1285
- }} ${A(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=${(n) => {
1286
- n.preventDefault();
1293
+ }} ${A(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=${(r) => {
1294
+ r.preventDefault();
1287
1295
  const p = e.trim();
1288
1296
  p && (this.assistantEl.value?.submitMessage(p), this.inputText = "");
1289
- }} ${A(this.formEl)}><arcgis-portal-mentionable-text-area .portal=${a} .user=${o} rows=3 .popoverListLabel=${t.mentionEntities} .placeholder=${t.placeholder} .value=${e} @arcgisUserMentionableTextAreaKeyDown=${({ detail: n }) => {
1290
- n.key === "Enter" && !n.shiftKey && (n.preventDefault(), this.formEl.value?.requestSubmit());
1291
- }} @arcgisUserMentionableTextAreaChange=${({ detail: n }) => {
1292
- this.inputText = n ?? "";
1297
+ }} ${A(this.formEl)}><arcgis-portal-mentionable-text-area .portal=${s} .user=${o} rows=3 .popoverListLabel=${t.mentionEntities} .placeholder=${t.placeholder} .value=${e} @arcgisUserMentionableTextAreaKeyDown=${({ detail: r }) => {
1298
+ r.key === "Enter" && !r.shiftKey && (r.preventDefault(), this.formEl.value?.requestSubmit());
1299
+ }} @arcgisUserMentionableTextAreaChange=${({ detail: r }) => {
1300
+ this.inputText = r ?? "";
1293
1301
  }} ${A(this.inputEl)}></arcgis-portal-mentionable-text-area><div class="chat-actions"><arcgis-portal-voice-input @arcgisVoiceInputStart=${() => {
1294
1302
  this.isListening = !0, this.isVoiceInputDisabled = !1;
1295
1303
  }} @arcgisVoiceInputStop=${() => {
1296
1304
  this.isListening = !1, this.isVoiceInputDisabled = !1;
1297
- }} @arcgisVoiceInputError=${(n) => {
1298
- n.detail.errorCode === "not-supported" && (this.showVoiceInput = !1);
1299
- }} @arcgisVoiceInputInterimTranscription=${(n) => {
1300
- this.inputText = n.detail.text;
1301
- }} ${A(this.voiceInputEl)}></arcgis-portal-voice-input>${u && M`<calcite-button icon-start=microphone .label=${t.voiceInput} round .disabled=${c} .appearance=${l ? "solid" : "outline-fill"} @click=${async () => {
1305
+ }} @arcgisVoiceInputError=${(r) => {
1306
+ r.detail.errorCode === "not-supported" && (this.showVoiceInput = !1);
1307
+ }} @arcgisVoiceInputInterimTranscription=${(r) => {
1308
+ this.inputText = r.detail.text;
1309
+ }} ${A(this.voiceInputEl)}></arcgis-portal-voice-input>${c && M`<calcite-button icon-start=microphone .label=${t.voiceInput} round .disabled=${u} .appearance=${i ? "solid" : "outline-fill"} @click=${async () => {
1302
1310
  this.isVoiceInputDisabled = !0;
1303
- const n = this.voiceInputEl.value;
1304
- l ? await n?.stopListening() : await n?.startListening();
1305
- }}></calcite-button>` || ""}<calcite-button type=submit icon-start=send round .disabled=${!e.trim()} .label=${t.send}>${t.send}</calcite-button></div></form><arcgis-assistant-agent .agent=${Be} .context=${{ portal: a, user: o, navigationTargetMap: i }}></arcgis-assistant-agent><arcgis-assistant-agent .agent=${Jt} .context=${{ portal: a, user: o, navigationTargetMap: i }}></arcgis-assistant-agent><arcgis-assistant-agent .agent=${le} .context=${{ portal: a, user: o, navigationTargetMap: i }}></arcgis-assistant-agent><arcgis-assistant-agent .agent=${ke} .context=${{ portal: a, user: o, navigationTargetMap: i }}></arcgis-assistant-agent>${this.interrupt && M`<arcgis-portal-ai-assistant-interrupt slot=interrupt .type=${this.interrupt.type} .message=${this.interrupt.message} .options=${this.interrupt.options} @arcgisSubmit=${({ detail: n }) => {
1306
- this.assistantEl.value?.submitInterrupt(n);
1311
+ const r = this.voiceInputEl.value;
1312
+ i ? await r?.stopListening() : await r?.startListening();
1313
+ }}></calcite-button>` || ""}<calcite-button type=submit icon-start=send round .disabled=${!e.trim()} .label=${t.send}>${t.send}</calcite-button></div></form><arcgis-assistant-agent .agent=${Le} .context=${{ portal: s, user: o, navigationTargetMap: l }}></arcgis-assistant-agent><arcgis-assistant-agent .agent=${Wt} .context=${{ portal: s, user: o, navigationTargetMap: l }}></arcgis-assistant-agent><arcgis-assistant-agent .agent=${ue} .context=${{ portal: s, user: o, navigationTargetMap: l }}></arcgis-assistant-agent><arcgis-assistant-agent .agent=${ke} .context=${{ portal: s, user: o, navigationTargetMap: l }}></arcgis-assistant-agent>${this.interrupt && M`<arcgis-portal-ai-assistant-interrupt slot=interrupt .type=${this.interrupt.type} .message=${this.interrupt.message} .options=${this.interrupt.options} @arcgisSubmit=${({ detail: r }) => {
1314
+ this.assistantEl.value?.submitInterrupt(r);
1307
1315
  }} @arcgisCancel=${() => {
1308
1316
  this.assistantEl.value?.cancelInterrupt();
1309
1317
  }}></arcgis-portal-ai-assistant-interrupt>` || ""}</arcgis-assistant>`;
1310
1318
  }
1311
1319
  }
1312
- ut("arcgis-portal-ai-assistant", We);
1320
+ pt("arcgis-portal-ai-assistant", Je);
1313
1321
  export {
1314
- We as ArcgisPortalAiAssistant
1322
+ Je as ArcgisPortalAiAssistant
1315
1323
  };