@nemesis-oss/ollama-sdk 1.0.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +154 -0
- package/README.md +402 -11
- package/dist/{compose-DC11aDJn.d.cts → compose-CDWq8oxJ.d.cts} +80 -4
- package/dist/{compose-DC11aDJn.d.ts → compose-CDWq8oxJ.d.ts} +80 -4
- package/dist/index.cjs +504 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +448 -13
- package/dist/index.d.ts +448 -13
- package/dist/index.js +498 -71
- package/dist/index.js.map +1 -1
- package/dist/skills.cjs.map +1 -1
- package/dist/skills.d.cts +2 -2
- package/dist/skills.d.ts +2 -2
- package/dist/skills.js.map +1 -1
- package/package.json +5 -4
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,160 @@ All notable changes to `@nemesis-oss/ollama-sdk` will be documented in this file
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.3.0] - 2026-08-25
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Client-side quota monitoring (`QuotaManager`).** Ollama Cloud doesn't expose
|
|
13
|
+
account-level quota through the API — no response header or endpoint reports how much
|
|
14
|
+
of your plan's session/weekly limit is left (see
|
|
15
|
+
[ollama/ollama#15663](https://github.com/ollama/ollama/issues/15663)). `QuotaManager`
|
|
16
|
+
tracks usage you record (via `recordUsage`, which reads `extractUsage`-normalized token
|
|
17
|
+
counts off a raw response) against budgets you configure over one or more rolling
|
|
18
|
+
windows, and refuses to proceed (`canProceed`/`assertCanProceed`) once a window's budget
|
|
19
|
+
is spent — a local safety net to complement, not replace, catching the server's own
|
|
20
|
+
`OllamaRateLimitError`. `createOllamaCloudFreeTierQuota` is a convenience factory
|
|
21
|
+
wiring up the free tier's documented 5-hour session and 7-day weekly window cadence
|
|
22
|
+
(you still supply the token/request budgets, since Ollama doesn't publish the actual
|
|
23
|
+
ceilings). New `OllamaQuotaExceededError` (`code: 'quota_exceeded'`) is thrown by
|
|
24
|
+
`assertCanProceed`. See the [Quota Monitoring](./README.md#quota-monitoring) README
|
|
25
|
+
section.
|
|
26
|
+
- **Credential-scoped multi-key routing.** `OllamaEndpoint` gains an optional `models`
|
|
27
|
+
allow-list, for the common case of several Ollama Cloud API keys each entitled to a
|
|
28
|
+
different model. `EndpointRegistry.candidates(model)` now filters to endpoints whose
|
|
29
|
+
`models` includes the requested model (endpoints without `models` stay eligible for
|
|
30
|
+
every model — fully backward compatible), so `chat`/`generate`/`embed`/`embeddings` and
|
|
31
|
+
model-lifecycle calls (`showModel`, `pullModel`, etc.) automatically resolve the
|
|
32
|
+
authorized credential for the model requested, and cross-endpoint failover between
|
|
33
|
+
differently-scoped endpoints never sends a request to a key that isn't entitled to that
|
|
34
|
+
model. Requesting a model no configured endpoint is scoped to throws the new
|
|
35
|
+
`OllamaModelRoutingError` (`code: 'model_routing_error'`) immediately, before any
|
|
36
|
+
network call — the SDK never probes unauthorized keys to see which one happens to
|
|
37
|
+
work. See the README's
|
|
38
|
+
["Multiple API keys, each entitled to different models"](./README.md#multiple-api-keys-each-entitled-to-different-models)
|
|
39
|
+
and the
|
|
40
|
+
[multi-model agent benchmarking guide](./docs/guides/multi-model-agent-benchmarking.md).
|
|
41
|
+
- **`credentials` + `modelBindings` config.** An ergonomic, map-based alternative to
|
|
42
|
+
writing `endpoints` with per-entry `models` allow-lists by hand: `OllamaClientConfig`
|
|
43
|
+
gains `credentials` (named `{ apiKey, baseUrl?, headers? }` entries, keyed by an id you
|
|
44
|
+
choose), `modelBindings` (maps a model to the credential id, or ids, authorized to serve
|
|
45
|
+
it), and `defaultCredential` (a fallback credential for any model with no explicit
|
|
46
|
+
binding). Both config shapes compile down to the same `EndpointRegistry`/
|
|
47
|
+
`executeWithFailover` routing above — this is config sugar, not a second routing
|
|
48
|
+
mechanism — so behavior (including `OllamaModelRoutingError` on an unrouted model) is
|
|
49
|
+
identical either way. `modelBindings` referencing an unknown credential id throws at
|
|
50
|
+
construction. New `resolveCredentialEndpoints` export for anyone who wants the
|
|
51
|
+
translation without going through `OllamaClient`.
|
|
52
|
+
- **Round-robin candidate selection.** `EndpointRegistryOptions` (passed via
|
|
53
|
+
`OllamaClientConfig.endpointHealth`) gains `strategy: 'priority' | 'round-robin'`
|
|
54
|
+
(default `'priority'`, unchanged prior behavior). With `'round-robin'`,
|
|
55
|
+
`EndpointRegistry.candidates()` rotates each same-priority group of healthy candidates
|
|
56
|
+
by one position per call, so consecutive `chat`/`generate`/`embed`/etc. calls spread
|
|
57
|
+
across a pool of interchangeable endpoints or unbound `credentials` (e.g. several
|
|
58
|
+
free-tier Ollama Cloud keys with no `models`/`modelBindings` restriction) instead of
|
|
59
|
+
always preferring the first one. Candidates at different priorities are unaffected —
|
|
60
|
+
a higher-priority candidate is still always tried first — and failover to the rest of
|
|
61
|
+
the (rotated) list still applies if the first pick fails. See the README's
|
|
62
|
+
["A free pool of interchangeable keys — and spreading load across it"](./README.md#a-free-pool-of-interchangeable-keys--and-spreading-load-across-it).
|
|
63
|
+
- **Least-connections candidate selection.** `EndpointRegistryOptions.strategy` gains a
|
|
64
|
+
third value, `'least-connections'`, alongside `'priority'` (default) and
|
|
65
|
+
`'round-robin'`. Each same-priority tier is ordered by ascending in-flight request
|
|
66
|
+
count (new `EndpointRegistry.acquire`/`release`, wired into `OllamaClient.executeWithFailover`
|
|
67
|
+
around each attempt) rather than a fixed rotation, so concurrent `Promise.all`-style
|
|
68
|
+
fan-out deterministically lands on distinct candidates — the motivating case being
|
|
69
|
+
several Ollama Cloud free-tier accounts, each capped at 1 concurrent request: `N`
|
|
70
|
+
concurrent requests against `N` such accounts land one-per-account rather than risking
|
|
71
|
+
two on the same still-busy one, because the endpoint choice and its `acquire()` happen
|
|
72
|
+
synchronously with no `await` in between (JS's single-threaded execution rules out the
|
|
73
|
+
race entirely). `EndpointHealth` gains `activeRequests`, also exposed via
|
|
74
|
+
`client.endpointStatus()`, for observability regardless of `strategy`. See the README's
|
|
75
|
+
["Concurrent requests across single-slot accounts (least-connections)"](./README.md#concurrent-requests-across-single-slot-accounts-least-connections).
|
|
76
|
+
- **`maxConcurrentPerEndpoint` — queueing past capacity.** `EndpointRegistryOptions`
|
|
77
|
+
gains `maxConcurrentPerEndpoint`, capping in-flight requests per endpoint exactly. Once
|
|
78
|
+
every otherwise-eligible candidate is at that cap, a request waits (FIFO, new
|
|
79
|
+
`EndpointRegistry.filterWithCapacity`/`waitForCapacity`) for one to free rather than
|
|
80
|
+
being routed to an already-saturated candidate — the gap `'least-connections'` alone
|
|
81
|
+
doesn't close for `N + 1` concurrent calls against `N` capacity-1 candidates. Waiting is
|
|
82
|
+
bounded by the request's own `timeoutMs`/`AbortSignal`; a queued call that times out or
|
|
83
|
+
is cancelled is dequeued and rejects without ever being sent.
|
|
84
|
+
|
|
85
|
+
### Fixed
|
|
86
|
+
|
|
87
|
+
- **Streaming requests (`chatStream`/`generateStream`) now hold their endpoint's
|
|
88
|
+
concurrency slot for the lifetime of the stream, not just until it starts.**
|
|
89
|
+
Previously, `acquire`/`release` around a streaming call released the slot as soon as
|
|
90
|
+
`http.requestStream` resolved (response headers received) — before any tokens were
|
|
91
|
+
actually read — so `'least-connections'`/`maxConcurrentPerEndpoint` accounting stopped
|
|
92
|
+
reflecting reality the moment a stream was returned, undercounting real concurrency for
|
|
93
|
+
as long as the caller kept consuming it. `executeWithFailover` gains an internal
|
|
94
|
+
`holdUntil` hook, wired to the returned `OllamaStream`'s `finalResult` for `chatStream`/
|
|
95
|
+
`generateStream` (and the streaming `pull`/`push`/`create` progress endpoints), so the
|
|
96
|
+
slot now releases only once the stream is fully drained, errors, or is aborted.
|
|
97
|
+
|
|
98
|
+
## [1.2.0] - 2026-08-24
|
|
99
|
+
|
|
100
|
+
Closes gaps found during a documentation/API-parity review against the official Ollama
|
|
101
|
+
API — two of which were genuine issues, the rest already covered (multimodal `images`,
|
|
102
|
+
native `think`, `/api/embed`, and full model-lifecycle management all predate this
|
|
103
|
+
release; see the new README sections documenting them).
|
|
104
|
+
|
|
105
|
+
### Fixed
|
|
106
|
+
|
|
107
|
+
- **`webSearch`/`webFetch` were non-functional against real Ollama Cloud.** They
|
|
108
|
+
previously posted to `<configured-baseUrl>/api/websearch` and `/webfetch` — the wrong
|
|
109
|
+
host (Ollama's web tools only ever exist at `https://ollama.com`, never proxied through
|
|
110
|
+
a local server) _and_ the wrong path (missing the underscore: `/api/web_search`,
|
|
111
|
+
`/api/web_fetch`) _and_ the wrong request/response field names. Both methods now always
|
|
112
|
+
target `https://ollama.com` regardless of `baseUrl`/`endpoints`, using the resolved
|
|
113
|
+
`apiKey`/`OLLAMA_API_KEY`, and use the real field names (`max_results` request,
|
|
114
|
+
`content` response). `WebSearchRequestOptions.count` and `WebSearchResult.snippet` are
|
|
115
|
+
kept as `@deprecated` back-compat aliases (mapped to/mirrored from the correct fields)
|
|
116
|
+
rather than removed outright. `WebFetchResponse` gains the `title`/`links` fields the
|
|
117
|
+
real API actually returns.
|
|
118
|
+
|
|
119
|
+
### Added
|
|
120
|
+
|
|
121
|
+
- **`logprobs`/`top_logprobs`:** Added to `ChatRequestOptions`/`GenerateRequestOptions`
|
|
122
|
+
(request) and `ChatResponse`/`GenerateResponse` (response, as a new `Logprob[]` typed
|
|
123
|
+
by the new `Logprob`/`LogprobToken` types), matching the official `/api/chat` and
|
|
124
|
+
`/api/generate` schemas.
|
|
125
|
+
- `OLLAMA_CLOUD_BASE_URL` exported for consumers who want to reference the fixed web-tools
|
|
126
|
+
host directly.
|
|
127
|
+
|
|
128
|
+
## [1.1.0] - 2026-08-23
|
|
129
|
+
|
|
130
|
+
Brings the SDK's typed surface up to date with Ollama v0.13.3+.
|
|
131
|
+
|
|
132
|
+
### Added
|
|
133
|
+
|
|
134
|
+
- **`/api/create` field parity:** `CreateRequestOptions` now exposes the documented
|
|
135
|
+
`template`, `renderer`, `parser`, `license`, `system`, `parameters`, and `messages`
|
|
136
|
+
fields alongside the existing `from`/`files`/`adapters`/`quantize`. The old
|
|
137
|
+
`modelfile` string field is kept for backward compatibility but marked `@deprecated`
|
|
138
|
+
in favor of the discrete fields.
|
|
139
|
+
- **OpenAI Responses API bridge:** `client.openai.responses()` / `createResponses()`
|
|
140
|
+
POST to `/v1/responses`. Ollama implements this non-statefully, so
|
|
141
|
+
`previous_response_id`/`conversation` are typed but documented as ignored.
|
|
142
|
+
- **`reasoning_effort` / `reasoning.effort`:** Added to `OpenAIChatCompletionRequest`
|
|
143
|
+
for thinking models (`deepseek-r1`, `qwen3`, etc.), matching Ollama's OpenAI
|
|
144
|
+
compatibility docs.
|
|
145
|
+
- **`tool_choice` / `parallel_tool_calls`:** Now typed as accepted-but-ignored on
|
|
146
|
+
`OpenAIChatCompletionRequest` (previously omitted entirely), so passing a standard
|
|
147
|
+
OpenAI request object type-checks without modification.
|
|
148
|
+
- **Raw image bytes:** `Message.images` and `GenerateRequestOptions.images` accept
|
|
149
|
+
`Uint8Array` alongside base64 strings. `OllamaClient.chat()`/`generate()` encode any
|
|
150
|
+
`Uint8Array` entries to base64 automatically via the new `encodeImage` utility
|
|
151
|
+
(exported from the package root), using `Buffer` on Node and `btoa` elsewhere so it
|
|
152
|
+
stays Edge Runtime-safe.
|
|
153
|
+
- **`doneReason` in stream results:** `ChatStreamResult`/`GenerateStreamResult` now
|
|
154
|
+
carry `doneReason`, mapped from the final chunk's `done_reason` (e.g. `"stop"`,
|
|
155
|
+
`"load"`, `"unload"`).
|
|
156
|
+
|
|
157
|
+
### Fixed
|
|
158
|
+
|
|
159
|
+
- `package.json`'s `homepage`, `repository`, and `bugs` URLs now point at
|
|
160
|
+
`ollama-sdk` instead of the pre-rename `ollama-client-ts`.
|
|
161
|
+
|
|
8
162
|
## [1.0.0] - 2026-08-17
|
|
9
163
|
|
|
10
164
|
First public release. The version was `0.1.0` throughout development but was never
|