76a67e8237
将分散的 config.yml、workflow.yaml、sandbox.yaml 加载逻辑统一到 AppConfig 模型, 启动时一次性校验,失败则 fast-fail。sandbox.py 改为从统一配置取值,消除重复加载。 同时修复 onebot 测试并新增14个统一配置测试(总测试 285→300)。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
131 lines
4.7 KiB
Python
131 lines
4.7 KiB
Python
import os
|
|
import secrets
|
|
import sys
|
|
|
|
_INSECURE_SECRETS = {"secret", "114514", "changethiskey12345"}
|
|
_secret_key = os.getenv("SECRET_KEY")
|
|
_is_dev = os.getenv("KILOSTAR_ENV", "production").lower() in ("dev", "development")
|
|
|
|
if not _secret_key or _secret_key in _INSECURE_SECRETS:
|
|
if _is_dev:
|
|
_secret_key = secrets.token_urlsafe(32)
|
|
os.environ["SECRET_KEY"] = _secret_key
|
|
print(
|
|
"⚠️ [开发模式] 未提供有效的 SECRET_KEY,已生成临时随机密钥(重启后失效)。"
|
|
)
|
|
else:
|
|
print(
|
|
"❌ [致命错误] 未提供有效的 SECRET_KEY 或使用了不安全的默认值。\n"
|
|
" 请设置环境变量 SECRET_KEY 为一个高熵的随机字符串。\n"
|
|
" 可使用: python -c \"import secrets; print(secrets.token_urlsafe(32))\"\n"
|
|
" 若为开发环境,请设置 KILOSTAR_ENV=dev 以允许自动生成临时密钥。"
|
|
)
|
|
sys.exit(1)
|
|
|
|
from kilostar.utils.config_loader import get_app_config
|
|
|
|
try:
|
|
_app_cfg = get_app_config()
|
|
except Exception as e:
|
|
print(f"❌ [致命错误] 配置文件校验失败:{e}")
|
|
sys.exit(1)
|
|
|
|
import asyncio
|
|
import ray
|
|
from ray import serve
|
|
|
|
from kilostar.worker_cluster import WorkerCluster
|
|
from kilostar.utils.banner import print_banner
|
|
from kilostar.core.postgres_database import PostgresDatabase
|
|
from kilostar.core.global_state_machine import GlobalStateMachine
|
|
from kilostar.core.global_workflow_manager import GlobalWorkflowManager
|
|
from kilostar.core.individual.regulatory_node import RegulatoryNode
|
|
from kilostar.core.individual.consciousness_node import ConsciousnessNode
|
|
from kilostar.core.individual.control_node import ControlNode
|
|
from kilostar.api import KiloStarGateway
|
|
|
|
|
|
async def start_system():
|
|
env_vars = {
|
|
"POSTGRES_USER": os.getenv("POSTGRES_USER", "postgres"),
|
|
"POSTGRES_PASSWORD": os.getenv("POSTGRES_PASSWORD", ""),
|
|
"POSTGRES_HOST": os.getenv("POSTGRES_HOST", "db"),
|
|
"POSTGRES_PORT": os.getenv("POSTGRES_PORT", "5432"),
|
|
"POSTGRES_DB": os.getenv("POSTGRES_DB", "postgres"),
|
|
"SECRET_KEY": os.getenv("SECRET_KEY"),
|
|
}
|
|
|
|
ray.init(
|
|
ignore_reinit_error=True,
|
|
namespace="kilostar",
|
|
dashboard_host="0.0.0.0",
|
|
dashboard_port=8265,
|
|
runtime_env={"env_vars": env_vars},
|
|
)
|
|
|
|
# 2. 启动数据库组件
|
|
postgres_database = PostgresDatabase.options(name="postgres_database").remote()
|
|
await postgres_database.init_db.remote()
|
|
|
|
global_state_machine = GlobalStateMachine.options(
|
|
name="global_state_machine", namespace="kilostar", lifetime="detached"
|
|
).remote(postgres_database)
|
|
|
|
print("正在等待 GlobalStateMachine 初始化并加载注册表...")
|
|
try:
|
|
# 强制执行初始化方法并阻塞等待结果。
|
|
# 如果 __init__ 或 init_state_machine 中有任何报错,会立刻在这里抛出!
|
|
await global_state_machine.init_state_machine.remote()
|
|
print("GlobalStateMachine 初始化成功!")
|
|
except Exception as e:
|
|
print(f"\n[致命错误] GlobalStateMachine 启动失败!真实报错如下:\n{e}\n")
|
|
return
|
|
|
|
global_workflow_manager = GlobalWorkflowManager.options(
|
|
name="global_workflow_manager", namespace="kilostar", lifetime="detached"
|
|
).remote()
|
|
|
|
# 4. 启动核心节点
|
|
regulatory_node = RegulatoryNode.options(name="regulatory_node").remote()
|
|
consciousness_node = ConsciousnessNode.options(name="consciousness_node").remote()
|
|
control_node = ControlNode.options(name="control_node").remote()
|
|
|
|
try:
|
|
WorkerCluster.options(
|
|
name="worker_cluster",
|
|
lifetime="detached", # 保证它在后台一直运行
|
|
).remote()
|
|
print("✅ WorkerCluster 已成功启动并注册!")
|
|
except ValueError:
|
|
print("WorkerCluster 已经存在。")
|
|
|
|
# 工作流以一次性 ray task 形式由 ConsciousnessNode 直接 fire,不再需要常驻 engine actor。
|
|
|
|
print("正在等待 GlobalWorkflowManager 初始化与恢复工作流...")
|
|
try:
|
|
await global_workflow_manager.init_manager.remote()
|
|
print("GlobalWorkflowManager 初始化成功!")
|
|
except Exception as e:
|
|
print(f"\n[致命错误] GlobalWorkflowManager 启动失败!真实报错如下:\n{e}\n")
|
|
return
|
|
|
|
# 6. 启动 FastAPI 网关 (使用 Ray Serve)
|
|
serve.start(http_options={"host": "0.0.0.0", "port": 8000})
|
|
serve.run(KiloStarGateway.bind())
|
|
|
|
# 挂起主线程以保持系统运行
|
|
while True:
|
|
await asyncio.sleep(3600)
|
|
|
|
|
|
def main():
|
|
print_banner()
|
|
try:
|
|
asyncio.run(start_system())
|
|
except KeyboardInterrupt:
|
|
print("系统已退出。")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|