The Retry button of the failure card called regenerate, which cut the
transcript back to the user's message and ran it again. Every message,
tool call and result the failed run had produced was lost, on the
server and on the page.
Add POST /api/chats/{id}/resume. It starts a turn from the transcript
as it is: nothing is removed, the model keeps its own saved state (so
finished tool calls are not repeated and a compaction summary stays),
messages that waited are delivered first, and the model gets a note to
go on instead of the question again. It does nothing when the chat is
not at a failed turn or a turn runs, so a double click starts one run.
The reason of a failure is now kept as a transcript line, so a reload
shows the same card text as the live page. The card stands after the
kept messages.
Assisted-by: Claude:claude-sonnet-5-5
A gateway spec for the enumerating tool was missing from the case
inventories of the gateway and artifacts suites, so the exact-match gate
failed on master.
Assisted-by: Claude:claude-sonnet-5-5
The face, voice, fine-tuning and quantization add-ons moved their English
strings from en.js modules to JSON bundles, and the memory add-on has one
too, so the copy test failed to import the old modules. Read the JSON
bundles instead. The allow-list keys and checks are unchanged.
Assisted-by: Claude:claude-sonnet-5-5
The warning block set a raw 4px radius as the fallback of a token that does
not exist, which raised the count of raw border radii above the baseline.
Use the existing --radius-sm token.
Assisted-by: Claude:claude-sonnet-5-5
Each Telegram binding keeps one long poll (up to 25 s) in flight, and
every poll took one of the 4 call slots of the add-on client. Five
bindings left no slot for the other calls (test, send, typing, me,
media, tool calls), which failed with "not sent", and the extra bindings
never polled.
Polls now count against a separate pool of 64 per add-on client. The
limit of the short calls stays at Concurrency. Both pools stop at
withdraw, and drain waits for polls as well.
Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
The index was not regenerated after the PiKVM approval setting and the
GitHub tool changes, so the generator output and the committed file
differed and the packaging test failed. Regenerate it with catalog.sh and
update the expected GitHub tool count in the test.
Assisted-by: Claude:claude-sonnet-5-5
Four specs of the enumerating tool were missing from the case inventory
of the contracts suite, so the exact-match gate failed on master.
Assisted-by: Claude:claude-sonnet-5-5
power-action and send-key are now approvalOverridable. The add-on page
has an "Ask before acting" section with Ask each time (default) or
Don't ask for each of them, with a plain warning that a chat can then
switch the machine off at once. type-text has no such choice and always
asks. The connection row lists which tools run without asking. The
page strings are translated to Italian and the shared connector pages
show the same list in the access view and the access preview.
Assisted-by: Claude:claude-sonnet-5-5
A write tool with approval "always" always waits for a person. A tool can
now also declare approvalOverridable, and the owner can then choose not to
be asked for that one tool, with a user setting approval-<tool> (ask or
skip, default ask). It is the only way to relax the ceiling.
The host honors the setting only for the owner's own chat and for a
messaging chat whose senders are all paired with the bot. Allowlisted
but unpaired senders, anyone-mode senders, roles, triggers, jobs, pages,
sub-agents and calls without a chat still wait for a person. The setting
is read again at the apply. Every run without a card is logged with the
tool, the connection and the outcome, never the arguments, and is added
to the latest decisions of the connection. The access view and the
access preview list the relaxable tools and who they run for.
Assisted-by: Claude:claude-sonnet-5-5
The previous change held the agent profile back with the owner's
personal notes. The profile holds the standing rules of the agent, like
its instructions, so every sender must get it. Only the user and agent
notes stay for the owner and paired senders.
The table spec now expects the profile for every kind of sender, and
for a turn with no known sender, so it fails if the profile is gated
again. The docs no longer list the profile among the gated notes.
Assisted-by: Claude:claude-sonnet-5-5
The GitHub add-on refused classic tokens in the page only, and its
repository list took exact owner/name entries.
A classic token (ghp_) is now an explicit choice of the connection. The
kind declares a token guard: the host refuses a token with that prefix
unless the connection sets the option classicToken to allow, and the
request that turns it on must carry confirm_wider_token. It is checked
when the token is saved and again each time it is used, so switching
the option off stops a stored token. The list and the write mode still
apply. The page shows a warning and two ticks.
The list takes owner/* and *. The host matches them before the add-on
runs, without regard to case and on whole names, so other-owner/x and
owner-evil/x are not covered by acme/*, and a key that holds a star is
never a name. A kind opts in with wildcardResources; only GitHub does,
so the other add-ons keep exact matching. Saving * needs
confirm_any_resource, and the write mode stays separate. A read tool
that declares enumerates (the new list-repos) runs only for a list of *
and asks GitHub which repositories the token reaches.
Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Creating a binding with no agent (home-assistant, jellyfin, pikvm,
github) failed with a 500. The token check for a new binding looked up
the agent even when the binding had none, so the host refused it. The
check now looks up an agent only when the binding has one. The token is
still required and a foreign agent is still refused.
A host denial (connectors.ErrForbidden) reached the client as a 500
server_error. The connector endpoints now answer 403 with a fixed text
that names no part of the check.
A person could have 10 bindings. Several bots plus one credential
binding per service need more, so the limit is now 50, like the limit
of resources and triggers. The docs and the API description say so.
Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Writes to the user and agent notes already needed a paired sender, but
the turn start read them for every sender. An allowlisted sender who was
not paired, or anyone in an open channel, got the owner's notes and the
agent's notes in the prompt, in context_read, and in the scopes asked
from an add-on that serves the notes.
A messaging chat now reads the user and agent notes and the agent
profile only when the sender is paired. The notes of the conversation
stay for everyone. A turn with no known sender counts as unpaired. The
access view and its preview get a notes.read entry per kind of sender
that is refused with the existing sender_needs_pairing code and its
plain text.
Assisted-by: Claude:claude-sonnet-5-5
These five pages kept their English text in en.js files or in strings
inside the page code, so the add-on locale gate did not cover them and
they could not be translated.
Each page now reads one JSON bundle per language of the web UI, checked
by the add-on locale gate. A list of notes is stored as numbered keys
and put back together by the page. Fine-tuning and quantization take
every language from the host tools locale files, plus a few own keys
that are translated in all languages. Voice, face and memory have a
draft Italian translation; their other languages repeat the English
text for the keys the host has no translation for.
Assisted-by: Claude:claude-sonnet-5-5
With the reply language on auto, the sentences the host writes in a chat
used the language detected from the sender, and the interface language
of the owner only when a server hook supplied it. No hook was wired, so
the interface language was never used.
The page of a connector add-on now sends its interface language with
each save (ui_language). The binding keeps it, so every frontend of a
cluster knows it. With auto, the host speaks that language when its
catalog has it, and reads the language of the sender only when the
owner's language is unknown or not in the catalog. A save without the
field keeps the stored value, and a value that is not a language tag is
ignored. A fixed reply language still wins.
The label of the Automatic option says what it does now, in all nine
languages of the page.
Assisted-by: Claude:claude-sonnet-5-5
Add and Remove of the chats' collection adapter had only been tried
against a fake. The new specs run them on the real collections service
and its chromem engine, with the embedding call answered in memory, so
they need no model, database or network and run in CI as they are.
They cover storing and searching an entry, removing it by file name
while keeping the others, a repeated undo, a missing collection, the
separation of users, the anonymous root and a service that has not
started.
Assisted-by: Claude:claude-sonnet-5-5
The access view, the preview and the kinds call returned English text
for each capability and each refusal. They now add the same text in the
language of the request (lang query, then Accept-Language), in new
localized_* fields. Codes, English fields and the model-facing text stay
as they were.
The texts live in the new connectortext package, one JSON file per
language (it, de, es, fr, id, ko, pt-BR, zh-CN), keyed by capability
and by refusal code. A test fails when a capability or a code lacks a
text in any language, or when {action} is lost.
The shared connector page asks for the page language and shows the
localized fields, with English as the fallback for each field.
Assisted-by: Claude:claude-sonnet-5-5
Memory is built in. Drop the package matrix, the catalog template and the
entry in the generated library index, and stop building it in the package
workflow, so the add-on is no longer offered for a new install. The sources
stay as the fixture of copies that are still installed: the host keeps the
alias that maps the legacy id to the built-in provider, and the add-on page
keeps its notice that memory is built in. The inventories and the docs follow.
Assisted-by: Claude:claude-sonnet-5-5
The provider picker now draws the slot's health notice (the circuit breaker
is open) with the shared Notice component. When the selected add-on serves
the slot and declares the forget role, it also offers "Forget everything from
this provider", behind a confirmation dialog that says whether the change can
be undone. The action calls DELETE /api/chats/memory; the built-in provider,
Off and a provider that is down have none.
Assisted-by: Claude:claude-sonnet-5-5
A text that a model proposes for a collection is checked with the secret
patterns that already keep a memory note from being saved at once. A
flagged text is still stored and shown, with a warning on the card, and
the owner can confirm it in the web interface. A messaging chat cannot
confirm it: the host does not write it in the chat, and a yes does not
apply it. A no still drops it.
The proposal carries the result in a new warning field, worked out at
each read.
Assisted-by: Claude:claude-sonnet-5-5
The install dialog and the upgrade approval ask the owner for the
permissions of a release. The owner answers from the verified manifest of
the staged package, so every read downloaded the package again, checked
its signature, and held the operation lock the whole time. A second read
(a retry, the upgrade approval, a reopened dialog) paid the full cost
again and waited behind the first.
Keep the verified answer per release, keyed by the digest the library
pins, for ten minutes, and let concurrent reads share one download. The
operation lock is held for the stage only. A moving tag has no fixed
bytes and is still read every time. The installed flag is read on every
call, and the nonce still binds the digest, so nothing is shown as
allowed that the owner has not confirmed.
The dialogs now say what they wait for after three seconds instead of a
bare "Reading what this add-on asks for...".
The update check cache is empty after every start, so a moving channel
read as "not known" on each visit until an administrator asked. The owner
now checks the installed add-ons in the background shortly after start
and every 30 minutes.
Measured with a package that takes 500 ms to download: the second read
went from 510 ms to 13 microseconds, and two concurrent reads from 410
and 820 ms to 404 ms each.
Assisted-by: Claude:claude-sonnet-5-5
The collections list reports max_chunk_size and chunk_overlap. The
Suggested changes card for a knowledge text now says how many passages
will be embedded and with which model, estimated from the text size and
the chunking of the server. Without a model name the card says "the
server's embedding model".
Assisted-by: Claude:claude-sonnet-5-5
The collections list now reports search_mode: semantic for the chromem
engine and hybrid for the postgres engine, which also matches words.
The Knowledge page shows it in plain words, so a person knows whether
an exact code or name can be found.
Assisted-by: Claude:claude-sonnet-5-5
The effective view and the test chat list name the built-in memory. The
provider guard reads that as an add-on name, so list the three files with
the reason.
Assisted-by: Claude:claude-sonnet-5-5
The agent form now has an Effective view that says in plain words what
the agent can do right now, worked out from the form as it stands, saved
or not: tools, skills, files, extra rights, rights it uses on its own,
the memory choice and the save level that applies, knowledge
collections and messaging connections. Each line names the section it
explains. Anything blocked shows its reason code and one fix: a button
that moves to the switch on this form, or a link to the page that owns
it. A connection that is saved is checked with the existing access
preview endpoint. A line says when memory is off in the person's
Settings.
Try it sends a message to a short-lived test chat built from the form
(model, tool switches, instructions as the system prompt) without saving
the agent. The panel says that permissions, memory, knowledge and
folders are not used by the test, and the chat is deleted on close. The
header gets a More menu with Export for a saved agent.
Assisted-by: Claude:claude-sonnet-5-5
The adapter spec 'stores the proposal and applies nothing when the host
holds the call for a person' passes in the suite but was not in the
required case inventory, so the inventory check failed with a mismatch
of one extra case. Add it, taking the name from the passing run.
Assisted-by: Claude:claude-sonnet-5-5
The global setup builds a fixed list of add-on bundles and sets
E2E_ADDON_BUNDLES_BUILT so workers do not build. The Memory add-on was
not in the list, and its notice spec skips its own build when the
variable is set, so on CI no dist existed, every asset answered 403 and
the notice never drew. Locally the dist of an earlier run was still
there, which hid it.
Add the Memory bundle to the list.
Assisted-by: Claude:claude-sonnet-5-5
The circuit breaker spec used a real 150 ms cool-down. Under the race
detector on a loaded runner, the turns between opening the breaker and
the "no call goes out" check took longer than that, so the rest was
already over and a call went out. The spec now runs on a service clock
that only moves when the spec moves it.
The reply-language spec sent "/new" as soon as the previous answer
reached the chat. The answer is delivered before the turn is marked
finished, so on a slow run the command was refused as busy and the
refusal text (in the fixed language) came back instead of the new-chat
text. The spec helper now waits for the turn to end first, as a person
does after reading the answer.
Assisted-by: Claude:claude-sonnet-5-5
The host now calls the roles of the notes slot itself, not only the tools
the model sees.
- At the start of a turn the context role is called with a 3 s limit and
a 6 KiB cap. The text goes in front of the message as data, in markers
that it cannot close, and not in the prompt, so it does not restart the
chat engine. The session passes the turn message to the hook and takes
an optional per-turn context block from it.
- A write through a provider follows the save level, the agent grant and
the messaging rules. Only Save and tell me applies a write at once, and
not for a remote provider that cannot undo. Other writes are held for a
confirmation.
- The export and the forget of a provider are routed by
GET and DELETE /api/chats/memory.
- A provider that fails three times in a row is left alone for a minute,
the slot shows a plain notice and the chat goes on without notes.
- Every call writes one audit line with the outcome and the size, and
never any text.
- The add-on that the built-in provider replaces is an alias: it is not
listed and a choice that names it means the built-in provider.
Assisted-by: Claude:claude-sonnet-5-5 go
A provider that says remote: true sends notes to a service, so its
manifest must declare capabilities.network. The person and the host see
the network access before anything is sent. A manifest without it is
refused.
Add aliases to a slot descriptor: add-on IDs that the built-in provider
stands in for. A copy of a retired add-on that is still installed keeps
working without serving a second time, and a stored choice that names it
means the built-in provider.
Assisted-by: Claude:claude-sonnet-5-5 go
Add the change kind `knowledge` and the sensitive grant and capability
`knowledge.write`. A text for a collection goes through the same
proposal flow as the other kinds, but it is never applied unasked:
the Ask, Auto and Always confirm levels all wait for the owner, and the
Never level takes the kind away. Confirm adds one entry to the
collection and Undo removes it. Text is capped at 64 KiB.
A paired sender can answer yes, no or undo in a messaging chat; a
sender who is only on the allowlist cannot. The connection page
explains a block with the shared reason codes, plus knowledge_none and
knowledge_no_embedding. The Suggested changes card names the
collection and previews the text. A kind can now declare a destination
other than the home folder, so core code stays generic.
Assisted-by: Claude:claude-sonnet-5-5
Part 2 of the agent editor redesign.
- Tool levels (Look only, Assistant, Full) set the stored switches and
grants. Applying one, or a starting template, shows what changed and
can be undone before saving. A level never grants a sensitive right.
- Templates are cards that say which level they start at.
- A Connections section holds the choice of connections an add-on may
use and lists where the agent is connected. It uses the existing
connections field and the messaging list.
- The model picker has search and shows what each model can do.
- Memory choices sit two by two to shorten the section.
- Advanced collapses, and the section nav sticks under the header on a
phone.
- The overflow guards now cover 360 px, and the agent editor 320 px.
Assisted-by: Claude:claude-sonnet-5-5
Memory is the first provider slot. The person picks one provider for the
notes: the built-in one, Off, or an add-on that declares the slot. The
choice is kept per person with the other host settings.
Core stays generic. providerslots.go lists the providers of a slot,
stores and resolves the choice, and gates an add-on that declares a slot:
its context files, skills and role tools count only while it is the
provider picked, and the chat can narrow a slot off for itself. The
notes wire into it in memory.go: an adapter gives the add-on's files and
skills behind the MemoryProvider interface, the built-in provider stops
reading while another serves, and the On or Off switch and the choice
stay one answer.
If the add-on that was picked stops, is disabled or is removed, memory is
off with the code memory_provider_unavailable and the add-on is named.
It never falls back to the built-in provider, so a note is not read or
saved where the person did not choose. The choice stays stored.
Add GET /api/chats/providers, GET and PUT /api/chats/providers/{slot}.
Settings > Memory lists the providers from that answer with a generic
picker, shows the failure with the shared Notice and offers to use the
built-in provider. Document the facility for add-on authors, and test it
with a fake add-on that provides the slot.
Assisted-by: Claude:claude-sonnet-5-5 go
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DjrQyk8ovFXvy5zrjHX1BD
A provider slot is a job the host does itself and lets an add-on do in
its place. The host owns the slot, its gates and a built-in provider;
the person picks one provider.
Add the closed list of slots as data (provider-slots.json) with a
descriptor per slot: the choice a person has, the built-in provider, the
roles a provider can fill, the contributions the slot activates and the
facts a provider may declare. Add the optional manifest key
capabilities.provides, validated against the descriptor: the slot and
its version, the tools of each role (declared, of the right kind, not
page-only, not shadowing, one role each), typed properties, and the
context file scopes. The manifest stays at api 2.
Carry the declaration through the apps list and the tool adapter so the
host can list the add-ons that provide a slot.
Assisted-by: Claude:claude-sonnet-5-5 go
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DjrQyk8ovFXvy5zrjHX1BD
The agent form was an accordion of nine folds with two Save buttons and no
summary. It is now one page: a sticky header with the agent name, mode,
unsaved-change count, model, tool and memory chips and a single Save,
a section nav that scrolls to Identity, Capabilities, Memory and
knowledge and Advanced, and one card per section.
Nothing the form saves changed, and the API is untouched. The parts keep
their data-section ids, test ids and summary lines. The folds are gone,
so the e2e specs no longer click them open; the "needs a name" and
"changed" checks now read the card header (data-group). The nav wraps
on a phone instead of scrolling sideways, and the page has no
horizontal overflow from 320 px up.
Assisted-by: Claude:claude-sonnet-5-5
Add a Notice component to the add-on settings kit so a package can show
the host's own notice: severity, title, reason and one action. The
Memory add-on page uses it to say that memory is built in and to link to
Settings > Memory. A host without Notice falls back to Callout.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The Home slash command that opens collections is now /knowledge. /memory
still finds it, and no skill can take either name.
The Conversations tab of Settings > Memory gets a line that says what
the notes are and that a sender who is not paired always waits for
approval. Add an end-to-end test that reads and deletes one of them.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Draw the editor of a saved agent with short names, one add-on and two
messaging connections (one missing a permission) at desktop and phone
widths, with the sidebar open and collapsed, every fold open.
Assisted-by: Claude:claude-sonnet-5-5
The add-on manifests now carry the title and description as language
maps. packagedApp copied the map into the title field, which the apps
list sends as plain English text, so the sidebar, the drawer and the
Home slash menu drew nothing for Studio and Talk. It now sends the
English text in title and description and the maps in titles and
descriptions, as the server does.
The Settings tab strip scrolls sideways on a phone by design, and it
outgrew 390 px when the Memory tab was added. Allow it in the overflow
spec like the other tab strips.
Assisted-by: Claude:claude-sonnet-5-5
The fail-closed change renamed one unit case and replaced three Go
cases of the apps list while the owner is busy. The inventory in
suites.json still listed the old names, so the gallery-ui, gateway and
artifacts suites reported an inventory mismatch.
Assisted-by: Claude:claude-sonnet-5-5
A frontend kept the last apps list per person and answered 200 with a
stale mark when the owner timed out. Two frontends then disagreed: one
with a cached list answered 200, the other a typed 503. The acceptance
contract is that every frontend gives the same typed answer when the
owner cannot answer, so the server cache is gone.
The route now answers owner_busy (timeout) or owner_unavailable with a
503 from every frontend. An owner that is up and busy still answers
from its snapshot, with the operation of each add-on in the list. The
Add-ons page keeps the last list in the browser and shows it with the
busy notice, so it never goes empty. The specs, the docs and the
swagger spec follow the new contract.
Assisted-by: Claude:claude-sonnet-5-5
The shared production fixtures were refused when the producer and a
consumer job ran on runners with different patch releases of Go (1.26.9
and 1.26.10). A patch release builds and runs the same fixtures, so the
identity now keeps the Go minor and the Node major. protoc stays exact.
Assisted-by: Claude:claude-sonnet-5-5
A person can now choose four save levels on the Memory tab: Save it and
tell me, Ask me first (the default), Always confirm and Never. Always
confirm is like ask, and nothing can loosen it: no agent or messaging
setting overrides it, and the model cannot undo or forget a note by
itself (revert_change is refused, and the person uses the Undo).
One function, effectiveSaveLevel, combines the rules. The strictest wins,
in the order auto, ask, always, never. The inputs are the level of the
person, the rule of the saved agent, the messaging row and the chat.
A table test covers every combination.
A saved agent has an optional memory_save field: always or never. It can
only be stricter than the person, so auto is not offered and the API
refuses it. A write without the field keeps the stored rule, and use_mine
clears it. It is stored by both stores and is part of an agent export and
import. The agent form shows three cards under When it wants to save a
note.
The new row In messaging apps (messaging_save on GET and PUT
/api/chats/memory) takes ask (the default), paired_private or never. With
paired_private a note is saved at once only when the sender is paired and
the chat is one-to-one, and it goes to the notes of that conversation,
with an Undo. The limits stay: five notes a reply, the size limit, and a
note that looks like a secret still waits. The row cannot loosen the level
of the person when that is always or never. A setting that cannot be read
reads as ask.
The connector turn now carries whether the chat is one-to-one and whether
the sender is paired, in the turn grant and in the worker JSON. Both read
as false when unknown. The Telegram, Slack and Discord transports already
set Direct; new specs pin it for private, group and supergroup chats,
direct messages, channels, group conversations and threads.
A note from a messaging chat goes to the conversation first. It reaches the
notes of the agent or of the person only from a paired sender, only when
the memory choice of the agent allows that scope, and only after that
sender confirms it. Under Always confirm only the paired sender who asked
can confirm. An agent whose memory is None still saves nothing.
The script of the confirm-in-chat specs now proposes a note for the
conversation, because a sender who is only listed cannot write to the
notes of the person.
Assisted-by: Claude:claude-sonnet-5-5
The list stays on screen with a banner when a refresh fails. The banner
text changed from "may be out of date" to "Showing the last known
state.", so the polling spec waited for text that is no longer shown.
Assert the banner by its test id, as the busy-owner spec does.
Assisted-by: Claude:claude-sonnet-5-5
The connector spec "keeps asking when the setting is ..." read the tool
results as soon as the bot had an answer. The harness records a result
after it emitted the turn events, so under load the answer could come
first and the list was empty. The spec now waits for the result.
Shutdown left two background writers running: the file text indexer loop
ran on the application context, and the chat search backfill had no stop.
A test that removed its temp directory right after Shutdown could meet a
write into the "textindex" folder ("directory not empty"). The indexer
loop now has its own context and Shutdown waits for it, and the chat
store gets a Close that stops the backfill and waits.
Assisted-by: Claude:claude-sonnet-5-5
The memory choice of an agent names the built-in memory in the agent
form, the notes list and the agent delete. The add-on name guard flagged
those four lines after the previous commit.
Assisted-by: Claude:claude-sonnet-5-5
A saved agent now has a memory choice: Mine and its own, Its own only,
Mine, or None. The host enforces it. The notes in the prompt and the
scopes of context_read follow the choice, and a memory note may go only to
the scope the choice allows: the agent's own notes, or the person's. The
propose_change tool offers the model only those scopes, a note needs no
scope, and any other scope is refused. None offers no memory kind.
An agent saved before the field has no choice and behaves as before: it
reads notes when its add-ons name Memory and the model picks the scope.
A write without the field keeps the stored choice. The person's Off, a
private chat and the agent's grant still decide first. Sub-agents get no
notes and cannot save; triggers read per the choice and cannot save.
Messaging chats read as before.
The agent form has a Memory section with the four choices, an "As before"
note for older agents, a switch for the permission to save, and the line
that memory is off in the settings. New agents start with Mine and its own.
Deleting an agent that has notes asks to keep, export or delete them
(DELETE /api/chats/agents/{id}?memory=keep|export|delete). Kept notes show
on the Memory page under Deleted agents, and the notes list has a tab for
each agent. Copying an agent never copies its notes.
Assisted-by: Claude:claude-sonnet-5-5
A new opt-in tool group, Past chats (history), gives a chat two read-only
tools. search_chats finds messages in the earlier chats of the person
(query, scope this_chat, this_agent or all, limit, since) and read_chat
reads one chat from a message number. A call returns at most 10 hits with
300 character snippets, or 20 messages and about 6 KiB. Every result is
wrapped as untrusted text, a closing line in an old message cannot end
the wrapper, and the tool says plainly when nothing is found.
What the tools never reach: another user's chats, private chats (a chat
with the notes of memory switched off), sub-agent runs, and every chat
that no person started, which leaves out the messaging chats that hold
the words of other senders. A saved agent needs the new grant
history.read, which is off by default and turns the group on when it is
saved. An agent that works in a folder may search only its own chats. A
run that starts by itself, a messaging chat and a sub-agent do not get
the tools. The grant, the switch and the agent are checked again at each
call. Each call writes one log line with the tool, user, chat, scope, a
hash of the query and the chats returned, and never a query or a message.
The Tools menu and the agent form show the group and the grant through
the existing lists. The docs and the API notes describe both.
Assisted-by: Claude:claude-sonnet-5-5