@geminilight/mindos 0.6.63 → 0.6.65
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/_standalone/.mindos-build-version +1 -1
- package/_standalone/.next/BUILD_ID +1 -1
- package/_standalone/.next/app-path-routes-manifest.json +21 -21
- package/_standalone/.next/build-manifest.json +2 -2
- package/_standalone/.next/cache/.previewinfo +1 -1
- package/_standalone/.next/cache/.rscinfo +1 -1
- package/_standalone/.next/cache/config.json +3 -3
- package/_standalone/.next/prerender-manifest.json +3 -3
- package/_standalone/.next/server/app/.well-known/agent-card.json/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/_global-error.html +2 -2
- package/_standalone/.next/server/app/_global-error.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/_standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/_standalone/.next/server/app/_not-found/page.js +1 -1
- package/_standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page.js +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/agents/[agentKey]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/agents/page.js +1 -1
- package/_standalone/.next/server/app/agents/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/agents/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/delegations/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/discover/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/a2a/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/config/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/detect/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/install/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/registry/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/acp/session/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agent-activity/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agents/copy-skill/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/agents/copy-skill/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agents/custom/detect/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/agents/custom/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/ask/route.js +48 -42
- package/_standalone/.next/server/app/api/ask/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/ask/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/ask-sessions/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/auth/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/backlinks/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/backlinks/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/bootstrap/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/changes/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/changes/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/export/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/export/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/extract-pdf/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/import/route.js +1 -1
- package/_standalone/.next/server/app/api/file/import/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/file/import/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/raw/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/file/raw/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/file/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/file/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/graph/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/graph/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/inbox/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/inbox/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/init/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/agents/route.js +1 -1
- package/_standalone/.next/server/app/api/mcp/agents/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/mcp/agents/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/install/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/install-skill/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/restart/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/status/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/mcp/uninstall/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/monitoring/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/monitoring/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/recent-files/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/recent-files/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/search/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/list-models/route.js +1 -1
- package/_standalone/.next/server/app/api/settings/list-models/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/reset-token/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/route.js +1 -1
- package/_standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/settings/test-key/route.js +1 -1
- package/_standalone/.next/server/app/api/settings/test-key/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/check-path/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/check-port/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/generate-token/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/ls/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/setup/route.js +1 -1
- package/_standalone/.next/server/app/api/setup/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/skills/route.js +1 -1
- package/_standalone/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/sync/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/tree-version/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/tree-version/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/uninstall/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update-check/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/update-status/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/api/workflows/route.js.nft.json +1 -1
- package/_standalone/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/changes/page.js +1 -1
- package/_standalone/.next/server/app/changes/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/changes/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/echo/[segment]/page.js +2 -2
- package/_standalone/.next/server/app/echo/[segment]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/echo/[segment]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/echo/page.js +1 -1
- package/_standalone/.next/server/app/echo/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/echo/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/explore/page.js +1 -1
- package/_standalone/.next/server/app/explore/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/explore/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/help/page.js +1 -1
- package/_standalone/.next/server/app/help/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/inbox/history/page.js +1 -1
- package/_standalone/.next/server/app/inbox/history/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/inbox/history/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/login/page.js +1 -1
- package/_standalone/.next/server/app/login/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/page.js +1 -1
- package/_standalone/.next/server/app/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/setup/page.js +2 -2
- package/_standalone/.next/server/app/setup/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/trash/page.js +3 -3
- package/_standalone/.next/server/app/trash/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/trash/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/view/[...path]/page.js +2 -2
- package/_standalone/.next/server/app/view/[...path]/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/view/[...path]/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app/wiki/page.js +1 -1
- package/_standalone/.next/server/app/wiki/page.js.nft.json +1 -1
- package/_standalone/.next/server/app/wiki/page_client-reference-manifest.js +1 -1
- package/_standalone/.next/server/app-paths-manifest.json +21 -21
- package/_standalone/.next/server/chunks/122.js +222 -0
- package/_standalone/.next/server/chunks/3113.js +52 -0
- package/_standalone/.next/server/chunks/6539.js +1 -1
- package/_standalone/.next/server/chunks/8388.js +2 -2
- package/_standalone/.next/server/chunks/953.js +3 -3
- package/_standalone/.next/server/chunks/9787.js +2 -0
- package/_standalone/.next/server/pages/500.html +2 -2
- package/_standalone/.next/server/server-reference-manifest.js +1 -1
- package/_standalone/.next/server/server-reference-manifest.json +1 -1
- package/_standalone/.next/static/chunks/1001-99da82ec8d8c136f.js +1 -0
- package/_standalone/.next/static/chunks/5149-4d828886dda479fa.js +1 -0
- package/_standalone/.next/static/chunks/{5581-82e5db227f8e9393.js → 5581-c671163a2fe1b312.js} +2 -2
- package/_standalone/.next/static/chunks/6636-53238eff89503f03.js +6 -0
- package/_standalone/.next/static/chunks/6757-1c1a89720fdda8f0.js +1 -0
- package/_standalone/.next/static/chunks/7129-20e9d2463a9da646.js +1 -0
- package/_standalone/.next/static/chunks/{3674-be69a8b858ceacdd.js → 7294-cac25d97869afadc.js} +1 -1
- package/_standalone/.next/static/chunks/8225-21e5cebc3731ddf0.js +1 -0
- package/_standalone/.next/static/chunks/8520-b51810e66293ceb8.js +22 -0
- package/_standalone/.next/static/chunks/9207-dc9c31b351a2ed78.js +1 -0
- package/_standalone/.next/static/chunks/app/agents/[agentKey]/{page-b0dabe793500383d.js → page-2f5cf97e03dc1cc9.js} +1 -1
- package/_standalone/.next/static/chunks/app/agents/{page-1f1ac330c8177cf6.js → page-50eac58d511dcc6e.js} +1 -1
- package/_standalone/.next/static/chunks/app/echo/[segment]/page-2a00f4686adf3885.js +11 -0
- package/_standalone/.next/static/chunks/app/{layout-50a6b1164ee98ab9.js → layout-2cb7a6602d2e5d5f.js} +62 -58
- package/_standalone/.next/static/chunks/app/{page-73802bd31d7f6c9f.js → page-5ab911b2226f6ff7.js} +1 -1
- package/_standalone/.next/static/chunks/app/setup/page-907b7c57fad2292b.js +1 -0
- package/_standalone/.next/static/chunks/app/trash/page-11a511b065ea84c2.js +1 -0
- package/_standalone/.next/static/chunks/app/view/[...path]/{page-808f39963bf04715.js → page-26e47dd4c533a58c.js} +2 -2
- package/_standalone/.next/static/css/67e7918f5ed7d147.css +1 -0
- package/_standalone/.next/trace +65 -65
- package/_standalone/__tests__/api/ask-attachments.test.ts +194 -0
- package/_standalone/__tests__/api/settings.test.ts +16 -12
- package/_standalone/__tests__/api/setup.test.ts +11 -9
- package/_standalone/__tests__/api/test-key.test.ts +0 -10
- package/_standalone/__tests__/components/UpdateToast.test.ts +344 -0
- package/_standalone/__tests__/core/context.test.ts +48 -426
- package/_standalone/__tests__/lib/pi-skills.test.ts +4 -4
- package/_standalone/__tests__/lib/settings-ai-client.test.ts +32 -12
- package/_standalone/__tests__/setup.ts +5 -5
- package/_standalone/components/ask/AskContent.tsx +70 -40
- package/_standalone/components/ask/AskHeader.tsx +8 -1
- package/_standalone/components/ask/MessageList.tsx +37 -3
- package/_standalone/components/ask/ProviderModelCapsule.tsx +51 -129
- package/_standalone/components/settings/AiTab.tsx +270 -347
- package/_standalone/components/settings/CustomProviderFields.tsx +121 -0
- package/_standalone/components/settings/CustomProvidersCard.tsx +2 -2
- package/_standalone/components/settings/KnowledgeTab.tsx +6 -20
- package/_standalone/components/settings/McpAgentInstall.tsx +7 -2
- package/_standalone/components/settings/Primitives.tsx +48 -104
- package/_standalone/components/settings/ProviderModal.tsx +38 -221
- package/_standalone/components/settings/SettingsContent.tsx +5 -12
- package/_standalone/components/settings/TestButton.tsx +64 -0
- package/_standalone/components/settings/types.ts +3 -12
- package/_standalone/components/settings/useCustomProviderForm.ts +132 -0
- package/_standalone/components/setup/StepAI.tsx +3 -3
- package/_standalone/components/shared/ModelInput.tsx +18 -4
- package/_standalone/components/shared/ProviderSelect.tsx +126 -134
- package/_standalone/hooks/useAskChat.ts +97 -13
- package/_standalone/hooks/useAskPanel.ts +17 -1
- package/_standalone/lib/settings-ai-client.ts +17 -8
- package/_standalone/tsconfig.tsbuildinfo +1 -1
- package/app/app/api/ask/route.ts +124 -44
- package/app/app/api/mcp/agents/route.ts +3 -3
- package/app/app/api/settings/list-models/route.ts +15 -26
- package/app/app/api/settings/route.ts +14 -59
- package/app/app/api/settings/test-key/route.ts +47 -12
- package/app/app/api/setup/route.ts +36 -18
- package/app/app/api/skills/route.ts +1 -1
- package/app/app/layout.tsx +5 -3
- package/app/components/HomeContent.tsx +11 -0
- package/app/components/UpdateToast.tsx +255 -0
- package/app/components/ask/AskContent.tsx +70 -40
- package/app/components/ask/AskHeader.tsx +8 -1
- package/app/components/ask/MessageList.tsx +37 -3
- package/app/components/ask/ProviderModelCapsule.tsx +51 -129
- package/app/components/settings/AiTab.tsx +270 -347
- package/app/components/settings/CustomProviderFields.tsx +121 -0
- package/app/components/settings/CustomProvidersCard.tsx +2 -2
- package/app/components/settings/KnowledgeTab.tsx +6 -20
- package/app/components/settings/McpAgentInstall.tsx +7 -2
- package/app/components/settings/Primitives.tsx +48 -104
- package/app/components/settings/ProviderModal.tsx +38 -221
- package/app/components/settings/SettingsContent.tsx +5 -12
- package/app/components/settings/TestButton.tsx +64 -0
- package/app/components/settings/types.ts +3 -12
- package/app/components/settings/useCustomProviderForm.ts +132 -0
- package/app/components/setup/StepAI.tsx +3 -3
- package/app/components/shared/ModelInput.tsx +18 -4
- package/app/components/shared/ProviderSelect.tsx +126 -134
- package/app/hooks/useAskChat.ts +97 -13
- package/app/hooks/useAskPanel.ts +17 -1
- package/app/lib/agent/context.ts +65 -0
- package/app/lib/agent/providers.ts +25 -0
- package/app/lib/agent/tools.ts +1 -1
- package/app/lib/custom-endpoints.ts +129 -29
- package/app/lib/i18n/modules/settings.ts +20 -0
- package/app/lib/pi-integration/skills.ts +16 -4
- package/app/lib/settings-ai-client.ts +17 -8
- package/app/lib/settings.ts +64 -90
- package/app/lib/types.ts +4 -0
- package/package.json +1 -1
- package/_standalone/.next/server/chunks/530.js +0 -218
- package/_standalone/.next/server/chunks/9007.js +0 -2
- package/_standalone/.next/server/chunks/9137.js +0 -52
- package/_standalone/.next/static/chunks/1309-373ade1b40aea186.js +0 -1
- package/_standalone/.next/static/chunks/3165-9189a38fd9ebf6f2.js +0 -1
- package/_standalone/.next/static/chunks/4587-5d06728133fff222.js +0 -1
- package/_standalone/.next/static/chunks/6261-5ce86db54b19ae46.js +0 -1
- package/_standalone/.next/static/chunks/6636-9bbc90fb3b8731fe.js +0 -6
- package/_standalone/.next/static/chunks/7637-904b0a381dc3ec02.js +0 -1
- package/_standalone/.next/static/chunks/8520-84e607f33c409f91.js +0 -22
- package/_standalone/.next/static/chunks/9207-9a4a1a1ede4f8e6e.js +0 -1
- package/_standalone/.next/static/chunks/app/echo/[segment]/page-bc5e104eb7ae6327.js +0 -11
- package/_standalone/.next/static/chunks/app/setup/page-79acb0baf38184c6.js +0 -1
- package/_standalone/.next/static/chunks/app/trash/page-d040db56863da504.js +0 -1
- package/_standalone/.next/static/css/1287672978833d07.css +0 -1
- package/_standalone/lib/agent/context.ts +0 -403
- /package/_standalone/.next/static/{X86rF8dKEO0InosOw4a2_ → eIlwbGas1iRGonlPyEwj7}/_buildManifest.js +0 -0
- /package/_standalone/.next/static/{X86rF8dKEO0InosOw4a2_ → eIlwbGas1iRGonlPyEwj7}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { Field, Select, Input, PasswordInput } from './Primitives';
|
|
4
|
+
import { PROVIDER_PRESETS, ALL_PROVIDER_IDS, type ProviderId } from '@/lib/agent/providers';
|
|
5
|
+
import ModelInput from '@/components/shared/ModelInput';
|
|
6
|
+
import type { CustomProviderFormState } from './useCustomProviderForm';
|
|
7
|
+
import type { AiTabProps } from './types';
|
|
8
|
+
|
|
9
|
+
interface CustomProviderFieldsProps {
|
|
10
|
+
form: CustomProviderFormState;
|
|
11
|
+
t: AiTabProps['t'];
|
|
12
|
+
locale: string;
|
|
13
|
+
/** "compact" = inline in AiTab (name+protocol side by side), "full" = modal layout */
|
|
14
|
+
layout?: 'compact' | 'full';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Shared form fields for provider editing.
|
|
19
|
+
* Renders: Name, Protocol, Base URL, API Key, Model.
|
|
20
|
+
*/
|
|
21
|
+
export default function CustomProviderFields({
|
|
22
|
+
form, t, locale, layout = 'full',
|
|
23
|
+
}: CustomProviderFieldsProps) {
|
|
24
|
+
const basePreset = PROVIDER_PRESETS[form.protocol];
|
|
25
|
+
|
|
26
|
+
const nameLabel = locale === 'zh' ? '名称' : 'Name';
|
|
27
|
+
const protocolLabel = locale === 'zh' ? '协议' : 'Protocol';
|
|
28
|
+
const namePlaceholder = locale === 'zh' ? '输入名称' : 'Enter name';
|
|
29
|
+
|
|
30
|
+
const nameHint = form.isDuplicateName
|
|
31
|
+
? (locale === 'zh' ? '名称已存在' : 'Name already exists')
|
|
32
|
+
: undefined;
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<div className="space-y-3">
|
|
36
|
+
{/* Name + Protocol */}
|
|
37
|
+
{layout === 'compact' ? (
|
|
38
|
+
<div className="grid grid-cols-2 gap-3">
|
|
39
|
+
<Field label={nameLabel} hint={nameHint} hintError={form.isDuplicateName}>
|
|
40
|
+
<Input
|
|
41
|
+
value={form.name}
|
|
42
|
+
onChange={e => form.setName(e.target.value)}
|
|
43
|
+
placeholder={namePlaceholder}
|
|
44
|
+
autoFocus
|
|
45
|
+
/>
|
|
46
|
+
</Field>
|
|
47
|
+
<Field label={protocolLabel}>
|
|
48
|
+
<Select
|
|
49
|
+
value={form.protocol}
|
|
50
|
+
onChange={e => form.setProtocol(e.target.value as ProviderId)}
|
|
51
|
+
>
|
|
52
|
+
{ALL_PROVIDER_IDS.map(id => (
|
|
53
|
+
<option key={id} value={id}>
|
|
54
|
+
{locale === 'zh' ? PROVIDER_PRESETS[id].nameZh : PROVIDER_PRESETS[id].name}
|
|
55
|
+
</option>
|
|
56
|
+
))}
|
|
57
|
+
</Select>
|
|
58
|
+
</Field>
|
|
59
|
+
</div>
|
|
60
|
+
) : (
|
|
61
|
+
<>
|
|
62
|
+
<Field label={nameLabel} hint={nameHint} hintError={form.isDuplicateName}>
|
|
63
|
+
<Input
|
|
64
|
+
value={form.name}
|
|
65
|
+
onChange={e => form.setName(e.target.value)}
|
|
66
|
+
placeholder={namePlaceholder}
|
|
67
|
+
/>
|
|
68
|
+
</Field>
|
|
69
|
+
<Field label={protocolLabel}>
|
|
70
|
+
<Select
|
|
71
|
+
value={form.protocol}
|
|
72
|
+
onChange={e => form.setProtocol(e.target.value as ProviderId)}
|
|
73
|
+
>
|
|
74
|
+
{ALL_PROVIDER_IDS.map(id => (
|
|
75
|
+
<option key={id} value={id}>
|
|
76
|
+
{locale === 'zh' ? PROVIDER_PRESETS[id].nameZh : PROVIDER_PRESETS[id].name}
|
|
77
|
+
</option>
|
|
78
|
+
))}
|
|
79
|
+
</Select>
|
|
80
|
+
</Field>
|
|
81
|
+
</>
|
|
82
|
+
)}
|
|
83
|
+
|
|
84
|
+
{/* Base URL */}
|
|
85
|
+
<Field label="Base URL">
|
|
86
|
+
<Input
|
|
87
|
+
value={form.baseUrl}
|
|
88
|
+
onChange={e => form.setBaseUrl(e.target.value)}
|
|
89
|
+
placeholder={basePreset.fixedBaseUrl || 'https://api.example.com/v1'}
|
|
90
|
+
/>
|
|
91
|
+
</Field>
|
|
92
|
+
|
|
93
|
+
{/* API Key */}
|
|
94
|
+
<Field
|
|
95
|
+
label={<>API Key <span className="text-muted-foreground/50 font-normal">{locale === 'zh' ? '(可选)' : '(optional)'}</span></>}
|
|
96
|
+
>
|
|
97
|
+
<PasswordInput
|
|
98
|
+
value={form.apiKey}
|
|
99
|
+
onChange={form.setApiKey}
|
|
100
|
+
placeholder="sk-..."
|
|
101
|
+
/>
|
|
102
|
+
</Field>
|
|
103
|
+
|
|
104
|
+
{/* Model */}
|
|
105
|
+
<Field label={locale === 'zh' ? '模型' : 'Model'}>
|
|
106
|
+
<ModelInput
|
|
107
|
+
value={form.model}
|
|
108
|
+
onChange={form.setModel}
|
|
109
|
+
placeholder={basePreset.defaultModel}
|
|
110
|
+
provider={form.protocol}
|
|
111
|
+
apiKey={form.apiKey}
|
|
112
|
+
baseUrl={form.baseUrl}
|
|
113
|
+
supportsListModels={!!form.baseUrl.trim()}
|
|
114
|
+
allowNoKey
|
|
115
|
+
browseLabel={t.settings.ai.listModels}
|
|
116
|
+
noModelsLabel={t.settings.ai.noModelsFound}
|
|
117
|
+
/>
|
|
118
|
+
</Field>
|
|
119
|
+
</div>
|
|
120
|
+
);
|
|
121
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { useState, useCallback, useMemo, useRef } from 'react';
|
|
4
4
|
import { Trash2, Edit2, Layers } from 'lucide-react';
|
|
5
5
|
import { useLocale } from '@/lib/stores/locale-store';
|
|
6
|
-
import { type CustomProvider, generateCustomProviderId,
|
|
6
|
+
import { type CustomProvider, generateCustomProviderId, isValidProvider } from '@/lib/custom-endpoints';
|
|
7
7
|
import { SettingCard } from './Primitives';
|
|
8
8
|
import ProviderModal from './ProviderModal';
|
|
9
9
|
|
|
@@ -76,7 +76,7 @@ export default function CustomProvidersCard({
|
|
|
76
76
|
<div className="flex-1 min-w-0">
|
|
77
77
|
<div className="font-medium text-sm">{provider.name}</div>
|
|
78
78
|
<div className="text-xs text-muted-foreground mt-1">
|
|
79
|
-
{provider.
|
|
79
|
+
{provider.protocol} · {provider.model}
|
|
80
80
|
</div>
|
|
81
81
|
<div className="text-2xs text-muted-foreground/60 mt-1 truncate font-mono">
|
|
82
82
|
{provider.baseUrl}
|
|
@@ -4,7 +4,7 @@ import { useState, useEffect, useCallback, useSyncExternalStore, useRef } from '
|
|
|
4
4
|
import { Copy, Check, RefreshCw, Trash2, Sparkles, ChevronDown, ChevronRight, Loader2, Cpu, Zap, Database as DatabaseIcon, HardDrive, RotateCcw, FlaskConical } from 'lucide-react';
|
|
5
5
|
import { toast } from '@/lib/toast';
|
|
6
6
|
import type { KnowledgeTabProps } from './types';
|
|
7
|
-
import { Field, Input, EnvBadge, SectionLabel, Toggle, SettingCard, SettingRow } from './Primitives';
|
|
7
|
+
import { Field, Input, EnvBadge, SectionLabel, Toggle, SettingCard, SettingRow, PasswordInput } from './Primitives';
|
|
8
8
|
import { ConfirmDialog } from '@/components/agents/AgentsPrimitives';
|
|
9
9
|
import { apiFetch } from '@/lib/api';
|
|
10
10
|
import { copyToClipboard } from '@/lib/clipboard';
|
|
@@ -103,9 +103,6 @@ export function KnowledgeTab({ data, setData, t }: KnowledgeTabProps) {
|
|
|
103
103
|
() => 'http://localhost',
|
|
104
104
|
);
|
|
105
105
|
|
|
106
|
-
const [showPassword, setShowPassword] = useState(false);
|
|
107
|
-
const isPasswordMasked = data.webPassword === '***set***';
|
|
108
|
-
|
|
109
106
|
const [resetting, setResetting] = useState(false);
|
|
110
107
|
// revealed holds the plaintext token after regenerate, until user navigates away
|
|
111
108
|
const [revealedToken, setRevealedToken] = useState<string | null>(null);
|
|
@@ -198,22 +195,11 @@ export function KnowledgeTab({ data, setData, t }: KnowledgeTabProps) {
|
|
|
198
195
|
title={k.securityTitle ?? 'Security'}
|
|
199
196
|
>
|
|
200
197
|
<Field label={k.webPassword} hint={k.webPasswordHint}>
|
|
201
|
-
<
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
onFocus={() => { if (isPasswordMasked) setData(d => d ? { ...d, webPassword: '' } : d); }}
|
|
207
|
-
placeholder={k.passwordPlaceholder ?? 'Leave empty to disable'}
|
|
208
|
-
/>
|
|
209
|
-
<button
|
|
210
|
-
type="button"
|
|
211
|
-
onClick={() => setShowPassword(v => !v)}
|
|
212
|
-
className="px-3 py-2 text-sm rounded-lg border border-border text-muted-foreground hover:text-foreground hover:bg-muted transition-colors shrink-0"
|
|
213
|
-
>
|
|
214
|
-
{showPassword ? (k.passwordHide ?? 'Hide') : (k.passwordShow ?? 'Show')}
|
|
215
|
-
</button>
|
|
216
|
-
</div>
|
|
198
|
+
<PasswordInput
|
|
199
|
+
value={data.webPassword ?? ''}
|
|
200
|
+
onChange={v => setData(d => d ? { ...d, webPassword: v } : d)}
|
|
201
|
+
placeholder={k.passwordPlaceholder ?? 'Leave empty to disable'}
|
|
202
|
+
/>
|
|
217
203
|
</Field>
|
|
218
204
|
|
|
219
205
|
<Field
|
|
@@ -6,6 +6,7 @@ import CustomSelect from '@/components/CustomSelect';
|
|
|
6
6
|
import { apiFetch } from '@/lib/api';
|
|
7
7
|
import { copyToClipboard } from '@/lib/clipboard';
|
|
8
8
|
import { toast } from '@/lib/toast';
|
|
9
|
+
import { PasswordInput } from './Primitives';
|
|
9
10
|
import type { AgentInfo, McpAgentInstallProps } from './types';
|
|
10
11
|
|
|
11
12
|
/* ── Agent Install ─────────────────────────────────────────────── */
|
|
@@ -177,8 +178,12 @@ export default function AgentInstall({ agents, t, onRefresh, mode = 'mcp', activ
|
|
|
177
178
|
</div>
|
|
178
179
|
<div className="space-y-1">
|
|
179
180
|
<label className="text-muted-foreground">{m?.httpToken ?? 'Auth Token'}</label>
|
|
180
|
-
<
|
|
181
|
-
|
|
181
|
+
<PasswordInput
|
|
182
|
+
value={httpToken}
|
|
183
|
+
onChange={setHttpToken}
|
|
184
|
+
placeholder="Bearer token"
|
|
185
|
+
size="sm"
|
|
186
|
+
/>
|
|
182
187
|
</div>
|
|
183
188
|
</div>
|
|
184
189
|
)}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import React, { useState, useRef, useEffect, useCallback, useMemo, useId } from 'react';
|
|
4
|
-
import { ChevronDown, Check } from 'lucide-react';
|
|
4
|
+
import { ChevronDown, Check, Eye, EyeOff } from 'lucide-react';
|
|
5
5
|
|
|
6
6
|
export function SectionLabel({ children }: { children: React.ReactNode }) {
|
|
7
7
|
return <p className="text-xs font-medium text-muted-foreground uppercase tracking-wider mb-3">{children}</p>;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
export function Field({ label, hint, children }: { label: React.ReactNode; hint?: string; children: React.ReactNode }) {
|
|
10
|
+
export function Field({ label, hint, hintError, children }: { label: React.ReactNode; hint?: string; hintError?: boolean; children: React.ReactNode }) {
|
|
11
11
|
return (
|
|
12
12
|
<div className="space-y-1.5">
|
|
13
13
|
<label className="text-sm text-foreground font-medium">{label}</label>
|
|
14
14
|
{children}
|
|
15
|
-
{hint && <p className=
|
|
15
|
+
{hint && <p className={`text-xs ${hintError ? 'text-destructive' : 'text-muted-foreground'}`}>{hint}</p>}
|
|
16
16
|
</div>
|
|
17
17
|
);
|
|
18
18
|
}
|
|
@@ -26,6 +26,51 @@ export function Input({ className = '', ...props }: React.InputHTMLAttributes<HT
|
|
|
26
26
|
);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Password/secret input with inline eye toggle.
|
|
31
|
+
* Eye only shows when input has content. Icon sits inside the border.
|
|
32
|
+
*/
|
|
33
|
+
export function PasswordInput({ value, onChange, placeholder, disabled, className = '', size = 'md' }: {
|
|
34
|
+
value: string;
|
|
35
|
+
onChange: (v: string) => void;
|
|
36
|
+
placeholder?: string;
|
|
37
|
+
disabled?: boolean;
|
|
38
|
+
className?: string;
|
|
39
|
+
size?: 'sm' | 'md';
|
|
40
|
+
}) {
|
|
41
|
+
const [show, setShow] = useState(false);
|
|
42
|
+
const sm = size === 'sm';
|
|
43
|
+
return (
|
|
44
|
+
<div className={`flex items-center border border-border rounded-lg bg-background focus-within:ring-1 focus-within:ring-ring overflow-hidden ${className}`}>
|
|
45
|
+
<input
|
|
46
|
+
type={show ? 'text' : 'password'}
|
|
47
|
+
value={value}
|
|
48
|
+
onChange={e => onChange(e.target.value)}
|
|
49
|
+
placeholder={placeholder ?? '••••••••'}
|
|
50
|
+
disabled={disabled}
|
|
51
|
+
className={`flex-1 bg-transparent text-foreground placeholder:text-muted-foreground outline-none disabled:opacity-50 ${
|
|
52
|
+
sm ? 'px-2.5 py-1.5 text-xs font-mono' : 'px-3 py-2 text-sm'
|
|
53
|
+
}`}
|
|
54
|
+
/>
|
|
55
|
+
{!!value && (
|
|
56
|
+
<button
|
|
57
|
+
type="button"
|
|
58
|
+
tabIndex={-1}
|
|
59
|
+
onMouseDown={e => e.preventDefault()}
|
|
60
|
+
onClick={() => setShow(v => !v)}
|
|
61
|
+
disabled={disabled}
|
|
62
|
+
className={`shrink-0 text-muted-foreground hover:text-foreground transition-colors disabled:opacity-50 ${
|
|
63
|
+
sm ? 'p-1.5' : 'p-2'
|
|
64
|
+
}`}
|
|
65
|
+
title={show ? 'Hide' : 'Show'}
|
|
66
|
+
>
|
|
67
|
+
{show ? <EyeOff size={sm ? 14 : 16} /> : <Eye size={sm ? 14 : 16} />}
|
|
68
|
+
</button>
|
|
69
|
+
)}
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
29
74
|
interface SelectOption { value: string; label: string }
|
|
30
75
|
|
|
31
76
|
export function Select({ value, onChange, children, className = '', disabled }: {
|
|
@@ -195,107 +240,6 @@ export function Toggle({ checked, onChange, size = 'md', disabled, title, onClic
|
|
|
195
240
|
);
|
|
196
241
|
}
|
|
197
242
|
|
|
198
|
-
export function ApiKeyInput({ value, onChange, placeholder, disabled, labels }: {
|
|
199
|
-
value: string;
|
|
200
|
-
onChange: (v: string) => void;
|
|
201
|
-
placeholder?: string;
|
|
202
|
-
disabled?: boolean;
|
|
203
|
-
labels?: { change?: string; cancel?: string };
|
|
204
|
-
}) {
|
|
205
|
-
const isMasked = value === '***set***';
|
|
206
|
-
const [editing, setEditing] = useState(false);
|
|
207
|
-
const [draft, setDraft] = useState('');
|
|
208
|
-
const inputRef = useRef<HTMLInputElement>(null);
|
|
209
|
-
const prevValueRef = useRef(value);
|
|
210
|
-
|
|
211
|
-
// Reset editing when the masked value identity changes (e.g. provider switch)
|
|
212
|
-
useEffect(() => {
|
|
213
|
-
if (prevValueRef.current !== value) {
|
|
214
|
-
prevValueRef.current = value;
|
|
215
|
-
setEditing(false);
|
|
216
|
-
setDraft('');
|
|
217
|
-
}
|
|
218
|
-
}, [value]);
|
|
219
|
-
|
|
220
|
-
const commitDraft = useCallback(() => {
|
|
221
|
-
if (draft.trim()) {
|
|
222
|
-
onChange(draft);
|
|
223
|
-
}
|
|
224
|
-
setEditing(false);
|
|
225
|
-
setDraft('');
|
|
226
|
-
}, [draft, onChange]);
|
|
227
|
-
|
|
228
|
-
const cancelEdit = useCallback(() => {
|
|
229
|
-
setEditing(false);
|
|
230
|
-
setDraft('');
|
|
231
|
-
}, []);
|
|
232
|
-
|
|
233
|
-
const changeLabel = labels?.change ?? 'Change';
|
|
234
|
-
const cancelLabel = labels?.cancel ?? 'Cancel';
|
|
235
|
-
|
|
236
|
-
// Masked state: show dots + "Change" button. No clearing on click.
|
|
237
|
-
if (isMasked && !editing) {
|
|
238
|
-
return (
|
|
239
|
-
<div className="flex items-center gap-2">
|
|
240
|
-
<div className="flex-1 px-3 py-2 text-sm bg-muted/50 border border-border rounded-lg text-muted-foreground select-none tracking-widest">
|
|
241
|
-
••••••••••••
|
|
242
|
-
</div>
|
|
243
|
-
<button
|
|
244
|
-
type="button"
|
|
245
|
-
onClick={() => {
|
|
246
|
-
setDraft('');
|
|
247
|
-
setEditing(true);
|
|
248
|
-
requestAnimationFrame(() => inputRef.current?.focus());
|
|
249
|
-
}}
|
|
250
|
-
disabled={disabled}
|
|
251
|
-
className="shrink-0 px-3 py-2 text-xs font-medium rounded-lg border border-border text-muted-foreground hover:text-foreground hover:bg-muted transition-colors disabled:opacity-50"
|
|
252
|
-
>
|
|
253
|
-
{changeLabel}
|
|
254
|
-
</button>
|
|
255
|
-
</div>
|
|
256
|
-
);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// Edit mode (replacing masked key) — uses local draft, commits on Enter/blur
|
|
260
|
-
if (editing) {
|
|
261
|
-
return (
|
|
262
|
-
<div className="flex items-center gap-2">
|
|
263
|
-
<input
|
|
264
|
-
ref={inputRef}
|
|
265
|
-
type="password"
|
|
266
|
-
value={draft}
|
|
267
|
-
onChange={e => setDraft(e.target.value)}
|
|
268
|
-
onKeyDown={e => { if (e.key === 'Enter') commitDraft(); }}
|
|
269
|
-
onBlur={commitDraft}
|
|
270
|
-
placeholder={placeholder ?? 'sk-...'}
|
|
271
|
-
disabled={disabled}
|
|
272
|
-
className="flex-1 px-3 py-2 text-sm bg-background border border-border rounded-lg text-foreground placeholder:text-muted-foreground outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:opacity-50"
|
|
273
|
-
/>
|
|
274
|
-
<button
|
|
275
|
-
type="button"
|
|
276
|
-
onMouseDown={e => e.preventDefault()}
|
|
277
|
-
onClick={cancelEdit}
|
|
278
|
-
className="shrink-0 px-3 py-2 text-xs font-medium rounded-lg border border-border text-muted-foreground hover:text-foreground hover:bg-muted transition-colors"
|
|
279
|
-
>
|
|
280
|
-
{cancelLabel}
|
|
281
|
-
</button>
|
|
282
|
-
</div>
|
|
283
|
-
);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// Normal (no masked key) — direct editing
|
|
287
|
-
return (
|
|
288
|
-
<input
|
|
289
|
-
type="password"
|
|
290
|
-
value={value}
|
|
291
|
-
onChange={e => onChange(e.target.value)}
|
|
292
|
-
placeholder={placeholder ?? 'sk-...'}
|
|
293
|
-
disabled={disabled}
|
|
294
|
-
className="w-full px-3 py-2 text-sm bg-background border border-border rounded-lg text-foreground placeholder:text-muted-foreground outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:opacity-50"
|
|
295
|
-
/>
|
|
296
|
-
);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
243
|
/**
|
|
300
244
|
* 💡 SUGGESTION #10: Unified primary button primitive for amber actions
|
|
301
245
|
* Replaces inline `style={{ background: 'var(--amber)', color: 'var(--amber-foreground)' }}` pattern
|