@arcgis/ai-components 5.2.0-next.114 → 5.2.0-next.115

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.
Files changed (71) hide show
  1. package/dist/agent-utils/types.d.ts +13 -3
  2. package/dist/cdn/{HXEAVHLM.js → 23CPLCYW.js} +1 -1
  3. package/dist/cdn/{64IWQ7A4.js → 2NODROJN.js} +1 -1
  4. package/dist/cdn/{6P44KOKX.js → 4WYNWR6R.js} +1 -1
  5. package/dist/cdn/{6OOZSZRJ.js → 5QXGQW2N.js} +1 -1
  6. package/dist/cdn/{TGYRNH5D.js → 6KSMVYBS.js} +1 -1
  7. package/dist/cdn/{H5DD7DRB.js → 6XZYQ74A.js} +1 -1
  8. package/dist/cdn/{TAWMLPK2.js → 6YRLY5TX.js} +1 -1
  9. package/dist/cdn/{WSWB3B7B.js → 7ELUGB4X.js} +1 -1
  10. package/dist/cdn/{QXOOEBIR.js → BJNYJCS5.js} +1 -1
  11. package/dist/cdn/{Q5WITJ3L.js → BKAXFQIS.js} +1 -1
  12. package/dist/cdn/{JO7U7E24.js → BN7CIVBD.js} +1 -1
  13. package/dist/cdn/{V6HOUZPZ.js → C7P6MHMZ.js} +1 -1
  14. package/dist/cdn/{PMILRLSD.js → CESQ3SFP.js} +1 -1
  15. package/dist/cdn/{L3K457Y6.js → CLTV27HJ.js} +1 -1
  16. package/dist/cdn/{F5NIRETW.js → CSTXLFCP.js} +1 -1
  17. package/dist/cdn/{HHQTKKYE.js → CVAVY7R2.js} +1 -1
  18. package/dist/cdn/{AKOLZ4JN.js → CZIAU7PC.js} +1 -1
  19. package/dist/cdn/{J3D2JL4H.js → DEPD7PJL.js} +1 -1
  20. package/dist/cdn/{C2RSZ3VK.js → H4N7VNL5.js} +1 -1
  21. package/dist/cdn/{XOULSLM7.js → HAHL6K4X.js} +1 -1
  22. package/dist/cdn/{H4BVWDNV.js → HFHRMM6Q.js} +1 -1
  23. package/dist/cdn/{TAMMDFVT.js → HSILCMAR.js} +1 -1
  24. package/dist/cdn/{4XTSGMV7.js → ITCZC2VY.js} +1 -1
  25. package/dist/cdn/{U7SYNCYR.js → JTEY4E7E.js} +1 -1
  26. package/dist/cdn/{3UEKINYC.js → JTKVVKZK.js} +1 -1
  27. package/dist/cdn/{O4NVW75A.js → K5FWDMTV.js} +1 -1
  28. package/dist/cdn/{EYOWRGDP.js → KPJHQ424.js} +1 -1
  29. package/dist/cdn/{MXTXJKFE.js → KQGC2FCP.js} +1 -1
  30. package/dist/cdn/{YYDZAPJP.js → LDIUJUI7.js} +1 -1
  31. package/dist/cdn/NR2O3AP2.js +2 -0
  32. package/dist/cdn/NWJQ7KTC.js +2 -0
  33. package/dist/cdn/{YR7EYQ4X.js → PGVLC374.js} +1 -1
  34. package/dist/cdn/{SXM4NUT5.js → PQRE67OM.js} +1 -1
  35. package/dist/cdn/QZL4SAYR.js +6 -0
  36. package/dist/cdn/{2642ADON.js → SLD4ZVT6.js} +1 -1
  37. package/dist/cdn/{Y5O6VNSQ.js → UZ6OAU3F.js} +2 -2
  38. package/dist/cdn/{RMLCWLJC.js → VBEZDXBV.js} +1 -1
  39. package/dist/cdn/VJRJ2HAM.js +3 -0
  40. package/dist/cdn/{UDRKUVZP.js → VYOIFJVE.js} +1 -1
  41. package/dist/cdn/{ZGQ27DU2.js → XUYARLRP.js} +1 -1
  42. package/dist/cdn/{CLRFKSAT.js → ZA2WIUWH.js} +1 -1
  43. package/dist/cdn/{LUYP76B7.js → ZCFYGCCV.js} +1 -1
  44. package/dist/cdn/{Y27GVWWU.js → ZGZX7GR5.js} +1 -1
  45. package/dist/cdn/agent-utils/index.js +1 -1
  46. package/dist/cdn/assets/assistant/t9n/messages.en.json +1 -1
  47. package/dist/cdn/assets/assistant-chat-entry/t9n/messages.en.json +1 -1
  48. package/dist/cdn/index.js +1 -1
  49. package/dist/chunks/baseAgentState.js +7 -6
  50. package/dist/chunks/orchestrator.js +9 -6
  51. package/dist/components/arcgis-assistant/customElement.d.ts +23 -3
  52. package/dist/components/arcgis-assistant/customElement.js +213 -187
  53. package/dist/components/arcgis-assistant/types.d.ts +108 -0
  54. package/dist/components/arcgis-assistant-chat-entry/customElement.d.ts +15 -4
  55. package/dist/components/arcgis-assistant-chat-entry/customElement.js +344 -45
  56. package/dist/components/arcgis-assistant-chat-entry/index.js +3 -0
  57. package/dist/docs/api.json +1 -1
  58. package/dist/docs/docs.json +1 -1
  59. package/dist/docs/vscode.html-custom-data.json +1 -1
  60. package/dist/docs/web-types.json +1 -1
  61. package/dist/loader.js +2 -2
  62. package/dist/types/lumina.d.ts +2 -2
  63. package/dist/types/preact.d.ts +2 -2
  64. package/dist/types/react.d.ts +2 -2
  65. package/dist/types/stencil.d.ts +2 -2
  66. package/dist/utils/index.d.ts +20 -0
  67. package/package.json +5 -5
  68. package/dist/cdn/2O4DON37.js +0 -2
  69. package/dist/cdn/AXY6RA5N.js +0 -3
  70. package/dist/cdn/FS7GXTTQ.js +0 -6
  71. package/dist/cdn/RLEHNAIA.js +0 -2
@@ -98,6 +98,112 @@ export type AssistantPromptSelectDetail = {
98
98
  prompt: string;
99
99
  };
100
100
 
101
+ /**
102
+ * A command selected in an assistant submission.
103
+ * A submission can contain at most one command.
104
+ *
105
+ * @internal
106
+ */
107
+ export type AssistantCommandInputPart = Readonly<{
108
+ kind: "command";
109
+ id: string;
110
+ label: string;
111
+ agentId?: string;
112
+ requiresText?: boolean;
113
+ data?: unknown;
114
+ }>;
115
+
116
+ /**
117
+ * A selectable command returned by an assistant command provider.
118
+ *
119
+ * @internal
120
+ */
121
+ export type AssistantCommandSuggestion = Readonly<{
122
+ id: string;
123
+ label: string;
124
+ description?: string;
125
+ agentId?: string;
126
+ requiresText?: boolean;
127
+ data?: unknown;
128
+ }>;
129
+
130
+ /**
131
+ * Provides suggestions for the reserved `/` command trigger in the assistant chat entry.
132
+ *
133
+ * @internal
134
+ */
135
+ export type AssistantCommandProvider = Readonly<{ getSuggestions: (query: string, signal: AbortSignal) => Promise<readonly AssistantCommandSuggestion[]> | readonly AssistantCommandSuggestion[]; }>;
136
+
137
+ /**
138
+ * An entity selected in an assistant submission.
139
+ *
140
+ * @internal
141
+ */
142
+ export type AssistantEntityInputPart = Readonly<{
143
+ kind: "entity";
144
+ providerId: string;
145
+ trigger: string;
146
+ id: string;
147
+ label: string;
148
+ data?: unknown;
149
+ }>;
150
+
151
+ /**
152
+ * A selectable entity returned by an assistant entity provider.
153
+ *
154
+ * @internal
155
+ */
156
+ export type AssistantEntitySuggestion = Readonly<{
157
+ id: string;
158
+ label: string;
159
+ description?: string;
160
+ data?: unknown;
161
+ }>;
162
+
163
+ /**
164
+ * Provides entity suggestions for a trigger in the assistant chat entry.
165
+ * The `/` trigger is reserved for commands.
166
+ * Selected entities remain in the submitted prompt and do not affect agent routing.
167
+ *
168
+ * @internal
169
+ */
170
+ export type AssistantEntityProvider = Readonly<{
171
+ id: string;
172
+ trigger: string;
173
+ getSuggestions: (query: string, signal: AbortSignal) => Promise<readonly AssistantEntitySuggestion[]> | readonly AssistantEntitySuggestion[];
174
+ }>;
175
+
176
+ /**
177
+ * Structured input submitted with an assistant request.
178
+ *
179
+ * @internal
180
+ */
181
+ export type AssistantInputPart = AssistantCommandInputPart | AssistantEntityInputPart;
182
+
183
+ /**
184
+ * Options for submitting an assistant message.
185
+ * Requests with parts but no message text require a command with an `agentId` or an explicitly selected agent through
186
+ * `alwaysUseAgentId`.
187
+ * Parts are scoped to this request; they are not persisted in message history.
188
+ *
189
+ * @internal
190
+ */
191
+ export type SubmitMessageOptions = Readonly<{
192
+ parts?: readonly AssistantInputPart[];
193
+ displayText?: string;
194
+ }>;
195
+
196
+ /**
197
+ * A snapshot of an assistant submission, separating execution text from display text.
198
+ *
199
+ * @internal
200
+ */
201
+ export type AssistantSubmission = Readonly<{
202
+ prompt: string;
203
+ displayText: string;
204
+ parts: readonly AssistantInputPart[];
205
+ }>;
206
+
101
207
  /** Detail payload emitted by the assistant slottable request event. */
102
208
  export type AssistantSlottableRequestDetail = {
103
209
  /** The request name describing the slot being requested. */
@@ -125,6 +231,8 @@ export interface UserMessage extends ChatMessageBase {
125
231
  * This content is sent to the assistant and its agents for processing and generating responses.
126
232
  */
127
233
  content: string;
234
+ /** Structured input parts submitted with the message. */
235
+ parts?: readonly AssistantInputPart[];
128
236
  }
129
237
 
130
238
  /** Feedback provided by the user for a specific message. */
@@ -1,7 +1,7 @@
1
1
  /// <reference path="../../index.d.ts" />
2
2
  import type Collection from "@arcgis/core/core/Collection.js";
3
3
  import type { PublicLitElement as LitElement } from "@arcgis/lumina";
4
- import type { ChatMessage } from "../arcgis-assistant/types.js";
4
+ import type { AssistantCommandProvider, AssistantEntityProvider, AssistantSubmission, ChatMessage } from "../arcgis-assistant/types.js";
5
5
  import type { T9nMeta } from "@arcgis/lumina/controllers";
6
6
 
7
7
  /**
@@ -13,13 +13,24 @@ import type { T9nMeta } from "@arcgis/lumina/controllers";
13
13
  */
14
14
  export abstract class ArcgisAssistantChatEntry extends LitElement {
15
15
  /** @internal */
16
- protected _messages: { entryPlaceholder: string; } & T9nMeta<{ entryPlaceholder: string; }>;
16
+ protected _messages: {
17
+ entryPlaceholder: string;
18
+ loadingSuggestions: string;
19
+ textRequired: string;
20
+ suggestions: string;
21
+ } & T9nMeta<{
22
+ entryPlaceholder: string;
23
+ loadingSuggestions: string;
24
+ textRequired: string;
25
+ suggestions: string;
26
+ }>;
17
27
  /** @default false */
18
28
  accessor awaitingResponse: boolean;
29
+ accessor commandProvider: AssistantCommandProvider | undefined;
19
30
  /** @default false */
20
31
  accessor disabled: boolean;
32
+ accessor entityProviders: readonly AssistantEntityProvider[];
21
33
  accessor entryPlaceholder: string | undefined;
22
- /** @default "" */
23
34
  accessor inputValue: string;
24
35
  /** @default false */
25
36
  accessor keyboardShortcutsDisabled: boolean;
@@ -29,7 +40,7 @@ export abstract class ArcgisAssistantChatEntry extends LitElement {
29
40
  accessor voiceInputEnabled: boolean;
30
41
  submitMessage(): Promise<void>;
31
42
  readonly arcgisCancel: import("@arcgis/lumina").TargetedEvent<this, void>;
32
- readonly arcgisSubmit: import("@arcgis/lumina").TargetedEvent<this, string>;
43
+ readonly arcgisSubmit: import("@arcgis/lumina").TargetedEvent<this, AssistantSubmission | string>;
33
44
  readonly "@eventTypes": {
34
45
  arcgisCancel: ArcgisAssistantChatEntry["arcgisCancel"]["detail"];
35
46
  arcgisSubmit: ArcgisAssistantChatEntry["arcgisSubmit"]["detail"];
@@ -1,71 +1,366 @@
1
1
  /* COPYRIGHT Esri - https://js.arcgis.com/5.2/LICENSE.txt */
2
- import { c as d } from "../../chunks/runtime.js";
3
- import { css as p, html as c } from "lit";
4
- import { LitElement as f, createEvent as l, safeClassMap as g } from "@arcgis/lumina";
5
- import { createRef as u, ref as h } from "lit/directives/ref.js";
6
- import { u as m } from "../../chunks/useT9n.js";
7
- import y from "@arcgis/core/core/Collection.js";
8
- import { classes as v } from "@arcgis/toolkit/dom";
9
- const b = p`:host{--calcite-text-area-border-color: var(--calcite-color-border-1);--calcite-text-area-divider-color: var(--calcite-color-border-1);--calcite-text-area-corner-radius: var(--calcite-border-radius)}.input-container{display:flex;flex-direction:column}.footer-start{display:flex;gap:var(--calcite-spacing-md);flex-wrap:wrap;align-items:center}.footer-end{display:flex;gap:var(--calcite-spacing-md);align-items:center}.status-indicator{width:9px;height:9px;border-radius:100%;background-color:var(--calcite-color-status-success)}.status-indicator[data-status=working]{background-color:var(--calcite-color-status-warning)}.status-indicator[data-status=error]{background-color:var(--calcite-color-status-danger)}.status-text{text-transform:capitalize}.focused{--calcite-text-area-shadow: var(--calcite-shadow-sm)}`;
10
- class w extends f {
2
+ import { c as b } from "../../chunks/runtime.js";
3
+ import { css as S, html as g } from "lit";
4
+ import { LitElement as w, createEvent as f, safeClassMap as _ } from "@arcgis/lumina";
5
+ import { createRef as m, ref as v } from "lit/directives/ref.js";
6
+ import { u as $ } from "../../chunks/useT9n.js";
7
+ import I from "@arcgis/core/core/Collection.js";
8
+ const k = S`:host{--calcite-text-area-border-color: var(--calcite-color-border-1);--calcite-text-area-divider-color: var(--calcite-color-border-1);--calcite-text-area-corner-radius: var(--calcite-border-radius)}.input-container{display:flex;flex-direction:column}.footer-start{display:flex;gap:var(--calcite-spacing-md);flex-wrap:wrap;align-items:center}.footer-end{display:flex;gap:var(--calcite-spacing-md);align-items:center}.focused{--calcite-text-area-shadow: var(--calcite-shadow-sm)}.suggestions-loading{padding:var(--calcite-spacing-sm)}`, q = {
9
+ suggestions: [],
10
+ loading: !1,
11
+ selectedIndex: 0
12
+ };
13
+ function y(d) {
14
+ return d.filter(({ trigger: t }) => t !== "" && t !== "/").sort((t, e) => e.trigger.length - t.trigger.length);
15
+ }
16
+ class P {
17
+ constructor(t) {
18
+ this._onStateChange = t;
19
+ }
20
+ #t = null;
21
+ #o;
22
+ #e = q;
23
+ get state() {
24
+ return this.#e;
25
+ }
26
+ get activeSuggestion() {
27
+ return this.#o;
28
+ }
29
+ get selectedSuggestion() {
30
+ return this.#e.suggestions[this.#e.selectedIndex];
31
+ }
32
+ moveSelection(t) {
33
+ this.#r({
34
+ selectedIndex: Math.max(0, Math.min(this.#e.selectedIndex + t, this.#e.suggestions.length - 1))
35
+ });
36
+ }
37
+ async update(t, e, i) {
38
+ this.#t?.abort();
39
+ const s = this.#i(t, e, i);
40
+ if (!s) {
41
+ this.close();
42
+ return;
43
+ }
44
+ const n = new AbortController();
45
+ this.#t = n, this.#o = s, this.#r({ suggestions: [], loading: !0, selectedIndex: 0 });
46
+ try {
47
+ const o = await s.provider.getSuggestions(
48
+ s.query,
49
+ n.signal
50
+ );
51
+ if (n.signal.aborted || this.#t !== n)
52
+ return;
53
+ this.#r({
54
+ suggestions: o,
55
+ loading: !1,
56
+ selectedIndex: 0
57
+ });
58
+ } catch {
59
+ n.signal.aborted || this.close();
60
+ }
61
+ }
62
+ async resolveTypedInputs(t, e, i, s) {
63
+ const n = await this.#s(t, e.commandProvider, i, s);
64
+ return s.aborted ? [] : (n.push(...await this.#a(t, e.entityProviders, i, s)), n);
65
+ }
66
+ close() {
67
+ this.#t?.abort(), this.#t = null, this.#o = void 0, this.#r({ suggestions: [], loading: !1, selectedIndex: 0 });
68
+ }
69
+ #i(t, e, i) {
70
+ if (e == null)
71
+ return;
72
+ const s = t.slice(0, e), n = s.slice(1);
73
+ if (i.commandProvider && s.startsWith("/") && !/\s/u.test(n))
74
+ return { kind: "command", provider: i.commandProvider, start: 0, end: e, query: n };
75
+ const o = y(i.entityProviders);
76
+ for (const r of o) {
77
+ const l = s.lastIndexOf(r.trigger), a = s.slice(l + r.trigger.length);
78
+ if (l !== -1 && r.trigger && !/\s/u.test(a) && (l === 0 || /\s/u.test(s[l - 1] ?? "")))
79
+ return { kind: "entity", provider: r, start: l, end: e, query: a };
80
+ }
81
+ }
82
+ async #s(t, e, i, s) {
83
+ const n = /^\/([^\s]+)/u.exec(t);
84
+ if (!n || !e)
85
+ return [];
86
+ const [o, r] = n;
87
+ if (i.some((c) => c.start === 0 && c.end === o.length))
88
+ return [];
89
+ const l = await e.getSuggestions(r, s);
90
+ if (s.aborted)
91
+ return [];
92
+ const a = l.find((c) => c.id === r);
93
+ return a ? [
94
+ {
95
+ start: 0,
96
+ end: o.length,
97
+ part: {
98
+ kind: "command",
99
+ id: a.id,
100
+ label: a.label,
101
+ agentId: a.agentId,
102
+ requiresText: a.requiresText || void 0,
103
+ data: a.data
104
+ }
105
+ }
106
+ ] : [];
107
+ }
108
+ async #a(t, e, i, s) {
109
+ const n = y(e), o = [];
110
+ for (const r of t.matchAll(/(?:^|\s)(\S+)/gu)) {
111
+ const l = r[1], a = n.find((u) => l.startsWith(u.trigger));
112
+ if (!a)
113
+ continue;
114
+ const c = r.index + r[0].length - l.length;
115
+ if (i.some((u) => u.start === c && u.end === c + l.length))
116
+ continue;
117
+ const h = l.slice(a.trigger.length);
118
+ if (!h)
119
+ continue;
120
+ const x = await a.getSuggestions(h, s);
121
+ if (s.aborted)
122
+ return [];
123
+ const p = x.find((u) => u.id === h);
124
+ p && o.push({
125
+ start: c,
126
+ end: c + l.length,
127
+ part: {
128
+ kind: "entity",
129
+ providerId: a.id,
130
+ trigger: a.trigger,
131
+ id: p.id,
132
+ label: p.label,
133
+ data: p.data
134
+ }
135
+ });
136
+ }
137
+ return o;
138
+ }
139
+ #r(t) {
140
+ this.#e = { ...this.#e, ...t }, this._onStateChange(this.#e);
141
+ }
142
+ }
143
+ function C(d, t, e, i) {
144
+ if (d === t && !i)
145
+ return [...e];
146
+ let s = 0;
147
+ const n = Math.min(d.length, t.length, i?.start ?? d.length);
148
+ for (; s < n && d[s] === t[s]; )
149
+ s += 1;
150
+ let o = d.length, r = t.length;
151
+ const l = Math.max(s, i?.end ?? s);
152
+ for (; o > l && r > s && d[o - 1] === t[r - 1]; )
153
+ o -= 1, r -= 1;
154
+ const a = r - o;
155
+ return e.flatMap((c) => {
156
+ const h = c.end <= s ? c : c.start >= o ? { ...c, start: c.start + a, end: c.end + a } : void 0;
157
+ return h && (h.part.kind !== "command" || h.start === 0) && (h.start === 0 || /\s/u.test(t[h.start - 1])) && (h.end === t.length || /\s/u.test(t[h.end])) ? [h] : [];
158
+ });
159
+ }
160
+ function R(d, t) {
161
+ for (const e of [...t].reverse())
162
+ e.part.kind === "command" && (d = d.slice(0, e.start) + d.slice(e.end).replace(/^[\t ]+/u, ""));
163
+ return d.trim();
164
+ }
165
+ function D(d, t) {
166
+ let e = 0;
167
+ return t.flatMap((i) => {
168
+ const s = i.kind === "command" ? `/${i.id}` : `${i.trigger}${i.id}`, n = d.indexOf(s, e);
169
+ return n === -1 ? [] : (e = n + s.length, [{ start: n, end: e, part: i }]);
170
+ });
171
+ }
172
+ class E extends w {
11
173
  constructor() {
12
- super(...arguments), this.#s = u(), this.#i = u(), this.#t = -1, this.#e = "", this.#a = (t) => {
174
+ super(...arguments), this.#t = m(), this.#o = m(), this.#i = new P((t) => this._suggestionState = t), this.#s = [], this.#a = "", this.#r = "", this.#h = () => {
175
+ const t = this.#t.value?.shadowRoot?.querySelector("textarea");
176
+ this.#l = t ? { start: t.selectionStart, end: t.selectionEnd } : void 0;
177
+ }, this.#d = (t) => {
13
178
  t.stopPropagation();
14
- const s = t.detail;
15
- this._setDraftValue(s.value), s.focusInput && this.#s.value && this.#s.value.setFocus();
16
- }, this.#r = (t) => {
17
- const s = t.target.value ?? "";
18
- this.inputValue = s, this.#e = s;
19
- }, this._messages = m({ blocking: !0 }), this._inFocus = !1, this.keyboardShortcutsDisabled = !1, this.awaitingResponse = !1, this.inputValue = "", this.voiceInputEnabled = !1, this.messages = new y([]), this.disabled = !1, this.arcgisCancel = l(), this.arcgisSubmit = l();
179
+ const e = t.detail;
180
+ this._setDraftValue(e.value), e.focusInput && this.#t.value && this.#t.value.setFocus();
181
+ }, this.#u = (t) => {
182
+ const e = t.target.value ?? "", i = this.#l;
183
+ this.#l = void 0, this.#c(e, i), this.inputValue = e;
184
+ const s = this.#t.value?.shadowRoot?.querySelector("textarea")?.selectionStart;
185
+ this.#i.update(e, s, {
186
+ commandProvider: this.commandProvider,
187
+ entityProviders: this.entityProviders ?? []
188
+ });
189
+ }, this.#g = async (t) => {
190
+ if (!(t.altKey || t.ctrlKey || t.metaKey || t.shiftKey || this.keyboardShortcutsDisabled)) {
191
+ if (this._suggestionState.suggestions.length > 0) {
192
+ if (t.key === "ArrowDown") {
193
+ t.preventDefault(), this.#i.moveSelection(1);
194
+ return;
195
+ }
196
+ if (t.key === "ArrowUp") {
197
+ t.preventDefault(), this.#i.moveSelection(-1);
198
+ return;
199
+ }
200
+ if (t.key === "Enter") {
201
+ t.preventDefault(), await this.#v(this.#i.selectedSuggestion);
202
+ return;
203
+ }
204
+ if (t.key === "Escape") {
205
+ t.preventDefault(), this.#i.close();
206
+ return;
207
+ }
208
+ }
209
+ switch (t.key) {
210
+ case "Enter":
211
+ t.preventDefault(), await this.submitMessage();
212
+ break;
213
+ case "ArrowUp":
214
+ await this._navigateHistory("up", t);
215
+ break;
216
+ case "ArrowDown":
217
+ await this._navigateHistory("down", t);
218
+ break;
219
+ }
220
+ }
221
+ }, this._messages = $({ blocking: !0 }), this._inFocus = !1, this._suggestionState = this.#i.state, this._textRequired = !1, this.keyboardShortcutsDisabled = !1, this.awaitingResponse = !1, this.voiceInputEnabled = !1, this.messages = new I([]), this.disabled = !1, this.entityProviders = [], this.arcgisCancel = f(), this.arcgisSubmit = f({ cancelable: !0 });
20
222
  }
21
223
  static {
22
- this.properties = { _inFocus: 16, _userMessages: 16, keyboardShortcutsDisabled: 5, entryPlaceholder: 1, awaitingResponse: 5, inputValue: 1, status: 1, voiceInputEnabled: 5, messages: 0, disabled: 5 };
224
+ this.properties = { _inFocus: 16, _suggestionState: 16, _textRequired: 16, keyboardShortcutsDisabled: 5, entryPlaceholder: 1, awaitingResponse: 5, inputValue: 1, status: 1, voiceInputEnabled: 5, messages: 0, disabled: 5, commandProvider: 0, entityProviders: 0 };
23
225
  }
24
226
  static {
25
- this.styles = b;
227
+ this.styles = k;
26
228
  }
27
- #s;
28
- #i;
29
229
  #t;
230
+ #o;
30
231
  #e;
232
+ #i;
233
+ #s;
31
234
  #a;
32
235
  #r;
33
- get _userMessages() {
34
- return this.messages.toArray().filter((t) => t.role === "user").map(({ content: t }) => t);
236
+ #n;
237
+ #l;
238
+ #h;
239
+ #d;
240
+ #u;
241
+ #g;
242
+ get inputValue() {
243
+ return this.#r;
244
+ }
245
+ set inputValue(t) {
246
+ t !== this.#r && (this.#r = t, this.#n?.abort(), this.#n = void 0);
35
247
  }
36
248
  async submitMessage() {
37
249
  if (this.awaitingResponse) {
38
- this.arcgisCancel.emit();
250
+ this.#n?.abort(), this.#n = void 0, this.arcgisCancel.emit();
39
251
  return;
40
252
  }
41
- const t = this.inputValue.trim();
42
- t && (this.arcgisSubmit.emit(t), this.inputValue = "", this.#t = -1, this.#e = "", this.#i.value?.clearDraftSession(), this.#s.value && await this.#s.value.setFocus());
253
+ const t = this.inputValue;
254
+ this.#c(t), this.#n?.abort();
255
+ const e = new AbortController();
256
+ this.#n = e;
257
+ let i;
258
+ try {
259
+ if (i = await this.#i.resolveTypedInputs(t, {
260
+ commandProvider: this.commandProvider,
261
+ entityProviders: this.entityProviders ?? []
262
+ }, this.#s, e.signal), e.signal.aborted || this.#n !== e)
263
+ return;
264
+ } catch (r) {
265
+ if (e.signal.aborted)
266
+ return;
267
+ throw r;
268
+ } finally {
269
+ this.#n === e && (this.#n = void 0);
270
+ }
271
+ this.#s.push(...i.filter((r) => !this.#s.some((l) => l.start === r.start && l.end === r.end)));
272
+ const s = R(t, this.#s);
273
+ if (this._textRequired = !s && this.#s.some((r) => r.part.kind === "command" && (r.part.requiresText ?? !1)), this._textRequired) {
274
+ await this.#t.value?.setFocus();
275
+ return;
276
+ }
277
+ const n = this.#p();
278
+ if (!s && n.length === 0)
279
+ return;
280
+ const o = {
281
+ prompt: s,
282
+ displayText: t.trim(),
283
+ parts: n
284
+ };
285
+ this.arcgisSubmit.emit(o.parts.length ? o : s).defaultPrevented || (this.inputValue = "", this.#s = [], this.#a = "", this.#e = void 0, this.#i.close(), this.#o.value?.clearDraftSession(), this.#t.value && await this.#t.value.setFocus());
43
286
  }
44
287
  loaded() {
45
- this.manager.onLifecycle(() => (this.el.addEventListener("arcgisVoiceInputDraftChange", this.#a), {
288
+ this.manager.onLifecycle(() => (this.el.addEventListener("arcgisVoiceInputDraftChange", this.#d), {
46
289
  remove: () => {
47
- this.el.removeEventListener("arcgisVoiceInputDraftChange", this.#a);
290
+ this.el.removeEventListener("arcgisVoiceInputDraftChange", this.#d);
48
291
  }
49
292
  }));
50
293
  }
51
- async _navigateHistory(t, s) {
52
- const a = this.#s.value;
53
- if (!a)
294
+ async _navigateHistory(t, e) {
295
+ const i = this.#t.value;
296
+ if (!i)
54
297
  return;
55
- const e = this._userMessages;
56
- if (e.length === 0)
298
+ const s = this.messages.toArray().filter((c) => c.role === "user");
299
+ if (s.length === 0)
300
+ return;
301
+ const n = i.value ?? "", o = i.shadowRoot?.querySelector("textarea"), r = o?.selectionStart, l = o?.selectionEnd;
302
+ if (r == null || l == null || r !== l || t === "up" && r !== 0 || t === "down" && r !== n.length)
303
+ return;
304
+ if (t === "up") {
305
+ this.#e ? this.#e.index = Math.max(0, this.#e.index - 1) : this.#e = {
306
+ index: s.length - 1,
307
+ draft: this.#y()
308
+ }, this.#f(s[this.#e.index]), e.preventDefault();
57
309
  return;
58
- const r = a.value ?? "", o = a.shadowRoot?.querySelector("textarea"), i = o?.selectionStart, n = o?.selectionEnd;
59
- if (!(i == null || n == null) && !(i !== n || t === "up" && i !== 0 || t === "down" && i !== r.length)) {
60
- if (t === "up") {
61
- this.#t === -1 ? (this.#e = r, this.#t = e.length - 1) : this.#t = Math.max(0, this.#t - 1), this.inputValue = e[this.#t] ?? "", s.preventDefault();
62
- return;
63
- }
64
- this.#t !== -1 && (this.#t < e.length - 1 ? (this.#t += 1, this.inputValue = e[this.#t] ?? "") : (this.#t = -1, this.inputValue = this.#e), s.preventDefault());
65
310
  }
311
+ const a = this.#e;
312
+ a && (a.index < s.length - 1 ? (a.index += 1, this.#f(s[a.index])) : (this.#e = void 0, this.#m(a.draft)), e.preventDefault());
313
+ }
314
+ #y() {
315
+ return this.#c(this.inputValue), {
316
+ value: this.inputValue,
317
+ parts: this.#p()
318
+ };
319
+ }
320
+ #p() {
321
+ return this.#s.map((t) => t.part);
322
+ }
323
+ #f(t) {
324
+ const e = t.parts ?? [];
325
+ this.#m({ value: t.content, parts: e });
326
+ }
327
+ #m(t) {
328
+ this.inputValue = t.value, this.#a = t.value, this.#s = D(t.value, t.parts), this.#l = void 0, this._textRequired = !1, this.#i.close();
66
329
  }
67
330
  _setDraftValue(t) {
68
- this.inputValue = t, this.#t = -1, this.#e = t;
331
+ this.#i.close(), this.#s = [], this.#a = t, this.#l = void 0, this._textRequired = !1, this.inputValue = t, this.#e = void 0;
332
+ }
333
+ #c(t, e) {
334
+ this._textRequired = !1, this.#s = C(this.#a, t, this.#s, e), this.#a = t;
335
+ }
336
+ async #v(t) {
337
+ const e = this.#i.activeSuggestion;
338
+ if (!t || !e)
339
+ return;
340
+ const s = `${e.kind === "command" ? "/" : e.provider.trigger}${t.id}`, n = `${this.inputValue.slice(0, e.start)}${s} ${this.inputValue.slice(e.end)}`;
341
+ this.#c(n), this.#s.push({
342
+ start: e.start,
343
+ end: e.start + s.length,
344
+ part: e.kind === "command" ? {
345
+ kind: "command",
346
+ id: t.id,
347
+ label: t.label,
348
+ agentId: "agentId" in t ? t.agentId : void 0,
349
+ requiresText: "requiresText" in t && t.requiresText || void 0,
350
+ data: t.data
351
+ } : {
352
+ kind: "entity",
353
+ providerId: e.provider.id,
354
+ trigger: e.provider.trigger,
355
+ id: t.id,
356
+ label: t.label,
357
+ data: t.data
358
+ }
359
+ }), this.#s.sort((l, a) => l.start - a.start), this.inputValue = n, this.#e = void 0;
360
+ const o = e.start + s.length + 1;
361
+ this.#i.close(), await this.updateComplete, await this.#t.value?.setFocus();
362
+ const r = this.#t.value?.shadowRoot?.querySelector("textarea");
363
+ r && (r.selectionStart = o, r.selectionEnd = o);
69
364
  }
70
365
  _onFocusIn() {
71
366
  this._inFocus = !0;
@@ -73,13 +368,17 @@ class w extends f {
73
368
  _onFocusOut() {
74
369
  this._inFocus = !1;
75
370
  }
371
+ #x(t) {
372
+ return t ? g`<calcite-popover .open=${this._suggestionState.suggestions.length > 0 || this._suggestionState.loading} placement=top-start .label=${this._messages.suggestions} .referenceElement=${t} trigger-disabled pointer-disabled focus-trap-disabled><calcite-list .label=${this._messages.suggestions} selection-appearance=highlight selection-mode=single-persist .loading=${this._suggestionState.loading}>${this._suggestionState.loading ? null : this._suggestionState.suggestions.map((e, i) => g`<calcite-list-item .label=${e.label} .description=${e.description} .selected=${i === this._suggestionState.selectedIndex} @click=${() => {
373
+ this.#v(e);
374
+ }}></calcite-list-item>`)}</calcite-list>${this._suggestionState.loading ? g`<div class="suggestions-loading" role=status>${this._messages.loadingSuggestions}</div>` : null}</calcite-popover>` : null;
375
+ }
76
376
  render() {
77
- return c`<div class="input-container"><calcite-text-area class=${g(v({ focused: this._inFocus }))} .value=${this.inputValue} .placeholder=${this.entryPlaceholder ?? this._messages.entryPlaceholder} resize=vertical @calciteTextAreaInput=${this.#r} .disabled=${this.disabled} @keydown=${async (t) => {
78
- t.altKey || t.ctrlKey || t.metaKey || t.shiftKey || this.keyboardShortcutsDisabled || (t.key === "Enter" ? (t.preventDefault(), await this.submitMessage()) : t.key === "ArrowUp" ? await this._navigateHistory("up", t) : t.key === "ArrowDown" && await this._navigateHistory("down", t));
79
- }} @focusin=${this._onFocusIn} @focusout=${this._onFocusOut} ${h(this.#s)}><div slot=footer-start class="footer-start"><slot name=entry-actions-start></slot></div><div slot=footer-end class="footer-end">${this.voiceInputEnabled ? c`<arcgis-assistant-speech-input .awaitingResponse=${this.awaitingResponse} .inputValue=${this.inputValue} ${h(this.#i)}></arcgis-assistant-speech-input>` : null}<slot name=entry-actions-end></slot></div></calcite-text-area></div>`;
377
+ const t = this.#t.value;
378
+ return g`<div class="input-container">${this._textRequired ? g`<div role=alert>${this._messages.textRequired}</div>` : null}<calcite-text-area class=${_({ focused: this._inFocus })} .value=${this.inputValue} .placeholder=${this.entryPlaceholder ?? this._messages.entryPlaceholder} resize=vertical @calciteTextAreaInput=${this.#u} @beforeinput=${this.#h} .status=${this._textRequired ? "invalid" : "idle"} .disabled=${this.disabled} @keydown=${this.#g} @focusin=${this._onFocusIn} @focusout=${this._onFocusOut} ${v(this.#t)}><div slot=footer-start class="footer-start"><slot name=entry-actions-start></slot></div><div slot=footer-end class="footer-end">${this.voiceInputEnabled ? g`<arcgis-assistant-speech-input .awaitingResponse=${this.awaitingResponse} .inputValue=${this.inputValue} ${v(this.#o)}></arcgis-assistant-speech-input>` : null}<slot name=entry-actions-end></slot></div></calcite-text-area>${this.#x(t)}</div>`;
80
379
  }
81
380
  }
82
- d("arcgis-assistant-chat-entry", w);
381
+ b("arcgis-assistant-chat-entry", E);
83
382
  export {
84
- w as ArcgisAssistantChatEntry
383
+ E as ArcgisAssistantChatEntry
85
384
  };
@@ -1,3 +1,6 @@
1
+ import "@esri/calcite-components/components/calcite-popover";
2
+ import "@esri/calcite-components/components/calcite-list";
3
+ import "@esri/calcite-components/components/calcite-list-item";
1
4
  import "@esri/calcite-components/components/calcite-text-area";
2
5
  import "../arcgis-assistant-speech-input/index.js";
3
6
  export * from "./customElement.js";