get-claudia 1.55.21 → 1.57.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 +79 -0
- package/bin/index.js +213 -5
- package/bin/manifest-lib.js +245 -0
- package/memory-daemon/claudia_memory/daemon/health.py +1 -1
- package/memory-daemon/claudia_memory/daemon/scheduler.py +1 -1
- package/memory-daemon/claudia_memory/mcp/server.py +132 -123
- package/memory-daemon/claudia_memory/services/consolidate.py +1 -1
- package/memory-daemon/claudia_memory/services/remember.py +1 -1
- package/package.json +6 -2
- package/template-v2/.claude/hooks/__pycache__/post-tool-capture.cpython-313.pyc +0 -0
- package/template-v2/.claude/hooks/__pycache__/session-health-check.cpython-313.pyc +0 -0
- package/template-v2/.claude/hooks/__pycache__/user-prompt-capture.cpython-313.pyc +0 -0
- package/template-v2/.claude/hooks/hooks.json +11 -11
- package/template-v2/.claude/hooks/post-tool-capture.py +110 -10
- package/template-v2/.claude/hooks/pre-compact.py +4 -4
- package/template-v2/.claude/hooks/pre-compact.sh +1 -1
- package/template-v2/.claude/hooks/session-health-check.py +52 -4
- package/template-v2/.claude/hooks/session-summary.py +399 -0
- package/template-v2/.claude/hooks/user-prompt-capture.py +123 -0
- package/template-v2/.claude/manifest.json +73 -0
- package/template-v2/.claude/rules/claudia-principles.md +2 -2
- package/template-v2/.claude/rules/memory-availability.md +3 -3
- package/template-v2/.claude/rules/memory-commitment.md +92 -0
- package/template-v2/.claude/settings.local.json +26 -0
- package/template-v2/.claude/skills/capture-meeting/SKILL.md +6 -6
- package/template-v2/.claude/skills/capture-meeting/evals/basic.yaml +1 -1
- package/template-v2/.claude/skills/deep-context/SKILL.md +7 -7
- package/template-v2/.claude/skills/meditate/SKILL.md +10 -10
- package/template-v2/.claude/skills/meditate/evals/basic.yaml +1 -1
- package/template-v2/.claude/skills/meeting-prep/SKILL.md +3 -3
- package/template-v2/.claude/skills/memory-health/SKILL.md +1 -1
- package/template-v2/.claude/skills/memory-manager.md +85 -85
- package/template-v2/.claude/skills/morning-brief/SKILL.md +10 -10
- package/template-v2/.claude/skills/research/SKILL.md +2 -2
- package/template-v2/.claude/skills/skill-index.json +1 -1
- package/template-v2/CLAUDE.md +6 -6
- package/template-v2/.claude/hooks/__pycache__/pre-compact.cpython-313.pyc +0 -0
- package/template-v2/gitignore +0 -35
|
@@ -158,17 +158,17 @@ def _guard_response_size(text: str, tool_name: str) -> str:
|
|
|
158
158
|
# They return a CallToolResult directly.
|
|
159
159
|
|
|
160
160
|
|
|
161
|
-
@_handler("
|
|
161
|
+
@_handler("memory_temporal", "memory_upcoming", "memory_since", "memory_timeline", "memory_morning_context")
|
|
162
162
|
async def _handle_temporal(arguments, db, config, logger, **ctx):
|
|
163
163
|
# Determine operation from merged tool or backward-compat alias
|
|
164
|
-
name = ctx.get("tool_name", "
|
|
165
|
-
if name == "
|
|
164
|
+
name = ctx.get("tool_name", "memory_temporal")
|
|
165
|
+
if name == "memory_upcoming":
|
|
166
166
|
op = "upcoming"
|
|
167
|
-
elif name == "
|
|
167
|
+
elif name == "memory_since":
|
|
168
168
|
op = "since"
|
|
169
|
-
elif name == "
|
|
169
|
+
elif name == "memory_timeline":
|
|
170
170
|
op = "timeline"
|
|
171
|
-
elif name == "
|
|
171
|
+
elif name == "memory_morning_context":
|
|
172
172
|
op = "morning"
|
|
173
173
|
else:
|
|
174
174
|
op = arguments.get("operation", "upcoming")
|
|
@@ -240,18 +240,18 @@ async def _handle_temporal(arguments, db, config, logger, **ctx):
|
|
|
240
240
|
)
|
|
241
241
|
|
|
242
242
|
|
|
243
|
-
@_handler("
|
|
243
|
+
@_handler("memory_graph", "memory_project_network", "memory_find_path", "memory_network_hubs", "memory_dormant_relationships", "memory_reconnections")
|
|
244
244
|
async def _handle_graph(arguments, db, config, logger, **ctx):
|
|
245
|
-
name = ctx.get("tool_name", "
|
|
246
|
-
if name == "
|
|
245
|
+
name = ctx.get("tool_name", "memory_graph")
|
|
246
|
+
if name == "memory_project_network":
|
|
247
247
|
op = "network"
|
|
248
|
-
elif name == "
|
|
248
|
+
elif name == "memory_find_path":
|
|
249
249
|
op = "path"
|
|
250
|
-
elif name == "
|
|
250
|
+
elif name == "memory_network_hubs":
|
|
251
251
|
op = "hubs"
|
|
252
|
-
elif name == "
|
|
252
|
+
elif name == "memory_dormant_relationships":
|
|
253
253
|
op = "dormant"
|
|
254
|
-
elif name == "
|
|
254
|
+
elif name == "memory_reconnections":
|
|
255
255
|
op = "reconnect"
|
|
256
256
|
else:
|
|
257
257
|
op = arguments.get("operation", "network")
|
|
@@ -347,18 +347,18 @@ async def _handle_graph(arguments, db, config, logger, **ctx):
|
|
|
347
347
|
)
|
|
348
348
|
|
|
349
349
|
|
|
350
|
-
@_handler("
|
|
350
|
+
@_handler("memory_entities", "memory_entity", "memory_search_entities", "memory_merge_entities", "memory_delete_entity", "memory_entity_overview")
|
|
351
351
|
async def _handle_entities(arguments, db, config, logger, **ctx):
|
|
352
|
-
name = ctx.get("tool_name", "
|
|
353
|
-
if name == "
|
|
352
|
+
name = ctx.get("tool_name", "memory_entities")
|
|
353
|
+
if name == "memory_entity":
|
|
354
354
|
op = "create"
|
|
355
|
-
elif name == "
|
|
355
|
+
elif name == "memory_search_entities":
|
|
356
356
|
op = "search"
|
|
357
|
-
elif name == "
|
|
357
|
+
elif name == "memory_merge_entities":
|
|
358
358
|
op = "merge"
|
|
359
|
-
elif name == "
|
|
359
|
+
elif name == "memory_delete_entity":
|
|
360
360
|
op = "delete"
|
|
361
|
-
elif name == "
|
|
361
|
+
elif name == "memory_entity_overview":
|
|
362
362
|
op = "overview"
|
|
363
363
|
else:
|
|
364
364
|
op = arguments.get("operation", "search")
|
|
@@ -438,16 +438,16 @@ async def _handle_entities(arguments, db, config, logger, **ctx):
|
|
|
438
438
|
)
|
|
439
439
|
|
|
440
440
|
|
|
441
|
-
@_handler("
|
|
441
|
+
@_handler("memory_vault", "memory_sync_vault", "memory_vault_status", "memory_generate_canvas", "memory_import_vault_edits")
|
|
442
442
|
async def _handle_vault(arguments, db, config, logger, **ctx):
|
|
443
|
-
name = ctx.get("tool_name", "
|
|
444
|
-
if name == "
|
|
443
|
+
name = ctx.get("tool_name", "memory_vault")
|
|
444
|
+
if name == "memory_sync_vault":
|
|
445
445
|
op = "sync"
|
|
446
|
-
elif name == "
|
|
446
|
+
elif name == "memory_vault_status":
|
|
447
447
|
op = "status"
|
|
448
|
-
elif name == "
|
|
448
|
+
elif name == "memory_generate_canvas":
|
|
449
449
|
op = "canvas"
|
|
450
|
-
elif name == "
|
|
450
|
+
elif name == "memory_import_vault_edits":
|
|
451
451
|
op = "import"
|
|
452
452
|
else:
|
|
453
453
|
op = arguments.get("operation", "status")
|
|
@@ -522,14 +522,14 @@ async def _handle_vault(arguments, db, config, logger, **ctx):
|
|
|
522
522
|
)
|
|
523
523
|
|
|
524
524
|
|
|
525
|
-
@_handler("
|
|
525
|
+
@_handler("memory_modify", "memory_correct", "memory_invalidate", "memory_invalidate_relationship")
|
|
526
526
|
async def _handle_modify(arguments, db, config, logger, **ctx):
|
|
527
|
-
name = ctx.get("tool_name", "
|
|
528
|
-
if name == "
|
|
527
|
+
name = ctx.get("tool_name", "memory_modify")
|
|
528
|
+
if name == "memory_correct":
|
|
529
529
|
op = "correct"
|
|
530
|
-
elif name == "
|
|
530
|
+
elif name == "memory_invalidate":
|
|
531
531
|
op = "invalidate"
|
|
532
|
-
elif name == "
|
|
532
|
+
elif name == "memory_invalidate_relationship":
|
|
533
533
|
op = "invalidate_relationship"
|
|
534
534
|
else:
|
|
535
535
|
op = arguments.get("operation", "correct")
|
|
@@ -570,14 +570,14 @@ async def _handle_modify(arguments, db, config, logger, **ctx):
|
|
|
570
570
|
)
|
|
571
571
|
|
|
572
572
|
|
|
573
|
-
@_handler("
|
|
573
|
+
@_handler("memory_session", "memory_buffer_turn", "memory_session_context", "memory_unsummarized")
|
|
574
574
|
async def _handle_session(arguments, db, config, logger, **ctx):
|
|
575
|
-
name = ctx.get("tool_name", "
|
|
576
|
-
if name == "
|
|
575
|
+
name = ctx.get("tool_name", "memory_session")
|
|
576
|
+
if name == "memory_buffer_turn":
|
|
577
577
|
op = "buffer"
|
|
578
|
-
elif name == "
|
|
578
|
+
elif name == "memory_session_context":
|
|
579
579
|
op = "context"
|
|
580
|
-
elif name == "
|
|
580
|
+
elif name == "memory_unsummarized":
|
|
581
581
|
op = "unsummarized"
|
|
582
582
|
else:
|
|
583
583
|
op = arguments.get("operation", "context")
|
|
@@ -614,14 +614,14 @@ async def _handle_session(arguments, db, config, logger, **ctx):
|
|
|
614
614
|
)
|
|
615
615
|
|
|
616
616
|
|
|
617
|
-
@_handler("
|
|
617
|
+
@_handler("memory_document", "memory_file", "memory_documents", "memory_purge")
|
|
618
618
|
async def _handle_document(arguments, db, config, logger, **ctx):
|
|
619
|
-
name = ctx.get("tool_name", "
|
|
620
|
-
if name == "
|
|
619
|
+
name = ctx.get("tool_name", "memory_document")
|
|
620
|
+
if name == "memory_file":
|
|
621
621
|
op = "store"
|
|
622
|
-
elif name == "
|
|
622
|
+
elif name == "memory_documents":
|
|
623
623
|
op = "search"
|
|
624
|
-
elif name == "
|
|
624
|
+
elif name == "memory_purge":
|
|
625
625
|
op = "purge"
|
|
626
626
|
else:
|
|
627
627
|
op = arguments.get("operation", "search")
|
|
@@ -667,12 +667,12 @@ async def _handle_document(arguments, db, config, logger, **ctx):
|
|
|
667
667
|
)
|
|
668
668
|
|
|
669
669
|
|
|
670
|
-
@_handler("
|
|
670
|
+
@_handler("memory_provenance", "memory_trace", "memory_audit_history")
|
|
671
671
|
async def _handle_provenance(arguments, db, config, logger, **ctx):
|
|
672
|
-
name = ctx.get("tool_name", "
|
|
673
|
-
if name == "
|
|
672
|
+
name = ctx.get("tool_name", "memory_provenance")
|
|
673
|
+
if name == "memory_trace":
|
|
674
674
|
op = "trace"
|
|
675
|
-
elif name == "
|
|
675
|
+
elif name == "memory_audit_history":
|
|
676
676
|
op = "audit"
|
|
677
677
|
else:
|
|
678
678
|
op = arguments.get("operation", "trace")
|
|
@@ -739,11 +739,11 @@ async def _handle_provenance(arguments, db, config, logger, **ctx):
|
|
|
739
739
|
)
|
|
740
740
|
|
|
741
741
|
|
|
742
|
-
@_handler("
|
|
742
|
+
@_handler("memory_remember")
|
|
743
743
|
async def _handle_remember(arguments, db, config, logger, **ctx):
|
|
744
744
|
_coerce_arg(arguments, "about")
|
|
745
745
|
memory_id = remember_fact(
|
|
746
|
-
content=_require(arguments, "content", "
|
|
746
|
+
content=_require(arguments, "content", "memory_remember"),
|
|
747
747
|
memory_type=arguments.get("type", "fact"),
|
|
748
748
|
about_entities=arguments.get("about"),
|
|
749
749
|
importance=arguments.get("importance", 1.0),
|
|
@@ -774,7 +774,7 @@ async def _handle_remember(arguments, db, config, logger, **ctx):
|
|
|
774
774
|
)
|
|
775
775
|
|
|
776
776
|
|
|
777
|
-
@_handler("
|
|
777
|
+
@_handler("memory_recall")
|
|
778
778
|
async def _handle_recall(arguments, db, config, logger, **ctx):
|
|
779
779
|
_coerce_arg(arguments, "types")
|
|
780
780
|
_coerce_arg(arguments, "ids")
|
|
@@ -802,7 +802,7 @@ async def _handle_recall(arguments, db, config, logger, **ctx):
|
|
|
802
802
|
]
|
|
803
803
|
}
|
|
804
804
|
)
|
|
805
|
-
response_text = _guard_response_size(response_text, "
|
|
805
|
+
response_text = _guard_response_size(response_text, "memory_recall")
|
|
806
806
|
return CallToolResult(
|
|
807
807
|
content=[TextContent(type="text", text=response_text)]
|
|
808
808
|
)
|
|
@@ -844,7 +844,7 @@ async def _handle_recall(arguments, db, config, logger, **ctx):
|
|
|
844
844
|
]
|
|
845
845
|
}
|
|
846
846
|
)
|
|
847
|
-
response_text = _guard_response_size(response_text, "
|
|
847
|
+
response_text = _guard_response_size(response_text, "memory_recall")
|
|
848
848
|
return CallToolResult(
|
|
849
849
|
content=[TextContent(type="text", text=response_text)]
|
|
850
850
|
)
|
|
@@ -869,17 +869,17 @@ async def _handle_recall(arguments, db, config, logger, **ctx):
|
|
|
869
869
|
]
|
|
870
870
|
}
|
|
871
871
|
)
|
|
872
|
-
response_text = _guard_response_size(response_text, "
|
|
872
|
+
response_text = _guard_response_size(response_text, "memory_recall")
|
|
873
873
|
return CallToolResult(
|
|
874
874
|
content=[TextContent(type="text", text=response_text)]
|
|
875
875
|
)
|
|
876
876
|
|
|
877
877
|
|
|
878
|
-
@_handler("
|
|
878
|
+
@_handler("memory_about")
|
|
879
879
|
async def _handle_about(arguments, db, config, logger, **ctx):
|
|
880
880
|
_coerce_int(arguments, "limit")
|
|
881
881
|
result = recall_about(
|
|
882
|
-
entity_name=_require(arguments, "entity", "
|
|
882
|
+
entity_name=_require(arguments, "entity", "memory_about"),
|
|
883
883
|
limit=arguments.get("limit", 20),
|
|
884
884
|
include_historical=arguments.get("include_historical", False),
|
|
885
885
|
)
|
|
@@ -901,18 +901,18 @@ async def _handle_about(arguments, db, config, logger, **ctx):
|
|
|
901
901
|
]
|
|
902
902
|
|
|
903
903
|
response_text = json.dumps(result)
|
|
904
|
-
response_text = _guard_response_size(response_text, "
|
|
904
|
+
response_text = _guard_response_size(response_text, "memory_about")
|
|
905
905
|
return CallToolResult(
|
|
906
906
|
content=[TextContent(type="text", text=response_text)]
|
|
907
907
|
)
|
|
908
908
|
|
|
909
909
|
|
|
910
|
-
@_handler("
|
|
910
|
+
@_handler("memory_relate")
|
|
911
911
|
async def _handle_relate(arguments, db, config, logger, **ctx):
|
|
912
912
|
relationship_id = relate_entities(
|
|
913
|
-
source=_require(arguments, "source", "
|
|
914
|
-
target=_require(arguments, "target", "
|
|
915
|
-
relationship=_require(arguments, "relationship", "
|
|
913
|
+
source=_require(arguments, "source", "memory_relate"),
|
|
914
|
+
target=_require(arguments, "target", "memory_relate"),
|
|
915
|
+
relationship=_require(arguments, "relationship", "memory_relate"),
|
|
916
916
|
strength=arguments.get("strength", 1.0),
|
|
917
917
|
valid_at=arguments.get("valid_at"),
|
|
918
918
|
supersedes=arguments.get("supersedes", False),
|
|
@@ -929,7 +929,7 @@ async def _handle_relate(arguments, db, config, logger, **ctx):
|
|
|
929
929
|
)
|
|
930
930
|
|
|
931
931
|
|
|
932
|
-
@_handler("
|
|
932
|
+
@_handler("memory_consolidate")
|
|
933
933
|
async def _handle_consolidate(arguments, db, config, logger, **ctx):
|
|
934
934
|
result = run_full_consolidation()
|
|
935
935
|
return CallToolResult(
|
|
@@ -942,7 +942,7 @@ async def _handle_consolidate(arguments, db, config, logger, **ctx):
|
|
|
942
942
|
)
|
|
943
943
|
|
|
944
944
|
|
|
945
|
-
@_handler("
|
|
945
|
+
@_handler("memory_end_session")
|
|
946
946
|
async def _handle_end_session(arguments, db, config, logger, **ctx):
|
|
947
947
|
_coerce_int(arguments, "episode_id")
|
|
948
948
|
# Coerce all array fields (LLMs may send JSON strings)
|
|
@@ -970,7 +970,7 @@ async def _handle_end_session(arguments, db, config, logger, **ctx):
|
|
|
970
970
|
|
|
971
971
|
result = end_session(
|
|
972
972
|
episode_id=episode_id,
|
|
973
|
-
narrative=_require(arguments, "narrative", "
|
|
973
|
+
narrative=_require(arguments, "narrative", "memory_end_session"),
|
|
974
974
|
facts=arguments.get("facts"),
|
|
975
975
|
commitments=arguments.get("commitments"),
|
|
976
976
|
entities=arguments.get("entities"),
|
|
@@ -1003,7 +1003,7 @@ async def _handle_end_session(arguments, db, config, logger, **ctx):
|
|
|
1003
1003
|
)
|
|
1004
1004
|
|
|
1005
1005
|
|
|
1006
|
-
@_handler("
|
|
1006
|
+
@_handler("memory_reflections")
|
|
1007
1007
|
async def _handle_reflections(arguments, db, config, logger, **ctx):
|
|
1008
1008
|
_coerce_int(arguments, "limit")
|
|
1009
1009
|
_coerce_int(arguments, "reflection_id")
|
|
@@ -1097,7 +1097,7 @@ async def _handle_reflections(arguments, db, config, logger, **ctx):
|
|
|
1097
1097
|
)
|
|
1098
1098
|
|
|
1099
1099
|
|
|
1100
|
-
@_handler("
|
|
1100
|
+
@_handler("memory_batch")
|
|
1101
1101
|
async def _handle_batch(arguments, db, config, logger, **ctx):
|
|
1102
1102
|
_coerce_arg(arguments, "operations")
|
|
1103
1103
|
operations = arguments.get("operations", [])
|
|
@@ -1225,11 +1225,11 @@ async def _handle_ingest(arguments, db, config, logger, **ctx):
|
|
|
1225
1225
|
)
|
|
1226
1226
|
|
|
1227
1227
|
|
|
1228
|
-
@_handler("
|
|
1228
|
+
@_handler("memory_multi_recall")
|
|
1229
1229
|
async def _handle_multi_recall(arguments, db, config, logger, **ctx):
|
|
1230
1230
|
"""Execute multiple recall queries in a single call and return deduplicated results.
|
|
1231
1231
|
|
|
1232
|
-
This is the compound equivalent of calling
|
|
1232
|
+
This is the compound equivalent of calling memory_recall N times sequentially.
|
|
1233
1233
|
Saves N-1 model round trips and deduplicates overlapping results server-side.
|
|
1234
1234
|
"""
|
|
1235
1235
|
_coerce_arg(arguments, "queries")
|
|
@@ -1309,11 +1309,11 @@ async def _handle_multi_recall(arguments, db, config, logger, **ctx):
|
|
|
1309
1309
|
}
|
|
1310
1310
|
text = json.dumps(response)
|
|
1311
1311
|
return CallToolResult(
|
|
1312
|
-
content=[TextContent(type="text", text=_guard_response_size(text, "
|
|
1312
|
+
content=[TextContent(type="text", text=_guard_response_size(text, "memory_multi_recall"))]
|
|
1313
1313
|
)
|
|
1314
1314
|
|
|
1315
1315
|
|
|
1316
|
-
@_handler("
|
|
1316
|
+
@_handler("memory_deep_context")
|
|
1317
1317
|
async def _handle_deep_context(arguments, db, config, logger, **ctx):
|
|
1318
1318
|
"""Server-side deep context assembly. Replaces 6-8 sequential MCP calls with one.
|
|
1319
1319
|
|
|
@@ -1321,7 +1321,7 @@ async def _handle_deep_context(arguments, db, config, logger, **ctx):
|
|
|
1321
1321
|
temporal sweep + episode search. Deduplicates by memory ID across all steps.
|
|
1322
1322
|
Returns a structured JSON object ready for synthesis.
|
|
1323
1323
|
"""
|
|
1324
|
-
target = _require(arguments, "target", "
|
|
1324
|
+
target = _require(arguments, "target", "memory_deep_context")
|
|
1325
1325
|
entity_limit = arguments.get("entity_limit", 50)
|
|
1326
1326
|
recall_limit = arguments.get("recall_limit", 50)
|
|
1327
1327
|
connected_limit = arguments.get("connected_limit", 10)
|
|
@@ -1488,11 +1488,11 @@ async def _handle_deep_context(arguments, db, config, logger, **ctx):
|
|
|
1488
1488
|
|
|
1489
1489
|
text = json.dumps(result)
|
|
1490
1490
|
return CallToolResult(
|
|
1491
|
-
content=[TextContent(type="text", text=_guard_response_size(text, "
|
|
1491
|
+
content=[TextContent(type="text", text=_guard_response_size(text, "memory_deep_context"))]
|
|
1492
1492
|
)
|
|
1493
1493
|
|
|
1494
1494
|
|
|
1495
|
-
@_handler("
|
|
1495
|
+
@_handler("memory_briefing")
|
|
1496
1496
|
async def _handle_briefing(arguments, db, config, logger, **ctx):
|
|
1497
1497
|
briefing_text = _build_briefing()
|
|
1498
1498
|
return CallToolResult(
|
|
@@ -1505,7 +1505,7 @@ async def _handle_briefing(arguments, db, config, logger, **ctx):
|
|
|
1505
1505
|
)
|
|
1506
1506
|
|
|
1507
1507
|
|
|
1508
|
-
@_handler("
|
|
1508
|
+
@_handler("memory_summary")
|
|
1509
1509
|
async def _handle_summary(arguments, db, config, logger, **ctx):
|
|
1510
1510
|
_coerce_int(arguments, "top_facts_limit")
|
|
1511
1511
|
entity_names = arguments.get("entities", [])
|
|
@@ -1601,7 +1601,7 @@ async def _handle_summary(arguments, db, config, logger, **ctx):
|
|
|
1601
1601
|
)
|
|
1602
1602
|
|
|
1603
1603
|
|
|
1604
|
-
@_handler("
|
|
1604
|
+
@_handler("memory_system_health")
|
|
1605
1605
|
async def _handle_system_health(arguments, db, config, logger, **ctx):
|
|
1606
1606
|
import urllib.request, urllib.error
|
|
1607
1607
|
report = None
|
|
@@ -1626,7 +1626,7 @@ async def _handle_system_health(arguments, db, config, logger, **ctx):
|
|
|
1626
1626
|
)
|
|
1627
1627
|
|
|
1628
1628
|
|
|
1629
|
-
@_handler("
|
|
1629
|
+
@_handler("memory_backup")
|
|
1630
1630
|
async def _handle_backup(arguments, db, config, logger, **ctx):
|
|
1631
1631
|
import urllib.request, urllib.error
|
|
1632
1632
|
result = None
|
|
@@ -1650,11 +1650,11 @@ async def _handle_backup(arguments, db, config, logger, **ctx):
|
|
|
1650
1650
|
)
|
|
1651
1651
|
|
|
1652
1652
|
|
|
1653
|
-
@_handler("
|
|
1653
|
+
@_handler("memory_project_health")
|
|
1654
1654
|
async def _handle_project_health(arguments, db, config, logger, **ctx):
|
|
1655
1655
|
_coerce_int(arguments, "days_ahead")
|
|
1656
1656
|
from ..services.recall import project_relationship_health
|
|
1657
|
-
entity = _require(arguments, "entity", "
|
|
1657
|
+
entity = _require(arguments, "entity", "memory_project_health")
|
|
1658
1658
|
days_ahead = arguments.get("days_ahead", 30)
|
|
1659
1659
|
result = project_relationship_health(entity, days_ahead)
|
|
1660
1660
|
return CallToolResult(
|
|
@@ -1662,13 +1662,13 @@ async def _handle_project_health(arguments, db, config, logger, **ctx):
|
|
|
1662
1662
|
)
|
|
1663
1663
|
|
|
1664
1664
|
|
|
1665
|
-
@_handler("
|
|
1665
|
+
@_handler("memory_lifecycle")
|
|
1666
1666
|
async def _handle_lifecycle(arguments, db, config, logger, **ctx):
|
|
1667
|
-
op = _require(arguments, "operation", "
|
|
1667
|
+
op = _require(arguments, "operation", "memory_lifecycle")
|
|
1668
1668
|
|
|
1669
1669
|
if op == "set":
|
|
1670
|
-
fact_id = _require(arguments, "fact_id", "
|
|
1671
|
-
tier = _require(arguments, "tier", "
|
|
1670
|
+
fact_id = _require(arguments, "fact_id", "memory_lifecycle")
|
|
1671
|
+
tier = _require(arguments, "tier", "memory_lifecycle")
|
|
1672
1672
|
reason = arguments.get("reason", "manual")
|
|
1673
1673
|
if tier == "sacred":
|
|
1674
1674
|
db.execute(
|
|
@@ -1690,7 +1690,7 @@ async def _handle_lifecycle(arguments, db, config, logger, **ctx):
|
|
|
1690
1690
|
)
|
|
1691
1691
|
|
|
1692
1692
|
elif op == "protect":
|
|
1693
|
-
entity_name = _require(arguments, "entity", "
|
|
1693
|
+
entity_name = _require(arguments, "entity", "memory_lifecycle")
|
|
1694
1694
|
reason = arguments.get("reason", "user-designated")
|
|
1695
1695
|
canonical = entity_name.strip().lower()
|
|
1696
1696
|
row = db.execute(
|
|
@@ -1709,7 +1709,7 @@ async def _handle_lifecycle(arguments, db, config, logger, **ctx):
|
|
|
1709
1709
|
)
|
|
1710
1710
|
|
|
1711
1711
|
elif op == "archive":
|
|
1712
|
-
fact_id = _require(arguments, "fact_id", "
|
|
1712
|
+
fact_id = _require(arguments, "fact_id", "memory_lifecycle")
|
|
1713
1713
|
db.execute(
|
|
1714
1714
|
"UPDATE memories SET lifecycle_tier = 'archived', archived_at = datetime('now'), updated_at = datetime('now') WHERE fact_id = ?",
|
|
1715
1715
|
(fact_id,),
|
|
@@ -1719,7 +1719,7 @@ async def _handle_lifecycle(arguments, db, config, logger, **ctx):
|
|
|
1719
1719
|
)
|
|
1720
1720
|
|
|
1721
1721
|
elif op == "restore":
|
|
1722
|
-
fact_id = _require(arguments, "fact_id", "
|
|
1722
|
+
fact_id = _require(arguments, "fact_id", "memory_lifecycle")
|
|
1723
1723
|
db.execute(
|
|
1724
1724
|
"UPDATE memories SET lifecycle_tier = 'active', archived_at = NULL, updated_at = datetime('now') WHERE fact_id = ?",
|
|
1725
1725
|
(fact_id,),
|
|
@@ -1758,12 +1758,12 @@ async def _handle_lifecycle(arguments, db, config, logger, **ctx):
|
|
|
1758
1758
|
)
|
|
1759
1759
|
|
|
1760
1760
|
|
|
1761
|
-
@_handler("
|
|
1761
|
+
@_handler("memory_context")
|
|
1762
1762
|
async def _handle_context(arguments, db, config, logger, **ctx):
|
|
1763
1763
|
from ..services.context_builder import build_context
|
|
1764
1764
|
_coerce_int(arguments, "token_budget")
|
|
1765
1765
|
result = build_context(
|
|
1766
|
-
query=_require(arguments, "query", "
|
|
1766
|
+
query=_require(arguments, "query", "memory_context"),
|
|
1767
1767
|
token_budget=arguments.get("token_budget", 8000),
|
|
1768
1768
|
include_sacred=arguments.get("include_sacred", True),
|
|
1769
1769
|
entity=arguments.get("entity"),
|
|
@@ -1773,9 +1773,9 @@ async def _handle_context(arguments, db, config, logger, **ctx):
|
|
|
1773
1773
|
)
|
|
1774
1774
|
|
|
1775
1775
|
|
|
1776
|
-
@_handler("
|
|
1776
|
+
@_handler("memory_checkpoint")
|
|
1777
1777
|
async def _handle_checkpoint(arguments, db, config, logger, **ctx):
|
|
1778
|
-
op = _require(arguments, "operation", "
|
|
1778
|
+
op = _require(arguments, "operation", "memory_checkpoint")
|
|
1779
1779
|
|
|
1780
1780
|
if op == "save":
|
|
1781
1781
|
name = arguments.get("name", "manual")
|
|
@@ -1819,12 +1819,12 @@ async def _handle_checkpoint(arguments, db, config, logger, **ctx):
|
|
|
1819
1819
|
)
|
|
1820
1820
|
|
|
1821
1821
|
|
|
1822
|
-
@_handler("
|
|
1822
|
+
@_handler("memory_rollback")
|
|
1823
1823
|
async def _handle_rollback(arguments, db, config, logger, **ctx):
|
|
1824
|
-
op = _require(arguments, "operation", "
|
|
1824
|
+
op = _require(arguments, "operation", "memory_rollback")
|
|
1825
1825
|
|
|
1826
1826
|
if op == "set":
|
|
1827
|
-
ts = _require(arguments, "timestamp", "
|
|
1827
|
+
ts = _require(arguments, "timestamp", "memory_rollback")
|
|
1828
1828
|
db.execute(
|
|
1829
1829
|
"INSERT INTO _meta (key, value, updated_at) VALUES ('view_as_of', ?, datetime('now')) ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = datetime('now')",
|
|
1830
1830
|
(ts,),
|
|
@@ -1855,6 +1855,15 @@ async def _handle_rollback(arguments, db, config, logger, **ctx):
|
|
|
1855
1855
|
)
|
|
1856
1856
|
|
|
1857
1857
|
|
|
1858
|
+
# ── Backward compatibility: accept dot-notation names during transition ──
|
|
1859
|
+
# Users who haven't updated skills/hooks may still call memory.recall instead
|
|
1860
|
+
# of memory_recall. Register aliases so both work. list_tools() only advertises
|
|
1861
|
+
# underscore names; these aliases only affect call_tool() dispatch.
|
|
1862
|
+
# TODO: Remove after v1.58.0 (2 release cycles)
|
|
1863
|
+
_DOT_ALIASES = {k.replace("_", ".", 1): v for k, v in _TOOL_HANDLERS.items()
|
|
1864
|
+
if k.startswith("memory_")}
|
|
1865
|
+
_TOOL_HANDLERS.update(_DOT_ALIASES)
|
|
1866
|
+
|
|
1858
1867
|
# Initialize the MCP server
|
|
1859
1868
|
server = Server("claudia-memory")
|
|
1860
1869
|
|
|
@@ -1864,7 +1873,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
1864
1873
|
"""List all available memory tools"""
|
|
1865
1874
|
tools = [
|
|
1866
1875
|
Tool(
|
|
1867
|
-
name="
|
|
1876
|
+
name="memory_remember",
|
|
1868
1877
|
title="Store a Memory",
|
|
1869
1878
|
description="Store information in Claudia's memory. Use for facts, preferences, observations, or learnings about people, projects, or the user.",
|
|
1870
1879
|
annotations=ToolAnnotations(destructiveHint=False),
|
|
@@ -1920,7 +1929,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
1920
1929
|
},
|
|
1921
1930
|
),
|
|
1922
1931
|
Tool(
|
|
1923
|
-
name="
|
|
1932
|
+
name="memory_recall",
|
|
1924
1933
|
title="Search Memory",
|
|
1925
1934
|
description=(
|
|
1926
1935
|
"Search Claudia's memory for relevant information. Uses hybrid vector + full-text "
|
|
@@ -1967,7 +1976,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
1967
1976
|
},
|
|
1968
1977
|
),
|
|
1969
1978
|
Tool(
|
|
1970
|
-
name="
|
|
1979
|
+
name="memory_about",
|
|
1971
1980
|
title="Get Entity Context",
|
|
1972
1981
|
description="Get all context about a specific person, project, or entity. Returns memories, relationships, and metadata.",
|
|
1973
1982
|
annotations=ToolAnnotations(readOnlyHint=True),
|
|
@@ -1993,7 +2002,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
1993
2002
|
},
|
|
1994
2003
|
),
|
|
1995
2004
|
Tool(
|
|
1996
|
-
name="
|
|
2005
|
+
name="memory_relate",
|
|
1997
2006
|
title="Create Relationship",
|
|
1998
2007
|
description="Create or strengthen a relationship between two entities (people, projects, etc.)",
|
|
1999
2008
|
annotations=ToolAnnotations(destructiveHint=False),
|
|
@@ -2041,7 +2050,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
2041
2050
|
},
|
|
2042
2051
|
),
|
|
2043
2052
|
Tool(
|
|
2044
|
-
name="
|
|
2053
|
+
name="memory_consolidate",
|
|
2045
2054
|
title="Run Consolidation",
|
|
2046
2055
|
description="Manually trigger memory consolidation (decay, merging, pattern detection). Usually runs automatically at 3 AM.",
|
|
2047
2056
|
annotations=ToolAnnotations(destructiveHint=False),
|
|
@@ -2051,7 +2060,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
2051
2060
|
},
|
|
2052
2061
|
),
|
|
2053
2062
|
Tool(
|
|
2054
|
-
name="
|
|
2063
|
+
name="memory_end_session",
|
|
2055
2064
|
title="End Session",
|
|
2056
2065
|
description=(
|
|
2057
2066
|
"Finalize a session with a narrative summary and structured extractions. "
|
|
@@ -2222,7 +2231,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
2222
2231
|
},
|
|
2223
2232
|
),
|
|
2224
2233
|
Tool(
|
|
2225
|
-
name="
|
|
2234
|
+
name="memory_reflections",
|
|
2226
2235
|
title="Manage Reflections",
|
|
2227
2236
|
description=(
|
|
2228
2237
|
"Get or search persistent reflections (observations, patterns, learnings, questions) "
|
|
@@ -2273,14 +2282,14 @@ async def list_tools() -> ListToolsResult:
|
|
|
2273
2282
|
},
|
|
2274
2283
|
),
|
|
2275
2284
|
Tool(
|
|
2276
|
-
name="
|
|
2285
|
+
name="memory_batch",
|
|
2277
2286
|
title="Batch Memory Operations",
|
|
2278
2287
|
description=(
|
|
2279
2288
|
"Execute multiple memory operations in a single call. Use this for mid-session "
|
|
2280
2289
|
"entity creation when processing a new person, meeting transcript, or topic that "
|
|
2281
2290
|
"requires entity creation, multiple memories, and relationships. Much more efficient "
|
|
2282
|
-
"than calling
|
|
2283
|
-
"For end-of-session summaries, use
|
|
2291
|
+
"than calling memory_entity, memory_remember, and memory_relate separately. "
|
|
2292
|
+
"For end-of-session summaries, use memory_end_session instead."
|
|
2284
2293
|
),
|
|
2285
2294
|
annotations=ToolAnnotations(destructiveHint=False),
|
|
2286
2295
|
inputSchema={
|
|
@@ -2381,11 +2390,11 @@ async def list_tools() -> ListToolsResult:
|
|
|
2381
2390
|
},
|
|
2382
2391
|
),
|
|
2383
2392
|
Tool(
|
|
2384
|
-
name="
|
|
2393
|
+
name="memory_multi_recall",
|
|
2385
2394
|
title="Multi-Query Recall",
|
|
2386
2395
|
description=(
|
|
2387
2396
|
"Execute multiple recall queries in a single call. Returns deduplicated results "
|
|
2388
|
-
"grouped by query. Use instead of calling
|
|
2397
|
+
"grouped by query. Use instead of calling memory_recall repeatedly when you need "
|
|
2389
2398
|
"to search across several dimensions (e.g., different topics, entity types, or "
|
|
2390
2399
|
"time-sensitive items). Saves round trips and deduplicates overlapping results "
|
|
2391
2400
|
"server-side. Each query can specify its own limit, types filter, and entity filter."
|
|
@@ -2417,7 +2426,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
2417
2426
|
},
|
|
2418
2427
|
),
|
|
2419
2428
|
Tool(
|
|
2420
|
-
name="
|
|
2429
|
+
name="memory_deep_context",
|
|
2421
2430
|
title="Deep Context Assembly",
|
|
2422
2431
|
description=(
|
|
2423
2432
|
"Full-context deep analysis in a single call. Executes the complete deep-context "
|
|
@@ -2425,7 +2434,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
2425
2434
|
"temporal sweep (observations/learnings/commitments), and episode search. "
|
|
2426
2435
|
"Deduplicates by memory ID across all steps. Returns structured JSON ready for "
|
|
2427
2436
|
"synthesis. Use for meeting prep, relationship deep dives, or strategic analysis. "
|
|
2428
|
-
"Replaces 6-8 sequential
|
|
2437
|
+
"Replaces 6-8 sequential memory_about/memory_recall calls with one compound call."
|
|
2429
2438
|
),
|
|
2430
2439
|
annotations=ToolAnnotations(readOnlyHint=True),
|
|
2431
2440
|
inputSchema={
|
|
@@ -2470,13 +2479,13 @@ async def list_tools() -> ListToolsResult:
|
|
|
2470
2479
|
},
|
|
2471
2480
|
),
|
|
2472
2481
|
Tool(
|
|
2473
|
-
name="
|
|
2482
|
+
name="memory_briefing",
|
|
2474
2483
|
title="Compact Briefing",
|
|
2475
2484
|
description=(
|
|
2476
2485
|
"Compact session briefing (~500 tokens). Returns aggregate counts and highlights: "
|
|
2477
2486
|
"active commitments, cooling relationships, unread messages, top prediction, "
|
|
2478
2487
|
"recent activity. Call at session start instead of loading full context. "
|
|
2479
|
-
"Use
|
|
2488
|
+
"Use memory_recall or memory_about to drill into specifics during conversation."
|
|
2480
2489
|
),
|
|
2481
2490
|
annotations=ToolAnnotations(readOnlyHint=True),
|
|
2482
2491
|
inputSchema={
|
|
@@ -2521,12 +2530,12 @@ async def list_tools() -> ListToolsResult:
|
|
|
2521
2530
|
},
|
|
2522
2531
|
),
|
|
2523
2532
|
Tool(
|
|
2524
|
-
name="
|
|
2533
|
+
name="memory_summary",
|
|
2525
2534
|
title="Entity Summaries",
|
|
2526
2535
|
description=(
|
|
2527
2536
|
"Get a lightweight summary for one or more entities. Returns name, type, "
|
|
2528
2537
|
"importance, memory count, relationship count, last mentioned date, and "
|
|
2529
|
-
"top facts. Cheaper than
|
|
2538
|
+
"top facts. Cheaper than memory_about for quick overviews."
|
|
2530
2539
|
),
|
|
2531
2540
|
annotations=ToolAnnotations(readOnlyHint=True),
|
|
2532
2541
|
inputSchema={
|
|
@@ -2547,7 +2556,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
2547
2556
|
},
|
|
2548
2557
|
),
|
|
2549
2558
|
Tool(
|
|
2550
|
-
name="
|
|
2559
|
+
name="memory_system_health",
|
|
2551
2560
|
title="System Health Check",
|
|
2552
2561
|
description=(
|
|
2553
2562
|
"Get comprehensive system health: schema version, component status, "
|
|
@@ -2561,7 +2570,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
2561
2570
|
},
|
|
2562
2571
|
),
|
|
2563
2572
|
Tool(
|
|
2564
|
-
name="
|
|
2573
|
+
name="memory_backup",
|
|
2565
2574
|
title="Trigger Database Backup",
|
|
2566
2575
|
description=(
|
|
2567
2576
|
"Trigger an immediate backup of the memory database. Returns the path "
|
|
@@ -2574,7 +2583,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
2574
2583
|
},
|
|
2575
2584
|
),
|
|
2576
2585
|
Tool(
|
|
2577
|
-
name="
|
|
2586
|
+
name="memory_project_health",
|
|
2578
2587
|
title="Project Health Check",
|
|
2579
2588
|
description=(
|
|
2580
2589
|
"Project when a relationship will go dormant based on contact velocity. "
|
|
@@ -2601,7 +2610,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
2601
2610
|
),
|
|
2602
2611
|
# ── Merged tools (8 composite tools with operation parameter) ──
|
|
2603
2612
|
Tool(
|
|
2604
|
-
name="
|
|
2613
|
+
name="memory_temporal",
|
|
2605
2614
|
title="Temporal Queries",
|
|
2606
2615
|
description=(
|
|
2607
2616
|
"Time-based memory queries: upcoming deadlines, recent changes, entity timelines, "
|
|
@@ -2645,7 +2654,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
2645
2654
|
},
|
|
2646
2655
|
),
|
|
2647
2656
|
Tool(
|
|
2648
|
-
name="
|
|
2657
|
+
name="memory_graph",
|
|
2649
2658
|
title="Relationship Graph",
|
|
2650
2659
|
description=(
|
|
2651
2660
|
"Explore the entity relationship graph: project networks, connection paths, "
|
|
@@ -2710,7 +2719,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
2710
2719
|
},
|
|
2711
2720
|
),
|
|
2712
2721
|
Tool(
|
|
2713
|
-
name="
|
|
2722
|
+
name="memory_entities",
|
|
2714
2723
|
title="Entity Management",
|
|
2715
2724
|
description=(
|
|
2716
2725
|
"Create, search, merge, delete, or overview entities (people, projects, orgs). "
|
|
@@ -2795,7 +2804,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
2795
2804
|
},
|
|
2796
2805
|
),
|
|
2797
2806
|
Tool(
|
|
2798
|
-
name="
|
|
2807
|
+
name="memory_vault",
|
|
2799
2808
|
title="Obsidian Vault",
|
|
2800
2809
|
description=(
|
|
2801
2810
|
"Manage the Obsidian vault integration: sync memory to vault, check status, "
|
|
@@ -2831,7 +2840,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
2831
2840
|
},
|
|
2832
2841
|
),
|
|
2833
2842
|
Tool(
|
|
2834
|
-
name="
|
|
2843
|
+
name="memory_modify",
|
|
2835
2844
|
title="Modify Memories & Relationships",
|
|
2836
2845
|
description=(
|
|
2837
2846
|
"Correct, invalidate, or end relationships. "
|
|
@@ -2877,7 +2886,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
2877
2886
|
},
|
|
2878
2887
|
),
|
|
2879
2888
|
Tool(
|
|
2880
|
-
name="
|
|
2889
|
+
name="memory_session",
|
|
2881
2890
|
title="Session Lifecycle",
|
|
2882
2891
|
description=(
|
|
2883
2892
|
"Session management: buffer turns, load context, or check unsummarized sessions. "
|
|
@@ -2920,7 +2929,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
2920
2929
|
},
|
|
2921
2930
|
),
|
|
2922
2931
|
Tool(
|
|
2923
|
-
name="
|
|
2932
|
+
name="memory_document",
|
|
2924
2933
|
title="Document Storage",
|
|
2925
2934
|
description=(
|
|
2926
2935
|
"Store or search documents (transcripts, emails, files). "
|
|
@@ -2986,7 +2995,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
2986
2995
|
},
|
|
2987
2996
|
),
|
|
2988
2997
|
Tool(
|
|
2989
|
-
name="
|
|
2998
|
+
name="memory_provenance",
|
|
2990
2999
|
title="Provenance & Audit",
|
|
2991
3000
|
description=(
|
|
2992
3001
|
"Trace memory origins, get full audit trails, or verify hash chain integrity. "
|
|
@@ -3022,7 +3031,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
3022
3031
|
),
|
|
3023
3032
|
# ── Lifecycle / Sacred memory tools ──
|
|
3024
3033
|
Tool(
|
|
3025
|
-
name="
|
|
3034
|
+
name="memory_lifecycle",
|
|
3026
3035
|
title="Memory Lifecycle",
|
|
3027
3036
|
description="Manage memory lifecycle tiers (sacred/active/cooling/archived) and entity close-circle status.",
|
|
3028
3037
|
inputSchema={
|
|
@@ -3058,7 +3067,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
3058
3067
|
},
|
|
3059
3068
|
),
|
|
3060
3069
|
Tool(
|
|
3061
|
-
name="
|
|
3070
|
+
name="memory_context",
|
|
3062
3071
|
title="Build Context Window",
|
|
3063
3072
|
description="Build a token-budgeted context window with sacred facts always included. Uses the Context Relevance Engine (CRE).",
|
|
3064
3073
|
inputSchema={
|
|
@@ -3085,7 +3094,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
3085
3094
|
},
|
|
3086
3095
|
),
|
|
3087
3096
|
Tool(
|
|
3088
|
-
name="
|
|
3097
|
+
name="memory_checkpoint",
|
|
3089
3098
|
title="Database Checkpoints",
|
|
3090
3099
|
description="Save, list, or restore database checkpoints (labeled backups).",
|
|
3091
3100
|
inputSchema={
|
|
@@ -3105,7 +3114,7 @@ async def list_tools() -> ListToolsResult:
|
|
|
3105
3114
|
},
|
|
3106
3115
|
),
|
|
3107
3116
|
Tool(
|
|
3108
|
-
name="
|
|
3117
|
+
name="memory_rollback",
|
|
3109
3118
|
title="Temporal Rollback",
|
|
3110
3119
|
description="Set a temporal view filter so recall only returns memories created before a given timestamp. Non-destructive.",
|
|
3111
3120
|
inputSchema={
|
|
@@ -3507,7 +3516,7 @@ def _build_session_context(token_budget: str = "normal") -> str:
|
|
|
3507
3516
|
unsummarized = get_unsummarized_turns()
|
|
3508
3517
|
if unsummarized:
|
|
3509
3518
|
sections.append(f"## Unsummarized Sessions ({len(unsummarized)})\n")
|
|
3510
|
-
sections.append("**Action needed:** Generate retroactive summaries using `
|
|
3519
|
+
sections.append("**Action needed:** Generate retroactive summaries using `memory_end_session` for each.\n")
|
|
3511
3520
|
for session in unsummarized:
|
|
3512
3521
|
ep_id = session.get("episode_id", "?")
|
|
3513
3522
|
turn_count = session.get("turn_count", 0)
|