1"""

2 AgentOS v0.80 统一配置系统。

3 v0.80新增: BenchmarkCfg。

4 v0.70基线: PluginsCfg, GeminiCfg, ContractsCfg, OrchestratorCfg, ScorerCfg。

5 v0.60基线: GuardrailsCfg, RateLimitCfg, StateMachineCfg, ResilienceCfg。

6"""

7

8 from __future__ import annotations

9

10 import os

11 from dataclasses import dataclass, field, fields

12

13

14@dataclass

15 class ModelConfig:

16 """LLM 模型配置。"""

17

18 default: str = "deepseek-v3.1"

19 fallback_chain: list[str] = field(default_factory=lambda: ["kimi-k2.6", "qwen-3.6-plus"])

20 auto_select: bool = True

21 max_retries: int = 3

22 request_timeout: int = 120

23 api_base: str = ""

24 api_key: str = ""

25

26

27@dataclass

28 class LoopCfg:

29 """Agent 主循环配置。"""

30

31 max_iterations: int = 100

32 max_retries_per_step: int = 2

33 step_timeout_seconds: int = 120

34 enable_streaming: bool = False

35 enable_checkpoints: bool = True

36 checkpoint_interval: int = 5

37

38

39@dataclass

40 class MemoryCfg:

41 """记忆系统配置。"""

42 short_term_capacity: int = 50

43 long_term_enabled: bool = True

44 long_term_max_entries: int = 100000

45 vector_dim: int = 1536

46 vector_backend: str = "faiss"

47 vector_persist_dir: str = "./vector_data"

48 compression_interval: int = 20

49

50

51@dataclass

52 class SecurityCfg:

53 """安全策略配置。"""

54 sandbox_enabled: bool = False

55 sandbox_image: str = "agentos-sandbox:latest"

56 max_file_size_mb: int = 100

57 allowed_paths: list[str] = field(default_factory=lambda: [".", "/tmp/agentos"])

58

59

60@dataclass

61 class ObservabilityCfg:

62 """可观测性配置。"""

63 tracer_enabled: bool = True

64 tracer_backend: str = "console"

65 langsmith_api_key: str = ""

66 log_level: str = "INFO"

67

68

69@dataclass

70 class MCPServersCfg:

71 """MCP 服务器列表配置。"""

72 servers: list[dict] = field(default_factory=list)

73

74

75@dataclass

76 class ReflectionCfg:

77 """反思循环配置。"""

78 enabled: bool = True

79 frequency: int = 3

80 max_loops: int = 3

81 enable_self_critique: bool = True

82

83

84@dataclass

85 class CostCfg:

86 """成本控制配置。"""

87 enabled: bool = True

88 budget_limit: float = 0.0

89 warn_threshold: float = 0.8

90

91

92@dataclass

93 class FeedbackCfg:

94 """反馈回路配置。"""

95 enabled: bool = True

96 human_in_the_loop: bool = False

97 approval_trigger: str = "high_risk"

98 storage_path: str = "./feedback_data.jsonl"

99

100

101@dataclass

102 class APICfg:

103 """API 服务配置。"""

104 enabled: bool = True

105 host: str = "0.0.0.0"

106 port: int = 8080

107 cors_origins: list[str] = field(default_factory=lambda: ["*"])

108

109

110@dataclass

111 class SwarmCfg:

112 """Swarm 多 Agent 协作配置。"""

113 enabled: bool = True

114 topology: str = "sequential" # sequential|parallel|debate|hierarchical|broadcast

115 max_parallel_agents: int = 4

116 enable_communication: bool = True

117 enable_blackboard: bool = True

118

119

120@dataclass

121 class QueueCfg:

122 """任务队列配置。"""

123 enabled: bool = False

124 backend: str = "memory" # memory|redis

125 redis_url: str = "redis://localhost:6379/0"

126 concurrency: int = 4

127 max_retries: int = 3

128 retry_backoff: str = "exponential" # exponential|linear|fixed

129

130

131@dataclass

132 class CacheCfg:

133 """语义缓存配置。"""

134 enabled: bool = True

135 lru_size: int = 500

136 semantic_enabled: bool = True

137 similarity_threshold: float = 0.92

138 default_ttl: float = 3600

139

140

141@dataclass

142 class ExperimentCfg:

143 """A/B 实验配置。"""

144 enabled: bool = False

145 auto_evaluator: str = "llm_judge"

146 trials_per_variant: int = 3

147 shuffle_trials: bool = True

148

149

150@dataclass

151 class MultimodalCfg:

152 """多模态处理配置。"""

153 enabled: bool = True

154 max_image_size: int = 2048

155 whisper_model: str = "base"

156 document_parser: str = "auto" # auto|PyPDF2|unstructured

157

158

159@dataclass

160 class MCPServerCfg:

161 """MCP 服务端配置。"""

162 enabled: bool = False

163 transport: str = "stdio"

164 host: str = "0.0.0.0"

165 port: int = 9000

166 server_name: str = "AgentOS-MCP-Server"

167

168

169@dataclass

170 class GuardrailsCfg:

171 """安全护栏配置。"""

172 enabled: bool = True

173 block_pii: bool = True

174 block_injection: bool = True

175 moderation_threshold: str = "medium"

176

177

178@dataclass

179 class RateLimitCfg:

180 """限流配置。"""

181 enabled: bool = True

182 strategy: str = "token_bucket"

183 max_requests: int = 60

184 per_seconds: float = 60.0

185 burst_size: int = 10

186 max_concurrent: int = 5

187 queue_timeout: float = 30.0

188

189

190@dataclass

191 class StateMachineCfg:

192 """状态机配置。"""

193 max_thinking_time: float = 300.0

194 max_acting_time: float = 120.0

195 max_observing_time: float = 60.0

196 max_total_time: float = 3600.0

197 auto_recover: bool = True

198

199

200@dataclass

201 class ResilienceCfg:

202 """弹性容错配置。"""

203 retry_max: int = 3

204 retry_base_delay: float = 1.0

205 retry_max_delay: float = 30.0

206 circuit_failure_threshold: int = 5

207 circuit_timeout: float = 30.0

208

209

210# ── v0.70 新增配置段 ────────────────────────────────────────────────────

211

212@dataclass

213 class PluginsCfg:

214 """插件系统配置。"""

215 enabled: bool = True

216 plugins_dir: str = "./plugins"

217 auto_discover: bool = True

218 hot_reload: bool = False

219 max_plugins: int = 50

220

221

222@dataclass

223 class GeminiCfg:

224 """Gemini 模型配置。"""

225 enabled: bool = True

226 api_key: str = ""

227 default_model: str = "gemini-2.5-flash"

228 vision_enabled: bool = True

229 max_image_size: int = 4096

230 safety_threshold: str = "BLOCK_ONLY_HIGH"

231

232

233@dataclass

234 class ContractsCfg:

235 """能力契约配置。"""

236 enabled: bool = True

237 auto_discover: bool = True

238 heartbeat_interval: float = 30.0

239 stale_timeout: float = 300.0

240 max_registered: int = 100

241

242

243@dataclass

244 class OrchestratorCfg:

245 """编排器配置。"""

246 enabled: bool = True

247 global_timeout: float = 300.0

248 default_retries: int = 3

249 max_concurrent_tools: int = 10

250 dag_export_dir: str = "./dags"

251

252

253@dataclass

254 class ScorerCfg:

255 """评分器配置。"""

256 enabled: bool = True

257 strategy: str = "composite"

258 pass_threshold: float = 0.6

259 enable_semantic: bool = True

260

261

262# ── v0.80 新增配置段 ────────────────────────────────────────────────────

263

264@dataclass

265 class BenchmarkCfg:

266 """性能基准配置。"""

267 enabled: bool = True

268 output_dir: str = "./benchmarks"

269 warmup_iterations: int = 3

270 measure_iterations: int = 10

271 concurrency_levels: list[int] = field(default_factory=lambda: [1, 4, 8])

272 timeout_per_run: float = 30.0

273

274

275@dataclass

276 class HealthCfg:

277 """健康检查配置。"""

278 readiness_enabled: bool = True

279 liveness_enabled: bool = True

280 disk_threshold_mb: int = 100

281 memory_threshold_mb: int = 50

282

283

284@dataclass

285 class AuditCfg:

286 """安全审计配置。"""

287 enabled: bool = False

288 severity_threshold: str = "medium"

289 report_format: str = "markdown"

290 auto_scan_on_startup: bool = False

291

292

293@dataclass

294 class DeployCfg:

295 """部署配置。"""

296 base_image: str = "python:3.11-slim"

297 port: int = 8000

298 workers: int = 4

299 healthcheck_endpoint: str = "/health"

300

301

302@dataclass

303 class MiddlewareCfg:

304 """中间件配置。"""

305 cors_enabled: bool = True

306 cors_origins: list = field(default_factory=lambda: ["*"])

307 auth_enabled: bool = False

308 request_logging: bool = True

309 rate_limit_rpm: int = 0

310

311

312@dataclass

313 class AgentOSConfig:

314 """AgentOS v0.90 总配置。"""

315

316 model: ModelConfig = field(default_factory=ModelConfig)

317 loop: LoopCfg = field(default_factory=LoopCfg)

318 memory: MemoryCfg = field(default_factory=MemoryCfg)

319 security: SecurityCfg = field(default_factory=SecurityCfg)

320 observability: ObservabilityCfg = field(default_factory=ObservabilityCfg)

321 mcp: MCPServersCfg = field(default_factory=MCPServersCfg)

322 reflection: ReflectionCfg = field(default_factory=ReflectionCfg)

323 cost: CostCfg = field(default_factory=CostCfg)

324 feedback: FeedbackCfg = field(default_factory=FeedbackCfg)

325 api: APICfg = field(default_factory=APICfg)

326 swarm: SwarmCfg = field(default_factory=SwarmCfg)

327 queue: QueueCfg = field(default_factory=QueueCfg)

328 cache: CacheCfg = field(default_factory=CacheCfg)

329 experiment: ExperimentCfg = field(default_factory=ExperimentCfg)

330 multimodal: MultimodalCfg = field(default_factory=MultimodalCfg)

331 mcp_server: MCPServerCfg = field(default_factory=MCPServerCfg)

332 guardrails: GuardrailsCfg = field(default_factory=GuardrailsCfg)

333 rate_limit: RateLimitCfg = field(default_factory=RateLimitCfg)

334 state_machine: StateMachineCfg = field(default_factory=StateMachineCfg)

335 resilience: ResilienceCfg = field(default_factory=ResilienceCfg)

336 plugins: PluginsCfg = field(default_factory=PluginsCfg)

337 gemini: GeminiCfg = field(default_factory=GeminiCfg)

338 contracts: ContractsCfg = field(default_factory=ContractsCfg)

339 orchestrator: OrchestratorCfg = field(default_factory=OrchestratorCfg)

340 scorer: ScorerCfg = field(default_factory=ScorerCfg)

341 benchmark: BenchmarkCfg = field(default_factory=BenchmarkCfg)

342 health: HealthCfg = field(default_factory=HealthCfg)

343 audit: AuditCfg = field(default_factory=AuditCfg)

344 deploy: DeployCfg = field(default_factory=DeployCfg)

345 middleware: MiddlewareCfg = field(default_factory=MiddlewareCfg)

346 version: str = "0.90.0"

347

348 def to_dict(self) -> dict:

349 result = {}

350 for f in fields(self):

351 val = getattr(self, f.name)

352 if hasattr(val, "__dataclass_fields__"):

353 result[f.name] = {ff.name: getattr(val, ff.name) for ff in fields(val)}

354 else:

355 result[f.name] = val

356 return result

357

358

359 def load_config(path: str | None = None) -> AgentOSConfig:

360 config = AgentOSConfig()

361 if path and os.path.exists(path):

362 try:

363 import yaml

364 with open(path) as f:

365 data = yaml.safe_load(f)

366 _merge(config, data)

367 except ImportError:

368 pass

369 except Exception:

370 pass

371 _override_from_env(config)

372 return config

373

374

375 def _merge(config: AgentOSConfig, data: dict):

376 for key, val in data.items():

377 if hasattr(config, key):

378 section = getattr(config, key)

379 if hasattr(section, "__dataclass_fields__") and isinstance(val, dict):

380 for sk, sv in val.items():

381 if hasattr(section, sk):

382 setattr(section, sk, sv)

383 else:

384 setattr(config, key, val)

385

386

387 def _override_from_env(config: AgentOSConfig):

388 env_map = {

389 "AGENTOS_MODEL": ("model", "default"),

390 "AGENTOS_MAX_ITERATIONS": ("loop", "max_iterations"),

391 "AGENTOS_ENABLE_STREAMING": ("loop", "enable_streaming"),

392 "AGENTOS_LOG_LEVEL": ("observability", "log_level"),

393 "AGENTOS_BUDGET_LIMIT": ("cost", "budget_limit"),

394 "AGENTOS_ENABLE_REFLECTION": ("reflection", "enabled"),

395 "AGENTOS_ENABLE_COST_TRACKING": ("cost", "enabled"),

396 "AGENTOS_API_PORT": ("api", "port"),

397 "AGENTOS_SWARM_TOPOLOGY": ("swarm", "topology"),

398 "AGENTOS_SWARM_MAX_PARALLEL": ("swarm", "max_parallel_agents"),

399 "AGENTOS_CACHE_LRU_SIZE": ("cache", "lru_size"),

400 "AGENTOS_CACHE_SEMANTIC": ("cache", "semantic_enabled"),

401 "AGENTOS_QUEUE_CONCURRENCY": ("queue", "concurrency"),

402 "AGENTOS_MCP_SERVER_PORT": ("mcp_server", "port"),

403 "AGENTOS_PLUGINS_DIR": ("plugins", "plugins_dir"),

404 "AGENTOS_PLUGINS_HOT_RELOAD": ("plugins", "hot_reload"),

405 "AGENTOS_GEMINI_API_KEY": ("gemini", "api_key"),

406 "AGENTOS_GEMINI_MODEL": ("gemini", "default_model"),

407 "AGENTOS_CONTRACTS_ENABLED": ("contracts", "enabled"),

408 "AGENTOS_ORCHESTRATOR_TIMEOUT": ("orchestrator", "global_timeout"),

409 "AGENTOS_SCORER_STRATEGY": ("scorer", "strategy"),

410 "AGENTOS_SCORER_THRESHOLD": ("scorer", "pass_threshold"),

411 }

412 for env_key, (section, field_name) in env_map.items():

413 val = os.environ.get(env_key)

414 if val is not None:

415 sec = getattr(config, section)

416 default_type = type(getattr(type(sec)(), field_name, ""))

417 if default_type is bool:

418 val_typed = val.lower() in ("1", "true", "yes")

419 elif default_type is float:

420 val_typed = float(val)

421 elif default_type is int:

422 val_typed = int(val)

423 else:

424 val_typed = val

425 setattr(sec, field_name, val_typed)