From d1a06ec32e6fe31d8675bd23aa22b4bee84c5339 Mon Sep 17 00:00:00 2001
From: liukuikun <24622904+Harold-lkk@users.noreply.github.com>
Date: Mon, 29 Jul 2024 14:57:29 +0800
Subject: [PATCH] [Refactor] remove unused for mindsearch (#210)
---
.dockerignore | 7 -
Dockerfile | 28 -
Dockerfile-base | 26 -
README.md | 78 +-
README_in_HIN.md | 51 +
README_in_beng.md | 55 +
README_ja_JP.md | 56 +
app.py | 272 -
docs/imgs/mindsearch_framework.png | Bin 989604 -> 0 bytes
docs/imgs/mindsearch_openset.png | Bin 119228 -> 0 bytes
environment.yml | 500 -
examples/web_graph_ci_demo.py | 44 -
examples/web_graph_gradio_demo.py | 193 -
examples/web_graph_streamlit_demo.py | 357 -
frontend/.gitignore | 20 -
frontend/.prettierignore | 7 -
frontend/.prettierrc.json | 7 -
frontend/README.md | 14 -
frontend/index.html | 14 -
frontend/package-lock.json | 9973 -------------------
frontend/package.json | 49 -
frontend/src/App.module.less | 54 -
frontend/src/App.tsx | 23 -
frontend/src/assets/background.png | Bin 36899 -> 0 bytes
frontend/src/assets/fold-icon.svg | 3 -
frontend/src/assets/logo.svg | 24 -
frontend/src/assets/pack-up.svg | 4 -
frontend/src/assets/sendIcon.svg | 4 -
frontend/src/assets/show-right-icon.png | Bin 8870 -> 0 bytes
frontend/src/assets/unflod-icon.svg | 3 -
frontend/src/components/iconfont/index.tsx | 7 -
frontend/src/config/cgi.ts | 2 -
frontend/src/global.d.ts | 1 -
frontend/src/index.less | 62 -
frontend/src/index.tsx | 10 -
frontend/src/pages/render/index.module.less | 848 --
frontend/src/pages/render/index.tsx | 681 --
frontend/src/pages/render/mindMapItem.tsx | 39 -
frontend/src/routes/routes.tsx | 38 -
frontend/src/utils/tools.ts | 24 -
frontend/src/vite-env.d.ts | 9 -
frontend/tsconfig.json | 24 -
frontend/vite.config.ts | 62 -
lagent/agents/mindsearch_agent.py | 395 -
44 files changed, 214 insertions(+), 13854 deletions(-)
delete mode 100644 .dockerignore
delete mode 100644 Dockerfile
delete mode 100644 Dockerfile-base
create mode 100644 README_in_HIN.md
create mode 100644 README_in_beng.md
create mode 100644 README_ja_JP.md
delete mode 100644 app.py
delete mode 100644 docs/imgs/mindsearch_framework.png
delete mode 100644 docs/imgs/mindsearch_openset.png
delete mode 100644 environment.yml
delete mode 100644 examples/web_graph_ci_demo.py
delete mode 100644 examples/web_graph_gradio_demo.py
delete mode 100644 examples/web_graph_streamlit_demo.py
delete mode 100644 frontend/.gitignore
delete mode 100644 frontend/.prettierignore
delete mode 100644 frontend/.prettierrc.json
delete mode 100644 frontend/README.md
delete mode 100644 frontend/index.html
delete mode 100644 frontend/package-lock.json
delete mode 100644 frontend/package.json
delete mode 100644 frontend/src/App.module.less
delete mode 100644 frontend/src/App.tsx
delete mode 100644 frontend/src/assets/background.png
delete mode 100644 frontend/src/assets/fold-icon.svg
delete mode 100644 frontend/src/assets/logo.svg
delete mode 100644 frontend/src/assets/pack-up.svg
delete mode 100644 frontend/src/assets/sendIcon.svg
delete mode 100644 frontend/src/assets/show-right-icon.png
delete mode 100644 frontend/src/assets/unflod-icon.svg
delete mode 100644 frontend/src/components/iconfont/index.tsx
delete mode 100644 frontend/src/config/cgi.ts
delete mode 100644 frontend/src/global.d.ts
delete mode 100644 frontend/src/index.less
delete mode 100644 frontend/src/index.tsx
delete mode 100644 frontend/src/pages/render/index.module.less
delete mode 100644 frontend/src/pages/render/index.tsx
delete mode 100644 frontend/src/pages/render/mindMapItem.tsx
delete mode 100644 frontend/src/routes/routes.tsx
delete mode 100644 frontend/src/utils/tools.ts
delete mode 100644 frontend/src/vite-env.d.ts
delete mode 100644 frontend/tsconfig.json
delete mode 100644 frontend/vite.config.ts
delete mode 100644 lagent/agents/mindsearch_agent.py
diff --git a/.dockerignore b/.dockerignore
deleted file mode 100644
index 5102d2c4..00000000
--- a/.dockerignore
+++ /dev/null
@@ -1,7 +0,0 @@
-.github/
-.vscode/
-docs/*/_build/
-*.egg-info
-lib/
-tmp_dir/
-work_dir/
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index eae2993a..00000000
--- a/Dockerfile
+++ /dev/null
@@ -1,28 +0,0 @@
-FROM continuumio/miniconda3
-
-ARG PUYU_API_KEY
-ENV PUYU_API_KEY=${PUYU_API_KEY}
-
-ARG BING_API_KEY
-ENV BING_API_KEY=${BING_API_KEY}
-
-# 设置环境变量
-ENV PATH=/opt/conda/bin:$PATH
-
-# 创建并激活 fastapi 环境
-RUN conda create --name fastapi python=3.10 -y
-
-# 克隆git仓库
-RUN git clone --branch ljn/fastapi https://github.com/liujiangning30/lagent.git /app
-WORKDIR /app
-
-# 激活环境并安装依赖包
-RUN /bin/bash -c "source activate fastapi && \
- pip install sse-starlette janus pyvis fastapi uvicorn termcolor -i https://pypi.tuna.tsinghua.edu.cn/simple && \
- pip install -e . -i https://pypi.tuna.tsinghua.edu.cn/simple"
-
-# 暴露 FastAPI 默认端口
-EXPOSE 8000
-
-# 启动 FastAPI 服务
-CMD ["/bin/bash", "-c", "source activate fastapi && uvicorn app:app --host 0.0.0.0 --port 8000"]
diff --git a/Dockerfile-base b/Dockerfile-base
deleted file mode 100644
index f9a4943b..00000000
--- a/Dockerfile-base
+++ /dev/null
@@ -1,26 +0,0 @@
-# 使用官方的 Python 镜像作为基础镜像
-FROM python:3.10-slim
-
-# 安装必要的工具
-RUN apt-get update && apt-get install -y \
- wget \
- bzip2 \
- git \
- && apt-get clean \
- && rm -rf /var/lib/apt/lists/*
-
-# 下载并安装 Miniconda
-RUN wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O /tmp/miniconda.sh && \
- /bin/bash /tmp/miniconda.sh -b -p /opt/conda && \
- rm /tmp/miniconda.sh
-
-# 设置环境变量
-ENV PATH=/opt/conda/bin:$PATH
-
-# 创建并激活 fastapi 环境
-RUN conda create --name fastapi python=3.10 -y
-
-# 激活环境并安装依赖包
-RUN /bin/bash -c "source activate fastapi && \
- pip install sse-starlette janus pyvis -i https://pypi.tuna.tsinghua.edu.cn/simple && \
- pip install lmdeploy==0.2.3 -i https://pypi.tuna.tsinghua.edu.cn/simple"
diff --git a/README.md b/README.md
index 3b32fb0b..a8b89294 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,6 @@
-
-
-
-# Lagent $\times$ MindSearch
-[Research Preview](https://mindsearch.netlify.app/) | [Paper]() | [Blog](https://mindsearch.netlify.app/mindsearch)
-
-
+
[![docs](https://img.shields.io/badge/docs-latest-blue)](https://lagent.readthedocs.io/en/latest/)
[![PyPI](https://img.shields.io/pypi/v/lagent)](https://pypi.org/project/lagent)
@@ -16,8 +10,9 @@
![Visitors](https://api.visitorbadge.io/api/visitors?path=InternLM%2Flagent%20&countColor=%23263759&style=flat)
![GitHub forks](https://img.shields.io/github/forks/InternLM/lagent)
![GitHub Repo stars](https://img.shields.io/github/stars/InternLM/lagent)
+![GitHub contributors](https://img.shields.io/github/contributors/InternLM/lagent)
-English | [简体中文](README_zh-CN.md)
+English | [简体中文](README_zh-CN.md) | [日本語](README_ja_JP.md) | [हिंदी](README_in_HIN.md) | [বাংলা](README_in_beng.md) | [한국어](README_KR_Kr.md)
@@ -25,31 +20,60 @@ English | [简体中文](README_zh-CN.md)
👋 join us on 𝕏 (Twitter), Discord and WeChat
-## ✨ MindSearch: Towards Deeper and Wider AI Search Engine
+
+
+https://github.com/InternLM/lagent/assets/24622904/3242f9bf-32d2-4907-8815-e16a75a4ac0e
-#### Demo Video here
+
-MindSearch is an open-source AI Search Engine Framework with Perplexity.ai Pro performance. You can simply deploy it with your own perplexity.ai style search engine with either close-source LLMs (GPT, Claude) or open-source LLMs (InternLM2.5-7b-chat). It owns following features:
-- 🤔 **Ask everything you want to know**: MindSearch is designed to solve any question in your life and use web knowledge.
-- 📚 **In-depth Knowledge Discovery**: MindSearch browses hundreds of web pages to answer your question, providing deeper and wider knowledge base answer.
-- 🔍 **Detailed Solution Path**: MindSearch exposes all details, allowing users to check everything they want. This greatly improves the credibility of its final response as well as usability.
-- 💻 **Optimized UI Experimence**: Providing all kinds of interfaces for users, including React, Streamlit, Terminal. Choose any type based on your need.
+## Getting Started
-## ⚡️ MindSearch vs other AI Search Engines
+Please see the [overview](docs/en/get_started/overview.md) for the general introduction of Lagent. Meanwhile, we provide extremely simple code for quick start. You may refer to [examples](examples/) for more details.
-Comparison on human preference based on depth, breadth, factuality of the response generated by ChatGPT-Web, Perplexity.ai (Pro), and MindSearch. Results are obtained on 100 human-crafted real-world questions and evaluated by 5 human experts *.
-
-
-
-* All experiments are done before July.7 2024.
+### Installation
-## ⚽️ Getting Started
+Install with pip (Recommended).
-### Lagent Installation
+```bash
+pip install lagent
+```
-MindSearch backend with Lagent, please see the [overview](docs/en/get_started/overview.md) for the general introduction of Lagent. Meanwhile, we provide extremely simple code for quick start. You may refer to [examples](examples/) for more details.
+### Run a Web Demo
-### MindSearch
+You need to install Streamlit first.
+
+```bash
+# pip install streamlit
+streamlit run examples/internlm2_agent_web_demo.py
+```
+
+## What's Lagent?
+
+Lagent is a lightweight open-source framework that allows users to efficiently build large language model(LLM)-based agents. It also provides some typical tools to augment LLM. The overview of our framework is shown below:
+
+![image](https://github.com/InternLM/lagent/assets/24351120/cefc4145-2ad8-4f80-b88b-97c05d1b9d3e)
+
+## Major Features
+
+- Stream Output: Provides the `stream_chat` interface for streaming output, allowing cool streaming demos right at your local setup.
+- Interfacing is unified, with a comprehensive design upgrade for enhanced extensibility, including:
+ - Model: Whether it's the OpenAI API, Transformers, or LMDeploy inference acceleration framework, you can seamlessly switch between models.
+ - Action: Simple inheritance and decoration allow you to create your own personal toolkit, adaptable to both InternLM and GPT.
+ - Agent: Consistent with the Model's input interface, the transformation from model to intelligent agent only takes one step, facilitating the exploration and implementation of various agents.
+- Documentation has been thoroughly upgraded with full API documentation coverage.
+
+## 💻Tech Stack
+
+
+
+
+
+
+### All Thanks To Our Contributors:
+
+
+
+
## Citation
@@ -66,4 +90,6 @@ If you find this project useful in your research, please consider cite:
## License
-This project is released under the [Apache 2.0 license](LICENSE).
\ No newline at end of file
+This project is released under the [Apache 2.0 license](LICENSE).
+
+
🔼 Back to top
diff --git a/README_in_HIN.md b/README_in_HIN.md
new file mode 100644
index 00000000..552dbc98
--- /dev/null
+++ b/README_in_HIN.md
@@ -0,0 +1,51 @@
+
+
+
+
+[![docs](https://img.shields.io/badge/docs-latest-blue)](https://lagent.readthedocs.io/en/latest/)
+[![PyPI](https://img.shields.io/pypi/v/lagent)](https://pypi.org/project/lagent)
+[![license](https://img.shields.io/github/license/InternLM/lagent.svg)](https://github.com/InternLM/lagent/tree/main/LICENSE)
+[![issue resolution](https://img.shields.io/github/issues-closed-raw/InternLM/lagent)](https://github.com/InternLM/lagent/issues)
+[![open issues](https://img.shields.io/github/issues-raw/InternLM/lagent)](https://github.com/InternLM/lagent/issues)
+
+English | [简体中文](README_zh-CN.md) | [日本語](README_ja_JP.md) | [हिंदी](README_in_HIN.md) | [বাংলা](README_in_beng.md) | [한국어](README_KR_Kr.md)
+
+
+
+
+
+https://github.com/InternLM/lagent/assets/24622904/cb851b31-6932-422e-a776-b1aa68f2a64f
+
+
+
+## शुरू करना
+
+लैजेंट के सामान्य परिचय के लिए कृपया [अवलोकन](docs/in/get_started/overview.md) देखें। इस बीच, हम त्वरित शुरुआत के लिए अत्यंत सरल कोड प्रदान करते हैं। अधिक जानकारी के लिए आप [उदाहरण](examples/) अधिक जानकारी के लिए।
+
+### इंस्टालेशन
+
+pip के साथ स्थापित करें (अनुशंसित)।
+
+```bash
+pip install lagent
+```
+
+### वेब डेमो चलाएँ
+
+```bash
+# You need to install streamlit first
+# pip install streamlit
+streamlit run examples/internlm2_agent_web_demo.py
+```
+
+## परिचय
+
+Lagent एक हल्का ओपन-सोर्स फ्रेमवर्क है जो उपयोगकर्ताओं को बड़े भाषा मॉडल (एलएलएम)-आधारित एजेंटों को कुशलतापूर्वक बनाने की अनुमति देता है। यह एलएलएम को बढ़ाने के लिए कुछ विशिष्ट उपकरण भी प्रदान करता है। हमारे ढांचे का अवलोकन नीचे दिखाया गया है:
+
+![image](https://github.com/InternLM/lagent/assets/24351120/cefc4145-2ad8-4f80-b88b-97c05d1b9d3e)
+
+## लाइसेंस
+
+यह प्रोजेक्ट [Apache 2.0 license](LICENSE) के तहत जारी किया गया है।
+
+🔼 Back to top
diff --git a/README_in_beng.md b/README_in_beng.md
new file mode 100644
index 00000000..31681b83
--- /dev/null
+++ b/README_in_beng.md
@@ -0,0 +1,55 @@
+
+
+
+
+[![docs](https://img.shields.io/badge/docs-latest-blue)](https://lagent.readthedocs.io/en/latest/)
+[![PyPI](https://img.shields.io/pypi/v/lagent)](https://pypi.org/project/lagent)
+[![license](https://img.shields.io/github/license/InternLM/lagent.svg)](https://github.com/InternLM/lagent/tree/main/LICENSE)
+[![issue resolution](https://img.shields.io/github/issues-closed-raw/InternLM/lagent)](https://github.com/InternLM/lagent/issues)
+[![open issues](https://img.shields.io/github/issues-raw/InternLM/lagent)](https://github.com/InternLM/lagent/issues)
+
+English | [简体中文](README_zh-CN.md) | [日本語](README_ja_JP.md) | [हिंदी](README_in_HIN.md) | [বাংলা](README_in_beng.md) | [한국어](README_KR_Kr.md)
+
+
+
+
+ 👋 Twitter, Discord এবং WeChat সাথে আমাদের সাথে যোগদান করুন
+
+
+
+
+https://github.com/InternLM/lagent/assets/24622904/cb851b31-6932-422e-a776-b1aa68f2a64f
+
+
+
+## শুরু করা
+
+লেজেন্টের সাধারণ পরিচিতির জন্য [অবলো](docs/en/get_started/overview.md) দেখ
+
+## ইনস্টলেশন
+
+পিপ দিয়ে ইনস্টল করুন (সুপারিশ).
+
+```bash
+pip install lagent
+```
+
+### ওয়েব ডেমো চালান
+
+```bash
+# You need to install streamlit first
+# pip install streamlit
+streamlit run examples/internlm2_agent_web_demo.py
+```
+
+## পরিচিতি
+
+লেজেন্ট হল একটি হালকা ওপেন-সোর্স ফ্রেমওয়ার্ক, যা ব্যবহারকারীদের দ্বারা প্রশাসক ভাষা মডেল (LLM) ভিত্তিক এজেন্ট সৃজনশীলভাবে তৈরি করতে দেয়। এটি লেজেন্ট যেসব প্রধান সরঞ্জাম সরবরাহ করে, সেটি নীচে দেখানো হয়:
+
+![image](https://github.com/InternLM/lagent/assets/24351120/cefc4145-2ad8-4f80-b88b-97c05d1b9d3e)
+
+## লাইসেন্স
+
+এই প্রকল্পটি [Apache 2.0 license](LICENSE) অনুসরণ করে প্রকাশিত হয়।
+
+🔼 Back to top
diff --git a/README_ja_JP.md b/README_ja_JP.md
new file mode 100644
index 00000000..a53187de
--- /dev/null
+++ b/README_ja_JP.md
@@ -0,0 +1,56 @@
+
+
+
+
+[![docs](https://img.shields.io/badge/docs-latest-blue)](https://lagent.readthedocs.io/en/latest/)
+[![PyPI](https://img.shields.io/pypi/v/lagent)](https://pypi.org/project/lagent)
+[![license](https://img.shields.io/github/license/InternLM/lagent.svg)](https://github.com/InternLM/lagent/tree/main/LICENSE)
+[![issue resolution](https://img.shields.io/github/issues-closed-raw/InternLM/lagent)](https://github.com/InternLM/lagent/issues)
+[![open issues](https://img.shields.io/github/issues-raw/InternLM/lagent)](https://github.com/InternLM/lagent/issues)
+
+English | [简体中文](README_zh-CN.md) | [日本語](README_ja_JP.md) | [हिंदी](README_in_HIN.md) | [বাংলা](README_in_beng.md) | [한국어](README_KR_Kr.md)
+
+
+
+
+ 👋 Twitter, Discord そして WeChat に参加する
+
+
+
+
+https://github.com/InternLM/lagent/assets/24622904/cb851b31-6932-422e-a776-b1aa68f2a64f
+
+
+
+## はじめに
+
+Lagent の概要については[概要](docs/ja/get_started/overview.md)をご覧ください。また、クイックスタートのために非常にシンプルなコードを用意しています。詳細は [examples](examples/) を参照してください。
+
+### インストール
+
+pip でインストールする(推奨)。
+
+```bash
+pip install lagent
+```
+
+### ウェブデモの実行
+
+最初に streamlit をインストールする必要があります
+
+```bash
+# pip install streamlit
+streamlit run examples/internlm2_agent_web_demo.py
+```
+
+## はじめに
+
+Lagent は、大規模言語モデル(LLM)ベースのエージェントを効率的に構築できる軽量なオープンソースフレームワークです。また、LLM を拡張するための典型的なツールも提供します。我々のフレームワークの概要を以下に示します:
+
+![image](https://github.com/InternLM/lagent/assets/24351120/cefc4145-2ad8-4f80-b88b-97c05d1b9d3e)
+
+## ライセンス
+
+このプロジェクトは [Apache 2.0 license](LICENSE) の下でリリースされています。
+
+🔼 Back to top
diff --git a/app.py b/app.py
deleted file mode 100644
index 215db6c5..00000000
--- a/app.py
+++ /dev/null
@@ -1,272 +0,0 @@
-import asyncio
-import json
-import logging
-import os
-from dataclasses import asdict, dataclass
-from datetime import datetime
-from typing import Dict, List, Optional, Union
-
-import janus
-from fastapi import FastAPI, HTTPException
-from fastapi.middleware.cors import CORSMiddleware
-from pydantic import BaseModel
-from sse_starlette.sse import EventSourceResponse
-
-import lagent.actions as action_factory
-import lagent.agents as agent_factory
-import lagent.llms as llm_factory
-from lagent.actions import ActionExecutor
-from lagent.agents.mindsearch_prompt import (FINAL_RESPONSE_EN,
- GRAPH_PROMPT_EN,
- searcher_context_template_en,
- searcher_input_template_en,
- searcher_system_prompt_en)
-from lagent.schema import AgentStatusCode
-
-# from lagent.agents.mindsearch_prompt import (GRAPH_PROMPT_CN,
-# searcher_context_template_cn,
-# searcher_input_template_cn,
-# searcher_system_prompt_cn,
-# FINAL_RESPONSE_CN)
-
-
-@dataclass
-class InvalidConfig:
- type: Optional[str] = None
- cfg: Optional[dict] = None
- details: Optional[str] = None
-
-
-def init_agent(cfg):
-
- # from lagent.llms import INTERNLM2_META
-
- def init_module(module_cfg, module_factory):
- try:
- module_type = module_cfg.pop('type')
- module_class = getattr(module_factory, module_type)
- module = module_class(**module_cfg)
- return module
- except Exception as exc:
- logging.exception(str(exc))
- return InvalidConfig(
- type=module_type, cfg=module_cfg, details=str(exc))
-
- def init_executor(module_cfg):
- plugin_executor = None
- interpreter_executor = None
- if 'plugin' in module_cfg:
- actions = []
- plugin_cfg = module_cfg.pop('plugin')
- for ac_cfg in plugin_cfg:
- ac = init_module(ac_cfg, action_factory)
- if isinstance(ac, InvalidConfig):
- return ac
- actions.append(ac)
- plugin_executor = ActionExecutor(actions=actions)
- if 'interpreter' in module_cfg:
- interpreter_cfg = module_cfg.pop('interpreter')
- ci = init_module(interpreter_cfg, action_factory)
- if isinstance(ci, InvalidConfig):
- return ci
- interpreter_executor = ActionExecutor(actions=[ci])
- return plugin_executor, interpreter_executor
-
- llm_cfg = cfg.get('llm', None)
- if not llm_cfg:
- # llm_cfg = dict(
- # type='LMDeployClient',
- # model_name='internlm2-chat-7b',
- # url=os.environ.get('LLM_URL', 'http://localhost:23333'),
- # meta_template=INTERNLM2_META,
- # max_new_tokens=4096,
- # top_p=0.8,
- # top_k=1,
- # temperature=0.8,
- # repetition_penalty=1.02,
- # stop_words=['<|im_end|>'])
- url = 'https://puyu.openxlab.org.cn/puyu/api/v1/chat/completions'
- llm_cfg = dict(
- type='GPTAPI',
- model_type='internlm2.5-latest',
- openai_api_base=url,
- key=os.environ.get('PUYU_API_KEY', 'YOUR PUYU API KEY'),
- meta_template=[
- dict(role='system', api_role='system'),
- dict(role='user', api_role='user'),
- dict(role='assistant', api_role='assistant'),
- dict(role='environment', api_role='environment')
- ],
- top_p=0.8,
- top_k=1,
- temperature=0.8,
- max_new_tokens=8192,
- repetition_penalty=1.02,
- stop_words=['<|im_end|>'])
- llm = init_module(llm_cfg, llm_factory)
- if isinstance(llm, InvalidConfig):
- return llm
- if cfg.get('type', None) is None:
- cfg['type'] = 'MindSearchAgent'
- searcher_cfg = cfg.get('searcher', None)
- if searcher_cfg:
- cfg.pop('searcher')
- if cfg['type'] == 'MindSearchAgent' and searcher_cfg is None:
- searcher_cfg = dict(
- llm=llm,
- plugin=[
- dict(
- type='BingBrowser',
- api_key=os.environ.get('BING_API_KEY',
- 'YOUR BING API KEY'))
- ],
- protocol=dict(
- type='MindSearchProtocol',
- meta_prompt=datetime.now().strftime(
- 'The current date is %Y-%m-%d.'),
- plugin_prompt=searcher_system_prompt_en,
- ),
- template=dict(
- input=searcher_input_template_en,
- context=searcher_context_template_en))
- if searcher_cfg:
- # searcher initialization
- if 'type' in searcher_cfg:
- searcher_cfg.pop('type')
- if isinstance(searcher_cfg['llm'], dict):
- searcher_llm = init_module(searcher_cfg['llm'], llm_factory)
- if isinstance(searcher_llm, InvalidConfig):
- return searcher_llm
- searcher_cfg['llm'] = searcher_llm
- searcher_protocol = init_module(searcher_cfg['protocol'],
- agent_factory)
- if isinstance(searcher_protocol, InvalidConfig):
- return searcher_protocol
- searcher_cfg['protocol'] = searcher_protocol
- executors = init_executor(searcher_cfg)
- if isinstance(executors, InvalidConfig):
- return executors
- searcher_cfg['plugin_executor'] = executors[0]
- cfg['searcher_cfg'] = searcher_cfg
- if cfg.get('protocol', None) is None:
- cfg['protocol'] = dict(
- type='MindSearchProtocol',
- meta_prompt=datetime.now().strftime(
- 'The current date is %Y-%m-%d.'),
- interpreter_prompt=GRAPH_PROMPT_EN,
- response_prompt=FINAL_RESPONSE_EN)
- if cfg.get('max_turn', None) is None:
- cfg['max_turn'] = 10
- # agent initialization
- cfg['llm'] = llm
- protocol = init_module(cfg['protocol'], agent_factory)
- if isinstance(protocol, InvalidConfig):
- return protocol
- cfg['protocol'] = protocol
- executors = init_executor(cfg)
- if isinstance(executors, InvalidConfig):
- return executors
- if isinstance(executors[0], ActionExecutor):
- cfg['plugin_executor'] = executors[0]
- if isinstance(executors[1], ActionExecutor):
- cfg['interpreter_executor'] = executors[1]
- agent = init_module(cfg, agent_factory)
- return agent
-
-
-def convert_adjacency_to_tree(adjacency_input, root_name):
-
- def build_tree(node_name):
- node = {'name': node_name, 'children': []}
- if node_name in adjacency_input:
- for child in adjacency_input[node_name]:
- child_node = build_tree(child['name'])
- child_node['state'] = child['state']
- child_node['id'] = child['id']
- node['children'].append(child_node)
- return node
-
- return build_tree(root_name)
-
-
-# agent = os.environ.get('agent_cfg', dict())
-
-app = FastAPI(docs_url='/')
-
-app.add_middleware(
- CORSMiddleware,
- allow_origins=['*'],
- allow_credentials=True,
- allow_methods=['*'],
- allow_headers=['*'])
-
-
-class GenerationParams(BaseModel):
- inputs: Union[str, List[Dict]]
- agent_cfg: Dict = dict()
-
-
-@app.post('/solve')
-async def run(request: GenerationParams):
- inputs = request.inputs
- agent = init_agent(request.agent_cfg)
- if not inputs:
- raise HTTPException(status_code=400, detail='Inputs are required')
- if isinstance(agent, InvalidConfig):
- raise InvalidConfig(**agent)
-
- async def generate():
- try:
- queue = janus.Queue()
-
- # 使用 run_in_executor 将同步生成器包装成异步生成器
- def sync_generator_wrapper():
- try:
- for response in agent.stream_chat(inputs):
- queue.sync_q.put(response)
- except KeyError as e:
- logging.error(f'KeyError in sync_generator_wrapper: {e}')
-
- async def async_generator_wrapper():
- loop = asyncio.get_event_loop()
- loop.run_in_executor(None, sync_generator_wrapper)
- while True:
- response = await queue.async_q.get()
- yield response
- if not isinstance(
- response,
- tuple) and response.state == AgentStatusCode.END:
- break
-
- async for response in async_generator_wrapper():
- if isinstance(response, tuple):
- agent_return, node_name = response
- else:
- agent_return = response
- node_name = None
- adjacency_list = convert_adjacency_to_tree(
- agent_return.adjacency_list, 'root')
- assert adjacency_list[
- 'name'] == 'root' and 'children' in adjacency_list
- agent_return.adjacency_list = adjacency_list['children']
- response_json = json.dumps(
- dict(
- response=asdict(agent_return), current_node=node_name),
- ensure_ascii=False)
- yield {'data': response_json}
- # yield f'data: {response_json}\n\n'
- except Exception as exc:
- msg = 'An error occurred while generating the response.'
- logging.exception(msg)
- response_json = json.dumps(
- dict(error=dict(msg=msg, details=str(exc))),
- ensure_ascii=False)
- yield {'data': response_json}
- # yield f'data: {response_json}\n\n'
-
- return EventSourceResponse(generate())
-
-
-if __name__ == '__main__':
- import uvicorn
- uvicorn.run(app, host='0.0.0.0', port=8000, log_level='info')
diff --git a/docs/imgs/mindsearch_framework.png b/docs/imgs/mindsearch_framework.png
deleted file mode 100644
index 24c545c1487691d7b4092ca1142a2296f6af2766..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 989604
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≧Juxh8@p)!qB
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 |