@opengeni/react 3.7.0-canary.7 → 3.8.0-canary.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/chat.js +1 -1
- package/dist/chunk-5M6VTFJ5.js +171 -0
- package/dist/chunk-5M6VTFJ5.js.map +1 -0
- package/dist/{chunk-IOLVN74D.js → chunk-6J56T3MG.js} +15 -1
- package/dist/chunk-6J56T3MG.js.map +1 -0
- package/dist/{chunk-BQGIXRKV.js → chunk-7BWFU6H4.js} +22 -4
- package/dist/chunk-7BWFU6H4.js.map +1 -0
- package/dist/{chunk-3HIF5IFC.js → chunk-7W6PVVTK.js} +63 -18
- package/dist/chunk-7W6PVVTK.js.map +1 -0
- package/dist/{chunk-ZFOFY5ST.js → chunk-NLTS7JHI.js} +16 -31
- package/dist/chunk-NLTS7JHI.js.map +1 -0
- package/dist/chunk-NOSYBS2D.js +208 -0
- package/dist/chunk-NOSYBS2D.js.map +1 -0
- package/dist/{chunk-F2CFHN3Y.js → chunk-YAIPFO5D.js} +2 -1
- package/dist/chunk-YAIPFO5D.js.map +1 -0
- package/dist/chunk-YBM6CQRU.js +292 -0
- package/dist/chunk-YBM6CQRU.js.map +1 -0
- package/dist/chunk-ZYRGEKWS.js +216 -0
- package/dist/chunk-ZYRGEKWS.js.map +1 -0
- package/dist/components/composer.d.ts +4 -2
- package/dist/components/message-timeline.d.ts +9 -2
- package/dist/components/timeline-annotation-chrome.d.ts +25 -0
- package/dist/components/timeline-annotation-layout.d.ts +42 -0
- package/dist/components/timeline-annotation-markers.d.ts +8 -0
- package/dist/components/timeline-annotation-reveal-context.d.ts +4 -0
- package/dist/components/timeline-annotation-shared.d.ts +31 -0
- package/dist/components/timeline-annotations-dialog.d.ts +1 -1
- package/dist/components/timeline-annotations.d.ts +8 -2
- package/dist/composer.js +2 -2
- package/dist/hooks/use-composer.d.ts +2 -0
- package/dist/index.js +9 -6
- package/dist/index.js.map +1 -1
- package/dist/interaction.js +6 -6
- package/dist/machines.js +1 -1
- package/dist/{queue-surface-implementation-XL2A6PBM.js → queue-surface-implementation-LK3S4BIW.js} +5 -2
- package/dist/{queue-surface-implementation-XL2A6PBM.js.map → queue-surface-implementation-LK3S4BIW.js.map} +1 -1
- package/dist/session-ui.js +8 -5
- package/dist/session.js +1 -1
- package/dist/timeline-annotation-markers-DRSTLEM6.js +165 -0
- package/dist/timeline-annotation-markers-DRSTLEM6.js.map +1 -0
- package/dist/timeline-annotation-selection-IHLUGVND.js +236 -0
- package/dist/timeline-annotation-selection-IHLUGVND.js.map +1 -0
- package/dist/timeline-annotations-dialog-6Q53N5FG.js +262 -0
- package/dist/timeline-annotations-dialog-6Q53N5FG.js.map +1 -0
- package/package.json +2 -2
- package/src/components/chat-composer.tsx +5 -2
- package/src/components/composer.tsx +40 -5
- package/src/components/copy-button.tsx +1 -0
- package/src/components/machines-dashboard.tsx +1 -16
- package/src/components/message-timeline.tsx +357 -297
- package/src/components/timeline-annotation-chrome.tsx +183 -0
- package/src/components/timeline-annotation-layout.ts +268 -0
- package/src/components/timeline-annotation-markers.tsx +185 -0
- package/src/components/timeline-annotation-reveal-context.ts +9 -0
- package/src/components/timeline-annotation-selection.tsx +99 -54
- package/src/components/timeline-annotation-shared.ts +245 -0
- package/src/components/timeline-annotations-dialog.tsx +172 -128
- package/src/components/timeline-annotations.tsx +178 -45
- package/src/hooks/use-composer.ts +17 -0
- package/styles/compiled.css +86 -22
- package/dist/chunk-3HIF5IFC.js.map +0 -1
- package/dist/chunk-BQGIXRKV.js.map +0 -1
- package/dist/chunk-F2CFHN3Y.js.map +0 -1
- package/dist/chunk-IOLVN74D.js.map +0 -1
- package/dist/chunk-W3OUAH6M.js +0 -170
- package/dist/chunk-W3OUAH6M.js.map +0 -1
- package/dist/chunk-ZFOFY5ST.js.map +0 -1
- package/dist/timeline-annotation-selection-3L7LHGG2.js +0 -187
- package/dist/timeline-annotation-selection-3L7LHGG2.js.map +0 -1
- package/dist/timeline-annotations-dialog-U7EVLR75.js +0 -196
- package/dist/timeline-annotations-dialog-U7EVLR75.js.map +0 -1
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
// src/components/timeline-annotation-shared.ts
|
|
2
|
+
var ANNOTATION_CHROME_SELECTOR = "[data-og-annotation-chrome], [data-og-annotation-badge], [data-og-annotation-popover]";
|
|
3
|
+
function annotationHasNote(note) {
|
|
4
|
+
return note.trim().length > 0;
|
|
5
|
+
}
|
|
6
|
+
function annotationDisplayOrdinal(annotation, index) {
|
|
7
|
+
return typeof annotation.ordinal === "number" ? annotation.ordinal : index + 1;
|
|
8
|
+
}
|
|
9
|
+
function sourceKindLabel(kind) {
|
|
10
|
+
switch (kind) {
|
|
11
|
+
case "user_message":
|
|
12
|
+
return "Your message";
|
|
13
|
+
case "assistant_message":
|
|
14
|
+
return "Assistant";
|
|
15
|
+
case "tool_output":
|
|
16
|
+
return "Tool output";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function annotationSourceLabel(source) {
|
|
20
|
+
return source.label?.trim() || sourceKindLabel(source.kind);
|
|
21
|
+
}
|
|
22
|
+
function truncateAnnotationQuote(quote, maxChars = 160) {
|
|
23
|
+
const normalized = quote.replace(/\s+/g, " ").trim();
|
|
24
|
+
if (normalized.length <= maxChars) return normalized;
|
|
25
|
+
return `${normalized.slice(0, Math.max(0, maxChars - 1)).trimEnd()}\u2026`;
|
|
26
|
+
}
|
|
27
|
+
function cssEscapeAttribute(value) {
|
|
28
|
+
if (typeof CSS !== "undefined" && typeof CSS.escape === "function") return CSS.escape(value);
|
|
29
|
+
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
30
|
+
}
|
|
31
|
+
function isAnnotationChromeNode(node) {
|
|
32
|
+
const element = node instanceof Element ? node : node?.parentElement;
|
|
33
|
+
return Boolean(element?.closest(ANNOTATION_CHROME_SELECTOR));
|
|
34
|
+
}
|
|
35
|
+
function occurrenceOffsets(text, quote) {
|
|
36
|
+
if (!quote) return [];
|
|
37
|
+
const offsets = [];
|
|
38
|
+
let cursor = 0;
|
|
39
|
+
while (cursor <= text.length - quote.length) {
|
|
40
|
+
const offset = text.indexOf(quote, cursor);
|
|
41
|
+
if (offset < 0) break;
|
|
42
|
+
offsets.push(offset);
|
|
43
|
+
cursor = offset + 1;
|
|
44
|
+
}
|
|
45
|
+
return offsets;
|
|
46
|
+
}
|
|
47
|
+
function uniqueNonEmpty(values) {
|
|
48
|
+
const seen = /* @__PURE__ */ new Set();
|
|
49
|
+
const out = [];
|
|
50
|
+
for (const value of values) {
|
|
51
|
+
if (!value || seen.has(value)) continue;
|
|
52
|
+
seen.add(value);
|
|
53
|
+
out.push(value);
|
|
54
|
+
}
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
57
|
+
function matchingQuoteInSource(sourceText, quote) {
|
|
58
|
+
for (const candidate of uniqueNonEmpty([quote, quote.trim()])) {
|
|
59
|
+
if (sourceText.includes(candidate)) return candidate;
|
|
60
|
+
}
|
|
61
|
+
const trimmed = quote.trim();
|
|
62
|
+
for (let length = trimmed.length; length >= 8; length--) {
|
|
63
|
+
const slice = trimmed.slice(0, length);
|
|
64
|
+
if (sourceText.includes(slice)) return slice;
|
|
65
|
+
}
|
|
66
|
+
for (let start = 1; start <= trimmed.length - 8; start++) {
|
|
67
|
+
const slice = trimmed.slice(start);
|
|
68
|
+
if (sourceText.includes(slice)) return slice;
|
|
69
|
+
}
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
function annotatableText(root) {
|
|
73
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
|
|
74
|
+
acceptNode(node) {
|
|
75
|
+
if (!(node instanceof Text) || node.data.length === 0) return NodeFilter.FILTER_REJECT;
|
|
76
|
+
if (isAnnotationChromeNode(node)) return NodeFilter.FILTER_REJECT;
|
|
77
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
const spans = [];
|
|
81
|
+
let text = "";
|
|
82
|
+
let current;
|
|
83
|
+
while (current = walker.nextNode()) {
|
|
84
|
+
if (!(current instanceof Text)) continue;
|
|
85
|
+
spans.push({ node: current, start: text.length, length: current.data.length });
|
|
86
|
+
text += current.data;
|
|
87
|
+
}
|
|
88
|
+
return { text, spans };
|
|
89
|
+
}
|
|
90
|
+
function pointAt(spans, offset, stickEnd) {
|
|
91
|
+
if (spans.length === 0) return null;
|
|
92
|
+
for (let index = 0; index < spans.length; index++) {
|
|
93
|
+
const span = spans[index];
|
|
94
|
+
const local = offset - span.start;
|
|
95
|
+
if (local < 0) continue;
|
|
96
|
+
if (local < span.length || local === span.length && (stickEnd || index === spans.length - 1)) {
|
|
97
|
+
return { node: span.node, offset: local };
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const last = spans[spans.length - 1];
|
|
101
|
+
return { node: last.node, offset: last.length };
|
|
102
|
+
}
|
|
103
|
+
function rangeFromOffsets(spans, startOffset, endOffset) {
|
|
104
|
+
const start = pointAt(spans, startOffset, false);
|
|
105
|
+
const end = pointAt(spans, endOffset, true);
|
|
106
|
+
if (!start || !end) return null;
|
|
107
|
+
const range = document.createRange();
|
|
108
|
+
range.setStart(start.node, start.offset);
|
|
109
|
+
range.setEnd(end.node, end.offset);
|
|
110
|
+
return range.collapsed ? null : range;
|
|
111
|
+
}
|
|
112
|
+
function buildQuoteRange(sourceEl, quote, occurrenceIndex = 0) {
|
|
113
|
+
if (!quote) return null;
|
|
114
|
+
const { text, spans } = annotatableText(sourceEl);
|
|
115
|
+
const offsets = occurrenceOffsets(text, quote);
|
|
116
|
+
if (offsets.length === 0) return null;
|
|
117
|
+
const start = offsets[Math.min(Math.max(0, occurrenceIndex), offsets.length - 1)];
|
|
118
|
+
return rangeFromOffsets(spans, start, start + quote.length);
|
|
119
|
+
}
|
|
120
|
+
function quoteOccurrenceIndex(sourceEl, range, quote) {
|
|
121
|
+
try {
|
|
122
|
+
const prefix = range.cloneRange();
|
|
123
|
+
prefix.selectNodeContents(sourceEl);
|
|
124
|
+
prefix.setEnd(range.startContainer, range.startOffset);
|
|
125
|
+
return occurrenceOffsets(prefix.toString(), quote).length;
|
|
126
|
+
} catch {
|
|
127
|
+
return 0;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function clipRangeToSource(range, sourceEl) {
|
|
131
|
+
const startOk = sourceEl.contains(range.startContainer) && !isAnnotationChromeNode(range.startContainer);
|
|
132
|
+
const endOk = sourceEl.contains(range.endContainer) && !isAnnotationChromeNode(range.endContainer);
|
|
133
|
+
if (!startOk && !endOk) return null;
|
|
134
|
+
const { spans } = annotatableText(sourceEl);
|
|
135
|
+
if (spans.length === 0) return null;
|
|
136
|
+
const next = range.cloneRange();
|
|
137
|
+
const first = spans[0];
|
|
138
|
+
const last = spans[spans.length - 1];
|
|
139
|
+
if (!startOk) next.setStart(first.node, 0);
|
|
140
|
+
if (!endOk) next.setEnd(last.node, last.node.data.length);
|
|
141
|
+
return next.collapsed ? null : next;
|
|
142
|
+
}
|
|
143
|
+
function visibleClientRect(range) {
|
|
144
|
+
try {
|
|
145
|
+
const bounding = range.getBoundingClientRect();
|
|
146
|
+
if (bounding.width > 0 || bounding.height > 0) return bounding;
|
|
147
|
+
} catch {
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
const rects = range.getClientRects();
|
|
151
|
+
for (let index = 0; index < rects.length; index++) {
|
|
152
|
+
const rect = rects.item(index);
|
|
153
|
+
if (rect && (rect.width > 0 || rect.height > 0)) return rect;
|
|
154
|
+
}
|
|
155
|
+
} catch {
|
|
156
|
+
}
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
function resolveAnnotationRevealRoot(from) {
|
|
160
|
+
const conversation = from?.closest("[data-og-conversation]");
|
|
161
|
+
if (conversation instanceof HTMLElement) {
|
|
162
|
+
const nested = conversation.querySelector("[data-og-timeline-scroller]");
|
|
163
|
+
return nested instanceof HTMLElement ? nested : conversation;
|
|
164
|
+
}
|
|
165
|
+
const scroller = from?.closest("[data-og-timeline-scroller]");
|
|
166
|
+
return scroller instanceof HTMLElement ? scroller : null;
|
|
167
|
+
}
|
|
168
|
+
function revealLoadedAnnotationSource(source, root) {
|
|
169
|
+
if (typeof document === "undefined") return false;
|
|
170
|
+
if (root === null) return false;
|
|
171
|
+
const element = (root ?? document).querySelector(
|
|
172
|
+
`[data-og-annotation-source-key="${cssEscapeAttribute(source.eventId)}"]`
|
|
173
|
+
);
|
|
174
|
+
if (!(element instanceof HTMLElement)) return false;
|
|
175
|
+
element.scrollIntoView({ block: "center", behavior: "smooth" });
|
|
176
|
+
element.animate?.(
|
|
177
|
+
[
|
|
178
|
+
{
|
|
179
|
+
boxShadow: "inset 0 0 0 2px color-mix(in oklch, var(--og-accent) 70%, transparent)",
|
|
180
|
+
backgroundColor: "color-mix(in oklch, var(--og-accent) 14%, transparent)"
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
boxShadow: "inset 0 0 0 2px transparent",
|
|
184
|
+
backgroundColor: "transparent"
|
|
185
|
+
}
|
|
186
|
+
],
|
|
187
|
+
{ duration: 1400, easing: "ease-out" }
|
|
188
|
+
);
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export {
|
|
193
|
+
annotationHasNote,
|
|
194
|
+
annotationDisplayOrdinal,
|
|
195
|
+
annotationSourceLabel,
|
|
196
|
+
truncateAnnotationQuote,
|
|
197
|
+
cssEscapeAttribute,
|
|
198
|
+
occurrenceOffsets,
|
|
199
|
+
matchingQuoteInSource,
|
|
200
|
+
annotatableText,
|
|
201
|
+
buildQuoteRange,
|
|
202
|
+
quoteOccurrenceIndex,
|
|
203
|
+
clipRangeToSource,
|
|
204
|
+
visibleClientRect,
|
|
205
|
+
resolveAnnotationRevealRoot,
|
|
206
|
+
revealLoadedAnnotationSource
|
|
207
|
+
};
|
|
208
|
+
//# sourceMappingURL=chunk-NOSYBS2D.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/timeline-annotation-shared.ts"],"sourcesContent":["import type { TimelineAnnotationSource } from \"@opengeni/sdk\";\n\nexport const ANNOTATION_CHROME_SELECTOR =\n \"[data-og-annotation-chrome], [data-og-annotation-badge], [data-og-annotation-popover]\";\n\nexport function annotationHasNote(note: string): boolean {\n return note.trim().length > 0;\n}\n\nexport function annotationDisplayOrdinal(\n annotation: { readonly id?: string; readonly ordinal?: number | undefined },\n index: number,\n): number {\n return typeof annotation.ordinal === \"number\" ? annotation.ordinal : index + 1;\n}\n\nexport function sourceKindLabel(kind: TimelineAnnotationSource[\"kind\"]): string {\n switch (kind) {\n case \"user_message\":\n return \"Your message\";\n case \"assistant_message\":\n return \"Assistant\";\n case \"tool_output\":\n return \"Tool output\";\n }\n}\n\nexport function annotationSourceLabel(source: TimelineAnnotationSource): string {\n return source.label?.trim() || sourceKindLabel(source.kind);\n}\n\nexport function truncateAnnotationQuote(quote: string, maxChars = 160): string {\n const normalized = quote.replace(/\\s+/g, \" \").trim();\n if (normalized.length <= maxChars) return normalized;\n return `${normalized.slice(0, Math.max(0, maxChars - 1)).trimEnd()}…`;\n}\n\nexport function cssEscapeAttribute(value: string): string {\n if (typeof CSS !== \"undefined\" && typeof CSS.escape === \"function\") return CSS.escape(value);\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n}\n\nexport function isAnnotationChromeNode(node: Node | null): boolean {\n const element = node instanceof Element ? node : node?.parentElement;\n return Boolean(element?.closest(ANNOTATION_CHROME_SELECTOR));\n}\n\nexport function occurrenceOffsets(text: string, quote: string): number[] {\n if (!quote) return [];\n const offsets: number[] = [];\n let cursor = 0;\n while (cursor <= text.length - quote.length) {\n const offset = text.indexOf(quote, cursor);\n if (offset < 0) break;\n offsets.push(offset);\n cursor = offset + 1;\n }\n return offsets;\n}\n\nfunction uniqueNonEmpty(values: string[]): string[] {\n const seen = new Set<string>();\n const out: string[] = [];\n for (const value of values) {\n if (!value || seen.has(value)) continue;\n seen.add(value);\n out.push(value);\n }\n return out;\n}\n\nexport function matchingQuoteInSource(sourceText: string, quote: string): string | null {\n for (const candidate of uniqueNonEmpty([quote, quote.trim()])) {\n if (sourceText.includes(candidate)) return candidate;\n }\n const trimmed = quote.trim();\n for (let length = trimmed.length; length >= 8; length--) {\n const slice = trimmed.slice(0, length);\n if (sourceText.includes(slice)) return slice;\n }\n for (let start = 1; start <= trimmed.length - 8; start++) {\n const slice = trimmed.slice(start);\n if (sourceText.includes(slice)) return slice;\n }\n return null;\n}\n\ntype AnnotatableSpan = {\n node: Text;\n start: number;\n length: number;\n};\n\nexport function annotatableText(root: HTMLElement): { text: string; spans: AnnotatableSpan[] } {\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {\n acceptNode(node) {\n if (!(node instanceof Text) || node.data.length === 0) return NodeFilter.FILTER_REJECT;\n if (isAnnotationChromeNode(node)) return NodeFilter.FILTER_REJECT;\n return NodeFilter.FILTER_ACCEPT;\n },\n });\n const spans: AnnotatableSpan[] = [];\n let text = \"\";\n let current: Node | null;\n while ((current = walker.nextNode())) {\n if (!(current instanceof Text)) continue;\n spans.push({ node: current, start: text.length, length: current.data.length });\n text += current.data;\n }\n return { text, spans };\n}\n\nfunction pointAt(\n spans: AnnotatableSpan[],\n offset: number,\n stickEnd: boolean,\n): { node: Text; offset: number } | null {\n if (spans.length === 0) return null;\n for (let index = 0; index < spans.length; index++) {\n const span = spans[index]!;\n const local = offset - span.start;\n if (local < 0) continue;\n if (\n local < span.length ||\n (local === span.length && (stickEnd || index === spans.length - 1))\n ) {\n return { node: span.node, offset: local };\n }\n }\n const last = spans[spans.length - 1]!;\n return { node: last.node, offset: last.length };\n}\n\nexport function rangeFromOffsets(\n spans: AnnotatableSpan[],\n startOffset: number,\n endOffset: number,\n): Range | null {\n const start = pointAt(spans, startOffset, false);\n const end = pointAt(spans, endOffset, true);\n if (!start || !end) return null;\n const range = document.createRange();\n range.setStart(start.node, start.offset);\n range.setEnd(end.node, end.offset);\n return range.collapsed ? null : range;\n}\n\nexport function buildQuoteRange(\n sourceEl: HTMLElement,\n quote: string,\n occurrenceIndex = 0,\n): Range | null {\n if (!quote) return null;\n const { text, spans } = annotatableText(sourceEl);\n const offsets = occurrenceOffsets(text, quote);\n if (offsets.length === 0) return null;\n const start = offsets[Math.min(Math.max(0, occurrenceIndex), offsets.length - 1)]!;\n return rangeFromOffsets(spans, start, start + quote.length);\n}\n\nexport function quoteOccurrenceIndex(sourceEl: HTMLElement, range: Range, quote: string): number {\n try {\n const prefix = range.cloneRange();\n prefix.selectNodeContents(sourceEl);\n prefix.setEnd(range.startContainer, range.startOffset);\n return occurrenceOffsets(prefix.toString(), quote).length;\n } catch {\n return 0;\n }\n}\n\nexport function clipRangeToSource(range: Range, sourceEl: HTMLElement): Range | null {\n const startOk =\n sourceEl.contains(range.startContainer) && !isAnnotationChromeNode(range.startContainer);\n const endOk =\n sourceEl.contains(range.endContainer) && !isAnnotationChromeNode(range.endContainer);\n if (!startOk && !endOk) return null;\n const { spans } = annotatableText(sourceEl);\n if (spans.length === 0) return null;\n const next = range.cloneRange();\n const first = spans[0]!;\n const last = spans[spans.length - 1]!;\n if (!startOk) next.setStart(first.node, 0);\n if (!endOk) next.setEnd(last.node, last.node.data.length);\n return next.collapsed ? null : next;\n}\n\nexport function visibleClientRect(range: Range): DOMRect | null {\n try {\n const bounding = range.getBoundingClientRect();\n if (bounding.width > 0 || bounding.height > 0) return bounding;\n } catch {\n // jsdom ranges may omit layout geometry.\n }\n try {\n const rects = range.getClientRects();\n for (let index = 0; index < rects.length; index++) {\n const rect = rects.item(index);\n if (rect && (rect.width > 0 || rect.height > 0)) return rect;\n }\n } catch {\n // jsdom ranges may omit client rects.\n }\n return null;\n}\n\nexport function resolveAnnotationRevealRoot(from: Element | null | undefined): HTMLElement | null {\n const conversation = from?.closest(\"[data-og-conversation]\");\n if (conversation instanceof HTMLElement) {\n const nested = conversation.querySelector(\"[data-og-timeline-scroller]\");\n return nested instanceof HTMLElement ? nested : conversation;\n }\n const scroller = from?.closest(\"[data-og-timeline-scroller]\");\n return scroller instanceof HTMLElement ? scroller : null;\n}\n\nexport function revealLoadedAnnotationSource(\n source: TimelineAnnotationSource,\n root?: ParentNode | null,\n): boolean {\n if (typeof document === \"undefined\") return false;\n // An explicit null root means the caller already scoped the search and found\n // no owning timeline. Do not fall back to `document`, or a second mounted\n // timeline with the same event id would steal the reveal.\n if (root === null) return false;\n const element = (root ?? document).querySelector(\n `[data-og-annotation-source-key=\"${cssEscapeAttribute(source.eventId)}\"]`,\n );\n if (!(element instanceof HTMLElement)) return false;\n element.scrollIntoView({ block: \"center\", behavior: \"smooth\" });\n element.animate?.(\n [\n {\n boxShadow: \"inset 0 0 0 2px color-mix(in oklch, var(--og-accent) 70%, transparent)\",\n backgroundColor: \"color-mix(in oklch, var(--og-accent) 14%, transparent)\",\n },\n {\n boxShadow: \"inset 0 0 0 2px transparent\",\n backgroundColor: \"transparent\",\n },\n ],\n { duration: 1400, easing: \"ease-out\" },\n );\n return true;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -707,6 +707,7 @@ function CopyHoverFrame({
|
|
|
707
707
|
/* @__PURE__ */ jsxs2(
|
|
708
708
|
"div",
|
|
709
709
|
{
|
|
710
|
+
"data-og-annotation-chrome": "",
|
|
710
711
|
className: cn(
|
|
711
712
|
"mt-1 flex h-7 items-center gap-1.5",
|
|
712
713
|
align === "end" ? "justify-end" : "justify-start"
|
|
@@ -1412,4 +1413,4 @@ export {
|
|
|
1412
1413
|
sandboxFilePathFromHref,
|
|
1413
1414
|
Markdown
|
|
1414
1415
|
};
|
|
1415
|
-
//# sourceMappingURL=chunk-
|
|
1416
|
+
//# sourceMappingURL=chunk-YAIPFO5D.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/human-input-form.tsx","../src/components/copy-button.tsx","../src/components/markdown.tsx","../src/lib/motion.ts","../src/lib/motion-inspect.ts","../src/components/soften-streaming-markdown.ts","../src/components/stream-reveal.ts"],"sourcesContent":["import type {\n HumanInputAnswer,\n HumanInputQuestion,\n SessionHumanInputRequest,\n SubmitHumanInputResponseRequest,\n} from \"@opengeni/sdk\";\nimport { ChevronDownIcon, ChevronUpIcon, MessageCircleQuestionIcon } from \"lucide-react\";\nimport { useEffect, useId, useRef, useState, type FormEvent, type ReactNode } from \"react\";\nimport { cn } from \"../lib/cn\";\n\nexport type HumanInputAnswerDraft = {\n values: string[];\n other: string;\n otherSelected: boolean;\n};\n\nexport type HumanInputFormMessages = {\n title: string;\n description: string;\n submit: string;\n skip: string;\n submitting: string;\n other: string;\n deadlineLabel: string;\n formatDeadline: (value: string) => string;\n required: string;\n otherRequired: string;\n minSelections: (count: number) => string;\n maxSelections: (count: number) => string;\n optional: string;\n /** Shown when the question list overflows the card and more content is below. */\n moreBelow: string;\n questionCount: (count: number) => string;\n collapse: string;\n expand: string;\n selectionHint: (min: number | null | undefined, max: number | null | undefined) => string | null;\n};\n\nexport const defaultHumanInputFormMessages: HumanInputFormMessages = {\n title: \"Input required\",\n /** Multi-question chrome has no default subtitle; hosts may still override. */\n description: \"\",\n submit: \"Send answers\",\n skip: \"Skip\",\n submitting: \"Submitting…\",\n other: \"Other\",\n deadlineLabel: \"Expires\",\n formatDeadline,\n required: \"This question is required.\",\n otherRequired: \"Enter a value for Other.\",\n minSelections: (count) => `Choose at least ${count} option${count === 1 ? \"\" : \"s\"}.`,\n maxSelections: (count) => `Choose no more than ${count} option${count === 1 ? \"\" : \"s\"}.`,\n optional: \"Optional\",\n moreBelow: \"More below\",\n questionCount: (count) => `${count} questions`,\n collapse: \"Collapse\",\n expand: \"Expand\",\n selectionHint: (min, max) => {\n if (min != null && max != null) return `Choose ${min}–${max}.`;\n if (min != null) return `Choose at least ${min}.`;\n if (max != null) return `Choose up to ${max}.`;\n return null;\n },\n};\n\nexport type HumanInputFormProps = {\n request: Pick<SessionHumanInputRequest, \"id\" | \"questions\" | \"allowSkip\" | \"expiresAt\">;\n onSubmit: (response: SubmitHumanInputResponseRequest) => void | Promise<void>;\n submitting?: boolean | undefined;\n error?: string | null | undefined;\n title?: ReactNode;\n description?: ReactNode;\n /** e.g. \"1 of 2\" when a host is stepping through parallel requests. */\n progressLabel?: ReactNode;\n submitLabel?: string | undefined;\n skipLabel?: string | undefined;\n messages?: Partial<HumanInputFormMessages> | undefined;\n autoFocus?: boolean | undefined;\n /** Start collapsed to a compact bar (drafts still retained). */\n defaultCollapsed?: boolean | undefined;\n className?: string | undefined;\n};\n\n/**\n * Styled but host-neutral renderer for one structured request. Matches the\n * waiting-tone decision language of ApprovalSurface: question-first, compact\n * options, sticky ask/submit chrome. Hosts can replace title/description or\n * use `useHumanInputRequests` headlessly.\n */\nexport function HumanInputForm(props: HumanInputFormProps) {\n // The pending-request read model is refreshed after session events and\n // returns newly allocated question arrays for the same durable request.\n // Key the state owner by that request's lifecycle identity so reconciliation\n // cannot erase an answer that the operator is still typing.\n return <HumanInputRequestForm key={props.request.id} {...props} />;\n}\n\nfunction HumanInputRequestForm({\n request,\n onSubmit,\n submitting = false,\n error,\n title,\n description,\n progressLabel,\n submitLabel,\n skipLabel,\n messages: messageOverrides,\n autoFocus = true,\n defaultCollapsed = false,\n className,\n}: HumanInputFormProps) {\n const messages = { ...defaultHumanInputFormMessages, ...messageOverrides };\n const singleQuestion = request.questions.length === 1 ? request.questions[0]! : null;\n const resolvedTitle =\n title === undefined\n ? singleQuestion\n ? (singleQuestion.label ?? singleQuestion.prompt)\n : messages.title\n : title;\n const resolvedDescription =\n description === undefined\n ? singleQuestion\n ? singleQuestion.label\n ? singleQuestion.prompt\n : (singleQuestion.helpText ?? null)\n : messages.description || null\n : description;\n const resolvedSubmitLabel = submitLabel ?? messages.submit;\n const resolvedSkipLabel = skipLabel ?? messages.skip;\n const formId = useId();\n const titleId = useId();\n const scrollRef = useRef<HTMLDivElement>(null);\n const [drafts, setDrafts] = useState<Record<string, HumanInputAnswerDraft>>(() =>\n initialDrafts(request.questions),\n );\n const [validationErrors, setValidationErrors] = useState<Record<string, string>>({});\n const [submissionError, setSubmissionError] = useState<string | null>(null);\n const [submittingInternally, setSubmittingInternally] = useState(false);\n const [overflowBelow, setOverflowBelow] = useState(false);\n const [collapsed, setCollapsed] = useState(defaultCollapsed);\n const submissionInFlight = useRef(false);\n const submissionGeneration = useRef(0);\n const busy = submitting || submittingInternally;\n\n useEffect(() => {\n if (collapsed) {\n setOverflowBelow(false);\n return;\n }\n const node = scrollRef.current;\n if (!node) return;\n const sync = () => {\n const { scrollTop, scrollHeight, clientHeight } = node;\n setOverflowBelow(\n scrollHeight > clientHeight + 2 && scrollTop + clientHeight < scrollHeight - 4,\n );\n };\n // Layout after paint: first sync can run before the max-height flex\n // constraint resolves, which falsely reports no overflow.\n const frame = requestAnimationFrame(sync);\n node.addEventListener(\"scroll\", sync, { passive: true });\n const observer = typeof ResizeObserver !== \"undefined\" ? new ResizeObserver(sync) : null;\n observer?.observe(node);\n const content = node.firstElementChild;\n if (content) observer?.observe(content);\n return () => {\n cancelAnimationFrame(frame);\n node.removeEventListener(\"scroll\", sync);\n observer?.disconnect();\n };\n }, [request.id, request.questions, collapsed]);\n\n const update = (\n questionId: string,\n apply: (draft: HumanInputAnswerDraft) => HumanInputAnswerDraft,\n ): void => {\n setDrafts((current) => ({\n ...current,\n [questionId]: apply(current[questionId] ?? emptyDraft()),\n }));\n setValidationErrors((current) => {\n if (!(questionId in current)) return current;\n const next = { ...current };\n delete next[questionId];\n return next;\n });\n };\n\n const submitResponse = async (response: SubmitHumanInputResponseRequest): Promise<void> => {\n if (busy || submissionInFlight.current) return;\n const generation = submissionGeneration.current;\n submissionInFlight.current = true;\n setSubmissionError(null);\n setSubmittingInternally(true);\n try {\n await onSubmit(response);\n } catch (cause) {\n if (generation === submissionGeneration.current) {\n setSubmissionError(cause instanceof Error ? cause.message : String(cause));\n }\n } finally {\n if (generation === submissionGeneration.current) {\n submissionInFlight.current = false;\n setSubmittingInternally(false);\n }\n }\n };\n\n const focusQuestion = (questionId: string): void => {\n const root = scrollRef.current;\n if (!root) return;\n const block = Array.from(\n root.querySelectorAll<HTMLElement>(\"[data-human-input-question]\"),\n ).find((node) => node.getAttribute(\"data-human-input-question\") === questionId);\n block?.scrollIntoView({ block: \"nearest\", behavior: \"smooth\" });\n const focusable = block?.querySelector<HTMLElement>(\n \"input:not([type='hidden']):not([disabled]), textarea:not([disabled])\",\n );\n focusable?.focus({ preventScroll: true });\n };\n\n const submit = async (event: FormEvent<HTMLFormElement>): Promise<void> => {\n event.preventDefault();\n const result = answersFromDrafts(request.questions, drafts, messages);\n if (Object.keys(result.errors).length > 0) {\n setValidationErrors(result.errors);\n const firstInvalid = request.questions.find((question) => question.id in result.errors);\n if (firstInvalid) {\n // After paint so aria-invalid / error text exist under the question.\n requestAnimationFrame(() => focusQuestion(firstInvalid.id));\n }\n return;\n }\n await submitResponse({ outcome: \"answered\", answers: result.answers });\n };\n\n const metaBits = [\n progressLabel,\n !singleQuestion ? messages.questionCount(request.questions.length) : null,\n request.expiresAt ? (\n <>\n {messages.deadlineLabel}{\" \"}\n <time dateTime={request.expiresAt} title={new Date(request.expiresAt).toLocaleString()}>\n {messages.formatDeadline(request.expiresAt)}\n </time>\n </>\n ) : null,\n ].filter(Boolean);\n\n if (collapsed) {\n return (\n <div\n data-human-input-request={request.id}\n data-human-input-collapsed=\"\"\n aria-labelledby={titleId}\n className={cn(\n \"og-root flex w-full items-center gap-3 rounded-og-lg border border-og-status-waiting/35 bg-og-status-waiting/5 px-3 py-2.5 shadow-og-sm\",\n className,\n )}\n >\n <span className=\"inline-flex size-8 shrink-0 items-center justify-center rounded-og-md bg-og-status-waiting/12 text-og-status-waiting\">\n <MessageCircleQuestionIcon aria-hidden=\"true\" className=\"size-4\" />\n </span>\n <div className=\"min-w-0 flex-1\">\n <h2 id={titleId} className=\"truncate text-og-sm font-semibold text-og-fg\">\n {resolvedTitle}\n </h2>\n {metaBits.length > 0 ? (\n <p className=\"mt-0.5 truncate text-og-xs text-og-fg-subtle\">{metaBits.join(\" · \")}</p>\n ) : null}\n </div>\n <button\n type=\"button\"\n onClick={() => setCollapsed(false)}\n className=\"inline-flex min-h-8 shrink-0 items-center gap-1 rounded-og-md border border-og-border px-2.5 py-1 text-og-xs font-medium text-og-fg-muted transition-colors hover:bg-og-surface-1 hover:text-og-fg\"\n >\n {messages.expand}\n <ChevronDownIcon aria-hidden=\"true\" className=\"size-3.5\" />\n </button>\n </div>\n );\n }\n\n return (\n <form\n data-human-input-request={request.id}\n onSubmit={(event) => void submit(event)}\n aria-labelledby={titleId}\n className={cn(\n // Multi-question: pin height at the cap so the flex body gets a real\n // box and overflow-y engages. max-height alone + percentage/`h-full`\n // children often sizes to content and clips with no scroll.\n \"og-root flex min-h-0 w-full flex-col overflow-hidden rounded-og-lg border border-og-status-waiting/35 bg-og-status-waiting/5 shadow-og-sm\",\n singleQuestion\n ? \"max-h-[min(28rem,50dvh)]\"\n : \"h-[min(28rem,50dvh)] max-h-[min(28rem,50dvh)]\",\n className,\n )}\n >\n <header className=\"shrink-0 border-b border-og-status-waiting/20 px-4 py-3\">\n <div className=\"flex items-start gap-3\">\n <span className=\"mt-0.5 inline-flex size-8 shrink-0 items-center justify-center rounded-og-md bg-og-status-waiting/12 text-og-status-waiting\">\n <MessageCircleQuestionIcon aria-hidden=\"true\" className=\"size-4\" />\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-baseline gap-x-2 gap-y-0.5\">\n <h2 id={titleId} className=\"text-og-md font-semibold text-og-fg\">\n {resolvedTitle}\n {singleQuestion?.required && !request.allowSkip ? (\n <span aria-hidden className=\"ml-1 text-og-status-failed\">\n *\n </span>\n ) : null}\n </h2>\n {progressLabel ? (\n <span className=\"text-og-xs font-medium text-og-status-waiting\">\n {progressLabel}\n </span>\n ) : null}\n {!singleQuestion ? (\n <span className=\"text-og-xs font-medium text-og-fg-subtle\">\n {messages.questionCount(request.questions.length)}\n </span>\n ) : null}\n </div>\n {resolvedDescription ? (\n <div className=\"mt-0.5 text-og-sm text-og-fg-muted\">{resolvedDescription}</div>\n ) : null}\n {request.expiresAt ? (\n <p className=\"mt-1 text-og-xs text-og-fg-subtle\">\n {messages.deadlineLabel}{\" \"}\n <time\n dateTime={request.expiresAt}\n title={new Date(request.expiresAt).toLocaleString()}\n >\n {messages.formatDeadline(request.expiresAt)}\n </time>\n </p>\n ) : null}\n {request.allowSkip && singleQuestion ? (\n <p className=\"mt-1 text-og-xs text-og-fg-subtle\">Or skip and let the agent decide.</p>\n ) : null}\n </div>\n <button\n type=\"button\"\n onClick={() => setCollapsed(true)}\n aria-label={messages.collapse}\n title={messages.collapse}\n className=\"inline-flex size-8 shrink-0 items-center justify-center rounded-og-md text-og-fg-muted transition-colors hover:bg-og-surface-1 hover:text-og-fg\"\n >\n <ChevronUpIcon aria-hidden=\"true\" className=\"size-4\" />\n </button>\n </div>\n </header>\n\n <div className=\"relative flex min-h-0 flex-1 flex-col overflow-hidden\">\n <div\n ref={scrollRef}\n className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain [scrollbar-gutter:stable]\"\n >\n <fieldset disabled={busy} className=\"min-w-0 space-y-4 px-4 py-3\">\n {request.questions.map((question, index) => {\n if (singleQuestion) {\n // Title already carries the question; only render the control + help extras.\n return (\n <div key={question.id} data-human-input-question={question.id}>\n <QuestionControls\n question={question}\n questionNumber={null}\n labelledBy={titleId}\n draft={drafts[question.id] ?? emptyDraft()}\n fieldId={`${formId}-${index}`}\n error={validationErrors[question.id]}\n messages={messages}\n autoFocus={autoFocus}\n firstOption\n showPromptChrome={false}\n allowSkip={request.allowSkip}\n busy={busy}\n onUpdate={(apply) => update(question.id, apply)}\n />\n </div>\n );\n }\n return (\n <div\n key={question.id}\n data-human-input-question={question.id}\n className=\"flex flex-col gap-1.5\"\n >\n <QuestionControls\n question={question}\n questionNumber={index + 1}\n labelledBy={undefined}\n draft={drafts[question.id] ?? emptyDraft()}\n fieldId={`${formId}-${index}`}\n error={validationErrors[question.id]}\n messages={messages}\n autoFocus={autoFocus && index === 0}\n firstOption={index === 0}\n showPromptChrome\n allowSkip={request.allowSkip}\n busy={busy}\n onUpdate={(apply) => update(question.id, apply)}\n />\n </div>\n );\n })}\n </fieldset>\n </div>\n {overflowBelow ? (\n <div\n className=\"pointer-events-none absolute inset-x-0 bottom-0 z-[1] flex flex-col items-center\"\n aria-hidden=\"true\"\n >\n <div className=\"h-10 w-full bg-gradient-to-t from-og-surface-1 via-og-surface-1/85 to-transparent\" />\n <span className=\"-mt-5 mb-1 rounded-og-full bg-og-surface-1 px-2.5 py-0.5 text-og-xs font-medium text-og-fg-muted shadow-og-sm ring-1 ring-og-border/60\">\n {messages.moreBelow}\n </span>\n </div>\n ) : null}\n </div>\n\n {(error ?? submissionError) ? (\n <p\n role=\"alert\"\n className=\"relative z-10 shrink-0 px-4 pb-1 text-og-sm text-og-status-failed\"\n >\n {error ?? submissionError}\n </p>\n ) : null}\n\n <footer className=\"relative z-10 flex shrink-0 items-center justify-end gap-2 border-t border-og-status-waiting/20 bg-og-surface-1/95 px-4 py-3 backdrop-blur-[2px]\">\n {request.allowSkip ? (\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => void submitResponse({ outcome: \"skipped\" })}\n className=\"inline-flex min-h-9 items-center rounded-og-md border border-og-border px-3 py-1.5 text-og-sm font-medium text-og-fg-muted transition-colors hover:bg-og-surface-1 hover:text-og-fg disabled:opacity-50\"\n >\n {resolvedSkipLabel}\n </button>\n ) : null}\n <button\n type=\"submit\"\n disabled={busy}\n className=\"inline-flex min-h-9 items-center rounded-og-md bg-og-accent-deep px-3 py-1.5 text-og-sm font-medium text-og-accent-fg transition hover:brightness-110 disabled:opacity-50\"\n >\n {busy ? messages.submitting : resolvedSubmitLabel}\n </button>\n </footer>\n </form>\n );\n}\n\nfunction QuestionControls({\n question,\n questionNumber,\n labelledBy,\n draft,\n fieldId,\n error,\n messages,\n autoFocus,\n firstOption,\n showPromptChrome,\n allowSkip,\n busy,\n onUpdate,\n}: {\n question: HumanInputQuestion;\n questionNumber: number | null;\n labelledBy: string | undefined;\n draft: HumanInputAnswerDraft;\n fieldId: string;\n error: string | undefined;\n messages: HumanInputFormMessages;\n autoFocus: boolean;\n firstOption: boolean;\n showPromptChrome: boolean;\n allowSkip: boolean;\n busy: boolean;\n onUpdate: (apply: (draft: HumanInputAnswerDraft) => HumanInputAnswerDraft) => void;\n}) {\n const errorId = `${fieldId}-error`;\n const helpId = `${fieldId}-help`;\n const labelId = `${fieldId}-label`;\n const promptId = `${fieldId}-prompt`;\n const otherChoiceId = `${fieldId}-other-choice`;\n const otherLabelId = `${fieldId}-other-label`;\n const otherTextId = `${fieldId}-other-text`;\n const visibleLabel = question.label ?? question.prompt;\n const controlLabelId = showPromptChrome ? labelId : labelledBy;\n const hint =\n question.kind === \"multi_select\"\n ? messages.selectionHint(\n question.validation?.minSelections,\n question.validation?.maxSelections,\n )\n : null;\n const describedBy =\n [\n question.label && showPromptChrome ? promptId : null,\n question.helpText && showPromptChrome ? helpId : null,\n hint ? `${fieldId}-hint` : null,\n error ? errorId : null,\n ]\n .filter(Boolean)\n .join(\" \") || undefined;\n const selectOtherDraft = (current: HumanInputAnswerDraft): HumanInputAnswerDraft => ({\n ...current,\n otherSelected: true,\n ...(question.kind === \"single_select\" ? { values: [] } : {}),\n });\n return (\n <>\n {showPromptChrome ? (\n <>\n <div className=\"flex flex-wrap items-baseline gap-x-2\">\n <label\n id={labelId}\n htmlFor={question.kind === \"text\" ? fieldId : undefined}\n className=\"text-og-sm font-medium text-og-fg\"\n >\n {questionNumber === null ? null : (\n <span className=\"mr-1.5 tabular-nums text-og-fg-muted\">{questionNumber}.</span>\n )}\n {questionNumber === null ? null : \" \"}\n {visibleLabel}\n {question.required && !allowSkip ? (\n <span aria-hidden className=\"ml-1 text-og-status-failed\">\n *\n </span>\n ) : !question.required ? (\n <span className=\"ml-1.5 text-og-xs font-normal text-og-fg-subtle\">\n {messages.optional}\n </span>\n ) : null}\n </label>\n </div>\n {question.label ? (\n <p id={promptId} className=\"text-og-sm text-og-fg-muted\">\n {question.prompt}\n </p>\n ) : null}\n {question.helpText ? (\n <p id={helpId} className=\"text-og-xs text-og-fg-subtle\">\n {question.helpText}\n </p>\n ) : null}\n {hint ? (\n <p id={`${fieldId}-hint`} className=\"text-og-xs text-og-fg-subtle\">\n {hint}\n </p>\n ) : null}\n </>\n ) : (\n <>\n {!question.required && allowSkip === false ? (\n <p className=\"text-og-xs text-og-fg-subtle\">{messages.optional}</p>\n ) : null}\n {question.helpText && question.label ? (\n <p id={helpId} className=\"mb-1.5 text-og-xs text-og-fg-subtle\">\n {question.helpText}\n </p>\n ) : null}\n {hint ? (\n <p id={`${fieldId}-hint`} className=\"mb-1.5 text-og-xs text-og-fg-subtle\">\n {hint}\n </p>\n ) : null}\n </>\n )}\n\n {question.kind === \"text\" ? (\n <textarea\n id={fieldId}\n value={draft.values[0] ?? \"\"}\n onChange={(event) =>\n onUpdate((current) => ({\n ...current,\n values: event.target.value ? [event.target.value] : [],\n }))\n }\n aria-invalid={Boolean(error)}\n aria-labelledby={controlLabelId}\n aria-describedby={describedBy}\n autoFocus={autoFocus}\n rows={2}\n className=\"min-h-14 w-full resize-y rounded-og-md border border-og-border bg-og-surface-1 px-3 py-2 text-og-sm text-og-fg outline-hidden placeholder:text-og-fg-subtle focus:border-og-accent\"\n />\n ) : (\n <div\n role={question.kind === \"single_select\" ? \"radiogroup\" : \"group\"}\n aria-labelledby={controlLabelId}\n aria-describedby={describedBy}\n className=\"flex flex-col gap-0.5\"\n >\n {question.options.map((option, optionIndex) => {\n const checked = draft.values.includes(option.id);\n return (\n <label\n key={option.id}\n className={cn(\n \"flex cursor-pointer items-start gap-2.5 rounded-og-md px-2.5 py-2 transition-colors\",\n checked\n ? \"bg-og-status-waiting/12 text-og-fg\"\n : \"text-og-fg hover:bg-og-surface-1/80\",\n )}\n >\n <input\n type={question.kind === \"single_select\" ? \"radio\" : \"checkbox\"}\n name={question.kind === \"single_select\" ? fieldId : undefined}\n autoFocus={autoFocus && firstOption && optionIndex === 0}\n checked={checked}\n onChange={(event) =>\n onUpdate((current) => ({\n ...current,\n values:\n question.kind === \"single_select\"\n ? event.target.checked\n ? [option.id]\n : []\n : event.target.checked\n ? [...current.values, option.id]\n : current.values.filter((value) => value !== option.id),\n ...(question.kind === \"single_select\" && event.target.checked\n ? { otherSelected: false }\n : {}),\n }))\n }\n className=\"mt-0.5 accent-og-accent\"\n />\n <span className=\"min-w-0\">\n <span className=\"block text-og-sm font-medium\">{option.label}</span>\n {option.description ? (\n <span className=\"mt-0.5 block text-og-xs text-og-fg-muted\">\n {option.description}\n </span>\n ) : null}\n </span>\n </label>\n );\n })}\n <div\n className={cn(\n \"flex items-start gap-2.5 rounded-og-md px-2.5 py-2 transition-colors\",\n draft.otherSelected\n ? \"bg-og-status-waiting/12 text-og-fg\"\n : \"text-og-fg hover:bg-og-surface-1/80\",\n )}\n >\n <input\n id={otherChoiceId}\n type={question.kind === \"single_select\" ? \"radio\" : \"checkbox\"}\n name={question.kind === \"single_select\" ? fieldId : undefined}\n aria-labelledby={otherLabelId}\n checked={draft.otherSelected}\n autoFocus={autoFocus && firstOption && question.options.length === 0}\n onChange={(event) =>\n onUpdate((current) => ({\n ...current,\n otherSelected: event.target.checked,\n ...(question.kind === \"single_select\" && event.target.checked\n ? { values: [] }\n : {}),\n }))\n }\n className=\"mt-2 accent-og-accent\"\n />\n <span className=\"min-w-0 flex-1\">\n <label\n id={otherLabelId}\n htmlFor={otherChoiceId}\n className=\"block text-og-sm font-medium\"\n >\n {messages.other}\n </label>\n <label htmlFor={otherTextId} className=\"sr-only\">\n {messages.other} answer for {visibleLabel}\n </label>\n <input\n id={otherTextId}\n type=\"text\"\n value={draft.other}\n disabled={busy}\n placeholder=\"Type a value…\"\n onClick={() => onUpdate(selectOtherDraft)}\n onFocus={() => onUpdate(selectOtherDraft)}\n onChange={(event) => {\n const other = event.target.value;\n onUpdate((current) => ({\n ...selectOtherDraft(current),\n other,\n }));\n }}\n className=\"mt-1.5 w-full rounded-og-sm border border-og-border bg-og-surface-1 px-2 py-1.5 text-og-sm text-og-fg outline-hidden focus:border-og-accent disabled:opacity-50\"\n />\n </span>\n </div>\n </div>\n )}\n {error ? (\n <p id={errorId} role=\"alert\" className=\"text-og-xs text-og-status-failed\">\n {error}\n </p>\n ) : null}\n </>\n );\n}\n\nexport function answersFromDrafts(\n questions: HumanInputQuestion[],\n drafts: Record<string, HumanInputAnswerDraft>,\n messageOverrides: Partial<HumanInputFormMessages> = {},\n): { answers: HumanInputAnswer[]; errors: Record<string, string> } {\n const messages = { ...defaultHumanInputFormMessages, ...messageOverrides };\n const answers: HumanInputAnswer[] = [];\n const errors: Record<string, string> = {};\n for (const question of questions) {\n const draft = drafts[question.id] ?? emptyDraft();\n const values = question.kind === \"text\" ? draft.values.filter(Boolean) : draft.values;\n const other = draft.otherSelected ? draft.other : \"\";\n const hasOther = Boolean(other.trim());\n const supplied = values.length + (hasOther ? 1 : 0);\n\n // Other-selected-but-empty must win over generic \"required\" — otherwise the\n // user sees the wrong diagnosis next to a clearly selected control.\n if (question.kind !== \"text\" && draft.otherSelected && !hasOther) {\n errors[question.id] = messages.otherRequired;\n continue;\n }\n\n if (question.required && supplied === 0) {\n errors[question.id] = messages.required;\n continue;\n }\n if (question.kind !== \"text\") {\n const min = question.validation?.minSelections;\n const max = question.kind === \"single_select\" ? 1 : question.validation?.maxSelections;\n if (min != null && supplied < min) {\n errors[question.id] = messages.minSelections(min);\n continue;\n }\n if (max != null && supplied > max) {\n errors[question.id] = messages.maxSelections(max);\n continue;\n }\n }\n if (supplied > 0) {\n answers.push({\n questionId: question.id,\n values,\n ...(hasOther ? { other } : {}),\n });\n }\n }\n return { answers, errors };\n}\n\nfunction initialDrafts(questions: HumanInputQuestion[]): Record<string, HumanInputAnswerDraft> {\n return Object.fromEntries(questions.map((question) => [question.id, emptyDraft()]));\n}\n\nfunction emptyDraft(): HumanInputAnswerDraft {\n return { values: [], other: \"\", otherSelected: false };\n}\n\nfunction formatDeadline(value: string): string {\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return value;\n const ms = date.getTime() - Date.now();\n if (ms <= 0) return \"deadline passed\";\n const minutes = Math.round(ms / 60_000);\n if (minutes < 1) return \"in under a minute\";\n if (minutes < 60) return `in ${minutes}m`;\n const hours = Math.round(minutes / 60);\n if (hours < 48) return `in ${hours}h`;\n return date.toLocaleString();\n}\n","import { CheckIcon, CopyIcon } from \"lucide-react\";\nimport { useEffect, useRef, useState, type MouseEvent, type ReactNode } from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { copyTextToClipboard } from \"../lib/clipboard\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"./tooltip\";\n\nconst COPIED_MS = 1600;\n\nexport type CopyButtonProps = {\n /** Plain text to copy, or a lazy getter (tables / late DOM). */\n text: string | (() => string);\n /** Accessible name + tooltip while idle. */\n label?: string | undefined;\n className?: string | undefined;\n /**\n * `always` — visible control.\n * `group-hover` — parent must use `group/copy`; fades in on hover/focus-visible.\n */\n reveal?: \"always\" | \"group-hover\" | undefined;\n};\n\n/**\n * Ghost icon copy control — no chrome box, no \"Copy code\" label.\n * Copy → check flash. Hover-reveal via `group/copy` on a parent.\n */\nexport function CopyButton({\n text,\n label = \"Copy\",\n className,\n reveal = \"group-hover\",\n}: CopyButtonProps) {\n const [copied, setCopied] = useState(false);\n const [tipOpen, setTipOpen] = useState(false);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n if (timerRef.current !== null) {\n clearTimeout(timerRef.current);\n }\n };\n }, []);\n\n const onClick = async (event: MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n // Capture before any await: React nulls `currentTarget` after the\n // synchronous handler turn. Blurring via the stale target throws and used\n // to skip the copied-reset timer, leaving the tip stuck on \"Copied\".\n const button = event.currentTarget;\n const pointerActivated = event.detail > 0;\n const value = typeof text === \"function\" ? text() : text;\n const ok = await copyTextToClipboard(value);\n if (!ok) {\n return;\n }\n setCopied(true);\n setTipOpen(true);\n if (timerRef.current !== null) {\n clearTimeout(timerRef.current);\n }\n // Always arm the reset before blur — a throw here must not leave the\n // forced \"Copied\" tip open forever.\n timerRef.current = setTimeout(() => {\n timerRef.current = null;\n setCopied(false);\n setTipOpen(false);\n }, COPIED_MS);\n // Pointer activation focuses the button and leaves `group-focus-within`\n // stuck after the cursor leaves — chrome never \"unhovers\". Keyboard\n // activation (`detail === 0`) keeps focus for a11y.\n if (pointerActivated) {\n button.blur();\n }\n };\n\n const tip = copied ? \"Copied\" : label;\n\n return (\n <Tooltip\n open={copied ? true : tipOpen}\n onOpenChange={(next) => {\n if (!copied) {\n setTipOpen(next);\n }\n }}\n >\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n data-og-copy=\"\"\n data-state={copied ? \"copied\" : \"idle\"}\n aria-label={tip}\n onClick={onClick}\n className={cn(\n \"inline-flex size-7 shrink-0 items-center justify-center rounded-og-sm pointer-coarse:size-11\",\n \"text-og-fg-subtle transition-[opacity,color,background-color] duration-150\",\n \"hover:bg-og-surface-2/80 hover:text-og-fg\",\n \"focus-visible:opacity-100 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent/40\",\n reveal === \"group-hover\" &&\n \"opacity-0 group-hover/copy:opacity-100 group-focus-within/copy:opacity-100 pointer-coarse:opacity-70\",\n copied && \"opacity-100 text-og-accent\",\n className,\n )}\n >\n {copied ? (\n <CheckIcon className=\"size-3.5\" aria-hidden />\n ) : (\n <CopyIcon className=\"size-3.5\" aria-hidden />\n )}\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"top\">{tip}</TooltipContent>\n </Tooltip>\n );\n}\n\n/** Hover-reveal chrome around a message / turn so {@link CopyButton} can fade in. */\nexport function CopyHoverFrame({\n children,\n className,\n copyText,\n label,\n align = \"end\",\n trailing,\n}: {\n children: ReactNode;\n className?: string | undefined;\n copyText: string;\n label: string;\n align?: \"start\" | \"end\" | undefined;\n /** Optional footer meta (e.g. sent/finished clock) — immediately after the copy control. */\n trailing?: ReactNode | undefined;\n}) {\n if (copyText.trim().length === 0) {\n return <div className={className}>{children}</div>;\n }\n return (\n <div className={cn(\"group/copy\", className)}>\n {children}\n {/* Sit under the body — top-right overlay collided with the first line. */}\n <div\n data-og-annotation-chrome=\"\"\n className={cn(\n \"mt-1 flex h-7 items-center gap-1.5\",\n align === \"end\" ? \"justify-end\" : \"justify-start\",\n )}\n >\n <CopyButton text={copyText} label={label} reveal=\"group-hover\" />\n {trailing}\n </div>\n </div>\n );\n}\n","import {\n Children,\n isValidElement,\n memo,\n useEffect,\n useMemo,\n useReducer,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from \"react\";\nimport ReactMarkdown, {\n defaultUrlTransform,\n type Components,\n type UrlTransform,\n} from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport { cn } from \"../lib/cn\";\nimport { tableElementToTsv } from \"../lib/clipboard\";\nimport { prefersReducedMotion } from \"../lib/motion\";\nimport { MOTION_INSPECT_SCALE } from \"../lib/motion-inspect\";\nimport { CopyButton } from \"./copy-button\";\nimport { softenStreamingMarkdown } from \"./soften-streaming-markdown\";\nimport { createStreamReveal, rehypeStreamReveal, type StreamReveal } from \"./stream-reveal\";\nimport { TooltipProvider } from \"./tooltip\";\n\n/**\n * The default renderer for chat message bodies in {@link MessageTimeline}.\n *\n * Agent (and user) messages arrive as GitHub-flavored markdown. This turns the\n * raw text into styled HTML using `react-markdown` + `remark-gfm`, themed to the\n * package's `og-*` design tokens so it reads as one cohesive dark surface — no\n * stock Tailwind colors leak in.\n *\n * It re-parses on every render, which is exactly right for streaming: a body\n * that is still arriving (an unterminated `**`, a half-open code fence, a table\n * mid-row) renders as best-effort markdown and resolves cleanly as the rest of\n * the tokens land. Consumers who want a different renderer can still pass\n * `renderMessageText` to `MessageTimeline` to override this entirely.\n */\nexport type MarkdownProps = {\n children: string;\n className?: string | undefined;\n /**\n * While true, newly arrived source fades in through tip ink (`.og-stream-ink`):\n * an age window over each append batch — fast streams keep a large soft band,\n * slow streams a tight tip. Paint-only: the DOM always holds the full truthful\n * text. Once streaming ends and trailing ink settles, the body re-renders as\n * plain markdown with a short local settle breath (no page-wide view\n * transition — that blinked the whole document).\n */\n streaming?: boolean | undefined;\n /**\n * Open a session-local file link in the host's Files surface. The path is the\n * exact decoded `sandbox:` payload; `line`, when present, is 1-based.\n */\n onSandboxFile?: ((path: string, line?: number) => void | Promise<void>) | undefined;\n};\n\n/** Exact target path plus optional 1-based line from a markdown href. */\nexport type SandboxFileLocation = {\n path: string;\n line: number | null;\n};\n\n/* --- element renderers (themed to og-* tokens) ------------------------------ */\n\nconst baseComponents: Components = {\n h1: ({ children, ...props }) => (\n <h1\n className=\"mt-5 mb-2.5 text-xl font-semibold tracking-tight text-og-fg first:mt-0\"\n {...props}\n >\n {children}\n </h1>\n ),\n h2: ({ children, ...props }) => (\n <h2 className=\"mt-5 mb-2 text-lg font-semibold tracking-tight text-og-fg first:mt-0\" {...props}>\n {children}\n </h2>\n ),\n h3: ({ children, ...props }) => (\n <h3\n className=\"mt-4 mb-1.5 text-og-md font-semibold tracking-tight text-og-fg first:mt-0\"\n {...props}\n >\n {children}\n </h3>\n ),\n h4: ({ children, ...props }) => (\n <h4\n className=\"mt-4 mb-1.5 text-og-sm font-semibold uppercase tracking-[0.04em] text-og-fg-muted first:mt-0\"\n {...props}\n >\n {children}\n </h4>\n ),\n p: ({ children, ...props }) => (\n <p className=\"my-2.5 leading-7 first:mt-0 last:mb-0\" {...props}>\n {children}\n </p>\n ),\n strong: ({ children, ...props }) => (\n <strong className=\"font-semibold text-og-fg\" {...props}>\n {children}\n </strong>\n ),\n em: ({ children, ...props }) => (\n <em className=\"italic\" {...props}>\n {children}\n </em>\n ),\n ul: ({ children, ...props }) => (\n <ul\n className=\"my-2.5 ml-5 flex list-disc flex-col gap-1 marker:text-og-fg-subtle first:mt-0 last:mb-0\"\n {...props}\n >\n {children}\n </ul>\n ),\n ol: ({ children, ...props }) => (\n <ol\n className=\"my-2.5 ml-5 flex list-decimal flex-col gap-1 marker:text-og-fg-subtle first:mt-0 last:mb-0\"\n {...props}\n >\n {children}\n </ol>\n ),\n // GFM task-list items carry a leading checkbox <input>; `list-none` + a\n // negative margin pull the checkbox back to the bullet column so it aligns\n // with the text.\n li: ({ children, ...props }) => (\n <li\n className=\"leading-7 marker:text-og-fg-subtle [&>ul]:my-1 [&>ol]:my-1 [&:has(>input)]:list-none [&:has(>input)]:-ml-5\"\n {...props}\n >\n {children}\n </li>\n ),\n input: ({ type, ...props }) =>\n type === \"checkbox\" ? (\n <input\n {...props}\n type=\"checkbox\"\n disabled\n className=\"mr-2 size-3.5 translate-y-[2px] cursor-default accent-og-accent align-baseline\"\n />\n ) : (\n <input type={type} {...props} />\n ),\n blockquote: ({ children, ...props }) => (\n <blockquote\n className=\"my-3 border-l-2 border-og-border-strong pl-3.5 text-og-fg-muted [&>p]:my-1.5 first:mt-0 last:mb-0\"\n {...props}\n >\n {children}\n </blockquote>\n ),\n hr: (props) => <hr className=\"my-4 border-0 border-t border-og-border\" {...props} />,\n // Inline `code` vs fenced code blocks. react-markdown v10 no longer passes an\n // `inline` flag; a fenced block is a <code> whose parent is <pre> (styled by\n // the `pre` renderer), so a `code` reaching here is treated as inline.\n code: ({ children, className: _className, ...props }) => (\n <code\n className=\"rounded-og-xs bg-og-surface-1 px-1 py-0.5 font-og-mono text-og-sm text-og-fg\"\n {...props}\n >\n {children}\n </code>\n ),\n // Fenced code — quiet mono block (no card / no nested vertical scroll).\n pre: ({ children }) => <MarkdownCodeBlock>{children}</MarkdownCodeBlock>,\n // Tables stay unboxed (hairline rules); hover reveals a TSV copy control.\n table: ({ children, ...props }) => <MarkdownTable {...props}>{children}</MarkdownTable>,\n thead: ({ children, ...props }) => <thead {...props}>{children}</thead>,\n th: ({ children, ...props }) => (\n <th\n className=\"border-b border-og-border px-0 py-1.5 pr-4 text-left font-medium text-og-fg first:pl-0\"\n {...props}\n >\n {children}\n </th>\n ),\n td: ({ children, ...props }) => (\n <td\n className=\"border-b border-og-border/70 px-0 py-1.5 pr-4 align-top text-og-fg-muted [tr:last-child>&]:border-b-0\"\n {...props}\n >\n {children}\n </td>\n ),\n img: ({ alt, src, ...props }) =>\n src ? (\n <img\n alt={alt ?? \"\"}\n src={src}\n className=\"my-3 max-w-full rounded-og-md border border-og-border\"\n {...props}\n />\n ) : alt ? (\n <span className=\"text-og-fg-subtle\" aria-disabled=\"true\">\n {alt}\n </span>\n ) : null,\n};\n\nconst MARKDOWN_LINK_CLASS =\n \"break-words font-medium text-og-accent-strong underline-offset-2 hover:underline\";\n\nfunction markdownComponents(onSandboxFile: MarkdownProps[\"onSandboxFile\"]): Components {\n return {\n ...baseComponents,\n a: ({ children, href, ...props }) => {\n const location = sandboxFileLocationFromHref(href);\n if (location !== null) {\n return (\n <SandboxMarkdownLink location={location} onSandboxFile={onSandboxFile}>\n {children}\n </SandboxMarkdownLink>\n );\n }\n if (isSandboxHref(href) || !href) {\n return (\n <span\n className=\"break-words font-medium text-og-fg-subtle underline decoration-dotted underline-offset-2\"\n aria-disabled=\"true\"\n title={\n isSandboxHref(href)\n ? \"This sandbox file reference is invalid\"\n : \"This link is unavailable\"\n }\n >\n {children}\n </span>\n );\n }\n return (\n <a\n className={MARKDOWN_LINK_CLASS}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n href={href}\n {...props}\n >\n {children}\n </a>\n );\n },\n };\n}\n\nfunction SandboxMarkdownLink({\n location,\n onSandboxFile,\n children,\n}: {\n location: SandboxFileLocation;\n onSandboxFile: MarkdownProps[\"onSandboxFile\"];\n children: ReactNode;\n}) {\n const [state, setState] = useState<\"idle\" | \"loading\" | \"error\">(\"idle\");\n const { path, line } = location;\n if (!onSandboxFile) {\n return (\n <span\n className=\"break-words font-medium text-og-fg-subtle underline decoration-dotted underline-offset-2\"\n aria-disabled=\"true\"\n title=\"This sandbox file requires a session-aware handler\"\n >\n {children}\n </span>\n );\n }\n const idleTitle = line !== null ? `Open ${path} at line ${line}` : `Open ${path}`;\n return (\n <button\n type=\"button\"\n className={cn(\n MARKDOWN_LINK_CLASS,\n \"inline-flex min-h-7 cursor-pointer items-center disabled:cursor-wait disabled:opacity-70 pointer-coarse:min-h-11\",\n )}\n disabled={state === \"loading\"}\n aria-busy={state === \"loading\"}\n title={state === \"error\" ? \"Couldn't open this file. Select to retry.\" : idleTitle}\n onClick={() => {\n setState(\"loading\");\n void Promise.resolve(onSandboxFile(path, line ?? undefined)).then(\n () => setState(\"idle\"),\n () => setState(\"error\"),\n );\n }}\n >\n {children}\n {state === \"loading\" ? \" (opening…)\" : state === \"error\" ? \" (retry)\" : null}\n </button>\n );\n}\n\nconst SANDBOX_SCHEME = \"sandbox:\";\nconst LEGACY_WORKSPACE_PREFIX = \"/workspace/\";\nconst TRAILING_LINE = /:([0-9]+)$/u;\nconst TRAILING_INVALID_LINE = /:-(?:[0-9]+)$|:[0-9]+-[0-9]+$/u;\nconst CONTROL_CHARACTER = /[\\u0000-\\u001f\\u007f]/u;\n\nfunction isSandboxHref(href: string | undefined): boolean {\n return href?.startsWith(SANDBOX_SCHEME) ?? false;\n}\n\n/**\n * Parse an OpenGeni `sandbox:` application href (plus the historical bare\n * `/workspace/...` form). The decoded path is intentionally opaque here:\n * target selection, path policy, and filesystem authority belong to the\n * session-aware host and its FileSystem boundary.\n */\nexport function sandboxFileLocationFromHref(href: string | undefined): SandboxFileLocation | null {\n if (!href) return null;\n const encodedLocation = isSandboxHref(href)\n ? href.slice(SANDBOX_SCHEME.length)\n : href.startsWith(LEGACY_WORKSPACE_PREFIX)\n ? href\n : null;\n if (!encodedLocation || encodedLocation.includes(\"?\") || encodedLocation.includes(\"#\")) {\n return null;\n }\n if (TRAILING_INVALID_LINE.test(encodedLocation)) return null;\n const lineMatch = TRAILING_LINE.exec(encodedLocation);\n const encodedPath = lineMatch ? encodedLocation.slice(0, -lineMatch[0].length) : encodedLocation;\n const line = lineMatch?.[1] ? Number(lineMatch[1]) : null;\n if (line !== null && (!Number.isSafeInteger(line) || line < 1)) return null;\n if (!encodedPath) return null;\n try {\n const path = decodeURIComponent(encodedPath);\n return path && !CONTROL_CHARACTER.test(path) ? { path, line } : null;\n } catch {\n return null;\n }\n}\n\n/** Return the exact decoded path for a supported sandbox-link href. */\nexport function sandboxFilePathFromHref(href: string | undefined): string | null {\n return sandboxFileLocationFromHref(href)?.path ?? null;\n}\n\nconst markdownUrlTransform: UrlTransform = (url, key, node) =>\n key === \"href\" && node.tagName === \"a\" && isSandboxHref(url) ? url : defaultUrlTransform(url);\n\n/** How long after the stream ends the reveal pipeline stays for trailing animations. */\n/** Trailing ink window after stream end — keep ≥ {@link INK_FADE_MS}. */\nconst REVEAL_LINGER_MS = 480 * MOTION_INSPECT_SCALE;\n/** Keep in sync with `--og-duration-markdown-crystallize` / view-transition CSS. */\nconst MARKDOWN_SETTLE_MS = 480 * MOTION_INSPECT_SCALE;\n\nfunction nodeText(node: ReactNode): string {\n if (node == null || typeof node === \"boolean\") {\n return \"\";\n }\n if (typeof node === \"string\" || typeof node === \"number\") {\n return String(node);\n }\n if (Array.isArray(node)) {\n return node.map(nodeText).join(\"\");\n }\n if (isValidElement<{ children?: ReactNode }>(node)) {\n return nodeText(node.props.children);\n }\n return \"\";\n}\n\nfunction fenceLanguage(children: ReactNode): string | null {\n let found: string | null = null;\n Children.forEach(children, (child) => {\n if (found || !isValidElement<{ className?: string }>(child)) {\n return;\n }\n const match = /language-([a-zA-Z0-9_+-]+)/.exec(child.props.className ?? \"\");\n if (match?.[1]) {\n found = match[1];\n }\n });\n return found;\n}\n\nfunction MarkdownCodeBlock({ children }: { children?: ReactNode }) {\n const code = nodeText(children).replace(/\\n$/, \"\");\n const language = fenceLanguage(children);\n // mt-only (no mb / last:mb-0): next sibling streaming in used to flip a\n // previous block's bottom margin on and yank tip-follow. Copy is overlay-only.\n // Fixed leading + overflow-x:auto with stable block chrome so wide ASCII lines\n // don't pop a scrollbar gutters mid-stream (another tip bob).\n return (\n <div className=\"group/copy relative mt-3 first:mt-0\">\n <div className=\"pointer-events-none absolute top-1.5 right-1.5 z-10 flex items-center gap-1\">\n {language ? (\n <span className=\"rounded px-1 py-0.5 font-og-mono text-[10px] uppercase tracking-wide text-og-fg-subtle/80 opacity-0 transition-opacity group-hover/copy:opacity-100 pointer-coarse:opacity-70\">\n {language}\n </span>\n ) : null}\n <div className=\"pointer-events-auto\">\n <CopyButton text={code} label=\"Copy code\" reveal=\"group-hover\" />\n </div>\n </div>\n <pre\n tabIndex={0}\n className=\"overflow-x-auto overflow-y-hidden rounded-og-md bg-og-surface-1/70 px-3 py-2.5 font-og-mono text-og-sm leading-5 text-og-fg-muted [scrollbar-gutter:stable] [&>code]:block [&>code]:border-0 [&>code]:bg-transparent [&>code]:p-0 [&>code]:leading-5 [&>code]:text-inherit\"\n >\n {children}\n </pre>\n </div>\n );\n}\n\nfunction MarkdownTable({ children, className, ...props }: ComponentPropsWithoutRef<\"table\">) {\n const tableRef = useRef<HTMLTableElement | null>(null);\n return (\n <div className=\"group/copy relative mt-3 max-w-full first:mt-0\">\n <div className=\"pointer-events-none absolute top-0 right-0 z-10\">\n <div className=\"pointer-events-auto\">\n <CopyButton\n text={() => tableElementToTsv(tableRef.current)}\n label=\"Copy table\"\n reveal=\"group-hover\"\n />\n </div>\n </div>\n <div className=\"overflow-x-auto\" tabIndex={0}>\n <table\n ref={tableRef}\n className={cn(\"w-full min-w-0 border-collapse text-og-base\", className)}\n {...props}\n >\n {children}\n </table>\n </div>\n </div>\n );\n}\n\nfunction MarkdownImpl({ children, className, streaming = false, onSandboxFile }: MarkdownProps) {\n // Tip-ink engine for THIS body: created on the first streaming render, kept\n // through a short linger after the stream ends (so the last age window can\n // finish), then dropped so settled bodies pay zero cost. Observing during\n // render is idempotent per text length — StrictMode double-renders are safe.\n const revealRef = useRef<StreamReveal | null>(null);\n const bodyRef = useRef<HTMLDivElement | null>(null);\n const [, bump] = useReducer((n: number) => n + 1, 0);\n const [settling, setSettling] = useState(false);\n const hadRevealRef = useRef(false);\n const now = typeof performance !== \"undefined\" ? performance.now() : Date.now();\n\n // Local settle breath only — View Transitions with `::view-transition-*(*)`\n // were fading the document root and felt like a full-page blink / focus loss\n // right as a turn ended (just before the next user message in the seed loop).\n const crystallize = (mutate: () => void) => {\n mutate();\n setSettling(true);\n bump();\n return setTimeout(() => setSettling(false), MARKDOWN_SETTLE_MS);\n };\n if (streaming && revealRef.current === null && !prefersReducedMotion()) {\n revealRef.current = createStreamReveal();\n }\n const reveal = revealRef.current;\n if (reveal !== null && streaming) {\n reveal.observe(children, now);\n }\n if (reveal !== null) {\n hadRevealRef.current = true;\n }\n const revealActive = reveal !== null && (streaming || reveal.hasActive(now));\n // The plugin walks the standard hast tree; a structural local type keeps the\n // module dependency-free, at the cost of this narrowing cast at the seam.\n const rehypePlugins =\n revealActive && reveal !== null\n ? ([[rehypeStreamReveal, { reveal, now }]] as unknown as NonNullable<\n Parameters<typeof ReactMarkdown>[0][\"rehypePlugins\"]\n >)\n : undefined;\n\n // Drop tip ink after trailing age windows finish. Same commit crystallizes:\n // ink spans → final plain markdown (soften off) + a short local settle breath.\n useEffect(() => {\n if (streaming || revealRef.current === null) {\n return;\n }\n let clearSettle: ReturnType<typeof setTimeout> | undefined;\n const timer = setTimeout(() => {\n const shouldSettle = hadRevealRef.current && !prefersReducedMotion();\n if (shouldSettle) {\n hadRevealRef.current = false;\n }\n if (shouldSettle) {\n clearSettle = crystallize(() => {\n revealRef.current = null;\n });\n } else {\n revealRef.current = null;\n bump();\n }\n }, REVEAL_LINGER_MS);\n return () => {\n clearTimeout(timer);\n if (clearSettle !== undefined) {\n clearTimeout(clearSettle);\n }\n };\n }, [streaming]);\n\n // No-reveal path (stream ended before any ink batch): soften already dropped\n // with `streaming`; keep the same local settle breath.\n const wasStreamingRef = useRef(streaming);\n useEffect(() => {\n const ended = wasStreamingRef.current && !streaming;\n wasStreamingRef.current = streaming;\n if (!ended || revealRef.current !== null || prefersReducedMotion()) {\n return;\n }\n setSettling(true);\n const timer = setTimeout(() => setSettling(false), MARKDOWN_SETTLE_MS);\n return () => clearTimeout(timer);\n }, [streaming]);\n\n // Soften unfinished markers for DISPLAY while the reveal pipeline is alive\n // (stream + linger) — not only while `streaming` — so task lists / tables /\n // fences don't snap to final GFM one commit before the crystallize morph.\n // Reveal identity still tracks the true source (`children`).\n const parseText = streaming || revealActive ? softenStreamingMarkdown(children) : children;\n const components = useMemo(() => markdownComponents(onSandboxFile), [onSandboxFile]);\n\n // `min-w-0` lets the prose shrink inside flex parents (message bubbles) so\n // long links and code blocks wrap/scroll instead of forcing overflow.\n return (\n <TooltipProvider delayDuration={400}>\n <div\n ref={bodyRef}\n className={cn(\n \"og-markdown-body min-w-0 break-words\",\n settling && \"og-markdown-settle\",\n className,\n )}\n >\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n rehypePlugins={rehypePlugins}\n components={components}\n urlTransform={markdownUrlTransform}\n >\n {parseText}\n </ReactMarkdown>\n </div>\n </TooltipProvider>\n );\n}\n\n/** Memoized so streaming re-renders of the parent don't re-parse settled bodies. */\nexport const Markdown = memo(MarkdownImpl);\n","import { flushSync } from \"react-dom\";\n\n/**\n * Live `prefers-reduced-motion` check for JS-driven motion (scroll glides,\n * streaming word reveals). CSS animations are already neutralized globally in\n * styles/index.css; this lets the imperative paths skip their work entirely.\n */\nlet query: MediaQueryList | null | undefined;\n\nexport function prefersReducedMotion(): boolean {\n if (query === undefined) {\n query =\n typeof window !== \"undefined\" && typeof window.matchMedia === \"function\"\n ? window.matchMedia(\"(prefers-reduced-motion: reduce)\")\n : null;\n }\n return query?.matches ?? false;\n}\n\n/** Test seam: forget the cached MediaQueryList so a stubbed matchMedia applies. */\nexport function resetReducedMotionCache(): void {\n query = undefined;\n}\n\ntype ViewTransitionResult = { finished: Promise<void> };\ntype ViewTransitionCallback = () => void;\ntype ViewTransitionOptions = {\n update: ViewTransitionCallback;\n types?: string[];\n};\ntype ViewTransitionStarter = {\n (callback: ViewTransitionCallback): ViewTransitionResult;\n (options: ViewTransitionOptions): ViewTransitionResult;\n};\n\n/** Active VT type for markdown crystallize — scoped CSS, not a full-page blink. */\nexport const MARKDOWN_CRYSTALLIZE_VT_TYPE = \"og-md-crystallize\";\n\n/**\n * Run a DOM update inside the browser View Transition API when available.\n * Snapshots the before/after paint and cross-fades (or custom CSS morphs)\n * between them — the platform \"morph\" primitive React's experimental\n * `<ViewTransition>` wraps. Falls back to a synchronous update.\n */\nexport function runViewTransition(update: () => void, options?: { types?: string[] }): void {\n if (prefersReducedMotion()) {\n update();\n return;\n }\n const doc = typeof document !== \"undefined\" ? document : null;\n const start = doc\n ? ((doc as Document & { startViewTransition?: ViewTransitionStarter }).startViewTransition ??\n null)\n : null;\n if (typeof start !== \"function\") {\n update();\n return;\n }\n const types = options?.types;\n if (types && types.length > 0) {\n try {\n Reflect.apply(start, doc, [\n {\n update: () => {\n flushSync(update);\n },\n types,\n },\n ]);\n return;\n } catch {\n // Older engines only accept the callback form.\n }\n }\n Reflect.apply(start, doc, [\n () => {\n flushSync(update);\n },\n ]);\n}\n","/**\n * TEMP eyeball scale for vertical motion (tip-follow, settle fold, CSS).\n * Set back to `1` before landing — not a product knob.\n */\nexport const MOTION_INSPECT_SCALE = 1;\n","/**\n * Display-only softener for mid-stream markdown.\n *\n * While tokens are still arriving, incomplete markers (`**bold`, an open\n * fence, a half-finished link) would otherwise render as raw punctuation —\n * the hard \"breaking\" flash. This closes a small set of common unfinished\n * constructs so the parse looks settled; the SOURCE string is never mutated\n * (callers pass the softened copy only into the markdown parser).\n *\n * When the real closers land, the softened and true parses converge and the\n * crystallize breath covers the remount.\n */\n\nexport function softenStreamingMarkdown(source: string): string {\n if (source.length === 0) {\n return source;\n }\n let text = source;\n\n // Unclosed fenced code block: an odd count of ``` line-openers means the\n // trailing fence is still in flight. Always soft-close — including an empty\n // opener — so code chrome (padding/tint) appears once at ``` and lines only\n // grow the body. Stripping empty openers deferred chrome until the first\n // body line, which landed as one fat height spike (yank around fences).\n //\n // If the body already ends with `\\n`, append only ``` — a second `\\n``` would\n // invent a blank line that vanishes when the real closer lands (height shrink\n // → tip-follow compensate + mid soft-rise cancel = up/down flicker).\n if (countFences(text) % 2 === 1) {\n text += text.endsWith(\"\\n\") ? \"```\" : \"\\n```\";\n }\n\n // Work outside fenced blocks so we don't \"fix\" markers that are literal\n // code content.\n const segments = splitByFences(text);\n for (const segment of segments) {\n if (segment.kind === \"fence\") {\n continue;\n }\n segment.value = closeInlineMarkers(segment.value);\n }\n let result = segments.map((segment) => segment.value).join(\"\");\n // split(\"\\n\") drops a trailing newline into an empty final line; restore it\n // so balanced finished fences round-trip byte-identical.\n if (text.endsWith(\"\\n\") && !result.endsWith(\"\\n\")) {\n result += \"\\n\";\n }\n return result;\n}\n\nfunction countFences(text: string): number {\n let count = 0;\n for (const line of text.split(\"\\n\")) {\n if (/^ {0,3}```/.test(line)) {\n count += 1;\n }\n }\n return count;\n}\n\ntype Segment = { kind: \"prose\" | \"fence\"; value: string };\n\nfunction splitByFences(text: string): Segment[] {\n const segments: Segment[] = [];\n const lines = text.split(\"\\n\");\n let buf: string[] = [];\n let inFence = false;\n /**\n * `boundary`: prose → fence. `join` alone drops a blank line before ```\n * (`[\"a\",\"\"].join` → `\"a\\n\"`, need `\"a\\n\\n\"`), so append an extra `\\n`.\n * `end`: final segment. Trailing `\"\"` from `split(\"\\n\")` already encodes a\n * terminating newline — do NOT append another (that was inventing `\\n\\n`\n * on every streamed line and shrinking it away at crystallize).\n */\n const flush = (kind: Segment[\"kind\"], mode: \"boundary\" | \"end\") => {\n if (buf.length === 0) {\n return;\n }\n let value = buf.join(\"\\n\");\n if (mode === \"boundary\") {\n value += \"\\n\";\n }\n segments.push({ kind, value });\n buf = [];\n };\n for (const line of lines) {\n const isFence = /^ {0,3}```/.test(line);\n if (isFence) {\n if (inFence) {\n buf.push(line);\n flush(\"fence\", \"end\");\n inFence = false;\n } else {\n flush(\"prose\", \"boundary\");\n buf.push(line);\n inFence = true;\n }\n continue;\n }\n buf.push(line);\n }\n flush(inFence ? \"fence\" : \"prose\", \"end\");\n return segments;\n}\n\n/**\n * Close unmatched **, *, ~~, and ` in prose. Order matters: handle the\n * longer bold/strike markers before single `*` so we don't steal from `**`.\n */\nfunction closeInlineMarkers(prose: string): string {\n let text = prose;\n text = closeDelimiter(text, \"~~\");\n text = closeDelimiter(text, \"**\");\n text = closeDelimiter(text, \"__\");\n text = closeSingleBackticks(text);\n text = closeSingleAsterisks(text);\n text = closeUnfinishedLink(text);\n return text;\n}\n\nfunction closeDelimiter(text: string, delimiter: string): string {\n // Count occurrences that aren't escaped. Odd → append a closer.\n let count = 0;\n let i = 0;\n while (i < text.length) {\n if (text[i] === \"\\\\\" && i + 1 < text.length) {\n i += 2;\n continue;\n }\n if (text.startsWith(delimiter, i)) {\n count += 1;\n i += delimiter.length;\n continue;\n }\n i += 1;\n }\n return count % 2 === 1 ? insertBeforeTrailingNewlines(text, delimiter) : text;\n}\n\n/** Soft closers belong before trailing `\\n`s so restore/round-trip stay stable. */\nfunction insertBeforeTrailingNewlines(text: string, suffix: string): string {\n let end = text.length;\n while (end > 0 && text[end - 1] === \"\\n\") {\n end -= 1;\n }\n return text.slice(0, end) + suffix + text.slice(end);\n}\n\nfunction closeSingleBackticks(text: string): string {\n // Ignore ``` (fences already stripped) and even pairs. A trailing unmatched\n // ` is the common \"inline code still typing\" case.\n let count = 0;\n for (let i = 0; i < text.length; i += 1) {\n if (text[i] === \"\\\\\" && i + 1 < text.length) {\n i += 1;\n continue;\n }\n if (text[i] === \"`\") {\n // Skip triple backticks if any leaked into prose.\n if (text.startsWith(\"```\", i)) {\n i += 2;\n continue;\n }\n count += 1;\n }\n }\n return count % 2 === 1 ? insertBeforeTrailingNewlines(text, \"`\") : text;\n}\n\nfunction closeSingleAsterisks(text: string): string {\n // Count `*` that are NOT part of `**` (already handled). Odd → close italic.\n let count = 0;\n for (let i = 0; i < text.length; i += 1) {\n if (text[i] === \"\\\\\" && i + 1 < text.length) {\n i += 1;\n continue;\n }\n if (text[i] === \"*\" && text[i + 1] === \"*\") {\n i += 1;\n continue;\n }\n if (text[i] === \"*\") {\n count += 1;\n }\n }\n return count % 2 === 1 ? insertBeforeTrailingNewlines(text, \"*\") : text;\n}\n\nfunction closeUnfinishedLink(text: string): string {\n // `[label](url` without the trailing `)` — close it. Bare `[label` without\n // `](` is left alone (too ambiguous with footnotes / prose brackets).\n const open = text.lastIndexOf(\"](\");\n if (open === -1) {\n return text;\n }\n const after = text.slice(open + 2);\n if (after.includes(\")\")) {\n return text;\n }\n // Don't close if a later `[` started something else after.\n if (after.includes(\"[\")) {\n return text;\n }\n return insertBeforeTrailingNewlines(text, \")\");\n}\n","/* ----------------------------------------------------------------------------\n Streaming tip ink (age-window fade)\n\n Append-only markdown grows at the tip. Rather than staggering per-word\n onsets (glitter under fast models), each append batch is born at wall time\n and fades in over a fixed age window:\n\n opacity progress = clamp((now − birth) / INK_FADE_MS, 0, 1)\n\n Fast arrival → many recent characters still young → a large soft band.\n Slow arrival → only the tip is young → a tight tip wash.\n Same rule both ways; time does the work. No per-word stagger, no artificial\n content lag — layout always holds the truthful text; paint only.\n\n Identity is the character offset into the source. CSS animation-delay =\n birth − now (often negative) so mid-fade re-renders resume, never restart.\n Runs settle back to plain text once age ≥ INK_FADE_MS (zero span cost).\n -------------------------------------------------------------------------- */\n\nimport { MOTION_INSPECT_SCALE } from \"../lib/motion-inspect\";\n\n/** Keep in sync with `--og-duration-stream` / `.og-stream-ink` in styles. */\nexport const INK_FADE_MS = 420 * MOTION_INSPECT_SCALE;\n/** @deprecated Use {@link INK_FADE_MS}. */\nexport const WORD_ANIMATION_MS = INK_FADE_MS;\n\n/**\n * A first observation larger than this is pre-existing history (timeline\n * opened mid-stream), not live tip — it renders instantly.\n */\nconst INITIAL_ANIMATED_LIMIT = 400;\n\ntype InkBatch = {\n start: number;\n end: number;\n birth: number;\n};\n\nexport type StreamReveal = {\n /** Register the full current source text; new suffix becomes an ink batch. */\n observe(text: string, now: number): void;\n /**\n * CSS animation-delay (ms) for the run covering `offset`, or null when that\n * ink has settled and should render as plain text. Negative = resume mid-fade.\n */\n delayFor(offset: number, now: number): number | null;\n /** True while any batch is still inside its fade window. */\n hasActive(now: number): boolean;\n};\n\nexport function createStreamReveal(): StreamReveal {\n let batches: InkBatch[] = [];\n let revealedChars = -1;\n\n return {\n observe(text, now) {\n if (revealedChars === -1) {\n revealedChars = text.length > INITIAL_ANIMATED_LIMIT ? text.length : 0;\n }\n if (text.length <= revealedChars) {\n // Idempotent re-observation (StrictMode) or defensive no-op on shrink.\n revealedChars = Math.max(revealedChars, text.length);\n return;\n }\n batches.push({ start: revealedChars, end: text.length, birth: now });\n revealedChars = text.length;\n batches = batches.filter((batch) => batch.birth + INK_FADE_MS > now);\n },\n\n delayFor(offset, now) {\n const batch = findBatch(batches, offset);\n if (!batch) {\n return null;\n }\n const delay = batch.birth - now;\n return delay + INK_FADE_MS <= 0 ? null : delay;\n },\n\n hasActive(now) {\n const last = batches[batches.length - 1];\n return last !== undefined && last.birth + INK_FADE_MS > now;\n },\n };\n}\n\nfunction findBatch(batches: readonly InkBatch[], offset: number): InkBatch | null {\n let low = 0;\n let high = batches.length - 1;\n while (low <= high) {\n const mid = (low + high) >> 1;\n const batch = batches[mid]!;\n if (offset < batch.start) {\n high = mid - 1;\n } else if (offset >= batch.end) {\n low = mid + 1;\n } else {\n return batch;\n }\n }\n return null;\n}\n\n/* ----------------------------------------------------------------------------\n rehype: wrap still-fading source runs in `.og-stream-ink` spans.\n\n Contiguous offsets that share one birth (one append batch) become ONE span —\n a continuous ink surface, not per-word glitter. Code/pre stay plain. Nodes\n without source positions (syntax rewritten around them) render plain too.\n -------------------------------------------------------------------------- */\n\ntype HastText = {\n type: \"text\";\n value: string;\n position?: { start?: { offset?: number | undefined } | undefined } | undefined;\n};\n\ntype HastParent = {\n type: string;\n tagName?: string;\n value?: string;\n children?: HastChild[];\n};\n\ntype HastChild = (HastText | HastParent) & Record<string, unknown>;\n\nexport function rehypeStreamReveal(options: { reveal: StreamReveal; now: number }) {\n const { reveal, now } = options;\n return (tree: HastParent) => {\n walk(tree, false);\n };\n\n function walk(node: HastParent, insideVerbatim: boolean): void {\n if (!node.children) {\n return;\n }\n const verbatim = insideVerbatim || node.tagName === \"code\" || node.tagName === \"pre\";\n const next: HastChild[] = [];\n for (const child of node.children) {\n if (child.type === \"text\" && !verbatim) {\n next.push(...splitTextNode(child as HastText));\n continue;\n }\n walk(child as HastParent, verbatim);\n next.push(child);\n }\n node.children = next;\n }\n\n function splitTextNode(node: HastText): HastChild[] {\n const sourceOffset = node.position?.start?.offset;\n if (sourceOffset === undefined) {\n return [node as HastChild];\n }\n const value = node.value;\n const out: HastChild[] = [];\n let plain = \"\";\n const flushPlain = () => {\n if (plain.length > 0) {\n out.push({ type: \"text\", value: plain } as HastChild);\n plain = \"\";\n }\n };\n\n let i = 0;\n while (i < value.length) {\n const delay = reveal.delayFor(sourceOffset + i, now);\n let j = i + 1;\n while (j < value.length) {\n const nextDelay = reveal.delayFor(sourceOffset + j, now);\n if (nextDelay !== delay) {\n break;\n }\n j += 1;\n }\n const slice = value.slice(i, j);\n if (delay === null) {\n plain += slice;\n } else {\n flushPlain();\n out.push({\n type: \"element\",\n tagName: \"span\",\n properties: {\n className: [\"og-stream-ink\"],\n style: `animation-delay:${Math.round(delay)}ms`,\n },\n children: [{ type: \"text\", value: slice }],\n } as unknown as HastChild);\n }\n i = j;\n }\n flushPlain();\n return out.length > 0 ? out : [node as HastChild];\n }\n}\n"],"mappings":"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","names":["useEffect","useRef","useState","jsx","jsxs","useState","useRef","useEffect","useEffect","useRef","useState","jsx","jsxs","useState","useRef","useEffect"]}
|