@orkestrel/ollama 0.0.14 → 0.0.15
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/README.md +10 -4
- package/dist/src/server/index.cjs +88 -35
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +192 -137
- package/dist/src/server/index.d.ts +192 -137
- package/dist/src/server/index.js +88 -35
- package/dist/src/server/index.js.map +1 -1
- package/package.json +17 -18
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { ContextFormat } from '@orkestrel/agent';
|
|
2
|
-
import { Message } from '@orkestrel/agent';
|
|
3
|
-
import { ProviderDelta } from '@orkestrel/agent';
|
|
4
|
-
import { ProviderInterface } from '@orkestrel/agent';
|
|
5
|
-
import { ProviderResult } from '@orkestrel/agent';
|
|
6
|
-
import { ProviderStreamOptions } from '@orkestrel/agent';
|
|
7
|
-
import { ThinkSplitterInterface } from '@orkestrel/agent';
|
|
8
|
-
import { TimeoutInterface } from '@orkestrel/timeout';
|
|
9
|
-
import { TokenUsage } from '@orkestrel/budget';
|
|
10
|
-
import { ToolCall } from '@orkestrel/tool';
|
|
11
|
-
import { ToolDefinition } from '@orkestrel/tool';
|
|
1
|
+
import type { ContextFormat } from '@orkestrel/agent';
|
|
2
|
+
import type { Message } from '@orkestrel/agent';
|
|
3
|
+
import type { ProviderDelta } from '@orkestrel/agent';
|
|
4
|
+
import type { ProviderInterface } from '@orkestrel/agent';
|
|
5
|
+
import type { ProviderResult } from '@orkestrel/agent';
|
|
6
|
+
import type { ProviderStreamOptions } from '@orkestrel/agent';
|
|
7
|
+
import type { ThinkSplitterInterface } from '@orkestrel/agent';
|
|
8
|
+
import type { TimeoutInterface } from '@orkestrel/timeout';
|
|
9
|
+
import type { TokenUsage } from '@orkestrel/budget';
|
|
10
|
+
import type { ToolCall } from '@orkestrel/tool';
|
|
11
|
+
import type { ToolDefinition } from '@orkestrel/tool';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* Builds a
|
|
14
|
+
* Builds a `ProviderResult` from a turn's content, reasoning, tool calls, and usage.
|
|
15
15
|
*
|
|
16
16
|
* @remarks
|
|
17
17
|
* Only the present optionals are set: no empty `thinking`, no empty `tools`, and no
|
|
@@ -38,36 +38,43 @@ export declare function buildResult(content: string, thinking: string, tools: re
|
|
|
38
38
|
* @remarks
|
|
39
39
|
* Only `model` is required; `url` defaults to the local daemon, `keepAlive` to `'5m'`,
|
|
40
40
|
* `timeout` to `120_000`ms, and `options` is forwarded verbatim as sampling
|
|
41
|
-
* parameters (`temperature`, `seed`, and `num_predict`).
|
|
41
|
+
* parameters (`temperature`, `seed`, and `num_predict`). Each call takes an
|
|
42
42
|
* `AbortSignal` to bound the request; a `stream` cancelled mid-flight throws a
|
|
43
43
|
* `ProviderAbortError` carrying the partial result.
|
|
44
44
|
*
|
|
45
45
|
* The optional `fetch` + `headers` form a transport seam (see {@link OllamaOptions}):
|
|
46
46
|
* point `url` at your own server, inject a custom `fetch`, and have `headers` attach a
|
|
47
47
|
* generated/obfuscated bearer token your server validates — so a browser runtime
|
|
48
|
-
* reaches the LLM through your middleware
|
|
48
|
+
* reaches the LLM through your middleware without this library ever handling the real API
|
|
49
49
|
* key. Both omitted ⇒ the global `fetch` and only a JSON content type.
|
|
50
50
|
*
|
|
51
|
-
* The optional `format` is the provider's context-framing default — the
|
|
51
|
+
* The optional `format` is the provider's context-framing default — the provider-default
|
|
52
52
|
* level of `AgentContext`'s format cascade (beaten by a manager-options or per-item
|
|
53
53
|
* override, beating the managers' built-in framing), declaring how this
|
|
54
54
|
* provider's models prefer context sections framed (for example XML group wrappers vs. Markdown
|
|
55
|
-
* headers). It is
|
|
56
|
-
* `/api/chat` `format` wire parameter (structured output) — the
|
|
57
|
-
* the shared word. Omitted ⇒ the provider is
|
|
55
|
+
* headers). It is exposed on the provider for the Agent's `build()` and is not Ollama's
|
|
56
|
+
* `/api/chat` `format` wire parameter (structured output) — the framing default and that
|
|
57
|
+
* wire parameter are unrelated despite the shared word. Omitted ⇒ the provider is
|
|
58
|
+
* framing-agnostic (core's built-in defaults).
|
|
58
59
|
*
|
|
59
60
|
* @param options - `model` (required), and optional `url` / `keepAlive` / `timeout` /
|
|
60
61
|
* `options` / `fetch` / `headers` / `format` (see {@link OllamaOptions})
|
|
61
62
|
* @returns A working {@link ProviderInterface} backed by Ollama
|
|
62
63
|
*
|
|
63
|
-
* @example
|
|
64
|
+
* @example createOllama + generate
|
|
64
65
|
* ```ts
|
|
65
66
|
* import { createAbort } from '@orkestrel/abort'
|
|
66
67
|
* import { createOllama } from '@orkestrel/ollama'
|
|
67
68
|
*
|
|
68
|
-
* const provider = createOllama({ model: 'qwen3.5:2b-q4_K_M' })
|
|
69
|
+
* const provider = createOllama({ model: 'qwen3.5:2b-q4_K_M', options: { temperature: 0 } })
|
|
69
70
|
* const abort = createAbort()
|
|
71
|
+
* const messages = [
|
|
72
|
+
* { id: '1', role: 'user', content: 'Summarize the release notes for version 2.0.' },
|
|
73
|
+
* ] as const
|
|
74
|
+
*
|
|
70
75
|
* const result = await provider.generate(messages, abort.signal)
|
|
76
|
+
* console.log(result.content)
|
|
77
|
+
* if (result.usage) charge(result.usage) // fold into a token budget
|
|
71
78
|
* ```
|
|
72
79
|
*
|
|
73
80
|
* @example
|
|
@@ -83,7 +90,7 @@ export declare function buildResult(content: string, thinking: string, tools: re
|
|
|
83
90
|
*
|
|
84
91
|
* @example
|
|
85
92
|
* Declare a context-framing default — wrap the instructions section in an XML group (the
|
|
86
|
-
* provider-default level of `AgentContext`'s cascade;
|
|
93
|
+
* provider-default level of `AgentContext`'s cascade; not the wire `format`):
|
|
87
94
|
* ```ts
|
|
88
95
|
* const provider = createOllama({
|
|
89
96
|
* model: 'qwen3.5:2b-q4_K_M',
|
|
@@ -100,8 +107,9 @@ export declare function buildResult(content: string, thinking: string, tools: re
|
|
|
100
107
|
export declare function createOllama(options: OllamaOptions): ProviderInterface;
|
|
101
108
|
|
|
102
109
|
/**
|
|
103
|
-
* Names how long the model stays resident after a call
|
|
104
|
-
* omitted
|
|
110
|
+
* Names how long the model stays resident after a call — `'5m'` when
|
|
111
|
+
* `OllamaOptions.keepAlive` is omitted, Ollama's own `keep_alive` default, expressed as a
|
|
112
|
+
* duration string.
|
|
105
113
|
*
|
|
106
114
|
* @remarks
|
|
107
115
|
* The name mirrors the Ollama `/api/chat` `keep_alive` field this value is sent as, so
|
|
@@ -109,12 +117,15 @@ export declare function createOllama(options: OllamaOptions): ProviderInterface;
|
|
|
109
117
|
*/
|
|
110
118
|
export declare const DEFAULT_KEEP_ALIVE = "5m";
|
|
111
119
|
|
|
112
|
-
/**
|
|
120
|
+
/**
|
|
121
|
+
* Names the local Ollama daemon base URL, `'http://localhost:11434'`, assumed when
|
|
122
|
+
* `OllamaOptions.url` is omitted.
|
|
123
|
+
*/
|
|
113
124
|
export declare const DEFAULT_OLLAMA_URL = "http://localhost:11434";
|
|
114
125
|
|
|
115
126
|
/**
|
|
116
|
-
* Names the per-call deadline in milliseconds when `OllamaOptions.timeout` is
|
|
117
|
-
* generous enough that a cold model load does not trip it.
|
|
127
|
+
* Names the per-call deadline in milliseconds, `120_000`, when `OllamaOptions.timeout` is
|
|
128
|
+
* omitted — generous enough that a cold model load does not trip it.
|
|
118
129
|
*/
|
|
119
130
|
export declare const DEFAULT_PROVIDER_TIMEOUT = 120000;
|
|
120
131
|
|
|
@@ -205,17 +216,22 @@ export declare function extractUsage(record: Readonly<Record<string, unknown>>):
|
|
|
205
216
|
/**
|
|
206
217
|
* Checks whether a value is an {@link OllamaHTTPError}.
|
|
207
218
|
*
|
|
219
|
+
* @remarks
|
|
220
|
+
* The check is an `instanceof` test, so it narrows a caught `unknown` to the error class
|
|
221
|
+
* without parsing the thrown message.
|
|
222
|
+
*
|
|
208
223
|
* @param value - The value to test
|
|
209
224
|
* @returns True if `value` is an `OllamaHTTPError`; false otherwise
|
|
210
225
|
*/
|
|
211
226
|
export declare function isOllamaHTTPError(value: unknown): value is OllamaHTTPError;
|
|
212
227
|
|
|
213
228
|
/**
|
|
214
|
-
* Joins a call's
|
|
229
|
+
* Joins a call's reasoning carriers — the splitter's separated in-content spans and the
|
|
230
|
+
* accumulated wire-side `message.thinking` — into the result's `thinking`.
|
|
215
231
|
*
|
|
216
232
|
* @param splitter - The per-call splitter holding the separated in-content spans
|
|
217
233
|
* @param wired - The accumulated wire-side `message.thinking` text
|
|
218
|
-
* @returns The
|
|
234
|
+
* @returns The carriers separated by a blank line, or whichever one is non-empty
|
|
219
235
|
*
|
|
220
236
|
* @example
|
|
221
237
|
* ```ts
|
|
@@ -243,15 +259,14 @@ export declare function joinThinking(splitter: ThinkSplitterInterface, wired: st
|
|
|
243
259
|
export declare function mapMessages(messages: readonly Message[]): WireChatRequest['messages'];
|
|
244
260
|
|
|
245
261
|
/**
|
|
246
|
-
* Names the cap,
|
|
262
|
+
* Names the character cap, `2048`, on how much of a non-OK response body is
|
|
247
263
|
* incorporated into a thrown {@link OllamaHTTPError}'s message.
|
|
248
264
|
*
|
|
249
265
|
* @remarks
|
|
250
266
|
* Bounds the excerpt so a defensive proxy or a misbehaving daemon handing
|
|
251
267
|
* back an unbounded response body cannot inflate the thrown error's message
|
|
252
|
-
* without limit
|
|
253
|
-
*
|
|
254
|
-
* concern.
|
|
268
|
+
* without limit, while the cap stays generous enough to carry a useful
|
|
269
|
+
* diagnostic snippet.
|
|
255
270
|
*/
|
|
256
271
|
export declare const MAX_ERROR_BODY_LENGTH = 2048;
|
|
257
272
|
|
|
@@ -263,7 +278,8 @@ export declare const MAX_ERROR_BODY_LENGTH = 2048;
|
|
|
263
278
|
* HTTP response was received at all, for example a `null` body). Thrown by
|
|
264
279
|
* {@link OllamaProvider} at its HTTP failure sites — the non-OK status branch and the
|
|
265
280
|
* null-body branch — so a caller can branch on `error.code` and read `error.status`
|
|
266
|
-
* for the HTTP number instead of parsing the message.
|
|
281
|
+
* for the HTTP number instead of parsing the message. The message carries a body excerpt
|
|
282
|
+
* bounded to {@link MAX_ERROR_BODY_LENGTH} — `2048` characters. Narrow a caught value with
|
|
267
283
|
* {@link isOllamaHTTPError}.
|
|
268
284
|
*
|
|
269
285
|
* @example
|
|
@@ -311,8 +327,8 @@ export declare interface OllamaHTTPErrorOptions {
|
|
|
311
327
|
*
|
|
312
328
|
* The optional `fetch` + `headers` form a **transport seam**: by default the provider
|
|
313
329
|
* talks straight to a local daemon over `globalThis.fetch` with only a JSON content
|
|
314
|
-
* type, but a browser-side runtime can inject a custom transport
|
|
315
|
-
* (for example an obfuscated bearer token) so requests route through the developer's
|
|
330
|
+
* type, but a browser-side runtime can inject both a custom transport and a dynamic header
|
|
331
|
+
* (for example an obfuscated bearer token) so requests route through the developer's own
|
|
316
332
|
* server, which validates that header and forwards to the real LLM. Your app never
|
|
317
333
|
* holds a real API key — the real key lives only on the developer's server; the
|
|
318
334
|
* `headers` hook supplies whatever short-lived/obfuscated token that server expects.
|
|
@@ -337,12 +353,12 @@ export declare interface OllamaOptions {
|
|
|
337
353
|
readonly options?: Readonly<Record<string, unknown>>;
|
|
338
354
|
/**
|
|
339
355
|
* Sets the `/api/chat` `think` wire flag; defaults to `false`. When `true`, a thinking-capable
|
|
340
|
-
* model (for example `qwen3`) separates its reasoning
|
|
356
|
+
* model (for example `qwen3`) separates its reasoning natively at the wire — the daemon returns it
|
|
341
357
|
* on the distinct `message.thinking` channel (surfaced on `ProviderResult.thinking`) rather
|
|
342
358
|
* than inline in `message.content`. The default is `false`, so a non-thinking model needs no
|
|
343
359
|
* configuration and answers immediately; the per-call ThinkSplitter
|
|
344
360
|
* remains the defensive fallback for daemons/models that still inline `<think>` tags either
|
|
345
|
-
* way. Set it `true` for a thinking model whose reasoning you intend to
|
|
361
|
+
* way. Set it `true` for a thinking model whose reasoning you intend to display separately.
|
|
346
362
|
*/
|
|
347
363
|
readonly think?: boolean;
|
|
348
364
|
/**
|
|
@@ -357,18 +373,18 @@ export declare interface OllamaOptions {
|
|
|
357
373
|
* headers are merged into the request on top of the base `Content-Type`. Use it to
|
|
358
374
|
* attach an authorization header — for example an obfuscated/generated bearer token the
|
|
359
375
|
* developer's server validates before relaying to the real LLM — so a browser
|
|
360
|
-
* runtime can authenticate
|
|
376
|
+
* runtime can authenticate without your app ever handling a real API key. Async so a
|
|
361
377
|
* token can be refreshed/fetched per call. A returned `Content-Type` overrides the
|
|
362
378
|
* default; other headers add to it. Omitted ⇒ only `Content-Type: application/json`.
|
|
363
379
|
*/
|
|
364
380
|
readonly headers?: () => Readonly<Record<string, string>> | Promise<Readonly<Record<string, string>>>;
|
|
365
381
|
/**
|
|
366
|
-
* Sets the provider's
|
|
382
|
+
* Sets the provider's optional context-framing default — the provider-default level of
|
|
367
383
|
* `AgentContext`'s format cascade (beaten by a manager-options or per-item override,
|
|
368
384
|
* beating the managers' built-in framing). Declares how this provider's models prefer
|
|
369
385
|
* context sections framed (for example XML group wrappers vs. Markdown headers). Omitted ⇒
|
|
370
|
-
* the provider is framing-agnostic and core's built-in defaults apply unchanged.
|
|
371
|
-
*
|
|
386
|
+
* the provider is framing-agnostic and core's built-in defaults apply unchanged. This
|
|
387
|
+
* is the prompt-context framing consumed by `AgentContext.build()` — it is not
|
|
372
388
|
* Ollama's `/api/chat` `format` wire parameter (structured-output / JSON schema),
|
|
373
389
|
* which this provider sends only when a call supplies a `schema`; the two are unrelated
|
|
374
390
|
* despite the shared word.
|
|
@@ -383,16 +399,16 @@ export declare interface OllamaOptions {
|
|
|
383
399
|
* @remarks
|
|
384
400
|
* - **Wire protocol.** Posts `{ model, messages, stream, keep_alive, think }` plus
|
|
385
401
|
* passthrough sampling `options` and mapped function `tools`. The `think` flag is
|
|
386
|
-
*
|
|
402
|
+
* configurable through {@link OllamaOptions.think} (default `false`). Non-stream parses
|
|
387
403
|
* one JSON body; stream consumes NDJSON (one JSON object per `\n`-terminated line) —
|
|
388
404
|
* deltas carry `message.content`, the final `done: true` line carries the token usage.
|
|
389
405
|
* - **Think separation.** The wire `think` flag is configurable
|
|
390
406
|
* ({@link OllamaOptions.think}, default `false`). With `think: true` a thinking model's
|
|
391
|
-
* daemon separates reasoning
|
|
392
|
-
* channel (read here through `extractThinking`) instead of inline in `message.content`.
|
|
407
|
+
* daemon separates reasoning natively — returning it on the distinct `message.thinking`
|
|
408
|
+
* channel (read here through `extractThinking`) instead of inline in `message.content`. Either
|
|
393
409
|
* way the per-call {@link ThinkSplitterInterface} is the defensive guarantee: a daemon
|
|
394
410
|
* may ignore `think: false` for a thinking model and inline `<think>` tags, so every
|
|
395
|
-
* content delta routes through the splitter, only
|
|
411
|
+
* content delta routes through the splitter, only clean content is yielded / assembled,
|
|
396
412
|
* and the separated reasoning (plus any daemon-side `message.thinking` deltas) lands on
|
|
397
413
|
* `ProviderResult.thinking`, never in the conversation.
|
|
398
414
|
* - **Boundary narrowing.** Every wire value arrives as `unknown` and is
|
|
@@ -401,11 +417,11 @@ export declare interface OllamaOptions {
|
|
|
401
417
|
* usage, `{}` arguments), never a throw.
|
|
402
418
|
* - **Bounded.** Each call arms a {@link Timeout} for `OllamaOptions.timeout` and
|
|
403
419
|
* passes `AbortSignal.any([timeout.signal, signal])` to `fetch`, so the caller's
|
|
404
|
-
* signal
|
|
420
|
+
* signal and the deadline both cancel the request. The timeout is always cleared —
|
|
405
421
|
* in `#fetch` if the request fails/aborts, otherwise in the consuming call's `finally`.
|
|
406
422
|
* - **Abort recovers partial.** A `stream` cancelled mid-flight throws a
|
|
407
423
|
* `ProviderAbortError` carrying the partial result assembled so far; pairing the
|
|
408
|
-
* `TextDecoder({ stream: true })` with the
|
|
424
|
+
* `TextDecoder({ stream: true })` with the `createNDJSONParser` parser keeps multi-byte
|
|
409
425
|
* UTF-8 splits and partial lines honest.
|
|
410
426
|
* - **Event-free.** A pure functional boundary — no Emitter, no events.
|
|
411
427
|
* - **Transport seam.** {@link OllamaOptions.fetch} swaps the transport (default
|
|
@@ -436,107 +452,146 @@ export declare class OllamaProvider implements ProviderInterface {
|
|
|
436
452
|
*/
|
|
437
453
|
get id(): string;
|
|
438
454
|
/**
|
|
439
|
-
* Exposes the provider's context-framing default — the
|
|
440
|
-
* {@link import('@orkestrel/agent').AgentContextInterface.build}'s format cascade (it
|
|
441
|
-
* the managers' built-in framing, is
|
|
442
|
-
* Satisfies the
|
|
455
|
+
* Exposes the provider's context-framing default — the provider-default level of
|
|
456
|
+
* {@link import('@orkestrel/agent').AgentContextInterface.build}'s format cascade (it beats
|
|
457
|
+
* the managers' built-in framing, is beaten by a manager-options or per-item override).
|
|
458
|
+
* Satisfies the optional {@link ProviderInterface.format} contract member: `undefined`
|
|
443
459
|
* when {@link OllamaOptions.format} was omitted (the framing-agnostic default ⇒ core's
|
|
444
460
|
* built-in framing applies unchanged), else the exact configured framing the Agent
|
|
445
461
|
* threads into `build()`.
|
|
446
462
|
*
|
|
447
463
|
* @remarks
|
|
448
|
-
*
|
|
449
|
-
* on the `/api/chat` wire (it is absent from `#body` / the request). This is
|
|
450
|
-
* structured-output `format` wire parameter — that one
|
|
464
|
+
* Expose-only — read by the Agent loop and consumed by core's cascade; it is never sent
|
|
465
|
+
* on the `/api/chat` wire (it is absent from `#body` / the request). This is not Ollama's
|
|
466
|
+
* structured-output `format` wire parameter — that one is sent in `#body`, but only when
|
|
451
467
|
* a per-call `ProviderStreamOptions.schema` is supplied; only the word collides.
|
|
452
468
|
*
|
|
453
469
|
* @returns The configured {@link ContextFormat}, or `undefined` when none
|
|
454
470
|
*/
|
|
455
471
|
get format(): ContextFormat | undefined;
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
472
|
+
/**
|
|
473
|
+
* Generates one complete turn and resolves the assembled result — the clean content,
|
|
474
|
+
* any separated reasoning, any tool calls, and any usage the wire reported.
|
|
475
|
+
*
|
|
476
|
+
* @remarks
|
|
477
|
+
* Sends `stream: false` and parses one JSON body. Content routes through a per-call
|
|
478
|
+
* think splitter, so the assembled content stays clean even where the daemon renders a
|
|
479
|
+
* thinking model's reasoning inline; the separated spans and any daemon-side
|
|
480
|
+
* `message.thinking` land on `thinking`. The caller's signal and the armed deadline
|
|
481
|
+
* both cancel the request, and the deadline is cleared once the body is read.
|
|
482
|
+
*
|
|
483
|
+
* @param messages - The conversation turns to send
|
|
484
|
+
* @param signal - The caller's bounding signal, folded with the armed deadline
|
|
485
|
+
* @param tools - The callable tools to advertise for this turn, when the caller passes any
|
|
486
|
+
* @param options - The per-call overrides, `think` and `schema` among them
|
|
487
|
+
* @returns The assembled result of the turn
|
|
488
|
+
* @throws {@link OllamaHTTPError} When the daemon answers a non-OK status.
|
|
489
|
+
*/
|
|
490
|
+
generate(messages: readonly Message[], signal: AbortSignal, tools?: readonly ToolDefinition[], options?: ProviderStreamOptions): Promise<ProviderResult>;
|
|
491
|
+
/**
|
|
492
|
+
* Streams one turn, yielding a channel-tagged delta per non-empty content or reasoning
|
|
493
|
+
* span and returning the assembled result when the stream completes.
|
|
494
|
+
*
|
|
495
|
+
* @remarks
|
|
496
|
+
* Sends `stream: true` and consumes NDJSON — one JSON object per newline-terminated
|
|
497
|
+
* line — pairing a streaming `TextDecoder` with the `NDJSONParser` so a record split
|
|
498
|
+
* across byte reads is reassembled. The returned result's content is the splitter's
|
|
499
|
+
* clean accumulation, beside any tool calls collected across lines and the usage the
|
|
500
|
+
* `done` line carries. A cancel mid-flight throws a `ProviderAbortError` carrying the
|
|
501
|
+
* partial assembled so far.
|
|
502
|
+
*
|
|
503
|
+
* @param messages - The conversation turns to send
|
|
504
|
+
* @param signal - The caller's bounding signal, folded with the armed deadline
|
|
505
|
+
* @param tools - The callable tools to advertise for this turn, when the caller passes any
|
|
506
|
+
* @param options - The per-call overrides, `think` and `schema` among them
|
|
507
|
+
* @returns The assembled result of the turn, after the last delta
|
|
508
|
+
* @throws {@link OllamaHTTPError} When the daemon answers a non-OK status or a `null` body.
|
|
509
|
+
*/
|
|
510
|
+
stream(messages: readonly Message[], signal: AbortSignal, tools?: readonly ToolDefinition[], options?: ProviderStreamOptions): AsyncGenerator<ProviderDelta, ProviderResult>;
|
|
511
|
+
}
|
|
459
512
|
|
|
460
|
-
/**
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
export declare interface OllamaResponse {
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
}
|
|
513
|
+
/**
|
|
514
|
+
* Represents an open `POST /api/chat` response together with the deadline and the
|
|
515
|
+
* combined signal that bound the request.
|
|
516
|
+
*
|
|
517
|
+
* @remarks
|
|
518
|
+
* The `response` is the open `POST /api/chat` `Response`; `timeout` is the armed
|
|
519
|
+
* {@link TimeoutInterface} the consuming call clears once it finishes reading the body
|
|
520
|
+
* (or that the provider clears on a failed or aborted request); `combined` is the
|
|
521
|
+
* `AbortSignal.any([timeout.signal, callerSignal])` the request was issued under, which
|
|
522
|
+
* the streaming path checks to tell a mid-stream cancel apart from any other error.
|
|
523
|
+
*/
|
|
524
|
+
export declare interface OllamaResponse {
|
|
525
|
+
readonly response: Response;
|
|
526
|
+
readonly timeout: TimeoutInterface;
|
|
527
|
+
readonly combined: AbortSignal;
|
|
528
|
+
}
|
|
476
529
|
|
|
477
|
-
/**
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
export declare function parseBody(response: Response): Promise<Readonly<Record<string, unknown>> | undefined>;
|
|
530
|
+
/**
|
|
531
|
+
* Parses a non-stream `/api/chat` response body into a wire record.
|
|
532
|
+
*
|
|
533
|
+
* @remarks
|
|
534
|
+
* Total by construction: an empty body, a body that is not JSON, and a body whose JSON is
|
|
535
|
+
* not an object all yield `undefined`, so a malformed daemon response never escapes as a
|
|
536
|
+
* `SyntaxError`. The call site supplies the empty-record default that reads as empty
|
|
537
|
+
* content and no usage.
|
|
538
|
+
*
|
|
539
|
+
* @param response - The 200-OK `/api/chat` response whose body is read as text
|
|
540
|
+
* @returns The parsed record, or `undefined` when the body is empty or malformed
|
|
541
|
+
*
|
|
542
|
+
* @example
|
|
543
|
+
* ```ts
|
|
544
|
+
* await parseBody(new Response('{"message":{"content":"ok"}}'))
|
|
545
|
+
* // { message: { content: 'ok' } }
|
|
546
|
+
* ```
|
|
547
|
+
*/
|
|
548
|
+
export declare function parseBody(response: Response): Promise<Readonly<Record<string, unknown>> | undefined>;
|
|
496
549
|
|
|
497
|
-
/**
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
550
|
+
/**
|
|
551
|
+
* Represents the exact `POST /api/chat` request body `OllamaProvider` sends — the internal typed
|
|
552
|
+
* wire contract.
|
|
553
|
+
*
|
|
554
|
+
* @remarks
|
|
555
|
+
* This is the typed wire shape asserted against the official `ollama` client's
|
|
556
|
+
* `ChatRequest` by the compile-time parity test; `src/` never imports `ollama` itself.
|
|
557
|
+
* `messages` mirrors the minimal turn shape `mapMessages` builds (`role` / `content`, plus
|
|
558
|
+
* `tool_calls` only on a turn that replays them and `images` only on a multimodal
|
|
559
|
+
* turn); `options` and `tools` are only present when configured. `format` carries the
|
|
560
|
+
* `/api/chat` structured-output constraint, forwarded verbatim from the per-call
|
|
561
|
+
* `ProviderStreamOptions.schema` and absent when no schema is supplied.
|
|
562
|
+
*/
|
|
563
|
+
export declare interface WireChatRequest {
|
|
564
|
+
readonly model: string;
|
|
565
|
+
readonly messages: ReadonlyArray<{
|
|
566
|
+
readonly role: string;
|
|
567
|
+
readonly content: string;
|
|
568
|
+
readonly tool_calls?: ReadonlyArray<{
|
|
569
|
+
readonly function: {
|
|
570
|
+
readonly name: string;
|
|
571
|
+
readonly arguments: Readonly<Record<string, unknown>>;
|
|
572
|
+
};
|
|
573
|
+
}>;
|
|
574
|
+
readonly images?: readonly string[];
|
|
575
|
+
}>;
|
|
576
|
+
readonly stream: boolean;
|
|
577
|
+
readonly keep_alive: string | number;
|
|
578
|
+
readonly think: boolean;
|
|
579
|
+
readonly options?: Readonly<Record<string, unknown>>;
|
|
580
|
+
readonly tools?: ReadonlyArray<{
|
|
581
|
+
readonly type: 'function';
|
|
582
|
+
readonly function: {
|
|
583
|
+
readonly name: string;
|
|
584
|
+
readonly description?: string;
|
|
585
|
+
readonly parameters?: Readonly<Record<string, unknown>>;
|
|
586
|
+
};
|
|
587
|
+
}>;
|
|
588
|
+
/**
|
|
589
|
+
* Holds the `/api/chat` structured-output constraint — a JSON-Schema object forwarded
|
|
590
|
+
* verbatim from the per-call `ProviderStreamOptions.schema`. This is not
|
|
591
|
+
* `OllamaOptions.format` (the unrelated prompt-context framing); only present
|
|
592
|
+
* when a call supplies a `schema`.
|
|
593
|
+
*/
|
|
594
|
+
readonly format?: Readonly<Record<string, unknown>>;
|
|
595
|
+
}
|
|
541
596
|
|
|
542
|
-
export { }
|
|
597
|
+
export { }
|