@ai-sdk/openai-compatible 0.0.12 → 0.0.13

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @ai-sdk/openai-compatible
2
2
 
3
+ ## 0.0.13
4
+
5
+ ### Patch Changes
6
+
7
+ - 6564812: feat (provider/openai-compatible): Add'l exports for customization.
8
+
3
9
  ## 0.0.12
4
10
 
5
11
  ### Patch Changes
@@ -0,0 +1,88 @@
1
+ import { JSONValue, LanguageModelV1Prompt, LanguageModelV1FinishReason, LanguageModelV1ObjectGenerationMode } from '@ai-sdk/provider';
2
+ import { FetchFunction } from '@ai-sdk/provider-utils';
3
+ import { ZodSchema } from 'zod';
4
+
5
+ type OpenAICompatibleChatPrompt = Array<OpenAICompatibleMessage>;
6
+ type OpenAICompatibleMessage = OpenAICompatibleSystemMessage | OpenAICompatibleUserMessage | OpenAICompatibleAssistantMessage | OpenAICompatibleToolMessage;
7
+ type JsonRecord<T = never> = Record<string, JSONValue | JSONValue[] | T | T[] | undefined>;
8
+ interface OpenAICompatibleSystemMessage extends JsonRecord {
9
+ role: 'system';
10
+ content: string;
11
+ }
12
+ interface OpenAICompatibleUserMessage extends JsonRecord<OpenAICompatibleContentPart> {
13
+ role: 'user';
14
+ content: string | Array<OpenAICompatibleContentPart>;
15
+ }
16
+ type OpenAICompatibleContentPart = OpenAICompatibleContentPartText | OpenAICompatibleContentPartImage;
17
+ interface OpenAICompatibleContentPartImage extends JsonRecord {
18
+ type: 'image_url';
19
+ image_url: {
20
+ url: string;
21
+ };
22
+ }
23
+ interface OpenAICompatibleContentPartText extends JsonRecord {
24
+ type: 'text';
25
+ text: string;
26
+ }
27
+ interface OpenAICompatibleAssistantMessage extends JsonRecord<OpenAICompatibleMessageToolCall> {
28
+ role: 'assistant';
29
+ content?: string | null;
30
+ tool_calls?: Array<OpenAICompatibleMessageToolCall>;
31
+ }
32
+ interface OpenAICompatibleMessageToolCall extends JsonRecord {
33
+ type: 'function';
34
+ id: string;
35
+ function: {
36
+ arguments: string;
37
+ name: string;
38
+ strict?: boolean;
39
+ };
40
+ }
41
+ interface OpenAICompatibleToolMessage extends JsonRecord {
42
+ role: 'tool';
43
+ content: string;
44
+ tool_call_id: string;
45
+ }
46
+
47
+ declare function convertToOpenAICompatibleChatMessages(prompt: LanguageModelV1Prompt): OpenAICompatibleChatPrompt;
48
+
49
+ declare function mapOpenAICompatibleFinishReason(finishReason: string | null | undefined): LanguageModelV1FinishReason;
50
+
51
+ declare function getResponseMetadata({ id, model, created, }: {
52
+ id?: string | undefined | null;
53
+ created?: number | undefined | null;
54
+ model?: string | undefined | null;
55
+ }): {
56
+ id: string | undefined;
57
+ modelId: string | undefined;
58
+ timestamp: Date | undefined;
59
+ };
60
+
61
+ type ProviderErrorStructure<T> = {
62
+ errorSchema: ZodSchema<T>;
63
+ errorToMessage: (error: T) => string;
64
+ isRetryable?: (response: Response, error?: T) => boolean;
65
+ };
66
+
67
+ type OpenAICompatibleChatConfig = {
68
+ provider: string;
69
+ headers: () => Record<string, string | undefined>;
70
+ url: (options: {
71
+ modelId: string;
72
+ path: string;
73
+ }) => string;
74
+ fetch?: FetchFunction;
75
+ errorStructure?: ProviderErrorStructure<any>;
76
+ /**
77
+ Default object generation mode that should be used with this model when
78
+ no mode is specified. Should be the mode with the best results for this
79
+ model. `undefined` can be specified if object generation is not supported.
80
+ */
81
+ defaultObjectGenerationMode?: LanguageModelV1ObjectGenerationMode;
82
+ /**
83
+ * Whether the model supports structured outputs.
84
+ */
85
+ supportsStructuredOutputs?: boolean;
86
+ };
87
+
88
+ export { type OpenAICompatibleChatConfig, convertToOpenAICompatibleChatMessages, getResponseMetadata, mapOpenAICompatibleFinishReason };
@@ -0,0 +1,88 @@
1
+ import { JSONValue, LanguageModelV1Prompt, LanguageModelV1FinishReason, LanguageModelV1ObjectGenerationMode } from '@ai-sdk/provider';
2
+ import { FetchFunction } from '@ai-sdk/provider-utils';
3
+ import { ZodSchema } from 'zod';
4
+
5
+ type OpenAICompatibleChatPrompt = Array<OpenAICompatibleMessage>;
6
+ type OpenAICompatibleMessage = OpenAICompatibleSystemMessage | OpenAICompatibleUserMessage | OpenAICompatibleAssistantMessage | OpenAICompatibleToolMessage;
7
+ type JsonRecord<T = never> = Record<string, JSONValue | JSONValue[] | T | T[] | undefined>;
8
+ interface OpenAICompatibleSystemMessage extends JsonRecord {
9
+ role: 'system';
10
+ content: string;
11
+ }
12
+ interface OpenAICompatibleUserMessage extends JsonRecord<OpenAICompatibleContentPart> {
13
+ role: 'user';
14
+ content: string | Array<OpenAICompatibleContentPart>;
15
+ }
16
+ type OpenAICompatibleContentPart = OpenAICompatibleContentPartText | OpenAICompatibleContentPartImage;
17
+ interface OpenAICompatibleContentPartImage extends JsonRecord {
18
+ type: 'image_url';
19
+ image_url: {
20
+ url: string;
21
+ };
22
+ }
23
+ interface OpenAICompatibleContentPartText extends JsonRecord {
24
+ type: 'text';
25
+ text: string;
26
+ }
27
+ interface OpenAICompatibleAssistantMessage extends JsonRecord<OpenAICompatibleMessageToolCall> {
28
+ role: 'assistant';
29
+ content?: string | null;
30
+ tool_calls?: Array<OpenAICompatibleMessageToolCall>;
31
+ }
32
+ interface OpenAICompatibleMessageToolCall extends JsonRecord {
33
+ type: 'function';
34
+ id: string;
35
+ function: {
36
+ arguments: string;
37
+ name: string;
38
+ strict?: boolean;
39
+ };
40
+ }
41
+ interface OpenAICompatibleToolMessage extends JsonRecord {
42
+ role: 'tool';
43
+ content: string;
44
+ tool_call_id: string;
45
+ }
46
+
47
+ declare function convertToOpenAICompatibleChatMessages(prompt: LanguageModelV1Prompt): OpenAICompatibleChatPrompt;
48
+
49
+ declare function mapOpenAICompatibleFinishReason(finishReason: string | null | undefined): LanguageModelV1FinishReason;
50
+
51
+ declare function getResponseMetadata({ id, model, created, }: {
52
+ id?: string | undefined | null;
53
+ created?: number | undefined | null;
54
+ model?: string | undefined | null;
55
+ }): {
56
+ id: string | undefined;
57
+ modelId: string | undefined;
58
+ timestamp: Date | undefined;
59
+ };
60
+
61
+ type ProviderErrorStructure<T> = {
62
+ errorSchema: ZodSchema<T>;
63
+ errorToMessage: (error: T) => string;
64
+ isRetryable?: (response: Response, error?: T) => boolean;
65
+ };
66
+
67
+ type OpenAICompatibleChatConfig = {
68
+ provider: string;
69
+ headers: () => Record<string, string | undefined>;
70
+ url: (options: {
71
+ modelId: string;
72
+ path: string;
73
+ }) => string;
74
+ fetch?: FetchFunction;
75
+ errorStructure?: ProviderErrorStructure<any>;
76
+ /**
77
+ Default object generation mode that should be used with this model when
78
+ no mode is specified. Should be the mode with the best results for this
79
+ model. `undefined` can be specified if object generation is not supported.
80
+ */
81
+ defaultObjectGenerationMode?: LanguageModelV1ObjectGenerationMode;
82
+ /**
83
+ * Whether the model supports structured outputs.
84
+ */
85
+ supportsStructuredOutputs?: boolean;
86
+ };
87
+
88
+ export { type OpenAICompatibleChatConfig, convertToOpenAICompatibleChatMessages, getResponseMetadata, mapOpenAICompatibleFinishReason };
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/internal/index.ts
21
+ var internal_exports = {};
22
+ __export(internal_exports, {
23
+ convertToOpenAICompatibleChatMessages: () => convertToOpenAICompatibleChatMessages,
24
+ getResponseMetadata: () => getResponseMetadata,
25
+ mapOpenAICompatibleFinishReason: () => mapOpenAICompatibleFinishReason
26
+ });
27
+ module.exports = __toCommonJS(internal_exports);
28
+
29
+ // src/convert-to-openai-compatible-chat-messages.ts
30
+ var import_provider = require("@ai-sdk/provider");
31
+ var import_provider_utils = require("@ai-sdk/provider-utils");
32
+ function getOpenAIMetadata(message) {
33
+ var _a, _b;
34
+ return (_b = (_a = message == null ? void 0 : message.providerMetadata) == null ? void 0 : _a.openaiCompatible) != null ? _b : {};
35
+ }
36
+ function convertToOpenAICompatibleChatMessages(prompt) {
37
+ const messages = [];
38
+ for (const { role, content, ...message } of prompt) {
39
+ const metadata = getOpenAIMetadata({ ...message });
40
+ switch (role) {
41
+ case "system": {
42
+ messages.push({ role: "system", content, ...metadata });
43
+ break;
44
+ }
45
+ case "user": {
46
+ if (content.length === 1 && content[0].type === "text") {
47
+ messages.push({
48
+ role: "user",
49
+ content: content[0].text,
50
+ ...getOpenAIMetadata(content[0])
51
+ });
52
+ break;
53
+ }
54
+ messages.push({
55
+ role: "user",
56
+ content: content.map((part) => {
57
+ var _a;
58
+ const partMetadata = getOpenAIMetadata(part);
59
+ switch (part.type) {
60
+ case "text": {
61
+ return { type: "text", text: part.text, ...partMetadata };
62
+ }
63
+ case "image": {
64
+ return {
65
+ type: "image_url",
66
+ image_url: {
67
+ url: part.image instanceof URL ? part.image.toString() : `data:${(_a = part.mimeType) != null ? _a : "image/jpeg"};base64,${(0, import_provider_utils.convertUint8ArrayToBase64)(part.image)}`
68
+ },
69
+ ...partMetadata
70
+ };
71
+ }
72
+ case "file": {
73
+ throw new import_provider.UnsupportedFunctionalityError({
74
+ functionality: "File content parts in user messages"
75
+ });
76
+ }
77
+ }
78
+ }),
79
+ ...metadata
80
+ });
81
+ break;
82
+ }
83
+ case "assistant": {
84
+ let text = "";
85
+ const toolCalls = [];
86
+ for (const part of content) {
87
+ const partMetadata = getOpenAIMetadata(part);
88
+ switch (part.type) {
89
+ case "text": {
90
+ text += part.text;
91
+ break;
92
+ }
93
+ case "tool-call": {
94
+ toolCalls.push({
95
+ id: part.toolCallId,
96
+ type: "function",
97
+ function: {
98
+ name: part.toolName,
99
+ arguments: JSON.stringify(part.args)
100
+ },
101
+ ...partMetadata
102
+ });
103
+ break;
104
+ }
105
+ default: {
106
+ const _exhaustiveCheck = part;
107
+ throw new Error(`Unsupported part: ${_exhaustiveCheck}`);
108
+ }
109
+ }
110
+ }
111
+ messages.push({
112
+ role: "assistant",
113
+ content: text,
114
+ tool_calls: toolCalls.length > 0 ? toolCalls : void 0,
115
+ ...metadata
116
+ });
117
+ break;
118
+ }
119
+ case "tool": {
120
+ for (const toolResponse of content) {
121
+ const toolResponseMetadata = getOpenAIMetadata(toolResponse);
122
+ messages.push({
123
+ role: "tool",
124
+ tool_call_id: toolResponse.toolCallId,
125
+ content: JSON.stringify(toolResponse.result),
126
+ ...toolResponseMetadata
127
+ });
128
+ }
129
+ break;
130
+ }
131
+ default: {
132
+ const _exhaustiveCheck = role;
133
+ throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
134
+ }
135
+ }
136
+ }
137
+ return messages;
138
+ }
139
+
140
+ // src/map-openai-compatible-finish-reason.ts
141
+ function mapOpenAICompatibleFinishReason(finishReason) {
142
+ switch (finishReason) {
143
+ case "stop":
144
+ return "stop";
145
+ case "length":
146
+ return "length";
147
+ case "content_filter":
148
+ return "content-filter";
149
+ case "function_call":
150
+ case "tool_calls":
151
+ return "tool-calls";
152
+ default:
153
+ return "unknown";
154
+ }
155
+ }
156
+
157
+ // src/get-response-metadata.ts
158
+ function getResponseMetadata({
159
+ id,
160
+ model,
161
+ created
162
+ }) {
163
+ return {
164
+ id: id != null ? id : void 0,
165
+ modelId: model != null ? model : void 0,
166
+ timestamp: created != null ? new Date(created * 1e3) : void 0
167
+ };
168
+ }
169
+ // Annotate the CommonJS export names for ESM import in node:
170
+ 0 && (module.exports = {
171
+ convertToOpenAICompatibleChatMessages,
172
+ getResponseMetadata,
173
+ mapOpenAICompatibleFinishReason
174
+ });
175
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/internal/index.ts","../../src/convert-to-openai-compatible-chat-messages.ts","../../src/map-openai-compatible-finish-reason.ts","../../src/get-response-metadata.ts"],"sourcesContent":["export { convertToOpenAICompatibleChatMessages } from '../convert-to-openai-compatible-chat-messages';\nexport { mapOpenAICompatibleFinishReason } from '../map-openai-compatible-finish-reason';\nexport { getResponseMetadata } from '../get-response-metadata';\nexport type { OpenAICompatibleChatConfig } from '../openai-compatible-chat-language-model';\n","import {\n LanguageModelV1Prompt,\n LanguageModelV1ProviderMetadata,\n UnsupportedFunctionalityError,\n} from '@ai-sdk/provider';\nimport { convertUint8ArrayToBase64 } from '@ai-sdk/provider-utils';\nimport { OpenAICompatibleChatPrompt } from './openai-compatible-api-types';\n\nfunction getOpenAIMetadata(message: {\n providerMetadata?: LanguageModelV1ProviderMetadata;\n}) {\n return message?.providerMetadata?.openaiCompatible ?? {};\n}\n\nexport function convertToOpenAICompatibleChatMessages(\n prompt: LanguageModelV1Prompt,\n): OpenAICompatibleChatPrompt {\n const messages: OpenAICompatibleChatPrompt = [];\n for (const { role, content, ...message } of prompt) {\n const metadata = getOpenAIMetadata({ ...message });\n switch (role) {\n case 'system': {\n messages.push({ role: 'system', content, ...metadata });\n break;\n }\n\n case 'user': {\n if (content.length === 1 && content[0].type === 'text') {\n messages.push({\n role: 'user',\n content: content[0].text,\n ...getOpenAIMetadata(content[0]),\n });\n break;\n }\n\n messages.push({\n role: 'user',\n content: content.map(part => {\n const partMetadata = getOpenAIMetadata(part);\n switch (part.type) {\n case 'text': {\n return { type: 'text', text: part.text, ...partMetadata };\n }\n case 'image': {\n return {\n type: 'image_url',\n image_url: {\n url:\n part.image instanceof URL\n ? part.image.toString()\n : `data:${\n part.mimeType ?? 'image/jpeg'\n };base64,${convertUint8ArrayToBase64(part.image)}`,\n },\n ...partMetadata,\n };\n }\n case 'file': {\n throw new UnsupportedFunctionalityError({\n functionality: 'File content parts in user messages',\n });\n }\n }\n }),\n ...metadata,\n });\n\n break;\n }\n\n case 'assistant': {\n let text = '';\n const toolCalls: Array<{\n id: string;\n type: 'function';\n function: { name: string; arguments: string };\n }> = [];\n\n for (const part of content) {\n const partMetadata = getOpenAIMetadata(part);\n switch (part.type) {\n case 'text': {\n text += part.text;\n break;\n }\n case 'tool-call': {\n toolCalls.push({\n id: part.toolCallId,\n type: 'function',\n function: {\n name: part.toolName,\n arguments: JSON.stringify(part.args),\n },\n ...partMetadata,\n });\n break;\n }\n default: {\n const _exhaustiveCheck: never = part;\n throw new Error(`Unsupported part: ${_exhaustiveCheck}`);\n }\n }\n }\n\n messages.push({\n role: 'assistant',\n content: text,\n tool_calls: toolCalls.length > 0 ? toolCalls : undefined,\n ...metadata,\n });\n\n break;\n }\n\n case 'tool': {\n for (const toolResponse of content) {\n const toolResponseMetadata = getOpenAIMetadata(toolResponse);\n messages.push({\n role: 'tool',\n tool_call_id: toolResponse.toolCallId,\n content: JSON.stringify(toolResponse.result),\n ...toolResponseMetadata,\n });\n }\n break;\n }\n\n default: {\n const _exhaustiveCheck: never = role;\n throw new Error(`Unsupported role: ${_exhaustiveCheck}`);\n }\n }\n }\n\n return messages;\n}\n","import { LanguageModelV1FinishReason } from '@ai-sdk/provider';\n\nexport function mapOpenAICompatibleFinishReason(\n finishReason: string | null | undefined,\n): LanguageModelV1FinishReason {\n switch (finishReason) {\n case 'stop':\n return 'stop';\n case 'length':\n return 'length';\n case 'content_filter':\n return 'content-filter';\n case 'function_call':\n case 'tool_calls':\n return 'tool-calls';\n default:\n return 'unknown';\n }\n}\n","export function getResponseMetadata({\n id,\n model,\n created,\n}: {\n id?: string | undefined | null;\n created?: number | undefined | null;\n model?: string | undefined | null;\n}) {\n return {\n id: id ?? undefined,\n modelId: model ?? undefined,\n timestamp: created != null ? new Date(created * 1000) : undefined,\n };\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,148 @@
1
+ // src/convert-to-openai-compatible-chat-messages.ts
2
+ import {
3
+ UnsupportedFunctionalityError
4
+ } from "@ai-sdk/provider";
5
+ import { convertUint8ArrayToBase64 } from "@ai-sdk/provider-utils";
6
+ function getOpenAIMetadata(message) {
7
+ var _a, _b;
8
+ return (_b = (_a = message == null ? void 0 : message.providerMetadata) == null ? void 0 : _a.openaiCompatible) != null ? _b : {};
9
+ }
10
+ function convertToOpenAICompatibleChatMessages(prompt) {
11
+ const messages = [];
12
+ for (const { role, content, ...message } of prompt) {
13
+ const metadata = getOpenAIMetadata({ ...message });
14
+ switch (role) {
15
+ case "system": {
16
+ messages.push({ role: "system", content, ...metadata });
17
+ break;
18
+ }
19
+ case "user": {
20
+ if (content.length === 1 && content[0].type === "text") {
21
+ messages.push({
22
+ role: "user",
23
+ content: content[0].text,
24
+ ...getOpenAIMetadata(content[0])
25
+ });
26
+ break;
27
+ }
28
+ messages.push({
29
+ role: "user",
30
+ content: content.map((part) => {
31
+ var _a;
32
+ const partMetadata = getOpenAIMetadata(part);
33
+ switch (part.type) {
34
+ case "text": {
35
+ return { type: "text", text: part.text, ...partMetadata };
36
+ }
37
+ case "image": {
38
+ return {
39
+ type: "image_url",
40
+ image_url: {
41
+ url: part.image instanceof URL ? part.image.toString() : `data:${(_a = part.mimeType) != null ? _a : "image/jpeg"};base64,${convertUint8ArrayToBase64(part.image)}`
42
+ },
43
+ ...partMetadata
44
+ };
45
+ }
46
+ case "file": {
47
+ throw new UnsupportedFunctionalityError({
48
+ functionality: "File content parts in user messages"
49
+ });
50
+ }
51
+ }
52
+ }),
53
+ ...metadata
54
+ });
55
+ break;
56
+ }
57
+ case "assistant": {
58
+ let text = "";
59
+ const toolCalls = [];
60
+ for (const part of content) {
61
+ const partMetadata = getOpenAIMetadata(part);
62
+ switch (part.type) {
63
+ case "text": {
64
+ text += part.text;
65
+ break;
66
+ }
67
+ case "tool-call": {
68
+ toolCalls.push({
69
+ id: part.toolCallId,
70
+ type: "function",
71
+ function: {
72
+ name: part.toolName,
73
+ arguments: JSON.stringify(part.args)
74
+ },
75
+ ...partMetadata
76
+ });
77
+ break;
78
+ }
79
+ default: {
80
+ const _exhaustiveCheck = part;
81
+ throw new Error(`Unsupported part: ${_exhaustiveCheck}`);
82
+ }
83
+ }
84
+ }
85
+ messages.push({
86
+ role: "assistant",
87
+ content: text,
88
+ tool_calls: toolCalls.length > 0 ? toolCalls : void 0,
89
+ ...metadata
90
+ });
91
+ break;
92
+ }
93
+ case "tool": {
94
+ for (const toolResponse of content) {
95
+ const toolResponseMetadata = getOpenAIMetadata(toolResponse);
96
+ messages.push({
97
+ role: "tool",
98
+ tool_call_id: toolResponse.toolCallId,
99
+ content: JSON.stringify(toolResponse.result),
100
+ ...toolResponseMetadata
101
+ });
102
+ }
103
+ break;
104
+ }
105
+ default: {
106
+ const _exhaustiveCheck = role;
107
+ throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
108
+ }
109
+ }
110
+ }
111
+ return messages;
112
+ }
113
+
114
+ // src/map-openai-compatible-finish-reason.ts
115
+ function mapOpenAICompatibleFinishReason(finishReason) {
116
+ switch (finishReason) {
117
+ case "stop":
118
+ return "stop";
119
+ case "length":
120
+ return "length";
121
+ case "content_filter":
122
+ return "content-filter";
123
+ case "function_call":
124
+ case "tool_calls":
125
+ return "tool-calls";
126
+ default:
127
+ return "unknown";
128
+ }
129
+ }
130
+
131
+ // src/get-response-metadata.ts
132
+ function getResponseMetadata({
133
+ id,
134
+ model,
135
+ created
136
+ }) {
137
+ return {
138
+ id: id != null ? id : void 0,
139
+ modelId: model != null ? model : void 0,
140
+ timestamp: created != null ? new Date(created * 1e3) : void 0
141
+ };
142
+ }
143
+ export {
144
+ convertToOpenAICompatibleChatMessages,
145
+ getResponseMetadata,
146
+ mapOpenAICompatibleFinishReason
147
+ };
148
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/convert-to-openai-compatible-chat-messages.ts","../../src/map-openai-compatible-finish-reason.ts","../../src/get-response-metadata.ts"],"sourcesContent":["import {\n LanguageModelV1Prompt,\n LanguageModelV1ProviderMetadata,\n UnsupportedFunctionalityError,\n} from '@ai-sdk/provider';\nimport { convertUint8ArrayToBase64 } from '@ai-sdk/provider-utils';\nimport { OpenAICompatibleChatPrompt } from './openai-compatible-api-types';\n\nfunction getOpenAIMetadata(message: {\n providerMetadata?: LanguageModelV1ProviderMetadata;\n}) {\n return message?.providerMetadata?.openaiCompatible ?? {};\n}\n\nexport function convertToOpenAICompatibleChatMessages(\n prompt: LanguageModelV1Prompt,\n): OpenAICompatibleChatPrompt {\n const messages: OpenAICompatibleChatPrompt = [];\n for (const { role, content, ...message } of prompt) {\n const metadata = getOpenAIMetadata({ ...message });\n switch (role) {\n case 'system': {\n messages.push({ role: 'system', content, ...metadata });\n break;\n }\n\n case 'user': {\n if (content.length === 1 && content[0].type === 'text') {\n messages.push({\n role: 'user',\n content: content[0].text,\n ...getOpenAIMetadata(content[0]),\n });\n break;\n }\n\n messages.push({\n role: 'user',\n content: content.map(part => {\n const partMetadata = getOpenAIMetadata(part);\n switch (part.type) {\n case 'text': {\n return { type: 'text', text: part.text, ...partMetadata };\n }\n case 'image': {\n return {\n type: 'image_url',\n image_url: {\n url:\n part.image instanceof URL\n ? part.image.toString()\n : `data:${\n part.mimeType ?? 'image/jpeg'\n };base64,${convertUint8ArrayToBase64(part.image)}`,\n },\n ...partMetadata,\n };\n }\n case 'file': {\n throw new UnsupportedFunctionalityError({\n functionality: 'File content parts in user messages',\n });\n }\n }\n }),\n ...metadata,\n });\n\n break;\n }\n\n case 'assistant': {\n let text = '';\n const toolCalls: Array<{\n id: string;\n type: 'function';\n function: { name: string; arguments: string };\n }> = [];\n\n for (const part of content) {\n const partMetadata = getOpenAIMetadata(part);\n switch (part.type) {\n case 'text': {\n text += part.text;\n break;\n }\n case 'tool-call': {\n toolCalls.push({\n id: part.toolCallId,\n type: 'function',\n function: {\n name: part.toolName,\n arguments: JSON.stringify(part.args),\n },\n ...partMetadata,\n });\n break;\n }\n default: {\n const _exhaustiveCheck: never = part;\n throw new Error(`Unsupported part: ${_exhaustiveCheck}`);\n }\n }\n }\n\n messages.push({\n role: 'assistant',\n content: text,\n tool_calls: toolCalls.length > 0 ? toolCalls : undefined,\n ...metadata,\n });\n\n break;\n }\n\n case 'tool': {\n for (const toolResponse of content) {\n const toolResponseMetadata = getOpenAIMetadata(toolResponse);\n messages.push({\n role: 'tool',\n tool_call_id: toolResponse.toolCallId,\n content: JSON.stringify(toolResponse.result),\n ...toolResponseMetadata,\n });\n }\n break;\n }\n\n default: {\n const _exhaustiveCheck: never = role;\n throw new Error(`Unsupported role: ${_exhaustiveCheck}`);\n }\n }\n }\n\n return messages;\n}\n","import { LanguageModelV1FinishReason } from '@ai-sdk/provider';\n\nexport function mapOpenAICompatibleFinishReason(\n finishReason: string | null | undefined,\n): LanguageModelV1FinishReason {\n switch (finishReason) {\n case 'stop':\n return 'stop';\n case 'length':\n return 'length';\n case 'content_filter':\n return 'content-filter';\n case 'function_call':\n case 'tool_calls':\n return 'tool-calls';\n default:\n return 'unknown';\n }\n}\n","export function getResponseMetadata({\n id,\n model,\n created,\n}: {\n id?: string | undefined | null;\n created?: number | undefined | null;\n model?: string | undefined | null;\n}) {\n return {\n id: id ?? undefined,\n modelId: model ?? undefined,\n timestamp: created != null ? new Date(created * 1000) : undefined,\n };\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/openai-compatible",
3
- "version": "0.0.12",
3
+ "version": "0.0.13",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -8,6 +8,7 @@
8
8
  "types": "./dist/index.d.ts",
9
9
  "files": [
10
10
  "dist/**/*",
11
+ "internal/dist/**/*",
11
12
  "CHANGELOG.md"
12
13
  ],
13
14
  "exports": {
@@ -16,6 +17,12 @@
16
17
  "types": "./dist/index.d.ts",
17
18
  "import": "./dist/index.mjs",
18
19
  "require": "./dist/index.js"
20
+ },
21
+ "./internal": {
22
+ "types": "./internal/dist/index.d.ts",
23
+ "import": "./internal/dist/index.mjs",
24
+ "module": "./internal/dist/index.mjs",
25
+ "require": "./internal/dist/index.js"
19
26
  }
20
27
  },
21
28
  "dependencies": {
@@ -52,7 +59,7 @@
52
59
  "scripts": {
53
60
  "build": "tsup",
54
61
  "build:watch": "tsup --watch",
55
- "clean": "rm -rf dist",
62
+ "clean": "rm -rf dist && rm -rf internal/dist",
56
63
  "lint": "eslint \"./**/*.ts*\"",
57
64
  "type-check": "tsc --noEmit",
58
65
  "prettier-check": "prettier --check \"./**/*.ts*\"",