fix(dreamer): reject whitespace-only map-memories output before validation

Draft
IC
4h ago
+101-14

Refs #718

Summary

Fixes map-memories validation rejecting valid model output when assistantText returns whitespace-only. Full root-cause analysis and evidence are in the linked issue.

Change

Tighten the module-private assistantText in packages/plugin/src/features/magic-context/dreamer/map-memories.ts to return null for whitespace-only output, so the || text fallback (hidden path) and the || ... fallback fire instead of validating whitespace. Make the client path (validateOutput) null-safe. Extract the two validation dispatch callbacks into named functions for testability.

  • assistantText: return joined.trim() ? joined : null (whitespace-only → null; un-trimmed content preserved so currentManifest slicing is unaffected).
  • Client path: raw == null guard before currentManifest (→ "map-memories returned no output").
  • Hidden path (:492) and the failure-recovery site (:621) are unchanged and benefit automatically via ||.

Behavior note

On the client path, whitespace-only output now throws map-memories returned no output instead of missing complete root element — a more accurate message; intentional. The hasLengthCappedOutput guard is preserved from the original :576 and is covered by a test.

Harness coverage (required)

  • OpenCode 1: covered — validation lives in the shared TS core (packages/plugin/src/features/magic-context/dreamer/).
  • OpenCode 2: covered — same shared core.
  • Pi: covered — reuses the shared core via @magic-context/core (task-executor imports mapMemories).
  • OMP: covered — same shared core path as Pi.
  • Rust module: not applicable — crates/ contains no manifest validation (grep-confirmed: no validateMapMemoriesManifest / extractCompleteManifestBody / mappingsBody).

Tests

bun test map-memories.test.ts: 41 pass / 0 fail (12 new regression tests). Both dispatch paths covered: whitespace / empty / tool-only → fall back to completion.text (hidden) or "no output" (client); a real manifest carried by messages keeps priority over completion.text; length-capped guard preserved. Replay reproduced fail-before / pass-after for both paths.


Summary by cubic

Fixes map-memories validation rejecting valid model output when assistantText returns whitespace-only content. assistantText now returns null for whitespace-only output, so the hidden path falls back to completion.text (the real manifest) and the client path throws map-memories returned no output instead of validating whitespace as a manifest.

  • Extracted the two validation dispatch callbacks into the exported parseMapMemoriesCompletion and validateClientMapMemories helpers for direct testing.
  • Added regression tests covering whitespace, empty, and tool-only messages on both paths, plus the preserved length-capped guard.

RetriggerView in GreptileConfidence Score: 4/5

The PR should not merge until the previously reported ID type mismatch is fixed.

Findings

  1. P1 New helpers fail type checking ▶

Summary

The PR treats whitespace-only assistant output as missing output.

  • Map-memories treats whitespace-only assistant text as absent.

Reviews (2) · Last reviewed commit: "fix(dreamer): reject whitespace-only map..." · Reviewed by Greptile