Keep numpy scalars out of memory metadata and API JSON
Memory consolidation stores FAISS relevance scores (numpy scalars) in document metadata. The values get pickled into the docstore and crash json.dumps with 'Object of type float32 is not JSON serializable' in helpers/api.py for handlers that return full metadata. Coerce scores to native floats at the source and serialize responses with default=float.
Jehu committed
Aug 21, 2026 at 08:34 UTC
c26ed8064e872ba23d8fbf79057d4caeec064b3d
3 files changed
+4
-4
helpers/api.py
+1
-1
@@ -83,7 +83,7 @@ class ApiHandler:
83
if isinstance(output, Response):
84
return output
85
else:
86
- response_json = json.dumps(output)
86
+ response_json = json.dumps(output, default=float)
87
return Response(
88
response=response_json, status=200, mimetype="application/json"
89
)
plugins/_memory/helpers/memory.py
+1
-1
@@ -594,7 +594,7 @@ class Memory:
594
res = max(
595
0, min(1, res)
596
) # float precision can cause values like 1.0000000596046448
597
- return res
597
+ return float(res) # native float, not numpy scalar (JSON serializable)
598
599
@staticmethod
600
def format_docs_plain(docs: list[Document]) -> list[str]:
plugins/_memory/helpers/memory_consolidation.py
+2
-2
@@ -344,7 +344,7 @@ class MemoryConsolidator:
344
filter=f"area == '{area}'"
345
)
346
for doc, score in semantic_results:
347
- doc.metadata['_consolidation_similarity'] = score
347
+ doc.metadata['_consolidation_similarity'] = float(score) if score is not None else 0.0
348
all_similar.append(doc)
349
350
# Step 3: Keyword-based searches with real scores
@@ -358,7 +358,7 @@ class MemoryConsolidator:
358
filter=f"area == '{area}'"
359
)
360
for doc, score in keyword_results:
361
- doc.metadata['_consolidation_similarity'] = score
361
+ doc.metadata['_consolidation_similarity'] = float(score) if score is not None else 0.0
362
all_similar.append(doc)
363
364
# Step 4: Deduplicate by document ID, keep highest score per memory ID