mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-07-22 14:08:28 +00:00
fix: preserve locale in documentation links (#3717)
This commit is contained in:
parent
90fdda77e8
commit
0ee35ca38f
13
frontend/src/components/docs/localized-cards.tsx
Normal file
13
frontend/src/components/docs/localized-cards.tsx
Normal file
@ -0,0 +1,13 @@
|
||||
import { Cards as NextraCards } from "nextra/components";
|
||||
import type { ComponentProps } from "react";
|
||||
|
||||
import { LocalizedCard } from "./localized-mdx-components";
|
||||
|
||||
function LocalizedCardsRoot(props: ComponentProps<typeof NextraCards>) {
|
||||
return <NextraCards {...props} />;
|
||||
}
|
||||
|
||||
export const LocalizedCards = Object.assign(LocalizedCardsRoot, {
|
||||
Card: LocalizedCard,
|
||||
displayName: "LocalizedCards",
|
||||
});
|
||||
15
frontend/src/components/docs/localized-links.ts
Normal file
15
frontend/src/components/docs/localized-links.ts
Normal file
@ -0,0 +1,15 @@
|
||||
const SUPPORTED_DOC_LANGUAGES = new Set(["en", "zh"]);
|
||||
const UNLOCALIZED_DOCS_PATH = /^\/docs(?=\/|[?#]|$)/;
|
||||
|
||||
export function localizeDocsHref(
|
||||
href: string,
|
||||
lang: string | undefined,
|
||||
): string {
|
||||
if (!lang || !SUPPORTED_DOC_LANGUAGES.has(lang)) {
|
||||
return href;
|
||||
}
|
||||
if (!UNLOCALIZED_DOCS_PATH.test(href)) {
|
||||
return href;
|
||||
}
|
||||
return `/${lang}${href}`;
|
||||
}
|
||||
43
frontend/src/components/docs/localized-mdx-components.tsx
Normal file
43
frontend/src/components/docs/localized-mdx-components.tsx
Normal file
@ -0,0 +1,43 @@
|
||||
"use client";
|
||||
|
||||
import { useParams } from "next/navigation";
|
||||
import { Anchor, Cards as NextraCards } from "nextra/components";
|
||||
import type { ComponentProps } from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
import { localizeDocsHref } from "./localized-links";
|
||||
|
||||
const DOCS_LINK_CLASS_NAME =
|
||||
"x:text-primary-600 x:underline x:hover:no-underline x:decoration-from-font x:[text-underline-position:from-font]";
|
||||
|
||||
function useDocumentLanguage(): string | undefined {
|
||||
const { lang } = useParams<{ lang?: string }>();
|
||||
return lang;
|
||||
}
|
||||
|
||||
export function LocalizedDocsLink({
|
||||
href,
|
||||
className,
|
||||
...props
|
||||
}: ComponentProps<typeof Anchor>) {
|
||||
const lang = useDocumentLanguage();
|
||||
const localizedHref =
|
||||
typeof href === "string" ? localizeDocsHref(href, lang) : href;
|
||||
|
||||
return (
|
||||
<Anchor
|
||||
{...props}
|
||||
className={cn(DOCS_LINK_CLASS_NAME, className)}
|
||||
href={localizedHref}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function LocalizedCard({
|
||||
href,
|
||||
...props
|
||||
}: ComponentProps<typeof NextraCards.Card>) {
|
||||
const lang = useDocumentLanguage();
|
||||
return <NextraCards.Card {...props} href={localizeDocsHref(href, lang)} />;
|
||||
}
|
||||
@ -3,7 +3,7 @@ title: Agents and Threads
|
||||
description: DeerFlow App supports multiple named agents and maintains conversation state across sessions through threads and checkpointing.
|
||||
---
|
||||
|
||||
import { Callout, Cards, Steps } from "nextra/components";
|
||||
import { Callout, Steps } from "nextra/components";
|
||||
|
||||
# Agents and Threads
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Configuration
|
||||
description: DeerFlow App is configured through two files and a set of environment variables. This page covers the application-level configuration that most operators need to set up before deploying.
|
||||
---
|
||||
|
||||
import { Callout, Cards, Tabs } from "nextra/components";
|
||||
import { Callout, Tabs } from "nextra/components";
|
||||
|
||||
# Configuration
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Deployment Guide
|
||||
description: "This guide covers all supported deployment methods for DeerFlow App: local development, Docker Compose, and production with Kubernetes-managed sandboxes."
|
||||
---
|
||||
|
||||
import { Callout, Cards, Steps, Tabs } from "nextra/components";
|
||||
import { Callout, Steps, Tabs } from "nextra/components";
|
||||
|
||||
# Deployment Guide
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: DeerFlow App
|
||||
description: DeerFlow App is the reference implementation of what a production DeerFlow experience looks like. It assembles the Harness runtime, a web-based conversation workspace, an API gateway, and a reverse proxy into a single deployable system.
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# DeerFlow App
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Operations and Troubleshooting
|
||||
description: This page covers day-to-day operational tasks and solutions to common problems when running DeerFlow App.
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# Operations and Troubleshooting
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Quick Start
|
||||
description: This guide walks you through starting DeerFlow App on your local machine using the `make dev` workflow. Gateway, Frontend, and nginx start together and are accessible through a single URL.
|
||||
---
|
||||
|
||||
import { Callout, Cards, Steps } from "nextra/components";
|
||||
import { Callout, Steps } from "nextra/components";
|
||||
|
||||
# Quick Start
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Workspace Usage
|
||||
description: The DeerFlow App workspace is a browser-based interface for having multi-turn conversations with the agent, tracking task progress, viewing artifacts, and managing files.
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# Workspace Usage
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Configuration
|
||||
description: "DeerFlow's configuration system is designed around one goal: every meaningful behavior should be expressible in a config file, not hardcoded in the application. This makes deployments reproducible, auditable, and easy to customize per environment."
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# Configuration
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Customization
|
||||
description: DeerFlow's pluggable architecture means most parts of the system can be replaced or extended without forking the core. This page maps the extension points and explains how to use each one.
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# Customization
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Design Principles
|
||||
description: Understanding the design principles behind DeerFlow Harness helps you use it effectively, extend it confidently, and reason about how your agents will behave in production.
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# Design Principles
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Install DeerFlow Harness
|
||||
description: The DeerFlow Harness is the Python SDK and runtime foundation for building your own Super Agent systems.
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# Install DeerFlow Harness
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Integration Guide
|
||||
description: DeerFlow Harness is not only a standalone application. It is a Python library you can import and use inside your own backend, API server, automation system, or multi-agent orchestrator.
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# Integration Guide
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Lead Agent
|
||||
description: The Lead Agent is the central executor in a DeerFlow thread. Every conversation, task, and workflow flows through it. Understanding how it works helps you configure it effectively and extend it when needed.
|
||||
---
|
||||
|
||||
import { Callout, Cards, Steps } from "nextra/components";
|
||||
import { Callout, Steps } from "nextra/components";
|
||||
|
||||
# Lead Agent
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: MCP Integration
|
||||
description: The **Model Context Protocol (MCP)** is an open standard for connecting language models to external tools and data sources. DeerFlow's MCP integration allows you to extend the agent with any tool server that implements the MCP protocol — without modifying the harness itself.
|
||||
---
|
||||
|
||||
import { Callout, Cards, Steps } from "nextra/components";
|
||||
import { Callout, Steps } from "nextra/components";
|
||||
|
||||
# MCP Integration
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Memory
|
||||
description: Memory is a runtime feature of the DeerFlow Harness. It is not a simple conversation log — it is a structured store of facts and context summaries that persist across separate sessions and inform the agent's behavior in future conversations.
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# Memory
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Quick Start
|
||||
description: Learn how to create and run a DeerFlow agent with create_deerflow_agent, from model setup to streaming responses.
|
||||
---
|
||||
|
||||
import { Callout, Cards, Steps } from "nextra/components";
|
||||
import { Callout, Steps } from "nextra/components";
|
||||
|
||||
# Quick Start
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Sandbox
|
||||
description: The sandbox gives the Lead Agent a controlled environment where it can read files, write outputs, run shell commands, and produce artifacts. Without a sandbox, the agent can only generate text. With a sandbox, it can write and execute code, process data files, generate charts, and build deliverables.
|
||||
---
|
||||
|
||||
import { Callout, Cards, Tabs } from "nextra/components";
|
||||
import { Callout, Tabs } from "nextra/components";
|
||||
|
||||
# Sandbox
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Skills
|
||||
description: A skill is more than a prompt. It is a self-contained capability package that can include structured instructions, step-by-step workflows, domain-specific best practices, supporting resources, and tool configurations. Skills are loaded on demand — they inject their content when a task calls for them and stay out of the context otherwise.
|
||||
---
|
||||
|
||||
import { Callout, Cards, FileTree, Steps } from "nextra/components";
|
||||
import { Callout, FileTree, Steps } from "nextra/components";
|
||||
|
||||
# Skills
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Subagents
|
||||
description: When a task is too broad for a single reasoning thread, or when parts of it can be done in parallel, the Lead Agent delegates work to **subagents**. A subagent is a self-contained agent invocation that receives a specific task, executes it, and returns the result.
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# Subagents
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Tools
|
||||
description: "The Lead Agent is a tool-calling agent. Tools are how it interacts with the world: searching the web, reading and writing files, running commands, delegating tasks, and presenting outputs to the user."
|
||||
---
|
||||
|
||||
import { Callout, Cards, Tabs } from "nextra/components";
|
||||
import { Callout, Tabs } from "nextra/components";
|
||||
|
||||
# Tools
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Core Concepts
|
||||
description: Before you go deeper into DeerFlow, it helps to anchor on a few concepts that appear throughout the system. These concepts explain what DeerFlow is optimizing for and why its architecture looks the way it does.
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# Core Concepts
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Harness vs App
|
||||
description: "DeerFlow has two layers that are closely related but serve different purposes."
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# Harness vs App
|
||||
|
||||
|
||||
@ -3,7 +3,6 @@ title: Introduction
|
||||
description: DeerFlow is a runtime harness for building long-horizon agent systems with skills, memory, tools, and sandboxed execution.
|
||||
---
|
||||
|
||||
import { Cards } from "nextra/components";
|
||||
|
||||
# Introduction
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Why DeerFlow
|
||||
description: DeerFlow exists because modern agent systems need more than a chat loop. A useful agent must plan over long horizons, break work into sub-tasks, use tools, manipulate files, run code safely, and preserve enough context to stay coherent across a complex task. DeerFlow was built to provide that runtime foundation.
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# Why DeerFlow
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Agent 与线程
|
||||
description: 了解 DeerFlow 中 Agent 与线程的关系,以及如何管理自定义 Agent 和对话线程。
|
||||
---
|
||||
|
||||
import { Callout, Cards, Steps } from "nextra/components";
|
||||
import { Callout, Steps } from "nextra/components";
|
||||
|
||||
# Agent 与线程
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: 配置
|
||||
description: 本页面涵盖 DeerFlow 应用的所有配置层——`config.yaml`、前端环境变量、`extensions_config.json` 和运行时环境变量。
|
||||
---
|
||||
|
||||
import { Callout, Cards, Tabs } from "nextra/components";
|
||||
import { Callout, Tabs } from "nextra/components";
|
||||
|
||||
# 配置
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: 部署指南
|
||||
description: 本指南涵盖 DeerFlow 应用所有支持的部署方式:本地开发、Docker Compose 以及使用 Kubernetes 管理沙箱的生产环境。
|
||||
---
|
||||
|
||||
import { Callout, Cards, Steps, Tabs } from "nextra/components";
|
||||
import { Callout, Steps, Tabs } from "nextra/components";
|
||||
|
||||
# 部署指南
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: DeerFlow 应用
|
||||
description: DeerFlow 应用是 DeerFlow 生产体验的参考实现。它将 Harness 运行时、基于 Web 的对话工作区、API Gateway 和反向代理组合成一个可部署的完整系统。
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# DeerFlow 应用
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: 运维与排障
|
||||
description: 本页面涵盖运行 DeerFlow 应用的操作信息:日志记录、常见问题和维护任务。
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# 运维与排障
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: 快速上手
|
||||
description: 本指南引导你使用 `make dev` 工作流在本地机器上启动 DeerFlow 应用。Gateway、前端和 nginx 会一起启动,通过单个 URL 访问。
|
||||
---
|
||||
|
||||
import { Callout, Cards, Steps } from "nextra/components";
|
||||
import { Callout, Steps } from "nextra/components";
|
||||
|
||||
# 快速上手
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: 工作区使用
|
||||
description: DeerFlow 工作区是一个基于浏览器的对话界面,你可以在其中向 Agent 发送消息、上传文件、查看中间步骤,以及下载生成的产出物。
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# 工作区使用
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: 配置
|
||||
description: DeerFlow 的配置系统围绕一个目标设计:每一个有意义的行为都应该可以在配置文件中表达,而不是硬编码在应用程序中。这使部署可重现、可审计,并且易于按环境定制。
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# 配置
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: 自定义与扩展
|
||||
description: DeerFlow 的可插拔架构意味着系统的大多数部分都可以在不 fork 核心的情况下被替换或扩展。本页面列举了扩展点,并解释如何使用每一个。
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# 自定义与扩展
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: 设计理念
|
||||
description: 了解 DeerFlow Harness 背后的设计理念,有助于你有效地使用它、自信地扩展它,并推断 Agent 在生产环境中的行为方式。
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# 设计理念
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: 安装 DeerFlow Harness
|
||||
description: DeerFlow Harness 是构建自己 Super Agent 系统的 Python SDK 和运行时基础。
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# 安装 DeerFlow Harness
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: 集成指南
|
||||
description: DeerFlow Harness 不仅仅是一个独立应用程序——它是一个可以导入并在你自己的后端、API 服务器、自动化系统或多 Agent 协调器中使用的 Python 库。
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# 集成指南
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Lead Agent
|
||||
description: Lead Agent 是 DeerFlow 线程中的核心执行者。每个对话、任务和工作流都通过它进行。理解它的工作方式有助于你有效地配置它,并在需要时扩展它。
|
||||
---
|
||||
|
||||
import { Callout, Cards, Steps } from "nextra/components";
|
||||
import { Callout, Steps } from "nextra/components";
|
||||
|
||||
# Lead Agent
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: MCP 集成
|
||||
description: Model Context Protocol(MCP) 是连接语言模型与外部工具和数据源的开放标准。DeerFlow 的 MCP 集成允许你用任何实现了 MCP 协议的工具服务器扩展 Agent——无需修改 Harness 本身。
|
||||
---
|
||||
|
||||
import { Callout, Cards, Steps } from "nextra/components";
|
||||
import { Callout, Steps } from "nextra/components";
|
||||
|
||||
# MCP 集成
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: 记忆系统
|
||||
description: 记忆是 DeerFlow Harness 的一个运行时功能。它不是简单的对话日志,而是跨多个独立会话持久化、在未来对话中影响 Agent 行为的结构化事实和上下文摘要存储。
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# 记忆系统
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: 快速上手
|
||||
description: 学习如何使用 create_deerflow_agent 创建并运行 DeerFlow Agent,从模型初始化到流式响应。
|
||||
---
|
||||
|
||||
import { Callout, Cards, Steps } from "nextra/components";
|
||||
import { Callout, Steps } from "nextra/components";
|
||||
|
||||
# 快速上手
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: 沙箱
|
||||
description: 沙箱为 Lead Agent 提供一个受控环境,在其中可以读取文件、写入输出、运行 Shell 命令并生成产出物。没有沙箱,Agent 只能生成文本;有了沙箱,它可以编写和执行代码、处理数据文件、生成图表并构建交付物。
|
||||
---
|
||||
|
||||
import { Callout, Cards, Tabs } from "nextra/components";
|
||||
import { Callout, Tabs } from "nextra/components";
|
||||
|
||||
# 沙箱
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: 技能
|
||||
description: 技能不仅仅是提示词。它是一个自包含的能力包,可以包含结构化指令、分步工作流、领域最佳实践、支撑资源和工具配置。技能按需加载——在任务需要时注入内容,否则不影响上下文。
|
||||
---
|
||||
|
||||
import { Callout, Cards, FileTree, Steps } from "nextra/components";
|
||||
import { Callout, FileTree, Steps } from "nextra/components";
|
||||
|
||||
# 技能
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: 子 Agent
|
||||
description: 当一个任务对单个推理线程来说太宽泛,或者部分任务可以并行完成时,Lead Agent 将工作委派给**子 Agent**。子 Agent 是一个独立的 Agent 调用,接收特定任务、执行并返回结果。
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# 子 Agent
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: 工具
|
||||
description: Lead Agent 是一个工具调用 Agent。工具是它与世界交互的方式:搜索网络、读写文件、运行命令、委派任务以及向用户呈现输出。
|
||||
---
|
||||
|
||||
import { Callout, Cards, Tabs } from "nextra/components";
|
||||
import { Callout, Tabs } from "nextra/components";
|
||||
|
||||
# 工具
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: 核心概念
|
||||
description: 在深入了解 DeerFlow 之前,先建立一些贯穿整个系统的核心概念。这些概念解释了 DeerFlow 的优化目标以及其架构设计的原因。
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# 核心概念
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: Harness 与应用
|
||||
description: DeerFlow 有两个紧密相关但服务于不同目的的层次:.
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# Harness 与应用
|
||||
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
title: 简介
|
||||
description: DeerFlow 是一个运行时 Harness,用于构建支持技能、记忆、工具和沙箱执行的长时序 Agent 系统。
|
||||
---
|
||||
import { Cards } from "nextra/components";
|
||||
|
||||
# 简介
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ title: 为什么选择 DeerFlow
|
||||
description: DeerFlow 的诞生是因为现代 Agent 系统需要的不仅仅是一个聊天循环。一个真正有用的 Agent 必须能够进行长时序规划、将任务拆解为子任务、使用工具、操作文件、安全地运行代码,并在复杂任务中保持足够的上下文连贯性。DeerFlow 正是为提供这样的运行时基础而构建的。
|
||||
---
|
||||
|
||||
import { Callout, Cards } from "nextra/components";
|
||||
import { Callout } from "nextra/components";
|
||||
|
||||
# 为什么选择 DeerFlow
|
||||
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
import { useMDXComponents as getThemeComponents } from "nextra-theme-docs"; // nextra-theme-blog or your custom theme
|
||||
|
||||
import { LocalizedCards } from "@/components/docs/localized-cards";
|
||||
import { LocalizedDocsLink } from "@/components/docs/localized-mdx-components";
|
||||
|
||||
// Get the default MDX components
|
||||
const themeComponents = getThemeComponents();
|
||||
|
||||
@ -7,5 +10,7 @@ const themeComponents = getThemeComponents();
|
||||
export function useMDXComponents() {
|
||||
return {
|
||||
...themeComponents,
|
||||
a: LocalizedDocsLink,
|
||||
Cards: LocalizedCards,
|
||||
};
|
||||
}
|
||||
|
||||
54
frontend/tests/e2e/docs-localized-links.spec.ts
Normal file
54
frontend/tests/e2e/docs-localized-links.spec.ts
Normal file
@ -0,0 +1,54 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
|
||||
test.describe("Localized documentation links", () => {
|
||||
test("keeps English card navigation in the English docs", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto("/en/docs/introduction/core-concepts");
|
||||
|
||||
const card = page.locator("a.nextra-card", { hasText: "Why DeerFlow" });
|
||||
await expect(card).toHaveAttribute(
|
||||
"href",
|
||||
"/en/docs/introduction/why-deerflow",
|
||||
);
|
||||
|
||||
await card.click();
|
||||
await expect(page).toHaveURL(/\/en\/docs\/introduction\/why-deerflow$/);
|
||||
await expect(page.locator("main h1")).toContainText("Why DeerFlow");
|
||||
});
|
||||
|
||||
test("keeps Chinese card navigation in the Chinese docs", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto("/zh/docs/introduction/core-concepts");
|
||||
|
||||
const card = page.locator("a.nextra-card", { hasText: "Harness 与应用" });
|
||||
await expect(card).toHaveAttribute(
|
||||
"href",
|
||||
"/zh/docs/introduction/harness-vs-app",
|
||||
);
|
||||
|
||||
await card.click();
|
||||
await expect(page).toHaveURL(/\/zh\/docs\/introduction\/harness-vs-app$/);
|
||||
await expect(page.locator("main h1")).toContainText("Harness 与应用");
|
||||
});
|
||||
|
||||
test("localizes regular Markdown links", async ({ page }) => {
|
||||
await page.goto("/en/docs/application/workspace-usage");
|
||||
|
||||
const link = page
|
||||
.locator("main")
|
||||
.getByRole("link", { name: "Agents and Threads" })
|
||||
.first();
|
||||
await expect(link).toHaveAttribute(
|
||||
"href",
|
||||
"/en/docs/application/agents-and-threads",
|
||||
);
|
||||
|
||||
await link.click();
|
||||
await expect(page).toHaveURL(
|
||||
/\/en\/docs\/application\/agents-and-threads$/,
|
||||
);
|
||||
await expect(page.locator("main h1")).toContainText("Agents and Threads");
|
||||
});
|
||||
});
|
||||
65
frontend/tests/unit/components/docs/localized-links.test.ts
Normal file
65
frontend/tests/unit/components/docs/localized-links.test.ts
Normal file
@ -0,0 +1,65 @@
|
||||
import { readFileSync, readdirSync } from "node:fs";
|
||||
import { join, relative } from "node:path";
|
||||
|
||||
import { describe, expect, it } from "@rstest/core";
|
||||
|
||||
import { localizeDocsHref } from "@/components/docs/localized-links";
|
||||
|
||||
const CONTENT_ROOT = join(process.cwd(), "src/content");
|
||||
|
||||
function findMdxFiles(directory: string): string[] {
|
||||
return readdirSync(directory, { withFileTypes: true }).flatMap((entry) => {
|
||||
const path = join(directory, entry.name);
|
||||
return entry.isDirectory()
|
||||
? findMdxFiles(path)
|
||||
: entry.name.endsWith(".mdx")
|
||||
? [path]
|
||||
: [];
|
||||
});
|
||||
}
|
||||
|
||||
describe("localizeDocsHref", () => {
|
||||
it.each([
|
||||
["/docs", "en", "/en/docs"],
|
||||
["/docs/introduction", "en", "/en/docs/introduction"],
|
||||
[
|
||||
"/docs/introduction?tab=overview#next",
|
||||
"zh",
|
||||
"/zh/docs/introduction?tab=overview#next",
|
||||
],
|
||||
])("localizes %s for %s", (href, lang, expected) => {
|
||||
expect(localizeDocsHref(href, lang)).toBe(expected);
|
||||
});
|
||||
|
||||
it.each([
|
||||
["/en/docs/introduction", "zh"],
|
||||
["/zh/docs/introduction", "en"],
|
||||
["https://example.com/docs", "en"],
|
||||
["#overview", "zh"],
|
||||
["mailto:docs@example.com", "en"],
|
||||
["/workspace", "zh"],
|
||||
["/docs-extra", "en"],
|
||||
["/docs/introduction", "fr"],
|
||||
["/docs/introduction", undefined],
|
||||
])("leaves %s unchanged for language %s", (href, lang) => {
|
||||
expect(localizeDocsHref(href, lang)).toBe(href);
|
||||
});
|
||||
});
|
||||
|
||||
describe("documentation Cards imports", () => {
|
||||
it("does not bypass the locale-aware MDX Cards component", () => {
|
||||
const violations = findMdxFiles(CONTENT_ROOT)
|
||||
.filter((path) => {
|
||||
const source = readFileSync(path, "utf8");
|
||||
const nextraImports = source.matchAll(
|
||||
/import\s*\{([^}]*)\}\s*from\s*["']nextra\/components["']/g,
|
||||
);
|
||||
return [...nextraImports].some((match) =>
|
||||
match[1]?.split(",").some((name) => name.trim() === "Cards"),
|
||||
);
|
||||
})
|
||||
.map((path) => relative(CONTENT_ROOT, path));
|
||||
|
||||
expect(violations).toEqual([]);
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user