Merge branch 'gzy' into 'master'
Gzy See merge request knowledge-base-bj/deerflow-server!114
This commit is contained in:
commit
da56a53a9c
6 files changed
+116
-50
No files matched your search
@@ -7,6 +7,7 @@ import { QueryClientProvider } from "@/components/query-client-provider";
|
|||||||
import { AuthSyncWatcher } from "@/core/auth/sync";
|
import { AuthSyncWatcher } from "@/core/auth/sync";
|
||||||
import { I18nProvider } from "@/core/i18n/context";
|
import { I18nProvider } from "@/core/i18n/context";
|
||||||
import { detectLocale } from "@/core/i18n/locale";
|
import { detectLocale } from "@/core/i18n/locale";
|
||||||
|
import { resolveForcedThemeForPath } from "@/core/page-layout/chats-iframe-route";
|
||||||
import { ChatProvider } from "@/contexts/ChatContext";
|
import { ChatProvider } from "@/contexts/ChatContext";
|
||||||
import { ThemeProvider } from "@/contexts/ThemeContext";
|
import { ThemeProvider } from "@/contexts/ThemeContext";
|
||||||
|
|
||||||
@@ -29,7 +30,7 @@ import { NotFoundPage } from "./pages/NotFoundPage";
|
|||||||
function AppProviders({ children }: { children: React.ReactNode }) {
|
function AppProviders({ children }: { children: React.ReactNode }) {
|
||||||
const locale = useMemo(() => detectLocale(), []);
|
const locale = useMemo(() => detectLocale(), []);
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const forcedTheme = location.pathname === "/landing" ? "light" : undefined;
|
const forcedTheme = resolveForcedThemeForPath(location.pathname);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NextThemesProvider
|
<NextThemesProvider
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import assert from "node:assert/strict";
|
||||||
|
import test from "node:test";
|
||||||
|
|
||||||
|
import {
|
||||||
|
isChatsIframeWorkspacePath,
|
||||||
|
resolveForcedThemeForPath,
|
||||||
|
} from "./chats-iframe-route.ts";
|
||||||
|
|
||||||
|
test("matches only workspace chats_iframe routes", () => {
|
||||||
|
assert.equal(
|
||||||
|
isChatsIframeWorkspacePath("/page/workspace/chats_iframe/new"),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
isChatsIframeWorkspacePath("/page/workspace/chats_iframe/thread-123"),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
assert.equal(isChatsIframeWorkspacePath("/page/workspace/chats/new"), false);
|
||||||
|
assert.equal(isChatsIframeWorkspacePath("/landing"), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("forces light theme for landing and chats_iframe routes only", () => {
|
||||||
|
assert.equal(resolveForcedThemeForPath("/landing"), "light");
|
||||||
|
assert.equal(
|
||||||
|
resolveForcedThemeForPath("/page/workspace/chats_iframe/new"),
|
||||||
|
"light",
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
resolveForcedThemeForPath("/page/workspace/chats_iframe/thread-123"),
|
||||||
|
"light",
|
||||||
|
);
|
||||||
|
assert.equal(resolveForcedThemeForPath("/page/workspace/chats/new"), undefined);
|
||||||
|
});
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
export function isChatsIframeWorkspacePath(pathname: string): boolean {
|
||||||
|
return (
|
||||||
|
pathname === "/page/workspace/chats_iframe/new" ||
|
||||||
|
pathname.startsWith("/page/workspace/chats_iframe/")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resolveForcedThemeForPath(
|
||||||
|
pathname: string,
|
||||||
|
): "light" | undefined {
|
||||||
|
if (pathname === "/landing" || isChatsIframeWorkspacePath(pathname)) {
|
||||||
|
return "light";
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
@@ -3,8 +3,10 @@ import { Navigate, Route, Routes } from "react-router-dom";
|
|||||||
|
|
||||||
import { PageSidebar } from "@/components/page-sidebar";
|
import { PageSidebar } from "@/components/page-sidebar";
|
||||||
import { PageSidebarDark } from "@/components/page-sidebar-dark";
|
import { PageSidebarDark } from "@/components/page-sidebar-dark";
|
||||||
|
import { isChatsIframeWorkspacePath } from "@/core/page-layout/chats-iframe-route";
|
||||||
import { readSidebarEnabled } from "@/core/page-layout/sidebar-enabled";
|
import { readSidebarEnabled } from "@/core/page-layout/sidebar-enabled";
|
||||||
import { useTheme } from "@/contexts/ThemeContext";
|
import { useTheme } from "@/contexts/ThemeContext";
|
||||||
|
import { useLocation } from "react-router-dom";
|
||||||
|
|
||||||
import WorkspaceRoutes from "./WorkspaceRoutes";
|
import WorkspaceRoutes from "./WorkspaceRoutes";
|
||||||
import StrategyRoutes from "./StrategyRoutes";
|
import StrategyRoutes from "./StrategyRoutes";
|
||||||
@@ -16,17 +18,20 @@ import NotebookRoutes from "./NotebookRoutes";
|
|||||||
function PageLayout() {
|
function PageLayout() {
|
||||||
const [collapsed, setCollapsed] = useState(false);
|
const [collapsed, setCollapsed] = useState(false);
|
||||||
const sidebarEnabled = useMemo(() => readSidebarEnabled(), []);
|
const sidebarEnabled = useMemo(() => readSidebarEnabled(), []);
|
||||||
|
const location = useLocation();
|
||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
const isDark = theme === "dark";
|
const isDark = theme === "dark";
|
||||||
|
const pageSidebarAllowed =
|
||||||
|
sidebarEnabled && !isChatsIframeWorkspacePath(location.pathname);
|
||||||
|
|
||||||
// h-full(100%)而非 h-screen(100vh):配合 globals.css 的 html/body/#root height:100%
|
// h-full(100%)而非 h-screen(100vh):配合 globals.css 的 html/body/#root height:100%
|
||||||
// 高度链,根布局跟随容器高度。全屏下 100% 解析到视口,与 h-screen 等价;无界等嵌套
|
// 高度链,根布局跟随容器高度。全屏下 100% 解析到视口,与 h-screen 等价;无界等嵌套
|
||||||
// 下容器不占满整屏时,高度才能正确收缩而非锁死整屏。
|
// 下容器不占满整屏时,高度才能正确收缩而非锁死整屏。
|
||||||
return (
|
return (
|
||||||
<div className="h-full flex flex-col bg-muted/20">
|
<div className="h-full flex flex-col bg-muted/20">
|
||||||
{sidebarEnabled && <Header collapsed={collapsed} />}
|
{pageSidebarAllowed && <Header collapsed={collapsed} />}
|
||||||
<div className="flex flex-1 overflow-hidden">
|
<div className="flex flex-1 overflow-hidden">
|
||||||
{sidebarEnabled && (
|
{pageSidebarAllowed && (
|
||||||
isDark ? (
|
isDark ? (
|
||||||
<PageSidebarDark
|
<PageSidebarDark
|
||||||
collapsed={collapsed}
|
collapsed={collapsed}
|
||||||
@@ -41,7 +46,7 @@ function PageLayout() {
|
|||||||
)}
|
)}
|
||||||
<main
|
<main
|
||||||
className={`flex-1 overflow-hidden ${
|
className={`flex-1 overflow-hidden ${
|
||||||
!sidebarEnabled
|
!pageSidebarAllowed
|
||||||
? ""
|
? ""
|
||||||
: isDark
|
: isDark
|
||||||
// 深色 sidebar:展开 118px(10 + 98 + 10 gap),收起 = 0 sidebar 完全消失,
|
// 深色 sidebar:展开 118px(10 + 98 + 10 gap),收起 = 0 sidebar 完全消失,
|
||||||
@@ -59,9 +64,9 @@ function PageLayout() {
|
|||||||
element={
|
element={
|
||||||
<WorkspaceRoutes
|
<WorkspaceRoutes
|
||||||
pageSidebarCollapsed={collapsed}
|
pageSidebarCollapsed={collapsed}
|
||||||
pageSidebarHidden={!sidebarEnabled}
|
pageSidebarHidden={!pageSidebarAllowed}
|
||||||
headerHidden={!sidebarEnabled}
|
headerHidden={!pageSidebarAllowed}
|
||||||
compactWorkspaceSidebar={sidebarEnabled}
|
compactWorkspaceSidebar={pageSidebarAllowed}
|
||||||
pageSidebarDark={isDark}
|
pageSidebarDark={isDark}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ export function WorkspaceLayout({
|
|||||||
children,
|
children,
|
||||||
pageSidebarCollapsed,
|
pageSidebarCollapsed,
|
||||||
pageSidebarHidden = false,
|
pageSidebarHidden = false,
|
||||||
|
workspaceSidebarHidden = false,
|
||||||
headerHidden = false,
|
headerHidden = false,
|
||||||
compactWorkspaceSidebar = false,
|
compactWorkspaceSidebar = false,
|
||||||
wrapperOverflowHidden = false,
|
wrapperOverflowHidden = false,
|
||||||
@@ -76,6 +77,7 @@ export function WorkspaceLayout({
|
|||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
pageSidebarCollapsed: boolean;
|
pageSidebarCollapsed: boolean;
|
||||||
pageSidebarHidden?: boolean;
|
pageSidebarHidden?: boolean;
|
||||||
|
workspaceSidebarHidden?: boolean;
|
||||||
headerHidden?: boolean;
|
headerHidden?: boolean;
|
||||||
compactWorkspaceSidebar?: boolean;
|
compactWorkspaceSidebar?: boolean;
|
||||||
wrapperOverflowHidden?: boolean;
|
wrapperOverflowHidden?: boolean;
|
||||||
@@ -109,7 +111,9 @@ export function WorkspaceLayout({
|
|||||||
data-page-sidebar-collapsed={pageSidebarCollapsed}
|
data-page-sidebar-collapsed={pageSidebarCollapsed}
|
||||||
defaultOpen
|
defaultOpen
|
||||||
>
|
>
|
||||||
<WorkspaceSidebar compactChrome={compactWorkspaceSidebar} />
|
{!workspaceSidebarHidden && (
|
||||||
|
<WorkspaceSidebar compactChrome={compactWorkspaceSidebar} />
|
||||||
|
)}
|
||||||
<SidebarInset
|
<SidebarInset
|
||||||
className={cn('min-w-0', insetOverflowHidden && 'overflow-hidden')}
|
className={cn('min-w-0', insetOverflowHidden && 'overflow-hidden')}
|
||||||
>
|
>
|
||||||
@@ -205,7 +209,11 @@ export default function WorkspaceRoutes({
|
|||||||
<Route
|
<Route
|
||||||
path="chats_iframe/new"
|
path="chats_iframe/new"
|
||||||
element={
|
element={
|
||||||
<WorkspaceLayout {...layoutProps}>
|
<WorkspaceLayout
|
||||||
|
{...layoutProps}
|
||||||
|
pageSidebarHidden
|
||||||
|
workspaceSidebarHidden
|
||||||
|
>
|
||||||
<ChatRuntime>
|
<ChatRuntime>
|
||||||
<IframeChatPage />
|
<IframeChatPage />
|
||||||
</ChatRuntime>
|
</ChatRuntime>
|
||||||
@@ -217,6 +225,8 @@ export default function WorkspaceRoutes({
|
|||||||
element={
|
element={
|
||||||
<WorkspaceLayout
|
<WorkspaceLayout
|
||||||
{...layoutProps}
|
{...layoutProps}
|
||||||
|
pageSidebarHidden
|
||||||
|
workspaceSidebarHidden
|
||||||
wrapperOverflowHidden
|
wrapperOverflowHidden
|
||||||
insetOverflowHidden
|
insetOverflowHidden
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ models:
|
|||||||
# supports_vision: true
|
# supports_vision: true
|
||||||
# supports_thinking: true
|
# supports_thinking: true
|
||||||
|
|
||||||
|
|
||||||
# - name: deepseek-v4-flash
|
# - name: deepseek-v4-flash
|
||||||
# display_name: DeepSeek V4 Flash
|
# display_name: DeepSeek V4 Flash
|
||||||
# use: langchain_openai:ChatOpenAI
|
# use: langchain_openai:ChatOpenAI
|
||||||
@@ -118,7 +117,7 @@ models:
|
|||||||
display_name: deepseek-ai/DeepSeek-V4-Flash
|
display_name: deepseek-ai/DeepSeek-V4-Flash
|
||||||
use: langchain_openai:ChatOpenAI
|
use: langchain_openai:ChatOpenAI
|
||||||
model: deepseek-ai/DeepSeek-V4-Flash
|
model: deepseek-ai/DeepSeek-V4-Flash
|
||||||
api_key: sk-ighylafootabtuthwueirmoycccyqtdgbifyhozduvolkdyt
|
api_key: sk-ighylafootabtuthwueirmoycccyqtdgbifyhozduvolkdyt
|
||||||
base_url: https://api.siliconflow.cn/v1/
|
base_url: https://api.siliconflow.cn/v1/
|
||||||
max_tokens: 4096
|
max_tokens: 4096
|
||||||
temperature: 1.0
|
temperature: 1.0
|
||||||
@@ -128,7 +127,7 @@ models:
|
|||||||
display_name: Pro/MiniMaxAI/MiniMax-M2.5
|
display_name: Pro/MiniMaxAI/MiniMax-M2.5
|
||||||
use: langchain_openai:ChatOpenAI
|
use: langchain_openai:ChatOpenAI
|
||||||
model: Pro/MiniMaxAI/MiniMax-M2.5
|
model: Pro/MiniMaxAI/MiniMax-M2.5
|
||||||
api_key: sk-ighylafootabtuthwueirmoycccyqtdgbifyhozduvolkdyt
|
api_key: sk-ighylafootabtuthwueirmoycccyqtdgbifyhozduvolkdyt
|
||||||
base_url: https://api.siliconflow.cn/v1/
|
base_url: https://api.siliconflow.cn/v1/
|
||||||
max_tokens: 4096
|
max_tokens: 4096
|
||||||
temperature: 1.0
|
temperature: 1.0
|
||||||
@@ -138,7 +137,7 @@ models:
|
|||||||
display_name: inclusionAI/Ling-flash-2.0
|
display_name: inclusionAI/Ling-flash-2.0
|
||||||
use: langchain_openai:ChatOpenAI
|
use: langchain_openai:ChatOpenAI
|
||||||
model: inclusionAI/Ling-flash-2.0
|
model: inclusionAI/Ling-flash-2.0
|
||||||
api_key: sk-ighylafootabtuthwueirmoycccyqtdgbifyhozduvolkdyt
|
api_key: sk-ighylafootabtuthwueirmoycccyqtdgbifyhozduvolkdyt
|
||||||
base_url: https://api.siliconflow.cn/v1/
|
base_url: https://api.siliconflow.cn/v1/
|
||||||
max_tokens: 4096
|
max_tokens: 4096
|
||||||
temperature: 1.0
|
temperature: 1.0
|
||||||
@@ -148,7 +147,7 @@ models:
|
|||||||
display_name: deepseek-ai/DeepSeek-V4-Pro
|
display_name: deepseek-ai/DeepSeek-V4-Pro
|
||||||
use: langchain_openai:ChatOpenAI
|
use: langchain_openai:ChatOpenAI
|
||||||
model: deepseek-ai/DeepSeek-V4-Pro
|
model: deepseek-ai/DeepSeek-V4-Pro
|
||||||
api_key: sk-ighylafootabtuthwueirmoycccyqtdgbifyhozduvolkdyt
|
api_key: sk-ighylafootabtuthwueirmoycccyqtdgbifyhozduvolkdyt
|
||||||
base_url: https://api.siliconflow.cn/v1/
|
base_url: https://api.siliconflow.cn/v1/
|
||||||
max_tokens: 4096
|
max_tokens: 4096
|
||||||
temperature: 1.0
|
temperature: 1.0
|
||||||
@@ -254,14 +253,14 @@ skills:
|
|||||||
skill_evolution:
|
skill_evolution:
|
||||||
enabled: true
|
enabled: true
|
||||||
curator:
|
curator:
|
||||||
enabled: true # 每 24 小时自动清理 + 合并 skill
|
enabled: true # 每 24 小时自动清理 + 合并 skill
|
||||||
interval_hours: 24
|
interval_hours: 24
|
||||||
review_worker:
|
review_worker:
|
||||||
enabled: true # 被动复盘开关
|
enabled: true # 被动复盘开关
|
||||||
min_tool_calls: 5 # 触发阈值:本轮至少 5 次工具调用,与 prompt 中"≥5 步"硬条件一致
|
min_tool_calls: 5 # 触发阈值:本轮至少 5 次工具调用,与 prompt 中"≥5 步"硬条件一致
|
||||||
max_messages: 60 # 传给 LLM 的最大消息条数
|
max_messages: 60 # 传给 LLM 的最大消息条数
|
||||||
timeout_seconds: 120 # 单次 review 超时(秒)
|
timeout_seconds: 120 # 单次 review 超时(秒)
|
||||||
model_name: # 留空则使用主模型
|
model_name: # 留空则使用主模型
|
||||||
|
|
||||||
agents_api:
|
agents_api:
|
||||||
enabled: true
|
enabled: true
|
||||||
@@ -272,31 +271,30 @@ auth_login:
|
|||||||
# 口令不对直接 401。password 留空则默认口令为 123ewq。仅作用于用户名直登。
|
# 口令不对直接 401。password 留空则默认口令为 123ewq。仅作用于用户名直登。
|
||||||
username_login:
|
username_login:
|
||||||
require_password: false
|
require_password: false
|
||||||
password: ""
|
password: ''
|
||||||
# token 换登录:前端用 ?authToken=上游token 进入,后端调用 token_info_url
|
# token 换登录:前端用 ?authToken=上游token 进入,后端调用 token_info_url
|
||||||
# (把该 token 直接拼成 Authorization: Bearer <token> 头)换出用户名,再登录;
|
# (把该 token 直接拼成 Authorization: Bearer <token> 头)换出用户名,再登录;
|
||||||
# 用户名不在库里时自动注册。
|
# 用户名不在库里时自动注册。
|
||||||
token_login:
|
token_login:
|
||||||
enabled: false
|
enabled: false
|
||||||
token_info_url: "https://ch1.b.uat.4.cn/consumer/login/getTokenInfo"
|
token_info_url: 'https://ch1.b.uat.4.cn/consumer/login/getTokenInfo'
|
||||||
# 已弃用:鉴权头现由前端传入的 token 拼成 "Bearer <token>",此项不再生效,保留仅兼容。
|
# 已弃用:鉴权头现由前端传入的 token 拼成 "Bearer <token>",此项不再生效,保留仅兼容。
|
||||||
service_authorization: "Bearer admin"
|
service_authorization: 'Bearer admin'
|
||||||
timeout_seconds: 10
|
timeout_seconds: 10
|
||||||
# 上游是 HTTPS。UAT/内网常用自签或私有 CA 证书,默认 verify=true 会握手失败导致
|
# 上游是 HTTPS。UAT/内网常用自签或私有 CA 证书,默认 verify=true 会握手失败导致
|
||||||
# 永远 401。此处 uat 域名按自签处理,先关校验;生产请置 true 或配 ca_cert_path。
|
# 永远 401。此处 uat 域名按自签处理,先关校验;生产请置 true 或配 ca_cert_path。
|
||||||
verify_ssl: false
|
verify_ssl: false
|
||||||
ca_cert_path: "" # 可选:PEM 格式 CA 包路径,设置后优先生效并启用校验
|
ca_cert_path: '' # 可选:PEM 格式 CA 包路径,设置后优先生效并启用校验
|
||||||
|
|
||||||
# 日志系统入口(仅管理员可见):右下角「设置」菜单中会多出一个「日志系统」入口,
|
# 日志系统入口(仅管理员可见):右下角「设置」菜单中会多出一个「日志系统」入口,
|
||||||
# 点击后在新标签页打开下面的 url。enabled 关掉则不显示该入口。
|
# 点击后在新标签页打开下面的 url。enabled 关掉则不显示该入口。
|
||||||
|
|
||||||
|
|
||||||
database:
|
database:
|
||||||
backend: sqlite
|
backend: sqlite
|
||||||
sqlite_dir: .deer-flow/data
|
sqlite_dir: .deer-flow/data
|
||||||
pool_size: 20 # 基础连接池(postgres/mysql 生效;sqlite 忽略)
|
pool_size: 20 # 基础连接池(postgres/mysql 生效;sqlite 忽略)
|
||||||
max_overflow: 20 # 高峰期可临时超出 pool_size 的额外连接数,真实上限 = pool_size + max_overflow
|
max_overflow: 20 # 高峰期可临时超出 pool_size 的额外连接数,真实上限 = pool_size + max_overflow
|
||||||
pool_timeout: 30 # 池满时等待空闲连接的秒数,超时报错
|
pool_timeout: 30 # 池满时等待空闲连接的秒数,超时报错
|
||||||
echo_sql: false
|
echo_sql: false
|
||||||
|
|
||||||
checkpointer:
|
checkpointer:
|
||||||
@@ -308,35 +306,38 @@ checkpointer:
|
|||||||
# users/{user_id}/memory_config.json > .deer-flow/memory_user_overrides.json > 此处
|
# users/{user_id}/memory_config.json > .deer-flow/memory_user_overrides.json > 此处
|
||||||
memory:
|
memory:
|
||||||
enabled: true
|
enabled: true
|
||||||
version: v1 # 记忆版本: 'v1'(原版 DeerFlow, memory.json + LLM 自动提取)
|
version:
|
||||||
# 'v2'(USER.md/MEMORY.md + 可选 Hindsight)
|
v1 # 记忆版本: 'v1'(原版 DeerFlow, memory.json + LLM 自动提取)
|
||||||
provider: hindsight # 'builtin' | 'hindsight'(外部 provider 名)
|
# 'v2'(USER.md/MEMORY.md + 可选 Hindsight)
|
||||||
# builtin 始终启用,这里只决定 external 选哪个
|
provider:
|
||||||
# (version=v1 时此字段忽略)
|
hindsight # 'builtin' | 'hindsight'(外部 provider 名)
|
||||||
|
# builtin 始终启用,这里只决定 external 选哪个
|
||||||
|
# (version=v1 时此字段忽略)
|
||||||
|
|
||||||
# V1 专属配置 —— version=v1 时生效
|
# V1 专属配置 —— version=v1 时生效
|
||||||
v1:
|
v1:
|
||||||
max_facts: 100 # 最多保留的事实条数,超出时驱逐最低置信度的事实
|
max_facts: 100 # 最多保留的事实条数,超出时驱逐最低置信度的事实
|
||||||
fact_confidence_threshold: 0.7 # 事实置信度阈值,低于此值不保存
|
fact_confidence_threshold: 0.7 # 事实置信度阈值,低于此值不保存
|
||||||
debounce_seconds: 30 # 对话结束后延迟多少秒才触发 LLM 提取
|
debounce_seconds: 30 # 对话结束后延迟多少秒才触发 LLM 提取
|
||||||
model_name: "" # 用于事实提取的 LLM 模型名;空则继承全局默认模型
|
model_name: '' # 用于事实提取的 LLM 模型名;空则继承全局默认模型
|
||||||
token_budget: 2000 # 注入系统提示词的 token 预算
|
token_budget: 2000 # 注入系统提示词的 token 预算
|
||||||
builtin:
|
builtin:
|
||||||
enabled: true
|
enabled: true
|
||||||
memory_char_limit: 2200
|
memory_char_limit: 2200
|
||||||
user_char_limit: 1375
|
user_char_limit: 1375
|
||||||
deduplicate_on_load: true
|
deduplicate_on_load: true
|
||||||
|
|
||||||
hindsight: # provider=hindsight 时生效,需另行部署 Hindsight 服务
|
hindsight: # provider=hindsight 时生效,需另行部署 Hindsight 服务
|
||||||
mode: local_external # 'cloud' | 'local_embedded' | 'local_external'
|
mode: local_external # 'cloud' | 'local_embedded' | 'local_external'
|
||||||
api_url: http://47.88.25.99:18888
|
api_url: http://47.88.25.99:18888
|
||||||
api_key: "" # 部署 Hindsight 后填,或改成 $HINDSIGHT_API_KEY 并设同名环境变量
|
api_key:
|
||||||
# 注意:写成 $VAR 但环境变量未设置会导致配置加载失败
|
'' # 部署 Hindsight 后填,或改成 $HINDSIGHT_API_KEY 并设同名环境变量
|
||||||
bank_id_template: "deerflow-user-{user_id}"
|
# 注意:写成 $VAR 但环境变量未设置会导致配置加载失败
|
||||||
work_bank_id_template: "deerflow-work-{user_id}-{agent_id}"
|
bank_id_template: 'deerflow-user-{user_id}'
|
||||||
|
work_bank_id_template: 'deerflow-work-{user_id}-{agent_id}'
|
||||||
memory_mode: context # 'context' | 'tools' | 'hybrid'
|
memory_mode: context # 'context' | 'tools' | 'hybrid'
|
||||||
bank_mission: "你是一个中文记忆助手,负责从对话中提炼和存储重要信息。所有记忆内容必须使用中文记录。"
|
bank_mission: '你是一个中文记忆助手,负责从对话中提炼和存储重要信息。所有记忆内容必须使用中文记录。'
|
||||||
bank_retain_mission: "请从以下对话中提炼重要信息,包括用户的偏好、需求、背景知识和关键事实。所有提炼的内容必须用中文表达。"
|
bank_retain_mission: '请从以下对话中提炼重要信息,包括用户的偏好、需求、背景知识和关键事实。所有提炼的内容必须用中文表达。'
|
||||||
recall_budget: mid # 'low' | 'mid' | 'high'
|
recall_budget: mid # 'low' | 'mid' | 'high'
|
||||||
recall_max_tokens: 4096
|
recall_max_tokens: 4096
|
||||||
recall_max_input_chars: 800
|
recall_max_input_chars: 800
|
||||||
@@ -344,8 +345,8 @@ memory:
|
|||||||
auto_retain: true
|
auto_retain: true
|
||||||
retain_async: true
|
retain_async: true
|
||||||
retain_every_n_turns: 1
|
retain_every_n_turns: 1
|
||||||
retain_user_prefix: "User"
|
retain_user_prefix: 'User'
|
||||||
retain_assistant_prefix: "Assistant"
|
retain_assistant_prefix: 'Assistant'
|
||||||
|
|
||||||
# background_extraction:预留功能,代码尚未实现 —— 仅设计文档存在。
|
# background_extraction:预留功能,代码尚未实现 —— 仅设计文档存在。
|
||||||
# 待对应版本支持后,取消下面整段注释即可启用(漏记兜底)。
|
# 待对应版本支持后,取消下面整段注释即可启用(漏记兜底)。
|
||||||
@@ -363,7 +364,7 @@ memory:
|
|||||||
max_tokens: 2000
|
max_tokens: 2000
|
||||||
include_builtin: true
|
include_builtin: true
|
||||||
include_hindsight: true
|
include_hindsight: true
|
||||||
context_tag: "memory-context" # 包裹 Hindsight recall 的标签名
|
context_tag: 'memory-context' # 包裹 Hindsight recall 的标签名
|
||||||
|
|
||||||
security:
|
security:
|
||||||
scan_content: true # 注入/外渗模式扫描
|
scan_content: true # 注入/外渗模式扫描
|
||||||
@@ -381,5 +382,5 @@ ai_writing:
|
|||||||
|
|
||||||
log_system:
|
log_system:
|
||||||
enabled: true
|
enabled: true
|
||||||
url: "https://your-log-system.example.com"
|
url: 'https://your-log-system.example.com'
|
||||||
label: "日志系统"
|
label: '日志系统'
|
||||||
Reference in new issue
Block a user