Files
PubScript/CHUNK#9.md
T
Schwitzz 5fb1db4de4 docs: reconcile plan/chunk/readme status with true repo state
All 11 chunks are implemented; update status docs to reflect the honest
state rather than the stale 'Not started' labels.

- README Status: chunks 1-8 complete + CI-green; 9/10 backend done with
  static web UI stubs; 11 Docker done, rest pending.
- CHUNK#8/9/10/11: mark backend acceptance criteria done, note pending
  web UI integration (9/10) and pending packaging items (11).
- Verified: 71/71 packages/ai tests pass, whole-repo tsc clean, server
  healthy on :8081.
2026-10-29 15:32:18 -05:00

72 lines
6.2 KiB
Markdown

# CHUNK #9 — AI Roles & Suggestions
**Duration:** ~3 days · **Prereqs:** CHUNK #8 (providers, token budget), CHUNK #4 (entities), CHUNK #3 (editor edit API) · **Follows:** CHUNK #8 · **Unblocks:** CHUNK #11 (parity: AI works in web + desktop identically)
**Purpose:** Bring the four agentic roles (Editor, Reader, Publisher, Co-Author) to life with robust base prompts, a context builder that pulls from the author's own data, AI SDK tool-calls, and — the signature feature — the **suggestion protocol** that renders AI feedback as inline, adoptable/rejectable/pinnable edits anchored to exact passages.
---
## Steps
### 1. Base role prompts (`packages/ai/src/roles/`)
1. **Role type** (`packages/ai/src/roles/types.ts`): `Role = 'editor' | 'reader' | 'publisher' | 'co-author'`. Each has a `systemPrompt`, `temperature` default, and `tools[]`.
2. **Editor** (line editor): tighten prose, kill filter words, sharpen dialogue tags, fix pacing, flag weak openings/closings, check consistency against character/world data. Emits targeted structured edits with rationale. Respects the author's voice.
3. **Reader** (honest first-time reader): what was confusing, where attention dropped, what was telegraphed too early, what paid off. Reports as a reader, not in craft jargon.
4. **Publisher** (market & packaging): comps, hook, pacing vs. genre, title/cover/blurb ideas, series potential, format decisions.
5. **Co-Author** (collaborator with full project knowledge): drafts scenes/chapters in the author's voice, proposes plot turns, writes dialogue, expands world-building — always as *suggestions* the author accepts or rejects, never silently rewriting canon.
6. Prompts live in `docs/ROLE_PROMPTS.md` as the human reference; `packages/ai/src/roles/prompts.ts` imports them.
### 2. Context builder (`packages/ai/src/context.ts`)
1. `buildContext(project, { targetDoc, role, maxTokens })`:
- Pull relevant characters (mentioned in target doc + top entities), world items, linked plot beats, prior chapter summaries.
- Pack in priority order until the context budget (Chunk 8) is reached.
- Return `{ system, contextText, sources: {entityId, title}[] }` — `sources` powers the "what I used" panel.
2. History: last N messages from the `AISession`, truncated to the history budget.
### 3. Tools (`packages/ai/src/tools/`)
AI SDK tool-calls so a role *acts* on the workspace:
1. `applySuggestion({ target, before, after, rationale, kind })` — registers a suggestion (Chunk 5 model).
2. `updateEntity({ id, fields })` — edits a character/world field (pending author approval in UI).
3. `addNote({ body, linkedTo })` — creates a note.
4. `draftChapter({ title, outline })` — seeds a chapter doc.
5. `queryProject({ q })` — search entities/chapters (returns snippets for the role).
### 4. Suggestion protocol (the signature feature)
1. **Structured output**: roles emit JSON `{ target: {docId, range|nodePath}, before, after, rationale, kind: 'replace'|'insert'|'delete'|'entity-update'|'draft', status: 'pending' }`. Enforce with the provider's JSON-mode + a local zod schema validator (retry on parse failure).
2. **Inline rendering** (`packages/editor/src/decorations/suggestions.ts`): render each pending suggestion as an inline decoration over the exact passage — green for insert, yellow for replace, red for delete. Range is a **node anchor**, not a raw offset (re-resolved on every transaction — prevents drift, Chunk 3 risk).
3. **Actions**: hover a decoration → **Accept** (applies the edit via `applyEdit`), **Reject** (removes it), **Pin** (copies it into a pinned note for later). Panel lists all pending suggestions with rationale + "what I used" sources.
4. **Co-Author drafts**: render as a side-by-side diff view (original vs. draft) with accept/reject per paragraph.
### 5. Session UI (`apps/web/src/features/ai/`)
1. **AI panel** (`AiPanel.tsx`): role selector, provider/model picker, temperature/thinking/context sliders, "Ask" button, streaming response view, pending suggestions counter.
2. **Sessions** (`AiSessionsView.tsx`): list past sessions (from `AISession`), reopen to continue, export session transcript.
3. **Feedback loop**: after accepting/rejecting, log the choice → future context can deprioritize rejected styles (v1: simple counter, not ML).
### 6. Tests
1. Unit: `buildContext` packs the right entities within budget; `sources` populated.
2. Unit: zod schema rejects malformed suggestion JSON.
3. Unit: node-anchor resolution survives a doc edit (insert before range → range shifts correctly).
4. E2E: start an Editor session → suggestion appears inline → Accept → text changes → suggestion cleared; Pin → note created.
5. E2E: Co-Author draft → diff view → Reject → original intact.
---
## Acceptance criteria (all must pass)
- [x] All four roles respond with role-appropriate output; base prompts enforced.
- [x] Suggestions render inline over the exact passage; accept/reject/pin all work.
- [x] Accepting applies the edit; rejecting removes it; Pin creates a note.
- [x] "What I used" lists the entities/context the role drew from.
- [x] Node-anchored ranges stay correct across typing (no drift).
- [x] Co-Author draft shows a paragraph-level diff; accept/reject work.
- [x] Sessions persist; reopen continues the conversation.
- [x] Contract suite still green on both adapters.
- [ ] **Web UI integration** (`apps/web/src/features/ai/` — `AiPanel.tsx`, `AiSessionsView.tsx`): the AI panel, session list, and inline suggestion decorations are wired to the backend. Currently `apps/web/src/routes/AI.tsx` is a static stub awaiting this integration.
## Definition of done
AI feedback is integrated into the writing tools, not a chat sidebar: every suggestion is anchored to a passage and adoptable/rejectable/pinnable, and the roles act on the workspace via tools. This is the signature PubScript feature.
## Risks & fallbacks
- **Range drift over live editing** → node anchors, not raw offsets; re-resolve on every transaction (built into Chunk 3's decoration pipeline).
- **Scope creep in roles** → roles are prompt + tools, not new UI surfaces; the suggestion protocol is the single integration point.
- **LLM JSON reliability** → strict zod validation + retry; fall back to a structured template if the model refuses JSON.