Skip to content

Commit 306f2a1

Browse files
修复Sessions和Memory存储问题,修复类型错误 (#165)
* 修复Sessions和Memory存储问题,修复类型错误 * 修复迁移
1 parent c3fcce3 commit 306f2a1

8 files changed

Lines changed: 1212 additions & 1138 deletions

File tree

nonebot_plugin_suggarchat/handlers/chat.py

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
ToolResult,
5050
get_memory_data,
5151
)
52-
from ..utils.models import InsightsModel
52+
from ..utils.models import ImageContent, ImageUrl, InsightsModel, TextContent
5353
from ..utils.tokenizer import hybrid_token_count
5454

5555
command_prefix = get_driver().config.command_start or "/"
@@ -80,7 +80,9 @@ async def get_tokens(
8080
if isinstance(st["content"], str):
8181
full_string += st["content"]
8282
else:
83-
temp_string = "".join(s["text"] for s in st["content"] if s["type"] == "text")
83+
temp_string = "".join(
84+
s["text"] for s in st["content"] if s["type"] == "text"
85+
)
8486
full_string += temp_string
8587
it = hybrid_token_count(full_string)
8688
ot = hybrid_token_count(response.content)
@@ -97,8 +99,8 @@ async def enforce_token_limit(
9799
"""
98100
控制 token 数量,删除超出限制的旧消息.
99101
"""
100-
train = copy.deepcopy(train)
101-
memory_l = [train, *data.memory.messages]
102+
train_model = Message.model_validate(train)
103+
memory_l: list[Message | ToolResult] = [train_model, *data.memory.messages]
102104
tokens = await get_tokens(memory_l, response)
103105
if not config_manager.config.llm_config.enable_tokens_limit:
104106
return tokens
@@ -131,6 +133,7 @@ async def enforce_token_limit(
131133
tk_tmp = hybrid_token_count(
132134
full_string, config_manager.config.llm_config.tokens_count_mode
133135
)
136+
await asyncio.sleep(0)
134137
return tokens
135138

136139

@@ -198,25 +201,22 @@ async def handle_group_message(
198201
if config_manager.config.parse_segments:
199202
text = (
200203
[
201-
{
202-
"type": "text",
203-
"text": f"[{role}][{Date}][{user_name}{user_id})]说:{content}",
204-
},
204+
TextContent(
205+
text=f"[{role}][{Date}][{user_name}{user_id})]说:{content}"
206+
)
205207
]
206208
+ [
207-
{"type": "input_image", "url": seg.data.get("url")}
209+
ImageContent(image_url=ImageUrl(url=seg.data["url"]))
208210
for seg in event.message
209-
if seg.data.get("type") == "image"
211+
if seg.data.get("type") == "image" and seg.data.get("url")
210212
]
211213
if is_multimodal
212214
else f"[{role}][{Date}][{user_name}{user_id})]说:{content}"
213215
)
214216
else:
215217
text = event.message.extract_plain_text()
216218

217-
data.memory.messages.append(
218-
Message.model_validate({"role": "user", "content": text})
219-
)
219+
data.memory.messages.append(Message(role="user", content=text))
220220
if chat_manager.debug:
221221
logger.debug(f"当前群组提示词:\n{config_manager.group_train}")
222222
# 控制记忆长度和 token 限制
@@ -275,24 +275,21 @@ async def handle_private_message(
275275
if config_manager.config.parse_segments:
276276
text = (
277277
[
278-
{
279-
"type": "text",
280-
"text": f"{Date}{await get_friend_name(event.user_id, bot=bot)}{event.user_id}): {content!s}",
281-
},
278+
TextContent(
279+
text=f"{Date}{await get_friend_name(event.user_id, bot=bot)}{event.user_id}): {content!s}"
280+
)
282281
]
283282
+ [
284-
{"type": "image_url", "image_url": {"url": seg.data.get("url")}}
283+
ImageContent(image_url=ImageUrl(url=seg.data["url"]))
285284
for seg in event.message
286-
if seg.data.get("type") == "image"
285+
if seg.data.get("type") == "image" and seg.data.get("url")
287286
]
288287
if is_multimodal
289288
else f"{Date}{await get_friend_name(event.user_id, bot=bot)}{event.user_id}): {content!s}"
290289
)
291290
else:
292291
text = event.message.extract_plain_text()
293-
data.memory.messages.append(
294-
Message.model_validate({"role": "user", "content": text})
295-
)
292+
data.memory.messages.append(Message(role="user", content=text))
296293
if chat_manager.debug:
297294
logger.debug(f"当前私聊提示词:\n{config_manager.private_train}")
298295
# 控制记忆长度和 token 限制

nonebot_plugin_suggarchat/migrations/3537b7cb6a29_init.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,12 @@ def upgrade(name: str = "") -> None:
2828
sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
2929
sa.Column("ins_id", sa.Integer(), nullable=False),
3030
sa.Column("is_group", sa.Boolean(), nullable=False),
31-
sa.Column("messages_json", sa.Text(), nullable=False),
32-
sa.Column("sessions_json", sa.Text(), nullable=False),
31+
sa.Column(
32+
"messages_json", sa.Text(), nullable=False, server_default=sa.text("'{}'")
33+
),
34+
sa.Column(
35+
"sessions_json", sa.Text(), nullable=False, server_default=sa.text("'[]'")
36+
),
3337
sa.Column("time", sa.DateTime(), nullable=False),
3438
sa.Column("usage_count", sa.Integer(), nullable=False),
3539
sa.PrimaryKeyConstraint("id", name=op.f("pk_suggarchat_memory_data")),
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"""Json
2+
3+
迁移 ID: 5740c5aae763
4+
父迁移: 25b14ed0ad3c
5+
创建时间: 2025-08-21 15:46:52.697364
6+
7+
"""
8+
9+
from __future__ import annotations
10+
11+
from collections.abc import Sequence
12+
13+
import sqlalchemy as sa
14+
from alembic import op
15+
16+
revision: str = "5740c5aae763"
17+
down_revision: str | Sequence[str] | None = "25b14ed0ad3c"
18+
branch_labels: str | Sequence[str] | None = None
19+
depends_on: str | Sequence[str] | None = None
20+
21+
22+
def upgrade(name: str = "") -> None:
23+
if name:
24+
return
25+
# ### commands auto generated by Alembic - please adjust! ###
26+
with op.batch_alter_table("suggarchat_memory_data", schema=None) as batch_op:
27+
batch_op.alter_column(
28+
"memory_json",
29+
existing_type=sa.TEXT(),
30+
type_=sa.JSON(),
31+
existing_nullable=False,
32+
existing_server_default="'{}'",
33+
)
34+
batch_op.alter_column(
35+
"sessions_json",
36+
existing_type=sa.TEXT(),
37+
type_=sa.JSON(),
38+
existing_nullable=False,
39+
existing_server_default="'[]'",
40+
)
41+
42+
# ### end Alembic commands ###
43+
44+
45+
def downgrade(name: str = "") -> None:
46+
if name:
47+
return
48+
# ### commands auto generated by Alembic - please adjust! ###
49+
with op.batch_alter_table("suggarchat_memory_data", schema=None) as batch_op:
50+
batch_op.alter_column(
51+
"sessions_json",
52+
existing_type=sa.JSON(),
53+
type_=sa.TEXT(),
54+
existing_nullable=False,
55+
existing_server_default="'[]'",
56+
)
57+
batch_op.alter_column(
58+
"memory_json",
59+
existing_type=sa.JSON(),
60+
type_=sa.TEXT(),
61+
existing_nullable=False,
62+
existing_server_default="'{}'",
63+
)
64+
65+
# ### end Alembic commands ###

nonebot_plugin_suggarchat/utils/libchat.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ async def tools_caller(
138138
continue
139139
else:
140140
raise err or RuntimeError("所有适配器调用失败")
141+
142+
141143
async def get_chat(
142144
messages: list[Message | ToolResult],
143145
) -> UniResponse[str, None]:

nonebot_plugin_suggarchat/utils/memory.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from __future__ import annotations
22

3-
import json
43
import time
54
from datetime import datetime
65
from typing import overload
@@ -96,19 +95,19 @@ async def get_memory_data(
9695

9796
session.add(memory)
9897
await session.refresh(memory)
99-
memory_json_text = memory.memory_json
100-
sessions_json = memory.sessions_json
98+
memory_data = memory.memory_json
99+
sessions_data = memory.sessions_json
101100
messages = [
102101
(
103102
Message.model_validate(i)
104103
if i["role"] != "tool"
105104
else ToolResult.model_validate(i)
106105
)
107-
for i in (json.loads(memory_json_text))["messages"]
106+
for i in (memory_data)["messages"]
108107
]
109108
c_memory = Memory(messages=messages, time=memory.time.timestamp())
110109

111-
sessions = [Memory.model_validate(i) for i in json.loads(sessions_json)]
110+
sessions = [Memory.model_validate(i) for i in sessions_data]
112111
conf = MemoryModel(
113112
memory=c_memory,
114113
sessions=sessions,
@@ -172,8 +171,8 @@ async def write_memory_data(
172171
for_update=True,
173172
)
174173
session.add(memory)
175-
memory.memory_json = data.memory.model_dump_json()
176-
memory.sessions_json = json.dumps([s.model_dump() for s in data.sessions])
174+
memory.memory_json = data.memory.model_dump()
175+
memory.sessions_json = [s.model_dump() for s in data.sessions]
177176
memory.time = datetime.fromtimestamp(data.timestamp)
178177
memory.usage_count = data.usage
179178
memory.input_token_usage = data.input_token_usage

nonebot_plugin_suggarchat/utils/models.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from pydantic import BaseModel as B_Model
88
from pydantic import Field
99
from sqlalchemy import (
10+
JSON,
1011
BigInteger,
1112
Boolean,
1213
DateTime,
@@ -193,12 +194,18 @@ class Memory(Model):
193194
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
194195
ins_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
195196
is_group: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
196-
memory_json: Mapped[str] = mapped_column(
197-
Text,
198-
default=MemoryModel().model_dump_json(),
197+
memory_json: Mapped[dict[str, Any]] = mapped_column(
198+
JSON,
199+
default=MemoryModel().model_dump(),
199200
nullable=False,
201+
server_default=text("'{}'"),
202+
)
203+
sessions_json: Mapped[list[dict[str, Any]]] = mapped_column(
204+
JSON,
205+
default=[],
206+
nullable=False,
207+
server_default=text("'[]'"),
200208
)
201-
sessions_json: Mapped[str] = mapped_column(Text, default="[]", nullable=False)
202209
time: Mapped[datetime] = mapped_column(
203210
DateTime, default=datetime.now, nullable=False
204211
)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "nonebot_plugin_suggarchat"
3-
version = "3.4.5"
3+
version = "3.4.5.1"
44
description = "SuggarChat chat framework"
55
authors = [{ name = "LiteSuggarDEV", email = "windowserror@163.com" }]
66
dependencies = [

0 commit comments

Comments
 (0)