@relayplane/proxy 0.1.8 → 0.1.9

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/index.d.mts CHANGED
@@ -1071,6 +1071,19 @@ declare const ConfigSchema: z.ZodObject<{
1071
1071
  qualityModel?: string | undefined;
1072
1072
  costModel?: string | undefined;
1073
1073
  }>>;
1074
+ auth: z.ZodOptional<z.ZodObject<{
1075
+ anthropicApiKey: z.ZodOptional<z.ZodString>;
1076
+ anthropicMaxToken: z.ZodOptional<z.ZodString>;
1077
+ useMaxForModels: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1078
+ }, "strip", z.ZodTypeAny, {
1079
+ anthropicApiKey?: string | undefined;
1080
+ anthropicMaxToken?: string | undefined;
1081
+ useMaxForModels?: string[] | undefined;
1082
+ }, {
1083
+ anthropicApiKey?: string | undefined;
1084
+ anthropicMaxToken?: string | undefined;
1085
+ useMaxForModels?: string[] | undefined;
1086
+ }>>;
1074
1087
  }, "strip", z.ZodTypeAny, {
1075
1088
  strategies?: Record<string, {
1076
1089
  model: string;
@@ -1081,6 +1094,11 @@ declare const ConfigSchema: z.ZodObject<{
1081
1094
  qualityModel?: string | undefined;
1082
1095
  costModel?: string | undefined;
1083
1096
  } | undefined;
1097
+ auth?: {
1098
+ anthropicApiKey?: string | undefined;
1099
+ anthropicMaxToken?: string | undefined;
1100
+ useMaxForModels?: string[] | undefined;
1101
+ } | undefined;
1084
1102
  }, {
1085
1103
  strategies?: Record<string, {
1086
1104
  model: string;
@@ -1091,6 +1109,11 @@ declare const ConfigSchema: z.ZodObject<{
1091
1109
  qualityModel?: string | undefined;
1092
1110
  costModel?: string | undefined;
1093
1111
  } | undefined;
1112
+ auth?: {
1113
+ anthropicApiKey?: string | undefined;
1114
+ anthropicMaxToken?: string | undefined;
1115
+ useMaxForModels?: string[] | undefined;
1116
+ } | undefined;
1094
1117
  }>;
1095
1118
  type StrategyConfig = z.infer<typeof StrategySchema>;
1096
1119
  type Config = z.infer<typeof ConfigSchema>;
package/dist/index.d.ts CHANGED
@@ -1071,6 +1071,19 @@ declare const ConfigSchema: z.ZodObject<{
1071
1071
  qualityModel?: string | undefined;
1072
1072
  costModel?: string | undefined;
1073
1073
  }>>;
1074
+ auth: z.ZodOptional<z.ZodObject<{
1075
+ anthropicApiKey: z.ZodOptional<z.ZodString>;
1076
+ anthropicMaxToken: z.ZodOptional<z.ZodString>;
1077
+ useMaxForModels: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1078
+ }, "strip", z.ZodTypeAny, {
1079
+ anthropicApiKey?: string | undefined;
1080
+ anthropicMaxToken?: string | undefined;
1081
+ useMaxForModels?: string[] | undefined;
1082
+ }, {
1083
+ anthropicApiKey?: string | undefined;
1084
+ anthropicMaxToken?: string | undefined;
1085
+ useMaxForModels?: string[] | undefined;
1086
+ }>>;
1074
1087
  }, "strip", z.ZodTypeAny, {
1075
1088
  strategies?: Record<string, {
1076
1089
  model: string;
@@ -1081,6 +1094,11 @@ declare const ConfigSchema: z.ZodObject<{
1081
1094
  qualityModel?: string | undefined;
1082
1095
  costModel?: string | undefined;
1083
1096
  } | undefined;
1097
+ auth?: {
1098
+ anthropicApiKey?: string | undefined;
1099
+ anthropicMaxToken?: string | undefined;
1100
+ useMaxForModels?: string[] | undefined;
1101
+ } | undefined;
1084
1102
  }, {
1085
1103
  strategies?: Record<string, {
1086
1104
  model: string;
@@ -1091,6 +1109,11 @@ declare const ConfigSchema: z.ZodObject<{
1091
1109
  qualityModel?: string | undefined;
1092
1110
  costModel?: string | undefined;
1093
1111
  } | undefined;
1112
+ auth?: {
1113
+ anthropicApiKey?: string | undefined;
1114
+ anthropicMaxToken?: string | undefined;
1115
+ useMaxForModels?: string[] | undefined;
1116
+ } | undefined;
1094
1117
  }>;
1095
1118
  type StrategyConfig = z.infer<typeof StrategySchema>;
1096
1119
  type Config = z.infer<typeof ConfigSchema>;
package/dist/index.js CHANGED
@@ -1638,12 +1638,19 @@ var StrategySchema = import_zod.z.object({
1638
1638
  minConfidence: import_zod.z.number().min(0).max(1).optional(),
1639
1639
  fallback: import_zod.z.string().optional()
1640
1640
  });
1641
+ var AuthSchema = import_zod.z.object({
1642
+ anthropicApiKey: import_zod.z.string().optional(),
1643
+ anthropicMaxToken: import_zod.z.string().optional(),
1644
+ useMaxForModels: import_zod.z.array(import_zod.z.string()).optional()
1645
+ // Default: ['opus']
1646
+ }).optional();
1641
1647
  var ConfigSchema = import_zod.z.object({
1642
1648
  strategies: import_zod.z.record(import_zod.z.string(), StrategySchema).optional(),
1643
1649
  defaults: import_zod.z.object({
1644
1650
  qualityModel: import_zod.z.string().optional(),
1645
1651
  costModel: import_zod.z.string().optional()
1646
- }).optional()
1652
+ }).optional(),
1653
+ auth: AuthSchema
1647
1654
  });
1648
1655
  var DEFAULT_CONFIG = {
1649
1656
  strategies: {
@@ -1703,6 +1710,19 @@ function loadConfig() {
1703
1710
  function getStrategy(config, taskType) {
1704
1711
  return config.strategies?.[taskType] ?? null;
1705
1712
  }
1713
+ function getAnthropicAuth(config, model) {
1714
+ const auth = config.auth;
1715
+ const useMaxForModels = auth?.useMaxForModels ?? ["opus"];
1716
+ const shouldUseMax = useMaxForModels.some((m) => model.toLowerCase().includes(m.toLowerCase()));
1717
+ if (shouldUseMax && auth?.anthropicMaxToken) {
1718
+ return { type: "max", value: auth.anthropicMaxToken };
1719
+ }
1720
+ const apiKey = auth?.anthropicApiKey ?? process.env["ANTHROPIC_API_KEY"];
1721
+ if (apiKey) {
1722
+ return { type: "apiKey", value: apiKey };
1723
+ }
1724
+ return null;
1725
+ }
1706
1726
  function watchConfig(onChange) {
1707
1727
  const configPath = getConfigPath();
1708
1728
  const dir = path2.dirname(configPath);
@@ -1723,7 +1743,7 @@ function watchConfig(onChange) {
1723
1743
  }
1724
1744
 
1725
1745
  // src/proxy.ts
1726
- var VERSION = "0.1.8";
1746
+ var VERSION = "0.1.9";
1727
1747
  var recentRuns = [];
1728
1748
  var MAX_RECENT_RUNS = 100;
1729
1749
  var modelCounts = {};
@@ -1791,13 +1811,17 @@ function extractPromptText(messages) {
1791
1811
  return "";
1792
1812
  }).join("\n");
1793
1813
  }
1794
- async function forwardToAnthropic(request, targetModel, apiKey, betaHeaders) {
1814
+ async function forwardToAnthropic(request, targetModel, auth, betaHeaders) {
1795
1815
  const anthropicBody = buildAnthropicBody(request, targetModel, false);
1796
1816
  const headers = {
1797
1817
  "Content-Type": "application/json",
1798
- "x-api-key": apiKey,
1799
1818
  "anthropic-version": "2023-06-01"
1800
1819
  };
1820
+ if (auth.type === "max") {
1821
+ headers["Authorization"] = `Bearer ${auth.value}`;
1822
+ } else {
1823
+ headers["x-api-key"] = auth.value;
1824
+ }
1801
1825
  if (betaHeaders) {
1802
1826
  headers["anthropic-beta"] = betaHeaders;
1803
1827
  }
@@ -1808,13 +1832,17 @@ async function forwardToAnthropic(request, targetModel, apiKey, betaHeaders) {
1808
1832
  });
1809
1833
  return response;
1810
1834
  }
1811
- async function forwardToAnthropicStream(request, targetModel, apiKey, betaHeaders) {
1835
+ async function forwardToAnthropicStream(request, targetModel, auth, betaHeaders) {
1812
1836
  const anthropicBody = buildAnthropicBody(request, targetModel, true);
1813
1837
  const headers = {
1814
1838
  "Content-Type": "application/json",
1815
- "x-api-key": apiKey,
1816
1839
  "anthropic-version": "2023-06-01"
1817
1840
  };
1841
+ if (auth.type === "max") {
1842
+ headers["Authorization"] = `Bearer ${auth.value}`;
1843
+ } else {
1844
+ headers["x-api-key"] = auth.value;
1845
+ }
1818
1846
  if (betaHeaders) {
1819
1847
  headers["anthropic-beta"] = betaHeaders;
1820
1848
  }
@@ -2620,12 +2648,24 @@ async function startProxy(config = {}) {
2620
2648
  }
2621
2649
  }
2622
2650
  log(`Routing to: ${targetProvider}/${targetModel}`);
2623
- const apiKeyEnv = DEFAULT_ENDPOINTS[targetProvider]?.apiKeyEnv ?? `${targetProvider.toUpperCase()}_API_KEY`;
2624
- const apiKey = process.env[apiKeyEnv];
2625
- if (!apiKey) {
2626
- res.writeHead(500, { "Content-Type": "application/json" });
2627
- res.end(JSON.stringify({ error: `Missing ${apiKeyEnv} environment variable` }));
2628
- return;
2651
+ let apiKey;
2652
+ let anthropicAuth = null;
2653
+ if (targetProvider === "anthropic") {
2654
+ anthropicAuth = getAnthropicAuth(currentConfig, targetModel);
2655
+ if (!anthropicAuth) {
2656
+ res.writeHead(500, { "Content-Type": "application/json" });
2657
+ res.end(JSON.stringify({ error: "No Anthropic auth configured (set ANTHROPIC_API_KEY or config.auth.anthropicMaxToken)" }));
2658
+ return;
2659
+ }
2660
+ log(`Using ${anthropicAuth.type === "max" ? "MAX token" : "API key"} auth for ${targetModel}`);
2661
+ } else {
2662
+ const apiKeyEnv = DEFAULT_ENDPOINTS[targetProvider]?.apiKeyEnv ?? `${targetProvider.toUpperCase()}_API_KEY`;
2663
+ apiKey = process.env[apiKeyEnv];
2664
+ if (!apiKey) {
2665
+ res.writeHead(500, { "Content-Type": "application/json" });
2666
+ res.end(JSON.stringify({ error: `Missing ${apiKeyEnv} environment variable` }));
2667
+ return;
2668
+ }
2629
2669
  }
2630
2670
  const startTime = Date.now();
2631
2671
  const betaHeaders = req.headers["anthropic-beta"];
@@ -2636,6 +2676,7 @@ async function startProxy(config = {}) {
2636
2676
  targetProvider,
2637
2677
  targetModel,
2638
2678
  apiKey,
2679
+ anthropicAuth,
2639
2680
  relay,
2640
2681
  promptText,
2641
2682
  taskType,
@@ -2652,6 +2693,7 @@ async function startProxy(config = {}) {
2652
2693
  targetProvider,
2653
2694
  targetModel,
2654
2695
  apiKey,
2696
+ anthropicAuth,
2655
2697
  relay,
2656
2698
  promptText,
2657
2699
  taskType,
@@ -2681,12 +2723,13 @@ async function startProxy(config = {}) {
2681
2723
  });
2682
2724
  });
2683
2725
  }
2684
- async function handleStreamingRequest(res, request, targetProvider, targetModel, apiKey, relay, promptText, taskType, confidence, routingMode, startTime, log, betaHeaders) {
2726
+ async function handleStreamingRequest(res, request, targetProvider, targetModel, apiKey, anthropicAuth, relay, promptText, taskType, confidence, routingMode, startTime, log, betaHeaders) {
2685
2727
  let providerResponse;
2686
2728
  try {
2687
2729
  switch (targetProvider) {
2688
2730
  case "anthropic":
2689
- providerResponse = await forwardToAnthropicStream(request, targetModel, apiKey, betaHeaders);
2731
+ if (!anthropicAuth) throw new Error("No Anthropic auth");
2732
+ providerResponse = await forwardToAnthropicStream(request, targetModel, anthropicAuth, betaHeaders);
2690
2733
  break;
2691
2734
  case "google":
2692
2735
  providerResponse = await forwardToGeminiStream(request, targetModel, apiKey);
@@ -2764,13 +2807,14 @@ async function handleStreamingRequest(res, request, targetProvider, targetModel,
2764
2807
  });
2765
2808
  res.end();
2766
2809
  }
2767
- async function handleNonStreamingRequest(res, request, targetProvider, targetModel, apiKey, relay, promptText, taskType, confidence, routingMode, startTime, log, betaHeaders) {
2810
+ async function handleNonStreamingRequest(res, request, targetProvider, targetModel, apiKey, anthropicAuth, relay, promptText, taskType, confidence, routingMode, startTime, log, betaHeaders) {
2768
2811
  let providerResponse;
2769
2812
  let responseData;
2770
2813
  try {
2771
2814
  switch (targetProvider) {
2772
2815
  case "anthropic": {
2773
- providerResponse = await forwardToAnthropic(request, targetModel, apiKey, betaHeaders);
2816
+ if (!anthropicAuth) throw new Error("No Anthropic auth");
2817
+ providerResponse = await forwardToAnthropic(request, targetModel, anthropicAuth, betaHeaders);
2774
2818
  const rawData = await providerResponse.json();
2775
2819
  if (!providerResponse.ok) {
2776
2820
  res.writeHead(providerResponse.status, { "Content-Type": "application/json" });