@dianshuv/copilot-api 0.7.6 → 0.7.7

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.
Files changed (2) hide show
  1. package/dist/main.mjs +71 -14
  2. package/package.json +1 -1
package/dist/main.mjs CHANGED
@@ -1213,7 +1213,7 @@ const patchClaude = defineCommand({
1213
1213
 
1214
1214
  //#endregion
1215
1215
  //#region package.json
1216
- var version = "0.7.6";
1216
+ var version = "0.7.7";
1217
1217
 
1218
1218
  //#endregion
1219
1219
  //#region src/lib/adaptive-rate-limiter.ts
@@ -2272,6 +2272,11 @@ function captureRequest(params) {
2272
2272
  };
2273
2273
  if (params.reasoningTokens !== void 0) properties.reasoning_tokens = params.reasoningTokens;
2274
2274
  if (params.stopReason !== void 0) properties.stop_reason = params.stopReason;
2275
+ if (params.status !== void 0) properties.status = params.status;
2276
+ if (params.copilotErrorCode !== void 0) properties.copilot_error_code = params.copilotErrorCode;
2277
+ if (params.errorPhase !== void 0) properties.error_phase = params.errorPhase;
2278
+ if (params.endpoint !== void 0) properties.endpoint = params.endpoint;
2279
+ if (params.attempt !== void 0) properties.attempt = params.attempt;
2275
2280
  client.capture({
2276
2281
  distinctId,
2277
2282
  event: "copilot_api_request",
@@ -3632,6 +3637,18 @@ async function autoTruncateOpenAI(payload, model, config = {}) {
3632
3637
  };
3633
3638
  }
3634
3639
 
3640
+ //#endregion
3641
+ //#region src/lib/error-metrics.ts
3642
+ function extractErrorMetrics(error) {
3643
+ if (!(error instanceof HTTPError)) return {};
3644
+ const metrics = { status: error.status };
3645
+ try {
3646
+ const parsed = JSON.parse(error.responseText);
3647
+ if (parsed.error?.code) metrics.copilotErrorCode = parsed.error.code;
3648
+ } catch {}
3649
+ return metrics;
3650
+ }
3651
+
3635
3652
  //#endregion
3636
3653
  //#region src/routes/shared.ts
3637
3654
  /**
@@ -3658,7 +3675,7 @@ function updateTrackerStatus(trackingId, status) {
3658
3675
  requestTracker.updateRequest(trackingId, { status });
3659
3676
  }
3660
3677
  /** Record error response to history */
3661
- function recordErrorResponse(ctx, model, error) {
3678
+ function recordErrorResponse(ctx, model, error, endpoint, stream) {
3662
3679
  recordResponse(ctx.historyId, {
3663
3680
  success: false,
3664
3681
  model,
@@ -3669,6 +3686,23 @@ function recordErrorResponse(ctx, model, error) {
3669
3686
  error: error instanceof Error ? error.message : "Unknown error",
3670
3687
  content: null
3671
3688
  }, Date.now() - ctx.startTime);
3689
+ if (endpoint !== void 0) {
3690
+ const { status, copilotErrorCode } = extractErrorMetrics(error);
3691
+ captureRequest({
3692
+ model,
3693
+ inputTokens: 0,
3694
+ outputTokens: 0,
3695
+ durationMs: Date.now() - ctx.startTime,
3696
+ success: false,
3697
+ stream: stream ?? false,
3698
+ toolCount: 0,
3699
+ status,
3700
+ copilotErrorCode,
3701
+ errorPhase: stream ? "pre_stream" : "non_stream",
3702
+ endpoint,
3703
+ attempt: 1
3704
+ });
3705
+ }
3672
3706
  }
3673
3707
  /** Complete TUI tracking and send PostHog analytics */
3674
3708
  function completeTracking(trackingId, inputTokens, outputTokens, queueWaitMs, reasoningTokens, analytics) {
@@ -3727,10 +3761,11 @@ function createTruncationMarker$1(result) {
3727
3761
  }
3728
3762
  /** Record streaming error to history (works with any accumulator type) */
3729
3763
  function recordStreamError(opts) {
3730
- const { acc, fallbackModel, ctx, error } = opts;
3764
+ const { acc, fallbackModel, ctx, error, endpoint } = opts;
3765
+ const model = acc.model || fallbackModel;
3731
3766
  recordResponse(ctx.historyId, {
3732
3767
  success: false,
3733
- model: acc.model || fallbackModel,
3768
+ model,
3734
3769
  usage: {
3735
3770
  input_tokens: 0,
3736
3771
  output_tokens: 0
@@ -3738,6 +3773,23 @@ function recordStreamError(opts) {
3738
3773
  error: formatError(error),
3739
3774
  content: null
3740
3775
  }, Date.now() - ctx.startTime);
3776
+ if (endpoint !== void 0) {
3777
+ const { status, copilotErrorCode } = extractErrorMetrics(error);
3778
+ captureRequest({
3779
+ model,
3780
+ inputTokens: acc.inputTokens ?? 0,
3781
+ outputTokens: acc.outputTokens ?? 0,
3782
+ durationMs: Date.now() - ctx.startTime,
3783
+ success: false,
3784
+ stream: true,
3785
+ toolCount: 0,
3786
+ status,
3787
+ copilotErrorCode,
3788
+ errorPhase: "mid_stream",
3789
+ endpoint,
3790
+ attempt: 1
3791
+ });
3792
+ }
3741
3793
  }
3742
3794
  /** Type guard for non-streaming responses */
3743
3795
  function isNonStreaming(response) {
@@ -3889,7 +3941,7 @@ async function executeRequest(opts) {
3889
3941
  });
3890
3942
  } catch (error) {
3891
3943
  if (error instanceof HTTPError && error.status === 413) await logPayloadSizeInfo(payload, selectedModel);
3892
- recordErrorResponse(ctx, payload.model, error);
3944
+ recordErrorResponse(ctx, payload.model, error, "chat_completions", payload.stream ?? false);
3893
3945
  throw error;
3894
3946
  }
3895
3947
  }
@@ -4031,7 +4083,8 @@ async function handleStreamingResponse$1(opts) {
4031
4083
  acc,
4032
4084
  fallbackModel: payload.model,
4033
4085
  ctx,
4034
- error
4086
+ error,
4087
+ endpoint: "chat_completions"
4035
4088
  });
4036
4089
  failTracking(ctx.trackingId, error);
4037
4090
  throw error;
@@ -4575,7 +4628,8 @@ async function handleGeminiGenerate(c, model, isStream) {
4575
4628
  acc: { model: streamState.model || model },
4576
4629
  fallbackModel: model,
4577
4630
  ctx,
4578
- error
4631
+ error,
4632
+ endpoint: "chat_completions"
4579
4633
  });
4580
4634
  failTracking(ctx.trackingId, error);
4581
4635
  }
@@ -7546,7 +7600,7 @@ async function handleDirectAnthropicCompletion(c, anthropicPayload, ctx, initiat
7546
7600
  return handleDirectAnthropicNonStreamingResponse(c, response, ctx, truncateResult, effectivePayload);
7547
7601
  } catch (error) {
7548
7602
  if (error instanceof HTTPError && error.status === 413) logPayloadSizeInfoAnthropic(effectivePayload, selectedModel);
7549
- recordErrorResponse(ctx, anthropicPayload.model, error);
7603
+ recordErrorResponse(ctx, anthropicPayload.model, error, "messages", anthropicPayload.stream ?? false);
7550
7604
  throw error;
7551
7605
  }
7552
7606
  }
@@ -7664,7 +7718,8 @@ async function handleDirectAnthropicStreamingResponse(opts) {
7664
7718
  acc,
7665
7719
  fallbackModel: anthropicPayload.model,
7666
7720
  ctx,
7667
- error
7721
+ error,
7722
+ endpoint: "messages"
7668
7723
  });
7669
7724
  failTracking(ctx.trackingId, error);
7670
7725
  const errorEvent = translateErrorToAnthropicErrorEvent(error);
@@ -7759,7 +7814,7 @@ async function handleTranslatedCompletion(c, anthropicPayload, ctx, initiatorOve
7759
7814
  });
7760
7815
  } catch (error) {
7761
7816
  if (error instanceof HTTPError && error.status === 413) await logPayloadSizeInfo(openAIPayload, selectedModel);
7762
- recordErrorResponse(ctx, anthropicPayload.model, error);
7817
+ recordErrorResponse(ctx, anthropicPayload.model, error, "messages", anthropicPayload.stream ?? false);
7763
7818
  throw error;
7764
7819
  }
7765
7820
  }
@@ -7850,7 +7905,8 @@ async function handleStreamingResponse(opts) {
7850
7905
  acc,
7851
7906
  fallbackModel: anthropicPayload.model,
7852
7907
  ctx,
7853
- error
7908
+ error,
7909
+ endpoint: "messages"
7854
7910
  });
7855
7911
  failTracking(ctx.trackingId, error);
7856
7912
  const errorEvent = translateErrorToAnthropicErrorEvent(error);
@@ -8363,7 +8419,7 @@ const handleResponses = async (c) => {
8363
8419
  };
8364
8420
  const selectedModel = findModelById(payload.model);
8365
8421
  if (!(selectedModel?.supported_endpoints?.includes(RESPONSES_ENDPOINT) ?? false)) {
8366
- recordErrorResponse(ctx, model, /* @__PURE__ */ new Error("This model does not support the responses endpoint."));
8422
+ recordErrorResponse(ctx, model, /* @__PURE__ */ new Error("This model does not support the responses endpoint."), "responses", stream);
8367
8423
  return c.json({ error: {
8368
8424
  message: "This model does not support the responses endpoint. Please choose a different model.",
8369
8425
  type: "invalid_request_error"
@@ -8429,7 +8485,8 @@ const handleResponses = async (c) => {
8429
8485
  acc: { model: finalResult?.model || model },
8430
8486
  fallbackModel: model,
8431
8487
  ctx,
8432
- error
8488
+ error,
8489
+ endpoint: "responses"
8433
8490
  });
8434
8491
  failTracking(trackingId, error);
8435
8492
  throw error;
@@ -8448,7 +8505,7 @@ const handleResponses = async (c) => {
8448
8505
  consola.debug("Forwarding native Responses result:", JSON.stringify(result).slice(-400));
8449
8506
  return c.json(result);
8450
8507
  } catch (error) {
8451
- recordErrorResponse(ctx, model, error);
8508
+ recordErrorResponse(ctx, model, error, "responses", stream);
8452
8509
  failTracking(trackingId, error);
8453
8510
  throw error;
8454
8511
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dianshuv/copilot-api",
3
- "version": "0.7.6",
3
+ "version": "0.7.7",
4
4
  "description": "Turn GitHub Copilot into OpenAI/Anthropic API compatible server. Usable with Claude Code!",
5
5
  "author": "dianshuv",
6
6
  "type": "module",