mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-30 07:39:06 +08:00
Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2
This commit is contained in:
commit
23f7b39753
@ -77,7 +77,7 @@ Please review the following critical information before submitting your Pull Req
|
||||
Our core team is currently focused on significant architectural updates that involve these data structures. To ensure stability and focus during this period, contributions of this nature will be temporarily managed internally.
|
||||
|
||||
* **PRs that require changes to Redux state shape or IndexedDB schemas will be closed.**
|
||||
* **This restriction is temporary and will be lifted with the release of `v2.0.0`.** You can track the progress of `v2.0.0` and its related discussions on issue [#10162](https://github.com/YOUR_ORG/YOUR_REPO/issues/10162) (please replace with your actual repo link).
|
||||
* **This restriction is temporary and will be lifted with the release of `v2.0.0`.** You can track the progress of `v2.0.0` and its related discussions on issue [#10162](https://github.com/CherryHQ/cherry-studio/pull/10162).
|
||||
|
||||
We highly encourage contributions for:
|
||||
* Bug fixes 🐞
|
||||
|
||||
@ -81,7 +81,7 @@ git commit --signoff -m "Your commit message"
|
||||
我们的核心团队目前正专注于涉及这些数据结构的关键架构更新和基础工作。为确保在此期间的稳定性与专注,此类贡献将暂时由内部进行管理。
|
||||
|
||||
* **需要更改 Redux 状态结构或 IndexedDB schema 的 PR 将会被关闭。**
|
||||
* **此限制是临时性的,并将在 `v2.0.0` 版本发布后解除。** 您可以通过 Issue [#10162](https://github.com/YOUR_ORG/YOUR_REPO/issues/10162) (请替换为您的实际仓库链接) 跟踪 `v2.0.0` 的进展及相关讨论。
|
||||
* **此限制是临时性的,并将在 `v2.0.0` 版本发布后解除。** 您可以通过 Issue [#10162](https://github.com/CherryHQ/cherry-studio/pull/10162) 跟踪 `v2.0.0` 的进展及相关讨论。
|
||||
|
||||
我们非常鼓励以下类型的贡献:
|
||||
* 错误修复 🐞
|
||||
|
||||
@ -334,13 +334,13 @@
|
||||
--cs-ring: hsla(84, 81%, 44%, 0.4);
|
||||
|
||||
/* UI Element Colors */
|
||||
--cs-secondary: hsla(0, 0%, 0%, 0.05); /* Secondary Button Background */
|
||||
--cs-secondary: hsla(0, 0%, 0%, 0.05); /* Secondary Button Background */
|
||||
--cs-secondary-hover: hsla(0, 0%, 0%, 0.85);
|
||||
--cs-secondary-active: hsla(0, 0%, 0%, 0.7);
|
||||
--cs-muted: hsla(0, 0%, 0%, 0.05); /* Muted/Subtle Background */
|
||||
--cs-accent: hsla(0, 0%, 0%, 0.05); /* Accent Background */
|
||||
--cs-ghost-hover: hsla(0, 0%, 0%, 0.05); /* Ghost Button Hover */
|
||||
--cs-ghost-active: hsla(0, 0%, 0%, 0.1); /* Ghost Button Active */
|
||||
--cs-muted: hsla(0, 0%, 0%, 0.05); /* Muted/Subtle Background */
|
||||
--cs-accent: hsla(0, 0%, 0%, 0.05); /* Accent Background */
|
||||
--cs-ghost-hover: hsla(0, 0%, 0%, 0.05); /* Ghost Button Hover */
|
||||
--cs-ghost-active: hsla(0, 0%, 0%, 0.1); /* Ghost Button Active */
|
||||
|
||||
/* Sidebar */
|
||||
--cs-sidebar: var(--cs-white);
|
||||
@ -390,43 +390,43 @@
|
||||
/* Spacing & Sizing (合并) */
|
||||
/* ==================== */
|
||||
|
||||
--cs-size-5xs: 0.25rem; /* 4px */
|
||||
--cs-size-4xs: 0.5rem; /* 8px */
|
||||
--cs-size-3xs: 0.75rem; /* 12px */
|
||||
--cs-size-2xs: 1rem; /* 16px */
|
||||
--cs-size-xs: 1.5rem; /* 24px */
|
||||
--cs-size-sm: 2rem; /* 32px */
|
||||
--cs-size-md: 2.5rem; /* 40px */
|
||||
--cs-size-lg: 3rem; /* 48px */
|
||||
--cs-size-xl: 3.5rem; /* 56px */
|
||||
--cs-size-2xl: 4rem; /* 64px */
|
||||
--cs-size-3xl: 4.5rem; /* 72px */
|
||||
--cs-size-4xl: 5rem; /* 80px */
|
||||
--cs-size-5xl: 5.5rem; /* 88px */
|
||||
--cs-size-6xl: 6rem; /* 96px */
|
||||
--cs-size-7xl: 6.5rem; /* 104px */
|
||||
--cs-size-8xl: 7rem; /* 112px */
|
||||
--cs-size-5xs: 0.25rem; /* 4px */
|
||||
--cs-size-4xs: 0.5rem; /* 8px */
|
||||
--cs-size-3xs: 0.75rem; /* 12px */
|
||||
--cs-size-2xs: 1rem; /* 16px */
|
||||
--cs-size-xs: 1.5rem; /* 24px */
|
||||
--cs-size-sm: 2rem; /* 32px */
|
||||
--cs-size-md: 2.5rem; /* 40px */
|
||||
--cs-size-lg: 3rem; /* 48px */
|
||||
--cs-size-xl: 3.5rem; /* 56px */
|
||||
--cs-size-2xl: 4rem; /* 64px */
|
||||
--cs-size-3xl: 4.5rem; /* 72px */
|
||||
--cs-size-4xl: 5rem; /* 80px */
|
||||
--cs-size-5xl: 5.5rem; /* 88px */
|
||||
--cs-size-6xl: 6rem; /* 96px */
|
||||
--cs-size-7xl: 6.5rem; /* 104px */
|
||||
--cs-size-8xl: 7rem; /* 112px */
|
||||
|
||||
/* ==================== */
|
||||
/* Border Radius */
|
||||
/* ==================== */
|
||||
|
||||
--cs-radius-4xs: 0.25rem; /* 4px */
|
||||
--cs-radius-3xs: 0.5rem; /* 8px */
|
||||
--cs-radius-2xs: 0.75rem; /* 12px */
|
||||
--cs-radius-xs: 1rem; /* 16px */
|
||||
--cs-radius-sm: 1.5rem; /* 24px */
|
||||
--cs-radius-md: 2rem; /* 32px */
|
||||
--cs-radius-lg: 2.5rem; /* 40px */
|
||||
--cs-radius-xl: 3rem; /* 48px */
|
||||
--cs-radius-2xl: 3.5rem; /* 56px */
|
||||
--cs-radius-3xl: 4rem; /* 64px */
|
||||
--cs-radius-round: 999px; /* 保持 px,因为是特殊值 */
|
||||
--cs-radius-4xs: 0.25rem; /* 4px */
|
||||
--cs-radius-3xs: 0.5rem; /* 8px */
|
||||
--cs-radius-2xs: 0.75rem; /* 12px */
|
||||
--cs-radius-xs: 1rem; /* 16px */
|
||||
--cs-radius-sm: 1.5rem; /* 24px */
|
||||
--cs-radius-md: 2rem; /* 32px */
|
||||
--cs-radius-lg: 2.5rem; /* 40px */
|
||||
--cs-radius-xl: 3rem; /* 48px */
|
||||
--cs-radius-2xl: 3.5rem; /* 56px */
|
||||
--cs-radius-3xl: 4rem; /* 64px */
|
||||
--cs-radius-round: 999px; /* 保持 px,因为是特殊值 */
|
||||
|
||||
/* Border Width */
|
||||
--cs-border-width-sm: 1px; /* 1px */
|
||||
--cs-border-width-md: 2px; /* 2px */
|
||||
--cs-border-width-lg: 3px; /* 3px */
|
||||
--cs-border-width-sm: 1px; /* 1px */
|
||||
--cs-border-width-md: 2px; /* 2px */
|
||||
--cs-border-width-lg: 3px; /* 3px */
|
||||
|
||||
/* ==================== */
|
||||
/* Typography */
|
||||
@ -442,43 +442,43 @@
|
||||
--cs-font-weight-bold: 700;
|
||||
|
||||
/* Font Sizes - Body */
|
||||
--cs-font-size-body-xs: 0.75rem; /* 12px */
|
||||
--cs-font-size-body-sm: 0.875rem; /* 14px */
|
||||
--cs-font-size-body-md: 1rem; /* 16px */
|
||||
--cs-font-size-body-lg: 1.125rem; /* 18px */
|
||||
--cs-font-size-body-xs: 0.75rem; /* 12px */
|
||||
--cs-font-size-body-sm: 0.875rem; /* 14px */
|
||||
--cs-font-size-body-md: 1rem; /* 16px */
|
||||
--cs-font-size-body-lg: 1.125rem; /* 18px */
|
||||
|
||||
/* Font Sizes - Heading */
|
||||
--cs-font-size-heading-xs: 1.25rem; /* 20px */
|
||||
--cs-font-size-heading-sm: 1.5rem; /* 24px */
|
||||
--cs-font-size-heading-md: 2rem; /* 32px */
|
||||
--cs-font-size-heading-lg: 2.5rem; /* 40px */
|
||||
--cs-font-size-heading-xl: 3rem; /* 48px */
|
||||
--cs-font-size-heading-2xl: 3.75rem; /* 60px */
|
||||
--cs-font-size-heading-xs: 1.25rem; /* 20px */
|
||||
--cs-font-size-heading-sm: 1.5rem; /* 24px */
|
||||
--cs-font-size-heading-md: 2rem; /* 32px */
|
||||
--cs-font-size-heading-lg: 2.5rem; /* 40px */
|
||||
--cs-font-size-heading-xl: 3rem; /* 48px */
|
||||
--cs-font-size-heading-2xl: 3.75rem; /* 60px */
|
||||
|
||||
/* Line Heights - Body */
|
||||
--cs-line-height-body-xs: 1.25rem; /* 20px */
|
||||
--cs-line-height-body-sm: 1.5rem; /* 24px */
|
||||
--cs-line-height-body-md: 1.5rem; /* 24px */
|
||||
--cs-line-height-body-lg: 1.75rem; /* 28px */
|
||||
--cs-line-height-body-xs: 1.25rem; /* 20px */
|
||||
--cs-line-height-body-sm: 1.5rem; /* 24px */
|
||||
--cs-line-height-body-md: 1.5rem; /* 24px */
|
||||
--cs-line-height-body-lg: 1.75rem; /* 28px */
|
||||
|
||||
/* Line Heights - Heading */
|
||||
--cs-line-height-heading-xs: 2rem; /* 32px */
|
||||
--cs-line-height-heading-sm: 2.5rem; /* 40px */
|
||||
--cs-line-height-heading-md: 3rem; /* 48px */
|
||||
--cs-line-height-heading-xs: 2rem; /* 32px */
|
||||
--cs-line-height-heading-sm: 2.5rem; /* 40px */
|
||||
--cs-line-height-heading-md: 3rem; /* 48px */
|
||||
--cs-line-height-heading-lg: 3.75rem; /* 60px */
|
||||
--cs-line-height-heading-xl: 5rem; /* 80px */
|
||||
--cs-line-height-heading-xl: 5rem; /* 80px */
|
||||
|
||||
/* Paragraph Spacing */
|
||||
--cs-paragraph-spacing-body-xs: 0.75rem; /* 12px */
|
||||
--cs-paragraph-spacing-body-sm: 0.875rem; /* 14px */
|
||||
--cs-paragraph-spacing-body-md: 1rem; /* 16px */
|
||||
--cs-paragraph-spacing-body-lg: 1.125rem; /* 18px */
|
||||
--cs-paragraph-spacing-heading-xs: 1.25rem; /* 20px */
|
||||
--cs-paragraph-spacing-heading-sm: 1.5rem; /* 24px */
|
||||
--cs-paragraph-spacing-heading-md: 2rem; /* 32px */
|
||||
--cs-paragraph-spacing-heading-lg: 2.5rem; /* 40px */
|
||||
--cs-paragraph-spacing-heading-xl: 3rem; /* 48px */
|
||||
--cs-paragraph-spacing-heading-2xl: 3.75rem; /* 60px */
|
||||
--cs-paragraph-spacing-body-xs: 0.75rem; /* 12px */
|
||||
--cs-paragraph-spacing-body-sm: 0.875rem; /* 14px */
|
||||
--cs-paragraph-spacing-body-md: 1rem; /* 16px */
|
||||
--cs-paragraph-spacing-body-lg: 1.125rem; /* 18px */
|
||||
--cs-paragraph-spacing-heading-xs: 1.25rem; /* 20px */
|
||||
--cs-paragraph-spacing-heading-sm: 1.5rem; /* 24px */
|
||||
--cs-paragraph-spacing-heading-md: 2rem; /* 32px */
|
||||
--cs-paragraph-spacing-heading-lg: 2.5rem; /* 40px */
|
||||
--cs-paragraph-spacing-heading-xl: 3rem; /* 48px */
|
||||
--cs-paragraph-spacing-heading-2xl: 3.75rem; /* 60px */
|
||||
}
|
||||
|
||||
/* ==================== */
|
||||
@ -506,13 +506,13 @@
|
||||
--cs-ring: hsla(84, 81%, 44%, 0.4);
|
||||
|
||||
/* UI Element Colors - Dark Mode */
|
||||
--cs-secondary: hsla(0, 0%, 100%, 0.1); /* Secondary Button Background */
|
||||
--cs-secondary: hsla(0, 0%, 100%, 0.1); /* Secondary Button Background */
|
||||
--cs-secondary-hover: hsla(0, 0%, 100%, 0.2);
|
||||
--cs-secondary-active: hsla(0, 0%, 100%, 0.25);
|
||||
--cs-muted: hsla(0, 0%, 100%, 0.1); /* Muted/Subtle Background */
|
||||
--cs-accent: hsla(0, 0%, 100%, 0.1); /* Accent Background */
|
||||
--cs-ghost-hover: hsla(0, 0%, 100%, 0.1); /* Ghost Button Hover */
|
||||
--cs-ghost-active: hsla(0, 0%, 100%, 0.15); /* Ghost Button Active */
|
||||
--cs-muted: hsla(0, 0%, 100%, 0.1); /* Muted/Subtle Background */
|
||||
--cs-accent: hsla(0, 0%, 100%, 0.1); /* Accent Background */
|
||||
--cs-ghost-hover: hsla(0, 0%, 100%, 0.1); /* Ghost Button Hover */
|
||||
--cs-ghost-active: hsla(0, 0%, 100%, 0.15); /* Ghost Button Active */
|
||||
|
||||
/* Sidebar */
|
||||
--cs-sidebar: var(--cs-black);
|
||||
@ -558,4 +558,3 @@
|
||||
--cs-ghost-button-background-hover: var(--cs-ghost-hover);
|
||||
--cs-ghost-button-background-active: var(--cs-ghost-active);
|
||||
}
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
@import 'tailwindcss';
|
||||
@import 'tw-animate-css';
|
||||
@import './theme.css'; /* 已包含 design-tokens.css 和所有 cs-* 工具类 */
|
||||
@import './theme.css'; /* 已包含 design-tokens.css 和所有 cs-* 工具类 */
|
||||
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
|
||||
|
||||
@ -239,4 +239,3 @@
|
||||
--border-width-cs-md: var(--cs-border-width-md);
|
||||
--border-width-cs-lg: var(--cs-border-width-lg);
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import '@renderer/databases'
|
||||
|
||||
import { Spinner } from '@heroui/react'
|
||||
import type { FC } from 'react'
|
||||
import { useMemo } from 'react'
|
||||
import { lazy, Suspense, useMemo } from 'react'
|
||||
import { HashRouter, Route, Routes } from 'react-router-dom'
|
||||
|
||||
import Sidebar from './components/app/Sidebar'
|
||||
@ -9,18 +10,25 @@ import { ErrorBoundary } from './components/ErrorBoundary'
|
||||
import TabsContainer from './components/Tab/TabContainer'
|
||||
import NavigationHandler from './handler/NavigationHandler'
|
||||
import { useNavbarPosition } from './hooks/useNavbar'
|
||||
import CodeToolsPage from './pages/code/CodeToolsPage'
|
||||
import FilesPage from './pages/files/FilesPage'
|
||||
import HomePage from './pages/home/HomePage'
|
||||
import KnowledgePage from './pages/knowledge/KnowledgePage'
|
||||
import LaunchpadPage from './pages/launchpad/LaunchpadPage'
|
||||
import MinAppPage from './pages/minapps/MinAppPage'
|
||||
import MinAppsPage from './pages/minapps/MinAppsPage'
|
||||
import NotesPage from './pages/notes/NotesPage'
|
||||
import PaintingsRoutePage from './pages/paintings/PaintingsRoutePage'
|
||||
import SettingsPage from './pages/settings/SettingsPage'
|
||||
import AssistantPresetsPage from './pages/store/assistants/presets/AssistantPresetsPage'
|
||||
import TranslatePage from './pages/translate/TranslatePage'
|
||||
|
||||
const HomePage = lazy(() => import('./pages/home/HomePage'))
|
||||
const AssistantPresetsPage = lazy(() => import('./pages/store/assistants/presets/AssistantPresetsPage'))
|
||||
const PaintingsRoutePage = lazy(() => import('./pages/paintings/PaintingsRoutePage'))
|
||||
const TranslatePage = lazy(() => import('./pages/translate/TranslatePage'))
|
||||
const FilesPage = lazy(() => import('./pages/files/FilesPage'))
|
||||
const NotesPage = lazy(() => import('./pages/notes/NotesPage'))
|
||||
const KnowledgePage = lazy(() => import('./pages/knowledge/KnowledgePage'))
|
||||
const MinAppPage = lazy(() => import('./pages/minapps/MinAppPage'))
|
||||
const MinAppsPage = lazy(() => import('./pages/minapps/MinAppsPage'))
|
||||
const CodeToolsPage = lazy(() => import('./pages/code/CodeToolsPage'))
|
||||
const SettingsPage = lazy(() => import('./pages/settings/SettingsPage'))
|
||||
const LaunchpadPage = lazy(() => import('./pages/launchpad/LaunchpadPage'))
|
||||
|
||||
const RouterFallback: FC = () => (
|
||||
<div className="flex h-full w-full items-center justify-center">
|
||||
<Spinner color="primary" size="lg" label="Loading" />
|
||||
</div>
|
||||
)
|
||||
|
||||
const Router: FC = () => {
|
||||
const { navbarPosition } = useNavbarPosition()
|
||||
@ -28,20 +36,22 @@ const Router: FC = () => {
|
||||
const routes = useMemo(() => {
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
<Routes>
|
||||
<Route path="/" element={<HomePage />} />
|
||||
<Route path="/store" element={<AssistantPresetsPage />} />
|
||||
<Route path="/paintings/*" element={<PaintingsRoutePage />} />
|
||||
<Route path="/translate" element={<TranslatePage />} />
|
||||
<Route path="/files" element={<FilesPage />} />
|
||||
<Route path="/notes" element={<NotesPage />} />
|
||||
<Route path="/knowledge" element={<KnowledgePage />} />
|
||||
<Route path="/apps/:appId" element={<MinAppPage />} />
|
||||
<Route path="/apps" element={<MinAppsPage />} />
|
||||
<Route path="/code" element={<CodeToolsPage />} />
|
||||
<Route path="/settings/*" element={<SettingsPage />} />
|
||||
<Route path="/launchpad" element={<LaunchpadPage />} />
|
||||
</Routes>
|
||||
<Suspense fallback={<RouterFallback />}>
|
||||
<Routes>
|
||||
<Route path="/" element={<HomePage />} />
|
||||
<Route path="/store" element={<AssistantPresetsPage />} />
|
||||
<Route path="/paintings/*" element={<PaintingsRoutePage />} />
|
||||
<Route path="/translate" element={<TranslatePage />} />
|
||||
<Route path="/files" element={<FilesPage />} />
|
||||
<Route path="/notes" element={<NotesPage />} />
|
||||
<Route path="/knowledge" element={<KnowledgePage />} />
|
||||
<Route path="/apps/:appId" element={<MinAppPage />} />
|
||||
<Route path="/apps" element={<MinAppsPage />} />
|
||||
<Route path="/code" element={<CodeToolsPage />} />
|
||||
<Route path="/settings/*" element={<SettingsPage />} />
|
||||
<Route path="/launchpad" element={<LaunchpadPage />} />
|
||||
</Routes>
|
||||
</Suspense>
|
||||
</ErrorBoundary>
|
||||
)
|
||||
}, [])
|
||||
|
||||
@ -20,6 +20,7 @@ export interface EditableNumberProps {
|
||||
suffix?: string
|
||||
prefix?: string
|
||||
align?: 'start' | 'center' | 'end'
|
||||
formatter?: (value: number | null) => string | number
|
||||
}
|
||||
|
||||
const EditableNumber: FC<EditableNumberProps> = ({
|
||||
@ -36,7 +37,8 @@ const EditableNumber: FC<EditableNumberProps> = ({
|
||||
style,
|
||||
className,
|
||||
size = 'middle',
|
||||
align = 'end'
|
||||
align = 'end',
|
||||
formatter
|
||||
}) => {
|
||||
const [isEditing, setIsEditing] = useState(false)
|
||||
const [inputValue, setInputValue] = useState(value)
|
||||
@ -90,7 +92,7 @@ const EditableNumber: FC<EditableNumberProps> = ({
|
||||
changeOnBlur={changeOnBlur}
|
||||
/>
|
||||
<DisplayText style={style} className={className} $align={align} $isEditing={isEditing}>
|
||||
{value ?? placeholder}
|
||||
{formatter ? formatter(value ?? null) : (value ?? placeholder)}
|
||||
</DisplayText>
|
||||
</Container>
|
||||
)
|
||||
|
||||
@ -838,7 +838,7 @@
|
||||
"label": "Context",
|
||||
"tip": "The number of previous messages to keep in the context."
|
||||
},
|
||||
"max": "Max",
|
||||
"max": "Unlimited",
|
||||
"max_tokens": {
|
||||
"confirm": "Set max tokens",
|
||||
"confirm_content": "Set the maximum number of tokens the model can generate. Need to consider the context limit of the model, otherwise an error will be reported",
|
||||
@ -1051,6 +1051,7 @@
|
||||
"copied": "Copied",
|
||||
"copy": "Copy",
|
||||
"copy_failed": "Copy failed",
|
||||
"current": "Current",
|
||||
"cut": "Cut",
|
||||
"default": "Default",
|
||||
"delete": "Delete",
|
||||
|
||||
@ -1051,6 +1051,7 @@
|
||||
"copied": "已复制",
|
||||
"copy": "复制",
|
||||
"copy_failed": "复制失败",
|
||||
"current": "当前",
|
||||
"cut": "剪切",
|
||||
"default": "默认",
|
||||
"delete": "删除",
|
||||
|
||||
@ -838,7 +838,7 @@
|
||||
"label": "上下文",
|
||||
"tip": "在上下文中保留的前幾則訊息"
|
||||
},
|
||||
"max": "最大",
|
||||
"max": "不限",
|
||||
"max_tokens": {
|
||||
"confirm": "設置最大 Token 數",
|
||||
"confirm_content": "設置單次交互所用的最大 Token 數,會影響返回結果的長度。要根據模型上下文限制來設定,否則會發生錯誤",
|
||||
@ -1051,6 +1051,7 @@
|
||||
"copied": "已複製",
|
||||
"copy": "複製",
|
||||
"copy_failed": "複製失敗",
|
||||
"current": "当前",
|
||||
"cut": "剪下",
|
||||
"default": "預設",
|
||||
"delete": "刪除",
|
||||
|
||||
@ -1051,6 +1051,7 @@
|
||||
"copied": "Kopiert",
|
||||
"copy": "Kopieren",
|
||||
"copy_failed": "Kopieren fehlgeschlagen",
|
||||
"current": "Aktuell",
|
||||
"cut": "Ausschneiden",
|
||||
"default": "Standard",
|
||||
"delete": "Löschen",
|
||||
|
||||
@ -838,7 +838,7 @@
|
||||
"label": "Πλήθος ενδιάμεσων",
|
||||
"tip": "Πλήθος των μηνυμάτων που θα παραμείνουν στα ενδιάμεσα, όσο μεγαλύτερο είναι το αριθμός, τόσο μεγαλύτερο είναι το μήκος του ενδιάμεσου και τόσο περισσότερα tokens χρησιμοποιούνται. Συνομιλία συνήθως συνιστάται μεταξύ 5-10"
|
||||
},
|
||||
"max": "Όχι ορισμένο",
|
||||
"max": "άπειρος",
|
||||
"max_tokens": {
|
||||
"confirm": "Ενεργοποίηση περιορισμού μήκους μηνύματος",
|
||||
"confirm_content": "Μετά την ενεργοποίηση του περιορισμού μήκους μηνύματος, ο μέγιστος αριθμός των tokens που χρησιμοποιούνται κάθε φορά, θα επηρεάζει το μήκος της απάντησης. Πρέπει να το ρυθμίζετε βάσει των περιορισμών του πλαισίου του μοντέλου, διαφορετικά θα σφάλλεται.",
|
||||
@ -1051,6 +1051,7 @@
|
||||
"copied": "Αντιγράφηκε",
|
||||
"copy": "Αντιγραφή",
|
||||
"copy_failed": "Αποτυχία αντιγραφής",
|
||||
"current": "Τρέχων",
|
||||
"cut": "Κοπή",
|
||||
"default": "Προεπιλογή",
|
||||
"delete": "Διαγραφή",
|
||||
|
||||
@ -1051,6 +1051,7 @@
|
||||
"copied": "Copiado",
|
||||
"copy": "Copiar",
|
||||
"copy_failed": "Error al copiar",
|
||||
"current": "Actual",
|
||||
"cut": "Cortar",
|
||||
"default": "Predeterminado",
|
||||
"delete": "Eliminar",
|
||||
|
||||
@ -1051,6 +1051,7 @@
|
||||
"copied": "Copié",
|
||||
"copy": "Copier",
|
||||
"copy_failed": "Échec de la copie",
|
||||
"current": "Actuel",
|
||||
"cut": "Couper",
|
||||
"default": "Défaut",
|
||||
"delete": "Supprimer",
|
||||
|
||||
@ -838,7 +838,7 @@
|
||||
"label": "コンテキスト",
|
||||
"tip": "コンテキストに保持する以前のメッセージの数"
|
||||
},
|
||||
"max": "最大",
|
||||
"max": "制限なし",
|
||||
"max_tokens": {
|
||||
"confirm": "最大トークン数",
|
||||
"confirm_content": "最大トークン数を設定すると、モデルが生成できる最大トークン数が制限されます。これにより、返される結果の長さに影響が出る可能性があります。モデルのコンテキスト制限に基づいて設定する必要があります。そうしないとエラーが発生します",
|
||||
@ -1051,6 +1051,7 @@
|
||||
"copied": "コピーされました",
|
||||
"copy": "コピー",
|
||||
"copy_failed": "コピーに失敗しました",
|
||||
"current": "現在",
|
||||
"cut": "切り取り",
|
||||
"default": "デフォルト",
|
||||
"delete": "削除",
|
||||
|
||||
@ -1051,6 +1051,7 @@
|
||||
"copied": "Copiado",
|
||||
"copy": "Copiar",
|
||||
"copy_failed": "Falha ao copiar",
|
||||
"current": "Atual",
|
||||
"cut": "Cortar",
|
||||
"default": "Padrão",
|
||||
"delete": "Excluir",
|
||||
|
||||
@ -838,7 +838,7 @@
|
||||
"label": "Контекст",
|
||||
"tip": "Количество предыдущих сообщений, которые нужно сохранить в контексте."
|
||||
},
|
||||
"max": "Максимум",
|
||||
"max": "без ограничений",
|
||||
"max_tokens": {
|
||||
"confirm": "Максимальное количество токенов",
|
||||
"confirm_content": "Установить максимальное количество токенов, влияет на длину результата. Нужно учитывать контекст модели, иначе будет ошибка",
|
||||
@ -1051,6 +1051,7 @@
|
||||
"copied": "Скопировано",
|
||||
"copy": "Копировать",
|
||||
"copy_failed": "Не удалось скопировать",
|
||||
"current": "Текущий",
|
||||
"cut": "Вырезать",
|
||||
"default": "По умолчанию",
|
||||
"delete": "Удалить",
|
||||
|
||||
@ -6,7 +6,7 @@ import type { GlobToolInput as GlobToolInputType, GlobToolOutput as GlobToolOutp
|
||||
|
||||
export function GlobTool({ input, output }: { input: GlobToolInputType; output?: GlobToolOutputType }) {
|
||||
// 如果有输出,计算文件数量
|
||||
const fileCount = output ? output.split('\n').filter((line) => line.trim()).length : 0
|
||||
const lineCount = output ? output.split('\n').filter((line) => line.trim()).length : 0
|
||||
|
||||
return (
|
||||
<AccordionItem
|
||||
@ -17,7 +17,7 @@ export function GlobTool({ input, output }: { input: GlobToolInputType; output?:
|
||||
icon={<FolderSearch className="h-4 w-4" />}
|
||||
label="Glob"
|
||||
params={input.pattern}
|
||||
stats={output ? `${fileCount} found` : undefined}
|
||||
stats={output ? `${lineCount} of output` : undefined}
|
||||
/>
|
||||
}>
|
||||
<div>{output}</div>
|
||||
|
||||
@ -8,20 +8,31 @@ import type { ReadToolInput as ReadToolInputType, ReadToolOutput as ReadToolOutp
|
||||
import { AgentToolsType } from './types'
|
||||
|
||||
export function ReadTool({ input, output }: { input: ReadToolInputType; output?: ReadToolOutputType }) {
|
||||
// 移除 system-reminder 标签及其内容的辅助函数
|
||||
const removeSystemReminderTags = (text: string): string => {
|
||||
// 使用正则表达式匹配 <system-reminder> 标签及其内容,包括换行符
|
||||
return text.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/gi, '')
|
||||
}
|
||||
|
||||
// 将 output 统一转换为字符串
|
||||
const outputString = useMemo(() => {
|
||||
if (!output) return null
|
||||
|
||||
let processedOutput: string
|
||||
|
||||
// 如果是 TextOutput[] 类型,提取所有 text 内容
|
||||
if (Array.isArray(output)) {
|
||||
return output
|
||||
processedOutput = output
|
||||
.filter((item): item is TextOutput => item.type === 'text')
|
||||
.map((item) => item.text)
|
||||
.map((item) => removeSystemReminderTags(item.text))
|
||||
.join('')
|
||||
} else {
|
||||
// 如果是字符串,直接使用
|
||||
processedOutput = output
|
||||
}
|
||||
|
||||
// 如果是字符串,直接返回
|
||||
return output
|
||||
// 移除 system-reminder 标签及其内容
|
||||
return removeSystemReminderTags(processedOutput)
|
||||
}, [output])
|
||||
|
||||
// 如果有输出,计算统计信息
|
||||
|
||||
@ -2,11 +2,7 @@ import { AccordionItem, Card, CardBody, Chip } from '@heroui/react'
|
||||
import { CheckCircle, Circle, Clock, ListTodo } from 'lucide-react'
|
||||
|
||||
import { ToolTitle } from './GenericTools'
|
||||
import type {
|
||||
TodoItem,
|
||||
TodoWriteToolInput as TodoWriteToolInputType,
|
||||
TodoWriteToolOutput as TodoWriteToolOutputType
|
||||
} from './types'
|
||||
import type { TodoItem, TodoWriteToolInput as TodoWriteToolInputType } from './types'
|
||||
import { AgentToolsType } from './types'
|
||||
|
||||
const getStatusConfig = (status: TodoItem['status']) => {
|
||||
@ -34,7 +30,7 @@ const getStatusConfig = (status: TodoItem['status']) => {
|
||||
}
|
||||
}
|
||||
|
||||
export function TodoWriteTool({ input, output }: { input: TodoWriteToolInputType; output?: TodoWriteToolOutputType }) {
|
||||
export function TodoWriteTool({ input }: { input: TodoWriteToolInputType }) {
|
||||
const doneCount = input.todos.filter((todo) => todo.status === 'completed').length
|
||||
return (
|
||||
<AccordionItem
|
||||
@ -72,7 +68,6 @@ export function TodoWriteTool({ input, output }: { input: TodoWriteToolInputType
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
{output}
|
||||
</AccordionItem>
|
||||
)
|
||||
}
|
||||
|
||||
@ -2,7 +2,12 @@ import { Button, DescriptionSwitch, HelpTooltip, RowFlex, Selector, type Selecto
|
||||
import { useMultiplePreferences, usePreference } from '@data/hooks/usePreference'
|
||||
import EditableNumber from '@renderer/components/EditableNumber'
|
||||
import Scrollbar from '@renderer/components/Scrollbar'
|
||||
import { DEFAULT_CONTEXTCOUNT, DEFAULT_MAX_TOKENS, DEFAULT_TEMPERATURE } from '@renderer/config/constant'
|
||||
import {
|
||||
DEFAULT_CONTEXTCOUNT,
|
||||
DEFAULT_MAX_TOKENS,
|
||||
DEFAULT_TEMPERATURE,
|
||||
MAX_CONTEXT_COUNT
|
||||
} from '@renderer/config/constant'
|
||||
import { isOpenAIModel } from '@renderer/config/models'
|
||||
import { UNKNOWN } from '@renderer/config/translate'
|
||||
import { useCodeStyle } from '@renderer/context/CodeStyleProvider'
|
||||
@ -214,9 +219,6 @@ const SettingsTab: FC<Props> = (props) => {
|
||||
setStreamOutput(assistant?.settings?.streamOutput ?? true)
|
||||
}, [assistant])
|
||||
|
||||
const assistantContextCount = assistant?.settings?.contextCount || 20
|
||||
const maxContextCount = assistantContextCount > 20 ? assistantContextCount : 20
|
||||
|
||||
const model = assistant.model || getDefaultModel()
|
||||
|
||||
const isOpenAI = isOpenAIModel(model)
|
||||
@ -269,21 +271,44 @@ const SettingsTab: FC<Props> = (props) => {
|
||||
) : (
|
||||
<SettingDivider />
|
||||
)}
|
||||
<Row align="middle">
|
||||
<Row align="middle" gutter={10} justify="space-between">
|
||||
<SettingRowTitleSmall>
|
||||
{t('chat.settings.context_count.label')}
|
||||
<HelpTooltip title={t('chat.settings.context_count.tip')} />
|
||||
</SettingRowTitleSmall>
|
||||
<Col span={8}>
|
||||
<EditableNumber
|
||||
min={0}
|
||||
max={20}
|
||||
step={1}
|
||||
value={contextCount}
|
||||
changeOnBlur
|
||||
onChange={(value) => {
|
||||
if (value !== null && value >= 0 && value <= 20) {
|
||||
setContextCount(value)
|
||||
onContextCountChange(value)
|
||||
}
|
||||
}}
|
||||
formatter={(value) => (value === MAX_CONTEXT_COUNT ? t('chat.settings.max') : (value ?? ''))}
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row align="middle" gutter={10}>
|
||||
<Col span={23}>
|
||||
<Col span={24}>
|
||||
<Slider
|
||||
min={0}
|
||||
max={maxContextCount}
|
||||
max={20}
|
||||
onChange={setContextCount}
|
||||
onChangeComplete={onContextCountChange}
|
||||
value={typeof contextCount === 'number' ? contextCount : 0}
|
||||
value={Math.min(contextCount, 20)}
|
||||
tooltip={{ open: false }}
|
||||
step={1}
|
||||
marks={{
|
||||
0: '0',
|
||||
10: '10',
|
||||
20: '20'
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
@ -360,6 +360,7 @@ const AssistantModelSettings: FC<Props> = ({ assistant, updateAssistant, updateA
|
||||
setTimeoutTimer('contextCount_onChange', () => updateAssistantSettings({ contextCount: value }), 500)
|
||||
}
|
||||
}}
|
||||
formatter={(value) => (value === MAX_CONTEXT_COUNT ? t('chat.settings.max') : (value ?? ''))}
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
</Col>
|
||||
@ -374,7 +375,7 @@ const AssistantModelSettings: FC<Props> = ({ assistant, updateAssistant, updateA
|
||||
value={typeof contextCount === 'number' ? contextCount : 0}
|
||||
marks={{ 0: '0', 25: '25', 50: '50', 75: '75', 100: t('chat.settings.max') }}
|
||||
step={1}
|
||||
tooltip={{ formatter: formatSliderTooltip }}
|
||||
tooltip={{ formatter: formatSliderTooltip, open: false }}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user