Merge pull request #371 from RhettOP/fix/issue-339-338-silent-exceptions-pagination

fix: paginate large collection reads and surface errors in MCP tools (#339, #338)
This commit is contained in:
Ben Sigman
2026-04-10 22:36:36 -07:00
committed by GitHub
+94 -34
View File
@@ -143,16 +143,25 @@ def tool_status():
count = col.count() count = col.count()
wings = {} wings = {}
rooms = {} rooms = {}
try: batch_size = 5000
all_meta = col.get(include=["metadatas"], limit=10000)["metadatas"] offset = 0
for m in all_meta: error_info = None
w = m.get("wing", "unknown") while True:
r = m.get("room", "unknown") try:
wings[w] = wings.get(w, 0) + 1 batch = col.get(include=["metadatas"], limit=batch_size, offset=offset)
rooms[r] = rooms.get(r, 0) + 1 rows = batch["metadatas"]
except Exception: for m in rows:
pass w = m.get("wing", "unknown")
return { r = m.get("room", "unknown")
wings[w] = wings.get(w, 0) + 1
rooms[r] = rooms.get(r, 0) + 1
offset += len(rows)
if len(rows) < batch_size:
break
except Exception as e:
error_info = f"Partial result, failed at offset {offset}: {str(e)}"
break
result = {
"total_drawers": count, "total_drawers": count,
"wings": wings, "wings": wings,
"rooms": rooms, "rooms": rooms,
@@ -160,6 +169,10 @@ def tool_status():
"protocol": PALACE_PROTOCOL, "protocol": PALACE_PROTOCOL,
"aaak_dialect": AAAK_SPEC, "aaak_dialect": AAAK_SPEC,
} }
if error_info:
result["error"] = error_info
result["partial"] = True
return result
# ── AAAK Dialect Spec ───────────────────────────────────────────────────────── # ── AAAK Dialect Spec ─────────────────────────────────────────────────────────
@@ -200,13 +213,28 @@ def tool_list_wings():
if not col: if not col:
return _no_palace() return _no_palace()
wings = {} wings = {}
batch_size = 5000
offset = 0
try: try:
all_meta = col.get(include=["metadatas"], limit=10000)["metadatas"] col.count() # verify collection is accessible
for m in all_meta: except Exception as e:
w = m.get("wing", "unknown") return {"wings": {}, "error": str(e)}
wings[w] = wings.get(w, 0) + 1 while True:
except Exception: try:
pass batch = col.get(include=["metadatas"], limit=batch_size, offset=offset)
rows = batch["metadatas"]
for m in rows:
w = m.get("wing", "unknown")
wings[w] = wings.get(w, 0) + 1
offset += len(rows)
if len(rows) < batch_size:
break
except Exception as e:
return {
"wings": wings,
"error": f"Partial result, failed at offset {offset}: {str(e)}",
"partial": True,
}
return {"wings": wings} return {"wings": wings}
@@ -215,16 +243,33 @@ def tool_list_rooms(wing: str = None):
if not col: if not col:
return _no_palace() return _no_palace()
rooms = {} rooms = {}
batch_size = 5000
offset = 0
where = {"wing": wing} if wing else None
try: try:
kwargs = {"include": ["metadatas"], "limit": 10000} col.count() # verify collection is accessible
if wing: except Exception as e:
kwargs["where"] = {"wing": wing} return {"wing": wing or "all", "rooms": {}, "error": str(e)}
all_meta = col.get(**kwargs)["metadatas"] while True:
for m in all_meta: try:
r = m.get("room", "unknown") kwargs = {"include": ["metadatas"], "limit": batch_size, "offset": offset}
rooms[r] = rooms.get(r, 0) + 1 if where:
except Exception: kwargs["where"] = where
pass batch = col.get(**kwargs)
rows = batch["metadatas"]
for m in rows:
r = m.get("room", "unknown")
rooms[r] = rooms.get(r, 0) + 1
offset += len(rows)
if len(rows) < batch_size:
break
except Exception as e:
return {
"wing": wing or "all",
"rooms": rooms,
"error": f"Partial result, failed at offset {offset}: {str(e)}",
"partial": True,
}
return {"wing": wing or "all", "rooms": rooms} return {"wing": wing or "all", "rooms": rooms}
@@ -233,16 +278,31 @@ def tool_get_taxonomy():
if not col: if not col:
return _no_palace() return _no_palace()
taxonomy = {} taxonomy = {}
batch_size = 5000
offset = 0
try: try:
all_meta = col.get(include=["metadatas"], limit=10000)["metadatas"] col.count() # verify collection is accessible
for m in all_meta: except Exception as e:
w = m.get("wing", "unknown") return {"taxonomy": {}, "error": str(e)}
r = m.get("room", "unknown") while True:
if w not in taxonomy: try:
taxonomy[w] = {} batch = col.get(include=["metadatas"], limit=batch_size, offset=offset)
taxonomy[w][r] = taxonomy[w].get(r, 0) + 1 rows = batch["metadatas"]
except Exception: for m in rows:
pass w = m.get("wing", "unknown")
r = m.get("room", "unknown")
if w not in taxonomy:
taxonomy[w] = {}
taxonomy[w][r] = taxonomy[w].get(r, 0) + 1
offset += len(rows)
if len(rows) < batch_size:
break
except Exception as e:
return {
"taxonomy": taxonomy,
"error": f"Partial result, failed at offset {offset}: {str(e)}",
"partial": True,
}
return {"taxonomy": taxonomy} return {"taxonomy": taxonomy}