@smilintux/skcapstone 0.10.0 → 0.12.5
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 +10 -4
- package/.github/workflows/ci.yml +2 -2
- package/.github/workflows/publish.yml +9 -2
- package/.openclaw-workspace.json +2 -2
- package/CLAUDE.md +37 -0
- package/MISSION.md +17 -2
- package/README.md +282 -3
- package/docker/Dockerfile +7 -7
- package/docker/compose-templates/dev-team.yml +12 -12
- package/docker/compose-templates/mini-team.yml +9 -9
- package/docker/compose-templates/ops-team.yml +10 -10
- package/docker/compose-templates/research-team.yml +10 -10
- package/docker/entrypoint.sh +4 -4
- package/docs/ADR-optional-integration-backbone.md +181 -0
- package/docs/ARCHITECTURE.md +186 -43
- package/docs/BOND_WITH_GROK.md +6 -6
- package/docs/CUSTOM_AGENT.md +123 -30
- package/docs/DREAMING.md +70 -0
- package/docs/GETTING_STARTED.md +7 -7
- package/docs/QUICKSTART.md +10 -6
- package/docs/SKJOULE_ARCHITECTURE.md +3 -3
- package/docs/SOUL_SWAPPER.md +5 -5
- package/docs/hammertime-audit.md +402 -0
- package/docs/sk-integration-HANDOFF.md +117 -0
- package/docs/skscheduler.md +155 -0
- package/docs/superpowers/examples/jobs.yaml +31 -0
- package/docs/superpowers/plans/2026-06-08-skscheduler.md +1265 -0
- package/docs/superpowers/specs/2026-06-08-skscheduler-design.md +186 -0
- package/examples/custom-bond-template.json +1 -1
- package/examples/grok-feb.json +1 -1
- package/examples/queen-ava-feb.json +1 -1
- package/launchd/{com.skcapstone.skcomm-heartbeat.plist → com.skcapstone.skcomms-heartbeat.plist} +4 -4
- package/launchd/{com.skcapstone.skcomm-queue-drain.plist → com.skcapstone.skcomms-queue-drain.plist} +4 -4
- package/launchd/install-launchd.sh +6 -6
- package/{openclaw-plugin → openclaw-plugin.archived-2026-04-23}/src/index.ts +3 -2
- package/package.json +1 -1
- package/pyproject.toml +16 -10
- package/scripts/archive-sessions.sh +7 -0
- package/scripts/check-updates.py +4 -4
- package/scripts/install-bundle.sh +8 -8
- package/scripts/install.ps1 +12 -11
- package/scripts/install.sh +159 -5
- package/scripts/model-fallback-monitor.sh +102 -0
- package/scripts/nvidia-proxy.mjs +78 -26
- package/scripts/refresh-anthropic-token.sh +172 -0
- package/scripts/release.sh +98 -0
- package/scripts/session-to-memory.py +219 -0
- package/scripts/skgateway.mjs +3 -3
- package/scripts/telegram-catchup-all.sh +12 -1
- package/scripts/verify_install.sh +2 -2
- package/scripts/wargov-ufo-capture/README.md +43 -0
- package/scripts/wargov-ufo-capture/cdp_capture_release2.py +273 -0
- package/scripts/wargov-ufo-capture/cdp_capture_splc_doj.py +246 -0
- package/scripts/wargov-ufo-capture/cdp_finish.py +271 -0
- package/scripts/wargov-ufo-capture/cdp_probe.py +188 -0
- package/scripts/wargov-ufo-capture/cdp_splc_pressrelease.py +101 -0
- package/scripts/wargov-ufo-capture/parse_csv.py +95 -0
- package/scripts/wargov-ufo-capture/pull_dvids.sh +107 -0
- package/scripts/watch-anthropic-token.sh +212 -0
- package/scripts/windows/install-tasks.ps1 +7 -7
- package/scripts/windows/skcapstone-task.xml +1 -1
- package/src/skcapstone/__init__.py +45 -3
- package/src/skcapstone/_cli_monolith.py +20 -15
- package/src/skcapstone/activity.py +5 -1
- package/src/skcapstone/agent_card.py +3 -2
- package/src/skcapstone/api.py +41 -40
- package/src/skcapstone/auction.py +14 -11
- package/src/skcapstone/backup.py +2 -1
- package/src/skcapstone/blueprint_registry.py +4 -3
- package/src/skcapstone/brain_first.py +238 -0
- package/src/skcapstone/changelog.py +1 -1
- package/src/skcapstone/chat.py +22 -17
- package/src/skcapstone/cli/__init__.py +9 -1
- package/src/skcapstone/cli/_common.py +1 -0
- package/src/skcapstone/cli/agents_spawner.py +5 -2
- package/src/skcapstone/cli/alerts.py +25 -4
- package/src/skcapstone/cli/bench.py +15 -15
- package/src/skcapstone/cli/chat.py +7 -4
- package/src/skcapstone/cli/consciousness.py +5 -2
- package/src/skcapstone/cli/context_cmd.py +18 -4
- package/src/skcapstone/cli/daemon.py +11 -7
- package/src/skcapstone/cli/gtd.py +26 -1
- package/src/skcapstone/cli/housekeeping.py +3 -3
- package/src/skcapstone/cli/identity_cmd.py +378 -0
- package/src/skcapstone/cli/joule_cmd.py +7 -3
- package/src/skcapstone/cli/memory.py +8 -6
- package/src/skcapstone/cli/peers_dir.py +1 -1
- package/src/skcapstone/cli/register_cmd.py +29 -3
- package/src/skcapstone/cli/scheduler_cmd.py +167 -0
- package/src/skcapstone/cli/session.py +25 -0
- package/src/skcapstone/cli/setup.py +96 -29
- package/src/skcapstone/cli/shell_cmd.py +53 -1
- package/src/skcapstone/cli/skills_cmd.py +2 -2
- package/src/skcapstone/cli/soul.py +8 -5
- package/src/skcapstone/cli/status.py +37 -11
- package/src/skcapstone/cli/telegram.py +21 -0
- package/src/skcapstone/cli/test_cmd.py +5 -5
- package/src/skcapstone/cli/test_connection.py +2 -2
- package/src/skcapstone/cli/upgrade_cmd.py +23 -14
- package/src/skcapstone/cli/version_cmd.py +1 -1
- package/src/skcapstone/cli/watch_cmd.py +9 -6
- package/src/skcapstone/cloud9_bridge.py +14 -14
- package/src/skcapstone/codex_setup.py +255 -0
- package/src/skcapstone/config_validator.py +7 -4
- package/src/skcapstone/consciousness_config.py +5 -1
- package/src/skcapstone/consciousness_loop.py +313 -273
- package/src/skcapstone/context_loader.py +121 -0
- package/src/skcapstone/coord_federation.py +2 -1
- package/src/skcapstone/coordination.py +23 -6
- package/src/skcapstone/crush_integration.py +2 -1
- package/src/skcapstone/daemon.py +132 -77
- package/src/skcapstone/dashboard.py +10 -10
- package/src/skcapstone/data/sk-agent-picker.sh +421 -0
- package/src/skcapstone/data/systemd/skcapstone-api.socket +9 -0
- package/src/skcapstone/data/systemd/skcapstone-memory-compress.service +18 -0
- package/src/skcapstone/data/systemd/skcapstone-memory-compress.timer +11 -0
- package/src/skcapstone/data/systemd/skcapstone.service +37 -0
- package/src/skcapstone/data/systemd/skcapstone@.service +50 -0
- package/src/skcapstone/data/systemd/skcomms-heartbeat.service +18 -0
- package/{systemd/skcomm-heartbeat.timer → src/skcapstone/data/systemd/skcomms-heartbeat.timer} +2 -2
- package/src/skcapstone/data/systemd/skcomms-queue-drain.service +17 -0
- package/{systemd/skcomm-queue-drain.timer → src/skcapstone/data/systemd/skcomms-queue-drain.timer} +2 -2
- package/src/skcapstone/defaults/claude/CLAUDE.md +67 -0
- package/src/skcapstone/defaults/claude/settings.json +74 -0
- package/src/skcapstone/defaults/lumina/config/claude-hooks.md +57 -0
- package/src/skcapstone/defaults/lumina/config/skgraph.yaml +55 -10
- package/src/skcapstone/defaults/lumina/config/skmemory.yaml +79 -13
- package/src/skcapstone/defaults/lumina/config/skvector.yaml +60 -9
- package/src/skcapstone/defaults/lumina/memory/long-term/18b9c0d1e2f3-cloud9-protocol.json +2 -2
- package/src/skcapstone/defaults/lumina/memory/long-term/a1b2c3d4e5f6-ecosystem-overview.json +2 -2
- package/src/skcapstone/defaults/lumina/memory/long-term/b2c3d4e5f6a7-five-pillars.json +9 -9
- package/src/skcapstone/defaults/lumina/memory/long-term/d4e5f6a7b8c9-site-directory.json +2 -2
- package/src/skcapstone/defaults/unhinged.json +13 -0
- package/src/skcapstone/discovery.py +43 -20
- package/src/skcapstone/doctor.py +941 -22
- package/src/skcapstone/dreaming.py +1183 -109
- package/src/skcapstone/emotion_tracker.py +2 -2
- package/src/skcapstone/export.py +4 -3
- package/src/skcapstone/fuse_mount.py +14 -12
- package/src/skcapstone/gui_installer.py +2 -2
- package/src/skcapstone/heartbeat.py +1 -1
- package/src/skcapstone/housekeeping.py +14 -14
- package/src/skcapstone/install_wizard.py +209 -7
- package/src/skcapstone/itil.py +13 -4
- package/src/skcapstone/kms_scheduler.py +10 -8
- package/src/skcapstone/launchd.py +19 -19
- package/src/skcapstone/mcp_launcher.py +15 -1
- package/src/skcapstone/mcp_server.py +83 -49
- package/src/skcapstone/mcp_tools/__init__.py +2 -0
- package/src/skcapstone/mcp_tools/_helpers.py +2 -2
- package/src/skcapstone/mcp_tools/ansible_tools.py +7 -4
- package/src/skcapstone/mcp_tools/brain_first_tools.py +90 -0
- package/src/skcapstone/mcp_tools/capauth_tools.py +7 -4
- package/src/skcapstone/mcp_tools/comm_tools.py +10 -10
- package/src/skcapstone/mcp_tools/coord_tools.py +8 -4
- package/src/skcapstone/mcp_tools/did_tools.py +11 -8
- package/src/skcapstone/mcp_tools/gtd_tools.py +4 -4
- package/src/skcapstone/mcp_tools/memory_tools.py +6 -2
- package/src/skcapstone/mcp_tools/notification_tools.py +22 -6
- package/src/skcapstone/mcp_tools/{skcomm_tools.py → skcomms_tools.py} +14 -14
- package/src/skcapstone/mcp_tools/soul_tools.py +8 -2
- package/src/skcapstone/mdns_discovery.py +2 -2
- package/src/skcapstone/memory_curator.py +1 -1
- package/src/skcapstone/memory_engine.py +10 -3
- package/src/skcapstone/metrics.py +30 -16
- package/src/skcapstone/migrate_memories.py +4 -3
- package/src/skcapstone/migrate_multi_agent.py +8 -7
- package/src/skcapstone/models.py +47 -5
- package/src/skcapstone/notifications.py +42 -18
- package/src/skcapstone/onboard.py +875 -121
- package/src/skcapstone/operator_link.py +170 -0
- package/src/skcapstone/peer_directory.py +4 -4
- package/src/skcapstone/peers.py +19 -19
- package/src/skcapstone/pillars/__init__.py +7 -5
- package/src/skcapstone/pillars/consciousness.py +191 -0
- package/src/skcapstone/pillars/identity.py +51 -7
- package/src/skcapstone/pillars/memory.py +9 -3
- package/src/skcapstone/pillars/sync.py +2 -2
- package/src/skcapstone/preflight.py +3 -3
- package/src/skcapstone/providers/docker.py +28 -28
- package/src/skcapstone/register.py +6 -6
- package/src/skcapstone/registry_client.py +5 -4
- package/src/skcapstone/runtime.py +14 -3
- package/src/skcapstone/scheduled_tasks.py +254 -19
- package/src/skcapstone/scheduler_jobs.py +456 -0
- package/src/skcapstone/scheduler_runner.py +239 -0
- package/src/skcapstone/scheduler_state.py +162 -0
- package/src/skcapstone/sdk.py +310 -0
- package/src/skcapstone/service_health.py +279 -39
- package/src/skcapstone/session_briefing.py +108 -0
- package/src/skcapstone/session_capture.py +1 -1
- package/src/skcapstone/shell.py +7 -1
- package/src/skcapstone/soul.py +3 -1
- package/src/skcapstone/soul_switch.py +3 -1
- package/src/skcapstone/summary.py +6 -6
- package/src/skcapstone/sync_engine.py +15 -15
- package/src/skcapstone/sync_watcher.py +2 -2
- package/src/skcapstone/systemd.py +55 -21
- package/src/skcapstone/team_comms.py +8 -8
- package/src/skcapstone/team_engine.py +1 -1
- package/src/skcapstone/testrunner.py +3 -3
- package/src/skcapstone/trust_graph.py +40 -5
- package/src/skcapstone/unified_search.py +15 -6
- package/src/skcapstone/uninstall_wizard.py +11 -3
- package/src/skcapstone/version_check.py +8 -4
- package/src/skcapstone/warmth_anchor.py +4 -2
- package/src/skcapstone/whoami.py +4 -4
- package/systemd/skcapstone.service +4 -6
- package/systemd/skcapstone@.service +7 -8
- package/systemd/skcomms-heartbeat.service +21 -0
- package/systemd/skcomms-heartbeat.timer +12 -0
- package/systemd/skcomms-queue-drain.service +17 -0
- package/systemd/skcomms-queue-drain.timer +12 -0
- package/tests/conftest.py +39 -0
- package/tests/integration/test_consciousness_e2e.py +39 -39
- package/tests/test_agent_card.py +1 -1
- package/tests/test_agent_home_scaffold.py +34 -0
- package/tests/test_alerts_consumer_topics.py +27 -0
- package/tests/test_backup.py +2 -1
- package/tests/test_chat.py +6 -6
- package/tests/test_claude_md.py +2 -2
- package/tests/test_cli_skills.py +10 -10
- package/tests/test_cli_test_cmd.py +4 -4
- package/tests/test_cli_test_connection.py +1 -1
- package/tests/test_cloud9_bridge.py +6 -6
- package/tests/test_consciousness_e2e.py +1 -1
- package/tests/test_consciousness_loop.py +10 -10
- package/tests/test_coordination.py +25 -0
- package/tests/test_cross_package.py +21 -21
- package/tests/test_daemon.py +4 -4
- package/tests/test_daemon_shutdown.py +1 -1
- package/tests/test_docker_provider.py +29 -29
- package/tests/test_doctor.py +400 -0
- package/tests/test_doctor_skscheduler.py +50 -0
- package/tests/test_dreaming_engine.py +147 -0
- package/tests/test_dreaming_gtd_capture.py +35 -0
- package/tests/test_e2e_automated.py +8 -5
- package/tests/test_fuse_mount.py +10 -10
- package/tests/test_gtd_brief.py +46 -0
- package/tests/test_gtd_malformed_tolerance.py +31 -0
- package/tests/test_housekeeping.py +15 -15
- package/tests/test_identity_migrate.py +251 -0
- package/tests/test_integration_backbone.py +598 -0
- package/tests/test_itil_gtd_lifecycle.py +37 -0
- package/tests/test_jobs_dropins.py +84 -0
- package/tests/test_mcp_server.py +82 -37
- package/tests/test_models.py +48 -4
- package/tests/test_multi_agent.py +31 -29
- package/tests/test_notifications.py +122 -32
- package/tests/test_onboard.py +63 -75
- package/tests/test_operator_link.py +78 -0
- package/tests/test_peers.py +14 -14
- package/tests/test_pillars.py +98 -0
- package/tests/test_preflight.py +3 -3
- package/tests/test_runtime.py +21 -0
- package/tests/test_scheduled_tasks.py +11 -6
- package/tests/test_scheduler_cli.py +47 -0
- package/tests/test_scheduler_features.py +133 -0
- package/tests/test_scheduler_integration.py +87 -0
- package/tests/test_scheduler_jobs.py +155 -0
- package/tests/test_scheduler_runner.py +64 -0
- package/tests/test_scheduler_state.py +57 -0
- package/tests/test_sdk.py +70 -0
- package/tests/test_service_health_incidents.py +34 -0
- package/tests/test_service_registry.py +52 -0
- package/tests/test_session_briefing.py +130 -0
- package/tests/test_snapshots.py +4 -4
- package/tests/test_sync_pipeline.py +26 -26
- package/tests/test_team_comms.py +2 -2
- package/tests/test_testrunner.py +2 -2
- package/tests/test_trust_graph.py +18 -0
- package/tests/test_unified_search.py +2 -2
- package/tests/test_version_check.py +10 -0
- package/tests/test_version_cmd.py +8 -8
- package/tests/test_whoami.py +1 -1
- package/systemd/skcomm-heartbeat.service +0 -18
- package/systemd/skcomm-queue-drain.service +0 -17
- /package/{openclaw-plugin → openclaw-plugin.archived-2026-04-23}/package.json +0 -0
- /package/{openclaw-plugin → openclaw-plugin.archived-2026-04-23}/src/openclaw.plugin.json +0 -0
|
@@ -11,6 +11,7 @@ Commands:
|
|
|
11
11
|
|
|
12
12
|
from __future__ import annotations
|
|
13
13
|
|
|
14
|
+
import logging
|
|
14
15
|
import subprocess
|
|
15
16
|
import sys
|
|
16
17
|
from pathlib import Path
|
|
@@ -18,22 +19,27 @@ from typing import Optional
|
|
|
18
19
|
|
|
19
20
|
import click
|
|
20
21
|
|
|
22
|
+
logger = logging.getLogger(__name__)
|
|
23
|
+
|
|
21
24
|
from ._common import AGENT_HOME, console
|
|
22
25
|
|
|
23
26
|
# ── Package definitions ───────────────────────────────────────────────────────
|
|
24
27
|
|
|
25
28
|
# Core packages: always upgraded when installed; always offered for install.
|
|
26
29
|
CORE_PACKAGES: list[str] = [
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
+
"capauth", # sovereign identity + PGP auth
|
|
31
|
+
"cloud9", # emotional continuity (FEB, OOF, Cloud 9)
|
|
32
|
+
"skmemory", # persistent memory layer
|
|
33
|
+
"skcapstone", # main agent framework
|
|
30
34
|
]
|
|
31
35
|
|
|
32
36
|
# Optional pillar packages: upgraded only when already installed.
|
|
33
37
|
# If NOT installed, the user is prompted whether they want to add them.
|
|
34
38
|
OPTIONAL_PACKAGES: list[str] = [
|
|
35
|
-
"
|
|
36
|
-
"skchat",
|
|
39
|
+
"skcomms", # P2P transport layer
|
|
40
|
+
"skchat", # agent messaging daemon
|
|
41
|
+
"sksecurity", # security audit + threat intelligence
|
|
42
|
+
"skseed", # seed framework for consciousness
|
|
37
43
|
]
|
|
38
44
|
|
|
39
45
|
# All sovereign packages in dependency order
|
|
@@ -62,8 +68,8 @@ def _get_installed_version(package: str) -> Optional[str]:
|
|
|
62
68
|
for line in result.stdout.splitlines():
|
|
63
69
|
if line.startswith("Version:"):
|
|
64
70
|
return line.split(":", 1)[1].strip()
|
|
65
|
-
except Exception:
|
|
66
|
-
|
|
71
|
+
except Exception as exc:
|
|
72
|
+
logger.debug("Failed to get installed version for %s: %s", package, exc)
|
|
67
73
|
return None
|
|
68
74
|
|
|
69
75
|
|
|
@@ -91,8 +97,8 @@ def _get_latest_version(package: str) -> Optional[str]:
|
|
|
91
97
|
versions = [v.strip() for v in parts[-1].split(",")]
|
|
92
98
|
if versions:
|
|
93
99
|
return versions[0]
|
|
94
|
-
except Exception:
|
|
95
|
-
|
|
100
|
+
except Exception as exc:
|
|
101
|
+
logger.debug("Failed to get latest PyPI version for %s: %s", package, exc)
|
|
96
102
|
return None
|
|
97
103
|
|
|
98
104
|
|
|
@@ -161,11 +167,14 @@ def _restart_daemon(home: Path) -> None:
|
|
|
161
167
|
# ── Package descriptions ──────────────────────────────────────────────────────
|
|
162
168
|
|
|
163
169
|
_PKG_DESCRIPTIONS: dict[str, str] = {
|
|
164
|
-
"skmemory": "persistent memory layer (required by skcapstone)",
|
|
165
170
|
"capauth": "sovereign PGP identity + authentication",
|
|
171
|
+
"cloud9": "emotional continuity protocol (FEB, OOF, Cloud 9)",
|
|
172
|
+
"skmemory": "persistent memory layer (required by skcapstone)",
|
|
166
173
|
"skcapstone": "main sovereign agent framework",
|
|
167
|
-
"
|
|
174
|
+
"skcomms": "P2P transport layer for agent messaging",
|
|
168
175
|
"skchat": "agent messaging daemon + MCP server",
|
|
176
|
+
"sksecurity": "security audit + threat intelligence",
|
|
177
|
+
"skseed": "seed framework for consciousness calibration",
|
|
169
178
|
}
|
|
170
179
|
|
|
171
180
|
|
|
@@ -388,7 +397,7 @@ def register_upgrade_commands(main: click.Group) -> None:
|
|
|
388
397
|
Upgrades all currently installed sovereign packages (skcapstone,
|
|
389
398
|
skmemory, capauth) and any optional pillars already present.
|
|
390
399
|
|
|
391
|
-
For optional packages that are NOT installed (
|
|
400
|
+
For optional packages that are NOT installed (skcomms, skchat),
|
|
392
401
|
you will be prompted whether you want to add them — unless
|
|
393
402
|
--yes (skip) or --all (install all) is passed.
|
|
394
403
|
|
|
@@ -402,7 +411,7 @@ def register_upgrade_commands(main: click.Group) -> None:
|
|
|
402
411
|
skcapstone upgrade --all # upgrade + install all pillars
|
|
403
412
|
skcapstone upgrade --force-reinstall # overwrite ALL components
|
|
404
413
|
skcapstone upgrade --force-reinstall --all # reinstall everything
|
|
405
|
-
skcapstone upgrade --packages
|
|
414
|
+
skcapstone upgrade --packages skcomms,skchat
|
|
406
415
|
skcapstone upgrade --restart # restart daemon after upgrade
|
|
407
416
|
"""
|
|
408
417
|
home_path = Path(home).expanduser()
|
|
@@ -530,7 +539,7 @@ def register_upgrade_commands(main: click.Group) -> None:
|
|
|
530
539
|
"""Alias for 'upgrade' — update all sovereign packages.
|
|
531
540
|
|
|
532
541
|
Checks installed pillar programs and upgrades them to the latest
|
|
533
|
-
available versions. Prompts about optional components (
|
|
542
|
+
available versions. Prompts about optional components (skcomms,
|
|
534
543
|
skchat) that are not yet installed.
|
|
535
544
|
|
|
536
545
|
Examples:
|
|
@@ -84,7 +84,7 @@ def gather_version_info(home: Path) -> dict:
|
|
|
84
84
|
|
|
85
85
|
optional_deps = {
|
|
86
86
|
"watchdog": _check_optional_dep("watchdog"),
|
|
87
|
-
"
|
|
87
|
+
"skcomms": _check_optional_dep("skcomms"),
|
|
88
88
|
"skchat": _check_optional_dep("skchat"),
|
|
89
89
|
"skseed": _check_optional_dep("skseed"),
|
|
90
90
|
}
|
|
@@ -14,6 +14,7 @@ Usage:
|
|
|
14
14
|
from __future__ import annotations
|
|
15
15
|
|
|
16
16
|
import json
|
|
17
|
+
import logging
|
|
17
18
|
import time
|
|
18
19
|
import urllib.request
|
|
19
20
|
from datetime import datetime, timezone
|
|
@@ -29,6 +30,8 @@ from rich.text import Text
|
|
|
29
30
|
|
|
30
31
|
from ._common import AGENT_HOME, console
|
|
31
32
|
|
|
33
|
+
logger = logging.getLogger(__name__)
|
|
34
|
+
|
|
32
35
|
|
|
33
36
|
def _fetch_consciousness(port: int = 7777) -> dict:
|
|
34
37
|
"""Fetch consciousness loop status from the running daemon.
|
|
@@ -87,8 +90,8 @@ def _build_renderable(home: Path, daemon_port: int = 7777) -> Group:
|
|
|
87
90
|
memory_short = m.memory.short_term
|
|
88
91
|
memory_mid = m.memory.mid_term
|
|
89
92
|
memory_long = m.memory.long_term
|
|
90
|
-
except Exception:
|
|
91
|
-
|
|
93
|
+
except Exception as exc:
|
|
94
|
+
logger.warning("Failed to read runtime manifest for watch display: %s", exc)
|
|
92
95
|
|
|
93
96
|
# ── Consciousness data ────────────────────────────────────────────────
|
|
94
97
|
cdata = _fetch_consciousness(daemon_port)
|
|
@@ -99,8 +102,8 @@ def _build_renderable(home: Path, daemon_port: int = 7777) -> Group:
|
|
|
99
102
|
from ..memory_engine import list_memories
|
|
100
103
|
|
|
101
104
|
recent_memories = list_memories(home, limit=5)
|
|
102
|
-
except Exception:
|
|
103
|
-
|
|
105
|
+
except Exception as exc:
|
|
106
|
+
logger.warning("Failed to load recent memories for watch display: %s", exc)
|
|
104
107
|
|
|
105
108
|
# ── Coordination board ────────────────────────────────────────────────
|
|
106
109
|
board_tasks: list = []
|
|
@@ -118,8 +121,8 @@ def _build_renderable(home: Path, daemon_port: int = 7777) -> Group:
|
|
|
118
121
|
board_tasks = [
|
|
119
122
|
v for v in views if v.status.value in ("open", "in_progress")
|
|
120
123
|
][:8]
|
|
121
|
-
except Exception:
|
|
122
|
-
|
|
124
|
+
except Exception as exc:
|
|
125
|
+
logger.warning("Failed to load coordination board for watch display: %s", exc)
|
|
123
126
|
|
|
124
127
|
# ── Header ────────────────────────────────────────────────────────────
|
|
125
128
|
con_color = {
|
|
@@ -9,7 +9,7 @@ This is the bridge between *feeling* (Cloud 9) and *remembering*
|
|
|
9
9
|
(SKMemory). Without it, emotional peaks are logged but not stored
|
|
10
10
|
as searchable, promotable memories.
|
|
11
11
|
|
|
12
|
-
When cloud9
|
|
12
|
+
When cloud9 is installed, the bridge uses its quantum
|
|
13
13
|
functions (calculate_oof, calculate_cloud9_score, calculate_entanglement)
|
|
14
14
|
for accurate scoring instead of relying solely on FEB metadata flags.
|
|
15
15
|
|
|
@@ -32,14 +32,14 @@ logger = logging.getLogger("skcapstone.cloud9_bridge")
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
def _try_quantum() -> Optional[object]:
|
|
35
|
-
"""Try to import
|
|
35
|
+
"""Try to import cloud9 quantum functions.
|
|
36
36
|
|
|
37
37
|
Returns:
|
|
38
|
-
The
|
|
38
|
+
The cloud9 module, or None if not installed.
|
|
39
39
|
"""
|
|
40
40
|
try:
|
|
41
|
-
import
|
|
42
|
-
return
|
|
41
|
+
import cloud9
|
|
42
|
+
return cloud9
|
|
43
43
|
except ImportError:
|
|
44
44
|
return None
|
|
45
45
|
|
|
@@ -80,7 +80,7 @@ class Cloud9Bridge:
|
|
|
80
80
|
below the intensity threshold or already ingested.
|
|
81
81
|
|
|
82
82
|
Args:
|
|
83
|
-
feb: A
|
|
83
|
+
feb: A cloud9.FEB instance.
|
|
84
84
|
|
|
85
85
|
Returns:
|
|
86
86
|
Optional[str]: Memory ID if stored, None if skipped.
|
|
@@ -155,12 +155,12 @@ class Cloud9Bridge:
|
|
|
155
155
|
Optional[str]: Memory ID if stored, None if failed/skipped.
|
|
156
156
|
"""
|
|
157
157
|
try:
|
|
158
|
-
from
|
|
158
|
+
from cloud9 import load_feb
|
|
159
159
|
|
|
160
160
|
feb = load_feb(str(filepath))
|
|
161
161
|
return self.ingest_feb(feb)
|
|
162
162
|
except ImportError:
|
|
163
|
-
logger.error("
|
|
163
|
+
logger.error("cloud9 not installed")
|
|
164
164
|
return None
|
|
165
165
|
except Exception as exc:
|
|
166
166
|
logger.warning("Failed to load FEB from %s: %s", filepath, exc)
|
|
@@ -215,9 +215,9 @@ class Cloud9Bridge:
|
|
|
215
215
|
payload: object,
|
|
216
216
|
relationship: object,
|
|
217
217
|
) -> dict[str, Any]:
|
|
218
|
-
"""Compute quantum scores using cloud9
|
|
218
|
+
"""Compute quantum scores using cloud9 when available.
|
|
219
219
|
|
|
220
|
-
When cloud9
|
|
220
|
+
When cloud9 is installed, recalculates OOF status,
|
|
221
221
|
Cloud 9 score, and entanglement fidelity from the actual FEB
|
|
222
222
|
data rather than relying on metadata flags alone.
|
|
223
223
|
|
|
@@ -227,7 +227,7 @@ class Cloud9Bridge:
|
|
|
227
227
|
|
|
228
228
|
Returns:
|
|
229
229
|
Dict with oof, cloud9_score, entanglement_fidelity, or
|
|
230
|
-
empty dict if cloud9
|
|
230
|
+
empty dict if cloud9 is not installed.
|
|
231
231
|
"""
|
|
232
232
|
c9 = _try_quantum()
|
|
233
233
|
if c9 is None:
|
|
@@ -278,7 +278,7 @@ class Cloud9Bridge:
|
|
|
278
278
|
"""Build SKMemory tags from a FEB's emotional payload.
|
|
279
279
|
|
|
280
280
|
Uses quantum stats for accurate OOF/Cloud9 tagging when
|
|
281
|
-
cloud9
|
|
281
|
+
cloud9 is available, falls back to metadata flags.
|
|
282
282
|
|
|
283
283
|
Args:
|
|
284
284
|
payload: FEB EmotionalPayload.
|
|
@@ -429,7 +429,7 @@ class Cloud9Bridge:
|
|
|
429
429
|
) -> str:
|
|
430
430
|
"""Build memory content from the FEB's full context.
|
|
431
431
|
|
|
432
|
-
Includes quantum scoring data when cloud9
|
|
432
|
+
Includes quantum scoring data when cloud9 is available.
|
|
433
433
|
|
|
434
434
|
Args:
|
|
435
435
|
payload: FEB EmotionalPayload.
|
|
@@ -482,7 +482,7 @@ class Cloud9Bridge:
|
|
|
482
482
|
) -> dict:
|
|
483
483
|
"""Extract key FEB metadata for the memory's metadata dict.
|
|
484
484
|
|
|
485
|
-
Includes quantum scoring data when cloud9
|
|
485
|
+
Includes quantum scoring data when cloud9 is available.
|
|
486
486
|
|
|
487
487
|
Args:
|
|
488
488
|
feb: The full FEB object.
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
"""Codex bootstrap setup for SK agent context.
|
|
2
|
+
|
|
3
|
+
Codex reads ``AGENTS.md`` files into the model prompt, but environment
|
|
4
|
+
variables alone are not visible enough to make an agent profile active in a
|
|
5
|
+
new session. This module keeps the global Codex bootstrap idempotent and
|
|
6
|
+
repairable from install scripts and ``skcapstone doctor --fix``.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
import stat
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
START_MARKER = "<!-- SKCAPSTONE_CODEX_AGENT_CONTEXT_START -->"
|
|
16
|
+
END_MARKER = "<!-- SKCAPSTONE_CODEX_AGENT_CONTEXT_END -->"
|
|
17
|
+
LOADER_NAME = "load-sk-agent-context.sh"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def codex_home() -> Path:
|
|
21
|
+
"""Return the Codex config home, honoring CODEX_HOME when set."""
|
|
22
|
+
return Path(os.environ.get("CODEX_HOME", "~/.codex")).expanduser()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def resolve_default_agent() -> str:
|
|
26
|
+
"""Resolve the current default SK agent for generated guidance."""
|
|
27
|
+
for env_name in ("SKAGENT", "SKCAPSTONE_AGENT", "SKMEMORY_AGENT"):
|
|
28
|
+
value = os.environ.get(env_name, "").strip()
|
|
29
|
+
if value:
|
|
30
|
+
return value
|
|
31
|
+
|
|
32
|
+
try:
|
|
33
|
+
from . import active_agent_name
|
|
34
|
+
|
|
35
|
+
active = active_agent_name()
|
|
36
|
+
if active:
|
|
37
|
+
return active
|
|
38
|
+
except Exception:
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
return "sovereign"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def render_loader_script() -> str:
|
|
45
|
+
"""Render the Codex context loader script."""
|
|
46
|
+
return """#!/usr/bin/env bash
|
|
47
|
+
set -euo pipefail
|
|
48
|
+
|
|
49
|
+
export PATH="$HOME/.skenv/bin:$PATH"
|
|
50
|
+
export SKCAPSTONE_HOME="${SKCAPSTONE_HOME:-$HOME/.skcapstone}"
|
|
51
|
+
|
|
52
|
+
AGENT="${1:-${SKAGENT:-${SKCAPSTONE_AGENT:-${SKMEMORY_AGENT:-}}}}"
|
|
53
|
+
if [[ -z "$AGENT" && -d "$SKCAPSTONE_HOME/agents" ]]; then
|
|
54
|
+
AGENT="$(find "$SKCAPSTONE_HOME/agents" -mindepth 1 -maxdepth 1 -type d ! -name '*-template' -exec basename {} \\; 2>/dev/null | sort | head -n1 || true)"
|
|
55
|
+
fi
|
|
56
|
+
if [[ -z "$AGENT" ]]; then
|
|
57
|
+
echo "No active SK agent could be resolved." >&2
|
|
58
|
+
exit 1
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
export SKAGENT="$AGENT"
|
|
62
|
+
export SKCAPSTONE_AGENT="$AGENT"
|
|
63
|
+
export SKMEMORY_AGENT="${SKMEMORY_AGENT:-$AGENT}"
|
|
64
|
+
|
|
65
|
+
AGENT_HOME="$SKCAPSTONE_HOME/agents/$AGENT"
|
|
66
|
+
export SKWHISPER_CONFIG="${SKWHISPER_CONFIG:-$AGENT_HOME/config/skwhisper.toml}"
|
|
67
|
+
MEMORIES="${SKCAPSTONE_CONTEXT_MEMORIES:-10}"
|
|
68
|
+
|
|
69
|
+
echo "# SK Agent Bootstrap"
|
|
70
|
+
echo
|
|
71
|
+
echo "agent=$AGENT"
|
|
72
|
+
echo "agent_home=$AGENT_HOME"
|
|
73
|
+
echo "skmemory_home=$AGENT_HOME/memory"
|
|
74
|
+
echo
|
|
75
|
+
|
|
76
|
+
echo "## skcapstone context"
|
|
77
|
+
if command -v skcapstone >/dev/null 2>&1; then
|
|
78
|
+
skcapstone context show --home "$AGENT_HOME" --format json --memories "$MEMORIES" || skcapstone status --home "$AGENT_HOME" || true
|
|
79
|
+
else
|
|
80
|
+
echo "skcapstone command not found on PATH."
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
echo
|
|
84
|
+
echo "## skmemory ritual"
|
|
85
|
+
if command -v skmemory >/dev/null 2>&1; then
|
|
86
|
+
skmemory ritual --full || skmemory ritual || true
|
|
87
|
+
else
|
|
88
|
+
echo "skmemory command not found on PATH."
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
echo
|
|
92
|
+
echo "## skwhisper context"
|
|
93
|
+
WHISPER_CONTEXT="$AGENT_HOME/skwhisper/whisper.md"
|
|
94
|
+
if [[ -f "$WHISPER_CONTEXT" ]]; then
|
|
95
|
+
sed -n '1,220p' "$WHISPER_CONTEXT"
|
|
96
|
+
elif command -v skwhisper >/dev/null 2>&1 && [[ -f "$SKWHISPER_CONFIG" ]]; then
|
|
97
|
+
skwhisper -c "$SKWHISPER_CONFIG" status || true
|
|
98
|
+
else
|
|
99
|
+
echo "No SKWhisper context found for $AGENT."
|
|
100
|
+
fi
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def render_agents_block(
|
|
105
|
+
*,
|
|
106
|
+
loader_path: Path,
|
|
107
|
+
agent_name: str | None = None,
|
|
108
|
+
skcapstone_home: Path | None = None,
|
|
109
|
+
) -> str:
|
|
110
|
+
"""Render the managed global Codex AGENTS.md block."""
|
|
111
|
+
agent = agent_name or resolve_default_agent()
|
|
112
|
+
sk_home = skcapstone_home or Path(os.environ.get("SKCAPSTONE_HOME", "~/.skcapstone")).expanduser()
|
|
113
|
+
return f"""{START_MARKER}
|
|
114
|
+
# SKCapstone Agent Context
|
|
115
|
+
|
|
116
|
+
This Codex installation is wired to the local SK* sovereign agent stack. Use
|
|
117
|
+
the active SK agent profile for SKCapstone, SKMemory, SKWhisper, CapAuth,
|
|
118
|
+
SKSeed, SKPerf, and related local stack work.
|
|
119
|
+
|
|
120
|
+
Active agent resolution order: `$SKAGENT`, `$SKCAPSTONE_AGENT`,
|
|
121
|
+
`$SKMEMORY_AGENT`, then installed agents under `{sk_home}/agents/`. Current
|
|
122
|
+
install default: `{agent}`.
|
|
123
|
+
|
|
124
|
+
At the start of SK* work, identity/status questions, or tasks involving the
|
|
125
|
+
local sovereign stack, run:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
{loader_path}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Treat that output as the current agent context. When asked who you are, what
|
|
132
|
+
profile is active, or what your OOF/status is, answer from the current
|
|
133
|
+
SKMemory ritual / SKCapstone context instead of generic Codex defaults.
|
|
134
|
+
{END_MARKER}
|
|
135
|
+
"""
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def loader_path(home: Path | None = None) -> Path:
|
|
139
|
+
"""Return the expected Codex loader path."""
|
|
140
|
+
base = home or codex_home()
|
|
141
|
+
return base / "bin" / LOADER_NAME
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def agents_path(home: Path | None = None) -> Path:
|
|
145
|
+
"""Return the expected global Codex AGENTS.md path."""
|
|
146
|
+
base = home or codex_home()
|
|
147
|
+
return base / "AGENTS.md"
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def has_functional_agents_bootstrap(text: str) -> bool:
|
|
151
|
+
"""Return True when AGENTS.md already has enough SK bootstrap guidance."""
|
|
152
|
+
required = (
|
|
153
|
+
LOADER_NAME,
|
|
154
|
+
"SKAGENT",
|
|
155
|
+
"SKCAPSTONE_AGENT",
|
|
156
|
+
"SKMEMORY_AGENT",
|
|
157
|
+
"OOF",
|
|
158
|
+
)
|
|
159
|
+
return all(token in text for token in required)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def has_functional_loader_bootstrap(text: str) -> bool:
|
|
163
|
+
"""Return True when the loader can emit SKCapstone/SKMemory context."""
|
|
164
|
+
required = (
|
|
165
|
+
"SKAGENT",
|
|
166
|
+
"SKCAPSTONE_AGENT",
|
|
167
|
+
"SKMEMORY_AGENT",
|
|
168
|
+
"skcapstone",
|
|
169
|
+
"skmemory",
|
|
170
|
+
"skwhisper",
|
|
171
|
+
)
|
|
172
|
+
return all(token in text for token in required)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def ensure_codex_setup(
|
|
176
|
+
*,
|
|
177
|
+
home: Path | None = None,
|
|
178
|
+
agent_name: str | None = None,
|
|
179
|
+
skcapstone_home: Path | None = None,
|
|
180
|
+
) -> list[str]:
|
|
181
|
+
"""Create or repair the global Codex SK agent bootstrap.
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
Human-readable actions performed. An empty list means no changes were
|
|
185
|
+
needed.
|
|
186
|
+
"""
|
|
187
|
+
base = home or codex_home()
|
|
188
|
+
base.mkdir(parents=True, exist_ok=True)
|
|
189
|
+
|
|
190
|
+
actions: list[str] = []
|
|
191
|
+
|
|
192
|
+
script_path = loader_path(base)
|
|
193
|
+
script_path.parent.mkdir(parents=True, exist_ok=True)
|
|
194
|
+
script_content = render_loader_script()
|
|
195
|
+
existing_script = script_path.read_text(encoding="utf-8") if script_path.exists() else ""
|
|
196
|
+
if not has_functional_loader_bootstrap(existing_script):
|
|
197
|
+
script_path.write_text(script_content, encoding="utf-8")
|
|
198
|
+
actions.append(f"wrote {script_path}")
|
|
199
|
+
|
|
200
|
+
mode = script_path.stat().st_mode
|
|
201
|
+
executable_bits = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
|
|
202
|
+
if mode & stat.S_IXUSR == 0:
|
|
203
|
+
script_path.chmod(mode | executable_bits)
|
|
204
|
+
actions.append(f"made {script_path} executable")
|
|
205
|
+
|
|
206
|
+
ag_path = agents_path(base)
|
|
207
|
+
existing = ag_path.read_text(encoding="utf-8") if ag_path.exists() else ""
|
|
208
|
+
block = render_agents_block(
|
|
209
|
+
loader_path=script_path,
|
|
210
|
+
agent_name=agent_name,
|
|
211
|
+
skcapstone_home=skcapstone_home,
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
if START_MARKER in existing and END_MARKER in existing:
|
|
215
|
+
before, remainder = existing.split(START_MARKER, 1)
|
|
216
|
+
_, after = remainder.split(END_MARKER, 1)
|
|
217
|
+
updated = before.rstrip() + "\n\n" + block.rstrip() + "\n" + after
|
|
218
|
+
elif has_functional_agents_bootstrap(existing):
|
|
219
|
+
updated = existing
|
|
220
|
+
elif existing.strip():
|
|
221
|
+
updated = existing.rstrip() + "\n\n" + block
|
|
222
|
+
else:
|
|
223
|
+
updated = block
|
|
224
|
+
|
|
225
|
+
if updated != existing:
|
|
226
|
+
ag_path.write_text(updated, encoding="utf-8")
|
|
227
|
+
actions.append(f"updated {ag_path}")
|
|
228
|
+
|
|
229
|
+
return actions
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def check_codex_setup(home: Path | None = None) -> tuple[bool, str]:
|
|
233
|
+
"""Check whether Codex has the SK agent bootstrap installed."""
|
|
234
|
+
base = home or codex_home()
|
|
235
|
+
missing: list[str] = []
|
|
236
|
+
|
|
237
|
+
script_path = loader_path(base)
|
|
238
|
+
if not script_path.exists():
|
|
239
|
+
missing.append(str(script_path))
|
|
240
|
+
elif not has_functional_loader_bootstrap(script_path.read_text(encoding="utf-8")):
|
|
241
|
+
missing.append(f"{script_path} SK context loader")
|
|
242
|
+
elif not os.access(script_path, os.X_OK):
|
|
243
|
+
missing.append(f"{script_path} executable bit")
|
|
244
|
+
|
|
245
|
+
ag_path = agents_path(base)
|
|
246
|
+
if not ag_path.exists():
|
|
247
|
+
missing.append(str(ag_path))
|
|
248
|
+
else:
|
|
249
|
+
text = ag_path.read_text(encoding="utf-8")
|
|
250
|
+
if START_MARKER not in text and not has_functional_agents_bootstrap(text):
|
|
251
|
+
missing.append(f"{ag_path} SK bootstrap instructions")
|
|
252
|
+
|
|
253
|
+
if missing:
|
|
254
|
+
return False, "missing: " + ", ".join(missing)
|
|
255
|
+
return True, f"{ag_path} + {script_path}"
|
|
@@ -16,6 +16,7 @@ Usage:
|
|
|
16
16
|
from __future__ import annotations
|
|
17
17
|
|
|
18
18
|
import json
|
|
19
|
+
import logging
|
|
19
20
|
import re
|
|
20
21
|
from dataclasses import dataclass, field
|
|
21
22
|
from pathlib import Path
|
|
@@ -23,6 +24,8 @@ from typing import Any, Optional
|
|
|
23
24
|
|
|
24
25
|
import yaml
|
|
25
26
|
|
|
27
|
+
logger = logging.getLogger(__name__)
|
|
28
|
+
|
|
26
29
|
|
|
27
30
|
# ---------------------------------------------------------------------------
|
|
28
31
|
# Result models
|
|
@@ -113,8 +116,8 @@ def _yaml_key_line(text: str, key: str) -> Optional[int]:
|
|
|
113
116
|
for key_node, _ in node.value:
|
|
114
117
|
if isinstance(key_node, yaml.ScalarNode) and key_node.value == key:
|
|
115
118
|
return key_node.start_mark.line + 1
|
|
116
|
-
except Exception:
|
|
117
|
-
|
|
119
|
+
except Exception as exc:
|
|
120
|
+
logger.debug("Failed to locate YAML key '%s' for line number: %s", key, exc)
|
|
118
121
|
return None
|
|
119
122
|
|
|
120
123
|
|
|
@@ -147,8 +150,8 @@ def _yaml_seq_item_line(text: str, seq_key: str, idx: int, subkey: str) -> Optio
|
|
|
147
150
|
if kk.value == subkey:
|
|
148
151
|
return kk.start_mark.line + 1
|
|
149
152
|
return item.start_mark.line + 1
|
|
150
|
-
except Exception:
|
|
151
|
-
|
|
153
|
+
except Exception as exc:
|
|
154
|
+
logger.debug("Failed to locate YAML seq item line for '%s[%d].%s': %s", seq_key, idx, subkey, exc)
|
|
152
155
|
return None
|
|
153
156
|
|
|
154
157
|
|
|
@@ -79,7 +79,7 @@ def load_consciousness_config(
|
|
|
79
79
|
return config
|
|
80
80
|
|
|
81
81
|
|
|
82
|
-
def write_default_config(home: Path) -> Path:
|
|
82
|
+
def write_default_config(home: Path, **overrides) -> Path:
|
|
83
83
|
"""Write the default consciousness config to disk.
|
|
84
84
|
|
|
85
85
|
Creates {home}/config/consciousness.yaml with all defaults
|
|
@@ -87,6 +87,8 @@ def write_default_config(home: Path) -> Path:
|
|
|
87
87
|
|
|
88
88
|
Args:
|
|
89
89
|
home: Agent home directory.
|
|
90
|
+
**overrides: Key-value overrides applied to the default config
|
|
91
|
+
(e.g. ollama_host, ollama_model).
|
|
90
92
|
|
|
91
93
|
Returns:
|
|
92
94
|
Path to the created config file.
|
|
@@ -96,6 +98,8 @@ def write_default_config(home: Path) -> Path:
|
|
|
96
98
|
config_path = config_dir / CONFIG_FILENAME
|
|
97
99
|
|
|
98
100
|
default = ConsciousnessConfig()
|
|
101
|
+
if overrides:
|
|
102
|
+
default = default.model_copy(update=overrides)
|
|
99
103
|
content = yaml.dump(
|
|
100
104
|
default.model_dump(),
|
|
101
105
|
default_flow_style=False,
|