@agent-native/core 0.125.0 → 0.127.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 +2 -2
- package/corpus/core/CHANGELOG.md +79 -0
- package/corpus/core/docs/content/external-agents-catalog.mdx +14 -11
- package/corpus/core/docs/content/mcp-protocol.mdx +9 -4
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/index.ts +2 -0
- package/corpus/core/src/agent/production-agent.ts +6 -1
- package/corpus/core/src/agent/run-manager.ts +37 -0
- package/corpus/core/src/agent/run-store.ts +18 -0
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +75 -43
- package/corpus/core/src/client/agent-chat.ts +19 -1
- package/corpus/core/src/client/chat/tool-call-display.tsx +25 -0
- package/corpus/core/src/client/resources/mcp-integration-catalog.ts +23 -0
- package/corpus/core/src/client/settings/AgentsSection.tsx +565 -71
- package/corpus/core/src/client/settings/SecretsSection.tsx +71 -36
- package/corpus/core/src/client/use-chat-models.ts +54 -37
- package/corpus/core/src/localization/default-messages.ts +11 -0
- package/corpus/core/src/mcp/ask-app-task-handle.ts +183 -0
- package/corpus/core/src/mcp/builtin-tools.ts +146 -34
- package/corpus/core/src/server/agent-capabilities.ts +8 -1
- package/corpus/core/src/server/agent-chat-plugin.ts +17 -0
- package/corpus/core/src/server/agent-discovery.ts +1 -1
- package/corpus/core/src/server/agent-peer-probe.ts +133 -0
- package/corpus/core/src/server/core-routes-plugin.ts +67 -0
- package/corpus/core/src/server/email-template.ts +13 -0
- package/corpus/core/src/server/email.ts +40 -4
- package/corpus/core/src/shared/mcp-embed-headers.ts +4 -0
- package/corpus/core/src/sharing/actions/share-resource.ts +55 -5
- package/corpus/core/src/sharing/registry.ts +41 -1
- package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +159 -119
- package/corpus/templates/assets/actions/edit-image.ts +31 -18
- package/corpus/templates/assets/actions/refine-image.ts +43 -29
- package/corpus/templates/assets/actions/restyle-image.ts +30 -19
- package/corpus/templates/assets/actions/variant-slots.ts +26 -0
- package/corpus/templates/assets/app/components/generation/GenerationResults.tsx +85 -17
- package/corpus/templates/clips/changelog/2026-07-27-share-notification-emails-now-include-a-clickable-recording-.md +6 -0
- package/corpus/templates/clips/server/db/index.ts +28 -6
- package/corpus/templates/clips/server/lib/share-email-hero.ts +105 -0
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +100 -12
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +17 -0
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +169 -22
- package/corpus/templates/design/app/hooks/use-question-flow.ts +21 -1
- package/corpus/templates/design/changelog/2026-07-28-the-model-you-pick-when-starting-a-new-design-is-now-used-fo.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-07-28-pending-apps-are-hidden-by-default-and-app-ownership-details.md +6 -0
- package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +5 -1
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +5 -0
- package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +31 -8
- package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +15 -0
- package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +78 -8
- package/corpus/templates/slides/app/components/presentation/PresenterView.tsx +179 -0
- package/corpus/templates/slides/app/components/presentation/present-channel.ts +15 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +10 -1
- package/corpus/templates/slides/app/lib/export-google-slides-client.ts +67 -0
- package/corpus/templates/slides/app/lib/export-pptx-client.ts +16 -3
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +11 -0
- package/corpus/templates/slides/app/pages/Presentation.tsx +11 -3
- package/corpus/templates/slides/changelog/2026-07-28-export-to-google-slides-now-creates-the-deck-directly-in-you.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-28-opening-a-presentation-link-directly-no-longer-bounces-back-.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-28-presenter-view-open-a-second-window-while-presenting-to-see-.md +6 -0
- package/corpus/templates/slides/server/routes/api/exports/google-slides.post.ts +90 -0
- package/corpus/toolkit/CHANGELOG.md +6 -0
- package/corpus/toolkit/package.json +1 -1
- package/corpus/toolkit/src/composer/TiptapComposer.tsx +143 -111
- package/corpus/toolkit/src/composer/runtime-adapters.tsx +2 -0
- package/dist/a2a/index.d.ts +2 -0
- package/dist/a2a/index.d.ts.map +1 -1
- package/dist/a2a/index.js +1 -0
- package/dist/a2a/index.js.map +1 -1
- package/dist/agent/production-agent.d.ts +2 -2
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +6 -3
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts +11 -0
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +34 -1
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/agent/run-store.d.ts +8 -0
- package/dist/agent/run-store.d.ts.map +1 -1
- package/dist/agent/run-store.js +16 -0
- package/dist/agent/run-store.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +60 -31
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat.d.ts +6 -0
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +13 -1
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +14 -0
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.d.ts +6 -0
- package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
- package/dist/client/resources/mcp-integration-catalog.js +16 -0
- package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
- package/dist/client/settings/AgentsSection.d.ts.map +1 -1
- package/dist/client/settings/AgentsSection.js +250 -30
- package/dist/client/settings/AgentsSection.js.map +1 -1
- package/dist/client/settings/SecretsSection.d.ts.map +1 -1
- package/dist/client/settings/SecretsSection.js +16 -2
- package/dist/client/settings/SecretsSection.js.map +1 -1
- package/dist/client/use-chat-models.d.ts.map +1 -1
- package/dist/client/use-chat-models.js +46 -27
- package/dist/client/use-chat-models.js.map +1 -1
- package/dist/collab/routes.d.ts +2 -2
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/localization/default-messages.d.ts +9 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +9 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/mcp/ask-app-task-handle.d.ts +25 -0
- package/dist/mcp/ask-app-task-handle.d.ts.map +1 -0
- package/dist/mcp/ask-app-task-handle.js +136 -0
- package/dist/mcp/ask-app-task-handle.js.map +1 -0
- package/dist/mcp/builtin-tools.d.ts +3 -3
- package/dist/mcp/builtin-tools.d.ts.map +1 -1
- package/dist/mcp/builtin-tools.js +115 -38
- package/dist/mcp/builtin-tools.js.map +1 -1
- package/dist/observability/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +4 -4
- package/dist/provider-api/actions/provider-api.d.ts +6 -6
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-capabilities.d.ts +7 -1
- package/dist/server/agent-capabilities.d.ts.map +1 -1
- package/dist/server/agent-capabilities.js +1 -0
- package/dist/server/agent-capabilities.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +7 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +16 -1
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-discovery.d.ts +1 -0
- package/dist/server/agent-discovery.d.ts.map +1 -1
- package/dist/server/agent-discovery.js +1 -1
- package/dist/server/agent-discovery.js.map +1 -1
- package/dist/server/agent-peer-probe.d.ts +37 -0
- package/dist/server/agent-peer-probe.d.ts.map +1 -0
- package/dist/server/agent-peer-probe.js +90 -0
- package/dist/server/agent-peer-probe.js.map +1 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +53 -0
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/email-template.d.ts +6 -0
- package/dist/server/email-template.d.ts.map +1 -1
- package/dist/server/email-template.js +6 -0
- package/dist/server/email-template.js.map +1 -1
- package/dist/server/email.d.ts +7 -0
- package/dist/server/email.d.ts.map +1 -1
- package/dist/server/email.js +31 -6
- package/dist/server/email.js.map +1 -1
- package/dist/shared/mcp-embed-headers.d.ts +1 -0
- package/dist/shared/mcp-embed-headers.d.ts.map +1 -1
- package/dist/shared/mcp-embed-headers.js +4 -0
- package/dist/shared/mcp-embed-headers.js.map +1 -1
- package/dist/sharing/actions/share-resource.d.ts.map +1 -1
- package/dist/sharing/actions/share-resource.js +49 -5
- package/dist/sharing/actions/share-resource.js.map +1 -1
- package/dist/sharing/registry.d.ts +40 -1
- package/dist/sharing/registry.d.ts.map +1 -1
- package/dist/sharing/registry.js.map +1 -1
- package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +159 -119
- package/docs/content/external-agents-catalog.mdx +14 -11
- package/docs/content/mcp-protocol.mdx +9 -4
- package/package.json +2 -2
- package/src/a2a/index.ts +2 -0
- package/src/agent/production-agent.ts +6 -1
- package/src/agent/run-manager.ts +37 -0
- package/src/agent/run-store.ts +18 -0
- package/src/client/MultiTabAssistantChat.tsx +75 -43
- package/src/client/agent-chat.ts +19 -1
- package/src/client/chat/tool-call-display.tsx +25 -0
- package/src/client/resources/mcp-integration-catalog.ts +23 -0
- package/src/client/settings/AgentsSection.tsx +565 -71
- package/src/client/settings/SecretsSection.tsx +71 -36
- package/src/client/use-chat-models.ts +54 -37
- package/src/localization/default-messages.ts +11 -0
- package/src/mcp/ask-app-task-handle.ts +183 -0
- package/src/mcp/builtin-tools.ts +146 -34
- package/src/server/agent-capabilities.ts +8 -1
- package/src/server/agent-chat-plugin.ts +17 -0
- package/src/server/agent-discovery.ts +1 -1
- package/src/server/agent-peer-probe.ts +133 -0
- package/src/server/core-routes-plugin.ts +67 -0
- package/src/server/email-template.ts +13 -0
- package/src/server/email.ts +40 -4
- package/src/shared/mcp-embed-headers.ts +4 -0
- package/src/sharing/actions/share-resource.ts +55 -5
- package/src/sharing/registry.ts +41 -1
- package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +159 -119
|
@@ -6,10 +6,11 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
6
6
|
*/
|
|
7
7
|
import { Picker, TextField } from "@agent-native/toolkit/design-system";
|
|
8
8
|
import { Button as ToolkitButton, ButtonBase as ToolkitButtonBase, } from "@agent-native/toolkit/ui/button";
|
|
9
|
+
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, } from "@agent-native/toolkit/ui/command";
|
|
9
10
|
import { IconCheck, IconChevronRight, IconExternalLink, IconLoader2, IconPlugConnected, IconPlus, IconTrash, IconRefresh, } from "@tabler/icons-react";
|
|
10
11
|
import React, { useEffect, useMemo, useState, useCallback } from "react";
|
|
11
12
|
import { agentNativePath } from "../api-path.js";
|
|
12
|
-
import {
|
|
13
|
+
import { Popover, PopoverContent, PopoverTrigger, } from "../components/ui/popover.js";
|
|
13
14
|
import { Tooltip, TooltipContent, TooltipTrigger, } from "../components/ui/tooltip.js";
|
|
14
15
|
import { useT } from "../i18n.js";
|
|
15
16
|
import { cn } from "../utils.js";
|
|
@@ -81,7 +82,20 @@ export function SecretsSection({ focusKey }) {
|
|
|
81
82
|
}, focusInput: openSecretKey === secret.key }, secret.key))) })), _jsx(AdHocKeysSection, { showForm: customKeyOpen, onShowFormChange: setCustomKeyOpen, showEmptyState: visibleSecrets.length === 0 })] }));
|
|
82
83
|
}
|
|
83
84
|
function KeysHeader({ availableSecrets = [], onSecret, onCustomKey, }) {
|
|
84
|
-
|
|
85
|
+
const [open, setOpen] = useState(false);
|
|
86
|
+
return (_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx("p", { className: "text-[11px] font-medium text-foreground", children: "Keys" }), _jsxs(Popover, { open: open, onOpenChange: setOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(ToolkitButtonBase, { type: "button", variant: "outline", className: "inline-flex items-center gap-1 rounded-md border border-border px-2 py-1 text-[10px] font-medium text-muted-foreground transition-colors hover:bg-accent/40 hover:text-foreground", children: [_jsx(IconPlus, { size: 11 }), "New"] }) }), _jsx(PopoverContent, { align: "end", className: "w-60 p-0", children: _jsxs(Command
|
|
87
|
+
// cmdk's default scorer matches loose subsequences, so "logo"
|
|
88
|
+
// also surfaces every "G-o-o-g-l-e ... " key.
|
|
89
|
+
, {
|
|
90
|
+
// cmdk's default scorer matches loose subsequences, so "logo"
|
|
91
|
+
// also surfaces every "G-o-o-g-l-e ... " key.
|
|
92
|
+
filter: (value, search) => value.toLowerCase().includes(search.toLowerCase()) ? 1 : 0, children: [availableSecrets.length > 0 && (_jsx(CommandInput, { placeholder: "Search keys..." })), _jsxs(CommandList, { children: [_jsx(CommandEmpty, { children: "No keys found." }), availableSecrets.length > 0 && (_jsxs(_Fragment, { children: [_jsx(CommandGroup, { heading: "Choose a key", children: availableSecrets.map((secret) => (_jsxs(CommandItem, { value: `${secret.label} ${secret.key}`, onSelect: () => {
|
|
93
|
+
setOpen(false);
|
|
94
|
+
onSecret?.(secret.key);
|
|
95
|
+
}, className: "flex items-center justify-between gap-3", children: [_jsx("span", { className: "truncate", children: secret.label }), secret.required && (_jsx("span", { className: "shrink-0 text-[9px] font-semibold uppercase tracking-wide text-amber-600 dark:text-amber-400", children: "Required" }))] }, secret.key))) }), _jsx(CommandSeparator, {})] })), _jsx(CommandGroup, { children: _jsxs(CommandItem, { value: "custom key", onSelect: () => {
|
|
96
|
+
setOpen(false);
|
|
97
|
+
onCustomKey();
|
|
98
|
+
}, children: [_jsx(IconPlus, { size: 14 }), "Custom"] }) })] })] }) })] })] }));
|
|
85
99
|
}
|
|
86
100
|
function SecretCard({ secret, onChanged, open, onOpenChange, focusInput, }) {
|
|
87
101
|
const [value, setValue] = useState("");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecretsSection.js","sourceRoot":"","sources":["../../../src/client/settings/SecretsSection.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * <SecretsSection /> — renders the registered secrets from the framework\n * secrets registry. Configured keys stay compact; adding or editing one\n * progressively discloses its controls.\n */\n\nimport { Picker, TextField } from \"@agent-native/toolkit/design-system\";\nimport {\n Button as ToolkitButton,\n ButtonBase as ToolkitButtonBase,\n} from \"@agent-native/toolkit/ui/button\";\nimport {\n IconCheck,\n IconChevronRight,\n IconExternalLink,\n IconLoader2,\n IconPlugConnected,\n IconPlus,\n IconTrash,\n IconRefresh,\n} from \"@tabler/icons-react\";\nimport React, { useEffect, useMemo, useState, useCallback } from \"react\";\n\nimport { agentNativePath } from \"../api-path.js\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"../components/ui/dropdown-menu.js\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"../components/ui/tooltip.js\";\nimport { useT } from \"../i18n.js\";\nimport { cn } from \"../utils.js\";\n\nconst Button = React.forwardRef<\n HTMLButtonElement,\n React.ComponentPropsWithoutRef<typeof ToolkitButton>\n>(({ className, ...props }, ref) => (\n <ToolkitButton\n ref={ref}\n variant=\"ghost\"\n className={cn(\n \"h-auto p-0 hover:bg-transparent hover:text-inherit active:scale-100 [&_svg]:!size-auto\",\n className,\n )}\n {...props}\n />\n));\nButton.displayName = \"SecretsPrimitiveButton\";\n\ninterface SecretStatus {\n key: string;\n label: string;\n description?: string;\n docsUrl?: string;\n scope: \"user\" | \"workspace\";\n kind: \"api-key\" | \"oauth\";\n required: boolean;\n status: \"set\" | \"unset\" | \"invalid\";\n last4?: string;\n updatedAt?: number;\n oauthProvider?: string;\n oauthConnectUrl?: string;\n error?: string;\n}\n\nconst ENDPOINT = agentNativePath(\"/_agent-native/secrets\");\n\nfunction notifySecretsChanged() {\n if (typeof window === \"undefined\") return;\n window.dispatchEvent(\n new CustomEvent(\"agent-engine:configured-changed\", {\n detail: { source: \"secrets\" },\n }),\n );\n}\n\nexport interface SecretsSectionProps {\n /** Optional hash fragment to focus a specific secret (e.g. \"secrets:OPENAI_API_KEY\"). */\n focusKey?: string;\n}\n\nexport function SecretsSection({ focusKey }: SecretsSectionProps) {\n const [secrets, setSecrets] = useState<SecretStatus[] | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [reloadToken, setReloadToken] = useState(0);\n const [openSecretKey, setOpenSecretKey] = useState<string | null>(\n focusKey ?? null,\n );\n const [customKeyOpen, setCustomKeyOpen] = useState(false);\n\n useEffect(() => {\n let cancelled = false;\n fetch(ENDPOINT)\n .then(async (r) => {\n if (!r.ok) {\n throw new Error(`Failed to load secrets (${r.status})`);\n }\n return (await r.json()) as SecretStatus[];\n })\n .then((data) => {\n if (!cancelled) setSecrets(data);\n })\n .catch((err) => {\n if (!cancelled) setError(err?.message ?? \"Failed to load\");\n });\n return () => {\n cancelled = true;\n };\n }, [reloadToken]);\n\n const reload = useCallback(() => setReloadToken((t) => t + 1), []);\n\n useEffect(() => {\n if (focusKey) {\n setCustomKeyOpen(false);\n setOpenSecretKey(focusKey);\n }\n }, [focusKey]);\n\n if (error) {\n return (\n <p className=\"text-[10px] text-red-500\">\n Failed to load secrets: {error}\n </p>\n );\n }\n if (secrets === null) {\n return (\n <div className=\"flex items-center gap-1.5 text-[10px] text-muted-foreground\">\n <IconLoader2 size={10} className=\"animate-spin\" />\n Loading…\n </div>\n );\n }\n if (secrets.length === 0) {\n return (\n <div className=\"space-y-3\">\n <KeysHeader onCustomKey={() => setCustomKeyOpen(true)} />\n <AdHocKeysSection\n showForm={customKeyOpen}\n onShowFormChange={setCustomKeyOpen}\n showEmptyState\n />\n </div>\n );\n }\n\n const visibleSecrets = secrets.filter(\n (secret) => secret.status !== \"unset\" || secret.key === openSecretKey,\n );\n const availableSecrets = secrets.filter(\n (secret) => secret.status === \"unset\" && secret.key !== openSecretKey,\n );\n\n return (\n <div className=\"space-y-3\">\n <KeysHeader\n availableSecrets={availableSecrets}\n onSecret={(key) => {\n setCustomKeyOpen(false);\n setOpenSecretKey(key);\n }}\n onCustomKey={() => {\n setOpenSecretKey(null);\n setCustomKeyOpen(true);\n }}\n />\n {visibleSecrets.length > 0 && (\n <div className=\"overflow-hidden rounded-md border border-border\">\n {visibleSecrets.map((secret) => (\n <SecretCard\n key={secret.key}\n secret={secret}\n onChanged={reload}\n open={openSecretKey === secret.key}\n onOpenChange={(open) => {\n if (open) setCustomKeyOpen(false);\n setOpenSecretKey(open ? secret.key : null);\n }}\n focusInput={openSecretKey === secret.key}\n />\n ))}\n </div>\n )}\n <AdHocKeysSection\n showForm={customKeyOpen}\n onShowFormChange={setCustomKeyOpen}\n showEmptyState={visibleSecrets.length === 0}\n />\n </div>\n );\n}\n\nfunction KeysHeader({\n availableSecrets = [],\n onSecret,\n onCustomKey,\n}: {\n availableSecrets?: SecretStatus[];\n onSecret?: (key: string) => void;\n onCustomKey: () => void;\n}) {\n return (\n <div className=\"flex items-center justify-between gap-3\">\n <p className=\"text-[11px] font-medium text-foreground\">Keys</p>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <ToolkitButtonBase\n type=\"button\"\n variant=\"outline\"\n className=\"inline-flex items-center gap-1 rounded-md border border-border px-2 py-1 text-[10px] font-medium text-muted-foreground transition-colors hover:bg-accent/40 hover:text-foreground\"\n >\n <IconPlus size={11} />\n New\n </ToolkitButtonBase>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-60\">\n {availableSecrets.length > 0 && (\n <>\n <DropdownMenuLabel>Choose a key</DropdownMenuLabel>\n {availableSecrets.map((secret) => (\n <DropdownMenuItem\n key={secret.key}\n onSelect={() => onSecret?.(secret.key)}\n className=\"flex items-center justify-between gap-3\"\n >\n <span className=\"truncate\">{secret.label}</span>\n {secret.required && (\n <span className=\"text-[9px] font-semibold uppercase tracking-wide text-amber-600 dark:text-amber-400\">\n Required\n </span>\n )}\n </DropdownMenuItem>\n ))}\n <DropdownMenuSeparator />\n </>\n )}\n <DropdownMenuItem onSelect={onCustomKey}>\n <IconPlus size={14} />\n Custom\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n );\n}\n\ninterface SecretCardProps {\n secret: SecretStatus;\n onChanged: () => void;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n focusInput?: boolean;\n}\n\nfunction SecretCard({\n secret,\n onChanged,\n open,\n onOpenChange,\n focusInput,\n}: SecretCardProps) {\n const [value, setValue] = useState(\"\");\n const [busy, setBusy] = useState<null | \"save\" | \"delete\" | \"test\">(null);\n const [confirmDelete, setConfirmDelete] = useState(false);\n const [toast, setToast] = useState<{\n kind: \"ok\" | \"err\";\n text: string;\n } | null>(null);\n const inputRef = React.useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (open && focusInput && inputRef.current) {\n inputRef.current.focus();\n }\n }, [focusInput, open]);\n\n const setToastAndClear = (kind: \"ok\" | \"err\", text: string, ms = 2500) => {\n setToast({ kind, text });\n setTimeout(() => setToast(null), ms);\n };\n\n const handleSave = async () => {\n if (!value.trim() || busy) return;\n setBusy(\"save\");\n try {\n const res = await fetch(`${ENDPOINT}/${encodeURIComponent(secret.key)}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ value: value.trim() }),\n });\n if (!res.ok) {\n const err = await res\n .json()\n .then((j: { error?: string }) => j.error)\n .catch(() => null);\n setToastAndClear(\"err\", err ?? `Save failed (${res.status})`);\n return;\n }\n setValue(\"\");\n setConfirmDelete(false);\n setToastAndClear(\"ok\", \"Saved\");\n notifySecretsChanged();\n onChanged();\n } finally {\n setBusy(null);\n }\n };\n\n const handleDelete = async () => {\n if (busy) return;\n setBusy(\"delete\");\n try {\n const res = await fetch(`${ENDPOINT}/${encodeURIComponent(secret.key)}`, {\n method: \"DELETE\",\n headers: { \"Content-Type\": \"application/json\" },\n });\n if (!res.ok) {\n const err = await res\n .json()\n .then((j: { error?: string }) => j.error)\n .catch(() => null);\n setToastAndClear(\"err\", err ?? `Delete failed (${res.status})`);\n return;\n }\n setToastAndClear(\"ok\", \"Removed\");\n setConfirmDelete(false);\n notifySecretsChanged();\n onChanged();\n } finally {\n setBusy(null);\n }\n };\n\n const handleTest = async () => {\n if (busy) return;\n setBusy(\"test\");\n try {\n const res = await fetch(\n `${ENDPOINT}/${encodeURIComponent(secret.key)}/test`,\n {\n method: \"POST\",\n },\n );\n const body = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n error?: string;\n };\n if (res.ok && body.ok) {\n setToastAndClear(\"ok\", \"Working\");\n } else {\n setToastAndClear(\n \"err\",\n body.error ?? (body.ok === false ? \"Invalid\" : `Test failed`),\n );\n }\n } finally {\n setBusy(null);\n }\n };\n\n const pill = useMemo(() => {\n if (secret.status === \"set\") {\n return (\n <span className=\"flex items-center gap-1 text-[10px] text-green-500\">\n <IconCheck size={10} />\n Set\n </span>\n );\n }\n if (secret.required) {\n return (\n <span className=\"rounded-full bg-red-500/15 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-red-500\">\n Required\n </span>\n );\n }\n return (\n <span className=\"rounded-full bg-accent/60 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-muted-foreground\">\n Optional\n </span>\n );\n }, [secret.status, secret.required]);\n\n const isOAuth = secret.kind === \"oauth\";\n\n return (\n <div className=\"border-b border-border last:border-b-0\">\n <Button\n type=\"button\"\n intent=\"neutral\"\n emphasis=\"ghost\"\n aria-expanded={open}\n onClick={() => onOpenChange(!open)}\n className=\"flex w-full items-center gap-2 px-2.5 py-2 text-start transition-colors hover:bg-accent/30\"\n >\n <IconChevronRight\n size={13}\n className={`shrink-0 text-muted-foreground transition-transform ${open ? \"rotate-90\" : \"\"}`}\n />\n <span className=\"min-w-0 flex-1 truncate text-[11px] font-medium text-foreground\">\n {secret.label}\n </span>\n {secret.status === \"set\" && secret.last4 && (\n <code className=\"text-[10px] text-muted-foreground\">\n ••••{secret.last4}\n </code>\n )}\n <span className=\"shrink-0\">{pill}</span>\n </Button>\n\n {open && (\n <div className=\"border-t border-border/60 bg-accent/20 px-3 pb-3 pt-2.5\">\n {secret.description && (\n <p className=\"mb-2 text-[10px] leading-relaxed text-muted-foreground\">\n {secret.description}\n </p>\n )}\n {isOAuth ? (\n <div className=\"mt-2 flex items-center gap-1.5\">\n {secret.oauthConnectUrl && (\n <a\n href={secret.oauthConnectUrl}\n className=\"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium no-underline\"\n style={{ backgroundColor: \"#00B5FF\", color: \"white\" }}\n >\n <IconPlugConnected size={10} />\n {secret.status === \"set\" ? \"Reconnect\" : \"Connect\"}\n </a>\n )}\n {secret.docsUrl && (\n <a\n href={secret.docsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] no-underline text-muted-foreground hover:text-foreground\"\n >\n Docs\n <IconExternalLink size={10} />\n </a>\n )}\n </div>\n ) : (\n <div className=\"mt-2 space-y-1.5\">\n {secret.status === \"set\" && (\n <div className=\"flex items-center gap-2 text-[10px] text-muted-foreground\">\n <span>Stored value ending in</span>\n <code className=\"rounded bg-background px-1 py-0.5 text-foreground\">\n {secret.last4}\n </code>\n </div>\n )}\n <div className=\"flex gap-1.5\">\n <TextField\n inputRef={inputRef}\n type=\"password\"\n aria-label={secret.label}\n value={value}\n onChange={setValue}\n onKeyDown={(event) => {\n if (event.key === \"Enter\") handleSave();\n }}\n placeholder={\n secret.status === \"set\"\n ? \"Enter new value to rotate\"\n : \"Paste key\"\n }\n className=\"flex-1 text-[11px]\"\n />\n <Button\n type=\"button\"\n intent=\"primary\"\n emphasis=\"solid\"\n onClick={handleSave}\n disabled={!value.trim() || busy !== null}\n className=\"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium disabled:opacity-40\"\n style={{ backgroundColor: \"#00B5FF\", color: \"white\" }}\n >\n {busy === \"save\" ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : secret.status === \"set\" ? (\n <>\n <IconRefresh size={10} />\n Rotate\n </>\n ) : (\n \"Save\"\n )}\n </Button>\n </div>\n <div className=\"flex items-center gap-1.5\">\n {secret.status === \"set\" && (\n <>\n <Button\n type=\"button\"\n intent=\"neutral\"\n emphasis=\"outline\"\n onClick={handleTest}\n disabled={busy !== null}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] text-muted-foreground hover:text-foreground disabled:opacity-40\"\n >\n {busy === \"test\" ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : (\n \"Test\"\n )}\n </Button>\n <Button\n type=\"button\"\n intent=\"danger\"\n emphasis=\"outline\"\n onClick={() => setConfirmDelete(true)}\n disabled={busy !== null}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] text-muted-foreground hover:text-red-500 disabled:opacity-40\"\n >\n <IconTrash size={10} />\n Remove\n </Button>\n </>\n )}\n {secret.docsUrl && (\n <a\n href={secret.docsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] no-underline text-muted-foreground hover:text-foreground ms-auto\"\n >\n Get key\n <IconExternalLink size={10} />\n </a>\n )}\n </div>\n {confirmDelete && (\n <div className=\"flex items-center gap-1.5 rounded border border-red-500/30 bg-red-500/10 px-2 py-1.5 text-[10px] text-red-500\">\n <span className=\"min-w-0 flex-1\">\n Remove this saved value?\n </span>\n <Button\n type=\"button\"\n intent=\"danger\"\n emphasis=\"solid\"\n onClick={handleDelete}\n disabled={busy !== null}\n className=\"inline-flex items-center gap-1 rounded border border-red-500/40 px-1.5 py-0.5 font-medium disabled:opacity-40\"\n >\n {busy === \"delete\" ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : (\n \"Confirm\"\n )}\n </Button>\n <Button\n type=\"button\"\n intent=\"neutral\"\n emphasis=\"outline\"\n onClick={() => setConfirmDelete(false)}\n disabled={busy !== null}\n className=\"rounded border border-border px-1.5 py-0.5 text-muted-foreground hover:text-foreground disabled:opacity-40\"\n >\n Cancel\n </Button>\n </div>\n )}\n </div>\n )}\n\n {toast && (\n <p\n className={`mt-1.5 text-[10px] ${\n toast.kind === \"ok\" ? \"text-green-500\" : \"text-red-500\"\n }`}\n >\n {toast.text}\n </p>\n )}\n </div>\n )}\n </div>\n );\n}\n\n// ─── Ad-hoc Keys Section ──────────────────────────────────────────────────\n\ninterface AdHocKey {\n name: string;\n scope: \"user\" | \"workspace\";\n scopeId: string;\n description: string | null;\n last4: string;\n createdAt: number;\n updatedAt: number;\n}\n\nconst ADHOC_ENDPOINT = agentNativePath(\"/_agent-native/secrets/adhoc\");\n\nfunction AdHocKeysSection({\n showForm,\n onShowFormChange,\n showEmptyState,\n}: {\n showForm: boolean;\n onShowFormChange: (show: boolean) => void;\n showEmptyState: boolean;\n}) {\n const t = useT();\n const [keys, setKeys] = useState<AdHocKey[]>([]);\n const [loading, setLoading] = useState(true);\n const [reloadToken, setReloadToken] = useState(0);\n const [formName, setFormName] = useState(\"\");\n const [formValue, setFormValue] = useState(\"\");\n const [formDescription, setFormDescription] = useState(\"\");\n const [formScope, setFormScope] = useState<\"user\" | \"workspace\">(\"user\");\n const [formBusy, setFormBusy] = useState(false);\n const [formError, setFormError] = useState<string | null>(null);\n const [confirmDeleteName, setConfirmDeleteName] = useState<string | null>(\n null,\n );\n const [deletingName, setDeletingName] = useState<string | null>(null);\n const [toast, setToast] = useState<{\n kind: \"ok\" | \"err\";\n text: string;\n } | null>(null);\n\n const showToast = useCallback(\n (kind: \"ok\" | \"err\", text: string, ms = 2500) => {\n setToast({ kind, text });\n setTimeout(() => setToast(null), ms);\n },\n [],\n );\n\n const reload = useCallback(() => setReloadToken((t) => t + 1), []);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n fetch(ADHOC_ENDPOINT)\n .then(async (r) => {\n if (!r.ok) throw new Error(`Failed to load (${r.status})`);\n return (await r.json()) as AdHocKey[];\n })\n .then((data) => {\n if (!cancelled) {\n setKeys(data);\n setLoading(false);\n }\n })\n .catch(() => {\n if (!cancelled) {\n setKeys([]);\n setLoading(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [reloadToken]);\n\n const resetForm = useCallback(() => {\n onShowFormChange(false);\n setFormName(\"\");\n setFormValue(\"\");\n setFormDescription(\"\");\n setFormScope(\"user\");\n setFormError(null);\n }, [onShowFormChange]);\n\n const handleAdd = useCallback(async () => {\n const name = formName.trim();\n const value = formValue.trim();\n if (!name || !value || formBusy) return;\n setFormBusy(true);\n setFormError(null);\n try {\n const res = await fetch(ADHOC_ENDPOINT, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n name,\n value,\n description: formDescription.trim() || undefined,\n scope: formScope,\n }),\n });\n if (!res.ok) {\n const body = await res\n .json()\n .then((j: { error?: string }) => j.error)\n .catch(() => null);\n setFormError(body ?? `Save failed (${res.status})`);\n return;\n }\n resetForm();\n showToast(\"ok\", \"Key saved\");\n notifySecretsChanged();\n reload();\n } catch (err: any) {\n setFormError(err?.message ?? \"Failed to save\");\n } finally {\n setFormBusy(false);\n }\n }, [\n formName,\n formValue,\n formDescription,\n formScope,\n formBusy,\n resetForm,\n showToast,\n reload,\n ]);\n\n const handleDelete = useCallback(\n async (name: string) => {\n setDeletingName(name);\n try {\n const res = await fetch(\n `${ADHOC_ENDPOINT}/${encodeURIComponent(name)}`,\n {\n method: \"DELETE\",\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n if (!res.ok) {\n showToast(\"err\", \"Failed to delete key\");\n return;\n }\n showToast(\"ok\", \"Key deleted\");\n setConfirmDeleteName(null);\n notifySecretsChanged();\n reload();\n } finally {\n setDeletingName(null);\n }\n },\n [showToast, reload],\n );\n\n return (\n <div className=\"space-y-2\">\n {showForm && (\n <div className=\"rounded-md border border-border px-2.5 py-2 bg-accent/30 space-y-1.5\">\n <TextField\n value={formName}\n onChange={(value) =>\n setFormName(value.toUpperCase().replace(/[^A-Z0-9_-]/g, \"\"))\n }\n className=\"w-full text-[11px]\"\n aria-label=\"Key name\"\n placeholder=\"KEY_NAME\"\n />\n <TextField\n type=\"password\"\n aria-label=\"Secret value\"\n value={formValue}\n onChange={setFormValue}\n className=\"w-full text-[11px]\"\n placeholder=\"Secret value\"\n />\n <TextField\n value={formDescription}\n aria-label=\"Description\"\n onChange={setFormDescription}\n className=\"w-full text-[11px]\"\n placeholder=\"Description (optional)\"\n />\n <Picker\n mode=\"select\"\n options={[\n { value: \"user\", label: t(\"secrets.scopePersonal\") },\n { value: \"workspace\", label: t(\"secrets.scopeWorkspace\") },\n ]}\n value={formScope}\n onChange={(value) => {\n if (value === \"user\" || value === \"workspace\") {\n setFormScope(value);\n }\n }}\n aria-label={t(\"secrets.scopeLabel\")}\n description={t(\n formScope === \"user\"\n ? \"secrets.scopePersonalDescription\"\n : \"secrets.scopeWorkspaceDescription\",\n )}\n className=\"text-[11px]\"\n />\n <div className=\"flex items-center justify-end gap-1.5\">\n <Button\n type=\"button\"\n intent=\"neutral\"\n emphasis=\"outline\"\n onClick={resetForm}\n className=\"rounded border border-border px-2 py-1 text-[10px] font-medium text-muted-foreground hover:text-foreground\"\n >\n Cancel\n </Button>\n <Button\n type=\"button\"\n intent=\"primary\"\n emphasis=\"solid\"\n onClick={handleAdd}\n disabled={!formName.trim() || !formValue.trim() || formBusy}\n className=\"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium disabled:opacity-40\"\n style={{ backgroundColor: \"#00B5FF\", color: \"white\" }}\n >\n {formBusy ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : (\n \"Save\"\n )}\n </Button>\n </div>\n {formError && <p className=\"text-[10px] text-red-500\">{formError}</p>}\n </div>\n )}\n\n {loading ? (\n <div className=\"flex items-center gap-1.5 text-[10px] text-muted-foreground\">\n <IconLoader2 size={10} className=\"animate-spin\" />\n Loading...\n </div>\n ) : keys.length === 0 && !showForm && showEmptyState ? (\n <p className=\"text-[10px] text-muted-foreground\">No keys added yet.</p>\n ) : keys.length > 0 ? (\n <div className=\"overflow-hidden rounded-md border border-border\">\n {keys.map((key) => (\n <div\n key={`${key.scope}-${key.name}`}\n className=\"border-b border-border px-2.5 py-2 last:border-b-0\"\n >\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-[11px] font-medium text-foreground font-mono truncate\">\n {key.name}\n </span>\n <span\n className={`rounded-full px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide ${\n key.scope === \"workspace\"\n ? \"bg-blue-500/15 text-blue-500\"\n : \"bg-accent/60 text-muted-foreground\"\n }`}\n >\n {key.scope === \"workspace\" ? \"workspace\" : \"personal\"}\n </span>\n </div>\n {key.description && (\n <p className=\"text-[10px] text-muted-foreground mt-0.5\">\n {key.description}\n </p>\n )}\n <div className=\"flex items-center gap-2 text-[10px] text-muted-foreground mt-0.5\">\n <span>\n Ending in{\" \"}\n <code className=\"rounded bg-background px-1 py-0.5 text-foreground\">\n {key.last4}\n </code>\n </span>\n </div>\n </div>\n <div className=\"shrink-0\">\n {confirmDeleteName === key.name ? (\n <div className=\"flex items-center gap-1\">\n <Button\n type=\"button\"\n intent=\"danger\"\n emphasis=\"solid\"\n onClick={() => handleDelete(key.name)}\n disabled={deletingName === key.name}\n className=\"rounded px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide bg-red-500/15 text-red-500 hover:bg-red-500/25 disabled:opacity-40\"\n >\n {deletingName === key.name ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : (\n \"Confirm\"\n )}\n </Button>\n <Button\n type=\"button\"\n intent=\"neutral\"\n emphasis=\"solid\"\n onClick={() => setConfirmDeleteName(null)}\n className=\"rounded px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide bg-accent/60 text-muted-foreground hover:text-foreground\"\n >\n Cancel\n </Button>\n </div>\n ) : (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n intent=\"danger\"\n emphasis=\"ghost\"\n onClick={() => setConfirmDeleteName(key.name)}\n className=\"text-muted-foreground hover:text-red-500\"\n >\n <IconTrash size={12} />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Delete</TooltipContent>\n </Tooltip>\n )}\n </div>\n </div>\n </div>\n ))}\n </div>\n ) : null}\n\n {toast && (\n <p\n className={`text-[10px] ${toast.kind === \"ok\" ? \"text-green-500\" : \"text-red-500\"}`}\n >\n {toast.text}\n </p>\n )}\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SecretsSection.js","sourceRoot":"","sources":["../../../src/client/settings/SecretsSection.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * <SecretsSection /> — renders the registered secrets from the framework\n * secrets registry. Configured keys stay compact; adding or editing one\n * progressively discloses its controls.\n */\n\nimport { Picker, TextField } from \"@agent-native/toolkit/design-system\";\nimport {\n Button as ToolkitButton,\n ButtonBase as ToolkitButtonBase,\n} from \"@agent-native/toolkit/ui/button\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n} from \"@agent-native/toolkit/ui/command\";\nimport {\n IconCheck,\n IconChevronRight,\n IconExternalLink,\n IconLoader2,\n IconPlugConnected,\n IconPlus,\n IconTrash,\n IconRefresh,\n} from \"@tabler/icons-react\";\nimport React, { useEffect, useMemo, useState, useCallback } from \"react\";\n\nimport { agentNativePath } from \"../api-path.js\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../components/ui/popover.js\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"../components/ui/tooltip.js\";\nimport { useT } from \"../i18n.js\";\nimport { cn } from \"../utils.js\";\n\nconst Button = React.forwardRef<\n HTMLButtonElement,\n React.ComponentPropsWithoutRef<typeof ToolkitButton>\n>(({ className, ...props }, ref) => (\n <ToolkitButton\n ref={ref}\n variant=\"ghost\"\n className={cn(\n \"h-auto p-0 hover:bg-transparent hover:text-inherit active:scale-100 [&_svg]:!size-auto\",\n className,\n )}\n {...props}\n />\n));\nButton.displayName = \"SecretsPrimitiveButton\";\n\ninterface SecretStatus {\n key: string;\n label: string;\n description?: string;\n docsUrl?: string;\n scope: \"user\" | \"workspace\";\n kind: \"api-key\" | \"oauth\";\n required: boolean;\n status: \"set\" | \"unset\" | \"invalid\";\n last4?: string;\n updatedAt?: number;\n oauthProvider?: string;\n oauthConnectUrl?: string;\n error?: string;\n}\n\nconst ENDPOINT = agentNativePath(\"/_agent-native/secrets\");\n\nfunction notifySecretsChanged() {\n if (typeof window === \"undefined\") return;\n window.dispatchEvent(\n new CustomEvent(\"agent-engine:configured-changed\", {\n detail: { source: \"secrets\" },\n }),\n );\n}\n\nexport interface SecretsSectionProps {\n /** Optional hash fragment to focus a specific secret (e.g. \"secrets:OPENAI_API_KEY\"). */\n focusKey?: string;\n}\n\nexport function SecretsSection({ focusKey }: SecretsSectionProps) {\n const [secrets, setSecrets] = useState<SecretStatus[] | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [reloadToken, setReloadToken] = useState(0);\n const [openSecretKey, setOpenSecretKey] = useState<string | null>(\n focusKey ?? null,\n );\n const [customKeyOpen, setCustomKeyOpen] = useState(false);\n\n useEffect(() => {\n let cancelled = false;\n fetch(ENDPOINT)\n .then(async (r) => {\n if (!r.ok) {\n throw new Error(`Failed to load secrets (${r.status})`);\n }\n return (await r.json()) as SecretStatus[];\n })\n .then((data) => {\n if (!cancelled) setSecrets(data);\n })\n .catch((err) => {\n if (!cancelled) setError(err?.message ?? \"Failed to load\");\n });\n return () => {\n cancelled = true;\n };\n }, [reloadToken]);\n\n const reload = useCallback(() => setReloadToken((t) => t + 1), []);\n\n useEffect(() => {\n if (focusKey) {\n setCustomKeyOpen(false);\n setOpenSecretKey(focusKey);\n }\n }, [focusKey]);\n\n if (error) {\n return (\n <p className=\"text-[10px] text-red-500\">\n Failed to load secrets: {error}\n </p>\n );\n }\n if (secrets === null) {\n return (\n <div className=\"flex items-center gap-1.5 text-[10px] text-muted-foreground\">\n <IconLoader2 size={10} className=\"animate-spin\" />\n Loading…\n </div>\n );\n }\n if (secrets.length === 0) {\n return (\n <div className=\"space-y-3\">\n <KeysHeader onCustomKey={() => setCustomKeyOpen(true)} />\n <AdHocKeysSection\n showForm={customKeyOpen}\n onShowFormChange={setCustomKeyOpen}\n showEmptyState\n />\n </div>\n );\n }\n\n const visibleSecrets = secrets.filter(\n (secret) => secret.status !== \"unset\" || secret.key === openSecretKey,\n );\n const availableSecrets = secrets.filter(\n (secret) => secret.status === \"unset\" && secret.key !== openSecretKey,\n );\n\n return (\n <div className=\"space-y-3\">\n <KeysHeader\n availableSecrets={availableSecrets}\n onSecret={(key) => {\n setCustomKeyOpen(false);\n setOpenSecretKey(key);\n }}\n onCustomKey={() => {\n setOpenSecretKey(null);\n setCustomKeyOpen(true);\n }}\n />\n {visibleSecrets.length > 0 && (\n <div className=\"overflow-hidden rounded-md border border-border\">\n {visibleSecrets.map((secret) => (\n <SecretCard\n key={secret.key}\n secret={secret}\n onChanged={reload}\n open={openSecretKey === secret.key}\n onOpenChange={(open) => {\n if (open) setCustomKeyOpen(false);\n setOpenSecretKey(open ? secret.key : null);\n }}\n focusInput={openSecretKey === secret.key}\n />\n ))}\n </div>\n )}\n <AdHocKeysSection\n showForm={customKeyOpen}\n onShowFormChange={setCustomKeyOpen}\n showEmptyState={visibleSecrets.length === 0}\n />\n </div>\n );\n}\n\nfunction KeysHeader({\n availableSecrets = [],\n onSecret,\n onCustomKey,\n}: {\n availableSecrets?: SecretStatus[];\n onSecret?: (key: string) => void;\n onCustomKey: () => void;\n}) {\n const [open, setOpen] = useState(false);\n\n return (\n <div className=\"flex items-center justify-between gap-3\">\n <p className=\"text-[11px] font-medium text-foreground\">Keys</p>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <ToolkitButtonBase\n type=\"button\"\n variant=\"outline\"\n className=\"inline-flex items-center gap-1 rounded-md border border-border px-2 py-1 text-[10px] font-medium text-muted-foreground transition-colors hover:bg-accent/40 hover:text-foreground\"\n >\n <IconPlus size={11} />\n New\n </ToolkitButtonBase>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className=\"w-60 p-0\">\n <Command\n // cmdk's default scorer matches loose subsequences, so \"logo\"\n // also surfaces every \"G-o-o-g-l-e ... \" key.\n filter={(value, search) =>\n value.toLowerCase().includes(search.toLowerCase()) ? 1 : 0\n }\n >\n {availableSecrets.length > 0 && (\n <CommandInput placeholder=\"Search keys...\" />\n )}\n <CommandList>\n <CommandEmpty>No keys found.</CommandEmpty>\n {availableSecrets.length > 0 && (\n <>\n <CommandGroup heading=\"Choose a key\">\n {availableSecrets.map((secret) => (\n <CommandItem\n key={secret.key}\n value={`${secret.label} ${secret.key}`}\n onSelect={() => {\n setOpen(false);\n onSecret?.(secret.key);\n }}\n className=\"flex items-center justify-between gap-3\"\n >\n <span className=\"truncate\">{secret.label}</span>\n {secret.required && (\n <span className=\"shrink-0 text-[9px] font-semibold uppercase tracking-wide text-amber-600 dark:text-amber-400\">\n Required\n </span>\n )}\n </CommandItem>\n ))}\n </CommandGroup>\n <CommandSeparator />\n </>\n )}\n <CommandGroup>\n <CommandItem\n value=\"custom key\"\n onSelect={() => {\n setOpen(false);\n onCustomKey();\n }}\n >\n <IconPlus size={14} />\n Custom\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n </div>\n );\n}\n\ninterface SecretCardProps {\n secret: SecretStatus;\n onChanged: () => void;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n focusInput?: boolean;\n}\n\nfunction SecretCard({\n secret,\n onChanged,\n open,\n onOpenChange,\n focusInput,\n}: SecretCardProps) {\n const [value, setValue] = useState(\"\");\n const [busy, setBusy] = useState<null | \"save\" | \"delete\" | \"test\">(null);\n const [confirmDelete, setConfirmDelete] = useState(false);\n const [toast, setToast] = useState<{\n kind: \"ok\" | \"err\";\n text: string;\n } | null>(null);\n const inputRef = React.useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (open && focusInput && inputRef.current) {\n inputRef.current.focus();\n }\n }, [focusInput, open]);\n\n const setToastAndClear = (kind: \"ok\" | \"err\", text: string, ms = 2500) => {\n setToast({ kind, text });\n setTimeout(() => setToast(null), ms);\n };\n\n const handleSave = async () => {\n if (!value.trim() || busy) return;\n setBusy(\"save\");\n try {\n const res = await fetch(`${ENDPOINT}/${encodeURIComponent(secret.key)}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ value: value.trim() }),\n });\n if (!res.ok) {\n const err = await res\n .json()\n .then((j: { error?: string }) => j.error)\n .catch(() => null);\n setToastAndClear(\"err\", err ?? `Save failed (${res.status})`);\n return;\n }\n setValue(\"\");\n setConfirmDelete(false);\n setToastAndClear(\"ok\", \"Saved\");\n notifySecretsChanged();\n onChanged();\n } finally {\n setBusy(null);\n }\n };\n\n const handleDelete = async () => {\n if (busy) return;\n setBusy(\"delete\");\n try {\n const res = await fetch(`${ENDPOINT}/${encodeURIComponent(secret.key)}`, {\n method: \"DELETE\",\n headers: { \"Content-Type\": \"application/json\" },\n });\n if (!res.ok) {\n const err = await res\n .json()\n .then((j: { error?: string }) => j.error)\n .catch(() => null);\n setToastAndClear(\"err\", err ?? `Delete failed (${res.status})`);\n return;\n }\n setToastAndClear(\"ok\", \"Removed\");\n setConfirmDelete(false);\n notifySecretsChanged();\n onChanged();\n } finally {\n setBusy(null);\n }\n };\n\n const handleTest = async () => {\n if (busy) return;\n setBusy(\"test\");\n try {\n const res = await fetch(\n `${ENDPOINT}/${encodeURIComponent(secret.key)}/test`,\n {\n method: \"POST\",\n },\n );\n const body = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n error?: string;\n };\n if (res.ok && body.ok) {\n setToastAndClear(\"ok\", \"Working\");\n } else {\n setToastAndClear(\n \"err\",\n body.error ?? (body.ok === false ? \"Invalid\" : `Test failed`),\n );\n }\n } finally {\n setBusy(null);\n }\n };\n\n const pill = useMemo(() => {\n if (secret.status === \"set\") {\n return (\n <span className=\"flex items-center gap-1 text-[10px] text-green-500\">\n <IconCheck size={10} />\n Set\n </span>\n );\n }\n if (secret.required) {\n return (\n <span className=\"rounded-full bg-red-500/15 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-red-500\">\n Required\n </span>\n );\n }\n return (\n <span className=\"rounded-full bg-accent/60 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-muted-foreground\">\n Optional\n </span>\n );\n }, [secret.status, secret.required]);\n\n const isOAuth = secret.kind === \"oauth\";\n\n return (\n <div className=\"border-b border-border last:border-b-0\">\n <Button\n type=\"button\"\n intent=\"neutral\"\n emphasis=\"ghost\"\n aria-expanded={open}\n onClick={() => onOpenChange(!open)}\n className=\"flex w-full items-center gap-2 px-2.5 py-2 text-start transition-colors hover:bg-accent/30\"\n >\n <IconChevronRight\n size={13}\n className={`shrink-0 text-muted-foreground transition-transform ${open ? \"rotate-90\" : \"\"}`}\n />\n <span className=\"min-w-0 flex-1 truncate text-[11px] font-medium text-foreground\">\n {secret.label}\n </span>\n {secret.status === \"set\" && secret.last4 && (\n <code className=\"text-[10px] text-muted-foreground\">\n ••••{secret.last4}\n </code>\n )}\n <span className=\"shrink-0\">{pill}</span>\n </Button>\n\n {open && (\n <div className=\"border-t border-border/60 bg-accent/20 px-3 pb-3 pt-2.5\">\n {secret.description && (\n <p className=\"mb-2 text-[10px] leading-relaxed text-muted-foreground\">\n {secret.description}\n </p>\n )}\n {isOAuth ? (\n <div className=\"mt-2 flex items-center gap-1.5\">\n {secret.oauthConnectUrl && (\n <a\n href={secret.oauthConnectUrl}\n className=\"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium no-underline\"\n style={{ backgroundColor: \"#00B5FF\", color: \"white\" }}\n >\n <IconPlugConnected size={10} />\n {secret.status === \"set\" ? \"Reconnect\" : \"Connect\"}\n </a>\n )}\n {secret.docsUrl && (\n <a\n href={secret.docsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] no-underline text-muted-foreground hover:text-foreground\"\n >\n Docs\n <IconExternalLink size={10} />\n </a>\n )}\n </div>\n ) : (\n <div className=\"mt-2 space-y-1.5\">\n {secret.status === \"set\" && (\n <div className=\"flex items-center gap-2 text-[10px] text-muted-foreground\">\n <span>Stored value ending in</span>\n <code className=\"rounded bg-background px-1 py-0.5 text-foreground\">\n {secret.last4}\n </code>\n </div>\n )}\n <div className=\"flex gap-1.5\">\n <TextField\n inputRef={inputRef}\n type=\"password\"\n aria-label={secret.label}\n value={value}\n onChange={setValue}\n onKeyDown={(event) => {\n if (event.key === \"Enter\") handleSave();\n }}\n placeholder={\n secret.status === \"set\"\n ? \"Enter new value to rotate\"\n : \"Paste key\"\n }\n className=\"flex-1 text-[11px]\"\n />\n <Button\n type=\"button\"\n intent=\"primary\"\n emphasis=\"solid\"\n onClick={handleSave}\n disabled={!value.trim() || busy !== null}\n className=\"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium disabled:opacity-40\"\n style={{ backgroundColor: \"#00B5FF\", color: \"white\" }}\n >\n {busy === \"save\" ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : secret.status === \"set\" ? (\n <>\n <IconRefresh size={10} />\n Rotate\n </>\n ) : (\n \"Save\"\n )}\n </Button>\n </div>\n <div className=\"flex items-center gap-1.5\">\n {secret.status === \"set\" && (\n <>\n <Button\n type=\"button\"\n intent=\"neutral\"\n emphasis=\"outline\"\n onClick={handleTest}\n disabled={busy !== null}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] text-muted-foreground hover:text-foreground disabled:opacity-40\"\n >\n {busy === \"test\" ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : (\n \"Test\"\n )}\n </Button>\n <Button\n type=\"button\"\n intent=\"danger\"\n emphasis=\"outline\"\n onClick={() => setConfirmDelete(true)}\n disabled={busy !== null}\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] text-muted-foreground hover:text-red-500 disabled:opacity-40\"\n >\n <IconTrash size={10} />\n Remove\n </Button>\n </>\n )}\n {secret.docsUrl && (\n <a\n href={secret.docsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center gap-1 rounded border border-border px-2 py-1 text-[10px] no-underline text-muted-foreground hover:text-foreground ms-auto\"\n >\n Get key\n <IconExternalLink size={10} />\n </a>\n )}\n </div>\n {confirmDelete && (\n <div className=\"flex items-center gap-1.5 rounded border border-red-500/30 bg-red-500/10 px-2 py-1.5 text-[10px] text-red-500\">\n <span className=\"min-w-0 flex-1\">\n Remove this saved value?\n </span>\n <Button\n type=\"button\"\n intent=\"danger\"\n emphasis=\"solid\"\n onClick={handleDelete}\n disabled={busy !== null}\n className=\"inline-flex items-center gap-1 rounded border border-red-500/40 px-1.5 py-0.5 font-medium disabled:opacity-40\"\n >\n {busy === \"delete\" ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : (\n \"Confirm\"\n )}\n </Button>\n <Button\n type=\"button\"\n intent=\"neutral\"\n emphasis=\"outline\"\n onClick={() => setConfirmDelete(false)}\n disabled={busy !== null}\n className=\"rounded border border-border px-1.5 py-0.5 text-muted-foreground hover:text-foreground disabled:opacity-40\"\n >\n Cancel\n </Button>\n </div>\n )}\n </div>\n )}\n\n {toast && (\n <p\n className={`mt-1.5 text-[10px] ${\n toast.kind === \"ok\" ? \"text-green-500\" : \"text-red-500\"\n }`}\n >\n {toast.text}\n </p>\n )}\n </div>\n )}\n </div>\n );\n}\n\n// ─── Ad-hoc Keys Section ──────────────────────────────────────────────────\n\ninterface AdHocKey {\n name: string;\n scope: \"user\" | \"workspace\";\n scopeId: string;\n description: string | null;\n last4: string;\n createdAt: number;\n updatedAt: number;\n}\n\nconst ADHOC_ENDPOINT = agentNativePath(\"/_agent-native/secrets/adhoc\");\n\nfunction AdHocKeysSection({\n showForm,\n onShowFormChange,\n showEmptyState,\n}: {\n showForm: boolean;\n onShowFormChange: (show: boolean) => void;\n showEmptyState: boolean;\n}) {\n const t = useT();\n const [keys, setKeys] = useState<AdHocKey[]>([]);\n const [loading, setLoading] = useState(true);\n const [reloadToken, setReloadToken] = useState(0);\n const [formName, setFormName] = useState(\"\");\n const [formValue, setFormValue] = useState(\"\");\n const [formDescription, setFormDescription] = useState(\"\");\n const [formScope, setFormScope] = useState<\"user\" | \"workspace\">(\"user\");\n const [formBusy, setFormBusy] = useState(false);\n const [formError, setFormError] = useState<string | null>(null);\n const [confirmDeleteName, setConfirmDeleteName] = useState<string | null>(\n null,\n );\n const [deletingName, setDeletingName] = useState<string | null>(null);\n const [toast, setToast] = useState<{\n kind: \"ok\" | \"err\";\n text: string;\n } | null>(null);\n\n const showToast = useCallback(\n (kind: \"ok\" | \"err\", text: string, ms = 2500) => {\n setToast({ kind, text });\n setTimeout(() => setToast(null), ms);\n },\n [],\n );\n\n const reload = useCallback(() => setReloadToken((t) => t + 1), []);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n fetch(ADHOC_ENDPOINT)\n .then(async (r) => {\n if (!r.ok) throw new Error(`Failed to load (${r.status})`);\n return (await r.json()) as AdHocKey[];\n })\n .then((data) => {\n if (!cancelled) {\n setKeys(data);\n setLoading(false);\n }\n })\n .catch(() => {\n if (!cancelled) {\n setKeys([]);\n setLoading(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [reloadToken]);\n\n const resetForm = useCallback(() => {\n onShowFormChange(false);\n setFormName(\"\");\n setFormValue(\"\");\n setFormDescription(\"\");\n setFormScope(\"user\");\n setFormError(null);\n }, [onShowFormChange]);\n\n const handleAdd = useCallback(async () => {\n const name = formName.trim();\n const value = formValue.trim();\n if (!name || !value || formBusy) return;\n setFormBusy(true);\n setFormError(null);\n try {\n const res = await fetch(ADHOC_ENDPOINT, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n name,\n value,\n description: formDescription.trim() || undefined,\n scope: formScope,\n }),\n });\n if (!res.ok) {\n const body = await res\n .json()\n .then((j: { error?: string }) => j.error)\n .catch(() => null);\n setFormError(body ?? `Save failed (${res.status})`);\n return;\n }\n resetForm();\n showToast(\"ok\", \"Key saved\");\n notifySecretsChanged();\n reload();\n } catch (err: any) {\n setFormError(err?.message ?? \"Failed to save\");\n } finally {\n setFormBusy(false);\n }\n }, [\n formName,\n formValue,\n formDescription,\n formScope,\n formBusy,\n resetForm,\n showToast,\n reload,\n ]);\n\n const handleDelete = useCallback(\n async (name: string) => {\n setDeletingName(name);\n try {\n const res = await fetch(\n `${ADHOC_ENDPOINT}/${encodeURIComponent(name)}`,\n {\n method: \"DELETE\",\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n if (!res.ok) {\n showToast(\"err\", \"Failed to delete key\");\n return;\n }\n showToast(\"ok\", \"Key deleted\");\n setConfirmDeleteName(null);\n notifySecretsChanged();\n reload();\n } finally {\n setDeletingName(null);\n }\n },\n [showToast, reload],\n );\n\n return (\n <div className=\"space-y-2\">\n {showForm && (\n <div className=\"rounded-md border border-border px-2.5 py-2 bg-accent/30 space-y-1.5\">\n <TextField\n value={formName}\n onChange={(value) =>\n setFormName(value.toUpperCase().replace(/[^A-Z0-9_-]/g, \"\"))\n }\n className=\"w-full text-[11px]\"\n aria-label=\"Key name\"\n placeholder=\"KEY_NAME\"\n />\n <TextField\n type=\"password\"\n aria-label=\"Secret value\"\n value={formValue}\n onChange={setFormValue}\n className=\"w-full text-[11px]\"\n placeholder=\"Secret value\"\n />\n <TextField\n value={formDescription}\n aria-label=\"Description\"\n onChange={setFormDescription}\n className=\"w-full text-[11px]\"\n placeholder=\"Description (optional)\"\n />\n <Picker\n mode=\"select\"\n options={[\n { value: \"user\", label: t(\"secrets.scopePersonal\") },\n { value: \"workspace\", label: t(\"secrets.scopeWorkspace\") },\n ]}\n value={formScope}\n onChange={(value) => {\n if (value === \"user\" || value === \"workspace\") {\n setFormScope(value);\n }\n }}\n aria-label={t(\"secrets.scopeLabel\")}\n description={t(\n formScope === \"user\"\n ? \"secrets.scopePersonalDescription\"\n : \"secrets.scopeWorkspaceDescription\",\n )}\n className=\"text-[11px]\"\n />\n <div className=\"flex items-center justify-end gap-1.5\">\n <Button\n type=\"button\"\n intent=\"neutral\"\n emphasis=\"outline\"\n onClick={resetForm}\n className=\"rounded border border-border px-2 py-1 text-[10px] font-medium text-muted-foreground hover:text-foreground\"\n >\n Cancel\n </Button>\n <Button\n type=\"button\"\n intent=\"primary\"\n emphasis=\"solid\"\n onClick={handleAdd}\n disabled={!formName.trim() || !formValue.trim() || formBusy}\n className=\"inline-flex items-center gap-1 rounded px-2 py-1 text-[10px] font-medium disabled:opacity-40\"\n style={{ backgroundColor: \"#00B5FF\", color: \"white\" }}\n >\n {formBusy ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : (\n \"Save\"\n )}\n </Button>\n </div>\n {formError && <p className=\"text-[10px] text-red-500\">{formError}</p>}\n </div>\n )}\n\n {loading ? (\n <div className=\"flex items-center gap-1.5 text-[10px] text-muted-foreground\">\n <IconLoader2 size={10} className=\"animate-spin\" />\n Loading...\n </div>\n ) : keys.length === 0 && !showForm && showEmptyState ? (\n <p className=\"text-[10px] text-muted-foreground\">No keys added yet.</p>\n ) : keys.length > 0 ? (\n <div className=\"overflow-hidden rounded-md border border-border\">\n {keys.map((key) => (\n <div\n key={`${key.scope}-${key.name}`}\n className=\"border-b border-border px-2.5 py-2 last:border-b-0\"\n >\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-[11px] font-medium text-foreground font-mono truncate\">\n {key.name}\n </span>\n <span\n className={`rounded-full px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide ${\n key.scope === \"workspace\"\n ? \"bg-blue-500/15 text-blue-500\"\n : \"bg-accent/60 text-muted-foreground\"\n }`}\n >\n {key.scope === \"workspace\" ? \"workspace\" : \"personal\"}\n </span>\n </div>\n {key.description && (\n <p className=\"text-[10px] text-muted-foreground mt-0.5\">\n {key.description}\n </p>\n )}\n <div className=\"flex items-center gap-2 text-[10px] text-muted-foreground mt-0.5\">\n <span>\n Ending in{\" \"}\n <code className=\"rounded bg-background px-1 py-0.5 text-foreground\">\n {key.last4}\n </code>\n </span>\n </div>\n </div>\n <div className=\"shrink-0\">\n {confirmDeleteName === key.name ? (\n <div className=\"flex items-center gap-1\">\n <Button\n type=\"button\"\n intent=\"danger\"\n emphasis=\"solid\"\n onClick={() => handleDelete(key.name)}\n disabled={deletingName === key.name}\n className=\"rounded px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide bg-red-500/15 text-red-500 hover:bg-red-500/25 disabled:opacity-40\"\n >\n {deletingName === key.name ? (\n <IconLoader2 size={10} className=\"animate-spin\" />\n ) : (\n \"Confirm\"\n )}\n </Button>\n <Button\n type=\"button\"\n intent=\"neutral\"\n emphasis=\"solid\"\n onClick={() => setConfirmDeleteName(null)}\n className=\"rounded px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide bg-accent/60 text-muted-foreground hover:text-foreground\"\n >\n Cancel\n </Button>\n </div>\n ) : (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n intent=\"danger\"\n emphasis=\"ghost\"\n onClick={() => setConfirmDeleteName(key.name)}\n className=\"text-muted-foreground hover:text-red-500\"\n >\n <IconTrash size={12} />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Delete</TooltipContent>\n </Tooltip>\n )}\n </div>\n </div>\n </div>\n ))}\n </div>\n ) : null}\n\n {toast && (\n <p\n className={`text-[10px] ${toast.kind === \"ok\" ? \"text-green-500\" : \"text-red-500\"}`}\n >\n {toast.text}\n </p>\n )}\n </div>\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-chat-models.d.ts","sourceRoot":"","sources":["../../src/client/use-chat-models.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAC;AAGhC,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,MAAM,WAAW,mBAAmB;IAClC,eAAe,EAAE,gBAAgB,EAAE,CAAC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,eAAe,CAAC;IAChC,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvD,cAAc,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IAClD,cAAc,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED,UAAU,OAAO;IACf;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAGD,eAAO,MAAM,kCAAkC,8CACF,CAAC;AAgC9C;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAC5B,UAAgC,EAChC,OAAc,GACf,GAAE,OAAY,GAAG,mBAAmB,
|
|
1
|
+
{"version":3,"file":"use-chat-models.d.ts","sourceRoot":"","sources":["../../src/client/use-chat-models.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAC;AAGhC,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,MAAM,WAAW,mBAAmB;IAClC,eAAe,EAAE,gBAAgB,EAAE,CAAC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,eAAe,CAAC;IAChC,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvD,cAAc,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IAClD,cAAc,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED,UAAU,OAAO;IACf;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAGD,eAAO,MAAM,kCAAkC,8CACF,CAAC;AAgC9C;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAC5B,UAAgC,EAChC,OAAc,GACf,GAAE,OAAY,GAAG,mBAAmB,CAmOpC"}
|
|
@@ -120,8 +120,12 @@ export function useChatModels({ storageKey = DEFAULT_STORAGE_KEY, enabled = true
|
|
|
120
120
|
.catch(() => null),
|
|
121
121
|
])
|
|
122
122
|
.then(([enginesData, envKeys, builderStatus]) => {
|
|
123
|
-
if (!enginesData?.engines)
|
|
123
|
+
if (!enginesData?.engines) {
|
|
124
|
+
// Without a catalog the picker keeps an unvalidated DEFAULT_MODEL,
|
|
125
|
+
// which is indistinguishable from a real selection unless we say so.
|
|
126
|
+
console.warn("[agent-chat] no engine list; model picker is showing an unvalidated default");
|
|
124
127
|
return;
|
|
128
|
+
}
|
|
125
129
|
const configuredKeys = new Set(envKeys
|
|
126
130
|
.filter((k) => k.configured)
|
|
127
131
|
.map((k) => k.key));
|
|
@@ -139,39 +143,54 @@ export function useChatModels({ storageKey = DEFAULT_STORAGE_KEY, enabled = true
|
|
|
139
143
|
setAvailableModels(groups);
|
|
140
144
|
setDefaultModel(nextDefaultModel);
|
|
141
145
|
const selection = selectionRef.current;
|
|
146
|
+
// Default only to a CONFIGURED group, and to nothing when there is
|
|
147
|
+
// none. `DEFAULT_MODEL` is a builder-gateway id that no group carries
|
|
148
|
+
// unless Builder is connected, and unconfigured groups are kept in the
|
|
149
|
+
// list for their connect affordance — so both `?? DEFAULT_MODEL` and
|
|
150
|
+
// `?? groups[0]` yield a selection the app cannot route, which the
|
|
151
|
+
// server silently replaces with its own default. An empty selection
|
|
152
|
+
// hides the picker instead of showing a model that will not be used.
|
|
153
|
+
const configuredGroups = groups.filter((g) => g.configured);
|
|
154
|
+
const resolveRoutableSelection = () => {
|
|
155
|
+
const group = configuredGroups.find((g) => g.models.includes(nextDefaultModel)) ??
|
|
156
|
+
configuredGroups[0];
|
|
157
|
+
if (!group)
|
|
158
|
+
return null;
|
|
159
|
+
const model = group.models.find((m) => m === nextDefaultModel) ?? group.models[0];
|
|
160
|
+
if (!model)
|
|
161
|
+
return null;
|
|
162
|
+
return {
|
|
163
|
+
model,
|
|
164
|
+
engine: group.engine,
|
|
165
|
+
effort: resolveReasoningEffortSelection(model, selection.selectedEffort),
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
const applyFallback = (persist) => {
|
|
169
|
+
const next = resolveRoutableSelection();
|
|
170
|
+
setSelectedModel(next?.model ?? "");
|
|
171
|
+
setSelectedEngine(next?.engine ?? "");
|
|
172
|
+
if (next) {
|
|
173
|
+
setSelectedEffort(next.effort);
|
|
174
|
+
if (persist)
|
|
175
|
+
writePersisted(storageKey, next);
|
|
176
|
+
}
|
|
177
|
+
};
|
|
142
178
|
if (!hasExplicitSelectionRef.current) {
|
|
143
|
-
|
|
144
|
-
groups[0];
|
|
145
|
-
const nextModel = defaultGroup?.models.find((model) => model === nextDefaultModel) ??
|
|
146
|
-
defaultGroup?.models[0] ??
|
|
147
|
-
nextDefaultModel;
|
|
148
|
-
const nextEngine = defaultGroup?.engine ?? "";
|
|
149
|
-
const nextEffort = resolveReasoningEffortSelection(nextModel, selection.selectedEffort);
|
|
150
|
-
setSelectedModel(nextModel);
|
|
151
|
-
setSelectedEngine(nextEngine);
|
|
152
|
-
setSelectedEffort(nextEffort);
|
|
179
|
+
applyFallback(false);
|
|
153
180
|
return;
|
|
154
181
|
}
|
|
155
182
|
const selectedGroup = groups.find((group) => group.models.includes(selection.selectedModel) &&
|
|
156
183
|
(!selection.selectedEngine ||
|
|
157
184
|
group.engine === selection.selectedEngine));
|
|
158
|
-
if (
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
const nextEffort = resolveReasoningEffortSelection(nextModel, selection.selectedEffort);
|
|
166
|
-
setSelectedModel(nextModel);
|
|
167
|
-
setSelectedEngine(nextEngine);
|
|
168
|
-
setSelectedEffort(nextEffort);
|
|
169
|
-
writePersisted(storageKey, {
|
|
170
|
-
model: nextModel,
|
|
171
|
-
engine: nextEngine,
|
|
172
|
-
effort: nextEffort,
|
|
173
|
-
});
|
|
185
|
+
if (selectedGroup) {
|
|
186
|
+
// Heal a selection stored without an engine (or with a stale one) so
|
|
187
|
+
// later submits carry the pair the catalog resolved.
|
|
188
|
+
if (selection.selectedEngine !== selectedGroup.engine) {
|
|
189
|
+
setSelectedEngine(selectedGroup.engine);
|
|
190
|
+
}
|
|
191
|
+
return;
|
|
174
192
|
}
|
|
193
|
+
applyFallback(true);
|
|
175
194
|
})
|
|
176
195
|
.catch(() => { })
|
|
177
196
|
.finally(() => setIsLoading(false));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-chat-models.js","sourceRoot":"","sources":["../../src/client/use-chat-models.ts"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { DEFAULT_MODEL } from \"../agent/default-model.js\";\nimport {\n DEFAULT_REASONING_EFFORT,\n getReasoningEffortOptionsForModel,\n resolveReasoningEffortSelection,\n type ReasoningEffort,\n} from \"../shared/reasoning-effort.js\";\nimport { agentNativePath } from \"./api-path.js\";\nimport {\n buildChatModelGroups,\n type EngineModelGroup,\n} from \"./chat-model-groups.js\";\nimport { callAction } from \"./use-action.js\";\n\nexport type { EngineModelGroup } from \"./chat-model-groups.js\";\n\nexport interface UseChatModelsResult {\n availableModels: EngineModelGroup[];\n defaultModel: string;\n selectedModel: string;\n selectedEngine: string;\n selectedEffort: ReasoningEffort;\n isLoading: boolean;\n onModelChange: (model: string, engine: string) => void;\n onEffortChange: (effort: ReasoningEffort) => void;\n refreshEngines: () => void;\n}\n\ninterface Options {\n /**\n * localStorage key used to persist the user's model + effort selection across\n * page loads. Pass `null` to disable persistence.\n */\n storageKey?: string | null;\n /**\n * Disable server-backed model discovery for hosts that provide their own\n * model list/state, such as Electron Code.\n */\n enabled?: boolean;\n}\n\nconst DEFAULT_STORAGE_KEY = \"agent-native:chat-models:selection\";\nexport const CHAT_MODEL_SELECTION_CHANGED_EVENT =\n \"agent-native:chat-model-selection-changed\";\n\ninterface PersistedSelection {\n model?: string;\n engine?: string;\n effort?: ReasoningEffort;\n}\n\nfunction readPersisted(key: string | null): PersistedSelection {\n if (!key || typeof window === \"undefined\") return {};\n try {\n const raw = window.localStorage.getItem(key);\n return raw ? (JSON.parse(raw) as PersistedSelection) : {};\n } catch {\n return {};\n }\n}\n\nfunction writePersisted(key: string | null, value: PersistedSelection) {\n if (!key || typeof window === \"undefined\") return;\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n queueMicrotask(() => {\n window.dispatchEvent(\n new CustomEvent(CHAT_MODEL_SELECTION_CHANGED_EVENT, {\n detail: { key },\n }),\n );\n });\n } catch {}\n}\n\n/**\n * Fetches available engines/models from the agent server and exposes the same\n * model picker state that `MultiTabAssistantChat` wires up — for surfaces like\n * the Dispatch homepage hero composer that need an identical model picker\n * without mounting the full tabbed chat.\n */\nexport function useChatModels({\n storageKey = DEFAULT_STORAGE_KEY,\n enabled = true,\n}: Options = {}): UseChatModelsResult {\n const [availableModels, setAvailableModels] = useState<EngineModelGroup[]>(\n [],\n );\n const [isLoading, setIsLoading] = useState(enabled);\n const [defaultModel, setDefaultModel] = useState<string>(DEFAULT_MODEL);\n\n const initialPersisted = readPersisted(storageKey);\n const hasExplicitSelectionRef = useRef(Boolean(initialPersisted.model));\n const [selectedModel, setSelectedModel] = useState<string>(\n initialPersisted.model ?? DEFAULT_MODEL,\n );\n const [selectedEngine, setSelectedEngine] = useState<string>(\n initialPersisted.engine ?? \"\",\n );\n const [selectedEffort, setSelectedEffort] = useState<ReasoningEffort>(\n resolveReasoningEffortSelection(\n initialPersisted.model ?? DEFAULT_MODEL,\n initialPersisted.effort,\n ),\n );\n const selectionRef = useRef({\n selectedModel,\n selectedEngine,\n selectedEffort,\n });\n\n useEffect(() => {\n selectionRef.current = {\n selectedModel,\n selectedEngine,\n selectedEffort,\n };\n }, [selectedEffort, selectedEngine, selectedModel]);\n\n useEffect(() => {\n if (!storageKey || typeof window === \"undefined\") return;\n\n const syncPersistedSelection = (event?: Event) => {\n const detail = (event as CustomEvent<{ key?: string }> | undefined)\n ?.detail;\n if (detail?.key && detail.key !== storageKey) return;\n\n const next = readPersisted(storageKey);\n if (!next.model) return;\n\n hasExplicitSelectionRef.current = true;\n setSelectedModel(next.model);\n setSelectedEngine(next.engine ?? \"\");\n setSelectedEffort(\n resolveReasoningEffortSelection(next.model, next.effort),\n );\n };\n const handleStorage = (event: StorageEvent) => {\n if (event.key === storageKey) syncPersistedSelection();\n };\n\n window.addEventListener(\n CHAT_MODEL_SELECTION_CHANGED_EVENT,\n syncPersistedSelection,\n );\n window.addEventListener(\"storage\", handleStorage);\n return () => {\n window.removeEventListener(\n CHAT_MODEL_SELECTION_CHANGED_EVENT,\n syncPersistedSelection,\n );\n window.removeEventListener(\"storage\", handleStorage);\n };\n }, [storageKey]);\n\n const onModelChange = useCallback(\n (model: string, engine: string) => {\n hasExplicitSelectionRef.current = true;\n const effortOptions = getReasoningEffortOptionsForModel(model);\n setSelectedModel(model);\n setSelectedEngine(engine);\n setSelectedEffort((prevEffort) => {\n const next = effortOptions.includes(prevEffort)\n ? prevEffort\n : DEFAULT_REASONING_EFFORT;\n writePersisted(storageKey, { model, engine, effort: next });\n return next;\n });\n },\n [storageKey],\n );\n\n const onEffortChange = useCallback(\n (effort: ReasoningEffort) => {\n hasExplicitSelectionRef.current = true;\n setSelectedEffort(effort);\n writePersisted(storageKey, {\n model: selectedModel,\n engine: selectedEngine,\n effort,\n });\n },\n [selectedEngine, selectedModel, storageKey],\n );\n\n const refreshEngines = useCallback(() => {\n if (!enabled) return;\n setIsLoading(true);\n Promise.all([\n callAction(\"manage-agent-engine\" as any, { action: \"list\" } as any).catch(\n () => null,\n ),\n fetch(agentNativePath(\"/_agent-native/env-status\"))\n .then((r) => (r.ok ? r.json() : []))\n .catch(() => []),\n fetch(agentNativePath(\"/_agent-native/builder/status\"))\n .then((r) => (r.ok ? r.json() : null))\n .catch(() => null),\n ])\n .then(([enginesData, envKeys, builderStatus]) => {\n if (!enginesData?.engines) return;\n const configuredKeys = new Set(\n (envKeys as Array<{ key: string; configured: boolean }>)\n .filter((k) => k.configured)\n .map((k) => k.key),\n );\n const builderConnected = builderStatus?.configured === true;\n const currentEngineName: string | undefined =\n enginesData.current?.engine;\n const currentModel: string | undefined = enginesData.current?.model;\n\n const groups = buildChatModelGroups({\n engines: enginesData.engines,\n configuredKeys,\n builderConnected,\n currentEngineName,\n currentModel,\n });\n const nextDefaultModel = currentModel ?? DEFAULT_MODEL;\n setAvailableModels(groups);\n setDefaultModel(nextDefaultModel);\n\n const selection = selectionRef.current;\n if (!hasExplicitSelectionRef.current) {\n const defaultGroup =\n groups.find((group) => group.models.includes(nextDefaultModel)) ??\n groups[0];\n const nextModel =\n defaultGroup?.models.find((model) => model === nextDefaultModel) ??\n defaultGroup?.models[0] ??\n nextDefaultModel;\n const nextEngine = defaultGroup?.engine ?? \"\";\n const nextEffort = resolveReasoningEffortSelection(\n nextModel,\n selection.selectedEffort,\n );\n setSelectedModel(nextModel);\n setSelectedEngine(nextEngine);\n setSelectedEffort(nextEffort);\n return;\n }\n\n const selectedGroup = groups.find(\n (group) =>\n group.models.includes(selection.selectedModel) &&\n (!selection.selectedEngine ||\n group.engine === selection.selectedEngine),\n );\n if (!selectedGroup) {\n const defaultGroup =\n groups.find((group) => group.models.includes(nextDefaultModel)) ??\n groups[0];\n const nextModel =\n defaultGroup?.models.find((model) => model === nextDefaultModel) ??\n defaultGroup?.models[0] ??\n nextDefaultModel;\n const nextEngine = defaultGroup?.engine ?? \"\";\n const nextEffort = resolveReasoningEffortSelection(\n nextModel,\n selection.selectedEffort,\n );\n setSelectedModel(nextModel);\n setSelectedEngine(nextEngine);\n setSelectedEffort(nextEffort);\n writePersisted(storageKey, {\n model: nextModel,\n engine: nextEngine,\n effort: nextEffort,\n });\n }\n })\n .catch(() => {})\n .finally(() => setIsLoading(false));\n }, [enabled, storageKey]);\n\n useEffect(() => {\n if (!enabled) {\n setIsLoading(false);\n return;\n }\n refreshEngines();\n }, [enabled, refreshEngines]);\n\n return {\n availableModels,\n defaultModel,\n selectedModel,\n selectedEngine,\n selectedEffort,\n isLoading,\n onModelChange,\n onEffortChange,\n refreshEngines,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"use-chat-models.js","sourceRoot":"","sources":["../../src/client/use-chat-models.ts"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { DEFAULT_MODEL } from \"../agent/default-model.js\";\nimport {\n DEFAULT_REASONING_EFFORT,\n getReasoningEffortOptionsForModel,\n resolveReasoningEffortSelection,\n type ReasoningEffort,\n} from \"../shared/reasoning-effort.js\";\nimport { agentNativePath } from \"./api-path.js\";\nimport {\n buildChatModelGroups,\n type EngineModelGroup,\n} from \"./chat-model-groups.js\";\nimport { callAction } from \"./use-action.js\";\n\nexport type { EngineModelGroup } from \"./chat-model-groups.js\";\n\nexport interface UseChatModelsResult {\n availableModels: EngineModelGroup[];\n defaultModel: string;\n selectedModel: string;\n selectedEngine: string;\n selectedEffort: ReasoningEffort;\n isLoading: boolean;\n onModelChange: (model: string, engine: string) => void;\n onEffortChange: (effort: ReasoningEffort) => void;\n refreshEngines: () => void;\n}\n\ninterface Options {\n /**\n * localStorage key used to persist the user's model + effort selection across\n * page loads. Pass `null` to disable persistence.\n */\n storageKey?: string | null;\n /**\n * Disable server-backed model discovery for hosts that provide their own\n * model list/state, such as Electron Code.\n */\n enabled?: boolean;\n}\n\nconst DEFAULT_STORAGE_KEY = \"agent-native:chat-models:selection\";\nexport const CHAT_MODEL_SELECTION_CHANGED_EVENT =\n \"agent-native:chat-model-selection-changed\";\n\ninterface PersistedSelection {\n model?: string;\n engine?: string;\n effort?: ReasoningEffort;\n}\n\nfunction readPersisted(key: string | null): PersistedSelection {\n if (!key || typeof window === \"undefined\") return {};\n try {\n const raw = window.localStorage.getItem(key);\n return raw ? (JSON.parse(raw) as PersistedSelection) : {};\n } catch {\n return {};\n }\n}\n\nfunction writePersisted(key: string | null, value: PersistedSelection) {\n if (!key || typeof window === \"undefined\") return;\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n queueMicrotask(() => {\n window.dispatchEvent(\n new CustomEvent(CHAT_MODEL_SELECTION_CHANGED_EVENT, {\n detail: { key },\n }),\n );\n });\n } catch {}\n}\n\n/**\n * Fetches available engines/models from the agent server and exposes the same\n * model picker state that `MultiTabAssistantChat` wires up — for surfaces like\n * the Dispatch homepage hero composer that need an identical model picker\n * without mounting the full tabbed chat.\n */\nexport function useChatModels({\n storageKey = DEFAULT_STORAGE_KEY,\n enabled = true,\n}: Options = {}): UseChatModelsResult {\n const [availableModels, setAvailableModels] = useState<EngineModelGroup[]>(\n [],\n );\n const [isLoading, setIsLoading] = useState(enabled);\n const [defaultModel, setDefaultModel] = useState<string>(DEFAULT_MODEL);\n\n const initialPersisted = readPersisted(storageKey);\n const hasExplicitSelectionRef = useRef(Boolean(initialPersisted.model));\n const [selectedModel, setSelectedModel] = useState<string>(\n initialPersisted.model ?? DEFAULT_MODEL,\n );\n const [selectedEngine, setSelectedEngine] = useState<string>(\n initialPersisted.engine ?? \"\",\n );\n const [selectedEffort, setSelectedEffort] = useState<ReasoningEffort>(\n resolveReasoningEffortSelection(\n initialPersisted.model ?? DEFAULT_MODEL,\n initialPersisted.effort,\n ),\n );\n const selectionRef = useRef({\n selectedModel,\n selectedEngine,\n selectedEffort,\n });\n\n useEffect(() => {\n selectionRef.current = {\n selectedModel,\n selectedEngine,\n selectedEffort,\n };\n }, [selectedEffort, selectedEngine, selectedModel]);\n\n useEffect(() => {\n if (!storageKey || typeof window === \"undefined\") return;\n\n const syncPersistedSelection = (event?: Event) => {\n const detail = (event as CustomEvent<{ key?: string }> | undefined)\n ?.detail;\n if (detail?.key && detail.key !== storageKey) return;\n\n const next = readPersisted(storageKey);\n if (!next.model) return;\n\n hasExplicitSelectionRef.current = true;\n setSelectedModel(next.model);\n setSelectedEngine(next.engine ?? \"\");\n setSelectedEffort(\n resolveReasoningEffortSelection(next.model, next.effort),\n );\n };\n const handleStorage = (event: StorageEvent) => {\n if (event.key === storageKey) syncPersistedSelection();\n };\n\n window.addEventListener(\n CHAT_MODEL_SELECTION_CHANGED_EVENT,\n syncPersistedSelection,\n );\n window.addEventListener(\"storage\", handleStorage);\n return () => {\n window.removeEventListener(\n CHAT_MODEL_SELECTION_CHANGED_EVENT,\n syncPersistedSelection,\n );\n window.removeEventListener(\"storage\", handleStorage);\n };\n }, [storageKey]);\n\n const onModelChange = useCallback(\n (model: string, engine: string) => {\n hasExplicitSelectionRef.current = true;\n const effortOptions = getReasoningEffortOptionsForModel(model);\n setSelectedModel(model);\n setSelectedEngine(engine);\n setSelectedEffort((prevEffort) => {\n const next = effortOptions.includes(prevEffort)\n ? prevEffort\n : DEFAULT_REASONING_EFFORT;\n writePersisted(storageKey, { model, engine, effort: next });\n return next;\n });\n },\n [storageKey],\n );\n\n const onEffortChange = useCallback(\n (effort: ReasoningEffort) => {\n hasExplicitSelectionRef.current = true;\n setSelectedEffort(effort);\n writePersisted(storageKey, {\n model: selectedModel,\n engine: selectedEngine,\n effort,\n });\n },\n [selectedEngine, selectedModel, storageKey],\n );\n\n const refreshEngines = useCallback(() => {\n if (!enabled) return;\n setIsLoading(true);\n Promise.all([\n callAction(\"manage-agent-engine\" as any, { action: \"list\" } as any).catch(\n () => null,\n ),\n fetch(agentNativePath(\"/_agent-native/env-status\"))\n .then((r) => (r.ok ? r.json() : []))\n .catch(() => []),\n fetch(agentNativePath(\"/_agent-native/builder/status\"))\n .then((r) => (r.ok ? r.json() : null))\n .catch(() => null),\n ])\n .then(([enginesData, envKeys, builderStatus]) => {\n if (!enginesData?.engines) {\n // Without a catalog the picker keeps an unvalidated DEFAULT_MODEL,\n // which is indistinguishable from a real selection unless we say so.\n console.warn(\n \"[agent-chat] no engine list; model picker is showing an unvalidated default\",\n );\n return;\n }\n const configuredKeys = new Set(\n (envKeys as Array<{ key: string; configured: boolean }>)\n .filter((k) => k.configured)\n .map((k) => k.key),\n );\n const builderConnected = builderStatus?.configured === true;\n const currentEngineName: string | undefined =\n enginesData.current?.engine;\n const currentModel: string | undefined = enginesData.current?.model;\n\n const groups = buildChatModelGroups({\n engines: enginesData.engines,\n configuredKeys,\n builderConnected,\n currentEngineName,\n currentModel,\n });\n const nextDefaultModel = currentModel ?? DEFAULT_MODEL;\n setAvailableModels(groups);\n setDefaultModel(nextDefaultModel);\n\n const selection = selectionRef.current;\n\n // Default only to a CONFIGURED group, and to nothing when there is\n // none. `DEFAULT_MODEL` is a builder-gateway id that no group carries\n // unless Builder is connected, and unconfigured groups are kept in the\n // list for their connect affordance — so both `?? DEFAULT_MODEL` and\n // `?? groups[0]` yield a selection the app cannot route, which the\n // server silently replaces with its own default. An empty selection\n // hides the picker instead of showing a model that will not be used.\n const configuredGroups = groups.filter((g) => g.configured);\n const resolveRoutableSelection = () => {\n const group =\n configuredGroups.find((g) => g.models.includes(nextDefaultModel)) ??\n configuredGroups[0];\n if (!group) return null;\n const model =\n group.models.find((m) => m === nextDefaultModel) ?? group.models[0];\n if (!model) return null;\n return {\n model,\n engine: group.engine,\n effort: resolveReasoningEffortSelection(\n model,\n selection.selectedEffort,\n ),\n };\n };\n\n const applyFallback = (persist: boolean) => {\n const next = resolveRoutableSelection();\n setSelectedModel(next?.model ?? \"\");\n setSelectedEngine(next?.engine ?? \"\");\n if (next) {\n setSelectedEffort(next.effort);\n if (persist) writePersisted(storageKey, next);\n }\n };\n\n if (!hasExplicitSelectionRef.current) {\n applyFallback(false);\n return;\n }\n\n const selectedGroup = groups.find(\n (group) =>\n group.models.includes(selection.selectedModel) &&\n (!selection.selectedEngine ||\n group.engine === selection.selectedEngine),\n );\n if (selectedGroup) {\n // Heal a selection stored without an engine (or with a stale one) so\n // later submits carry the pair the catalog resolved.\n if (selection.selectedEngine !== selectedGroup.engine) {\n setSelectedEngine(selectedGroup.engine);\n }\n return;\n }\n applyFallback(true);\n })\n .catch(() => {})\n .finally(() => setIsLoading(false));\n }, [enabled, storageKey]);\n\n useEffect(() => {\n if (!enabled) {\n setIsLoading(false);\n return;\n }\n refreshEngines();\n }, [enabled, refreshEngines]);\n\n return {\n availableModels,\n defaultModel,\n selectedModel,\n selectedEngine,\n selectedEffort,\n isLoading,\n onModelChange,\n onEffortChange,\n refreshEngines,\n };\n}\n"]}
|
package/dist/collab/routes.d.ts
CHANGED
|
@@ -26,8 +26,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
|
|
|
26
26
|
* Body: { update: string (base64), requestSource?: string }
|
|
27
27
|
*/
|
|
28
28
|
export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
29
|
-
ok?: undefined;
|
|
30
29
|
error: string;
|
|
30
|
+
ok?: undefined;
|
|
31
31
|
} | {
|
|
32
32
|
error?: undefined;
|
|
33
33
|
ok: boolean;
|
|
@@ -41,9 +41,9 @@ export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import
|
|
|
41
41
|
* Body: { text: string, fieldName?: string, requestSource?: string }
|
|
42
42
|
*/
|
|
43
43
|
export declare const postCollabText: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
44
|
-
text?: undefined;
|
|
45
44
|
ok?: undefined;
|
|
46
45
|
error: string;
|
|
46
|
+
text?: undefined;
|
|
47
47
|
} | {
|
|
48
48
|
error?: undefined;
|
|
49
49
|
ok: boolean;
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
* Body: { json: any, fieldName?: string, type?: "map"|"array", requestSource?: string }
|
|
14
14
|
*/
|
|
15
15
|
export declare const postCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
16
|
-
error: string;
|
|
17
16
|
ok?: undefined;
|
|
17
|
+
error: string;
|
|
18
18
|
} | {
|
|
19
19
|
error?: undefined;
|
|
20
20
|
ok: boolean;
|
|
@@ -17,12 +17,12 @@ declare const _default: import("../../action.js").ActionDefinition<{
|
|
|
17
17
|
id?: undefined;
|
|
18
18
|
provider?: undefined;
|
|
19
19
|
} | {
|
|
20
|
+
error?: undefined;
|
|
20
21
|
configured?: undefined;
|
|
21
22
|
connectPath?: undefined;
|
|
22
23
|
url: string;
|
|
23
24
|
id: string;
|
|
24
25
|
provider: string;
|
|
25
|
-
error?: undefined;
|
|
26
26
|
}>;
|
|
27
27
|
export default _default;
|
|
28
28
|
//# sourceMappingURL=upload-image.d.ts.map
|
|
@@ -183,6 +183,7 @@ declare const messages: {
|
|
|
183
183
|
otherAppsDescription: string;
|
|
184
184
|
availableCount: string;
|
|
185
185
|
activeCount: string;
|
|
186
|
+
pendingCount: string;
|
|
186
187
|
hiddenCount: string;
|
|
187
188
|
createApp: string;
|
|
188
189
|
templates: string;
|
|
@@ -192,6 +193,14 @@ declare const messages: {
|
|
|
192
193
|
show: string;
|
|
193
194
|
hiddenApps: string;
|
|
194
195
|
hiddenAppCount: string;
|
|
196
|
+
pendingApps: string;
|
|
197
|
+
pendingAppsDescription: string;
|
|
198
|
+
showPendingApps: string;
|
|
199
|
+
hidePendingApps: string;
|
|
200
|
+
noActiveWorkspaceApps: string;
|
|
201
|
+
noActiveWorkspaceAppsDescription: string;
|
|
202
|
+
appMetadataOwner: string;
|
|
203
|
+
appMetadataTeams: string;
|
|
195
204
|
workspaceAppFallback: string;
|
|
196
205
|
workspaceAppDescription: string;
|
|
197
206
|
pageNotFound: string;
|