# Upgrade from 0.x to 1.0

> **Upcoming in 1.0 (preview). These pages describe the main branch of LLMSlim Core, which becomes the 0.13 release candidate and then 1.0. `pip install llmslim` installs 0.12.0 today, which doesn't have everything described here.** Docs for what pip installs: https://www.llmslim.app/docs.md

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

The breaking and default changes between LLMSlim 0.12 and 1.0: Python 3.10, date_format defaulting to None, narrower __all__ lists, planner_version, keyless servers, and what is new.

Category: Migration · Version: 1.0 · Updated: November 2026 · 7 min read

## 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.

terminal:

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

> **Pin before you depend on it:** Main changes between releases. For anything that matters, wait for the release candidate or pin a commit: `@git+https://github.com/Thanatos9404/llmslim@<commit>`.

## Checklist

In the order you are likely to meet them:

- Python 3.10 or newer ([below](https://www.llmslim.app/docs/1.0/migrate-to-1-0#python)).
- `Memory.search` shows a session's date once ([below](https://www.llmslim.app/docs/1.0/migrate-to-1-0#date-format)). 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](https://www.llmslim.app/docs/1.0/migrate-to-1-0#all)).
- `planner_version` is the release ([below](https://www.llmslim.app/docs/1.0/migrate-to-1-0#planner-version)): trace ids change in every release.
- A keyless `llmslim serve` or proxy answers only to this machine's names ([below](https://www.llmslim.app/docs/1.0/migrate-to-1-0#keyless-servers)).
- Database outages are a 503, not a 500 ([below](https://www.llmslim.app/docs/1.0/migrate-to-1-0#errors)).

## 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.py:

```python
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 default:

```text
[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](https://www.llmslim.app/docs/1.0/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.py:

```python
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](https://www.llmslim.app/docs/1.0/api-stability#semver)). 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`](https://www.llmslim.app/docs/1.0/import-history): Claude Code, ChatGPT, Claude.ai, Mem0 and JSONL history, in one command.
- [`explain=True`](https://www.llmslim.app/docs/1.0/explain): why each turn was kept, cut or left out.
- [MongoDB](https://www.llmslim.app/docs/1.0/storage-backends#mongodb) as a memory store.
- [An OpenAI-compatible chat endpoint](https://www.llmslim.app/docs/1.0/openai-compatible-endpoint) in `llmslim serve` (experimental).
- [Remote MCP](https://www.llmslim.app/docs/1.0/remote-mcp): `llmslim mcp --transport http` (experimental).
- Mastra tools and an output processor in the [TypeScript client](https://www.llmslim.app/docs/1.0/quickstart-typescript#mastra) (already on npm as 0.2.0).
- Release files attested with SLSA build provenance and an SBOM; `SECURITY.md` shows how to verify them.

## FAQ

### 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](https://www.llmslim.app/docs/1.0/api-stability).

## Related

- [API stability](https://www.llmslim.app/docs/1.0/api-stability.md)
- [Migrate from Mem0](https://www.llmslim.app/docs/1.0/migrate-from-mem0.md)

Canonical page: https://www.llmslim.app/docs/1.0/migrate-to-1-0
