diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000000000000000000000000000000000000..347d681fa1be11c55e1a1c895fb1976676384768
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,12 @@
+**/node_modules
+**/dist
+**/.git
+**/.gitignore
+**/.vscode
+**/README.md
+**/LICENSE
+**/.env
+**/npm-debug.log
+**/yarn-debug.log
+**/yarn-error.log
+**/.pnpm-debug.log
diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000000000000000000000000000000000000..988ff22c4502bf56b9b64c26c7dc01f92d5d99f8
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,6 @@
+OPENAI_API_KEY=
+OPENAI_API_BASE=
+OPENAI_MODEL=
+SILICON_API_KEY=
+SILICON_MODEL=
+InternLM_API_KEY=
\ No newline at end of file
diff --git a/.gitattributes b/.gitattributes
index a6344aac8c09253b3b630fb776ae94478aa0275b..7b9d43cd21feb4270b5e58e1e959613896bdd1bc 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,35 +1,4 @@
-*.7z filter=lfs diff=lfs merge=lfs -text
-*.arrow filter=lfs diff=lfs merge=lfs -text
-*.bin filter=lfs diff=lfs merge=lfs -text
-*.bz2 filter=lfs diff=lfs merge=lfs -text
-*.ckpt filter=lfs diff=lfs merge=lfs -text
-*.ftz filter=lfs diff=lfs merge=lfs -text
-*.gz filter=lfs diff=lfs merge=lfs -text
-*.h5 filter=lfs diff=lfs merge=lfs -text
-*.joblib filter=lfs diff=lfs merge=lfs -text
-*.lfs.* filter=lfs diff=lfs merge=lfs -text
-*.mlmodel filter=lfs diff=lfs merge=lfs -text
-*.model filter=lfs diff=lfs merge=lfs -text
-*.msgpack filter=lfs diff=lfs merge=lfs -text
-*.npy filter=lfs diff=lfs merge=lfs -text
-*.npz filter=lfs diff=lfs merge=lfs -text
-*.onnx filter=lfs diff=lfs merge=lfs -text
-*.ot filter=lfs diff=lfs merge=lfs -text
-*.parquet filter=lfs diff=lfs merge=lfs -text
-*.pb filter=lfs diff=lfs merge=lfs -text
-*.pickle filter=lfs diff=lfs merge=lfs -text
-*.pkl filter=lfs diff=lfs merge=lfs -text
-*.pt filter=lfs diff=lfs merge=lfs -text
-*.pth filter=lfs diff=lfs merge=lfs -text
-*.rar filter=lfs diff=lfs merge=lfs -text
-*.safetensors filter=lfs diff=lfs merge=lfs -text
-saved_model/**/* filter=lfs diff=lfs merge=lfs -text
-*.tar.* filter=lfs diff=lfs merge=lfs -text
-*.tar filter=lfs diff=lfs merge=lfs -text
-*.tflite filter=lfs diff=lfs merge=lfs -text
-*.tgz filter=lfs diff=lfs merge=lfs -text
-*.wasm filter=lfs diff=lfs merge=lfs -text
-*.xz filter=lfs diff=lfs merge=lfs -text
-*.zip filter=lfs diff=lfs merge=lfs -text
-*.zst filter=lfs diff=lfs merge=lfs -text
-*tfevents* filter=lfs diff=lfs merge=lfs -text
+*.png filter=lfs diff=lfs merge=lfs -text
+*.jpg filter=lfs diff=lfs merge=lfs -text
+*.gif filter=lfs diff=lfs merge=lfs -text
+*.mp4 filter=lfs diff=lfs merge=lfs -text
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..d9636f41858a5f157483f5852dd3bdeacfde85ff
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,165 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[ciod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+# For a library or package, you might want to ignore these files since the code is
+# intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# poetry
+# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+# This is especially recommended for binary packages to ensure reproducibility, and is more
+# commonly ignored for libraries.
+# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# pdm
+# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
+#pdm.lock
+# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
+# in version control.
+# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
+.pdm.toml
+.pdm-python
+.pdm-build/
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# PyCharm
+# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
+# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+# and can be added to the global gitignore or merged into this file. For a more nuclear
+# option (not recommended) you can uncomment the following to ignore the entire idea folder.
+#.idea/
+
+.env
+temp
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..da8ac627c3efbab20b63e948b4dea14446ae4b60
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,46 @@
+exclude: ^(tests/data|scripts|frontend/React)/
+repos:
+ - repo: https://github.com/PyCQA/flake8
+ rev: 7.0.0
+ hooks:
+ - id: flake8
+ args: ["--max-line-length=120"]
+ - repo: https://github.com/PyCQA/isort
+ rev: 5.13.2
+ hooks:
+ - id: isort
+ - repo: https://github.com/pre-commit/mirrors-yapf
+ rev: v0.32.0
+ hooks:
+ - id: yapf
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v4.5.0
+ hooks:
+ - id: trailing-whitespace
+ - id: check-yaml
+ - id: end-of-file-fixer
+ - id: requirements-txt-fixer
+ - id: double-quote-string-fixer
+ - id: check-merge-conflict
+ - id: fix-encoding-pragma
+ args: ["--remove"]
+ - id: mixed-line-ending
+ args: ["--fix=lf"]
+ - repo: https://github.com/executablebooks/mdformat
+ rev: 0.7.17
+ hooks:
+ - id: mdformat
+ args: ["--number"]
+ additional_dependencies:
+ - mdformat-openmmlab
+ - mdformat_frontmatter
+ - linkify-it-py
+ - repo: https://github.com/codespell-project/codespell
+ rev: v2.2.6
+ hooks:
+ - id: codespell
+ - repo: https://github.com/asottile/pyupgrade
+ rev: v3.15.0
+ hooks:
+ - id: pyupgrade
+ args: ["--py36-plus"]
diff --git a/.pylintrc b/.pylintrc
new file mode 100644
index 0000000000000000000000000000000000000000..73cb3ae572175832826c1b6386caaedf9aa037bd
--- /dev/null
+++ b/.pylintrc
@@ -0,0 +1,428 @@
+# This Pylint rcfile contains a best-effort configuration to uphold the
+# best-practices and style described in the Google Python style guide:
+# https://google.github.io/styleguide/pyguide.html
+#
+# Its canonical open-source location is:
+# https://google.github.io/styleguide/pylintrc
+
+[MASTER]
+
+# Files or directories to be skipped. They should be base names, not paths.
+ignore=third_party,storage
+
+# Files or directories matching the regex patterns are skipped. The regex
+# matches against base names, not paths.
+ignore-patterns=
+
+# Pickle collected data for later comparisons.
+persistent=no
+
+# List of plugins (as comma separated values of python modules names) to load,
+# usually to register additional checkers.
+load-plugins=
+
+# Use multiple processes to speed up Pylint.
+jobs=4
+
+# Allow loading of arbitrary C extensions. Extensions are imported into the
+# active Python interpreter and may run arbitrary code.
+unsafe-load-any-extension=no
+
+
+[MESSAGES CONTROL]
+
+# Only show warnings with the listed confidence levels. Leave empty to show
+# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
+confidence=
+
+# Enable the message, report, category or checker with the given id(s). You can
+# either give multiple identifier separated by comma (,) or put this option
+# multiple time (only on the command line, not in the configuration file where
+# it should appear only once). See also the "--disable" option for examples.
+#enable=
+
+# Disable the message, report, category or checker with the given id(s). You
+# can either give multiple identifiers separated by comma (,) or put this
+# option multiple times (only on the command line, not in the configuration
+# file where it should appear only once).You can also use "--disable=all" to
+# disable everything first and then reenable specific checks. For example, if
+# you want to run only the similarities checker, you can use "--disable=all
+# --enable=similarities". If you want to run only the classes checker, but have
+# no Warning level messages displayed, use"--disable=all --enable=classes
+# --disable=W"
+disable=abstract-method,
+ apply-builtin,
+ arguments-differ,
+ attribute-defined-outside-init,
+ backtick,
+ bad-option-value,
+ basestring-builtin,
+ buffer-builtin,
+ c-extension-no-member,
+ consider-using-enumerate,
+ cmp-builtin,
+ cmp-method,
+ coerce-builtin,
+ coerce-method,
+ delslice-method,
+ div-method,
+ duplicate-code,
+ eq-without-hash,
+ execfile-builtin,
+ file-builtin,
+ filter-builtin-not-iterating,
+ fixme,
+ getslice-method,
+ global-statement,
+ hex-method,
+ idiv-method,
+ implicit-str-concat,
+ import-error,
+ import-self,
+ import-star-module-level,
+ inconsistent-return-statements,
+ input-builtin,
+ intern-builtin,
+ invalid-str-codec,
+ locally-disabled,
+ long-builtin,
+ long-suffix,
+ map-builtin-not-iterating,
+ misplaced-comparison-constant,
+ missing-function-docstring,
+ metaclass-assignment,
+ next-method-called,
+ next-method-defined,
+ no-absolute-import,
+ no-else-break,
+ no-else-continue,
+ no-else-raise,
+ no-else-return,
+ no-init, # added
+ no-member,
+ no-name-in-module,
+ no-self-use,
+ nonzero-method,
+ oct-method,
+ old-division,
+ old-ne-operator,
+ old-octal-literal,
+ old-raise-syntax,
+ parameter-unpacking,
+ print-statement,
+ raising-string,
+ range-builtin-not-iterating,
+ raw_input-builtin,
+ rdiv-method,
+ reduce-builtin,
+ relative-import,
+ reload-builtin,
+ round-builtin,
+ setslice-method,
+ signature-differs,
+ standarderror-builtin,
+ suppressed-message,
+ sys-max-int,
+ too-few-public-methods,
+ too-many-ancestors,
+ too-many-arguments,
+ too-many-boolean-expressions,
+ too-many-branches,
+ too-many-instance-attributes,
+ too-many-locals,
+ too-many-nested-blocks,
+ too-many-public-methods,
+ too-many-return-statements,
+ too-many-statements,
+ trailing-newlines,
+ unichr-builtin,
+ unicode-builtin,
+ unnecessary-pass,
+ unpacking-in-except,
+ useless-else-on-loop,
+ useless-object-inheritance,
+ useless-suppression,
+ using-cmp-argument,
+ wrong-import-order,
+ xrange-builtin,
+ zip-builtin-not-iterating,
+
+
+[REPORTS]
+
+# Set the output format. Available formats are text, parseable, colorized, msvs
+# (visual studio) and html. You can also give a reporter class, eg
+# mypackage.mymodule.MyReporterClass.
+output-format=colorized
+
+# Tells whether to display a full report or only the messages
+reports=no
+
+# Python expression which should return a note less than 10 (10 is the highest
+# note). You have access to the variables errors warning, statement which
+# respectively contain the number of errors / warnings messages and the total
+# number of statements analyzed. This is used by the global evaluation report
+# (RP0004).
+evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
+
+# Template used to display messages. This is a python new-style format string
+# used to format the message information. See doc for all details
+#msg-template=
+
+
+[BASIC]
+
+# Good variable names which should always be accepted, separated by a comma
+good-names=main,_
+
+# Bad variable names which should always be refused, separated by a comma
+bad-names=
+
+# Colon-delimited sets of names that determine each other's naming style when
+# the name regexes allow several styles.
+name-group=
+
+# Include a hint for the correct naming format with invalid-name
+include-naming-hint=no
+
+# List of decorators that produce properties, such as abc.abstractproperty. Add
+# to this list to register other decorators that produce valid properties.
+property-classes=abc.abstractproperty,cached_property.cached_property,cached_property.threaded_cached_property,cached_property.cached_property_with_ttl,cached_property.threaded_cached_property_with_ttl
+
+# Regular expression matching correct function names
+function-rgx=^(?:(?P
MindSearch is an open-source AI Search Engine Framework with Perplexity.ai Pro performance. You can deploy your own Perplexity.ai-style search engine using either closed-source LLMs (GPT, Claude) or open-source LLMs (InternLM2.5-7b-chat).
""") - gr.HTML(""" - - """) + response = ( + agent_message["formatted"]["action"] + if agent_message["stream_state"] + in [AgentStatusCode.CODING, AgentStatusCode.CODE_END] + else agent_message["formatted"] and agent_message["formatted"].get("thought") + ) + format_response(history_planner, agent_message, response, -2) + if agent_message["stream_state"] == AgentStatusCode.END: + PLANNER_HISTORY = history_planner + yield history_planner, history_searcher, node_cnt + return history_planner, history_searcher, node_cnt + + +with gr.Blocks(css=os.path.join(os.path.dirname(__file__), "css", "gradio_front.css")) as demo: + with gr.Column(elem_classes="chat-box"): + gr.HTML("""+ MindSearch is an open-source AI Search Engine Framework with Perplexity.ai Pro performance. + You can deploy your own Perplexity.ai-style search engine using either + closed-source LLMs (GPT, Claude) + or open-source LLMs (InternLM2.5-7b-chat).
""" + ) + gr.HTML( + """ + """ + ) + gr.HTML( + """ + """ + ) + node_count = gr.State(0) with gr.Row(): - with gr.Column(scale=10): - with gr.Row(): - with gr.Column(): - planner = gr.Chatbot(label='planner', - height=700, - show_label=True, - show_copy_button=True, - bubble_full_width=False, - render_markdown=True) - with gr.Column(): - searcher = gr.Chatbot(label='searcher', - height=700, - show_label=True, - show_copy_button=True, - bubble_full_width=False, - render_markdown=True) - with gr.Row(): - user_input = gr.Textbox(show_label=False, - placeholder='inputs...', - lines=5, - container=False) - with gr.Row(): - with gr.Column(scale=2): - submitBtn = gr.Button('Submit') - with gr.Column(scale=1, min_width=20): - emptyBtn = gr.Button('Clear History') + planner = AgentChatbot( + label="planner", + height=600, + show_label=True, + show_copy_button=True, + bubble_full_width=False, + render_markdown=True, + elem_classes="chatbot-container", + ) + searcher = AgentChatbot( + label="searcher", + height=600, + show_label=True, + show_copy_button=True, + bubble_full_width=False, + render_markdown=True, + elem_classes="chatbot-container", + ) + with gr.Row(elem_classes="chat-box"): + # Text input area + user_input = gr.Textbox( + show_label=False, + placeholder="Type your message...", + lines=1, + container=False, + elem_classes="editor", + scale=4, + ) + # Buttons (now in the same Row) + submitBtn = gr.Button("submit", variant="primary", elem_classes="toolbarButton", scale=1) + clearBtn = gr.Button("clear", variant="secondary", elem_classes="toolbarButton", scale=1) + with gr.Row(elem_classes="examples-container"): + examples_component = gr.Examples( + [ + ["Find legal precedents in contract law."], + ["What are the top 10 e-commerce websites?"], + ["Generate a report on global climate change."], + ], + inputs=user_input, + label="Try these examples:", + ) def user(query, history): - return '', history + [[query, '']] + history.append(ChatMessage(role="user", content=query)) + history.append(ChatMessage(role="assistant", content="")) + graph_path = draw_search_graph({"root": []}) + history.append( + ChatFileMessage( + role="assistant", + file=gr.FileData(path=graph_path, mime_type=mimetypes.guess_type(graph_path)[0]), + ) + ) + return "", history - submitBtn.click(user, [user_input, planner], [user_input, planner], - queue=False).then(predict, [planner, searcher], - [planner, searcher]) - emptyBtn.click(rst_mem, [planner, searcher], [planner, searcher], - queue=False) + submitBtn.click(user, [user_input, planner], [user_input, planner], queue=False).then( + predict, + [planner, searcher, node_count], + [planner, searcher, node_count], + ) + clearBtn.click(rst_mem, None, [planner, searcher, node_count], queue=False) demo.queue() -demo.launch(server_name='0.0.0.0', - server_port=7860, - inbrowser=True, - share=True) +demo.launch() +# demo.launch(server_name="0.0.0.0", inbrowser=True, share=False) diff --git a/dist/assets/logo-38417354.svg b/assets/logo.svg similarity index 100% rename from dist/assets/logo-38417354.svg rename to assets/logo.svg diff --git a/assets/mindsearch_openset.png b/assets/mindsearch_openset.png new file mode 100644 index 0000000000000000000000000000000000000000..dec7d847debffa47e0216e6c9befbe32f46077ec --- /dev/null +++ b/assets/mindsearch_openset.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f40b4523db6ab851573642b438503c7c644ba989fd3c6a83d05bd32c0aa558f2 +size 117655 diff --git a/assets/teaser.gif b/assets/teaser.gif new file mode 100644 index 0000000000000000000000000000000000000000..cd978577ea8e860ef6f00501f7d8415e6ef5b5ca --- /dev/null +++ b/assets/teaser.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c0e6cd23ade8a36c7e94b6c204d0cf74a5e5a5baa8200571555fcc9183f28612 +size 3283087 diff --git a/backend_example.py b/backend_example.py new file mode 100644 index 0000000000000000000000000000000000000000..cea5b5c8a0e475d06e1198d63ffc2497c658cf39 --- /dev/null +++ b/backend_example.py @@ -0,0 +1,37 @@ +import json + +import requests + +# Define the backend URL +url = "http://localhost:8002/solve" +headers = {"Content-Type": "application/json"} + + +# Function to send a query to the backend and get the response +def get_response(query): + # Prepare the input data + data = {"inputs": query} + + # Send the request to the backend + response = requests.post(url, headers=headers, data=json.dumps(data), timeout=20, stream=True) + + # Process the streaming response + for chunk in response.iter_lines(chunk_size=8192, decode_unicode=False, delimiter=b"\n"): + if chunk: + decoded = chunk.decode("utf-8") + if decoded == "\r": + continue + if decoded[:6] == "data: ": + decoded = decoded[6:] + elif decoded.startswith(": ping - "): + continue + response_data = json.loads(decoded) + agent_return = response_data["response"] + node_name = response_data["current_node"] + print(f"Node: {node_name}, Response: {agent_return['response']}") + + +# Example usage +if __name__ == "__main__": + query = "What is the weather like today in New York?" + get_response(query) diff --git a/dist/assets/background-95159880.png b/dist/assets/background-95159880.png deleted file mode 100644 index 3c732cb6bbf084415e5cc309934a144e9bc6b5eb..0000000000000000000000000000000000000000 Binary files a/dist/assets/background-95159880.png and /dev/null differ diff --git a/dist/assets/index-327d01f5.js b/dist/assets/index-327d01f5.js deleted file mode 100644 index 3cb6f38a0a22420a9f4790ea197021a6f2edd558..0000000000000000000000000000000000000000 --- a/dist/assets/index-327d01f5.js +++ /dev/null @@ -1,72 +0,0 @@ -function YH(){import.meta.url,import("_").catch(()=>1);async function*e(){}}function fy(e,t){for(var n=0;nD?(P.sortIndex=C,t(l,P),n(s)===null&&P===n(l)&&(b?(v(R),R=-1):b=!0,L(_,C-D))):(P.sortIndex=W,t(s,P),y||m||(y=!0,H(x))),P},e.unstable_shouldYield=F,e.unstable_wrapCallback=function(P){var $=h;return function(){var C=h;h=$;try{return P.apply(this,arguments)}finally{h=C}}}})(Ay);xy.exports=Ay;var G_=xy.exports;/**
- * @license React
- * react-dom.production.min.js
- *
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */var K_=p,zn=G_;function ne(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n