Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fd583132d7 |
BIN
ai_chat.db
BIN
ai_chat.db
Binary file not shown.
40
init_config.py
Normal file
40
init_config.py
Normal 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()
|
||||||
111
logs/ai-chat.log
111
logs/ai-chat.log
@@ -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
24
main.py
@@ -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:
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -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
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
Reference in New Issue
Block a user