@relayplane/proxy 0.1.7 → 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.js CHANGED
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ DEFAULT_CONFIG: () => DEFAULT_CONFIG,
33
34
  DEFAULT_ENDPOINTS: () => DEFAULT_ENDPOINTS,
34
35
  MODEL_MAPPING: () => MODEL_MAPPING,
35
36
  MODEL_PRICING: () => MODEL_PRICING,
@@ -44,10 +45,14 @@ __export(index_exports, {
44
45
  TaskTypes: () => TaskTypes,
45
46
  calculateCost: () => calculateCost,
46
47
  calculateSavings: () => calculateSavings,
48
+ getConfigPath: () => getConfigPath,
47
49
  getInferenceConfidence: () => getInferenceConfidence,
48
50
  getModelPricing: () => getModelPricing,
51
+ getStrategy: () => getStrategy,
49
52
  inferTaskType: () => inferTaskType,
50
- startProxy: () => startProxy
53
+ loadConfig: () => loadConfig,
54
+ startProxy: () => startProxy,
55
+ watchConfig: () => watchConfig
51
56
  });
52
57
  module.exports = __toCommonJS(index_exports);
53
58
 
@@ -1623,12 +1628,127 @@ ${input.prompt}` : input.prompt;
1623
1628
  }
1624
1629
  };
1625
1630
 
1631
+ // src/config.ts
1632
+ var fs2 = __toESM(require("fs"));
1633
+ var path2 = __toESM(require("path"));
1634
+ var os2 = __toESM(require("os"));
1635
+ var import_zod = require("zod");
1636
+ var StrategySchema = import_zod.z.object({
1637
+ model: import_zod.z.string(),
1638
+ minConfidence: import_zod.z.number().min(0).max(1).optional(),
1639
+ fallback: import_zod.z.string().optional()
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();
1647
+ var ConfigSchema = import_zod.z.object({
1648
+ strategies: import_zod.z.record(import_zod.z.string(), StrategySchema).optional(),
1649
+ defaults: import_zod.z.object({
1650
+ qualityModel: import_zod.z.string().optional(),
1651
+ costModel: import_zod.z.string().optional()
1652
+ }).optional(),
1653
+ auth: AuthSchema
1654
+ });
1655
+ var DEFAULT_CONFIG = {
1656
+ strategies: {
1657
+ code_review: { model: "anthropic:claude-sonnet-4-20250514" },
1658
+ code_generation: { model: "anthropic:claude-3-5-haiku-latest" },
1659
+ analysis: { model: "anthropic:claude-sonnet-4-20250514" },
1660
+ summarization: { model: "anthropic:claude-3-5-haiku-latest" },
1661
+ creative_writing: { model: "anthropic:claude-sonnet-4-20250514" },
1662
+ data_extraction: { model: "anthropic:claude-3-5-haiku-latest" },
1663
+ translation: { model: "anthropic:claude-3-5-haiku-latest" },
1664
+ question_answering: { model: "anthropic:claude-3-5-haiku-latest" },
1665
+ general: { model: "anthropic:claude-3-5-haiku-latest" }
1666
+ },
1667
+ defaults: {
1668
+ qualityModel: "claude-sonnet-4-20250514",
1669
+ costModel: "claude-3-5-haiku-latest"
1670
+ }
1671
+ };
1672
+ function getConfigPath() {
1673
+ return path2.join(os2.homedir(), ".relayplane", "config.json");
1674
+ }
1675
+ function writeDefaultConfig() {
1676
+ const configPath = getConfigPath();
1677
+ const dir = path2.dirname(configPath);
1678
+ if (!fs2.existsSync(dir)) {
1679
+ fs2.mkdirSync(dir, { recursive: true });
1680
+ }
1681
+ if (!fs2.existsSync(configPath)) {
1682
+ fs2.writeFileSync(
1683
+ configPath,
1684
+ JSON.stringify(DEFAULT_CONFIG, null, 2) + "\n",
1685
+ "utf-8"
1686
+ );
1687
+ console.log(`[relayplane] Created default config at ${configPath}`);
1688
+ }
1689
+ }
1690
+ function loadConfig() {
1691
+ const configPath = getConfigPath();
1692
+ writeDefaultConfig();
1693
+ try {
1694
+ const raw = fs2.readFileSync(configPath, "utf-8");
1695
+ const parsed = JSON.parse(raw);
1696
+ const validated = ConfigSchema.parse(parsed);
1697
+ return validated;
1698
+ } catch (err) {
1699
+ if (err instanceof import_zod.z.ZodError) {
1700
+ console.error(`[relayplane] Invalid config: ${err.message}`);
1701
+ } else if (err instanceof SyntaxError) {
1702
+ console.error(`[relayplane] Config JSON parse error: ${err.message}`);
1703
+ } else {
1704
+ console.error(`[relayplane] Failed to load config: ${err}`);
1705
+ }
1706
+ console.log("[relayplane] Using default config");
1707
+ return DEFAULT_CONFIG;
1708
+ }
1709
+ }
1710
+ function getStrategy(config, taskType) {
1711
+ return config.strategies?.[taskType] ?? null;
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
+ }
1726
+ function watchConfig(onChange) {
1727
+ const configPath = getConfigPath();
1728
+ const dir = path2.dirname(configPath);
1729
+ if (!fs2.existsSync(dir)) {
1730
+ fs2.mkdirSync(dir, { recursive: true });
1731
+ }
1732
+ let debounceTimer = null;
1733
+ fs2.watch(dir, (eventType, filename) => {
1734
+ if (filename === "config.json") {
1735
+ if (debounceTimer) clearTimeout(debounceTimer);
1736
+ debounceTimer = setTimeout(() => {
1737
+ console.log("[relayplane] Config file changed, reloading...");
1738
+ const newConfig = loadConfig();
1739
+ onChange(newConfig);
1740
+ }, 100);
1741
+ }
1742
+ });
1743
+ }
1744
+
1626
1745
  // src/proxy.ts
1627
- var VERSION = "0.1.7";
1746
+ var VERSION = "0.1.9";
1628
1747
  var recentRuns = [];
1629
1748
  var MAX_RECENT_RUNS = 100;
1630
1749
  var modelCounts = {};
1631
1750
  var serverStartTime = 0;
1751
+ var currentConfig = loadConfig();
1632
1752
  var DEFAULT_ENDPOINTS = {
1633
1753
  anthropic: {
1634
1754
  baseUrl: "https://api.anthropic.com/v1",
@@ -1691,13 +1811,17 @@ function extractPromptText(messages) {
1691
1811
  return "";
1692
1812
  }).join("\n");
1693
1813
  }
1694
- async function forwardToAnthropic(request, targetModel, apiKey, betaHeaders) {
1814
+ async function forwardToAnthropic(request, targetModel, auth, betaHeaders) {
1695
1815
  const anthropicBody = buildAnthropicBody(request, targetModel, false);
1696
1816
  const headers = {
1697
1817
  "Content-Type": "application/json",
1698
- "x-api-key": apiKey,
1699
1818
  "anthropic-version": "2023-06-01"
1700
1819
  };
1820
+ if (auth.type === "max") {
1821
+ headers["Authorization"] = `Bearer ${auth.value}`;
1822
+ } else {
1823
+ headers["x-api-key"] = auth.value;
1824
+ }
1701
1825
  if (betaHeaders) {
1702
1826
  headers["anthropic-beta"] = betaHeaders;
1703
1827
  }
@@ -1708,13 +1832,17 @@ async function forwardToAnthropic(request, targetModel, apiKey, betaHeaders) {
1708
1832
  });
1709
1833
  return response;
1710
1834
  }
1711
- async function forwardToAnthropicStream(request, targetModel, apiKey, betaHeaders) {
1835
+ async function forwardToAnthropicStream(request, targetModel, auth, betaHeaders) {
1712
1836
  const anthropicBody = buildAnthropicBody(request, targetModel, true);
1713
1837
  const headers = {
1714
1838
  "Content-Type": "application/json",
1715
- "x-api-key": apiKey,
1716
1839
  "anthropic-version": "2023-06-01"
1717
1840
  };
1841
+ if (auth.type === "max") {
1842
+ headers["Authorization"] = `Bearer ${auth.value}`;
1843
+ } else {
1844
+ headers["x-api-key"] = auth.value;
1845
+ }
1718
1846
  if (betaHeaders) {
1719
1847
  headers["anthropic-beta"] = betaHeaders;
1720
1848
  }
@@ -2479,42 +2607,65 @@ async function startProxy(config = {}) {
2479
2607
  const confidence = getInferenceConfidence(promptText, taskType);
2480
2608
  log(`Inferred task: ${taskType} (confidence: ${confidence.toFixed(2)})`);
2481
2609
  if (routingMode !== "passthrough") {
2482
- const rule = relay.routing.get(taskType);
2483
- if (rule && rule.preferredModel) {
2484
- const parsed = parsePreferredModel(rule.preferredModel);
2610
+ const configStrategy = getStrategy(currentConfig, taskType);
2611
+ if (configStrategy) {
2612
+ const parsed = parsePreferredModel(configStrategy.model);
2485
2613
  if (parsed) {
2486
2614
  targetProvider = parsed.provider;
2487
2615
  targetModel = parsed.model;
2488
- log(`Using learned rule: ${rule.preferredModel}`);
2616
+ log(`Using config strategy: ${configStrategy.model}`);
2617
+ }
2618
+ }
2619
+ if (!configStrategy) {
2620
+ const rule = relay.routing.get(taskType);
2621
+ if (rule && rule.preferredModel) {
2622
+ const parsed = parsePreferredModel(rule.preferredModel);
2623
+ if (parsed) {
2624
+ targetProvider = parsed.provider;
2625
+ targetModel = parsed.model;
2626
+ log(`Using learned rule: ${rule.preferredModel}`);
2627
+ } else {
2628
+ const defaultRoute = DEFAULT_ROUTING[taskType];
2629
+ targetProvider = defaultRoute.provider;
2630
+ targetModel = defaultRoute.model;
2631
+ }
2489
2632
  } else {
2490
2633
  const defaultRoute = DEFAULT_ROUTING[taskType];
2491
2634
  targetProvider = defaultRoute.provider;
2492
2635
  targetModel = defaultRoute.model;
2493
2636
  }
2494
- } else {
2495
- const defaultRoute = DEFAULT_ROUTING[taskType];
2496
- targetProvider = defaultRoute.provider;
2497
- targetModel = defaultRoute.model;
2498
2637
  }
2499
2638
  if (routingMode === "cost") {
2500
- const simpleTasks = ["summarization", "data_extraction", "translation", "question_answering"];
2501
- if (simpleTasks.includes(taskType)) {
2502
- targetModel = "claude-3-5-haiku-latest";
2503
- targetProvider = "anthropic";
2504
- }
2639
+ const costModel = currentConfig.defaults?.costModel || "claude-3-5-haiku-latest";
2640
+ targetModel = costModel;
2641
+ targetProvider = "anthropic";
2642
+ log(`Cost mode: using ${costModel}`);
2505
2643
  } else if (routingMode === "quality") {
2506
- const qualityModel = process.env["RELAYPLANE_QUALITY_MODEL"] || "claude-sonnet-4-20250514";
2644
+ const qualityModel = currentConfig.defaults?.qualityModel || process.env["RELAYPLANE_QUALITY_MODEL"] || "claude-sonnet-4-20250514";
2507
2645
  targetModel = qualityModel;
2508
2646
  targetProvider = "anthropic";
2647
+ log(`Quality mode: using ${qualityModel}`);
2509
2648
  }
2510
2649
  }
2511
2650
  log(`Routing to: ${targetProvider}/${targetModel}`);
2512
- const apiKeyEnv = DEFAULT_ENDPOINTS[targetProvider]?.apiKeyEnv ?? `${targetProvider.toUpperCase()}_API_KEY`;
2513
- const apiKey = process.env[apiKeyEnv];
2514
- if (!apiKey) {
2515
- res.writeHead(500, { "Content-Type": "application/json" });
2516
- res.end(JSON.stringify({ error: `Missing ${apiKeyEnv} environment variable` }));
2517
- 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
+ }
2518
2669
  }
2519
2670
  const startTime = Date.now();
2520
2671
  const betaHeaders = req.headers["anthropic-beta"];
@@ -2525,6 +2676,7 @@ async function startProxy(config = {}) {
2525
2676
  targetProvider,
2526
2677
  targetModel,
2527
2678
  apiKey,
2679
+ anthropicAuth,
2528
2680
  relay,
2529
2681
  promptText,
2530
2682
  taskType,
@@ -2541,6 +2693,7 @@ async function startProxy(config = {}) {
2541
2693
  targetProvider,
2542
2694
  targetModel,
2543
2695
  apiKey,
2696
+ anthropicAuth,
2544
2697
  relay,
2545
2698
  promptText,
2546
2699
  taskType,
@@ -2552,6 +2705,10 @@ async function startProxy(config = {}) {
2552
2705
  );
2553
2706
  }
2554
2707
  });
2708
+ watchConfig((newConfig) => {
2709
+ currentConfig = newConfig;
2710
+ console.log("[relayplane] Config reloaded");
2711
+ });
2555
2712
  return new Promise((resolve, reject) => {
2556
2713
  server.on("error", reject);
2557
2714
  server.listen(port, host, () => {
@@ -2560,17 +2717,19 @@ async function startProxy(config = {}) {
2560
2717
  console.log(` Models: relayplane:auto, relayplane:cost, relayplane:quality`);
2561
2718
  console.log(` Endpoint: POST /v1/chat/completions`);
2562
2719
  console.log(` Stats: GET /stats, /runs, /health`);
2720
+ console.log(` Config: ~/.relayplane/config.json (hot-reload enabled)`);
2563
2721
  console.log(` Streaming: \u2705 Enabled`);
2564
2722
  resolve(server);
2565
2723
  });
2566
2724
  });
2567
2725
  }
2568
- 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) {
2569
2727
  let providerResponse;
2570
2728
  try {
2571
2729
  switch (targetProvider) {
2572
2730
  case "anthropic":
2573
- providerResponse = await forwardToAnthropicStream(request, targetModel, apiKey, betaHeaders);
2731
+ if (!anthropicAuth) throw new Error("No Anthropic auth");
2732
+ providerResponse = await forwardToAnthropicStream(request, targetModel, anthropicAuth, betaHeaders);
2574
2733
  break;
2575
2734
  case "google":
2576
2735
  providerResponse = await forwardToGeminiStream(request, targetModel, apiKey);
@@ -2648,13 +2807,14 @@ async function handleStreamingRequest(res, request, targetProvider, targetModel,
2648
2807
  });
2649
2808
  res.end();
2650
2809
  }
2651
- 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) {
2652
2811
  let providerResponse;
2653
2812
  let responseData;
2654
2813
  try {
2655
2814
  switch (targetProvider) {
2656
2815
  case "anthropic": {
2657
- providerResponse = await forwardToAnthropic(request, targetModel, apiKey, betaHeaders);
2816
+ if (!anthropicAuth) throw new Error("No Anthropic auth");
2817
+ providerResponse = await forwardToAnthropic(request, targetModel, anthropicAuth, betaHeaders);
2658
2818
  const rawData = await providerResponse.json();
2659
2819
  if (!providerResponse.ok) {
2660
2820
  res.writeHead(providerResponse.status, { "Content-Type": "application/json" });
@@ -2750,7 +2910,7 @@ async function handleNonStreamingRequest(res, request, targetProvider, targetMod
2750
2910
  }
2751
2911
 
2752
2912
  // src/types.ts
2753
- var import_zod = require("zod");
2913
+ var import_zod2 = require("zod");
2754
2914
  var TaskTypes = [
2755
2915
  "code_generation",
2756
2916
  "code_review",
@@ -2762,64 +2922,65 @@ var TaskTypes = [
2762
2922
  "question_answering",
2763
2923
  "general"
2764
2924
  ];
2765
- var TaskTypeSchema = import_zod.z.enum(TaskTypes);
2925
+ var TaskTypeSchema = import_zod2.z.enum(TaskTypes);
2766
2926
  var Providers = ["openai", "anthropic", "google", "xai", "moonshot", "local"];
2767
- var ProviderSchema = import_zod.z.enum(Providers);
2768
- var RelayPlaneConfigSchema = import_zod.z.object({
2769
- dbPath: import_zod.z.string().optional(),
2770
- providers: import_zod.z.record(ProviderSchema, import_zod.z.object({
2771
- apiKey: import_zod.z.string().optional(),
2772
- baseUrl: import_zod.z.string().optional()
2927
+ var ProviderSchema = import_zod2.z.enum(Providers);
2928
+ var RelayPlaneConfigSchema = import_zod2.z.object({
2929
+ dbPath: import_zod2.z.string().optional(),
2930
+ providers: import_zod2.z.record(ProviderSchema, import_zod2.z.object({
2931
+ apiKey: import_zod2.z.string().optional(),
2932
+ baseUrl: import_zod2.z.string().optional()
2773
2933
  })).optional(),
2774
2934
  defaultProvider: ProviderSchema.optional(),
2775
- defaultModel: import_zod.z.string().optional()
2935
+ defaultModel: import_zod2.z.string().optional()
2776
2936
  });
2777
- var RunInputSchema = import_zod.z.object({
2778
- prompt: import_zod.z.string().min(1),
2779
- systemPrompt: import_zod.z.string().optional(),
2937
+ var RunInputSchema = import_zod2.z.object({
2938
+ prompt: import_zod2.z.string().min(1),
2939
+ systemPrompt: import_zod2.z.string().optional(),
2780
2940
  taskType: TaskTypeSchema.optional(),
2781
- model: import_zod.z.string().optional(),
2782
- metadata: import_zod.z.record(import_zod.z.unknown()).optional()
2941
+ model: import_zod2.z.string().optional(),
2942
+ metadata: import_zod2.z.record(import_zod2.z.unknown()).optional()
2783
2943
  });
2784
2944
  var RuleSources = ["default", "user", "learned"];
2785
- var RoutingRuleSchema = import_zod.z.object({
2786
- id: import_zod.z.string(),
2945
+ var RoutingRuleSchema = import_zod2.z.object({
2946
+ id: import_zod2.z.string(),
2787
2947
  taskType: TaskTypeSchema,
2788
- preferredModel: import_zod.z.string(),
2789
- source: import_zod.z.enum(RuleSources),
2790
- confidence: import_zod.z.number().min(0).max(1).optional(),
2791
- sampleCount: import_zod.z.number().int().positive().optional(),
2792
- createdAt: import_zod.z.string(),
2793
- updatedAt: import_zod.z.string()
2948
+ preferredModel: import_zod2.z.string(),
2949
+ source: import_zod2.z.enum(RuleSources),
2950
+ confidence: import_zod2.z.number().min(0).max(1).optional(),
2951
+ sampleCount: import_zod2.z.number().int().positive().optional(),
2952
+ createdAt: import_zod2.z.string(),
2953
+ updatedAt: import_zod2.z.string()
2794
2954
  });
2795
2955
  var OutcomeQualities = ["excellent", "good", "acceptable", "poor", "failed"];
2796
- var OutcomeInputSchema = import_zod.z.object({
2797
- runId: import_zod.z.string().min(1),
2798
- success: import_zod.z.boolean(),
2799
- quality: import_zod.z.enum(OutcomeQualities).optional(),
2800
- latencySatisfactory: import_zod.z.boolean().optional(),
2801
- costSatisfactory: import_zod.z.boolean().optional(),
2802
- feedback: import_zod.z.string().optional()
2956
+ var OutcomeInputSchema = import_zod2.z.object({
2957
+ runId: import_zod2.z.string().min(1),
2958
+ success: import_zod2.z.boolean(),
2959
+ quality: import_zod2.z.enum(OutcomeQualities).optional(),
2960
+ latencySatisfactory: import_zod2.z.boolean().optional(),
2961
+ costSatisfactory: import_zod2.z.boolean().optional(),
2962
+ feedback: import_zod2.z.string().optional()
2803
2963
  });
2804
- var SuggestionSchema = import_zod.z.object({
2805
- id: import_zod.z.string(),
2964
+ var SuggestionSchema = import_zod2.z.object({
2965
+ id: import_zod2.z.string(),
2806
2966
  taskType: TaskTypeSchema,
2807
- currentModel: import_zod.z.string(),
2808
- suggestedModel: import_zod.z.string(),
2809
- reason: import_zod.z.string(),
2810
- confidence: import_zod.z.number().min(0).max(1),
2811
- expectedImprovement: import_zod.z.object({
2812
- successRate: import_zod.z.number().optional(),
2813
- latency: import_zod.z.number().optional(),
2814
- cost: import_zod.z.number().optional()
2967
+ currentModel: import_zod2.z.string(),
2968
+ suggestedModel: import_zod2.z.string(),
2969
+ reason: import_zod2.z.string(),
2970
+ confidence: import_zod2.z.number().min(0).max(1),
2971
+ expectedImprovement: import_zod2.z.object({
2972
+ successRate: import_zod2.z.number().optional(),
2973
+ latency: import_zod2.z.number().optional(),
2974
+ cost: import_zod2.z.number().optional()
2815
2975
  }),
2816
- sampleCount: import_zod.z.number().int().positive(),
2817
- createdAt: import_zod.z.string(),
2818
- accepted: import_zod.z.boolean().optional(),
2819
- acceptedAt: import_zod.z.string().optional()
2976
+ sampleCount: import_zod2.z.number().int().positive(),
2977
+ createdAt: import_zod2.z.string(),
2978
+ accepted: import_zod2.z.boolean().optional(),
2979
+ acceptedAt: import_zod2.z.string().optional()
2820
2980
  });
2821
2981
  // Annotate the CommonJS export names for ESM import in node:
2822
2982
  0 && (module.exports = {
2983
+ DEFAULT_CONFIG,
2823
2984
  DEFAULT_ENDPOINTS,
2824
2985
  MODEL_MAPPING,
2825
2986
  MODEL_PRICING,
@@ -2834,9 +2995,13 @@ var SuggestionSchema = import_zod.z.object({
2834
2995
  TaskTypes,
2835
2996
  calculateCost,
2836
2997
  calculateSavings,
2998
+ getConfigPath,
2837
2999
  getInferenceConfidence,
2838
3000
  getModelPricing,
3001
+ getStrategy,
2839
3002
  inferTaskType,
2840
- startProxy
3003
+ loadConfig,
3004
+ startProxy,
3005
+ watchConfig
2841
3006
  });
2842
3007
  //# sourceMappingURL=index.js.map