Skip to content

Commit 899f2e7

Browse files
authored
Merge pull request #16 from Daylily-Informatics/codex/set-missing-table-names-for-configuration
Update memory dump script for unified state table
2 parents 5a9e286 + 521e5ca commit 899f2e7

File tree

1 file changed

+47
-32
lines changed

1 file changed

+47
-32
lines changed

bin/dump_memory.py

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,52 @@
11
#!/usr/bin/env python3
2-
"""Dump short- and long-term memory DynamoDB tables as JSON."""
2+
"""Dump agent DynamoDB state (events + memories) as JSON."""
33

44
import argparse
55
import json
66
import os
77
import sys
88

99
import boto3
10-
from boto3.dynamodb.types import TypeDeserializer
10+
from boto3.dynamodb.conditions import Key
1111

1212

13-
def _scan_all(client, table_name: str):
14-
"""Read the entire table via Scan with pagination."""
13+
def _query_items(table, partition_key: str):
14+
"""Query all items for a given partition key."""
1515
items = []
1616
start_key = None
1717
while True:
18-
params = {"TableName": table_name}
18+
params = {"KeyConditionExpression": Key("pk").eq(partition_key)}
1919
if start_key:
2020
params["ExclusiveStartKey"] = start_key
21-
resp = client.scan(**params)
21+
resp = table.query(**params)
2222
items.extend(resp.get("Items", []))
2323
start_key = resp.get("LastEvaluatedKey")
2424
if not start_key:
2525
break
2626
return items
2727

2828

29-
def _deserialize_items(raw_items):
30-
deserializer = TypeDeserializer()
31-
return [{k: deserializer.deserialize(v) for k, v in item.items()} for item in raw_items]
29+
def _categorize_items(items):
30+
buckets = {"events": [], "memories": [], "other": []}
31+
for item in items:
32+
sk = str(item.get("sk", ""))
33+
if "#EVENT#" in sk:
34+
buckets["events"].append(item)
35+
elif "#MEMORY#" in sk:
36+
buckets["memories"].append(item)
37+
else:
38+
buckets["other"].append(item)
39+
return buckets
3240

3341

34-
def _dump_table(client, table_name: str, label: str):
35-
raw_items = _scan_all(client, table_name)
42+
def _dump(label: str, table_name: str, agent_id: str, items):
3643
payload = {
3744
"table": table_name,
38-
"count": len(raw_items),
39-
"items": _deserialize_items(raw_items),
45+
"agent_id": agent_id,
46+
"count": len(items),
47+
"items": items,
4048
}
41-
print(f"# {label}: {table_name}")
49+
print(f"# {label} (agent_id={agent_id})")
4250
print(json.dumps(payload, indent=2, default=str))
4351
print()
4452

@@ -51,34 +59,41 @@ def main():
5159
help="AWS region for DynamoDB operations (default: %(default)s)",
5260
)
5361
parser.add_argument(
54-
"--conversation-table",
55-
default=os.environ.get("CONVERSATION_TABLE", ""),
56-
help="DynamoDB table name for short-term session memory",
62+
"--state-table",
63+
default=os.environ.get("AGENT_STATE_TABLE", ""),
64+
help="DynamoDB table name for unified agent state (events + memories)",
5765
)
5866
parser.add_argument(
59-
"--ais-table",
60-
default=os.environ.get("AIS_MEMORY_TABLE", ""),
61-
help="DynamoDB table name for long-term AIS memory",
67+
"--agent-id",
68+
default=os.environ.get("AGENT_ID", "marvain-agent"),
69+
help="Agent id / partition key suffix to query (default: %(default)s)",
6270
)
6371
parser.add_argument(
6472
"--target",
65-
choices=["short", "long", "both"],
66-
default="both",
67-
help="Select which memory tables to dump (default: both)",
73+
choices=["all", "events", "memories", "other"],
74+
default="all",
75+
help="Select which categories to dump (default: all)",
6876
)
6977
args = parser.parse_args()
7078

71-
client = boto3.client("dynamodb", region_name=args.region)
79+
if not args.state_table:
80+
sys.exit("Missing state table name (set AGENT_STATE_TABLE or --state-table)")
7281

73-
if args.target in {"short", "both"}:
74-
if not args.conversation_table:
75-
sys.exit("Missing conversation table name (set CONVERSATION_TABLE or --conversation-table)")
76-
_dump_table(client, args.conversation_table, "Short-term conversation memory")
82+
dynamodb = boto3.resource("dynamodb", region_name=args.region)
83+
table = dynamodb.Table(args.state_table)
7784

78-
if args.target in {"long", "both"}:
79-
if not args.ais_table:
80-
sys.exit("Missing AIS memory table name (set AIS_MEMORY_TABLE or --ais-table)")
81-
_dump_table(client, args.ais_table, "Long-term AIS memory")
85+
partition_key = f"AGENT#{args.agent_id}"
86+
items = _query_items(table, partition_key)
87+
buckets = _categorize_items(items)
88+
89+
if args.target in {"events", "all"}:
90+
_dump("Events", args.state_table, args.agent_id, buckets["events"])
91+
92+
if args.target in {"memories", "all"}:
93+
_dump("Memories", args.state_table, args.agent_id, buckets["memories"])
94+
95+
if args.target in {"other", "all"}:
96+
_dump("Other items", args.state_table, args.agent_id, buckets["other"])
8297

8398

8499
if __name__ == "__main__":

0 commit comments

Comments
 (0)