@friendliai/ai-provider 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -0
- package/dist/index.d.mts +257 -0
- package/dist/index.d.ts +257 -0
- package/dist/index.js +1257 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1255 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +72 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,1255 @@
|
|
|
1
|
+
// src/friendliai-facade.ts
|
|
2
|
+
import { loadApiKey, withoutTrailingSlash } from "@ai-sdk/provider-utils";
|
|
3
|
+
|
|
4
|
+
// src/friendliai-chat-language-model.ts
|
|
5
|
+
import {
|
|
6
|
+
InvalidResponseDataError,
|
|
7
|
+
UnsupportedFunctionalityError as UnsupportedFunctionalityError2
|
|
8
|
+
} from "@ai-sdk/provider";
|
|
9
|
+
import {
|
|
10
|
+
combineHeaders,
|
|
11
|
+
createEventSourceResponseHandler,
|
|
12
|
+
createJsonResponseHandler,
|
|
13
|
+
generateId,
|
|
14
|
+
isParsableJson,
|
|
15
|
+
postJsonToApi
|
|
16
|
+
} from "@ai-sdk/provider-utils";
|
|
17
|
+
import { z as z2 } from "zod";
|
|
18
|
+
|
|
19
|
+
// src/convert-to-friendliai-chat-messages.ts
|
|
20
|
+
import {
|
|
21
|
+
UnsupportedFunctionalityError
|
|
22
|
+
} from "@ai-sdk/provider";
|
|
23
|
+
function convertToFriendliAIChatMessages({
|
|
24
|
+
prompt,
|
|
25
|
+
useLegacyFunctionCalling = false
|
|
26
|
+
}) {
|
|
27
|
+
const messages = [];
|
|
28
|
+
for (const { role, content } of prompt) {
|
|
29
|
+
switch (role) {
|
|
30
|
+
case "system": {
|
|
31
|
+
messages.push({ role: "system", content });
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
case "user": {
|
|
35
|
+
if (content.length === 1 && content[0].type === "text") {
|
|
36
|
+
messages.push({ role: "user", content: content[0].text });
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
messages.push({
|
|
40
|
+
role: "user",
|
|
41
|
+
content: content.map((part) => {
|
|
42
|
+
switch (part.type) {
|
|
43
|
+
case "text": {
|
|
44
|
+
return { type: "text", text: part.text };
|
|
45
|
+
}
|
|
46
|
+
case "image": {
|
|
47
|
+
throw new UnsupportedFunctionalityError({
|
|
48
|
+
functionality: "image-part"
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
});
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
case "assistant": {
|
|
57
|
+
let text = "";
|
|
58
|
+
const toolCalls = [];
|
|
59
|
+
for (const part of content) {
|
|
60
|
+
switch (part.type) {
|
|
61
|
+
case "text": {
|
|
62
|
+
text += part.text;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
case "tool-call": {
|
|
66
|
+
toolCalls.push({
|
|
67
|
+
id: part.toolCallId,
|
|
68
|
+
type: "function",
|
|
69
|
+
function: {
|
|
70
|
+
name: part.toolName,
|
|
71
|
+
arguments: JSON.stringify(part.args)
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
default: {
|
|
77
|
+
const _exhaustiveCheck = part;
|
|
78
|
+
throw new Error(`Unsupported part: ${_exhaustiveCheck}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (useLegacyFunctionCalling) {
|
|
83
|
+
if (toolCalls.length > 1) {
|
|
84
|
+
throw new UnsupportedFunctionalityError({
|
|
85
|
+
functionality: "useLegacyFunctionCalling with multiple tool calls in one message"
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
messages.push({
|
|
89
|
+
role: "assistant",
|
|
90
|
+
content: text,
|
|
91
|
+
function_call: toolCalls.length > 0 ? toolCalls[0].function : void 0
|
|
92
|
+
});
|
|
93
|
+
} else {
|
|
94
|
+
messages.push({
|
|
95
|
+
role: "assistant",
|
|
96
|
+
content: text,
|
|
97
|
+
tool_calls: toolCalls.length > 0 ? toolCalls : void 0
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
case "tool": {
|
|
103
|
+
for (const toolResponse of content) {
|
|
104
|
+
if (useLegacyFunctionCalling) {
|
|
105
|
+
messages.push({
|
|
106
|
+
role: "function",
|
|
107
|
+
name: toolResponse.toolName,
|
|
108
|
+
content: JSON.stringify(toolResponse.result)
|
|
109
|
+
});
|
|
110
|
+
} else {
|
|
111
|
+
messages.push({
|
|
112
|
+
role: "tool",
|
|
113
|
+
tool_call_id: toolResponse.toolCallId,
|
|
114
|
+
content: JSON.stringify(toolResponse.result)
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
default: {
|
|
121
|
+
const _exhaustiveCheck = role;
|
|
122
|
+
throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return messages;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// src/map-friendliai-chat-logprobs.ts
|
|
130
|
+
function mapFriendliAIChatLogProbsOutput(logprobs) {
|
|
131
|
+
var _a, _b;
|
|
132
|
+
return (_b = (_a = logprobs == null ? void 0 : logprobs.content) == null ? void 0 : _a.map(({ token, logprob, top_logprobs }) => ({
|
|
133
|
+
token,
|
|
134
|
+
logprob,
|
|
135
|
+
topLogprobs: top_logprobs ? top_logprobs.map(({ token: token2, logprob: logprob2 }) => ({
|
|
136
|
+
token: token2,
|
|
137
|
+
logprob: logprob2
|
|
138
|
+
})) : []
|
|
139
|
+
}))) != null ? _b : void 0;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// src/map-friendliai-finish-reason.ts
|
|
143
|
+
function mapFriendliAIFinishReason(finishReason) {
|
|
144
|
+
switch (finishReason) {
|
|
145
|
+
case "stop":
|
|
146
|
+
return "stop";
|
|
147
|
+
case "length":
|
|
148
|
+
return "length";
|
|
149
|
+
case "content_filter":
|
|
150
|
+
return "content-filter";
|
|
151
|
+
case "function_call":
|
|
152
|
+
case "tool_calls":
|
|
153
|
+
return "tool-calls";
|
|
154
|
+
default:
|
|
155
|
+
return "unknown";
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// src/friendliai-error.ts
|
|
160
|
+
import { z } from "zod";
|
|
161
|
+
import { createJsonErrorResponseHandler } from "@ai-sdk/provider-utils";
|
|
162
|
+
var friendliAIErrorDataSchema = z.object({
|
|
163
|
+
error: z.object({
|
|
164
|
+
message: z.string(),
|
|
165
|
+
// The additional information below is handled loosely to support
|
|
166
|
+
// FriendliAI-compatible providers that have slightly different error
|
|
167
|
+
// responses:
|
|
168
|
+
type: z.string().nullish(),
|
|
169
|
+
param: z.any().nullish(),
|
|
170
|
+
code: z.union([z.string(), z.number()]).nullish()
|
|
171
|
+
})
|
|
172
|
+
});
|
|
173
|
+
var friendliaiFailedResponseHandler = createJsonErrorResponseHandler({
|
|
174
|
+
errorSchema: friendliAIErrorDataSchema,
|
|
175
|
+
errorToMessage: (data) => data.error.message
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// src/friendliai-chat-language-model.ts
|
|
179
|
+
var FriendliAIChatLanguageModel = class {
|
|
180
|
+
constructor(modelId, settings, config) {
|
|
181
|
+
this.specificationVersion = "v1";
|
|
182
|
+
this.modelId = modelId;
|
|
183
|
+
this.settings = settings;
|
|
184
|
+
this.config = config;
|
|
185
|
+
}
|
|
186
|
+
get supportsStructuredOutputs() {
|
|
187
|
+
return this.settings.structuredOutputs === true;
|
|
188
|
+
}
|
|
189
|
+
get defaultObjectGenerationMode() {
|
|
190
|
+
return this.supportsStructuredOutputs ? "json" : "tool";
|
|
191
|
+
}
|
|
192
|
+
get provider() {
|
|
193
|
+
return this.config.provider;
|
|
194
|
+
}
|
|
195
|
+
getArgs({
|
|
196
|
+
mode,
|
|
197
|
+
prompt,
|
|
198
|
+
maxTokens,
|
|
199
|
+
temperature,
|
|
200
|
+
topP,
|
|
201
|
+
topK,
|
|
202
|
+
frequencyPenalty,
|
|
203
|
+
presencePenalty,
|
|
204
|
+
stopSequences,
|
|
205
|
+
responseFormat,
|
|
206
|
+
seed
|
|
207
|
+
}) {
|
|
208
|
+
var _a;
|
|
209
|
+
const type = mode.type;
|
|
210
|
+
const warnings = [];
|
|
211
|
+
if (topK != null) {
|
|
212
|
+
warnings.push({
|
|
213
|
+
type: "unsupported-setting",
|
|
214
|
+
setting: "topK"
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
if (responseFormat != null && responseFormat.type === "json" && responseFormat.schema != null) {
|
|
218
|
+
warnings.push({
|
|
219
|
+
type: "unsupported-setting",
|
|
220
|
+
setting: "responseFormat",
|
|
221
|
+
details: "JSON response format schema is not supported"
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
const useLegacyFunctionCalling = this.settings.useLegacyFunctionCalling;
|
|
225
|
+
if (useLegacyFunctionCalling && this.settings.parallelToolCalls === true) {
|
|
226
|
+
throw new UnsupportedFunctionalityError2({
|
|
227
|
+
functionality: "useLegacyFunctionCalling with parallelToolCalls"
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
if (useLegacyFunctionCalling && this.settings.structuredOutputs === true) {
|
|
231
|
+
throw new UnsupportedFunctionalityError2({
|
|
232
|
+
functionality: "structuredOutputs with useLegacyFunctionCalling"
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
const baseArgs = {
|
|
236
|
+
// model id:
|
|
237
|
+
model: this.modelId,
|
|
238
|
+
// model specific settings:
|
|
239
|
+
logit_bias: this.settings.logitBias,
|
|
240
|
+
logprobs: this.settings.logprobs === true || typeof this.settings.logprobs === "number" ? true : void 0,
|
|
241
|
+
top_logprobs: typeof this.settings.logprobs === "number" ? this.settings.logprobs : typeof this.settings.logprobs === "boolean" ? this.settings.logprobs ? 0 : void 0 : void 0,
|
|
242
|
+
user: this.settings.user,
|
|
243
|
+
parallel_tool_calls: this.settings.parallelToolCalls,
|
|
244
|
+
// standardized settings:
|
|
245
|
+
max_tokens: maxTokens,
|
|
246
|
+
temperature,
|
|
247
|
+
top_p: topP,
|
|
248
|
+
frequency_penalty: frequencyPenalty,
|
|
249
|
+
presence_penalty: presencePenalty,
|
|
250
|
+
stop: stopSequences,
|
|
251
|
+
seed,
|
|
252
|
+
// response format:
|
|
253
|
+
response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? { type: "json_object" } : void 0,
|
|
254
|
+
// messages:
|
|
255
|
+
messages: convertToFriendliAIChatMessages({
|
|
256
|
+
prompt,
|
|
257
|
+
useLegacyFunctionCalling
|
|
258
|
+
})
|
|
259
|
+
};
|
|
260
|
+
switch (type) {
|
|
261
|
+
case "regular": {
|
|
262
|
+
return {
|
|
263
|
+
args: {
|
|
264
|
+
...baseArgs,
|
|
265
|
+
...prepareToolsAndToolChoice({
|
|
266
|
+
mode,
|
|
267
|
+
useLegacyFunctionCalling,
|
|
268
|
+
structuredOutputs: this.settings.structuredOutputs,
|
|
269
|
+
tools: this.settings.tools
|
|
270
|
+
})
|
|
271
|
+
},
|
|
272
|
+
warnings
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
case "object-json": {
|
|
276
|
+
return {
|
|
277
|
+
args: {
|
|
278
|
+
...baseArgs,
|
|
279
|
+
response_format: this.settings.structuredOutputs === true ? {
|
|
280
|
+
type: "json_schema",
|
|
281
|
+
json_schema: {
|
|
282
|
+
schema: mode.schema,
|
|
283
|
+
strict: true,
|
|
284
|
+
name: (_a = mode.name) != null ? _a : "response",
|
|
285
|
+
description: mode.description
|
|
286
|
+
}
|
|
287
|
+
} : { type: "json_object" }
|
|
288
|
+
},
|
|
289
|
+
warnings
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
case "object-tool": {
|
|
293
|
+
return {
|
|
294
|
+
args: useLegacyFunctionCalling ? {
|
|
295
|
+
...baseArgs,
|
|
296
|
+
function_call: {
|
|
297
|
+
name: mode.tool.name
|
|
298
|
+
},
|
|
299
|
+
functions: [
|
|
300
|
+
{
|
|
301
|
+
name: mode.tool.name,
|
|
302
|
+
description: mode.tool.description,
|
|
303
|
+
parameters: mode.tool.parameters
|
|
304
|
+
}
|
|
305
|
+
]
|
|
306
|
+
} : {
|
|
307
|
+
...baseArgs,
|
|
308
|
+
tool_choice: {
|
|
309
|
+
type: "function",
|
|
310
|
+
function: { name: mode.tool.name }
|
|
311
|
+
},
|
|
312
|
+
tools: [
|
|
313
|
+
{
|
|
314
|
+
type: "function",
|
|
315
|
+
function: {
|
|
316
|
+
name: mode.tool.name,
|
|
317
|
+
description: mode.tool.description,
|
|
318
|
+
parameters: mode.tool.parameters,
|
|
319
|
+
strict: this.settings.structuredOutputs === true ? true : void 0
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
]
|
|
323
|
+
},
|
|
324
|
+
warnings
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
default: {
|
|
328
|
+
const _exhaustiveCheck = type;
|
|
329
|
+
throw new Error(`Unsupported type: ${_exhaustiveCheck}`);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
async doGenerate(options) {
|
|
334
|
+
var _a, _b, _c, _d, _e, _f;
|
|
335
|
+
const { args, warnings } = this.getArgs(options);
|
|
336
|
+
const { responseHeaders, value: response } = await postJsonToApi({
|
|
337
|
+
url: this.config.url({
|
|
338
|
+
path: "/chat/completions",
|
|
339
|
+
modelId: this.modelId
|
|
340
|
+
}),
|
|
341
|
+
headers: combineHeaders(this.config.headers(), options.headers),
|
|
342
|
+
body: args,
|
|
343
|
+
failedResponseHandler: friendliaiFailedResponseHandler,
|
|
344
|
+
successfulResponseHandler: createJsonResponseHandler(
|
|
345
|
+
friendliAIChatResponseSchema
|
|
346
|
+
),
|
|
347
|
+
abortSignal: options.abortSignal,
|
|
348
|
+
fetch: this.config.fetch
|
|
349
|
+
});
|
|
350
|
+
const { messages: rawPrompt, ...rawSettings } = args;
|
|
351
|
+
const choice = response.choices[0];
|
|
352
|
+
return {
|
|
353
|
+
text: (_a = choice.message.content) != null ? _a : void 0,
|
|
354
|
+
toolCalls: this.settings.useLegacyFunctionCalling && choice.message.function_call ? [
|
|
355
|
+
{
|
|
356
|
+
toolCallType: "function",
|
|
357
|
+
toolCallId: generateId(),
|
|
358
|
+
toolName: choice.message.function_call.name,
|
|
359
|
+
args: choice.message.function_call.arguments
|
|
360
|
+
}
|
|
361
|
+
] : (_b = choice.message.tool_calls) == null ? void 0 : _b.map((toolCall) => {
|
|
362
|
+
var _a2;
|
|
363
|
+
return {
|
|
364
|
+
toolCallType: "function",
|
|
365
|
+
toolCallId: (_a2 = toolCall.id) != null ? _a2 : generateId(),
|
|
366
|
+
toolName: toolCall.function.name,
|
|
367
|
+
args: toolCall.function.arguments
|
|
368
|
+
};
|
|
369
|
+
}),
|
|
370
|
+
finishReason: mapFriendliAIFinishReason(choice.finish_reason),
|
|
371
|
+
usage: {
|
|
372
|
+
promptTokens: (_d = (_c = response.usage) == null ? void 0 : _c.prompt_tokens) != null ? _d : NaN,
|
|
373
|
+
completionTokens: (_f = (_e = response.usage) == null ? void 0 : _e.completion_tokens) != null ? _f : NaN
|
|
374
|
+
},
|
|
375
|
+
rawCall: { rawPrompt, rawSettings },
|
|
376
|
+
rawResponse: { headers: responseHeaders },
|
|
377
|
+
warnings,
|
|
378
|
+
logprobs: mapFriendliAIChatLogProbsOutput(choice.logprobs)
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
async doStream(options) {
|
|
382
|
+
const { args, warnings } = this.getArgs(options);
|
|
383
|
+
const { responseHeaders, value: response } = await postJsonToApi({
|
|
384
|
+
url: this.config.url({
|
|
385
|
+
path: "/chat/completions",
|
|
386
|
+
modelId: this.modelId
|
|
387
|
+
}),
|
|
388
|
+
headers: combineHeaders(this.config.headers(), options.headers),
|
|
389
|
+
body: {
|
|
390
|
+
...args,
|
|
391
|
+
stream: true,
|
|
392
|
+
// only include stream_options when in strict compatibility mode:
|
|
393
|
+
stream_options: this.config.compatibility === "strict" ? { include_usage: true } : void 0
|
|
394
|
+
},
|
|
395
|
+
failedResponseHandler: friendliaiFailedResponseHandler,
|
|
396
|
+
successfulResponseHandler: createEventSourceResponseHandler(
|
|
397
|
+
friendliaiChatChunkSchema
|
|
398
|
+
),
|
|
399
|
+
abortSignal: options.abortSignal,
|
|
400
|
+
fetch: this.config.fetch
|
|
401
|
+
});
|
|
402
|
+
const { messages: rawPrompt, ...rawSettings } = args;
|
|
403
|
+
const toolCalls = [];
|
|
404
|
+
let finishReason = "unknown";
|
|
405
|
+
let usage = {
|
|
406
|
+
promptTokens: void 0,
|
|
407
|
+
completionTokens: void 0
|
|
408
|
+
};
|
|
409
|
+
let logprobs;
|
|
410
|
+
const { useLegacyFunctionCalling } = this.settings;
|
|
411
|
+
return {
|
|
412
|
+
stream: response.pipeThrough(
|
|
413
|
+
new TransformStream({
|
|
414
|
+
transform(chunk, controller) {
|
|
415
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
|
|
416
|
+
if (!chunk.success) {
|
|
417
|
+
finishReason = "error";
|
|
418
|
+
controller.enqueue({ type: "error", error: chunk.error });
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
const value = chunk.value;
|
|
422
|
+
if ("tool_call_id" in value) {
|
|
423
|
+
switch (value.state) {
|
|
424
|
+
case "START":
|
|
425
|
+
break;
|
|
426
|
+
case "UPDATE":
|
|
427
|
+
break;
|
|
428
|
+
case "END":
|
|
429
|
+
break;
|
|
430
|
+
case "ERROR":
|
|
431
|
+
finishReason = "error";
|
|
432
|
+
controller.enqueue({
|
|
433
|
+
type: "error",
|
|
434
|
+
error: new Error(
|
|
435
|
+
`Tool call error: ${(_b = (_a = value.error) == null ? void 0 : _a.msg) != null ? _b : "Unknown error"} (type: ${(_d = (_c = value.error) == null ? void 0 : _c.type) != null ? _d : "unknown"})`
|
|
436
|
+
)
|
|
437
|
+
});
|
|
438
|
+
break;
|
|
439
|
+
default:
|
|
440
|
+
finishReason = "error";
|
|
441
|
+
controller.enqueue({
|
|
442
|
+
type: "error",
|
|
443
|
+
error: new Error(
|
|
444
|
+
`Unsupported tool call state: ${value.state}`
|
|
445
|
+
)
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
if ("error" in value) {
|
|
451
|
+
finishReason = "error";
|
|
452
|
+
controller.enqueue({ type: "error", error: value.error });
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
if (value.usage != null) {
|
|
456
|
+
usage = {
|
|
457
|
+
promptTokens: (_e = value.usage.prompt_tokens) != null ? _e : void 0,
|
|
458
|
+
completionTokens: (_f = value.usage.completion_tokens) != null ? _f : void 0
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
const choice = value.choices[0];
|
|
462
|
+
if ((choice == null ? void 0 : choice.finish_reason) != null) {
|
|
463
|
+
finishReason = mapFriendliAIFinishReason(choice.finish_reason);
|
|
464
|
+
}
|
|
465
|
+
if ((choice == null ? void 0 : choice.delta) == null) {
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
const delta = choice.delta;
|
|
469
|
+
if (delta.content != null) {
|
|
470
|
+
controller.enqueue({
|
|
471
|
+
type: "text-delta",
|
|
472
|
+
textDelta: delta.content
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
const mappedLogprobs = mapFriendliAIChatLogProbsOutput(
|
|
476
|
+
choice == null ? void 0 : choice.logprobs
|
|
477
|
+
);
|
|
478
|
+
if (mappedLogprobs == null ? void 0 : mappedLogprobs.length) {
|
|
479
|
+
if (logprobs === void 0) logprobs = [];
|
|
480
|
+
logprobs.push(...mappedLogprobs);
|
|
481
|
+
}
|
|
482
|
+
const mappedToolCalls = useLegacyFunctionCalling && delta.function_call != null ? [
|
|
483
|
+
{
|
|
484
|
+
type: "function",
|
|
485
|
+
id: generateId(),
|
|
486
|
+
function: delta.function_call,
|
|
487
|
+
index: 0
|
|
488
|
+
}
|
|
489
|
+
] : delta.tool_calls;
|
|
490
|
+
if (mappedToolCalls != null) {
|
|
491
|
+
for (const toolCallDelta of mappedToolCalls) {
|
|
492
|
+
const index = toolCallDelta.index;
|
|
493
|
+
if (toolCalls[index] == null) {
|
|
494
|
+
if (toolCallDelta.type !== "function") {
|
|
495
|
+
throw new InvalidResponseDataError({
|
|
496
|
+
data: toolCallDelta,
|
|
497
|
+
message: `Expected 'function' type.`
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
if (toolCallDelta.id == null) {
|
|
501
|
+
throw new InvalidResponseDataError({
|
|
502
|
+
data: toolCallDelta,
|
|
503
|
+
message: `Expected 'id' to be a string.`
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
if (((_g = toolCallDelta.function) == null ? void 0 : _g.name) == null) {
|
|
507
|
+
throw new InvalidResponseDataError({
|
|
508
|
+
data: toolCallDelta,
|
|
509
|
+
message: `Expected 'function.name' to be a string.`
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
toolCalls[index] = {
|
|
513
|
+
id: toolCallDelta.id,
|
|
514
|
+
type: "function",
|
|
515
|
+
function: {
|
|
516
|
+
name: toolCallDelta.function.name,
|
|
517
|
+
arguments: (_h = toolCallDelta.function.arguments) != null ? _h : ""
|
|
518
|
+
}
|
|
519
|
+
};
|
|
520
|
+
const toolCall2 = toolCalls[index];
|
|
521
|
+
if (((_i = toolCall2.function) == null ? void 0 : _i.name) != null && ((_j = toolCall2.function) == null ? void 0 : _j.arguments) != null) {
|
|
522
|
+
if (toolCall2.function.arguments.length > 0) {
|
|
523
|
+
controller.enqueue({
|
|
524
|
+
type: "tool-call-delta",
|
|
525
|
+
toolCallType: "function",
|
|
526
|
+
toolCallId: toolCall2.id,
|
|
527
|
+
toolName: toolCall2.function.name,
|
|
528
|
+
argsTextDelta: toolCall2.function.arguments
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
if (isParsableJson(toolCall2.function.arguments)) {
|
|
532
|
+
controller.enqueue({
|
|
533
|
+
type: "tool-call",
|
|
534
|
+
toolCallType: "function",
|
|
535
|
+
toolCallId: (_k = toolCall2.id) != null ? _k : generateId(),
|
|
536
|
+
toolName: toolCall2.function.name,
|
|
537
|
+
args: toolCall2.function.arguments
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
continue;
|
|
542
|
+
}
|
|
543
|
+
const toolCall = toolCalls[index];
|
|
544
|
+
if (((_l = toolCallDelta.function) == null ? void 0 : _l.arguments) != null) {
|
|
545
|
+
toolCall.function.arguments += (_n = (_m = toolCallDelta.function) == null ? void 0 : _m.arguments) != null ? _n : "";
|
|
546
|
+
}
|
|
547
|
+
controller.enqueue({
|
|
548
|
+
type: "tool-call-delta",
|
|
549
|
+
toolCallType: "function",
|
|
550
|
+
toolCallId: toolCall.id,
|
|
551
|
+
toolName: toolCall.function.name,
|
|
552
|
+
argsTextDelta: (_o = toolCallDelta.function.arguments) != null ? _o : ""
|
|
553
|
+
});
|
|
554
|
+
if (((_p = toolCall.function) == null ? void 0 : _p.name) != null && ((_q = toolCall.function) == null ? void 0 : _q.arguments) != null && isParsableJson(toolCall.function.arguments)) {
|
|
555
|
+
controller.enqueue({
|
|
556
|
+
type: "tool-call",
|
|
557
|
+
toolCallType: "function",
|
|
558
|
+
toolCallId: (_r = toolCall.id) != null ? _r : generateId(),
|
|
559
|
+
toolName: toolCall.function.name,
|
|
560
|
+
args: toolCall.function.arguments
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
},
|
|
566
|
+
flush(controller) {
|
|
567
|
+
var _a, _b;
|
|
568
|
+
controller.enqueue({
|
|
569
|
+
type: "finish",
|
|
570
|
+
finishReason,
|
|
571
|
+
logprobs,
|
|
572
|
+
usage: {
|
|
573
|
+
promptTokens: (_a = usage.promptTokens) != null ? _a : NaN,
|
|
574
|
+
completionTokens: (_b = usage.completionTokens) != null ? _b : NaN
|
|
575
|
+
}
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
})
|
|
579
|
+
),
|
|
580
|
+
rawCall: { rawPrompt, rawSettings },
|
|
581
|
+
rawResponse: { headers: responseHeaders },
|
|
582
|
+
warnings
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
};
|
|
586
|
+
var friendliAITokenUsageSchema = z2.object({
|
|
587
|
+
prompt_tokens: z2.number().nullish(),
|
|
588
|
+
completion_tokens: z2.number().nullish()
|
|
589
|
+
}).nullish();
|
|
590
|
+
var friendliAIChatResponseSchema = z2.object({
|
|
591
|
+
choices: z2.array(
|
|
592
|
+
z2.object({
|
|
593
|
+
message: z2.object({
|
|
594
|
+
role: z2.literal("assistant").nullish(),
|
|
595
|
+
content: z2.string().nullish(),
|
|
596
|
+
function_call: z2.object({
|
|
597
|
+
arguments: z2.string(),
|
|
598
|
+
name: z2.string()
|
|
599
|
+
}).nullish(),
|
|
600
|
+
tool_calls: z2.array(
|
|
601
|
+
z2.object({
|
|
602
|
+
id: z2.string().nullish(),
|
|
603
|
+
type: z2.literal("function"),
|
|
604
|
+
function: z2.object({
|
|
605
|
+
name: z2.string(),
|
|
606
|
+
arguments: z2.string()
|
|
607
|
+
})
|
|
608
|
+
})
|
|
609
|
+
).nullish()
|
|
610
|
+
}),
|
|
611
|
+
index: z2.number(),
|
|
612
|
+
logprobs: z2.object({
|
|
613
|
+
content: z2.array(
|
|
614
|
+
z2.object({
|
|
615
|
+
token: z2.string(),
|
|
616
|
+
logprob: z2.number(),
|
|
617
|
+
top_logprobs: z2.array(
|
|
618
|
+
z2.object({
|
|
619
|
+
token: z2.string(),
|
|
620
|
+
logprob: z2.number()
|
|
621
|
+
})
|
|
622
|
+
)
|
|
623
|
+
})
|
|
624
|
+
).nullable()
|
|
625
|
+
}).nullish(),
|
|
626
|
+
finish_reason: z2.string().nullish()
|
|
627
|
+
})
|
|
628
|
+
),
|
|
629
|
+
usage: friendliAITokenUsageSchema
|
|
630
|
+
});
|
|
631
|
+
var friendliaiChatChunkSchema = z2.union([
|
|
632
|
+
z2.object({
|
|
633
|
+
name: z2.string(),
|
|
634
|
+
state: z2.enum(["END", "START", "ERROR", "UPDATE"]),
|
|
635
|
+
status: z2.enum(["ENDED", "STARTED", "ERRORED", "UPDATING"]),
|
|
636
|
+
message: z2.null(),
|
|
637
|
+
parameters: z2.array(
|
|
638
|
+
z2.object({
|
|
639
|
+
name: z2.string(),
|
|
640
|
+
value: z2.string()
|
|
641
|
+
})
|
|
642
|
+
),
|
|
643
|
+
result: z2.string(),
|
|
644
|
+
error: z2.object({
|
|
645
|
+
type: z2.enum(["INVALID_PARAMETER", "UNKNOWN"]),
|
|
646
|
+
msg: z2.string()
|
|
647
|
+
}).nullable(),
|
|
648
|
+
timestamp: z2.number(),
|
|
649
|
+
usage: z2.null(),
|
|
650
|
+
tool_call_id: z2.string()
|
|
651
|
+
}),
|
|
652
|
+
z2.object({
|
|
653
|
+
choices: z2.array(
|
|
654
|
+
z2.object({
|
|
655
|
+
delta: z2.object({
|
|
656
|
+
role: z2.enum(["assistant"]).nullish(),
|
|
657
|
+
content: z2.string().nullish(),
|
|
658
|
+
function_call: z2.object({
|
|
659
|
+
name: z2.string().optional(),
|
|
660
|
+
arguments: z2.string().optional()
|
|
661
|
+
}).nullish(),
|
|
662
|
+
tool_calls: z2.array(
|
|
663
|
+
z2.object({
|
|
664
|
+
index: z2.number(),
|
|
665
|
+
id: z2.string().nullish(),
|
|
666
|
+
type: z2.literal("function").optional(),
|
|
667
|
+
function: z2.object({
|
|
668
|
+
name: z2.string().nullish(),
|
|
669
|
+
arguments: z2.string().nullish()
|
|
670
|
+
})
|
|
671
|
+
})
|
|
672
|
+
).nullish()
|
|
673
|
+
}).nullish(),
|
|
674
|
+
logprobs: z2.object({
|
|
675
|
+
content: z2.array(
|
|
676
|
+
z2.object({
|
|
677
|
+
token: z2.string(),
|
|
678
|
+
logprob: z2.number(),
|
|
679
|
+
top_logprobs: z2.array(
|
|
680
|
+
z2.object({
|
|
681
|
+
token: z2.string(),
|
|
682
|
+
logprob: z2.number()
|
|
683
|
+
})
|
|
684
|
+
)
|
|
685
|
+
})
|
|
686
|
+
).nullable()
|
|
687
|
+
}).nullish(),
|
|
688
|
+
finish_reason: z2.string().nullable().optional(),
|
|
689
|
+
index: z2.number()
|
|
690
|
+
})
|
|
691
|
+
),
|
|
692
|
+
usage: friendliAITokenUsageSchema
|
|
693
|
+
}),
|
|
694
|
+
friendliAIErrorDataSchema
|
|
695
|
+
]);
|
|
696
|
+
function prepareToolsAndToolChoice({
|
|
697
|
+
mode,
|
|
698
|
+
useLegacyFunctionCalling = false,
|
|
699
|
+
structuredOutputs = false,
|
|
700
|
+
tools: hostedTools
|
|
701
|
+
}) {
|
|
702
|
+
var _a;
|
|
703
|
+
const tools = ((_a = mode.tools) == null ? void 0 : _a.length) ? mode.tools : void 0;
|
|
704
|
+
if (tools == null && hostedTools != null) {
|
|
705
|
+
return { tools: void 0, tool_choice: void 0 };
|
|
706
|
+
}
|
|
707
|
+
const toolChoice = mode.toolChoice;
|
|
708
|
+
if (useLegacyFunctionCalling) {
|
|
709
|
+
const mappedFunctions = tools == null ? void 0 : tools.map((tool) => ({
|
|
710
|
+
name: tool.name,
|
|
711
|
+
description: tool.description,
|
|
712
|
+
parameters: tool.parameters
|
|
713
|
+
}));
|
|
714
|
+
if (toolChoice == null) {
|
|
715
|
+
return { functions: mappedFunctions, function_call: void 0 };
|
|
716
|
+
}
|
|
717
|
+
const type2 = toolChoice.type;
|
|
718
|
+
switch (type2) {
|
|
719
|
+
case "auto":
|
|
720
|
+
case "none":
|
|
721
|
+
case void 0:
|
|
722
|
+
return {
|
|
723
|
+
functions: mappedFunctions,
|
|
724
|
+
function_call: void 0
|
|
725
|
+
};
|
|
726
|
+
case "required":
|
|
727
|
+
throw new UnsupportedFunctionalityError2({
|
|
728
|
+
functionality: "useLegacyFunctionCalling and toolChoice: required"
|
|
729
|
+
});
|
|
730
|
+
default:
|
|
731
|
+
return {
|
|
732
|
+
functions: mappedFunctions,
|
|
733
|
+
function_call: { name: toolChoice.toolName }
|
|
734
|
+
};
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
const mappedTools = tools == null ? void 0 : tools.map((tool) => ({
|
|
738
|
+
type: "function",
|
|
739
|
+
function: {
|
|
740
|
+
name: tool.name,
|
|
741
|
+
description: tool.description,
|
|
742
|
+
parameters: tool.parameters,
|
|
743
|
+
strict: structuredOutputs === true ? true : void 0
|
|
744
|
+
}
|
|
745
|
+
}));
|
|
746
|
+
const mappedHostedTools = hostedTools == null ? void 0 : hostedTools.map((tool) => ({
|
|
747
|
+
type: tool.type
|
|
748
|
+
}));
|
|
749
|
+
if (toolChoice == null) {
|
|
750
|
+
return {
|
|
751
|
+
tools: [...mappedTools != null ? mappedTools : [], ...mappedHostedTools != null ? mappedHostedTools : []],
|
|
752
|
+
tool_choice: void 0
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
const type = toolChoice.type;
|
|
756
|
+
switch (type) {
|
|
757
|
+
case "auto":
|
|
758
|
+
case "none":
|
|
759
|
+
case "required":
|
|
760
|
+
return {
|
|
761
|
+
tools: [...mappedTools != null ? mappedTools : [], ...mappedHostedTools != null ? mappedHostedTools : []],
|
|
762
|
+
tool_choice: type
|
|
763
|
+
};
|
|
764
|
+
case "tool":
|
|
765
|
+
return {
|
|
766
|
+
tools: [...mappedTools != null ? mappedTools : [], ...mappedHostedTools != null ? mappedHostedTools : []],
|
|
767
|
+
tool_choice: {
|
|
768
|
+
type: "function",
|
|
769
|
+
function: {
|
|
770
|
+
name: toolChoice.toolName
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
};
|
|
774
|
+
default: {
|
|
775
|
+
const _exhaustiveCheck = type;
|
|
776
|
+
throw new Error(`Unsupported tool choice type: ${_exhaustiveCheck}`);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
// src/friendliai-completion-language-model.ts
|
|
782
|
+
import {
|
|
783
|
+
UnsupportedFunctionalityError as UnsupportedFunctionalityError4
|
|
784
|
+
} from "@ai-sdk/provider";
|
|
785
|
+
import {
|
|
786
|
+
combineHeaders as combineHeaders2,
|
|
787
|
+
createEventSourceResponseHandler as createEventSourceResponseHandler2,
|
|
788
|
+
createJsonResponseHandler as createJsonResponseHandler2,
|
|
789
|
+
postJsonToApi as postJsonToApi2
|
|
790
|
+
} from "@ai-sdk/provider-utils";
|
|
791
|
+
import { z as z3 } from "zod";
|
|
792
|
+
|
|
793
|
+
// src/convert-to-friendliai-completion-prompt.ts
|
|
794
|
+
import {
|
|
795
|
+
InvalidPromptError,
|
|
796
|
+
UnsupportedFunctionalityError as UnsupportedFunctionalityError3
|
|
797
|
+
} from "@ai-sdk/provider";
|
|
798
|
+
function convertToFriendliAICompletionPrompt({
|
|
799
|
+
prompt,
|
|
800
|
+
inputFormat,
|
|
801
|
+
user = "user",
|
|
802
|
+
assistant = "assistant"
|
|
803
|
+
}) {
|
|
804
|
+
if (inputFormat === "prompt" && prompt.length === 1 && prompt[0].role === "user" && prompt[0].content.length === 1 && prompt[0].content[0].type === "text") {
|
|
805
|
+
return { prompt: prompt[0].content[0].text };
|
|
806
|
+
}
|
|
807
|
+
let text = "";
|
|
808
|
+
if (prompt[0].role === "system") {
|
|
809
|
+
text += `${prompt[0].content}
|
|
810
|
+
|
|
811
|
+
`;
|
|
812
|
+
prompt = prompt.slice(1);
|
|
813
|
+
}
|
|
814
|
+
for (const { role, content } of prompt) {
|
|
815
|
+
switch (role) {
|
|
816
|
+
case "system": {
|
|
817
|
+
throw new InvalidPromptError({
|
|
818
|
+
message: "Unexpected system message in prompt: ${content}",
|
|
819
|
+
prompt
|
|
820
|
+
});
|
|
821
|
+
}
|
|
822
|
+
case "user": {
|
|
823
|
+
const userMessage = content.map((part) => {
|
|
824
|
+
switch (part.type) {
|
|
825
|
+
case "text": {
|
|
826
|
+
return part.text;
|
|
827
|
+
}
|
|
828
|
+
case "image": {
|
|
829
|
+
throw new UnsupportedFunctionalityError3({
|
|
830
|
+
functionality: "images"
|
|
831
|
+
});
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
}).join("");
|
|
835
|
+
text += `${user}:
|
|
836
|
+
${userMessage}
|
|
837
|
+
|
|
838
|
+
`;
|
|
839
|
+
break;
|
|
840
|
+
}
|
|
841
|
+
case "assistant": {
|
|
842
|
+
const assistantMessage = content.map((part) => {
|
|
843
|
+
switch (part.type) {
|
|
844
|
+
case "text": {
|
|
845
|
+
return part.text;
|
|
846
|
+
}
|
|
847
|
+
case "tool-call": {
|
|
848
|
+
throw new UnsupportedFunctionalityError3({
|
|
849
|
+
functionality: "tool-call messages"
|
|
850
|
+
});
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
}).join("");
|
|
854
|
+
text += `${assistant}:
|
|
855
|
+
${assistantMessage}
|
|
856
|
+
|
|
857
|
+
`;
|
|
858
|
+
break;
|
|
859
|
+
}
|
|
860
|
+
case "tool": {
|
|
861
|
+
throw new UnsupportedFunctionalityError3({
|
|
862
|
+
functionality: "tool messages"
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
default: {
|
|
866
|
+
const _exhaustiveCheck = role;
|
|
867
|
+
throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
text += `${assistant}:
|
|
872
|
+
`;
|
|
873
|
+
return {
|
|
874
|
+
prompt: text,
|
|
875
|
+
stopSequences: [`
|
|
876
|
+
${user}:`]
|
|
877
|
+
};
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
// src/map-friendliai-completion-logprobs.ts
|
|
881
|
+
function mapFriendliAICompletionLogProbs(logprobs) {
|
|
882
|
+
return logprobs == null ? void 0 : logprobs.tokens.map((token, index) => ({
|
|
883
|
+
token,
|
|
884
|
+
logprob: logprobs.token_logprobs[index],
|
|
885
|
+
topLogprobs: logprobs.top_logprobs ? Object.entries(logprobs.top_logprobs[index]).map(
|
|
886
|
+
([token2, logprob]) => ({
|
|
887
|
+
token: token2,
|
|
888
|
+
logprob
|
|
889
|
+
})
|
|
890
|
+
) : []
|
|
891
|
+
}));
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
// src/friendliai-completion-language-model.ts
|
|
895
|
+
var FriendliAICompletionLanguageModel = class {
|
|
896
|
+
constructor(modelId, settings, config) {
|
|
897
|
+
this.specificationVersion = "v1";
|
|
898
|
+
this.defaultObjectGenerationMode = void 0;
|
|
899
|
+
this.modelId = modelId;
|
|
900
|
+
this.settings = settings;
|
|
901
|
+
this.config = config;
|
|
902
|
+
}
|
|
903
|
+
get provider() {
|
|
904
|
+
return this.config.provider;
|
|
905
|
+
}
|
|
906
|
+
getArgs({
|
|
907
|
+
mode,
|
|
908
|
+
inputFormat,
|
|
909
|
+
prompt,
|
|
910
|
+
maxTokens,
|
|
911
|
+
temperature,
|
|
912
|
+
topP,
|
|
913
|
+
topK,
|
|
914
|
+
frequencyPenalty,
|
|
915
|
+
presencePenalty,
|
|
916
|
+
stopSequences: userStopSequences,
|
|
917
|
+
responseFormat,
|
|
918
|
+
seed
|
|
919
|
+
}) {
|
|
920
|
+
var _a;
|
|
921
|
+
const type = mode.type;
|
|
922
|
+
const warnings = [];
|
|
923
|
+
if (topK != null) {
|
|
924
|
+
warnings.push({
|
|
925
|
+
type: "unsupported-setting",
|
|
926
|
+
setting: "topK"
|
|
927
|
+
});
|
|
928
|
+
}
|
|
929
|
+
if (responseFormat != null && responseFormat.type !== "text") {
|
|
930
|
+
warnings.push({
|
|
931
|
+
type: "unsupported-setting",
|
|
932
|
+
setting: "responseFormat",
|
|
933
|
+
details: "JSON response format is not supported."
|
|
934
|
+
});
|
|
935
|
+
}
|
|
936
|
+
const { prompt: completionPrompt, stopSequences } = convertToFriendliAICompletionPrompt({ prompt, inputFormat });
|
|
937
|
+
const stop = [...stopSequences != null ? stopSequences : [], ...userStopSequences != null ? userStopSequences : []];
|
|
938
|
+
const baseArgs = {
|
|
939
|
+
// model id:
|
|
940
|
+
model: this.modelId,
|
|
941
|
+
// model specific settings:
|
|
942
|
+
echo: this.settings.echo,
|
|
943
|
+
logit_bias: this.settings.logitBias,
|
|
944
|
+
logprobs: typeof this.settings.logprobs === "number" ? this.settings.logprobs : typeof this.settings.logprobs === "boolean" ? this.settings.logprobs ? 0 : void 0 : void 0,
|
|
945
|
+
suffix: this.settings.suffix,
|
|
946
|
+
user: this.settings.user,
|
|
947
|
+
// standardized settings:
|
|
948
|
+
max_tokens: maxTokens,
|
|
949
|
+
temperature,
|
|
950
|
+
top_p: topP,
|
|
951
|
+
frequency_penalty: frequencyPenalty,
|
|
952
|
+
presence_penalty: presencePenalty,
|
|
953
|
+
seed,
|
|
954
|
+
// prompt:
|
|
955
|
+
prompt: completionPrompt,
|
|
956
|
+
// stop sequences:
|
|
957
|
+
stop: stop.length > 0 ? stop : void 0
|
|
958
|
+
};
|
|
959
|
+
switch (type) {
|
|
960
|
+
case "regular": {
|
|
961
|
+
if ((_a = mode.tools) == null ? void 0 : _a.length) {
|
|
962
|
+
throw new UnsupportedFunctionalityError4({
|
|
963
|
+
functionality: "tools"
|
|
964
|
+
});
|
|
965
|
+
}
|
|
966
|
+
if (mode.toolChoice) {
|
|
967
|
+
throw new UnsupportedFunctionalityError4({
|
|
968
|
+
functionality: "toolChoice"
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
return { args: baseArgs, warnings };
|
|
972
|
+
}
|
|
973
|
+
case "object-json": {
|
|
974
|
+
throw new UnsupportedFunctionalityError4({
|
|
975
|
+
functionality: "object-json mode"
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
case "object-tool": {
|
|
979
|
+
throw new UnsupportedFunctionalityError4({
|
|
980
|
+
functionality: "object-tool mode"
|
|
981
|
+
});
|
|
982
|
+
}
|
|
983
|
+
default: {
|
|
984
|
+
const _exhaustiveCheck = type;
|
|
985
|
+
throw new Error(`Unsupported type: ${_exhaustiveCheck}`);
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
async doGenerate(options) {
|
|
990
|
+
const { args, warnings } = this.getArgs(options);
|
|
991
|
+
const { responseHeaders, value: response } = await postJsonToApi2({
|
|
992
|
+
url: this.config.url({
|
|
993
|
+
path: "/completions",
|
|
994
|
+
modelId: this.modelId
|
|
995
|
+
}),
|
|
996
|
+
headers: combineHeaders2(this.config.headers(), options.headers),
|
|
997
|
+
body: args,
|
|
998
|
+
failedResponseHandler: friendliaiFailedResponseHandler,
|
|
999
|
+
successfulResponseHandler: createJsonResponseHandler2(
|
|
1000
|
+
friendliAICompletionResponseSchema
|
|
1001
|
+
),
|
|
1002
|
+
abortSignal: options.abortSignal,
|
|
1003
|
+
fetch: this.config.fetch
|
|
1004
|
+
});
|
|
1005
|
+
const { prompt: rawPrompt, ...rawSettings } = args;
|
|
1006
|
+
const choice = response.choices[0];
|
|
1007
|
+
return {
|
|
1008
|
+
text: choice.text,
|
|
1009
|
+
usage: {
|
|
1010
|
+
promptTokens: response.usage.prompt_tokens,
|
|
1011
|
+
completionTokens: response.usage.completion_tokens
|
|
1012
|
+
},
|
|
1013
|
+
finishReason: mapFriendliAIFinishReason(choice.finish_reason),
|
|
1014
|
+
logprobs: mapFriendliAICompletionLogProbs(choice.logprobs),
|
|
1015
|
+
rawCall: { rawPrompt, rawSettings },
|
|
1016
|
+
rawResponse: { headers: responseHeaders },
|
|
1017
|
+
warnings
|
|
1018
|
+
};
|
|
1019
|
+
}
|
|
1020
|
+
async doStream(options) {
|
|
1021
|
+
const { args, warnings } = this.getArgs(options);
|
|
1022
|
+
const { responseHeaders, value: response } = await postJsonToApi2({
|
|
1023
|
+
url: this.config.url({
|
|
1024
|
+
path: "/completions",
|
|
1025
|
+
modelId: this.modelId
|
|
1026
|
+
}),
|
|
1027
|
+
headers: combineHeaders2(this.config.headers(), options.headers),
|
|
1028
|
+
body: {
|
|
1029
|
+
...args,
|
|
1030
|
+
stream: true,
|
|
1031
|
+
// only include stream_options when in strict compatibility mode:
|
|
1032
|
+
stream_options: this.config.compatibility === "strict" ? { include_usage: true } : void 0
|
|
1033
|
+
},
|
|
1034
|
+
failedResponseHandler: friendliaiFailedResponseHandler,
|
|
1035
|
+
successfulResponseHandler: createEventSourceResponseHandler2(
|
|
1036
|
+
friendliaiCompletionChunkSchema
|
|
1037
|
+
),
|
|
1038
|
+
abortSignal: options.abortSignal,
|
|
1039
|
+
fetch: this.config.fetch
|
|
1040
|
+
});
|
|
1041
|
+
const { prompt: rawPrompt, ...rawSettings } = args;
|
|
1042
|
+
let finishReason = "unknown";
|
|
1043
|
+
let usage = {
|
|
1044
|
+
promptTokens: Number.NaN,
|
|
1045
|
+
completionTokens: Number.NaN
|
|
1046
|
+
};
|
|
1047
|
+
let logprobs;
|
|
1048
|
+
return {
|
|
1049
|
+
stream: response.pipeThrough(
|
|
1050
|
+
new TransformStream({
|
|
1051
|
+
transform(chunk, controller) {
|
|
1052
|
+
if (!chunk.success) {
|
|
1053
|
+
finishReason = "error";
|
|
1054
|
+
controller.enqueue({ type: "error", error: chunk.error });
|
|
1055
|
+
return;
|
|
1056
|
+
}
|
|
1057
|
+
const value = chunk.value;
|
|
1058
|
+
if ("error" in value) {
|
|
1059
|
+
finishReason = "error";
|
|
1060
|
+
controller.enqueue({ type: "error", error: value.error });
|
|
1061
|
+
return;
|
|
1062
|
+
}
|
|
1063
|
+
if (value.usage != null) {
|
|
1064
|
+
usage = {
|
|
1065
|
+
promptTokens: value.usage.prompt_tokens,
|
|
1066
|
+
completionTokens: value.usage.completion_tokens
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
const choice = value.choices[0];
|
|
1070
|
+
if ((choice == null ? void 0 : choice.finish_reason) != null) {
|
|
1071
|
+
finishReason = mapFriendliAIFinishReason(choice.finish_reason);
|
|
1072
|
+
}
|
|
1073
|
+
if ((choice == null ? void 0 : choice.text) != null) {
|
|
1074
|
+
controller.enqueue({
|
|
1075
|
+
type: "text-delta",
|
|
1076
|
+
textDelta: choice.text
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
1079
|
+
const mappedLogprobs = mapFriendliAICompletionLogProbs(
|
|
1080
|
+
choice == null ? void 0 : choice.logprobs
|
|
1081
|
+
);
|
|
1082
|
+
if (mappedLogprobs == null ? void 0 : mappedLogprobs.length) {
|
|
1083
|
+
if (logprobs === void 0) logprobs = [];
|
|
1084
|
+
logprobs.push(...mappedLogprobs);
|
|
1085
|
+
}
|
|
1086
|
+
},
|
|
1087
|
+
flush(controller) {
|
|
1088
|
+
controller.enqueue({
|
|
1089
|
+
type: "finish",
|
|
1090
|
+
finishReason,
|
|
1091
|
+
logprobs,
|
|
1092
|
+
usage
|
|
1093
|
+
});
|
|
1094
|
+
}
|
|
1095
|
+
})
|
|
1096
|
+
),
|
|
1097
|
+
rawCall: { rawPrompt, rawSettings },
|
|
1098
|
+
rawResponse: { headers: responseHeaders },
|
|
1099
|
+
warnings
|
|
1100
|
+
};
|
|
1101
|
+
}
|
|
1102
|
+
};
|
|
1103
|
+
var friendliAICompletionResponseSchema = z3.object({
|
|
1104
|
+
choices: z3.array(
|
|
1105
|
+
z3.object({
|
|
1106
|
+
text: z3.string(),
|
|
1107
|
+
finish_reason: z3.string(),
|
|
1108
|
+
logprobs: z3.object({
|
|
1109
|
+
tokens: z3.array(z3.string()),
|
|
1110
|
+
token_logprobs: z3.array(z3.number()),
|
|
1111
|
+
top_logprobs: z3.array(z3.record(z3.string(), z3.number())).nullable()
|
|
1112
|
+
}).nullable().optional()
|
|
1113
|
+
})
|
|
1114
|
+
),
|
|
1115
|
+
usage: z3.object({
|
|
1116
|
+
prompt_tokens: z3.number(),
|
|
1117
|
+
completion_tokens: z3.number()
|
|
1118
|
+
})
|
|
1119
|
+
});
|
|
1120
|
+
var friendliaiCompletionChunkSchema = z3.union([
|
|
1121
|
+
z3.object({
|
|
1122
|
+
choices: z3.array(
|
|
1123
|
+
z3.object({
|
|
1124
|
+
text: z3.string(),
|
|
1125
|
+
finish_reason: z3.string().nullish(),
|
|
1126
|
+
index: z3.number(),
|
|
1127
|
+
logprobs: z3.object({
|
|
1128
|
+
tokens: z3.array(z3.string()),
|
|
1129
|
+
token_logprobs: z3.array(z3.number()),
|
|
1130
|
+
top_logprobs: z3.array(z3.record(z3.string(), z3.number())).nullable()
|
|
1131
|
+
}).nullable().optional()
|
|
1132
|
+
})
|
|
1133
|
+
),
|
|
1134
|
+
usage: z3.object({
|
|
1135
|
+
prompt_tokens: z3.number(),
|
|
1136
|
+
completion_tokens: z3.number()
|
|
1137
|
+
}).optional().nullable()
|
|
1138
|
+
}),
|
|
1139
|
+
friendliAIErrorDataSchema
|
|
1140
|
+
]);
|
|
1141
|
+
|
|
1142
|
+
// src/friendliai-facade.ts
|
|
1143
|
+
var FriendliAI = class {
|
|
1144
|
+
/**
|
|
1145
|
+
* Creates a new FriendliAI provider instance.
|
|
1146
|
+
*/
|
|
1147
|
+
constructor(options = {}) {
|
|
1148
|
+
var _a, _b;
|
|
1149
|
+
this.baseURL = (_b = withoutTrailingSlash((_a = options.baseURL) != null ? _a : options.baseUrl)) != null ? _b : "https://inference.friendli.ai/tools/v1";
|
|
1150
|
+
this.apiKey = options.apiKey;
|
|
1151
|
+
this.teamId = options.teamId;
|
|
1152
|
+
this.headers = options.headers;
|
|
1153
|
+
}
|
|
1154
|
+
get baseConfig() {
|
|
1155
|
+
return {
|
|
1156
|
+
teamId: this.teamId,
|
|
1157
|
+
baseURL: this.baseURL,
|
|
1158
|
+
headers: () => ({
|
|
1159
|
+
Authorization: `Bearer ${loadApiKey({
|
|
1160
|
+
apiKey: this.apiKey,
|
|
1161
|
+
environmentVariableName: "FRIENDLI_API_KEY",
|
|
1162
|
+
description: "FriendliAI"
|
|
1163
|
+
})}`,
|
|
1164
|
+
"X-Friendli-Team": this.teamId,
|
|
1165
|
+
...this.headers
|
|
1166
|
+
})
|
|
1167
|
+
};
|
|
1168
|
+
}
|
|
1169
|
+
chat(modelId, settings = {}) {
|
|
1170
|
+
return new FriendliAIChatLanguageModel(modelId, settings, {
|
|
1171
|
+
provider: "friendliai.chat",
|
|
1172
|
+
...this.baseConfig,
|
|
1173
|
+
compatibility: "strict",
|
|
1174
|
+
url: ({ path }) => `${this.baseURL}${path}`
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
completion(modelId, settings = {}) {
|
|
1178
|
+
return new FriendliAICompletionLanguageModel(modelId, settings, {
|
|
1179
|
+
provider: "friendliai.completion",
|
|
1180
|
+
...this.baseConfig,
|
|
1181
|
+
compatibility: "strict",
|
|
1182
|
+
url: ({ path }) => `${this.baseURL}${path}`
|
|
1183
|
+
});
|
|
1184
|
+
}
|
|
1185
|
+
};
|
|
1186
|
+
|
|
1187
|
+
// src/friendliai-provider.ts
|
|
1188
|
+
import {
|
|
1189
|
+
NoSuchModelError
|
|
1190
|
+
} from "@ai-sdk/provider";
|
|
1191
|
+
import {
|
|
1192
|
+
loadApiKey as loadApiKey2,
|
|
1193
|
+
withoutTrailingSlash as withoutTrailingSlash2
|
|
1194
|
+
} from "@ai-sdk/provider-utils";
|
|
1195
|
+
function createFriendliAI(options = {}) {
|
|
1196
|
+
var _a, _b;
|
|
1197
|
+
const baseURL = (_b = withoutTrailingSlash2((_a = options.baseURL) != null ? _a : options.baseUrl)) != null ? _b : "https://inference.friendli.ai/tools/v1";
|
|
1198
|
+
const compatibility = "compatible";
|
|
1199
|
+
const getHeaders = () => ({
|
|
1200
|
+
Authorization: `Bearer ${loadApiKey2({
|
|
1201
|
+
apiKey: options.apiKey,
|
|
1202
|
+
environmentVariableName: "FRIENDLI_API_KEY",
|
|
1203
|
+
description: "FriendliAI API key"
|
|
1204
|
+
})}`,
|
|
1205
|
+
"X-Friendli-Team": options.teamId,
|
|
1206
|
+
...options.headers
|
|
1207
|
+
});
|
|
1208
|
+
const createChatModel = (modelId, settings = {}) => new FriendliAIChatLanguageModel(modelId, settings, {
|
|
1209
|
+
provider: "friendliai.chat",
|
|
1210
|
+
url: ({ path }) => `${baseURL}${path}`,
|
|
1211
|
+
headers: getHeaders,
|
|
1212
|
+
compatibility,
|
|
1213
|
+
fetch: options.fetch
|
|
1214
|
+
});
|
|
1215
|
+
const createCompletionModel = (modelId, settings = {}) => new FriendliAICompletionLanguageModel(modelId, settings, {
|
|
1216
|
+
provider: "friendliai.completion",
|
|
1217
|
+
url: ({ path }) => `${baseURL}${path}`,
|
|
1218
|
+
headers: getHeaders,
|
|
1219
|
+
compatibility,
|
|
1220
|
+
fetch: options.fetch
|
|
1221
|
+
});
|
|
1222
|
+
const createLanguageModel = (modelId, settings) => {
|
|
1223
|
+
if (new.target) {
|
|
1224
|
+
throw new Error(
|
|
1225
|
+
"The FriendliAI model function cannot be called with the new keyword."
|
|
1226
|
+
);
|
|
1227
|
+
}
|
|
1228
|
+
if (modelId === "gpt-3.5-turbo") {
|
|
1229
|
+
return createCompletionModel(
|
|
1230
|
+
modelId,
|
|
1231
|
+
settings
|
|
1232
|
+
);
|
|
1233
|
+
}
|
|
1234
|
+
return createChatModel(modelId, settings);
|
|
1235
|
+
};
|
|
1236
|
+
const provider = function(modelId, settings) {
|
|
1237
|
+
return createLanguageModel(modelId, settings);
|
|
1238
|
+
};
|
|
1239
|
+
provider.languageModel = createLanguageModel;
|
|
1240
|
+
provider.chat = createChatModel;
|
|
1241
|
+
provider.completion = createCompletionModel;
|
|
1242
|
+
provider.textEmbeddingModel = (modelId) => {
|
|
1243
|
+
throw new NoSuchModelError({ modelId, modelType: "textEmbeddingModel" });
|
|
1244
|
+
};
|
|
1245
|
+
return provider;
|
|
1246
|
+
}
|
|
1247
|
+
var friendliai = createFriendliAI({
|
|
1248
|
+
// compatibility: "compatible", // strict for FriendliAI API
|
|
1249
|
+
});
|
|
1250
|
+
export {
|
|
1251
|
+
FriendliAI,
|
|
1252
|
+
createFriendliAI,
|
|
1253
|
+
friendliai
|
|
1254
|
+
};
|
|
1255
|
+
//# sourceMappingURL=index.mjs.map
|