nonebot-plugin-githubmodels 0.2.3__tar.gz → 0.2.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {nonebot_plugin_githubmodels-0.2.3 → nonebot_plugin_githubmodels-0.2.4}/LICENSE +1 -1
- {nonebot_plugin_githubmodels-0.2.3 → nonebot_plugin_githubmodels-0.2.4}/PKG-INFO +16 -20
- nonebot_plugin_githubmodels-0.2.4/README.md +41 -0
- nonebot_plugin_githubmodels-0.2.4/nonebot_plugin_githubmodels/GPT_handler.py +29 -0
- {nonebot_plugin_githubmodels-0.2.3 → nonebot_plugin_githubmodels-0.2.4}/nonebot_plugin_githubmodels/__init__.py +47 -41
- {nonebot_plugin_githubmodels-0.2.3 → nonebot_plugin_githubmodels-0.2.4}/nonebot_plugin_githubmodels/config.py +4 -1
- nonebot_plugin_githubmodels-0.2.4/nonebot_plugin_githubmodels/context_manager.py +16 -0
- {nonebot_plugin_githubmodels-0.2.3 → nonebot_plugin_githubmodels-0.2.4}/pyproject.toml +1 -1
- nonebot_plugin_githubmodels-0.2.3/README.md +0 -45
|
@@ -16,4 +16,4 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
|
16
16
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
17
17
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
18
18
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
19
|
-
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
19
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: nonebot-plugin-githubmodels
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: API 调用 GitHub Models 的大语言模型
|
|
5
5
|
Home-page: https://github.com/lyqgzbl/nonebot-plugin-githubmodels
|
|
6
6
|
License: MIT
|
|
@@ -38,33 +38,29 @@ Description-Content-Type: text/markdown
|
|
|
38
38
|
|
|
39
39
|
_✨ API调用GitHub models大语言模型 ✨_
|
|
40
40
|
|
|
41
|
-
</
|
|
41
|
+
<a href ="https://raw.githubusercontent.com/lyqgzbl/nonebot-plugin-githubmodels/refs/heads/main/LICENSE"><img src="https://img.shields.io/pypi/l/nonebot-plugin-githubmodels"> </a>
|
|
42
|
+
<a href="https://pypi.python.org/pypi/nonebot-plugin-githubmodels"> <img src="https://img.shields.io/pypi/v/nonebot-plugin-githubmodels.svg" alt="pypi"></a>
|
|
43
|
+
<img src="https://img.shields.io/badge/python-3.8+-blue.svg" alt="python">
|
|
42
44
|
|
|
43
|
-
|
|
44
|
-
<a href="https://raw.githubusercontent.com/kexue-z/nonebot-plugin-heweather/master/LICENSE">
|
|
45
|
-
<img src="https://img.shields.io/github/license/kexue-z/nonebot-plugin-heweather.svg" alt="license">
|
|
46
|
-
</a>
|
|
47
|
-
<a href="https://pypi.org/project/nonebot-plugin-heweather/">
|
|
48
|
-
<img src="https://img.shields.io/pypi/v/nonebot-plugin-heweather" alt="pypi">
|
|
49
|
-
</a>
|
|
50
|
-
<img src="https://img.shields.io/badge/python-3.8+-blue.svg" alt="python">
|
|
51
|
-
</p>
|
|
45
|
+
</div>
|
|
52
46
|
|
|
53
47
|
# 安装
|
|
54
|
-
|
|
55
|
-
使用nb-cli
|
|
48
|
+
使用nb-cli [推荐]
|
|
56
49
|
```shell
|
|
57
50
|
nb plugin install nonebot-plugin-githubmodels
|
|
58
51
|
```
|
|
52
|
+
使用pip
|
|
53
|
+
```shell
|
|
54
|
+
pip install nonebot-plugin-githubmodels
|
|
55
|
+
```
|
|
59
56
|
|
|
60
|
-
#
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
”AI 重置“ 重置上下文记忆
|
|
57
|
+
# 使用
|
|
58
|
+
命令需要加 [NoneBot 命令前缀](https://nonebot.dev/docs/appendices/config#command-start-和-command-separator) (默认为`/`)
|
|
59
|
+
使用命令`AI`/`ai`触发插件
|
|
60
|
+
命令选项`-r` 重置上下文记忆
|
|
61
|
+
命令选项`-i` 临时启用图片回复
|
|
66
62
|
|
|
67
63
|
# 配置
|
|
68
64
|
|
|
69
|
-
|
|
65
|
+
配置参见 [.env.example](https://github.com/lyqgzbl/nonebot-plugin-githubmodels/blob/main/.env.example)
|
|
70
66
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<!-- markdownlint-disable MD033 MD036 MD041 -->
|
|
2
|
+
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+
<a href="https://v2.nonebot.dev/store">
|
|
6
|
+
<img src="https://raw.githubusercontent.com/A-kirami/nonebot-plugin-template/resources/nbp_logo.png" width="180" height="180" alt="NoneBotPluginLogo">
|
|
7
|
+
</a>
|
|
8
|
+
|
|
9
|
+
<p>
|
|
10
|
+
<img src="https://raw.githubusercontent.com/lgc-NB2Dev/readme/main/template/plugin.svg" alt="NoneBotPluginText">
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
# nonebot-plugin-githubmodels
|
|
14
|
+
|
|
15
|
+
_✨ API调用GitHub models大语言模型 ✨_
|
|
16
|
+
|
|
17
|
+
<a href ="https://raw.githubusercontent.com/lyqgzbl/nonebot-plugin-githubmodels/refs/heads/main/LICENSE"><img src="https://img.shields.io/pypi/l/nonebot-plugin-githubmodels"> </a>
|
|
18
|
+
<a href="https://pypi.python.org/pypi/nonebot-plugin-githubmodels"> <img src="https://img.shields.io/pypi/v/nonebot-plugin-githubmodels.svg" alt="pypi"></a>
|
|
19
|
+
<img src="https://img.shields.io/badge/python-3.8+-blue.svg" alt="python">
|
|
20
|
+
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
# 安装
|
|
24
|
+
使用nb-cli [推荐]
|
|
25
|
+
```shell
|
|
26
|
+
nb plugin install nonebot-plugin-githubmodels
|
|
27
|
+
```
|
|
28
|
+
使用pip
|
|
29
|
+
```shell
|
|
30
|
+
pip install nonebot-plugin-githubmodels
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
# 使用
|
|
34
|
+
命令需要加 [NoneBot 命令前缀](https://nonebot.dev/docs/appendices/config#command-start-和-command-separator) (默认为`/`)
|
|
35
|
+
使用命令`AI`/`ai`触发插件
|
|
36
|
+
命令选项`-r` 重置上下文记忆
|
|
37
|
+
命令选项`-i` 临时启用图片回复
|
|
38
|
+
|
|
39
|
+
# 配置
|
|
40
|
+
|
|
41
|
+
配置参见 [.env.example](https://github.com/lyqgzbl/nonebot-plugin-githubmodels/blob/main/.env.example)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from openai import AsyncOpenAI
|
|
2
|
+
|
|
3
|
+
class GPTHandler:
|
|
4
|
+
def __init__(
|
|
5
|
+
self,
|
|
6
|
+
api_key: str,
|
|
7
|
+
endpoint: str,
|
|
8
|
+
model_name: str,
|
|
9
|
+
max_context_length: int,
|
|
10
|
+
temperature: float,
|
|
11
|
+
max_tokens: int,
|
|
12
|
+
top_p: float,
|
|
13
|
+
):
|
|
14
|
+
self.client = AsyncOpenAI(base_url=endpoint, api_key=api_key)
|
|
15
|
+
self.model_name = model_name
|
|
16
|
+
self.max_context_length = max_context_length
|
|
17
|
+
self.temperature = temperature
|
|
18
|
+
self.max_tokens = max_tokens
|
|
19
|
+
self.top_p = top_p
|
|
20
|
+
|
|
21
|
+
async def get_response(self, messages: list) -> str:
|
|
22
|
+
response = await self.client.chat.completions.create(
|
|
23
|
+
messages=messages,
|
|
24
|
+
model=self.model_name,
|
|
25
|
+
temperature=self.temperature,
|
|
26
|
+
max_tokens=self.max_tokens,
|
|
27
|
+
top_p=self.top_p,
|
|
28
|
+
)
|
|
29
|
+
return response.choices[0].message.content
|
|
@@ -1,26 +1,47 @@
|
|
|
1
1
|
import nonebot
|
|
2
2
|
from nonebot import require, get_plugin_config
|
|
3
|
+
from nonebot.rule import Rule
|
|
4
|
+
from nonebot.log import logger
|
|
5
|
+
from nonebot.plugin import PluginMetadata
|
|
6
|
+
|
|
3
7
|
require("nonebot_plugin_alconna")
|
|
4
8
|
require("nonebot_plugin_htmlrender")
|
|
5
|
-
from openai import AsyncOpenAI
|
|
6
9
|
from arclet.alconna import Args, Option, Alconna, MultiVar
|
|
7
|
-
from nonebot.plugin import PluginMetadata
|
|
8
|
-
from nonebot_plugin_htmlrender import md_to_pic
|
|
9
10
|
from nonebot_plugin_alconna import UniMessage, on_alconna, Match
|
|
11
|
+
from nonebot_plugin_htmlrender import md_to_pic
|
|
12
|
+
|
|
10
13
|
from .config import Config
|
|
14
|
+
from .GPT_handler import GPTHandler
|
|
15
|
+
from .context_manager import ContextManager
|
|
16
|
+
|
|
11
17
|
|
|
12
18
|
plugin_config = get_plugin_config(Config)
|
|
13
|
-
TOKEN = plugin_config.github_token
|
|
14
|
-
MODEL_NAME = plugin_config.ai_model_name
|
|
15
19
|
REPLY_IMAGE = plugin_config.ai_reply_image
|
|
16
|
-
MAX_CONTEXT_LENGTH = plugin_config.max_context_length
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
|
|
22
|
+
if not plugin_config.github_token:
|
|
23
|
+
logger.opt(colors=True).warning("<yellow>缺失必要配置项 'github_token',已禁用该插件</yellow>")
|
|
24
|
+
GPT_handler = None
|
|
25
|
+
else:
|
|
26
|
+
GPT_handler = GPTHandler(
|
|
27
|
+
api_key=plugin_config.github_token,
|
|
28
|
+
endpoint="https://models.inference.ai.azure.com",
|
|
29
|
+
model_name=plugin_config.ai_model_name,
|
|
30
|
+
max_context_length=plugin_config.max_context_length,
|
|
31
|
+
temperature=plugin_config.ai_temperature,
|
|
32
|
+
max_tokens=plugin_config.ai_max_tokens,
|
|
33
|
+
top_p=plugin_config.ai_top_p,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def is_enable() -> Rule:
|
|
38
|
+
def _rule() -> bool:
|
|
39
|
+
return bool(plugin_config.github_token)
|
|
40
|
+
return Rule(_rule)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
context_manager = ContextManager(max_context_length=plugin_config.max_context_length)
|
|
44
|
+
|
|
24
45
|
|
|
25
46
|
ai = on_alconna(
|
|
26
47
|
Alconna(
|
|
@@ -29,17 +50,19 @@ ai = on_alconna(
|
|
|
29
50
|
Option("-r|--reset"),
|
|
30
51
|
Option("-i|--image"),
|
|
31
52
|
),
|
|
53
|
+
rule=is_enable(),
|
|
32
54
|
use_cmd_start=True,
|
|
33
55
|
block=True,
|
|
34
56
|
aliases={"ai"},
|
|
35
57
|
)
|
|
36
58
|
|
|
59
|
+
|
|
37
60
|
@ai.assign("reset")
|
|
38
61
|
async def ai_reset():
|
|
39
|
-
|
|
40
|
-
shared_context = []
|
|
62
|
+
context_manager.reset_context()
|
|
41
63
|
await ai.finish("上下文已重置")
|
|
42
64
|
|
|
65
|
+
|
|
43
66
|
@ai.assign("image")
|
|
44
67
|
async def ai_image(user_input: Match[tuple[str]]):
|
|
45
68
|
if user_input.available:
|
|
@@ -47,40 +70,22 @@ async def ai_image(user_input: Match[tuple[str]]):
|
|
|
47
70
|
REPLY_IMAGE = True
|
|
48
71
|
ai.set_path_arg("user_input", " ".join(user_input.result))
|
|
49
72
|
|
|
73
|
+
|
|
50
74
|
@ai.handle()
|
|
51
75
|
async def handle_function(user_input: Match[tuple[str]]):
|
|
52
76
|
if user_input.available:
|
|
53
77
|
ai.set_path_arg("user_input", " ".join(user_input.result))
|
|
54
78
|
|
|
79
|
+
|
|
55
80
|
@ai.got_path("user_input", prompt="请输入有效问题")
|
|
56
81
|
async def got_location(user_input: str):
|
|
57
|
-
global
|
|
58
|
-
if MAX_CONTEXT_LENGTH > 0:
|
|
59
|
-
shared_context.append({"role": "user", "content": user_input})
|
|
60
|
-
if len(shared_context) > MAX_CONTEXT_LENGTH:
|
|
61
|
-
shared_context = shared_context[-MAX_CONTEXT_LENGTH:]
|
|
62
|
-
|
|
63
|
-
messages = [
|
|
64
|
-
{"role": "system", "content": "回答尽量简练,请始终用中文回答"}
|
|
65
|
-
]
|
|
66
|
-
if MAX_CONTEXT_LENGTH > 0:
|
|
67
|
-
messages += shared_context
|
|
68
|
-
else:
|
|
69
|
-
messages.append({"role": "user", "content": user_input})
|
|
70
|
-
|
|
82
|
+
global REPLY_IMAGE
|
|
71
83
|
try:
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
top_p=1,
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
reply = response.choices[0].message.content
|
|
81
|
-
if MAX_CONTEXT_LENGTH > 0:
|
|
82
|
-
shared_context.append({"role": "assistant", "content": reply})
|
|
83
|
-
|
|
84
|
+
messages = [{"role": "system", "content": "回答尽量简练,请始终用中文回答"}]
|
|
85
|
+
context_manager.add_message("user", user_input)
|
|
86
|
+
messages += context_manager.get_context()
|
|
87
|
+
reply = await GPT_handler.get_response(messages)
|
|
88
|
+
context_manager.add_message("assistant", reply)
|
|
84
89
|
if REPLY_IMAGE:
|
|
85
90
|
pic = await md_to_pic(md=reply)
|
|
86
91
|
await UniMessage.image(raw=pic).send(reply_to=True)
|
|
@@ -89,6 +94,7 @@ async def got_location(user_input: str):
|
|
|
89
94
|
finally:
|
|
90
95
|
REPLY_IMAGE = plugin_config.ai_reply_image
|
|
91
96
|
|
|
97
|
+
|
|
92
98
|
__plugin_meta__ = PluginMetadata(
|
|
93
99
|
name="githubmodels",
|
|
94
100
|
description="API 调用 GitHub Models 的大语言模型",
|
|
@@ -96,4 +102,4 @@ __plugin_meta__ = PluginMetadata(
|
|
|
96
102
|
type="application",
|
|
97
103
|
homepage="https://github.com/lyqgzbl/nonebot-plugin-githubmodels",
|
|
98
104
|
supported_adapters=None,
|
|
99
|
-
)
|
|
105
|
+
)
|
|
@@ -3,6 +3,9 @@ from pydantic import BaseModel, Field
|
|
|
3
3
|
|
|
4
4
|
class Config(BaseModel):
|
|
5
5
|
github_token: Optional[str] = None
|
|
6
|
-
ai_model_name: str = "gpt-4o-mini"
|
|
7
6
|
max_context_length: int = Field(20)
|
|
8
7
|
ai_reply_image: bool = False
|
|
8
|
+
ai_model_name: str = "gpt-4o-mini"
|
|
9
|
+
ai_temperature: float = Field(1.0)
|
|
10
|
+
ai_max_tokens: int = Field(1024)
|
|
11
|
+
ai_top_p: float = Field(1.0)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class ContextManager:
|
|
2
|
+
def __init__(self, max_context_length: int):
|
|
3
|
+
self.max_context_length = max_context_length
|
|
4
|
+
self.shared_context = []
|
|
5
|
+
|
|
6
|
+
def add_message(self, role: str, content: str):
|
|
7
|
+
if self.max_context_length > 0:
|
|
8
|
+
self.shared_context.append({"role": role, "content": content})
|
|
9
|
+
if len(self.shared_context) > self.max_context_length:
|
|
10
|
+
self.shared_context = self.shared_context[-self.max_context_length:]
|
|
11
|
+
|
|
12
|
+
def get_context(self):
|
|
13
|
+
return self.shared_context.copy() if self.max_context_length > 0 else []
|
|
14
|
+
|
|
15
|
+
def reset_context(self):
|
|
16
|
+
self.shared_context = []
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
<!-- markdownlint-disable MD033 MD036 MD041 -->
|
|
2
|
-
|
|
3
|
-
<div align="center">
|
|
4
|
-
|
|
5
|
-
<a href="https://v2.nonebot.dev/store">
|
|
6
|
-
<img src="https://raw.githubusercontent.com/A-kirami/nonebot-plugin-template/resources/nbp_logo.png" width="180" height="180" alt="NoneBotPluginLogo">
|
|
7
|
-
</a>
|
|
8
|
-
|
|
9
|
-
<p>
|
|
10
|
-
<img src="https://raw.githubusercontent.com/lgc-NB2Dev/readme/main/template/plugin.svg" alt="NoneBotPluginText">
|
|
11
|
-
</p>
|
|
12
|
-
|
|
13
|
-
# nonebot-plugin-githubmodels
|
|
14
|
-
|
|
15
|
-
_✨ API调用GitHub models大语言模型 ✨_
|
|
16
|
-
|
|
17
|
-
</div>
|
|
18
|
-
|
|
19
|
-
<p align="center">
|
|
20
|
-
<a href="https://raw.githubusercontent.com/kexue-z/nonebot-plugin-heweather/master/LICENSE">
|
|
21
|
-
<img src="https://img.shields.io/github/license/kexue-z/nonebot-plugin-heweather.svg" alt="license">
|
|
22
|
-
</a>
|
|
23
|
-
<a href="https://pypi.org/project/nonebot-plugin-heweather/">
|
|
24
|
-
<img src="https://img.shields.io/pypi/v/nonebot-plugin-heweather" alt="pypi">
|
|
25
|
-
</a>
|
|
26
|
-
<img src="https://img.shields.io/badge/python-3.8+-blue.svg" alt="python">
|
|
27
|
-
</p>
|
|
28
|
-
|
|
29
|
-
# 安装
|
|
30
|
-
|
|
31
|
-
使用nb-cli
|
|
32
|
-
```shell
|
|
33
|
-
nb plugin install nonebot-plugin-githubmodels
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
# 指令
|
|
37
|
-
|
|
38
|
-
“AI xxx” 询问AI
|
|
39
|
-
例如“AI 嗨”
|
|
40
|
-
|
|
41
|
-
”AI 重置“ 重置上下文记忆
|
|
42
|
-
|
|
43
|
-
# 配置
|
|
44
|
-
|
|
45
|
-
## 见 [.env.example](https://github.com/lyqgzbl/nonebot-plugin-githubmodels/blob/main/.env.example)
|