@nick3/copilot-api 1.10.30 → 1.10.34

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.
@@ -1,13 +1,13 @@
1
1
  import { A as accountFromState, B as compactSystemPromptStarts, C as copilotHeaders, D as prepareForCompact, E as normalizeDomain, F as resolveTraceId, L as compactAutoContinuePromptStarts, M as captureOutboundHeadersSnapshot, O as prepareInteractionHeaders, P as requestContext, R as compactMessageSections, S as copilotBaseUrl, T as copilotWebSocketHeaders, b as HTTPError, c as getUUID, d as parseUserIdMetadata, f as resolveAffinityKey, g as getCopilotUsage, h as getDeviceCode, j as state, k as prepareMessageProxyHeaders, l as isNullish, m as getGitHubUser, o as generateRequestIdFromPayload, p as sleep, s as getRootSessionId, t as pollAccessToken, u as normalizeStableSessionId, v as getProxyEnvDispatcher, x as forwardError } from "./poll-access-token-GzVkiTH8.js";
2
2
  import { a as getAccountClientIdentityByLoginAndApp, b as getCurrentIdentityEnvironment, d as loadRegistry, g as saveRegistry, h as saveAccountToken, l as listAccountsFromRegistry, m as removeAccountToken, p as removeAccountFromRegistry, r as addAccountToRegistry, t as isAccountType } from "./account-DpW8RaT6.js";
3
3
  import { r as ensurePaths, t as PATHS } from "./paths-Bpsb62LK.js";
4
- import { C as isResponsesApiWebSocketEnabled, D as resolveModelAlias, E as resolveMappedModel, S as isResponsesApiWebSearchEnabled, T as mergeConfigWithDefaults, _ as isAccountAffinityEnabled, a as getConfig, b as isMessagesApiEnabled, c as getModelAliases, d as getProviderConfig, g as getSmallModel, i as getClaudeTokenMultiplier, k as shouldCompactUseSmallModel, l as getModelAliasesInfo, m as getReasoningEffortForModel, n as getAliasTargetSet, o as getExtraPromptForModel, p as getRawProviderConfig, r as getAnthropicApiKey, s as getLogLevel, t as PROVIDER_TYPE_ANTHROPIC, u as getModelRefreshIntervalMs, v as isForceAgentEnabled, x as isResponsesApiContextManagementEnabled, y as isMessageStartInputTokensFallbackEnabled } from "./config-XZv75uoU.js";
5
- import { a as forwardCodexResponses, n as setupCodexToken } from "./token-9O2KJcF5.js";
4
+ import { A as shouldCompactUseSmallModel, C as isResponsesApiWebSearchEnabled, D as resolveMappedModel, E as mergeConfigWithDefaults, O as resolveModelAlias, S as isResponsesApiContextManagementEnabled, _ as getSmallModel, a as getConfig, b as isMessageStartInputTokensFallbackEnabled, c as getModelAliases, d as getModelResponsesApiCompactThreshold$1, f as getProviderConfig, h as getReasoningEffortForModel, i as getClaudeTokenMultiplier, l as getModelAliasesInfo, m as getRawProviderConfig, n as getAliasTargetSet, o as getExtraPromptForModel, r as getAnthropicApiKey, s as getLogLevel, t as PROVIDER_TYPE_ANTHROPIC, u as getModelRefreshIntervalMs, v as isAccountAffinityEnabled, w as isResponsesApiWebSocketEnabled, x as isMessagesApiEnabled, y as isForceAgentEnabled } from "./config-BaU_aWgi.js";
5
+ import { a as forwardCodexResponses, n as setupCodexToken } from "./token-671YFxgv.js";
6
6
  import { i as getRequestOutboundStore, r as getRedactedHeaderKeys } from "./request-outbound-DZTxxtcx.js";
7
7
  import { i as isMcpHttpEnabledFromEnv, n as DEFAULT_MCP_HTTP_PATH } from "./mcp-http-config-DMdUDz1D.js";
8
8
  import { a as isDeferredToolName, c as parseMcpToolSearchSentinel, i as isBridgeToolSearchName, l as selectDeferredToolsByNames, n as BRIDGE_TOOL_SEARCH_NAME, o as listDeferredToolNames, r as formatToolSearchBridgeArguments, s as normalizeToolSearchBridgeArguments, u as shouldEnableResponsesToolSearch } from "./mcp-server-DEqHrXFq.js";
9
9
  import { n as handleStreamableHttpMcpRequest, r as mcpHttpCorsOptions } from "./mcp-http-DI4Vz01p.js";
10
- import { C as createAuthMiddleware, S as isDevModeEnabled, _ as normalizeMessagesUsage, b as copilotFetch, c as accountsManager, d as extractResponsesUsageFromStreamEvent, f as getClientIpInfo, g as normalizeEmbeddingsUsage, h as normalizeChatCompletionsUsage, l as applySharedSessionAffinityRetention, m as getStatsStore, p as getRequestHistoryStore, s as updateQuotaRefreshSchedulerFromConfig, t as closeResponsesBridge, u as extractResponsesUsageFromResult, v as normalizeResponsesUsage, x as flushPendingCapture, y as toLocalDateString } from "./responses-bridge-registry-JjUvTCST.js";
10
+ import { C as createAuthMiddleware, S as isDevModeEnabled, _ as normalizeMessagesUsage, b as copilotFetch, c as accountsManager, d as extractResponsesUsageFromStreamEvent, f as getClientIpInfo, g as normalizeEmbeddingsUsage, h as normalizeChatCompletionsUsage, l as applySharedSessionAffinityRetention, m as getStatsStore, p as getRequestHistoryStore, s as updateQuotaRefreshSchedulerFromConfig, t as closeResponsesBridge, u as extractResponsesUsageFromResult, v as normalizeResponsesUsage, x as flushPendingCapture, y as toLocalDateString } from "./responses-bridge-registry-DqCoY6Ex.js";
11
11
  import consola from "consola";
12
12
  import fs, { readFile } from "node:fs/promises";
13
13
  import { createHash, randomUUID } from "node:crypto";
@@ -954,6 +954,44 @@ const stripCacheControl = (payload) => {
954
954
  }
955
955
  }
956
956
  };
957
+ const normalizeCacheControl = (cacheControl) => {
958
+ if (!cacheControl || typeof cacheControl !== "object" || Array.isArray(cacheControl)) return;
959
+ const type = cacheControl.type;
960
+ return type === "ephemeral" ? { type } : void 0;
961
+ };
962
+ const applyTopLevelCacheControl = (payload) => {
963
+ const topLevel = normalizeCacheControl(payload.cache_control);
964
+ if (!topLevel) {
965
+ if (payload.cache_control !== void 0) delete payload.cache_control;
966
+ return;
967
+ }
968
+ delete payload.cache_control;
969
+ for (let m = payload.messages.length - 1; m >= 0; m--) {
970
+ const message = payload.messages[m];
971
+ if (typeof message.content === "string") {
972
+ message.content = [{
973
+ type: "text",
974
+ text: message.content,
975
+ cache_control: { ...topLevel }
976
+ }];
977
+ return;
978
+ }
979
+ if (!Array.isArray(message.content)) continue;
980
+ for (let b = message.content.length - 1; b >= 0; b--) {
981
+ const block = message.content[b];
982
+ if (block.type !== "text" && block.type !== "image" && block.type !== "tool_use" && block.type !== "tool_result") continue;
983
+ block.cache_control ??= { ...topLevel };
984
+ return;
985
+ }
986
+ }
987
+ };
988
+ const stripToolEagerInputStreaming = (payload) => {
989
+ if (!payload.tools || payload.tools.length === 0) return;
990
+ for (const tool of payload.tools) {
991
+ const extended = tool;
992
+ if ("eager_input_streaming" in extended) delete extended.eager_input_streaming;
993
+ }
994
+ };
957
995
  const filterAssistantThinkingBlocks = (payload) => {
958
996
  for (const msg of payload.messages) if (msg.role === "assistant" && Array.isArray(msg.content)) msg.content = msg.content.filter((block) => {
959
997
  if (block.type !== "thinking") return true;
@@ -962,6 +1000,8 @@ const filterAssistantThinkingBlocks = (payload) => {
962
1000
  };
963
1001
  const prepareMessagesApiPayload = (payload, selectedModel) => {
964
1002
  stripCacheControl(payload);
1003
+ applyTopLevelCacheControl(payload);
1004
+ stripToolEagerInputStreaming(payload);
965
1005
  filterAssistantThinkingBlocks(payload);
966
1006
  const hasThinking = Boolean(payload.thinking);
967
1007
  const toolChoice = payload.tool_choice;
@@ -3746,6 +3786,41 @@ const createHandlerLogger = (name) => {
3746
3786
  return instance;
3747
3787
  };
3748
3788
  //#endregion
3789
+ //#region src/lib/provider-model.ts
3790
+ const parseProviderModelAlias = (model) => {
3791
+ const separatorIndex = model.indexOf("/");
3792
+ if (separatorIndex <= 0 || separatorIndex === model.length - 1) return null;
3793
+ const provider = model.slice(0, separatorIndex).trim();
3794
+ const providerModel = model.slice(separatorIndex + 1).trim();
3795
+ if (!provider || !providerModel) return null;
3796
+ return {
3797
+ model: providerModel,
3798
+ provider
3799
+ };
3800
+ };
3801
+ const resolveExistingProviderModelAlias = (model, resolveProvider) => {
3802
+ const alias = parseProviderModelAlias(model);
3803
+ if (!alias) return null;
3804
+ return resolveProvider(alias.provider) ? alias : null;
3805
+ };
3806
+ const createFallbackModel = (modelId) => ({
3807
+ capabilities: {
3808
+ family: "provider",
3809
+ limits: {},
3810
+ object: "model_capabilities",
3811
+ supports: {},
3812
+ tokenizer: "o200k_base",
3813
+ type: "chat"
3814
+ },
3815
+ id: modelId,
3816
+ model_picker_enabled: false,
3817
+ name: modelId,
3818
+ object: "model",
3819
+ preview: false,
3820
+ vendor: "provider",
3821
+ version: "unknown"
3822
+ });
3823
+ //#endregion
3749
3824
  //#region src/lib/rate-limit.ts
3750
3825
  async function checkRateLimit(state) {
3751
3826
  if (state.rateLimitSeconds === void 0) return;
@@ -3771,6 +3846,210 @@ async function checkRateLimit(state) {
3771
3846
  consola.info("Rate limit wait completed, proceeding with request");
3772
3847
  }
3773
3848
  //#endregion
3849
+ //#region src/lib/provider-resolver.ts
3850
+ function isMissingCodexCredentialsError(error) {
3851
+ return error instanceof Error && error.message === "Codex credentials not found. Run `copilot-api auth login --provider codex` first.";
3852
+ }
3853
+ async function resolveProviderConfig$3(providerName) {
3854
+ const normalizedProviderName = providerName.trim();
3855
+ if (!normalizedProviderName) return null;
3856
+ if (normalizedProviderName === "codex") {
3857
+ if (getRawProviderConfig(normalizedProviderName)?.enabled === false) return null;
3858
+ try {
3859
+ await setupCodexToken();
3860
+ } catch (error) {
3861
+ if (isMissingCodexCredentialsError(error)) return null;
3862
+ throw error;
3863
+ }
3864
+ const providerConfig = getProviderConfig(normalizedProviderName);
3865
+ if (!providerConfig) return null;
3866
+ return {
3867
+ ...providerConfig,
3868
+ apiKey: state.codexAccessToken ?? providerConfig.apiKey
3869
+ };
3870
+ }
3871
+ return getProviderConfig(normalizedProviderName);
3872
+ }
3873
+ //#endregion
3874
+ //#region src/lib/token-usage.ts
3875
+ function normalizeOpenAIUsage$1(usage) {
3876
+ const cacheCreationInputTokens = usage?.prompt_tokens_details?.cache_creation_input_tokens;
3877
+ const cacheReadInputTokens = usage?.prompt_tokens_details?.cached_tokens;
3878
+ return {
3879
+ inputTokens: usage?.prompt_tokens === void 0 ? void 0 : Math.max(0, usage.prompt_tokens - (cacheCreationInputTokens ?? 0) - (cacheReadInputTokens ?? 0)),
3880
+ outputTokens: usage?.completion_tokens,
3881
+ cacheCreationInputTokens,
3882
+ cacheReadInputTokens
3883
+ };
3884
+ }
3885
+ function createProviderTokenUsageRecorder(options) {
3886
+ const logger = createHandlerLogger(`provider-${options.providerName}`);
3887
+ return (usage) => {
3888
+ logger.debug(`${options.endpoint} usage`, {
3889
+ model: options.model,
3890
+ provider: options.providerName,
3891
+ ...usage
3892
+ });
3893
+ };
3894
+ }
3895
+ //#endregion
3896
+ //#region src/services/providers/provider-proxy.ts
3897
+ const SHARED_FORWARDABLE_HEADERS = ["accept", "user-agent"];
3898
+ const ANTHROPIC_FORWARDABLE_HEADERS = ["anthropic-version", "anthropic-beta"];
3899
+ const STRIPPED_RESPONSE_HEADERS = [
3900
+ "connection",
3901
+ "content-encoding",
3902
+ "content-length",
3903
+ "keep-alive",
3904
+ "proxy-authenticate",
3905
+ "proxy-authorization",
3906
+ "te",
3907
+ "trailer",
3908
+ "transfer-encoding",
3909
+ "upgrade"
3910
+ ];
3911
+ function buildProviderUpstreamHeaders(providerConfig, requestHeaders) {
3912
+ const authHeaders = {};
3913
+ if (providerConfig.authType === "x-api-key") authHeaders["x-api-key"] = providerConfig.apiKey;
3914
+ else authHeaders.authorization = `Bearer ${providerConfig.apiKey}`;
3915
+ const headers = {
3916
+ "content-type": "application/json",
3917
+ accept: "application/json",
3918
+ ...authHeaders
3919
+ };
3920
+ for (const headerName of SHARED_FORWARDABLE_HEADERS) {
3921
+ const headerValue = requestHeaders.get(headerName);
3922
+ if (headerValue) headers[headerName] = headerValue;
3923
+ }
3924
+ if (providerConfig.type !== "anthropic") return headers;
3925
+ for (const headerName of ANTHROPIC_FORWARDABLE_HEADERS) {
3926
+ const headerValue = requestHeaders.get(headerName);
3927
+ if (headerValue) headers[headerName] = headerValue;
3928
+ }
3929
+ return headers;
3930
+ }
3931
+ function createProviderProxyResponse(upstreamResponse, body) {
3932
+ const headers = new Headers(upstreamResponse.headers);
3933
+ for (const headerName of STRIPPED_RESPONSE_HEADERS) headers.delete(headerName);
3934
+ return new Response(body ?? upstreamResponse.body, {
3935
+ headers,
3936
+ status: upstreamResponse.status,
3937
+ statusText: upstreamResponse.statusText
3938
+ });
3939
+ }
3940
+ async function forwardProviderMessages(providerConfig, payload, requestHeaders, fetchImpl = fetch) {
3941
+ return await fetchImpl(`${providerConfig.baseUrl}/v1/messages`, {
3942
+ method: "POST",
3943
+ headers: buildProviderUpstreamHeaders(providerConfig, requestHeaders),
3944
+ body: JSON.stringify(payload)
3945
+ });
3946
+ }
3947
+ async function forwardProviderChatCompletions(providerConfig, payload, requestHeaders, fetchImpl = fetch) {
3948
+ return await fetchImpl(`${providerConfig.baseUrl}/v1/chat/completions`, {
3949
+ method: "POST",
3950
+ headers: buildProviderUpstreamHeaders(providerConfig, requestHeaders),
3951
+ body: JSON.stringify(payload)
3952
+ });
3953
+ }
3954
+ async function forwardProviderResponses(providerConfig, payload, requestHeaders) {
3955
+ return await fetch(`${providerConfig.baseUrl}/v1/responses`, {
3956
+ method: "POST",
3957
+ headers: buildProviderUpstreamHeaders(providerConfig, requestHeaders),
3958
+ body: JSON.stringify(payload)
3959
+ });
3960
+ }
3961
+ async function forwardProviderModels(providerConfig, requestHeaders, fetchImpl = fetch) {
3962
+ return await fetchImpl(`${providerConfig.baseUrl}/v1/models`, {
3963
+ method: "GET",
3964
+ headers: buildProviderUpstreamHeaders(providerConfig, requestHeaders)
3965
+ });
3966
+ }
3967
+ //#endregion
3968
+ //#region src/routes/provider/chat-completions/handler.ts
3969
+ const logger$8 = createHandlerLogger("provider-chat-completions-handler");
3970
+ async function handleProviderChatCompletionsForProvider(c, options) {
3971
+ const { payload, provider } = options;
3972
+ const providerConfig = await (c.get("providerConfigResolver") ?? resolveProviderConfig$3)(provider);
3973
+ if (providerConfig?.type !== "openai-compatible") return c.json({ error: {
3974
+ message: `Provider '${provider}' does not support the /v1/chat/completions endpoint`,
3975
+ type: "invalid_request_error"
3976
+ } }, 400);
3977
+ const modelConfig = providerConfig.models?.[payload.model];
3978
+ applyProviderModelDefaults(payload, modelConfig);
3979
+ applyMissingExtraBody$1(payload, { extraBody: modelConfig?.extraBody });
3980
+ applyProviderStreamOptions(payload);
3981
+ debugJson(logger$8, "provider.chat_completions.request", {
3982
+ payload,
3983
+ provider
3984
+ });
3985
+ const upstreamResponse = await forwardProviderChatCompletions(providerConfig, payload, c.req.raw.headers);
3986
+ if (!upstreamResponse.ok) {
3987
+ logger$8.error("Failed to create provider chat completions", {
3988
+ provider,
3989
+ statusCode: upstreamResponse.status
3990
+ });
3991
+ throw new HTTPError(`Failed to create ${provider} chat completions`, upstreamResponse);
3992
+ }
3993
+ const recordUsage = createProviderChatCompletionsUsageRecorder(payload, provider);
3994
+ const contentType = upstreamResponse.headers.get("content-type") ?? "";
3995
+ if (Boolean(payload.stream) && contentType.includes("text/event-stream")) return streamProviderChatCompletions(c, upstreamResponse, {
3996
+ provider,
3997
+ recordUsage
3998
+ });
3999
+ const responseBody = await upstreamResponse.clone().json();
4000
+ recordUsage(normalizeOpenAIUsage$1(responseBody.usage));
4001
+ debugJson(logger$8, "provider.chat_completions.response", responseBody);
4002
+ return createProviderProxyResponse(upstreamResponse);
4003
+ }
4004
+ const applyProviderModelDefaults = (payload, modelConfig) => {
4005
+ payload.temperature ??= modelConfig?.temperature;
4006
+ payload.top_p ??= modelConfig?.topP;
4007
+ payload.top_k ??= modelConfig?.topK;
4008
+ };
4009
+ const applyMissingExtraBody$1 = (payload, options) => {
4010
+ for (const [key, value] of Object.entries(options.extraBody ?? {})) if (!Object.hasOwn(payload, key)) payload[key] = value;
4011
+ };
4012
+ const applyProviderStreamOptions = (payload) => {
4013
+ if (!payload.stream) return;
4014
+ payload.stream_options = {
4015
+ ...payload.stream_options ?? {},
4016
+ include_usage: true
4017
+ };
4018
+ };
4019
+ const createProviderChatCompletionsUsageRecorder = (payload, provider) => createProviderTokenUsageRecorder({
4020
+ endpoint: "chat_completions",
4021
+ model: payload.model,
4022
+ providerName: provider
4023
+ });
4024
+ const streamProviderChatCompletions = (c, upstreamResponse, options) => {
4025
+ logger$8.debug("provider.chat_completions.streaming", { provider: options.provider });
4026
+ return streamSSE(c, async (stream) => {
4027
+ let usage = {};
4028
+ try {
4029
+ for await (const chunk of events(upstreamResponse)) {
4030
+ debugJson(logger$8, "provider.chat_completions.stream_chunk", chunk);
4031
+ if (chunk.data && chunk.data !== "[DONE]") {
4032
+ const parsedChunk = parseChatCompletionChunkData(chunk.data);
4033
+ if (parsedChunk?.usage) usage = normalizeOpenAIUsage$1(parsedChunk.usage);
4034
+ }
4035
+ await stream.writeSSE({
4036
+ event: chunk.event,
4037
+ data: chunk.data ?? ""
4038
+ });
4039
+ }
4040
+ } finally {
4041
+ options.recordUsage(usage);
4042
+ }
4043
+ });
4044
+ };
4045
+ const parseChatCompletionChunkData = (data) => {
4046
+ try {
4047
+ return JSON.parse(data);
4048
+ } catch {
4049
+ return null;
4050
+ }
4051
+ };
4052
+ //#endregion
3774
4053
  //#region src/routes/chat-completions/support.ts
3775
4054
  const CHAT_COMPLETIONS_ENDPOINT$1 = "/chat/completions";
3776
4055
  const GPT_5_4_MODEL_ID = "gpt-5.4";
@@ -3915,10 +4194,21 @@ function maybeRejectChatCompletionsClientModel(c, store, params) {
3915
4194
  return null;
3916
4195
  }
3917
4196
  async function handleCompletion$1(c) {
4197
+ const payload = await c.req.json();
4198
+ const mappedModelResolver = c.get("resolveMappedModel") ?? resolveMappedModel;
4199
+ const providerConfigResolver = c.get("providerConfigResolver") ?? getProviderConfig;
4200
+ payload.model = mappedModelResolver(payload.model);
4201
+ const providerModelAlias = resolveExistingProviderModelAlias(payload.model, providerConfigResolver);
4202
+ if (providerModelAlias) {
4203
+ payload.model = providerModelAlias.model;
4204
+ return await handleProviderChatCompletionsForProvider(c, {
4205
+ payload,
4206
+ provider: providerModelAlias.provider
4207
+ });
4208
+ }
3918
4209
  await checkRateLimit(state);
3919
4210
  const store = getRequestHistoryStore();
3920
4211
  const request = buildRequestContext$1(c);
3921
- const payload = await c.req.json();
3922
4212
  const clientModel = payload.model;
3923
4213
  const streamRequested = Boolean(payload.stream);
3924
4214
  const normalizedPromptCacheKey = applyChatRequestMetadata(request, payload, getChatInitiator(payload.messages));
@@ -4515,44 +4805,9 @@ async function runEmbeddingsWithAccount({ c, store, ctx, payload, clientModel, s
4515
4805
  }
4516
4806
  }
4517
4807
  //#endregion
4518
- //#region src/lib/provider-model.ts
4519
- const parseProviderModelAlias = (model) => {
4520
- const separatorIndex = model.indexOf("/");
4521
- if (separatorIndex <= 0 || separatorIndex === model.length - 1) return null;
4522
- const provider = model.slice(0, separatorIndex).trim();
4523
- const providerModel = model.slice(separatorIndex + 1).trim();
4524
- if (!provider || !providerModel) return null;
4525
- return {
4526
- model: providerModel,
4527
- provider
4528
- };
4529
- };
4530
- const resolveExistingProviderModelAlias = (model, resolveProvider) => {
4531
- const alias = parseProviderModelAlias(model);
4532
- if (!alias) return null;
4533
- return resolveProvider(alias.provider) ? alias : null;
4534
- };
4535
- const createFallbackModel = (modelId) => ({
4536
- capabilities: {
4537
- family: "provider",
4538
- limits: {},
4539
- object: "model_capabilities",
4540
- supports: {},
4541
- tokenizer: "o200k_base",
4542
- type: "chat"
4543
- },
4544
- id: modelId,
4545
- model_picker_enabled: false,
4546
- name: modelId,
4547
- object: "model",
4548
- preview: false,
4549
- vendor: "provider",
4550
- version: "unknown"
4551
- });
4552
- //#endregion
4553
4808
  //#region src/routes/provider/messages/count-tokens-handler.ts
4554
4809
  const logger$6 = createHandlerLogger("provider-count-tokens-handler");
4555
- const resolveProviderConfig$3 = (c, provider) => {
4810
+ const resolveProviderConfig$2 = (c, provider) => {
4556
4811
  return (c.get("providerConfigResolver") ?? getProviderConfig)(provider);
4557
4812
  };
4558
4813
  async function handleProviderCountTokens(c) {
@@ -4565,7 +4820,7 @@ async function handleProviderCountTokens(c) {
4565
4820
  async function handleProviderCountTokensForProvider(c, options) {
4566
4821
  const { payload: anthropicPayload, provider } = options;
4567
4822
  normalizeSystemMessages(anthropicPayload);
4568
- const providerConfig = resolveProviderConfig$3(c, provider);
4823
+ const providerConfig = resolveProviderConfig$2(c, provider);
4569
4824
  if (!providerConfig) return c.json({ error: {
4570
4825
  message: `Provider '${provider}' not found or disabled`,
4571
4826
  type: "invalid_request_error"
@@ -5045,7 +5300,11 @@ const consumeResponsesWebSocketStream = async (stream) => {
5045
5300
  for await (const chunk of stream) {
5046
5301
  if (!chunk.data || chunk.data === "[DONE]") continue;
5047
5302
  const event = JSON.parse(chunk.data);
5048
- if (event.type === "error") throw new Error(event.message);
5303
+ if (event.type === "error") {
5304
+ const status = typeof event.code === "string" ? parseInt(event.code, 10) : NaN;
5305
+ const httpStatus = Number.isFinite(status) && status >= 100 && status < 600 ? status : 500;
5306
+ throw new HTTPError(event.message, new Response(JSON.stringify({ error: { message: event.message } }), { status: httpStatus }));
5307
+ }
5049
5308
  if (event.type === "response.completed" || event.type === "response.failed" || event.type === "response.incomplete") return event.response;
5050
5309
  }
5051
5310
  throw new Error("Responses websocket ended without a terminal response");
@@ -6025,82 +6284,10 @@ function closeThinkingBlockIfOpen(state, events) {
6025
6284
  }
6026
6285
  }
6027
6286
  //#endregion
6028
- //#region src/services/providers/provider-proxy.ts
6029
- const SHARED_FORWARDABLE_HEADERS = ["accept", "user-agent"];
6030
- const ANTHROPIC_FORWARDABLE_HEADERS = ["anthropic-version", "anthropic-beta"];
6031
- const STRIPPED_RESPONSE_HEADERS = [
6032
- "connection",
6033
- "content-encoding",
6034
- "content-length",
6035
- "keep-alive",
6036
- "proxy-authenticate",
6037
- "proxy-authorization",
6038
- "te",
6039
- "trailer",
6040
- "transfer-encoding",
6041
- "upgrade"
6042
- ];
6043
- function buildProviderUpstreamHeaders(providerConfig, requestHeaders) {
6044
- const authHeaders = {};
6045
- if (providerConfig.authType === "x-api-key") authHeaders["x-api-key"] = providerConfig.apiKey;
6046
- else authHeaders.authorization = `Bearer ${providerConfig.apiKey}`;
6047
- const headers = {
6048
- "content-type": "application/json",
6049
- accept: "application/json",
6050
- ...authHeaders
6051
- };
6052
- for (const headerName of SHARED_FORWARDABLE_HEADERS) {
6053
- const headerValue = requestHeaders.get(headerName);
6054
- if (headerValue) headers[headerName] = headerValue;
6055
- }
6056
- if (providerConfig.type !== "anthropic") return headers;
6057
- for (const headerName of ANTHROPIC_FORWARDABLE_HEADERS) {
6058
- const headerValue = requestHeaders.get(headerName);
6059
- if (headerValue) headers[headerName] = headerValue;
6060
- }
6061
- return headers;
6062
- }
6063
- function createProviderProxyResponse(upstreamResponse, body) {
6064
- const headers = new Headers(upstreamResponse.headers);
6065
- for (const headerName of STRIPPED_RESPONSE_HEADERS) headers.delete(headerName);
6066
- return new Response(body ?? upstreamResponse.body, {
6067
- headers,
6068
- status: upstreamResponse.status,
6069
- statusText: upstreamResponse.statusText
6070
- });
6071
- }
6072
- async function forwardProviderMessages(providerConfig, payload, requestHeaders, fetchImpl = fetch) {
6073
- return await fetchImpl(`${providerConfig.baseUrl}/v1/messages`, {
6074
- method: "POST",
6075
- headers: buildProviderUpstreamHeaders(providerConfig, requestHeaders),
6076
- body: JSON.stringify(payload)
6077
- });
6078
- }
6079
- async function forwardProviderChatCompletions(providerConfig, payload, requestHeaders, fetchImpl = fetch) {
6080
- return await fetchImpl(`${providerConfig.baseUrl}/v1/chat/completions`, {
6081
- method: "POST",
6082
- headers: buildProviderUpstreamHeaders(providerConfig, requestHeaders),
6083
- body: JSON.stringify(payload)
6084
- });
6085
- }
6086
- async function forwardProviderResponses(providerConfig, payload, requestHeaders) {
6087
- return await fetch(`${providerConfig.baseUrl}/v1/responses`, {
6088
- method: "POST",
6089
- headers: buildProviderUpstreamHeaders(providerConfig, requestHeaders),
6090
- body: JSON.stringify(payload)
6091
- });
6092
- }
6093
- async function forwardProviderModels(providerConfig, requestHeaders, fetchImpl = fetch) {
6094
- return await fetchImpl(`${providerConfig.baseUrl}/v1/models`, {
6095
- method: "GET",
6096
- headers: buildProviderUpstreamHeaders(providerConfig, requestHeaders)
6097
- });
6098
- }
6099
- //#endregion
6100
6287
  //#region src/routes/provider/messages/handler.ts
6101
6288
  const logger$5 = createHandlerLogger("provider-messages-handler");
6102
6289
  const getProviderFetch$1 = (c) => c.get("providerFetch") ?? fetch;
6103
- const resolveProviderConfig$2 = (c, provider) => {
6290
+ const resolveProviderConfig$1 = (c, provider) => {
6104
6291
  return (c.get("providerConfigResolver") ?? getProviderConfig)(provider);
6105
6292
  };
6106
6293
  const OPENAI_COMPATIBLE_CONTEXT_CACHE_MARKER_LIMIT = 4;
@@ -6136,7 +6323,7 @@ async function handleProviderMessages(c) {
6136
6323
  }
6137
6324
  async function handleProviderMessagesForProvider(c, options) {
6138
6325
  const { instrumentation, payload, provider } = options;
6139
- const providerConfig = resolveProviderConfig$2(c, provider);
6326
+ const providerConfig = resolveProviderConfig$1(c, provider);
6140
6327
  if (!providerConfig) {
6141
6328
  const message = `Provider '${provider}' not found or disabled`;
6142
6329
  instrumentation?.onError?.({
@@ -7008,6 +7195,7 @@ const stringifyToolSearchArguments = (argumentsValue) => {
7008
7195
  };
7009
7196
  const DEFAULT_RESPONSES_COMPACT_THRESHOLD_RATIO = .9;
7010
7197
  const responsesUtilsDependencies = {
7198
+ getModelResponsesApiCompactThreshold: getModelResponsesApiCompactThreshold$1,
7011
7199
  isResponsesApiContextManagementEnabled,
7012
7200
  isResponsesApiWebSocketEnabled
7013
7201
  };
@@ -7116,6 +7304,11 @@ const resolveResponsesCompactThreshold = (maxPromptTokens, compactThresholdRatio
7116
7304
  if (typeof maxPromptTokens === "number" && maxPromptTokens > 0) return Math.floor(maxPromptTokens * compactThresholdRatio);
7117
7305
  return 2e5 * compactThresholdRatio;
7118
7306
  };
7307
+ const getModelResponsesApiCompactThreshold = (model) => {
7308
+ const threshold = responsesUtilsDependencies.getModelResponsesApiCompactThreshold(model);
7309
+ if (typeof threshold !== "number" || !Number.isFinite(threshold) || threshold <= 0) return;
7310
+ return threshold;
7311
+ };
7119
7312
  const createCompactionContextManagement = (compactThreshold) => [{
7120
7313
  type: "compaction",
7121
7314
  compact_threshold: compactThreshold
@@ -7123,7 +7316,7 @@ const createCompactionContextManagement = (compactThreshold) => [{
7123
7316
  const applyResponsesApiContextManagement = (payload, maxPromptTokens, compactThresholdRatio = DEFAULT_RESPONSES_COMPACT_THRESHOLD_RATIO) => {
7124
7317
  if (payload.context_management !== void 0) return;
7125
7318
  if (!responsesUtilsDependencies.isResponsesApiContextManagementEnabled()) return;
7126
- payload.context_management = createCompactionContextManagement(resolveResponsesCompactThreshold(maxPromptTokens, compactThresholdRatio));
7319
+ payload.context_management = createCompactionContextManagement(getModelResponsesApiCompactThreshold(payload.model) ?? resolveResponsesCompactThreshold(maxPromptTokens, compactThresholdRatio));
7127
7320
  };
7128
7321
  const compactInputByLatestCompaction = (payload) => {
7129
7322
  if (!Array.isArray(payload.input) || payload.input.length === 0) return;
@@ -8492,14 +8685,14 @@ function getModels() {
8492
8685
  //#region src/routes/provider/models/route.ts
8493
8686
  const logger$3 = createHandlerLogger("provider-models-handler");
8494
8687
  const getProviderFetch = (c) => c.get("providerFetch") ?? fetch;
8495
- const resolveProviderConfig$1 = (c, provider) => {
8688
+ const resolveProviderConfig = (c, provider) => {
8496
8689
  return (c.get("providerConfigResolver") ?? getProviderConfig)(provider);
8497
8690
  };
8498
8691
  const providerModelRoutes = new Hono();
8499
8692
  providerModelRoutes.get("/", async (c) => {
8500
8693
  const provider = c.req.param("provider") ?? "";
8501
8694
  try {
8502
- const providerConfig = resolveProviderConfig$1(c, provider);
8695
+ const providerConfig = resolveProviderConfig(c, provider);
8503
8696
  if (!providerConfig) return c.json({ error: {
8504
8697
  message: `Provider '${provider}' not found or disabled`,
8505
8698
  type: "invalid_request_error"
@@ -8560,31 +8753,6 @@ const isCodexRateLimitWindow = (value) => {
8560
8753
  return typeof record.reset_after_seconds === "number" && typeof record.reset_at === "number" && typeof record.used_percent === "number" && typeof record.window_minutes === "number";
8561
8754
  };
8562
8755
  //#endregion
8563
- //#region src/lib/provider-resolver.ts
8564
- function isMissingCodexCredentialsError(error) {
8565
- return error instanceof Error && error.message === "Codex credentials not found. Run `copilot-api auth login --provider codex` first.";
8566
- }
8567
- async function resolveProviderConfig(providerName) {
8568
- const normalizedProviderName = providerName.trim();
8569
- if (!normalizedProviderName) return null;
8570
- if (normalizedProviderName === "codex") {
8571
- if (getRawProviderConfig(normalizedProviderName)?.enabled === false) return null;
8572
- try {
8573
- await setupCodexToken();
8574
- } catch (error) {
8575
- if (isMissingCodexCredentialsError(error)) return null;
8576
- throw error;
8577
- }
8578
- const providerConfig = getProviderConfig(normalizedProviderName);
8579
- if (!providerConfig) return null;
8580
- return {
8581
- ...providerConfig,
8582
- apiKey: state.codexAccessToken ?? providerConfig.apiKey
8583
- };
8584
- }
8585
- return getProviderConfig(normalizedProviderName);
8586
- }
8587
- //#endregion
8588
8756
  //#region src/routes/provider/responses/handler.ts
8589
8757
  const logger$2 = createHandlerLogger("provider-responses-handler");
8590
8758
  async function handleProviderResponsesForProvider(c, options) {
@@ -8593,7 +8761,7 @@ async function handleProviderResponsesForProvider(c, options) {
8593
8761
  payload,
8594
8762
  provider
8595
8763
  });
8596
- const providerConfig = await resolveProviderConfig(provider);
8764
+ const providerConfig = await resolveProviderConfig$3(provider);
8597
8765
  if (providerConfig?.type !== "openai-responses") return c.json({ error: {
8598
8766
  message: `Provider '${provider}' does not support the /v1/responses endpoint`,
8599
8767
  type: "invalid_request_error"
@@ -8731,7 +8899,7 @@ const handleResponses = async (c) => {
8731
8899
  debugJson(logger$1, "Responses request payload:", payload);
8732
8900
  const requestedModel = payload.model;
8733
8901
  payload.model = resolveMappedModel(payload.model);
8734
- if (payload.model !== requestedModel) logger$1.debug(`Resolved model mapping: ${requestedModel} -> ${payload.model}`);
8902
+ if (payload.model !== requestedModel) consola.debug(`Resolved model mapping: ${requestedModel} -> ${payload.model}`);
8735
8903
  const providerModelAlias = parseProviderModelAlias(payload.model);
8736
8904
  if (providerModelAlias) {
8737
8905
  payload.model = providerModelAlias.model;
@@ -9360,4 +9528,4 @@ createServer();
9360
9528
  //#endregion
9361
9529
  export { createServer };
9362
9530
 
9363
- //# sourceMappingURL=server-BYKxAFro.js.map
9531
+ //# sourceMappingURL=server-C7pCkArb.js.map