Public release notes for SAALT packages. Versions follow semver. Entries use the Keep a Changelog format.
SAALT Core
Release notes for the core SAALT platform — the web app, REST API, App runtime, and built-in features. These are the developer-facing technical notes; the in-app What's New covers the same releases at a higher, user-facing level.
v1.6.0 — unreleased
Breaking
- New build toolchain and runtime image. Core builds with pnpm and Vite+ (Vite 8, Vitest 5) instead of npm, runs React Router 8.5 and better-auth 1.7, and pins Node.js
24.22.1. The container image is built on the Vite+ image and runs on Debian (bookworm-slim) instead of Alpine, as user uid 100 / gid 101. Custom Dockerfiles or build pipelines needvp install --frozen-lockfileandvp run generate && vp run build. A Helm chart is now part of the repository. - Microsoft sign-in accounts are re-keyed. A migration for better-auth 1.7 rewrites the account id of Microsoft sign-ins from the token's
subto itsoid; accounts without a stored token, with an unreadable one or with a conflict are left as they are. OAUTH_HUB_URLnow defaults tohttps://oauth.saalt.ai.
Added
- A sidebar next to the chat for what the Agent builds. Two new built-in tools feed it: artifacts (Markdown, HTML and React — previewed in a sandboxed iframe with no same-origin access, no network and a strict CSP; versions, full screen, copy and download; up to 1,000,000 characters) and a task list (up to 20 items) the model keeps current during long jobs. Mermaid diagrams open there as cards with zoom and SVG export, rendered by a new synchronous renderer that no longer hangs while streaming; sources over 50,000 characters are not drawn. Both tools are on whenever the model supports tools, but not for public Agents or API calls. See Chat.
- Memory import. Personal Settings → Memory → Import memories gives the user a prompt to run in ChatGPT or Claude; the pasted answer (3–20,000 characters) is turned into at most 50 personal memories of the user's personal Agent, each redacted, de-duplicated and screened like any other memory. See Memory.
- Feedback with context. A thumbs-down asks "What result did you expect?" (
feedback.comment, one rating per message). With PostHog configured, a comment sends the conversation up to the rated answer as a PostHog$ai_traceevent — secrets redacted in several passes, capped at 500 KB, never for incognito conversations or users who opted out of analytics. An occasional in-chat rating ("How is SAALT doing so far?", in about one of four conversations) is driven byPOSTHOG_CHAT_SURVEY_*; ratings of 3 or lower can share the conversation the same way. - Platform guide for every Agent. A built-in
platform-guideSkill, generated from this documentation and downloaded fromPLATFORM_GUIDE_ZIP_URL, lets Agents answer how-to questions about SAALT. See Skills. - Skills can be viewed read-only, and custom Skills downloaded as a
.zip; Agents can save Skills they built in the code sandbox, and Skills work in Projects. - Managed MCP credentials. Catalog MCP servers can offer sign-in managed by SAALT, configured through
MCP_<SLUG>_*environment variables: a SAALT-provided OAuth app (users still sign in with their own accounts) or one shared credential. See MCP servers. - Knowledge folder upload in batches of 20 with progress and a partial-failure count, up to 1,000 files per upload; Office templates (
.dotx,.potx,.ppsx,.xltx) are accepted, in the UI and inPOST /knowledge/{agentId}/documents. SAALT_LICENSE_KEYsets the license key and overrides the one stored in Global Settings.- Apps can be made available to every user's personal Agent only (
plugin_availability.isPersonal); system prompt versions can carry a name and description. bridge.user.me()returns the user's interfacelanguage. The published Bridge type adds it with the next Bridge release. See Bridge.
Changed
- Tool loops are budgeted per turn. When one tool has been called 10 times in a turn, the model is asked once to stop, summarise what it has and ask the user how to continue; at 25 calls of the same tool it must answer in text. The limit of 100 steps per turn is unchanged.
- Every conversation starts with SAALT's platform instructions ahead of the Agent's system prompt — in the chat and in
POST /llm/{agentId}/conversation. - Knowledge documents keep their file name unless exactly the same name exists (then
-2,-3, …); files are stored under a unique path, so same-named uploads no longer overwrite each other. - The Bridge conversation API (
findFirst,findMany) accepts Apps enabled for the Space, globally or for personal Agents, not only for the Agent itself. - Code-execution sandboxes are kept for 24 hours of inactivity (
SANDBOX_IDLE_TIMEOUT_MS, was 20 minutes) and at most 7 days (SANDBOX_HARD_TIMEOUT_MS, was 1 hour). x-forwarded-proto: httpsfrom a TLS-terminating load balancer is trusted, so form actions work behind it.- Chat titles follow the language you wrote in; after signing in again you return to your conversation; the Agent user list only shows users who may chat with the Agent; the Projects list in the sidebar shows five and Show more.
Fixed
- Bulk download of Knowledge documents downloads every selected file.
- Agent Inventor no longer stops at creating agent when the prompt contains German quotation marks.
- Leaked OpenAI citation markers are removed from answers.
- Dropping a file on the chat input of an Agent with uploads turned off now explains why.
- Mobile: the model button no longer overflows, and the Agent start page and chat history fit small screens.
v1.5.6 — 2026-10-22
Security
- Node.js 24.22.1. All container images move from
node:24.18.0-alpinetonode:24.22.1-alpine, the October 2026 Node.js security release (Brotli decompression and TLS hostname-verification fixes).
v1.5.5 — 2026-10-22
Fixed
- Background jobs with custom ids were never queued. Job ids containing
:were rejected by the queue, so memory extraction (since v1.5.0), automatic RAPTOR summary builds and Re-embed all in Admin → Models silently did nothing. They run again. - Document parsing with local file storage uses
INTERNAL_APP_URL. File URLs handed to the document parser now preferINTERNAL_APP_URLoverAPP_URL, so parsing no longer fails in clusters where the public URL doesn't resolve from inside. See Environment variables.
v1.5.4 — 2026-10-21
Added
- Model administration in the UI. With
CLIENT_MODEL_CONFIG_ENABLED=true, super admins pick the instance's active models in Admin → Models from live discovery across OpenAI, Anthropic, Vertex AI and LiteLLM, set the defaults, enable embedding models and see prices (missing prices are filled from LiteLLM's public price map). Changing the default embedding model asks for confirmation and can re-embed existing Knowledge; the current default can't be deactivated. Model ids are shown as readable names (gpt-6-astra→ GPT-6 Astra). Without the flag the instance keeps using the model list from the SAALT configuration service. - LiteLLM as a provider (
LITELLM_BASE_URL,LITELLM_API_KEY), and custom OpenAI-compatible models added by hand. A custom model's API key is read from an environment variable whose name starts withCUSTOM_LLM_; the UI only shows whether it is set. Custom endpoints are checked against SSRF on save and on every request (no credentials in the URL, no link-local or metadata hosts, redirects refused). See Environment variables.
Changed
- Recalled memory is appended to the latest user message instead of the system prompt, behind a prompt-cache breakpoint, so the cached prompt prefix stays stable across turns.
Fixed
- Vertex AI chat and embedding models use
GOOGLE_CLOUD_PROJECTinstead of a fixed project. - Rapid toggles in Admin → Models no longer overwrite each other.
v1.5.3 — 2026-10-19
Changed
- App buttons follow
ctain/meta. On an Agent's integrations page the card header is no longer a link; withoutcta.userthe default View button appears only for Apps withhasAdminChatPageand opens the App's page in the Agent settings. In Admin → Apps a button appears only whencta.adminis set, and never for standalone Apps. See App metadata.
v1.5.2 — 2026-10-19
Added
ctain App metadata. An App can declarecta.userandcta.admin({ url, label }) in/meta; Core renders them as buttons on the Agent's integrations page and on the Admin → Apps card. See App metadata.- Large Knowledge bases are copied in the background when an Agent is cloned. The clone is usable right away, and its chat shows a notice while the Knowledge is still being indexed. Cloning also prefills the source Agent's system prompt and maps Knowledge tags to documents by name.
- MCP OAuth with pre-registered clients goes through the SAALT OAuth hub when the instance has
OAUTH_PROXY_SECRET, so one redirect URI serves every instance. Dynamically registered clients keep the instance's own callback.
Changed
- Starting a new conversation no longer reloads the page.
- On phones and tablets, inputs in Apps, Knowledge and Space pages no longer focus automatically and pop up the keyboard.
Fixed
- A new conversation started from an incognito chat is no longer incognito.
Security
- Renaming and archiving a conversation is limited to its owner. The chat action now checks that the conversation belongs to the current user on that Agent and answers
404otherwise; before, another user's conversation could be renamed or archived by its id.
v1.5.1 — 2026-10-14
Changed
- The default container port for Apps is
8080instead of3000, both in the Add App dialog and for one-click installs from the catalog. Catalog images that listen on8080failed their/metaprobe under the old default and kept restarting. Apps already installed keep their port; an App that listens on3000now needs that port entered in the dialog.
v1.5.0 — 2026-10-14
Breaking
- Two-factor authentication is required for password sign-ins. Every session started with a password — sign-in, sign-up, password change — must complete a TOTP code from an authenticator app, and an account without 2FA is sent to set it up before it can do anything else. Until then Core treats the session as signed out, including for App requests. Accounts that sign in only with Google or Microsoft are not affected. Backup codes (ten, single use) cover a lost device, and super admins can reset a user's 2FA under Users & Permissions. See Profile.
- Error tracking moved from Sentry to PostHog.
SENTRY_DSNis no longer read; errors, metrics and product analytics are sent to PostHog whenPOSTHOG_KEYis set (POSTHOG_HOSTselects the region). Error reports no longer carry credentials, request bodies or query-string tokens, and PostHog headers are not forwarded to App backends. - The least-trusted model security tier is called
globalinstead ofus-cloud. A model whose config still saysus-cloudis treated asglobal, and a model without a valid tier falls back toglobal.ModelInfo.securityTiernow reportssecure,eu-hostedorglobal. See the Bridge reference.
Added
- Memory, rebuilt. The model no longer saves memories through a tool call; a background job extracts durable facts once a conversation has been quiet for a minute and reconciles them with the existing ones (add, update, delete), and a guard model screens every write against prompt injection. Memories are personal (one user, one Agent) or shared (agent-wide). A fact that looks useful for everyone becomes a suggestion shown only to the user it came from, on the start screen of their next new chat, and is shared only once they approve it. Each turn uses a semantic top-12 search plus pinned memories instead of the whole set (
memory,memory_candidate,memory_history,dream_run). A nightly consolidation (dreaming) merges duplicates, replaces contradicted facts and retires stale ones; its last run can be reverted per Agent. Common secret formats are redacted before storage, each bucket is capped at 500 memories, and incognito conversations, public Agents, anonymous users and API-key access are excluded. Agents gain a Memory section (shared memories, Allow shared memory, pinning, revert), and super admins a Memory block in Global Settings (nightly consolidation, dream model, Backfill memory embeddings — run it once after upgrading, since memories from before 1.5.0 have no embedding). See Memory. - API key management through the API. A global key marked Can manage API keys in Developer Settings is a master key: it can list, create, update and delete its owner's other keys under
/api/v1/core/api-keys, for as long as the owner holds Create & Manage API Keys. Keys created this way can never manage keys themselves, and master keys cannot be changed or deleted through the API. See the API overview. - Asynchronous file parsing for Apps —
bridge.files.parseFileAsyncqueues a parse and returns ajobId;getParseFileStatusreads the result, kept for 24 hours, and an optionalcallbackPathlets Core notify the App once the job is done.parseFile's model options gainoverridePrompt, which replaces the default OCR prompt instead of extending it; it andpromptExtensionare limited to 10,000 characters each. Published as@open-agent-kit/[email protected]. - Built-in tools for
generateTextandgenerateObjectare opt-in per call throughoptions.defaultTools(knowledgeBase,accessWeb), in the core API and the Bridge alike. A tool runs only when the Agent also has it enabled.disableToolsswitches all of them off — forgenerateText, so does a model configured without tools.generateObjectgained tool support and answers404for an unknown Agent. - Favorites — users can star Agents and Apps; favorites appear in the sidebar, on the home dashboard and in Spaces (
user_favorite). - A per-user opt-out from usage analytics in Personal Settings (
user.analyticsOptOut). Analytics are pseudonymous: Agent and Space ids are hashed, URLs anonymised, and only the email domain is recorded. - Costs are stored per LLM call —
llm_invocationgainsinputCost,cachedInputCost,outputCostandtotalCost, fixed at the time of the call. - An activity view for administrators under Admin Tools → Activity, filterable by user, resource type, source, time range and free text, with a CSV export of the filtered result capped at 50,000 rows.
- SAALT can be installed on phones and tablets — Core serves a web app manifest (
display: standalone), so it can be added to the home screen and launched like an app. - The sidebar marks conversations that are still generating an answer, and member fields in permission groups autocomplete users by name or email.
- With
TAVILY_API_KEYset, web access reads pages through Tavily Extract and falls back to fetching the page itself. - The Report Issue (via Jira) menu entry opens the address in
REPORT_ISSUE_URL. - Users who sign in with a password can Set up again their authenticator app in Personal Settings to move to a new device; the two-factor section is hidden for accounts without a password.
- With PostHog configured, each LLM call made in a user's request is traced to PostHog — user id, conversation id, hashed Agent id and the calling feature, without prompts or responses. Users who opted out of usage analytics are not traced, and neither are background jobs or API-key calls.
Changed
- Incognito conversations are deleted 30 days after their last activity by a scheduled job. They were previously kept, hidden from everyone, indefinitely. See Chat.
- An Agent holds at most 1,000 Knowledge Documents.
POST /knowledge/{agentId}/documentsand manual uploads answer409at the limit; App knowledge syncs import up to the limit and log how many documents they skipped. GET /agentsno longer answers403for aspaceIdthe caller cannot see; it returns only Agents the caller may chat with and the key may reach, so such a request yields an empty page.- Once a personal-Agent model policy has been saved, models added to the instance later stay unavailable to personal Agents until an administrator enables them.
- Tool-using chats run up to 100 steps instead of 25, and on the last step the model is made to summarise what it found instead of ending the turn without an answer. The
generateText,generateObjectand conversation API endpoints keep their limit of 25. - The MCP catalog was refreshed, the connection dialog shows the OAuth redirect URI to register with the MCP server, and deleting a connected server no longer leads to a broken page.
- Plugin data is indexed by App and identifier, which speeds up standalone Apps' reads.
- The selected reasoning effort is kept when moving from the personal chat to an Agent chat.
Fixed
- Editing an API key without sending its permissions — for example only switching Can manage API keys — reset the key to global scope; it now keeps its scope.
- Ongoing conversations could break with Anthropic models (source tool not found) and with Gemini models (Corrupted thought signature) when earlier turns were replayed.
- Pasting a very large image could crash the chat.
- Drag and drop is blocked when file upload is disabled for the personal Agent.
- Inconsistent interface language in places, duplicated load more entries in the chat sidebar, and stray quotes, Markdown characters or inline reasoning in the label of a code-execution tool call.
v1.4.9 — 2026-10-09
Fixed
- Code execution on the remote sandbox driver failed for large inputs with
413. Seeding the sandbox sent every file in one tarball request, which exceeded the request size limit of the proxy in front of the sandbox host. Core now unpacks the archive itself and writes the files one request at a time, checking every path stays inside the target directory. Affects deployments withSANDBOX_DRIVER=remoteonly.
v1.4.8 — 2026-09-30
Security
- The App proxy gate matches its protected prefixes without a path boundary. Requests to
/app/<id>/…whose path starts with/admin,/user,/knowledgeor/standalonerequire a SAALT session and the user's permission on the App. The match previously required a/or the end of the path after the prefix, so React Router's single-fetch data URLs (/user.data,/admin.data) reached the App without the permission check. The gate now also classifies the URL actually forwarded to the App rather than the raw request path, rejects any path containing an ASCII control character with400, and logs every rejected request. For App authors: a route whose path merely begins with one of these words —/user-sync,/knowledgebase-hook— is now session-gated too; give machine-to-machine routes a path outside these prefixes. See Standalone Apps.
Fixed
- OpenAI models' interim "commentary" text no longer appears in answers. The OpenAI Responses API marks the model's working notes with a
commentaryphase; a model middleware now drops those text parts from both streamed and non-streamed output, so they reach neither the chat nor the REST, gateway or Bridge responses. - The tool-call group could crash the chat with Maximum update depth exceeded when its label changed repeatedly.
v1.4.7 — 2026-09-30
Fixed
- OpenAI commentary text appeared as part of the answer in the embedded chat widget. The chat UI now renders it as reasoning, which the widget hides — v1.4.8 then removes it before it reaches any client.
- The user CSV export is sorted consistently.
v1.4.6 — 2026-09-29
Breaking
- Web search now runs on Tavily. The
core__webSearchtool uses Tavily instead of Google Custom Search and is registered only when web access is enabled for the Agent andTAVILY_API_KEYis set.GOOGLE_CUSTOM_SEARCH_API_KEYandGOOGLE_CUSTOM_SEARCH_ENGINE_IDare no longer read — a deployment that only sets those loses the tool without an error. Reading a given URL (accessWeb) is unaffected.
Added
- Resumable chat streams. The user's message is persisted when the stream starts and the reply is kept server-side, so reloading the page or returning to a conversation picks up a reply that is still being generated. Stopping a reply now keeps the text produced so far instead of discarding it.
- Agents can look at the images they produce in code execution — charts and renders created in the sandbox can be viewed by the model to check and refine its own output, OpenAI-compatible models included. Images viewed only for that purpose are not shown in the conversation. See Code execution.
saalt_instance_urlrequest header — Core now sends the public address of the instance to Apps alongsidesaalt_session_tokenandsaalt_server_url, on view, tool, cron and knowledge requests. See Standalone Apps.- Uploading a Skill without a name or description asks for them instead of failing, and malformed frontmatter is handled.
Changed
- A model's security tier comes only from its explicit
securityTier.regionis no longer consulted; a model without a valid explicit tier is classifiedus-cloud. - Users without a Space land on their personal Agent after sign-in.
- Text copied from a chat answer is stripped of invisible Unicode artefacts.
- Tool components rendered by Apps are no longer collapsed into the tool-call group, and the Set Availability dialog for Apps gained a search and a scrolling Agent list.
Fixed
- Web access misread
text/xmlresponses as HTML and returned empty content. - Document parsing detects a file's character set from the whole file rather than its beginning.
- A stream that ends for an unexpected reason is reported as an error instead of ending silently.
v1.4.5 — 2026-09-23
Changed
- Section summaries (RAPTOR) are disabled by default. Automatic and manual index builds, the build worker and retrieval-time summaries all check one instance-wide switch,
RAPTOR_ENABLED, which is off unless set totrue. Jobs already queued are drained without running, and the Knowledge Index tab tells users the feature is currently disabled. This is a temporary measure; leaf-chunk retrieval is unaffected. See Knowledge.
v1.4.4 — 2026-09-23
Added
- Projects — private, user-owned Agents (
flavor: PROJECT) for organising your own work. Each Project keeps its chats, files (Knowledge) and instructions together, is visible only to its owner and is listed under Projects in the sidebar. Chats can be moved between the personal Agent and Projects via Move to project. Projects are available while personal Agents are enabled. See Projects. - Model replacements from the config API — an admin-managed map from a retired model key or
modelIdto its current successor. Whenever a stored key no longer resolves, Core follows the map, so retiring a model no longer breaks every Agent, App or user preference that still references it.
Fixed
- Switching an existing conversation to an Anthropic model could be rejected because of reasoning blocks produced by a different provider earlier in the conversation. Reasoning is now stripped from every earlier assistant turn before the history is replayed, including chains of consecutive turns from mismatched models.
v1.4.3 — 2026-09-22
Added
- Sampling controls on the OpenAI-compatible gateway —
POST /chat/completionsacceptstop_k(clamped to 1–64) alongsidetemperatureandtop_p. Each of the three is dropped per model where the model's configuration marks it unsupported, as reasoning models require, instead of failing the request. See OpenAI-compatible API. - Session grouping on the gateway — an
X-Session-Idorx-litellm-session-idrequest header is forwarded as the session id for usage tracking, so a client's turns group together. Requests without either header are not grouped. - User export as CSV for super admins, from the permissions screen.
INTERNAL_APP_URL— the base URL Core hands to Apps whose target is only reachable inside the deployment's own network (in-cluster service names,.local/.internalhosts, private IP literals), so their bridge calls come back over the internal network rather than the public one. Defaults toAPP_URL.
Changed
- Code execution is on by default. New Agents are created with it enabled, and for personal Agents a policy saved without an explicit value now means enabled rather than disabled; an administrator can still switch it off centrally. See Code execution.
- Agents carry an explicit kind.
agent.isPersonalis replaced byagent.flavor(AgentFlavor:AGENTfor Space Agents,PERSONALfor a user's personal Agent,PROJECTfor other user-owned Agents), enforced by a check constraint that ties the kind to ownership; the at-most-one-personal-Agent-per-user index now keys off the kind. Existing personal Agents are backfilled. - Web access reads the main content of a page rather than the whole document, dropping navigation, footers and other boilerplate before the text reaches the model.
- The public Agent embed shows a model's display name instead of its key, and MCP connections surface the provider's real OAuth error and report a server as unreachable only when both transport attempts failed.
v1.4.2 — 2026-09-16
Fixed
- The New Agent view could crash right after the creation animation when using Custom Setup, from an effect callback whose return value was mistaken for a cleanup function.
v1.4.1 — 2026-09-16
Fixed
- A permission check on
/app/<id>/*App sub-paths was checking every request, when only/admin,/user,/knowledgeand/standaloneare meant to require a SAALT session. Everything else under an App's path — its own API routes, OAuth callbacks, inbound webhooks — is meant to authenticate itself (API keys, OAuthstate, signatures), which is the contract Apps were built against before v1.4.0. Unauthenticated and third-party calls into those routes were rejected with 401 until this was scoped back correctly. - A globally-enabled App did not run for user-owned personal Agents, because
getAgentIdsForPluginexcluded them from the "global" set while the tool-availability check that decides whether an Agent runs the App's tools did not — so a personal Agent could call the App's tools but the bridge token'sagentIdallowlist did not include it, and every agent-targeted call 403'd. Global now means every Agent, personal ones included.
v1.4.0 — 2026-09-15
Added
- Skills marketplace — Skills now carry a provenance:
skill.source(CUSTOM,DEFAULTorMARKETPLACE),skill.providerandskill.sourceId, plusskill.creatorType(SAALTorUSER) andskill.creatorId. Marketplace Skills are installed by scoping a published Skill to a Space or Agent throughskill_availabilityrather than by copying it, and uninstalling removes that availability. Marketplace entries are archived instead of deleted, a Skill's live version is pinned by anactiveVersionIdforeign key ontoskill_version, duplicate Skill names are rejected, and a zip import is fetched through the safe-fetch path. The default code-execution Skills are seeded locally at startup. See Skills. - Speech input in chat — dictate a message instead of typing it, with the transcript streaming into the composer as it is recognised.
- Model security tiers — every model resolves to one of three tiers, ordered most to least trusted:
secure(SAALT's own hosting region),eu-hosted(any other EU region) andus-cloud(everything else). The tier is taken from an explicitsecurityTiersupplied by the config API and otherwise inferred fromregion; anything unclassifiable fails closed tous-cloud. Capability tags such asdeep_researchare never consulted. The model selector shows the tier, warns when a switch moves to a less-trusted one, and displays a price indicator in euro.ModelInfoalso gained a freeformlocationLabelfor display, which must not be used for classification — see the Bridge reference. - Remote sandbox driver for code execution —
SANDBOX_DRIVERnow acceptsremotealongsidedocker,kubernetesandopenshift, so sandboxes can run on a dedicated host instead of the cluster that runs SAALT. The switch falls back to the container-appsAPP_CONTAINER_DRIVERfor deployments that already schedule containers, and the sandbox stays dormant unless a driver is set. Limits (CPU, disk, idle and hard timeouts, image) are configured per deployment. - Permission-group membership is managed inside the group — members can be added and removed from the group's own screen instead of only per user.
Changed
- Compaction now also runs mid-stream, not only between turns;
conversation.firstKeptPartIndexrecords the boundary inside a partially kept message, so a long single response can be compacted without discarding the whole turn. - Search jumps to the point in the conversation where the match occurs instead of opening it at the top, and the dialog gained a default height and a debounce.
- More than three files returned by a code-execution sandbox render as a table rather than a list, and the sidebar's collapsed state is remembered in a cookie.
Fixed
- Newly created Agents could be locked out of every App with a 403. The plugin-token allowlist was cached in Redis under a key with no expiry, so an Agent created after the cache was populated never appeared in it. The cache is now invalidated whenever an Agent is created or deleted.
- Social login failed with
account_not_linkedfor existing users. SAALT has no email-verification flow, souser.emailVerifiednever carried meaning, but Better Auth refuses to implicitly link a trusted Google or Microsoft account to an unverified user. Existing users are backfilled as verified.
v1.3.5 — 2026-09-09
No functional changes. This release carries deployment configuration only; the platform behaves identically to v1.3.4.
v1.3.4 — 2026-09-07
Changed
- Failed document conversions report with structured diagnostic context. When a document cannot be parsed, the error report now carries the document id, file name, extension and whether an LLM was configured for the run — and, where the converter chain itself raises the failure, one entry per converter that was tried, each with its own error type and message. Reports are fingerprinted on the converter chain, so repeat failures of the same kind group together instead of arriving as unrelated errors. Reporting requires a Sentry DSN to be configured; nothing changes about how documents are parsed.
v1.3.3 — 2026-09-02
Fixed
- Cached input tokens are priced more accurately in the usage figures. The cost shown in usage reporting is derived from the token counts on
llm_invocation. Providers reportinputTokensas the full total, with cached reads already counted inside it, so applying the standard input price to that total and then adding the cached portion on top overstated the calculated cost. The standard price now applies only to the non-cached remainder. Where a model's config carries no explicitcachedInputprice, cached reads fall back to 10% of the input price — in line with how providers such as Anthropic price prompt caching — rather than the full input price.
v1.3.2 — 2026-09-01
Added
- Conversation context compaction — long conversations are summarised into a durable checkpoint instead of being rebuilt on every turn.
conversation.firstKeptMessageIdmarks the boundary between the summarised prefix and the messages still sent verbatim; the checkpoint is written once when the conversation exceeds its token budget and reused by every later turn, and attachments before the boundary are replaced by a note. This replaces the previous background job that regenerated a rolling summary after each reply, so the request prefix stays stable and remains eligible for provider prompt caching between turns. The migration clears all legacyconversation.summaryvalues. Compaction attempts are tracked alongside the stream. - Delete a single message from an Agent's conversation history, from the conversation detail view in the Agent's space.
- Chat shows a note while conversation tracking is active, so a user can see when an Agent admin is able to review the conversation. Suppressed for incognito conversations, which are stored but hidden from everyone, Agent admins included. See Chat.
- Superadmins can delete their own account, behind a danger confirmation and a sign-out flow. A new guard (
superAdminGuard.server.ts) prevents removing the last superadmin, or stripping theglobal.super_adminscope from the last permission group that grants it. - Invitations record who sent them —
invitation.invitedById, nulled if that user is later deleted.
Changed
- Search — hits render their markdown instead of showing raw syntax, the dialog was reworked with skeleton loading and mobile styles, and single-character queries no longer run.
- Spaces and Agents carry a shared or private label in the overview, and subagents inside a space now appear in the Integration Availability overview.
- The default Agent system prompt was trimmed, and new Agents get a short default description instead of an empty one.
- App settings modals are wider, the sidebar collapse is animated, password inputs have a show/hide toggle, and the browser's native
window.confirmwas replaced by the in-app confirm dialog.
v1.3.1 — 2026-08-25
Changed
- Attachments that are neither images nor PDFs download directly instead of opening in a new tab.
- Tool-call groups show truncated labels with improved taglines, updated labels for code tool calls, and more room in the message body.
streamTexttelemetry is reported when a Sentry DSN is configured.
Fixed
- Chat scrolling and jumping — the long-message clamp is relative to the viewport, the view no longer resets after streaming finishes, a spacer keeps message height consistent, height is recalculated once the on-screen keyboard has settled on iOS, and a small jump on tool calls in Safari is gone.
- The loading indicator is hidden once streaming starts and no longer disappears in some states; the typewriter effect is back.
v1.3.0 — 2026-08-19
Added
- Skills — a reusable, versioned procedure an Agent follows for a recurring task: the instructions plus the templates and files it needs. Backed by
skill,skill_versionandskill_blobtables with aSkillStatuslifecycle and per-provider references (skill_version_provider_reference);skill_availabilityrows scope which Agents may use a Skill. Uploaded resources are stored as blobs and handed to the Agent at execution time. - Code execution — Agents can run code over uploaded files and larger datasets in an isolated sandbox and return the result as a table, chart or report. Execution state is tracked per conversation in
conversation.codeExecutionState. - Container Apps — an App can ship as a container image instead of only a proxied URL.
installed_pluginsgains atypediscriminator (PluginType) pluscontainerImage,containerPortandlastError; registry credentials live in the newcontainer_registry_credentialstable. See Apps. - Usage attribution and reset countdown —
llm_invocation.isIncludedUsageseparates subscription-covered calls from billable ones, and the usage limit now shows when the current window resets.
Changed
- A new model selector in chat, and an updated analytics page.
- The browser's native file API is used where available, with a fallback otherwise.
- Cloning an Agent carries its full configuration, and per-Agent model overrides apply consistently.
Fixed
- Cross-user conversation disclosure in the generate endpoints — a supplied conversation id is now validated against the requesting user. Previously an id belonging to another user, or an arbitrary id against a public Agent, could read back that conversation's history.
- Provider reasoning-item references are stripped when a turn is trimmed from history, so OpenAI-family models no longer fail on a truncated reasoning chain.
- Token usage is recorded for streamed conversations.
v1.2.4 — 2026-08-10
Fixed
- Editing an App's URL now invalidates the cache across all replicas, instead of only the one that served the edit.
- Provider-specific tool metadata is stripped from message history before it is replayed to a model.
v1.2.3 — 2026-08-10
Added
- Time-based usage quotas — per-user usage windows (
user.usageWindowStartedAt) with weekly limits and reported overage. - Sampling controls (
temperature,top_p,top_k) can be disabled per Agent.
Changed
- Personal Agents save a model change automatically.
- Memory is not applied to API-driven streaming conversations; that path stays a raw model call.
Fixed
generateTextandgenerateObjectin the core API rejectsystem-role messages instead of accepting them silently. See the API reference.- Spacing around rendered tool calls in chat.
v1.2.2 — 2026-08-03
Added
- Instances running without outbound connectivity fetch a default configuration.
Fixed
- An App's identifier is updated on refresh, so a renamed App keeps resolving.
v1.2.1 — 2026-08-03
Added
- Mermaid diagrams render in chat. See Chat.
- MCP re-authentication — expired MCP OAuth grants are detected and surfaced, with error handling around the OAuth status check.
- An App's URL can be edited after installation. See Apps.
Fixed
- Aborted response streams are handled without leaving the turn in a broken state.
- Image-generation cost is reported correctly in usage analytics.
v1.2.0 — 2026-07-03
Added
- Memory — durable per-Agent, per-user facts carried across conversations, so answers stay relevant without re-explaining context each time. Personal (per-user) and shared (agent-wide) memories are stored separately and capped per bucket, gated by the Agent's
memoryEnabled/sharedMemoryEnabledsettings; a background pass consolidates and safety-screens entries before they are stored. See Memory. - Standalone Apps — Apps can run agent-less and full-page as their own destination, rather than always attached to an Agent's chat. Declared with
standalone: trueplus a stableidin the App's/meta, served under/app/{id}, and given a standalone-scoped Bridge (noagentId— agent-targeted Bridge calls are rejected). See Standalone apps. - OpenAI-compatible API — a gateway at
/api/openai/v1that speaks the OpenAI format, so existing OpenAI SDKs and tools work against SAALT with minimal changes. Implementschat/completions(streaming, tool calls, and token usage),models, andembeddings, plus a SAALT-specificrerankextension. Authenticate with an API key viaAuthorization: Bearerorx-api-key. See OpenAI-compatible API. - Personal agents — user-owned Agents (
isPersonal) scoped to a single user, alongside shared team Spaces; each user gets a personal chat Agent scaffolded automatically. - Conversation API — REST endpoints to list and continue conversations and read their messages:
GET/POST /llm/{agentId}/conversationandGET /llm/{agentId}/conversation/{conversationId}/messages. Conversation search is backed by Postgres trigram and full-text indexes. See the API reference.
Changed
- Rewritten Chat experience — an in-chat Agent switcher, drag-and-drop / paste file uploads, conversation search, per-Agent model preference, and deep-research progress indicators. Chat routing moved to
/space/{spaceId}/agent/{agentId}; the legacy/chat/{agentId}path redirects. See Chat.
This is the first published SAALT Core release entry. Full historical core release notes will follow. For the current API contract, see the API reference.
Bridge — @open-agent-kit/bridge
Release notes for the TypeScript SDK that Apps use to talk to SAALT Core. See Bridge SDK reference for the current method surface.
v1.2.0 — 2026-08-03
First stable 1.2.0 release — the standalone-bridge rework: bind-once scope, transcription, agent-less LLM generation, and conversation listing. Install with npm i @open-agent-kit/bridge. Changes below are relative to the previous stable release, v1.0.8.
Breaking
createBridgenow binds scope once at construction —createBridge({ token, serverUrl, agentId? }). Per-callagentIdarguments were removed fromconfig,pluginData,knowledge,conversation,agent, andllm.getAvailableModels; the scope is taken from the bridge instance instead.- Agent-only namespaces (
knowledge,conversation,agent,llm.getAvailableModels) throw on a standalone (agent-less) bridge.
Added
- Standalone (agent-less) bridge support — omit
agentIdwhen constructing to talk to SAALT Core without an Agent scope. - Exported
BridgeScopetype:{ type: "agent"; agentId } | { type: "standalone" }. llm.transcribe(params)— speech-to-text over an audio/video clip via Gemini. Params:model,audioBase64,mimeType, optionalprompt; returns{ text }. Works on both standalone and agent-scoped bridges.llm.generateText,generateObject, andgenerateImagenow run on a standalone bridge (no agent required); the model resolves to the instance-wide default.conversation.findMany(filter)— list an agent's conversations with an optional Prisma-style filter (where/select/orderBy/skip/take/cursor), returning a bareConversation[]. Message bodies are not included (usefindFirstper conversation, as they can be large); incognito and private conversations are never returned, and archived ones are excluded by default. Requires an agent-scoped bridge. See thebridge.conversationreference.llm.getAvailableModelsnow also returnsmodels: ModelInfo[]alongsidedefaultModelandavailableModels— the full metadata (key,modelId,displayName,provider,region,tags,pricing, …) for each allowed model, so a picker can show names and badges instead of raw keys.
Changed
- Forwarded proxy headers renamed:
oak_session_token/oak_server_url→saalt_session_token/saalt_server_url(plus a newsaalt_base_path). - The SDK's admin API base path moved to
/api/v1/bridge. The legacy/api/v1/adminbase path 307-redirects for backwards compatibility.
v1.0.8 — 2026-06-26
Added
bridge.llm.generateSpeech(params)— text-to-speech via Gemini TTS. Returns{ base64, mimeType }for the synthesized audio. Supports a single prebuiltvoiceNameor a multi-speakerspeakersarray (up to 2 speakers, each mapping a speaker label to a voice).
Breaking
- None.
v1.0.7 — 2026-06-25
Added
bridge.llm.getAvailableModels(agentId)— returns{ defaultModel, availableModels }for the Agent so Apps can gate model selection to what the Agent actually allows.
Changed
bridge.llm.generateImagenow accepts an optionalimageConfig(aspectRatio— one of1:1,4:3,3:4,16:9,9:16;resolution—1K,2K, or4K) and an optional inpaintingmask(a data URL). Existing calls without these fields are unchanged.
Breaking
- None.
v1.0.6 — 2026-05-26
Added
bridge.agent.getAgent(agentId)— returns{ id, name, model }for the given Agent so Apps can render the configured LLM model or display name. Token-scoped: the call returns403if the App's bearer token does not include the requestedagentId.
Breaking
- None.
v1.0.5 — 2026-05-26
Changed
- Raised the undici dispatcher
headersTimeoutfrom 30 minutes to 60 minutes so long-running LLM and file-parse calls don't time out at the SDK transport layer.
Breaking
- None.
v1.0.4 — 2026-05-08
Added
bridge.knowledge.attachTagToDocument(agentId, documentId, tagId)— attach an existing knowledge tag to a document.bridge.knowledge.removeTagFromDocument(agentId, documentId, tagId)— detach a knowledge tag from a document.
Breaking
- None.
v1.0.3 — 2026-05-08
Added
bridge.knowledge.createTag(agentId, tag)— create a knowledge tag for an agent.bridge.knowledge.listTags(agentId)— list knowledge tags for an agent.bridge.knowledge.updateTag(agentId, tagId, updates)— update a knowledge tag's name or color.bridge.knowledge.deleteTag(agentId, tagId)— delete a knowledge tag.- Types:
KnowledgeTag,KnowledgeTagInput,KnowledgeTagUpdate.
Breaking
- None.
v1.0.2 — 2026-04-01
Changed
- HTTP requests now use a custom
undiciAgentdispatcher with a 30-minute headers timeout, so long-running LLM calls aren't cut off by Node's default fetch timeout.
Added
undici ^7.24.6runtime dependency. Node 18+ ships with undici, but Apps must allow it as a transitive dep.
Breaking
- None.
v1.0.1 — 2026-03-25
Added
- Package
README.mdwith installation snippet and a namespace reference table.
No code or API changes in this release.
Breaking
- None.
v1.0.0 — 2026-02-09
Initial public release of @open-agent-kit/bridge.
Added
createBridge({ token, serverUrl })factory andOAKBridgereturn type.decodeToken(token)helper for inspecting the forwarded session token.Toolsclass for registering an App's Tools, with exportedToolandToolExecuteParamstypes.- Bridge namespaces:
bridge.data.config,bridge.data.pluginData,bridge.llm,bridge.files,bridge.knowledge,bridge.conversation,bridge.user. PluginMetatype and re-exportedFilePart/ImagePart/TextPartfrom@ai-sdk/provider-utils.- Runtime dependencies:
zod,zod-from-json-schema,zodex.
Breaking
- None (initial release).