@artooi/ag-ui-web-component 0.7.0 → 0.8.1
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 +41 -1
- package/README.md +46 -9
- package/dist/ag-ui-web-component.bundle.js +148 -11
- package/dist/ag-ui-web-component.bundle.js.map +3 -3
- package/dist/constants.d.ts +5 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/core/ag_ui_chat.d.ts +4 -0
- package/dist/core/ag_ui_chat.d.ts.map +1 -1
- package/dist/index.js +190 -10
- package/dist/index.js.map +2 -2
- package/dist/ui/styles.d.ts +1 -1
- package/dist/ui/styles.d.ts.map +1 -1
- package/dist/ui/tool_call_card.d.ts +13 -6
- package/dist/ui/tool_call_card.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +5 -0
- package/src/core/ag_ui_chat.ts +54 -5
- package/src/ui/styles.ts +137 -0
- package/src/ui/tool_call_card.ts +23 -8
- package/src/version.ts +1 -1
package/dist/constants.d.ts
CHANGED
|
@@ -77,12 +77,17 @@ export declare const DEFAULT_ATTACHMENT_MAX_BYTES: number;
|
|
|
77
77
|
* How much detail a tool-call card shows. Set via the `data-tool-display`
|
|
78
78
|
* attribute on `<ag-ui-chat>`; defaults to `full` (back-compatible).
|
|
79
79
|
*
|
|
80
|
+
* - `inline` — the lightest mode: a single status row (icon + summary) with no
|
|
81
|
+
* surrounding card chrome, the result tucked behind its own toggle. Reads as
|
|
82
|
+
* one line of the answer rather than a boxed card — pairs with the answer
|
|
83
|
+
* well (page mode).
|
|
80
84
|
* - `minimal` — just the tool name + status pill. No args, no result body.
|
|
81
85
|
* - `compact` — name + status, with args *and* result tucked behind a single
|
|
82
86
|
* collapsed "Details" toggle. The light default for dense UIs.
|
|
83
87
|
* - `full` — args shown inline, result behind its own toggle (the original).
|
|
84
88
|
*/
|
|
85
89
|
export declare const TOOL_DISPLAY: {
|
|
90
|
+
readonly INLINE: "inline";
|
|
86
91
|
readonly MINIMAL: "minimal";
|
|
87
92
|
readonly COMPACT: "compact";
|
|
88
93
|
readonly FULL: "full";
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAGA,wEAAwE;AACxE,eAAO,MAAM,WAAW,eAAe,CAAC;AAExC;;;;GAIG;AACH,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C;;;;;GAKG;AACH,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C,qCAAqC;AACrC,eAAO,MAAM,YAAY;;;CAGf,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,kBAAkB,CAAC;AAEjD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,cAAc,CAAC;AAEzC;;;;GAIG;AACH,eAAO,MAAM,aAAa,cAAc,CAAC;AAEzC;;;;;GAKG;AACH,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C,yEAAyE;AACzE,eAAO,MAAM,eAAe,KAAK,CAAC;AAElC;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;;;CAKnB,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;;CAIpB,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,QAAmB,CAAC;AAE7D
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAGA,wEAAwE;AACxE,eAAO,MAAM,WAAW,eAAe,CAAC;AAExC;;;;GAIG;AACH,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C;;;;;GAKG;AACH,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C,qCAAqC;AACrC,eAAO,MAAM,YAAY;;;CAGf,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,kBAAkB,CAAC;AAEjD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,cAAc,CAAC;AAEzC;;;;GAIG;AACH,eAAO,MAAM,aAAa,cAAc,CAAC;AAEzC;;;;;GAKG;AACH,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C,yEAAyE;AACzE,eAAO,MAAM,eAAe,KAAK,CAAC;AAElC;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;;;CAKnB,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;;CAIpB,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,QAAmB,CAAC;AAE7D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,YAAY;;;;;CAKf,CAAC"}
|
|
@@ -184,6 +184,10 @@ export declare class AgUiChat extends HTMLElement {
|
|
|
184
184
|
* Assistant content is rendered as sanitised markdown/HTML; user content
|
|
185
185
|
* stays literal text (no need to parse what the user typed, and it avoids
|
|
186
186
|
* rendering user-authored markup).
|
|
187
|
+
*
|
|
188
|
+
* Assistant bubbles land in the current answer group (WELL-1), opening one if
|
|
189
|
+
* needed; a user bubble closes the prior group and sits directly in the list
|
|
190
|
+
* (the well wraps the *assistant* turn, the user message precedes it).
|
|
187
191
|
*/
|
|
188
192
|
appendMessage(role: MessageRole, content: string): HTMLDivElement;
|
|
189
193
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ag_ui_chat.d.ts","sourceRoot":"","sources":["../../src/core/ag_ui_chat.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ag_ui_chat.d.ts","sourceRoot":"","sources":["../../src/core/ag_ui_chat.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -24,6 +24,7 @@ var ATTACHMENT_STATUS = {
|
|
|
24
24
|
};
|
|
25
25
|
var DEFAULT_ATTACHMENT_MAX_BYTES = 10 * 1024 * 1024;
|
|
26
26
|
var TOOL_DISPLAY = {
|
|
27
|
+
INLINE: "inline",
|
|
27
28
|
MINIMAL: "minimal",
|
|
28
29
|
COMPACT: "compact",
|
|
29
30
|
FULL: "full"
|
|
@@ -3488,6 +3489,17 @@ var STYLES = `
|
|
|
3488
3489
|
--ag-ui-danger: #b91c1c;
|
|
3489
3490
|
--ag-ui-muted: #6b7280;
|
|
3490
3491
|
|
|
3492
|
+
/* Tool-call status icon glyphs (override to re-theme) + spinner speed.
|
|
3493
|
+
The pending state is the animated ring; the settled states use these. */
|
|
3494
|
+
--ag-ui-tool-icon-done: "\u2713";
|
|
3495
|
+
--ag-ui-tool-icon-error: "\u2715";
|
|
3496
|
+
--ag-ui-tool-icon-declined: "\u2298";
|
|
3497
|
+
--ag-ui-tool-spin-duration: 0.7s;
|
|
3498
|
+
|
|
3499
|
+
/* Answer well (opt-in via data-answer-well) \u2014 boxes a whole assistant turn. */
|
|
3500
|
+
--ag-ui-well-bg: transparent;
|
|
3501
|
+
--ag-ui-well-border: var(--ag-ui-border);
|
|
3502
|
+
|
|
3491
3503
|
/* Surface \u2014 set --ag-ui-shadow: none for a flush, embedded panel. */
|
|
3492
3504
|
--ag-ui-shadow: 0 12px 32px rgba(20, 20, 50, 0.18);
|
|
3493
3505
|
--ag-ui-font: inherit;
|
|
@@ -3510,6 +3522,8 @@ var STYLES = `
|
|
|
3510
3522
|
--ag-ui-inset: auto 24px 24px auto;
|
|
3511
3523
|
--ag-ui-max-width: calc(100vw - 48px);
|
|
3512
3524
|
--ag-ui-max-height: calc(100vh - 48px);
|
|
3525
|
+
/* Reading-column width for placement="page" (full-bleed, centred content). */
|
|
3526
|
+
--ag-ui-content-max-width: 820px;
|
|
3513
3527
|
|
|
3514
3528
|
position: var(--ag-ui-position);
|
|
3515
3529
|
inset: var(--ag-ui-inset);
|
|
@@ -3597,6 +3611,48 @@ var STYLES = `
|
|
|
3597
3611
|
--ag-ui-radius: 0;
|
|
3598
3612
|
}
|
|
3599
3613
|
|
|
3614
|
+
/* Page (PAGE-1): full-bleed background with a centred reading column. Unlike
|
|
3615
|
+
"full" (edge-to-edge, left-aligned messages) the content sits in a column
|
|
3616
|
+
capped at --ag-ui-content-max-width. The column is produced by symmetric auto
|
|
3617
|
+
padding on the scroll area + composer (no per-row wrapper), so user pills
|
|
3618
|
+
still right-align and the assistant well spans the column. */
|
|
3619
|
+
:host([placement="page"]) {
|
|
3620
|
+
--ag-ui-inset: 0;
|
|
3621
|
+
--ag-ui-width: 100vw;
|
|
3622
|
+
--ag-ui-height: 100vh;
|
|
3623
|
+
--ag-ui-max-width: 100vw;
|
|
3624
|
+
--ag-ui-max-height: 100vh;
|
|
3625
|
+
--ag-ui-radius: 0;
|
|
3626
|
+
}
|
|
3627
|
+
|
|
3628
|
+
:host([placement="page"]) .messages {
|
|
3629
|
+
padding-inline: max(var(--ag-ui-pad), calc((100% - var(--ag-ui-content-max-width)) / 2));
|
|
3630
|
+
}
|
|
3631
|
+
|
|
3632
|
+
:host([placement="page"]) .input-row {
|
|
3633
|
+
padding-inline: max(12px, calc((100% - var(--ag-ui-content-max-width)) / 2));
|
|
3634
|
+
}
|
|
3635
|
+
|
|
3636
|
+
/* The rows between the message list and the composer (skill chips, the
|
|
3637
|
+
/-command palette, the missing-placeholder hint, the upload tray) line up
|
|
3638
|
+
with the column too \u2014 chips are padding-based, the palette/hint/tray are
|
|
3639
|
+
margin-based, so each gets its own inline axis nudged by the same gutter. */
|
|
3640
|
+
:host([placement="page"]) .skill-chips,
|
|
3641
|
+
:host([placement="page"]) .attachment-tray {
|
|
3642
|
+
padding-inline: max(12px, calc((100% - var(--ag-ui-content-max-width)) / 2));
|
|
3643
|
+
}
|
|
3644
|
+
|
|
3645
|
+
:host([placement="page"]) .skill-palette,
|
|
3646
|
+
:host([placement="page"]) .skill-hint {
|
|
3647
|
+
margin-inline: max(12px, calc((100% - var(--ag-ui-content-max-width)) / 2));
|
|
3648
|
+
}
|
|
3649
|
+
|
|
3650
|
+
/* In the reading column the assistant well uses the full width; the user
|
|
3651
|
+
message stays a right-aligned pill (its default align-self + max-width). */
|
|
3652
|
+
:host([placement="page"]) .message--assistant {
|
|
3653
|
+
max-width: 100%;
|
|
3654
|
+
}
|
|
3655
|
+
|
|
3600
3656
|
/* Sidebar (CUST-3): a full-height docked panel that slides open/closed and
|
|
3601
3657
|
collapses to a slim icon rail (not the floating launcher). Docked right by
|
|
3602
3658
|
default; data-side="left" docks it left. Overlay by default \u2014 set
|
|
@@ -3793,6 +3849,27 @@ var STYLES = `
|
|
|
3793
3849
|
display: none;
|
|
3794
3850
|
}
|
|
3795
3851
|
|
|
3852
|
+
/* \u2500\u2500 Answer group / well (WELL-1) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
3853
|
+
One .answer per assistant turn wraps the streamed text, its tool cards,
|
|
3854
|
+
and the pending indicator so a whole answer reads (and can be boxed) as one
|
|
3855
|
+
unit. A flex column on the message-list gap, stretched to the list width so
|
|
3856
|
+
its children keep their own left/right alignment. data-answer-well opts into
|
|
3857
|
+
the bordered "well"; without it the layout is today's flat stack. */
|
|
3858
|
+
.answer {
|
|
3859
|
+
display: flex;
|
|
3860
|
+
flex-direction: column;
|
|
3861
|
+
gap: var(--ag-ui-space);
|
|
3862
|
+
align-self: stretch;
|
|
3863
|
+
min-width: 0;
|
|
3864
|
+
}
|
|
3865
|
+
|
|
3866
|
+
:host([data-answer-well]) .answer {
|
|
3867
|
+
padding: var(--ag-ui-pad);
|
|
3868
|
+
background: var(--ag-ui-well-bg);
|
|
3869
|
+
border: 1px solid var(--ag-ui-well-border);
|
|
3870
|
+
border-radius: var(--ag-ui-radius);
|
|
3871
|
+
}
|
|
3872
|
+
|
|
3796
3873
|
.message {
|
|
3797
3874
|
max-width: 80%;
|
|
3798
3875
|
padding: var(--ag-ui-msg-pad);
|
|
@@ -3965,10 +4042,71 @@ var STYLES = `
|
|
|
3965
4042
|
}
|
|
3966
4043
|
|
|
3967
4044
|
.tool-call-name {
|
|
4045
|
+
flex: 1;
|
|
4046
|
+
min-width: 0;
|
|
3968
4047
|
font-weight: 600;
|
|
3969
4048
|
word-break: break-word;
|
|
3970
4049
|
}
|
|
3971
4050
|
|
|
4051
|
+
/* Leading status icon (CARD-1). Empty in the DOM \u2014 the glyph/spinner is drawn
|
|
4052
|
+
here from the card's data-status, so it stays themeable. */
|
|
4053
|
+
.tool-call-icon {
|
|
4054
|
+
flex: none;
|
|
4055
|
+
box-sizing: border-box;
|
|
4056
|
+
display: inline-flex;
|
|
4057
|
+
align-items: center;
|
|
4058
|
+
justify-content: center;
|
|
4059
|
+
width: 14px;
|
|
4060
|
+
height: 14px;
|
|
4061
|
+
font-size: 12px;
|
|
4062
|
+
line-height: 1;
|
|
4063
|
+
}
|
|
4064
|
+
|
|
4065
|
+
/* Pending: a real spinning ring. Speed is tunable; reduced motion stops it. */
|
|
4066
|
+
.tool-call[data-status="pending"] .tool-call-icon {
|
|
4067
|
+
border: 2px solid var(--ag-ui-muted);
|
|
4068
|
+
border-top-color: transparent;
|
|
4069
|
+
border-radius: 50%;
|
|
4070
|
+
animation: ag-ui-tool-spin var(--ag-ui-tool-spin-duration) linear infinite;
|
|
4071
|
+
}
|
|
4072
|
+
|
|
4073
|
+
@keyframes ag-ui-tool-spin {
|
|
4074
|
+
to { transform: rotate(360deg); }
|
|
4075
|
+
}
|
|
4076
|
+
|
|
4077
|
+
/* Settled: a themeable glyph coloured by outcome. */
|
|
4078
|
+
.tool-call[data-status="done"] .tool-call-icon::before {
|
|
4079
|
+
content: var(--ag-ui-tool-icon-done);
|
|
4080
|
+
color: var(--ag-ui-success);
|
|
4081
|
+
}
|
|
4082
|
+
|
|
4083
|
+
.tool-call[data-status="error"] .tool-call-icon::before {
|
|
4084
|
+
content: var(--ag-ui-tool-icon-error);
|
|
4085
|
+
color: var(--ag-ui-danger);
|
|
4086
|
+
}
|
|
4087
|
+
|
|
4088
|
+
.tool-call[data-status="declined"] .tool-call-icon::before {
|
|
4089
|
+
content: var(--ag-ui-tool-icon-declined);
|
|
4090
|
+
color: var(--ag-ui-muted);
|
|
4091
|
+
}
|
|
4092
|
+
|
|
4093
|
+
@media (prefers-reduced-motion: reduce) {
|
|
4094
|
+
.tool-call[data-status="pending"] .tool-call-icon {
|
|
4095
|
+
animation: none;
|
|
4096
|
+
}
|
|
4097
|
+
}
|
|
4098
|
+
|
|
4099
|
+
/* Inline display mode (CARD-1): the lightest card \u2014 drop the box chrome so the
|
|
4100
|
+
status row reads as one line of the answer; the result toggle still expands
|
|
4101
|
+
below it. */
|
|
4102
|
+
.tool-call[data-display="inline"] {
|
|
4103
|
+
max-width: 100%;
|
|
4104
|
+
background: transparent;
|
|
4105
|
+
border: none;
|
|
4106
|
+
padding: 2px 0;
|
|
4107
|
+
gap: 2px;
|
|
4108
|
+
}
|
|
4109
|
+
|
|
3972
4110
|
.tool-call-status {
|
|
3973
4111
|
flex: none;
|
|
3974
4112
|
padding: 1px 8px;
|
|
@@ -4740,15 +4878,19 @@ var ToolCallCard = class {
|
|
|
4740
4878
|
const head = document.createElement("div");
|
|
4741
4879
|
head.className = "tool-call-head";
|
|
4742
4880
|
head.setAttribute("part", "tool-card-head");
|
|
4881
|
+
const icon = document.createElement("span");
|
|
4882
|
+
icon.className = "tool-call-icon";
|
|
4883
|
+
icon.setAttribute("part", "tool-card-icon");
|
|
4884
|
+
icon.setAttribute("aria-hidden", "true");
|
|
4743
4885
|
const label = document.createElement("span");
|
|
4744
4886
|
label.className = "tool-call-name";
|
|
4745
4887
|
label.setAttribute("part", "tool-card-name");
|
|
4746
|
-
label.textContent =
|
|
4888
|
+
label.textContent = summary ?? name;
|
|
4747
4889
|
this.#status = document.createElement("span");
|
|
4748
4890
|
this.#status.className = "tool-call-status";
|
|
4749
4891
|
this.#status.setAttribute("part", "tool-card-status");
|
|
4750
4892
|
this.#status.textContent = statusLabels(strings)[TOOL_CALL_STATUS.PENDING];
|
|
4751
|
-
head.append(label, this.#status);
|
|
4893
|
+
head.append(icon, label, this.#status);
|
|
4752
4894
|
this.element.append(head);
|
|
4753
4895
|
if (mode === TOOL_DISPLAY.FULL) {
|
|
4754
4896
|
const argsEl = document.createElement("pre");
|
|
@@ -4764,8 +4906,8 @@ var ToolCallCard = class {
|
|
|
4764
4906
|
}
|
|
4765
4907
|
/**
|
|
4766
4908
|
* Flip the status pill to ``status`` and, unless in `minimal` mode, append a
|
|
4767
|
-
* collapsed body behind a click-to-expand toggle: the result alone (`full`
|
|
4768
|
-
* or the args + result together (`compact`).
|
|
4909
|
+
* collapsed body behind a click-to-expand toggle: the result alone (`full` /
|
|
4910
|
+
* `inline`), or the args + result together (`compact`).
|
|
4769
4911
|
*/
|
|
4770
4912
|
settle(status, text2) {
|
|
4771
4913
|
this.#settled = true;
|
|
@@ -5481,6 +5623,13 @@ var AgUiChat = class extends HTMLElement {
|
|
|
5481
5623
|
// it; ≤1 ⇒ it arrived at once and the word reveal is appropriate.
|
|
5482
5624
|
#streamDeltas = 0;
|
|
5483
5625
|
#pending = null;
|
|
5626
|
+
// The current assistant turn's grouping container (WELL-1). One `.answer`
|
|
5627
|
+
// wraps everything a single answer produces — streamed text, tool cards, the
|
|
5628
|
+
// pending indicator — so it can be boxed as one "well" by CSS. Opened on the
|
|
5629
|
+
// turn's first run start, closed at settle, so it spans the whole multi-round
|
|
5630
|
+
// frontend-tool loop (which is several AG-UI runs), not one run. `null`
|
|
5631
|
+
// between turns; user bubbles never enter it.
|
|
5632
|
+
#currentGroup = null;
|
|
5484
5633
|
#threadId = "";
|
|
5485
5634
|
#initialMessages = [];
|
|
5486
5635
|
// Skill catalog by source; merged backend → embed → client (later wins).
|
|
@@ -5614,7 +5763,7 @@ var AgUiChat = class extends HTMLElement {
|
|
|
5614
5763
|
*/
|
|
5615
5764
|
get toolDisplay() {
|
|
5616
5765
|
const attr = this.getAttribute("data-tool-display");
|
|
5617
|
-
if (attr === TOOL_DISPLAY.MINIMAL || attr === TOOL_DISPLAY.COMPACT) {
|
|
5766
|
+
if (attr === TOOL_DISPLAY.INLINE || attr === TOOL_DISPLAY.MINIMAL || attr === TOOL_DISPLAY.COMPACT) {
|
|
5618
5767
|
return attr;
|
|
5619
5768
|
}
|
|
5620
5769
|
return TOOL_DISPLAY.FULL;
|
|
@@ -5881,6 +6030,7 @@ Use the read_attachment tool with an id to read a file's contents.`
|
|
|
5881
6030
|
#resetState() {
|
|
5882
6031
|
this.#client = null;
|
|
5883
6032
|
this.#streamingBubble = null;
|
|
6033
|
+
this.#currentGroup = null;
|
|
5884
6034
|
this.#hidePending();
|
|
5885
6035
|
this.#toolCards.clear();
|
|
5886
6036
|
this.#serverSettled.clear();
|
|
@@ -6012,6 +6162,10 @@ Use the read_attachment tool with an id to read a file's contents.`
|
|
|
6012
6162
|
* Assistant content is rendered as sanitised markdown/HTML; user content
|
|
6013
6163
|
* stays literal text (no need to parse what the user typed, and it avoids
|
|
6014
6164
|
* rendering user-authored markup).
|
|
6165
|
+
*
|
|
6166
|
+
* Assistant bubbles land in the current answer group (WELL-1), opening one if
|
|
6167
|
+
* needed; a user bubble closes the prior group and sits directly in the list
|
|
6168
|
+
* (the well wraps the *assistant* turn, the user message precedes it).
|
|
6015
6169
|
*/
|
|
6016
6170
|
appendMessage(role, content) {
|
|
6017
6171
|
const bubble = document.createElement("div");
|
|
@@ -6019,14 +6173,34 @@ Use the read_attachment tool with an id to read a file's contents.`
|
|
|
6019
6173
|
bubble.setAttribute("part", `message message-${role}`);
|
|
6020
6174
|
if (role === MESSAGE_ROLE.ASSISTANT) {
|
|
6021
6175
|
bubble.innerHTML = renderMarkdown(content, { allowImages: this.allowImages });
|
|
6176
|
+
this.#ensureGroup().appendChild(bubble);
|
|
6022
6177
|
} else {
|
|
6178
|
+
this.#currentGroup = null;
|
|
6023
6179
|
bubble.textContent = content;
|
|
6180
|
+
this.#messages.appendChild(bubble);
|
|
6024
6181
|
}
|
|
6025
|
-
this.#messages.appendChild(bubble);
|
|
6026
6182
|
this.#updateEmptyState();
|
|
6027
6183
|
this.#messages.scrollTop = this.#messages.scrollHeight;
|
|
6028
6184
|
return bubble;
|
|
6029
6185
|
}
|
|
6186
|
+
/**
|
|
6187
|
+
* The open answer group, creating and appending it on first use. Everything a
|
|
6188
|
+
* single assistant turn renders (text, tool cards, the pending indicator)
|
|
6189
|
+
* goes inside it, so the opt-in `data-answer-well` styling can box the whole
|
|
6190
|
+
* turn. Idempotent across the turn's runs — it persists until {@link #handlers}'
|
|
6191
|
+
* `onSettled` nulls it.
|
|
6192
|
+
*/
|
|
6193
|
+
#ensureGroup() {
|
|
6194
|
+
if (this.#currentGroup === null) {
|
|
6195
|
+
const group = document.createElement("div");
|
|
6196
|
+
group.className = "answer";
|
|
6197
|
+
group.setAttribute("part", "answer");
|
|
6198
|
+
this.#currentGroup = group;
|
|
6199
|
+
this.#messages.appendChild(group);
|
|
6200
|
+
this.#updateEmptyState();
|
|
6201
|
+
}
|
|
6202
|
+
return this.#currentGroup;
|
|
6203
|
+
}
|
|
6030
6204
|
#render() {
|
|
6031
6205
|
const style = document.createElement("style");
|
|
6032
6206
|
style.textContent = STYLES;
|
|
@@ -6332,6 +6506,7 @@ Use the read_attachment tool with an id to read a file's contents.`
|
|
|
6332
6506
|
return {
|
|
6333
6507
|
onRunStart: () => {
|
|
6334
6508
|
this.#setRunning(true);
|
|
6509
|
+
this.#ensureGroup();
|
|
6335
6510
|
this.#showPending();
|
|
6336
6511
|
},
|
|
6337
6512
|
onTextDelta: (buffer) => {
|
|
@@ -6382,6 +6557,11 @@ Use the read_attachment tool with an id to read a file's contents.`
|
|
|
6382
6557
|
card.settle(TOOL_CALL_STATUS.DONE, this.#strings.noResult);
|
|
6383
6558
|
}
|
|
6384
6559
|
}
|
|
6560
|
+
if (this.#currentGroup !== null && this.#currentGroup.childElementCount === 0) {
|
|
6561
|
+
this.#currentGroup.remove();
|
|
6562
|
+
this.#updateEmptyState();
|
|
6563
|
+
}
|
|
6564
|
+
this.#currentGroup = null;
|
|
6385
6565
|
}
|
|
6386
6566
|
};
|
|
6387
6567
|
}
|
|
@@ -6392,7 +6572,7 @@ Use the read_attachment tool with an id to read a file's contents.`
|
|
|
6392
6572
|
note.setAttribute("part", "stopped");
|
|
6393
6573
|
note.setAttribute("role", "status");
|
|
6394
6574
|
note.textContent = this.#strings.stopped;
|
|
6395
|
-
this.#
|
|
6575
|
+
this.#ensureGroup().appendChild(note);
|
|
6396
6576
|
this.#updateEmptyState();
|
|
6397
6577
|
this.#messages.scrollTop = this.#messages.scrollHeight;
|
|
6398
6578
|
}
|
|
@@ -6416,7 +6596,7 @@ Use the read_attachment tool with an id to read a file's contents.`
|
|
|
6416
6596
|
pending.appendChild(dot);
|
|
6417
6597
|
}
|
|
6418
6598
|
this.#pending = pending;
|
|
6419
|
-
this.#
|
|
6599
|
+
this.#ensureGroup().appendChild(pending);
|
|
6420
6600
|
this.#updateEmptyState();
|
|
6421
6601
|
this.#messages.scrollTop = this.#messages.scrollHeight;
|
|
6422
6602
|
}
|
|
@@ -6449,7 +6629,7 @@ Use the read_attachment tool with an id to read a file's contents.`
|
|
|
6449
6629
|
const summary = typeof labelled === "string" ? labelled : this.toolSummaries[call.name] ?? this.#toolCatalog[call.name] ?? prettifyToolName(call.name);
|
|
6450
6630
|
const card = new ToolCallCard(call.name, call.args, this.toolDisplay, summary, this.#strings);
|
|
6451
6631
|
this.#toolCards.set(call.id, card);
|
|
6452
|
-
this.#
|
|
6632
|
+
this.#ensureGroup().appendChild(card.element);
|
|
6453
6633
|
this.#updateEmptyState();
|
|
6454
6634
|
this.#messages.scrollTop = this.#messages.scrollHeight;
|
|
6455
6635
|
return card;
|
|
@@ -6496,7 +6676,7 @@ function setControlValue(el, value) {
|
|
|
6496
6676
|
}
|
|
6497
6677
|
|
|
6498
6678
|
// src/version.ts
|
|
6499
|
-
var VERSION = "0.
|
|
6679
|
+
var VERSION = "0.8.1";
|
|
6500
6680
|
export {
|
|
6501
6681
|
AgUiChat,
|
|
6502
6682
|
AgUiClient,
|