Skip to content

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

Description

@kiwipaulrob

Description

The defaultDraftValidator in crystallize.ts throws skill.crystallize.invalid: missing summary when the LLM returns valid JSON but omits the required summary key. This is a separate failure mode from the empty-response case addressed by PR #2064.

Reproduction

The LLM (e.g. DeepSeek V4 Flash) occasionally returns valid JSON skill drafts without a summary key. The validator at line ~303 checks if (!draft.summary) and throws immediately. This happens every 5-10 seconds in a busy bridge, flooding logs and blocking the crystallizer queue.

Proposed Fix

Instead of throwing, auto-generate a fallback summary from available fields in priority order:

  1. retrievalBlurb (first)
  2. First step body or title
  3. Skill name
  4. Static placeholder "skill procedure"

The autoSummary fallback should never be empty so the function never throws for missing summary.

if (!draft.summary) {
    const autoSummary = draft.retrievalBlurb
        || (draft.steps?.[0]?.body || draft.steps?.[0]?.title)
        || draft.name
        || "skill procedure";
    draft.summary = autoSummary.slice(0, 200);
}

Impact

Without this fix, bridge logs fill with 10+ ERROR skill.crystallize.failed messages per minute. The crystallizer accumulates a backlog and other RPC requests (like memory.search) can time out waiting for the queue to drain.

Environment

  • MemOS version: v2.0.19 (plugin install from dev branch)
  • LLM: DeepSeek V4 Flash via openai_compatible provider
  • Embedding: local ONNX (Xenova/all-MiniLM-L6-v2, 384-dim)
  • Hermes Agent with memos-local-plugin

Metadata

Metadata

Labels

area:pluginOpenClaw & Hermesstatus:needs-triageNeeds initial triage | 需要初步判断 & 问题复现

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions