@byfriends/kosong 0.2.2 → 0.2.3

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.
@@ -1,4 +1,5 @@
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";
1
+ import { P as Message, S as ModelCapability, d as StreamedMessage, f as ThinkingEffort, l as GenerateOptions, o as ChatProviderError, u as ProviderRequestAuth, x as Tool } from "./errors-wlT14tC4.mjs";
2
+ import { n as ResolvedAuth, t as BaseChatProvider } from "./base-chat-provider-B_Ow8SIj.mjs";
2
3
  import Anthropic from "@anthropic-ai/sdk";
3
4
  import { MessageCreateParams } from "@anthropic-ai/sdk/resources/messages/messages.js";
4
5
 
@@ -16,6 +17,7 @@ interface AnthropicOptions {
16
17
  clientFactory?: (auth: ProviderRequestAuth) => Anthropic;
17
18
  }
18
19
  interface AnthropicGenerationKwargs {
20
+ [key: string]: unknown;
19
21
  max_tokens?: number | undefined;
20
22
  temperature?: number | undefined;
21
23
  top_k?: number | undefined;
@@ -40,29 +42,19 @@ interface AnthropicGenerationKwargs {
40
42
  */
41
43
  declare function resolveDefaultMaxTokens(model: string, override?: number): number;
42
44
  declare function convertAnthropicError(error: unknown): ChatProviderError;
43
- declare class AnthropicChatProvider implements ChatProvider {
45
+ declare class AnthropicChatProvider extends BaseChatProvider<AnthropicGenerationKwargs> {
44
46
  readonly name: string;
45
- private _model;
46
47
  private _stream;
47
- private _client;
48
- private _generationKwargs;
49
48
  private _metadata;
50
- private _apiKey;
51
- private _baseUrl;
52
- private _defaultHeaders;
53
- private _clientFactory;
54
49
  constructor(options: AnthropicOptions);
55
50
  get modelName(): string;
56
51
  get thinkingEffort(): ThinkingEffort | null;
57
52
  get modelParameters(): Record<string, unknown>;
58
53
  getCapability(model?: string): ModelCapability;
59
54
  generate(systemPrompt: string, tools: Tool[], history: Message[], options?: GenerateOptions): Promise<StreamedMessage>;
60
- private _createClient;
61
- private _buildClient;
55
+ private static buildClient;
56
+ protected createRawClient(auth: ResolvedAuth, defaultHeaders: Record<string, string> | undefined): Anthropic;
62
57
  withThinking(effort: ThinkingEffort): AnthropicChatProvider;
63
- withGenerationKwargs(kwargs: Partial<AnthropicGenerationKwargs>): AnthropicChatProvider;
64
- private _withGenerationKwargs;
65
- private _clone;
66
58
  }
67
59
  //#endregion
68
60
  export { resolveDefaultMaxTokens as i, AnthropicOptions as n, convertAnthropicError as r, AnthropicChatProvider as t };
@@ -0,0 +1,74 @@
1
+ import { P as Message, S as ModelCapability, d as StreamedMessage, f as ThinkingEffort, l as GenerateOptions, s as ChatProvider, u as ProviderRequestAuth, x as Tool } from "./errors-wlT14tC4.mjs";
2
+
3
+ //#region src/providers/base-chat-provider.d.ts
4
+ /**
5
+ * Per-provider generation-keyword bag. Each subclass constrains this to its
6
+ * own interface (e.g. `GenerationKwargs`, `AnthropicGenerationKwargs`).
7
+ * The index signature is the common supertype all four share.
8
+ */
9
+ type BaseGenerationKwargs = Record<string, unknown>;
10
+ /**
11
+ * Resolved auth handed to {@link BaseChatProvider.createRawClient}.
12
+ */
13
+ interface ResolvedAuth {
14
+ readonly apiKey: string;
15
+ readonly headers: Record<string, string> | undefined;
16
+ }
17
+ /**
18
+ * Abstract base implementing the SDK-agnostic ChatProvider boilerplate.
19
+ *
20
+ * Subclasses must implement:
21
+ * - `generate(...)` — the streaming/dispatch loop (protocol-specific)
22
+ * - `createRawClient(auth, defaultHeaders)` — `new OpenAI(...)` / `new Anthropic(...)` / etc.
23
+ * - `thinkingEffort` getter — per-provider effort mapping
24
+ * - `getCapability(model?)` — per-provider capability registry lookup
25
+ * - `withThinking(effort)` — per-provider thinking configuration
26
+ *
27
+ * Subclasses inherit: `_clone`, `withGenerationKwargs`, `modelName`,
28
+ * `modelParameters`, and the `_createClient` shell.
29
+ */
30
+ declare abstract class BaseChatProvider<TKwargs extends BaseGenerationKwargs> implements ChatProvider {
31
+ protected readonly _model: string;
32
+ protected _generationKwargs: TKwargs;
33
+ protected readonly _apiKey: string | undefined;
34
+ protected readonly _baseUrl: string;
35
+ protected readonly _defaultHeaders: Record<string, string> | undefined;
36
+ protected _client: unknown;
37
+ protected readonly _clientFactory: ((auth: ProviderRequestAuth) => unknown) | undefined;
38
+ /** Provider name; subclasses set via constructor. */
39
+ abstract readonly name: string;
40
+ protected constructor(_model: string, _generationKwargs: TKwargs, _apiKey?: string | undefined, _baseUrl?: string, _defaultHeaders?: Record<string, string> | undefined, _client?: unknown, _clientFactory?: ((auth: ProviderRequestAuth) => unknown) | undefined);
41
+ get modelName(): string;
42
+ get modelParameters(): Record<string, unknown>;
43
+ abstract get thinkingEffort(): ThinkingEffort | null;
44
+ abstract getCapability(model?: string): ModelCapability;
45
+ abstract generate(systemPrompt: string, tools: Tool[], history: Message[], options?: GenerateOptions): Promise<StreamedMessage>;
46
+ abstract withThinking(effort: ThinkingEffort): ChatProvider;
47
+ /**
48
+ * Return a shallow copy of this provider with `kwargs` merged into the
49
+ * generation-keyword bag. The clone shares transport state (client) with
50
+ * the original; only `_generationKwargs` is deep-copied.
51
+ */
52
+ withGenerationKwargs(kwargs: TKwargs): this;
53
+ /**
54
+ * Shallow clone preserving prototype and instance state, with a fresh
55
+ * `_generationKwargs` copy. Subclasses with extra clone-time cleanup
56
+ * (e.g. resetting a lazy `_files` cache) override and call `super._clone()`
57
+ * then apply their cleanup.
58
+ */
59
+ protected _clone(): this;
60
+ /**
61
+ * Resolve the SDK client for the current request, using cached/client-factory
62
+ * auth resolution. Delegates the actual SDK construction to
63
+ * {@link createRawClient}. The provider name passed to `requireProviderApiKey`
64
+ * is the subclass's `name`.
65
+ */
66
+ protected _createClient(auth: ProviderRequestAuth | undefined): unknown;
67
+ /**
68
+ * Construct the provider-specific SDK client. Implemented by each subclass
69
+ * (e.g. `new OpenAI({...})`, `new Anthropic({...})`, `new GoogleGenAI({...})`).
70
+ */
71
+ protected abstract createRawClient(auth: ResolvedAuth, defaultHeaders: Record<string, string> | undefined): unknown;
72
+ }
73
+ //#endregion
74
+ export { ResolvedAuth as n, BaseChatProvider as t };
@@ -0,0 +1,23 @@
1
+ import { I as StreamedMessagePart, c as FinishReason, d as StreamedMessage, h as TokenUsage } from "./errors-wlT14tC4.mjs";
2
+
3
+ //#region src/providers/base-streamed-message.d.ts
4
+ declare abstract class BaseStreamedMessage implements StreamedMessage {
5
+ protected _id: string | null;
6
+ protected _usage: TokenUsage | null;
7
+ protected _finishReason: FinishReason | null;
8
+ protected _rawFinishReason: string | null;
9
+ private _iter;
10
+ get id(): string | null;
11
+ get usage(): TokenUsage | null;
12
+ get finishReason(): FinishReason | null;
13
+ get rawFinishReason(): string | null;
14
+ [Symbol.asyncIterator](): AsyncIterator<StreamedMessagePart>;
15
+ /**
16
+ * Build the protocol-specific async iterable of message parts. The subclass
17
+ * drives the provider's stream and populates `_id` / `_usage` /
18
+ * `_finishReason` / `_rawFinishReason` as it runs.
19
+ */
20
+ protected abstract _buildIter(): AsyncIterable<StreamedMessagePart>;
21
+ }
22
+ //#endregion
23
+ export { BaseStreamedMessage as t };
@@ -1,4 +1,4 @@
1
- import { o as ChatProviderError } from "./errors-WFxxzL1B.mjs";
1
+ import { l as ChatProviderError } from "./provider-common-CaxKVTTJ.mjs";
2
2
  //#region src/capability.ts
3
3
  const UNKNOWN_CAPABILITY_MARKER = Symbol.for("byf.kosong.UNKNOWN_CAPABILITY");
4
4
  /**
@@ -338,4 +338,113 @@ function resolveAuthBackedClient(state, auth, build) {
338
338
  return build(auth);
339
339
  }
340
340
  //#endregion
341
- export { getGoogleGenAIModelCapability as a, resolveCapabilityFromRegistry as c, isUnknownCapability as d, getAnthropicModelCapability as i, usesOpenAIResponsesDeveloperRole as l, requireProviderApiKey as n, getOpenAILegacyModelCapability as o, resolveAuthBackedClient as r, getOpenAIResponsesModelCapability as s, mergeRequestHeaders as t, UNKNOWN_CAPABILITY as u };
341
+ //#region src/providers/base-chat-provider.ts
342
+ /**
343
+ * Abstract base implementing the SDK-agnostic ChatProvider boilerplate.
344
+ *
345
+ * Subclasses must implement:
346
+ * - `generate(...)` — the streaming/dispatch loop (protocol-specific)
347
+ * - `createRawClient(auth, defaultHeaders)` — `new OpenAI(...)` / `new Anthropic(...)` / etc.
348
+ * - `thinkingEffort` getter — per-provider effort mapping
349
+ * - `getCapability(model?)` — per-provider capability registry lookup
350
+ * - `withThinking(effort)` — per-provider thinking configuration
351
+ *
352
+ * Subclasses inherit: `_clone`, `withGenerationKwargs`, `modelName`,
353
+ * `modelParameters`, and the `_createClient` shell.
354
+ */
355
+ var BaseChatProvider = class {
356
+ _model;
357
+ _generationKwargs;
358
+ _apiKey;
359
+ _baseUrl;
360
+ _defaultHeaders;
361
+ _client;
362
+ _clientFactory;
363
+ constructor(_model, _generationKwargs, _apiKey = void 0, _baseUrl = "", _defaultHeaders = void 0, _client = void 0, _clientFactory = void 0) {
364
+ this._model = _model;
365
+ this._generationKwargs = _generationKwargs;
366
+ this._apiKey = _apiKey;
367
+ this._baseUrl = _baseUrl;
368
+ this._defaultHeaders = _defaultHeaders;
369
+ this._client = _client;
370
+ this._clientFactory = _clientFactory;
371
+ }
372
+ get modelName() {
373
+ return this._model;
374
+ }
375
+ get modelParameters() {
376
+ return {
377
+ model: this._model,
378
+ ...this._generationKwargs
379
+ };
380
+ }
381
+ /**
382
+ * Return a shallow copy of this provider with `kwargs` merged into the
383
+ * generation-keyword bag. The clone shares transport state (client) with
384
+ * the original; only `_generationKwargs` is deep-copied.
385
+ */
386
+ withGenerationKwargs(kwargs) {
387
+ const clone = this._clone();
388
+ clone._generationKwargs = {
389
+ ...clone._generationKwargs,
390
+ ...kwargs
391
+ };
392
+ return clone;
393
+ }
394
+ /**
395
+ * Shallow clone preserving prototype and instance state, with a fresh
396
+ * `_generationKwargs` copy. Subclasses with extra clone-time cleanup
397
+ * (e.g. resetting a lazy `_files` cache) override and call `super._clone()`
398
+ * then apply their cleanup.
399
+ */
400
+ _clone() {
401
+ const clone = Object.assign(Object.create(Object.getPrototypeOf(this)), this);
402
+ clone._generationKwargs = { ...this._generationKwargs };
403
+ return clone;
404
+ }
405
+ /**
406
+ * Resolve the SDK client for the current request, using cached/client-factory
407
+ * auth resolution. Delegates the actual SDK construction to
408
+ * {@link createRawClient}. The provider name passed to `requireProviderApiKey`
409
+ * is the subclass's `name`.
410
+ */
411
+ _createClient(auth) {
412
+ return resolveAuthBackedClient({
413
+ cachedClient: this._client,
414
+ clientFactory: this._clientFactory
415
+ }, auth, (a) => {
416
+ const defaultHeaders = mergeRequestHeaders(this._defaultHeaders, a?.headers);
417
+ return this.createRawClient({
418
+ apiKey: requireProviderApiKey(this.name, a, this._apiKey),
419
+ headers: defaultHeaders
420
+ }, defaultHeaders);
421
+ });
422
+ }
423
+ };
424
+ //#endregion
425
+ //#region src/providers/base-streamed-message.ts
426
+ var BaseStreamedMessage = class {
427
+ _id = null;
428
+ _usage = null;
429
+ _finishReason = null;
430
+ _rawFinishReason = null;
431
+ _iter;
432
+ get id() {
433
+ return this._id;
434
+ }
435
+ get usage() {
436
+ return this._usage;
437
+ }
438
+ get finishReason() {
439
+ return this._finishReason;
440
+ }
441
+ get rawFinishReason() {
442
+ return this._rawFinishReason;
443
+ }
444
+ async *[Symbol.asyncIterator]() {
445
+ this._iter ??= this._buildIter();
446
+ yield* this._iter;
447
+ }
448
+ };
449
+ //#endregion
450
+ export { resolveAuthBackedClient as a, getOpenAILegacyModelCapability as c, usesOpenAIResponsesDeveloperRole as d, UNKNOWN_CAPABILITY as f, requireProviderApiKey as i, getOpenAIResponsesModelCapability as l, BaseChatProvider as n, getAnthropicModelCapability as o, isUnknownCapability as p, mergeRequestHeaders as r, getGoogleGenAIModelCapability as s, BaseStreamedMessage as t, resolveCapabilityFromRegistry as u };
@@ -1,4 +1,6 @@
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";
1
+ import { I as StreamedMessagePart, P as Message, S as ModelCapability, d as StreamedMessage, f as ThinkingEffort, l as GenerateOptions, o as ChatProviderError, u as ProviderRequestAuth, x as Tool } from "./errors-wlT14tC4.mjs";
2
+ import { n as ResolvedAuth, t as BaseChatProvider } from "./base-chat-provider-B_Ow8SIj.mjs";
3
+ import { t as BaseStreamedMessage } from "./base-streamed-message-D738gMHT.mjs";
2
4
  import { GoogleGenAI } from "@google/genai";
3
5
 
4
6
  //#region src/providers/google-genai.d.ts
@@ -43,18 +45,12 @@ interface GooglePart {
43
45
  [key: string]: unknown;
44
46
  }
45
47
  declare function messagesToGoogleGenAIContents(messages: Message[]): GoogleContent[];
46
- declare class GoogleGenAIStreamedMessage implements StreamedMessage {
47
- private _id;
48
- private _usage;
49
- private _finishReason;
50
- private _rawFinishReason;
51
- private readonly _iter;
48
+ declare class GoogleGenAIStreamedMessage extends BaseStreamedMessage {
49
+ private readonly _response;
50
+ private readonly _isStream;
51
+ private readonly _signal;
52
52
  constructor(response: AsyncIterable<Record<string, unknown>> | Record<string, unknown>, isStream: boolean, signal?: AbortSignal);
53
- get id(): string | null;
54
- get usage(): TokenUsage | null;
55
- get finishReason(): FinishReason | null;
56
- get rawFinishReason(): string | null;
57
- [Symbol.asyncIterator](): AsyncIterator<StreamedMessagePart>;
53
+ protected _buildIter(): AsyncGenerator<StreamedMessagePart>;
58
54
  private _captureFinishReason;
59
55
  /** Yield parts from a single (non-streamed) GenerateContentResponse. */
60
56
  private _extractChunkParts;
@@ -70,28 +66,26 @@ declare class GoogleGenAIStreamedMessage implements StreamedMessage {
70
66
  * Convert a Google GenAI SDK error (or raw Error) to a kosong `ChatProviderError`.
71
67
  */
72
68
  declare function convertGoogleGenAIError(error: unknown): ChatProviderError;
73
- declare class GoogleGenAIChatProvider implements ChatProvider {
69
+ declare class GoogleGenAIChatProvider extends BaseChatProvider<GoogleGenAIGenerationKwargs> {
74
70
  readonly name: string;
75
- private _model;
76
- private _client;
77
- private _generationKwargs;
78
- private _vertexai;
79
71
  private _stream;
80
- private _apiKey;
72
+ private _vertexai;
81
73
  private _project;
82
74
  private _location;
83
- private _clientFactory;
84
75
  constructor(options: GoogleGenAIOptions);
85
- private _buildClient;
86
- get modelName(): string;
76
+ private static buildClient;
87
77
  get thinkingEffort(): ThinkingEffort | null;
88
78
  get modelParameters(): Record<string, unknown>;
89
79
  getCapability(model?: string): ModelCapability;
90
80
  generate(systemPrompt: string, tools: Tool[], history: Message[], options?: GenerateOptions): Promise<StreamedMessage>;
91
- private _createClient;
81
+ /**
82
+ * Override the base auth-resolution path to preserve the Vertex AI
83
+ * short-circuit: Vertex uses service credentials, not request-scoped keys
84
+ * or headers, so `requireProviderApiKey` must not be enforced there.
85
+ */
86
+ protected _createClient(auth: ProviderRequestAuth | undefined): GoogleGenAI;
87
+ protected createRawClient(auth: ResolvedAuth, _defaultHeaders: Record<string, string> | undefined): GoogleGenAI;
92
88
  withThinking(effort: ThinkingEffort): GoogleGenAIChatProvider;
93
- withGenerationKwargs(kwargs: GoogleGenAIGenerationKwargs): GoogleGenAIChatProvider;
94
- private _clone;
95
89
  }
96
90
  //#endregion
97
91
  export { convertGoogleGenAIError as a, GoogleGenAIStreamedMessage as i, GoogleGenAIGenerationKwargs as n, messagesToGoogleGenAIContents as o, GoogleGenAIOptions as r, GoogleGenAIChatProvider as t };
package/dist/index.d.mts CHANGED
@@ -1,8 +1,8 @@
1
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";
2
+ import { n as AnthropicOptions } from "./anthropic-BYlmhwZs.mjs";
3
+ import { r as GoogleGenAIOptions } from "./google-genai-CSE4ZD3A.mjs";
4
+ import { i as ToolMessageConversion } from "./openai-common-7D2LXUK2.mjs";
5
+ import { r as OpenAIResponsesOptions } from "./openai-responses-Bj6eg-S0.mjs";
6
6
  import OpenAI from "openai";
7
7
 
8
8
  //#region src/providers/openai-completions.d.ts
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { _ as mergeInPlace, a as isFunctionToolCall, d as createToolMessage, f as createUserMessage, g as isToolCallPart, h as isToolCall, i as extractUsage, l as toolToOpenAI, m as isContentPart, n as convertOpenAIError, o as normalizeOpenAIFinishReason, p as extractText, r as convertToolMessageContent, s as reasoningEffortToThinkingEffort, t as convertContentPart, u as createAssistantMessage } from "./openai-common-Dl42y_vn.mjs";
2
- import { a as APITimeoutError, i as APIStatusError, n as APIContextOverflowError, o as ChatProviderError, r as APIEmptyResponseError, t as APIConnectionError } from "./errors-WFxxzL1B.mjs";
3
- import { c as resolveCapabilityFromRegistry, d as isUnknownCapability, n as requireProviderApiKey, o as getOpenAILegacyModelCapability, r as resolveAuthBackedClient, t as mergeRequestHeaders, u as UNKNOWN_CAPABILITY } from "./request-auth-BMXt8jRu.mjs";
1
+ import { _ as mergeInPlace, a as isFunctionToolCall, d as createToolMessage, f as createUserMessage, g as isToolCallPart, h as isToolCall, i as extractUsage, l as toolToOpenAI, m as isContentPart, n as convertOpenAIError, o as normalizeOpenAIFinishReason, p as extractText, r as convertToolMessageContent, s as reasoningEffortToThinkingEffort, t as convertContentPart, u as createAssistantMessage } from "./openai-common-B7Ex3mNh.mjs";
2
+ import { a as APIContextOverflowError, c as APITimeoutError, i as APIConnectionError, l as ChatProviderError, o as APIEmptyResponseError, s as APIStatusError } from "./provider-common-CaxKVTTJ.mjs";
3
+ import { a as resolveAuthBackedClient, c as getOpenAILegacyModelCapability, f as UNKNOWN_CAPABILITY, i as requireProviderApiKey, n as BaseChatProvider, p as isUnknownCapability, r as mergeRequestHeaders, t as BaseStreamedMessage, u as resolveCapabilityFromRegistry } from "./base-streamed-message-Kok6Drxr.mjs";
4
4
  import { AnthropicChatProvider } from "./providers/anthropic.mjs";
5
5
  import { GoogleGenAIChatProvider } from "./providers/google-genai.mjs";
6
6
  import { OpenAIResponsesChatProvider } from "./providers/openai-responses.mjs";
@@ -650,30 +650,19 @@ function extractUsageFromChunk(chunk) {
650
650
  if (choiceUsage !== null && choiceUsage !== void 0 && typeof choiceUsage === "object") return choiceUsage;
651
651
  return null;
652
652
  }
653
- var OpenAICompletionsStreamedMessage = class {
654
- _id = null;
655
- _usage = null;
656
- _finishReason = null;
657
- _rawFinishReason = null;
658
- _iter;
653
+ var OpenAICompletionsStreamedMessage = class extends BaseStreamedMessage {
654
+ _response;
655
+ _isStream;
656
+ _reasoningKey;
659
657
  constructor(response, isStream, reasoningKey) {
660
- if (isStream) this._iter = this._convertStreamResponse(response, reasoningKey);
661
- else this._iter = this._convertNonStreamResponse(response, reasoningKey);
662
- }
663
- get id() {
664
- return this._id;
665
- }
666
- get usage() {
667
- return this._usage;
668
- }
669
- get finishReason() {
670
- return this._finishReason;
671
- }
672
- get rawFinishReason() {
673
- return this._rawFinishReason;
658
+ super();
659
+ this._response = response;
660
+ this._isStream = isStream;
661
+ this._reasoningKey = reasoningKey;
674
662
  }
675
- async *[Symbol.asyncIterator]() {
676
- yield* this._iter;
663
+ _buildIter() {
664
+ if (this._isStream) return this._convertStreamResponse(this._response, this._reasoningKey);
665
+ return this._convertNonStreamResponse(this._response, this._reasoningKey);
677
666
  }
678
667
  _captureFinishReason(raw) {
679
668
  const normalized = normalizeOpenAIFinishReason(raw);
@@ -733,42 +722,29 @@ var OpenAICompletionsStreamedMessage = class {
733
722
  }
734
723
  }
735
724
  };
736
- var OpenAICompletionsChatProvider = class {
725
+ var OpenAICompletionsChatProvider = class extends BaseChatProvider {
737
726
  name = "openai-completions";
738
- _model;
739
727
  _stream;
740
- _apiKey;
741
- _baseUrl;
742
- _defaultHeaders;
743
- _generationKwargs;
744
728
  _thinkingEffortKey;
745
729
  _reasoningKey;
746
730
  _toolMessageConversion;
747
- _client;
748
- _clientFactory;
749
731
  _files;
750
732
  constructor(options) {
751
- const apiKey = options.apiKey;
752
- this._apiKey = apiKey === void 0 || apiKey.length === 0 ? void 0 : apiKey;
753
- this._baseUrl = options.baseUrl ?? "";
754
- this._defaultHeaders = options.defaultHeaders;
755
- this._clientFactory = options.clientFactory;
756
- this._model = options.model;
733
+ const apiKey = options.apiKey === void 0 || options.apiKey.length === 0 ? void 0 : options.apiKey;
734
+ const baseUrl = options.baseUrl ?? "";
735
+ const generationKwargs = { ...options.generationKwargs };
736
+ const client = apiKey === void 0 ? void 0 : new OpenAI({
737
+ apiKey,
738
+ baseURL: baseUrl,
739
+ defaultHeaders: options.defaultHeaders
740
+ });
741
+ super(options.model, generationKwargs, apiKey, baseUrl, options.defaultHeaders, client, options.clientFactory);
757
742
  this._stream = options.stream ?? true;
758
743
  const normalizedThinkingEffortKey = options.thinkingEffortKey?.trim();
759
744
  this._thinkingEffortKey = normalizedThinkingEffortKey !== void 0 && normalizedThinkingEffortKey.length > 0 ? normalizedThinkingEffortKey : "reasoning_effort";
760
745
  const normalizedReasoningKey = options.reasoningKey?.trim();
761
746
  this._reasoningKey = normalizedReasoningKey !== void 0 && normalizedReasoningKey.length > 0 ? normalizedReasoningKey : void 0;
762
- this._generationKwargs = { ...options.generationKwargs };
763
747
  this._toolMessageConversion = options.toolMessageConversion ?? null;
764
- this._client = this._apiKey === void 0 ? void 0 : new OpenAI({
765
- apiKey: this._apiKey,
766
- baseURL: this._baseUrl,
767
- defaultHeaders: this._defaultHeaders
768
- });
769
- }
770
- get modelName() {
771
- return this._model;
772
748
  }
773
749
  get thinkingEffort() {
774
750
  const customValue = this._generationKwargs[this._thinkingEffortKey];
@@ -854,9 +830,6 @@ var OpenAICompletionsChatProvider = class {
854
830
  const nextEffort = { [this._thinkingEffortKey]: reasoningEffort };
855
831
  return this._withGenerationKwargs(nextEffort).withExtraBody({ thinking });
856
832
  }
857
- withGenerationKwargs(kwargs) {
858
- return this._withGenerationKwargs(kwargs);
859
- }
860
833
  withMaxCompletionTokens(maxCompletionTokens) {
861
834
  return this._withGenerationKwargs({ max_completion_tokens: maxCompletionTokens });
862
835
  }
@@ -874,33 +847,21 @@ var OpenAICompletionsChatProvider = class {
874
847
  };
875
848
  return this._withGenerationKwargs({ extra_body: merged });
876
849
  }
877
- _createClient(auth) {
878
- return resolveAuthBackedClient({
879
- cachedClient: this._client,
880
- clientFactory: this._clientFactory
881
- }, auth, (a) => {
882
- const defaultHeaders = mergeRequestHeaders(this._defaultHeaders, a?.headers);
883
- return new OpenAI({
884
- apiKey: requireProviderApiKey("OpenAICompletionsChatProvider", a, this._apiKey),
885
- baseURL: this._baseUrl,
886
- defaultHeaders
887
- });
888
- });
889
- }
890
850
  _withGenerationKwargs(kwargs) {
891
- const clone = this._clone();
892
- clone._generationKwargs = {
893
- ...clone._generationKwargs,
894
- ...kwargs
895
- };
896
- return clone;
851
+ return this.withGenerationKwargs(kwargs);
897
852
  }
898
853
  _clone() {
899
- const clone = Object.assign(Object.create(Object.getPrototypeOf(this)), this);
900
- clone._generationKwargs = { ...this._generationKwargs };
854
+ const clone = super._clone();
901
855
  clone._files = void 0;
902
856
  return clone;
903
857
  }
858
+ createRawClient(auth, defaultHeaders) {
859
+ return new OpenAI({
860
+ apiKey: auth.apiKey,
861
+ baseURL: this._baseUrl,
862
+ defaultHeaders
863
+ });
864
+ }
904
865
  };
905
866
  //#endregion
906
867
  //#region src/providers/index.ts
@@ -89,7 +89,7 @@ declare function extractUsage(usage: unknown): TokenUsage | null;
89
89
  * - `'content_filter'` → `'filtered'`
90
90
  * - any other non-null string → `'other'`
91
91
  */
92
- declare function normalizeOpenAIFinishReason(raw: string | null | undefined): {
92
+ declare const normalizeOpenAIFinishReason: (raw: string | null | undefined) => {
93
93
  finishReason: FinishReason | null;
94
94
  rawFinishReason: string | null;
95
95
  };
@@ -1,4 +1,4 @@
1
- import { a as APITimeoutError, o as ChatProviderError, s as normalizeAPIStatusError, t as APIConnectionError$1 } from "./errors-WFxxzL1B.mjs";
1
+ import { c as APITimeoutError, i as APIConnectionError$1, l as ChatProviderError, r as makeFinishReasonNormalizer, u as normalizeAPIStatusError } from "./provider-common-CaxKVTTJ.mjs";
2
2
  import { APIConnectionError, APIConnectionTimeoutError, APIError, OpenAIError } from "openai";
3
3
  //#region src/message.ts
4
4
  /** Check if a streamed part is a ContentPart (text, think, image_url, audio_url, video_url). */
@@ -263,35 +263,13 @@ function extractUsage(usage) {
263
263
  * - `'content_filter'` → `'filtered'`
264
264
  * - any other non-null string → `'other'`
265
265
  */
266
- function normalizeOpenAIFinishReason(raw) {
267
- if (raw === null || raw === void 0) return {
268
- finishReason: null,
269
- rawFinishReason: null
270
- };
271
- switch (raw) {
272
- case "stop": return {
273
- finishReason: "completed",
274
- rawFinishReason: raw
275
- };
276
- case "tool_calls":
277
- case "function_call": return {
278
- finishReason: "tool_calls",
279
- rawFinishReason: raw
280
- };
281
- case "length": return {
282
- finishReason: "truncated",
283
- rawFinishReason: raw
284
- };
285
- case "content_filter": return {
286
- finishReason: "filtered",
287
- rawFinishReason: raw
288
- };
289
- default: return {
290
- finishReason: "other",
291
- rawFinishReason: raw
292
- };
293
- }
294
- }
266
+ const normalizeOpenAIFinishReason = makeFinishReasonNormalizer({
267
+ stop: "completed",
268
+ tool_calls: "tool_calls",
269
+ function_call: "tool_calls",
270
+ length: "truncated",
271
+ content_filter: "filtered"
272
+ });
295
273
  /**
296
274
  * Convert tool-role message content according to the chosen strategy.
297
275
  */
@@ -1,5 +1,7 @@
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, s as ChatProvider, u as ProviderRequestAuth, x as Tool } from "./errors-wlT14tC4.mjs";
2
- import { i as ToolMessageConversion } from "./openai-common-DwkxUSyI.mjs";
1
+ import { I as StreamedMessagePart, P as Message, S as ModelCapability, d as StreamedMessage, f as ThinkingEffort, l as GenerateOptions, u as ProviderRequestAuth, x as Tool } from "./errors-wlT14tC4.mjs";
2
+ import { n as ResolvedAuth, t as BaseChatProvider } from "./base-chat-provider-B_Ow8SIj.mjs";
3
+ import { t as BaseStreamedMessage } from "./base-streamed-message-D738gMHT.mjs";
4
+ import { i as ToolMessageConversion } from "./openai-common-7D2LXUK2.mjs";
3
5
  import OpenAI from "openai";
4
6
 
5
7
  //#region src/providers/openai-responses.d.ts
@@ -20,46 +22,29 @@ interface OpenAIResponsesGenerationKwargs {
20
22
  reasoning_effort?: string | undefined;
21
23
  [key: string]: unknown;
22
24
  }
23
- declare class OpenAIResponsesStreamedMessage implements StreamedMessage {
24
- private _id;
25
- private _usage;
26
- private _finishReason;
27
- private _rawFinishReason;
28
- private readonly _iter;
25
+ declare class OpenAIResponsesStreamedMessage extends BaseStreamedMessage {
26
+ private readonly _response;
27
+ private readonly _isStream;
29
28
  constructor(response: unknown, isStream: boolean);
30
- get id(): string | null;
31
- get usage(): TokenUsage | null;
32
- get finishReason(): FinishReason | null;
33
- get rawFinishReason(): string | null;
34
- [Symbol.asyncIterator](): AsyncIterator<StreamedMessagePart>;
29
+ protected _buildIter(): AsyncGenerator<StreamedMessagePart>;
35
30
  private _captureFinishReasonFromResponse;
36
31
  private _extractUsage;
37
32
  private _convertNonStreamResponse;
38
33
  private _convertStreamResponse;
39
34
  }
40
- declare class OpenAIResponsesChatProvider implements ChatProvider {
35
+ declare class OpenAIResponsesChatProvider extends BaseChatProvider<OpenAIResponsesGenerationKwargs> {
41
36
  readonly name: string;
42
- private _model;
43
37
  private _stream;
44
- private _apiKey;
45
- private _baseUrl;
46
- private _defaultHeaders;
47
- private _generationKwargs;
48
38
  private _toolMessageConversion;
49
- private _client;
50
39
  private _httpClient;
51
- private _clientFactory;
52
40
  constructor(options: OpenAIResponsesOptions);
53
- get modelName(): string;
54
41
  get thinkingEffort(): ThinkingEffort | null;
55
42
  get modelParameters(): Record<string, unknown>;
56
43
  getCapability(model?: string): ModelCapability;
57
44
  generate(systemPrompt: string, tools: Tool[], history: Message[], options?: GenerateOptions): Promise<StreamedMessage>;
58
45
  withThinking(effort: ThinkingEffort): OpenAIResponsesChatProvider;
59
- withGenerationKwargs(kwargs: OpenAIResponsesGenerationKwargs): OpenAIResponsesChatProvider;
60
- private _clone;
61
- private _createClient;
62
- private _buildClient;
46
+ protected createRawClient(auth: ResolvedAuth, defaultHeaders: Record<string, string> | undefined): OpenAI;
47
+ private static buildClient;
63
48
  }
64
49
  //#endregion
65
50
  export { OpenAIResponsesStreamedMessage as i, OpenAIResponsesGenerationKwargs as n, OpenAIResponsesOptions as r, OpenAIResponsesChatProvider as t };