sally29 downloadsChat with AI about selected Markdown and save only the excerpts you confirm.
AI Reading Companion lets you select text in any Obsidian Markdown note, discuss it with an OpenAI-compatible model, collect answer excerpts in an editable draft, and save only the draft you confirm.
The conversation, reasoning output, search results, and unselected answer text are not written to your Vault automatically.
web_search tools and source annotations.Folder/Note/AI conversations.md.On tablets, Obsidian may provide more room, but the same touch-safe workflow is used whenever the app is running in mobile mode.
By default, the excerpt is appended to the source note under:
## AI excerpts
The heading is created automatically when it does not exist. You can instead save every confirmed excerpt to one central note.
Each model configuration can use either the OpenAI-compatible Chat Completions protocol or Responses API. The adapter converts the same conversation and local function tools to the selected wire format.
The first setting, Interface language, switches the complete settings page between English and Simplified Chinese. English remains the default for marketplace installations, and the choice is stored without changing any provider, key, search, or saving configuration.
web_search; Kimi Coding and GLM Coding Plan default to Chat Completions with their matching plan-search adapter. Providers without a paired adapter reuse an already configured portable independent service such as Tavily; if none exists, web access remains off instead of reusing an incompatible coding-plan credential. Future presets use the same mapping instead of adding UI-specific special cases.chat/completions or responses URL.Web access has two mutually exclusive execution paths for each request:
Each named model configuration stores one explicit Web access route:
There is no automatic failover between hosted search, independent search, and disabled access. Switching model configurations also switches their saved web-access route, independent-search policy, and selected search configuration(s). Independent services are saved separately and grouped by established protocols and adapters: vendor bundled endpoints, REST search APIs, or Streamable HTTP MCP. A custom URL is not treated as a universal search protocol because authentication, request bodies, and result formats vary by provider.
WebSearch and FetchURL functions. Use it with models that support OpenAI-style function calling.Existing Kimi Coding configurations are migrated automatically to the Kimi Coding plan search adapter. This is plugin-executed search, not a provider-hosted Responses API tool. Disabling the search provider leaves normal chat unchanged.
The GLM Coding Plan preset connects to its official webSearchPrime Remote MCP endpoint and reuses the selected GLM model key by default. The generic Remote MCP option covers other plans that publish a Streamable HTTP MCP server. Its URL field is deliberately labeled as an MCP endpoint: an ordinary REST search URL, local stdio MCP, or vendor CLI-only tool is not compatible. Some coding plans also require a different general-platform key for search even when model access uses a subscription key.
Local retrieval is deliberately folder-scoped and lexical in this version; it does not create embeddings or a whole-vault index. Inside the selected scope, the plugin maintains a bounded, incremental in-memory body-term cache in addition to note metadata. The cache is discarded with the plugin process and never expands beyond the authorized folder.
The first retrieval pass compares the question with cached filenames, headings, aliases, tags, links, and bounded body terms, then reads only a few high-scoring passages. Results are balanced across personal/user-curated notes, external material, and unknown identity; every passage retains that identity and an epistemic-status label in the Context Receipt. Further tool calls accept temporary source references, not arbitrary file paths. Retrieved notes may be imported material, so the model is instructed not to treat them as the user's own knowledge or as a proven connection without textual support.
Related historical questions from the same selected scope may be included as continuity cues. The plugin does not include the old assistant answer, and a prior question is never treated as supporting evidence.
The plugin observes only explicit statements about how you prefer to learn or receive explanations. A signal remains a local candidate until similar evidence appears in three distinct conversations, after which it becomes ready for review. Use Review learning memory candidates from the command palette to confirm, reject, or delete it. Only confirmed preferences enter the model context, and they control presentation style rather than factual conclusions. Candidates become stale after 90 days; confirmed preferences are marked for review after 180 days without use. The store is capped at 50 records.
Use Show agent runtime diagnostics to inspect local p50/p95 duration, completion and cancellation counts, context-trimming rate, and categorized failures. This is operational diagnostics, not telemetry: it remains in Obsidian's plugin data.json, keeps at most 200 records for 30 days, is capped at 256 KB, and can be cleared from the dialog or the plugin settings.
Open Sources used this turn beneath an answer and choose Review and save. Edit the title and excerpt, optionally add why you kept it, review the destination, and confirm. Only the reviewed fields are written to the configured Web source inbox. If the filename already exists, the plugin creates a timestamped copy instead of overwriting it.
The model/tool loop is implemented by a provider-neutral AgentRuntime. It owns model turns, tool-call parsing, tool registration, tool-result messages, round limits, cancellation checks, runtime events, and final-response detection. A frozen RunPlan defines the current request's budgets and grants. ContextBuilder selects bounded context and produces a visible receipt, while ModelTransport translates Chat Completions or Responses API requests and classifies transport errors. A RunController owns stop and timeout semantics, and a ToolGateway enforces explicit grants, call budgets, result-size limits, and abort propagation before any client-executed tool runs. Provider-hosted Responses tools execute on the provider side and return source annotations through the protocol adapter.
Tools are registered as a definition plus an async executor. Executors return model-visible text and optional internal artifacts; for example, the WebSearch and FetchURL tools return source records as artifacts, which the reading view turns into its source list. The runtime itself does not contain web-search, note, or knowledge-base logic.
Temporary sessions are stored separately from plugin settings with count, age, and byte limits. Older conversation turns are compacted once into a deterministic role-labelled continuity block when they exceed the current context budget. Scoped retrieval separates evidence identity, historical questions provide continuity without old AI answers, and confirmed learning preferences affect explanation style only. See the staged Agent development plan for scope, acceptance criteria, and deliberately deferred work.
The default template records the time, source note, heading, line range, question, and confirmed answer excerpt. Available variables:
{{timestamp}}, {{date}}, {{sourceLink}}, {{sourceFile}}, {{sourceHeading}}, {{sourceLabel}}, {{lineRange}}, {{question}}, {{answer}}, {{questionQuote}}, and {{answerQuote}}.
When you send a question, the plugin sends the selected passage, your question, the current conversation history, the configured system prompt, and any images you explicitly selected to the configured API endpoint.
When provider-hosted search is enabled, the configured Responses API host receives the conversation and performs its hosted search internally; the plugin receives the final response and source annotations. Otherwise, the current question or a model-generated query is sent to the separately configured search provider. In model-controlled mode, the plugin may also fetch a limited amount of text from relevant public HTTP or HTTPS pages; local and private-network page addresses are blocked. Search results and fetched pages are sent to the chat model as untrusted reference material. A web source is written to the Vault only after you review and confirm its visible save form.
When local retrieval is enabled for a conversation, the plugin compares the question with cached metadata and a bounded in-memory body-term index inside the selected allowed folder, and may read a few matching note passages. Those passages, their Obsidian links, identity labels, related historical questions, and confirmed learning preferences may be sent to the configured chat model. No whole-vault index or vector database is built. Selected answer text first stays in the temporary editable draft; only the draft you explicitly save is written to the Vault.
To recover interrupted work, the plugin stores bounded temporary-session data inside Obsidian's plugin data.json. It keeps at most 20 recent sessions for 30 days and caps the session section at 2 MB. It does not copy image binaries, store API keys, or treat these temporary conversations as user-confirmed knowledge. Clearing the conversation list removes the stored session list.
Learning-preference candidates and confirmations are stored in a separate bounded section of the same data.json. Operational counters use another bounded section that deliberately excludes user content, file paths, URLs, source excerpts, and credentials. The Local data and privacy section in plugin settings explains these limits and can clear all three local Agent-data sections without deleting model, search, or saving configurations. Versions that used sessions.json, learning-memory.json, and run-metrics.json migrate those files once and remove them after a successful migration.
The plugin contains no telemetry, advertising, or background analytics. The model API key is sent only to the configured model host, and the separate search key is sent only to the configured search endpoint. Only configure endpoints you trust.
Download main.js, manifest.json, and styles.css from a GitHub release and place them in:
<vault>/.obsidian/plugins/ai-reading-companion/
Restart Obsidian and enable AI Reading Companion under Community plugins.
npm install
npm run dev
npm run build
npm run lint
npm run verify
npm run verify checks lint rules, compiles the production bundle, and confirms that package, manifest, compatibility, and release-file versions agree.
minAppVersion in manifest.json if compatibility changed.npm version patch, npm version minor, or npm version major.v prefix).The release contains main.js, manifest.json, and styles.css, as required by Obsidian.
Apache License 2.0.