@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 +6 -0
- package/internal/dist/index.d.mts +88 -0
- package/internal/dist/index.d.ts +88 -0
- package/internal/dist/index.js +175 -0
- package/internal/dist/index.js.map +1 -0
- package/internal/dist/index.mjs +148 -0
- package/internal/dist/index.mjs.map +1 -0
- package/package.json +9 -2
package/CHANGELOG.md
CHANGED
@@ -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.
|
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*\"",
|