A modern, feature-rich AI chat application built with Next.js 16, Vercel AI SDK v6, and Anthropic Claude Sonnet 4.5.
ChatNoire provides a polished chat experience with a persistent knowledge filesystem, large document RAG, parallel context-saving agents, web search, file attachments, authentication, and more.
- Streaming Responses β Real-time response streaming with stop functionality
- Conversation History β Automatically saves chats to IndexedDB with full CRUD support
- Chat History Search β Hybrid search (lexical + semantic + reranking) across past conversations
- Parallel Chat Sessions β Start new chats while responses are still streaming
- Auto Title Generation β AI-generated titles based on conversation content
- Message Editing β Edit previous messages and regenerate responses from that point
- Persistent Storage β Client-side IndexedDB storage that Claude can read/write via tools
- Hybrid Search (RAG) β Combines lexical + semantic search with RRF (Reciprocal Rank Fusion)
- Knowledge Graph β Create semantic relationships between files (extends, references, requires, contradicts, etc.)
- Graph Traversal β Navigate prerequisite chains, find related content, and detect contradictions
- Sidebar Browser β Visual file browser in the sidebar to explore your knowledge base
- KB Summary Preload β Hybrid context strategy with summary at prompt start for fast retrieval
- Quote-Grounding β Claude extracts quotes from files before synthesizing responses
- Upload Large Documents β Upload PDFs, text files, and markdown for Q&A without loading into context
- PDF Support β Hybrid PDF extraction using PDF.js (free) with Claude Haiku fallback for scanned documents
- Intelligent Quality Detection β Automatically detects low-quality PDF.js extraction and falls back to AI OCR
- Automatic Chunking β Heading-aware chunking with 15% overlap to preserve context at boundaries
- Hybrid Search β Combines lexical (exact terms) + semantic (meaning) with RRF fusion
- Cross-Encoder Reranking β Optional reranking stage improves retrieval accuracy by 20-40%
- Document Browser β Visual browser to manage uploaded documents
- Background Indexing β Documents are indexed in the background; you can continue using the app while indexing completes
- Full-Screen Viewer β Cursor-style 3-panel layout with header bar showing document title and status
- Native PDF Rendering β View PDFs with page navigation and zoom controls using react-pdf
- Screenshot Selection β Drag to select any region, press Enter to capture and chat about it
- Multiple Chat Tabs β Open multiple chats side-by-side about different selections
- Document Sidebar β Switch between documents without leaving the viewer
- Collapsible Panels β Resize or collapse sidebars with intuitive icons and expand indicators
- Chat Badge β Collapsed chat panel shows badge with active chat count
- Optional Viewing β Document viewer opens only when you click the View button, not automatically on upload
- Web Search β Anthropic's first-party web search tool for real-time information
- Parallel Context Savers β Spawn up to 6 background agents to save different categories simultaneously
- Agent Orchestrator UI β Visual slot-based progress indicator showing agent status
- Multi-Model Support β Choose between Haiku, Sonnet, and Opus tiers
- Tool Support β Extensible architecture for adding custom AI tools
- Better Auth β OAuth authentication with GitHub and Google providers
- Owner Mode β Owner emails get free access using server-side API keys
- BYOK (Bring Your Own Key) β Non-owners can provide their own API keys via Settings
- Per-User Key Storage β API keys stored securely in localStorage, scoped per user
- Rich Markdown Rendering β Headers, bold, italic, lists, tables, code blocks with syntax highlighting
- LaTeX/KaTeX Support β Mathematical equations rendered beautifully
- Inline Icons β Use
:IconName:syntax for react-icons (Ionicons, FontAwesome, Material, etc.) - Dark/Light/System Theme β Full theme support with system preference detection
- Neumorphic Tool Cards β Beautiful neumorphic design for tool execution visualizations
- Collapsible Sidebar β Clean UI with persistent sidebar state
- Expandable Input β Expand the text input for composing longer messages
- Copy Code Blocks β One-click copy for code snippets in responses
- File Attachments β Attach text files and PDFs (with automatic text extraction via pdfjs-dist)
- Large Document Upload β Upload documents for RAG-based Q&A
pnpm install
# or
npm install- Go to console.anthropic.com
- Sign in or create a free account
- Navigate to Settings β API Keys (or go directly to console.anthropic.com/settings/keys)
- Click "Create Key"
- Copy the key β it will look like
sk-ant-api03-...
Important: You will only see the full key once. Save it somewhere safe!
Copy the example file and fill in your values:
cp .env.local.example .env.localRequired API Keys:
# Anthropic API Key - for Claude chat
# Get yours at: https://console.anthropic.com/settings/keys
ANTHROPIC_API_KEY=sk-ant-api03-your-key-here
# OpenAI API Key - for embeddings/semantic search
# Get yours at: https://platform.openai.com/api-keys
OPENAI_API_KEY=sk-proj-your-key-hereAuthentication (Required for multi-user):
# Secret key for signing sessions (generate with: openssl rand -base64 32)
BETTER_AUTH_SECRET=your-random-32-character-secret-here
# Base URL for auth callbacks
BETTER_AUTH_URL=http://localhost:3000
# GitHub OAuth (create at: https://github.com/settings/developers)
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
# Google OAuth (create at: https://console.cloud.google.com/apis/credentials)
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
# Owner emails - these users get free access to server API keys
OWNER_EMAILS=your@email.comOptional - Enhanced Reranking:
# Cohere API Key - for cross-encoder reranking (improves RAG accuracy by 20-40%)
# Get yours at: https://dashboard.cohere.com/api-keys
# If not set, falls back to GPT-4o-mini reranking using your OpenAI key
COHERE_API_KEY=your-cohere-api-key-hereOptional - Model Configuration:
# Main chat model (default: claude-sonnet-4-5)
MAIN_MODEL=claude-sonnet-4-5
# Context Saver agent model (default: claude-sonnet-4-5)
CONTEXT_SAVER_MODEL=claude-sonnet-4-5pnpm dev
# or
npm run devOpen http://localhost:3000 in your browser.
βββ agents/ # Agent definitions
β βββ index.ts # Export all agents
β βββ chat-agent.ts # Main chat agent with ToolLoopAgent
β βββ context-saver-agent.ts # Parallel context-saving agent
β
βββ knowledge/ # Knowledge Filesystem (client-side storage)
β βββ index.ts # Public API exports
β βββ idb.ts # IndexedDB schema and initialization
β βββ operations.ts # Filesystem operations (read, write, list, etc.)
β βββ kb-summary.ts # KB summary generator for hybrid preload
β βββ types.ts # TypeScript types
β βββ backup.ts # Backup/restore functionality
β βββ embeddings/ # RAG semantic search system
β β βββ index.ts # Embeddings public API
β β βββ operations.ts # Embedding & search operations
β β βββ hybrid-search.ts # Lexical + semantic hybrid search with RRF
β β βββ lexical-search.ts # BM25-style term matching
β β βββ chunker.ts # Heading-aware chunker with overlap
β β βββ embed-client.ts # OpenAI embedding API client
β β βββ reranker.ts # Cross-encoder reranking (Cohere/OpenAI)
β β βββ types.ts # Embedding types
β βββ links/ # Knowledge Graph system
β β βββ index.ts # Links public API
β β βββ operations.ts # Link CRUD operations
β β βββ graph-traversal.ts # BFS graph traversal
β β βββ types.ts # Link/graph types
β βββ large-documents/ # Large document RAG system
β βββ index.ts # Large docs public API
β βββ idb.ts # IndexedDB schema for documents + file storage
β βββ operations.ts # Upload, index, hybrid search, PDF extraction with quality detection
β βββ lexical-search.ts # BM25-style term matching for documents
β βββ types.ts # Large document types
β
βββ tools/ # Tool definitions
β βββ index.ts # Export all tools (createTools factory)
β βββ knowledge-tools.ts # Knowledge filesystem + graph tools (kb_list, kb_read, kb_link, kb_graph, etc.)
β βββ document-search.ts # Large document search tools
β βββ save-to-context.ts # Parallel context-saving tool
β βββ web-search.ts # Anthropic web search integration
β βββ example-weather.ts.example # Example tool template
β
βββ components/
β βββ ai-chat.tsx # Main chat UI component
β βββ chat-sidebar.tsx # Sidebar with conversation history & KB browser
β βββ knowledge-browser.tsx # Knowledge filesystem browser UI
β βββ knowledge-graph-viewer.tsx # Interactive knowledge graph visualization
β βββ large-document-browser.tsx # Large document upload/manage UI (background indexing)
β βββ chat/ # Shared chat components (reused by main chat & document viewer)
β β βββ index.ts # Public exports
β β βββ markdown-content.tsx # Markdown/LaTeX/code rendering with syntax highlighting
β β βββ tool-invocation.tsx # Tool call UI rendering
β β βββ chat-message.tsx # Complete message rendering (text, tools, files)
β βββ document-viewer/ # Full-screen document viewer
β β βββ index.tsx # Main 3-panel layout with header bar and react-resizable-panels
β β βββ pdf-viewer.tsx # PDF rendering with native canvas screenshot capture
β β βββ text-viewer.tsx # Markdown/text rendering with text selection
β β βββ chat-panel.tsx # Tabbed chat container
β β βββ chat-instance.tsx # Individual margin chat (Sonnet model, supports text & image)
β β βββ document-sidebar.tsx # Document list sidebar with collapsible expand indicator
β βββ embeddings-viewer.tsx # KB embeddings debug viewer
β βββ document-embeddings-viewer.tsx # Document embeddings debug viewer
β βββ chat-embeddings-viewer.tsx # Chat embeddings debug viewer
β βββ theme-provider.tsx # Theme context provider
β βββ tools/ # Tool-specific UI components
β β βββ agent-orchestrator-view.tsx # Visual agent progress slots
β β βββ context-saver-view.tsx # Context saver streaming display
β β βββ knowledge-tool-view.tsx # KB tool result cards
β β βββ knowledge-link-tool-view.tsx # Knowledge graph link result cards
β β βββ document-search-view.tsx # Large doc search results
β β βββ chat-search-view.tsx # Chat history search results
β β βββ web-search-view.tsx # Web search result display
β β βββ chunk-viewer-modal.tsx # Chunk detail modal
β β βββ generic-tool-view.tsx # Fallback for unknown tools
β βββ ui/ # shadcn/ui components
β
βββ lib/
β βββ auth.ts # Better Auth server configuration
β βββ auth-client.ts # Better Auth client
β βββ auth-helper.ts # Auth utilities for API routes
β βββ api-keys.ts # BYOK API key management
β βββ use-chat-history.ts # Chat history hook
β βββ chat-types.ts # Chat-related types
β βββ storage/ # Storage utilities
β β βββ chat-store.ts # Chat storage operations
β β βββ chat-chunker.ts # Chat message chunking with overlap
β β βββ chat-embeddings-idb.ts # Chat embeddings IndexedDB
β β βββ chat-embeddings-ops.ts # Chat embeddings operations
β β βββ chat-lexical-search.ts # BM25-style term matching for chat
β β βββ chat-hybrid-search.ts # Hybrid search for chat (lexical + semantic + RRF)
β βββ utils.ts # Utility functions
β
βββ app/
β βββ api/
β β βββ auth/[...all]/route.ts # Better Auth catch-all route
β β βββ chat/route.ts # Main chat API endpoint
β β βββ embed/route.ts # Embedding API endpoint
β β βββ context-saver/route.ts # Context saver agent endpoint
β β βββ generate-title/route.ts # Auto title generation endpoint
β β βββ parse-pdf/route.ts # Claude Haiku PDF extraction fallback (uses free trial)
β βββ page.tsx # Main page
β βββ layout.tsx # Root layout
β βββ globals.css # Global styles
β
βββ docs/ # Technical documentation
β βββ RAG_SEMANTIC_SEARCH.md # Hybrid search implementation details
β βββ UNIFIED_SEARCH_PLAN.md # Unified hybrid search across all tools
β βββ CROSS_CHAT_CONTEXT_SYSTEM.md # Cross-chat context system docs
β βββ KNOWLEDGE_FILESYSTEM_REFACTOR.md
β
βββ .env.local # Your environment variables (create this!)
ChatNoire includes a Knowledge Filesystem β a persistent client-side storage system that Claude can read and write via tools. This allows the AI to remember information about you across conversations.
The Knowledge Filesystem is stored in IndexedDB in your browser, providing fast, local access without any API calls. Claude has access to tools for managing your knowledge base:
| Tool | Description |
|---|---|
kb_list(path) |
List folder contents |
kb_read(path) |
Read a file's contents |
kb_write(path, content) |
Create or overwrite a file |
kb_append(path, content) |
Append to a file |
kb_mkdir(path) |
Create a folder |
kb_delete(path) |
Delete a file or folder |
kb_search(query, topK?) |
Hybrid search across all files (lexical + semantic) |
kb_link(source, target, relationship) |
Create a relationship between two files |
kb_unlink(source, target, relationship) |
Remove a relationship |
kb_links(path) |
Query all links for a file (incoming and outgoing) |
kb_graph(startPath, depth?, relationship?, direction?) |
Traverse the knowledge graph |
When you share information, Claude can spawn parallel context saver agents (up to 6) to organize and save different categories simultaneously:
| Tool | Description |
|---|---|
save_to_context(information, context?) |
Spawn a background agent to save one category |
For example, if you say "I'm John, a software engineer at Google, and I prefer dark mode", Claude will spawn 3 parallel agents:
- Personal info agent β saves name
- Work info agent β saves job details
- Preferences agent β saves UI preferences
The UI shows a beautiful slot-based progress indicator that fills as agents complete.
ChatNoire uses a hybrid search system that combines lexical and semantic approaches for optimal retrieval:
Why hybrid? Dense embeddings alone miss exact term matches (like error codes or API names), while keyword search alone misses conceptual relationships. Hybrid search gives you both.
- Lexical Search β BM25-style term matching with TF-IDF scoring
- Semantic Search β OpenAI embeddings for meaning-based retrieval
- RRF Fusion β Reciprocal Rank Fusion combines both result lists
- Reranking (optional) β Cross-encoder reranks top candidates for 20-40% accuracy boost
RRF is the 2025 industry standard for combining search results. Unlike weighted scores, RRF uses ranks not scores, making it robust across different scoring systems:
RRF(d) = 1/(k + semantic_rank) + 1/(k + lexical_rank)
Documents that appear in both lexical AND semantic results get boosted.
After initial retrieval, a cross-encoder model reranks the top candidates by examining query-document pairs together. This captures word-level interactions that bi-encoders miss.
| Backend | Quality | Cost | Notes |
|---|---|---|---|
| Cohere | Best | $2/1000 searches | Purpose-built, fastest |
| GPT-4o-mini | Good | ~$0.15/1M tokens | Default if no Cohere key |
| None | Baseline | Free | Skip reranking |
Note: Requires
OPENAI_API_KEYfor embeddings. Reranking uses GPT-4o-mini by default, or Cohere ifCOHERE_API_KEYis set.
All three search tools share the same hybrid search pipeline:
| Feature | KB Search | Chat Search | Document Search |
|---|---|---|---|
| Semantic search (embeddings) | β | β | β |
| Lexical/term matching | β | β | β |
| Hybrid fusion (RRF) | β | β | β |
| Cross-encoder reranking | β | β | β |
| Retrieve-then-rerank (50βtopK) | β | β | β |
| Query type detection | β | β | β |
| Chunk overlap (~15%) | β | β | β |
| Matched terms in results | β | β | β |
This ensures consistent behavior and accuracy regardless of which search tool Claude uses.
Additionally, the Knowledge Graph provides relationship-based retrieval via kb_links and kb_graph, complementing the search-based approach with structural navigation.
ChatNoire uses a hybrid context strategy for optimal performance:
- Summary at start: A compact index of your KB is included in Claude's system prompt
- Semantic search: Claude uses
kb_searchto find relevant content by meaning or exact terms - On-demand retrieval: Claude uses
kb_readto fetch full file contents when needed - Quote-grounding: Claude extracts quotes from files before synthesizing responses for accuracy
ChatNoire includes a Knowledge Graph that transforms your knowledge base from isolated files into an interconnected web of ideas. Claude automatically creates relationships when you share information.
| Type | Meaning | Example |
|---|---|---|
extends |
Target builds on source | "calculus.md" extends "algebra.md" |
references |
Target cites source | "project-plan.md" references "requirements.md" |
contradicts |
Target conflicts with source | "diet-2025.md" contradicts "diet-2024.md" |
requires |
Target is prerequisite for source | "ml-advanced.md" requires "linear-algebra.md" |
blocks |
Source blocks progress on target | "tech-debt.md" blocks "feature-x.md" |
relates-to |
General thematic connection | "react-hooks.md" relates-to "state-management.md" |
Use kb_graph to navigate the knowledge graph:
- Find prerequisites:
kb_graph("ml-notes.md", depth=3, relationship="requires") - Discover related content:
kb_graph("react.md", direction="both") - Impact analysis:
kb_graph("api.md", direction="incoming")β what depends on this? - Detect contradictions:
kb_graph("diet.md", relationship="contradicts")
The graph can be visualized in the sidebar under Visualization β Graph tab.
knowledge/
βββ about-me/
β βββ background.md
β βββ resume.md
βββ preferences/
β βββ coding-style.md
βββ projects/
β βββ current-project.md
β βββ ideas.md
βββ work/
βββ team.md
For documents too large to fit in Claude's context window, ChatNoire provides a Large Document RAG system. Upload PDFs, text files, or markdown and ask questions without loading the entire document.
- Upload β Click "Upload Document" or drag-and-drop a file in the Large Documents browser
- Storage β File is immediately stored in IndexedDB for viewing
- Background Indexing β Document is indexed in the background while you continue using the app
- PDF Extraction β PDFs are parsed using PDF.js (free), with intelligent quality detection that falls back to Claude Haiku for scanned/image-based documents
- Chunking β Document is split into ~512-token chunks with 15% overlap
- Embedding β Each chunk is embedded using OpenAI's embedding model
- Storage β Chunks with embeddings stored in IndexedDB (client-side)
- Search β Claude uses
document_searchto find relevant chunks by meaning - Rerank β Top candidates are reranked for higher accuracy
- Answer β Claude synthesizes an answer from the retrieved chunks
| Tool | Description |
|---|---|
document_search(query, topK?, documentId?) |
Semantic search across uploaded documents |
document_list() |
List all uploaded documents |
ChatNoire uses an intelligent hybrid PDF extraction strategy:
| Method | Cost | Speed | Best For |
|---|---|---|---|
| PDF.js | Free | Fast | Text-based PDFs with selectable text |
| Claude Haiku | ~$0.01/page | Slower | Scanned documents, image-heavy PDFs |
The system automatically detects when PDF.js extraction yields low-quality content by checking:
- Character density β At least 500 chars/page expected for real documents
- Word density β Real text has 5+ words per 100 characters
- Text structure β Proper spacing ratios indicate readable content
When quality checks fail, the system automatically falls back to Claude Haiku for AI-powered OCR.
| Parameter | Value | Rationale |
|---|---|---|
| Chunk Size | 512 tokens | Optimal for fact-focused Q&A retrieval |
| Overlap | 75 tokens (15%) | Prevents context loss at boundaries |
| Splitter | Heading-aware | Respects document structure (Markdown headings, paragraphs, sentences) |
- Text β
.txt,.md,.json,.xml,.csv,.html(up to 10MB) - PDF β Automatic text extraction with AI fallback (up to 50MB)
When you upload a document:
- The file is immediately stored and appears in your document list
- Indexing (text extraction, chunking, embedding) runs in the background
- You can view the document immediately while indexing continues
- The document shows "Indexing..." status until complete
- Once indexed, the document shows a checkmark and is searchable via RAG
Indexing always completes, even if you navigate away or close the browser tab (as long as the tab remains open in the background).
ChatNoire includes a Document Viewer with a Cursor-style 3-panel layout for reading and discussing documents.
Documents are not opened automatically when uploaded. To view a document:
- Go to the Large Documents section in the sidebar
- Click the eye icon (View button) on any document
- The document viewer opens as a full-screen overlay
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β π Document.pdf [Indexing...] β [β] β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β [Document Sidebar] β [PDF/Text Viewer] β [Chat Panel] β
β (collapsible, resizable) β (main content area) β (collapsible) β
β β β β
β > Documents β βββββββββββββββββββββββ β [Chat 1] [Chat 2] β
β β’ Calculus.pdf β β β β βββββββββββββββββ β
β β Physics.pdf β β PDF Page Render β β Selection: [img] β
β β Notes.md β β β β β
β β β [Drag to select] β β User: Explain... β
β β β [βββββββββββββ] β β Claude: This... β
β β β [β selection β] β β β
β β β [βββββββββββββ] β β ββββββββββββββββ β
β β βββββββββββββββββββββββ β β [input...] β β
β β [β Page 1/50 βΆ] [Zoom] β ββββββββββββββββ β
β [πβΈ] β [Capture (Enter)] [Cancel] β [π¬ 2] β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
When sidebars are collapsed, intuitive icons with expand indicators appear:
- Left sidebar: File icon with chevron (πβΈ)
- Right chat panel: Message icon with chat count badge (π¬ 2)
- Full-Screen Overlay β Immersive reading experience with header bar (press ESC to close)
- PDF Viewer β Native PDF rendering with page navigation and zoom
- Text Viewer β Markdown rendering for text documents
- Screenshot Selection β Drag to select a region, press Enter to capture and chat
- Multiple Chat Tabs β Open multiple conversations side-by-side
- Resizable Panels β Drag to resize using
react-resizable-panels - Collapsible Sidebars β Collapse panels for more reading space with clear expand indicators
- Status Indicators β Header shows document name, indexing status, and processing errors
The screenshot-based selection provides a robust way to discuss any part of a document:
- Drag to draw a selection rectangle on the PDF
- A visual overlay shows your selection with page number
- Press Enter to capture (or click the "Capture" button)
- Press Escape to cancel the selection
- The screenshot is captured directly from the PDF canvas (fast, no external libraries)
- Claude (Sonnet) analyzes the visual content and responds
This approach is more robust than text selection because:
- Works with scanned PDFs, diagrams, charts, and images
- Captures visual layout and formatting
- No issues with PDF text layer misalignment
- Supports any visual content, not just text
- Uses native canvas capture for speed and reliability
The margin chat fully reuses the existing chat infrastructure with complete feature parity:
- Same
/api/chatendpoint anduseChathook as the main chat - Shared
ChatMessagecomponent for full markdown/LaTeX/code rendering - Shared
ToolInvocationRendererfor displaying tool calls and results - All tools (KB search, document search, web search) work in margin chat
- Syntax-highlighted code blocks, KaTeX math, GFM tablesβidentical to the main chat
- Each chat tab is an independent conversation with its own history
This ensures the document viewer chat has the exact same rendering quality as the main chat.
ChatNoire can search across your past conversations to find relevant context. This uses the same unified hybrid search as the Knowledge Base and Large Documents.
| Tool | Description |
|---|---|
chat_search(query, topK?) |
Hybrid search across chat history (lexical + semantic + reranking) |
- Hybrid Search β Combines lexical (exact terms) and semantic (meaning) with RRF fusion
- Auto Query Detection β Automatically detects query type (exact, semantic, or mixed)
- Cross-Encoder Reranking β Optional reranking for 20-40% accuracy improvement
- Chunk Overlap β 15% overlap between chunks to preserve context at boundaries
- Matched Terms β Shows which terms matched for transparency
Chat messages are automatically chunked (with overlap) and embedded when conversations are saved.
ChatNoire integrates Anthropic's first-party web search capability, giving Claude real-time access to the internet.
- Up to 5 searches per conversation (configurable)
- Automatic source citations
- Optional domain allow/block lists
- Optional user location for relevant results
- Current events, news, or recent information
- Up-to-date documentation or API references
- User explicitly asks to search the web
- Topics where training data might be outdated
Create a new file in /tools/ (e.g., calculator.ts):
import { tool } from "ai";
import { z } from "zod";
export const calculatorTool = tool({
description: "Perform mathematical calculations",
inputSchema: z.object({
expression: z.string().describe("Math expression to evaluate"),
}),
execute: async ({ expression }) => {
const result = eval(expression); // Use a safe math parser in production!
return { expression, result };
},
});Add your tool to /tools/index.ts:
import { calculatorTool } from "./calculator";
export function createTools(apiKey: string): ToolSet {
return {
...knowledgeTools,
save_to_context: saveToContextTool,
web_search: createWebSearchTool(apiKey),
calculator: calculatorTool, // Add your tool here
};
}Create a component in /components/tools/ to render your tool's results beautifully. See knowledge-tool-view.tsx or web-search-view.tsx for examples.
Edit /agents/chat-agent.ts to customize the agent's behavior. The createChatAgent function builds the agent with:
- Model: Configurable between Haiku 4.5, Sonnet 4.5, and Opus 4.5 via the model selector
- Instructions: System prompt with XML-structured context engineering
- Tools: All tools from
/tools/index.ts(KB, graph, documents, web search, context savers) - KB Summary: Pre-generated summary of your knowledge base for hybrid preload
| Tier | Model | Display Name | Best For |
|---|---|---|---|
| Haiku | claude-haiku-4-5-20251001 | Apprentice | Fast, simple tasks |
| Sonnet | claude-sonnet-4-5-20250929 | Master | Balanced speed/quality |
| Opus | claude-opus-4-5-20251101 | Grandmaster | Complex reasoning |
The system prompt follows research-backed context engineering principles:
- XML-structured data at TOP (improves retrieval by up to 30%)
- Quote-grounding instruction (improves accuracy by 20+ percentage points)
- Hybrid preload strategy (summary + just-in-time retrieval)
- Ensure the file is named exactly
.env.local(with the leading dot) - Verify it's in the project root (same level as
package.json) - Check there are no spaces around the
=sign - Restart the dev server after creating the file
- Verify you copied the full key (it's quite long)
- Ensure the key starts with
sk-ant-api03- - Check for extra spaces or quotes around the key
- Confirm the key hasn't been revoked in the Anthropic console
If you see an API key error when uploading PDFs, it means the PDF requires AI-powered OCR (scanned or image-based PDF). The system uses Claude Haiku via the free trial for this. Ensure your server has ANTHROPIC_API_KEY configured, or the system will use the free trial automatically.
If a PDF document has surprisingly few chunks (e.g., 9 chunks for a 20-page paper), this usually means PDF.js extracted low-quality text. Try:
- Delete the document
- Re-upload it β the improved quality detection should now trigger AI OCR fallback
- Framework: Next.js 16 with App Router
- AI SDK: Vercel AI SDK v6 (
aiv6.0.34,@ai-sdk/react,@ai-sdk/anthropic) - Model: Claude Sonnet 4.5 (Anthropic)
- Embeddings: OpenAI
text-embedding-3-small(ortext-embedding-3-largewith dimension reduction) - Reranking: Cohere Rerank API or GPT-4o-mini fallback
- Additional Providers:
@ai-sdk/openai,@ai-sdk/groq(available for extensions) - Authentication: Better Auth with GitHub and Google OAuth
- Styling: Tailwind CSS v4
- Components: shadcn/ui + Radix UI
- Icons: React Icons (Ionicons, FontAwesome, Material, BoxIcons, Ant Design)
- Markdown: react-markdown with remark-gfm
- Math Rendering: KaTeX with rehype-katex and remark-math
- Syntax Highlighting: react-syntax-highlighter with Prism
- PDF Parsing: pdfjs-dist (client-side extraction) + Claude Haiku (AI fallback with quality detection)
- PDF Viewing: react-pdf for native PDF rendering
- Resizable Panels: react-resizable-panels for document viewer layout
- Storage: IndexedDB (via
idb) for knowledge base, chat history, large documents, and file data - Validation: Zod
- Notifications: Sonner
ChatNoire uses Better Auth for authentication with OAuth providers.
| User Type | API Keys Used | Configuration |
|---|---|---|
| Owner | Server-side env keys | Email in OWNER_EMAILS |
| BYOK User | Their own keys | Entered via Settings modal |
Owner emails get free access using the API keys in your .env.local. Other users must provide their own keys through the Settings modal (stored in their browser's localStorage).
-
GitHub: Create OAuth app at github.com/settings/developers
- Callback URL:
http://localhost:3000/api/auth/callback/github
- Callback URL:
-
Google: Create credentials at console.cloud.google.com
- Callback URL:
http://localhost:3000/api/auth/callback/google
- Callback URL:
- Push your code to GitHub
- Import the repository in Vercel
- Add environment variables in Project Settings:
ANTHROPIC_API_KEYOPENAI_API_KEYBETTER_AUTH_SECRETBETTER_AUTH_URL(your production URL)GITHUB_CLIENT_IDandGITHUB_CLIENT_SECRETGOOGLE_CLIENT_IDandGOOGLE_CLIENT_SECRETOWNER_EMAILSCOHERE_API_KEY(optional)
- Update OAuth callback URLs to use your production domain
- Deploy!
MIT