mirror of
https://github.com/LiteyukiStudio/nonebot-plugin-marshoai.git
synced 2025-01-26 18:12:47 +08:00
✨ 添加插件加载模块及相关模型,支持插件的动态加载与管理;新增天气、环境和时间获取功能;重构工具函数;删除不再使用的文件
This commit is contained in:
parent
a9938d30ed
commit
3f969ecf33
@ -3,6 +3,8 @@ from typing import Any
|
|||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
from .typing import ASYNC_FUNCTION_CALL_FUNC
|
||||||
|
|
||||||
|
|
||||||
class PluginMetadata(BaseModel):
|
class PluginMetadata(BaseModel):
|
||||||
"""
|
"""
|
||||||
@ -67,3 +69,75 @@ class Plugin(BaseModel):
|
|||||||
|
|
||||||
def __eq__(self, other: Any) -> bool:
|
def __eq__(self, other: Any) -> bool:
|
||||||
return self.name == other.name
|
return self.name == other.name
|
||||||
|
|
||||||
|
|
||||||
|
class FunctionCallArgument(BaseModel):
|
||||||
|
"""
|
||||||
|
插件函数参数对象
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
----------
|
||||||
|
name: str
|
||||||
|
参数名称
|
||||||
|
type: str
|
||||||
|
参数类型 string integer等
|
||||||
|
description: str
|
||||||
|
参数描述
|
||||||
|
"""
|
||||||
|
|
||||||
|
type_: str
|
||||||
|
"""参数类型描述 string integer等"""
|
||||||
|
description: str
|
||||||
|
"""参数描述"""
|
||||||
|
default: Any = None
|
||||||
|
"""默认值"""
|
||||||
|
|
||||||
|
def data(self) -> dict[str, Any]:
|
||||||
|
return {"type": self.type_, "description": self.description}
|
||||||
|
|
||||||
|
|
||||||
|
class FunctionCall(BaseModel):
|
||||||
|
"""
|
||||||
|
插件函数对象
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
----------
|
||||||
|
name: str
|
||||||
|
函数名称
|
||||||
|
func: "FUNCTION_CALL"
|
||||||
|
函数对象
|
||||||
|
"""
|
||||||
|
|
||||||
|
name: str
|
||||||
|
"""函数名称 module.func"""
|
||||||
|
description: str
|
||||||
|
"""函数描述 这个函数用于获取天气信息"""
|
||||||
|
arguments: dict[str, FunctionCallArgument]
|
||||||
|
"""函数参数信息"""
|
||||||
|
function: ASYNC_FUNCTION_CALL_FUNC
|
||||||
|
"""函数对象"""
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
arbitrary_types_allowed = True
|
||||||
|
|
||||||
|
def __hash__(self) -> int:
|
||||||
|
return hash(self.name)
|
||||||
|
|
||||||
|
def data(self) -> dict[str, Any]:
|
||||||
|
"""生成函数描述信息
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict[str, Any]: 函数描述信息 字典
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
"type": "function",
|
||||||
|
"function": {
|
||||||
|
"name": self.name,
|
||||||
|
"description": self.description,
|
||||||
|
"parameters": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {k: v.data() for k, v in self.arguments.items()},
|
||||||
|
},
|
||||||
|
"required": [k for k, v in self.arguments.items() if v.default is None],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -4,18 +4,20 @@
|
|||||||
import inspect
|
import inspect
|
||||||
from typing import Any, Callable, Coroutine, TypeAlias
|
from typing import Any, Callable, Coroutine, TypeAlias
|
||||||
|
|
||||||
import nonebot
|
from nonebot import logger
|
||||||
|
|
||||||
|
from .models import FunctionCall, FunctionCallArgument
|
||||||
|
from .typing import (
|
||||||
|
ASYNC_FUNCTION_CALL_FUNC,
|
||||||
|
FUNCTION_CALL_FUNC,
|
||||||
|
SYNC_FUNCTION_CALL_FUNC,
|
||||||
|
)
|
||||||
from .utils import is_coroutine_callable
|
from .utils import is_coroutine_callable
|
||||||
|
|
||||||
SYNC_FUNCTION_CALL: TypeAlias = Callable[..., str]
|
_loaded_functions: dict[str, FUNCTION_CALL_FUNC] = {}
|
||||||
ASYNC_FUNCTION_CALL: TypeAlias = Callable[..., Coroutine[str, Any, str]]
|
|
||||||
FUNCTION_CALL: TypeAlias = SYNC_FUNCTION_CALL | ASYNC_FUNCTION_CALL
|
|
||||||
|
|
||||||
_loaded_functions: dict[str, FUNCTION_CALL] = {}
|
|
||||||
|
|
||||||
|
|
||||||
def async_wrapper(func: SYNC_FUNCTION_CALL) -> ASYNC_FUNCTION_CALL:
|
def async_wrapper(func: SYNC_FUNCTION_CALL_FUNC) -> ASYNC_FUNCTION_CALL_FUNC:
|
||||||
"""将同步函数包装为异步函数,但是不会真正异步执行,仅用于统一调用及函数签名
|
"""将同步函数包装为异步函数,但是不会真正异步执行,仅用于统一调用及函数签名
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -31,7 +33,7 @@ def async_wrapper(func: SYNC_FUNCTION_CALL) -> ASYNC_FUNCTION_CALL:
|
|||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
def function_call(*funcs: FUNCTION_CALL):
|
def function_call(*funcs: FUNCTION_CALL_FUNC) -> None:
|
||||||
"""返回一个装饰器,装饰一个函数, 使其注册为一个可被AI调用的function call函数
|
"""返回一个装饰器,装饰一个函数, 使其注册为一个可被AI调用的function call函数
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -41,15 +43,20 @@ def function_call(*funcs: FUNCTION_CALL):
|
|||||||
str: 函数定义信息
|
str: 函数定义信息
|
||||||
"""
|
"""
|
||||||
for func in funcs:
|
for func in funcs:
|
||||||
if module := inspect.getmodule(func):
|
function_call = get_function_info(func)
|
||||||
module_name = module.__name__ + "."
|
# TODO: 注册函数
|
||||||
else:
|
|
||||||
module_name = ""
|
|
||||||
name = func.__name__
|
|
||||||
if not is_coroutine_callable(func):
|
|
||||||
func = async_wrapper(func) # type: ignore
|
|
||||||
|
|
||||||
_loaded_functions[name] = func
|
|
||||||
nonebot.logger.opt(colors=True).info(
|
def get_function_info(func: FUNCTION_CALL_FUNC):
|
||||||
f"加载 function call: <c>{module_name}{name}</c>"
|
"""获取函数信息
|
||||||
)
|
|
||||||
|
Args:
|
||||||
|
func: 函数对象
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
FunctionCall: 函数信息对象模型
|
||||||
|
"""
|
||||||
|
name = func.__name__
|
||||||
|
description = func.__doc__
|
||||||
|
logger.info(f"注册函数: {name} {description}")
|
||||||
|
# TODO: 获取函数参数信息
|
||||||
|
5
nonebot_plugin_marshoai/plugin/typing.py
Normal file
5
nonebot_plugin_marshoai/plugin/typing.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
from typing import Any, Callable, Coroutine, TypeAlias
|
||||||
|
|
||||||
|
SYNC_FUNCTION_CALL_FUNC: TypeAlias = Callable[..., str]
|
||||||
|
ASYNC_FUNCTION_CALL_FUNC: TypeAlias = Callable[..., Coroutine[str, Any, str]]
|
||||||
|
FUNCTION_CALL_FUNC: TypeAlias = SYNC_FUNCTION_CALL_FUNC | ASYNC_FUNCTION_CALL_FUNC
|
Loading…
x
Reference in New Issue
Block a user