@webless/agent 0.9.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/embed.css +5 -5
- package/dist/embed.css.map +1 -1
- package/dist/react.cjs +31 -41
- package/dist/react.cjs.map +1 -1
- package/dist/react.css +5 -5
- package/dist/react.css.map +1 -1
- package/dist/react.d.cts +3 -1
- package/dist/react.d.ts +3 -1
- package/dist/react.js +31 -41
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
package/dist/react.d.cts
CHANGED
|
@@ -153,9 +153,11 @@ type AgentTranscriptProps = {
|
|
|
153
153
|
agentLabel?: string;
|
|
154
154
|
visitorLabel?: string;
|
|
155
155
|
label?: string;
|
|
156
|
+
/** Hide the opening marker when the host already shows the conversation date. */
|
|
157
|
+
showInitialTimestamp?: boolean;
|
|
156
158
|
formatTimestamp?: (createdAt: number) => string;
|
|
157
159
|
};
|
|
158
160
|
/** Renders a stored snapshot; never creates a session or exposes chat actions. */
|
|
159
|
-
declare function AgentTranscript({ messages, activities, theme, colorScheme, agentLabel, visitorLabel, label, formatTimestamp, }: AgentTranscriptProps): react.JSX.Element;
|
|
161
|
+
declare function AgentTranscript({ messages, activities, theme, colorScheme, agentLabel, visitorLabel, label, formatTimestamp, showInitialTimestamp, }: AgentTranscriptProps): react.JSX.Element;
|
|
160
162
|
|
|
161
163
|
export { AGENT_ANSWER_FEEDBACK_EVENT_TYPE, AgentColorScheme, AgentInputResponse, AgentMessageFeedback, AgentPlacementConfig, AgentRail, AgentRailPhase, type AgentRailProps, AgentRailState, AgentRailTheme, AgentToolUiSurface, AgentTranscript, type AgentTranscriptActivity, type AgentTranscriptProps, AgentWidget, type AgentWidgetProps, ConversationMessage, FollowUpSuggestion, MessageActions, ResolvedVisitorToolResultPresentation, ToolStep, type UseAgentChatOptions, VisitorToolResultRegistry, buildAgentAnswerFeedbackEvent, createIdleSuggestions, findPrecedingVisitorText, hasVisitorMessages, isAgentBusy, sendAgentAnswerFeedback, useAgentChat };
|
package/dist/react.d.ts
CHANGED
|
@@ -153,9 +153,11 @@ type AgentTranscriptProps = {
|
|
|
153
153
|
agentLabel?: string;
|
|
154
154
|
visitorLabel?: string;
|
|
155
155
|
label?: string;
|
|
156
|
+
/** Hide the opening marker when the host already shows the conversation date. */
|
|
157
|
+
showInitialTimestamp?: boolean;
|
|
156
158
|
formatTimestamp?: (createdAt: number) => string;
|
|
157
159
|
};
|
|
158
160
|
/** Renders a stored snapshot; never creates a session or exposes chat actions. */
|
|
159
|
-
declare function AgentTranscript({ messages, activities, theme, colorScheme, agentLabel, visitorLabel, label, formatTimestamp, }: AgentTranscriptProps): react.JSX.Element;
|
|
161
|
+
declare function AgentTranscript({ messages, activities, theme, colorScheme, agentLabel, visitorLabel, label, formatTimestamp, showInitialTimestamp, }: AgentTranscriptProps): react.JSX.Element;
|
|
160
162
|
|
|
161
163
|
export { AGENT_ANSWER_FEEDBACK_EVENT_TYPE, AgentColorScheme, AgentInputResponse, AgentMessageFeedback, AgentPlacementConfig, AgentRail, AgentRailPhase, type AgentRailProps, AgentRailState, AgentRailTheme, AgentToolUiSurface, AgentTranscript, type AgentTranscriptActivity, type AgentTranscriptProps, AgentWidget, type AgentWidgetProps, ConversationMessage, FollowUpSuggestion, MessageActions, ResolvedVisitorToolResultPresentation, ToolStep, type UseAgentChatOptions, VisitorToolResultRegistry, buildAgentAnswerFeedbackEvent, createIdleSuggestions, findPrecedingVisitorText, hasVisitorMessages, isAgentBusy, sendAgentAnswerFeedback, useAgentChat };
|
package/dist/react.js
CHANGED
|
@@ -29,6 +29,9 @@ import {
|
|
|
29
29
|
useAgentColorScheme
|
|
30
30
|
} from "./chunk-3E632FNE.js";
|
|
31
31
|
|
|
32
|
+
// src/react/components/AgentTranscript/AgentTranscript.tsx
|
|
33
|
+
import { Fragment as Fragment2 } from "react";
|
|
34
|
+
|
|
32
35
|
// src/react/components/AgentTranscript/TranscriptActivity.tsx
|
|
33
36
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
34
37
|
var statusLabels = {
|
|
@@ -56,16 +59,12 @@ function RecordedResult({
|
|
|
56
59
|
return /* @__PURE__ */ jsx(VisitorToolResultView, { disabled: true, result });
|
|
57
60
|
}
|
|
58
61
|
function TranscriptActivity({
|
|
59
|
-
activity
|
|
60
|
-
formatTimestamp
|
|
62
|
+
activity
|
|
61
63
|
}) {
|
|
62
|
-
const date = new Date(activity.createdAt);
|
|
63
|
-
const validTimestamp = Number.isFinite(date.getTime());
|
|
64
64
|
const result = activity.result?.kind === "hidden" ? void 0 : activity.result;
|
|
65
65
|
const heading = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
66
66
|
/* @__PURE__ */ jsx("span", { children: activity.category === "specialist" ? `Specialist \xB7 ${activity.label}` : activity.label }),
|
|
67
|
-
activity.status !== "completed" ? /* @__PURE__ */ jsx("span", { className: "agent-transcript__activity-status", children: statusLabels[activity.status] }) : null
|
|
68
|
-
validTimestamp ? /* @__PURE__ */ jsx("time", { dateTime: date.toISOString(), children: formatTimestamp(activity.createdAt) }) : null
|
|
67
|
+
activity.status !== "completed" ? /* @__PURE__ */ jsx("span", { className: "agent-transcript__activity-status", children: statusLabels[activity.status] }) : null
|
|
69
68
|
] });
|
|
70
69
|
return /* @__PURE__ */ jsx("li", { className: "agent-transcript__activity", "data-status": activity.status, children: result ? /* @__PURE__ */ jsxs("details", { children: [
|
|
71
70
|
/* @__PURE__ */ jsx("summary", { className: "agent-transcript__activity-heading", children: heading }),
|
|
@@ -127,7 +126,8 @@ function AgentTranscript({
|
|
|
127
126
|
agentLabel = "Agent",
|
|
128
127
|
visitorLabel = "Visitor",
|
|
129
128
|
label = "Conversation transcript",
|
|
130
|
-
formatTimestamp = defaultTimestamp
|
|
129
|
+
formatTimestamp = defaultTimestamp,
|
|
130
|
+
showInitialTimestamp = true
|
|
131
131
|
}) {
|
|
132
132
|
const scheme = useAgentColorScheme(colorScheme);
|
|
133
133
|
const entries = [
|
|
@@ -145,41 +145,31 @@ function AgentTranscript({
|
|
|
145
145
|
"data-color-scheme": scheme,
|
|
146
146
|
"aria-label": label,
|
|
147
147
|
style: agentThemeStyle(theme, scheme),
|
|
148
|
-
children: entries.map((
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
TranscriptActivity,
|
|
152
|
-
{
|
|
153
|
-
activity: message,
|
|
154
|
-
formatTimestamp
|
|
155
|
-
},
|
|
156
|
-
message.id
|
|
157
|
-
);
|
|
158
|
-
if (message.role === "visitor" && !message.text.trim()) return null;
|
|
159
|
-
const date = new Date(message.createdAt);
|
|
148
|
+
children: entries.map((entry, index) => {
|
|
149
|
+
const date = new Date(entry.createdAt);
|
|
150
|
+
const previous = entries[index - 1];
|
|
160
151
|
const validTimestamp = Number.isFinite(date.getTime());
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
{
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
);
|
|
152
|
+
const showTimestamp = validTimestamp && (previous ? entry.createdAt - previous.createdAt >= 5 * 60 * 1e3 || date.toISOString().slice(0, 10) !== new Date(previous.createdAt).toJSON()?.slice(0, 10) : showInitialTimestamp);
|
|
153
|
+
return /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
154
|
+
showTimestamp ? /* @__PURE__ */ jsx2("li", { className: "agent-transcript__time-marker", children: /* @__PURE__ */ jsx2("time", { dateTime: date.toISOString(), children: formatTimestamp(entry.createdAt) }) }) : null,
|
|
155
|
+
entry.kind === "activity" ? /* @__PURE__ */ jsx2(TranscriptActivity, { activity: entry }) : /* @__PURE__ */ jsxs2(
|
|
156
|
+
"li",
|
|
157
|
+
{
|
|
158
|
+
className: `agent-transcript__message agent-transcript__message--${entry.role}`,
|
|
159
|
+
children: [
|
|
160
|
+
/* @__PURE__ */ jsx2("div", { className: "agent-transcript__meta", children: /* @__PURE__ */ jsx2("span", { children: entry.role === "visitor" ? visitorLabel : agentLabel }) }),
|
|
161
|
+
/* @__PURE__ */ jsx2(
|
|
162
|
+
MessageBubble,
|
|
163
|
+
{
|
|
164
|
+
message: entry.role === "agent" ? { ...entry, streaming: false } : entry,
|
|
165
|
+
bookingReadOnly: true,
|
|
166
|
+
bookingDisabled: true
|
|
167
|
+
}
|
|
168
|
+
)
|
|
169
|
+
]
|
|
170
|
+
}
|
|
171
|
+
)
|
|
172
|
+
] }, `${entry.kind}:${entry.id}`);
|
|
183
173
|
})
|
|
184
174
|
}
|
|
185
175
|
);
|
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react/components/AgentTranscript/TranscriptActivity.tsx","../src/react/components/AgentTranscript/group-activities.ts","../src/react/components/AgentTranscript/AgentTranscript.tsx"],"sourcesContent":["import type { ResolvedVisitorToolResultPresentation } from \"../../lib/tool-result\";\nimport { VisitorToolResultView } from \"../VisitorToolResultView/VisitorToolResultView\";\nimport { SearchReferences } from \"../SearchReferences/SearchReferences\";\nimport { BookingCard } from \"../BookingCard/BookingCard\";\n\nexport type AgentTranscriptActivity = {\n id: string;\n createdAt: number;\n callId: string;\n category: \"tool\" | \"specialist\";\n label: string;\n status: \"started\" | \"completed\" | \"failed\" | \"rejected\";\n result?: ResolvedVisitorToolResultPresentation;\n};\n\nconst statusLabels = {\n started: \"No result recorded\",\n completed: \"\",\n failed: \"Failed\",\n rejected: \"Rejected\",\n};\n\nfunction RecordedResult({\n result,\n}: {\n result: ResolvedVisitorToolResultPresentation;\n}) {\n if (result.kind === \"search\") return <SearchReferences results={[result]} />;\n if (result.kind === \"booking\") {\n const card = result.card;\n if (card.type === \"booking_offer\")\n return <BookingCard readOnly offer={card} />;\n if (card.type === \"booking_confirmed\")\n return (\n <p>Booking confirmed{card.startTime ? ` · ${card.startTime}` : \"\"}</p>\n );\n if (card.type === \"booking_canceled\") return <p>Booking canceled</p>;\n return <p>Information requested</p>;\n }\n return <VisitorToolResultView disabled result={result} />;\n}\n\nexport function TranscriptActivity({\n activity,\n formatTimestamp,\n}: {\n activity: AgentTranscriptActivity;\n formatTimestamp: (createdAt: number) => string;\n}) {\n const date = new Date(activity.createdAt);\n const validTimestamp = Number.isFinite(date.getTime());\n const result =\n activity.result?.kind === \"hidden\" ? undefined : activity.result;\n const heading = (\n <>\n <span>\n {activity.category === \"specialist\"\n ? `Specialist · ${activity.label}`\n : activity.label}\n </span>\n {activity.status !== \"completed\" ? (\n <span className=\"agent-transcript__activity-status\">\n {statusLabels[activity.status]}\n </span>\n ) : null}\n {validTimestamp ? (\n <time dateTime={date.toISOString()}>\n {formatTimestamp(activity.createdAt)}\n </time>\n ) : null}\n </>\n );\n return (\n <li className=\"agent-transcript__activity\" data-status={activity.status}>\n {result ? (\n <details>\n <summary className=\"agent-transcript__activity-heading\">\n {heading}\n </summary>\n <div className=\"agent-transcript__activity-result\">\n <RecordedResult result={result} />\n </div>\n </details>\n ) : (\n <div className=\"agent-transcript__activity-heading\">{heading}</div>\n )}\n </li>\n );\n}\n","import type { AgentTranscriptActivity } from \"./TranscriptActivity\";\n\n/** A paginated snapshot may deliver a call and its result on different pages. */\nexport function groupTranscriptActivities(\n activities: readonly AgentTranscriptActivity[],\n) {\n const calls = new Map<\n string,\n {\n latest: AgentTranscriptActivity;\n id: string;\n startedAt: number;\n label: string;\n }\n >();\n for (const activity of activities) {\n const key = `${activity.category}:${activity.callId}`;\n const previous = calls.get(key);\n if (!previous) {\n calls.set(key, {\n latest: activity,\n id: activity.id,\n startedAt: activity.createdAt,\n label: activity.label,\n });\n continue;\n }\n const previousHasResult = previous.latest.status !== \"started\";\n const nextHasResult = activity.status !== \"started\";\n const useNext =\n (nextHasResult && !previousHasResult) ||\n (nextHasResult === previousHasResult &&\n activity.createdAt >= previous.latest.createdAt);\n const latest = useNext ? activity : previous.latest;\n calls.set(key, {\n latest,\n id: previous.id,\n startedAt: Math.min(previous.startedAt, activity.createdAt),\n label:\n activity.createdAt < previous.startedAt\n ? activity.label\n : previous.label,\n });\n }\n return [...calls.values()].map(({ latest, id, startedAt, label }) => ({\n ...latest,\n id,\n label,\n createdAt: startedAt,\n }));\n}\n","import type {\n ConversationMessage,\n AgentColorScheme,\n AgentRailTheme,\n} from \"../../types/conversation\";\nimport { useAgentColorScheme } from \"../../hooks/useAgentColorScheme\";\nimport { agentThemeStyle } from \"../../lib/agent-theme\";\nimport { VisitorToolResultView } from \"../VisitorToolResultView/VisitorToolResultView\";\nimport { MessageBubble } from \"../MessageBubble/MessageBubble\";\nimport {\n TranscriptActivity,\n type AgentTranscriptActivity,\n} from \"./TranscriptActivity\";\nimport { groupTranscriptActivities } from \"./group-activities\";\nimport \"./AgentTranscript.css\";\n\nexport type { AgentTranscriptActivity } from \"./TranscriptActivity\";\n\nexport type AgentTranscriptProps = {\n messages: readonly ConversationMessage[];\n activities?: readonly AgentTranscriptActivity[];\n theme?: Partial<AgentRailTheme>;\n colorScheme?: AgentColorScheme;\n agentLabel?: string;\n visitorLabel?: string;\n label?: string;\n formatTimestamp?: (createdAt: number) => string;\n};\n\nconst timestampFormat = new Intl.DateTimeFormat(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n timeZone: \"UTC\",\n});\nfunction defaultTimestamp(createdAt: number) {\n return `${timestampFormat.format(createdAt)} UTC`;\n}\n\n/** Renders a stored snapshot; never creates a session or exposes chat actions. */\nexport function AgentTranscript({\n messages,\n activities = [],\n theme,\n colorScheme,\n agentLabel = \"Agent\",\n visitorLabel = \"Visitor\",\n label = \"Conversation transcript\",\n formatTimestamp = defaultTimestamp,\n}: AgentTranscriptProps) {\n const scheme = useAgentColorScheme(colorScheme);\n const entries = [\n ...messages.map((message) => ({ kind: \"message\" as const, ...message })),\n ...groupTranscriptActivities(activities).map((activity) => ({\n kind: \"activity\" as const,\n ...activity,\n })),\n ].sort((left, right) => left.createdAt - right.createdAt);\n return (\n <ol\n className=\"webless-agent-root agent-transcript not-typeset\"\n data-not-typeset=\"\"\n data-color-scheme={scheme}\n aria-label={label}\n style={agentThemeStyle(theme, scheme)}\n >\n {entries.map((message) => {\n if (message.kind === \"activity\")\n return (\n <TranscriptActivity\n key={message.id}\n activity={message}\n formatTimestamp={formatTimestamp}\n />\n );\n if (message.role === \"visitor\" && !message.text.trim()) return null;\n const date = new Date(message.createdAt);\n const validTimestamp = Number.isFinite(date.getTime());\n return (\n <li\n key={message.id}\n className={`agent-transcript__message agent-transcript__message--${message.role}`}\n >\n <div className=\"agent-transcript__meta\">\n <span>\n {message.role === \"visitor\" ? visitorLabel : agentLabel}\n </span>\n {validTimestamp ? (\n <time dateTime={date.toISOString()}>\n {formatTimestamp(message.createdAt)}\n </time>\n ) : null}\n </div>\n {message.role === \"agent\" ? message.toolResults?.map((result) => (\n <VisitorToolResultView key={result.id} result={result} />\n )) : null}\n <MessageBubble\n message={\n message.role === \"agent\"\n ? { ...message, streaming: false }\n : message\n }\n bookingReadOnly\n bookingDisabled\n />\n </li>\n );\n })}\n </ol>\n );\n}\n"],"mappings":"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","names":["jsx","jsxs"]}
|
|
1
|
+
{"version":3,"sources":["../src/react/components/AgentTranscript/AgentTranscript.tsx","../src/react/components/AgentTranscript/TranscriptActivity.tsx","../src/react/components/AgentTranscript/group-activities.ts"],"sourcesContent":["import { Fragment } from \"react\";\nimport type {\n ConversationMessage,\n AgentColorScheme,\n AgentRailTheme,\n} from \"../../types/conversation\";\nimport { useAgentColorScheme } from \"../../hooks/useAgentColorScheme\";\nimport { agentThemeStyle } from \"../../lib/agent-theme\";\nimport { VisitorToolResultView } from \"../VisitorToolResultView/VisitorToolResultView\";\nimport { MessageBubble } from \"../MessageBubble/MessageBubble\";\nimport {\n TranscriptActivity,\n type AgentTranscriptActivity,\n} from \"./TranscriptActivity\";\nimport { groupTranscriptActivities } from \"./group-activities\";\nimport \"./AgentTranscript.css\";\n\nexport type { AgentTranscriptActivity } from \"./TranscriptActivity\";\n\nexport type AgentTranscriptProps = {\n messages: readonly ConversationMessage[];\n activities?: readonly AgentTranscriptActivity[];\n theme?: Partial<AgentRailTheme>;\n colorScheme?: AgentColorScheme;\n agentLabel?: string;\n visitorLabel?: string;\n label?: string;\n /** Hide the opening marker when the host already shows the conversation date. */\n showInitialTimestamp?: boolean;\n formatTimestamp?: (createdAt: number) => string;\n};\n\nconst timestampFormat = new Intl.DateTimeFormat(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n timeZone: \"UTC\",\n});\nfunction defaultTimestamp(createdAt: number) {\n return `${timestampFormat.format(createdAt)} UTC`;\n}\n\n/** Renders a stored snapshot; never creates a session or exposes chat actions. */\nexport function AgentTranscript({\n messages,\n activities = [],\n theme,\n colorScheme,\n agentLabel = \"Agent\",\n visitorLabel = \"Visitor\",\n label = \"Conversation transcript\",\n formatTimestamp = defaultTimestamp,\n showInitialTimestamp = true,\n}: AgentTranscriptProps) {\n const scheme = useAgentColorScheme(colorScheme);\n const entries = [\n ...messages.map((message) => ({ kind: \"message\" as const, ...message })),\n ...groupTranscriptActivities(activities).map((activity) => ({\n kind: \"activity\" as const,\n ...activity,\n })),\n ].sort((left, right) => left.createdAt - right.createdAt);\n return (\n <ol\n className=\"webless-agent-root agent-transcript not-typeset\"\n data-not-typeset=\"\"\n data-color-scheme={scheme}\n aria-label={label}\n style={agentThemeStyle(theme, scheme)}\n >\n {entries.map((entry, index) => {\n const date = new Date(entry.createdAt);\n const previous = entries[index - 1];\n const validTimestamp = Number.isFinite(date.getTime());\n const showTimestamp =\n validTimestamp &&\n (previous\n ? entry.createdAt - previous.createdAt >= 5 * 60 * 1000 ||\n date.toISOString().slice(0, 10) !==\n new Date(previous.createdAt).toJSON()?.slice(0, 10)\n : showInitialTimestamp);\n return (\n <Fragment key={`${entry.kind}:${entry.id}`}>\n {showTimestamp ? (\n <li className=\"agent-transcript__time-marker\">\n <time dateTime={date.toISOString()}>\n {formatTimestamp(entry.createdAt)}\n </time>\n </li>\n ) : null}\n {entry.kind === \"activity\" ? (\n <TranscriptActivity activity={entry} />\n ) : (\n <li\n className={`agent-transcript__message agent-transcript__message--${entry.role}`}\n >\n <div className=\"agent-transcript__meta\">\n <span>\n {entry.role === \"visitor\" ? visitorLabel : agentLabel}\n </span>\n </div>\n <MessageBubble\n message={\n entry.role === \"agent\"\n ? { ...entry, streaming: false }\n : entry\n }\n bookingReadOnly\n bookingDisabled\n />\n </li>\n )}\n </Fragment>\n );\n })}\n </ol>\n );\n}\n","import type { ResolvedVisitorToolResultPresentation } from \"../../lib/tool-result\";\nimport { VisitorToolResultView } from \"../VisitorToolResultView/VisitorToolResultView\";\nimport { SearchReferences } from \"../SearchReferences/SearchReferences\";\nimport { BookingCard } from \"../BookingCard/BookingCard\";\n\nexport type AgentTranscriptActivity = {\n id: string;\n createdAt: number;\n callId: string;\n category: \"tool\" | \"specialist\";\n label: string;\n status: \"started\" | \"completed\" | \"failed\" | \"rejected\";\n result?: ResolvedVisitorToolResultPresentation;\n};\n\nconst statusLabels = {\n started: \"No result recorded\",\n completed: \"\",\n failed: \"Failed\",\n rejected: \"Rejected\",\n};\n\nfunction RecordedResult({\n result,\n}: {\n result: ResolvedVisitorToolResultPresentation;\n}) {\n if (result.kind === \"search\") return <SearchReferences results={[result]} />;\n if (result.kind === \"booking\") {\n const card = result.card;\n if (card.type === \"booking_offer\")\n return <BookingCard readOnly offer={card} />;\n if (card.type === \"booking_confirmed\")\n return (\n <p>Booking confirmed{card.startTime ? ` · ${card.startTime}` : \"\"}</p>\n );\n if (card.type === \"booking_canceled\") return <p>Booking canceled</p>;\n return <p>Information requested</p>;\n }\n return <VisitorToolResultView disabled result={result} />;\n}\n\nexport function TranscriptActivity({\n activity,\n}: {\n activity: AgentTranscriptActivity;\n}) {\n const result =\n activity.result?.kind === \"hidden\" ? undefined : activity.result;\n const heading = (\n <>\n <span>\n {activity.category === \"specialist\"\n ? `Specialist · ${activity.label}`\n : activity.label}\n </span>\n {activity.status !== \"completed\" ? (\n <span className=\"agent-transcript__activity-status\">\n {statusLabels[activity.status]}\n </span>\n ) : null}\n </>\n );\n return (\n <li className=\"agent-transcript__activity\" data-status={activity.status}>\n {result ? (\n <details>\n <summary className=\"agent-transcript__activity-heading\">\n {heading}\n </summary>\n <div className=\"agent-transcript__activity-result\">\n <RecordedResult result={result} />\n </div>\n </details>\n ) : (\n <div className=\"agent-transcript__activity-heading\">{heading}</div>\n )}\n </li>\n );\n}\n","import type { AgentTranscriptActivity } from \"./TranscriptActivity\";\n\n/** A paginated snapshot may deliver a call and its result on different pages. */\nexport function groupTranscriptActivities(\n activities: readonly AgentTranscriptActivity[],\n) {\n const calls = new Map<\n string,\n {\n latest: AgentTranscriptActivity;\n id: string;\n startedAt: number;\n label: string;\n }\n >();\n for (const activity of activities) {\n const key = `${activity.category}:${activity.callId}`;\n const previous = calls.get(key);\n if (!previous) {\n calls.set(key, {\n latest: activity,\n id: activity.id,\n startedAt: activity.createdAt,\n label: activity.label,\n });\n continue;\n }\n const previousHasResult = previous.latest.status !== \"started\";\n const nextHasResult = activity.status !== \"started\";\n const useNext =\n (nextHasResult && !previousHasResult) ||\n (nextHasResult === previousHasResult &&\n activity.createdAt >= previous.latest.createdAt);\n const latest = useNext ? activity : previous.latest;\n calls.set(key, {\n latest,\n id: previous.id,\n startedAt: Math.min(previous.startedAt, activity.createdAt),\n label:\n activity.createdAt < previous.startedAt\n ? activity.label\n : previous.label,\n });\n }\n return [...calls.values()].map(({ latest, id, startedAt, label }) => ({\n ...latest,\n id,\n label,\n createdAt: startedAt,\n }));\n}\n"],"mappings":"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","names":["Fragment","jsx","jsxs","Fragment"]}
|