diff --git a/AgentVerseIO/BaseIO.py b/AgentVerseIO/BaseIO.py
new file mode 100644
index 000000000..facc2fe3e
--- /dev/null
+++ b/AgentVerseIO/BaseIO.py
@@ -0,0 +1,32 @@
+from AgentVerseIO.input.CommandLineInput import CommandLineInput
+from AgentVerseIO.input.base import BaseInput
+from AgentVerseIO.output.CommandLineOutput import CommandLineOutput
+from AgentVerseIO.output.base import BaseOutput
+
+
+class AgentVerseIO:
+ def __init__(self, input: BaseInput, output: BaseOutput) -> None:
+ if input is None:
+ self.Input = CommandLineInput()
+ else:
+ if not isinstance(input, BaseInput):
+ raise TypeError("input must be a BaseInput instance")
+
+ self.Input = input
+
+ if output is None:
+ self.Output = CommandLineOutput()
+ else:
+ if not isinstance(output, BaseOutput):
+ raise TypeError("output must be a BaseOutput instance")
+
+ self.Output = output
+
+ def set_logger(self, logger):
+ self.logger = logger
+ self.Input.set_logger(logger)
+ self.Output.set_logger(logger)
+
+ def close(self):
+ self.Input.close()
+ self.Output.close()
diff --git a/AgentVerseIO/exception.py b/AgentVerseIO/exception.py
new file mode 100644
index 000000000..fd25d7f97
--- /dev/null
+++ b/AgentVerseIO/exception.py
@@ -0,0 +1,124 @@
+class AgentVerseIOError(Exception):
+ """Base class for exceptions in this module."""
+
+ pass
+
+
+class AgentVerseIOInterruptError(AgentVerseIOError):
+ """Exception raised for errors in the input.
+
+ Attributes:
+ message -- explanation of the error
+ """
+
+ def __init__(self, message="AgentVerse IO Interrupt!"):
+ self.message = message
+ super().__init__(self.message)
+
+
+class AgentVerseIOTimeoutError(AgentVerseIOError):
+ """Exception raised for errors in the input.
+
+ Attributes:
+ message -- explanation of the error
+ """
+
+ def __init__(self, message="AgentVerse IO Timeout!"):
+ self.message = message
+ super().__init__(self.message)
+
+
+class AgentVerseIOCloseError(AgentVerseIOError):
+ """Exception raised for errors in the input.
+
+ Attributes:
+ message -- explanation of the error
+ """
+
+ def __init__(self, message="AgentVerse IO Close!"):
+ self.message = message
+ super().__init__(self.message)
+
+
+class AgentVerseIOWebSocketError(AgentVerseIOError):
+ """Exception raised for errors in the input.
+
+ Attributes:
+ message -- explanation of the error
+ """
+
+ def __init__(self, message="AgentVerse IO WebSocket Error!"):
+ self.message = message
+ super().__init__(self.message)
+
+
+class AgentVerseIOWebSocketTimeoutError(AgentVerseIOWebSocketError):
+ """Exception raised for errors in the input.
+
+ Attributes:
+ message -- explanation of the error
+ """
+
+ def __init__(self, message="AgentVerse IO WebSocket Timeout!"):
+ self.message = message
+ super().__init__(self.message)
+
+
+class AgentVerseIOWebSocketDisconnectError(AgentVerseIOWebSocketError):
+ """Exception raised for errors in the input.
+
+ Attributes:
+ message -- explanation of the error
+ """
+
+ def __init__(self, message="AgentVerse IO WebSocket Disconnect!"):
+ self.message = message
+ super().__init__(self.message)
+
+
+class AgentVerseIOWebSocketConnectError(AgentVerseIOWebSocketError):
+ """Exception raised for errors in the input.
+
+ Attributes:
+ message -- explanation of the error
+ """
+
+ def __init__(self, message="AgentVerse IO WebSocket Connect Error!"):
+ self.message = message
+ super().__init__(self.message)
+
+
+class AgentVerseIOWebSocketCloseError(AgentVerseIOWebSocketError):
+ """Exception raised for errors in the input.
+
+ Attributes:
+ message -- explanation of the error
+ """
+
+ def __init__(self, message="AgentVerse IO WebSocket Close!"):
+ self.message = message
+ super().__init__(self.message)
+
+
+class AgentVerseIOWebSocketSendError(AgentVerseIOWebSocketError):
+ """Exception raised for errors in the input.
+
+ Attributes:
+ message -- explanation of the error
+ """
+
+ def __init__(self, message="AgentVerse IO WebSocket Send Error!"):
+ self.message = message
+ super().__init__(self.message)
+
+
+class AgentVerseIOWebSocketReceiveError(AgentVerseIOWebSocketError):
+ """Exception raised for errors in the input.
+
+ Attributes:
+ message -- explanation of the error
+ """
+
+ def __init__(self, message="AgentVerse IO WebSocket Receive Error!"):
+ self.message = message
+ super().__init__(self.message)
diff --git a/AgentVerseIO/input/CommandLineInput.py b/AgentVerseIO/input/CommandLineInput.py
new file mode 100644
index 000000000..ad5d9fae1
--- /dev/null
+++ b/AgentVerseIO/input/CommandLineInput.py
@@ -0,0 +1,95 @@
+import asyncio
+import functools
+import time
+from colorama import Fore
+from AgentVerseIO.exception import AgentVerseIOCloseError, AgentVerseIOTimeoutError
+from AgentVerseIO.input.base import BaseInput
+from inputimeout import inputimeout, TimeoutOccurred
+import math
+
+
+def timer(func):
+ @functools.wraps(func)
+ def wrapper(*args, **kwargs):
+ try:
+ start_time = time.time()
+ result = func(*args, **kwargs)
+ end_time = time.time()
+ except:
+ pass
+
+ return wrapper
+
+
+class CommandLineInput(BaseInput):
+ def __init__(self, do_interrupt: bool = False, max_wait_seconds: int = 600):
+ super().__init__(do_interrupt, max_wait_seconds)
+
+ async def run(self, input_data):
+ if self.do_interrupt:
+ data = await self.interrupt(input_data)
+ else:
+ data = input_data
+ return data
+
+ async def get_each_input(self, key, value, res, timeout):
+ self.logger.typewriter_log(
+ f"Now, ASK For {key}, Origin Input: {value}", Fore.RED, f""
+ )
+ self.logger.typewriter_log(
+ f"Now, you can modify the current field by entering some information, and then press 'Enter' to continue, if you want to keep the original input, please enter '-1' and then press 'Enter':",
+ Fore.GREEN,
+ )
+ temp = inputimeout(
+ prompt=f"You have {timeout} seconds to input:\n", timeout=timeout
+ )
+ if temp == "-1":
+ return value
+ else:
+ return temp
+
+ async def get_input(self, origin_data):
+ self.logger.typewriter_log(
+ "Next, you can start modifying the original input by typing 'Y/y/yes' or skip this step by typing 'N/n/no' and then press 'Enter' to continue the loop:",
+ Fore.RED,
+ )
+ update = inputimeout(
+ prompt=f"You have to make a decision within 60 seconds:\n", timeout=60
+ )
+ res = {"args": {}}
+ if update in ["y", "Y", "yes"]:
+ execute_time = self.max_wait_seconds
+ if isinstance(origin_data, dict):
+ args = origin_data.get("args", "")
+ self.logger.typewriter_log(
+ f"Next, you will have a total of {self.max_wait_seconds} seconds to modify each option:",
+ Fore.RED,
+ )
+ for key, value in args.items():
+ if key == "done":
+ res[key] = False
+ continue
+ start_time = time.time()
+ res["args"][key] = await self.get_each_input(
+ key, value, res, execute_time
+ )
+ end_time = time.time()
+ execute_time = math.floor(execute_time - (end_time - start_time))
+ self.logger.info(f"modify the input, receive the data: {res}")
+ else:
+ res = origin_data
+ self.logger.info("skip this step")
+ self.logger.info("continue the loop")
+ res["done"] = True
+ return res
+
+ async def interrupt(self, input_data):
+ try:
+ data = await self.get_input(input_data)
+ return data
+ except TimeoutOccurred:
+ self.logger.error(f"Waiting timemout, close connection!")
+ raise AgentVerseIOTimeoutError("timeout!")
+
+ def close(self):
+ raise AgentVerseIOCloseError("close connection!")
diff --git a/AgentVerseIO/input/HttpInput.py b/AgentVerseIO/input/HttpInput.py
new file mode 100644
index 000000000..c9f2c12e4
--- /dev/null
+++ b/AgentVerseIO/input/HttpInput.py
@@ -0,0 +1,9 @@
+from AgentVerseIO.input.base import BaseInput
+
+
+class HttpInput(BaseInput):
+ def __init__(self):
+ super().__init__()
+
+ def run(self):
+ raise NotImplementedError
diff --git a/AgentVerseIO/input/RestApiInput.py b/AgentVerseIO/input/RestApiInput.py
new file mode 100644
index 000000000..5987d7718
--- /dev/null
+++ b/AgentVerseIO/input/RestApiInput.py
@@ -0,0 +1,9 @@
+from AgentVerseIO.input.base import BaseInput
+
+
+class RestApiInput(BaseInput):
+ def __init__(self):
+ super().__init__()
+
+ def run(self):
+ raise NotImplementedError
diff --git a/AgentVerseIO/input/WebSocketInput.py b/AgentVerseIO/input/WebSocketInput.py
new file mode 100644
index 000000000..6e561afd1
--- /dev/null
+++ b/AgentVerseIO/input/WebSocketInput.py
@@ -0,0 +1,71 @@
+import asyncio
+import json
+
+from fastapi import WebSocket, WebSocketDisconnect
+
+from AgentVerseIO.exception import (
+ AgentVerseIOWebSocketDisconnectError,
+ AgentVerseIOWebSocketTimeoutError,
+)
+from AgentVerseIO.input.base import BaseInput
+from AgentVerseServer.loggers.logs import Logger
+from AgentVerseServer.response_body import WebsocketResponseBody
+
+
+class WebSocketInput(BaseInput):
+ def __init__(
+ self,
+ websocket: WebSocket,
+ do_interrupt: bool = False,
+ max_wait_seconds: int = 600,
+ ):
+ super().__init__(do_interrupt, max_wait_seconds)
+ self.websocket = websocket
+
+ def set_logger(self, logger: Logger):
+ self.logger = logger
+
+ def set_interrupt(self, do_interrupt: bool = True):
+ self.do_interrupt = do_interrupt
+
+ async def interrupt(self):
+ wait = 0
+ while wait < self.max_wait_seconds:
+ print(
+ f"\r waiting for {wait} second, remaining {self.max_wait_seconds - wait} second",
+ end="",
+ )
+ try:
+ data = await asyncio.wait_for(self.auto_receive(), 1)
+ if isinstance(data, dict):
+ data_type = data.get("type", None)
+ # if data_type == "ping":
+ # await self.websocket.send_json({"type": "pong"})
+ # continue
+ if data_type == "data":
+ self.logger.info(f"Receiving data change request...")
+ self.logger.info(f"Received :{data}")
+ wait = 0
+ return data
+ else:
+ pass
+ except asyncio.TimeoutError:
+ wait += 1
+ self.logger.error(f"Wait timeout, close.")
+ self.websocket.send_text(
+ WebsocketResponseBody(
+ data=None, status="failed", message="Wait timeout, close."
+ ).to_text()
+ )
+ raise AgentVerseIOWebSocketTimeoutError
+
+ async def auto_receive(self):
+ data = await self.websocket.receive_json()
+ return data
+
+ async def run(self, input):
+ if self.do_interrupt:
+ data = await self.interrupt()
+ return data
+ else:
+ return input
diff --git a/AgentVerseIO/input/base.py b/AgentVerseIO/input/base.py
new file mode 100644
index 000000000..473050e77
--- /dev/null
+++ b/AgentVerseIO/input/base.py
@@ -0,0 +1,27 @@
+from abc import ABCMeta, abstractmethod
+import asyncio
+
+from AgentVerseIO.exception import AgentVerseIOCloseError
+
+
+class BaseInput(metaclass=ABCMeta):
+ def __init__(self, do_interrupt: bool = False, max_wait_seconds: int = 600):
+ self.do_interrupt = do_interrupt
+ if self.do_interrupt:
+ self.max_wait_seconds = max_wait_seconds
+
+ def set_wait(self, do_interrupt: bool = True):
+ self.do_interrupt = do_interrupt
+
+ def set_logger(self, logger):
+ self.logger = logger
+
+ async def interrupt(self):
+ raise NotImplementedError
+
+ def run(self):
+ raise NotImplementedError
+
+ def close(self):
+ # raise AgentVerseIOCloseError("close connection!")
+ pass
diff --git a/AgentVerseIO/output/CommandLineOutput.py b/AgentVerseIO/output/CommandLineOutput.py
new file mode 100644
index 000000000..326495a33
--- /dev/null
+++ b/AgentVerseIO/output/CommandLineOutput.py
@@ -0,0 +1,13 @@
+from AgentVerseIO.exception import AgentVerseIOCloseError
+from AgentVerseIO.output.base import BaseOutput
+
+
+class CommandLineOutput(BaseOutput):
+ def __init__(self):
+ super().__init__()
+
+ async def run(self, output):
+ pass
+
+ def close(self):
+ raise AgentVerseIOCloseError("close connection!")
diff --git a/AgentVerseIO/output/HttpOutput.py b/AgentVerseIO/output/HttpOutput.py
new file mode 100644
index 000000000..ddad42e9b
--- /dev/null
+++ b/AgentVerseIO/output/HttpOutput.py
@@ -0,0 +1,9 @@
+from AgentVerseIO.output.base import BaseOutput
+
+
+class HttpOutput(BaseOutput):
+ def __init__(self):
+ super().__init__()
+
+ def run(self, output):
+ print(output)
diff --git a/AgentVerseIO/output/RestApiOutput.py b/AgentVerseIO/output/RestApiOutput.py
new file mode 100644
index 000000000..71047c6cb
--- /dev/null
+++ b/AgentVerseIO/output/RestApiOutput.py
@@ -0,0 +1,9 @@
+from AgentVerseIO.output.base import BaseOutput
+
+
+class RestApiOutput(BaseOutput):
+ def __init__(self):
+ super().__init__()
+
+ def run(self, output):
+ print(output)
diff --git a/AgentVerseIO/output/SSEOutput.py b/AgentVerseIO/output/SSEOutput.py
new file mode 100644
index 000000000..548fca0de
--- /dev/null
+++ b/AgentVerseIO/output/SSEOutput.py
@@ -0,0 +1,9 @@
+from AgentVerseIO.output.base import BaseOutput
+
+
+class SSEOutput(BaseOutput):
+ def __init__(self):
+ super().__init__()
+
+ def run(self, output):
+ print(output)
diff --git a/AgentVerseIO/output/WebSocketOutput.py b/AgentVerseIO/output/WebSocketOutput.py
new file mode 100644
index 000000000..71d841b83
--- /dev/null
+++ b/AgentVerseIO/output/WebSocketOutput.py
@@ -0,0 +1,22 @@
+import traceback
+from fastapi import WebSocket
+from AgentVerseIO.exception import AgentVerseIOWebSocketDisconnectError
+from AgentVerseIO.output.base import BaseOutput
+from AgentVerseServer.response_body import WebsocketResponseBody
+
+
+class WebSocketOutput(BaseOutput):
+ def __init__(self, websocket: WebSocket):
+ super().__init__()
+ self.websocket = websocket
+
+ def set_logger(self, logger):
+ self.logger = logger
+
+ async def run(self, output: dict):
+ try:
+ websocket_data = WebsocketResponseBody(**output).to_text()
+ await self.websocket.send_text(websocket_data)
+ except Exception as e:
+ self.logger.info(traceback.format_exc())
+ raise AgentVerseIOWebSocketDisconnectError
diff --git a/AgentVerseIO/output/base.py b/AgentVerseIO/output/base.py
new file mode 100644
index 000000000..da9977694
--- /dev/null
+++ b/AgentVerseIO/output/base.py
@@ -0,0 +1,18 @@
+from abc import ABCMeta, abstractmethod
+
+from AgentVerseIO.exception import AgentVerseIOCloseError
+
+
+class BaseOutput(metaclass=ABCMeta):
+ def __init__(self, kwargs: dict = None):
+ self.kwargs = kwargs
+
+ def set_logger(self, logger):
+ self.logger = logger
+
+ def run(self):
+ raise NotImplementedError
+
+ def close(self):
+ # raise AgentVerseIOCloseError("close connection!")
+ pass
diff --git a/AgentVerseServer/README.md b/AgentVerseServer/README.md
new file mode 100644
index 000000000..c2817b26f
--- /dev/null
+++ b/AgentVerseServer/README.md
@@ -0,0 +1,45 @@
+# AgentVerse-Server Frontend and Backend Demo
+
+This is a demo of the AgentVerse-Server frontend and backend. The backend communication is mainly implemented using fastapi's `websocket`, supplemented with essential restful APIs. The frontend service is deployed locally.
+
+
+## Launching AgentVerse-Server
+
+First, we ran web ui docker when build ToolServer network.
+
+This will start an instance of AgentVerse-Server listening to port `8090` on the local machine. The configuration details can be found in the `AgentVerseServer/docker-compose.yml` file.
+
+After completing the image compilation and startup, you need to start the nginx service. Execute the following command on another command line:
+
+```
+docker exec AgentVerse-Server systemctl start nginx
+```
+
+When you see the following output, it means the image has been successfully compiled and launched:
+
+![AgentVerse-Server成功示例](https://gitee.com/sailaoda/pic2/raw/master/2023/202309272123424.png)
+
+
+## Using AgentVerse-Server
+
+After completing the above steps, you can access the frontend interface by visiting http://localhost:5173 in a web browser. Default user: admin, token: agentverse-admin, you can use it to login. An example of the interface is shown below:
+
+![login](https://gitee.com/sailaoda/pic2/raw/master/2023/202309272130865.png)
+
+Once you're inside the AgentVerse-Server, you can start using it as demonstrated:
+
+![playground](https://gitee.com/sailaoda/pic2/raw/master/2023/202309272132478.png)
+
+## Additional Information
+
+If you are running this in a Windows environment, you might encounter an error while building the image, which looks like this: `AgentVerseServer/dockerfiles/build.sh: line 2: cd: $'AgentVerseServer/dockerfiles\r': No such file or directory` as shown below:
+
+![windows_build_docker](https://gitee.com/sailaoda/pic2/raw/master/2023/202309280213559.png)
+
+To resolve this, you can navigate to the directory first, then proceed with the compilation. Use the following commands:
+
+```bash
+cd AgentVerseServer/dockerfiles/
+bash build.sh
+```
+
diff --git a/AgentVerseServer/README_zh.md b/AgentVerseServer/README_zh.md
new file mode 100644
index 000000000..dc1955788
--- /dev/null
+++ b/AgentVerseServer/README_zh.md
@@ -0,0 +1,44 @@
+# AgentVerse-Server 前后端 Demo
+
+AgentVerse-Server 前后端 Demo,后端通信部分主要由fastapi的`websocket`实现,辅以必要的restful接口;前端服务进行本地部署。
+
+
+## 启动 AgentVerse-Server
+
+我们已经开启了web ui的docker镜像,在之前 build ToolServer 网络的时候。
+
+这将启动一个AgentVerse-Server实例,监听本机`8090`端口,配置信息在`AgentVerseServer/docker-compose.yml`文件中。
+
+完成镜像编译和启动后还需启动nginx服务,在另一个命令行执行如下命令:
+
+```
+docker exec AgentVerse-Server systemctl start nginx
+```
+
+出现如下输出,就是镜像编译与启动成功了:
+
+![AgentVerse-Server成功示例](https://gitee.com/sailaoda/pic2/raw/master/2023/202309272123424.png)
+
+
+## 使用 AgentVerse-Server
+完成上述操作后,浏览器访问 http://localhost:5173 即可进入前端界面,示例如下 (可以默认用户名: admin, token: agentverse-admin 进行登录):
+
+![login](https://gitee.com/sailaoda/pic2/raw/master/2023/202309272130865.png)
+
+进入 AgentVerse-Server 后即可开始使用,如下所示:
+
+![playground](https://gitee.com/sailaoda/pic2/raw/master/2023/202309272132478.png)
+
+## 其他
+
+如果您是在windows环境中运行,在编译镜像时可能会出现`AgentVerseServer/dockerfiles/build.sh: line 2: cd: $'AgentVerseServer/dockerfiles\r': No such file or directory`的报错情况,如下所示:
+
+![windows_build_docker](https://gitee.com/sailaoda/pic2/raw/master/2023/202309280213559.png)
+
+您可以先进入路径目录,在进行编译,即可解决,执行命令如下:
+
+```bash
+cd AgentVerseServer/dockerfiles/
+bash build.sh
+```
+
diff --git a/AgentVerseServer/database/__init__.py b/AgentVerseServer/database/__init__.py
new file mode 100644
index 000000000..f10ef166c
--- /dev/null
+++ b/AgentVerseServer/database/__init__.py
@@ -0,0 +1,121 @@
+from typing import Union
+
+from sqlalchemy.orm import Session
+
+from AgentVerseServer.envs import AgentVerseServerEnv
+from AgentVerseServer.models.interaction import InteractionBase
+from AgentVerseServer.models.parameter import InteractionParameter
+from AgentVerseServer.models.shared_interaction import SharedInteractionBase
+
+from typing import Union
+
+
+class UserBaseInterface:
+ """ """
+
+ def __init__(self, envs: AgentVerseServerEnv) -> None:
+ pass
+
+ def register_db(self, db: Session):
+ self.db = db
+
+ def init(self):
+ raise NotImplementedError
+
+ def get_user_list(self) -> list:
+ raise NotImplementedError
+
+ def get_user_dict_list(self):
+ raise NotImplementedError
+
+ def get_user(
+ self, user_id: Union[str, None] = None, email: Union[str, None] = None
+ ):
+ raise NotImplementedError
+
+ def user_is_exist(
+ self, user_id: Union[str, None] = None, email: Union[str, None] = None
+ ):
+ raise NotImplementedError
+
+ def token_is_exist(self, user_id: str, token: Union[str, None] = None):
+ raise NotImplementedError
+
+ def user_is_valid(
+ self,
+ user_id: Union[str, None] = None,
+ email: Union[str, None] = None,
+ token: Union[str, None] = None,
+ ):
+ raise NotImplementedError
+
+ def add_user(self, user_dict: dict):
+ raise NotImplementedError
+
+ def update_user(self, user):
+ raise NotImplementedError
+
+
+class InteractionBaseInterface:
+ def __init__(self, envs: AgentVerseServerEnv) -> None:
+ pass
+
+ def register_db(self, db: Session):
+ self.db = db
+
+ def init(self):
+ raise NotImplementedError
+
+ def get_interaction_dict_list(self):
+ raise NotImplementedError
+
+ def get_interaction_list(self) -> list:
+ raise NotImplementedError
+
+ def get_interaction(self, interaction_id: str) -> InteractionBase:
+ raise NotImplementedError
+
+ def create_interaction(self, interaction: InteractionBase):
+ raise NotImplementedError
+
+ def add_parameter(self, parameter: InteractionParameter):
+ raise NotImplementedError
+
+ def get_interaction_by_user_id(self, user_id: str) -> list:
+ raise NotImplementedError
+
+ def get_shared_interactions(self, page_size: int = 20, page_index: int = 1):
+ raise NotImplementedError
+
+ def get_interaction_by_interaction_id(self, interaction_id: str):
+ raise NotImplementedError
+
+ def interaction_is_exist(self, interaction_id: str):
+ raise NotImplementedError
+
+ def update_interaction(self, interaction: InteractionBase):
+ raise NotImplementedError
+
+ def update_interaction_status(
+ self, interaction_id: str, status: str, message: str, current_step: int
+ ):
+ raise NotImplementedError
+
+ def update_interaction_parameter(
+ self, interaction_id: str, parameter: InteractionParameter
+ ):
+ raise NotImplementedError
+
+ def is_running(self, user_id: str):
+ raise NotImplementedError
+
+ def delete_interaction(self, interaction_id: str):
+ raise NotImplementedError
+
+ def add_share(self, shared: SharedInteractionBase):
+ raise NotImplementedError
+
+ def get_shared_interaction(
+ self, interaction_id: str
+ ) -> Union[SharedInteractionBase, None]:
+ raise NotImplementedError
diff --git a/AgentVerseServer/database/connect.py b/AgentVerseServer/database/connect.py
new file mode 100644
index 000000000..30ea562b4
--- /dev/null
+++ b/AgentVerseServer/database/connect.py
@@ -0,0 +1,30 @@
+from sqlalchemy import create_engine
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import sessionmaker
+
+from AgentVerseServer.database.models import Base
+from AgentVerseServer.envs import AgentVerseServerEnv
+
+
+class DBConnection:
+ def __init__(self, envs: AgentVerseServerEnv) -> None:
+ if envs.DB.db_type == "file":
+ raise ValueError(
+ "Require a sql database, such as sqlite, mysql, postgresql"
+ )
+
+ SQLALCHEMY_DATABASE_URL = envs.DB.db_url
+
+ engine = create_engine(
+ SQLALCHEMY_DATABASE_URL,
+ pool_size=10,
+ max_overflow=2,
+ pool_timeout=30,
+ pool_recycle=-1,
+ )
+
+ # Base.metadata.create_all(bind=engine)
+
+ SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
+
+ self.db_session = SessionLocal()
diff --git a/AgentVerseServer/database/dbi.py b/AgentVerseServer/database/dbi.py
new file mode 100644
index 000000000..c1ac03578
--- /dev/null
+++ b/AgentVerseServer/database/dbi.py
@@ -0,0 +1,386 @@
+import traceback
+from datetime import datetime
+
+from sqlalchemy.orm import Session
+from sqlalchemy.sql import func
+from typing import Union
+from AgentVerseServer.database import InteractionBaseInterface, UserBaseInterface
+from AgentVerseServer.database.models import (
+ Interaction,
+ Parameter,
+ SharedInteraction,
+ User,
+)
+from AgentVerseServer.envs import AgentVerseServerEnv
+from AgentVerseServer.models.interaction import InteractionBase
+from AgentVerseServer.models.parameter import InteractionParameter
+from AgentVerseServer.models.shared_interaction import SharedInteractionBase
+from AgentVerseServer.models.user import AgentVerseUser
+
+
+class UserDBInterface(UserBaseInterface):
+ def __init__(self, envs: AgentVerseServerEnv) -> None:
+ if envs.DB.use_db and envs.DB.db_type == "file":
+ raise ValueError(
+ "UserDB except a sql database, such as sqlite, mysql, postgresql"
+ )
+ self.db_url = envs.DB.db_url
+
+ def register_db(self, db: Session):
+ self.db = db
+
+ def init(self):
+ raise NotImplementedError
+
+ def get_user_list(self) -> list[AgentVerseUser]:
+ users = self.db.query(User).all()
+ users = [AgentVerseUser.from_db(user) for user in users]
+ return users
+
+ def get_user_dict_list(self):
+ return self.user_list_cache
+
+ def get_user(
+ self, user_id: Union[str, None] = None, email: Union[str, None] = None
+ ) -> Union[AgentVerseUser, None]:
+ if not email and not user_id:
+ return None
+ if email:
+ user = (
+ self.db.query(User)
+ .filter(User.email == email, User.deleted == False)
+ .first()
+ )
+ else:
+ user = (
+ self.db.query(User)
+ .filter(User.user_id == user_id, User.deleted == False)
+ .first()
+ )
+
+ return AgentVerseUser.from_db(user) if user else None
+
+ def user_is_exist(
+ self, user_id: Union[str, None] = None, email: Union[str, None] = None
+ ):
+ if not email and not user_id:
+ return False
+ if email:
+ user = (
+ self.db.query(User)
+ .filter(User.email == email, User.deleted == False)
+ .first()
+ )
+ else:
+ user = (
+ self.db.query(User)
+ .filter(User.user_id == user_id, User.deleted == False)
+ .first()
+ )
+ return user is not None
+
+ def token_is_exist(self, user_id: str, token: Union[str, None] = None):
+ if not token:
+ return False
+
+ user = (
+ self.db.query(User)
+ .filter(User.user_id == user_id, User.token == token, User.deleted == False)
+ .first()
+ )
+ return user is not None
+
+ def user_is_valid(
+ self,
+ user_id: Union[str, None] = None,
+ email: Union[str, None] = None,
+ token: Union[str, None] = None,
+ ):
+ if email == "":
+ return False
+ user = (
+ self.db.query(User)
+ .filter(User.user_id == user_id, User.token == token, User.deleted == False)
+ .first()
+ )
+ if token == None:
+ if user.email == email and user.available:
+ return True
+ if user_id != None:
+ if user.user_id == user_id and user.token == token and user.available:
+ return True
+ if email != None:
+ if user.email == email and user.token == token and user.available:
+ return True
+ return False
+
+ def add_user(self, user_dict: dict):
+ try:
+ self.db.add(User(**user_dict))
+ self.db.commit()
+ except Exception as e:
+ self.db.rollback()
+ print(traceback.print_exec())
+
+ def update_user(self, user: AgentVerseUser):
+ db_user = (
+ self.db.query(User)
+ .filter(User.user_id == user.user_id, User.deleted == False)
+ .first()
+ )
+ try:
+ db_user.available = user.available
+ db_user.email = user.email
+ db_user.name = user.name
+ db_user.token = user.token
+ db_user.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+ self.db.commit()
+ except Exception as e:
+ self.db.rollback()
+ print(traceback.print_exec())
+
+
+class InteractionDBInterface(InteractionBaseInterface):
+ def __init__(self, envs: AgentVerseServerEnv) -> None:
+ super().__init__(envs)
+ if envs.DB.use_db and envs.DB.db_type not in ["sqlite", "mysql", "postgresql"]:
+ raise ValueError(
+ "UserDB except a sql database, such as sqlite, mysql, postgresql"
+ )
+ self.db_url = envs.DB.db_url
+
+ def register_db(self, db: Session):
+ self.db = db
+
+ def init(self):
+ """
+ not use
+ """
+ raise NotImplementedError
+
+ def get_interaction_dict_list(self):
+ raise NotImplementedError
+
+ def get_interaction_list(self) -> list[InteractionBase]:
+ interactions = self.db.query(Interaction).all()
+ return [InteractionBase.from_db(interaction) for interaction in interactions]
+
+ def get_interaction(self, interaction_id: str) -> Union[InteractionBase, None]:
+ interaction = (
+ self.db.query(Interaction)
+ .filter(Interaction.interaction_id == interaction_id)
+ .first()
+ )
+ return InteractionBase.from_db(interaction) if interaction else None
+
+ def create_interaction(self, base: InteractionBase) -> InteractionBase:
+ """
+ 创建一个对话
+ """
+ try:
+ self.db.add(Interaction(**base.to_dict()))
+ self.db.commit()
+ except Exception as e:
+ self.db.rollback()
+ print(traceback.print_exec())
+ return None
+
+ def add_parameter(self, parameter: InteractionParameter):
+ """
+ 创建一个对话
+ """
+ try:
+ self.db.add(Parameter(**parameter.to_dict()))
+ self.db.commit()
+ except Exception as e:
+ self.db.rollback()
+ print(traceback.print_exec())
+
+ return None
+
+ def get_interaction_by_user_id(
+ self, user_id: str, page_size: int = 20, page_num: int = 1
+ ) -> list[dict]:
+ """
+ 查看对话历史
+ """
+ total = (
+ self.db.query(func.count(Interaction.id))
+ .filter(Interaction.user_id == user_id, Interaction.is_deleted == False)
+ .scalar()
+ )
+ interaction_list = (
+ self.db.query(Interaction)
+ .filter(Interaction.user_id == user_id, Interaction.is_deleted == False)
+ .limit(page_size)
+ .offset((page_num - 1) * page_size)
+ .all()
+ )
+ data = []
+ for i, interaction in enumerate(interaction_list):
+ d_ = InteractionBase.from_db(interaction).to_dict(
+ exclude=["recorder_root_dir", "is_deleted"]
+ )
+ parameter = [
+ {**p.args} if isinstance(p.args, dict) else p.args
+ for p in self.get_parameter(d_["interaction_id"])
+ ]
+ d_["parameters"] = parameter
+ data.append(d_)
+ return {"total": total, "rows": data}
+
+ def get_shared_interactions(
+ self, page_size: int = 20, page_num: int = 1
+ ) -> list[dict]:
+ """
+ 获取社区分享的数据
+ """
+ total = (
+ self.db.query(func.count(SharedInteraction.id))
+ .filter(SharedInteraction.is_deleted == False)
+ .scalar()
+ )
+ interaction_list = (
+ self.db.query(SharedInteraction)
+ .filter(SharedInteraction.is_deleted == False)
+ .order_by(SharedInteraction.star.desc())
+ .limit(page_size)
+ .offset((page_num - 1) * page_size)
+ .all()
+ )
+ data = []
+ for i, interaction in enumerate(interaction_list):
+ d_ = SharedInteractionBase.from_db(interaction).to_dict(
+ exclude=["record_dir", "is_deleted"]
+ )
+ parameter = [
+ {**p.args} if isinstance(p.args, dict) else p.args
+ for p in self.get_parameter(d_["interaction_id"])
+ ]
+ d_["parameters"] = parameter
+ data.append(d_)
+ return {"total": total, "rows": data}
+
+ def get_shared_interaction(
+ self, interaction_id: str
+ ) -> Union[SharedInteractionBase, None]:
+ interaction = (
+ self.db.query(SharedInteraction)
+ .filter(
+ SharedInteraction.interaction_id == interaction_id,
+ SharedInteraction.is_deleted == False,
+ )
+ .first()
+ )
+ return SharedInteractionBase.from_db(interaction) if interaction else None
+
+ def interaction_is_exist(self, interaction_id: str) -> bool:
+ interaction = (
+ self.db.query(Interaction)
+ .filter(
+ Interaction.interaction_id == interaction_id,
+ Interaction.is_deleted == False,
+ )
+ .first()
+ )
+ return interaction is not None
+
+ def update_interaction(self, base_data: dict):
+ try:
+ if "interaction_id" not in base_data:
+ raise ValueError("interaction_id is required")
+ interaction = (
+ self.db.query(Interaction)
+ .filter(Interaction.interaction_id == base_data["interaction_id"])
+ .first()
+ )
+ if interaction is None:
+ raise ValueError("interaction is not exist")
+ for k, v in base_data.items():
+ if k == "interaction_id":
+ continue
+ setattr(interaction, k, v)
+ interaction.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+ self.db.commit()
+ except Exception as e:
+ self.db.rollback()
+ print(traceback.print_exec())
+
+ def update_interaction_status(
+ self, interaction_id: str, status: str, message: str, current_step: int
+ ):
+ try:
+ db_interaction = (
+ self.db.query(Interaction)
+ .filter(Interaction.interaction_id == interaction_id)
+ .first()
+ )
+ db_interaction.status = status
+ db_interaction.message = message
+ db_interaction.current_step = current_step
+ db_interaction.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+ self.db.commit()
+ except Exception as e:
+ self.db.rollback()
+ print(traceback.print_exec())
+
+ def update_interaction_parameter(
+ self, interaction_id: str, parameter: InteractionParameter
+ ):
+ try:
+ db_parameter = (
+ self.db.query(Parameter)
+ .filter(
+ Parameter.interaction_id == interaction_id,
+ Parameter.parameter_id == parameter.parameter_id,
+ )
+ .first()
+ )
+ if db_parameter is None:
+ self.db.add(Parameter(**parameter.to_dict()))
+ self.db.commit()
+ except Exception as e:
+ self.db.rollback()
+ print(traceback.print_exec())
+
+ def is_running(self, user_id: str):
+ interaction = (
+ self.db.query(Interaction)
+ .filter(
+ Interaction.user_id == user_id,
+ Interaction.status.in_(("running", "waiting")),
+ )
+ .first()
+ )
+ return interaction is not None
+
+ def get_parameter(self, interaction_id: str):
+ parameters = (
+ self.db.query(Parameter)
+ .filter(Parameter.interaction_id == interaction_id)
+ .all()
+ )
+ return [InteractionParameter.from_db(param) for param in parameters]
+
+ def delete_interaction(self, interaction_id: str):
+ try:
+ interaction = (
+ self.db.query(Interaction)
+ .filter(Interaction.interaction_id == interaction_id)
+ .first()
+ )
+ if interaction is None:
+ raise ValueError("interaction is not exist")
+ interaction.is_deleted = True
+ self.db.commit()
+ except Exception as e:
+ self.db.rollback()
+ print(traceback.print_exec())
+
+ def add_share(self, shared: SharedInteractionBase):
+ try:
+ self.db.add(SharedInteraction(**shared.to_dict()))
+ self.db.commit()
+ except Exception as e:
+ self.db.rollback()
+ print(traceback.print_exec())
diff --git a/AgentVerseServer/database/lsi.py b/AgentVerseServer/database/lsi.py
new file mode 100644
index 000000000..dc3d76503
--- /dev/null
+++ b/AgentVerseServer/database/lsi.py
@@ -0,0 +1,364 @@
+import copy
+import json
+import os
+from datetime import datetime
+from typing import Union
+from sqlalchemy.orm import Session
+
+from AgentVerseServer.database import InteractionBaseInterface, UserBaseInterface
+from AgentVerseServer.envs import AgentVerseServerEnv
+from AgentVerseServer.interaction import InteractionParameter
+from AgentVerseServer.models.interaction import InteractionBase
+from AgentVerseServer.models.user import AgentVerseUser
+
+
+class UserLocalStorageInterface(UserBaseInterface):
+ def __init__(self, envs: AgentVerseServerEnv) -> None:
+ if envs.DB.db_type != "file":
+ raise ValueError("UserLocalStorageInterface only support file db")
+ try:
+ self.db_url = envs.DB.db_url.get("users", "users/users.json")
+ except Exception as e:
+ raise ValueError("UserLocalStorageInterface only support json file")
+ self.envs = envs
+ self.user_list_cache = []
+ self.init()
+
+ def register_db(self, db: Session):
+ self.db = db
+
+ def init(self):
+ if not os.path.exists(os.path.dirname(self.db_url)):
+ os.makedirs(os.path.dirname(self.db_url))
+
+ if not os.path.exists(self.db_url):
+ with open(self.db_url, "w", encoding="utf-8") as f:
+ if self.envs.default_login:
+ json.dump(
+ [
+ {
+ "user_id": "admin",
+ "email": "admin",
+ "token": "agentverse-admin",
+ "name": "admin",
+ "available": True,
+ "create_time": datetime.now().strftime(
+ "%Y-%m-%d %H:%M:%S"
+ ),
+ "update_time": datetime.now().strftime(
+ "%Y-%m-%d %H:%M:%S"
+ ),
+ "corporation": "agentverse",
+ "industry": "AI",
+ "position": "agentverse",
+ "deleted": False,
+ }
+ ],
+ f,
+ indent=2,
+ ensure_ascii=False,
+ )
+ else:
+ json.dump([], f, indent=2, ensure_ascii=False)
+
+ with open(self.db_url, "r", encoding="utf-8") as f:
+ self.user_list_cache = json.load(f)
+
+ def get_user_list(self) -> list:
+ users = []
+ for user_dict in self.user_list_cache:
+ users.append(AgentVerseUser(**user_dict))
+
+ return users
+
+ def get_user_dict_list(self):
+ return self.user_list_cache
+
+ def get_user(
+ self, user_id: Union[str, None] = None, email: Union[str, None] = None
+ ) -> Union[AgentVerseUser, None]:
+ if not email and not user_id:
+ return None
+ user_list = self.get_user_list()
+ for user in user_list:
+ if user.email == email and not user.deleted:
+ return user
+ if user.user_id == user_id and not user.deleted:
+ return user
+ return None
+
+ def user_is_exist(
+ self, user_id: Union[str, None] = None, email: Union[str, None] = None
+ ):
+ if not email and not user_id:
+ return False
+
+ user_list = self.get_user_list()
+
+ for user in user_list:
+ if user.email == email and not user.deleted:
+ return True
+ if user.user_id == user_id and not user.deleted:
+ return True
+ return False
+
+ def token_is_exist(self, user_id: str, token: Union[str, None] = None):
+ if not token:
+ return False
+
+ user_list = self.get_user_list()
+
+ for user in user_list:
+ if user.user_id == user_id and user.token == token and not user.deleted:
+ return True
+ return False
+
+ def user_is_valid(
+ self,
+ user_id: Union[str, None] = None,
+ email: Union[str, None] = None,
+ token: Union[str, None] = None,
+ ):
+ if email == "":
+ return False
+ user_list = self.get_user_list()
+ for user in user_list:
+ if token == None:
+ if user.email == email and user.available and not user.deleted:
+ return True
+ if user_id != None:
+ if (
+ user.user_id == user_id
+ and user.token == token
+ and user.available
+ and not user.deleted
+ ):
+ return True
+ if email != None:
+ if (
+ user.email == email
+ and user.token == token
+ and user.available
+ and not user.deleted
+ ):
+ return True
+ return False
+
+ def add_user(self, user_dict: dict):
+ self.user_list_cache.append(user_dict)
+ with open(self.db_url, "w", encoding="utf-8") as f:
+ json.dump(self.user_list_cache, f, indent=2, ensure_ascii=False)
+
+ def update_user(self, user: AgentVerseUser):
+ for i, user_dict in enumerate(self.user_list_cache):
+ if user.user_id == user_dict["user_id"]:
+ user_dict["available"] = user.available
+
+ with open(self.db_url, "w", encoding="utf-8") as f:
+ json.dump(self.user_list_cache, f, indent=2, ensure_ascii=False)
+
+
+class InteractionLocalStorageInterface(InteractionBaseInterface):
+ def __init__(self, envs: AgentVerseServerEnv) -> None:
+ super().__init__(envs)
+ if envs.DB.db_type != "file":
+ raise ValueError("InteractionLocalStorageInterface only support file db")
+ try:
+ self.db_url = envs.DB.db_url.get(
+ "interactions", "AgentVerseServer/localstorage/records/interaction.json"
+ )
+ self.parameter_url = envs.DB.db_url.get(
+ "parameter", "AgentVerseServer/localstorage/records/parameter.json"
+ )
+ except Exception as e:
+ raise ValueError("InteractionLocalStorageInterface only support json file")
+ self.interaction_list_cache = []
+ self.interaction_parameter_cache = []
+ self.init()
+
+ def register_db(self, db: Session):
+ self.db = db
+
+ def init(self):
+ if not os.path.exists(os.path.dirname(self.db_url)):
+ os.makedirs(os.path.dirname(self.db_url))
+
+ if not os.path.exists(self.db_url):
+ with open(self.db_url, "w", encoding="utf-8") as f:
+ json.dump([], f, indent=2, ensure_ascii=False)
+
+ if not os.path.exists(os.path.dirname(self.parameter_url)):
+ os.makedirs(os.path.dirname(self.parameter_url))
+
+ if not os.path.exists(self.parameter_url):
+ with open(self.parameter_url, "w", encoding="utf-8") as f:
+ json.dump({}, f, indent=2, ensure_ascii=False)
+
+ with open(self.db_url, "r", encoding="utf-8") as f:
+ self.interaction_list_cache = json.load(f)
+
+ with open(self.parameter_url, "r", encoding="utf-8") as f:
+ self.interaction_parameter_cache = json.load(f)
+
+ def get_interaction_dict_list(self):
+ interactions = copy.deepcopy(self.interaction_list_cache)
+ return interactions
+
+ def get_interaction_list(self) -> list:
+ interactions = copy.deepcopy(self.interaction_list_cache)
+ return interactions
+
+ def get_interaction(self, interaction_id: str) -> Union[InteractionBase, None]:
+ interaction_list = self.get_interaction_list()
+ for interaction in interaction_list:
+ if interaction["interaction_id"] == interaction_id:
+ return InteractionBase(**interaction)
+ return None
+
+ def create_interaction(self, base: InteractionBase):
+ self.interaction_list_cache.append(base.to_dict())
+ with open(self.db_url, "w", encoding="utf-8") as f:
+ json.dump(self.interaction_list_cache, f, indent=2, ensure_ascii=False)
+
+ def add_parameter(self, parameter: InteractionParameter = None):
+ if parameter is not None:
+ interaction_ids = [k for k in self.interaction_parameter_cache.keys()]
+ if parameter.interaction_id not in interaction_ids:
+ self.interaction_parameter_cache[parameter.interaction_id] = [
+ parameter.to_dict()
+ ]
+ else:
+ self.interaction_parameter_cache[parameter.interaction_id].append(
+ parameter.to_dict()
+ )
+
+ with open(self.parameter_url, "w", encoding="utf-8") as f:
+ json.dump(
+ self.interaction_parameter_cache, f, indent=2, ensure_ascii=False
+ )
+
+ def get_parameter(self, interaction_id: str) -> list[InteractionParameter]:
+ interaction_ids = [k for k in self.interaction_parameter_cache.keys()]
+ if interaction_id not in interaction_ids:
+ return []
+ else:
+ return [
+ InteractionParameter(**p)
+ for p in self.interaction_parameter_cache[interaction_id]
+ ]
+
+ def get_interaction_by_user_id(
+ self, user_id: str, page_size: int = 10, page_num: int = 1
+ ) -> list[dict]:
+ _data = []
+ interaction_list = self.get_interaction_list()
+ user_interaction_list = [
+ interaction
+ for interaction in interaction_list
+ if interaction["user_id"] == user_id and not interaction["is_deleted"]
+ ]
+ total = len(user_interaction_list)
+ user_interaction_list = user_interaction_list[::-1]
+ user_interaction_list = user_interaction_list[
+ (page_num - 1) * page_size : page_num * page_size
+ ]
+
+ for i, interaction in enumerate(user_interaction_list):
+ parameter = [
+ {**p.args} if isinstance(p.args, dict) else p.args
+ for p in self.get_parameter(interaction["interaction_id"])
+ ]
+ interaction["parameters"] = parameter
+ _data.append(interaction)
+ return {"total": total, "rows": user_interaction_list}
+
+ def get_interaction_by_interaction_id(
+ self, interaction_id: str
+ ) -> Union[InteractionBase, None]:
+ interaction_list = self.get_interaction_list()
+ for interaction in interaction_list:
+ if interaction["interaction_id"] == interaction_id:
+ return interaction
+ return None
+
+ def interaction_is_exist(self, interaction_id: str) -> bool:
+ interaction_list = self.get_interaction_list()
+ for interaction in interaction_list:
+ if (
+ interaction["interaction_id"] == interaction_id
+ and not interaction["is_deleted"]
+ ):
+ return True
+ return False
+
+ def update_interaction(self, base_data: dict):
+ if "interaction_id" not in base_data.keys():
+ raise ValueError("interaction_id must be in base_data")
+ for i, interaction_dict in enumerate(self.interaction_list_cache):
+ if interaction_dict["interaction_id"] == base_data["interaction_id"]:
+ for k, v in base_data.items():
+ if k == "interaction_id":
+ continue
+ self.interaction_list_cache[i][k] = v
+ break
+
+ with open(self.db_url, "w", encoding="utf-8") as f:
+ json.dump(self.interaction_list_cache, f, indent=2, ensure_ascii=False)
+
+ def update_interaction_status(
+ self, interaction_id: str, status: str, message: str, current_step: int
+ ):
+ for i, interaction_dict in enumerate(self.interaction_list_cache):
+ if interaction_dict["interaction_id"] == interaction_id:
+ self.interaction_list_cache[i]["status"] = status
+ self.interaction_list_cache[i]["message"] = message
+ self.interaction_list_cache[i]["current_step"] = current_step
+ self.interaction_list_cache[i]["update_time"] = datetime.now().strftime(
+ "%Y-%m-%d %H:%M:%S"
+ )
+ break
+
+ with open(self.db_url, "w", encoding="utf-8") as f:
+ json.dump(self.interaction_list_cache, f, indent=2, ensure_ascii=False)
+
+ def update_interaction_parameter(
+ self, interaction_id: str, parameter: InteractionParameter
+ ):
+ interaction_ids = [k for k in self.interaction_parameter_cache.keys()]
+ if interaction_id not in interaction_ids:
+ self.interaction_parameter_cache[interaction_id] = [parameter.to_dict()]
+ else:
+ self.interaction_parameter_cache[interaction_id].append(parameter.to_dict())
+
+ with open(self.parameter_url, "w", encoding="utf-8") as f:
+ json.dump(self.interaction_parameter_cache, f, indent=2, ensure_ascii=False)
+
+ def is_running(self, user_id: str):
+ interaction_list = self.get_interaction_list()
+ for interaction in interaction_list:
+ if (
+ interaction["user_id"] == user_id
+ and interaction["status"] in ["running", "waiting"]
+ and not interaction["is_deleted"]
+ ):
+ return True
+ return False
+
+ def delete_interaction(self, interaction_id: str):
+ interaction_list = self.get_interaction_list()
+ for i, interaction_dict in enumerate(interaction_list):
+ if interaction_dict["interaction_id"] == interaction_id:
+ self.interaction_list_cache[i]["is_deleted"] = True
+ break
+
+ with open(self.db_url, "w", encoding="utf-8") as f:
+ json.dump(self.interaction_list_cache, f, indent=2, ensure_ascii=False)
+
+ def get_shared_interaction(
+ self, interaction_id: str
+ ) -> Union[InteractionBase, None]:
+ interaction_list = self.get_interaction_list()
+ for interaction in interaction_list:
+ if interaction["interaction_id"] == interaction_id:
+ return InteractionBase(**interaction)
+ return None
diff --git a/AgentVerseServer/database/models.py b/AgentVerseServer/database/models.py
new file mode 100644
index 000000000..0dea8aeb7
--- /dev/null
+++ b/AgentVerseServer/database/models.py
@@ -0,0 +1,67 @@
+from sqlalchemy import JSON, Boolean, Column, ForeignKey, Integer, String, Text
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import relationship
+
+
+Base = declarative_base()
+
+
+class User(Base):
+ __tablename__="users"
+
+ id=Column(Integer,primary_key=True,index=True)
+ user_id = Column(String(32), unique=True, index=True)
+ email = Column(String(255), unique=True)
+ name = Column(String(255))
+ token = Column(String(255))
+ available = Column(Boolean, default=True)
+ deleted = Column(Boolean, default=False)
+ corporation = Column(Text)
+ industry = Column(Text)
+ position = Column(String(255))
+ create_time = Column(String(255))
+ update_time = Column(String(255))
+
+
+class Interaction(Base):
+ __tablename__ = "interactions"
+
+ id = Column(Integer, primary_key=True, index=True)
+ interaction_id = Column(String(255))
+ user_id = Column(String(255))
+ create_time = Column(String(255))
+ update_time = Column(String(255))
+ description = Column(String(255))
+ agent = Column(String(255))
+ mode = Column(String(255))
+ recorder_root_dir = Column(Text)
+ file_list = Column(JSON)
+ status = Column(String(255))
+ message = Column(Text)
+ current_step = Column(String(255))
+ is_deleted = Column(Boolean, default=False)
+
+
+class Parameter(Base):
+ __tablename__ = "interaction_parameters"
+
+ id = Column(Integer, primary_key=True, index=True)
+ interaction_id = Column(String(32), unique=True, index=True)
+ parameter_id = Column(String(32))
+ args = Column(JSON)
+
+
+class SharedInteraction(Base):
+ __tablename__ = "shared_interactions"
+
+ id = Column(Integer, primary_key=True, index=True)
+ interaction_id = Column(String(255))
+ user_name = Column(String(255))
+ create_time = Column(String(255))
+ update_time = Column(String(255))
+ description = Column(String(255))
+ agent = Column(String(255))
+ mode = Column(String(255))
+ is_deleted = Column(Boolean, default=False)
+ star = Column(Integer, default=0)
+ record_dir = Column(Text)
diff --git a/AgentVerseServer/database/sql/create_mysql_table.sql b/AgentVerseServer/database/sql/create_mysql_table.sql
new file mode 100644
index 000000000..af7871065
--- /dev/null
+++ b/AgentVerseServer/database/sql/create_mysql_table.sql
@@ -0,0 +1,79 @@
+SET NAMES utf8mb4;
+SET FOREIGN_KEY_CHECKS = 0;
+
+-- ----------------------------
+-- Table structure for interaction_parameters
+-- ----------------------------
+DROP TABLE IF EXISTS `interaction_parameters`;
+CREATE TABLE `interaction_parameters` (
+ `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
+ `interaction_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '对话ID',
+ `parameter_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '参数ID',
+ `args` json NULL COMMENT '参数',
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 88 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for interactions
+-- ----------------------------
+DROP TABLE IF EXISTS `interactions`;
+CREATE TABLE `interactions` (
+ `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
+ `interaction_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '对话ID',
+ `user_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户ID',
+ `create_time` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建时间',
+ `update_time` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '更新时间',
+ `description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '描述',
+ `agent` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '代理',
+ `mode` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '模式',
+ `recorder_root_dir` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '录音根目录',
+ `file_list` json NULL COMMENT '文件列表',
+ `status` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '状态',
+ `message` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '消息',
+ `current_step` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '当前步骤',
+ `is_deleted` tinyint(1) NULL DEFAULT 0 COMMENT '是否删除',
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 92 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for shared_interactions
+-- ----------------------------
+DROP TABLE IF EXISTS `shared_interactions`;
+CREATE TABLE `shared_interactions` (
+ `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
+ `interaction_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '交互ID',
+ `user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户名',
+ `create_time` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '创建时间',
+ `update_time` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '更新时间',
+ `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '描述',
+ `agent` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'agent',
+ `mode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '模式',
+ `is_deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
+ `star` int NOT NULL DEFAULT 0 COMMENT '星级',
+ `record_dir` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '记录路径',
+ PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 50 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Table structure for users
+-- ----------------------------
+DROP TABLE IF EXISTS `users`;
+CREATE TABLE `users` (
+ `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
+ `user_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户ID',
+ `email` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '邮箱',
+ `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '姓名',
+ `token` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '令牌',
+ `available` tinyint(1) NULL DEFAULT 1 COMMENT '是否可用',
+ `corporation` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '公司',
+ `industry` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '行业',
+ `position` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '职位',
+ `create_time` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建时间',
+ `update_time` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '更新时间',
+ `deleted` tinyint(1) NULL DEFAULT NULL COMMENT '删除标识',
+ PRIMARY KEY (`id`) USING BTREE,
+ UNIQUE INDEX `user_id`(`user_id` ASC) USING BTREE,
+ UNIQUE INDEX `email`(`email` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 152 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
+
+SET FOREIGN_KEY_CHECKS = 1;
diff --git a/AgentVerseServer/envs.py b/AgentVerseServer/envs.py
new file mode 100644
index 000000000..008f19dc8
--- /dev/null
+++ b/AgentVerseServer/envs.py
@@ -0,0 +1,95 @@
+import os
+
+from dotenv import find_dotenv, load_dotenv
+
+load_dotenv(find_dotenv(".env"))
+
+
+class AgentVerseServerEnv:
+ """
+ AgentVerseServer environment variables
+ if you change value of the environment variable, you need to restart the AgentVerseServer by running the following command:
+ `python start_server.py`
+ or start a unicorn server by yourself
+
+ """
+
+ app = "app:app"
+ prod: bool = os.getenv("PROD", "False").lower() == "true"
+ base_dir = "AgentVerseServer"
+ use_redis: bool = False
+ recorder_root_dir = "running_records"
+ # you can set default_login with True to use the default user "admin" with token "agentverse-admin" to login,
+ default_login: bool = True
+ # the parameter check_running is used to check whether the interaction is running,
+ # if you want to connect more than one AgentVerseServer, you can set check_running to True,
+ # in which case the AgentVerseServer will check whether the interaction is running in other AgentVerseServer
+ check_running: bool = False
+ host = "0.0.0.0"
+ port = 8090
+ debug = True
+ reload = True
+ workers = 1
+
+ class DB:
+ use_db = False
+ # Optional["file", "sqlite", "mysql", "postgresql"]
+ db_type = "file"
+ if db_type == "file":
+ # if you want to use file to store data, you can set db_url to {"users": "path/to/users.json", "interactions": "path/to/interaction.json", "parameter": "path/to/parameter.json"}
+ db_url = {
+ "users": "AgentVerseServer/localstorage/users/users.json",
+ "interactions": "AgentVerseServer/localstorage/records/interaction.json",
+ "parameter": "AgentVerseServer/localstorage/records/parameter.json",
+ }
+ else:
+ if db_type == "sqlite":
+ # if you want to use sqlite to store data, you can set db_url to "sqlite://{}", in which {} is the absolute path of the sqlite file
+ db_url = "sqlite://"
+ if db_type == "mysql":
+ # if you want to use mysql to store data, you can set db_url to "mysql+pymysql://{}:{}@{}:{}/{}, in which {} is {db_user, db_password, db_host, db_port, db_name}
+ db_url = "mysql+pymysql://"
+ if db_type == "postgresql":
+ # if you want to use postgresql to store data, you can set db_url to "postgresql://{}:{}@{}:{}/{}"
+ db_url = ""
+
+ class Redis:
+ use_redis = False
+ redis_url = "redis://localhost"
+ redis_host = "localhost"
+ redis_port = 6379
+ redis_db = 0
+ redis_password = None
+
+ # if you want to use email to send message, you can set send_email to True and set email_host, email_port, email_user, email_password, auth_server
+ class Email:
+ send_email = False
+ email_host = ""
+ email_port = 465
+ email_user = ""
+ email_password = ""
+ auth_server = ""
+
+ # if you want to use upload function, you can set upload_dir to the path of the upload directory and set upload_allowed_types to the allowed types
+ class Upload:
+ upload_dir = "AgentVerseServer/localstorage/upload"
+ if not os.path.exists(upload_dir):
+ os.makedirs(upload_dir)
+ upload_allowed_types = [
+ "image/png",
+ "image/jpeg",
+ "image/gif",
+ "text/plain",
+ "application/msword",
+ "pdf",
+ "txt",
+ "pptx",
+ "xlsx",
+ "doc",
+ "ppt",
+ "xls",
+ ]
+
+
+if os.path.exists("AgentVerseServer/prod_server_envs.py") and AgentVerseServerEnv.prod:
+ from AgentVerseServer.prod_server_envs import AgentVerseServerEnv
diff --git a/AgentVerseServer/exts/mail_ext.py b/AgentVerseServer/exts/mail_ext.py
new file mode 100644
index 000000000..dbd817099
--- /dev/null
+++ b/AgentVerseServer/exts/mail_ext.py
@@ -0,0 +1,21 @@
+from AgentVerseServer.envs import AgentVerseServerEnv
+
+
+def email_content(user):
+ html_body = f"""
+
+
+
Hello {user['name']},
+
Welcome to AgentVerse, your personal assistant! Thanks for signing up for AgentVerse. There are some information about your account:
+
Your AgentVerse Account: {user["email"]}
+
You need to use this token for authentication on subsequent logins:
+
You need to use this token for authentication on subsequent logins:
+
Token: {user["token"]}
+
+
Next is an activation link. You need to click on this link to activate your account. After that, you will be able to use AgentVerse happily:{AgentVerseServerEnv.Email.auth_server}/auth?user_id={user["user_id"]}&token={user["token"]}! This Verification link will expire in 7 days.
+
If you have any questions, please contact us at youragentverse@gmail.com .
+
Best wishes!
+
AgentVerse Team
+
+"""
+ return html_body
diff --git a/AgentVerseServer/interaction.py b/AgentVerseServer/interaction.py
new file mode 100644
index 000000000..38e948178
--- /dev/null
+++ b/AgentVerseServer/interaction.py
@@ -0,0 +1,197 @@
+import abc
+import json
+import os
+import uuid
+from datetime import datetime
+
+from AgentVerseIO.BaseIO import AgentVerseIO
+from AgentVerseServer.database import InteractionBaseInterface
+from AgentVerseServer.envs import AgentVerseServerEnv
+from AgentVerseServer.loggers.logs import Logger
+from AgentVerseServer.models.interaction import InteractionBase
+from AgentVerseServer.models.parameter import InteractionParameter
+from AgentVerseServer.models.subround import Subround
+from AgentVerseServer.models.ws import AgentVerseOutputData
+
+
+class AgentVerseInteraction(metaclass=abc.ABCMeta):
+ def __init__(
+ self,
+ base: InteractionBase,
+ parameter: InteractionParameter,
+ interrupt: bool = False,
+ ) -> None:
+ self.base = base
+ self.parameter = parameter
+ self._cache: AgentVerseOutputData = None
+
+ self.current_step = uuid.uuid4().hex
+ self.logger = None
+ self.interrupt = interrupt
+ self.log_dir = os.path.join(
+ os.path.join(
+ AgentVerseServerEnv.base_dir, "localstorage", "interact_records"
+ ),
+ datetime.now().strftime("%Y-%m-%d"),
+ self.base.interaction_id,
+ )
+ if not os.path.exists(self.log_dir):
+ os.makedirs(self.log_dir)
+
+ def to_dict(self):
+ return self.parameter.to_dict()
+
+ def to_json(self):
+ return json.dumps(self.to_dict(), indent=2, ensure_ascii=False)
+
+ def resister_logger(self, logger: Logger):
+ self.logger = logger
+ self.logger.info(f"init interaction: {self.base.interaction_id}")
+
+ def resister_io(self, io: AgentVerseIO):
+ self.io = io
+
+ def register_db(self, db: InteractionBaseInterface):
+ self.db = db
+
+ def register_recorder_root_dir(self, recorder_root_dir):
+ self.recorder_root_dir = recorder_root_dir
+
+ def init_cache(self, data: AgentVerseOutputData):
+ self._cache = data
+ self.logger.info(f"init cache")
+
+ def get_cache(self) -> dict:
+ return self._cache.to_dict() if self.data_cache is not None else {}
+
+ def save_cache(self):
+ # self.logger.info(f"save cache into mongodb")
+ with open(os.path.join(self.log_dir, "cache.json"), "w", encoding="utf-8") as f:
+ json.dump(self._cache.to_dict(), f, indent=2, ensure_ascii=False)
+
+ async def update_cache(self, update_data: dict, status="", current: str = None):
+ if status not in [
+ "start",
+ "subround",
+ "refinement",
+ "stage",
+ "finished",
+ "failed",
+ ]:
+ raise ValueError(
+ "status must be in ['start', 'subround', 'refinement', 'stage', 'finished', 'failed']"
+ )
+
+ self.current_step = uuid.uuid4().hex
+ # self.logger.typewriter_log(
+ # f"CURRENT: {self.current_step}", f"update cache, status {status}, current {current}, update_data: {update_data}")
+ # if status == "inner":
+ # tool_name = (
+ # update_data.get("using_tools", {}).get("tool_name", "")
+ # if isinstance(update_data, dict)
+ # else ""
+ # )
+
+ # if tool_name == "subtask_submit":
+ # status = "subtask_submit"
+
+ push_data = {
+ "status": status,
+ "current": current,
+ "random_seed": self.current_step,
+ "data": update_data,
+ }
+
+ if status == "start":
+ # for k, v in update_data.items():
+ # if k == "subtasks":
+ # update_data["subtasks"] = [Subround(**subtask) for subtask in v]
+
+ # self._cache.update(update_data)
+
+ push_data = {
+ "status": status,
+ "random_seed": self.current_step,
+ "data": {
+ k: v if k != "subtasks" else [l.to_dict() for l in v]
+ for k, v in update_data.items()
+ },
+ }
+ self.db.update_interaction_status(
+ self.base.interaction_id,
+ status="running",
+ message="running",
+ current_step=self.current_step,
+ )
+
+ if status == "refinement":
+ if current is None:
+ raise ValueError("current must be a task_id while status is refinement")
+ if not isinstance(update_data, dict):
+ raise ValueError(
+ "update_data must be a dict while status is refinement"
+ )
+ # sub_task = None
+ # for subtask in self._cache.subtasks:
+ # if current == subtask.task_id:
+ # subtask.refinement = update_data
+ # sub_task = subtask.to_dict()
+ # break
+ push_data = {
+ "status": status,
+ # "node_id": sub_task.get("node_id", ""),
+ # "task_id": sub_task.get("task_id", ""),
+ # "name": sub_task.get("name", ""),
+ # "args": sub_task.get("args", ""),
+ "current": current,
+ "data": update_data,
+ "random_seed": self.current_step,
+ }
+ self.db.update_interaction_status(
+ self.base.interaction_id,
+ status="running",
+ message="running",
+ current_step=self.current_step,
+ )
+
+ if status == "stage":
+ if current is None:
+ raise ValueError("current must be a task_id while status is inner")
+ if not isinstance(update_data, dict):
+ raise ValueError("update_data must be a dict while status is inner")
+
+ push_data = {
+ "status": status,
+ "current": current,
+ "data": update_data,
+ "random_seed": self.current_step,
+ }
+
+ await self.auto_send(push_data=push_data)
+ if status == "finished":
+ await self.auto_close()
+
+ async def auto_send(self, push_data):
+ # self.logger.info(f"send data: {push_data}")
+ await self.io.Output.run(push_data)
+
+ async def auto_receive(self, can_modify=None):
+ data = await self.io.Input.run(can_modify)
+ self.db.add_parameter(
+ InteractionParameter(
+ parameter_id=uuid.uuid4().hex,
+ interaction_id=self.base.interaction_id,
+ args=data.get("args", {}),
+ )
+ )
+ return data
+
+ async def auto_close(self):
+ # self.io.close()
+ self.logger.info(f"close io connection")
+ self.db.update_interaction_status(
+ self.base.interaction_id,
+ status="finished",
+ message="io connection closed",
+ current_step=self.current_step,
+ )
diff --git a/AgentVerseServer/localstorage/records/interaction.json b/AgentVerseServer/localstorage/records/interaction.json
new file mode 100644
index 000000000..52dbf4f14
--- /dev/null
+++ b/AgentVerseServer/localstorage/records/interaction.json
@@ -0,0 +1,194 @@
+[
+ {
+ "interaction_id": "f129298f-f322-4e27-bf50-1c5c24080f8c",
+ "user_id": "admin",
+ "create_time": "2023-11-22 19:09:17",
+ "description": "Recently, it has become po",
+ "recorder_root_dir": "",
+ "status": "running",
+ "message": "running",
+ "current_step": "ffd39042f9c049ca97f499f63ad81e92",
+ "update_time": "2023-11-22 19:09:18",
+ "is_deleted": false
+ },
+ {
+ "interaction_id": "2bc0d416-7c85-42b9-9702-e13b1ea18752",
+ "user_id": "admin",
+ "create_time": "2023-11-23 10:25:37",
+ "description": "Recently, it has become po",
+ "recorder_root_dir": "",
+ "status": "running",
+ "message": "running",
+ "current_step": "654188ff662242e09257bfa4c96e2785",
+ "update_time": "2023-11-23 10:25:38",
+ "is_deleted": false
+ },
+ {
+ "interaction_id": "2cb9a0a7-754f-424e-9c5b-b324b395a305",
+ "user_id": "admin",
+ "create_time": "2023-11-23 10:29:41",
+ "description": "Recently, it has become po",
+ "recorder_root_dir": "",
+ "status": "failed",
+ "message": "failed, code: 1011",
+ "current_step": "0577acd3be02461cbf4d61a7c562a82c",
+ "update_time": "2023-11-23 10:42:53",
+ "is_deleted": false
+ },
+ {
+ "interaction_id": "046bfefd-c6cd-42c5-ab7f-743e4a70ba6d",
+ "user_id": "admin",
+ "create_time": "2023-11-23 11:07:16",
+ "description": "Recently, it has become po",
+ "recorder_root_dir": "",
+ "status": "failed",
+ "message": "failed, code: 1011",
+ "current_step": "ea385c3ebc3d421f829059d36f36fcf5",
+ "update_time": "2023-11-23 11:10:21",
+ "is_deleted": false
+ },
+ {
+ "interaction_id": "d46138ac-7e84-45a9-bd99-711e2c916872",
+ "user_id": "admin",
+ "create_time": "2023-11-23 11:13:36",
+ "description": "Recently, it has become po",
+ "recorder_root_dir": "",
+ "status": "running",
+ "message": "running",
+ "current_step": "5d07b259b9314329b0137e1b61a54a99",
+ "update_time": "2023-11-23 11:13:36",
+ "is_deleted": false
+ },
+ {
+ "interaction_id": "80818f18-759a-4b0f-86a5-4efa3acd1e60",
+ "user_id": "admin",
+ "create_time": "2023-11-23 11:14:47",
+ "description": "Recently, it has become po",
+ "recorder_root_dir": "",
+ "status": "failed",
+ "message": "failed, code: 1011",
+ "current_step": "32fb6bf460b242e296183e816ce3b68d",
+ "update_time": "2023-11-23 11:17:36",
+ "is_deleted": false
+ },
+ {
+ "interaction_id": "c1d0573e-da50-4ac4-952b-ecd6b65f9138",
+ "user_id": "admin",
+ "create_time": "2023-11-23 11:23:04",
+ "description": "Recently, it has become po",
+ "recorder_root_dir": "",
+ "status": "running",
+ "message": "running",
+ "current_step": "d60437ed091341f8b738c79b7f301ae8",
+ "update_time": "2023-11-23 11:23:05",
+ "is_deleted": false
+ },
+ {
+ "interaction_id": "d8658322-7ff7-412d-8920-d03d8cebab69",
+ "user_id": "admin",
+ "create_time": "2023-11-23 11:25:29",
+ "description": "Recently, it has become po",
+ "recorder_root_dir": "",
+ "status": "running",
+ "message": "running",
+ "current_step": "f5922963e15545cfa8c18dd43bd45e42",
+ "update_time": "2023-11-23 11:25:30",
+ "is_deleted": false
+ },
+ {
+ "interaction_id": "6a081ca4-0929-4e01-98fe-1892c1d30703",
+ "user_id": "admin",
+ "create_time": "2023-11-23 11:27:09",
+ "description": "Recently, it has become po",
+ "recorder_root_dir": "",
+ "status": "running",
+ "message": "running",
+ "current_step": "4e45cfa759594200aca0b4409095a74b",
+ "update_time": "2023-11-23 11:27:09",
+ "is_deleted": false
+ },
+ {
+ "interaction_id": "6b8a7a53-596b-46d5-8e50-8912a350ab77",
+ "user_id": "admin",
+ "create_time": "2023-11-23 11:35:44",
+ "description": "Recently, it has become po",
+ "recorder_root_dir": "",
+ "status": "failed",
+ "message": "failed, code: 1011",
+ "current_step": "2e9d1e2445f34c1da602bc407fae2f02",
+ "update_time": "2023-11-23 11:42:43",
+ "is_deleted": false
+ },
+ {
+ "interaction_id": "817102cd-c753-4c07-976b-898750839f3c",
+ "user_id": "admin",
+ "create_time": "2023-11-23 11:43:57",
+ "description": "Recently, it has become po",
+ "recorder_root_dir": "",
+ "status": "running",
+ "message": "running",
+ "current_step": "f039273001ea4d619cb2eba1edd51679",
+ "update_time": "2023-11-23 11:53:46",
+ "is_deleted": false
+ },
+ {
+ "interaction_id": "f4390315-6c72-4294-9b98-1742630fac66",
+ "user_id": "admin",
+ "create_time": "2023-11-23 12:44:52",
+ "description": "Recently, it has become po",
+ "recorder_root_dir": "",
+ "status": "running",
+ "message": "running",
+ "current_step": "598077104f304b658ae0d2bfbf41c2da",
+ "update_time": "2023-11-23 12:44:53",
+ "is_deleted": false
+ },
+ {
+ "interaction_id": "b71d597d-4e62-47f6-ae75-1f43e5b97ea2",
+ "user_id": "admin",
+ "create_time": "2023-11-23 13:24:16",
+ "description": "Recently, it has become po",
+ "recorder_root_dir": "",
+ "status": "running",
+ "message": "running",
+ "current_step": "b29e0f0b39bf48b6b04e4be9d26385e5",
+ "update_time": "2023-11-23 13:33:16",
+ "is_deleted": false
+ },
+ {
+ "interaction_id": "b8914884-788c-4d01-adc2-fe48f6848e7e",
+ "user_id": "admin",
+ "create_time": "2023-11-23 14:28:23",
+ "description": "Recently, it has become po",
+ "recorder_root_dir": "",
+ "status": "failed",
+ "message": "failed, code: 1011",
+ "current_step": "db988f8373724d82bd64bdee3bf20a81",
+ "update_time": "2023-11-23 14:32:12",
+ "is_deleted": false
+ },
+ {
+ "interaction_id": "e9449b8c-df48-45c6-833c-59a5303f2986",
+ "user_id": "admin",
+ "create_time": "2023-11-23 14:56:25",
+ "description": "Recently, it has become po",
+ "recorder_root_dir": "",
+ "status": "failed",
+ "message": "failed, code: 1011",
+ "current_step": "810979f181d34f05897f3dca4b31ef58",
+ "update_time": "2023-11-23 15:04:19",
+ "is_deleted": false
+ },
+ {
+ "interaction_id": "12049de3-4d6a-4230-98ae-37faa33f328b",
+ "user_id": "admin",
+ "create_time": "2023-11-23 15:13:52",
+ "description": "Recently, it has become po",
+ "recorder_root_dir": "",
+ "status": "running",
+ "message": "running",
+ "current_step": "bb86050108994ca48e7a3f6675687c6a",
+ "update_time": "2023-11-23 15:21:57",
+ "is_deleted": false
+ }
+]
\ No newline at end of file
diff --git a/AgentVerseServer/localstorage/records/parameter.json b/AgentVerseServer/localstorage/records/parameter.json
new file mode 100644
index 000000000..8ea347b8e
--- /dev/null
+++ b/AgentVerseServer/localstorage/records/parameter.json
@@ -0,0 +1,432 @@
+{
+ "f129298f-f322-4e27-bf50-1c5c24080f8c": [
+ {
+ "interaction_id": "f129298f-f322-4e27-bf50-1c5c24080f8c",
+ "parameter_id": "2a800e51c3ae48f8bcab060d9251837c",
+ "args": {
+ "goal": {
+ "_object": {
+ "history": {},
+ "historyArr": [],
+ "sharedArr": [],
+ "currentInput": {
+ "task_des": "Recently, it has become popular in the AI field to verify the mathematical reasoning abilities of large language models by observing if they can solve the \"24-Point Game.\" What is this game? Does it have a code-based solution? If it does, provide a Python code along with test cases and test its functionality. What are some other similar games that can be used to test the models' mathematical reasoning abilities?",
+ "cnt_agents": "3"
+ },
+ "isRequestingAi": false,
+ "msgInfoList": [],
+ "setting": {},
+ "isShouldRefreshHistory": false
+ },
+ "_key": "currentInput",
+ "__v_isRef": true
+ }
+ }
+ }
+ ],
+ "2bc0d416-7c85-42b9-9702-e13b1ea18752": [
+ {
+ "interaction_id": "2bc0d416-7c85-42b9-9702-e13b1ea18752",
+ "parameter_id": "f9c7b90bf0ad4f6f898956f314b89d3f",
+ "args": {
+ "goal": {
+ "_object": {
+ "history": {},
+ "historyArr": [],
+ "sharedArr": [],
+ "currentInput": {
+ "task_des": "Recently, it has become popular in the AI field to verify the mathematical reasoning abilities of large language models by observing if they can solve the \"24-Point Game.\" What is this game? Does it have a code-based solution? If it does, provide a Python code along with test cases and test its functionality. What are some other similar games that can be used to test the models' mathematical reasoning abilities?",
+ "cnt_agents": "3"
+ },
+ "isRequestingAi": false,
+ "msgInfoList": [],
+ "setting": {},
+ "isShouldRefreshHistory": false
+ },
+ "_key": "currentInput",
+ "__v_isRef": true
+ }
+ }
+ }
+ ],
+ "2cb9a0a7-754f-424e-9c5b-b324b395a305": [
+ {
+ "interaction_id": "2cb9a0a7-754f-424e-9c5b-b324b395a305",
+ "parameter_id": "1256a90ab59a4e719a8fd4f3f72c374e",
+ "args": {
+ "goal": {
+ "_object": {
+ "history": {},
+ "historyArr": [],
+ "sharedArr": [],
+ "currentInput": {
+ "task_des": "Recently, it has become popular in the AI field to verify the mathematical reasoning abilities of large language models by observing if they can solve the \"24-Point Game.\" What is this game? Does it have a code-based solution? If it does, provide a Python code along with test cases and test its functionality. What are some other similar games that can be used to test the models' mathematical reasoning abilities?",
+ "cnt_agents": "3"
+ },
+ "isRequestingAi": false,
+ "msgInfoList": [],
+ "setting": {},
+ "isShouldRefreshHistory": false
+ },
+ "_key": "currentInput",
+ "__v_isRef": true
+ }
+ }
+ },
+ {
+ "interaction_id": "2cb9a0a7-754f-424e-9c5b-b324b395a305",
+ "parameter_id": "20f0d5c09cf94382a0ae68fd4e7848a6",
+ "args": {}
+ }
+ ],
+ "046bfefd-c6cd-42c5-ab7f-743e4a70ba6d": [
+ {
+ "interaction_id": "046bfefd-c6cd-42c5-ab7f-743e4a70ba6d",
+ "parameter_id": "e4d2b7dbc9e34f08a52ebd4541d72989",
+ "args": {
+ "goal": {
+ "_object": {
+ "history": {},
+ "historyArr": [],
+ "sharedArr": [],
+ "currentInput": {
+ "task_des": "Recently, it has become popular in the AI field to verify the mathematical reasoning abilities of large language models by observing if they can solve the \"24-Point Game.\" What is this game? Does it have a code-based solution? If it does, provide a Python code along with test cases and test its functionality. What are some other similar games that can be used to test the models' mathematical reasoning abilities?",
+ "cnt_agents": "3"
+ },
+ "isRequestingAi": false,
+ "msgInfoList": [],
+ "setting": {},
+ "isShouldRefreshHistory": false
+ },
+ "_key": "currentInput",
+ "__v_isRef": true
+ }
+ }
+ },
+ {
+ "interaction_id": "046bfefd-c6cd-42c5-ab7f-743e4a70ba6d",
+ "parameter_id": "47175e173bc94a26ab9895f9d3aa4894",
+ "args": {}
+ }
+ ],
+ "d46138ac-7e84-45a9-bd99-711e2c916872": [
+ {
+ "interaction_id": "d46138ac-7e84-45a9-bd99-711e2c916872",
+ "parameter_id": "9f96f3366ae445eebee81d1558bb6ba8",
+ "args": {
+ "goal": {
+ "_object": {
+ "history": {},
+ "historyArr": [],
+ "sharedArr": [],
+ "currentInput": {
+ "task_des": "Recently, it has become popular in the AI field to verify the mathematical reasoning abilities of large language models by observing if they can solve the \"24-Point Game.\" What is this game? Does it have a code-based solution? If it does, provide a Python code along with test cases and test its functionality. What are some other similar games that can be used to test the models' mathematical reasoning abilities?",
+ "cnt_agents": "3"
+ },
+ "isRequestingAi": false,
+ "msgInfoList": [],
+ "setting": {},
+ "isShouldRefreshHistory": false
+ },
+ "_key": "currentInput",
+ "__v_isRef": true
+ }
+ }
+ }
+ ],
+ "80818f18-759a-4b0f-86a5-4efa3acd1e60": [
+ {
+ "interaction_id": "80818f18-759a-4b0f-86a5-4efa3acd1e60",
+ "parameter_id": "b648d65c49424c4c84c198d39c767d45",
+ "args": {
+ "goal": {
+ "_object": {
+ "history": {},
+ "historyArr": [],
+ "sharedArr": [],
+ "currentInput": {
+ "task_des": "Recently, it has become popular in the AI field to verify the mathematical reasoning abilities of large language models by observing if they can solve the \"24-Point Game.\" What is this game? Does it have a code-based solution? If it does, provide a Python code along with test cases and test its functionality. What are some other similar games that can be used to test the models' mathematical reasoning abilities?",
+ "cnt_agents": "3"
+ },
+ "isRequestingAi": false,
+ "msgInfoList": [],
+ "setting": {},
+ "isShouldRefreshHistory": false
+ },
+ "_key": "currentInput",
+ "__v_isRef": true
+ }
+ }
+ },
+ {
+ "interaction_id": "80818f18-759a-4b0f-86a5-4efa3acd1e60",
+ "parameter_id": "c7f1188f35754f0cb7f99753255d065f",
+ "args": {}
+ }
+ ],
+ "c1d0573e-da50-4ac4-952b-ecd6b65f9138": [
+ {
+ "interaction_id": "c1d0573e-da50-4ac4-952b-ecd6b65f9138",
+ "parameter_id": "cc6584253b0a4bc7a794da6c64d3fff8",
+ "args": {
+ "goal": {
+ "_object": {
+ "history": {},
+ "historyArr": [],
+ "sharedArr": [],
+ "currentInput": {
+ "task_des": "Recently, it has become popular in the AI field to verify the mathematical reasoning abilities of large language models by observing if they can solve the \"24-Point Game.\" What is this game? Does it have a code-based solution? If it does, provide a Python code along with test cases and test its functionality. What are some other similar games that can be used to test the models' mathematical reasoning abilities?",
+ "cnt_agents": "3"
+ },
+ "isRequestingAi": false,
+ "msgInfoList": [],
+ "setting": {},
+ "isShouldRefreshHistory": false
+ },
+ "_key": "currentInput",
+ "__v_isRef": true
+ }
+ }
+ }
+ ],
+ "d8658322-7ff7-412d-8920-d03d8cebab69": [
+ {
+ "interaction_id": "d8658322-7ff7-412d-8920-d03d8cebab69",
+ "parameter_id": "57266f645ea54f38a1f32f12a64af607",
+ "args": {
+ "goal": {
+ "_object": {
+ "history": {},
+ "historyArr": [],
+ "sharedArr": [],
+ "currentInput": {
+ "task_des": "Recently, it has become popular in the AI field to verify the mathematical reasoning abilities of large language models by observing if they can solve the \"24-Point Game.\" What is this game? Does it have a code-based solution? If it does, provide a Python code along with test cases and test its functionality. What are some other similar games that can be used to test the models' mathematical reasoning abilities?",
+ "cnt_agents": "3"
+ },
+ "isRequestingAi": false,
+ "msgInfoList": [],
+ "setting": {},
+ "isShouldRefreshHistory": false
+ },
+ "_key": "currentInput",
+ "__v_isRef": true
+ }
+ }
+ }
+ ],
+ "6a081ca4-0929-4e01-98fe-1892c1d30703": [
+ {
+ "interaction_id": "6a081ca4-0929-4e01-98fe-1892c1d30703",
+ "parameter_id": "3b928bc921194b1e99ffe031faa954e8",
+ "args": {
+ "goal": {
+ "_object": {
+ "history": {},
+ "historyArr": [],
+ "sharedArr": [],
+ "currentInput": {
+ "task_des": "Recently, it has become popular in the AI field to verify the mathematical reasoning abilities of large language models by observing if they can solve the \"24-Point Game.\" What is this game? Does it have a code-based solution? If it does, provide a Python code along with test cases and test its functionality. What are some other similar games that can be used to test the models' mathematical reasoning abilities?",
+ "cnt_agents": "3"
+ },
+ "isRequestingAi": false,
+ "msgInfoList": [],
+ "setting": {},
+ "isShouldRefreshHistory": false
+ },
+ "_key": "currentInput",
+ "__v_isRef": true
+ }
+ }
+ }
+ ],
+ "6b8a7a53-596b-46d5-8e50-8912a350ab77": [
+ {
+ "interaction_id": "6b8a7a53-596b-46d5-8e50-8912a350ab77",
+ "parameter_id": "880d21d2863c45b990e33bc6017b51ed",
+ "args": {
+ "goal": {
+ "_object": {
+ "history": {},
+ "historyArr": [],
+ "sharedArr": [],
+ "currentInput": {
+ "task_des": "Recently, it has become popular in the AI field to verify the mathematical reasoning abilities of large language models by observing if they can solve the \"24-Point Game.\" What is this game? Does it have a code-based solution? If it does, provide a Python code along with test cases and test its functionality. What are some other similar games that can be used to test the models' mathematical reasoning abilities?",
+ "cnt_agents": "3"
+ },
+ "isRequestingAi": false,
+ "msgInfoList": [],
+ "setting": {},
+ "isShouldRefreshHistory": false
+ },
+ "_key": "currentInput",
+ "__v_isRef": true
+ }
+ }
+ },
+ {
+ "interaction_id": "6b8a7a53-596b-46d5-8e50-8912a350ab77",
+ "parameter_id": "332015bbd83d44ff86ccf954475d324d",
+ "args": {}
+ }
+ ],
+ "817102cd-c753-4c07-976b-898750839f3c": [
+ {
+ "interaction_id": "817102cd-c753-4c07-976b-898750839f3c",
+ "parameter_id": "7b643f48c26e4f928a1c5a2896114ec0",
+ "args": {
+ "goal": {
+ "_object": {
+ "history": {},
+ "historyArr": [],
+ "sharedArr": [],
+ "currentInput": {
+ "task_des": "Recently, it has become popular in the AI field to verify the mathematical reasoning abilities of large language models by observing if they can solve the \"24-Point Game.\" What is this game? Does it have a code-based solution? If it does, provide a Python code along with test cases and test its functionality. What are some other similar games that can be used to test the models' mathematical reasoning abilities?",
+ "cnt_agents": "3"
+ },
+ "isRequestingAi": false,
+ "msgInfoList": [],
+ "setting": {},
+ "isShouldRefreshHistory": false
+ },
+ "_key": "currentInput",
+ "__v_isRef": true
+ }
+ }
+ }
+ ],
+ "f4390315-6c72-4294-9b98-1742630fac66": [
+ {
+ "interaction_id": "f4390315-6c72-4294-9b98-1742630fac66",
+ "parameter_id": "bd7ea3849d8745079ccadc4be6184ed8",
+ "args": {
+ "goal": {
+ "_object": {
+ "history": {},
+ "historyArr": [],
+ "sharedArr": [],
+ "currentInput": {
+ "task_des": "Recently, it has become popular in the AI field to verify the mathematical reasoning abilities of large language models by observing if they can solve the \"24-Point Game.\" What is this game? Does it have a code-based solution? If it does, provide a Python code along with test cases and test its functionality. What are some other similar games that can be used to test the models' mathematical reasoning abilities?",
+ "cnt_agents": "3"
+ },
+ "isRequestingAi": false,
+ "msgInfoList": [],
+ "setting": {},
+ "isShouldRefreshHistory": false
+ },
+ "_key": "currentInput",
+ "__v_isRef": true
+ }
+ }
+ }
+ ],
+ "b71d597d-4e62-47f6-ae75-1f43e5b97ea2": [
+ {
+ "interaction_id": "b71d597d-4e62-47f6-ae75-1f43e5b97ea2",
+ "parameter_id": "f7d3686084094a20a67921e866c3fa24",
+ "args": {
+ "goal": {
+ "_object": {
+ "history": {},
+ "historyArr": [],
+ "sharedArr": [],
+ "currentInput": {
+ "task_des": "Recently, it has become popular in the AI field to verify the mathematical reasoning abilities of large language models by observing if they can solve the \"24-Point Game.\" What is this game? Does it have a code-based solution? If it does, provide a Python code along with test cases and test its functionality. What are some other similar games that can be used to test the models' mathematical reasoning abilities?",
+ "cnt_agents": "3"
+ },
+ "isRequestingAi": false,
+ "msgInfoList": [],
+ "setting": {},
+ "isShouldRefreshHistory": false
+ },
+ "_key": "currentInput",
+ "__v_isRef": true
+ }
+ }
+ }
+ ],
+ "b8914884-788c-4d01-adc2-fe48f6848e7e": [
+ {
+ "interaction_id": "b8914884-788c-4d01-adc2-fe48f6848e7e",
+ "parameter_id": "72312018491e4a58ae3f5423602e9fd2",
+ "args": {
+ "goal": {
+ "_object": {
+ "history": {},
+ "historyArr": [],
+ "sharedArr": [],
+ "currentInput": {
+ "task_des": "Recently, it has become popular in the AI field to verify the mathematical reasoning abilities of large language models by observing if they can solve the \"24-Point Game.\" What is this game? Does it have a code-based solution? If it does, provide a Python code along with test cases and test its functionality. What are some other similar games that can be used to test the models' mathematical reasoning abilities?",
+ "cnt_agents": "3"
+ },
+ "isRequestingAi": false,
+ "msgInfoList": [],
+ "setting": {},
+ "isShouldRefreshHistory": false
+ },
+ "_key": "currentInput",
+ "__v_isRef": true
+ }
+ }
+ },
+ {
+ "interaction_id": "b8914884-788c-4d01-adc2-fe48f6848e7e",
+ "parameter_id": "8df21fa3cdc24347864fd5ba517edcef",
+ "args": {}
+ }
+ ],
+ "e9449b8c-df48-45c6-833c-59a5303f2986": [
+ {
+ "interaction_id": "e9449b8c-df48-45c6-833c-59a5303f2986",
+ "parameter_id": "9757b96be8f945b58c4f340fd3895f7a",
+ "args": {
+ "goal": {
+ "_object": {
+ "history": {},
+ "historyArr": [],
+ "sharedArr": [],
+ "currentInput": {
+ "task_des": "Recently, it has become popular in the AI field to verify the mathematical reasoning abilities of large language models by observing if they can solve the \"24-Point Game.\" What is this game? Does it have a code-based solution? If it does, provide a Python code along with test cases and test its functionality. What are some other similar games that can be used to test the models' mathematical reasoning abilities?",
+ "cnt_agents": "3"
+ },
+ "isRequestingAi": false,
+ "msgInfoList": [],
+ "setting": {},
+ "isShouldRefreshHistory": false
+ },
+ "_key": "currentInput",
+ "__v_isRef": true
+ }
+ }
+ },
+ {
+ "interaction_id": "e9449b8c-df48-45c6-833c-59a5303f2986",
+ "parameter_id": "ba147a7c62994a9ebe169aa25f6d6ea7",
+ "args": {}
+ }
+ ],
+ "12049de3-4d6a-4230-98ae-37faa33f328b": [
+ {
+ "interaction_id": "12049de3-4d6a-4230-98ae-37faa33f328b",
+ "parameter_id": "5a88233b53ae4286b959c1d7837c0adf",
+ "args": {
+ "goal": {
+ "_object": {
+ "history": {},
+ "historyArr": [],
+ "sharedArr": [],
+ "currentInput": {
+ "task_des": "Recently, it has become popular in the AI field to verify the mathematical reasoning abilities of large language models by observing if they can solve the \"24-Point Game.\" What is this game? Does it have a code-based solution? If it does, provide a Python code along with test cases and test its functionality. What are some other similar games that can be used to test the models' mathematical reasoning abilities?",
+ "cnt_agents": "3"
+ },
+ "isRequestingAi": false,
+ "msgInfoList": [],
+ "setting": {},
+ "isShouldRefreshHistory": false
+ },
+ "_key": "currentInput",
+ "__v_isRef": true
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/AgentVerseServer/localstorage/users/users.json b/AgentVerseServer/localstorage/users/users.json
new file mode 100644
index 000000000..b93b6f03e
--- /dev/null
+++ b/AgentVerseServer/localstorage/users/users.json
@@ -0,0 +1,15 @@
+[
+ {
+ "user_id": "admin",
+ "email": "admin",
+ "token": "agentverse-admin",
+ "name": "admin",
+ "available": true,
+ "create_time": "2023-10-27 14:31:09",
+ "update_time": "2023-10-27 14:31:09",
+ "corporation": "agentverse",
+ "industry": "AI",
+ "position": "agentverse",
+ "deleted": false
+ }
+]
\ No newline at end of file
diff --git a/AgentVerseServer/loggers/logs.py b/AgentVerseServer/loggers/logs.py
new file mode 100644
index 000000000..ceeb59ff3
--- /dev/null
+++ b/AgentVerseServer/loggers/logs.py
@@ -0,0 +1,256 @@
+import abc
+import json
+import logging
+import os
+import random
+import re
+import time
+import uuid
+from logging import LogRecord
+from typing import Any
+
+from colorama import Fore, Style
+
+class JsonFileHandler(logging.FileHandler):
+ def __init__(self, filename, mode="a", encoding=None, delay=False):
+ super().__init__(filename, mode, encoding, delay)
+
+ def emit(self, record):
+ json_data = json.loads(self.format(record))
+ with open(self.baseFilename, "w", encoding="utf-8") as f:
+ json.dump(json_data, f, ensure_ascii=False, indent=4)
+
+
+class JsonFormatter(logging.Formatter):
+ def format(self, record):
+ return record.msg
+
+class Logger(metaclass=abc.ABCMeta):
+ """
+ Logger that handle titles in different colors.
+ Outputs logs in console, activity.log, and errors.log
+ For console handler: simulates typing
+ """
+
+ def __init__(self, log_dir: str = None, log_name: str= "", log_file: str = "activity.log", error_file: str = "errors.log"):
+
+ if not os.path.exists(log_dir):
+ os.makedirs(log_dir)
+
+ # create log directory if it doesn't exist
+ self.log_name = time.strftime("%Y-%m-%d", time.localtime()) if not log_name else log_name
+ self.logger = logging.getLogger(self.log_name)
+ console_formatter = RecordFormatter("%(title_color)s %(message)s")
+
+ # Create a handler for console which simulate typing
+ self.typing_console_handler = TypingConsoleHandler()
+ self.typing_console_handler.setLevel(logging.INFO)
+ self.typing_console_handler.setFormatter(console_formatter)
+
+ # Create a handler for console without typing simulation
+ self.console_handler = ConsoleHandler()
+ self.console_handler.setLevel(logging.DEBUG)
+ self.console_handler.setFormatter(console_formatter)
+
+
+ self.speak_mode = False
+ self.chat_plugins = []
+
+ # Info handler in activity.log
+ self.file_handler = logging.FileHandler(
+ os.path.join(log_dir, log_file), "a", "utf-8"
+ )
+ self.file_handler.setLevel(logging.DEBUG)
+ info_formatter = RecordFormatter(
+ "%(asctime)s [%(threadName)s] %(levelname)s: %(title)s %(message)s"
+ )
+ self.file_handler.setFormatter(info_formatter)
+
+ # Error handler error.log
+ error_handler = logging.FileHandler(
+ os.path.join(log_dir, error_file), "a", "utf-8"
+ )
+ error_handler.setLevel(logging.ERROR)
+ error_formatter = RecordFormatter(
+ "%(asctime)s [%(threadName)s] %(levelname)s %(module)s:%(funcName)s:%(lineno)d %(title)s"
+ " %(message_no_color)s"
+ )
+ error_handler.setFormatter(error_formatter)
+
+ # self.typing_logger = logging.getLogger(self.log_name)
+ # if not self.typing_logger.handlers:
+ # self.typing_logger.addHandler(self.typing_console_handler)
+ # self.typing_logger.addHandler(self.file_handler)
+ # self.typing_logger.addHandler(error_handler)
+ # self.typing_logger.setLevel(logging.DEBUG)
+
+ if self.log_name.endswith("_INTERACT") or not self.logger.handlers:
+ # self.logger.addHandler(self.typing_console_handler)
+ self.logger.addHandler(self.console_handler)
+ self.logger.addHandler(error_handler)
+ self.logger.addHandler(self.file_handler)
+ self.logger.setLevel(logging.DEBUG)
+
+
+ def typewriter_log(
+ self, title="", title_color="", content="", speak_text=False, level=logging.INFO
+ ):
+ # if speak_text and self.speak_mode:
+ # say_text(f"{title}. {content}")
+
+ for plugin in self.chat_plugins:
+ plugin.report(f"{title}. {content}")
+
+ if content:
+ if isinstance(content, list):
+ content = " ".join(content)
+ else:
+ content = ""
+
+ self.logger.log(
+ level, content, extra={"title": title, "color": title_color}
+ )
+
+ def debug(
+ self,
+ message,
+ title="",
+ title_color="",
+ ):
+ self._log(title, title_color, message, logging.DEBUG)
+
+ def info(
+ self,
+ message,
+ title="",
+ title_color="",
+ ):
+ self._log(title, title_color, message, logging.INFO)
+
+ def warn(
+ self,
+ message,
+ title="",
+ title_color="",
+ ):
+ self._log(title, title_color, message, logging.WARN)
+
+ def error(self, title, message=""):
+ self._log(title, Fore.RED, message, logging.ERROR)
+
+ def _log(
+ self,
+ title: str = "",
+ title_color: str = "",
+ message: str = "",
+ level=logging.INFO,
+ ):
+ if message:
+ if isinstance(message, list):
+ message = " ".join(message)
+ self.logger.log(
+ level, message, extra={"title": str(title), "color": str(title_color)}
+ )
+
+ def set_level(self, level):
+ self.logger.setLevel(level)
+ self.typing_logger.setLevel(level)
+
+ def double_check(self, additionalText=None):
+ if not additionalText:
+ additionalText = (
+ "Please ensure you've setup and configured everything"
+ " correctly. Read https://github.com/Torantulino/Auto-GPT#readme to "
+ "double check. You can also create a github issue or join the discord"
+ " and ask there!"
+ )
+
+ self.typewriter_log("DOUBLE CHECK CONFIGURATION", Fore.YELLOW, additionalText)
+
+ def log_json(self, data: Any, file_name: str) -> None:
+ # Define log directory
+ this_files_dir_path = os.path.dirname(__file__)
+ log_dir = os.path.join(this_files_dir_path, "../logs")
+
+ # Create a handler for JSON files
+ json_file_path = os.path.join(log_dir, file_name)
+ json_data_handler = JsonFileHandler(json_file_path)
+ json_data_handler.setFormatter(JsonFormatter())
+
+ # Log the JSON data using the custom file handler
+ self.json_logger.addHandler(json_data_handler)
+ self.json_logger.debug(data)
+ self.json_logger.removeHandler(json_data_handler)
+
+ def get_log_directory(self):
+ this_files_dir_path = os.path.dirname(__file__)
+ log_dir = os.path.join(this_files_dir_path, "../logs")
+ return os.path.abspath(log_dir)
+
+
+"""
+Output stream to console using simulated typing
+"""
+
+
+class TypingConsoleHandler(logging.StreamHandler):
+ def emit(self, record):
+ min_typing_speed = 0.05
+ max_typing_speed = 0.01
+
+ msg = self.format(record)
+ try:
+ words = msg.split()
+ for i, word in enumerate(words):
+ print(word, end="", flush=True)
+ if i < len(words) - 1:
+ print(" ", end="", flush=True)
+ typing_speed = random.uniform(min_typing_speed, max_typing_speed)
+ time.sleep(typing_speed)
+ # type faster after each word
+ min_typing_speed = min_typing_speed * 0.95
+ max_typing_speed = max_typing_speed * 0.95
+ print()
+ except Exception:
+ self.handleError(record)
+
+
+class ConsoleHandler(logging.StreamHandler):
+ def emit(self, record) -> None:
+ msg = self.format(record)
+ try:
+ print(msg)
+ except Exception:
+ self.handleError(record)
+
+
+class RecordFormatter(logging.Formatter):
+ """
+ Allows to handle custom placeholders 'title_color' and 'message_no_color'.
+ To use this formatter, make sure to pass 'color', 'title' as log extras.
+ """
+
+ def format(self, record: LogRecord) -> str:
+ if hasattr(record, "color"):
+ record.title_color = (
+ getattr(record, "color")
+ + getattr(record, "title", "")
+ + " "
+ + Style.RESET_ALL
+ )
+ else:
+ record.title_color = getattr(record, "title", "")
+
+ # Add this line to set 'title' to an empty string if it doesn't exist
+ record.title = getattr(record, "title", "")
+
+ if hasattr(record, "msg"):
+ record.message_no_color = remove_color_codes(getattr(record, "msg"))
+ else:
+ record.message_no_color = ""
+ return super().format(record)
+
+
+def remove_color_codes(s: str) -> str:
+ ansi_escape = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
+ return ansi_escape.sub("", s)
diff --git a/AgentVerseServer/manager.py b/AgentVerseServer/manager.py
new file mode 100644
index 000000000..05f048ad7
--- /dev/null
+++ b/AgentVerseServer/manager.py
@@ -0,0 +1,86 @@
+from __future__ import annotations
+
+import asyncio
+import os
+import threading
+from typing import Dict, List
+
+from fastapi import WebSocket, WebSocketDisconnect, status
+
+from AgentVerseIO.exception import (
+ AgentVerseIOWebSocketReceiveError,
+ AgentVerseIOWebSocketSendError,
+)
+from AgentVerseServer.envs import AgentVerseServerEnv
+from AgentVerseServer.loggers.logs import Logger
+from AgentVerseServer.response_body import WebsocketResponseBody
+
+
+class Singleton(type):
+ _instances = {}
+
+ def __call__(cls, *args, **kwargs):
+ if cls not in cls._instances:
+ cls._instances[cls] = super().__call__(*args, **kwargs)
+ return cls._instances[cls]
+
+
+class WebSocketConnectionManager(metaclass=Singleton):
+ def __init__(self):
+ self.active_connections: List[Dict[str, WebSocket]] = []
+ self.logger = Logger(
+ log_dir=os.path.join(AgentVerseServerEnv.base_dir, "logs"),
+ log_file="websocket.log",
+ )
+
+ self.create_pong_task()
+
+ async def connect(self, websocket: WebSocket, websocket_id: str):
+ await websocket.accept()
+ self.logger.info(f"websocket {websocket_id} connected")
+ self.active_connections.append({websocket_id: websocket})
+
+ async def disconnect(self, websocket_id: str, websocket: WebSocket):
+ self.active_connections.remove({websocket_id: websocket})
+ self.logger.info(f"websocket {websocket_id} remove from active connections")
+
+ def is_connected(self, websocket_id: str) -> bool:
+ for connection in self.active_connections:
+ if websocket_id in connection.keys():
+ return True
+ return False
+
+ def get_connection(self, websocket_id: str) -> WebSocket:
+ for connection in self.active_connections:
+ if websocket_id in connection.keys():
+ return connection[websocket_id]
+ return None
+
+ async def broadcast_pong(self):
+ while True:
+ self.logger.info(
+ f"pong broadcast for active connections: {len(self.active_connections)}"
+ )
+
+ # for connection in self.active_connections:
+ # for websocket_id, websocket in connection.items():
+ # # websocket.websocket_timeout = 15
+ # try:
+ # await websocket.send_text(
+ # WebsocketResponseBody(
+ # status="pong", data={"type": "pong"}, message="pong"
+ # ).to_text()
+ # )
+ # except Exception as e:
+ # # self.logger.error(f"websocket {websocket_id} is disconnected")
+ # # self.active_connections.remove(connection)
+ # continue
+ await asyncio.sleep(40)
+
+ def loop_pong(self):
+ asyncio.run(self.broadcast_pong())
+
+ def create_pong_task(self):
+ self.logger.info("Create task for pong broadcast")
+ pong = threading.Thread(target=self.loop_pong, daemon=True)
+ pong.start()
diff --git a/AgentVerseServer/models/interaction.py b/AgentVerseServer/models/interaction.py
new file mode 100644
index 000000000..4e2b20425
--- /dev/null
+++ b/AgentVerseServer/models/interaction.py
@@ -0,0 +1,72 @@
+"""
+"""
+
+import abc
+import json
+
+
+class InteractionBase(metaclass=abc.ABCMeta):
+ def __init__(
+ self,
+ interaction_id: str,
+ user_id: str,
+ create_time: str,
+ description: str,
+ recorder_root_dir: str = "",
+ status: str = "",
+ message: str = "",
+ current_step: str = "",
+ update_time: str = "",
+ is_deleted: bool = False,
+ ):
+ self.interaction_id = interaction_id
+ self.user_id = user_id
+ self.create_time = create_time
+ self.description = description
+ self.recorder_root_dir = recorder_root_dir
+ self.status = status
+ self.message = message
+ self.current_step = current_step
+ self.update_time = update_time
+ self.is_deleted = is_deleted
+
+ def to_dict(self, include=None, exclude=None):
+ data = {
+ "interaction_id": self.interaction_id,
+ "user_id": self.user_id,
+ "create_time": self.create_time,
+ "description": self.description,
+ "recorder_root_dir": self.recorder_root_dir,
+ "status": self.status,
+ "message": self.message,
+ "current_step": self.current_step,
+ "update_time": self.update_time,
+ "is_deleted": self.is_deleted,
+ }
+ if include:
+ data = {k: v for k, v in data.items() if k in include}
+ if exclude:
+ data = {k: v for k, v in data.items() if k not in exclude}
+ return data
+
+ def to_json(self):
+ return json.dumps(self.to_dict(), indent=2, ensure_ascii=False)
+
+ @classmethod
+ def from_json(cls, json_data):
+ return cls(**json_data)
+
+ @classmethod
+ def from_db(cls, interaction):
+ return cls(
+ interaction.interaction_id,
+ interaction.user_id,
+ interaction.create_time,
+ interaction.description,
+ interaction.recorder_root_dir,
+ interaction.status,
+ interaction.message,
+ interaction.current_step,
+ interaction.update_time,
+ interaction.is_deleted,
+ )
diff --git a/AgentVerseServer/models/node.py b/AgentVerseServer/models/node.py
new file mode 100644
index 000000000..1c1c50328
--- /dev/null
+++ b/AgentVerseServer/models/node.py
@@ -0,0 +1,35 @@
+import abc
+import json
+import uuid
+
+
+class Node(metaclass=abc.ABCMeta):
+ def __init__(
+ self,
+ thoughts: str,
+ using_tools: str,
+ is_last: bool = False,
+ node_id: str = None,
+ ):
+ if node_id is None:
+ self.node_id = uuid.uuid4().hex
+ else:
+ self.node_id = node_id
+ self.thoughts = thoughts
+ self.using_tools = using_tools
+ self.is_last = is_last
+
+ def to_dict(self):
+ return {
+ "node_id": self.node_id,
+ "thoughts": self.thoughts,
+ "using_tools": self.using_tools,
+ "is_last": self.is_last,
+ }
+
+ def to_json(self):
+ return json.dumps(self.to_dict(), indent=2, ensure_ascii=False)
+
+ @classmethod
+ def from_json(cls, json_data):
+ return cls(**json_data)
diff --git a/AgentVerseServer/models/parameter.py b/AgentVerseServer/models/parameter.py
new file mode 100644
index 000000000..a4137ef52
--- /dev/null
+++ b/AgentVerseServer/models/parameter.py
@@ -0,0 +1,35 @@
+import abc
+import json
+from typing import Union
+
+
+class InteractionParameter(metaclass=abc.ABCMeta):
+ def __init__(self,
+ interaction_id: str,
+ parameter_id: str,
+ args: Union[str, dict, None] = None
+ ):
+ self.interaction_id = interaction_id
+ self.args = args
+ self.parameter_id = parameter_id
+
+ def to_dict(self):
+ return {
+ "interaction_id": self.interaction_id,
+ "parameter_id": self.parameter_id,
+ "args": self.args,
+ }
+
+ def to_json(self):
+ return json.dumps(self.to_dict(), indent=2, ensure_ascii=False)
+
+ @classmethod
+ def from_json(cls, json_data):
+ return cls(**json_data)
+
+ @classmethod
+ def from_db(cls, interaction):
+ return cls(interaction.interaction_id,
+ interaction.parameter_id,
+ interaction.args
+ )
\ No newline at end of file
diff --git a/AgentVerseServer/models/shared_interaction.py b/AgentVerseServer/models/shared_interaction.py
new file mode 100644
index 000000000..68846fd15
--- /dev/null
+++ b/AgentVerseServer/models/shared_interaction.py
@@ -0,0 +1,69 @@
+"""
+"""
+
+import abc
+import json
+
+
+class SharedInteractionBase(metaclass=abc.ABCMeta):
+ def __init__(self,
+ interaction_id: str,
+ user_name: str,
+ create_time: str,
+ update_time: str,
+ description: str,
+ agent: str = "",
+ mode: str = "",
+ is_deleted: bool = False,
+ star: int = 0,
+ record_dir: str = "",
+ ):
+ self.interaction_id = interaction_id
+ self.user_name = user_name
+ self.create_time = create_time
+ self.update_time = update_time
+ self.description = description
+ self.agent = agent
+ self.mode = mode
+ self.is_deleted = is_deleted
+ self.star = star
+ self.record_dir = record_dir
+
+ def to_dict(self, include=None, exclude=None):
+ data = {
+ "interaction_id": self.interaction_id,
+ "user_name": self.user_name,
+ "create_time": self.create_time,
+ "update_time": self.update_time,
+ "description": self.description,
+ "agent": self.agent,
+ "mode": self.mode,
+ "is_deleted": self.is_deleted,
+ "star": self.star,
+ "record_dir": self.record_dir,
+ }
+ if include:
+ data = {k: v for k, v in data.items() if k in include}
+ if exclude:
+ data = {k: v for k, v in data.items() if k not in exclude}
+ return data
+
+
+ def to_json(self):
+ return json.dumps(self.to_dict(), indent=2, ensure_ascii=False)
+
+ @classmethod
+ def from_db(cls, interaction):
+ return cls(interaction.interaction_id,
+ interaction.user_name,
+ interaction.create_time,
+ interaction.update_time,
+ interaction.description,
+ interaction.agent,
+ interaction.mode,
+ interaction.is_deleted,
+ interaction.star,
+ interaction.record_dir,
+ )
+
+
\ No newline at end of file
diff --git a/AgentVerseServer/models/subround.py b/AgentVerseServer/models/subround.py
new file mode 100644
index 000000000..a6dc63445
--- /dev/null
+++ b/AgentVerseServer/models/subround.py
@@ -0,0 +1,66 @@
+import abc
+import json
+import uuid
+from AgentVerseServer.models.node import Node
+
+
+class Subround(metaclass=abc.ABCMeta):
+ def __init__(
+ self,
+ name: str = "",
+ goal: str = "",
+ exceute_status: str = "",
+ task_id: str = "",
+ recruitment: list = None,
+ decision_make: list = None,
+ aciton_exectuion: list = None,
+ evaluation: list = None,
+ node_id: str = None,
+ refinement: dict = None,
+ ):
+ self.name = name
+ self.goal = goal
+ self.task_id = task_id
+ self.exceute_status = exceute_status
+ self.recruitment = recruitment
+ self.decision_make = decision_make
+ self.aciton_exectuion = aciton_exectuion
+ self.evaluation = evaluation
+ self.refinement = refinement
+ if node_id is None:
+ self.node_id = uuid.uuid4().hex
+ else:
+ self.node_id = node_id
+
+ def to_dict(self):
+ return {
+ "node_id": self.node_id,
+ "task_id": self.task_id,
+ "name": self.name,
+ "goal": self.goal,
+ "exceute_status": self.exceute_status,
+ "refinement": self.refinement,
+ "recruitment": [
+ node.to_dict() if isinstance(node, Node) else node
+ for node in self.recruitment
+ ],
+ "decision_makes": [
+ node.to_dict() if isinstance(node, Node) else node
+ for node in self.decision_make
+ ],
+ "aciton_exectuion": [
+ node.to_dict() if isinstance(node, Node) else node
+ for node in self.aciton_exectuion
+ ],
+ "evaluation": [
+ node.to_dict() if isinstance(node, Node) else node
+ for node in self.evaluation
+ ],
+ }
+
+ def to_json(self):
+ return json.dumps(self.to_dict(), indent=2, ensure_ascii=False)
+
+ @classmethod
+ def from_json(cls, json_data):
+ return cls(**json_data)
diff --git a/AgentVerseServer/models/user.py b/AgentVerseServer/models/user.py
new file mode 100644
index 000000000..114d4d7c6
--- /dev/null
+++ b/AgentVerseServer/models/user.py
@@ -0,0 +1,100 @@
+import abc
+import json
+
+from AgentVerseServer.database.models import User
+
+
+class AgentVerseUser(metaclass=abc.ABCMeta):
+ def __init__(
+ self,
+ user_id: str,
+ email: str,
+ name: str,
+ token: str,
+ available: bool = True,
+ corporation: str = None,
+ industry: str = None,
+ position: str = None,
+ create_time: str = None,
+ update_time: str = None,
+ deleted: bool = False,
+ ):
+ self.user_id = user_id
+ self.email = email
+ self.name = name
+ self.token = token
+ self.available = available
+ self.corporation = corporation
+ self.industry = industry
+ self.position = position
+ self.create_time = create_time
+ self.update_time = update_time
+ self.deleted = deleted
+
+ def to_dict(self):
+ return {
+ "user_id": self.user_id,
+ "email": self.email,
+ "name": self.name,
+ "token": self.token,
+ "available": self.available,
+ "corporation": self.corporation,
+ "industry": self.industry,
+ "position": self.position,
+ "create_time": self.create_time,
+ "update_time": self.update_time,
+ "deleted": self.deleted,
+ }
+
+ def to_json(self):
+ return json.dumps(self.to_dict(), indent=2, ensure_ascii=False)
+
+ @staticmethod
+ def from_dict(user_dict: dict):
+ return AgentVerseUser(
+ user_id=user_dict["user_id"],
+ email=user_dict["email"],
+ name=user_dict["name"],
+ token=user_dict["token"],
+ available=user_dict["available"],
+ corporation=user_dict["corporation"],
+ industry=user_dict["industry"],
+ position=user_dict["position"],
+ create_time=user_dict["create_time"],
+ update_time=user_dict["update_time"],
+ deleted=user_dict["deleted"],
+ )
+
+ @staticmethod
+ def from_json(user_json: str):
+ return AgentVerseUser.from_dict(json.loads(user_json))
+
+ def is_available(self):
+ return self.available
+
+ @staticmethod
+ def from_db(user: User):
+ user_id = user.user_id
+ email = user.email
+ name = user.name
+ token = user.token
+ available = user.available
+ corporation = user.corporation
+ industry = user.industry
+ position = user.position
+ create_time = user.create_time
+ update_time = user.update_time
+ deleted = user.deleted
+ return AgentVerseUser(
+ user_id=user_id,
+ email=email,
+ name=name,
+ token=token,
+ available=available,
+ corporation=corporation,
+ industry=industry,
+ position=position,
+ create_time=create_time,
+ update_time=update_time,
+ deleted=deleted,
+ )
diff --git a/AgentVerseServer/models/ws.py b/AgentVerseServer/models/ws.py
new file mode 100644
index 000000000..8dfed4e7e
--- /dev/null
+++ b/AgentVerseServer/models/ws.py
@@ -0,0 +1,47 @@
+import abc
+import json
+import uuid
+
+from AgentVerseServer.models.subround import Subround
+
+
+class AgentVerseOutputData(metaclass=abc.ABCMeta):
+ def __init__(
+ self,
+ task_id: str,
+ name: str,
+ goal: str,
+ subrounds: None,
+ node_id: str = None,
+ ):
+ if subrounds is None:
+ subrounds = []
+ self.name = name
+ self.goal = goal
+ self.task_id = task_id
+ self.subrounds = subrounds
+ if node_id is None:
+ self.node_id = uuid.uuid4().hex
+ else:
+ self.node_id = node_id
+
+ def to_dict(self):
+ return {
+ "task_id": self.task_id,
+ "node_id": self.node_id,
+ "name": self.name,
+ "goal": self.goal,
+ "subrounds": [subround.to_dict() for subround in self.subrounds],
+ }
+
+ def to_json(self):
+ return json.dumps(self.to_dict(), indent=2, ensure_ascii=False)
+
+ @classmethod
+ def from_json(cls, json_data):
+ return cls(**json_data)
+
+ def update(self, update_data: dict):
+ for k, v in update_data.items():
+ setattr(self, k, v)
+ return self
diff --git a/AgentVerseServer/nginx/nginx.conf b/AgentVerseServer/nginx/nginx.conf
new file mode 100644
index 000000000..9202e604a
--- /dev/null
+++ b/AgentVerseServer/nginx/nginx.conf
@@ -0,0 +1,80 @@
+user root;
+worker_processes auto;
+pid /run/nginx.pid;
+include /etc/nginx/modules-enabled/*.conf;
+
+events {
+ worker_connections 768;
+}
+
+error_log /var/log/nginx/error.log warn;
+
+http {
+ sendfile on;
+ tcp_nopush on;
+ client_max_body_size 1024m;
+ tcp_nodelay on;
+ keepalive_timeout 65;
+ types_hash_max_size 2048;
+
+ map $http_upgrade $connection_upgrade {
+ default keep-alive; #默认为keep-alive 可以支持 一般http请求
+ 'websocket' upgrade; #如果为websocket 则为 upgrade 可升级的。
+
+ }
+
+ log_format detailreq escape=json '{ "@timestamp": "$time_iso8601", '
+ '"remote_addr": "$remote_addr",'
+ '"costime": "$request_time",'
+ '"realtime": "$upstream_response_time",'
+ '"status": $status,'
+ '"x_forwarded": "$http_x_forwarded_for",'
+ '"referer": "$http_referer",'
+ '"request": "$request",'
+ '"upstr_addr": "$upstream_addr",'
+ '"bytes":$body_bytes_sent,'
+ '"agent": "$http_user_agent" }';
+
+ access_log /var/log/nginx/access.log detailreq;
+
+ error_log /var/log/nginx/error.log;
+
+ include /etc/nginx/mime.types;
+ default_type application/octet-stream;
+
+
+ ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
+ ssl_prefer_server_ciphers on;
+
+ gzip on;
+
+ include /etc/nginx/conf.d/*.conf;
+ include /etc/nginx/sites-enabled/*;
+
+ # agentverse
+ server {
+ listen 5173;
+ server_name 127.0.0.1;
+ #此处是前端的请求
+ location / {
+ root /app/dist;
+ index index.html;
+ try_files $uri $uri/ /index.html;
+ }
+ #动态请求 这个是后端的请求
+ location /api {
+ proxy_pass http://127.0.0.1:8090;
+ proxy_set_header Host $host;
+ rewrite "^/api/(.*)$" /$1 break;
+ }
+ location ^~ /ws {
+ proxy_pass http://127.0.0.1:8090/ws;
+ proxy_set_header Host $host;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection $connection_upgrade;
+ }
+
+ # Load configuration files for the default server block.
+ include /etc/nginx/default.d/*.conf;
+ }
+}
diff --git a/AgentVerseServer/request_body.py b/AgentVerseServer/request_body.py
new file mode 100644
index 000000000..1d900a229
--- /dev/null
+++ b/AgentVerseServer/request_body.py
@@ -0,0 +1,34 @@
+import re
+from typing import Optional, Union
+from fastapi import Form
+from pydantic import BaseModel, validator
+from typing import Union
+class User(BaseModel):
+ email: str
+ token: Union[str, None] = None
+
+ @validator("email")
+ def email_is_valid(cls, v):
+ if v == "":
+ raise ValueError("email is empty")
+ if re.match(r"[^@]+@[^@]+\.[^@]+", v) == None:
+ raise ValueError("email is invalid")
+
+ return v
+
+
+
+ # @validator("email")
+ # def email_is_valid(cls, v):
+ # if v == "":
+ # raise ValueError("email is empty")
+ # if re.match(r"[^@]+@[^@]+\.[^@]+", v) == None:
+ # raise ValueError("email is invalid")
+
+ # return v
+
+
+class RequestBody(BaseModel):
+ token: str
+ query: str
+ mode: str
diff --git a/AgentVerseServer/requirements.txt b/AgentVerseServer/requirements.txt
new file mode 100644
index 000000000..54e12a614
--- /dev/null
+++ b/AgentVerseServer/requirements.txt
@@ -0,0 +1,18 @@
+uvicorn
+fastapi
+yagmail
+inputimeout
+sqlalchemy
+python-multipart
+colorama
+json5
+func_timeout
+openai
+regex
+jsonschema
+tiktoken
+tenacity
+pinecone-client
+python-dotenv
+markdown2
+websockets
\ No newline at end of file
diff --git a/AgentVerseServer/response_body.py b/AgentVerseServer/response_body.py
new file mode 100644
index 000000000..9b348f4c8
--- /dev/null
+++ b/AgentVerseServer/response_body.py
@@ -0,0 +1,35 @@
+import json
+from typing import Optional, Union
+
+from pydantic import BaseModel, Json
+
+
+class ResponseBody(BaseModel):
+ data: Union[str, dict, list, Json, None] = None
+ success: bool = True
+ message: Union[str, None] = None
+
+ def to_dict(self):
+ return self.dict()
+
+ def to_json(self):
+ return self.json()
+
+
+class WebsocketResponseBody():
+ def __init__(self, data: Union[str, dict, list, Json, None], status: str = "success", message: Union[str, None] = None, **kwargs):
+ self.data = data
+ self.status = status
+ self.message = message
+ self.extend(kwargs)
+
+
+ def to_text(self):
+ return json.dumps(self.__dict__, ensure_ascii=False, indent=2)
+
+
+ def extend(self, extend: dict):
+ for key, value in extend.items():
+ if key not in self.__dict__.keys():
+ self.__dict__[key] = value
+
diff --git a/AgentVerseServer/server.py b/AgentVerseServer/server.py
new file mode 100644
index 000000000..b8e3c3a7a
--- /dev/null
+++ b/AgentVerseServer/server.py
@@ -0,0 +1,46 @@
+import json
+import os
+import traceback
+
+from colorama import Fore
+
+from AgentVerseServer.envs import AgentVerseServerEnv
+from AgentVerseServer.interaction import AgentVerseInteraction
+from agentverse.logging import Logger
+
+# from AgentVerseServer.manager import manager
+from AgentVerseServer.response_body import WebsocketResponseBody
+
+
+class AgentVerseServer:
+ def __init__(self) -> None:
+ self.logger: Logger = None
+
+ def set_logger(self, logger):
+ self.logger = logger
+
+ async def interact(self, interaction: AgentVerseInteraction):
+ from agentverse.tasksolving import TaskSolving
+
+ web_tasks_dir = os.path.join(
+ os.path.dirname(__file__), "..", "agentverse", "tasks"
+ )
+ web_task = "tasksolving/tool_using/24point"
+ agentversepipeline = TaskSolving.from_task(
+ web_task,
+ web_tasks_dir,
+ cnt_agents=int(
+ interaction.parameter.args["goal"]["_object"]["currentInput"][
+ "cnt_agents"
+ ]
+ ),
+ task_description=interaction.parameter.args["goal"]["_object"][
+ "currentInput"
+ ]["task_des"],
+ )
+
+ try:
+ self.logger.info(f"Start TaskSolving")
+ await agentversepipeline.run(interaction=interaction)
+ except Exception:
+ self.logger.info(traceback.format_exc())
diff --git a/AgentVerseServer/utils.py b/AgentVerseServer/utils.py
new file mode 100644
index 000000000..9083c1873
--- /dev/null
+++ b/AgentVerseServer/utils.py
@@ -0,0 +1,204 @@
+import abc
+import asyncio
+import json
+import os
+import random
+import shutil
+import time
+import traceback
+
+from fastapi import WebSocket
+
+from AgentVerseServer.database import InteractionBaseInterface, UserBaseInterface
+from AgentVerseServer.envs import AgentVerseServerEnv
+from AgentVerseServer.models.interaction import InteractionBase
+from AgentVerseServer.models.shared_interaction import SharedInteractionBase
+from AgentVerseServer.response_body import WebsocketResponseBody
+
+
+class Util(metaclass=abc.ABCMeta):
+ @staticmethod
+ def send_message(client, message):
+ client.sendall(message.encode())
+
+ @staticmethod
+ def recv_message(client):
+ return client.recv(1024).decode()
+
+
+class AutoReplayUtil(metaclass=abc.ABCMeta):
+ @staticmethod
+ async def do_replay(websocket: WebSocket, base: InteractionBase):
+ with open(
+ os.path.join(
+ AgentVerseServerEnv.base_dir,
+ "localstorage",
+ "interact_records",
+ base.create_time[:10],
+ base.interaction_id,
+ "cache.json",
+ ),
+ "r",
+ ) as f:
+ history = json.load(f)
+
+ await AutoReplayUtil.do_replay_start(websocket, history)
+
+ @staticmethod
+ async def do_replay_start(websocket: WebSocket, history: dict):
+ init_data = {}
+ for key, value in history.items():
+ if key == "subtasks":
+ init_data[key] = [{**v, "inner": []} for v in value]
+ else:
+ init_data[key] = value
+
+ await asyncio.sleep(random.randint(1, 5))
+ await websocket.send_text(
+ WebsocketResponseBody(
+ status="start", data=init_data, message="success"
+ ).to_text()
+ )
+
+ await AutoReplayUtil.do_auto_replay(websocket, history)
+
+ @staticmethod
+ async def do_auto_replay(websocket: WebSocket, history: dict):
+ cache_list = history.get("subtasks", [])
+ item = cache_list.pop(0)
+ while item is not None:
+ inner = item.get("inner", [])
+ if inner:
+ inner_props = inner.pop(0)
+ while inner_props is not None:
+ send = True
+ tool_name = (
+ inner_props.get("using_tools", {}).get("tool_name", "")
+ if isinstance(inner_props, dict)
+ else ""
+ )
+
+ await asyncio.sleep(random.randint(1, 5))
+ if tool_name == "subtask_submit":
+ send_data = {
+ "task_id": item.get("task_id", ""),
+ "name": item.get("name", ""),
+ "goal": item.get("goal", ""),
+ "handler": item.get("handler", ""),
+ "data": inner_props,
+ "current": item.get("task_id", ""),
+ "status": "subtask_submit",
+ "message": "",
+ }
+
+ else:
+ send_data = {
+ "task_id": item.get("task_id", ""),
+ "name": item.get("name", ""),
+ "goal": item.get("goal", ""),
+ "handler": item.get("handler", ""),
+ "data": inner_props,
+ "current": item.get("task_id", ""),
+ "status": "inner",
+ "message": "",
+ }
+ await websocket.send_text(
+ WebsocketResponseBody(**send_data).to_text()
+ )
+ if inner:
+ inner_props = inner.pop(0)
+ else:
+ inner_props = None
+ if inner_props is None:
+ await asyncio.sleep(random.randint(1, 5))
+ send_data = {
+ "task_id": item.get("task_id", ""),
+ "name": item.get("name", ""),
+ "goal": item.get("goal", ""),
+ "handler": item.get("handler", ""),
+ "data": item.get("refinement", {}),
+ "current": item.get("task_id", ""),
+ "status": "refinement",
+ "message": "",
+ }
+ await websocket.send_text(
+ WebsocketResponseBody(**send_data).to_text()
+ )
+ await asyncio.sleep(5)
+
+ if cache_list:
+ await asyncio.sleep(random.randint(1, 5))
+ sub_send_data = {
+ "data": [{**r_, "inner": []} for r_ in cache_list],
+ "current": cache_list[0]["task_id"],
+ "status": "subtask",
+ "message": "",
+ }
+
+ await websocket.send_text(
+ WebsocketResponseBody(**sub_send_data).to_text()
+ )
+ item = cache_list.pop(0)
+ else:
+ item = None
+
+
+class ShareUtil(metaclass=abc.ABCMeta):
+ db: InteractionBaseInterface = None
+ user_db: UserBaseInterface = None
+
+ @staticmethod
+ def register_db(db, user_db):
+ ShareUtil.db = db
+ ShareUtil.user_db = user_db
+
+ @staticmethod
+ def share_interaction(interaction_id: str, user_id: str):
+ try:
+ interaction = ShareUtil.db.get_interaction(interaction_id)
+ if interaction is None:
+ return False
+ user_name = ShareUtil.user_db.get_user(user_id).name
+ record_dir = os.path.join(
+ AgentVerseServerEnv.base_dir,
+ "localstorage",
+ "interact_records",
+ interaction.create_time[:10],
+ interaction_id,
+ )
+ if not os.path.exists(record_dir):
+ return False
+ shared_dir = os.path.join(
+ AgentVerseServerEnv.base_dir,
+ "localstorage",
+ "shared_interact_records",
+ interaction_id,
+ )
+ if not os.path.exists(shared_dir):
+ os.makedirs(shared_dir)
+ for file in os.listdir(record_dir):
+ shutil.copy(os.path.join(record_dir, file), shared_dir)
+ shared = SharedInteractionBase(
+ interaction_id=interaction_id,
+ user_name=user_name,
+ create_time=interaction.create_time,
+ update_time=interaction.update_time,
+ description=interaction.description,
+ agent=interaction.agent,
+ mode=interaction.mode,
+ is_deleted=interaction.is_deleted,
+ star=0,
+ record_dir=shared_dir,
+ )
+ ShareUtil.db.add_share(shared)
+ return True
+ except Exception as e:
+ traceback.print_exc()
+ return False
+
+ @staticmethod
+ async def do_replay(websocket: WebSocket, shared: SharedInteractionBase):
+ with open(os.path.join(shared.record_dir, "cache.json"), "r") as f:
+ history = json.load(f)
+
+ await AutoReplayUtil.do_replay_start(websocket, history)
diff --git a/AgentVerseWeb/.gitignore b/AgentVerseWeb/.gitignore
new file mode 100644
index 000000000..163eb9577
--- /dev/null
+++ b/AgentVerseWeb/.gitignore
@@ -0,0 +1,30 @@
+.DS_Store
+**/.DS_Store
+.DS_Store?
+
+
+/build
+/dist
+/node_modules
+node_modules/
+dist/
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+yarn.lock
+package-lock.json
+tests/**/coverage/
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+yarn.lock
+yarn.lock
+*.lock
+yarn.lock
+package-lock.json
+src/api/backend.ts
diff --git a/AgentVerseWeb/Dockerfile b/AgentVerseWeb/Dockerfile
new file mode 100644
index 000000000..ee715d39e
--- /dev/null
+++ b/AgentVerseWeb/Dockerfile
@@ -0,0 +1,35 @@
+# FROM 基于node的版本镜像,并通过构建阶段命名,将有node环境的阶段命名为build-stage
+FROM node:lts-alpine as build-stage
+# 设置工作区为 /build 于系统文件隔离
+WORKDIR /build
+# copy package.json/package-lock.json 到容器 /build 目录
+COPY package*.json ./
+# 在容器中安装依赖
+RUN npm install
+# 拷贝其他文件到容器 /build 目录,分两次拷贝是因为保持 node_modules 一致
+COPY . .
+# 打包
+RUN npm run build:prod_docker
+
+# production stage
+FROM nginx:alpine as production-stage
+WORKDIR /app
+COPY --from=build-stage /build/dist /usr/share/nginx/html
+EXPOSE 3000
+# CMD ["npm", "start"]
+
+# 创建镜像
+# docker build . -t test-image:latest
+# 通过 docker images 命令查看所有镜像
+# docker images
+
+# 创建并启动container 映射端口 本地/linux 默认80 例 3000/80
+# docker run -d -p 3000:80 --rm --name test-container test-image:latest
+# run:创建并运行 docker 容器
+# -d: 后台运行容器
+# 3000:80:将当前服务器的 80 端口(冒号前的 80),映射到容器的 80 端口(冒号后的 80)
+# --name:给容器命名,便于之后定位容器
+# test-image:latest:基于 test-image 最新版本的镜像创建容器
+
+
+
diff --git a/AgentVerseWeb/README.md b/AgentVerseWeb/README.md
new file mode 100644
index 000000000..c52aa6227
--- /dev/null
+++ b/AgentVerseWeb/README.md
@@ -0,0 +1,22 @@
+# AgentVerse
+
+A large-scale agent-based model by Tsinghua University NLP lab.
+
+
+
+## Install Dependencies 安装依赖
+
+```bash
+npm install
+```
+
+## Modify code in Node_Modules 修改node_modules中的文件
+
+
+
+## Run 运行
+
+```bash
+npm run dev
+```
+
diff --git a/AgentVerseWeb/auto-imports.d.ts b/AgentVerseWeb/auto-imports.d.ts
new file mode 100644
index 000000000..5c5ac8f6c
--- /dev/null
+++ b/AgentVerseWeb/auto-imports.d.ts
@@ -0,0 +1,666 @@
+// Generated by 'unplugin-auto-import'
+export {}
+declare global {
+ const AUTH_STATE: typeof import('./src/composables/useEnums')['AUTH_STATE']
+ const AesEncryption: typeof import('./src/composables/useCrypto')['AesEncryption']
+ const CACHE_LOCATION: typeof import('./src/composables/useEnums')['CACHE_LOCATION']
+ const EffectScope: typeof import('vue')['EffectScope']
+ const HISTORY_TALK: typeof import('./src/composables/useEnums')['HISTORY_TALK']
+ const RoleEnum: typeof import('./types/user')['RoleEnum']
+ const STORAGE_TOKEN: typeof import('./src/composables/useEnums')['STORAGE_TOKEN']
+ const TOKEN: typeof import('./src/composables/useEnums')['TOKEN']
+ const USER_INFO: typeof import('./src/composables/useEnums')['USER_INFO']
+ const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
+ const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
+ const autoResetRef: typeof import('@vueuse/core')['autoResetRef']
+ const computed: typeof import('vue')['computed']
+ const computedAsync: typeof import('@vueuse/core')['computedAsync']
+ const computedEager: typeof import('@vueuse/core')['computedEager']
+ const computedInject: typeof import('@vueuse/core')['computedInject']
+ const computedWithControl: typeof import('@vueuse/core')['computedWithControl']
+ const controlledComputed: typeof import('@vueuse/core')['controlledComputed']
+ const controlledRef: typeof import('@vueuse/core')['controlledRef']
+ const createApp: typeof import('vue')['createApp']
+ const createEventHook: typeof import('@vueuse/core')['createEventHook']
+ const createGlobalState: typeof import('@vueuse/core')['createGlobalState']
+ const createInjectionState: typeof import('@vueuse/core')['createInjectionState']
+ const createPinia: typeof import('pinia')['createPinia']
+ const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn']
+ const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable']
+ const createUnrefFn: typeof import('@vueuse/core')['createUnrefFn']
+ const customRef: typeof import('vue')['customRef']
+ const debouncedRef: typeof import('@vueuse/core')['debouncedRef']
+ const debouncedWatch: typeof import('@vueuse/core')['debouncedWatch']
+ const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
+ const defineComponent: typeof import('vue')['defineComponent']
+ const defineStore: typeof import('pinia')['defineStore']
+ const eagerComputed: typeof import('@vueuse/core')['eagerComputed']
+ const effectScope: typeof import('vue')['effectScope']
+ const extendRef: typeof import('@vueuse/core')['extendRef']
+ const getActivePinia: typeof import('pinia')['getActivePinia']
+ const getCurrentInstance: typeof import('vue')['getCurrentInstance']
+ const getCurrentScope: typeof import('vue')['getCurrentScope']
+ const globalD: typeof import('./types/global.d')['default']
+ const h: typeof import('vue')['h']
+ const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch']
+ const inject: typeof import('vue')['inject']
+ const isDefined: typeof import('@vueuse/core')['isDefined']
+ const isProxy: typeof import('vue')['isProxy']
+ const isReactive: typeof import('vue')['isReactive']
+ const isReadonly: typeof import('vue')['isReadonly']
+ const isRef: typeof import('vue')['isRef']
+ const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable']
+ const mapActions: typeof import('pinia')['mapActions']
+ const mapGetters: typeof import('pinia')['mapGetters']
+ const mapState: typeof import('pinia')['mapState']
+ const mapStores: typeof import('pinia')['mapStores']
+ const mapWritableState: typeof import('pinia')['mapWritableState']
+ const markRaw: typeof import('vue')['markRaw']
+ const nextTick: typeof import('vue')['nextTick']
+ const onActivated: typeof import('vue')['onActivated']
+ const onBeforeMount: typeof import('vue')['onBeforeMount']
+ const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']
+ const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate']
+ const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
+ const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
+ const onClickOutside: typeof import('@vueuse/core')['onClickOutside']
+ const onDeactivated: typeof import('vue')['onDeactivated']
+ const onErrorCaptured: typeof import('vue')['onErrorCaptured']
+ const onKeyStroke: typeof import('@vueuse/core')['onKeyStroke']
+ const onLongPress: typeof import('@vueuse/core')['onLongPress']
+ const onMounted: typeof import('vue')['onMounted']
+ const onRenderTracked: typeof import('vue')['onRenderTracked']
+ const onRenderTriggered: typeof import('vue')['onRenderTriggered']
+ const onScopeDispose: typeof import('vue')['onScopeDispose']
+ const onServerPrefetch: typeof import('vue')['onServerPrefetch']
+ const onStartTyping: typeof import('@vueuse/core')['onStartTyping']
+ const onUnmounted: typeof import('vue')['onUnmounted']
+ const onUpdated: typeof import('vue')['onUpdated']
+ const pausableWatch: typeof import('@vueuse/core')['pausableWatch']
+ const provide: typeof import('vue')['provide']
+ const reactify: typeof import('@vueuse/core')['reactify']
+ const reactifyObject: typeof import('@vueuse/core')['reactifyObject']
+ const reactive: typeof import('vue')['reactive']
+ const reactiveComputed: typeof import('@vueuse/core')['reactiveComputed']
+ const reactiveOmit: typeof import('@vueuse/core')['reactiveOmit']
+ const reactivePick: typeof import('@vueuse/core')['reactivePick']
+ const readonly: typeof import('vue')['readonly']
+ const ref: typeof import('vue')['ref']
+ const refAutoReset: typeof import('@vueuse/core')['refAutoReset']
+ const refDebounced: typeof import('@vueuse/core')['refDebounced']
+ const refDefault: typeof import('@vueuse/core')['refDefault']
+ const refThrottled: typeof import('@vueuse/core')['refThrottled']
+ const refWithControl: typeof import('@vueuse/core')['refWithControl']
+ const resolveComponent: typeof import('vue')['resolveComponent']
+ const resolveDirective: typeof import('vue')['resolveDirective']
+ const resolveRef: typeof import('@vueuse/core')['resolveRef']
+ const resolveUnref: typeof import('@vueuse/core')['resolveUnref']
+ const setActivePinia: typeof import('pinia')['setActivePinia']
+ const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix']
+ const setupStore: typeof import('./src/store/index')['setupStore']
+ const shallowReactive: typeof import('vue')['shallowReactive']
+ const shallowReadonly: typeof import('vue')['shallowReadonly']
+ const shallowRef: typeof import('vue')['shallowRef']
+ const store: typeof import('./src/store/index')['store']
+ const storeToRefs: typeof import('pinia')['storeToRefs']
+ const syncRef: typeof import('@vueuse/core')['syncRef']
+ const syncRefs: typeof import('@vueuse/core')['syncRefs']
+ const templateRef: typeof import('@vueuse/core')['templateRef']
+ const throttledRef: typeof import('@vueuse/core')['throttledRef']
+ const throttledWatch: typeof import('@vueuse/core')['throttledWatch']
+ const toRaw: typeof import('vue')['toRaw']
+ const toReactive: typeof import('@vueuse/core')['toReactive']
+ const toRef: typeof import('vue')['toRef']
+ const toRefs: typeof import('vue')['toRefs']
+ const triggerRef: typeof import('vue')['triggerRef']
+ const tryOnBeforeMount: typeof import('@vueuse/core')['tryOnBeforeMount']
+ const tryOnBeforeUnmount: typeof import('@vueuse/core')['tryOnBeforeUnmount']
+ const tryOnMounted: typeof import('@vueuse/core')['tryOnMounted']
+ const tryOnScopeDispose: typeof import('@vueuse/core')['tryOnScopeDispose']
+ const tryOnUnmounted: typeof import('@vueuse/core')['tryOnUnmounted']
+ const unref: typeof import('vue')['unref']
+ const unrefElement: typeof import('@vueuse/core')['unrefElement']
+ const until: typeof import('@vueuse/core')['until']
+ const useActiveElement: typeof import('@vueuse/core')['useActiveElement']
+ const useApiDetailsRequest: typeof import('./src/composables/useApi')['useApiDetailsRequest']
+ const useArrayEvery: typeof import('@vueuse/core')['useArrayEvery']
+ const useArrayFilter: typeof import('@vueuse/core')['useArrayFilter']
+ const useArrayFind: typeof import('@vueuse/core')['useArrayFind']
+ const useArrayFindIndex: typeof import('@vueuse/core')['useArrayFindIndex']
+ const useArrayFindLast: typeof import('@vueuse/core')['useArrayFindLast']
+ const useArrayJoin: typeof import('@vueuse/core')['useArrayJoin']
+ const useArrayMap: typeof import('@vueuse/core')['useArrayMap']
+ const useArrayReduce: typeof import('@vueuse/core')['useArrayReduce']
+ const useArraySome: typeof import('@vueuse/core')['useArraySome']
+ const useArrayUnique: typeof import('@vueuse/core')['useArrayUnique']
+ const useAsset: typeof import('./src/composables/useUtil')['useAsset']
+ const useAsyncQueue: typeof import('@vueuse/core')['useAsyncQueue']
+ const useAsyncState: typeof import('@vueuse/core')['useAsyncState']
+ const useAttrs: typeof import('vue')['useAttrs']
+ const useAuthStore: typeof import('./src/store/modules/auth')['useAuthStore']
+ const useAuthStoreOut: typeof import('./src/store/modules/auth')['useAuthStoreOut']
+ const useBase64: typeof import('@vueuse/core')['useBase64']
+ const useBattery: typeof import('@vueuse/core')['useBattery']
+ const useBluetooth: typeof import('@vueuse/core')['useBluetooth']
+ const useBreakpoints: typeof import('@vueuse/core')['useBreakpoints']
+ const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel']
+ const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation']
+ const useCached: typeof import('@vueuse/core')['useCached']
+ const useChart: typeof import('./src/composables/useChart')['useChart']
+ const useChatRequest: typeof import('./src/composables/useApi')['useChatRequest']
+ const useCheckAuth: typeof import('./src/composables/useUtil')['useCheckAuth']
+ const useCheckPhoneRequest: typeof import('./src/composables/useApi')['useCheckPhoneRequest']
+ const useCheckTokenRequest: typeof import('./src/composables/useApi')['useCheckTokenRequest']
+ const useClearLocalCache: typeof import('./src/composables/useUtil')['useClearLocalCache']
+ const useClipboard: typeof import('@vueuse/core')['useClipboard']
+ const useCloned: typeof import('@vueuse/core')['useCloned']
+ const useColorMode: typeof import('@vueuse/core')['useColorMode']
+ const useConfigStore: typeof import('./src/store/modules/config')['useConfigStore']
+ const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog']
+ const useCounter: typeof import('@vueuse/core')['useCounter']
+ const useCreateCopyDom: typeof import('./src/composables/useUtil')['useCreateCopyDom']
+ const useCrypto: typeof import('./src/composables/useCrypto')['default']
+ const useCssModule: typeof import('vue')['useCssModule']
+ const useCssVar: typeof import('@vueuse/core')['useCssVar']
+ const useCssVars: typeof import('vue')['useCssVars']
+ const useCurrentElement: typeof import('@vueuse/core')['useCurrentElement']
+ const useCycleList: typeof import('@vueuse/core')['useCycleList']
+ const useDark: typeof import('@vueuse/core')['useDark']
+ const useDateFormat: typeof import('@vueuse/core')['useDateFormat']
+ const useDebounce: typeof import('@vueuse/core')['useDebounce']
+ const useDebounceFn: typeof import('@vueuse/core')['useDebounceFn']
+ const useDebouncedRefHistory: typeof import('@vueuse/core')['useDebouncedRefHistory']
+ const useDeleteHistoryRequest: typeof import('./src/composables/useApi')['useDeleteHistoryRequest']
+ const useDetailRequest: typeof import('./src/composables/useApi')['useDetailRequest']
+ const useDeviceMotion: typeof import('@vueuse/core')['useDeviceMotion']
+ const useDeviceOrientation: typeof import('@vueuse/core')['useDeviceOrientation']
+ const useDevicePixelRatio: typeof import('@vueuse/core')['useDevicePixelRatio']
+ const useDevicesList: typeof import('@vueuse/core')['useDevicesList']
+ const useDisplayMedia: typeof import('@vueuse/core')['useDisplayMedia']
+ const useDocumentVisibility: typeof import('@vueuse/core')['useDocumentVisibility']
+ const useDraggable: typeof import('@vueuse/core')['useDraggable']
+ const useDropZone: typeof import('@vueuse/core')['useDropZone']
+ const useElementBounding: typeof import('@vueuse/core')['useElementBounding']
+ const useElementByPoint: typeof import('@vueuse/core')['useElementByPoint']
+ const useElementHover: typeof import('@vueuse/core')['useElementHover']
+ const useElementSize: typeof import('@vueuse/core')['useElementSize']
+ const useElementVisibility: typeof import('@vueuse/core')['useElementVisibility']
+ const useEmailCodeRequest: typeof import('./src/composables/useApi')['useEmailCodeRequest']
+ const useEventBus: typeof import('@vueuse/core')['useEventBus']
+ const useEventListener: typeof import('@vueuse/core')['useEventListener']
+ const useEventSource: typeof import('@vueuse/core')['useEventSource']
+ const useEyeDropper: typeof import('@vueuse/core')['useEyeDropper']
+ const useFavicon: typeof import('@vueuse/core')['useFavicon']
+ const useFeedbackRequest: typeof import('./src/composables/useApi')['useFeedbackRequest']
+ const useFetch: typeof import('@vueuse/core')['useFetch']
+ const useFileDialog: typeof import('@vueuse/core')['useFileDialog']
+ const useFileSystemAccess: typeof import('@vueuse/core')['useFileSystemAccess']
+ const useFocus: typeof import('@vueuse/core')['useFocus']
+ const useFocusWithin: typeof import('@vueuse/core')['useFocusWithin']
+ const useFps: typeof import('@vueuse/core')['useFps']
+ const useFullscreen: typeof import('@vueuse/core')['useFullscreen']
+ const useGamepad: typeof import('@vueuse/core')['useGamepad']
+ const useGeolocation: typeof import('@vueuse/core')['useGeolocation']
+ const useGetLocalCache: typeof import('./src/composables/useUtil')['useGetLocalCache']
+ const useHistoryByIdRequest: typeof import('./src/composables/useApi')['useHistoryByIdRequest']
+ const useHistoryListRequest: typeof import('./src/composables/useApi')['useHistoryListRequest']
+ const useHistoryTalkStore: typeof import('./src/store/modules/talk')['useHistoryTalkStore']
+ const useIdle: typeof import('@vueuse/core')['useIdle']
+ const useImage: typeof import('@vueuse/core')['useImage']
+ const useInfiniteScroll: typeof import('@vueuse/core')['useInfiniteScroll']
+ const useInitWaterMark: typeof import('./src/composables/useUtil')['useInitWaterMark']
+ const useIntersectionObserver: typeof import('@vueuse/core')['useIntersectionObserver']
+ const useInterval: typeof import('@vueuse/core')['useInterval']
+ const useIntervalFn: typeof import('@vueuse/core')['useIntervalFn']
+ const useIsExistSensitive: typeof import('./src/composables/useSensitive')['useIsExistSensitive']
+ const useIsMac: typeof import('./src/composables/useUtil')['useIsMac']
+ const useKeyModifier: typeof import('@vueuse/core')['useKeyModifier']
+ const useLastChanged: typeof import('@vueuse/core')['useLastChanged']
+ const useLink: typeof import('vue-router')['useLink']
+ const useLocalStorage: typeof import('@vueuse/core')['useLocalStorage']
+ const useLoginRequest: typeof import('./src/composables/useApi')['useLoginRequest']
+ const useLogoutRequest: typeof import('./src/composables/useApi')['useLogoutRequest']
+ const useMagicKeys: typeof import('@vueuse/core')['useMagicKeys']
+ const useManualRefHistory: typeof import('@vueuse/core')['useManualRefHistory']
+ const useMediaControls: typeof import('@vueuse/core')['useMediaControls']
+ const useMediaQuery: typeof import('@vueuse/core')['useMediaQuery']
+ const useMemoize: typeof import('@vueuse/core')['useMemoize']
+ const useMemory: typeof import('@vueuse/core')['useMemory']
+ const useMobileCodeRequest: typeof import('./src/composables/useApi')['useMobileCodeRequest']
+ const useMounted: typeof import('@vueuse/core')['useMounted']
+ const useMouse: typeof import('@vueuse/core')['useMouse']
+ const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement']
+ const useMousePressed: typeof import('@vueuse/core')['useMousePressed']
+ const useMutationObserver: typeof import('@vueuse/core')['useMutationObserver']
+ const useNavigateTo: typeof import('./src/composables/useUtil')['useNavigateTo']
+ const useNavigatorLanguage: typeof import('@vueuse/core')['useNavigatorLanguage']
+ const useNetwork: typeof import('@vueuse/core')['useNetwork']
+ const useNow: typeof import('@vueuse/core')['useNow']
+ const useObjectUrl: typeof import('@vueuse/core')['useObjectUrl']
+ const useOffsetPagination: typeof import('@vueuse/core')['useOffsetPagination']
+ const useOnline: typeof import('@vueuse/core')['useOnline']
+ const usePageLeave: typeof import('@vueuse/core')['usePageLeave']
+ const useParallax: typeof import('@vueuse/core')['useParallax']
+ const usePermission: typeof import('@vueuse/core')['usePermission']
+ const usePointer: typeof import('@vueuse/core')['usePointer']
+ const usePointerLock: typeof import('@vueuse/core')['usePointerLock']
+ const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe']
+ const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme']
+ const usePreferredContrast: typeof import('@vueuse/core')['usePreferredContrast']
+ const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark']
+ const usePreferredLanguages: typeof import('@vueuse/core')['usePreferredLanguages']
+ const usePreferredReducedMotion: typeof import('@vueuse/core')['usePreferredReducedMotion']
+ const usePrevious: typeof import('@vueuse/core')['usePrevious']
+ const useQueryChatRequest: typeof import('./src/composables/useApi')['useQueryChatRequest']
+ const useRafFn: typeof import('@vueuse/core')['useRafFn']
+ const useRefHistory: typeof import('@vueuse/core')['useRefHistory']
+ const useRegisterRequest: typeof import('./src/composables/useApi')['useRegisterRequest']
+ const useResizeObserver: typeof import('@vueuse/core')['useResizeObserver']
+ const useRoundStore: typeof import('./src/store/modules/round')['useRoundStore']
+ const useRoute: typeof import('vue-router')['useRoute']
+ const useRouter: typeof import('vue-router')['useRouter']
+ const useSSE: typeof import('./src/composables/useSSE')['default']
+ const useScreenOrientation: typeof import('@vueuse/core')['useScreenOrientation']
+ const useScreenSafeArea: typeof import('@vueuse/core')['useScreenSafeArea']
+ const useScriptTag: typeof import('@vueuse/core')['useScriptTag']
+ const useScroll: typeof import('@vueuse/core')['useScroll']
+ const useScrollLock: typeof import('@vueuse/core')['useScrollLock']
+ const useSessionStorage: typeof import('@vueuse/core')['useSessionStorage']
+ const useSetLocalCache: typeof import('./src/composables/useUtil')['useSetLocalCache']
+ const useShare: typeof import('@vueuse/core')['useShare']
+ const useSharedConvsRequest: typeof import('./src/composables/useApi')['useSharedConvsRequest']
+ const useSignUpRequest: typeof import('./src/composables/useApi')['useSignUpRequest']
+ const useSlots: typeof import('vue')['useSlots']
+ const useSorted: typeof import('@vueuse/core')['useSorted']
+ const useSpeechRecognition: typeof import('@vueuse/core')['useSpeechRecognition']
+ const useSpeechSynthesis: typeof import('@vueuse/core')['useSpeechSynthesis']
+ const useStepper: typeof import('@vueuse/core')['useStepper']
+ const useStorage: typeof import('@vueuse/core')['useStorage']
+ const useStorageAsync: typeof import('@vueuse/core')['useStorageAsync']
+ const useStyleTag: typeof import('@vueuse/core')['useStyleTag']
+ const useSupported: typeof import('@vueuse/core')['useSupported']
+ const useSwipe: typeof import('@vueuse/core')['useSwipe']
+ const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList']
+ const useTextDirection: typeof import('@vueuse/core')['useTextDirection']
+ const useTextSelection: typeof import('@vueuse/core')['useTextSelection']
+ const useTextareaAutosize: typeof import('@vueuse/core')['useTextareaAutosize']
+ const useThrottle: typeof import('@vueuse/core')['useThrottle']
+ const useThrottleFn: typeof import('@vueuse/core')['useThrottleFn']
+ const useThrottledRefHistory: typeof import('@vueuse/core')['useThrottledRefHistory']
+ const useTimeAgo: typeof import('@vueuse/core')['useTimeAgo']
+ const useTimeout: typeof import('@vueuse/core')['useTimeout']
+ const useTimeoutFn: typeof import('@vueuse/core')['useTimeoutFn']
+ const useTimeoutPoll: typeof import('@vueuse/core')['useTimeoutPoll']
+ const useTimestamp: typeof import('@vueuse/core')['useTimestamp']
+ const useTitle: typeof import('@vueuse/core')['useTitle']
+ const useToNumber: typeof import('@vueuse/core')['useToNumber']
+ const useToString: typeof import('@vueuse/core')['useToString']
+ const useToggle: typeof import('@vueuse/core')['useToggle']
+ const useTransition: typeof import('@vueuse/core')['useTransition']
+ const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams']
+ const useUserMedia: typeof import('@vueuse/core')['useUserMedia']
+ const useUserStore: typeof import('./src/store/modules/user')['useUserStore']
+ const useVModel: typeof import('@vueuse/core')['useVModel']
+ const useVModels: typeof import('@vueuse/core')['useVModels']
+ const useValidEmail: typeof import('./src/composables/useValid')['useValidEmail']
+ const useValidPhone: typeof import('./src/composables/useValid')['useValidPhone']
+ const useVibrate: typeof import('@vueuse/core')['useVibrate']
+ const useVirtualList: typeof import('@vueuse/core')['useVirtualList']
+ const useWakeLock: typeof import('@vueuse/core')['useWakeLock']
+ const useWebNotification: typeof import('@vueuse/core')['useWebNotification']
+ const useWebSocket: typeof import('@vueuse/core')['useWebSocket']
+ const useWebWorker: typeof import('@vueuse/core')['useWebWorker']
+ const useWebWorkerFn: typeof import('@vueuse/core')['useWebWorkerFn']
+ const useWindowFocus: typeof import('@vueuse/core')['useWindowFocus']
+ const useWindowOpen: typeof import('./src/composables/useUtil')['useWindowOpen']
+ const useWindowScroll: typeof import('@vueuse/core')['useWindowScroll']
+ const useWindowSize: typeof import('@vueuse/core')['useWindowSize']
+ const watch: typeof import('vue')['watch']
+ const watchArray: typeof import('@vueuse/core')['watchArray']
+ const watchAtMost: typeof import('@vueuse/core')['watchAtMost']
+ const watchDebounced: typeof import('@vueuse/core')['watchDebounced']
+ const watchEffect: typeof import('vue')['watchEffect']
+ const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable']
+ const watchOnce: typeof import('@vueuse/core')['watchOnce']
+ const watchPausable: typeof import('@vueuse/core')['watchPausable']
+ const watchPostEffect: typeof import('vue')['watchPostEffect']
+ const watchSyncEffect: typeof import('vue')['watchSyncEffect']
+ const watchThrottled: typeof import('@vueuse/core')['watchThrottled']
+ const watchTriggerable: typeof import('@vueuse/core')['watchTriggerable']
+ const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter']
+ const whenever: typeof import('@vueuse/core')['whenever']
+}
+// for vue template auto import
+import { UnwrapRef } from 'vue'
+declare module 'vue' {
+ interface ComponentCustomProperties {
+ readonly AUTH_STATE: UnwrapRef
+ readonly AesEncryption: UnwrapRef
+ readonly CACHE_LOCATION: UnwrapRef
+ readonly EffectScope: UnwrapRef
+ readonly HISTORY_TALK: UnwrapRef
+ readonly RoleEnum: UnwrapRef
+ readonly STORAGE_TOKEN: UnwrapRef
+ readonly TOKEN: UnwrapRef
+ readonly USER_INFO: UnwrapRef
+ readonly acceptHMRUpdate: UnwrapRef
+ readonly asyncComputed: UnwrapRef
+ readonly autoResetRef: UnwrapRef
+ readonly computed: UnwrapRef
+ readonly computedAsync: UnwrapRef
+ readonly computedEager: UnwrapRef
+ readonly computedInject: UnwrapRef
+ readonly computedWithControl: UnwrapRef
+ readonly controlledComputed: UnwrapRef
+ readonly controlledRef: UnwrapRef
+ readonly createApp: UnwrapRef
+ readonly createEventHook: UnwrapRef
+ readonly createGlobalState: UnwrapRef
+ readonly createInjectionState: UnwrapRef
+ readonly createPinia: UnwrapRef
+ readonly createReactiveFn: UnwrapRef
+ readonly createSharedComposable: UnwrapRef
+ readonly createUnrefFn: UnwrapRef
+ readonly customRef: UnwrapRef
+ readonly debouncedRef: UnwrapRef
+ readonly debouncedWatch: UnwrapRef
+ readonly defineAsyncComponent: UnwrapRef
+ readonly defineComponent: UnwrapRef
+ readonly defineStore: UnwrapRef
+ readonly eagerComputed: UnwrapRef
+ readonly effectScope: UnwrapRef
+ readonly extendRef: UnwrapRef
+ readonly getActivePinia: UnwrapRef
+ readonly getCurrentInstance: UnwrapRef
+ readonly getCurrentScope: UnwrapRef
+ readonly globalD: UnwrapRef
+ readonly h: UnwrapRef
+ readonly ignorableWatch: UnwrapRef
+ readonly inject: UnwrapRef
+ readonly isDefined: UnwrapRef
+ readonly isProxy: UnwrapRef
+ readonly isReactive: UnwrapRef
+ readonly isReadonly: UnwrapRef
+ readonly isRef: UnwrapRef
+ readonly makeDestructurable: UnwrapRef
+ readonly mapActions: UnwrapRef
+ readonly mapGetters: UnwrapRef
+ readonly mapState: UnwrapRef
+ readonly mapStores: UnwrapRef
+ readonly mapWritableState: UnwrapRef
+ readonly markRaw: UnwrapRef
+ readonly nextTick: UnwrapRef
+ readonly onActivated: UnwrapRef
+ readonly onBeforeMount: UnwrapRef
+ readonly onBeforeRouteLeave: UnwrapRef
+ readonly onBeforeRouteUpdate: UnwrapRef
+ readonly onBeforeUnmount: UnwrapRef
+ readonly onBeforeUpdate: UnwrapRef
+ readonly onClickOutside: UnwrapRef
+ readonly onDeactivated: UnwrapRef
+ readonly onErrorCaptured: UnwrapRef
+ readonly onKeyStroke: UnwrapRef
+ readonly onLongPress: UnwrapRef
+ readonly onMounted: UnwrapRef
+ readonly onRenderTracked: UnwrapRef
+ readonly onRenderTriggered: UnwrapRef
+ readonly onScopeDispose: UnwrapRef
+ readonly onServerPrefetch: UnwrapRef
+ readonly onStartTyping: UnwrapRef
+ readonly onUnmounted: UnwrapRef
+ readonly onUpdated: UnwrapRef
+ readonly pausableWatch: UnwrapRef
+ readonly provide: UnwrapRef
+ readonly reactify: UnwrapRef
+ readonly reactifyObject: UnwrapRef
+ readonly reactive: UnwrapRef
+ readonly reactiveComputed: UnwrapRef
+ readonly reactiveOmit: UnwrapRef
+ readonly reactivePick: UnwrapRef
+ readonly readonly: UnwrapRef
+ readonly ref: UnwrapRef
+ readonly refAutoReset: UnwrapRef
+ readonly refDebounced: UnwrapRef
+ readonly refDefault: UnwrapRef
+ readonly refThrottled: UnwrapRef
+ readonly refWithControl: UnwrapRef
+ readonly resolveComponent: UnwrapRef
+ readonly resolveDirective: UnwrapRef
+ readonly resolveRef: UnwrapRef
+ readonly resolveUnref: UnwrapRef
+ readonly setActivePinia: UnwrapRef
+ readonly setMapStoreSuffix: UnwrapRef
+ readonly setupStore: UnwrapRef
+ readonly shallowReactive: UnwrapRef
+ readonly shallowReadonly: UnwrapRef
+ readonly shallowRef: UnwrapRef
+ readonly store: UnwrapRef
+ readonly storeToRefs: UnwrapRef
+ readonly syncRef: UnwrapRef
+ readonly syncRefs: UnwrapRef
+ readonly templateRef: UnwrapRef
+ readonly throttledRef: UnwrapRef
+ readonly throttledWatch: UnwrapRef
+ readonly toRaw: UnwrapRef
+ readonly toReactive: UnwrapRef
+ readonly toRef: UnwrapRef
+ readonly toRefs: UnwrapRef
+ readonly triggerRef: UnwrapRef
+ readonly tryOnBeforeMount: UnwrapRef
+ readonly tryOnBeforeUnmount: UnwrapRef
+ readonly tryOnMounted: UnwrapRef
+ readonly tryOnScopeDispose: UnwrapRef
+ readonly tryOnUnmounted: UnwrapRef
+ readonly unref: UnwrapRef
+ readonly unrefElement: UnwrapRef
+ readonly until: UnwrapRef
+ readonly useActiveElement: UnwrapRef
+ readonly useApiDetailsRequest: UnwrapRef
+ readonly useArrayEvery: UnwrapRef
+ readonly useArrayFilter: UnwrapRef
+ readonly useArrayFind: UnwrapRef
+ readonly useArrayFindIndex: UnwrapRef
+ readonly useArrayFindLast: UnwrapRef
+ readonly useArrayJoin: UnwrapRef
+ readonly useArrayMap: UnwrapRef
+ readonly useArrayReduce: UnwrapRef
+ readonly useArraySome: UnwrapRef
+ readonly useArrayUnique: UnwrapRef
+ readonly useAsset: UnwrapRef
+ readonly useAsyncQueue: UnwrapRef
+ readonly useAsyncState: UnwrapRef
+ readonly useAttrs: UnwrapRef
+ readonly useAuthStore: UnwrapRef
+ readonly useAuthStoreOut: UnwrapRef
+ readonly useBase64: UnwrapRef
+ readonly useBattery: UnwrapRef
+ readonly useBluetooth: UnwrapRef
+ readonly useBreakpoints: UnwrapRef
+ readonly useBroadcastChannel: UnwrapRef
+ readonly useBrowserLocation: UnwrapRef
+ readonly useCached: UnwrapRef
+ readonly useChart: UnwrapRef
+ readonly useChatRequest: UnwrapRef
+ readonly useCheckAuth: UnwrapRef
+ readonly useCheckPhoneRequest: UnwrapRef
+ readonly useCheckTokenRequest: UnwrapRef
+ readonly useClearLocalCache: UnwrapRef
+ readonly useClipboard: UnwrapRef
+ readonly useCloned: UnwrapRef
+ readonly useColorMode: UnwrapRef
+ readonly useConfigStore: UnwrapRef
+ readonly useConfirmDialog: UnwrapRef
+ readonly useCounter: UnwrapRef
+ readonly useCreateCopyDom: UnwrapRef
+ readonly useCrypto: UnwrapRef
+ readonly useCssModule: UnwrapRef
+ readonly useCssVar: UnwrapRef
+ readonly useCssVars: UnwrapRef
+ readonly useCurrentElement: UnwrapRef
+ readonly useCycleList: UnwrapRef
+ readonly useDark: UnwrapRef
+ readonly useDateFormat: UnwrapRef
+ readonly useDebounce: UnwrapRef
+ readonly useDebounceFn: UnwrapRef
+ readonly useDebouncedRefHistory: UnwrapRef
+ readonly useDeleteHistoryRequest: UnwrapRef
+ readonly useDetailRequest: UnwrapRef
+ readonly useDeviceMotion: UnwrapRef
+ readonly useDeviceOrientation: UnwrapRef
+ readonly useDevicePixelRatio: UnwrapRef
+ readonly useDevicesList: UnwrapRef
+ readonly useDisplayMedia: UnwrapRef
+ readonly useDocumentVisibility: UnwrapRef
+ readonly useDraggable: UnwrapRef
+ readonly useDropZone: UnwrapRef
+ readonly useElementBounding: UnwrapRef
+ readonly useElementByPoint: UnwrapRef
+ readonly useElementHover: UnwrapRef
+ readonly useElementSize: UnwrapRef
+ readonly useElementVisibility: UnwrapRef
+ readonly useEmailCodeRequest: UnwrapRef
+ readonly useEventBus: UnwrapRef
+ readonly useEventListener: UnwrapRef
+ readonly useEventSource: UnwrapRef
+ readonly useEyeDropper: UnwrapRef
+ readonly useFavicon: UnwrapRef
+ readonly useFeedbackRequest: UnwrapRef
+ readonly useFetch: UnwrapRef
+ readonly useFileDialog: UnwrapRef
+ readonly useFileSystemAccess: UnwrapRef
+ readonly useFocus: UnwrapRef
+ readonly useFocusWithin: UnwrapRef
+ readonly useFps: UnwrapRef
+ readonly useFullscreen: UnwrapRef
+ readonly useGamepad: UnwrapRef
+ readonly useGeolocation: UnwrapRef
+ readonly useGetLocalCache: UnwrapRef
+ readonly useHistoryByIdRequest: UnwrapRef
+ readonly useHistoryListRequest: UnwrapRef
+ readonly useHistoryTalkStore: UnwrapRef
+ readonly useIdle: UnwrapRef
+ readonly useImage: UnwrapRef
+ readonly useInfiniteScroll: UnwrapRef
+ readonly useInitWaterMark: UnwrapRef
+ readonly useIntersectionObserver: UnwrapRef
+ readonly useInterval: UnwrapRef
+ readonly useIntervalFn: UnwrapRef
+ readonly useIsExistSensitive: UnwrapRef
+ readonly useIsMac: UnwrapRef
+ readonly useKeyModifier: UnwrapRef
+ readonly useLastChanged: UnwrapRef
+ readonly useLink: UnwrapRef
+ readonly useLocalStorage: UnwrapRef
+ readonly useLoginRequest: UnwrapRef
+ readonly useLogoutRequest: UnwrapRef
+ readonly useMagicKeys: UnwrapRef
+ readonly useManualRefHistory: UnwrapRef
+ readonly useMediaControls: UnwrapRef
+ readonly useMediaQuery: UnwrapRef
+ readonly useMemoize: UnwrapRef
+ readonly useMemory: UnwrapRef
+ readonly useMobileCodeRequest: UnwrapRef
+ readonly useMounted: UnwrapRef
+ readonly useMouse: UnwrapRef
+ readonly useMouseInElement: UnwrapRef
+ readonly useMousePressed: UnwrapRef
+ readonly useMutationObserver: UnwrapRef
+ readonly useNavigateTo: UnwrapRef
+ readonly useNavigatorLanguage: UnwrapRef
+ readonly useNetwork: UnwrapRef
+ readonly useNow: UnwrapRef
+ readonly useObjectUrl: UnwrapRef
+ readonly useOffsetPagination: UnwrapRef
+ readonly useOnline: UnwrapRef
+ readonly usePageLeave: UnwrapRef
+ readonly useParallax: UnwrapRef
+ readonly usePermission: UnwrapRef
+ readonly usePointer: UnwrapRef
+ readonly usePointerLock: UnwrapRef
+ readonly usePointerSwipe: UnwrapRef
+ readonly usePreferredColorScheme: UnwrapRef
+ readonly usePreferredContrast: UnwrapRef
+ readonly usePreferredDark: UnwrapRef
+ readonly usePreferredLanguages: UnwrapRef
+ readonly usePreferredReducedMotion: UnwrapRef
+ readonly usePrevious: UnwrapRef
+ readonly useQueryChatRequest: UnwrapRef
+ readonly useRafFn: UnwrapRef
+ readonly useRefHistory: UnwrapRef
+ readonly useRegisterRequest: UnwrapRef