@agent-native/toolkit 0.221.0-same-host-mcp-20261027-20261027081850 → 0.221.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 +16 -1
- package/dist/app/agentkit/react/components.d.ts +5 -3
- package/dist/app/agentkit/react/components.d.ts.map +1 -1
- package/dist/app/agentkit/react/components.js +103 -42
- package/dist/app/agentkit/react/components.js.map +1 -1
- package/dist/app/agentkit/react/styles.css +93 -65
- package/dist/app/agentkit/react/voice-transcripts.d.ts +22 -1
- package/dist/app/agentkit/react/voice-transcripts.d.ts.map +1 -1
- package/dist/app/agentkit/react/voice-transcripts.js +209 -8
- package/dist/app/agentkit/react/voice-transcripts.js.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.js +55 -40
- package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
- package/dist/app/chat/agentkit-chat/guided-questions.d.ts +1 -0
- package/dist/app/chat/agentkit-chat/guided-questions.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/guided-questions.js +18 -6
- package/dist/app/chat/agentkit-chat/guided-questions.js.map +1 -1
- package/dist/app/chat/agentkit-chat/index.d.ts +1 -1
- package/dist/app/chat/agentkit-chat/index.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/index.js +1 -1
- package/dist/app/chat/agentkit-chat/index.js.map +1 -1
- package/dist/app/chat/chat/run-recovery.d.ts.map +1 -1
- package/dist/app/chat/chat/run-recovery.js +5 -1
- package/dist/app/chat/chat/run-recovery.js.map +1 -1
- package/dist/app/chat/composer/runtime-adapters.d.ts.map +1 -1
- package/dist/app/chat/composer/runtime-adapters.js +2 -0
- package/dist/app/chat/composer/runtime-adapters.js.map +1 -1
- package/dist/app/chat/reply-connection-suggestion.d.ts +29 -0
- package/dist/app/chat/reply-connection-suggestion.d.ts.map +1 -0
- package/dist/app/chat/reply-connection-suggestion.js +42 -0
- package/dist/app/chat/reply-connection-suggestion.js.map +1 -0
- package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.js +7 -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 +7 -0
- package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
- package/dist/app/i18n/catalogs/en-US.d.ts +7 -0
- package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/en-US.js +7 -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 +7 -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 +7 -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 +7 -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 +7 -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 +7 -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 +7 -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 +7 -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 +7 -0
- package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
- package/dist/app/mcp-approval/McpApprovalReview.d.ts +25 -0
- package/dist/app/mcp-approval/McpApprovalReview.d.ts.map +1 -0
- package/dist/app/mcp-approval/McpApprovalReview.js +342 -0
- package/dist/app/mcp-approval/McpApprovalReview.js.map +1 -0
- package/dist/app/onboarding/FirstRunOnboarding.d.ts.map +1 -1
- package/dist/app/onboarding/FirstRunOnboarding.js +299 -71
- package/dist/app/onboarding/FirstRunOnboarding.js.map +1 -1
- package/dist/app/onboarding/GettingStartedCard.js +1 -1
- package/dist/app/onboarding/GettingStartedCard.js.map +1 -1
- package/dist/app/onboarding/first-run-builder-credits-flag.d.ts +2 -0
- package/dist/app/onboarding/first-run-builder-credits-flag.d.ts.map +1 -0
- package/dist/app/onboarding/first-run-builder-credits-flag.js +8 -0
- package/dist/app/onboarding/first-run-builder-credits-flag.js.map +1 -0
- package/dist/app/providers/AppProviders.d.ts.map +1 -1
- package/dist/app/providers/AppProviders.js +14 -1
- package/dist/app/providers/AppProviders.js.map +1 -1
- package/dist/app/resources/McpConnectionSuggestion.d.ts +2 -4
- package/dist/app/resources/McpConnectionSuggestion.d.ts.map +1 -1
- package/dist/app/resources/McpConnectionSuggestion.js +59 -36
- package/dist/app/resources/McpConnectionSuggestion.js.map +1 -1
- package/dist/app/settings/account/PreferencesSettings.d.ts.map +1 -1
- package/dist/app/settings/account/PreferencesSettings.js +14 -1
- package/dist/app/settings/account/PreferencesSettings.js.map +1 -1
- package/dist/app/settings/account/ThemeFamilySettings.js +2 -2
- package/dist/app/settings/account/ThemeFamilySettings.js.map +1 -1
- package/dist/app/settings/account/search-entries.d.ts +1 -0
- package/dist/app/settings/account/search-entries.d.ts.map +1 -1
- package/dist/app/settings/account/search-entries.js +5 -0
- package/dist/app/settings/account/search-entries.js.map +1 -1
- package/dist/app/settings/shell/SettingsShell.d.ts.map +1 -1
- package/dist/app/settings/shell/SettingsShell.js +26 -2
- package/dist/app/settings/shell/SettingsShell.js.map +1 -1
- package/dist/app/shared/AppShellSkeleton.d.ts.map +1 -1
- package/dist/app/shared/AppShellSkeleton.js +4 -10
- package/dist/app/shared/AppShellSkeleton.js.map +1 -1
- package/dist/app/shared/EnvironmentBadge.d.ts +2 -1
- package/dist/app/shared/EnvironmentBadge.d.ts.map +1 -1
- package/dist/app/shared/EnvironmentBadge.js +2 -3
- package/dist/app/shared/EnvironmentBadge.js.map +1 -1
- package/dist/app/shared/is-builder-io-employee.d.ts +8 -0
- package/dist/app/shared/is-builder-io-employee.d.ts.map +1 -0
- package/dist/app/shared/is-builder-io-employee.js +10 -0
- package/dist/app/shared/is-builder-io-employee.js.map +1 -0
- package/dist/app/styles/agent-conversation.css +30 -17
- package/dist/app/styles/theme-families.css +22 -5
- package/dist/app/styles/tokens/agent-kit.css +3 -3
- package/dist/composer/PromptComposer.d.ts +15 -3
- package/dist/composer/PromptComposer.d.ts.map +1 -1
- package/dist/composer/PromptComposer.js +74 -16
- package/dist/composer/PromptComposer.js.map +1 -1
- package/dist/composer/RealtimeVoiceMode.d.ts +7 -0
- package/dist/composer/RealtimeVoiceMode.d.ts.map +1 -1
- package/dist/composer/RealtimeVoiceMode.js +9 -2
- package/dist/composer/RealtimeVoiceMode.js.map +1 -1
- package/dist/composer/TiptapComposer.d.ts +7 -0
- package/dist/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/composer/TiptapComposer.js +12 -4
- package/dist/composer/TiptapComposer.js.map +1 -1
- package/dist/composer/VoiceButton.d.ts +2 -0
- package/dist/composer/VoiceButton.d.ts.map +1 -1
- package/dist/composer/VoiceButton.js +5 -4
- package/dist/composer/VoiceButton.js.map +1 -1
- package/dist/composer/index.d.ts +2 -2
- package/dist/composer/index.d.ts.map +1 -1
- package/dist/composer/index.js +1 -1
- package/dist/composer/index.js.map +1 -1
- package/dist/composer/prompt-attachments.d.ts +20 -0
- package/dist/composer/prompt-attachments.d.ts.map +1 -1
- package/dist/composer/prompt-attachments.js +188 -11
- package/dist/composer/prompt-attachments.js.map +1 -1
- package/dist/composer/realtime-voice-transcript.d.ts +27 -0
- package/dist/composer/realtime-voice-transcript.d.ts.map +1 -1
- package/dist/composer/realtime-voice-transcript.js +34 -1
- package/dist/composer/realtime-voice-transcript.js.map +1 -1
- package/dist/composer/realtime-voice-turn-metrics.d.ts +43 -0
- package/dist/composer/realtime-voice-turn-metrics.d.ts.map +1 -0
- package/dist/composer/realtime-voice-turn-metrics.js +132 -0
- package/dist/composer/realtime-voice-turn-metrics.js.map +1 -0
- package/dist/composer/runtime-adapters.d.ts +4 -1
- package/dist/composer/runtime-adapters.d.ts.map +1 -1
- package/dist/composer/runtime-adapters.js +2 -1
- package/dist/composer/runtime-adapters.js.map +1 -1
- package/dist/composer/useRealtimeVoiceMode.d.ts +61 -9
- package/dist/composer/useRealtimeVoiceMode.d.ts.map +1 -1
- package/dist/composer/useRealtimeVoiceMode.js +536 -99
- package/dist/composer/useRealtimeVoiceMode.js.map +1 -1
- package/dist/composer/voice-chat-icon.d.ts +7 -0
- package/dist/composer/voice-chat-icon.d.ts.map +1 -0
- package/dist/composer/voice-chat-icon.js +14 -0
- package/dist/composer/voice-chat-icon.js.map +1 -0
- package/dist/editor/DragHandle.d.ts +12 -1
- package/dist/editor/DragHandle.d.ts.map +1 -1
- package/dist/editor/DragHandle.js +165 -41
- package/dist/editor/DragHandle.js.map +1 -1
- package/dist/editor/RegistryBlockNode.d.ts +20 -0
- package/dist/editor/RegistryBlockNode.d.ts.map +1 -1
- package/dist/editor/RegistryBlockNode.js +58 -13
- package/dist/editor/RegistryBlockNode.js.map +1 -1
- package/dist/editor/index.d.ts +2 -2
- package/dist/editor/index.d.ts.map +1 -1
- package/dist/editor/index.js +1 -1
- package/dist/editor/index.js.map +1 -1
- package/dist/styles.css +2 -0
- package/dist/ui/dropdown-menu.d.ts.map +1 -1
- package/dist/ui/dropdown-menu.js +5 -1
- package/dist/ui/dropdown-menu.js.map +1 -1
- package/package.json +14 -4
- package/src/app/agentkit/react/components.regenerate-readiness.spec.tsx +3 -1
- package/src/app/agentkit/react/components.spec.tsx +24 -4
- package/src/app/agentkit/react/components.tsx +174 -44
- package/src/app/agentkit/react/composer-context.spec.tsx +3 -0
- package/src/app/agentkit/react/disclosures.spec.tsx +124 -0
- package/src/app/agentkit/react/lifecycle.spec.tsx +8 -2
- package/src/app/agentkit/react/message-actions.spec.tsx +161 -5
- package/src/app/agentkit/react/saved-reply-reload.spec.tsx +206 -0
- package/src/app/agentkit/react/styles.css +93 -65
- package/src/app/agentkit/react/voice-transcripts.spec.tsx +239 -4
- package/src/app/agentkit/react/voice-transcripts.ts +245 -8
- package/src/app/chat/AgentKitAssistantChat.spec.tsx +59 -11
- package/src/app/chat/AgentKitAssistantChat.tsx +74 -62
- package/src/app/chat/agentkit-chat/guided-answers-context.spec.ts +9 -0
- package/src/app/chat/agentkit-chat/guided-questions.tsx +17 -7
- package/src/app/chat/agentkit-chat/index.ts +1 -0
- package/src/app/chat/chat/run-recovery.spec.tsx +45 -0
- package/src/app/chat/chat/run-recovery.tsx +6 -1
- package/src/app/chat/composer/runtime-adapters.tsx +2 -0
- package/src/app/chat/reply-connection-suggestion.spec.ts +121 -0
- package/src/app/chat/reply-connection-suggestion.ts +76 -0
- package/src/app/i18n/catalogs/ar-SA.ts +10 -0
- package/src/app/i18n/catalogs/de-DE.ts +10 -0
- package/src/app/i18n/catalogs/en-US.ts +10 -0
- package/src/app/i18n/catalogs/es-ES.ts +10 -0
- package/src/app/i18n/catalogs/fr-FR.ts +10 -0
- package/src/app/i18n/catalogs/hi-IN.ts +10 -0
- package/src/app/i18n/catalogs/ja-JP.ts +10 -0
- package/src/app/i18n/catalogs/ko-KR.ts +10 -0
- package/src/app/i18n/catalogs/pt-BR.ts +10 -0
- package/src/app/i18n/catalogs/zh-CN.ts +10 -0
- package/src/app/i18n/catalogs/zh-TW.ts +10 -0
- package/src/app/mcp-approval/McpApprovalReview.spec.tsx +687 -0
- package/src/app/mcp-approval/McpApprovalReview.tsx +913 -0
- package/src/app/onboarding/FirstRunOnboarding.spec.tsx +736 -26
- package/src/app/onboarding/FirstRunOnboarding.tsx +473 -145
- package/src/app/onboarding/GettingStartedCard.tsx +1 -1
- package/src/app/onboarding/first-run-builder-credits-flag.spec.ts +13 -0
- package/src/app/onboarding/first-run-builder-credits-flag.ts +9 -0
- package/src/app/providers/AppProviders.spec.tsx +109 -0
- package/src/app/providers/AppProviders.tsx +53 -1
- package/src/app/resources/McpConnectionSuggestion.spec.ts +77 -12
- package/src/app/resources/McpConnectionSuggestion.tsx +69 -51
- package/src/app/settings/VoiceChatSettings.spec.tsx +6 -1
- package/src/app/settings/account/PreferencesSettings.spec.tsx +73 -0
- package/src/app/settings/account/PreferencesSettings.tsx +24 -7
- package/src/app/settings/account/ThemeFamilySettings.tsx +2 -2
- package/src/app/settings/account/search-entries.spec.ts +14 -0
- package/src/app/settings/account/search-entries.ts +9 -0
- package/src/app/settings/shell/SettingsShell.tsx +29 -2
- package/src/app/shared/AppShellSkeleton.spec.tsx +2 -2
- package/src/app/shared/AppShellSkeleton.tsx +3 -16
- package/src/app/shared/EnvironmentBadge.tsx +3 -4
- package/src/app/shared/is-builder-io-employee.ts +17 -0
- package/src/app/styles/agent-conversation.css +30 -17
- package/src/app/styles/theme-families.css +22 -5
- package/src/app/styles/theme-families.spec.ts +73 -0
- package/src/app/styles/tokens/agent-kit.css +3 -3
- package/src/composer/AgentSuggestionBar.overflow.spec.tsx +1 -1
- package/src/composer/AttachmentChip.spec.tsx +87 -0
- package/src/composer/PromptComposer.context.spec.tsx +8 -4
- package/src/composer/PromptComposer.setup-card.spec.tsx +170 -0
- package/src/composer/PromptComposer.tsx +125 -14
- package/src/composer/RealtimeVoiceMode.spec.tsx +48 -0
- package/src/composer/RealtimeVoiceMode.tsx +45 -2
- package/src/composer/TiptapComposer.tsx +25 -0
- package/src/composer/TiptapComposer.voice-toolbar.spec.tsx +4 -1
- package/src/composer/VoiceButton.tsx +8 -3
- package/src/composer/index.ts +4 -0
- package/src/composer/prompt-attachments.spec.ts +160 -8
- package/src/composer/prompt-attachments.ts +221 -12
- package/src/composer/realtime-voice-transcript.spec.ts +36 -0
- package/src/composer/realtime-voice-transcript.ts +56 -1
- package/src/composer/realtime-voice-turn-metrics.spec.ts +175 -0
- package/src/composer/realtime-voice-turn-metrics.ts +192 -0
- package/src/composer/runtime-adapters.tsx +5 -1
- package/src/composer/useRealtimeVoiceMode.session.spec.tsx +487 -2
- package/src/composer/useRealtimeVoiceMode.spec.ts +267 -65
- package/src/composer/useRealtimeVoiceMode.tsx +716 -139
- package/src/composer/voice-chat-icon.tsx +19 -0
- package/src/editor/DragHandle.spec.ts +217 -0
- package/src/editor/DragHandle.ts +214 -55
- package/src/editor/RegistryBlockNode.spec.ts +172 -2
- package/src/editor/RegistryBlockNode.tsx +91 -13
- package/src/editor/index.ts +4 -0
- package/src/styles.css +2 -0
- package/src/ui/dropdown-menu.tsx +4 -0
|
@@ -1152,8 +1152,14 @@ describe("AgentChat lifecycle", () => {
|
|
|
1152
1152
|
revision: 2,
|
|
1153
1153
|
});
|
|
1154
1154
|
await flush();
|
|
1155
|
-
|
|
1156
|
-
|
|
1155
|
+
// The saved reply kept no reasoning, so only the turn's time is left, and
|
|
1156
|
+
// with no model or usage recorded it has nothing to open to.
|
|
1157
|
+
const settled = tree.container.querySelectorAll<HTMLElement>(
|
|
1158
|
+
".agentkit-activities",
|
|
1159
|
+
);
|
|
1160
|
+
expect(settled).toHaveLength(1);
|
|
1161
|
+
expect(settled[0]?.dataset.expandable).toBe("false");
|
|
1162
|
+
expect(settled[0]?.textContent).toBe("Worked for 4s");
|
|
1157
1163
|
expect(
|
|
1158
1164
|
tree.container
|
|
1159
1165
|
.querySelector('[data-message-id="assistant-1"]')
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
// @vitest-environment happy-dom
|
|
2
2
|
|
|
3
3
|
import { AgentKitClient } from "@agent-native/agentkit/client";
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
import {
|
|
5
|
+
createAgentKitProtocolVersionOffer,
|
|
6
|
+
createCapabilityUnavailableError,
|
|
7
|
+
negotiateAgentKitProtocolVersion,
|
|
8
|
+
parseAgentCapabilitiesDiscovery,
|
|
9
|
+
type AgentEvent,
|
|
10
|
+
type AgentMessage,
|
|
11
|
+
type AgentToolCall,
|
|
12
|
+
type AgentTransport,
|
|
9
13
|
} from "@agent-native/agentkit/protocol";
|
|
10
14
|
import { act, type ReactNode } from "react";
|
|
11
15
|
import { createRoot } from "react-dom/client";
|
|
@@ -284,6 +288,111 @@ describe("assistant reply toolbar", () => {
|
|
|
284
288
|
expect(labelsOf(set(older, "secondary"))).toEqual(["Fork from here"]);
|
|
285
289
|
});
|
|
286
290
|
|
|
291
|
+
it("names each icon-only action in a tooltip on hover", async () => {
|
|
292
|
+
const { container, toolbar } = await renderChat();
|
|
293
|
+
const latest = toolbar("assistant-latest");
|
|
294
|
+
const user = container.querySelector<HTMLElement>(
|
|
295
|
+
'[data-message-id="user-2"] .agentkit-message-actions',
|
|
296
|
+
)!;
|
|
297
|
+
const hoverName = async (button: HTMLButtonElement) => {
|
|
298
|
+
vi.useFakeTimers();
|
|
299
|
+
try {
|
|
300
|
+
await act(async () => {
|
|
301
|
+
button.dispatchEvent(
|
|
302
|
+
new PointerEvent("pointermove", {
|
|
303
|
+
bubbles: true,
|
|
304
|
+
pointerType: "mouse",
|
|
305
|
+
}),
|
|
306
|
+
);
|
|
307
|
+
vi.advanceTimersByTime(1000);
|
|
308
|
+
});
|
|
309
|
+
const name = document.querySelector('[role="tooltip"]')?.textContent;
|
|
310
|
+
await act(async () => {
|
|
311
|
+
button.dispatchEvent(
|
|
312
|
+
new PointerEvent("pointerleave", {
|
|
313
|
+
bubbles: true,
|
|
314
|
+
pointerType: "mouse",
|
|
315
|
+
}),
|
|
316
|
+
);
|
|
317
|
+
vi.advanceTimersByTime(1000);
|
|
318
|
+
});
|
|
319
|
+
return name;
|
|
320
|
+
} finally {
|
|
321
|
+
vi.useRealTimers();
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
const names: Array<string | null | undefined> = [];
|
|
326
|
+
const hoverAll = async (scope: HTMLElement) => {
|
|
327
|
+
for (const button of Array.from(scope.querySelectorAll("button"))) {
|
|
328
|
+
// The idle set is inert, so only the open set's actions can be hovered.
|
|
329
|
+
if (!button.closest("[inert]")) names.push(await hoverName(button));
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
await hoverAll(latest);
|
|
333
|
+
await press(toggle(latest));
|
|
334
|
+
await hoverAll(set(latest, "secondary")!);
|
|
335
|
+
await hoverAll(user);
|
|
336
|
+
expect(names).toEqual([
|
|
337
|
+
"Copy message",
|
|
338
|
+
"Good response",
|
|
339
|
+
"Bad response",
|
|
340
|
+
"More actions",
|
|
341
|
+
"Retry",
|
|
342
|
+
"Fork from here",
|
|
343
|
+
"Copy request ID",
|
|
344
|
+
"Copy message",
|
|
345
|
+
]);
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
it("shows a degraded action's reason in its tooltip, not a second native title", async () => {
|
|
349
|
+
const reason = "Feedback is queued and may take a minute to record.";
|
|
350
|
+
const { toolbar } = await renderChat({
|
|
351
|
+
transport: {
|
|
352
|
+
async discoverCapabilities() {
|
|
353
|
+
return parseAgentCapabilitiesDiscovery({
|
|
354
|
+
protocol: negotiateAgentKitProtocolVersion(
|
|
355
|
+
createAgentKitProtocolVersionOffer(),
|
|
356
|
+
),
|
|
357
|
+
discoveredAt: "2026-10-23T00:00:00.000Z",
|
|
358
|
+
capabilities: [
|
|
359
|
+
{ id: "threadForking", state: "available" },
|
|
360
|
+
{
|
|
361
|
+
id: "feedback",
|
|
362
|
+
state: "degraded",
|
|
363
|
+
error: createCapabilityUnavailableError("feedback", {
|
|
364
|
+
message: reason,
|
|
365
|
+
retryable: true,
|
|
366
|
+
}),
|
|
367
|
+
},
|
|
368
|
+
],
|
|
369
|
+
});
|
|
370
|
+
},
|
|
371
|
+
},
|
|
372
|
+
});
|
|
373
|
+
const good = thumb(toolbar("assistant-latest"), "positive");
|
|
374
|
+
|
|
375
|
+
expect(good.disabled).toBe(false);
|
|
376
|
+
expect(good.hasAttribute("title")).toBe(false);
|
|
377
|
+
vi.useFakeTimers();
|
|
378
|
+
try {
|
|
379
|
+
await act(async () => {
|
|
380
|
+
good.dispatchEvent(
|
|
381
|
+
new PointerEvent("pointermove", {
|
|
382
|
+
bubbles: true,
|
|
383
|
+
pointerType: "mouse",
|
|
384
|
+
}),
|
|
385
|
+
);
|
|
386
|
+
vi.advanceTimersByTime(1000);
|
|
387
|
+
});
|
|
388
|
+
} finally {
|
|
389
|
+
vi.useRealTimers();
|
|
390
|
+
}
|
|
391
|
+
expect(document.querySelector('[role="tooltip"]')?.textContent).toBe(
|
|
392
|
+
`Good response${reason}`,
|
|
393
|
+
);
|
|
394
|
+
});
|
|
395
|
+
|
|
287
396
|
it("shows More as pressed while its actions are open, past its hover fill", async () => {
|
|
288
397
|
const { toolbar } = await renderChat();
|
|
289
398
|
const more = toggle(toolbar("assistant-latest"));
|
|
@@ -618,6 +727,53 @@ describe("Worked for run details", () => {
|
|
|
618
727
|
).toBe("1");
|
|
619
728
|
}
|
|
620
729
|
|
|
730
|
+
const charged = await renderChat({
|
|
731
|
+
loadRunUsage: async () => ({
|
|
732
|
+
durationMs: null,
|
|
733
|
+
billing: {
|
|
734
|
+
providerCostUsd: 0.02,
|
|
735
|
+
providerCostSource: "reported" as const,
|
|
736
|
+
builderCredits: 0,
|
|
737
|
+
builderCreditsSource: "estimated" as const,
|
|
738
|
+
incomplete: false,
|
|
739
|
+
},
|
|
740
|
+
}),
|
|
741
|
+
events: runEvents("run-latest", [...toolWork], latestAnswer),
|
|
742
|
+
});
|
|
743
|
+
await press(
|
|
744
|
+
charged.container.querySelector(".agentkit-activities-summary"),
|
|
745
|
+
);
|
|
746
|
+
await act(async () => {
|
|
747
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
748
|
+
});
|
|
749
|
+
const charge = charged.container.querySelector('[data-detail="credits"]');
|
|
750
|
+
expect(charge?.querySelector("dt")?.textContent).toBe("Cost");
|
|
751
|
+
expect(charge?.querySelector("dd")?.textContent).toBe("$0.02");
|
|
752
|
+
|
|
753
|
+
// Auto names no model, so with no steps the zero is the only detail left
|
|
754
|
+
// and still shows.
|
|
755
|
+
const alone = await renderChat({
|
|
756
|
+
followUpModel: "auto",
|
|
757
|
+
loadRunUsage: async () => ({
|
|
758
|
+
durationMs: null,
|
|
759
|
+
billing: {
|
|
760
|
+
providerCostUsd: 0,
|
|
761
|
+
providerCostSource: "reported" as const,
|
|
762
|
+
builderCredits: 0,
|
|
763
|
+
builderCreditsSource: "estimated" as const,
|
|
764
|
+
incomplete: false,
|
|
765
|
+
},
|
|
766
|
+
}),
|
|
767
|
+
events: runEvents("run-latest", [], latestAnswer),
|
|
768
|
+
});
|
|
769
|
+
await press(alone.container.querySelector(".agentkit-activities-summary"));
|
|
770
|
+
await act(async () => {
|
|
771
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
772
|
+
});
|
|
773
|
+
expect(
|
|
774
|
+
alone.container.querySelector('[data-detail="credits"] dd')?.textContent,
|
|
775
|
+
).toMatch(/^0\.0\b/);
|
|
776
|
+
|
|
621
777
|
const unrecorded = await renderChat({
|
|
622
778
|
loadRunUsage: async () => ({ durationMs: null, billing: null }),
|
|
623
779
|
events: runEvents("run-latest", [...toolWork], latestAnswer),
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
// @vitest-environment happy-dom
|
|
2
|
+
|
|
3
|
+
import { AgentKitClient } from "@agent-native/agentkit/client";
|
|
4
|
+
import { createAgentNativeAgentKitTransport } from "@agent-native/core/client/agentkit-chat/transport";
|
|
5
|
+
import { act } from "react";
|
|
6
|
+
import { createRoot, type Root } from "react-dom/client";
|
|
7
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
8
|
+
|
|
9
|
+
import { AgentKitChat } from "./components.js";
|
|
10
|
+
import { AgentKitProvider } from "./context.js";
|
|
11
|
+
|
|
12
|
+
const threadId = "thread-saved-reply-reload";
|
|
13
|
+
const runId = "run-saved-reply-reload";
|
|
14
|
+
const turnId = "turn-saved-reply-reload";
|
|
15
|
+
const promptId = "message-prompt";
|
|
16
|
+
const streamedId = "message-streamed-reply";
|
|
17
|
+
const startedAt = Date.parse("2026-10-26T21:43:54.411Z");
|
|
18
|
+
const completedAt = startedAt + 19_193;
|
|
19
|
+
const streamedAnswer = "Here are the main answers so you can pick.";
|
|
20
|
+
const savedAnswer = "Here are the main answers, so you can pick your own.";
|
|
21
|
+
|
|
22
|
+
function iso(ms: number): string {
|
|
23
|
+
return new Date(ms).toISOString();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function event(sequence: number, occurredAt: number, body: object) {
|
|
27
|
+
return {
|
|
28
|
+
id: `${runId}:${sequence}`,
|
|
29
|
+
threadId,
|
|
30
|
+
runId,
|
|
31
|
+
sequence,
|
|
32
|
+
occurredAt: iso(occurredAt),
|
|
33
|
+
...body,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const activity = {
|
|
38
|
+
id: "activity-read",
|
|
39
|
+
kind: "read",
|
|
40
|
+
label: "Read the brief",
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// The thread as the server saves it: its own copy of the reply under its own
|
|
44
|
+
// id, beside the chat's copy under the id the run's events use.
|
|
45
|
+
const storedThread = {
|
|
46
|
+
id: threadId,
|
|
47
|
+
threadData: JSON.stringify({
|
|
48
|
+
messages: [
|
|
49
|
+
{
|
|
50
|
+
message: {
|
|
51
|
+
id: `server-user-${runId}`,
|
|
52
|
+
role: "user",
|
|
53
|
+
content: [{ type: "text", text: "Compare them" }],
|
|
54
|
+
metadata: {
|
|
55
|
+
custom: {
|
|
56
|
+
submittedRunId: runId,
|
|
57
|
+
submittedTurnId: turnId,
|
|
58
|
+
agentKitMessageId: promptId,
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
parentId: null,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
message: {
|
|
66
|
+
id: `server-${runId}`,
|
|
67
|
+
role: "assistant",
|
|
68
|
+
status: { type: "complete", reason: "stop" },
|
|
69
|
+
content: [{ type: "text", text: savedAnswer }],
|
|
70
|
+
metadata: {
|
|
71
|
+
runId,
|
|
72
|
+
custom: {
|
|
73
|
+
turnId,
|
|
74
|
+
foldedRunIds: [runId],
|
|
75
|
+
agentNativeRunDurationMs: 19_027,
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
parentId: `server-user-${runId}`,
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
agentKit: {
|
|
83
|
+
messages: [
|
|
84
|
+
{
|
|
85
|
+
id: promptId,
|
|
86
|
+
role: "user",
|
|
87
|
+
parts: [{ type: "text", text: "Compare them" }],
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
id: streamedId,
|
|
91
|
+
role: "assistant",
|
|
92
|
+
status: "complete",
|
|
93
|
+
parts: [{ type: "text", text: streamedAnswer }],
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
events: [
|
|
97
|
+
event(1, startedAt, { type: "run.started" }),
|
|
98
|
+
event(2, startedAt + 200, {
|
|
99
|
+
type: "activity.started",
|
|
100
|
+
activity: { ...activity, status: "running" },
|
|
101
|
+
}),
|
|
102
|
+
event(3, startedAt + 1_200, {
|
|
103
|
+
type: "activity.completed",
|
|
104
|
+
activity: { ...activity, status: "completed" },
|
|
105
|
+
}),
|
|
106
|
+
event(4, completedAt, {
|
|
107
|
+
type: "message.completed",
|
|
108
|
+
message: {
|
|
109
|
+
id: streamedId,
|
|
110
|
+
role: "assistant",
|
|
111
|
+
status: "complete",
|
|
112
|
+
parts: [{ type: "text", text: streamedAnswer }],
|
|
113
|
+
},
|
|
114
|
+
}),
|
|
115
|
+
event(5, completedAt, { type: "run.completed" }),
|
|
116
|
+
],
|
|
117
|
+
runs: [
|
|
118
|
+
{
|
|
119
|
+
id: runId,
|
|
120
|
+
threadId,
|
|
121
|
+
status: "completed",
|
|
122
|
+
startedAt: iso(startedAt),
|
|
123
|
+
completedAt: iso(completedAt),
|
|
124
|
+
lastSequence: 5,
|
|
125
|
+
activeMessageId: streamedId,
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
activeRunIds: [],
|
|
129
|
+
suggestions: [],
|
|
130
|
+
},
|
|
131
|
+
}),
|
|
132
|
+
runLifecycles: {
|
|
133
|
+
queriedRunIds: [runId],
|
|
134
|
+
runs: [
|
|
135
|
+
{
|
|
136
|
+
id: runId,
|
|
137
|
+
status: "completed",
|
|
138
|
+
startedAt,
|
|
139
|
+
completedAt,
|
|
140
|
+
errorCode: null,
|
|
141
|
+
abortReason: null,
|
|
142
|
+
terminalReason: "done",
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
function json(value: unknown): Response {
|
|
149
|
+
return new Response(JSON.stringify(value), {
|
|
150
|
+
status: 200,
|
|
151
|
+
headers: { "content-type": "application/json" },
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
let client: AgentKitClient | undefined;
|
|
156
|
+
let container: HTMLDivElement;
|
|
157
|
+
let root: Root;
|
|
158
|
+
|
|
159
|
+
beforeEach(() => {
|
|
160
|
+
vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true);
|
|
161
|
+
container = document.createElement("div");
|
|
162
|
+
document.body.append(container);
|
|
163
|
+
root = createRoot(container);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
afterEach(async () => {
|
|
167
|
+
await act(async () => root.unmount());
|
|
168
|
+
client?.dispose();
|
|
169
|
+
client = undefined;
|
|
170
|
+
container.remove();
|
|
171
|
+
vi.unstubAllGlobals();
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
describe("reloading a thread whose saved reply differs from the stream", () => {
|
|
175
|
+
it("shows the saved reply with its Worked for row", async () => {
|
|
176
|
+
const transport = createAgentNativeAgentKitTransport({
|
|
177
|
+
fetch: vi.fn(async (input: string | URL | Request) =>
|
|
178
|
+
String(input).includes("/runs/active")
|
|
179
|
+
? json({ active: false, status: "completed", runId })
|
|
180
|
+
: json(storedThread),
|
|
181
|
+
) as typeof fetch,
|
|
182
|
+
});
|
|
183
|
+
client = new AgentKitClient({ transport });
|
|
184
|
+
await client.loadThread(threadId);
|
|
185
|
+
await act(async () =>
|
|
186
|
+
root.render(
|
|
187
|
+
<AgentKitProvider controller={client!} threadId={threadId}>
|
|
188
|
+
<AgentKitChat composer={false} />
|
|
189
|
+
</AgentKitProvider>,
|
|
190
|
+
),
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
const transcript = container.querySelector(".agentkit-transcript")!;
|
|
194
|
+
const replies = transcript.querySelectorAll(
|
|
195
|
+
'[data-message-id][data-role="assistant"]',
|
|
196
|
+
);
|
|
197
|
+
expect(
|
|
198
|
+
[...replies].map((reply) => reply.getAttribute("data-message-id")),
|
|
199
|
+
).toEqual([streamedId]);
|
|
200
|
+
expect(replies[0]?.textContent).toContain(savedAnswer);
|
|
201
|
+
expect(transcript.textContent).not.toContain(streamedAnswer);
|
|
202
|
+
expect(
|
|
203
|
+
transcript.querySelector(".agentkit-activities-label")?.textContent,
|
|
204
|
+
).toBe("Worked for 19s");
|
|
205
|
+
});
|
|
206
|
+
});
|