@artooi/ag-ui-web-component 0.45.0 → 0.46.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 +60 -1
- package/README.md +64 -9
- package/dist/ag-ui-web-component.bundle.js +384 -147
- package/dist/ag-ui-web-component.bundle.js.map +4 -4
- package/dist/constants.d.ts +4 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/core/ag_ui_chat.d.ts +10 -5
- package/dist/core/ag_ui_chat.d.ts.map +1 -1
- package/dist/index.js +609 -33
- package/dist/index.js.map +4 -4
- package/dist/tools/tool_catalog.d.ts +5 -0
- package/dist/tools/tool_catalog.d.ts.map +1 -1
- package/dist/tools/tool_dispatch.d.ts.map +1 -1
- package/dist/ui/interrupts/confirmation_styles.d.ts.map +1 -1
- package/dist/ui/placement/surface_for.d.ts +12 -1
- package/dist/ui/placement/surface_for.d.ts.map +1 -1
- package/dist/ui/progress/thoughts_styles.d.ts.map +1 -1
- package/dist/ui/progress/tool_call_card.d.ts +8 -0
- package/dist/ui/progress/tool_call_card.d.ts.map +1 -1
- package/dist/ui/progress/tool_group_styles.d.ts +2 -0
- package/dist/ui/progress/tool_group_styles.d.ts.map +1 -0
- package/dist/ui/progress/tool_step_group.d.ts +47 -0
- package/dist/ui/progress/tool_step_group.d.ts.map +1 -0
- package/dist/ui/progress/tool_step_styles.d.ts.map +1 -1
- package/dist/ui/shell/token_styles.d.ts.map +1 -1
- package/dist/ui/styles.d.ts.map +1 -1
- package/dist/ui/themes/ledger_styles.d.ts.map +1 -1
- package/dist/ui/themes/soft_styles.d.ts.map +1 -1
- package/dist/ui/transcript/groups_tool_steps.d.ts +13 -0
- package/dist/ui/transcript/groups_tool_steps.d.ts.map +1 -0
- package/dist/ui/transcript/message_styles.d.ts.map +1 -1
- package/dist/ui/transcript/transcript.d.ts +16 -1
- package/dist/ui/transcript/transcript.d.ts.map +1 -1
- package/dist/ui/ui_strings.d.ts +18 -0
- package/dist/ui/ui_strings.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +4 -1
- package/src/core/ag_ui_chat.ts +14 -6
- package/src/tools/tool_catalog.ts +23 -10
- package/src/tools/tool_dispatch.ts +26 -11
- package/src/ui/interrupts/confirmation_styles.ts +0 -2
- package/src/ui/placement/surface_for.ts +12 -1
- package/src/ui/progress/thoughts_styles.ts +0 -2
- package/src/ui/progress/tool_call_card.ts +11 -0
- package/src/ui/progress/tool_group_styles.ts +232 -0
- package/src/ui/progress/tool_step_group.ts +269 -0
- package/src/ui/progress/tool_step_styles.ts +0 -2
- package/src/ui/shell/token_styles.ts +2 -0
- package/src/ui/styles.ts +5 -0
- package/src/ui/themes/ledger_styles.ts +15 -0
- package/src/ui/themes/soft_styles.ts +20 -0
- package/src/ui/transcript/groups_tool_steps.ts +16 -0
- package/src/ui/transcript/message_styles.ts +0 -2
- package/src/ui/transcript/transcript.ts +109 -3
- package/src/ui/ui_strings.ts +31 -0
- package/src/version.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -55,6 +55,7 @@ var ATTACHMENT_STATUS = {
|
|
|
55
55
|
};
|
|
56
56
|
var DEFAULT_ATTACHMENT_MAX_BYTES = 10 * 1024 * 1024;
|
|
57
57
|
var TOOL_DISPLAY = {
|
|
58
|
+
GROUPED: "grouped",
|
|
58
59
|
INLINE: "inline",
|
|
59
60
|
MINIMAL: "minimal",
|
|
60
61
|
COMPACT: "compact",
|
|
@@ -1014,6 +1015,13 @@ var DEFAULT_UI_STRINGS = {
|
|
|
1014
1015
|
declinedLabel: "Declined",
|
|
1015
1016
|
interruptedLabel: "Not finished",
|
|
1016
1017
|
details: "Details",
|
|
1018
|
+
toolGroupSteps: "{count} steps",
|
|
1019
|
+
toolGroupWorking: "Working through {count} steps",
|
|
1020
|
+
toolGroupWorked: "Worked through {count} steps",
|
|
1021
|
+
toolGroupWaiting: "{count} waiting for you",
|
|
1022
|
+
toolGroupFailed: "{count} failed",
|
|
1023
|
+
toolGroupDeclined: "{count} declined",
|
|
1024
|
+
toolStepRepeat: "({n})",
|
|
1017
1025
|
subAgentWorking: "Working\u2026",
|
|
1018
1026
|
subAgentDelegatedTo: "Delegated to {agent}",
|
|
1019
1027
|
subAgentFinished: "{agent} finished",
|
|
@@ -1447,14 +1455,19 @@ var ToolCatalog = class {
|
|
|
1447
1455
|
});
|
|
1448
1456
|
const renderer = this.#host.askUserRenderer();
|
|
1449
1457
|
let answer;
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1458
|
+
this.#host.setAsking(callId, true);
|
|
1459
|
+
try {
|
|
1460
|
+
if (renderer === null) {
|
|
1461
|
+
answer = await builtIn();
|
|
1462
|
+
} else {
|
|
1463
|
+
try {
|
|
1464
|
+
answer = await renderer.call(this.#host.element, request, { signal });
|
|
1465
|
+
} catch (error) {
|
|
1466
|
+
answer = await this.#afterRendererFailed(error, signal, callId, builtIn);
|
|
1467
|
+
}
|
|
1457
1468
|
}
|
|
1469
|
+
} finally {
|
|
1470
|
+
this.#host.setAsking(callId, false);
|
|
1458
1471
|
}
|
|
1459
1472
|
this.#host.decision.close();
|
|
1460
1473
|
this.#host.updateEmptyState();
|
|
@@ -1752,6 +1765,7 @@ var ToolDispatch = class {
|
|
|
1752
1765
|
const card = this.#host.transcript.cardFor(call);
|
|
1753
1766
|
this.#host.transcript.forgetCard(call.id);
|
|
1754
1767
|
this.#host.transcript.setCardElement(call.id, card.element);
|
|
1768
|
+
this.#host.transcript.holdRunning(call.id, card);
|
|
1755
1769
|
const tool = this.#host.tools.wasAdvertised(call.name) ? this.#host.tools.resolve(call.name) : null;
|
|
1756
1770
|
if (tool === null) {
|
|
1757
1771
|
if (!this.#host.transcript.isServerSettled(call.id)) {
|
|
@@ -1784,15 +1798,21 @@ var ToolDispatch = class {
|
|
|
1784
1798
|
request.message = confirmText;
|
|
1785
1799
|
}
|
|
1786
1800
|
const signal = this.#host.decision.open();
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1801
|
+
card.setAsking(true);
|
|
1802
|
+
let accepted;
|
|
1803
|
+
try {
|
|
1804
|
+
const decision = requestConfirmation(this.#host.transcript.ensureGroup(), request, {
|
|
1805
|
+
signal,
|
|
1806
|
+
strings: this.#host.strings(),
|
|
1807
|
+
// Offered only where it can be honoured -- see `#confirmationRule`.
|
|
1808
|
+
...rule === "destructive" ? { onAlwaysAllow: () => this.#sessionApproved.add(call.name) } : {}
|
|
1809
|
+
});
|
|
1810
|
+
this.#host.transcript.updateEmptyState();
|
|
1811
|
+
this.#host.transcript.follow();
|
|
1812
|
+
accepted = await decision;
|
|
1813
|
+
} finally {
|
|
1814
|
+
card.setAsking(false);
|
|
1815
|
+
}
|
|
1796
1816
|
this.#host.decision.close();
|
|
1797
1817
|
if (this.#host.tenure() !== tenure) {
|
|
1798
1818
|
return null;
|
|
@@ -1893,6 +1913,9 @@ var ToolDispatch = class {
|
|
|
1893
1913
|
request.args = card.args;
|
|
1894
1914
|
}
|
|
1895
1915
|
card?.mark(TOOL_CALL_STATUS.DEFERRED);
|
|
1916
|
+
if (card !== void 0) {
|
|
1917
|
+
this.#host.transcript.revealStep(card);
|
|
1918
|
+
}
|
|
1896
1919
|
const builtIn = () => requestApproval(card?.approvalSlot ?? this.#host.transcript.ensureGroup(), request, {
|
|
1897
1920
|
signal,
|
|
1898
1921
|
strings: this.#host.strings(),
|
|
@@ -6956,6 +6979,16 @@ var ToolCallCard = class {
|
|
|
6956
6979
|
this.element.setAttribute("data-status", status);
|
|
6957
6980
|
this.#status.textContent = statusLabels(this.#strings)[status];
|
|
6958
6981
|
}
|
|
6982
|
+
/**
|
|
6983
|
+
* Say whether a prompt is open on this call, a question it asked or a
|
|
6984
|
+
* confirmation it needs. A flag of its own beside the status, which stays
|
|
6985
|
+
* `pending`: the call is still running as far as the status goes, and a card
|
|
6986
|
+
* display mode that reads the status draws it exactly as before. The step
|
|
6987
|
+
* group reads the flag to tell a call waiting on a person from one working.
|
|
6988
|
+
*/
|
|
6989
|
+
setAsking(asking) {
|
|
6990
|
+
this.element.toggleAttribute("data-asking", asking);
|
|
6991
|
+
}
|
|
6959
6992
|
/**
|
|
6960
6993
|
* Record that a human approved or declined this call, as a line in the card.
|
|
6961
6994
|
* The prompt disappears once answered, so this is the only lasting trace that
|
|
@@ -8038,8 +8071,6 @@ var CONFIRMATION_STYLES = `
|
|
|
8038
8071
|
padding: 8px 10px;
|
|
8039
8072
|
max-height: 140px;
|
|
8040
8073
|
overflow: auto;
|
|
8041
|
-
/* Scrolling past the end of this must not scroll the page behind it. */
|
|
8042
|
-
overscroll-behavior: contain;
|
|
8043
8074
|
font-size: 12px;
|
|
8044
8075
|
font-family: ui-monospace, "SF Mono", Menlo, monospace;
|
|
8045
8076
|
background: var(--_assistant-bg);
|
|
@@ -9057,8 +9088,6 @@ var THOUGHTS_STYLES = `
|
|
|
9057
9088
|
border-left: 2px solid var(--_border);
|
|
9058
9089
|
max-height: 220px;
|
|
9059
9090
|
overflow: auto;
|
|
9060
|
-
/* Scrolling past the end of this must not scroll the page behind it. */
|
|
9061
|
-
overscroll-behavior: contain;
|
|
9062
9091
|
white-space: pre-wrap;
|
|
9063
9092
|
word-break: break-word;
|
|
9064
9093
|
font-family: inherit;
|
|
@@ -9075,6 +9104,225 @@ var THOUGHTS_STYLES = `
|
|
|
9075
9104
|
}
|
|
9076
9105
|
`;
|
|
9077
9106
|
|
|
9107
|
+
// src/ui/progress/tool_group_styles.ts
|
|
9108
|
+
var CARD_MODES = [
|
|
9109
|
+
'[data-tool-display="inline"]',
|
|
9110
|
+
'[data-tool-display="minimal"]',
|
|
9111
|
+
'[data-tool-display="compact"]',
|
|
9112
|
+
'[data-tool-display="full"]'
|
|
9113
|
+
].join(", ");
|
|
9114
|
+
var GROUPED = `:host(:where(:not(${CARD_MODES})))`;
|
|
9115
|
+
var CARDS = `:host(:is(${CARD_MODES}))`;
|
|
9116
|
+
var TOOL_GROUP_STYLES = `
|
|
9117
|
+
/* \u2500\u2500 The folded tool-step group \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
|
|
9118
|
+
One quiet row per run of consecutive calls, the cards one click down as
|
|
9119
|
+
plain lines rather than boxes. Every rule is scoped to grouped mode, so
|
|
9120
|
+
none of it reaches a group drawn earlier once the host moves to a card
|
|
9121
|
+
mode. */
|
|
9122
|
+
${GROUPED} .tool-group {
|
|
9123
|
+
align-self: stretch;
|
|
9124
|
+
display: flex;
|
|
9125
|
+
flex-direction: column;
|
|
9126
|
+
min-width: 0;
|
|
9127
|
+
}
|
|
9128
|
+
|
|
9129
|
+
${GROUPED} .tool-group-head {
|
|
9130
|
+
appearance: none;
|
|
9131
|
+
align-self: flex-start;
|
|
9132
|
+
max-width: 100%;
|
|
9133
|
+
display: inline-flex;
|
|
9134
|
+
align-items: center;
|
|
9135
|
+
gap: 8px;
|
|
9136
|
+
margin: 0 0 0 -6px;
|
|
9137
|
+
padding: 4px 6px;
|
|
9138
|
+
border: 0;
|
|
9139
|
+
border-radius: 6px;
|
|
9140
|
+
background: transparent;
|
|
9141
|
+
color: var(--_muted);
|
|
9142
|
+
font: inherit;
|
|
9143
|
+
font-size: var(--_text-sm);
|
|
9144
|
+
line-height: 1.3;
|
|
9145
|
+
text-align: left;
|
|
9146
|
+
cursor: pointer;
|
|
9147
|
+
}
|
|
9148
|
+
|
|
9149
|
+
${GROUPED} .tool-group-head:hover {
|
|
9150
|
+
background: var(--_hover);
|
|
9151
|
+
color: var(--_fg);
|
|
9152
|
+
}
|
|
9153
|
+
|
|
9154
|
+
${GROUPED} .tool-group-head:focus-visible {
|
|
9155
|
+
outline: 2px solid var(--_ring);
|
|
9156
|
+
outline-offset: 1px;
|
|
9157
|
+
}
|
|
9158
|
+
|
|
9159
|
+
${GROUPED} .tool-group-label {
|
|
9160
|
+
min-width: 0;
|
|
9161
|
+
font-weight: 500;
|
|
9162
|
+
color: var(--_ink-2);
|
|
9163
|
+
overflow-wrap: anywhere;
|
|
9164
|
+
}
|
|
9165
|
+
|
|
9166
|
+
${GROUPED} .tool-group-meta {
|
|
9167
|
+
min-width: 0;
|
|
9168
|
+
color: var(--_muted);
|
|
9169
|
+
overflow-wrap: anywhere;
|
|
9170
|
+
}
|
|
9171
|
+
|
|
9172
|
+
/* Each note opens with a middle dot, which also parts the first note from
|
|
9173
|
+
the label. */
|
|
9174
|
+
${GROUPED} .tool-group-note::before {
|
|
9175
|
+
content: "\\00B7";
|
|
9176
|
+
margin: 0 6px 0 2px;
|
|
9177
|
+
}
|
|
9178
|
+
|
|
9179
|
+
${GROUPED} .tool-group[data-state="error"] .tool-group-meta {
|
|
9180
|
+
color: var(--_danger);
|
|
9181
|
+
}
|
|
9182
|
+
|
|
9183
|
+
${GROUPED} .tool-group-icon {
|
|
9184
|
+
flex: none;
|
|
9185
|
+
box-sizing: border-box;
|
|
9186
|
+
width: 14px;
|
|
9187
|
+
height: 14px;
|
|
9188
|
+
background: currentColor;
|
|
9189
|
+
mask: var(--_ico-check) center / contain no-repeat;
|
|
9190
|
+
color: var(--_success);
|
|
9191
|
+
}
|
|
9192
|
+
|
|
9193
|
+
${GROUPED} .tool-group[data-state="error"] .tool-group-icon {
|
|
9194
|
+
mask-image: var(--_ico-error);
|
|
9195
|
+
color: var(--_danger);
|
|
9196
|
+
}
|
|
9197
|
+
|
|
9198
|
+
${GROUPED} .tool-group[data-state="running"] .tool-group-icon {
|
|
9199
|
+
mask: none;
|
|
9200
|
+
background: none;
|
|
9201
|
+
border: 2px solid var(--_muted);
|
|
9202
|
+
border-top-color: transparent;
|
|
9203
|
+
border-radius: 50%;
|
|
9204
|
+
animation: ag-ui-tool-spin var(--_tool-spin-duration) linear infinite;
|
|
9205
|
+
}
|
|
9206
|
+
|
|
9207
|
+
/* Waiting on the user: a steady accent dot rather than a spinner, and the
|
|
9208
|
+
count in the accent's ink. */
|
|
9209
|
+
${GROUPED} .tool-group[data-state="waiting"] .tool-group-icon {
|
|
9210
|
+
mask: none;
|
|
9211
|
+
border-radius: 50%;
|
|
9212
|
+
transform: scale(0.6);
|
|
9213
|
+
background: var(--_accent);
|
|
9214
|
+
}
|
|
9215
|
+
|
|
9216
|
+
${GROUPED} .tool-group[data-state="waiting"] .tool-group-meta {
|
|
9217
|
+
color: var(--_accent-ink);
|
|
9218
|
+
font-weight: 500;
|
|
9219
|
+
}
|
|
9220
|
+
|
|
9221
|
+
${GROUPED} .tool-group-chevron {
|
|
9222
|
+
flex: none;
|
|
9223
|
+
width: 12px;
|
|
9224
|
+
height: 12px;
|
|
9225
|
+
background: currentColor;
|
|
9226
|
+
mask: var(--_ico-chevron) center / contain no-repeat;
|
|
9227
|
+
opacity: 0.7;
|
|
9228
|
+
transition: transform var(--_motion) var(--_ease);
|
|
9229
|
+
}
|
|
9230
|
+
|
|
9231
|
+
${GROUPED} .tool-group[data-open="true"] .tool-group-chevron {
|
|
9232
|
+
transform: rotate(90deg);
|
|
9233
|
+
}
|
|
9234
|
+
|
|
9235
|
+
@media (prefers-reduced-motion: reduce) {
|
|
9236
|
+
${GROUPED} .tool-group[data-state="running"] .tool-group-icon {
|
|
9237
|
+
animation: none;
|
|
9238
|
+
}
|
|
9239
|
+
}
|
|
9240
|
+
|
|
9241
|
+
${GROUPED} .tool-group-list {
|
|
9242
|
+
display: flex;
|
|
9243
|
+
flex-direction: column;
|
|
9244
|
+
gap: 2px;
|
|
9245
|
+
margin: 2px 0 4px 6px;
|
|
9246
|
+
padding-left: 13px;
|
|
9247
|
+
border-left: 1px solid var(--_border);
|
|
9248
|
+
}
|
|
9249
|
+
|
|
9250
|
+
${GROUPED} .tool-group[data-open="false"] .tool-group-list {
|
|
9251
|
+
display: none;
|
|
9252
|
+
}
|
|
9253
|
+
|
|
9254
|
+
/* A card inside the group is one line of the list: icon, name, and its
|
|
9255
|
+
Details control at the end, with the arguments and result opening under
|
|
9256
|
+
the whole row. */
|
|
9257
|
+
${GROUPED} .tool-group .tool-call {
|
|
9258
|
+
max-width: 100%;
|
|
9259
|
+
align-self: stretch;
|
|
9260
|
+
flex-flow: row wrap;
|
|
9261
|
+
align-items: center;
|
|
9262
|
+
gap: 2px 10px;
|
|
9263
|
+
padding: 3px 0;
|
|
9264
|
+
border: 0;
|
|
9265
|
+
border-radius: 0;
|
|
9266
|
+
background: transparent;
|
|
9267
|
+
color: var(--_ink-2);
|
|
9268
|
+
font-family: inherit;
|
|
9269
|
+
font-size: var(--_text-sm);
|
|
9270
|
+
}
|
|
9271
|
+
|
|
9272
|
+
${GROUPED} .tool-group .tool-call-head {
|
|
9273
|
+
flex: 1 1 auto;
|
|
9274
|
+
justify-content: flex-start;
|
|
9275
|
+
}
|
|
9276
|
+
|
|
9277
|
+
${GROUPED} .tool-group .tool-call-name {
|
|
9278
|
+
flex: 0 1 auto;
|
|
9279
|
+
font-weight: 450;
|
|
9280
|
+
}
|
|
9281
|
+
|
|
9282
|
+
/* The repeat ordinal on a step whose label an earlier step has. */
|
|
9283
|
+
${GROUPED} .tool-call-repeat {
|
|
9284
|
+
color: var(--_muted);
|
|
9285
|
+
font-variant-numeric: tabular-nums;
|
|
9286
|
+
}
|
|
9287
|
+
|
|
9288
|
+
${GROUPED} .tool-group .tool-call-toggle {
|
|
9289
|
+
font-family: inherit;
|
|
9290
|
+
font-size: var(--_text-xs);
|
|
9291
|
+
color: var(--_muted);
|
|
9292
|
+
}
|
|
9293
|
+
|
|
9294
|
+
${GROUPED} .tool-group .tool-call-body,
|
|
9295
|
+
${GROUPED} .tool-group .tool-call-approval,
|
|
9296
|
+
${GROUPED} .tool-group .tool-call-subagent {
|
|
9297
|
+
flex-basis: 100%;
|
|
9298
|
+
}
|
|
9299
|
+
|
|
9300
|
+
/* Grouping is decided as each card is built, so a card mode set afterwards
|
|
9301
|
+
finds groups already drawn. It flattens them: the group and its list stop
|
|
9302
|
+
generating boxes, the row and the repeat ordinals go, and every card lays
|
|
9303
|
+
out as a direct child of the answer, exactly as a card built in that mode
|
|
9304
|
+
does. */
|
|
9305
|
+
${CARDS} .tool-group,
|
|
9306
|
+
${CARDS} .tool-group-list {
|
|
9307
|
+
display: contents;
|
|
9308
|
+
}
|
|
9309
|
+
|
|
9310
|
+
${CARDS} .tool-group-head,
|
|
9311
|
+
${CARDS} .tool-call-repeat {
|
|
9312
|
+
display: none;
|
|
9313
|
+
}
|
|
9314
|
+
|
|
9315
|
+
/* Each of these declares its own display, which beats the user-agent rule for
|
|
9316
|
+
the hidden attribute, so each needs its own. The host prefix is there for
|
|
9317
|
+
weight, not scope: it lifts these over the card-mode rules above that set
|
|
9318
|
+
display, which are heavier than a bare class and attribute. */
|
|
9319
|
+
:host .tool-group[hidden],
|
|
9320
|
+
:host .tool-group-head[hidden],
|
|
9321
|
+
:host .tool-group-list[hidden] {
|
|
9322
|
+
display: none;
|
|
9323
|
+
}
|
|
9324
|
+
`;
|
|
9325
|
+
|
|
9078
9326
|
// src/ui/progress/tool_step_styles.ts
|
|
9079
9327
|
var TOOL_STEP_STYLES = `
|
|
9080
9328
|
.tool-call {
|
|
@@ -9271,8 +9519,6 @@ var TOOL_STEP_STYLES = `
|
|
|
9271
9519
|
padding: 6px 8px;
|
|
9272
9520
|
max-height: 160px;
|
|
9273
9521
|
overflow: auto;
|
|
9274
|
-
/* Scrolling past the end of this must not scroll the page behind it. */
|
|
9275
|
-
overscroll-behavior: contain;
|
|
9276
9522
|
background: var(--_bg);
|
|
9277
9523
|
border: 1px solid var(--_border);
|
|
9278
9524
|
border-radius: 6px;
|
|
@@ -9718,6 +9964,7 @@ var TOKEN_STYLES = `
|
|
|
9718
9964
|
--_line-strong: var(--ag-ui-line-strong, color-mix(in oklch, var(--_fg) 20%, var(--_bg)));
|
|
9719
9965
|
--_wash: var(--ag-ui-wash, color-mix(in oklch, var(--_fg) 4.5%, var(--_bg)));
|
|
9720
9966
|
--_accent-ink: var(--ag-ui-accent-ink, color-mix(in oklch, var(--_accent) 82%, var(--_fg)));
|
|
9967
|
+
--_ring: var(--ag-ui-ring, color-mix(in oklch, var(--_accent) 55%, transparent));
|
|
9721
9968
|
/* The user's turn is the accent at a whisper. With Quiet's graphite accent
|
|
9722
9969
|
that is a neutral wash; once a host sets a brand accent it becomes a tint
|
|
9723
9970
|
of the brand, which is the one thing Soft does that Quiet keeps. */
|
|
@@ -10049,6 +10296,7 @@ var TOKEN_STYLES = `
|
|
|
10049
10296
|
--_ico-check: var(--ag-ui-ico-check, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 8.5l3 3 6-7'/%3E%3C/svg%3E"));
|
|
10050
10297
|
--_ico-error: var(--ag-ui-ico-error, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round'%3E%3Ccircle cx='8' cy='8' r='6.2'/%3E%3Cpath d='M8 4.9v3.7M8 11.1v.1'/%3E%3C/svg%3E"));
|
|
10051
10298
|
--_ico-declined: var(--ag-ui-ico-declined, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round'%3E%3Ccircle cx='8' cy='8' r='6.2'/%3E%3Cpath d='M3.8 12.2l8.4-8.4'/%3E%3C/svg%3E"));
|
|
10299
|
+
--_ico-chevron: var(--ag-ui-ico-chevron, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 3.5l4.5 4.5L6 12.5'/%3E%3C/svg%3E"));
|
|
10052
10300
|
}
|
|
10053
10301
|
|
|
10054
10302
|
/* The colour drawn on the accent, from the accent's own luminance: white on
|
|
@@ -10267,6 +10515,21 @@ var LEDGER_STYLES = `
|
|
|
10267
10515
|
letter-spacing: 0.01em;
|
|
10268
10516
|
}
|
|
10269
10517
|
|
|
10518
|
+
/* The step group's row reads as a ledger heading. Unscoped to grouped mode:
|
|
10519
|
+
a card mode hides the row and drops the list's box, so neither reaches a
|
|
10520
|
+
flattened card. */
|
|
10521
|
+
:host([theme~="ledger"]) .tool-group-head {
|
|
10522
|
+
font-family: var(--_code-font);
|
|
10523
|
+
font-size: var(--_text-xs);
|
|
10524
|
+
border-radius: 2px;
|
|
10525
|
+
text-transform: uppercase;
|
|
10526
|
+
letter-spacing: 0.06em;
|
|
10527
|
+
}
|
|
10528
|
+
|
|
10529
|
+
:host([theme~="ledger"]) .tool-group-list {
|
|
10530
|
+
border-left: 1px dashed var(--_line-strong);
|
|
10531
|
+
}
|
|
10532
|
+
|
|
10270
10533
|
:host([theme~="ledger"]) .chart-block {
|
|
10271
10534
|
border-top: 1px solid var(--_line-strong);
|
|
10272
10535
|
border-bottom: 1px solid var(--_line);
|
|
@@ -10650,6 +10913,26 @@ var SOFT_STYLES = `
|
|
|
10650
10913
|
color: var(--_accent-ink);
|
|
10651
10914
|
}
|
|
10652
10915
|
|
|
10916
|
+
/* The step group's row as a tinted pill. Unscoped to grouped mode: a card
|
|
10917
|
+
mode hides the row and drops the list's box, so neither reaches a
|
|
10918
|
+
flattened card. */
|
|
10919
|
+
:host([theme~="soft"]) .tool-group-head {
|
|
10920
|
+
background: var(--_tint);
|
|
10921
|
+
border: 1px solid var(--_border);
|
|
10922
|
+
border-radius: 999px;
|
|
10923
|
+
padding: 5px 12px 5px 9px;
|
|
10924
|
+
margin-left: 0;
|
|
10925
|
+
}
|
|
10926
|
+
|
|
10927
|
+
:host([theme~="soft"]) .tool-group-head:hover {
|
|
10928
|
+
background: var(--_tint-2);
|
|
10929
|
+
}
|
|
10930
|
+
|
|
10931
|
+
:host([theme~="soft"]) .tool-group-list {
|
|
10932
|
+
border-left-color: var(--_tint-2);
|
|
10933
|
+
margin-left: 14px;
|
|
10934
|
+
}
|
|
10935
|
+
|
|
10653
10936
|
:host([theme~="soft"]) .chart-block {
|
|
10654
10937
|
background: var(--_bg);
|
|
10655
10938
|
border: 1px solid var(--_border);
|
|
@@ -11318,8 +11601,6 @@ var MESSAGE_STYLES = `
|
|
|
11318
11601
|
.message--assistant pre {
|
|
11319
11602
|
padding: 8px 10px;
|
|
11320
11603
|
overflow: auto;
|
|
11321
|
-
/* Scrolling past the end of this must not scroll the page behind it. */
|
|
11322
|
-
overscroll-behavior: contain;
|
|
11323
11604
|
background: var(--_bg);
|
|
11324
11605
|
border: 1px solid var(--_border);
|
|
11325
11606
|
border-radius: 6px;
|
|
@@ -11627,6 +11908,10 @@ var STYLES = [
|
|
|
11627
11908
|
QUESTION_STYLES,
|
|
11628
11909
|
SKILL_STYLES,
|
|
11629
11910
|
HISTORY_STYLES,
|
|
11911
|
+
// The step group restates, inside a group, card rules the modules above set
|
|
11912
|
+
// at rest; it outweighs them rather than relying on order, and sits ahead
|
|
11913
|
+
// of the themes so a theme restating a group rule at equal weight wins.
|
|
11914
|
+
TOOL_GROUP_STYLES,
|
|
11630
11915
|
// Each theme's structure comes last: it restates rules the modules above
|
|
11631
11916
|
// set at rest, at equal weight. Classic and code have no structural
|
|
11632
11917
|
// module; they are the base stylesheet, and classic adds only its
|
|
@@ -15854,6 +16139,200 @@ var ThoughtsBlock = class {
|
|
|
15854
16139
|
}
|
|
15855
16140
|
};
|
|
15856
16141
|
|
|
16142
|
+
// src/ui/progress/tool_step_group.ts
|
|
16143
|
+
var OPEN_STATUSES = /* @__PURE__ */ new Set([
|
|
16144
|
+
TOOL_CALL_STATUS.PENDING,
|
|
16145
|
+
TOOL_CALL_STATUS.DEFERRED
|
|
16146
|
+
]);
|
|
16147
|
+
var RUNNING_SUBAGENT = `.tool-call-subagent > .subagent:is(${[
|
|
16148
|
+
SUBAGENT_PHASE.STARTED,
|
|
16149
|
+
SUBAGENT_PHASE.TOOL_CALL,
|
|
16150
|
+
SUBAGENT_PHASE.TOOL_RESULT
|
|
16151
|
+
].map((phase) => `[data-phase="${phase}"]`).join(", ")})`;
|
|
16152
|
+
var WATCHED_ATTRIBUTES = [
|
|
16153
|
+
"data-status",
|
|
16154
|
+
"data-asking",
|
|
16155
|
+
"data-phase",
|
|
16156
|
+
"data-agent"
|
|
16157
|
+
];
|
|
16158
|
+
var ToolStepGroup = class {
|
|
16159
|
+
element;
|
|
16160
|
+
#strings;
|
|
16161
|
+
#list;
|
|
16162
|
+
#head;
|
|
16163
|
+
#label;
|
|
16164
|
+
#meta;
|
|
16165
|
+
/** The steps, in order. Cards only ever join a group, so this is its list's children. */
|
|
16166
|
+
#steps = [];
|
|
16167
|
+
/** Whether the group has already opened itself for the current wait. */
|
|
16168
|
+
#openedForWait = false;
|
|
16169
|
+
constructor(strings) {
|
|
16170
|
+
this.#strings = strings;
|
|
16171
|
+
this.element = document.createElement("div");
|
|
16172
|
+
this.element.className = "tool-group";
|
|
16173
|
+
this.element.setAttribute("part", "tool-group");
|
|
16174
|
+
this.element.setAttribute("data-open", "false");
|
|
16175
|
+
this.#head = document.createElement("button");
|
|
16176
|
+
this.#head.type = "button";
|
|
16177
|
+
this.#head.className = "tool-group-head";
|
|
16178
|
+
this.#head.setAttribute("part", "tool-group-head");
|
|
16179
|
+
this.#head.setAttribute("aria-expanded", "false");
|
|
16180
|
+
const icon = document.createElement("span");
|
|
16181
|
+
icon.className = "tool-group-icon";
|
|
16182
|
+
icon.setAttribute("part", "tool-group-icon");
|
|
16183
|
+
icon.setAttribute("aria-hidden", "true");
|
|
16184
|
+
this.#label = document.createElement("span");
|
|
16185
|
+
this.#label.className = "tool-group-label";
|
|
16186
|
+
this.#label.setAttribute("part", "tool-group-label");
|
|
16187
|
+
this.#meta = document.createElement("span");
|
|
16188
|
+
this.#meta.className = "tool-group-meta";
|
|
16189
|
+
this.#meta.setAttribute("part", "tool-group-meta");
|
|
16190
|
+
const chevron = document.createElement("span");
|
|
16191
|
+
chevron.className = "tool-group-chevron";
|
|
16192
|
+
chevron.setAttribute("aria-hidden", "true");
|
|
16193
|
+
this.#head.append(icon, this.#label, this.#meta, chevron);
|
|
16194
|
+
this.#head.addEventListener("click", () => {
|
|
16195
|
+
this.setOpen(this.element.getAttribute("data-open") !== "true");
|
|
16196
|
+
});
|
|
16197
|
+
this.#list = document.createElement("div");
|
|
16198
|
+
this.#list.className = "tool-group-list";
|
|
16199
|
+
this.#list.setAttribute("part", "tool-group-list");
|
|
16200
|
+
this.element.append(this.#head, this.#list);
|
|
16201
|
+
new MutationObserver(() => {
|
|
16202
|
+
this.#refresh();
|
|
16203
|
+
}).observe(this.#list, {
|
|
16204
|
+
attributes: true,
|
|
16205
|
+
attributeFilter: [...WATCHED_ATTRIBUTES],
|
|
16206
|
+
subtree: true
|
|
16207
|
+
});
|
|
16208
|
+
}
|
|
16209
|
+
/**
|
|
16210
|
+
* Add a card's element as the group's next step, under the label the card
|
|
16211
|
+
* was built with.
|
|
16212
|
+
*
|
|
16213
|
+
* A step whose label an earlier step already has gets a repeat ordinal,
|
|
16214
|
+
* "Fill field (2)", in an element of its own beside the card's name. The
|
|
16215
|
+
* name itself is never rewritten, so a group flattened back into per-call
|
|
16216
|
+
* cards by a card display mode shows exactly the label the card was built
|
|
16217
|
+
* with, and the CSS hides the ordinal there.
|
|
16218
|
+
*/
|
|
16219
|
+
add(card, name) {
|
|
16220
|
+
const seen = this.#steps.filter((step) => step.name === name).length + 1;
|
|
16221
|
+
let label = name;
|
|
16222
|
+
if (seen > 1) {
|
|
16223
|
+
const repeat = document.createElement("span");
|
|
16224
|
+
repeat.className = "tool-call-repeat";
|
|
16225
|
+
repeat.setAttribute("part", "tool-card-repeat");
|
|
16226
|
+
repeat.textContent = fillUiString(this.#strings.toolStepRepeat, { n: seen });
|
|
16227
|
+
card.querySelector(".tool-call-name")?.after(repeat);
|
|
16228
|
+
label = `${name} ${repeat.textContent}`;
|
|
16229
|
+
}
|
|
16230
|
+
this.#steps.push({ element: card, name, label });
|
|
16231
|
+
this.#list.append(card);
|
|
16232
|
+
this.#refresh();
|
|
16233
|
+
}
|
|
16234
|
+
/** Show or hide the per-step cards. */
|
|
16235
|
+
setOpen(open) {
|
|
16236
|
+
this.element.setAttribute("data-open", String(open));
|
|
16237
|
+
this.#head.setAttribute("aria-expanded", String(open));
|
|
16238
|
+
}
|
|
16239
|
+
/**
|
|
16240
|
+
* Open the group now, for the wait that is about to start.
|
|
16241
|
+
*
|
|
16242
|
+
* The group opens itself from its mutation observer, which runs a tick after
|
|
16243
|
+
* the card is marked deferred. The approval prompt is drawn, and takes focus,
|
|
16244
|
+
* in the same tick as the mark, while the list is still out of the layout: the
|
|
16245
|
+
* focus is dropped and the scroll it would cause never happens. So the caller
|
|
16246
|
+
* that is about to draw the prompt opens the group first, and this marks the
|
|
16247
|
+
* wait as already answered for, so the observer's later refresh does not open
|
|
16248
|
+
* it again over a user who folded it.
|
|
16249
|
+
*/
|
|
16250
|
+
reveal() {
|
|
16251
|
+
this.#openedForWait = true;
|
|
16252
|
+
this.setOpen(true);
|
|
16253
|
+
}
|
|
16254
|
+
/**
|
|
16255
|
+
* The row's note for a running sub-agent, naming it, or `null` when no step
|
|
16256
|
+
* is delegating right now. Only a step that is itself still running counts.
|
|
16257
|
+
*/
|
|
16258
|
+
#delegation() {
|
|
16259
|
+
for (const { element } of this.#steps) {
|
|
16260
|
+
const panel = element.getAttribute("data-status") === TOOL_CALL_STATUS.PENDING ? element.querySelector(RUNNING_SUBAGENT) : null;
|
|
16261
|
+
if (panel !== null) {
|
|
16262
|
+
const agent = panel.getAttribute("data-agent");
|
|
16263
|
+
return agent === null ? this.#strings.subAgentWorking : fillUiString(this.#strings.subAgentDelegatedTo, { agent });
|
|
16264
|
+
}
|
|
16265
|
+
}
|
|
16266
|
+
return null;
|
|
16267
|
+
}
|
|
16268
|
+
#refresh() {
|
|
16269
|
+
const strings = this.#strings;
|
|
16270
|
+
const steps = this.#steps;
|
|
16271
|
+
const statuses = steps.map((step) => step.element.getAttribute("data-status") ?? "");
|
|
16272
|
+
const open = steps.filter((_2, i) => OPEN_STATUSES.has(statuses[i]));
|
|
16273
|
+
const count = (status) => statuses.filter((s) => s === status).length;
|
|
16274
|
+
const failed = count(TOOL_CALL_STATUS.ERROR);
|
|
16275
|
+
const declined = count(TOOL_CALL_STATUS.DECLINED);
|
|
16276
|
+
const deferred = count(TOOL_CALL_STATUS.DEFERRED);
|
|
16277
|
+
const asking = steps.filter((step) => step.element.hasAttribute("data-asking")).length;
|
|
16278
|
+
const waiting = deferred + asking;
|
|
16279
|
+
const total = steps.length;
|
|
16280
|
+
if (deferred > 0 && !this.#openedForWait) {
|
|
16281
|
+
this.#openedForWait = true;
|
|
16282
|
+
this.setOpen(true);
|
|
16283
|
+
} else if (deferred === 0) {
|
|
16284
|
+
this.#openedForWait = false;
|
|
16285
|
+
}
|
|
16286
|
+
let state = "done";
|
|
16287
|
+
if (waiting > 0) {
|
|
16288
|
+
state = "waiting";
|
|
16289
|
+
} else if (open.length > 0) {
|
|
16290
|
+
state = "running";
|
|
16291
|
+
} else if (failed > 0) {
|
|
16292
|
+
state = "error";
|
|
16293
|
+
}
|
|
16294
|
+
this.element.setAttribute("data-state", state);
|
|
16295
|
+
this.element.setAttribute("data-count", String(total));
|
|
16296
|
+
const only = total === 1 ? steps[0] : void 0;
|
|
16297
|
+
if (only !== void 0) {
|
|
16298
|
+
this.#label.textContent = only.label;
|
|
16299
|
+
} else {
|
|
16300
|
+
const template = state === "waiting" ? strings.toolGroupSteps : state === "running" ? strings.toolGroupWorking : strings.toolGroupWorked;
|
|
16301
|
+
this.#label.textContent = fillUiString(template, { count: total });
|
|
16302
|
+
}
|
|
16303
|
+
const notes = [];
|
|
16304
|
+
const delegation = this.#delegation();
|
|
16305
|
+
const current = open[0];
|
|
16306
|
+
if (waiting > 0) {
|
|
16307
|
+
notes.push(fillUiString(strings.toolGroupWaiting, { count: waiting }));
|
|
16308
|
+
} else if (delegation !== null) {
|
|
16309
|
+
notes.push(delegation);
|
|
16310
|
+
} else if (current !== void 0 && total > 1) {
|
|
16311
|
+
notes.push(current.label);
|
|
16312
|
+
}
|
|
16313
|
+
if (failed > 0) {
|
|
16314
|
+
notes.push(fillUiString(strings.toolGroupFailed, { count: failed }));
|
|
16315
|
+
}
|
|
16316
|
+
if (declined > 0) {
|
|
16317
|
+
notes.push(fillUiString(strings.toolGroupDeclined, { count: declined }));
|
|
16318
|
+
}
|
|
16319
|
+
this.#meta.replaceChildren(
|
|
16320
|
+
...notes.map((text4) => {
|
|
16321
|
+
const note = document.createElement("span");
|
|
16322
|
+
note.className = "tool-group-note";
|
|
16323
|
+
note.textContent = text4;
|
|
16324
|
+
return note;
|
|
16325
|
+
})
|
|
16326
|
+
);
|
|
16327
|
+
this.#meta.hidden = notes.length === 0;
|
|
16328
|
+
}
|
|
16329
|
+
};
|
|
16330
|
+
|
|
16331
|
+
// src/ui/transcript/groups_tool_steps.ts
|
|
16332
|
+
function groupsToolSteps(mode) {
|
|
16333
|
+
return mode === TOOL_DISPLAY.GROUPED;
|
|
16334
|
+
}
|
|
16335
|
+
|
|
15857
16336
|
// src/ui/transcript/render_or_warn.ts
|
|
15858
16337
|
function renderOrWarn(render, subject) {
|
|
15859
16338
|
try {
|
|
@@ -15960,6 +16439,12 @@ var Transcript = class {
|
|
|
15960
16439
|
#toolCards = /* @__PURE__ */ new Map();
|
|
15961
16440
|
/** Card elements by call id, so a rendering handler can find its own card. */
|
|
15962
16441
|
#cardElements = /* @__PURE__ */ new Map();
|
|
16442
|
+
/**
|
|
16443
|
+
* Cards whose call is being run, by call id. A card leaves the awaiting ones
|
|
16444
|
+
* the moment its call is dispatched, and a handler that opens a prompt on its
|
|
16445
|
+
* own card is still running long after, so it is found here.
|
|
16446
|
+
*/
|
|
16447
|
+
#running = /* @__PURE__ */ new Map();
|
|
15963
16448
|
/**
|
|
15964
16449
|
* Call ids whose card was already settled from a streamed server-side result
|
|
15965
16450
|
* (`TOOL_CALL_RESULT`), so the post-run executeTool sweep doesn't overwrite
|
|
@@ -15980,6 +16465,24 @@ var Transcript = class {
|
|
|
15980
16465
|
// the answer group while a reasoning model thinks and collapsed once the
|
|
15981
16466
|
// answer's first text token arrives. `null` outside a reasoning turn.
|
|
15982
16467
|
#thoughts = null;
|
|
16468
|
+
/** The step group behind each group element, so a new card can find its run. */
|
|
16469
|
+
#stepGroups = /* @__PURE__ */ new WeakMap();
|
|
16470
|
+
/**
|
|
16471
|
+
* An empty comment after each step group that has rendered output, which
|
|
16472
|
+
* every later output is placed before, so a group's outputs come out in call
|
|
16473
|
+
* order. Every card of a round joins its group before any handler runs, so
|
|
16474
|
+
* placing each output straight after the group would put the newest first;
|
|
16475
|
+
* and a marker rather than the last output, because an output may be a
|
|
16476
|
+
* fragment, which leaves nothing behind to place the next one after.
|
|
16477
|
+
*/
|
|
16478
|
+
#groupEnds = /* @__PURE__ */ new WeakMap();
|
|
16479
|
+
/**
|
|
16480
|
+
* The step group element each placed output belongs to. A tool's own output
|
|
16481
|
+
* does not end its group: the next call joins the group above it. Without
|
|
16482
|
+
* that, replay -- which draws each restored call's output before the next
|
|
16483
|
+
* call's card -- would split a run the live stream drew as one group.
|
|
16484
|
+
*/
|
|
16485
|
+
#outputGroups = /* @__PURE__ */ new WeakMap();
|
|
15983
16486
|
constructor(host) {
|
|
15984
16487
|
this.#host = host;
|
|
15985
16488
|
}
|
|
@@ -16075,6 +16578,18 @@ var Transcript = class {
|
|
|
16075
16578
|
forgetCards() {
|
|
16076
16579
|
this.#serverSettled.clear();
|
|
16077
16580
|
this.#cardElements.clear();
|
|
16581
|
+
this.#running.clear();
|
|
16582
|
+
}
|
|
16583
|
+
/** Remember the card of a call being run, for {@link setAsking}. */
|
|
16584
|
+
holdRunning(callId, card) {
|
|
16585
|
+
this.#running.set(callId, card);
|
|
16586
|
+
}
|
|
16587
|
+
/**
|
|
16588
|
+
* Say whether a prompt is open on the card of a running call. A call id of
|
|
16589
|
+
* none, or one no card was held for, has no card to say it on.
|
|
16590
|
+
*/
|
|
16591
|
+
setAsking(callId, asking) {
|
|
16592
|
+
this.#running.get(callId)?.setAsking(asking);
|
|
16078
16593
|
}
|
|
16079
16594
|
/** Empty the list back to its empty-state region. The last half of wiping it. */
|
|
16080
16595
|
empty() {
|
|
@@ -16248,7 +16763,23 @@ var Transcript = class {
|
|
|
16248
16763
|
if (node === null) {
|
|
16249
16764
|
return;
|
|
16250
16765
|
}
|
|
16251
|
-
this.#cardElements.get(call.id)
|
|
16766
|
+
const anchor = this.#cardElements.get(call.id);
|
|
16767
|
+
const group = anchor?.closest(".tool-group");
|
|
16768
|
+
if (group === null || group === void 0) {
|
|
16769
|
+
anchor?.after(node);
|
|
16770
|
+
} else {
|
|
16771
|
+
let end = this.#groupEnds.get(group);
|
|
16772
|
+
if (end === void 0) {
|
|
16773
|
+
end = document.createComment("");
|
|
16774
|
+
group.after(end);
|
|
16775
|
+
this.#groupEnds.set(group, end);
|
|
16776
|
+
}
|
|
16777
|
+
const placed = node instanceof DocumentFragment ? [...node.children] : [node];
|
|
16778
|
+
end.before(node);
|
|
16779
|
+
for (const output of placed) {
|
|
16780
|
+
this.#outputGroups.set(output, group);
|
|
16781
|
+
}
|
|
16782
|
+
}
|
|
16252
16783
|
this.afterGrew();
|
|
16253
16784
|
}
|
|
16254
16785
|
/** Update the empty state and follow the foot, after the transcript grew. */
|
|
@@ -16276,11 +16807,49 @@ var Transcript = class {
|
|
|
16276
16807
|
formatPayload: (payload) => this.#host.formatToolPayload(payload)
|
|
16277
16808
|
});
|
|
16278
16809
|
this.#toolCards.set(call.id, card);
|
|
16279
|
-
this.
|
|
16810
|
+
if (groupsToolSteps(this.#host.toolDisplay())) {
|
|
16811
|
+
this.#stepGroup().add(card.element, summary);
|
|
16812
|
+
} else {
|
|
16813
|
+
this.ensureGroup().appendChild(card.element);
|
|
16814
|
+
}
|
|
16280
16815
|
this.updateEmptyState();
|
|
16281
16816
|
this.follow();
|
|
16282
16817
|
return card;
|
|
16283
16818
|
}
|
|
16819
|
+
/**
|
|
16820
|
+
* Open the step group ``card`` sits in, at once, ahead of a prompt about to be
|
|
16821
|
+
* drawn inside it. A no-op for a card drawn in a card display mode, which has
|
|
16822
|
+
* no group.
|
|
16823
|
+
*/
|
|
16824
|
+
revealStep(card) {
|
|
16825
|
+
const group = card.element.closest(".tool-group");
|
|
16826
|
+
(group === null ? void 0 : this.#stepGroups.get(group))?.reveal();
|
|
16827
|
+
}
|
|
16828
|
+
/**
|
|
16829
|
+
* The step group a new card joins. Consecutive cards share one, and so do
|
|
16830
|
+
* cards separated only by the group's own rendered output; anything else in
|
|
16831
|
+
* between (text, a confirmation, a question) starts the next.
|
|
16832
|
+
*
|
|
16833
|
+
* The pending dots are not skipped over: a tool call takes them down before
|
|
16834
|
+
* its card is drawn, so they are never what a card finds at the foot of the
|
|
16835
|
+
* turn.
|
|
16836
|
+
*/
|
|
16837
|
+
#stepGroup() {
|
|
16838
|
+
const answer = this.ensureGroup();
|
|
16839
|
+
const last = answer.lastElementChild;
|
|
16840
|
+
const existing = last === null ? void 0 : this.#stepGroups.get(this.#outputGroups.get(last) ?? last);
|
|
16841
|
+
if (existing !== void 0) {
|
|
16842
|
+
return existing;
|
|
16843
|
+
}
|
|
16844
|
+
const group = new ToolStepGroup(this.#host.strings());
|
|
16845
|
+
this.#stepGroups.set(group.element, group);
|
|
16846
|
+
if (last === null) {
|
|
16847
|
+
answer.prepend(group.element);
|
|
16848
|
+
} else {
|
|
16849
|
+
last.after(group.element);
|
|
16850
|
+
}
|
|
16851
|
+
return group;
|
|
16852
|
+
}
|
|
16284
16853
|
};
|
|
16285
16854
|
|
|
16286
16855
|
// src/core/activity_registry.ts
|
|
@@ -18440,6 +19009,7 @@ var AgUiChat = class extends HTMLElement {
|
|
|
18440
19009
|
askUser: () => this.askUser,
|
|
18441
19010
|
askUserRenderer: () => this.askUserRenderer,
|
|
18442
19011
|
decision: this.#decision,
|
|
19012
|
+
setAsking: (callId, asking) => this.#transcript.setAsking(callId, asking),
|
|
18443
19013
|
ensureGroup: () => this.#transcript.ensureGroup(),
|
|
18444
19014
|
strings: () => this.#strings,
|
|
18445
19015
|
hidePending: () => this.#transcript.hidePending(),
|
|
@@ -18492,6 +19062,7 @@ var AgUiChat = class extends HTMLElement {
|
|
|
18492
19062
|
resolveTool: (name) => this.#tools.resolve(name),
|
|
18493
19063
|
toolSummaries: () => this.toolSummaries,
|
|
18494
19064
|
serverSummary: (name) => this.#tools.summary(name),
|
|
19065
|
+
toolDisplay: () => this.toolDisplay,
|
|
18495
19066
|
// A thunk over the live property, not the property itself: the card keeps
|
|
18496
19067
|
// this for the life of the call, and the result region is filled when the
|
|
18497
19068
|
// tool settles -- which can be long after a host set the hook.
|
|
@@ -18963,18 +19534,23 @@ var AgUiChat = class extends HTMLElement {
|
|
|
18963
19534
|
}
|
|
18964
19535
|
/**
|
|
18965
19536
|
* How much detail tool-call cards show, from the `data-tool-display`
|
|
18966
|
-
* attribute (`minimal` / `inline` / `compact` / `full`).
|
|
19537
|
+
* attribute (`grouped` / `minimal` / `inline` / `compact` / `full`).
|
|
19538
|
+
* Defaults to `grouped`, for an absent attribute and for a value the
|
|
19539
|
+
* element does not know; `full` is the per-call card default before
|
|
19540
|
+
* `grouped` existed.
|
|
18967
19541
|
*
|
|
18968
|
-
*
|
|
18969
|
-
* restyles every card already in the
|
|
18970
|
-
*
|
|
19542
|
+
* The four card modes are applied by the shadow CSS from the attribute
|
|
19543
|
+
* itself, so changing between them restyles every card already in the
|
|
19544
|
+
* transcript. Whether calls fold into a step group is decided as each card
|
|
19545
|
+
* is built: switching to `grouped` folds only the calls drawn afterwards,
|
|
19546
|
+
* and switching away flattens the existing groups, again by CSS.
|
|
18971
19547
|
*/
|
|
18972
19548
|
get toolDisplay() {
|
|
18973
19549
|
const attr = this.getAttribute("data-tool-display");
|
|
18974
|
-
if (attr === TOOL_DISPLAY.INLINE || attr === TOOL_DISPLAY.MINIMAL || attr === TOOL_DISPLAY.COMPACT) {
|
|
19550
|
+
if (attr === TOOL_DISPLAY.INLINE || attr === TOOL_DISPLAY.MINIMAL || attr === TOOL_DISPLAY.COMPACT || attr === TOOL_DISPLAY.FULL) {
|
|
18975
19551
|
return attr;
|
|
18976
19552
|
}
|
|
18977
|
-
return TOOL_DISPLAY.
|
|
19553
|
+
return TOOL_DISPLAY.GROUPED;
|
|
18978
19554
|
}
|
|
18979
19555
|
set toolDisplay(value) {
|
|
18980
19556
|
this.setAttribute("data-tool-display", value);
|
|
@@ -20342,7 +20918,7 @@ function setControlValue(el2, value) {
|
|
|
20342
20918
|
}
|
|
20343
20919
|
|
|
20344
20920
|
// src/version.ts
|
|
20345
|
-
var VERSION = "0.
|
|
20921
|
+
var VERSION = "0.46.0";
|
|
20346
20922
|
export {
|
|
20347
20923
|
ATTACHMENT_EVENT,
|
|
20348
20924
|
AgUiChat,
|