pi-lemonade-link 1.0.2 → 2.0.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/docs/ollama.md CHANGED
@@ -4,18 +4,970 @@ Lemonade supports the [Ollama API](https://github.com/ollama/ollama/blob/main/do
4
4
 
5
5
  To enable auto-detection by Ollama-integrated apps, configure the server to use the Ollama default port `11434`. See [Server Configuration](../guide/configuration/README.md#settings-reference) for how to change the port.
6
6
 
7
- | Endpoint | Status | Notes |
8
- |----------|--------|-------|
9
- | `POST /api/chat` | Supported | Streaming and non-streaming |
10
- | `POST /api/generate` | Supported | Text completion + image generation |
11
- | `GET /api/tags` | Supported | Lists downloaded models |
12
- | `POST /api/show` | Supported | Model details |
13
- | `DELETE /api/delete` | Supported | |
14
- | `POST /api/pull` | Supported | Download with progress |
15
- | `POST /api/embed` | Supported | New embeddings format |
16
- | `POST /api/embeddings` | Supported | Legacy embeddings |
17
- | `GET /api/ps` | Supported | Running models |
18
- | `GET /api/version` | Supported | |
19
- | `POST /api/create` | Not supported | Returns 501 |
20
- | `POST /api/copy` | Not supported | Returns 501 |
21
- | `POST /api/push` | Not supported | Returns 501 |
7
+ A model name may carry a `:latest` tag, which Lemonade ignores. Errors answer with a JSON body `{"error": "<message>"}`. An unknown model answers `404`, and so does a route that loads the model on first use when that load fails for any reason, except a load blocked by a `collection.router` residency constraint, which answers `409`. A backend error answers `500`.
8
+
9
+ <!-- BEGIN GENERATED: ollama.summary -->
10
+ | Method | Endpoint | Status | Description |
11
+ |--------|----------|--------|-------------|
12
+ | `POST` | [`/api/chat`](#post-apichat) | Supported | Generate the next chat message |
13
+ | `POST` | [`/api/generate`](#post-apigenerate) | Supported | Continue a prompt or generate an image |
14
+ | `GET` | [`/api/tags`](#get-apitags) | Supported | List downloaded models |
15
+ | `POST` | [`/api/show`](#post-apishow) | Supported | Describe a model |
16
+ | `DELETE` | [`/api/delete`](#delete-apidelete) | Supported | Delete a model |
17
+ | `POST` | [`/api/pull`](#post-apipull) | Supported | Download a model |
18
+ | `POST` | [`/api/embed`](#post-apiembed) | Supported | Embed one or more texts |
19
+ | `POST` | [`/api/embeddings`](#post-apiembeddings) | Supported | Embed one text in the older format |
20
+ | `GET` | [`/api/ps`](#get-apips) | Supported | List loaded models |
21
+ | `GET` | [`/api/version`](#get-apiversion) | Supported | Report the Ollama version |
22
+ | `POST` | [`/api/create`](#post-apicreate) | Not supported | Create a model from a Modelfile |
23
+ | `POST` | [`/api/copy`](#post-apicopy) | Not supported | Copy a model |
24
+ | `POST` | [`/api/push`](#post-apipush) | Not supported | Push a model to a registry |
25
+ | `POST` | [`/api/blobs/{digest}`](#post-apiblobsdigest) | Not supported | Upload a blob |
26
+ <!-- END GENERATED: ollama.summary -->
27
+
28
+ <!-- BEGIN GENERATED: ollama.chat -->
29
+ ## `POST /api/chat`
30
+ <sub>![Status](https://img.shields.io/badge/status-partially_available-yellow)</sub>
31
+
32
+ Generates the next assistant message for a conversation, loading the model on first use. Lemonade runs it as an OpenAI chat completion and converts the result.
33
+
34
+ Requires `LEMONADE_API_KEY` when it is set.
35
+
36
+ ### Parameters
37
+
38
+ | Parameter | Required | Description | Status |
39
+ |-----------|----------|-------------|--------|
40
+ | `model` | Yes | The model to run; loaded on first use. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
41
+ | `messages` | No | Conversation so far. Each message has a `role` and `content`, plus optional `images` (base64 strings), `tool_calls`, and, on `tool` messages, `tool_name` or `tool_call_id`. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
42
+ | `stream` | No | `true` streams the response as newline-delimited JSON; `false` sends one response once complete. Defaults to `true`. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
43
+ | `options` | No | Sampling options: `temperature`, `top_p`, `seed`, `stop`, `num_predict` (maximum generated tokens) and `repeat_penalty`, which is sent as OpenAI's `frequency_penalty`. These keys are also accepted at the top level, where they win. `num_ctx` sets the context size when this request loads the model, unless `ctx_size` is sent. Other keys are ignored. | <sub>![Status](https://img.shields.io/badge/partial-yellow)</sub> |
44
+ | `tools` | No | A list of tools the model may call. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
45
+ | `format` | No | `json` constrains the reply to a JSON object. A JSON schema is accepted but not applied. | <sub>![Status](https://img.shields.io/badge/partial-yellow)</sub> |
46
+ | `think` | No | `true`, `false`, `low`, `medium`, `high` or `max`. Not applied: reasoning models think regardless. Qwen3 models skip their reasoning when the prompt ends with `/no_think`. | <sub>![Status](https://img.shields.io/badge/not_available-red)</sub> |
47
+ | `keep_alive` | No | `0` with an empty input unloads the model, answering with `done_reason: "unload"`. Other values are ignored. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
48
+ | `ctx_size` | No | Lemonade extension: context size to load the model with, when this request loads it. Ignored when the model is already loaded. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
49
+
50
+ A request with tools and streaming runs non-streaming on the backend and answers with two NDJSON lines: the whole message, then the final line.
51
+
52
+ ### Examples
53
+
54
+ #### Non-streaming
55
+
56
+ === "PowerShell"
57
+
58
+ ```powershell
59
+ Invoke-WebRequest `
60
+ -Uri "http://localhost:13305/api/chat" `
61
+ -Method POST `
62
+ -Headers @{ "Content-Type" = "application/json" } `
63
+ -Body '{
64
+ "model": "Qwen3-0.6B-GGUF",
65
+ "messages": [{"role": "user", "content": "What is the capital of France? /no_think"}],
66
+ "stream": false
67
+ }'
68
+ ```
69
+
70
+ === "Bash"
71
+
72
+ ```bash
73
+ curl http://localhost:13305/api/chat \
74
+ -H "Content-Type: application/json" \
75
+ -d '{
76
+ "model": "Qwen3-0.6B-GGUF",
77
+ "messages": [{"role": "user", "content": "What is the capital of France? /no_think"}],
78
+ "stream": false
79
+ }'
80
+ ```
81
+
82
+ **Response:** `200 OK`
83
+
84
+ ```json
85
+ {
86
+ "model": "Qwen3-0.6B-GGUF",
87
+ "created_at": "2024-01-01T00:00:00Z",
88
+ "message": {"role": "assistant", "content": "The capital of France is **Paris**."},
89
+ "done": true,
90
+ "done_reason": "stop",
91
+ "prompt_eval_count": 19,
92
+ "eval_count": 14,
93
+ "total_duration": 0,
94
+ "load_duration": 0,
95
+ "prompt_eval_duration": 27064000,
96
+ "eval_duration": 71276000
97
+ }
98
+ ```
99
+
100
+ #### Streaming
101
+
102
+ === "PowerShell"
103
+
104
+ ```powershell
105
+ Invoke-WebRequest `
106
+ -Uri "http://localhost:13305/api/chat" `
107
+ -Method POST `
108
+ -Headers @{ "Content-Type" = "application/json" } `
109
+ -Body '{
110
+ "model": "Qwen3-0.6B-GGUF",
111
+ "messages": [{"role": "user", "content": "What is the capital of France? /no_think"}],
112
+ "stream": true
113
+ }'
114
+ ```
115
+
116
+ === "Bash"
117
+
118
+ ```bash
119
+ curl http://localhost:13305/api/chat \
120
+ -H "Content-Type: application/json" \
121
+ -d '{
122
+ "model": "Qwen3-0.6B-GGUF",
123
+ "messages": [{"role": "user", "content": "What is the capital of France? /no_think"}],
124
+ "stream": true
125
+ }'
126
+ ```
127
+
128
+ **Response:** `200 OK`
129
+
130
+ ```text
131
+ {"model": "Qwen3-0.6B-GGUF", "created_at": "2024-01-01T00:00:00Z", "message": {"role": "assistant", "content": ""}, "done": false}
132
+ {"model": "Qwen3-0.6B-GGUF", "created_at": "2024-01-01T00:00:00Z", "message": {"role": "assistant", "content": "The"}, "done": false}
133
+ {"model": "Qwen3-0.6B-GGUF", "created_at": "2024-01-01T00:00:00Z", "message": {"role": "assistant", "content": " capital"}, "done": false}
134
+ ...
135
+ {"model": "Qwen3-0.6B-GGUF", "created_at": "2024-01-01T00:00:00Z", "message": {"role": "assistant", "content": ""}, "done": true, "done_reason": "stop"}
136
+ {"model": "Qwen3-0.6B-GGUF", "created_at": "2024-01-01T00:00:00Z", "message": {"role": "assistant", "content": ""}, "done": true, "done_reason": "stop", "prompt_eval_count": 0, "eval_count": 0, "total_duration": 0, "load_duration": 0, "prompt_eval_duration": 0, "eval_duration": 0}
137
+ ```
138
+
139
+ ### Response format
140
+
141
+ #### JSON
142
+
143
+ - `model` - The model that generated the response.
144
+ - `created_at` - Always `2024-01-01T00:00:00Z`.
145
+ - `message` - The assistant's message; in a streamed line, the next piece of it.
146
+ - `role` - Always `assistant`.
147
+ - `content` - The message text.
148
+ - `thinking` - Reasoning models only: the model's thinking.
149
+ - `tool_calls` - Calls to the request's tools, with arguments as objects.
150
+ - `done` - `false` while the message streams; `true` once it ends, and on a response that is not streamed.
151
+ - `done_reason` - `stop`, `length`, `tool_calls`, or `unload` after an unload request.
152
+ - `prompt_eval_count` - Prompt tokens.
153
+ - `eval_count` - Generated tokens.
154
+ - `total_duration`, `load_duration` - Always `0`.
155
+ - `prompt_eval_duration` - Prompt processing time in nanoseconds, when the backend reports timings; otherwise `0`.
156
+ - `eval_duration` - Generation time in nanoseconds, when the backend reports timings; otherwise `0`.
157
+
158
+ #### NDJSON
159
+
160
+ Each line carries the next message piece with `done: false`. When the message ends, a line with `done: true` and the real `done_reason` follows, then a last `done: true` line with the token counts, which are `0` when the backend reports no usage, and `done_reason` `stop`.
161
+
162
+ - `model` - The model that generated the response.
163
+ - `created_at` - Always `2024-01-01T00:00:00Z`.
164
+ - `message` - The assistant's message; in a streamed line, the next piece of it.
165
+ - `role` - Always `assistant`.
166
+ - `content` - The message text.
167
+ - `thinking` - Reasoning models only: the model's thinking.
168
+ - `tool_calls` - Calls to the request's tools, with arguments as objects.
169
+ - `done` - `false` while the message streams; `true` once it ends, and on a response that is not streamed.
170
+ - `done_reason` - `stop`, `length`, `tool_calls`, or `unload` after an unload request.
171
+ - `prompt_eval_count` - Prompt tokens.
172
+ - `eval_count` - Generated tokens.
173
+ - `total_duration`, `load_duration` - Always `0`.
174
+ - `prompt_eval_duration` - Prompt processing time in nanoseconds on a request with tools, when the backend reports timings; otherwise `0`.
175
+ - `eval_duration` - Generation time in nanoseconds on a request with tools, when the backend reports timings; otherwise `0`.
176
+
177
+ ### Errors
178
+
179
+ | Status | Code | When |
180
+ |--------|------|------|
181
+ | `400` | `invalid_json` | The body is not a JSON object |
182
+ | `400` | `missing_argument` | A required argument is missing |
183
+ | `400` | `invalid_argument` | An argument or a value nested in it has the wrong JSON type, or a value its schema does not list |
184
+ | `404` | | `model` fails to load for any reason other than a residency conflict, such as naming no model or a failed download |
185
+ | `409` | `router_residency_conflict` | Loading the requested model would evict a model that a `collection.router` model needs resident on the same NPU |
186
+ | `500` | | The backend reports an error, whatever its own status |
187
+ | `500` | | The request fails unexpectedly |
188
+ <!-- END GENERATED: ollama.chat -->
189
+
190
+ <!-- BEGIN GENERATED: ollama.generate -->
191
+ ## `POST /api/generate`
192
+ <sub>![Status](https://img.shields.io/badge/status-partially_available-yellow)</sub>
193
+
194
+ Continues a prompt, loading the model on first use. Lemonade runs it as an OpenAI text completion and converts the result. Naming an image model generates an image instead.
195
+
196
+ Requires `LEMONADE_API_KEY` when it is set.
197
+
198
+ ### Parameters
199
+
200
+ | Parameter | Required | Description | Status |
201
+ |-----------|----------|-------------|--------|
202
+ | `model` | Yes | The model to run; loaded on first use. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
203
+ | `prompt` | No | Text to continue, or the image to generate for an image model. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
204
+ | `stream` | No | `true` streams the response as newline-delimited JSON; `false` sends one response once complete. Defaults to `true`. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
205
+ | `options` | No | Sampling options: `temperature`, `top_p`, `stop`, `num_predict` (maximum generated tokens), `repeat_penalty`, which is sent as OpenAI's `frequency_penalty`, and the `seed`, `width`, `height`, `steps` and `cfg_scale` documented below. A key given at the top level wins. `num_ctx` sets the context size when this request loads the model, unless `ctx_size` is sent. Other keys are ignored. | <sub>![Status](https://img.shields.io/badge/partial-yellow)</sub> |
206
+ | `width` | No | Image models only: image width in pixels. Defaults to `512`. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
207
+ | `height` | No | Image models only: image height in pixels. Defaults to `512`. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
208
+ | `steps` | No | Image models only: inference steps. Defaults to the model's own. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
209
+ | `cfg_scale` | No | Image models only: classifier-free guidance scale. Defaults to the model's own. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
210
+ | `seed` | No | Random seed for reproducible output. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
211
+ | `keep_alive` | No | `0` with an empty input unloads the model, answering with `done_reason: "unload"`. Other values are ignored. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
212
+ | `ctx_size` | No | Lemonade extension: context size to load the model with, when this request loads it. Ignored when the model is already loaded. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
213
+ | `system` | No | System prompt. Ignored. | <sub>![Status](https://img.shields.io/badge/not_available-red)</sub> |
214
+ | `format` | No | Output format constraint. Ignored. | <sub>![Status](https://img.shields.io/badge/not_available-red)</sub> |
215
+
216
+ Image generation never streams.
217
+
218
+ ### Examples
219
+
220
+ #### Non-streaming
221
+
222
+ === "PowerShell"
223
+
224
+ ```powershell
225
+ Invoke-WebRequest `
226
+ -Uri "http://localhost:13305/api/generate" `
227
+ -Method POST `
228
+ -Headers @{ "Content-Type" = "application/json" } `
229
+ -Body '{
230
+ "model": "Qwen3-0.6B-GGUF",
231
+ "prompt": "The capital of France is",
232
+ "options": {"num_predict": 16},
233
+ "stream": false
234
+ }'
235
+ ```
236
+
237
+ === "Bash"
238
+
239
+ ```bash
240
+ curl http://localhost:13305/api/generate \
241
+ -H "Content-Type: application/json" \
242
+ -d '{
243
+ "model": "Qwen3-0.6B-GGUF",
244
+ "prompt": "The capital of France is",
245
+ "options": {"num_predict": 16},
246
+ "stream": false
247
+ }'
248
+ ```
249
+
250
+ **Response:** `200 OK`
251
+
252
+ ```json
253
+ {
254
+ "model": "Qwen3-0.6B-GGUF",
255
+ "created_at": "2024-01-01T00:00:00Z",
256
+ "response": " Paris. True or False? Also, what is the capital of France?\n\nThe",
257
+ "done": true,
258
+ "done_reason": "stop",
259
+ "context": [],
260
+ "prompt_eval_count": 5,
261
+ "eval_count": 16,
262
+ "total_duration": 0,
263
+ "load_duration": 0,
264
+ "prompt_eval_duration": 0,
265
+ "eval_duration": 0
266
+ }
267
+ ```
268
+
269
+ #### Streaming
270
+
271
+ === "PowerShell"
272
+
273
+ ```powershell
274
+ Invoke-WebRequest `
275
+ -Uri "http://localhost:13305/api/generate" `
276
+ -Method POST `
277
+ -Headers @{ "Content-Type" = "application/json" } `
278
+ -Body '{
279
+ "model": "Qwen3-0.6B-GGUF",
280
+ "prompt": "The capital of France is",
281
+ "options": {"num_predict": 16},
282
+ "stream": true
283
+ }'
284
+ ```
285
+
286
+ === "Bash"
287
+
288
+ ```bash
289
+ curl http://localhost:13305/api/generate \
290
+ -H "Content-Type: application/json" \
291
+ -d '{
292
+ "model": "Qwen3-0.6B-GGUF",
293
+ "prompt": "The capital of France is",
294
+ "options": {"num_predict": 16},
295
+ "stream": true
296
+ }'
297
+ ```
298
+
299
+ **Response:** `200 OK`
300
+
301
+ ```text
302
+ {"model": "Qwen3-0.6B-GGUF", "created_at": "2024-01-01T00:00:00Z", "response": " Paris", "done": false}
303
+ {"model": "Qwen3-0.6B-GGUF", "created_at": "2024-01-01T00:00:00Z", "response": ",", "done": false}
304
+ {"model": "Qwen3-0.6B-GGUF", "created_at": "2024-01-01T00:00:00Z", "response": " France", "done": false}
305
+ ...
306
+ {"model": "Qwen3-0.6B-GGUF", "created_at": "2024-01-01T00:00:00Z", "response": "", "done": true, "done_reason": "length"}
307
+ {"model": "Qwen3-0.6B-GGUF", "created_at": "2024-01-01T00:00:00Z", "response": "", "done": true, "done_reason": "stop", "context": [], "prompt_eval_count": 5, "eval_count": 16, "total_duration": 0, "load_duration": 0, "prompt_eval_duration": 0, "eval_duration": 0}
308
+ ```
309
+
310
+ ### Response format
311
+
312
+ #### JSON
313
+
314
+ - `model` - The model that generated the response.
315
+ - `created_at` - Always `2024-01-01T00:00:00Z`.
316
+ - `response` - Generated text. Empty for an image model.
317
+ - `image` - Image models only: the generated image, base64-encoded.
318
+ - `done` - `true` on a response that is not streamed, and on the last two lines of a stream.
319
+ - `done_reason` - `stop`, or `unload` after an unload request.
320
+ - `context` - Always empty.
321
+ - `prompt_eval_count` - Prompt tokens.
322
+ - `eval_count` - Generated tokens.
323
+ - `total_duration`, `load_duration`, `prompt_eval_duration`, `eval_duration` - Always `0`.
324
+
325
+ #### NDJSON
326
+
327
+ Each line carries the next piece of text with `done: false`. When the text ends, a line with `done: true` and the real `done_reason` follows, then a last `done: true` line with the token counts and `done_reason` `stop`.
328
+
329
+ - `model` - The model that generated the response.
330
+ - `created_at` - Always `2024-01-01T00:00:00Z`.
331
+ - `response` - Generated text. Empty for an image model.
332
+ - `image` - Image models only: the generated image, base64-encoded.
333
+ - `done` - `true` on a response that is not streamed, and on the last two lines of a stream.
334
+ - `done_reason` - `stop`, `length`, or `unload` after an unload request.
335
+ - `context` - Always empty.
336
+ - `prompt_eval_count` - Prompt tokens.
337
+ - `eval_count` - Generated tokens.
338
+ - `total_duration`, `load_duration`, `prompt_eval_duration`, `eval_duration` - Always `0`.
339
+
340
+ ### Errors
341
+
342
+ | Status | Code | When |
343
+ |--------|------|------|
344
+ | `400` | `invalid_json` | The body is not a JSON object |
345
+ | `400` | `missing_argument` | A required argument is missing |
346
+ | `400` | `invalid_argument` | An argument or a value nested in it has the wrong JSON type, or a value its schema does not list |
347
+ | `404` | | `model` fails to load for any reason other than a residency conflict, such as naming no model or a failed download |
348
+ | `409` | `router_residency_conflict` | Loading the requested model would evict a model that a `collection.router` model needs resident on the same NPU |
349
+ | `500` | | The backend reports an error, whatever its own status |
350
+ | `500` | | The request fails unexpectedly |
351
+ <!-- END GENERATED: ollama.generate -->
352
+
353
+ <!-- BEGIN GENERATED: ollama.tags -->
354
+ ## `GET /api/tags`
355
+ <sub>![Status](https://img.shields.io/badge/status-fully_available-green)</sub>
356
+
357
+ Lists the downloaded models in Ollama's format.
358
+
359
+ Requires `LEMONADE_API_KEY` when it is set.
360
+
361
+ ### Parameters
362
+
363
+ This endpoint does not take any parameters.
364
+
365
+ ### Example
366
+
367
+ === "PowerShell"
368
+
369
+ ```powershell
370
+ Invoke-WebRequest -Uri "http://localhost:13305/api/tags"
371
+ ```
372
+
373
+ === "Bash"
374
+
375
+ ```bash
376
+ curl http://localhost:13305/api/tags
377
+ ```
378
+
379
+ **Response:** `200 OK`
380
+
381
+ ```json
382
+ {
383
+ "models": [
384
+ {
385
+ "name": "Phishing-Email-Detection-ONNX:latest",
386
+ "model": "Phishing-Email-Detection-ONNX:latest",
387
+ "modified_at": "2024-01-01T00:00:00Z",
388
+ "size": 268435456,
389
+ "digest": "sha256:0000000000000000000000000000000000000000000000000000000000000000",
390
+ "details": {
391
+ "parent_model": "",
392
+ "format": "gguf",
393
+ "family": "onnxruntime",
394
+ "families": ["onnxruntime"],
395
+ "parameter_size": "",
396
+ "quantization_level": ""
397
+ }
398
+ },
399
+ ... 10 more
400
+ ]
401
+ }
402
+ ```
403
+
404
+ ### Response format
405
+
406
+ - `models` - The downloaded models.
407
+ - `name` - Lemonade model name with a `:latest` tag.
408
+ - `model` - Same as `name`.
409
+ - `modified_at` - Always `2024-01-01T00:00:00Z`.
410
+ - `size` - Size in bytes, from the registry's estimate.
411
+ - `digest` - Always an all-zero sha256.
412
+ - `details` - Inferred from the model name, recipe and checkpoint.
413
+ - `parent_model` - Always empty.
414
+ - `format` - Always `gguf`.
415
+ - `family` - The model's recipe, e.g. `llamacpp`.
416
+ - `families` - A list holding only `family`.
417
+ - `parameter_size` - From the model name, e.g. `0.6B`; empty when the name has none.
418
+ - `quantization_level` - From the checkpoint, e.g. `Q4_0`; empty when the checkpoint has none.
419
+
420
+ ### Errors
421
+
422
+ | Status | When |
423
+ |--------|------|
424
+ | `500` | The request fails unexpectedly |
425
+ <!-- END GENERATED: ollama.tags -->
426
+
427
+ <!-- BEGIN GENERATED: ollama.show -->
428
+ ## `POST /api/show`
429
+ <sub>![Status](https://img.shields.io/badge/status-fully_available-green)</sub>
430
+
431
+ Describes one registered model in Ollama's format.
432
+
433
+ Requires `LEMONADE_API_KEY` when it is set.
434
+
435
+ ### Parameters
436
+
437
+ | Parameter | Required | Description | Status |
438
+ |-----------|----------|-------------|--------|
439
+ | `model` or `name` | Yes | The model's name. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
440
+
441
+ ### Example
442
+
443
+ === "PowerShell"
444
+
445
+ ```powershell
446
+ Invoke-WebRequest `
447
+ -Uri "http://localhost:13305/api/show" `
448
+ -Method POST `
449
+ -Headers @{ "Content-Type" = "application/json" } `
450
+ -Body '{"model": "Qwen3-0.6B-GGUF"}'
451
+ ```
452
+
453
+ === "Bash"
454
+
455
+ ```bash
456
+ curl http://localhost:13305/api/show \
457
+ -H "Content-Type: application/json" \
458
+ -d '{"model": "Qwen3-0.6B-GGUF"}'
459
+ ```
460
+
461
+ **Response:** `200 OK`
462
+
463
+ ```json
464
+ {
465
+ "modelfile": "# Modelfile generated by Lemonade\nFROM unsloth/Qwen3-0.6B-GGUF:Q4_0",
466
+ "parameters": "num_ctx -1",
467
+ "template": "",
468
+ "details": {
469
+ "parent_model": "",
470
+ "format": "gguf",
471
+ "family": "llamacpp",
472
+ "families": ["llamacpp"],
473
+ "parameter_size": "0.6B",
474
+ "quantization_level": "Q4_0"
475
+ },
476
+ "capabilities": ["completion", "tools", "thinking"],
477
+ "model_info": {
478
+ "general.architecture": "llamacpp",
479
+ "general.file_type": 0,
480
+ "general.parameter_count": 0,
481
+ "general.quantization_version": 0,
482
+ "llamacpp.context_length": -1
483
+ }
484
+ }
485
+ ```
486
+
487
+ ### Response format
488
+
489
+ - `modelfile` - A `FROM` line naming the checkpoint.
490
+ - `parameters` - `num_ctx` followed by the model's configured context size, which is `-1` when Lemonade sizes the context at load time.
491
+ - `template` - Always empty.
492
+ - `details` - Inferred from the model name, recipe and checkpoint.
493
+ - `parent_model` - Always empty.
494
+ - `format` - Always `gguf`.
495
+ - `family` - The model's recipe, e.g. `llamacpp`.
496
+ - `families` - A list holding only `family`.
497
+ - `parameter_size` - From the model name, e.g. `0.6B`; empty when the name has none.
498
+ - `quantization_level` - From the checkpoint, e.g. `Q4_0`; empty when the checkpoint has none.
499
+ - `capabilities` - From the model's labels: `completion` for chat models, `embedding` for embedding models, plus `tools`, `vision` and `thinking` for the `tool-calling` (or `tools`), `vision` and `reasoning` labels.
500
+ - `model_info` - `general.architecture` (the recipe) and `<recipe>.context_length` (the context size in `parameters`); the other keys are always `0`.
501
+
502
+ ### Errors
503
+
504
+ | Status | Code | When |
505
+ |--------|------|------|
506
+ | `400` | `invalid_json` | The body is not a JSON object |
507
+ | `400` | `missing_argument` | A required argument is missing |
508
+ | `400` | `invalid_argument` | An argument or a value nested in it has the wrong JSON type, or a value its schema does not list |
509
+ | `404` | | `model` names no model in the registry, or one filtered out on this system |
510
+ | `500` | | The request fails unexpectedly |
511
+ <!-- END GENERATED: ollama.show -->
512
+
513
+ <!-- BEGIN GENERATED: ollama.delete -->
514
+ ## `DELETE /api/delete`
515
+ <sub>![Status](https://img.shields.io/badge/status-fully_available-green)</sub>
516
+
517
+ Deletes a downloaded model's files, unloading it first when it is loaded.
518
+
519
+ Requires `LEMONADE_API_KEY` when it is set.
520
+
521
+ ### Parameters
522
+
523
+ | Parameter | Required | Description | Status |
524
+ |-----------|----------|-------------|--------|
525
+ | `model` or `name` | Yes | The model's name. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
526
+
527
+ Success answers `200` with an empty body, as Ollama does.
528
+
529
+ ### Example
530
+
531
+ === "PowerShell"
532
+
533
+ ```powershell
534
+ Invoke-WebRequest `
535
+ -Uri "http://localhost:13305/api/delete" `
536
+ -Method DELETE `
537
+ -Headers @{ "Content-Type" = "application/json" } `
538
+ -Body '{"model": "RealESRGAN-x4plus-anime"}'
539
+ ```
540
+
541
+ === "Bash"
542
+
543
+ ```bash
544
+ curl -X DELETE http://localhost:13305/api/delete \
545
+ -H "Content-Type: application/json" \
546
+ -d '{"model": "RealESRGAN-x4plus-anime"}'
547
+ ```
548
+
549
+ **Response:** `200 OK`
550
+
551
+ ### Errors
552
+
553
+ | Status | Code | When |
554
+ |--------|------|------|
555
+ | `400` | `invalid_json` | The body is not a JSON object |
556
+ | `400` | `missing_argument` | A required argument is missing |
557
+ | `400` | `invalid_argument` | An argument or a value nested in it has the wrong JSON type, or a value its schema does not list |
558
+ | `404` | | `model` names no model in the registry, or one filtered out on this system |
559
+ | `500` | | Deleting fails for another reason, for example for an `extra.` model, a file that stays locked after the retries, or a failed unload |
560
+ <!-- END GENERATED: ollama.delete -->
561
+
562
+ <!-- BEGIN GENERATED: ollama.pull -->
563
+ ## `POST /api/pull`
564
+ <sub>![Status](https://img.shields.io/badge/status-fully_available-green)</sub>
565
+
566
+ Downloads a registered model, or updates it when its registry has a newer version.
567
+
568
+ Requires `LEMONADE_API_KEY` when it is set.
569
+
570
+ ### Parameters
571
+
572
+ | Parameter | Required | Description | Status |
573
+ |-----------|----------|-------------|--------|
574
+ | `model` or `name` | Yes | The model's name. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
575
+ | `stream` | No | `true` streams the response as newline-delimited JSON; `false` sends one response once complete. Defaults to `true`. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
576
+
577
+ Only models already in Lemonade's registry can be pulled; use [`POST /v1/pull`](./lemonade.md#post-v1pull) to register a new one.
578
+
579
+ ### Examples
580
+
581
+ #### Streaming
582
+
583
+ === "PowerShell"
584
+
585
+ ```powershell
586
+ Invoke-WebRequest `
587
+ -Uri "http://localhost:13305/api/pull" `
588
+ -Method POST `
589
+ -Headers @{ "Content-Type" = "application/json" } `
590
+ -Body '{"model": "Qwen3-0.6B-GGUF", "stream": true}'
591
+ ```
592
+
593
+ === "Bash"
594
+
595
+ ```bash
596
+ curl http://localhost:13305/api/pull \
597
+ -H "Content-Type: application/json" \
598
+ -d '{"model": "Qwen3-0.6B-GGUF", "stream": true}'
599
+ ```
600
+
601
+ **Response:** `200 OK`
602
+
603
+ ```text
604
+ {"status": "pulling manifest"}
605
+ {"status": "downloading Qwen3-0.6B-Q4_0.gguf", "digest": "sha256:Qwen3-0.6B-Q4_0.gguf", "completed": 0, "total": 382156480}
606
+ {"status": "downloading Qwen3-0.6B-Q4_0.gguf", "digest": "sha256:Qwen3-0.6B-Q4_0.gguf", "completed": 382156480, "total": 382156480}
607
+ ...
608
+ {"status": "success"}
609
+ {"status": "success"}
610
+ ```
611
+
612
+ #### Non-streaming
613
+
614
+ === "PowerShell"
615
+
616
+ ```powershell
617
+ Invoke-WebRequest `
618
+ -Uri "http://localhost:13305/api/pull" `
619
+ -Method POST `
620
+ -Headers @{ "Content-Type" = "application/json" } `
621
+ -Body '{"model": "RealESRGAN-x4plus-anime", "stream": false}'
622
+ ```
623
+
624
+ === "Bash"
625
+
626
+ ```bash
627
+ curl http://localhost:13305/api/pull \
628
+ -H "Content-Type: application/json" \
629
+ -d '{"model": "RealESRGAN-x4plus-anime", "stream": false}'
630
+ ```
631
+
632
+ **Response:** `200 OK`
633
+
634
+ ```json
635
+ {"status": "success"}
636
+ ```
637
+
638
+ ### Response format
639
+
640
+ #### NDJSON
641
+
642
+ The first line is `pulling manifest`, then one line per progress report, then two `success` lines.
643
+
644
+ - `status` - `pulling manifest`, `downloading <file>`, or `success`.
645
+ - `digest` - Download lines: `sha256:` followed by the file name.
646
+ - `completed` - Download lines: bytes of the file downloaded so far.
647
+ - `total` - Download lines: the file's size in bytes.
648
+ - `error` - Only on a failed download's last line.
649
+
650
+ #### JSON
651
+
652
+ - `status` - Always `success`.
653
+
654
+ ### Errors
655
+
656
+ | Status | Code | When |
657
+ |--------|------|------|
658
+ | `400` | `invalid_json` | The body is not a JSON object |
659
+ | `400` | `missing_argument` | A required argument is missing |
660
+ | `400` | `invalid_argument` | An argument or a value nested in it has the wrong JSON type, or a value its schema does not list |
661
+ | `400` | `lemond_offline` | `offline` is set to `true` |
662
+ | `404` | | `model` names no model in the registry, or one filtered out on this system |
663
+ | `500` | | A non-streaming download fails |
664
+ <!-- END GENERATED: ollama.pull -->
665
+
666
+ <!-- BEGIN GENERATED: ollama.embed -->
667
+ ## `POST /api/embed`
668
+ <sub>![Status](https://img.shields.io/badge/status-partially_available-yellow)</sub>
669
+
670
+ Returns one embedding per input text, loading the model on first use.
671
+
672
+ Requires `LEMONADE_API_KEY` when it is set.
673
+
674
+ ### Parameters
675
+
676
+ | Parameter | Required | Description | Status |
677
+ |-----------|----------|-------------|--------|
678
+ | `model` | Yes | The model to run; loaded on first use. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
679
+ | `input` | Yes | Text to embed, or an array of texts. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
680
+ | `options` | No | `num_ctx` sets the context size when this request loads the model, unless `ctx_size` is sent. Other keys are ignored. | <sub>![Status](https://img.shields.io/badge/partial-yellow)</sub> |
681
+ | `ctx_size` | No | Lemonade extension: context size to load the model with, when this request loads it. Ignored when the model is already loaded. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
682
+
683
+ ### Example
684
+
685
+ === "PowerShell"
686
+
687
+ ```powershell
688
+ Invoke-WebRequest `
689
+ -Uri "http://localhost:13305/api/embed" `
690
+ -Method POST `
691
+ -Headers @{ "Content-Type" = "application/json" } `
692
+ -Body '{"model": "nomic-embed-text-v1-GGUF", "input": "Why is the sky blue?"}'
693
+ ```
694
+
695
+ === "Bash"
696
+
697
+ ```bash
698
+ curl http://localhost:13305/api/embed \
699
+ -H "Content-Type: application/json" \
700
+ -d '{"model": "nomic-embed-text-v1-GGUF", "input": "Why is the sky blue?"}'
701
+ ```
702
+
703
+ **Response:** `200 OK`
704
+
705
+ ```json
706
+ {
707
+ "model": "nomic-embed-text-v1-GGUF",
708
+ "embeddings": [
709
+ [0.030419785529375076, 0.051205702126026154, -0.007968701422214508, -0.016216253861784935, 0.014430047944188118, 0.09111383557319641, -0.016361059620976448, 0.00019216086366213858, ... 760 more]
710
+ ],
711
+ "total_duration": 0,
712
+ "load_duration": 0,
713
+ "prompt_eval_count": 0
714
+ }
715
+ ```
716
+
717
+ ### Response format
718
+
719
+ - `model` - The model that produced the embeddings.
720
+ - `embeddings` - One vector per input, in input order.
721
+ - `total_duration`, `load_duration`, `prompt_eval_count` - Always `0`.
722
+
723
+ ### Errors
724
+
725
+ | Status | Code | When |
726
+ |--------|------|------|
727
+ | `400` | `invalid_json` | The body is not a JSON object |
728
+ | `400` | `missing_argument` | A required argument is missing |
729
+ | `400` | `invalid_argument` | An argument or a value nested in it has the wrong JSON type, or a value its schema does not list |
730
+ | `404` | | `model` fails to load for any reason other than a residency conflict, such as naming no model or a failed download |
731
+ | `409` | `router_residency_conflict` | Loading the requested model would evict a model that a `collection.router` model needs resident on the same NPU |
732
+ | `500` | | The backend reports an error, whatever its own status |
733
+ | `500` | | The request fails unexpectedly |
734
+ <!-- END GENERATED: ollama.embed -->
735
+
736
+ <!-- BEGIN GENERATED: ollama.embeddings -->
737
+ ## `POST /api/embeddings`
738
+ <sub>![Status](https://img.shields.io/badge/status-partially_available-yellow)</sub>
739
+
740
+ Returns the embedding of one text in Ollama's older format, loading the model on first use.
741
+
742
+ Requires `LEMONADE_API_KEY` when it is set.
743
+
744
+ ### Parameters
745
+
746
+ | Parameter | Required | Description | Status |
747
+ |-----------|----------|-------------|--------|
748
+ | `model` | Yes | The model to run; loaded on first use. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
749
+ | `prompt` or `input` | Yes | Text to embed. For an array, only the first text's embedding is returned. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
750
+ | `options` | No | `num_ctx` sets the context size when this request loads the model, unless `ctx_size` is sent. Other keys are ignored. | <sub>![Status](https://img.shields.io/badge/partial-yellow)</sub> |
751
+ | `ctx_size` | No | Lemonade extension: context size to load the model with, when this request loads it. Ignored when the model is already loaded. | <sub>![Status](https://img.shields.io/badge/available-green)</sub> |
752
+
753
+ ### Example
754
+
755
+ === "PowerShell"
756
+
757
+ ```powershell
758
+ Invoke-WebRequest `
759
+ -Uri "http://localhost:13305/api/embeddings" `
760
+ -Method POST `
761
+ -Headers @{ "Content-Type" = "application/json" } `
762
+ -Body '{"model": "nomic-embed-text-v1-GGUF", "prompt": "Why is the sky blue?"}'
763
+ ```
764
+
765
+ === "Bash"
766
+
767
+ ```bash
768
+ curl http://localhost:13305/api/embeddings \
769
+ -H "Content-Type: application/json" \
770
+ -d '{"model": "nomic-embed-text-v1-GGUF", "prompt": "Why is the sky blue?"}'
771
+ ```
772
+
773
+ **Response:** `200 OK`
774
+
775
+ ```json
776
+ {
777
+ "model": "nomic-embed-text-v1-GGUF",
778
+ "embedding": [0.030419785529375076, 0.051205702126026154, -0.007968701422214508, -0.016216253861784935, 0.014430047944188118, 0.09111383557319641, -0.016361059620976448, 0.00019216086366213858, ... 760 more]
779
+ }
780
+ ```
781
+
782
+ ### Response format
783
+
784
+ - `model` - The model that produced the embedding.
785
+ - `embedding` - The text's embedding vector.
786
+
787
+ ### Errors
788
+
789
+ | Status | Code | When |
790
+ |--------|------|------|
791
+ | `400` | `invalid_json` | The body is not a JSON object |
792
+ | `400` | `missing_argument` | A required argument is missing |
793
+ | `400` | `invalid_argument` | An argument or a value nested in it has the wrong JSON type, or a value its schema does not list |
794
+ | `404` | | `model` fails to load for any reason other than a residency conflict, such as naming no model or a failed download |
795
+ | `409` | `router_residency_conflict` | Loading the requested model would evict a model that a `collection.router` model needs resident on the same NPU |
796
+ | `500` | | The backend reports an error, whatever its own status |
797
+ | `500` | | The request fails unexpectedly |
798
+ <!-- END GENERATED: ollama.embeddings -->
799
+
800
+ <!-- BEGIN GENERATED: ollama.ps -->
801
+ ## `GET /api/ps`
802
+ <sub>![Status](https://img.shields.io/badge/status-fully_available-green)</sub>
803
+
804
+ Lists the loaded models in Ollama's format.
805
+
806
+ Requires `LEMONADE_API_KEY` when it is set.
807
+
808
+ ### Parameters
809
+
810
+ This endpoint does not take any parameters.
811
+
812
+ [`GET /v1/health`](./lemonade.md#get-v1health) reports the loaded models in full.
813
+
814
+ ### Example
815
+
816
+ === "PowerShell"
817
+
818
+ ```powershell
819
+ Invoke-WebRequest -Uri "http://localhost:13305/api/ps"
820
+ ```
821
+
822
+ === "Bash"
823
+
824
+ ```bash
825
+ curl http://localhost:13305/api/ps
826
+ ```
827
+
828
+ **Response:** `200 OK`
829
+
830
+ ```json
831
+ {
832
+ "models": [
833
+ {
834
+ "name": "nomic-embed-text-v1-GGUF:latest",
835
+ "model": "nomic-embed-text-v1-GGUF:latest",
836
+ "size": 0,
837
+ "digest": "sha256:0000000000000000000000000000000000000000000000000000000000000000",
838
+ "details": {
839
+ "parent_model": "",
840
+ "format": "gguf",
841
+ "family": "llamacpp",
842
+ "families": ["llamacpp"],
843
+ "parameter_size": "",
844
+ "quantization_level": "Q4_K_S"
845
+ },
846
+ "expires_at": "2099-01-01T00:00:00Z",
847
+ "size_vram": 0
848
+ },
849
+ ... 3 more
850
+ ]
851
+ }
852
+ ```
853
+
854
+ ### Response format
855
+
856
+ - `models` - The loaded models.
857
+ - `name` - Lemonade model name with a `:latest` tag.
858
+ - `model` - Same as `name`.
859
+ - `size` - Always `0`.
860
+ - `digest` - Always an all-zero sha256.
861
+ - `details` - Inferred from the model name, recipe and checkpoint.
862
+ - `parent_model` - Always empty.
863
+ - `format` - Always `gguf`.
864
+ - `family` - The model's recipe, e.g. `llamacpp`.
865
+ - `families` - A list holding only `family`.
866
+ - `parameter_size` - From the model name, e.g. `0.6B`; empty when the name has none.
867
+ - `quantization_level` - From the checkpoint, e.g. `Q4_0`; empty when the checkpoint has none.
868
+ - `expires_at` - Always `2099-01-01T00:00:00Z`.
869
+ - `size_vram` - Always `0`.
870
+
871
+ ### Errors
872
+
873
+ | Status | When |
874
+ |--------|------|
875
+ | `500` | The request fails unexpectedly |
876
+ <!-- END GENERATED: ollama.ps -->
877
+
878
+ <!-- BEGIN GENERATED: ollama.version -->
879
+ ## `GET /api/version`
880
+ <sub>![Status](https://img.shields.io/badge/status-fully_available-green)</sub>
881
+
882
+ Reports an Ollama version recent enough for Ollama clients' version checks. [`GET /v1/health`](./lemonade.md#get-v1health) reports Lemonade's own version.
883
+
884
+ Requires `LEMONADE_API_KEY` when it is set.
885
+
886
+ ### Parameters
887
+
888
+ This endpoint does not take any parameters.
889
+
890
+ ### Example
891
+
892
+ === "PowerShell"
893
+
894
+ ```powershell
895
+ Invoke-WebRequest -Uri "http://localhost:13305/api/version"
896
+ ```
897
+
898
+ === "Bash"
899
+
900
+ ```bash
901
+ curl http://localhost:13305/api/version
902
+ ```
903
+
904
+ **Response:** `200 OK`
905
+
906
+ ```json
907
+ {"version": "0.16.1"}
908
+ ```
909
+
910
+ ### Response format
911
+
912
+ - `version` - The Ollama version Lemonade reports to clients.
913
+ <!-- END GENERATED: ollama.version -->
914
+
915
+ <!-- BEGIN GENERATED: ollama.create -->
916
+ ## `POST /api/create`
917
+ <sub>![Status](https://img.shields.io/badge/status-not_available-red)</sub>
918
+
919
+ Register a model with [`POST /v1/pull`](./lemonade.md#post-v1pull) instead.
920
+
921
+ Requires `LEMONADE_API_KEY` when it is set.
922
+
923
+ ### Errors
924
+
925
+ | Status | When |
926
+ |--------|------|
927
+ | `501` | Lemonade does not support this Ollama operation |
928
+ <!-- END GENERATED: ollama.create -->
929
+
930
+ <!-- BEGIN GENERATED: ollama.copy -->
931
+ ## `POST /api/copy`
932
+ <sub>![Status](https://img.shields.io/badge/status-not_available-red)</sub>
933
+
934
+
935
+
936
+ Requires `LEMONADE_API_KEY` when it is set.
937
+
938
+ ### Errors
939
+
940
+ | Status | When |
941
+ |--------|------|
942
+ | `501` | Lemonade does not support this Ollama operation |
943
+ <!-- END GENERATED: ollama.copy -->
944
+
945
+ <!-- BEGIN GENERATED: ollama.push -->
946
+ ## `POST /api/push`
947
+ <sub>![Status](https://img.shields.io/badge/status-not_available-red)</sub>
948
+
949
+
950
+
951
+ Requires `LEMONADE_API_KEY` when it is set.
952
+
953
+ ### Errors
954
+
955
+ | Status | When |
956
+ |--------|------|
957
+ | `501` | Lemonade does not support this Ollama operation |
958
+ <!-- END GENERATED: ollama.push -->
959
+
960
+ <!-- BEGIN GENERATED: ollama.blobs -->
961
+ ## `POST /api/blobs/{digest}`
962
+ <sub>![Status](https://img.shields.io/badge/status-not_available-red)</sub>
963
+
964
+
965
+
966
+ Requires `LEMONADE_API_KEY` when it is set.
967
+
968
+ ### Errors
969
+
970
+ | Status | When |
971
+ |--------|------|
972
+ | `501` | Lemonade does not support this Ollama operation |
973
+ <!-- END GENERATED: ollama.blobs -->