@agent-native/core 0.155.0 → 0.157.1
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/corpus/README.md +1 -1
- package/corpus/templates/analytics/server/jobs/analytics-bigquery-backfill.ts +19 -4
- package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +7 -2
- package/corpus/templates/assets/app/components/asset/AssetPreviewDialog.tsx +3 -1
- package/corpus/templates/assets/app/global.css +4 -0
- package/corpus/templates/assets/app/i18n-data.ts +21 -1
- package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +18 -15
- package/corpus/templates/brain/app/routes/sources.tsx +1 -2
- package/corpus/templates/calendar/app/hooks/use-bookings.ts +12 -2
- package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +64 -2
- package/corpus/templates/calendar/server/handlers/bookings.ts +219 -93
- package/corpus/templates/calendar/server/plugins/auth.ts +0 -2
- package/corpus/templates/clips/actions/create-folder.ts +7 -1
- package/corpus/templates/clips/actions/create-meeting.ts +6 -2
- package/corpus/templates/clips/actions/create-recording.ts +5 -3
- package/corpus/templates/clips/actions/finalize-recording.ts +97 -65
- package/corpus/templates/clips/actions/import-loom-recording.ts +5 -3
- package/corpus/templates/clips/actions/request-recording-access.ts +272 -0
- package/corpus/templates/clips/actions/stitch-recordings.ts +5 -3
- package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +38 -63
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +177 -134
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +3 -21
- package/corpus/templates/clips/app/components/sharing/share-ui.tsx +13 -30
- package/corpus/templates/clips/app/i18n/en-US.ts +10 -0
- package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +5 -5
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +24 -17
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +151 -20
- package/corpus/templates/clips/changelog/2026-08-14-long-resumable-uploads-now-abort-cleanly-and-show-errors.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-14-standardized-share-popovers.md +6 -0
- package/corpus/templates/clips/chrome-extension/public/manifest.json +11 -3
- package/corpus/templates/clips/chrome-extension/src/github-preview-content.ts +37 -8
- package/corpus/templates/clips/chrome-extension/src/github-preview.ts +3 -3
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +8 -25
- package/corpus/templates/clips/desktop/src/app.tsx +24 -0
- package/corpus/templates/clips/desktop/src/lib/media-capture-constraints.ts +42 -13
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +11 -18
- package/corpus/templates/clips/desktop/src/overlays/onboarding.tsx +1 -0
- package/corpus/templates/clips/desktop/src/shared/config.ts +1 -0
- package/corpus/templates/clips/desktop/src/styles.css +24 -9
- package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +3 -0
- package/corpus/templates/clips/desktop/src-tauri/src/config.rs +8 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +154 -176
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +115 -31
- package/corpus/templates/clips/desktop/src-tauri/src/rewind_clip.rs +7 -0
- package/corpus/templates/clips/server/db/index.ts +1 -0
- package/corpus/templates/clips/server/db/schema.ts +1 -0
- package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +6 -1
- package/corpus/templates/clips/server/lib/emails.ts +23 -0
- package/corpus/templates/clips/server/lib/public-agent-context.ts +55 -0
- package/corpus/templates/clips/server/lib/recordings.ts +2 -1
- package/corpus/templates/clips/server/lib/resumable-upload-cleanup.ts +49 -0
- package/corpus/templates/clips/server/lib/s3-upload-provider.ts +34 -7
- package/corpus/templates/clips/server/lib/upload-interruption.ts +15 -1
- package/corpus/templates/clips/server/lib/upload-lease.ts +94 -9
- package/corpus/templates/clips/server/routes/api/agent-context.json.get.ts +82 -7
- package/corpus/templates/clips/server/routes/api/public-recording.get.ts +1 -0
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +71 -12
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/interrupt.post.ts +4 -3
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/reset-chunks.post.ts +19 -0
- package/corpus/templates/clips/server/routes/api/uploads/reap.post.ts +8 -1
- package/corpus/templates/clips/shared/recording-link.ts +4 -0
- package/corpus/templates/clips/shared/share-loader-response.ts +2 -1
- package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +7 -16
- package/corpus/templates/factory/AGENTS.md +5 -1
- package/corpus/templates/factory/README.md +6 -2
- package/corpus/templates/factory/actions/view-screen.ts +15 -0
- package/corpus/templates/factory/app/components/factory/FactoryAgentsView.tsx +58 -189
- package/corpus/templates/factory/app/components/layout/Header.tsx +1 -0
- package/corpus/templates/factory/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/factory/app/components/layout/Sidebar.tsx +7 -0
- package/corpus/templates/factory/app/hooks/use-navigation-state.ts +3 -0
- package/corpus/templates/factory/app/i18n/en-US.ts +3 -1
- package/corpus/templates/factory/app/routes/agents.tsx +9 -0
- package/corpus/templates/mail/server/plugins/auth.ts +0 -2
- package/corpus/templates/plan/app/components/plan/LocalCodebasePicker.tsx +50 -14
- package/corpus/templates/plan/app/pages/PlansPage.tsx +9 -19
- package/corpus/templates/slides/app/components/editor/AddSlidePopover.tsx +98 -29
- package/corpus/templates/slides/app/components/editor/EditorActionCluster.tsx +45 -91
- package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +94 -2
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +17 -29
- package/corpus/templates/slides/app/components/editor/HistoryPanel.tsx +7 -1
- package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +1 -1
- package/corpus/templates/slides/app/context/DeckContext.tsx +108 -19
- package/corpus/templates/slides/app/global.css +7 -40
- package/corpus/templates/slides/app/i18n/en-US.ts +4 -0
- package/corpus/templates/slides/app/lib/editor-shortcuts.ts +46 -0
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +143 -45
- package/dist/agent/index.d.ts +1 -1
- package/dist/agent/production-agent.d.ts +30 -0
- package/dist/agent/production-agent.js +100 -8
- package/dist/agent/types.d.ts +9 -0
- package/dist/client/AgentPanel.d.ts +13 -1
- package/dist/client/AgentPanel.js +22 -17
- package/dist/client/AssistantChat.d.ts +15 -1
- package/dist/client/AssistantChat.js +135 -48
- package/dist/client/HighlightedCodeBlock.js +12 -2
- package/dist/client/MultiTabAssistantChat.js +44 -27
- package/dist/client/agent-chat/index.d.ts +1 -0
- package/dist/client/agent-chat/index.js +1 -0
- package/dist/client/chat/markdown-renderer.js +20 -5
- package/dist/client/chat/message-components.d.ts +2 -2
- package/dist/client/chat/message-components.js +69 -35
- package/dist/client/chat/run-recovery.d.ts +4 -1
- package/dist/client/chat/run-recovery.js +62 -30
- package/dist/client/chat/tool-call-display.d.ts +12 -3
- package/dist/client/chat/tool-call-display.js +79 -40
- package/dist/client/chat/widgets/DataChartRenderer.js +3 -1
- package/dist/client/chat/widgets/DataChartWidget.js +8 -2
- package/dist/client/chat/widgets/DataInsightsWidget.js +3 -1
- package/dist/client/chat/widgets/DataTableWidget.js +23 -9
- package/dist/client/chat/widgets/builtin-tool-renderers.js +3 -1
- package/dist/client/chat-first/apps-rail.js +1 -1
- package/dist/client/components/ui/message-scroller.d.ts +1 -1
- package/dist/client/components/ui/message-scroller.js +7 -3
- package/dist/client/composer/runtime-adapters.js +3 -2
- package/dist/client/context-xray/ContextMeter.js +5 -1
- package/dist/client/context-xray/ContextXRayPanel.js +5 -5
- package/dist/client/error-format.d.ts +4 -0
- package/dist/client/error-format.js +93 -5
- package/dist/client/i18n.js +83 -17
- package/dist/client/observability/ThumbsFeedback.js +10 -8
- package/dist/client/settings/AccountSettingsCard.js +48 -19
- package/dist/client/sharing/ShareButton.d.ts +1 -2
- package/dist/client/sharing/ShareButton.js +151 -81
- package/dist/client/sharing/ShareDialog.js +5 -4
- package/dist/client/use-chat-threads.js +10 -14
- package/dist/coding-tools/run-code.js +2 -1
- package/dist/coding-tools/sandbox/background.d.ts +1 -0
- package/dist/coding-tools/sandbox/background.js +8 -1
- package/dist/coding-tools/sandbox/executions-store.d.ts +2 -0
- package/dist/coding-tools/sandbox/executions-store.js +41 -3
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/localization/core-messages/ar-SA.d.ts +3 -0
- package/dist/localization/core-messages/ar-SA.js +541 -0
- package/dist/localization/core-messages/de-DE.d.ts +3 -0
- package/dist/localization/core-messages/de-DE.js +513 -0
- package/dist/localization/core-messages/en-US.d.ts +513 -0
- package/dist/localization/core-messages/en-US.js +513 -0
- package/dist/localization/core-messages/es-ES.d.ts +3 -0
- package/dist/localization/core-messages/es-ES.js +520 -0
- package/dist/localization/core-messages/fr-FR.d.ts +3 -0
- package/dist/localization/core-messages/fr-FR.js +520 -0
- package/dist/localization/core-messages/hi-IN.d.ts +3 -0
- package/dist/localization/core-messages/hi-IN.js +513 -0
- package/dist/localization/core-messages/ja-JP.d.ts +3 -0
- package/dist/localization/core-messages/ja-JP.js +506 -0
- package/dist/localization/core-messages/ko-KR.d.ts +3 -0
- package/dist/localization/core-messages/ko-KR.js +506 -0
- package/dist/localization/core-messages/pt-BR.d.ts +3 -0
- package/dist/localization/core-messages/pt-BR.js +520 -0
- package/dist/localization/core-messages/zh-CN.d.ts +3 -0
- package/dist/localization/core-messages/zh-CN.js +506 -0
- package/dist/localization/core-messages/zh-TW.d.ts +3 -0
- package/dist/localization/core-messages/zh-TW.js +506 -0
- package/dist/localization/core-messages.d.ts +524 -0
- package/dist/localization/core-messages.js +124 -0
- package/dist/localization/default-messages.d.ts +3 -0
- package/dist/localization/default-messages.js +3 -0
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
- package/dist/provider-api/actions/provider-api.d.ts +15 -15
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-chat/plugin-options.d.ts +7 -2
- package/dist/server/agent-chat-plugin.d.ts +10 -0
- package/dist/server/agent-chat-plugin.js +144 -41
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-run-context.d.ts +7 -1
- package/dist/server/agent-run-context.js +9 -2
- package/dist/server/agent-teams-run-queue.d.ts +3 -0
- package/dist/server/agent-teams.js +38 -9
- package/dist/server/auth-marketing.d.ts +1 -0
- package/dist/server/auth-marketing.js +0 -2
- package/dist/server/auth.d.ts +1 -0
- package/dist/server/auth.js +18 -0
- package/dist/server/index.d.ts +1 -1
- package/dist/server/onboarding-html.d.ts +1 -0
- package/dist/server/onboarding-html.js +2 -88
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/request-context.d.ts +7 -0
- package/dist/server/request-context.js +15 -0
- package/dist/shared/markdown-block-split.d.ts +16 -0
- package/dist/shared/markdown-block-split.js +81 -5
- package/dist/styles/agent-native.css +13 -0
- package/dist/voice/voice-cleanup-prompt.js +1 -0
- package/docs/content/agent-surfaces.mdx +30 -0
- package/package.json +2 -2
- package/corpus/templates/clips/shared/mic-audio-cleanup.ts +0 -350
|
@@ -32,6 +32,7 @@ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "./com
|
|
|
32
32
|
import { AgentComposerFrame, TiptapComposer, } from "./composer/index.js";
|
|
33
33
|
import { useAgentDynamicSuggestionsResult, } from "./dynamic-suggestions.js";
|
|
34
34
|
import { GuidedQuestionFlow, useGuidedQuestionFlow, } from "./guided-questions.js";
|
|
35
|
+
import { useT } from "./i18n.js";
|
|
35
36
|
import { buildSignInReturnHref } from "./require-session.js";
|
|
36
37
|
import { addMcpConnectionCompleteListener, consumeMcpConnectionResume, } from "./resources/mcp-connection-resume.js";
|
|
37
38
|
import { McpConnectionSuggestion } from "./resources/McpConnectionSuggestion.js";
|
|
@@ -365,6 +366,7 @@ function getImageAttachmentSrc(attachment) {
|
|
|
365
366
|
return imagePart && "image" in imagePart ? imagePart.image : null;
|
|
366
367
|
}
|
|
367
368
|
function ComposerAttachmentPreviewCard({ attachment, onRemove, }) {
|
|
369
|
+
const t = useT();
|
|
368
370
|
const [imageSrc, setImageSrc] = useState(null);
|
|
369
371
|
useEffect(() => {
|
|
370
372
|
const nextSrc = getImageAttachmentSrc(attachment);
|
|
@@ -383,7 +385,9 @@ function ComposerAttachmentPreviewCard({ attachment, onRemove, }) {
|
|
|
383
385
|
? "h-20 w-20 rounded-xl shadow-[0_12px_30px_-18px_rgba(0,0,0,0.7)]"
|
|
384
386
|
: "inline-flex max-w-[220px] items-center gap-2 rounded-lg px-2.5 py-2 text-xs"), children: [isImage ? (_jsxs(_Fragment, { children: [_jsx("img", { src: imageSrc, alt: attachment.name, className: "h-full w-full object-cover" }), _jsx("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/80 via-black/30 to-transparent px-2 py-1.5", children: _jsx("div", { className: "truncate text-[10px] font-medium text-white/95", children: attachment.name }) })] })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-md bg-background text-[10px] font-semibold uppercase tracking-[0.12em] text-muted-foreground", children: attachment.name.split(".").pop() || "file" }), _jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "truncate font-medium", children: attachment.name }), _jsx("div", { className: "text-[11px] text-muted-foreground", children: attachment.contentType || attachment.type })] })] })), _jsx("button", { type: "button", onClick: () => onRemove(attachment.id), className: cn("absolute flex h-6 w-6 items-center justify-center rounded-full border border-border/60 bg-background/95 text-muted-foreground shadow-sm transition hover:text-foreground", isImage
|
|
385
387
|
? "end-1.5 top-1.5 opacity-100 md:opacity-0 md:group-hover:opacity-100"
|
|
386
|
-
: "end-1.5 top-1.5"), "aria-label":
|
|
388
|
+
: "end-1.5 top-1.5"), "aria-label": t("agentChat.composer.removeAttachment", {
|
|
389
|
+
name: attachment.name,
|
|
390
|
+
}), children: _jsx(IconX, { className: "h-3 w-3" }) })] }));
|
|
387
391
|
}
|
|
388
392
|
function ComposerAttachmentPreviewStrip() {
|
|
389
393
|
const attachments = useComposer((state) => state.attachments);
|
|
@@ -980,14 +984,38 @@ export function resolveAssistantChatRunningState({ forceStopped, isRuntimeRunnin
|
|
|
980
984
|
showRunningInUI: !forceStopped && !hasTerminalRunError && (isRunning || isAutoResuming),
|
|
981
985
|
};
|
|
982
986
|
}
|
|
983
|
-
export function resolveAssistantChatRunningStatusLabel({ runningActivityLabel, isAutoResuming, isReconnecting, hasReconnectContent,
|
|
984
|
-
|
|
987
|
+
export function resolveAssistantChatRunningStatusLabel({ runningActivityLabel, isAutoResuming, isReconnecting, hasReconnectContent, labels = {
|
|
988
|
+
thinking: "Thinking",
|
|
989
|
+
resuming: "Resuming",
|
|
990
|
+
stillWorking: "Still working",
|
|
991
|
+
}, }) {
|
|
992
|
+
if (runningActivityLabel) {
|
|
993
|
+
if (runningActivityLabel === "Thinking")
|
|
994
|
+
return labels.thinking;
|
|
995
|
+
if (runningActivityLabel === "Working") {
|
|
996
|
+
return labels.working ?? "Working";
|
|
997
|
+
}
|
|
998
|
+
if (runningActivityLabel === "Contacting model") {
|
|
999
|
+
return labels.contactingModel ?? "Contacting model";
|
|
1000
|
+
}
|
|
1001
|
+
const localizedActivityPatterns = [
|
|
1002
|
+
[/^Starting (.+)\.\.\.$/, labels.starting],
|
|
1003
|
+
[/^Preparing (.+)\.\.\.$/, labels.preparing],
|
|
1004
|
+
[/^Writing (.+)\.\.\.$/, labels.writing],
|
|
1005
|
+
[/^Still generating (.+)$/, labels.stillGenerating],
|
|
1006
|
+
];
|
|
1007
|
+
for (const [pattern, translateActivity] of localizedActivityPatterns) {
|
|
1008
|
+
const match = runningActivityLabel.match(pattern);
|
|
1009
|
+
if (match?.[1] && translateActivity)
|
|
1010
|
+
return translateActivity(match[1]);
|
|
1011
|
+
}
|
|
985
1012
|
return runningActivityLabel;
|
|
1013
|
+
}
|
|
986
1014
|
if (isAutoResuming)
|
|
987
|
-
return
|
|
1015
|
+
return labels.resuming;
|
|
988
1016
|
if (isReconnecting && hasReconnectContent)
|
|
989
|
-
return
|
|
990
|
-
return
|
|
1017
|
+
return labels.stillWorking;
|
|
1018
|
+
return labels.thinking;
|
|
991
1019
|
}
|
|
992
1020
|
export function resolveAssistantChatComposerPlaceholder(composerPlaceholder) {
|
|
993
1021
|
return composerPlaceholder ?? DEFAULT_ASSISTANT_CHAT_COMPOSER_PLACEHOLDER;
|
|
@@ -1109,6 +1137,9 @@ function AssistantChatScrollerControls({ resumeFollowingRef, }) {
|
|
|
1109
1137
|
}, [resumeFollowingRef, scrollToEnd]);
|
|
1110
1138
|
return null;
|
|
1111
1139
|
}
|
|
1140
|
+
export function shouldShowAssistantChatModelSelector(showModelSelector) {
|
|
1141
|
+
return showModelSelector !== false;
|
|
1142
|
+
}
|
|
1112
1143
|
export const CHAT_STORAGE_PREFIX = "agent-chat:";
|
|
1113
1144
|
const THREAD_SNAPSHOT_CACHE_PREFIX = `${CHAT_STORAGE_PREFIX}thread-snapshot:`;
|
|
1114
1145
|
function threadSnapshotCacheKey(apiUrl, threadId) {
|
|
@@ -1344,7 +1375,8 @@ export function useAutoResumeStatus(tabId, forceStopped) {
|
|
|
1344
1375
|
function approvalResolutionIdentity(approvalKey, toolCallId) {
|
|
1345
1376
|
return `${toolCallId ?? ""}\u0000${approvalKey}`;
|
|
1346
1377
|
}
|
|
1347
|
-
const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateText, suggestions, dynamicSuggestions, threadFooterSlot, emptyStateAddon, showHeader = true, onSwitchToCli, className, apiUrl, tabId, browserTabId, threadId, contextScope, isActiveComposer = true, onMessageCountChange, onSaveThread, onGenerateTitle, composerSlot, onComposerTextChange, composerAreaClassName, composerPlaceholder, missingApiKeySetupLayout = "default", composerLayoutVariant = "default", centerComposerWhenEmpty = false, emptyStateDisplay = "default", composerToolbarSlot, composerExtraActionButton, composerDisabled = false, composerDisabledPlaceholder, isNewThread, isThreadStateLoading, onSlashCommand, execMode, onExecModeChange, approvalActions, planModeDisabled, planModeDisabledReason, selectedModel, defaultModel, selectedEngine, selectedEffort, availableModels, modelListLoading, onModelChange, onEffortChange, imageModelMenu, onForkChat, onConnectProvider, onConnectLocalRuntime, plusMenuMode = "full", providerStatusChecksEnabled = true, loadHistoryRepository, historyReloadKey, externalStreaming = false, agentChatSurface = "app", suppressInlineOpenApp = false, }, ref) {
|
|
1378
|
+
const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateText, suggestions, dynamicSuggestions, threadFooterSlot, emptyStateAddon, showHeader = true, onSwitchToCli, className, apiUrl, tabId, browserTabId, threadId, contextScope, isActiveComposer = true, onMessageCountChange, onSaveThread, onGenerateTitle, composerSlot, onComposerTextChange, composerAreaClassName, composerPlaceholder, missingApiKeySetupLayout = "default", composerLayoutVariant = "default", centerComposerWhenEmpty = false, emptyStateDisplay = "default", composerToolbarSlot, composerExtraActionButton, showModelSelector = true, composerDisabled = false, composerDisabledPlaceholder, isNewThread, isThreadStateLoading, onSlashCommand, execMode, onExecModeChange, approvalActions, planModeDisabled, planModeDisabledReason, selectedModel, defaultModel, selectedEngine, selectedEffort, availableModels, modelListLoading, onModelChange, onEffortChange, imageModelMenu, onForkChat, onConnectProvider, onConnectLocalRuntime, plusMenuMode = "full", providerStatusChecksEnabled = true, loadHistoryRepository, historyReloadKey, externalStreaming = false, agentChatSurface = "app", suppressInlineOpenApp = false, }, ref) {
|
|
1379
|
+
const t = useT();
|
|
1348
1380
|
const thread = useThread();
|
|
1349
1381
|
const threadRuntime = useThreadRuntime();
|
|
1350
1382
|
const composerRuntime = useComposerRuntime();
|
|
@@ -1441,10 +1473,10 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1441
1473
|
void Promise.all(attachments.map((file) => composerRuntime.addAttachment(file))).catch((error) => {
|
|
1442
1474
|
const msg = error instanceof Error
|
|
1443
1475
|
? error.message
|
|
1444
|
-
: "
|
|
1476
|
+
: t("agentChat.composer.droppedFileError");
|
|
1445
1477
|
setComposerError(msg);
|
|
1446
1478
|
});
|
|
1447
|
-
}, [composerRuntime, setComposerError]);
|
|
1479
|
+
}, [composerRuntime, setComposerError, t]);
|
|
1448
1480
|
// Patch the underlying assistant-ui MessageRepository so addOrUpdateMessage
|
|
1449
1481
|
// can't throw "Parent message not found" mid-run. assistant-ui calls
|
|
1450
1482
|
// `repository.clear()` from `runtime.import()` and from `resetHead(null)`,
|
|
@@ -1721,6 +1753,17 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1721
1753
|
isAutoResuming,
|
|
1722
1754
|
isReconnecting,
|
|
1723
1755
|
hasReconnectContent: reconnectContent.length > 0,
|
|
1756
|
+
labels: {
|
|
1757
|
+
thinking: t("agentChat.status.thinking"),
|
|
1758
|
+
resuming: t("agentChat.status.resuming"),
|
|
1759
|
+
stillWorking: t("agentChat.status.stillWorking"),
|
|
1760
|
+
working: t("agentChat.status.working"),
|
|
1761
|
+
contactingModel: t("agentChat.status.contactingModel"),
|
|
1762
|
+
starting: (activity) => t("agentChat.status.starting", { activity }),
|
|
1763
|
+
preparing: (activity) => t("agentChat.status.preparing", { activity }),
|
|
1764
|
+
writing: (activity) => t("agentChat.status.writing", { activity }),
|
|
1765
|
+
stillGenerating: (activity) => t("agentChat.status.stillGenerating", { activity }),
|
|
1766
|
+
},
|
|
1724
1767
|
});
|
|
1725
1768
|
const reconnectActivityContent = useMemo(() => isReconnecting || reconnectFrozen
|
|
1726
1769
|
? reconnectActivityFallbackContent(runningActivityTool)
|
|
@@ -2375,10 +2418,10 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
2375
2418
|
}
|
|
2376
2419
|
setRunErrorInfo({
|
|
2377
2420
|
message: reconnectErrorCode === "run_timeout"
|
|
2378
|
-
? "
|
|
2421
|
+
? t("agentChat.recovery.backgroundTimeout")
|
|
2379
2422
|
: reconnectErrorCode === "reconnect_stream_ended"
|
|
2380
|
-
? "
|
|
2381
|
-
: "
|
|
2423
|
+
? t("agentChat.recovery.streamEnded")
|
|
2424
|
+
: t("agentChat.recovery.noProgress"),
|
|
2382
2425
|
errorCode: reconnectErrorCode,
|
|
2383
2426
|
recoverable: true,
|
|
2384
2427
|
runId,
|
|
@@ -2453,7 +2496,14 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
2453
2496
|
};
|
|
2454
2497
|
void streamReconnect();
|
|
2455
2498
|
return true;
|
|
2456
|
-
}, [
|
|
2499
|
+
}, [
|
|
2500
|
+
apiUrl,
|
|
2501
|
+
refreshThreadFromServer,
|
|
2502
|
+
t,
|
|
2503
|
+
tabId,
|
|
2504
|
+
threadId,
|
|
2505
|
+
wasRecentlyStoppedRun,
|
|
2506
|
+
]);
|
|
2457
2507
|
const reconnectActiveRunForThread = useCallback(async () => {
|
|
2458
2508
|
if (!threadId)
|
|
2459
2509
|
return false;
|
|
@@ -2489,7 +2539,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
2489
2539
|
clearActiveRunIfMatches(threadId, storedActiveRun.runId);
|
|
2490
2540
|
window.dispatchEvent(new CustomEvent("agent-chat:run-error", {
|
|
2491
2541
|
detail: {
|
|
2492
|
-
message: "
|
|
2542
|
+
message: t("agentChat.recovery.statusCheckFailed"),
|
|
2493
2543
|
errorCode: "run_status_unavailable",
|
|
2494
2544
|
recoverable: true,
|
|
2495
2545
|
...(storedActiveRun.runId
|
|
@@ -2520,7 +2570,14 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
2520
2570
|
catch {
|
|
2521
2571
|
return false;
|
|
2522
2572
|
}
|
|
2523
|
-
}, [
|
|
2573
|
+
}, [
|
|
2574
|
+
apiUrl,
|
|
2575
|
+
refreshThreadFromServer,
|
|
2576
|
+
startReconnectToRun,
|
|
2577
|
+
t,
|
|
2578
|
+
tabId,
|
|
2579
|
+
threadId,
|
|
2580
|
+
]);
|
|
2524
2581
|
useEffect(() => {
|
|
2525
2582
|
if (!threadId || !isNewThread)
|
|
2526
2583
|
return;
|
|
@@ -3529,7 +3586,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
3529
3586
|
catch (err) {
|
|
3530
3587
|
const msg = err instanceof Error
|
|
3531
3588
|
? err.message
|
|
3532
|
-
: "
|
|
3589
|
+
: t("agentChat.composer.attachmentError");
|
|
3533
3590
|
setComposerError(msg);
|
|
3534
3591
|
reportAgentChatSubmitResult(submitMessageId, false, "attachment-error");
|
|
3535
3592
|
return;
|
|
@@ -3721,6 +3778,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
3721
3778
|
selectedEffort,
|
|
3722
3779
|
selectedEngine,
|
|
3723
3780
|
selectedModel,
|
|
3781
|
+
t,
|
|
3724
3782
|
updateComposerContextItems,
|
|
3725
3783
|
]);
|
|
3726
3784
|
const mcpResumeTimerRef = useRef(null);
|
|
@@ -4040,7 +4098,8 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
4040
4098
|
getApprovalResolution,
|
|
4041
4099
|
onApprovalResolved: recordApprovalResolution,
|
|
4042
4100
|
onApprove: (approvalKey) => {
|
|
4043
|
-
void addToQueue("Approved. Go ahead and run the requested action.",
|
|
4101
|
+
void addToQueue("Approved. Go ahead and run the requested action.", // i18n-ignore -- stable hidden agent instruction, not UI copy.
|
|
4102
|
+
undefined, undefined, undefined, undefined, "queued", undefined, false, false, false, true, // hideUserMessage: this is a protocol continuation, not a new prompt
|
|
4044
4103
|
undefined, [approvalKey]);
|
|
4045
4104
|
},
|
|
4046
4105
|
...(approvalActions?.onDeny ? { onDeny: approvalActions.onDeny } : {}),
|
|
@@ -4070,19 +4129,19 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
4070
4129
|
? "centered"
|
|
4071
4130
|
: compactMissingKeyEmptyState
|
|
4072
4131
|
? "compact-setup"
|
|
4073
|
-
: undefined, className: cn("relative flex flex-1 flex-col h-full min-h-0 text-foreground", className), onDragEnter: handleChatDragEnter, onDragOver: handleChatDragOver, onDragLeave: handleChatDragLeave, onDropCapture: handleChatDropCapture, onDrop: handleChatDrop, children: [dropActive && (_jsx("div", { "aria-hidden": "true", className: "pointer-events-none absolute inset-0 z-50 flex items-center justify-center rounded-md border-2 border-dashed border-primary/70 bg-primary/5 backdrop-blur-[1px]", children: _jsx("span", { className: "rounded-md bg-background/90 px-3 py-1.5 text-xs font-medium text-foreground shadow-sm", children: "
|
|
4074
|
-
? "
|
|
4132
|
+
: undefined, className: cn("relative flex flex-1 flex-col h-full min-h-0 text-foreground", className), onDragEnter: handleChatDragEnter, onDragOver: handleChatDragOver, onDragLeave: handleChatDragLeave, onDropCapture: handleChatDropCapture, onDrop: handleChatDrop, children: [dropActive && (_jsx("div", { "aria-hidden": "true", className: "pointer-events-none absolute inset-0 z-50 flex items-center justify-center rounded-md border-2 border-dashed border-primary/70 bg-primary/5 backdrop-blur-[1px]", children: _jsx("span", { className: "rounded-md bg-background/90 px-3 py-1.5 text-xs font-medium text-foreground shadow-sm", children: t("agentChat.composer.dropToAttach") }) })), showHeader && (_jsxs("div", { className: "flex h-11 shrink-0 items-center justify-between border-b border-border px-4", children: [_jsx("span", { className: "text-[13px] font-medium text-muted-foreground", children: "Agent" }), _jsx("div", { className: "flex items-center gap-1", children: onSwitchToCli && (_jsx(TooltipProvider, { delayDuration: 200, children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { onClick: onSwitchToCli, "aria-label": t("agentChat.header.switchToCli"), className: "flex items-center gap-1 text-[12px] text-muted-foreground hover:text-foreground px-2 py-1 rounded-md hover:bg-accent", children: [_jsx(IconTerminal, { className: "h-3.5 w-3.5" }), "CLI"] }) }), _jsx(TooltipContent, { children: t("agentChat.header.switchToCli") })] }) })) })] })), _jsxs(MessageScrollerProvider, { autoScroll: true, children: [_jsx(AssistantChatScrollerControls, { resumeFollowingRef: resumeFollowingRef }), _jsxs(MessageScroller, { className: "agent-chat-scroll", children: [_jsx(MessageScrollerViewport, { children: authError ? (_jsxs("div", { className: "flex flex-col items-center justify-center h-full px-4 gap-3", children: [_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-muted", children: authSessionAvailable ? (_jsx(IconRefresh, { className: "h-5 w-5 text-muted-foreground" })) : (_jsx(IconMessage, { className: "h-5 w-5 text-muted-foreground" })) }), _jsxs("div", { className: "text-center max-w-[280px]", children: [_jsx("p", { className: "text-sm font-medium text-foreground mb-1", children: authSessionAvailable
|
|
4133
|
+
? t("agentChat.auth.refreshTitle")
|
|
4075
4134
|
: authError.sessionExpired
|
|
4076
|
-
? "
|
|
4077
|
-
: "
|
|
4078
|
-
? "
|
|
4135
|
+
? t("agentChat.auth.expiredTitle")
|
|
4136
|
+
: t("agentChat.auth.requiredTitle") }), _jsx("p", { className: "text-xs text-muted-foreground leading-relaxed", children: authSessionAvailable
|
|
4137
|
+
? t("agentChat.auth.refreshDescription")
|
|
4079
4138
|
: authError.sessionExpired
|
|
4080
|
-
? "
|
|
4081
|
-
: "
|
|
4139
|
+
? t("agentChat.auth.expiredDescription")
|
|
4140
|
+
: t("agentChat.auth.requiredDescription") })] }), _jsxs("div", { className: "flex gap-2", children: [!authError.sessionExpired &&
|
|
4082
4141
|
!authSessionAvailable && (_jsx("button", { onClick: () => {
|
|
4083
4142
|
window.location.href =
|
|
4084
4143
|
buildSignInReturnHref();
|
|
4085
|
-
}, className: "text-xs text-background bg-foreground hover:opacity-90 px-3 py-1.5 rounded-md", children: "
|
|
4144
|
+
}, className: "text-xs text-background bg-foreground hover:opacity-90 px-3 py-1.5 rounded-md", children: t("agentChat.auth.logIn") })), authError.sessionExpired &&
|
|
4086
4145
|
!authSessionAvailable && (_jsx("button", { onClick: async () => {
|
|
4087
4146
|
try {
|
|
4088
4147
|
await fetch(agentNativePath("/_agent-native/auth/logout"), {
|
|
@@ -4093,16 +4152,18 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
4093
4152
|
console.error("Failed to log out before reloading the chat", error);
|
|
4094
4153
|
}
|
|
4095
4154
|
window.location.reload();
|
|
4096
|
-
}, className: "text-xs text-destructive hover:text-destructive/80 px-3 py-1.5 rounded-md border border-destructive/30 hover:bg-destructive/10", children: "
|
|
4155
|
+
}, className: "text-xs text-destructive hover:text-destructive/80 px-3 py-1.5 rounded-md border border-destructive/30 hover:bg-destructive/10", children: t("agentChat.auth.logOut") })), _jsx("button", { onClick: () => {
|
|
4097
4156
|
setAuthError(null);
|
|
4098
4157
|
window.location.reload();
|
|
4099
4158
|
}, className: authSessionAvailable
|
|
4100
4159
|
? "text-xs text-background bg-foreground hover:opacity-90 px-3 py-1.5 rounded-md"
|
|
4101
|
-
: "text-xs text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md border border-border hover:bg-accent", children: "
|
|
4160
|
+
: "text-xs text-muted-foreground hover:text-foreground px-3 py-1.5 rounded-md border border-border hover:bg-accent", children: t("agentChat.auth.refreshChat") })] })] })) : isRestoring && centeredRestoringState ? (_jsxs("div", { className: cn("agent-empty-state", emptyStateDisplay === "hidden"
|
|
4102
4161
|
? "sr-only"
|
|
4103
|
-
: "flex h-full flex-col items-center justify-center gap-3 px-4 py-16"), "aria-busy": "true", children: [_jsx(IconMessage, { className: "h-5 w-5 text-muted-foreground/60" }), _jsx("p", { className: "sr-only", children: emptyStateText ??
|
|
4162
|
+
: "flex h-full flex-col items-center justify-center gap-3 px-4 py-16"), "aria-busy": "true", children: [_jsx(IconMessage, { className: "h-5 w-5 text-muted-foreground/60" }), _jsx("p", { className: "sr-only", children: emptyStateText ??
|
|
4163
|
+
t("agentChat.empty.loadingChat") })] })) : isRestoring ? (_jsxs("div", { className: "flex flex-col gap-3 p-4", children: [_jsx("div", { className: "flex justify-end", children: _jsx("div", { className: "h-8 w-32 rounded-lg bg-muted animate-pulse" }) }), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("div", { className: "h-4 w-48 rounded bg-muted animate-pulse" }), _jsx("div", { className: "h-4 w-64 rounded bg-muted animate-pulse" }), _jsx("div", { className: "h-4 w-40 rounded bg-muted animate-pulse" })] })] })) : showEmptyState ? (_jsxs("div", { className: cn("agent-empty-state", emptyStateDisplay === "hidden"
|
|
4104
4164
|
? "sr-only"
|
|
4105
|
-
: "flex h-full flex-col items-center justify-center gap-3 px-4 py-16"), children: [_jsx(IconMessage, { className: "h-5 w-5 text-muted-foreground/60" }), _jsx("p", { className: "sr-only", children: emptyStateText ??
|
|
4165
|
+
: "flex h-full flex-col items-center justify-center gap-3 px-4 py-16"), children: [_jsx(IconMessage, { className: "h-5 w-5 text-muted-foreground/60" }), _jsx("p", { className: "sr-only", children: emptyStateText ??
|
|
4166
|
+
t("agentChat.empty.prompt") }), emptyStateAddon, resolvedSuggestions &&
|
|
4106
4167
|
resolvedSuggestions.length > 0 ? (_jsx("div", { className: "flex w-full max-w-[280px] flex-col gap-1", children: resolvedSuggestions.map((suggestion) => (_jsx("button", { onClick: () => {
|
|
4107
4168
|
if (engineSetupRequired) {
|
|
4108
4169
|
requestMissingKeySetup();
|
|
@@ -4110,13 +4171,33 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
4110
4171
|
}
|
|
4111
4172
|
void addToQueue(suggestion);
|
|
4112
4173
|
}, className: "w-full px-2 py-1 text-center text-[13px] text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", children: suggestion }, suggestion))) })) : null, showInlineEmptyThreadFooterSlot ? (_jsx("div", { className: "agent-thread-footer-slot agent-thread-footer-slot--empty", children: resolvedThreadFooterSlot })) : null] })) : (_jsxs(MessageScrollerContent, { className: "agent-thread-content gap-4 px-4 py-4", children: [_jsx(AssistantMessageListErrorBoundary, { resetKey: messageListResetKey, children: _jsx(UserStoppedRunContext.Provider, { value: wasRecentlyStoppedRun, children: _jsx(ThreadPrimitive.Messages
|
|
4113
|
-
//
|
|
4114
|
-
//
|
|
4115
|
-
//
|
|
4116
|
-
|
|
4174
|
+
// Deliberately NOT keyed on part structure. Doing that
|
|
4175
|
+
// remounted the whole transcript every time a tool call
|
|
4176
|
+
// started or a placeholder id was rewritten — a flash and a
|
|
4177
|
+
// lost scroll position in the middle of an answer. The
|
|
4178
|
+
// error boundary above is the mechanism for assistant-ui's
|
|
4179
|
+
// stale tap-resource errors: it catches them, clears, and
|
|
4180
|
+
// retries, and its retry signature includes the reset key so
|
|
4181
|
+
// a genuinely new structure always gets a fresh budget.
|
|
4182
|
+
// `assistant-ui-part-churn.spec.tsx` drives append, mutate,
|
|
4183
|
+
// rename and splice through both the import and streaming
|
|
4184
|
+
// paths and records that no such error occurs.
|
|
4185
|
+
, {
|
|
4186
|
+
// Deliberately NOT keyed on part structure. Doing that
|
|
4187
|
+
// remounted the whole transcript every time a tool call
|
|
4188
|
+
// started or a placeholder id was rewritten — a flash and a
|
|
4189
|
+
// lost scroll position in the middle of an answer. The
|
|
4190
|
+
// error boundary above is the mechanism for assistant-ui's
|
|
4191
|
+
// stale tap-resource errors: it catches them, clears, and
|
|
4192
|
+
// retries, and its retry signature includes the reset key so
|
|
4193
|
+
// a genuinely new structure always gets a fresh budget.
|
|
4194
|
+
// `assistant-ui-part-churn.spec.tsx` drives append, mutate,
|
|
4195
|
+
// rename and splice through both the import and streaming
|
|
4196
|
+
// paths and records that no such error occurs.
|
|
4197
|
+
components: {
|
|
4117
4198
|
UserMessage: AssistantChatUserMessageItem,
|
|
4118
4199
|
AssistantMessage: AssistantChatAssistantMessageItem,
|
|
4119
|
-
} }
|
|
4200
|
+
} }) }) }), visibleLoopLimit && !showRunningInUI && (_jsx(MessageScrollerItem, { children: _jsx(LoopLimitContinueCard, { info: visibleLoopLimit, onContinue: () => {
|
|
4120
4201
|
setShowContinue(false);
|
|
4121
4202
|
setLoopLimitInfo(null);
|
|
4122
4203
|
addToQueue("Continue from where you left off.", undefined, undefined, undefined, undefined, "queued", "continue");
|
|
@@ -4132,10 +4213,12 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
4132
4213
|
visibleReconnectContent.length > 0 && (_jsx(MessageScrollerItem, { children: _jsx(ReconnectStreamMessage, { content: visibleReconnectContent, allowActivitySpinner: !reconnectFrozen }) })), showReconnectOverlay &&
|
|
4133
4214
|
visibleReconnectContent.length === 0 &&
|
|
4134
4215
|
reconnectContent.length === 0 &&
|
|
4135
|
-
reconnectActivityContent.length > 0 && (_jsx(MessageScrollerItem, { children: _jsx(ReconnectStreamMessage, { content: reconnectActivityContent, allowActivitySpinner: !reconnectFrozen }) })), showGlobalRunningStatus && (_jsx(MessageScrollerItem, { children: _jsx(RunningActivityStatus, { label: runningStatusLabel }) })), visibleQueuedMessages.length > 0 && (_jsx(MessageScrollerItem, { children: _jsxs("div", { className: "flex items-center justify-end gap-1.5 pr-0.5 text-xs text-muted-foreground", children: [_jsx(IconClock, { className: "h-3 w-3" }),
|
|
4216
|
+
reconnectActivityContent.length > 0 && (_jsx(MessageScrollerItem, { children: _jsx(ReconnectStreamMessage, { content: reconnectActivityContent, allowActivitySpinner: !reconnectFrozen }) })), showGlobalRunningStatus && (_jsx(MessageScrollerItem, { children: _jsx(RunningActivityStatus, { label: runningStatusLabel }) })), visibleQueuedMessages.length > 0 && (_jsx(MessageScrollerItem, { children: _jsxs("div", { className: "flex items-center justify-end gap-1.5 pr-0.5 text-xs text-muted-foreground", children: [_jsx(IconClock, { className: "h-3 w-3" }), _jsx("span", { children: t("agentChat.queue.count", {
|
|
4217
|
+
count: visibleQueuedMessages.length,
|
|
4218
|
+
}) })] }) })), visibleQueuedMessages.map((msg) => {
|
|
4136
4219
|
const displayText = displayableUserMessageText(msg.text);
|
|
4137
4220
|
const imageSources = queuedMessageImageSources(msg);
|
|
4138
|
-
return (_jsx(MessageScrollerItem, { messageId: msg.id, children: _jsxs("div", { className: "group flex items-start justify-end gap-1.5", children: [isRunning && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => sendQueuedMessageNow(msg.id), "aria-label": "
|
|
4221
|
+
return (_jsx(MessageScrollerItem, { messageId: msg.id, children: _jsxs("div", { className: "group flex items-start justify-end gap-1.5", children: [isRunning && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => sendQueuedMessageNow(msg.id), "aria-label": t("agentChat.queue.sendNow"), className: "mt-1.5 flex h-5 w-5 cursor-pointer items-center justify-center rounded-full border border-border bg-background text-muted-foreground opacity-0 shadow-sm transition-opacity hover:bg-accent hover:text-foreground focus-visible:opacity-100 group-hover:opacity-100", children: _jsx(IconArrowUp, { className: "h-3 w-3" }) }) }), _jsx(TooltipContent, { children: t("agentChat.queue.sendNowHint") })] })), _jsx("button", { type: "button", onClick: () => applyLocalQueuedMessages((prev) => prev.filter((m) => m.id !== msg.id)), "aria-label": t("agentChat.queue.remove"), className: "mt-1.5 flex h-5 w-5 cursor-pointer items-center justify-center rounded-full border border-border bg-background text-muted-foreground opacity-0 shadow-sm transition-opacity hover:bg-accent hover:text-foreground focus-visible:opacity-100 group-hover:opacity-100", children: _jsx(IconX, { className: "h-3 w-3" }) }), _jsxs("div", { className: "max-w-[85%] rounded-lg bg-accent/50 px-3 py-2 text-sm leading-relaxed text-foreground/60 whitespace-pre-wrap break-words", children: [displayText, imageSources.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-1.5 mt-1.5", children: imageSources.map((img, j) => (_jsx("img", { src: img, alt: "", className: "h-12 w-12 rounded object-cover border border-border/50" }, j))) }))] })] }) }, msg.id));
|
|
4139
4222
|
}), resolvedThreadFooterSlot ? (_jsx(MessageScrollerItem, { children: _jsx("div", { className: "agent-thread-footer-slot", children: resolvedThreadFooterSlot }) })) : null] })) }), !authError && !isRestoring && !showEmptyState ? (_jsx(MessageScrollerButton, {})) : null] })] }, chatScrollResetKey), showComposerSlot ? composerSlot : null, isActiveComposer && (_jsx(McpConnectionSuggestion, { text: composerText })), showCenteredEmptyThreadFooterSlot ? (_jsx("div", { className: "agent-thread-footer-slot agent-thread-footer-slot--centered-empty", children: resolvedThreadFooterSlot })) : null, guidedQuestions && guidedQuestions.length > 0 && (_jsx("div", { className: "shrink-0 px-3 pb-2", children: _jsx(GuidedQuestionFlow, { questions: guidedQuestions, onSubmit: handleGuidedQuestionsSubmit, onSkip: handleGuidedQuestionsSkip, ...(guidedQuestionsTitle
|
|
4140
4223
|
? { title: guidedQuestionsTitle }
|
|
4141
4224
|
: {}), ...(guidedQuestionsDescription
|
|
@@ -4144,7 +4227,7 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
4144
4227
|
? { skipLabel: guidedQuestionsSkipLabel }
|
|
4145
4228
|
: {}), ...(guidedQuestionsSubmitLabel
|
|
4146
4229
|
? { submitLabel: guidedQuestionsSubmitLabel }
|
|
4147
|
-
: {}), className: "h-auto items-stretch justify-stretch bg-transparent" }) })), composerError && (_jsxs("div", { role: "alert", className: "shrink-0 mx-3 mb-1.5 flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: [_jsx(IconAlertTriangle, { className: "h-3.5 w-3.5 mt-0.5 shrink-0" }), _jsx("span", { className: "flex-1 leading-snug", children: composerError }), _jsx("button", { type: "button", "aria-label": "
|
|
4230
|
+
: {}), className: "h-auto items-stretch justify-stretch bg-transparent" }) })), composerError && (_jsxs("div", { role: "alert", className: "shrink-0 mx-3 mb-1.5 flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: [_jsx(IconAlertTriangle, { className: "h-3.5 w-3.5 mt-0.5 shrink-0" }), _jsx("span", { className: "flex-1 leading-snug", children: composerError }), _jsx("button", { type: "button", "aria-label": t("agentChat.common.dismissError"), onClick: () => setComposerError(null), className: "shrink-0 opacity-70 hover:opacity-100", children: _jsx(IconX, { className: "h-3 w-3" }) })] })), _jsxs("div", { className: "agent-composer-stack", "data-agent-composer-adjacent-ui": hasComposerAccessoryAboveStack
|
|
4148
4231
|
? "true"
|
|
4149
4232
|
: undefined, children: [_jsx(SelectionAttachedPill, {}), showPlanModeCallout && (_jsx(PlanModeCallout, { canImplementPlan: canImplementPlan, onImplementPlan: handleImplementPlan, onSwitchToAct: handleSwitchToAct })), showInlineMissingKeySetup ? (_jsx(BuilderSetupCard, { fullWidth: true, layout: "sidebar", onConnected: handleBuilderConnected })) : null, _jsxs(Popover, { open: showMissingKeySetup &&
|
|
4150
4233
|
!showInlineMissingKeySetup &&
|
|
@@ -4152,24 +4235,26 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
4152
4235
|
!showMissingKeySetup &&
|
|
4153
4236
|
"opacity-70"), rootClassName: cn(showMissingKeySetup &&
|
|
4154
4237
|
"agent-composer-root--missing-key"), children: showMissingKeySetup &&
|
|
4155
|
-
!showInlineMissingKeySetup ? (_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { type: "button", className: "agent-composer-missing-key-trigger", "aria-label": "
|
|
4238
|
+
!showInlineMissingKeySetup ? (_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { type: "button", className: "agent-composer-missing-key-trigger", "aria-label": t("agentChat.setup.connectToStart"), children: _jsxs("span", { className: "agent-composer-missing-key-content", children: [_jsxs("span", { className: "agent-composer-missing-key-copy", children: [_jsx("span", { className: "agent-composer-missing-key-title", children: missingApiKeySetupLayout ===
|
|
4156
4239
|
"sidebar"
|
|
4157
|
-
? "
|
|
4158
|
-
: "
|
|
4159
|
-
"sidebar" ? (_jsx("span", { className: "agent-composer-missing-key-description", children: "
|
|
4240
|
+
? t("agentChat.setup.connectToChat")
|
|
4241
|
+
: t("agentChat.setup.connectToStart") }), missingApiKeySetupLayout !==
|
|
4242
|
+
"sidebar" ? (_jsx("span", { className: "agent-composer-missing-key-description", children: t("agentChat.setup.builderCredits") })) : null] }), _jsx("span", { className: "agent-composer-missing-key-cta", children: t("agentChat.setup.connectAi") })] }) }) })) : (_jsxs(_Fragment, { children: [_jsx(ComposerAttachmentPreviewStrip, {}), _jsx(TiptapComposer, { focusRef: tiptapRef, onTextChange: isActiveComposer
|
|
4160
4243
|
? handleComposerTextChange
|
|
4161
4244
|
: undefined, disabled: isComposerDisabled ||
|
|
4162
4245
|
showInlineMissingKeySetup, placeholder: showInlineMissingKeySetup
|
|
4163
|
-
? "
|
|
4246
|
+
? t("agentChat.setup.connectPlaceholder")
|
|
4164
4247
|
: engineSetupRequired
|
|
4165
|
-
? "
|
|
4248
|
+
? t("agentChat.setup.connectPlaceholder")
|
|
4166
4249
|
: composerDisabled
|
|
4167
4250
|
? (composerDisabledPlaceholder ??
|
|
4168
|
-
"
|
|
4251
|
+
t("agentChat.composer.openDesktop"))
|
|
4169
4252
|
: isRunning
|
|
4170
4253
|
? queuedMessages.length > 0
|
|
4171
|
-
?
|
|
4172
|
-
|
|
4254
|
+
? t("agentChat.queue.followUpWithCount", {
|
|
4255
|
+
count: queuedMessages.length,
|
|
4256
|
+
})
|
|
4257
|
+
: t("agentChat.queue.followUp")
|
|
4173
4258
|
: resolveAssistantChatComposerPlaceholder(composerPlaceholder), onSubmit: isRunning ||
|
|
4174
4259
|
composerContextItems.length > 0
|
|
4175
4260
|
? (text, references, attachments, options) => void addToQueue(text, undefined, references.length > 0
|
|
@@ -4178,9 +4263,11 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
4178
4263
|
isRunning,
|
|
4179
4264
|
requestedIntent: options?.intent,
|
|
4180
4265
|
}), undefined, true)
|
|
4181
|
-
: undefined, willQueue: engineSetupRequired || isRunning, onSlashCommand: onSlashCommand, execMode: execMode, onExecModeChange: onExecModeChange, planModeDisabled: planModeDisabled, planModeDisabledReason: planModeDisabledReason, selectedModel: selectedModel ?? defaultModel, selectedEffort: selectedEffort, availableModels: availableModels, modelListLoading: modelListLoading, onModelChange:
|
|
4266
|
+
: undefined, willQueue: engineSetupRequired || isRunning, onSlashCommand: onSlashCommand, execMode: execMode, onExecModeChange: onExecModeChange, planModeDisabled: planModeDisabled, planModeDisabledReason: planModeDisabledReason, selectedModel: selectedModel ?? defaultModel, selectedEffort: selectedEffort, availableModels: availableModels, modelListLoading: modelListLoading, onModelChange: shouldShowAssistantChatModelSelector(showModelSelector)
|
|
4267
|
+
? onModelChange
|
|
4268
|
+
: undefined, onEffortChange: onEffortChange, imageModelMenu: imageModelMenu, onConnectProvider: onConnectProvider, onConnectLocalRuntime: onConnectLocalRuntime, toolbarSlot: composerToolbarSlot, contextItems: composerContextItems, onRemoveContextItem: removeComposerContextItem, plusMenuMode: plusMenuMode, layoutVariant: composerLayoutVariant, providerConnectStatusEnabled: providerStatusChecksEnabled, voiceEnabled: true, draftScope: threadId || tabId, interceptBuildRequestsForBuilder: true, onAttachmentError: setComposerError, extraActionButton: composerExtraActionButton, stopButton: showRunningInUI ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => stopActiveRun({
|
|
4182
4269
|
preserveQueuedMessages: true,
|
|
4183
|
-
}), "aria-label": "
|
|
4270
|
+
}), "aria-label": t("agentChat.composer.stopResponse"), "data-agent-composer-slot": "stop-button", className: "shrink-0 flex h-7 w-7 cursor-pointer items-center justify-center rounded-full bg-primary text-primary-foreground shadow-sm transition-opacity hover:opacity-90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", children: _jsx(IconPlayerStopFilled, { className: "h-3 w-3" }) }) }), _jsx(TooltipContent, { children: t("agentChat.composer.stopResponse") })] })) : undefined })] })) }), showMissingKeySetup &&
|
|
4184
4271
|
!showInlineMissingKeySetup ? (_jsx(PopoverContent, { side: missingApiKeySetupLayout === "sidebar"
|
|
4185
4272
|
? "top"
|
|
4186
4273
|
: "bottom", align: "center", sideOffset: 8, collisionPadding: 12, "data-agent-native-composer-popover": "true", className: "z-[260] box-border w-[min(calc(100vw-2rem),var(--radix-popover-content-available-width,26rem),26rem)] rounded-lg border-border p-3 shadow-lg", children: _jsx(BuilderSetupContent, { onConnected: handleBuilderConnected, layout: missingApiKeySetupLayout }) })) : null] })] })] }) }) }) }) }) }) }) }) }) }) }));
|
|
@@ -44,6 +44,13 @@ export function HighlightedCodeBlock({ code, lang, containerClass, streaming = f
|
|
|
44
44
|
const renderedHashRef = useRef(null);
|
|
45
45
|
const debounceTimerRef = useRef(null);
|
|
46
46
|
const cancelledRef = useRef(false);
|
|
47
|
+
// Whether this block has already put code on screen. Reserving space
|
|
48
|
+
// invisibly is right on FIRST paint — it avoids an unhighlighted→highlighted
|
|
49
|
+
// flash — but once code is visible, hiding it again to wait for Shiki blanks
|
|
50
|
+
// a code box the user was reading. That is what happened whenever the block
|
|
51
|
+
// lost its html (a re-highlight after the content changed): readable code
|
|
52
|
+
// went blank mid-answer.
|
|
53
|
+
const hasPaintedRef = useRef(false);
|
|
47
54
|
useEffect(() => {
|
|
48
55
|
cancelledRef.current = false;
|
|
49
56
|
return () => {
|
|
@@ -108,11 +115,14 @@ export function HighlightedCodeBlock({ code, lang, containerClass, streaming = f
|
|
|
108
115
|
}
|
|
109
116
|
}, [code, lang, streaming, loadHighlighter]);
|
|
110
117
|
if (html) {
|
|
118
|
+
hasPaintedRef.current = true;
|
|
111
119
|
return (_jsx("div", { className: containerClass, dangerouslySetInnerHTML: { __html: html } }));
|
|
112
120
|
}
|
|
113
121
|
// Streaming: show plain growing text (previous html already kept above when
|
|
114
122
|
// available). Non-streaming first paint: reserve space invisibly so we never
|
|
115
|
-
// flash unhighlighted → highlighted.
|
|
116
|
-
const showPlain = streaming || failed;
|
|
123
|
+
// flash unhighlighted → highlighted. Once painted, never hide again.
|
|
124
|
+
const showPlain = streaming || failed || hasPaintedRef.current;
|
|
125
|
+
if (showPlain)
|
|
126
|
+
hasPaintedRef.current = true;
|
|
117
127
|
return (_jsx("div", { className: containerClass, "aria-busy": !showPlain && !failed, children: _jsx("pre", { children: _jsx("code", { className: lang ? `language-${lang}` : undefined, style: showPlain ? undefined : { visibility: "hidden" }, children: code }) }) }));
|
|
118
128
|
}
|