810676ff21
- src/chat-view.ts: Add getIcon() returning 'bot' for the view tab icon.
Improve render() with role-specific CSS classes (user vs assistant) and
message header structure for better styling hooks.
- src/main.ts: Add ribbon icon ('bot') in the left sidebar that opens the
chat view with a single click.
- styles.css (new): Modern chat UI with message bubbles, distinct user and
assistant themes using Obsidian CSS variables, sticky input bar, styled
send button with accent color, and emoji role indicators.
- install.sh: Copy styles.css into the plugin directory and verify its
presence during installation.
- README.md: Include styles.css in manual install instructions.
- __mocks__/obsidian.ts: Add addRibbonIcon() mock for test compatibility.
- tests/chat-view.test.ts: Add getIcon() assertion.
187 lines
7.7 KiB
Markdown
Executable File
187 lines
7.7 KiB
Markdown
Executable File
# Obsidian Ollama Plugin
|
||
|
||
A plugin that integrates [Ollama](https://ollama.ai) with Obsidian, allowing you to chat with local AI models, search your vault context, and use AI tools like creating files.
|
||
|
||
## Features
|
||
|
||
- Chat with Ollama models directly in Obsidian
|
||
- Vault context search — the assistant can reference your notes
|
||
- Tool integration — create files based on chat responses
|
||
- Streaming responses
|
||
- Semantic response cache — repeated or similar queries are answered instantly without hitting the model (requires ChromaDB)
|
||
- Customisable model, URL, and cache settings
|
||
|
||
## Prerequisites
|
||
|
||
1. **Install Ollama**: Follow the instructions at [ollama.ai](https://ollama.ai)
|
||
2. **Start Ollama**: `ollama serve`
|
||
3. **Pull a chat model**: `ollama pull llama3` (or any other model you prefer)
|
||
|
||
### Optional — Semantic Cache
|
||
|
||
The semantic cache stores responses in a local [ChromaDB](https://www.trychroma.com) vector database. When you ask a question that is semantically similar to one already cached, the stored answer is returned immediately instead of calling the model.
|
||
|
||
1. **Install ChromaDB**:
|
||
```bash
|
||
pip install chromadb
|
||
```
|
||
2. **Start ChromaDB**:
|
||
```bash
|
||
chroma run --host localhost --port 8000
|
||
```
|
||
3. **Pull an embedding model** (used to generate vectors for cache lookups):
|
||
```bash
|
||
ollama pull nomic-embed-text
|
||
```
|
||
4. Enable the cache in the plugin settings and configure the ChromaDB URL.
|
||
|
||
## Installation
|
||
|
||
### Quick install (recommended)
|
||
|
||
Use the included install script. It handles dependency installation, building, and copying the plugin into your vault:
|
||
|
||
```bash
|
||
# Clone or download this repository, then run:
|
||
./install.sh /path/to/your/obsidian/vault
|
||
```
|
||
|
||
The script will:
|
||
- Install npm dependencies (excluding Ollama — you install that separately)
|
||
- Compile the TypeScript plugin
|
||
- Copy the built plugin into `<vault>/.obsidian/plugins/ollama-plugin/`
|
||
|
||
### Manual install
|
||
|
||
If you prefer to install manually:
|
||
|
||
```bash
|
||
npm install
|
||
npm run build
|
||
```
|
||
|
||
Then copy the plugin into your vault:
|
||
|
||
```bash
|
||
mkdir -p /path/to/vault/.obsidian/plugins/ollama-plugin
|
||
cp manifest.json /path/to/vault/.obsidian/plugins/ollama-plugin/
|
||
cp main.js /path/to/vault/.obsidian/plugins/ollama-plugin/
|
||
cp styles.css /path/to/vault/.obsidian/plugins/ollama-plugin/
|
||
# Remove old dist/ from previous installs (no longer needed with bundling)
|
||
rm -rf /path/to/vault/.obsidian/plugins/ollama-plugin/dist
|
||
```
|
||
|
||
> **Note:** The plugin is now bundled into a single `main.js` via esbuild. The `obsidian` npm package is a dev-only type stub — Obsidian provides its own API at runtime. The `chromadb` client library is also bundled into `main.js`, so no extra `node_modules` copy is needed for the semantic cache feature.
|
||
|
||
### After installation
|
||
|
||
1. Restart Obsidian (or reload: `Ctrl+Shift+P` → "Reload app without saving")
|
||
2. Go to **Settings → Community plugins** → enable **Ollama Plugin**
|
||
3. Configure the plugin at **Settings → Ollama Settings**
|
||
|
||
## Configuration
|
||
|
||
Open **Settings → Ollama Settings** to configure the plugin.
|
||
|
||
| Setting | Default | Description |
|
||
|---------|---------|-------------|
|
||
| Ollama URL | `http://localhost:11434` | Base URL of your Ollama instance |
|
||
| Model | `llama3` | Model used for chat responses |
|
||
| Vault Search Limit | `3` | Maximum number of vault entries to include in context |
|
||
| Max Message History | `50` | Maximum number of messages kept in conversation history |
|
||
| Enable Semantic Cache | Off | Cache responses for fast repeated queries |
|
||
| ChromaDB URL | `http://localhost:8000` | URL of your running ChromaDB instance |
|
||
| Cache Embedding Model | `nomic-embed-text` | Ollama model used to generate cache embeddings |
|
||
| Cache Similarity Threshold | `0.85` | Minimum cosine similarity (0–1) for a cache hit — higher values require closer matches |
|
||
| Clear Semantic Cache | — | Button to wipe all cached responses from ChromaDB |
|
||
|
||
## Usage
|
||
|
||
1. Open the chat view via the command palette (`Ctrl+P` → "Open Ollama Chat") or the ribbon icon
|
||
2. Type your message in the input box
|
||
3. Press **Enter** or click **Send** to send your message
|
||
4. Press **Shift+Enter** to insert a line break
|
||
5. Click **New Chat** to start a fresh conversation
|
||
|
||
## Semantic Cache Behaviour
|
||
|
||
- The cache is **bypassed** when tool calls are involved (e.g. file creation), since those requests have side effects.
|
||
- Responses are stored against the last user message in the conversation. If a new query is sufficiently similar (above the configured threshold), the cached response is returned.
|
||
- Re-asking the same question updates the existing cache entry rather than creating a duplicate.
|
||
- Use the **Clear Semantic Cache** button in settings to remove all stored responses (for example after switching embedding models).
|
||
|
||
## Vault Context
|
||
|
||
When you send a message, the plugin automatically searches your vault for relevant notes and includes them as context. The search uses weighted scoring:
|
||
|
||
- **Headings** — 5x weight
|
||
- **Frontmatter title** — 3x weight
|
||
- **Frontmatter tags** — 2.5x weight
|
||
- **First paragraph** — 1.5x weight
|
||
- **General content** — 1x weight
|
||
|
||
## Tools
|
||
|
||
The plugin exposes a `create_file` tool that allows the AI to create new markdown files in your vault. Paths are validated for safety (no `.obsidian`/`.git` access, no path traversal).
|
||
|
||
## Supported Models
|
||
|
||
Any Ollama-supported model works. Popular choices:
|
||
|
||
- `llama3`
|
||
- `llama2`
|
||
- `mistral`
|
||
- `codellama`
|
||
- and many more — see [ollama.com/library](https://ollama.com/library)
|
||
|
||
## Development
|
||
|
||
```bash
|
||
npm install
|
||
npm run build
|
||
npm test
|
||
```
|
||
|
||
## Troubleshooting
|
||
|
||
| Symptom | Likely cause | Fix |
|
||
|---------|-------------|-----|
|
||
| Plugin doesn't appear in Obsidian | Install script was not run or failed | Run `./install.sh /path/to/vault` and reload Obsidian |
|
||
| Cannot connect to Ollama | Ollama is not running | Run `ollama serve` |
|
||
| Model not found | Model not pulled | Run `ollama pull <model>` |
|
||
| Semantic cache unavailable (notice shown) | ChromaDB is not running, or the ChromaDB URL is wrong | Start ChromaDB (`chroma run`) and verify the URL in settings |
|
||
| Cache always misses | Similarity threshold is too high, or the embedding model was changed | Lower the threshold or click **Clear Semantic Cache** and let the cache rebuild |
|
||
| Slow first response after enabling cache | Embedding model not yet pulled | Run `ollama pull nomic-embed-text` (or the model you configured) |
|
||
| Permission issues | Vault write permissions | Check that your Obsidian vault has proper write permissions |
|
||
|
||
## Security
|
||
|
||
- File paths are validated to prevent access to `.obsidian/` and `.git/` directories
|
||
- Path traversal attempts (`..`) are blocked
|
||
- Absolute paths and Windows drive letters are rejected
|
||
- Maximum path length is enforced (200 characters)
|
||
|
||
## License
|
||
|
||
MIT License
|
||
|
||
Copyright (c) 2024 Flo Egger
|
||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
of this software and associated documentation files (the "Software"), to deal
|
||
in the Software without restriction, including without limitation the rights
|
||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
copies of the Software, and to permit persons to whom the Software is
|
||
furnished to do so, subject to the following conditions:
|
||
|
||
The above copyright notice and this permission notice shall be included in all
|
||
copies or substantial portions of the Software.
|
||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||
SOFTWARE.
|