@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.
- package/custom-elements.json +814 -704
- package/dist/ai-actions-toolbar/ai-actions-toolbar.d.ts +4 -1
- package/dist/ai-actions-toolbar/ai-actions-toolbar.mjs +10 -3
- package/dist/ai-assistant-response/ai-assistant-response.d.ts +8 -8
- package/dist/ai-assistant-response/ai-assistant-response.mjs +14 -5
- package/dist/ai-chatbot/ag-ui-adapter.d.ts +2 -0
- package/dist/ai-chatbot/ag-ui-adapter.mjs +11 -3
- package/dist/ai-chatbot/ai-chatbot.d.ts +7 -0
- package/dist/ai-chatbot/ai-chatbot.mjs +21 -2
- package/dist/ai-chatbot/ai-chatbot.scss.mjs +1 -1
- package/dist/ai-chatbot/index.d.ts +2 -2
- package/dist/ai-chatbot/message-state-controller.d.ts +2 -1
- package/dist/ai-chatbot/message-state-controller.mjs +11 -2
- package/dist/ai-chatbot/types.d.ts +7 -0
- package/dist/ai-message-thread/ai-message-thread.d.ts +1 -0
- package/dist/ai-message-thread/ai-message-thread.mjs +8 -12
- package/dist/ai-prompt/ai-prompt.d.ts +5 -0
- package/dist/ai-prompt/ai-prompt.mjs +94 -2
- package/package.json +1 -1
|
@@ -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
|
-
|
|
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<
|
|
31
|
-
* @event {CustomEvent<
|
|
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
|
-
|
|
121
|
-
|
|
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
|
-
|
|
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.#
|
|
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
|
-
|
|
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
|
-
|
|
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;
|
|
@@ -95,17 +95,13 @@ handleRefresh_fn = function(messageId) {
|
|
|
95
95
|
detail: { messageId }
|
|
96
96
|
});
|
|
97
97
|
};
|
|
98
|
-
handleThumbsUp_fn = function(messageId) {
|
|
99
|
-
|
|
100
|
-
|
|
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
|
-
|
|
106
|
-
|
|
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
|
|
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:
|
|
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();
|