@agent-native/toolkit 0.214.0 → 0.216.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/agentkit/react/chat.d.ts.map +1 -1
- package/dist/app/agentkit/react/chat.js +2 -2
- package/dist/app/agentkit/react/chat.js.map +1 -1
- package/dist/app/agentkit/react/components.d.ts +4 -1
- package/dist/app/agentkit/react/components.d.ts.map +1 -1
- package/dist/app/agentkit/react/components.js +69 -15
- package/dist/app/agentkit/react/components.js.map +1 -1
- package/dist/app/agentkit/react/context.d.ts +7 -1
- package/dist/app/agentkit/react/context.d.ts.map +1 -1
- package/dist/app/agentkit/react/context.js +5 -1
- package/dist/app/agentkit/react/context.js.map +1 -1
- package/dist/app/agentkit/react/index.d.ts +1 -0
- package/dist/app/agentkit/react/index.d.ts.map +1 -1
- package/dist/app/agentkit/react/index.js +1 -0
- package/dist/app/agentkit/react/index.js.map +1 -1
- package/dist/app/agentkit/react/root.d.ts +4 -1
- package/dist/app/agentkit/react/root.d.ts.map +1 -1
- package/dist/app/agentkit/react/root.js +2 -2
- package/dist/app/agentkit/react/root.js.map +1 -1
- package/dist/app/agentkit/react/styles.css +43 -6
- package/dist/app/agentkit/react/transcript-layout.d.ts +51 -0
- package/dist/app/agentkit/react/transcript-layout.d.ts.map +1 -0
- package/dist/app/agentkit/react/transcript-layout.js +34 -0
- package/dist/app/agentkit/react/transcript-layout.js.map +1 -0
- package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.js +3 -3
- package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
- package/dist/app/chat/AgentPanel.d.ts +2 -0
- package/dist/app/chat/AgentPanel.d.ts.map +1 -1
- package/dist/app/chat/AgentPanel.js +6 -2
- package/dist/app/chat/AgentPanel.js.map +1 -1
- package/dist/app/chat/chat/index.d.ts +2 -0
- package/dist/app/chat/chat/index.d.ts.map +1 -1
- package/dist/app/chat/chat/index.js.map +1 -1
- package/dist/app/chat/chat/surface-types.d.ts +7 -0
- package/dist/app/chat/chat/surface-types.d.ts.map +1 -1
- package/dist/app/chat/chat/surface-types.js.map +1 -1
- package/dist/app/chat/chat/tool-call-display.d.ts +7 -2
- package/dist/app/chat/chat/tool-call-display.d.ts.map +1 -1
- package/dist/app/chat/chat/tool-call-display.js +10 -9
- package/dist/app/chat/chat/tool-call-display.js.map +1 -1
- package/dist/app/chat/chat/widgets/DataChartRenderer.d.ts.map +1 -1
- package/dist/app/chat/chat/widgets/DataChartRenderer.js +196 -26
- package/dist/app/chat/chat/widgets/DataChartRenderer.js.map +1 -1
- package/dist/app/chat/chat/widgets/DataChartWidget.d.ts.map +1 -1
- package/dist/app/chat/chat/widgets/DataChartWidget.js +5 -1
- package/dist/app/chat/chat/widgets/DataChartWidget.js.map +1 -1
- package/dist/app/chat/chat/widgets/DataWidgetDisplayControls.d.ts +2 -2
- package/dist/app/chat/chat/widgets/DataWidgetDisplayControls.d.ts.map +1 -1
- package/dist/app/chat/chat/widgets/DataWidgetDisplayControls.js +6 -4
- package/dist/app/chat/chat/widgets/DataWidgetDisplayControls.js.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.js +1 -0
- package/dist/app/i18n/catalogs/ar-SA.js.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.js +1 -0
- package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
- package/dist/app/i18n/catalogs/en-US.d.ts +1 -0
- package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/en-US.js +1 -0
- package/dist/app/i18n/catalogs/en-US.js.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.js +1 -0
- package/dist/app/i18n/catalogs/es-ES.js.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.js +1 -0
- package/dist/app/i18n/catalogs/fr-FR.js.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.js +1 -0
- package/dist/app/i18n/catalogs/hi-IN.js.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.js +1 -0
- package/dist/app/i18n/catalogs/ja-JP.js.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.js +1 -0
- package/dist/app/i18n/catalogs/ko-KR.js.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.js +1 -0
- package/dist/app/i18n/catalogs/pt-BR.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.js +1 -0
- package/dist/app/i18n/catalogs/zh-CN.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.js +1 -0
- package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
- package/dist/composer/ComposerContextBanner.d.ts +3 -1
- package/dist/composer/ComposerContextBanner.d.ts.map +1 -1
- package/dist/composer/ComposerContextBanner.js +2 -2
- package/dist/composer/ComposerContextBanner.js.map +1 -1
- package/package.json +3 -3
- package/src/app/agentkit/react/chat.tsx +2 -0
- package/src/app/agentkit/react/components.interaction.spec.tsx +107 -0
- package/src/app/agentkit/react/components.spec.tsx +28 -1
- package/src/app/agentkit/react/components.tsx +153 -17
- package/src/app/agentkit/react/context.tsx +12 -0
- package/src/app/agentkit/react/index.ts +1 -0
- package/src/app/agentkit/react/lifecycle.spec.tsx +186 -16
- package/src/app/agentkit/react/root.tsx +7 -0
- package/src/app/agentkit/react/styles.css +43 -6
- package/src/app/agentkit/react/transcript-layout.spec.ts +72 -0
- package/src/app/agentkit/react/transcript-layout.ts +97 -0
- package/src/app/auth/AuthPage.attribution.spec.tsx +6 -0
- package/src/app/chat/AgentKitAssistantChat.spec.tsx +39 -0
- package/src/app/chat/AgentKitAssistantChat.tsx +5 -0
- package/src/app/chat/AgentPanel.page-header-share.spec.tsx +101 -0
- package/src/app/chat/AgentPanel.tsx +14 -2
- package/src/app/chat/chat/index.ts +2 -0
- package/src/app/chat/chat/surface-types.ts +10 -0
- package/src/app/chat/chat/tool-call-display.spec.tsx +83 -0
- package/src/app/chat/chat/tool-call-display.tsx +40 -8
- package/src/app/chat/chat/widgets/DataChartRenderer.spec.tsx +632 -0
- package/src/app/chat/chat/widgets/DataChartRenderer.tsx +308 -51
- package/src/app/chat/chat/widgets/DataChartWidget.spec.tsx +126 -23
- package/src/app/chat/chat/widgets/DataChartWidget.tsx +10 -0
- package/src/app/chat/chat/widgets/DataWidgetDisplayControls.tsx +26 -6
- package/src/app/i18n/catalogs/ar-SA.ts +1 -0
- package/src/app/i18n/catalogs/de-DE.ts +2 -0
- package/src/app/i18n/catalogs/en-US.ts +2 -0
- package/src/app/i18n/catalogs/es-ES.ts +2 -0
- package/src/app/i18n/catalogs/fr-FR.ts +2 -0
- package/src/app/i18n/catalogs/hi-IN.ts +1 -0
- package/src/app/i18n/catalogs/ja-JP.ts +2 -0
- package/src/app/i18n/catalogs/ko-KR.ts +1 -0
- package/src/app/i18n/catalogs/pt-BR.ts +2 -0
- package/src/app/i18n/catalogs/zh-CN.ts +1 -0
- package/src/app/i18n/catalogs/zh-TW.ts +1 -0
- package/src/composer/ComposerContextBanner.spec.tsx +31 -5
- package/src/composer/ComposerContextBanner.tsx +7 -2
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
import {
|
|
41
41
|
createContext,
|
|
42
42
|
Component,
|
|
43
|
+
Fragment,
|
|
43
44
|
memo,
|
|
44
45
|
useCallback,
|
|
45
46
|
useContext,
|
|
@@ -49,6 +50,7 @@ import {
|
|
|
49
50
|
useRef,
|
|
50
51
|
useState,
|
|
51
52
|
type ComponentType,
|
|
53
|
+
type CSSProperties,
|
|
52
54
|
type ErrorInfo,
|
|
53
55
|
type KeyboardEvent as ReactKeyboardEvent,
|
|
54
56
|
type PointerEvent as ReactPointerEvent,
|
|
@@ -138,6 +140,11 @@ import {
|
|
|
138
140
|
} from "./context.js";
|
|
139
141
|
import { orderMessageContent } from "./message-content-order.js";
|
|
140
142
|
import { AgentStreamingText } from "./streaming-text.js";
|
|
143
|
+
import {
|
|
144
|
+
workedForRowChevronStyle,
|
|
145
|
+
workedForRowSummaryStyle,
|
|
146
|
+
type AgentChatTranscriptLayout,
|
|
147
|
+
} from "./transcript-layout.js";
|
|
141
148
|
|
|
142
149
|
// AgentKit React installs without @agent-native/core, so it repeats core's
|
|
143
150
|
// replay markers. Its specs assert core's attribute names.
|
|
@@ -1465,7 +1472,8 @@ export function AgentActivityGroup({
|
|
|
1465
1472
|
excludeAgentActivities?: boolean;
|
|
1466
1473
|
isCurrentSegment?: boolean;
|
|
1467
1474
|
}) {
|
|
1468
|
-
const { threadId, slots, registry, labels } =
|
|
1475
|
+
const { threadId, slots, registry, labels, formatWorkedForDuration } =
|
|
1476
|
+
useAgentKit();
|
|
1469
1477
|
const thread = useAgentThread();
|
|
1470
1478
|
const runEvents = runId
|
|
1471
1479
|
? thread.events.filter((event) => event.runId === runId)
|
|
@@ -1762,6 +1770,7 @@ export function AgentActivityGroup({
|
|
|
1762
1770
|
}
|
|
1763
1771
|
const hasExpandableActivity = displayGroups.length > 0;
|
|
1764
1772
|
const formatDuration = (ms: number) =>
|
|
1773
|
+
formatWorkedForDuration?.(ms) ??
|
|
1765
1774
|
formatAgentKitDuration(ms, {
|
|
1766
1775
|
hour: labels.durationHourShort,
|
|
1767
1776
|
minute: labels.durationMinuteShort,
|
|
@@ -1908,7 +1917,7 @@ function AgentWorkDisclosure({
|
|
|
1908
1917
|
current?: ReactNode;
|
|
1909
1918
|
children: ReactNode;
|
|
1910
1919
|
}) {
|
|
1911
|
-
const { slots } = useAgentKit();
|
|
1920
|
+
const { slots, workedForRowLayout } = useAgentKit();
|
|
1912
1921
|
const [open, setOpen] = useState(false);
|
|
1913
1922
|
const Summary = slots.workedForSummary;
|
|
1914
1923
|
return (
|
|
@@ -1921,6 +1930,7 @@ function AgentWorkDisclosure({
|
|
|
1921
1930
|
<summary
|
|
1922
1931
|
className="agentkit-activities-summary"
|
|
1923
1932
|
aria-disabled={!expandable}
|
|
1933
|
+
style={workedForRowSummaryStyle(workedForRowLayout)}
|
|
1924
1934
|
onClick={(event) => {
|
|
1925
1935
|
event.preventDefault();
|
|
1926
1936
|
if (!expandable) return;
|
|
@@ -1934,12 +1944,14 @@ function AgentWorkDisclosure({
|
|
|
1934
1944
|
expandable={expandable}
|
|
1935
1945
|
open={open}
|
|
1936
1946
|
current={current}
|
|
1947
|
+
layout={workedForRowLayout}
|
|
1937
1948
|
/>
|
|
1938
1949
|
) : (
|
|
1939
1950
|
<>
|
|
1940
1951
|
<IconChevronRight
|
|
1941
1952
|
aria-hidden="true"
|
|
1942
1953
|
className="agentkit-icon agentkit-summary-chevron"
|
|
1954
|
+
style={workedForRowChevronStyle(workedForRowLayout)}
|
|
1943
1955
|
/>
|
|
1944
1956
|
<span className="agentkit-activities-summary-content">
|
|
1945
1957
|
{label ? (
|
|
@@ -3798,11 +3810,15 @@ export function AgentMessageActions({
|
|
|
3798
3810
|
);
|
|
3799
3811
|
}
|
|
3800
3812
|
|
|
3813
|
+
const AgentKitPostWidgetTextContext =
|
|
3814
|
+
createContext<AgentChatTranscriptLayout["postWidgetText"]>(undefined);
|
|
3815
|
+
|
|
3801
3816
|
export function AgentMessageView({
|
|
3802
3817
|
value: message,
|
|
3803
3818
|
threadId,
|
|
3804
3819
|
}: AgentKitRenderProps<AgentMessage>) {
|
|
3805
3820
|
const { labels, slots, resolveMessageContentOrder } = useAgentKit();
|
|
3821
|
+
const postWidgetText = useContext(AgentKitPostWidgetTextContext);
|
|
3806
3822
|
const thread = useAgentThread(threadId);
|
|
3807
3823
|
const visibleMessage = stripAgentMessageContext(message);
|
|
3808
3824
|
const Supplement = slots.messageSupplement;
|
|
@@ -3843,6 +3859,7 @@ export function AgentMessageView({
|
|
|
3843
3859
|
<Supplement value={visibleMessage} threadId={threadId} />
|
|
3844
3860
|
) : null;
|
|
3845
3861
|
}
|
|
3862
|
+
let hasSeenWidget = false;
|
|
3846
3863
|
return (
|
|
3847
3864
|
<article
|
|
3848
3865
|
className="agentkit-message"
|
|
@@ -3852,20 +3869,39 @@ export function AgentMessageView({
|
|
|
3852
3869
|
aria-busy={message.status === "streaming"}
|
|
3853
3870
|
>
|
|
3854
3871
|
<div className="agentkit-message-content">
|
|
3855
|
-
{orderedContent.map((item, index) =>
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3872
|
+
{orderedContent.map((item, index) => {
|
|
3873
|
+
const isWidget =
|
|
3874
|
+
item.type === "widget" ||
|
|
3875
|
+
(item.type === "part" && item.part.type === "widget");
|
|
3876
|
+
const followsWidget =
|
|
3877
|
+
message.role === "assistant" &&
|
|
3878
|
+
postWidgetText !== undefined &&
|
|
3879
|
+
hasSeenWidget &&
|
|
3880
|
+
item.type === "part" &&
|
|
3881
|
+
item.part.type === "text";
|
|
3882
|
+
if (isWidget) hasSeenWidget = true;
|
|
3883
|
+
const content = (
|
|
3884
|
+
<AgentMessagePartView
|
|
3885
|
+
value={
|
|
3886
|
+
item.type === "widget"
|
|
3887
|
+
? { type: "widget", widget: item.widget }
|
|
3888
|
+
: item.part
|
|
3889
|
+
}
|
|
3890
|
+
threadId={threadId}
|
|
3891
|
+
active={message.status === "streaming"}
|
|
3892
|
+
resetKey={`${threadId}:${message.id}:${index}`}
|
|
3893
|
+
userMessage={message.role === "user"}
|
|
3894
|
+
/>
|
|
3895
|
+
);
|
|
3896
|
+
|
|
3897
|
+
return followsWidget ? (
|
|
3898
|
+
<div key={item.key} data-post-widget-text="true">
|
|
3899
|
+
{content}
|
|
3900
|
+
</div>
|
|
3901
|
+
) : (
|
|
3902
|
+
<Fragment key={item.key}>{content}</Fragment>
|
|
3903
|
+
);
|
|
3904
|
+
})}
|
|
3869
3905
|
{attachedAnnotations.length ? (
|
|
3870
3906
|
<div className="agentkit-annotations">
|
|
3871
3907
|
{attachedAnnotations.map((annotation) => (
|
|
@@ -4800,9 +4836,103 @@ export interface AgentKitChatProps {
|
|
|
4800
4836
|
emptyComposerPlacement?: "center" | "bottom";
|
|
4801
4837
|
/** Follow new output until the user deliberately scrolls away. */
|
|
4802
4838
|
autoScroll?: boolean;
|
|
4839
|
+
/** Optional transcript geometry. Omitted values keep the shared defaults. */
|
|
4840
|
+
transcriptLayout?: AgentChatTranscriptLayout;
|
|
4803
4841
|
className?: string;
|
|
4804
4842
|
}
|
|
4805
4843
|
|
|
4844
|
+
type AgentKitTranscriptContentStyle = CSSProperties & {
|
|
4845
|
+
"--agentkit-transcript-top-inset"?: string;
|
|
4846
|
+
"--agentkit-transcript-lane-width"?: string;
|
|
4847
|
+
"--agentkit-transcript-lane-offset-inline"?: string;
|
|
4848
|
+
"--agentkit-transcript-message-gap"?: string;
|
|
4849
|
+
"--agentkit-transcript-message-line-height"?: string;
|
|
4850
|
+
"--agentkit-transcript-font-family"?: string;
|
|
4851
|
+
"--agentkit-transcript-post-widget-text-color"?: string;
|
|
4852
|
+
"--agentkit-transcript-post-widget-paragraph-padding-block"?: string;
|
|
4853
|
+
"--agentkit-user-bubble-line-height"?: string;
|
|
4854
|
+
"--agentkit-user-bubble-max-width"?: string;
|
|
4855
|
+
"--agentkit-user-bubble-offset-inline"?: string;
|
|
4856
|
+
"--agentkit-user-bubble-padding-block"?: string;
|
|
4857
|
+
"--agentkit-user-bubble-padding-inline"?: string;
|
|
4858
|
+
};
|
|
4859
|
+
|
|
4860
|
+
function transcriptLength(value: number | undefined, name: string) {
|
|
4861
|
+
if (value === undefined) return undefined;
|
|
4862
|
+
if (!Number.isFinite(value) || value < 0) {
|
|
4863
|
+
throw new RangeError(
|
|
4864
|
+
`transcriptLayout.${name} must be a non-negative number`,
|
|
4865
|
+
);
|
|
4866
|
+
}
|
|
4867
|
+
return `${value}px`;
|
|
4868
|
+
}
|
|
4869
|
+
|
|
4870
|
+
function transcriptOffset(value: number | undefined, name: string) {
|
|
4871
|
+
if (value === undefined) return undefined;
|
|
4872
|
+
if (!Number.isFinite(value)) {
|
|
4873
|
+
throw new RangeError(`transcriptLayout.${name} must be a finite number`);
|
|
4874
|
+
}
|
|
4875
|
+
return `${value}px`;
|
|
4876
|
+
}
|
|
4877
|
+
|
|
4878
|
+
function transcriptContentStyle(
|
|
4879
|
+
layout?: AgentChatTranscriptLayout,
|
|
4880
|
+
): AgentKitTranscriptContentStyle | undefined {
|
|
4881
|
+
if (!layout) return undefined;
|
|
4882
|
+
return {
|
|
4883
|
+
"--agentkit-transcript-top-inset": transcriptLength(
|
|
4884
|
+
layout.topInset,
|
|
4885
|
+
"topInset",
|
|
4886
|
+
),
|
|
4887
|
+
"--agentkit-transcript-lane-width": transcriptLength(
|
|
4888
|
+
layout.messageLaneWidth,
|
|
4889
|
+
"messageLaneWidth",
|
|
4890
|
+
),
|
|
4891
|
+
"--agentkit-transcript-lane-offset-inline": transcriptOffset(
|
|
4892
|
+
layout.messageLaneOffsetInline,
|
|
4893
|
+
"messageLaneOffsetInline",
|
|
4894
|
+
),
|
|
4895
|
+
"--agentkit-transcript-message-gap": transcriptLength(
|
|
4896
|
+
layout.messageGap,
|
|
4897
|
+
"messageGap",
|
|
4898
|
+
),
|
|
4899
|
+
"--agentkit-transcript-message-line-height": transcriptLength(
|
|
4900
|
+
layout.messageLineHeight,
|
|
4901
|
+
"messageLineHeight",
|
|
4902
|
+
),
|
|
4903
|
+
"--agentkit-transcript-font-family": layout.fontFamily,
|
|
4904
|
+
"--agentkit-transcript-post-widget-text-color":
|
|
4905
|
+
layout.postWidgetText?.tone === "muted"
|
|
4906
|
+
? "var(--agentkit-text-muted)"
|
|
4907
|
+
: undefined,
|
|
4908
|
+
"--agentkit-transcript-post-widget-paragraph-padding-block":
|
|
4909
|
+
transcriptLength(
|
|
4910
|
+
layout.postWidgetText?.paragraphPaddingBlock,
|
|
4911
|
+
"postWidgetText.paragraphPaddingBlock",
|
|
4912
|
+
),
|
|
4913
|
+
"--agentkit-user-bubble-line-height": transcriptLength(
|
|
4914
|
+
layout.userBubbleLineHeight,
|
|
4915
|
+
"userBubbleLineHeight",
|
|
4916
|
+
),
|
|
4917
|
+
"--agentkit-user-bubble-max-width": transcriptLength(
|
|
4918
|
+
layout.userBubbleMaxWidth,
|
|
4919
|
+
"userBubbleMaxWidth",
|
|
4920
|
+
),
|
|
4921
|
+
"--agentkit-user-bubble-offset-inline": transcriptOffset(
|
|
4922
|
+
layout.userBubbleOffsetInline,
|
|
4923
|
+
"userBubbleOffsetInline",
|
|
4924
|
+
),
|
|
4925
|
+
"--agentkit-user-bubble-padding-block": transcriptLength(
|
|
4926
|
+
layout.userBubblePadding?.block,
|
|
4927
|
+
"userBubblePadding.block",
|
|
4928
|
+
),
|
|
4929
|
+
"--agentkit-user-bubble-padding-inline": transcriptLength(
|
|
4930
|
+
layout.userBubblePadding?.inline,
|
|
4931
|
+
"userBubblePadding.inline",
|
|
4932
|
+
),
|
|
4933
|
+
};
|
|
4934
|
+
}
|
|
4935
|
+
|
|
4806
4936
|
const AGENTKIT_TRANSCRIPT_BOTTOM_THRESHOLD = 24;
|
|
4807
4937
|
const AGENTKIT_TRANSCRIPT_SCROLLBAR_IDLE_MS = 900;
|
|
4808
4938
|
const AGENTKIT_TRANSCRIPT_SCROLL_KEYS = new Set([
|
|
@@ -4832,6 +4962,7 @@ export function AgentKitChat({
|
|
|
4832
4962
|
hasRenderedMessages = false,
|
|
4833
4963
|
emptyComposerPlacement = "center",
|
|
4834
4964
|
autoScroll = true,
|
|
4965
|
+
transcriptLayout,
|
|
4835
4966
|
className,
|
|
4836
4967
|
}: AgentKitChatProps) {
|
|
4837
4968
|
const { threadId, slots, registry, labels, onThreadForked } = useAgentKit();
|
|
@@ -5582,12 +5713,17 @@ export function AgentKitChat({
|
|
|
5582
5713
|
<div
|
|
5583
5714
|
ref={transcriptContentRef}
|
|
5584
5715
|
className="agentkit-transcript-content"
|
|
5716
|
+
style={transcriptContentStyle(transcriptLayout)}
|
|
5585
5717
|
>
|
|
5586
5718
|
<AgentKitRegionSlot slot={Transcript} threadId={threadId}>
|
|
5587
5719
|
{!hasConversation && EmptyState ? (
|
|
5588
5720
|
<EmptyState threadId={threadId} />
|
|
5589
5721
|
) : null}
|
|
5590
|
-
|
|
5722
|
+
<AgentKitPostWidgetTextContext.Provider
|
|
5723
|
+
value={transcriptLayout?.postWidgetText}
|
|
5724
|
+
>
|
|
5725
|
+
{transcriptItems}
|
|
5726
|
+
</AgentKitPostWidgetTextContext.Provider>
|
|
5591
5727
|
{approvalEntries.map(([approvalId, request]) => (
|
|
5592
5728
|
<AgentKitSurfaceBoundary
|
|
5593
5729
|
key={`${threadId}:${approvalId}`}
|
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
} from "react";
|
|
45
45
|
|
|
46
46
|
import type { AgentMessageContentOrderResolver } from "./message-content-order.js";
|
|
47
|
+
import type { AgentChatWorkedForRowLayout } from "./transcript-layout.js";
|
|
47
48
|
|
|
48
49
|
export interface AgentKitRenderProps<T> {
|
|
49
50
|
value: T;
|
|
@@ -87,6 +88,7 @@ export interface AgentKitWorkedForSummaryRenderProps {
|
|
|
87
88
|
expandable: boolean;
|
|
88
89
|
open: boolean;
|
|
89
90
|
current?: ReactNode;
|
|
91
|
+
layout?: AgentChatWorkedForRowLayout;
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
export interface AgentConnectionErrorRenderProps {
|
|
@@ -495,6 +497,8 @@ export interface AgentKitProviderProps {
|
|
|
495
497
|
/** Receives full renderer failures while the UI shows a safe fallback. */
|
|
496
498
|
onRenderError?: (failure: AgentKitRenderFailure) => void;
|
|
497
499
|
resolveMessageContentOrder?: AgentMessageContentOrderResolver;
|
|
500
|
+
workedForRowLayout?: AgentChatWorkedForRowLayout;
|
|
501
|
+
formatWorkedForDuration?: (durationMs: number) => string;
|
|
498
502
|
onClientEffect?: (effect: {
|
|
499
503
|
type: "client.effect" | "client.deeplink";
|
|
500
504
|
name: string;
|
|
@@ -525,6 +529,8 @@ export interface AgentKitContextValue {
|
|
|
525
529
|
onConnectionRequest?: AgentKitProviderProps["onConnectionRequest"];
|
|
526
530
|
onRenderError?: (failure: AgentKitRenderFailure) => void;
|
|
527
531
|
resolveMessageContentOrder?: AgentMessageContentOrderResolver;
|
|
532
|
+
workedForRowLayout?: AgentChatWorkedForRowLayout;
|
|
533
|
+
formatWorkedForDuration?: (durationMs: number) => string;
|
|
528
534
|
registerComposerFocus: (threadId: ThreadId, focus: () => void) => () => void;
|
|
529
535
|
requestComposerFocus: (threadId: ThreadId) => void;
|
|
530
536
|
}
|
|
@@ -546,6 +552,8 @@ export function AgentKitProvider({
|
|
|
546
552
|
onConnectionRequest,
|
|
547
553
|
onRenderError,
|
|
548
554
|
resolveMessageContentOrder,
|
|
555
|
+
workedForRowLayout,
|
|
556
|
+
formatWorkedForDuration,
|
|
549
557
|
onClientEffect,
|
|
550
558
|
children,
|
|
551
559
|
}: AgentKitProviderProps) {
|
|
@@ -613,6 +621,8 @@ export function AgentKitProvider({
|
|
|
613
621
|
onConnectionRequest,
|
|
614
622
|
onRenderError,
|
|
615
623
|
resolveMessageContentOrder,
|
|
624
|
+
workedForRowLayout,
|
|
625
|
+
formatWorkedForDuration,
|
|
616
626
|
registerComposerFocus,
|
|
617
627
|
requestComposerFocus,
|
|
618
628
|
}),
|
|
@@ -631,6 +641,8 @@ export function AgentKitProvider({
|
|
|
631
641
|
onConnectionRequest,
|
|
632
642
|
onRenderError,
|
|
633
643
|
resolveMessageContentOrder,
|
|
644
|
+
workedForRowLayout,
|
|
645
|
+
formatWorkedForDuration,
|
|
634
646
|
registerComposerFocus,
|
|
635
647
|
requestComposerFocus,
|
|
636
648
|
],
|
|
@@ -185,7 +185,7 @@ describe("AgentChat lifecycle", () => {
|
|
|
185
185
|
});
|
|
186
186
|
const tree = mount();
|
|
187
187
|
|
|
188
|
-
|
|
188
|
+
const renderChat = (enablePostWidgetText: boolean) => (
|
|
189
189
|
<AgentKitProvider
|
|
190
190
|
controller={observable.controller}
|
|
191
191
|
threadId={threadId}
|
|
@@ -213,24 +213,152 @@ describe("AgentChat lifecycle", () => {
|
|
|
213
213
|
},
|
|
214
214
|
}}
|
|
215
215
|
slots={{
|
|
216
|
-
text: ({ value }) =>
|
|
216
|
+
text: ({ value }) => (
|
|
217
|
+
<div className="agentkit-markdown" data-chat-part>
|
|
218
|
+
<p>{value.text}</p>
|
|
219
|
+
</div>
|
|
220
|
+
),
|
|
217
221
|
}}
|
|
218
222
|
>
|
|
219
|
-
<AgentKitChat
|
|
220
|
-
|
|
223
|
+
<AgentKitChat
|
|
224
|
+
composer={false}
|
|
225
|
+
transcriptLayout={
|
|
226
|
+
enablePostWidgetText
|
|
227
|
+
? {
|
|
228
|
+
postWidgetText: {
|
|
229
|
+
tone: "muted",
|
|
230
|
+
paragraphPaddingBlock: 4,
|
|
231
|
+
},
|
|
232
|
+
}
|
|
233
|
+
: undefined
|
|
234
|
+
}
|
|
235
|
+
/>
|
|
236
|
+
</AgentKitProvider>
|
|
221
237
|
);
|
|
238
|
+
await tree.render(renderChat(true));
|
|
222
239
|
|
|
223
240
|
const content = tree.container.querySelector(
|
|
224
241
|
`[data-message-id="${message.id}"] .agentkit-message-content`,
|
|
225
242
|
);
|
|
243
|
+
const transcriptContent = tree.container.querySelector(
|
|
244
|
+
".agentkit-transcript-content",
|
|
245
|
+
);
|
|
226
246
|
const renderedOrder = [...(content?.children ?? [])].map((element) =>
|
|
227
|
-
element.hasAttribute("data-
|
|
247
|
+
element.hasAttribute("data-post-widget-text")
|
|
228
248
|
? element.textContent
|
|
229
|
-
: element.hasAttribute("data-
|
|
230
|
-
?
|
|
231
|
-
: "
|
|
249
|
+
: element.hasAttribute("data-chat-part")
|
|
250
|
+
? element.textContent
|
|
251
|
+
: element.hasAttribute("data-chart-result")
|
|
252
|
+
? "chart"
|
|
253
|
+
: "other",
|
|
232
254
|
);
|
|
233
255
|
expect(renderedOrder).toEqual(["Intro. ", "chart", "Summary."]);
|
|
256
|
+
expect(content?.children[0].hasAttribute("data-post-widget-text")).toBe(
|
|
257
|
+
false,
|
|
258
|
+
);
|
|
259
|
+
expect(content?.children[2].hasAttribute("data-post-widget-text")).toBe(
|
|
260
|
+
true,
|
|
261
|
+
);
|
|
262
|
+
expect(
|
|
263
|
+
content?.children[2].querySelector(".agentkit-markdown p"),
|
|
264
|
+
).not.toBeNull();
|
|
265
|
+
expect(transcriptContent?.getAttribute("style")).toContain(
|
|
266
|
+
"--agentkit-transcript-post-widget-text-color: var(--agentkit-text-muted)",
|
|
267
|
+
);
|
|
268
|
+
expect(transcriptContent?.getAttribute("style")).toContain(
|
|
269
|
+
"--agentkit-transcript-post-widget-paragraph-padding-block: 4px",
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
await tree.render(renderChat(false));
|
|
273
|
+
const defaultContent = tree.container.querySelector(
|
|
274
|
+
`[data-message-id="${message.id}"] .agentkit-message-content`,
|
|
275
|
+
);
|
|
276
|
+
expect(
|
|
277
|
+
[...(defaultContent?.children ?? [])].some((element) =>
|
|
278
|
+
element.hasAttribute("data-post-widget-text"),
|
|
279
|
+
),
|
|
280
|
+
).toBe(false);
|
|
281
|
+
await tree.unmount();
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
it("styles assistant text after an embedded widget part", async () => {
|
|
285
|
+
const threadId = "thread-embedded-content-order";
|
|
286
|
+
const widget = {
|
|
287
|
+
id: "chart-embedded-content-order",
|
|
288
|
+
kind: "test-chart",
|
|
289
|
+
data: {},
|
|
290
|
+
};
|
|
291
|
+
const message = {
|
|
292
|
+
id: "assistant-embedded-content-order",
|
|
293
|
+
role: "assistant" as const,
|
|
294
|
+
status: "complete" as const,
|
|
295
|
+
parts: [
|
|
296
|
+
{ type: "text" as const, text: "Intro." },
|
|
297
|
+
{ type: "widget" as const, widget },
|
|
298
|
+
{ type: "text" as const, text: "Summary." },
|
|
299
|
+
],
|
|
300
|
+
};
|
|
301
|
+
const thread = {
|
|
302
|
+
...createAgentThreadState(threadId),
|
|
303
|
+
messages: [message],
|
|
304
|
+
};
|
|
305
|
+
const observable = observableController({
|
|
306
|
+
connection: "connected",
|
|
307
|
+
capabilities: {},
|
|
308
|
+
capabilitiesStatus: "ready",
|
|
309
|
+
threads: { [threadId]: thread },
|
|
310
|
+
revision: 0,
|
|
311
|
+
});
|
|
312
|
+
const tree = mount();
|
|
313
|
+
|
|
314
|
+
await tree.render(
|
|
315
|
+
<AgentKitProvider
|
|
316
|
+
controller={observable.controller}
|
|
317
|
+
threadId={threadId}
|
|
318
|
+
registry={{
|
|
319
|
+
widgets: {
|
|
320
|
+
"test-chart": () => <span data-chart-result>Chart</span>,
|
|
321
|
+
},
|
|
322
|
+
}}
|
|
323
|
+
slots={{
|
|
324
|
+
text: ({ value }) => (
|
|
325
|
+
<div data-chat-part>
|
|
326
|
+
<p>{value.text}</p>
|
|
327
|
+
</div>
|
|
328
|
+
),
|
|
329
|
+
}}
|
|
330
|
+
>
|
|
331
|
+
<AgentKitChat
|
|
332
|
+
composer={false}
|
|
333
|
+
transcriptLayout={{
|
|
334
|
+
postWidgetText: {
|
|
335
|
+
tone: "muted",
|
|
336
|
+
paragraphPaddingBlock: 4,
|
|
337
|
+
},
|
|
338
|
+
}}
|
|
339
|
+
/>
|
|
340
|
+
</AgentKitProvider>,
|
|
341
|
+
);
|
|
342
|
+
|
|
343
|
+
const content = tree.container.querySelector(
|
|
344
|
+
`[data-message-id="${message.id}"] .agentkit-message-content`,
|
|
345
|
+
);
|
|
346
|
+
const renderedOrder = [...(content?.children ?? [])].map((element) =>
|
|
347
|
+
element.hasAttribute("data-post-widget-text")
|
|
348
|
+
? element.textContent
|
|
349
|
+
: element.hasAttribute("data-chat-part")
|
|
350
|
+
? element.textContent
|
|
351
|
+
: element.hasAttribute("data-chart-result")
|
|
352
|
+
? "chart"
|
|
353
|
+
: "other",
|
|
354
|
+
);
|
|
355
|
+
expect(renderedOrder).toEqual(["Intro.", "chart", "Summary."]);
|
|
356
|
+
expect(content?.children[0].hasAttribute("data-post-widget-text")).toBe(
|
|
357
|
+
false,
|
|
358
|
+
);
|
|
359
|
+
expect(content?.children[2].hasAttribute("data-post-widget-text")).toBe(
|
|
360
|
+
true,
|
|
361
|
+
);
|
|
234
362
|
await tree.unmount();
|
|
235
363
|
});
|
|
236
364
|
|
|
@@ -1686,7 +1814,7 @@ describe("AgentChat lifecycle", () => {
|
|
|
1686
1814
|
await tree.unmount();
|
|
1687
1815
|
});
|
|
1688
1816
|
|
|
1689
|
-
it("preserves visible reasoning
|
|
1817
|
+
it("preserves visible reasoning and applies the worked-row layout", async () => {
|
|
1690
1818
|
const threadId = "thread-reasoning-work";
|
|
1691
1819
|
const runId = "run-reasoning-work";
|
|
1692
1820
|
const base = (sequence: number, seconds: number = sequence) => ({
|
|
@@ -1771,10 +1899,24 @@ describe("AgentChat lifecycle", () => {
|
|
|
1771
1899
|
});
|
|
1772
1900
|
const observable = observableController(snapshot(0));
|
|
1773
1901
|
const tree = mount();
|
|
1902
|
+
const workedForRowLayout = {
|
|
1903
|
+
chevronSize: 12,
|
|
1904
|
+
iconGap: 8,
|
|
1905
|
+
marginBlockStart: -12,
|
|
1906
|
+
fontSize: 13,
|
|
1907
|
+
lineHeight: 16,
|
|
1908
|
+
paddingBlock: 2,
|
|
1909
|
+
paddingInline: 4,
|
|
1910
|
+
};
|
|
1911
|
+
const formatWorkedForDuration = (durationMs: number) =>
|
|
1912
|
+
`${Math.round(durationMs / 1000)} seconds`;
|
|
1774
1913
|
await tree.render(
|
|
1775
|
-
<
|
|
1914
|
+
<AgentKitRoot
|
|
1776
1915
|
controller={observable.controller}
|
|
1777
1916
|
threadId={threadId}
|
|
1917
|
+
load="manual"
|
|
1918
|
+
workedForRowLayout={workedForRowLayout}
|
|
1919
|
+
formatWorkedForDuration={formatWorkedForDuration}
|
|
1778
1920
|
registry={{
|
|
1779
1921
|
activities: {
|
|
1780
1922
|
reasoning: ({ value }) => (
|
|
@@ -1791,11 +1933,15 @@ describe("AgentChat lifecycle", () => {
|
|
|
1791
1933
|
}}
|
|
1792
1934
|
>
|
|
1793
1935
|
<AgentKitChat composer={false} />
|
|
1794
|
-
</
|
|
1936
|
+
</AgentKitRoot>,
|
|
1795
1937
|
);
|
|
1796
1938
|
const work = tree.container.querySelector<HTMLDetailsElement>(
|
|
1797
1939
|
".agentkit-activities",
|
|
1798
1940
|
)!;
|
|
1941
|
+
expect(
|
|
1942
|
+
work.querySelector<HTMLElement>(".agentkit-activities-summary")?.style
|
|
1943
|
+
.marginBlockStart,
|
|
1944
|
+
).toBe("-12px");
|
|
1799
1945
|
expect(work.open).toBe(false);
|
|
1800
1946
|
expect(
|
|
1801
1947
|
tree.container.querySelectorAll(".agentkit-activities"),
|
|
@@ -1821,10 +1967,19 @@ describe("AgentChat lifecycle", () => {
|
|
|
1821
1967
|
".agentkit-activities-summary > .agentkit-summary-chevron",
|
|
1822
1968
|
),
|
|
1823
1969
|
).not.toBeNull();
|
|
1970
|
+
expect(work.querySelector("summary")?.getAttribute("style")).toContain(
|
|
1971
|
+
"gap: 8px",
|
|
1972
|
+
);
|
|
1973
|
+
expect(
|
|
1974
|
+
work.querySelector<HTMLElement>(".agentkit-summary-chevron")?.style.width,
|
|
1975
|
+
).toBe("12px");
|
|
1824
1976
|
await tree.render(
|
|
1825
|
-
<
|
|
1977
|
+
<AgentKitRoot
|
|
1826
1978
|
controller={observable.controller}
|
|
1827
1979
|
threadId={threadId}
|
|
1980
|
+
load="manual"
|
|
1981
|
+
workedForRowLayout={workedForRowLayout}
|
|
1982
|
+
formatWorkedForDuration={formatWorkedForDuration}
|
|
1828
1983
|
registry={{
|
|
1829
1984
|
activities: {
|
|
1830
1985
|
reasoning: ({ value }) => (
|
|
@@ -1838,8 +1993,12 @@ describe("AgentChat lifecycle", () => {
|
|
|
1838
1993
|
{value.text}
|
|
1839
1994
|
</span>
|
|
1840
1995
|
),
|
|
1841
|
-
workedForSummary: ({ label, open, current }) => (
|
|
1842
|
-
<span
|
|
1996
|
+
workedForSummary: ({ label, open, current, layout }) => (
|
|
1997
|
+
<span
|
|
1998
|
+
data-work-summary
|
|
1999
|
+
data-open={open}
|
|
2000
|
+
data-icon-gap={layout?.iconGap}
|
|
2001
|
+
>
|
|
1843
2002
|
<span>{label}</span>
|
|
1844
2003
|
<span data-work-chevron aria-hidden="true">
|
|
1845
2004
|
›
|
|
@@ -1850,12 +2009,15 @@ describe("AgentChat lifecycle", () => {
|
|
|
1850
2009
|
}}
|
|
1851
2010
|
>
|
|
1852
2011
|
<AgentKitChat composer={false} />
|
|
1853
|
-
</
|
|
2012
|
+
</AgentKitRoot>,
|
|
1854
2013
|
);
|
|
1855
2014
|
expect(work.querySelector("[data-work-summary]")?.textContent).toContain(
|
|
1856
2015
|
"Searching documentation",
|
|
1857
2016
|
);
|
|
1858
2017
|
expect(work.querySelector("[data-work-chevron]")).not.toBeNull();
|
|
2018
|
+
expect(work.querySelector("[data-work-summary]")?.dataset.iconGap).toBe(
|
|
2019
|
+
"8",
|
|
2020
|
+
);
|
|
1859
2021
|
expect(
|
|
1860
2022
|
work.querySelector("[data-work-summary]")?.getAttribute("data-open"),
|
|
1861
2023
|
).toBe("false");
|
|
@@ -1880,7 +2042,15 @@ describe("AgentChat lifecycle", () => {
|
|
|
1880
2042
|
await flush();
|
|
1881
2043
|
expect(tree.container.querySelector(".agentkit-activities")).toBe(work);
|
|
1882
2044
|
expect(work.open).toBe(false);
|
|
1883
|
-
expect(work.querySelector("summary")?.textContent).toBe(
|
|
2045
|
+
expect(work.querySelector("summary")?.textContent).toBe(
|
|
2046
|
+
"Worked for 18 seconds›",
|
|
2047
|
+
);
|
|
2048
|
+
expect(work.querySelector<HTMLElement>("summary")?.style.fontSize).toBe(
|
|
2049
|
+
"13px",
|
|
2050
|
+
);
|
|
2051
|
+
expect(work.querySelector<HTMLElement>("summary")?.style.lineHeight).toBe(
|
|
2052
|
+
"16px",
|
|
2053
|
+
);
|
|
1884
2054
|
expect(work.querySelector("[data-agentkit-current-activity]")).toBeNull();
|
|
1885
2055
|
expect(tree.container.querySelectorAll("article")).toHaveLength(1);
|
|
1886
2056
|
const answer = tree.container.querySelector(
|
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
type AgentKitSlots,
|
|
32
32
|
} from "./context.js";
|
|
33
33
|
import type { AgentMessageContentOrderResolver } from "./message-content-order.js";
|
|
34
|
+
import type { AgentChatWorkedForRowLayout } from "./transcript-layout.js";
|
|
34
35
|
|
|
35
36
|
const mountedManagedClients = new WeakMap<AgentKitClient, number>();
|
|
36
37
|
|
|
@@ -86,6 +87,8 @@ export interface AgentKitRootBaseProps {
|
|
|
86
87
|
) => Promise<AgentConnectionResponse>;
|
|
87
88
|
onRenderError?: (failure: AgentKitRenderFailure) => void;
|
|
88
89
|
resolveMessageContentOrder?: AgentMessageContentOrderResolver;
|
|
90
|
+
workedForRowLayout?: AgentChatWorkedForRowLayout;
|
|
91
|
+
formatWorkedForDuration?: (durationMs: number) => string;
|
|
89
92
|
onClientEffect?: (effect: {
|
|
90
93
|
type: "client.effect" | "client.deeplink";
|
|
91
94
|
name: string;
|
|
@@ -116,6 +119,8 @@ export function AgentKitRoot({
|
|
|
116
119
|
onConnectionRequest,
|
|
117
120
|
onRenderError,
|
|
118
121
|
resolveMessageContentOrder,
|
|
122
|
+
workedForRowLayout,
|
|
123
|
+
formatWorkedForDuration,
|
|
119
124
|
onClientEffect,
|
|
120
125
|
load = "auto",
|
|
121
126
|
onLoadError,
|
|
@@ -294,6 +299,8 @@ export function AgentKitRoot({
|
|
|
294
299
|
onConnectionRequest={onConnectionRequest}
|
|
295
300
|
onRenderError={onRenderError}
|
|
296
301
|
resolveMessageContentOrder={resolveMessageContentOrder}
|
|
302
|
+
workedForRowLayout={workedForRowLayout}
|
|
303
|
+
formatWorkedForDuration={formatWorkedForDuration}
|
|
297
304
|
onClientEffect={onClientEffect}
|
|
298
305
|
>
|
|
299
306
|
{children}
|