@nick3/copilot-api 1.0.8 → 1.1.5

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,4 +1,4 @@
1
- import { HTTPError, PATHS, accountFromState, accountsManager, copilotBaseUrl, copilotHeaders, forwardError, getAliasTargetSet, getConfig, getCopilotUsage, getExtraPromptForModel, getModelAliases, getModelAliasesInfo, getModelRefreshIntervalMs, getReasoningEffortForModel, getSmallModel, isForceAgentEnabled, isFreeModelLoadBalancingEnabled, isMessageStartInputTokensFallbackEnabled, isNullish, listAccountsFromRegistry, mergeConfigWithDefaults, shouldCompactUseSmallModel, sleep, state } from "./accounts-manager-CJtqVqDx.js";
1
+ import { HTTPError, PATHS, accountFromState, accountsManager, copilotBaseUrl, copilotHeaders, forwardError, getAliasTargetSet, getConfig, getCopilotUsage, getExtraPromptForModel, getModelAliases, getModelAliasesInfo, getModelRefreshIntervalMs, getReasoningEffortForModel, getSmallModel, isForceAgentEnabled, isFreeModelLoadBalancingEnabled, isMessageStartInputTokensFallbackEnabled, isNullish, listAccountsFromRegistry, mergeConfigWithDefaults, shouldCompactUseSmallModel, sleep, state } from "./accounts-manager-MluR5e6y.js";
2
2
  import consola from "consola";
3
3
  import fs, { readFile } from "node:fs/promises";
4
4
  import * as path$1 from "node:path";
@@ -14,27 +14,56 @@ import { streamSSE } from "hono/streaming";
14
14
  import util from "node:util";
15
15
  import { events } from "fetch-event-stream";
16
16
 
17
- //#region src/lib/api-key-auth.ts
18
- const API_KEY_ENV_VAR = "COPILOT_API_KEY";
19
- function resolveConfiguredApiKey() {
20
- const envKey = process.env[API_KEY_ENV_VAR]?.trim();
21
- if (envKey) return envKey;
22
- const configKey = getConfig().apiKey?.trim();
23
- if (configKey) return configKey;
24
- }
25
- function parseBearerToken(value) {
26
- const trimmed = value.trim();
27
- if (!trimmed.toLowerCase().startsWith("bearer ")) return void 0;
28
- return trimmed.slice(7).trim() || void 0;
29
- }
30
- function extractRequestApiKey(headers) {
31
- const headerToken = headers.get("x-api-key")?.trim();
32
- if (headerToken) return headerToken;
33
- const bearer = headers.get("authorization");
34
- if (bearer) {
35
- const token = parseBearerToken(bearer);
36
- if (token) return token;
17
+ //#region src/lib/request-auth.ts
18
+ const LEGACY_API_KEY_ENV_VAR = "COPILOT_API_KEY";
19
+ let warnedLegacyEnvFallback = false;
20
+ let warnedLegacyConfigFallback = false;
21
+ function normalizeApiKeys(apiKeys) {
22
+ if (!Array.isArray(apiKeys)) {
23
+ if (apiKeys !== void 0) consola.warn("Invalid auth.apiKeys config. Expected an array of strings.");
24
+ return [];
25
+ }
26
+ const normalizedKeys = apiKeys.filter((key) => typeof key === "string").map((key) => key.trim()).filter((key) => key.length > 0);
27
+ if (normalizedKeys.length !== apiKeys.length) consola.warn("Invalid auth.apiKeys entries found. Only non-empty strings are allowed.");
28
+ return [...new Set(normalizedKeys)];
29
+ }
30
+ function getConfiguredApiKeys() {
31
+ const config = getConfig();
32
+ const configuredApiKeys = normalizeApiKeys(config.auth?.apiKeys);
33
+ if (configuredApiKeys.length > 0) return configuredApiKeys;
34
+ const envApiKey = process.env[LEGACY_API_KEY_ENV_VAR]?.trim();
35
+ if (envApiKey) {
36
+ if (!warnedLegacyEnvFallback) {
37
+ warnedLegacyEnvFallback = true;
38
+ consola.warn(`Using legacy ${LEGACY_API_KEY_ENV_VAR}. Please migrate to config.auth.apiKeys.`);
39
+ }
40
+ return [envApiKey];
41
+ }
42
+ const legacyConfigApiKey = config.apiKey?.trim();
43
+ if (legacyConfigApiKey) {
44
+ if (!warnedLegacyConfigFallback) {
45
+ warnedLegacyConfigFallback = true;
46
+ consola.warn("Using deprecated config.apiKey. Please migrate to config.auth.apiKeys.");
47
+ }
48
+ return [legacyConfigApiKey];
37
49
  }
50
+ return configuredApiKeys;
51
+ }
52
+ function extractRequestApiKey(c) {
53
+ const xApiKey = c.req.header("x-api-key")?.trim();
54
+ if (xApiKey) return xApiKey;
55
+ const authorization = c.req.header("authorization");
56
+ if (!authorization) return null;
57
+ const [scheme, ...rest] = authorization.trim().split(/\s+/);
58
+ if (scheme.toLowerCase() !== "bearer") return null;
59
+ return rest.join(" ").trim() || null;
60
+ }
61
+ function createUnauthorizedResponse(c) {
62
+ c.header("WWW-Authenticate", "Bearer realm=\"copilot-api\"");
63
+ return c.json({ error: {
64
+ message: "Unauthorized. Provide Authorization: Bearer <key> or x-api-key.",
65
+ type: "unauthorized"
66
+ } }, 401);
38
67
  }
39
68
  function normalizePathname(pathname) {
40
69
  if (pathname.length > 1 && pathname.endsWith("/")) return pathname.slice(0, -1);
@@ -43,10 +72,6 @@ function normalizePathname(pathname) {
43
72
  function hasPrefixBoundary(pathname, prefix) {
44
73
  return pathname === prefix || pathname.startsWith(`${prefix}/`);
45
74
  }
46
- function isProtectedPath(pathnameRaw) {
47
- const pathname = normalizePathname(pathnameRaw);
48
- return hasPrefixBoundary(pathname, "/v1") || hasPrefixBoundary(pathname, "/token") || hasPrefixBoundary(pathname, "/usage") || hasPrefixBoundary(pathname, "/chat/completions") || hasPrefixBoundary(pathname, "/embeddings") || hasPrefixBoundary(pathname, "/models") || hasPrefixBoundary(pathname, "/responses");
49
- }
50
75
  function timingSafeKeyCompare(a, b) {
51
76
  try {
52
77
  const aBuf = Buffer.from(a);
@@ -57,30 +82,21 @@ function timingSafeKeyCompare(a, b) {
57
82
  return false;
58
83
  }
59
84
  }
60
- function createApiKeyAuthMiddleware(options = {}) {
61
- const getConfiguredKey = options.getConfiguredApiKey ?? resolveConfiguredApiKey;
62
- const isPathProtected = options.isProtectedPath ?? isProtectedPath;
85
+ function createAuthMiddleware(options = {}) {
86
+ const getApiKeys = options.getApiKeys ?? getConfiguredApiKeys;
87
+ const allowUnauthenticatedPaths = new Set((options.allowUnauthenticatedPaths ?? ["/"]).map((path$2) => normalizePathname(path$2)));
88
+ const allowUnauthenticatedPathPrefixes = (options.allowUnauthenticatedPathPrefixes ?? []).map((path$2) => normalizePathname(path$2));
89
+ const allowOptionsBypass = options.allowOptionsBypass ?? true;
63
90
  return async (c, next) => {
64
- if (c.req.method === "OPTIONS") {
65
- await next();
66
- return;
67
- }
68
- const url = new URL(c.req.url, "http://local");
69
- if (!isPathProtected(url.pathname)) {
70
- await next();
71
- return;
72
- }
73
- const configuredKey = getConfiguredKey();
74
- if (!configuredKey) {
75
- await next();
76
- return;
77
- }
78
- const providedKey = extractRequestApiKey(c.req.raw.headers);
79
- if (!providedKey || !timingSafeKeyCompare(providedKey, configuredKey)) return c.json({ error: {
80
- message: "Unauthorized. Provide Authorization: Bearer <key> or x-api-key.",
81
- type: "unauthorized"
82
- } }, 401);
83
- await next();
91
+ if (allowOptionsBypass && c.req.method === "OPTIONS") return next();
92
+ const pathname = normalizePathname(new URL(c.req.url, "http://local").pathname);
93
+ if (allowUnauthenticatedPaths.has(pathname)) return next();
94
+ if (allowUnauthenticatedPathPrefixes.some((prefix) => hasPrefixBoundary(pathname, prefix))) return next();
95
+ const apiKeys = getApiKeys();
96
+ if (apiKeys.length === 0) return next();
97
+ const requestApiKey = extractRequestApiKey(c);
98
+ if (!(requestApiKey ? apiKeys.some((apiKey) => timingSafeKeyCompare(requestApiKey, apiKey)) : false)) return createUnauthorizedResponse(c);
99
+ return next();
84
100
  };
85
101
  }
86
102
 
@@ -705,6 +721,7 @@ function parseTriStateBool(value) {
705
721
  if (value === "0") return false;
706
722
  }
707
723
  const CONFIG_KEYS = new Set([
724
+ "auth",
708
725
  "extraPrompts",
709
726
  "smallModel",
710
727
  "freeModelLoadBalancing",
@@ -755,6 +772,16 @@ function parseOptionalNonNegativeNumber(value, field) {
755
772
  if (!Number.isFinite(value) || value < 0) return { error: `${field} must be a non-negative number` };
756
773
  return { value };
757
774
  }
775
+ function parseAuthConfig(value) {
776
+ if (value === null || value === void 0) return { clear: true };
777
+ if (!isPlainObject(value)) return { error: "auth must be an object" };
778
+ for (const key of Object.keys(value)) if (key !== "apiKeys") return { error: `auth.${key} is not supported` };
779
+ if (!("apiKeys" in value) || value.apiKeys === null || value.apiKeys === void 0) return { value: { apiKeys: [] } };
780
+ if (!Array.isArray(value.apiKeys)) return { error: "auth.apiKeys must be an array of strings" };
781
+ const normalizedApiKeys = value.apiKeys.filter((item) => typeof item === "string").map((item) => item.trim()).filter((item) => item.length > 0);
782
+ if (normalizedApiKeys.length !== value.apiKeys.length) return { error: "auth.apiKeys must contain non-empty strings only" };
783
+ return { value: { apiKeys: [...new Set(normalizedApiKeys)] } };
784
+ }
758
785
  function parseStringRecord(value, field) {
759
786
  if (value === null || value === void 0) return { clear: true };
760
787
  if (!isPlainObject(value)) return { error: `${field} must be an object with string values` };
@@ -830,6 +857,15 @@ function applyOptionalString(next, key, value) {
830
857
  }
831
858
  next[key] = parsed.value;
832
859
  }
860
+ function applyAuthConfig(next, value) {
861
+ const parsed = parseAuthConfig(value);
862
+ if ("error" in parsed) return parsed.error;
863
+ if ("clear" in parsed) {
864
+ delete next.auth;
865
+ return;
866
+ }
867
+ next.auth = parsed.value;
868
+ }
833
869
  function applyOptionalBoolean(next, key, value) {
834
870
  const parsed = parseOptionalBoolean(value, key);
835
871
  if ("error" in parsed) return parsed.error;
@@ -875,51 +911,29 @@ function applyModelAliases(next, value) {
875
911
  }
876
912
  next.modelAliases = parsed.value;
877
913
  }
914
+ const CONFIG_PATCH_HANDLERS = {
915
+ auth: applyAuthConfig,
916
+ extraPrompts: applyExtraPrompts,
917
+ smallModel: (next, value) => applyOptionalString(next, "smallModel", value),
918
+ freeModelLoadBalancing: (next, value) => applyOptionalBoolean(next, "freeModelLoadBalancing", value),
919
+ apiKey: (next, value) => applyOptionalString(next, "apiKey", value),
920
+ modelReasoningEfforts: applyReasoningEfforts,
921
+ modelAliases: applyModelAliases,
922
+ allowOriginalModelNamesForAliases: (next, value) => applyOptionalBoolean(next, "allowOriginalModelNamesForAliases", value),
923
+ useFunctionApplyPatch: (next, value) => applyOptionalBoolean(next, "useFunctionApplyPatch", value),
924
+ forceAgent: (next, value) => applyOptionalBoolean(next, "forceAgent", value),
925
+ compactUseSmallModel: (next, value) => applyOptionalBoolean(next, "compactUseSmallModel", value),
926
+ messageStartInputTokensFallback: (next, value) => applyOptionalBoolean(next, "messageStartInputTokensFallback", value),
927
+ modelRefreshIntervalHours: (next, value) => applyOptionalNumber(next, "modelRefreshIntervalHours", value)
928
+ };
878
929
  function applyConfigPatch(base, input) {
879
930
  const next = { ...base };
880
931
  for (const [rawKey, value] of Object.entries(input)) {
881
932
  const key = rawKey;
882
933
  if (!CONFIG_KEYS.has(key)) return { error: `Unknown config key: ${rawKey}` };
883
- let error;
884
- switch (rawKey) {
885
- case "extraPrompts":
886
- error = applyExtraPrompts(next, value);
887
- break;
888
- case "smallModel":
889
- error = applyOptionalString(next, "smallModel", value);
890
- break;
891
- case "freeModelLoadBalancing":
892
- error = applyOptionalBoolean(next, "freeModelLoadBalancing", value);
893
- break;
894
- case "apiKey":
895
- error = applyOptionalString(next, "apiKey", value);
896
- break;
897
- case "modelReasoningEfforts":
898
- error = applyReasoningEfforts(next, value);
899
- break;
900
- case "modelAliases":
901
- error = applyModelAliases(next, value);
902
- break;
903
- case "allowOriginalModelNamesForAliases":
904
- error = applyOptionalBoolean(next, "allowOriginalModelNamesForAliases", value);
905
- break;
906
- case "useFunctionApplyPatch":
907
- error = applyOptionalBoolean(next, "useFunctionApplyPatch", value);
908
- break;
909
- case "forceAgent":
910
- error = applyOptionalBoolean(next, "forceAgent", value);
911
- break;
912
- case "compactUseSmallModel":
913
- error = applyOptionalBoolean(next, "compactUseSmallModel", value);
914
- break;
915
- case "messageStartInputTokensFallback":
916
- error = applyOptionalBoolean(next, "messageStartInputTokensFallback", value);
917
- break;
918
- case "modelRefreshIntervalHours":
919
- error = applyOptionalNumber(next, "modelRefreshIntervalHours", value);
920
- break;
921
- default: return { error: `Unsupported config key: ${rawKey}` };
922
- }
934
+ const handler = CONFIG_PATCH_HANDLERS[rawKey];
935
+ if (!handler) return { error: `Unsupported config key: ${rawKey}` };
936
+ const error = handler(next, value);
923
937
  if (error) return { error };
924
938
  }
925
939
  return { config: next };
@@ -2237,11 +2251,12 @@ const createResponses = async (payload, { vision, initiator, upstreamRequestId }
2237
2251
  //#endregion
2238
2252
  //#region src/routes/messages/responses-translation.ts
2239
2253
  const MESSAGE_TYPE = "message";
2254
+ const CODEX_PHASE_MODEL = "gpt-5.3-codex";
2240
2255
  const THINKING_TEXT$1 = "Thinking...";
2241
2256
  const translateAnthropicMessagesToResponsesPayload = (payload, modelOverride) => {
2242
2257
  const model = modelOverride ?? payload.model;
2243
2258
  const input = [];
2244
- for (const message of payload.messages) input.push(...translateMessage(message));
2259
+ for (const message of payload.messages) input.push(...translateMessage(message, payload.model));
2245
2260
  const translatedTools = convertAnthropicTools(payload.tools);
2246
2261
  const toolChoice = convertAnthropicToolChoice(payload.tool_choice);
2247
2262
  const { safetyIdentifier, promptCacheKey } = parseUserId(payload.metadata?.user_id);
@@ -2267,9 +2282,9 @@ const translateAnthropicMessagesToResponsesPayload = (payload, modelOverride) =>
2267
2282
  include: ["reasoning.encrypted_content"]
2268
2283
  };
2269
2284
  };
2270
- const translateMessage = (message) => {
2285
+ const translateMessage = (message, model) => {
2271
2286
  if (message.role === "user") return translateUserMessage(message);
2272
- return translateAssistantMessage(message);
2287
+ return translateAssistantMessage(message, model);
2273
2288
  };
2274
2289
  const translateUserMessage = (message) => {
2275
2290
  if (typeof message.content === "string") return [createMessage("user", message.content)];
@@ -2278,36 +2293,46 @@ const translateUserMessage = (message) => {
2278
2293
  const pendingContent = [];
2279
2294
  for (const block of message.content) {
2280
2295
  if (block.type === "tool_result") {
2281
- flushPendingContent("user", pendingContent, items);
2296
+ flushPendingContent(pendingContent, items, { role: "user" });
2282
2297
  items.push(createFunctionCallOutput(block));
2283
2298
  continue;
2284
2299
  }
2285
2300
  const converted = translateUserContentBlock(block);
2286
2301
  if (converted) pendingContent.push(converted);
2287
2302
  }
2288
- flushPendingContent("user", pendingContent, items);
2303
+ flushPendingContent(pendingContent, items, { role: "user" });
2289
2304
  return items;
2290
2305
  };
2291
- const translateAssistantMessage = (message) => {
2292
- if (typeof message.content === "string") return [createMessage("assistant", message.content)];
2306
+ const translateAssistantMessage = (message, model) => {
2307
+ const assistantPhase = resolveAssistantPhase(model, message.content);
2308
+ if (typeof message.content === "string") return [createMessage("assistant", message.content, assistantPhase)];
2293
2309
  if (!Array.isArray(message.content)) return [];
2294
2310
  const items = [];
2295
2311
  const pendingContent = [];
2296
2312
  for (const block of message.content) {
2297
2313
  if (block.type === "tool_use") {
2298
- flushPendingContent("assistant", pendingContent, items);
2314
+ flushPendingContent(pendingContent, items, {
2315
+ role: "assistant",
2316
+ phase: assistantPhase
2317
+ });
2299
2318
  items.push(createFunctionToolCall(block));
2300
2319
  continue;
2301
2320
  }
2302
2321
  if (block.type === "thinking" && block.signature && block.signature.includes("@")) {
2303
- flushPendingContent("assistant", pendingContent, items);
2322
+ flushPendingContent(pendingContent, items, {
2323
+ role: "assistant",
2324
+ phase: assistantPhase
2325
+ });
2304
2326
  items.push(createReasoningContent(block));
2305
2327
  continue;
2306
2328
  }
2307
2329
  const converted = translateAssistantContentBlock(block);
2308
2330
  if (converted) pendingContent.push(converted);
2309
2331
  }
2310
- flushPendingContent("assistant", pendingContent, items);
2332
+ flushPendingContent(pendingContent, items, {
2333
+ role: "assistant",
2334
+ phase: assistantPhase
2335
+ });
2311
2336
  return items;
2312
2337
  };
2313
2338
  const translateUserContentBlock = (block) => {
@@ -2323,17 +2348,26 @@ const translateAssistantContentBlock = (block) => {
2323
2348
  default: return;
2324
2349
  }
2325
2350
  };
2326
- const flushPendingContent = (role, pendingContent, target) => {
2351
+ const flushPendingContent = (pendingContent, target, message) => {
2327
2352
  if (pendingContent.length === 0) return;
2328
2353
  const messageContent = [...pendingContent];
2329
- target.push(createMessage(role, messageContent));
2354
+ target.push(createMessage(message.role, messageContent, message.phase));
2330
2355
  pendingContent.length = 0;
2331
2356
  };
2332
- const createMessage = (role, content) => ({
2357
+ const createMessage = (role, content, phase) => ({
2333
2358
  type: MESSAGE_TYPE,
2334
2359
  role,
2335
- content
2360
+ content,
2361
+ ...role === "assistant" && phase ? { phase } : {}
2336
2362
  });
2363
+ const resolveAssistantPhase = (model, content) => {
2364
+ if (!shouldApplyCodexPhase(model)) return;
2365
+ if (typeof content === "string") return "final_answer";
2366
+ if (!Array.isArray(content)) return;
2367
+ if (!content.some((block) => block.type === "text")) return;
2368
+ return content.some((block) => block.type === "tool_use") ? "commentary" : "final_answer";
2369
+ };
2370
+ const shouldApplyCodexPhase = (model) => model === CODEX_PHASE_MODEL;
2337
2371
  const createTextContent = (text) => ({
2338
2372
  type: "input_text",
2339
2373
  text
@@ -2608,7 +2642,7 @@ const createChatCompletions = async (payload, account, options) => {
2608
2642
  const ctx = account ?? accountFromState();
2609
2643
  if (!ctx.copilotToken) throw new Error("Copilot token not found");
2610
2644
  const enableVision = payload.messages.some((x) => typeof x.content !== "string" && x.content?.some((x$1) => x$1.type === "image_url"));
2611
- const initiator = getChatInitiator(payload.messages);
2645
+ const initiator = options?.initiator ?? getChatInitiator(payload.messages);
2612
2646
  const headers = {
2613
2647
  ...copilotHeaders(ctx, enableVision, options?.upstreamRequestId),
2614
2648
  "X-Initiator": initiator
@@ -4057,7 +4091,7 @@ const createMessages = async (payload, account, options) => {
4057
4091
  const ctx = account ?? accountFromState();
4058
4092
  if (!ctx.copilotToken) throw new Error("Copilot token not found");
4059
4093
  const enableVision = payload.messages.some((message) => Array.isArray(message.content) && message.content.some((block) => block.type === "image"));
4060
- const initiator = getMessagesInitiator(payload);
4094
+ const initiator = options?.initiator ?? getMessagesInitiator(payload);
4061
4095
  const headers = {
4062
4096
  ...copilotHeaders(ctx, enableVision, options?.upstreamRequestId),
4063
4097
  "X-Initiator": initiator
@@ -4335,6 +4369,51 @@ function closeThinkingBlockIfOpen(state$1, events$1) {
4335
4369
  }
4336
4370
  }
4337
4371
 
4372
+ //#endregion
4373
+ //#region src/routes/messages/subagent-marker.ts
4374
+ const subagentMarkerPrefix = "__SUBAGENT_MARKER__";
4375
+ const parseSubagentMarkerFromFirstUser = (payload) => {
4376
+ const firstUserMessage = payload.messages.find((msg) => msg.role === "user");
4377
+ if (!firstUserMessage || !Array.isArray(firstUserMessage.content)) return null;
4378
+ for (const block of firstUserMessage.content) {
4379
+ if (block.type !== "text") continue;
4380
+ const marker = parseSubagentMarkerFromSystemReminder(block.text);
4381
+ if (marker) return marker;
4382
+ }
4383
+ return null;
4384
+ };
4385
+ const parseSubagentMarkerFromSystemReminder = (text) => {
4386
+ const startTag = "<system-reminder>";
4387
+ const endTag = "</system-reminder>";
4388
+ let searchFrom = 0;
4389
+ while (true) {
4390
+ const reminderStart = text.indexOf(startTag, searchFrom);
4391
+ if (reminderStart === -1) break;
4392
+ const contentStart = reminderStart + 17;
4393
+ const reminderEnd = text.indexOf(endTag, contentStart);
4394
+ if (reminderEnd === -1) break;
4395
+ const reminderContent = text.slice(contentStart, reminderEnd);
4396
+ const markerIndex = reminderContent.indexOf(subagentMarkerPrefix);
4397
+ if (markerIndex === -1) {
4398
+ searchFrom = reminderEnd + 18;
4399
+ continue;
4400
+ }
4401
+ const markerJson = reminderContent.slice(markerIndex + 19).trim();
4402
+ try {
4403
+ const parsed = JSON.parse(markerJson);
4404
+ if (!parsed.session_id || !parsed.agent_id || !parsed.agent_type) {
4405
+ searchFrom = reminderEnd + 18;
4406
+ continue;
4407
+ }
4408
+ return parsed;
4409
+ } catch {
4410
+ searchFrom = reminderEnd + 18;
4411
+ continue;
4412
+ }
4413
+ }
4414
+ return null;
4415
+ };
4416
+
4338
4417
  //#endregion
4339
4418
  //#region src/routes/messages/handler.ts
4340
4419
  const logger$2 = createHandlerLogger("messages-handler");
@@ -4353,6 +4432,9 @@ async function handleCompletion(c) {
4353
4432
  const userAgent = c.req.header("user-agent") ?? void 0;
4354
4433
  const anthropicPayload = await c.req.json();
4355
4434
  logger$2.debug("Anthropic request payload:", JSON.stringify(anthropicPayload));
4435
+ const subagentMarker = parseSubagentMarkerFromFirstUser(anthropicPayload);
4436
+ const initiatorOverride = subagentMarker ? "agent" : void 0;
4437
+ if (subagentMarker) logger$2.debug("Detected Subagent marker:", JSON.stringify(subagentMarker));
4356
4438
  const anthropicBeta = c.req.header("anthropic-beta");
4357
4439
  const isCompact = isCompactRequest(anthropicPayload);
4358
4440
  if (anthropicBeta && isWarmupProbeRequest(anthropicPayload)) anthropicPayload.model = getSmallModel();
@@ -4381,11 +4463,12 @@ async function handleCompletion(c) {
4381
4463
  userAgent,
4382
4464
  userId,
4383
4465
  safetyIdentifier: normalizedSafetyIdentifier,
4384
- promptCacheKey: normalizedPromptCacheKey
4466
+ promptCacheKey: normalizedPromptCacheKey,
4467
+ initiator: initiatorOverride
4385
4468
  });
4386
4469
  if (blockedResponse) return blockedResponse;
4387
4470
  const openAIPayload = translateToOpenAI(anthropicPayload);
4388
- const fallbackInitiator = getChatInitiator(openAIPayload.messages);
4471
+ const fallbackInitiator = initiatorOverride ?? getChatInitiator(openAIPayload.messages);
4389
4472
  const selection = await accountsManager.selectAccountForRequest([
4390
4473
  {
4391
4474
  modelId: clientModel,
@@ -4448,6 +4531,7 @@ async function handleCompletion(c) {
4448
4531
  c,
4449
4532
  anthropicPayload,
4450
4533
  anthropicBetaHeader: anthropicBeta ?? void 0,
4534
+ initiatorOverride,
4451
4535
  instr,
4452
4536
  selectedModel
4453
4537
  });
@@ -4455,27 +4539,32 @@ async function handleCompletion(c) {
4455
4539
  c,
4456
4540
  anthropicPayload,
4457
4541
  openAIPayload,
4542
+ initiatorOverride,
4458
4543
  selectedModel,
4459
4544
  instr
4460
4545
  });
4461
4546
  return await handleWithChatCompletions({
4462
4547
  c,
4463
4548
  openAIPayload,
4549
+ initiatorOverride,
4464
4550
  selectedModel,
4465
4551
  instr
4466
4552
  });
4467
4553
  }
4468
4554
  const handleWithChatCompletions = async (params) => {
4469
- const { c, openAIPayload, selectedModel, instr } = params;
4555
+ const { c, openAIPayload, initiatorOverride, selectedModel, instr } = params;
4470
4556
  logger$2.debug("Translated OpenAI request payload:", JSON.stringify(openAIPayload));
4471
4557
  const ctx = toAccountContext(instr.account);
4472
- const initiator = getChatInitiator(openAIPayload.messages);
4558
+ const initiator = initiatorOverride ?? getChatInitiator(openAIPayload.messages);
4473
4559
  const upstreamRequestId = randomUUID();
4474
4560
  instr.initiator = initiator;
4475
4561
  instr.upstreamRequestId = upstreamRequestId;
4476
4562
  let response;
4477
4563
  try {
4478
- response = await createChatCompletions(openAIPayload, ctx, { upstreamRequestId });
4564
+ response = await createChatCompletions(openAIPayload, ctx, {
4565
+ upstreamRequestId,
4566
+ initiator
4567
+ });
4479
4568
  } catch (error) {
4480
4569
  return await handleChatCompletionsCreateError({
4481
4570
  error,
@@ -4505,19 +4594,20 @@ const handleWithChatCompletions = async (params) => {
4505
4594
  }));
4506
4595
  };
4507
4596
  const handleWithResponsesApi = async (params) => {
4508
- const { c, anthropicPayload, openAIPayload, selectedModel, instr } = params;
4597
+ const { c, anthropicPayload, openAIPayload, initiatorOverride, selectedModel, instr } = params;
4509
4598
  const responsesPayload = translateAnthropicMessagesToResponsesPayload(anthropicPayload, selectedModel.id);
4510
4599
  logger$2.debug("Translated Responses payload:", JSON.stringify(responsesPayload));
4511
4600
  const { vision, initiator } = getResponsesRequestOptions(responsesPayload);
4601
+ const resolvedInitiator = initiatorOverride ?? initiator;
4512
4602
  const ctx = toAccountContext(instr.account);
4513
4603
  const upstreamRequestId = randomUUID();
4514
- instr.initiator = initiator;
4604
+ instr.initiator = resolvedInitiator;
4515
4605
  instr.upstreamRequestId = upstreamRequestId;
4516
4606
  let response;
4517
4607
  try {
4518
4608
  response = await createResponses(responsesPayload, {
4519
4609
  vision,
4520
- initiator,
4610
+ initiator: resolvedInitiator,
4521
4611
  upstreamRequestId
4522
4612
  }, ctx);
4523
4613
  } catch (error) {
@@ -4969,7 +5059,7 @@ async function streamMessagesAndLog(params) {
4969
5059
  }
4970
5060
  }
4971
5061
  const handleWithMessagesApi = async (params) => {
4972
- const { c, anthropicPayload, anthropicBetaHeader, instr, selectedModel } = params;
5062
+ const { c, anthropicPayload, anthropicBetaHeader, initiatorOverride, instr, selectedModel } = params;
4973
5063
  for (const msg of anthropicPayload.messages) if (msg.role === "assistant" && Array.isArray(msg.content)) msg.content = msg.content.filter((block) => {
4974
5064
  if (block.type !== "thinking") return true;
4975
5065
  return block.thinking && block.thinking !== "Thinking..." && block.signature && !block.signature.includes("@");
@@ -4981,13 +5071,15 @@ const handleWithMessagesApi = async (params) => {
4981
5071
  logger$2.debug("Translated Messages payload:", JSON.stringify(anthropicPayload));
4982
5072
  const ctx = toAccountContext(instr.account);
4983
5073
  const upstreamRequestId = randomUUID();
4984
- instr.initiator = getMessagesInitiator(anthropicPayload);
5074
+ const initiator = initiatorOverride ?? getMessagesInitiator(anthropicPayload);
5075
+ instr.initiator = initiator;
4985
5076
  instr.upstreamRequestId = upstreamRequestId;
4986
5077
  let response;
4987
5078
  try {
4988
5079
  response = await createMessages(anthropicPayload, ctx, {
4989
5080
  anthropicBetaHeader,
4990
- upstreamRequestId
5081
+ upstreamRequestId,
5082
+ initiator
4991
5083
  });
4992
5084
  } catch (error) {
4993
5085
  return await handleMessagesCreateError({
@@ -5635,7 +5727,7 @@ usageRoute.get("/:accountIndex", async (c) => {
5635
5727
  const server = new Hono();
5636
5728
  server.use(logger());
5637
5729
  server.use(cors());
5638
- server.use("*", createApiKeyAuthMiddleware());
5730
+ server.use("*", createAuthMiddleware({ allowUnauthenticatedPathPrefixes: ["/admin", "/api/admin"] }));
5639
5731
  server.get("/", (c) => c.text("Server running"));
5640
5732
  server.route("/chat/completions", completionRoutes);
5641
5733
  server.route("/models", modelRoutes);
@@ -5653,4 +5745,4 @@ server.route("/v1/messages", messageRoutes);
5653
5745
 
5654
5746
  //#endregion
5655
5747
  export { server };
5656
- //# sourceMappingURL=server-BnJIteDi.js.map
5748
+ //# sourceMappingURL=server-6hnk3aRJ.js.map