Skip to content

1.0.0

Choose a tag to compare

@dioKaratzas dioKaratzas released this 02 Nov 21:52
a6f2051

Release: major

The first stable release. OpenRouter's models work through Apple's Foundation Models API, and the public API is now settled: from here on, a breaking change comes only in a new major version.

.package(url: "https://github.com/dioKaratzas/swift-language-models", from: "1.0.0")

Breaking changes since 0.9.5

  • Shared metadata moves to the core: LanguageModelMetadataKey, FinishReason, Citation and ModelReasoning. OpenRouter-only keys start with openRouter..
  • Types with a single parent are nested under it, such as OpenRouterOptions.AutoRouter and OpenRouterRouting.Sort. Closed enums become open vocabularies, and the Bool? routing settings become the Permission and Requirement enums.
  • OpenRouterProvider and providers() become OpenRouterEndpoint and endpoints().
  • LanguageModelsLogging.minimumLevel takes Apple's OSLogType, and the Pareto router's price cap is a Decimal.
  • Errors map more precisely:
    • a URLError is rethrown as it is;
    • a 504 is a timeout;
    • a spending budget that resets is rateLimited;
    • a rejected image is unsupportedTranscriptContent;
    • token_limit_exceeded gets its own OpenRouterError code.

New

  • A guided answer that breaks a guide throws a ParsingError whose underlyingError is GuideViolations, naming each value's path, keyword, value and limit.
  • OpenRouterOptions.parallelToolCalls, a price cap for the Pareto router, and the OpenRouterPlugin vocabulary.
  • The one retry of a briefly unavailable gateway waits for a Retry-After of up to 10 seconds; a longer one throws at once, with the wait on the error.

Fixes

  • Requests: the API key stays on a redirect to the same host; only the settings the app asked for are sent; .off turns reasoning off on a model that can stop reasoning, even when none isn't among its levels.
  • Answers: a guided answer cut off at the token limit throws; tool-call arguments must be a whole JSON object; reasoning goes back as the model sent it; server-sent events follow every line-break rule; whole-number guides compare exactly.
  • Logging: a host's error message stays out of the log.
  • Catalog: an update can't deprecate a model the module's own code uses, and removing a model renames no other model's static.
  • Docs: a response cache hit runs the answer's tool calls again.

Under the hood

OpenRouter's requests now go through a shared Chat Completions engine, which builds, sends, retries and streams each request, while OpenRouter adds only what its API does differently, as typed values. This changes no public API and no request: the exact bytes of each request and answer are pinned by tests. It prepares the package for more providers.

What's Changed

Breaking changes

  • feat!: settle the 1.0 API, share a provider core, and fix what the pre-release review found by @dioKaratzas in #27

Other changes

  • refactor: send Chat Completions requests through typed provider dialects by @dioKaratzas in #28

Full Changelog: 0.9.5...1.0.0