@dianshuv/copilot-api 0.8.0 → 0.8.1
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/main.mjs +56 -11
- package/package.json +1 -1
package/dist/main.mjs
CHANGED
|
@@ -1348,7 +1348,7 @@ const patchClaude = defineCommand({
|
|
|
1348
1348
|
|
|
1349
1349
|
//#endregion
|
|
1350
1350
|
//#region package.json
|
|
1351
|
-
var version = "0.8.
|
|
1351
|
+
var version = "0.8.1";
|
|
1352
1352
|
|
|
1353
1353
|
//#endregion
|
|
1354
1354
|
//#region src/lib/adaptive-rate-limiter.ts
|
|
@@ -3448,13 +3448,39 @@ function isOneMillionSuffixedClaudeId(modelId) {
|
|
|
3448
3448
|
}
|
|
3449
3449
|
|
|
3450
3450
|
//#endregion
|
|
3451
|
-
//#region src/
|
|
3452
|
-
|
|
3451
|
+
//#region src/lib/headers.ts
|
|
3452
|
+
/**
|
|
3453
|
+
* Vendor-neutral header-bag helpers.
|
|
3454
|
+
*
|
|
3455
|
+
* HTTP header names are case-insensitive, but a plain-object header bag is
|
|
3456
|
+
* case-sensitive on its keys. Code that wants to look up "anthropic-beta"
|
|
3457
|
+
* without knowing whether some other producer wrote "Anthropic-Beta" needs
|
|
3458
|
+
* `findHeaderKey`. Code that wants to set a header without creating a
|
|
3459
|
+
* second case variant of the same name needs `setHeader`.
|
|
3460
|
+
*/
|
|
3453
3461
|
/** Case-insensitive lookup of a header key in a plain-object header bag. */
|
|
3454
3462
|
function findHeaderKey(headers, name) {
|
|
3455
3463
|
const lower = name.toLowerCase();
|
|
3456
3464
|
return Object.keys(headers).find((k) => k.toLowerCase() === lower);
|
|
3457
3465
|
}
|
|
3466
|
+
/** Case-insensitive read of a header value. */
|
|
3467
|
+
function getHeader(headers, name) {
|
|
3468
|
+
const key = findHeaderKey(headers, name);
|
|
3469
|
+
return key === void 0 ? void 0 : headers[key];
|
|
3470
|
+
}
|
|
3471
|
+
/**
|
|
3472
|
+
* Set a header value at the existing case variant if one is present, else at
|
|
3473
|
+
* the supplied canonical name. Prevents a second key (different case) from
|
|
3474
|
+
* being added for the same logical header.
|
|
3475
|
+
*/
|
|
3476
|
+
function setHeader(headers, name, value) {
|
|
3477
|
+
const key = findHeaderKey(headers, name) ?? name;
|
|
3478
|
+
headers[key] = value;
|
|
3479
|
+
}
|
|
3480
|
+
|
|
3481
|
+
//#endregion
|
|
3482
|
+
//#region src/services/copilot/create-chat-completions.ts
|
|
3483
|
+
const GPT_MODEL_PATTERN = /^gpt-/i;
|
|
3458
3484
|
const createChatCompletions = async (payload, options) => {
|
|
3459
3485
|
if (!state.copilotToken) throw new Error("Copilot token not found");
|
|
3460
3486
|
const vendor = options?.resolvedModel?.vendor;
|
|
@@ -7121,15 +7147,18 @@ async function createAnthropicMessages(payload, options) {
|
|
|
7121
7147
|
const headers = {
|
|
7122
7148
|
...copilotHeaders(state, {
|
|
7123
7149
|
vision: enableVision,
|
|
7124
|
-
intent: isAgentCall ? "conversation-agent" : "conversation-panel"
|
|
7150
|
+
intent: isAgentCall ? "conversation-agent" : "conversation-panel",
|
|
7151
|
+
modelRequestHeaders: resolvedModel?.request_headers
|
|
7125
7152
|
}),
|
|
7126
7153
|
"X-Initiator": options?.initiator ?? (isAgentCall ? "agent" : "user"),
|
|
7127
7154
|
"anthropic-version": "2023-06-01"
|
|
7128
7155
|
};
|
|
7129
|
-
const
|
|
7130
|
-
|
|
7131
|
-
if (options?.injectContext1mBeta)
|
|
7132
|
-
if (
|
|
7156
|
+
const proxyBeta = buildAnthropicBetaHeaders(filteredPayload.model, resolvedModel)["anthropic-beta"];
|
|
7157
|
+
let mergedBeta = mergeBetaFeatures(getHeader(headers, "anthropic-beta"), proxyBeta);
|
|
7158
|
+
if (options?.injectContext1mBeta) mergedBeta = appendContext1mBeta(mergedBeta);
|
|
7159
|
+
if (options?.clientAnthropicBetaHeader) mergedBeta = mergeBetaFeatures(mergedBeta, options.clientAnthropicBetaHeader);
|
|
7160
|
+
if (mergedBeta.length > 0) setHeader(headers, "anthropic-beta", mergedBeta);
|
|
7161
|
+
if (!("context_management" in filteredPayload) && isContextEditingEnabled(filteredPayload.model)) {
|
|
7133
7162
|
const hasThinking = filteredPayload.thinking?.type === "enabled";
|
|
7134
7163
|
const cm = buildContextManagement(state.contextEditingMode, hasThinking);
|
|
7135
7164
|
if (cm) {
|
|
@@ -7178,7 +7207,11 @@ function stripServerToolsFromPayload(tools) {
|
|
|
7178
7207
|
}
|
|
7179
7208
|
return result.length > 0 ? result : void 0;
|
|
7180
7209
|
}
|
|
7181
|
-
/**
|
|
7210
|
+
/**
|
|
7211
|
+
* Effective 1M context window. Two ways a request lands on this size:
|
|
7212
|
+
* (a) base model id + context-1m-2025-08-07 beta header (e.g. claude-opus-4.8),
|
|
7213
|
+
* (b) a distinct upstream "-1m-internal" model id (e.g. claude-opus-4.7-1m-internal).
|
|
7214
|
+
*/
|
|
7182
7215
|
const ONE_MILLION_CONTEXT_WINDOW_TOKENS = 1e6;
|
|
7183
7216
|
/**
|
|
7184
7217
|
* Convert a Claude model id from the client-facing dash convention to the
|
|
@@ -7212,7 +7245,17 @@ function resolveAnthropicModelForDirectPath(modelId) {
|
|
|
7212
7245
|
}
|
|
7213
7246
|
if (modelId.endsWith("-1m")) {
|
|
7214
7247
|
const baseId = modelId.slice(0, -3);
|
|
7215
|
-
|
|
7248
|
+
const dottedBaseId = dashToDotClaudeId(baseId);
|
|
7249
|
+
for (const candidateId of [`${baseId}-1m-internal`, `${dottedBaseId}-1m-internal`]) {
|
|
7250
|
+
const internal = findModelById(candidateId);
|
|
7251
|
+
if (internal?.vendor === "Anthropic") return {
|
|
7252
|
+
model: internal,
|
|
7253
|
+
baseModelId: candidateId,
|
|
7254
|
+
oneMillionFallback: false,
|
|
7255
|
+
effectiveContextWindowTokens: ONE_MILLION_CONTEXT_WINDOW_TOKENS
|
|
7256
|
+
};
|
|
7257
|
+
}
|
|
7258
|
+
for (const candidateId of [baseId, dottedBaseId]) {
|
|
7216
7259
|
const base = findModelById(candidateId);
|
|
7217
7260
|
if (base?.vendor === "Anthropic") return {
|
|
7218
7261
|
model: base,
|
|
@@ -7928,11 +7971,13 @@ async function handleDirectAnthropicCompletion(c, anthropicPayload, ctx, initiat
|
|
|
7928
7971
|
}
|
|
7929
7972
|
} else if (state.autoTruncate && !selectedModel) consola.debug(`[Anthropic] Model '${anthropicPayload.model}' not found, skipping auto-truncate`);
|
|
7930
7973
|
if (state.manualApprove) await awaitApproval();
|
|
7974
|
+
const clientAnthropicBetaHeader = c.req.header("anthropic-beta");
|
|
7931
7975
|
try {
|
|
7932
7976
|
const { result: response, queueWaitMs } = await executeWithAdaptiveRateLimit(() => createAnthropicMessages(effectivePayload, {
|
|
7933
7977
|
initiator: initiatorOverride,
|
|
7934
7978
|
injectContext1mBeta: needsContext1mBeta,
|
|
7935
|
-
errorModelIdOverride: needsContext1mBeta ? originalModelId : void 0
|
|
7979
|
+
errorModelIdOverride: needsContext1mBeta ? originalModelId : void 0,
|
|
7980
|
+
clientAnthropicBetaHeader
|
|
7936
7981
|
}));
|
|
7937
7982
|
ctx.queueWaitMs = queueWaitMs;
|
|
7938
7983
|
if (Symbol.asyncIterator in response) {
|