Skip to content

lm15 1.0.1

Choose a tag to compare

@MaximeRivest MaximeRivest released this 25 Sep 15:23
· 67 commits to main since this release

The first stable release. pip install lm15 now installs it (no --pre).
It is 1.0.0rc3 plus the changes below.

Why 1.0.1 and not 1.0.0: a 1.0.0 was uploaded to PyPI on 2026-06-11 by
mistake and removed seven hours later (see "Re-stage 1.0.0 as 1.0.0a1"
below). PyPI never accepts a removed version number again. There is no
1.0.0 of lm15; 1.0.1 is the first stable release. Contract: lm15-contract b0ff3c0.

What 1.0 promises. The chat core is frozen for 1.x: the canonical types,
their JSON form, errors, request and response mapping, streaming, credential
resolution and model listing. Removing or changing any of it needs a 2.0.
Provisional, and allowed to change during 1.x with a contract change entry:
files, batches, image/speech/video generation, stored-cache resources, live
sessions, Chat Completions ingest, and managed sign-in (lm15.login,
connect()), whose provider permission and billing are unverified except
for xAI. Pin an exact version if you use those. See docs/roadmap.md.

  • Type checkers accept the documented calls. Request(messages=[...]),
    tools=[...], Config(stop=[...]), Message(parts=[...]) and the other
    value types that store a tuple but accept a list now say so to mypy and
    pyright (generated __init__ signatures; runtime unchanged). Before, every
    documentation example failed mypy --strict on its first Request. JSON
    inputs (response_format, tool parameters, extensions, DataPart
    values) accept an ordinary dict, since their contents are checked at
    runtime; Message.tool accepts any mapping. The transport release
    callbacks and three annotations naming unimported types are corrected.
  • No silent content loss (MAP-10, MAP-6; behaviour change). A media part
    a provider's format has no place for now raises UnsupportedFeatureError
    naming the part (feature="messages[i].parts[j]") before anything is sent.
    Before, 1.0.0rc3 sent audio, video or binary parts to Anthropic as an empty
    text block, and dropped media in assistant turns on the OpenAI formats,
    without a word. Likewise config.cache.resource on a provider with no
    stored caches (Groq, DeepSeek, Z.AI, Ollama, xAI, Meta's Anthropic door)
    raises instead of being ignored: the resource holds the start of the prompt.
  • Windows. A local path in canonical JSON (FileUploadRequest.path, media
    parts' path) is written with / on every OS, as INV-009 now says; on
    Windows it was \data\clip.mp4, so the same request serialized
    differently there. A cloud CLI's output (az, gcloud) is decoded as UTF-8
    leniently, so an unusual character in its messages cannot crash a sign-in.
  • CI: tests on Python 3.10–3.14 × Linux, macOS, Windows, with deprecations and
    text I/O that does not name its encoding as errors; a type-checking gate.

Everything else new since 1.0.0rc1 (managed authentication, R3, MAP-15, judgments, and the rc2 changes) is in the 1.0.0rc3 section of CHANGELOG.md.