@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
|
@@ -66,7 +66,10 @@ import { buildSignInReturnHref } from "@agent-native/core/client/sign-in-return"
|
|
|
66
66
|
import { useFileUploadStatus } from "@agent-native/core/client/uploads";
|
|
67
67
|
import { useSession } from "@agent-native/core/client/use-session";
|
|
68
68
|
import { AGENTKIT_CHAT_MIGRATION_GUIDE_URL } from "@agent-native/core/package-lifecycle/migration-message";
|
|
69
|
-
import {
|
|
69
|
+
import {
|
|
70
|
+
splitAgentChatContextFromMessage,
|
|
71
|
+
stripAgentChatContextFromMessage,
|
|
72
|
+
} from "@agent-native/core/shared";
|
|
70
73
|
import { writeClipboardText } from "@agent-native/toolkit/clipboard";
|
|
71
74
|
import {
|
|
72
75
|
AgentSuggestionBar,
|
|
@@ -177,6 +180,7 @@ import { formatFeedbackReport } from "./feedback-report.js";
|
|
|
177
180
|
import { FileStorageSetupPopover } from "./FileStorageSetupPopover.js";
|
|
178
181
|
import { reconcileSettledRun } from "./reconcile-settled-run.js";
|
|
179
182
|
import { RunStuckBanner } from "./RunStuckBanner.js";
|
|
183
|
+
import { SESSION_REPLAY_MASK_PROPS } from "./session-replay-privacy.js";
|
|
180
184
|
import { ThinkingDisplayProvider } from "./thinking-display.js";
|
|
181
185
|
|
|
182
186
|
export interface AgentKitAssistantChatProps extends AssistantChatProps {
|
|
@@ -4333,7 +4337,10 @@ function AgentKitComposerSurface({
|
|
|
4333
4337
|
className="mx-3 mb-1.5 flex shrink-0 items-start gap-2 rounded-md border border-border bg-muted/70 px-3 py-2 text-xs text-foreground shadow-sm"
|
|
4334
4338
|
>
|
|
4335
4339
|
<IconAlertTriangle className="mt-0.5 h-3.5 w-3.5 shrink-0 text-muted-foreground" />
|
|
4336
|
-
<span
|
|
4340
|
+
<span
|
|
4341
|
+
{...SESSION_REPLAY_MASK_PROPS}
|
|
4342
|
+
className="min-w-0 flex-1 break-words leading-snug"
|
|
4343
|
+
>
|
|
4337
4344
|
{composerError}
|
|
4338
4345
|
</span>
|
|
4339
4346
|
<button
|
|
@@ -5044,7 +5051,9 @@ function AgentKitConnectionError({
|
|
|
5044
5051
|
</a>
|
|
5045
5052
|
</>
|
|
5046
5053
|
) : (
|
|
5047
|
-
<span
|
|
5054
|
+
<span {...SESSION_REPLAY_MASK_PROPS}>
|
|
5055
|
+
{formatAgentKitErrorText(error, t)}
|
|
5056
|
+
</span>
|
|
5048
5057
|
)}
|
|
5049
5058
|
{error.retryable ? (
|
|
5050
5059
|
<button
|
|
@@ -5059,7 +5068,11 @@ function AgentKitConnectionError({
|
|
|
5059
5068
|
</button>
|
|
5060
5069
|
) : null}
|
|
5061
5070
|
{recoveryError ? (
|
|
5062
|
-
<span
|
|
5071
|
+
<span
|
|
5072
|
+
{...SESSION_REPLAY_MASK_PROPS}
|
|
5073
|
+
className="mt-2 block"
|
|
5074
|
+
role="alert"
|
|
5075
|
+
>
|
|
5063
5076
|
{formatAgentKitErrorText(
|
|
5064
5077
|
{ code: "runtime_error", message: recoveryError.message },
|
|
5065
5078
|
t,
|
|
@@ -5390,17 +5403,27 @@ async function uploadAgentChatAttachments(
|
|
|
5390
5403
|
);
|
|
5391
5404
|
}
|
|
5392
5405
|
|
|
5393
|
-
function
|
|
5394
|
-
return
|
|
5406
|
+
function rawAgentMessageTextFromParts(parts: AgentMessage["parts"]): string {
|
|
5407
|
+
return parts
|
|
5395
5408
|
.filter((part) => part.type === "text")
|
|
5396
|
-
.map((part) =>
|
|
5397
|
-
part.type === "text"
|
|
5398
|
-
? splitAgentChatContextFromMessage(part.text).message
|
|
5399
|
-
: "",
|
|
5400
|
-
)
|
|
5409
|
+
.map((part) => (part.type === "text" ? part.text : ""))
|
|
5401
5410
|
.join("\n");
|
|
5402
5411
|
}
|
|
5403
5412
|
|
|
5413
|
+
export function agentMessageTextFromParts(
|
|
5414
|
+
parts: AgentMessage["parts"],
|
|
5415
|
+
): string {
|
|
5416
|
+
return stripAgentChatContextFromMessage(rawAgentMessageTextFromParts(parts));
|
|
5417
|
+
}
|
|
5418
|
+
|
|
5419
|
+
function rawAgentMessageText(message: AgentMessage): string {
|
|
5420
|
+
return rawAgentMessageTextFromParts(message.parts);
|
|
5421
|
+
}
|
|
5422
|
+
|
|
5423
|
+
function agentMessageText(message: AgentMessage): string {
|
|
5424
|
+
return agentMessageTextFromParts(message.parts);
|
|
5425
|
+
}
|
|
5426
|
+
|
|
5404
5427
|
function persistedAgentMessage(message: AgentMessage): AgentMessage {
|
|
5405
5428
|
return {
|
|
5406
5429
|
...message,
|
|
@@ -5432,14 +5455,12 @@ function createAgentKitThreadSnapshot(thread: AgentThreadState) {
|
|
|
5432
5455
|
createdAt: message.createdAt,
|
|
5433
5456
|
},
|
|
5434
5457
|
}));
|
|
5435
|
-
const
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
[...messages].reverse().find((message) => message.role === "user")!,
|
|
5442
|
-
);
|
|
5458
|
+
const firstUser = messages.find((message) => message.role === "user");
|
|
5459
|
+
const latestUser = [...messages]
|
|
5460
|
+
.reverse()
|
|
5461
|
+
.find((message) => message.role === "user");
|
|
5462
|
+
const firstUserText = firstUser && rawAgentMessageText(firstUser);
|
|
5463
|
+
const latestUserText = latestUser && agentMessageText(latestUser);
|
|
5443
5464
|
const handoffThread = thread.thread as AgentKitHandoffThreadSnapshot | null;
|
|
5444
5465
|
const savedTitle = handoffThread?.title?.trim();
|
|
5445
5466
|
const titleSource: "fallback" | undefined =
|
|
@@ -5733,7 +5754,7 @@ function appendVoiceTranscriptsToThreadSnapshot(
|
|
|
5733
5754
|
}),
|
|
5734
5755
|
title:
|
|
5735
5756
|
snapshot.title ||
|
|
5736
|
-
(firstUser ? fallbackChatTitle(
|
|
5757
|
+
(firstUser ? fallbackChatTitle(rawAgentMessageText(firstUser)) : ""),
|
|
5737
5758
|
preview: latestUser ? agentMessageText(latestUser).slice(0, 280) : "",
|
|
5738
5759
|
messageCount: messages.length,
|
|
5739
5760
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ModelEngineConfig } from "@agent-native/core/agent/model-version";
|
|
1
2
|
import { getBrowserTabId } from "@agent-native/core/client/hooks";
|
|
2
3
|
import { buildSettingsRoute } from "@agent-native/core/navigation";
|
|
3
4
|
import {
|
|
@@ -767,6 +768,8 @@ function AgentPanelInner({
|
|
|
767
768
|
const t = useT();
|
|
768
769
|
const location = useLocation();
|
|
769
770
|
const mounted = useClientOnly();
|
|
771
|
+
const [activeChatModelEngine, setActiveChatModelEngine] =
|
|
772
|
+
useState<ModelEngineConfig | null>(null);
|
|
770
773
|
const onboardingPreviewMode = useOnboardingPreviewMode();
|
|
771
774
|
const firstRunOnboardingGateOwnsSurface =
|
|
772
775
|
useFirstRunOnboardingGateOwnsSurface();
|
|
@@ -2402,6 +2405,7 @@ function AgentPanelInner({
|
|
|
2402
2405
|
emptyStateAddon={emptyStateAddon}
|
|
2403
2406
|
emptyStateFooter={emptyStateFooter}
|
|
2404
2407
|
onMessageCountChange={onMessageCountChange}
|
|
2408
|
+
onActiveModelEngineChange={setActiveChatModelEngine}
|
|
2405
2409
|
suggestions={suggestions}
|
|
2406
2410
|
dynamicSuggestions={dynamicSuggestions}
|
|
2407
2411
|
suggestionPlacement={
|
|
@@ -2493,7 +2497,7 @@ function AgentPanelInner({
|
|
|
2493
2497
|
</div>
|
|
2494
2498
|
}
|
|
2495
2499
|
>
|
|
2496
|
-
<ResourcesPanel />
|
|
2500
|
+
<ResourcesPanel modelEngine={activeChatModelEngine} />
|
|
2497
2501
|
</Suspense>
|
|
2498
2502
|
</div>
|
|
2499
2503
|
)}
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
sendToAgentChat,
|
|
19
19
|
} from "@agent-native/core/client/agent-chat";
|
|
20
20
|
import { CHAT_MODEL_SELECTION_CHANGED_EVENT } from "@agent-native/core/client/agent-chat";
|
|
21
|
+
import { chatModelSelectionStorageKey } from "@agent-native/core/client/agent-chat";
|
|
21
22
|
import type {
|
|
22
23
|
ChatThreadScope,
|
|
23
24
|
ChatThreadSummary,
|
|
@@ -116,6 +117,7 @@ const assistantChatMockState = vi.hoisted(() => ({
|
|
|
116
117
|
|
|
117
118
|
const threadMocks = vi.hoisted(() => ({
|
|
118
119
|
activeThreadId: "thread-1" as string | null,
|
|
120
|
+
isLoading: false,
|
|
119
121
|
evictedThreadIds: [] as string[],
|
|
120
122
|
threads: [
|
|
121
123
|
{
|
|
@@ -216,12 +218,14 @@ const ANTHROPIC_ENGINES = [
|
|
|
216
218
|
{
|
|
217
219
|
name: "anthropic",
|
|
218
220
|
label: "Claude",
|
|
221
|
+
defaultModel: "claude-sonnet-5-5",
|
|
219
222
|
supportedModels: ["claude-sonnet-5"],
|
|
220
223
|
requiredEnvVars: ["ANTHROPIC_API_KEY"],
|
|
221
224
|
},
|
|
222
225
|
{
|
|
223
226
|
name: "ai-sdk:openai",
|
|
224
227
|
label: "OpenAI",
|
|
228
|
+
defaultModel: "gpt-5.6-luna",
|
|
225
229
|
supportedModels: ["gpt-5.6-luna"],
|
|
226
230
|
requiredEnvVars: ["OPENAI_API_KEY"],
|
|
227
231
|
},
|
|
@@ -246,6 +250,28 @@ function stubCatalog(
|
|
|
246
250
|
builderConfigured = false,
|
|
247
251
|
) {
|
|
248
252
|
invalidateClientStatusRequests();
|
|
253
|
+
const modelEngines = Object.fromEntries(
|
|
254
|
+
(
|
|
255
|
+
engines as Array<{
|
|
256
|
+
name: string;
|
|
257
|
+
label: string;
|
|
258
|
+
defaultModel?: string;
|
|
259
|
+
supportedModels?: string[];
|
|
260
|
+
acceptsCustomModels?: boolean;
|
|
261
|
+
preserveCustomModels?: boolean;
|
|
262
|
+
}>
|
|
263
|
+
).map((engine) => [
|
|
264
|
+
engine.name,
|
|
265
|
+
{
|
|
266
|
+
name: engine.name,
|
|
267
|
+
label: engine.label,
|
|
268
|
+
defaultModel: engine.defaultModel ?? engine.supportedModels?.[0] ?? "",
|
|
269
|
+
supportedModels: engine.supportedModels ?? [],
|
|
270
|
+
...(engine.acceptsCustomModels ? { acceptsCustomModels: true } : {}),
|
|
271
|
+
...(engine.preserveCustomModels ? { preserveCustomModels: true } : {}),
|
|
272
|
+
},
|
|
273
|
+
]),
|
|
274
|
+
);
|
|
249
275
|
modelCatalogMocks.load = async () => ({
|
|
250
276
|
state: "available",
|
|
251
277
|
groups: buildChatModelGroups({
|
|
@@ -253,6 +279,8 @@ function stubCatalog(
|
|
|
253
279
|
configuredKeys,
|
|
254
280
|
builderConnected: builderConfigured,
|
|
255
281
|
}),
|
|
282
|
+
modelEngines,
|
|
283
|
+
currentModelEngine: null,
|
|
256
284
|
defaultModel: "gpt-5-6-luna",
|
|
257
285
|
loadLiveGroups: async () => null,
|
|
258
286
|
});
|
|
@@ -353,6 +381,8 @@ vi.mock("./AgentKitAssistantChat.js", async () => {
|
|
|
353
381
|
composerDisabled?: boolean;
|
|
354
382
|
composerDisabledPlaceholder?: string;
|
|
355
383
|
isActiveComposer?: boolean;
|
|
384
|
+
isNewThread?: boolean;
|
|
385
|
+
isThreadStateLoading?: boolean;
|
|
356
386
|
contextScope?: ChatThreadScope | null;
|
|
357
387
|
contextNamespace?: string;
|
|
358
388
|
onThreadRestoreNotFound?: () => void;
|
|
@@ -403,6 +433,10 @@ vi.mock("./AgentKitAssistantChat.js", async () => {
|
|
|
403
433
|
}
|
|
404
434
|
data-disabled-placeholder={props.composerDisabledPlaceholder}
|
|
405
435
|
data-composer-active={props.isActiveComposer ? "true" : "false"}
|
|
436
|
+
data-new-thread={props.isNewThread ? "true" : "false"}
|
|
437
|
+
data-thread-state-loading={
|
|
438
|
+
props.isThreadStateLoading ? "true" : "false"
|
|
439
|
+
}
|
|
406
440
|
data-context-scope={
|
|
407
441
|
props.contextScope
|
|
408
442
|
? `${props.contextScope.type}:${props.contextScope.id}`
|
|
@@ -427,6 +461,7 @@ function resetThreadMocks() {
|
|
|
427
461
|
assistantChatMockState.onSaveThread = undefined;
|
|
428
462
|
assistantChatMockState.branchNavigation = undefined;
|
|
429
463
|
threadMocks.activeThreadId = "thread-1";
|
|
464
|
+
threadMocks.isLoading = false;
|
|
430
465
|
threadMocks.evictedThreadIds = [];
|
|
431
466
|
threadMocks.threads = [
|
|
432
467
|
{
|
|
@@ -1024,6 +1059,51 @@ describe("MultiTabAssistantChat postMessage bridge", () => {
|
|
|
1024
1059
|
await view.cleanup();
|
|
1025
1060
|
});
|
|
1026
1061
|
|
|
1062
|
+
it("reports the active thread's exact engine to its resource panel", async () => {
|
|
1063
|
+
const storageKey = "resources-engine-context";
|
|
1064
|
+
const engines = [
|
|
1065
|
+
{
|
|
1066
|
+
name: "anthropic",
|
|
1067
|
+
label: "Anthropic",
|
|
1068
|
+
defaultModel: "claude-sonnet-5-5",
|
|
1069
|
+
supportedModels: ["claude-sonnet-5-5", "claude-fable-5"],
|
|
1070
|
+
requiredEnvVars: ["ANTHROPIC_API_KEY"],
|
|
1071
|
+
},
|
|
1072
|
+
];
|
|
1073
|
+
stubCatalog(engines, ["ANTHROPIC_API_KEY"]);
|
|
1074
|
+
window.localStorage.setItem(
|
|
1075
|
+
chatModelSelectionStorageKey(storageKey),
|
|
1076
|
+
JSON.stringify({ model: "claude-sonnet-5-5", engine: "anthropic" }),
|
|
1077
|
+
);
|
|
1078
|
+
|
|
1079
|
+
let selectedEngine: {
|
|
1080
|
+
name: string;
|
|
1081
|
+
supportedModels: readonly string[];
|
|
1082
|
+
} | null = null;
|
|
1083
|
+
const el = document.createElement("div");
|
|
1084
|
+
document.body.appendChild(el);
|
|
1085
|
+
const localRoot = createRoot(el);
|
|
1086
|
+
await act(async () => {
|
|
1087
|
+
localRoot.render(
|
|
1088
|
+
<MultiTabAssistantChat
|
|
1089
|
+
storageKey={storageKey}
|
|
1090
|
+
onActiveModelEngineChange={(engine) => {
|
|
1091
|
+
selectedEngine = engine;
|
|
1092
|
+
}}
|
|
1093
|
+
/>,
|
|
1094
|
+
);
|
|
1095
|
+
await Promise.resolve();
|
|
1096
|
+
await Promise.resolve();
|
|
1097
|
+
});
|
|
1098
|
+
|
|
1099
|
+
expect(selectedEngine).toMatchObject({
|
|
1100
|
+
name: "anthropic",
|
|
1101
|
+
supportedModels: ["claude-sonnet-5-5", "claude-fable-5"],
|
|
1102
|
+
});
|
|
1103
|
+
await act(async () => localRoot.unmount());
|
|
1104
|
+
el.remove();
|
|
1105
|
+
});
|
|
1106
|
+
|
|
1027
1107
|
it("keeps the last model readiness when status refresh is unavailable", async () => {
|
|
1028
1108
|
const view = await mountWithCatalog(ANTHROPIC_ENGINES, [
|
|
1029
1109
|
"ANTHROPIC_API_KEY",
|
|
@@ -1049,25 +1129,58 @@ describe("MultiTabAssistantChat postMessage bridge", () => {
|
|
|
1049
1129
|
|
|
1050
1130
|
it("keeps a host-supplied model catalog instead of the discovered one", async () => {
|
|
1051
1131
|
stubCatalog(ANTHROPIC_ENGINES, ["ANTHROPIC_API_KEY"]);
|
|
1132
|
+
const storageKey = "host-catalog-test";
|
|
1133
|
+
window.localStorage.setItem(
|
|
1134
|
+
chatModelSelectionStorageKey(storageKey),
|
|
1135
|
+
JSON.stringify({ model: "host-model", engine: "anthropic" }),
|
|
1136
|
+
);
|
|
1137
|
+
let activeEngine: {
|
|
1138
|
+
name: string;
|
|
1139
|
+
defaultModel: string;
|
|
1140
|
+
supportedModels: readonly string[];
|
|
1141
|
+
selectableModels?: readonly string[];
|
|
1142
|
+
} | null = null;
|
|
1052
1143
|
const el = document.createElement("div");
|
|
1053
1144
|
document.body.appendChild(el);
|
|
1054
1145
|
const localRoot = createRoot(el);
|
|
1055
1146
|
await act(async () => {
|
|
1056
1147
|
localRoot.render(
|
|
1057
1148
|
<MultiTabAssistantChat
|
|
1058
|
-
storageKey=
|
|
1149
|
+
storageKey={storageKey}
|
|
1150
|
+
onActiveModelEngineChange={(engine) => {
|
|
1151
|
+
activeEngine = engine;
|
|
1152
|
+
}}
|
|
1153
|
+
/>,
|
|
1154
|
+
);
|
|
1155
|
+
await Promise.resolve();
|
|
1156
|
+
await Promise.resolve();
|
|
1157
|
+
});
|
|
1158
|
+
await act(async () => {
|
|
1159
|
+
await Promise.resolve();
|
|
1160
|
+
await Promise.resolve();
|
|
1161
|
+
});
|
|
1162
|
+
expect(activeEngine).toMatchObject({
|
|
1163
|
+
name: "anthropic",
|
|
1164
|
+
supportedModels: ["claude-sonnet-5"],
|
|
1165
|
+
});
|
|
1166
|
+
|
|
1167
|
+
await act(async () => {
|
|
1168
|
+
localRoot.render(
|
|
1169
|
+
<MultiTabAssistantChat
|
|
1170
|
+
storageKey={storageKey}
|
|
1059
1171
|
availableModels={[
|
|
1060
1172
|
{
|
|
1061
|
-
engine: "
|
|
1062
|
-
label: "Host",
|
|
1063
|
-
models: ["host-model"],
|
|
1173
|
+
engine: "anthropic",
|
|
1174
|
+
label: "Host Anthropic",
|
|
1175
|
+
models: ["host-model", "host-model-2"],
|
|
1064
1176
|
configured: true,
|
|
1065
1177
|
},
|
|
1066
1178
|
]}
|
|
1179
|
+
onActiveModelEngineChange={(engine) => {
|
|
1180
|
+
activeEngine = engine;
|
|
1181
|
+
}}
|
|
1067
1182
|
/>,
|
|
1068
1183
|
);
|
|
1069
|
-
});
|
|
1070
|
-
await act(async () => {
|
|
1071
1184
|
await Promise.resolve();
|
|
1072
1185
|
await Promise.resolve();
|
|
1073
1186
|
});
|
|
@@ -1076,7 +1189,13 @@ describe("MultiTabAssistantChat postMessage bridge", () => {
|
|
|
1076
1189
|
el
|
|
1077
1190
|
.querySelector("[data-testid='assistant-chat']")
|
|
1078
1191
|
?.getAttribute("data-model-catalog"),
|
|
1079
|
-
).toBe("
|
|
1192
|
+
).toBe("anthropic:true");
|
|
1193
|
+
expect(activeEngine).toMatchObject({
|
|
1194
|
+
name: "anthropic",
|
|
1195
|
+
defaultModel: "host-model",
|
|
1196
|
+
supportedModels: ["host-model", "host-model-2"],
|
|
1197
|
+
selectableModels: ["host-model", "host-model-2"],
|
|
1198
|
+
});
|
|
1080
1199
|
|
|
1081
1200
|
await act(async () => localRoot.unmount());
|
|
1082
1201
|
el.remove();
|
|
@@ -1469,6 +1588,32 @@ describe("MultiTabAssistantChat postMessage bridge", () => {
|
|
|
1469
1588
|
window.removeEventListener("agentNative.chatSubmitTarget", onTarget);
|
|
1470
1589
|
});
|
|
1471
1590
|
|
|
1591
|
+
it("shows a known-new chat while the separate thread list is loading", () => {
|
|
1592
|
+
threadMocks.isLoading = true;
|
|
1593
|
+
threadMocks.isNewThread.mockReturnValue(true);
|
|
1594
|
+
|
|
1595
|
+
act(() => {
|
|
1596
|
+
root.render(<MultiTabAssistantChat storageKey="bridge-test" />);
|
|
1597
|
+
});
|
|
1598
|
+
|
|
1599
|
+
const chat = container.querySelector("[data-testid='assistant-chat']");
|
|
1600
|
+
expect(chat?.getAttribute("data-new-thread")).toBe("true");
|
|
1601
|
+
expect(chat?.getAttribute("data-thread-state-loading")).toBe("false");
|
|
1602
|
+
});
|
|
1603
|
+
|
|
1604
|
+
it("keeps existing thread restoration loading while the thread list loads", () => {
|
|
1605
|
+
threadMocks.isLoading = true;
|
|
1606
|
+
threadMocks.isNewThread.mockReturnValue(false);
|
|
1607
|
+
|
|
1608
|
+
act(() => {
|
|
1609
|
+
root.render(<MultiTabAssistantChat storageKey="bridge-test" />);
|
|
1610
|
+
});
|
|
1611
|
+
|
|
1612
|
+
const chat = container.querySelector("[data-testid='assistant-chat']");
|
|
1613
|
+
expect(chat?.getAttribute("data-new-thread")).toBe("false");
|
|
1614
|
+
expect(chat?.getAttribute("data-thread-state-loading")).toBe("true");
|
|
1615
|
+
});
|
|
1616
|
+
|
|
1472
1617
|
it("creates a foreground tab when the active chat has messages", async () => {
|
|
1473
1618
|
threadMocks.isNewThread.mockReturnValue(true);
|
|
1474
1619
|
chatHandleMocks.exportThreadSnapshot.mockReturnValueOnce({
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AgentChatAttachment } from "@agent-native/core";
|
|
2
2
|
import { CHATGPT_SUBSCRIPTION_ENGINE_NAME } from "@agent-native/core/agent/chatgpt-subscription-contract";
|
|
3
|
+
import type { ModelEngineConfig } from "@agent-native/core/agent/model-version";
|
|
3
4
|
import type { AgentChatMessage } from "@agent-native/core/client/agent-chat";
|
|
4
5
|
import {
|
|
5
6
|
DEFAULT_MODEL,
|
|
@@ -885,6 +886,8 @@ export type MultiTabAssistantChatProps = Omit<
|
|
|
885
886
|
showScopeBadge?: boolean;
|
|
886
887
|
/** Cadence for hydrating agent-team sub-agent tab status. Default: 3000. */
|
|
887
888
|
agentTeamPollMs?: number;
|
|
889
|
+
/** Reports the exact model engine selected for the active thread. */
|
|
890
|
+
onActiveModelEngineChange?: (engine: ModelEngineConfig | null) => void;
|
|
888
891
|
};
|
|
889
892
|
|
|
890
893
|
export function MultiTabAssistantChat({
|
|
@@ -905,6 +908,7 @@ export function MultiTabAssistantChat({
|
|
|
905
908
|
modelListError: hostModelListError,
|
|
906
909
|
onRetryModelList: hostOnRetryModelList,
|
|
907
910
|
onModelChange: hostOnModelChange,
|
|
911
|
+
onActiveModelEngineChange,
|
|
908
912
|
...props
|
|
909
913
|
}: MultiTabAssistantChatProps) {
|
|
910
914
|
const translate = useT();
|
|
@@ -1154,6 +1158,9 @@ export function MultiTabAssistantChat({
|
|
|
1154
1158
|
const [discoveredModels, setDiscoveredModels] = useState<EngineModelGroup[]>(
|
|
1155
1159
|
[],
|
|
1156
1160
|
);
|
|
1161
|
+
const [discoveredModelEngines, setDiscoveredModelEngines] = useState<
|
|
1162
|
+
Readonly<Record<string, ModelEngineConfig>>
|
|
1163
|
+
>({});
|
|
1157
1164
|
const availableModels = hostAvailableModels ?? discoveredModels;
|
|
1158
1165
|
const [discoveredModelsLoading, setModelListLoading] = useState(true);
|
|
1159
1166
|
const [discoveredModelsError, setDiscoveredModelsError] = useState(false);
|
|
@@ -1280,6 +1287,51 @@ export function MultiTabAssistantChat({
|
|
|
1280
1287
|
[availableModels, persistedModelSelection, modelSelectionVersion],
|
|
1281
1288
|
);
|
|
1282
1289
|
|
|
1290
|
+
useEffect(() => {
|
|
1291
|
+
if (!onActiveModelEngineChange) return;
|
|
1292
|
+
const selection = activeThreadId
|
|
1293
|
+
? resolveThreadModelSelection(activeThreadId)
|
|
1294
|
+
: undefined;
|
|
1295
|
+
const selectedModel = selection?.model ?? defaultModel;
|
|
1296
|
+
const engineName =
|
|
1297
|
+
selection?.engine ??
|
|
1298
|
+
availableModels.find((group) => group.models.includes(selectedModel))
|
|
1299
|
+
?.engine;
|
|
1300
|
+
const hostEngineGroups = hostManagedModels
|
|
1301
|
+
? availableModels.filter((group) => group.engine === engineName)
|
|
1302
|
+
: [];
|
|
1303
|
+
const hostSelectableModels = [
|
|
1304
|
+
...new Set(hostEngineGroups.flatMap((group) => group.models)),
|
|
1305
|
+
];
|
|
1306
|
+
const hostModelEngine =
|
|
1307
|
+
engineName && hostSelectableModels.length > 0
|
|
1308
|
+
? {
|
|
1309
|
+
name: engineName,
|
|
1310
|
+
label: hostEngineGroups[0]?.label ?? engineName,
|
|
1311
|
+
defaultModel: hostSelectableModels.includes(selectedModel)
|
|
1312
|
+
? selectedModel
|
|
1313
|
+
: hostSelectableModels[0]!,
|
|
1314
|
+
supportedModels: hostSelectableModels,
|
|
1315
|
+
selectableModels: hostSelectableModels,
|
|
1316
|
+
}
|
|
1317
|
+
: null;
|
|
1318
|
+
onActiveModelEngineChange(
|
|
1319
|
+
hostManagedModels
|
|
1320
|
+
? hostModelEngine
|
|
1321
|
+
: engineName
|
|
1322
|
+
? (discoveredModelEngines[engineName] ?? null)
|
|
1323
|
+
: null,
|
|
1324
|
+
);
|
|
1325
|
+
}, [
|
|
1326
|
+
activeThreadId,
|
|
1327
|
+
availableModels,
|
|
1328
|
+
defaultModel,
|
|
1329
|
+
discoveredModelEngines,
|
|
1330
|
+
hostManagedModels,
|
|
1331
|
+
onActiveModelEngineChange,
|
|
1332
|
+
resolveThreadModelSelection,
|
|
1333
|
+
]);
|
|
1334
|
+
|
|
1283
1335
|
const persistModelSelection = useCallback(
|
|
1284
1336
|
(selection: ModelSelection) => {
|
|
1285
1337
|
setPersistedModelSelection(selection);
|
|
@@ -1425,10 +1477,25 @@ export function MultiTabAssistantChat({
|
|
|
1425
1477
|
}
|
|
1426
1478
|
setDiscoveredModelsError(false);
|
|
1427
1479
|
setDiscoveredModels(catalog.groups);
|
|
1480
|
+
setDiscoveredModelEngines(catalog.modelEngines);
|
|
1428
1481
|
setDefaultModel(catalog.defaultModel);
|
|
1429
1482
|
void catalog.loadLiveGroups().then((liveGroups) => {
|
|
1430
1483
|
if (isCurrentRequest() && liveGroups) {
|
|
1431
1484
|
setDiscoveredModels(liveGroups);
|
|
1485
|
+
setDiscoveredModelEngines((current) => {
|
|
1486
|
+
const next = { ...current };
|
|
1487
|
+
for (const group of liveGroups) {
|
|
1488
|
+
const engine = next[group.engine];
|
|
1489
|
+
if (engine) {
|
|
1490
|
+
next[group.engine] = {
|
|
1491
|
+
...engine,
|
|
1492
|
+
supportedModels: group.models,
|
|
1493
|
+
selectableModels: group.models,
|
|
1494
|
+
};
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
return next;
|
|
1498
|
+
});
|
|
1432
1499
|
}
|
|
1433
1500
|
});
|
|
1434
1501
|
})
|
|
@@ -3194,6 +3261,8 @@ export function MultiTabAssistantChat({
|
|
|
3194
3261
|
tabId === activeThreadId || mountedTabsRef.current.has(tabId),
|
|
3195
3262
|
)
|
|
3196
3263
|
.map((tabId) => {
|
|
3264
|
+
const isKnownNewThread =
|
|
3265
|
+
newThreadIds.current.has(tabId) || isNewThread(tabId);
|
|
3197
3266
|
const modelSelection = resolveThreadModelSelection(tabId);
|
|
3198
3267
|
const modelSelectionPending =
|
|
3199
3268
|
!hostManagedModels && modelListLoading && !modelSelection;
|
|
@@ -3229,9 +3298,7 @@ export function MultiTabAssistantChat({
|
|
|
3229
3298
|
isolateHistoryByScope={isolateHistoryByScope}
|
|
3230
3299
|
isActiveComposer={!contentHidden && tabId === activeThreadId}
|
|
3231
3300
|
apiUrl={apiUrl}
|
|
3232
|
-
isNewThread={
|
|
3233
|
-
newThreadIds.current.has(tabId) || isNewThread(tabId)
|
|
3234
|
-
}
|
|
3301
|
+
isNewThread={isKnownNewThread}
|
|
3235
3302
|
onThreadRestoreNotFound={
|
|
3236
3303
|
tabId === activeThreadId &&
|
|
3237
3304
|
(props.agentChatSurface !== "desktop" ||
|
|
@@ -3239,7 +3306,7 @@ export function MultiTabAssistantChat({
|
|
|
3239
3306
|
? clearActiveTab
|
|
3240
3307
|
: undefined
|
|
3241
3308
|
}
|
|
3242
|
-
isThreadStateLoading={isLoading}
|
|
3309
|
+
isThreadStateLoading={isLoading && !isKnownNewThread}
|
|
3243
3310
|
onMessageCountChange={(count) => {
|
|
3244
3311
|
setMessageCounts((prev) =>
|
|
3245
3312
|
prev[tabId] === count
|
|
@@ -126,6 +126,23 @@ describe("CoreAgentKitApproval", () => {
|
|
|
126
126
|
expect(startRun).not.toHaveBeenCalled();
|
|
127
127
|
});
|
|
128
128
|
|
|
129
|
+
it("masks a failed resolution's message in replays", async () => {
|
|
130
|
+
const client = new AgentKitClient({
|
|
131
|
+
transport: createTransport({
|
|
132
|
+
resolveApproval: vi.fn(async () => {
|
|
133
|
+
throw new Error("Jane Doe's calendar is locked");
|
|
134
|
+
}),
|
|
135
|
+
}),
|
|
136
|
+
});
|
|
137
|
+
renderApproval(client);
|
|
138
|
+
|
|
139
|
+
await clickButton("Approve");
|
|
140
|
+
|
|
141
|
+
const error = container.querySelector(".agentkit-command-error");
|
|
142
|
+
expect(error?.textContent).toBe("Jane Doe's calendar is locked");
|
|
143
|
+
expect(error?.hasAttribute("data-an-mask")).toBe(true);
|
|
144
|
+
});
|
|
145
|
+
|
|
129
146
|
it("uses a generic summary when the tool name is not safe to display", () => {
|
|
130
147
|
const client = new AgentKitClient({ transport: createTransport() });
|
|
131
148
|
renderApproval(client, {
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
} from "../../agentkit/react/context.js";
|
|
13
13
|
import { ActionCard } from "../chat/widgets/ActionCard.js";
|
|
14
14
|
import { compactOutlineButtonClassName } from "../components/ui/button-classes.js";
|
|
15
|
+
import { SESSION_REPLAY_MASK_PROPS } from "../session-replay-privacy.js";
|
|
15
16
|
|
|
16
17
|
type ApprovalSlotProps = AgentKitRenderProps<AgentApprovalRequest> & {
|
|
17
18
|
runId: string;
|
|
@@ -160,6 +161,7 @@ function SimpleToolApproval({
|
|
|
160
161
|
/>
|
|
161
162
|
{resolution.error ? (
|
|
162
163
|
<p
|
|
164
|
+
{...SESSION_REPLAY_MASK_PROPS}
|
|
163
165
|
role="alert"
|
|
164
166
|
className="agentkit-command-error block px-3 pb-3 text-xs"
|
|
165
167
|
>
|