@design.estate/dees-catalog 6.7.0 → 6.8.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/dist_bundle/bundle.js +1153 -193
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/elements/00group-harness/dees-harness-message/dees-harness-message.d.ts +2 -1
- package/dist_ts_web/elements/00group-harness/dees-harness-message/dees-harness-message.js +57 -17
- package/dist_ts_web/elements/00group-harness/dees-harness-message-list/dees-harness-message-list.d.ts +92 -6
- package/dist_ts_web/elements/00group-harness/dees-harness-message-list/dees-harness-message-list.js +921 -49
- package/dist_ts_web/elements/00group-harness/dees-harness-permission-card/dees-harness-permission-card.d.ts +5 -1
- package/dist_ts_web/elements/00group-harness/dees-harness-permission-card/dees-harness-permission-card.js +42 -7
- package/dist_ts_web/elements/00group-harness/dees-harness-question-card/dees-harness-question-card.d.ts +6 -1
- package/dist_ts_web/elements/00group-harness/dees-harness-question-card/dees-harness-question-card.js +53 -14
- package/dist_ts_web/elements/00group-harness/dees-harness-reasoning/dees-harness-reasoning.d.ts +2 -1
- package/dist_ts_web/elements/00group-harness/dees-harness-reasoning/dees-harness-reasoning.js +13 -3
- package/dist_ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.js +31 -13
- package/dist_ts_web/elements/00group-harness/dees-harness-session-sidebar/dees-harness-session-sidebar.js +9 -3
- package/dist_ts_web/elements/00group-harness/dees-harness-tool-card/dees-harness-tool-card.d.ts +6 -1
- package/dist_ts_web/elements/00group-harness/dees-harness-tool-card/dees-harness-tool-card.js +135 -13
- package/dist_ts_web/elements/00group-harness/harness.styles.js +16 -13
- package/dist_ts_web/elements/00group-harness/interfaces.d.ts +30 -0
- package/dist_ts_web/elements/00group-harness/toolregistry.d.ts +2 -0
- package/dist_ts_web/elements/00group-harness/toolregistry.js +7 -1
- package/package.json +2 -2
- package/readme.md +4 -2
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/00group-harness/dees-harness-message/dees-harness-message.ts +53 -15
- package/ts_web/elements/00group-harness/dees-harness-message-list/dees-harness-message-list.ts +943 -51
- package/ts_web/elements/00group-harness/dees-harness-permission-card/dees-harness-permission-card.ts +37 -8
- package/ts_web/elements/00group-harness/dees-harness-question-card/dees-harness-question-card.ts +40 -12
- package/ts_web/elements/00group-harness/dees-harness-reasoning/dees-harness-reasoning.ts +6 -2
- package/ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.ts +30 -12
- package/ts_web/elements/00group-harness/dees-harness-session-sidebar/dees-harness-session-sidebar.ts +8 -2
- package/ts_web/elements/00group-harness/dees-harness-tool-card/dees-harness-tool-card.ts +119 -11
- package/ts_web/elements/00group-harness/harness.styles.ts +15 -12
- package/ts_web/elements/00group-harness/interfaces.ts +34 -0
- package/ts_web/elements/00group-harness/toolregistry.ts +7 -0
package/ts_web/elements/00group-harness/dees-harness-permission-card/dees-harness-permission-card.ts
CHANGED
|
@@ -10,7 +10,11 @@ import {
|
|
|
10
10
|
cssManager,
|
|
11
11
|
} from '@design.estate/dees-element';
|
|
12
12
|
import { themeDefaultStyles } from '../../00theme.js';
|
|
13
|
-
import type {
|
|
13
|
+
import type {
|
|
14
|
+
IHarnessPermissionRequest,
|
|
15
|
+
IHarnessPermissionViewState,
|
|
16
|
+
THarnessPermissionResponse,
|
|
17
|
+
} from '../interfaces.js';
|
|
14
18
|
import { harnessStringifyValue } from '../harness.helpers.js';
|
|
15
19
|
import '../../00group-button/dees-button/dees-button.js';
|
|
16
20
|
import '../../00group-feedback/dees-badge/dees-badge.js';
|
|
@@ -45,6 +49,12 @@ export class DeesHarnessPermissionCard extends DeesElement {
|
|
|
45
49
|
@property({ type: Boolean })
|
|
46
50
|
accessor busy: boolean = false;
|
|
47
51
|
|
|
52
|
+
@property({ attribute: false })
|
|
53
|
+
accessor viewState: IHarnessPermissionViewState | undefined = undefined;
|
|
54
|
+
|
|
55
|
+
@property({ type: Boolean })
|
|
56
|
+
accessor suppressEntry: boolean = false;
|
|
57
|
+
|
|
48
58
|
@state()
|
|
49
59
|
accessor remember: boolean = false;
|
|
50
60
|
|
|
@@ -53,7 +63,11 @@ export class DeesHarnessPermissionCard extends DeesElement {
|
|
|
53
63
|
accessor answered: THarnessPermissionResponse | undefined = undefined;
|
|
54
64
|
|
|
55
65
|
public get effectiveResponse(): THarnessPermissionResponse | undefined {
|
|
56
|
-
return this.request.response ?? this.answered;
|
|
66
|
+
return this.request.response ?? this.answered ?? this.viewState?.answered;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private get effectiveRemember(): boolean {
|
|
70
|
+
return this.remember || this.viewState?.remember === true;
|
|
57
71
|
}
|
|
58
72
|
|
|
59
73
|
public static styles = [
|
|
@@ -82,6 +96,10 @@ export class DeesHarnessPermissionCard extends DeesElement {
|
|
|
82
96
|
}
|
|
83
97
|
}
|
|
84
98
|
|
|
99
|
+
:host(.no-entry) {
|
|
100
|
+
animation: none;
|
|
101
|
+
}
|
|
102
|
+
|
|
85
103
|
@media (prefers-reduced-motion: reduce) {
|
|
86
104
|
:host {
|
|
87
105
|
animation: none;
|
|
@@ -183,7 +201,7 @@ export class DeesHarnessPermissionCard extends DeesElement {
|
|
|
183
201
|
: ''}
|
|
184
202
|
<div class="actions">
|
|
185
203
|
${this.effectiveResponse
|
|
186
|
-
? html`<span class="answeredNote">Answered: ${this.effectiveResponse}${this.
|
|
204
|
+
? html`<span class="answeredNote">Answered: ${this.effectiveResponse}${this.effectiveRemember ? ' (remembered)' : ''}</span>`
|
|
187
205
|
: html`
|
|
188
206
|
<dees-button type="accent" size="sm" ?disabled=${disabled} @clicked=${() => this.respond('once')}>
|
|
189
207
|
Allow Once
|
|
@@ -197,11 +215,12 @@ export class DeesHarnessPermissionCard extends DeesElement {
|
|
|
197
215
|
<label class="rememberLabel">
|
|
198
216
|
<input
|
|
199
217
|
type="checkbox"
|
|
200
|
-
.checked=${this.
|
|
218
|
+
.checked=${this.effectiveRemember}
|
|
201
219
|
?disabled=${disabled}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
220
|
+
@change=${(event: Event) => {
|
|
221
|
+
this.remember = (event.currentTarget as HTMLInputElement).checked;
|
|
222
|
+
if (this.viewState) this.viewState.remember = this.remember;
|
|
223
|
+
}}
|
|
205
224
|
/>
|
|
206
225
|
remember for this session
|
|
207
226
|
</label>
|
|
@@ -213,13 +232,18 @@ export class DeesHarnessPermissionCard extends DeesElement {
|
|
|
213
232
|
|
|
214
233
|
private respond(response: THarnessPermissionResponse): void {
|
|
215
234
|
if (this.busy || this.effectiveResponse !== undefined) return;
|
|
235
|
+
const remember = this.effectiveRemember || response === 'always';
|
|
216
236
|
this.answered = response;
|
|
237
|
+
if (this.viewState) {
|
|
238
|
+
this.viewState.answered = response;
|
|
239
|
+
this.viewState.remember = remember;
|
|
240
|
+
}
|
|
217
241
|
this.dispatchEvent(
|
|
218
242
|
new CustomEvent('harness-permission-response', {
|
|
219
243
|
detail: {
|
|
220
244
|
requestId: this.request.id,
|
|
221
245
|
response,
|
|
222
|
-
remember
|
|
246
|
+
remember,
|
|
223
247
|
request: this.request,
|
|
224
248
|
},
|
|
225
249
|
bubbles: true,
|
|
@@ -227,4 +251,9 @@ export class DeesHarnessPermissionCard extends DeesElement {
|
|
|
227
251
|
}),
|
|
228
252
|
);
|
|
229
253
|
}
|
|
254
|
+
|
|
255
|
+
public firstUpdated(changedPropertiesArg: Map<string, unknown>): void {
|
|
256
|
+
super.firstUpdated(changedPropertiesArg);
|
|
257
|
+
if (this.suppressEntry) this.classList.add('no-entry');
|
|
258
|
+
}
|
|
230
259
|
}
|
package/ts_web/elements/00group-harness/dees-harness-question-card/dees-harness-question-card.ts
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
cssManager,
|
|
11
11
|
} from '@design.estate/dees-element';
|
|
12
12
|
import { themeDefaultStyles } from '../../00theme.js';
|
|
13
|
-
import type { IHarnessQuestionRequest } from '../interfaces.js';
|
|
13
|
+
import type { IHarnessQuestionRequest, IHarnessQuestionViewState } from '../interfaces.js';
|
|
14
14
|
import '../../00group-button/dees-button/dees-button.js';
|
|
15
15
|
import '../../00group-utility/dees-icon/dees-icon.js';
|
|
16
16
|
|
|
@@ -38,6 +38,12 @@ export class DeesHarnessQuestionCard extends DeesElement {
|
|
|
38
38
|
@property({ type: Boolean })
|
|
39
39
|
accessor busy: boolean = false;
|
|
40
40
|
|
|
41
|
+
@property({ attribute: false })
|
|
42
|
+
accessor viewState: IHarnessQuestionViewState | undefined = undefined;
|
|
43
|
+
|
|
44
|
+
@property({ type: Boolean })
|
|
45
|
+
accessor suppressEntry: boolean = false;
|
|
46
|
+
|
|
41
47
|
/** local optimistic answer; request.response (host echo) takes precedence */
|
|
42
48
|
@state()
|
|
43
49
|
accessor answered: string[] | undefined = undefined;
|
|
@@ -49,7 +55,17 @@ export class DeesHarnessQuestionCard extends DeesElement {
|
|
|
49
55
|
accessor customText: string = '';
|
|
50
56
|
|
|
51
57
|
public get effectiveResponse(): string[] | undefined {
|
|
52
|
-
return this.request.response ?? this.answered;
|
|
58
|
+
return this.request.response ?? this.answered ?? this.viewState?.answered;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private get effectiveSelected(): ReadonlySet<string> {
|
|
62
|
+
return this.selected.size > 0
|
|
63
|
+
? this.selected
|
|
64
|
+
: new Set(this.viewState?.selected ?? []);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private get effectiveCustomText(): string {
|
|
68
|
+
return this.customText || this.viewState?.customText || '';
|
|
53
69
|
}
|
|
54
70
|
|
|
55
71
|
public static styles = [
|
|
@@ -72,6 +88,10 @@ export class DeesHarnessQuestionCard extends DeesElement {
|
|
|
72
88
|
}
|
|
73
89
|
}
|
|
74
90
|
|
|
91
|
+
:host(.no-entry) {
|
|
92
|
+
animation: none;
|
|
93
|
+
}
|
|
94
|
+
|
|
75
95
|
@media (prefers-reduced-motion: reduce) {
|
|
76
96
|
:host {
|
|
77
97
|
animation: none;
|
|
@@ -230,7 +250,7 @@ export class DeesHarnessQuestionCard extends DeesElement {
|
|
|
230
250
|
<div class="options" role=${request.multiSelect ? 'group' : 'radiogroup'}>
|
|
231
251
|
${request.options.map((option) => html`
|
|
232
252
|
<button
|
|
233
|
-
class="option ${this.
|
|
253
|
+
class="option ${this.effectiveSelected.has(option.label) ? 'selected' : ''}"
|
|
234
254
|
type="button"
|
|
235
255
|
?disabled=${disabled}
|
|
236
256
|
@click=${() => this.handleOptionClick(option.label)}
|
|
@@ -249,23 +269,24 @@ export class DeesHarnessQuestionCard extends DeesElement {
|
|
|
249
269
|
<div class="customRow">
|
|
250
270
|
<input
|
|
251
271
|
placeholder="Answer in your own words…"
|
|
252
|
-
.value=${this.
|
|
272
|
+
.value=${this.effectiveCustomText}
|
|
253
273
|
?disabled=${disabled}
|
|
254
274
|
@input=${(event: Event) => {
|
|
255
275
|
this.customText = (event.currentTarget as HTMLInputElement).value;
|
|
276
|
+
if (this.viewState) this.viewState.customText = this.customText;
|
|
256
277
|
}}
|
|
257
278
|
@keydown=${(event: KeyboardEvent) => {
|
|
258
|
-
if (event.key === 'Enter' && this.
|
|
259
|
-
this.respond([...this.
|
|
279
|
+
if (event.key === 'Enter' && this.effectiveCustomText.trim()) {
|
|
280
|
+
this.respond([...this.effectiveSelected, this.effectiveCustomText.trim()]);
|
|
260
281
|
}
|
|
261
282
|
}}
|
|
262
283
|
/>
|
|
263
284
|
<dees-button
|
|
264
285
|
size="sm"
|
|
265
|
-
?disabled=${disabled || (!this.
|
|
286
|
+
?disabled=${disabled || (!this.effectiveCustomText.trim() && !this.effectiveSelected.size)}
|
|
266
287
|
@clicked=${() => {
|
|
267
|
-
const answers = [...this.
|
|
268
|
-
if (this.
|
|
288
|
+
const answers = [...this.effectiveSelected];
|
|
289
|
+
if (this.effectiveCustomText.trim()) answers.push(this.effectiveCustomText.trim());
|
|
269
290
|
this.respond(answers);
|
|
270
291
|
}}
|
|
271
292
|
>Send Answer</dees-button>
|
|
@@ -278,8 +299,8 @@ export class DeesHarnessQuestionCard extends DeesElement {
|
|
|
278
299
|
<dees-button
|
|
279
300
|
type="accent"
|
|
280
301
|
size="sm"
|
|
281
|
-
?disabled=${disabled || !this.
|
|
282
|
-
@clicked=${() => this.respond([...this.
|
|
302
|
+
?disabled=${disabled || !this.effectiveSelected.size}
|
|
303
|
+
@clicked=${() => this.respond([...this.effectiveSelected])}
|
|
283
304
|
>Confirm</dees-button>
|
|
284
305
|
</div>
|
|
285
306
|
`
|
|
@@ -292,10 +313,11 @@ export class DeesHarnessQuestionCard extends DeesElement {
|
|
|
292
313
|
private handleOptionClick(label: string): void {
|
|
293
314
|
if (this.busy || this.effectiveResponse !== undefined) return;
|
|
294
315
|
if (this.request.multiSelect) {
|
|
295
|
-
const next = new Set(this.
|
|
316
|
+
const next = new Set(this.effectiveSelected);
|
|
296
317
|
if (next.has(label)) next.delete(label);
|
|
297
318
|
else next.add(label);
|
|
298
319
|
this.selected = next;
|
|
320
|
+
if (this.viewState) this.viewState.selected = [...next];
|
|
299
321
|
return;
|
|
300
322
|
}
|
|
301
323
|
this.respond([label]);
|
|
@@ -304,6 +326,7 @@ export class DeesHarnessQuestionCard extends DeesElement {
|
|
|
304
326
|
private respond(answers: string[]): void {
|
|
305
327
|
if (this.busy || this.effectiveResponse !== undefined || !answers.length) return;
|
|
306
328
|
this.answered = answers;
|
|
329
|
+
if (this.viewState) this.viewState.answered = answers;
|
|
307
330
|
this.dispatchEvent(
|
|
308
331
|
new CustomEvent('harness-question-response', {
|
|
309
332
|
detail: {
|
|
@@ -316,4 +339,9 @@ export class DeesHarnessQuestionCard extends DeesElement {
|
|
|
316
339
|
}),
|
|
317
340
|
);
|
|
318
341
|
}
|
|
342
|
+
|
|
343
|
+
public firstUpdated(changedPropertiesArg: Map<string, unknown>): void {
|
|
344
|
+
super.firstUpdated(changedPropertiesArg);
|
|
345
|
+
if (this.suppressEntry) this.classList.add('no-entry');
|
|
346
|
+
}
|
|
319
347
|
}
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
cssManager,
|
|
11
11
|
} from '@design.estate/dees-element';
|
|
12
12
|
import { themeDefaultStyles } from '../../00theme.js';
|
|
13
|
-
import type { IHarnessReasoningPart } from '../interfaces.js';
|
|
13
|
+
import type { IHarnessMessageViewState, IHarnessReasoningPart } from '../interfaces.js';
|
|
14
14
|
import { harnessFormatDuration } from '../harness.helpers.js';
|
|
15
15
|
import '../../00group-utility/dees-icon/dees-icon.js';
|
|
16
16
|
|
|
@@ -37,6 +37,9 @@ export class DeesHarnessReasoning extends DeesElement {
|
|
|
37
37
|
@property({ attribute: false })
|
|
38
38
|
accessor reasoningParts: IHarnessReasoningPart[] = [];
|
|
39
39
|
|
|
40
|
+
@property({ attribute: false })
|
|
41
|
+
accessor viewState: IHarnessMessageViewState | undefined = undefined;
|
|
42
|
+
|
|
40
43
|
@state()
|
|
41
44
|
accessor expanded: boolean | undefined = undefined;
|
|
42
45
|
|
|
@@ -178,7 +181,7 @@ export class DeesHarnessReasoning extends DeesElement {
|
|
|
178
181
|
}
|
|
179
182
|
|
|
180
183
|
public get isOpen(): boolean {
|
|
181
|
-
return this.expanded ?? this.isStreaming;
|
|
184
|
+
return this.expanded ?? this.viewState?.reasoningExpanded ?? this.isStreaming;
|
|
182
185
|
}
|
|
183
186
|
|
|
184
187
|
/** All parts joined into the one full trace the expanded body shows. */
|
|
@@ -224,6 +227,7 @@ export class DeesHarnessReasoning extends DeesElement {
|
|
|
224
227
|
aria-expanded=${this.isOpen ? 'true' : 'false'}
|
|
225
228
|
@click=${() => {
|
|
226
229
|
this.expanded = !this.isOpen;
|
|
230
|
+
if (this.viewState) this.viewState.reasoningExpanded = this.expanded;
|
|
227
231
|
}}
|
|
228
232
|
>
|
|
229
233
|
<span class="chevron ${this.isOpen ? 'open' : ''}">
|
package/ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.ts
CHANGED
|
@@ -367,6 +367,8 @@ export class DeesHarnessSessionList extends DeesElement {
|
|
|
367
367
|
}
|
|
368
368
|
|
|
369
369
|
.itemInner {
|
|
370
|
+
position: relative;
|
|
371
|
+
isolation: isolate;
|
|
370
372
|
min-width: 0;
|
|
371
373
|
overflow: hidden;
|
|
372
374
|
border: 1px solid var(--card-inner-border);
|
|
@@ -399,24 +401,34 @@ export class DeesHarnessSessionList extends DeesElement {
|
|
|
399
401
|
|
|
400
402
|
@keyframes workingBackgroundScan {
|
|
401
403
|
from {
|
|
402
|
-
|
|
404
|
+
transform: translate3d(-60%, 0, 0);
|
|
403
405
|
}
|
|
404
406
|
to {
|
|
405
|
-
|
|
407
|
+
transform: translate3d(0, 0, 0);
|
|
406
408
|
}
|
|
407
409
|
}
|
|
408
410
|
|
|
409
411
|
.item.state-working .itemInner {
|
|
410
|
-
background:
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
412
|
+
background: var(--dees-color-bg-primary);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
.item.state-working .itemInner::before {
|
|
416
|
+
content: '';
|
|
417
|
+
position: absolute;
|
|
418
|
+
z-index: -1;
|
|
419
|
+
inset: 0 auto 0 0;
|
|
420
|
+
width: 250%;
|
|
421
|
+
pointer-events: none;
|
|
422
|
+
background: linear-gradient(
|
|
423
|
+
105deg,
|
|
424
|
+
transparent 40%,
|
|
425
|
+
color-mix(in srgb, var(--session-working) 6%, transparent) 45%,
|
|
426
|
+
color-mix(in srgb, var(--session-working) 20%, transparent) 50%,
|
|
427
|
+
color-mix(in srgb, var(--session-working) 6%, transparent) 55%,
|
|
428
|
+
transparent 60%
|
|
429
|
+
);
|
|
430
|
+
transform: translate3d(-60%, 0, 0);
|
|
431
|
+
will-change: transform;
|
|
420
432
|
animation: workingBackgroundScan 2s linear infinite;
|
|
421
433
|
}
|
|
422
434
|
|
|
@@ -923,12 +935,18 @@ export class DeesHarnessSessionList extends DeesElement {
|
|
|
923
935
|
.item,
|
|
924
936
|
.itemInner,
|
|
925
937
|
.item.state-attention .itemInner,
|
|
938
|
+
.item.state-working .itemInner::before,
|
|
926
939
|
.item.state-working .itemHeader .stateDot,
|
|
927
940
|
.scrollShadow,
|
|
928
941
|
.expandToggle dees-icon {
|
|
929
942
|
animation: none;
|
|
930
943
|
transition: none;
|
|
931
944
|
}
|
|
945
|
+
|
|
946
|
+
.item.state-working .itemInner::before {
|
|
947
|
+
transform: translate3d(-60%, 0, 0);
|
|
948
|
+
will-change: auto;
|
|
949
|
+
}
|
|
932
950
|
}
|
|
933
951
|
|
|
934
952
|
@media (pointer: coarse) {
|
package/ts_web/elements/00group-harness/dees-harness-session-sidebar/dees-harness-session-sidebar.ts
CHANGED
|
@@ -694,8 +694,14 @@ export class DeesHarnessSessionSidebar extends DeesElement {
|
|
|
694
694
|
<span class="sectionHeadingText">${labelArg}</span>
|
|
695
695
|
${summaryArg ? html`<span class="sectionSummary">${summaryArg}</span>` : ''}
|
|
696
696
|
</button>
|
|
697
|
-
<div
|
|
698
|
-
|
|
697
|
+
<div
|
|
698
|
+
id=${contentId}
|
|
699
|
+
class="sectionContent"
|
|
700
|
+
role="region"
|
|
701
|
+
aria-hidden=${String(!expanded)}
|
|
702
|
+
?hidden=${!expanded}
|
|
703
|
+
>
|
|
704
|
+
${expanded ? contentArg : ''}
|
|
699
705
|
</div>
|
|
700
706
|
</section>
|
|
701
707
|
`;
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
} from '@design.estate/dees-element';
|
|
12
12
|
import { themeDefaultStyles } from '../../00theme.js';
|
|
13
13
|
import type {
|
|
14
|
+
IHarnessMessageViewState,
|
|
14
15
|
IHarnessToolCall,
|
|
15
16
|
THarnessContentBlock,
|
|
16
17
|
THarnessMessageStreamDelta,
|
|
@@ -69,6 +70,9 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
69
70
|
@property({ type: Boolean })
|
|
70
71
|
accessor allowSubtaskStreams: boolean = true;
|
|
71
72
|
|
|
73
|
+
@property({ attribute: false })
|
|
74
|
+
accessor viewState: IHarnessMessageViewState | undefined = undefined;
|
|
75
|
+
|
|
72
76
|
@state()
|
|
73
77
|
accessor expanded: boolean | undefined = undefined;
|
|
74
78
|
|
|
@@ -102,9 +106,12 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
102
106
|
private observedBodyInner: Element | null = null;
|
|
103
107
|
private fullscreenPortal: HTMLElementTagNameMap['dees-harness-tool-fullscreen'] | null = null;
|
|
104
108
|
private disclosureFrame: number | null = null;
|
|
109
|
+
private returnScrollFrame: number | null = null;
|
|
105
110
|
private subtaskResultElement: HTMLElement | null = null;
|
|
106
111
|
private subtaskResultResizeObserver: ResizeObserver | null = null;
|
|
107
112
|
private terminalTailFollowing = true;
|
|
113
|
+
private terminalScrollHydrated = false;
|
|
114
|
+
private terminalScrollHydrationFrame: number | null = null;
|
|
108
115
|
private terminalTailReturnTimeout: ReturnType<typeof setTimeout> | null = null;
|
|
109
116
|
private terminalTailReturnDelayMs = 5000;
|
|
110
117
|
|
|
@@ -208,18 +215,18 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
208
215
|
|
|
209
216
|
@keyframes harness-card-open-chat-scan {
|
|
210
217
|
0% {
|
|
211
|
-
|
|
218
|
+
transform: translate3d(-60%, 0, 0);
|
|
212
219
|
opacity: 0;
|
|
213
220
|
}
|
|
214
221
|
1% {
|
|
215
222
|
opacity: 0.35;
|
|
216
223
|
}
|
|
217
224
|
20% {
|
|
218
|
-
|
|
225
|
+
transform: translate3d(0, 0, 0);
|
|
219
226
|
opacity: 0.35;
|
|
220
227
|
}
|
|
221
228
|
24%, 100% {
|
|
222
|
-
|
|
229
|
+
transform: translate3d(0, 0, 0);
|
|
223
230
|
opacity: 0;
|
|
224
231
|
}
|
|
225
232
|
}
|
|
@@ -608,7 +615,8 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
608
615
|
.harness-card.outcomeScan::after {
|
|
609
616
|
content: '';
|
|
610
617
|
position: absolute;
|
|
611
|
-
inset: 0;
|
|
618
|
+
inset: 0 auto 0 0;
|
|
619
|
+
width: 250%;
|
|
612
620
|
pointer-events: none;
|
|
613
621
|
background: linear-gradient(
|
|
614
622
|
105deg,
|
|
@@ -617,7 +625,9 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
617
625
|
color-mix(in srgb, var(--harness-outcome-scan-color) 14%, transparent) 50%,
|
|
618
626
|
color-mix(in srgb, var(--harness-outcome-scan-color) 3%, transparent) 55%,
|
|
619
627
|
transparent 60%
|
|
620
|
-
)
|
|
628
|
+
);
|
|
629
|
+
transform: translate3d(-60%, 0, 0);
|
|
630
|
+
will-change: transform;
|
|
621
631
|
animation: harness-tool-outcome-scan 0.48s linear 0.08s both;
|
|
622
632
|
}
|
|
623
633
|
|
|
@@ -631,8 +641,8 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
631
641
|
}
|
|
632
642
|
|
|
633
643
|
@keyframes harness-tool-outcome-scan {
|
|
634
|
-
from {
|
|
635
|
-
to {
|
|
644
|
+
from { transform: translate3d(-60%, 0, 0); }
|
|
645
|
+
to { transform: translate3d(0, 0, 0); }
|
|
636
646
|
}
|
|
637
647
|
|
|
638
648
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -647,6 +657,7 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
647
657
|
.harness-card.outcomeScan::after {
|
|
648
658
|
animation: none;
|
|
649
659
|
opacity: 0;
|
|
660
|
+
will-change: auto;
|
|
650
661
|
}
|
|
651
662
|
}
|
|
652
663
|
`,
|
|
@@ -665,6 +676,7 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
665
676
|
|
|
666
677
|
public get isOpen(): boolean {
|
|
667
678
|
if (this.expanded !== undefined) return this.expanded;
|
|
679
|
+
if (this.viewState?.toolExpanded !== undefined) return this.viewState.toolExpanded;
|
|
668
680
|
const descriptor = this.descriptor;
|
|
669
681
|
if (descriptor.kind === 'subtask' && this.call.subtask) {
|
|
670
682
|
return this.allowSubtaskStreams
|
|
@@ -774,12 +786,14 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
774
786
|
if (this.disclosureFrame !== null) cancelAnimationFrame(this.disclosureFrame);
|
|
775
787
|
this.disclosureFrame = null;
|
|
776
788
|
this.expanded = false;
|
|
789
|
+
if (this.viewState) this.viewState.toolExpanded = false;
|
|
777
790
|
return;
|
|
778
791
|
}
|
|
779
792
|
if (this.bodyMounted) {
|
|
780
793
|
if (this.disclosureFrame !== null) cancelAnimationFrame(this.disclosureFrame);
|
|
781
794
|
this.disclosureFrame = null;
|
|
782
795
|
this.expanded = true;
|
|
796
|
+
if (this.viewState) this.viewState.toolExpanded = true;
|
|
783
797
|
return;
|
|
784
798
|
}
|
|
785
799
|
this.bodyMounted = true;
|
|
@@ -791,12 +805,18 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
791
805
|
if (!this.isConnected || this.expanded !== false) return;
|
|
792
806
|
this.shadowRoot?.querySelector<HTMLElement>('.bodyDisclosure')?.getBoundingClientRect();
|
|
793
807
|
this.expanded = true;
|
|
808
|
+
if (this.viewState) this.viewState.toolExpanded = true;
|
|
794
809
|
});
|
|
795
810
|
});
|
|
796
811
|
};
|
|
797
812
|
|
|
798
813
|
private readonly openFullscreen = (): void => {
|
|
799
814
|
if (this.fullscreenPortal || this.hasSubtaskPreview) return;
|
|
815
|
+
this.dispatchEvent(new CustomEvent('harness-card-retention', {
|
|
816
|
+
detail: { active: true },
|
|
817
|
+
bubbles: true,
|
|
818
|
+
composed: true,
|
|
819
|
+
}));
|
|
800
820
|
// Appended to document.body: content-visibility containment in the
|
|
801
821
|
// transcript would trap a position: fixed layer inside this card.
|
|
802
822
|
const portal = document.createElement('dees-harness-tool-fullscreen');
|
|
@@ -826,7 +846,10 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
826
846
|
// reduced-motion skips the animation, so animationend never fires there
|
|
827
847
|
if (this.flashFallbackTimeout) clearTimeout(this.flashFallbackTimeout);
|
|
828
848
|
this.flashFallbackTimeout = setTimeout(() => this.endReturnFlash(), 900);
|
|
829
|
-
|
|
849
|
+
if (this.returnScrollFrame !== null) cancelAnimationFrame(this.returnScrollFrame);
|
|
850
|
+
this.returnScrollFrame = requestAnimationFrame(() => {
|
|
851
|
+
this.returnScrollFrame = null;
|
|
852
|
+
if (!this.isConnected) return;
|
|
830
853
|
this.scrollIntoView({ block: 'center', behavior: 'smooth' });
|
|
831
854
|
});
|
|
832
855
|
};
|
|
@@ -838,6 +861,11 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
838
861
|
}
|
|
839
862
|
if (!this.returnFlash) return;
|
|
840
863
|
this.returnFlash = false;
|
|
864
|
+
this.dispatchEvent(new CustomEvent('harness-card-retention', {
|
|
865
|
+
detail: { active: false },
|
|
866
|
+
bubbles: true,
|
|
867
|
+
composed: true,
|
|
868
|
+
}));
|
|
841
869
|
this.dispatchEvent(new CustomEvent('harness-card-flash', {
|
|
842
870
|
detail: { active: false },
|
|
843
871
|
bubbles: true,
|
|
@@ -861,11 +889,44 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
861
889
|
|
|
862
890
|
public willUpdate(changedProperties: Map<PropertyKey, unknown>): void {
|
|
863
891
|
super.willUpdate(changedProperties);
|
|
892
|
+
if (changedProperties.has('viewState') || changedProperties.has('call')) {
|
|
893
|
+
this.terminalScrollHydrated = false;
|
|
894
|
+
if (this.terminalScrollHydrationFrame !== null) {
|
|
895
|
+
cancelAnimationFrame(this.terminalScrollHydrationFrame);
|
|
896
|
+
this.terminalScrollHydrationFrame = null;
|
|
897
|
+
}
|
|
898
|
+
if (this.expanded === undefined && this.viewState?.toolExpanded !== undefined) {
|
|
899
|
+
this.expanded = this.viewState.toolExpanded;
|
|
900
|
+
}
|
|
901
|
+
if (!this.outputExpanded && this.viewState?.toolOutputExpanded === true) this.outputExpanded = true;
|
|
902
|
+
if (this.diffViewOverride === null && this.viewState?.toolDiffView !== undefined) {
|
|
903
|
+
this.diffViewOverride = this.viewState.toolDiffView;
|
|
904
|
+
}
|
|
905
|
+
if (this.viewState?.toolTerminalTailFollowing !== undefined) {
|
|
906
|
+
this.terminalTailFollowing = this.viewState.toolTerminalTailFollowing;
|
|
907
|
+
}
|
|
908
|
+
if (this.viewState) {
|
|
909
|
+
const subtask = this.call.subtask;
|
|
910
|
+
const ownsLiveTranscript = Boolean(
|
|
911
|
+
this.hasLiveSubtaskPreview && subtask?.previewState === 'ready',
|
|
912
|
+
);
|
|
913
|
+
if (!subtask || !ownsLiveTranscript) {
|
|
914
|
+
delete this.viewState.subtaskTranscript;
|
|
915
|
+
delete this.viewState.subtaskTranscriptSessionId;
|
|
916
|
+
} else if (
|
|
917
|
+
this.viewState.subtaskTranscriptSessionId !== subtask.sessionId
|
|
918
|
+
|| !this.viewState.subtaskTranscript
|
|
919
|
+
) {
|
|
920
|
+
this.viewState.subtaskTranscriptSessionId = subtask.sessionId;
|
|
921
|
+
this.viewState.subtaskTranscript = { messages: {}, permissions: {}, questions: {} };
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
}
|
|
864
925
|
const previousCall = changedProperties.get('call') as IHarnessToolCall | undefined;
|
|
865
926
|
if (!previousCall) return;
|
|
866
927
|
if (previousCall.id !== this.call.id) {
|
|
867
|
-
this.diffViewOverride = null;
|
|
868
|
-
this.terminalTailFollowing = true;
|
|
928
|
+
this.diffViewOverride = this.viewState?.toolDiffView ?? null;
|
|
929
|
+
this.terminalTailFollowing = this.viewState?.toolTerminalTailFollowing ?? true;
|
|
869
930
|
this.cancelTerminalTailReturn();
|
|
870
931
|
return;
|
|
871
932
|
}
|
|
@@ -887,6 +948,10 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
887
948
|
public updated(changedProperties: Map<PropertyKey, unknown>): void {
|
|
888
949
|
super.updated(changedProperties);
|
|
889
950
|
if (!this.isConnected) return;
|
|
951
|
+
this.terminalScrollHydrationFrame ??= requestAnimationFrame(() => {
|
|
952
|
+
this.terminalScrollHydrationFrame = null;
|
|
953
|
+
if (this.isConnected) this.terminalScrollHydrated = true;
|
|
954
|
+
});
|
|
890
955
|
if (this.isOpen && !this.bodyMounted) this.bodyMounted = true;
|
|
891
956
|
if (changedProperties.has('call') && this.fullscreenPortal) {
|
|
892
957
|
this.fullscreenPortal.call = this.enrichedCall;
|
|
@@ -923,12 +988,21 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
923
988
|
});
|
|
924
989
|
this.bodyResizeObserver.observe(bodyInner);
|
|
925
990
|
if (this.terminalTailFollowing) this.scrollTerminalToTail();
|
|
991
|
+
else if (this.viewState?.toolTerminalScrollTop !== undefined) {
|
|
992
|
+
const frame = this.shadowRoot?.querySelector<HTMLElement>('.bodyClipFrame');
|
|
993
|
+
if (frame) this.setTerminalScrollTop(frame, this.viewState.toolTerminalScrollTop);
|
|
994
|
+
}
|
|
926
995
|
}
|
|
927
996
|
|
|
928
997
|
private readonly handleBodyScroll = (eventArg: Event): void => {
|
|
929
998
|
if (this.descriptor.kind !== 'terminal' || this.uncapped) return;
|
|
999
|
+
if (!this.terminalScrollHydrated) return;
|
|
930
1000
|
const frame = eventArg.currentTarget as HTMLElement;
|
|
931
1001
|
this.terminalTailFollowing = frame.scrollHeight - frame.scrollTop - frame.clientHeight <= 2;
|
|
1002
|
+
if (this.viewState) {
|
|
1003
|
+
this.viewState.toolTerminalTailFollowing = this.terminalTailFollowing;
|
|
1004
|
+
this.viewState.toolTerminalScrollTop = frame.scrollTop;
|
|
1005
|
+
}
|
|
932
1006
|
if (this.terminalTailFollowing) this.cancelTerminalTailReturn();
|
|
933
1007
|
};
|
|
934
1008
|
|
|
@@ -936,7 +1010,16 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
936
1010
|
if (this.descriptor.kind !== 'terminal' || this.uncapped || !this.isOpen) return;
|
|
937
1011
|
const frame = this.shadowRoot?.querySelector<HTMLElement>('.bodyClipFrame');
|
|
938
1012
|
if (!frame) return;
|
|
939
|
-
|
|
1013
|
+
if (this.viewState?.toolTerminalTailFollowing === false) {
|
|
1014
|
+
this.terminalTailFollowing = false;
|
|
1015
|
+
this.setTerminalScrollTop(frame, this.viewState.toolTerminalScrollTop ?? frame.scrollTop);
|
|
1016
|
+
return;
|
|
1017
|
+
}
|
|
1018
|
+
this.setTerminalScrollTop(frame, frame.scrollHeight);
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
private setTerminalScrollTop(frameArg: HTMLElement, scrollTopArg: number): void {
|
|
1022
|
+
frameArg.scrollTop = scrollTopArg;
|
|
940
1023
|
}
|
|
941
1024
|
|
|
942
1025
|
private readonly scheduleTerminalTailReturn = (): void => {
|
|
@@ -945,7 +1028,12 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
945
1028
|
this.terminalTailReturnTimeout = setTimeout(() => {
|
|
946
1029
|
this.terminalTailReturnTimeout = null;
|
|
947
1030
|
this.terminalTailFollowing = true;
|
|
1031
|
+
if (this.viewState) this.viewState.toolTerminalTailFollowing = true;
|
|
948
1032
|
this.scrollTerminalToTail();
|
|
1033
|
+
if (this.viewState) {
|
|
1034
|
+
const frame = this.shadowRoot?.querySelector<HTMLElement>('.bodyClipFrame');
|
|
1035
|
+
if (frame) this.viewState.toolTerminalScrollTop = frame.scrollTop;
|
|
1036
|
+
}
|
|
949
1037
|
}, this.terminalTailReturnDelayMs);
|
|
950
1038
|
};
|
|
951
1039
|
|
|
@@ -957,6 +1045,7 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
957
1045
|
|
|
958
1046
|
private readonly handleDiffViewChange = (eventArg: CustomEvent<IDiffViewChangeDetail>): void => {
|
|
959
1047
|
this.diffViewOverride = eventArg.detail.diffView;
|
|
1048
|
+
if (this.viewState) this.viewState.toolDiffView = this.diffViewOverride;
|
|
960
1049
|
};
|
|
961
1050
|
|
|
962
1051
|
private readonly syncSubtaskResultScroll = (): void => {
|
|
@@ -998,6 +1087,15 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
998
1087
|
cancelAnimationFrame(this.disclosureFrame);
|
|
999
1088
|
this.disclosureFrame = null;
|
|
1000
1089
|
}
|
|
1090
|
+
if (this.returnScrollFrame !== null) {
|
|
1091
|
+
cancelAnimationFrame(this.returnScrollFrame);
|
|
1092
|
+
this.returnScrollFrame = null;
|
|
1093
|
+
}
|
|
1094
|
+
if (this.terminalScrollHydrationFrame !== null) {
|
|
1095
|
+
cancelAnimationFrame(this.terminalScrollHydrationFrame);
|
|
1096
|
+
this.terminalScrollHydrationFrame = null;
|
|
1097
|
+
}
|
|
1098
|
+
this.terminalScrollHydrated = false;
|
|
1001
1099
|
if (this.flashFallbackTimeout) {
|
|
1002
1100
|
clearTimeout(this.flashFallbackTimeout);
|
|
1003
1101
|
this.flashFallbackTimeout = null;
|
|
@@ -1007,8 +1105,16 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
1007
1105
|
this.outcomeScanFallbackTimeout = null;
|
|
1008
1106
|
}
|
|
1009
1107
|
this.cancelTerminalTailReturn();
|
|
1108
|
+
if (this.fullscreenPortal || this.returnFlash) {
|
|
1109
|
+
this.dispatchEvent(new CustomEvent('harness-card-retention', {
|
|
1110
|
+
detail: { active: false },
|
|
1111
|
+
bubbles: true,
|
|
1112
|
+
composed: true,
|
|
1113
|
+
}));
|
|
1114
|
+
}
|
|
1010
1115
|
this.fullscreenPortal?.remove();
|
|
1011
1116
|
this.fullscreenPortal = null;
|
|
1117
|
+
this.returnFlash = false;
|
|
1012
1118
|
this.bodyResizeObserver?.disconnect();
|
|
1013
1119
|
this.bodyResizeObserver = null;
|
|
1014
1120
|
this.observedBodyInner = null;
|
|
@@ -1064,6 +1170,7 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
1064
1170
|
.questions=${subtask.questions ?? []}
|
|
1065
1171
|
.status=${subtask.status}
|
|
1066
1172
|
.toolRegistry=${this.toolRegistry}
|
|
1173
|
+
.viewState=${this.viewState?.subtaskTranscript}
|
|
1067
1174
|
.allowSubtaskStreams=${false}
|
|
1068
1175
|
.autoFollow=${this.isOpen}
|
|
1069
1176
|
.hideScrollbar=${true}
|
|
@@ -1160,6 +1267,7 @@ export class DeesHarnessToolCard extends DeesElement {
|
|
|
1160
1267
|
type="button"
|
|
1161
1268
|
@click=${() => {
|
|
1162
1269
|
this.outputExpanded = true;
|
|
1270
|
+
if (this.viewState) this.viewState.toolOutputExpanded = true;
|
|
1163
1271
|
}}
|
|
1164
1272
|
>
|
|
1165
1273
|
Show all
|