@agent-native/toolkit 0.205.0 → 0.206.0-nightly-20261009011246
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/components.d.ts.map +1 -1
- package/dist/app/agentkit/react/components.js +17 -9
- package/dist/app/agentkit/react/components.js.map +1 -1
- package/dist/app/auth/AuthPage.d.ts.map +1 -1
- package/dist/app/auth/AuthPage.js +11 -0
- package/dist/app/auth/AuthPage.js.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.d.ts +2 -0
- package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.js +24 -14
- package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
- package/dist/app/chat/AgentPanel.d.ts.map +1 -1
- package/dist/app/chat/AgentPanel.js +3 -2
- package/dist/app/chat/AgentPanel.js.map +1 -1
- package/dist/app/chat/MultiTabAssistantChat.d.ts +4 -1
- package/dist/app/chat/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/MultiTabAssistantChat.js +61 -3
- package/dist/app/chat/MultiTabAssistantChat.js.map +1 -1
- package/dist/app/chat/agentkit-chat/approval-card.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/approval-card.js +2 -1
- package/dist/app/chat/agentkit-chat/approval-card.js.map +1 -1
- package/dist/app/chat/chat/run-recovery.d.ts.map +1 -1
- package/dist/app/chat/chat/run-recovery.js +74 -8
- package/dist/app/chat/chat/run-recovery.js.map +1 -1
- package/dist/app/chat/chat/tool-call-display.d.ts.map +1 -1
- package/dist/app/chat/chat/tool-call-display.js +6 -4
- package/dist/app/chat/chat/tool-call-display.js.map +1 -1
- package/dist/app/chat/chat-first/ChatFirstAgentActivityPanel.d.ts.map +1 -1
- package/dist/app/chat/chat-first/ChatFirstAgentActivityPanel.js +2 -1
- package/dist/app/chat/chat-first/ChatFirstAgentActivityPanel.js.map +1 -1
- package/dist/app/chat/conversation/AgentConversation.d.ts.map +1 -1
- package/dist/app/chat/conversation/AgentConversation.js +10 -7
- package/dist/app/chat/conversation/AgentConversation.js.map +1 -1
- package/dist/app/chat/fallback-chat-title.d.ts.map +1 -1
- package/dist/app/chat/fallback-chat-title.js +2 -4
- package/dist/app/chat/fallback-chat-title.js.map +1 -1
- package/dist/app/chat/mcp-apps/McpAppRenderer.d.ts.map +1 -1
- package/dist/app/chat/mcp-apps/McpAppRenderer.js +3 -2
- package/dist/app/chat/mcp-apps/McpAppRenderer.js.map +1 -1
- package/dist/app/chat/session-replay-privacy.d.ts +7 -0
- package/dist/app/chat/session-replay-privacy.d.ts.map +1 -0
- package/dist/app/chat/session-replay-privacy.js +6 -0
- package/dist/app/chat/session-replay-privacy.js.map +1 -0
- package/dist/app/extensions/ExtensionViewer.d.ts +4 -1
- package/dist/app/extensions/ExtensionViewer.d.ts.map +1 -1
- package/dist/app/extensions/ExtensionViewer.js +3 -3
- package/dist/app/extensions/ExtensionViewer.js.map +1 -1
- package/dist/app/extensions/ExtensionViewerPage.d.ts +4 -1
- package/dist/app/extensions/ExtensionViewerPage.d.ts.map +1 -1
- package/dist/app/extensions/ExtensionViewerPage.js +2 -2
- package/dist/app/extensions/ExtensionViewerPage.js.map +1 -1
- package/dist/app/onboarding/FirstRunOnboarding.d.ts.map +1 -1
- package/dist/app/onboarding/FirstRunOnboarding.js +53 -12
- package/dist/app/onboarding/FirstRunOnboarding.js.map +1 -1
- package/dist/app/onboarding/OnboardingPanel.d.ts.map +1 -1
- package/dist/app/onboarding/OnboardingPanel.js +14 -4
- package/dist/app/onboarding/OnboardingPanel.js.map +1 -1
- package/dist/app/resources/ResourceEditor.d.ts +4 -1
- package/dist/app/resources/ResourceEditor.d.ts.map +1 -1
- package/dist/app/resources/ResourceEditor.js +18 -7
- package/dist/app/resources/ResourceEditor.js.map +1 -1
- package/dist/app/resources/ResourcesPanel.d.ts +4 -1
- package/dist/app/resources/ResourcesPanel.d.ts.map +1 -1
- package/dist/app/resources/ResourcesPanel.js +18 -18
- package/dist/app/resources/ResourcesPanel.js.map +1 -1
- package/dist/app/resources/custom-agent-model-options.d.ts +16 -0
- package/dist/app/resources/custom-agent-model-options.d.ts.map +1 -0
- package/dist/app/resources/custom-agent-model-options.js +53 -0
- package/dist/app/resources/custom-agent-model-options.js.map +1 -0
- package/dist/app/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/app/settings/SettingsPanel.js +34 -3
- package/dist/app/settings/SettingsPanel.js.map +1 -1
- package/dist/app/settings/SettingsTabsPage.d.ts.map +1 -1
- package/dist/app/settings/SettingsTabsPage.js +2 -0
- package/dist/app/settings/SettingsTabsPage.js.map +1 -1
- package/dist/app/settings/api-keys/ApiKeyDialogs.d.ts.map +1 -1
- package/dist/app/settings/api-keys/ApiKeyDialogs.js +49 -9
- package/dist/app/settings/api-keys/ApiKeyDialogs.js.map +1 -1
- package/dist/app/settings/api-keys/ApiKeysSettingsPage.js +2 -1
- package/dist/app/settings/api-keys/ApiKeysSettingsPage.js.map +1 -1
- package/dist/app/settings/model/ModelSettingsPage.d.ts.map +1 -1
- package/dist/app/settings/model/ModelSettingsPage.js +43 -9
- package/dist/app/settings/model/ModelSettingsPage.js.map +1 -1
- package/dist/app/settings/model/ProviderDialog.d.ts +4 -0
- package/dist/app/settings/model/ProviderDialog.d.ts.map +1 -1
- package/dist/app/settings/model/ProviderDialog.js +107 -11
- package/dist/app/settings/model/ProviderDialog.js.map +1 -1
- package/dist/app/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/app/settings/useBuilderStatus.js +13 -10
- package/dist/app/settings/useBuilderStatus.js.map +1 -1
- package/dist/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/composer/TiptapComposer.js +51 -13
- package/dist/composer/TiptapComposer.js.map +1 -1
- package/package.json +4 -4
- package/src/app/agentkit/react/components.interaction.spec.tsx +229 -1
- package/src/app/agentkit/react/components.spec.tsx +42 -1
- package/src/app/agentkit/react/components.tsx +46 -12
- package/src/app/auth/AuthPage.tsx +13 -0
- package/src/app/chat/AgentKitAssistantChat.spec.tsx +116 -5
- package/src/app/chat/AgentKitAssistantChat.tsx +41 -20
- package/src/app/chat/AgentPanel.tsx +5 -1
- package/src/app/chat/MultiTabAssistantChat.spec.tsx +152 -7
- package/src/app/chat/MultiTabAssistantChat.tsx +71 -4
- package/src/app/chat/agentkit-chat/approval-card.spec.tsx +17 -0
- package/src/app/chat/agentkit-chat/approval-card.tsx +2 -0
- package/src/app/chat/chat/run-recovery.spec.tsx +354 -9
- package/src/app/chat/chat/run-recovery.tsx +178 -10
- package/src/app/chat/chat/tool-call-display.spec.tsx +77 -0
- package/src/app/chat/chat/tool-call-display.tsx +23 -6
- package/src/app/chat/chat-first/ChatFirstAgentActivityPanel.tsx +2 -1
- package/src/app/chat/conversation/AgentConversation.spec.tsx +190 -1
- package/src/app/chat/conversation/AgentConversation.tsx +32 -8
- package/src/app/chat/fallback-chat-title.spec.ts +44 -0
- package/src/app/chat/fallback-chat-title.ts +3 -4
- package/src/app/chat/mcp-apps/McpAppRenderer.spec.ts +24 -0
- package/src/app/chat/mcp-apps/McpAppRenderer.tsx +10 -2
- package/src/app/chat/session-replay-privacy.spec.ts +14 -0
- package/src/app/chat/session-replay-privacy.ts +5 -0
- package/src/app/extensions/ExtensionViewer.tsx +15 -3
- package/src/app/extensions/ExtensionViewerPage.tsx +7 -3
- package/src/app/onboarding/FirstRunOnboarding.spec.tsx +252 -2
- package/src/app/onboarding/FirstRunOnboarding.tsx +56 -9
- package/src/app/onboarding/OnboardingPanel.save-scope.spec.tsx +1 -0
- package/src/app/onboarding/OnboardingPanel.tsx +15 -3
- package/src/app/resources/ResourceEditor.spec.tsx +240 -5
- package/src/app/resources/ResourceEditor.tsx +57 -10
- package/src/app/resources/ResourcesPanel.spec.ts +86 -4
- package/src/app/resources/ResourcesPanel.tsx +49 -16
- package/src/app/resources/custom-agent-model-options.ts +92 -0
- package/src/app/settings/SettingsPanel.model-defaults.spec.tsx +26 -13
- package/src/app/settings/SettingsPanel.tsx +35 -3
- package/src/app/settings/SettingsTabsPage.spec.tsx +97 -0
- package/src/app/settings/SettingsTabsPage.tsx +2 -0
- package/src/app/settings/api-keys/ApiKeyDialogs.tsx +84 -22
- package/src/app/settings/api-keys/ApiKeysSettingsPage.spec.tsx +229 -1
- package/src/app/settings/api-keys/ApiKeysSettingsPage.tsx +3 -2
- package/src/app/settings/model/ModelSettingsPage.spec.tsx +99 -9
- package/src/app/settings/model/ModelSettingsPage.tsx +79 -11
- package/src/app/settings/model/ProviderDialog.spec.tsx +192 -1
- package/src/app/settings/model/ProviderDialog.tsx +225 -29
- package/src/app/settings/useBuilderStatus.spec.tsx +49 -0
- package/src/app/settings/useBuilderStatus.ts +16 -10
- package/src/composer/TiptapComposer.spec.ts +97 -2
- package/src/composer/TiptapComposer.tsx +67 -13
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/toolkit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.206.0-nightly-20261009011246",
|
|
4
4
|
"description": "Reusable app-building UI and helpers for Agent-Native apps.",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -673,7 +673,7 @@
|
|
|
673
673
|
"y-protocols": "^1.0.7",
|
|
674
674
|
"yjs": "^13.6.33",
|
|
675
675
|
"zod": "^4.3.6",
|
|
676
|
-
"@agent-native/agentkit": "^0.
|
|
676
|
+
"@agent-native/agentkit": "^0.206.0-nightly-20261009011246"
|
|
677
677
|
},
|
|
678
678
|
"devDependencies": {
|
|
679
679
|
"@excalidraw/excalidraw": "0.18.1",
|
|
@@ -697,10 +697,10 @@
|
|
|
697
697
|
"typescript-7": "npm:typescript@^7.0.2",
|
|
698
698
|
"vite": "8.1.0",
|
|
699
699
|
"vitest": "^4.1.5",
|
|
700
|
-
"@agent-native/core": "^0.
|
|
700
|
+
"@agent-native/core": "^0.206.0-nightly-20261009011246"
|
|
701
701
|
},
|
|
702
702
|
"peerDependencies": {
|
|
703
|
-
"@agent-native/core": "
|
|
703
|
+
"@agent-native/core": "0.206.0-nightly-20261009011246",
|
|
704
704
|
"@excalidraw/excalidraw": ">=0.18",
|
|
705
705
|
"@excalidraw/mermaid-to-excalidraw": ">=2",
|
|
706
706
|
"@tanstack/react-query": "^5.99.2",
|
|
@@ -45,11 +45,152 @@ vi.mock("../../../design-system/index.js", async (importOriginal) => {
|
|
|
45
45
|
|
|
46
46
|
import { AgentKitClient } from "@agent-native/agentkit/client";
|
|
47
47
|
import type { AgentTransport } from "@agent-native/agentkit/protocol";
|
|
48
|
+
import {
|
|
49
|
+
SESSION_REPLAY_BLOCK_ATTRIBUTE,
|
|
50
|
+
SESSION_REPLAY_MASK_ATTRIBUTE,
|
|
51
|
+
} from "@agent-native/core/client/session-replay-privacy";
|
|
48
52
|
|
|
49
53
|
import { getComposerDraftKey } from "../../../composer/draft-key.js";
|
|
50
|
-
import {
|
|
54
|
+
import {
|
|
55
|
+
AgentActivityItem,
|
|
56
|
+
AgentInteractionItem,
|
|
57
|
+
AgentKitChat,
|
|
58
|
+
AgentMessageActions,
|
|
59
|
+
} from "./components.js";
|
|
51
60
|
import { AgentKitProvider } from "./context.js";
|
|
52
61
|
|
|
62
|
+
describe("AgentActivityItem replay privacy", () => {
|
|
63
|
+
it.each(["failed", "completed"] as const)(
|
|
64
|
+
"hides only failed activity diagnostics (%s)",
|
|
65
|
+
async (status) => {
|
|
66
|
+
const client = new AgentKitClient({
|
|
67
|
+
transport: {
|
|
68
|
+
async startRun() {
|
|
69
|
+
return { runId: "run-example" };
|
|
70
|
+
},
|
|
71
|
+
async *subscribeToRun() {},
|
|
72
|
+
async cancelRun() {},
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
const container = document.createElement("div");
|
|
76
|
+
document.body.appendChild(container);
|
|
77
|
+
const root = createRoot(container);
|
|
78
|
+
vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true);
|
|
79
|
+
try {
|
|
80
|
+
await act(async () =>
|
|
81
|
+
root.render(
|
|
82
|
+
<AgentKitProvider controller={client} threadId="thread-example">
|
|
83
|
+
<AgentActivityItem
|
|
84
|
+
value={{
|
|
85
|
+
id: "activity-example",
|
|
86
|
+
kind: "tool",
|
|
87
|
+
label: "Example tool",
|
|
88
|
+
status,
|
|
89
|
+
detail: "Example Person's example notes.",
|
|
90
|
+
summary: [
|
|
91
|
+
{ type: "text", text: "Example Document diagnostics." },
|
|
92
|
+
{
|
|
93
|
+
type: "citation",
|
|
94
|
+
title: "Example report",
|
|
95
|
+
url: "https://example.test/report?person=example",
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
}}
|
|
99
|
+
threadId="thread-example"
|
|
100
|
+
/>
|
|
101
|
+
</AgentKitProvider>,
|
|
102
|
+
),
|
|
103
|
+
);
|
|
104
|
+
const disclosure = container.querySelector<HTMLButtonElement>(
|
|
105
|
+
"button[aria-expanded]",
|
|
106
|
+
)!;
|
|
107
|
+
expect(
|
|
108
|
+
disclosure.closest(`[${SESSION_REPLAY_MASK_ATTRIBUTE}]`),
|
|
109
|
+
).toBeNull();
|
|
110
|
+
expect(
|
|
111
|
+
container
|
|
112
|
+
.querySelector(".agentkit-activity-label")
|
|
113
|
+
?.closest(`[${SESSION_REPLAY_MASK_ATTRIBUTE}]`),
|
|
114
|
+
).toBeNull();
|
|
115
|
+
const detail = container.querySelector(".agentkit-activity-detail");
|
|
116
|
+
expect(detail?.hasAttribute(SESSION_REPLAY_MASK_ATTRIBUTE)).toBe(
|
|
117
|
+
status === "failed",
|
|
118
|
+
);
|
|
119
|
+
expect(detail?.hasAttribute("title")).toBe(status !== "failed");
|
|
120
|
+
await act(async () => disclosure.click());
|
|
121
|
+
const summary = container.querySelector(".agentkit-activity-summary");
|
|
122
|
+
expect(summary?.textContent).toContain("Example Document diagnostics.");
|
|
123
|
+
expect(
|
|
124
|
+
summary
|
|
125
|
+
?.querySelector('a[href^="https://example.test/report"]')
|
|
126
|
+
?.closest(`[${SESSION_REPLAY_BLOCK_ATTRIBUTE}]`) !== null,
|
|
127
|
+
).toBe(status === "failed");
|
|
128
|
+
} finally {
|
|
129
|
+
await act(async () => root.unmount());
|
|
130
|
+
await client.shutdown();
|
|
131
|
+
container.remove();
|
|
132
|
+
vi.unstubAllGlobals();
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
describe("AgentInteractionItem replay privacy", () => {
|
|
139
|
+
it.each(["failed", "completed"] as const)(
|
|
140
|
+
"masks only failed interaction details (%s)",
|
|
141
|
+
async (kind) => {
|
|
142
|
+
const client = new AgentKitClient({
|
|
143
|
+
transport: {
|
|
144
|
+
async startRun() {
|
|
145
|
+
return { runId: "run-example" };
|
|
146
|
+
},
|
|
147
|
+
async *subscribeToRun() {},
|
|
148
|
+
async cancelRun() {},
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
const container = document.createElement("div");
|
|
152
|
+
document.body.appendChild(container);
|
|
153
|
+
const root = createRoot(container);
|
|
154
|
+
vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true);
|
|
155
|
+
try {
|
|
156
|
+
await act(async () =>
|
|
157
|
+
root.render(
|
|
158
|
+
<AgentKitProvider controller={client} threadId="thread-example">
|
|
159
|
+
<AgentInteractionItem
|
|
160
|
+
value={{
|
|
161
|
+
id: "interaction-example",
|
|
162
|
+
kind,
|
|
163
|
+
agentId: "agent-example",
|
|
164
|
+
detail: "Example Person's example notes",
|
|
165
|
+
}}
|
|
166
|
+
threadId="thread-example"
|
|
167
|
+
/>
|
|
168
|
+
</AgentKitProvider>,
|
|
169
|
+
),
|
|
170
|
+
);
|
|
171
|
+
const detail = container.querySelector(
|
|
172
|
+
".agentkit-agent-interaction-detail",
|
|
173
|
+
);
|
|
174
|
+
expect(detail?.textContent).toBe("Example Person's example notes");
|
|
175
|
+
expect(detail?.hasAttribute(SESSION_REPLAY_MASK_ATTRIBUTE)).toBe(
|
|
176
|
+
kind === "failed",
|
|
177
|
+
);
|
|
178
|
+
expect(detail?.hasAttribute("title")).toBe(kind !== "failed");
|
|
179
|
+
expect(
|
|
180
|
+
container
|
|
181
|
+
.querySelector(".agentkit-agent-interaction-label")
|
|
182
|
+
?.closest(`[${SESSION_REPLAY_MASK_ATTRIBUTE}]`),
|
|
183
|
+
).toBeNull();
|
|
184
|
+
} finally {
|
|
185
|
+
await act(async () => root.unmount());
|
|
186
|
+
await client.shutdown();
|
|
187
|
+
container.remove();
|
|
188
|
+
vi.unstubAllGlobals();
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
);
|
|
192
|
+
});
|
|
193
|
+
|
|
53
194
|
describe("AgentKitChat interactions", () => {
|
|
54
195
|
it("preserves host submission disablement", async () => {
|
|
55
196
|
const client = new AgentKitClient({
|
|
@@ -1045,6 +1186,93 @@ describe("AgentKitChat interactions", () => {
|
|
|
1045
1186
|
}
|
|
1046
1187
|
});
|
|
1047
1188
|
|
|
1189
|
+
it("masks the default composer's send and attachment errors", async () => {
|
|
1190
|
+
const transport: AgentTransport = {
|
|
1191
|
+
capabilities: { uploads: true },
|
|
1192
|
+
async startRun() {
|
|
1193
|
+
throw new Error("Jane Doe's notes are locked");
|
|
1194
|
+
},
|
|
1195
|
+
async *subscribeToRun() {},
|
|
1196
|
+
async cancelRun() {},
|
|
1197
|
+
};
|
|
1198
|
+
const client = new AgentKitClient({ transport });
|
|
1199
|
+
const container = document.createElement("div");
|
|
1200
|
+
document.body.appendChild(container);
|
|
1201
|
+
const root = createRoot(container);
|
|
1202
|
+
const actEnvironment = globalThis as typeof globalThis & {
|
|
1203
|
+
IS_REACT_ACT_ENVIRONMENT?: boolean;
|
|
1204
|
+
};
|
|
1205
|
+
const previousActEnvironment = actEnvironment.IS_REACT_ACT_ENVIRONMENT;
|
|
1206
|
+
actEnvironment.IS_REACT_ACT_ENVIRONMENT = true;
|
|
1207
|
+
const composerError = (text: string) =>
|
|
1208
|
+
[...container.querySelectorAll(".agentkit-composer-error span")].find(
|
|
1209
|
+
(span) => span.textContent?.includes(text),
|
|
1210
|
+
);
|
|
1211
|
+
|
|
1212
|
+
try {
|
|
1213
|
+
await act(async () => {
|
|
1214
|
+
root.render(
|
|
1215
|
+
<AgentKitProvider controller={client} threadId="thread-errors">
|
|
1216
|
+
<AgentKitChat
|
|
1217
|
+
composerProps={{
|
|
1218
|
+
initialText: "Summarize my notes",
|
|
1219
|
+
modelStatusChecksEnabled: false,
|
|
1220
|
+
}}
|
|
1221
|
+
/>
|
|
1222
|
+
</AgentKitProvider>,
|
|
1223
|
+
);
|
|
1224
|
+
await Promise.resolve();
|
|
1225
|
+
});
|
|
1226
|
+
|
|
1227
|
+
const drop = new Event("drop", { bubbles: true, cancelable: true });
|
|
1228
|
+
Object.defineProperty(drop, "dataTransfer", {
|
|
1229
|
+
value: {
|
|
1230
|
+
types: ["Files"],
|
|
1231
|
+
files: [
|
|
1232
|
+
new File(["zip"], "Jane Doe taxes.zip", {
|
|
1233
|
+
type: "application/zip",
|
|
1234
|
+
}),
|
|
1235
|
+
],
|
|
1236
|
+
dropEffect: "none",
|
|
1237
|
+
},
|
|
1238
|
+
});
|
|
1239
|
+
await act(async () => {
|
|
1240
|
+
container.querySelector(".agentkit-chat")?.dispatchEvent(drop);
|
|
1241
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1242
|
+
});
|
|
1243
|
+
expect(
|
|
1244
|
+
composerError("Jane Doe taxes.zip")?.hasAttribute(
|
|
1245
|
+
SESSION_REPLAY_MASK_ATTRIBUTE,
|
|
1246
|
+
),
|
|
1247
|
+
).toBe(true);
|
|
1248
|
+
|
|
1249
|
+
await act(async () => {
|
|
1250
|
+
container
|
|
1251
|
+
.querySelector<HTMLButtonElement>(
|
|
1252
|
+
'[data-agent-composer-slot="send-button"]',
|
|
1253
|
+
)
|
|
1254
|
+
?.click();
|
|
1255
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1256
|
+
});
|
|
1257
|
+
expect(
|
|
1258
|
+
composerError("Jane Doe's notes are locked")?.hasAttribute(
|
|
1259
|
+
SESSION_REPLAY_MASK_ATTRIBUTE,
|
|
1260
|
+
),
|
|
1261
|
+
).toBe(true);
|
|
1262
|
+
} finally {
|
|
1263
|
+
await act(async () => {
|
|
1264
|
+
root.unmount();
|
|
1265
|
+
await Promise.resolve();
|
|
1266
|
+
});
|
|
1267
|
+
container.remove();
|
|
1268
|
+
if (previousActEnvironment === undefined) {
|
|
1269
|
+
delete actEnvironment.IS_REACT_ACT_ENVIRONMENT;
|
|
1270
|
+
} else {
|
|
1271
|
+
actEnvironment.IS_REACT_ACT_ENVIRONMENT = previousActEnvironment;
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
});
|
|
1275
|
+
|
|
1048
1276
|
it("disables transcript file drops when the host disables uploads", async () => {
|
|
1049
1277
|
const transport: AgentTransport = {
|
|
1050
1278
|
capabilities: { uploads: true },
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
import { ToolkitProvider } from "../../../provider.js";
|
|
18
18
|
import { AgentChat } from "./chat.js";
|
|
19
19
|
import {
|
|
20
|
+
AgentConnectionErrorView,
|
|
20
21
|
AgentKitComposer,
|
|
21
22
|
AgentKitChat,
|
|
22
23
|
type AgentKitComposerProps,
|
|
@@ -32,6 +33,43 @@ import {
|
|
|
32
33
|
} from "./context.js";
|
|
33
34
|
import { AgentKitRoot } from "./root.js";
|
|
34
35
|
|
|
36
|
+
describe("AgentConnectionErrorView replay privacy", () => {
|
|
37
|
+
it("masks connection and recovery messages while preserving the headline and reconnect control", () => {
|
|
38
|
+
const client = new AgentKitClient({
|
|
39
|
+
transport: {
|
|
40
|
+
async startRun() {
|
|
41
|
+
return { runId: "run-example" };
|
|
42
|
+
},
|
|
43
|
+
async *subscribeToRun() {},
|
|
44
|
+
async cancelRun() {},
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
const html = renderToStaticMarkup(
|
|
48
|
+
<AgentKitProvider controller={client} threadId="thread-example">
|
|
49
|
+
<AgentConnectionErrorView
|
|
50
|
+
error={{
|
|
51
|
+
code: "runtime_error",
|
|
52
|
+
message: "Example Person's connection failed.",
|
|
53
|
+
retryable: true,
|
|
54
|
+
}}
|
|
55
|
+
threadId="thread-example"
|
|
56
|
+
recover={async () => {}}
|
|
57
|
+
recovering={false}
|
|
58
|
+
recoveryError={new Error("Example Document recovery failed.")}
|
|
59
|
+
/>
|
|
60
|
+
</AgentKitProvider>,
|
|
61
|
+
);
|
|
62
|
+
expect(html).toContain(
|
|
63
|
+
'<span data-an-mask="">Example Person's connection failed.</span>',
|
|
64
|
+
);
|
|
65
|
+
expect(html).toContain(
|
|
66
|
+
'<span data-an-mask="" class="agentkit-command-error">Example Document recovery failed.</span>',
|
|
67
|
+
);
|
|
68
|
+
expect(html).toContain("<strong>Something went wrong</strong>");
|
|
69
|
+
expect(html).toContain("Reconnect");
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
35
73
|
describe("AgentMessageActions request IDs", () => {
|
|
36
74
|
it("prefers an explicit request ID and never uses the local message ID", () => {
|
|
37
75
|
expect(
|
|
@@ -1782,7 +1820,10 @@ describe("AgentKitChat", () => {
|
|
|
1782
1820
|
expect(defaultHtml.match(/class="agentkit-run-failure"/g)).toHaveLength(1);
|
|
1783
1821
|
expect(defaultHtml).toContain('data-run-id="run-failure"');
|
|
1784
1822
|
expect(defaultHtml).toContain('data-error-code="tool_timeout"');
|
|
1785
|
-
expect(defaultHtml).toContain(
|
|
1823
|
+
expect(defaultHtml).toContain(
|
|
1824
|
+
'<span data-an-mask="">The dashboard check timed out.</span>',
|
|
1825
|
+
);
|
|
1826
|
+
expect(defaultHtml).toContain("<strong>Run failed</strong>");
|
|
1786
1827
|
|
|
1787
1828
|
const slotCalls: AgentRunFailureRenderProps[] = [];
|
|
1788
1829
|
const RunFailure = (props: AgentRunFailureRenderProps) => {
|
|
@@ -138,6 +138,11 @@ import {
|
|
|
138
138
|
} from "./context.js";
|
|
139
139
|
import { AgentStreamingText } from "./streaming-text.js";
|
|
140
140
|
|
|
141
|
+
// AgentKit React installs without @agent-native/core, so it repeats core's
|
|
142
|
+
// replay markers. Its specs assert core's attribute names.
|
|
143
|
+
const SESSION_REPLAY_MASK_PROPS = { "data-an-mask": "" } as const;
|
|
144
|
+
const SESSION_REPLAY_BLOCK_PROPS = { "data-an-block": "" } as const;
|
|
145
|
+
|
|
141
146
|
export interface AgentKitErrorBoundaryProps {
|
|
142
147
|
children: ReactNode;
|
|
143
148
|
resetKey?: string | number;
|
|
@@ -920,7 +925,12 @@ export function AgentInteractionItem({
|
|
|
920
925
|
{object ? (
|
|
921
926
|
<ObjectRenderer value={object} threadId={threadId} />
|
|
922
927
|
) : detail ? (
|
|
923
|
-
<span
|
|
928
|
+
<span
|
|
929
|
+
{...(interaction.kind === "failed"
|
|
930
|
+
? SESSION_REPLAY_MASK_PROPS
|
|
931
|
+
: { title: detail })}
|
|
932
|
+
className="agentkit-agent-interaction-detail"
|
|
933
|
+
>
|
|
924
934
|
{detail}
|
|
925
935
|
</span>
|
|
926
936
|
) : null}
|
|
@@ -987,7 +997,13 @@ export function AgentActivityItem({
|
|
|
987
997
|
</span>
|
|
988
998
|
{object ? <ObjectRenderer value={object} threadId={threadId} /> : null}
|
|
989
999
|
{detail ? (
|
|
990
|
-
|
|
1000
|
+
// Replays mask text but record attributes, so failure text gets no title.
|
|
1001
|
+
<span
|
|
1002
|
+
{...(activity.status === "failed"
|
|
1003
|
+
? SESSION_REPLAY_MASK_PROPS
|
|
1004
|
+
: { title: detail })}
|
|
1005
|
+
className="agentkit-activity-detail"
|
|
1006
|
+
>
|
|
991
1007
|
{detail}
|
|
992
1008
|
</span>
|
|
993
1009
|
) : null}
|
|
@@ -1008,7 +1024,11 @@ export function AgentActivityItem({
|
|
|
1008
1024
|
) : null}
|
|
1009
1025
|
</div>
|
|
1010
1026
|
{open ? (
|
|
1011
|
-
|
|
1027
|
+
// Summary parts can render links, and replays keep their attributes.
|
|
1028
|
+
<div
|
|
1029
|
+
{...(activity.status === "failed" ? SESSION_REPLAY_BLOCK_PROPS : {})}
|
|
1030
|
+
className="agentkit-activity-summary"
|
|
1031
|
+
>
|
|
1012
1032
|
{activity.summary?.map((part, index) => {
|
|
1013
1033
|
const safePart =
|
|
1014
1034
|
part.type === "text"
|
|
@@ -2331,7 +2351,11 @@ export function AgentApprovalPrompt({
|
|
|
2331
2351
|
)}
|
|
2332
2352
|
</div>
|
|
2333
2353
|
{resolution.error ? (
|
|
2334
|
-
<p
|
|
2354
|
+
<p
|
|
2355
|
+
{...SESSION_REPLAY_MASK_PROPS}
|
|
2356
|
+
className="agentkit-command-error"
|
|
2357
|
+
role="alert"
|
|
2358
|
+
>
|
|
2335
2359
|
{resolution.error.message}
|
|
2336
2360
|
</p>
|
|
2337
2361
|
) : null}
|
|
@@ -2452,7 +2476,7 @@ export function AgentConnectionRequestCard({
|
|
|
2452
2476
|
{resolution.error ? (
|
|
2453
2477
|
<div className="agentkit-command-error" role="alert">
|
|
2454
2478
|
<IconAlertCircle aria-hidden="true" className="agentkit-icon" />
|
|
2455
|
-
<span>{resolution.error.message}</span>
|
|
2479
|
+
<span {...SESSION_REPLAY_MASK_PROPS}>{resolution.error.message}</span>
|
|
2456
2480
|
</div>
|
|
2457
2481
|
) : null}
|
|
2458
2482
|
</Surface>
|
|
@@ -2501,7 +2525,11 @@ function AgentWidgetActionButton({
|
|
|
2501
2525
|
{action.label}
|
|
2502
2526
|
</ActionButton>
|
|
2503
2527
|
{invocation.error ? (
|
|
2504
|
-
<span
|
|
2528
|
+
<span
|
|
2529
|
+
{...SESSION_REPLAY_MASK_PROPS}
|
|
2530
|
+
className="agentkit-command-error"
|
|
2531
|
+
role="alert"
|
|
2532
|
+
>
|
|
2505
2533
|
{invocation.error.message}
|
|
2506
2534
|
</span>
|
|
2507
2535
|
) : null}
|
|
@@ -3724,7 +3752,11 @@ export function AgentMessageActions({
|
|
|
3724
3752
|
</>
|
|
3725
3753
|
)}
|
|
3726
3754
|
{actionError ? (
|
|
3727
|
-
<span
|
|
3755
|
+
<span
|
|
3756
|
+
{...SESSION_REPLAY_MASK_PROPS}
|
|
3757
|
+
className="agentkit-command-error"
|
|
3758
|
+
role="alert"
|
|
3759
|
+
>
|
|
3728
3760
|
{actionError.message}
|
|
3729
3761
|
</span>
|
|
3730
3762
|
) : null}
|
|
@@ -3880,7 +3912,7 @@ export function AgentRunFailure({
|
|
|
3880
3912
|
<IconAlertCircle aria-hidden="true" className="agentkit-icon" />
|
|
3881
3913
|
<div className="agentkit-run-failure-copy">
|
|
3882
3914
|
<strong>{labels.runFailed}</strong>
|
|
3883
|
-
<span>{error.message}</span>
|
|
3915
|
+
<span {...SESSION_REPLAY_MASK_PROPS}>{error.message}</span>
|
|
3884
3916
|
{canContinue ? (
|
|
3885
3917
|
<div className="agentkit-error-actions">
|
|
3886
3918
|
<ActionButton
|
|
@@ -3919,7 +3951,7 @@ export function AgentConnectionErrorView({
|
|
|
3919
3951
|
role="alert"
|
|
3920
3952
|
>
|
|
3921
3953
|
<strong>{labels.error}</strong>
|
|
3922
|
-
<span>{error.message}</span>
|
|
3954
|
+
<span {...SESSION_REPLAY_MASK_PROPS}>{error.message}</span>
|
|
3923
3955
|
{error.retryable ? (
|
|
3924
3956
|
<div className="agentkit-error-actions">
|
|
3925
3957
|
<ActionButton
|
|
@@ -3933,7 +3965,9 @@ export function AgentConnectionErrorView({
|
|
|
3933
3965
|
</div>
|
|
3934
3966
|
) : null}
|
|
3935
3967
|
{recoveryError ? (
|
|
3936
|
-
<span className="agentkit-command-error">
|
|
3968
|
+
<span {...SESSION_REPLAY_MASK_PROPS} className="agentkit-command-error">
|
|
3969
|
+
{recoveryError.message}
|
|
3970
|
+
</span>
|
|
3937
3971
|
) : null}
|
|
3938
3972
|
</div>
|
|
3939
3973
|
);
|
|
@@ -4691,13 +4725,13 @@ export function AgentKitComposer({
|
|
|
4691
4725
|
{command.error ? (
|
|
4692
4726
|
<div className="agentkit-composer-error" role="alert">
|
|
4693
4727
|
<IconAlertCircle aria-hidden="true" className="agentkit-icon" />
|
|
4694
|
-
<span>{command.error.message}</span>
|
|
4728
|
+
<span {...SESSION_REPLAY_MASK_PROPS}>{command.error.message}</span>
|
|
4695
4729
|
</div>
|
|
4696
4730
|
) : null}
|
|
4697
4731
|
{attachmentError ? (
|
|
4698
4732
|
<div className="agentkit-composer-error" role="alert">
|
|
4699
4733
|
<IconAlertCircle aria-hidden="true" className="agentkit-icon" />
|
|
4700
|
-
<span>{attachmentError}</span>
|
|
4734
|
+
<span {...SESSION_REPLAY_MASK_PROPS}>{attachmentError}</span>
|
|
4701
4735
|
</div>
|
|
4702
4736
|
) : null}
|
|
4703
4737
|
</div>
|
|
@@ -204,9 +204,22 @@ async function requestJson(
|
|
|
204
204
|
url: string,
|
|
205
205
|
init: RequestInit = {},
|
|
206
206
|
): Promise<AuthRequestResult> {
|
|
207
|
+
const headers = new Headers(init.headers);
|
|
208
|
+
if (typeof window !== "undefined") {
|
|
209
|
+
const requestUrl = new URL(url, window.location.href);
|
|
210
|
+
const sessionId = getAnalyticsSessionId();
|
|
211
|
+
if (
|
|
212
|
+
requestUrl.origin === window.location.origin &&
|
|
213
|
+
sessionId &&
|
|
214
|
+
/^[!-~]{1,127}$/.test(sessionId)
|
|
215
|
+
) {
|
|
216
|
+
headers.set("X-Agent-Native-Session-Id", sessionId);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
207
219
|
const response = await fetch(url, {
|
|
208
220
|
credentials: "include",
|
|
209
221
|
...init,
|
|
222
|
+
headers,
|
|
210
223
|
});
|
|
211
224
|
let data: Record<string, unknown> = {};
|
|
212
225
|
let readable = false;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
// @vitest-environment happy-dom
|
|
2
2
|
|
|
3
3
|
import { AgentKitClient } from "@agent-native/agentkit/client";
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
AgentMessage,
|
|
6
|
+
AgentTransport,
|
|
7
|
+
} from "@agent-native/agentkit/protocol";
|
|
5
8
|
import React, { act, createRef } from "react";
|
|
6
9
|
import { createRoot, type Root } from "react-dom/client";
|
|
7
10
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
@@ -639,6 +642,7 @@ import {
|
|
|
639
642
|
import { AgentKitActionWidget } from "./agentkit-chat/action-widget.js";
|
|
640
643
|
import {
|
|
641
644
|
AgentKitAssistantChat,
|
|
645
|
+
agentMessageTextFromParts,
|
|
642
646
|
type AgentKitAssistantChatProps,
|
|
643
647
|
} from "./AgentKitAssistantChat.js";
|
|
644
648
|
import type {
|
|
@@ -859,7 +863,10 @@ describe("AgentKitAssistantChat host behavior", () => {
|
|
|
859
863
|
parts: [
|
|
860
864
|
{
|
|
861
865
|
type: "text",
|
|
862
|
-
text:
|
|
866
|
+
text: appendAgentChatContextToMessage(
|
|
867
|
+
"Summarize @[the sprint|resource:123] <context>",
|
|
868
|
+
"Private context",
|
|
869
|
+
),
|
|
863
870
|
},
|
|
864
871
|
],
|
|
865
872
|
};
|
|
@@ -902,7 +909,81 @@ describe("AgentKitAssistantChat host behavior", () => {
|
|
|
902
909
|
|
|
903
910
|
expect(savedSnapshots).toHaveBeenCalledWith(
|
|
904
911
|
chatMocks.threadId,
|
|
905
|
-
expect.objectContaining({
|
|
912
|
+
expect.objectContaining({
|
|
913
|
+
title: "Summarize @the sprint <context>",
|
|
914
|
+
preview: "Summarize @[the sprint|resource:123] <context>",
|
|
915
|
+
}),
|
|
916
|
+
);
|
|
917
|
+
});
|
|
918
|
+
|
|
919
|
+
it("strips ambiguous text between legacy blocks across raw message parts", async () => {
|
|
920
|
+
const savedSnapshots = vi.fn();
|
|
921
|
+
const messageParts: AgentMessage["parts"] = [
|
|
922
|
+
{
|
|
923
|
+
type: "text",
|
|
924
|
+
text: "Summarize sprint <context>private first</context>ambiguous private",
|
|
925
|
+
},
|
|
926
|
+
{
|
|
927
|
+
type: "text",
|
|
928
|
+
text: " gap<context>private second</context> visible continuation",
|
|
929
|
+
},
|
|
930
|
+
];
|
|
931
|
+
const message = {
|
|
932
|
+
id: "message-user-legacy-context",
|
|
933
|
+
role: "user",
|
|
934
|
+
status: "complete",
|
|
935
|
+
createdAt: "2026-10-07T12:00:00.000Z",
|
|
936
|
+
parts: messageParts,
|
|
937
|
+
};
|
|
938
|
+
chatMocks.thread = {
|
|
939
|
+
...chatMocks.thread,
|
|
940
|
+
thread: {
|
|
941
|
+
id: chatMocks.threadId,
|
|
942
|
+
title: "",
|
|
943
|
+
createdAt: message.createdAt,
|
|
944
|
+
updatedAt: message.createdAt,
|
|
945
|
+
},
|
|
946
|
+
messages: [message],
|
|
947
|
+
events: [],
|
|
948
|
+
activeRunIds: [],
|
|
949
|
+
runs: {},
|
|
950
|
+
approvals: {},
|
|
951
|
+
approvalRunIds: {},
|
|
952
|
+
connectionRequests: {},
|
|
953
|
+
connectionRequestRunIds: {},
|
|
954
|
+
tools: {},
|
|
955
|
+
activities: {},
|
|
956
|
+
queuedMessages: [],
|
|
957
|
+
tasks: {},
|
|
958
|
+
taskGroups: {},
|
|
959
|
+
widgets: {},
|
|
960
|
+
widgetMessageIds: {},
|
|
961
|
+
annotations: {},
|
|
962
|
+
annotationMessageIds: {},
|
|
963
|
+
agents: {},
|
|
964
|
+
agentInteractions: [],
|
|
965
|
+
artifacts: [],
|
|
966
|
+
};
|
|
967
|
+
|
|
968
|
+
const props = baseProps({
|
|
969
|
+
onSaveThread: savedSnapshots,
|
|
970
|
+
runtime: {} as never,
|
|
971
|
+
});
|
|
972
|
+
await mount(props);
|
|
973
|
+
await act(async () => root.render(null));
|
|
974
|
+
|
|
975
|
+
expect(agentMessageTextFromParts(messageParts)).toBe(
|
|
976
|
+
"Summarize sprint visible continuation",
|
|
977
|
+
);
|
|
978
|
+
expect(savedSnapshots).toHaveBeenCalledWith(
|
|
979
|
+
chatMocks.threadId,
|
|
980
|
+
expect.objectContaining({
|
|
981
|
+
title: "Summarize sprint visible continuation",
|
|
982
|
+
preview: "Summarize sprint visible continuation",
|
|
983
|
+
}),
|
|
984
|
+
);
|
|
985
|
+
expect(savedSnapshots.mock.calls[0]?.[1].preview).not.toContain(
|
|
986
|
+
"ambiguous private",
|
|
906
987
|
);
|
|
907
988
|
});
|
|
908
989
|
|
|
@@ -4511,6 +4592,29 @@ describe("AgentKitAssistantChat host behavior", () => {
|
|
|
4511
4592
|
window.removeEventListener("agent-chat:missing-api-key", onBlocked);
|
|
4512
4593
|
});
|
|
4513
4594
|
|
|
4595
|
+
it("masks a connection failure message without masking recovery controls", async () => {
|
|
4596
|
+
chatMocks.connectionError = {
|
|
4597
|
+
code: "runtime_error",
|
|
4598
|
+
message: "Example Person's example document is locked.",
|
|
4599
|
+
retryable: true,
|
|
4600
|
+
};
|
|
4601
|
+
await mount(baseProps());
|
|
4602
|
+
const message = Array.from(container.querySelectorAll("span")).find(
|
|
4603
|
+
(element) =>
|
|
4604
|
+
element.textContent === `Error: ${chatMocks.connectionError.message}`,
|
|
4605
|
+
);
|
|
4606
|
+
expect(message?.hasAttribute("data-an-mask")).toBe(true);
|
|
4607
|
+
expect(
|
|
4608
|
+
message?.closest('[role="alert"]')?.hasAttribute("data-an-mask"),
|
|
4609
|
+
).toBe(false);
|
|
4610
|
+
expect(
|
|
4611
|
+
message
|
|
4612
|
+
?.closest('[role="alert"]')
|
|
4613
|
+
?.querySelector("button")
|
|
4614
|
+
?.closest("[data-an-mask]"),
|
|
4615
|
+
).toBeNull();
|
|
4616
|
+
});
|
|
4617
|
+
|
|
4514
4618
|
it("does not repeat the composer setup card in a missing-key run failure", async () => {
|
|
4515
4619
|
chatMocks.readiness = {
|
|
4516
4620
|
canChat: false,
|
|
@@ -5078,8 +5182,15 @@ describe("AgentKitAssistantChat host behavior", () => {
|
|
|
5078
5182
|
chatMocks.composerProps.stopButton.props.onClick();
|
|
5079
5183
|
await Promise.resolve();
|
|
5080
5184
|
});
|
|
5081
|
-
|
|
5082
|
-
|
|
5185
|
+
const alert = container.querySelector('[role="alert"]');
|
|
5186
|
+
expect(alert?.textContent).toContain("Stop unavailable");
|
|
5187
|
+
const message = Array.from(alert?.querySelectorAll("span") ?? []).find(
|
|
5188
|
+
(element) => element.textContent === "Stop unavailable",
|
|
5189
|
+
);
|
|
5190
|
+
expect(message?.hasAttribute("data-an-mask")).toBe(true);
|
|
5191
|
+
expect(alert?.hasAttribute("data-an-mask")).toBe(false);
|
|
5192
|
+
expect(alert?.querySelector("button")?.closest("[data-an-mask]")).toBe(
|
|
5193
|
+
null,
|
|
5083
5194
|
);
|
|
5084
5195
|
await act(async () => {
|
|
5085
5196
|
chatMocks.composerProps.stopButton.props.onClick();
|