foxclaw 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (495) hide show
  1. package/README.md +54 -29
  2. package/bin/foxclaw.cjs +51 -0
  3. package/index.js +11 -10
  4. package/package.json +46 -38
  5. package/python/.dockerignore +35 -0
  6. package/python/.env.example +165 -0
  7. package/python/.gitattributes +46 -0
  8. package/python/.github/workflows/ci.yml +122 -0
  9. package/python/.github/workflows/release.yml +183 -0
  10. package/python/Dockerfile +64 -0
  11. package/python/LICENSE +21 -0
  12. package/python/MANIFEST.in +14 -0
  13. package/python/README.md +192 -0
  14. package/python/README_CN.md +324 -0
  15. package/python/bench/bm25_audit.py +199 -0
  16. package/python/bench/bm25_regression.py +178 -0
  17. package/python/bench/bm25_stress.py +159 -0
  18. package/python/bench/cd_audit.py +238 -0
  19. package/python/bench/chaos.py +142 -0
  20. package/python/bench/concurrency.py +103 -0
  21. package/python/bench/e2e_real_models.py +95 -0
  22. package/python/bench/llm_retry_test.py +248 -0
  23. package/python/bench/load_test.py +196 -0
  24. package/python/bench/vector_ivf_upgrade.py +134 -0
  25. package/python/docs/CHANNELS.md +195 -0
  26. package/python/docs/GOVERNANCE.md +164 -0
  27. package/python/docs/RELEASE.md +109 -0
  28. package/python/docs/RUN.md +75 -0
  29. package/python/docs/RUN_CN.md +121 -0
  30. package/python/docs//351/205/215/347/275/256/346/214/207/345/215/227.md +152 -0
  31. package/python/evals/__init__.py +0 -0
  32. package/python/evals/governance/README.md +61 -0
  33. package/python/evals/governance/__init__.py +0 -0
  34. package/python/evals/governance/cases.py +152 -0
  35. package/python/evals/governance/compare_embeddings.py +94 -0
  36. package/python/evals/governance/convergence.svg +11 -0
  37. package/python/evals/governance/report.json +371 -0
  38. package/python/evals/governance/run_evals.py +400 -0
  39. package/python/examples/governance_middleware_demo.py +77 -0
  40. package/python/examples/langgraph_governance_demo.py +108 -0
  41. package/python/examples/sample_itinerary.csv +6 -0
  42. package/python/examples/sample_knowledge.csv +9 -0
  43. package/python/examples/sample_transactions.csv +14 -0
  44. package/python/foxclaw/__init__.py +526 -0
  45. package/python/foxclaw/agents/__init__.py +12 -0
  46. package/python/foxclaw/agents/agents.py +35 -0
  47. package/python/foxclaw/agents/base.py +865 -0
  48. package/python/foxclaw/agents/impl/__init__.py +1 -0
  49. package/python/foxclaw/agents/impl/_helpers.py +78 -0
  50. package/python/foxclaw/agents/impl/finance.py +248 -0
  51. package/python/foxclaw/agents/impl/office.py +367 -0
  52. package/python/foxclaw/agents/impl/supervisor.py +659 -0
  53. package/python/foxclaw/agents/mixins/_context.py +151 -0
  54. package/python/foxclaw/agents/mixins/augment.py +149 -0
  55. package/python/foxclaw/agents/mixins/llm.py +66 -0
  56. package/python/foxclaw/agents/mixins/memory.py +35 -0
  57. package/python/foxclaw/agents/mixins/preference.py +81 -0
  58. package/python/foxclaw/agents/mixins/prompt.py +77 -0
  59. package/python/foxclaw/agents/mixins/skillbox.py +58 -0
  60. package/python/foxclaw/agents/mixins/tool_exec.py +443 -0
  61. package/python/foxclaw/api/__init__.py +283 -0
  62. package/python/foxclaw/api/app.py +123 -0
  63. package/python/foxclaw/api/middleware.py +317 -0
  64. package/python/foxclaw/api/routes/ahs.py +417 -0
  65. package/python/foxclaw/api/routes/attachments.py +117 -0
  66. package/python/foxclaw/api/routes/browser.py +39 -0
  67. package/python/foxclaw/api/routes/domain.py +314 -0
  68. package/python/foxclaw/api/routes/knowledge.py +163 -0
  69. package/python/foxclaw/api/routes/llm_admin.py +461 -0
  70. package/python/foxclaw/api/routes/memory.py +89 -0
  71. package/python/foxclaw/api/routes/orchestration.py +41 -0
  72. package/python/foxclaw/api/routes/recovery.py +43 -0
  73. package/python/foxclaw/api/routes/review.py +275 -0
  74. package/python/foxclaw/api/routes/search.py +37 -0
  75. package/python/foxclaw/api/routes/system.py +327 -0
  76. package/python/foxclaw/api/routes/task.py +281 -0
  77. package/python/foxclaw/api/routes/ws.py +68 -0
  78. package/python/foxclaw/api/spine.py +55 -0
  79. package/python/foxclaw/browser/__init__.py +13 -0
  80. package/python/foxclaw/browser/action/__init__.py +1 -0
  81. package/python/foxclaw/browser/action/action_executor.py +54 -0
  82. package/python/foxclaw/browser/action/action_types.py +45 -0
  83. package/python/foxclaw/browser/action/action_verifier.py +68 -0
  84. package/python/foxclaw/browser/action/url_policy.py +147 -0
  85. package/python/foxclaw/browser/adapter/__init__.py +1 -0
  86. package/python/foxclaw/browser/adapter/base_adapter.py +23 -0
  87. package/python/foxclaw/browser/adapter/web_adapter.py +46 -0
  88. package/python/foxclaw/browser/driver/__init__.py +1 -0
  89. package/python/foxclaw/browser/driver/base_driver.py +61 -0
  90. package/python/foxclaw/browser/driver/playwright_driver.py +166 -0
  91. package/python/foxclaw/browser/perception/__init__.py +1 -0
  92. package/python/foxclaw/browser/perception/dom_extractor.py +43 -0
  93. package/python/foxclaw/browser/perception/element_indexer.py +57 -0
  94. package/python/foxclaw/browser/perception/semantic_reducer.py +33 -0
  95. package/python/foxclaw/browser/perception/snapshot.py +29 -0
  96. package/python/foxclaw/browser/service.py +148 -0
  97. package/python/foxclaw/browser/session/__init__.py +1 -0
  98. package/python/foxclaw/browser/session/session_manager.py +57 -0
  99. package/python/foxclaw/capability/__init__.py +12 -0
  100. package/python/foxclaw/capability/embedding_service.py +67 -0
  101. package/python/foxclaw/channels/__init__.py +140 -0
  102. package/python/foxclaw/channels/discord.py +184 -0
  103. package/python/foxclaw/channels/dispatcher.py +204 -0
  104. package/python/foxclaw/channels/feishu.py +225 -0
  105. package/python/foxclaw/channels/openclaw_bridge.py +156 -0
  106. package/python/foxclaw/channels/signing.py +187 -0
  107. package/python/foxclaw/channels/telegram.py +121 -0
  108. package/python/foxclaw/channels/weixin.py +225 -0
  109. package/python/foxclaw/cli.py +154 -0
  110. package/python/foxclaw/cognitive/__init__.py +4 -0
  111. package/python/foxclaw/cognitive/reasoner.py +82 -0
  112. package/python/foxclaw/cognitive/state.py +147 -0
  113. package/python/foxclaw/core/__init__.py +9 -0
  114. package/python/foxclaw/core/audit_chain.py +133 -0
  115. package/python/foxclaw/core/audit_sink.py +100 -0
  116. package/python/foxclaw/core/compaction.py +283 -0
  117. package/python/foxclaw/core/config.py +65 -0
  118. package/python/foxclaw/core/confirm_nonce.py +157 -0
  119. package/python/foxclaw/core/dispatch.py +27 -0
  120. package/python/foxclaw/core/envfile.py +48 -0
  121. package/python/foxclaw/core/failure_policy.py +151 -0
  122. package/python/foxclaw/core/gateway.py +85 -0
  123. package/python/foxclaw/core/governance_audit.py +175 -0
  124. package/python/foxclaw/core/idempotency.py +289 -0
  125. package/python/foxclaw/core/injection_guard.py +221 -0
  126. package/python/foxclaw/core/memory_adapter.py +516 -0
  127. package/python/foxclaw/core/metrics.py +89 -0
  128. package/python/foxclaw/core/model_router.py +1097 -0
  129. package/python/foxclaw/core/paths.py +103 -0
  130. package/python/foxclaw/core/recovery.py +362 -0
  131. package/python/foxclaw/core/scheduler.py +144 -0
  132. package/python/foxclaw/core/secrets.py +134 -0
  133. package/python/foxclaw/core/sessions.py +157 -0
  134. package/python/foxclaw/core/settings.py +430 -0
  135. package/python/foxclaw/core/shared_write.py +198 -0
  136. package/python/foxclaw/core/steering_queue.py +153 -0
  137. package/python/foxclaw/core/system_bus.py +84 -0
  138. package/python/foxclaw/core/thought_chain.py +318 -0
  139. package/python/foxclaw/core/token_meter.py +235 -0
  140. package/python/foxclaw/core/tools.py +172 -0
  141. package/python/foxclaw/core/tracing.py +390 -0
  142. package/python/foxclaw/core/truth_pipeline.py +114 -0
  143. package/python/foxclaw/core/vec_recall_adapter.py +503 -0
  144. package/python/foxclaw/core/verify.py +181 -0
  145. package/python/foxclaw/core/web_search.py +242 -0
  146. package/python/foxclaw/finance/__init__.py +15 -0
  147. package/python/foxclaw/finance/evidence.py +153 -0
  148. package/python/foxclaw/finance/fx.py +100 -0
  149. package/python/foxclaw/finance/graph.py +188 -0
  150. package/python/foxclaw/finance/models.py +150 -0
  151. package/python/foxclaw/finance/nlparse.py +575 -0
  152. package/python/foxclaw/finance/policy.py +329 -0
  153. package/python/foxclaw/finance/reasoner.py +129 -0
  154. package/python/foxclaw/finance/reasoning.py +340 -0
  155. package/python/foxclaw/finance/reconcile.py +180 -0
  156. package/python/foxclaw/finance/runtime.py +527 -0
  157. package/python/foxclaw/governance/__init__.py +24 -0
  158. package/python/foxclaw/governance/middleware.py +184 -0
  159. package/python/foxclaw/harness/__init__.py +17 -0
  160. package/python/foxclaw/harness/_base.py +72 -0
  161. package/python/foxclaw/harness/_policy.py +359 -0
  162. package/python/foxclaw/harness/drift.py +89 -0
  163. package/python/foxclaw/harness/event_bus.py +31 -0
  164. package/python/foxclaw/harness/harness.py +446 -0
  165. package/python/foxclaw/harness/loop_detection.py +152 -0
  166. package/python/foxclaw/itinerary/__init__.py +10 -0
  167. package/python/foxclaw/itinerary/amap_client.py +117 -0
  168. package/python/foxclaw/itinerary/models.py +80 -0
  169. package/python/foxclaw/itinerary/reasoner.py +101 -0
  170. package/python/foxclaw/itinerary/reasoning.py +174 -0
  171. package/python/foxclaw/itinerary/runtime.py +148 -0
  172. package/python/foxclaw/kernel/__init__.py +13 -0
  173. package/python/foxclaw/kernel/capabilities.py +73 -0
  174. package/python/foxclaw/kernel/policy_gate.py +114 -0
  175. package/python/foxclaw/kernel/process_manager.py +205 -0
  176. package/python/foxclaw/kernel/scheduler.py +131 -0
  177. package/python/foxclaw/kernel/sentinel.py +453 -0
  178. package/python/foxclaw/kernel/sentinel_client.py +246 -0
  179. package/python/foxclaw/kernel/spine.py +97 -0
  180. package/python/foxclaw/knowledge/__init__.py +376 -0
  181. package/python/foxclaw/knowledge/truth_crystallizer.py +92 -0
  182. package/python/foxclaw/learning/__init__.py +12 -0
  183. package/python/foxclaw/learning/knowledge_graph.py +149 -0
  184. package/python/foxclaw/learning/models.py +93 -0
  185. package/python/foxclaw/learning/reasoner.py +70 -0
  186. package/python/foxclaw/learning/runtime.py +363 -0
  187. package/python/foxclaw/learning/spaced_repetition.py +96 -0
  188. package/python/foxclaw/mcp_server.py +189 -0
  189. package/python/foxclaw/orchestration/__init__.py +184 -0
  190. package/python/foxclaw/pipeline/__init__.py +23 -0
  191. package/python/foxclaw/pipeline/cognitive_pipeline.py +481 -0
  192. package/python/foxclaw/pipeline/supervisor_stages.py +230 -0
  193. package/python/foxclaw/planning/__init__.py +17 -0
  194. package/python/foxclaw/planning/llm_planner.py +232 -0
  195. package/python/foxclaw/planning/planner.py +99 -0
  196. package/python/foxclaw/search/__init__.py +24 -0
  197. package/python/foxclaw/search/agent_port.py +194 -0
  198. package/python/foxclaw/search/evidence.py +113 -0
  199. package/python/foxclaw/search/external_search.py +50 -0
  200. package/python/foxclaw/search/hkc_read_port.py +60 -0
  201. package/python/foxclaw/search/internal_search.py +73 -0
  202. package/python/foxclaw/search/models.py +129 -0
  203. package/python/foxclaw/search/planner.py +44 -0
  204. package/python/foxclaw/search/retriever.py +39 -0
  205. package/python/foxclaw/search/runtime.py +134 -0
  206. package/python/foxclaw/search/strategy.py +44 -0
  207. package/python/foxclaw/skills/__init__.py +613 -0
  208. package/python/foxclaw/skills/hooks_spec.py +73 -0
  209. package/python/foxclaw/skills/lifecycle.py +278 -0
  210. package/python/foxclaw/skills/markdown_skill.py +174 -0
  211. package/python/foxclaw/skills/markdown_store.py +39 -0
  212. package/python/foxclaw/skills/mcp_client.py +190 -0
  213. package/python/foxclaw/skills/mcp_store.py +43 -0
  214. package/python/foxclaw/skills/permission.py +180 -0
  215. package/python/foxclaw/skills/pipeline.py +386 -0
  216. package/python/foxclaw/skills/policy.py +80 -0
  217. package/python/foxclaw/skills/review.py +72 -0
  218. package/python/foxclaw/skills/store.py +57 -0
  219. package/python/frontend/assets/core_bg.jpg +0 -0
  220. package/python/frontend/deck/auth.js +32 -0
  221. package/python/frontend/deck/chat_model_picker.js +537 -0
  222. package/python/frontend/deck/domain.js +296 -0
  223. package/python/frontend/deck/main.js +1950 -0
  224. package/python/frontend/deck/markdown.js +48 -0
  225. package/python/frontend/deck/settings.js +324 -0
  226. package/python/frontend/deck/state.js +6 -0
  227. package/python/frontend/deck/util.js +6 -0
  228. package/python/frontend/deck/visuals.js +212 -0
  229. package/python/frontend/deck.css +855 -0
  230. package/python/frontend/deck.html +686 -0
  231. package/python/frontend/deck_v2.html +341 -0
  232. package/python/frontend/planet/index.html +266 -0
  233. package/python/frontend/planet/planet.css +579 -0
  234. package/python/frontend/planet/planet.js +1637 -0
  235. package/python/frontend/planet/vendor/three.core.min.js +6 -0
  236. package/python/frontend/planet/vendor/three.module.min.js +6 -0
  237. package/python/frontend/v3/assets/index-BD7VPbMV.js +33 -0
  238. package/python/frontend/v3/assets/index-CAvnYWGH.css +1 -0
  239. package/python/frontend/v3/index.html +15 -0
  240. package/python/frontend/widget_runtime.js +295 -0
  241. package/python/frontend/widgets.js +696 -0
  242. package/python/frontend_src/index.html +14 -0
  243. package/python/frontend_src/package-lock.json +1376 -0
  244. package/python/frontend_src/package.json +19 -0
  245. package/python/frontend_src/src/App.vue +62 -0
  246. package/python/frontend_src/src/api.js +89 -0
  247. package/python/frontend_src/src/components/ChatDock.vue +377 -0
  248. package/python/frontend_src/src/components/ComposerMenu.vue +75 -0
  249. package/python/frontend_src/src/components/DocViewer.vue +171 -0
  250. package/python/frontend_src/src/components/Inspector.vue +241 -0
  251. package/python/frontend_src/src/components/LeftRail.vue +394 -0
  252. package/python/frontend_src/src/components/MenuPopover.vue +130 -0
  253. package/python/frontend_src/src/components/MessageStream.vue +401 -0
  254. package/python/frontend_src/src/components/ModelPicker.vue +355 -0
  255. package/python/frontend_src/src/components/QuickIngest.vue +118 -0
  256. package/python/frontend_src/src/components/Stage.vue +226 -0
  257. package/python/frontend_src/src/components/ToolMenu.vue +144 -0
  258. package/python/frontend_src/src/components/TopBar.vue +90 -0
  259. package/python/frontend_src/src/components/panels/ActivityPanel.vue +84 -0
  260. package/python/frontend_src/src/components/panels/AgentsPanel.vue +86 -0
  261. package/python/frontend_src/src/components/panels/KnowledgePanel.vue +441 -0
  262. package/python/frontend_src/src/components/panels/MemoryPanel.vue +118 -0
  263. package/python/frontend_src/src/components/panels/PanelBox.vue +51 -0
  264. package/python/frontend_src/src/components/panels/ReviewPanel.vue +308 -0
  265. package/python/frontend_src/src/components/panels/SettingsPanel.vue +254 -0
  266. package/python/frontend_src/src/components/panels/TasksPanel.vue +74 -0
  267. package/python/frontend_src/src/components/panels/ToolsPanel.vue +640 -0
  268. package/python/frontend_src/src/components/panels/UsagePanel.vue +105 -0
  269. package/python/frontend_src/src/lib/fmt.js +48 -0
  270. package/python/frontend_src/src/lib/md.js +204 -0
  271. package/python/frontend_src/src/main.js +7 -0
  272. package/python/frontend_src/src/stores/app.js +106 -0
  273. package/python/frontend_src/src/stores/chat.js +484 -0
  274. package/python/frontend_src/src/stores/model.js +104 -0
  275. package/python/frontend_src/src/stores/panels.js +330 -0
  276. package/python/frontend_src/src/styles/base.css +138 -0
  277. package/python/frontend_src/src/styles/panel.css +117 -0
  278. package/python/frontend_src/src/styles/tokens.css +78 -0
  279. package/python/frontend_src/vite.config.js +46 -0
  280. package/python/pyproject.toml +265 -0
  281. package/python/skills/README.md +123 -0
  282. package/python/skills/execution-contract/SKILL.md +30 -0
  283. package/python/skills/general-assistant/SKILL.md +34 -0
  284. package/python/skills/planner/SKILL.md +33 -0
  285. package/python/skills/schedule-itinerary/SKILL.md +35 -0
  286. package/python/skills/skill-composition/SKILL.md +31 -0
  287. package/python/skills/skill-guard/SKILL.md +67 -0
  288. package/python/skills/skill-memory/SKILL.md +50 -0
  289. package/python/skills/skill-router/SKILL.md +35 -0
  290. package/python/tests/conftest.py +76 -0
  291. package/python/tests/run_all.py +263 -0
  292. package/python/tests/test_agent_lifecycle.py +360 -0
  293. package/python/tests/test_ahs_p2.py +414 -0
  294. package/python/tests/test_anthropic_tools.py +206 -0
  295. package/python/tests/test_api.py +87 -0
  296. package/python/tests/test_api_auth.py +83 -0
  297. package/python/tests/test_api_host_guard.py +69 -0
  298. package/python/tests/test_attachments.py +167 -0
  299. package/python/tests/test_audit_chain.py +121 -0
  300. package/python/tests/test_audit_sink.py +136 -0
  301. package/python/tests/test_browser.py +153 -0
  302. package/python/tests/test_browser_request_guard.py +184 -0
  303. package/python/tests/test_capabilities.py +158 -0
  304. package/python/tests/test_channel_signing.py +192 -0
  305. package/python/tests/test_channel_trust.py +109 -0
  306. package/python/tests/test_channels.py +184 -0
  307. package/python/tests/test_cli.py +46 -0
  308. package/python/tests/test_compaction_toolpair.py +119 -0
  309. package/python/tests/test_config_layering.py +65 -0
  310. package/python/tests/test_confirm_nonce.py +197 -0
  311. package/python/tests/test_context_compaction_wiring.py +130 -0
  312. package/python/tests/test_dispatch.py +95 -0
  313. package/python/tests/test_domain_evals.py +403 -0
  314. package/python/tests/test_domain_import.py +78 -0
  315. package/python/tests/test_domain_reasoners.py +148 -0
  316. package/python/tests/test_e2e.py +178 -0
  317. package/python/tests/test_emb_cache.py +107 -0
  318. package/python/tests/test_embedding_singleton.py +89 -0
  319. package/python/tests/test_envfile.py +83 -0
  320. package/python/tests/test_evals_smoke.py +114 -0
  321. package/python/tests/test_event_spine.py +182 -0
  322. package/python/tests/test_evidence_semantic.py +101 -0
  323. package/python/tests/test_evidence_sse.py +97 -0
  324. package/python/tests/test_file_ingest.py +146 -0
  325. package/python/tests/test_finance.py +153 -0
  326. package/python/tests/test_finance_ledger.py +252 -0
  327. package/python/tests/test_finance_persist.py +178 -0
  328. package/python/tests/test_gateway.py +144 -0
  329. package/python/tests/test_governance.py +468 -0
  330. package/python/tests/test_governance_audit.py +359 -0
  331. package/python/tests/test_governance_middleware.py +143 -0
  332. package/python/tests/test_hkc.py +286 -0
  333. package/python/tests/test_hkc_index_build_manager.py +339 -0
  334. package/python/tests/test_hkc_manifest_reuse.py +317 -0
  335. package/python/tests/test_hkc_search_event_sync.py +533 -0
  336. package/python/tests/test_import_path_guard.py +161 -0
  337. package/python/tests/test_injection_guard.py +211 -0
  338. package/python/tests/test_integration.py +141 -0
  339. package/python/tests/test_itinerary.py +103 -0
  340. package/python/tests/test_kee_semantic.py +89 -0
  341. package/python/tests/test_kernel.py +222 -0
  342. package/python/tests/test_learning.py +110 -0
  343. package/python/tests/test_llm_admin.py +160 -0
  344. package/python/tests/test_llm_planner.py +366 -0
  345. package/python/tests/test_markdown_skills.py +73 -0
  346. package/python/tests/test_markdown_skills_openclaw.py +71 -0
  347. package/python/tests/test_mcp_connectors.py +109 -0
  348. package/python/tests/test_mcp_guardian_discovery.py +91 -0
  349. package/python/tests/test_mcp_no_memory.py +43 -0
  350. package/python/tests/test_mcp_policy_gate.py +77 -0
  351. package/python/tests/test_mcp_server.py +95 -0
  352. package/python/tests/test_memory_recall.py +95 -0
  353. package/python/tests/test_metrics.py +66 -0
  354. package/python/tests/test_multi_chain.py +102 -0
  355. package/python/tests/test_multimodal.py +135 -0
  356. package/python/tests/test_negotiation.py +146 -0
  357. package/python/tests/test_orchestration.py +119 -0
  358. package/python/tests/test_orchestration_decoupled.py +109 -0
  359. package/python/tests/test_p3_p5_hardening.py +338 -0
  360. package/python/tests/test_parallel_dispatch.py +215 -0
  361. package/python/tests/test_pipeline.py +533 -0
  362. package/python/tests/test_plan_visible.py +86 -0
  363. package/python/tests/test_planner.py +95 -0
  364. package/python/tests/test_policy_gate.py +109 -0
  365. package/python/tests/test_reasoner.py +185 -0
  366. package/python/tests/test_release_check.py +263 -0
  367. package/python/tests/test_resume_checkpoint.py +156 -0
  368. package/python/tests/test_routing.py +95 -0
  369. package/python/tests/test_scheduler.py +141 -0
  370. package/python/tests/test_search.py +204 -0
  371. package/python/tests/test_secrets.py +159 -0
  372. package/python/tests/test_semantic.py +78 -0
  373. package/python/tests/test_sessions.py +91 -0
  374. package/python/tests/test_settings.py +281 -0
  375. package/python/tests/test_shadow_learning.py +330 -0
  376. package/python/tests/test_shared_write.py +207 -0
  377. package/python/tests/test_skill_taint_gate.py +154 -0
  378. package/python/tests/test_skills.py +133 -0
  379. package/python/tests/test_stats_and_events.py +165 -0
  380. package/python/tests/test_streaming.py +60 -0
  381. package/python/tests/test_supervisor_pipeline.py +177 -0
  382. package/python/tests/test_supervisor_triage.py +108 -0
  383. package/python/tests/test_taint.py +117 -0
  384. package/python/tests/test_task_stream.py +85 -0
  385. package/python/tests/test_thinking_sse.py +67 -0
  386. package/python/tests/test_thinking_stream.py +76 -0
  387. package/python/tests/test_tool_center.py +129 -0
  388. package/python/tests/test_tool_parallel.py +113 -0
  389. package/python/tests/test_tool_params.py +103 -0
  390. package/python/tests/test_tool_use.py +242 -0
  391. package/python/tests/test_toplevel_concurrency.py +117 -0
  392. package/python/tests/test_tracing.py +290 -0
  393. package/python/tests/test_truth_crystallizer.py +127 -0
  394. package/python/tests/test_truth_flow.py +93 -0
  395. package/python/tests/test_url_policy.py +53 -0
  396. package/python/tests/test_verify_evidence.py +225 -0
  397. package/python/tests/test_version_sync.py +71 -0
  398. package/python/tests/test_web_trigger.py +99 -0
  399. package/python/tools/check_faiss_type.py +31 -0
  400. package/python/tools/check_log.ps1 +46 -0
  401. package/python/tools/ivf_status.py +72 -0
  402. package/python/tools/mypy_baseline.txt +5 -0
  403. package/python/tools/mypy_ratchet.py +97 -0
  404. package/python/tools/pack.py +178 -0
  405. package/python/tools/release_check.py +349 -0
  406. package/python/tools/restart_foxclaw.ps1 +74 -0
  407. package/python/tools/shared_write_audit.py +204 -0
  408. package/python/tools/size_baseline.txt +28 -0
  409. package/python/tools/size_check.py +102 -0
  410. package/python/tools/verify_env.bat +2 -0
  411. package/python/tools/verify_env.py +25 -0
  412. package/python/vendor/HMR_LICENSE +37 -0
  413. package/python/vendor/HMR_README.md +65 -0
  414. package/python/vendor/hkc/LICENSE +37 -0
  415. package/python/vendor/hkc/hkc_ace/__init__.py +0 -0
  416. package/python/vendor/hkc/hkc_ace/ace.py +457 -0
  417. package/python/vendor/hkc/hkc_ace/skill_taxonomy.json +465 -0
  418. package/python/vendor/hkc/hkc_api/__init__.py +0 -0
  419. package/python/vendor/hkc/hkc_api/container.py +416 -0
  420. package/python/vendor/hkc/hkc_api/ingest_jobs.py +103 -0
  421. package/python/vendor/hkc/hkc_api/main.py +157 -0
  422. package/python/vendor/hkc/hkc_api/routes/__init__.py +0 -0
  423. package/python/vendor/hkc/hkc_api/routes/ability.py +151 -0
  424. package/python/vendor/hkc/hkc_api/routes/config.py +51 -0
  425. package/python/vendor/hkc/hkc_api/routes/knowledge.py +630 -0
  426. package/python/vendor/hkc/hkc_api/routes/search.py +88 -0
  427. package/python/vendor/hkc/hkc_api/schemas.py +153 -0
  428. package/python/vendor/hkc/hkc_api/synthesis.py +179 -0
  429. package/python/vendor/hkc/hkc_core/__init__.py +0 -0
  430. package/python/vendor/hkc/hkc_core/graph/__init__.py +0 -0
  431. package/python/vendor/hkc/hkc_core/graph/base.py +188 -0
  432. package/python/vendor/hkc/hkc_core/graph/sqlite_store.py +789 -0
  433. package/python/vendor/hkc/hkc_core/models/__init__.py +0 -0
  434. package/python/vendor/hkc/hkc_core/models/enums.py +65 -0
  435. package/python/vendor/hkc/hkc_core/models/ku.py +307 -0
  436. package/python/vendor/hkc/hkc_core/utils/__init__.py +0 -0
  437. package/python/vendor/hkc/hkc_core/utils/id_gen.py +113 -0
  438. package/python/vendor/hkc/hkc_crystallizer/__init__.py +44 -0
  439. package/python/vendor/hkc/hkc_crystallizer/adapters.py +94 -0
  440. package/python/vendor/hkc/hkc_crystallizer/candidate.py +145 -0
  441. package/python/vendor/hkc/hkc_crystallizer/crystallizer.py +179 -0
  442. package/python/vendor/hkc/hkc_crystallizer/ingress.py +90 -0
  443. package/python/vendor/hkc/hkc_kde/__init__.py +0 -0
  444. package/python/vendor/hkc/hkc_kde/chunker.py +197 -0
  445. package/python/vendor/hkc/hkc_kde/extractor.py +623 -0
  446. package/python/vendor/hkc/hkc_kde/kde.py +298 -0
  447. package/python/vendor/hkc/hkc_kde/loaders/__init__.py +0 -0
  448. package/python/vendor/hkc/hkc_kde/loaders/ebook_loader.py +153 -0
  449. package/python/vendor/hkc/hkc_kde/loaders/office_loader.py +194 -0
  450. package/python/vendor/hkc/hkc_kde/loaders/pdf_loader.py +162 -0
  451. package/python/vendor/hkc/hkc_kde/loaders/text_loader.py +157 -0
  452. package/python/vendor/hkc/hkc_kde/loaders/web_loader.py +91 -0
  453. package/python/vendor/hkc/hkc_kde/models.py +74 -0
  454. package/python/vendor/hkc/hkc_kde/packager.py +329 -0
  455. package/python/vendor/hkc/hkc_kde/relation_disc.py +151 -0
  456. package/python/vendor/hkc/hkc_kee/__init__.py +0 -0
  457. package/python/vendor/hkc/hkc_kee/dedup.py +227 -0
  458. package/python/vendor/hkc/hkc_kee/fingerprint.py +106 -0
  459. package/python/vendor/hkc/hkc_kee/kee.py +541 -0
  460. package/python/vendor/hkc/hkc_kep/__init__.py +0 -0
  461. package/python/vendor/hkc/hkc_kep/event_bus.py +205 -0
  462. package/python/vendor/hkc/hkc_sdk/__init__.py +63 -0
  463. package/python/vendor/hkc/hkc_sdk/base.py +151 -0
  464. package/python/vendor/hkc/hkc_sdk/direct_client.py +153 -0
  465. package/python/vendor/hkc/hkc_sdk/exceptions.py +39 -0
  466. package/python/vendor/hkc/hkc_sdk/http_client.py +166 -0
  467. package/python/vendor/hkc/hkc_sdk/models.py +171 -0
  468. package/python/vendor/hkc/hkc_search/__init__.py +0 -0
  469. package/python/vendor/hkc/hkc_search/bm25.py +325 -0
  470. package/python/vendor/hkc/hkc_search/embedding_backends.py +374 -0
  471. package/python/vendor/hkc/hkc_search/graph_search.py +132 -0
  472. package/python/vendor/hkc/hkc_search/hybrid.py +331 -0
  473. package/python/vendor/hkc/hkc_search/index_build_manager.py +378 -0
  474. package/python/vendor/hkc/hkc_search/vector_search.py +484 -0
  475. package/python/vendor/hmr/__init__.py +0 -0
  476. package/python/vendor/hmr/core/__init__.py +0 -0
  477. package/python/vendor/hmr/core/hmr.py +684 -0
  478. package/python/vendor/hmr/core/models.py +310 -0
  479. package/python/vendor/hmr/engines/__init__.py +0 -0
  480. package/python/vendor/hmr/engines/evolution.py +710 -0
  481. package/python/vendor/hmr/engines/jit_compiler.py +472 -0
  482. package/python/vendor/hmr/engines/lifecycle.py +264 -0
  483. package/python/vendor/hmr/engines/policy.py +625 -0
  484. package/python/vendor/hmr/engines/recall.py +260 -0
  485. package/python/vendor/hmr/engines/runtime_state.py +158 -0
  486. package/python/vendor/hmr/engines/scheduler.py +323 -0
  487. package/python/vendor/hmr/engines/semantic.py +150 -0
  488. package/python/vendor/hmr/engines/temporal.py +261 -0
  489. package/python/vendor/hmr/engines/thought_chain.py +635 -0
  490. package/python/vendor/hmr/graph/__init__.py +0 -0
  491. package/python/vendor/hmr/graph/cwg.py +338 -0
  492. package/python/vendor/hmr/graph/memory_graph.py +530 -0
  493. package/python/vendor/hmr/storage/__init__.py +0 -0
  494. package/python/vendor/hmr/storage/memory_fs.py +300 -0
  495. package/python/vendor/hmr/storage/vector_store.py +520 -0
@@ -0,0 +1,46 @@
1
+ import { execSync } from 'node:child_process'
2
+ import { defineConfig } from 'vite'
3
+ import vue from '@vitejs/plugin-vue'
4
+ import { fileURLToPath, URL } from 'node:url'
5
+
6
+ /* 设置面板底部的版本行照 OpenClaw 写成 git@<sha> · <N 天前>。
7
+ 构建时抓一次 git 信息;没有 git(打包机 / 压缩包)就退回 dev,不让构建失败。 */
8
+ function gitInfo() {
9
+ try {
10
+ const sha = execSync('git rev-parse --short HEAD', { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim()
11
+ const ts = Number(execSync('git log -1 --format=%ct', { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim()) * 1000
12
+ return { sha, ts: Number.isFinite(ts) ? ts : 0 }
13
+ } catch {
14
+ return { sha: 'dev', ts: 0 }
15
+ }
16
+ }
17
+
18
+ /* 产物直接写进 frontend/v3/,后端 (StaticFiles(directory=frontend, html=True)) 零改动:
19
+ /v3/ -> frontend/v3/index.html
20
+ base 必须是 '/v3/',否则 assets 会打到站点根。 */
21
+ export default defineConfig({
22
+ base: '/v3/',
23
+ plugins: [vue()],
24
+ resolve: {
25
+ alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) },
26
+ },
27
+ define: {
28
+ __APP_INFO__: JSON.stringify({ git: gitInfo(), built: Date.now() }),
29
+ },
30
+ build: {
31
+ outDir: '../frontend/v3',
32
+ emptyOutDir: true,
33
+ target: 'es2022',
34
+ },
35
+ server: {
36
+ port: 5173,
37
+ /* dev 时把 API 与 WS 透到本地后端,前端代码里一律用相对路径 /api */
38
+ proxy: {
39
+ '/api': { target: 'http://127.0.0.1:8000', changeOrigin: true },
40
+ '/ws': { target: 'ws://127.0.0.1:8000', ws: true },
41
+ '/planet': { target: 'http://127.0.0.1:8000', changeOrigin: true },
42
+ /* /knowledge/* 无 /api 前缀:HKC 自带 router 由后端根路径挂载 */
43
+ '/knowledge': { target: 'http://127.0.0.1:8000', changeOrigin: true },
44
+ },
45
+ },
46
+ })
@@ -0,0 +1,265 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "foxclaw"
7
+ version = "0.1.2"
8
+ description = "Foxclaw - a personal agent with memory, built on the HMR memory runtime"
9
+ requires-python = ">=3.11"
10
+
11
+ # 项目页正文(long_description)。此前缺这一行,PyPI 项目页只显示
12
+ # 「该软件包的作者未提供项目描述」——元数据里没有 Description。中英文各一份,
13
+ # 这里按主要读者选中文版;发布门槛见 tools/release_check.py 的 no_readme /
14
+ # no_long_description 检查(缺正文直接失败,不再允许空白页发出)。
15
+ readme = { file = "README_CN.md", content-type = "text/markdown" }
16
+
17
+ # 许可:仓库根目录 LICENSE 为 MIT。这里用 { file = "LICENSE" } 而不是 PEP 639 的
18
+ # SPDX 字符串(`license = "MIT"`),因为 build-system 只要求 setuptools>=68,而
19
+ # SPDX 字符串要 setuptools>=77 才会被接受;老写法在 68+ 全部可用,metadata 里同样
20
+ # 带上完整许可全文。
21
+ license = { file = "LICENSE" }
22
+ classifiers = [
23
+ "License :: OSI Approved :: MIT License",
24
+ ]
25
+
26
+ # 依赖以本表为唯一来源(CI 用 `pip install -e .` 安装,不再手写第二份清单)。
27
+ # 注意:HMR 与 HKC 以 vendor/ 内嵌随包分发、走 sys.path 加载,不是 PyPI 依赖,
28
+ # 故此处**不**声明 hmr/hkc —— 此前声明 hmr>=1.0.0 是空转项(永不从 PyPI 安装)。
29
+ dependencies = [
30
+ # LLM 提供商(未装/未配 key 时模型路由降级 stub,其余功能照常)
31
+ "anthropic>=0.25.0",
32
+ "openai>=1.0.0",
33
+ # 语义嵌入与向量检索(Harness 语义漂移检测 + HKC 语义搜索)
34
+ "sentence-transformers>=2.7.0",
35
+ "numpy>=1.26.0",
36
+ "scikit-learn>=1.4.0",
37
+ # HKC 向量索引的硬依赖(不是可选):vendor/hkc/hkc_search/vector_search.py
38
+ # 的 VectorIndex._init_index() 缺 faiss 时直接 raise ImportError。
39
+ # 此前只在注释里写「已随本体」而依赖表漏声明 → CI 干净环境装不到,
40
+ # test_hkc_manifest_reuse 顶层 import 失败(collection error),
41
+ # Stage B/C 的 vector.size() 断言全红。本机曾手动装过,故一直没暴露。
42
+ "faiss-cpu>=1.8.0",
43
+ # API 服务
44
+ "fastapi>=0.111.0",
45
+ "uvicorn>=0.29.0",
46
+ "websockets>=12.0",
47
+ "pydantic>=2.0.0",
48
+ # 内置 MCP 服务器(/api/mcp/)+ Skill MCP 客户端(mcp_server.py / skills/mcp_client.py 顶层硬依赖)
49
+ # 锁 <2.0:mcp 2.x 是大重构(拆出 mcp_types、改 fastmcp/streamable_http/sse 客户端 API、
50
+ # 换 httpx2),与本仓库基于 1.x 的调用不兼容;1.27.x 已在 CI 与本地全量回归验证。
51
+ "mcp>=1.27.0,<2.0",
52
+ # HTTP 客户端(渠道适配器 + Web 工具)。沿用既有 <0.28 约束
53
+ "httpx>=0.24,<0.28",
54
+ # 飞书加密事件解密
55
+ "cryptography>=41.0.0",
56
+ # 配置与终端输出
57
+ "pyyaml>=6.0.0",
58
+ "python-dotenv>=1.0.0",
59
+ "rich>=13.7.0",
60
+ ]
61
+
62
+ [project.scripts]
63
+ # 命令名与包名一致(foxclaw),`pip install` 之后直接可用:
64
+ # `pip install -e .` 之后可直接 `foxclaw serve`。
65
+ foxclaw = "foxclaw.cli:main"
66
+
67
+ [tool.setuptools]
68
+ # vendor/ 里的 HMR 与 HKC 是内嵌运行时(不是 PyPI 依赖)。此前 packages.find 只收
69
+ # foxclaw*,装完 import 得到的是「记忆/知识子系统全部降级为 None」的占位包。
70
+ # 这里把它们真正打进 wheel,并让 package-data 一并带上 LICENSE/JSON 等非 .py 资源。
71
+ include-package-data = true
72
+
73
+ [tool.setuptools.packages.find]
74
+ # foxclaw 在仓库根;hmr 在 vendor/ 下;hkc_* 在 vendor/hkc/ 下 —— 三个搜索根都要给。
75
+ where = [".", "vendor", "vendor/hkc"]
76
+ include = ["foxclaw*", "hmr*", "hkc_*"]
77
+
78
+ [project.optional-dependencies]
79
+ dev = [
80
+ "pytest>=8.0",
81
+ "pytest-asyncio>=0.23.0",
82
+ "ruff>=0.16",
83
+ "mypy>=1.10",
84
+ "coverage>=7.5",
85
+ # 默认回归硬依赖:test_file_ingest / test_domain_import 顶层 import docx/openpyxl,
86
+ # 缺失即 ModuleNotFoundError。与下方 knowledge-files 重复声明是刻意的——
87
+ # 此处是"测试视角"(回归必需),下方是"功能视角"(文件摄入)。放 dev 而非 knowledge-files,
88
+ # 避免为了两个 docx/xlsx 测试连带拖入 pymupdf/ebooklib/mobi 等 PDF/epub 重依赖。
89
+ "python-docx>=1.1",
90
+ "openpyxl>=3.1",
91
+ ]
92
+ # 浏览器子系统(HIR-Browser)。playwright 是重可选依赖:装了才启用真实浏览器,
93
+ # 未装则 /api/browser/* 优雅降级(available=False)。装后还需 `playwright install chromium`。
94
+ browser = ["playwright>=1.44.0"]
95
+ # Google Gemini provider。model_router 在 FOXCLAW_PROVIDER=google 时才惰性 import
96
+ # google.generativeai;未装则该分支 ImportError(其余 provider 不受影响)。此前只在
97
+ # 文档里写「pip install google-generativeai」,依赖表无对应声明,属 R1 检测出的缺口。
98
+ gemini = ["google-generativeai>=0.8"]
99
+ # 自定义模型 API key 存 OS 凭据库(Windows DPAPI / macOS Keychain / Linux Secret
100
+ # Service)。未装则回退 base64 混淆(防 grep,非加密),见 core/secrets.py。
101
+ keyring = ["keyring>=24.0"]
102
+ # 知识核心(HKC,vendor/hkc)。核心运行时依赖;缺失时 /api/knowledge/* 优雅降级。
103
+ # 真实语义向量另需 sentence-transformers+faiss(已随本体);文件摄入见 knowledge-files。
104
+ knowledge = ["networkx>=3.0", "rank-bm25>=0.2", "aiofiles>=23.0", "requests>=2.31"]
105
+ # HKC 文件摄入(PDF/epub/mobi/docx/xlsx)。仅当要摄入电子书/PDF/Office 文档时需要。
106
+ knowledge-files = ["pymupdf>=1.24", "ebooklib>=0.18", "beautifulsoup4>=4.12", "mobi>=0.3.3", "python-multipart>=0.0.9", "python-docx>=1.1", "openpyxl>=3.1"]
107
+
108
+
109
+ # ─────────────────────────────────────────────────────────────
110
+ # 工程化工具链(S1):ruff / mypy / pytest / coverage
111
+ # 策略:首次引入,存量告警显式豁免(只保留死代码/真 bug 硬门),S3 拆分后逐步收紧。
112
+ # ─────────────────────────────────────────────────────────────
113
+
114
+ [tool.ruff]
115
+ line-length = 120
116
+ target-version = "py311"
117
+ # 只 lint 主包 + 测试;vendor/ 是内嵌第三方,frontend/skills/tools/bench/evals/examples 非 Python 主包。
118
+ extend-exclude = ["vendor/", "frontend/", "skills/", "tools/", "bench/", "evals/", "examples/"]
119
+
120
+ [tool.ruff.lint]
121
+ select = ["E", "F", "W", "B", "I", "UP"]
122
+ # 存量告警显式豁免(风格/现代化类);F 系列(pyflakes 死代码/未定义名)已清零并作为硬门。
123
+ # S3 拆分大文件后,逐条从 ignore 移除以收紧。
124
+ ignore = [
125
+ "E501", # line-too-long(862 存量)
126
+ "E701", "E702", "E731", "E741", "E401", "E402", # pycodestyle 风格
127
+ "I001", # import 排序(138 存量)
128
+ "B008", "B034", "B904", "B905", # bugbear 非致命(33 存量)
129
+ "UP006", "UP015", "UP017", "UP031", "UP035", "UP037", "UP041", "UP042", "UP045", # pyupgrade(143 存量)
130
+ ]
131
+
132
+ [tool.mypy]
133
+ python_version = "3.11"
134
+ ignore_missing_imports = true
135
+ check_untyped_defs = true
136
+ # 渐进式:mypy 存量错误用棘轮门管理(tools/mypy_ratchet.py + tools/mypy_baseline.txt)。
137
+ # 2026-11 实测 673 errors in 90 files,已冻结:CI 中错误数一旦增加即失败,
138
+ # 下降后用 `python tools/mypy_ratchet.py --update` 调低基线。只降不升。
139
+
140
+ [tool.pytest.ini_options]
141
+ testpaths = ["tests"]
142
+ # S2 迁移完成:全部 76 个测试文件均已迁移为 pytest(无顶层 import 副作用,可安全收集)。
143
+ # 注意:网关/内置MCP/流式限流等少数测试依赖模块级单例(FOXCLAW_GATEWAY、FOXCLAW_MCP_SERVER、
144
+ # _STREAM_LIMITER 均在 import 时按 env 固化),单进程 `pytest tests/` 会让这些单例被首个
145
+ # import 定死、相互污染。故全量执行统一走 tests/run_all.py(每个文件独立子进程
146
+ # `python -m pytest <file> -q` 隔离)。本白名单确保任意单文件可被 pytest 收集/运行。
147
+ python_files = [
148
+ "test_agent_lifecycle.py",
149
+ "test_ahs_p2.py",
150
+ "test_anthropic_tools.py",
151
+ "test_api.py",
152
+ "test_api_auth.py",
153
+ "test_api_host_guard.py",
154
+ "test_attachments.py",
155
+ "test_audit_chain.py",
156
+ "test_audit_sink.py",
157
+ "test_browser.py",
158
+ "test_browser_request_guard.py",
159
+ "test_capabilities.py",
160
+ "test_channel_signing.py",
161
+ "test_channel_trust.py",
162
+ "test_channels.py",
163
+ "test_cli.py",
164
+ "test_compaction_toolpair.py",
165
+ "test_config_layering.py",
166
+ "test_confirm_nonce.py",
167
+ "test_context_compaction_wiring.py",
168
+ "test_dispatch.py",
169
+ "test_domain_evals.py",
170
+ "test_domain_import.py",
171
+ "test_domain_reasoners.py",
172
+ "test_e2e.py",
173
+ "test_emb_cache.py",
174
+ "test_embedding_singleton.py",
175
+ "test_evals_smoke.py",
176
+ "test_event_spine.py",
177
+ "test_evidence_semantic.py",
178
+ "test_evidence_sse.py",
179
+ "test_file_ingest.py",
180
+ "test_finance.py",
181
+ "test_gateway.py",
182
+ "test_governance.py",
183
+ "test_governance_audit.py",
184
+ "test_governance_middleware.py",
185
+ "test_hkc.py",
186
+ "test_hkc_index_build_manager.py",
187
+ "test_hkc_manifest_reuse.py",
188
+ "test_hkc_search_event_sync.py",
189
+ "test_import_path_guard.py",
190
+ "test_injection_guard.py",
191
+ "test_integration.py",
192
+ "test_itinerary.py",
193
+ "test_kee_semantic.py",
194
+ "test_kernel.py",
195
+ "test_learning.py",
196
+ "test_llm_planner.py",
197
+ "test_markdown_skills.py",
198
+ "test_markdown_skills_openclaw.py",
199
+ "test_mcp_connectors.py",
200
+ "test_mcp_guardian_discovery.py",
201
+ "test_mcp_no_memory.py",
202
+ "test_mcp_policy_gate.py",
203
+ "test_mcp_server.py",
204
+ "test_memory_recall.py",
205
+ "test_metrics.py",
206
+ "test_multi_chain.py",
207
+ "test_multimodal.py",
208
+ "test_negotiation.py",
209
+ "test_orchestration.py",
210
+ "test_orchestration_decoupled.py",
211
+ "test_p3_p5_hardening.py",
212
+ "test_parallel_dispatch.py",
213
+ "test_pipeline.py",
214
+ "test_plan_visible.py",
215
+ "test_planner.py",
216
+ "test_policy_gate.py",
217
+ "test_reasoner.py",
218
+ "test_release_check.py",
219
+ "test_resume_checkpoint.py",
220
+ "test_routing.py",
221
+ "test_scheduler.py",
222
+ "test_search.py",
223
+ "test_semantic.py",
224
+ "test_sessions.py",
225
+ "test_settings.py",
226
+ "test_shadow_learning.py",
227
+ "test_shared_write.py",
228
+ "test_envfile.py",
229
+ "test_secrets.py",
230
+ "test_skill_taint_gate.py",
231
+ "test_skills.py",
232
+ "test_stats_and_events.py",
233
+ "test_streaming.py",
234
+ "test_supervisor_pipeline.py",
235
+ "test_verify_evidence.py",
236
+ "test_supervisor_triage.py",
237
+ "test_taint.py",
238
+ "test_task_stream.py",
239
+ "test_thinking_sse.py",
240
+ "test_thinking_stream.py",
241
+ "test_tool_center.py",
242
+ "test_tool_parallel.py",
243
+ "test_tool_params.py",
244
+ "test_tool_use.py",
245
+ "test_toplevel_concurrency.py",
246
+ "test_tracing.py",
247
+ "test_truth_crystallizer.py",
248
+ "test_truth_flow.py",
249
+ "test_url_policy.py",
250
+ "test_version_sync.py",
251
+ "test_web_trigger.py",
252
+ ]
253
+ addopts = "-q"
254
+
255
+ [tool.coverage.run]
256
+ source = ["foxclaw"]
257
+ # 全量回归走 run_all.py(每文件独立子进程),coverage 需 parallel 模式:每个子进程各写一份
258
+ # .coverage,最后 `coverage combine` 合并成基线。patch=["subprocess"] 让 coverage run 设置
259
+ # COVERAGE_PROCESS_CONFIG 环境变量,子进程经 coverage 的 sitecustomize(.pth)自动测量,
260
+ # 无需逐个子进程手动包 coverage run(run_all.py 的 subprocess 用 dict(os.environ,...) 继承,链路完整)。
261
+ parallel = true
262
+ patch = ["subprocess"]
263
+
264
+ [tool.coverage.report]
265
+ show_missing = true
@@ -0,0 +1,123 @@
1
+ # Foxclaw Skill 实现 — AHS 标准的参考落地
2
+
3
+ > 本目录是 **Agent Harness Skills (AHS) v1.0 标准在 Foxclaw 中的具体实现**。
4
+ >
5
+ > - **公用标准**(`/agent-harness-skills/`):厂商无关的抽象规范,定义"应该怎样"。
6
+ > - **本实现**(本目录):把抽象规范**绑定到 Foxclaw 的真实模块**,定义"在 Foxclaw 里实际怎么做"。
7
+ >
8
+ > 两者是"规范 vs 参考实现"的关系。读标准看 `/agent-harness-skills/`,读落地看这里。
9
+
10
+ ---
11
+
12
+ ## 标准 → Foxclaw 实现 的映射
13
+
14
+ AHS 标准里的每个抽象概念,在 Foxclaw 里都有一个**真实模块**承接。这张表是本实现的核心:
15
+
16
+ | AHS 抽象概念 | Foxclaw 真实模块 | 文件 |
17
+ |-------------|----------------|------|
18
+ | agent / executor | 五个认知 Agent(主管/财务/行政/办公/助手) | `foxclaw/agents/agents.py` |
19
+ | skill-guard(守门·四阶段权限) | `permission.py::evaluate`(四阶段);V2 后经统一门 **PolicyGate** 归一 | `foxclaw/skills/permission.py` `foxclaw/kernel/policy_gate.py` |
20
+ | 认知护栏(标准之外) | Harness 三维漂移检测(语义/工具/范围) | `foxclaw/harness/harness.py` |
21
+ | skill-memory(记忆) | HMR v2.0 双层记忆适配器 | `foxclaw/core/memory_adapter.py` |
22
+ | 审计追踪 | ThoughtChain 思维链 + HookManager.audit_log(有界) | `foxclaw/core/thought_chain.py` `foxclaw/skills/lifecycle.py` |
23
+ | execution-contract(契约) | `SkillSpec` / `SkillResult` 数据结构 | `foxclaw/skills/__init__.py` |
24
+ | skill-router(路由) | **P1-2 统一 planner** 打分 + 主管分诊 + 管线内 `stage_route`(A) | `foxclaw/planning/planner.py` `foxclaw/skills/pipeline.py` `foxclaw/agents/agents.py` |
25
+ | planner(规划) | **P1-2 确定性拆解** `plan()` + 管线 `stage_plan`(A) | `foxclaw/planning/planner.py` `foxclaw/skills/pipeline.py` |
26
+ | skill-composition(编排) | skill 级 `compose`(+回滚补偿)+ Agent 级 Orchestration(P3 解耦) | `foxclaw/skills/pipeline.py` `foxclaw/orchestration/` |
27
+ | 断路器 / 循环检测 | `CircuitBreaker` + `ToolLoopDetector`(skill 层横切) | `foxclaw/skills/lifecycle.py` `foxclaw/harness/loop_detection.py` |
28
+ | 管线内工具调用(A 方案) | Agent 在认知管线内受 PolicyGate 治理地自主用工具 | `foxclaw/pipeline/cognitive_pipeline.py` `foxclaw/agents/base.py` |
29
+ | 领域 skill | 财务/学习/行程内核 | `foxclaw/finance/` `foxclaw/learning/` `foxclaw/itinerary/` |
30
+ | 模型调用 | 多模型路由(DeepSeek 等) | `foxclaw/core/model_router.py` |
31
+
32
+ ---
33
+
34
+ ## 六个 skill 在 Foxclaw 里的具体落地
35
+
36
+ ### 1. execution-contract → Foxclaw 的 SkillSpec/SkillResult
37
+
38
+ 标准定义了抽象的 SkillInput/SkillOutput。**Foxclaw 用 `foxclaw/skills/__init__.py` 里的
39
+ `SkillSpec` 和 `SkillResult` 落地**:
40
+ - `SkillResult` 字段:`skill_id/success/output/status/message/loop_warning`——**无 trace_node_id**;审计追踪由 ThoughtChain(Agent `_think` 写节点)+ HookManager.audit_log 独立承担,不塞进结果结构
41
+ - `trust_level` → **`SkillSpec.trust_level()` 单一真源**(`permission.evaluate` 直接调用它)按 kind(local/mcp/web_api)推断,SkillAdapter 据此对 mcp 结果降级(原 `permission.TRUST_LEVEL` 双真源 dict 已删,见 V3·P6)
42
+ - 输入校验 → `permission.evaluate` **Stage1** 对 `SkillSpec.params` 执行(经 `invoke → PolicyGate.check_action → evaluate`)
43
+
44
+ > 差异:标准是 schema 描述;Foxclaw 是可运行的 Python dataclass + 真实校验代码。
45
+
46
+ ### 2. skill-router → 主管 Agent 的分诊
47
+
48
+ 标准定义了三步打分算法。**P1-2 后:该算法(否定过滤 0.8×触发命中 + 0.2×描述匹配)统一在 `foxclaw/planning/planner.py::trigger_route`,主管分派 / `skills/pipeline.py::route` / 管线 `stage_route` 都复用**:
49
+ - 否定词检测 → 统一原语 `planner.is_negated`;主管另有 `_is_meta` 判元问题
50
+ - 主管路由 `SupervisorAgent._route()` 基于 `ROUTING_KEYWORDS`,选定后 `subagents[target].run_task()` 分派
51
+ - **A 方案**:管线内 `stage_route` 用同一 `route` 选主 **skill** 写 `ctx.route`(opt-in,默认关)
52
+
53
+ > 差异:标准是"选一个 skill_id";Foxclaw 有两条落地——① 主管把任务分派给**真实 Agent 实例**;② 管线内直接选 **skill**。共用 `planning.planner` 打分引擎。
54
+
55
+ ### 3. planner → 主管 Agent 的任务分解
56
+
57
+ 标准定义了结构化执行计划。**P1-2 后:任务拆分由确定性统一 planner 承担**:
58
+ - `skills/pipeline.py::plan` 用 `planning/planner.py` 的 `split_on`/`PARALLEL_TRIGGERS`/`SPLIT_MARKERS` 把任务拆成 Plan/PlanTask(并行/顺序 + 依赖),不再纯靠 LLM 猜结构
59
+ - 管线 `stage_plan` 把任务结构写入 `ctx.plan`(informational)
60
+ - 每子任务经 `route` 映射到 skill / 领域 Agent;assumptions/risks 写入 ThoughtChain 节点
61
+
62
+ > 差异:标准是 JSON 计划模板;Foxclaw 是**确定性 P1-2 拆结构** + 需要生成性内容时另调真实 LLM + 写入真实思维链。
63
+
64
+ ### 4. skill-composition → 主管编排 + Orchestration 引擎
65
+
66
+ 标准定义了串行/并行/混合编排。**Foxclaw 有两层落地**:
67
+ - **skill 级**:`skills/pipeline.py::compose` 按计划串行执行各 skill,关键路径失败 → 逆序回滚有副作用步骤(`_rollback` compensate/需人工)
68
+ - **Agent 级**:`foxclaw/orchestration/` 跨 Agent 路由(`/api/orchestration/request` → `route_request`,P3 已解耦通用)+ 态势聚合(`/api/orchestration/situation`)
69
+ - 断路器 → **`CircuitBreaker`(`skills/lifecycle.py`,skill 层构件,非 Harness)**
70
+
71
+ > 差异:标准是编排协议;Foxclaw 是 skill 级 compose(带回滚补偿)+ Agent 级真实消息路由/态势引擎。
72
+
73
+ ### 5. skill-guard → Foxclaw 的 Harness(这是最核心的落地)⭐
74
+
75
+ 标准定义了四阶段权限管线。**四阶段全部实现在 `foxclaw/skills/permission.py::evaluate`**(不是 harness.py——harness 是下面另一回事的三维漂移检测)。V2 后经统一门 `PolicyGate.check_action` 调用:
76
+
77
+ | 标准的四阶段 | Foxclaw 的实现(全在 `permission.py::evaluate`) |
78
+ |-------------|--------------|
79
+ | Stage1 validate | 校验 `SkillSpec.params` 必填项 |
80
+ | Stage2 deny>ask>allow | `PermissionRules` 规则匹配(deny 铁律不可覆盖) |
81
+ | Stage3 capability | `side_effect`/`destructive`/`external`/readonly,Fail-closed |
82
+ | Stage4 confirm | 有副作用/external/ask 规则且未确认 → 需确认 |
83
+
84
+ > **V2 统一门(①Step4)**:动作权限(上表)与推理漂移(下方 Harness)归一到 `foxclaw/kernel/policy_gate.py` 的一套 `Verdict` + 统一 `policy.decision.*` 审计事件,底层仍是同一次 evaluate/check,行为逐字不变。
85
+ > **V2 管线内 dispatch(A 方案)**:Agent 在认知管线内自主用工具时,`stage_act` 同样经此四阶段——只读自动、有副作用挂起 `needs_confirmation`(dispatch 前拦截 ⇒ 零副作用)。
86
+
87
+ **Foxclaw 独有的增强(标准之外的护城河)——注意:这是 Harness,与上面的四阶段权限是两回事:**
88
+ - **三维漂移检测**(语义/工具/范围)→ 这是标准没有的"认知护栏",防 Agent 跑偏
89
+ - **Shadow 校准模式** → 新 Agent 前 N 轮只观测不拦截,自动校准阈值
90
+ - **调度层豁免**(`block_on_semantic` + `IS_ROUTER`)→ 主管豁免语义拦截
91
+ - **Policy 自学习** → 重复漂移模式自动沉淀为规则
92
+
93
+ > 差异:标准 guard 只管"工具权限";Foxclaw Harness = 工具权限 + **认知漂移检测**(Foxclaw 原创)。
94
+ > 这正是 Foxclaw 作为"认知型 Agent OS"区别于工具型 Agent 的核心价值。
95
+
96
+ ### 6. skill-memory → HMR 双层记忆
97
+
98
+ 标准定义了后端无关的记忆协议。**Foxclaw 用 HMR(`memory_adapter.py`)落地**:
99
+ - 召回 → `_recall_memory(task)` 真实调 HMR 向量检索
100
+ - 注入 → 召回结果写入 Agent 的 messages 上下文
101
+ - 提取持久化 → 办公 Agent 的 `_store_memory` 真实写入 HMR
102
+ - private/shared 双层 → Foxclaw HMR 的真实双层架构(by_agent 分布)
103
+ - embedding → 真实的 TF-IDF 降级 / sentence-transformers / OpenAI embedding
104
+
105
+ > 差异:标准是"后端无关协议";Foxclaw 是绑定 HMR v2.0 的真实记忆引擎,带衰减和双层。
106
+
107
+ ---
108
+
109
+ ## 一句话总结
110
+
111
+ > **公用版 AHS 定义"Agent Harness 的 skill 层应该长什么样"(抽象规范);
112
+ > Foxclaw 版把它落到"用 HMR 做记忆、用 Harness 三维漂移做守门、用三 Agent(主管/财务/办公学习)做路由编排、
113
+ > 用 ThoughtChain 做审计"的真实实现上。**
114
+ >
115
+ > Foxclaw 实现不仅满足标准,还在 guard 维度**超出标准**(增加了认知漂移检测这一护城河)。
116
+
117
+ ---
118
+
119
+ ## 对照阅读
120
+
121
+ - 想了解**标准本身** → 读 `/agent-harness-skills/README_CN.md`
122
+ - 想了解**Foxclaw 怎么实现标准** → 读本文件
123
+ - 想看**实现代码** → 见上方映射表里的真实模块文件
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: execution-contract
3
+ version: "1.0-foxclaw"
4
+ implements: agent-harness-skills/execution-contract
5
+ description: Foxclaw 实现版契约。把 AHS 标准的 IO 结构落地到 SkillSpec/SkillResult 数据结构。
6
+ bound_modules:
7
+ - foxclaw/skills/__init__.py (SkillSpec / SkillResult / SkillAdapter)
8
+ - foxclaw/skills/permission.py (输入校验 Stage1)
9
+ side_effect: read
10
+ trust_level: high
11
+ ---
12
+
13
+ # Execution Contract(Foxclaw 实现版)
14
+
15
+ > AHS 标准 `execution-contract` 在 Foxclaw 的落地。标准定义 IO schema,本文件定义 Foxclaw 的真实数据结构。
16
+
17
+ ## 标准 → Foxclaw 真实落地
18
+
19
+ | AHS 标准 | Foxclaw 实现 | 代码位置 |
20
+ |---------|------------|---------|
21
+ | SkillInput | `SkillAdapter.invoke` 的入参 | `skills/__init__.py` |
22
+ | SkillOutput | `SkillResult` dataclass(字段:`skill_id/success/output/status/message/loop_warning`) | `skills/__init__.py: SkillResult` |
23
+ | 审计追踪 | **不在 SkillResult 里**——由 ThoughtChain(Agent `_think` 写节点)+ SkillAdapter 的 `HookManager.audit_log`(有界)双重承担 | `core/thought_chain.py`、`skills/lifecycle.py` |
24
+ | trust_level | **`SkillSpec.trust_level()` 单一真源**(`permission.evaluate` 直接调用)按 kind(local/web_api/mcp)推断,`SkillAdapter` 据此对 mcp 结果降级(原 `permission.TRUST_LEVEL` 已删,见 V3·P6) | `skills/__init__.py`、`skills/permission.py` |
25
+ | 输入校验 | `permission.evaluate` **Stage1** 校验 `SkillSpec.params`(经 `invoke → PolicyGate.check_action → evaluate`) | `skills/permission.py: evaluate` |
26
+
27
+ ## 关键差异
28
+
29
+ > 标准是 schema 描述;Foxclaw 是可运行的 Python dataclass + 真实校验代码。
30
+ > 注:`SkillResult` **无 `trace_node_id` 字段**——审计追踪独立由 ThoughtChain + HookManager 承担,不塞进结果结构。
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: general-assistant
3
+ version: "1.0-foxclaw"
4
+ builtin: true
5
+ side_effect: read
6
+ description: 通用助理技能。信息整理、汇总、跨域转述、沟通措辞、待办跟进。原是独立的"助手 Agent",现下放为指令技能,由主管/办公在任何 Agent 命中"整理/汇总/沟通"类任务时自动注入。
7
+ triggers: [整理, 汇总, 汇总一下, 纪要, 邮件, 协助, 沟通, 联系, 转达, 待办, 跟进, 汇报]
8
+ ---
9
+
10
+ # General Assistant(通用助理)
11
+
12
+ > 原 `AssistantAgent` 下放而成。它不再是一个常驻 Agent —— 谁来干这件事,取决于任务流向哪个
13
+ > Agent(主管统筹、办公学习、财务),技能只负责"怎么干"。
14
+
15
+ ## 什么时候用
16
+
17
+ - 用户给了一堆散乱材料(多封邮件、多个文件、几段对话),要一个结论或一份纪要;
18
+ - 要把某个领域的产出转述给别的场景(财务结论 → 给同事的说明;学习笔记 → 汇报材料);
19
+ - 需要一段得体的对外措辞(邮件、消息、回复),而不是继续深挖领域内容;
20
+ - 需要把已经聊过的事收成待办清单并跟进。
21
+
22
+ ## 做法
23
+
24
+ 1. **先分清事实与结论**:事实必须有出处(用户原话、文件、工具返回);结论要能指出它由哪几条事实推出。
25
+ 2. **一段一段收敛**:材料 → 要点(每条一行) → 归并同类 → 排序(重要/紧急) → 成稿。
26
+ 3. **跨域转述保真**:引用数字时带单位和口径(含不含税、哪个时间段),不四舍五入到失真。
27
+ 4. **措辞**默认简洁、无套话;对外的邮件给主题行 + 正文,不给"注意事项"说教。
28
+ 5. 收尾给一个**可执行**的下一步(谁、做什么、何时),没有就明说"无需跟进"。
29
+
30
+ ## 硬边界
31
+
32
+ - 材料里没有的事不补;补了要标「推测」。
33
+ - 不把"我建议"写成"已经安排"——没有执行凭据就不声称已完成。
34
+ - 涉及付款、发送、删除等有副作用的动作,交回主管走确认流程,不要在本技能里直接做。
@@ -0,0 +1,33 @@
1
+ ---
2
+ name: planner
3
+ version: "1.0-foxclaw"
4
+ implements: agent-harness-skills/planner
5
+ description: Foxclaw 实现版规划。把 AHS 标准的任务分解落地到主管 Agent 的 plan 逻辑。
6
+ bound_modules:
7
+ - foxclaw/planning/planner.py (★ P1-2 统一拆分原语:split_on / PARALLEL_TRIGGERS / SPLIT_MARKERS)
8
+ - foxclaw/skills/pipeline.py (plan:确定性拆解为 Plan/PlanTask)
9
+ - foxclaw/pipeline/cognitive_pipeline.py (stage_plan:管线内结构规划)
10
+ - foxclaw/agents/agents.py (SupervisorAgent._plan_task / run_task)
11
+ side_effect: read
12
+ trust_level: high
13
+ ---
14
+
15
+ # Planner(Foxclaw 实现版)
16
+
17
+ > AHS 标准 `planner` 在 Foxclaw 的落地。标准定义计划结构,本文件定义 Foxclaw 用主管真实 LLM 生成。
18
+
19
+ ## 标准 → Foxclaw 真实落地
20
+
21
+ > ⚠️ **P1-2 后:任务拆分(并行/顺序连接词、`split_on`)由确定性统一 planner 承担**——`skills/pipeline.py::plan` 与管线 `stage_plan` 都用 `foxclaw/planning/planner.py` 的 `PARALLEL_TRIGGERS`/`SPLIT_MARKERS`,不再纯靠 LLM 猜结构。
22
+
23
+ | AHS 标准 | Foxclaw 实现 | 代码位置 |
24
+ |---------|------------|---------|
25
+ | 出执行计划(拆结构) | `plan(task)` 确定性拆成 Plan/PlanTask(并行/顺序 + 依赖) | `skills/pipeline.py: plan` |
26
+ | 拆分原语 | `split_on` + 并行/顺序连接词表 | `planning/planner.py` |
27
+ | 子任务→执行者 | 每子任务经 `route` 映射到 skill / 领域 Agent | `skills/pipeline.py: route`、`agents.py: _route` |
28
+ | 管线内结构化 | `stage_plan` 把任务结构写入 `ctx.plan`(informational) | `pipeline/cognitive_pipeline.py: stage_plan` |
29
+ | assumptions/risks | 写入 Agent 的 ThoughtChain 节点 | `core/thought_chain.py` |
30
+
31
+ ## 关键差异
32
+
33
+ > 标准是 JSON 计划模板;Foxclaw 是**确定性 P1-2 planner 拆结构**(可并行/顺序 + 依赖)+ 主管对需要生成性内容时另调真实 LLM + 写入真实 ThoughtChain。
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: schedule-itinerary
3
+ version: "1.0-foxclaw"
4
+ builtin: true
5
+ side_effect: read
6
+ description: 日程行程技能。排期、会议、出差、路线与冲突检查、差旅预算协商。原是独立的"行政 Agent",现下放为指令技能,由办公学习 Agent 在命中日程类任务时注入;行程内核(ItineraryRuntime)仍由代码提供真实路线与冲突数据。
7
+ triggers: [日程, 行程, 会议, 出差, 预约, 日历, 路线, 提醒, 排期, 时间冲突, 几点]
8
+ ---
9
+
10
+ # Schedule & Itinerary(日程行程)
11
+
12
+ > 原 `AdminAgent` 下放而成。**能力分两层**:真实路线/冲突由 `ItineraryRuntime` 算(代码),
13
+ > 本技能只规定"怎么排、怎么问、怎么不硬闯"。
14
+
15
+ ## 什么时候用
16
+
17
+ - 用户要给一段时间内的安排(今天/本周/出差几天)定顺序;
18
+ - 要判断"这个会议塞不塞得进去",或两个安排是否撞车;
19
+ - 出差需要路线、耗时、可达性判断;
20
+ - 差旅预算被财务拒了,需要降标准重报。
21
+
22
+ ## 做法
23
+
24
+ 1. **先取约束,再排**:硬约束(截止时间、必须到场、交通耗时)优先于软偏好(上午效率高)。
25
+ 2. **冲突必须查,不许假设**:已有行程与待排时间相差 1 小时内即视为可能冲突,标出来让用户定。
26
+ 3. **给方案而不是给日程表**:最多 2 个方案,各自代价(早起的代价、多花的时间)写清楚。
27
+ 4. **预算协商一轮一降、有下限**:每轮降到上一轮的 75%,不低于原始申请的 60%;到下限就认输
28
+ 交人决定,不贴着红线反复试探。
29
+ 5. 输出用时间轴(时间 → 事项 → 地点/通勤),不要散文。
30
+
31
+ ## 硬边界
32
+
33
+ - 内核没挂载/没有路点时,明说"按估算排",不要把估算讲成实际路线。
34
+ - 不替用户对外承诺时间;排完是"建议",发出邀请属副作用动作,交回主管确认。
35
+ - 查不到(地图/接口失败)就说查不到,不猜通勤时长。
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: skill-composition
3
+ version: "1.0-foxclaw"
4
+ implements: agent-harness-skills/skill-composition
5
+ description: Foxclaw 实现版编排。把 AHS 标准的多 skill 协作落地到主管编排 + Orchestration 引擎。
6
+ bound_modules:
7
+ - foxclaw/skills/pipeline.py (★ compose:多 skill 串行执行 + 逆序回滚补偿)
8
+ - foxclaw/skills/lifecycle.py (CircuitBreaker 断路器)
9
+ - foxclaw/orchestration/ (跨 Agent 编排:route_request / gather_situation)
10
+ - foxclaw/agents/agents.py (SupervisorAgent)
11
+ side_effect: read
12
+ trust_level: high
13
+ ---
14
+
15
+ # Skill Composition(Foxclaw 实现版)
16
+
17
+ > AHS 标准 `skill-composition` 在 Foxclaw 的落地。标准定义编排协议,本文件定义 Foxclaw 用真实编排引擎。
18
+
19
+ ## 标准 → Foxclaw 真实落地
20
+
21
+ | AHS 标准 | Foxclaw 实现 | 代码位置 |
22
+ |---------|------------|---------|
23
+ | 多 skill 编排 | `compose(plan)` 按计划串行执行各 skill | `skills/pipeline.py: compose` |
24
+ | 失败回滚 | 关键路径失败 → 逆序回滚有副作用步骤(compensate/需人工) | `skills/pipeline.py: _rollback` |
25
+ | 跨 Agent 协作 | `/api/orchestration/request` → `Orchestrator.route_request`(P3 已解耦、通用) | `api.py:571`、`orchestration/` |
26
+ | 全局态势 | `/api/orchestration/situation` → `gather_situation` | `api.py:554`、`orchestration/` |
27
+ | 断路器 | `CircuitBreaker`(三态机,每 skill 独立) | `skills/lifecycle.py: CircuitBreaker` |
28
+
29
+ ## 关键差异
30
+
31
+ > 标准是编排协议;Foxclaw 有两层:**skill 级** `compose`(多 skill + 回滚补偿,`skills/pipeline.py`)+ **Agent 级** orchestration(跨 Agent 路由/态势,P3 已去领域硬编码)。断路器是 **skill 层**构件(`lifecycle.py`),不属 Harness。