@visma-swno/gaia-chat-ui 5.0.1 → 5.2.0
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/CHANGELOG.md +182 -93
- package/README.md +39 -40
- package/dist/app/app.d.ts +84 -4
- package/dist/components/canvas/iframe-preview/iframe-preview.d.ts +55 -4
- package/dist/components/composer/message-composer.d.ts +53 -0
- package/dist/components/conversation/context-changed-divider/context-changed-divider.d.ts +40 -0
- package/dist/components/conversation/context-divider.d.ts +55 -0
- package/dist/components/conversation/conversation.d.ts +5 -0
- package/dist/components/conversation/welcome-message/welcome-message.d.ts +9 -1
- package/dist/components/feedback/feedback-confirmation.d.ts +3 -0
- package/dist/components/feedback/feedback.d.ts +1 -0
- package/dist/components/history/history-item.d.ts +40 -0
- package/dist/components/history/history-view.d.ts +41 -0
- package/dist/components/layout/app-header/app-header.d.ts +5 -5
- package/dist/components/message/assistant-message.d.ts +4 -7
- package/dist/components/message/message-actions.d.ts +5 -0
- package/dist/components/message/message-attachments.d.ts +36 -0
- package/dist/components/message/message-attachments.styles.d.ts +2 -0
- package/dist/components/message/message.d.ts +1 -2
- package/dist/components/message/renderers/reasoning-block.d.ts +36 -0
- package/dist/components/message/renderers/reasoning-block.styles.d.ts +2 -0
- package/dist/components/message/renderers/tool-status-block.d.ts +6 -1
- package/dist/components/primitives/form-field/form-field.d.ts +8 -0
- package/dist/components/primitives/tooltip/tooltip.d.ts +3 -0
- package/dist/components/settings/settings-view.d.ts +30 -0
- package/dist/components/shared/controllers/iframe-preview-controller.d.ts +11 -0
- package/dist/core/adapters/citation-utils.d.ts +5 -3
- package/dist/core/adapters/index.d.ts +1 -1
- package/dist/core/adapters/memoized-mapper.d.ts +8 -9
- package/dist/core/adapters/message-mapper.d.ts +4 -11
- package/dist/core/adapters/message-normalizer.d.ts +22 -0
- package/dist/core/adapters/message-types.d.ts +38 -10
- package/dist/core/adapters/reasoning-utils.d.ts +29 -0
- package/dist/core/adapters/tool-utils.d.ts +37 -0
- package/dist/core/canvas/canvas-store.d.ts +6 -0
- package/dist/core/constants.d.ts +4 -0
- package/dist/core/errors.d.ts +3 -2
- package/dist/core/messages.d.ts +31 -1
- package/dist/core/store/agent-subscriber.d.ts +11 -1
- package/dist/core/store/auth-coordinator.d.ts +22 -4
- package/dist/core/store/chat-store.d.ts +132 -12
- package/dist/core/store/config-manager.d.ts +3 -18
- package/dist/core/store/consent-storage.d.ts +10 -0
- package/dist/core/store/history-coordinator.d.ts +77 -0
- package/dist/core/store/index.d.ts +8 -4
- package/dist/core/store/plugin-selection-manager.d.ts +5 -0
- package/dist/core/store/run-coordinator.d.ts +45 -7
- package/dist/core/store/selection-manager.d.ts +4 -0
- package/dist/core/store/selectors/component-selectors.d.ts +57 -5
- package/dist/core/store/selectors/index.d.ts +2 -2
- package/dist/core/store/selectors/message-selectors.d.ts +4 -33
- package/dist/core/store/session-manager.d.ts +53 -8
- package/dist/core/store/support-manager.d.ts +3 -0
- package/dist/core/store/tool-selection-manager.d.ts +5 -0
- package/dist/core/types.d.ts +101 -10
- package/dist/custom-elements.json +1 -1
- package/dist/{da--slbCKBx.js → da-DDxL51tD.js} +61 -2
- package/dist/{index-C2Q856CM.js → esm-lz7YfYzg.js} +3455 -4997
- package/dist/{fi-Cc9g_Z1U.js → fi-twx072Zu.js} +64 -5
- package/dist/generated/locales/da.d.ts +59 -0
- package/dist/generated/locales/fi.d.ts +59 -0
- package/dist/generated/locales/nb.d.ts +59 -0
- package/dist/generated/locales/nl.d.ts +59 -0
- package/dist/generated/locales/sv.d.ts +59 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.es.js +16632 -13135
- package/dist/learning-universe-B_ZGsjBI.js +5 -0
- package/dist/markdown-BsU07hR0.js +2696 -0
- package/dist/{nb-BvGJ1d1A.js → nb-CeFzi8EU.js} +61 -2
- package/dist/{nl-BMUWAHah.js → nl-D1Z5TDkR.js} +61 -2
- package/dist/rolldown-runtime--_vEcKDh.js +29 -0
- package/dist/services/agent-service.d.ts +12 -9
- package/dist/services/api-client.d.ts +6 -0
- package/dist/services/api-schemas.d.ts +180 -40
- package/dist/services/conversations-client.d.ts +23 -0
- package/dist/services/index.d.ts +1 -1
- package/dist/services/message-converter.d.ts +5 -0
- package/dist/signalr-K7e2DzwD.js +1535 -0
- package/dist/{sv-DpcFtI4M.js → sv-BnYyj9E_.js} +60 -1
- package/dist/types/events.d.ts +29 -3
- package/dist/types/host-context.d.ts +22 -0
- package/dist/types/index.d.ts +5 -3
- package/dist/types/message-attachment.d.ts +7 -0
- package/dist/utils/i18n-check-helpers.d.ts +15 -0
- package/dist/utils/polling-task.d.ts +11 -1
- package/dist/vscode.html-custom-data.json +100 -7
- package/dist/{vsn-B4oW66pe.js → vsn-CBq00924.js} +1 -1
- package/package.json +23 -17
- package/dist/learning-universe-DsDXQ8wT.js +0 -5
- package/dist/markdown-BwfOAOOm.js +0 -1676
- package/dist/signalr-C1wWrBvq.js +0 -1783
package/dist/app/app.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PropertyValues } from 'lit';
|
|
2
2
|
import { StrategyType } from '../core/store';
|
|
3
3
|
import { TokenFetcher } from '../services/auth-service';
|
|
4
|
-
import { FrontendTool, HostContextProvider } from '../types';
|
|
4
|
+
import { FrontendTool, HostContext, HostContextProvider } from '../types';
|
|
5
5
|
import { BaseElement } from '../components/shared/base-element';
|
|
6
6
|
/**
|
|
7
7
|
* Root chat widget component.
|
|
@@ -12,6 +12,7 @@ import { BaseElement } from '../components/shared/base-element';
|
|
|
12
12
|
* @element gaia-chat
|
|
13
13
|
*
|
|
14
14
|
* @fires {ConversationClearedEvent} conversation-cleared - When the user clears the conversation
|
|
15
|
+
* @fires {ConversationRestoredEvent} conversation-restored - When a conversation is restored from history, carrying the persisted host-context snapshot so the host app can re-orient to the tenant / customer / company it was about.
|
|
15
16
|
* @fires {MessageSentEvent} message-sent - When the user sends a message
|
|
16
17
|
* @fires {ToolCallApprovedEvent} tool-call-approved - When the user approves a tool call
|
|
17
18
|
* @fires {ToolCallDeclinedEvent} tool-call-declined - When the user declines a tool call
|
|
@@ -27,6 +28,24 @@ import { BaseElement } from '../components/shared/base-element';
|
|
|
27
28
|
* auth-strategy="visitor"
|
|
28
29
|
* ></gaia-chat>
|
|
29
30
|
* ```
|
|
31
|
+
*
|
|
32
|
+
* ### Host-provided conversation id
|
|
33
|
+
*
|
|
34
|
+
* Setting the `conversation-id` attribute opens that conversation as a
|
|
35
|
+
* **scoped view** without overwriting the user's normal stored session. This
|
|
36
|
+
* is for host apps that need to deep-link back into a specific conversation
|
|
37
|
+
* — e.g. a report designer reopening the chat that produced a given report.
|
|
38
|
+
* Removing the attribute restores the localStorage-backed conversation.
|
|
39
|
+
*
|
|
40
|
+
* ```html
|
|
41
|
+
* <gaia-chat conversation-id="d4f9..." profile-id="default"></gaia-chat>
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* If the user clears the chat while a host-provided `conversation-id` is set,
|
|
45
|
+
* `conversation-cleared` fires with `previousConversationId` matching the
|
|
46
|
+
* pinned value. Treat that as the user opting out of the deep-link — typical
|
|
47
|
+
* responses are to clear/update the attribute, or leave it pinned and accept
|
|
48
|
+
* that the next mount will re-restore the deep-linked conversation.
|
|
30
49
|
*/
|
|
31
50
|
export declare class ChatApp extends BaseElement {
|
|
32
51
|
static styles: import('lit').CSSResult[];
|
|
@@ -42,10 +61,22 @@ export declare class ChatApp extends BaseElement {
|
|
|
42
61
|
authStrategy: StrategyType;
|
|
43
62
|
/** Whether to show a close button in the header. */
|
|
44
63
|
closeable: boolean;
|
|
45
|
-
/**
|
|
46
|
-
|
|
64
|
+
/** Whether to show the conversation history button in the header. */
|
|
65
|
+
enableHistory: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Host-provided conversation id (#2644). When set, this conversation is
|
|
68
|
+
* restored instead of the one persisted in localStorage. The localStorage
|
|
69
|
+
* value is **not** overwritten — clearing the attribute returns the widget
|
|
70
|
+
* to that previous conversation. Empty string is treated as unset.
|
|
71
|
+
*/
|
|
72
|
+
conversationId: string;
|
|
47
73
|
/** Frontend tool definitions sent to the agent. */
|
|
48
74
|
tools: FrontendTool[];
|
|
75
|
+
/**
|
|
76
|
+
* Readonly mode: hides the composer, header actions, and connection overlay.
|
|
77
|
+
* Use `setReadonlyMessages()` to inject messages for display.
|
|
78
|
+
*/
|
|
79
|
+
readonlyMode: boolean;
|
|
49
80
|
private get activeLang();
|
|
50
81
|
private langObserver?;
|
|
51
82
|
private store;
|
|
@@ -54,20 +85,69 @@ export declare class ChatApp extends BaseElement {
|
|
|
54
85
|
private canvasActive;
|
|
55
86
|
private canvasExpanded;
|
|
56
87
|
private supportSessionEnded;
|
|
88
|
+
private historyOpen;
|
|
89
|
+
private settingsOpen;
|
|
90
|
+
private attachmentsEnabled;
|
|
91
|
+
private supportConnected;
|
|
92
|
+
private isDraggingOver;
|
|
93
|
+
private dragDepth;
|
|
57
94
|
private disposables;
|
|
58
95
|
private ctx;
|
|
59
96
|
private handleInlineQuestionClick;
|
|
60
97
|
connectedCallback(): void;
|
|
61
98
|
disconnectedCallback(): void;
|
|
62
99
|
private handleAuthChanged;
|
|
100
|
+
/**
|
|
101
|
+
* Reconcile the chat surface with the current `conversation-id` attribute
|
|
102
|
+
* when no auth-related prop changed alongside it. Non-empty value → scoped
|
|
103
|
+
* restore (no localStorage write). Empty/absent → fall back to the
|
|
104
|
+
* localStorage-backed conversation via `loadHistory`.
|
|
105
|
+
*/
|
|
106
|
+
private applyConversationIdOverride;
|
|
63
107
|
willUpdate(changedProperties: PropertyValues): void;
|
|
64
|
-
private applySelectedModel;
|
|
65
108
|
private toggleHostAttribute;
|
|
66
109
|
private handleKeyDown;
|
|
110
|
+
/**
|
|
111
|
+
* Retroactively update the host-context snapshot for the most recent user
|
|
112
|
+
* message. Call this after a mid-run context confirmation (e.g. a frontend
|
|
113
|
+
* tool) so the "Context changed" divider renders immediately.
|
|
114
|
+
*/
|
|
115
|
+
patchCurrentMessageHostContext(props: Record<string, unknown>): void;
|
|
116
|
+
/**
|
|
117
|
+
* Returns the host-context snapshot persisted for the active conversation,
|
|
118
|
+
* shaped as a {@link HostContext}, or `null` when none is available.
|
|
119
|
+
*
|
|
120
|
+
* The localStorage-backed restore path (`loadHistory`) hydrates this snapshot
|
|
121
|
+
* but does not emit {@link ConversationRestoredEvent}, so a host app that
|
|
122
|
+
* supplies context via `hostContextProvider` can read it here to keep
|
|
123
|
+
* follow-up messages scoped to the restored tenant/company after a refresh.
|
|
124
|
+
*/
|
|
125
|
+
getActiveHostContext(): HostContext | null;
|
|
126
|
+
/** Whether a file dragged over the widget can currently be attached. */
|
|
127
|
+
private get canAcceptDrop();
|
|
128
|
+
private get composer();
|
|
129
|
+
private dragContainsFiles;
|
|
130
|
+
private handleDragEnter;
|
|
131
|
+
private handleDragOver;
|
|
132
|
+
private handleDragLeave;
|
|
133
|
+
private handleDrop;
|
|
67
134
|
/** Clears the current conversation and resets the chat. */
|
|
68
135
|
clearConversation(): void;
|
|
69
136
|
/** Stops any active support session. */
|
|
70
137
|
stopSupport(): void;
|
|
138
|
+
/** Sends a message programmatically after the chat has initialized. */
|
|
139
|
+
sendMessage(message: string): Promise<void>;
|
|
140
|
+
/**
|
|
141
|
+
* Inject messages for readonly display. Accepts AG-UI format messages
|
|
142
|
+
* (as returned by the inspect API) and runs them through the full message
|
|
143
|
+
* pipeline so tool calls, search results, reasoning, and citations all
|
|
144
|
+
* render correctly.
|
|
145
|
+
*
|
|
146
|
+
* @param messages - AG-UI format message objects from the backend.
|
|
147
|
+
* @param thumbs - Optional map of messageId → "up" | "down" for feedback indicators.
|
|
148
|
+
*/
|
|
149
|
+
setReadonlyMessages(messages: ReadonlyArray<Record<string, unknown>>, thumbs?: Readonly<Record<string, string>>): void;
|
|
150
|
+
private waitForInitialization;
|
|
71
151
|
render(): import('lit-html').TemplateResult<1>;
|
|
72
152
|
}
|
|
73
153
|
declare global {
|
|
@@ -41,13 +41,64 @@ export declare class IframePreview extends BaseElement {
|
|
|
41
41
|
private handleRendererReady;
|
|
42
42
|
private transpileAndSend;
|
|
43
43
|
private updateIframeHtml;
|
|
44
|
+
/**
|
|
45
|
+
* Single source of truth for report sanitization. Branches on whether the
|
|
46
|
+
* LLM produced a full document or a fragment, runs DOMPurify with the
|
|
47
|
+
* matching options, then runs the defense-in-depth post-pass. Both the
|
|
48
|
+
* chart-bundle precheck in `updateIframeHtml` and the final `buildHtml`
|
|
49
|
+
* call site consume the same output, so detection and rendering can never
|
|
50
|
+
* disagree about what survives sanitisation.
|
|
51
|
+
*/
|
|
52
|
+
private sanitizeContent;
|
|
44
53
|
private loadChartsScript;
|
|
45
54
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
55
|
+
* Returns the error harness script tag with a per-render CSP nonce.
|
|
56
|
+
* The nonce matches the one embedded in the Content-Security-Policy meta
|
|
57
|
+
* tag, so `script-src 'unsafe-inline'` is not required.
|
|
58
|
+
*/
|
|
59
|
+
private static errorHarness;
|
|
60
|
+
/**
|
|
61
|
+
* Returns the CSP meta tag for the report iframe, scoped to a per-render
|
|
62
|
+
* nonce.
|
|
63
|
+
*
|
|
64
|
+
* Using a nonce eliminates the need for `script-src 'unsafe-inline'`:
|
|
65
|
+
* only `<script nonce="…">` elements whose nonce matches the policy are
|
|
66
|
+
* executed, so a DOMPurify zero-day that lets an inline `<script>` survive
|
|
67
|
+
* sanitization cannot execute — it would have no nonce.
|
|
68
|
+
*
|
|
69
|
+
* The iframe is loaded via `srcdoc`, which does not receive the server's
|
|
70
|
+
* HTTP-header CSP applied to /canvas/*. The policy therefore lives inside
|
|
71
|
+
* the document itself and mirrors the transpile-renderer policy
|
|
72
|
+
* (assistant/src/Api/Program.cs). `connect-src 'none'` is the critical
|
|
73
|
+
* directive — it blocks fetch/XHR/beacon so surviving scripts cannot
|
|
74
|
+
* exfiltrate report contents to an external host.
|
|
75
|
+
*/
|
|
76
|
+
private static buildCspMeta;
|
|
77
|
+
/** Tags stripped from LLM-authored report HTML. Script/handler removal is
|
|
78
|
+
* already covered by DOMPurify defaults; these add belt-and-braces against
|
|
79
|
+
* tags that can navigate, load external resources, or submit data.
|
|
80
|
+
*
|
|
81
|
+
* Notably *not* forbidden — these are intended report features:
|
|
82
|
+
* - `<svg>`: pdf-report skill instructs the LLM to inline SVG icons
|
|
83
|
+
* and diagrams (see `assistant/src/Plugins/PdfReport/skills/.../SKILL.md`).
|
|
84
|
+
* The script-execution risk from SVG-mediated DOMPurify mXSS is
|
|
85
|
+
* neutralised by the per-render CSP nonce — a surviving inline `<script>`
|
|
86
|
+
* would have no nonce and the browser would refuse to run it.
|
|
87
|
+
* - `<img>`: pdf-report supports PNG data URIs (`src="data:image/png;…"`),
|
|
88
|
+
* and the iframe CSP already restricts `img-src` to `data: blob:`.
|
|
89
|
+
* - `<style>`: pdf-report embeds all CSS in `<style>` blocks. The element
|
|
90
|
+
* itself is safe; CSS-injection-via-attribute is blocked by
|
|
91
|
+
* `REPORT_FORBID_ATTRS` below.
|
|
49
92
|
*/
|
|
50
|
-
private static readonly
|
|
93
|
+
private static readonly REPORT_FORBID_TAGS;
|
|
94
|
+
/** Attributes stripped from LLM-authored report HTML. The inline `style`
|
|
95
|
+
* attribute is the main UI-spoofing vector left after `<script>`/handler
|
|
96
|
+
* removal — e.g. `<div style="position:fixed;inset:0;background:#fff;
|
|
97
|
+
* z-index:9999">…fake content…</div>` could mask the rest of the report
|
|
98
|
+
* inside the iframe. The pdf-report skill never instructs the LLM to use
|
|
99
|
+
* inline `style` attributes (it embeds all CSS in a `<style>` block), so
|
|
100
|
+
* forbidding the attribute does not regress intended functionality. */
|
|
101
|
+
private static readonly REPORT_FORBID_ATTRS;
|
|
51
102
|
private buildHtml;
|
|
52
103
|
private escapeHtml;
|
|
53
104
|
render(): import('lit-html').TemplateResult<1>;
|
|
@@ -21,28 +21,78 @@ export declare class GaiaMessageComposer extends BaseElement {
|
|
|
21
21
|
textareaWrap: HTMLDivElement;
|
|
22
22
|
textarea: HTMLTextAreaElement;
|
|
23
23
|
autosize: HTMLDivElement;
|
|
24
|
+
attachmentInput?: HTMLInputElement;
|
|
24
25
|
private value;
|
|
25
26
|
private invalid;
|
|
27
|
+
private pendingAttachments;
|
|
28
|
+
private attachmentError;
|
|
29
|
+
private uploadingCount;
|
|
30
|
+
private isRecording;
|
|
31
|
+
private speechSupported;
|
|
32
|
+
private recognition;
|
|
26
33
|
profileId: string;
|
|
27
34
|
hostContextProvider?: HostContextProvider;
|
|
28
35
|
rows: number;
|
|
29
36
|
maxRows: number;
|
|
30
37
|
connectedCallback(): void;
|
|
31
38
|
disconnectedCallback(): void;
|
|
39
|
+
/** Whether an attachment upload is currently in flight. */
|
|
40
|
+
private get uploadingAttachment();
|
|
32
41
|
private get notAllowedToSendMessage();
|
|
42
|
+
private get canUseVoiceDictation();
|
|
33
43
|
private isMessageNotAllowed;
|
|
34
44
|
private validateInput;
|
|
45
|
+
private initSpeechRecognition;
|
|
46
|
+
private toggleRecording;
|
|
35
47
|
private handleChange;
|
|
36
48
|
private handleInput;
|
|
37
49
|
private handleFeedbackClosed;
|
|
38
50
|
private closeFeedbackIfOpen;
|
|
39
51
|
private handleSendMessage;
|
|
52
|
+
private handleStopMessage;
|
|
40
53
|
private resolveHostContext;
|
|
41
54
|
private dispatchToSupport;
|
|
42
55
|
private dispatchToAssistant;
|
|
56
|
+
private handleAttachmentButtonClick;
|
|
57
|
+
private clearPendingAttachments;
|
|
58
|
+
/** Dismisses the attachment error banner without discarding staged attachments. */
|
|
59
|
+
private dismissAttachmentError;
|
|
60
|
+
private removePendingAttachment;
|
|
61
|
+
private handleAttachmentSelected;
|
|
62
|
+
private processAttachmentFiles;
|
|
63
|
+
private uploadAttachmentFile;
|
|
64
|
+
/**
|
|
65
|
+
* Whether a file can currently be accepted as a pending attachment.
|
|
66
|
+
*
|
|
67
|
+
* False when attachments are disabled for the profile, the support channel
|
|
68
|
+
* is active, or the composer is disabled/loading. Callers should check this
|
|
69
|
+
* before suppressing native browser behaviour (e.g. paste) so they don't
|
|
70
|
+
* swallow the event without effect. Multiple attachments may be queued, so
|
|
71
|
+
* an in-flight upload does not block accepting further files.
|
|
72
|
+
*/
|
|
73
|
+
get canAcceptAttachment(): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Uploads files dropped anywhere on the chat surface as pending attachments.
|
|
76
|
+
*
|
|
77
|
+
* Called by the root chat component, which owns the drag-and-drop overlay so
|
|
78
|
+
* files can be dropped over the entire widget rather than only the composer.
|
|
79
|
+
* Guards against uploads while attachments are unavailable for the active
|
|
80
|
+
* channel/profile.
|
|
81
|
+
*/
|
|
82
|
+
acceptDroppedFiles(files: File[]): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* Uploads a single dropped file as a pending attachment.
|
|
85
|
+
*
|
|
86
|
+
* Thin wrapper around {@link acceptDroppedFiles} retained for callers that
|
|
87
|
+
* only have a single file to hand.
|
|
88
|
+
*/
|
|
89
|
+
acceptDroppedFile(file: File): Promise<void>;
|
|
43
90
|
private handleSuggestedQuestionClick;
|
|
44
91
|
private handleKeyDown;
|
|
92
|
+
private handlePaste;
|
|
45
93
|
private maybeEmitTyping;
|
|
94
|
+
private createPreviewUrl;
|
|
95
|
+
private revokeAllPreviewUrls;
|
|
46
96
|
protected updated(changed: PropertyValues): Promise<void>;
|
|
47
97
|
/** Sets focus on the textarea. */
|
|
48
98
|
focus(options?: FocusOptions): void;
|
|
@@ -51,6 +101,9 @@ export declare class GaiaMessageComposer extends BaseElement {
|
|
|
51
101
|
/** Selects all the text in the textarea. */
|
|
52
102
|
select(): void;
|
|
53
103
|
render(): import('lit-html').TemplateResult<1>;
|
|
104
|
+
private getPendingAttachmentPreviews;
|
|
105
|
+
private renderPendingAttachmentPreviews;
|
|
106
|
+
private renderAttachmentError;
|
|
54
107
|
}
|
|
55
108
|
declare global {
|
|
56
109
|
interface HTMLElementTagNameMap {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { BaseElement } from '../../shared/base-element';
|
|
2
|
+
/**
|
|
3
|
+
* Per-key diff between two adjacent host-context snapshots. Drives the expanded
|
|
4
|
+
* comparison view that the divider reveals on click. Mirrors the shape produced
|
|
5
|
+
* by `describeHostContextDiff()` in the conversation renderer — the divider is
|
|
6
|
+
* purely presentational and trusts its caller to compute the diff.
|
|
7
|
+
*/
|
|
8
|
+
export type HostContextDiff = {
|
|
9
|
+
added: Record<string, unknown>;
|
|
10
|
+
removed: Record<string, unknown>;
|
|
11
|
+
changed: Record<string, {
|
|
12
|
+
from: unknown;
|
|
13
|
+
to: unknown;
|
|
14
|
+
}>;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Visual divider rendered between two adjacent user messages whose host-supplied
|
|
18
|
+
* context differs (e.g. the host app pivoted from one customer to another mid-chat).
|
|
19
|
+
*
|
|
20
|
+
* Renders a centered "Context changed" disclosure button between two horizontal
|
|
21
|
+
* rules. Clicking the button toggles a panel below that lists the per-key diff —
|
|
22
|
+
* added / changed / removed entries — so the user can compare what shifted.
|
|
23
|
+
*
|
|
24
|
+
* @element gaia-context-changed-divider
|
|
25
|
+
*/
|
|
26
|
+
export declare class GaiaContextChangedDivider extends BaseElement {
|
|
27
|
+
/** Per-key diff of host context. Drives the expanded comparison view. */
|
|
28
|
+
diff?: HostContextDiff;
|
|
29
|
+
private expanded;
|
|
30
|
+
static styles: import('lit').CSSResult[];
|
|
31
|
+
private toggle;
|
|
32
|
+
private renderEntries;
|
|
33
|
+
private renderDetails;
|
|
34
|
+
render(): import('lit-html').TemplateResult<1>;
|
|
35
|
+
}
|
|
36
|
+
declare global {
|
|
37
|
+
interface HTMLElementTagNameMap {
|
|
38
|
+
'gaia-context-changed-divider': GaiaContextChangedDivider;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { HostContextDiff } from './context-changed-divider/context-changed-divider';
|
|
2
|
+
import { UiMessage } from '../../core/adapters/message-types';
|
|
3
|
+
import { HostContextSnapshot } from '../../core/types';
|
|
4
|
+
/**
|
|
5
|
+
* Pure helpers that decide when the `<gaia-context-changed-divider>` fires and what
|
|
6
|
+
* diff it should display. Extracted from `<gaia-conversation>` so the gating
|
|
7
|
+
* invariants — "first user message never fires", "baseline advances on every user
|
|
8
|
+
* message even with no context", "transitions to/from no-context still fire" — can
|
|
9
|
+
* be unit-tested without mounting the conversation component. The renderer just
|
|
10
|
+
* consumes the Map this module produces.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Decide whether a "Context changed" divider should fire between two adjacent user
|
|
14
|
+
* messages' host-context snapshots. Fires whenever the two snapshots differ, treating
|
|
15
|
+
* `undefined`/`null` as a first-class "no host context" state — so a transition from
|
|
16
|
+
* `{ companyId: 123 }` to `undefined` (e.g. user switched profile and the host stopped
|
|
17
|
+
* forwarding companyId) draws a line, just like any other change. The first user
|
|
18
|
+
* message in a conversation never fires; that gating happens in
|
|
19
|
+
* `computeContextChangedMessageIds`, not here.
|
|
20
|
+
*
|
|
21
|
+
* Both ends of the pipeline serialize via JSON-shaped objects, so a key-sorted
|
|
22
|
+
* recursive deep-equal is sufficient — we don't need to handle Maps, Dates, or other
|
|
23
|
+
* non-JSON types.
|
|
24
|
+
*/
|
|
25
|
+
export declare function shouldFireContextChangedDivider(previous: HostContextSnapshot | undefined, current: HostContextSnapshot | undefined): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Classify the differences between two host-context snapshots into added / removed /
|
|
28
|
+
* changed keys. The result is passed straight into `<gaia-context-changed-divider>`,
|
|
29
|
+
* which renders it as the expandable comparison view shown when the user opens the
|
|
30
|
+
* divider.
|
|
31
|
+
*/
|
|
32
|
+
export declare function describeHostContextDiff(previous: HostContextSnapshot | undefined, current: HostContextSnapshot | undefined): HostContextDiff;
|
|
33
|
+
/**
|
|
34
|
+
* Identify user messages that need a "Context changed" divider rendered above them,
|
|
35
|
+
* paired with the summary the divider should display. A user message qualifies when
|
|
36
|
+
* its recorded host-context differs from the previous user message's — including
|
|
37
|
+
* transitions to/from "no recorded context". The very first user message never
|
|
38
|
+
* qualifies because there's no prior turn to compare to.
|
|
39
|
+
*
|
|
40
|
+
* Works identically for live sends (snapshot written by the run-coordinator) and
|
|
41
|
+
* rehydrated chats (snapshot loaded from `conversation_v2_messages` via the restore
|
|
42
|
+
* path) — both populate the same `messageHostContexts` map.
|
|
43
|
+
*
|
|
44
|
+
* Returns a Map of message id → diff describing the per-key change. The divider
|
|
45
|
+
* uses the diff to render its expanded comparison view on demand. O(1) lookup per
|
|
46
|
+
* group.
|
|
47
|
+
*/
|
|
48
|
+
export declare function computeContextChangedMessageIds(messages: UiMessage[], contexts: Record<string, HostContextSnapshot>): Map<string, HostContextDiff>;
|
|
49
|
+
/**
|
|
50
|
+
* Internal JSON-shape deep-equal. Exported solely for unit tests that lock in the
|
|
51
|
+
* key-order-independence and array-vs-object behavior the divider gating depends on.
|
|
52
|
+
* Not part of the module's public API — callers should use `shouldFireContextChangedDivider`
|
|
53
|
+
* or `describeHostContextDiff` instead of comparing snapshots directly.
|
|
54
|
+
*/
|
|
55
|
+
export declare function deepEqual(a: unknown, b: unknown): boolean;
|
|
@@ -14,10 +14,14 @@ export declare class GaiaConversation extends BaseElement {
|
|
|
14
14
|
private containerRef;
|
|
15
15
|
private scrollViewRef;
|
|
16
16
|
private lastMessageRef;
|
|
17
|
+
private selectConversationState;
|
|
17
18
|
private ctrl;
|
|
19
|
+
private sharingCtrl;
|
|
20
|
+
private sharingPromptTriggered;
|
|
18
21
|
private handleThumb;
|
|
19
22
|
private scrollCtrl;
|
|
20
23
|
protected updated(): Promise<void>;
|
|
24
|
+
private handleSharingPromptResponse;
|
|
21
25
|
/**
|
|
22
26
|
* Whether the thinking indicator should be visible.
|
|
23
27
|
* Hidden when the last message is a pending tool call with a visible
|
|
@@ -29,6 +33,7 @@ export declare class GaiaConversation extends BaseElement {
|
|
|
29
33
|
*/
|
|
30
34
|
private isMessageInActiveRun;
|
|
31
35
|
private renderRunGroup;
|
|
36
|
+
private renderRunGroupBody;
|
|
32
37
|
render(): import('lit-html').TemplateResult<1>;
|
|
33
38
|
}
|
|
34
39
|
declare global {
|
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
import { WelcomeMessage } from '../../../core/types';
|
|
2
2
|
import { BaseElement } from '../../shared/base-element';
|
|
3
|
+
export interface SharingPromptResponseEvent {
|
|
4
|
+
accepted: boolean;
|
|
5
|
+
}
|
|
3
6
|
/**
|
|
4
7
|
* Welcome screen shown when the conversation is empty.
|
|
5
8
|
*
|
|
6
9
|
* Renders a greeting title, optional body text, a call-to-action prompt,
|
|
7
|
-
*
|
|
10
|
+
* optional informational cards, and an optional inline consent prompt.
|
|
8
11
|
*
|
|
9
12
|
* @element gaia-welcome-message
|
|
10
13
|
*/
|
|
11
14
|
export declare class GaiaWelcomeMessage extends BaseElement {
|
|
12
15
|
static styles: import('lit').CSSResult[][];
|
|
13
16
|
welcomeMessage?: WelcomeMessage;
|
|
17
|
+
/** Whether to show the inline sharing consent prompt below block cards. */
|
|
18
|
+
showSharingPrompt: boolean;
|
|
19
|
+
private handleYes;
|
|
20
|
+
private handleNo;
|
|
14
21
|
render(): import('lit-html').TemplateResult<1>;
|
|
22
|
+
private renderSharingPrompt;
|
|
15
23
|
}
|
|
16
24
|
declare global {
|
|
17
25
|
interface HTMLElementTagNameMap {
|
|
@@ -11,10 +11,13 @@ import { BaseElement } from '../shared/base-element';
|
|
|
11
11
|
export declare class GaiaFeedbackConfirmation extends BaseElement {
|
|
12
12
|
static styles: import('lit').CSSResult[];
|
|
13
13
|
private ctrl;
|
|
14
|
+
private copyTimeoutId;
|
|
14
15
|
private copied;
|
|
16
|
+
disconnectedCallback(): void;
|
|
15
17
|
private get visitorUserId();
|
|
16
18
|
private get shouldShowPrivacyId();
|
|
17
19
|
private handleClose;
|
|
20
|
+
private clearCopyTimeout;
|
|
18
21
|
private handleCopyPrivacyId;
|
|
19
22
|
render(): import('lit-html').TemplateResult<1>;
|
|
20
23
|
}
|
|
@@ -29,6 +29,7 @@ export declare class GaiaFeedback extends BaseElement {
|
|
|
29
29
|
private handleCommentChange;
|
|
30
30
|
private handleSubmit;
|
|
31
31
|
private handleConsentConfirmed;
|
|
32
|
+
private submitAndClose;
|
|
32
33
|
protected firstUpdated(_changedProperties: PropertyValues): void;
|
|
33
34
|
private handleKeyDown;
|
|
34
35
|
private handleClose;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ConversationSummary } from '../../core/types';
|
|
2
|
+
import { BaseElement } from '../shared/base-element';
|
|
3
|
+
/**
|
|
4
|
+
* A single row in {@link GaiaHistoryView}. Shows the title, a context label
|
|
5
|
+
* when available (customer / company / partner), a relative timestamp, and
|
|
6
|
+
* row-level rename / delete actions.
|
|
7
|
+
*
|
|
8
|
+
* Stays stateless w.r.t. the store — actions bubble up as CustomEvents and
|
|
9
|
+
* are handled by the parent `<gaia-history-view>` which forwards them to
|
|
10
|
+
* `HistoryCoordinator`. Rename uses a minimal inline edit mode to keep the
|
|
11
|
+
* MVP scope small (no modal component dependency).
|
|
12
|
+
*
|
|
13
|
+
* @element gaia-history-item
|
|
14
|
+
*
|
|
15
|
+
* @fires history-item-select - When the row is activated. Detail: `{ summary }`.
|
|
16
|
+
* @fires history-item-rename - After the user confirms a new title. Detail: `{ id, title }`.
|
|
17
|
+
* @fires history-item-delete - After the user confirms deletion. Detail: `{ id }`.
|
|
18
|
+
*/
|
|
19
|
+
export declare class GaiaHistoryItem extends BaseElement {
|
|
20
|
+
static styles: import('lit').CSSResult[];
|
|
21
|
+
summary: ConversationSummary;
|
|
22
|
+
active: boolean;
|
|
23
|
+
private editing;
|
|
24
|
+
private draftTitle;
|
|
25
|
+
private handleSelect;
|
|
26
|
+
private handleKeyDown;
|
|
27
|
+
private startRename;
|
|
28
|
+
private cancelRename;
|
|
29
|
+
private confirmRename;
|
|
30
|
+
private handleEditKey;
|
|
31
|
+
private handleInput;
|
|
32
|
+
private handleDelete;
|
|
33
|
+
private getContextLabel;
|
|
34
|
+
render(): import('lit-html').TemplateResult<1>;
|
|
35
|
+
}
|
|
36
|
+
declare global {
|
|
37
|
+
interface HTMLElementTagNameMap {
|
|
38
|
+
'gaia-history-item': GaiaHistoryItem;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { PropertyValues } from 'lit';
|
|
2
|
+
import { BaseElement } from '../shared/base-element';
|
|
3
|
+
/**
|
|
4
|
+
* Full-area conversation history panel. Replaces the chat area inside
|
|
5
|
+
* `<gaia-chat>` when `historyOpen` is true.
|
|
6
|
+
*
|
|
7
|
+
* Renders a profile-scoped list of previous conversations. Row actions (rename,
|
|
8
|
+
* delete) are delegated to `<gaia-history-item>`. Clicking a row restores the
|
|
9
|
+
* conversation into the active chat and fires a `conversation-restored` event
|
|
10
|
+
* via {@link ChatStore.restoreConversationById}.
|
|
11
|
+
*
|
|
12
|
+
* @element gaia-history-view
|
|
13
|
+
*/
|
|
14
|
+
export declare class GaiaHistoryView extends BaseElement {
|
|
15
|
+
static styles: import('lit').CSSResult[];
|
|
16
|
+
private ctrl;
|
|
17
|
+
private sentinelObserver?;
|
|
18
|
+
private observedSentinel?;
|
|
19
|
+
private handleClose;
|
|
20
|
+
private handleRetry;
|
|
21
|
+
private handleSelect;
|
|
22
|
+
private handleRename;
|
|
23
|
+
private handleDelete;
|
|
24
|
+
disconnectedCallback(): void;
|
|
25
|
+
protected updated(_changed: PropertyValues): void;
|
|
26
|
+
/**
|
|
27
|
+
* Attach or tear down the IntersectionObserver that watches the bottom-of-list
|
|
28
|
+
* sentinel. The sentinel is only rendered while more pages are available, so
|
|
29
|
+
* this runs on every update and follows the DOM: observe when the sentinel is
|
|
30
|
+
* present, detach when it isn't. The observer's root is the scrollable list
|
|
31
|
+
* container, not the viewport, so nested scroll regions (embedded widget) fire
|
|
32
|
+
* correctly.
|
|
33
|
+
*/
|
|
34
|
+
private syncSentinelObserver;
|
|
35
|
+
render(): import('lit-html').TemplateResult<1>;
|
|
36
|
+
}
|
|
37
|
+
declare global {
|
|
38
|
+
interface HTMLElementTagNameMap {
|
|
39
|
+
'gaia-history-view': GaiaHistoryView;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { PropertyValues } from 'lit';
|
|
2
2
|
import { BaseElement } from '../../shared/base-element';
|
|
3
3
|
/**
|
|
4
|
-
* Application header bar with feedback, new-chat, and close actions.
|
|
5
|
-
*
|
|
6
|
-
* Renders a toolbar with icon buttons for opening the feedback form,
|
|
7
|
-
* clearing the conversation, and closing the chat widget. Actions are
|
|
8
|
-
* disabled while the chat is initializing or a run is in progress.
|
|
4
|
+
* Application header bar with data settings, feedback, new-chat, and close actions.
|
|
9
5
|
*
|
|
10
6
|
* @element gaia-app-header
|
|
11
7
|
*
|
|
@@ -17,15 +13,19 @@ export declare class GaiaAppHeader extends BaseElement {
|
|
|
17
13
|
private ctrl;
|
|
18
14
|
private toolbar;
|
|
19
15
|
closeable: boolean;
|
|
16
|
+
enableHistory: boolean;
|
|
20
17
|
connectedCallback(): void;
|
|
21
18
|
disconnectedCallback(): void;
|
|
22
19
|
protected updated(changed: PropertyValues): void;
|
|
23
20
|
private getToolbarButtons;
|
|
24
21
|
private handleFeedbackClosed;
|
|
25
22
|
private handleClearConversation;
|
|
23
|
+
private handleToggleHistory;
|
|
26
24
|
private handleToggleFeedback;
|
|
27
25
|
private handleCloseChat;
|
|
26
|
+
private toggleDataSettings;
|
|
28
27
|
render(): import('lit-html').TemplateResult<1>;
|
|
28
|
+
private renderDataSettingsButton;
|
|
29
29
|
}
|
|
30
30
|
declare global {
|
|
31
31
|
interface HTMLElementTagNameMap {
|
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
import { nothing } from 'lit';
|
|
2
|
-
import { UiAssistantMessage } from '../../core/adapters';
|
|
3
|
-
import { SearchCitation } from '../../core/adapters/tool-utils';
|
|
2
|
+
import { UiAssistantMessage } from '../../core/adapters/message-types';
|
|
4
3
|
import { BaseElement } from '../shared/base-element';
|
|
5
4
|
export declare class GaiaAssistantMessage extends BaseElement {
|
|
6
5
|
static styles: import('lit').CSSResult[][];
|
|
7
6
|
message: UiAssistantMessage;
|
|
8
|
-
citations: SearchCitation[];
|
|
9
7
|
isStreaming: boolean;
|
|
10
8
|
private bodyEl;
|
|
11
|
-
|
|
12
|
-
private cachedExtraction;
|
|
13
|
-
private getExtractedContent;
|
|
9
|
+
private expandedToolCallIds;
|
|
14
10
|
render(): import('lit-html').TemplateResult<1> | typeof nothing;
|
|
15
|
-
private
|
|
11
|
+
private renderPart;
|
|
16
12
|
private renderToolCall;
|
|
13
|
+
private toggleToolCall;
|
|
17
14
|
private handleInlineQuestionClick;
|
|
18
15
|
}
|
|
19
16
|
declare global {
|
|
@@ -27,6 +27,10 @@ export declare class GaiaMessageActions extends BaseElement {
|
|
|
27
27
|
copyContent: string;
|
|
28
28
|
/** Whether this message belongs to the currently active run. Hides actions while active. */
|
|
29
29
|
inActiveRun: boolean;
|
|
30
|
+
/** Readonly mode: shows static feedback indicator instead of interactive buttons. */
|
|
31
|
+
readonly: boolean;
|
|
32
|
+
/** Persisted feedback state from API. Used in readonly mode to display the thumb icon. */
|
|
33
|
+
thumb: 'up' | 'down' | null;
|
|
30
34
|
/** Callback for submitting message thumbs. Set by parent message component. */
|
|
31
35
|
onThumb?: (messageId: string, isPositive: boolean | null) => Promise<boolean>;
|
|
32
36
|
private isCopied;
|
|
@@ -37,6 +41,7 @@ export declare class GaiaMessageActions extends BaseElement {
|
|
|
37
41
|
render(): import('lit-html').TemplateResult<1> | typeof nothing;
|
|
38
42
|
private renderCopyButton;
|
|
39
43
|
private renderFeedbackButtons;
|
|
44
|
+
private renderFeedbackIndicator;
|
|
40
45
|
private handleCopyClick;
|
|
41
46
|
private handleFeedbackClick;
|
|
42
47
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { nothing } from 'lit';
|
|
2
|
+
import { MessageAttachment } from '../../types';
|
|
3
|
+
import { BaseElement } from '../shared/base-element';
|
|
4
|
+
export declare class GaiaMessageAttachments extends BaseElement {
|
|
5
|
+
static styles: import('lit').CSSResult[];
|
|
6
|
+
attachments: MessageAttachment[];
|
|
7
|
+
onRemoveAttachment?: (attachment: MessageAttachment) => void;
|
|
8
|
+
fullWidth: boolean;
|
|
9
|
+
compact: boolean;
|
|
10
|
+
render(): import('lit-html').TemplateResult<1> | typeof nothing;
|
|
11
|
+
private renderCompactAttachment;
|
|
12
|
+
private renderAttachment;
|
|
13
|
+
private renderRemoveButton;
|
|
14
|
+
private handleRemoveClick;
|
|
15
|
+
private isImageAttachment;
|
|
16
|
+
private isPdfAttachment;
|
|
17
|
+
/**
|
|
18
|
+
* Splits a file name so the tail (extension and a few trailing characters)
|
|
19
|
+
* stays pinned while the start truncates with an ellipsis, yielding a
|
|
20
|
+
* middle-truncated name such as `Screens…nal.pdf`.
|
|
21
|
+
*/
|
|
22
|
+
private splitFileName;
|
|
23
|
+
/** Formats a byte count into a compact, locale-aware size (e.g. `1.2 MB`). */
|
|
24
|
+
private formatFileSize;
|
|
25
|
+
/**
|
|
26
|
+
* Formats a magnitude and byte unit using the active locale, falling back to
|
|
27
|
+
* a plain `value unit` string if the runtime lacks `Intl.NumberFormat` unit
|
|
28
|
+
* support.
|
|
29
|
+
*/
|
|
30
|
+
private formatSizeNumber;
|
|
31
|
+
}
|
|
32
|
+
declare global {
|
|
33
|
+
interface HTMLElementTagNameMap {
|
|
34
|
+
'gaia-message-attachments': GaiaMessageAttachments;
|
|
35
|
+
}
|
|
36
|
+
}
|