@agent-native/toolkit 0.212.1 → 0.214.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/agent-native.eject.json +9 -0
- package/dist/app/agentkit/react/components.d.ts.map +1 -1
- package/dist/app/agentkit/react/components.js +10 -4
- package/dist/app/agentkit/react/components.js.map +1 -1
- package/dist/app/agentkit/react/context.d.ts +13 -1
- package/dist/app/agentkit/react/context.d.ts.map +1 -1
- package/dist/app/agentkit/react/context.js +3 -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/message-content-order.d.ts +21 -0
- package/dist/app/agentkit/react/message-content-order.d.ts.map +1 -0
- package/dist/app/agentkit/react/message-content-order.js +173 -0
- package/dist/app/agentkit/react/message-content-order.js.map +1 -0
- package/dist/app/agentkit/react/root.d.ts +3 -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 +2 -2
- package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.js +7 -2
- package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
- package/dist/app/chat/AgentPanel.d.ts +14 -2
- package/dist/app/chat/AgentPanel.d.ts.map +1 -1
- package/dist/app/chat/AgentPanel.js +22 -5
- package/dist/app/chat/AgentPanel.js.map +1 -1
- package/dist/app/chat/chat/surface-types.d.ts +8 -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/widgets/DataChartRenderer.d.ts.map +1 -1
- package/dist/app/chat/chat/widgets/DataChartRenderer.js +127 -30
- package/dist/app/chat/chat/widgets/DataChartRenderer.js.map +1 -1
- package/dist/app/chat/chat/widgets/DataChartWidget.d.ts +3 -2
- package/dist/app/chat/chat/widgets/DataChartWidget.d.ts.map +1 -1
- package/dist/app/chat/chat/widgets/DataChartWidget.js +14 -9
- package/dist/app/chat/chat/widgets/DataChartWidget.js.map +1 -1
- package/dist/app/chat/chat/widgets/DataInsightsWidget.js +1 -1
- package/dist/app/chat/chat/widgets/DataInsightsWidget.js.map +1 -1
- package/dist/app/chat/chat/widgets/DataTableWidget.d.ts +3 -2
- package/dist/app/chat/chat/widgets/DataTableWidget.d.ts.map +1 -1
- package/dist/app/chat/chat/widgets/DataTableWidget.js +10 -66
- package/dist/app/chat/chat/widgets/DataTableWidget.js.map +1 -1
- package/dist/app/chat/chat/widgets/DataWidgetDisplayControls.d.ts +11 -0
- package/dist/app/chat/chat/widgets/DataWidgetDisplayControls.d.ts.map +1 -0
- package/dist/app/chat/chat/widgets/DataWidgetDisplayControls.js +131 -0
- package/dist/app/chat/chat/widgets/DataWidgetDisplayControls.js.map +1 -0
- package/dist/app/chat/chat/widgets/builtin-tool-renderers.js +2 -2
- package/dist/app/chat/chat/widgets/builtin-tool-renderers.js.map +1 -1
- package/dist/app/chat/mcp-apps/McpAppRenderer.d.ts.map +1 -1
- package/dist/app/chat/mcp-apps/McpAppRenderer.js +6 -5
- package/dist/app/chat/mcp-apps/McpAppRenderer.js.map +1 -1
- package/dist/app/chat/mcp-apps/mcp-app-theme.d.ts +2 -0
- package/dist/app/chat/mcp-apps/mcp-app-theme.d.ts.map +1 -0
- package/dist/app/chat/mcp-apps/mcp-app-theme.js +11 -0
- package/dist/app/chat/mcp-apps/mcp-app-theme.js.map +1 -0
- package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.js +10 -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 +10 -0
- package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
- package/dist/app/i18n/catalogs/en-US.d.ts +10 -0
- package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/en-US.js +10 -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 +10 -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 +10 -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 +10 -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 +10 -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 +10 -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 +10 -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 +10 -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 +10 -0
- package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
- package/dist/app/org/AuthenticationSection.d.ts +3 -0
- package/dist/app/org/AuthenticationSection.d.ts.map +1 -1
- package/dist/app/org/AuthenticationSection.js +9 -3
- package/dist/app/org/AuthenticationSection.js.map +1 -1
- package/dist/app/org/pages/OrgAuthenticationPage.d.ts.map +1 -1
- package/dist/app/org/pages/OrgAuthenticationPage.js +2 -2
- package/dist/app/org/pages/OrgAuthenticationPage.js.map +1 -1
- package/dist/app/providers/AppProviders.d.ts +2 -1
- package/dist/app/providers/AppProviders.d.ts.map +1 -1
- package/dist/app/providers/AppProviders.js +4 -3
- package/dist/app/providers/AppProviders.js.map +1 -1
- package/dist/app/providers/ThemeFamilySync.d.ts +2 -0
- package/dist/app/providers/ThemeFamilySync.d.ts.map +1 -0
- package/dist/app/providers/ThemeFamilySync.js +6 -0
- package/dist/app/providers/ThemeFamilySync.js.map +1 -0
- package/dist/app/settings/account/PreferencesSettings.d.ts.map +1 -1
- package/dist/app/settings/account/PreferencesSettings.js +2 -1
- package/dist/app/settings/account/PreferencesSettings.js.map +1 -1
- package/dist/app/settings/account/ThemeFamilySettings.d.ts +2 -0
- package/dist/app/settings/account/ThemeFamilySettings.d.ts.map +1 -0
- package/dist/app/settings/account/ThemeFamilySettings.js +31 -0
- package/dist/app/settings/account/ThemeFamilySettings.js.map +1 -0
- package/dist/app/settings/account/search-entries.d.ts.map +1 -1
- package/dist/app/settings/account/search-entries.js +6 -0
- package/dist/app/settings/account/search-entries.js.map +1 -1
- package/dist/app/shared/DefaultSpinner.d.ts.map +1 -1
- package/dist/app/shared/DefaultSpinner.js +4 -5
- package/dist/app/shared/DefaultSpinner.js.map +1 -1
- package/dist/app/shared/ErrorBoundary.d.ts +1 -0
- package/dist/app/shared/ErrorBoundary.d.ts.map +1 -1
- package/dist/app/shared/ErrorBoundary.js +27 -12
- package/dist/app/shared/ErrorBoundary.js.map +1 -1
- package/dist/app/shared/PoweredByBadge.d.ts.map +1 -1
- package/dist/app/shared/PoweredByBadge.js +8 -49
- package/dist/app/shared/PoweredByBadge.js.map +1 -1
- package/dist/app/styles/agent-conversation.css +0 -23
- package/dist/app/styles/agent-native.css +1 -1
- package/dist/app/styles/theme-families.css +66 -0
- package/dist/composer/ComposerContextBanner.d.ts +22 -0
- package/dist/composer/ComposerContextBanner.d.ts.map +1 -0
- package/dist/composer/ComposerContextBanner.js +9 -0
- package/dist/composer/ComposerContextBanner.js.map +1 -0
- package/dist/composer/ComposerModePicker.d.ts +26 -0
- package/dist/composer/ComposerModePicker.d.ts.map +1 -0
- package/dist/composer/ComposerModePicker.js +14 -0
- package/dist/composer/ComposerModePicker.js.map +1 -0
- package/dist/composer/index.d.ts +2 -0
- package/dist/composer/index.d.ts.map +1 -1
- package/dist/composer/index.js +2 -0
- package/dist/composer/index.js.map +1 -1
- package/dist/styles.css +1 -0
- package/package.json +3 -3
- package/src/app/agentkit/react/components.spec.tsx +12 -0
- package/src/app/agentkit/react/components.tsx +41 -22
- package/src/app/agentkit/react/context.tsx +17 -0
- package/src/app/agentkit/react/index.ts +1 -0
- package/src/app/agentkit/react/lifecycle.spec.tsx +116 -1
- package/src/app/agentkit/react/message-content-order.spec.ts +190 -0
- package/src/app/agentkit/react/message-content-order.ts +246 -0
- package/src/app/agentkit/react/root.tsx +4 -0
- package/src/app/agentkit/react/styles.css +2 -2
- package/src/app/chat/AgentKitAssistantChat.spec.tsx +19 -0
- package/src/app/chat/AgentKitAssistantChat.tsx +10 -1
- package/src/app/chat/AgentPanel.header.spec.ts +72 -14
- package/src/app/chat/AgentPanel.tsx +97 -53
- package/src/app/chat/chat/surface-types.ts +8 -0
- package/src/app/chat/chat/widgets/DataChartRenderer.spec.tsx +217 -0
- package/src/app/chat/chat/widgets/DataChartRenderer.tsx +306 -68
- package/src/app/chat/chat/widgets/DataChartWidget.spec.tsx +329 -0
- package/src/app/chat/chat/widgets/DataChartWidget.ssr.spec.tsx +25 -0
- package/src/app/chat/chat/widgets/DataChartWidget.tsx +48 -33
- package/src/app/chat/chat/widgets/DataInsightsWidget.tsx +2 -2
- package/src/app/chat/chat/widgets/DataTableWidget.spec.tsx +37 -3
- package/src/app/chat/chat/widgets/DataTableWidget.tsx +22 -86
- package/src/app/chat/chat/widgets/DataWidgetDisplayControls.tsx +301 -0
- package/src/app/chat/chat/widgets/builtin-tool-renderers.tsx +5 -5
- package/src/app/chat/mcp-apps/McpAppRenderer.tsx +10 -5
- package/src/app/chat/mcp-apps/mcp-app-theme.spec.ts +30 -0
- package/src/app/chat/mcp-apps/mcp-app-theme.ts +11 -0
- package/src/app/i18n/catalogs/ar-SA.ts +12 -0
- package/src/app/i18n/catalogs/de-DE.ts +13 -0
- package/src/app/i18n/catalogs/en-US.ts +12 -0
- package/src/app/i18n/catalogs/es-ES.ts +14 -0
- package/src/app/i18n/catalogs/fr-FR.ts +14 -0
- package/src/app/i18n/catalogs/hi-IN.ts +12 -0
- package/src/app/i18n/catalogs/ja-JP.ts +12 -0
- package/src/app/i18n/catalogs/ko-KR.ts +12 -0
- package/src/app/i18n/catalogs/pt-BR.ts +13 -0
- package/src/app/i18n/catalogs/zh-CN.ts +11 -0
- package/src/app/i18n/catalogs/zh-TW.ts +12 -0
- package/src/app/org/AuthenticationSection.spec.tsx +62 -0
- package/src/app/org/AuthenticationSection.tsx +47 -1
- package/src/app/org/pages/OrgAuthenticationPage.tsx +4 -0
- package/src/app/org/pages/OrgSettingsPages.spec.tsx +3 -0
- package/src/app/providers/AppProviders.spec.tsx +71 -0
- package/src/app/providers/AppProviders.tsx +10 -0
- package/src/app/providers/ThemeFamilySync.tsx +6 -0
- package/src/app/settings/account/PreferencesSettings.spec.tsx +13 -2
- package/src/app/settings/account/PreferencesSettings.tsx +8 -0
- package/src/app/settings/account/ThemeFamilySettings.tsx +61 -0
- package/src/app/settings/account/search-entries.ts +6 -0
- package/src/app/shared/DefaultSpinner.spec.tsx +14 -0
- package/src/app/shared/DefaultSpinner.tsx +4 -5
- package/src/app/shared/ErrorBoundary.spec.tsx +45 -2
- package/src/app/shared/ErrorBoundary.tsx +37 -12
- package/src/app/shared/PoweredByBadge.spec.tsx +16 -0
- package/src/app/shared/PoweredByBadge.tsx +8 -50
- package/src/app/styles/agent-conversation.css +0 -23
- package/src/app/styles/agent-native.css +1 -1
- package/src/app/styles/agent-native.spec.ts +18 -0
- package/src/app/styles/theme-families.css +66 -0
- package/src/app/styles/theme-families.spec.ts +29 -0
- package/src/composer/ComposerContextBanner.spec.tsx +74 -0
- package/src/composer/ComposerContextBanner.tsx +72 -0
- package/src/composer/ComposerModePicker.spec.tsx +101 -0
- package/src/composer/ComposerModePicker.tsx +98 -0
- package/src/composer/index.ts +9 -0
- package/src/styles.css +1 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AgentEvent,
|
|
3
|
+
AgentMessage,
|
|
4
|
+
AgentMessagePart,
|
|
5
|
+
AgentWidget,
|
|
6
|
+
} from "@agent-native/agentkit/protocol";
|
|
7
|
+
|
|
8
|
+
export type AgentMessageContentItem =
|
|
9
|
+
| { key: string; type: "part"; part: AgentMessagePart }
|
|
10
|
+
| { key: string; type: "widget"; widget: AgentWidget };
|
|
11
|
+
|
|
12
|
+
export interface AgentMessageContentOrderInput {
|
|
13
|
+
message: AgentMessage;
|
|
14
|
+
parts: AgentMessagePart[];
|
|
15
|
+
widgets: AgentWidget[];
|
|
16
|
+
events: AgentEvent[];
|
|
17
|
+
defaultOrder: AgentMessageContentItem[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type AgentMessageContentOrderResolver = (
|
|
21
|
+
input: AgentMessageContentOrderInput,
|
|
22
|
+
) => AgentMessageContentItem[];
|
|
23
|
+
|
|
24
|
+
type TextContentOrderItem = Extract<
|
|
25
|
+
AgentMessageContentItem,
|
|
26
|
+
{ type: "part" }
|
|
27
|
+
> & {
|
|
28
|
+
part: Extract<AgentMessagePart, { type: "text" }>;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
function isTextContentOrderItem(
|
|
32
|
+
item: AgentMessageContentItem | null | undefined,
|
|
33
|
+
): item is TextContentOrderItem {
|
|
34
|
+
return (
|
|
35
|
+
item?.type === "part" &&
|
|
36
|
+
typeof item.key === "string" &&
|
|
37
|
+
item.part?.type === "text" &&
|
|
38
|
+
typeof item.part.text === "string"
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function resolvedItemsPreserveContent(
|
|
43
|
+
defaultOrder: AgentMessageContentItem[],
|
|
44
|
+
resolvedOrder: AgentMessageContentItem[],
|
|
45
|
+
): AgentMessageContentItem[] | undefined {
|
|
46
|
+
if (!Array.isArray(resolvedOrder)) return undefined;
|
|
47
|
+
|
|
48
|
+
const defaultText = defaultOrder
|
|
49
|
+
.filter(isTextContentOrderItem)
|
|
50
|
+
.map((item) => item.part.text)
|
|
51
|
+
.join("");
|
|
52
|
+
const resolvedText = resolvedOrder
|
|
53
|
+
.filter(isTextContentOrderItem)
|
|
54
|
+
.map((item) => item.part.text)
|
|
55
|
+
.join("");
|
|
56
|
+
if (defaultText !== resolvedText) return undefined;
|
|
57
|
+
|
|
58
|
+
const expectedItems = new Map<string, AgentMessageContentItem[]>();
|
|
59
|
+
for (const item of defaultOrder) {
|
|
60
|
+
if (item.type === "part" && item.part.type === "text") continue;
|
|
61
|
+
const identity = `${item.type}:${item.key}`;
|
|
62
|
+
const matchingItems = expectedItems.get(identity) ?? [];
|
|
63
|
+
matchingItems.push(item);
|
|
64
|
+
expectedItems.set(identity, matchingItems);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const preservedItems: AgentMessageContentItem[] = [];
|
|
68
|
+
for (const item of resolvedOrder) {
|
|
69
|
+
if (!item || typeof item !== "object") return undefined;
|
|
70
|
+
if (item.type === "part" && item.part?.type === "text") {
|
|
71
|
+
if (typeof item.key !== "string" || typeof item.part.text !== "string") {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
preservedItems.push(item);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (
|
|
79
|
+
(item.type !== "part" && item.type !== "widget") ||
|
|
80
|
+
typeof item.key !== "string"
|
|
81
|
+
) {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const identity = `${item.type}:${item.key}`;
|
|
86
|
+
const matchingItems = expectedItems.get(identity);
|
|
87
|
+
const original = matchingItems?.shift();
|
|
88
|
+
if (!original) return undefined;
|
|
89
|
+
preservedItems.push(original);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (
|
|
93
|
+
[...expectedItems.values()].some((matchingItems) => matchingItems.length)
|
|
94
|
+
) {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
return preservedItems;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Uses the stream timeline only when it reconstructs the saved text exactly. */
|
|
101
|
+
export function orderMessageContent(
|
|
102
|
+
message: AgentMessage,
|
|
103
|
+
visibleParts: AgentMessagePart[],
|
|
104
|
+
attachedWidgets: AgentWidget[],
|
|
105
|
+
events: AgentEvent[],
|
|
106
|
+
resolveOrder?: AgentMessageContentOrderResolver,
|
|
107
|
+
): AgentMessageContentItem[] {
|
|
108
|
+
const fallback = [
|
|
109
|
+
...visibleParts.map((part, index) => ({
|
|
110
|
+
key: `${message.id}-${index}`,
|
|
111
|
+
type: "part" as const,
|
|
112
|
+
part,
|
|
113
|
+
})),
|
|
114
|
+
...attachedWidgets.map((widget) => ({
|
|
115
|
+
key: widget.id,
|
|
116
|
+
type: "widget" as const,
|
|
117
|
+
widget,
|
|
118
|
+
})),
|
|
119
|
+
];
|
|
120
|
+
const resolve = (defaultOrder: AgentMessageContentItem[]) => {
|
|
121
|
+
const resolvedOrder = resolveOrder?.({
|
|
122
|
+
message,
|
|
123
|
+
parts: visibleParts,
|
|
124
|
+
widgets: attachedWidgets,
|
|
125
|
+
events,
|
|
126
|
+
defaultOrder,
|
|
127
|
+
});
|
|
128
|
+
if (resolvedOrder == null) return defaultOrder;
|
|
129
|
+
return (
|
|
130
|
+
resolvedItemsPreserveContent(defaultOrder, resolvedOrder) ?? defaultOrder
|
|
131
|
+
);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
if (
|
|
135
|
+
attachedWidgets.length === 0 ||
|
|
136
|
+
message.parts.length !== 1 ||
|
|
137
|
+
message.parts[0]?.type !== "text" ||
|
|
138
|
+
visibleParts.length !== 1 ||
|
|
139
|
+
visibleParts[0]?.type !== "text" ||
|
|
140
|
+
visibleParts[0].text !== message.parts[0].text
|
|
141
|
+
) {
|
|
142
|
+
return resolve(fallback);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const widgetIds = new Set(attachedWidgets.map((widget) => widget.id));
|
|
146
|
+
const widgetOffsets = new Map<string, number>();
|
|
147
|
+
const widgetEventOrder = new Map<string, number>();
|
|
148
|
+
let reconstructedText = "";
|
|
149
|
+
let textOffset = 0;
|
|
150
|
+
|
|
151
|
+
for (const [eventIndex, event] of events.entries()) {
|
|
152
|
+
if (event.type === "message.created" && event.message.id === message.id) {
|
|
153
|
+
const createdParts = event.message.parts;
|
|
154
|
+
if (
|
|
155
|
+
createdParts.length > 1 ||
|
|
156
|
+
createdParts.some((part) => part.type !== "text")
|
|
157
|
+
) {
|
|
158
|
+
return resolve(fallback);
|
|
159
|
+
}
|
|
160
|
+
reconstructedText =
|
|
161
|
+
createdParts[0]?.type === "text" ? createdParts[0].text : "";
|
|
162
|
+
textOffset = reconstructedText.length;
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (event.type === "message.delta" && event.messageId === message.id) {
|
|
167
|
+
reconstructedText += event.text;
|
|
168
|
+
textOffset += event.text.length;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (
|
|
173
|
+
(event.type === "widget.created" || event.type === "widget.updated") &&
|
|
174
|
+
event.messageId === message.id &&
|
|
175
|
+
widgetIds.has(event.widget.id) &&
|
|
176
|
+
!widgetOffsets.has(event.widget.id)
|
|
177
|
+
) {
|
|
178
|
+
widgetOffsets.set(event.widget.id, textOffset);
|
|
179
|
+
widgetEventOrder.set(event.widget.id, eventIndex);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const fullText = message.parts[0].text;
|
|
184
|
+
if (
|
|
185
|
+
reconstructedText !== fullText ||
|
|
186
|
+
widgetOffsets.size !== attachedWidgets.length ||
|
|
187
|
+
[...widgetOffsets.values()].some((offset) => {
|
|
188
|
+
if (offset === 0 || offset === fullText.length) return false;
|
|
189
|
+
const preceding = fullText.charCodeAt(offset - 1);
|
|
190
|
+
const following = fullText.charCodeAt(offset);
|
|
191
|
+
return (
|
|
192
|
+
preceding >= 0xd800 &&
|
|
193
|
+
preceding <= 0xdbff &&
|
|
194
|
+
following >= 0xdc00 &&
|
|
195
|
+
following <= 0xdfff
|
|
196
|
+
);
|
|
197
|
+
})
|
|
198
|
+
) {
|
|
199
|
+
return resolve(fallback);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const widgetsAtOffset = new Map<number, AgentWidget[]>();
|
|
203
|
+
for (const widget of attachedWidgets) {
|
|
204
|
+
const offset = widgetOffsets.get(widget.id)!;
|
|
205
|
+
const widgets = widgetsAtOffset.get(offset) ?? [];
|
|
206
|
+
widgets.push(widget);
|
|
207
|
+
widgetsAtOffset.set(offset, widgets);
|
|
208
|
+
}
|
|
209
|
+
for (const widgets of widgetsAtOffset.values()) {
|
|
210
|
+
widgets.sort(
|
|
211
|
+
(first, second) =>
|
|
212
|
+
widgetEventOrder.get(first.id)! - widgetEventOrder.get(second.id)!,
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const insertions = [...widgetsAtOffset.entries()].sort(
|
|
217
|
+
([first], [second]) => first - second,
|
|
218
|
+
);
|
|
219
|
+
const part = visibleParts[0];
|
|
220
|
+
if (part.type !== "text") return resolve(fallback);
|
|
221
|
+
|
|
222
|
+
const ordered: AgentMessageContentItem[] = [];
|
|
223
|
+
let cursor = 0;
|
|
224
|
+
for (const [offset, widgets] of insertions) {
|
|
225
|
+
if (offset > cursor) {
|
|
226
|
+
ordered.push({
|
|
227
|
+
key: `${message.id}-text-${cursor}`,
|
|
228
|
+
type: "part",
|
|
229
|
+
part: { ...part, text: part.text.slice(cursor, offset) },
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
for (const widget of widgets) {
|
|
233
|
+
ordered.push({ key: widget.id, type: "widget", widget });
|
|
234
|
+
}
|
|
235
|
+
cursor = offset;
|
|
236
|
+
}
|
|
237
|
+
if (cursor < part.text.length) {
|
|
238
|
+
ordered.push({
|
|
239
|
+
key: `${message.id}-text-${cursor}`,
|
|
240
|
+
type: "part",
|
|
241
|
+
part: { ...part, text: part.text.slice(cursor) },
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return resolve(ordered);
|
|
246
|
+
}
|
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
type AgentKitRunUsageLoader,
|
|
31
31
|
type AgentKitSlots,
|
|
32
32
|
} from "./context.js";
|
|
33
|
+
import type { AgentMessageContentOrderResolver } from "./message-content-order.js";
|
|
33
34
|
|
|
34
35
|
const mountedManagedClients = new WeakMap<AgentKitClient, number>();
|
|
35
36
|
|
|
@@ -84,6 +85,7 @@ export interface AgentKitRootBaseProps {
|
|
|
84
85
|
request: AgentConnectionRequest,
|
|
85
86
|
) => Promise<AgentConnectionResponse>;
|
|
86
87
|
onRenderError?: (failure: AgentKitRenderFailure) => void;
|
|
88
|
+
resolveMessageContentOrder?: AgentMessageContentOrderResolver;
|
|
87
89
|
onClientEffect?: (effect: {
|
|
88
90
|
type: "client.effect" | "client.deeplink";
|
|
89
91
|
name: string;
|
|
@@ -113,6 +115,7 @@ export function AgentKitRoot({
|
|
|
113
115
|
loadRunUsage,
|
|
114
116
|
onConnectionRequest,
|
|
115
117
|
onRenderError,
|
|
118
|
+
resolveMessageContentOrder,
|
|
116
119
|
onClientEffect,
|
|
117
120
|
load = "auto",
|
|
118
121
|
onLoadError,
|
|
@@ -290,6 +293,7 @@ export function AgentKitRoot({
|
|
|
290
293
|
loadRunUsage={loadRunUsage}
|
|
291
294
|
onConnectionRequest={onConnectionRequest}
|
|
292
295
|
onRenderError={onRenderError}
|
|
296
|
+
resolveMessageContentOrder={resolveMessageContentOrder}
|
|
293
297
|
onClientEffect={onClientEffect}
|
|
294
298
|
>
|
|
295
299
|
{children}
|
|
@@ -1216,7 +1216,7 @@ body:has(> [data-agent-native-composer-popover="true"]) > .fixed.inset-0 {
|
|
|
1216
1216
|
inline-size: fit-content;
|
|
1217
1217
|
max-inline-size: 100%;
|
|
1218
1218
|
align-items: center;
|
|
1219
|
-
gap:
|
|
1219
|
+
gap: 1rem;
|
|
1220
1220
|
}
|
|
1221
1221
|
|
|
1222
1222
|
.agentkit-activities {
|
|
@@ -1418,7 +1418,7 @@ body:has(> [data-agent-native-composer-popover="true"]) > .fixed.inset-0 {
|
|
|
1418
1418
|
}
|
|
1419
1419
|
|
|
1420
1420
|
.agentkit-activities-summary > .agentkit-summary-chevron {
|
|
1421
|
-
opacity:
|
|
1421
|
+
opacity: 1;
|
|
1422
1422
|
}
|
|
1423
1423
|
|
|
1424
1424
|
.agentkit-activities[data-expandable="true"]
|
|
@@ -3348,6 +3348,25 @@ describe("AgentKitAssistantChat host behavior", () => {
|
|
|
3348
3348
|
expect(container.querySelector(".agentkit-home-intro")).toBeNull();
|
|
3349
3349
|
});
|
|
3350
3350
|
|
|
3351
|
+
it("renders the shared context banner slot alongside the existing composer slot", async () => {
|
|
3352
|
+
await mount(
|
|
3353
|
+
baseProps({
|
|
3354
|
+
composerSlot: <div data-testid="legacy-composer-slot">Notice</div>,
|
|
3355
|
+
composerContextBannerSlot: (
|
|
3356
|
+
<div data-testid="composer-context-banner-slot">Add context</div>
|
|
3357
|
+
),
|
|
3358
|
+
}),
|
|
3359
|
+
);
|
|
3360
|
+
|
|
3361
|
+
const composer = container.querySelector(".agentkit-host-composer")!;
|
|
3362
|
+
expect(
|
|
3363
|
+
composer.querySelector('[data-testid="legacy-composer-slot"]'),
|
|
3364
|
+
).not.toBeNull();
|
|
3365
|
+
expect(
|
|
3366
|
+
composer.querySelector('[data-testid="composer-context-banner-slot"]'),
|
|
3367
|
+
).not.toBeNull();
|
|
3368
|
+
});
|
|
3369
|
+
|
|
3351
3370
|
it("puts the beginning revert before messages inside the scrollable transcript", async () => {
|
|
3352
3371
|
chatMocks.thread.messages = [
|
|
3353
3372
|
{ id: "first-message", role: "user", parts: [] },
|
|
@@ -2093,9 +2093,17 @@ export const AgentKitAssistantChat = forwardRef<
|
|
|
2093
2093
|
threadId={threadId}
|
|
2094
2094
|
load={agentKitLoad}
|
|
2095
2095
|
onLoadError={onThreadRestoreLoadError}
|
|
2096
|
-
slots={
|
|
2096
|
+
slots={
|
|
2097
|
+
props.workedForSummarySlot
|
|
2098
|
+
? {
|
|
2099
|
+
...agentKitSlots,
|
|
2100
|
+
workedForSummary: props.workedForSummarySlot,
|
|
2101
|
+
}
|
|
2102
|
+
: agentKitSlots
|
|
2103
|
+
}
|
|
2097
2104
|
registry={agentKitRegistry}
|
|
2098
2105
|
labels={labels}
|
|
2106
|
+
resolveMessageContentOrder={props.resolveMessageContentOrder}
|
|
2099
2107
|
branchNavigation={props.branchNavigation}
|
|
2100
2108
|
loadRunUsage={loadRunUsage}
|
|
2101
2109
|
buildFeedbackReport={formatFeedbackReport}
|
|
@@ -5979,6 +5987,7 @@ function AgentKitComposerSurface({
|
|
|
5979
5987
|
})}
|
|
5980
5988
|
/>
|
|
5981
5989
|
{props.composerSlot}
|
|
5990
|
+
{props.composerContextBannerSlot}
|
|
5982
5991
|
{showHomeIntro ? (
|
|
5983
5992
|
<div className="agentkit-home-intro">{props.homeIntroSlot}</div>
|
|
5984
5993
|
) : null}
|
|
@@ -31,6 +31,8 @@ import {
|
|
|
31
31
|
shouldHandleAgentSidebarToggle,
|
|
32
32
|
shouldHandleAgentPanelChatShortcut,
|
|
33
33
|
shouldShowAgentPanelFullViewAction,
|
|
34
|
+
resolveAgentPanelPageHeaderActions,
|
|
35
|
+
resolveAgentPanelPageToolbarSlot,
|
|
34
36
|
shouldShowAgentPanelPageHeader,
|
|
35
37
|
shouldShowAgentPanelPageNewChatButton,
|
|
36
38
|
shouldShowAgentPanelChatTabBar,
|
|
@@ -350,22 +352,60 @@ describe("AgentPanel header tab visibility", () => {
|
|
|
350
352
|
expect(shouldDefaultAgentChatSurfacePageHeader(undefined)).toBe(false);
|
|
351
353
|
});
|
|
352
354
|
|
|
353
|
-
it("
|
|
354
|
-
|
|
355
|
+
it("keeps share and host toolbar actions when the title menu is hidden", async () => {
|
|
356
|
+
expect(
|
|
357
|
+
resolveAgentPanelPageHeaderActions({
|
|
358
|
+
showPageTitleMenu: false,
|
|
359
|
+
canShareActiveTab: true,
|
|
360
|
+
}),
|
|
361
|
+
).toEqual({ showPageTitleMenu: false, showShareAction: true });
|
|
355
362
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
363
|
+
const container = document.createElement("div");
|
|
364
|
+
document.body.append(container);
|
|
365
|
+
const root = createRoot(container);
|
|
366
|
+
const toggleHistory = vi.fn();
|
|
367
|
+
const clearActiveTab = vi.fn();
|
|
368
|
+
const toolbar = resolveAgentPanelPageToolbarSlot(
|
|
369
|
+
(actions) =>
|
|
370
|
+
React.createElement(
|
|
371
|
+
"div",
|
|
372
|
+
null,
|
|
373
|
+
React.createElement(
|
|
374
|
+
"button",
|
|
375
|
+
{ onClick: actions.toggleHistory },
|
|
376
|
+
actions.showHistory ? "Hide chats" : "All chats",
|
|
377
|
+
),
|
|
378
|
+
actions.activeTabMessageCount > 0
|
|
379
|
+
? React.createElement(
|
|
380
|
+
"button",
|
|
381
|
+
{ onClick: actions.clearActiveTab },
|
|
382
|
+
"Clear chat",
|
|
383
|
+
)
|
|
384
|
+
: null,
|
|
385
|
+
),
|
|
386
|
+
{
|
|
387
|
+
activeTabMessageCount: 2,
|
|
388
|
+
clearActiveTab,
|
|
389
|
+
showHistory: false,
|
|
390
|
+
toggleHistory,
|
|
391
|
+
},
|
|
367
392
|
);
|
|
368
|
-
|
|
393
|
+
|
|
394
|
+
try {
|
|
395
|
+
await act(async () => root.render(toolbar));
|
|
396
|
+
const buttons = container.querySelectorAll("button");
|
|
397
|
+
expect([...buttons].map((button) => button.textContent)).toEqual([
|
|
398
|
+
"All chats",
|
|
399
|
+
"Clear chat",
|
|
400
|
+
]);
|
|
401
|
+
await act(async () => buttons[0]?.click());
|
|
402
|
+
await act(async () => buttons[1]?.click());
|
|
403
|
+
expect(toggleHistory).toHaveBeenCalledOnce();
|
|
404
|
+
expect(clearActiveTab).toHaveBeenCalledOnce();
|
|
405
|
+
} finally {
|
|
406
|
+
await act(async () => root.unmount());
|
|
407
|
+
container.remove();
|
|
408
|
+
}
|
|
369
409
|
});
|
|
370
410
|
|
|
371
411
|
it("normalizes legacy and unknown modes back to chat", () => {
|
|
@@ -1193,6 +1233,24 @@ describe("AgentChatSurface chrome defaults", () => {
|
|
|
1193
1233
|
expect(surface.props.showHeader).toBe(true);
|
|
1194
1234
|
expect(surface.props.showTabBar).toBe(true);
|
|
1195
1235
|
});
|
|
1236
|
+
|
|
1237
|
+
it("allows a page host to hide only the title menu", () => {
|
|
1238
|
+
const surface = AgentChatSurface({
|
|
1239
|
+
mode: "page",
|
|
1240
|
+
showPageTitleMenu: false,
|
|
1241
|
+
});
|
|
1242
|
+
const panel = surface.props.children[1];
|
|
1243
|
+
const headerActions = resolveAgentPanelPageHeaderActions({
|
|
1244
|
+
showPageTitleMenu: false,
|
|
1245
|
+
canShareActiveTab: true,
|
|
1246
|
+
});
|
|
1247
|
+
|
|
1248
|
+
expect(panel.props.showPageTitleMenu).toBe(false);
|
|
1249
|
+
expect(headerActions).toEqual({
|
|
1250
|
+
showPageTitleMenu: false,
|
|
1251
|
+
showShareAction: true,
|
|
1252
|
+
});
|
|
1253
|
+
});
|
|
1196
1254
|
});
|
|
1197
1255
|
|
|
1198
1256
|
describe("AgentPanel stale lazy chunk recovery", () => {
|
|
@@ -441,6 +441,30 @@ export function shouldShowAgentPanelPageHeader(
|
|
|
441
441
|
);
|
|
442
442
|
}
|
|
443
443
|
|
|
444
|
+
export function resolveAgentPanelPageHeaderActions({
|
|
445
|
+
showPageTitleMenu = true,
|
|
446
|
+
canShareActiveTab,
|
|
447
|
+
}: {
|
|
448
|
+
showPageTitleMenu?: boolean;
|
|
449
|
+
canShareActiveTab: boolean;
|
|
450
|
+
}) {
|
|
451
|
+
return { showPageTitleMenu, showShareAction: canShareActiveTab };
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
export type AgentPanelPageToolbarActions = Pick<
|
|
455
|
+
MultiTabAssistantChatHeaderCallbackProps,
|
|
456
|
+
"activeTabMessageCount" | "clearActiveTab" | "showHistory" | "toggleHistory"
|
|
457
|
+
>;
|
|
458
|
+
|
|
459
|
+
export function resolveAgentPanelPageToolbarSlot(
|
|
460
|
+
slot:
|
|
461
|
+
| React.ReactNode
|
|
462
|
+
| ((actions: AgentPanelPageToolbarActions) => React.ReactNode),
|
|
463
|
+
actions: AgentPanelPageToolbarActions,
|
|
464
|
+
) {
|
|
465
|
+
return typeof slot === "function" ? slot(actions) : slot;
|
|
466
|
+
}
|
|
467
|
+
|
|
444
468
|
export function shouldShowAgentPanelCliTabBar(cliTabs: string[]) {
|
|
445
469
|
return cliTabs.length > 1;
|
|
446
470
|
}
|
|
@@ -583,8 +607,13 @@ export interface AgentPanelProps extends Omit<
|
|
|
583
607
|
showPageNewChatButton?: boolean;
|
|
584
608
|
showPageHeader?: boolean;
|
|
585
609
|
showPageHeaderWhenEmpty?: boolean;
|
|
610
|
+
/** Hide the default page title menu while keeping the shared page actions. */
|
|
611
|
+
showPageTitleMenu?: boolean;
|
|
586
612
|
pageHeaderLeadingSlot?: React.ReactNode;
|
|
587
|
-
|
|
613
|
+
/** Render host page actions alongside Share, with the active chat controls. */
|
|
614
|
+
pageToolbarSlot?:
|
|
615
|
+
| React.ReactNode
|
|
616
|
+
| ((actions: AgentPanelPageToolbarActions) => React.ReactNode);
|
|
588
617
|
onPageHeaderVisibilityChange?: (visible: boolean) => void;
|
|
589
618
|
chatOnly?: boolean;
|
|
590
619
|
agentPageHref?: string;
|
|
@@ -778,6 +807,7 @@ function AgentPanelInner({
|
|
|
778
807
|
showPageNewChatButton = false,
|
|
779
808
|
showPageHeader = false,
|
|
780
809
|
showPageHeaderWhenEmpty = false,
|
|
810
|
+
showPageTitleMenu = true,
|
|
781
811
|
pageHeaderLeadingSlot,
|
|
782
812
|
pageToolbarSlot,
|
|
783
813
|
onPageHeaderVisibilityChange,
|
|
@@ -1694,11 +1724,16 @@ function AgentPanelInner({
|
|
|
1694
1724
|
showPageHeaderWhenEmpty,
|
|
1695
1725
|
activeTabIsPersisted,
|
|
1696
1726
|
);
|
|
1697
|
-
const canShareActiveTab =
|
|
1727
|
+
const canShareActiveTab = Boolean(
|
|
1698
1728
|
activeTab &&
|
|
1699
1729
|
(activeTabIsPersisted ||
|
|
1700
1730
|
activeTabMessageCount > 0 ||
|
|
1701
|
-
activeTab.status !== "idle")
|
|
1731
|
+
activeTab.status !== "idle"),
|
|
1732
|
+
);
|
|
1733
|
+
const pageHeaderActions = resolveAgentPanelPageHeaderActions({
|
|
1734
|
+
showPageTitleMenu,
|
|
1735
|
+
canShareActiveTab,
|
|
1736
|
+
});
|
|
1702
1737
|
const showNewChatAction =
|
|
1703
1738
|
showPageNewChatButton &&
|
|
1704
1739
|
shouldShowAgentPanelPageNewChatButton(
|
|
@@ -1707,6 +1742,12 @@ function AgentPanelInner({
|
|
|
1707
1742
|
activeTabMessageCount,
|
|
1708
1743
|
activeTabIsPersisted,
|
|
1709
1744
|
);
|
|
1745
|
+
const toolbarSlot = resolveAgentPanelPageToolbarSlot(pageToolbarSlot, {
|
|
1746
|
+
activeTabMessageCount,
|
|
1747
|
+
clearActiveTab,
|
|
1748
|
+
showHistory,
|
|
1749
|
+
toggleHistory,
|
|
1750
|
+
});
|
|
1710
1751
|
|
|
1711
1752
|
return (
|
|
1712
1753
|
<>
|
|
@@ -1730,62 +1771,64 @@ function AgentPanelInner({
|
|
|
1730
1771
|
<h1 className="truncate text-xs font-medium text-foreground">
|
|
1731
1772
|
{activeTab?.label || t("agentPanel.newChat")}
|
|
1732
1773
|
</h1>
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
<DropdownMenuTrigger asChild>
|
|
1738
|
-
<button
|
|
1739
|
-
type="button"
|
|
1740
|
-
data-agent-page-title-menu=""
|
|
1741
|
-
aria-label={t("agentPanel.panelOptions")}
|
|
1742
|
-
className="flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent/60 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring data-[state=open]:bg-accent data-[state=open]:text-foreground"
|
|
1743
|
-
>
|
|
1744
|
-
<IconDotsVertical size={14} />
|
|
1745
|
-
</button>
|
|
1746
|
-
</DropdownMenuTrigger>
|
|
1747
|
-
<DropdownMenuContent
|
|
1748
|
-
align="start"
|
|
1749
|
-
sideOffset={5}
|
|
1750
|
-
className="w-44"
|
|
1751
|
-
onCloseAutoFocus={(event) => {
|
|
1752
|
-
consumeAgentPanelOverlayFocusRestore(
|
|
1753
|
-
pendingHeaderOverlayRef,
|
|
1754
|
-
event,
|
|
1755
|
-
);
|
|
1756
|
-
}}
|
|
1774
|
+
{pageHeaderActions.showPageTitleMenu ? (
|
|
1775
|
+
<DropdownMenu
|
|
1776
|
+
open={headerMenuOpen}
|
|
1777
|
+
onOpenChange={setHeaderMenuOpen}
|
|
1757
1778
|
>
|
|
1758
|
-
|
|
1759
|
-
<
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
toggleHistory,
|
|
1765
|
-
pendingHeaderOverlayRef,
|
|
1766
|
-
)
|
|
1767
|
-
}
|
|
1779
|
+
<DropdownMenuTrigger asChild>
|
|
1780
|
+
<button
|
|
1781
|
+
type="button"
|
|
1782
|
+
data-agent-page-title-menu=""
|
|
1783
|
+
aria-label={t("agentPanel.panelOptions")}
|
|
1784
|
+
className="flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent/60 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring data-[state=open]:bg-accent data-[state=open]:text-foreground"
|
|
1768
1785
|
>
|
|
1769
|
-
<
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1786
|
+
<IconDotsVertical size={14} />
|
|
1787
|
+
</button>
|
|
1788
|
+
</DropdownMenuTrigger>
|
|
1789
|
+
<DropdownMenuContent
|
|
1790
|
+
align="start"
|
|
1791
|
+
sideOffset={5}
|
|
1792
|
+
className="w-44"
|
|
1793
|
+
onCloseAutoFocus={(event) => {
|
|
1794
|
+
consumeAgentPanelOverlayFocusRestore(
|
|
1795
|
+
pendingHeaderOverlayRef,
|
|
1796
|
+
event,
|
|
1797
|
+
);
|
|
1798
|
+
}}
|
|
1799
|
+
>
|
|
1800
|
+
{toggleHistory ? (
|
|
1801
|
+
<DropdownMenuItem
|
|
1802
|
+
onSelect={(event) =>
|
|
1803
|
+
deferAgentPanelOverlayOpen(
|
|
1804
|
+
event,
|
|
1805
|
+
closeHeaderMenuForOverlay,
|
|
1806
|
+
toggleHistory,
|
|
1807
|
+
pendingHeaderOverlayRef,
|
|
1808
|
+
)
|
|
1809
|
+
}
|
|
1810
|
+
>
|
|
1811
|
+
<IconHistory size={14} className="shrink-0" />
|
|
1812
|
+
{showHistory
|
|
1813
|
+
? t("agentPanel.hideChats")
|
|
1814
|
+
: t("agentPanel.allChats")}
|
|
1815
|
+
</DropdownMenuItem>
|
|
1816
|
+
) : null}
|
|
1817
|
+
{activeTabMessageCount > 0 ? (
|
|
1818
|
+
<DropdownMenuItem onSelect={clearActiveTab}>
|
|
1819
|
+
<IconX size={14} className="shrink-0" />
|
|
1820
|
+
{t("agentPanel.clearChat")}
|
|
1821
|
+
</DropdownMenuItem>
|
|
1822
|
+
) : null}
|
|
1823
|
+
</DropdownMenuContent>
|
|
1824
|
+
</DropdownMenu>
|
|
1825
|
+
) : null}
|
|
1783
1826
|
{activeTab?.status === "running" ? (
|
|
1784
1827
|
<span className="size-1.5 shrink-0 rounded-full bg-muted-foreground/55 animate-pulse motion-reduce:animate-none" />
|
|
1785
1828
|
) : null}
|
|
1786
1829
|
</div>
|
|
1787
1830
|
<div className="flex shrink-0 items-center gap-1">
|
|
1788
|
-
{
|
|
1831
|
+
{pageHeaderActions.showShareAction && activeTab ? (
|
|
1789
1832
|
<ShareButton
|
|
1790
1833
|
resourceType="chat_thread"
|
|
1791
1834
|
resourceId={activeTab.id}
|
|
@@ -1798,7 +1841,7 @@ function AgentPanelInner({
|
|
|
1798
1841
|
triggerClassName="size-8 p-0 border-0 bg-transparent shadow-none hover:bg-accent/60"
|
|
1799
1842
|
/>
|
|
1800
1843
|
) : null}
|
|
1801
|
-
{
|
|
1844
|
+
{toolbarSlot}
|
|
1802
1845
|
{showNewChatAction ? (
|
|
1803
1846
|
<button
|
|
1804
1847
|
type="button"
|
|
@@ -1829,6 +1872,7 @@ function AgentPanelInner({
|
|
|
1829
1872
|
pageToolbarSlot,
|
|
1830
1873
|
pendingHeaderOverlayRef,
|
|
1831
1874
|
setHeaderMenuOpen,
|
|
1875
|
+
showPageTitleMenu,
|
|
1832
1876
|
showPageNewChatButton,
|
|
1833
1877
|
t,
|
|
1834
1878
|
],
|