Repository navigation
Releases: no-problem-dev/swift-llm-cloud
Release list
6.1.1
Changed
mapAPIErrorToLLMErrornow says why it has nodefault:, and what the nextAPIErrorcase maps
to. swift-api-client 6.0.0 addsemptyResponseBody(statusCode:outputType:), which this switch
does not handle, so raising the pin breaks the build — confirmed rather than assumed: compiled
the same switch against the 6.0.0 source and goterror: switch must be exhaustive. No
default:was added. The build break is the mechanism, the oneLLMError.isRetryablealready
documents for its own switch, and no fallback would be right:unknown(_:)drops whatever the
new case carries, and every other case claims something specific that the retry policy then acts
on.@unknown defaultwas measured too — it downgrades the error to a warning, and a warning
does not failswift test, so the wrong mapping would ship in silence. The pin is
from: "5.0.0", so nothing resolves 6.0.0 until someone raises that line; the one-line addition
belongs in that same edit, and it iscase .emptyResponseBody: return .emptyResponse.
6.1.0
Added
GeminiClient.logsandOpenAIClient.logsexpose what the HTTP layer reports for their calls,
including the raw SSE chunks of a stream. The events a caller receives are already parsed and
accumulated, which loses the bytes inside adata:line and where one chunk ended — the only
evidence for whether a model wrote a trailing newline itself or a chunk boundary merely looks
like one. For OpenAI this is the Responses engine's feed, since every streaming call is routed
there. Reading it is opt-in; nothing buffers until you iterate.
Fixed
scripts/compute-next-version.shcounted a defaulted parameter as a removal. Ported from
swift-http-transport 2.2.1, with its regression test.
6.0.0
Changed
- Adopts swift-api-client 5.0.0, swift-llm-client 5.0.0 and swift-http-transport 2.1.0. A 403 maps
toLLMError.unauthorizedalongside 401 — that case's own doc already covers both ("missing,
wrong, or not allowed to reach this model"), neither is retryable, and both are fixed by changing
the credential or the plan. - The
APIError.invalidResponsearm of the error mapping is gone. It was dead: upstream never
constructed the case, so the condition always arrived asTransportError.invalidResponseinside
.networkError, and the branch's"Invalid URL or response"message described something it
never handled.
Changed
- Raised the swift-api-client pin to 5.0.0 and the swift-http-transport pin to 2.0.0. 4.0.0 of
api-client cannot resolve alongside http-transport 2.x — its own pin bump did not land until
5.0.0 — and 5.0.0 is also the release that boxes the injected transport in
AnyStreamingTransport, which is what keepsAPIClientImpl's existential transport working
now thatRetryingTransportis generic. Nothing this package names changes. mapAPIErrorToLLMErrortakesAPIError's new shape..forbiddenjoins.unauthorizedon
LLMError.unauthorized, which already means "the API key is missing, wrong, or not allowed
to reach this model" and is what every provider contract here already returns for both 401
and 403; neither is retryable and both are fixed by changing the credential or the plan
behind it..conflictingAuthHeaderbecomesinvalidRequest, since the request is refused
before it is sent.- The
invalidResponsearm is gone with the case. It was never reachable:APIErrornever
constructed it, and the condition has always arrived asTransportError.invalidResponse
inside.networkError, which is where it still arrives.
5.0.0
Fixed
generateWithUsageandgeneraterecursed forever on every cloud client. Both were
unreachable at run time onAnthropicClient,GeminiClient,OpenAIClient,DeepSeekClient,
GroqClient,MistralClient,OpenRouterClientandXAIClient— a call never returned, and
the process grew until it was killed. The requirement in llm-client 3.x took
systemPrompt: SystemPrompt?while every implementation here declaredsystemPrompt: String?,
so none of them witnessed it. The convenience method beside the requirement — same signature,
optional arguments defaulted — witnessed it instead and called straight back into itself. It
compiled, and no test called either method, so nothing ever said so. llm-client 4.0.0 gives the
requirement a distinct signature, which turned this into a compile error and is how it was
found. Confirmed against 3.13.0 in a throwaway package: 85 GB of memory before the kernel
killed it, with neither implementation ever entered.
Removed
-
BREAKING — the methods that implement llm-client's protocol requirements now take an options
value instead of a list of optional arguments, following llm-client 4.0.0. Gone from the
public API:Type Removed AnthropicClient,GeminiClientgenerateWithUsage(input:model:systemPrompt:temperature:maxTokens:),generateWithUsage(messages:model:systemPrompt:temperature:maxTokens:),chat(messages:model:systemPrompt:temperature:maxTokens:)OpenAIClient,DeepSeekClient,GroqClient,MistralClient,OpenRouterClient,XAIClientthe same three, inherited from OpenAICompatibleClientProtocolGeminiClient,OpenAIClientgenerateImage(input:model:size:quality:format:n:),generateImages(input:model:size:quality:format:n:),startVideoGeneration(input:model:duration:aspectRatio:resolution:)OpenAIClientgenerateSpeech(input:model:voice:speed:format:)Each is replaced by a form taking
GenerationOptions,ChatOptions,ImageGenerationOptions,
VideoGenerationOptionsorSpeechGenerationOptions.Most call sites need no change. llm-client still supplies the same argument lists as
convenience methods with defaults, soclient.generateImage(input:, model:, size: .square1024)
andclient.chat(messages:, model:, systemPrompt: "…")still compile and now reach a real
implementation. What breaks is passing aStringvariable asgenerateWithUsage's system
prompt: the surviving overload takesSystemPrompt, which a string literal converts to but a
Stringdoes not — wrap it asSystemPrompt(stringLiteral: text)or pass the literal directly.
Code that conformed its own type to these protocols by forwarding to a cloud client must adopt
the options-taking signatures too, or it will no longer conform.
Changed
- Raised the floors to llm-client 4.0.0, swift-structured-data 3.0.0 and swift-api-client 3.0.3,
and added a direct dependency on swift-http-transport 1.1.2. api-client 3.0.3 stopped
re-exportingHTTPTransport, and this package namesHTTPTransport,HTTPStreamingTransport,
URLSessionTransportandSSEEventinternally, so it now depends on and imports that module
itself. None of those types appear in this package's public API, so nothing is asked of
consumers beyond resolving the new floors.