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.
- package/README.md +54 -29
- package/bin/foxclaw.cjs +51 -0
- package/index.js +4 -10
- package/package.json +46 -38
- package/python/.dockerignore +35 -0
- package/python/.env.example +173 -0
- package/python/.gitattributes +46 -0
- package/python/.github/workflows/ci.yml +167 -0
- package/python/.github/workflows/release.yml +183 -0
- package/python/CHANGELOG.md +57 -0
- package/python/CHANGELOG_CN.md +57 -0
- package/python/Dockerfile +64 -0
- package/python/LICENSE +21 -0
- package/python/MANIFEST.in +14 -0
- package/python/README.md +201 -0
- package/python/README_CN.md +336 -0
- package/python/bench/bm25_audit.py +186 -0
- package/python/bench/bm25_regression.py +177 -0
- package/python/bench/bm25_stress.py +155 -0
- package/python/bench/cd_audit.py +215 -0
- package/python/bench/chaos.py +140 -0
- package/python/bench/concurrency.py +103 -0
- package/python/bench/e2e_real_models.py +94 -0
- package/python/bench/llm_retry_test.py +241 -0
- package/python/bench/load_test.py +193 -0
- package/python/bench/vector_ivf_upgrade.py +128 -0
- package/python/docs/CHANNELS.md +195 -0
- package/python/docs/GOVERNANCE.md +164 -0
- package/python/docs/RELEASE.md +110 -0
- package/python/docs/RUN.md +75 -0
- package/python/docs/RUN_CN.md +121 -0
- package/python/docs//351/205/215/347/275/256/346/214/207/345/215/227.md +152 -0
- package/python/evals/__init__.py +0 -0
- package/python/evals/governance/README.md +61 -0
- package/python/evals/governance/__init__.py +0 -0
- package/python/evals/governance/cases.py +115 -0
- package/python/evals/governance/compare_embeddings.py +94 -0
- package/python/evals/governance/convergence.svg +11 -0
- package/python/evals/governance/report.json +371 -0
- package/python/evals/governance/run_evals.py +368 -0
- package/python/examples/governance_middleware_demo.py +72 -0
- package/python/examples/langgraph_governance_demo.py +104 -0
- package/python/examples/sample_itinerary.csv +6 -0
- package/python/examples/sample_knowledge.csv +9 -0
- package/python/examples/sample_transactions.csv +14 -0
- package/python/foxclaw/__init__.py +408 -0
- package/python/foxclaw/agents/__init__.py +12 -0
- package/python/foxclaw/agents/agents.py +35 -0
- package/python/foxclaw/agents/base.py +794 -0
- package/python/foxclaw/agents/impl/__init__.py +1 -0
- package/python/foxclaw/agents/impl/_helpers.py +70 -0
- package/python/foxclaw/agents/impl/finance.py +231 -0
- package/python/foxclaw/agents/impl/office.py +350 -0
- package/python/foxclaw/agents/impl/supervisor.py +592 -0
- package/python/foxclaw/agents/mixins/_context.py +128 -0
- package/python/foxclaw/agents/mixins/augment.py +143 -0
- package/python/foxclaw/agents/mixins/llm.py +67 -0
- package/python/foxclaw/agents/mixins/memory.py +41 -0
- package/python/foxclaw/agents/mixins/preference.py +131 -0
- package/python/foxclaw/agents/mixins/prompt.py +71 -0
- package/python/foxclaw/agents/mixins/skillbox.py +58 -0
- package/python/foxclaw/agents/mixins/tool_exec.py +417 -0
- package/python/foxclaw/api/__init__.py +224 -0
- package/python/foxclaw/api/_state.py +43 -0
- package/python/foxclaw/api/bootstrap.py +96 -0
- package/python/foxclaw/api/middleware.py +294 -0
- package/python/foxclaw/api/routes/ahs.py +404 -0
- package/python/foxclaw/api/routes/attachments.py +116 -0
- package/python/foxclaw/api/routes/browser.py +35 -0
- package/python/foxclaw/api/routes/domain.py +306 -0
- package/python/foxclaw/api/routes/knowledge.py +145 -0
- package/python/foxclaw/api/routes/llm_admin.py +449 -0
- package/python/foxclaw/api/routes/memory.py +105 -0
- package/python/foxclaw/api/routes/orchestration.py +39 -0
- package/python/foxclaw/api/routes/recovery.py +44 -0
- package/python/foxclaw/api/routes/review.py +266 -0
- package/python/foxclaw/api/routes/search.py +33 -0
- package/python/foxclaw/api/routes/system.py +311 -0
- package/python/foxclaw/api/routes/task.py +263 -0
- package/python/foxclaw/api/routes/ws.py +64 -0
- package/python/foxclaw/api/spine.py +52 -0
- package/python/foxclaw/browser/__init__.py +13 -0
- package/python/foxclaw/browser/action/__init__.py +1 -0
- package/python/foxclaw/browser/action/action_executor.py +50 -0
- package/python/foxclaw/browser/action/action_types.py +44 -0
- package/python/foxclaw/browser/action/action_verifier.py +68 -0
- package/python/foxclaw/browser/action/url_policy.py +143 -0
- package/python/foxclaw/browser/adapter/__init__.py +1 -0
- package/python/foxclaw/browser/adapter/base_adapter.py +23 -0
- package/python/foxclaw/browser/adapter/web_adapter.py +46 -0
- package/python/foxclaw/browser/driver/__init__.py +1 -0
- package/python/foxclaw/browser/driver/base_driver.py +61 -0
- package/python/foxclaw/browser/driver/playwright_driver.py +170 -0
- package/python/foxclaw/browser/perception/__init__.py +1 -0
- package/python/foxclaw/browser/perception/dom_extractor.py +42 -0
- package/python/foxclaw/browser/perception/element_indexer.py +56 -0
- package/python/foxclaw/browser/perception/semantic_reducer.py +33 -0
- package/python/foxclaw/browser/perception/snapshot.py +29 -0
- package/python/foxclaw/browser/service.py +144 -0
- package/python/foxclaw/browser/session/__init__.py +1 -0
- package/python/foxclaw/browser/session/session_manager.py +57 -0
- package/python/foxclaw/capability/__init__.py +12 -0
- package/python/foxclaw/capability/embedding_service.py +65 -0
- package/python/foxclaw/channels/__init__.py +138 -0
- package/python/foxclaw/channels/discord.py +175 -0
- package/python/foxclaw/channels/dispatcher.py +179 -0
- package/python/foxclaw/channels/feishu.py +215 -0
- package/python/foxclaw/channels/openclaw_bridge.py +151 -0
- package/python/foxclaw/channels/signing.py +187 -0
- package/python/foxclaw/channels/telegram.py +120 -0
- package/python/foxclaw/channels/weixin.py +215 -0
- package/python/foxclaw/cli.py +183 -0
- package/python/foxclaw/cognitive/__init__.py +4 -0
- package/python/foxclaw/cognitive/reasoner.py +81 -0
- package/python/foxclaw/cognitive/state.py +141 -0
- package/python/foxclaw/core/__init__.py +9 -0
- package/python/foxclaw/core/audit_chain.py +131 -0
- package/python/foxclaw/core/audit_sink.py +100 -0
- package/python/foxclaw/core/compaction.py +265 -0
- package/python/foxclaw/core/config.py +65 -0
- package/python/foxclaw/core/confirm_nonce.py +151 -0
- package/python/foxclaw/core/dispatch.py +27 -0
- package/python/foxclaw/core/envfile.py +48 -0
- package/python/foxclaw/core/failure_policy.py +142 -0
- package/python/foxclaw/core/gateway.py +81 -0
- package/python/foxclaw/core/governance_audit.py +171 -0
- package/python/foxclaw/core/idempotency.py +282 -0
- package/python/foxclaw/core/injection_guard.py +202 -0
- package/python/foxclaw/core/memory_adapter.py +489 -0
- package/python/foxclaw/core/metrics.py +88 -0
- package/python/foxclaw/core/model_router.py +985 -0
- package/python/foxclaw/core/paths.py +103 -0
- package/python/foxclaw/core/recovery.py +349 -0
- package/python/foxclaw/core/scheduler.py +141 -0
- package/python/foxclaw/core/secrets.py +131 -0
- package/python/foxclaw/core/sessions.py +155 -0
- package/python/foxclaw/core/settings.py +414 -0
- package/python/foxclaw/core/shared_write.py +186 -0
- package/python/foxclaw/core/steering_queue.py +154 -0
- package/python/foxclaw/core/system_bus.py +84 -0
- package/python/foxclaw/core/thought_chain.py +316 -0
- package/python/foxclaw/core/token_meter.py +231 -0
- package/python/foxclaw/core/tools.py +164 -0
- package/python/foxclaw/core/tracing.py +375 -0
- package/python/foxclaw/core/truth_pipeline.py +110 -0
- package/python/foxclaw/core/update_check.py +149 -0
- package/python/foxclaw/core/vec_recall_adapter.py +477 -0
- package/python/foxclaw/core/verify.py +173 -0
- package/python/foxclaw/core/web_search.py +218 -0
- package/python/foxclaw/finance/__init__.py +15 -0
- package/python/foxclaw/finance/evidence.py +149 -0
- package/python/foxclaw/finance/fx.py +98 -0
- package/python/foxclaw/finance/graph.py +179 -0
- package/python/foxclaw/finance/models.py +146 -0
- package/python/foxclaw/finance/nlparse.py +515 -0
- package/python/foxclaw/finance/policy.py +301 -0
- package/python/foxclaw/finance/reasoner.py +121 -0
- package/python/foxclaw/finance/reasoning.py +319 -0
- package/python/foxclaw/finance/reconcile.py +175 -0
- package/python/foxclaw/finance/runtime.py +500 -0
- package/python/foxclaw/governance/__init__.py +24 -0
- package/python/foxclaw/governance/middleware.py +176 -0
- package/python/foxclaw/harness/__init__.py +17 -0
- package/python/foxclaw/harness/_base.py +66 -0
- package/python/foxclaw/harness/_policy.py +340 -0
- package/python/foxclaw/harness/drift.py +77 -0
- package/python/foxclaw/harness/event_bus.py +28 -0
- package/python/foxclaw/harness/harness.py +358 -0
- package/python/foxclaw/harness/loop_detection.py +145 -0
- package/python/foxclaw/itinerary/__init__.py +10 -0
- package/python/foxclaw/itinerary/amap_client.py +114 -0
- package/python/foxclaw/itinerary/models.py +80 -0
- package/python/foxclaw/itinerary/reasoner.py +96 -0
- package/python/foxclaw/itinerary/reasoning.py +168 -0
- package/python/foxclaw/itinerary/runtime.py +144 -0
- package/python/foxclaw/kernel/__init__.py +13 -0
- package/python/foxclaw/kernel/capabilities.py +72 -0
- package/python/foxclaw/kernel/policy_gate.py +108 -0
- package/python/foxclaw/kernel/process_manager.py +186 -0
- package/python/foxclaw/kernel/scheduler.py +125 -0
- package/python/foxclaw/kernel/sentinel.py +443 -0
- package/python/foxclaw/kernel/sentinel_client.py +243 -0
- package/python/foxclaw/kernel/spine.py +97 -0
- package/python/foxclaw/knowledge/__init__.py +360 -0
- package/python/foxclaw/knowledge/truth_crystallizer.py +89 -0
- package/python/foxclaw/learning/__init__.py +12 -0
- package/python/foxclaw/learning/knowledge_graph.py +144 -0
- package/python/foxclaw/learning/models.py +93 -0
- package/python/foxclaw/learning/reasoner.py +67 -0
- package/python/foxclaw/learning/runtime.py +351 -0
- package/python/foxclaw/learning/spaced_repetition.py +91 -0
- package/python/foxclaw/mcp_server.py +188 -0
- package/python/foxclaw/orchestration/__init__.py +167 -0
- package/python/foxclaw/pipeline/__init__.py +23 -0
- package/python/foxclaw/pipeline/cognitive_pipeline.py +429 -0
- package/python/foxclaw/pipeline/stage_meta.py +21 -0
- package/python/foxclaw/pipeline/supervisor_stages.py +201 -0
- package/python/foxclaw/planning/__init__.py +17 -0
- package/python/foxclaw/planning/llm_planner.py +232 -0
- package/python/foxclaw/planning/planner.py +94 -0
- package/python/foxclaw/search/__init__.py +24 -0
- package/python/foxclaw/search/agent_port.py +190 -0
- package/python/foxclaw/search/evidence.py +109 -0
- package/python/foxclaw/search/external_search.py +50 -0
- package/python/foxclaw/search/hkc_read_port.py +60 -0
- package/python/foxclaw/search/internal_search.py +71 -0
- package/python/foxclaw/search/models.py +127 -0
- package/python/foxclaw/search/planner.py +44 -0
- package/python/foxclaw/search/retriever.py +39 -0
- package/python/foxclaw/search/runtime.py +127 -0
- package/python/foxclaw/search/strategy.py +44 -0
- package/python/foxclaw/skills/__init__.py +559 -0
- package/python/foxclaw/skills/archive.py +111 -0
- package/python/foxclaw/skills/fetch.py +226 -0
- package/python/foxclaw/skills/hooks_spec.py +69 -0
- package/python/foxclaw/skills/install_cmd.py +216 -0
- package/python/foxclaw/skills/lifecycle.py +252 -0
- package/python/foxclaw/skills/markdown_skill.py +175 -0
- package/python/foxclaw/skills/markdown_store.py +39 -0
- package/python/foxclaw/skills/mcp_client.py +184 -0
- package/python/foxclaw/skills/mcp_store.py +40 -0
- package/python/foxclaw/skills/permission.py +145 -0
- package/python/foxclaw/skills/pipeline.py +354 -0
- package/python/foxclaw/skills/policy.py +74 -0
- package/python/foxclaw/skills/review.py +72 -0
- package/python/foxclaw/skills/store.py +57 -0
- package/python/frontend/assets/core_bg.jpg +0 -0
- package/python/frontend/deck/auth.js +25 -0
- package/python/frontend/deck/chat_model_picker.js +483 -0
- package/python/frontend/deck/domain.js +276 -0
- package/python/frontend/deck/main.js +1806 -0
- package/python/frontend/deck/markdown.js +44 -0
- package/python/frontend/deck/settings.js +307 -0
- package/python/frontend/deck/state.js +5 -0
- package/python/frontend/deck/util.js +4 -0
- package/python/frontend/deck/visuals.js +190 -0
- package/python/frontend/deck.css +855 -0
- package/python/frontend/deck.html +686 -0
- package/python/frontend/deck_v2.html +341 -0
- package/python/frontend/planet/index.html +266 -0
- package/python/frontend/planet/planet.css +579 -0
- package/python/frontend/planet/planet.js +1436 -0
- package/python/frontend/planet/vendor/three.core.min.js +6 -0
- package/python/frontend/planet/vendor/three.module.min.js +6 -0
- package/python/frontend/v3/assets/index-CQSBdxk4.js +34 -0
- package/python/frontend/v3/assets/index-D5nIsjms.css +1 -0
- package/python/frontend/v3/index.html +15 -0
- package/python/frontend/widget_runtime.js +252 -0
- package/python/frontend/widgets.js +639 -0
- package/python/frontend_src/index.html +14 -0
- package/python/frontend_src/package-lock.json +1376 -0
- package/python/frontend_src/package.json +19 -0
- package/python/frontend_src/src/App.vue +58 -0
- package/python/frontend_src/src/api.js +82 -0
- package/python/frontend_src/src/components/ChatDock.vue +365 -0
- package/python/frontend_src/src/components/ComposerMenu.vue +75 -0
- package/python/frontend_src/src/components/DocViewer.vue +162 -0
- package/python/frontend_src/src/components/Inspector.vue +235 -0
- package/python/frontend_src/src/components/LeftRail.vue +415 -0
- package/python/frontend_src/src/components/MenuPopover.vue +128 -0
- package/python/frontend_src/src/components/MessageStream.vue +389 -0
- package/python/frontend_src/src/components/ModelPicker.vue +350 -0
- package/python/frontend_src/src/components/QuickIngest.vue +112 -0
- package/python/frontend_src/src/components/Stage.vue +272 -0
- package/python/frontend_src/src/components/ToolMenu.vue +141 -0
- package/python/frontend_src/src/components/TopBar.vue +118 -0
- package/python/frontend_src/src/components/panels/ActivityPanel.vue +82 -0
- package/python/frontend_src/src/components/panels/AgentsPanel.vue +83 -0
- package/python/frontend_src/src/components/panels/KnowledgePanel.vue +425 -0
- package/python/frontend_src/src/components/panels/MemoryPanel.vue +117 -0
- package/python/frontend_src/src/components/panels/PanelBox.vue +50 -0
- package/python/frontend_src/src/components/panels/ReviewPanel.vue +292 -0
- package/python/frontend_src/src/components/panels/SettingsPanel.vue +358 -0
- package/python/frontend_src/src/components/panels/TasksPanel.vue +73 -0
- package/python/frontend_src/src/components/panels/ToolsPanel.vue +746 -0
- package/python/frontend_src/src/components/panels/UsagePanel.vue +105 -0
- package/python/frontend_src/src/lib/fmt.js +44 -0
- package/python/frontend_src/src/lib/i18n.js +53 -0
- package/python/frontend_src/src/lib/locales/en.js +173 -0
- package/python/frontend_src/src/lib/locales/zh.js +174 -0
- package/python/frontend_src/src/lib/md.js +190 -0
- package/python/frontend_src/src/main.js +9 -0
- package/python/frontend_src/src/stores/app.js +91 -0
- package/python/frontend_src/src/stores/chat.js +450 -0
- package/python/frontend_src/src/stores/model.js +96 -0
- package/python/frontend_src/src/stores/panels.js +289 -0
- package/python/frontend_src/src/stores/profile.js +31 -0
- package/python/frontend_src/src/stores/system.js +25 -0
- package/python/frontend_src/src/styles/base.css +138 -0
- package/python/frontend_src/src/styles/panel.css +117 -0
- package/python/frontend_src/src/styles/tokens.css +78 -0
- package/python/frontend_src/vite.config.js +39 -0
- package/python/pyproject.toml +268 -0
- package/python/requirements.txt +311 -0
- package/python/skills/README.md +123 -0
- package/python/skills/execution-contract/SKILL.md +30 -0
- package/python/skills/general-assistant/SKILL.md +34 -0
- package/python/skills/planner/SKILL.md +33 -0
- package/python/skills/schedule-itinerary/SKILL.md +35 -0
- package/python/skills/skill-composition/SKILL.md +31 -0
- package/python/skills/skill-guard/SKILL.md +67 -0
- package/python/skills/skill-memory/SKILL.md +50 -0
- package/python/skills/skill-router/SKILL.md +35 -0
- package/python/tests/conftest.py +54 -0
- package/python/tests/run_all.py +200 -0
- package/python/tests/test_agent_lifecycle.py +326 -0
- package/python/tests/test_ahs_p2.py +393 -0
- package/python/tests/test_anthropic_tools.py +192 -0
- package/python/tests/test_api.py +97 -0
- package/python/tests/test_api_auth.py +79 -0
- package/python/tests/test_api_host_guard.py +69 -0
- package/python/tests/test_attachments.py +151 -0
- package/python/tests/test_audit_chain.py +116 -0
- package/python/tests/test_audit_sink.py +130 -0
- package/python/tests/test_browser.py +149 -0
- package/python/tests/test_browser_request_guard.py +180 -0
- package/python/tests/test_capabilities.py +152 -0
- package/python/tests/test_channel_signing.py +185 -0
- package/python/tests/test_channel_trust.py +109 -0
- package/python/tests/test_channels.py +174 -0
- package/python/tests/test_cli.py +46 -0
- package/python/tests/test_compaction_toolpair.py +119 -0
- package/python/tests/test_config_layering.py +61 -0
- package/python/tests/test_confirm_nonce.py +186 -0
- package/python/tests/test_context_compaction_wiring.py +124 -0
- package/python/tests/test_dispatch.py +89 -0
- package/python/tests/test_domain_evals.py +334 -0
- package/python/tests/test_domain_import.py +72 -0
- package/python/tests/test_domain_reasoners.py +134 -0
- package/python/tests/test_e2e.py +161 -0
- package/python/tests/test_emb_cache.py +97 -0
- package/python/tests/test_embedding_singleton.py +87 -0
- package/python/tests/test_envfile.py +83 -0
- package/python/tests/test_evals_smoke.py +90 -0
- package/python/tests/test_event_spine.py +174 -0
- package/python/tests/test_evidence_semantic.py +88 -0
- package/python/tests/test_evidence_sse.py +94 -0
- package/python/tests/test_file_ingest.py +135 -0
- package/python/tests/test_finance.py +144 -0
- package/python/tests/test_finance_ledger.py +245 -0
- package/python/tests/test_finance_persist.py +174 -0
- package/python/tests/test_gateway.py +125 -0
- package/python/tests/test_governance.py +421 -0
- package/python/tests/test_governance_audit.py +324 -0
- package/python/tests/test_governance_middleware.py +137 -0
- package/python/tests/test_hkc.py +268 -0
- package/python/tests/test_hkc_index_build_manager.py +306 -0
- package/python/tests/test_hkc_manifest_reuse.py +294 -0
- package/python/tests/test_hkc_search_event_sync.py +482 -0
- package/python/tests/test_import_path_guard.py +155 -0
- package/python/tests/test_injection_guard.py +193 -0
- package/python/tests/test_integration.py +117 -0
- package/python/tests/test_itinerary.py +100 -0
- package/python/tests/test_kee_semantic.py +84 -0
- package/python/tests/test_kernel.py +212 -0
- package/python/tests/test_learning.py +101 -0
- package/python/tests/test_llm_admin.py +145 -0
- package/python/tests/test_llm_planner.py +344 -0
- package/python/tests/test_markdown_skills.py +62 -0
- package/python/tests/test_markdown_skills_openclaw.py +66 -0
- package/python/tests/test_mcp_connectors.py +97 -0
- package/python/tests/test_mcp_guardian_discovery.py +87 -0
- package/python/tests/test_mcp_no_memory.py +43 -0
- package/python/tests/test_mcp_policy_gate.py +76 -0
- package/python/tests/test_mcp_server.py +92 -0
- package/python/tests/test_memory_recall.py +92 -0
- package/python/tests/test_metrics.py +58 -0
- package/python/tests/test_multi_chain.py +90 -0
- package/python/tests/test_multimodal.py +122 -0
- package/python/tests/test_negotiation.py +136 -0
- package/python/tests/test_orchestration.py +109 -0
- package/python/tests/test_orchestration_decoupled.py +103 -0
- package/python/tests/test_p3_p5_hardening.py +324 -0
- package/python/tests/test_parallel_dispatch.py +207 -0
- package/python/tests/test_pipeline.py +492 -0
- package/python/tests/test_plan_visible.py +86 -0
- package/python/tests/test_planner.py +88 -0
- package/python/tests/test_policy_gate.py +108 -0
- package/python/tests/test_profile.py +67 -0
- package/python/tests/test_readme_claims.py +163 -0
- package/python/tests/test_reasoner.py +170 -0
- package/python/tests/test_release_check.py +252 -0
- package/python/tests/test_resume_checkpoint.py +148 -0
- package/python/tests/test_routing.py +85 -0
- package/python/tests/test_scheduler.py +138 -0
- package/python/tests/test_search.py +194 -0
- package/python/tests/test_secrets.py +153 -0
- package/python/tests/test_semantic.py +69 -0
- package/python/tests/test_sessions.py +90 -0
- package/python/tests/test_settings.py +265 -0
- package/python/tests/test_shadow_learning.py +290 -0
- package/python/tests/test_shared_write.py +200 -0
- package/python/tests/test_skill_taint_gate.py +145 -0
- package/python/tests/test_skills.py +117 -0
- package/python/tests/test_skills_fetch.py +282 -0
- package/python/tests/test_stats_and_events.py +162 -0
- package/python/tests/test_streaming.py +55 -0
- package/python/tests/test_supervisor_pipeline.py +176 -0
- package/python/tests/test_supervisor_triage.py +102 -0
- package/python/tests/test_taint.py +112 -0
- package/python/tests/test_task_stream.py +74 -0
- package/python/tests/test_thinking_sse.py +66 -0
- package/python/tests/test_thinking_stream.py +76 -0
- package/python/tests/test_tool_center.py +113 -0
- package/python/tests/test_tool_parallel.py +113 -0
- package/python/tests/test_tool_params.py +99 -0
- package/python/tests/test_tool_use.py +229 -0
- package/python/tests/test_toplevel_concurrency.py +116 -0
- package/python/tests/test_tracing.py +256 -0
- package/python/tests/test_truth_crystallizer.py +125 -0
- package/python/tests/test_truth_flow.py +88 -0
- package/python/tests/test_update_check.py +95 -0
- package/python/tests/test_url_policy.py +53 -0
- package/python/tests/test_verify_evidence.py +212 -0
- package/python/tests/test_version_sync.py +100 -0
- package/python/tests/test_web_trigger.py +82 -0
- package/python/tools/check_faiss_type.py +30 -0
- package/python/tools/check_log.ps1 +38 -0
- package/python/tools/ivf_status.py +72 -0
- package/python/tools/mypy_baseline.txt +13 -0
- package/python/tools/mypy_ratchet.py +143 -0
- package/python/tools/pack.py +173 -0
- package/python/tools/release_check.py +349 -0
- package/python/tools/restart_foxclaw.ps1 +71 -0
- package/python/tools/shared_write_audit.py +190 -0
- package/python/tools/size_baseline.txt +28 -0
- package/python/tools/size_check.py +102 -0
- package/python/tools/strip_comments.py +228 -0
- package/python/tools/verify_env.bat +2 -0
- package/python/tools/verify_env.py +25 -0
- package/python/vendor/HMR_LICENSE +37 -0
- package/python/vendor/HMR_README.md +65 -0
- package/python/vendor/hkc/LICENSE +37 -0
- package/python/vendor/hkc/hkc_ace/__init__.py +0 -0
- package/python/vendor/hkc/hkc_ace/ace.py +457 -0
- package/python/vendor/hkc/hkc_ace/skill_taxonomy.json +465 -0
- package/python/vendor/hkc/hkc_api/__init__.py +0 -0
- package/python/vendor/hkc/hkc_api/container.py +416 -0
- package/python/vendor/hkc/hkc_api/ingest_jobs.py +103 -0
- package/python/vendor/hkc/hkc_api/main.py +157 -0
- package/python/vendor/hkc/hkc_api/routes/__init__.py +0 -0
- package/python/vendor/hkc/hkc_api/routes/ability.py +151 -0
- package/python/vendor/hkc/hkc_api/routes/config.py +51 -0
- package/python/vendor/hkc/hkc_api/routes/knowledge.py +630 -0
- package/python/vendor/hkc/hkc_api/routes/search.py +88 -0
- package/python/vendor/hkc/hkc_api/schemas.py +153 -0
- package/python/vendor/hkc/hkc_api/synthesis.py +179 -0
- package/python/vendor/hkc/hkc_core/__init__.py +0 -0
- package/python/vendor/hkc/hkc_core/graph/__init__.py +0 -0
- package/python/vendor/hkc/hkc_core/graph/base.py +188 -0
- package/python/vendor/hkc/hkc_core/graph/sqlite_store.py +789 -0
- package/python/vendor/hkc/hkc_core/models/__init__.py +0 -0
- package/python/vendor/hkc/hkc_core/models/enums.py +65 -0
- package/python/vendor/hkc/hkc_core/models/ku.py +307 -0
- package/python/vendor/hkc/hkc_core/utils/__init__.py +0 -0
- package/python/vendor/hkc/hkc_core/utils/id_gen.py +113 -0
- package/python/vendor/hkc/hkc_crystallizer/__init__.py +44 -0
- package/python/vendor/hkc/hkc_crystallizer/adapters.py +94 -0
- package/python/vendor/hkc/hkc_crystallizer/candidate.py +145 -0
- package/python/vendor/hkc/hkc_crystallizer/crystallizer.py +179 -0
- package/python/vendor/hkc/hkc_crystallizer/ingress.py +90 -0
- package/python/vendor/hkc/hkc_kde/__init__.py +0 -0
- package/python/vendor/hkc/hkc_kde/chunker.py +197 -0
- package/python/vendor/hkc/hkc_kde/extractor.py +623 -0
- package/python/vendor/hkc/hkc_kde/kde.py +298 -0
- package/python/vendor/hkc/hkc_kde/loaders/__init__.py +0 -0
- package/python/vendor/hkc/hkc_kde/loaders/ebook_loader.py +153 -0
- package/python/vendor/hkc/hkc_kde/loaders/office_loader.py +194 -0
- package/python/vendor/hkc/hkc_kde/loaders/pdf_loader.py +162 -0
- package/python/vendor/hkc/hkc_kde/loaders/text_loader.py +157 -0
- package/python/vendor/hkc/hkc_kde/loaders/web_loader.py +91 -0
- package/python/vendor/hkc/hkc_kde/models.py +74 -0
- package/python/vendor/hkc/hkc_kde/packager.py +329 -0
- package/python/vendor/hkc/hkc_kde/relation_disc.py +151 -0
- package/python/vendor/hkc/hkc_kee/__init__.py +0 -0
- package/python/vendor/hkc/hkc_kee/dedup.py +227 -0
- package/python/vendor/hkc/hkc_kee/fingerprint.py +106 -0
- package/python/vendor/hkc/hkc_kee/kee.py +541 -0
- package/python/vendor/hkc/hkc_kep/__init__.py +0 -0
- package/python/vendor/hkc/hkc_kep/event_bus.py +205 -0
- package/python/vendor/hkc/hkc_sdk/__init__.py +63 -0
- package/python/vendor/hkc/hkc_sdk/base.py +151 -0
- package/python/vendor/hkc/hkc_sdk/direct_client.py +153 -0
- package/python/vendor/hkc/hkc_sdk/exceptions.py +39 -0
- package/python/vendor/hkc/hkc_sdk/http_client.py +166 -0
- package/python/vendor/hkc/hkc_sdk/models.py +171 -0
- package/python/vendor/hkc/hkc_search/__init__.py +0 -0
- package/python/vendor/hkc/hkc_search/bm25.py +325 -0
- package/python/vendor/hkc/hkc_search/embedding_backends.py +374 -0
- package/python/vendor/hkc/hkc_search/graph_search.py +132 -0
- package/python/vendor/hkc/hkc_search/hybrid.py +331 -0
- package/python/vendor/hkc/hkc_search/index_build_manager.py +378 -0
- package/python/vendor/hkc/hkc_search/vector_search.py +484 -0
- package/python/vendor/hmr/__init__.py +0 -0
- package/python/vendor/hmr/core/__init__.py +0 -0
- package/python/vendor/hmr/core/hmr.py +684 -0
- package/python/vendor/hmr/core/models.py +310 -0
- package/python/vendor/hmr/engines/__init__.py +0 -0
- package/python/vendor/hmr/engines/evolution.py +710 -0
- package/python/vendor/hmr/engines/jit_compiler.py +472 -0
- package/python/vendor/hmr/engines/lifecycle.py +264 -0
- package/python/vendor/hmr/engines/policy.py +625 -0
- package/python/vendor/hmr/engines/recall.py +260 -0
- package/python/vendor/hmr/engines/runtime_state.py +158 -0
- package/python/vendor/hmr/engines/scheduler.py +323 -0
- package/python/vendor/hmr/engines/semantic.py +150 -0
- package/python/vendor/hmr/engines/temporal.py +261 -0
- package/python/vendor/hmr/engines/thought_chain.py +635 -0
- package/python/vendor/hmr/graph/__init__.py +0 -0
- package/python/vendor/hmr/graph/cwg.py +338 -0
- package/python/vendor/hmr/graph/memory_graph.py +530 -0
- package/python/vendor/hmr/storage/__init__.py +0 -0
- package/python/vendor/hmr/storage/memory_fs.py +300 -0
- package/python/vendor/hmr/storage/vector_store.py +520 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# 两段式发布。为什么不能"打 tag 就自动上传":
|
|
4
|
+
# PyPI / npm 的版本号**不可撤回** —— 传上去只能 yank(仍占号、仍能被 pin 装到),
|
|
5
|
+
# 不能覆盖重发。所以 CI 的默认行为是「校验 + 构建 + 挂 GitHub Release」,
|
|
6
|
+
# 真正的外发必须人工触发一次 workflow_dispatch,并在 environment 里审批。
|
|
7
|
+
#
|
|
8
|
+
# 阶段一(push tag v*):版本/tag 一致性 → 构建 wheel+sdist+npm tgz → 产物结构校验
|
|
9
|
+
# → GitHub Release 附件(可反复重跑,错了删 tag 重来)
|
|
10
|
+
# 阶段二(workflow_dispatch):勾 publish=pypi/npm/both + 填 ref=tag,审批后才上传
|
|
11
|
+
#
|
|
12
|
+
# 需要预先准备(仓库 Settings):
|
|
13
|
+
# Environments: pypi、npm(各配 Required reviewers → 这就是"审批门")
|
|
14
|
+
# Secrets: PYPI_API_TOKEN(npt_... 项目级 token)、NPM_TOKEN(granular,仅 publish)
|
|
15
|
+
# 换 OIDC 时:PyPI 用 pending publisher、npm 用 trusted publishing,
|
|
16
|
+
# 把 publish-* 里的 password/NODE_AUTH_TOKEN 去掉并加 `permissions: id-token: write`。
|
|
17
|
+
on:
|
|
18
|
+
push:
|
|
19
|
+
tags: ["v*"]
|
|
20
|
+
workflow_dispatch:
|
|
21
|
+
inputs:
|
|
22
|
+
publish:
|
|
23
|
+
description: "上传目标(需对应 environment 审批)"
|
|
24
|
+
type: choice
|
|
25
|
+
options: ["none", "pypi", "npm", "both"]
|
|
26
|
+
default: "none"
|
|
27
|
+
ref:
|
|
28
|
+
description: "要构建/发布的 tag(如 v0.1.0;发布时必填)"
|
|
29
|
+
type: string
|
|
30
|
+
default: ""
|
|
31
|
+
|
|
32
|
+
permissions:
|
|
33
|
+
contents: read
|
|
34
|
+
|
|
35
|
+
# 同一 tag 并发跑两次发布 = 两个进程抢同一个版本号
|
|
36
|
+
concurrency:
|
|
37
|
+
group: release-${{ github.ref }}
|
|
38
|
+
cancel-in-progress: false
|
|
39
|
+
|
|
40
|
+
jobs:
|
|
41
|
+
build:
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
timeout-minutes: 15
|
|
44
|
+
steps:
|
|
45
|
+
- uses: actions/checkout@v4
|
|
46
|
+
with:
|
|
47
|
+
ref: ${{ inputs.ref || github.ref }}
|
|
48
|
+
|
|
49
|
+
- uses: actions/setup-python@v5
|
|
50
|
+
with:
|
|
51
|
+
python-version: "3.12"
|
|
52
|
+
|
|
53
|
+
- uses: actions/setup-node@v4
|
|
54
|
+
with:
|
|
55
|
+
node-version: "20"
|
|
56
|
+
|
|
57
|
+
- name: Install release toolchain
|
|
58
|
+
# 只装构建器,不 `pip install -e .`:构建 wheel 不需要 torch/faiss 那套运行时
|
|
59
|
+
# 依赖(唯一 import 的 release_check.py 是纯标准库),装了只会把 job 拖成 5 分钟。
|
|
60
|
+
run: |
|
|
61
|
+
python -m pip install --upgrade pip
|
|
62
|
+
pip install "build>=1.2"
|
|
63
|
+
|
|
64
|
+
# 发布必须锚定 tag:否则发出去的是分支 HEAD,版本号对不上任何 tag,
|
|
65
|
+
# 事后连"这版对应哪次提交"都答不上来。
|
|
66
|
+
- name: Require tag when publishing
|
|
67
|
+
if: github.event_name == 'workflow_dispatch' && inputs.publish != 'none'
|
|
68
|
+
env:
|
|
69
|
+
REF: ${{ inputs.ref }}
|
|
70
|
+
run: |
|
|
71
|
+
if [ -z "$REF" ]; then
|
|
72
|
+
echo "::error::publish=${{ inputs.publish }} 时必须填 ref(如 v0.1.0),不能发分支 HEAD"
|
|
73
|
+
exit 1
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
- name: Version / tag gate
|
|
77
|
+
env:
|
|
78
|
+
TAG: ${{ github.event_name == 'push' && github.ref_name || inputs.ref }}
|
|
79
|
+
run: |
|
|
80
|
+
if [ -n "$TAG" ]; then
|
|
81
|
+
python tools/release_check.py --tag "$TAG"
|
|
82
|
+
else
|
|
83
|
+
python tools/release_check.py
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
- name: Build wheel + sdist
|
|
87
|
+
run: python -m build --outdir dist
|
|
88
|
+
|
|
89
|
+
- name: Pack npm tarball
|
|
90
|
+
# 必须先跑 build.cjs:它把项目源码复制进 npm/python/,npm 包才算完整。
|
|
91
|
+
# `npm pack` 不触发 prepublishOnly(只有 publish 才触发),漏了这步打出来的
|
|
92
|
+
# 是 2KB 空壳——里面没有 python/,npx foxclaw 直接跑不起来。
|
|
93
|
+
# 同时 build.cjs 自带红线自检:含内部文档就 exit 1,构建随之失败。
|
|
94
|
+
working-directory: npm
|
|
95
|
+
run: |
|
|
96
|
+
node build.cjs
|
|
97
|
+
npm pack --pack-destination ../dist
|
|
98
|
+
|
|
99
|
+
- name: Artifact gate
|
|
100
|
+
# 包里出现 .env / docs/internal / 运行期数据 = 停下,不许发(宁可不出包)
|
|
101
|
+
run: python tools/release_check.py --dist dist --npm-tgz dist/*.tgz
|
|
102
|
+
|
|
103
|
+
- uses: actions/upload-artifact@v4
|
|
104
|
+
with:
|
|
105
|
+
name: python-dist
|
|
106
|
+
path: |
|
|
107
|
+
dist/*.whl
|
|
108
|
+
dist/*.tar.gz
|
|
109
|
+
if-no-files-found: error
|
|
110
|
+
|
|
111
|
+
- uses: actions/upload-artifact@v4
|
|
112
|
+
with:
|
|
113
|
+
name: npm-tgz
|
|
114
|
+
path: dist/*.tgz
|
|
115
|
+
if-no-files-found: error
|
|
116
|
+
|
|
117
|
+
github-release:
|
|
118
|
+
# 只有 tag 才挂 Release;手工触发构建不建 Release
|
|
119
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
120
|
+
needs: build
|
|
121
|
+
runs-on: ubuntu-latest
|
|
122
|
+
permissions:
|
|
123
|
+
contents: write
|
|
124
|
+
steps:
|
|
125
|
+
- uses: actions/download-artifact@v4
|
|
126
|
+
with:
|
|
127
|
+
path: dist
|
|
128
|
+
merge-multiple: true
|
|
129
|
+
|
|
130
|
+
- name: Publish GitHub Release
|
|
131
|
+
env:
|
|
132
|
+
GH_TOKEN: ${{ github.token }}
|
|
133
|
+
GH_REPO: ${{ github.repository }}
|
|
134
|
+
TAG: ${{ github.ref_name }}
|
|
135
|
+
run: |
|
|
136
|
+
if gh release view "$TAG" >/dev/null 2>&1; then
|
|
137
|
+
gh release upload "$TAG" dist/* --clobber # 重跑时覆盖附件,不重建 Release
|
|
138
|
+
else
|
|
139
|
+
gh release create "$TAG" dist/* --title "$TAG" --generate-notes
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
publish-pypi:
|
|
143
|
+
if: >-
|
|
144
|
+
github.event_name == 'workflow_dispatch' &&
|
|
145
|
+
(inputs.publish == 'pypi' || inputs.publish == 'both')
|
|
146
|
+
needs: build
|
|
147
|
+
runs-on: ubuntu-latest
|
|
148
|
+
# environment 上配 Required reviewers:这一步停在"等待审批",人点了才动
|
|
149
|
+
environment: pypi
|
|
150
|
+
steps:
|
|
151
|
+
- uses: actions/download-artifact@v4
|
|
152
|
+
with:
|
|
153
|
+
name: python-dist
|
|
154
|
+
path: dist
|
|
155
|
+
|
|
156
|
+
- name: Upload to PyPI
|
|
157
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
158
|
+
with:
|
|
159
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
160
|
+
packages-dir: dist/
|
|
161
|
+
|
|
162
|
+
publish-npm:
|
|
163
|
+
if: >-
|
|
164
|
+
github.event_name == 'workflow_dispatch' &&
|
|
165
|
+
(inputs.publish == 'npm' || inputs.publish == 'both')
|
|
166
|
+
needs: build
|
|
167
|
+
runs-on: ubuntu-latest
|
|
168
|
+
environment: npm
|
|
169
|
+
steps:
|
|
170
|
+
- uses: actions/setup-node@v4
|
|
171
|
+
with:
|
|
172
|
+
node-version: "20"
|
|
173
|
+
registry-url: "https://registry.npmjs.org"
|
|
174
|
+
|
|
175
|
+
- uses: actions/download-artifact@v4
|
|
176
|
+
with:
|
|
177
|
+
name: npm-tgz
|
|
178
|
+
path: dist
|
|
179
|
+
|
|
180
|
+
- name: Publish to npm
|
|
181
|
+
env:
|
|
182
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
183
|
+
run: npm publish ./dist/*.tgz --access public
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Changes from the first public release 0.1.0 to the current version, newest first.
|
|
4
|
+
|
|
5
|
+
Chinese version: [CHANGELOG_CN.md](CHANGELOG_CN.md).
|
|
6
|
+
|
|
7
|
+
## 0.1.3 — 2026-11-11
|
|
8
|
+
|
|
9
|
+
Bilingual interface, and Settings moved where it belongs.
|
|
10
|
+
|
|
11
|
+
**Interface**
|
|
12
|
+
|
|
13
|
+
- New i18n layer (`lib/i18n.js` plus en/zh dictionaries): sidebar, menus, chat, stage, settings and toast strings all resolve through the dictionaries; a missing key falls back to the key, so nothing renders blank.
|
|
14
|
+
- Settings gains "Interface → Language" with instant Chinese / English switching, persisted in `localStorage` (`foxclawLang`) and kept across reloads.
|
|
15
|
+
- Date and number formatting follow the language (`zh-CN` / `en-US`), and `<html lang>` stays in sync.
|
|
16
|
+
- Settings moved out of the "More" popover into a pinned entry at the bottom of the left rail, separated by a rule and left unaffected by session-list scrolling.
|
|
17
|
+
- The version badge in the top bar reads `/api/system/info`; it no longer falls back to a hard-coded `v3.0`.
|
|
18
|
+
|
|
19
|
+
**Docs**
|
|
20
|
+
|
|
21
|
+
- README reconciled with the repository as it actually is: agent count, channels, ingest caps, chunk geometry, supported formats and internal links all verified one by one, with a test to keep them from drifting again.
|
|
22
|
+
|
|
23
|
+
## 0.1.2 — 2026-11-10
|
|
24
|
+
|
|
25
|
+
Version consolidation and skill installation.
|
|
26
|
+
|
|
27
|
+
- Version number unified across five places (`pyproject.toml` / `foxclaw/__init__.py` / `npm/package.json` / `npm/index.js` / `frontend_src/package.json`), guarded by `tests/test_version_sync.py` so npm and PyPI cannot drift apart.
|
|
28
|
+
- `foxclaw skills install` accepts ClawHub / GitHub / URL / local archives; the tools panel can install an instruction skill straight from an uploaded `SKILL.md` or OpenClaw package.
|
|
29
|
+
- First run asks how to address you (editable in settings); an optional new-version check was added.
|
|
30
|
+
- `tools/sync_public.ps1` now builds the public tree directly instead of relying on a local clone.
|
|
31
|
+
- Type annotations closed out: mypy went from 645 to 0, and CI turned into a ratchet that may only go down.
|
|
32
|
+
- Explanatory comments stripped repo-wide, so the public tree no longer carries internal notes.
|
|
33
|
+
|
|
34
|
+
## 0.1.1 — 2026-11-09
|
|
35
|
+
|
|
36
|
+
npm-only republish; there is no matching version bump in the repository.
|
|
37
|
+
|
|
38
|
+
- The npm package excludes internal docs (`docs/reports` and friends) and debug leftovers, aborting the pack when any are detected — 0.1.1 had shipped internal documents in the public package.
|
|
39
|
+
- `build.cjs` now runs before `npm pack`, fixing GitHub Release assets that were 2 KB empty shells.
|
|
40
|
+
- `pyproject` gained a readme, so the PyPI page is no longer description-less.
|
|
41
|
+
- `requirements.txt` is compiled with `uv pip compile --universal` so platform-specific dependencies carry markers; CI gained a dependency audit gate.
|
|
42
|
+
- MIT license and metadata added.
|
|
43
|
+
|
|
44
|
+
## 0.1.0 — 2026-11-06
|
|
45
|
+
|
|
46
|
+
First public release, on both channels: PyPI `foxclaw` and npm `foxclaw`.
|
|
47
|
+
|
|
48
|
+
- Runtime: FastAPI service plus the `foxclaw` command-line entry point.
|
|
49
|
+
- Agents: multiple agents collapsed into three (assistant / office / knowledge); the rest were demoted to instruction skills.
|
|
50
|
+
- Knowledge (HKC) and memory (HMR) embedded via `vendor/`: knowledge is extractable and searchable, and review scheduling runs on SM-2.
|
|
51
|
+
- Governance: policy gate, audit hash chain, shadow learning and circuit breaker; import paths are allow-listed and skill side effects default to fail-closed.
|
|
52
|
+
- Config: typed reads instead of raw `.env`, and `foxclaw config check` turns a misconfiguration from a crash into a message.
|
|
53
|
+
- Security: DNS rebinding, browser SSRF and untrusted channel instructions closed off; channel path signatures plus one-shot nonces for sensitive actions.
|
|
54
|
+
- Pipeline: visible plans, reasoning emitted as its own SSE event, step-level checkpoints for resume-after-interrupt.
|
|
55
|
+
- Frontend: Vue3 three-column renderer, persistent feature entries in the left rail, dual-state inspector on the right.
|
|
56
|
+
|
|
57
|
+
> Both packages are **placeholders**: `vendor/` (HKC / HMR) is not shipped, so a fresh install only gets the importable skeleton. See [docs/RELEASE.md](docs/RELEASE.md).
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# 更新日志
|
|
2
|
+
|
|
3
|
+
从 0.1.0 首次公开到当前版本的变更记录,最新的排在最前面。
|
|
4
|
+
|
|
5
|
+
英文版:[CHANGELOG.md](CHANGELOG.md)。
|
|
6
|
+
|
|
7
|
+
## 0.1.3 — 2026-11-11
|
|
8
|
+
|
|
9
|
+
界面双语化,并把「设置」放到该在的位置。
|
|
10
|
+
|
|
11
|
+
**界面**
|
|
12
|
+
|
|
13
|
+
- 新增 i18n 基建(`lib/i18n.js` + 中英字典),侧栏、菜单、对话、舞台、设置、提示文案统一走字典;缺词回退 key,不会渲染成空白。
|
|
14
|
+
- 设置面板新增「界面 → 语言」,中文 / English 即时切换,写入 `localStorage`(`foxclawLang`),刷新后保持。
|
|
15
|
+
- 日期与数字格式随语言切换(`zh-CN` / `en-US`),`<html lang>` 同步。
|
|
16
|
+
- 「设置」从「更多」弹层移到左栏底部常驻入口,带分隔线,不随会话列表滚动。
|
|
17
|
+
- 顶栏版本号改为读后端 `/api/system/info`,取不到时不再显示硬编码的 `v3.0`。
|
|
18
|
+
|
|
19
|
+
**文档**
|
|
20
|
+
|
|
21
|
+
- README 按仓库实际校准:智能体数量、渠道、摄取上限、分块几何、支持格式、内部链接全部逐条核对,并加测试防止再次漂移。
|
|
22
|
+
|
|
23
|
+
## 0.1.2 — 2026-11-10
|
|
24
|
+
|
|
25
|
+
版本号收口、技能安装成型。
|
|
26
|
+
|
|
27
|
+
- 版本号五处统一(`pyproject.toml` / `foxclaw/__init__.py` / `npm/package.json` / `npm/index.js` / `frontend_src/package.json`),并由 `tests/test_version_sync.py` 盯住,防 npm 与 PyPI 漂移。
|
|
28
|
+
- `foxclaw skills install` 支持 ClawHub / GitHub / URL / 本地包;工具面板可直接上传 `SKILL.md` 或 OpenClaw 包安装指令技能。
|
|
29
|
+
- 首次启动引导询问称呼,可在设置中修改;新增可选的新版本检查提示。
|
|
30
|
+
- `tools/sync_public.ps1` 改为直接构造公开树推远端,不再依赖本地克隆。
|
|
31
|
+
- 类型标注收口:mypy 从 645 降到 0,CI 改为棘轮门(只降不升)。
|
|
32
|
+
- 全仓剥离解释性注释,公开树下不再混入内部说明。
|
|
33
|
+
|
|
34
|
+
## 0.1.1 — 2026-11-09
|
|
35
|
+
|
|
36
|
+
只在 npm 通道补发,仓库内没有对应版本号的提交记录。
|
|
37
|
+
|
|
38
|
+
- npm 包排除 `docs/reports` 等内部文档与调试残留,自检命中即中止打包(0.1.1 曾把内部文档打进公开包)。
|
|
39
|
+
- `npm pack` 前先跑 `build.cjs`,修 GitHub Release 附件只有 2KB 空壳。
|
|
40
|
+
- 修 `pyproject` 缺 `readme`,PyPI 项目页不再没有项目描述。
|
|
41
|
+
- `requirements.txt` 改用 `uv pip compile --universal`,平台相关依赖带上 marker;CI 增加依赖审计门。
|
|
42
|
+
- 补 MIT 许可证与 metadata。
|
|
43
|
+
|
|
44
|
+
## 0.1.0 — 2026-11-06
|
|
45
|
+
|
|
46
|
+
首个公开版本,PyPI `foxclaw` 与 npm `foxclaw` 双通道。
|
|
47
|
+
|
|
48
|
+
- 运行时:FastAPI 服务 + `foxclaw` 命令行入口。
|
|
49
|
+
- 智能体:多智能体收敛为三(助手 / 办公 / 知识),其余能力下放为指令技能。
|
|
50
|
+
- 知识库(HKC)与记忆(HMR)以内嵌 `vendor/` 形式接入:知识可抽取、可检索,复习走 SM-2 排程。
|
|
51
|
+
- 治理层:策略门、审计哈希链、影子学习与断路器;导入路径白名单,技能副作用默认 fail-closed。
|
|
52
|
+
- 配置:从 `.env` 改为类型化读取,`foxclaw config check` 把「配置写错」从崩溃变成提示。
|
|
53
|
+
- 安全:堵 DNS rebinding、浏览器 SSRF、渠道陌生指令三个可利用面;渠道路径签名 + 动作一次性 nonce 确认。
|
|
54
|
+
- 链路:计划可见化、推理过程独立 SSE 事件、步骤级 checkpoint 断点续跑。
|
|
55
|
+
- 前端:Vue3 三栏渲染层,左栏功能入口常驻,右栏双态检视。
|
|
56
|
+
|
|
57
|
+
> 两个包都是**占位包**:`vendor/`(HKC / HMR)不入包,装完只能 import 骨架,完整运行时从仓库获取。详见 [docs/RELEASE.md](docs/RELEASE.md)。
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# syntax=docker/dockerfile:1
|
|
2
|
+
|
|
3
|
+
# Foxclaw — 认知智能体操作系统
|
|
4
|
+
#
|
|
5
|
+
# 一个镜像两种用法:
|
|
6
|
+
# 1) 跑服务:docker run -p 8000:8000 foxclaw
|
|
7
|
+
# 2) 跑全量回归(构建/CI 自检):docker run --rm foxclaw python tests/run_all.py
|
|
8
|
+
#
|
|
9
|
+
# 镜像较大(>2GB)是 sentence-transformers/torch 的代价——语义检索与治理漂移检测
|
|
10
|
+
# 都依赖真实 embedding,这是能力而非可裁剪项。测试锁 HF_HUB_OFFLINE 离线读预热缓存。
|
|
11
|
+
|
|
12
|
+
FROM python:3.12-slim
|
|
13
|
+
|
|
14
|
+
ENV PYTHONUNBUFFERED=1 \
|
|
15
|
+
PIP_NO_CACHE_DIR=1 \
|
|
16
|
+
PYTHONDONTWRITEBYTECODE=1 \
|
|
17
|
+
HF_HOME=/root/.cache/huggingface
|
|
18
|
+
|
|
19
|
+
WORKDIR /app
|
|
20
|
+
|
|
21
|
+
# 系统依赖:torch 需要 libgomp1(OpenMP 运行时)。slim 镜像默认缺失,
|
|
22
|
+
# 缺了会在 import torch 时报 libgomp.so.1 找不到。
|
|
23
|
+
RUN apt-get update \
|
|
24
|
+
&& apt-get install -y --no-install-recommends libgomp1 \
|
|
25
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
26
|
+
|
|
27
|
+
# ── 依赖层(利用 Docker layer 缓存:改源码不重装 torch)──────────────
|
|
28
|
+
# 必须拷 foxclaw/ 与 vendor/ 才能 editable install(HMR/HKC 是 vendor 内嵌、
|
|
29
|
+
# 走 sys.path 加载,非 PyPI 依赖,见 pyproject.toml 注记)。
|
|
30
|
+
COPY pyproject.toml ./
|
|
31
|
+
COPY foxclaw/ foxclaw/
|
|
32
|
+
COPY vendor/ vendor/
|
|
33
|
+
|
|
34
|
+
# 依赖以 pyproject.toml 为唯一来源;dev extra 补 pytest/ruff/mypy/coverage +
|
|
35
|
+
# openpyxl/python-docx(默认回归 test_file_ingest/test_domain_import 硬依赖),
|
|
36
|
+
# 使镜像既能跑服务又能跑全量回归(与 CI 对齐)。
|
|
37
|
+
# 【关键】先装 CPU 版 torch:PyPI 默认 torch 在 Linux 上会拖入整套 CUDA toolkit
|
|
38
|
+
# (nvidia-* 十几个包 + cuda-toolkit,镜像 +4GB、下载极慢),而 Foxclaw 语义检索
|
|
39
|
+
# 只需 CPU。先从 PyTorch 官方 CPU index 装好 torch,sentence-transformers 见
|
|
40
|
+
# 约束已满足即不再重装 CUDA 版。
|
|
41
|
+
# --mount=type=cache 复用 pip 下载缓存:改依赖后重建无需重下 torch 等大 wheel
|
|
42
|
+
# --retries/--timeout:国内网络抖动时 pip 默认重试(5次/15s)偏短,会把 filelock 等
|
|
43
|
+
# 依赖的 index 元数据请求超时误判为"无匹配发行版"(ResolutionImpossible),放宽后更稳。
|
|
44
|
+
RUN --mount=type=cache,target=/root/.cache/pip pip install --upgrade pip \
|
|
45
|
+
&& pip install --retries 8 --timeout 60 torch --index-url https://download.pytorch.org/whl/cpu \
|
|
46
|
+
&& pip install --retries 8 --timeout 60 -e ".[dev]"
|
|
47
|
+
|
|
48
|
+
# ── 预热默认 embedding(all-MiniLM-L6-v2)────────────────────────────
|
|
49
|
+
# run_all.py 内部注入 HF_HUB_OFFLINE=1 离线读取。若镜像内没有缓存,
|
|
50
|
+
# sentence-transformers 会降级为 n-gram 哈希嵌入——对中文几乎无区分度,
|
|
51
|
+
# 语义漂移分恒为 1.0 → 治理测试全红(见 .github/workflows/ci.yml 的教训)。
|
|
52
|
+
# 故在 build 期一次性下载好,运行期离线可用、不依赖外网。
|
|
53
|
+
# 【HF_ENDPOINT】默认走 hf-mirror.com(国内直连 huggingface.co 常被墙、DNS 解析失败);
|
|
54
|
+
# 海外/CI 可 `docker build --build-arg HF_ENDPOINT= ...` 覆盖,或留空走官方 HuggingFace。
|
|
55
|
+
ARG HF_ENDPOINT=https://hf-mirror.com
|
|
56
|
+
RUN HF_ENDPOINT="${HF_ENDPOINT}" python -c "from sentence_transformers import SentenceTransformer; SentenceTransformer('all-MiniLM-L6-v2')"
|
|
57
|
+
|
|
58
|
+
# ── 其余仓库内容(frontend 前端静态 / skills / docs 等)──────────────
|
|
59
|
+
COPY . .
|
|
60
|
+
|
|
61
|
+
EXPOSE 8000
|
|
62
|
+
|
|
63
|
+
# 默认启动 API 服务;跑回归用:docker run --rm foxclaw python tests/run_all.py
|
|
64
|
+
CMD ["python", "-m", "uvicorn", "foxclaw.api:app", "--host", "0.0.0.0", "--port", "8000"]
|
package/python/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 snowfoxHQ
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# sdist 必须自带 vendor/ 下的 HMR 与 HKC —— 它们是内嵌运行时,不是 PyPI 依赖。
|
|
2
|
+
# 缺了它们,pip install 装出来的包记忆/知识子系统会整体降级为 None。
|
|
3
|
+
graft vendor
|
|
4
|
+
graft foxclaw
|
|
5
|
+
|
|
6
|
+
# sdist 必须带正文文件:pyproject 的 readme 指向 README_CN.md,PyPI 项目页正文取自它。
|
|
7
|
+
include README.md
|
|
8
|
+
include README_CN.md
|
|
9
|
+
include LICENSE
|
|
10
|
+
|
|
11
|
+
prune vendor/__pycache__
|
|
12
|
+
prune foxclaw/__pycache__
|
|
13
|
+
global-exclude *.pyc
|
|
14
|
+
global-exclude *.pyo
|
package/python/README.md
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Foxclaw · A Personal Agent with Memory
|
|
2
|
+
|
|
3
|
+
A **personal agent with memory** — to a user, an agent that remembers; to a developer, an agent runtime built on the HMR memory runtime: three collaborating agents, cross-layer Harness governance, with the memory/cognition layer fully decoupled from any LLM.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
Traditional frameworks: memory = storage, agents = stateless execution
|
|
7
|
+
Foxclaw: memory = living cognitive runtime, agents = reason · learn · evolve
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## What it is
|
|
11
|
+
|
|
12
|
+
Foxclaw is not "yet another agent framework" but a personal agent that actually remembers; under the hood, an agent runtime. Its moats are independent of any LLM:
|
|
13
|
+
|
|
14
|
+
- **ThoughtChain** — each agent's reasoning is an auditable, comparable directed graph, not a log
|
|
15
|
+
- **Harness** — three-dimensional drift detection (semantic / tool / scope) + shadow-mode self-calibration + policy self-learning
|
|
16
|
+
- **Evolution** — every harness truncation teaches the policy; the system gets sharper with use
|
|
17
|
+
- **Runtime governance** — idempotency, crash recovery, loop detection, etc., keeping the system reliable under real-world operation
|
|
18
|
+
|
|
19
|
+
Three agents: Supervisor (coordination), Finance, Office (learning + itinerary). Each has isolated memory and policy evolution, mounts external ecosystems via the Skill layer, and connects to mainstream messaging platforms via the channel layer. The former Assistant and Admin responsibilities are now **instruction skills** (`skills/general-assistant`, `skills/schedule-itinerary`) mounted on demand, not separate agents.
|
|
20
|
+
|
|
21
|
+
## Domain kernels
|
|
22
|
+
|
|
23
|
+
Finance / Office each mount an isomorphic kernel (pure-algorithm layer + external tool interface + gatekeeper):
|
|
24
|
+
|
|
25
|
+
- **Finance** — budget reasoning, MAD anomaly detection, cash-flow forecast; gatekeeper with four permissions, emits approval requests rather than moving money. **Advanced trio**: structured evidence chains (explainable risk), financial data graph (trace who caused an overspend), reconciliation (3-tier matching + suspicious-charge detection).
|
|
26
|
+
- **Office** — SM-2 spaced repetition (mastery + forgetting risk) + knowledge graph (cluster discovery).
|
|
27
|
+
- **Office · itinerary** — TSP routing, reachability ("won't make it") detection, time conflicts, geo-clustering; integrates Amap.
|
|
28
|
+
|
|
29
|
+
## Messaging platforms
|
|
30
|
+
|
|
31
|
+
Four mainstream platforms via a unified channel abstraction, **each adapter implemented to its own official spec** (not one mold):
|
|
32
|
+
|
|
33
|
+
| Channel | Model | Credential |
|
|
34
|
+
|---------|-------|-----------|
|
|
35
|
+
| WeChat | iLink Bot API, long-poll + context_token | scan-login token |
|
|
36
|
+
| Feishu | event-subscription webhook + signature + token refresh | App ID/Secret |
|
|
37
|
+
| Telegram | Bot API getUpdates polling | bot token |
|
|
38
|
+
| Discord | Gateway WebSocket + REST | bot token |
|
|
39
|
+
|
|
40
|
+
Closed loop (`ChannelDispatcher`): receive → Supervisor → reply to origin, with per-channel session isolation and idempotent dedup. See [docs/CHANNELS.md](docs/CHANNELS.md).
|
|
41
|
+
|
|
42
|
+
## Runtime governance
|
|
43
|
+
|
|
44
|
+
Keeps the system reliable under message redelivery, crashes, long tasks, and loops. See [docs/GOVERNANCE.md](docs/GOVERNANCE.md): idempotency guard, crash/restart recovery (boot_id avoids pid reuse), tool-loop detection, context compaction, hook standardization, steering queue.
|
|
45
|
+
|
|
46
|
+
## Quick start
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
python -m venv .venv # isolated env — don't pollute the system Python
|
|
50
|
+
.venv\Scripts\activate # macOS / Linux: source .venv/bin/activate
|
|
51
|
+
pip install -r requirements.txt # pinned closure generated from pyproject.toml
|
|
52
|
+
pip install -e . --no-deps # foxclaw itself, without re-resolving deps
|
|
53
|
+
python tests/run_all.py # full regression (all green)
|
|
54
|
+
export DEEPSEEK_API_KEY=sk-... # or ANTHROPIC_API_KEY; unset → stub
|
|
55
|
+
python -m uvicorn foxclaw.api:app --port 8000
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
> `requirements.txt` is generated by `uv pip compile pyproject.toml --universal -o requirements.txt` — don't hand-edit.
|
|
59
|
+
> `--universal` is required: without it the compile is platform-specific and drags Windows-only packages
|
|
60
|
+
> (e.g. `pywin32`) into the list, which breaks installation on Linux CI. With it, platform deps carry
|
|
61
|
+
> `; sys_platform == ...` markers and pip skips what doesn't apply.
|
|
62
|
+
> Re-run after changing dependencies in `pyproject.toml`, otherwise the lock lags behind the declaration.
|
|
63
|
+
|
|
64
|
+
See [docs/RUN.md](docs/RUN.md). Chinese docs: [README_CN.md](README_CN.md). Release history: [CHANGELOG.md](CHANGELOG.md).
|
|
65
|
+
|
|
66
|
+
> **Windows**: don't place the project under OneDrive-managed folders (Documents/Desktop/Pictures); Python can't create dirs inside redirect placeholders. Use a path like `C:\foxclaw`.
|
|
67
|
+
|
|
68
|
+
## Knowledge base (HKC) model config
|
|
69
|
+
|
|
70
|
+
HKC's knowledge base uses **two different types of models**, each for one job, both configured in `.env` — no code changes:
|
|
71
|
+
|
|
72
|
+
| Stage | Model type | What it does | Config keys |
|
|
73
|
+
|-------|-----------|-------------|-------------|
|
|
74
|
+
| Write (ingesting books/files) | **Generative LLM** (reads & emits JSON) | Extracts entities / concepts / facts / claims from each chunk | `HKC_LLM_*` |
|
|
75
|
+
| Retrieve (querying) | **embedding** (text → vector) | Vectorizes knowledge & queries, ranks by semantic similarity | `HKC_EMBEDDING_*` |
|
|
76
|
+
|
|
77
|
+
They are not interchangeable: an embedding model cannot generate text (can't produce JSON), and an LLM is not suited to vector search.
|
|
78
|
+
|
|
79
|
+
### First, pick your case
|
|
80
|
+
|
|
81
|
+
| Your environment | Extraction model setup | `HKC_LLM_API_KEY` value |
|
|
82
|
+
|---|---|---|
|
|
83
|
+
| Have local Ollama | `openai-compatible` + `base_url` pointing at Ollama | **any non-empty value** (Ollama ignores it; `ollama` is just a placeholder) |
|
|
84
|
+
| No local model | Use a **public cloud model** (DeepSeek / OpenAI / Qwen …), see table | the platform's **real API key** |
|
|
85
|
+
|
|
86
|
+
### Case A · local Ollama
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
HKC_LLM_PROVIDER=openai-compatible
|
|
90
|
+
HKC_LLM_API_KEY=ollama # placeholder only for local Ollama; never use this for cloud
|
|
91
|
+
HKC_LLM_MODEL=my-qwen-32k:latest # a model name from your `ollama list`
|
|
92
|
+
HKC_LLM_BASE_URL=http://localhost:11434/v1 # Ollama's OpenAI-compatible endpoint
|
|
93
|
+
HKC_LLM_TIMEOUT=180 # local models are slow; relax the default 60s
|
|
94
|
+
HKC_EXTRACT_CONCURRENCY=2 # 1–2 for local, up to 5 for cloud APIs
|
|
95
|
+
HKC_EXTRACT_BATCH=8 # optional: extract N chunks per call, saves tokens & time; default 1 = per-chunk
|
|
96
|
+
HKC_MAX_CHUNKS_PER_DOC=800 # optional: per-doc chunk cap; default 800 (~1.25M chars); 0 = no cap, see below
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Case B · public cloud model (no local model)
|
|
100
|
+
|
|
101
|
+
`HKC_LLM_MODEL` is the platform's **public model id** (passed through verbatim); `HKC_LLM_API_KEY` is the platform's **real key**:
|
|
102
|
+
|
|
103
|
+
| Platform | `HKC_LLM_PROVIDER` | `HKC_LLM_API_KEY` | `HKC_LLM_MODEL` example | `HKC_LLM_BASE_URL` |
|
|
104
|
+
|---|---|---|---|---|
|
|
105
|
+
| DeepSeek | `deepseek` | `sk-...` (DeepSeek key) | `deepseek-chat` / `deepseek-reasoner` | leave blank (official default) |
|
|
106
|
+
| OpenAI | `openai` | `sk-...` (OpenAI key) | `gpt-4o-mini` / `gpt-4o` | leave blank |
|
|
107
|
+
| Qwen (Alibaba) | `openai-compatible` | DashScope key | `qwen-max` / `qwen-plus` | `https://dashscope.aliyuncs.com/compatible-mode/v1` |
|
|
108
|
+
| Zhipu / Moonshot / MiniMax … | `openai-compatible` | that platform's key | that platform's model id | that platform's OpenAI-compatible URL |
|
|
109
|
+
|
|
110
|
+
DeepSeek example:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
HKC_LLM_PROVIDER=deepseek
|
|
114
|
+
HKC_LLM_API_KEY=sk-your-deepseek-key
|
|
115
|
+
HKC_LLM_MODEL=deepseek-chat
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Retrieval model (embedding)
|
|
119
|
+
|
|
120
|
+
The retrieval model does **not** use Ollama; it uses sentence-transformers, and auto-downloads weights from HuggingFace when missing locally:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
HKC_EMBEDDING=local
|
|
124
|
+
HKC_EMBEDDING_MODEL=BAAI/bge-m3 # auto-downloads on first use (~2.2 GB); or a local path like C:\...\bge-m3
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Leave it unset if you don't need semantic precision (defaults to `stub` pseudo-semantics, works out of the box).
|
|
128
|
+
|
|
129
|
+
### Where to put the key, and precedence
|
|
130
|
+
|
|
131
|
+
- **`.env` is the source of truth** — read at startup; restart after editing.
|
|
132
|
+
- The "extraction model" section in the planet page's connection settings is an **optional runtime override** (stored in browser localStorage, may override `.env` on refresh); leave it blank to always follow `.env`.
|
|
133
|
+
- The page's first "API Key" field is the backend auth token (`.env`'s `FOXCLAW_API_KEY`), unrelated to the model keys.
|
|
134
|
+
|
|
135
|
+
> Note: switching the embedding model changes the vector dimension (e.g. 384 → 1024), so you must rebuild the knowledge index (clear and re-ingest).
|
|
136
|
+
|
|
137
|
+
### How much can I ingest at once?
|
|
138
|
+
|
|
139
|
+
**The limits are hard — exceeding them returns an error, never a silent truncation:**
|
|
140
|
+
|
|
141
|
+
| Entry point | Limit | On overflow |
|
|
142
|
+
|---|---|---|
|
|
143
|
+
| File upload (`/knowledge/ingest/file`, `/ingest/file/async`) | **20 MB per file** | `413 file too large` |
|
|
144
|
+
| Pasted text (`/knowledge/ingest/text`) | **2,000,000 characters** | `413 text too large` |
|
|
145
|
+
| Chunks per document | **800 by default** (~1.25M chars); `HKC_MAX_CHUNKS_PER_DOC=0` disables the cap | Only the first N chunks are processed, with a "document too large" warning |
|
|
146
|
+
|
|
147
|
+
Supported formats: `.pdf` `.md` `.markdown` `.txt` `.epub` `.mobi` `.azw3` `.azw` `.docx` `.xlsx`. `.doc` is not supported, and **scanned PDFs get no OCR** — image-only pages yield no text at all.
|
|
148
|
+
|
|
149
|
+
**A chunk is the billing and timing unit**, and it is fixed:
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
max 1792 chars per chunk, 224 chars of overlap
|
|
153
|
+
→ roughly 1 chunk per 1568 characters
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Time and cost reference** (batch=4, concurrency=8, cloud DeepSeek, CJK content):
|
|
157
|
+
|
|
158
|
+
| Content | File size | Chunks | Expected time |
|
|
159
|
+
|---|---|---|---|
|
|
160
|
+
| 100k chars | ~100 KB | ~64 | ~6 min |
|
|
161
|
+
| 500k chars | ~500 KB | ~320 | ~32 min |
|
|
162
|
+
| 1M chars | ~1 MB | ~640 | ~1 hour |
|
|
163
|
+
| 7M chars (ceiling) | ~20 MB | ~4400 | ~7 hours |
|
|
164
|
+
|
|
165
|
+
Token ratio: **~4k input + 2k output tokens per 10k characters** (batch extraction already amortizes the system prompt) — multiply by your provider's rates. English content is 2–3× the characters of CJK for the same bytes, so it costs proportionally more.
|
|
166
|
+
|
|
167
|
+
**Practical guidance:**
|
|
168
|
+
|
|
169
|
+
- **Keep single files at 2–5 MB.** That covers an ordinary ebook, finishes within tens of minutes, and lets you watch progress.
|
|
170
|
+
- **Leave `HKC_MAX_CHUNKS_PER_DOC` at its default of 800.** Read the section below before lifting it — the reason is not just "it's slow".
|
|
171
|
+
- **Use file upload, not paste, for anything long.** `/ingest/text` is synchronous and holds the request; `/ingest/file/async` runs in a background thread and exposes `processed/total` progress.
|
|
172
|
+
- **Re-uploading the same file is free.** Content SHA-256 is checked first and duplicates return `409 already ingested`.
|
|
173
|
+
- **When extraction fails, check the log keyword first.** "JSON parse failed" means the model's output was cut off mid-JSON (common with dense CJK documents) — lower `HKC_EXTRACT_BATCH` or raise `HKC_EXTRACT_MAX_TOKENS` (default 8192, the output ceiling). Only when that keyword is absent should you check the API key or network.
|
|
174
|
+
|
|
175
|
+
### Per-document chunk cap: why the default is 800
|
|
176
|
+
|
|
177
|
+
`HKC_MAX_CHUNKS_PER_DOC` defaults to **800 chunks**, chosen as the intersection of "covers real documents completely" and "finishes in a time you can sit through, at a cost you can predict":
|
|
178
|
+
|
|
179
|
+
| Cap | Characters covered | Chunks | Expected time | Cost (cloud) |
|
|
180
|
+
|---|---|---|---|---|
|
|
181
|
+
| **800 (default)** | ~1.25M | 800 | ~1.3 hours | ~$0.4 |
|
|
182
|
+
| 2000 | ~3.1M | 2000 | ~3.3 hours | ~$1 |
|
|
183
|
+
| 0 (uncapped, i.e. a full 20 MB file) | ~7M | ~4400 | **7+ hours** | ~$2.3 |
|
|
184
|
+
|
|
185
|
+
> Costs are rough order-of-magnitude estimates at DeepSeek list prices; scale for your provider.
|
|
186
|
+
|
|
187
|
+
**Why not raise it (and especially not to 0):** uploads accept up to 20 MB. With no chunk cap, one accidental upload — a 20 MB scanned PDF, a rotated log dump — runs in the background for the better part of a day while billing the whole time. Ingestion runs on a background thread with no checkpoint and no rollback button: you either watch it finish or kill the whole service. The default exists to stop obviously unreasonable volumes up front, not to be as restrictive as possible.
|
|
188
|
+
|
|
189
|
+
**Why not shrink it either:** past the cap only the first N chunks are processed, and the **whole file's SHA-256 is already recorded** as ingested. Re-uploading the same file is rejected with `409`. So a truncated ingest cannot be completed by "raising the cap and sending it again" — you must split the file by chapter and upload the parts separately. 800 chunks leaves enough headroom that ordinary documents and normal ebooks never hit the cap.
|
|
190
|
+
|
|
191
|
+
**If you genuinely need a whole book,** raise the cap (or set 0) for that one ingest and set it back to 800 afterwards. A "document too large: split into N chunks" warning in the log means truncation happened, and it reports how much was dropped.
|
|
192
|
+
|
|
193
|
+
## Philosophy
|
|
194
|
+
|
|
195
|
+
Memory and cognition are fully decoupled from the LLM. The model is a replaceable text generator; the real moat (ThoughtChain audit + Harness drift + policy self-learning + domain kernels) exists independently of any model.
|
|
196
|
+
|
|
197
|
+
## License
|
|
198
|
+
|
|
199
|
+
MIT — see [LICENSE](LICENSE). Use it, modify it, ship it, sell it; just keep the copyright notice.
|
|
200
|
+
|
|
201
|
+
The runtimes vendored under `vendor/` keep their own licenses (see `vendor/hkc/LICENSE`).
|