load_skill runs with the context the harness gives it, which has no
execution scope, so the status of the commands read as not selected and
the document skills were dropped. Make the descriptor and skill
resolution open a scope when the context has none, and report a scope-less
status read as a programming error: logged once in production, a failure
of the spec in tests.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The spec builds the turn tools under the product scope and then calls
load_skill with a context of its own, as the harness does. It fails
with the not_selected text on master.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The shared connector page reads the kind list. It shows the thread
context switch for a kind that can give a thread's messages, and a
select for each option that the kind declares. The spec names of the
contract suite are listed for the harness.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The option followThreads says which threads the bot follows without a new
mention: own (default) follows the threads that a top-level mention
started, any also follows a thread that other people started once the bot
is mentioned in it, never needs a mention each time. A mention inside a
thread that people started is answered and, in own mode, not followed.
The followed threads are kept in the add-on's data directory, written
atomically, and expire after a day without a message, so a restart or a
reconnect does not make the bot forget them.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
A kind can declare options with a few values and a default (manifest
api 2). The host checks the owner's choice against the declaration,
stores it on the binding, shows it in the REST API and sends the value in
effect with every poll. The add-on decides what the option means.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The Slack add-on declares history.thread (manifest api 2) and serves the
op history with conversations.replies. It pages through the thread, keeps
the newest messages, marks the bot's own, names the authors from a small
cache and gives file names only. A thread of more than 1000 messages is
refused instead of shown from its middle. The fake Slack serves
conversations.replies.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
A platform that implements HistoryReader answers the op history. The
route checks the thread, bounds the limit and the answer, and does not
wait out a rate limit.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
When a message in a thread makes a new chat, the host asks the add-on of
a kind that declares history for the earlier messages, once, and hands
them to the first turn as a delimited block of untrusted content. The
block is bounded in messages and bytes, keeps the newest, is flattened
and escaped, and is not kept in the transcript. A failure or a missing
ability leaves the turn as it was.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
A binding reads the earlier messages of a thread by default. The new
thread_context option turns that off, and the kind list says which kinds
can give a thread's messages. It is stored like send_files: the zero
value keeps the default.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
A connector kind can declare history.thread in its manifest (api 2) and
then serves the op history: the earlier messages of one thread, oldest
first, bounded by a limit. A kind that declares nothing is never asked.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The provider guard rejects a shipped add-on name in a string literal,
and the swagger example of the network title in the apps view named one.
Use a neutral example value.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The apps list reads capabilities.network from the receipt's manifest, and
no gateway call depends on it, as for the connector.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Describe capabilities.network for add-on authors: its fields, how the
host control attaches to it, that the chats_egress_* settings keep their
names and values, and how a manifest without the field keeps working.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The Network row of the chat Tools menu, the consent and blocked cards and
the network-policy block on an add-on's Settings tab take the network
title and the preset titles from the API (network, as the add-on
declares it) and no longer say "Sandbox". The setting labels are
neutral. A second add-on with another ID and title gets the same row,
card and block.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Fail when a file that builds the text of the command network, the
built-in bash or the host-exec setting writes the name of an add-on.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The manifest keeps asking for the network-policy control and the
egress.check operation, and now also declares capabilities.network with
the title the host uses in text. A test keeps the control working for a
manifest of the same shape that declares no network.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The chat's network view, the administrator view and the line the model
reads about the network of its commands now take their name from the
capabilities.network an add-on declares, or from the title of its
commands tool when it declares none. The sentences no longer say
"Sandbox" or "the sandbox". The API gains a network object with the
title and the preset titles next to the existing addon field.
The text of the built-in bash and of the host-exec setting names an
add-on that provides bash instead of one add-on.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
An app whose network-policy control the host draws now carries its
declared network: the kind, a title for text (the declared one, else the
add-on's own) and the preset titles. The control no longer needs a tool
that shadows bash when the add-on declares capabilities.network.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The network-policy host control was tied to a tool that shadows bash, so
it could only belong to an add-on that replaces that one tool. An add-on
now declares capabilities.network (kind egress-check, an optional title
and optional preset titles) and the host attaches the control to the
declaration. A manifest that declares nothing keeps the old attachment.
The field is additive and needs manifest api 2 and the egress.check host
operation.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The agent task form, the scheduling rule sheet and the add-on model
selector now draw the shared picker: a button that opens a listbox, with
a warm or cold tag inside each option name. Four specs still used the
old select, combobox and exact option names.
Task and rule specs open the picker button and choose from the list. The
rule spec types a custom name in the filter and takes it with Enter. The
diarization and 3D animation specs match options by their model name
prefix, as the other specs already do.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Read addons/*/manifest.json at run time and check every string of every
locale and every Settings label for the name of an add-on that shadows a
built-in tool or skill, serves as a connector or declares the execution
provider. The allow-list keeps a reason per key and fails when an entry no
longer matches.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The locale files and the Settings labels said "Sandbox" for the add-on that
runs commands. The strings now say "commands" or "an add-on that isolates
commands", in every shipped locale. The name of the serving add-on in the
network section and in a transcript step comes from its declared title in
the add-on list.
Remove the strings that no component reads (the Sandbox notice texts, the
Tools menu sandbox lines and the Home wizard step). Add the seven
execution-status reasons to the locales that lacked them and lower the
i18n baseline, which master was over by seven keys.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Read addons/*/manifest.json at run time and find the add-ons that shadow a
built-in tool or skill, serve as a connector or declare the execution
provider. One spec scans the string literals of core and pkg for their
names; another builds the command prompts and the network text for every
state and checks that none names a shipped provider. A short allow-list
holds the strings that name a platform or a token format as content.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The prompt, the Tools menu reasons, the network error texts, the CLI help,
the API instructions and the assistant tool descriptions said "Sandbox" for
the add-on that runs commands. Core must not know that name.
The reason a chat has no commands now uses the title the provider declares
("the Zeta add-on is off for this chat") or, when none is installed, says
"the add-on that runs commands". Text that has no provider in hand speaks of
the network of commands or of an add-on that isolates them.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The tool adapter no longer builds the listing for one add-on by id. It
reads capabilities.resources.list of any add-on, names the tool with
the add-on id and the declared name, and rejects a manifest that ships
a tool of that name. A second add-on with a different id now gets the
same tool through the same code path.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The apps list now holds the resource mapping of each manifest, so the
tool adapter can act on the listing declaration without knowing any
add-on. A manifest of API 1 written before the declaration existed
keeps its listing through one marked compatibility file, with a spec
that tells when to delete it.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The manifest now asks the host for the databases-list tool through
capabilities.resources.list and accepts manifest API 2, which the
declaration needs.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
An add-on that keeps resources can now ask the host for a read tool
that lists the ones the caller may use, by declaring
capabilities.resources.list. The declaration names the tool and,
optionally, the key of the result array. It needs manifest API 2 and
must not reuse the name of a tool the add-on declares.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Union of both case lists in the add-on suite inventory; the swagger
files are regenerated from the merged code.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Playwright specs with a stubbed API: confirm, edit then confirm, dismiss,
undo, expired, stale, a failed write, unknown kinds and sources, the inbox
count and row, the Proposals page, and the Memory tab with read, edit,
delete and clear all. The account spec lists the new tab.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The tab lists the context files that the host puts in the prompt (the
user's index and topics, each agent's and conversation's notes, and the
agent profiles) with their sizes against the caps. The owner can read,
edit, delete and clear them; an index over its cap cannot be saved.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
A propose_change tool line now draws a card in the thread, for any kind
and any source: the kind, file and scope, the source, the time left and a
line diff against the file as it is now. The owner can Confirm, edit the
text then confirm, or Dismiss. A confirmed change shows a receipt with
Undo. Expired and stale proposals say nothing was saved and offer to ask
the assistant again; a failed write leaves the proposal waiting.
The inbox button counts the waiting changes and its panel links to a new
Proposals page that lists them with the same card.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Pure helpers with node tests: a line diff with context, the state of a
proposal (including a pending one whose time ran out), the source and
scope wording inputs, and the size of a context index against its caps.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Document the optional body of the confirm route, the context-files route,
the card the thread draws for any kind and source, and the Memory tab. The
context-file listing is a person's own action, so the actor scan allows it.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The apps API spec checks that the generated docs match the emitted
fields, so it needs a descriptor in its full fixture.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Describe the descriptor for add-on authors: its fields, what the host
does with them, the API 2 requirement and the behavior of a manifest
that declares none. Add the new fields to the generated API docs.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The Sandbox add-on states in its manifest that its bash tool runs
commands, under which title, with which note for the model, and that it
supplies the runtime of the document skills. The manifest accepts API 1
to 2. A spec checks that the manifest matches the descriptor in code.
A guard spec fails when the studio package or the add-on tool adapter
compares a string with the ID of the Sandbox again, or when the files
that build the commands text name it.
The contracts suite inventory lists the new specs, and two specs of the
network-policy status that it was missing.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Document skills, the Commands block of the prompt and load_skill no
longer compare an add-on ID or provider with "sandbox". The host asks
whether the add-on that ships a skill serves the chat's commands and
whether the typed execution status reports them isolated. Skills that
need that are listed by the broker from the add-on's manifest, and the
text names the provider by the title its manifest declares.
An add-on whose commands tool declares no descriptor behaves as a
provider of commands under its own title and keeps the isolation check
for its document skills.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
A tool that shadows bash can now declare an execution descriptor: its
class, a title and a note for the model, and the skill kinds whose
runtime it supplies. The host reads it to build its text and to decide
which skills need isolated execution, instead of knowing add-on IDs.
The field is optional and needs manifest API 2. The host now speaks
API 2 and still accepts add-ons that declare only API 1, so manifests
that declare nothing new keep working unchanged.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The proposal card lets the owner correct the text before confirming.
POST /api/chats/changes/{id}/confirm now accepts an optional JSON body
{"content": "..."}. The text has the same size limit and text check as a
proposal, the file and the audit hash hold what was written, and a
refused text leaves the proposal waiting.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The Memory settings page needs to know which index and topic files the
host loads into the prompt. GET /api/chats/context-files walks the
registered context sources, expands the agent and channel folders that
exist, adds the agent profiles and reports each file with its size, the
line count of the index, and the caps. It only reads; the page edits and
deletes through the Files API.
Assisted-by: Claude Code:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>