From bfe88d021721fc3d188e89e76f50911fd77466ef Mon Sep 17 00:00:00 2001 From: Wayne Sutton Date: Fri, 26 Dec 2025 12:31:33 -0800 Subject: [PATCH] feat: add AI Agent chat integration with Anthropic Claude API 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 --- .../ai_chat_write_agent_9b3e5be2.plan.md | 269 ++++++ ...om_homepage_configuration_83419476.plan.md | 301 ++++++ AGENTS.md | 2 +- FORK_CONFIG.md | 81 ++ README.md | 27 + TASK.md | 44 +- changelog.md | 76 ++ content/blog/setup-guide.md | 68 ++ content/pages/changelog-page.md | 58 ++ content/pages/docs.md | 3 + convex/_generated/api.d.ts | 4 + convex/aiChatActions.ts | 307 ++++++ convex/aiChats.ts | 356 +++++++ convex/pages.ts | 4 + convex/posts.ts | 6 + convex/schema.ts | 30 + files.md | 320 +++---- fork-config.json.example | 7 +- package-lock.json | 40 + package.json | 1 + public/llms.txt | 2 +- public/raw/changelog.md | 58 ++ public/raw/docs.md | 2 + public/raw/setup-guide.md | 68 ++ scripts/configure-fork.ts | 25 + scripts/sync-posts.ts | 6 + src/App.tsx | 31 +- src/components/AIChatView.tsx | 719 +++++++++++++++ src/components/LogoMarquee.tsx | 22 +- src/components/RightSidebar.tsx | 42 +- src/config/siteConfig.ts | 45 +- src/pages/Post.tsx | 46 +- src/pages/Write.tsx | 171 +++- src/styles/global.css | 871 +++++++++++++++++- 34 files changed, 3867 insertions(+), 245 deletions(-) create mode 100644 .cursor/plans/ai_chat_write_agent_9b3e5be2.plan.md create mode 100644 .cursor/plans/custom_homepage_configuration_83419476.plan.md create mode 100644 convex/aiChatActions.ts create mode 100644 convex/aiChats.ts create mode 100644 src/components/AIChatView.tsx diff --git a/.cursor/plans/ai_chat_write_agent_9b3e5be2.plan.md b/.cursor/plans/ai_chat_write_agent_9b3e5be2.plan.md new file mode 100644 index 0000000..5df1540 --- /dev/null +++ b/.cursor/plans/ai_chat_write_agent_9b3e5be2.plan.md @@ -0,0 +1,269 @@ +--- +name: AI Chat Write Agent +overview: 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. +todos: + - id: schema + content: Add aiChats table to convex/schema.ts with indexes + status: completed + - id: backend-mutations + content: Create convex/aiChats.ts with queries and mutations + status: completed + dependencies: + - schema + - id: backend-action + content: Create convex/aiChatActions.ts with Claude API integration + status: completed + dependencies: + - backend-mutations + - id: siteconfig + content: Add AIChatConfig interface and defaults to siteConfig.ts + status: completed + - id: chat-component + content: Create AIChatView.tsx component with full chat UI + status: completed + dependencies: + - backend-mutations + - backend-action + - id: chat-styles + content: Add AI chat CSS styles to global.css (theme-aware) + status: completed + dependencies: + - chat-component + - id: right-sidebar + content: Update RightSidebar.tsx to conditionally render AIChatView + status: completed + dependencies: + - chat-component + - siteconfig + - id: write-page + content: Update Write.tsx with AI chat mode toggle + status: completed + dependencies: + - chat-component + - siteconfig + - id: post-page + content: Update Post.tsx to pass content context to RightSidebar + status: completed + dependencies: + - right-sidebar + - id: frontmatter + content: Add aiChat field to sync-posts.ts and Write.tsx field definitions + status: completed + - id: dependencies + content: Add @anthropic-ai/sdk to package.json + status: completed +--- + +# AI Chat Write Agent Implementation + +## Architecture Overview + +```mermaid +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`](convex/schema.ts) to add the `aiChats` table: + +```typescript +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`](convex/aiChats.ts) + +Queries and mutations for chat management: + +- `getAIChatByContext` - Fetch chat for sessionId + contextId +- `getOrCreateAIChat` - Create chat if none exists +- `addUserMessage` - Add user message +- `addAssistantMessage` - Internal mutation for AI response +- `clearChat` - Clear messages +- `setPageContext` - Store loaded page content + +### Create [`convex/aiChatActions.ts`](convex/aiChatActions.ts) + +Node.js action for Claude API: + +- `generateResponse` - Calls Claude API with conversation history +- Uses `ANTHROPIC_API_KEY` environment variable +- Loads system prompt from `CLAUDE_SYSTEM_PROMPT` or split `CLAUDE_PROMPT_*` variables +- Model: `claude-sonnet-4-20250514` with 2048 max tokens +- Includes last 20 messages as context + +--- + +## 3. Frontend Components + +### Create [`src/components/AIChatView.tsx`](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`](src/components/RightSidebar.tsx) + +Transform from empty placeholder to conditional chat container: + +- Accept `aiChatEnabled`, `pageContent`, and `slug` props +- Render `AIChatView` when enabled +- Pass page context for "Load Content" feature + +--- + +## 4. Page Updates + +### Update [`src/pages/Write.tsx`](src/pages/Write.tsx) + +Add AI chat mode toggle: + +- New state: `isAIChatMode` (boolean) +- Add "AI Chat" button in Actions section (using `ChatCircle` from Phosphor Icons) +- When active: replace `