@adea-ai/ui 0.67.1 → 0.68.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/README.md +58 -0
- package/dist/NOTICE +34 -0
- package/dist/components/conversation/index.d.ts +1 -0
- package/dist/components/conversation/index.d.ts.map +1 -1
- package/dist/components/conversation/index.js +2 -1
- package/dist/components/conversation/transcript-composition.d.ts +66 -0
- package/dist/components/conversation/transcript-composition.d.ts.map +1 -0
- package/dist/components/conversation/transcript-composition.js +395 -0
- package/dist/components/conversation/transcript-composition.js.map +1 -0
- package/dist/components/conversation/transcript-folding.d.ts +22 -0
- package/dist/components/conversation/transcript-folding.d.ts.map +1 -0
- package/dist/components/conversation/transcript-folding.js +43 -0
- package/dist/components/conversation/transcript-folding.js.map +1 -0
- package/dist/components/conversation/transcript-grouping.d.ts +54 -0
- package/dist/components/conversation/transcript-grouping.d.ts.map +1 -0
- package/dist/components/conversation/transcript-grouping.js +155 -0
- package/dist/components/conversation/transcript-grouping.js.map +1 -0
- package/dist/index.js +2 -1
- package/dist/r/conversation.json +15 -0
- package/dist/r/registry.json +15 -0
- package/dist/r/src/components/conversation/index.ts +17 -0
- package/dist/r/src/components/conversation/transcript-composition.tsx +555 -0
- package/dist/r/src/components/conversation/transcript-folding.ts +61 -0
- package/dist/r/src/components/conversation/transcript-grouping.ts +204 -0
- package/package.json +8 -1
- package/registry.json +15 -0
- package/src/components/conversation/index.ts +17 -0
- package/src/components/conversation/transcript-composition.tsx +555 -0
- package/src/components/conversation/transcript-folding.ts +61 -0
- package/src/components/conversation/transcript-grouping.ts +204 -0
package/README.md
CHANGED
|
@@ -448,3 +448,61 @@ draft state, persistence, message reconciliation and editor behavior. The model
|
|
|
448
448
|
does not read storage or the clipboard, upload files, edit a textarea, or
|
|
449
449
|
provide undo/history, previews or chips. Its selected source and Apache-2.0
|
|
450
450
|
attribution are recorded in the issue #532 entry in `NOTICE`.
|
|
451
|
+
|
|
452
|
+
## Transcript composition
|
|
453
|
+
|
|
454
|
+
`TranscriptComposition` assembles ordered host-classified rows, contiguous groups,
|
|
455
|
+
turn presentation and accessible fold controls. Import it from the public component
|
|
456
|
+
subpath:
|
|
457
|
+
|
|
458
|
+
```tsx
|
|
459
|
+
import {
|
|
460
|
+
TranscriptComposition,
|
|
461
|
+
type TranscriptCompositionRendererProps,
|
|
462
|
+
type TranscriptRow,
|
|
463
|
+
} from '@adea-ai/ui/components/conversation/transcript-composition'
|
|
464
|
+
|
|
465
|
+
type Message = { text: string }
|
|
466
|
+
const rows: readonly TranscriptRow<Message>[] = [
|
|
467
|
+
{ id: 'question-1', value: { text: 'Inspect the cursor.' }, opensTurn: 'reset' },
|
|
468
|
+
{
|
|
469
|
+
id: 'tool-1',
|
|
470
|
+
value: { text: 'Read the cursor.' },
|
|
471
|
+
fold: 'tool',
|
|
472
|
+
call: { phase: 'request', id: 'call-1' },
|
|
473
|
+
},
|
|
474
|
+
]
|
|
475
|
+
|
|
476
|
+
function HostMessage(props: TranscriptCompositionRendererProps<Message>) {
|
|
477
|
+
return <article>{props.row.value.text}</article>
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
export function TranscriptPreview() {
|
|
481
|
+
return <TranscriptComposition rows={rows} renderRow={HostMessage} />
|
|
482
|
+
}
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
Each row needs a stable unique `id` within its transcript. The host supplies the
|
|
486
|
+
Solid row component and classifies turn boundaries, calls, conclusions,
|
|
487
|
+
always-visible actions and redacted values. The renderer does not parse protocol
|
|
488
|
+
payloads or decide permission, session, event, delivery or success state.
|
|
489
|
+
|
|
490
|
+
Settled tool folds start closed and unmount their hidden row payloads. Live rows
|
|
491
|
+
stay open until the host marks them settled; an explicit row choice survives that
|
|
492
|
+
running-state transition. `foldMode="prose"` folds host-marked eligible activity
|
|
493
|
+
before a host-designated conclusion, leaving that conclusion visible.
|
|
494
|
+
The `foldState="collapsed"` command keeps hidden
|
|
495
|
+
content mounted. It folds eligible rows before a host-marked conclusion; without
|
|
496
|
+
that boundary it leaves prose visible and can still collapse explicitly classified
|
|
497
|
+
tool calls. Always-visible rows stay in place. `disclosure` plus
|
|
498
|
+
`onDisclosureChange` lets an application restore explicit choices from its own
|
|
499
|
+
durable store using `transcriptDisclosureKey`.
|
|
500
|
+
|
|
501
|
+
`bun run check:packed-transcript` installs the actual tarball without optional
|
|
502
|
+
chart/carousel engines, compiles both published export conditions, and checks the
|
|
503
|
+
same behavior in headless Chromium, WebKit and native Node SSR. It covers row-owner
|
|
504
|
+
identity through loose-to-turn promotion, tool request counting, mounted prose,
|
|
505
|
+
keyboard disclosure, visible actions and automated accessibility. This is shared
|
|
506
|
+
composition evidence; bounded runtime projection, storage and production chat
|
|
507
|
+
integration remain application acceptance gates. Attribution for the selected
|
|
508
|
+
KiroCrew source contracts is recorded in the issue-specific `NOTICE` entry.
|
package/dist/NOTICE
CHANGED
|
@@ -291,3 +291,37 @@ refused. React, Lexical, browser clipboard/File handling, localStorage side-tabl
|
|
|
291
291
|
recovery, backend message reconciliation, uploads, textarea editing, previews,
|
|
292
292
|
chips, undo/history and submit/persistence authority are not included. This
|
|
293
293
|
selected model is not rich editing, complete Chat, or application adoption.
|
|
294
|
+
|
|
295
|
+
## Shared transcript composition translated from KiroCrew
|
|
296
|
+
|
|
297
|
+
`packages/ui/src/components/conversation/transcript-grouping.ts`,
|
|
298
|
+
`transcript-folding.ts` and the `transcript-composition.tsx` component substantially
|
|
299
|
+
translate the ordered display grouping and turn disclosure contracts in
|
|
300
|
+
`website/src/app-sdk/ChatMessageList.tsx`,
|
|
301
|
+
`website/src/pages/chat/groupDisplayItems.ts`,
|
|
302
|
+
`website/src/pages/chat/TurnBlock.tsx`,
|
|
303
|
+
`website/src/pages/chat/CollapsibleToolGroup.tsx` and
|
|
304
|
+
`website/src/pages/chat/rowDisclosure.tsx`, pinned at KiroCrew revision
|
|
305
|
+
`283e136c0f902e965a535a7c9548c57c7504fed0`.
|
|
306
|
+
|
|
307
|
+
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
308
|
+
This product includes software developed at Amazon.com, Inc.
|
|
309
|
+
(https://www.amazon.com/). Licensed under the Apache License, Version 2.0.
|
|
310
|
+
|
|
311
|
+
Retained: ordered host-classified turns and contiguous groups, structural sharing,
|
|
312
|
+
stable row owners during loose-to-turn promotion, running/default disclosure,
|
|
313
|
+
host-restorable explicit pins, distinct request counting, tool-payload unmounting,
|
|
314
|
+
mounted interim prose, and visible host-marked actionable or interactive rows.
|
|
315
|
+
The host supplies row identity, redaction, conclusion and call classifications;
|
|
316
|
+
the renderer owns no protocol parser, permission, session, event or success
|
|
317
|
+
authority. Solid/Kobalte-compatible controls and keyed row owners replace React,
|
|
318
|
+
Redux and Framer Motion ownership. Relevant test contracts come from
|
|
319
|
+
`website/src/test/groupDisplayItems.test.ts`,
|
|
320
|
+
`website/src/test/groupDisplayItems.structuralSharing.test.ts`,
|
|
321
|
+
`website/src/test/TurnBlock.test.tsx`,
|
|
322
|
+
`website/src/test/TurnBlock.disclosurePin.test.tsx`,
|
|
323
|
+
`website/src/test/TurnBlock.disclosureDurable.test.tsx`,
|
|
324
|
+
`website/src/test/TurnBlock.rowMemo.test.tsx` and
|
|
325
|
+
`website/src/test/rowDisclosure.test.tsx`; compiled and Solid packed consumers are
|
|
326
|
+
exercised in headless Chromium, WebKit and native Node SSR. Full runtime projection,
|
|
327
|
+
durable application storage and production Chat adoption remain host-owned gates.
|
|
@@ -4,6 +4,7 @@ export { ConversationAvatar, type ConversationAvatarKind, type ConversationAvata
|
|
|
4
4
|
export { ConversationSurface, type ConversationSurfaceProps, type ConversationReadingPosition, } from './conversation-surface';
|
|
5
5
|
export { ComposerAttachmentButton, ComposerHint, MessageComposer, type MessageComposerProps, } from './message-composer';
|
|
6
6
|
export { MessageBody, MessageDayDivider, MessageGroup, MessageRow, type MessageRowProps, } from './message-row';
|
|
7
|
+
export { TranscriptComposition, transcriptDisclosureKey, type TranscriptCompositionProps, type TranscriptCompositionFold, type TranscriptCompositionRowContext, type TranscriptCompositionRendererProps, type TranscriptDisplayKind, type GroupedTranscript, type TranscriptDisplayItem, type TranscriptFoldState, type TranscriptFoldMode, type TranscriptFoldPlan, type TranscriptMounting, type TranscriptRow, type TranscriptTurnItem, } from './transcript-composition';
|
|
7
8
|
export { AttachmentCard, ThreadPanel, type AttachmentCardProps, type ThreadPanelProps, } from './thread-panel';
|
|
8
9
|
export { countLines, expandAll, findTokenRanges, formatToken, isPasteBlock, nextSeq, pruneBlocks, recollapsePastes, remapCarriedBlocks, shouldCollapse, stripTrailingBlankLines, tokenRangeAt, PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, type PasteBlock, } from './paste-tokens';
|
|
9
10
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAChG,OAAO,EAAE,cAAc,EAAE,KAAK,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAChG,OAAO,EACL,kBAAkB,EAClB,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,GAC7B,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,mBAAmB,EACnB,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,GACjC,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,wBAAwB,EACxB,YAAY,EACZ,eAAe,EACf,KAAK,oBAAoB,GAC1B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,UAAU,EACV,KAAK,eAAe,GACrB,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,cAAc,EACd,WAAW,EACX,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EACL,UAAU,EACV,SAAS,EACT,eAAe,EACf,WAAW,EACX,YAAY,EACZ,OAAO,EACP,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,uBAAuB,EACvB,YAAY,EACZ,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,KAAK,UAAU,GAChB,MAAM,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAChG,OAAO,EAAE,cAAc,EAAE,KAAK,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAChG,OAAO,EACL,kBAAkB,EAClB,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,GAC7B,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,mBAAmB,EACnB,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,GACjC,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,wBAAwB,EACxB,YAAY,EACZ,eAAe,EACf,KAAK,oBAAoB,GAC1B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,UAAU,EACV,KAAK,eAAe,GACrB,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,EAC9B,KAAK,+BAA+B,EACpC,KAAK,kCAAkC,EACvC,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,kBAAkB,GACxB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EACL,cAAc,EACd,WAAW,EACX,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EACL,UAAU,EACV,SAAS,EACT,eAAe,EACf,WAAW,EACX,YAAY,EACZ,OAAO,EACP,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,uBAAuB,EACvB,YAAY,EACZ,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,KAAK,UAAU,GAChB,MAAM,gBAAgB,CAAA"}
|
|
@@ -4,6 +4,7 @@ import { ConversationAvatar } from "./conversation-avatar.js";
|
|
|
4
4
|
import { ConversationSurface } from "./conversation-surface.js";
|
|
5
5
|
import { ComposerAttachmentButton, ComposerHint, MessageComposer } from "./message-composer.js";
|
|
6
6
|
import { MessageBody, MessageDayDivider, MessageGroup, MessageRow } from "./message-row.js";
|
|
7
|
+
import { TranscriptComposition, transcriptDisclosureKey } from "./transcript-composition.js";
|
|
7
8
|
import { AttachmentCard, ThreadPanel } from "./thread-panel.js";
|
|
8
9
|
import { PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, countLines, expandAll, findTokenRanges, formatToken, isPasteBlock, nextSeq, pruneBlocks, recollapsePastes, remapCarriedBlocks, shouldCollapse, stripTrailingBlankLines, tokenRangeAt } from "./paste-tokens.js";
|
|
9
|
-
export { AttachmentCard, BusySendButton, ChatComposer, ComposerAttachmentButton, ComposerHint, ConversationAvatar, ConversationSurface, MessageBody, MessageComposer, MessageDayDivider, MessageGroup, MessageRow, PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, ThreadPanel, countLines, expandAll, findTokenRanges, formatToken, isPasteBlock, nextSeq, pruneBlocks, recollapsePastes, remapCarriedBlocks, shouldCollapse, stripTrailingBlankLines, tokenRangeAt };
|
|
10
|
+
export { AttachmentCard, BusySendButton, ChatComposer, ComposerAttachmentButton, ComposerHint, ConversationAvatar, ConversationSurface, MessageBody, MessageComposer, MessageDayDivider, MessageGroup, MessageRow, PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, ThreadPanel, TranscriptComposition, countLines, expandAll, findTokenRanges, formatToken, isPasteBlock, nextSeq, pruneBlocks, recollapsePastes, remapCarriedBlocks, shouldCollapse, stripTrailingBlankLines, tokenRangeAt, transcriptDisclosureKey };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { Component, ComponentProps } from 'solid-js';
|
|
2
|
+
import { type TranscriptRow } from './transcript-grouping';
|
|
3
|
+
import { type TranscriptFoldMode, type TranscriptMounting } from './transcript-folding';
|
|
4
|
+
export type TranscriptFoldState = 'default' | 'collapsed' | 'expanded';
|
|
5
|
+
export type TranscriptDisplayKind = 'single' | 'group' | 'turn';
|
|
6
|
+
export type { GroupedTranscript, TranscriptDisplayItem, TranscriptRow, TranscriptTurnItem, } from './transcript-grouping';
|
|
7
|
+
export type { TranscriptFoldMode, TranscriptFoldPlan, TranscriptMounting, } from './transcript-folding';
|
|
8
|
+
export type TranscriptCompositionFold = Readonly<{
|
|
9
|
+
/** Stable host persistence key. Use with `transcriptDisclosureKey` to seed a store. */
|
|
10
|
+
key: string;
|
|
11
|
+
mode: TranscriptFoldMode;
|
|
12
|
+
mounting: TranscriptMounting;
|
|
13
|
+
/** Distinct host-classified request IDs in this contiguous fold segment. */
|
|
14
|
+
callCount: number;
|
|
15
|
+
}>;
|
|
16
|
+
export type TranscriptCompositionRowContext = Readonly<{
|
|
17
|
+
/** Original index in the caller's row array, including rows hidden by the host. */
|
|
18
|
+
index: number;
|
|
19
|
+
/** The row's current position in the generic display composition. */
|
|
20
|
+
displayKind: TranscriptDisplayKind;
|
|
21
|
+
group?: Readonly<{
|
|
22
|
+
index: number;
|
|
23
|
+
size: number;
|
|
24
|
+
}>;
|
|
25
|
+
turn?: Readonly<{
|
|
26
|
+
/** Derived from the first stable row ID; presentation bookkeeping only. */
|
|
27
|
+
id: string;
|
|
28
|
+
/** A presentation state, never proof of successful runtime completion. */
|
|
29
|
+
complete: boolean;
|
|
30
|
+
interim: boolean;
|
|
31
|
+
}>;
|
|
32
|
+
fold?: TranscriptCompositionFold;
|
|
33
|
+
}>;
|
|
34
|
+
export type TranscriptCompositionRendererProps<T> = Readonly<{
|
|
35
|
+
/** Reactive Solid prop; a row component keeps its DOM owner stable as values update. */
|
|
36
|
+
row: TranscriptRow<T>;
|
|
37
|
+
context: TranscriptCompositionRowContext;
|
|
38
|
+
}>;
|
|
39
|
+
export type TranscriptCompositionProps<T> = Omit<ComponentProps<'div'>, 'children'> & {
|
|
40
|
+
/** Ordered, already redacted rows with host-supplied semantic classifications. */
|
|
41
|
+
rows: readonly TranscriptRow<T>[];
|
|
42
|
+
/** Render one host row. Permission, session, event and protocol authority stay outside this component. */
|
|
43
|
+
renderRow: Component<TranscriptCompositionRendererProps<T>>;
|
|
44
|
+
/** The host's current run state. Live rows stay mounted and expanded until settled. */
|
|
45
|
+
running?: boolean;
|
|
46
|
+
/** Reset scope for row identity and disclosure. It is not inferred from display content. */
|
|
47
|
+
resetKey?: string | number | null;
|
|
48
|
+
/** Default settled fold policy. `tools` keeps prose visible; `prose` retains a proven conclusion. */
|
|
49
|
+
foldMode?: TranscriptFoldMode;
|
|
50
|
+
/** Global command state. `collapsed` keeps hidden content mounted; prose folds only before a host-marked conclusion. */
|
|
51
|
+
foldState?: TranscriptFoldState;
|
|
52
|
+
onFoldStateChange?: (state: TranscriptFoldState) => void;
|
|
53
|
+
/** Optional controlled disclosure map keyed by `transcriptDisclosureKey`. */
|
|
54
|
+
disclosure?: ReadonlyMap<string, boolean>;
|
|
55
|
+
onDisclosureChange?: (key: string, expanded: boolean) => void;
|
|
56
|
+
};
|
|
57
|
+
/** Stable, transcript-scoped key for host-owned disclosure restoration. */
|
|
58
|
+
export declare function transcriptDisclosureKey(resetKey: string | number | null | undefined, mode: TranscriptFoldMode, firstRowId: string): string;
|
|
59
|
+
/**
|
|
60
|
+
* Compose host-classified rows into stable turns, contiguous groups and disclosures.
|
|
61
|
+
* Row render owners are keyed by `id` in a single list, so loose rows keep their DOM
|
|
62
|
+
* owners when the grouping threshold promotes them into a turn. The caller owns row
|
|
63
|
+
* identity, protocol meaning, redaction, permissions and durable conversation state.
|
|
64
|
+
*/
|
|
65
|
+
export declare function TranscriptComposition<T>(props: TranscriptCompositionProps<T>): import("solid-js").JSX.Element;
|
|
66
|
+
//# sourceMappingURL=transcript-composition.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcript-composition.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/transcript-composition.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
import { cn } from "../../lib/utils.js";
|
|
2
|
+
import { Button } from "../ui/button/button.js";
|
|
3
|
+
import { applyTranscriptRunningState, createTranscriptGrouper } from "./transcript-grouping.js";
|
|
4
|
+
import { planTranscriptFold } from "./transcript-folding.js";
|
|
5
|
+
import { createComponent, effect, insert, memo, mergeProps, setAttribute, spread, template } from "solid-js/web";
|
|
6
|
+
import { ChevronDown } from "lucide-solid";
|
|
7
|
+
import { For, Show, createComponent as createComponent$1, createMemo, createSignal, createUniqueId, splitProps } from "solid-js";
|
|
8
|
+
//#region src/components/conversation/transcript-composition.tsx
|
|
9
|
+
var _tmpl$ = /*#__PURE__*/ template(`<div data-slot=transcript-row class="flex min-w-0 flex-col gap-1"><div data-slot=transcript-row-content>`);
|
|
10
|
+
var _tmpl$2 = /*#__PURE__*/ template(`<span>`);
|
|
11
|
+
var _tmpl$3 = /*#__PURE__*/ template(`<div class="flex justify-end">`);
|
|
12
|
+
var _tmpl$4 = /*#__PURE__*/ template(`<div data-slot=transcript-composition><div data-slot=transcript-rows class="flex min-w-0 flex-col gap-1">`);
|
|
13
|
+
var encodeId = (value) => encodeURIComponent(value);
|
|
14
|
+
/** Stable, transcript-scoped key for host-owned disclosure restoration. */
|
|
15
|
+
function transcriptDisclosureKey(resetKey, mode, firstRowId) {
|
|
16
|
+
return `transcript:${encodeId(String(resetKey ?? ""))}:${mode}:${encodeId(firstRowId)}`;
|
|
17
|
+
}
|
|
18
|
+
function panelId(instanceId, resetKey, rowId) {
|
|
19
|
+
return `${instanceId}-row-${encodeId(resetKey)}-${encodeId(rowId)}`;
|
|
20
|
+
}
|
|
21
|
+
function buttonId(instanceId, resetKey, segmentKey) {
|
|
22
|
+
return `${instanceId}-fold-${encodeId(resetKey)}-${encodeId(segmentKey)}`;
|
|
23
|
+
}
|
|
24
|
+
function sameGroup(a, b) {
|
|
25
|
+
return a === b || !!a && !!b && a.index === b.index && a.size === b.size;
|
|
26
|
+
}
|
|
27
|
+
function sameTurn(a, b) {
|
|
28
|
+
return a === b || !!a && !!b && a.id === b.id && a.complete === b.complete && a.interim === b.interim;
|
|
29
|
+
}
|
|
30
|
+
function sameFold(a, b) {
|
|
31
|
+
return a === b || !!a && !!b && a.key === b.key && a.mode === b.mode && a.mounting === b.mounting && a.callCount === b.callCount;
|
|
32
|
+
}
|
|
33
|
+
function sameFoldGroup(a, b) {
|
|
34
|
+
return a === b || !!a && !!b && a.key === b.key && a.callCount === b.callCount && a.rows.length === b.rows.length && a.rows.every((row, index) => row === b.rows[index]);
|
|
35
|
+
}
|
|
36
|
+
function sameRecord(a, b) {
|
|
37
|
+
return a.row === b.row && a.index === b.index && a.displayKind === b.displayKind && sameGroup(a.group, b.group) && sameTurn(a.turn, b.turn) && sameFold(a.fold, b.fold) && sameFoldGroup(a.foldControl, b.foldControl);
|
|
38
|
+
}
|
|
39
|
+
function firstRow(item) {
|
|
40
|
+
return item.kind === "single" ? item.row : item.rows[0];
|
|
41
|
+
}
|
|
42
|
+
function appendTurnItem(item, displayKind, turn, indices, into) {
|
|
43
|
+
if (item.kind === "single") {
|
|
44
|
+
into.push({
|
|
45
|
+
row: item.row,
|
|
46
|
+
index: indices.get(item.row) ?? item.index,
|
|
47
|
+
displayKind,
|
|
48
|
+
turn
|
|
49
|
+
});
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
item.rows.forEach((row, index) => {
|
|
53
|
+
into.push({
|
|
54
|
+
row,
|
|
55
|
+
index: indices.get(row) ?? item.startIndex + index,
|
|
56
|
+
displayKind,
|
|
57
|
+
group: {
|
|
58
|
+
index,
|
|
59
|
+
size: item.rows.length
|
|
60
|
+
},
|
|
61
|
+
turn
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function appendDisplayItem(item, indices, into) {
|
|
66
|
+
if (item.kind !== "turn") {
|
|
67
|
+
appendTurnItem(item, item.kind, void 0, indices, into);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const turn = {
|
|
71
|
+
id: item.items.map(firstRow).find((row) => row)?.id ?? "empty-turn",
|
|
72
|
+
complete: item.complete,
|
|
73
|
+
interim: !!item.interim
|
|
74
|
+
};
|
|
75
|
+
for (const child of item.items) appendTurnItem(child, "turn", turn, indices, into);
|
|
76
|
+
}
|
|
77
|
+
function buildDisclosures(records, defaultMode, foldState, resetKey) {
|
|
78
|
+
const controls = [];
|
|
79
|
+
let scope = [];
|
|
80
|
+
const flushScope = () => {
|
|
81
|
+
if (!scope.length) return;
|
|
82
|
+
const rows = scope.map((record) => record.row);
|
|
83
|
+
const hasInterimTurn = scope.some((record) => record.turn?.interim);
|
|
84
|
+
const hasConclusion = scope.some((record) => record.row.conclusion);
|
|
85
|
+
const mode = hasInterimTurn ? "interim" : foldState === "default" ? defaultMode : foldState === "collapsed" ? hasConclusion ? "prose" : "tools" : "interim";
|
|
86
|
+
const plan = planTranscriptFold(rows, {
|
|
87
|
+
mode,
|
|
88
|
+
settled: true
|
|
89
|
+
});
|
|
90
|
+
const foldable = plan.entries.flatMap((entry, index) => entry.mounting === "always" ? [] : [{
|
|
91
|
+
record: scope[index],
|
|
92
|
+
mounting: entry.mounting
|
|
93
|
+
}]);
|
|
94
|
+
if (foldable.length) {
|
|
95
|
+
const control = {
|
|
96
|
+
key: transcriptDisclosureKey(resetKey, mode, scope[0]?.row.id ?? foldable[0].record.row.id),
|
|
97
|
+
mode,
|
|
98
|
+
callCount: plan.callCount,
|
|
99
|
+
rows: foldable.map(({ record }) => record.row)
|
|
100
|
+
};
|
|
101
|
+
controls.push(control);
|
|
102
|
+
foldable.forEach(({ record, mounting }, index) => {
|
|
103
|
+
record.fold = {
|
|
104
|
+
key: control.key,
|
|
105
|
+
mode: control.mode,
|
|
106
|
+
mounting: foldState === "collapsed" ? "hide-when-collapsed" : mounting,
|
|
107
|
+
callCount: control.callCount
|
|
108
|
+
};
|
|
109
|
+
if (index === 0) record.foldControl = control;
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
scope = [];
|
|
113
|
+
};
|
|
114
|
+
for (const record of records) {
|
|
115
|
+
if (record.row.opensTurn && scope.length) flushScope();
|
|
116
|
+
scope.push(record);
|
|
117
|
+
}
|
|
118
|
+
flushScope();
|
|
119
|
+
return controls;
|
|
120
|
+
}
|
|
121
|
+
function foldLabel(mode, count, expanded) {
|
|
122
|
+
const subject = mode === "tools" ? count === 1 ? "1 tool call" : count > 1 ? `${count} tool calls` : "tool details" : mode === "prose" ? "earlier activity" : "interim activity";
|
|
123
|
+
return `${expanded ? "Hide" : "Show"} ${subject}`;
|
|
124
|
+
}
|
|
125
|
+
function TranscriptRowEntry(props) {
|
|
126
|
+
const current = props.record;
|
|
127
|
+
const id = () => panelId(props.prefix, props.resetKey(), current().row.id);
|
|
128
|
+
const foldControl = () => current().foldControl;
|
|
129
|
+
const disclosureKey = () => current().fold?.key;
|
|
130
|
+
const expanded = () => {
|
|
131
|
+
const key = disclosureKey();
|
|
132
|
+
return key ? props.expanded(key)() : true;
|
|
133
|
+
};
|
|
134
|
+
const collapsed = () => !!current().fold && !expanded();
|
|
135
|
+
const disabled = () => props.running() || props.foldState() !== "default";
|
|
136
|
+
const context = () => ({
|
|
137
|
+
index: current().index,
|
|
138
|
+
displayKind: current().displayKind,
|
|
139
|
+
group: current().group,
|
|
140
|
+
turn: current().turn,
|
|
141
|
+
fold: current().fold
|
|
142
|
+
});
|
|
143
|
+
const groupIndex = () => current().group?.index;
|
|
144
|
+
const groupSize = () => current().group?.size;
|
|
145
|
+
const renderable = () => current().fold?.mounting !== "unmount-when-collapsed" || !collapsed();
|
|
146
|
+
const renderHostRow = () => createComponent$1(props.renderRow, {
|
|
147
|
+
get row() {
|
|
148
|
+
return current().row;
|
|
149
|
+
},
|
|
150
|
+
get context() {
|
|
151
|
+
return context();
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
const controlLabel = () => {
|
|
155
|
+
const control = foldControl();
|
|
156
|
+
return control ? foldLabel(control.mode, control.callCount, expanded()) : "";
|
|
157
|
+
};
|
|
158
|
+
const controlRows = () => foldControl()?.rows.map((row) => panelId(props.prefix, props.resetKey(), row.id)).join(" ");
|
|
159
|
+
return (() => {
|
|
160
|
+
var _el$ = _tmpl$(), _el$2 = _el$.firstChild;
|
|
161
|
+
insert(_el$, createComponent(Show, {
|
|
162
|
+
get when() {
|
|
163
|
+
return foldControl();
|
|
164
|
+
},
|
|
165
|
+
children: (control) => createComponent(Button, {
|
|
166
|
+
get id() {
|
|
167
|
+
return buttonId(props.prefix, props.resetKey(), control().key);
|
|
168
|
+
},
|
|
169
|
+
type: "button",
|
|
170
|
+
variant: "ghost",
|
|
171
|
+
size: "sm",
|
|
172
|
+
"class": "w-full justify-start",
|
|
173
|
+
get ["aria-label"]() {
|
|
174
|
+
return controlLabel();
|
|
175
|
+
},
|
|
176
|
+
get ["aria-controls"]() {
|
|
177
|
+
return controlRows();
|
|
178
|
+
},
|
|
179
|
+
get ["aria-expanded"]() {
|
|
180
|
+
return expanded();
|
|
181
|
+
},
|
|
182
|
+
get ["aria-disabled"]() {
|
|
183
|
+
return disabled() || void 0;
|
|
184
|
+
},
|
|
185
|
+
onClick: () => props.onToggle(control().key, !expanded()),
|
|
186
|
+
get children() {
|
|
187
|
+
return [createComponent(ChevronDown, {
|
|
188
|
+
"aria-hidden": "true",
|
|
189
|
+
"class": "size-4 shrink-0"
|
|
190
|
+
}), (() => {
|
|
191
|
+
var _el$3 = _tmpl$2();
|
|
192
|
+
insert(_el$3, controlLabel);
|
|
193
|
+
return _el$3;
|
|
194
|
+
})()];
|
|
195
|
+
}
|
|
196
|
+
})
|
|
197
|
+
}), _el$2);
|
|
198
|
+
insert(_el$2, createComponent(Show, {
|
|
199
|
+
get when() {
|
|
200
|
+
return memo(() => !!renderable())() ? current() : void 0;
|
|
201
|
+
},
|
|
202
|
+
children: (record) => {
|
|
203
|
+
record();
|
|
204
|
+
return renderHostRow();
|
|
205
|
+
}
|
|
206
|
+
}));
|
|
207
|
+
effect((_p$) => {
|
|
208
|
+
var _v$ = current().displayKind, _v$2 = groupIndex(), _v$3 = groupSize(), _v$4 = id(), _v$5 = collapsed(), _v$6 = collapsed() || void 0;
|
|
209
|
+
_v$ !== _p$.e && setAttribute(_el$, "data-display-kind", _p$.e = _v$);
|
|
210
|
+
_v$2 !== _p$.t && setAttribute(_el$, "data-group-index", _p$.t = _v$2);
|
|
211
|
+
_v$3 !== _p$.a && setAttribute(_el$, "data-group-size", _p$.a = _v$3);
|
|
212
|
+
_v$4 !== _p$.o && setAttribute(_el$2, "id", _p$.o = _v$4);
|
|
213
|
+
_v$5 !== _p$.i && (_el$2.hidden = _p$.i = _v$5);
|
|
214
|
+
_v$6 !== _p$.n && setAttribute(_el$2, "aria-hidden", _p$.n = _v$6);
|
|
215
|
+
return _p$;
|
|
216
|
+
}, {
|
|
217
|
+
e: void 0,
|
|
218
|
+
t: void 0,
|
|
219
|
+
a: void 0,
|
|
220
|
+
o: void 0,
|
|
221
|
+
i: void 0,
|
|
222
|
+
n: void 0
|
|
223
|
+
});
|
|
224
|
+
return _el$;
|
|
225
|
+
})();
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Compose host-classified rows into stable turns, contiguous groups and disclosures.
|
|
229
|
+
* Row render owners are keyed by `id` in a single list, so loose rows keep their DOM
|
|
230
|
+
* owners when the grouping threshold promotes them into a turn. The caller owns row
|
|
231
|
+
* identity, protocol meaning, redaction, permissions and durable conversation state.
|
|
232
|
+
*/
|
|
233
|
+
function TranscriptComposition(props) {
|
|
234
|
+
const [local, rest] = splitProps(props, [
|
|
235
|
+
"class",
|
|
236
|
+
"rows",
|
|
237
|
+
"renderRow",
|
|
238
|
+
"running",
|
|
239
|
+
"resetKey",
|
|
240
|
+
"foldMode",
|
|
241
|
+
"foldState",
|
|
242
|
+
"onFoldStateChange",
|
|
243
|
+
"disclosure",
|
|
244
|
+
"onDisclosureChange"
|
|
245
|
+
]);
|
|
246
|
+
const instanceId = createUniqueId();
|
|
247
|
+
const grouper = createTranscriptGrouper();
|
|
248
|
+
const [internalFoldState, setInternalFoldState] = createSignal("default");
|
|
249
|
+
const rowHandles = /* @__PURE__ */ new Map();
|
|
250
|
+
const disclosureSignals = /* @__PURE__ */ new Map();
|
|
251
|
+
let lastResetKey = String(local.resetKey ?? "");
|
|
252
|
+
const resetKey = () => String(local.resetKey ?? "");
|
|
253
|
+
const foldState = () => local.foldState ?? internalFoldState();
|
|
254
|
+
const running = () => !!local.running;
|
|
255
|
+
const localDisclosure = (key) => {
|
|
256
|
+
let signal = disclosureSignals.get(key);
|
|
257
|
+
if (!signal) {
|
|
258
|
+
const [get, set] = createSignal(void 0);
|
|
259
|
+
signal = {
|
|
260
|
+
get,
|
|
261
|
+
set
|
|
262
|
+
};
|
|
263
|
+
disclosureSignals.set(key, signal);
|
|
264
|
+
}
|
|
265
|
+
return signal;
|
|
266
|
+
};
|
|
267
|
+
const disclosureExpanded = (key) => {
|
|
268
|
+
const signal = localDisclosure(key);
|
|
269
|
+
return () => {
|
|
270
|
+
if (running()) return true;
|
|
271
|
+
if (foldState() === "collapsed") return false;
|
|
272
|
+
if (foldState() === "expanded") return true;
|
|
273
|
+
return local.disclosure?.get(key) ?? signal.get() ?? false;
|
|
274
|
+
};
|
|
275
|
+
};
|
|
276
|
+
const grouped = createMemo(() => grouper(local.rows));
|
|
277
|
+
const layout = createMemo(() => {
|
|
278
|
+
const identity = resetKey();
|
|
279
|
+
if (identity !== lastResetKey) {
|
|
280
|
+
rowHandles.clear();
|
|
281
|
+
disclosureSignals.clear();
|
|
282
|
+
lastResetKey = identity;
|
|
283
|
+
}
|
|
284
|
+
const indexByRow = new Map(local.rows.map((row, index) => [row, index]));
|
|
285
|
+
const display = applyTranscriptRunningState(grouped(), running());
|
|
286
|
+
const records = [];
|
|
287
|
+
display.forEach((item) => appendDisplayItem(item, indexByRow, records));
|
|
288
|
+
return {
|
|
289
|
+
rows: records,
|
|
290
|
+
controls: buildDisclosures(records, local.foldMode ?? "tools", foldState(), identity)
|
|
291
|
+
};
|
|
292
|
+
});
|
|
293
|
+
const handles = createMemo(() => {
|
|
294
|
+
const live = /* @__PURE__ */ new Set();
|
|
295
|
+
const identity = resetKey();
|
|
296
|
+
const result = layout().rows.map((record) => {
|
|
297
|
+
const key = `${identity}\u001f${record.row.id}`;
|
|
298
|
+
live.add(key);
|
|
299
|
+
let handle = rowHandles.get(key);
|
|
300
|
+
if (!handle) {
|
|
301
|
+
const [get, set] = createSignal(record);
|
|
302
|
+
handle = {
|
|
303
|
+
key,
|
|
304
|
+
get,
|
|
305
|
+
set,
|
|
306
|
+
last: record
|
|
307
|
+
};
|
|
308
|
+
rowHandles.set(key, handle);
|
|
309
|
+
} else if (!sameRecord(handle.last, record)) {
|
|
310
|
+
handle.last = record;
|
|
311
|
+
handle.set(record);
|
|
312
|
+
}
|
|
313
|
+
return handle;
|
|
314
|
+
});
|
|
315
|
+
for (const key of rowHandles.keys()) if (!live.has(key)) rowHandles.delete(key);
|
|
316
|
+
return result;
|
|
317
|
+
});
|
|
318
|
+
const allControlIds = () => layout().controls.flatMap((control) => control.rows.map((row) => panelId(instanceId, resetKey(), row.id))).join(" ");
|
|
319
|
+
const updateFoldState = () => {
|
|
320
|
+
if (running()) return;
|
|
321
|
+
const current = foldState();
|
|
322
|
+
const next = current === "default" ? "collapsed" : current === "collapsed" ? "expanded" : "default";
|
|
323
|
+
if (local.foldState === void 0) setInternalFoldState(next);
|
|
324
|
+
local.onFoldStateChange?.(next);
|
|
325
|
+
};
|
|
326
|
+
const updateDisclosure = (key, expanded) => {
|
|
327
|
+
if (running() || foldState() !== "default") return;
|
|
328
|
+
if (local.disclosure) {
|
|
329
|
+
local.onDisclosureChange?.(key, expanded);
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
localDisclosure(key).set(expanded);
|
|
333
|
+
local.onDisclosureChange?.(key, expanded);
|
|
334
|
+
};
|
|
335
|
+
return (() => {
|
|
336
|
+
var _el$4 = _tmpl$4(), _el$6 = _el$4.firstChild;
|
|
337
|
+
spread(_el$4, mergeProps({
|
|
338
|
+
get ["data-fold-state"]() {
|
|
339
|
+
return foldState();
|
|
340
|
+
},
|
|
341
|
+
get ["class"]() {
|
|
342
|
+
return cn("flex w-full min-w-0 flex-col gap-1", local.class);
|
|
343
|
+
}
|
|
344
|
+
}, rest), false, true);
|
|
345
|
+
insert(_el$4, createComponent(Show, {
|
|
346
|
+
get when() {
|
|
347
|
+
return local.onFoldStateChange;
|
|
348
|
+
},
|
|
349
|
+
get children() {
|
|
350
|
+
var _el$5 = _tmpl$3();
|
|
351
|
+
insert(_el$5, createComponent(Button, {
|
|
352
|
+
id: `${instanceId}-fold-all`,
|
|
353
|
+
type: "button",
|
|
354
|
+
variant: "ghost",
|
|
355
|
+
size: "sm",
|
|
356
|
+
get ["aria-controls"]() {
|
|
357
|
+
return allControlIds() || void 0;
|
|
358
|
+
},
|
|
359
|
+
get ["aria-disabled"]() {
|
|
360
|
+
return running() || void 0;
|
|
361
|
+
},
|
|
362
|
+
onClick: updateFoldState,
|
|
363
|
+
get children() {
|
|
364
|
+
return memo(() => foldState() === "default")() ? "Collapse all activity" : foldState() === "collapsed" ? "Expand all activity" : "Restore default folding";
|
|
365
|
+
}
|
|
366
|
+
}));
|
|
367
|
+
return _el$5;
|
|
368
|
+
}
|
|
369
|
+
}), _el$6);
|
|
370
|
+
insert(_el$6, createComponent(For, {
|
|
371
|
+
get each() {
|
|
372
|
+
return handles();
|
|
373
|
+
},
|
|
374
|
+
children: (handle) => createComponent(TranscriptRowEntry, {
|
|
375
|
+
get record() {
|
|
376
|
+
return handle.get;
|
|
377
|
+
},
|
|
378
|
+
get renderRow() {
|
|
379
|
+
return local.renderRow;
|
|
380
|
+
},
|
|
381
|
+
prefix: instanceId,
|
|
382
|
+
resetKey,
|
|
383
|
+
expanded: disclosureExpanded,
|
|
384
|
+
running,
|
|
385
|
+
foldState,
|
|
386
|
+
onToggle: updateDisclosure
|
|
387
|
+
})
|
|
388
|
+
}));
|
|
389
|
+
return _el$4;
|
|
390
|
+
})();
|
|
391
|
+
}
|
|
392
|
+
//#endregion
|
|
393
|
+
export { TranscriptComposition, transcriptDisclosureKey };
|
|
394
|
+
|
|
395
|
+
//# sourceMappingURL=transcript-composition.js.map
|