@friendliai/ai-provider 1.0.0-beta.1 → 1.0.0

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 CHANGED
@@ -27,30 +27,101 @@ module.exports = __toCommonJS(index_exports);
27
27
 
28
28
  // src/friendli-provider.ts
29
29
  var import_openai_compatible = require("@ai-sdk/openai-compatible");
30
- var import_provider3 = require("@ai-sdk/provider");
30
+ var import_provider4 = require("@ai-sdk/provider");
31
31
  var import_provider_utils5 = require("@ai-sdk/provider-utils");
32
32
 
33
33
  // src/friendli-chat-language-model.ts
34
34
  var import_internal = require("@ai-sdk/openai-compatible/internal");
35
- var import_provider2 = require("@ai-sdk/provider");
35
+ var import_provider3 = require("@ai-sdk/provider");
36
36
  var import_provider_utils2 = require("@ai-sdk/provider-utils");
37
37
  var import_v42 = require("zod/v4");
38
38
 
39
39
  // src/friendli-error.ts
40
+ var import_provider = require("@ai-sdk/provider");
40
41
  var import_provider_utils = require("@ai-sdk/provider-utils");
41
42
  var import_v4 = require("zod/v4");
42
- var friendliaiErrorSchema = import_v4.z.object({
43
+ var friendliErrorResponseSchema = import_v4.z.object({
43
44
  message: import_v4.z.string(),
44
- error: import_v4.z.record(import_v4.z.string(), import_v4.z.any())
45
+ error: import_v4.z.record(import_v4.z.string(), import_v4.z.any()).optional()
45
46
  });
47
+ var openAIStyleErrorResponseSchema = import_v4.z.object({
48
+ error: import_v4.z.object({
49
+ message: import_v4.z.string()
50
+ }).loose()
51
+ }).loose();
52
+ var friendliaiErrorSchema = import_v4.z.union([
53
+ // OpenAI/OpenRouter style error: { "error": { "message": "..." } }
54
+ openAIStyleErrorResponseSchema,
55
+ // Friendli style error: { "message": "...", "error": { ... } }
56
+ friendliErrorResponseSchema
57
+ ]);
46
58
  var friendliaiErrorStructure = {
47
59
  errorSchema: friendliaiErrorSchema,
48
- errorToMessage: (data) => data.message
60
+ errorToMessage: (data) => {
61
+ if (typeof data === "object" && data != null && "error" in data && typeof data.error === "object" && data.error != null && "message" in data.error && typeof data.error.message === "string") {
62
+ return data.error.message;
63
+ }
64
+ if (typeof data === "object" && data != null && "message" in data && typeof data.message === "string") {
65
+ return data.message;
66
+ }
67
+ return "Unknown error";
68
+ }
69
+ };
70
+ var friendliaiFailedResponseHandler = async ({
71
+ response,
72
+ url,
73
+ requestBodyValues
74
+ }) => {
75
+ const responseBody = await response.text();
76
+ const responseHeaders = {};
77
+ response.headers.forEach((value, key) => {
78
+ responseHeaders[key] = value;
79
+ });
80
+ const baseErrorOptions = {
81
+ url,
82
+ requestBodyValues,
83
+ statusCode: response.status,
84
+ responseHeaders,
85
+ responseBody
86
+ };
87
+ const trimmedBody = responseBody.trim();
88
+ if (trimmedBody === "") {
89
+ const fallback2 = response.statusText || `Request failed with status ${response.status}`;
90
+ return {
91
+ responseHeaders,
92
+ value: new import_provider.APICallError({
93
+ message: fallback2,
94
+ ...baseErrorOptions
95
+ })
96
+ };
97
+ }
98
+ const parsedError = await (0, import_provider_utils.safeParseJSON)({
99
+ text: responseBody,
100
+ schema: friendliaiErrorSchema
101
+ });
102
+ if (parsedError.success) {
103
+ return {
104
+ responseHeaders,
105
+ value: new import_provider.APICallError({
106
+ message: friendliaiErrorStructure.errorToMessage(parsedError.value),
107
+ data: parsedError.value,
108
+ ...baseErrorOptions
109
+ })
110
+ };
111
+ }
112
+ const fallback = trimmedBody || response.statusText || `Request failed with status ${response.status}`;
113
+ return {
114
+ responseHeaders,
115
+ value: new import_provider.APICallError({
116
+ message: fallback,
117
+ cause: parsedError.error,
118
+ ...baseErrorOptions
119
+ })
120
+ };
49
121
  };
50
- var friendliaiFailedResponseHandler = (0, import_provider_utils.createJsonErrorResponseHandler)(friendliaiErrorStructure);
51
122
 
52
123
  // src/friendli-prepare-tools.ts
53
- var import_provider = require("@ai-sdk/provider");
124
+ var import_provider2 = require("@ai-sdk/provider");
54
125
  function prepareTools({
55
126
  tools,
56
127
  toolChoice
@@ -65,7 +136,9 @@ function prepareTools({
65
136
  for (const tool of tools) {
66
137
  if (tool.type === "provider") {
67
138
  openaiCompatTools.push({
68
- // NOTE: It would be better to use tool.name, but since ":" is replaced with "_", the following code is used instead
139
+ // NOTE: Friendli tool-assisted API expects provider tool types like "web:search".
140
+ // We derive it from the provider tool id (e.g. "friendli.web:search" -> "web:search")
141
+ // instead of tool.name (often "web_search").
69
142
  type: (_a = tool.id.split(".")[1]) != null ? _a : "unknown"
70
143
  });
71
144
  } else {
@@ -99,7 +172,7 @@ function prepareTools({
99
172
  };
100
173
  default: {
101
174
  const _exhaustiveCheck = type;
102
- throw new import_provider.UnsupportedFunctionalityError({
175
+ throw new import_provider2.UnsupportedFunctionalityError({
103
176
  functionality: `tool choice type: ${_exhaustiveCheck}`
104
177
  });
105
178
  }
@@ -107,6 +180,28 @@ function prepareTools({
107
180
  }
108
181
 
109
182
  // src/friendli-chat-language-model.ts
183
+ function isRecord(value) {
184
+ return typeof value === "object" && value != null;
185
+ }
186
+ function isHostedToolExecutionChunk(value) {
187
+ if (!isRecord(value)) return false;
188
+ return typeof value.status === "string" && typeof value.name === "string" && Array.isArray(value.parameters);
189
+ }
190
+ function getChunkErrorMessage(value) {
191
+ if (!isRecord(value)) return void 0;
192
+ if (typeof value.message === "string") {
193
+ return value.message;
194
+ }
195
+ const nestedError = value.error;
196
+ if (isRecord(nestedError) && typeof nestedError.message === "string") {
197
+ return nestedError.message;
198
+ }
199
+ return void 0;
200
+ }
201
+ function isOpenAIChatChunk(value) {
202
+ if (!isRecord(value)) return false;
203
+ return Array.isArray(value.choices);
204
+ }
110
205
  var FriendliAIChatLanguageModel = class {
111
206
  // type inferred via constructor
112
207
  constructor(modelId, config) {
@@ -116,7 +211,7 @@ var FriendliAIChatLanguageModel = class {
116
211
  this.config = config;
117
212
  const errorStructure = friendliaiErrorStructure;
118
213
  this.chunkSchema = createOpenAICompatibleChatChunkSchema(errorStructure.errorSchema);
119
- this.failedResponseHandler = (0, import_provider_utils2.createJsonErrorResponseHandler)(friendliaiErrorStructure);
214
+ this.failedResponseHandler = friendliaiFailedResponseHandler;
120
215
  this.supportsStructuredOutputs = (_a = config.supportsStructuredOutputs) != null ? _a : true;
121
216
  }
122
217
  get provider() {
@@ -144,14 +239,20 @@ var FriendliAIChatLanguageModel = class {
144
239
  }) {
145
240
  var _a;
146
241
  const warnings = [];
147
- if (topK != null) {
148
- warnings.push({ type: "unsupported", feature: "topK" });
149
- }
150
242
  const friendliOptions = await (0, import_provider_utils2.parseProviderOptions)({
243
+ provider: "friendliai",
244
+ providerOptions,
245
+ schema: friendliProviderOptionsSchema
246
+ });
247
+ const legacyFriendliOptions = await (0, import_provider_utils2.parseProviderOptions)({
151
248
  provider: "friendli",
152
249
  providerOptions,
153
250
  schema: friendliProviderOptionsSchema
154
251
  });
252
+ const options = {
253
+ ...legacyFriendliOptions,
254
+ ...friendliOptions
255
+ };
155
256
  if ((responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && !this.supportsStructuredOutputs) {
156
257
  warnings.push({
157
258
  type: "unsupported",
@@ -167,6 +268,14 @@ var FriendliAIChatLanguageModel = class {
167
268
  tools,
168
269
  toolChoice
169
270
  });
271
+ const isToolsPresent = openaiTools != null && openaiTools.length > 0;
272
+ if (isToolsPresent && (responseFormat != null || (options == null ? void 0 : options.regex) != null)) {
273
+ warnings.push({
274
+ type: "unsupported",
275
+ feature: "responseFormat",
276
+ details: "response_format is not supported when tools are present."
277
+ });
278
+ }
170
279
  return {
171
280
  args: {
172
281
  // >>> hard-coded default options >>>
@@ -178,36 +287,39 @@ var FriendliAIChatLanguageModel = class {
178
287
  max_tokens: maxOutputTokens,
179
288
  temperature,
180
289
  top_p: topP,
290
+ top_k: topK,
181
291
  frequency_penalty: frequencyPenalty,
182
292
  presence_penalty: presencePenalty,
183
- response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? this.supportsStructuredOutputs === true && responseFormat.schema != null ? {
293
+ response_format: isToolsPresent === false ? (responseFormat == null ? void 0 : responseFormat.type) === "json" ? this.supportsStructuredOutputs === true && responseFormat.schema != null ? {
184
294
  type: "json_schema",
185
295
  json_schema: {
186
296
  schema: responseFormat.schema,
187
297
  name: (_a = responseFormat.name) != null ? _a : "response",
188
298
  description: responseFormat.description
189
299
  }
190
- } : { type: "json_object" } : (friendliOptions == null ? void 0 : friendliOptions.regex) != null ? {
300
+ } : { type: "json_object" } : (options == null ? void 0 : options.regex) != null ? {
191
301
  type: "regex",
192
- schema: friendliOptions.regex
193
- } : void 0,
302
+ schema: options.regex
303
+ } : void 0 : void 0,
194
304
  stop: stopSequences,
195
305
  seed,
196
- ...(friendliOptions == null ? void 0 : friendliOptions.chat_template_kwargs) ? { chat_template_kwargs: friendliOptions.chat_template_kwargs } : {},
197
- // ...providerOptions?.[this.providerOptionsName],
198
- // reasoning_effort: compatibleOptions.reasoningEffort,
306
+ min_p: options == null ? void 0 : options.minP,
307
+ repetition_penalty: options == null ? void 0 : options.repetitionPenalty,
308
+ xtc_threshold: options == null ? void 0 : options.xtcThreshold,
309
+ xtc_probability: options == null ? void 0 : options.xtcProbability,
310
+ ...(options == null ? void 0 : options.chat_template_kwargs) ? { chat_template_kwargs: options.chat_template_kwargs } : {},
199
311
  // messages:
200
312
  messages: (0, import_internal.convertToOpenAICompatibleChatMessages)(prompt),
201
313
  // tools:
202
314
  tools: openaiTools,
203
315
  tool_choice: openaiToolChoice,
204
- parallel_tool_calls: friendliOptions == null ? void 0 : friendliOptions.parallelToolCalls
316
+ parallel_tool_calls: options == null ? void 0 : options.parallelToolCalls
205
317
  },
206
318
  warnings: [...warnings, ...toolWarnings]
207
319
  };
208
320
  }
209
321
  async doGenerate(options) {
210
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
322
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
211
323
  const { args, warnings } = await this.getArgs({ ...options, stream: false });
212
324
  const body = JSON.stringify(args);
213
325
  const {
@@ -251,18 +363,21 @@ var FriendliAIChatLanguageModel = class {
251
363
  }
252
364
  return {
253
365
  content,
254
- finishReason: (0, import_internal.mapOpenAICompatibleFinishReason)(choice.finish_reason),
366
+ finishReason: {
367
+ unified: (0, import_internal.mapOpenAICompatibleFinishReason)(choice.finish_reason),
368
+ raw: (_b = choice.finish_reason) != null ? _b : void 0
369
+ },
255
370
  usage: {
256
371
  inputTokens: {
257
- total: (_c = (_b = responseBody.usage) == null ? void 0 : _b.prompt_tokens) != null ? _c : void 0,
372
+ total: (_d = (_c = responseBody.usage) == null ? void 0 : _c.prompt_tokens) != null ? _d : void 0,
258
373
  noCache: void 0,
259
- cacheRead: (_f = (_e = (_d = responseBody.usage) == null ? void 0 : _d.prompt_tokens_details) == null ? void 0 : _e.cached_tokens) != null ? _f : void 0,
374
+ cacheRead: (_g = (_f = (_e = responseBody.usage) == null ? void 0 : _e.prompt_tokens_details) == null ? void 0 : _f.cached_tokens) != null ? _g : void 0,
260
375
  cacheWrite: void 0
261
376
  },
262
377
  outputTokens: {
263
- total: (_h = (_g = responseBody.usage) == null ? void 0 : _g.completion_tokens) != null ? _h : void 0,
378
+ total: (_i = (_h = responseBody.usage) == null ? void 0 : _h.completion_tokens) != null ? _i : void 0,
264
379
  text: void 0,
265
- reasoning: (_k = (_j = (_i = responseBody.usage) == null ? void 0 : _i.completion_tokens_details) == null ? void 0 : _j.reasoning_tokens) != null ? _k : void 0
380
+ reasoning: (_l = (_k = (_j = responseBody.usage) == null ? void 0 : _j.completion_tokens_details) == null ? void 0 : _k.reasoning_tokens) != null ? _l : void 0
266
381
  }
267
382
  },
268
383
  // providerMetadata,
@@ -298,7 +413,8 @@ var FriendliAIChatLanguageModel = class {
298
413
  fetch: this.config.fetch
299
414
  });
300
415
  const toolCalls = [];
301
- let finishReason = "unknown";
416
+ let finishReason = "other";
417
+ let rawFinishReason;
302
418
  const usage = {
303
419
  completionTokens: void 0,
304
420
  completionTokensDetails: {
@@ -320,9 +436,10 @@ var FriendliAIChatLanguageModel = class {
320
436
  start(controller) {
321
437
  controller.enqueue({ type: "stream-start", warnings });
322
438
  },
323
- // TODO we lost type safety on Chunk, most likely due to the error schema. MUST FIX
439
+ // NOTE: Chunk values can contain OpenAI-compatible deltas, hosted tool events, and error events.
440
+ // We narrow with type guards for safe handling.
324
441
  transform(chunk, controller) {
325
- var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
442
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
326
443
  if (!chunk.success) {
327
444
  finishReason = "error";
328
445
  controller.enqueue({ type: "error", error: chunk.error });
@@ -330,7 +447,7 @@ var FriendliAIChatLanguageModel = class {
330
447
  }
331
448
  const value = chunk.value;
332
449
  metadataExtractor == null ? void 0 : metadataExtractor.processChunk(chunk.rawValue);
333
- if ("status" in value) {
450
+ if (isHostedToolExecutionChunk(value)) {
334
451
  const toolCallId = (_a2 = value.tool_call_id) != null ? _a2 : (0, import_provider_utils2.generateId)();
335
452
  switch (value.status) {
336
453
  case "STARTED":
@@ -373,26 +490,36 @@ var FriendliAIChatLanguageModel = class {
373
490
  }
374
491
  return;
375
492
  }
376
- if ("error" in value) {
493
+ const chunkErrorMessage = getChunkErrorMessage(value);
494
+ if (chunkErrorMessage != null) {
377
495
  finishReason = "error";
378
- controller.enqueue({ type: "error", error: value.error.message });
496
+ controller.enqueue({ type: "error", error: chunkErrorMessage });
379
497
  return;
380
498
  }
499
+ if (!isOpenAIChatChunk(value)) {
500
+ finishReason = "error";
501
+ controller.enqueue({
502
+ type: "error",
503
+ error: new Error("Unsupported chunk shape")
504
+ });
505
+ return;
506
+ }
507
+ const chunkValue = value;
381
508
  if (isFirstChunk) {
382
509
  isFirstChunk = false;
383
510
  controller.enqueue({
384
511
  type: "response-metadata",
385
- ...(0, import_internal.getResponseMetadata)(value)
512
+ ...(0, import_internal.getResponseMetadata)(chunkValue)
386
513
  });
387
514
  }
388
- if (value.usage != null) {
515
+ if (chunkValue.usage != null) {
389
516
  const {
390
517
  prompt_tokens,
391
518
  completion_tokens,
392
519
  total_tokens,
393
520
  prompt_tokens_details,
394
521
  completion_tokens_details
395
- } = value.usage;
522
+ } = chunkValue.usage;
396
523
  usage.promptTokens = prompt_tokens != null ? prompt_tokens : void 0;
397
524
  usage.completionTokens = completion_tokens != null ? completion_tokens : void 0;
398
525
  usage.totalTokens = total_tokens != null ? total_tokens : void 0;
@@ -409,8 +536,9 @@ var FriendliAIChatLanguageModel = class {
409
536
  usage.promptTokensDetails.cachedTokens = prompt_tokens_details == null ? void 0 : prompt_tokens_details.cached_tokens;
410
537
  }
411
538
  }
412
- const choice = value.choices[0];
539
+ const choice = chunkValue.choices[0];
413
540
  if ((choice == null ? void 0 : choice.finish_reason) != null) {
541
+ rawFinishReason = choice.finish_reason;
414
542
  finishReason = (0, import_internal.mapOpenAICompatibleFinishReason)(choice.finish_reason);
415
543
  }
416
544
  if ((choice == null ? void 0 : choice.delta) == null) {
@@ -436,19 +564,19 @@ var FriendliAIChatLanguageModel = class {
436
564
  const index = toolCallDelta.index;
437
565
  if (toolCalls[index] == null) {
438
566
  if (toolCallDelta.type !== "function") {
439
- throw new import_provider2.InvalidResponseDataError({
567
+ throw new import_provider3.InvalidResponseDataError({
440
568
  data: toolCallDelta,
441
569
  message: `Expected 'function' type.`
442
570
  });
443
571
  }
444
572
  if (toolCallDelta.id == null) {
445
- throw new import_provider2.InvalidResponseDataError({
573
+ throw new import_provider3.InvalidResponseDataError({
446
574
  data: toolCallDelta,
447
575
  message: `Expected 'id' to be a string.`
448
576
  });
449
577
  }
450
578
  if (((_e = toolCallDelta.function) == null ? void 0 : _e.name) == null) {
451
- throw new import_provider2.InvalidResponseDataError({
579
+ throw new import_provider3.InvalidResponseDataError({
452
580
  data: toolCallDelta,
453
581
  message: `Expected 'function.name' to be a string.`
454
582
  });
@@ -493,12 +621,12 @@ var FriendliAIChatLanguageModel = class {
493
621
  controller.enqueue({
494
622
  type: "tool-input-delta",
495
623
  id: toolCall.id,
496
- delta: (_m = toolCallDelta.function.arguments) != null ? _m : ""
624
+ delta: (_n = (_m = toolCallDelta.function) == null ? void 0 : _m.arguments) != null ? _n : ""
497
625
  });
498
- if (((_n = toolCall.function) == null ? void 0 : _n.name) != null && ((_o = toolCall.function) == null ? void 0 : _o.arguments) != null && (0, import_provider_utils2.isParsableJson)(toolCall.function.arguments)) {
626
+ if (((_o = toolCall.function) == null ? void 0 : _o.name) != null && ((_p = toolCall.function) == null ? void 0 : _p.arguments) != null && (0, import_provider_utils2.isParsableJson)(toolCall.function.arguments)) {
499
627
  controller.enqueue({
500
628
  type: "tool-call",
501
- toolCallId: (_p = toolCall.id) != null ? _p : (0, import_provider_utils2.generateId)(),
629
+ toolCallId: (_q = toolCall.id) != null ? _q : (0, import_provider_utils2.generateId)(),
502
630
  toolName: toolCall.function.name,
503
631
  input: toolCall.function.arguments
504
632
  });
@@ -521,7 +649,10 @@ var FriendliAIChatLanguageModel = class {
521
649
  }
522
650
  controller.enqueue({
523
651
  type: "finish",
524
- finishReason,
652
+ finishReason: {
653
+ unified: finishReason,
654
+ raw: rawFinishReason
655
+ },
525
656
  usage: {
526
657
  inputTokens: {
527
658
  total: (_a2 = usage.promptTokens) != null ? _a2 : void 0,
@@ -545,86 +676,6 @@ var FriendliAIChatLanguageModel = class {
545
676
  };
546
677
  }
547
678
  };
548
- var friendliAIChatResponseSchema = import_v42.z.object({
549
- id: import_v42.z.string().nullish(),
550
- created: import_v42.z.number().nullish(),
551
- model: import_v42.z.string().nullish(),
552
- choices: import_v42.z.array(
553
- import_v42.z.object({
554
- message: import_v42.z.object({
555
- role: import_v42.z.literal("assistant").nullish(),
556
- content: import_v42.z.string().nullish(),
557
- tool_calls: import_v42.z.array(
558
- import_v42.z.object({
559
- id: import_v42.z.string().nullish(),
560
- type: import_v42.z.literal("function"),
561
- function: import_v42.z.object({
562
- name: import_v42.z.string(),
563
- arguments: import_v42.z.union([import_v42.z.string(), import_v42.z.any()]).nullish()
564
- })
565
- })
566
- ).nullish()
567
- }),
568
- finish_reason: import_v42.z.string().nullish()
569
- })
570
- ),
571
- usage: import_v42.z.object({
572
- prompt_tokens: import_v42.z.number().nullish(),
573
- completion_tokens: import_v42.z.number().nullish()
574
- }).nullish()
575
- });
576
- var friendliaiChatChunkSchema = import_v42.z.union([
577
- import_v42.z.object({
578
- id: import_v42.z.string().nullish(),
579
- created: import_v42.z.number().nullish(),
580
- model: import_v42.z.string().nullish(),
581
- choices: import_v42.z.array(
582
- import_v42.z.object({
583
- delta: import_v42.z.object({
584
- role: import_v42.z.enum(["assistant"]).nullish(),
585
- content: import_v42.z.string().nullish(),
586
- tool_calls: import_v42.z.array(
587
- import_v42.z.object({
588
- index: import_v42.z.number(),
589
- id: import_v42.z.string().nullish(),
590
- type: import_v42.z.literal("function").optional(),
591
- function: import_v42.z.object({
592
- name: import_v42.z.string().nullish(),
593
- arguments: import_v42.z.string().nullish()
594
- })
595
- })
596
- ).nullish()
597
- }).nullish(),
598
- finish_reason: import_v42.z.string().nullish()
599
- })
600
- ),
601
- usage: import_v42.z.object({
602
- prompt_tokens: import_v42.z.number().nullish(),
603
- completion_tokens: import_v42.z.number().nullish()
604
- }).nullish()
605
- }),
606
- import_v42.z.object({
607
- name: import_v42.z.string(),
608
- status: import_v42.z.enum(["ENDED", "STARTED", "ERRORED", "UPDATING"]),
609
- message: import_v42.z.null(),
610
- parameters: import_v42.z.array(
611
- import_v42.z.object({
612
- name: import_v42.z.string(),
613
- value: import_v42.z.string()
614
- })
615
- ),
616
- result: import_v42.z.string().nullable(),
617
- error: import_v42.z.object({
618
- type: import_v42.z.enum(["INVALID_PARAMETER", "UNKNOWN"]),
619
- msg: import_v42.z.string()
620
- }).nullable(),
621
- timestamp: import_v42.z.number(),
622
- usage: import_v42.z.null(),
623
- tool_call_id: import_v42.z.string().nullable()
624
- // temporary fix for "file:text" tool calls
625
- }),
626
- friendliaiErrorSchema
627
- ]);
628
679
  var openaiCompatibleTokenUsageSchema = import_v42.z.object({
629
680
  prompt_tokens: import_v42.z.number().nullish(),
630
681
  completion_tokens: import_v42.z.number().nullish(),
@@ -723,7 +774,23 @@ var friendliProviderOptionsSchema = import_v42.z.object({
723
774
  */
724
775
  // regex: z.instanceof(RegExp).nullish(),
725
776
  regex: import_v42.z.string().nullish(),
726
- chat_template_kwargs: import_v42.z.record(import_v42.z.string(), import_v42.z.any()).nullish()
777
+ chat_template_kwargs: import_v42.z.record(import_v42.z.string(), import_v42.z.any()).nullish(),
778
+ /**
779
+ * A scaling factor used to determine the minimum token probability threshold.
780
+ */
781
+ minP: import_v42.z.number().nullish(),
782
+ /**
783
+ * Penalizes tokens that have already appeared in the generated result.
784
+ */
785
+ repetitionPenalty: import_v42.z.number().nullish(),
786
+ /**
787
+ * A probability threshold used to identify “top choice” tokens for exclusion in XTC sampling.
788
+ */
789
+ xtcThreshold: import_v42.z.number().nullish(),
790
+ /**
791
+ * The probability that XTC (Exclude Top Choices) filtering will be applied for each sampling decision.
792
+ */
793
+ xtcProbability: import_v42.z.number().nullish()
727
794
  });
728
795
 
729
796
  // src/friendli-settings.ts
@@ -754,53 +821,64 @@ var FriendliAIServerlessModelIds = [
754
821
 
755
822
  // src/friendli-tools.ts
756
823
  var import_provider_utils3 = require("@ai-sdk/provider-utils");
824
+ var import_v43 = require("zod/v4");
825
+ var inputSchema = import_v43.z.object({}).loose();
826
+ var outputSchema = import_v43.z.unknown();
827
+ var webSearchTool = (0, import_provider_utils3.createProviderToolFactoryWithOutputSchema)({
828
+ id: "friendli.web:search",
829
+ inputSchema,
830
+ outputSchema
831
+ });
832
+ var webUrlTool = (0, import_provider_utils3.createProviderToolFactoryWithOutputSchema)({
833
+ id: "friendli.web:url",
834
+ inputSchema,
835
+ outputSchema
836
+ });
837
+ var mathCalendarTool = (0, import_provider_utils3.createProviderToolFactoryWithOutputSchema)({
838
+ id: "friendli.math:calendar",
839
+ inputSchema,
840
+ outputSchema
841
+ });
842
+ var mathStatisticsTool = (0, import_provider_utils3.createProviderToolFactoryWithOutputSchema)({
843
+ id: "friendli.math:statistics",
844
+ inputSchema,
845
+ outputSchema
846
+ });
847
+ var mathCalculatorTool = (0, import_provider_utils3.createProviderToolFactoryWithOutputSchema)({
848
+ id: "friendli.math:calculator",
849
+ inputSchema,
850
+ outputSchema
851
+ });
852
+ var codePythonInterpreterTool = (0, import_provider_utils3.createProviderToolFactoryWithOutputSchema)({
853
+ id: "friendli.code:python-interpreter",
854
+ inputSchema,
855
+ outputSchema
856
+ });
857
+ var linkupSearchTool = (0, import_provider_utils3.createProviderToolFactoryWithOutputSchema)({
858
+ id: "friendli.linkup:search",
859
+ inputSchema,
860
+ outputSchema
861
+ });
757
862
  function webSearch() {
758
- return {
759
- type: "provider",
760
- id: "friendli.web:search",
761
- args: {},
762
- inputSchema: (0, import_provider_utils3.jsonSchema)({ type: "object", properties: {} })
763
- };
863
+ return webSearchTool({});
764
864
  }
765
865
  function webUrl() {
766
- return {
767
- type: "provider",
768
- id: "friendli.web:url",
769
- args: {},
770
- inputSchema: (0, import_provider_utils3.jsonSchema)({ type: "object", properties: {} })
771
- };
866
+ return webUrlTool({});
772
867
  }
773
868
  function mathCalendar() {
774
- return {
775
- type: "provider",
776
- id: "friendli.math:calendar",
777
- args: {},
778
- inputSchema: (0, import_provider_utils3.jsonSchema)({ type: "object", properties: {} })
779
- };
869
+ return mathCalendarTool({});
780
870
  }
781
871
  function mathStatistics() {
782
- return {
783
- type: "provider",
784
- id: "friendli.math:statistics",
785
- args: {},
786
- inputSchema: (0, import_provider_utils3.jsonSchema)({ type: "object", properties: {} })
787
- };
872
+ return mathStatisticsTool({});
788
873
  }
789
874
  function mathCalculator() {
790
- return {
791
- type: "provider",
792
- id: "friendli.math:calculator",
793
- args: {},
794
- inputSchema: (0, import_provider_utils3.jsonSchema)({ type: "object", properties: {} })
795
- };
875
+ return mathCalculatorTool({});
796
876
  }
797
877
  function codePythonInterpreter() {
798
- return {
799
- type: "provider",
800
- id: "friendli.code:python-interpreter",
801
- args: {},
802
- inputSchema: (0, import_provider_utils3.jsonSchema)({ type: "object", properties: {} })
803
- };
878
+ return codePythonInterpreterTool({});
879
+ }
880
+ function linkupSearch() {
881
+ return linkupSearchTool({});
804
882
  }
805
883
  var friendliTools = {
806
884
  webSearch,
@@ -808,7 +886,8 @@ var friendliTools = {
808
886
  mathCalendar,
809
887
  mathStatistics,
810
888
  mathCalculator,
811
- codePythonInterpreter
889
+ codePythonInterpreter,
890
+ linkupSearch
812
891
  };
813
892
 
814
893
  // src/get-available-models.ts
@@ -975,7 +1054,8 @@ function createFriendli(options = {}) {
975
1054
  provider: `friendliai.${type}.chat`,
976
1055
  url: ({ path }) => `${baseURL}${path}`,
977
1056
  headers: getHeaders,
978
- fetch: options.fetch
1057
+ fetch: options.fetch,
1058
+ includeUsage: options.includeUsage
979
1059
  });
980
1060
  };
981
1061
  const createCompletionModel = (modelId) => {
@@ -989,16 +1069,16 @@ function createFriendli(options = {}) {
989
1069
  });
990
1070
  };
991
1071
  const createTextEmbeddingModel = (modelId) => {
992
- throw new import_provider3.NoSuchModelError({ modelId, modelType: "embeddingModel" });
1072
+ throw new import_provider4.NoSuchModelError({ modelId, modelType: "embeddingModel" });
993
1073
  };
994
1074
  const createImageModel = (modelId) => {
995
- throw new import_provider3.NoSuchModelError({ modelId, modelType: "imageModel" });
1075
+ throw new import_provider4.NoSuchModelError({ modelId, modelType: "imageModel" });
996
1076
  };
997
1077
  const createTranscriptionModel = (modelId) => {
998
- throw new import_provider3.NoSuchModelError({ modelId, modelType: "languageModel" });
1078
+ throw new import_provider4.NoSuchModelError({ modelId, modelType: "languageModel" });
999
1079
  };
1000
1080
  const createSpeechModel = (modelId) => {
1001
- throw new import_provider3.NoSuchModelError({ modelId, modelType: "languageModel" });
1081
+ throw new import_provider4.NoSuchModelError({ modelId, modelType: "languageModel" });
1002
1082
  };
1003
1083
  const provider = (modelId) => createLanguageModel(modelId);
1004
1084
  provider.languageModel = createLanguageModel;