feat: 支持Matrix access_token登录,配置AI模型接口

This commit is contained in:
2026-04-11 11:58:14 +08:00
parent c27fc8c02f
commit fd583132d7
8 changed files with 186 additions and 22 deletions

Binary file not shown.

40
init_config.py Normal file
View File

@@ -0,0 +1,40 @@
#!/usr/bin/env python3
"""初始化配置"""
import sys
sys.path.insert(0, '/home/xian/.openclaw/workspace-coder/works/ai-chat')
from models import SessionLocal, SystemConfig, init_db
# 初始化数据库
init_db()
db = SessionLocal()
# 配置AI模型
configs = [
{'key': 'ai_api_base', 'value': 'http://192.168.2.17:19007/v1', 'description': 'AI模型API地址'},
{'key': 'ai_api_key', 'value': 'xxxx', 'description': 'AI模型API Key'},
{'key': 'ai_model', 'value': 'auto', 'description': 'AI模型名称'},
# 配置Matrix Bot
{'key': 'matrix_homeserver', 'value': 'https://matrix.tphai.com', 'description': 'Matrix服务器地址'},
{'key': 'matrix_username', 'value': '@tester:matrix.tphai.com', 'description': 'Matrix Bot用户名'},
{'key': 'matrix_access_token', 'value': 'syt_dGVzdGVy_eMwWfezCXSyBgHzvkmly_4dWFtM', 'description': 'Matrix Bot Access Token'},
]
for config in configs:
existing = db.query(SystemConfig).filter(SystemConfig.key == config['key']).first()
if existing:
existing.value = config['value']
existing.description = config['description']
else:
db.add(SystemConfig(**config))
db.commit()
print("配置已写入数据库")
# 显示配置
for c in db.query(SystemConfig).all():
print(f"{c.key}: {c.value}")
db.close()

View File

@@ -1,18 +1,93 @@
Traceback (most recent call last): /home/xian/.openclaw/workspace-coder/works/ai-chat/main.py:445: DeprecationWarning:
File "/home/xian/.openclaw/workspace-coder/works/ai-chat/main.py", line 17, in <module> on_event is deprecated, use lifespan event handlers instead.
from models import init_db, get_db, User, Conversation, Message, SystemConfig
File "/home/xian/.openclaw/workspace-coder/works/ai-chat/models/__init__.py", line 1, in <module> Read more about it in the
from .database import Base, engine, SessionLocal, get_db, init_db [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/).
File "/home/xian/.openclaw/workspace-coder/works/ai-chat/models/database.py", line 33, in <module>
class Conversation(Base): @app.on_event("startup")
File "/home/xian/.local/lib/python3.10/site-packages/sqlalchemy/orm/decl_api.py", line 195, in __init__ /home/xian/.openclaw/workspace-coder/works/ai-chat/main.py:470: DeprecationWarning:
_as_declarative(reg, cls, dict_) on_event is deprecated, use lifespan event handlers instead.
File "/home/xian/.local/lib/python3.10/site-packages/sqlalchemy/orm/decl_base.py", line 247, in _as_declarative
return _MapperConfig.setup_mapping(registry, cls, dict_, None, {}) Read more about it in the
File "/home/xian/.local/lib/python3.10/site-packages/sqlalchemy/orm/decl_base.py", line 328, in setup_mapping [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/).
return _ClassScanMapperConfig(
File "/home/xian/.local/lib/python3.10/site-packages/sqlalchemy/orm/decl_base.py", line 574, in __init__ @app.on_event("shutdown")
self._extract_mappable_attributes() INFO: Started server process [1416772]
File "/home/xian/.local/lib/python3.10/site-packages/sqlalchemy/orm/decl_base.py", line 1507, in _extract_mappable_attributes INFO: Waiting for application startup.
raise exc.InvalidRequestError( INFO:__main__:数据库初始化完成
sqlalchemy.exc.InvalidRequestError: Attribute name 'metadata' is reserved when using the Declarative API. INFO:services.ai_service:AI配置已更新: http://192.168.2.17:19007/v1, model=auto
INFO:__main__:AI配置已加载: http://192.168.2.17:19007/v1, model=auto
INFO:services.matrix_service:Matrix连接成功(使用token): @tester:matrix.tphai.com
INFO:__main__:Matrix Bot已启动
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:19020 (Press CTRL+C to quit)
WARNING:nio.client.async_client:Timed out, sleeping for 0s
WARNING:nio.client.async_client:Timed out, sleeping for 0s
WARNING:nio.client.async_client:Timed out, sleeping for 0s
WARNING:nio.client.async_client:Timed out, sleeping for 0s
WARNING:nio.client.async_client:Timed out, sleeping for 1s
WARNING:nio.client.async_client:Timed out, sleeping for 3s
WARNING: Unsupported upgrade request.
WARNING: No supported WebSocket library detected. Please use "pip install 'uvicorn[standard]'", or install 'websockets' or 'wsproto' manually.
INFO: 192.168.2.10:58534 - "GET /ws/web_c8teajbbm HTTP/1.1" 404 Not Found
WARNING:nio.client.async_client:Timed out, sleeping for 6s
WARNING: Unsupported upgrade request.
WARNING: No supported WebSocket library detected. Please use "pip install 'uvicorn[standard]'", or install 'websockets' or 'wsproto' manually.
INFO: 192.168.2.10:58535 - "GET /ws/web_c8teajbbm HTTP/1.1" 404 Not Found
WARNING:nio.client.async_client:Timed out, sleeping for 12s
WARNING: Unsupported upgrade request.
WARNING: No supported WebSocket library detected. Please use "pip install 'uvicorn[standard]'", or install 'websockets' or 'wsproto' manually.
INFO: 192.168.2.10:58536 - "GET /ws/web_c8teajbbm HTTP/1.1" 404 Not Found
WARNING: Unsupported upgrade request.
WARNING: No supported WebSocket library detected. Please use "pip install 'uvicorn[standard]'", or install 'websockets' or 'wsproto' manually.
INFO: 192.168.2.10:58541 - "GET /ws/web_c8teajbbm HTTP/1.1" 404 Not Found
WARNING: Unsupported upgrade request.
WARNING: No supported WebSocket library detected. Please use "pip install 'uvicorn[standard]'", or install 'websockets' or 'wsproto' manually.
INFO: 192.168.2.10:58542 - "GET /ws/web_c8teajbbm HTTP/1.1" 404 Not Found
WARNING:nio.client.async_client:Timed out, sleeping for 25s
WARNING: Unsupported upgrade request.
WARNING: No supported WebSocket library detected. Please use "pip install 'uvicorn[standard]'", or install 'websockets' or 'wsproto' manually.
INFO: 192.168.2.10:58544 - "GET /ws/web_c8teajbbm HTTP/1.1" 404 Not Found
WARNING: Unsupported upgrade request.
WARNING: No supported WebSocket library detected. Please use "pip install 'uvicorn[standard]'", or install 'websockets' or 'wsproto' manually.
INFO: 192.168.2.10:58549 - "GET /ws/web_c8teajbbm HTTP/1.1" 404 Not Found
INFO: 127.0.0.1:53464 - "GET /api/admin/config HTTP/1.1" 200 OK
WARNING: Unsupported upgrade request.
WARNING: No supported WebSocket library detected. Please use "pip install 'uvicorn[standard]'", or install 'websockets' or 'wsproto' manually.
INFO: 192.168.2.10:58554 - "GET /ws/web_c8teajbbm HTTP/1.1" 404 Not Found
WARNING: Unsupported upgrade request.
WARNING: No supported WebSocket library detected. Please use "pip install 'uvicorn[standard]'", or install 'websockets' or 'wsproto' manually.
INFO: 192.168.2.10:58555 - "GET /ws/web_c8teajbbm HTTP/1.1" 404 Not Found
WARNING: Unsupported upgrade request.
WARNING: No supported WebSocket library detected. Please use "pip install 'uvicorn[standard]'", or install 'websockets' or 'wsproto' manually.
INFO: 192.168.2.10:58560 - "GET /ws/web_c8teajbbm HTTP/1.1" 404 Not Found
WARNING: Unsupported upgrade request.
WARNING: No supported WebSocket library detected. Please use "pip install 'uvicorn[standard]'", or install 'websockets' or 'wsproto' manually.
INFO: 192.168.2.10:58561 - "GET /ws/web_c8teajbbm HTTP/1.1" 404 Not Found
WARNING:nio.client.async_client:Timed out, sleeping for 51s
WARNING: Unsupported upgrade request.
WARNING: No supported WebSocket library detected. Please use "pip install 'uvicorn[standard]'", or install 'websockets' or 'wsproto' manually.
INFO: 192.168.2.10:58562 - "GET /ws/web_c8teajbbm HTTP/1.1" 404 Not Found
WARNING: Unsupported upgrade request.
WARNING: No supported WebSocket library detected. Please use "pip install 'uvicorn[standard]'", or install 'websockets' or 'wsproto' manually.
INFO: 192.168.2.10:58567 - "GET /ws/web_c8teajbbm HTTP/1.1" 404 Not Found
WARNING: Unsupported upgrade request.
WARNING: No supported WebSocket library detected. Please use "pip install 'uvicorn[standard]'", or install 'websockets' or 'wsproto' manually.
INFO: 192.168.2.10:58572 - "GET /ws/web_c8teajbbm HTTP/1.1" 404 Not Found
WARNING: Unsupported upgrade request.
WARNING: No supported WebSocket library detected. Please use "pip install 'uvicorn[standard]'", or install 'websockets' or 'wsproto' manually.
INFO: 192.168.2.10:58573 - "GET /ws/web_c8teajbbm HTTP/1.1" 404 Not Found
WARNING: Unsupported upgrade request.
WARNING: No supported WebSocket library detected. Please use "pip install 'uvicorn[standard]'", or install 'websockets' or 'wsproto' manually.
INFO: 192.168.2.10:58574 - "GET /ws/web_c8teajbbm HTTP/1.1" 404 Not Found
WARNING: Unsupported upgrade request.
WARNING: No supported WebSocket library detected. Please use "pip install 'uvicorn[standard]'", or install 'websockets' or 'wsproto' manually.
INFO: 192.168.2.10:58579 - "GET /ws/web_c8teajbbm HTTP/1.1" 404 Not Found
WARNING: Unsupported upgrade request.
WARNING: No supported WebSocket library detected. Please use "pip install 'uvicorn[standard]'", or install 'websockets' or 'wsproto' manually.
INFO: 192.168.2.10:58580 - "GET /ws/web_c8teajbbm HTTP/1.1" 404 Not Found
INFO: 127.0.0.1:37888 - "GET / HTTP/1.1" 200 OK
INFO: 127.0.0.1:37892 - "GET /admin HTTP/1.1" 200 OK
WARNING: Unsupported upgrade request.
WARNING: No supported WebSocket library detected. Please use "pip install 'uvicorn[standard]'", or install 'websockets' or 'wsproto' manually.
INFO: 192.168.2.10:58583 - "GET /ws/web_c8teajbbm HTTP/1.1" 404 Not Found

24
main.py
View File

@@ -14,7 +14,7 @@ import logging
from datetime import datetime from datetime import datetime
import os import os
from models import init_db, get_db, User, Conversation, Message, SystemConfig from models import init_db, get_db, SessionLocal, User, Conversation, Message, SystemConfig
from services import ai_service, ConversationService, matrix_bot from services import ai_service, ConversationService, matrix_bot
# 配置日志 # 配置日志
@@ -379,7 +379,15 @@ async def update_config(data: dict, db: Session = Depends(get_db)):
db.commit() db.commit()
# 如果更新了Matrix配置重新连接 # 根据配置类型执行相应操作
if key.startswith('ai_'):
# 更新AI服务配置
configs = {c.key: c.value for c in db.query(SystemConfig).all()}
api_base = configs.get('ai_api_base', 'http://192.168.2.17:19007/v1')
api_key = configs.get('ai_api_key', 'xxxx')
model = configs.get('ai_model', 'auto')
ai_service.update_config(api_base, api_key, model)
if key.startswith('matrix_') and matrix_bot.is_running: if key.startswith('matrix_') and matrix_bot.is_running:
await matrix_bot.disconnect() await matrix_bot.disconnect()
await matrix_bot.init_from_config() await matrix_bot.init_from_config()
@@ -440,6 +448,18 @@ async def startup():
init_db() init_db()
logger.info("数据库初始化完成") logger.info("数据库初始化完成")
# 从数据库加载AI配置
db = SessionLocal()
try:
configs = {c.key: c.value for c in db.query(SystemConfig).all()}
api_base = configs.get('ai_api_base', 'http://192.168.2.17:19007/v1')
api_key = configs.get('ai_api_key', 'xxxx')
model = configs.get('ai_model', 'auto')
ai_service.update_config(api_base, api_key, model)
logger.info(f"AI配置已加载: {api_base}, model={model}")
finally:
db.close()
# 初始化Matrix Bot # 初始化Matrix Bot
await matrix_bot.init_from_config() await matrix_bot.init_from_config()
if matrix_bot.is_running: if matrix_bot.is_running:

View File

@@ -4,10 +4,28 @@ AI服务 - 调用大模型API
import httpx import httpx
from typing import List, Dict, Optional from typing import List, Dict, Optional
import json import json
import logging
logger = logging.getLogger(__name__)
# 默认配置
DEFAULT_API_BASE = "http://192.168.2.17:19007/v1"
DEFAULT_API_KEY = "xxxx"
DEFAULT_MODEL = "auto"
class AIService: class AIService:
def __init__(self, api_base: str = "http://192.168.2.17:19007/v1", api_key: str = "sk-local", model: str = "qwen3.5-4b"): def __init__(self, api_base: str = None, api_key: str = None, model: str = None):
self.api_base = api_base or DEFAULT_API_BASE
self.api_key = api_key or DEFAULT_API_KEY
self.model = model or DEFAULT_MODEL
def update_config(self, api_base: str, api_key: str, model: str):
"""更新配置"""
self.api_base = api_base
self.api_key = api_key
self.model = model
logger.info(f"AI配置已更新: {api_base}, model={model}")
self.api_base = api_base self.api_base = api_base
self.api_key = api_key self.api_key = api_key
self.model = model self.model = model

View File

@@ -19,6 +19,7 @@ class MatrixBot:
self.homeserver: str = "" self.homeserver: str = ""
self.username: str = "" self.username: str = ""
self.password: str = "" self.password: str = ""
self.access_token: str = ""
self.is_running: bool = False self.is_running: bool = False
self.on_message_callback: Optional[Callable] = None self.on_message_callback: Optional[Callable] = None
@@ -30,8 +31,9 @@ class MatrixBot:
self.homeserver = configs.get('matrix_homeserver', 'https://matrix.tphai.com') self.homeserver = configs.get('matrix_homeserver', 'https://matrix.tphai.com')
self.username = configs.get('matrix_username', '') self.username = configs.get('matrix_username', '')
self.password = configs.get('matrix_password', '') self.password = configs.get('matrix_password', '')
self.access_token = configs.get('matrix_access_token', '')
if self.username and self.password: if self.username and (self.password or self.access_token):
await self.connect() await self.connect()
finally: finally:
db.close() db.close()
@@ -44,6 +46,15 @@ class MatrixBot:
try: try:
self.client = AsyncClient(self.homeserver, self.username) self.client = AsyncClient(self.homeserver, self.username)
# 如果有access_token直接使用
if self.access_token:
self.client.access_token = self.access_token
logger.info(f"Matrix连接成功(使用token): {self.username}")
self.is_running = True
return True
# 否则使用密码登录
response = await self.client.login(self.password) response = await self.client.login(self.password)
if isinstance(response, LoginResponse): if isinstance(response, LoginResponse):