fix: handle missing similarity and object profile items in context display#26
fix: handle missing similarity and object profile items in context display#26kui123456789 wants to merge 3 commits intosupermemoryai:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes edge cases in the prompt context injection so that user/profile facts and memory search results display correctly even when upstream APIs omit or change field shapes.
Changes:
- Handle profile facts that may be returned as objects by extracting
.content(instead of printing[object Object]). - Default missing
similarityto0during formatting to avoid[NaN%]displays. - Make
similarityoptional in minimal result shapes and guard sorting/formatting accordingly.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/services/context.ts | Makes similarity optional + formats profile facts more robustly for prompt injection |
| src/index.ts | Guards similarity sorting/formatting in search tool responses and helper formatter |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/services/context.ts
Outdated
| const text = typeof fact === "string" ? fact : (fact as { content?: string }).content ?? String(fact); | ||
| parts.push(`- ${text}`); |
There was a problem hiding this comment.
String(fact) will still render as [object Object] for object-shaped profile items that don't have a content field, which is the same user-facing symptom this change is trying to eliminate. Consider using a more informative object fallback (e.g., JSON stringification) and adding a null check so unexpected null/undefined entries don't cause issues.
src/services/context.ts
Outdated
| const text = typeof fact === "string" ? fact : (fact as { content?: string }).content ?? String(fact); | ||
| parts.push(`- ${text}`); |
There was a problem hiding this comment.
This fact-to-text conversion logic is duplicated for static and dynamic facts. Consider extracting a small helper (with the same safer object fallback) so the formatting stays consistent and easier to evolve.
listMemories API returns null summary by default. Added includeContent param and fallback chain (summary || content || title) so project knowledge entries display actual text instead of blank lines.
Address Copilot review comments: - Extract duplicated fact-to-text logic into reusable helper - Use JSON.stringify instead of String() for unknown object shapes to avoid [object Object] fallback
Summary
Fixes three display bugs in the context injection shown to LLMs:
[object Object]in User Profile — When the profile API returns items as{id, content, metadata}objects instead of plain strings,${fact}calls.toString()producing[object Object]. Now handles both shapes: extracts.contentfor objects, uses string directly otherwise.[NaN%]in Relevant Memories — When the search API returns results without asimilarityfield (e.g. from custom backends/proxies),undefined * 100producesNaN. Now defaults to0via nullish coalescing (similarity ?? 0).Empty content in Project Knowledge —
listMemoriesAPI returnssummary: nullby default without content body. AddedincludeContent: trueparam and fallback chain (summary || content || title || "") so project knowledge entries display actual text instead of blank lines.Changes
src/services/context.ts:.contentwhen neededMath.round((mem.similarity ?? 0) * 100)for both project and user memoriessimilarityfield made optional (similarity?: number)src/services/client.ts:listMemories: addedincludeContent: trueto fetch full memory contentsrc/index.ts:memory: m.summary || m.content || m.title || ""fallback chain(b.similarity ?? 0) - (a.similarity ?? 0)for safe comparisonMath.round((r.similarity ?? 0) * 100)in search tool handler andformatSearchResultssimilarity?: number(optional) informatSearchResultsparameter typeBefore / After