mirror of
https://github.com/waynesutton/markdown-site.git
synced 2026-01-12 04:09:14 +00:00
Add AI writing assistant (Agent) powered by Anthropic Claude API. Agent can be enabled on Write page (replaces textarea) and optionally in RightSidebar on posts/pages via frontmatter. Features: - AIChatView component with per-page chat history - Page content context support for AI responses - Markdown rendering for AI responses - User-friendly error handling for missing API keys - System prompt configurable via Convex environment variables - Anonymous session authentication using localStorage Environment variables required: - ANTHROPIC_API_KEY (required) - CLAUDE_PROMPT_STYLE, CLAUDE_PROMPT_COMMUNITY, CLAUDE_PROMPT_RULES (optional split prompts) - CLAUDE_SYSTEM_PROMPT (optional single prompt fallback) Configuration: - siteConfig.aiChat.enabledOnWritePage: Enable Agent toggle on /write page - siteConfig.aiChat.enabledOnContent: Allow Agent on posts/pages via frontmatter - Frontmatter aiChat: true (requires rightSidebar: true) Updated files: - src/components/AIChatView.tsx: AI chat interface component - src/components/RightSidebar.tsx: Conditional Agent rendering - src/pages/Write.tsx: Agent mode toggle (title changes to Agent) - convex/aiChats.ts: Chat history queries and mutations - convex/aiChatActions.ts: Claude API integration with error handling - convex/schema.ts: aiChats table with indexes - src/config/siteConfig.ts: AIChatConfig interface - Documentation updated across all files Documentation: - files.md: Updated component descriptions - changelog.md: Added v1.33.0 entry - TASK.md: Marked AI chat tasks as completed - README.md: Added AI Agent Chat section - content/pages/docs.md: Added AI Agent chat documentation - content/blog/setup-guide.md: Added AI Agent chat setup instructions - public/raw/changelog.md: Added v1.33.0 entry
7.7 KiB
7.7 KiB
name, overview, todos
| name | overview | todos | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| AI Chat Write Agent | Implement an AI-powered chat write agent that integrates with the Write page (replacing textarea when active) and optionally appears in the RightSidebar on posts/pages. Uses Anthropic Claude API with anonymous sessions, per-page chat history stored in Convex, and optional page content loading. |
|
AI Chat Write Agent Implementation
Architecture Overview
flowchart TB
subgraph frontend [Frontend Components]
AIChatView[AIChatView Component]
WritePage[Write.tsx]
RightSidebar[RightSidebar.tsx]
PostPage[Post.tsx]
end
subgraph convex [Convex Backend]
aiChats[aiChats.ts - Queries/Mutations]
aiChatActions[aiChatActions.ts - Claude API Action]
schema[schema.ts - aiChats table]
end
subgraph external [External Services]
Claude[Anthropic Claude API]
end
WritePage -->|mode toggle| AIChatView
RightSidebar -->|when aiChat enabled| AIChatView
PostPage -->|passes content context| RightSidebar
AIChatView -->|mutations| aiChats
AIChatView -->|action| aiChatActions
aiChatActions -->|API call| Claude
aiChats -->|read/write| schema
Key Design Decisions
- Anonymous Sessions: Uses localStorage
sessionId(UUID) until auth is added - Chat Scope: Per-page using slug as context identifier (e.g., "write-page", "about", "my-post-slug")
- Page Context: Optional button to load current page's markdown into chat context
- Mode Toggle: Write page switches between textarea and chat interface
- Configuration: Separate siteConfig toggles for Write page and RightSidebar
1. Database Schema Updates
Update convex/schema.ts to add the aiChats table:
aiChats: defineTable({
sessionId: v.string(),
contextId: v.string(), // slug or "write-page"
messages: v.array(
v.object({
role: v.union(v.literal("user"), v.literal("assistant")),
content: v.string(),
timestamp: v.number(),
}),
),
pageContext: v.optional(v.string()), // loaded page content
lastMessageAt: v.optional(v.number()),
})
.index("by_session_and_context", ["sessionId", "contextId"])
.index("by_session", ["sessionId"])
2. Convex Backend
Create convex/aiChats.ts
Queries and mutations for chat management:
getAIChatByContext- Fetch chat for sessionId + contextIdgetOrCreateAIChat- Create chat if none existsaddUserMessage- Add user messageaddAssistantMessage- Internal mutation for AI responseclearChat- Clear messagessetPageContext- Store loaded page content
Create convex/aiChatActions.ts
Node.js action for Claude API:
generateResponse- Calls Claude API with conversation history- Uses
ANTHROPIC_API_KEYenvironment variable - Loads system prompt from
CLAUDE_SYSTEM_PROMPTor splitCLAUDE_PROMPT_*variables - Model:
claude-sonnet-4-20250514with 2048 max tokens - Includes last 20 messages as context
3. Frontend Components
Create src/components/AIChatView.tsx
Main chat component with:
- Message list with markdown rendering (react-markdown)
- Auto-expanding textarea input
- Send button and keyboard shortcuts (Enter to send, Shift+Enter newline)
- Loading state with stop generation button
- Clear chat command ("clear")
- Copy message button on AI responses
- "Load Page Content" button (when page content available)
- Theme-aware styling matching existing UI
Update src/components/RightSidebar.tsx
Transform from empty placeholder to conditional chat container:
- Accept
aiChatEnabled,pageContent, andslugprops - Render
AIChatViewwhen enabled - Pass page context for "Load Content" feature
4. Page Updates
Update src/pages/Write.tsx
Add AI chat mode toggle:
- New state:
isAIChatMode(boolean) - Add "AI Chat" button in Actions section (using
ChatCirclefrom Phosphor Icons) - When active: replace
<textarea>with<AIChatView contextId="write-page" /> - Show "Back to Editor" button to switch back
- Respect
siteConfig.aiChat.enabledOnWritePagesetting
Update src/pages/Post.tsx
Pass content to RightSidebar:
- Check
siteConfig.aiChat.enabledOnContentAND frontmatteraiChat: true - Pass
pageContent={content}andslugto RightSidebar - Add new frontmatter field
aiChatto field definitions
5. Configuration
Update src/config/siteConfig.ts
Add AI chat configuration interface and defaults:
export interface AIChatConfig {
enabledOnWritePage: boolean; // Show AI chat on /write
enabledOnContent: boolean; // Allow AI chat on posts/pages via frontmatter
}
// In SiteConfig interface:
aiChat: AIChatConfig;
// Default values:
aiChat: {
enabledOnWritePage: true,
enabledOnContent: true,
},
Update Frontmatter Fields
Add aiChat field to sync scripts and field definitions:
scripts/sync-posts.ts- Add to PostFrontmatter and PageFrontmattersrc/pages/Write.tsx- Add to POST_FIELDS and PAGE_FIELDS
6. Styling
Update src/styles/global.css
Add AI chat styles (approximately 300-400 lines):
.ai-chat-view- Main container.ai-chat-messages- Scrollable message list.ai-chat-message,.ai-chat-message-user,.ai-chat-message-assistant.ai-chat-input-container,.ai-chat-input,.ai-chat-send-button.ai-chat-loading,.ai-chat-stop-button.ai-chat-copy-button,.ai-chat-clear-button.ai-chat-load-context-button- Theme variants for dark, light, tan, cloud
- Mobile responsive styles
7. Dependencies
Update package.json
Add required packages:
"@anthropic-ai/sdk": "^0.71.2"
Note: react-markdown and remark-gfm already exist in the project.---
8. Environment Variables
Add to Convex deployment:
ANTHROPIC_API_KEY(required) - Claude API keyCLAUDE_SYSTEM_PROMPT(optional) - Custom system prompt for writing assistant