Every LLM-backed feature (Post-Processing, Proofreading, Title Generation, Property Filler) now reads from one CHAT_PROVIDERS registry instead of 5 hand-duplicated provider lists, so they always offer the exact same providers in the exact same order. - Add Groq as a 5th chat-completion provider (was transcription-only despite its OpenAI-compatible API and an already-collected key). - Provider dropdowns disable options with no API key configured (shown as e.g. "Anthropic (no API key)") instead of silently failing at runtime when picked. - Collapse 3 byte-for-byte duplicated resolveProvider() methods (Proofreader, TitleGenerator, PropertyFiller) plus AudioHandler's getPostProcessingApiKey() into one resolveChatProvider() helper (src/ProviderResolver.ts). - Fix Custom provider: previously Proofreading/Title/Property silently reused Post-Processing's postProcessingUrl with no visible field to set it. Renamed to a shared customApiUrl field with its own UI (createCustomProviderFields), now exposed on every tab that offers Custom, plus rows on the API Keys tab. Migrates old data.json values automatically. - Update README settings reference and getting-started sections to match. No behavior change for existing single-provider setups; migration handles the postProcessingUrl -> customApiUrl rename transparently.
NibbleAI
AI-powered tools for your Obsidian vault — speech-to-text, proofreading, title generation, property filling, and more.
NibbleAI is a central hub for small, practical AI-assisted tasks inside Obsidian. Instead of installing a dozen single-purpose plugins, NibbleAI gives you one consistent interface with shared configuration, a unified AI service, and a growing set of capabilities.
Features
🎙️ Speech-to-Text (Transcription)
Record audio directly in Obsidian or upload existing audio/video files, and get instant transcripts via OpenAI Whisper (or any compatible API — Groq, Azure, etc.).
- Record with your microphone using the built-in recorder
- Upload audio/video files from disk
- Transcribe existing audio files via the file context menu
- Post-process transcripts with an LLM to fix grammar, remove filler words, and format as Markdown
- Auto-generate note filenames from the transcript content
- Template system for note content (
{{date}},{{time}},{{title}},{{transcription}},{{audioFile}})
✍️ Proofreading
Fix punctuation and grammar of selected text with a single command or right-click.
- Prompt injection resistant — the built-in system prompt explicitly guards against prompt injection attacks in the text being proofread
- Smart quote replacement — straight quotes → curly quotes (except in code blocks)
- Works with any OpenAI-compatible provider (OpenRouter, OpenAI, etc.)
🏷️ Title Generation
Generate a descriptive title for the current note with one command. Choose how to apply it:
- Rename the file — the note's filename becomes the generated title
- Set a frontmatter property — adds or updates a
title:field in the YAML frontmatter
📋 Property Filling
Fill any frontmatter property with AI-generated content. Built-in quick commands for common properties:
- Fill any property — prompts you for the property name
- Fill "summary" — one-click command
- Fill "tags" — one-click command
- Customizable generation prompt with
{property}placeholder
Installation
From Obsidian Community Plugins (once published)
- Open Settings → Community plugins
- Disable Safe mode
- Click Browse and search for "NibbleAI"
- Install and Enable
Manual Installation
- Download the latest release from the Releases page
- Extract the folder to
YourVault/.obsidian/plugins/nibbleai/ - Enable the plugin in Settings → Community plugins
Build from Source
git clone https://github.com/your-username/nibbleai.git
cd nibbleai
npm install
npm run build
Then copy the main.js, manifest.json, and styles.css to your vault's plugins folder.
Getting Started
1. Configure API Keys
Open Settings → NibbleAI and add at least one API key:
| Key | Used For |
|---|---|
| Groq API Key | Whisper transcription, and as a chat provider for proofreading/title/property/post-processing |
| OpenAI API Key | Whisper transcription, and as a chat provider for proofreading/title/property/post-processing |
| Anthropic API Key | Claude models for proofreading/title/property/post-processing |
| OpenRouter API Key | Access to hundreds of models for proofreading/title/property/post-processing |
| Custom API Key + URL | Any OpenAI-compatible endpoint (self-hosted, Azure, etc.) |
Every LLM-backed feature (Proofreading, Title Generation, Property Filler, Post-Processing) shows the same provider dropdown — pick any provider that has a key configured above.
Tip: An OpenRouter API key with a free model like
google/gemini-2.5-flash-litecosts nothing and works great across all four AI features.
2. Try the Features
| Feature | How to Use |
|---|---|
| Record audio | Click the 🤖 ribbon icon, or use the Start/stop recording command (Alt+Q) |
| Upload audio | Use the Upload audio file command |
| Transcribe existing file | Right-click an audio file in the file explorer |
| Proofread text | Select text → right-click → "Fix punctuation and grammar with AI" |
| Generate title | Use the Generate title for current note command |
| Fill property | Use the Fill property with AI command (or the presets for summary / tags) |
Commands
| Command | Icon | Default Hotkey | Description |
|---|---|---|---|
| Start/stop recording | mic |
Alt+Q |
Toggle recording on/off |
| Upload audio file | upload |
— | Choose an audio/video file to transcribe |
| Pause/resume recording | pause |
— | Pause or resume an active recording |
| Open recording controls | popup-open |
— | Show the recording modal |
| Fix punctuation and grammar | wand |
— | Proofread selected text with AI |
| Generate title for current note | heading |
— | Generate and apply a title |
| Fill property with AI | pencil |
— | Prompt for a property name, then fill it |
| Fill "summary" property | list |
— | Directly fill the summary property |
| Fill "tags" property | tags |
— | Directly fill the tags property |
URI Protocol
NibbleAI registers the nibbleai:// protocol handler, allowing external tools to control recording:
| URI | Action |
|---|---|
obsidian://nibbleai |
Open recording controls |
obsidian://nibbleai?command=start |
Start recording |
obsidian://nibbleai?command=stop |
Stop recording |
obsidian://nibbleai?command=pause |
Pause/resume recording |
obsidian://nibbleai?command=cancel |
Cancel recording |
This is useful for automation tools, Stream Deck, or scripting.
Model Selection
Wherever you need to select an AI model (post-processing, proofreading, title generation), NibbleAI provides a Browse models button that opens a searchable dialog of available OpenRouter models:
- Models are fetched live from
openrouter.ai/api/v1/models - Free models appear first (marked with a Free badge)
- Type to filter by name, ID, or description
- You can still type a model ID manually if you prefer
Settings Reference
API Keys
Securely stored in your system keychain via Obsidian's SecretStorage. Never written to data.json.
Transcription
| Setting | Default | Description |
|---|---|---|
| API URL | https://api.openai.com/v1/audio/transcriptions |
Whisper-compatible endpoint |
| Model | whisper-1 |
Transcription model |
| Language | (empty) | Language hint (auto-detect if empty) |
| Prompt | (empty) | Boosts accuracy for specific terms |
| Cursor context | Off | Send text around cursor as context |
| Temperature | 0 |
Sampling temperature (0–1) |
| Response format | json |
Output format |
Recording
| Setting | Default | Description |
|---|---|---|
| Microphone | Default | Audio input device |
| Save audio file | On | Save recording to vault |
| Audio save path | (vault root) | Folder for audio files |
Output
| Setting | Default | Description |
|---|---|---|
| Create note file | On | Create a .md file per transcription |
| Note save path | (vault root) | Folder for notes |
| Note filename template | {{datetime}} |
Variables: {{date}}, {{time}}, {{datetime}}, {{title}} |
| Note template | ![[{{audioFile}}]]\n{{transcription}} |
Variables: {{transcription}}, {{audioFile}}, {{title}} |
Post-Processing
| Setting | Default | Description |
|---|---|---|
| Enable | Off | Clean up transcripts with an LLM |
| Provider | Anthropic | Any configured provider: Anthropic, OpenAI, Groq, OpenRouter, or Custom |
| Model | claude-sonnet-4-20250514 |
LLM for cleanup |
| Auto-generate title | Off | Create filenames from content |
Proofreading
| Setting | Default | Description |
|---|---|---|
| Provider | OpenRouter | Any configured provider: Anthropic, OpenAI, Groq, OpenRouter, or Custom |
| Model | openai/gpt-4o-mini |
Model for proofreading |
| Temperature | 0.2 |
Lower = more consistent |
| Max tokens | 2000 |
Maximum response length |
| System prompt | (built-in) | Editable with prompt injection protections |
Title Generation
| Setting | Default | Description |
|---|---|---|
| Provider | OpenRouter | Any configured provider: Anthropic, OpenAI, Groq, OpenRouter, or Custom |
| Model | openai/gpt-4o-mini |
Model for generating titles |
| Mode | Rename file | Rename file or set frontmatter property |
| Max title length | 8 words | Maximum words in generated title |
Property Filler
| Setting | Default | Description |
|---|---|---|
| Provider | OpenRouter | Any configured provider: Anthropic, OpenAI, Groq, OpenRouter, or Custom |
| Model | openai/gpt-4o-mini |
Model for generating property values |
| Custom prompt | (built-in) | Template with {property} placeholder |
| Overwrite existing | Off | Replace existing property values |
Architecture
NibbleAI/
├── main.ts # Plugin entry point, commands, events
├── src/
│ ├── SettingsManager.ts # Settings + SecretStorage management
│ ├── AIService.ts # Unified AI client (OpenAI-compatible + Anthropic-native)
│ ├── ProviderResolver.ts # Shared provider → API key/endpoint resolution
│ ├── ModelBrowser.ts # OpenRouter model suggest modal
│ ├── PostProcessor.ts # LLM post-processing for transcripts
│ ├── NibbleAISettingsTab.ts # Settings UI
│ ├── recorder/ # Audio recording (Timer, StatusBar, Controls, AudioRecorder)
│ ├── transcription/ # Whisper API calls + template rendering
│ ├── proofreading/ # Proofreading module
│ ├── title/ # Title generation module
│ └── property/ # Property filling module
└── styles.css # Plugin styles
All AI calls go through AIService.callChatCompletion(), which handles both OpenAI-compatible and Anthropic-native API formats. Each feature module is self-contained and receives the plugin instance for access to settings and the Obsidian API.
Development
# Install dependencies
npm install
# Build for production
npm run build
# Watch mode (auto-rebuild on changes)
npm run dev
# Type-check only
npx tsc --noEmit -skipLibCheck
Set the OUTPUT_PATH environment variable to output main.js directly into your vault's plugin directory for fast iteration:
OUTPUT_PATH=/path/to/your/vault/.obsidian/plugins/nibbleai npm run dev
License
MIT
NibbleAI — small bites of AI for your Obsidian vault.