Releases: mrrepac/ai-assist
Release list
1.0.0
One point zero. Nothing new to press — this release is about what holds the plugin up.
What 1.0 means here
Two promises, and both of them are about not losing your work.
The data files will not break. data.json (settings, and the API keys of every
provider in them) and history.json (your conversations) carry a schemaVersion, and the
format is written down in docs/data-format.md. A file from a newer version of the plugin is
recognised as such instead of being overwritten; a file that will not parse is copied aside
under a timestamped name and you are told where it went, rather than being silently replaced
with defaults.
The paths that spend your money are covered by tests. 510 of them, up from 455 in the
previous release and 385 five releases ago. What used to be checked by hand is now checked on
every build.
What changed under the hood
Nothing you press behaves differently. The panel's submit() — the method that sends a
question — was 339 lines holding four separate concerns, and seven of the nine defects fixed
across the last five releases lived inside it. Two of those concerns moved out:
-
request.tsdecides what travels to the model. Which fragment and which attachments go
with the question; whether the note is included; whether the model may use tools; what is
cleared from the chip afterwards; how the system prompt is assembled; which past messages
fit the context budget and whose pictures go with them. Every one of those decisions has
been wrong at least once, and none of them could be checked without launching Obsidian.
Now they are a function with fifty-three tests. -
turn.tsdecides whose feed this is. While the model answers, the feed can be taken out
from under the reply — by clearing the chat, by starting a new conversation, by the undo
notice, by removing the question itself. A reply appended after any of those lands in the
middle of someone else's conversation, in the feed and in the context of the next request.
That rule was written in three places in three different ways, and in a fourth it was simply
forgotten. Now there is one of it.
The behaviour is unchanged on purpose: the old method was compared to the new one rule by
rule, and the tool loop, the streaming and the error handling were not touched at all.
Two differences worth naming
Both are invisible in use, but they are differences:
- The active note is now read on every turn, and the plan decides whether it travels — where
before it was not read at all in a private chat. It is a read with no side effects. - If the pictures of the current question and those of an earlier message both go missing at
once, the two notices about it now appear in the opposite order.
Where it stands
Desktop and mobile, isDesktopOnly: false. Providers reachable from Russia without a VPN:
DeepSeek, Polza.ai, ChadGPT, GPTunnel, Perplexity, and local models through Ollama or
LM Studio. Images, PDFs and documents travel with a question; the selected text is rewritten
in place, with the edit log and an undo button; the conversation saves to a note.
Still unproven: the mobile pass over attachments — pasting a picture from the clipboard and
the file dialog have not been exercised on a phone since they arrived in 0.7.0.
0.10.0
A version number for the data files, a panel that starts clean, and settings that survive the trip between machines.
What changed in how it behaves
Two defaults are different from 0.9.0. Both can be turned off in the settings.
A run from a note starts a new conversation. Every path counts: the quick menu, a one-off
prompt, "ask about the selection", and — new in this release — an action that rewrites the text
in place. The panel is cleared first, so the card you are waiting for is the only thing on
screen, and the conversation before it is not paid for again on the next question. The cleared
conversation comes back if you click the notice, which stands for eight seconds.
The edit log is cleared along with it. The cards used to survive because each one carries an
"Undo edit" button. But the text is rewritten in the note itself, and Ctrl+Z was never taken
away. If you want the button within reach anyway, turn on Keep the edit log — it sits under
the toggle above and appears only when there is a clearing to be kept from.
The data files have a version now
data.json and history.json carry a schemaVersion, and the format they describe is written
down in docs/data-format.md. Nothing about this is visible in use; it matters because after
1.0 these files may not be broken, and until now there was no number to check.
Four outcomes are told apart when a file is read: absent, current, written by a newer version of
the plugin, and unreadable. The interesting one is the last.
A settings file that will not parse is copied aside, not silently replaced. Obsidian's own
loadData() returns nothing both when the file is missing and when it is corrupt, and the
plugin used to treat the two the same — which means a stray byte in data.json cost you every
API key you had entered, without a word. The broken file is now copied next to the original
under a free name with a timestamp, and you are told where it went. The chat log gets the same
treatment, quietly: there are no keys in it.
Settings arriving from the other machine are no longer trampled
If your vault syncs, data.json written on another machine used to be overwritten by whatever
this machine happened to hold — and since a draft in the input field is saved as you type, the
overwriting was armed on every keystroke. The plugin now notices the file changing underneath it
and re-reads the settings.
Only the settings: re-reading everything would throw away a live conversation. And only when the
file parses — a file that arrives broken, or vanishes mid-read, leaves what you have alone.
Worth knowing: Obsidian Sync carries manifest.json, main.js, styles.css and data.json,
and nothing else. history.json — your conversations — stays on the machine that wrote it.
Under the hood
455 checks, up from 412. Reading and writing the two files moved into store.ts, which imports
nothing from Obsidian, so the tests can drive it directly against deliberately damaged files.
The rules for what survives a clearing and what a restore keeps live in history.ts for the same
reason.
One race is fixed along the way: the undo notice lives for eight seconds — exactly as long as the
model spends rewriting — and clicking it used to swap the whole feed for the snapshot, carrying
off the card of the edit in flight along with its undo button, while the note had already been
rewritten. The restore now merges the snapshot with whatever arrived after it.
0.9.0
LM Studio, a refusal that finally explains itself, and eight quiet defects.
LM Studio is back in the list
The preset was dropped in August after a symptom that looked like the server's fault: the
model list arrived, the question got no answer. Measured against a running instance, neither
half turned out to be mysterious.
The list travels through requestUrl, which goes around the browser, so it works. The stream
travels through fetch — and LM Studio sends no Access-Control-Allow-Origin at all, while
the preflight on /chat/completions answers 400. The POST never leaves the building. Ollama,
for contrast, echoes app://obsidian.md back, which is exactly why it streams.
So LM Studio returns with no stream, the same way ChadGPT has always worked: the answer is
fetched whole, and the streaming toggle hides itself rather than sitting there pretending. CORS
is a switch in LM Studio's own server settings, but it is off by default — and a setting that
only works after a trip into someone else's settings is not a default.
No key is asked for: the address is already recognised as local. An address that has been
sitting in your settings as "another one" becomes the preset on its own, model and all.
A refusal now says what went wrong
An OpenAI-shaped error carries its explanation in error.message, and that was the only shape
the plugin knew how to read. Plenty of servers answer with a bare string instead — LM Studio
uses the first shape for "no such model" and the second for everything else:
{"error":"The number of tokens to keep from the initial prompt is greater than the context
length (n_keep: 8637 >= n_ctx: 8192). Try to load the model with a larger context length,
or provide a shorter input."}
Every word of that used to be thrown away, and what reached you was "the provider rejected the
request", full stop. Both shapes are read now.
Where the complaint is about the context window, a line is added in your own language. This
one is worth knowing: a local model is loaded with the context it was given at load time, not
the one it is capable of — a model advertising 262 144 tokens is routinely holding 8 192, and
a note sent as context will not fit.
Two spaces at the end of a line
Every rewriting action carries a paragraph asking the model to leave the markup alone. It
listed markdown symbols, indentation, code blocks and wiki-links — and said nothing about the
one thing models actually destroy: the two trailing spaces that make a hard break. That is
what goes first, and a couplet comes back as a paragraph.
The paragraph now names the mechanism instead of assuming it. What went the other way was a
matter of taste: the old wording also declared a missing full stop or a lower-case letter
opening a line to be the author's device rather than a mistake. Not everyone writes that way
on purpose, and the models that ignore instructions ignored it anyway.
Eight quiet defects
Found by reading the whole plugin again after 0.8.0.
- Asking again, or retrying after an error, silently cleared the attachment chip. A picture
attached for the next question vanished without a word — and stayed in session memory for
good, since it never reached the feed and nothing was left to forget it. - Closing the panel lost the attachments. The data outlived the list naming it, which comes
to the same thing as not keeping it. - The copy button under an answer had nothing to catch. When the clipboard refused, nothing
appeared at all: the notice stands after the await and was never reached. - A rewrite that ran into the model's length limit threw away what it had cost. The first
pass is the expensive one, and continuing billed only for the second. Both are added now, and
the price appears straight away — it has been paid whether or not the answer is finished. - A single-page PDF longer than the limit travels whole, but was announced as a beginning —
on the chip and to the model, which would then decline to judge an "incomplete" text. - A document that did not survive a restart called itself an image.
- A saved conversation was signed with the model from the settings header, even when a
private chat or a one-off "ask again" had answered it. - Dragging promised more than it did. The frame lit up for any text while the drop handler
knew only pictures and PDFs. A note now lands on the chip as a fragment, and plain text lands
in the question field at the caret.
Under the hood
412 checks, up from 385. describeError is exported to the tests — there was no way to reach
it before, which is precisely why the refusal text went missing for so long.
0.8.0
A PDF in the question — read where the text already is.
A document is attached the same ways a picture is: the paperclip, dragged into the panel,
"from the vault", or an ![[embed]] in the open note. What travels, though, is not the file
but its text — the layer already inside the PDF.
Why that is the interesting part
Text works with every provider. Including DeepSeek, which takes no images at all — so the
model most of these questions were going to anyway can now be asked about a document. The
"this model does not take images" warning does not fire for documents, because there is
nothing to warn about.
Nothing is recognised here, either. What is written in the file is what goes; the plugin only
reads it.
What the chip says before you send
методичка.pdf · 12 pp. · 34 000 chars. The characters are the price of the question, and
they are on screen before the question leaves rather than in the bill afterwards.
A document longer than the limit is sent from the beginning, and the chip says so — (the beginning only). The cut falls on a page boundary, never mid-sentence: a page broken in half
reads as a failure to read the file, not as a deliberate trim. The limit is the same 40 000
characters the note-as-context has had all along.
Documents follow the same rule as pictures in a conversation: only the freshest one travels
into a new request, and about the others the model is told in words. A document is not copied
into the vault — the setting promises to keep images, and it is right to: a screenshot in a
chat is worth seeing again, a twenty-megabyte document in the attachments folder is litter.
So a PDF from disk lives until the next restart, and a PDF from the vault is read by its path
and outlives everything.
A scan says so itself
A photograph of a page has no text in it at all. The plugin says exactly that when the file
is attached — "there is no text layer in this PDF, only pictures of the pages" — rather than
sending an empty question and letting the answer explain what went wrong. Pulling text out of
a picture is a different job, and this release does not pretend to do it.
No new weight
Obsidian already ships pdf.js — its own PDF viewer runs on it — and it turns out to be
reachable: the global it installs is made read-only rather than taken away. It loads lazily,
so when nothing has opened a PDF yet the plugin loads it exactly the way Obsidian does.
Half a megabyte of library and a megabyte and a half of worker that would otherwise have been
carried a second time, for a file already sitting next door. The plugin grew by five
kilobytes.
0.7.0
A picture in the question: screenshots, files and images from the vault.
Some questions are about something you can only point at — a screenshot of an error, a photo
of a page, a diagram sitting in a note. Until now the chat could only be told about them in
words.
Four ways in
- From the clipboard. Take a screenshot, press
Ctrl+Vin the input field, ask. The
detour through "save the file, find the file, attach the file" is gone entirely. A pasted
image has no name of its own, so it is given one the way Obsidian names them: what it is,
plus a timestamp. - Dragged into the panel. A file from the desktop, or a note from Obsidian's own file
explorer — the panel takes both. While something is being dragged over it, it says what it
will do with it. - The paperclip in the footer. The ordinary file dialog. It is a
labelwith aninput
inside rather than a button, because a file dialog opened from code does not appear while
no note is open in Obsidian — which is exactly when the chat gets opened. - Right-click on the paperclip — or the
…menu, which is the way to it on a phone:
from the vault, any image in it, searchable by name and folder; and from this note,
by the images embedded in the note you have open. That last one matters more than it
sounds: a note goes to the model as text, and![[diagram.png]]is a line of text to it,
not a picture.
Up to four pictures per question. Not a limit the provider imposes — the limit is the bill.
The bill is what shapes the rest
A picture is scaled down to 1200 px before it leaves. A phone photo at full size is megabytes
of base64 and a visible line on the bill, while what can be read on it is exactly the same.
PNG is kept when it weighs no more than half again over JPEG: what is usually attached is a
screenshot, and what has to stay legible on it is letters. Transparency gets white put under
it — in JPEG it would otherwise go black, and nothing is visible on black.
The weight of each picture is shown on its chip, because that is the price of the
question.
Pictures from earlier replies are not carried into a new request. Each one is paid for on
every question, and a conversation that began with a photo would otherwise haul it along to
the end. Only the most recent picture in the conversation goes; about the others the model is
told, in words, that there was one — without that the conversation reads as questions about
nothing.
A provider known to be blind to images says so before you send. DeepSeek takes no images
in any of its models, and the chip bar says it outright, with the button that fixes it right
there in the warning. For everyone else it cannot be known in advance — with the aggregators
it depends on the model chosen — so a refusal from the provider now comes with a plain-spoken
hint instead of a bare "the request was rejected".
Where the picture lives
With "Keep images brought into the chat" switched on, the picture lands in the vault's
attachment folder — the same one Obsidian itself uses when you paste into a note, wherever
you have pointed that setting. It goes there as the question is sent, never before: a
picture attached and then taken back leaves nothing behind at all.
With the setting off it lives until the next restart and never touches the disk.
A private chat writes nothing either way, and says so when a picture is attached rather
than leaving you to find out later.
Pictures survive the panel being closed, sit above the question in the feed, and are opened
by a click when they are files in the vault. Editing a question brings its pictures back to
the chip bar with it; asking again sends the same ones. Saving the conversation into a note
writes a vault picture out as a link — and one that only lived in memory as a note saying so,
rather than as a link to a file that does not exist.
Things that were quietly going wrong
Found while going over the new code, and over the rest of the plugin after it:
- Retry after an error sent the question without its pictures — and, if new ones had been
attached while the error sat on screen, with somebody else's instead. The same fault the
attached fragment had in 0.6.0, in the same place. - The "does not take images" warning did not go away when the model was switched — not
even by the button inside the warning itself, which exists for nothing else. Switching to
a blind model went unannounced in the same way. - Pictures stayed in memory for the whole session, including after the conversation they
belonged to had been cleared, where nothing could reach them any more. Ones that are in the
vault are now released as the conversation goes; the disk brings them back. - A dropped file that was not an image did nothing at all — no picture, no message, which
reads as a broken plugin rather than as "not that kind of file". - A failed save went unmentioned. The setting promised the vault; if it did not work out,
you would have found out after a restart, when the question could no longer be repeated. - Finishing a cut-off answer said nothing about the picture the question had been about,
so the model carried on writing while pointing at nothing. - Editing a question overwrote pictures already on the chip bar without a word.
0.6.1
The description in the catalogue, which had gone stale.
No code changes: an installed 0.6.0 behaves exactly the same, and there is nothing
to gain by updating except the entry in the plugin list looking right.
The catalogue builds its entry from the manifest at the moment a release is
published, so the text there was still the one from 0.1.0 — and it advertised two
things that no longer exist: tidying up spacing, which was cut in 0.1.2, and
cleaning up transcripts, which went in 0.3.0. It also listed the providers without
Perplexity, which became a preset in 0.6.0.
0.6.0
A provider that reads the web before answering, an action that picks its own model, and a
cut-off answer you can ask to finish.
Perplexity
A new preset — and less a model than a search engine with a model on top. It reads the web
first and answers from what it found, attaching the pages it used. You reach for it for
facts, names and dates: the things an ordinary model does not know and invents with perfect
confidence.
Three of its quirks are handled so they do not look like breakage:
- It publishes no list of models. "Fetch the list" would have hit a 404 captioned "no
such model at this address" — a lie twice over. The four Sonar models are built in, and the
button shows them without a request. The field is still free text, so a new name can be
typed in without waiting for a plugin update. - It has no editing tools. Function calling is not something it does; a request carrying
tools comes back as a 400 on every question. The plugin no longer sends them, and the
settings say so under the toggle rather than leaving you to guess. - Picking it fills in the model.
sonaris set straight away — there is nothing to
guess at and nothing to look up.
Sources under the answer
The point of a search model is that its answer can be checked. The links it was built on now
sit under the answer, collapsed — there can be a dozen, and they get opened only when the
answer is doubted. They are stored with the answer, so they survive a restart of Obsidian.
The numbers are taken out of the text. A search model cites as it writes — "born in
Moscow[1][6][8]" — and in a long answer those tails sit after every sentence and get in the
way of reading, while telling you nothing on their own. They are stripped; the list below is
what they pointed at anyway. Code blocks and [[wiki links]] are left alone, and a number
the model cites without sending us the source is left alone too — in someone's own text
[1] is just a number in brackets.
A source keeps the number the provider gave it. A repeated page is shown once and a non-web
address is not shown at all, but neither renumbers the rest.
Saving the conversation to a note keeps the sources: the list is written out after the
answer.
An action can have its own model
Proofreading is done no worse by the cheapest model there is; judging a text without a strong
one is pointless; and facts have to be looked up where there is a web. Until now every action
went to whatever stood in the panel header, so getting this right meant switching the header
before each keystroke — and forgetting to, sooner or later.
An action now carries a provider of its own: pick one in the action's own window, and it
always goes there. Leave it on "the one in the panel" and nothing changes. Only providers you
have already configured are offered — an action that cannot run is not worth creating. If the
chosen one loses its model later, the action says so and refuses to run: quietly falling back
to the header would mean an action created to search the web answering out of its head.
A private chat can have its own model
A private chat is started to ask something that is not about the vault at all — and the model
wanted there is usually a different one: cheaper, or simply not the one you keep your work
with. Until now it answered with whatever stood in the header, so getting this right meant
switching on the way in and switching back on the way out — and forgetting on the way out.
There is now a setting for it. Pick a provider and every private chat goes to it; the panel
header names whoever is actually answering, so there is nothing to remember. Picking a model
in the header while in a private chat changes that same setting rather than the panel one —
leave the private chat and everything is where you left it.
The choice does not touch privacy either way: what makes a private chat private is that
nothing from the vault is sent, and that holds whichever model answers.
A cut-off answer can be finished
The model runs out of room and stops mid-word. Until now that was the end of the run: the
half you had paid for stayed in the card, and the only way on was to copy it by hand or ask
again from the beginning — paying for the same text twice.
There is now a Finish it button. It sends the answer back as the model's own words and
asks it to carry on from the exact character it stopped at, then joins the two halves.
- In the chat the continuation is glued into the same answer, not added as a second
reply — otherwise a long text, which is the whole reason this exists, would have to be
copied in pieces and stitched together. The token count for the answer adds up across both
halves. - For an edit over a selection the joined text is applied to the note as a normal edit,
with its diff and its Undo. If the model runs out of room a second time, the button is
simply there again.
The beginning of an interrupted edit lives in memory until Obsidian restarts, so after a
restart the button is gone rather than promising something it cannot do.
Things that were quietly going wrong
- Retry after an error no longer drops the attached fragment. Attach a piece of a note,
ask about it, lose the network, press Retry — and the question went off without the
fragment, silently. The panel clears the attachment when the question leaves, and the retry
had nothing left to pick up. - Retry no longer cuts into a different conversation. If the chat was cleared while the
error was still on screen, the retry trimmed the feed by a position that now pointed into
whatever had replaced it. - Two edits can no longer start at once. The "that is a lot of text" question is a modal;
while it waited, a second edit passed the busy check, and the two overwrote each other's
handle — so Stop only ever reached the last one.
0.5.0
A chat that leaves the vault alone when you ask it to, a model that stopped rummaging in
your note uninvited, and the price of a question written on the button.
A private chat
Like a private window in a browser: a separate conversation where nothing leaves the
vault at all — no note, no selected fragment, no editing tools, no system prompt, not even
your own one from the settings. Just the model, the way it answers on the provider's own
site.
Start it from the … menu in the panel header, from the command palette, or with Alt+2 if
you let the plugin take the keys. The header is tinted while you are in it, and in place of
the "note as context" button sits an unplugged cord — there is nothing to switch on. A
normal "New chat" brings everything back.
It is a property of the conversation, not a setting: nothing to leave switched on by
accident and forget about. A fragment selected in a note is never picked up there, however
it got selected — and the plugin says so out loud rather than quietly sending it.
The model stopped rummaging in your note
Asked to invent a joke about cheese, the model would first go and read whatever note you had
open. It cost a whole extra round trip — 5 600 tokens in instead of 1 100 — for a question
that had nothing to do with the note. The system prompt only ever explained how to edit
a note and never said when not to reach for it.
Now the model is told whether it can see the note at all: with the note attached it is asked
not to read it a second time, and without it — not to go looking just in case. Most
questions are answered with words, and it is told that too.
The card for a read no longer says "Applied" in green either. Nothing was applied — the note
did not change.
What a question costs
- The context button now carries a number. With it on, the open note goes to the model
with every question; the button looked exactly the same for a one-line note and for a
twelve-thousand-character script. Hover it for the exact figures — the note and the
conversation separately. - The running total for the conversation sits under the input field. Each answer already
showed its own cost; nobody was adding ten of them up by hand. Edits made over a selection
count towards it too — they are paid for the same way.
Ask again — with a different model
"Ask again" used to re-run the same question through the same model that had just
disappointed you. It now opens a menu: the same one first, then every provider you have
configured. The choice is for that one run — the plugin does not switch over, so your next
question goes where it was going before.
The journal of edits gained the same menu, and its cards are now signed with the model that
did the work — otherwise there is no telling which one came out better.
Where new notes go
A saved conversation, and anything the model creates on its own, used to land in the vault
root. There is now a choice in the settings: the root, one folder of your own, or next to
the note you are working on. A folder is created if it is not there yet — matched
case-insensitively, one step at a time, so archive/ai cannot quietly become a second
Archive.
Things that were quietly going wrong
- An answer that arrived only as reasoning is no longer thrown away. Some models — and
some providers — put the whole text in the reasoning field and leave the answer empty. The
panel said "the model returned an empty answer" and dropped everything, including the
tokens you had paid for. The reasoning now becomes the answer, and the chat says as much. - A stopped stream no longer lands in the middle of the next question. Pressing Stop
returns whatever arrived as a normal answer, not an error, so the panel filed it away
without checking whose turn it was. Ask something new before the previous answer finishes
and the leftovers used to appear underneath your new question. - An edit card no longer claims success when the edit failed. A fragment that was not
found, a note that had been closed, a tool the model invented — all of it was marked
"Applied", and the model was then told in the conversation that the work was done. - The down arrow in the quick menu no longer wipes what you typed. In a three-line field
it is how you move to the next line; instead it replaced the prompt with nothing, with no
way back. - A malformed action in
data.jsonno longer stops the plugin from loading. An action
missing its name took the whole load down with it — settings and conversation included —
which is precisely what the merge routine exists to prevent. - A provider answering with something that is not JSON now says so instead of showing a
bareSyntaxError. Proxies and portals hand back an HTML page with a 200 more often than
one would think.
0.4.0
Two days of quality-of-life work — and a handful of things that could quietly eat your
text.
Changed on purpose: Enter in the quick menu
A one-off instruction typed into the quick menu used to rewrite the selected text on
Enter and answer in the chat on Ctrl+Enter. They are the other way round now: Enter
answers in the chat, Ctrl+Enter rewrites the text. "Summarise this chapter", typed in a
hurry, used to replace the chapter with its summary — and Enter is a key people press
without looking. The destructive one should cost an extra finger.
Working without selecting anything
- The section under the cursor joins the whole note and the paragraph as an answer to
"what if nothing is selected". It runs from the heading above the cursor down to the next
one of the same level, subsections included — exactly what folds when you collapse that
heading. The heading goes to the model together with the text, so it knows what the text
is about; the blank lines and the---before the next section stay behind. - The quick menu shows what it took: a row of paragraph / section / note with the size
of each, the one from your settings picked, and the piece itself highlighted in the note.
The arrow keys change it for that one run, and your setting stays as it was. An empty
line no longer means "select something first" either — the menu opens with the section. - A question before sending a lot. Past a threshold you set — 20 000 characters by
default — a long piece goes to the model only after you say yes. 0 never asks.
Right-click on the selection
The editor's context menu now offers the quick menu and a question to the chat — and the
actions from your keys, each on its own line, if you switch that on in the quick-menu
settings. On a phone it is the same menu, held down. With nothing selected the plugin adds
nothing to it: a stray click should not rewrite a whole note.
The conversation is yours to edit
- "Ask again" under an answer drops it along with the question and sends the question
again, exactly as it was — down to the system prompt, if it came from an action. - The pencil under your own question puts the text back into the field, with the
fragment it was about, and takes the rest of the conversation off. - The bin removes a message; a question leaves together with the answers to it.
Anything removed comes back from the notice, the same way a cleared chat does. - The input field remembers. An unfinished question survives closing the panel and
restarting Obsidian, and the up arrow walks through your previous questions. - Every answer is signed with the model that wrote it. Models are switched from the
panel header, and afterwards there was no telling who said what. - A saved conversation is named after its first question, not by the date alone.
Run it again
The journal of edits got a second button. "Run it again" brings the text back and runs the
same action over it once more: the old card becomes "undone", the new edit lands below. An
answer from a model is a roll of the dice, and rerolling it used to mean Ctrl+Z by hand
plus finding the action again.
Things that were happening to your note
- An action that answers in the panel no longer gets the editing tools. "Show it in the
panel" already says "leave the note alone" — but the model had the tools anyway, and
"summarise this chapter" could end with the summary lying where the chapter was. - …and it no longer drags the open note along. "Send the current note as context" is
about a conversation in the panel; an action over a selection has already said what to
work on. The model was seeing the same text twice and taking one of the copies for a
duplicate. - An action no longer picks up the fragment attached in the panel. A paragraph went as
the question, and a whole chapter went with it — attached earlier, and paid for again. - "Apply" on an edit card no longer takes the keyboard focus. The card appears by
itself, in the middle of an answer, and Enter at that moment — the Enter just pressed to
send the question — meant "yes, rewrite my note". - A cut-off answer never goes into the note. When the model runs out of room and stops
mid-sentence, the reply is not written over your text: it stays in the card, and the chat
says what happened. The provider says so infinish_reason, which the plugin had never
read.
Gone
- Thinking mode. The switch asked for reasoning but could not forbid it: a model that
reasons by default kept reasoning with the switch off. A setting that does not do what
its name says is worse than no setting at all. - Translation language. It fed
{lang}to prompts, and the action that used it was
removed two versions ago.
0.3.1
An audit of the whole plugin, and the fixes it turned up. Nothing new to learn — the
things below either did not work or were not true.
Fixes
- The note button in the panel header saves what you press. It wrote to the chat
history file instead of the settings, so "send the current note as context" was back to
off by the next start. Alt+1is no longer promised out of the box. It has not been claimed automatically
since 0.1.3 — a plugin should not take a key on someone else's keyboard — but the README
and the quick-menu description still said it would. The switch that gives the menu its
key is right there in the quick-menu settings.- An empty address is a refusal, not DeepSeek. Picking "Custom" and pressing "Test
connection" before typing anything used to send your key to a provider you did not
choose. - A full URL pasted from the documentation works. A trailing
/chat/completionsis
dropped before the method is appended, so the model list no longer asks the provider for
.../chat/completions/models. - An answer cut short by a new question stays on screen but out of the conversation.
Filed at the end, it used to sit after the question that interrupted it — in the feed
and in the context of the next request, in that order. - A word-level diff costs a third of the memory it did, and a pair of very long texts
is counted rather than drawn. - Smaller: the chat history is never written to the vault root; a tool name that a
provider repeats in full in every chunk is not glued to itself; an edit is undone in the
note itself rather than in a tab that only looks like one; a failed request without
streaming no longer surfaces as an error in the console.
Said out loud
A model allowed to edit notes can read the open note by itself, whether or not "Send the
current note as context" is on. Every call it makes is shown in the panel as a card — and
now the setting and the README say so too, instead of leaving two switches that look like
one promise.