@tylertech/forge-ai 0.7.0 → 0.7.2

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,4 +1,5 @@
1
- import { LitElement, TemplateResult } from 'lit';
1
+ import { LitElement, TemplateResult, PropertyValues } from 'lit';
2
+ import { FeedbackType } from '../ai-chatbot/types.js';
2
3
  declare global {
3
4
  interface HTMLElementTagNameMap {
4
5
  'forge-ai-actions-toolbar': AiActionsToolbarComponent;
@@ -26,12 +27,14 @@ export declare const AiActionsToolbarComponentTagName: keyof HTMLElementTagNameM
26
27
  export declare class AiActionsToolbarComponent extends LitElement {
27
28
  static styles: import('lit').CSSResult;
28
29
  enableReactions: boolean;
30
+ feedbackType?: FeedbackType;
29
31
  private _thumbsUpActive;
30
32
  private _thumbsDownActive;
31
33
  private _popoverOpen;
32
34
  private _thumbsDownButton;
33
35
  private _thumbsDownPopover;
34
36
  private _thumbsDownFeedbackTextarea?;
37
+ willUpdate(changedProperties: PropertyValues<this>): void;
35
38
  private _emitActionEvent;
36
39
  private _emitFeedbackEvent;
37
40
  private _handleThumbsUp;
@@ -23,6 +23,12 @@ let AiActionsToolbarComponent = class extends LitElement {
23
23
  this._thumbsDownActive = false;
24
24
  this._popoverOpen = false;
25
25
  }
26
+ willUpdate(changedProperties) {
27
+ if (changedProperties.has("feedbackType") && this.feedbackType) {
28
+ this._thumbsUpActive = this.feedbackType === "positive";
29
+ this._thumbsDownActive = this.feedbackType === "negative";
30
+ }
31
+ }
26
32
  _emitActionEvent(action) {
27
33
  const event = new CustomEvent("forge-ai-actions-toolbar-action", {
28
34
  detail: { action }
@@ -31,9 +37,7 @@ let AiActionsToolbarComponent = class extends LitElement {
31
37
  }
32
38
  _emitFeedbackEvent(action, feedback) {
33
39
  const event = new CustomEvent("forge-ai-actions-toolbar-feedback", {
34
- detail: { action, feedback },
35
- bubbles: true,
36
- composed: true
40
+ detail: { action, feedback }
37
41
  });
38
42
  this.dispatchEvent(event);
39
43
  }
@@ -177,6 +181,9 @@ AiActionsToolbarComponent.styles = unsafeCSS(styles);
177
181
  __decorateClass([
178
182
  property({ type: Boolean, attribute: "enable-reactions" })
179
183
  ], AiActionsToolbarComponent.prototype, "enableReactions", 2);
184
+ __decorateClass([
185
+ property({ attribute: "feedback-type" })
186
+ ], AiActionsToolbarComponent.prototype, "feedbackType", 2);
180
187
  __decorateClass([
181
188
  state()
182
189
  ], AiActionsToolbarComponent.prototype, "_thumbsUpActive", 2);
@@ -11,14 +11,14 @@ declare global {
11
11
  'forge-ai-assistant-response-refresh': CustomEvent<{
12
12
  responseId: string;
13
13
  }>;
14
- 'forge-ai-assistant-response-thumbs-up': CustomEvent<{
15
- responseId: string;
16
- }>;
17
- 'forge-ai-assistant-response-thumbs-down': CustomEvent<{
18
- responseId: string;
19
- }>;
14
+ 'forge-ai-assistant-response-thumbs-up': CustomEvent<ForgeAiAssistantResponseFeedbackEventData>;
15
+ 'forge-ai-assistant-response-thumbs-down': CustomEvent<ForgeAiAssistantResponseFeedbackEventData>;
20
16
  }
21
17
  }
18
+ export interface ForgeAiAssistantResponseFeedbackEventData {
19
+ responseId: string;
20
+ feedback?: string;
21
+ }
22
22
  export declare const AiAssistantResponseComponentTagName: keyof HTMLElementTagNameMap;
23
23
  /**
24
24
  * @tag forge-ai-assistant-response
@@ -27,8 +27,8 @@ export declare const AiAssistantResponseComponentTagName: keyof HTMLElementTagNa
27
27
  *
28
28
  * @event {CustomEvent<{ responseId: string }>} forge-ai-assistant-response-copy - Fired when copy action is clicked
29
29
  * @event {CustomEvent<{ responseId: string }>} forge-ai-assistant-response-refresh - Fired when refresh action is clicked
30
- * @event {CustomEvent<{ responseId: string }>} forge-ai-assistant-response-thumbs-up - Fired when thumbs up is clicked
31
- * @event {CustomEvent<{ responseId: string }>} forge-ai-assistant-response-thumbs-down - Fired when thumbs down is clicked
30
+ * @event {CustomEvent<ForgeAiAssistantResponseFeedbackEventData>} forge-ai-assistant-response-thumbs-up - Fired when thumbs up is clicked
31
+ * @event {CustomEvent<ForgeAiAssistantResponseFeedbackEventData>} forge-ai-assistant-response-thumbs-down - Fired when thumbs down is clicked
32
32
  */
33
33
  export declare class AiAssistantResponseComponent extends LitElement {
34
34
  #private;
@@ -1,6 +1,7 @@
1
1
  import { unsafeCSS, LitElement, html, nothing } from "lit";
2
2
  import { property, state, query, customElement } from "lit/decorators.js";
3
3
  import { unsafeHTML } from "lit/directives/unsafe-html.js";
4
+ import { ifDefined } from "lit/directives/if-defined.js";
4
5
  import { MarkdownStreamController } from "../ai-chatbot/markdown-stream-controller.mjs";
5
6
  import "../ai-actions-toolbar/ai-actions-toolbar.mjs";
6
7
  import "../ai-chatbot/ai-chatbot-tool-call.mjs";
@@ -26,7 +27,7 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
26
27
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
27
28
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
28
29
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
29
- var _internals, _markdownController, _debugIcon, _AiAssistantResponseComponent_instances, hasVisibleContent_get, updateEmptyState_fn, renderTextChunk_fn, renderToolCall_fn, children_get, handleToolbarAction_fn, handleDebugClick_fn, handleDebugPopoverToggle_fn, debugButton_get, debugPopover_get, toolbar_get;
30
+ var _internals, _markdownController, _debugIcon, _AiAssistantResponseComponent_instances, hasVisibleContent_get, updateEmptyState_fn, renderTextChunk_fn, renderToolCall_fn, children_get, handleToolbarAction_fn, handleToolbarFeedback_fn, handleDebugClick_fn, handleDebugPopoverToggle_fn, debugButton_get, debugPopover_get, toolbar_get;
30
31
  const AiAssistantResponseComponentTagName = "forge-ai-assistant-response";
31
32
  let AiAssistantResponseComponent = class extends LitElement {
32
33
  constructor() {
@@ -116,9 +117,15 @@ handleToolbarAction_fn = function(event) {
116
117
  const action = event.detail.action;
117
118
  const eventType = `forge-ai-assistant-response-${action}`;
118
119
  const bubbleEvent = new CustomEvent(eventType, {
119
- detail: { responseId: this.response.id },
120
- bubbles: true,
121
- composed: true
120
+ detail: { responseId: this.response.id }
121
+ });
122
+ this.dispatchEvent(bubbleEvent);
123
+ };
124
+ handleToolbarFeedback_fn = function(event) {
125
+ const { action, feedback } = event.detail;
126
+ const eventType = action === "positive" ? "forge-ai-assistant-response-thumbs-up" : "forge-ai-assistant-response-thumbs-down";
127
+ const bubbleEvent = new CustomEvent(eventType, {
128
+ detail: { responseId: this.response.id, feedback }
122
129
  });
123
130
  this.dispatchEvent(bubbleEvent);
124
131
  };
@@ -177,7 +184,9 @@ toolbar_get = function() {
177
184
  <div class="toolbar-container">
178
185
  <forge-ai-actions-toolbar
179
186
  ?enable-reactions=${this.enableReactions}
180
- @forge-ai-actions-toolbar-action=${__privateMethod(this, _AiAssistantResponseComponent_instances, handleToolbarAction_fn)}>
187
+ feedback-type=${ifDefined(this.response.feedback?.type)}
188
+ @forge-ai-actions-toolbar-action=${__privateMethod(this, _AiAssistantResponseComponent_instances, handleToolbarAction_fn)}
189
+ @forge-ai-actions-toolbar-feedback=${__privateMethod(this, _AiAssistantResponseComponent_instances, handleToolbarFeedback_fn)}>
181
190
  </forge-ai-actions-toolbar>
182
191
  ${__privateGet(this, _AiAssistantResponseComponent_instances, debugButton_get)}
183
192
  </div>
@@ -11,6 +11,8 @@ export declare class AgUiAdapter extends AgentAdapter {
11
11
  constructor(config: AgUiAdapterConfig, threadId?: string);
12
12
  get threadId(): string;
13
13
  set threadId(value: string);
14
+ setContext(context: Record<string, unknown>): void;
15
+ getContext(): Record<string, unknown>;
14
16
  static create(config: AgUiAdapterConfig & {
15
17
  threadId?: string;
16
18
  }): Promise<AgUiAdapter>;
@@ -2,14 +2,13 @@ import { HttpAgentWithCredentials } from "./http-agent-with-credentials.mjs";
2
2
  import { AgentAdapter } from "./agent-adapter.mjs";
3
3
  import { generateId } from "./utils.mjs";
4
4
  class AgUiAdapter extends AgentAdapter {
5
- #config;
6
5
  #agent;
7
6
  #toolCalls = /* @__PURE__ */ new Map();
8
7
  #threadId;
9
8
  #textBuffers = /* @__PURE__ */ new Map();
9
+ #context = {};
10
10
  constructor(config, threadId) {
11
11
  super();
12
- this.#config = config;
13
12
  this.#threadId = threadId ?? generateId();
14
13
  this.#agent = new HttpAgentWithCredentials({
15
14
  url: config.url,
@@ -19,6 +18,9 @@ class AgUiAdapter extends AgentAdapter {
19
18
  if (config.tools) {
20
19
  this.setTools(config.tools);
21
20
  }
21
+ if (config.context) {
22
+ this.#context = { ...config.context };
23
+ }
22
24
  this.#setupSubscriber();
23
25
  }
24
26
  get threadId() {
@@ -28,6 +30,12 @@ class AgUiAdapter extends AgentAdapter {
28
30
  this.#threadId = value;
29
31
  this.#agent.threadId = value;
30
32
  }
33
+ setContext(context) {
34
+ this.#context = { ...context };
35
+ }
36
+ getContext() {
37
+ return { ...this.#context };
38
+ }
31
39
  static async create(config) {
32
40
  const { threadId, ...adapterConfig } = config;
33
41
  const adapter = new AgUiAdapter(adapterConfig, threadId ?? generateId());
@@ -51,7 +59,7 @@ class AgUiAdapter extends AgentAdapter {
51
59
  throw new Error("Adapter not connected. Call connect() first.");
52
60
  }
53
61
  const transformedMessages = this.#transformMessages(messages);
54
- const context = this.#config.context ? this.#transformContext(this.#config.context) : void 0;
62
+ const context = Object.keys(this.#context).length ? this.#transformContext(this.#context) : void 0;
55
63
  this.#agent.setMessages(transformedMessages);
56
64
  const tools = this.#transformTools(this._tools);
57
65
  this.#agent.runAgent({ tools, context });
@@ -22,6 +22,7 @@ declare global {
22
22
  'forge-ai-chatbot-file-select': CustomEvent<ForgeAiChatbotFileSelectEventData>;
23
23
  'forge-ai-voice-input-result': CustomEvent<ForgeAiVoiceInputResultEvent>;
24
24
  'forge-ai-chatbot-file-remove': CustomEvent<ForgeAiChatbotFileRemoveEventData>;
25
+ 'forge-ai-chatbot-response-feedback': CustomEvent<ForgeAiChatbotResponseFeedbackEventData>;
25
26
  }
26
27
  }
27
28
  export interface ForgeAiChatbotMessageEventData {
@@ -38,6 +39,11 @@ export interface ForgeAiChatbotErrorEventData {
38
39
  export interface ForgeAiChatbotFileRemoveEventData {
39
40
  fileId: string;
40
41
  }
42
+ export interface ForgeAiChatbotResponseFeedbackEventData {
43
+ messageId: string;
44
+ type: 'positive' | 'negative';
45
+ feedback?: string;
46
+ }
41
47
  export declare const AiChatbotComponentTagName: keyof HTMLElementTagNameMap;
42
48
  /**
43
49
  * Type for feature toggle values
@@ -70,6 +76,7 @@ export type FeatureToggle = 'on' | 'off';
70
76
  * @event {CustomEvent<void>} forge-ai-chatbot-minimize - Fired when header minimize button is clicked
71
77
  * @event {CustomEvent<void>} forge-ai-chatbot-clear - Fired when header clear option is selected (cancelable, prevents clearMessages() if default prevented)
72
78
  * @event {CustomEvent<void>} forge-ai-chatbot-info - Fired when header info option is selected
79
+ * @event {CustomEvent<ForgeAiChatbotResponseFeedbackEventData>} forge-ai-chatbot-response-feedback - Fired when user provides feedback on a response (thumbs up/down)
73
80
  */
74
81
  export declare class AiChatbotComponent extends LitElement {
75
82
  #private;
@@ -506,10 +506,28 @@ handleRefresh_fn = function(evt) {
506
506
  this.adapter.sendMessage(this.getMessages());
507
507
  };
508
508
  handleThumbsUp_fn = function(evt) {
509
- console.warn("thumbs-up", evt.detail.messageId);
509
+ __privateGet(this, _messageStateController).setResponseFeedback(evt.detail.messageId, {
510
+ type: "positive",
511
+ reason: evt.detail.feedback
512
+ });
513
+ const detail = {
514
+ messageId: evt.detail.messageId,
515
+ type: "positive",
516
+ feedback: evt.detail.feedback
517
+ };
518
+ __privateMethod(this, _AiChatbotComponent_instances, dispatchEvent_fn).call(this, { type: "forge-ai-chatbot-response-feedback", detail });
510
519
  };
511
520
  handleThumbsDown_fn = function(evt) {
512
- console.warn("thumbs-down", evt.detail.messageId);
521
+ __privateGet(this, _messageStateController).setResponseFeedback(evt.detail.messageId, {
522
+ type: "negative",
523
+ reason: evt.detail.feedback
524
+ });
525
+ const detail = {
526
+ messageId: evt.detail.messageId,
527
+ type: "negative",
528
+ feedback: evt.detail.feedback
529
+ };
530
+ __privateMethod(this, _AiChatbotComponent_instances, dispatchEvent_fn).call(this, { type: "forge-ai-chatbot-response-feedback", detail });
513
531
  };
514
532
  processFileUpload_fn = function(file, timestamp) {
515
533
  const fileId = generateId();
@@ -585,6 +603,7 @@ handleAttachmentRemove_fn = function(evt) {
585
603
  }
586
604
  };
587
605
  handleSuggestionSelect_fn = async function(evt) {
606
+ __privateGet(this, _promptRef).value?.addToHistory(evt.detail.text);
588
607
  await this.sendMessage(evt.detail.text);
589
608
  __privateGet(this, _promptRef).value?.focus();
590
609
  };
@@ -1,4 +1,4 @@
1
- const styles = '/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/* prettier-ignore */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n:host {\n display: block;\n width: 100%;\n height: 100%;\n}\n\nforge-ai-chat-interface::part(messages) {\n overflow: hidden;\n}\nforge-ai-chat-interface forge-ai-message-thread {\n min-height: 0;\n}\n\n.session-files {\n display: flex;\n flex-direction: column;\n gap: var(--forge-spacing-xsmall, 8px);\n min-width: 0;\n}\n.session-files .session-files-header {\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-family: var(--forge-typography-label1-font-family, var(--forge-typography-font-family, "Roboto", sans-serif));\n font-size: var(--forge-typography-label1-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-font-size-scale, 0.75)));\n font-weight: var(--forge-typography-label1-font-weight, 400);\n line-height: var(--forge-typography-label1-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-line-height-scale, 1.25)));\n letter-spacing: var(--forge-typography-label1-letter-spacing, 0.0357142857em);\n text-transform: var(--forge-typography-label1-text-transform, inherit);\n text-decoration: var(--forge-typography-label1-text-decoration, inherit);\n color: var(--forge-theme-text-medium, rgba(0, 0, 0, 0.6));\n}\n.session-files .session-files-list::-webkit-scrollbar {\n height: var(--forge-scrollbar-height, 16px);\n width: var(--forge-scrollbar-width, 16px);\n}\n.session-files .session-files-list::-webkit-scrollbar-track {\n background-color: var(--forge-scrollbar-track-container, var(--forge-theme-surface-container-low, #ebebeb));\n}\n.session-files .session-files-list::-webkit-scrollbar-track:hover {\n background-color: var(--forge-scrollbar-track-container-hover, var(--forge-theme-surface-container-low, #ebebeb));\n}\n.session-files .session-files-list::-webkit-scrollbar-corner {\n background-color: var(--forge-scrollbar-track-container, var(--forge-theme-surface-container-low, #ebebeb));\n}\n.session-files .session-files-list::-webkit-scrollbar-thumb {\n height: var(--forge-scrollbar-thumb-min-height, 32px);\n width: var(--forge-scrollbar-thumb-min-width, 32px);\n border-radius: var(--forge-scrollbar-border-radius, calc(var(--forge-shape-full, 9999px) * var(--forge-shape-factor, 1)));\n border-width: var(--forge-scrollbar-border-width, 3px);\n border-style: solid;\n border-color: transparent;\n background-color: var(--forge-scrollbar-thumb-container, var(--forge-theme-surface-container-medium, #c2c2c2));\n background-clip: content-box;\n}\n.session-files .session-files-list::-webkit-scrollbar-thumb:hover {\n background-color: var(--forge-scrollbar-thumb-container-hover, var(--forge-theme-surface-container-high, #9e9e9e));\n}\n.session-files .session-files-list {\n display: flex;\n gap: var(--forge-spacing-small, 12px);\n overflow-x: auto;\n padding-block-end: var(--forge-spacing-xsmall, 8px);\n}\n\n.disclaimer {\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-family: var(--forge-typography-label1-font-family, var(--forge-typography-font-family, "Roboto", sans-serif));\n font-size: var(--forge-typography-label1-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-font-size-scale, 0.75)));\n font-weight: var(--forge-typography-label1-font-weight, 400);\n line-height: var(--forge-typography-label1-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-line-height-scale, 1.25)));\n letter-spacing: var(--forge-typography-label1-letter-spacing, 0.0357142857em);\n text-transform: var(--forge-typography-label1-text-transform, inherit);\n text-decoration: var(--forge-typography-label1-text-decoration, inherit);\n color: var(--forge-theme-text-medium, rgba(0, 0, 0, 0.6));\n text-align: center;\n margin-block-start: var(--forge-spacing-xxsmall, 4px);\n}';
1
+ const styles = '/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/* prettier-ignore */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n:host {\n display: block;\n width: 100%;\n height: 100%;\n}\n\nforge-ai-chat-interface::part(messages) {\n overflow: hidden;\n}\nforge-ai-chat-interface forge-ai-message-thread {\n min-height: 0;\n}\n\n.session-files {\n display: flex;\n flex-direction: column;\n gap: var(--forge-spacing-xsmall, 8px);\n min-width: 0;\n}\n.session-files .session-files-header {\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-family: var(--forge-typography-label1-font-family, var(--forge-typography-font-family, "Roboto", sans-serif));\n font-size: var(--forge-typography-label1-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-font-size-scale, 0.75)));\n font-weight: var(--forge-typography-label1-font-weight, 400);\n line-height: var(--forge-typography-label1-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-line-height-scale, 1.25)));\n letter-spacing: var(--forge-typography-label1-letter-spacing, 0.0357142857em);\n text-transform: var(--forge-typography-label1-text-transform, inherit);\n text-decoration: var(--forge-typography-label1-text-decoration, inherit);\n color: var(--forge-theme-text-medium, rgba(0, 0, 0, 0.6));\n}\n.session-files .session-files-list::-webkit-scrollbar {\n height: var(--forge-scrollbar-height, 16px);\n width: var(--forge-scrollbar-width, 16px);\n}\n.session-files .session-files-list::-webkit-scrollbar-track {\n background-color: var(--forge-scrollbar-track-container, var(--forge-theme-surface-container-low, #ebebeb));\n}\n.session-files .session-files-list::-webkit-scrollbar-track:hover {\n background-color: var(--forge-scrollbar-track-container-hover, var(--forge-theme-surface-container-low, #ebebeb));\n}\n.session-files .session-files-list::-webkit-scrollbar-corner {\n background-color: var(--forge-scrollbar-track-container, var(--forge-theme-surface-container-low, #ebebeb));\n}\n.session-files .session-files-list::-webkit-scrollbar-thumb {\n height: var(--forge-scrollbar-thumb-min-height, 32px);\n width: var(--forge-scrollbar-thumb-min-width, 32px);\n border-radius: var(--forge-scrollbar-border-radius, calc(var(--forge-shape-full, 9999px) * var(--forge-shape-factor, 1)));\n border-width: var(--forge-scrollbar-border-width, 3px);\n border-style: solid;\n border-color: transparent;\n background-color: var(--forge-scrollbar-thumb-container, var(--forge-theme-surface-container-medium, #c2c2c2));\n background-clip: content-box;\n}\n.session-files .session-files-list::-webkit-scrollbar-thumb:hover {\n background-color: var(--forge-scrollbar-thumb-container-hover, var(--forge-theme-surface-container-high, #9e9e9e));\n}\n.session-files .session-files-list {\n display: flex;\n gap: var(--forge-spacing-small, 12px);\n overflow-x: auto;\n padding-block-end: var(--forge-spacing-xsmall, 8px);\n}\n\n.disclaimer {\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-family: var(--forge-typography-label1-font-family, var(--forge-typography-font-family, "Roboto", sans-serif));\n font-size: var(--forge-typography-label1-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-font-size-scale, 0.75)));\n font-weight: var(--forge-typography-label1-font-weight, 400);\n line-height: var(--forge-typography-label1-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-label-line-height-scale, 1.25)));\n letter-spacing: var(--forge-typography-label1-letter-spacing, 0.0357142857em);\n text-transform: var(--forge-typography-label1-text-transform, inherit);\n text-decoration: var(--forge-typography-label1-text-decoration, inherit);\n color: var(--forge-theme-text-medium, rgba(0, 0, 0, 0.6));\n text-align: center;\n margin-block-start: var(--forge-spacing-xxsmall, 4px);\n margin-block-end: calc(var(--forge-spacing-small, 12px) * -1);\n}';
2
2
  export {
3
3
  styles as default
4
4
  };
@@ -1,9 +1,9 @@
1
1
  export { AiChatbotComponent, AiChatbotComponentTagName } from './ai-chatbot.js';
2
- export type { ForgeAiChatbotMessageEventData, ForgeAiChatbotToolCallEventData, ForgeAiChatbotErrorEventData, FeatureToggle } from './ai-chatbot.js';
2
+ export type { ForgeAiChatbotMessageEventData, ForgeAiChatbotToolCallEventData, ForgeAiChatbotErrorEventData, ForgeAiChatbotResponseFeedbackEventData, FeatureToggle } from './ai-chatbot.js';
3
3
  export { AiChatbotToolCallComponent, AiChatbotToolCallComponentTagName } from './ai-chatbot-tool-call.js';
4
4
  export type { Suggestion } from '../ai-suggestions/index.js';
5
5
  export { AgentAdapter, type MessageStartEvent, type MessageDeltaEvent, type MessageEndEvent, type ToolCallEvent, type ToolCallStartEvent, type ToolCallArgsEvent, type ToolCallEndEvent, type FileUploadEvent, type FileRemoveEvent, type AdapterState, type ErrorEvent, type CustomAgentEvent, type RawAgentEvent, type RunStartedAgentEvent, type StepStartedAgentEvent, type StepFinishedAgentEvent, type StateSnapshotAgentEvent, type StateDeltaAgentEvent, type ActivitySnapshotAgentEvent, type ActivityDeltaAgentEvent } from './agent-adapter.js';
6
- export type { ChatMessage, ToolDefinition, ToolCall, ToolRenderer, IToolRenderer, HandlerContext, FileAttachment, UploadedFileMetadata, FileUploadCallbacks, FileUploadHandler, FileRemoveCallbacks, ForgeAiChatbotFileSelectEventData, ThreadState } from './types.js';
6
+ export type { ChatMessage, ToolDefinition, ToolCall, ToolRenderer, IToolRenderer, HandlerContext, FileAttachment, UploadedFileMetadata, FileUploadCallbacks, FileUploadHandler, FileRemoveCallbacks, ForgeAiChatbotFileSelectEventData, ThreadState, FeedbackType, ResponseFeedback } from './types.js';
7
7
  export * from './ag-ui-adapter.js';
8
8
  export * from './http-agent-with-credentials.js';
9
9
  export * from './event-emitter.js';
@@ -1,5 +1,5 @@
1
1
  import { ReactiveController, ReactiveControllerHost } from 'lit';
2
- import { ChatMessage, MessageItem, ToolCall, ToolDefinition, AssistantResponse } from './types.js';
2
+ import { ChatMessage, MessageItem, ToolCall, ToolDefinition, AssistantResponse, ResponseFeedback } from './types.js';
3
3
  import { MessageStartEvent, MessageDeltaEvent, MessageEndEvent, ToolCallStartEvent, ToolCallArgsEvent, ToolCallEndEvent, ToolResultEvent } from './agent-adapter.js';
4
4
  export interface MessageStateControllerConfig {
5
5
  tools: Map<string, ToolDefinition>;
@@ -51,4 +51,5 @@ export declare class MessageStateController implements ReactiveController {
51
51
  */
52
52
  getMessages(): ChatMessage[];
53
53
  setMessages(messages: ChatMessage[]): void;
54
+ setResponseFeedback(responseId: string, feedback: ResponseFeedback): void;
54
55
  }
@@ -298,7 +298,8 @@ class MessageStateController {
298
298
  timestamp: response.timestamp,
299
299
  status: response.status === "streaming" ? "streaming" : response.status === "error" ? "error" : "complete",
300
300
  toolCalls: toolCalls.length ? toolCalls : void 0,
301
- eventStream: response.eventStream
301
+ eventStream: response.eventStream,
302
+ feedback: response.feedback
302
303
  };
303
304
  messages.push(message);
304
305
  } else if (item.type === "toolCall") {
@@ -331,7 +332,8 @@ class MessageStateController {
331
332
  children,
332
333
  status: msg.status === "streaming" ? "streaming" : msg.status === "error" ? "error" : "complete",
333
334
  timestamp: msg.timestamp,
334
- eventStream: msg.eventStream
335
+ eventStream: msg.eventStream,
336
+ feedback: msg.feedback
335
337
  };
336
338
  messageItems.push({ type: "assistant", data: response });
337
339
  } else {
@@ -341,6 +343,13 @@ class MessageStateController {
341
343
  this._messageItems = messageItems;
342
344
  this.#notifyStateChange();
343
345
  }
346
+ setResponseFeedback(responseId, feedback) {
347
+ const item = this._messageItems.find((i) => i.type === "assistant" && i.data.id === responseId);
348
+ if (item?.type === "assistant") {
349
+ item.data.feedback = feedback;
350
+ this.#notifyStateChange();
351
+ }
352
+ }
344
353
  #appendEventToMessage(id, event) {
345
354
  const messageExists = this._messageItems.some((item) => item.type === "message" && item.data.id === id);
346
355
  if (!messageExists) {
@@ -138,6 +138,7 @@ export interface ChatMessage {
138
138
  toolCalls?: ToolCall[];
139
139
  toolCallId?: string;
140
140
  eventStream?: StreamEvent[];
141
+ feedback?: ResponseFeedback;
141
142
  }
142
143
  export interface ToolCall<TArgs = Record<string, unknown>> {
143
144
  id: string;
@@ -159,12 +160,18 @@ export type ResponseItem = {
159
160
  type: 'toolCall';
160
161
  data: ToolCall;
161
162
  };
163
+ export type FeedbackType = 'positive' | 'negative';
164
+ export interface ResponseFeedback {
165
+ type: FeedbackType;
166
+ reason?: string;
167
+ }
162
168
  export interface AssistantResponse {
163
169
  id: string;
164
170
  children: ResponseItem[];
165
171
  status: 'streaming' | 'complete' | 'error';
166
172
  timestamp: number;
167
173
  eventStream?: StreamEvent[];
174
+ feedback?: ResponseFeedback;
168
175
  }
169
176
  export interface FileAttachment {
170
177
  id: string;
@@ -20,6 +20,7 @@ export interface ForgeAiMessageThreadRefreshEventData {
20
20
  }
21
21
  export interface ForgeAiMessageThreadThumbsEventData {
22
22
  messageId: string;
23
+ feedback?: string;
23
24
  }
24
25
  export declare const AiMessageThreadComponentTagName: keyof HTMLElementTagNameMap;
25
26
  /**
@@ -95,17 +95,13 @@ handleRefresh_fn = function(messageId) {
95
95
  detail: { messageId }
96
96
  });
97
97
  };
98
- handleThumbsUp_fn = function(messageId) {
99
- __privateMethod(this, _AiMessageThreadComponent_instances, dispatchEvent_fn).call(this, {
100
- type: "forge-ai-message-thread-thumbs-up",
101
- detail: { messageId }
102
- });
98
+ handleThumbsUp_fn = function(messageId, feedback) {
99
+ const detail = { messageId, feedback };
100
+ __privateMethod(this, _AiMessageThreadComponent_instances, dispatchEvent_fn).call(this, { type: "forge-ai-message-thread-thumbs-up", detail });
103
101
  };
104
- handleThumbsDown_fn = function(messageId) {
105
- __privateMethod(this, _AiMessageThreadComponent_instances, dispatchEvent_fn).call(this, {
106
- type: "forge-ai-message-thread-thumbs-down",
107
- detail: { messageId }
108
- });
102
+ handleThumbsDown_fn = function(messageId, feedback) {
103
+ const detail = { messageId, feedback };
104
+ __privateMethod(this, _AiMessageThreadComponent_instances, dispatchEvent_fn).call(this, { type: "forge-ai-message-thread-thumbs-down", detail });
109
105
  };
110
106
  renderToolCall_fn = function(toolCall) {
111
107
  const toolDefinition = this.tools?.get(toolCall.name);
@@ -123,8 +119,8 @@ renderAssistantResponse_fn = function(response) {
123
119
  ?debug-mode=${this.debugMode}
124
120
  @forge-ai-assistant-response-copy=${(e) => __privateMethod(this, _AiMessageThreadComponent_instances, handleCopy_fn).call(this, e.detail.responseId)}
125
121
  @forge-ai-assistant-response-refresh=${(e) => __privateMethod(this, _AiMessageThreadComponent_instances, handleRefresh_fn).call(this, e.detail.responseId)}
126
- @forge-ai-assistant-response-thumbs-up=${(e) => __privateMethod(this, _AiMessageThreadComponent_instances, handleThumbsUp_fn).call(this, e.detail.responseId)}
127
- @forge-ai-assistant-response-thumbs-down=${(e) => __privateMethod(this, _AiMessageThreadComponent_instances, handleThumbsDown_fn).call(this, e.detail.responseId)}>
122
+ @forge-ai-assistant-response-thumbs-up=${(e) => __privateMethod(this, _AiMessageThreadComponent_instances, handleThumbsUp_fn).call(this, e.detail.responseId, e.detail.feedback)}
123
+ @forge-ai-assistant-response-thumbs-down=${(e) => __privateMethod(this, _AiMessageThreadComponent_instances, handleThumbsDown_fn).call(this, e.detail.responseId, e.detail.feedback)}>
128
124
  </forge-ai-assistant-response>
129
125
  `;
130
126
  };
@@ -73,6 +73,11 @@ export declare class AiPromptComponent extends LitElement {
73
73
  constructor();
74
74
  willUpdate(changedProperties: PropertyValues<this>): void;
75
75
  firstUpdated(): void;
76
+ /**
77
+ * Adds a message to the input history for up/down arrow navigation.
78
+ * Use this when sending messages externally (e.g., from suggestions).
79
+ */
80
+ addToHistory(message: string): void;
76
81
  private _handleSend;
77
82
  private _handleInput;
78
83
  private _handleKeyDown;
@@ -22,7 +22,16 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
22
22
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
23
23
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
24
24
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
25
- var _internals, _AiPromptComponent_instances, setCssState_fn, _actionsSlot, shouldShowStopButton_get, conditionalActions_get, handleSlotChange_fn, handleSlashCommandSelect_fn, handleSlashCommandClose_fn, slashCommandMenu_get;
25
+ var __privateWrapper = (obj, member, setter, getter) => ({
26
+ set _(value) {
27
+ __privateSet(obj, member, value);
28
+ },
29
+ get _() {
30
+ return __privateGet(obj, member, getter);
31
+ }
32
+ });
33
+ var _internals, _messageHistory, _historyIndex, _draftMessage, _AiPromptComponent_instances, setCssState_fn, resetHistoryNavigation_fn, navigateHistory_fn, _actionsSlot, shouldShowStopButton_get, conditionalActions_get, handleSlotChange_fn, handleSlashCommandSelect_fn, handleSlashCommandClose_fn, slashCommandMenu_get;
34
+ const MAX_HISTORY_SIZE = 50;
26
35
  const AiPromptComponentTagName = "forge-ai-prompt";
27
36
  let AiPromptComponent = class extends LitElement {
28
37
  constructor() {
@@ -41,6 +50,9 @@ let AiPromptComponent = class extends LitElement {
41
50
  this._slashMenuOpen = false;
42
51
  this._slashMenuQuery = "";
43
52
  __privateAdd(this, _internals);
53
+ __privateAdd(this, _messageHistory, []);
54
+ __privateAdd(this, _historyIndex, -1);
55
+ __privateAdd(this, _draftMessage, "");
44
56
  __privateAdd(this, _actionsSlot, html`<slot name="actions" @slotchange=${__privateMethod(this, _AiPromptComponent_instances, handleSlotChange_fn)}></slot>`);
45
57
  __privateSet(this, _internals, this.attachInternals());
46
58
  __privateMethod(this, _AiPromptComponent_instances, setCssState_fn).call(this);
@@ -55,14 +67,34 @@ let AiPromptComponent = class extends LitElement {
55
67
  this.focus();
56
68
  }
57
69
  }
70
+ /**
71
+ * Adds a message to the input history for up/down arrow navigation.
72
+ * Use this when sending messages externally (e.g., from suggestions).
73
+ */
74
+ addToHistory(message) {
75
+ const trimmed = message?.trim();
76
+ if (!trimmed) {
77
+ return;
78
+ }
79
+ if (__privateGet(this, _messageHistory)[__privateGet(this, _messageHistory).length - 1] === trimmed) {
80
+ __privateMethod(this, _AiPromptComponent_instances, resetHistoryNavigation_fn).call(this);
81
+ return;
82
+ }
83
+ __privateGet(this, _messageHistory).push(trimmed);
84
+ if (__privateGet(this, _messageHistory).length > MAX_HISTORY_SIZE) {
85
+ __privateGet(this, _messageHistory).shift();
86
+ }
87
+ __privateMethod(this, _AiPromptComponent_instances, resetHistoryNavigation_fn).call(this);
88
+ }
58
89
  _handleSend() {
59
90
  if (this.sendDisabled || this.inputDisabled || !this.value.trim()) {
60
91
  return;
61
92
  }
93
+ const messageValue = this.value;
62
94
  const now = /* @__PURE__ */ new Date();
63
95
  const event = new CustomEvent("forge-ai-prompt-send", {
64
96
  detail: {
65
- value: this.value,
97
+ value: messageValue,
66
98
  time: now.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }),
67
99
  date: now
68
100
  },
@@ -72,6 +104,7 @@ let AiPromptComponent = class extends LitElement {
72
104
  });
73
105
  this.dispatchEvent(event);
74
106
  if (!event.defaultPrevented) {
107
+ this.addToHistory(messageValue);
75
108
  this.value = "";
76
109
  this._slashMenuOpen = false;
77
110
  this._slashMenuQuery = "";
@@ -79,6 +112,10 @@ let AiPromptComponent = class extends LitElement {
79
112
  }
80
113
  _handleInput(event) {
81
114
  this.value = event.target.value;
115
+ if (__privateGet(this, _historyIndex) !== -1) {
116
+ __privateSet(this, _draftMessage, this.value);
117
+ __privateSet(this, _historyIndex, -1);
118
+ }
82
119
  if (this.slashCommands.length === 0) {
83
120
  this.dispatchEvent(new Event("input", { bubbles: true, composed: true }));
84
121
  return;
@@ -101,6 +138,20 @@ let AiPromptComponent = class extends LitElement {
101
138
  return;
102
139
  }
103
140
  }
141
+ const hasModifier = event.shiftKey || event.ctrlKey || event.metaKey;
142
+ if (!hasModifier) {
143
+ if (event.key === "ArrowUp") {
144
+ if (__privateMethod(this, _AiPromptComponent_instances, navigateHistory_fn).call(this, -1)) {
145
+ event.preventDefault();
146
+ return;
147
+ }
148
+ } else if (event.key === "ArrowDown") {
149
+ if (__privateMethod(this, _AiPromptComponent_instances, navigateHistory_fn).call(this, 1)) {
150
+ event.preventDefault();
151
+ return;
152
+ }
153
+ }
154
+ }
104
155
  if (event.key === "Enter" && !event.shiftKey) {
105
156
  if (event.isComposing) {
106
157
  return;
@@ -222,11 +273,52 @@ let AiPromptComponent = class extends LitElement {
222
273
  }
223
274
  };
224
275
  _internals = /* @__PURE__ */ new WeakMap();
276
+ _messageHistory = /* @__PURE__ */ new WeakMap();
277
+ _historyIndex = /* @__PURE__ */ new WeakMap();
278
+ _draftMessage = /* @__PURE__ */ new WeakMap();
225
279
  _AiPromptComponent_instances = /* @__PURE__ */ new WeakSet();
226
280
  setCssState_fn = function() {
227
281
  toggleState(__privateGet(this, _internals), "inline", this.variant === "inline");
228
282
  toggleState(__privateGet(this, _internals), "stacked", this.variant === "stacked");
229
283
  };
284
+ resetHistoryNavigation_fn = function() {
285
+ __privateSet(this, _historyIndex, -1);
286
+ __privateSet(this, _draftMessage, "");
287
+ };
288
+ navigateHistory_fn = function(direction) {
289
+ if (__privateGet(this, _messageHistory).length === 0) {
290
+ return false;
291
+ }
292
+ if (direction > 0 && __privateGet(this, _historyIndex) === -1) {
293
+ return false;
294
+ }
295
+ if (direction < 0) {
296
+ if (__privateGet(this, _historyIndex) === -1) {
297
+ __privateSet(this, _draftMessage, this.value);
298
+ __privateSet(this, _historyIndex, __privateGet(this, _messageHistory).length - 1);
299
+ } else if (__privateGet(this, _historyIndex) > 0) {
300
+ __privateWrapper(this, _historyIndex)._--;
301
+ } else {
302
+ return false;
303
+ }
304
+ } else {
305
+ const newIndex = __privateGet(this, _historyIndex) + 1;
306
+ if (newIndex >= __privateGet(this, _messageHistory).length) {
307
+ __privateSet(this, _historyIndex, -1);
308
+ this.value = __privateGet(this, _draftMessage);
309
+ if (this._inputElement) {
310
+ this._inputElement.value = __privateGet(this, _draftMessage);
311
+ }
312
+ return true;
313
+ }
314
+ __privateSet(this, _historyIndex, newIndex);
315
+ }
316
+ this.value = __privateGet(this, _messageHistory)[__privateGet(this, _historyIndex)];
317
+ if (this._inputElement) {
318
+ this._inputElement.value = __privateGet(this, _messageHistory)[__privateGet(this, _historyIndex)];
319
+ }
320
+ return true;
321
+ };
230
322
  _actionsSlot = /* @__PURE__ */ new WeakMap();
231
323
  shouldShowStopButton_get = function() {
232
324
  return this.running && !this.value.trim();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tylertech/forge-ai",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "A library of Tyler Forge™ AI chat interface web components.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Tyler Technologies, Inc.",