部分类型注解修复,优化import顺序,删除无用API文件
This commit is contained in:
@@ -1,26 +0,0 @@
|
||||
from src.chat.heart_flow.heartflow import heartflow
|
||||
from src.chat.heart_flow.sub_heartflow import ChatState
|
||||
from src.common.logger import get_logger
|
||||
|
||||
logger = get_logger("api")
|
||||
|
||||
|
||||
async def get_all_subheartflow_ids() -> list:
|
||||
"""获取所有子心流的ID列表"""
|
||||
all_subheartflows = heartflow.subheartflow_manager.get_all_subheartflows()
|
||||
return [subheartflow.subheartflow_id for subheartflow in all_subheartflows]
|
||||
|
||||
|
||||
async def forced_change_subheartflow_status(subheartflow_id: str, status: ChatState) -> bool:
|
||||
"""强制改变子心流的状态"""
|
||||
subheartflow = await heartflow.get_or_create_subheartflow(subheartflow_id)
|
||||
if subheartflow:
|
||||
return await heartflow.force_change_subheartflow_status(subheartflow_id, status)
|
||||
return False
|
||||
|
||||
|
||||
async def get_all_states():
|
||||
"""获取所有状态"""
|
||||
all_states = await heartflow.api_get_all_states()
|
||||
logger.debug(f"所有状态: {all_states}")
|
||||
return all_states
|
||||
@@ -1,169 +0,0 @@
|
||||
import platform
|
||||
import psutil
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
||||
def get_system_info():
|
||||
"""获取操作系统信息"""
|
||||
return {
|
||||
"system": platform.system(),
|
||||
"release": platform.release(),
|
||||
"version": platform.version(),
|
||||
"machine": platform.machine(),
|
||||
"processor": platform.processor(),
|
||||
}
|
||||
|
||||
|
||||
def get_python_version():
|
||||
"""获取 Python 版本信息"""
|
||||
return sys.version
|
||||
|
||||
|
||||
def get_cpu_usage():
|
||||
"""获取系统总CPU使用率"""
|
||||
return psutil.cpu_percent(interval=1)
|
||||
|
||||
|
||||
def get_process_cpu_usage():
|
||||
"""获取当前进程CPU使用率"""
|
||||
process = psutil.Process(os.getpid())
|
||||
return process.cpu_percent(interval=1)
|
||||
|
||||
|
||||
def get_memory_usage():
|
||||
"""获取系统内存使用情况 (单位 MB)"""
|
||||
mem = psutil.virtual_memory()
|
||||
bytes_to_mb = lambda x: round(x / (1024 * 1024), 2) # noqa
|
||||
return {
|
||||
"total_mb": bytes_to_mb(mem.total),
|
||||
"available_mb": bytes_to_mb(mem.available),
|
||||
"percent": mem.percent,
|
||||
"used_mb": bytes_to_mb(mem.used),
|
||||
"free_mb": bytes_to_mb(mem.free),
|
||||
}
|
||||
|
||||
|
||||
def get_process_memory_usage():
|
||||
"""获取当前进程内存使用情况 (单位 MB)"""
|
||||
process = psutil.Process(os.getpid())
|
||||
mem_info = process.memory_info()
|
||||
bytes_to_mb = lambda x: round(x / (1024 * 1024), 2) # noqa
|
||||
return {
|
||||
"rss_mb": bytes_to_mb(mem_info.rss), # Resident Set Size: 实际使用物理内存
|
||||
"vms_mb": bytes_to_mb(mem_info.vms), # Virtual Memory Size: 虚拟内存大小
|
||||
"percent": process.memory_percent(), # 进程内存使用百分比
|
||||
}
|
||||
|
||||
|
||||
def get_disk_usage(path="/"):
|
||||
"""获取指定路径磁盘使用情况 (单位 GB)"""
|
||||
disk = psutil.disk_usage(path)
|
||||
bytes_to_gb = lambda x: round(x / (1024 * 1024 * 1024), 2) # noqa
|
||||
return {
|
||||
"total_gb": bytes_to_gb(disk.total),
|
||||
"used_gb": bytes_to_gb(disk.used),
|
||||
"free_gb": bytes_to_gb(disk.free),
|
||||
"percent": disk.percent,
|
||||
}
|
||||
|
||||
|
||||
def get_all_basic_info():
|
||||
"""获取所有基本信息并封装返回"""
|
||||
# 对于进程CPU使用率,需要先初始化
|
||||
process = psutil.Process(os.getpid())
|
||||
process.cpu_percent(interval=None) # 初始化调用
|
||||
process_cpu = process.cpu_percent(interval=0.1) # 短暂间隔获取
|
||||
|
||||
return {
|
||||
"system_info": get_system_info(),
|
||||
"python_version": get_python_version(),
|
||||
"cpu_usage_percent": get_cpu_usage(),
|
||||
"process_cpu_usage_percent": process_cpu,
|
||||
"memory_usage": get_memory_usage(),
|
||||
"process_memory_usage": get_process_memory_usage(),
|
||||
"disk_usage_root": get_disk_usage("/"),
|
||||
}
|
||||
|
||||
|
||||
def get_all_basic_info_string() -> str:
|
||||
"""获取所有基本信息并以带解释的字符串形式返回"""
|
||||
info = get_all_basic_info()
|
||||
|
||||
sys_info = info["system_info"]
|
||||
mem_usage = info["memory_usage"]
|
||||
proc_mem_usage = info["process_memory_usage"]
|
||||
disk_usage = info["disk_usage_root"]
|
||||
|
||||
# 对进程内存使用百分比进行格式化,保留两位小数
|
||||
proc_mem_percent = round(proc_mem_usage["percent"], 2)
|
||||
|
||||
output_string = f"""[系统信息]
|
||||
- 操作系统: {sys_info["system"]} (例如: Windows, Linux)
|
||||
- 发行版本: {sys_info["release"]} (例如: 11, Ubuntu 20.04)
|
||||
- 详细版本: {sys_info["version"]}
|
||||
- 硬件架构: {sys_info["machine"]} (例如: AMD64)
|
||||
- 处理器信息: {sys_info["processor"]}
|
||||
|
||||
[Python 环境]
|
||||
- Python 版本: {info["python_version"]}
|
||||
|
||||
[CPU 状态]
|
||||
- 系统总 CPU 使用率: {info["cpu_usage_percent"]}%
|
||||
- 当前进程 CPU 使用率: {info["process_cpu_usage_percent"]}%
|
||||
|
||||
[系统内存使用情况]
|
||||
- 总物理内存: {mem_usage["total_mb"]} MB
|
||||
- 可用物理内存: {mem_usage["available_mb"]} MB
|
||||
- 物理内存使用率: {mem_usage["percent"]}%
|
||||
- 已用物理内存: {mem_usage["used_mb"]} MB
|
||||
- 空闲物理内存: {mem_usage["free_mb"]} MB
|
||||
|
||||
[当前进程内存使用情况]
|
||||
- 实际使用物理内存 (RSS): {proc_mem_usage["rss_mb"]} MB
|
||||
- 占用虚拟内存 (VMS): {proc_mem_usage["vms_mb"]} MB
|
||||
- 进程内存使用率: {proc_mem_percent}%
|
||||
|
||||
[磁盘使用情况 (根目录)]
|
||||
- 总空间: {disk_usage["total_gb"]} GB
|
||||
- 已用空间: {disk_usage["used_gb"]} GB
|
||||
- 可用空间: {disk_usage["free_gb"]} GB
|
||||
- 磁盘使用率: {disk_usage["percent"]}%
|
||||
"""
|
||||
return output_string
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(f"System Info: {get_system_info()}")
|
||||
print(f"Python Version: {get_python_version()}")
|
||||
print(f"CPU Usage: {get_cpu_usage()}%")
|
||||
# 第一次调用 process.cpu_percent() 会返回0.0或一个无意义的值,需要间隔一段时间再调用
|
||||
# 或者在初始化Process对象后,先调用一次cpu_percent(interval=None),然后再调用cpu_percent(interval=1)
|
||||
current_process = psutil.Process(os.getpid())
|
||||
current_process.cpu_percent(interval=None) # 初始化
|
||||
print(f"Process CPU Usage: {current_process.cpu_percent(interval=1)}%") # 实际获取
|
||||
|
||||
memory_usage_info = get_memory_usage()
|
||||
print(
|
||||
f"Memory Usage: Total={memory_usage_info['total_mb']}MB, Used={memory_usage_info['used_mb']}MB, Percent={memory_usage_info['percent']}%"
|
||||
)
|
||||
|
||||
process_memory_info = get_process_memory_usage()
|
||||
print(
|
||||
f"Process Memory Usage: RSS={process_memory_info['rss_mb']}MB, VMS={process_memory_info['vms_mb']}MB, Percent={process_memory_info['percent']}%"
|
||||
)
|
||||
|
||||
disk_usage_info = get_disk_usage("/")
|
||||
print(
|
||||
f"Disk Usage (Root): Total={disk_usage_info['total_gb']}GB, Used={disk_usage_info['used_gb']}GB, Percent={disk_usage_info['percent']}%"
|
||||
)
|
||||
|
||||
print("\n--- All Basic Info (JSON) ---")
|
||||
all_info = get_all_basic_info()
|
||||
import json
|
||||
|
||||
print(json.dumps(all_info, indent=4, ensure_ascii=False))
|
||||
|
||||
print("\n--- All Basic Info (String with Explanations) ---")
|
||||
info_string = get_all_basic_info_string()
|
||||
print(info_string)
|
||||
@@ -1,317 +0,0 @@
|
||||
from typing import List, Optional, Dict, Any
|
||||
import strawberry
|
||||
|
||||
# from packaging.version import Version
|
||||
import os
|
||||
|
||||
ROOT_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
|
||||
|
||||
|
||||
@strawberry.type
|
||||
class APIBotConfig:
|
||||
"""机器人配置类"""
|
||||
|
||||
INNER_VERSION: str # 配置文件内部版本号(toml为字符串)
|
||||
MAI_VERSION: str # 硬编码的版本信息
|
||||
|
||||
# bot
|
||||
BOT_QQ: Optional[int] # 机器人QQ号
|
||||
BOT_NICKNAME: Optional[str] # 机器人昵称
|
||||
BOT_ALIAS_NAMES: List[str] # 机器人别名列表
|
||||
|
||||
# group
|
||||
talk_allowed_groups: List[int] # 允许回复消息的群号列表
|
||||
talk_frequency_down_groups: List[int] # 降低回复频率的群号列表
|
||||
ban_user_id: List[int] # 禁止回复和读取消息的QQ号列表
|
||||
|
||||
# personality
|
||||
personality_core: str # 人格核心特点描述
|
||||
personality_sides: List[str] # 人格细节描述列表
|
||||
|
||||
# identity
|
||||
identity_detail: List[str] # 身份特点列表
|
||||
age: int # 年龄(岁)
|
||||
gender: str # 性别
|
||||
appearance: str # 外貌特征描述
|
||||
|
||||
# platforms
|
||||
platforms: Dict[str, str] # 平台信息
|
||||
|
||||
# chat
|
||||
allow_focus_mode: bool # 是否允许专注聊天状态
|
||||
base_normal_chat_num: int # 最多允许多少个群进行普通聊天
|
||||
base_focused_chat_num: int # 最多允许多少个群进行专注聊天
|
||||
observation_context_size: int # 观察到的最长上下文大小
|
||||
message_buffer: bool # 是否启用消息缓冲
|
||||
ban_words: List[str] # 禁止词列表
|
||||
ban_msgs_regex: List[str] # 禁止消息的正则表达式列表
|
||||
|
||||
# normal_chat
|
||||
model_reasoning_probability: float # 推理模型概率
|
||||
model_normal_probability: float # 普通模型概率
|
||||
emoji_chance: float # 表情符号出现概率
|
||||
thinking_timeout: int # 思考超时时间
|
||||
willing_mode: str # 意愿模式
|
||||
response_interested_rate_amplifier: float # 回复兴趣率放大器
|
||||
emoji_response_penalty: float # 表情回复惩罚
|
||||
mentioned_bot_inevitable_reply: bool # 提及 bot 必然回复
|
||||
at_bot_inevitable_reply: bool # @bot 必然回复
|
||||
|
||||
# focus_chat
|
||||
reply_trigger_threshold: float # 回复触发阈值
|
||||
default_decay_rate_per_second: float # 默认每秒衰减率
|
||||
|
||||
# compressed
|
||||
compressed_length: int # 压缩长度
|
||||
compress_length_limit: int # 压缩长度限制
|
||||
|
||||
# emoji
|
||||
max_emoji_num: int # 最大表情符号数量
|
||||
max_reach_deletion: bool # 达到最大数量时是否删除
|
||||
check_interval: int # 检查表情包的时间间隔(分钟)
|
||||
save_emoji: bool # 是否保存表情包
|
||||
steal_emoji: bool # 是否偷取表情包
|
||||
enable_check: bool # 是否启用表情包过滤
|
||||
check_prompt: str # 表情包过滤要求
|
||||
|
||||
# memory
|
||||
build_memory_interval: int # 记忆构建间隔
|
||||
build_memory_distribution: List[float] # 记忆构建分布
|
||||
build_memory_sample_num: int # 采样数量
|
||||
build_memory_sample_length: int # 采样长度
|
||||
memory_compress_rate: float # 记忆压缩率
|
||||
forget_memory_interval: int # 记忆遗忘间隔
|
||||
memory_forget_time: int # 记忆遗忘时间(小时)
|
||||
memory_forget_percentage: float # 记忆遗忘比例
|
||||
consolidate_memory_interval: int # 记忆整合间隔
|
||||
consolidation_similarity_threshold: float # 相似度阈值
|
||||
consolidation_check_percentage: float # 检查节点比例
|
||||
memory_ban_words: List[str] # 记忆禁止词列表
|
||||
|
||||
# mood
|
||||
mood_update_interval: float # 情绪更新间隔
|
||||
mood_decay_rate: float # 情绪衰减率
|
||||
mood_intensity_factor: float # 情绪强度因子
|
||||
|
||||
# keywords_reaction
|
||||
keywords_reaction_enable: bool # 是否启用关键词反应
|
||||
keywords_reaction_rules: List[Dict[str, Any]] # 关键词反应规则
|
||||
|
||||
# chinese_typo
|
||||
chinese_typo_enable: bool # 是否启用中文错别字
|
||||
chinese_typo_error_rate: float # 中文错别字错误率
|
||||
chinese_typo_min_freq: int # 中文错别字最小频率
|
||||
chinese_typo_tone_error_rate: float # 中文错别字声调错误率
|
||||
chinese_typo_word_replace_rate: float # 中文错别字单词替换率
|
||||
|
||||
# response_splitter
|
||||
enable_response_splitter: bool # 是否启用回复分割器
|
||||
response_max_length: int # 回复最大长度
|
||||
response_max_sentence_num: int # 回复最大句子数
|
||||
enable_kaomoji_protection: bool # 是否启用颜文字保护
|
||||
|
||||
model_max_output_length: int # 模型最大输出长度
|
||||
|
||||
# remote
|
||||
remote_enable: bool # 是否启用远程功能
|
||||
|
||||
# experimental
|
||||
enable_friend_chat: bool # 是否启用好友聊天
|
||||
talk_allowed_private: List[int] # 允许私聊的QQ号列表
|
||||
pfc_chatting: bool # 是否启用PFC聊天
|
||||
|
||||
# 模型配置
|
||||
llm_reasoning: Dict[str, Any] # 推理模型配置
|
||||
llm_normal: Dict[str, Any] # 普通模型配置
|
||||
llm_topic_judge: Dict[str, Any] # 主题判断模型配置
|
||||
summary: Dict[str, Any] # 总结模型配置
|
||||
vlm: Dict[str, Any] # VLM模型配置
|
||||
llm_heartflow: Dict[str, Any] # 心流模型配置
|
||||
llm_observation: Dict[str, Any] # 观察模型配置
|
||||
llm_sub_heartflow: Dict[str, Any] # 子心流模型配置
|
||||
llm_plan: Optional[Dict[str, Any]] # 计划模型配置
|
||||
embedding: Dict[str, Any] # 嵌入模型配置
|
||||
llm_PFC_action_planner: Optional[Dict[str, Any]] # PFC行动计划模型配置
|
||||
llm_PFC_chat: Optional[Dict[str, Any]] # PFC聊天模型配置
|
||||
llm_PFC_reply_checker: Optional[Dict[str, Any]] # PFC回复检查模型配置
|
||||
llm_tool_use: Optional[Dict[str, Any]] # 工具使用模型配置
|
||||
|
||||
api_urls: Optional[Dict[str, str]] # API地址配置
|
||||
|
||||
@staticmethod
|
||||
def validate_config(config: dict):
|
||||
"""
|
||||
校验传入的 toml 配置字典是否合法。
|
||||
:param config: toml库load后的配置字典
|
||||
:raises: ValueError, KeyError, TypeError
|
||||
"""
|
||||
# 检查主层级
|
||||
required_sections = [
|
||||
"inner",
|
||||
"bot",
|
||||
"groups",
|
||||
"personality",
|
||||
"identity",
|
||||
"platforms",
|
||||
"chat",
|
||||
"normal_chat",
|
||||
"focus_chat",
|
||||
"emoji",
|
||||
"memory",
|
||||
"mood",
|
||||
"keywords_reaction",
|
||||
"chinese_typo",
|
||||
"response_splitter",
|
||||
"remote",
|
||||
"experimental",
|
||||
"model",
|
||||
]
|
||||
for section in required_sections:
|
||||
if section not in config:
|
||||
raise KeyError(f"缺少配置段: [{section}]")
|
||||
|
||||
# 检查部分关键字段
|
||||
if "version" not in config["inner"]:
|
||||
raise KeyError("缺少 inner.version 字段")
|
||||
if not isinstance(config["inner"]["version"], str):
|
||||
raise TypeError("inner.version 必须为字符串")
|
||||
|
||||
if "qq" not in config["bot"]:
|
||||
raise KeyError("缺少 bot.qq 字段")
|
||||
if not isinstance(config["bot"]["qq"], int):
|
||||
raise TypeError("bot.qq 必须为整数")
|
||||
|
||||
if "personality_core" not in config["personality"]:
|
||||
raise KeyError("缺少 personality.personality_core 字段")
|
||||
if not isinstance(config["personality"]["personality_core"], str):
|
||||
raise TypeError("personality.personality_core 必须为字符串")
|
||||
|
||||
if "identity_detail" not in config["identity"]:
|
||||
raise KeyError("缺少 identity.identity_detail 字段")
|
||||
if not isinstance(config["identity"]["identity_detail"], list):
|
||||
raise TypeError("identity.identity_detail 必须为列表")
|
||||
|
||||
# 可继续添加更多字段的类型和值检查
|
||||
# ...
|
||||
|
||||
# 检查模型配置
|
||||
model_keys = [
|
||||
"llm_reasoning",
|
||||
"llm_normal",
|
||||
"llm_topic_judge",
|
||||
"summary",
|
||||
"vlm",
|
||||
"llm_heartflow",
|
||||
"llm_observation",
|
||||
"llm_sub_heartflow",
|
||||
"embedding",
|
||||
]
|
||||
if "model" not in config:
|
||||
raise KeyError("缺少 [model] 配置段")
|
||||
for key in model_keys:
|
||||
if key not in config["model"]:
|
||||
raise KeyError(f"缺少 model.{key} 配置")
|
||||
|
||||
# 检查通过
|
||||
return True
|
||||
|
||||
|
||||
@strawberry.type
|
||||
class APIEnvConfig:
|
||||
"""环境变量配置"""
|
||||
|
||||
HOST: str # 服务主机地址
|
||||
PORT: int # 服务端口
|
||||
|
||||
PLUGINS: List[str] # 插件列表
|
||||
|
||||
MONGODB_HOST: str # MongoDB 主机地址
|
||||
MONGODB_PORT: int # MongoDB 端口
|
||||
DATABASE_NAME: str # 数据库名称
|
||||
|
||||
CHAT_ANY_WHERE_BASE_URL: str # ChatAnywhere 基础URL
|
||||
SILICONFLOW_BASE_URL: str # SiliconFlow 基础URL
|
||||
DEEP_SEEK_BASE_URL: str # DeepSeek 基础URL
|
||||
|
||||
DEEP_SEEK_KEY: Optional[str] # DeepSeek API Key
|
||||
CHAT_ANY_WHERE_KEY: Optional[str] # ChatAnywhere API Key
|
||||
SILICONFLOW_KEY: Optional[str] # SiliconFlow API Key
|
||||
|
||||
SIMPLE_OUTPUT: Optional[bool] # 是否简化输出
|
||||
CONSOLE_LOG_LEVEL: Optional[str] # 控制台日志等级
|
||||
FILE_LOG_LEVEL: Optional[str] # 文件日志等级
|
||||
DEFAULT_CONSOLE_LOG_LEVEL: Optional[str] # 默认控制台日志等级
|
||||
DEFAULT_FILE_LOG_LEVEL: Optional[str] # 默认文件日志等级
|
||||
|
||||
@strawberry.field
|
||||
def get_env(self) -> str:
|
||||
return "env"
|
||||
|
||||
@staticmethod
|
||||
def validate_config(config: dict):
|
||||
"""
|
||||
校验环境变量配置字典是否合法。
|
||||
:param config: 环境变量配置字典
|
||||
:raises: KeyError, TypeError
|
||||
"""
|
||||
required_fields = [
|
||||
"HOST",
|
||||
"PORT",
|
||||
"PLUGINS",
|
||||
"MONGODB_HOST",
|
||||
"MONGODB_PORT",
|
||||
"DATABASE_NAME",
|
||||
"CHAT_ANY_WHERE_BASE_URL",
|
||||
"SILICONFLOW_BASE_URL",
|
||||
"DEEP_SEEK_BASE_URL",
|
||||
]
|
||||
for field in required_fields:
|
||||
if field not in config:
|
||||
raise KeyError(f"缺少环境变量配置字段: {field}")
|
||||
|
||||
if not isinstance(config["HOST"], str):
|
||||
raise TypeError("HOST 必须为字符串")
|
||||
if not isinstance(config["PORT"], int):
|
||||
raise TypeError("PORT 必须为整数")
|
||||
if not isinstance(config["PLUGINS"], list):
|
||||
raise TypeError("PLUGINS 必须为列表")
|
||||
if not isinstance(config["MONGODB_HOST"], str):
|
||||
raise TypeError("MONGODB_HOST 必须为字符串")
|
||||
if not isinstance(config["MONGODB_PORT"], int):
|
||||
raise TypeError("MONGODB_PORT 必须为整数")
|
||||
if not isinstance(config["DATABASE_NAME"], str):
|
||||
raise TypeError("DATABASE_NAME 必须为字符串")
|
||||
if not isinstance(config["CHAT_ANY_WHERE_BASE_URL"], str):
|
||||
raise TypeError("CHAT_ANY_WHERE_BASE_URL 必须为字符串")
|
||||
if not isinstance(config["SILICONFLOW_BASE_URL"], str):
|
||||
raise TypeError("SILICONFLOW_BASE_URL 必须为字符串")
|
||||
if not isinstance(config["DEEP_SEEK_BASE_URL"], str):
|
||||
raise TypeError("DEEP_SEEK_BASE_URL 必须为字符串")
|
||||
|
||||
# 可选字段类型检查
|
||||
optional_str_fields = [
|
||||
"DEEP_SEEK_KEY",
|
||||
"CHAT_ANY_WHERE_KEY",
|
||||
"SILICONFLOW_KEY",
|
||||
"CONSOLE_LOG_LEVEL",
|
||||
"FILE_LOG_LEVEL",
|
||||
"DEFAULT_CONSOLE_LOG_LEVEL",
|
||||
"DEFAULT_FILE_LOG_LEVEL",
|
||||
]
|
||||
for field in optional_str_fields:
|
||||
if field in config and config[field] is not None and not isinstance(config[field], str):
|
||||
raise TypeError(f"{field} 必须为字符串或None")
|
||||
|
||||
if (
|
||||
"SIMPLE_OUTPUT" in config
|
||||
and config["SIMPLE_OUTPUT"] is not None
|
||||
and not isinstance(config["SIMPLE_OUTPUT"], bool)
|
||||
):
|
||||
raise TypeError("SIMPLE_OUTPUT 必须为布尔值或None")
|
||||
|
||||
# 检查通过
|
||||
return True
|
||||
|
||||
|
||||
print("当前路径:")
|
||||
print(ROOT_PATH)
|
||||
@@ -1,22 +0,0 @@
|
||||
import strawberry
|
||||
|
||||
from fastapi import FastAPI
|
||||
from strawberry.fastapi import GraphQLRouter
|
||||
|
||||
from src.common.server import get_global_server
|
||||
|
||||
|
||||
@strawberry.type
|
||||
class Query:
|
||||
@strawberry.field
|
||||
def hello(self) -> str:
|
||||
return "Hello World"
|
||||
|
||||
|
||||
schema = strawberry.Schema(Query)
|
||||
|
||||
graphql_app = GraphQLRouter(schema)
|
||||
|
||||
fast_api_app: FastAPI = get_global_server().get_app()
|
||||
|
||||
fast_api_app.include_router(graphql_app, prefix="/graphql")
|
||||
@@ -1 +0,0 @@
|
||||
pass
|
||||
112
src/api/main.py
112
src/api/main.py
@@ -1,112 +0,0 @@
|
||||
from fastapi import APIRouter
|
||||
from strawberry.fastapi import GraphQLRouter
|
||||
import os
|
||||
import sys
|
||||
|
||||
# from src.chat.heart_flow.heartflow import heartflow
|
||||
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")))
|
||||
# from src.config.config import BotConfig
|
||||
from src.common.logger import get_logger
|
||||
from src.api.reload_config import reload_config as reload_config_func
|
||||
from src.common.server import get_global_server
|
||||
from src.api.apiforgui import (
|
||||
get_all_subheartflow_ids,
|
||||
forced_change_subheartflow_status,
|
||||
get_subheartflow_cycle_info,
|
||||
get_all_states,
|
||||
)
|
||||
from src.chat.heart_flow.sub_heartflow import ChatState
|
||||
from src.api.basic_info_api import get_all_basic_info # 新增导入
|
||||
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
logger = get_logger("api")
|
||||
|
||||
logger.info("麦麦API服务器已启动")
|
||||
graphql_router = GraphQLRouter(schema=None, path="/") # Replace `None` with your actual schema
|
||||
|
||||
router.include_router(graphql_router, prefix="/graphql", tags=["GraphQL"])
|
||||
|
||||
|
||||
@router.post("/config/reload")
|
||||
async def reload_config():
|
||||
return await reload_config_func()
|
||||
|
||||
|
||||
@router.get("/gui/subheartflow/get/all")
|
||||
async def get_subheartflow_ids():
|
||||
"""获取所有子心流的ID列表"""
|
||||
return await get_all_subheartflow_ids()
|
||||
|
||||
|
||||
@router.post("/gui/subheartflow/forced_change_status")
|
||||
async def forced_change_subheartflow_status_api(subheartflow_id: str, status: ChatState): # noqa
|
||||
"""强制改变子心流的状态"""
|
||||
# 参数检查
|
||||
if not isinstance(status, ChatState):
|
||||
logger.warning(f"无效的状态参数: {status}")
|
||||
return {"status": "failed", "reason": "invalid status"}
|
||||
logger.info(f"尝试将子心流 {subheartflow_id} 状态更改为 {status.value}")
|
||||
success = await forced_change_subheartflow_status(subheartflow_id, status)
|
||||
if success:
|
||||
logger.info(f"子心流 {subheartflow_id} 状态更改为 {status.value} 成功")
|
||||
return {"status": "success"}
|
||||
else:
|
||||
logger.error(f"子心流 {subheartflow_id} 状态更改为 {status.value} 失败")
|
||||
return {"status": "failed"}
|
||||
|
||||
|
||||
@router.get("/stop")
|
||||
async def force_stop_maibot():
|
||||
"""强制停止MAI Bot"""
|
||||
from bot import request_shutdown
|
||||
|
||||
success = await request_shutdown()
|
||||
if success:
|
||||
logger.info("MAI Bot已强制停止")
|
||||
return {"status": "success"}
|
||||
else:
|
||||
logger.error("MAI Bot强制停止失败")
|
||||
return {"status": "failed"}
|
||||
|
||||
|
||||
@router.get("/gui/subheartflow/cycleinfo")
|
||||
async def get_subheartflow_cycle_info_api(subheartflow_id: str, history_len: int):
|
||||
"""获取子心流的循环信息"""
|
||||
cycle_info = await get_subheartflow_cycle_info(subheartflow_id, history_len)
|
||||
if cycle_info:
|
||||
return {"status": "success", "data": cycle_info}
|
||||
else:
|
||||
logger.warning(f"子心流 {subheartflow_id} 循环信息未找到")
|
||||
return {"status": "failed", "reason": "subheartflow not found"}
|
||||
|
||||
|
||||
@router.get("/gui/get_all_states")
|
||||
async def get_all_states_api():
|
||||
"""获取所有状态"""
|
||||
all_states = await get_all_states()
|
||||
if all_states:
|
||||
return {"status": "success", "data": all_states}
|
||||
else:
|
||||
logger.warning("获取所有状态失败")
|
||||
return {"status": "failed", "reason": "failed to get all states"}
|
||||
|
||||
|
||||
@router.get("/info")
|
||||
async def get_system_basic_info():
|
||||
"""获取系统基本信息"""
|
||||
logger.info("请求系统基本信息")
|
||||
try:
|
||||
info = get_all_basic_info()
|
||||
return {"status": "success", "data": info}
|
||||
except Exception as e:
|
||||
logger.error(f"获取系统基本信息失败: {e}")
|
||||
return {"status": "failed", "reason": str(e)}
|
||||
|
||||
|
||||
def start_api_server():
|
||||
"""启动API服务器"""
|
||||
get_global_server().register_router(router, prefix="/api/v1")
|
||||
# pass
|
||||
@@ -1,24 +0,0 @@
|
||||
from fastapi import HTTPException
|
||||
from rich.traceback import install
|
||||
from src.config.config import get_config_dir, load_config
|
||||
from src.common.logger import get_logger
|
||||
import os
|
||||
|
||||
install(extra_lines=3)
|
||||
|
||||
logger = get_logger("api")
|
||||
|
||||
|
||||
async def reload_config():
|
||||
try:
|
||||
from src.config import config as config_module
|
||||
|
||||
logger.debug("正在重载配置文件...")
|
||||
bot_config_path = os.path.join(get_config_dir(), "bot_config.toml")
|
||||
config_module.global_config = load_config(config_path=bot_config_path)
|
||||
logger.debug("配置文件重载成功")
|
||||
return {"status": "reloaded"}
|
||||
except FileNotFoundError as e:
|
||||
raise HTTPException(status_code=404, detail=str(e)) from e
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"重载配置时发生错误: {str(e)}") from e
|
||||
Reference in New Issue
Block a user