Merge pull request #11 from Fu-Jie/copilot/reuse-db-connection

Refactor async-context-compression to re-use OpenWebUI's internal DB connection
This commit is contained in:
Jeff
2025-12-31 13:04:42 +08:00
committed by GitHub
5 changed files with 203 additions and 247 deletions

View File

@@ -349,6 +349,119 @@ requirements: python-docx==1.1.2, openpyxl==3.1.2
---
## 🗄️ 数据库连接规范 (Database Connection)
### 复用 OpenWebUI 内部连接 (Re-use OpenWebUI's Internal Connection)
当插件需要持久化存储时,**必须**复用 Open WebUI 的内部数据库连接,而不是创建新的数据库引擎。这确保了:
- 插件与数据库类型无关(自动支持 PostgreSQL、SQLite 等)
- 自动继承 Open WebUI 的数据库配置
- 避免连接池资源浪费
- 保持与 Open WebUI 核心的兼容性
When a plugin requires persistent storage, it **MUST** re-use Open WebUI's internal database connection instead of creating a new database engine. This ensures:
- The plugin is database-agnostic (automatically supports PostgreSQL, SQLite, etc.)
- Automatic inheritance of Open WebUI's database configuration
- No wasted connection pool resources
- Compatibility with Open WebUI's core
### 实现示例 (Implementation Example)
```python
# Open WebUI internal database (re-use shared connection)
from open_webui.internal.db import engine as owui_engine
from open_webui.internal.db import Session as owui_Session
from open_webui.internal.db import Base as owui_Base
from sqlalchemy import Column, String, Text, DateTime, Integer, inspect
from datetime import datetime
class PluginTable(owui_Base):
"""Plugin storage table - inherits from OpenWebUI's Base"""
__tablename__ = "plugin_table_name"
__table_args__ = {"extend_existing": True} # Required to avoid conflicts on plugin reload
id = Column(Integer, primary_key=True, autoincrement=True)
unique_id = Column(String(255), unique=True, nullable=False, index=True)
data = Column(Text, nullable=False)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
class Filter: # or Pipe, Action, etc.
def __init__(self):
self.valves = self.Valves()
self._db_engine = owui_engine
self._SessionLocal = owui_Session
self._init_database()
def _init_database(self):
"""Initialize the database table using OpenWebUI's shared connection."""
try:
inspector = inspect(self._db_engine)
if not inspector.has_table("plugin_table_name"):
PluginTable.__table__.create(bind=self._db_engine, checkfirst=True)
print("[Database] ✅ Created plugin table using OpenWebUI's shared connection.")
else:
print("[Database] ✅ Using OpenWebUI's shared connection. Table already exists.")
except Exception as e:
print(f"[Database] ❌ Initialization failed: {str(e)}")
def _save_data(self, unique_id: str, data: str):
"""Save data using context manager pattern."""
try:
with self._SessionLocal() as session:
# Your database operations here
session.commit()
except Exception as e:
print(f"[Storage] ❌ Database save failed: {str(e)}")
def _load_data(self, unique_id: str):
"""Load data using context manager pattern."""
try:
with self._SessionLocal() as session:
record = session.query(PluginTable).filter_by(unique_id=unique_id).first()
if record:
session.expunge(record) # Detach from session for use after close
return record
except Exception as e:
print(f"[Load] ❌ Database read failed: {str(e)}")
return None
```
### 禁止的做法 (Prohibited Practices)
以下做法**已被弃用**,不应在新插件中使用:
The following practices are **deprecated** and should NOT be used in new plugins:
```python
# ❌ 禁止: 读取 DATABASE_URL 环境变量
# ❌ Prohibited: Reading DATABASE_URL environment variable
database_url = os.getenv("DATABASE_URL")
# ❌ 禁止: 创建独立的数据库引擎
# ❌ Prohibited: Creating a separate database engine
from sqlalchemy import create_engine
self._db_engine = create_engine(database_url, **engine_args)
# ❌ 禁止: 创建独立的会话工厂
# ❌ Prohibited: Creating a separate session factory
from sqlalchemy.orm import sessionmaker
self._SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=self._db_engine)
# ❌ 禁止: 使用独立的 Base
# ❌ Prohibited: Using a separate Base
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
```
---
## 🔧 代码规范 (Code Style)
### Python 规范

View File

@@ -1,6 +1,6 @@
# Async Context Compression Filter
**Author:** [Fu-Jie](https://github.com/Fu-Jie) | **Version:** 1.0.0 | **License:** MIT
**Author:** [Fu-Jie](https://github.com/Fu-Jie) | **Version:** 1.1.0 | **License:** MIT
> **Important Note**: To ensure the maintainability and usability of all filters, each filter should be accompanied by clear and complete documentation to fully explain its functionality, configuration, and usage.
@@ -12,7 +12,7 @@ This filter significantly reduces token consumption in long conversations by usi
-**Automatic Compression**: Triggers context compression automatically based on a message count threshold.
-**Asynchronous Summarization**: Generates summaries in the background without blocking the current chat response.
-**Persistent Storage**: Supports both PostgreSQL and SQLite databases to ensure summaries are not lost after a service restart.
-**Persistent Storage**: Uses Open WebUI's shared database connection - automatically supports any database backend (PostgreSQL, SQLite, etc.).
-**Flexible Retention Policy**: Freely configure the number of initial and final messages to keep, ensuring critical information and context continuity.
-**Smart Injection**: Intelligently injects the generated historical summary into the new context.
@@ -20,18 +20,11 @@ This filter significantly reduces token consumption in long conversations by usi
## Installation & Configuration
### 1. Environment Variable
### 1. Database (Automatic)
This plugin requires a database connection. You **must** configure the `DATABASE_URL` in your Open WebUI environment variables.
This plugin automatically uses Open WebUI's shared database connection. **No additional database configuration is required.**
- **PostgreSQL Example**:
```
DATABASE_URL=postgresql://user:password@host:5432/openwebui
```
- **SQLite Example**:
```
DATABASE_URL=sqlite:///path/to/your/data/webui.db
```
The `chat_summary` table will be created automatically on first run.
### 2. Filter Order
@@ -64,8 +57,8 @@ You can adjust the following parameters in the filter's settings:
## Troubleshooting
- **Problem: Database connection failed.**
- **Solution**: Please ensure the `DATABASE_URL` environment variable is set correctly and that the database service is running.
- **Problem: Database table not created.**
- **Solution**: Ensure Open WebUI is properly configured with a database and check Open WebUI's logs for detailed error messages.
- **Problem: Summary not generated.**
- **Solution**: Check if the `compression_threshold` has been met and verify that `summary_model` is configured correctly. Check the logs for detailed errors.

View File

@@ -1,6 +1,6 @@
# 异步上下文压缩过滤器
**作者:** [Fu-Jie](https://github.com/Fu-Jie) | **版本:** 1.0.0 | **许可证:** MIT
**作者:** [Fu-Jie](https://github.com/Fu-Jie) | **版本:** 1.1.0 | **许可证:** MIT
> **重要提示**:为了确保所有过滤器的可维护性和易用性,每个过滤器都应附带清晰、完整的文档,以确保其功能、配置和使用方法得到充分说明。
@@ -12,7 +12,7 @@
-**自动压缩**: 基于消息数量阈值自动触发上下文压缩。
-**异步摘要**: 在后台生成摘要,不阻塞当前对话的响应。
-**持久化存储**: 支持 PostgreSQLSQLite 数据库,确保摘要在服务重启后不丢失
-**持久化存储**: 使用 Open WebUI 的共享数据库连接 - 自动支持任何数据库后端(PostgreSQLSQLite 等)
-**灵活保留策略**: 可自由配置保留对话头部和尾部的消息数量,确保关键信息和上下文的连贯性。
-**智能注入**: 将生成的历史摘要智能地注入到新的上下文中。
@@ -22,18 +22,11 @@
## 安装与配置
### 1. 环境变量
### 1. 数据库(自动)
本插件的运行依赖于数据库,您**必须**在 Open WebUI 的环境变量中配置 `DATABASE_URL`
本插件自动使用 Open WebUI 的共享数据库连接。**无需额外的数据库配置。**
- **PostgreSQL 示例**:
```
DATABASE_URL=postgresql://user:password@host:5432/openwebui
```
- **SQLite 示例**:
```
DATABASE_URL=sqlite:///path/to/your/data/webui.db
```
`chat_summary` 表将在首次运行时自动创建。
### 2. 过滤器顺序
@@ -101,8 +94,8 @@
## 故障排除
- **问题:数据库连接失败**
- **解决**:请确认 `DATABASE_URL` 环境变量已正确设置,并且数据库服务运行正常
- **问题:数据库表未创建**
- **解决**:确保 Open WebUI 已正确配置数据库,并查看 Open WebUI 的日志以获取详细的错误信息
- **问题:摘要未生成**
- **解决**:检查 `compression_threshold_tokens` 是否已达到,并确认 `summary_model` 配置正确。查看日志以获取详细错误。

View File

@@ -5,7 +5,7 @@ author: Fu-Jie
author_url: https://github.com/Fu-Jie
funding_url: https://github.com/Fu-Jie/awesome-openwebui
description: Reduces token consumption in long conversations while maintaining coherence through intelligent summarization and message compression.
version: 1.0.1
version: 1.1.0
license: MIT
═══════════════════════════════════════════════════════════════════════════════
@@ -49,14 +49,13 @@ Phase 2: Outlet (Post-response processing)
💾 Storage
═══════════════════════════════════════════════════════════════════════════════
This filter uses a database for persistent storage, configured via the `DATABASE_URL` environment variable. It supports both PostgreSQL and SQLite.
This filter uses Open WebUI's shared database connection for persistent storage.
It automatically reuses Open WebUI's internal SQLAlchemy engine and SessionLocal,
making the plugin database-agnostic and ensuring compatibility with any database
backend that Open WebUI supports (PostgreSQL, SQLite, etc.).
Configuration:
- The `DATABASE_URL` environment variable must be set.
- PostgreSQL Example: `postgresql://user:password@host:5432/openwebui`
- SQLite Example: `sqlite:///path/to/your/database.db`
The filter automatically selects the appropriate database driver based on the `DATABASE_URL` prefix (`postgres` or `sqlite`).
No additional database configuration is required - the plugin inherits
Open WebUI's database settings automatically.
Table Structure (`chat_summary`):
- id: Primary Key (auto-increment)
@@ -142,21 +141,8 @@ debug_mode
🔧 Deployment
═══════════════════════════════════════════════════════
Docker Compose Example:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
services:
openwebui:
environment:
DATABASE_URL: postgresql://user:password@postgres:5432/openwebui
depends_on:
- postgres
postgres:
image: postgres:15-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: openwebui
The plugin automatically uses Open WebUI's shared database connection.
No additional database configuration is required.
Suggested Filter Installation Order:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
@@ -201,9 +187,10 @@ Statistics:
⚠️ Important Notes
═══════════════════════════════════════════════════════════════════════════════
1. Database Permissions
⚠ Ensure the user specified in `DATABASE_URL` has permissions to create tables.
⚠ The `chat_summary` table will be created automatically on first run.
1. Database Connection
✓ The plugin uses Open WebUI's shared database connection automatically.
✓ No additional configuration is required.
✓ The `chat_summary` table will be created automatically on first run.
2. Retention Policy
⚠ The `keep_first` setting is crucial for preserving initial messages that contain system prompts. Configure it as needed.
@@ -226,13 +213,11 @@ Statistics:
🐛 Troubleshooting
═══════════════════════════════════════════════════════════════════════════════
Problem: Database connection failed
Problem: Database table not created
Solution:
1. Verify that the `DATABASE_URL` environment variable is set correctly.
2. Confirm that `DATABASE_URL` starts with either `sqlite` or `postgres`.
3. Ensure the database service is running and network connectivity is normal.
4. Validate the username, password, host, and port in the connection URL.
5. Check the Open WebUI container logs for detailed error messages.
1. Ensure Open WebUI is properly configured with a database.
2. Check the Open WebUI container logs for detailed error messages.
3. Verify that Open WebUI's database connection is working correctly.
Problem: Summary not generated
Solution:
@@ -258,7 +243,6 @@ from typing import Optional, Dict, Any, List, Union, Callable, Awaitable
import asyncio
import json
import hashlib
import os
import time
# Open WebUI built-in imports
@@ -267,6 +251,11 @@ from open_webui.models.users import Users
from fastapi.requests import Request
from open_webui.main import app as webui_app
# Open WebUI internal database (re-use shared connection)
from open_webui.internal.db import engine as owui_engine
from open_webui.internal.db import Session as owui_Session
from open_webui.internal.db import Base as owui_Base
# Try to import tiktoken
try:
import tiktoken
@@ -274,18 +263,15 @@ except ImportError:
tiktoken = None
# Database imports
from sqlalchemy import create_engine, Column, String, Text, DateTime, Integer
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import Column, String, Text, DateTime, Integer, inspect
from datetime import datetime
Base = declarative_base()
class ChatSummary(Base):
class ChatSummary(owui_Base):
"""Chat Summary Storage Table"""
__tablename__ = "chat_summary"
__table_args__ = {"extend_existing": True}
id = Column(Integer, primary_key=True, autoincrement=True)
chat_id = Column(String(255), unique=True, nullable=False, index=True)
@@ -298,74 +284,29 @@ class ChatSummary(Base):
class Filter:
def __init__(self):
self.valves = self.Valves()
self._db_engine = None
self._SessionLocal = None
self._db_engine = owui_engine
self._SessionLocal = owui_Session
self.temp_state = {} # Used to pass temporary data between inlet and outlet
self._init_database()
def _init_database(self):
"""Initializes the database connection and table."""
"""Initializes the database table using Open WebUI's shared connection."""
try:
database_url = os.getenv("DATABASE_URL")
if not database_url:
# Check if table exists using SQLAlchemy inspect
inspector = inspect(self._db_engine)
if not inspector.has_table("chat_summary"):
# Create the chat_summary table if it doesn't exist
ChatSummary.__table__.create(bind=self._db_engine, checkfirst=True)
print(
"[Database] ❌ Error: DATABASE_URL environment variable is not set. Please set this variable."
"[Database] ✅ Successfully created chat_summary table using Open WebUI's shared database connection."
)
self._db_engine = None
self._SessionLocal = None
return
db_type = None
engine_args = {}
if database_url.startswith("sqlite"):
db_type = "SQLite"
engine_args = {
"connect_args": {"check_same_thread": False},
"echo": False,
}
elif database_url.startswith("postgres"):
db_type = "PostgreSQL"
if database_url.startswith("postgres://"):
database_url = database_url.replace(
"postgres://", "postgresql://", 1
)
print(
"[Database] Automatically converted postgres:// to postgresql://"
)
engine_args = {
"pool_pre_ping": True,
"pool_recycle": 3600,
"echo": False,
}
else:
print(
f"[Database] ❌ Error: Unsupported database type. DATABASE_URL must start with 'sqlite' or 'postgres'. Current value: {database_url}"
"[Database] ✅ Using Open WebUI's shared database connection. chat_summary table already exists."
)
self._db_engine = None
self._SessionLocal = None
return
# Create database engine
self._db_engine = create_engine(database_url, **engine_args)
# Create session factory
self._SessionLocal = sessionmaker(
autocommit=False, autoflush=False, bind=self._db_engine
)
# Create table if it doesn't exist
Base.metadata.create_all(bind=self._db_engine)
print(
f"[Database] ✅ Successfully connected to {db_type} and initialized the chat_summary table."
)
except Exception as e:
print(f"[Database] ❌ Initialization failed: {str(e)}")
self._db_engine = None
self._SessionLocal = None
class Valves(BaseModel):
priority: int = Field(
@@ -416,14 +357,8 @@ class Filter:
def _save_summary(self, chat_id: str, summary: str, compressed_count: int):
"""Saves the summary to the database."""
if not self._SessionLocal:
if self.valves.debug_mode:
print("[Storage] Database not initialized, skipping summary save.")
return
try:
session = self._SessionLocal()
try:
with self._SessionLocal() as session:
# Find existing record
existing = session.query(ChatSummary).filter_by(chat_id=chat_id).first()
@@ -457,27 +392,18 @@ class Filter:
f"[Storage] Summary has been {action.lower()} in the database (Chat ID: {chat_id})"
)
finally:
session.close()
except Exception as e:
print(f"[Storage] ❌ Database save failed: {str(e)}")
def _load_summary_record(self, chat_id: str) -> Optional[ChatSummary]:
"""Loads the summary record object from the database."""
if not self._SessionLocal:
return None
try:
session = self._SessionLocal()
try:
with self._SessionLocal() as session:
record = session.query(ChatSummary).filter_by(chat_id=chat_id).first()
if record:
# Detach the object from the session so it can be used after session close
session.expunge(record)
return record
finally:
session.close()
except Exception as e:
print(f"[Load] ❌ Database read failed: {str(e)}")
return None

View File

@@ -5,7 +5,7 @@ author: Fu-Jie
author_url: https://github.com/Fu-Jie
funding_url: https://github.com/Fu-Jie/awesome-openwebui
description: 通过智能摘要和消息压缩,降低长对话的 token 消耗,同时保持对话连贯性。
version: 1.0.0
version: 1.1.0
license: MIT
═══════════════════════════════════════════════════════════════════════════════
@@ -49,14 +49,12 @@ license: MIT
💾 存储方案
═══════════════════════════════════════════════════════════════════════════════
本过滤器使用数据库进行持久化存储,通过 `DATABASE_URL` 环境变量进行配置,支持 PostgreSQL 和 SQLite
本过滤器使用 Open WebUI 的共享数据库连接进行持久化存储。
它自动复用 Open WebUI 内部的 SQLAlchemy 引擎和 SessionLocal
使插件与数据库类型无关,并确保与 Open WebUI 支持的任何数据库后端
PostgreSQL、SQLite 等)兼容。
配置方式:
- 必须设置 `DATABASE_URL` 环境变量。
- PostgreSQL 示例: `postgresql://user:password@host:5432/openwebui`
- SQLite 示例: `sqlite:///path/to/your/database.db`
过滤器会根据 `DATABASE_URL` 的前缀(`postgres` 或 `sqlite`)自动选择合适的数据库驱动。
无需额外的数据库配置 - 插件自动继承 Open WebUI 的数据库设置。
表结构:
- id: 主键(自增)
@@ -142,21 +140,8 @@ debug_mode (调试模式)
🔧 部署配置
═══════════════════════════════════════════════════════
Docker Compose 示例:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
services:
openwebui:
environment:
DATABASE_URL: postgresql://user:password@postgres:5432/openwebui
depends_on:
- postgres
postgres:
image: postgres:15-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: openwebui
插件自动使用 Open WebUI 的共享数据库连接。
无需额外的数据库配置。
过滤器安装顺序建议:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
@@ -201,9 +186,10 @@ Docker Compose 示例:
⚠️ 注意事项
═══════════════════════════════════════════════════════════════════════════════
1. 数据库权限
⚠ 确保 `DATABASE_URL` 指向的用户有创建表的权限
⚠ 首次运行会自动创建 `chat_summary` 表
1. 数据库连接
✓ 插件自动使用 Open WebUI 的共享数据库连接
✓ 无需额外配置
✓ 首次运行会自动创建 `chat_summary` 表。
2. 保留策略
⚠ `keep_first` 配置对于保留包含提示或环境变量的初始消息非常重要。请根据需要进行配置。
@@ -226,13 +212,11 @@ Docker Compose 示例:
🐛 故障排除
═══════════════════════════════════════════════════════════════════════════════
问题:数据库连接失败
问题:数据库表未创建
解决:
1. 确认 `DATABASE_URL` 环境变量已正确设置
2. 确认 `DATABASE_URL` 以 `sqlite` 或 `postgres` 开头
3. 确认数据库服务正在运行,并且网络连接正常
4. 验证连接 URL 中的用户名、密码、主机和端口是否正确。
5. 查看 Open WebUI 的容器日志以获取详细的错误信息。
1. 确保 Open WebUI 已正确配置数据库
2. 查看 Open WebUI 的容器日志以获取详细的错误信息
3. 验证 Open WebUI 的数据库连接是否正常工作
问题:摘要未生成
解决:
@@ -258,7 +242,6 @@ from typing import Optional, Dict, Any, List, Union, Callable, Awaitable
import asyncio
import json
import hashlib
import os
import time
# Open WebUI 内置导入
@@ -267,6 +250,11 @@ from open_webui.models.users import Users
from fastapi.requests import Request
from open_webui.main import app as webui_app
# Open WebUI 内部数据库 (复用共享连接)
from open_webui.internal.db import engine as owui_engine
from open_webui.internal.db import Session as owui_Session
from open_webui.internal.db import Base as owui_Base
# 尝试导入 tiktoken
try:
import tiktoken
@@ -274,18 +262,15 @@ except ImportError:
tiktoken = None
# 数据库导入
from sqlalchemy import create_engine, Column, String, Text, DateTime, Integer
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import Column, String, Text, DateTime, Integer, inspect
from datetime import datetime
Base = declarative_base()
class ChatSummary(Base):
class ChatSummary(owui_Base):
"""对话摘要存储表"""
__tablename__ = "chat_summary"
__table_args__ = {"extend_existing": True}
id = Column(Integer, primary_key=True, autoincrement=True)
chat_id = Column(String(255), unique=True, nullable=False, index=True)
@@ -298,68 +283,29 @@ class ChatSummary(Base):
class Filter:
def __init__(self):
self.valves = self.Valves()
self._db_engine = None
self._SessionLocal = None
self._db_engine = owui_engine
self._SessionLocal = owui_Session
self.temp_state = {} # 用于在 inlet 和 outlet 之间传递临时数据
self._init_database()
def _init_database(self):
"""初始化数据库连接和"""
"""使用 Open WebUI 的共享连接初始化数据库表"""
try:
database_url = os.getenv("DATABASE_URL")
if not database_url:
print("[数据库] ❌ 错误: DATABASE_URL 环境变量未设置。请设置该变量。")
self._db_engine = None
self._SessionLocal = None
return
db_type = None
engine_args = {}
if database_url.startswith("sqlite"):
db_type = "SQLite"
engine_args = {
"connect_args": {"check_same_thread": False},
"echo": False,
}
elif database_url.startswith("postgres"):
db_type = "PostgreSQL"
if database_url.startswith("postgres://"):
database_url = database_url.replace(
"postgres://", "postgresql://", 1
)
print("[数据库] 已自动将 postgres:// 转换为 postgresql://")
engine_args = {
"pool_pre_ping": True,
"pool_recycle": 3600,
"echo": False,
}
# 使用 SQLAlchemy inspect 检查表是否存在
inspector = inspect(self._db_engine)
if not inspector.has_table("chat_summary"):
# 如果表不存在则创建
ChatSummary.__table__.create(bind=self._db_engine, checkfirst=True)
print(
"[数据库] ✅ 使用 Open WebUI 的共享数据库连接成功创建 chat_summary 表。"
)
else:
print(
f"[数据库] ❌ 错误: 不支持的数据库类型。DATABASE_URL 必须以 'sqlite''postgres' 开头。当前值: {database_url}"
"[数据库] ✅ 使用 Open WebUI 的共享数据库连接。chat_summary 表已存在。"
)
self._db_engine = None
self._SessionLocal = None
return
# 创建数据库引擎
self._db_engine = create_engine(database_url, **engine_args)
# 创建会话工厂
self._SessionLocal = sessionmaker(
autocommit=False, autoflush=False, bind=self._db_engine
)
# 创建表(如果不存在)
Base.metadata.create_all(bind=self._db_engine)
print(f"[数据库] ✅ 成功连接到 {db_type} 并初始化 chat_summary 表")
except Exception as e:
print(f"[数据库] ❌ 初始化失败: {str(e)}")
self._db_engine = None
self._SessionLocal = None
class Valves(BaseModel):
priority: int = Field(
@@ -401,14 +347,8 @@ class Filter:
def _save_summary(self, chat_id: str, summary: str, compressed_count: int):
"""保存摘要到数据库"""
if not self._SessionLocal:
if self.valves.debug_mode:
print("[存储] 数据库未初始化,跳过保存摘要")
return
try:
session = self._SessionLocal()
try:
with self._SessionLocal() as session:
# 查找现有记录
existing = session.query(ChatSummary).filter_by(chat_id=chat_id).first()
@@ -440,27 +380,18 @@ class Filter:
action = "更新" if existing else "创建"
print(f"[存储] 摘要已{action}到数据库 (Chat ID: {chat_id})")
finally:
session.close()
except Exception as e:
print(f"[存储] ❌ 数据库保存失败: {str(e)}")
def _load_summary_record(self, chat_id: str) -> Optional[ChatSummary]:
"""从数据库加载摘要记录对象"""
if not self._SessionLocal:
return None
try:
session = self._SessionLocal()
try:
with self._SessionLocal() as session:
record = session.query(ChatSummary).filter_by(chat_id=chat_id).first()
if record:
# Detach the object from the session so it can be used after session close
session.expunge(record)
return record
finally:
session.close()
except Exception as e:
print(f"[加载] ❌ 数据库读取失败: {str(e)}")
return None
@@ -815,7 +746,7 @@ class Filter:
# 计算当前总 Token (使用摘要模型进行计数)
total_tokens = await asyncio.to_thread(
self._calculate_messages_tokens, messages, summary_model_id
self._calculate_messages_tokens, messages
)
if total_tokens > max_context_tokens: