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