@dianshuv/copilot-api 0.7.6 → 0.7.8

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 +104 -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.8";
1217
1217
 
1218
1218
  //#endregion
1219
1219
  //#region src/lib/adaptive-rate-limiter.ts
@@ -2272,6 +2272,16 @@ 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;
2280
+ if (params.errorName !== void 0) properties.error_name = params.errorName;
2281
+ if (params.errorCode !== void 0) properties.error_code = params.errorCode;
2282
+ if (params.causeName !== void 0) properties.cause_name = params.causeName;
2283
+ if (params.causeCode !== void 0) properties.cause_code = params.causeCode;
2284
+ if (params.errorMessage !== void 0) properties.error_message = params.errorMessage;
2275
2285
  client.capture({
2276
2286
  distinctId,
2277
2287
  event: "copilot_api_request",
@@ -3632,6 +3642,48 @@ async function autoTruncateOpenAI(payload, model, config = {}) {
3632
3642
  };
3633
3643
  }
3634
3644
 
3645
+ //#endregion
3646
+ //#region src/lib/error-metrics.ts
3647
+ function safeString(value, max = 200) {
3648
+ try {
3649
+ if (typeof value !== "string") return void 0;
3650
+ return value.length > max ? value.slice(0, max) : value;
3651
+ } catch {
3652
+ return;
3653
+ }
3654
+ }
3655
+ function getStringProp(obj, key, max = 200) {
3656
+ try {
3657
+ if (typeof obj !== "object" || obj === null) return void 0;
3658
+ return safeString(obj[key], max);
3659
+ } catch {
3660
+ return;
3661
+ }
3662
+ }
3663
+ function extractErrorMetrics(error) {
3664
+ if (error instanceof HTTPError) {
3665
+ const metrics = { status: error.status };
3666
+ try {
3667
+ const parsed = JSON.parse(error.responseText);
3668
+ if (parsed.error?.code) metrics.copilotErrorCode = parsed.error.code;
3669
+ } catch {}
3670
+ return metrics;
3671
+ }
3672
+ if (!(error instanceof Error)) return {};
3673
+ const metrics = {};
3674
+ try {
3675
+ metrics.errorName = getStringProp(error, "name");
3676
+ metrics.errorMessage = getStringProp(error, "message");
3677
+ metrics.errorCode = getStringProp(error, "code");
3678
+ const cause = error.cause;
3679
+ if (cause !== void 0 && cause !== null) {
3680
+ metrics.causeName = getStringProp(cause, "name");
3681
+ metrics.causeCode = getStringProp(cause, "code");
3682
+ }
3683
+ } catch {}
3684
+ return metrics;
3685
+ }
3686
+
3635
3687
  //#endregion
3636
3688
  //#region src/routes/shared.ts
3637
3689
  /**
@@ -3658,7 +3710,7 @@ function updateTrackerStatus(trackingId, status) {
3658
3710
  requestTracker.updateRequest(trackingId, { status });
3659
3711
  }
3660
3712
  /** Record error response to history */
3661
- function recordErrorResponse(ctx, model, error) {
3713
+ function recordErrorResponse(ctx, model, error, endpoint, stream) {
3662
3714
  recordResponse(ctx.historyId, {
3663
3715
  success: false,
3664
3716
  model,
@@ -3669,6 +3721,22 @@ function recordErrorResponse(ctx, model, error) {
3669
3721
  error: error instanceof Error ? error.message : "Unknown error",
3670
3722
  content: null
3671
3723
  }, Date.now() - ctx.startTime);
3724
+ if (endpoint !== void 0) {
3725
+ const metrics = extractErrorMetrics(error);
3726
+ captureRequest({
3727
+ model,
3728
+ inputTokens: 0,
3729
+ outputTokens: 0,
3730
+ durationMs: Date.now() - ctx.startTime,
3731
+ success: false,
3732
+ stream: stream ?? false,
3733
+ toolCount: 0,
3734
+ ...metrics,
3735
+ errorPhase: stream ? "pre_stream" : "non_stream",
3736
+ endpoint,
3737
+ attempt: 1
3738
+ });
3739
+ }
3672
3740
  }
3673
3741
  /** Complete TUI tracking and send PostHog analytics */
3674
3742
  function completeTracking(trackingId, inputTokens, outputTokens, queueWaitMs, reasoningTokens, analytics) {
@@ -3727,10 +3795,11 @@ function createTruncationMarker$1(result) {
3727
3795
  }
3728
3796
  /** Record streaming error to history (works with any accumulator type) */
3729
3797
  function recordStreamError(opts) {
3730
- const { acc, fallbackModel, ctx, error } = opts;
3798
+ const { acc, fallbackModel, ctx, error, endpoint } = opts;
3799
+ const model = acc.model || fallbackModel;
3731
3800
  recordResponse(ctx.historyId, {
3732
3801
  success: false,
3733
- model: acc.model || fallbackModel,
3802
+ model,
3734
3803
  usage: {
3735
3804
  input_tokens: 0,
3736
3805
  output_tokens: 0
@@ -3738,6 +3807,22 @@ function recordStreamError(opts) {
3738
3807
  error: formatError(error),
3739
3808
  content: null
3740
3809
  }, Date.now() - ctx.startTime);
3810
+ if (endpoint !== void 0) {
3811
+ const metrics = extractErrorMetrics(error);
3812
+ captureRequest({
3813
+ model,
3814
+ inputTokens: acc.inputTokens ?? 0,
3815
+ outputTokens: acc.outputTokens ?? 0,
3816
+ durationMs: Date.now() - ctx.startTime,
3817
+ success: false,
3818
+ stream: true,
3819
+ toolCount: 0,
3820
+ ...metrics,
3821
+ errorPhase: "mid_stream",
3822
+ endpoint,
3823
+ attempt: 1
3824
+ });
3825
+ }
3741
3826
  }
3742
3827
  /** Type guard for non-streaming responses */
3743
3828
  function isNonStreaming(response) {
@@ -3889,7 +3974,7 @@ async function executeRequest(opts) {
3889
3974
  });
3890
3975
  } catch (error) {
3891
3976
  if (error instanceof HTTPError && error.status === 413) await logPayloadSizeInfo(payload, selectedModel);
3892
- recordErrorResponse(ctx, payload.model, error);
3977
+ recordErrorResponse(ctx, payload.model, error, "chat_completions", payload.stream ?? false);
3893
3978
  throw error;
3894
3979
  }
3895
3980
  }
@@ -4031,7 +4116,8 @@ async function handleStreamingResponse$1(opts) {
4031
4116
  acc,
4032
4117
  fallbackModel: payload.model,
4033
4118
  ctx,
4034
- error
4119
+ error,
4120
+ endpoint: "chat_completions"
4035
4121
  });
4036
4122
  failTracking(ctx.trackingId, error);
4037
4123
  throw error;
@@ -4575,7 +4661,8 @@ async function handleGeminiGenerate(c, model, isStream) {
4575
4661
  acc: { model: streamState.model || model },
4576
4662
  fallbackModel: model,
4577
4663
  ctx,
4578
- error
4664
+ error,
4665
+ endpoint: "chat_completions"
4579
4666
  });
4580
4667
  failTracking(ctx.trackingId, error);
4581
4668
  }
@@ -7546,7 +7633,7 @@ async function handleDirectAnthropicCompletion(c, anthropicPayload, ctx, initiat
7546
7633
  return handleDirectAnthropicNonStreamingResponse(c, response, ctx, truncateResult, effectivePayload);
7547
7634
  } catch (error) {
7548
7635
  if (error instanceof HTTPError && error.status === 413) logPayloadSizeInfoAnthropic(effectivePayload, selectedModel);
7549
- recordErrorResponse(ctx, anthropicPayload.model, error);
7636
+ recordErrorResponse(ctx, anthropicPayload.model, error, "messages", anthropicPayload.stream ?? false);
7550
7637
  throw error;
7551
7638
  }
7552
7639
  }
@@ -7664,7 +7751,8 @@ async function handleDirectAnthropicStreamingResponse(opts) {
7664
7751
  acc,
7665
7752
  fallbackModel: anthropicPayload.model,
7666
7753
  ctx,
7667
- error
7754
+ error,
7755
+ endpoint: "messages"
7668
7756
  });
7669
7757
  failTracking(ctx.trackingId, error);
7670
7758
  const errorEvent = translateErrorToAnthropicErrorEvent(error);
@@ -7759,7 +7847,7 @@ async function handleTranslatedCompletion(c, anthropicPayload, ctx, initiatorOve
7759
7847
  });
7760
7848
  } catch (error) {
7761
7849
  if (error instanceof HTTPError && error.status === 413) await logPayloadSizeInfo(openAIPayload, selectedModel);
7762
- recordErrorResponse(ctx, anthropicPayload.model, error);
7850
+ recordErrorResponse(ctx, anthropicPayload.model, error, "messages", anthropicPayload.stream ?? false);
7763
7851
  throw error;
7764
7852
  }
7765
7853
  }
@@ -7850,7 +7938,8 @@ async function handleStreamingResponse(opts) {
7850
7938
  acc,
7851
7939
  fallbackModel: anthropicPayload.model,
7852
7940
  ctx,
7853
- error
7941
+ error,
7942
+ endpoint: "messages"
7854
7943
  });
7855
7944
  failTracking(ctx.trackingId, error);
7856
7945
  const errorEvent = translateErrorToAnthropicErrorEvent(error);
@@ -8363,7 +8452,7 @@ const handleResponses = async (c) => {
8363
8452
  };
8364
8453
  const selectedModel = findModelById(payload.model);
8365
8454
  if (!(selectedModel?.supported_endpoints?.includes(RESPONSES_ENDPOINT) ?? false)) {
8366
- recordErrorResponse(ctx, model, /* @__PURE__ */ new Error("This model does not support the responses endpoint."));
8455
+ recordErrorResponse(ctx, model, /* @__PURE__ */ new Error("This model does not support the responses endpoint."), "responses", stream);
8367
8456
  return c.json({ error: {
8368
8457
  message: "This model does not support the responses endpoint. Please choose a different model.",
8369
8458
  type: "invalid_request_error"
@@ -8429,7 +8518,8 @@ const handleResponses = async (c) => {
8429
8518
  acc: { model: finalResult?.model || model },
8430
8519
  fallbackModel: model,
8431
8520
  ctx,
8432
- error
8521
+ error,
8522
+ endpoint: "responses"
8433
8523
  });
8434
8524
  failTracking(trackingId, error);
8435
8525
  throw error;
@@ -8448,7 +8538,7 @@ const handleResponses = async (c) => {
8448
8538
  consola.debug("Forwarding native Responses result:", JSON.stringify(result).slice(-400));
8449
8539
  return c.json(result);
8450
8540
  } catch (error) {
8451
- recordErrorResponse(ctx, model, error);
8541
+ recordErrorResponse(ctx, model, error, "responses", stream);
8452
8542
  failTracking(trackingId, error);
8453
8543
  throw error;
8454
8544
  }
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.8",
4
4
  "description": "Turn GitHub Copilot into OpenAI/Anthropic API compatible server. Usable with Claude Code!",
5
5
  "author": "dianshuv",
6
6
  "type": "module",