@byfriends/kosong 0.1.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/LICENSE +28 -0
- package/README.md +11 -0
- package/dist/anthropic-Dm_GqFgS.d.mts +69 -0
- package/dist/capability-registry-CMBuEYcf.mjs +161 -0
- package/dist/chat-completions-stream-BuMu_xr9.mjs +62 -0
- package/dist/errors-DweKbIOf.d.mts +42 -0
- package/dist/errors-WFxxzL1B.mjs +80 -0
- package/dist/google-genai-hX0X6CF3.d.mts +98 -0
- package/dist/index.d.mts +161 -0
- package/dist/index.mjs +287 -0
- package/dist/openai-common-08qin3UI.mjs +278 -0
- package/dist/openai-common-B6cK2ig3.d.mts +105 -0
- package/dist/openai-compat-CMrIk-ib.d.mts +132 -0
- package/dist/openai-compat-CWbwO4b7.mjs +801 -0
- package/dist/openai-legacy-B6CVfLlr.d.mts +71 -0
- package/dist/openai-responses-BxOwxtd3.d.mts +65 -0
- package/dist/provider-DiJKWMsQ.d.mts +371 -0
- package/dist/providers/anthropic.d.mts +2 -0
- package/dist/providers/anthropic.mjs +720 -0
- package/dist/providers/google-genai.d.mts +2 -0
- package/dist/providers/google-genai.mjs +562 -0
- package/dist/providers/openai-common.d.mts +2 -0
- package/dist/providers/openai-common.mjs +2 -0
- package/dist/providers/openai-compat.d.mts +2 -0
- package/dist/providers/openai-compat.mjs +2 -0
- package/dist/providers/openai-legacy.d.mts +2 -0
- package/dist/providers/openai-legacy.mjs +248 -0
- package/dist/providers/openai-responses.d.mts +2 -0
- package/dist/providers/openai-responses.mjs +623 -0
- package/dist/request-auth-DCWSyCKI.mjs +63 -0
- package/package.json +89 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { a as APITimeoutError, o as ChatProviderError, s as normalizeAPIStatusError, t as APIConnectionError$1 } from "./errors-WFxxzL1B.mjs";
|
|
2
|
+
import { APIConnectionError, APIConnectionTimeoutError, APIError, OpenAIError } from "openai";
|
|
3
|
+
//#region src/message.ts
|
|
4
|
+
/** Check if a streamed part is a ContentPart (text, think, image_url, audio_url, video_url). */
|
|
5
|
+
function isContentPart(part) {
|
|
6
|
+
const t = part.type;
|
|
7
|
+
return t === "text" || t === "think" || t === "image_url" || t === "audio_url" || t === "video_url";
|
|
8
|
+
}
|
|
9
|
+
/** Check if a streamed part is a ToolCall. */
|
|
10
|
+
function isToolCall(part) {
|
|
11
|
+
return part.type === "function";
|
|
12
|
+
}
|
|
13
|
+
/** Check if a streamed part is a ToolCallPart (streaming argument delta). */
|
|
14
|
+
function isToolCallPart(part) {
|
|
15
|
+
return part.type === "tool_call_part";
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Merge `source` into `target` in-place for streaming accumulation.
|
|
19
|
+
*
|
|
20
|
+
* Supported combinations:
|
|
21
|
+
* - TextPart + TextPart -> concatenate text
|
|
22
|
+
* - ThinkPart + ThinkPart -> concatenate think (refuse if target.encrypted already set)
|
|
23
|
+
* - ToolCall + ToolCallPart -> append arguments
|
|
24
|
+
*
|
|
25
|
+
* **Routing for parallel tool calls**: When OpenAI (or compatible) APIs stream
|
|
26
|
+
* multiple tool calls in parallel, argument deltas may interleave across calls.
|
|
27
|
+
* To handle this, {@link generate} routes ToolCallParts by their optional
|
|
28
|
+
* {@link ToolCallPart.index} field (mirroring the provider's streaming index)
|
|
29
|
+
* to the correct pending ToolCall, rather than relying on sequential ordering.
|
|
30
|
+
* This function still performs sequential merging as a fallback when the
|
|
31
|
+
* pending part matches the incoming one.
|
|
32
|
+
*
|
|
33
|
+
* Returns `true` if the merge was performed, `false` otherwise.
|
|
34
|
+
*/
|
|
35
|
+
function mergeInPlace(target, source) {
|
|
36
|
+
if (target.type === "text" && source.type === "text") {
|
|
37
|
+
target.text += source.text;
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
if (target.type === "think" && source.type === "think") {
|
|
41
|
+
if (target.encrypted !== void 0) return false;
|
|
42
|
+
target.think += source.think;
|
|
43
|
+
if (source.encrypted !== void 0) target.encrypted = source.encrypted;
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
if (target.type === "function" && source.type === "tool_call_part") {
|
|
47
|
+
if (source.argumentsPart !== null) target.arguments = target.arguments === null ? source.argumentsPart : target.arguments + source.argumentsPart;
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Extract the concatenated text from a message's content parts.
|
|
54
|
+
*
|
|
55
|
+
* @param message The message to extract text from.
|
|
56
|
+
* @param sep Separator between text parts. Defaults to empty string.
|
|
57
|
+
*/
|
|
58
|
+
function extractText(message, sep = "") {
|
|
59
|
+
return message.content.filter((part) => part.type === "text").map((part) => part.text).join(sep);
|
|
60
|
+
}
|
|
61
|
+
/** Create a simple user message with a single text part. */
|
|
62
|
+
function createUserMessage(content) {
|
|
63
|
+
return {
|
|
64
|
+
role: "user",
|
|
65
|
+
content: [{
|
|
66
|
+
type: "text",
|
|
67
|
+
text: content
|
|
68
|
+
}],
|
|
69
|
+
toolCalls: []
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/** Create an assistant message from content parts and optional tool calls. */
|
|
73
|
+
function createAssistantMessage(content, toolCalls) {
|
|
74
|
+
return {
|
|
75
|
+
role: "assistant",
|
|
76
|
+
content,
|
|
77
|
+
toolCalls: toolCalls ?? []
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/** Create a tool result message. */
|
|
81
|
+
function createToolMessage(toolCallId, output) {
|
|
82
|
+
return {
|
|
83
|
+
role: "tool",
|
|
84
|
+
content: typeof output === "string" ? [{
|
|
85
|
+
type: "text",
|
|
86
|
+
text: output
|
|
87
|
+
}] : output,
|
|
88
|
+
toolCalls: [],
|
|
89
|
+
toolCallId
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
//#region src/providers/openai-common.ts
|
|
94
|
+
/**
|
|
95
|
+
* Convert a kosong `ContentPart` to OpenAI-compatible content part.
|
|
96
|
+
* Returns `null` for think parts (handled separately as reasoning_content).
|
|
97
|
+
*/
|
|
98
|
+
function convertContentPart(part) {
|
|
99
|
+
switch (part.type) {
|
|
100
|
+
case "text": return {
|
|
101
|
+
type: "text",
|
|
102
|
+
text: part.text
|
|
103
|
+
};
|
|
104
|
+
case "think": return null;
|
|
105
|
+
case "image_url": return {
|
|
106
|
+
type: "image_url",
|
|
107
|
+
image_url: part.imageUrl.id === void 0 ? { url: part.imageUrl.url } : {
|
|
108
|
+
url: part.imageUrl.url,
|
|
109
|
+
id: part.imageUrl.id
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
case "audio_url": return {
|
|
113
|
+
type: "audio_url",
|
|
114
|
+
audio_url: part.audioUrl.id === void 0 ? { url: part.audioUrl.url } : {
|
|
115
|
+
url: part.audioUrl.url,
|
|
116
|
+
id: part.audioUrl.id
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
case "video_url": return {
|
|
120
|
+
type: "video_url",
|
|
121
|
+
video_url: part.videoUrl.id === void 0 ? { url: part.videoUrl.url } : {
|
|
122
|
+
url: part.videoUrl.url,
|
|
123
|
+
id: part.videoUrl.id
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
default: throw new Error(`Unknown content part type: ${part.type}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Convert a kosong `Tool` to OpenAI tool format.
|
|
131
|
+
*/
|
|
132
|
+
function toolToOpenAI(tool) {
|
|
133
|
+
return {
|
|
134
|
+
type: "function",
|
|
135
|
+
function: {
|
|
136
|
+
name: tool.name,
|
|
137
|
+
description: tool.description,
|
|
138
|
+
parameters: tool.parameters
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
const NETWORK_RE = /network|connection|connect|disconnect/i;
|
|
143
|
+
const TIMEOUT_RE = /timed?\s*out|timeout|deadline/i;
|
|
144
|
+
function classifyBaseApiError(message) {
|
|
145
|
+
if (TIMEOUT_RE.test(message)) return new APITimeoutError(message);
|
|
146
|
+
if (NETWORK_RE.test(message)) return new APIConnectionError$1(message);
|
|
147
|
+
return new ChatProviderError(`Error: ${message}`);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Convert an OpenAI SDK error (or raw Error) to a kosong `ChatProviderError`.
|
|
151
|
+
*/
|
|
152
|
+
function convertOpenAIError(error) {
|
|
153
|
+
if (error instanceof ChatProviderError) return error;
|
|
154
|
+
if (error instanceof APIConnectionTimeoutError) return new APITimeoutError(error.message);
|
|
155
|
+
if (error instanceof APIConnectionError) return new APIConnectionError$1(error.message);
|
|
156
|
+
if (error instanceof APIError && typeof error.status === "number") {
|
|
157
|
+
const reqId = error.requestID ?? null;
|
|
158
|
+
return normalizeAPIStatusError(error.status, error.message, reqId);
|
|
159
|
+
}
|
|
160
|
+
if (error instanceof APIError && error.constructor === APIError && error.error === void 0) return classifyBaseApiError(error.message);
|
|
161
|
+
if (error instanceof OpenAIError) return new ChatProviderError(`Error: ${error.message}`);
|
|
162
|
+
if (error instanceof Error) return new ChatProviderError(`Error: ${error.message}`);
|
|
163
|
+
return new ChatProviderError(`Error: ${String(error)}`);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Type guard: narrow a tool call union to the function-type variant.
|
|
167
|
+
* Works with OpenAI SDK's `ChatCompletionMessageToolCall` as well as
|
|
168
|
+
* any object carrying `{ type: string }`.
|
|
169
|
+
*/
|
|
170
|
+
function isFunctionToolCall(tc) {
|
|
171
|
+
return tc.type === "function";
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Map kosong `ThinkingEffort` to OpenAI `reasoning_effort` string.
|
|
175
|
+
*/
|
|
176
|
+
function thinkingEffortToReasoningEffort(effort) {
|
|
177
|
+
switch (effort) {
|
|
178
|
+
case "off": return;
|
|
179
|
+
case "low": return "low";
|
|
180
|
+
case "medium": return "medium";
|
|
181
|
+
case "high": return "high";
|
|
182
|
+
case "xhigh":
|
|
183
|
+
case "max": return "xhigh";
|
|
184
|
+
default: throw new Error(`Unknown thinking effort: ${String(effort)}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Map OpenAI `reasoning_effort` string back to kosong `ThinkingEffort`.
|
|
189
|
+
*/
|
|
190
|
+
function reasoningEffortToThinkingEffort(reasoning) {
|
|
191
|
+
if (reasoning === void 0 || reasoning === null) return null;
|
|
192
|
+
switch (reasoning) {
|
|
193
|
+
case "low":
|
|
194
|
+
case "minimal": return "low";
|
|
195
|
+
case "medium": return "medium";
|
|
196
|
+
case "high": return "high";
|
|
197
|
+
case "xhigh":
|
|
198
|
+
case "max": return "xhigh";
|
|
199
|
+
case "none": return "off";
|
|
200
|
+
default: return "off";
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Extract `TokenUsage` from an OpenAI-compatible usage object.
|
|
205
|
+
*/
|
|
206
|
+
function extractUsage(usage) {
|
|
207
|
+
if (usage === null || usage === void 0 || typeof usage !== "object") return null;
|
|
208
|
+
const u = usage;
|
|
209
|
+
const promptTokens = typeof u["prompt_tokens"] === "number" ? u["prompt_tokens"] : 0;
|
|
210
|
+
const completionTokens = typeof u["completion_tokens"] === "number" ? u["completion_tokens"] : 0;
|
|
211
|
+
let cached = 0;
|
|
212
|
+
if (typeof u["cached_tokens"] === "number") cached = u["cached_tokens"];
|
|
213
|
+
else if (typeof u["prompt_tokens_details"] === "object" && u["prompt_tokens_details"] !== null) {
|
|
214
|
+
const details = u["prompt_tokens_details"];
|
|
215
|
+
if (typeof details["cached_tokens"] === "number") cached = details["cached_tokens"];
|
|
216
|
+
}
|
|
217
|
+
return {
|
|
218
|
+
inputOther: promptTokens - cached,
|
|
219
|
+
output: completionTokens,
|
|
220
|
+
inputCacheRead: cached,
|
|
221
|
+
inputCacheCreation: 0
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Normalize an OpenAI Chat Completions–style `finish_reason` string to the
|
|
226
|
+
* unified {@link FinishReason} enum.
|
|
227
|
+
*
|
|
228
|
+
* Used by both the Byf and OpenAI Legacy adapters because they share the
|
|
229
|
+
* Chat Completions wire format. Returns `{ finishReason: null,
|
|
230
|
+
* rawFinishReason: null }` when the upstream value is missing or `null` so
|
|
231
|
+
* callers can treat "no signal" uniformly.
|
|
232
|
+
*
|
|
233
|
+
* Mapping:
|
|
234
|
+
* - `'stop'` → `'completed'`
|
|
235
|
+
* - `'tool_calls'` → `'tool_calls'`
|
|
236
|
+
* - `'function_call'` → `'tool_calls'` (legacy alias)
|
|
237
|
+
* - `'length'` → `'truncated'`
|
|
238
|
+
* - `'content_filter'` → `'filtered'`
|
|
239
|
+
* - any other non-null string → `'other'`
|
|
240
|
+
*/
|
|
241
|
+
function normalizeOpenAIFinishReason(raw) {
|
|
242
|
+
if (raw === null || raw === void 0) return {
|
|
243
|
+
finishReason: null,
|
|
244
|
+
rawFinishReason: null
|
|
245
|
+
};
|
|
246
|
+
switch (raw) {
|
|
247
|
+
case "stop": return {
|
|
248
|
+
finishReason: "completed",
|
|
249
|
+
rawFinishReason: raw
|
|
250
|
+
};
|
|
251
|
+
case "tool_calls":
|
|
252
|
+
case "function_call": return {
|
|
253
|
+
finishReason: "tool_calls",
|
|
254
|
+
rawFinishReason: raw
|
|
255
|
+
};
|
|
256
|
+
case "length": return {
|
|
257
|
+
finishReason: "truncated",
|
|
258
|
+
rawFinishReason: raw
|
|
259
|
+
};
|
|
260
|
+
case "content_filter": return {
|
|
261
|
+
finishReason: "filtered",
|
|
262
|
+
rawFinishReason: raw
|
|
263
|
+
};
|
|
264
|
+
default: return {
|
|
265
|
+
finishReason: "other",
|
|
266
|
+
rawFinishReason: raw
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Convert tool-role message content according to the chosen strategy.
|
|
272
|
+
*/
|
|
273
|
+
function convertToolMessageContent(message, conversion) {
|
|
274
|
+
if (conversion === "extract_text") return extractText(message);
|
|
275
|
+
return message.content.map((p) => convertContentPart(p)).filter((p) => p !== null);
|
|
276
|
+
}
|
|
277
|
+
//#endregion
|
|
278
|
+
export { mergeInPlace as _, isFunctionToolCall as a, thinkingEffortToReasoningEffort as c, createToolMessage as d, createUserMessage as f, isToolCallPart as g, isToolCall as h, extractUsage as i, toolToOpenAI as l, isContentPart as m, convertOpenAIError as n, normalizeOpenAIFinishReason as o, extractText as p, convertToolMessageContent as r, reasoningEffortToThinkingEffort as s, convertContentPart as t, createAssistantMessage as u };
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { b as Message, c as TokenUsage, n as FinishReason, o as ThinkingEffort, p as Tool, v as ContentPart } from "./provider-DiJKWMsQ.mjs";
|
|
2
|
+
import { o as ChatProviderError } from "./errors-DweKbIOf.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/providers/openai-common.d.ts
|
|
5
|
+
interface OpenAIContentPart {
|
|
6
|
+
type: string;
|
|
7
|
+
text?: string | undefined;
|
|
8
|
+
image_url?: {
|
|
9
|
+
url: string;
|
|
10
|
+
id?: string | null;
|
|
11
|
+
} | undefined;
|
|
12
|
+
audio_url?: {
|
|
13
|
+
url: string;
|
|
14
|
+
id?: string | null;
|
|
15
|
+
} | undefined;
|
|
16
|
+
video_url?: {
|
|
17
|
+
url: string;
|
|
18
|
+
id?: string | null;
|
|
19
|
+
} | undefined;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Convert a kosong `ContentPart` to OpenAI-compatible content part.
|
|
23
|
+
* Returns `null` for think parts (handled separately as reasoning_content).
|
|
24
|
+
*/
|
|
25
|
+
declare function convertContentPart(part: ContentPart): OpenAIContentPart | null;
|
|
26
|
+
interface OpenAIToolParam {
|
|
27
|
+
type: string;
|
|
28
|
+
function: {
|
|
29
|
+
name: string;
|
|
30
|
+
description?: string;
|
|
31
|
+
parameters?: Record<string, unknown>;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Convert a kosong `Tool` to OpenAI tool format.
|
|
36
|
+
*/
|
|
37
|
+
declare function toolToOpenAI(tool: Tool): OpenAIToolParam;
|
|
38
|
+
/**
|
|
39
|
+
* Convert an OpenAI SDK error (or raw Error) to a kosong `ChatProviderError`.
|
|
40
|
+
*/
|
|
41
|
+
declare function convertOpenAIError(error: unknown): ChatProviderError;
|
|
42
|
+
/** Shape of a function-type tool call (subset used by the guard). */
|
|
43
|
+
interface FunctionToolCallShape {
|
|
44
|
+
type: 'function';
|
|
45
|
+
id: string;
|
|
46
|
+
function: {
|
|
47
|
+
name: string;
|
|
48
|
+
arguments: string | null;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Type guard: narrow a tool call union to the function-type variant.
|
|
53
|
+
* Works with OpenAI SDK's `ChatCompletionMessageToolCall` as well as
|
|
54
|
+
* any object carrying `{ type: string }`.
|
|
55
|
+
*/
|
|
56
|
+
declare function isFunctionToolCall<T extends {
|
|
57
|
+
type: string;
|
|
58
|
+
}>(tc: T): tc is T & FunctionToolCallShape;
|
|
59
|
+
/**
|
|
60
|
+
* Map kosong `ThinkingEffort` to OpenAI `reasoning_effort` string.
|
|
61
|
+
*/
|
|
62
|
+
declare function thinkingEffortToReasoningEffort(effort: ThinkingEffort): string | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* Map OpenAI `reasoning_effort` string back to kosong `ThinkingEffort`.
|
|
65
|
+
*/
|
|
66
|
+
declare function reasoningEffortToThinkingEffort(reasoning: string | undefined): ThinkingEffort | null;
|
|
67
|
+
/**
|
|
68
|
+
* Extract `TokenUsage` from an OpenAI-compatible usage object.
|
|
69
|
+
*/
|
|
70
|
+
declare function extractUsage(usage: unknown): TokenUsage | null;
|
|
71
|
+
/**
|
|
72
|
+
* Normalize an OpenAI Chat Completions–style `finish_reason` string to the
|
|
73
|
+
* unified {@link FinishReason} enum.
|
|
74
|
+
*
|
|
75
|
+
* Used by both the Byf and OpenAI Legacy adapters because they share the
|
|
76
|
+
* Chat Completions wire format. Returns `{ finishReason: null,
|
|
77
|
+
* rawFinishReason: null }` when the upstream value is missing or `null` so
|
|
78
|
+
* callers can treat "no signal" uniformly.
|
|
79
|
+
*
|
|
80
|
+
* Mapping:
|
|
81
|
+
* - `'stop'` → `'completed'`
|
|
82
|
+
* - `'tool_calls'` → `'tool_calls'`
|
|
83
|
+
* - `'function_call'` → `'tool_calls'` (legacy alias)
|
|
84
|
+
* - `'length'` → `'truncated'`
|
|
85
|
+
* - `'content_filter'` → `'filtered'`
|
|
86
|
+
* - any other non-null string → `'other'`
|
|
87
|
+
*/
|
|
88
|
+
declare function normalizeOpenAIFinishReason(raw: string | null | undefined): {
|
|
89
|
+
finishReason: FinishReason | null;
|
|
90
|
+
rawFinishReason: string | null;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Strategy for converting tool-role message content.
|
|
94
|
+
*
|
|
95
|
+
* - `'extract_text'`: flatten all content parts into a single text string
|
|
96
|
+
* (some providers require tool results as plain text).
|
|
97
|
+
* - `null`: convert content parts to the standard OpenAI content-part array.
|
|
98
|
+
*/
|
|
99
|
+
type ToolMessageConversion = 'extract_text' | null;
|
|
100
|
+
/**
|
|
101
|
+
* Convert tool-role message content according to the chosen strategy.
|
|
102
|
+
*/
|
|
103
|
+
declare function convertToolMessageContent(message: Message, conversion: ToolMessageConversion): string | OpenAIContentPart[];
|
|
104
|
+
//#endregion
|
|
105
|
+
export { convertContentPart as a, extractUsage as c, reasoningEffortToThinkingEffort as d, thinkingEffortToReasoningEffort as f, ToolMessageConversion as i, isFunctionToolCall as l, OpenAIContentPart as n, convertOpenAIError as o, toolToOpenAI as p, OpenAIToolParam as r, convertToolMessageContent as s, FunctionToolCallShape as t, normalizeOpenAIFinishReason as u };
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { D as VideoURLPart, a as StreamedMessage, b as Message, i as ProviderRequestAuth, m as ModelCapability, o as ThinkingEffort, p as Tool, r as GenerateOptions, s as VideoUploadInput, t as ChatProvider } from "./provider-DiJKWMsQ.mjs";
|
|
2
|
+
import OpenAI from "openai";
|
|
3
|
+
|
|
4
|
+
//#region src/providers/openai-compat-files.d.ts
|
|
5
|
+
interface OpenAICompatUploadOptions {
|
|
6
|
+
auth?: ProviderRequestAuth;
|
|
7
|
+
signal?: AbortSignal;
|
|
8
|
+
}
|
|
9
|
+
interface OpenAICompatFilesOptions {
|
|
10
|
+
apiKey?: string;
|
|
11
|
+
baseUrl: string;
|
|
12
|
+
defaultHeaders?: Record<string, string>;
|
|
13
|
+
clientFactory?: (auth: ProviderRequestAuth) => OpenAI;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* OpenAI-compatible file upload client.
|
|
17
|
+
*
|
|
18
|
+
* Wraps the underlying OpenAI-compatible `files.create` API to upload videos
|
|
19
|
+
* to the file service and return them as {@link VideoURLPart} values
|
|
20
|
+
* suitable for use in chat messages.
|
|
21
|
+
*
|
|
22
|
+
* An `OpenAICompatFiles` instance is typically obtained from
|
|
23
|
+
* {@link OpenAICompatChatProvider.files}.
|
|
24
|
+
*/
|
|
25
|
+
declare class OpenAICompatFiles {
|
|
26
|
+
private readonly _apiKey;
|
|
27
|
+
private readonly _baseUrl;
|
|
28
|
+
private readonly _defaultHeaders;
|
|
29
|
+
private readonly _client;
|
|
30
|
+
private readonly _clientFactory;
|
|
31
|
+
constructor(options: OpenAICompatFilesOptions);
|
|
32
|
+
/**
|
|
33
|
+
* Upload a video file for use in chat messages.
|
|
34
|
+
*
|
|
35
|
+
* Accepts either a local filesystem path or an in-memory
|
|
36
|
+
* {@link VideoUploadInput}. Returns a {@link VideoURLPart} referencing the
|
|
37
|
+
* uploaded file by its file id.
|
|
38
|
+
*
|
|
39
|
+
* @param input - Local path string or `{ data, mimeType }` object.
|
|
40
|
+
* @returns A `VideoURLPart` whose `url` references the uploaded file
|
|
41
|
+
* by its file id (e.g. `ms://<file-id>`).
|
|
42
|
+
* @throws {ChatProviderError} if the input is not a video or the upload
|
|
43
|
+
* fails.
|
|
44
|
+
*/
|
|
45
|
+
uploadVideo(input: string | VideoUploadInput, options?: OpenAICompatUploadOptions): Promise<VideoURLPart>;
|
|
46
|
+
private _createClient;
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region src/providers/openai-compat.d.ts
|
|
50
|
+
interface OpenAICompatOptions {
|
|
51
|
+
apiKey?: string;
|
|
52
|
+
baseUrl?: string;
|
|
53
|
+
model: string;
|
|
54
|
+
stream?: boolean;
|
|
55
|
+
defaultHeaders?: Record<string, string>;
|
|
56
|
+
thinkingEffortKey?: string;
|
|
57
|
+
generationKwargs?: GenerationKwargs;
|
|
58
|
+
clientFactory?: (auth: ProviderRequestAuth) => OpenAI;
|
|
59
|
+
}
|
|
60
|
+
interface GenerationKwargs {
|
|
61
|
+
/**
|
|
62
|
+
* Legacy completion-budget alias. Some OpenAI-compatible APIs still accept
|
|
63
|
+
* `max_tokens`, but for reasoning models it shares the budget with
|
|
64
|
+
* `reasoning_content` and a small value can cause a 200 response with no
|
|
65
|
+
* `content`. Prefer `max_completion_tokens`. When both are set
|
|
66
|
+
* `max_completion_tokens` wins; this provider normalizes by sending only
|
|
67
|
+
* `max_completion_tokens` on the wire.
|
|
68
|
+
*/
|
|
69
|
+
max_tokens?: number | undefined;
|
|
70
|
+
max_completion_tokens?: number | undefined;
|
|
71
|
+
temperature?: number | undefined;
|
|
72
|
+
top_p?: number | undefined;
|
|
73
|
+
n?: number | undefined;
|
|
74
|
+
presence_penalty?: number | undefined;
|
|
75
|
+
frequency_penalty?: number | undefined;
|
|
76
|
+
stop?: string | string[] | undefined;
|
|
77
|
+
reasoning_effort?: string | undefined;
|
|
78
|
+
prompt_cache_key?: string | undefined;
|
|
79
|
+
extra_body?: ExtraBody;
|
|
80
|
+
[key: string]: unknown;
|
|
81
|
+
}
|
|
82
|
+
interface ThinkingConfig {
|
|
83
|
+
type?: 'enabled' | 'disabled';
|
|
84
|
+
keep?: unknown;
|
|
85
|
+
[key: string]: unknown;
|
|
86
|
+
}
|
|
87
|
+
interface ExtraBody {
|
|
88
|
+
thinking?: ThinkingConfig;
|
|
89
|
+
[key: string]: unknown;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Extract usage from a streaming chunk. Some OpenAI-compatible providers may place usage in
|
|
93
|
+
* `choices[0].usage` in addition to the top-level `usage` field.
|
|
94
|
+
*/
|
|
95
|
+
declare function extractUsageFromChunk(chunk: Record<string, unknown>): Record<string, unknown> | null;
|
|
96
|
+
declare class OpenAICompatChatProvider implements ChatProvider {
|
|
97
|
+
readonly name: string;
|
|
98
|
+
private _model;
|
|
99
|
+
private _stream;
|
|
100
|
+
private _apiKey;
|
|
101
|
+
private _baseUrl;
|
|
102
|
+
private _defaultHeaders;
|
|
103
|
+
private _generationKwargs;
|
|
104
|
+
private _thinkingEffortKey;
|
|
105
|
+
private _client;
|
|
106
|
+
private _clientFactory;
|
|
107
|
+
private _files;
|
|
108
|
+
constructor(options: OpenAICompatOptions);
|
|
109
|
+
get modelName(): string;
|
|
110
|
+
/**
|
|
111
|
+
* File upload client for an OpenAI-compatible service.
|
|
112
|
+
*
|
|
113
|
+
* Use this to upload videos (and other media in the future) to the file
|
|
114
|
+
* service and receive a content part that can be embedded in chat
|
|
115
|
+
* messages.
|
|
116
|
+
*/
|
|
117
|
+
get files(): OpenAICompatFiles;
|
|
118
|
+
uploadVideo(input: string | VideoUploadInput, options?: GenerateOptions): Promise<VideoURLPart>;
|
|
119
|
+
get thinkingEffort(): ThinkingEffort | null;
|
|
120
|
+
get modelParameters(): Record<string, unknown>;
|
|
121
|
+
generate(systemPrompt: string, tools: Tool[], history: Message[], options?: GenerateOptions): Promise<StreamedMessage>;
|
|
122
|
+
getCapability(_model?: string): ModelCapability;
|
|
123
|
+
withThinking(effort: ThinkingEffort): OpenAICompatChatProvider;
|
|
124
|
+
withGenerationKwargs(kwargs: GenerationKwargs): OpenAICompatChatProvider;
|
|
125
|
+
withMaxCompletionTokens(maxCompletionTokens: number): OpenAICompatChatProvider;
|
|
126
|
+
withExtraBody(extraBody: ExtraBody): OpenAICompatChatProvider;
|
|
127
|
+
private _createClient;
|
|
128
|
+
private _withGenerationKwargs;
|
|
129
|
+
private _clone;
|
|
130
|
+
}
|
|
131
|
+
//#endregion
|
|
132
|
+
export { ThinkingConfig as a, OpenAICompatOptions as i, GenerationKwargs as n, extractUsageFromChunk as o, OpenAICompatChatProvider as r, ExtraBody as t };
|