@byfriends/kosong 0.1.0 → 0.2.1

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.
Files changed (29) hide show
  1. package/dist/{anthropic-Dm_GqFgS.d.mts → anthropic-0CVG5rBE.d.mts} +1 -2
  2. package/dist/{provider-DiJKWMsQ.d.mts → errors-wlT14tC4.d.mts} +227 -2
  3. package/dist/{google-genai-hX0X6CF3.d.mts → google-genai-xKK8lI_R.d.mts} +1 -2
  4. package/dist/index.d.mts +66 -12
  5. package/dist/index.mjs +945 -21
  6. package/dist/{openai-common-08qin3UI.mjs → openai-common-Dl42y_vn.mjs} +27 -2
  7. package/dist/{openai-common-B6cK2ig3.d.mts → openai-common-DwkxUSyI.d.mts} +7 -3
  8. package/dist/{openai-responses-BxOwxtd3.d.mts → openai-responses-DZ9mQ5RA.d.mts} +2 -2
  9. package/dist/providers/anthropic.d.mts +1 -1
  10. package/dist/providers/anthropic.mjs +56 -68
  11. package/dist/providers/google-genai.d.mts +1 -1
  12. package/dist/providers/google-genai.mjs +1 -2
  13. package/dist/providers/openai-common.d.mts +1 -1
  14. package/dist/providers/openai-common.mjs +1 -1
  15. package/dist/providers/openai-responses.d.mts +1 -1
  16. package/dist/providers/openai-responses.mjs +21 -4
  17. package/dist/request-auth-BMXt8jRu.mjs +341 -0
  18. package/package.json +1 -11
  19. package/dist/capability-registry-CMBuEYcf.mjs +0 -161
  20. package/dist/chat-completions-stream-BuMu_xr9.mjs +0 -62
  21. package/dist/errors-DweKbIOf.d.mts +0 -42
  22. package/dist/openai-compat-CMrIk-ib.d.mts +0 -132
  23. package/dist/openai-compat-CWbwO4b7.mjs +0 -801
  24. package/dist/openai-legacy-B6CVfLlr.d.mts +0 -71
  25. package/dist/providers/openai-compat.d.mts +0 -2
  26. package/dist/providers/openai-compat.mjs +0 -2
  27. package/dist/providers/openai-legacy.d.mts +0 -2
  28. package/dist/providers/openai-legacy.mjs +0 -248
  29. package/dist/request-auth-DCWSyCKI.mjs +0 -63
@@ -1,5 +1,4 @@
1
- import { a as StreamedMessage, b as Message, i as ProviderRequestAuth, m as ModelCapability, o as ThinkingEffort, p as Tool, r as GenerateOptions, t as ChatProvider } from "./provider-DiJKWMsQ.mjs";
2
- import { o as ChatProviderError } from "./errors-DweKbIOf.mjs";
1
+ import { P as Message, S as ModelCapability, d as StreamedMessage, f as ThinkingEffort, l as GenerateOptions, o as ChatProviderError, s as ChatProvider, u as ProviderRequestAuth, x as Tool } from "./errors-wlT14tC4.mjs";
3
2
  import Anthropic from "@anthropic-ai/sdk";
4
3
  import { MessageCreateParams } from "@anthropic-ai/sdk/resources/messages/messages.js";
5
4
 
@@ -38,6 +38,18 @@ interface VideoURLPart {
38
38
  * {@link ChatProvider.generate}.
39
39
  */
40
40
  type ContentPart = TextPart | ThinkPart | ImageURLPart | AudioURLPart | VideoURLPart;
41
+ /**
42
+ * Cache hint metadata attached to a {@link Message}.
43
+ *
44
+ * Used by the cache staking layer to signal which messages are good
45
+ * cache breakpoint candidates (e.g. the last message of a previous turn).
46
+ * The Anthropic adapter reads these hints to inject `cache_control` on
47
+ * the appropriate content blocks.
48
+ */
49
+ interface CacheHint {
50
+ readonly isLastTurnEnd?: boolean;
51
+ readonly isSuddenLargeContext?: boolean;
52
+ }
41
53
  interface ToolCall {
42
54
  type: 'function';
43
55
  id: string;
@@ -100,6 +112,8 @@ interface Message {
100
112
  toolCallId?: string;
101
113
  /** When `true`, indicates the message was not fully received (e.g. stream interrupted). */
102
114
  partial?: boolean;
115
+ /** Cache hint metadata for prompt caching strategies. */
116
+ cacheHint?: CacheHint;
103
117
  }
104
118
  /** Check if a streamed part is a ContentPart (text, think, image_url, audio_url, video_url). */
105
119
  declare function isContentPart(part: StreamedMessagePart): part is ContentPart;
@@ -140,7 +154,146 @@ declare function createAssistantMessage(content: ContentPart[], toolCalls?: Tool
140
154
  /** Create a tool result message. */
141
155
  declare function createToolMessage(toolCallId: string, output: string | ContentPart[]): Message;
142
156
  //#endregion
157
+ //#region src/prompt-plan.d.ts
158
+ /**
159
+ * Cache scope for a {@link PromptBlock} in a {@link PromptPlan}.
160
+ *
161
+ * Scopes determine the lifetime and sharing boundaries of cached prompt
162
+ * content, allowing providers to apply cache-breaking policies appropriately.
163
+ *
164
+ * - `'global'`: Content is cacheable across all projects/sessions. Useful for
165
+ * stable system prompts that rarely change.
166
+ * - `'project'`: Content is cacheable within a single project. Typical for
167
+ * project-specific instructions, domain knowledge, or coding standards.
168
+ * - `'session'`: Content is cacheable only within the current session.
169
+ * Appropriate for conversation context that persists across turns but not
170
+ * across sessions.
171
+ * - `'none'`: Content is not cacheable. Use for ephemeral or highly dynamic
172
+ * content (user input, temporary context, rapidly changing data).
173
+ */
174
+ type CacheScope = 'global' | 'project' | 'session' | 'none';
175
+ /**
176
+ * Cache strategy supported by a provider.
177
+ *
178
+ * Each provider advertises which caching mechanism it implements via
179
+ * {@link ProviderCacheCapability.strategy}. Consumers must respect this
180
+ * when constructing {@link PromptPlan}s to avoid sending unsupported
181
+ * cache directives.
182
+ *
183
+ * - `'explicit-block'`: Provider supports explicit cache control at the
184
+ * block level (e.g., Anthropic's `cache_control` headers). Each
185
+ * {@link PromptBlock} can be independently marked as cacheable.
186
+ * - `'prompt-cache-key'`: Provider supports a cache key that spans the
187
+ * entire prompt (OpenAI's `prompt_cache_key` approach).
188
+ * - `'prefix-match'`: Provider caches by matching prompt prefixes
189
+ * (OpenAI's automatic prefix caching for repeated prefixes).
190
+ * Reserved for future use — no provider currently declares this strategy.
191
+ * - `'none'`: Provider does not support prompt caching.
192
+ */
193
+ type CacheStrategy = 'explicit-block' | 'prompt-cache-key' | 'prefix-match' | 'none';
194
+ /**
195
+ * A single named block of text with an associated cache scope.
196
+ *
197
+ * {@link PromptPlan}s are composed of multiple blocks, each with its own
198
+ * caching semantics. This structure allows providers to apply different
199
+ * cache policies to different parts of the system prompt (e.g., global
200
+ * instructions vs. session-specific context).
201
+ *
202
+ * @readonly
203
+ */
204
+ interface PromptBlock {
205
+ /**
206
+ * Identifier for this block.
207
+ *
208
+ * Used for debugging, logging, and potentially for cache key generation.
209
+ * Should be stable and descriptive (e.g., `'system-instructions'`,
210
+ * `'project-context'`).
211
+ */
212
+ readonly name: string;
213
+ /**
214
+ * Text content of this block.
215
+ *
216
+ * The actual prompt text that will be sent to the LLM. Blocks are
217
+ * typically concatenated in order when constructing the full system
218
+ * prompt.
219
+ */
220
+ readonly text: string;
221
+ /**
222
+ * Cache scope for this block.
223
+ *
224
+ * Determines how providers may cache this content. See {@link CacheScope}
225
+ * for details on each scope's semantics.
226
+ */
227
+ readonly cacheScope: CacheScope;
228
+ }
229
+ /**
230
+ * A structured prompt plan that defines cacheable blocks.
231
+ *
232
+ * PromptPlans allow consumers to provide explicit caching hints alongside
233
+ * their prompt content. When passed via {@link GenerateOptions.promptPlan},
234
+ * providers that support caching can translate the plan into their native
235
+ * cache control format.
236
+ *
237
+ * Example usage:
238
+ * ```ts
239
+ * const plan: PromptPlan = {
240
+ * blocks: [
241
+ * { name: 'system', text: 'You are a helpful assistant.', cacheScope: 'global' },
242
+ * { name: 'project', text: 'Project-specific rules...', cacheScope: 'project' },
243
+ * { name: 'context', text: 'Current session context...', cacheScope: 'session' },
244
+ * { name: 'user-query', text: 'Answer this question...', cacheScope: 'none' },
245
+ * ],
246
+ * };
247
+ * ```
248
+ *
249
+ * @readonly
250
+ */
251
+ interface PromptPlan {
252
+ /**
253
+ * Ordered list of blocks that compose this prompt plan.
254
+ *
255
+ * Blocks are typically concatenated in order when constructing the full
256
+ * system prompt. Each block's `cacheScope` determines its caching
257
+ * semantics.
258
+ */
259
+ readonly blocks: readonly PromptBlock[];
260
+ }
261
+ //#endregion
143
262
  //#region src/capability.d.ts
263
+ /**
264
+ * Cache capability advertised by a provider.
265
+ *
266
+ * Providers that support prompt caching expose this via
267
+ * {@link ModelCapability.cache} to describe which caching mechanisms they
268
+ * implement and any constraints consumers must respect.
269
+ *
270
+ * @readonly
271
+ */
272
+ interface ProviderCacheCapability {
273
+ /**
274
+ * The caching strategy supported by this provider.
275
+ *
276
+ * See {@link CacheStrategy} for strategy descriptions and semantics.
277
+ */
278
+ readonly strategy: CacheStrategy;
279
+ /**
280
+ * Maximum number of cacheable blocks supported.
281
+ *
282
+ * Only applicable for `'explicit-block'` strategy. Providers may limit
283
+ * the number of distinct cache points they support (e.g., Anthropic
284
+ * supports up to 4 cache breakpoints). Omitted means "unknown" or "no
285
+ * practical limit."
286
+ */
287
+ readonly maxCacheableBlocks?: number;
288
+ /**
289
+ * Cache scopes supported by this provider.
290
+ *
291
+ * Providers may not support all scopes (e.g., some may not support
292
+ * `'global'` scoping). When omitted, consumers should assume all scopes
293
+ * are supported.
294
+ */
295
+ readonly supportedScopes?: readonly CacheScope[];
296
+ }
144
297
  /**
145
298
  * Declared capabilities for a specific model exposed by a {@link ChatProvider}.
146
299
  *
@@ -157,7 +310,18 @@ interface ModelCapability {
157
310
  readonly audio_in: boolean;
158
311
  readonly thinking: boolean;
159
312
  readonly tool_use: boolean;
313
+ readonly thinking_effort: boolean;
314
+ readonly thinking_xhigh: boolean;
315
+ readonly thinking_max: boolean;
160
316
  readonly max_context_tokens: number;
317
+ /**
318
+ * Cache capability for this model.
319
+ *
320
+ * Present when the provider supports prompt caching. Consumers can inspect
321
+ * this field to determine which caching strategies and scopes are
322
+ * available, then construct appropriate {@link PromptPlan}s.
323
+ */
324
+ readonly cache?: ProviderCacheCapability;
161
325
  }
162
326
  /**
163
327
  * Shared read-only default returned when a provider has not catalogued a
@@ -217,6 +381,19 @@ declare function emptyUsage(): TokenUsage;
217
381
  * Sum two TokenUsage values.
218
382
  */
219
383
  declare function addUsage(a: TokenUsage, b: TokenUsage): TokenUsage;
384
+ /**
385
+ * Branded type for cache hit rate to avoid accidental misuse as a raw number.
386
+ */
387
+ type CacheHitRate = number & {
388
+ readonly __brand: unique symbol;
389
+ };
390
+ /**
391
+ * Compute the cache hit rate as a branded number between 0 and 1.
392
+ *
393
+ * Returns `undefined` when no input tokens were processed (inputTotal === 0),
394
+ * so callers can distinguish "no data" from "zero hits".
395
+ */
396
+ declare function cacheHitRate(usage: TokenUsage): CacheHitRate | undefined;
220
397
  //#endregion
221
398
  //#region src/provider.d.ts
222
399
  /**
@@ -304,6 +481,13 @@ interface GenerateOptions {
304
481
  * each request/retry so providers never retain mutable credential state.
305
482
  */
306
483
  auth?: ProviderRequestAuth;
484
+ /**
485
+ * Structured prompt plan with explicit cache scoping.
486
+ *
487
+ * When provided, providers that support caching may translate this into
488
+ * their native cache control format.
489
+ */
490
+ promptPlan?: PromptPlan;
307
491
  }
308
492
  /**
309
493
  * In-memory video bytes for providers that require an uploaded file
@@ -347,7 +531,7 @@ interface ChatProvider {
347
531
  *
348
532
  * Implementations MUST NOT mutate or replace internal HTTP clients on the
349
533
  * returned clone — the clone is expected to share transport state with the
350
- * original. See `OpenAICompatChatProvider._clone()` for the rationale.
534
+ * original. See `OpenAICompletionsChatProvider._clone()` for the rationale.
351
535
  */
352
536
  withMaxCompletionTokens?(maxCompletionTokens: number): ChatProvider;
353
537
  /** Upload a video and return a content part that can be sent to this provider. */
@@ -368,4 +552,45 @@ interface ChatProvider {
368
552
  getContextSizeLimit?(): number | undefined;
369
553
  }
370
554
  //#endregion
371
- export { createUserMessage as A, TextPart as C, VideoURLPart as D, ToolCallPart as E, mergeInPlace as F, isContentPart as M, isToolCall as N, createAssistantMessage as O, isToolCallPart as P, StreamedMessagePart as S, ToolCall as T, AudioURLPart as _, StreamedMessage as a, Message as b, TokenUsage as c, grandTotal as d, inputTotal as f, isUnknownCapability as g, UNKNOWN_CAPABILITY as h, ProviderRequestAuth as i, extractText as j, createToolMessage as k, addUsage as l, ModelCapability as m, FinishReason as n, ThinkingEffort as o, Tool as p, GenerateOptions as r, VideoUploadInput as s, ChatProvider as t, emptyUsage as u, ContentPart as v, ThinkPart as w, Role as x, ImageURLPart as y };
555
+ //#region src/errors.d.ts
556
+ /**
557
+ * Base error for all chat provider errors.
558
+ */
559
+ declare class ChatProviderError extends Error {
560
+ constructor(message: string);
561
+ }
562
+ /**
563
+ * Network-level connection failure.
564
+ */
565
+ declare class APIConnectionError extends ChatProviderError {
566
+ constructor(message: string);
567
+ }
568
+ /**
569
+ * Request timed out.
570
+ */
571
+ declare class APITimeoutError extends ChatProviderError {
572
+ constructor(message: string);
573
+ }
574
+ /**
575
+ * HTTP status error from the API.
576
+ */
577
+ declare class APIStatusError extends ChatProviderError {
578
+ readonly statusCode: number;
579
+ readonly requestId: string | null;
580
+ constructor(statusCode: number, message: string, requestId?: string | null);
581
+ }
582
+ /**
583
+ * HTTP status error that specifically means the request exceeded the model
584
+ * context window.
585
+ */
586
+ declare class APIContextOverflowError extends APIStatusError {
587
+ constructor(statusCode: number, message: string, requestId?: string | null);
588
+ }
589
+ /**
590
+ * The API returned an empty response (no content, no tool calls).
591
+ */
592
+ declare class APIEmptyResponseError extends ChatProviderError {
593
+ constructor(message: string);
594
+ }
595
+ //#endregion
596
+ export { AudioURLPart as A, ToolCallPart as B, ProviderCacheCapability as C, CacheStrategy as D, CacheScope as E, Role as F, extractText as G, createAssistantMessage as H, StreamedMessagePart as I, isToolCallPart as J, isContentPart as K, TextPart as L, ContentPart as M, ImageURLPart as N, PromptBlock as O, Message as P, ThinkPart as R, ModelCapability as S, isUnknownCapability as T, createToolMessage as U, VideoURLPart as V, createUserMessage as W, mergeInPlace as Y, cacheHitRate as _, APITimeoutError as a, inputTotal as b, FinishReason as c, StreamedMessage as d, ThinkingEffort as f, addUsage as g, TokenUsage as h, APIStatusError as i, CacheHint as j, PromptPlan as k, GenerateOptions as l, CacheHitRate as m, APIContextOverflowError as n, ChatProviderError as o, VideoUploadInput as p, isToolCall as q, APIEmptyResponseError as r, ChatProvider as s, APIConnectionError as t, ProviderRequestAuth as u, emptyUsage as v, UNKNOWN_CAPABILITY as w, Tool as x, grandTotal as y, ToolCall as z };
@@ -1,5 +1,4 @@
1
- import { S as StreamedMessagePart, a as StreamedMessage, b as Message, c as TokenUsage, i as ProviderRequestAuth, m as ModelCapability, n as FinishReason, o as ThinkingEffort, p as Tool, r as GenerateOptions, t as ChatProvider } from "./provider-DiJKWMsQ.mjs";
2
- import { o as ChatProviderError } from "./errors-DweKbIOf.mjs";
1
+ import { I as StreamedMessagePart, P as Message, S as ModelCapability, c as FinishReason, d as StreamedMessage, f as ThinkingEffort, h as TokenUsage, l as GenerateOptions, o as ChatProviderError, s as ChatProvider, u as ProviderRequestAuth, x as Tool } from "./errors-wlT14tC4.mjs";
3
2
  import { GoogleGenAI } from "@google/genai";
4
3
 
5
4
  //#region src/providers/google-genai.d.ts
package/dist/index.d.mts CHANGED
@@ -1,19 +1,53 @@
1
- import { A as createUserMessage, C as TextPart, D as VideoURLPart, E as ToolCallPart, F as mergeInPlace, M as isContentPart, N as isToolCall, O as createAssistantMessage, P as isToolCallPart, S as StreamedMessagePart, T as ToolCall, _ as AudioURLPart, a as StreamedMessage, b as Message, c as TokenUsage, d as grandTotal, f as inputTotal, g as isUnknownCapability, h as UNKNOWN_CAPABILITY, i as ProviderRequestAuth, j as extractText, k as createToolMessage, l as addUsage, m as ModelCapability, n as FinishReason, o as ThinkingEffort, p as Tool, r as GenerateOptions, s as VideoUploadInput, t as ChatProvider, u as emptyUsage, v as ContentPart, w as ThinkPart, x as Role, y as ImageURLPart } from "./provider-DiJKWMsQ.mjs";
2
- import { a as APITimeoutError, i as APIStatusError, n as APIContextOverflowError, o as ChatProviderError, r as APIEmptyResponseError, t as APIConnectionError } from "./errors-DweKbIOf.mjs";
3
- import { n as AnthropicOptions } from "./anthropic-Dm_GqFgS.mjs";
4
- import { r as GoogleGenAIOptions } from "./google-genai-hX0X6CF3.mjs";
5
- import { i as OpenAICompatOptions } from "./openai-compat-CMrIk-ib.mjs";
6
- import { r as OpenAILegacyOptions } from "./openai-legacy-B6CVfLlr.mjs";
7
- import { r as OpenAIResponsesOptions } from "./openai-responses-BxOwxtd3.mjs";
1
+ import { A as AudioURLPart, B as ToolCallPart, C as ProviderCacheCapability, D as CacheStrategy, E as CacheScope, F as Role, G as extractText, H as createAssistantMessage, I as StreamedMessagePart, J as isToolCallPart, K as isContentPart, L as TextPart, M as ContentPart, N as ImageURLPart, O as PromptBlock, P as Message, R as ThinkPart, S as ModelCapability, T as isUnknownCapability, U as createToolMessage, V as VideoURLPart, W as createUserMessage, Y as mergeInPlace, _ as cacheHitRate, a as APITimeoutError, b as inputTotal, c as FinishReason, d as StreamedMessage, f as ThinkingEffort, g as addUsage, h as TokenUsage, i as APIStatusError, j as CacheHint, k as PromptPlan, l as GenerateOptions, m as CacheHitRate, n as APIContextOverflowError, o as ChatProviderError, p as VideoUploadInput, q as isToolCall, r as APIEmptyResponseError, s as ChatProvider, t as APIConnectionError, u as ProviderRequestAuth, v as emptyUsage, w as UNKNOWN_CAPABILITY, x as Tool, y as grandTotal, z as ToolCall } from "./errors-wlT14tC4.mjs";
2
+ import { n as AnthropicOptions } from "./anthropic-0CVG5rBE.mjs";
3
+ import { r as GoogleGenAIOptions } from "./google-genai-xKK8lI_R.mjs";
4
+ import { i as ToolMessageConversion } from "./openai-common-DwkxUSyI.mjs";
5
+ import { r as OpenAIResponsesOptions } from "./openai-responses-DZ9mQ5RA.mjs";
6
+ import OpenAI from "openai";
8
7
 
8
+ //#region src/providers/openai-completions.d.ts
9
+ interface OpenAICompletionsOptions {
10
+ apiKey?: string;
11
+ baseUrl?: string;
12
+ model: string;
13
+ stream?: boolean;
14
+ defaultHeaders?: Record<string, string>;
15
+ thinkingEffortKey?: string;
16
+ reasoningKey?: string;
17
+ toolMessageConversion?: ToolMessageConversion;
18
+ generationKwargs?: GenerationKwargs;
19
+ clientFactory?: (auth: ProviderRequestAuth) => OpenAI;
20
+ }
21
+ interface GenerationKwargs {
22
+ max_tokens?: number | undefined;
23
+ max_completion_tokens?: number | undefined;
24
+ temperature?: number | undefined;
25
+ top_p?: number | undefined;
26
+ n?: number | undefined;
27
+ presence_penalty?: number | undefined;
28
+ frequency_penalty?: number | undefined;
29
+ stop?: string | string[] | undefined;
30
+ reasoning_effort?: string | undefined;
31
+ prompt_cache_key?: string | undefined;
32
+ extra_body?: ExtraBody;
33
+ [key: string]: unknown;
34
+ }
35
+ interface ThinkingConfig {
36
+ type?: 'enabled' | 'disabled';
37
+ keep?: unknown;
38
+ [key: string]: unknown;
39
+ }
40
+ interface ExtraBody {
41
+ thinking?: ThinkingConfig;
42
+ [key: string]: unknown;
43
+ }
44
+ //#endregion
9
45
  //#region src/providers/index.d.ts
10
46
  type ProviderConfig = ({
11
47
  type: 'anthropic';
12
48
  } & AnthropicOptions) | ({
13
- type: 'openai';
14
- } & OpenAILegacyOptions) | ({
15
- type: 'openai-compat';
16
- } & OpenAICompatOptions) | ({
49
+ type: 'openai-completions';
50
+ } & OpenAICompletionsOptions) | ({
17
51
  type: 'google-genai';
18
52
  } & GoogleGenAIOptions) | ({
19
53
  type: 'openai_responses';
@@ -23,6 +57,14 @@ type ProviderConfig = ({
23
57
  type ProviderType = ProviderConfig['type'];
24
58
  declare function createProvider(config: ProviderConfig): ChatProvider;
25
59
  //#endregion
60
+ //#region src/providers/capability-registry.d.ts
61
+ /**
62
+ * Tries all provider-specific capability registries and returns the first
63
+ * non-UNKNOWN match. Used when the provider context is unknown (e.g., catalog
64
+ * enrichment) to fill in accurate thinking capability flags.
65
+ */
66
+ declare function resolveCapabilityFromRegistry(modelName: string): ModelCapability | undefined;
67
+ //#endregion
26
68
  //#region src/catalog.d.ts
27
69
  /**
28
70
  * models.dev-style catalog: a public map of provider/model metadata. Callers
@@ -118,6 +160,18 @@ interface GenerateResult {
118
160
  * `null` if the provider did not emit one.
119
161
  */
120
162
  readonly rawFinishReason: string | null;
163
+ /**
164
+ * Milliseconds between the `provider.generate()` call and the first
165
+ * streamed chunk. `undefined` when the stream produced no chunks
166
+ * (empty response, early abort, or error).
167
+ */
168
+ readonly llmFirstTokenLatencyMs?: number | undefined;
169
+ /**
170
+ * Milliseconds between the `provider.generate()` call and stream
171
+ * exhaustion (last chunk consumed). `undefined` when the stream
172
+ * produced no chunks (empty response, early abort, or error).
173
+ */
174
+ readonly llmStreamDurationMs?: number | undefined;
121
175
  }
122
176
  interface GenerateCallbacks {
123
177
  onMessagePart?: (part: StreamedMessagePart) => void | Promise<void>;
@@ -158,4 +212,4 @@ interface GenerateCallbacks {
158
212
  */
159
213
  declare function generate(provider: ChatProvider, systemPrompt: string, tools: Tool[], history: Message[], callbacks?: GenerateCallbacks, options?: GenerateOptions): Promise<GenerateResult>;
160
214
  //#endregion
161
- export { APIConnectionError, APIContextOverflowError, APIEmptyResponseError, APIStatusError, APITimeoutError, type AudioURLPart, type Catalog, type CatalogModel, type CatalogModelEntry, type CatalogProviderEntry, ChatProvider, ChatProviderError, type ContentPart, FinishReason, type GenerateCallbacks, GenerateOptions, type GenerateResult, type ImageURLPart, type Message, type ModelCapability, type ProviderConfig, ProviderRequestAuth, type ProviderType, type Role, StreamedMessage, type StreamedMessagePart, type TextPart, type ThinkPart, ThinkingEffort, type TokenUsage, type Tool, type ToolCall, type ToolCallPart, UNKNOWN_CAPABILITY, type VideoURLPart, VideoUploadInput, addUsage, catalogBaseUrl, catalogModelToCapability, catalogProviderModels, createAssistantMessage, createProvider, createToolMessage, createUserMessage, emptyUsage, extractText, generate, grandTotal, inferWireType, inputTotal, isContentPart, isToolCall, isToolCallPart, isUnknownCapability, mergeInPlace };
215
+ export { APIConnectionError, APIContextOverflowError, APIEmptyResponseError, APIStatusError, APITimeoutError, type AudioURLPart, type CacheHint, type CacheHitRate, type CacheScope, type CacheStrategy, type Catalog, type CatalogModel, type CatalogModelEntry, type CatalogProviderEntry, ChatProvider, ChatProviderError, type ContentPart, FinishReason, type GenerateCallbacks, GenerateOptions, type GenerateResult, type ImageURLPart, type Message, type ModelCapability, type PromptBlock, type PromptPlan, type ProviderCacheCapability, type ProviderConfig, ProviderRequestAuth, type ProviderType, type Role, StreamedMessage, type StreamedMessagePart, type TextPart, type ThinkPart, ThinkingEffort, type TokenUsage, type Tool, type ToolCall, type ToolCallPart, UNKNOWN_CAPABILITY, type VideoURLPart, VideoUploadInput, addUsage, cacheHitRate, catalogBaseUrl, catalogModelToCapability, catalogProviderModels, createAssistantMessage, createProvider, createToolMessage, createUserMessage, emptyUsage, extractText, generate, grandTotal, inferWireType, inputTotal, isContentPart, isToolCall, isToolCallPart, isUnknownCapability, mergeInPlace, resolveCapabilityFromRegistry };