Skip to main content

Upgrade from 0.x to 1.0

What changes from 0.12, what to do about it, and how to try 1.0 before it ships.

7 min readUpdated November 2026New in 1.0

Try 1.0 before the release

pip install llmslim installs 0.12.0 until 1.0 is on PyPI. These pages describe the main branch, which becomes the 0.13 release candidate and then 1.0. To try it now, install it from GitHub. It reports its version as 0.12.0 until the release changes it.

terminalbash
pip install "llmslim @ git+https://github.com/Thanatos9404/llmslim"
pip install "llmslim[mcp,server] @ git+https://github.com/Thanatos9404/llmslim"   # with extras

Checklist

In the order you are likely to meet them:

  • Python 3.10 or newer (below).
  • Memory.search shows a session's date once (below). If you compare its text to recorded output, pass date_format="%Y-%m-%d" or record it again.
  • Some helper names left the __all__ lists of integration modules and llmslim.server (below).
  • planner_version is the release (below): trace ids change in every release.
  • A keyless llmslim serve or proxy answers only to this machine's names (below).
  • Database outages are a 503, not a 500 (below).

Python 3.10 or newer

1.0 requires Python 3.10. Python 3.9 reached end of life in October 2025, and the MCP server and most framework extras already needed 3.10. On Python 3.9, pip keeps installing 0.12.0, so nothing breaks by surprise; the public API doesn't change. The extras lose their python_version markers.

A session's date is shown once

When Memory.search selects from a long history, the first kept turn of a session shows its full stamp, and so does a later turn whose time differs from the one shown last. Any other kept turn used to repeat the date, [2026-10-17] assistant: ...; it now shows assistant: ... alone, under the stamp above it. date_format now defaults to None. The repeated date was most of each kept turn's label, so more turns fit. A history that fits the budget whole still shows the full stamp on every turn.

date_format.pypython
from llmslim.memory import Memory

memory = Memory("memory.db")                          # 1.0: role: text under the session's stamp
memory = Memory("memory.db", date_format="%Y-%m-%d")  # the labels of 0.12, byte for byte
1.0, by defaulttext
[2026-10-17 (Sat) 14:05] user: I'm planning a trip to Jaipur in December for my sister's wedding.
assistant: ... Congratulations! December is a lovely time to visit Jaipur.
user: Which hotels near the City Palace would you suggest?
0.12, or 1.0 with date_format="%Y-%m-%d"text
[2026-10-17 (Sat) 14:05] user: I'm planning a trip to Jaipur in December for my sister's wedding.
[2026-10-17] assistant: ... Congratulations! December is a lovely time to visit Jaipur.
[2026-10-17] user: Which hotels near the City Palace would you suggest?

Stored text still can't pass for a label: where a label can be the role alone, a line in a code block or table that starts with user:, assistant:, system: or tool: is indented by two spaces. With a date_format string, only dated lookalikes are indented, as before.

Narrower public lists

Before 1.0 freezes the public API, these names left __all__. They stay importable from the modules that define them, but they are internal now, so a later release may change them:

  • llmslim.server exports create_app and main (and the experimental ChatUpstream); api_keys_from and is_loopback are internal.
  • llmslim.integrations.web_search exports WebSearchSource, WebSearchResult and their errors; its 20 helper functions and limits are internal.
  • llmslim.integrations.sarvam keeps its documented classes and functions, their result types and errors (35 names, down from 42). Its guard prefixes, default limits and sarvam_chat_cost_inr are internal, and it no longer re-exports the text and document limits. sarvam_text and sarvam_documents keep their documented names.
  • llmslim.planning.planner.PLANNER_VERSION and llmslim.planning.progressive.PLANNER_VERSION still import, but left those modules' __all__.

llmslim.tokens, llmslim.mcp and llmslim.integrations.openai_agents now declare __all__, without renaming or removing anything. A star import (from module import *) gets only what __all__ lists. API stability says what is public.

planner_version is the release

PlanMetrics.planner_version and ContextTrace.planner_version were fixed at "0.7.0" ("0.6.0" for plan_context) since 0.7.0, though planner output changed in later releases. They are now llmslim.__version__, read when the plan is made. ContextTrace.trace_id is derived from the envelope and this version, so the same envelope gets a new trace id in each release. If you stored trace ids or compared planner_version to a constant, compare to the release instead.

planner_version.pypython
import llmslim
from llmslim import plan_context

plan = plan_context(messages=[{"role": "user", "content": "Hello"}], model="sarvam-105b")
assert plan.metrics.planner_version == llmslim.__version__  # 0.12 said "0.6.0" here

Keyless servers answer only to this machine

A server on 127.0.0.1 is reachable from any page the user opens: a cross-site request could store a planted instruction in memory, and DNS rebinding let a page read and delete every memory. So a keyless llmslim serve and the llmslim proxy now answer only requests whose Host names this machine (localhost, a *.localhost name, 127.0.0.0/8, [::1]) and refuse with a 403 any request whose Origin is another site. Clients that send no Origin, such as curl, SDKs and agents, aren't affected.

  • If clients reach a keyless server by another name (host.docker.internal from a container, say), add it with --allowed-host (repeatable; * for any), LLMSLIM_ALLOWED_HOSTS or create_app(..., allowed_hosts=[...]).
  • Servers with API keys accept any Host as before, unless you pin names the same way.
  • The proxy takes --allowed-host and create_proxy_app(..., allowed_hosts=[...]).

Cleaner errors from servers

When Postgres or MongoDB can't be reached, llmslim serve answers a 503 with "type": "store_unavailable" and Retry-After: 5 (0.12 answered a plain-text 500), and recovers by itself when the database is back. Any other failure in a route is a JSON 500, "type": "server_error". llmslim serve and llmslim mcp exit at start with one line when the store can't be opened. Hostile JSON (too deep, wrong types, out-of-range times, a lone surrogate) is a 400, and Memory.add refuses a timestamp with no UTC time with a ValueError.

Output that changes

Which turns search keeps is output content, which a minor release may improve (see API stability). Between 0.12 and 1.0:

  • a reply short enough to be one window inherits its session's relevance, as a user turn does, so conversations between two people stored as user and assistant keep more of the second speaker's turns;
  • fit (/v1/context/fit, fit_context) stays within about 2% of its budget for any text: when compression can't get there (one long code block, say), the result is cut to the longest head that fits the budget;
  • the Docker image installs the Postgres and MongoDB drivers.

What's new

Each has its own guide:

  • llmslim import: Claude Code, ChatGPT, Claude.ai, Mem0 and JSONL history, in one command.
  • explain=True: why each turn was kept, cut or left out.
  • MongoDB as a memory store.
  • An OpenAI-compatible chat endpoint in llmslim serve (experimental).
  • Remote MCP: llmslim mcp --transport http (experimental).
  • Mastra tools and an output processor in the TypeScript client (already on npm as 0.2.0).
  • Release files attested with SLSA build provenance and an SBOM; SECURITY.md shows how to verify them.

Questions

Do I have to change my code?

Most code runs unchanged. Check the Python version, any import of a name that left __all__, any test that compares Memory.search text byte for byte, and any client that reaches a keyless server by a name other than localhost.

Will my stored memory open in 1.0?

Yes. 1.0 reads SQLite files and Postgres tables written by 0.12.

What does 1.0 promise that 0.x didn't?

Semantic versioning for the public API: no breaking change before 2.0, and a deprecation period of at least two minor releases and 90 days before anything is removed. See API stability.