@friendliai/ai-provider 0.2.6 → 0.2.7-alpha.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
@@ -61,70 +61,51 @@ var friendliaiFailedResponseHandler = (0, import_provider_utils.createJsonErrorR
61
61
  // src/friendli-prepare-tools.ts
62
62
  var import_provider = require("@ai-sdk/provider");
63
63
  function prepareTools({
64
- mode,
65
- tools: hostedTools
64
+ tools,
65
+ toolChoice
66
66
  }) {
67
- var _a;
68
- const tools = ((_a = mode.tools) == null ? void 0 : _a.length) ? mode.tools : void 0;
67
+ tools = (tools == null ? void 0 : tools.length) ? tools : void 0;
69
68
  const toolWarnings = [];
70
- if (tools == null && hostedTools == null) {
71
- return { tools: void 0, tool_choice: void 0, toolWarnings };
69
+ if (tools == null) {
70
+ return { tools: void 0, toolChoice: void 0, toolWarnings };
72
71
  }
73
- const toolChoice = mode.toolChoice;
74
- const mappedTools = [];
75
- if (tools) {
76
- for (const tool of tools) {
77
- if (tool.type === "provider-defined") {
78
- toolWarnings.push({ type: "unsupported-tool", tool });
79
- } else {
80
- mappedTools.push({
81
- type: "function",
82
- function: {
83
- name: tool.name,
84
- description: tool.description,
85
- parameters: tool.parameters
86
- }
87
- });
88
- }
72
+ const openaiCompatTools = [];
73
+ for (const tool of tools) {
74
+ if (tool.type === "provider-defined") {
75
+ toolWarnings.push({ type: "unsupported-tool", tool });
76
+ } else {
77
+ openaiCompatTools.push({
78
+ type: "function",
79
+ function: {
80
+ name: tool.name,
81
+ description: tool.description,
82
+ parameters: tool.parameters
83
+ }
84
+ });
89
85
  }
90
86
  }
91
- const mappedHostedTools = hostedTools == null ? void 0 : hostedTools.map((tool) => {
92
- return {
93
- type: tool.type
94
- };
95
- });
96
87
  if (toolChoice == null) {
97
- return {
98
- tools: [...mappedTools != null ? mappedTools : [], ...mappedHostedTools != null ? mappedHostedTools : []],
99
- tool_choice: void 0,
100
- toolWarnings
101
- };
88
+ return { tools: openaiCompatTools, toolChoice: void 0, toolWarnings };
102
89
  }
103
90
  const type = toolChoice.type;
104
91
  switch (type) {
105
92
  case "auto":
106
93
  case "none":
107
94
  case "required":
108
- return {
109
- tools: [...mappedTools != null ? mappedTools : [], ...mappedHostedTools != null ? mappedHostedTools : []],
110
- tool_choice: type,
111
- toolWarnings
112
- };
95
+ return { tools: openaiCompatTools, toolChoice: type, toolWarnings };
113
96
  case "tool":
114
97
  return {
115
- tools: [...mappedTools != null ? mappedTools : [], ...mappedHostedTools != null ? mappedHostedTools : []],
116
- tool_choice: {
98
+ tools: openaiCompatTools,
99
+ toolChoice: {
117
100
  type: "function",
118
- function: {
119
- name: toolChoice.toolName
120
- }
101
+ function: { name: toolChoice.toolName }
121
102
  },
122
103
  toolWarnings
123
104
  };
124
105
  default: {
125
106
  const _exhaustiveCheck = type;
126
107
  throw new import_provider.UnsupportedFunctionalityError({
127
- functionality: `Unsupported tool choice type: ${_exhaustiveCheck}`
108
+ functionality: `tool choice type: ${_exhaustiveCheck}`
128
109
  });
129
110
  }
130
111
  }
@@ -132,39 +113,48 @@ function prepareTools({
132
113
 
133
114
  // src/friendli-chat-language-model.ts
134
115
  var FriendliAIChatLanguageModel = class {
135
- constructor(modelId, settings, config) {
136
- this.specificationVersion = "v1";
116
+ // type inferred via constructor
117
+ constructor(modelId, config) {
118
+ this.specificationVersion = "v2";
137
119
  var _a;
138
120
  this.modelId = modelId;
139
- this.settings = settings;
140
121
  this.config = config;
122
+ const errorStructure = friendliaiErrorStructure;
123
+ this.chunkSchema = createOpenAICompatibleChatChunkSchema(
124
+ errorStructure.errorSchema
125
+ );
141
126
  this.failedResponseHandler = (0, import_provider_utils2.createJsonErrorResponseHandler)(
142
127
  friendliaiErrorStructure
143
128
  );
144
129
  this.supportsStructuredOutputs = (_a = config.supportsStructuredOutputs) != null ? _a : true;
145
130
  }
146
- get defaultObjectGenerationMode() {
147
- var _a;
148
- return (_a = this.config.defaultObjectGenerationMode) != null ? _a : "json";
149
- }
150
131
  get provider() {
151
132
  return this.config.provider;
152
133
  }
153
- getArgs({
154
- mode,
134
+ get supportedUrls() {
135
+ var _a, _b, _c;
136
+ return (_c = (_b = (_a = this.config).supportedUrls) == null ? void 0 : _b.call(_a)) != null ? _c : {};
137
+ }
138
+ async getArgs({
155
139
  prompt,
156
- maxTokens,
140
+ maxOutputTokens,
157
141
  temperature,
158
142
  topP,
159
143
  topK,
160
144
  frequencyPenalty,
161
145
  presencePenalty,
146
+ // providerOptions,
162
147
  stopSequences,
163
148
  responseFormat,
164
- seed
149
+ seed,
150
+ toolChoice,
151
+ tools
165
152
  }) {
166
- const type = mode.type;
153
+ var _a;
167
154
  const warnings = [];
155
+ if (topK != null) {
156
+ warnings.push({ type: "unsupported-setting", setting: "topK" });
157
+ }
168
158
  if ((responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && !this.supportsStructuredOutputs) {
169
159
  warnings.push({
170
160
  type: "unsupported-setting",
@@ -172,220 +162,173 @@ var FriendliAIChatLanguageModel = class {
172
162
  details: "JSON response format schema is only supported with structuredOutputs"
173
163
  });
174
164
  }
175
- const baseArgs = {
176
- // model id:
177
- model: this.modelId,
178
- // model specific settings:
179
- user: this.settings.user,
180
- parallel_tool_calls: this.settings.parallelToolCalls,
181
- // standardized settings:
182
- max_tokens: maxTokens,
183
- temperature,
184
- top_p: topP,
185
- top_k: topK,
186
- frequency_penalty: frequencyPenalty,
187
- presence_penalty: presencePenalty,
188
- response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? this.supportsStructuredOutputs === true && responseFormat.schema != null ? {
189
- type: "json_schema",
190
- json_schema: {
191
- schema: responseFormat.schema,
192
- description: responseFormat.description
193
- }
194
- } : { type: "json_object" } : void 0,
195
- stop: stopSequences,
196
- seed,
197
- // messages:
198
- messages: (0, import_internal.convertToOpenAICompatibleChatMessages)(prompt)
199
- };
200
- if (this.settings.regex != null && type !== "regular") {
201
- throw new import_provider2.UnsupportedFunctionalityError({
202
- functionality: "egular expression is only supported with regular mode (generateText, streamText)"
203
- });
204
- }
205
- switch (type) {
206
- case "regular": {
207
- if (this.settings.regex != null) {
208
- if (this.settings.tools != null || mode.tools != null) {
209
- throw new import_provider2.UnsupportedFunctionalityError({
210
- functionality: "Regular expression and tools cannot be used together. Use either regular expression or tools."
211
- });
165
+ const {
166
+ tools: openaiTools,
167
+ toolChoice: openaiToolChoice,
168
+ toolWarnings
169
+ } = prepareTools({
170
+ tools,
171
+ toolChoice
172
+ });
173
+ return {
174
+ args: {
175
+ // model id:
176
+ model: this.modelId,
177
+ // model specific settings:
178
+ // user: compatibleOptions.user,
179
+ // standardized settings:
180
+ max_tokens: maxOutputTokens,
181
+ temperature,
182
+ top_p: topP,
183
+ frequency_penalty: frequencyPenalty,
184
+ presence_penalty: presencePenalty,
185
+ response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? this.supportsStructuredOutputs === true && responseFormat.schema != null ? {
186
+ type: "json_schema",
187
+ json_schema: {
188
+ schema: responseFormat.schema,
189
+ name: (_a = responseFormat.name) != null ? _a : "response",
190
+ description: responseFormat.description
212
191
  }
213
- return {
214
- args: {
215
- ...baseArgs,
216
- response_format: {
217
- type: "regex",
218
- schema: this.settings.regex.source
219
- }
220
- },
221
- warnings
222
- };
223
- }
224
- const { tools, tool_choice, toolWarnings } = prepareTools({
225
- mode,
226
- tools: this.settings.tools
227
- });
228
- return {
229
- args: { ...baseArgs, tools, tool_choice },
230
- warnings: [...warnings, ...toolWarnings]
231
- };
232
- }
233
- case "object-json": {
234
- return {
235
- args: {
236
- ...baseArgs,
237
- response_format: this.supportsStructuredOutputs === true && mode.schema != null ? {
238
- type: "json_schema",
239
- json_schema: {
240
- schema: mode.schema,
241
- description: mode.description
242
- }
243
- } : { type: "json_object" }
244
- },
245
- warnings
246
- };
247
- }
248
- case "object-tool": {
249
- return {
250
- args: {
251
- ...baseArgs,
252
- tool_choice: {
253
- type: "function",
254
- function: { name: mode.tool.name }
255
- },
256
- tools: [
257
- {
258
- type: "function",
259
- function: {
260
- name: mode.tool.name,
261
- description: mode.tool.description,
262
- parameters: mode.tool.parameters
263
- }
264
- }
265
- ]
266
- },
267
- warnings
268
- };
269
- }
270
- default: {
271
- const _exhaustiveCheck = type;
272
- throw new Error(`Unsupported type: ${_exhaustiveCheck}`);
273
- }
274
- }
192
+ } : { type: "json_object" } : void 0,
193
+ stop: stopSequences,
194
+ seed,
195
+ // ...providerOptions?.[this.providerOptionsName],
196
+ // reasoning_effort: compatibleOptions.reasoningEffort,
197
+ // messages:
198
+ messages: (0, import_internal.convertToOpenAICompatibleChatMessages)(prompt),
199
+ // tools:
200
+ tools: openaiTools,
201
+ tool_choice: openaiToolChoice
202
+ },
203
+ warnings: [...warnings, ...toolWarnings]
204
+ };
275
205
  }
276
206
  async doGenerate(options) {
277
- var _a, _b, _c, _d, _e, _f;
278
- const { args, warnings } = this.getArgs({ ...options });
279
- const body = JSON.stringify({ ...args, stream: false });
280
- const { responseHeaders, value: response } = await (0, import_provider_utils2.postJsonToApi)({
207
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
208
+ const { args, warnings } = await this.getArgs({ ...options });
209
+ const body = JSON.stringify(args);
210
+ const {
211
+ responseHeaders,
212
+ value: responseBody,
213
+ rawValue: rawResponse
214
+ } = await (0, import_provider_utils2.postJsonToApi)({
281
215
  url: this.config.url({
282
216
  path: "/chat/completions",
283
217
  modelId: this.modelId
284
218
  }),
285
219
  headers: (0, import_provider_utils2.combineHeaders)(this.config.headers(), options.headers),
286
- body: {
287
- ...args,
288
- stream: false
289
- },
220
+ body: args,
290
221
  failedResponseHandler: this.failedResponseHandler,
291
222
  successfulResponseHandler: (0, import_provider_utils2.createJsonResponseHandler)(
292
- friendliAIChatResponseSchema
223
+ OpenAICompatibleChatResponseSchema
293
224
  ),
294
225
  abortSignal: options.abortSignal,
295
226
  fetch: this.config.fetch
296
227
  });
297
- const { messages: rawPrompt, ...rawSettings } = args;
298
- const choice = response.choices[0];
299
- return {
300
- text: (_a = choice.message.content) != null ? _a : void 0,
301
- toolCalls: (_b = choice.message.tool_calls) == null ? void 0 : _b.map((toolCall) => {
302
- var _a2;
303
- return {
228
+ const choice = responseBody.choices[0];
229
+ const content = [];
230
+ const text = choice.message.content;
231
+ if (text != null && text.length > 0) {
232
+ content.push({ type: "text", text });
233
+ }
234
+ const reasoning = choice.message.reasoning_content;
235
+ if (reasoning != null && reasoning.length > 0) {
236
+ content.push({
237
+ type: "reasoning",
238
+ text: reasoning
239
+ });
240
+ }
241
+ if (choice.message.tool_calls != null) {
242
+ for (const toolCall of choice.message.tool_calls) {
243
+ content.push({
244
+ type: "tool-call",
304
245
  toolCallType: "function",
305
- toolCallId: (_a2 = toolCall.id) != null ? _a2 : (0, import_provider_utils2.generateId)(),
246
+ toolCallId: (_a = toolCall.id) != null ? _a : (0, import_provider_utils2.generateId)(),
306
247
  toolName: toolCall.function.name,
307
- args: typeof toolCall.function.arguments === "string" ? toolCall.function.arguments : JSON.stringify(toolCall.function.arguments)
308
- };
309
- }),
248
+ args: toolCall.function.arguments
249
+ });
250
+ }
251
+ }
252
+ return {
253
+ content,
310
254
  finishReason: (0, import_internal.mapOpenAICompatibleFinishReason)(choice.finish_reason),
311
255
  usage: {
312
- promptTokens: (_d = (_c = response.usage) == null ? void 0 : _c.prompt_tokens) != null ? _d : NaN,
313
- completionTokens: (_f = (_e = response.usage) == null ? void 0 : _e.completion_tokens) != null ? _f : NaN
256
+ inputTokens: (_c = (_b = responseBody.usage) == null ? void 0 : _b.prompt_tokens) != null ? _c : void 0,
257
+ outputTokens: (_e = (_d = responseBody.usage) == null ? void 0 : _d.completion_tokens) != null ? _e : void 0,
258
+ totalTokens: (_g = (_f = responseBody.usage) == null ? void 0 : _f.total_tokens) != null ? _g : void 0,
259
+ reasoningTokens: (_j = (_i = (_h = responseBody.usage) == null ? void 0 : _h.completion_tokens_details) == null ? void 0 : _i.reasoning_tokens) != null ? _j : void 0,
260
+ cachedInputTokens: (_m = (_l = (_k = responseBody.usage) == null ? void 0 : _k.prompt_tokens_details) == null ? void 0 : _l.cached_tokens) != null ? _m : void 0
314
261
  },
315
- rawCall: { rawPrompt, rawSettings },
316
- rawResponse: { headers: responseHeaders },
317
- response: (0, import_internal.getResponseMetadata)(response),
318
- warnings,
319
- request: { body }
262
+ // providerMetadata,
263
+ request: { body },
264
+ response: {
265
+ ...(0, import_internal.getResponseMetadata)(responseBody),
266
+ headers: responseHeaders,
267
+ body: rawResponse
268
+ },
269
+ warnings
320
270
  };
321
271
  }
322
272
  async doStream(options) {
323
- const { args, warnings } = this.getArgs({ ...options });
324
- const body = JSON.stringify({ ...args, stream: true });
273
+ var _a;
274
+ const { args, warnings } = await this.getArgs({ ...options });
275
+ const body = {
276
+ ...args,
277
+ stream: true,
278
+ // only include stream_options when in strict compatibility mode:
279
+ stream_options: this.config.includeUsage ? { include_usage: true } : void 0
280
+ };
281
+ const metadataExtractor = (_a = this.config.metadataExtractor) == null ? void 0 : _a.createStreamExtractor();
325
282
  const { responseHeaders, value: response } = await (0, import_provider_utils2.postJsonToApi)({
326
283
  url: this.config.url({
327
284
  path: "/chat/completions",
328
285
  modelId: this.modelId
329
286
  }),
330
287
  headers: (0, import_provider_utils2.combineHeaders)(this.config.headers(), options.headers),
331
- body: {
332
- ...args,
333
- stream: true,
334
- stream_options: { include_usage: true }
335
- },
336
- failedResponseHandler: friendliaiFailedResponseHandler,
288
+ body,
289
+ failedResponseHandler: this.failedResponseHandler,
337
290
  successfulResponseHandler: (0, import_provider_utils2.createEventSourceResponseHandler)(
338
- friendliaiChatChunkSchema
291
+ this.chunkSchema
339
292
  ),
340
293
  abortSignal: options.abortSignal,
341
294
  fetch: this.config.fetch
342
295
  });
343
- const { messages: rawPrompt, ...rawSettings } = args;
344
296
  const toolCalls = [];
345
297
  let finishReason = "unknown";
346
- let usage = {
298
+ const usage = {
299
+ completionTokens: void 0,
300
+ completionTokensDetails: {
301
+ reasoningTokens: void 0,
302
+ acceptedPredictionTokens: void 0,
303
+ rejectedPredictionTokens: void 0
304
+ },
347
305
  promptTokens: void 0,
348
- completionTokens: void 0
306
+ promptTokensDetails: {
307
+ cachedTokens: void 0
308
+ },
309
+ totalTokens: void 0
349
310
  };
350
311
  let isFirstChunk = true;
351
- let providerMetadata;
312
+ const providerOptionsName = "friendliai";
352
313
  return {
353
314
  stream: response.pipeThrough(
354
315
  new TransformStream({
316
+ start(controller) {
317
+ controller.enqueue({ type: "stream-start", warnings });
318
+ },
319
+ // TODO we lost type safety on Chunk, most likely due to the error schema. MUST FIX
355
320
  transform(chunk, controller) {
356
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
321
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
357
322
  if (!chunk.success) {
358
323
  finishReason = "error";
359
324
  controller.enqueue({ type: "error", error: chunk.error });
360
325
  return;
361
326
  }
362
327
  const value = chunk.value;
363
- if ("status" in value) {
364
- switch (value.status) {
365
- case "STARTED":
366
- break;
367
- case "UPDATING":
368
- break;
369
- case "ENDED":
370
- break;
371
- case "ERRORED":
372
- finishReason = "error";
373
- break;
374
- default:
375
- finishReason = "error";
376
- controller.enqueue({
377
- type: "error",
378
- error: new Error(
379
- `Unsupported tool call status: ${value.status}`
380
- )
381
- });
382
- }
383
- return;
384
- }
385
- if ("message" in value) {
386
- console.error("Error chunk:", value);
328
+ metadataExtractor == null ? void 0 : metadataExtractor.processChunk(chunk.rawValue);
329
+ if ("error" in value) {
387
330
  finishReason = "error";
388
- controller.enqueue({ type: "error", error: value.message });
331
+ controller.enqueue({ type: "error", error: value.error.message });
389
332
  return;
390
333
  }
391
334
  if (isFirstChunk) {
@@ -396,10 +339,28 @@ var FriendliAIChatLanguageModel = class {
396
339
  });
397
340
  }
398
341
  if (value.usage != null) {
399
- usage = {
400
- promptTokens: (_a = value.usage.prompt_tokens) != null ? _a : void 0,
401
- completionTokens: (_b = value.usage.completion_tokens) != null ? _b : void 0
402
- };
342
+ const {
343
+ prompt_tokens,
344
+ completion_tokens,
345
+ total_tokens,
346
+ prompt_tokens_details,
347
+ completion_tokens_details
348
+ } = value.usage;
349
+ usage.promptTokens = prompt_tokens != null ? prompt_tokens : void 0;
350
+ usage.completionTokens = completion_tokens != null ? completion_tokens : void 0;
351
+ usage.totalTokens = total_tokens != null ? total_tokens : void 0;
352
+ if ((completion_tokens_details == null ? void 0 : completion_tokens_details.reasoning_tokens) != null) {
353
+ usage.completionTokensDetails.reasoningTokens = completion_tokens_details == null ? void 0 : completion_tokens_details.reasoning_tokens;
354
+ }
355
+ if ((completion_tokens_details == null ? void 0 : completion_tokens_details.accepted_prediction_tokens) != null) {
356
+ usage.completionTokensDetails.acceptedPredictionTokens = completion_tokens_details == null ? void 0 : completion_tokens_details.accepted_prediction_tokens;
357
+ }
358
+ if ((completion_tokens_details == null ? void 0 : completion_tokens_details.rejected_prediction_tokens) != null) {
359
+ usage.completionTokensDetails.rejectedPredictionTokens = completion_tokens_details == null ? void 0 : completion_tokens_details.rejected_prediction_tokens;
360
+ }
361
+ if ((prompt_tokens_details == null ? void 0 : prompt_tokens_details.cached_tokens) != null) {
362
+ usage.promptTokensDetails.cachedTokens = prompt_tokens_details == null ? void 0 : prompt_tokens_details.cached_tokens;
363
+ }
403
364
  }
404
365
  const choice = value.choices[0];
405
366
  if ((choice == null ? void 0 : choice.finish_reason) != null) {
@@ -411,10 +372,16 @@ var FriendliAIChatLanguageModel = class {
411
372
  return;
412
373
  }
413
374
  const delta = choice.delta;
375
+ if (delta.reasoning_content != null) {
376
+ controller.enqueue({
377
+ type: "reasoning",
378
+ text: delta.reasoning_content
379
+ });
380
+ }
414
381
  if (delta.content != null) {
415
382
  controller.enqueue({
416
- type: "text-delta",
417
- textDelta: delta.content
383
+ type: "text",
384
+ text: delta.content
418
385
  });
419
386
  }
420
387
  if (delta.tool_calls != null) {
@@ -433,7 +400,7 @@ var FriendliAIChatLanguageModel = class {
433
400
  message: `Expected 'id' to be a string.`
434
401
  });
435
402
  }
436
- if (((_c = toolCallDelta.function) == null ? void 0 : _c.name) == null) {
403
+ if (((_a2 = toolCallDelta.function) == null ? void 0 : _a2.name) == null) {
437
404
  throw new import_provider2.InvalidResponseDataError({
438
405
  data: toolCallDelta,
439
406
  message: `Expected 'function.name' to be a string.`
@@ -444,11 +411,12 @@ var FriendliAIChatLanguageModel = class {
444
411
  type: "function",
445
412
  function: {
446
413
  name: toolCallDelta.function.name,
447
- arguments: (_d = toolCallDelta.function.arguments) != null ? _d : ""
448
- }
414
+ arguments: (_b = toolCallDelta.function.arguments) != null ? _b : ""
415
+ },
416
+ hasFinished: false
449
417
  };
450
418
  const toolCall2 = toolCalls[index];
451
- if (((_e = toolCall2.function) == null ? void 0 : _e.name) != null && ((_f = toolCall2.function) == null ? void 0 : _f.arguments) != null) {
419
+ if (((_c = toolCall2.function) == null ? void 0 : _c.name) != null && ((_d = toolCall2.function) == null ? void 0 : _d.arguments) != null) {
452
420
  if (toolCall2.function.arguments.length > 0) {
453
421
  controller.enqueue({
454
422
  type: "tool-call-delta",
@@ -462,55 +430,71 @@ var FriendliAIChatLanguageModel = class {
462
430
  controller.enqueue({
463
431
  type: "tool-call",
464
432
  toolCallType: "function",
465
- toolCallId: (_g = toolCall2.id) != null ? _g : (0, import_provider_utils2.generateId)(),
433
+ toolCallId: (_e = toolCall2.id) != null ? _e : (0, import_provider_utils2.generateId)(),
466
434
  toolName: toolCall2.function.name,
467
435
  args: toolCall2.function.arguments
468
436
  });
437
+ toolCall2.hasFinished = true;
469
438
  }
470
439
  }
471
440
  continue;
472
441
  }
473
442
  const toolCall = toolCalls[index];
474
- if (((_h = toolCallDelta.function) == null ? void 0 : _h.arguments) != null) {
475
- toolCall.function.arguments += (_j = (_i = toolCallDelta.function) == null ? void 0 : _i.arguments) != null ? _j : "";
443
+ if (toolCall.hasFinished) {
444
+ continue;
445
+ }
446
+ if (((_f = toolCallDelta.function) == null ? void 0 : _f.arguments) != null) {
447
+ toolCall.function.arguments += (_h = (_g = toolCallDelta.function) == null ? void 0 : _g.arguments) != null ? _h : "";
476
448
  }
477
449
  controller.enqueue({
478
450
  type: "tool-call-delta",
479
451
  toolCallType: "function",
480
452
  toolCallId: toolCall.id,
481
453
  toolName: toolCall.function.name,
482
- argsTextDelta: (_k = toolCallDelta.function.arguments) != null ? _k : ""
454
+ argsTextDelta: (_i = toolCallDelta.function.arguments) != null ? _i : ""
483
455
  });
484
- if (((_l = toolCall.function) == null ? void 0 : _l.name) != null && ((_m = toolCall.function) == null ? void 0 : _m.arguments) != null && (0, import_provider_utils2.isParsableJson)(toolCall.function.arguments)) {
456
+ if (((_j = toolCall.function) == null ? void 0 : _j.name) != null && ((_k = toolCall.function) == null ? void 0 : _k.arguments) != null && (0, import_provider_utils2.isParsableJson)(toolCall.function.arguments)) {
485
457
  controller.enqueue({
486
458
  type: "tool-call",
487
459
  toolCallType: "function",
488
- toolCallId: (_n = toolCall.id) != null ? _n : (0, import_provider_utils2.generateId)(),
460
+ toolCallId: (_l = toolCall.id) != null ? _l : (0, import_provider_utils2.generateId)(),
489
461
  toolName: toolCall.function.name,
490
462
  args: toolCall.function.arguments
491
463
  });
464
+ toolCall.hasFinished = true;
492
465
  }
493
466
  }
494
467
  }
495
468
  },
496
469
  flush(controller) {
497
- var _a, _b;
470
+ var _a2, _b, _c, _d, _e;
471
+ const providerMetadata = {
472
+ [providerOptionsName]: {},
473
+ ...metadataExtractor == null ? void 0 : metadataExtractor.buildMetadata()
474
+ };
475
+ if (usage.completionTokensDetails.acceptedPredictionTokens != null) {
476
+ providerMetadata[providerOptionsName].acceptedPredictionTokens = usage.completionTokensDetails.acceptedPredictionTokens;
477
+ }
478
+ if (usage.completionTokensDetails.rejectedPredictionTokens != null) {
479
+ providerMetadata[providerOptionsName].rejectedPredictionTokens = usage.completionTokensDetails.rejectedPredictionTokens;
480
+ }
498
481
  controller.enqueue({
499
482
  type: "finish",
500
483
  finishReason,
501
484
  usage: {
502
- promptTokens: (_a = usage.promptTokens) != null ? _a : NaN,
503
- completionTokens: (_b = usage.completionTokens) != null ? _b : NaN
485
+ inputTokens: (_a2 = usage.promptTokens) != null ? _a2 : void 0,
486
+ outputTokens: (_b = usage.completionTokens) != null ? _b : void 0,
487
+ totalTokens: (_c = usage.totalTokens) != null ? _c : void 0,
488
+ reasoningTokens: (_d = usage.completionTokensDetails.reasoningTokens) != null ? _d : void 0,
489
+ cachedInputTokens: (_e = usage.promptTokensDetails.cachedTokens) != null ? _e : void 0
504
490
  },
505
- ...providerMetadata != null ? { providerMetadata } : {}
491
+ providerMetadata
506
492
  });
507
493
  }
508
494
  })
509
495
  ),
510
- rawCall: { rawPrompt, rawSettings },
511
- rawResponse: { headers: responseHeaders },
512
- warnings,
513
- request: { body }
496
+ request: { body },
497
+ response: { headers: responseHeaders }
514
498
  };
515
499
  }
516
500
  };
@@ -594,6 +578,75 @@ var friendliaiChatChunkSchema = import_zod2.z.union([
594
578
  }),
595
579
  friendliaiErrorSchema
596
580
  ]);
581
+ var openaiCompatibleTokenUsageSchema = import_zod2.z.object({
582
+ prompt_tokens: import_zod2.z.number().nullish(),
583
+ completion_tokens: import_zod2.z.number().nullish(),
584
+ total_tokens: import_zod2.z.number().nullish(),
585
+ prompt_tokens_details: import_zod2.z.object({
586
+ cached_tokens: import_zod2.z.number().nullish()
587
+ }).nullish(),
588
+ completion_tokens_details: import_zod2.z.object({
589
+ reasoning_tokens: import_zod2.z.number().nullish(),
590
+ accepted_prediction_tokens: import_zod2.z.number().nullish(),
591
+ rejected_prediction_tokens: import_zod2.z.number().nullish()
592
+ }).nullish()
593
+ }).nullish();
594
+ var OpenAICompatibleChatResponseSchema = import_zod2.z.object({
595
+ id: import_zod2.z.string().nullish(),
596
+ created: import_zod2.z.number().nullish(),
597
+ model: import_zod2.z.string().nullish(),
598
+ choices: import_zod2.z.array(
599
+ import_zod2.z.object({
600
+ message: import_zod2.z.object({
601
+ role: import_zod2.z.literal("assistant").nullish(),
602
+ content: import_zod2.z.string().nullish(),
603
+ reasoning_content: import_zod2.z.string().nullish(),
604
+ tool_calls: import_zod2.z.array(
605
+ import_zod2.z.object({
606
+ id: import_zod2.z.string().nullish(),
607
+ type: import_zod2.z.literal("function"),
608
+ function: import_zod2.z.object({
609
+ name: import_zod2.z.string(),
610
+ arguments: import_zod2.z.string()
611
+ })
612
+ })
613
+ ).nullish()
614
+ }),
615
+ finish_reason: import_zod2.z.string().nullish()
616
+ })
617
+ ),
618
+ usage: openaiCompatibleTokenUsageSchema
619
+ });
620
+ var createOpenAICompatibleChatChunkSchema = (errorSchema) => import_zod2.z.union([
621
+ import_zod2.z.object({
622
+ id: import_zod2.z.string().nullish(),
623
+ created: import_zod2.z.number().nullish(),
624
+ model: import_zod2.z.string().nullish(),
625
+ choices: import_zod2.z.array(
626
+ import_zod2.z.object({
627
+ delta: import_zod2.z.object({
628
+ role: import_zod2.z.enum(["assistant"]).nullish(),
629
+ content: import_zod2.z.string().nullish(),
630
+ reasoning_content: import_zod2.z.string().nullish(),
631
+ tool_calls: import_zod2.z.array(
632
+ import_zod2.z.object({
633
+ index: import_zod2.z.number(),
634
+ id: import_zod2.z.string().nullish(),
635
+ type: import_zod2.z.literal("function").nullish(),
636
+ function: import_zod2.z.object({
637
+ name: import_zod2.z.string().nullish(),
638
+ arguments: import_zod2.z.string().nullish()
639
+ })
640
+ })
641
+ ).nullish()
642
+ }).nullish(),
643
+ finish_reason: import_zod2.z.string().nullish()
644
+ })
645
+ ),
646
+ usage: openaiCompatibleTokenUsageSchema
647
+ }),
648
+ errorSchema
649
+ ]);
597
650
 
598
651
  // src/friendli-provider.ts
599
652
  function createFriendli(options = {}) {
@@ -646,28 +699,29 @@ function createFriendli(options = {}) {
646
699
  };
647
700
  }
648
701
  };
649
- const createChatModel = (modelId, settings = {}) => {
702
+ const createChatModel = (modelId) => {
650
703
  const { baseURL, type } = baseURLAutoSelect(
651
704
  modelId,
652
- settings.endpoint || "auto",
653
- options.baseURL,
654
- settings.tools
705
+ // settings.endpoint || 'auto',
706
+ "auto",
707
+ options.baseURL
708
+ // settings.tools,
655
709
  );
656
- return new FriendliAIChatLanguageModel(modelId, settings, {
710
+ return new FriendliAIChatLanguageModel(modelId, {
657
711
  provider: `friendliai.${type}.chat`,
658
712
  url: ({ path }) => `${baseURL}${path}`,
659
713
  headers: getHeaders,
660
- fetch: options.fetch,
661
- defaultObjectGenerationMode: "json"
714
+ fetch: options.fetch
662
715
  });
663
716
  };
664
- const createCompletionModel = (modelId, settings = {}) => {
717
+ const createCompletionModel = (modelId) => {
665
718
  const { baseURL, type } = baseURLAutoSelect(
666
719
  modelId,
667
- settings.endpoint || "auto",
720
+ // settings.endpoint || 'auto',
721
+ "auto",
668
722
  options.baseURL
669
723
  );
670
- return new import_openai_compatible.OpenAICompatibleCompletionLanguageModel(modelId, settings, {
724
+ return new import_openai_compatible.OpenAICompatibleCompletionLanguageModel(modelId, {
671
725
  provider: `friendliai.${type}.completion`,
672
726
  url: ({ path }) => `${baseURL}${path}`,
673
727
  headers: getHeaders,
@@ -675,25 +729,24 @@ function createFriendli(options = {}) {
675
729
  errorStructure: friendliaiErrorStructure
676
730
  });
677
731
  };
678
- const createBetaModel = (modelId, settings = {}) => {
732
+ const createBetaModel = (modelId) => {
679
733
  const { baseURL, type } = baseURLAutoSelect(
680
734
  modelId,
681
735
  "beta",
682
736
  options.baseURL
683
737
  );
684
- return new FriendliAIChatLanguageModel(modelId, settings, {
738
+ return new FriendliAIChatLanguageModel(modelId, {
685
739
  provider: `friendliai.${type}.chat`,
686
740
  url: ({ path }) => `${baseURL}${path}`,
687
741
  headers: getHeaders,
688
- fetch: options.fetch,
689
- defaultObjectGenerationMode: "json"
742
+ fetch: options.fetch
690
743
  });
691
744
  };
692
745
  const createTextEmbeddingModel = (modelId) => {
693
746
  throw new import_provider3.NoSuchModelError({ modelId, modelType: "textEmbeddingModel" });
694
747
  };
695
- const provider = function(modelId, settings) {
696
- return createChatModel(modelId, settings);
748
+ const provider = function(modelId) {
749
+ return createChatModel(modelId);
697
750
  };
698
751
  provider.beta = createBetaModel;
699
752
  provider.chat = createChatModel;