foxclaw 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -29
- package/bin/foxclaw.cjs +51 -0
- package/index.js +11 -10
- package/package.json +46 -38
- package/python/.dockerignore +35 -0
- package/python/.env.example +165 -0
- package/python/.gitattributes +46 -0
- package/python/.github/workflows/ci.yml +122 -0
- package/python/.github/workflows/release.yml +183 -0
- package/python/Dockerfile +64 -0
- package/python/LICENSE +21 -0
- package/python/MANIFEST.in +14 -0
- package/python/README.md +192 -0
- package/python/README_CN.md +324 -0
- package/python/bench/bm25_audit.py +199 -0
- package/python/bench/bm25_regression.py +178 -0
- package/python/bench/bm25_stress.py +159 -0
- package/python/bench/cd_audit.py +238 -0
- package/python/bench/chaos.py +142 -0
- package/python/bench/concurrency.py +103 -0
- package/python/bench/e2e_real_models.py +95 -0
- package/python/bench/llm_retry_test.py +248 -0
- package/python/bench/load_test.py +196 -0
- package/python/bench/vector_ivf_upgrade.py +134 -0
- package/python/docs/CHANNELS.md +195 -0
- package/python/docs/GOVERNANCE.md +164 -0
- package/python/docs/RELEASE.md +109 -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 +152 -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 +400 -0
- package/python/examples/governance_middleware_demo.py +77 -0
- package/python/examples/langgraph_governance_demo.py +108 -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 +526 -0
- package/python/foxclaw/agents/__init__.py +12 -0
- package/python/foxclaw/agents/agents.py +35 -0
- package/python/foxclaw/agents/base.py +865 -0
- package/python/foxclaw/agents/impl/__init__.py +1 -0
- package/python/foxclaw/agents/impl/_helpers.py +78 -0
- package/python/foxclaw/agents/impl/finance.py +248 -0
- package/python/foxclaw/agents/impl/office.py +367 -0
- package/python/foxclaw/agents/impl/supervisor.py +659 -0
- package/python/foxclaw/agents/mixins/_context.py +151 -0
- package/python/foxclaw/agents/mixins/augment.py +149 -0
- package/python/foxclaw/agents/mixins/llm.py +66 -0
- package/python/foxclaw/agents/mixins/memory.py +35 -0
- package/python/foxclaw/agents/mixins/preference.py +81 -0
- package/python/foxclaw/agents/mixins/prompt.py +77 -0
- package/python/foxclaw/agents/mixins/skillbox.py +58 -0
- package/python/foxclaw/agents/mixins/tool_exec.py +443 -0
- package/python/foxclaw/api/__init__.py +283 -0
- package/python/foxclaw/api/app.py +123 -0
- package/python/foxclaw/api/middleware.py +317 -0
- package/python/foxclaw/api/routes/ahs.py +417 -0
- package/python/foxclaw/api/routes/attachments.py +117 -0
- package/python/foxclaw/api/routes/browser.py +39 -0
- package/python/foxclaw/api/routes/domain.py +314 -0
- package/python/foxclaw/api/routes/knowledge.py +163 -0
- package/python/foxclaw/api/routes/llm_admin.py +461 -0
- package/python/foxclaw/api/routes/memory.py +89 -0
- package/python/foxclaw/api/routes/orchestration.py +41 -0
- package/python/foxclaw/api/routes/recovery.py +43 -0
- package/python/foxclaw/api/routes/review.py +275 -0
- package/python/foxclaw/api/routes/search.py +37 -0
- package/python/foxclaw/api/routes/system.py +327 -0
- package/python/foxclaw/api/routes/task.py +281 -0
- package/python/foxclaw/api/routes/ws.py +68 -0
- package/python/foxclaw/api/spine.py +55 -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 +54 -0
- package/python/foxclaw/browser/action/action_types.py +45 -0
- package/python/foxclaw/browser/action/action_verifier.py +68 -0
- package/python/foxclaw/browser/action/url_policy.py +147 -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 +166 -0
- package/python/foxclaw/browser/perception/__init__.py +1 -0
- package/python/foxclaw/browser/perception/dom_extractor.py +43 -0
- package/python/foxclaw/browser/perception/element_indexer.py +57 -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 +148 -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 +67 -0
- package/python/foxclaw/channels/__init__.py +140 -0
- package/python/foxclaw/channels/discord.py +184 -0
- package/python/foxclaw/channels/dispatcher.py +204 -0
- package/python/foxclaw/channels/feishu.py +225 -0
- package/python/foxclaw/channels/openclaw_bridge.py +156 -0
- package/python/foxclaw/channels/signing.py +187 -0
- package/python/foxclaw/channels/telegram.py +121 -0
- package/python/foxclaw/channels/weixin.py +225 -0
- package/python/foxclaw/cli.py +154 -0
- package/python/foxclaw/cognitive/__init__.py +4 -0
- package/python/foxclaw/cognitive/reasoner.py +82 -0
- package/python/foxclaw/cognitive/state.py +147 -0
- package/python/foxclaw/core/__init__.py +9 -0
- package/python/foxclaw/core/audit_chain.py +133 -0
- package/python/foxclaw/core/audit_sink.py +100 -0
- package/python/foxclaw/core/compaction.py +283 -0
- package/python/foxclaw/core/config.py +65 -0
- package/python/foxclaw/core/confirm_nonce.py +157 -0
- package/python/foxclaw/core/dispatch.py +27 -0
- package/python/foxclaw/core/envfile.py +48 -0
- package/python/foxclaw/core/failure_policy.py +151 -0
- package/python/foxclaw/core/gateway.py +85 -0
- package/python/foxclaw/core/governance_audit.py +175 -0
- package/python/foxclaw/core/idempotency.py +289 -0
- package/python/foxclaw/core/injection_guard.py +221 -0
- package/python/foxclaw/core/memory_adapter.py +516 -0
- package/python/foxclaw/core/metrics.py +89 -0
- package/python/foxclaw/core/model_router.py +1097 -0
- package/python/foxclaw/core/paths.py +103 -0
- package/python/foxclaw/core/recovery.py +362 -0
- package/python/foxclaw/core/scheduler.py +144 -0
- package/python/foxclaw/core/secrets.py +134 -0
- package/python/foxclaw/core/sessions.py +157 -0
- package/python/foxclaw/core/settings.py +430 -0
- package/python/foxclaw/core/shared_write.py +198 -0
- package/python/foxclaw/core/steering_queue.py +153 -0
- package/python/foxclaw/core/system_bus.py +84 -0
- package/python/foxclaw/core/thought_chain.py +318 -0
- package/python/foxclaw/core/token_meter.py +235 -0
- package/python/foxclaw/core/tools.py +172 -0
- package/python/foxclaw/core/tracing.py +390 -0
- package/python/foxclaw/core/truth_pipeline.py +114 -0
- package/python/foxclaw/core/vec_recall_adapter.py +503 -0
- package/python/foxclaw/core/verify.py +181 -0
- package/python/foxclaw/core/web_search.py +242 -0
- package/python/foxclaw/finance/__init__.py +15 -0
- package/python/foxclaw/finance/evidence.py +153 -0
- package/python/foxclaw/finance/fx.py +100 -0
- package/python/foxclaw/finance/graph.py +188 -0
- package/python/foxclaw/finance/models.py +150 -0
- package/python/foxclaw/finance/nlparse.py +575 -0
- package/python/foxclaw/finance/policy.py +329 -0
- package/python/foxclaw/finance/reasoner.py +129 -0
- package/python/foxclaw/finance/reasoning.py +340 -0
- package/python/foxclaw/finance/reconcile.py +180 -0
- package/python/foxclaw/finance/runtime.py +527 -0
- package/python/foxclaw/governance/__init__.py +24 -0
- package/python/foxclaw/governance/middleware.py +184 -0
- package/python/foxclaw/harness/__init__.py +17 -0
- package/python/foxclaw/harness/_base.py +72 -0
- package/python/foxclaw/harness/_policy.py +359 -0
- package/python/foxclaw/harness/drift.py +89 -0
- package/python/foxclaw/harness/event_bus.py +31 -0
- package/python/foxclaw/harness/harness.py +446 -0
- package/python/foxclaw/harness/loop_detection.py +152 -0
- package/python/foxclaw/itinerary/__init__.py +10 -0
- package/python/foxclaw/itinerary/amap_client.py +117 -0
- package/python/foxclaw/itinerary/models.py +80 -0
- package/python/foxclaw/itinerary/reasoner.py +101 -0
- package/python/foxclaw/itinerary/reasoning.py +174 -0
- package/python/foxclaw/itinerary/runtime.py +148 -0
- package/python/foxclaw/kernel/__init__.py +13 -0
- package/python/foxclaw/kernel/capabilities.py +73 -0
- package/python/foxclaw/kernel/policy_gate.py +114 -0
- package/python/foxclaw/kernel/process_manager.py +205 -0
- package/python/foxclaw/kernel/scheduler.py +131 -0
- package/python/foxclaw/kernel/sentinel.py +453 -0
- package/python/foxclaw/kernel/sentinel_client.py +246 -0
- package/python/foxclaw/kernel/spine.py +97 -0
- package/python/foxclaw/knowledge/__init__.py +376 -0
- package/python/foxclaw/knowledge/truth_crystallizer.py +92 -0
- package/python/foxclaw/learning/__init__.py +12 -0
- package/python/foxclaw/learning/knowledge_graph.py +149 -0
- package/python/foxclaw/learning/models.py +93 -0
- package/python/foxclaw/learning/reasoner.py +70 -0
- package/python/foxclaw/learning/runtime.py +363 -0
- package/python/foxclaw/learning/spaced_repetition.py +96 -0
- package/python/foxclaw/mcp_server.py +189 -0
- package/python/foxclaw/orchestration/__init__.py +184 -0
- package/python/foxclaw/pipeline/__init__.py +23 -0
- package/python/foxclaw/pipeline/cognitive_pipeline.py +481 -0
- package/python/foxclaw/pipeline/supervisor_stages.py +230 -0
- package/python/foxclaw/planning/__init__.py +17 -0
- package/python/foxclaw/planning/llm_planner.py +232 -0
- package/python/foxclaw/planning/planner.py +99 -0
- package/python/foxclaw/search/__init__.py +24 -0
- package/python/foxclaw/search/agent_port.py +194 -0
- package/python/foxclaw/search/evidence.py +113 -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 +73 -0
- package/python/foxclaw/search/models.py +129 -0
- package/python/foxclaw/search/planner.py +44 -0
- package/python/foxclaw/search/retriever.py +39 -0
- package/python/foxclaw/search/runtime.py +134 -0
- package/python/foxclaw/search/strategy.py +44 -0
- package/python/foxclaw/skills/__init__.py +613 -0
- package/python/foxclaw/skills/hooks_spec.py +73 -0
- package/python/foxclaw/skills/lifecycle.py +278 -0
- package/python/foxclaw/skills/markdown_skill.py +174 -0
- package/python/foxclaw/skills/markdown_store.py +39 -0
- package/python/foxclaw/skills/mcp_client.py +190 -0
- package/python/foxclaw/skills/mcp_store.py +43 -0
- package/python/foxclaw/skills/permission.py +180 -0
- package/python/foxclaw/skills/pipeline.py +386 -0
- package/python/foxclaw/skills/policy.py +80 -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 +32 -0
- package/python/frontend/deck/chat_model_picker.js +537 -0
- package/python/frontend/deck/domain.js +296 -0
- package/python/frontend/deck/main.js +1950 -0
- package/python/frontend/deck/markdown.js +48 -0
- package/python/frontend/deck/settings.js +324 -0
- package/python/frontend/deck/state.js +6 -0
- package/python/frontend/deck/util.js +6 -0
- package/python/frontend/deck/visuals.js +212 -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 +1637 -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-BD7VPbMV.js +33 -0
- package/python/frontend/v3/assets/index-CAvnYWGH.css +1 -0
- package/python/frontend/v3/index.html +15 -0
- package/python/frontend/widget_runtime.js +295 -0
- package/python/frontend/widgets.js +696 -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 +62 -0
- package/python/frontend_src/src/api.js +89 -0
- package/python/frontend_src/src/components/ChatDock.vue +377 -0
- package/python/frontend_src/src/components/ComposerMenu.vue +75 -0
- package/python/frontend_src/src/components/DocViewer.vue +171 -0
- package/python/frontend_src/src/components/Inspector.vue +241 -0
- package/python/frontend_src/src/components/LeftRail.vue +394 -0
- package/python/frontend_src/src/components/MenuPopover.vue +130 -0
- package/python/frontend_src/src/components/MessageStream.vue +401 -0
- package/python/frontend_src/src/components/ModelPicker.vue +355 -0
- package/python/frontend_src/src/components/QuickIngest.vue +118 -0
- package/python/frontend_src/src/components/Stage.vue +226 -0
- package/python/frontend_src/src/components/ToolMenu.vue +144 -0
- package/python/frontend_src/src/components/TopBar.vue +90 -0
- package/python/frontend_src/src/components/panels/ActivityPanel.vue +84 -0
- package/python/frontend_src/src/components/panels/AgentsPanel.vue +86 -0
- package/python/frontend_src/src/components/panels/KnowledgePanel.vue +441 -0
- package/python/frontend_src/src/components/panels/MemoryPanel.vue +118 -0
- package/python/frontend_src/src/components/panels/PanelBox.vue +51 -0
- package/python/frontend_src/src/components/panels/ReviewPanel.vue +308 -0
- package/python/frontend_src/src/components/panels/SettingsPanel.vue +254 -0
- package/python/frontend_src/src/components/panels/TasksPanel.vue +74 -0
- package/python/frontend_src/src/components/panels/ToolsPanel.vue +640 -0
- package/python/frontend_src/src/components/panels/UsagePanel.vue +105 -0
- package/python/frontend_src/src/lib/fmt.js +48 -0
- package/python/frontend_src/src/lib/md.js +204 -0
- package/python/frontend_src/src/main.js +7 -0
- package/python/frontend_src/src/stores/app.js +106 -0
- package/python/frontend_src/src/stores/chat.js +484 -0
- package/python/frontend_src/src/stores/model.js +104 -0
- package/python/frontend_src/src/stores/panels.js +330 -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 +46 -0
- package/python/pyproject.toml +265 -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 +76 -0
- package/python/tests/run_all.py +263 -0
- package/python/tests/test_agent_lifecycle.py +360 -0
- package/python/tests/test_ahs_p2.py +414 -0
- package/python/tests/test_anthropic_tools.py +206 -0
- package/python/tests/test_api.py +87 -0
- package/python/tests/test_api_auth.py +83 -0
- package/python/tests/test_api_host_guard.py +69 -0
- package/python/tests/test_attachments.py +167 -0
- package/python/tests/test_audit_chain.py +121 -0
- package/python/tests/test_audit_sink.py +136 -0
- package/python/tests/test_browser.py +153 -0
- package/python/tests/test_browser_request_guard.py +184 -0
- package/python/tests/test_capabilities.py +158 -0
- package/python/tests/test_channel_signing.py +192 -0
- package/python/tests/test_channel_trust.py +109 -0
- package/python/tests/test_channels.py +184 -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 +65 -0
- package/python/tests/test_confirm_nonce.py +197 -0
- package/python/tests/test_context_compaction_wiring.py +130 -0
- package/python/tests/test_dispatch.py +95 -0
- package/python/tests/test_domain_evals.py +403 -0
- package/python/tests/test_domain_import.py +78 -0
- package/python/tests/test_domain_reasoners.py +148 -0
- package/python/tests/test_e2e.py +178 -0
- package/python/tests/test_emb_cache.py +107 -0
- package/python/tests/test_embedding_singleton.py +89 -0
- package/python/tests/test_envfile.py +83 -0
- package/python/tests/test_evals_smoke.py +114 -0
- package/python/tests/test_event_spine.py +182 -0
- package/python/tests/test_evidence_semantic.py +101 -0
- package/python/tests/test_evidence_sse.py +97 -0
- package/python/tests/test_file_ingest.py +146 -0
- package/python/tests/test_finance.py +153 -0
- package/python/tests/test_finance_ledger.py +252 -0
- package/python/tests/test_finance_persist.py +178 -0
- package/python/tests/test_gateway.py +144 -0
- package/python/tests/test_governance.py +468 -0
- package/python/tests/test_governance_audit.py +359 -0
- package/python/tests/test_governance_middleware.py +143 -0
- package/python/tests/test_hkc.py +286 -0
- package/python/tests/test_hkc_index_build_manager.py +339 -0
- package/python/tests/test_hkc_manifest_reuse.py +317 -0
- package/python/tests/test_hkc_search_event_sync.py +533 -0
- package/python/tests/test_import_path_guard.py +161 -0
- package/python/tests/test_injection_guard.py +211 -0
- package/python/tests/test_integration.py +141 -0
- package/python/tests/test_itinerary.py +103 -0
- package/python/tests/test_kee_semantic.py +89 -0
- package/python/tests/test_kernel.py +222 -0
- package/python/tests/test_learning.py +110 -0
- package/python/tests/test_llm_admin.py +160 -0
- package/python/tests/test_llm_planner.py +366 -0
- package/python/tests/test_markdown_skills.py +73 -0
- package/python/tests/test_markdown_skills_openclaw.py +71 -0
- package/python/tests/test_mcp_connectors.py +109 -0
- package/python/tests/test_mcp_guardian_discovery.py +91 -0
- package/python/tests/test_mcp_no_memory.py +43 -0
- package/python/tests/test_mcp_policy_gate.py +77 -0
- package/python/tests/test_mcp_server.py +95 -0
- package/python/tests/test_memory_recall.py +95 -0
- package/python/tests/test_metrics.py +66 -0
- package/python/tests/test_multi_chain.py +102 -0
- package/python/tests/test_multimodal.py +135 -0
- package/python/tests/test_negotiation.py +146 -0
- package/python/tests/test_orchestration.py +119 -0
- package/python/tests/test_orchestration_decoupled.py +109 -0
- package/python/tests/test_p3_p5_hardening.py +338 -0
- package/python/tests/test_parallel_dispatch.py +215 -0
- package/python/tests/test_pipeline.py +533 -0
- package/python/tests/test_plan_visible.py +86 -0
- package/python/tests/test_planner.py +95 -0
- package/python/tests/test_policy_gate.py +109 -0
- package/python/tests/test_reasoner.py +185 -0
- package/python/tests/test_release_check.py +263 -0
- package/python/tests/test_resume_checkpoint.py +156 -0
- package/python/tests/test_routing.py +95 -0
- package/python/tests/test_scheduler.py +141 -0
- package/python/tests/test_search.py +204 -0
- package/python/tests/test_secrets.py +159 -0
- package/python/tests/test_semantic.py +78 -0
- package/python/tests/test_sessions.py +91 -0
- package/python/tests/test_settings.py +281 -0
- package/python/tests/test_shadow_learning.py +330 -0
- package/python/tests/test_shared_write.py +207 -0
- package/python/tests/test_skill_taint_gate.py +154 -0
- package/python/tests/test_skills.py +133 -0
- package/python/tests/test_stats_and_events.py +165 -0
- package/python/tests/test_streaming.py +60 -0
- package/python/tests/test_supervisor_pipeline.py +177 -0
- package/python/tests/test_supervisor_triage.py +108 -0
- package/python/tests/test_taint.py +117 -0
- package/python/tests/test_task_stream.py +85 -0
- package/python/tests/test_thinking_sse.py +67 -0
- package/python/tests/test_thinking_stream.py +76 -0
- package/python/tests/test_tool_center.py +129 -0
- package/python/tests/test_tool_parallel.py +113 -0
- package/python/tests/test_tool_params.py +103 -0
- package/python/tests/test_tool_use.py +242 -0
- package/python/tests/test_toplevel_concurrency.py +117 -0
- package/python/tests/test_tracing.py +290 -0
- package/python/tests/test_truth_crystallizer.py +127 -0
- package/python/tests/test_truth_flow.py +93 -0
- package/python/tests/test_url_policy.py +53 -0
- package/python/tests/test_verify_evidence.py +225 -0
- package/python/tests/test_version_sync.py +71 -0
- package/python/tests/test_web_trigger.py +99 -0
- package/python/tools/check_faiss_type.py +31 -0
- package/python/tools/check_log.ps1 +46 -0
- package/python/tools/ivf_status.py +72 -0
- package/python/tools/mypy_baseline.txt +5 -0
- package/python/tools/mypy_ratchet.py +97 -0
- package/python/tools/pack.py +178 -0
- package/python/tools/release_check.py +349 -0
- package/python/tools/restart_foxclaw.ps1 +74 -0
- package/python/tools/shared_write_audit.py +204 -0
- package/python/tools/size_baseline.txt +28 -0
- package/python/tools/size_check.py +102 -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,686 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>FOXCLAW DECK · AI 指挥中枢 v2</title>
|
|
7
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
8
|
+
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;600;700;900&family=Share+Tech+Mono&family=Rajdhani:wght@300;400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
|
|
9
|
+
<style>
|
|
10
|
+
:root{
|
|
11
|
+
--void:#03060e;--deep:#060b18;--panel:rgba(10,20,40,0.55);--panel-solid:#0a1428;--glass:rgba(14,28,54,0.4);
|
|
12
|
+
--hud:#1de9ff;--hud-dim:rgba(29,233,255,0.5);--hud-faint:rgba(29,233,255,0.12);--hud-glow:rgba(29,233,255,0.6);
|
|
13
|
+
--plasma:#b066ff;--plasma-dim:rgba(176,102,255,0.5);--plasma-faint:rgba(176,102,255,0.12);
|
|
14
|
+
--amber:#ffb347;--amber-faint:rgba(255,179,71,0.12);--jade:#1dffa6;--jade-faint:rgba(29,255,166,0.12);
|
|
15
|
+
--alert:#ff4060;--alert-faint:rgba(255,64,96,0.12);--rose:#ff5e9c;--azure:#4d9fff;
|
|
16
|
+
--txt:#cfe8ff;--txt-dim:#6b88aa;--txt-faint:#3a4d68;
|
|
17
|
+
--line:rgba(29,233,255,0.18);--line-soft:rgba(120,160,220,0.1);
|
|
18
|
+
--mono:'Share Tech Mono',monospace;--display:'Orbitron',sans-serif;--tech:'Rajdhani',sans-serif;--sc:'Noto Sans SC',sans-serif;
|
|
19
|
+
}
|
|
20
|
+
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
|
|
21
|
+
html,body{height:100%;width:100%;background:var(--void);color:var(--txt);font-family:var(--tech);overflow:hidden;-webkit-font-smoothing:antialiased;user-select:none}
|
|
22
|
+
::-webkit-scrollbar{width:5px;height:5px}::-webkit-scrollbar-track{background:transparent}
|
|
23
|
+
::-webkit-scrollbar-thumb{background:var(--hud-faint);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:var(--hud-dim)}
|
|
24
|
+
|
|
25
|
+
.deck-bg{position:fixed;inset:0;z-index:0;background:radial-gradient(ellipse 80% 50% at 50% 0%,rgba(29,233,255,0.06),transparent 60%),radial-gradient(ellipse 60% 40% at 80% 100%,rgba(176,102,255,0.05),transparent 55%),radial-gradient(ellipse 50% 60% at 15% 80%,rgba(29,255,166,0.03),transparent 50%),var(--void)}
|
|
26
|
+
.grid-overlay{position:fixed;inset:0;z-index:1;pointer-events:none;background-image:linear-gradient(var(--line-soft) 1px,transparent 1px),linear-gradient(90deg,var(--line-soft) 1px,transparent 1px);background-size:48px 48px;mask-image:radial-gradient(ellipse 90% 80% at 50% 45%,#000 30%,transparent 90%);opacity:0.5}
|
|
27
|
+
.scanline{position:fixed;left:0;right:0;height:120px;z-index:2;pointer-events:none;background:linear-gradient(to bottom,transparent,rgba(29,233,255,0.025),transparent);animation:scan 8s linear infinite}
|
|
28
|
+
@keyframes scan{0%{top:-120px}100%{top:100%}}
|
|
29
|
+
.starfield{position:fixed;inset:0;z-index:1;pointer-events:none}
|
|
30
|
+
.star{position:absolute;background:#fff;border-radius:50%;animation:twinkle var(--d) ease-in-out infinite}
|
|
31
|
+
@keyframes twinkle{0%,100%{opacity:var(--o)}50%{opacity:0.1}}
|
|
32
|
+
|
|
33
|
+
.deck{position:relative;z-index:5;height:100vh;width:100vw;display:grid;grid-template-rows:54px 1fr 88px;grid-template-areas:"command" "bridge" "console"}
|
|
34
|
+
|
|
35
|
+
.command-bar{grid-area:command;display:flex;align-items:center;padding:0 20px;gap:18px;background:linear-gradient(to bottom,rgba(8,16,32,0.9),rgba(6,12,24,0.5));border-bottom:1px solid var(--line);position:relative}
|
|
36
|
+
.command-bar::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--hud-dim),transparent)}
|
|
37
|
+
.deck-brand{display:flex;align-items:center;gap:10px}
|
|
38
|
+
.brand-mark{width:34px;height:34px;position:relative;display:flex;align-items:center;justify-content:center}
|
|
39
|
+
.brand-mark::before{content:'';position:absolute;inset:0;border:1.5px solid var(--hud);border-radius:50%;border-top-color:transparent;border-bottom-color:transparent;animation:spin 4s linear infinite}
|
|
40
|
+
.brand-mark::after{content:'';position:absolute;inset:5px;border:1px solid var(--plasma-dim);border-radius:50%;border-left-color:transparent;border-right-color:transparent;animation:spin 3s linear infinite reverse}
|
|
41
|
+
.brand-core{width:8px;height:8px;background:var(--hud);border-radius:50%;box-shadow:0 0 10px var(--hud-glow)}
|
|
42
|
+
@keyframes spin{to{transform:rotate(360deg)}}
|
|
43
|
+
.brand-text{font-family:var(--display);font-weight:700;font-size:16px;letter-spacing:0.18em;color:var(--txt)}
|
|
44
|
+
.brand-text b{color:var(--hud);text-shadow:0 0 12px var(--hud-glow)}
|
|
45
|
+
.brand-ver{font-family:var(--mono);font-size:9px;color:var(--txt-faint);letter-spacing:0.1em;margin-top:-2px}
|
|
46
|
+
.cmd-divider{width:1px;height:26px;background:var(--line)}
|
|
47
|
+
.workspace-tabs{display:flex;gap:4px}
|
|
48
|
+
.ws-tab{font-family:var(--tech);font-size:12px;font-weight:600;letter-spacing:0.05em;padding:6px 14px;border-radius:4px;cursor:pointer;color:var(--txt-dim);border:1px solid transparent;transition:all .15s;text-transform:uppercase;display:flex;align-items:center;gap:6px}
|
|
49
|
+
.ws-tab:hover{color:var(--txt);background:var(--hud-faint)}
|
|
50
|
+
.ws-tab.active{color:var(--hud);border-color:var(--hud-dim);background:var(--hud-faint);text-shadow:0 0 8px var(--hud-glow)}
|
|
51
|
+
.ws-tab .dot{width:5px;height:5px;border-radius:50%;background:currentColor}
|
|
52
|
+
.cmd-spacer{flex:1}
|
|
53
|
+
.sys-telemetry{display:flex;align-items:center;gap:14px;font-family:var(--mono);font-size:10px}
|
|
54
|
+
.tele-item{display:flex;flex-direction:column;align-items:flex-end;line-height:1.2}
|
|
55
|
+
.tele-label{color:var(--txt-faint);font-size:8px;letter-spacing:0.15em}
|
|
56
|
+
.tele-val{color:var(--hud);font-size:12px}.tele-val.warn{color:var(--amber)}.tele-val.ok{color:var(--jade)}
|
|
57
|
+
.add-widget-btn{display:none;align-items:center;gap:6px;border:1px solid var(--plasma-dim);border-radius:4px;padding:6px 12px;cursor:pointer;color:var(--plasma);font-family:var(--tech);font-size:12px;font-weight:600;letter-spacing:0.05em;background:var(--plasma-faint);transition:all .15s}
|
|
58
|
+
.add-widget-btn:hover{background:rgba(176,102,255,0.2)}
|
|
59
|
+
.mode-toggle.edit ~ .add-widget-btn,body.edit .add-widget-btn{display:flex}
|
|
60
|
+
.mode-toggle{display:flex;align-items:center;gap:8px;border:1px solid var(--line);border-radius:20px;padding:5px 6px 5px 12px;cursor:pointer;transition:all .2s}
|
|
61
|
+
.mode-toggle:hover{border-color:var(--hud-dim)}
|
|
62
|
+
.mode-toggle .mt-label{font-size:11px;font-weight:600;letter-spacing:0.06em;color:var(--txt-dim)}
|
|
63
|
+
.mode-switch{width:36px;height:18px;border-radius:10px;background:var(--panel-solid);border:1px solid var(--line);position:relative;transition:all .2s}
|
|
64
|
+
.mode-switch::after{content:'';position:absolute;top:1px;left:1px;width:14px;height:14px;border-radius:50%;background:var(--txt-dim);transition:all .25s}
|
|
65
|
+
.mode-toggle.edit .mode-switch{background:var(--plasma-faint);border-color:var(--plasma-dim)}
|
|
66
|
+
.mode-toggle.edit .mode-switch::after{left:19px;background:var(--plasma);box-shadow:0 0 8px var(--plasma)}
|
|
67
|
+
.mode-toggle.edit .mt-label{color:var(--plasma)}
|
|
68
|
+
|
|
69
|
+
.bridge{grid-area:bridge;display:grid;grid-template-columns:300px 1fr 320px;gap:14px;padding:14px 18px;overflow:hidden;min-height:0;position:relative}
|
|
70
|
+
.bridge.edit-mode{background:linear-gradient(var(--plasma-faint) 1px,transparent 1px),linear-gradient(90deg,var(--plasma-faint) 1px,transparent 1px);background-size:24px 24px}
|
|
71
|
+
.bridge-col{display:flex;flex-direction:column;gap:14px;overflow:hidden;min-height:0}
|
|
72
|
+
|
|
73
|
+
.panel{background:var(--panel);border:1px solid var(--line);border-radius:4px;position:relative;backdrop-filter:blur(8px);display:flex;flex-direction:column;overflow:hidden}
|
|
74
|
+
.panel::before,.panel::after{content:'';position:absolute;width:12px;height:12px;pointer-events:none;border-color:var(--hud-dim);border-style:solid}
|
|
75
|
+
.panel::before{top:-1px;left:-1px;border-width:1px 0 0 1px}
|
|
76
|
+
.panel::after{bottom:-1px;right:-1px;border-width:0 1px 1px 0}
|
|
77
|
+
.panel-corner-tr,.panel-corner-bl{position:absolute;width:12px;height:12px;pointer-events:none;border-color:var(--hud-dim);border-style:solid}
|
|
78
|
+
.panel-corner-tr{top:-1px;right:-1px;border-width:1px 1px 0 0}
|
|
79
|
+
.panel-corner-bl{bottom:-1px;left:-1px;border-width:0 0 1px 1px}
|
|
80
|
+
.bridge.edit-mode .panel{border-color:var(--plasma-dim);cursor:move}
|
|
81
|
+
.bridge.edit-mode .panel::before,.bridge.edit-mode .panel::after,.bridge.edit-mode .panel-corner-tr,.bridge.edit-mode .panel-corner-bl{border-color:var(--plasma)}
|
|
82
|
+
.panel.dragging{opacity:0.7;z-index:100;box-shadow:0 0 30px var(--plasma-dim)}
|
|
83
|
+
.panel-head{display:flex;align-items:center;gap:8px;padding:9px 12px;border-bottom:1px solid var(--line);flex-shrink:0;background:linear-gradient(to right,var(--hud-faint),transparent)}
|
|
84
|
+
.panel-head .ph-icon{color:var(--hud);font-size:13px;width:16px;text-align:center}
|
|
85
|
+
.panel-head .ph-title{font-family:var(--display);font-size:10px;font-weight:600;letter-spacing:0.12em;color:var(--txt);text-transform:uppercase;flex:1}
|
|
86
|
+
.panel-head .ph-status{font-family:var(--mono);font-size:9px;color:var(--txt-dim)}
|
|
87
|
+
.panel-head .ph-drag{color:var(--plasma);font-size:12px;display:none;cursor:grab}
|
|
88
|
+
.panel-head .ph-remove{color:var(--alert);font-size:11px;cursor:pointer}
|
|
89
|
+
.bridge.edit-mode .panel-head .ph-drag{display:block}
|
|
90
|
+
.panel-body{flex:1;overflow-y:auto;min-height:0;position:relative}
|
|
91
|
+
|
|
92
|
+
.roster{padding:8px}
|
|
93
|
+
.agent-pod{display:flex;align-items:center;gap:10px;padding:9px 10px;margin-bottom:6px;border:1px solid var(--line-soft);border-radius:4px;cursor:pointer;transition:all .15s;position:relative;overflow:hidden;background:var(--glass)}
|
|
94
|
+
.agent-pod::before{content:'';position:absolute;left:0;top:0;bottom:0;width:2px;background:var(--apc,var(--hud));opacity:0;transition:opacity .15s}
|
|
95
|
+
.agent-pod:hover{border-color:var(--apc,var(--hud-dim));background:var(--hud-faint)}.agent-pod:hover::before{opacity:1}
|
|
96
|
+
.agent-pod.active{border-color:var(--apc);background:rgba(29,233,255,0.06);box-shadow:inset 0 0 20px rgba(29,233,255,0.05)}
|
|
97
|
+
.agent-pod.active::before{opacity:1;box-shadow:0 0 10px var(--apc)}
|
|
98
|
+
.pod-avatar{width:38px;height:38px;border-radius:4px;flex-shrink:0;position:relative;display:flex;align-items:center;justify-content:center;font-size:18px;background:var(--glass);border:1px solid var(--apc,var(--hud-dim))}
|
|
99
|
+
.pod-avatar .ring-pulse{position:absolute;inset:-3px;border:1px solid var(--apc,var(--hud));border-radius:5px;opacity:0;animation:podpulse 2s ease-out infinite}
|
|
100
|
+
.agent-pod.busy .pod-avatar .ring-pulse{opacity:1}
|
|
101
|
+
@keyframes podpulse{0%{transform:scale(1);opacity:0.6}100%{transform:scale(1.25);opacity:0}}
|
|
102
|
+
.pod-info{flex:1;min-width:0}
|
|
103
|
+
.pod-name{font-family:var(--display);font-size:11px;font-weight:600;letter-spacing:0.04em;color:var(--txt)}
|
|
104
|
+
.pod-role{font-size:10px;color:var(--txt-dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
105
|
+
.pod-state{display:flex;align-items:center;gap:4px;margin-top:3px;font-family:var(--mono);font-size:8px;letter-spacing:0.08em;color:var(--txt-faint)}
|
|
106
|
+
.pod-state .s-dot{width:5px;height:5px;border-radius:50%;background:var(--jade);box-shadow:0 0 5px var(--jade)}
|
|
107
|
+
.agent-pod.busy .pod-state .s-dot{background:var(--amber);box-shadow:0 0 5px var(--amber);animation:blink 1s infinite}
|
|
108
|
+
@keyframes blink{50%{opacity:0.3}}
|
|
109
|
+
.pod-metric{text-align:right;flex-shrink:0}
|
|
110
|
+
.pod-metric .pm-val{font-family:var(--mono);font-size:16px;color:var(--apc,var(--hud))}
|
|
111
|
+
.pod-metric .pm-lbl{font-size:8px;color:var(--txt-faint);letter-spacing:0.06em}
|
|
112
|
+
|
|
113
|
+
.core-panel{flex:1;display:flex;flex-direction:column;min-height:0}
|
|
114
|
+
.core-stage{flex:1;position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;overflow:hidden;min-height:0}
|
|
115
|
+
.core-orbit{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:340px;height:340px}
|
|
116
|
+
.orbit-ring{position:absolute;border-radius:50%;border:1px solid var(--hud-faint);top:50%;left:50%;transform:translate(-50%,-50%)}
|
|
117
|
+
.orbit-ring.r1{width:340px;height:340px;border-style:dashed;animation:spin 60s linear infinite}
|
|
118
|
+
.orbit-ring.r2{width:260px;height:260px;border-color:var(--plasma-faint);animation:spin 40s linear infinite reverse}
|
|
119
|
+
.orbit-ring.r3{width:190px;height:190px;border-color:var(--hud-faint)}
|
|
120
|
+
.orbit-tick{position:absolute;top:50%;left:50%;width:340px;height:340px;transform:translate(-50%,-50%);animation:spin 30s linear infinite}
|
|
121
|
+
.orbit-tick span{position:absolute;width:3px;height:8px;background:var(--hud-dim);top:0;left:50%;transform-origin:center 170px}
|
|
122
|
+
.radar-sweep{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:340px;height:340px;border-radius:50%;background:conic-gradient(from 0deg,transparent 0deg,transparent 320deg,rgba(29,233,255,0.15) 358deg,rgba(29,233,255,0.3) 360deg);animation:spin 4s linear infinite}
|
|
123
|
+
.core-avatar{position:relative;z-index:3;width:130px;height:130px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:54px;background:radial-gradient(circle at 50% 40%,rgba(29,233,255,0.18),rgba(10,20,40,0.8));border:2px solid var(--cac,var(--hud));box-shadow:0 0 40px var(--cac,var(--hud-glow)),inset 0 0 30px rgba(29,233,255,0.15);animation:coreFloat 4s ease-in-out infinite}
|
|
124
|
+
@keyframes coreFloat{0%,100%{transform:translateY(0)}50%{transform:translateY(-8px)}}
|
|
125
|
+
.core-name{position:relative;z-index:3;margin-top:22px;font-family:var(--display);font-size:20px;font-weight:700;letter-spacing:0.2em;color:var(--txt);text-shadow:0 0 16px var(--cac,var(--hud-glow));text-transform:uppercase}
|
|
126
|
+
.core-role{position:relative;z-index:3;font-family:var(--tech);font-size:12px;color:var(--txt-dim);letter-spacing:0.15em;margin-top:2px}
|
|
127
|
+
.core-statusline{position:relative;z-index:3;margin-top:18px;font-family:var(--mono);font-size:12px;color:var(--cac,var(--hud));letter-spacing:0.1em;min-height:18px;display:flex;align-items:center;gap:8px}
|
|
128
|
+
.core-statusline .cs-cursor{width:8px;height:14px;background:var(--cac,var(--hud));animation:blink 1s step-end infinite}
|
|
129
|
+
.core-telemetry{position:relative;z-index:3;display:flex;gap:18px;margin-top:18px}
|
|
130
|
+
.ct-stat{text-align:center}.ct-stat .cts-val{font-family:var(--mono);font-size:20px;color:var(--txt)}.ct-stat .cts-lbl{font-size:9px;color:var(--txt-faint);letter-spacing:0.1em;text-transform:uppercase}
|
|
131
|
+
.core-hud-tl,.core-hud-tr,.core-hud-bl,.core-hud-br{position:absolute;font-family:var(--mono);font-size:9px;color:var(--txt-faint);line-height:1.5;z-index:4;letter-spacing:0.05em}
|
|
132
|
+
.core-hud-tl{top:12px;left:14px}.core-hud-tr{top:12px;right:14px;text-align:right}.core-hud-bl{bottom:12px;left:14px}.core-hud-br{bottom:12px;right:14px;text-align:right}
|
|
133
|
+
.core-hud-tl b,.core-hud-tr b,.core-hud-bl b,.core-hud-br b{color:var(--hud);font-weight:400}
|
|
134
|
+
|
|
135
|
+
.harness-widget{padding:12px;display:flex;align-items:center;gap:14px}
|
|
136
|
+
.h-ring-svg{flex-shrink:0}
|
|
137
|
+
.h-ring-bg{fill:none;stroke:var(--line);stroke-width:5}
|
|
138
|
+
.h-ring-fg{fill:none;stroke-width:5;stroke-linecap:round;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset 1s ease;filter:drop-shadow(0 0 4px currentColor)}
|
|
139
|
+
.h-ring-label{font-family:var(--mono);text-anchor:middle;dominant-baseline:central}
|
|
140
|
+
.h-info{flex:1}
|
|
141
|
+
.h-mode{display:inline-flex;align-items:center;gap:5px;font-family:var(--mono);font-size:9px;padding:3px 8px;border-radius:3px;letter-spacing:0.08em}
|
|
142
|
+
.h-mode.shadow{background:var(--amber-faint);color:var(--amber)}.h-mode.active{background:var(--jade-faint);color:var(--jade)}
|
|
143
|
+
.h-detail{font-family:var(--mono);font-size:10px;color:var(--txt-dim);margin-top:8px;line-height:1.6}.h-detail b{color:var(--hud)}
|
|
144
|
+
.weight-section{padding:0 12px 12px}
|
|
145
|
+
.wt-row{display:flex;align-items:center;gap:8px;margin-bottom:7px}
|
|
146
|
+
.wt-lbl{font-size:10px;color:var(--txt-dim);width:56px;flex-shrink:0;letter-spacing:0.03em}
|
|
147
|
+
.wt-track{flex:1;height:3px;background:var(--panel-solid);border-radius:2px;overflow:hidden;border:1px solid var(--line-soft)}
|
|
148
|
+
.wt-fill{height:100%;border-radius:2px;transition:width .8s ease;box-shadow:0 0 6px currentColor}
|
|
149
|
+
.wt-pct{font-family:var(--mono);font-size:9px;color:var(--txt-faint);width:26px;text-align:right}
|
|
150
|
+
|
|
151
|
+
.tc-stream{padding:10px 12px;display:flex;flex-direction:column;gap:5px}
|
|
152
|
+
.tc-node{display:flex;gap:8px;align-items:flex-start}
|
|
153
|
+
.tc-rail{display:flex;flex-direction:column;align-items:center;flex-shrink:0;padding-top:3px}
|
|
154
|
+
.tc-dot{width:7px;height:7px;border-radius:50%;border:1.5px solid var(--tcc,var(--hud));background:var(--void);flex-shrink:0;box-shadow:0 0 6px var(--tcc,var(--hud))}
|
|
155
|
+
.tc-seg{width:1px;flex:1;min-height:14px;background:linear-gradient(var(--tcc,var(--line)),transparent);margin-top:2px;opacity:0.5}
|
|
156
|
+
.tc-card{flex:1;background:var(--glass);border:1px solid var(--line-soft);border-radius:3px;padding:6px 9px;margin-bottom:3px}
|
|
157
|
+
.tc-top{display:flex;justify-content:space-between;align-items:center;margin-bottom:3px}
|
|
158
|
+
.tc-type{font-family:var(--mono);font-size:8px;letter-spacing:0.1em;color:var(--txt-faint);text-transform:uppercase}
|
|
159
|
+
.tc-stat{font-family:var(--mono);font-size:8px;padding:1px 5px;border-radius:3px;letter-spacing:0.05em}
|
|
160
|
+
.st-PASS{background:var(--jade-faint);color:var(--jade)}.st-WARN{background:var(--amber-faint);color:var(--amber)}.st-BLOCK{background:var(--alert-faint);color:var(--alert)}.st-BASELINE{background:var(--plasma-faint);color:var(--plasma)}.st-PENDING{background:var(--hud-faint);color:var(--txt-dim)}
|
|
161
|
+
.tc-text{font-size:10px;color:var(--txt-dim);line-height:1.5;font-family:var(--sc)}
|
|
162
|
+
.tc-meta{display:flex;gap:6px;margin-top:4px}
|
|
163
|
+
.tc-pill{font-family:var(--mono);font-size:8px;color:var(--txt-faint);background:var(--panel-solid);padding:1px 5px;border-radius:3px;border:1px solid var(--line-soft)}
|
|
164
|
+
|
|
165
|
+
.evt-feed{padding:8px 10px;display:flex;flex-direction:column;gap:5px}
|
|
166
|
+
.evt{background:var(--glass);border:1px solid var(--line-soft);border-radius:3px;padding:6px 9px;border-left:2px solid var(--ec,var(--hud));animation:evtIn .3s ease}
|
|
167
|
+
@keyframes evtIn{from{opacity:0;transform:translateX(-6px)}to{opacity:1;transform:translateX(0)}}
|
|
168
|
+
.evt-top{display:flex;justify-content:space-between;align-items:center}
|
|
169
|
+
.evt-type{font-family:var(--mono);font-size:8px;letter-spacing:0.1em;text-transform:uppercase;color:var(--ec,var(--hud))}
|
|
170
|
+
.evt-time{font-family:var(--mono);font-size:8px;color:var(--txt-faint)}
|
|
171
|
+
.evt-body{font-size:9px;color:var(--txt-dim);margin-top:2px;line-height:1.4;font-family:var(--mono)}
|
|
172
|
+
|
|
173
|
+
/* DAG widget */
|
|
174
|
+
.dag-wrap{padding:8px 10px;height:100%;display:flex;align-items:center;justify-content:center}
|
|
175
|
+
.dag-svg{width:100%;height:100%;max-height:230px}
|
|
176
|
+
.dag-edge{transition:stroke .3s}
|
|
177
|
+
.dag-edge-flow{stroke:var(--hud)!important;stroke-width:2.5!important;stroke-dasharray:6 6;animation:dagDash .7s linear;filter:drop-shadow(0 0 4px var(--hud-glow))}
|
|
178
|
+
@keyframes dagDash{from{stroke-dashoffset:24}to{stroke-dashoffset:0}}
|
|
179
|
+
.dag-node{transition:opacity .3s}
|
|
180
|
+
.dag-node-shape{transition:all .3s}
|
|
181
|
+
.dag-node.dag-dim{opacity:0.35}
|
|
182
|
+
.dag-node.dag-active .dag-node-shape{filter:drop-shadow(0 0 6px var(--dnc))}
|
|
183
|
+
.dag-node.dag-active .dag-label{fill:var(--dnc)!important}
|
|
184
|
+
.dag-node.dag-pulse .dag-node-shape{stroke-width:3;filter:drop-shadow(0 0 12px var(--dnc));transform-box:fill-box;transform-origin:center;animation:dagNodePulse .7s ease}
|
|
185
|
+
@keyframes dagNodePulse{0%,100%{transform:scale(1)}40%{transform:scale(1.25)}}
|
|
186
|
+
.dag-icon{pointer-events:none}
|
|
187
|
+
|
|
188
|
+
/* Terminal widget */
|
|
189
|
+
.term{height:100%;display:flex;flex-direction:column;font-family:var(--mono);font-size:11px;padding:8px 10px}
|
|
190
|
+
.term-out{flex:1;overflow-y:auto;min-height:0;line-height:1.55}
|
|
191
|
+
.term-line{display:flex;gap:6px;white-space:pre-wrap;word-break:break-word;animation:termIn .15s ease}
|
|
192
|
+
@keyframes termIn{from{opacity:0}to{opacity:1}}
|
|
193
|
+
.tl-ts{color:var(--txt-faint);flex-shrink:0;font-size:9px;padding-top:1px}
|
|
194
|
+
.tl-pfx{flex-shrink:0;font-weight:bold}
|
|
195
|
+
.tl-txt{flex:1}
|
|
196
|
+
.tl-cmd .tl-pfx,.tl-cmd .tl-txt{color:var(--hud)}
|
|
197
|
+
.tl-info .tl-pfx,.tl-info .tl-txt{color:var(--azure)}
|
|
198
|
+
.tl-ok .tl-pfx,.tl-ok .tl-txt{color:var(--jade)}
|
|
199
|
+
.tl-warn .tl-pfx,.tl-warn .tl-txt{color:var(--amber)}
|
|
200
|
+
.tl-err .tl-pfx,.tl-err .tl-txt{color:var(--alert)}
|
|
201
|
+
.tl-tool .tl-pfx,.tl-tool .tl-txt{color:var(--plasma)}
|
|
202
|
+
.tl-out .tl-txt{color:var(--txt-dim)}
|
|
203
|
+
.term-prompt-line{display:flex;align-items:center;gap:3px;flex-shrink:0;padding-top:6px;border-top:1px solid var(--line-soft);margin-top:4px;font-size:10px}
|
|
204
|
+
.term-ps{color:var(--jade)}.term-ps-sep{color:var(--txt-dim)}.term-ps-path{color:var(--azure)}.term-ps-dollar{color:var(--txt-dim);margin:0 4px}
|
|
205
|
+
.term-caret{width:7px;height:13px;background:var(--hud);animation:blink 1s step-end infinite}
|
|
206
|
+
|
|
207
|
+
/* AI Browser widget */
|
|
208
|
+
.brz{height:100%;display:flex;flex-direction:column;padding:6px}
|
|
209
|
+
.brz-bar{display:flex;align-items:center;gap:8px;padding:6px 8px;background:var(--panel-solid);border:1px solid var(--line);border-radius:4px 4px 0 0;flex-shrink:0}
|
|
210
|
+
.brz-dots{display:flex;gap:4px}
|
|
211
|
+
.brz-dots span{width:7px;height:7px;border-radius:50%;background:var(--txt-faint)}
|
|
212
|
+
.brz-dots span:nth-child(1){background:#ff4060}.brz-dots span:nth-child(2){background:#ffb347}.brz-dots span:nth-child(3){background:#1dffa6}
|
|
213
|
+
.brz-url{flex:1;font-family:var(--mono);font-size:10px;color:var(--txt-dim);background:var(--void);padding:4px 10px;border-radius:3px;border:1px solid var(--line-soft);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
214
|
+
.brz-status{font-family:var(--mono);font-size:8px;padding:2px 6px;border-radius:3px;letter-spacing:0.05em;background:var(--hud-faint);color:var(--txt-dim)}
|
|
215
|
+
.brz-status.loading{background:var(--amber-faint);color:var(--amber)}
|
|
216
|
+
.brz-status.loaded{background:var(--jade-faint);color:var(--jade)}
|
|
217
|
+
.brz-progress{height:2px;width:0;background:var(--hud);box-shadow:0 0 6px var(--hud-glow);transition:width .6s ease,opacity .3s;opacity:0}
|
|
218
|
+
.brz-viewport{flex:1;background:rgba(8,14,28,0.6);border:1px solid var(--line);border-top:none;border-radius:0 0 4px 4px;overflow:hidden;position:relative;min-height:0}
|
|
219
|
+
.brz-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:var(--txt-faint);font-family:var(--mono);font-size:10px}
|
|
220
|
+
.brz-page{padding:12px;position:relative;height:100%}
|
|
221
|
+
.brz-skel{background:linear-gradient(90deg,var(--line-soft),rgba(29,233,255,0.06),var(--line-soft));background-size:200% 100%;animation:skelShine 1.5s infinite;border-radius:3px}
|
|
222
|
+
@keyframes skelShine{0%{background-position:200% 0}100%{background-position:-200% 0}}
|
|
223
|
+
.brz-skel-title{height:14px;width:55%;margin-bottom:10px}
|
|
224
|
+
.brz-skel-nav{display:flex;gap:8px;margin-bottom:12px}
|
|
225
|
+
.brz-skel-nav span{height:8px;width:36px;background:var(--line-soft);border-radius:3px}
|
|
226
|
+
.brz-hero{height:50px;background:linear-gradient(135deg,var(--hud-faint),var(--plasma-faint));border-radius:4px;margin-bottom:12px;border:1px solid var(--line-soft)}
|
|
227
|
+
.brz-skel-line{height:7px;margin-bottom:7px}.w90{width:90%}.w75{width:75%}.w85{width:85%}
|
|
228
|
+
.brz-cards{display:flex;gap:8px;margin-top:12px}
|
|
229
|
+
.brz-card{flex:1;height:40px;background:var(--glass);border:1px solid var(--line-soft);border-radius:4px}
|
|
230
|
+
.brz-cursor{position:absolute;font-size:14px;color:var(--hud);transition:left .5s ease,top .5s ease,opacity .3s;opacity:0;z-index:5;filter:drop-shadow(0 0 6px var(--hud-glow));pointer-events:none;transform:translate(-50%,-50%)}
|
|
231
|
+
.brz-cursor::after{content:attr(data-label);position:absolute;left:16px;top:-2px;font-family:var(--sc);font-size:9px;color:var(--hud);background:var(--void);padding:2px 6px;border-radius:3px;border:1px solid var(--hud-dim);white-space:nowrap}
|
|
232
|
+
.brz-cursor.act-click{color:var(--amber)}.brz-cursor.act-extract{color:var(--jade)}
|
|
233
|
+
.brz-ripple{position:absolute;width:20px;height:20px;border:2px solid var(--hud);border-radius:50%;transform:translate(-50%,-50%);animation:brzRipple .6s ease-out;pointer-events:none;z-index:4}
|
|
234
|
+
@keyframes brzRipple{0%{width:8px;height:8px;opacity:1}100%{width:40px;height:40px;opacity:0}}
|
|
235
|
+
|
|
236
|
+
/* Voice widget */
|
|
237
|
+
.voice{height:100%;display:flex;flex-direction:column;padding:10px;gap:8px}
|
|
238
|
+
.voice-wave{width:100%;height:44px;background:var(--void);border:1px solid var(--line-soft);border-radius:4px;flex-shrink:0}
|
|
239
|
+
.voice-transcript{flex:1;font-family:var(--sc);font-size:12px;color:var(--txt-faint);line-height:1.5;overflow-y:auto;min-height:24px;display:flex;align-items:center;padding:0 4px}
|
|
240
|
+
.voice-transcript.has-text{color:var(--txt);align-items:flex-start}
|
|
241
|
+
.voice-controls{display:flex;align-items:center;gap:10px;flex-shrink:0}
|
|
242
|
+
.voice-mic{width:40px;height:40px;border-radius:50%;border:1.5px solid var(--hud);background:var(--hud-faint);color:var(--hud);font-size:16px;cursor:pointer;transition:all .2s;flex-shrink:0}
|
|
243
|
+
.voice-mic:hover{background:rgba(29,233,255,0.2)}
|
|
244
|
+
.voice-mic.recording{border-color:var(--alert);color:var(--alert);background:var(--alert-faint);animation:micPulse 1.2s infinite}
|
|
245
|
+
@keyframes micPulse{0%,100%{box-shadow:0 0 0 0 rgba(255,64,96,0.4)}50%{box-shadow:0 0 0 8px rgba(255,64,96,0)}}
|
|
246
|
+
.voice-meta{flex:1;min-width:0}
|
|
247
|
+
.voice-state{font-family:var(--mono);font-size:11px;color:var(--txt-dim)}
|
|
248
|
+
.voice-hint{font-size:9px;color:var(--txt-faint);margin-top:1px}
|
|
249
|
+
.voice-send{background:var(--jade-faint);border:1px solid var(--jade);color:var(--jade);font-family:var(--tech);font-size:11px;font-weight:600;padding:8px 12px;border-radius:4px;cursor:pointer;transition:all .15s;flex-shrink:0}
|
|
250
|
+
.voice-send:hover:not(:disabled){background:rgba(29,255,166,0.2)}
|
|
251
|
+
.voice-send:disabled{opacity:0.35;cursor:not-allowed}
|
|
252
|
+
|
|
253
|
+
.console{grid-area:console;display:flex;align-items:center;gap:14px;padding:0 18px;background:linear-gradient(to top,rgba(8,16,32,0.9),rgba(6,12,24,0.4));border-top:1px solid var(--line);position:relative}
|
|
254
|
+
.console::before{content:'';position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--hud-dim),transparent)}
|
|
255
|
+
.flow-viz{display:flex;align-items:center;gap:6px;flex-shrink:0}
|
|
256
|
+
.flow-node{width:34px;height:34px;border-radius:4px;display:flex;align-items:center;justify-content:center;font-size:15px;border:1px solid var(--line);background:var(--glass);position:relative;transition:all .2s}
|
|
257
|
+
.flow-node.lit{border-color:var(--hud);box-shadow:0 0 12px var(--hud-glow);background:var(--hud-faint)}
|
|
258
|
+
.flow-arrow{color:var(--txt-faint);font-size:12px;font-family:var(--mono)}
|
|
259
|
+
.flow-arrow.lit{color:var(--hud);text-shadow:0 0 8px var(--hud-glow)}
|
|
260
|
+
.console-input-wrap{flex:1;display:flex;align-items:center;gap:10px;position:relative}
|
|
261
|
+
.ci-prompt{font-family:var(--mono);font-size:14px;color:var(--hud);text-shadow:0 0 8px var(--hud-glow)}
|
|
262
|
+
.console-input{flex:1;background:var(--panel);border:1px solid var(--line);border-radius:4px;color:var(--txt);font-family:var(--sc);font-size:14px;padding:11px 16px;outline:none;transition:all .2s;letter-spacing:0.02em}
|
|
263
|
+
.console-input:focus{border-color:var(--hud);box-shadow:0 0 0 1px var(--hud-dim),inset 0 0 20px rgba(29,233,255,0.05)}
|
|
264
|
+
.console-input::placeholder{color:var(--txt-faint)}.console-input:disabled{opacity:0.5}
|
|
265
|
+
.quick-cmds{display:flex;gap:6px;position:absolute;top:-34px;left:30px}
|
|
266
|
+
.qc{background:var(--panel);border:1px solid var(--line-soft);border-radius:14px;color:var(--txt-dim);font-family:var(--tech);font-size:11px;font-weight:500;padding:4px 11px;cursor:pointer;transition:all .15s;backdrop-filter:blur(8px)}
|
|
267
|
+
.qc:hover{border-color:var(--hud-dim);color:var(--hud)}
|
|
268
|
+
.agent-target{background:var(--panel);border:1px solid var(--line);border-radius:4px;color:var(--hud);font-family:var(--tech);font-size:13px;font-weight:600;padding:11px 12px;outline:none;cursor:pointer;letter-spacing:0.04em}
|
|
269
|
+
.transmit-btn{background:var(--hud-faint);border:1px solid var(--hud);border-radius:4px;color:var(--hud);font-family:var(--display);font-size:12px;font-weight:600;letter-spacing:0.1em;padding:11px 22px;cursor:pointer;transition:all .15s;text-transform:uppercase;display:flex;align-items:center;gap:8px}
|
|
270
|
+
.transmit-btn:hover{background:rgba(29,233,255,0.2);box-shadow:0 0 16px var(--hud-glow)}
|
|
271
|
+
.transmit-btn:active{transform:scale(0.97)}.transmit-btn:disabled{opacity:0.4;cursor:not-allowed;box-shadow:none}
|
|
272
|
+
|
|
273
|
+
.chat-log{position:absolute;bottom:12px;left:14px;right:14px;max-height:42%;overflow-y:auto;display:flex;flex-direction:column;gap:8px;z-index:5;pointer-events:auto}
|
|
274
|
+
.msg{max-width:80%;padding:8px 12px;border-radius:4px;font-size:12px;line-height:1.6;font-family:var(--sc);backdrop-filter:blur(6px)}
|
|
275
|
+
.msg.user{align-self:flex-end;background:var(--plasma-faint);border:1px solid var(--plasma-dim);color:var(--txt)}
|
|
276
|
+
.msg.agent{align-self:flex-start;background:var(--glass);border:1px solid var(--line)}
|
|
277
|
+
.msg.blocked{background:var(--alert-faint);border-color:var(--alert)}
|
|
278
|
+
.msg .m-tag{font-family:var(--mono);font-size:9px;color:var(--txt-faint);margin-bottom:3px;letter-spacing:0.06em}
|
|
279
|
+
.empty{padding:24px;text-align:center;color:var(--txt-faint);font-family:var(--mono);font-size:10px;letter-spacing:0.05em}
|
|
280
|
+
.offline-banner{position:fixed;bottom:96px;left:50%;transform:translateX(-50%);z-index:200;background:var(--amber-faint);border:1px solid var(--amber);border-radius:4px;padding:6px 16px;font-family:var(--mono);font-size:10px;color:var(--amber);letter-spacing:0.05em;display:none}
|
|
281
|
+
|
|
282
|
+
/* Widget Library modal */
|
|
283
|
+
.lib-overlay{position:fixed;inset:0;z-index:300;background:rgba(3,6,14,0.8);backdrop-filter:blur(4px);display:none;align-items:center;justify-content:center}
|
|
284
|
+
.lib-overlay.show{display:flex}
|
|
285
|
+
.lib-modal{background:var(--panel-solid);border:1px solid var(--plasma-dim);border-radius:6px;padding:20px;width:480px;max-width:90vw;position:relative}
|
|
286
|
+
.lib-modal::before,.lib-modal::after{content:'';position:absolute;width:14px;height:14px;border-color:var(--plasma);border-style:solid}
|
|
287
|
+
.lib-modal::before{top:-1px;left:-1px;border-width:1px 0 0 1px}.lib-modal::after{bottom:-1px;right:-1px;border-width:0 1px 1px 0}
|
|
288
|
+
.lib-title{font-family:var(--display);font-size:13px;font-weight:600;letter-spacing:0.1em;color:var(--plasma);margin-bottom:14px;text-transform:uppercase}
|
|
289
|
+
.lib-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
|
|
290
|
+
.lib-card{background:var(--glass);border:1px solid var(--line-soft);border-radius:4px;padding:12px;cursor:pointer;transition:all .15s;display:flex;align-items:center;gap:10px}
|
|
291
|
+
.lib-card:hover{border-color:var(--plasma-dim);background:var(--plasma-faint)}
|
|
292
|
+
.lib-icon{font-size:18px;color:var(--hud);width:24px;text-align:center}
|
|
293
|
+
.lib-info{flex:1}.lib-name{font-family:var(--tech);font-size:12px;font-weight:600;color:var(--txt)}.lib-col{font-size:9px;color:var(--txt-faint);font-family:var(--mono)}
|
|
294
|
+
.lib-close{position:absolute;top:14px;right:16px;color:var(--txt-dim);cursor:pointer;font-size:16px}.lib-close:hover{color:var(--alert)}
|
|
295
|
+
</style>
|
|
296
|
+
</head>
|
|
297
|
+
<body>
|
|
298
|
+
|
|
299
|
+
<div class="deck-bg"></div>
|
|
300
|
+
<div class="starfield" id="starfield"></div>
|
|
301
|
+
<div class="grid-overlay"></div>
|
|
302
|
+
<div class="scanline"></div>
|
|
303
|
+
|
|
304
|
+
<div class="deck">
|
|
305
|
+
<div class="command-bar">
|
|
306
|
+
<div class="deck-brand">
|
|
307
|
+
<div class="brand-mark"><div class="brand-core"></div></div>
|
|
308
|
+
<div><div class="brand-text">FOXCLAW <b>DECK</b></div><div class="brand-ver">AI COMMAND BRIDGE · v2.0 · WIDGET RUNTIME</div></div>
|
|
309
|
+
</div>
|
|
310
|
+
<div class="cmd-divider"></div>
|
|
311
|
+
<div class="workspace-tabs" id="wsTabs">
|
|
312
|
+
<div class="ws-tab active" data-ws="command"><span class="dot"></span>指挥</div>
|
|
313
|
+
<div class="ws-tab" data-ws="research"><span class="dot"></span>研究</div>
|
|
314
|
+
<div class="ws-tab" data-ws="finance"><span class="dot"></span>财务</div>
|
|
315
|
+
<div class="ws-tab" data-ws="warroom"><span class="dot"></span>作战室</div>
|
|
316
|
+
</div>
|
|
317
|
+
<div class="cmd-spacer"></div>
|
|
318
|
+
<div class="sys-telemetry">
|
|
319
|
+
<div class="tele-item"><span class="tele-label">AGENTS</span><span class="tele-val ok" id="teleAgents">5/5</span></div>
|
|
320
|
+
<div class="tele-item"><span class="tele-label">MEMORY</span><span class="tele-val" id="teleMemory">0</span></div>
|
|
321
|
+
<div class="tele-item"><span class="tele-label">HARNESS</span><span class="tele-val warn" id="teleHarness">SHADOW</span></div>
|
|
322
|
+
<div class="tele-item"><span class="tele-label">UPLINK</span><span class="tele-val" id="teleUplink">···</span></div>
|
|
323
|
+
</div>
|
|
324
|
+
<div class="cmd-divider"></div>
|
|
325
|
+
<div class="mode-toggle" id="modeToggle" onclick="toggleMode()">
|
|
326
|
+
<span class="mt-label">显示</span><div class="mode-switch"></div>
|
|
327
|
+
</div>
|
|
328
|
+
<div class="add-widget-btn" id="addWidgetBtn" onclick="openLibrary()">+ 添加面板</div>
|
|
329
|
+
</div>
|
|
330
|
+
|
|
331
|
+
<div class="bridge" id="bridge">
|
|
332
|
+
<div class="bridge-col" id="colLeft"></div>
|
|
333
|
+
<div class="bridge-col" id="colCenter"></div>
|
|
334
|
+
<div class="bridge-col" id="colRight"></div>
|
|
335
|
+
</div>
|
|
336
|
+
|
|
337
|
+
<div class="console">
|
|
338
|
+
<div class="flow-viz" id="flowViz">
|
|
339
|
+
<div class="flow-node" data-flow="supervisor" title="主管">🏢</div><span class="flow-arrow">›</span>
|
|
340
|
+
<div class="flow-node" data-flow="finance" title="财务">💰</div><span class="flow-arrow">›</span>
|
|
341
|
+
<div class="flow-node" data-flow="office" title="办公学习 · 日程">📚</div>
|
|
342
|
+
</div>
|
|
343
|
+
<div class="cmd-divider"></div>
|
|
344
|
+
<div class="console-input-wrap">
|
|
345
|
+
<div class="quick-cmds">
|
|
346
|
+
<div class="qc" onclick="quickCmd('分析本月收支情况')">分析收支</div>
|
|
347
|
+
<div class="qc" onclick="quickCmd('制定下周工作计划')">工作计划</div>
|
|
348
|
+
<div class="qc" onclick="quickCmd('学习AI最新论文摘要')">学习总结</div>
|
|
349
|
+
<div class="qc" onclick="quickCmd('生成月度报告')">生成报告</div>
|
|
350
|
+
</div>
|
|
351
|
+
<span class="ci-prompt">❯</span>
|
|
352
|
+
<input class="console-input" id="consoleInput" placeholder="下达指令... 主管 Agent 将自动调度" onkeydown="handleKey(event)">
|
|
353
|
+
</div>
|
|
354
|
+
<select class="agent-target" id="agentTarget">
|
|
355
|
+
<option value="supervisor">◈ 主管</option>
|
|
356
|
+
<option value="finance">◈ 财务</option><option value="office">◈ 办公学习</option>
|
|
357
|
+
</select>
|
|
358
|
+
<button class="transmit-btn" id="transmitBtn" onclick="transmit()"><span>传输</span> ❯❯</button>
|
|
359
|
+
</div>
|
|
360
|
+
</div>
|
|
361
|
+
|
|
362
|
+
<div class="offline-banner" id="offlineBanner">⚠ 后端离线 · 显示演示数据</div>
|
|
363
|
+
|
|
364
|
+
<div class="lib-overlay" id="libOverlay" onclick="if(event.target===this)closeLibrary()">
|
|
365
|
+
<div class="lib-modal">
|
|
366
|
+
<div class="lib-close" onclick="closeLibrary()">✕</div>
|
|
367
|
+
<div class="lib-title">面板库 · 点击添加到指挥舱</div>
|
|
368
|
+
<div class="lib-grid" id="libGrid"></div>
|
|
369
|
+
</div>
|
|
370
|
+
</div>
|
|
371
|
+
|
|
372
|
+
<script src="widget_runtime.js"></script>
|
|
373
|
+
<script src="widgets.js"></script>
|
|
374
|
+
<script>
|
|
375
|
+
/* ════════════════════════════════════════════════════════════
|
|
376
|
+
FOXCLAW DECK v2 — Main wiring
|
|
377
|
+
════════════════════════════════════════════════════════════ */
|
|
378
|
+
// 从后端服务时(http://host:port)用同源地址;直接双击打开 html(file://)时回退到 localhost:8000
|
|
379
|
+
const _origin = (location.protocol === 'http:' || location.protocol === 'https:')
|
|
380
|
+
? location.origin : 'http://localhost:8000';
|
|
381
|
+
const API = _origin + '/api';
|
|
382
|
+
const WS = (_origin.replace(/^http/, 'ws')) + '/ws/harness';
|
|
383
|
+
const AGENTS=[
|
|
384
|
+
{id:'supervisor',name:'主管',code:'SUPERVISOR',role:'全局统筹',emoji:'🏢',color:'#1de9ff',tasks:0},
|
|
385
|
+
{id:'finance', name:'财务',code:'FINANCE', role:'财务专业',emoji:'💰',color:'#ffb347',tasks:0},
|
|
386
|
+
{id:'office', name:'办公学习',code:'OFFICE', role:'办公·学习·日程',emoji:'📚',color:'#1dffa6',tasks:0},
|
|
387
|
+
];
|
|
388
|
+
const AG=id=>AGENTS.find(a=>a.id===id);
|
|
389
|
+
let activeAgent='supervisor',editMode=false,online=false,ws=null,taskSeq=0;
|
|
390
|
+
const tasks=[];
|
|
391
|
+
|
|
392
|
+
const esc=s=>String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/\n/g,'<br>');
|
|
393
|
+
const statusColor=s=>({PASS:'#1dffa6',WARN:'#ffb347',BLOCK:'#ff4060',BASELINE:'#b066ff',PENDING:'#3a4d68'}[s]||'#1de9ff');
|
|
394
|
+
|
|
395
|
+
/* ── 共享上下文:widget 通过 ctx 调用这些 ── */
|
|
396
|
+
const ctx={
|
|
397
|
+
AGENTS, AG, activeAgent,
|
|
398
|
+
setActiveCore,
|
|
399
|
+
loadChainInto, loadHarnessInto,
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
window.addEventListener('DOMContentLoaded',()=>{
|
|
403
|
+
buildStars();
|
|
404
|
+
WidgetRuntime.init(
|
|
405
|
+
{left:document.getElementById('colLeft'),center:document.getElementById('colCenter'),right:document.getElementById('colRight')},
|
|
406
|
+
ctx
|
|
407
|
+
);
|
|
408
|
+
// 恢复布局,失败则用默认
|
|
409
|
+
if(!WidgetRuntime.loadLayout()){
|
|
410
|
+
WidgetRuntime.setLayout(WidgetRuntime.defaultLayout());
|
|
411
|
+
}
|
|
412
|
+
WidgetRuntime.notifyAgentChange('supervisor');
|
|
413
|
+
bindWorkspaces();
|
|
414
|
+
connectWS();
|
|
415
|
+
pollAll();
|
|
416
|
+
setInterval(pollAll,10000);
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
function buildStars(){
|
|
420
|
+
const f=document.getElementById('starfield');let h='';
|
|
421
|
+
for(let i=0;i<90;i++){const s=Math.random()*1.8+0.3,o=Math.random()*0.6+0.2,d=Math.random()*4+2;
|
|
422
|
+
h+=`<div class="star" style="left:${Math.random()*100}%;top:${Math.random()*100}%;width:${s}px;height:${s}px;--o:${o};--d:${d}s"></div>`;}
|
|
423
|
+
f.innerHTML=h;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/* ── ACTIVE CORE ── */
|
|
427
|
+
function setActiveCore(id){
|
|
428
|
+
activeAgent=id; ctx.activeAgent=id;
|
|
429
|
+
document.getElementById('agentTarget').value=id;
|
|
430
|
+
document.documentElement.style.setProperty('--cac',AG(id).color);
|
|
431
|
+
WidgetRuntime.notifyAgentChange(id);
|
|
432
|
+
WidgetRuntime.refreshAll(id);
|
|
433
|
+
setFlowActive(id);
|
|
434
|
+
}
|
|
435
|
+
function setCoreStatus(text,busy){
|
|
436
|
+
const coreBody=ctx._coreEl;
|
|
437
|
+
if(coreBody){
|
|
438
|
+
const t=coreBody.querySelector('[data-role="core-status-text"]'); if(t)t.textContent=text;
|
|
439
|
+
}
|
|
440
|
+
// roster busy state
|
|
441
|
+
if(ctx._rosterRefresh)ctx._rosterRefresh();
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/* ── FLOW ── */
|
|
445
|
+
function setFlowActive(id){document.querySelectorAll('.flow-node').forEach(n=>n.classList.toggle('lit',n.dataset.flow===id));}
|
|
446
|
+
function dagPulse(id){if(ctx._dagEl&&typeof _dagPulse==='function')_dagPulse(ctx._dagEl,id);}
|
|
447
|
+
function browseIfRelevant(task,agentId){
|
|
448
|
+
if(!ctx.browseTo)return;
|
|
449
|
+
// 涉及搜索/学习/查询的任务触发浏览器可视化
|
|
450
|
+
const webKeywords=['学习','搜索','查','论文','新闻','网','资料','了解','调研'];
|
|
451
|
+
if(webKeywords.some(k=>task.includes(k))){
|
|
452
|
+
const q=encodeURIComponent(task.slice(0,20));
|
|
453
|
+
ctx.browseTo(`https://www.bing.com/search?q=${q}`);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
function termExec(task,agentId){
|
|
457
|
+
if(!ctx.termLog)return;
|
|
458
|
+
const a=AG(agentId);
|
|
459
|
+
const steps=[
|
|
460
|
+
[`task dispatch --agent ${agentId} "${task.slice(0,24)}"`,'cmd',0],
|
|
461
|
+
[`[${a.code}] 接收指令 · 注册目标基线`,'info',300],
|
|
462
|
+
[`recall --query "${task.slice(0,16)}" --top-k 5`,'tool',650],
|
|
463
|
+
[`检索到 3 条相关记忆 · 注入上下文`,'ok',950],
|
|
464
|
+
[`reasoning · 分析任务类型与执行路径`,'out',1300],
|
|
465
|
+
[`harness check · Δ drift 评估中...`,'tool',1700],
|
|
466
|
+
[`harness PASS · 推理链已记录`,'ok',2050],
|
|
467
|
+
];
|
|
468
|
+
steps.forEach(([line,type,delay])=>setTimeout(()=>ctx.termLog(line,type),delay));
|
|
469
|
+
}
|
|
470
|
+
function animateFlow(){
|
|
471
|
+
const nodes=document.querySelectorAll('.flow-node'),arrows=document.querySelectorAll('.flow-arrow');let i=0;
|
|
472
|
+
const iv=setInterval(()=>{nodes.forEach(n=>n.classList.remove('lit'));arrows.forEach(a=>a.classList.remove('lit'));
|
|
473
|
+
if(i<nodes.length){nodes[i].classList.add('lit');if(i>0)arrows[i-1].classList.add('lit');}i++;
|
|
474
|
+
if(i>nodes.length){clearInterval(iv);setFlowActive(activeAgent);}},180);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/* ── MODE / LIBRARY ── */
|
|
478
|
+
function toggleMode(){
|
|
479
|
+
editMode=!editMode;
|
|
480
|
+
const t=document.getElementById('modeToggle'),b=document.getElementById('bridge');
|
|
481
|
+
t.classList.toggle('edit',editMode);
|
|
482
|
+
document.body.classList.toggle('edit',editMode);
|
|
483
|
+
t.querySelector('.mt-label').textContent=editMode?'编辑':'显示';
|
|
484
|
+
b.classList.toggle('edit-mode',editMode);
|
|
485
|
+
WidgetRuntime.setEditMode(editMode);
|
|
486
|
+
document.querySelectorAll('.panel').forEach(p=>editMode?enableDrag(p):disableDrag(p));
|
|
487
|
+
}
|
|
488
|
+
function openLibrary(){
|
|
489
|
+
const grid=document.getElementById('libGrid');
|
|
490
|
+
grid.innerHTML=WidgetRuntime.getLibrary().map(w=>`
|
|
491
|
+
<div class="lib-card" onclick="addPanel('${w.id}')">
|
|
492
|
+
<div class="lib-icon">${w.icon}</div>
|
|
493
|
+
<div class="lib-info"><div class="lib-name">${w.title}</div><div class="lib-col">→ ${w.defaultColumn}</div></div>
|
|
494
|
+
</div>`).join('');
|
|
495
|
+
document.getElementById('libOverlay').classList.add('show');
|
|
496
|
+
}
|
|
497
|
+
function closeLibrary(){document.getElementById('libOverlay').classList.remove('show');}
|
|
498
|
+
function addPanel(widgetId){
|
|
499
|
+
WidgetRuntime.addInstance(widgetId);
|
|
500
|
+
closeLibrary();
|
|
501
|
+
if(editMode){document.querySelectorAll('.panel').forEach(p=>enableDrag(p));WidgetRuntime.setEditMode(true);}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/* ── DRAG ── */
|
|
505
|
+
let dragEl=null,dragOX=0,dragOY=0;
|
|
506
|
+
function enableDrag(panel){
|
|
507
|
+
const handle=panel.querySelector('.ph-drag');if(!handle)return;
|
|
508
|
+
handle.onmousedown=e=>{
|
|
509
|
+
e.preventDefault();dragEl=panel;
|
|
510
|
+
const r=panel.getBoundingClientRect();dragOX=e.clientX-r.left;dragOY=e.clientY-r.top;
|
|
511
|
+
panel.classList.add('dragging');panel.style.position='fixed';panel.style.width=r.width+'px';
|
|
512
|
+
panel.style.left=r.left+'px';panel.style.top=r.top+'px';panel.style.zIndex=200;
|
|
513
|
+
document.onmousemove=onDragMove;document.onmouseup=onDragEnd;
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
function disableDrag(panel){const h=panel.querySelector('.ph-drag');if(h)h.onmousedown=null;
|
|
517
|
+
panel.style.position='';panel.style.left='';panel.style.top='';panel.style.width='';panel.style.zIndex='';}
|
|
518
|
+
function onDragMove(e){if(!dragEl)return;dragEl.style.left=(e.clientX-dragOX)+'px';dragEl.style.top=(e.clientY-dragOY)+'px';
|
|
519
|
+
['colLeft','colCenter','colRight'].forEach(id=>{const c=document.getElementById(id),r=c.getBoundingClientRect();
|
|
520
|
+
c.style.outline=(e.clientX>r.left&&e.clientX<r.right)?'1px dashed var(--plasma)':'';});}
|
|
521
|
+
function onDragEnd(e){
|
|
522
|
+
if(!dragEl)return;let target=null;
|
|
523
|
+
['colLeft','colCenter','colRight'].forEach(id=>{const c=document.getElementById(id),r=c.getBoundingClientRect();
|
|
524
|
+
c.style.outline='';if(e.clientX>r.left&&e.clientX<r.right)target=c;});
|
|
525
|
+
const p=dragEl;p.classList.remove('dragging');
|
|
526
|
+
p.style.position='';p.style.left='';p.style.top='';p.style.width='';p.style.zIndex='';
|
|
527
|
+
if(target){const sibs=[...target.children];let inserted=false;
|
|
528
|
+
for(const s of sibs){if(s!==p&&e.clientY<s.getBoundingClientRect().top+s.offsetHeight/2){target.insertBefore(p,s);inserted=true;break;}}
|
|
529
|
+
if(!inserted&&p.parentElement!==target)target.appendChild(p);}
|
|
530
|
+
dragEl=null;document.onmousemove=null;document.onmouseup=null;
|
|
531
|
+
WidgetRuntime.captureLayoutFromDOM();
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/* ── WORKSPACES ── */
|
|
535
|
+
function bindWorkspaces(){
|
|
536
|
+
document.querySelectorAll('.ws-tab').forEach(t=>{t.onclick=()=>{
|
|
537
|
+
document.querySelectorAll('.ws-tab').forEach(x=>x.classList.remove('active'));t.classList.add('active');
|
|
538
|
+
const map={research:'office',finance:'finance',warroom:'supervisor',command:'supervisor'};
|
|
539
|
+
if(map[t.dataset.ws])setActiveCore(map[t.dataset.ws]);};});
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/* ── CONSOLE ── */
|
|
543
|
+
function handleKey(e){if(e.key==='Enter'){e.preventDefault();transmit();}}
|
|
544
|
+
function quickCmd(t){document.getElementById('consoleInput').value=t;transmit();}
|
|
545
|
+
async function transmit(){
|
|
546
|
+
const input=document.getElementById('consoleInput'),task=input.value.trim();if(!task)return;
|
|
547
|
+
const agentId=document.getElementById('agentTarget').value;
|
|
548
|
+
if(agentId!==activeAgent)setActiveCore(agentId);
|
|
549
|
+
const btn=document.getElementById('transmitBtn');btn.disabled=true;input.value='';
|
|
550
|
+
addMsg('user',task);addTask(task,agentId);animateFlow();dagPulse(agentId);
|
|
551
|
+
termExec(task,agentId);browseIfRelevant(task,agentId);
|
|
552
|
+
setCoreStatus('解析指令...',true);typeStatus(['解析指令...','检索记忆...','规划方案...','执行中...']);
|
|
553
|
+
const a=AG(agentId);a.tasks++;updatePodTask(agentId,a.tasks);
|
|
554
|
+
try{
|
|
555
|
+
const r=await fetch(`${API}/task`,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({task,agent_id:agentId})});
|
|
556
|
+
const data=await r.json();
|
|
557
|
+
if(data.error==='harness_blocked'){addMsg('agent',`⛔ HARNESS 截断 · ${data.reason}`,true);setCoreStatus('指令被拦截',false);updateTask(task,'BLOCK');if(ctx.termLog)ctx.termLog(`harness BLOCK · ${data.reason}`,'err');}
|
|
558
|
+
else{const res=typeof data.result==='string'?data.result:JSON.stringify(data.result,null,2);
|
|
559
|
+
addMsg('agent',res);setCoreStatus('任务完成 · 待命中',false);updateTask(task,'PASS');
|
|
560
|
+
if(ctx.termLog)ctx.termLog('task complete · 记忆已巩固写回','ok');
|
|
561
|
+
// 主管真实调度:若结果含 dispatched_to,DAG 沿真实派发路径重新点亮
|
|
562
|
+
const dt=data.result&&data.result.dispatched_to;
|
|
563
|
+
if(dt&&dt!=='supervisor'&&agentId==='supervisor'){
|
|
564
|
+
if(ctx.termLog)ctx.termLog(`dispatch → ${dt} · 子 Agent 执行并汇聚`,'tool');
|
|
565
|
+
dagPulse(dt);
|
|
566
|
+
}
|
|
567
|
+
WidgetRuntime.refreshAll(agentId);}
|
|
568
|
+
}catch(e){
|
|
569
|
+
addMsg('agent',`◌ 离线模式 · 演示响应:已记录任务「${task.slice(0,20)}」并写入 ${a.name} 记忆库`);
|
|
570
|
+
setCoreStatus('离线演示 · 待命中',false);updateTask(task,'PASS');demoChain(agentId,task);
|
|
571
|
+
if(ctx.termLog)ctx.termLog('offline · 演示执行完成 · 记忆已写入','ok');
|
|
572
|
+
}finally{btn.disabled=false;}
|
|
573
|
+
}
|
|
574
|
+
let typeIv=null;
|
|
575
|
+
function typeStatus(steps){clearInterval(typeIv);let i=0;
|
|
576
|
+
typeIv=setInterval(()=>{const coreBody=ctx._coreEl;
|
|
577
|
+
if(i<steps.length&&coreBody){const t=coreBody.querySelector('[data-role="core-status-text"]');if(t)t.textContent=steps[i];i++;}
|
|
578
|
+
else clearInterval(typeIv);},600);}
|
|
579
|
+
|
|
580
|
+
function addMsg(role,content,blocked){
|
|
581
|
+
const coreBody=ctx._coreEl;if(!coreBody)return;
|
|
582
|
+
const log=coreBody.querySelector('[data-role="chat-log"]');if(!log)return;
|
|
583
|
+
const a=AG(activeAgent);const el=document.createElement('div');
|
|
584
|
+
el.className=`msg ${role}${blocked?' blocked':''}`;
|
|
585
|
+
el.innerHTML=role==='agent'?`<div class="m-tag">${a.name} AGENT</div>${esc(content)}`:esc(content);
|
|
586
|
+
log.appendChild(el);log.scrollTop=log.scrollHeight;
|
|
587
|
+
}
|
|
588
|
+
function updatePodTask(agentId,n){
|
|
589
|
+
document.querySelectorAll(`[data-podtask="${agentId}"]`).forEach(e=>e.textContent=n);
|
|
590
|
+
const coreBody=ctx._coreEl;if(coreBody){const t=coreBody.querySelector('[data-core="tasks"]');if(t&&agentId===activeAgent)t.textContent=n;}
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/* ── TASKS ── */
|
|
594
|
+
function addTask(name,agentId){
|
|
595
|
+
const id=`tsk${taskSeq++}`,a=AG(agentId);
|
|
596
|
+
const s=ctx._taskStreamEl;if(!s)return;
|
|
597
|
+
s.querySelector('.empty')?.remove();
|
|
598
|
+
const el=document.createElement('div');el.className='tc-node';el.id=id;
|
|
599
|
+
el.innerHTML=`<div class="tc-rail"><div class="tc-dot" style="--tcc:${a.color}"></div></div>
|
|
600
|
+
<div class="tc-card"><div class="tc-top"><span class="tc-type">${a.code}</span><span class="tc-stat st-PENDING" id="${id}-st">RUNNING</span></div>
|
|
601
|
+
<div class="tc-text">${esc(name.slice(0,50))}</div></div>`;
|
|
602
|
+
s.insertBefore(el,s.firstChild);tasks.unshift({id,name,agentId});
|
|
603
|
+
}
|
|
604
|
+
function updateTask(name,status){
|
|
605
|
+
const t=tasks.find(x=>name.startsWith(x.name.slice(0,30))||x.name.startsWith(name.slice(0,30)));if(!t)return;
|
|
606
|
+
const el=document.getElementById(`${t.id}-st`);if(!el)return;
|
|
607
|
+
el.className=`tc-stat st-${status}`;el.textContent=status==='PASS'?'DONE':status==='BLOCK'?'BLOCKED':'RUNNING';
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/* ── DATA LOADERS (called by widgets via ctx) ── */
|
|
611
|
+
async function loadChainInto(el,agentId){
|
|
612
|
+
const stream=el.querySelector('[data-role="tc-stream"]');if(!stream)return;
|
|
613
|
+
try{const r=await fetch(`${API}/thoughtchain/${agentId}/chain`);const d=await r.json();
|
|
614
|
+
renderChainEl(stream,(d.nodes||[]).slice(-15).reverse());}
|
|
615
|
+
catch{stream.innerHTML='<div class="empty">离线 · 无推理数据</div>';}
|
|
616
|
+
}
|
|
617
|
+
function renderChainEl(stream,nodes){
|
|
618
|
+
if(!nodes.length){stream.innerHTML='<div class="empty">执行任务后显示推理轨迹</div>';return;}
|
|
619
|
+
stream.innerHTML=nodes.map((n,i)=>{const c=statusColor(n.harness_status);
|
|
620
|
+
return`<div class="tc-node"><div class="tc-rail"><div class="tc-dot" style="--tcc:${c}"></div>${i<nodes.length-1?`<div class="tc-seg" style="--tcc:${c}"></div>`:''}</div>
|
|
621
|
+
<div class="tc-card"><div class="tc-top"><span class="tc-type">${n.type||'reasoning'}</span><span class="tc-stat st-${n.harness_status}">${n.harness_status}</span></div>
|
|
622
|
+
<div class="tc-text">${esc((n.content||'').slice(0,80))}${(n.content||'').length>80?'…':''}</div>
|
|
623
|
+
<div class="tc-meta"><span class="tc-pill">conf ${(n.conf||0).toFixed(2)}</span>${n.harness_delta!=null?`<span class="tc-pill">Δ ${n.harness_delta.toFixed(3)}</span>`:''}${n.dominant_dim?`<span class="tc-pill">${n.dominant_dim}</span>`:''}</div></div></div>`;}).join('');
|
|
624
|
+
// 更新核心 HUD
|
|
625
|
+
const coreBody=ctx._coreEl;if(coreBody){const nn=coreBody.querySelector('[data-hud="nodes"]');if(nn)nn.textContent=nodes.length;
|
|
626
|
+
const cn=coreBody.querySelector('[data-core="nodes"]');if(cn)cn.textContent=nodes.length;}
|
|
627
|
+
}
|
|
628
|
+
function demoChain(agentId,task){
|
|
629
|
+
const stream=document.querySelector('[data-widget="thoughtchain"] [data-role="tc-stream"]');if(!stream)return;
|
|
630
|
+
const demo=[
|
|
631
|
+
{type:'goal',content:`目标基线:${task}`,conf:1.0,harness_status:'BASELINE'},
|
|
632
|
+
{type:'memory_retrieval',content:'检索相关历史记忆 3 条',conf:0.95,harness_status:'PASS',harness_delta:0.04,dominant_dim:'semantic'},
|
|
633
|
+
{type:'reasoning',content:'分析任务类型与执行路径',conf:0.91,harness_status:'PASS',harness_delta:0.08,dominant_dim:'semantic'},
|
|
634
|
+
{type:'decision',content:'生成执行方案并记录决策',conf:0.88,harness_status:'PASS',harness_delta:0.11,dominant_dim:'scope'},
|
|
635
|
+
];
|
|
636
|
+
renderChainEl(stream,demo.reverse());
|
|
637
|
+
}
|
|
638
|
+
async function loadHarnessInto(el,agentId){
|
|
639
|
+
try{const[hR,sR]=await Promise.all([fetch(`${API}/harness/${agentId}/status`),fetch(`${API}/thoughtchain/${agentId}/summary`)]);
|
|
640
|
+
applyHarnessEl(el,await hR.json(),await sR.json());}
|
|
641
|
+
catch{applyHarnessEl(el,{thresholds:{run_count:0,shadow_rounds:20,block:0.25,warn:0.15,shadow_mode:true},weights:{semantic:0.5,tool:0.3,scope:0.2},policy:{version:1,learned_rules:0}},{avg_delta:0,total_nodes:0,avg_confidence:0});}
|
|
642
|
+
}
|
|
643
|
+
function applyHarnessEl(el,h,sum){
|
|
644
|
+
const th=h.thresholds||{},wt=h.weights||{semantic:0.5,tool:0.3,scope:0.2},pol=h.policy||{};
|
|
645
|
+
const prog=Math.min((th.run_count||0)/(th.shadow_rounds||20),1),circ=2*Math.PI*30;
|
|
646
|
+
const ring=el.querySelector('[data-role="h-ring"]');
|
|
647
|
+
if(ring){ring.style.strokeDashoffset=circ*(1-prog);ring.style.stroke=th.shadow_mode?'#ffb347':'#1dffa6';}
|
|
648
|
+
const setT=(r,v)=>{const e=el.querySelector(`[data-role="${r}"]`);if(e)e.textContent=v;};
|
|
649
|
+
setT('h-ring-val',th.run_count||0);setT('h-block',(th.block||0.25).toFixed(3));
|
|
650
|
+
setT('h-warn',(th.warn||0.15).toFixed(3));setT('h-avg',(sum.avg_delta||0).toFixed(3));
|
|
651
|
+
const chip=el.querySelector('[data-role="h-mode"]');
|
|
652
|
+
if(chip){if(th.shadow_mode===false){chip.className='h-mode active';chip.textContent='● ACTIVE 活跃';
|
|
653
|
+
document.getElementById('teleHarness').textContent='ACTIVE';document.getElementById('teleHarness').className='tele-val ok';}
|
|
654
|
+
else{chip.className='h-mode shadow';chip.textContent='◔ SHADOW 校准';}}
|
|
655
|
+
const setW=(r,v)=>{const f=el.querySelector(`[data-role="wt-${r}"]`),p=el.querySelector(`[data-role="wt-${r}-pct"]`);
|
|
656
|
+
if(f)f.style.width=`${(v*100).toFixed(0)}%`;if(p)p.textContent=`${(v*100).toFixed(0)}%`;};
|
|
657
|
+
setW('sem',wt.semantic||0.5);setW('tool',wt.tool||0.3);setW('scope',wt.scope||0.2);
|
|
658
|
+
// core HUD
|
|
659
|
+
const coreBody=ctx._coreEl;if(coreBody){
|
|
660
|
+
const u=(k,v)=>{const e=coreBody.querySelector(`[data-hud="${k}"]`);if(e)e.textContent=v;};
|
|
661
|
+
u('conf',(sum.avg_confidence||0).toFixed(2));u('drift',(sum.avg_delta||0).toFixed(3));
|
|
662
|
+
u('policy','v'+(pol.version||1));u('rules',pol.learned_rules||0);u('block',(th.block||0.25).toFixed(2));
|
|
663
|
+
u('mode',th.shadow_mode===false?'ACTIVE':'SHADOW');
|
|
664
|
+
const m=coreBody.querySelector('[data-core="mem"]');if(m)m.textContent=sum.total_nodes||0;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/* ── POLL + WS ── */
|
|
669
|
+
async function pollAll(){
|
|
670
|
+
try{const r=await fetch(`${API}/status`);if(!r.ok)throw 0;const data=await r.json();setOnline(true);
|
|
671
|
+
let mem=0;for(const[id,s]of Object.entries(data))mem+=s?.thought_chain?.total_nodes||0;
|
|
672
|
+
document.getElementById('teleMemory').textContent=mem;WidgetRuntime.refreshAll(activeAgent);
|
|
673
|
+
}catch{setOnline(false);}
|
|
674
|
+
}
|
|
675
|
+
function setOnline(v){online=v;
|
|
676
|
+
document.getElementById('teleUplink').textContent=v?'LINKED':'OFFLINE';
|
|
677
|
+
document.getElementById('teleUplink').className=v?'tele-val ok':'tele-val warn';
|
|
678
|
+
document.getElementById('offlineBanner').style.display=v?'none':'block';}
|
|
679
|
+
function connectWS(){
|
|
680
|
+
try{ws=new WebSocket(WS);
|
|
681
|
+
ws.onmessage=e=>{try{const m=JSON.parse(e.data);WidgetRuntime.dispatch(m.event,{data:m.data});}catch{}};
|
|
682
|
+
ws.onopen=()=>setOnline(true);ws.onclose=()=>setTimeout(connectWS,4000);}catch{}
|
|
683
|
+
}
|
|
684
|
+
</script>
|
|
685
|
+
</body>
|
|
686
|
+
</html>
|