@syntrologie/adapt-chatbot 2.8.0-canary.420 → 2.8.0-canary.421
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AdaptiveChatBar.d.ts +14 -0
- package/dist/AdaptiveChatBar.d.ts.map +1 -1
- package/dist/AdaptiveChatBar.js +1 -1
- package/dist/{chunk-2NX6765N.js → chunk-5W75LR6M.js} +35 -2
- package/dist/chunk-5W75LR6M.js.map +7 -0
- package/dist/runtime.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-2NX6765N.js.map +0 -7
|
@@ -142,6 +142,17 @@ export declare class AdaptiveChatBar extends LitElement {
|
|
|
142
142
|
* message lands, so this also closes the empty state in one go.
|
|
143
143
|
*/
|
|
144
144
|
private _onIntroSuggestion;
|
|
145
|
+
/**
|
|
146
|
+
* Reply-chip tap that arrived during the run TAIL. Chips render the
|
|
147
|
+
* moment the reply text lands, but `inFlight` (which includes
|
|
148
|
+
* `runActive` — typing events, tool tail, RUN_FINISHED) can lag for
|
|
149
|
+
* seconds. The old `if (this.inFlight) return;` guard silently ATE
|
|
150
|
+
* those taps — the visitor's chosen reply never appeared as their
|
|
151
|
+
* message (live repro, deployed vela 2026-07-08). Now the tap queues
|
|
152
|
+
* (latest wins) and dispatches when `inFlight` clears.
|
|
153
|
+
*/
|
|
154
|
+
private _queuedSuggestedReply;
|
|
155
|
+
protected willUpdate(changed: Map<string, unknown>): void;
|
|
145
156
|
/**
|
|
146
157
|
* Visitor tapped an inline `suggest_replies` chip in the trail. Submit
|
|
147
158
|
* the chip text through the SAME `chat-message-sent` channel a typed
|
|
@@ -149,6 +160,9 @@ export declare class AdaptiveChatBar extends LitElement {
|
|
|
149
160
|
* chatSession.send → transport) — no fabricated AG-UI events. The
|
|
150
161
|
* trail clears the chips on its own once the reply lands and a newer
|
|
151
162
|
* assistant turn becomes the latest.
|
|
163
|
+
*
|
|
164
|
+
* A tap while the previous run is still closing is QUEUED, never
|
|
165
|
+
* dropped — see `_queuedSuggestedReply`.
|
|
152
166
|
*/
|
|
153
167
|
private _onSuggestedReply;
|
|
154
168
|
render(): import("lit-html").TemplateResult<1>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdaptiveChatBar.d.ts","sourceRoot":"","sources":["../src/AdaptiveChatBar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAQ,UAAU,EAAW,MAAM,KAAK,CAAC;AAGhD,OAAO,wBAAwB,CAAC;AAChC,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,YAAY,EACb,MAAM,wBAAwB,CAAC;AAMhC,qBAAa,eAAgB,SAAQ,UAAU;IAC7C,OAAgB,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAcxB;IAEF,QAAQ,EAAE,YAAY,EAAE,CAAM;IAC9B,SAAS,UAAS;IAClB,YAAY,EAAE,WAAW,EAAE,CAAM;IACjC;yEACqE;IACrE,aAAa,EAAE,iBAAiB,EAAE,CAAM;IACxC;;oEAEgE;IAChE,iBAAiB,EAAE,mBAAmB,GAAG,SAAS,CAAa;IAE/D;;;;;;;OAOG;IACH,YAAY,SAAM;IAClB;;;;;OAKG;IACH,eAAe,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAa;IAE3E;;;uDAGmD;IACnD,aAAa,UAAS;IACtB,WAAW,SAAuB;IAClC;;;;;OAKG;IACH,aAAa,SAA0B;IACvC;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAa;IACzC;;;;;;OAMG;IACH,QAAQ,UAAS;IACjB,MAAM,SAAM;IAEH,gBAAgB,IAAI,WAAW;IAI/B,iBAAiB,IAAI,IAAI;IASzB,oBAAoB,IAAI,IAAI;IAYrC,OAAO,CAAC,QAAQ,CAEd;IAEF,OAAO,CAAC,UAAU,CAShB;IAKF,OAAO,CAAC,kBAAkB,
|
|
1
|
+
{"version":3,"file":"AdaptiveChatBar.d.ts","sourceRoot":"","sources":["../src/AdaptiveChatBar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAQ,UAAU,EAAW,MAAM,KAAK,CAAC;AAGhD,OAAO,wBAAwB,CAAC;AAChC,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,YAAY,EACb,MAAM,wBAAwB,CAAC;AAMhC,qBAAa,eAAgB,SAAQ,UAAU;IAC7C,OAAgB,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAcxB;IAEF,QAAQ,EAAE,YAAY,EAAE,CAAM;IAC9B,SAAS,UAAS;IAClB,YAAY,EAAE,WAAW,EAAE,CAAM;IACjC;yEACqE;IACrE,aAAa,EAAE,iBAAiB,EAAE,CAAM;IACxC;;oEAEgE;IAChE,iBAAiB,EAAE,mBAAmB,GAAG,SAAS,CAAa;IAE/D;;;;;;;OAOG;IACH,YAAY,SAAM;IAClB;;;;;OAKG;IACH,eAAe,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAa;IAE3E;;;uDAGmD;IACnD,aAAa,UAAS;IACtB,WAAW,SAAuB;IAClC;;;;;OAKG;IACH,aAAa,SAA0B;IACvC;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAa;IACzC;;;;;;OAMG;IACH,QAAQ,UAAS;IACjB,MAAM,SAAM;IAEH,gBAAgB,IAAI,WAAW;IAI/B,iBAAiB,IAAI,IAAI;IASzB,oBAAoB,IAAI,IAAI;IAYrC,OAAO,CAAC,QAAQ,CAEd;IAEF,OAAO,CAAC,UAAU,CAShB;IAKF,OAAO,CAAC,kBAAkB,CAUxB;IAEF,OAAO,CAAC,sBAAsB,CAM5B;IAEF,OAAO,CAAC,uBAAuB,CAK7B;IAEF,OAAO,CAAC,iBAAiB,CAEvB;IAEF,OAAO,CAAC,KAAK;IAwBb;;;;;;;OAOG;IACH,OAAO,CAAC,kBAAkB,CAmBxB;IAEF;;;;;;;;OAQG;IACH,OAAO,CAAC,qBAAqB,CAAuB;cAEjC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAsBlE;;;;;;;;;;OAUG;IACH,OAAO,CAAC,iBAAiB,CAoBvB;IAEO,MAAM;CAkDhB;AA8OD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,mBAAmB,EAAE,eAAe,CAAC;KACtC;CACF"}
|
package/dist/AdaptiveChatBar.js
CHANGED
|
@@ -85,6 +85,7 @@ var AdaptiveChatBar = class extends LitElement {
|
|
|
85
85
|
// wins from the user not having to scan for which control is active.
|
|
86
86
|
this._onSendOrInterrupt = () => {
|
|
87
87
|
if (this.inFlight) {
|
|
88
|
+
this._queuedSuggestedReply = null;
|
|
88
89
|
this.dispatchEvent(new CustomEvent("chat-interrupt", { bubbles: true, composed: true }));
|
|
89
90
|
return;
|
|
90
91
|
}
|
|
@@ -128,6 +129,16 @@ var AdaptiveChatBar = class extends LitElement {
|
|
|
128
129
|
})
|
|
129
130
|
);
|
|
130
131
|
};
|
|
132
|
+
/**
|
|
133
|
+
* Reply-chip tap that arrived during the run TAIL. Chips render the
|
|
134
|
+
* moment the reply text lands, but `inFlight` (which includes
|
|
135
|
+
* `runActive` — typing events, tool tail, RUN_FINISHED) can lag for
|
|
136
|
+
* seconds. The old `if (this.inFlight) return;` guard silently ATE
|
|
137
|
+
* those taps — the visitor's chosen reply never appeared as their
|
|
138
|
+
* message (live repro, deployed vela 2026-07-08). Now the tap queues
|
|
139
|
+
* (latest wins) and dispatches when `inFlight` clears.
|
|
140
|
+
*/
|
|
141
|
+
this._queuedSuggestedReply = null;
|
|
131
142
|
/**
|
|
132
143
|
* Visitor tapped an inline `suggest_replies` chip in the trail. Submit
|
|
133
144
|
* the chip text through the SAME `chat-message-sent` channel a typed
|
|
@@ -135,12 +146,18 @@ var AdaptiveChatBar = class extends LitElement {
|
|
|
135
146
|
* chatSession.send → transport) — no fabricated AG-UI events. The
|
|
136
147
|
* trail clears the chips on its own once the reply lands and a newer
|
|
137
148
|
* assistant turn becomes the latest.
|
|
149
|
+
*
|
|
150
|
+
* A tap while the previous run is still closing is QUEUED, never
|
|
151
|
+
* dropped — see `_queuedSuggestedReply`.
|
|
138
152
|
*/
|
|
139
153
|
this._onSuggestedReply = (e) => {
|
|
140
154
|
const detail = e.detail;
|
|
141
155
|
if (!detail?.text) return;
|
|
142
156
|
e.stopPropagation();
|
|
143
|
-
if (this.inFlight)
|
|
157
|
+
if (this.inFlight) {
|
|
158
|
+
this._queuedSuggestedReply = detail.text;
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
144
161
|
this.inFlight = true;
|
|
145
162
|
this.dispatchEvent(
|
|
146
163
|
new CustomEvent("chat-message-sent", {
|
|
@@ -167,6 +184,7 @@ var AdaptiveChatBar = class extends LitElement {
|
|
|
167
184
|
_send() {
|
|
168
185
|
const text = this._input.trim();
|
|
169
186
|
if (!text) return;
|
|
187
|
+
this._queuedSuggestedReply = null;
|
|
170
188
|
this.dispatchEvent(
|
|
171
189
|
new CustomEvent("chat-message-sent", {
|
|
172
190
|
detail: { text },
|
|
@@ -178,6 +196,21 @@ var AdaptiveChatBar = class extends LitElement {
|
|
|
178
196
|
const input = this.querySelector("input[data-chat-input]");
|
|
179
197
|
if (input) input.value = "";
|
|
180
198
|
}
|
|
199
|
+
willUpdate(changed) {
|
|
200
|
+
super.willUpdate?.(changed);
|
|
201
|
+
if (changed.has("inFlight") && changed.get("inFlight") === true && !this.inFlight && this._queuedSuggestedReply) {
|
|
202
|
+
const text = this._queuedSuggestedReply;
|
|
203
|
+
this._queuedSuggestedReply = null;
|
|
204
|
+
this.inFlight = true;
|
|
205
|
+
this.dispatchEvent(
|
|
206
|
+
new CustomEvent("chat-message-sent", {
|
|
207
|
+
detail: { text },
|
|
208
|
+
bubbles: true,
|
|
209
|
+
composed: true
|
|
210
|
+
})
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
181
214
|
render() {
|
|
182
215
|
return html`
|
|
183
216
|
<div style=${styleMap(rootStyles(this.forceExpanded))}>
|
|
@@ -424,4 +457,4 @@ if (!customElements.get("adaptive-chat-bar")) {
|
|
|
424
457
|
export {
|
|
425
458
|
AdaptiveChatBar
|
|
426
459
|
};
|
|
427
|
-
//# sourceMappingURL=chunk-
|
|
460
|
+
//# sourceMappingURL=chunk-5W75LR6M.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/AdaptiveChatBar.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * AdaptiveChatBar \u2014 the canvas lid composition for the chat-canvas\n * experience. Renders the bubble-up trail on top and an always-visible\n * input row below.\n *\n * Wiring contract (events out):\n * - `chat-message-sent` ({ text }): the user submitted text via Enter\n * or the send button. The owning code is responsible for pushing\n * this into the conversation history and producing a reply.\n *\n * Wiring contract (props in):\n * - `messages`: the conversation trail, passed straight through to\n * `<adaptive-chat-trail>`.\n * - `placeholder`: input placeholder copy. Defaults to a generic\n * \"Ask, find, or navigate\u2026\" \u2014 the host (typically the slot's lid\n * widget mount) can override to a context-specific string.\n *\n * Light DOM. Glassmorphism is applied at the input-row level so the\n * trail above floats over the host page without chrome. See PRD \u00A74.4.\n */\n\nimport { html, LitElement, nothing } from 'lit';\nimport { styleMap } from 'lit/directives/style-map.js';\n\nimport './AdaptiveChatTrail.js';\nimport type {\n InlineTrailWidget,\n InlineWidgetMounter,\n TileReceipt,\n TrailMessage,\n} from './AdaptiveChatTrail.js';\nimport { getElementInstanceStore } from './elements/store-singleton.js';\n\nconst DEFAULT_PLACEHOLDER = 'Ask, find, or navigate\u2026';\nconst DEFAULT_ASSISTANT_NAME = 'Assistant';\n\nexport class AdaptiveChatBar extends LitElement {\n static override properties = {\n messages: { attribute: false },\n placeholder: { type: String },\n assistantName: { type: String },\n greeting: { type: String },\n inFlight: { type: Boolean, reflect: true },\n thinkingText: { attribute: false },\n introSuggestion: { attribute: false },\n forceExpanded: { type: Boolean, reflect: true },\n maximized: { type: Boolean },\n tileReceipts: { attribute: false },\n inlineWidgets: { attribute: false },\n mountInlineWidget: { attribute: false },\n _input: { state: true },\n };\n\n messages: TrailMessage[] = [];\n maximized = false;\n tileReceipts: TileReceipt[] = [];\n /** Widgets rendered inline in the trail (reco carousel), sourced from\n * the store's `chat-inline` slot mounts. Forwarded to the trail. */\n inlineWidgets: InlineTrailWidget[] = [];\n /** Registry-backed mounter for inline widgets whose id is not their\n * custom-element tag (product card, comparison, FAQ). Set by the\n * mountable from `runtime.widgets`; forwarded to the trail. */\n mountInlineWidget: InlineWidgetMounter | undefined = undefined;\n\n /**\n * Live reasoning narration from the model \u2014 streamed in via\n * AG-UI THINKING_TEXT_MESSAGE_CONTENT events and forwarded by\n * the ChatSession subscription on the host (mountable).\n * Forwarded verbatim to the trail, which renders it in place of\n * the silent loading dots between turns. Empty string when no\n * thinking turn is active.\n */\n thinkingText = '';\n /**\n * Pre-conversation suggestion button \u2014 forwarded to the trail's\n * empty-state pane. When the visitor clicks it the trail emits\n * `trail-intro-suggestion`; we catch that here and submit the\n * configured prompt through the normal send path.\n */\n introSuggestion: { label: string; prompt: string } | undefined = undefined;\n\n /** Pass-through to {@link AdaptiveChatTrail}'s ``forceExpanded`` prop.\n * Hosts that mount the chat-bar in a full-screen surface (mobile\n * panel, agent app, etc.) set this to skip the collapse affordance\n * \u2014 there is no smaller state to fall back to. */\n forceExpanded = false;\n placeholder = DEFAULT_PLACEHOLDER;\n /**\n * Name shown in the (forceExpanded) header. Defaults to a generic\n * \"Assistant\". Hosts can override per-workspace (e.g. Vela sets\n * \"Vela Concierge\") without inventing new SDK surface \u2014 it threads\n * through the same mount config the placeholder does.\n */\n assistantName = DEFAULT_ASSISTANT_NAME;\n /**\n * Initial assistant message shown before any real conversation\n * starts. Renders inside the trail as a phantom assistant chip\n * when messages.length === 0; auto-disappears as soon as the\n * first user message lands. Mirrors ChatAssistantLit's greeting.\n */\n greeting: string | undefined = undefined;\n /**\n * Whether a chat round-trip is in flight (request sent, awaiting\n * reply). The single send/stop button morphs accordingly: \u2191 when\n * ready, \u23F9 when in-flight. Parent owns this state \u2014 set true after\n * `chat-message-sent` fires, false when the reply lands or the\n * request is aborted. Enter is inert while in-flight.\n */\n inFlight = false;\n _input = '';\n\n override createRenderRoot(): HTMLElement {\n return this;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Listen on the host element so that `tile-receipt-activate` events\n // dispatched directly on this element (as well as bubbling up from the\n // trail child) are handled in one place.\n this.addEventListener('tile-receipt-activate', this._onTileReceiptActivate);\n this.addEventListener('alert-receipt-activate', this._onAlertReceiptActivate);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('tile-receipt-activate', this._onTileReceiptActivate);\n this.removeEventListener('alert-receipt-activate', this._onAlertReceiptActivate);\n }\n\n // Host-level styling (display, width, height, flex, etc.) is owned\n // by the container \u2014 SDK shadow root provides default rules, panel\n // overrides via design tokens (--sc-chat-bar-host-*). This adaptive\n // never sets inline styles on itself. See SmartCanvasElementLit's\n // static styles for the rule.\n\n private _onInput = (e: Event): void => {\n this._input = (e.target as HTMLInputElement).value;\n };\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n // Enter is the send affordance \u2014 while in-flight there's nothing\n // to send, so it's a no-op. Interrupt requires the explicit\n // \u23F9 click to avoid surprise-aborting on a stray keystroke.\n if (this.inFlight) return;\n this._send();\n }\n };\n\n // Single button. Click delegates to send-or-interrupt based on\n // current state. Same DOM node, different behavior \u2014 discoverability\n // wins from the user not having to scan for which control is active.\n private _onSendOrInterrupt = (): void => {\n if (this.inFlight) {\n // Stop means stop: discard any chip tap queued during this run \u2014\n // otherwise the interrupt flips inFlight false and the queue flush\n // would fire a NEW turn the instant the user pressed stop.\n this._queuedSuggestedReply = null;\n this.dispatchEvent(new CustomEvent('chat-interrupt', { bubbles: true, composed: true }));\n return;\n }\n this._send();\n };\n\n private _onTileReceiptActivate = (e: Event): void => {\n const { instanceId } = (e as CustomEvent<{ instanceId: string }>).detail;\n getElementInstanceStore()?.recreate(instanceId);\n this.dispatchEvent(\n new CustomEvent('tile-recall', { detail: { instanceId }, bubbles: true, composed: true })\n );\n };\n\n private _onAlertReceiptActivate = (e: Event): void => {\n const { instanceId } = (e as CustomEvent<{ instanceId: string }>).detail;\n this.dispatchEvent(\n new CustomEvent('alert-recall', { detail: { instanceId }, bubbles: true, composed: true })\n );\n };\n\n private _onMaximizeToggle = (): void => {\n this.dispatchEvent(new CustomEvent('chat-maximize-toggle', { bubbles: true, composed: true }));\n };\n\n private _send(): void {\n const text = this._input.trim();\n if (!text) return;\n // A typed message is the user's NEWEST intent \u2014 it supersedes any chip\n // tap still queued from the run tail (defense: Enter is currently inert\n // while inFlight, but this guard must not depend on that staying true).\n this._queuedSuggestedReply = null;\n this.dispatchEvent(\n new CustomEvent<{ text: string }>('chat-message-sent', {\n detail: { text },\n bubbles: true,\n composed: true,\n })\n );\n this._input = '';\n // Drop the input value too \u2014 the input's bound value is `this._input`\n // via the render, but jsdom's two-way binding via property only takes\n // effect after the next render, so set it imperatively for the test\n // and for browser symmetry (most browsers do the right thing here\n // anyway because Lit re-renders on the state change).\n const input = this.querySelector<HTMLInputElement>('input[data-chat-input]');\n if (input) input.value = '';\n }\n\n /**\n * Visitor tapped the intro suggestion button in the empty-state\n * trail. Submit the configured prompt through the same channel as\n * a typed message so listeners (mountable \u2192 chatSession.send) see\n * a uniform shape \u2014 no need for a parallel \"suggestion-sent\" path.\n * The trail's intro pane auto-disappears the moment the first\n * message lands, so this also closes the empty state in one go.\n */\n private _onIntroSuggestion = (e: Event): void => {\n const detail = (e as CustomEvent<{ prompt: string }>).detail;\n if (!detail?.prompt) return;\n e.stopPropagation();\n if (this.inFlight) return;\n // Latch in-flight optimistically. `inFlight` is owned by the parent\n // mountable and only pushed back down after it handles\n // `chat-message-sent` + a Lit render cycle. Two taps in the same frame\n // both see inFlight===false otherwise, double-dispatching one intended\n // reply (C3). Set it true synchronously here; the parent confirms/owns\n // it from the next render and clears it when the reply lands.\n this.inFlight = true;\n this.dispatchEvent(\n new CustomEvent<{ text: string }>('chat-message-sent', {\n detail: { text: detail.prompt },\n bubbles: true,\n composed: true,\n })\n );\n };\n\n /**\n * Reply-chip tap that arrived during the run TAIL. Chips render the\n * moment the reply text lands, but `inFlight` (which includes\n * `runActive` \u2014 typing events, tool tail, RUN_FINISHED) can lag for\n * seconds. The old `if (this.inFlight) return;` guard silently ATE\n * those taps \u2014 the visitor's chosen reply never appeared as their\n * message (live repro, deployed vela 2026-07-08). Now the tap queues\n * (latest wins) and dispatches when `inFlight` clears.\n */\n private _queuedSuggestedReply: string | null = null;\n\n protected override willUpdate(changed: Map<string, unknown>): void {\n super.willUpdate?.(changed);\n if (\n changed.has('inFlight') &&\n changed.get('inFlight') === true &&\n !this.inFlight &&\n this._queuedSuggestedReply\n ) {\n const text = this._queuedSuggestedReply;\n this._queuedSuggestedReply = null;\n // Same latch + channel as a direct tap.\n this.inFlight = true;\n this.dispatchEvent(\n new CustomEvent<{ text: string }>('chat-message-sent', {\n detail: { text },\n bubbles: true,\n composed: true,\n })\n );\n }\n }\n\n /**\n * Visitor tapped an inline `suggest_replies` chip in the trail. Submit\n * the chip text through the SAME `chat-message-sent` channel a typed\n * message uses, so the reply rides the existing send path (mountable \u2192\n * chatSession.send \u2192 transport) \u2014 no fabricated AG-UI events. The\n * trail clears the chips on its own once the reply lands and a newer\n * assistant turn becomes the latest.\n *\n * A tap while the previous run is still closing is QUEUED, never\n * dropped \u2014 see `_queuedSuggestedReply`.\n */\n private _onSuggestedReply = (e: Event): void => {\n const detail = (e as CustomEvent<{ text: string }>).detail;\n if (!detail?.text) return;\n e.stopPropagation();\n if (this.inFlight) {\n this._queuedSuggestedReply = detail.text;\n return;\n }\n // Latch in-flight optimistically \u2014 same race as `_onIntroSuggestion`\n // (C3). The parent owns `inFlight` and only re-asserts it after a render\n // cycle, so a same-frame double tap would otherwise fire two\n // `chat-message-sent` events for one chip.\n this.inFlight = true;\n this.dispatchEvent(\n new CustomEvent<{ text: string }>('chat-message-sent', {\n detail: { text: detail.text },\n bubbles: true,\n composed: true,\n })\n );\n };\n\n override render() {\n return html`\n <div style=${styleMap(rootStyles(this.forceExpanded))}>\n ${this.forceExpanded ? renderHeader(this.assistantName) : nothing}\n <adaptive-chat-trail\n .messages=${this.messages}\n .greeting=${this.greeting}\n .forceExpanded=${this.forceExpanded}\n .inFlight=${this.inFlight}\n .thinkingText=${this.thinkingText}\n .introSuggestion=${this.introSuggestion}\n .tileReceipts=${this.tileReceipts}\n .inlineWidgets=${this.inlineWidgets}\n .mountInlineWidget=${this.mountInlineWidget}\n @trail-intro-suggestion=${this._onIntroSuggestion}\n @trail-suggested-reply=${this._onSuggestedReply}\n ></adaptive-chat-trail>\n <div style=${styleMap(rowStyles(this.forceExpanded))} data-chat-row>\n <button\n type=\"button\"\n data-chat-maximize\n @click=${this._onMaximizeToggle}\n aria-label=${this.maximized ? 'Exit full screen' : 'Maximize chat'}\n title=${this.maximized ? 'Normal' : 'Maximize'}\n aria-pressed=${this.maximized ? 'true' : 'false'}\n style=${styleMap(maximizeStyles(this.maximized))}\n >${this.maximized ? '\u2921' : '\u2922'}</button>\n <input\n data-chat-input\n type=\"text\"\n placeholder=${this.placeholder}\n .value=${this._input}\n @input=${this._onInput}\n @keydown=${this._onKeyDown}\n style=${styleMap(inputStyles())}\n aria-label=\"Chat input\"\n />\n <button\n type=\"button\"\n data-chat-send\n data-state=${this.inFlight ? 'in-flight' : 'ready'}\n @click=${this._onSendOrInterrupt}\n aria-label=${this.inFlight ? 'Stop' : 'Send message'}\n title=${this.inFlight ? 'Interrupt' : 'Send'}\n style=${styleMap(sendStyles(this.inFlight))}\n >${this.inFlight ? '\u25A0' : '\u2191'}</button>\n </div>\n </div>\n `;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Styles \u2014 kept inline (Lit styleMap) so they participate in light-DOM\n// rendering and pick up host CSS variables (e.g. --sc-tile-background).\n// ---------------------------------------------------------------------------\n\nfunction rootStyles(forceExpanded: boolean): Record<string, string> {\n // When the host expects the chat to fill its container (full-screen\n // panel, agent app), we grow vertically AND wrap the whole widget in\n // its own chrome card \u2014 trail + input read as one cohesive surface\n // instead of a naked trail above a chrome'd input. Floating mounts\n // (bottom-right pinned, etc.) stay chrome-less here because their\n // chrome is owned by the host's positioned wrapper.\n if (!forceExpanded) {\n return {\n display: 'flex',\n flexDirection: 'column',\n gap: '6px',\n width: '100%',\n pointerEvents: 'auto',\n };\n }\n // Input is ABSOLUTELY positioned at the bottom of this chrome card\n // (see rowStyles forceExpanded mode). That guarantees the input is\n // always visible \u2014 even when the lid region is tighter than the\n // chat-bar would naturally want. The flex column above holds\n // header + trail; padding-bottom reserves the input's footprint so\n // trail content can never overlap.\n //\n // Priority of \"what disappears when space is tight\":\n // Trail (shrinks to 0 first via flex: 1 1 0)\n // Header (can shrink via default flex: 0 1 auto)\n // Input (NEVER \u2014 it's positioned absolute, always at the bottom)\n return {\n position: 'relative',\n display: 'flex',\n flexDirection: 'column',\n gap: '8px',\n width: '100%',\n height: '100%',\n boxSizing: 'border-box',\n flex: '1 1 auto',\n minHeight: '0',\n overflow: 'hidden',\n pointerEvents: 'auto',\n background: 'var(--sc-tile-background, rgba(255, 255, 255, 0.92))',\n border: 'var(--sc-tile-border, 1px solid rgba(0, 0, 0, 0.06))',\n borderRadius: 'var(--sc-tile-border-radius, 14px)',\n boxShadow: 'var(--sc-tile-shadow, 0 12px 32px -16px rgba(0, 0, 0, 0.18))',\n // Reserves room for the absolute-positioned input pill (36px high\n // + 12px from bottom) plus a 16px visual gap above the input.\n padding: '0.75rem 0.75rem calc(36px + 1.75rem)',\n color: 'var(--sc-tile-title-color, inherit)',\n fontFamily: 'var(--sc-font-family, inherit)',\n // Override the trail's host-layout tokens so the trail (a flex item\n // of this column) fills a definite-height parent AND contributes its\n // content height in an indefinite one. basis AUTO (not 0) is\n // load-bearing: grow:1 still fills a full-screen panel, but basis auto\n // also lets the trail's content height propagate up the fill chain so a\n // SHRINK-WRAP host (velvet's bottom sheet) hugs the content with no void.\n // A basis-0 layer anywhere in the chain reports 0 min-content and\n // collapses the sheet to header+input. shrink:1 + min-height:0 still lets\n // the trail yield first when space is tight (input is absolute-pinned).\n // The SDK-level rule in SmartCanvasElementLit consumes these tokens on\n // adaptive-chat-trail's host element. Containers OWN host styling\n // via tokens; the adaptive never sets inline styles on its host.\n ['--sc-chat-trail-host-display']: 'flex',\n ['--sc-chat-trail-host-flex-direction']: 'column',\n ['--sc-chat-trail-host-flex']: '1 1 auto',\n ['--sc-chat-trail-host-min-height']: '0',\n ['--sc-chat-trail-host-overflow']: 'hidden',\n };\n}\n\nfunction rowStyles(forceExpanded: boolean): Record<string, string> {\n // forceExpanded \u2014 root container already carries the chrome; row\n // becomes a flat input-pill inside that chrome (subtle border + soft\n // background, no shadow/blur).\n if (forceExpanded) {\n // Absolute-pinned to the chrome card's bottom edge so it never\n // disappears under any container size. The chrome reserves\n // padding-bottom equal to this row's footprint so flex content\n // above (header + trail) can't overlap.\n return {\n position: 'absolute',\n left: '0.75rem',\n right: '0.75rem',\n bottom: '0.75rem',\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n padding: '6px 14px',\n borderRadius: '9999px',\n background: 'rgba(0, 0, 0, 0.04)',\n border: '1px solid rgba(0, 0, 0, 0.10)',\n color: 'var(--sc-content-text-color, inherit)',\n fontFamily: 'var(--sc-font-family, inherit)',\n minHeight: '36px',\n };\n }\n // Floating mount \u2014 keeps the original tile-chrome look.\n return {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n padding: '10px 12px',\n borderRadius: 'var(--sc-tile-border-radius, 14px)',\n background: 'var(--sc-tile-background, rgba(15, 19, 24, 0.6))',\n backdropFilter: 'var(--sc-chat-bar-blur, blur(24px) saturate(140%))',\n WebkitBackdropFilter: 'var(--sc-chat-bar-blur, blur(24px) saturate(140%))',\n border: 'var(--sc-tile-border, 1px solid rgba(255, 255, 255, 0.08))',\n boxShadow: 'var(--sc-tile-shadow, 0 2px 12px rgba(0, 0, 0, 0.3))',\n color: 'var(--sc-tile-title-color, #fafafa)',\n fontFamily: 'var(--sc-font-family, inherit)',\n };\n}\n\n// Maximize / restore toggle in the chat bar. Legibility matters: the old\n// treatment reused the decorative avatar chip then stripped its background and\n// border and let `font: inherit` shrink the glyph \u2014 leaving a faint, ghosted\n// (0.95-alpha) character that read as \"barely visible\" and gave no visual\n// signal of its on/off state. This mirrors the sibling send button (28px,\n// filled-accent affordance) and makes the ACTIVE (maximized) state a filled\n// chip so the toggle state is obvious at a glance.\nfunction maximizeStyles(maximized: boolean): Record<string, string> {\n return {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '28px',\n height: '28px',\n borderRadius: '9999px',\n // Active (maximized): filled accent chip. Idle: subtle accent chip with a\n // visible ring. Colour is full-opacity in both states (no 0.95 ghosting).\n background: maximized\n ? 'hsl(var(--sc-accent-color) / 0.85)'\n : 'hsl(var(--sc-accent-color) / 0.15)',\n border: maximized ? 'none' : '1px solid hsl(var(--sc-accent-color) / 0.45)',\n color: maximized ? 'var(--sc-accent-foreground, #fff)' : 'hsl(var(--sc-accent-color))',\n flexShrink: '0',\n fontSize: '16px',\n lineHeight: '1',\n padding: '0',\n cursor: 'pointer',\n transition: 'background 150ms ease, color 150ms ease, border-color 150ms ease',\n };\n}\n\nfunction inputStyles(): Record<string, string> {\n return {\n flex: '1',\n minWidth: '0',\n background: 'transparent',\n border: 'none',\n outline: 'none',\n color: 'inherit',\n fontSize: '13px',\n };\n}\n\nfunction sendStyles(inFlight: boolean): Record<string, string> {\n return {\n width: '28px',\n height: '28px',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: '9999px',\n // Ready: filled accent (send is the affordance). In-flight: hollow\n // ring + accent ring (stop is a one-of-a-kind disruptive action,\n // styled differently so the user reads \"this isn't just send\").\n background: inFlight ? 'transparent' : 'hsl(var(--sc-accent-color) / 0.85)',\n color: inFlight ? 'hsl(var(--sc-accent-color) / 0.95)' : 'var(--sc-accent-foreground, #fff)',\n border: inFlight ? '1px solid hsl(var(--sc-accent-color) / 0.55)' : 'none',\n cursor: 'pointer',\n flexShrink: '0',\n transition: 'background 150ms ease, color 150ms ease, border-color 150ms ease',\n };\n}\n\n/**\n * Compact single-line chat header. Prior version stacked the name over a\n * two-line status block inside a flex-column wrapper with a 28px avatar and\n * `padding: 4px 4px 12px`, which wasted a lot of vertical space (user\n * feedback: \"bad use of vertical space\"). This is now ONE inline row \u2014\n * small avatar dot \u00B7 name \u00B7 live-status dot \u00B7 short status \u2014 at roughly half\n * the height. All surfaces share this chrome.\n */\nfunction renderHeader(assistantName: string) {\n const headerStyles: Record<string, string> = {\n display: 'flex',\n alignItems: 'center',\n gap: '7px',\n // Halved vertical footprint: 6px total block padding vs the old 16px\n // (4px top + 12px bottom). Horizontal padding unchanged.\n padding: '3px 4px',\n borderBottom: '1px solid var(--sc-content-divider-color, rgba(0, 0, 0, 0.08))',\n flex: '0 0 auto',\n };\n // Small brand dot \u2014 shrunk from a 28px avatar to a 16px chip so the\n // whole header collapses to a single text line. Still tracks the\n // workspace brand primary so it matches the rest of the canvas chrome.\n const avatar: Record<string, string> = {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '16px',\n height: '16px',\n borderRadius: '9999px',\n background:\n 'var(--sc-tile-icon-background, linear-gradient(135deg, var(--sc-color-primary, #5faf7d) 0%, var(--sc-color-primary-hover, #3d8a5e) 100%))',\n color: '#fff',\n flexShrink: '0',\n fontSize: '9px',\n lineHeight: '1',\n };\n const name: Record<string, string> = {\n fontSize: '0.8rem',\n fontWeight: '600',\n color: 'var(--sc-content-text-color, inherit)',\n lineHeight: '1.2',\n flexShrink: '0',\n };\n // No status line or presence dot (\"Online \u00B7 understands your session\") \u2014\n // user feedback: that's chrome a visitor doesn't need. Avatar + name only.\n return html`\n <div style=${styleMap(headerStyles)} data-chat-header>\n <span style=${styleMap(avatar)} aria-hidden=\"true\">\u2726</span>\n <span style=${styleMap(name)}>${assistantName}</span>\n </div>\n `;\n}\n\nif (!customElements.get('adaptive-chat-bar')) {\n customElements.define('adaptive-chat-bar', AdaptiveChatBar);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'adaptive-chat-bar': AdaptiveChatBar;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/runtime.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/AdaptiveChatBar.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * AdaptiveChatBar \u2014 the canvas lid composition for the chat-canvas\n * experience. Renders the bubble-up trail on top and an always-visible\n * input row below.\n *\n * Wiring contract (events out):\n * - `chat-message-sent` ({ text }): the user submitted text via Enter\n * or the send button. The owning code is responsible for pushing\n * this into the conversation history and producing a reply.\n *\n * Wiring contract (props in):\n * - `messages`: the conversation trail, passed straight through to\n * `<adaptive-chat-trail>`.\n * - `placeholder`: input placeholder copy. Defaults to a generic\n * \"Ask, find, or navigate\u2026\" \u2014 the host (typically the slot's lid\n * widget mount) can override to a context-specific string.\n *\n * Light DOM. Glassmorphism is applied at the input-row level so the\n * trail above floats over the host page without chrome. See PRD \u00A74.4.\n */\n\nimport { html, LitElement, nothing } from 'lit';\nimport { styleMap } from 'lit/directives/style-map.js';\n\nimport './AdaptiveChatTrail.js';\nimport type {\n InlineTrailWidget,\n InlineWidgetMounter,\n TileReceipt,\n TrailMessage,\n} from './AdaptiveChatTrail.js';\nimport { getElementInstanceStore } from './elements/store-singleton.js';\n\nconst DEFAULT_PLACEHOLDER = 'Ask, find, or navigate\u2026';\nconst DEFAULT_ASSISTANT_NAME = 'Assistant';\n\nexport class AdaptiveChatBar extends LitElement {\n static override properties = {\n messages: { attribute: false },\n placeholder: { type: String },\n assistantName: { type: String },\n greeting: { type: String },\n inFlight: { type: Boolean, reflect: true },\n thinkingText: { attribute: false },\n introSuggestion: { attribute: false },\n forceExpanded: { type: Boolean, reflect: true },\n maximized: { type: Boolean },\n tileReceipts: { attribute: false },\n inlineWidgets: { attribute: false },\n mountInlineWidget: { attribute: false },\n _input: { state: true },\n };\n\n messages: TrailMessage[] = [];\n maximized = false;\n tileReceipts: TileReceipt[] = [];\n /** Widgets rendered inline in the trail (reco carousel), sourced from\n * the store's `chat-inline` slot mounts. Forwarded to the trail. */\n inlineWidgets: InlineTrailWidget[] = [];\n /** Registry-backed mounter for inline widgets whose id is not their\n * custom-element tag (product card, comparison, FAQ). Set by the\n * mountable from `runtime.widgets`; forwarded to the trail. */\n mountInlineWidget: InlineWidgetMounter | undefined = undefined;\n\n /**\n * Live reasoning narration from the model \u2014 streamed in via\n * AG-UI THINKING_TEXT_MESSAGE_CONTENT events and forwarded by\n * the ChatSession subscription on the host (mountable).\n * Forwarded verbatim to the trail, which renders it in place of\n * the silent loading dots between turns. Empty string when no\n * thinking turn is active.\n */\n thinkingText = '';\n /**\n * Pre-conversation suggestion button \u2014 forwarded to the trail's\n * empty-state pane. When the visitor clicks it the trail emits\n * `trail-intro-suggestion`; we catch that here and submit the\n * configured prompt through the normal send path.\n */\n introSuggestion: { label: string; prompt: string } | undefined = undefined;\n\n /** Pass-through to {@link AdaptiveChatTrail}'s ``forceExpanded`` prop.\n * Hosts that mount the chat-bar in a full-screen surface (mobile\n * panel, agent app, etc.) set this to skip the collapse affordance\n * \u2014 there is no smaller state to fall back to. */\n forceExpanded = false;\n placeholder = DEFAULT_PLACEHOLDER;\n /**\n * Name shown in the (forceExpanded) header. Defaults to a generic\n * \"Assistant\". Hosts can override per-workspace (e.g. Vela sets\n * \"Vela Concierge\") without inventing new SDK surface \u2014 it threads\n * through the same mount config the placeholder does.\n */\n assistantName = DEFAULT_ASSISTANT_NAME;\n /**\n * Initial assistant message shown before any real conversation\n * starts. Renders inside the trail as a phantom assistant chip\n * when messages.length === 0; auto-disappears as soon as the\n * first user message lands. Mirrors ChatAssistantLit's greeting.\n */\n greeting: string | undefined = undefined;\n /**\n * Whether a chat round-trip is in flight (request sent, awaiting\n * reply). The single send/stop button morphs accordingly: \u2191 when\n * ready, \u23F9 when in-flight. Parent owns this state \u2014 set true after\n * `chat-message-sent` fires, false when the reply lands or the\n * request is aborted. Enter is inert while in-flight.\n */\n inFlight = false;\n _input = '';\n\n override createRenderRoot(): HTMLElement {\n return this;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Listen on the host element so that `tile-receipt-activate` events\n // dispatched directly on this element (as well as bubbling up from the\n // trail child) are handled in one place.\n this.addEventListener('tile-receipt-activate', this._onTileReceiptActivate);\n this.addEventListener('alert-receipt-activate', this._onAlertReceiptActivate);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('tile-receipt-activate', this._onTileReceiptActivate);\n this.removeEventListener('alert-receipt-activate', this._onAlertReceiptActivate);\n }\n\n // Host-level styling (display, width, height, flex, etc.) is owned\n // by the container \u2014 SDK shadow root provides default rules, panel\n // overrides via design tokens (--sc-chat-bar-host-*). This adaptive\n // never sets inline styles on itself. See SmartCanvasElementLit's\n // static styles for the rule.\n\n private _onInput = (e: Event): void => {\n this._input = (e.target as HTMLInputElement).value;\n };\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n // Enter is the send affordance \u2014 while in-flight there's nothing\n // to send, so it's a no-op. Interrupt requires the explicit\n // \u23F9 click to avoid surprise-aborting on a stray keystroke.\n if (this.inFlight) return;\n this._send();\n }\n };\n\n // Single button. Click delegates to send-or-interrupt based on\n // current state. Same DOM node, different behavior \u2014 discoverability\n // wins from the user not having to scan for which control is active.\n private _onSendOrInterrupt = (): void => {\n if (this.inFlight) {\n this.dispatchEvent(new CustomEvent('chat-interrupt', { bubbles: true, composed: true }));\n return;\n }\n this._send();\n };\n\n private _onTileReceiptActivate = (e: Event): void => {\n const { instanceId } = (e as CustomEvent<{ instanceId: string }>).detail;\n getElementInstanceStore()?.recreate(instanceId);\n this.dispatchEvent(\n new CustomEvent('tile-recall', { detail: { instanceId }, bubbles: true, composed: true })\n );\n };\n\n private _onAlertReceiptActivate = (e: Event): void => {\n const { instanceId } = (e as CustomEvent<{ instanceId: string }>).detail;\n this.dispatchEvent(\n new CustomEvent('alert-recall', { detail: { instanceId }, bubbles: true, composed: true })\n );\n };\n\n private _onMaximizeToggle = (): void => {\n this.dispatchEvent(new CustomEvent('chat-maximize-toggle', { bubbles: true, composed: true }));\n };\n\n private _send(): void {\n const text = this._input.trim();\n if (!text) return;\n this.dispatchEvent(\n new CustomEvent<{ text: string }>('chat-message-sent', {\n detail: { text },\n bubbles: true,\n composed: true,\n })\n );\n this._input = '';\n // Drop the input value too \u2014 the input's bound value is `this._input`\n // via the render, but jsdom's two-way binding via property only takes\n // effect after the next render, so set it imperatively for the test\n // and for browser symmetry (most browsers do the right thing here\n // anyway because Lit re-renders on the state change).\n const input = this.querySelector<HTMLInputElement>('input[data-chat-input]');\n if (input) input.value = '';\n }\n\n /**\n * Visitor tapped the intro suggestion button in the empty-state\n * trail. Submit the configured prompt through the same channel as\n * a typed message so listeners (mountable \u2192 chatSession.send) see\n * a uniform shape \u2014 no need for a parallel \"suggestion-sent\" path.\n * The trail's intro pane auto-disappears the moment the first\n * message lands, so this also closes the empty state in one go.\n */\n private _onIntroSuggestion = (e: Event): void => {\n const detail = (e as CustomEvent<{ prompt: string }>).detail;\n if (!detail?.prompt) return;\n e.stopPropagation();\n if (this.inFlight) return;\n // Latch in-flight optimistically. `inFlight` is owned by the parent\n // mountable and only pushed back down after it handles\n // `chat-message-sent` + a Lit render cycle. Two taps in the same frame\n // both see inFlight===false otherwise, double-dispatching one intended\n // reply (C3). Set it true synchronously here; the parent confirms/owns\n // it from the next render and clears it when the reply lands.\n this.inFlight = true;\n this.dispatchEvent(\n new CustomEvent<{ text: string }>('chat-message-sent', {\n detail: { text: detail.prompt },\n bubbles: true,\n composed: true,\n })\n );\n };\n\n /**\n * Visitor tapped an inline `suggest_replies` chip in the trail. Submit\n * the chip text through the SAME `chat-message-sent` channel a typed\n * message uses, so the reply rides the existing send path (mountable \u2192\n * chatSession.send \u2192 transport) \u2014 no fabricated AG-UI events. The\n * trail clears the chips on its own once the reply lands and a newer\n * assistant turn becomes the latest.\n */\n private _onSuggestedReply = (e: Event): void => {\n const detail = (e as CustomEvent<{ text: string }>).detail;\n if (!detail?.text) return;\n e.stopPropagation();\n if (this.inFlight) return;\n // Latch in-flight optimistically \u2014 same race as `_onIntroSuggestion`\n // (C3). The parent owns `inFlight` and only re-asserts it after a render\n // cycle, so a same-frame double tap would otherwise fire two\n // `chat-message-sent` events for one chip.\n this.inFlight = true;\n this.dispatchEvent(\n new CustomEvent<{ text: string }>('chat-message-sent', {\n detail: { text: detail.text },\n bubbles: true,\n composed: true,\n })\n );\n };\n\n override render() {\n return html`\n <div style=${styleMap(rootStyles(this.forceExpanded))}>\n ${this.forceExpanded ? renderHeader(this.assistantName) : nothing}\n <adaptive-chat-trail\n .messages=${this.messages}\n .greeting=${this.greeting}\n .forceExpanded=${this.forceExpanded}\n .inFlight=${this.inFlight}\n .thinkingText=${this.thinkingText}\n .introSuggestion=${this.introSuggestion}\n .tileReceipts=${this.tileReceipts}\n .inlineWidgets=${this.inlineWidgets}\n .mountInlineWidget=${this.mountInlineWidget}\n @trail-intro-suggestion=${this._onIntroSuggestion}\n @trail-suggested-reply=${this._onSuggestedReply}\n ></adaptive-chat-trail>\n <div style=${styleMap(rowStyles(this.forceExpanded))} data-chat-row>\n <button\n type=\"button\"\n data-chat-maximize\n @click=${this._onMaximizeToggle}\n aria-label=${this.maximized ? 'Exit full screen' : 'Maximize chat'}\n title=${this.maximized ? 'Normal' : 'Maximize'}\n aria-pressed=${this.maximized ? 'true' : 'false'}\n style=${styleMap(maximizeStyles(this.maximized))}\n >${this.maximized ? '\u2921' : '\u2922'}</button>\n <input\n data-chat-input\n type=\"text\"\n placeholder=${this.placeholder}\n .value=${this._input}\n @input=${this._onInput}\n @keydown=${this._onKeyDown}\n style=${styleMap(inputStyles())}\n aria-label=\"Chat input\"\n />\n <button\n type=\"button\"\n data-chat-send\n data-state=${this.inFlight ? 'in-flight' : 'ready'}\n @click=${this._onSendOrInterrupt}\n aria-label=${this.inFlight ? 'Stop' : 'Send message'}\n title=${this.inFlight ? 'Interrupt' : 'Send'}\n style=${styleMap(sendStyles(this.inFlight))}\n >${this.inFlight ? '\u25A0' : '\u2191'}</button>\n </div>\n </div>\n `;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Styles \u2014 kept inline (Lit styleMap) so they participate in light-DOM\n// rendering and pick up host CSS variables (e.g. --sc-tile-background).\n// ---------------------------------------------------------------------------\n\nfunction rootStyles(forceExpanded: boolean): Record<string, string> {\n // When the host expects the chat to fill its container (full-screen\n // panel, agent app), we grow vertically AND wrap the whole widget in\n // its own chrome card \u2014 trail + input read as one cohesive surface\n // instead of a naked trail above a chrome'd input. Floating mounts\n // (bottom-right pinned, etc.) stay chrome-less here because their\n // chrome is owned by the host's positioned wrapper.\n if (!forceExpanded) {\n return {\n display: 'flex',\n flexDirection: 'column',\n gap: '6px',\n width: '100%',\n pointerEvents: 'auto',\n };\n }\n // Input is ABSOLUTELY positioned at the bottom of this chrome card\n // (see rowStyles forceExpanded mode). That guarantees the input is\n // always visible \u2014 even when the lid region is tighter than the\n // chat-bar would naturally want. The flex column above holds\n // header + trail; padding-bottom reserves the input's footprint so\n // trail content can never overlap.\n //\n // Priority of \"what disappears when space is tight\":\n // Trail (shrinks to 0 first via flex: 1 1 0)\n // Header (can shrink via default flex: 0 1 auto)\n // Input (NEVER \u2014 it's positioned absolute, always at the bottom)\n return {\n position: 'relative',\n display: 'flex',\n flexDirection: 'column',\n gap: '8px',\n width: '100%',\n height: '100%',\n boxSizing: 'border-box',\n flex: '1 1 auto',\n minHeight: '0',\n overflow: 'hidden',\n pointerEvents: 'auto',\n background: 'var(--sc-tile-background, rgba(255, 255, 255, 0.92))',\n border: 'var(--sc-tile-border, 1px solid rgba(0, 0, 0, 0.06))',\n borderRadius: 'var(--sc-tile-border-radius, 14px)',\n boxShadow: 'var(--sc-tile-shadow, 0 12px 32px -16px rgba(0, 0, 0, 0.18))',\n // Reserves room for the absolute-positioned input pill (36px high\n // + 12px from bottom) plus a 16px visual gap above the input.\n padding: '0.75rem 0.75rem calc(36px + 1.75rem)',\n color: 'var(--sc-tile-title-color, inherit)',\n fontFamily: 'var(--sc-font-family, inherit)',\n // Override the trail's host-layout tokens so the trail (a flex item\n // of this column) fills a definite-height parent AND contributes its\n // content height in an indefinite one. basis AUTO (not 0) is\n // load-bearing: grow:1 still fills a full-screen panel, but basis auto\n // also lets the trail's content height propagate up the fill chain so a\n // SHRINK-WRAP host (velvet's bottom sheet) hugs the content with no void.\n // A basis-0 layer anywhere in the chain reports 0 min-content and\n // collapses the sheet to header+input. shrink:1 + min-height:0 still lets\n // the trail yield first when space is tight (input is absolute-pinned).\n // The SDK-level rule in SmartCanvasElementLit consumes these tokens on\n // adaptive-chat-trail's host element. Containers OWN host styling\n // via tokens; the adaptive never sets inline styles on its host.\n ['--sc-chat-trail-host-display']: 'flex',\n ['--sc-chat-trail-host-flex-direction']: 'column',\n ['--sc-chat-trail-host-flex']: '1 1 auto',\n ['--sc-chat-trail-host-min-height']: '0',\n ['--sc-chat-trail-host-overflow']: 'hidden',\n };\n}\n\nfunction rowStyles(forceExpanded: boolean): Record<string, string> {\n // forceExpanded \u2014 root container already carries the chrome; row\n // becomes a flat input-pill inside that chrome (subtle border + soft\n // background, no shadow/blur).\n if (forceExpanded) {\n // Absolute-pinned to the chrome card's bottom edge so it never\n // disappears under any container size. The chrome reserves\n // padding-bottom equal to this row's footprint so flex content\n // above (header + trail) can't overlap.\n return {\n position: 'absolute',\n left: '0.75rem',\n right: '0.75rem',\n bottom: '0.75rem',\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n padding: '6px 14px',\n borderRadius: '9999px',\n background: 'rgba(0, 0, 0, 0.04)',\n border: '1px solid rgba(0, 0, 0, 0.10)',\n color: 'var(--sc-content-text-color, inherit)',\n fontFamily: 'var(--sc-font-family, inherit)',\n minHeight: '36px',\n };\n }\n // Floating mount \u2014 keeps the original tile-chrome look.\n return {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n padding: '10px 12px',\n borderRadius: 'var(--sc-tile-border-radius, 14px)',\n background: 'var(--sc-tile-background, rgba(15, 19, 24, 0.6))',\n backdropFilter: 'var(--sc-chat-bar-blur, blur(24px) saturate(140%))',\n WebkitBackdropFilter: 'var(--sc-chat-bar-blur, blur(24px) saturate(140%))',\n border: 'var(--sc-tile-border, 1px solid rgba(255, 255, 255, 0.08))',\n boxShadow: 'var(--sc-tile-shadow, 0 2px 12px rgba(0, 0, 0, 0.3))',\n color: 'var(--sc-tile-title-color, #fafafa)',\n fontFamily: 'var(--sc-font-family, inherit)',\n };\n}\n\n// Maximize / restore toggle in the chat bar. Legibility matters: the old\n// treatment reused the decorative avatar chip then stripped its background and\n// border and let `font: inherit` shrink the glyph \u2014 leaving a faint, ghosted\n// (0.95-alpha) character that read as \"barely visible\" and gave no visual\n// signal of its on/off state. This mirrors the sibling send button (28px,\n// filled-accent affordance) and makes the ACTIVE (maximized) state a filled\n// chip so the toggle state is obvious at a glance.\nfunction maximizeStyles(maximized: boolean): Record<string, string> {\n return {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '28px',\n height: '28px',\n borderRadius: '9999px',\n // Active (maximized): filled accent chip. Idle: subtle accent chip with a\n // visible ring. Colour is full-opacity in both states (no 0.95 ghosting).\n background: maximized\n ? 'hsl(var(--sc-accent-color) / 0.85)'\n : 'hsl(var(--sc-accent-color) / 0.15)',\n border: maximized ? 'none' : '1px solid hsl(var(--sc-accent-color) / 0.45)',\n color: maximized ? 'var(--sc-accent-foreground, #fff)' : 'hsl(var(--sc-accent-color))',\n flexShrink: '0',\n fontSize: '16px',\n lineHeight: '1',\n padding: '0',\n cursor: 'pointer',\n transition: 'background 150ms ease, color 150ms ease, border-color 150ms ease',\n };\n}\n\nfunction inputStyles(): Record<string, string> {\n return {\n flex: '1',\n minWidth: '0',\n background: 'transparent',\n border: 'none',\n outline: 'none',\n color: 'inherit',\n fontSize: '13px',\n };\n}\n\nfunction sendStyles(inFlight: boolean): Record<string, string> {\n return {\n width: '28px',\n height: '28px',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: '9999px',\n // Ready: filled accent (send is the affordance). In-flight: hollow\n // ring + accent ring (stop is a one-of-a-kind disruptive action,\n // styled differently so the user reads \"this isn't just send\").\n background: inFlight ? 'transparent' : 'hsl(var(--sc-accent-color) / 0.85)',\n color: inFlight ? 'hsl(var(--sc-accent-color) / 0.95)' : 'var(--sc-accent-foreground, #fff)',\n border: inFlight ? '1px solid hsl(var(--sc-accent-color) / 0.55)' : 'none',\n cursor: 'pointer',\n flexShrink: '0',\n transition: 'background 150ms ease, color 150ms ease, border-color 150ms ease',\n };\n}\n\n/**\n * Compact single-line chat header. Prior version stacked the name over a\n * two-line status block inside a flex-column wrapper with a 28px avatar and\n * `padding: 4px 4px 12px`, which wasted a lot of vertical space (user\n * feedback: \"bad use of vertical space\"). This is now ONE inline row \u2014\n * small avatar dot \u00B7 name \u00B7 live-status dot \u00B7 short status \u2014 at roughly half\n * the height. All surfaces share this chrome.\n */\nfunction renderHeader(assistantName: string) {\n const headerStyles: Record<string, string> = {\n display: 'flex',\n alignItems: 'center',\n gap: '7px',\n // Halved vertical footprint: 6px total block padding vs the old 16px\n // (4px top + 12px bottom). Horizontal padding unchanged.\n padding: '3px 4px',\n borderBottom: '1px solid var(--sc-content-divider-color, rgba(0, 0, 0, 0.08))',\n flex: '0 0 auto',\n };\n // Small brand dot \u2014 shrunk from a 28px avatar to a 16px chip so the\n // whole header collapses to a single text line. Still tracks the\n // workspace brand primary so it matches the rest of the canvas chrome.\n const avatar: Record<string, string> = {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '16px',\n height: '16px',\n borderRadius: '9999px',\n background:\n 'var(--sc-tile-icon-background, linear-gradient(135deg, var(--sc-color-primary, #5faf7d) 0%, var(--sc-color-primary-hover, #3d8a5e) 100%))',\n color: '#fff',\n flexShrink: '0',\n fontSize: '9px',\n lineHeight: '1',\n };\n const name: Record<string, string> = {\n fontSize: '0.8rem',\n fontWeight: '600',\n color: 'var(--sc-content-text-color, inherit)',\n lineHeight: '1.2',\n flexShrink: '0',\n };\n // No status line or presence dot (\"Online \u00B7 understands your session\") \u2014\n // user feedback: that's chrome a visitor doesn't need. Avatar + name only.\n return html`\n <div style=${styleMap(headerStyles)} data-chat-header>\n <span style=${styleMap(avatar)} aria-hidden=\"true\">\u2726</span>\n <span style=${styleMap(name)}>${assistantName}</span>\n </div>\n `;\n}\n\nif (!customElements.get('adaptive-chat-bar')) {\n customElements.define('adaptive-chat-bar', AdaptiveChatBar);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'adaptive-chat-bar': AdaptiveChatBar;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|