Files
nibbleai/README.md
T
olivier 9b7ec36828 Unify AI provider selection across all features
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.
2026-09-07 17:14:33 -04:00

264 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# NibbleAI
> AI-powered tools for your Obsidian vault — speech-to-text, proofreading, title generation, property filling, and more.
[![Obsidian plugin](https://img.shields.io/badge/Obsidian-plugin-blue?logo=obsidian)](https://obsidian.md)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
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)
1. Open **Settings****Community plugins**
2. Disable **Safe mode**
3. Click **Browse** and search for "NibbleAI"
4. Install and **Enable**
### Manual Installation
1. Download the latest release from the [Releases page](https://github.com/your-username/nibbleai/releases)
2. Extract the folder to `YourVault/.obsidian/plugins/nibbleai/`
3. Enable the plugin in **Settings****Community plugins**
### Build from Source
```bash
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](https://openrouter.ai/keys) API key with a free model like `google/gemini-2.5-flash-lite` costs 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 (01) |
| 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
```bash
# 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:
```bash
OUTPUT_PATH=/path/to/your/vault/.obsidian/plugins/nibbleai npm run dev
```
---
## License
MIT
---
*NibbleAI — small bites of AI for your Obsidian vault.*