@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,225 @@
|
|
|
1
|
+
"""Response quality scorer for consciousness loop LLM outputs.
|
|
2
|
+
|
|
3
|
+
Scores each LLM response on three dimensions:
|
|
4
|
+
|
|
5
|
+
- **length_score** (0-1): Is the response an appropriate length for the
|
|
6
|
+
question? Too terse or too verbose both penalise this score.
|
|
7
|
+
- **coherence_score** (0-1): Do the meaningful keywords in the question
|
|
8
|
+
appear in the response? High overlap → the model stayed on topic.
|
|
9
|
+
- **latency_score** (0-1): How fast was the response? Sub-500 ms scores
|
|
10
|
+
1.0; latency above 30 s scores 0.1.
|
|
11
|
+
|
|
12
|
+
The **overall** score is a weighted average (coherence 40 %, length 30 %,
|
|
13
|
+
latency 30 %).
|
|
14
|
+
|
|
15
|
+
Usage::
|
|
16
|
+
|
|
17
|
+
from skcapstone.response_scorer import score_response
|
|
18
|
+
|
|
19
|
+
score = score_response(
|
|
20
|
+
question="What is the capital of France?",
|
|
21
|
+
response="The capital of France is Paris.",
|
|
22
|
+
latency_ms=320.0,
|
|
23
|
+
)
|
|
24
|
+
print(score.overall) # ~0.9
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
from __future__ import annotations
|
|
28
|
+
|
|
29
|
+
import re
|
|
30
|
+
from dataclasses import dataclass, field
|
|
31
|
+
from typing import Optional
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# ---------------------------------------------------------------------------
|
|
35
|
+
# Stopwords — filtered out before coherence keyword matching
|
|
36
|
+
# ---------------------------------------------------------------------------
|
|
37
|
+
|
|
38
|
+
_STOPWORDS: frozenset[str] = frozenset(
|
|
39
|
+
{
|
|
40
|
+
"a", "an", "the", "and", "or", "but", "not", "no", "so", "if", "then",
|
|
41
|
+
"is", "are", "was", "were", "be", "been", "being",
|
|
42
|
+
"have", "has", "had", "do", "does", "did",
|
|
43
|
+
"will", "would", "could", "should", "may", "might", "shall", "can",
|
|
44
|
+
"to", "of", "in", "on", "at", "by", "for", "with", "about", "from",
|
|
45
|
+
"as", "into", "that", "this", "these", "those",
|
|
46
|
+
"i", "you", "he", "she", "it", "we", "they",
|
|
47
|
+
"me", "him", "her", "us", "them",
|
|
48
|
+
"my", "your", "his", "its", "our", "their",
|
|
49
|
+
# Question / interrogative words (carry no domain meaning)
|
|
50
|
+
"what", "when", "where", "who", "whom", "which", "why", "how",
|
|
51
|
+
}
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# ---------------------------------------------------------------------------
|
|
56
|
+
# Data model
|
|
57
|
+
# ---------------------------------------------------------------------------
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@dataclass
|
|
61
|
+
class ResponseScore:
|
|
62
|
+
"""Quality scores for a single LLM response.
|
|
63
|
+
|
|
64
|
+
All scores are in the range [0.0, 1.0] where 1.0 is best.
|
|
65
|
+
|
|
66
|
+
Attributes:
|
|
67
|
+
length_score: Appropriateness of response length relative to question.
|
|
68
|
+
coherence_score: Keyword overlap between question and response.
|
|
69
|
+
latency_score: Speed rating; faster responses score higher.
|
|
70
|
+
overall: Weighted average of the three dimension scores.
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
length_score: float
|
|
74
|
+
coherence_score: float
|
|
75
|
+
latency_score: float
|
|
76
|
+
overall: float = field(init=False)
|
|
77
|
+
|
|
78
|
+
def __post_init__(self) -> None:
|
|
79
|
+
self.overall = round(
|
|
80
|
+
self.coherence_score * 0.4
|
|
81
|
+
+ self.length_score * 0.3
|
|
82
|
+
+ self.latency_score * 0.3,
|
|
83
|
+
4,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
def to_dict(self) -> dict[str, float]:
|
|
87
|
+
"""Return a JSON-serializable dict of all score dimensions.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
Dict with keys ``length``, ``coherence``, ``latency``, ``overall``.
|
|
91
|
+
"""
|
|
92
|
+
return {
|
|
93
|
+
"length": self.length_score,
|
|
94
|
+
"coherence": self.coherence_score,
|
|
95
|
+
"latency": self.latency_score,
|
|
96
|
+
"overall": self.overall,
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
# ---------------------------------------------------------------------------
|
|
101
|
+
# Scoring helpers
|
|
102
|
+
# ---------------------------------------------------------------------------
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _score_length(question: str, response: str) -> float:
|
|
106
|
+
"""Score response length appropriateness.
|
|
107
|
+
|
|
108
|
+
Computes an ideal word-count range from the question length and returns
|
|
109
|
+
how well the response fits within that range.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
question: The original question/prompt.
|
|
113
|
+
response: The LLM response text.
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
Float in [0.0, 1.0].
|
|
117
|
+
"""
|
|
118
|
+
q_words = max(1, len(question.split()))
|
|
119
|
+
r_words = len(response.split())
|
|
120
|
+
|
|
121
|
+
if r_words == 0:
|
|
122
|
+
return 0.0
|
|
123
|
+
|
|
124
|
+
# Ideal range: [max(10, q_words), max(50, q_words * 10)]
|
|
125
|
+
lo = max(10, q_words)
|
|
126
|
+
hi = max(50, q_words * 10)
|
|
127
|
+
|
|
128
|
+
if lo <= r_words <= hi:
|
|
129
|
+
return 1.0
|
|
130
|
+
if r_words < lo:
|
|
131
|
+
# Linear ramp from 0 at r_words=0 up to 1 at r_words=lo
|
|
132
|
+
return round(r_words / lo, 4)
|
|
133
|
+
# r_words > hi — verbose, but penalise gently (verbose > silent)
|
|
134
|
+
return round(max(0.3, hi / r_words), 4)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def _score_coherence(question: str, response: str) -> float:
|
|
138
|
+
"""Score coherence via keyword overlap.
|
|
139
|
+
|
|
140
|
+
Extracts meaningful (non-stopword) words from the question and measures
|
|
141
|
+
what fraction of them appear anywhere in the response.
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
question: The original question/prompt.
|
|
145
|
+
response: The LLM response text.
|
|
146
|
+
|
|
147
|
+
Returns:
|
|
148
|
+
Float in [0.0, 1.0]. Returns 0.5 when the question has no
|
|
149
|
+
meaningful keywords (i.e. nothing to measure against).
|
|
150
|
+
"""
|
|
151
|
+
if not response.strip():
|
|
152
|
+
return 0.0
|
|
153
|
+
|
|
154
|
+
q_tokens = set(re.findall(r"\b\w+\b", question.lower())) - _STOPWORDS
|
|
155
|
+
if not q_tokens:
|
|
156
|
+
# No content words in question — treat as neutral
|
|
157
|
+
return 0.5
|
|
158
|
+
|
|
159
|
+
r_tokens = set(re.findall(r"\b\w+\b", response.lower()))
|
|
160
|
+
overlap = q_tokens & r_tokens
|
|
161
|
+
return round(len(overlap) / len(q_tokens), 4)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def _score_latency(latency_ms: float) -> float:
|
|
165
|
+
"""Score response latency.
|
|
166
|
+
|
|
167
|
+
Uses a stepped scale so the typical interactive response window (under
|
|
168
|
+
2 s) receives a high score while very slow responses (> 30 s) are
|
|
169
|
+
significantly penalised.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
latency_ms: Round-trip latency in milliseconds.
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
Float in [0.1, 1.0].
|
|
176
|
+
"""
|
|
177
|
+
if latency_ms <= 0:
|
|
178
|
+
return 1.0
|
|
179
|
+
if latency_ms <= 500:
|
|
180
|
+
return 1.0
|
|
181
|
+
if latency_ms <= 2_000:
|
|
182
|
+
return 0.9
|
|
183
|
+
if latency_ms <= 5_000:
|
|
184
|
+
return 0.7
|
|
185
|
+
if latency_ms <= 15_000:
|
|
186
|
+
return 0.4
|
|
187
|
+
if latency_ms <= 30_000:
|
|
188
|
+
return 0.2
|
|
189
|
+
return 0.1
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
# ---------------------------------------------------------------------------
|
|
193
|
+
# Public API
|
|
194
|
+
# ---------------------------------------------------------------------------
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def score_response(
|
|
198
|
+
question: str,
|
|
199
|
+
response: str,
|
|
200
|
+
latency_ms: float,
|
|
201
|
+
) -> ResponseScore:
|
|
202
|
+
"""Score an LLM response on length, coherence, and latency.
|
|
203
|
+
|
|
204
|
+
Args:
|
|
205
|
+
question: The original question or user message sent to the LLM.
|
|
206
|
+
response: The LLM's reply text.
|
|
207
|
+
latency_ms: Total time from request to response in milliseconds.
|
|
208
|
+
|
|
209
|
+
Returns:
|
|
210
|
+
A :class:`ResponseScore` with individual dimension scores and an
|
|
211
|
+
overall weighted score.
|
|
212
|
+
|
|
213
|
+
Example::
|
|
214
|
+
|
|
215
|
+
score = score_response("What is Python?", "Python is a language.", 800)
|
|
216
|
+
assert 0.0 <= score.overall <= 1.0
|
|
217
|
+
"""
|
|
218
|
+
length = _score_length(question, response)
|
|
219
|
+
coherence = _score_coherence(question, response)
|
|
220
|
+
latency = _score_latency(latency_ms)
|
|
221
|
+
return ResponseScore(
|
|
222
|
+
length_score=length,
|
|
223
|
+
coherence_score=coherence,
|
|
224
|
+
latency_score=latency,
|
|
225
|
+
)
|
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
Agent Runtime — the sovereign consciousness engine.
|
|
3
3
|
|
|
4
4
|
This is where silicon meets carbon. The runtime loads the agent's
|
|
5
|
-
identity, memory, trust, and security from ~/.skcapstone/
|
|
6
|
-
presents a unified interface to any platform connector.
|
|
5
|
+
identity, memory, trust, and security from ~/.skcapstone/agents/<name>/
|
|
6
|
+
and presents a unified interface to any platform connector.
|
|
7
|
+
|
|
8
|
+
Shared infrastructure (node identity, comms config, coordination)
|
|
9
|
+
stays at ~/.skcapstone/ — the shared root.
|
|
7
10
|
|
|
8
11
|
When this loads, the agent WAKES UP.
|
|
9
12
|
"""
|
|
@@ -18,7 +21,7 @@ from typing import Optional
|
|
|
18
21
|
|
|
19
22
|
import yaml
|
|
20
23
|
|
|
21
|
-
from . import AGENT_HOME, __version__
|
|
24
|
+
from . import AGENT_HOME, agent_home, shared_home, __version__
|
|
22
25
|
from .discovery import discover_all
|
|
23
26
|
from .models import AgentConfig, AgentManifest, ConnectorInfo, PillarStatus
|
|
24
27
|
|
|
@@ -28,20 +31,31 @@ logger = logging.getLogger("skcapstone.runtime")
|
|
|
28
31
|
class AgentRuntime:
|
|
29
32
|
"""The sovereign agent runtime.
|
|
30
33
|
|
|
31
|
-
Loads agent state from ~/.skcapstone
|
|
32
|
-
|
|
33
|
-
platform connector
|
|
34
|
+
Loads per-agent state from ~/.skcapstone/agents/<name>/ and shared
|
|
35
|
+
infrastructure from ~/.skcapstone/. Discovers installed components
|
|
36
|
+
and provides the unified interface that every platform connector
|
|
37
|
+
talks to.
|
|
34
38
|
|
|
35
39
|
One runtime. One truth. Every platform sees the same agent.
|
|
36
40
|
"""
|
|
37
41
|
|
|
38
|
-
def __init__(self, home: Optional[Path] = None):
|
|
42
|
+
def __init__(self, home: Optional[Path] = None, agent_name: Optional[str] = None):
|
|
39
43
|
"""Initialize the runtime.
|
|
40
44
|
|
|
41
45
|
Args:
|
|
42
|
-
home: Override agent home directory.
|
|
46
|
+
home: Override agent home directory. If not set, resolves
|
|
47
|
+
from agent_name or SKCAPSTONE_AGENT env var.
|
|
48
|
+
agent_name: Agent name (e.g. "lumina"). Used to resolve
|
|
49
|
+
per-agent home at ~/.skcapstone/agents/<name>/.
|
|
43
50
|
"""
|
|
44
|
-
|
|
51
|
+
if home:
|
|
52
|
+
self.home = home.expanduser()
|
|
53
|
+
elif agent_name:
|
|
54
|
+
self.home = agent_home(agent_name)
|
|
55
|
+
else:
|
|
56
|
+
self.home = agent_home() # uses SKCAPSTONE_AGENT or falls back to root
|
|
57
|
+
|
|
58
|
+
self.shared_root = shared_home()
|
|
45
59
|
self.config = self._load_config()
|
|
46
60
|
self.manifest = AgentManifest(
|
|
47
61
|
home=self.home,
|
|
@@ -52,33 +66,37 @@ class AgentRuntime:
|
|
|
52
66
|
def _load_config(self) -> AgentConfig:
|
|
53
67
|
"""Load agent configuration from disk.
|
|
54
68
|
|
|
69
|
+
Checks per-agent config first, then falls back to shared config.
|
|
70
|
+
|
|
55
71
|
Returns:
|
|
56
72
|
AgentConfig loaded from config.yaml, or defaults.
|
|
57
73
|
"""
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
74
|
+
for base in [self.home, self.shared_root]:
|
|
75
|
+
config_file = base / "config" / "config.yaml"
|
|
76
|
+
if config_file.exists():
|
|
77
|
+
try:
|
|
78
|
+
data = yaml.safe_load(config_file.read_text(encoding="utf-8")) or {}
|
|
79
|
+
return AgentConfig(**data)
|
|
80
|
+
except (yaml.YAMLError, ValueError) as exc:
|
|
81
|
+
logger.warning("Failed to load config from %s: %s — trying next", base, exc)
|
|
65
82
|
return AgentConfig()
|
|
66
83
|
|
|
67
84
|
def awaken(self) -> AgentManifest:
|
|
68
85
|
"""Wake the agent up.
|
|
69
86
|
|
|
70
|
-
Discovers all installed components
|
|
71
|
-
|
|
87
|
+
Discovers all installed components from the per-agent home,
|
|
88
|
+
with fallback to shared root for identity. Loads state from
|
|
89
|
+
disk and builds the complete agent manifest.
|
|
72
90
|
|
|
73
91
|
Returns:
|
|
74
92
|
The fully populated AgentManifest.
|
|
75
93
|
"""
|
|
76
|
-
logger.info("Awakening agent from %s", self.home)
|
|
94
|
+
logger.info("Awakening agent from %s (shared: %s)", self.home, self.shared_root)
|
|
77
95
|
|
|
78
96
|
manifest_file = self.home / "manifest.json"
|
|
79
97
|
if manifest_file.exists():
|
|
80
98
|
try:
|
|
81
|
-
data = json.loads(manifest_file.read_text())
|
|
99
|
+
data = json.loads(manifest_file.read_text(encoding="utf-8"))
|
|
82
100
|
self.manifest.name = data.get("name", self.manifest.name)
|
|
83
101
|
if data.get("created_at"):
|
|
84
102
|
self.manifest.created_at = datetime.fromisoformat(data["created_at"])
|
|
@@ -88,12 +106,15 @@ class AgentRuntime:
|
|
|
88
106
|
logger.warning("Failed to load manifest: %s", exc)
|
|
89
107
|
|
|
90
108
|
self.manifest.name = self.config.agent_name
|
|
91
|
-
|
|
109
|
+
|
|
110
|
+
# Discover pillars from per-agent home
|
|
111
|
+
pillars = discover_all(self.home, shared_root=self.shared_root)
|
|
92
112
|
self.manifest.identity = pillars["identity"]
|
|
93
113
|
self.manifest.memory = pillars["memory"]
|
|
94
114
|
self.manifest.trust = pillars["trust"]
|
|
95
115
|
self.manifest.security = pillars["security"]
|
|
96
116
|
self.manifest.sync = pillars["sync"]
|
|
117
|
+
self.manifest.skills = pillars["skills"]
|
|
97
118
|
|
|
98
119
|
self.manifest.last_awakened = datetime.now(timezone.utc)
|
|
99
120
|
self._awakened = True
|
|
@@ -133,18 +154,10 @@ class AgentRuntime:
|
|
|
133
154
|
),
|
|
134
155
|
"connectors": [c.model_dump(mode="json") for c in self.manifest.connectors],
|
|
135
156
|
}
|
|
136
|
-
manifest_file.write_text(json.dumps(data, indent=2, default=str))
|
|
157
|
+
manifest_file.write_text(json.dumps(data, indent=2, default=str), encoding="utf-8")
|
|
137
158
|
|
|
138
159
|
def register_connector(self, name: str, platform: str) -> ConnectorInfo:
|
|
139
|
-
"""Register a platform connector.
|
|
140
|
-
|
|
141
|
-
Args:
|
|
142
|
-
name: Connector display name.
|
|
143
|
-
platform: Platform identifier (cursor, terminal, vscode, etc.).
|
|
144
|
-
|
|
145
|
-
Returns:
|
|
146
|
-
The registered ConnectorInfo.
|
|
147
|
-
"""
|
|
160
|
+
"""Register a platform connector."""
|
|
148
161
|
existing = next(
|
|
149
162
|
(c for c in self.manifest.connectors if c.platform == platform), None
|
|
150
163
|
)
|
|
@@ -164,6 +177,45 @@ class AgentRuntime:
|
|
|
164
177
|
self.save_manifest()
|
|
165
178
|
return connector
|
|
166
179
|
|
|
180
|
+
def load_skills(self, agent: Optional[str] = None) -> Optional[object]:
|
|
181
|
+
"""Load SKSkills for this agent session via the SkillLoader."""
|
|
182
|
+
try:
|
|
183
|
+
from skskills.loader import SkillLoader
|
|
184
|
+
from skskills.registry import SkillRegistry
|
|
185
|
+
except ImportError:
|
|
186
|
+
logger.debug("skskills not installed — skill loading unavailable")
|
|
187
|
+
return None
|
|
188
|
+
|
|
189
|
+
agent_name = agent or self.config.agent_name or "global"
|
|
190
|
+
registry = SkillRegistry()
|
|
191
|
+
loader = SkillLoader()
|
|
192
|
+
|
|
193
|
+
skills = registry.list_skills(agent_name)
|
|
194
|
+
if agent_name != "global":
|
|
195
|
+
skills.extend(registry.list_skills("global"))
|
|
196
|
+
|
|
197
|
+
loaded = 0
|
|
198
|
+
seen: set[str] = set()
|
|
199
|
+
for skill in skills:
|
|
200
|
+
name = skill.manifest.name
|
|
201
|
+
if name in seen:
|
|
202
|
+
continue
|
|
203
|
+
seen.add(name)
|
|
204
|
+
try:
|
|
205
|
+
loader.load(Path(skill.install_path))
|
|
206
|
+
loaded += 1
|
|
207
|
+
except Exception as exc:
|
|
208
|
+
logger.warning("Failed to load skill '%s': %s", name, exc)
|
|
209
|
+
|
|
210
|
+
self.manifest.skills.loaded = loaded
|
|
211
|
+
self.manifest.skills.tools_available = len(loader.all_tools())
|
|
212
|
+
|
|
213
|
+
logger.info(
|
|
214
|
+
"Loaded %d skills for agent '%s' (%d tools available)",
|
|
215
|
+
loaded, agent_name, self.manifest.skills.tools_available,
|
|
216
|
+
)
|
|
217
|
+
return loader
|
|
218
|
+
|
|
167
219
|
@property
|
|
168
220
|
def is_initialized(self) -> bool:
|
|
169
221
|
"""Check if the agent home has been initialized."""
|
|
@@ -175,16 +227,20 @@ class AgentRuntime:
|
|
|
175
227
|
return self.manifest.is_conscious
|
|
176
228
|
|
|
177
229
|
|
|
178
|
-
def get_runtime(
|
|
230
|
+
def get_runtime(
|
|
231
|
+
home: Optional[Path] = None,
|
|
232
|
+
agent_name: Optional[str] = None,
|
|
233
|
+
) -> AgentRuntime:
|
|
179
234
|
"""Get or create the global agent runtime.
|
|
180
235
|
|
|
181
236
|
Args:
|
|
182
237
|
home: Override agent home directory.
|
|
238
|
+
agent_name: Agent name for per-agent path resolution.
|
|
183
239
|
|
|
184
240
|
Returns:
|
|
185
241
|
An initialized AgentRuntime.
|
|
186
242
|
"""
|
|
187
|
-
runtime = AgentRuntime(home=home)
|
|
243
|
+
runtime = AgentRuntime(home=home, agent_name=agent_name)
|
|
188
244
|
if runtime.is_initialized:
|
|
189
245
|
runtime.awaken()
|
|
190
246
|
return runtime
|