gitlab-ai-provider 5.3.3 → 6.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
@@ -242,7 +242,7 @@ var GitLabDirectAccessClient = class {
242
242
 
243
243
  // src/gitlab-anthropic-language-model.ts
244
244
  var GitLabAnthropicLanguageModel = class {
245
- specificationVersion = "v2";
245
+ specificationVersion = "v3";
246
246
  modelId;
247
247
  supportedUrls = {};
248
248
  config;
@@ -401,10 +401,14 @@ ${message.content}` : message.content;
401
401
  resultContent = part.output.value;
402
402
  } else if (part.output.type === "json") {
403
403
  resultContent = JSON.stringify(part.output.value);
404
+ } else if (part.output.type === "content") {
405
+ resultContent = JSON.stringify(part.output.value);
404
406
  } else if (part.output.type === "error-text") {
405
407
  resultContent = part.output.value;
406
408
  } else if (part.output.type === "error-json") {
407
409
  resultContent = JSON.stringify(part.output.value);
410
+ } else if (part.output.type === "execution-denied") {
411
+ resultContent = part.output.reason ?? "Tool execution denied.";
408
412
  } else {
409
413
  resultContent = JSON.stringify(part.output);
410
414
  }
@@ -427,18 +431,41 @@ ${message.content}` : message.content;
427
431
  * Convert Anthropic finish reason to AI SDK format
428
432
  */
429
433
  convertFinishReason(stopReason) {
430
- switch (stopReason) {
431
- case "end_turn":
432
- return "stop";
433
- case "stop_sequence":
434
- return "stop";
435
- case "max_tokens":
436
- return "length";
437
- case "tool_use":
438
- return "tool-calls";
439
- default:
440
- return "unknown";
441
- }
434
+ const unified = (() => {
435
+ switch (stopReason) {
436
+ case "end_turn":
437
+ return "stop";
438
+ case "stop_sequence":
439
+ return "stop";
440
+ case "max_tokens":
441
+ return "length";
442
+ case "tool_use":
443
+ return "tool-calls";
444
+ default:
445
+ return "other";
446
+ }
447
+ })();
448
+ return { unified, raw: stopReason ?? void 0 };
449
+ }
450
+ createUsage(params) {
451
+ const inputTotal = params?.inputTotal;
452
+ const outputTotal = params?.outputTotal;
453
+ const cacheRead = params?.cacheRead;
454
+ const cacheWrite = params?.cacheWrite;
455
+ return {
456
+ inputTokens: {
457
+ total: inputTotal,
458
+ noCache: inputTotal == null ? void 0 : Math.max(0, inputTotal - (cacheRead ?? 0) - (cacheWrite ?? 0)),
459
+ cacheRead,
460
+ cacheWrite
461
+ },
462
+ outputTokens: {
463
+ total: outputTotal,
464
+ text: outputTotal,
465
+ reasoning: params?.outputReasoning
466
+ },
467
+ raw: params?.raw
468
+ };
442
469
  }
443
470
  async doGenerate(options) {
444
471
  return this.doGenerateWithRetry(options, false);
@@ -478,11 +505,13 @@ ${message.content}` : message.content;
478
505
  });
479
506
  }
480
507
  }
481
- const usage = {
482
- inputTokens: response.usage.input_tokens,
483
- outputTokens: response.usage.output_tokens,
484
- totalTokens: response.usage.input_tokens + response.usage.output_tokens
485
- };
508
+ const rawUsage = response.usage;
509
+ const usage = this.createUsage({
510
+ inputTotal: response.usage.input_tokens,
511
+ outputTotal: response.usage.output_tokens,
512
+ cacheRead: rawUsage.cache_read_input_tokens,
513
+ cacheWrite: rawUsage.cache_creation_input_tokens
514
+ });
486
515
  return {
487
516
  content,
488
517
  finishReason: this.convertFinishReason(response.stop_reason),
@@ -538,12 +567,8 @@ ${message.content}` : message.content;
538
567
  const stream = new ReadableStream({
539
568
  start: async (controller) => {
540
569
  const contentBlocks = {};
541
- const usage = {
542
- inputTokens: 0,
543
- outputTokens: 0,
544
- totalTokens: 0
545
- };
546
- let finishReason = "unknown";
570
+ let usage = self.createUsage();
571
+ let finishReason = { unified: "other", raw: void 0 };
547
572
  try {
548
573
  const anthropicStream = client.messages.stream(requestBody, {
549
574
  signal: options.abortSignal
@@ -558,7 +583,14 @@ ${message.content}` : message.content;
558
583
  switch (event.type) {
559
584
  case "message_start":
560
585
  if (event.message.usage) {
561
- usage.inputTokens = event.message.usage.input_tokens;
586
+ usage = self.createUsage({
587
+ inputTotal: event.message.usage.input_tokens,
588
+ outputTotal: usage.outputTokens.total,
589
+ outputReasoning: usage.outputTokens.reasoning,
590
+ cacheRead: usage.inputTokens.cacheRead,
591
+ cacheWrite: usage.inputTokens.cacheWrite,
592
+ raw: usage.raw
593
+ });
562
594
  }
563
595
  controller.enqueue({
564
596
  type: "response-metadata",
@@ -630,8 +662,14 @@ ${message.content}` : message.content;
630
662
  }
631
663
  case "message_delta":
632
664
  if (event.usage) {
633
- usage.outputTokens = event.usage.output_tokens;
634
- usage.totalTokens = (usage.inputTokens || 0) + event.usage.output_tokens;
665
+ usage = self.createUsage({
666
+ inputTotal: usage.inputTokens.total,
667
+ outputTotal: event.usage.output_tokens,
668
+ outputReasoning: usage.outputTokens.reasoning,
669
+ cacheRead: usage.inputTokens.cacheRead,
670
+ cacheWrite: usage.inputTokens.cacheWrite,
671
+ raw: usage.raw
672
+ });
635
673
  }
636
674
  if (event.delta.stop_reason) {
637
675
  finishReason = self.convertFinishReason(event.delta.stop_reason);
@@ -831,7 +869,7 @@ var MODEL_ID_TO_ANTHROPIC_MODEL = Object.fromEntries(
831
869
 
832
870
  // src/gitlab-openai-language-model.ts
833
871
  var GitLabOpenAILanguageModel = class {
834
- specificationVersion = "v2";
872
+ specificationVersion = "v3";
835
873
  modelId;
836
874
  supportedUrls = {};
837
875
  config;
@@ -977,10 +1015,14 @@ var GitLabOpenAILanguageModel = class {
977
1015
  resultContent = part.output.value;
978
1016
  } else if (part.output.type === "json") {
979
1017
  resultContent = JSON.stringify(part.output.value);
1018
+ } else if (part.output.type === "content") {
1019
+ resultContent = JSON.stringify(part.output.value);
980
1020
  } else if (part.output.type === "error-text") {
981
1021
  resultContent = part.output.value;
982
1022
  } else if (part.output.type === "error-json") {
983
1023
  resultContent = JSON.stringify(part.output.value);
1024
+ } else if (part.output.type === "execution-denied") {
1025
+ resultContent = part.output.reason ?? "Tool execution denied.";
984
1026
  } else {
985
1027
  resultContent = JSON.stringify(part.output);
986
1028
  }
@@ -996,18 +1038,40 @@ var GitLabOpenAILanguageModel = class {
996
1038
  return messages;
997
1039
  }
998
1040
  convertFinishReason(finishReason) {
999
- switch (finishReason) {
1000
- case "stop":
1001
- return "stop";
1002
- case "length":
1003
- return "length";
1004
- case "tool_calls":
1005
- return "tool-calls";
1006
- case "content_filter":
1007
- return "content-filter";
1008
- default:
1009
- return "unknown";
1010
- }
1041
+ const unified = (() => {
1042
+ switch (finishReason) {
1043
+ case "stop":
1044
+ return "stop";
1045
+ case "length":
1046
+ return "length";
1047
+ case "tool_calls":
1048
+ return "tool-calls";
1049
+ case "content_filter":
1050
+ return "content-filter";
1051
+ default:
1052
+ return "other";
1053
+ }
1054
+ })();
1055
+ return { unified, raw: finishReason ?? void 0 };
1056
+ }
1057
+ createUsage(params) {
1058
+ const inputTotal = params?.inputTotal;
1059
+ const outputTotal = params?.outputTotal;
1060
+ const cacheRead = params?.cacheRead;
1061
+ return {
1062
+ inputTokens: {
1063
+ total: inputTotal,
1064
+ noCache: inputTotal == null ? void 0 : Math.max(0, inputTotal - (cacheRead ?? 0)),
1065
+ cacheRead,
1066
+ cacheWrite: void 0
1067
+ },
1068
+ outputTokens: {
1069
+ total: outputTotal,
1070
+ text: outputTotal,
1071
+ reasoning: params?.outputReasoning
1072
+ },
1073
+ raw: params?.raw
1074
+ };
1011
1075
  }
1012
1076
  /**
1013
1077
  * Convert tools to Responses API format
@@ -1024,7 +1088,7 @@ var GitLabOpenAILanguageModel = class {
1024
1088
  name: tool.name,
1025
1089
  description: tool.description || "",
1026
1090
  parameters: schema,
1027
- strict: false
1091
+ strict: tool.strict
1028
1092
  };
1029
1093
  });
1030
1094
  }
@@ -1075,10 +1139,14 @@ var GitLabOpenAILanguageModel = class {
1075
1139
  resultContent = part.output.value;
1076
1140
  } else if (part.output.type === "json") {
1077
1141
  resultContent = JSON.stringify(part.output.value);
1142
+ } else if (part.output.type === "content") {
1143
+ resultContent = JSON.stringify(part.output.value);
1078
1144
  } else if (part.output.type === "error-text") {
1079
1145
  resultContent = part.output.value;
1080
1146
  } else if (part.output.type === "error-json") {
1081
1147
  resultContent = JSON.stringify(part.output.value);
1148
+ } else if (part.output.type === "execution-denied") {
1149
+ resultContent = part.output.reason ?? "Tool execution denied.";
1082
1150
  } else {
1083
1151
  resultContent = JSON.stringify(part.output);
1084
1152
  }
@@ -1107,20 +1175,23 @@ var GitLabOpenAILanguageModel = class {
1107
1175
  */
1108
1176
  convertResponsesStatus(status, hasToolCalls = false) {
1109
1177
  if (hasToolCalls) {
1110
- return "tool-calls";
1111
- }
1112
- switch (status) {
1113
- case "completed":
1114
- return "stop";
1115
- case "incomplete":
1116
- return "length";
1117
- case "cancelled":
1118
- return "stop";
1119
- case "failed":
1120
- return "error";
1121
- default:
1122
- return "unknown";
1123
- }
1178
+ return { unified: "tool-calls", raw: status };
1179
+ }
1180
+ const unified = (() => {
1181
+ switch (status) {
1182
+ case "completed":
1183
+ return "stop";
1184
+ case "incomplete":
1185
+ return "length";
1186
+ case "cancelled":
1187
+ return "stop";
1188
+ case "failed":
1189
+ return "error";
1190
+ default:
1191
+ return "other";
1192
+ }
1193
+ })();
1194
+ return { unified, raw: status };
1124
1195
  }
1125
1196
  async doGenerate(options) {
1126
1197
  if (this.useResponsesApi) {
@@ -1163,11 +1234,12 @@ var GitLabOpenAILanguageModel = class {
1163
1234
  }
1164
1235
  }
1165
1236
  }
1166
- const usage = {
1167
- inputTokens: response.usage?.prompt_tokens || 0,
1168
- outputTokens: response.usage?.completion_tokens || 0,
1169
- totalTokens: response.usage?.total_tokens || 0
1170
- };
1237
+ const usage = this.createUsage({
1238
+ inputTotal: response.usage?.prompt_tokens,
1239
+ outputTotal: response.usage?.completion_tokens,
1240
+ cacheRead: response.usage?.prompt_tokens_details?.cached_tokens,
1241
+ raw: { total_tokens: response.usage?.total_tokens }
1242
+ });
1171
1243
  return {
1172
1244
  content,
1173
1245
  finishReason: this.convertFinishReason(choice?.finish_reason),
@@ -1234,11 +1306,13 @@ var GitLabOpenAILanguageModel = class {
1234
1306
  });
1235
1307
  }
1236
1308
  }
1237
- const usage = {
1238
- inputTokens: response.usage?.input_tokens || 0,
1239
- outputTokens: response.usage?.output_tokens || 0,
1240
- totalTokens: response.usage?.total_tokens || 0
1241
- };
1309
+ const usage = this.createUsage({
1310
+ inputTotal: response.usage?.input_tokens,
1311
+ outputTotal: response.usage?.output_tokens,
1312
+ outputReasoning: response.usage?.output_tokens_details?.reasoning_tokens,
1313
+ cacheRead: response.usage?.input_tokens_details?.cached_tokens,
1314
+ raw: { total_tokens: response.usage?.total_tokens }
1315
+ });
1242
1316
  return {
1243
1317
  content,
1244
1318
  finishReason: this.convertResponsesStatus(response.status, hasToolCalls),
@@ -1297,12 +1371,8 @@ var GitLabOpenAILanguageModel = class {
1297
1371
  const stream = new ReadableStream({
1298
1372
  start: async (controller) => {
1299
1373
  const toolCalls = {};
1300
- const usage = {
1301
- inputTokens: 0,
1302
- outputTokens: 0,
1303
- totalTokens: 0
1304
- };
1305
- let finishReason = "unknown";
1374
+ let usage = self.createUsage();
1375
+ let finishReason = { unified: "other", raw: void 0 };
1306
1376
  let textStarted = false;
1307
1377
  const textId = "text-0";
1308
1378
  try {
@@ -1360,9 +1430,12 @@ var GitLabOpenAILanguageModel = class {
1360
1430
  finishReason = self.convertFinishReason(choice.finish_reason);
1361
1431
  }
1362
1432
  if (chunk.usage) {
1363
- usage.inputTokens = chunk.usage.prompt_tokens || 0;
1364
- usage.outputTokens = chunk.usage.completion_tokens || 0;
1365
- usage.totalTokens = chunk.usage.total_tokens || 0;
1433
+ usage = self.createUsage({
1434
+ inputTotal: chunk.usage.prompt_tokens,
1435
+ outputTotal: chunk.usage.completion_tokens,
1436
+ cacheRead: chunk.usage.prompt_tokens_details?.cached_tokens,
1437
+ raw: { total_tokens: chunk.usage.total_tokens }
1438
+ });
1366
1439
  }
1367
1440
  }
1368
1441
  if (textStarted) {
@@ -1442,12 +1515,8 @@ var GitLabOpenAILanguageModel = class {
1442
1515
  const stream = new ReadableStream({
1443
1516
  start: async (controller) => {
1444
1517
  const toolCalls = {};
1445
- const usage = {
1446
- inputTokens: 0,
1447
- outputTokens: 0,
1448
- totalTokens: 0
1449
- };
1450
- let finishReason = "unknown";
1518
+ let usage = self.createUsage();
1519
+ let finishReason = { unified: "other", raw: void 0 };
1451
1520
  let textStarted = false;
1452
1521
  const textId = "text-0";
1453
1522
  try {
@@ -1509,9 +1578,13 @@ var GitLabOpenAILanguageModel = class {
1509
1578
  const hasToolCalls2 = Object.keys(toolCalls).length > 0;
1510
1579
  finishReason = self.convertResponsesStatus(event.response.status, hasToolCalls2);
1511
1580
  if (event.response.usage) {
1512
- usage.inputTokens = event.response.usage.input_tokens || 0;
1513
- usage.outputTokens = event.response.usage.output_tokens || 0;
1514
- usage.totalTokens = event.response.usage.total_tokens || 0;
1581
+ usage = self.createUsage({
1582
+ inputTotal: event.response.usage.input_tokens,
1583
+ outputTotal: event.response.usage.output_tokens,
1584
+ outputReasoning: event.response.usage.output_tokens_details?.reasoning_tokens,
1585
+ cacheRead: event.response.usage.input_tokens_details?.cached_tokens,
1586
+ raw: { total_tokens: event.response.usage.total_tokens }
1587
+ });
1515
1588
  }
1516
1589
  }
1517
1590
  }
@@ -1519,8 +1592,8 @@ var GitLabOpenAILanguageModel = class {
1519
1592
  controller.enqueue({ type: "text-end", id: textId });
1520
1593
  }
1521
1594
  const hasToolCalls = Object.keys(toolCalls).length > 0;
1522
- if (hasToolCalls && finishReason === "stop") {
1523
- finishReason = "tool-calls";
1595
+ if (hasToolCalls && finishReason.unified === "stop") {
1596
+ finishReason = { unified: "tool-calls", raw: finishReason.raw };
1524
1597
  }
1525
1598
  for (const tc of Object.values(toolCalls)) {
1526
1599
  controller.enqueue({ type: "tool-input-end", id: tc.callId });
@@ -1580,7 +1653,7 @@ var GitLabOpenAILanguageModel = class {
1580
1653
  var import_isomorphic_ws = __toESM(require("isomorphic-ws"));
1581
1654
 
1582
1655
  // src/version.ts
1583
- var VERSION = true ? "5.3.2" : "0.0.0-dev";
1656
+ var VERSION = true ? "5.3.3" : "0.0.0-dev";
1584
1657
 
1585
1658
  // src/gitlab-workflow-types.ts
1586
1659
  var WorkflowType = /* @__PURE__ */ ((WorkflowType2) => {
@@ -2944,7 +3017,7 @@ function minimalSchema(schemaStr) {
2944
3017
  }
2945
3018
  }
2946
3019
  var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
2947
- specificationVersion = "v2";
3020
+ specificationVersion = "v3";
2948
3021
  modelId;
2949
3022
  supportedUrls = {};
2950
3023
  config;
@@ -3245,16 +3318,34 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
3245
3318
  get workflowId() {
3246
3319
  return this.currentWorkflowId;
3247
3320
  }
3321
+ createUsage(params) {
3322
+ return {
3323
+ inputTokens: {
3324
+ total: params?.inputTotal,
3325
+ noCache: params?.inputTotal,
3326
+ cacheRead: void 0,
3327
+ cacheWrite: void 0
3328
+ },
3329
+ outputTokens: {
3330
+ total: params?.outputTotal,
3331
+ text: params?.outputTotal,
3332
+ reasoning: void 0
3333
+ }
3334
+ };
3335
+ }
3336
+ createFinishReason(unified, raw) {
3337
+ return { unified, raw };
3338
+ }
3248
3339
  // ---------------------------------------------------------------------------
3249
- // LanguageModelV2 — doGenerate (non-streaming)
3340
+ // LanguageModelV3 — doGenerate (non-streaming)
3250
3341
  // ---------------------------------------------------------------------------
3251
3342
  async doGenerate(options) {
3252
3343
  const { stream } = await this.doStream(options);
3253
3344
  const reader = stream.getReader();
3254
3345
  const textParts = [];
3255
3346
  const toolCalls = [];
3256
- let finishReason = "unknown";
3257
- const usage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
3347
+ let finishReason = { unified: "other", raw: void 0 };
3348
+ let usage = this.createUsage();
3258
3349
  try {
3259
3350
  while (true) {
3260
3351
  const { done, value } = await reader.read();
@@ -3274,9 +3365,7 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
3274
3365
  case "finish":
3275
3366
  finishReason = value.finishReason;
3276
3367
  if (value.usage) {
3277
- usage.inputTokens = value.usage.inputTokens ?? 0;
3278
- usage.outputTokens = value.usage.outputTokens ?? 0;
3279
- usage.totalTokens = value.usage.totalTokens ?? 0;
3368
+ usage = value.usage;
3280
3369
  }
3281
3370
  break;
3282
3371
  case "error":
@@ -3295,7 +3384,7 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
3295
3384
  return { content, finishReason, usage, warnings: [] };
3296
3385
  }
3297
3386
  // ---------------------------------------------------------------------------
3298
- // LanguageModelV2 — doStream (streaming)
3387
+ // LanguageModelV3 — doStream (streaming)
3299
3388
  // ---------------------------------------------------------------------------
3300
3389
  async doStream(options) {
3301
3390
  const goal = this.extractGoalFromPrompt(options.prompt);
@@ -3561,8 +3650,8 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
3561
3650
  const outputTokens = Math.ceil(ss.streamedOutputChars / 4);
3562
3651
  controller.enqueue({
3563
3652
  type: "finish",
3564
- finishReason: "stop",
3565
- usage: { inputTokens, outputTokens, totalTokens: inputTokens + outputTokens }
3653
+ finishReason: this.createFinishReason("stop", "completed"),
3654
+ usage: this.createUsage({ inputTotal: inputTokens, outputTotal: outputTokens })
3566
3655
  });
3567
3656
  ss.streamClosed = true;
3568
3657
  controller.close();
@@ -3619,8 +3708,8 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
3619
3708
  const outTok = Math.ceil(ss.streamedOutputChars / 4);
3620
3709
  controller.enqueue({
3621
3710
  type: "finish",
3622
- finishReason: "stop",
3623
- usage: { inputTokens: inTok, outputTokens: outTok, totalTokens: inTok + outTok }
3711
+ finishReason: this.createFinishReason("stop", "closed"),
3712
+ usage: this.createUsage({ inputTotal: inTok, outputTotal: outTok })
3624
3713
  });
3625
3714
  ss.streamClosed = true;
3626
3715
  controller.close();
@@ -3737,8 +3826,7 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
3737
3826
  toolCallId: requestID,
3738
3827
  toolName,
3739
3828
  result: errorText,
3740
- isError: true,
3741
- providerExecuted: true
3829
+ isError: true
3742
3830
  });
3743
3831
  } else {
3744
3832
  safeEnqueue({
@@ -3750,8 +3838,7 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
3750
3838
  title: toolTitle,
3751
3839
  metadata: toolMetadata
3752
3840
  },
3753
- isError: false,
3754
- providerExecuted: true
3841
+ isError: false
3755
3842
  });
3756
3843
  }
3757
3844
  } else {
@@ -3762,8 +3849,7 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
3762
3849
  toolCallId: requestID,
3763
3850
  toolName,
3764
3851
  result: errorMsg,
3765
- isError: true,
3766
- providerExecuted: true
3852
+ isError: true
3767
3853
  });
3768
3854
  }
3769
3855
  } catch (error) {
@@ -3775,8 +3861,7 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
3775
3861
  toolCallId: requestID,
3776
3862
  toolName,
3777
3863
  result: errorMsg,
3778
- isError: true,
3779
- providerExecuted: true
3864
+ isError: true
3780
3865
  });
3781
3866
  } finally {
3782
3867
  ss.pendingToolCount--;
@@ -4375,13 +4460,13 @@ function createGitLab(options = {}) {
4375
4460
  return createAgenticChatModel(modelId);
4376
4461
  };
4377
4462
  const provider = Object.assign((modelId) => createDefaultModel(modelId), {
4378
- specificationVersion: "v2",
4463
+ specificationVersion: "v3",
4379
4464
  languageModel: createDefaultModel,
4380
4465
  chat: createDefaultModel,
4381
4466
  agenticChat: createAgenticChatModel,
4382
4467
  workflowChat: createWorkflowChatModel
4383
4468
  });
4384
- provider.textEmbeddingModel = (modelId) => {
4469
+ provider.embeddingModel = (modelId) => {
4385
4470
  throw new GitLabError({
4386
4471
  message: `GitLab provider does not support text embedding models. Model ID: ${modelId}`
4387
4472
  });