fix: paginate large collection reads and surface errors in MCP tools (#339, #338)

This commit is contained in:
Openclaw
2026-04-09 13:33:45 +01:00
parent 26835e30ef
commit d20c8ab992
+69 -34
View File
@@ -96,16 +96,22 @@ 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 offset < count:
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 for m in batch["metadatas"]:
except Exception: w = m.get("wing", "unknown")
pass r = m.get("room", "unknown")
return { wings[w] = wings.get(w, 0) + 1
rooms[r] = rooms.get(r, 0) + 1
offset += batch_size
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,
@@ -113,6 +119,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 ─────────────────────────────────────────────────────────
@@ -153,13 +163,21 @@ 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"] total = col.count()
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 offset < total:
except Exception: try:
pass batch = col.get(include=["metadatas"], limit=batch_size, offset=offset)
for m in batch["metadatas"]:
w = m.get("wing", "unknown")
wings[w] = wings.get(w, 0) + 1
offset += batch_size
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}
@@ -168,16 +186,25 @@ 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} total = col.count()
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 offset < total:
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)
for m in batch["metadatas"]:
r = m.get("room", "unknown")
rooms[r] = rooms.get(r, 0) + 1
offset += batch_size
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}
@@ -186,16 +213,24 @@ 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"] total = col.count()
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 offset < total:
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 for m in batch["metadatas"]:
except Exception: w = m.get("wing", "unknown")
pass r = m.get("room", "unknown")
if w not in taxonomy:
taxonomy[w] = {}
taxonomy[w][r] = taxonomy[w].get(r, 0) + 1
offset += batch_size
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}