ebullient1k downloadsLocal AI content generation with Ollama. Features custom prompts, content filtering, link expansion, continuous conversations, and extensible filter API.
Generate AI content in Obsidian using local LLMs or OpenAI-compatible APIs. Features custom prompts, content filters, and an API for advanced integrations.
Important Notes
- Privacy: Supports local processing with Ollama or external OpenAI-compatible APIs
- Network Use: Plugin only communicates with your configured LLM provider(s)
- Mobile Support: Works on both desktop and mobile devices
[[wikilinks]] in your promptswindow.promptFlow.filtersChoose one or more:
llama3.1).obsidian/plugins/prompt-flow/ directoryAssuming you have the BRAT plugin installed and enabled:
https://github.com/ebullient/obsidian-prompt-flow/ as the URL, and install the pluginSee CONTRIBUTING.md for development setup instructions.
ollama pull llama3.1https://api.openai.com, https://openrouter.ai/api, http://localhost:8080)gpt-4o, gpt-4o-mini, meta-llama/llama-3.1-8b-instruct)<prompt name> (e.g., "Generate reflection question")In Settings → Prompt Flow → Prompts:
For each prompt, a command is automatically created: Generate [prompt name]
You can override the prompt file on a per-note basis using frontmatter:
---
prompt-file: "prompts/creative-writing-coach.md"
---
Available override:
prompt-file: Path to a custom prompt fileThis override allows different notes to use different prompt files with the same command. Without this override, the plugin uses the prompt file configured in Settings for that command.
To override the connection or model, specify these in the prompt file's frontmatter instead (see Prompt File Configuration below).
Prompt files can include frontmatter to customize behavior:
---
connection: openrouter
model: meta-llama/llama-3.1-8b-instruct
num_ctx: 4096
temperature: 0.7
top_p: 0.9
isContinuous: true
includeLinks: true
excludeCalloutTypes: ["todo", "warning"]
wrapInBlockquote: true
---
You are a reflective companion. Ask concise questions that help summarize the
day.
Available options:
connection: Connection name to use (overrides default)model: Specific model to usenum_ctx: Context window size (tokens). Ollama only; also sets the window filter budgetmax_tokens: Cap on generated length. Sent as max_tokens (OpenAI-compatible) or num_predict (Ollama)temperature: Randomness (0.0-2.0, default: 0.8)top_p: Nucleus sampling threshold (0.0-1.0)top_k: Top-k sampling limit (not in the OpenAI schema; sent as an extension)repeat_penalty: Penalty for repetition (>0, default: 1.1; not in the OpenAI schema; sent as an extension)context: Portion of the note to send (above, below, selection, none, or omit for full note)isContinuous: Keep conversation context between requests (default: false)includeLinks: Auto-expand [[wikilinks]] to include linked content (default: false)excludePatterns: Array of regex patterns to exclude linksexcludeCalloutTypes: Array of callout types to filter from contentfilters: Array of filter function names from window.promptFlow.filterswrapInBlockquote: Format output as blockquote (default: true)calloutHeading: Heading text for callout-style formattingWhen isContinuous is true, the plugin maintains conversation context for each prompt/note combination. This allows follow-up prompts to build on previous exchanges. Context is automatically cleared after 30 minutes of inactivity.
When includeLinks is enabled, the plugin automatically includes content from [[wikilinks]] and embedded files in your note. This provides the AI with broader context.
Link filtering:
Configure global exclude patterns in Settings → Link filtering, or use excludePatterns in prompt frontmatter to filter specific links.
Two settings control how much of the note is sent to the model.
context — what to include from the note
The context parameter selects which part of the active note is used as input, relative to the cursor position:
| Value | Behavior |
|---|---|
| (omitted) | Full note content |
above |
Text from the start of the note up to the cursor |
below |
Text from the cursor to the end of the note |
selection |
Currently selected text; falls back to no content if nothing is selected |
none |
No note content — prompt text only |
Use above when the prompt should summarize or act on what you've written so far. Use below for prompts that process the remainder of a note. Use selection for prompts that should act on a highlighted passage. Use none when the prompt is self-contained and note content would only add noise.
num_ctx and the built-in window filter
num_ctx is only sent to Ollama. It is the model's working memory — how many tokens it holds at once, prompt and output together — not a limit on output length, which is max_tokens.
Ollama defaults well below what the model advertises, and overflow is silent: the answer still reads well, written from the tail of what survived. Setting num_ctx in a prompt overrides that for the call. See ollama#2714.
OpenAI-compatible connections ignore it — context is fixed when the server starts (--ctx-size for llama-server).
When note content (including any expanded wikilinks) may exceed the model's context window, add window to the filters list. It trims the content to fit within the budget (num_ctx × 3 × 0.8 characters). If the note contains embedded or linked content (appended after the EMBEDDED/LINKED CONTENT marker), that section is dropped first. If the primary note content still exceeds the budget, it is truncated to fit.
---
num_ctx: 4096
filters:
- window
---
Summarize the key points from my notes.
num_ctx must be set when using the window filter — the plugin will show an error if it is missing. This applies on every backend, including OpenAI-compatible ones that otherwise ignore num_ctx: the budget is calculated locally, before anything is sent.
max_tokens and thinking models
max_tokens caps how much the model generates, and is independent of num_ctx.
On a thinking model — Qwen3 and others that reason before answering — the budget is spent on reasoning first. A cap that looks generous for the answer can be consumed entirely before the model starts writing, producing an empty response rather than a short one. Leave real headroom, or turn thinking off for that prompt (Qwen3 honours /no_think in the prompt text).
The plugin exposes window.promptFlow.filters for external scripts (CustomJS, other plugins) to register content transformation functions.
Example filter registration:
// In a CustomJS script or another plugin
window.promptFlow = window.promptFlow || {};
window.promptFlow.filters = window.promptFlow.filters || {};
window.promptFlow.filters.redactSecrets = (content) => {
return content.replace(/password:\s*\S+/gi, "password: ***");
};
Using filters in prompt files:
---
filters:
- redactSecrets
- removeEmojis
---
Generate a thoughtful reflection question.
Filters are applied in the order specified before sending content to the LLM.
Configure one or more LLM provider connections in Settings → Prompt Flow → Connections.
Ollama connection settings:
http://localhost:11434)llama3.1, mistral)10m, 1h, -1 for always)OpenAI-compatible connection settings:
/v1 — the plugin appends the path itself (e.g. https://host:8443, not https://host:8443/v1)The plugin auto-detects the correct API path structure for different OpenAI-compatible services (standard /v1 or OpenWebUI /api/v1).
Keep alive is not offered for OpenAI-compatible connections, and a value left over from a connection that was previously Ollama is ignored. How long a model stays resident is a server-side setting there — with llama-swap it is the per-model ttl in its config.
[display text](link target)Cannot connect to LLM provider:
ollama serve) and check the base URLNo models found:
ollama pull llama3.1) and verify with ollama listEmpty or truncated response:
max_tokens in the prompt, reduce the document size, or increase the server's context sizemax_tokens and thinking models aboveGenerated content not appearing:
See CONTRIBUTING.md for development setup, build commands, and architecture details. AI assistants should review CLAUDE.md for working guidelines.
This plugin is based on Build an LLM Journaling Reflection Plugin for Obsidian by Thomas Chang. See his implementation.
Additional implementation ideas come from the Canvas Conversation plugin by André Baltazar
MIT