Skip to content

feat(kb): edit documents in place with textReplacements and pick the response shape - #896

Open
kmonsoe wants to merge 1 commit into
feat/cms-block-editsfrom
feat/kb-text-replacements
Open

feat(kb): edit documents in place with textReplacements and pick the response shape#896
kmonsoe wants to merge 1 commit into
feat/cms-block-editsfrom
feat/kb-text-replacements

Conversation

@kmonsoe

@kmonsoe kmonsoe commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Stacked on #895 — merge that first, then retarget this PR to main before merging it.

Why

A knowledge-base document is one markdown body that the support agent answers from verbatim. Changing one fact today means resending the whole body, and a regenerated body drifts: a caveat disappears, a number gets rounded. Same problem #895 fixes for CMS entries, same fix.

What

kb_update_document gains textReplacements — an ordered, all-or-nothing list of { oldText, newText, replaceAll? } edits applied to the stored body, reusing the shared helper from #895.

  • Each oldText must match exactly once, or set replaceAll. Zero matches fails with kb_replacement_no_match, several with kb_replacement_ambiguous; nothing is written and version does not move.
  • body and textReplacements are alternatives; sending both is rejected.
  • Title, tags, audiences and sourceUrl ride along on the same call as before.
  • The /v1/kb/candidates/:id PATCH accepts the same field. KbInvalidError now carries a code, and the candidates controller passes it through, so the dashboard can translate these errors if it ever needs to.

responseFormat: "full" | "summary" on kb_create_document, kb_update_document, kb_restore_version and kb_publish_curation_revision, defaulting to full. summary shortens the body to a lead and reports its word count in bodySummary.

kb_propose_curation_revision deliberately still takes the full proposed body — the reviewer sees it diffed against the current document — and the new skill says so.

Skills

New skill://kb/revise-document owns the editing loop. import-from-google-docs and review-content point at it for small edits. Fixtures regenerated.

Tests

  • kb.service.test.ts: happy path with ordered edits and replaceAll, coded failures leave the row untouched, body/replacements overlap rejected, summary presenter for long and short bodies.
  • kb.integration.test.ts: the surface through /mcp, including error codes in the tool result and responseFormat on create and restore.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VJjhaB9bMU1agbqVKTwbB1

…response shape

kb_update_document takes textReplacements — ordered, all-or-nothing exact-match
edits applied to the stored body, sharing the CMS implementation — so an agent
can correct a fact without regenerating the document. Document-returning write
tools take responseFormat (full | summary). KbInvalidError carries a code so
kb_replacement_no_match and kb_replacement_ambiguous reach the control plane.
New skill://kb/revise-document documents the loop.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VJjhaB9bMU1agbqVKTwbB1
@kmonsoe
kmonsoe force-pushed the feat/kb-text-replacements branch from 52bd3f3 to ff08c16 Compare September 6, 2026 18:45
@kmonsoe
kmonsoe changed the base branch from feat/cms-text-replacements to feat/cms-block-edits September 6, 2026 18:45
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.

1 participant