@smilintux/skcapstone 0.5.2 → 0.5.4
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/package.json +1 -1
- package/pyproject.toml +1 -1
- package/src/skcapstone/consciousness_config.py +5 -1
- package/src/skcapstone/consciousness_loop.py +6 -1
- 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 +35 -0
- package/src/skcapstone/data/systemd/skcapstone@.service +50 -0
- package/src/skcapstone/data/systemd/skcomm-heartbeat.service +18 -0
- package/src/skcapstone/data/systemd/skcomm-heartbeat.timer +12 -0
- package/src/skcapstone/data/systemd/skcomm-queue-drain.service +17 -0
- package/src/skcapstone/data/systemd/skcomm-queue-drain.timer +12 -0
- package/src/skcapstone/doctor.py +11 -0
- package/src/skcapstone/onboard.py +740 -76
- package/src/skcapstone/systemd.py +1 -1
- package/docs/CLAUDE-CODE-API.md +0 -139
- package/scripts/claude-code-api.py +0 -455
package/package.json
CHANGED
package/pyproject.toml
CHANGED
|
@@ -102,7 +102,7 @@ Changelog = "https://github.com/smilinTux/skcapstone/releases"
|
|
|
102
102
|
where = ["src"]
|
|
103
103
|
|
|
104
104
|
[tool.setuptools.package-data]
|
|
105
|
-
skcapstone = ["SKILL.md", "defaults/**/*.json", "defaults/**/*.yaml", "defaults/**/*.feb", "defaults/**/*.md"]
|
|
105
|
+
skcapstone = ["SKILL.md", "defaults/**/*.json", "defaults/**/*.yaml", "defaults/**/*.feb", "defaults/**/*.md", "data/*.yaml", "data/systemd/*.service", "data/systemd/*.socket", "data/systemd/*.timer"]
|
|
106
106
|
|
|
107
107
|
[tool.black]
|
|
108
108
|
line-length = 99
|
|
@@ -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,
|
|
@@ -108,6 +108,8 @@ class ConsciousnessConfig(BaseModel):
|
|
|
108
108
|
"passthrough",
|
|
109
109
|
]
|
|
110
110
|
)
|
|
111
|
+
ollama_host: str = "http://localhost:11434"
|
|
112
|
+
ollama_model: str = "llama3.2"
|
|
111
113
|
desktop_notifications: bool = True
|
|
112
114
|
|
|
113
115
|
|
|
@@ -151,6 +153,8 @@ def _backend_from_model(model_name: str, tier: ModelTier) -> str:
|
|
|
151
153
|
return "grok"
|
|
152
154
|
if "kimi" in name_base or "moonshot" in name_base:
|
|
153
155
|
return "kimi"
|
|
156
|
+
if "minimax" in name_base:
|
|
157
|
+
return "minimax"
|
|
154
158
|
if "nvidia" in name_base:
|
|
155
159
|
return "nvidia"
|
|
156
160
|
if any(p in name_base for p in _OLLAMA_MODEL_PATTERNS):
|
|
@@ -256,7 +260,7 @@ class LLMBridge:
|
|
|
256
260
|
self._available: dict[str, bool] = {}
|
|
257
261
|
self._cache: Optional[ResponseCache] = cache
|
|
258
262
|
self._fallback_tracker = FallbackTracker()
|
|
259
|
-
self._ollama_pool = _OllamaPool(os.environ.get("OLLAMA_HOST",
|
|
263
|
+
self._ollama_pool = _OllamaPool(os.environ.get("OLLAMA_HOST", config.ollama_host))
|
|
260
264
|
self._probe_available_backends()
|
|
261
265
|
|
|
262
266
|
def _probe_available_backends(self) -> None:
|
|
@@ -299,6 +303,7 @@ class LLMBridge:
|
|
|
299
303
|
anthropic_callback,
|
|
300
304
|
grok_callback,
|
|
301
305
|
kimi_callback,
|
|
306
|
+
minimax_callback,
|
|
302
307
|
nvidia_callback,
|
|
303
308
|
ollama_callback,
|
|
304
309
|
openai_callback,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[Unit]
|
|
2
|
+
Description=SKCapstone Memory Compression — weekly LLM synthesis of aged long-term memories
|
|
3
|
+
Documentation=https://github.com/smilinTux/skcapstone
|
|
4
|
+
After=network-online.target
|
|
5
|
+
|
|
6
|
+
[Service]
|
|
7
|
+
Type=oneshot
|
|
8
|
+
ExecStart=skcapstone memory compress
|
|
9
|
+
Nice=15
|
|
10
|
+
|
|
11
|
+
NoNewPrivileges=true
|
|
12
|
+
ProtectSystem=strict
|
|
13
|
+
ProtectHome=read-only
|
|
14
|
+
ReadWritePaths=%h/.skcapstone %h/.skmemory
|
|
15
|
+
PrivateTmp=true
|
|
16
|
+
|
|
17
|
+
Environment=PYTHONUNBUFFERED=1
|
|
18
|
+
Environment=OLLAMA_KEEP_ALIVE=5m
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
[Unit]
|
|
2
|
+
Description=SKCapstone Sovereign Agent Daemon
|
|
3
|
+
Documentation=https://github.com/smilinTux/skcapstone
|
|
4
|
+
After=network-online.target ollama.service syncthing.service
|
|
5
|
+
Wants=network-online.target
|
|
6
|
+
|
|
7
|
+
[Service]
|
|
8
|
+
Type=simple
|
|
9
|
+
ExecStart=%h/.skenv/bin/skcapstone daemon start --foreground
|
|
10
|
+
ExecStop=%h/.skenv/bin/skcapstone daemon stop
|
|
11
|
+
ExecReload=/bin/kill -HUP $MAINPID
|
|
12
|
+
Restart=on-failure
|
|
13
|
+
RestartSec=10
|
|
14
|
+
# Cap memory to prevent OOM from large model loading
|
|
15
|
+
MemoryMax=4G
|
|
16
|
+
# Keep Ollama models warm for 5 minutes between requests
|
|
17
|
+
Environment=PYTHONUNBUFFERED=1
|
|
18
|
+
Environment=OLLAMA_KEEP_ALIVE=5m
|
|
19
|
+
Environment=SKCAPSTONE_AGENT=lumina
|
|
20
|
+
# Journal logging
|
|
21
|
+
StandardOutput=journal
|
|
22
|
+
StandardError=journal
|
|
23
|
+
SyslogIdentifier=skcapstone
|
|
24
|
+
|
|
25
|
+
# Security hardening
|
|
26
|
+
NoNewPrivileges=true
|
|
27
|
+
ProtectSystem=strict
|
|
28
|
+
ProtectHome=read-only
|
|
29
|
+
ReadWritePaths=%h/.skcapstone %h/.skenv %h/.capauth %h/.cloud9 %h/.skcomm %h/.skchat
|
|
30
|
+
PrivateTmp=true
|
|
31
|
+
ProtectKernelTunables=true
|
|
32
|
+
ProtectControlGroups=true
|
|
33
|
+
|
|
34
|
+
[Install]
|
|
35
|
+
WantedBy=default.target
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# SKCapstone multi-agent systemd template unit.
|
|
2
|
+
#
|
|
3
|
+
# Each named agent runs as a separate service instance:
|
|
4
|
+
#
|
|
5
|
+
# systemctl --user enable skcapstone@opus skcapstone@jarvis
|
|
6
|
+
# systemctl --user start skcapstone@opus skcapstone@jarvis
|
|
7
|
+
#
|
|
8
|
+
# The instance name (%i) is passed to --agent so the daemon picks up
|
|
9
|
+
# ~/.skcapstone/agents/%i/ as its home directory and auto-assigns a port.
|
|
10
|
+
#
|
|
11
|
+
# Stop a single agent:
|
|
12
|
+
# systemctl --user stop skcapstone@jarvis
|
|
13
|
+
|
|
14
|
+
[Unit]
|
|
15
|
+
Description=SKCapstone Sovereign Agent — %i
|
|
16
|
+
Documentation=https://github.com/smilinTux/skcapstone
|
|
17
|
+
After=network-online.target ollama.service syncthing.service
|
|
18
|
+
Wants=network-online.target
|
|
19
|
+
# Multiple instances may coexist; no conflicts between them.
|
|
20
|
+
|
|
21
|
+
[Service]
|
|
22
|
+
Type=notify
|
|
23
|
+
ExecStart=skcapstone daemon start --agent %i --foreground
|
|
24
|
+
ExecStop=skcapstone daemon stop --agent %i
|
|
25
|
+
ExecReload=/bin/kill -HUP $MAINPID
|
|
26
|
+
Restart=on-failure
|
|
27
|
+
RestartSec=10
|
|
28
|
+
# Watchdog: daemon must call sd_notify("WATCHDOG=1") at least every 5 minutes
|
|
29
|
+
WatchdogSec=300
|
|
30
|
+
# Pass instance name as env var so imported modules that read SKCAPSTONE_AGENT
|
|
31
|
+
# resolve the correct per-agent home even before the CLI flag is processed.
|
|
32
|
+
Environment=PYTHONUNBUFFERED=1
|
|
33
|
+
Environment=OLLAMA_KEEP_ALIVE=5m
|
|
34
|
+
Environment=SKCAPSTONE_AGENT=%i
|
|
35
|
+
# Journal logging — logs appear under skcapstone@<instance>
|
|
36
|
+
StandardOutput=journal
|
|
37
|
+
StandardError=journal
|
|
38
|
+
SyslogIdentifier=skcapstone@%i
|
|
39
|
+
|
|
40
|
+
# Security hardening (same as single-agent unit)
|
|
41
|
+
NoNewPrivileges=true
|
|
42
|
+
ProtectSystem=strict
|
|
43
|
+
ProtectHome=read-only
|
|
44
|
+
ReadWritePaths=%h/.skcapstone %h/.skmemory %h/.capauth %h/.cloud9 %h/.skcomm %h/.skchat
|
|
45
|
+
PrivateTmp=true
|
|
46
|
+
ProtectKernelTunables=true
|
|
47
|
+
ProtectControlGroups=true
|
|
48
|
+
|
|
49
|
+
[Install]
|
|
50
|
+
WantedBy=default.target
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[Unit]
|
|
2
|
+
Description=SKComm Heartbeat Emission
|
|
3
|
+
Documentation=https://github.com/smilinTux/skcomm
|
|
4
|
+
After=network-online.target
|
|
5
|
+
|
|
6
|
+
[Service]
|
|
7
|
+
Type=oneshot
|
|
8
|
+
ExecStart=skcomm heartbeat --no-emit
|
|
9
|
+
ExecStart=skcomm heartbeat
|
|
10
|
+
Nice=19
|
|
11
|
+
|
|
12
|
+
NoNewPrivileges=true
|
|
13
|
+
ProtectSystem=strict
|
|
14
|
+
ProtectHome=read-only
|
|
15
|
+
ReadWritePaths=%h/.skcapstone %h/.skcomm
|
|
16
|
+
PrivateTmp=true
|
|
17
|
+
|
|
18
|
+
Environment=PYTHONUNBUFFERED=1
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[Unit]
|
|
2
|
+
Description=SKComm Heartbeat Timer — periodic liveness announcements
|
|
3
|
+
Documentation=https://github.com/smilinTux/skcomm
|
|
4
|
+
|
|
5
|
+
[Timer]
|
|
6
|
+
OnBootSec=30s
|
|
7
|
+
OnUnitActiveSec=60s
|
|
8
|
+
RandomizedDelaySec=10s
|
|
9
|
+
Persistent=true
|
|
10
|
+
|
|
11
|
+
[Install]
|
|
12
|
+
WantedBy=timers.target
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
[Unit]
|
|
2
|
+
Description=SKComm Queue Drain — retry undelivered messages
|
|
3
|
+
Documentation=https://github.com/smilinTux/skcomm
|
|
4
|
+
After=network-online.target
|
|
5
|
+
|
|
6
|
+
[Service]
|
|
7
|
+
Type=oneshot
|
|
8
|
+
ExecStart=skcomm queue drain
|
|
9
|
+
Nice=19
|
|
10
|
+
|
|
11
|
+
NoNewPrivileges=true
|
|
12
|
+
ProtectSystem=strict
|
|
13
|
+
ProtectHome=read-only
|
|
14
|
+
ReadWritePaths=%h/.skcapstone %h/.skcomm
|
|
15
|
+
PrivateTmp=true
|
|
16
|
+
|
|
17
|
+
Environment=PYTHONUNBUFFERED=1
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[Unit]
|
|
2
|
+
Description=SKComm Queue Drain Timer — periodic message retry
|
|
3
|
+
Documentation=https://github.com/smilinTux/skcomm
|
|
4
|
+
|
|
5
|
+
[Timer]
|
|
6
|
+
OnBootSec=60s
|
|
7
|
+
OnUnitActiveSec=120s
|
|
8
|
+
RandomizedDelaySec=15s
|
|
9
|
+
Persistent=true
|
|
10
|
+
|
|
11
|
+
[Install]
|
|
12
|
+
WantedBy=timers.target
|
package/src/skcapstone/doctor.py
CHANGED
|
@@ -162,6 +162,17 @@ def _check_packages() -> list[Check]:
|
|
|
162
162
|
category="packages",
|
|
163
163
|
)
|
|
164
164
|
)
|
|
165
|
+
except (ValueError, RuntimeError, OSError) as exc:
|
|
166
|
+
# Package installed but failed to initialize (e.g. no agent configured)
|
|
167
|
+
checks.append(
|
|
168
|
+
Check(
|
|
169
|
+
name=f"pkg:{pkg_name}",
|
|
170
|
+
description=desc,
|
|
171
|
+
passed=True,
|
|
172
|
+
detail=f"installed (init pending: {exc})",
|
|
173
|
+
category="packages",
|
|
174
|
+
)
|
|
175
|
+
)
|
|
165
176
|
|
|
166
177
|
return checks
|
|
167
178
|
|