Skip to content

fix(plugin): derive missing crystallization summaries - #2222

Open
RerankerGuo wants to merge 3 commits into
MemTensor:mainfrom
RerankerGuo:fix/issue-2143-crystallize-summary-fallback
Open

fix(plugin): derive missing crystallization summaries#2222
RerankerGuo wants to merge 3 commits into
MemTensor:mainfrom
RerankerGuo:fix/issue-2143-crystallize-summary-fallback

Conversation

@RerankerGuo

Copy link
Copy Markdown
Contributor

Description

Fixes #2143.

When the crystallization LLM returns a structurally useful draft but omits
summary, normalization currently produces an empty string and the default
validator rejects the entire draft.

This change derives a sanitized fallback summary in this order:

  1. retrieval_blurb / retrievalBlurb, when provided by older or alternate models
  2. The first normalized step body or title
  3. The normalized display title or skill name
  4. A final static fallback

Existing non-empty summaries are unchanged. Missing steps remain invalid, so
this does not weaken the structural validator.

Related Issue (Required): Fixes #2143

Type of change

  • Bug fix (non-breaking change which fixes an issue)

How Has This Been Tested?

  • Unit Test
  • Test Script Or Test Steps

Evidence:

  • Before the fix, the two new regressions failed with
    skill.crystallize.invalid: missing summary.
  • npm test -- tests/unit/skill/crystallize.test.ts -> 9 passed.
  • npm run lint -> TypeScript project check passed.
  • npm run build -> plugin build passed.
  • The broader tests/unit/skill run passed 35 tests; 13 database-backed tests
    could not start because the local Node 26 install lacks the
    better-sqlite3 native binding after an --ignore-scripts install.

Impact

  • Breaking change: no
  • Scope: skill draft normalization only
  • Dependencies: none
  • Existing valid summaries and validation of missing steps are unchanged

Checklist

  • I have performed a self-review of my own code
  • I have added tests that prove the fix is effective
  • I have linked the issue to this PR
  • No documentation update is required for this internal recovery path
  • Review requested from @hijzy and @whipser030

Reviewer Checklist

@Memtensor-AI Memtensor-AI added area:plugin OpenClaw & Hermes status:in-progress Someone or AI is working on it | 人工或 AI 正在处理 labels Aug 5, 2026
@Memtensor-AI

Memtensor-AI commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

🤖 Open Code Review

Target: PR #2222
Task: f0d912ead9bac289
Base: main
Head: fix/issue-2143-crystallize-summary-fallback

🔍 OpenCodeReview found 1 issue(s) in this PR.


1. apps/memos-local-plugin/core/skill/crystallize.ts (L369)

String.prototype.slice counts UTF-16 code units, not Unicode code points or grapheme clusters. For content containing multi-byte characters (e.g., Chinese, Japanese, Korean, emoji), this can silently split a surrogate pair and produce a malformed string. Consider using a Unicode-aware truncation, such as [...summarySource].slice(0, MAX_SUMMARY_LENGTH).join('') (splits by code point), or at minimum document that the limit is in code units.

💡 Suggested Change

Before:

  const summary = summarySource.slice(0, MAX_SUMMARY_LENGTH);

After:

  const summary = [...summarySource].slice(0, MAX_SUMMARY_LENGTH).join("");

Generated by cloud-assistant via Open Code Review.

@Memtensor-AI

Copy link
Copy Markdown
Collaborator

✅ Automated Test Results: PASSED

All tests passed (9/9 executed). memos_local_plugin/unit: 9/9. Duration: 3s [advisory, non-gating] AI-generated tests on branch test/auto-gen-32083f8dbbd21f66-20260805162117: 19/19 passed — these do NOT affect the PR verdict; review the branch manually.

Branch: fix/issue-2143-crystallize-summary-fallback

@Memtensor-AI Memtensor-AI added status:ready Ready for implementation; waiting for assignee or AI dispatch | 可进入实现,等待认领或派发 and removed status:in-progress Someone or AI is working on it | 人工或 AI 正在处理 labels Aug 5, 2026
@Memtensor-AI Memtensor-AI added status:in-progress Someone or AI is working on it | 人工或 AI 正在处理 and removed status:ready Ready for implementation; waiting for assignee or AI dispatch | 可进入实现,等待认领或派发 labels Aug 6, 2026
@syzsunshine219

Copy link
Copy Markdown
Collaborator

Updated this PR at a1dcfb2c to address both unresolved OCR findings.

Changes:

  • select the first sanitized summary source, then apply the 200-character cap uniformly to explicit and derived summaries
  • remove the unreachable optional/static fallback; displayTitle is already guaranteed non-empty
  • add a regression test for an explicit 250-character summary (observed failing before the fix, passing after)

Merge status:

  • the PR is already based on the latest main (0 behind / 1 ahead)
  • merge-tree completed without conflicts

Local verification:

  • focused crystallization suite: 10/10 passed
  • complete local-plugin suite: 159 files, 1305 passed, 2 skipped
  • npm run lint: passed
  • npm run build: passed
  • git diff --check: passed

Fresh OCR and AutoTest checks are pending. Python Actions run: https://github.com/MemTensor/MemOS/actions/runs/31122705498 (16 jobs queued while GitHub Actions is under a major outage).

@Memtensor-AI

Copy link
Copy Markdown
Collaborator

✅ Automated Test Results: PASSED

All tests passed (10/10 executed). memos_local_plugin/unit: 10/10. Duration: 3s [advisory, non-gating] AI-generated tests on branch test/auto-gen-afc7396792f82328-20260807012102: 24/25 passed, 1 failed — these do NOT affect the PR verdict; review the branch manually.

Branch: fix/issue-2143-crystallize-summary-fallback

Extract the shared summary clamp into MAX_SUMMARY_LENGTH and cover long retrieval-blurb fallbacks so explicit and derived summaries stay bounded consistently.

Test: npm --prefix apps/memos-local-plugin test -- tests/unit/skill/crystallize.test.ts\nTest: npm --prefix apps/memos-local-plugin run lint\nTest: npm --prefix apps/memos-local-plugin run build
@RerankerGuo

RerankerGuo commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @syzsunshine219 for updating the branch in a1dcfb2c and validating the full plugin suite.

I kept that normalization fix and addressed the remaining OCR finding in 6e824e1c:

  • extracted the shared 200-character cap to MAX_SUMMARY_LENGTH;
  • retained the existing source priority and uniform clamp for explicit and derived summaries;
  • added a regression proving a 250-character retrieval_blurb fallback is sanitized and clamped to 200 characters.

Verification:

  • npm --prefix apps/memos-local-plugin test -- tests/unit/skill/crystallize.test.ts -> 11 passed
  • npm --prefix apps/memos-local-plugin run lint -> passed
  • npm --prefix apps/memos-local-plugin run build -> passed
  • git diff --check -> passed

The complete local-plugin unit run could not complete in this local Node 26 environment because the existing better-sqlite3 native binding is unavailable for Node ABI 147. It reported 955 passed before the database-backed failures. This is the same environment limitation already documented for the earlier branch validation and is unrelated to the two crystallization files.

CI update for run 31557357464:

  • all 8 macOS and all 4 Windows jobs passed;
  • all 4 Ubuntu jobs stopped before build, Ruff, or tests on the unchanged src/memos/embedders/cache.py top-level cachetools import;
  • Open Code Review passed with one non-blocking finding;
  • AutoTest reported an environment issue before tests because its SSH clone failed with kex_exchange_identification: Connection closed by remote host.

I have kept the unrelated core/optional dependency issue out of this PR.

@Memtensor-AI

Copy link
Copy Markdown
Collaborator

⚠️ Automated Test Results: ENV ISSUE

The test environment encountered an issue that requires manual attention.

Details: Executor error: Command failed: git clone --depth 1 --branch fix/issue-2143-crystallize-summary-fallback git@github.com:RerankerGuo/MemOS.git /data/test-workspaces/f0d912ead9bac289/repo
Cloning into '/data/test-workspaces/f0d912ead9bac289/repo'...
nc: read failed (0/4): Broken pipe
kex_exchange_identification: Connection closed by remote host
Connection closed by UNKNOWN port 65535
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
Branch: fix/issue-2143-crystallize-summary-fallback

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:plugin OpenClaw & Hermes status:in-progress Someone or AI is working on it | 人工或 AI 正在处理

Projects

None yet

Development

Successfully merging this pull request may close these issues.

crystallize: defaultDraftValidator throws skill.crystallize.invalid: missing summary when LLM omits summary field

4 participants