@agent-native/core 0.157.2 → 0.157.4
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/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/analytics/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +40 -1
- package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/assets/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/brain/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/calendar/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +3 -1
- package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/chat/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/clips/.agents/skills/meetings/SKILL.md +7 -7
- package/corpus/templates/clips/actions/approve-recording-access-request.ts +147 -0
- package/corpus/templates/clips/actions/request-recording-access.ts +121 -23
- package/corpus/templates/clips/actions/view-screen.ts +1 -1
- package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +34 -53
- package/corpus/templates/clips/app/components/player/request-access-dialog.tsx +104 -0
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +36 -45
- package/corpus/templates/clips/app/components/sharing/share-ui.tsx +3 -6
- package/corpus/templates/clips/app/i18n/en-US.ts +26 -1
- package/corpus/templates/clips/app/lib/public-meeting.ts +1 -1
- package/corpus/templates/clips/app/routes/access-request.approve.tsx +250 -0
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +9 -32
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +123 -37
- package/corpus/templates/clips/app/routes/share.meeting.$meetingId.tsx +41 -1
- package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +1 -0
- package/corpus/templates/clips/server/lib/emails.ts +40 -11
- package/corpus/templates/clips/shared/recording-link.ts +32 -1
- package/corpus/templates/clips/shared/share-attribution.ts +13 -0
- package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/content/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/content/actions/add-database-item.ts +9 -0
- package/corpus/templates/content/actions/describe-content-database.ts +92 -0
- package/corpus/templates/content/actions/list-content-databases.ts +213 -72
- package/corpus/templates/content/actions/set-document-property.ts +9 -0
- package/corpus/templates/content/actions/submit-content-database-form.ts +9 -0
- package/corpus/templates/content/actions/update-document.ts +9 -0
- package/corpus/templates/content/app/components/editor/DocumentBlockFields.tsx +22 -10
- package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +2 -1
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +245 -9
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +192 -134
- package/corpus/templates/content/app/components/editor/database/settings.tsx +7 -0
- package/corpus/templates/content/app/components/editor/extensions/ImageBlock.tsx +61 -45
- package/corpus/templates/content/app/components/editor/extensions/ImageNode.ts +6 -0
- package/corpus/templates/content/app/components/editor/image-upload.ts +137 -5
- package/corpus/templates/content/app/global.css +8 -0
- package/corpus/templates/content/app/hooks/use-content-database.ts +91 -11
- package/corpus/templates/content/changelog/2026-08-12-image-uploads-now-confirm-the-image-can-be-displayed-before-.md +6 -0
- package/corpus/templates/content/changelog/2026-08-14-images-fill-the-page-width-by-default-and-remain-visible-whe.md +6 -0
- package/corpus/templates/content/changelog/2026-08-14-images-inserted-from-the-slash-command-stay-saved-after-uplo.md +6 -0
- package/corpus/templates/content/changelog/2026-08-14-svg-files-can-be-selected-reliably-from-the-image-picker.md +6 -0
- package/corpus/templates/content/parity/matrix.md +1 -1
- package/corpus/templates/content/parity/matrix.ts +7 -1
- package/corpus/templates/content/server/plugins/agent-chat.ts +3 -0
- package/corpus/templates/content/shared/api.ts +9 -0
- package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/crm/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/design/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/dispatch/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/factory/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/factory/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/forms/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/macros/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/mail/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +6 -1
- package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/plan/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/plan/app/pages/PlansPage.tsx +25 -30
- package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/slides/.agents/skills/sharing/SKILL.md +21 -0
- package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +2 -1
- package/corpus/templates/slides/app/components/editor/ShareDialog.tsx +124 -180
- package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +1 -0
- package/corpus/templates/slides/app/global.css +99 -3
- package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
- package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/corpus/templates/tasks/.agents/skills/sharing/SKILL.md +21 -0
- package/dist/chat-threads/schema.d.ts +1 -1
- package/dist/cli/code-agent-executor.js +318 -0
- package/dist/client/AgentPanel.d.ts +13 -1
- package/dist/client/AgentPanel.js +41 -3
- package/dist/client/AssistantChat.d.ts +9 -1
- package/dist/client/AssistantChat.js +26 -13
- package/dist/client/MultiTabAssistantChat.js +18 -5
- package/dist/client/agent-chat.d.ts +8 -0
- package/dist/client/agent-chat.js +15 -0
- package/dist/client/app-chat-sidebar.d.ts +23 -0
- package/dist/client/app-chat-sidebar.js +53 -0
- package/dist/client/app-providers.js +31 -2
- package/dist/client/frame-protocol.d.ts +20 -2
- package/dist/client/hooks/index.d.ts +1 -0
- package/dist/client/hooks/index.js +1 -0
- package/dist/client/sharing/AgentShareSection.d.ts +8 -0
- package/dist/client/sharing/AgentShareSection.js +50 -0
- package/dist/client/sharing/ShareButton.js +2 -1
- package/dist/client/sharing/ShareDialog.d.ts +2 -2
- package/dist/client/sharing/ShareDialog.js +21 -29
- package/dist/client/sharing/index.d.ts +1 -0
- package/dist/client/sharing/index.js +1 -0
- package/dist/client/sharing/useShareButtonController.d.ts +1 -0
- package/dist/client/sharing/useShareDialogController.d.ts +3 -0
- package/dist/client/sharing/useShareDialogController.js +2 -1
- package/dist/client/theme.d.ts +21 -0
- package/dist/client/theme.js +60 -0
- package/dist/client/ui/index.d.ts +1 -1
- package/dist/client/ui/index.js +1 -1
- package/dist/client/use-session.js +23 -0
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/dashboard-storage/schema.d.ts +1 -1
- package/dist/data-programs/schema.d.ts +1 -1
- package/dist/extensions/schema.d.ts +1 -1
- package/dist/localization/core-messages/ar-SA.js +6 -0
- package/dist/localization/core-messages/de-DE.js +6 -0
- package/dist/localization/core-messages/en-US.d.ts +6 -0
- package/dist/localization/core-messages/en-US.js +6 -0
- package/dist/localization/core-messages/es-ES.js +6 -0
- package/dist/localization/core-messages/fr-FR.js +6 -0
- package/dist/localization/core-messages/hi-IN.js +6 -0
- package/dist/localization/core-messages/ja-JP.js +6 -0
- package/dist/localization/core-messages/ko-KR.js +6 -0
- package/dist/localization/core-messages/pt-BR.js +6 -0
- package/dist/localization/core-messages/zh-CN.js +6 -0
- package/dist/localization/core-messages/zh-TW.js +6 -0
- package/dist/localization/core-messages.d.ts +6 -0
- package/dist/localization/default-messages.d.ts +1 -0
- package/dist/localization/default-messages.js +1 -0
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +5 -5
- package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
- package/dist/provider-api/actions/provider-api.d.ts +14 -14
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/auth.js +8 -5
- package/dist/server/identity-sso-store.d.ts +6 -1
- package/dist/server/identity-sso-store.js +57 -14
- package/dist/server/identity-sso.d.ts +7 -8
- package/dist/server/identity-sso.js +15 -12
- package/dist/sharing/actions/list-resource-shares.d.ts +2 -0
- package/dist/sharing/actions/list-resource-shares.js +1 -0
- package/dist/sharing/schema.d.ts +1 -1
- package/dist/sharing/schema.js +4 -1
- package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/dist/templates/chat/.agents/skills/sharing/SKILL.md +21 -0
- package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/dist/templates/default/.agents/skills/sharing/SKILL.md +21 -0
- package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/dist/templates/workspace-core/.agents/skills/sharing/SKILL.md +21 -0
- package/docs/content/cross-app-sso.mdx +24 -17
- package/package.json +3 -3
- package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/src/templates/chat/.agents/skills/sharing/SKILL.md +21 -0
- package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/src/templates/default/.agents/skills/sharing/SKILL.md +21 -0
- package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
- package/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +21 -0
|
@@ -10,7 +10,7 @@ import { useState, useRef, useEffect, useCallback, useMemo, useLayoutEffect, for
|
|
|
10
10
|
import { createPollEngine } from "../shared/poll-engine.js";
|
|
11
11
|
import { clearPendingTurnIfMatches, clearActiveRunIfMatches, getPendingTurn, getActiveRunActivityTool, getActiveRun, hasRecentActiveRunProgress, resolveReconnectAfterSeq, setActiveRun, updateActiveRunActivity, updateActiveRunSeq, } from "./active-run-state.js";
|
|
12
12
|
import { activeRunLooksAlive, createAgentChatAdapter, hasInFlightToolCall, } from "./agent-chat-adapter.js";
|
|
13
|
-
import { appendAgentChatContextToMessage, formatAgentChatContextItemsForPrompt, getAgentChatContextState, isAgentChatSubmitCancelled, normalizeAgentChatContextItem, publishAgentChatContextItems, refreshAgentChatContext, reportAgentChatSubmitResult, subscribeAgentChatContext, } from "./agent-chat.js";
|
|
13
|
+
import { appendAgentChatContextToMessage, filterAgentChatContextItems, formatAgentChatContextItemsForPrompt, getAgentChatContextState, isAgentChatSubmitCancelled, normalizeAgentChatContextItem, publishAgentChatContextItems, refreshAgentChatContext, reportAgentChatSubmitResult, subscribeAgentChatContext, } from "./agent-chat.js";
|
|
14
14
|
import { captureError } from "./analytics.js";
|
|
15
15
|
import { agentNativePath } from "./api-path.js";
|
|
16
16
|
import { AssistantMessageListErrorBoundary, AssistantUiStaleIndexErrorBoundary, } from "./assistant-ui-recovery.js";
|
|
@@ -1375,7 +1375,7 @@ export function useAutoResumeStatus(tabId, forceStopped) {
|
|
|
1375
1375
|
function approvalResolutionIdentity(approvalKey, toolCallId) {
|
|
1376
1376
|
return `${toolCallId ?? ""}\u0000${approvalKey}`;
|
|
1377
1377
|
}
|
|
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) {
|
|
1378
|
+
const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateText, suggestions, dynamicSuggestions, threadFooterSlot, emptyStateAddon, showHeader = true, onSwitchToCli, className, apiUrl, tabId, browserTabId, threadId, contextScope, contextNamespace, 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, availableAgents, selectedAgent, onAgentChange, imageModelMenu, onForkChat, onConnectProvider, onConnectLocalRuntime, plusMenuMode = "full", providerStatusChecksEnabled = true, loadHistoryRepository, historyReloadKey, externalStreaming = false, agentChatSurface = "app", suppressInlineOpenApp = false, }, ref) {
|
|
1379
1379
|
const t = useT();
|
|
1380
1380
|
const thread = useThread();
|
|
1381
1381
|
const threadRuntime = useThreadRuntime();
|
|
@@ -1529,11 +1529,18 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1529
1529
|
const composerContextItemsRef = useRef([]);
|
|
1530
1530
|
const isActiveComposerRef = useRef(isActiveComposer);
|
|
1531
1531
|
isActiveComposerRef.current = isActiveComposer;
|
|
1532
|
+
const normalizedContextNamespace = contextNamespace?.trim() || undefined;
|
|
1532
1533
|
const publishComposerContextItems = useCallback((items) => {
|
|
1533
1534
|
if (!isActiveComposerRef.current)
|
|
1534
1535
|
return;
|
|
1535
|
-
|
|
1536
|
-
|
|
1536
|
+
const hiddenItems = normalizedContextNamespace
|
|
1537
|
+
? getAgentChatContextState().items.filter((item) => {
|
|
1538
|
+
const itemNamespace = item.contextNamespace?.trim();
|
|
1539
|
+
return (itemNamespace && itemNamespace !== normalizedContextNamespace);
|
|
1540
|
+
})
|
|
1541
|
+
: [];
|
|
1542
|
+
publishAgentChatContextItems([...hiddenItems, ...items]);
|
|
1543
|
+
}, [normalizedContextNamespace]);
|
|
1537
1544
|
const updateComposerContextItems = useCallback((updater) => {
|
|
1538
1545
|
setComposerContextItems((previous) => {
|
|
1539
1546
|
const next = updater(previous);
|
|
@@ -1556,6 +1563,10 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1556
1563
|
const item = normalizeAgentChatContextItem(rawItem);
|
|
1557
1564
|
if (!item)
|
|
1558
1565
|
return;
|
|
1566
|
+
if (filterAgentChatContextItems([item], normalizedContextNamespace)
|
|
1567
|
+
.length === 0) {
|
|
1568
|
+
return;
|
|
1569
|
+
}
|
|
1559
1570
|
updateComposerContextItems((previous) => {
|
|
1560
1571
|
const index = previous.findIndex((current) => current.key === item.key);
|
|
1561
1572
|
if (index === -1)
|
|
@@ -1594,21 +1605,23 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
1594
1605
|
void refreshAgentChatContext().then((state) => {
|
|
1595
1606
|
if (cancelled || !isActiveComposerRef.current)
|
|
1596
1607
|
return;
|
|
1597
|
-
|
|
1598
|
-
|
|
1608
|
+
const visibleItems = filterAgentChatContextItems(state.items, normalizedContextNamespace);
|
|
1609
|
+
composerContextItemsRef.current = visibleItems;
|
|
1610
|
+
setComposerContextItems(visibleItems);
|
|
1599
1611
|
});
|
|
1600
1612
|
const unsubscribe = subscribeAgentChatContext(() => {
|
|
1601
1613
|
if (cancelled || !isActiveComposerRef.current)
|
|
1602
1614
|
return;
|
|
1603
1615
|
const state = getAgentChatContextState();
|
|
1604
|
-
|
|
1605
|
-
|
|
1616
|
+
const visibleItems = filterAgentChatContextItems(state.items, normalizedContextNamespace);
|
|
1617
|
+
composerContextItemsRef.current = visibleItems;
|
|
1618
|
+
setComposerContextItems(visibleItems);
|
|
1606
1619
|
});
|
|
1607
1620
|
return () => {
|
|
1608
1621
|
cancelled = true;
|
|
1609
1622
|
unsubscribe();
|
|
1610
1623
|
};
|
|
1611
|
-
}, [isActiveComposer]);
|
|
1624
|
+
}, [isActiveComposer, normalizedContextNamespace]);
|
|
1612
1625
|
// Tracks the JSON of the last queue we successfully persisted so the
|
|
1613
1626
|
// debounced save effect can skip no-op writes (e.g. restore-from-server
|
|
1614
1627
|
// on mount, or queue state that hasn't actually changed).
|
|
@@ -4263,16 +4276,16 @@ const AssistantChatInner = forwardRef(function AssistantChatInner({ emptyStateTe
|
|
|
4263
4276
|
isRunning,
|
|
4264
4277
|
requestedIntent: options?.intent,
|
|
4265
4278
|
}), undefined, true)
|
|
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)
|
|
4279
|
+
: undefined, willQueue: engineSetupRequired || isRunning, onSlashCommand: onSlashCommand, execMode: execMode, onExecModeChange: onExecModeChange, planModeDisabled: planModeDisabled, planModeDisabledReason: planModeDisabledReason, selectedModel: selectedModel ?? defaultModel, selectedEffort: selectedEffort, availableModels: availableModels, availableAgents: availableAgents, selectedAgent: selectedAgent, modelListLoading: modelListLoading, onModelChange: shouldShowAssistantChatModelSelector(showModelSelector)
|
|
4267
4280
|
? 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({
|
|
4281
|
+
: undefined, onEffortChange: onEffortChange, onAgentChange: onAgentChange, 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({
|
|
4269
4282
|
preserveQueuedMessages: true,
|
|
4270
4283
|
}), "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 &&
|
|
4271
4284
|
!showInlineMissingKeySetup ? (_jsx(PopoverContent, { side: missingApiKeySetupLayout === "sidebar"
|
|
4272
4285
|
? "top"
|
|
4273
4286
|
: "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] })] })] }) }) }) }) }) }) }) }) }) }) }));
|
|
4274
4287
|
});
|
|
4275
|
-
export const AssistantChat = forwardRef(function AssistantChat({ apiUrl = agentNativePath("/_agent-native/agent-chat"), tabId, browserTabId, threadId, contextScope, isActiveComposer, ...props }, ref) {
|
|
4288
|
+
export const AssistantChat = forwardRef(function AssistantChat({ apiUrl = agentNativePath("/_agent-native/agent-chat"), tabId, browserTabId, threadId, contextScope, contextNamespace, isActiveComposer, ...props }, ref) {
|
|
4276
4289
|
const modelRef = useRef(props.selectedModel);
|
|
4277
4290
|
modelRef.current = props.selectedModel;
|
|
4278
4291
|
const engineRef = useRef(props.selectedEngine);
|
|
@@ -4335,5 +4348,5 @@ export const AssistantChat = forwardRef(function AssistantChat({ apiUrl = agentN
|
|
|
4335
4348
|
const runtime = useLocalRuntime(adapter, {
|
|
4336
4349
|
adapters: { attachments: attachmentAdapter },
|
|
4337
4350
|
});
|
|
4338
|
-
return (_jsx(AssistantRuntimeProvider, { runtime: runtime, children: _jsx(TooltipProvider, { delayDuration: 200, children: _jsx(ThreadPrimitive.Root, { className: "flex flex-1 flex-col h-full min-h-0 overflow-x-hidden", children: _jsx(AssistantUiStaleIndexErrorBoundary, { resetKey: `${tabId ?? ""}:${threadId ?? ""}`, componentName: "AssistantChat", children: _jsx(AssistantChatInner, { ref: ref, ...props, browserTabId: browserTabId, contextScope: contextScope, isActiveComposer: isActiveComposer, apiUrl: apiUrl, tabId: tabId, threadId: threadId }) }) }) }) }));
|
|
4351
|
+
return (_jsx(AssistantRuntimeProvider, { runtime: runtime, children: _jsx(TooltipProvider, { delayDuration: 200, children: _jsx(ThreadPrimitive.Root, { className: "flex flex-1 flex-col h-full min-h-0 overflow-x-hidden", children: _jsx(AssistantUiStaleIndexErrorBoundary, { resetKey: `${tabId ?? ""}:${threadId ?? ""}`, componentName: "AssistantChat", children: _jsx(AssistantChatInner, { ref: ref, ...props, browserTabId: browserTabId, contextScope: contextScope, contextNamespace: contextNamespace, isActiveComposer: isActiveComposer, apiUrl: apiUrl, tabId: tabId, threadId: threadId }) }) }) }) }));
|
|
4339
4352
|
});
|
|
@@ -3,7 +3,7 @@ import { IconPlus, IconHistory, IconX } from "@tabler/icons-react";
|
|
|
3
3
|
import { useState, useRef, useEffect, useCallback } from "react";
|
|
4
4
|
import { DEFAULT_MODEL } from "../agent/default-model.js";
|
|
5
5
|
import { DEFAULT_REASONING_EFFORT, isReasoningEffort, resolveReasoningEffortSelection, } from "../shared/reasoning-effort.js";
|
|
6
|
-
import { AGENT_CHAT_CLEAR_CONTEXT_MESSAGE_TYPE, AGENT_CHAT_REMOVE_CONTEXT_MESSAGE_TYPE, AGENT_CHAT_SET_CONTEXT_MESSAGE_TYPE, appendAgentChatContextToMessage, claimAgentChatOpenRequest, claimAgentChatSubmit, drainBufferedAgentChatOpenRequests, drainBufferedAgentChatSubmits, getAgentChatContextState, isAgentChatSubmitCancelled, normalizeAgentChatContextItem, parseSubmitChatMessage, removeAgentChatContextItem, reportAgentChatSubmitResult, reportAgentChatSubmitTarget, setAgentChatContextItem, } from "./agent-chat.js";
|
|
6
|
+
import { AGENT_CHAT_CLEAR_CONTEXT_MESSAGE_TYPE, AGENT_CHAT_REMOVE_CONTEXT_MESSAGE_TYPE, AGENT_CHAT_SET_CONTEXT_MESSAGE_TYPE, appendAgentChatContextToMessage, claimAgentChatOpenRequest, claimAgentChatSubmit, drainBufferedAgentChatOpenRequests, drainBufferedAgentChatSubmits, filterAgentChatContextItems, getAgentChatContextState, isAgentChatSubmitCancelled, normalizeAgentChatContextItem, parseSubmitChatMessage, removeAgentChatContextItem, reportAgentChatSubmitResult, reportAgentChatSubmitTarget, setAgentChatContextItem, } from "./agent-chat.js";
|
|
7
7
|
import { agentNativePath, appPath } from "./api-path.js";
|
|
8
8
|
import { AssistantChat, } from "./AssistantChat.js";
|
|
9
9
|
import { buildChatModelGroups, } from "./chat-model-groups.js";
|
|
@@ -386,6 +386,9 @@ function runToAgentTeamTabInfo(run) {
|
|
|
386
386
|
}
|
|
387
387
|
export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderOverlay, contentHidden = false, apiUrl = agentNativePath("/_agent-native/agent-chat"), storageKey, restoreActiveThread = true, browserTabId, threadUrlSync = false, scope = null, agentTeamPollMs = DEFAULT_AGENT_TEAM_POLL_MS, ...props }) {
|
|
388
388
|
const translate = useT();
|
|
389
|
+
const contextNamespace = scope
|
|
390
|
+
? scope.contextKey?.trim() || `scope:${scope.type}:${scope.id}`
|
|
391
|
+
: undefined;
|
|
389
392
|
const { enabled: threadUrlSyncEnabled, paramName: threadUrlParamName, routeThreadId, getPath: getThreadPath, navigate: navigateThreadUrl, } = resolveThreadUrlSync(threadUrlSync);
|
|
390
393
|
const threadRouteControlsActiveThread = threadUrlSyncEnabled &&
|
|
391
394
|
threadUrlSync !== true &&
|
|
@@ -578,6 +581,9 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
578
581
|
}, [bumpModelSelectionVersion, modelSelectionKey]);
|
|
579
582
|
const postMessageSubmissionsDisabled = props.composerDisabled === true;
|
|
580
583
|
const setContextInTab = useCallback((threadId, item, options) => {
|
|
584
|
+
if (filterAgentChatContextItems([item], contextNamespace).length === 0) {
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
581
587
|
const ref = chatRefs.current.get(threadId);
|
|
582
588
|
if (ref) {
|
|
583
589
|
ref.setComposerContextItem(item, options);
|
|
@@ -589,7 +595,7 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
589
595
|
? [...existing, item]
|
|
590
596
|
: existing.map((current, currentIndex) => currentIndex === index ? item : current);
|
|
591
597
|
pendingContextItems.current.set(threadId, next);
|
|
592
|
-
}, []);
|
|
598
|
+
}, [contextNamespace]);
|
|
593
599
|
const removeContextInTab = useCallback((threadId, key) => {
|
|
594
600
|
const ref = chatRefs.current.get(threadId);
|
|
595
601
|
if (ref) {
|
|
@@ -772,7 +778,7 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
772
778
|
const type = formatScopeType(nextScope.type);
|
|
773
779
|
const title = nextScope.label?.trim() ||
|
|
774
780
|
type.replace(/^./, (character) => character.toUpperCase());
|
|
775
|
-
const key = nextScope.contextKey || "agent-current-resource-context";
|
|
781
|
+
const key = nextScope.contextKey?.trim() || "agent-current-resource-context";
|
|
776
782
|
const marker = `Resource context: ${nextScope.type}:${nextScope.id}`;
|
|
777
783
|
const existing = getAgentChatContextState().items.find((item) => item.key === key);
|
|
778
784
|
let ownsContextItem = false;
|
|
@@ -780,6 +786,7 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
780
786
|
setAgentChatContextItem({
|
|
781
787
|
key,
|
|
782
788
|
title,
|
|
789
|
+
...(contextNamespace ? { contextNamespace } : {}),
|
|
783
790
|
context: [
|
|
784
791
|
marker,
|
|
785
792
|
`The user is currently viewing this ${type}.`,
|
|
@@ -802,7 +809,13 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
802
809
|
removeAgentChatContextItem(key);
|
|
803
810
|
}
|
|
804
811
|
};
|
|
805
|
-
}, [
|
|
812
|
+
}, [
|
|
813
|
+
contextNamespace,
|
|
814
|
+
scope?.contextKey,
|
|
815
|
+
scope?.id,
|
|
816
|
+
scope?.label,
|
|
817
|
+
scope?.type,
|
|
818
|
+
]);
|
|
806
819
|
// Persist open tab IDs to localStorage (exclude sub-agent tabs — they're session-only)
|
|
807
820
|
useEffect(() => {
|
|
808
821
|
if (openTabsKeyRef.current !== OPEN_TABS_KEY)
|
|
@@ -1797,7 +1810,7 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
1797
1810
|
else {
|
|
1798
1811
|
chatRefs.current.delete(tabId);
|
|
1799
1812
|
}
|
|
1800
|
-
}, threadId: tabId, tabId: tabId, browserTabId: browserTabId, isActiveComposer: tabId === activeThreadId, apiUrl: apiUrl, isNewThread: newThreadIds.current.has(tabId) || isNewThread(tabId), isThreadStateLoading: isLoading, onMessageCountChange: (count) => setMessageCounts((prev) => prev[tabId] === count
|
|
1813
|
+
}, threadId: tabId, tabId: tabId, browserTabId: browserTabId, contextNamespace: contextNamespace, isActiveComposer: tabId === activeThreadId, apiUrl: apiUrl, isNewThread: newThreadIds.current.has(tabId) || isNewThread(tabId), isThreadStateLoading: isLoading, onMessageCountChange: (count) => setMessageCounts((prev) => prev[tabId] === count
|
|
1801
1814
|
? prev
|
|
1802
1815
|
: { ...prev, [tabId]: count }), onSaveThread: handleSaveThread, onGenerateTitle: handleGenerateTitle, onSlashCommand: handleSlashCommand, selectedModel: modelSelection?.model, selectedEngine: modelSelection?.engine, selectedEffort: modelSelection?.effort ?? DEFAULT_REASONING_EFFORT, composerSlot: props.composerSlot, defaultModel: defaultModel, availableModels: availableModels, modelListLoading: modelListLoading, onModelChange: handleModelChange, onEffortChange: handleEffortChange, onForkChat: () => handleForkChat(tabId),
|
|
1803
1816
|
// Sub-agent tabs are read-only: sending a new message from the
|
|
@@ -94,6 +94,8 @@ export interface AgentChatContextItem {
|
|
|
94
94
|
title: string;
|
|
95
95
|
/** Hidden context included with the next submitted prompt. */
|
|
96
96
|
context: string;
|
|
97
|
+
/** Optional host namespace used to keep ambient context local to one surface. */
|
|
98
|
+
contextNamespace?: string;
|
|
97
99
|
}
|
|
98
100
|
export interface AgentChatContextSetOptions extends AgentChatContextItem {
|
|
99
101
|
/**
|
|
@@ -233,6 +235,12 @@ export declare function claimAgentChatOpenRequest(id: unknown): boolean;
|
|
|
233
235
|
/** Test-only: reset the self-submit buffer and claim set. */
|
|
234
236
|
export declare function _resetAgentChatSubmitBufferForTests(): void;
|
|
235
237
|
export declare function normalizeAgentChatContextItem(item: unknown): AgentChatContextItem | null;
|
|
238
|
+
/**
|
|
239
|
+
* Keep unscoped context visible everywhere, but hide ambient context owned by
|
|
240
|
+
* a different host surface. This prevents mounted-but-hidden app panes from
|
|
241
|
+
* leaking their resource chips into the active app's composer.
|
|
242
|
+
*/
|
|
243
|
+
export declare function filterAgentChatContextItems(items: readonly AgentChatContextItem[], contextNamespace?: string | null): AgentChatContextItem[];
|
|
236
244
|
export declare function normalizeAgentChatContextItems(items: unknown): AgentChatContextItem[];
|
|
237
245
|
export declare function publishAgentChatContextItems(items: readonly AgentChatContextItem[], options?: {
|
|
238
246
|
persist?: boolean;
|
|
@@ -207,12 +207,27 @@ export function normalizeAgentChatContextItem(item) {
|
|
|
207
207
|
const context = candidate.context.trim();
|
|
208
208
|
if (!key || !context)
|
|
209
209
|
return null;
|
|
210
|
+
const contextNamespace = typeof candidate.contextNamespace === "string"
|
|
211
|
+
? candidate.contextNamespace.trim()
|
|
212
|
+
: "";
|
|
210
213
|
return {
|
|
211
214
|
key,
|
|
212
215
|
title: candidate.title.trim() || key,
|
|
213
216
|
context,
|
|
217
|
+
...(contextNamespace ? { contextNamespace } : {}),
|
|
214
218
|
};
|
|
215
219
|
}
|
|
220
|
+
/**
|
|
221
|
+
* Keep unscoped context visible everywhere, but hide ambient context owned by
|
|
222
|
+
* a different host surface. This prevents mounted-but-hidden app panes from
|
|
223
|
+
* leaking their resource chips into the active app's composer.
|
|
224
|
+
*/
|
|
225
|
+
export function filterAgentChatContextItems(items, contextNamespace) {
|
|
226
|
+
const namespace = contextNamespace?.trim();
|
|
227
|
+
if (!namespace)
|
|
228
|
+
return [...items];
|
|
229
|
+
return items.filter((item) => !item.contextNamespace || item.contextNamespace.trim() === namespace);
|
|
230
|
+
}
|
|
216
231
|
export function normalizeAgentChatContextItems(items) {
|
|
217
232
|
if (!Array.isArray(items))
|
|
218
233
|
return [];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Custom event used by top-level hosts such as Electron webviews. */
|
|
2
|
+
export declare const APP_CHAT_SIDEBAR_STATE_EVENT = "agent-native:per-app-chat-state";
|
|
3
|
+
/** postMessage sent from a per-app chat host to its embedded app. */
|
|
4
|
+
export declare const APP_CHAT_SIDEBAR_STATE_MESSAGE = "agentNative.perAppChatState";
|
|
5
|
+
/** Request sent by an iframe that mounted after the host announced its state. */
|
|
6
|
+
export declare const APP_CHAT_SIDEBAR_STATE_REQUEST_MESSAGE = "agentNative.perAppChatStateRequest";
|
|
7
|
+
export interface AppChatSidebarState {
|
|
8
|
+
open: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function buildAppChatSidebarStateMessage(open: boolean): {
|
|
11
|
+
type: typeof APP_CHAT_SIDEBAR_STATE_MESSAGE;
|
|
12
|
+
data: AppChatSidebarState;
|
|
13
|
+
};
|
|
14
|
+
export declare function buildAppChatSidebarStateRequest(): {
|
|
15
|
+
type: typeof APP_CHAT_SIDEBAR_STATE_REQUEST_MESSAGE;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* The two host shells are the only AgentSidebar instances that control a
|
|
19
|
+
* separate app surface. Keeping this check here prevents ordinary in-app
|
|
20
|
+
* agent panels from changing the app's navigation chrome.
|
|
21
|
+
*/
|
|
22
|
+
export declare function isPerAppChatStorageKey(storageKey: string | undefined): boolean;
|
|
23
|
+
export declare function usePerAppChatOpen(): boolean;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
/** Custom event used by top-level hosts such as Electron webviews. */
|
|
3
|
+
export const APP_CHAT_SIDEBAR_STATE_EVENT = "agent-native:per-app-chat-state";
|
|
4
|
+
/** postMessage sent from a per-app chat host to its embedded app. */
|
|
5
|
+
export const APP_CHAT_SIDEBAR_STATE_MESSAGE = "agentNative.perAppChatState";
|
|
6
|
+
/** Request sent by an iframe that mounted after the host announced its state. */
|
|
7
|
+
export const APP_CHAT_SIDEBAR_STATE_REQUEST_MESSAGE = "agentNative.perAppChatStateRequest";
|
|
8
|
+
export function buildAppChatSidebarStateMessage(open) {
|
|
9
|
+
return {
|
|
10
|
+
type: APP_CHAT_SIDEBAR_STATE_MESSAGE,
|
|
11
|
+
data: { open },
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export function buildAppChatSidebarStateRequest() {
|
|
15
|
+
return { type: APP_CHAT_SIDEBAR_STATE_REQUEST_MESSAGE };
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The two host shells are the only AgentSidebar instances that control a
|
|
19
|
+
* separate app surface. Keeping this check here prevents ordinary in-app
|
|
20
|
+
* agent panels from changing the app's navigation chrome.
|
|
21
|
+
*/
|
|
22
|
+
export function isPerAppChatStorageKey(storageKey) {
|
|
23
|
+
return (storageKey === "desktop-app-chat" || storageKey === "dispatch-app-chat");
|
|
24
|
+
}
|
|
25
|
+
export function usePerAppChatOpen() {
|
|
26
|
+
const [open, setOpen] = useState(false);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const applyState = (value) => {
|
|
29
|
+
if (typeof value === "boolean")
|
|
30
|
+
setOpen(value);
|
|
31
|
+
};
|
|
32
|
+
const handleCustomEvent = (event) => {
|
|
33
|
+
applyState(event.detail?.open);
|
|
34
|
+
};
|
|
35
|
+
const handleMessage = (event) => {
|
|
36
|
+
if (window.parent === window || event.source !== window.parent)
|
|
37
|
+
return;
|
|
38
|
+
if (event.data?.type !== APP_CHAT_SIDEBAR_STATE_MESSAGE)
|
|
39
|
+
return;
|
|
40
|
+
applyState(event.data.data?.open);
|
|
41
|
+
};
|
|
42
|
+
window.addEventListener(APP_CHAT_SIDEBAR_STATE_EVENT, handleCustomEvent);
|
|
43
|
+
window.addEventListener("message", handleMessage);
|
|
44
|
+
if (window.parent !== window) {
|
|
45
|
+
window.parent.postMessage(buildAppChatSidebarStateRequest(), "*");
|
|
46
|
+
}
|
|
47
|
+
return () => {
|
|
48
|
+
window.removeEventListener(APP_CHAT_SIDEBAR_STATE_EVENT, handleCustomEvent);
|
|
49
|
+
window.removeEventListener("message", handleMessage);
|
|
50
|
+
};
|
|
51
|
+
}, []);
|
|
52
|
+
return open;
|
|
53
|
+
}
|
|
@@ -51,7 +51,7 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
51
51
|
import { Toaster } from "@agent-native/toolkit/ui/sonner";
|
|
52
52
|
import { TooltipProvider } from "@radix-ui/react-tooltip";
|
|
53
53
|
import { QueryClientProvider } from "@tanstack/react-query";
|
|
54
|
-
import { ThemeProvider } from "next-themes";
|
|
54
|
+
import { ThemeProvider, useTheme } from "next-themes";
|
|
55
55
|
import { useEffect, useRef } from "react";
|
|
56
56
|
import { useInRouterContext } from "react-router";
|
|
57
57
|
import { isHumanReadableDocumentTitle, normalizeDocumentTitle, } from "../shared/document-title.js";
|
|
@@ -63,6 +63,7 @@ import { RequireSession } from "./require-session.js";
|
|
|
63
63
|
import { AgentNativeRouteWarmup } from "./route-warmup.js";
|
|
64
64
|
import { RouteTransitionIndicator } from "./RouteTransitionIndicator.js";
|
|
65
65
|
import { RuntimeConfigNotice } from "./RuntimeConfigNotice.js";
|
|
66
|
+
import { EMBEDDED_THEME_CHANGE_EVENT, applyEmbeddedThemeUpdate, parseEmbeddedThemeUpdate, } from "./theme.js";
|
|
66
67
|
const DEFAULT_TOASTER = _jsx(Toaster, { richColors: true, position: "bottom-left" });
|
|
67
68
|
function RoutedAppEnhancements() {
|
|
68
69
|
const isInRouter = useInRouterContext();
|
|
@@ -81,6 +82,34 @@ function readDocumentTitleFallback() {
|
|
|
81
82
|
.find((title) => isHumanReadableDocumentTitle(title));
|
|
82
83
|
return normalizeDocumentTitle(metadataTitle, "Agent Native");
|
|
83
84
|
}
|
|
85
|
+
function EmbeddedThemeSync() {
|
|
86
|
+
const { setTheme } = useTheme();
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
const applyUpdate = (update) => {
|
|
89
|
+
if (!update)
|
|
90
|
+
return;
|
|
91
|
+
applyEmbeddedThemeUpdate(document.documentElement, update);
|
|
92
|
+
setTheme(update.theme);
|
|
93
|
+
};
|
|
94
|
+
const onMessage = (event) => {
|
|
95
|
+
if (window.parent === window || event.source !== window.parent)
|
|
96
|
+
return;
|
|
97
|
+
applyUpdate(parseEmbeddedThemeUpdate(event.data));
|
|
98
|
+
};
|
|
99
|
+
const onThemeChange = (event) => {
|
|
100
|
+
if (!(event instanceof CustomEvent))
|
|
101
|
+
return;
|
|
102
|
+
applyUpdate(parseEmbeddedThemeUpdate(event.detail));
|
|
103
|
+
};
|
|
104
|
+
window.addEventListener("message", onMessage);
|
|
105
|
+
window.addEventListener(EMBEDDED_THEME_CHANGE_EVENT, onThemeChange);
|
|
106
|
+
return () => {
|
|
107
|
+
window.removeEventListener("message", onMessage);
|
|
108
|
+
window.removeEventListener(EMBEDDED_THEME_CHANGE_EVENT, onThemeChange);
|
|
109
|
+
};
|
|
110
|
+
}, [setTheme]);
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
84
113
|
/** Repairs route metadata that would otherwise expose a structured payload in the tab. */
|
|
85
114
|
function DocumentTitleGuard({ fallbackTitle }) {
|
|
86
115
|
const initialTitleRef = useRef(null);
|
|
@@ -115,7 +144,7 @@ function DocumentTitleGuard({ fallbackTitle }) {
|
|
|
115
144
|
}
|
|
116
145
|
function ProvidersInner({ queryClient, defaultTheme = "system", themeAttribute = "class", tooltipDelayDuration, toaster = DEFAULT_TOASTER, disableThemeTransitions = true, i18n, documentTitleFallback, children, }) {
|
|
117
146
|
const localizedChildren = i18n === false ? (children) : (_jsx(AgentNativeI18nProvider, { ...(i18n ?? {}), children: children }));
|
|
118
|
-
return (_jsx(QueryClientProvider, { client: queryClient, children:
|
|
147
|
+
return (_jsx(QueryClientProvider, { client: queryClient, children: _jsxs(ThemeProvider, { attribute: themeAttribute, defaultTheme: defaultTheme, enableSystem: true, disableTransitionOnChange: disableThemeTransitions, children: [_jsx(EmbeddedThemeSync, {}), _jsxs(TooltipProvider, { delayDuration: tooltipDelayDuration, children: [localizedChildren, _jsx(DocumentTitleGuard, { fallbackTitle: documentTitleFallback }), _jsx(RuntimeConfigNotice, {}), _jsx(RoutedAppEnhancements, {}), toaster] })] }) }));
|
|
119
148
|
}
|
|
120
149
|
export function AppProviders({ queryClient, isPublicPath = false, clientOnlyFallback, sessionBypass = false, defaultTheme, themeAttribute, tooltipDelayDuration, toaster, disableThemeTransitions, i18n, documentTitleFallback, children, }) {
|
|
121
150
|
const fallback = clientOnlyFallback ?? _jsx(DefaultSpinner, {});
|
|
@@ -49,6 +49,17 @@ export interface ToggleSidebarMessage {
|
|
|
49
49
|
open?: boolean;
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
|
+
/** The host chat rail asks the embedded app to compact its own navigation. */
|
|
53
|
+
export interface PerAppChatSidebarStateMessage {
|
|
54
|
+
type: "agentNative.perAppChatState";
|
|
55
|
+
data: {
|
|
56
|
+
open: boolean;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/** The embedded app asks a host for the current per-app chat state on mount. */
|
|
60
|
+
export interface PerAppChatSidebarStateRequestMessage {
|
|
61
|
+
type: "agentNative.perAppChatStateRequest";
|
|
62
|
+
}
|
|
52
63
|
export interface EnterStyleEditingMessage {
|
|
53
64
|
type: "agentNative.enterStyleEditing";
|
|
54
65
|
data: {
|
|
@@ -78,7 +89,7 @@ export interface PresentationModeMessage {
|
|
|
78
89
|
export interface DesignCloseMessage {
|
|
79
90
|
type: "design:close";
|
|
80
91
|
}
|
|
81
|
-
export type AppToFrameMessage = AppReadyMessage | SubmitChatMessage | SetChatContextMessage | RemoveChatContextMessage | ClearChatContextMessage | GetUserInfoMessage | SetEnvVarsMessage | DevModeChangeMessage | ToggleSidebarMessage | EnterStyleEditingMessage | EnterTextEditingMessage | ExitSelectionModeMessage | PresentationModeMessage | DesignCloseMessage;
|
|
92
|
+
export type AppToFrameMessage = AppReadyMessage | AuthStateMessage | SubmitChatMessage | SetChatContextMessage | RemoveChatContextMessage | ClearChatContextMessage | GetUserInfoMessage | SetEnvVarsMessage | DevModeChangeMessage | ToggleSidebarMessage | PerAppChatSidebarStateRequestMessage | EnterStyleEditingMessage | EnterTextEditingMessage | ExitSelectionModeMessage | PresentationModeMessage | DesignCloseMessage;
|
|
82
93
|
export interface FrameOriginMessage {
|
|
83
94
|
type: "agentNative.frameOrigin";
|
|
84
95
|
origin: string;
|
|
@@ -98,6 +109,13 @@ export interface UserInfoMessage {
|
|
|
98
109
|
email?: string;
|
|
99
110
|
};
|
|
100
111
|
}
|
|
112
|
+
/** The embedded app's own session state, surfaced to a trusted host frame. */
|
|
113
|
+
export interface AuthStateMessage {
|
|
114
|
+
type: "agentNative.authState";
|
|
115
|
+
data: {
|
|
116
|
+
status: "authenticated" | "unauthenticated";
|
|
117
|
+
};
|
|
118
|
+
}
|
|
101
119
|
export interface CodeCompleteMessage {
|
|
102
120
|
type: "agentNative.codeComplete";
|
|
103
121
|
tabId: string;
|
|
@@ -132,5 +150,5 @@ export interface DesignInitMessage {
|
|
|
132
150
|
};
|
|
133
151
|
};
|
|
134
152
|
}
|
|
135
|
-
export type FrameToAppMessage = FrameOriginMessage | ChatRunningMessage | UserInfoMessage | CodeCompleteMessage | SidebarModeMessage | PresentationModeMessage | DesignInitMessage;
|
|
153
|
+
export type FrameToAppMessage = FrameOriginMessage | ChatRunningMessage | UserInfoMessage | PerAppChatSidebarStateMessage | CodeCompleteMessage | SidebarModeMessage | PresentationModeMessage | DesignInitMessage;
|
|
136
154
|
export type FrameMessage = AppToFrameMessage | FrameToAppMessage;
|
|
@@ -8,6 +8,7 @@ export { notifySessionInvalidated, useSession, type AuthSession, } from "../use-
|
|
|
8
8
|
export { ACTION_KEEPALIVE_BODY_BUDGET_BYTES, callAction, tryCallActionKeepalive, useActionQuery, useActionMutation, type ActionRegistry, type ClientActionCallOptions, type ClientActionMethod, type KeepaliveActionCallRejectionReason, type KeepaliveActionCallResult, } from "../use-action.js";
|
|
9
9
|
export { createAgentNativeQueryClient } from "../create-query-client.js";
|
|
10
10
|
export { AppProviders, type AppProvidersProps } from "../app-providers.js";
|
|
11
|
+
export { APP_CHAT_SIDEBAR_STATE_EVENT, APP_CHAT_SIDEBAR_STATE_MESSAGE, APP_CHAT_SIDEBAR_STATE_REQUEST_MESSAGE, buildAppChatSidebarStateMessage, buildAppChatSidebarStateRequest, isPerAppChatStorageKey, usePerAppChatOpen, type AppChatSidebarState, } from "../app-chat-sidebar.js";
|
|
11
12
|
export { usePinchZoom, type UsePinchZoomOptions } from "../use-pinch-zoom.js";
|
|
12
13
|
export { useAvatarUrl, uploadAvatar, invalidateAvatarCache, } from "../use-avatar.js";
|
|
13
14
|
export { usePollLoop, type UsePollLoopOptions, type UsePollLoopHandle, } from "../use-poll-loop.js";
|
|
@@ -8,6 +8,7 @@ export { notifySessionInvalidated, useSession, } from "../use-session.js";
|
|
|
8
8
|
export { ACTION_KEEPALIVE_BODY_BUDGET_BYTES, callAction, tryCallActionKeepalive, useActionQuery, useActionMutation, } from "../use-action.js";
|
|
9
9
|
export { createAgentNativeQueryClient } from "../create-query-client.js";
|
|
10
10
|
export { AppProviders } from "../app-providers.js";
|
|
11
|
+
export { APP_CHAT_SIDEBAR_STATE_EVENT, APP_CHAT_SIDEBAR_STATE_MESSAGE, APP_CHAT_SIDEBAR_STATE_REQUEST_MESSAGE, buildAppChatSidebarStateMessage, buildAppChatSidebarStateRequest, isPerAppChatStorageKey, usePerAppChatOpen, } from "../app-chat-sidebar.js";
|
|
11
12
|
export { usePinchZoom } from "../use-pinch-zoom.js";
|
|
12
13
|
export { useAvatarUrl, uploadAvatar, invalidateAvatarCache, } from "../use-avatar.js";
|
|
13
14
|
export { usePollLoop, } from "../use-poll-loop.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface AgentShareSectionProps {
|
|
2
|
+
resourceType: string;
|
|
3
|
+
resourceId: string;
|
|
4
|
+
enabled?: boolean;
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
/** Optional shared handoff for resources with a registered agent context. */
|
|
8
|
+
export declare function AgentShareSection({ resourceType, resourceId, enabled, className, }: AgentShareSectionProps): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ActionButton } from "@agent-native/toolkit/design-system";
|
|
3
|
+
import { ShareAgentsSection, ShareCopyRow, } from "@agent-native/toolkit/sharing";
|
|
4
|
+
import { useCallback, useState } from "react";
|
|
5
|
+
import { writeClipboardText } from "../clipboard.js";
|
|
6
|
+
import { useT } from "../i18n.js";
|
|
7
|
+
import { useActionMutation } from "../use-action.js";
|
|
8
|
+
/** Optional shared handoff for resources with a registered agent context. */
|
|
9
|
+
export function AgentShareSection({ resourceType, resourceId, enabled = false, className, }) {
|
|
10
|
+
const t = useT();
|
|
11
|
+
const createAgentLink = useActionMutation("create-agent-resource-link");
|
|
12
|
+
const [open, setOpen] = useState(false);
|
|
13
|
+
const [contextUrl, setContextUrl] = useState("");
|
|
14
|
+
const [linkError, setLinkError] = useState(false);
|
|
15
|
+
const loadContextUrl = useCallback(() => {
|
|
16
|
+
setContextUrl("");
|
|
17
|
+
setLinkError(false);
|
|
18
|
+
createAgentLink.mutate({ resourceType, resourceId }, {
|
|
19
|
+
onSuccess: (result) => {
|
|
20
|
+
if (result.contextUrl)
|
|
21
|
+
setContextUrl(result.contextUrl);
|
|
22
|
+
else
|
|
23
|
+
setLinkError(true);
|
|
24
|
+
},
|
|
25
|
+
onError: () => setLinkError(true),
|
|
26
|
+
});
|
|
27
|
+
}, [createAgentLink, resourceId, resourceType]);
|
|
28
|
+
const handleOpenChange = useCallback((nextOpen) => {
|
|
29
|
+
setOpen(nextOpen);
|
|
30
|
+
if (nextOpen && !contextUrl)
|
|
31
|
+
loadContextUrl();
|
|
32
|
+
}, [contextUrl, loadContextUrl]);
|
|
33
|
+
if (!enabled)
|
|
34
|
+
return null;
|
|
35
|
+
return (_jsx(ShareAgentsSection, { label: t("agentChat.share.shareWithAgents", {
|
|
36
|
+
defaultValue: "Share with agents",
|
|
37
|
+
}), open: open, onOpenChange: handleOpenChange, className: className, children: _jsxs("div", { className: "space-y-2", children: [contextUrl ? (_jsx(ShareCopyRow, { label: t("agentChat.share.agentContext", {
|
|
38
|
+
defaultValue: "Agent context link",
|
|
39
|
+
}), description: t("agentChat.share.agentContextDescription", {
|
|
40
|
+
defaultValue: "Read-only context for an external agent.",
|
|
41
|
+
}), value: contextUrl, copyLabel: t("agentChat.share.copy", { defaultValue: "Copy" }), copiedLabel: t("agentChat.share.copied", {
|
|
42
|
+
defaultValue: "Copied",
|
|
43
|
+
}), onCopy: writeClipboardText })) : null, createAgentLink.isPending ? (_jsx("div", { className: "text-xs text-muted-foreground", children: t("agentChat.share.preparingAgentLink", {
|
|
44
|
+
defaultValue: "Preparing agent link...",
|
|
45
|
+
}) })) : null, linkError ? (_jsxs("div", { className: "flex items-center justify-between gap-2 rounded-md border border-border bg-muted/30 px-3 py-2", children: [_jsx("span", { className: "text-xs text-muted-foreground", children: t("agentChat.share.agentLinkUnavailable", {
|
|
46
|
+
defaultValue: "Agent link unavailable.",
|
|
47
|
+
}) }), _jsx(ActionButton, { type: "button", emphasis: "ghost", size: "compact", onPress: loadContextUrl, disabled: createAgentLink.isPending, children: t("agentChat.share.retryAgentLink", {
|
|
48
|
+
defaultValue: "Retry",
|
|
49
|
+
}) })] })) : null] }) }));
|
|
50
|
+
}
|
|
@@ -7,6 +7,7 @@ import { writeClipboardText } from "../clipboard.js";
|
|
|
7
7
|
import { Popover, PopoverAnchor, PopoverContent, PopoverTrigger, } from "../components/ui/popover.js";
|
|
8
8
|
import { useT } from "../i18n.js";
|
|
9
9
|
import { cn } from "../utils.js";
|
|
10
|
+
import { AgentShareSection } from "./AgentShareSection.js";
|
|
10
11
|
import { useShareButtonController, } from "./useShareButtonController.js";
|
|
11
12
|
// Match shadcn's <Button size="sm" variant="outline"> sizing so the trigger
|
|
12
13
|
// sits flush next to other controls while staying transparent at rest.
|
|
@@ -181,7 +182,7 @@ function SharePanel(props) {
|
|
|
181
182
|
defaultValue: "Remove",
|
|
182
183
|
}), onClick: () => handleRemove(s), disabled: inFlight.has(keyOf(s)), className: BUTTON_GHOST_ICON, children: _jsx(IconTrash, { size: 14 }) })) : null] }, keyOf(s)))), !shares.length && !data?.ownerEmail ? (_jsx("li", { className: "px-1 py-1.5 text-sm text-muted-foreground", children: t("agentChat.share.noAccess", {
|
|
183
184
|
defaultValue: "No one has access yet.",
|
|
184
|
-
}) })) : null] })] }), shareError && !canManage ? (_jsx("div", { role: "alert", className: "mb-4 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: shareError })) : null, props.accessNote ? (_jsx("div", { className: "mb-4 rounded-md border border-border bg-muted/35 p-3 text-xs text-muted-foreground", children: props.accessNote })) : null, showShareLinks && shareUrlPlacement === "bottom" ? shareLinks : null, props.shareFooterContent] }));
|
|
185
|
+
}) })) : null] })] }), shareError && !canManage ? (_jsx("div", { role: "alert", className: "mb-4 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive", children: shareError })) : null, _jsx(AgentShareSection, { enabled: data?.agentReadable === true, resourceType: props.resourceType, resourceId: props.resourceId }), props.accessNote ? (_jsx("div", { className: "mb-4 rounded-md border border-border bg-muted/35 p-3 text-xs text-muted-foreground", children: props.accessNote })) : null, showShareLinks && shareUrlPlacement === "bottom" ? shareLinks : null, props.shareFooterContent] }));
|
|
185
186
|
if (!hasTabs)
|
|
186
187
|
return sharePanel;
|
|
187
188
|
const tabs = [
|
|
@@ -26,7 +26,7 @@ export interface ShareDialogProps {
|
|
|
26
26
|
* Framework share dialog. Drop into any template via
|
|
27
27
|
* `<ShareDialog open onClose resourceType resourceId />`. Passing `shareUrl`
|
|
28
28
|
* lights up a Link tab with a copy field; passing `embedUrl` lights up an
|
|
29
|
-
* Embed tab.
|
|
30
|
-
*
|
|
29
|
+
* Embed tab. People access stays on the primary sharing surface so the same
|
|
30
|
+
* Google-Docs-style flow works whether or not a link or embed is available.
|
|
31
31
|
*/
|
|
32
32
|
export declare function ShareDialog({ open, onClose, resourceType, resourceId, resourceTitle, shareUrl, embedUrl, embedTabContent, linkTabExtras, }: ShareDialogProps): import("react").JSX.Element | null;
|