mirror of
https://github.com/csunny/DB-GPT.git
synced 2026-07-16 17:15:22 +00:00
doc: migrate development guide doc
This commit is contained in:
182
docs/docs/agents/introduction/tools_use.md
Normal file
182
docs/docs/agents/introduction/tools_use.md
Normal 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.
|
||||
@@ -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.
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)章节中了解更多细节。
|
||||
110
docs/sidebars.js
110
docs/sidebars.js
@@ -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",
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user