@gitlab/gitlab-ai-provider 3.1.2 → 3.1.3

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
@@ -143,8 +143,6 @@ var GitLabDirectAccessClient = class {
143
143
  };
144
144
 
145
145
  // src/gitlab-agentic-language-model.ts
146
- var debugLog = (..._args) => {
147
- };
148
146
  var GitLabAgenticLanguageModel = class {
149
147
  specificationVersion = "v2";
150
148
  modelId;
@@ -173,14 +171,7 @@ var GitLabAgenticLanguageModel = class {
173
171
  */
174
172
  async getAnthropicClient(forceRefresh = false) {
175
173
  const tokenData = await this.directAccessClient.getDirectAccessToken(forceRefresh);
176
- debugLog("[gitlab-ai-provider] Token headers from GitLab:", tokenData.headers);
177
- debugLog("[gitlab-ai-provider] Proxy URL:", this.directAccessClient.getAnthropicProxyUrl());
178
174
  const { "x-api-key": _removed, ...filteredHeaders } = tokenData.headers;
179
- if (_removed) {
180
- debugLog(
181
- "[gitlab-ai-provider] Filtered out x-api-key from headers (using authToken instead)"
182
- );
183
- }
184
175
  this.anthropicClient = new Anthropic({
185
176
  apiKey: null,
186
177
  authToken: tokenData.token,
@@ -419,114 +410,155 @@ var GitLabAgenticLanguageModel = class {
419
410
  const self = this;
420
411
  const stream = new ReadableStream({
421
412
  start: async (controller) => {
413
+ const contentBlocks = {};
414
+ const usage = {
415
+ inputTokens: 0,
416
+ outputTokens: 0,
417
+ totalTokens: 0
418
+ };
419
+ let finishReason = "unknown";
422
420
  try {
423
- const anthropicStream = client.messages.stream(requestBody);
424
- let currentTextBlockId = null;
425
- let currentToolBlockId = null;
426
- let currentToolName = null;
427
- const usage = {
428
- inputTokens: 0,
429
- outputTokens: 0,
430
- totalTokens: 0
431
- };
432
- let finishReason = "unknown";
421
+ const anthropicStream = client.messages.stream(requestBody, {
422
+ signal: options.abortSignal
423
+ });
433
424
  controller.enqueue({
434
425
  type: "stream-start",
435
426
  warnings: []
436
427
  });
437
- for await (const event of anthropicStream) {
438
- switch (event.type) {
439
- case "message_start":
440
- if (event.message.usage) {
441
- usage.inputTokens = event.message.usage.input_tokens;
442
- }
443
- controller.enqueue({
444
- type: "response-metadata",
445
- id: event.message.id,
446
- modelId: event.message.model
447
- });
448
- break;
449
- case "content_block_start":
450
- if (event.content_block.type === "text") {
451
- currentTextBlockId = `text-${event.index}`;
452
- controller.enqueue({
453
- type: "text-start",
454
- id: currentTextBlockId
455
- });
456
- } else if (event.content_block.type === "tool_use") {
457
- currentToolBlockId = event.content_block.id;
458
- currentToolName = event.content_block.name;
459
- controller.enqueue({
460
- type: "tool-input-start",
461
- id: currentToolBlockId,
462
- toolName: currentToolName
463
- });
464
- }
465
- break;
466
- case "content_block_delta":
467
- if (event.delta.type === "text_delta" && currentTextBlockId) {
468
- controller.enqueue({
469
- type: "text-delta",
470
- id: currentTextBlockId,
471
- delta: event.delta.text
472
- });
473
- } else if (event.delta.type === "input_json_delta" && currentToolBlockId) {
474
- controller.enqueue({
475
- type: "tool-input-delta",
476
- id: currentToolBlockId,
477
- delta: event.delta.partial_json
478
- });
479
- }
480
- break;
481
- case "content_block_stop":
482
- if (currentTextBlockId) {
483
- controller.enqueue({
484
- type: "text-end",
485
- id: currentTextBlockId
486
- });
487
- currentTextBlockId = null;
488
- }
489
- if (currentToolBlockId) {
490
- controller.enqueue({
491
- type: "tool-input-end",
492
- id: currentToolBlockId
493
- });
494
- currentToolBlockId = null;
495
- currentToolName = null;
496
- }
497
- break;
498
- case "message_delta":
499
- if (event.usage) {
500
- usage.outputTokens = event.usage.output_tokens;
501
- usage.totalTokens = (usage.inputTokens || 0) + event.usage.output_tokens;
502
- }
503
- if (event.delta.stop_reason) {
504
- finishReason = self.convertFinishReason(event.delta.stop_reason);
505
- }
506
- break;
507
- case "message_stop": {
508
- const finalMessage = await anthropicStream.finalMessage();
509
- for (const block of finalMessage.content) {
510
- if (block.type === "tool_use") {
428
+ await new Promise((resolve2, reject) => {
429
+ anthropicStream.on("streamEvent", (event) => {
430
+ try {
431
+ switch (event.type) {
432
+ case "message_start":
433
+ if (event.message.usage) {
434
+ usage.inputTokens = event.message.usage.input_tokens;
435
+ }
511
436
  controller.enqueue({
512
- type: "tool-call",
513
- toolCallId: block.id,
514
- toolName: block.name,
515
- input: JSON.stringify(block.input)
437
+ type: "response-metadata",
438
+ id: event.message.id,
439
+ modelId: event.message.model
516
440
  });
441
+ break;
442
+ case "content_block_start":
443
+ if (event.content_block.type === "text") {
444
+ const textId = `text-${event.index}`;
445
+ contentBlocks[event.index] = { type: "text", id: textId };
446
+ controller.enqueue({
447
+ type: "text-start",
448
+ id: textId
449
+ });
450
+ } else if (event.content_block.type === "tool_use") {
451
+ contentBlocks[event.index] = {
452
+ type: "tool-call",
453
+ toolCallId: event.content_block.id,
454
+ toolName: event.content_block.name,
455
+ input: ""
456
+ };
457
+ controller.enqueue({
458
+ type: "tool-input-start",
459
+ id: event.content_block.id,
460
+ toolName: event.content_block.name
461
+ });
462
+ }
463
+ break;
464
+ case "content_block_delta": {
465
+ const block = contentBlocks[event.index];
466
+ if (event.delta.type === "text_delta" && block?.type === "text") {
467
+ controller.enqueue({
468
+ type: "text-delta",
469
+ id: block.id,
470
+ delta: event.delta.text
471
+ });
472
+ } else if (event.delta.type === "input_json_delta" && block?.type === "tool-call") {
473
+ block.input += event.delta.partial_json;
474
+ controller.enqueue({
475
+ type: "tool-input-delta",
476
+ id: block.toolCallId,
477
+ delta: event.delta.partial_json
478
+ });
479
+ }
480
+ break;
481
+ }
482
+ case "content_block_stop": {
483
+ const block = contentBlocks[event.index];
484
+ if (block?.type === "text") {
485
+ controller.enqueue({
486
+ type: "text-end",
487
+ id: block.id
488
+ });
489
+ } else if (block?.type === "tool-call") {
490
+ controller.enqueue({
491
+ type: "tool-input-end",
492
+ id: block.toolCallId
493
+ });
494
+ controller.enqueue({
495
+ type: "tool-call",
496
+ toolCallId: block.toolCallId,
497
+ toolName: block.toolName,
498
+ input: block.input === "" ? "{}" : block.input
499
+ });
500
+ }
501
+ delete contentBlocks[event.index];
502
+ break;
503
+ }
504
+ case "message_delta":
505
+ if (event.usage) {
506
+ usage.outputTokens = event.usage.output_tokens;
507
+ usage.totalTokens = (usage.inputTokens || 0) + event.usage.output_tokens;
508
+ }
509
+ if (event.delta.stop_reason) {
510
+ finishReason = self.convertFinishReason(event.delta.stop_reason);
511
+ }
512
+ break;
513
+ case "message_stop": {
514
+ controller.enqueue({
515
+ type: "finish",
516
+ finishReason,
517
+ usage
518
+ });
519
+ break;
517
520
  }
518
521
  }
519
- controller.enqueue({
520
- type: "finish",
521
- finishReason,
522
- usage
523
- });
524
- break;
522
+ } catch {
525
523
  }
524
+ });
525
+ anthropicStream.on("end", () => {
526
+ resolve2();
527
+ });
528
+ anthropicStream.on("error", (error) => {
529
+ reject(error);
530
+ });
531
+ });
532
+ for (const [, block] of Object.entries(contentBlocks)) {
533
+ if (block.type === "tool-call") {
534
+ controller.enqueue({
535
+ type: "tool-input-end",
536
+ id: block.toolCallId
537
+ });
538
+ controller.enqueue({
539
+ type: "tool-call",
540
+ toolCallId: block.toolCallId,
541
+ toolName: block.toolName,
542
+ input: block.input === "" ? "{}" : block.input
543
+ });
526
544
  }
527
545
  }
528
546
  controller.close();
529
547
  } catch (error) {
548
+ for (const [, block] of Object.entries(contentBlocks)) {
549
+ if (block.type === "tool-call") {
550
+ controller.enqueue({
551
+ type: "tool-input-end",
552
+ id: block.toolCallId
553
+ });
554
+ controller.enqueue({
555
+ type: "tool-call",
556
+ toolCallId: block.toolCallId,
557
+ toolName: block.toolName,
558
+ input: block.input === "" ? "{}" : block.input
559
+ });
560
+ }
561
+ }
530
562
  if (!isRetry && self.isTokenError(error)) {
531
563
  self.directAccessClient.invalidateToken();
532
564
  controller.enqueue({
@@ -996,7 +1028,7 @@ var GitLabProjectCache = class {
996
1028
  };
997
1029
 
998
1030
  // src/gitlab-project-detector.ts
999
- var debugLog2 = (..._args) => {
1031
+ var debugLog = (..._args) => {
1000
1032
  };
1001
1033
  var GitLabProjectDetector = class {
1002
1034
  config;
@@ -1025,35 +1057,35 @@ var GitLabProjectDetector = class {
1025
1057
  return cached;
1026
1058
  }
1027
1059
  try {
1028
- debugLog2(`[GitLabProjectDetector] Getting git remote URL from: ${workingDirectory}`);
1060
+ debugLog(`[GitLabProjectDetector] Getting git remote URL from: ${workingDirectory}`);
1029
1061
  const remoteUrl = await this.getGitRemoteUrl(workingDirectory, remoteName);
1030
1062
  if (!remoteUrl) {
1031
- debugLog2(`[GitLabProjectDetector] No git remote URL found`);
1063
+ debugLog(`[GitLabProjectDetector] No git remote URL found`);
1032
1064
  return null;
1033
1065
  }
1034
- debugLog2(`[GitLabProjectDetector] Git remote URL: ${remoteUrl}`);
1035
- debugLog2(
1066
+ debugLog(`[GitLabProjectDetector] Git remote URL: ${remoteUrl}`);
1067
+ debugLog(
1036
1068
  `[GitLabProjectDetector] Parsing project path from URL (instance: ${this.config.instanceUrl})`
1037
1069
  );
1038
1070
  const projectPath = this.parseGitRemoteUrl(remoteUrl, this.config.instanceUrl);
1039
1071
  if (!projectPath) {
1040
- debugLog2(
1072
+ debugLog(
1041
1073
  `[GitLabProjectDetector] Could not parse project path from URL (remote doesn't match instance)`
1042
1074
  );
1043
1075
  return null;
1044
1076
  }
1045
- debugLog2(`[GitLabProjectDetector] Parsed project path: ${projectPath}`);
1046
- debugLog2(`[GitLabProjectDetector] Fetching project from GitLab API: ${projectPath}`);
1077
+ debugLog(`[GitLabProjectDetector] Parsed project path: ${projectPath}`);
1078
+ debugLog(`[GitLabProjectDetector] Fetching project from GitLab API: ${projectPath}`);
1047
1079
  const project = await this.getProjectByPath(projectPath);
1048
- debugLog2(`[GitLabProjectDetector] \u2713 Project fetched successfully:`, project);
1080
+ debugLog(`[GitLabProjectDetector] \u2713 Project fetched successfully:`, project);
1049
1081
  this.cache.set(cacheKey, project);
1050
1082
  return project;
1051
1083
  } catch (error) {
1052
1084
  if (error instanceof GitLabError) {
1053
- debugLog2(`[GitLabProjectDetector] GitLab API error:`, error.message || error);
1085
+ debugLog(`[GitLabProjectDetector] GitLab API error:`, error.message || error);
1054
1086
  return null;
1055
1087
  }
1056
- debugLog2(`[GitLabProjectDetector] Unexpected error:`, error);
1088
+ debugLog(`[GitLabProjectDetector] Unexpected error:`, error);
1057
1089
  console.warn(`Failed to auto-detect GitLab project: ${error}`);
1058
1090
  return null;
1059
1091
  }