@friendliai/ai-provider 0.3.2 → 1.0.0-beta.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.mjs CHANGED
@@ -1,34 +1,16 @@
1
1
  // src/friendli-provider.ts
2
+ import { OpenAICompatibleCompletionLanguageModel } from "@ai-sdk/openai-compatible";
2
3
  import {
3
4
  NoSuchModelError
4
5
  } from "@ai-sdk/provider";
5
6
  import { loadApiKey as loadApiKey2, withoutTrailingSlash } from "@ai-sdk/provider-utils";
6
- import { OpenAICompatibleCompletionLanguageModel } from "@ai-sdk/openai-compatible";
7
-
8
- // src/friendli-settings.ts
9
- var FriendliAIServerlessModelIds = [
10
- "LGAI-EXAONE/EXAONE-4.0.1-32B",
11
- "skt/A.X-4.0",
12
- "skt/A.X-3.1",
13
- "naver-hyperclovax/HyperCLOVAX-SEED-Think-14B",
14
- "deepseek-ai/DeepSeek-R1-0528",
15
- "meta-llama/Llama-4-Maverick-17B-128E-Instruct",
16
- "meta-llama/Llama-4-Scout-17B-16E-Instruct",
17
- "meta-llama/Llama-3.3-70B-Instruct",
18
- "meta-llama-3.3-70b-instruct",
19
- "meta-llama/Llama-3.1-8B-Instruct",
20
- "meta-llama-3.1-8b-instruct",
21
- "Qwen/Qwen3-235B-A22B-Thinking-2507",
22
- "Qwen/Qwen3-235B-A22B-Instruct-2507",
23
- "Qwen/Qwen3-30B-A3B",
24
- "Qwen/Qwen3-32B",
25
- "google/gemma-3-27b-it",
26
- "mistralai/Mistral-Small-3.1-24B-Instruct-2503",
27
- "mistralai/Devstral-Small-2505",
28
- "mistralai/Magistral-Small-2506"
29
- ];
30
7
 
31
8
  // src/friendli-chat-language-model.ts
9
+ import {
10
+ convertToOpenAICompatibleChatMessages,
11
+ getResponseMetadata,
12
+ mapOpenAICompatibleFinishReason
13
+ } from "@ai-sdk/openai-compatible/internal";
32
14
  import {
33
15
  InvalidResponseDataError
34
16
  } from "@ai-sdk/provider";
@@ -42,16 +24,11 @@ import {
42
24
  parseProviderOptions,
43
25
  postJsonToApi
44
26
  } from "@ai-sdk/provider-utils";
45
- import {
46
- convertToOpenAICompatibleChatMessages,
47
- getResponseMetadata,
48
- mapOpenAICompatibleFinishReason
49
- } from "@ai-sdk/openai-compatible/internal";
50
- import { z as z2 } from "zod";
27
+ import { z as z2 } from "zod/v4";
51
28
 
52
29
  // src/friendli-error.ts
53
- import { z } from "zod";
54
30
  import { createJsonErrorResponseHandler } from "@ai-sdk/provider-utils";
31
+ import { z } from "zod/v4";
55
32
  var friendliaiErrorSchema = z.object({
56
33
  message: z.string(),
57
34
  error: z.record(z.string(), z.any())
@@ -78,7 +55,7 @@ function prepareTools({
78
55
  }
79
56
  const openaiCompatTools = [];
80
57
  for (const tool of tools) {
81
- if (tool.type === "provider-defined") {
58
+ if (tool.type === "provider") {
82
59
  openaiCompatTools.push({
83
60
  // NOTE: It would be better to use tool.name, but since ":" is replaced with "_", the following code is used instead
84
61
  type: (_a = tool.id.split(".")[1]) != null ? _a : "unknown"
@@ -125,7 +102,7 @@ function prepareTools({
125
102
  var FriendliAIChatLanguageModel = class {
126
103
  // type inferred via constructor
127
104
  constructor(modelId, config) {
128
- this.specificationVersion = "v2";
105
+ this.specificationVersion = "v3";
129
106
  var _a;
130
107
  this.modelId = modelId;
131
108
  this.config = config;
@@ -160,7 +137,7 @@ var FriendliAIChatLanguageModel = class {
160
137
  var _a;
161
138
  const warnings = [];
162
139
  if (topK != null) {
163
- warnings.push({ type: "unsupported-setting", setting: "topK" });
140
+ warnings.push({ type: "unsupported", feature: "topK" });
164
141
  }
165
142
  const friendliOptions = await parseProviderOptions({
166
143
  provider: "friendli",
@@ -169,8 +146,8 @@ var FriendliAIChatLanguageModel = class {
169
146
  });
170
147
  if ((responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && !this.supportsStructuredOutputs) {
171
148
  warnings.push({
172
- type: "unsupported-setting",
173
- setting: "responseFormat",
149
+ type: "unsupported",
150
+ feature: "responseFormat",
174
151
  details: "JSON response format schema is only supported with structuredOutputs"
175
152
  });
176
153
  }
@@ -222,7 +199,7 @@ var FriendliAIChatLanguageModel = class {
222
199
  };
223
200
  }
224
201
  async doGenerate(options) {
225
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
202
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
226
203
  const { args, warnings } = await this.getArgs({ ...options, stream: false });
227
204
  const body = JSON.stringify(args);
228
205
  const {
@@ -268,11 +245,17 @@ var FriendliAIChatLanguageModel = class {
268
245
  content,
269
246
  finishReason: mapOpenAICompatibleFinishReason(choice.finish_reason),
270
247
  usage: {
271
- inputTokens: (_c = (_b = responseBody.usage) == null ? void 0 : _b.prompt_tokens) != null ? _c : void 0,
272
- outputTokens: (_e = (_d = responseBody.usage) == null ? void 0 : _d.completion_tokens) != null ? _e : void 0,
273
- totalTokens: (_g = (_f = responseBody.usage) == null ? void 0 : _f.total_tokens) != null ? _g : void 0,
274
- reasoningTokens: (_j = (_i = (_h = responseBody.usage) == null ? void 0 : _h.completion_tokens_details) == null ? void 0 : _i.reasoning_tokens) != null ? _j : void 0,
275
- cachedInputTokens: (_m = (_l = (_k = responseBody.usage) == null ? void 0 : _k.prompt_tokens_details) == null ? void 0 : _l.cached_tokens) != null ? _m : void 0
248
+ inputTokens: {
249
+ total: (_c = (_b = responseBody.usage) == null ? void 0 : _b.prompt_tokens) != null ? _c : void 0,
250
+ noCache: void 0,
251
+ cacheRead: (_f = (_e = (_d = responseBody.usage) == null ? void 0 : _d.prompt_tokens_details) == null ? void 0 : _e.cached_tokens) != null ? _f : void 0,
252
+ cacheWrite: void 0
253
+ },
254
+ outputTokens: {
255
+ total: (_h = (_g = responseBody.usage) == null ? void 0 : _g.completion_tokens) != null ? _h : void 0,
256
+ text: void 0,
257
+ reasoning: (_k = (_j = (_i = responseBody.usage) == null ? void 0 : _i.completion_tokens_details) == null ? void 0 : _j.reasoning_tokens) != null ? _k : void 0
258
+ }
276
259
  },
277
260
  // providerMetadata,
278
261
  request: { body },
@@ -331,7 +314,7 @@ var FriendliAIChatLanguageModel = class {
331
314
  },
332
315
  // TODO we lost type safety on Chunk, most likely due to the error schema. MUST FIX
333
316
  transform(chunk, controller) {
334
- var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
317
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
335
318
  if (!chunk.success) {
336
319
  finishReason = "error";
337
320
  controller.enqueue({ type: "error", error: chunk.error });
@@ -339,6 +322,49 @@ var FriendliAIChatLanguageModel = class {
339
322
  }
340
323
  const value = chunk.value;
341
324
  metadataExtractor == null ? void 0 : metadataExtractor.processChunk(chunk.rawValue);
325
+ if ("status" in value) {
326
+ const toolCallId = (_a2 = value.tool_call_id) != null ? _a2 : generateId();
327
+ switch (value.status) {
328
+ case "STARTED":
329
+ controller.enqueue({
330
+ type: "tool-call",
331
+ toolCallId,
332
+ toolName: value.name,
333
+ input: JSON.stringify(
334
+ Object.fromEntries(value.parameters.map((p) => [p.name, p.value]))
335
+ ),
336
+ providerExecuted: true
337
+ });
338
+ break;
339
+ case "UPDATING":
340
+ break;
341
+ case "ENDED":
342
+ controller.enqueue({
343
+ type: "tool-result",
344
+ toolCallId,
345
+ toolName: value.name,
346
+ result: (_b = value.result) != null ? _b : ""
347
+ });
348
+ break;
349
+ case "ERRORED":
350
+ finishReason = "error";
351
+ controller.enqueue({
352
+ type: "tool-result",
353
+ toolCallId,
354
+ toolName: value.name,
355
+ result: (_d = (_c = value.error) == null ? void 0 : _c.msg) != null ? _d : "Unknown error",
356
+ isError: true
357
+ });
358
+ break;
359
+ default:
360
+ finishReason = "error";
361
+ controller.enqueue({
362
+ type: "error",
363
+ error: new Error(`Unsupported tool call status: ${value.status}`)
364
+ });
365
+ }
366
+ return;
367
+ }
342
368
  if ("error" in value) {
343
369
  finishReason = "error";
344
370
  controller.enqueue({ type: "error", error: value.error.message });
@@ -413,7 +439,7 @@ var FriendliAIChatLanguageModel = class {
413
439
  message: `Expected 'id' to be a string.`
414
440
  });
415
441
  }
416
- if (((_a2 = toolCallDelta.function) == null ? void 0 : _a2.name) == null) {
442
+ if (((_e = toolCallDelta.function) == null ? void 0 : _e.name) == null) {
417
443
  throw new InvalidResponseDataError({
418
444
  data: toolCallDelta,
419
445
  message: `Expected 'function.name' to be a string.`
@@ -424,12 +450,12 @@ var FriendliAIChatLanguageModel = class {
424
450
  type: "function",
425
451
  function: {
426
452
  name: toolCallDelta.function.name,
427
- arguments: (_b = toolCallDelta.function.arguments) != null ? _b : ""
453
+ arguments: (_f = toolCallDelta.function.arguments) != null ? _f : ""
428
454
  },
429
455
  hasFinished: false
430
456
  };
431
457
  const toolCall2 = toolCalls[index];
432
- if (((_c = toolCall2.function) == null ? void 0 : _c.name) != null && ((_d = toolCall2.function) == null ? void 0 : _d.arguments) != null) {
458
+ if (((_g = toolCall2.function) == null ? void 0 : _g.name) != null && ((_h = toolCall2.function) == null ? void 0 : _h.arguments) != null) {
433
459
  if (toolCall2.function.arguments.length > 0) {
434
460
  controller.enqueue({
435
461
  type: "tool-input-delta",
@@ -440,7 +466,7 @@ var FriendliAIChatLanguageModel = class {
440
466
  if (isParsableJson(toolCall2.function.arguments)) {
441
467
  controller.enqueue({
442
468
  type: "tool-call",
443
- toolCallId: (_e = toolCall2.id) != null ? _e : generateId(),
469
+ toolCallId: (_i = toolCall2.id) != null ? _i : generateId(),
444
470
  toolName: toolCall2.function.name,
445
471
  input: toolCall2.function.arguments
446
472
  });
@@ -453,18 +479,18 @@ var FriendliAIChatLanguageModel = class {
453
479
  if (toolCall.hasFinished) {
454
480
  continue;
455
481
  }
456
- if (((_f = toolCallDelta.function) == null ? void 0 : _f.arguments) != null) {
457
- toolCall.function.arguments += (_h = (_g = toolCallDelta.function) == null ? void 0 : _g.arguments) != null ? _h : "";
482
+ if (((_j = toolCallDelta.function) == null ? void 0 : _j.arguments) != null) {
483
+ toolCall.function.arguments += (_l = (_k = toolCallDelta.function) == null ? void 0 : _k.arguments) != null ? _l : "";
458
484
  }
459
485
  controller.enqueue({
460
486
  type: "tool-input-delta",
461
487
  id: toolCall.id,
462
- delta: (_i = toolCallDelta.function.arguments) != null ? _i : ""
488
+ delta: (_m = toolCallDelta.function.arguments) != null ? _m : ""
463
489
  });
464
- if (((_j = toolCall.function) == null ? void 0 : _j.name) != null && ((_k = toolCall.function) == null ? void 0 : _k.arguments) != null && isParsableJson(toolCall.function.arguments)) {
490
+ if (((_n = toolCall.function) == null ? void 0 : _n.name) != null && ((_o = toolCall.function) == null ? void 0 : _o.arguments) != null && isParsableJson(toolCall.function.arguments)) {
465
491
  controller.enqueue({
466
492
  type: "tool-call",
467
- toolCallId: (_l = toolCall.id) != null ? _l : generateId(),
493
+ toolCallId: (_p = toolCall.id) != null ? _p : generateId(),
468
494
  toolName: toolCall.function.name,
469
495
  input: toolCall.function.arguments
470
496
  });
@@ -474,7 +500,7 @@ var FriendliAIChatLanguageModel = class {
474
500
  }
475
501
  },
476
502
  flush(controller) {
477
- var _a2, _b, _c, _d, _e;
503
+ var _a2, _b, _c, _d;
478
504
  const providerMetadata = {
479
505
  [providerOptionsName]: {},
480
506
  ...metadataExtractor == null ? void 0 : metadataExtractor.buildMetadata()
@@ -489,11 +515,17 @@ var FriendliAIChatLanguageModel = class {
489
515
  type: "finish",
490
516
  finishReason,
491
517
  usage: {
492
- inputTokens: (_a2 = usage.promptTokens) != null ? _a2 : void 0,
493
- outputTokens: (_b = usage.completionTokens) != null ? _b : void 0,
494
- totalTokens: (_c = usage.totalTokens) != null ? _c : void 0,
495
- reasoningTokens: (_d = usage.completionTokensDetails.reasoningTokens) != null ? _d : void 0,
496
- cachedInputTokens: (_e = usage.promptTokensDetails.cachedTokens) != null ? _e : void 0
518
+ inputTokens: {
519
+ total: (_a2 = usage.promptTokens) != null ? _a2 : void 0,
520
+ noCache: void 0,
521
+ cacheRead: (_b = usage.promptTokensDetails.cachedTokens) != null ? _b : void 0,
522
+ cacheWrite: void 0
523
+ },
524
+ outputTokens: {
525
+ total: (_c = usage.completionTokens) != null ? _c : void 0,
526
+ text: void 0,
527
+ reasoning: (_d = usage.completionTokensDetails.reasoningTokens) != null ? _d : void 0
528
+ }
497
529
  },
498
530
  providerMetadata
499
531
  });
@@ -652,6 +684,25 @@ var createOpenAICompatibleChatChunkSchema = (errorSchema) => z2.union([
652
684
  ),
653
685
  usage: openaiCompatibleTokenUsageSchema
654
686
  }),
687
+ z2.object({
688
+ name: z2.string(),
689
+ status: z2.enum(["ENDED", "STARTED", "ERRORED", "UPDATING"]),
690
+ message: z2.null(),
691
+ parameters: z2.array(
692
+ z2.object({
693
+ name: z2.string(),
694
+ value: z2.string()
695
+ })
696
+ ),
697
+ result: z2.string().nullable(),
698
+ error: z2.object({
699
+ type: z2.enum(["INVALID_PARAMETER", "UNKNOWN"]),
700
+ msg: z2.string()
701
+ }).nullable(),
702
+ timestamp: z2.number(),
703
+ usage: z2.null(),
704
+ tool_call_id: z2.string().nullable()
705
+ }),
655
706
  errorSchema
656
707
  ]);
657
708
  var friendliProviderOptionsSchema = z2.object({
@@ -667,6 +718,91 @@ var friendliProviderOptionsSchema = z2.object({
667
718
  chat_template_kwargs: z2.record(z2.string(), z2.any()).nullish()
668
719
  });
669
720
 
721
+ // src/friendli-settings.ts
722
+ var FriendliAIServerlessModelIds = [
723
+ "MiniMaxAI/MiniMax-M2",
724
+ "zai-org/GLM-4.6",
725
+ "LGAI-EXAONE/EXAONE-4.0.1-32B",
726
+ "skt/A.X-4.0",
727
+ "skt/A.X-3.1",
728
+ "naver-hyperclovax/HyperCLOVAX-SEED-Think-14B",
729
+ "deepseek-ai/DeepSeek-V3.1",
730
+ "deepseek-ai/DeepSeek-R1-0528",
731
+ "meta-llama/Llama-4-Maverick-17B-128E-Instruct",
732
+ "meta-llama/Llama-4-Scout-17B-16E-Instruct",
733
+ "meta-llama/Llama-3.3-70B-Instruct",
734
+ "meta-llama-3.3-70b-instruct",
735
+ "meta-llama/Llama-3.1-8B-Instruct",
736
+ "meta-llama-3.1-8b-instruct",
737
+ "Qwen/Qwen3-235B-A22B-Thinking-2507",
738
+ "Qwen/Qwen3-235B-A22B-Instruct-2507",
739
+ "Qwen/Qwen3-30B-A3B",
740
+ "Qwen/Qwen3-32B",
741
+ "google/gemma-3-27b-it",
742
+ "mistralai/Mistral-Small-3.1-24B-Instruct-2503",
743
+ "mistralai/Devstral-Small-2505",
744
+ "mistralai/Magistral-Small-2506"
745
+ ];
746
+
747
+ // src/friendli-tools.ts
748
+ import { jsonSchema } from "@ai-sdk/provider-utils";
749
+ function webSearch() {
750
+ return {
751
+ type: "provider",
752
+ id: "friendli.web:search",
753
+ args: {},
754
+ inputSchema: jsonSchema({ type: "object", properties: {} })
755
+ };
756
+ }
757
+ function webUrl() {
758
+ return {
759
+ type: "provider",
760
+ id: "friendli.web:url",
761
+ args: {},
762
+ inputSchema: jsonSchema({ type: "object", properties: {} })
763
+ };
764
+ }
765
+ function mathCalendar() {
766
+ return {
767
+ type: "provider",
768
+ id: "friendli.math:calendar",
769
+ args: {},
770
+ inputSchema: jsonSchema({ type: "object", properties: {} })
771
+ };
772
+ }
773
+ function mathStatistics() {
774
+ return {
775
+ type: "provider",
776
+ id: "friendli.math:statistics",
777
+ args: {},
778
+ inputSchema: jsonSchema({ type: "object", properties: {} })
779
+ };
780
+ }
781
+ function mathCalculator() {
782
+ return {
783
+ type: "provider",
784
+ id: "friendli.math:calculator",
785
+ args: {},
786
+ inputSchema: jsonSchema({ type: "object", properties: {} })
787
+ };
788
+ }
789
+ function codePythonInterpreter() {
790
+ return {
791
+ type: "provider",
792
+ id: "friendli.code:python-interpreter",
793
+ args: {},
794
+ inputSchema: jsonSchema({ type: "object", properties: {} })
795
+ };
796
+ }
797
+ var friendliTools = {
798
+ webSearch,
799
+ webUrl,
800
+ mathCalendar,
801
+ mathStatistics,
802
+ mathCalculator,
803
+ codePythonInterpreter
804
+ };
805
+
670
806
  // src/get-available-models.ts
671
807
  import { loadApiKey } from "@ai-sdk/provider-utils";
672
808
  var DEFAULT_GRAPHQL_URL = "https://api-internal.friendli.ai/api/graphql";
@@ -774,64 +910,6 @@ async function getAvailableModelsImpl(options) {
774
910
  return { models };
775
911
  }
776
912
 
777
- // src/friendli-tools.ts
778
- function webUrlBetaTool() {
779
- return {
780
- type: "provider-defined",
781
- id: "friendli.web:url",
782
- name: "web:url",
783
- args: {}
784
- };
785
- }
786
- function webSearchBetaTool() {
787
- return {
788
- type: "provider-defined",
789
- id: "friendli.web:search",
790
- name: "web:search",
791
- args: {}
792
- };
793
- }
794
- function mathCalendarBetaTool() {
795
- return {
796
- type: "provider-defined",
797
- id: "friendli.math:calendar",
798
- name: "math:calendar",
799
- args: {}
800
- };
801
- }
802
- function mathStatisticsBetaTool() {
803
- return {
804
- type: "provider-defined",
805
- id: "friendli.math:statistics",
806
- name: "math:statistics",
807
- args: {}
808
- };
809
- }
810
- function mathCalculatorBetaTool() {
811
- return {
812
- type: "provider-defined",
813
- id: "friendli.math:calculator",
814
- name: "math:calculator",
815
- args: {}
816
- };
817
- }
818
- function codePythonInterpreterBetaTool() {
819
- return {
820
- type: "provider-defined",
821
- id: "friendli.code:python-interpreter",
822
- name: "code:python-interpreter",
823
- args: {}
824
- };
825
- }
826
- var friendliTools = {
827
- webSearchBetaTool,
828
- webUrlBetaTool,
829
- mathCalendarBetaTool,
830
- mathStatisticsBetaTool,
831
- mathCalculatorBetaTool,
832
- codePythonInterpreterBetaTool
833
- };
834
-
835
913
  // src/friendli-provider.ts
836
914
  function createFriendli(options = {}) {
837
915
  const getHeaders = () => ({
@@ -903,7 +981,7 @@ function createFriendli(options = {}) {
903
981
  });
904
982
  };
905
983
  const createTextEmbeddingModel = (modelId) => {
906
- throw new NoSuchModelError({ modelId, modelType: "textEmbeddingModel" });
984
+ throw new NoSuchModelError({ modelId, modelType: "embeddingModel" });
907
985
  };
908
986
  const createImageModel = (modelId) => {
909
987
  throw new NoSuchModelError({ modelId, modelType: "imageModel" });
@@ -919,7 +997,7 @@ function createFriendli(options = {}) {
919
997
  provider.chat = createLanguageModel;
920
998
  provider.completion = createCompletionModel;
921
999
  provider.embedding = createTextEmbeddingModel;
922
- provider.textEmbeddingModel = createTextEmbeddingModel;
1000
+ provider.embeddingModel = createTextEmbeddingModel;
923
1001
  provider.getAvailableModels = async (opts) => {
924
1002
  var _a;
925
1003
  const defaultURL = "https://api-internal.friendli.ai/api/graphql";