# Bring Your LM 2026.10.28

Version 2026.10.28 · Build 19 · 2026-10-28

This release is about moving what you built. An agent, a tool or a provider can be exported to a
`.bylm.json` file, reviewed before it leaves the device, and imported on another device or by
someone else, with every conflict, host and key decided before anything is written. Alongside it,
the website opens a marketplace: a place to publish those files and to find the ones other people
shared, which you download and import yourself. Saved API keys became secrets with a page of their
own: one secret can serve several providers and tools, and it is sent only to hosts this device
approved. Constants hold the account ids and resource names that used to be retyped into every
tool. Tool templates gain MiniJinja.

## Share agents, tools and providers as files

Export sits in the menu of an agent's, tool's or provider's page, and in the agent list's selection
bar for several agents at once. It carries what the item depends on, so an agent travels with its
tools and sub-agents. Before anything is saved, a review lists what travels, where each tool sends,
and which keys the importer will be asked for. A credential the scanner finds pasted into a config
must be ticked off before the file can be saved.

- Providers stay out of an export by default, so the importer picks a provider and model of their
  own. A provider you do include warns when its address is `localhost`, a `.local` name or a
  private network address.
- An agent that runs on the embedded engine travels as a description of its model files, with an
  optional download page for each, instead of an id only your device knows.
- An agent or a model filter can say its model must handle image input or reasoning, which narrows
  the importer's model list to models that do.
- Key values never travel. The file names each key and constant once, by the name it has on this
  device, with a generated name such as "openrouter.ai API key" one tap away, and carries the hint
  and link saved on each secret.

Import is at the top of Settings, an empty Agents or Providers page opens it in one tap, and it
links to the marketplace. On Android a bundle opens from a file manager, a browser's downloads or
the share sheet. The import plan asks every question before it writes:

- Which workspace the file lands in, and per tool whether it goes there or into Global.
- What to do with each provider: import it, use one already here, or leave it out. A `localhost`
  Ollama or llama.cpp provider binds to your own of that kind, and Test connection checks an
  address first.
- Which model each agent and filter runs. A model id that differs only by vendor prefix, case, date
  or tag is matched to the listed one. An agent on an embedded model finds the shared files, or
  another quantization, in your models folder.
- Each key the file needs, once: a secret you already send to that host is picked for you, and one
  typed key fills every item that shares it. Each key and constant links to where its value is
  found when the file says, and a secret created here keeps that hint and link.
- Which hosts you accept, and, when an agent or tool of that name exists, a view of every setting
  the file would change, with the option to replace yours instead of adding a copy.

Re-importing a file leaves its unchanged tools alone and asks for no keys again. The results page
lists anything saved on a model its provider does not list, linked to its page. Text fields that
travel in a bundle count down near their limit and name invisible characters as you type.

## The marketplace

The website now has a marketplace of shared agents, tools and providers. It is a site you visit:
browse by kind, namespace and tag, download a release as a `.bylm.json` file, and import that file
in the app. Publishing is an upload from the browser after signing in with Google or GitHub, and
every upload waits for a moderator before it is public. Each listing shows its full
configuration and the keys and constants it needs, with a link to where each value is found, and
the terms say uploads are public under CC0. Uploading a bundle again leaves its unchanged, approved
items at their release instead of sending them back to review.

## Secrets

Settings → Secrets lists every saved secret. Each one's page shows what uses it, and from there you
can share, ask for, rotate, revoke or delete it. Rotating reaches every provider and tool using the
secret and the devices you choose, and revoking stops every updated device sending it.

- Providers and fetch tools pick their key from a selector instead of a text field, so reusing a key
  links the same secret rather than copying its value. Deleting a provider no longer deletes its key.
- A secret is sent only to hosts this device approved for it. A provider or tool whose address
  changed through sync, an import or an agent stops with a message naming the secret and host until
  you approve it on the secret's page.
- A fetch tool or a provider's headers can place more secrets than the API key with
  `{secrets.<name>}`, each linked on the form. A tool written with `{apiKey}` is told to use
  `{secrets.apiKey}`.
- A fetch tool can mark its key optional, for endpoints that answer without one.
- A fetch tool whose host comes from a constant must place its key as `{secrets.apiKey}`; saving
  one with `{apiKey}` is refused, so a device on an older version never sends the key to a host a
  model picked.
- A secret can say where its value comes from: a hint and a link, edited on its page and shown
  whenever a new value is asked for. A secret created from a provider or a file keeps theirs.
- Unused secrets are marked, filterable, and can be deleted in one go.
- Saving a provider whose API key would go over plain `http` to a public address warns first.
- The conversation page names the keys an agent needs that this device does not have, linked to
  where you type them.

## Constants

Settings → Constants keeps account ids, resource names and other non-secret text in one place. A
constant is global or private to a workspace, a workspace can override a global one, and an agent
can carry its own text for one, so two agents can use different accounts with the same tool. Write
`{constants.<name>}` in a fetch tool's URL, headers or body, or in a provider's base URL or headers,
and the form shows a field to link it. Tool filters can read constants too. A constant can link to
the page that shows its value. A shared file says which constants it needs, with their text only
when the exporter chooses to include it.

## Templates

- A fetch tool's template filter, model filter prompts and error template can be written in
  MiniJinja, with `{% if %}` and `{% for %}`. Every name they read is checked when the tool is
  saved, and a missing value stops the call instead of rendering empty. Status and arguments keep
  their types, so comparisons and sums work.
- A JSON body that is invalid because of a bare placeholder names the placeholder and how to quote
  or declare it.
- A JSON request body can be a MiniJinja template over the call's arguments, secrets, constants and
  request metadata.
- Provider headers and fetch templates can use `{meta.*}` request metadata: the conversation,
  agent, workspace and the app's name and version. A header such as
  `X-Session-Id: {meta.conversation.id}` lets a provider match its prompt cache per conversation.
- Template fields show the names they can read as chips that insert at the cursor, and a model
  filter's prompts offer the tool's own arguments.
- A fetch tool is refused on save, by the form, an agent or an import, when its URL is not a valid
  URI template, its JSON body is not JSON once filled, or its jq filter or cost expression does not
  compile.
- A model filter's answer schema may use any JSON Schema 2020-12 keyword, `pattern` included.

## Agents that set up other agents

An agent given the matching tools can now do more of the setup, and asks you first wherever a
request would go somewhere new:

- Create and edit providers. A new provider, a new address, a rename or a change to its
  authentication or headers waits for your approval in a prompt that shows what uses it.
- List secrets by name and host, have you create or change one, link or unlink it on a tool or
  provider, and delete one, without ever seeing a value.
- List, save and link constants, and give another agent its own text for one.
- Suggest a secret's or constant's hint and link, so the dialog asking you for a key already says
  where to get it.
- Edit one field of a fetch tool without stripping its authentication, retry or error settings, and
  keep a key linked to a tool whose icon it sets in the same step. A request body is accepted only
  with a content type it can be sent as.

These approvals can only be answered by a person, even inside a sub-agent another agent is
testing. Saving a sub-agent allowlist that would let agents call each other in a loop is refused,
naming the agents in call order. `tools-request_secret` and `tools-copy_secret` keep working for
this release; they are marked as retiring, and agents that use them also receive their
replacements.

An assistant given the tool-management tools sends noticeably smaller requests.

## Conversations

- When a provider fails mid-stream, the text that already appeared stays, marked as cut off with
  the reason, and sending a new message continues from it.
- An on-device reply that could not see the attached images says so and why, and a projector that
  failed to load can be tried again from that note.
- Conversations open at their newest message without scrolling, with no loading flash, and do far
  less background work while open.
- Quote blocks have a copy button that copies the quoted text without the `>` markers.
- The paragraph still streaming matches the finished ones.
- Stop on a reply that is waiting for your answer ends it instead of leaving a tool call loading and
  its jobs active; calls an earlier version left that way are ended once when the app starts.
- An assistant on OpenRouter is sent its own earlier reasoning once and intact, instead of in
  fragments.
- The agent list marks agents holding an unsent first message.
- The "Messages sent to model" limit is gone from the agent form, workspace overrides and the global
  conversation-loop settings; what the model is sent is set under context compaction. Agents that
  stored a message window keep working, and files exported with one still import.

## Models

- The model picker opens on models that take and return text, marks those that support structured
  output, and can show only those. Local engines and OpenRouter report that support correctly, and
  Ollama embedding models are shown as such.
- Reasoning controls show again for llama.cpp server models whose template can think, such as
  Gemma 4.
- An on-device vision model can load its projector with the model or only when a conversation shows
  it an image, set on the provider or per model.
- The embedded engine moves to llama.cpp b11946, with upstream's Vulkan and AMD fixes, image-input
  fixes for LFM2 and Gemma 4 vision models, MTP support for more model families, DeepSeek V4.1
  flash, LiquidAI LFM3, LFM3-VL and MiniCPM-OCR support, and a DRY sampler that no longer runs away
  with CPU and memory.
- An image too large for an embedded model's context fails at once, saying how many tokens the
  prompt needs and how many the context holds.
- Provider edits apply to the very next message in every conversation, not after a restart.

## Forms

Every form that edits an agent, provider, tool, workspace, embedded model or conversation asks
before discarding unsaved changes. A disabled Save says why and scrolls to the field that needs
fixing, a failed save says so above the button, and Save cannot be tapped twice. Out-of-range
values keep Save off instead of being quietly dropped or clamped, settings fields save once per edit,
and removing a row in the fetch tool form no longer shows its text in the row below. Cautions are
amber rather than error red.

## Devices and sync

- Settings → Devices shows each device's app version and badges this one when another runs a newer
  version.
- Starring an item or moving it between workspaces no longer undoes an edit synced from another
  device.
- A device still on 2026.09.12 keeps its prompts and the message details a newer version added.
- Sync refuses to turn on until its endpoint is a websocket URL, and says why.
- When a device on a newer version writes something this one cannot read, the rest keeps working.
  A list leaves out only the unreadable item instead of emptying, a message with a newer kind of
  attachment shows with a note, and changing a setting, renaming a secret or finishing a reply
  keeps what the newer version stored beside it.
- A provider or fetch tool holding a setting from a newer version, such as a new authentication or
  request method, says it needs a newer version of the app instead of sending a different request
  or its key the old way.

## Update every device you sync

A device still on 2026.09.12 syncs what this version writes, but it cannot read the new parts: a
tool or agent that uses them does not work there, and a change made there can undo them.

- A `{secrets.…}`, `{constants.…}` or `{meta.…}` placeholder is sent as written or left empty, so
  the request fails.
- A JSON body written in MiniJinja is sent empty, and a MiniJinja error template is ignored. A
  MiniJinja filter stops with "update the app" rather than running as Mustache.
- Editing a tool there, starring it or changing its icon drops its MiniJinja body and error template.
  Moving or copying a tool there, or copying an agent or a provider, drops its links to secrets and
  constants. A conversation started or edited there ignores the agent's own constant text.
- Sharing a secret from this version to that device fails there, and rotating or revoking a secret
  does not reach it: it keeps sending the key it holds.

Settings → Devices shows which devices still run an older version.

## Elsewhere

- The app is about 1.5 MB smaller per ABI.
- jq and sharing now work on 32-bit Android phones; the embedded engine is marked as unsupported
  there.
- The Android app now needs Android 9 or newer. Devices on Android 7 and 8 no longer receive
  updates.
- A tool's page tests the tool from its floating button, and Edit moves into the menu. An agent's
  tools are listed by name.
- Under All workspaces, each agent and conversation row names its workspace, and opening, editing
  or deleting a tool acts on the row picked even when another workspace has one of that name.
  Export works from one workspace at a time.
- Image cleanup reports a failed scan instead of offering to delete images that unreadable
  messages may still show.
- The Jobs page opens and loads further pages without a half-second stall.
- Settings lists Import first, then Secrets, Constants, Devices and Sync after Workspaces, and every
  row says what it holds.
- A screen opened from a What's new highlight has a back button to What's new.

## On the website

Every page also has a Markdown twin at its URL with `.md` added, listed in `/llms.txt`, and page
URLs no longer end in a slash.

---

[Bring Your LM](/) · [Docs](/docs/features) · [Marketplace](/marketplace)

[Articles](/articles) · [Releases](/releases) · [Bundle Format](/marketplace/bundle-format) · [Marketplace Terms](/terms) · [App Privacy](/privacy) · [Website Privacy](/website-privacy) · [Open Source](/open-source) · [llms.txt](/llms.txt)
