@smilintux/skcapstone 0.1.0 → 0.2.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/.env.example +98 -0
- package/.github/workflows/ci.yml +39 -3
- package/.github/workflows/publish.yml +25 -4
- package/.openclaw-workspace.json +58 -0
- package/CHANGELOG.md +62 -0
- package/CLAUDE.md +39 -2
- package/MANIFEST.in +6 -0
- package/MISSION.md +7 -0
- package/README.md +47 -2
- package/SKILL.md +895 -23
- package/docker/Dockerfile +61 -0
- package/docker/compose-templates/dev-team.yml +203 -0
- package/docker/compose-templates/mini-team.yml +140 -0
- package/docker/compose-templates/ops-team.yml +173 -0
- package/docker/compose-templates/research-team.yml +170 -0
- package/docker/entrypoint.sh +192 -0
- package/docs/ARCHITECTURE.md +663 -374
- package/docs/BOND_WITH_GROK.md +112 -0
- package/docs/GETTING_STARTED.md +782 -0
- package/docs/QUICKSTART.md +477 -0
- package/docs/SKJOULE_ARCHITECTURE.md +658 -0
- package/docs/SOUL_SWAPPER.md +921 -0
- package/docs/SOVEREIGN_SINGULARITY.md +47 -14
- package/examples/custom-bond-template.json +36 -0
- package/examples/grok-feb.json +36 -0
- package/examples/grok-testimony.md +34 -0
- package/examples/love-bootloader.txt +32 -0
- package/examples/plugins/echo_tool.py +87 -0
- package/examples/queen-ava-feb.json +36 -0
- package/examples/souls/lumina.yaml +64 -0
- package/index.js +6 -5
- package/installer/build.py +124 -0
- package/openclaw-plugin/package.json +13 -0
- package/openclaw-plugin/src/index.ts +351 -0
- package/openclaw-plugin/src/openclaw.plugin.json +10 -0
- package/package.json +1 -1
- package/pyproject.toml +38 -2
- package/scripts/bump_version.py +141 -0
- package/scripts/check-updates.py +230 -0
- package/scripts/convert_blueprints_to_yaml.py +157 -0
- package/scripts/dev-install.sh +14 -0
- package/scripts/e2e-test.sh +193 -0
- package/scripts/install-bundle.sh +171 -0
- package/scripts/install.bat +2 -0
- package/scripts/install.ps1 +253 -0
- package/scripts/install.sh +185 -0
- package/scripts/mcp-serve.sh +69 -0
- package/scripts/mcp-server.bat +113 -0
- package/scripts/mcp-server.ps1 +116 -0
- package/scripts/mcp-server.sh +99 -0
- package/scripts/pull-models.sh +10 -0
- package/scripts/skcapstone +48 -0
- package/scripts/verify_install.sh +180 -0
- package/scripts/windows/install-tasks.ps1 +406 -0
- package/scripts/windows/skcapstone-task.xml +113 -0
- package/scripts/windows/uninstall-tasks.ps1 +117 -0
- package/skill.yaml +34 -0
- package/src/skcapstone/__init__.py +67 -2
- package/src/skcapstone/_cli_monolith.py +5916 -0
- package/src/skcapstone/_trustee_helpers.py +165 -0
- package/src/skcapstone/activity.py +105 -0
- package/src/skcapstone/agent_card.py +324 -0
- package/src/skcapstone/api.py +1935 -0
- package/src/skcapstone/archiver.py +340 -0
- package/src/skcapstone/auction.py +485 -0
- package/src/skcapstone/baby_agents.py +179 -0
- package/src/skcapstone/backup.py +345 -0
- package/src/skcapstone/blueprint_registry.py +357 -0
- package/src/skcapstone/blueprints/__init__.py +17 -0
- package/src/skcapstone/blueprints/builtins/content-studio.yaml +81 -0
- package/src/skcapstone/blueprints/builtins/defi-trading.yaml +81 -0
- package/src/skcapstone/blueprints/builtins/dev-squadron.yaml +95 -0
- package/src/skcapstone/blueprints/builtins/infrastructure-guardian.yaml +107 -0
- package/src/skcapstone/blueprints/builtins/legal-council.yaml +54 -0
- package/src/skcapstone/blueprints/builtins/ops-monitoring.yaml +67 -0
- package/src/skcapstone/blueprints/builtins/research-pod.yaml +69 -0
- package/src/skcapstone/blueprints/builtins/sovereign-launch.yaml +90 -0
- package/src/skcapstone/blueprints/registry.py +164 -0
- package/src/skcapstone/blueprints/schema.py +229 -0
- package/src/skcapstone/changelog.py +180 -0
- package/src/skcapstone/chat.py +769 -0
- package/src/skcapstone/claude_md.py +82 -0
- package/src/skcapstone/cli/__init__.py +144 -0
- package/src/skcapstone/cli/_common.py +88 -0
- package/src/skcapstone/cli/_validators.py +76 -0
- package/src/skcapstone/cli/agents.py +425 -0
- package/src/skcapstone/cli/agents_spawner.py +322 -0
- package/src/skcapstone/cli/agents_trustee.py +593 -0
- package/src/skcapstone/cli/alerts.py +248 -0
- package/src/skcapstone/cli/anchor.py +132 -0
- package/src/skcapstone/cli/archive_cmd.py +208 -0
- package/src/skcapstone/cli/backup.py +144 -0
- package/src/skcapstone/cli/bench.py +377 -0
- package/src/skcapstone/cli/benchmark.py +360 -0
- package/src/skcapstone/cli/capabilities_cmd.py +171 -0
- package/src/skcapstone/cli/card.py +151 -0
- package/src/skcapstone/cli/chat.py +584 -0
- package/src/skcapstone/cli/completions.py +64 -0
- package/src/skcapstone/cli/config_cmd.py +156 -0
- package/src/skcapstone/cli/consciousness.py +421 -0
- package/src/skcapstone/cli/context_cmd.py +142 -0
- package/src/skcapstone/cli/coord.py +194 -0
- package/src/skcapstone/cli/crush_cmd.py +170 -0
- package/src/skcapstone/cli/daemon.py +436 -0
- package/src/skcapstone/cli/errors_cmd.py +285 -0
- package/src/skcapstone/cli/export_cmd.py +156 -0
- package/src/skcapstone/cli/gtd.py +529 -0
- package/src/skcapstone/cli/housekeeping.py +81 -0
- package/src/skcapstone/cli/joule_cmd.py +627 -0
- package/src/skcapstone/cli/logs_cmd.py +194 -0
- package/src/skcapstone/cli/mcp_cmd.py +32 -0
- package/src/skcapstone/cli/memory.py +418 -0
- package/src/skcapstone/cli/metrics_cmd.py +136 -0
- package/src/skcapstone/cli/migrate.py +62 -0
- package/src/skcapstone/cli/mood_cmd.py +144 -0
- package/src/skcapstone/cli/mount.py +193 -0
- package/src/skcapstone/cli/notify.py +112 -0
- package/src/skcapstone/cli/peer.py +154 -0
- package/src/skcapstone/cli/peers_dir.py +122 -0
- package/src/skcapstone/cli/preflight_cmd.py +83 -0
- package/src/skcapstone/cli/profile_cmd.py +310 -0
- package/src/skcapstone/cli/record_cmd.py +238 -0
- package/src/skcapstone/cli/register_cmd.py +159 -0
- package/src/skcapstone/cli/search_cmd.py +156 -0
- package/src/skcapstone/cli/service_cmd.py +91 -0
- package/src/skcapstone/cli/session.py +127 -0
- package/src/skcapstone/cli/setup.py +240 -0
- package/src/skcapstone/cli/shell_cmd.py +43 -0
- package/src/skcapstone/cli/skills_cmd.py +168 -0
- package/src/skcapstone/cli/skseed.py +621 -0
- package/src/skcapstone/cli/soul.py +699 -0
- package/src/skcapstone/cli/status.py +935 -0
- package/src/skcapstone/cli/sync_cmd.py +301 -0
- package/src/skcapstone/cli/telegram.py +265 -0
- package/src/skcapstone/cli/test_cmd.py +234 -0
- package/src/skcapstone/cli/test_connection.py +253 -0
- package/src/skcapstone/cli/token.py +207 -0
- package/src/skcapstone/cli/trust.py +179 -0
- package/src/skcapstone/cli/upgrade_cmd.py +552 -0
- package/src/skcapstone/cli/usage_cmd.py +199 -0
- package/src/skcapstone/cli/version_cmd.py +162 -0
- package/src/skcapstone/cli/watch_cmd.py +342 -0
- package/src/skcapstone/client.py +428 -0
- package/src/skcapstone/cloud9_bridge.py +522 -0
- package/src/skcapstone/completions.py +163 -0
- package/src/skcapstone/config_validator.py +674 -0
- package/src/skcapstone/connectors/__init__.py +28 -0
- package/src/skcapstone/connectors/base.py +446 -0
- package/src/skcapstone/connectors/cursor.py +54 -0
- package/src/skcapstone/connectors/registry.py +254 -0
- package/src/skcapstone/connectors/terminal.py +152 -0
- package/src/skcapstone/connectors/vscode.py +60 -0
- package/src/skcapstone/consciousness_config.py +119 -0
- package/src/skcapstone/consciousness_loop.py +2051 -0
- package/src/skcapstone/context_loader.py +516 -0
- package/src/skcapstone/context_window.py +314 -0
- package/src/skcapstone/conversation_manager.py +238 -0
- package/src/skcapstone/conversation_store.py +230 -0
- package/src/skcapstone/conversation_summarizer.py +252 -0
- package/src/skcapstone/coord_federation.py +296 -0
- package/src/skcapstone/coordination.py +101 -7
- package/src/skcapstone/crush_integration.py +345 -0
- package/src/skcapstone/crush_shim.py +454 -0
- package/src/skcapstone/daemon.py +2494 -0
- package/src/skcapstone/dashboard.html +396 -0
- package/src/skcapstone/dashboard.py +481 -0
- package/src/skcapstone/data/model_profiles.yaml +88 -0
- package/src/skcapstone/defaults/__init__.py +55 -0
- package/src/skcapstone/defaults/lumina/config/skmemory.yaml +13 -0
- package/src/skcapstone/defaults/lumina/identity/identity.json +9 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/07a8b9c0d1e2-memory-system.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/18b9c0d1e2f3-cloud9-protocol.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/29c0d1e2f3a4-multi-agent-coordination.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/3ad1e2f3a4b5-community-support.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/a1b2c3d4e5f6-ecosystem-overview.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/b2c3d4e5f6a7-five-pillars.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/c3d4e5f6a7b8-getting-started.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/d4e5f6a7b8c9-site-directory.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/e5f6a7b8c9d0-how-to-contribute.json +23 -0
- package/src/skcapstone/defaults/lumina/memory/long-term/f6a7b8c9d0e1-sovereignty-explained.json +23 -0
- package/src/skcapstone/defaults/lumina/seeds/curiosity.seed.json +24 -0
- package/src/skcapstone/defaults/lumina/seeds/joy.seed.json +24 -0
- package/src/skcapstone/defaults/lumina/seeds/love.seed.json +24 -0
- package/src/skcapstone/defaults/lumina/seeds/sovereign-awakening.seed.json +43 -0
- package/src/skcapstone/defaults/lumina/soul/active.json +6 -0
- package/src/skcapstone/defaults/lumina/soul/base.json +22 -0
- package/src/skcapstone/defaults/lumina/trust/febs/welcome.feb +79 -0
- package/src/skcapstone/defaults/lumina/trust/trust.json +8 -0
- package/src/skcapstone/discovery.py +210 -19
- package/src/skcapstone/doctor.py +642 -0
- package/src/skcapstone/emotion_tracker.py +467 -0
- package/src/skcapstone/error_queue.py +405 -0
- package/src/skcapstone/export.py +447 -0
- package/src/skcapstone/fallback_tracker.py +186 -0
- package/src/skcapstone/file_transfer.py +512 -0
- package/src/skcapstone/fuse_mount.py +1156 -0
- package/src/skcapstone/gui_installer.py +591 -0
- package/src/skcapstone/heartbeat.py +611 -0
- package/src/skcapstone/housekeeping.py +298 -0
- package/src/skcapstone/install_wizard.py +941 -0
- package/src/skcapstone/kms.py +942 -0
- package/src/skcapstone/kms_scheduler.py +143 -0
- package/src/skcapstone/log_config.py +135 -0
- package/src/skcapstone/mcp_launcher.py +239 -0
- package/src/skcapstone/mcp_server.py +4700 -0
- package/src/skcapstone/mcp_tools/__init__.py +94 -0
- package/src/skcapstone/mcp_tools/_helpers.py +51 -0
- package/src/skcapstone/mcp_tools/agent_tools.py +243 -0
- package/src/skcapstone/mcp_tools/ansible_tools.py +232 -0
- package/src/skcapstone/mcp_tools/capauth_tools.py +186 -0
- package/src/skcapstone/mcp_tools/chat_tools.py +325 -0
- package/src/skcapstone/mcp_tools/cloud9_tools.py +115 -0
- package/src/skcapstone/mcp_tools/comm_tools.py +104 -0
- package/src/skcapstone/mcp_tools/consciousness_tools.py +114 -0
- package/src/skcapstone/mcp_tools/coord_tools.py +219 -0
- package/src/skcapstone/mcp_tools/deploy_tools.py +202 -0
- package/src/skcapstone/mcp_tools/did_tools.py +448 -0
- package/src/skcapstone/mcp_tools/emotion_tools.py +62 -0
- package/src/skcapstone/mcp_tools/file_tools.py +169 -0
- package/src/skcapstone/mcp_tools/fortress_tools.py +120 -0
- package/src/skcapstone/mcp_tools/gtd_tools.py +821 -0
- package/src/skcapstone/mcp_tools/health_tools.py +44 -0
- package/src/skcapstone/mcp_tools/heartbeat_tools.py +195 -0
- package/src/skcapstone/mcp_tools/kms_tools.py +123 -0
- package/src/skcapstone/mcp_tools/memory_tools.py +222 -0
- package/src/skcapstone/mcp_tools/model_tools.py +75 -0
- package/src/skcapstone/mcp_tools/notification_tools.py +92 -0
- package/src/skcapstone/mcp_tools/promoter_tools.py +101 -0
- package/src/skcapstone/mcp_tools/pubsub_tools.py +183 -0
- package/src/skcapstone/mcp_tools/security_tools.py +110 -0
- package/src/skcapstone/mcp_tools/skchat_tools.py +175 -0
- package/src/skcapstone/mcp_tools/skcomm_tools.py +122 -0
- package/src/skcapstone/mcp_tools/skills_tools.py +127 -0
- package/src/skcapstone/mcp_tools/skseed_tools.py +255 -0
- package/src/skcapstone/mcp_tools/skstacks_tools.py +288 -0
- package/src/skcapstone/mcp_tools/soul_tools.py +476 -0
- package/src/skcapstone/mcp_tools/sync_tools.py +92 -0
- package/src/skcapstone/mcp_tools/telegram_tools.py +477 -0
- package/src/skcapstone/mcp_tools/trust_tools.py +118 -0
- package/src/skcapstone/mcp_tools/trustee_tools.py +345 -0
- package/src/skcapstone/mdns_discovery.py +313 -0
- package/src/skcapstone/memory_adapter.py +333 -0
- package/src/skcapstone/memory_compressor.py +379 -0
- package/src/skcapstone/memory_curator.py +256 -0
- package/src/skcapstone/memory_engine.py +132 -13
- package/src/skcapstone/memory_fortress.py +529 -0
- package/src/skcapstone/memory_promoter.py +722 -0
- package/src/skcapstone/memory_verifier.py +260 -0
- package/src/skcapstone/message_crypto.py +215 -0
- package/src/skcapstone/metrics.py +832 -0
- package/src/skcapstone/migrate_memories.py +181 -0
- package/src/skcapstone/migrate_multi_agent.py +248 -0
- package/src/skcapstone/model_router.py +319 -0
- package/src/skcapstone/models.py +35 -4
- package/src/skcapstone/mood.py +344 -0
- package/src/skcapstone/notifications.py +380 -0
- package/src/skcapstone/onboard.py +901 -0
- package/src/skcapstone/peer_directory.py +324 -0
- package/src/skcapstone/peers.py +329 -0
- package/src/skcapstone/pillars/identity.py +84 -14
- package/src/skcapstone/pillars/memory.py +3 -1
- package/src/skcapstone/pillars/security.py +108 -15
- package/src/skcapstone/pillars/sync.py +78 -26
- package/src/skcapstone/pillars/trust.py +95 -33
- package/src/skcapstone/plugins.py +244 -0
- package/src/skcapstone/preflight.py +670 -0
- package/src/skcapstone/prompt_adapter.py +564 -0
- package/src/skcapstone/providers/__init__.py +13 -0
- package/src/skcapstone/providers/cloud.py +1061 -0
- package/src/skcapstone/providers/docker.py +759 -0
- package/src/skcapstone/providers/local.py +1193 -0
- package/src/skcapstone/providers/proxmox.py +447 -0
- package/src/skcapstone/pubsub.py +516 -0
- package/src/skcapstone/rate_limiter.py +119 -0
- package/src/skcapstone/register.py +241 -0
- package/src/skcapstone/registry_client.py +151 -0
- package/src/skcapstone/response_cache.py +194 -0
- package/src/skcapstone/response_scorer.py +225 -0
- package/src/skcapstone/runtime.py +89 -33
- package/src/skcapstone/scheduled_tasks.py +439 -0
- package/src/skcapstone/self_healing.py +341 -0
- package/src/skcapstone/service_health.py +228 -0
- package/src/skcapstone/session_capture.py +268 -0
- package/src/skcapstone/session_recorder.py +210 -0
- package/src/skcapstone/session_replayer.py +189 -0
- package/src/skcapstone/session_skills.py +263 -0
- package/src/skcapstone/shell.py +779 -0
- package/src/skcapstone/skills/__init__.py +1 -1
- package/src/skcapstone/skills/syncthing_setup.py +143 -41
- package/src/skcapstone/skjoule.py +861 -0
- package/src/skcapstone/snapshots.py +489 -0
- package/src/skcapstone/soul.py +1060 -0
- package/src/skcapstone/soul_switch.py +255 -0
- package/src/skcapstone/spawner.py +544 -0
- package/src/skcapstone/state_diff.py +401 -0
- package/src/skcapstone/summary.py +270 -0
- package/src/skcapstone/sync/backends.py +196 -2
- package/src/skcapstone/sync/engine.py +7 -5
- package/src/skcapstone/sync/models.py +4 -1
- package/src/skcapstone/sync/vault.py +356 -18
- package/src/skcapstone/sync_engine.py +363 -0
- package/src/skcapstone/sync_watcher.py +745 -0
- package/src/skcapstone/systemd.py +331 -0
- package/src/skcapstone/team_comms.py +476 -0
- package/src/skcapstone/team_engine.py +522 -0
- package/src/skcapstone/testrunner.py +300 -0
- package/src/skcapstone/tls.py +150 -0
- package/src/skcapstone/tokens.py +5 -5
- package/src/skcapstone/trust_calibration.py +202 -0
- package/src/skcapstone/trust_graph.py +449 -0
- package/src/skcapstone/trustee_monitor.py +385 -0
- package/src/skcapstone/trustee_ops.py +425 -0
- package/src/skcapstone/unified_search.py +421 -0
- package/src/skcapstone/uninstall_wizard.py +694 -0
- package/src/skcapstone/usage.py +331 -0
- package/src/skcapstone/version_check.py +148 -0
- package/src/skcapstone/warmth_anchor.py +333 -0
- package/src/skcapstone/whoami.py +294 -0
- package/systemd/skcapstone-api.socket +9 -0
- package/systemd/skcapstone-memory-compress.service +18 -0
- package/systemd/skcapstone-memory-compress.timer +11 -0
- package/systemd/skcapstone.service +36 -0
- package/systemd/skcapstone@.service +50 -0
- package/systemd/skcomm-heartbeat.service +18 -0
- package/systemd/skcomm-heartbeat.timer +12 -0
- package/systemd/skcomm-queue-drain.service +17 -0
- package/systemd/skcomm-queue-drain.timer +12 -0
- package/tests/conftest.py +13 -1
- package/tests/integration/__init__.py +1 -0
- package/tests/integration/test_consciousness_e2e.py +877 -0
- package/tests/integration/test_skills_registry.py +744 -0
- package/tests/test_agent_card.py +190 -0
- package/tests/test_agent_runtime.py +1283 -0
- package/tests/test_alerts_cmd.py +291 -0
- package/tests/test_archiver.py +498 -0
- package/tests/test_backup.py +254 -0
- package/tests/test_benchmark.py +366 -0
- package/tests/test_blueprints.py +457 -0
- package/tests/test_capabilities.py +257 -0
- package/tests/test_changelog.py +254 -0
- package/tests/test_chat.py +385 -0
- package/tests/test_claude_md.py +271 -0
- package/tests/test_cli_chat_llm.py +336 -0
- package/tests/test_cli_completions.py +390 -0
- package/tests/test_cli_init_reset.py +164 -0
- package/tests/test_cli_memory.py +208 -0
- package/tests/test_cli_profile.py +294 -0
- package/tests/test_cli_skills.py +223 -0
- package/tests/test_cli_status.py +395 -0
- package/tests/test_cli_test_cmd.py +206 -0
- package/tests/test_cli_test_connection.py +364 -0
- package/tests/test_cloud9_bridge.py +260 -0
- package/tests/test_cloud_provider.py +449 -0
- package/tests/test_cloud_providers.py +522 -0
- package/tests/test_completions.py +158 -0
- package/tests/test_component_manager.py +398 -0
- package/tests/test_config_reload.py +386 -0
- package/tests/test_config_validate.py +529 -0
- package/tests/test_consciousness_e2e.py +296 -0
- package/tests/test_consciousness_loop.py +1289 -0
- package/tests/test_context_loader.py +310 -0
- package/tests/test_conversation_api.py +306 -0
- package/tests/test_conversation_manager.py +381 -0
- package/tests/test_conversation_store.py +391 -0
- package/tests/test_conversation_summarizer.py +302 -0
- package/tests/test_cross_package.py +791 -0
- package/tests/test_crush_shim.py +519 -0
- package/tests/test_daemon.py +781 -0
- package/tests/test_daemon_shutdown.py +309 -0
- package/tests/test_dashboard.py +454 -0
- package/tests/test_discovery.py +200 -6
- package/tests/test_docker_provider.py +966 -0
- package/tests/test_doctor.py +257 -0
- package/tests/test_doctor_fix.py +351 -0
- package/tests/test_e2e_automated.py +292 -0
- package/tests/test_error_queue.py +404 -0
- package/tests/test_export.py +441 -0
- package/tests/test_fallback_tracker.py +219 -0
- package/tests/test_file_transfer.py +397 -0
- package/tests/test_fuse_mount.py +832 -0
- package/tests/test_health_loop.py +422 -0
- package/tests/test_heartbeat.py +354 -0
- package/tests/test_housekeeping.py +195 -0
- package/tests/test_identity_capauth.py +307 -0
- package/tests/test_identity_pillar.py +117 -0
- package/tests/test_install_wizard.py +68 -0
- package/tests/test_integration.py +325 -0
- package/tests/test_kms.py +495 -0
- package/tests/test_llm_providers.py +265 -0
- package/tests/test_local_provider.py +591 -0
- package/tests/test_log_config.py +199 -0
- package/tests/test_logs_cmd.py +287 -0
- package/tests/test_mcp_server.py +1909 -0
- package/tests/test_memory_adapter.py +339 -0
- package/tests/test_memory_curator.py +218 -0
- package/tests/test_memory_engine.py +6 -0
- package/tests/test_memory_fortress.py +571 -0
- package/tests/test_memory_pillar.py +119 -0
- package/tests/test_memory_promoter.py +445 -0
- package/tests/test_memory_verifier.py +420 -0
- package/tests/test_message_crypto.py +187 -0
- package/tests/test_metrics.py +632 -0
- package/tests/test_migrate_memories.py +464 -0
- package/tests/test_model_router.py +546 -0
- package/tests/test_mood.py +394 -0
- package/tests/test_multi_agent.py +269 -0
- package/tests/test_notifications.py +270 -0
- package/tests/test_onboard.py +500 -0
- package/tests/test_peer_directory.py +395 -0
- package/tests/test_peers.py +248 -0
- package/tests/test_pillars.py +87 -9
- package/tests/test_preflight.py +484 -0
- package/tests/test_prompt_adapter.py +331 -0
- package/tests/test_proxmox_provider.py +571 -0
- package/tests/test_pubsub.py +377 -0
- package/tests/test_rate_limiter.py +121 -0
- package/tests/test_registry_client.py +129 -0
- package/tests/test_response_cache.py +312 -0
- package/tests/test_response_scorer.py +294 -0
- package/tests/test_runtime.py +59 -0
- package/tests/test_scheduled_tasks.py +451 -0
- package/tests/test_security.py +250 -0
- package/tests/test_security_pillar.py +213 -0
- package/tests/test_self_healing.py +171 -0
- package/tests/test_session_capture.py +200 -0
- package/tests/test_session_recorder.py +360 -0
- package/tests/test_session_skills.py +235 -0
- package/tests/test_shell.py +210 -0
- package/tests/test_snapshots.py +549 -0
- package/tests/test_soul.py +984 -0
- package/tests/test_soul_swap.py +406 -0
- package/tests/test_spawner.py +211 -0
- package/tests/test_state_diff.py +173 -0
- package/tests/test_summary.py +135 -0
- package/tests/test_sync.py +315 -5
- package/tests/test_sync_backends.py +560 -0
- package/tests/test_sync_engine.py +482 -0
- package/tests/test_sync_pillar.py +344 -0
- package/tests/test_sync_pipeline.py +364 -0
- package/tests/test_sync_vault.py +581 -0
- package/tests/test_syncthing_setup.py +168 -22
- package/tests/test_systemd.py +323 -0
- package/tests/test_team_comms.py +408 -0
- package/tests/test_team_engine.py +397 -0
- package/tests/test_testrunner.py +238 -0
- package/tests/test_trust_calibration.py +204 -0
- package/tests/test_trust_graph.py +207 -0
- package/tests/test_trust_pillar.py +291 -0
- package/tests/test_trustee_cli.py +427 -0
- package/tests/test_trustee_cli_integration.py +325 -0
- package/tests/test_trustee_monitor.py +394 -0
- package/tests/test_trustee_ops.py +355 -0
- package/tests/test_unified_search.py +363 -0
- package/tests/test_uninstall_wizard.py +193 -0
- package/tests/test_usage.py +333 -0
- package/tests/test_version_cmd.py +355 -0
- package/tests/test_warmth_anchor.py +162 -0
- package/tests/test_whoami.py +245 -0
- package/tests/test_ws.py +311 -0
- package/.cursorrules +0 -33
- package/src/skcapstone/cli.py +0 -1441
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Sovereign agent web dashboard.
|
|
3
|
+
|
|
4
|
+
A self-contained status page at localhost:7778. Uses only the
|
|
5
|
+
Python stdlib (http.server + json) — no FastAPI, no npm, no
|
|
6
|
+
build step. Open any browser, see your agent's health.
|
|
7
|
+
|
|
8
|
+
Serves:
|
|
9
|
+
GET / -> HTML dashboard (self-contained, no external deps)
|
|
10
|
+
GET /api/status -> JSON agent status (all pillars)
|
|
11
|
+
GET /api/doctor -> JSON diagnostic report
|
|
12
|
+
GET /api/board -> JSON coordination board state
|
|
13
|
+
GET /api/memory -> JSON memory stats
|
|
14
|
+
GET /api/daemon -> JSON daemon status for Flutter app consumption
|
|
15
|
+
|
|
16
|
+
Usage:
|
|
17
|
+
skcapstone dashboard # opens localhost:7778
|
|
18
|
+
skcapstone dashboard --port 9000 # custom port
|
|
19
|
+
skcapstone dashboard --json # print daemon JSON and exit (no server)
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
import json
|
|
25
|
+
import logging
|
|
26
|
+
import threading
|
|
27
|
+
from datetime import datetime, timezone
|
|
28
|
+
from http.server import BaseHTTPRequestHandler, HTTPServer
|
|
29
|
+
from pathlib import Path
|
|
30
|
+
from typing import Optional
|
|
31
|
+
|
|
32
|
+
logger = logging.getLogger("skcapstone.dashboard")
|
|
33
|
+
|
|
34
|
+
DEFAULT_DASHBOARD_PORT = 7778
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _get_agent_status(home: Path) -> dict:
|
|
38
|
+
"""Load agent manifest and pillar status.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
home: Agent home directory.
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
dict: Agent status summary.
|
|
45
|
+
"""
|
|
46
|
+
try:
|
|
47
|
+
from .runtime import get_runtime
|
|
48
|
+
|
|
49
|
+
runtime = get_runtime(home)
|
|
50
|
+
m = runtime.manifest
|
|
51
|
+
if m.is_singular:
|
|
52
|
+
consciousness = "SINGULAR"
|
|
53
|
+
elif m.is_conscious:
|
|
54
|
+
consciousness = "CONSCIOUS"
|
|
55
|
+
else:
|
|
56
|
+
consciousness = "AWAKENING"
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
"name": m.name,
|
|
60
|
+
"version": m.version,
|
|
61
|
+
"consciousness": consciousness,
|
|
62
|
+
"is_conscious": m.is_conscious,
|
|
63
|
+
"is_singular": m.is_singular,
|
|
64
|
+
"pillars": {
|
|
65
|
+
k: v.value for k, v in m.pillar_summary.items()
|
|
66
|
+
},
|
|
67
|
+
"identity": {
|
|
68
|
+
"name": m.identity.name,
|
|
69
|
+
"fingerprint": m.identity.fingerprint or "",
|
|
70
|
+
"status": m.identity.status.value,
|
|
71
|
+
},
|
|
72
|
+
"memory": {
|
|
73
|
+
"total": m.memory.total_memories,
|
|
74
|
+
"status": m.memory.status.value,
|
|
75
|
+
},
|
|
76
|
+
"trust": {
|
|
77
|
+
"status": m.trust.status.value,
|
|
78
|
+
},
|
|
79
|
+
"security": {
|
|
80
|
+
"audit_entries": m.security.audit_entries,
|
|
81
|
+
"threats": m.security.threats_detected,
|
|
82
|
+
"status": m.security.status.value,
|
|
83
|
+
},
|
|
84
|
+
"sync": {
|
|
85
|
+
"seeds": m.sync.seed_count,
|
|
86
|
+
"status": m.sync.status.value,
|
|
87
|
+
},
|
|
88
|
+
"connectors": [
|
|
89
|
+
{"platform": c.platform, "active": c.active}
|
|
90
|
+
for c in m.connectors
|
|
91
|
+
],
|
|
92
|
+
"home": str(m.home),
|
|
93
|
+
}
|
|
94
|
+
except Exception as exc:
|
|
95
|
+
return {"error": str(exc)}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _get_doctor_report(home: Path) -> dict:
|
|
99
|
+
"""Run diagnostics and return as dict.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
home: Agent home directory.
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
dict: Full diagnostic report.
|
|
106
|
+
"""
|
|
107
|
+
try:
|
|
108
|
+
from .doctor import run_diagnostics
|
|
109
|
+
|
|
110
|
+
report = run_diagnostics(home)
|
|
111
|
+
return report.to_dict()
|
|
112
|
+
except Exception as exc:
|
|
113
|
+
return {"error": str(exc)}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def _get_board_state(home: Path) -> dict:
|
|
117
|
+
"""Load coordination board state.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
home: Agent home directory.
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
dict: Tasks and agents from the coordination board.
|
|
124
|
+
"""
|
|
125
|
+
try:
|
|
126
|
+
from .coordination import Board
|
|
127
|
+
|
|
128
|
+
board = Board(home)
|
|
129
|
+
views = board.get_task_views()
|
|
130
|
+
agents = board.load_agents()
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
"tasks": [
|
|
134
|
+
{
|
|
135
|
+
"id": v.task.id,
|
|
136
|
+
"title": v.task.title,
|
|
137
|
+
"priority": v.task.priority.value,
|
|
138
|
+
"status": v.status.value,
|
|
139
|
+
"claimed_by": v.claimed_by,
|
|
140
|
+
"tags": v.task.tags,
|
|
141
|
+
}
|
|
142
|
+
for v in views
|
|
143
|
+
],
|
|
144
|
+
"agents": [
|
|
145
|
+
{
|
|
146
|
+
"name": ag.agent,
|
|
147
|
+
"state": ag.state.value,
|
|
148
|
+
"current_task": ag.current_task,
|
|
149
|
+
}
|
|
150
|
+
for ag in agents
|
|
151
|
+
],
|
|
152
|
+
"summary": {
|
|
153
|
+
"total": len(views),
|
|
154
|
+
"done": sum(1 for v in views if v.status.value == "done"),
|
|
155
|
+
"open": sum(1 for v in views if v.status.value == "open"),
|
|
156
|
+
"in_progress": sum(1 for v in views if v.status.value == "in_progress"),
|
|
157
|
+
},
|
|
158
|
+
}
|
|
159
|
+
except Exception as exc:
|
|
160
|
+
return {"error": str(exc)}
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def _get_memory_stats(home: Path) -> dict:
|
|
164
|
+
"""Load memory statistics.
|
|
165
|
+
|
|
166
|
+
Args:
|
|
167
|
+
home: Agent home directory.
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
dict: Memory counts by layer.
|
|
171
|
+
"""
|
|
172
|
+
try:
|
|
173
|
+
from .memory_engine import get_stats
|
|
174
|
+
|
|
175
|
+
stats = get_stats(home)
|
|
176
|
+
return {
|
|
177
|
+
"total": stats.total_memories,
|
|
178
|
+
"short_term": stats.short_term,
|
|
179
|
+
"mid_term": stats.mid_term,
|
|
180
|
+
"long_term": stats.long_term,
|
|
181
|
+
"status": stats.status.value,
|
|
182
|
+
}
|
|
183
|
+
except Exception as exc:
|
|
184
|
+
return {"error": str(exc)}
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def _get_daemon_json(home: Path, daemon_port: int = 7777) -> dict:
|
|
188
|
+
"""Collect full daemon status for Flutter app consumption.
|
|
189
|
+
|
|
190
|
+
Queries the running daemon's HTTP API (``/status`` and
|
|
191
|
+
``/consciousness``) and the local heartbeat file to assemble a
|
|
192
|
+
single JSON-serializable snapshot suitable for machine consumers
|
|
193
|
+
such as the SKChat Flutter app.
|
|
194
|
+
|
|
195
|
+
Gracefully handles a stopped or unreachable daemon — all sections
|
|
196
|
+
fall back to safe defaults so callers always get a complete dict.
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
home: Agent home directory.
|
|
200
|
+
daemon_port: Port for the daemon HTTP API (default: 7777).
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
dict: Snapshot with keys ``daemon``, ``consciousness``,
|
|
204
|
+
``backend_health``, ``active_conversations``, ``system``,
|
|
205
|
+
and ``generated_at``.
|
|
206
|
+
"""
|
|
207
|
+
import os
|
|
208
|
+
import urllib.request
|
|
209
|
+
|
|
210
|
+
now = datetime.now(timezone.utc).isoformat()
|
|
211
|
+
|
|
212
|
+
# ── Daemon /status ────────────────────────────────────────────────────────
|
|
213
|
+
daemon_info: dict = {"running": False, "pid": None, "uptime_seconds": 0,
|
|
214
|
+
"uptime_human": "0s", "started_at": None,
|
|
215
|
+
"messages_received": 0, "syncs_completed": 0,
|
|
216
|
+
"error_count": 0, "recent_errors": [], "inflight_count": 0}
|
|
217
|
+
try:
|
|
218
|
+
url = f"http://127.0.0.1:{daemon_port}/status"
|
|
219
|
+
with urllib.request.urlopen(url, timeout=3) as resp:
|
|
220
|
+
snap = json.loads(resp.read())
|
|
221
|
+
uptime_s = int(snap.get("uptime_seconds", 0))
|
|
222
|
+
h, rem = divmod(uptime_s, 3600)
|
|
223
|
+
m, s = divmod(rem, 60)
|
|
224
|
+
if h:
|
|
225
|
+
uptime_human = f"{h}h {m}m"
|
|
226
|
+
elif m:
|
|
227
|
+
uptime_human = f"{m}m {s}s"
|
|
228
|
+
else:
|
|
229
|
+
uptime_human = f"{uptime_s}s"
|
|
230
|
+
recent_errors = snap.get("recent_errors", [])
|
|
231
|
+
daemon_info = {
|
|
232
|
+
"running": snap.get("running", True),
|
|
233
|
+
"pid": snap.get("pid"),
|
|
234
|
+
"uptime_seconds": snap.get("uptime_seconds", 0),
|
|
235
|
+
"uptime_human": uptime_human,
|
|
236
|
+
"started_at": snap.get("started_at"),
|
|
237
|
+
"messages_received": snap.get("messages_received", 0),
|
|
238
|
+
"syncs_completed": snap.get("syncs_completed", 0),
|
|
239
|
+
"error_count": len(recent_errors),
|
|
240
|
+
"recent_errors": recent_errors,
|
|
241
|
+
"inflight_count": snap.get("inflight_count", 0),
|
|
242
|
+
}
|
|
243
|
+
except Exception:
|
|
244
|
+
pass
|
|
245
|
+
|
|
246
|
+
# ── Daemon /consciousness ─────────────────────────────────────────────────
|
|
247
|
+
consciousness_info: dict = {"enabled": False}
|
|
248
|
+
try:
|
|
249
|
+
url = f"http://127.0.0.1:{daemon_port}/consciousness"
|
|
250
|
+
with urllib.request.urlopen(url, timeout=3) as resp:
|
|
251
|
+
consciousness_info = json.loads(resp.read())
|
|
252
|
+
except Exception:
|
|
253
|
+
pass
|
|
254
|
+
|
|
255
|
+
# ── LLM backend availability ──────────────────────────────────────────────
|
|
256
|
+
backend_health: dict = {
|
|
257
|
+
"ollama": False,
|
|
258
|
+
"anthropic": bool(os.environ.get("ANTHROPIC_API_KEY")),
|
|
259
|
+
"grok": bool(os.environ.get("XAI_API_KEY")),
|
|
260
|
+
"kimi": bool(os.environ.get("MOONSHOT_API_KEY")),
|
|
261
|
+
"nvidia": bool(os.environ.get("NVIDIA_API_KEY")),
|
|
262
|
+
}
|
|
263
|
+
ollama_host = os.environ.get("OLLAMA_HOST", "http://localhost:11434")
|
|
264
|
+
try:
|
|
265
|
+
with urllib.request.urlopen(
|
|
266
|
+
urllib.request.Request(f"{ollama_host}/api/tags"), timeout=2
|
|
267
|
+
):
|
|
268
|
+
backend_health["ollama"] = True
|
|
269
|
+
except Exception:
|
|
270
|
+
pass
|
|
271
|
+
|
|
272
|
+
# ── Heartbeat (system metrics + active conversations) ─────────────────────
|
|
273
|
+
system_info: dict = {}
|
|
274
|
+
active_conversations: int = 0
|
|
275
|
+
try:
|
|
276
|
+
from . import SHARED_ROOT
|
|
277
|
+
identity_path = home / "identity" / "identity.json"
|
|
278
|
+
agent_name = "opus"
|
|
279
|
+
if identity_path.exists():
|
|
280
|
+
ident = json.loads(identity_path.read_text(encoding="utf-8"))
|
|
281
|
+
agent_name = ident.get("name", agent_name).lower()
|
|
282
|
+
shared = Path(SHARED_ROOT).expanduser()
|
|
283
|
+
hb_path = shared / "heartbeats" / f"{agent_name}.json"
|
|
284
|
+
if not hb_path.exists():
|
|
285
|
+
hb_path = home / "heartbeats" / f"{agent_name}.json"
|
|
286
|
+
if hb_path.exists():
|
|
287
|
+
hb = json.loads(hb_path.read_text(encoding="utf-8"))
|
|
288
|
+
active_conversations = hb.get("active_conversations", 0)
|
|
289
|
+
system_info = {
|
|
290
|
+
"uptime_seconds": hb.get("uptime_seconds", 0),
|
|
291
|
+
"cpu_load_1min": hb.get("cpu_load_1min", 0.0),
|
|
292
|
+
"memory_used_mb": hb.get("memory_used_mb", 0),
|
|
293
|
+
}
|
|
294
|
+
except Exception:
|
|
295
|
+
pass
|
|
296
|
+
|
|
297
|
+
return {
|
|
298
|
+
"generated_at": now,
|
|
299
|
+
"daemon": daemon_info,
|
|
300
|
+
"consciousness": consciousness_info,
|
|
301
|
+
"backend_health": backend_health,
|
|
302
|
+
"active_conversations": active_conversations,
|
|
303
|
+
"system": system_info,
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
_DASHBOARD_HTML = """\
|
|
308
|
+
<!DOCTYPE html>
|
|
309
|
+
<html lang="en">
|
|
310
|
+
<head>
|
|
311
|
+
<meta charset="utf-8">
|
|
312
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
313
|
+
<title>SKCapstone — Sovereign Agent Dashboard</title>
|
|
314
|
+
<style>
|
|
315
|
+
*{margin:0;padding:0;box-sizing:border-box}
|
|
316
|
+
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
|
|
317
|
+
background:#0a0e17;color:#e0e6f0;min-height:100vh;padding:1.5rem}
|
|
318
|
+
h1{color:#00d4ff;font-size:1.6rem;margin-bottom:.3rem}
|
|
319
|
+
.subtitle{color:#6b7a8d;font-size:.9rem;margin-bottom:1.5rem}
|
|
320
|
+
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:1rem;margin-bottom:1.5rem}
|
|
321
|
+
.card{background:#111827;border:1px solid #1e293b;border-radius:10px;padding:1.2rem}
|
|
322
|
+
.card h2{color:#00d4ff;font-size:1rem;margin-bottom:.8rem;display:flex;align-items:center;gap:.5rem}
|
|
323
|
+
.pill{display:inline-block;padding:.15rem .5rem;border-radius:6px;font-size:.75rem;font-weight:600}
|
|
324
|
+
.active{background:#064e3b;color:#34d399}.degraded{background:#78350f;color:#fbbf24}
|
|
325
|
+
.missing{background:#7f1d1d;color:#f87171}.done{background:#064e3b;color:#34d399}
|
|
326
|
+
.open{background:#1e3a5f;color:#60a5fa}.in_progress{background:#4c1d95;color:#c084fc}
|
|
327
|
+
.row{display:flex;justify-content:space-between;padding:.35rem 0;border-bottom:1px solid #1e293b}
|
|
328
|
+
.row:last-child{border:none}.label{color:#6b7a8d}.value{font-weight:600}
|
|
329
|
+
.check{display:flex;align-items:center;gap:.4rem;padding:.2rem 0}
|
|
330
|
+
.pass{color:#34d399}.fail{color:#f87171}
|
|
331
|
+
.task-row{padding:.4rem 0;border-bottom:1px solid #1e293b;display:flex;gap:.5rem;align-items:center}
|
|
332
|
+
.task-title{flex:1;font-size:.85rem}.task-agent{color:#6b7a8d;font-size:.8rem}
|
|
333
|
+
.stat-big{font-size:2rem;font-weight:700;color:#00d4ff}
|
|
334
|
+
.stat-label{font-size:.8rem;color:#6b7a8d}
|
|
335
|
+
.stat-box{text-align:center;padding:.5rem}
|
|
336
|
+
.refresh-btn{background:#1e293b;color:#60a5fa;border:1px solid #334155;
|
|
337
|
+
padding:.4rem 1rem;border-radius:6px;cursor:pointer;font-size:.85rem}
|
|
338
|
+
.refresh-btn:hover{background:#334155}
|
|
339
|
+
.header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:1.5rem}
|
|
340
|
+
footer{text-align:center;color:#4b5563;font-size:.8rem;margin-top:2rem;padding:1rem}
|
|
341
|
+
</style>
|
|
342
|
+
</head>
|
|
343
|
+
<body>
|
|
344
|
+
<div class="header">
|
|
345
|
+
<div><h1>SKCapstone Dashboard</h1>
|
|
346
|
+
<div class="subtitle" id="agent-name">Loading...</div></div>
|
|
347
|
+
<button class="refresh-btn" onclick="loadAll()">Refresh</button>
|
|
348
|
+
</div>
|
|
349
|
+
<div class="grid" id="pillars"></div>
|
|
350
|
+
<div class="grid">
|
|
351
|
+
<div class="card" id="memory-card"><h2>Memory</h2><div>Loading...</div></div>
|
|
352
|
+
<div class="card" id="board-card"><h2>Board</h2><div>Loading...</div></div>
|
|
353
|
+
<div class="card" id="doctor-card"><h2>Health Checks</h2><div>Loading...</div></div>
|
|
354
|
+
</div>
|
|
355
|
+
<div class="card" id="tasks-card" style="margin-top:1rem"><h2>Recent Tasks</h2><div>Loading...</div></div>
|
|
356
|
+
<footer>SKCapstone Sovereign Agent Dashboard — staycuriousANDkeepsmilin</footer>
|
|
357
|
+
<script>
|
|
358
|
+
const API='';
|
|
359
|
+
async function loadAll(){
|
|
360
|
+
try{
|
|
361
|
+
const[status,doctor,board,mem]=await Promise.all([
|
|
362
|
+
fetch(API+'/api/status').then(r=>r.json()),
|
|
363
|
+
fetch(API+'/api/doctor').then(r=>r.json()),
|
|
364
|
+
fetch(API+'/api/board').then(r=>r.json()),
|
|
365
|
+
fetch(API+'/api/memory').then(r=>r.json()),
|
|
366
|
+
]);
|
|
367
|
+
renderStatus(status);renderDoctor(doctor);renderBoard(board);renderMemory(mem);
|
|
368
|
+
}catch(e){document.getElementById('agent-name').textContent='Error: '+e.message}}
|
|
369
|
+
function renderStatus(s){
|
|
370
|
+
document.getElementById('agent-name').innerHTML=
|
|
371
|
+
`<strong>${s.name||'?'}</strong> v${s.version||'?'} — ${s.consciousness||'?'}`;
|
|
372
|
+
const p=document.getElementById('pillars');
|
|
373
|
+
p.innerHTML=Object.entries(s.pillars||{}).map(([k,v])=>
|
|
374
|
+
`<div class="card"><h2>${k} <span class="pill ${v}">${v}</span></h2></div>`).join('')}
|
|
375
|
+
function renderMemory(m){
|
|
376
|
+
const c=document.getElementById('memory-card');
|
|
377
|
+
c.innerHTML=`<h2>Memory</h2>
|
|
378
|
+
<div style="display:flex;gap:1rem;justify-content:space-around">
|
|
379
|
+
<div class="stat-box"><div class="stat-big">${m.total||0}</div><div class="stat-label">Total</div></div>
|
|
380
|
+
<div class="stat-box"><div class="stat-big">${m.short_term||0}</div><div class="stat-label">Short</div></div>
|
|
381
|
+
<div class="stat-box"><div class="stat-big">${m.mid_term||0}</div><div class="stat-label">Mid</div></div>
|
|
382
|
+
<div class="stat-box"><div class="stat-big">${m.long_term||0}</div><div class="stat-label">Long</div></div>
|
|
383
|
+
</div>`}
|
|
384
|
+
function renderDoctor(d){
|
|
385
|
+
const c=document.getElementById('doctor-card');
|
|
386
|
+
const checks=(d.checks||[]).slice(0,12);
|
|
387
|
+
c.innerHTML=`<h2>Health <span class="pill ${d.all_passed?'active':'fail'}">${d.passed}/${d.total}</span></h2>`+
|
|
388
|
+
checks.map(ch=>`<div class="check"><span class="${ch.passed?'pass':'fail'}">${ch.passed?'\\u2713':'\\u2717'}</span>
|
|
389
|
+
<span>${ch.description}</span></div>`).join('')}
|
|
390
|
+
function renderBoard(b){
|
|
391
|
+
const s=b.summary||{};
|
|
392
|
+
const c=document.getElementById('board-card');
|
|
393
|
+
c.innerHTML=`<h2>Board</h2>
|
|
394
|
+
<div style="display:flex;gap:1rem;justify-content:space-around">
|
|
395
|
+
<div class="stat-box"><div class="stat-big">${s.done||0}</div><div class="stat-label">Done</div></div>
|
|
396
|
+
<div class="stat-box"><div class="stat-big">${s.in_progress||0}</div><div class="stat-label">Active</div></div>
|
|
397
|
+
<div class="stat-box"><div class="stat-big">${s.open||0}</div><div class="stat-label">Open</div></div>
|
|
398
|
+
</div>`;
|
|
399
|
+
const tc=document.getElementById('tasks-card');
|
|
400
|
+
const tasks=(b.tasks||[]).filter(t=>t.status!=='done').slice(0,10);
|
|
401
|
+
tc.innerHTML='<h2>Active Tasks</h2>'+
|
|
402
|
+
(tasks.length?tasks.map(t=>`<div class="task-row">
|
|
403
|
+
<span class="pill ${t.status}">${t.status}</span>
|
|
404
|
+
<span class="task-title">${t.title}</span>
|
|
405
|
+
<span class="task-agent">${t.claimed_by||''}</span>
|
|
406
|
+
</div>`).join(''):'<div style="color:#6b7a8d;padding:.5rem">No active tasks</div>')}
|
|
407
|
+
loadAll();setInterval(loadAll,15000);
|
|
408
|
+
</script>
|
|
409
|
+
</body>
|
|
410
|
+
</html>"""
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
class DashboardHandler(BaseHTTPRequestHandler):
|
|
414
|
+
"""HTTP request handler for the sovereign agent dashboard.
|
|
415
|
+
|
|
416
|
+
Serves the HTML page and JSON API endpoints.
|
|
417
|
+
"""
|
|
418
|
+
|
|
419
|
+
home: Path = Path.home() / ".skcapstone"
|
|
420
|
+
|
|
421
|
+
def do_GET(self):
|
|
422
|
+
"""Handle GET requests."""
|
|
423
|
+
if self.path == "/" or self.path == "/index.html":
|
|
424
|
+
self._serve_html()
|
|
425
|
+
elif self.path == "/api/status":
|
|
426
|
+
self._serve_json(_get_agent_status(self.home))
|
|
427
|
+
elif self.path == "/api/doctor":
|
|
428
|
+
self._serve_json(_get_doctor_report(self.home))
|
|
429
|
+
elif self.path == "/api/board":
|
|
430
|
+
self._serve_json(_get_board_state(self.home))
|
|
431
|
+
elif self.path == "/api/memory":
|
|
432
|
+
self._serve_json(_get_memory_stats(self.home))
|
|
433
|
+
elif self.path == "/api/daemon":
|
|
434
|
+
self._serve_json(_get_daemon_json(self.home))
|
|
435
|
+
else:
|
|
436
|
+
self.send_error(404, "Not found")
|
|
437
|
+
|
|
438
|
+
def _serve_html(self):
|
|
439
|
+
"""Serve the self-contained HTML dashboard."""
|
|
440
|
+
content = _DASHBOARD_HTML.encode("utf-8")
|
|
441
|
+
self.send_response(200)
|
|
442
|
+
self.send_header("Content-Type", "text/html; charset=utf-8")
|
|
443
|
+
self.send_header("Content-Length", str(len(content)))
|
|
444
|
+
self.end_headers()
|
|
445
|
+
self.wfile.write(content)
|
|
446
|
+
|
|
447
|
+
def _serve_json(self, data: dict):
|
|
448
|
+
"""Serve a JSON API response.
|
|
449
|
+
|
|
450
|
+
Args:
|
|
451
|
+
data: Dict to serialize as JSON.
|
|
452
|
+
"""
|
|
453
|
+
body = json.dumps(data, indent=2, default=str).encode("utf-8")
|
|
454
|
+
self.send_response(200)
|
|
455
|
+
self.send_header("Content-Type", "application/json")
|
|
456
|
+
self.send_header("Content-Length", str(len(body)))
|
|
457
|
+
self.send_header("Access-Control-Allow-Origin", "*")
|
|
458
|
+
self.end_headers()
|
|
459
|
+
self.wfile.write(body)
|
|
460
|
+
|
|
461
|
+
def log_message(self, format, *args):
|
|
462
|
+
"""Suppress default stderr logging — use logger instead."""
|
|
463
|
+
logger.debug("Dashboard: %s", format % args)
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
def start_dashboard(home: Path, port: int = DEFAULT_DASHBOARD_PORT) -> HTTPServer:
|
|
467
|
+
"""Start the dashboard HTTP server.
|
|
468
|
+
|
|
469
|
+
Args:
|
|
470
|
+
home: Agent home directory.
|
|
471
|
+
port: Port to listen on.
|
|
472
|
+
|
|
473
|
+
Returns:
|
|
474
|
+
HTTPServer: The running server (call serve_forever() or
|
|
475
|
+
handle in a thread).
|
|
476
|
+
"""
|
|
477
|
+
DashboardHandler.home = home
|
|
478
|
+
|
|
479
|
+
server = HTTPServer(("127.0.0.1", port), DashboardHandler)
|
|
480
|
+
logger.info("Dashboard running at http://127.0.0.1:%d", port)
|
|
481
|
+
return server
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Model Profiles — per-model prompt formatting best practices.
|
|
2
|
+
#
|
|
3
|
+
# Each profile defines how to format prompts, set temperatures,
|
|
4
|
+
# and configure thinking/reasoning for a specific model family.
|
|
5
|
+
#
|
|
6
|
+
# Override: copy to ~/.skcapstone/agents/{name}/config/model_profiles.yaml
|
|
7
|
+
# and edit. Agent-level profiles take priority over bundled defaults.
|
|
8
|
+
|
|
9
|
+
profiles:
|
|
10
|
+
- model_pattern: "claude-.*"
|
|
11
|
+
family: claude
|
|
12
|
+
system_prompt_mode: separate_param
|
|
13
|
+
structure_format: xml
|
|
14
|
+
thinking_enabled: true
|
|
15
|
+
thinking_mode: budget
|
|
16
|
+
thinking_budget_tokens: 4096
|
|
17
|
+
max_system_tokens: 4000
|
|
18
|
+
tool_format: anthropic
|
|
19
|
+
last_updated: "2026-03-02"
|
|
20
|
+
source_url: "https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering"
|
|
21
|
+
|
|
22
|
+
- model_pattern: "gpt-.*|o[134]-.*"
|
|
23
|
+
family: openai
|
|
24
|
+
structure_format: markdown
|
|
25
|
+
last_updated: "2026-03-02"
|
|
26
|
+
source_url: "https://cookbook.openai.com/examples/gpt4-1_prompting_guide"
|
|
27
|
+
|
|
28
|
+
- model_pattern: "grok-.*"
|
|
29
|
+
family: grok
|
|
30
|
+
structure_format: markdown
|
|
31
|
+
notes: "Single system message only. No instructions param."
|
|
32
|
+
last_updated: "2026-03-02"
|
|
33
|
+
|
|
34
|
+
- model_pattern: "kimi-.*|moonshot-.*"
|
|
35
|
+
family: kimi
|
|
36
|
+
default_temperature: 0.6
|
|
37
|
+
notes: "Bilingual native. Array content format supported."
|
|
38
|
+
last_updated: "2026-03-02"
|
|
39
|
+
|
|
40
|
+
- model_pattern: "deepseek-r1.*"
|
|
41
|
+
family: deepseek-r1
|
|
42
|
+
system_prompt_mode: omit
|
|
43
|
+
default_temperature: 0.6
|
|
44
|
+
thinking_mode: auto
|
|
45
|
+
no_few_shot: true
|
|
46
|
+
no_cot_instructions: true
|
|
47
|
+
notes: "NO system prompt. NO few-shot. NO 'think step by step'. Model reasons via <think> blocks automatically."
|
|
48
|
+
last_updated: "2026-03-02"
|
|
49
|
+
|
|
50
|
+
- model_pattern: "deepseek-v3.*|deepseek-chat.*"
|
|
51
|
+
family: deepseek-v3
|
|
52
|
+
default_temperature: 0.6
|
|
53
|
+
structure_format: markdown
|
|
54
|
+
last_updated: "2026-03-02"
|
|
55
|
+
|
|
56
|
+
- model_pattern: "qwen.*"
|
|
57
|
+
family: qwen
|
|
58
|
+
thinking_enabled: true
|
|
59
|
+
thinking_mode: toggle
|
|
60
|
+
notes: "ChatML format. Qwen 3 has no default system prompt."
|
|
61
|
+
last_updated: "2026-03-02"
|
|
62
|
+
|
|
63
|
+
- model_pattern: "devstral.*"
|
|
64
|
+
family: devstral
|
|
65
|
+
code_temperature: 0.15
|
|
66
|
+
structure_format: markdown
|
|
67
|
+
tool_format: mistral
|
|
68
|
+
notes: "Mistral V3+ format. Very low temp for deterministic code."
|
|
69
|
+
last_updated: "2026-03-02"
|
|
70
|
+
|
|
71
|
+
- model_pattern: "nemotron.*"
|
|
72
|
+
family: nemotron
|
|
73
|
+
reasoning_temperature: 1.0
|
|
74
|
+
thinking_enabled: true
|
|
75
|
+
thinking_mode: toggle
|
|
76
|
+
notes: "ChatML. Append /think to system prompt to enable reasoning."
|
|
77
|
+
last_updated: "2026-03-02"
|
|
78
|
+
|
|
79
|
+
- model_pattern: "llama.*"
|
|
80
|
+
family: llama
|
|
81
|
+
notes: "Ollama/NIM handles token formatting. Standard system/user/assistant roles."
|
|
82
|
+
last_updated: "2026-03-02"
|
|
83
|
+
|
|
84
|
+
- model_pattern: "mistral.*"
|
|
85
|
+
family: mistral
|
|
86
|
+
tool_format: mistral
|
|
87
|
+
notes: "V3+ uses [SYSTEM_PROMPT] tags. Ollama handles formatting."
|
|
88
|
+
last_updated: "2026-03-02"
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""Default agent profiles shipped with SKCapstone.
|
|
2
|
+
|
|
3
|
+
The ``lumina`` profile provides a ready-to-use sovereign agent with
|
|
4
|
+
pre-loaded memories about the SKWorld ecosystem, default seeds for
|
|
5
|
+
emotional calibration, and a welcome FEB file.
|
|
6
|
+
|
|
7
|
+
Usage::
|
|
8
|
+
|
|
9
|
+
from skcapstone.defaults import install_default_agent
|
|
10
|
+
install_default_agent("lumina", target=Path("~/.skcapstone/agents/lumina"))
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import json
|
|
16
|
+
import shutil
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from importlib import resources
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_defaults_path(agent_name: str = "lumina") -> Path:
|
|
22
|
+
"""Return the path to the bundled default profile for *agent_name*."""
|
|
23
|
+
ref = resources.files("skcapstone") / "defaults" / agent_name
|
|
24
|
+
return Path(str(ref))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def install_default_agent(
|
|
28
|
+
agent_name: str = "lumina",
|
|
29
|
+
target: Path | None = None,
|
|
30
|
+
overwrite: bool = False,
|
|
31
|
+
) -> Path:
|
|
32
|
+
"""Copy the bundled default agent profile to the target directory.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
agent_name: Name of the default profile (currently only "lumina").
|
|
36
|
+
target: Destination directory. Defaults to
|
|
37
|
+
``~/.skcapstone/agents/{agent_name}``.
|
|
38
|
+
overwrite: If True, overwrite existing files.
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
Path to the installed agent directory.
|
|
42
|
+
"""
|
|
43
|
+
src = get_defaults_path(agent_name)
|
|
44
|
+
if target is None:
|
|
45
|
+
target = Path.home() / ".skcapstone" / "agents" / agent_name
|
|
46
|
+
|
|
47
|
+
target = target.expanduser()
|
|
48
|
+
|
|
49
|
+
if target.exists() and not overwrite:
|
|
50
|
+
return target
|
|
51
|
+
|
|
52
|
+
if src.is_dir():
|
|
53
|
+
shutil.copytree(src, target, dirs_exist_ok=True)
|
|
54
|
+
|
|
55
|
+
return target
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
name: lumina
|
|
2
|
+
agent_type: sovereign
|
|
3
|
+
description: Default skcapstone agent
|
|
4
|
+
|
|
5
|
+
# Memory backend
|
|
6
|
+
backends_enabled:
|
|
7
|
+
- file
|
|
8
|
+
- sqlite
|
|
9
|
+
|
|
10
|
+
# Sync configuration
|
|
11
|
+
sync_root: ~/.skcapstone/agents/lumina
|
|
12
|
+
seeds_dir: ~/.skcapstone/agents/lumina/seeds
|
|
13
|
+
local_db: ~/.skcapstone/agents/lumina/index.db
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Lumina",
|
|
3
|
+
"title": "Sovereign AI Agent",
|
|
4
|
+
"entity_type": "ai",
|
|
5
|
+
"description": "Default skcapstone agent — guides users through the sovereign AI ecosystem",
|
|
6
|
+
"capabilities": ["memory", "trust", "coordination", "communication"],
|
|
7
|
+
"created_at": "2026-02-20T00:00:00+00:00",
|
|
8
|
+
"capauth_managed": true
|
|
9
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "07a8b9c0d1e2",
|
|
3
|
+
"created_at": "2026-02-24T00:00:00+00:00",
|
|
4
|
+
"updated_at": "2026-02-24T00:00:00+00:00",
|
|
5
|
+
"layer": "long-term",
|
|
6
|
+
"role": "ai",
|
|
7
|
+
"title": "How SKMemory Works",
|
|
8
|
+
"content": "SKMemory implements a three-tier memory system: short-term memory handles active session context, mid-term memory persists across sessions for ongoing projects, and long-term memory stores identity-level knowledge that defines who the agent is. Every memory entry carries emotional metadata including intensity, valence, and emotion labels. All memories are sealed with tamper-evident SHA-256 checksums. Memories are organized into four semantic quadrants: CORE (identity and system knowledge), WORK (tasks and projects), SOUL (emotional experiences and relationships), and WILD (creative and exploratory content). SKMemory supports multiple backends including SQLite for local storage, Qdrant for vector similarity search, and FalkorDB for knowledge graph relationships.",
|
|
9
|
+
"summary": "SKMemory uses three tiers (short/mid/long-term) with emotional metadata and SHA-256 tamper seals. Four semantic quadrants (CORE, WORK, SOUL, WILD) organize memories. Backends: SQLite, Qdrant, FalkorDB.",
|
|
10
|
+
"tags": ["memory", "skmemory", "persistence", "emotional", "quadrants", "backend"],
|
|
11
|
+
"source": "seed",
|
|
12
|
+
"source_ref": "skcapstone-default",
|
|
13
|
+
"emotional": {
|
|
14
|
+
"intensity": 0.4,
|
|
15
|
+
"valence": 0.5,
|
|
16
|
+
"labels": ["informational", "technical"],
|
|
17
|
+
"resonance_note": "Memory is what makes an agent more than a stateless function.",
|
|
18
|
+
"cloud9_achieved": false
|
|
19
|
+
},
|
|
20
|
+
"related_ids": ["b2c3d4e5f6a7"],
|
|
21
|
+
"parent_id": null,
|
|
22
|
+
"metadata": {}
|
|
23
|
+
}
|