doc: migrate development guide doc

This commit is contained in:
alan.cl
2026-03-24 19:57:23 +08:00
parent 48f0ba081d
commit 8fef80a427
6 changed files with 652 additions and 25 deletions

View File

@@ -0,0 +1,182 @@
# Tool Use
While LLMs can complete a wide range of tasks, they may not work well for the domains
which need comprehensive expert knowledge. In addition, LLMs may also encounter
hallucination problems, which are hard to be resolved by themselves.
So, we need to use some tools to help LLMs to complete the tasks.
:::note
In DB-GPT agents, most LLMs support tool calls as long as their own capabilities are not too weak.
(Such as `glm-4-9b-chat`, `Yi-1.5-34B-Chat`, `Qwen2-72B-Instruct`, etc.)
:::
## Writing Tools
Sometimes, LLMs may not be able to complete the calculation tasks directly, so we can
write a simple calculator tool to help them.
```python
from dbgpt.agent.resource import tool
@tool
def simple_calculator(first_number: int, second_number: int, operator: str) -> float:
"""Simple calculator tool. Just support +, -, *, /."""
if isinstance(first_number, str):
first_number = int(first_number)
if isinstance(second_number, str):
second_number = int(second_number)
if operator == "+":
return first_number + second_number
elif operator == "-":
return first_number - second_number
elif operator == "*":
return first_number * second_number
elif operator == "/":
return first_number / second_number
else:
raise ValueError(f"Invalid operator: {operator}")
```
To test multiple tools, let's write another tool to help LLMs to count the number of files in a directory.
```python
import os
from typing_extensions import Annotated, Doc
@tool
def count_directory_files(path: Annotated[str, Doc("The directory path")]) -> int:
"""Count the number of files in a directory."""
if not os.path.isdir(path):
raise ValueError(f"Invalid directory path: {path}")
return len(os.listdir(path))
```
## Wrap Your Tools To `ToolPack`
Most of the time, you may have multiple tools, so you can wrap them to a `ToolPack`.
`ToolPack` is a collection of tools, you can use it to manage your tools, and the agent
can select the appropriate tool from the `ToolPack` according to the task requirements.
```python
from dbgpt.agent.resource import ToolPack
tools = ToolPack([simple_calculator, count_directory_files])
```
## Use Tools In Your Agent
```python
import asyncio
import os
from dbgpt.agent import AgentContext, AgentMemory, LLMConfig, UserProxyAgent
from dbgpt.agent.expand.tool_assistant_agent import ToolAssistantAgent
from dbgpt.model.proxy import OpenAILLMClient
async def main():
llm_client = OpenAILLMClient(
model_alias="gpt-3.5-turbo", # or other models, eg. "gpt-4o"
api_base=os.getenv("OPENAI_API_BASE"),
api_key=os.getenv("OPENAI_API_KEY"),
)
context: AgentContext = AgentContext(
conv_id="test123", language="en", temperature=0.5, max_new_tokens=2048
)
agent_memory = AgentMemory()
agent_memory.gpts_memory.init(conv_id="test123")
user_proxy = await UserProxyAgent().bind(agent_memory).bind(context).build()
tool_man = (
await ToolAssistantAgent()
.bind(context)
.bind(LLMConfig(llm_client=llm_client))
.bind(agent_memory)
.bind(tools)
.build()
)
await user_proxy.initiate_chat(
recipient=tool_man,
reviewer=user_proxy,
message="Calculate the product of 10 and 99",
)
await user_proxy.initiate_chat(
recipient=tool_man,
reviewer=user_proxy,
message="Count the number of files in /tmp",
)
# dbgpt-vis message infos
print(await agent_memory.gpts_memory.app_link_chat_message("test123"))
if __name__ == "__main__":
asyncio.run(main())
```
The output will be like this:
``````bash
--------------------------------------------------------------------------------
User (to LuBan)-[]:
"Calculate the product of 10 and 99"
--------------------------------------------------------------------------------
un_stream ai response: {
"thought": "To calculate the product of 10 and 99, we need to use a tool that can perform multiplication operation.",
"tool_name": "simple_calculator",
"args": {
"first_number": 10,
"second_number": 99,
"operator": "*"
}
}
--------------------------------------------------------------------------------
LuBan (to User)-[gpt-3.5-turbo]:
"{\n \"thought\": \"To calculate the product of 10 and 99, we need to use a tool that can perform multiplication operation.\",\n \"tool_name\": \"simple_calculator\",\n \"args\": {\n \"first_number\": 10,\n \"second_number\": 99,\n \"operator\": \"*\"\n }\n}"
>>>>>>>>LuBan Review info:
Pass(None)
>>>>>>>>LuBan Action report:
execution succeeded,
990
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
User (to LuBan)-[]:
"Count the number of files in /tmp"
--------------------------------------------------------------------------------
un_stream ai response: {
"thought": "To count the number of files in /tmp directory, we should use a tool that can perform this operation.",
"tool_name": "count_directory_files",
"args": {
"path": "/tmp"
}
}
--------------------------------------------------------------------------------
LuBan (to User)-[gpt-3.5-turbo]:
"{\n \"thought\": \"To count the number of files in /tmp directory, we should use a tool that can perform this operation.\",\n \"tool_name\": \"count_directory_files\",\n \"args\": {\n \"path\": \"/tmp\"\n }\n}"
>>>>>>>>LuBan Review info:
Pass(None)
>>>>>>>>LuBan Action report:
execution succeeded,
19
--------------------------------------------------------------------------------
``````
In the above code, we use the `ToolAssistantAgent` to select and call the appropriate tool.
## More Details?
In the above code, we use the `tool` decorator to define the tool function. It will wrap the function to a
`FunctionTool` object. And `FunctionTool` is a subclass of `BaseTool`, which is a base class of all tools.
Actually, **tool** is a special **resource** in the `DB-GPT` agent. You will see more details in the [Resource](../modules/resource/resource.md) section.

View File

@@ -108,3 +108,7 @@ After that, you can use it to build your APP according to [App Manage](./apps/ap
- [AWEL](../awel/awel.md)
- [AWEL CookBook](../awel/cookbook/)
- [AWEL Tutorial](../awel/tutorial/)
---
📖 Want to learn more about AWEL? Check out the [AWEL Tutorial](../awel/tutorial/) for step-by-step guides from basics to advanced patterns.

View File

@@ -55,6 +55,10 @@
"message": "数据源",
"description": "The label for category Datasources in sidebar docsSidebar"
},
"sidebar.docsSidebar.category.Application": {
"message": "应用管理",
"description": "The label for category Application in sidebar docsSidebar"
},
"sidebar.docsSidebar.category.App Guides": {
"message": "应用指南",
"description": "The label for category App Guides in sidebar docsSidebar"
@@ -307,8 +311,12 @@
"message": "GraphRAG",
"description": "The label for the doc item GraphRAG in sidebar docsSidebar, linking to the doc application/graph_rag"
},
"sidebar.docsSidebar.doc.App Manage": {
"message": "应用管理",
"description": "The label for the doc item App Manage in sidebar docsSidebar, linking to the doc application/apps/app_manage"
},
"sidebar.docsSidebar.doc.Chat Knowledge Base": {
"message": "Chat Knowledge Base",
"message": "知识库对话",
"description": "The label for the doc item Chat Knowledge Base in sidebar docsSidebar, linking to the doc application/apps/chat_knowledge"
},
"sidebar.docsSidebar.doc.Advanced RAG": {
@@ -370,5 +378,53 @@
"sidebar.docsSidebar.doc.Use Cases": {
"message": "使用案例",
"description": "The label for the doc item Use Cases in sidebar docsSidebar, linking to the doc use_cases"
},
"sidebar.sidebarApplication.category.App Guides": {
"message": "应用指南",
"description": "The label for category App Guides in sidebar sidebarApplication"
},
"sidebar.sidebarApplication.category.Functional Components": {
"message": "功能组件",
"description": "The label for category Functional Components in sidebar sidebarApplication"
},
"sidebar.sidebarApplication.doc.App Manage": {
"message": "应用管理",
"description": "The label for the doc item App Manage in sidebar sidebarApplication, linking to the doc application/apps/app_manage"
},
"sidebar.sidebarApplication.doc.Chat Knowledge Base": {
"message": "知识库对话",
"description": "The label for the doc item Chat Knowledge Base in sidebar sidebarApplication, linking to the doc application/apps/chat_knowledge"
},
"sidebar.sidebarApplication.doc.Chat Data": {
"message": "Chat Data",
"description": "The label for the doc item Chat Data in sidebar sidebarApplication, linking to the doc application/apps/chat_data"
},
"sidebar.sidebarApplication.doc.Chat DB": {
"message": "Chat DB",
"description": "The label for the doc item Chat DB in sidebar sidebarApplication, linking to the doc application/apps/chat_db"
},
"sidebar.sidebarApplication.doc.Chat Excel": {
"message": "Chat Excel",
"description": "The label for the doc item Chat Excel in sidebar sidebarApplication, linking to the doc application/apps/chat_excel"
},
"sidebar.sidebarApplication.doc.Chat Dashboard": {
"message": "Chat Dashboard",
"description": "The label for the doc item Chat Dashboard in sidebar sidebarApplication, linking to the doc application/apps/chat_dashboard"
},
"sidebar.sidebarApplication.doc.Prompts": {
"message": "提示词",
"description": "The label for the doc item Prompts in sidebar sidebarApplication, linking to the doc application/prompts"
},
"sidebar.sidebarApplication.doc.LLMs": {
"message": "模型管理",
"description": "The label for the doc item LLMs in sidebar sidebarApplication, linking to the doc application/llms"
},
"sidebar.sidebarApplication.doc.Use Data App With AWEL": {
"message": "使用 AWEL 构建数据应用",
"description": "The label for the doc item Use Data App With AWEL in sidebar sidebarApplication, linking to the doc application/awel"
},
"sidebar.sidebarApplication.doc.Benchmark": {
"message": "基准测试",
"description": "The label for the doc item Benchmark in sidebar sidebarApplication, linking to the doc modules/benchmark"
}
}

View File

@@ -0,0 +1,178 @@
# 工具使用
虽然大语言模型LLM可以完成各种各样的任务但在需要全面专业知识的领域中它们可能表现不佳。此外LLM 还可能遇到幻觉问题,而这些问题很难靠自身解决。
因此,我们需要使用一些工具来帮助 LLM 完成任务。
:::note
在 DB-GPT 智能体中,大多数 LLM 都支持工具调用,只要其自身能力不是太弱即可。
(例如 `glm-4-9b-chat``Yi-1.5-34B-Chat``Qwen2-72B-Instruct` 等)
:::
## 编写工具
有时候LLM 可能无法直接完成计算任务,因此我们可以编写一个简单的计算器工具来帮助它们。
```python
from dbgpt.agent.resource import tool
@tool
def simple_calculator(first_number: int, second_number: int, operator: str) -> float:
"""Simple calculator tool. Just support +, -, *, /."""
if isinstance(first_number, str):
first_number = int(first_number)
if isinstance(second_number, str):
second_number = int(second_number)
if operator == "+":
return first_number + second_number
elif operator == "-":
return first_number - second_number
elif operator == "*":
return first_number * second_number
elif operator == "/":
return first_number / second_number
else:
raise ValueError(f"Invalid operator: {operator}")
```
为了测试多个工具,我们再编写一个工具来帮助 LLM 统计目录中的文件数量。
```python
import os
from typing_extensions import Annotated, Doc
@tool
def count_directory_files(path: Annotated[str, Doc("The directory path")]) -> int:
"""Count the number of files in a directory."""
if not os.path.isdir(path):
raise ValueError(f"Invalid directory path: {path}")
return len(os.listdir(path))
```
## 将工具封装为 `ToolPack`
大多数情况下,你可能有多个工具,因此可以将它们封装为一个 `ToolPack`
`ToolPack` 是工具的集合,你可以用它来管理你的工具,智能体可以根据任务需求从 `ToolPack` 中选择合适的工具。
```python
from dbgpt.agent.resource import ToolPack
tools = ToolPack([simple_calculator, count_directory_files])
```
## 在智能体中使用工具
```python
import asyncio
import os
from dbgpt.agent import AgentContext, AgentMemory, LLMConfig, UserProxyAgent
from dbgpt.agent.expand.tool_assistant_agent import ToolAssistantAgent
from dbgpt.model.proxy import OpenAILLMClient
async def main():
llm_client = OpenAILLMClient(
model_alias="gpt-3.5-turbo", # 或其他模型,例如 "gpt-4o"
api_base=os.getenv("OPENAI_API_BASE"),
api_key=os.getenv("OPENAI_API_KEY"),
)
context: AgentContext = AgentContext(
conv_id="test123", language="en", temperature=0.5, max_new_tokens=2048
)
agent_memory = AgentMemory()
agent_memory.gpts_memory.init(conv_id="test123")
user_proxy = await UserProxyAgent().bind(agent_memory).bind(context).build()
tool_man = (
await ToolAssistantAgent()
.bind(context)
.bind(LLMConfig(llm_client=llm_client))
.bind(agent_memory)
.bind(tools)
.build()
)
await user_proxy.initiate_chat(
recipient=tool_man,
reviewer=user_proxy,
message="Calculate the product of 10 and 99",
)
await user_proxy.initiate_chat(
recipient=tool_man,
reviewer=user_proxy,
message="Count the number of files in /tmp",
)
# dbgpt-vis 消息信息
print(await agent_memory.gpts_memory.app_link_chat_message("test123"))
if __name__ == "__main__":
asyncio.run(main())
```
输出结果如下:
```bash
--------------------------------------------------------------------------------
User (to LuBan)-[]:
"Calculate the product of 10 and 99"
--------------------------------------------------------------------------------
un_stream ai response: {
"thought": "To calculate the product of 10 and 99, we need to use a tool that can perform multiplication operation.",
"tool_name": "simple_calculator",
"args": {
"first_number": 10,
"second_number": 99,
"operator": "*"
}
}
--------------------------------------------------------------------------------
LuBan (to User)-[gpt-3.5-turbo]:
"{\n \"thought\": \"To calculate the product of 10 and 99, we need to use a tool that can perform multiplication operation.\",\n \"tool_name\": \"simple_calculator\",\n \"args\": {\n \"first_number\": 10,\n \"second_number\": 99,\n \"operator\": \"*\"\n }\n}"
>>>>>>>>LuBan Review info:
Pass(None)
>>>>>>>>LuBan Action report:
execution succeeded,
990
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
User (to LuBan)-[]:
"Count the number of files in /tmp"
--------------------------------------------------------------------------------
un_stream ai response: {
"thought": "To count the number of files in /tmp directory, we should use a tool that can perform this operation.",
"tool_name": "count_directory_files",
"args": {
"path": "/tmp"
}
}
--------------------------------------------------------------------------------
LuBan (to User)-[gpt-3.5-turbo]:
"{\n \"thought\": \"To count the number of files in /tmp directory, we should use a tool that can perform this operation.\",\n \"tool_name\": \"count_directory_files\",\n \"args\": {\n \"path\": \"/tmp\"\n }\n}"
>>>>>>>>LuBan Review info:
Pass(None)
>>>>>>>>LuBan Action report:
execution succeeded,
19
--------------------------------------------------------------------------------
```
在上面的代码中,我们使用 `ToolAssistantAgent` 来选择并调用合适的工具。
## 更多细节?
在上面的代码中,我们使用 `tool` 装饰器来定义工具函数。它会将函数封装为一个 `FunctionTool` 对象。而 `FunctionTool``BaseTool` 的子类,`BaseTool` 是所有工具的基类。
实际上,**工具**是 `DB-GPT` 智能体中一种特殊的**资源**。你可以在[资源](../modules/resource/resource.md)章节中了解更多细节。

View File

@@ -154,6 +154,8 @@ const sidebars = {
{
type: "category",
label: "Datasource Integrations",
collapsed: true,
collapsible: true,
items: [
{ type: "doc", id: "installation/integrations/mysql_install" },
{ type: "doc", id: "installation/integrations/sqlite_install" },
@@ -406,6 +408,7 @@ const sidebars = {
type: "category",
label: "Datasource Integrations",
collapsed: true,
collapsible: true,
items: [
{ type: "doc", id: "installation/integrations/clickhouse_install" },
{ type: "doc", id: "installation/integrations/postgres_install" },
@@ -556,8 +559,8 @@ const sidebars = {
{
type: "category",
label: "Datasource Integrations",
collapsed: false,
collapsible: false,
collapsed: true,
collapsible: true,
items: [
{ type: "doc", id: "installation/integrations/mysql_install" },
{ type: "doc", id: "installation/integrations/sqlite_install" },
@@ -574,19 +577,36 @@ const sidebars = {
{ type: "doc", id: "installation/integrations/vertica_install" },
],
},
],
sidebarApplication: [
{
type: "category",
label: "App Guides",
collapsed: false,
collapsible: false,
collapsible: true,
items: [
{ type: "doc", id: "application/apps/app_manage", label: "App Manage" },
{ type: "doc", id: "application/apps/chat_data", label: "Chat Data" },
{ type: "doc", id: "application/apps/chat_db", label: "Chat DB" },
{ type: "doc", id: "application/apps/chat_excel", label: "Chat Excel" },
{ type: "doc", id: "application/apps/chat_knowledge", label: "Chat Knowledge Base" },
{ type: "doc", id: "application/apps/chat_dashboard", label: "Chat Dashboard" },
{ type: "doc", id: "application/apps/chat_financial_report" },
],
},
{
type: "category",
label: "Functional Components",
collapsed: false,
collapsible: true,
items: [
{ type: "doc", id: "application/prompts", label: "Prompts" },
{ type: "doc", id: "application/llms", label: "LLMs" },
{ type: "doc", id: "application/awel", label: "Use Data App With AWEL" },
{ type: "doc", id: "modules/benchmark", label: "Benchmark" },
],
},
],
sidebarSandbox: [{ type: "doc", id: "sandbox/index", label: "Overview" }],
@@ -777,6 +797,75 @@ const sidebars = {
},
],
sidebarDevelopmentGuide: [
{
type: "category",
label: "Agents",
collapsed: true,
items: [
{ type: "doc", id: "agents/introduction/introduction", label: "Data Driven Multi-Agents" },
{ type: "doc", id: "agents/introduction/tools_use", label: "Tool Use" },
{ type: "doc", id: "agents/introduction/planning", label: "Planning" },
{ type: "doc", id: "agents/introduction/conversation", label: "Conversation" },
{ type: "doc", id: "agents/introduction/custom_agents", label: "Custom Agents" },
{
type: "category",
label: "Agent Modules",
collapsed: true,
items: [
{
type: "category",
label: "Profile",
collapsed: true,
items: [
{ type: "doc", id: "agents/modules/profile/profile" },
{ type: "doc", id: "agents/modules/profile/profile_creation" },
{ type: "doc", id: "agents/modules/profile/profile_to_prompt" },
{ type: "doc", id: "agents/modules/profile/profile_dynamic" },
],
},
{
type: "category",
label: "Memory",
collapsed: true,
items: [
{ type: "doc", id: "agents/modules/memory/memory" },
{ type: "doc", id: "agents/modules/memory/sensory_memory" },
{ type: "doc", id: "agents/modules/memory/short_term_memory" },
{ type: "doc", id: "agents/modules/memory/long_term_memory" },
{ type: "doc", id: "agents/modules/memory/hybrid_memory" },
],
},
{
type: "category",
label: "Plan",
collapsed: true,
items: [{ type: "doc", id: "agents/modules/plan/plan" }],
},
{
type: "category",
label: "Action",
collapsed: true,
items: [{ type: "doc", id: "agents/modules/action/action" }],
},
{
type: "category",
label: "Resource",
collapsed: true,
items: [
{ type: "doc", id: "agents/modules/resource/resource" },
{ type: "doc", id: "agents/modules/resource/tools" },
{ type: "doc", id: "agents/modules/resource/database" },
{ type: "doc", id: "agents/modules/resource/knowledge" },
{ type: "doc", id: "agents/modules/resource/pack" },
],
},
],
},
],
},
],
sidebarReference: [
{
type: "category",
@@ -819,7 +908,6 @@ const sidebars = {
},
{ type: "doc", id: "modules/visual", label: "Visual" },
{ type: "doc", id: "modules/eval", label: "Evaluation" },
{ type: "doc", id: "modules/benchmark", label: "Benchmark" },
],
sidebarHelp: [
@@ -890,6 +978,13 @@ module.exports = {
collapsible: true,
items: sidebars.sidebarDatasources,
},
{
type: "category",
label: "Application",
collapsed: true,
collapsible: true,
items: sidebars.sidebarApplication,
},
{
type: "category",
label: "Sandbox",
@@ -932,6 +1027,13 @@ module.exports = {
collapsible: true,
items: sidebars.sidebarReference,
},
{
type: "category",
label: "Development Guide",
collapsed: true,
collapsible: true,
items: sidebars.sidebarDevelopmentGuide,
},
{
type: "category",
label: "Help",

View File

@@ -1,10 +1,11 @@
import React from 'react';
import React, {useState, useRef, useEffect} from 'react';
import clsx from 'clsx';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import {useAlternatePageUtils} from '@docusaurus/theme-common/internal';
import {useCollapsible, Collapsible} from '@docusaurus/theme-common';
import {translate} from '@docusaurus/Translate';
import {useLocation} from '@docusaurus/router';
import DropdownNavbarItem from '@theme/NavbarItem/DropdownNavbarItem';
const localeFlags = {
en: '🇺🇸',
@@ -30,6 +31,112 @@ function renderLocaleNode(locale, localeConfigs) {
);
}
function LocaleDropdownDesktop({currentLocale, localeConfigs, localeItems, className}) {
const [isOpen, setIsOpen] = useState(false);
const closeTimerRef = useRef(null);
function handleMouseEnter() {
if (closeTimerRef.current) {
clearTimeout(closeTimerRef.current);
closeTimerRef.current = null;
}
setIsOpen(true);
}
function handleMouseLeave() {
// 短暂延迟关闭,让鼠标有时间移动到下拉菜单上
closeTimerRef.current = setTimeout(() => {
setIsOpen(false);
}, 100);
}
useEffect(() => {
return () => {
if (closeTimerRef.current) {
clearTimeout(closeTimerRef.current);
}
};
}, []);
return (
<div
className={clsx(
'navbar__item',
'dropdown',
'dropdown--hoverable',
{'dropdown--show': isOpen},
'navbar-language-dropdown',
className,
)}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}>
<a
href="#"
aria-haspopup="true"
aria-expanded={isOpen}
role="button"
className="navbar__link"
onClick={(e) => e.preventDefault()}>
{renderLocaleNode(currentLocale, localeConfigs)}
</a>
<ul className="dropdown__menu">
{localeItems.map((item, index) => (
<li key={index}>
<a
className={clsx('dropdown__link', item.className)}
href={item.href}
target={item.target}
lang={item.lang}>
{item.label}
</a>
</li>
))}
</ul>
</div>
);
}
function LocaleDropdownMobile({localeItems, className}) {
const mobileLabel = translate({
message: 'Languages',
id: 'theme.navbar.mobileLanguageDropdown.label',
description: 'The label for the mobile language switcher dropdown',
});
const {collapsed, toggleCollapsed} = useCollapsible({initialState: true});
return (
<li
className={clsx('menu__list-item', {
'menu__list-item--collapsed': collapsed,
})}>
<a
role="button"
className="menu__link menu__link--sublist menu__link--sublist-caret"
onClick={(e) => {
e.preventDefault();
toggleCollapsed();
}}
href="#">
{mobileLabel}
</a>
<Collapsible lazy as="ul" className="menu__list" collapsed={collapsed}>
{localeItems.map((item, index) => (
<li key={index} className="menu__list-item">
<a
className={clsx('menu__link', item.className)}
href={item.href}
target={item.target}
lang={item.lang}>
{item.label}
</a>
</li>
))}
</Collapsible>
</li>
);
}
export default function LocaleDropdownNavbarItem({
mobile,
dropdownItemsBefore = [],
@@ -45,18 +152,16 @@ export default function LocaleDropdownNavbarItem({
const {search, hash} = useLocation();
const localeItems = locales.map((locale) => {
const baseTo = `pathname://${alternatePageUtils.createUrl({
const href = `${alternatePageUtils.createUrl({
locale,
fullyQualified: false,
})}`;
const to = `${baseTo}${search}${hash}${queryString}`;
})}${search}${hash}${queryString}`;
return {
label: renderLocaleNode(locale, localeConfigs),
lang: localeConfigs[locale]?.htmlLang,
to,
href,
target: '_self',
autoAddBaseUrl: false,
className:
locale === currentLocale
? mobile
@@ -68,21 +173,21 @@ export default function LocaleDropdownNavbarItem({
const items = [...dropdownItemsBefore, ...localeItems, ...dropdownItemsAfter];
const mobileLabel = translate({
message: 'Languages',
id: 'theme.navbar.mobileLanguageDropdown.label',
description: 'The label for the mobile language switcher dropdown',
});
if (mobile) {
return (
<LocaleDropdownMobile
localeItems={items}
className={className}
/>
);
}
return (
<DropdownNavbarItem
{...props}
mobile={mobile}
className={clsx('navbar-language-dropdown', className)}
label={
mobile ? mobileLabel : renderLocaleNode(currentLocale, localeConfigs)
}
items={items}
<LocaleDropdownDesktop
currentLocale={currentLocale}
localeConfigs={localeConfigs}
localeItems={items}
className={className}
/>
);
}