The seam the Assistant rail talks to, and an honest default that does not pretend to be an AI.
The rail's UI is real: the conversation, the scope bound to the live selection, and per-message
Restore wired to genuine EditorSession history entries. What is stubbed is only the part
that would need a model — and Echo says so in its reply rather than fabricating an edit. A
suggestion the editor cannot actually make must not look like one it made.
config :mishka_cms_builder, :ai_backend, MyApp.RealAssistantA real backend returns the same message/0, optionally carrying ops — validated
MishkaCmsCore.Runtime.Authoring.Op structs the session applies through the ordinary funnel, so
an AI edit is undoable, containment-checked and plugin-visible exactly like a human one.
Summary
Functions
The configured backend.
One line about the configured backend, for the rail's Advanced settings panel.
Asks the configured backend for a change, scoped to the current selection.
Whether a real backend is configured.
A user's own message, for appending to the transcript before the backend answers.
Types
Callbacks
Functions
@spec adapter() :: module()
The configured backend.
@spec adapter_note() :: String.t()
One line about the configured backend, for the rail's Advanced settings panel.
Asks the configured backend for a change, scoped to the current selection.
opts names the document being edited — :token, :section, :resource_id, :site_id — so a
backend that would rather write its own ops than return them has the handle
MishkaCmsBuilder.EditorSession is addressed by.
@spec connected?() :: boolean()
Whether a real backend is configured.
The rail says so plainly either way. Claiming "Connected" while the default Echo is answering would make its honest "no model is configured" reply read as a malfunction instead of the truth.
A user's own message, for appending to the transcript before the backend answers.