Fix #2335: l3.abstraction hard-fails entire world-model generation on empty LLM title (no r - #2338
Conversation
…Tensor#2335) l3.abstraction previously threw LLM_OUTPUT_MALFORMED when the LLM returned an empty/whitespace `title`, aborting the entire world-model generation for the cluster. In production (v2.0.17) this turned a single flaky LLM response into a full pipeline failure. Soften the validator: keep the triple (environment / inference / constraints) as load-bearing but derive `title` from `domain_tags`, first environment label, or a static "Untitled world model" when the LLM leaves it empty. Emit `abstract.title_fallback` warn so ops still see the regression. Apply the same pattern to l2.induction — `title` is a display attribute while `trigger` and `procedure` remain load-bearing.
🤖 Open Code ReviewTarget: PR #2338 🔍 OpenCodeReview found 3 issue(s) in this PR. 1.
|
🔧 Open Code Review requested Agent fixOpen Code Review found 8 issue(s). I have resumed the development Agent to fix them.
The Agent will push a new commit to this PR branch. OCR will recheck after the commit is pushed. |
- Inline the raw-title check in l3.abstract (parity with l2.induce); drop the now-unused isEmptyString helper. - Add rawTitleType to the induce/abstract title_fallback warn logs so operators can distinguish null vs. "" vs. non-string LLM responses. - Route l2.induce.synthesiseTitle through sanitizeDerivedText + the shared truncate() helper so the fallback path matches the normal sanitised/ellipsised path. - Make l3.abstract's titleCaseTag and synthesiseTitle Unicode-safe by iterating over code points instead of UTF-16 code units, so emoji or surrogate-pair tags no longer corrupt the display title. - Drop the outdated docs/openspec/…-2335-….md pointer from the synthesiseTitle JSDoc — the referenced path never landed.
✅ Automated Test Results: PASSEDAll tests passed (16/16 executed). memos_local_plugin/unit: 16/16. Duration: 3s [advisory, non-gating] AI-generated tests on branch test/auto-gen-60cd97aef73c495f-20260903115355: 56/61 passed, 5 failed — these do NOT affect the PR verdict; review the branch manually. Branch: |
Description
Fixes issue #2335:
l3.abstractionno longer aborts a whole cluster's world-model generation when the LLM returns an emptytitle. Thevalidatecallback still requires the triple (environment/inference/constraints) but no longer throws on emptytitle;normaliseDraftsynthesises a fallback title fromdomain_tags(title-cased, joined with " · "), the first non-emptyenvironment[].label, or a static"Untitled world model".abstractDraftemits anabstract.title_fallbackwarn breadcrumb so ops can still spot LLM regressions.Applied the same softening to
l2.induction:titlebecomes a display attribute (falls back tosignatureLabel, else"Untitled policy") whiletriggerandprocedureremain load-bearing and still fail the draft when missing.Verified with vitest: the two focused test files run 16 tests (all passing) and the full
tests/unit/memory/l2 + l3suite runs 89 tests (all passing).tsc -p tsconfig.json --noEmitis clean. Changes touch four files underapps/memos-local-plugin/{core,tests}/memory/{l2,l3}; opsp task file and openspec change artefacts are staged in.ai-tasks/andopenspec/changes/for scheduler archival.Related Issue (Required): Fixes #2335
Type of change
Please delete options that are not relevant.
How Has This Been Tested?
Automated tests are pending.
Checklist
@whipser030, @hijzy please review this PR.
Reviewer Checklist