@arcgis/ai-components 5.2.0-next.88 → 5.2.0-next.89
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-utils/LLMAgent.js +1 -0
- package/dist/cdn/{7FY7WAA5.js → 222B5OU6.js} +1 -1
- package/dist/cdn/{APDJ4EPR.js → 2FOCAXWJ.js} +1 -1
- package/dist/cdn/6VJXUIXY.js +3 -0
- package/dist/cdn/{HJEYVERV.js → C5ZL5Z52.js} +5 -5
- package/dist/cdn/{EUM4DZDR.js → COL6QYGQ.js} +1 -1
- package/dist/cdn/{R7CCQNIY.js → CXP3ACSA.js} +1 -1
- package/dist/cdn/{ESHAIDS7.js → FUZ77UGP.js} +4 -4
- package/dist/cdn/{MBBDTSIF.js → HKSFWTWK.js} +5 -5
- package/dist/cdn/{GPXL4CYF.js → LPR72QZF.js} +2 -2
- package/dist/cdn/{64K5QGMS.js → LS4FJKFE.js} +1 -1
- package/dist/cdn/{YNWG4AIR.js → OYSPNIJI.js} +21 -21
- package/dist/cdn/{FAR3DFFK.js → PEYYWXFE.js} +1 -1
- package/dist/cdn/{C4MALUDF.js → SUYWKYWI.js} +2 -2
- package/dist/cdn/{PULEMR55.js → VTQKRCKU.js} +1 -1
- package/dist/cdn/Y5TYSBLZ.js +3 -0
- package/dist/cdn/{PQ5HW7F5.js → Y7QZBO46.js} +1 -1
- package/dist/cdn/{EMLOVMD4.js → ZVGUAOXE.js} +1 -1
- package/dist/cdn/agent-utils/index.js +1 -1
- package/dist/cdn/index.js +1 -1
- package/dist/chunks/adapter.js +55 -54
- package/dist/chunks/arcgisKnowledgeGraph.js +3 -2
- package/dist/chunks/dataExplorationGraph.js +3 -2
- package/dist/chunks/helpGraph.js +3 -2
- package/dist/chunks/layerStylingGraph.js +1 -0
- package/dist/chunks/navigationGraph.js +3 -2
- package/dist/chunks/orchestrator.js +322 -193
- package/dist/chunks/toolCallResponse.js +3 -2
- package/dist/components/arcgis-assistant/customElement.d.ts +16 -0
- package/dist/components/arcgis-assistant/customElement.js +190 -178
- package/dist/components/arcgis-assistant-agent/customElement.js +1 -0
- package/dist/components/arcgis-assistant-data-exploration-agent/customElement.js +1 -0
- package/dist/components/arcgis-assistant-help-agent/customElement.js +1 -0
- package/dist/components/arcgis-assistant-knowledge-agent/customElement.js +1 -0
- package/dist/components/arcgis-assistant-layer-styling-agent/customElement.js +6 -5
- package/dist/components/arcgis-assistant-navigation-agent/customElement.js +1 -0
- package/dist/docs/api.json +1 -1
- package/dist/docs/docs.json +1 -1
- package/dist/docs/vscode.html-custom-data.json +1 -1
- package/dist/docs/web-types.json +1 -1
- package/dist/loader.js +1 -1
- package/dist/orchestrator/orchestrator/orchestratorEvents.d.ts +78 -0
- package/dist/types/lumina.d.ts +2 -1
- package/dist/types/preact.d.ts +2 -1
- package/dist/types/react.d.ts +2 -1
- package/dist/types/stencil.d.ts +2 -1
- package/package.json +5 -5
- package/dist/cdn/L7XTRDFM.js +0 -3
- package/dist/cdn/ZUNLFO6M.js +0 -3
- /package/dist/cdn/{ONMNQBPO.js → SZ2QSSB3.js} +0 -0
|
@@ -7,7 +7,7 @@ import M from "@arcgis/core/portal/Portal.js";
|
|
|
7
7
|
import { LitElement as O, createEvent as p, nothing as f } from "@arcgis/lumina";
|
|
8
8
|
import * as B from "@arcgis/toolkit/log";
|
|
9
9
|
import { rethrowError as z } from "@arcgis/toolkit/log";
|
|
10
|
-
import { createRef as v, ref as
|
|
10
|
+
import { createRef as v, ref as k } from "lit/directives/ref.js";
|
|
11
11
|
import { u as U } from "../../chunks/useT9n.js";
|
|
12
12
|
import { O as q } from "../../chunks/orchestrator.js";
|
|
13
13
|
import "@langchain/core/callbacks/dispatch/web";
|
|
@@ -27,8 +27,8 @@ import { marked as E } from "marked";
|
|
|
27
27
|
import { g as j } from "../../chunks/utils3.js";
|
|
28
28
|
import { g as $ } from "../../chunks/slottableRequestUtils.js";
|
|
29
29
|
const H = A`:host{display:block;width:var(--arcgis-internal-panel-width, 100%);height:var(--arcgis-internal-expand-max-height, 100%);--calcite-panel-content-bottom-space: 0}.footer-container{display:flex;flex-direction:column;flex:1 1 0;gap:var(--calcite-spacing-md)}.content-container{display:flex;flex-direction:column;flex:1 1 0;min-height:0;position:relative;overflow:auto}.suggested-prompts-container{display:flex;justify-content:center;width:100%;background:var(--calcite-panel-background-color, var(--calcite-color-background))}.suggested-prompts{display:block;padding:var(--calcite-spacing-md);max-width:100%;box-sizing:border-box}.error-notice{padding:var(--calcite-spacing-sm)}.interrupt-waiting-message{font-style:italic;color:var(--calcite-color-text-2)}`;
|
|
30
|
-
function
|
|
31
|
-
return o.trim() ? E.lexer(o).filter((
|
|
30
|
+
function w(o) {
|
|
31
|
+
return o.trim() ? E.lexer(o).filter((e) => e.type !== "space").map((e) => E.parser([e])) : [];
|
|
32
32
|
}
|
|
33
33
|
class C {
|
|
34
34
|
constructor() {
|
|
@@ -36,17 +36,17 @@ class C {
|
|
|
36
36
|
}
|
|
37
37
|
// full streamed markdown so far
|
|
38
38
|
// Add one chunk and return all current segments.
|
|
39
|
-
push(
|
|
40
|
-
return this._rawText +=
|
|
39
|
+
push(e) {
|
|
40
|
+
return this._rawText += e, this._advanceStableBoundary(), this.getParts();
|
|
41
41
|
}
|
|
42
42
|
// Parse the remaining live tail. Call once at stream end.
|
|
43
43
|
finalize() {
|
|
44
|
-
const
|
|
45
|
-
return
|
|
44
|
+
const e = this._rawText.slice(this._stableText.length);
|
|
45
|
+
return e.trim() && (this._stableParts.push(...w(e)), this._stableText = this._rawText), this._stableParts;
|
|
46
46
|
}
|
|
47
47
|
// Get full output: stable segments + current live tail.
|
|
48
48
|
getParts() {
|
|
49
|
-
const
|
|
49
|
+
const e = this._trimIncompleteTail(this._rawText.slice(this._stableText.length)), s = e.trim() ? w(e) : [];
|
|
50
50
|
return [...this._stableParts, ...s];
|
|
51
51
|
}
|
|
52
52
|
reset() {
|
|
@@ -54,23 +54,23 @@ class C {
|
|
|
54
54
|
}
|
|
55
55
|
// Move parse-safe content from live tail into stable content.
|
|
56
56
|
_advanceStableBoundary() {
|
|
57
|
-
const
|
|
57
|
+
const e = this._rawText.slice(this._stableText.length), s = this._lastSafeBoundary(e);
|
|
58
58
|
if (s <= 0)
|
|
59
59
|
return;
|
|
60
|
-
const
|
|
61
|
-
this._stableParts.push(...
|
|
60
|
+
const i = e.slice(0, s);
|
|
61
|
+
this._stableParts.push(...w(i)), this._stableText += i;
|
|
62
62
|
}
|
|
63
63
|
/**
|
|
64
64
|
* Find the last blank-line boundary that is outside code fences.
|
|
65
65
|
* Returns 0 if no safe boundary is available yet.
|
|
66
66
|
*/
|
|
67
|
-
_lastSafeBoundary(
|
|
68
|
-
const s =
|
|
67
|
+
_lastSafeBoundary(e) {
|
|
68
|
+
const s = e.split(`
|
|
69
69
|
`);
|
|
70
|
-
let
|
|
71
|
-
for (const
|
|
72
|
-
/^\s*(```|~~~)/u.test(
|
|
73
|
-
return
|
|
70
|
+
let i = !1, t = 0, n = 0;
|
|
71
|
+
for (const r of s)
|
|
72
|
+
/^\s*(```|~~~)/u.test(r) && (i = !i), n += r.length + 1, r.trim() === "" && !i && (t = n);
|
|
73
|
+
return t < e.length ? t : 0;
|
|
74
74
|
}
|
|
75
75
|
/**
|
|
76
76
|
* Remove incomplete syntax at the end so we do not render partial markup.
|
|
@@ -79,26 +79,26 @@ class C {
|
|
|
79
79
|
* - HTML elements missing closing tags
|
|
80
80
|
* - markdown links missing closing ')'
|
|
81
81
|
*/
|
|
82
|
-
_trimIncompleteTail(
|
|
83
|
-
const s =
|
|
84
|
-
if (s !== -1 && !
|
|
85
|
-
return
|
|
86
|
-
const
|
|
87
|
-
if (
|
|
88
|
-
return
|
|
89
|
-
const
|
|
90
|
-
if (
|
|
91
|
-
const n =
|
|
82
|
+
_trimIncompleteTail(e) {
|
|
83
|
+
const s = e.lastIndexOf("<");
|
|
84
|
+
if (s !== -1 && !e.includes(">", s))
|
|
85
|
+
return e.slice(0, s);
|
|
86
|
+
const i = this._earliestUnclosedTag(e);
|
|
87
|
+
if (i !== -1)
|
|
88
|
+
return e.slice(0, i);
|
|
89
|
+
const t = e.lastIndexOf("[");
|
|
90
|
+
if (t !== -1) {
|
|
91
|
+
const n = e.slice(t);
|
|
92
92
|
if (!/\[[^\]]*\]\([^)]*\)/u.test(n))
|
|
93
|
-
return
|
|
93
|
+
return e.slice(0, t);
|
|
94
94
|
}
|
|
95
|
-
return
|
|
95
|
+
return e;
|
|
96
96
|
}
|
|
97
97
|
/**
|
|
98
98
|
* Return the index of the earliest unclosed opening tag, or -1.
|
|
99
99
|
* Ignores void elements (img, br, input, etc.) and self-closing tags.
|
|
100
100
|
*/
|
|
101
|
-
_earliestUnclosedTag(
|
|
101
|
+
_earliestUnclosedTag(e) {
|
|
102
102
|
const s = /* @__PURE__ */ new Set([
|
|
103
103
|
"br",
|
|
104
104
|
"img",
|
|
@@ -113,59 +113,59 @@ class C {
|
|
|
113
113
|
"source",
|
|
114
114
|
"track",
|
|
115
115
|
"wbr"
|
|
116
|
-
]),
|
|
117
|
-
for (let n =
|
|
118
|
-
const [,
|
|
116
|
+
]), i = /<(\/?)([a-zA-Z][\w-]*)\b[^>]*?(\/?)>/gu, t = [];
|
|
117
|
+
for (let n = i.exec(e); n; n = i.exec(e)) {
|
|
118
|
+
const [, r, a, l] = n, h = a.toLowerCase();
|
|
119
119
|
if (!(s.has(h) || l === "/"))
|
|
120
|
-
if (
|
|
121
|
-
for (let g =
|
|
122
|
-
if (
|
|
123
|
-
|
|
120
|
+
if (r === "/") {
|
|
121
|
+
for (let g = t.length - 1; g >= 0; g--)
|
|
122
|
+
if (t[g].name === h) {
|
|
123
|
+
t.splice(g);
|
|
124
124
|
break;
|
|
125
125
|
}
|
|
126
126
|
} else
|
|
127
|
-
|
|
127
|
+
t.push({ name: h, index: n.index });
|
|
128
128
|
}
|
|
129
|
-
return
|
|
129
|
+
return t.length ? t[0].index : -1;
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
function W(o) {
|
|
133
|
-
const
|
|
134
|
-
return
|
|
133
|
+
const e = new C();
|
|
134
|
+
return e.push(o), e.finalize();
|
|
135
135
|
}
|
|
136
|
-
const G = async (o) => await new Promise((
|
|
137
|
-
async function* Z(o, { chunkSize:
|
|
138
|
-
const
|
|
139
|
-
for (let
|
|
140
|
-
yield
|
|
141
|
-
yield
|
|
136
|
+
const G = async (o) => await new Promise((e) => setTimeout(e, o));
|
|
137
|
+
async function* Z(o, { chunkSize: e = 15, delay: s = 50 } = {}) {
|
|
138
|
+
const i = new C();
|
|
139
|
+
for (let t = 0; t < o.length; t += e)
|
|
140
|
+
yield i.push(o.slice(t, t + e)), await G(s);
|
|
141
|
+
yield i.finalize();
|
|
142
142
|
}
|
|
143
|
-
var J = Object.defineProperty, K = Object.getOwnPropertyDescriptor, u = (o,
|
|
144
|
-
for (var
|
|
145
|
-
(
|
|
146
|
-
return
|
|
143
|
+
var J = Object.defineProperty, K = Object.getOwnPropertyDescriptor, u = (o, e, s, i) => {
|
|
144
|
+
for (var t = i > 1 ? void 0 : i ? K(e, s) : e, n = o.length - 1, r; n >= 0; n--)
|
|
145
|
+
(r = o[n]) && (t = (i ? r(e, s, t) : r(t)) || t);
|
|
146
|
+
return i && t && J(e, s, t), t;
|
|
147
147
|
};
|
|
148
148
|
const S = (o) => !o || typeof o != "object" ? !1 : o.name === "AbortError";
|
|
149
|
-
async function* I(o,
|
|
150
|
-
if (
|
|
151
|
-
if (
|
|
152
|
-
yield { type: "cancelled", log: s, runId:
|
|
149
|
+
async function* I(o, e, s, i, t = !1) {
|
|
150
|
+
if (t) {
|
|
151
|
+
if (i?.aborted) {
|
|
152
|
+
yield { type: "cancelled", log: s, runId: e };
|
|
153
153
|
return;
|
|
154
154
|
}
|
|
155
|
-
yield { type: "block-data", blockType: "text", data: { parts: W(o) }, runId:
|
|
155
|
+
yield { type: "block-data", blockType: "text", data: { parts: W(o) }, runId: e };
|
|
156
156
|
return;
|
|
157
157
|
}
|
|
158
158
|
for await (const n of Z(o)) {
|
|
159
|
-
if (
|
|
160
|
-
yield { type: "cancelled", log: s, runId:
|
|
159
|
+
if (i?.aborted) {
|
|
160
|
+
yield { type: "cancelled", log: s, runId: e };
|
|
161
161
|
return;
|
|
162
162
|
}
|
|
163
|
-
yield { type: "block-data", blockType: "text", data: { parts: n }, runId:
|
|
163
|
+
yield { type: "block-data", blockType: "text", data: { parts: n }, runId: e };
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
let d = class extends V {
|
|
167
167
|
constructor(o) {
|
|
168
|
-
super(o), this.view = null, this.streamingDisabled = !1, this.loading = !1, this.processing = !1, this.processingStep = "";
|
|
168
|
+
super(o), this.view = null, this.streamingDisabled = !1, this.runtimeEventsEnabled = !1, this.loading = !1, this.processing = !1, this.processingStep = "";
|
|
169
169
|
}
|
|
170
170
|
async load() {
|
|
171
171
|
this._set("loading", !0);
|
|
@@ -183,6 +183,7 @@ let d = class extends V {
|
|
|
183
183
|
"orchestrator",
|
|
184
184
|
await q.init({
|
|
185
185
|
agents: [...this.agents],
|
|
186
|
+
runtimeEventsEnabled: this.runtimeEventsEnabled,
|
|
186
187
|
view: this.view ?? void 0
|
|
187
188
|
})
|
|
188
189
|
), this.addHandles([
|
|
@@ -197,52 +198,56 @@ let d = class extends V {
|
|
|
197
198
|
clearChatHistory() {
|
|
198
199
|
this.orchestrator?.newConversation();
|
|
199
200
|
}
|
|
200
|
-
async *ask(o,
|
|
201
|
+
async *ask(o, e) {
|
|
201
202
|
if (!this.orchestrator)
|
|
202
203
|
throw new Error("Orchestrator not initialized yet.");
|
|
203
204
|
this._set("processing", !0), this._set("processingStep", "");
|
|
204
205
|
const s = [];
|
|
205
|
-
let
|
|
206
|
+
let i, t = "pending";
|
|
206
207
|
try {
|
|
207
208
|
const n = this.orchestrator.ask(o);
|
|
208
|
-
for await (const
|
|
209
|
-
switch (
|
|
209
|
+
for await (const r of n)
|
|
210
|
+
switch (t = r.runId, r.type) {
|
|
211
|
+
case "runtime": {
|
|
212
|
+
yield { type: "runtime", event: r, runId: t };
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
210
215
|
case "trace": {
|
|
211
|
-
this._set("processingStep",
|
|
216
|
+
this._set("processingStep", r.data.text), s.push(r.data.text);
|
|
212
217
|
break;
|
|
213
218
|
}
|
|
214
219
|
case "completed": {
|
|
215
220
|
this._set("processing", !1), this._set("processingStep", "");
|
|
216
|
-
const a =
|
|
221
|
+
const a = r.result, l = !!a.content.length, h = !!i?.length;
|
|
217
222
|
if (!l && !h) {
|
|
218
|
-
yield { type: "completed", error: "No response received.", log: s, runId:
|
|
223
|
+
yield { type: "completed", error: "No response received.", log: s, runId: t };
|
|
219
224
|
return;
|
|
220
225
|
}
|
|
221
226
|
const g = a.content;
|
|
222
|
-
if (yield { type: "block-start", blockType: "text", runId:
|
|
223
|
-
for (const _ of
|
|
224
|
-
if (
|
|
225
|
-
yield { type: "cancelled", log: s, runId:
|
|
227
|
+
if (yield { type: "block-start", blockType: "text", runId: t }, yield* I(g, t, s, e, this.streamingDisabled), yield { type: "block-end", blockType: "text", runId: t }, h)
|
|
228
|
+
for (const _ of i) {
|
|
229
|
+
if (e?.aborted) {
|
|
230
|
+
yield { type: "cancelled", log: s, runId: t };
|
|
226
231
|
return;
|
|
227
232
|
}
|
|
228
233
|
const { type: b, data: y } = _;
|
|
229
|
-
if (yield { type: "block-start", blockType: b, runId:
|
|
234
|
+
if (yield { type: "block-start", blockType: b, runId: t }, b === "text") {
|
|
230
235
|
const P = typeof y?.content == "string" ? y.content : "";
|
|
231
|
-
yield* I(P,
|
|
236
|
+
yield* I(P, t, s, e, this.streamingDisabled);
|
|
232
237
|
} else
|
|
233
|
-
yield { type: "block-data", blockType: b, data: y, runId:
|
|
234
|
-
yield { type: "block-end", blockType: b, runId:
|
|
238
|
+
yield { type: "block-data", blockType: b, data: y, runId: t };
|
|
239
|
+
yield { type: "block-end", blockType: b, runId: t };
|
|
235
240
|
}
|
|
236
|
-
yield { type: "completed", response: g, blocks:
|
|
241
|
+
yield { type: "completed", response: g, blocks: i, log: s, runId: t };
|
|
237
242
|
return;
|
|
238
243
|
}
|
|
239
244
|
case "ux-suggestion": {
|
|
240
|
-
const a =
|
|
241
|
-
|
|
245
|
+
const a = r.suggestion;
|
|
246
|
+
i = i ? [...i, a] : [a];
|
|
242
247
|
break;
|
|
243
248
|
}
|
|
244
249
|
case "interrupt": {
|
|
245
|
-
const { kind: a, message: l, metadata: h } =
|
|
250
|
+
const { kind: a, message: l, metadata: h } = r.interrupt, g = Array.isArray(h) ? h.filter((b) => typeof b == "string") : [], _ = (() => {
|
|
246
251
|
switch (a) {
|
|
247
252
|
case "booleanChoice":
|
|
248
253
|
return { type: "boolean-choice", message: l, options: g };
|
|
@@ -256,29 +261,29 @@ let d = class extends V {
|
|
|
256
261
|
return { type: a, message: l, options: g };
|
|
257
262
|
}
|
|
258
263
|
})();
|
|
259
|
-
this._set("processingStep", "Waiting for user input..."), yield { type: "interrupt", payload: _, runId:
|
|
264
|
+
this._set("processingStep", "Waiting for user input..."), yield { type: "interrupt", payload: _, runId: t };
|
|
260
265
|
break;
|
|
261
266
|
}
|
|
262
267
|
case "cancelled": {
|
|
263
|
-
yield { type: "cancelled", log: s, runId:
|
|
268
|
+
yield { type: "cancelled", log: s, runId: t };
|
|
264
269
|
return;
|
|
265
270
|
}
|
|
266
271
|
case "error": {
|
|
267
|
-
if (
|
|
268
|
-
yield { type: "cancelled", log: s, runId:
|
|
272
|
+
if (e?.aborted || S(r.error)) {
|
|
273
|
+
yield { type: "cancelled", log: s, runId: t };
|
|
269
274
|
return;
|
|
270
275
|
}
|
|
271
|
-
yield { type: "completed", error:
|
|
276
|
+
yield { type: "completed", error: r.error.message, log: s, runId: t };
|
|
272
277
|
return;
|
|
273
278
|
}
|
|
274
279
|
default: {
|
|
275
|
-
console.warn("Unknown event type:",
|
|
280
|
+
console.warn("Unknown event type:", r);
|
|
276
281
|
break;
|
|
277
282
|
}
|
|
278
283
|
}
|
|
279
284
|
} catch (n) {
|
|
280
|
-
if (
|
|
281
|
-
yield { type: "cancelled", log: s, runId:
|
|
285
|
+
if (e?.aborted || S(n)) {
|
|
286
|
+
yield { type: "cancelled", log: s, runId: t };
|
|
282
287
|
return;
|
|
283
288
|
}
|
|
284
289
|
console.warn("Error during message processing:", n), yield { type: "completed", error: "An error occurred during message processing.", log: s, runId: "error" };
|
|
@@ -306,6 +311,9 @@ u([
|
|
|
306
311
|
u([
|
|
307
312
|
m()
|
|
308
313
|
], d.prototype, "streamingDisabled", 2);
|
|
314
|
+
u([
|
|
315
|
+
m()
|
|
316
|
+
], d.prototype, "runtimeEventsEnabled", 2);
|
|
309
317
|
u([
|
|
310
318
|
m({ readOnly: !0 })
|
|
311
319
|
], d.prototype, "loading", 2);
|
|
@@ -319,48 +327,48 @@ d = u([
|
|
|
319
327
|
F("OrchestratorController")
|
|
320
328
|
], d);
|
|
321
329
|
const Q = "Embeddings resource 'embeddings-v01.json' not found in the webmap portal item.", X = "Embeddings not found for this web map.", Y = "https://developers.arcgis.com/javascript/latest/agentic-apps/ai-webmap-setup/#embeddings";
|
|
322
|
-
class
|
|
330
|
+
class ee extends O {
|
|
323
331
|
constructor() {
|
|
324
|
-
super(...arguments), this._messages = U({ blocking: !0 }), this.#
|
|
325
|
-
|
|
326
|
-
}, this.#n = (
|
|
327
|
-
|
|
328
|
-
const s =
|
|
332
|
+
super(...arguments), this._messages = U({ blocking: !0 }), this.#e = v(), this.#l = v(), this.#s = v(), this.#t = null, this.#r = /* @__PURE__ */ new Map(), this.#i = M.getDefault(), this.#a = (e) => {
|
|
333
|
+
e.stopPropagation(), this.cancelInterrupt();
|
|
334
|
+
}, this.#n = (e) => {
|
|
335
|
+
e.stopPropagation();
|
|
336
|
+
const s = e.detail;
|
|
329
337
|
this.submitInterrupt(s);
|
|
330
|
-
}, this.#c = (
|
|
331
|
-
|
|
332
|
-
const s =
|
|
338
|
+
}, this.#c = (e) => {
|
|
339
|
+
e.stopPropagation(), this.keepSuggestedPrompts || (this.suggestedPrompts = []);
|
|
340
|
+
const s = e.detail;
|
|
333
341
|
this._inputValue = "", this.arcgisSubmit.emit(s), this.submitMessage(s);
|
|
334
|
-
}, this.#h = (
|
|
335
|
-
if (this._canceling = !0,
|
|
342
|
+
}, this.#h = (e) => {
|
|
343
|
+
if (this._canceling = !0, e.stopPropagation(), this.arcgisCancel.emit(), this._interrupt) {
|
|
336
344
|
this.orchestrator?.cancelInterrupt(), this._interrupt = null;
|
|
337
345
|
return;
|
|
338
346
|
}
|
|
339
|
-
this._orchestratorController?.cancel(), this.#
|
|
340
|
-
}, this.#g = (
|
|
341
|
-
|
|
342
|
-
const s =
|
|
347
|
+
this._orchestratorController?.cancel(), this.#t?.abort(), this.#t = null;
|
|
348
|
+
}, this.#g = (e) => {
|
|
349
|
+
e.stopPropagation();
|
|
350
|
+
const s = e.detail;
|
|
343
351
|
this.arcgisFeedback.emit(s);
|
|
344
|
-
}, this.#p = (
|
|
345
|
-
|
|
346
|
-
const s =
|
|
352
|
+
}, this.#p = (e) => {
|
|
353
|
+
e.stopPropagation();
|
|
354
|
+
const s = e.detail;
|
|
347
355
|
this._inputValue = s.prompt, this.arcgisPromptSelect.emit(s);
|
|
348
|
-
}, this.#d = (
|
|
349
|
-
this.arcgisSlottableRequest.emit(
|
|
350
|
-
}, this._orchestratorController = null, this._interrupt = null, this._interruptDetails = [], this._error = null, this._inputValue = "", this._isAnswering = !1, this._canceling = !1, this.messages = new L([]), this.referenceElement = null, this.suggestedPrompts = [], this.feedbackEnabled = !1, this.keepSuggestedPrompts = !1, this.streamingDisabled = !1, this.logEnabled = !1, this.copyEnabled = !1, this.voiceInputEnabled = !1, this.readAloudEnabled = !1, this.assistantAvatarEnabled = !1, this.userAvatarEnabled = !1, this.arcgisCancel = p(), this.arcgisError = p(), this.arcgisFeedback = p(), this.arcgisInterrupt = p(), this.arcgisInterruptCancel = p(), this.arcgisInterruptSubmit = p(), this.arcgisPromptSelect = p(), this.arcgisReady = p(), this.arcgisSubmit = p(), this.arcgisSlottableRequest = p({ bubbles: !1, composed: !1 }), this.arcgisResponse = p();
|
|
356
|
+
}, this.#d = (e) => {
|
|
357
|
+
this.arcgisSlottableRequest.emit(e.detail);
|
|
358
|
+
}, this._orchestratorController = null, this._interrupt = null, this._interruptDetails = [], this._error = null, this._inputValue = "", this._isAnswering = !1, this._canceling = !1, this.messages = new L([]), this.referenceElement = null, this.suggestedPrompts = [], this.feedbackEnabled = !1, this.keepSuggestedPrompts = !1, this.streamingDisabled = !1, this.runtimeEventsEnabled = !1, this.logEnabled = !1, this.copyEnabled = !1, this.voiceInputEnabled = !1, this.readAloudEnabled = !1, this.assistantAvatarEnabled = !1, this.userAvatarEnabled = !1, this.arcgisCancel = p(), this.arcgisError = p(), this.arcgisFeedback = p(), this.arcgisInterrupt = p(), this.arcgisInterruptCancel = p(), this.arcgisInterruptSubmit = p(), this.arcgisPromptSelect = p(), this.arcgisReady = p(), this.arcgisSubmit = p(), this.arcgisSlottableRequest = p({ bubbles: !1, composed: !1 }), this.arcgisResponse = p(), this.arcgisRuntime = p({ bubbles: !1, composed: !1 });
|
|
351
359
|
}
|
|
352
360
|
static {
|
|
353
|
-
this.properties = { _orchestratorController: 16, _interrupt: 16, _interruptDetails: 16, _error: 16, _inputValue: 16, _isAnswering: 16, _signedInUserId: 16, _canceling: 16, _isSignedIn: 16, _user: 16, awaitingResponse: 32, awaitingResponseStep: 32, interrupt: 32, messages: 0, orchestrator: 32, entryMessage: 1, heading: 1, description: 1, referenceElement: 1, suggestedPrompts: 0, feedbackEnabled: 5, keepSuggestedPrompts: 5, streamingDisabled: 5, logEnabled: 5, copyEnabled: 5, voiceInputEnabled: 5, readAloudEnabled: 5, assistantAvatarEnabled: 5, userAvatarEnabled: 5 };
|
|
361
|
+
this.properties = { _orchestratorController: 16, _interrupt: 16, _interruptDetails: 16, _error: 16, _inputValue: 16, _isAnswering: 16, _signedInUserId: 16, _canceling: 16, _isSignedIn: 16, _user: 16, awaitingResponse: 32, awaitingResponseStep: 32, interrupt: 32, messages: 0, orchestrator: 32, entryMessage: 1, heading: 1, description: 1, referenceElement: 1, suggestedPrompts: 0, feedbackEnabled: 5, keepSuggestedPrompts: 5, streamingDisabled: 5, runtimeEventsEnabled: 5, logEnabled: 5, copyEnabled: 5, voiceInputEnabled: 5, readAloudEnabled: 5, assistantAvatarEnabled: 5, userAvatarEnabled: 5 };
|
|
354
362
|
}
|
|
355
363
|
static {
|
|
356
364
|
this.styles = H;
|
|
357
365
|
}
|
|
358
|
-
#
|
|
366
|
+
#e;
|
|
359
367
|
#l;
|
|
360
368
|
#s;
|
|
361
|
-
#
|
|
362
|
-
#i;
|
|
369
|
+
#t;
|
|
363
370
|
#r;
|
|
371
|
+
#i;
|
|
364
372
|
#a;
|
|
365
373
|
#n;
|
|
366
374
|
#c;
|
|
@@ -370,24 +378,25 @@ class tt extends O {
|
|
|
370
378
|
#d;
|
|
371
379
|
async #o() {
|
|
372
380
|
try {
|
|
373
|
-
const
|
|
374
|
-
await
|
|
375
|
-
const s = [...this.#
|
|
381
|
+
const e = j(this.el, this.referenceElement);
|
|
382
|
+
await e?.componentOnReady();
|
|
383
|
+
const s = [...this.#r.values()];
|
|
376
384
|
return s.length ? (this._orchestratorController?.destroy(), this._orchestratorController = new d({
|
|
377
385
|
agents: s,
|
|
378
|
-
portal: this.#
|
|
386
|
+
portal: this.#i,
|
|
387
|
+
runtimeEventsEnabled: this.runtimeEventsEnabled,
|
|
379
388
|
streamingDisabled: this.streamingDisabled,
|
|
380
|
-
view:
|
|
389
|
+
view: e?.view
|
|
381
390
|
}), await this._orchestratorController.load(), this.requestUpdate(), !0) : (this._error = this._messages.noAgentsFoundMessage, !1);
|
|
382
|
-
} catch (
|
|
383
|
-
return this._error =
|
|
391
|
+
} catch (e) {
|
|
392
|
+
return this._error = e?.message ?? this._messages.orchestratorInitializationErrorMessage, z(this)(e), !1;
|
|
384
393
|
}
|
|
385
394
|
}
|
|
386
395
|
get _isSignedIn() {
|
|
387
|
-
return !!this.#
|
|
396
|
+
return !!this.#i?.user || !!this._signedInUserId;
|
|
388
397
|
}
|
|
389
398
|
get _user() {
|
|
390
|
-
return this.#
|
|
399
|
+
return this.#i?.user?.fullName || this.#i?.user?.username;
|
|
391
400
|
}
|
|
392
401
|
get awaitingResponse() {
|
|
393
402
|
return this._orchestratorController?.processing ?? !1;
|
|
@@ -407,14 +416,14 @@ class tt extends O {
|
|
|
407
416
|
cancelInterrupt() {
|
|
408
417
|
this.arcgisInterruptCancel.emit(), this.orchestrator?.cancelInterrupt(), this._interrupt = null;
|
|
409
418
|
}
|
|
410
|
-
register(
|
|
411
|
-
this.#
|
|
419
|
+
register(e) {
|
|
420
|
+
this.#r.set(e.agent.id, e), this._orchestratorController && this.#o();
|
|
412
421
|
}
|
|
413
|
-
unregister(
|
|
414
|
-
this.#
|
|
422
|
+
unregister(e) {
|
|
423
|
+
this.#r.delete(e), this._orchestratorController && this.#o();
|
|
415
424
|
}
|
|
416
|
-
async submitMessage(
|
|
417
|
-
const s =
|
|
425
|
+
async submitMessage(e) {
|
|
426
|
+
const s = e.trim();
|
|
418
427
|
if (!s || (this.messages.push({
|
|
419
428
|
id: Date.now().toString(),
|
|
420
429
|
// TODO: Replace with a more robust ID generation method or get from orchestrator
|
|
@@ -422,17 +431,20 @@ class tt extends O {
|
|
|
422
431
|
content: s
|
|
423
432
|
}), !this._orchestratorController))
|
|
424
433
|
return;
|
|
425
|
-
this.#
|
|
426
|
-
const
|
|
427
|
-
for await (const
|
|
428
|
-
const n =
|
|
429
|
-
switch (
|
|
434
|
+
this.#t = new AbortController(), this._orchestratorController.streamingDisabled = this.streamingDisabled;
|
|
435
|
+
const i = this._orchestratorController.ask(s, this.#t?.signal);
|
|
436
|
+
for await (const t of i) {
|
|
437
|
+
const n = t.runId, r = this.messages.at(-1);
|
|
438
|
+
switch (t.type) {
|
|
439
|
+
case "runtime":
|
|
440
|
+
this.arcgisRuntime.emit(t.event);
|
|
441
|
+
break;
|
|
430
442
|
case "block-start": {
|
|
431
443
|
this._isAnswering = !0;
|
|
432
|
-
const a = { type:
|
|
433
|
-
if (
|
|
434
|
-
const l = [...
|
|
435
|
-
this.messages.splice(-1, 1, { ...
|
|
444
|
+
const a = { type: t.blockType, isPending: !0 };
|
|
445
|
+
if (r?.role === "assistant" && r.id === n) {
|
|
446
|
+
const l = [...r.blocks ?? [], a];
|
|
447
|
+
this.messages.splice(-1, 1, { ...r, blocks: l });
|
|
436
448
|
} else
|
|
437
449
|
this.messages.push({
|
|
438
450
|
role: "assistant",
|
|
@@ -444,9 +456,9 @@ class tt extends O {
|
|
|
444
456
|
break;
|
|
445
457
|
}
|
|
446
458
|
case "block-data": {
|
|
447
|
-
if (
|
|
459
|
+
if (r?.role !== "assistant" || r?.id !== n)
|
|
448
460
|
break;
|
|
449
|
-
const a = [...
|
|
461
|
+
const a = [...r.blocks ?? []], l = a[a.length - 1], { blockType: h, data: g } = t;
|
|
450
462
|
if (l?.type !== h || !l.isPending)
|
|
451
463
|
break;
|
|
452
464
|
h === "text" ? a[a.length - 1] = {
|
|
@@ -455,91 +467,91 @@ class tt extends O {
|
|
|
455
467
|
...l.data,
|
|
456
468
|
parts: g?.parts
|
|
457
469
|
}
|
|
458
|
-
} : a[a.length - 1] = { ...l, data: { ...l.data, ...g ?? {} } }, this.messages.splice(-1, 1, { ...
|
|
470
|
+
} : a[a.length - 1] = { ...l, data: { ...l.data, ...g ?? {} } }, this.messages.splice(-1, 1, { ...r, blocks: a });
|
|
459
471
|
break;
|
|
460
472
|
}
|
|
461
473
|
case "block-end": {
|
|
462
|
-
if (
|
|
474
|
+
if (r?.role !== "assistant" || r?.id !== n)
|
|
463
475
|
break;
|
|
464
|
-
const a = [...
|
|
465
|
-
if (l?.type !==
|
|
476
|
+
const a = [...r.blocks ?? []], l = a[a.length - 1];
|
|
477
|
+
if (l?.type !== t.blockType || !l.isPending)
|
|
466
478
|
break;
|
|
467
479
|
const h = l;
|
|
468
|
-
a[a.length - 1] = { ...h, data: { ...h.data }, isPending: !1 }, this.messages.splice(-1, 1, { ...
|
|
480
|
+
a[a.length - 1] = { ...h, data: { ...h.data }, isPending: !1 }, this.messages.splice(-1, 1, { ...r, blocks: a });
|
|
469
481
|
break;
|
|
470
482
|
}
|
|
471
483
|
case "completed":
|
|
472
|
-
|
|
484
|
+
t.error ? (this.messages.push({
|
|
473
485
|
role: "assistant",
|
|
474
|
-
log:
|
|
475
|
-
error:
|
|
486
|
+
log: t.log,
|
|
487
|
+
error: t.error,
|
|
476
488
|
id: n,
|
|
477
489
|
interrupts: this._interruptDetails
|
|
478
|
-
}), this._interruptDetails = []) :
|
|
479
|
-
...
|
|
480
|
-
content:
|
|
481
|
-
blocks:
|
|
490
|
+
}), this._interruptDetails = []) : r?.role === "assistant" && r.id === n && this.messages.splice(-1, 1, {
|
|
491
|
+
...r,
|
|
492
|
+
content: t.response,
|
|
493
|
+
blocks: r.blocks?.map((a) => ({ ...a, data: { ...a.data }, isPending: !1 })) ?? [],
|
|
482
494
|
isStreaming: !1,
|
|
483
|
-
log:
|
|
484
|
-
}), this._isAnswering = !1, this.#
|
|
495
|
+
log: t.log
|
|
496
|
+
}), this._isAnswering = !1, this.#t = null, this._canceling = !1;
|
|
485
497
|
break;
|
|
486
498
|
case "interrupt":
|
|
487
|
-
this._interrupt = { ...
|
|
499
|
+
this._interrupt = { ...t.payload, id: n }, this.arcgisInterrupt.emit(this._interrupt);
|
|
488
500
|
break;
|
|
489
501
|
case "cancelled":
|
|
490
|
-
|
|
491
|
-
...
|
|
492
|
-
blocks:
|
|
502
|
+
r?.role === "assistant" && r.id === n ? this.messages.splice(-1, 1, {
|
|
503
|
+
...r,
|
|
504
|
+
blocks: r.blocks?.filter((a) => a.type === "text" || !a.isPending) ?? [],
|
|
493
505
|
isStreaming: !1,
|
|
494
|
-
log:
|
|
506
|
+
log: t.log,
|
|
495
507
|
error: `(${this._messages.stoppedByUserLabel})`
|
|
496
508
|
}) : (this.messages.push({
|
|
497
509
|
role: "assistant",
|
|
498
|
-
log:
|
|
510
|
+
log: t.log,
|
|
499
511
|
error: `(${this._messages.stoppedByUserLabel})`,
|
|
500
512
|
id: n,
|
|
501
513
|
interrupts: this._interruptDetails
|
|
502
|
-
}), this._interruptDetails = []), this._isAnswering = !1, this.#
|
|
514
|
+
}), this._interruptDetails = []), this._isAnswering = !1, this.#t = null, this._canceling = !1;
|
|
503
515
|
break;
|
|
504
516
|
}
|
|
505
517
|
}
|
|
506
518
|
}
|
|
507
|
-
submitInterrupt(
|
|
508
|
-
this.arcgisInterruptSubmit.emit(
|
|
519
|
+
submitInterrupt(e) {
|
|
520
|
+
this.arcgisInterruptSubmit.emit(e), this._interrupt && (this._interruptDetails = [...this._interruptDetails, { interrupt: this._interrupt, response: e }]), this.orchestrator?.resumeInterrupt(e), this._interrupt = null;
|
|
509
521
|
}
|
|
510
522
|
load() {
|
|
511
523
|
this.manager.onLifecycle(this._reset.bind(this));
|
|
512
524
|
}
|
|
513
525
|
loaded() {
|
|
514
526
|
this.manager.onLifecycle(() => {
|
|
515
|
-
this.#
|
|
516
|
-
const
|
|
517
|
-
const
|
|
518
|
-
|
|
519
|
-
}), s = this.messages.on("after-add", (
|
|
520
|
-
const
|
|
521
|
-
|
|
527
|
+
this.#e.value?.addEventListener("arcgisPromptSelect", this.#p), this.#e.value?.addEventListener("arcgisSubmit", this.#c), this.#e.value?.addEventListener("arcgisCancel", this.#h), this.#e.value?.addEventListener("arcgisFeedback", this.#g);
|
|
528
|
+
const e = D(() => !!this._interrupt && !!this.#s.value, () => {
|
|
529
|
+
const i = this.#s.value;
|
|
530
|
+
i.removeEventListener("arcgisSubmit", this.#n), i.removeEventListener("arcgisCancel", this.#a), i.addEventListener("arcgisSubmit", this.#n, { once: !0 }), i.addEventListener("arcgisCancel", this.#a, { once: !0 });
|
|
531
|
+
}), s = this.messages.on("after-add", (i) => {
|
|
532
|
+
const t = i.item;
|
|
533
|
+
t.role === "assistant" && (t.error || t.content) && this.arcgisResponse.emit(t);
|
|
522
534
|
});
|
|
523
535
|
return queueMicrotask(() => {
|
|
524
|
-
this.#o().then((
|
|
525
|
-
|
|
536
|
+
this.#o().then((i) => {
|
|
537
|
+
i ? this.arcgisReady.emit() : this._error && this.arcgisError.emit(new Error(this._error));
|
|
526
538
|
});
|
|
527
539
|
}), () => {
|
|
528
|
-
|
|
540
|
+
e.remove(), s.remove(), this.#e.value?.removeEventListener("arcgisPromptSelect", this.#p), this.#s.value?.removeEventListener("arcgisSubmit", this.#n), this.#s.value?.removeEventListener("arcgisCancel", this.#a), this.#e.value?.removeEventListener("arcgisSubmit", this.#c), this.#e.value?.removeEventListener("arcgisCancel", this.#h), this.#e.value?.removeEventListener("arcgisFeedback", this.#g), this._orchestratorController?.destroy(), this._orchestratorController = null;
|
|
529
541
|
};
|
|
530
542
|
});
|
|
531
543
|
}
|
|
532
544
|
_reset() {
|
|
533
|
-
this._orchestratorController?.cancel(), this.#
|
|
545
|
+
this._orchestratorController?.cancel(), this.#t?.abort(), this._interrupt = null, this.messages.removeAll(), this._error = null, this._inputValue = "", this._signedInUserId = void 0;
|
|
534
546
|
}
|
|
535
547
|
_renderEntryMessage() {
|
|
536
548
|
return this._isSignedIn ? this._error ? this._renderErrorNotice() : this.entryMessage ? this.messages.length > 0 ? null : c`<calcite-notice open kind=brand closable icon width=full><div slot=message>${this.entryMessage}</div></calcite-notice>` : c`<slot name=entry-message></slot>` : this._renderSignInNotice();
|
|
537
549
|
}
|
|
538
550
|
_renderSignInNotice() {
|
|
539
|
-
const
|
|
540
|
-
return c`<calcite-notice slot=entry-message open kind=brand icon width=full><div slot=message>${this._messages.signInRequiredMessage}</div>${
|
|
551
|
+
const e = this.#i;
|
|
552
|
+
return c`<calcite-notice slot=entry-message open kind=brand icon width=full><div slot=message>${this._messages.signInRequiredMessage}</div>${e ? c`<calcite-link slot=link @click=${async () => {
|
|
541
553
|
try {
|
|
542
|
-
const s = await N.getCredential(`${
|
|
554
|
+
const s = await N.getCredential(`${e.url}/sharing`);
|
|
543
555
|
this._signedInUserId = s.userId, this._error = null, this.requestUpdate(), await this.#o() ? this.arcgisReady.emit() : this._error && this.arcgisError.emit(new Error(this._error));
|
|
544
556
|
} catch (s) {
|
|
545
557
|
this._error = s?.message ?? this._messages.signInErrorMessage, this.arcgisError.emit(new Error(this._error)), B.log("error", this, "Error signing in:", { detail: { error: s } });
|
|
@@ -550,12 +562,12 @@ class tt extends O {
|
|
|
550
562
|
return this._error ? c`<calcite-notice slot=entry-message open kind=brand icon width=full>${this._error === Q ? c`<div slot=message>${X}</div><calcite-link slot=link .href=${Y} target=_blank title=${this._messages.learnAboutWebMapEmbeddingsLabel ?? f}>${this._messages.readMoreLabel}</calcite-link>` : c`<div slot=message>${this._error}</div>`}</calcite-notice>` : null;
|
|
551
563
|
}
|
|
552
564
|
render() {
|
|
553
|
-
return c`<calcite-panel .loading=${!this._orchestratorController && !this._error || this._orchestratorController?.loading} .heading=${this.heading ?? this._messages.assistantLabel} .description=${this.description} ${
|
|
565
|
+
return c`<calcite-panel .loading=${!this._orchestratorController && !this._error || this._orchestratorController?.loading} .heading=${this.heading ?? this._messages.assistantLabel} .description=${this.description} ${k(this.#e)}><slot name=header-actions-start slot=header-actions-start></slot><slot name=header-actions-end slot=header-actions-end></slot><div class="content-container"><arcgis-assistant-chat .loading=${this.awaitingResponse} .messages=${this.messages} .interrupt=${this._interrupt}><slot name=message-starter slot=message-starter></slot><slot name=messages slot=messages>${this.messages.map((e) => e.role === "assistant" ? c`<arcgis-assistant-message .message=${e} .feedbackEnabled=${this.feedbackEnabled} .logEnabled=${this.logEnabled} .copyEnabled=${this.copyEnabled} .readAloudEnabled=${this.readAloudEnabled} @arcgisSlottableRequest=${this.#d} .assistantAvatarEnabled=${this.assistantAvatarEnabled}>${e.blocks?.map((s, i) => c`<slot name=${$(e.id, i) ?? f} slot=${$(e.id, i) ?? f}><arcgis-assistant-message-block .block=${s}></arcgis-assistant-message-block></slot>`)}</arcgis-assistant-message>` : c`<arcgis-assistant-user-message .message=${e} .user=${this._user} .userAvatarEnabled=${this.userAvatarEnabled}></arcgis-assistant-user-message>`)}</slot>${this._interrupt ? c`<div slot=message-loading><div class="interrupt-waiting-message">${this._messages.waitingForUserInputMessage}</div></div>` : c`<slot name=message-loading slot=message-loading><arcgis-assistant-message-loading .loading=${this.awaitingResponse} .loadingMessage=${this.awaitingResponseStep} .assistantAvatarEnabled=${this.assistantAvatarEnabled} .interrupts=${this._interruptDetails}></arcgis-assistant-message-loading></slot>`}</arcgis-assistant-chat></div>${this._interrupt ? c`<slot name=interrupt><arcgis-assistant-interrupt slot=content-bottom .type=${this._interrupt.type} .message=${this._interrupt.message} .options=${this._interrupt.options} ${k(this.#s)}></arcgis-assistant-interrupt></slot>` : this.suggestedPrompts?.length ? c`<div class="suggested-prompts-container" slot=content-bottom><arcgis-assistant-suggested-prompts class="suggested-prompts" .prompts=${this.suggestedPrompts}></arcgis-assistant-suggested-prompts></div>` : null}<div class="footer-container" slot=footer>${this._renderEntryMessage()}<slot name=chat-entry><arcgis-assistant-chat-entry .awaitingResponse=${this.awaitingResponse || this._isAnswering} .inputValue=${this._inputValue} .messages=${this.messages} .voiceInputEnabled=${this.voiceInputEnabled} .disabled=${this._canceling || !this._isSignedIn || !!this._interrupt} ${k(this.#l)}><slot name=entry-actions-start slot=entry-actions-start></slot><slot name=entry-actions-end slot=entry-actions-end><calcite-button .iconStart=${this.awaitingResponse || this._isAnswering ? "circle-stop" : "send"} @click=${() => {
|
|
554
566
|
this.#l.value?.submitMessage();
|
|
555
567
|
}} round>${this.awaitingResponse || this._isAnswering ? this._messages.stopButtonLabel : this._messages.askButtonLabel}</calcite-button></slot></arcgis-assistant-chat-entry></slot><slot name=footer-content></slot></div></calcite-panel>`;
|
|
556
568
|
}
|
|
557
569
|
}
|
|
558
|
-
x("arcgis-assistant",
|
|
570
|
+
x("arcgis-assistant", ee);
|
|
559
571
|
export {
|
|
560
|
-
|
|
572
|
+
ee as ArcgisAssistant
|
|
561
573
|
};
|