foxclaw 0.1.0 → 0.1.3

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 (514) hide show
  1. package/README.md +54 -29
  2. package/bin/foxclaw.cjs +51 -0
  3. package/index.js +4 -10
  4. package/package.json +46 -38
  5. package/python/.dockerignore +35 -0
  6. package/python/.env.example +173 -0
  7. package/python/.gitattributes +46 -0
  8. package/python/.github/workflows/ci.yml +167 -0
  9. package/python/.github/workflows/release.yml +183 -0
  10. package/python/CHANGELOG.md +57 -0
  11. package/python/CHANGELOG_CN.md +57 -0
  12. package/python/Dockerfile +64 -0
  13. package/python/LICENSE +21 -0
  14. package/python/MANIFEST.in +14 -0
  15. package/python/README.md +201 -0
  16. package/python/README_CN.md +336 -0
  17. package/python/bench/bm25_audit.py +186 -0
  18. package/python/bench/bm25_regression.py +177 -0
  19. package/python/bench/bm25_stress.py +155 -0
  20. package/python/bench/cd_audit.py +215 -0
  21. package/python/bench/chaos.py +140 -0
  22. package/python/bench/concurrency.py +103 -0
  23. package/python/bench/e2e_real_models.py +94 -0
  24. package/python/bench/llm_retry_test.py +241 -0
  25. package/python/bench/load_test.py +193 -0
  26. package/python/bench/vector_ivf_upgrade.py +128 -0
  27. package/python/docs/CHANNELS.md +195 -0
  28. package/python/docs/GOVERNANCE.md +164 -0
  29. package/python/docs/RELEASE.md +110 -0
  30. package/python/docs/RUN.md +75 -0
  31. package/python/docs/RUN_CN.md +121 -0
  32. package/python/docs//351/205/215/347/275/256/346/214/207/345/215/227.md +152 -0
  33. package/python/evals/__init__.py +0 -0
  34. package/python/evals/governance/README.md +61 -0
  35. package/python/evals/governance/__init__.py +0 -0
  36. package/python/evals/governance/cases.py +115 -0
  37. package/python/evals/governance/compare_embeddings.py +94 -0
  38. package/python/evals/governance/convergence.svg +11 -0
  39. package/python/evals/governance/report.json +371 -0
  40. package/python/evals/governance/run_evals.py +368 -0
  41. package/python/examples/governance_middleware_demo.py +72 -0
  42. package/python/examples/langgraph_governance_demo.py +104 -0
  43. package/python/examples/sample_itinerary.csv +6 -0
  44. package/python/examples/sample_knowledge.csv +9 -0
  45. package/python/examples/sample_transactions.csv +14 -0
  46. package/python/foxclaw/__init__.py +408 -0
  47. package/python/foxclaw/agents/__init__.py +12 -0
  48. package/python/foxclaw/agents/agents.py +35 -0
  49. package/python/foxclaw/agents/base.py +794 -0
  50. package/python/foxclaw/agents/impl/__init__.py +1 -0
  51. package/python/foxclaw/agents/impl/_helpers.py +70 -0
  52. package/python/foxclaw/agents/impl/finance.py +231 -0
  53. package/python/foxclaw/agents/impl/office.py +350 -0
  54. package/python/foxclaw/agents/impl/supervisor.py +592 -0
  55. package/python/foxclaw/agents/mixins/_context.py +128 -0
  56. package/python/foxclaw/agents/mixins/augment.py +143 -0
  57. package/python/foxclaw/agents/mixins/llm.py +67 -0
  58. package/python/foxclaw/agents/mixins/memory.py +41 -0
  59. package/python/foxclaw/agents/mixins/preference.py +131 -0
  60. package/python/foxclaw/agents/mixins/prompt.py +71 -0
  61. package/python/foxclaw/agents/mixins/skillbox.py +58 -0
  62. package/python/foxclaw/agents/mixins/tool_exec.py +417 -0
  63. package/python/foxclaw/api/__init__.py +224 -0
  64. package/python/foxclaw/api/_state.py +43 -0
  65. package/python/foxclaw/api/bootstrap.py +96 -0
  66. package/python/foxclaw/api/middleware.py +294 -0
  67. package/python/foxclaw/api/routes/ahs.py +404 -0
  68. package/python/foxclaw/api/routes/attachments.py +116 -0
  69. package/python/foxclaw/api/routes/browser.py +35 -0
  70. package/python/foxclaw/api/routes/domain.py +306 -0
  71. package/python/foxclaw/api/routes/knowledge.py +145 -0
  72. package/python/foxclaw/api/routes/llm_admin.py +449 -0
  73. package/python/foxclaw/api/routes/memory.py +105 -0
  74. package/python/foxclaw/api/routes/orchestration.py +39 -0
  75. package/python/foxclaw/api/routes/recovery.py +44 -0
  76. package/python/foxclaw/api/routes/review.py +266 -0
  77. package/python/foxclaw/api/routes/search.py +33 -0
  78. package/python/foxclaw/api/routes/system.py +311 -0
  79. package/python/foxclaw/api/routes/task.py +263 -0
  80. package/python/foxclaw/api/routes/ws.py +64 -0
  81. package/python/foxclaw/api/spine.py +52 -0
  82. package/python/foxclaw/browser/__init__.py +13 -0
  83. package/python/foxclaw/browser/action/__init__.py +1 -0
  84. package/python/foxclaw/browser/action/action_executor.py +50 -0
  85. package/python/foxclaw/browser/action/action_types.py +44 -0
  86. package/python/foxclaw/browser/action/action_verifier.py +68 -0
  87. package/python/foxclaw/browser/action/url_policy.py +143 -0
  88. package/python/foxclaw/browser/adapter/__init__.py +1 -0
  89. package/python/foxclaw/browser/adapter/base_adapter.py +23 -0
  90. package/python/foxclaw/browser/adapter/web_adapter.py +46 -0
  91. package/python/foxclaw/browser/driver/__init__.py +1 -0
  92. package/python/foxclaw/browser/driver/base_driver.py +61 -0
  93. package/python/foxclaw/browser/driver/playwright_driver.py +170 -0
  94. package/python/foxclaw/browser/perception/__init__.py +1 -0
  95. package/python/foxclaw/browser/perception/dom_extractor.py +42 -0
  96. package/python/foxclaw/browser/perception/element_indexer.py +56 -0
  97. package/python/foxclaw/browser/perception/semantic_reducer.py +33 -0
  98. package/python/foxclaw/browser/perception/snapshot.py +29 -0
  99. package/python/foxclaw/browser/service.py +144 -0
  100. package/python/foxclaw/browser/session/__init__.py +1 -0
  101. package/python/foxclaw/browser/session/session_manager.py +57 -0
  102. package/python/foxclaw/capability/__init__.py +12 -0
  103. package/python/foxclaw/capability/embedding_service.py +65 -0
  104. package/python/foxclaw/channels/__init__.py +138 -0
  105. package/python/foxclaw/channels/discord.py +175 -0
  106. package/python/foxclaw/channels/dispatcher.py +179 -0
  107. package/python/foxclaw/channels/feishu.py +215 -0
  108. package/python/foxclaw/channels/openclaw_bridge.py +151 -0
  109. package/python/foxclaw/channels/signing.py +187 -0
  110. package/python/foxclaw/channels/telegram.py +120 -0
  111. package/python/foxclaw/channels/weixin.py +215 -0
  112. package/python/foxclaw/cli.py +183 -0
  113. package/python/foxclaw/cognitive/__init__.py +4 -0
  114. package/python/foxclaw/cognitive/reasoner.py +81 -0
  115. package/python/foxclaw/cognitive/state.py +141 -0
  116. package/python/foxclaw/core/__init__.py +9 -0
  117. package/python/foxclaw/core/audit_chain.py +131 -0
  118. package/python/foxclaw/core/audit_sink.py +100 -0
  119. package/python/foxclaw/core/compaction.py +265 -0
  120. package/python/foxclaw/core/config.py +65 -0
  121. package/python/foxclaw/core/confirm_nonce.py +151 -0
  122. package/python/foxclaw/core/dispatch.py +27 -0
  123. package/python/foxclaw/core/envfile.py +48 -0
  124. package/python/foxclaw/core/failure_policy.py +142 -0
  125. package/python/foxclaw/core/gateway.py +81 -0
  126. package/python/foxclaw/core/governance_audit.py +171 -0
  127. package/python/foxclaw/core/idempotency.py +282 -0
  128. package/python/foxclaw/core/injection_guard.py +202 -0
  129. package/python/foxclaw/core/memory_adapter.py +489 -0
  130. package/python/foxclaw/core/metrics.py +88 -0
  131. package/python/foxclaw/core/model_router.py +985 -0
  132. package/python/foxclaw/core/paths.py +103 -0
  133. package/python/foxclaw/core/recovery.py +349 -0
  134. package/python/foxclaw/core/scheduler.py +141 -0
  135. package/python/foxclaw/core/secrets.py +131 -0
  136. package/python/foxclaw/core/sessions.py +155 -0
  137. package/python/foxclaw/core/settings.py +414 -0
  138. package/python/foxclaw/core/shared_write.py +186 -0
  139. package/python/foxclaw/core/steering_queue.py +154 -0
  140. package/python/foxclaw/core/system_bus.py +84 -0
  141. package/python/foxclaw/core/thought_chain.py +316 -0
  142. package/python/foxclaw/core/token_meter.py +231 -0
  143. package/python/foxclaw/core/tools.py +164 -0
  144. package/python/foxclaw/core/tracing.py +375 -0
  145. package/python/foxclaw/core/truth_pipeline.py +110 -0
  146. package/python/foxclaw/core/update_check.py +149 -0
  147. package/python/foxclaw/core/vec_recall_adapter.py +477 -0
  148. package/python/foxclaw/core/verify.py +173 -0
  149. package/python/foxclaw/core/web_search.py +218 -0
  150. package/python/foxclaw/finance/__init__.py +15 -0
  151. package/python/foxclaw/finance/evidence.py +149 -0
  152. package/python/foxclaw/finance/fx.py +98 -0
  153. package/python/foxclaw/finance/graph.py +179 -0
  154. package/python/foxclaw/finance/models.py +146 -0
  155. package/python/foxclaw/finance/nlparse.py +515 -0
  156. package/python/foxclaw/finance/policy.py +301 -0
  157. package/python/foxclaw/finance/reasoner.py +121 -0
  158. package/python/foxclaw/finance/reasoning.py +319 -0
  159. package/python/foxclaw/finance/reconcile.py +175 -0
  160. package/python/foxclaw/finance/runtime.py +500 -0
  161. package/python/foxclaw/governance/__init__.py +24 -0
  162. package/python/foxclaw/governance/middleware.py +176 -0
  163. package/python/foxclaw/harness/__init__.py +17 -0
  164. package/python/foxclaw/harness/_base.py +66 -0
  165. package/python/foxclaw/harness/_policy.py +340 -0
  166. package/python/foxclaw/harness/drift.py +77 -0
  167. package/python/foxclaw/harness/event_bus.py +28 -0
  168. package/python/foxclaw/harness/harness.py +358 -0
  169. package/python/foxclaw/harness/loop_detection.py +145 -0
  170. package/python/foxclaw/itinerary/__init__.py +10 -0
  171. package/python/foxclaw/itinerary/amap_client.py +114 -0
  172. package/python/foxclaw/itinerary/models.py +80 -0
  173. package/python/foxclaw/itinerary/reasoner.py +96 -0
  174. package/python/foxclaw/itinerary/reasoning.py +168 -0
  175. package/python/foxclaw/itinerary/runtime.py +144 -0
  176. package/python/foxclaw/kernel/__init__.py +13 -0
  177. package/python/foxclaw/kernel/capabilities.py +72 -0
  178. package/python/foxclaw/kernel/policy_gate.py +108 -0
  179. package/python/foxclaw/kernel/process_manager.py +186 -0
  180. package/python/foxclaw/kernel/scheduler.py +125 -0
  181. package/python/foxclaw/kernel/sentinel.py +443 -0
  182. package/python/foxclaw/kernel/sentinel_client.py +243 -0
  183. package/python/foxclaw/kernel/spine.py +97 -0
  184. package/python/foxclaw/knowledge/__init__.py +360 -0
  185. package/python/foxclaw/knowledge/truth_crystallizer.py +89 -0
  186. package/python/foxclaw/learning/__init__.py +12 -0
  187. package/python/foxclaw/learning/knowledge_graph.py +144 -0
  188. package/python/foxclaw/learning/models.py +93 -0
  189. package/python/foxclaw/learning/reasoner.py +67 -0
  190. package/python/foxclaw/learning/runtime.py +351 -0
  191. package/python/foxclaw/learning/spaced_repetition.py +91 -0
  192. package/python/foxclaw/mcp_server.py +188 -0
  193. package/python/foxclaw/orchestration/__init__.py +167 -0
  194. package/python/foxclaw/pipeline/__init__.py +23 -0
  195. package/python/foxclaw/pipeline/cognitive_pipeline.py +429 -0
  196. package/python/foxclaw/pipeline/stage_meta.py +21 -0
  197. package/python/foxclaw/pipeline/supervisor_stages.py +201 -0
  198. package/python/foxclaw/planning/__init__.py +17 -0
  199. package/python/foxclaw/planning/llm_planner.py +232 -0
  200. package/python/foxclaw/planning/planner.py +94 -0
  201. package/python/foxclaw/search/__init__.py +24 -0
  202. package/python/foxclaw/search/agent_port.py +190 -0
  203. package/python/foxclaw/search/evidence.py +109 -0
  204. package/python/foxclaw/search/external_search.py +50 -0
  205. package/python/foxclaw/search/hkc_read_port.py +60 -0
  206. package/python/foxclaw/search/internal_search.py +71 -0
  207. package/python/foxclaw/search/models.py +127 -0
  208. package/python/foxclaw/search/planner.py +44 -0
  209. package/python/foxclaw/search/retriever.py +39 -0
  210. package/python/foxclaw/search/runtime.py +127 -0
  211. package/python/foxclaw/search/strategy.py +44 -0
  212. package/python/foxclaw/skills/__init__.py +559 -0
  213. package/python/foxclaw/skills/archive.py +111 -0
  214. package/python/foxclaw/skills/fetch.py +226 -0
  215. package/python/foxclaw/skills/hooks_spec.py +69 -0
  216. package/python/foxclaw/skills/install_cmd.py +216 -0
  217. package/python/foxclaw/skills/lifecycle.py +252 -0
  218. package/python/foxclaw/skills/markdown_skill.py +175 -0
  219. package/python/foxclaw/skills/markdown_store.py +39 -0
  220. package/python/foxclaw/skills/mcp_client.py +184 -0
  221. package/python/foxclaw/skills/mcp_store.py +40 -0
  222. package/python/foxclaw/skills/permission.py +145 -0
  223. package/python/foxclaw/skills/pipeline.py +354 -0
  224. package/python/foxclaw/skills/policy.py +74 -0
  225. package/python/foxclaw/skills/review.py +72 -0
  226. package/python/foxclaw/skills/store.py +57 -0
  227. package/python/frontend/assets/core_bg.jpg +0 -0
  228. package/python/frontend/deck/auth.js +25 -0
  229. package/python/frontend/deck/chat_model_picker.js +483 -0
  230. package/python/frontend/deck/domain.js +276 -0
  231. package/python/frontend/deck/main.js +1806 -0
  232. package/python/frontend/deck/markdown.js +44 -0
  233. package/python/frontend/deck/settings.js +307 -0
  234. package/python/frontend/deck/state.js +5 -0
  235. package/python/frontend/deck/util.js +4 -0
  236. package/python/frontend/deck/visuals.js +190 -0
  237. package/python/frontend/deck.css +855 -0
  238. package/python/frontend/deck.html +686 -0
  239. package/python/frontend/deck_v2.html +341 -0
  240. package/python/frontend/planet/index.html +266 -0
  241. package/python/frontend/planet/planet.css +579 -0
  242. package/python/frontend/planet/planet.js +1436 -0
  243. package/python/frontend/planet/vendor/three.core.min.js +6 -0
  244. package/python/frontend/planet/vendor/three.module.min.js +6 -0
  245. package/python/frontend/v3/assets/index-CQSBdxk4.js +34 -0
  246. package/python/frontend/v3/assets/index-D5nIsjms.css +1 -0
  247. package/python/frontend/v3/index.html +15 -0
  248. package/python/frontend/widget_runtime.js +252 -0
  249. package/python/frontend/widgets.js +639 -0
  250. package/python/frontend_src/index.html +14 -0
  251. package/python/frontend_src/package-lock.json +1376 -0
  252. package/python/frontend_src/package.json +19 -0
  253. package/python/frontend_src/src/App.vue +58 -0
  254. package/python/frontend_src/src/api.js +82 -0
  255. package/python/frontend_src/src/components/ChatDock.vue +365 -0
  256. package/python/frontend_src/src/components/ComposerMenu.vue +75 -0
  257. package/python/frontend_src/src/components/DocViewer.vue +162 -0
  258. package/python/frontend_src/src/components/Inspector.vue +235 -0
  259. package/python/frontend_src/src/components/LeftRail.vue +415 -0
  260. package/python/frontend_src/src/components/MenuPopover.vue +128 -0
  261. package/python/frontend_src/src/components/MessageStream.vue +389 -0
  262. package/python/frontend_src/src/components/ModelPicker.vue +350 -0
  263. package/python/frontend_src/src/components/QuickIngest.vue +112 -0
  264. package/python/frontend_src/src/components/Stage.vue +272 -0
  265. package/python/frontend_src/src/components/ToolMenu.vue +141 -0
  266. package/python/frontend_src/src/components/TopBar.vue +118 -0
  267. package/python/frontend_src/src/components/panels/ActivityPanel.vue +82 -0
  268. package/python/frontend_src/src/components/panels/AgentsPanel.vue +83 -0
  269. package/python/frontend_src/src/components/panels/KnowledgePanel.vue +425 -0
  270. package/python/frontend_src/src/components/panels/MemoryPanel.vue +117 -0
  271. package/python/frontend_src/src/components/panels/PanelBox.vue +50 -0
  272. package/python/frontend_src/src/components/panels/ReviewPanel.vue +292 -0
  273. package/python/frontend_src/src/components/panels/SettingsPanel.vue +358 -0
  274. package/python/frontend_src/src/components/panels/TasksPanel.vue +73 -0
  275. package/python/frontend_src/src/components/panels/ToolsPanel.vue +746 -0
  276. package/python/frontend_src/src/components/panels/UsagePanel.vue +105 -0
  277. package/python/frontend_src/src/lib/fmt.js +44 -0
  278. package/python/frontend_src/src/lib/i18n.js +53 -0
  279. package/python/frontend_src/src/lib/locales/en.js +173 -0
  280. package/python/frontend_src/src/lib/locales/zh.js +174 -0
  281. package/python/frontend_src/src/lib/md.js +190 -0
  282. package/python/frontend_src/src/main.js +9 -0
  283. package/python/frontend_src/src/stores/app.js +91 -0
  284. package/python/frontend_src/src/stores/chat.js +450 -0
  285. package/python/frontend_src/src/stores/model.js +96 -0
  286. package/python/frontend_src/src/stores/panels.js +289 -0
  287. package/python/frontend_src/src/stores/profile.js +31 -0
  288. package/python/frontend_src/src/stores/system.js +25 -0
  289. package/python/frontend_src/src/styles/base.css +138 -0
  290. package/python/frontend_src/src/styles/panel.css +117 -0
  291. package/python/frontend_src/src/styles/tokens.css +78 -0
  292. package/python/frontend_src/vite.config.js +39 -0
  293. package/python/pyproject.toml +268 -0
  294. package/python/requirements.txt +311 -0
  295. package/python/skills/README.md +123 -0
  296. package/python/skills/execution-contract/SKILL.md +30 -0
  297. package/python/skills/general-assistant/SKILL.md +34 -0
  298. package/python/skills/planner/SKILL.md +33 -0
  299. package/python/skills/schedule-itinerary/SKILL.md +35 -0
  300. package/python/skills/skill-composition/SKILL.md +31 -0
  301. package/python/skills/skill-guard/SKILL.md +67 -0
  302. package/python/skills/skill-memory/SKILL.md +50 -0
  303. package/python/skills/skill-router/SKILL.md +35 -0
  304. package/python/tests/conftest.py +54 -0
  305. package/python/tests/run_all.py +200 -0
  306. package/python/tests/test_agent_lifecycle.py +326 -0
  307. package/python/tests/test_ahs_p2.py +393 -0
  308. package/python/tests/test_anthropic_tools.py +192 -0
  309. package/python/tests/test_api.py +97 -0
  310. package/python/tests/test_api_auth.py +79 -0
  311. package/python/tests/test_api_host_guard.py +69 -0
  312. package/python/tests/test_attachments.py +151 -0
  313. package/python/tests/test_audit_chain.py +116 -0
  314. package/python/tests/test_audit_sink.py +130 -0
  315. package/python/tests/test_browser.py +149 -0
  316. package/python/tests/test_browser_request_guard.py +180 -0
  317. package/python/tests/test_capabilities.py +152 -0
  318. package/python/tests/test_channel_signing.py +185 -0
  319. package/python/tests/test_channel_trust.py +109 -0
  320. package/python/tests/test_channels.py +174 -0
  321. package/python/tests/test_cli.py +46 -0
  322. package/python/tests/test_compaction_toolpair.py +119 -0
  323. package/python/tests/test_config_layering.py +61 -0
  324. package/python/tests/test_confirm_nonce.py +186 -0
  325. package/python/tests/test_context_compaction_wiring.py +124 -0
  326. package/python/tests/test_dispatch.py +89 -0
  327. package/python/tests/test_domain_evals.py +334 -0
  328. package/python/tests/test_domain_import.py +72 -0
  329. package/python/tests/test_domain_reasoners.py +134 -0
  330. package/python/tests/test_e2e.py +161 -0
  331. package/python/tests/test_emb_cache.py +97 -0
  332. package/python/tests/test_embedding_singleton.py +87 -0
  333. package/python/tests/test_envfile.py +83 -0
  334. package/python/tests/test_evals_smoke.py +90 -0
  335. package/python/tests/test_event_spine.py +174 -0
  336. package/python/tests/test_evidence_semantic.py +88 -0
  337. package/python/tests/test_evidence_sse.py +94 -0
  338. package/python/tests/test_file_ingest.py +135 -0
  339. package/python/tests/test_finance.py +144 -0
  340. package/python/tests/test_finance_ledger.py +245 -0
  341. package/python/tests/test_finance_persist.py +174 -0
  342. package/python/tests/test_gateway.py +125 -0
  343. package/python/tests/test_governance.py +421 -0
  344. package/python/tests/test_governance_audit.py +324 -0
  345. package/python/tests/test_governance_middleware.py +137 -0
  346. package/python/tests/test_hkc.py +268 -0
  347. package/python/tests/test_hkc_index_build_manager.py +306 -0
  348. package/python/tests/test_hkc_manifest_reuse.py +294 -0
  349. package/python/tests/test_hkc_search_event_sync.py +482 -0
  350. package/python/tests/test_import_path_guard.py +155 -0
  351. package/python/tests/test_injection_guard.py +193 -0
  352. package/python/tests/test_integration.py +117 -0
  353. package/python/tests/test_itinerary.py +100 -0
  354. package/python/tests/test_kee_semantic.py +84 -0
  355. package/python/tests/test_kernel.py +212 -0
  356. package/python/tests/test_learning.py +101 -0
  357. package/python/tests/test_llm_admin.py +145 -0
  358. package/python/tests/test_llm_planner.py +344 -0
  359. package/python/tests/test_markdown_skills.py +62 -0
  360. package/python/tests/test_markdown_skills_openclaw.py +66 -0
  361. package/python/tests/test_mcp_connectors.py +97 -0
  362. package/python/tests/test_mcp_guardian_discovery.py +87 -0
  363. package/python/tests/test_mcp_no_memory.py +43 -0
  364. package/python/tests/test_mcp_policy_gate.py +76 -0
  365. package/python/tests/test_mcp_server.py +92 -0
  366. package/python/tests/test_memory_recall.py +92 -0
  367. package/python/tests/test_metrics.py +58 -0
  368. package/python/tests/test_multi_chain.py +90 -0
  369. package/python/tests/test_multimodal.py +122 -0
  370. package/python/tests/test_negotiation.py +136 -0
  371. package/python/tests/test_orchestration.py +109 -0
  372. package/python/tests/test_orchestration_decoupled.py +103 -0
  373. package/python/tests/test_p3_p5_hardening.py +324 -0
  374. package/python/tests/test_parallel_dispatch.py +207 -0
  375. package/python/tests/test_pipeline.py +492 -0
  376. package/python/tests/test_plan_visible.py +86 -0
  377. package/python/tests/test_planner.py +88 -0
  378. package/python/tests/test_policy_gate.py +108 -0
  379. package/python/tests/test_profile.py +67 -0
  380. package/python/tests/test_readme_claims.py +163 -0
  381. package/python/tests/test_reasoner.py +170 -0
  382. package/python/tests/test_release_check.py +252 -0
  383. package/python/tests/test_resume_checkpoint.py +148 -0
  384. package/python/tests/test_routing.py +85 -0
  385. package/python/tests/test_scheduler.py +138 -0
  386. package/python/tests/test_search.py +194 -0
  387. package/python/tests/test_secrets.py +153 -0
  388. package/python/tests/test_semantic.py +69 -0
  389. package/python/tests/test_sessions.py +90 -0
  390. package/python/tests/test_settings.py +265 -0
  391. package/python/tests/test_shadow_learning.py +290 -0
  392. package/python/tests/test_shared_write.py +200 -0
  393. package/python/tests/test_skill_taint_gate.py +145 -0
  394. package/python/tests/test_skills.py +117 -0
  395. package/python/tests/test_skills_fetch.py +282 -0
  396. package/python/tests/test_stats_and_events.py +162 -0
  397. package/python/tests/test_streaming.py +55 -0
  398. package/python/tests/test_supervisor_pipeline.py +176 -0
  399. package/python/tests/test_supervisor_triage.py +102 -0
  400. package/python/tests/test_taint.py +112 -0
  401. package/python/tests/test_task_stream.py +74 -0
  402. package/python/tests/test_thinking_sse.py +66 -0
  403. package/python/tests/test_thinking_stream.py +76 -0
  404. package/python/tests/test_tool_center.py +113 -0
  405. package/python/tests/test_tool_parallel.py +113 -0
  406. package/python/tests/test_tool_params.py +99 -0
  407. package/python/tests/test_tool_use.py +229 -0
  408. package/python/tests/test_toplevel_concurrency.py +116 -0
  409. package/python/tests/test_tracing.py +256 -0
  410. package/python/tests/test_truth_crystallizer.py +125 -0
  411. package/python/tests/test_truth_flow.py +88 -0
  412. package/python/tests/test_update_check.py +95 -0
  413. package/python/tests/test_url_policy.py +53 -0
  414. package/python/tests/test_verify_evidence.py +212 -0
  415. package/python/tests/test_version_sync.py +100 -0
  416. package/python/tests/test_web_trigger.py +82 -0
  417. package/python/tools/check_faiss_type.py +30 -0
  418. package/python/tools/check_log.ps1 +38 -0
  419. package/python/tools/ivf_status.py +72 -0
  420. package/python/tools/mypy_baseline.txt +13 -0
  421. package/python/tools/mypy_ratchet.py +143 -0
  422. package/python/tools/pack.py +173 -0
  423. package/python/tools/release_check.py +349 -0
  424. package/python/tools/restart_foxclaw.ps1 +71 -0
  425. package/python/tools/shared_write_audit.py +190 -0
  426. package/python/tools/size_baseline.txt +28 -0
  427. package/python/tools/size_check.py +102 -0
  428. package/python/tools/strip_comments.py +228 -0
  429. package/python/tools/verify_env.bat +2 -0
  430. package/python/tools/verify_env.py +25 -0
  431. package/python/vendor/HMR_LICENSE +37 -0
  432. package/python/vendor/HMR_README.md +65 -0
  433. package/python/vendor/hkc/LICENSE +37 -0
  434. package/python/vendor/hkc/hkc_ace/__init__.py +0 -0
  435. package/python/vendor/hkc/hkc_ace/ace.py +457 -0
  436. package/python/vendor/hkc/hkc_ace/skill_taxonomy.json +465 -0
  437. package/python/vendor/hkc/hkc_api/__init__.py +0 -0
  438. package/python/vendor/hkc/hkc_api/container.py +416 -0
  439. package/python/vendor/hkc/hkc_api/ingest_jobs.py +103 -0
  440. package/python/vendor/hkc/hkc_api/main.py +157 -0
  441. package/python/vendor/hkc/hkc_api/routes/__init__.py +0 -0
  442. package/python/vendor/hkc/hkc_api/routes/ability.py +151 -0
  443. package/python/vendor/hkc/hkc_api/routes/config.py +51 -0
  444. package/python/vendor/hkc/hkc_api/routes/knowledge.py +630 -0
  445. package/python/vendor/hkc/hkc_api/routes/search.py +88 -0
  446. package/python/vendor/hkc/hkc_api/schemas.py +153 -0
  447. package/python/vendor/hkc/hkc_api/synthesis.py +179 -0
  448. package/python/vendor/hkc/hkc_core/__init__.py +0 -0
  449. package/python/vendor/hkc/hkc_core/graph/__init__.py +0 -0
  450. package/python/vendor/hkc/hkc_core/graph/base.py +188 -0
  451. package/python/vendor/hkc/hkc_core/graph/sqlite_store.py +789 -0
  452. package/python/vendor/hkc/hkc_core/models/__init__.py +0 -0
  453. package/python/vendor/hkc/hkc_core/models/enums.py +65 -0
  454. package/python/vendor/hkc/hkc_core/models/ku.py +307 -0
  455. package/python/vendor/hkc/hkc_core/utils/__init__.py +0 -0
  456. package/python/vendor/hkc/hkc_core/utils/id_gen.py +113 -0
  457. package/python/vendor/hkc/hkc_crystallizer/__init__.py +44 -0
  458. package/python/vendor/hkc/hkc_crystallizer/adapters.py +94 -0
  459. package/python/vendor/hkc/hkc_crystallizer/candidate.py +145 -0
  460. package/python/vendor/hkc/hkc_crystallizer/crystallizer.py +179 -0
  461. package/python/vendor/hkc/hkc_crystallizer/ingress.py +90 -0
  462. package/python/vendor/hkc/hkc_kde/__init__.py +0 -0
  463. package/python/vendor/hkc/hkc_kde/chunker.py +197 -0
  464. package/python/vendor/hkc/hkc_kde/extractor.py +623 -0
  465. package/python/vendor/hkc/hkc_kde/kde.py +298 -0
  466. package/python/vendor/hkc/hkc_kde/loaders/__init__.py +0 -0
  467. package/python/vendor/hkc/hkc_kde/loaders/ebook_loader.py +153 -0
  468. package/python/vendor/hkc/hkc_kde/loaders/office_loader.py +194 -0
  469. package/python/vendor/hkc/hkc_kde/loaders/pdf_loader.py +162 -0
  470. package/python/vendor/hkc/hkc_kde/loaders/text_loader.py +157 -0
  471. package/python/vendor/hkc/hkc_kde/loaders/web_loader.py +91 -0
  472. package/python/vendor/hkc/hkc_kde/models.py +74 -0
  473. package/python/vendor/hkc/hkc_kde/packager.py +329 -0
  474. package/python/vendor/hkc/hkc_kde/relation_disc.py +151 -0
  475. package/python/vendor/hkc/hkc_kee/__init__.py +0 -0
  476. package/python/vendor/hkc/hkc_kee/dedup.py +227 -0
  477. package/python/vendor/hkc/hkc_kee/fingerprint.py +106 -0
  478. package/python/vendor/hkc/hkc_kee/kee.py +541 -0
  479. package/python/vendor/hkc/hkc_kep/__init__.py +0 -0
  480. package/python/vendor/hkc/hkc_kep/event_bus.py +205 -0
  481. package/python/vendor/hkc/hkc_sdk/__init__.py +63 -0
  482. package/python/vendor/hkc/hkc_sdk/base.py +151 -0
  483. package/python/vendor/hkc/hkc_sdk/direct_client.py +153 -0
  484. package/python/vendor/hkc/hkc_sdk/exceptions.py +39 -0
  485. package/python/vendor/hkc/hkc_sdk/http_client.py +166 -0
  486. package/python/vendor/hkc/hkc_sdk/models.py +171 -0
  487. package/python/vendor/hkc/hkc_search/__init__.py +0 -0
  488. package/python/vendor/hkc/hkc_search/bm25.py +325 -0
  489. package/python/vendor/hkc/hkc_search/embedding_backends.py +374 -0
  490. package/python/vendor/hkc/hkc_search/graph_search.py +132 -0
  491. package/python/vendor/hkc/hkc_search/hybrid.py +331 -0
  492. package/python/vendor/hkc/hkc_search/index_build_manager.py +378 -0
  493. package/python/vendor/hkc/hkc_search/vector_search.py +484 -0
  494. package/python/vendor/hmr/__init__.py +0 -0
  495. package/python/vendor/hmr/core/__init__.py +0 -0
  496. package/python/vendor/hmr/core/hmr.py +684 -0
  497. package/python/vendor/hmr/core/models.py +310 -0
  498. package/python/vendor/hmr/engines/__init__.py +0 -0
  499. package/python/vendor/hmr/engines/evolution.py +710 -0
  500. package/python/vendor/hmr/engines/jit_compiler.py +472 -0
  501. package/python/vendor/hmr/engines/lifecycle.py +264 -0
  502. package/python/vendor/hmr/engines/policy.py +625 -0
  503. package/python/vendor/hmr/engines/recall.py +260 -0
  504. package/python/vendor/hmr/engines/runtime_state.py +158 -0
  505. package/python/vendor/hmr/engines/scheduler.py +323 -0
  506. package/python/vendor/hmr/engines/semantic.py +150 -0
  507. package/python/vendor/hmr/engines/temporal.py +261 -0
  508. package/python/vendor/hmr/engines/thought_chain.py +635 -0
  509. package/python/vendor/hmr/graph/__init__.py +0 -0
  510. package/python/vendor/hmr/graph/cwg.py +338 -0
  511. package/python/vendor/hmr/graph/memory_graph.py +530 -0
  512. package/python/vendor/hmr/storage/__init__.py +0 -0
  513. package/python/vendor/hmr/storage/memory_fs.py +300 -0
  514. package/python/vendor/hmr/storage/vector_store.py +520 -0
@@ -0,0 +1,408 @@
1
+ """
2
+ Foxclaw — 系统入口
3
+ 统一初始化:HMR + ThoughtChain + Harness + 三个 Agent
4
+ """
5
+
6
+ import os
7
+ import sys
8
+ import threading
9
+ from pathlib import Path
10
+ from typing import TYPE_CHECKING
11
+
12
+ if TYPE_CHECKING:
13
+ import anthropic
14
+
15
+ for _stream in (sys.stdout, sys.stderr):
16
+ try:
17
+ _reconf = getattr(_stream, "reconfigure", None)
18
+ if _reconf is not None:
19
+ _reconf(encoding="utf-8", errors="replace")
20
+ except Exception:
21
+ pass
22
+
23
+ __version__ = "0.1.3"
24
+
25
+ from .core.thought_chain import ThoughtChain
26
+
27
+
28
+ class Foxclaw:
29
+ """
30
+ Foxclaw 统一入口
31
+ 一次初始化,五个 Agent 共享 HMR + ThoughtChain,各有独立 Harness
32
+ """
33
+
34
+ def __init__(
35
+ self,
36
+ data_dir: str = "./foxclaw_data",
37
+ anthropic_api_key: str | None = None,
38
+ shadow_rounds: int = 20,
39
+ ):
40
+ self.data_dir = Path(data_dir).resolve()
41
+ os.makedirs(self.data_dir, exist_ok=True)
42
+
43
+ api_key = anthropic_api_key or os.environ.get("ANTHROPIC_API_KEY")
44
+ self.client: "anthropic.Anthropic | None" = None
45
+ if api_key:
46
+ try:
47
+ import anthropic
48
+ self.client = anthropic.Anthropic(api_key=api_key)
49
+ except Exception:
50
+ self.client = None
51
+ else:
52
+ self.client = None
53
+
54
+ try:
55
+ from .knowledge import init_hkc as _init_hkc_early
56
+ _early_hkc = _init_hkc_early(self.data_dir, api_key)
57
+ except Exception as _e:
58
+ _early_hkc = None
59
+ print(f"[Foxclaw] ⚠ 启动期 HKC 预装配失败(继续,降级): {_e}")
60
+
61
+ from .core.memory_adapter import create_memory_backend
62
+ self.hmr = create_memory_backend(
63
+ storage_path=str(self.data_dir / "hmr"),
64
+ llm_api_key=api_key,
65
+ )
66
+
67
+ if _early_hkc is not None:
68
+ try:
69
+ _early_hkc.close()
70
+ except Exception:
71
+ pass
72
+ try:
73
+ from hkc_api.container import reset_container
74
+ reset_container()
75
+ except Exception:
76
+ pass
77
+ _early_hkc = None
78
+
79
+ self._hkc_service = None
80
+ self._hkc_inited = False
81
+
82
+ self.thought_chain = ThoughtChain(
83
+ db_path=str(self.data_dir / "thoughtchain.db")
84
+ )
85
+
86
+ from .core.sessions import SessionStore
87
+ self.sessions = SessionStore(self.data_dir / "sessions")
88
+
89
+ from .core.model_router import ModelRouter
90
+ self.router = ModelRouter()
91
+
92
+ from .core.token_meter import TokenMeter
93
+ self.token_meter = TokenMeter(
94
+ log_path=str(self.data_dir / "token_usage.jsonl"))
95
+ self.router.meter = self.token_meter
96
+
97
+ from .kernel import EventSpine, CapabilityRegistry, Scheduler
98
+ self.event_spine = EventSpine()
99
+
100
+ _maxc = os.environ.get("FOXCLAW_MAX_CONCURRENCY", "").strip()
101
+ self.scheduler = Scheduler(
102
+ max_concurrency=int(_maxc) if _maxc.isdigit() else None,
103
+ spine=self.event_spine)
104
+
105
+ from .core.governance_audit import attach as _attach_gov_audit
106
+ self.governance_auditor = _attach_gov_audit(self.event_spine, self.data_dir)
107
+
108
+ from .kernel import PolicyGate
109
+ from .skills.permission import evaluate as _perm_eval
110
+
111
+ action_evaluator = _perm_eval
112
+ self.sentinel = None
113
+ if os.environ.get("FOXCLAW_GUARDIAN", "0").strip() in ("1", "true", "True", "yes", "on"):
114
+ from .kernel.sentinel_client import SentinelClient
115
+ self.sentinel = SentinelClient(data_dir=str(self.data_dir))
116
+ action_evaluator = self.sentinel.evaluate
117
+ self.policy_gate = PolicyGate(spine=self.event_spine, action_evaluator=action_evaluator,
118
+ auditor=self.governance_auditor)
119
+
120
+ self.capabilities = CapabilityRegistry()
121
+ self.capabilities.register("event_spine", self.event_spine)
122
+ self.capabilities.register("scheduler", self.scheduler)
123
+ self.capabilities.register("policy_gate", self.policy_gate)
124
+ self.capabilities.register("memory", self.hmr)
125
+ self.capabilities.register("thought_chain", self.thought_chain)
126
+ self.capabilities.register("router", self.router)
127
+ if self.sentinel is not None:
128
+ self.capabilities.register("sentinel", self.sentinel)
129
+
130
+ from .core.shared_write import SharedWritePolicy, attach as _attach_shared_write
131
+ self.shared_write_policy = SharedWritePolicy()
132
+ _attach_shared_write(self.hmr, self.shared_write_policy,
133
+ spine=self.event_spine)
134
+
135
+ from .core.audit_sink import attach as _attach_shared_write_audit
136
+ self.shared_write_audit = _attach_shared_write_audit(
137
+ self.event_spine, self.data_dir)
138
+
139
+ from .agents.agents import SupervisorAgent, FinanceAgent, OfficeAgent
140
+ agent_kwargs = dict(
141
+ hmr=self.hmr,
142
+ thought_chain=self.thought_chain,
143
+ client=self.client,
144
+ data_dir=str(self.data_dir),
145
+ shadow_rounds=shadow_rounds,
146
+ router=self.router,
147
+ spine=self.event_spine,
148
+ caps=self.capabilities,
149
+ )
150
+ self.supervisor = SupervisorAgent(**agent_kwargs)
151
+ self.finance = FinanceAgent(**agent_kwargs)
152
+ self.office = OfficeAgent(**agent_kwargs)
153
+
154
+ self._agents = {
155
+ "supervisor": self.supervisor,
156
+ "finance": self.finance,
157
+ "office": self.office,
158
+ }
159
+ self.capabilities.register("agents", self._agents)
160
+
161
+ self.supervisor.register_subagents({
162
+ "finance": self.finance,
163
+ "office": self.office,
164
+ })
165
+
166
+ from .finance import FinanceRuntime
167
+ self.finance_runtime = FinanceRuntime(
168
+ policy_path=str(self.data_dir / "finance_policy.yaml"),
169
+ hmr=self.hmr,
170
+ )
171
+ self.finance.attach_runtime(self.finance_runtime)
172
+
173
+ from .learning import LearningRuntime
174
+ self.learning_runtime = LearningRuntime(
175
+ hmr=self.hmr, hkc_provider=lambda: self.hkc,
176
+ persist_path=str(self.data_dir / "learning.json"))
177
+ self.office.attach_runtime(self.learning_runtime)
178
+
179
+ from .itinerary import ItineraryRuntime
180
+ self.itinerary_runtime = ItineraryRuntime(
181
+ amap_key=os.environ.get("AMAP_MAPS_API_KEY"), hmr=self.hmr)
182
+ self.office.attach_itinerary(self.itinerary_runtime)
183
+
184
+ from .orchestration import Orchestrator
185
+ self.orchestrator = Orchestrator(self.capabilities, auditor=self.governance_auditor)
186
+ self.supervisor.attach_orchestrator(self.orchestrator)
187
+ self.capabilities.register("orchestrator", self.orchestrator)
188
+
189
+ from .skills import build_default_registry, SkillAdapter
190
+ self.skill_registry = build_default_registry()
191
+ from .skills.store import SkillStore
192
+ self.skill_store = SkillStore(self.data_dir)
193
+ self.skill_store.load(self.skill_registry)
194
+ from .core.confirm_nonce import ConfirmationBroker
195
+ self.confirm_broker = ConfirmationBroker()
196
+ self.skill_adapter = SkillAdapter(
197
+ self.skill_registry, mcp_clients={}, policy_gate=self.policy_gate,
198
+ sentinel=self.sentinel, confirms=self.confirm_broker)
199
+ from .skills.mcp_client import McpManager
200
+ from .skills.mcp_store import McpStore
201
+ self.mcp_manager = McpManager()
202
+ self.mcp_store = McpStore(self.data_dir)
203
+ for _cfg in self.mcp_store.load():
204
+ self.mcp_manager.restore(_cfg)
205
+ self.skill_adapter.mcp_clients = self.mcp_manager
206
+ self.sync_mcp_servers_to_sentinel()
207
+ from .skills.policy import SkillPolicy
208
+ self.skill_policy = SkillPolicy(self.data_dir)
209
+ self.skill_adapter.skill_policy = self.skill_policy
210
+ from .skills.markdown_skill import MarkdownSkillRegistry
211
+ from .skills.markdown_store import MarkdownStore
212
+ self.md_skills = MarkdownSkillRegistry()
213
+ self.md_skills.policy = self.skill_policy
214
+ self.md_store = MarkdownStore(self.data_dir)
215
+ self.md_store.load(self.md_skills)
216
+ from .skills.markdown_skill import load_builtin_dir
217
+ load_builtin_dir(self.md_skills, Path(__file__).resolve().parent.parent / "skills")
218
+ for _ag in self._agents.values():
219
+ _ag.md_skills = self.md_skills
220
+ _ag.hooks = self.skill_adapter.hooks
221
+ _ag.attach_skills(self.skill_registry, self.skill_adapter)
222
+ self.supervisor.skill_registry = self.skill_registry
223
+ from .skills.pipeline import AHSPipeline
224
+ self.ahs_pipeline = AHSPipeline(self.skill_registry, self.skill_adapter)
225
+ from .core.system_bus import SystemBus
226
+ from .core.truth_pipeline import TruthPipeline
227
+ self.system_bus = SystemBus(spine=self.event_spine)
228
+ self.truth_pipeline = TruthPipeline(self.system_bus, hmr=self.hmr)
229
+ from .knowledge import TruthCrystallizer
230
+ self.truth_crystallizer = TruthCrystallizer(
231
+ hkc_provider=lambda: self.hkc,
232
+ enabled=os.environ.get("FOXCLAW_TRUTH_TO_HKC", "") == "1")
233
+ self.system_bus.subscribe("truth.appended", self.truth_crystallizer.on_truth,
234
+ exact=True)
235
+ from .kernel import ProcessManager
236
+ self.process_manager = ProcessManager(bus=self.system_bus)
237
+ self.scheduler.process_manager = self.process_manager
238
+ from .cognitive import CognitiveStateTracker
239
+ self.cognitive_state = CognitiveStateTracker(
240
+ self.system_bus, process_manager=self.process_manager)
241
+ if "supervisor" in self._agents:
242
+ self._agents["supervisor"]._system_bus = self.system_bus
243
+ self._agents["supervisor"]._process_manager = self.process_manager
244
+
245
+ from .core.recovery import RestartRecovery
246
+ self.recovery = RestartRecovery(
247
+ log_path=str(self.data_dir / "task_log.jsonl"),
248
+ spine=self.event_spine)
249
+ for _a in self._agents.values():
250
+ _a._recovery = self.recovery
251
+ self.interrupted_tasks = self.recovery.scan_interrupted()
252
+ self.recovery_plan = self.recovery.plan_recovery(self.interrupted_tasks)
253
+
254
+ from .browser import BrowserService
255
+ self.browser_service = BrowserService(
256
+ headless=os.environ.get("FOXCLAW_BROWSER_HEADLESS", "1") != "0")
257
+
258
+ self._hkc_api_key = api_key
259
+ self._hkc_service = None
260
+ self._hkc_inited = False
261
+ self._hkc_lock = threading.Lock()
262
+
263
+ self.capabilities.register_lazy("hkc", lambda: self.hkc)
264
+ self.capabilities.register_lazy("search_runtime", self._build_search_runtime)
265
+
266
+ print(f"[Foxclaw] ✓ 系统启动完成,数据目录: {self.data_dir}")
267
+ print(f"[Foxclaw] ✓ 三个 Agent 已就绪: {list(self._agents.keys())}")
268
+ if self.interrupted_tasks:
269
+ print(f"[Foxclaw] ⚠ 检测到 {len(self.interrupted_tasks)} 个上次被中断的任务"
270
+ f"(进程崩溃/重启)——恢复计划:可重试 {len(self.recovery_plan.retryable)},"
271
+ f"通知用户 {len(self.recovery_plan.notify_user)},"
272
+ f"需人工 {len(self.recovery_plan.needs_manual)}:")
273
+ for t in self.interrupted_tasks[:5]:
274
+ print(f" · 「{t.description[:40]}」(中断于 pid={t.pid})")
275
+ _ri = self.router.info()
276
+ if _ri['active']:
277
+ print(f"[Foxclaw] ✓ 模型路由: {_ri['provider']}({_ri['model']})")
278
+ else:
279
+ reason = getattr(self.router, 'fallback_reason', '') or '未配置任何模型 Key'
280
+ print(f"[Foxclaw] ⚠ 模型路由: 探测到 '{_ri['provider']}' 但降级 stub — {reason}")
281
+
282
+ @property
283
+ def hkc(self):
284
+ """HKC 知识核心接入句柄(HKCService)或 None(降级)。惰性装配:首次访问才装。
285
+ 线程安全(双检锁):并发首访只装配一次,避免多开一套 SQLite 句柄泄漏。"""
286
+ if self._hkc_inited:
287
+ return self._hkc_service
288
+ with self._hkc_lock:
289
+ if not self._hkc_inited:
290
+ from .knowledge import init_hkc, bridge_hkc_events
291
+ self._hkc_service = init_hkc(self.data_dir, self._hkc_api_key)
292
+ if self._hkc_service is not None:
293
+ bridge_hkc_events(self._hkc_service.event_bus, self.event_spine)
294
+ self._hkc_inited = True
295
+ return self._hkc_service
296
+
297
+ def sync_abilities_to_skills(self) -> list:
298
+ """【HKC 第2档 Step4】把 HKC 中 coverage 达标的 ACE 能力注册进 SkillRegistry(证据 gate:
299
+ 不足不注册)。**opt-in**:不在启动时自动调(编译有图开销、知识随时间变);由调用方在知识
300
+ 就绪后按需触发。注册的能力 skill 为 read,经 PolicyGate 治理、可被管线 stage_route 路由。
301
+ 返回注册的 skill id 列表。"""
302
+ from .knowledge import register_abilities_as_skills
303
+ reg = getattr(self, "skill_registry", None)
304
+ return register_abilities_as_skills(reg, self.hkc)
305
+
306
+ def sync_mcp_servers_to_sentinel(self) -> None:
307
+ """【P-Muse·第4步】把当前 MCP server 元数据同步给守门人(全量)。
308
+ 主进程不再长期持有 headers,故这里只推元数据;守门人侧 headers 空则保留旧值,
309
+ add_server 那次由 mcp_add_server_guardian 临时带一次 headers 覆盖。"""
310
+ sent = getattr(self, "sentinel", None)
311
+ if sent is not None and getattr(self, "mcp_manager", None) is not None:
312
+ sent.mcp_register(self.mcp_manager.servers())
313
+
314
+ def mcp_add_server_guardian(self, cfg: dict) -> list:
315
+ """【P-Muse·第4步】守门人模式下接入 MCP server 的发现流程:
316
+ 含 headers 的完整配置只在这一次调用里经手,推给守门人后主进程立即丢弃 headers,
317
+ 只存非敏感元数据(id/name/url/transport)。发现(list_tools)由守门人代执行。"""
318
+ meta = {k: cfg[k] for k in ("id", "name", "url", "transport")}
319
+ full = [dict(s) for s in self.mcp_manager.servers()]
320
+ full = [s for s in full if s.get("id") != cfg["id"]]
321
+ full.append(cfg)
322
+ sent = self.sentinel
323
+ if sent is None:
324
+ raise RuntimeError("守门人未启用(FOXCLAW_GUARDIAN=0),无法走守门人模式接入 MCP")
325
+ sent.mcp_register(full)
326
+ tools = sent.mcp_list_tools(cfg["id"])
327
+ self.mcp_manager.restore(meta)
328
+ self.mcp_store.save(self.mcp_manager.servers())
329
+ return tools
330
+
331
+ @property
332
+ def search_runtime(self):
333
+ """认知搜索内核(HSR)。经能力中枢惰性解析(首次触发 _build_search_runtime)。"""
334
+ return self.capabilities.get("search_runtime")
335
+
336
+ def _build_search_runtime(self):
337
+ """构造 HSR:内部三源全连通(HMR记忆 + HKC知识 knowledge_port + Agent态势 agent_port)。
338
+ 由 CapabilityRegistry 首次解析 "search_runtime" 时调用并缓存。
339
+ Agent 侧经 self._caps.get("search_runtime") 反向取用,故此处**不再注入** Agent。"""
340
+ from .search import SearchRuntime, HKCReadPort, AgentSourcePort
341
+ hkc = self.hkc
342
+ kp = HKCReadPort(client=hkc.client) if (hkc and hkc.available) else None
343
+ ap = AgentSourcePort(
344
+ agents=self._agents,
345
+ finance_runtime=getattr(self, "finance_runtime", None),
346
+ learning_runtime=getattr(self, "learning_runtime", None),
347
+ itinerary_runtime=getattr(self, "itinerary_runtime", None),
348
+ thought_chain=self.thought_chain,
349
+ skill_registry=getattr(self, "skill_registry", None),
350
+ hmr=self.hmr,
351
+ )
352
+ return SearchRuntime(hmr=self.hmr, knowledge_port=kp, agent_port=ap)
353
+
354
+ def get_agent(self, agent_id: str):
355
+ return self._agents.get(agent_id)
356
+
357
+ def get_all_status(self) -> dict:
358
+ return {
359
+ agent_id: agent.get_status()
360
+ for agent_id, agent in self._agents.items()
361
+ }
362
+
363
+ async def run(self, task: str, agent_id: str = "supervisor",
364
+ context: dict | None = None) -> dict:
365
+ """
366
+ 快捷运行接口
367
+ 默认由主管 Agent 处理,它会根据任务类型决定路由
368
+
369
+ context 现在透传给 Agent(此前 API 层收了 context 但这里丢掉,导致调用方
370
+ 无法传 `_resume_task_id` 之类控制项):`{"_resume_task_id": ...}` 即断点续跑。
371
+ """
372
+ agent = self._agents.get(agent_id)
373
+ if not agent:
374
+ return {"error": f"未知 Agent: {agent_id}"}
375
+ return await agent.run_task(task, context=context)
376
+
377
+ async def aclose(self):
378
+ """系统级异步 teardown:释放持有原生资源的子系统(浏览器专用线程/会话)。
379
+ 由 API lifespan 关停时调用;幂等。"""
380
+ svc = getattr(self, "browser_service", None)
381
+ if svc is not None:
382
+ try:
383
+ await svc.close()
384
+ except Exception:
385
+ pass
386
+ tc = getattr(self, "truth_crystallizer", None)
387
+ if tc is not None:
388
+ try:
389
+ tc.close()
390
+ except Exception:
391
+ pass
392
+ hkc_svc = getattr(self, "_hkc_service", None)
393
+ hkc_was_inited = getattr(self, "_hkc_inited", False) or hkc_svc is not None
394
+ if hkc_svc is not None:
395
+ try:
396
+ hkc_svc.close()
397
+ except Exception:
398
+ pass
399
+ self._hkc_service = None
400
+ if hkc_was_inited:
401
+ try:
402
+ from hkc_api.container import reset_container
403
+ reset_container()
404
+ except Exception:
405
+ pass
406
+ self._hkc_inited = False
407
+
408
+
@@ -0,0 +1,12 @@
1
+ """Foxclaw — Agents: CognitiveAgent 基类与三个 Agent"""
2
+ from .base import CognitiveAgent, HarnessBlockedError
3
+ from .agents import (
4
+ SupervisorAgent,
5
+ FinanceAgent,
6
+ OfficeAgent,
7
+ )
8
+
9
+ __all__ = [
10
+ "CognitiveAgent", "HarnessBlockedError",
11
+ "SupervisorAgent", "FinanceAgent", "OfficeAgent",
12
+ ]
@@ -0,0 +1,35 @@
1
+ """三个具体 Agent 实现(拓扑收缩后)。
2
+
3
+ Agent 拓扑 5 → 3(2026-11-07):
4
+ - impl/supervisor.py SupervisorAgent(主管:全局统筹/分诊/兜底自答)
5
+ - impl/finance.py FinanceAgent(财务:收支/预算/风控)
6
+ - impl/office.py OfficeAgent(办公学习:学习/知识/文档 + 日程/行程)
7
+ - impl/_helpers.py 共享辅助函数 + 多步链式常量
8
+
9
+ 原 `assistant`(通用助手)与 `admin`(行政:日程行程)不再作为独立 Agent 常驻:
10
+ · 角色行为下放为指令技能 `skills/general-assistant`、`skills/schedule-itinerary`
11
+ (frontmatter 标 builtin: true,随包注入命中的 Agent);
12
+ · admin 的行程内核与领域方法(plan_itinerary / handle_cross_request / concede)并入
13
+ OfficeAgent —— 领域逻辑仍归"离内核最近"的 Agent,不放进编排层。
14
+ · 助手原先独占的 skill 工具箱上移到 `mixins/skillbox.py`,三个 Agent 都能用技能。
15
+
16
+ 本文件只做 re-export,保持 `from foxclaw.agents.agents import X` 的历史兼容
17
+ (tests/*、foxclaw/__init__.py、pipeline/supervisor_stages.py 仍按此路径取符号)。
18
+ """
19
+ from .impl.supervisor import SupervisorAgent
20
+ from .impl.finance import FinanceAgent
21
+ from .impl.office import OfficeAgent
22
+ from .impl._helpers import (
23
+ _with_prior,
24
+ _fmt_mem,
25
+ _dispatch_failed,
26
+ _extract_step_results,
27
+ PRIOR_MAX_STEPS,
28
+ PRIOR_MAX_CHARS,
29
+ )
30
+
31
+ __all__ = [
32
+ "SupervisorAgent", "FinanceAgent", "OfficeAgent",
33
+ "_with_prior", "_fmt_mem", "_dispatch_failed", "_extract_step_results",
34
+ "PRIOR_MAX_STEPS", "PRIOR_MAX_CHARS",
35
+ ]