Skip to content

fix: handle missing similarity and object profile items in context display#26

Open
kui123456789 wants to merge 3 commits intosupermemoryai:mainfrom
kui123456789:fix/context-display-bugs
Open

fix: handle missing similarity and object profile items in context display#26
kui123456789 wants to merge 3 commits intosupermemoryai:mainfrom
kui123456789:fix/context-display-bugs

Conversation

@kui123456789
Copy link

@kui123456789 kui123456789 commented Mar 1, 2026

Summary

Fixes three display bugs in the context injection shown to LLMs:

  1. [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 .content for objects, uses string directly otherwise.

  2. [NaN%] in Relevant Memories — When the search API returns results without a similarity field (e.g. from custom backends/proxies), undefined * 100 produces NaN. Now defaults to 0 via nullish coalescing (similarity ?? 0).

  3. Empty content in Project KnowledgelistMemories API returns summary: null by default without content body. Added includeContent: true param and fallback chain (summary || content || title || "") so project knowledge entries display actual text instead of blank lines.

Changes

  • src/services/context.ts:

    • Profile items: detect string vs object, extract .content when needed
    • Similarity: Math.round((mem.similarity ?? 0) * 100) for both project and user memories
    • Interface: similarity field made optional (similarity?: number)
  • src/services/client.ts:

    • listMemories: added includeContent: true to fetch full memory content
  • src/index.ts:

    • Project memory mapping: memory: m.summary || m.content || m.title || "" fallback chain
    • Sort: (b.similarity ?? 0) - (a.similarity ?? 0) for safe comparison
    • Display: Math.round((r.similarity ?? 0) * 100) in search tool handler and formatSearchResults
    • Type: similarity?: number (optional) in formatSearchResults parameter type

Before / After

# Before
User Profile:
- [object Object]
- [object Object]
Project Knowledge:
- [100%] 
- [100%] 
Relevant Memories:
- [NaN%] 
- [NaN%] 

# After
User Profile:
- WSL2 Ubuntu-22.04 用户名为 z1803
- Git 用户名为 kui123456789
Project Knowledge:
- [100%] Conversation about opencode memory plugin development
Relevant Memories:
- [85%] some memory content

Copilot AI review requested due to automatic review settings March 1, 2026 19:09
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 similarity to 0 during formatting to avoid [NaN%] displays.
  • Make similarity optional 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.

Comment on lines 27 to 28
const text = typeof fact === "string" ? fact : (fact as { content?: string }).content ?? String(fact);
parts.push(`- ${text}`);
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines 35 to 36
const text = typeof fact === "string" ? fact : (fact as { content?: string }).content ?? String(fact);
parts.push(`- ${text}`);
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants