---
### π Π€Π°ΠΉΠ»: `TASKS.md` (ΠΡΠ°ΠΏ 1: ΠΠΎΠ»Π½ΡΠΉ ΡΠ°Π·Π±ΠΎΡ)
```markdown
# ΠΠ°Π΄Π°ΡΠΈ ΠΏΡΠΎΠ΅ΠΊΡΠ° Writer IDE
## π’ ΠΡΠ°ΠΏ 1: Π€ΡΠ½Π΄Π°ΠΌΠ΅Π½Ρ, Layout ΠΈ ΠΠ°Π·ΠΎΠ²ΡΠΉ Π Π΅Π΄Π°ΠΊΡΠΎΡ
### ΠΠ°Π΄Π°ΡΠ° 1.1: ΠΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ Frontend ΠΈ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠ° Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠ΅ΠΉ
**ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅**: Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ Next.js ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΈ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠ° Π²ΡΠ΅Ρ
Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΡΡ
Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊ Π΄Π»Ρ ΠΡΠ°ΠΏΠ° 1.
**ΠΡΠΈΡΠ΅ΡΠΈΠΈ ΡΡΠΏΠ΅Ρ
Π°**:
- ΠΠΎΠΌΠ°Π½Π΄Π° `npm run dev` Π² ΠΏΠ°ΠΏΠΊΠ΅ `frontend` Π·Π°ΠΏΡΡΠΊΠ°Π΅Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π° `localhost:3000`.
- Tailwind CSS ΡΠ°Π±ΠΎΡΠ°Π΅Ρ (ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° ΡΠ΅ΡΠ΅Π· ΠΊΠ»Π°ΡΡ `bg-red-500`).
**ΠΠ½ΡΡΡΡΠΊΡΠΈΡ Π΄Π»Ρ AI-Π°Π³Π΅Π½ΡΠ°**:
> "ΠΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΡΠΉ Next.js ΠΏΡΠΎΠ΅ΠΊΡ Π² ΡΠ΅ΠΊΡΡΠ΅ΠΉ ΠΏΠ°ΠΏΠΊΠ΅ Ρ TypeScript, Tailwind, App Router ΠΈ src-Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠ΅ΠΉ. ΠΠ°ΡΠ΅ΠΌ ΡΡΡΠ°Π½ΠΎΠ²ΠΈ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ: `@tiptap/react`, `@tiptap/starter-kit`, `@tiptap/extension-text-style`, `@tiptap/extension-color`, `@tiptap/extension-blockquote`, `@tiptap/extension-underline`, `zustand`, `lucide-react`, `axios`. Π£Π±Π΅Π΄ΠΈΡΡ, ΡΡΠΎ `tailwind.config.ts` Π½Π°ΡΡΡΠΎΠ΅Π½ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎ."
---
### ΠΠ°Π΄Π°ΡΠ° 1.2: ΠΠ°ΡΡΡΠΎΠΉΠΊΠ° Zustand Store (Π‘ΠΎΡΡΠΎΡΠ½ΠΈΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ)
**ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅**: Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π³Π»ΠΎΠ±Π°Π»ΡΠ½ΠΎΠ³ΠΎ Ρ
ΡΠ°Π½ΠΈΠ»ΠΈΡΠ° Π΄Π»Ρ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ Π°ΠΊΡΠΈΠ²Π½ΡΠΌ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠΎΠΌ, Π΅Π³ΠΎ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΡΠΌ ΠΈ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ Π±ΠΎΠΊΠΎΠ²ΡΡ
ΠΏΠ°Π½Π΅Π»Π΅ΠΉ.
**ΠΡΠΈΡΠ΅ΡΠΈΠΈ ΡΡΠΏΠ΅Ρ
Π°**:
- Π‘ΠΎΠ·Π΄Π°Π½ ΡΠ°ΠΉΠ» `frontend/src/stores/appStore.ts`.
- Store ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ: `activeDocumentId`, `documents` (ΠΌΠ°ΡΡΠΈΠ² ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Ρ id, title, content), ΡΡΠ½ΠΊΡΠΈΠΈ `setActiveDocument`, `updateDocumentContent`.
**ΠΠ½ΡΡΡΡΠΊΡΠΈΡ Π΄Π»Ρ AI-Π°Π³Π΅Π½ΡΠ°**:
> "Π‘ΠΎΠ·Π΄Π°ΠΉ Zustand store Π² `src/stores/appStore.ts`. ΠΠΏΡΠ΅Π΄Π΅Π»ΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ `Document` (id: string, title: string, content: string, type: 'scene' | 'chapter'). ΠΠΎΠ±Π°Π²Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ Π΄Π»Ρ ΡΠΏΠΈΡΠΊΠ° Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠΎΠ² ΠΈ Π°ΠΊΡΠΈΠ²Π½ΠΎΠ³ΠΎ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°, Π° ΡΠ°ΠΊΠΆΠ΅ ΡΠΊΡΠ΅Π½Ρ Π΄Π»Ρ ΠΈΡ
ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ. ΠΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΡΠΉ store ΠΎΠ΄Π½ΠΈΠΌ ΡΠ΅ΡΡΠΎΠ²ΡΠΌ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠΎΠΌ."
---
### ΠΠ°Π΄Π°ΡΠ° 1.3: ΠΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ° Layout (Π’ΡΠ΅Ρ
ΠΊΠΎΠ»ΠΎΠ½ΠΎΡΠ½ΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ)
**ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅**: Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠ³ΠΎ ΠΌΠ°ΠΊΠ΅ΡΠ° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ `src/app/layout.tsx` ΠΈ `src/app/page.tsx` Ρ ΡΡΠ΅ΠΌΡ ΠΊΠΎΠ»ΠΎΠ½ΠΊΠ°ΠΌΠΈ.
**ΠΡΠΈΡΠ΅ΡΠΈΠΈ ΡΡΠΏΠ΅Ρ
Π°**:
- ΠΠ΅Π²Π°Ρ ΠΊΠΎΠ»ΠΎΠ½ΠΊΠ° (w-64): ΠΠ°Π³Π»ΡΡΠΊΠ° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ° `FileExplorer`.
- Π‘ΡΠ΅Π΄Π½ΡΡ ΠΊΠΎΠ»ΠΎΠ½ΠΊΠ° (w-72): ΠΠ°Π³Π»ΡΡΠΊΠ° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ° `StoryExplorer`.
- ΠΡΠ°Π²Π°Ρ ΠΊΠΎΠ»ΠΎΠ½ΠΊΠ° (flex-1): ΠΠ±Π»Π°ΡΡΡ Π΄Π»Ρ ΡΠ΅Π΄Π°ΠΊΡΠΎΡΠ°.
- ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ CSS Grid ΠΈΠ»ΠΈ Flexbox. ΠΠ΄Π°ΠΏΡΠΈΠ²Π½ΠΎΡΡΡ: Π½Π° ΡΠΊΡΠ°Π½Π°Ρ
< 1024px Π±ΠΎΠΊΠΎΠ²ΡΠ΅ ΠΏΠ°Π½Π΅Π»ΠΈ ΡΠΊΡΡΠ²Π°ΡΡΡΡ (ΠΈΠ»ΠΈ ΡΠΆΠΈΠΌΠ°ΡΡΡΡ).
**ΠΠ½ΡΡΡΡΠΊΡΠΈΡ Π΄Π»Ρ AI-Π°Π³Π΅Π½ΡΠ°**:
> "Π‘ΠΎΠ·Π΄Π°ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ-Π·Π°Π³Π»ΡΡΠΊΠΈ `FileExplorer.tsx` ΠΈ `StoryExplorer.tsx` Π² `src/components/sidebar/`. Π Π΅Π°Π»ΠΈΠ·ΡΠΉ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ Layout Π² `src/app/page.tsx`, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ Flexbox ΠΈΠ»ΠΈ Grid Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΡΡΠ΅Ρ
ΠΊΠΎΠ»ΠΎΠ½ΠΎΠΊ Ρ ΡΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΉ ΡΠΈΡΠΈΠ½ΠΎΠΉ Π΄Π»Ρ ΡΠ°ΠΉΠ΄Π±Π°ΡΠΎΠ² ΠΈ `flex-1` Π΄Π»Ρ ΡΠ΅Π½ΡΡΠ°Π»ΡΠ½ΠΎΠΉ ΠΎΠ±Π»Π°ΡΡΠΈ. ΠΡΠΈΠΌΠ΅Π½ΠΈ ΡΠ΅ΠΌΠ½ΡΡ/ΡΠ²Π΅ΡΠ»ΡΡ ΡΠ΅ΠΌΡ ΡΠ΅ΡΠ΅Π· Tailwind."
---
### ΠΠ°Π΄Π°ΡΠ° 1.4: Π―Π΄ΡΠΎ Tiptap Π Π΅Π΄Π°ΠΊΡΠΎΡΠ°
**ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅**: Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΠ΅ΡΠ΅ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ° ΡΠ΅Π΄Π°ΠΊΡΠΎΡΠ° Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΎΠΉ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ ΡΠΎΡΠΌΠ°ΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ.
**ΠΡΠΈΡΠ΅ΡΠΈΠΈ ΡΡΠΏΠ΅Ρ
Π°**:
- ΠΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ `src/components/editor/Editor.tsx` ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΡΠ΅Ρ `useEditor` Ρ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡΠΌΠΈ: `StarterKit`, `TextStyle`, `Color`, `Underline`, `Blockquote`.
- Π Π΅Π΄Π°ΠΊΡΠΎΡ ΠΏΡΠΈΠ²ΡΠ·Π°Π½ ΠΊ Zustand store (Π·Π°Π³ΡΡΠΆΠ°Π΅Ρ `content` Π°ΠΊΡΠΈΠ²Π½ΠΎΠ³ΠΎ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ° ΠΈ ΡΠΎΡ
ΡΠ°Π½ΡΠ΅Ρ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ ΡΠ΅ΡΠ΅Π· `onUpdate`).
**ΠΠ½ΡΡΡΡΠΊΡΠΈΡ Π΄Π»Ρ AI-Π°Π³Π΅Π½ΡΠ°**:
> "Π‘ΠΎΠ·Π΄Π°ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ `Editor.tsx`. ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉ `@tiptap/react`. ΠΠΎΠ΄ΠΊΠ»ΡΡΠΈ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡ: StarterKit, TextStyle, Color, Underline, Blockquote. ΠΠ°ΡΡΡΠΎΠΉ `onUpdate`, ΡΡΠΎΠ±Ρ ΠΏΡΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ ΡΠ΅ΠΊΡΡΠ° Π²ΡΠ·ΡΠ²Π°Π»ΡΡ ΡΠΊΡΠ΅Π½ `updateDocumentContent` ΠΈΠ· `appStore`. ΠΠ±Π΅ΡΠ½ΠΈ ΡΠ΅Π΄Π°ΠΊΡΠΎΡ Π² div Ρ ΠΊΠ»Π°ΡΡΠ°ΠΌΠΈ Π΄Π»Ρ ΠΊΡΠ°ΡΠΈΠ²ΠΎΠ³ΠΎ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ (max-w-3xl, mx-auto, prose)."
---
### ΠΠ°Π΄Π°ΡΠ° 1.5: ΠΠ°Π½Π΅Π»Ρ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΎΠ² (Toolbar) Π΄Π»Ρ ΡΠΎΡΠΌΠ°ΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ
**ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅**: Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΠ»Π°Π²Π°ΡΡΠ΅ΠΉ ΠΈΠ»ΠΈ Π²Π΅ΡΡ
Π½Π΅ΠΉ ΠΏΠ°Π½Π΅Π»ΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠΎΠ² Π΄Π»Ρ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ ΡΡΠΈΠ»ΡΠΌΠΈ ΡΠ΅ΠΊΡΡΠ°.
**ΠΡΠΈΡΠ΅ΡΠΈΠΈ ΡΡΠΏΠ΅Ρ
Π°**:
- ΠΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ `src/components/editor/Toolbar.tsx`.
- ΠΠ½ΠΎΠΏΠΊΠΈ Π΄Π»Ρ: Bold, Italic, Underline, Blockquote, Π²ΡΠ±ΠΎΡ ΡΠ²Π΅ΡΠ° ΡΠ΅ΠΊΡΡΠ° (ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠΉ `` Π΄Π»Ρ ΠΏΡΠΎΡΡΠΎΡΡ).
- ΠΠ½ΠΎΠΏΠΊΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ `editor.chain().focus().toggleBold().run()` ΠΈ Π°Π½Π°Π»ΠΎΠ³ΠΈ.
**ΠΠ½ΡΡΡΡΠΊΡΠΈΡ Π΄Π»Ρ AI-Π°Π³Π΅Π½ΡΠ°**:
> "Π‘ΠΎΠ·Π΄Π°ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ `Toolbar.tsx`, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ `editor` ΠΈΠ· Tiptap ΠΊΠ°ΠΊ ΠΏΡΠΎΠΏΡ. Π Π΅Π°Π»ΠΈΠ·ΡΠΉ ΠΊΠ½ΠΎΠΏΠΊΠΈ ΡΠΎΡΠΌΠ°ΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ Lucide React ΠΈΠΊΠΎΠ½ΠΎΠΊ. ΠΠΎΠ±Π°Π²Ρ ΠΏΡΠΎΡΡΡΡ Π»ΠΎΠ³ΠΈΠΊΡ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΊΠΈ Π°ΠΊΡΠΈΠ²Π½ΠΎΠΉ ΠΊΠ½ΠΎΠΏΠΊΠΈ (ΡΠ΅ΡΠ΅Π· `editor.isActive('bold')`). Π Π°Π·ΠΌΠ΅ΡΡΠΈ ΡΡΠΎΡ Toolbar Π½Π°Π΄ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠΌ Editor."
---
### ΠΠ°Π΄Π°ΡΠ° 1.6: ΠΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ Backend (FastAPI)
**ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅**: ΠΠ°Π·ΠΎΠ²Π°Ρ Π½Π°ΡΡΡΠΎΠΉΠΊΠ° Python-ΡΠ΅ΡΠ²Π΅ΡΠ° Π΄Π»Ρ ΠΎΠ±ΡΠ»ΡΠΆΠΈΠ²Π°Π½ΠΈΡ frontend ΠΈ ΠΏΠΎΠ΄Π³ΠΎΡΠΎΠ²ΠΊΠΈ ΠΊ ΡΠ°Π±ΠΎΡΠ΅ Ρ ΡΠ°ΠΉΠ»Π°ΠΌΠΈ.
**ΠΡΠΈΡΠ΅ΡΠΈΠΈ ΡΡΠΏΠ΅Ρ
Π°**:
- Π€Π°ΠΉΠ» `backend/main.py` Π·Π°ΠΏΡΡΠΊΠ°Π΅ΡΡΡ ΡΠ΅ΡΠ΅Π· `uvicorn main:app --reload`.
- ΠΠ°ΡΡΡΠΎΠ΅Π½ CORS middleware, ΡΠ°Π·ΡΠ΅ΡΠ°ΡΡΠΈΠΉ Π·Π°ΠΏΡΠΎΡΡ Ρ `http://localhost:3000`.
- ΠΠ½Π΄ΠΏΠΎΠΈΠ½Ρ `GET /api/health` Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ `{"status": "ok"}`.
**ΠΠ½ΡΡΡΡΠΊΡΠΈΡ Π΄Π»Ρ AI-Π°Π³Π΅Π½ΡΠ°**:
> "Π‘ΠΎΠ·Π΄Π°ΠΉ Π±Π°Π·ΠΎΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ FastAPI Π² `backend/main.py`. ΠΠΎΠ±Π°Π²Ρ `CORSMiddleware` Ρ ΡΠ°Π·ΡΠ΅ΡΠ΅Π½Π½ΡΠΌΠΈ ΠΈΡΡΠΎΡΠ½ΠΈΠΊΠ°ΠΌΠΈ `http://localhost:3000`. Π‘ΠΎΠ·Π΄Π°ΠΉ ΠΏΡΠΎΡΡΠΎΠΉ ΡΠΎΡΡΠ΅Ρ `/api/health`. ΠΠ°ΠΏΠΈΡΠΈ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΡ ΠΏΠΎ Π·Π°ΠΏΡΡΠΊΡ (ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ venv, `pip install fastapi uvicorn pydantic`, Π·Π°ΠΏΡΡΠΊ)."
---
### ΠΠ°Π΄Π°ΡΠ° 1.7: ΠΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΡ Frontend ΠΈ Backend (Π‘ΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΠ΅/ΠΠ°Π³ΡΡΠ·ΠΊΠ°)
**ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅**: Π‘Π²ΡΠ·ΡΠ²Π°Π½ΠΈΠ΅ Zustand store Ρ Backend Π΄Π»Ρ ΠΈΠΌΠΈΡΠ°ΡΠΈΠΈ ΡΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΡ Π΄Π°Π½Π½ΡΡ
(ΠΏΠΎΠΊΠ° Π² ΠΏΠ°ΠΌΡΡΠΈ ΠΈΠ»ΠΈ ΠΏΡΠΎΡΡΠΎΠΌ JSON).
**ΠΡΠΈΡΠ΅ΡΠΈΠΈ ΡΡΠΏΠ΅Ρ
Π°**:
- ΠΡΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ ΡΠ΅ΠΊΡΡΠ° Π² ΡΠ΅Π΄Π°ΠΊΡΠΎΡΠ΅, ΡΠ΅ΡΠ΅Π· debounced-Π·Π°ΠΏΡΠΎΡ (ΠΈΠ»ΠΈ ΠΏΠΎ ΠΊΠ½ΠΎΠΏΠΊΠ΅ "Π‘ΠΎΡ
ΡΠ°Π½ΠΈΡΡ") Π΄Π°Π½Π½ΡΠ΅ ΠΎΡΠΏΡΠ°Π²Π»ΡΡΡΡΡ Π½Π° backend.
- ΠΡΠΈ Π·Π°Π³ΡΡΠ·ΠΊΠ΅ ΡΡΡΠ°Π½ΠΈΡΡ frontend Π·Π°ΠΏΡΠ°ΡΠΈΠ²Π°Π΅Ρ ΡΠΏΠΈΡΠΎΠΊ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠΎΠ² ΠΈ ΠΊΠΎΠ½ΡΠ΅Π½Ρ Π°ΠΊΡΠΈΠ²Π½ΠΎΠ³ΠΎ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ° Ρ backend.
**ΠΠ½ΡΡΡΡΠΊΡΠΈΡ Π΄Π»Ρ AI-Π°Π³Π΅Π½ΡΠ°**:
> "Π‘ΠΎΠ·Π΄Π°ΠΉ Π² `backend` ΠΏΡΠΎΡΡΠΎΠΉ in-memory ΡΠΏΠΈΡΠΎΠΊ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠΎΠ² (ΠΈΠ»ΠΈ Π·Π°ΠΏΠΈΡΡ Π² `data.json`). ΠΠΎΠ±Π°Π²Ρ ΡΠ½Π΄ΠΏΠΎΠΈΠ½ΡΡ `GET /api/documents` ΠΈ `POST /api/documents/{id}/content`. Π `frontend/src/lib/api.ts` ΡΠΎΠ·Π΄Π°ΠΉ ΡΠΈΠΏΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ Π΄Π»Ρ ΡΡΠΈΡ
Π·Π°ΠΏΡΠΎΡΠΎΠ². ΠΠ±Π½ΠΎΠ²ΠΈ `appStore`, ΡΡΠΎΠ±Ρ ΠΎΠ½ Π·Π°Π³ΡΡΠΆΠ°Π» Π΄Π°Π½Π½ΡΠ΅ ΠΏΡΠΈ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ."
---
## π‘ ΠΡΠ°ΠΏ 2: AI ΠΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΡ ΠΈ Inline-Π΄Π΅ΠΉΡΡΠ²ΠΈΡ
### ΠΠ°Π΄Π°ΡΠ° 2.1: Backend AI ΡΠ΅ΡΠ²ΠΈΡ (Π±Π°Π·ΠΎΠ²ΡΠΉ ΡΠΎΡΡΠ΅Ρ Π΄Π»Ρ LLM)
**ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅**: Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΡΠ΅ΡΠ²ΠΈΡΠ° Π½Π° backend Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Ρ AI-ΠΌΠΎΠ΄Π΅Π»ΡΠΌΠΈ (Ollama Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎ ΠΈ OpenRouter API).
**ΠΡΠΈΡΠ΅ΡΠΈΠΈ ΡΡΠΏΠ΅Ρ
Π°**:
- Π‘ΠΎΠ·Π΄Π°Π½ ΡΠ°ΠΉΠ» `backend/services/llm_router.py`
- Π‘Π΅ΡΠ²ΠΈΡ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ Π΄Π²Π° ΠΏΡΠΎΠ²Π°ΠΉΠ΄Π΅ΡΠ°: `ollama` ΠΈ `openrouter`
- ΠΠ½Π΄ΠΏΠΎΠΈΠ½Ρ `POST /api/ai/generate` ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ ΠΏΡΠΎΠΌΠΏΡ ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΡΠ³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ ΡΠ΅ΠΊΡΡ
- ΠΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠ° Π²ΡΠ±ΠΎΡΠ° ΠΌΠΎΠ΄Π΅Π»ΠΈ ΡΠ΅ΡΠ΅Π· ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ Π·Π°ΠΏΡΠΎΡΠ°
**ΠΠ½ΡΡΡΡΠΊΡΠΈΡ Π΄Π»Ρ AI-Π°Π³Π΅Π½ΡΠ°**:
> "Π‘ΠΎΠ·Π΄Π°ΠΉ ΡΠ΅ΡΠ²ΠΈΡ `backend/services/llm_router.py` Ρ ΠΊΠ»Π°ΡΡΠΎΠΌ `LLMRouter`. Π Π΅Π°Π»ΠΈΠ·ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄Ρ:
> - `generate_ollama(prompt, model)` β Π²ΡΠ·ΠΎΠ² Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΠΉ Ollama ΡΠ΅ΡΠ΅Π· `http://localhost:11434/api/generate`
> - `generate_openrouter(prompt, model, api_key)` β Π²ΡΠ·ΠΎΠ² OpenRouter API
> - `generate(prompt, provider, model, **kwargs)` β ΡΠ½ΠΈΠ²Π΅ΡΡΠ°Π»ΡΠ½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄, ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΠ°ΡΡΡΡΡΠΈΠ·ΠΈΡΡΠ΅Ρ Π·Π°ΠΏΡΠΎΡ
> Π‘ΠΎΠ·Π΄Π°ΠΉ ΡΠ½Π΄ΠΏΠΎΠΈΠ½Ρ `POST /api/ai/generate` Π² `backend/routers/ai.py`, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ JSON: `{prompt, provider, model, options}` ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ `{generated_text}`. ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉ `httpx` Π΄Π»Ρ async HTTP Π·Π°ΠΏΡΠΎΡΠΎΠ². ΠΠΎΠ±Π°Π²Ρ `httpx` Π² requirements.txt."
---
### ΠΠ°Π΄Π°ΡΠ° 2.2: Π‘ΠΈΡΡΠ΅ΠΌΠ° ΠΏΡΠ΅ΡΠ΅ΡΠΎΠ² Π΄Π»Ρ Π³Π΅Π½Π΅ΡΠ°ΡΠΈΠΈ
**ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅**: Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΏΡΠ΅ΡΠ΅ΡΠΎΠ² ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² Π³Π΅Π½Π΅ΡΠ°ΡΠΈΠΈ (Creative Draft, Editor, Brainstorm) Π½Π° backend.
**ΠΡΠΈΡΠ΅ΡΠΈΠΈ ΡΡΠΏΠ΅Ρ
Π°**:
- Π‘ΠΎΠ·Π΄Π°Π½ ΡΠ°ΠΉΠ» `backend/services/presets.py`
- ΠΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Ρ ΡΡΠΈ ΠΏΡΠ΅ΡΠ΅ΡΠ° Ρ ΡΠ°Π·Π½ΡΠΌΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°ΠΌΠΈ (temperature, top_p, frequency_penalty, presence_penalty)
- ΠΠ½Π΄ΠΏΠΎΠΈΠ½Ρ `/api/ai/generate` ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ `preset` ΠΈ ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅Ρ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠ΅ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ
**ΠΠ½ΡΡΡΡΠΊΡΠΈΡ Π΄Π»Ρ AI-Π°Π³Π΅Π½ΡΠ°**:
> "Π‘ΠΎΠ·Π΄Π°ΠΉ `backend/services/presets.py` Ρ ΡΡΠ΅ΠΌΡ ΠΏΡΠ΅ΡΠ΅ΡΠ°ΠΌΠΈ:
> - `CREATIVE_DRAFT`: temperature=0.85, top_p=0.92, frequency_penalty=0.3, presence_penalty=0.4
> - `EDITOR`: temperature=0.3, top_p=0.85, frequency_penalty=0.0, presence_penalty=0.0
> - `BRAINSTORM`: temperature=1.0, top_p=0.95, frequency_penalty=0.5, presence_penalty=0.6
> ΠΠ±Π½ΠΎΠ²ΠΈ `llm_router.py`, ΡΡΠΎΠ±Ρ ΠΌΠ΅ΡΠΎΠ΄ `generate` ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π» ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ `preset` ΠΈ ΠΏΡΠΈΠΌΠ΅Π½ΡΠ» ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΠΊ Π·Π°ΠΏΡΠΎΡΡ. ΠΠ±Π½ΠΎΠ²ΠΈ ΡΠ½Π΄ΠΏΠΎΠΈΠ½Ρ `/api/ai/generate` Π΄Π»Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΈ ΠΏΡΠ΅ΡΠ΅ΡΠΎΠ²."
---
### ΠΠ°Π΄Π°ΡΠ° 2.3: Frontend API ΠΊΠ»ΠΈΠ΅Π½Ρ Π΄Π»Ρ AI
**ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅**: Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΡΠΈΠΏΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ API ΠΊΠ»ΠΈΠ΅Π½ΡΠ° Π½Π° frontend Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Ρ AI ΡΠ½Π΄ΠΏΠΎΠΈΠ½ΡΠ°ΠΌΠΈ.
**ΠΡΠΈΡΠ΅ΡΠΈΠΈ ΡΡΠΏΠ΅Ρ
Π°**:
- Π‘ΠΎΠ·Π΄Π°Π½ ΡΠ°ΠΉΠ» `frontend/src/lib/ai-api.ts`
- Π€ΡΠ½ΠΊΡΠΈΡ `generateText(prompt, provider, model, preset)` Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΡΠ³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ ΡΠ΅ΠΊΡΡ
- ΠΡΠ΅ ΡΠΈΠΏΡ ΡΠΈΠΏΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Ρ (Π½ΠΈΠΊΠ°ΠΊΠΈΡ
`any`)
**ΠΠ½ΡΡΡΡΠΊΡΠΈΡ Π΄Π»Ρ AI-Π°Π³Π΅Π½ΡΠ°**:
> "Π‘ΠΎΠ·Π΄Π°ΠΉ `frontend/src/lib/ai-api.ts` Ρ ΡΠΈΠΏΠ°ΠΌΠΈ:
> ```typescript
> interface GenerateRequest {
> prompt: string;
> provider: 'ollama' | 'openrouter';
> model: string;
> preset: 'creative_draft' | 'editor' | 'brainstorm';
> options?: Record;
> }
> interface GenerateResponse {
> generated_text: string;
> }
> ```
> Π Π΅Π°Π»ΠΈΠ·ΡΠΉ ΡΡΠ½ΠΊΡΠΈΡ `generateText(request: GenerateRequest): Promise`, ΠΊΠΎΡΠΎΡΠ°Ρ Π²ΡΠ·ΡΠ²Π°Π΅Ρ `POST /api/ai/generate` ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ `generated_text`. ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉ axios ΠΈΠ· `lib/api.ts`."
---
### ΠΠ°Π΄Π°ΡΠ° 2.4: Inline AI ΠΌΠ΅Π½Ρ Π² ΡΠ΅Π΄Π°ΠΊΡΠΎΡΠ΅ (UI)
**ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅**: Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π²ΡΠΏΠ»ΡΠ²Π°ΡΡΠ΅Π³ΠΎ ΠΌΠ΅Π½Ρ ΠΏΡΠΈ Π²ΡΠ΄Π΅Π»Π΅Π½ΠΈΠΈ ΡΠ΅ΠΊΡΡΠ° Π² ΡΠ΅Π΄Π°ΠΊΡΠΎΡΠ΅ Π΄Π»Ρ Π²ΡΠ±ΠΎΡΠ° AI Π΄Π΅ΠΉΡΡΠ²ΠΈΠΉ.
**ΠΡΠΈΡΠ΅ΡΠΈΠΈ ΡΡΠΏΠ΅Ρ
Π°**:
- Π‘ΠΎΠ·Π΄Π°Π½ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ `frontend/src/components/editor/AIMenu.tsx`
- ΠΡΠΈ Π²ΡΠ΄Π΅Π»Π΅Π½ΠΈΠΈ ΡΠ΅ΠΊΡΡΠ° ΠΏΠΎΡΠ²Π»ΡΠ΅ΡΡΡ ΠΊΠ½ΠΎΠΏΠΊΠ° "β¨ AI"
- ΠΡΠΈ ΠΊΠ»ΠΈΠΊΠ΅ Π½Π° ΠΊΠ½ΠΎΠΏΠΊΡ ΠΎΡΠΊΡΡΠ²Π°Π΅ΡΡΡ ΠΌΠ΅Π½Ρ Ρ Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠΌΠΈ: "ΠΠ΅ΡΠ΅ΠΏΠΈΡΠ°ΡΡ", "Π Π°ΡΡΠΈΡΠΈΡΡ", "Π£ΠΏΡΠΎΡΡΠΈΡΡ", "Π‘Π²ΠΎΠΉ ΠΏΡΠΎΠΌΠΏΡ"
**ΠΠ½ΡΡΡΡΠΊΡΠΈΡ Π΄Π»Ρ AI-Π°Π³Π΅Π½ΡΠ°**:
> "Π‘ΠΎΠ·Π΄Π°ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ `AIMenu.tsx`, ΠΊΠΎΡΠΎΡΡΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ Tiptap BubbleMenu ΠΈΠ»ΠΈ FloatingMenu. ΠΡΠΈ Π²ΡΠ΄Π΅Π»Π΅Π½ΠΈΠΈ ΡΠ΅ΠΊΡΡΠ° ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°ΠΉ ΠΊΠ½ΠΎΠΏΠΊΡ Ρ ΠΈΠΊΠΎΠ½ΠΊΠΎΠΉ `Sparkles` ΠΈΠ· lucide-react. ΠΡΠΈ ΠΊΠ»ΠΈΠΊΠ΅ Π½Π° ΠΊΠ½ΠΎΠΏΠΊΡ ΠΎΡΠΊΡΡΠ²Π°ΠΉ dropdown Ρ ΠΏΡΠ½ΠΊΡΠ°ΠΌΠΈ: 'ΠΠ΅ΡΠ΅ΠΏΠΈΡΠ°ΡΡ', 'Π Π°ΡΡΠΈΡΠΈΡΡ', 'Π£ΠΏΡΠΎΡΡΠΈΡΡ', 'Π‘Π²ΠΎΠΉ ΠΏΡΠΎΠΌΠΏΡ...'. ΠΠ°ΠΆΠ΄ΡΠΉ ΠΏΡΠ½ΠΊΡ ΠΏΡΠΈ ΠΊΠ»ΠΈΠΊΠ΅ Π²ΡΠ·ΡΠ²Π°Π΅Ρ callback `onAction(action: string, selectedText: string)`. Π‘ΡΠΈΠ»ΠΈΠ·ΡΠΉ ΠΌΠ΅Π½Ρ Π² ΡΠ΅ΠΌΠ½ΠΎΠΉ ΡΠ΅ΠΌΠ΅ (bg-gray-800, border-gray-700)."
---
### ΠΠ°Π΄Π°ΡΠ° 2.5: Diff view Π΄Π»Ρ ΠΏΡΠ΅Π΄ΠΏΡΠΎΡΠΌΠΎΡΡΠ° AI ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ
**ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅**: Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ° Π΄Π»Ρ Π²ΠΈΠ·ΡΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠ΅ΠΊΡΡΠ° ΠΈ AI-ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΡ.
**ΠΡΠΈΡΠ΅ΡΠΈΠΈ ΡΡΠΏΠ΅Ρ
Π°**:
- Π‘ΠΎΠ·Π΄Π°Π½ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ `frontend/src/components/editor/AIDiffView.tsx`
- ΠΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°Π΅Ρ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»ΡΠ½ΡΠΉ ΡΠ΅ΠΊΡΡ ΡΠ»Π΅Π²Π° ΠΈ AI-ΡΠ΅ΠΊΡΡ ΡΠΏΡΠ°Π²Π°
- ΠΡΡΡ ΠΊΠ½ΠΎΠΏΠΊΠΈ "ΠΡΠΈΠ½ΡΡΡ" ΠΈ "ΠΡΠΊΠ»ΠΎΠ½ΠΈΡΡ"
- ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ Π΄Π»Ρ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ ΡΠ΅ΠΊΡΡΠ° (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, `diff` ΠΈΠ»ΠΈ ΠΏΡΠΎΡΡΡΡ Π²ΠΈΠ·ΡΠ°Π»ΠΈΠ·Π°ΡΠΈΡ)
**ΠΠ½ΡΡΡΡΠΊΡΠΈΡ Π΄Π»Ρ AI-Π°Π³Π΅Π½ΡΠ°**:
> "Π‘ΠΎΠ·Π΄Π°ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ `AIDiffView.tsx`, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ ΠΏΡΠΎΠΏΡΡ: `originalText: string`, `aiText: string`, `onAccept: () => void`, `onReject: () => void`. ΠΡΠΎΠ±ΡΠ°ΠΆΠ°ΠΉ Π΄Π²Π° Π±Π»ΠΎΠΊΠ° ΡΠ΅ΠΊΡΡΠ° (ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡΠΎΡΡΠΎ Π΄Π²Π° div ΡΡΠ΄ΠΎΠΌ ΠΈΠ»ΠΈ Π΄ΡΡΠ³ ΠΏΠΎΠ΄ Π΄ΡΡΠ³ΠΎΠΌ). ΠΠΎΠ±Π°Π²Ρ ΠΊΠ½ΠΎΠΏΠΊΠΈ 'β
ΠΡΠΈΠ½ΡΡΡ' ΠΈ 'β ΠΡΠΊΠ»ΠΎΠ½ΠΈΡΡ' Π²Π²Π΅ΡΡ
Ρ. Π‘ΡΠΈΠ»ΠΈΠ·ΡΠΉ: ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»ΡΠ½ΡΠΉ ΡΠ΅ΠΊΡΡ Ρ ΠΊΡΠ°ΡΠ½ΠΎΠ²Π°ΡΡΠΌ ΡΠΎΠ½ΠΎΠΌ (bg-red-900/20), AI ΡΠ΅ΠΊΡΡ Ρ Π·Π΅Π»Π΅Π½ΠΎΠ²Π°ΡΡΠΌ (bg-green-900/20). ΠΠ½ΠΎΠΏΠΊΠΈ: Accept β bg-green-600, Reject β bg-red-600."
---
### ΠΠ°Π΄Π°ΡΠ° 2.6: ΠΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΡ AI Π΄Π΅ΠΉΡΡΠ²ΠΈΠΉ Ρ ΡΠ΅Π΄Π°ΠΊΡΠΎΡΠΎΠΌ
**ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅**: Π‘Π²ΡΠ·ΡΠ²Π°Π½ΠΈΠ΅ AIMenu, AIDiffView ΠΈ API ΠΊΠ»ΠΈΠ΅Π½ΡΠ° Π΄Π»Ρ ΠΏΠΎΠ»Π½ΠΎΡΠ΅Π½Π½ΠΎΠΉ ΡΠ°Π±ΠΎΡΡ AI-ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ.
**ΠΡΠΈΡΠ΅ΡΠΈΠΈ ΡΡΠΏΠ΅Ρ
Π°**:
- ΠΡΠΈ Π²ΡΠ±ΠΎΡΠ΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ Π² AIMenu Π²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ API Ρ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΌ ΠΏΡΠΎΠΌΠΏΡΠΎΠΌ
- ΠΠΎΠΊΠ° ΠΈΠ΄Π΅Ρ Π³Π΅Π½Π΅ΡΠ°ΡΠΈΡ, ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°Π΅ΡΡΡ ΡΠΏΠΈΠ½Π½Π΅Ρ
- ΠΠΎΡΠ»Π΅ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΠΎΡΠ²Π΅ΡΠ° ΠΎΡΠΊΡΡΠ²Π°Π΅ΡΡΡ AIDiffView
- ΠΡΠΈ Π½Π°ΠΆΠ°ΡΠΈΠΈ "ΠΡΠΈΠ½ΡΡΡ" Π²ΡΠ΄Π΅Π»Π΅Π½Π½ΡΠΉ ΡΠ΅ΠΊΡΡ Π·Π°ΠΌΠ΅Π½ΡΠ΅ΡΡΡ Π½Π° AI-ΡΠ΅ΠΊΡΡ
- ΠΡΠΈ Π½Π°ΠΆΠ°ΡΠΈΠΈ "ΠΡΠΊΠ»ΠΎΠ½ΠΈΡΡ" Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΡΡΡ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»ΡΠ½ΡΠΉ ΡΠ΅ΠΊΡΡ
**ΠΠ½ΡΡΡΡΠΊΡΠΈΡ Π΄Π»Ρ AI-Π°Π³Π΅Π½ΡΠ°**:
> "ΠΠ½ΡΠ΅Π³ΡΠΈΡΡΠΉ AIMenu ΠΈ AIDiffView Π² Editor.tsx:
> 1. ΠΠΎΠ±Π°Π²Ρ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅: `selectedText`, `aiGeneratedText`, `showDiffView`, `isLoading`
> 2. ΠΡΠΈ Π²ΡΠ±ΠΎΡΠ΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ Π² AIMenu:
> - Π‘ΠΎΡ
ΡΠ°Π½ΠΈ `selectedText` ΠΈΠ· `editor.state.doc.textBetween(selection.from, selection.to)`
> - Π‘ΡΠΎΡΠΌΠΈΡΡΠΉ ΠΏΡΠΎΠΌΠΏΡ Π² Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΎΡ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π΄Π»Ρ 'ΠΠ΅ΡΠ΅ΠΏΠΈΡΠ°ΡΡ': 'ΠΠ΅ΡΠ΅ΠΏΠΈΡΠΈ ΡΡΠΎΡ ΡΠ΅ΠΊΡΡ, ΡΠ΄Π΅Π»Π°ΠΉ Π΅Π³ΠΎ Π±ΠΎΠ»Π΅Π΅ ΠΆΠΈΠ²ΡΠΌ ΠΈ ΠΊΠΈΠ½Π΅ΠΌΠ°ΡΠΎΠ³ΡΠ°ΡΠΈΡΠ½ΡΠΌ: [selectedText]')
> - ΠΡΠ·ΠΎΠ²ΠΈ `generateText` ΠΈΠ· `ai-api.ts` Ρ ΠΏΡΠ΅ΡΠ΅ΡΠΎΠΌ `creative_draft`
> - Π£ΡΡΠ°Π½ΠΎΠ²ΠΈ `aiGeneratedText` ΠΈ `showDiffView = true`
> 3. Π AIDiffView:
> - `onAccept`: Π·Π°ΠΌΠ΅Π½ΠΈ Π²ΡΠ΄Π΅Π»Π΅Π½Π½ΡΠΉ ΡΠ΅ΠΊΡΡ ΡΠ΅ΡΠ΅Π· `editor.chain().focus().deleteRange(selection).insertContent(aiGeneratedText).run()`
> - `onReject`: Π·Π°ΠΊΡΠΎΠΉ diff view, Π½ΠΈΡΠ΅Π³ΠΎ Π½Π΅ ΠΌΠ΅Π½ΡΠΉ
> 4. ΠΠΎΠΊΠ°ΠΆΠΈ ΡΠΏΠΈΠ½Π½Π΅Ρ (ΠΈΠ· lucide-react: `Loader2` Ρ Π°Π½ΠΈΠΌΠ°ΡΠΈΠ΅ΠΉ `animate-spin`), ΠΏΠΎΠΊΠ° `isLoading = true`"
---
## π ΠΡΠ°ΠΏ 3: ΠΠΎΠ½ΡΠ΅ΠΊΡΡ ΠΈ Story Bible
### ΠΠ°Π΄Π°ΡΠ° 3.1: Backend ΠΌΠΎΠ΄Π΅Π»Ρ ΠΈ API Π΄Π»Ρ Story Bible
**ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅**: Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΡΡΡΡΠΊΡΡΡΡ Π΄Π°Π½Π½ΡΡ
Π΄Π»Ρ Story Bible (ΠΏΠ΅ΡΡΠΎΠ½Π°ΠΆΠΈ, Π»ΠΎΠΊΠ°ΡΠΈΠΈ, ΡΠΎΠ±ΡΡΠΈΡ) ΠΈ API Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Ρ Π½Π΅ΠΉ.
**ΠΡΠΈΡΠ΅ΡΠΈΠΈ ΡΡΠΏΠ΅Ρ
Π°**:
- Π‘ΠΎΠ·Π΄Π°Π½Ρ Pydantic ΠΌΠΎΠ΄Π΅Π»ΠΈ Π΄Π»Ρ ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ (Character, Location, Event, StoryThread)
- Π‘ΠΎΠ·Π΄Π°Π½ ΡΠ½Π΄ΠΏΠΎΠΈΠ½Ρ `GET /api/projects/{id}/bible` Π΄Π»Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ Story Bible
- Π‘ΠΎΠ·Π΄Π°Π½ ΡΠ½Π΄ΠΏΠΎΠΈΠ½Ρ `PUT /api/projects/{id}/bible` Π΄Π»Ρ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ Story Bible
- ΠΠ°Π½Π½ΡΠ΅ Ρ
ΡΠ°Π½ΡΡΡΡ Π² JSON ΡΠ°ΠΉΠ»Π΅ Π½Π° Π΄ΠΈΡΠΊΠ΅ (Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎ)
**Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅ΠΌΠ°Ρ ΠΌΠΎΠ΄Π΅Π»Ρ**: `qwen/qwen-2.5-coder-7b-instruct` (ΠΏΡΠΎΡΡΠ°Ρ CRUD Π·Π°Π΄Π°ΡΠ°)
**ΠΠ½ΡΡΡΡΠΊΡΠΈΡ Π΄Π»Ρ AI-Π°Π³Π΅Π½ΡΠ°**:
> "Π‘ΠΎΠ·Π΄Π°ΠΉ Pydantic ΠΌΠΎΠ΄Π΅Π»ΠΈ Π² `backend/models/bible.py` Π΄Π»Ρ ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ: Character (id, name, description, traits, appearance), Location (id, name, description, atmosphere), Event (id, title, description, chapter), StoryThread (id, title, description, status). Π‘ΠΎΠ·Π΄Π°ΠΉ ΠΌΠΎΠ΄Π΅Π»Ρ StoryBible, ΠΊΠΎΡΠΎΡΠ°Ρ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΡΠΏΠΈΡΠΊΠΈ ΡΡΠΈΡ
ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ. Π‘ΠΎΠ·Π΄Π°ΠΉ ΡΠΎΡΡΠ΅Ρ `backend/routers/bible.py` Ρ ΡΠ½Π΄ΠΏΠΎΠΈΠ½ΡΠ°ΠΌΠΈ Π΄Π»Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΠΈ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ Story Bible. ΠΠ°Π½Π½ΡΠ΅ Ρ
ΡΠ°Π½ΠΈ Π² ΡΠ°ΠΉΠ»Π΅ `data/story_bible.json`. ΠΠΎΠ±Π°Π²Ρ ΡΡΠ½ΠΊΡΠΈΡ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ Ρ ΠΏΡΠΈΠΌΠ΅ΡΠΎΠΌ Π΄Π°Π½Π½ΡΡ
."
---
### ΠΠ°Π΄Π°ΡΠ° 3.2: Frontend UI Π΄Π»Ρ Story Bible (ΠΏΠ°Π½Π΅Π»Ρ)
**ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅**: Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΠ°Π½Π΅Π»ΠΈ Π΄Π»Ρ ΠΏΡΠΎΡΠΌΠΎΡΡΠ° ΠΈ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ Story Bible.
**ΠΡΠΈΡΠ΅ΡΠΈΠΈ ΡΡΠΏΠ΅Ρ
Π°**:
- Π‘ΠΎΠ·Π΄Π°Π½ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ `StoryBiblePanel.tsx` Ρ Π²ΠΊΠ»Π°Π΄ΠΊΠ°ΠΌΠΈ: ΠΠ΅ΡΡΠΎΠ½Π°ΠΆΠΈ, ΠΠΎΠΊΠ°ΡΠΈΠΈ, Π‘ΠΎΠ±ΡΡΠΈΡ, Π‘ΡΠΆΠ΅ΡΠ½ΡΠ΅ Π½ΠΈΡΠΈ
- ΠΠ°ΠΆΠ΄Π°Ρ Π²ΠΊΠ»Π°Π΄ΠΊΠ° ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°Π΅Ρ ΡΠΏΠΈΡΠΎΠΊ ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡΡ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ
- ΠΡΡΡ ΠΊΠ½ΠΎΠΏΠΊΠΈ "ΠΠΎΠ±Π°Π²ΠΈΡΡ" ΠΈ "Π£Π΄Π°Π»ΠΈΡΡ" Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΡΡΡΠ½ΠΎΡΡΠΈ
- ΠΠ°Π½Π΅Π»Ρ ΠΈΠ½ΡΠ΅Π³ΡΠΈΡΠΎΠ²Π°Π½Π° Π² layout (Π·Π°ΠΌΠ΅Π½ΡΠ΅Ρ ΠΈΠ»ΠΈ Π΄ΠΎΠΏΠΎΠ»Π½ΡΠ΅Ρ StoryExplorer)
**Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅ΠΌΠ°Ρ ΠΌΠΎΠ΄Π΅Π»Ρ**: `qwen/qwen-2.5-coder-7b-instruct` (UI ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ)
**ΠΠ½ΡΡΡΡΠΊΡΠΈΡ Π΄Π»Ρ AI-Π°Π³Π΅Π½ΡΠ°**:
> "Π‘ΠΎΠ·Π΄Π°ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ `src/components/sidebar/StoryBiblePanel.tsx` Ρ Π²ΠΊΠ»Π°Π΄ΠΊΠ°ΠΌΠΈ Π΄Π»Ρ ΠΏΠ΅ΡΡΠΎΠ½Π°ΠΆΠ΅ΠΉ, Π»ΠΎΠΊΠ°ΡΠΈΠΉ, ΡΠΎΠ±ΡΡΠΈΠΉ ΠΈ ΡΡΠΆΠ΅ΡΠ½ΡΡ
Π½ΠΈΡΠ΅ΠΉ. ΠΠ°ΠΆΠ΄Π°Ρ Π²ΠΊΠ»Π°Π΄ΠΊΠ° ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°Π΅Ρ ΡΠΏΠΈΡΠΎΠΊ ΠΊΠ°ΡΡΠΎΡΠ΅ΠΊ ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ. ΠΠ°ΡΡΠΎΡΠΊΠ° ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π½Π°Π·Π²Π°Π½ΠΈΠ΅, ΠΊΡΠ°ΡΠΊΠΎΠ΅ ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠΈ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ/ΡΠ΄Π°Π»Π΅Π½ΠΈΡ. ΠΠΎΠ±Π°Π²Ρ ΠΌΠΎΠ΄Π°Π»ΡΠ½ΠΎΠ΅ ΠΎΠΊΠ½ΠΎ Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ/ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΡΡΡΠ½ΠΎΡΡΠΈ Ρ ΠΏΠΎΠ»ΡΠΌΠΈ, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΌΠΈ ΠΌΠΎΠ΄Π΅Π»ΠΈ. ΠΠ½ΡΠ΅Π³ΡΠΈΡΡΠΉ ΠΏΠ°Π½Π΅Π»Ρ Π² layout, Π·Π°ΠΌΠ΅Π½ΠΈΠ² Π·Π°Π³Π»ΡΡΠΊΡ StoryExplorer. ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉ Zustand store Π΄Π»Ρ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ."
---
### ΠΠ°Π΄Π°ΡΠ° 3.3: ΠΠ°ΡΡΡΠΎΠΉΠΊΠΈ Π²ΡΠ±ΠΎΡΠ° ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ Π΄Π»Ρ ΡΠ°Π·Π½ΡΡ
Π·Π°Π΄Π°Ρ
**ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅**: Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ UI ΠΈ backend Π»ΠΎΠ³ΠΈΠΊΠΈ Π΄Π»Ρ Π²ΡΠ±ΠΎΡΠ° ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ ΠΏΠΎΠ΄ ΡΠ°Π·Π½ΡΠ΅ Π·Π°Π΄Π°ΡΠΈ (Π³Π΅Π½Π΅ΡΠ°ΡΠΈΡ, ΡΠΎΠ½ΠΎΠ²Π°Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ°, Π°Π½Π°Π»ΠΈΠ·).
**ΠΡΠΈΡΠ΅ΡΠΈΠΈ ΡΡΠΏΠ΅Ρ
Π°**:
- Π‘ΠΎΠ·Π΄Π°Π½ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ `ModelSettings.tsx` Ρ Π²ΡΠ±ΠΎΡΠΎΠΌ ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ Π΄Π»Ρ:
- ΠΠ΅Π½Π΅ΡΠ°ΡΠΈΠΈ ΡΠ΅ΠΊΡΡΠ° (ΠΎΡΠ½ΠΎΠ²Π½Π°Ρ ΠΌΠΎΠ΄Π΅Π»Ρ)
- Π€ΠΎΠ½ΠΎΠ²ΠΎΠΉ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ (ΠΈΠ·Π²Π»Π΅ΡΠ΅Π½ΠΈΠ΅ ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ)
- ΠΠ½Π°Π»ΠΈΠ·Π° ΡΠ΅ΠΊΡΡΠ° (ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° Π»ΠΎΠ³ΠΈΠΊΠΈ)
- ΠΠ°ΡΡΡΠΎΠΉΠΊΠΈ ΡΠΎΡ
ΡΠ°Π½ΡΡΡΡΡ Π² localStorage ΠΈΠ»ΠΈ backend
- ΠΡΠΈ Π³Π΅Π½Π΅ΡΠ°ΡΠΈΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ Π²ΡΠ±ΡΠ°Π½Π½ΡΠ΅ ΠΌΠΎΠ΄Π΅Π»ΠΈ
**Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅ΠΌΠ°Ρ ΠΌΠΎΠ΄Π΅Π»Ρ**: `qwen/qwen-2.5-coder-7b-instruct` (UI + ΠΈΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΡ)
**ΠΠ½ΡΡΡΡΠΊΡΠΈΡ Π΄Π»Ρ AI-Π°Π³Π΅Π½ΡΠ°**:
> "Π‘ΠΎΠ·Π΄Π°ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ `src/components/settings/ModelSettings.tsx` Ρ dropdown Π΄Π»Ρ Π²ΡΠ±ΠΎΡΠ° ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ Π΄Π»Ρ ΡΠ°Π·Π½ΡΡ
Π·Π°Π΄Π°Ρ: 'ΠΡΠ½ΠΎΠ²Π½Π°Ρ ΠΌΠΎΠ΄Π΅Π»Ρ Π΄Π»Ρ Π³Π΅Π½Π΅ΡΠ°ΡΠΈΠΈ', 'ΠΠΎΠ΄Π΅Π»Ρ Π΄Π»Ρ ΡΠΎΠ½ΠΎΠ²ΠΎΠΉ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ', 'ΠΠΎΠ΄Π΅Π»Ρ Π΄Π»Ρ Π°Π½Π°Π»ΠΈΠ·Π°'. ΠΠ°Π³ΡΡΠΆΠ°ΠΉ ΡΠΏΠΈΡΠΎΠΊ Π΄ΠΎΡΡΡΠΏΠ½ΡΡ
ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ ΡΠ΅ΡΠ΅Π· `getAvailableModels()` ΠΈΠ· `ai-api.ts`. Π‘ΠΎΡ
ΡΠ°Π½ΡΠΉ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ Π² Zustand store. ΠΠ±Π½ΠΎΠ²ΠΈ `ai-api.ts`, ΡΡΠΎΠ±Ρ ΡΡΠ½ΠΊΡΠΈΡ `generateText` ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π»Π° ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ `task_type` ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»Π° ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ ΠΈΠ· Π½Π°ΡΡΡΠΎΠ΅ΠΊ."
---
### ΠΠ°Π΄Π°ΡΠ° 3.4: Π€ΠΎΠ½ΠΎΠ²ΡΠΉ Π°Π³Π΅Π½Ρ Π΄Π»Ρ ΠΈΠ·Π²Π»Π΅ΡΠ΅Π½ΠΈΡ ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ
**ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅**: Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΡΠ΅ΡΠ²ΠΈΡΠ° Π΄Π»Ρ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ ΠΈΠ·Π²Π»Π΅ΡΠ΅Π½ΠΈΡ ΠΏΠ΅ΡΡΠΎΠ½Π°ΠΆΠ΅ΠΉ, Π»ΠΎΠΊΠ°ΡΠΈΠΉ ΠΈ ΡΠΎΠ±ΡΡΠΈΠΉ ΠΈΠ· ΡΠ΅ΠΊΡΡΠ° Π³Π»Π°Π²Ρ.
**ΠΡΠΈΡΠ΅ΡΠΈΠΈ ΡΡΠΏΠ΅Ρ
Π°**:
- Π‘ΠΎΠ·Π΄Π°Π½ ΡΠ΅ΡΠ²ΠΈΡ `backend/services/entity_extractor.py`
- Π‘Π΅ΡΠ²ΠΈΡ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ ΡΠ΅ΠΊΡΡ Π³Π»Π°Π²Ρ ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ JSON Ρ ΠΈΠ·Π²Π»Π΅ΡΠ΅Π½Π½ΡΠΌΠΈ ΡΡΡΠ½ΠΎΡΡΡΠΌΠΈ
- ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ ΠΏΡΠΎΠΌΠΏΡ Π΄Π»Ρ ΡΡΡΡΠΊΡΡΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ Π²ΡΠ²ΠΎΠ΄Π° (JSON mode)
- ΠΠ½ΡΠ΅Π³ΡΠΈΡΠΎΠ²Π°Π½ Ρ Story Bible (ΠΎΠ±Π½ΠΎΠ²Π»ΡΠ΅Ρ ΠΈΠ»ΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅Ρ Π½ΠΎΠ²ΡΠ΅ ΡΡΡΠ½ΠΎΡΡΠΈ)
**Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅ΠΌΠ°Ρ ΠΌΠΎΠ΄Π΅Π»Ρ**: `qwen/qwen-2.5-coder-32b-instruct` (ΡΠ»ΠΎΠΆΠ½ΡΠΉ ΠΏΡΠΎΠΌΠΏΡ-ΠΈΠ½ΠΆΠΈΠ½ΠΈΡΠΈΠ½Π³)
**ΠΠ½ΡΡΡΡΠΊΡΠΈΡ Π΄Π»Ρ AI-Π°Π³Π΅Π½ΡΠ°**:
> "Π‘ΠΎΠ·Π΄Π°ΠΉ ΡΠ΅ΡΠ²ΠΈΡ `backend/services/entity_extractor.py` Ρ ΡΡΠ½ΠΊΡΠΈΠ΅ΠΉ `extract_entities(text, existing_bible)`. Π€ΡΠ½ΠΊΡΠΈΡ ΡΠΎΡΠΌΠΈΡΡΠ΅Ρ ΠΏΡΠΎΠΌΠΏΡ Π΄Π»Ρ LLM, ΠΊΠΎΡΠΎΡΡΠΉ ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅Ρ ΠΈΠ· ΡΠ΅ΠΊΡΡΠ° Π½ΠΎΠ²ΡΡ
ΠΏΠ΅ΡΡΠΎΠ½Π°ΠΆΠ΅ΠΉ, Π»ΠΎΠΊΠ°ΡΠΈΠΈ ΠΈ ΡΠΎΠ±ΡΡΠΈΡ Π² ΡΠΎΡΠΌΠ°ΡΠ΅ JSON. ΠΡΠΎΠΌΠΏΡ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²ΠΊΠ»ΡΡΠ°ΡΡ ΠΏΡΠΈΠΌΠ΅ΡΡ ΡΠΎΡΠΌΠ°ΡΠ° Π²ΡΠ²ΠΎΠ΄Π° ΠΈ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΡ Π½Π΅ Π΄ΡΠ±Π»ΠΈΡΠΎΠ²Π°ΡΡ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠΈΠ΅ ΡΡΡΠ½ΠΎΡΡΠΈ ΠΈΠ· `existing_bible`. ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉ ΠΌΠΎΠ΄Π΅Π»Ρ Π΄Π»Ρ ΡΠΎΠ½ΠΎΠ²ΠΎΠΉ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΠΈΠ· Π½Π°ΡΡΡΠΎΠ΅ΠΊ. ΠΡΠ΅ΡΠ΅Ρ: `editor` (Π½ΠΈΠ·ΠΊΠ°Ρ ΡΠ΅ΠΌΠΏΠ΅ΡΠ°ΡΡΡΠ° Π΄Π»Ρ ΡΠΎΡΠ½ΠΎΡΡΠΈ)."
---
### ΠΠ°Π΄Π°ΡΠ° 3.5: ΠΠ²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Story Bible ΠΏΡΠΈ ΡΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΠΈ
**ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅**: ΠΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΡ ΠΈΠ·Π²Π»Π΅ΡΠ΅Π½ΠΈΡ ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ Ρ ΠΏΡΠΎΡΠ΅ΡΡΠΎΠΌ ΡΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΡ Π³Π»Π°Π²Ρ.
**ΠΡΠΈΡΠ΅ΡΠΈΠΈ ΡΡΠΏΠ΅Ρ
Π°**:
- ΠΡΠΈ ΡΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΠΈ Π³Π»Π°Π²Ρ (Π°Π²ΡΠΎΡΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΠ΅) Π²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ ΡΠΎΠ½ΠΎΠ²ΡΠΉ Π°Π³Π΅Π½Ρ
- ΠΠ³Π΅Π½Ρ Π°Π½Π°Π»ΠΈΠ·ΠΈΡΡΠ΅Ρ ΡΠ΅ΠΊΡΡ ΠΈ ΠΎΠ±Π½ΠΎΠ²Π»ΡΠ΅Ρ Story Bible
- ΠΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Π²ΠΈΠ΄ΠΈΡ ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ "Story Bible ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½Π°"
- ΠΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΎΡΠΊΠ»ΡΡΠΈΡΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Π² Π½Π°ΡΡΡΠΎΠΉΠΊΠ°Ρ
**Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅ΠΌΠ°Ρ ΠΌΠΎΠ΄Π΅Π»Ρ**: `qwen/qwen-2.5-coder-32b-instruct` (ΠΈΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΡ)
**ΠΠ½ΡΡΡΡΠΊΡΠΈΡ Π΄Π»Ρ AI-Π°Π³Π΅Π½ΡΠ°**:
> "ΠΠ±Π½ΠΎΠ²ΠΈ `Editor.tsx`, ΡΡΠΎΠ±Ρ ΠΏΡΠΈ Π°Π²ΡΠΎΡΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΠΈ (ΠΏΠΎΡΠ»Π΅ debounce) ΠΎΡΠΏΡΠ°Π²Π»ΡΠ» Π·Π°ΠΏΡΠΎΡ Π½Π° backend Π΄Π»Ρ ΠΈΠ·Π²Π»Π΅ΡΠ΅Π½ΠΈΡ ΡΡΡΠ½ΠΎΡΡΠ΅ΠΉ. Π‘ΠΎΠ·Π΄Π°ΠΉ ΡΠ½Π΄ΠΏΠΎΠΈΠ½Ρ `POST /api/ai/extract-entities` Π² `backend/routers/ai.py`, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ ΡΠ΅ΠΊΡΡ Π³Π»Π°Π²Ρ ΠΈ ΡΠ΅ΠΊΡΡΡΡ Story Bible, Π²ΡΠ·ΡΠ²Π°Π΅Ρ `entity_extractor`, ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½Π½ΡΡ Bible. ΠΠ° frontend Π΄ΠΎΠ±Π°Π²Ρ ΠΏΠ΅ΡΠ΅ΠΊΠ»ΡΡΠ°ΡΠ΅Π»Ρ 'ΠΠ²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΎΠ±Π½ΠΎΠ²Π»ΡΡΡ Story Bible' Π² Π½Π°ΡΡΡΠΎΠΉΠΊΠ°Ρ
. ΠΠΎΠΊΠ°Π·ΡΠ²Π°ΠΉ ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ (toast) ΠΏΡΠΈ ΡΡΠΏΠ΅ΡΠ½ΠΎΠΌ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΈ."
---
## π΄ ΠΡΠ°ΠΏ 4: ΠΠΊΡΠΏΠΎΡΡ ΠΈ ΠΏΠΎΠ»ΠΈΡΠΎΠ²ΠΊΠ°
*(ΠΡΠ΄Π΅Ρ Π°ΠΊΡΠΈΠ²ΠΈΡΠΎΠ²Π°Π½ ΠΏΠΎΡΠ»Π΅ ΡΡΠΏΠ΅ΡΠ½ΠΎΠ³ΠΎ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ ΠΡΠ°ΠΏΠ° 3)*