@jeffreycao/copilot-api 1.10.1 → 1.10.2
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 +28 -5
- package/README.zh-CN.md +28 -5
- package/dist/{auth-D7YCTWpx.js → auth-BHa2OHXf.js} +3 -3
- package/dist/{auth-D7YCTWpx.js.map → auth-BHa2OHXf.js.map} +1 -1
- package/dist/{check-usage-Dgg0nNEw.js → check-usage-BdXGp1Wr.js} +3 -3
- package/dist/{check-usage-Dgg0nNEw.js.map → check-usage-BdXGp1Wr.js.map} +1 -1
- package/dist/main.js +3 -3
- package/dist/{proxy-De0Po8kG.js → proxy-DQLzdeq3.js} +106 -6
- package/dist/proxy-DQLzdeq3.js.map +1 -0
- package/dist/{server-DpVPS3zt.js → server-csGHkK-m.js} +77 -16
- package/dist/server-csGHkK-m.js.map +1 -0
- package/dist/{start-DDII-0ML.js → start-BVraN8xz.js} +5 -5
- package/dist/{start-DDII-0ML.js.map → start-BVraN8xz.js.map} +1 -1
- package/dist/{token-BQlDdqtI.js → token-Dj8XsAxn.js} +2 -2
- package/dist/{token-BQlDdqtI.js.map → token-Dj8XsAxn.js.map} +1 -1
- package/dist/{utils-C5ej0z8n.js → utils-jHLgqAq2.js} +3 -3
- package/dist/{utils-C5ej0z8n.js.map → utils-jHLgqAq2.js.map} +1 -1
- package/package.json +1 -1
- package/dist/proxy-De0Po8kG.js.map +0 -1
- package/dist/server-DpVPS3zt.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as PATHS } from "./paths-DC-mqCY3.js";
|
|
2
|
-
import { D as generateTraceId, E as prepareMessageProxyHeaders, I as state, M as compactMessageSections, O as requestContext, P as compactSystemPromptStarts, T as prepareInteractionHeaders, _ as copilotWebSocketHeaders, c as getUUID, d as sleep, f as getCopilotUsage, g as copilotHeaders, h as copilotBaseUrl, j as compactAutoContinuePromptStarts, k as resolveTraceId$1, l as isNullish, m as forwardError, n as cacheModels, o as generateRequestIdFromPayload, p as HTTPError, s as getRootSessionId, u as parseUserIdMetadata, w as prepareForCompact } from "./utils-
|
|
3
|
-
import { a as getConfig, c as
|
|
2
|
+
import { D as generateTraceId, E as prepareMessageProxyHeaders, I as state, M as compactMessageSections, O as requestContext, P as compactSystemPromptStarts, T as prepareInteractionHeaders, _ as copilotWebSocketHeaders, c as getUUID, d as sleep, f as getCopilotUsage, g as copilotHeaders, h as copilotBaseUrl, j as compactAutoContinuePromptStarts, k as resolveTraceId$1, l as isNullish, m as forwardError, n as cacheModels, o as generateRequestIdFromPayload, p as HTTPError, s as getRootSessionId, u as parseUserIdMetadata, w as prepareForCompact } from "./utils-jHLgqAq2.js";
|
|
3
|
+
import { _ as setModelMappings, a as getConfig, c as getProviderConfig, d as isMessagesApiEnabled, f as isResponsesApiContextManagementModel, g as resolveMappedModel, i as getClaudeTokenMultiplier, l as getReasoningEffortForModel, m as isResponsesApiWebSocketEnabled, o as getExtraPromptForModel, p as isResponsesApiWebSearchEnabled, r as getAnthropicApiKey, s as getModelMappings, t as getProxyEnvDispatcher, u as getSmallModel } from "./proxy-DQLzdeq3.js";
|
|
4
4
|
import consola from "consola";
|
|
5
5
|
import fs from "node:fs/promises";
|
|
6
6
|
import path from "node:path";
|
|
@@ -12,6 +12,7 @@ import fs$1, { readFileSync } from "node:fs";
|
|
|
12
12
|
import { streamSSE } from "hono/streaming";
|
|
13
13
|
import util from "node:util";
|
|
14
14
|
import { events } from "fetch-event-stream";
|
|
15
|
+
import { z } from "zod";
|
|
15
16
|
import { WebSocket } from "undici";
|
|
16
17
|
//#region src/lib/request-auth.ts
|
|
17
18
|
function normalizeApiKeys(apiKeys) {
|
|
@@ -26,6 +27,14 @@ function normalizeApiKeys(apiKeys) {
|
|
|
26
27
|
function getConfiguredApiKeys() {
|
|
27
28
|
return normalizeApiKeys(getConfig().auth?.apiKeys);
|
|
28
29
|
}
|
|
30
|
+
function normalizeApiKey(apiKey) {
|
|
31
|
+
if (typeof apiKey !== "string") return null;
|
|
32
|
+
return apiKey.trim() || null;
|
|
33
|
+
}
|
|
34
|
+
function getConfiguredAdminApiKeys() {
|
|
35
|
+
const adminApiKey = normalizeApiKey(getConfig().auth?.adminApiKey);
|
|
36
|
+
return adminApiKey ? [adminApiKey] : [];
|
|
37
|
+
}
|
|
29
38
|
function extractRequestApiKey(c) {
|
|
30
39
|
const xApiKey = c.req.header("x-api-key")?.trim();
|
|
31
40
|
if (xApiKey) return xApiKey;
|
|
@@ -46,11 +55,14 @@ function createAuthMiddleware(options = {}) {
|
|
|
46
55
|
const getApiKeys = options.getApiKeys ?? getConfiguredApiKeys;
|
|
47
56
|
const allowUnauthenticatedPaths = options.allowUnauthenticatedPaths ?? ["/"];
|
|
48
57
|
const allowOptionsBypass = options.allowOptionsBypass ?? true;
|
|
58
|
+
const allowWhenNoApiKeys = options.allowWhenNoApiKeys ?? true;
|
|
59
|
+
const shouldSkipPath = options.shouldSkipPath ?? (() => false);
|
|
49
60
|
return async (c, next) => {
|
|
50
61
|
if (allowOptionsBypass && c.req.method === "OPTIONS") return next();
|
|
62
|
+
if (shouldSkipPath(c.req.path)) return next();
|
|
51
63
|
if (allowUnauthenticatedPaths.includes(c.req.path)) return next();
|
|
52
64
|
const apiKeys = getApiKeys();
|
|
53
|
-
if (apiKeys.length === 0) return next();
|
|
65
|
+
if (apiKeys.length === 0) return allowWhenNoApiKeys ? next() : createUnauthorizedResponse(c);
|
|
54
66
|
const requestApiKey = extractRequestApiKey(c);
|
|
55
67
|
if (!requestApiKey || !apiKeys.includes(requestApiKey)) return createUnauthorizedResponse(c);
|
|
56
68
|
return next();
|
|
@@ -1085,6 +1097,32 @@ completionRoutes.post("/", async (c) => {
|
|
|
1085
1097
|
}
|
|
1086
1098
|
});
|
|
1087
1099
|
//#endregion
|
|
1100
|
+
//#region src/routes/admin/config/route.ts
|
|
1101
|
+
const configRoutes = new Hono();
|
|
1102
|
+
const modelMappingsRequestSchema = z.object({ modelMappings: z.record(z.string(), z.string()) });
|
|
1103
|
+
configRoutes.get("/model-mappings", (c) => {
|
|
1104
|
+
return c.json({
|
|
1105
|
+
configPath: PATHS.CONFIG_PATH,
|
|
1106
|
+
modelMappings: getModelMappings()
|
|
1107
|
+
});
|
|
1108
|
+
});
|
|
1109
|
+
configRoutes.post("/model-mappings", async (c) => {
|
|
1110
|
+
try {
|
|
1111
|
+
const parseResult = modelMappingsRequestSchema.safeParse(await c.req.json());
|
|
1112
|
+
if (!parseResult.success) return c.json({ error: {
|
|
1113
|
+
message: parseResult.error.issues[0]?.message ?? "Invalid request body.",
|
|
1114
|
+
type: "invalid_request_error"
|
|
1115
|
+
} }, 400);
|
|
1116
|
+
const updatedModelMappings = setModelMappings(parseResult.data.modelMappings);
|
|
1117
|
+
return c.json({
|
|
1118
|
+
configPath: PATHS.CONFIG_PATH,
|
|
1119
|
+
modelMappings: updatedModelMappings
|
|
1120
|
+
});
|
|
1121
|
+
} catch (error) {
|
|
1122
|
+
return await forwardError(c, error);
|
|
1123
|
+
}
|
|
1124
|
+
});
|
|
1125
|
+
//#endregion
|
|
1088
1126
|
//#region src/services/copilot/create-embeddings.ts
|
|
1089
1127
|
const createEmbeddings = async (payload) => {
|
|
1090
1128
|
if (!state.copilotToken) throw new Error("Copilot token not found");
|
|
@@ -1819,6 +1857,7 @@ async function countTokensViaAnthropic(c, payload) {
|
|
|
1819
1857
|
*/
|
|
1820
1858
|
async function handleCountTokens(c) {
|
|
1821
1859
|
const anthropicPayload = await c.req.json();
|
|
1860
|
+
anthropicPayload.model = resolveMappedModel(anthropicPayload.model);
|
|
1822
1861
|
const providerModelAlias = parseProviderModelAlias(anthropicPayload.model);
|
|
1823
1862
|
if (providerModelAlias) {
|
|
1824
1863
|
anthropicPayload.model = providerModelAlias.model;
|
|
@@ -2905,14 +2944,23 @@ const MESSAGE_TYPE = "message";
|
|
|
2905
2944
|
const COMPACTION_SIGNATURE_PREFIX = "cm1#";
|
|
2906
2945
|
const COMPACTION_SIGNATURE_SEPARATOR = "@";
|
|
2907
2946
|
const THINKING_TEXT = "Thinking...";
|
|
2908
|
-
const
|
|
2947
|
+
const buildPromptCacheKey = (basePromptCacheKey, subagentAgentId) => {
|
|
2948
|
+
if (!basePromptCacheKey) return null;
|
|
2949
|
+
const normalizedSubagentAgentId = subagentAgentId?.trim() || null;
|
|
2950
|
+
if (!normalizedSubagentAgentId) return basePromptCacheKey;
|
|
2951
|
+
return `${basePromptCacheKey}:agent:${normalizedSubagentAgentId}`;
|
|
2952
|
+
};
|
|
2953
|
+
const translateAnthropicMessagesToResponsesPayload = (payload, subagentAgentId) => {
|
|
2909
2954
|
const input = [];
|
|
2910
2955
|
const applyPhase = shouldApplyPhase(payload.model);
|
|
2911
2956
|
for (const message of payload.messages) input.push(...translateMessage(message, payload.model, applyPhase));
|
|
2957
|
+
const hasOriginalTools = Array.isArray(payload.tools) && payload.tools.length > 0;
|
|
2912
2958
|
const translatedTools = convertAnthropicTools(payload.tools);
|
|
2913
2959
|
const toolChoice = convertAnthropicToolChoice(payload.tool_choice);
|
|
2914
|
-
const { sessionId:
|
|
2915
|
-
|
|
2960
|
+
const { sessionId: metadataPromptCacheKey } = parseUserIdMetadata(payload.metadata?.user_id);
|
|
2961
|
+
const sessionAffinity = requestContext.getStore()?.sessionAffinity?.trim() || null;
|
|
2962
|
+
const promptCacheKey = buildPromptCacheKey(metadataPromptCacheKey ?? sessionAffinity, subagentAgentId);
|
|
2963
|
+
const responsesPayload = {
|
|
2916
2964
|
model: payload.model,
|
|
2917
2965
|
input,
|
|
2918
2966
|
instructions: translateSystemPrompt(payload.system, payload.model),
|
|
@@ -2922,7 +2970,6 @@ const translateAnthropicMessagesToResponsesPayload = (payload) => {
|
|
|
2922
2970
|
tools: translatedTools,
|
|
2923
2971
|
tool_choice: toolChoice,
|
|
2924
2972
|
metadata: payload.metadata ? { ...payload.metadata } : null,
|
|
2925
|
-
prompt_cache_key: promptCacheKey,
|
|
2926
2973
|
stream: payload.stream ?? null,
|
|
2927
2974
|
store: false,
|
|
2928
2975
|
parallel_tool_calls: true,
|
|
@@ -2932,6 +2979,8 @@ const translateAnthropicMessagesToResponsesPayload = (payload) => {
|
|
|
2932
2979
|
},
|
|
2933
2980
|
include: ["reasoning.encrypted_content"]
|
|
2934
2981
|
};
|
|
2982
|
+
if (hasOriginalTools) responsesPayload.prompt_cache_key = promptCacheKey;
|
|
2983
|
+
return responsesPayload;
|
|
2935
2984
|
};
|
|
2936
2985
|
const encodeCompactionCarrierSignature = (compaction) => {
|
|
2937
2986
|
return `${COMPACTION_SIGNATURE_PREFIX}${compaction.encrypted_content}${COMPACTION_SIGNATURE_SEPARATOR}${compaction.id}`;
|
|
@@ -3047,8 +3096,8 @@ const resolveAssistantPhase = (_model, content, applyPhase) => {
|
|
|
3047
3096
|
if (!content.some((block) => block.type === "text")) return;
|
|
3048
3097
|
return content.some((block) => block.type === "tool_use") ? "commentary" : "final_answer";
|
|
3049
3098
|
};
|
|
3050
|
-
const shouldApplyPhase = (
|
|
3051
|
-
return
|
|
3099
|
+
const shouldApplyPhase = (_model) => {
|
|
3100
|
+
return true;
|
|
3052
3101
|
};
|
|
3053
3102
|
const createTextContent = (text) => ({
|
|
3054
3103
|
type: "input_text",
|
|
@@ -4116,7 +4165,7 @@ const handleWithChatCompletions = async (c, anthropicPayload, options) => {
|
|
|
4116
4165
|
};
|
|
4117
4166
|
const handleWithResponsesApi = async (c, anthropicPayload, options) => {
|
|
4118
4167
|
const { logger, selectedModel, ...requestOptions } = options;
|
|
4119
|
-
const responsesPayload = translateAnthropicMessagesToResponsesPayload(anthropicPayload);
|
|
4168
|
+
const responsesPayload = translateAnthropicMessagesToResponsesPayload(anthropicPayload, requestOptions.subagentMarker?.agent_id);
|
|
4120
4169
|
const recordUsage = createCopilotUsageRecorder({
|
|
4121
4170
|
endpoint: "responses",
|
|
4122
4171
|
fallbackSessionId: requestOptions.sessionId,
|
|
@@ -4322,6 +4371,9 @@ const messagesFlowHandlers = {
|
|
|
4322
4371
|
};
|
|
4323
4372
|
async function handleCompletion(c) {
|
|
4324
4373
|
const anthropicPayload = await c.req.json();
|
|
4374
|
+
const requestedModel = anthropicPayload.model;
|
|
4375
|
+
anthropicPayload.model = resolveMappedModel(anthropicPayload.model);
|
|
4376
|
+
if (anthropicPayload.model !== requestedModel) logger$3.debug(`Resolved model mapping: ${requestedModel} -> ${anthropicPayload.model}`);
|
|
4325
4377
|
const providerModelAlias = parseProviderModelAlias(anthropicPayload.model);
|
|
4326
4378
|
if (providerModelAlias) {
|
|
4327
4379
|
anthropicPayload.model = providerModelAlias.model;
|
|
@@ -4707,11 +4759,19 @@ const server = new Hono();
|
|
|
4707
4759
|
server.use(traceIdMiddleware);
|
|
4708
4760
|
server.use(logger());
|
|
4709
4761
|
server.use(cors());
|
|
4710
|
-
server.use("*", createAuthMiddleware({
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4762
|
+
server.use("*", createAuthMiddleware({
|
|
4763
|
+
allowUnauthenticatedPaths: [
|
|
4764
|
+
"/",
|
|
4765
|
+
"/usage-viewer",
|
|
4766
|
+
"/usage-viewer/"
|
|
4767
|
+
],
|
|
4768
|
+
shouldSkipPath: (path) => path.startsWith("/admin/")
|
|
4769
|
+
}));
|
|
4770
|
+
server.use("/admin/*", createAuthMiddleware({
|
|
4771
|
+
getApiKeys: getConfiguredAdminApiKeys,
|
|
4772
|
+
allowUnauthenticatedPaths: [],
|
|
4773
|
+
allowWhenNoApiKeys: false
|
|
4774
|
+
}));
|
|
4715
4775
|
server.get("/", (c) => c.text("Server running"));
|
|
4716
4776
|
server.get("/usage-viewer", (c) => {
|
|
4717
4777
|
const usageViewerFileUrl = new URL("../pages/index.html", import.meta.url);
|
|
@@ -4719,6 +4779,7 @@ server.get("/usage-viewer", (c) => {
|
|
|
4719
4779
|
});
|
|
4720
4780
|
server.get("/usage-viewer/", (c) => c.redirect("/usage-viewer", 301));
|
|
4721
4781
|
server.route("/chat/completions", completionRoutes);
|
|
4782
|
+
server.route("/admin/config", configRoutes);
|
|
4722
4783
|
server.route("/models", modelRoutes);
|
|
4723
4784
|
server.route("/embeddings", embeddingRoutes);
|
|
4724
4785
|
server.route("/usage", usageRoute);
|
|
@@ -4735,4 +4796,4 @@ server.route("/:provider/v1/models", providerModelRoutes);
|
|
|
4735
4796
|
//#endregion
|
|
4736
4797
|
export { server };
|
|
4737
4798
|
|
|
4738
|
-
//# sourceMappingURL=server-
|
|
4799
|
+
//# sourceMappingURL=server-csGHkK-m.js.map
|