@dianshuv/copilot-api 0.16.0 → 0.18.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/README.md +1 -1
- package/dist/main.mjs +92 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ make down
|
|
|
48
48
|
|---------|-------------|
|
|
49
49
|
| `start` | Start the API server (handles auth if needed) |
|
|
50
50
|
| `login` | Run GitHub authentication flow only |
|
|
51
|
-
| `logout` | Remove
|
|
51
|
+
| `logout` | Remove the local GitHub token file (does not revoke authorization on GitHub) |
|
|
52
52
|
| `debug` | Display diagnostic information |
|
|
53
53
|
|
|
54
54
|
### Start Command Options
|
package/dist/main.mjs
CHANGED
|
@@ -997,6 +997,8 @@ async function runLogout() {
|
|
|
997
997
|
throw error;
|
|
998
998
|
}
|
|
999
999
|
}
|
|
1000
|
+
consola.warn("This only removes the local token file. The OAuth App authorization is still active on GitHub and the token remains valid until revoked.");
|
|
1001
|
+
consola.info(`To fully revoke access, visit https://github.com/settings/connections/applications/${GITHUB_CLIENT_ID} and click "Revoke access".`);
|
|
1000
1002
|
}
|
|
1001
1003
|
const logout = defineCommand({
|
|
1002
1004
|
meta: {
|
|
@@ -1010,7 +1012,7 @@ const logout = defineCommand({
|
|
|
1010
1012
|
|
|
1011
1013
|
//#endregion
|
|
1012
1014
|
//#region package.json
|
|
1013
|
-
var version = "0.
|
|
1015
|
+
var version = "0.18.0";
|
|
1014
1016
|
|
|
1015
1017
|
//#endregion
|
|
1016
1018
|
//#region src/lib/event-loop-lag.ts
|
|
@@ -1592,6 +1594,8 @@ function captureRequest(params) {
|
|
|
1592
1594
|
tool_count: params.toolCount
|
|
1593
1595
|
};
|
|
1594
1596
|
if (params.reasoningTokens !== void 0) properties.reasoning_tokens = params.reasoningTokens;
|
|
1597
|
+
if (params.cachedInputTokens !== void 0) properties.cached_input_tokens = params.cachedInputTokens;
|
|
1598
|
+
if (params.totalInputTokens !== void 0) properties.total_input_tokens = params.totalInputTokens;
|
|
1595
1599
|
if (params.stopReason !== void 0) properties.stop_reason = params.stopReason;
|
|
1596
1600
|
if (params.status !== void 0) properties.status = params.status;
|
|
1597
1601
|
if (params.copilotErrorCode !== void 0) properties.copilot_error_code = params.copilotErrorCode;
|
|
@@ -2715,6 +2719,20 @@ function formatTokens(input, output) {
|
|
|
2715
2719
|
return `${formatNumber(input)}/${formatNumber(output)}`;
|
|
2716
2720
|
}
|
|
2717
2721
|
/**
|
|
2722
|
+
* Cache-hit segment for the complete line, e.g. `cache=90%` (or
|
|
2723
|
+
* `cache=90% (1.6K/1.8K)` under --verbose). Returns undefined when there is no
|
|
2724
|
+
* usable denominator or the request had zero cache hits, so non-cached and
|
|
2725
|
+
* non-LLM requests stay terse (minimize-noise). `total` is the full prompt size
|
|
2726
|
+
* normalized across API families; see completeTracking / the per-path extraction.
|
|
2727
|
+
*/
|
|
2728
|
+
function formatCacheHitRate(cached, total) {
|
|
2729
|
+
if (total === void 0 || total <= 0) return void 0;
|
|
2730
|
+
if (cached === void 0 || cached <= 0) return void 0;
|
|
2731
|
+
const pct = Math.round(cached / total * 100);
|
|
2732
|
+
if (consola.level >= 5) return `cache=${pct}% (${formatNumber(cached)}/${formatNumber(total)})`;
|
|
2733
|
+
return `cache=${pct}%`;
|
|
2734
|
+
}
|
|
2735
|
+
/**
|
|
2718
2736
|
* Console renderer that shows request lifecycle with apt-get style footer
|
|
2719
2737
|
*
|
|
2720
2738
|
* Log format:
|
|
@@ -2816,7 +2834,7 @@ var ConsoleRenderer = class {
|
|
|
2816
2834
|
* Format a complete log line with colored parts
|
|
2817
2835
|
*/
|
|
2818
2836
|
formatLogLine(parts) {
|
|
2819
|
-
const { prefix, time, method, path, model, status, duration, tokens, queueWait, phases, extra, isError, isDim } = parts;
|
|
2837
|
+
const { prefix, time, method, path, model, status, duration, tokens, cache, queueWait, phases, extra, isError, isDim } = parts;
|
|
2820
2838
|
if (isDim) {
|
|
2821
2839
|
const modelPart = model ? ` ${model}` : "";
|
|
2822
2840
|
const extraPart = extra ? ` ${extra}` : "";
|
|
@@ -2830,6 +2848,7 @@ var ConsoleRenderer = class {
|
|
|
2830
2848
|
if (duration) result += ` ${pc.yellow(duration)}`;
|
|
2831
2849
|
if (queueWait) result += ` ${pc.dim(`(queued ${queueWait})`)}`;
|
|
2832
2850
|
if (tokens) result += ` ${pc.blue(tokens)}`;
|
|
2851
|
+
if (cache) result += ` ${pc.dim(cache)}`;
|
|
2833
2852
|
if (phases) result += ` ${pc.dim(phases)}`;
|
|
2834
2853
|
if (extra) result += isError ? pc.red(extra) : extra;
|
|
2835
2854
|
return result;
|
|
@@ -2901,6 +2920,7 @@ var ConsoleRenderer = class {
|
|
|
2901
2920
|
const status = request.statusCode ?? 0;
|
|
2902
2921
|
const isError = request.status === "error" || status >= 400;
|
|
2903
2922
|
const tokens = request.model ? formatTokens(request.inputTokens, request.outputTokens) : void 0;
|
|
2923
|
+
const cache = formatCacheHitRate(request.cachedInputTokens, request.totalInputTokens);
|
|
2904
2924
|
const queueWait = request.queueWaitMs && request.queueWaitMs > 100 ? formatDuration(request.queueWaitMs) : void 0;
|
|
2905
2925
|
const message = this.formatLogLine({
|
|
2906
2926
|
prefix: isError ? "[FAIL]" : "[ OK ]",
|
|
@@ -2912,6 +2932,7 @@ var ConsoleRenderer = class {
|
|
|
2912
2932
|
duration: formatDuration(request.durationMs ?? 0),
|
|
2913
2933
|
queueWait,
|
|
2914
2934
|
tokens,
|
|
2935
|
+
cache,
|
|
2915
2936
|
phases: this.formatPhases(request),
|
|
2916
2937
|
extra: isError && request.error ? `: ${request.error}` : void 0,
|
|
2917
2938
|
isError,
|
|
@@ -2980,6 +3001,8 @@ var RequestTracker = class {
|
|
|
2980
3001
|
if (update.inputTokens !== void 0) request.inputTokens = update.inputTokens;
|
|
2981
3002
|
if (update.outputTokens !== void 0) request.outputTokens = update.outputTokens;
|
|
2982
3003
|
if (update.reasoningTokens !== void 0) request.reasoningTokens = update.reasoningTokens;
|
|
3004
|
+
if (update.cachedInputTokens !== void 0) request.cachedInputTokens = update.cachedInputTokens;
|
|
3005
|
+
if (update.totalInputTokens !== void 0) request.totalInputTokens = update.totalInputTokens;
|
|
2983
3006
|
if (update.error !== void 0) request.error = update.error;
|
|
2984
3007
|
if (update.queuePosition !== void 0) request.queuePosition = update.queuePosition;
|
|
2985
3008
|
if (update.queueWaitMs !== void 0) request.queueWaitMs = update.queueWaitMs;
|
|
@@ -4147,13 +4170,15 @@ function updateTrackerStatus(trackingId, status) {
|
|
|
4147
4170
|
requestTracker.updateRequest(trackingId, { status });
|
|
4148
4171
|
}
|
|
4149
4172
|
/** Complete TUI tracking and send PostHog analytics */
|
|
4150
|
-
function completeTracking(trackingId, inputTokens, outputTokens, queueWaitMs, reasoningTokens, analytics, timings) {
|
|
4173
|
+
function completeTracking(trackingId, inputTokens, outputTokens, queueWaitMs, reasoningTokens, analytics, timings, cache) {
|
|
4151
4174
|
if (!trackingId) return;
|
|
4152
4175
|
requestTracker.updateRequest(trackingId, {
|
|
4153
4176
|
inputTokens,
|
|
4154
4177
|
outputTokens,
|
|
4155
4178
|
queueWaitMs,
|
|
4156
4179
|
reasoningTokens,
|
|
4180
|
+
cachedInputTokens: cache?.cachedInputTokens,
|
|
4181
|
+
totalInputTokens: cache?.totalInputTokens,
|
|
4157
4182
|
...timingsToUpdate(timings)
|
|
4158
4183
|
});
|
|
4159
4184
|
requestTracker.completeRequest(trackingId, 200, {
|
|
@@ -4170,6 +4195,8 @@ function completeTracking(trackingId, inputTokens, outputTokens, queueWaitMs, re
|
|
|
4170
4195
|
stream: analytics.stream,
|
|
4171
4196
|
toolCount: analytics.toolCount ?? 0,
|
|
4172
4197
|
reasoningTokens,
|
|
4198
|
+
cachedInputTokens: cache?.cachedInputTokens,
|
|
4199
|
+
totalInputTokens: cache?.totalInputTokens,
|
|
4173
4200
|
stopReason: analytics.stopReason
|
|
4174
4201
|
});
|
|
4175
4202
|
}
|
|
@@ -4265,6 +4292,9 @@ function formatClientTruncationMarker(result) {
|
|
|
4265
4292
|
function getReasoningTokensFromOpenAIUsage(usage) {
|
|
4266
4293
|
return usage?.completion_tokens_details?.reasoning_tokens;
|
|
4267
4294
|
}
|
|
4295
|
+
function getCachedTokensFromOpenAIUsage(usage) {
|
|
4296
|
+
return usage?.prompt_tokens_details?.cached_tokens;
|
|
4297
|
+
}
|
|
4268
4298
|
async function handleCompletion$1(c) {
|
|
4269
4299
|
const rawPayload = await c.req.json();
|
|
4270
4300
|
consola.debug("Request payload:", JSON.stringify(rawPayload).slice(-400));
|
|
@@ -4379,11 +4409,14 @@ function handleNonStreamingResponse$1(c, originalResponse, ctx, payload) {
|
|
|
4379
4409
|
content: buildResponseContent(choice),
|
|
4380
4410
|
toolCalls: extractToolCalls(choice)
|
|
4381
4411
|
}, durationMs);
|
|
4412
|
+
const cachedInputTokens = usage ? getCachedTokensFromOpenAIUsage(usage) : void 0;
|
|
4382
4413
|
if (ctx.trackingId && usage) requestTracker.updateRequest(ctx.trackingId, {
|
|
4383
4414
|
inputTokens: usage.prompt_tokens,
|
|
4384
4415
|
outputTokens: usage.completion_tokens,
|
|
4385
4416
|
queueWaitMs: ctx.queueWaitMs,
|
|
4386
|
-
reasoningTokens
|
|
4417
|
+
reasoningTokens,
|
|
4418
|
+
cachedInputTokens,
|
|
4419
|
+
totalInputTokens: usage.prompt_tokens
|
|
4387
4420
|
});
|
|
4388
4421
|
captureRequest({
|
|
4389
4422
|
model: response.model,
|
|
@@ -4394,6 +4427,8 @@ function handleNonStreamingResponse$1(c, originalResponse, ctx, payload) {
|
|
|
4394
4427
|
stream: false,
|
|
4395
4428
|
toolCount: payload.tools?.length ?? 0,
|
|
4396
4429
|
reasoningTokens,
|
|
4430
|
+
cachedInputTokens,
|
|
4431
|
+
totalInputTokens: usage?.prompt_tokens,
|
|
4397
4432
|
stopReason: choice.finish_reason
|
|
4398
4433
|
});
|
|
4399
4434
|
return c.json(echoResponseBody(response, ctx));
|
|
@@ -4424,6 +4459,7 @@ function createStreamAccumulator() {
|
|
|
4424
4459
|
model: "",
|
|
4425
4460
|
inputTokens: 0,
|
|
4426
4461
|
outputTokens: 0,
|
|
4462
|
+
cachedTokens: 0,
|
|
4427
4463
|
reasoningTokens: 0,
|
|
4428
4464
|
finishReason: "",
|
|
4429
4465
|
content: "",
|
|
@@ -4467,7 +4503,10 @@ async function handleStreamingResponse$1(opts) {
|
|
|
4467
4503
|
durationMs: Date.now() - ctx.startTime,
|
|
4468
4504
|
stopReason: acc.finishReason || void 0,
|
|
4469
4505
|
toolCount: payload.tools?.length ?? 0
|
|
4470
|
-
}, ctx.timings
|
|
4506
|
+
}, ctx.timings, {
|
|
4507
|
+
cachedInputTokens: acc.cachedTokens,
|
|
4508
|
+
totalInputTokens: acc.inputTokens
|
|
4509
|
+
});
|
|
4471
4510
|
} catch (error) {
|
|
4472
4511
|
if (isAbortError(error)) {
|
|
4473
4512
|
consola.debug("[ChatCompletions] client disconnected mid-stream; upstream aborted");
|
|
@@ -4536,6 +4575,7 @@ function accumulateParsedChunk(parsed, acc, checkRepetition) {
|
|
|
4536
4575
|
if (parsed.usage) {
|
|
4537
4576
|
acc.inputTokens = parsed.usage.prompt_tokens;
|
|
4538
4577
|
acc.outputTokens = parsed.usage.completion_tokens;
|
|
4578
|
+
acc.cachedTokens = parsed.usage.prompt_tokens_details?.cached_tokens ?? 0;
|
|
4539
4579
|
acc.reasoningTokens = getReasoningTokensFromOpenAIUsage(parsed.usage) ?? 0;
|
|
4540
4580
|
}
|
|
4541
4581
|
const choice = parsed.choices?.[0];
|
|
@@ -7149,6 +7189,8 @@ function createAnthropicStreamAccumulator() {
|
|
|
7149
7189
|
model: "",
|
|
7150
7190
|
inputTokens: 0,
|
|
7151
7191
|
outputTokens: 0,
|
|
7192
|
+
cacheReadInputTokens: 0,
|
|
7193
|
+
cacheCreationInputTokens: 0,
|
|
7152
7194
|
stopReason: "",
|
|
7153
7195
|
content: "",
|
|
7154
7196
|
toolCalls: [],
|
|
@@ -7158,6 +7200,9 @@ function createAnthropicStreamAccumulator() {
|
|
|
7158
7200
|
}
|
|
7159
7201
|
function processAnthropicEvent(event, acc) {
|
|
7160
7202
|
switch (event.type) {
|
|
7203
|
+
case "message_start":
|
|
7204
|
+
handleMessageStart(event.message.usage, acc);
|
|
7205
|
+
break;
|
|
7161
7206
|
case "content_block_delta":
|
|
7162
7207
|
handleContentBlockDelta(event.delta, acc);
|
|
7163
7208
|
break;
|
|
@@ -7193,11 +7238,20 @@ function handleContentBlockStop(acc) {
|
|
|
7193
7238
|
acc.currentToolCall = null;
|
|
7194
7239
|
}
|
|
7195
7240
|
}
|
|
7241
|
+
function applyPromptSideUsage(usage, acc) {
|
|
7242
|
+
if (usage.input_tokens !== void 0) acc.inputTokens = usage.input_tokens;
|
|
7243
|
+
if (usage.cache_read_input_tokens !== void 0) acc.cacheReadInputTokens = usage.cache_read_input_tokens;
|
|
7244
|
+
if (usage.cache_creation_input_tokens !== void 0) acc.cacheCreationInputTokens = usage.cache_creation_input_tokens;
|
|
7245
|
+
}
|
|
7246
|
+
function handleMessageStart(usage, acc) {
|
|
7247
|
+
if (!usage) return;
|
|
7248
|
+
applyPromptSideUsage(usage, acc);
|
|
7249
|
+
}
|
|
7196
7250
|
function handleMessageDelta(delta, usage, acc) {
|
|
7197
7251
|
if (delta.stop_reason) acc.stopReason = delta.stop_reason;
|
|
7198
7252
|
if (usage) {
|
|
7199
|
-
acc.inputTokens = usage.input_tokens ?? 0;
|
|
7200
7253
|
acc.outputTokens = usage.output_tokens;
|
|
7254
|
+
applyPromptSideUsage(usage, acc);
|
|
7201
7255
|
}
|
|
7202
7256
|
}
|
|
7203
7257
|
function recordAnthropicStreamingResponse(acc, fallbackModel, ctx) {
|
|
@@ -8400,10 +8454,15 @@ function handleDirectAnthropicNonStreamingResponse(c, response, ctx, truncateRes
|
|
|
8400
8454
|
},
|
|
8401
8455
|
toolCalls: extractToolCallsFromContent(response.content)
|
|
8402
8456
|
}, Date.now() - ctx.startTime);
|
|
8457
|
+
const cacheRead = response.usage.cache_read_input_tokens ?? 0;
|
|
8458
|
+
const cacheCreation = response.usage.cache_creation_input_tokens ?? 0;
|
|
8459
|
+
const totalInputTokens = response.usage.input_tokens + cacheRead + cacheCreation;
|
|
8403
8460
|
if (ctx.trackingId) requestTracker.updateRequest(ctx.trackingId, {
|
|
8404
8461
|
inputTokens: response.usage.input_tokens,
|
|
8405
8462
|
outputTokens: response.usage.output_tokens,
|
|
8406
|
-
queueWaitMs: ctx.queueWaitMs
|
|
8463
|
+
queueWaitMs: ctx.queueWaitMs,
|
|
8464
|
+
cachedInputTokens: cacheRead,
|
|
8465
|
+
totalInputTokens
|
|
8407
8466
|
});
|
|
8408
8467
|
captureRequest({
|
|
8409
8468
|
model: response.model,
|
|
@@ -8413,6 +8472,8 @@ function handleDirectAnthropicNonStreamingResponse(c, response, ctx, truncateRes
|
|
|
8413
8472
|
success: true,
|
|
8414
8473
|
stream: false,
|
|
8415
8474
|
toolCount: payload.tools?.length ?? 0,
|
|
8475
|
+
cachedInputTokens: cacheRead,
|
|
8476
|
+
totalInputTokens,
|
|
8416
8477
|
stopReason: response.stop_reason ?? void 0
|
|
8417
8478
|
});
|
|
8418
8479
|
let finalResponse = response;
|
|
@@ -8498,7 +8559,10 @@ async function handleDirectAnthropicStreamingResponse(opts) {
|
|
|
8498
8559
|
durationMs: Date.now() - ctx.startTime,
|
|
8499
8560
|
stopReason: acc.stopReason || void 0,
|
|
8500
8561
|
toolCount: anthropicPayload.tools?.length ?? 0
|
|
8501
|
-
}, ctx.timings
|
|
8562
|
+
}, ctx.timings, {
|
|
8563
|
+
cachedInputTokens: acc.cacheReadInputTokens,
|
|
8564
|
+
totalInputTokens: acc.inputTokens + acc.cacheReadInputTokens + acc.cacheCreationInputTokens
|
|
8565
|
+
});
|
|
8502
8566
|
} catch (error) {
|
|
8503
8567
|
if (isAbortError(error)) {
|
|
8504
8568
|
consola.debug("[Anthropic] client disconnected mid-stream; upstream aborted");
|
|
@@ -8713,10 +8777,15 @@ function handleNonStreamingResponse(opts) {
|
|
|
8713
8777
|
},
|
|
8714
8778
|
toolCalls: extractToolCallsFromContent(anthropicResponse.content)
|
|
8715
8779
|
}, Date.now() - ctx.startTime);
|
|
8780
|
+
const cacheRead = anthropicResponse.usage.cache_read_input_tokens ?? 0;
|
|
8781
|
+
const cacheCreation = anthropicResponse.usage.cache_creation_input_tokens ?? 0;
|
|
8782
|
+
const totalInputTokens = anthropicResponse.usage.input_tokens + cacheRead + cacheCreation;
|
|
8716
8783
|
if (ctx.trackingId) requestTracker.updateRequest(ctx.trackingId, {
|
|
8717
8784
|
inputTokens: anthropicResponse.usage.input_tokens,
|
|
8718
8785
|
outputTokens: anthropicResponse.usage.output_tokens,
|
|
8719
|
-
queueWaitMs: ctx.queueWaitMs
|
|
8786
|
+
queueWaitMs: ctx.queueWaitMs,
|
|
8787
|
+
cachedInputTokens: cacheRead,
|
|
8788
|
+
totalInputTokens
|
|
8720
8789
|
});
|
|
8721
8790
|
captureRequest({
|
|
8722
8791
|
model: anthropicResponse.model,
|
|
@@ -8726,6 +8795,8 @@ function handleNonStreamingResponse(opts) {
|
|
|
8726
8795
|
success: true,
|
|
8727
8796
|
stream: false,
|
|
8728
8797
|
toolCount: anthropicPayload.tools?.length ?? 0,
|
|
8798
|
+
cachedInputTokens: cacheRead,
|
|
8799
|
+
totalInputTokens,
|
|
8729
8800
|
stopReason: anthropicResponse.stop_reason ?? void 0
|
|
8730
8801
|
});
|
|
8731
8802
|
return c.json(echoResponseBody(anthropicResponse, ctx));
|
|
@@ -8762,7 +8833,10 @@ async function handleStreamingResponse(opts) {
|
|
|
8762
8833
|
durationMs: Date.now() - ctx.startTime,
|
|
8763
8834
|
stopReason: acc.stopReason || void 0,
|
|
8764
8835
|
toolCount: anthropicPayload.tools?.length ?? 0
|
|
8765
|
-
}, ctx.timings
|
|
8836
|
+
}, ctx.timings, {
|
|
8837
|
+
cachedInputTokens: acc.cacheReadInputTokens,
|
|
8838
|
+
totalInputTokens: acc.inputTokens + acc.cacheReadInputTokens + acc.cacheCreationInputTokens
|
|
8839
|
+
});
|
|
8766
8840
|
} catch (error) {
|
|
8767
8841
|
if (isAbortError(error)) {
|
|
8768
8842
|
consola.debug("[Translated] client disconnected mid-stream; upstream aborted");
|
|
@@ -9395,7 +9469,10 @@ const handleResponses = async (c) => {
|
|
|
9395
9469
|
stream: true,
|
|
9396
9470
|
durationMs: Date.now() - startTime,
|
|
9397
9471
|
toolCount: tools.length
|
|
9398
|
-
}, ctx.timings
|
|
9472
|
+
}, ctx.timings, {
|
|
9473
|
+
cachedInputTokens: usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
9474
|
+
totalInputTokens: usage?.input_tokens ?? 0
|
|
9475
|
+
});
|
|
9399
9476
|
} else if (streamErrorMessage) {
|
|
9400
9477
|
recordResponse(historyId, {
|
|
9401
9478
|
success: false,
|
|
@@ -9446,7 +9523,10 @@ const handleResponses = async (c) => {
|
|
|
9446
9523
|
stream: false,
|
|
9447
9524
|
durationMs: Date.now() - startTime,
|
|
9448
9525
|
toolCount: tools.length
|
|
9449
|
-
}, ctx.timings
|
|
9526
|
+
}, ctx.timings, {
|
|
9527
|
+
cachedInputTokens: usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
9528
|
+
totalInputTokens: usage?.input_tokens ?? 0
|
|
9529
|
+
});
|
|
9450
9530
|
consola.debug("Forwarding native Responses result:", JSON.stringify(result).slice(-400));
|
|
9451
9531
|
return c.json(echoResponseBody(result, ctx));
|
|
9452
9532
|
} catch (error) {
|