superlocalmemory 3.2.2 → 3.3.0
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/CHANGELOG.md +43 -1
- package/README.md +106 -71
- package/package.json +1 -2
- package/pyproject.toml +16 -1
- package/src/superlocalmemory/cli/commands.py +309 -0
- package/src/superlocalmemory/cli/main.py +44 -0
- package/src/superlocalmemory/core/config.py +282 -11
- package/src/superlocalmemory/core/consolidation_engine.py +37 -0
- package/src/superlocalmemory/core/engine.py +21 -0
- package/src/superlocalmemory/core/engine_wiring.py +58 -8
- package/src/superlocalmemory/dynamics/activation_guided_quantization.py +374 -0
- package/src/superlocalmemory/dynamics/eap_scheduler.py +276 -0
- package/src/superlocalmemory/dynamics/ebbinghaus_langevin_coupling.py +171 -0
- package/src/superlocalmemory/encoding/cognitive_consolidator.py +804 -0
- package/src/superlocalmemory/hooks/auto_invoker.py +46 -8
- package/src/superlocalmemory/hooks/auto_parameterize.py +147 -0
- package/src/superlocalmemory/infra/heartbeat_monitor.py +140 -0
- package/src/superlocalmemory/infra/pid_manager.py +193 -0
- package/src/superlocalmemory/infra/process_reaper.py +572 -0
- package/src/superlocalmemory/learning/consolidation_quantization_worker.py +115 -0
- package/src/superlocalmemory/learning/forgetting_scheduler.py +263 -0
- package/src/superlocalmemory/learning/quantization_scheduler.py +320 -0
- package/src/superlocalmemory/math/ebbinghaus.py +309 -0
- package/src/superlocalmemory/math/fisher_quantized.py +251 -0
- package/src/superlocalmemory/math/hopfield.py +279 -0
- package/src/superlocalmemory/math/polar_quant.py +379 -0
- package/src/superlocalmemory/math/qjl.py +115 -0
- package/src/superlocalmemory/mcp/server.py +2 -0
- package/src/superlocalmemory/mcp/tools_v3.py +10 -0
- package/src/superlocalmemory/mcp/tools_v33.py +351 -0
- package/src/superlocalmemory/parameterization/__init__.py +47 -0
- package/src/superlocalmemory/parameterization/pattern_extractor.py +534 -0
- package/src/superlocalmemory/parameterization/pii_filter.py +106 -0
- package/src/superlocalmemory/parameterization/prompt_injector.py +216 -0
- package/src/superlocalmemory/parameterization/prompt_lifecycle.py +275 -0
- package/src/superlocalmemory/parameterization/soft_prompt_generator.py +425 -0
- package/src/superlocalmemory/retrieval/engine.py +21 -3
- package/src/superlocalmemory/retrieval/forgetting_filter.py +145 -0
- package/src/superlocalmemory/retrieval/hopfield_channel.py +335 -0
- package/src/superlocalmemory/retrieval/quantization_aware_search.py +133 -0
- package/src/superlocalmemory/retrieval/spreading_activation.py +1 -1
- package/src/superlocalmemory/retrieval/strategy.py +16 -6
- package/src/superlocalmemory/retrieval/vector_store.py +1 -1
- package/src/superlocalmemory/server/routes/agents.py +68 -8
- package/src/superlocalmemory/server/routes/learning.py +18 -1
- package/src/superlocalmemory/server/routes/lifecycle.py +36 -17
- package/src/superlocalmemory/server/routes/v3_api.py +503 -1
- package/src/superlocalmemory/storage/database.py +206 -0
- package/src/superlocalmemory/storage/embedding_migrator.py +178 -0
- package/src/superlocalmemory/storage/migration_v33.py +140 -0
- package/src/superlocalmemory/storage/quantized_store.py +261 -0
- package/src/superlocalmemory/storage/schema_v32.py +137 -0
- package/conftest.py +0 -5
|
@@ -41,6 +41,12 @@ def dispatch(args: Namespace) -> None:
|
|
|
41
41
|
"hooks": cmd_hooks,
|
|
42
42
|
"session-context": cmd_session_context,
|
|
43
43
|
"observe": cmd_observe,
|
|
44
|
+
# V3.3 commands
|
|
45
|
+
"decay": cmd_decay,
|
|
46
|
+
"quantize": cmd_quantize,
|
|
47
|
+
"consolidate": cmd_consolidate,
|
|
48
|
+
"soft-prompts": cmd_soft_prompts,
|
|
49
|
+
"reap": cmd_reap,
|
|
44
50
|
}
|
|
45
51
|
handler = handlers.get(args.command)
|
|
46
52
|
if handler:
|
|
@@ -102,6 +108,11 @@ def cmd_mode(args: Namespace) -> None:
|
|
|
102
108
|
)
|
|
103
109
|
updated.save()
|
|
104
110
|
print(f"Mode set to: {args.value.upper()}")
|
|
111
|
+
|
|
112
|
+
# V3.3: Check if embedding model changed — inform about re-indexing
|
|
113
|
+
if (config.embedding.provider != updated.embedding.provider
|
|
114
|
+
or config.embedding.model_name != updated.embedding.model_name):
|
|
115
|
+
print(" ⚠ Embedding model changed. Re-indexing will run on next recall.")
|
|
105
116
|
else:
|
|
106
117
|
print(f"Current mode: {config.mode.value.upper()}")
|
|
107
118
|
|
|
@@ -1174,3 +1185,301 @@ def cmd_observe(args: Namespace) -> None:
|
|
|
1174
1185
|
print(f"Not captured: {decision.reason}")
|
|
1175
1186
|
except Exception as exc:
|
|
1176
1187
|
logger.debug("observe failed: %s", exc)
|
|
1188
|
+
|
|
1189
|
+
|
|
1190
|
+
# -- V3.3 Commands -----------------------------------------------------------
|
|
1191
|
+
|
|
1192
|
+
|
|
1193
|
+
def cmd_decay(args: Namespace) -> None:
|
|
1194
|
+
"""Run Ebbinghaus forgetting decay cycle."""
|
|
1195
|
+
from superlocalmemory.core.config import SLMConfig
|
|
1196
|
+
from superlocalmemory.core.engine import MemoryEngine
|
|
1197
|
+
|
|
1198
|
+
use_json = getattr(args, "json", False)
|
|
1199
|
+
dry_run = getattr(args, "dry_run", True)
|
|
1200
|
+
profile = getattr(args, "profile", "")
|
|
1201
|
+
|
|
1202
|
+
try:
|
|
1203
|
+
config = SLMConfig.load()
|
|
1204
|
+
engine = MemoryEngine(config)
|
|
1205
|
+
engine.initialize()
|
|
1206
|
+
pid = profile or engine.profile_id
|
|
1207
|
+
|
|
1208
|
+
from superlocalmemory.math.ebbinghaus import EbbinghausCurve
|
|
1209
|
+
from superlocalmemory.learning.forgetting_scheduler import (
|
|
1210
|
+
ForgettingScheduler,
|
|
1211
|
+
)
|
|
1212
|
+
|
|
1213
|
+
ebbinghaus = EbbinghausCurve(config.forgetting)
|
|
1214
|
+
scheduler = ForgettingScheduler(
|
|
1215
|
+
engine._db, ebbinghaus, config.forgetting,
|
|
1216
|
+
)
|
|
1217
|
+
result = scheduler.run_decay_cycle(pid, force=True)
|
|
1218
|
+
except Exception as exc:
|
|
1219
|
+
if use_json:
|
|
1220
|
+
from superlocalmemory.cli.json_output import json_print
|
|
1221
|
+
json_print("decay", error={"code": "DECAY_ERROR", "message": str(exc)})
|
|
1222
|
+
sys.exit(1)
|
|
1223
|
+
raise
|
|
1224
|
+
|
|
1225
|
+
if use_json:
|
|
1226
|
+
from superlocalmemory.cli.json_output import json_print
|
|
1227
|
+
json_print("decay", data={"dry_run": dry_run, **result},
|
|
1228
|
+
next_actions=[
|
|
1229
|
+
{"command": "slm decay --execute --json", "description": "Apply transitions"},
|
|
1230
|
+
{"command": "slm status --json", "description": "Check system status"},
|
|
1231
|
+
])
|
|
1232
|
+
return
|
|
1233
|
+
|
|
1234
|
+
if result.get("skipped"):
|
|
1235
|
+
print(f"Skipped: {result.get('reason', 'unknown')}")
|
|
1236
|
+
return
|
|
1237
|
+
|
|
1238
|
+
total = result.get("total", 0)
|
|
1239
|
+
print(f"Decay cycle complete (dry_run={dry_run})")
|
|
1240
|
+
print(f" Total facts: {total}")
|
|
1241
|
+
print(f" Active: {result.get('active', 0)}")
|
|
1242
|
+
print(f" Warm: {result.get('warm', 0)}")
|
|
1243
|
+
print(f" Cold: {result.get('cold', 0)}")
|
|
1244
|
+
print(f" Archive: {result.get('archive', 0)}")
|
|
1245
|
+
print(f" Forgotten: {result.get('forgotten', 0)}")
|
|
1246
|
+
print(f" Transitions: {result.get('transitions', 0)}")
|
|
1247
|
+
|
|
1248
|
+
|
|
1249
|
+
def cmd_quantize(args: Namespace) -> None:
|
|
1250
|
+
"""Run EAP embedding quantization cycle."""
|
|
1251
|
+
from superlocalmemory.core.config import SLMConfig
|
|
1252
|
+
from superlocalmemory.core.engine import MemoryEngine
|
|
1253
|
+
|
|
1254
|
+
use_json = getattr(args, "json", False)
|
|
1255
|
+
dry_run = getattr(args, "dry_run", True)
|
|
1256
|
+
profile = getattr(args, "profile", "")
|
|
1257
|
+
|
|
1258
|
+
try:
|
|
1259
|
+
config = SLMConfig.load()
|
|
1260
|
+
engine = MemoryEngine(config)
|
|
1261
|
+
engine.initialize()
|
|
1262
|
+
pid = profile or engine.profile_id
|
|
1263
|
+
|
|
1264
|
+
from superlocalmemory.math.ebbinghaus import EbbinghausCurve
|
|
1265
|
+
from superlocalmemory.dynamics.eap_scheduler import EAPScheduler
|
|
1266
|
+
from superlocalmemory.storage.quantized_store import (
|
|
1267
|
+
QuantizedEmbeddingStore,
|
|
1268
|
+
)
|
|
1269
|
+
|
|
1270
|
+
from superlocalmemory.math.polar_quant import PolarQuantEncoder
|
|
1271
|
+
from superlocalmemory.math.qjl import QJLEncoder
|
|
1272
|
+
|
|
1273
|
+
ebbinghaus = EbbinghausCurve(config.forgetting)
|
|
1274
|
+
polar = PolarQuantEncoder(config.quantization.polar)
|
|
1275
|
+
qjl = QJLEncoder(config.quantization.qjl)
|
|
1276
|
+
qstore = QuantizedEmbeddingStore(
|
|
1277
|
+
engine._db, polar, qjl, config.quantization,
|
|
1278
|
+
)
|
|
1279
|
+
scheduler = EAPScheduler(
|
|
1280
|
+
engine._db, ebbinghaus, qstore, config.quantization,
|
|
1281
|
+
)
|
|
1282
|
+
result = scheduler.run_eap_cycle(pid)
|
|
1283
|
+
except Exception as exc:
|
|
1284
|
+
if use_json:
|
|
1285
|
+
from superlocalmemory.cli.json_output import json_print
|
|
1286
|
+
json_print("quantize", error={"code": "EAP_ERROR", "message": str(exc)})
|
|
1287
|
+
sys.exit(1)
|
|
1288
|
+
raise
|
|
1289
|
+
|
|
1290
|
+
if use_json:
|
|
1291
|
+
from superlocalmemory.cli.json_output import json_print
|
|
1292
|
+
json_print("quantize", data={"dry_run": dry_run, **result},
|
|
1293
|
+
next_actions=[
|
|
1294
|
+
{"command": "slm quantize --execute --json", "description": "Apply changes"},
|
|
1295
|
+
{"command": "slm status --json", "description": "Check status"},
|
|
1296
|
+
])
|
|
1297
|
+
return
|
|
1298
|
+
|
|
1299
|
+
print(f"EAP quantization cycle (dry_run={dry_run})")
|
|
1300
|
+
print(f" Total: {result.get('total', 0)}")
|
|
1301
|
+
print(f" Downgrades: {result.get('downgrades', 0)}")
|
|
1302
|
+
print(f" Upgrades: {result.get('upgrades', 0)}")
|
|
1303
|
+
print(f" Skipped: {result.get('skipped', 0)}")
|
|
1304
|
+
print(f" Errors: {result.get('errors', 0)}")
|
|
1305
|
+
|
|
1306
|
+
|
|
1307
|
+
def cmd_consolidate(args: Namespace) -> None:
|
|
1308
|
+
"""Run cognitive consolidation pipeline."""
|
|
1309
|
+
from superlocalmemory.core.config import SLMConfig
|
|
1310
|
+
from superlocalmemory.core.engine import MemoryEngine
|
|
1311
|
+
|
|
1312
|
+
use_json = getattr(args, "json", False)
|
|
1313
|
+
cognitive = getattr(args, "cognitive", False)
|
|
1314
|
+
profile = getattr(args, "profile", "")
|
|
1315
|
+
|
|
1316
|
+
if not cognitive:
|
|
1317
|
+
if use_json:
|
|
1318
|
+
from superlocalmemory.cli.json_output import json_print
|
|
1319
|
+
json_print("consolidate", error={
|
|
1320
|
+
"code": "MISSING_FLAG",
|
|
1321
|
+
"message": "Use --cognitive to run CCQ pipeline",
|
|
1322
|
+
})
|
|
1323
|
+
sys.exit(1)
|
|
1324
|
+
print("Use --cognitive to run CCQ consolidation pipeline.")
|
|
1325
|
+
print(" slm consolidate --cognitive")
|
|
1326
|
+
return
|
|
1327
|
+
|
|
1328
|
+
try:
|
|
1329
|
+
config = SLMConfig.load()
|
|
1330
|
+
engine = MemoryEngine(config)
|
|
1331
|
+
engine.initialize()
|
|
1332
|
+
pid = profile or engine.profile_id
|
|
1333
|
+
|
|
1334
|
+
from superlocalmemory.encoding.cognitive_consolidator import (
|
|
1335
|
+
CognitiveConsolidator,
|
|
1336
|
+
)
|
|
1337
|
+
|
|
1338
|
+
consolidator = CognitiveConsolidator(db=engine._db)
|
|
1339
|
+
result = consolidator.run_pipeline(pid)
|
|
1340
|
+
except Exception as exc:
|
|
1341
|
+
if use_json:
|
|
1342
|
+
from superlocalmemory.cli.json_output import json_print
|
|
1343
|
+
json_print("consolidate", error={
|
|
1344
|
+
"code": "CCQ_ERROR", "message": str(exc),
|
|
1345
|
+
})
|
|
1346
|
+
sys.exit(1)
|
|
1347
|
+
raise
|
|
1348
|
+
|
|
1349
|
+
if use_json:
|
|
1350
|
+
from superlocalmemory.cli.json_output import json_print
|
|
1351
|
+
json_print("consolidate", data={
|
|
1352
|
+
"clusters_found": result.clusters_found,
|
|
1353
|
+
"blocks_created": result.blocks_created,
|
|
1354
|
+
"facts_archived": result.facts_archived,
|
|
1355
|
+
"compression_ratio": round(result.compression_ratio, 3),
|
|
1356
|
+
}, next_actions=[
|
|
1357
|
+
{"command": "slm list --json", "description": "List recent memories"},
|
|
1358
|
+
{"command": "slm status --json", "description": "Check status"},
|
|
1359
|
+
])
|
|
1360
|
+
return
|
|
1361
|
+
|
|
1362
|
+
print("CCQ Cognitive Consolidation")
|
|
1363
|
+
print(f" Clusters found: {result.clusters_found}")
|
|
1364
|
+
print(f" Blocks created: {result.blocks_created}")
|
|
1365
|
+
print(f" Facts archived: {result.facts_archived}")
|
|
1366
|
+
print(f" Compression ratio: {result.compression_ratio:.3f}")
|
|
1367
|
+
|
|
1368
|
+
|
|
1369
|
+
def cmd_soft_prompts(args: Namespace) -> None:
|
|
1370
|
+
"""List active soft prompts (auto-learned user patterns)."""
|
|
1371
|
+
from superlocalmemory.core.config import SLMConfig
|
|
1372
|
+
from superlocalmemory.core.engine import MemoryEngine
|
|
1373
|
+
|
|
1374
|
+
use_json = getattr(args, "json", False)
|
|
1375
|
+
profile = getattr(args, "profile", "")
|
|
1376
|
+
|
|
1377
|
+
try:
|
|
1378
|
+
config = SLMConfig.load()
|
|
1379
|
+
engine = MemoryEngine(config)
|
|
1380
|
+
engine.initialize()
|
|
1381
|
+
pid = profile or engine.profile_id
|
|
1382
|
+
|
|
1383
|
+
rows = engine._db.execute(
|
|
1384
|
+
"SELECT prompt_id, category, content, confidence, "
|
|
1385
|
+
" effectiveness, token_count, version, created_at "
|
|
1386
|
+
"FROM soft_prompt_templates "
|
|
1387
|
+
"WHERE profile_id = ? AND active = 1 "
|
|
1388
|
+
"ORDER BY confidence DESC",
|
|
1389
|
+
(pid,),
|
|
1390
|
+
)
|
|
1391
|
+
prompts = []
|
|
1392
|
+
for row in rows:
|
|
1393
|
+
r = dict(row)
|
|
1394
|
+
prompts.append({
|
|
1395
|
+
"prompt_id": r["prompt_id"],
|
|
1396
|
+
"category": r["category"],
|
|
1397
|
+
"content": r["content"],
|
|
1398
|
+
"confidence": round(float(r["confidence"]), 3),
|
|
1399
|
+
"effectiveness": round(float(r["effectiveness"]), 3),
|
|
1400
|
+
"token_count": int(r["token_count"]),
|
|
1401
|
+
"version": int(r["version"]),
|
|
1402
|
+
"created_at": r["created_at"],
|
|
1403
|
+
})
|
|
1404
|
+
except Exception as exc:
|
|
1405
|
+
if use_json:
|
|
1406
|
+
from superlocalmemory.cli.json_output import json_print
|
|
1407
|
+
json_print("soft-prompts", error={
|
|
1408
|
+
"code": "QUERY_ERROR", "message": str(exc),
|
|
1409
|
+
})
|
|
1410
|
+
sys.exit(1)
|
|
1411
|
+
raise
|
|
1412
|
+
|
|
1413
|
+
if use_json:
|
|
1414
|
+
from superlocalmemory.cli.json_output import json_print
|
|
1415
|
+
json_print("soft-prompts", data={
|
|
1416
|
+
"prompts": prompts, "count": len(prompts), "profile": pid,
|
|
1417
|
+
}, next_actions=[
|
|
1418
|
+
{"command": "slm status --json", "description": "Check status"},
|
|
1419
|
+
])
|
|
1420
|
+
return
|
|
1421
|
+
|
|
1422
|
+
if not prompts:
|
|
1423
|
+
print("No active soft prompts.")
|
|
1424
|
+
return
|
|
1425
|
+
|
|
1426
|
+
print(f"Active soft prompts ({len(prompts)}):\n")
|
|
1427
|
+
for i, p in enumerate(prompts, 1):
|
|
1428
|
+
print(f" {i}. [{p['category']}] (conf={p['confidence']:.2f})")
|
|
1429
|
+
content_preview = p["content"][:100]
|
|
1430
|
+
if len(p["content"]) > 100:
|
|
1431
|
+
content_preview += "..."
|
|
1432
|
+
print(f" {content_preview}")
|
|
1433
|
+
|
|
1434
|
+
|
|
1435
|
+
def cmd_reap(args: Namespace) -> None:
|
|
1436
|
+
"""Find and kill orphaned SLM processes."""
|
|
1437
|
+
use_json = getattr(args, "json", False)
|
|
1438
|
+
dry_run = not getattr(args, "force", False)
|
|
1439
|
+
|
|
1440
|
+
try:
|
|
1441
|
+
from superlocalmemory.infra.process_reaper import (
|
|
1442
|
+
cleanup_all_orphans,
|
|
1443
|
+
ReaperConfig,
|
|
1444
|
+
)
|
|
1445
|
+
|
|
1446
|
+
config = ReaperConfig()
|
|
1447
|
+
result = cleanup_all_orphans(config, dry_run=dry_run)
|
|
1448
|
+
except Exception as exc:
|
|
1449
|
+
if use_json:
|
|
1450
|
+
from superlocalmemory.cli.json_output import json_print
|
|
1451
|
+
json_print("reap", error={
|
|
1452
|
+
"code": "REAP_ERROR", "message": str(exc),
|
|
1453
|
+
})
|
|
1454
|
+
sys.exit(1)
|
|
1455
|
+
raise
|
|
1456
|
+
|
|
1457
|
+
if use_json:
|
|
1458
|
+
from superlocalmemory.cli.json_output import json_print
|
|
1459
|
+
json_print("reap", data={
|
|
1460
|
+
"dry_run": dry_run,
|
|
1461
|
+
"total_found": result.get("total_found", 0),
|
|
1462
|
+
"orphans_found": result.get("orphans_found", 0),
|
|
1463
|
+
"killed": result.get("killed", 0),
|
|
1464
|
+
"skipped": result.get("skipped", 0),
|
|
1465
|
+
}, next_actions=[
|
|
1466
|
+
{"command": "slm reap --force --json", "description": "Kill orphans"},
|
|
1467
|
+
{"command": "slm status --json", "description": "Check status"},
|
|
1468
|
+
])
|
|
1469
|
+
return
|
|
1470
|
+
|
|
1471
|
+
total = result.get("total_found", 0)
|
|
1472
|
+
orphans = result.get("orphans_found", 0)
|
|
1473
|
+
killed = result.get("killed", 0)
|
|
1474
|
+
skipped = result.get("skipped", 0)
|
|
1475
|
+
|
|
1476
|
+
if dry_run:
|
|
1477
|
+
print(f"Process reaper (dry run)")
|
|
1478
|
+
else:
|
|
1479
|
+
print(f"Process reaper")
|
|
1480
|
+
print(f" Total SLM processes: {total}")
|
|
1481
|
+
print(f" Orphans found: {orphans}")
|
|
1482
|
+
print(f" Killed: {killed}")
|
|
1483
|
+
print(f" Skipped: {skipped}")
|
|
1484
|
+
if dry_run and orphans > 0:
|
|
1485
|
+
print("\n Use --force to kill orphaned processes.")
|
|
@@ -187,6 +187,50 @@ def main() -> None:
|
|
|
187
187
|
obs_p = sub.add_parser("observe", help="Auto-capture content (pipe or argument)")
|
|
188
188
|
obs_p.add_argument("content", nargs="?", default="", help="Content to evaluate")
|
|
189
189
|
|
|
190
|
+
# -- V3.3 Commands -------------------------------------------------
|
|
191
|
+
decay_p = sub.add_parser("decay", help="Run Ebbinghaus forgetting decay cycle")
|
|
192
|
+
decay_p.add_argument(
|
|
193
|
+
"--dry-run", action="store_true", default=True,
|
|
194
|
+
help="Preview without applying (default)",
|
|
195
|
+
)
|
|
196
|
+
decay_p.add_argument(
|
|
197
|
+
"--execute", dest="dry_run", action="store_false",
|
|
198
|
+
help="Apply zone transitions",
|
|
199
|
+
)
|
|
200
|
+
decay_p.add_argument("--profile", default="", help="Target profile")
|
|
201
|
+
decay_p.add_argument("--json", action="store_true", help="Output structured JSON (agent-native)")
|
|
202
|
+
|
|
203
|
+
quantize_p = sub.add_parser("quantize", help="Run EAP embedding quantization cycle")
|
|
204
|
+
quantize_p.add_argument(
|
|
205
|
+
"--dry-run", action="store_true", default=True,
|
|
206
|
+
help="Preview without applying (default)",
|
|
207
|
+
)
|
|
208
|
+
quantize_p.add_argument(
|
|
209
|
+
"--execute", dest="dry_run", action="store_false",
|
|
210
|
+
help="Apply precision changes",
|
|
211
|
+
)
|
|
212
|
+
quantize_p.add_argument("--profile", default="", help="Target profile")
|
|
213
|
+
quantize_p.add_argument("--json", action="store_true", help="Output structured JSON (agent-native)")
|
|
214
|
+
|
|
215
|
+
consolidate_p = sub.add_parser("consolidate", help="Run memory consolidation pipeline")
|
|
216
|
+
consolidate_p.add_argument(
|
|
217
|
+
"--cognitive", action="store_true",
|
|
218
|
+
help="Run CCQ cognitive consolidation",
|
|
219
|
+
)
|
|
220
|
+
consolidate_p.add_argument("--profile", default="", help="Target profile")
|
|
221
|
+
consolidate_p.add_argument("--json", action="store_true", help="Output structured JSON (agent-native)")
|
|
222
|
+
|
|
223
|
+
sp_p = sub.add_parser("soft-prompts", help="List active soft prompts (auto-learned patterns)")
|
|
224
|
+
sp_p.add_argument("--profile", default="", help="Target profile")
|
|
225
|
+
sp_p.add_argument("--json", action="store_true", help="Output structured JSON (agent-native)")
|
|
226
|
+
|
|
227
|
+
reap_p = sub.add_parser("reap", help="Find and kill orphaned SLM processes")
|
|
228
|
+
reap_p.add_argument(
|
|
229
|
+
"--force", action="store_true",
|
|
230
|
+
help="Kill orphans (default: dry run only)",
|
|
231
|
+
)
|
|
232
|
+
reap_p.add_argument("--json", action="store_true", help="Output structured JSON (agent-native)")
|
|
233
|
+
|
|
190
234
|
args = parser.parse_args()
|
|
191
235
|
|
|
192
236
|
if not args.command:
|