@relayplane/proxy 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -1
- package/dist/cli.js +126 -15
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +126 -15
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +96 -1
- package/dist/index.d.ts +96 -1
- package/dist/index.js +181 -60
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +175 -59
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1020,4 +1020,99 @@ declare class OutcomeRecorder {
|
|
|
1020
1020
|
};
|
|
1021
1021
|
}
|
|
1022
1022
|
|
|
1023
|
-
|
|
1023
|
+
/**
|
|
1024
|
+
* Configuration Management
|
|
1025
|
+
*
|
|
1026
|
+
* Handles loading, validation, and hot-reload of the config file.
|
|
1027
|
+
*
|
|
1028
|
+
* @packageDocumentation
|
|
1029
|
+
*/
|
|
1030
|
+
|
|
1031
|
+
/**
|
|
1032
|
+
* Strategy configuration for a task type
|
|
1033
|
+
*/
|
|
1034
|
+
declare const StrategySchema: z.ZodObject<{
|
|
1035
|
+
model: z.ZodString;
|
|
1036
|
+
minConfidence: z.ZodOptional<z.ZodNumber>;
|
|
1037
|
+
fallback: z.ZodOptional<z.ZodString>;
|
|
1038
|
+
}, "strip", z.ZodTypeAny, {
|
|
1039
|
+
model: string;
|
|
1040
|
+
minConfidence?: number | undefined;
|
|
1041
|
+
fallback?: string | undefined;
|
|
1042
|
+
}, {
|
|
1043
|
+
model: string;
|
|
1044
|
+
minConfidence?: number | undefined;
|
|
1045
|
+
fallback?: string | undefined;
|
|
1046
|
+
}>;
|
|
1047
|
+
/**
|
|
1048
|
+
* Full config schema
|
|
1049
|
+
*/
|
|
1050
|
+
declare const ConfigSchema: z.ZodObject<{
|
|
1051
|
+
strategies: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
1052
|
+
model: z.ZodString;
|
|
1053
|
+
minConfidence: z.ZodOptional<z.ZodNumber>;
|
|
1054
|
+
fallback: z.ZodOptional<z.ZodString>;
|
|
1055
|
+
}, "strip", z.ZodTypeAny, {
|
|
1056
|
+
model: string;
|
|
1057
|
+
minConfidence?: number | undefined;
|
|
1058
|
+
fallback?: string | undefined;
|
|
1059
|
+
}, {
|
|
1060
|
+
model: string;
|
|
1061
|
+
minConfidence?: number | undefined;
|
|
1062
|
+
fallback?: string | undefined;
|
|
1063
|
+
}>>>;
|
|
1064
|
+
defaults: z.ZodOptional<z.ZodObject<{
|
|
1065
|
+
qualityModel: z.ZodOptional<z.ZodString>;
|
|
1066
|
+
costModel: z.ZodOptional<z.ZodString>;
|
|
1067
|
+
}, "strip", z.ZodTypeAny, {
|
|
1068
|
+
qualityModel?: string | undefined;
|
|
1069
|
+
costModel?: string | undefined;
|
|
1070
|
+
}, {
|
|
1071
|
+
qualityModel?: string | undefined;
|
|
1072
|
+
costModel?: string | undefined;
|
|
1073
|
+
}>>;
|
|
1074
|
+
}, "strip", z.ZodTypeAny, {
|
|
1075
|
+
strategies?: Record<string, {
|
|
1076
|
+
model: string;
|
|
1077
|
+
minConfidence?: number | undefined;
|
|
1078
|
+
fallback?: string | undefined;
|
|
1079
|
+
}> | undefined;
|
|
1080
|
+
defaults?: {
|
|
1081
|
+
qualityModel?: string | undefined;
|
|
1082
|
+
costModel?: string | undefined;
|
|
1083
|
+
} | undefined;
|
|
1084
|
+
}, {
|
|
1085
|
+
strategies?: Record<string, {
|
|
1086
|
+
model: string;
|
|
1087
|
+
minConfidence?: number | undefined;
|
|
1088
|
+
fallback?: string | undefined;
|
|
1089
|
+
}> | undefined;
|
|
1090
|
+
defaults?: {
|
|
1091
|
+
qualityModel?: string | undefined;
|
|
1092
|
+
costModel?: string | undefined;
|
|
1093
|
+
} | undefined;
|
|
1094
|
+
}>;
|
|
1095
|
+
type StrategyConfig = z.infer<typeof StrategySchema>;
|
|
1096
|
+
type Config = z.infer<typeof ConfigSchema>;
|
|
1097
|
+
/**
|
|
1098
|
+
* Default configuration
|
|
1099
|
+
*/
|
|
1100
|
+
declare const DEFAULT_CONFIG: Config;
|
|
1101
|
+
/**
|
|
1102
|
+
* Get config file path
|
|
1103
|
+
*/
|
|
1104
|
+
declare function getConfigPath(): string;
|
|
1105
|
+
/**
|
|
1106
|
+
* Load and validate config
|
|
1107
|
+
*/
|
|
1108
|
+
declare function loadConfig(): Config;
|
|
1109
|
+
/**
|
|
1110
|
+
* Get strategy for a task type from config
|
|
1111
|
+
*/
|
|
1112
|
+
declare function getStrategy(config: Config, taskType: TaskType): StrategyConfig | null;
|
|
1113
|
+
/**
|
|
1114
|
+
* Watch config file for changes
|
|
1115
|
+
*/
|
|
1116
|
+
declare function watchConfig(onChange: (config: Config) => void): void;
|
|
1117
|
+
|
|
1118
|
+
export { type Config, DEFAULT_CONFIG, DEFAULT_ENDPOINTS, MODEL_MAPPING, MODEL_PRICING, type ModelCostBreakdown, type Outcome, type OutcomeQuality, OutcomeRecorder, PatternDetector, type Provider, type ProviderEndpoint, ProviderSchema, Providers, type ProxyConfig, RelayPlane, type RelayPlaneConfig, RoutingEngine, type RoutingRule, type RuleSource, type RunRecord, type SavingsReport, Store, type StrategyConfig, type Suggestion, type TaskType, TaskTypeSchema, TaskTypes, calculateCost, calculateSavings, getConfigPath, getInferenceConfidence, getModelPricing, getStrategy, inferTaskType, loadConfig, startProxy, watchConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -1020,4 +1020,99 @@ declare class OutcomeRecorder {
|
|
|
1020
1020
|
};
|
|
1021
1021
|
}
|
|
1022
1022
|
|
|
1023
|
-
|
|
1023
|
+
/**
|
|
1024
|
+
* Configuration Management
|
|
1025
|
+
*
|
|
1026
|
+
* Handles loading, validation, and hot-reload of the config file.
|
|
1027
|
+
*
|
|
1028
|
+
* @packageDocumentation
|
|
1029
|
+
*/
|
|
1030
|
+
|
|
1031
|
+
/**
|
|
1032
|
+
* Strategy configuration for a task type
|
|
1033
|
+
*/
|
|
1034
|
+
declare const StrategySchema: z.ZodObject<{
|
|
1035
|
+
model: z.ZodString;
|
|
1036
|
+
minConfidence: z.ZodOptional<z.ZodNumber>;
|
|
1037
|
+
fallback: z.ZodOptional<z.ZodString>;
|
|
1038
|
+
}, "strip", z.ZodTypeAny, {
|
|
1039
|
+
model: string;
|
|
1040
|
+
minConfidence?: number | undefined;
|
|
1041
|
+
fallback?: string | undefined;
|
|
1042
|
+
}, {
|
|
1043
|
+
model: string;
|
|
1044
|
+
minConfidence?: number | undefined;
|
|
1045
|
+
fallback?: string | undefined;
|
|
1046
|
+
}>;
|
|
1047
|
+
/**
|
|
1048
|
+
* Full config schema
|
|
1049
|
+
*/
|
|
1050
|
+
declare const ConfigSchema: z.ZodObject<{
|
|
1051
|
+
strategies: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
1052
|
+
model: z.ZodString;
|
|
1053
|
+
minConfidence: z.ZodOptional<z.ZodNumber>;
|
|
1054
|
+
fallback: z.ZodOptional<z.ZodString>;
|
|
1055
|
+
}, "strip", z.ZodTypeAny, {
|
|
1056
|
+
model: string;
|
|
1057
|
+
minConfidence?: number | undefined;
|
|
1058
|
+
fallback?: string | undefined;
|
|
1059
|
+
}, {
|
|
1060
|
+
model: string;
|
|
1061
|
+
minConfidence?: number | undefined;
|
|
1062
|
+
fallback?: string | undefined;
|
|
1063
|
+
}>>>;
|
|
1064
|
+
defaults: z.ZodOptional<z.ZodObject<{
|
|
1065
|
+
qualityModel: z.ZodOptional<z.ZodString>;
|
|
1066
|
+
costModel: z.ZodOptional<z.ZodString>;
|
|
1067
|
+
}, "strip", z.ZodTypeAny, {
|
|
1068
|
+
qualityModel?: string | undefined;
|
|
1069
|
+
costModel?: string | undefined;
|
|
1070
|
+
}, {
|
|
1071
|
+
qualityModel?: string | undefined;
|
|
1072
|
+
costModel?: string | undefined;
|
|
1073
|
+
}>>;
|
|
1074
|
+
}, "strip", z.ZodTypeAny, {
|
|
1075
|
+
strategies?: Record<string, {
|
|
1076
|
+
model: string;
|
|
1077
|
+
minConfidence?: number | undefined;
|
|
1078
|
+
fallback?: string | undefined;
|
|
1079
|
+
}> | undefined;
|
|
1080
|
+
defaults?: {
|
|
1081
|
+
qualityModel?: string | undefined;
|
|
1082
|
+
costModel?: string | undefined;
|
|
1083
|
+
} | undefined;
|
|
1084
|
+
}, {
|
|
1085
|
+
strategies?: Record<string, {
|
|
1086
|
+
model: string;
|
|
1087
|
+
minConfidence?: number | undefined;
|
|
1088
|
+
fallback?: string | undefined;
|
|
1089
|
+
}> | undefined;
|
|
1090
|
+
defaults?: {
|
|
1091
|
+
qualityModel?: string | undefined;
|
|
1092
|
+
costModel?: string | undefined;
|
|
1093
|
+
} | undefined;
|
|
1094
|
+
}>;
|
|
1095
|
+
type StrategyConfig = z.infer<typeof StrategySchema>;
|
|
1096
|
+
type Config = z.infer<typeof ConfigSchema>;
|
|
1097
|
+
/**
|
|
1098
|
+
* Default configuration
|
|
1099
|
+
*/
|
|
1100
|
+
declare const DEFAULT_CONFIG: Config;
|
|
1101
|
+
/**
|
|
1102
|
+
* Get config file path
|
|
1103
|
+
*/
|
|
1104
|
+
declare function getConfigPath(): string;
|
|
1105
|
+
/**
|
|
1106
|
+
* Load and validate config
|
|
1107
|
+
*/
|
|
1108
|
+
declare function loadConfig(): Config;
|
|
1109
|
+
/**
|
|
1110
|
+
* Get strategy for a task type from config
|
|
1111
|
+
*/
|
|
1112
|
+
declare function getStrategy(config: Config, taskType: TaskType): StrategyConfig | null;
|
|
1113
|
+
/**
|
|
1114
|
+
* Watch config file for changes
|
|
1115
|
+
*/
|
|
1116
|
+
declare function watchConfig(onChange: (config: Config) => void): void;
|
|
1117
|
+
|
|
1118
|
+
export { type Config, DEFAULT_CONFIG, DEFAULT_ENDPOINTS, MODEL_MAPPING, MODEL_PRICING, type ModelCostBreakdown, type Outcome, type OutcomeQuality, OutcomeRecorder, PatternDetector, type Provider, type ProviderEndpoint, ProviderSchema, Providers, type ProxyConfig, RelayPlane, type RelayPlaneConfig, RoutingEngine, type RoutingRule, type RuleSource, type RunRecord, type SavingsReport, Store, type StrategyConfig, type Suggestion, type TaskType, TaskTypeSchema, TaskTypes, calculateCost, calculateSavings, getConfigPath, getInferenceConfidence, getModelPricing, getStrategy, inferTaskType, loadConfig, startProxy, watchConfig };
|
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
|
-
|
|
53
|
+
loadConfig: () => loadConfig,
|
|
54
|
+
startProxy: () => startProxy,
|
|
55
|
+
watchConfig: () => watchConfig
|
|
51
56
|
});
|
|
52
57
|
module.exports = __toCommonJS(index_exports);
|
|
53
58
|
|
|
@@ -1623,12 +1628,107 @@ ${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 ConfigSchema = import_zod.z.object({
|
|
1642
|
+
strategies: import_zod.z.record(import_zod.z.string(), StrategySchema).optional(),
|
|
1643
|
+
defaults: import_zod.z.object({
|
|
1644
|
+
qualityModel: import_zod.z.string().optional(),
|
|
1645
|
+
costModel: import_zod.z.string().optional()
|
|
1646
|
+
}).optional()
|
|
1647
|
+
});
|
|
1648
|
+
var DEFAULT_CONFIG = {
|
|
1649
|
+
strategies: {
|
|
1650
|
+
code_review: { model: "anthropic:claude-sonnet-4-20250514" },
|
|
1651
|
+
code_generation: { model: "anthropic:claude-3-5-haiku-latest" },
|
|
1652
|
+
analysis: { model: "anthropic:claude-sonnet-4-20250514" },
|
|
1653
|
+
summarization: { model: "anthropic:claude-3-5-haiku-latest" },
|
|
1654
|
+
creative_writing: { model: "anthropic:claude-sonnet-4-20250514" },
|
|
1655
|
+
data_extraction: { model: "anthropic:claude-3-5-haiku-latest" },
|
|
1656
|
+
translation: { model: "anthropic:claude-3-5-haiku-latest" },
|
|
1657
|
+
question_answering: { model: "anthropic:claude-3-5-haiku-latest" },
|
|
1658
|
+
general: { model: "anthropic:claude-3-5-haiku-latest" }
|
|
1659
|
+
},
|
|
1660
|
+
defaults: {
|
|
1661
|
+
qualityModel: "claude-sonnet-4-20250514",
|
|
1662
|
+
costModel: "claude-3-5-haiku-latest"
|
|
1663
|
+
}
|
|
1664
|
+
};
|
|
1665
|
+
function getConfigPath() {
|
|
1666
|
+
return path2.join(os2.homedir(), ".relayplane", "config.json");
|
|
1667
|
+
}
|
|
1668
|
+
function writeDefaultConfig() {
|
|
1669
|
+
const configPath = getConfigPath();
|
|
1670
|
+
const dir = path2.dirname(configPath);
|
|
1671
|
+
if (!fs2.existsSync(dir)) {
|
|
1672
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
1673
|
+
}
|
|
1674
|
+
if (!fs2.existsSync(configPath)) {
|
|
1675
|
+
fs2.writeFileSync(
|
|
1676
|
+
configPath,
|
|
1677
|
+
JSON.stringify(DEFAULT_CONFIG, null, 2) + "\n",
|
|
1678
|
+
"utf-8"
|
|
1679
|
+
);
|
|
1680
|
+
console.log(`[relayplane] Created default config at ${configPath}`);
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
function loadConfig() {
|
|
1684
|
+
const configPath = getConfigPath();
|
|
1685
|
+
writeDefaultConfig();
|
|
1686
|
+
try {
|
|
1687
|
+
const raw = fs2.readFileSync(configPath, "utf-8");
|
|
1688
|
+
const parsed = JSON.parse(raw);
|
|
1689
|
+
const validated = ConfigSchema.parse(parsed);
|
|
1690
|
+
return validated;
|
|
1691
|
+
} catch (err) {
|
|
1692
|
+
if (err instanceof import_zod.z.ZodError) {
|
|
1693
|
+
console.error(`[relayplane] Invalid config: ${err.message}`);
|
|
1694
|
+
} else if (err instanceof SyntaxError) {
|
|
1695
|
+
console.error(`[relayplane] Config JSON parse error: ${err.message}`);
|
|
1696
|
+
} else {
|
|
1697
|
+
console.error(`[relayplane] Failed to load config: ${err}`);
|
|
1698
|
+
}
|
|
1699
|
+
console.log("[relayplane] Using default config");
|
|
1700
|
+
return DEFAULT_CONFIG;
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
function getStrategy(config, taskType) {
|
|
1704
|
+
return config.strategies?.[taskType] ?? null;
|
|
1705
|
+
}
|
|
1706
|
+
function watchConfig(onChange) {
|
|
1707
|
+
const configPath = getConfigPath();
|
|
1708
|
+
const dir = path2.dirname(configPath);
|
|
1709
|
+
if (!fs2.existsSync(dir)) {
|
|
1710
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
1711
|
+
}
|
|
1712
|
+
let debounceTimer = null;
|
|
1713
|
+
fs2.watch(dir, (eventType, filename) => {
|
|
1714
|
+
if (filename === "config.json") {
|
|
1715
|
+
if (debounceTimer) clearTimeout(debounceTimer);
|
|
1716
|
+
debounceTimer = setTimeout(() => {
|
|
1717
|
+
console.log("[relayplane] Config file changed, reloading...");
|
|
1718
|
+
const newConfig = loadConfig();
|
|
1719
|
+
onChange(newConfig);
|
|
1720
|
+
}, 100);
|
|
1721
|
+
}
|
|
1722
|
+
});
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1626
1725
|
// src/proxy.ts
|
|
1627
|
-
var VERSION = "0.1.
|
|
1726
|
+
var VERSION = "0.1.8";
|
|
1628
1727
|
var recentRuns = [];
|
|
1629
1728
|
var MAX_RECENT_RUNS = 100;
|
|
1630
1729
|
var modelCounts = {};
|
|
1631
1730
|
var serverStartTime = 0;
|
|
1731
|
+
var currentConfig = loadConfig();
|
|
1632
1732
|
var DEFAULT_ENDPOINTS = {
|
|
1633
1733
|
anthropic: {
|
|
1634
1734
|
baseUrl: "https://api.anthropic.com/v1",
|
|
@@ -2479,33 +2579,44 @@ async function startProxy(config = {}) {
|
|
|
2479
2579
|
const confidence = getInferenceConfidence(promptText, taskType);
|
|
2480
2580
|
log(`Inferred task: ${taskType} (confidence: ${confidence.toFixed(2)})`);
|
|
2481
2581
|
if (routingMode !== "passthrough") {
|
|
2482
|
-
const
|
|
2483
|
-
if (
|
|
2484
|
-
const parsed = parsePreferredModel(
|
|
2582
|
+
const configStrategy = getStrategy(currentConfig, taskType);
|
|
2583
|
+
if (configStrategy) {
|
|
2584
|
+
const parsed = parsePreferredModel(configStrategy.model);
|
|
2485
2585
|
if (parsed) {
|
|
2486
2586
|
targetProvider = parsed.provider;
|
|
2487
2587
|
targetModel = parsed.model;
|
|
2488
|
-
log(`Using
|
|
2588
|
+
log(`Using config strategy: ${configStrategy.model}`);
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
if (!configStrategy) {
|
|
2592
|
+
const rule = relay.routing.get(taskType);
|
|
2593
|
+
if (rule && rule.preferredModel) {
|
|
2594
|
+
const parsed = parsePreferredModel(rule.preferredModel);
|
|
2595
|
+
if (parsed) {
|
|
2596
|
+
targetProvider = parsed.provider;
|
|
2597
|
+
targetModel = parsed.model;
|
|
2598
|
+
log(`Using learned rule: ${rule.preferredModel}`);
|
|
2599
|
+
} else {
|
|
2600
|
+
const defaultRoute = DEFAULT_ROUTING[taskType];
|
|
2601
|
+
targetProvider = defaultRoute.provider;
|
|
2602
|
+
targetModel = defaultRoute.model;
|
|
2603
|
+
}
|
|
2489
2604
|
} else {
|
|
2490
2605
|
const defaultRoute = DEFAULT_ROUTING[taskType];
|
|
2491
2606
|
targetProvider = defaultRoute.provider;
|
|
2492
2607
|
targetModel = defaultRoute.model;
|
|
2493
2608
|
}
|
|
2494
|
-
} else {
|
|
2495
|
-
const defaultRoute = DEFAULT_ROUTING[taskType];
|
|
2496
|
-
targetProvider = defaultRoute.provider;
|
|
2497
|
-
targetModel = defaultRoute.model;
|
|
2498
2609
|
}
|
|
2499
2610
|
if (routingMode === "cost") {
|
|
2500
|
-
const
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
}
|
|
2611
|
+
const costModel = currentConfig.defaults?.costModel || "claude-3-5-haiku-latest";
|
|
2612
|
+
targetModel = costModel;
|
|
2613
|
+
targetProvider = "anthropic";
|
|
2614
|
+
log(`Cost mode: using ${costModel}`);
|
|
2505
2615
|
} else if (routingMode === "quality") {
|
|
2506
|
-
const qualityModel = process.env["RELAYPLANE_QUALITY_MODEL"] || "claude-sonnet-4-20250514";
|
|
2616
|
+
const qualityModel = currentConfig.defaults?.qualityModel || process.env["RELAYPLANE_QUALITY_MODEL"] || "claude-sonnet-4-20250514";
|
|
2507
2617
|
targetModel = qualityModel;
|
|
2508
2618
|
targetProvider = "anthropic";
|
|
2619
|
+
log(`Quality mode: using ${qualityModel}`);
|
|
2509
2620
|
}
|
|
2510
2621
|
}
|
|
2511
2622
|
log(`Routing to: ${targetProvider}/${targetModel}`);
|
|
@@ -2552,6 +2663,10 @@ async function startProxy(config = {}) {
|
|
|
2552
2663
|
);
|
|
2553
2664
|
}
|
|
2554
2665
|
});
|
|
2666
|
+
watchConfig((newConfig) => {
|
|
2667
|
+
currentConfig = newConfig;
|
|
2668
|
+
console.log("[relayplane] Config reloaded");
|
|
2669
|
+
});
|
|
2555
2670
|
return new Promise((resolve, reject) => {
|
|
2556
2671
|
server.on("error", reject);
|
|
2557
2672
|
server.listen(port, host, () => {
|
|
@@ -2560,6 +2675,7 @@ async function startProxy(config = {}) {
|
|
|
2560
2675
|
console.log(` Models: relayplane:auto, relayplane:cost, relayplane:quality`);
|
|
2561
2676
|
console.log(` Endpoint: POST /v1/chat/completions`);
|
|
2562
2677
|
console.log(` Stats: GET /stats, /runs, /health`);
|
|
2678
|
+
console.log(` Config: ~/.relayplane/config.json (hot-reload enabled)`);
|
|
2563
2679
|
console.log(` Streaming: \u2705 Enabled`);
|
|
2564
2680
|
resolve(server);
|
|
2565
2681
|
});
|
|
@@ -2750,7 +2866,7 @@ async function handleNonStreamingRequest(res, request, targetProvider, targetMod
|
|
|
2750
2866
|
}
|
|
2751
2867
|
|
|
2752
2868
|
// src/types.ts
|
|
2753
|
-
var
|
|
2869
|
+
var import_zod2 = require("zod");
|
|
2754
2870
|
var TaskTypes = [
|
|
2755
2871
|
"code_generation",
|
|
2756
2872
|
"code_review",
|
|
@@ -2762,64 +2878,65 @@ var TaskTypes = [
|
|
|
2762
2878
|
"question_answering",
|
|
2763
2879
|
"general"
|
|
2764
2880
|
];
|
|
2765
|
-
var TaskTypeSchema =
|
|
2881
|
+
var TaskTypeSchema = import_zod2.z.enum(TaskTypes);
|
|
2766
2882
|
var Providers = ["openai", "anthropic", "google", "xai", "moonshot", "local"];
|
|
2767
|
-
var ProviderSchema =
|
|
2768
|
-
var RelayPlaneConfigSchema =
|
|
2769
|
-
dbPath:
|
|
2770
|
-
providers:
|
|
2771
|
-
apiKey:
|
|
2772
|
-
baseUrl:
|
|
2883
|
+
var ProviderSchema = import_zod2.z.enum(Providers);
|
|
2884
|
+
var RelayPlaneConfigSchema = import_zod2.z.object({
|
|
2885
|
+
dbPath: import_zod2.z.string().optional(),
|
|
2886
|
+
providers: import_zod2.z.record(ProviderSchema, import_zod2.z.object({
|
|
2887
|
+
apiKey: import_zod2.z.string().optional(),
|
|
2888
|
+
baseUrl: import_zod2.z.string().optional()
|
|
2773
2889
|
})).optional(),
|
|
2774
2890
|
defaultProvider: ProviderSchema.optional(),
|
|
2775
|
-
defaultModel:
|
|
2891
|
+
defaultModel: import_zod2.z.string().optional()
|
|
2776
2892
|
});
|
|
2777
|
-
var RunInputSchema =
|
|
2778
|
-
prompt:
|
|
2779
|
-
systemPrompt:
|
|
2893
|
+
var RunInputSchema = import_zod2.z.object({
|
|
2894
|
+
prompt: import_zod2.z.string().min(1),
|
|
2895
|
+
systemPrompt: import_zod2.z.string().optional(),
|
|
2780
2896
|
taskType: TaskTypeSchema.optional(),
|
|
2781
|
-
model:
|
|
2782
|
-
metadata:
|
|
2897
|
+
model: import_zod2.z.string().optional(),
|
|
2898
|
+
metadata: import_zod2.z.record(import_zod2.z.unknown()).optional()
|
|
2783
2899
|
});
|
|
2784
2900
|
var RuleSources = ["default", "user", "learned"];
|
|
2785
|
-
var RoutingRuleSchema =
|
|
2786
|
-
id:
|
|
2901
|
+
var RoutingRuleSchema = import_zod2.z.object({
|
|
2902
|
+
id: import_zod2.z.string(),
|
|
2787
2903
|
taskType: TaskTypeSchema,
|
|
2788
|
-
preferredModel:
|
|
2789
|
-
source:
|
|
2790
|
-
confidence:
|
|
2791
|
-
sampleCount:
|
|
2792
|
-
createdAt:
|
|
2793
|
-
updatedAt:
|
|
2904
|
+
preferredModel: import_zod2.z.string(),
|
|
2905
|
+
source: import_zod2.z.enum(RuleSources),
|
|
2906
|
+
confidence: import_zod2.z.number().min(0).max(1).optional(),
|
|
2907
|
+
sampleCount: import_zod2.z.number().int().positive().optional(),
|
|
2908
|
+
createdAt: import_zod2.z.string(),
|
|
2909
|
+
updatedAt: import_zod2.z.string()
|
|
2794
2910
|
});
|
|
2795
2911
|
var OutcomeQualities = ["excellent", "good", "acceptable", "poor", "failed"];
|
|
2796
|
-
var OutcomeInputSchema =
|
|
2797
|
-
runId:
|
|
2798
|
-
success:
|
|
2799
|
-
quality:
|
|
2800
|
-
latencySatisfactory:
|
|
2801
|
-
costSatisfactory:
|
|
2802
|
-
feedback:
|
|
2912
|
+
var OutcomeInputSchema = import_zod2.z.object({
|
|
2913
|
+
runId: import_zod2.z.string().min(1),
|
|
2914
|
+
success: import_zod2.z.boolean(),
|
|
2915
|
+
quality: import_zod2.z.enum(OutcomeQualities).optional(),
|
|
2916
|
+
latencySatisfactory: import_zod2.z.boolean().optional(),
|
|
2917
|
+
costSatisfactory: import_zod2.z.boolean().optional(),
|
|
2918
|
+
feedback: import_zod2.z.string().optional()
|
|
2803
2919
|
});
|
|
2804
|
-
var SuggestionSchema =
|
|
2805
|
-
id:
|
|
2920
|
+
var SuggestionSchema = import_zod2.z.object({
|
|
2921
|
+
id: import_zod2.z.string(),
|
|
2806
2922
|
taskType: TaskTypeSchema,
|
|
2807
|
-
currentModel:
|
|
2808
|
-
suggestedModel:
|
|
2809
|
-
reason:
|
|
2810
|
-
confidence:
|
|
2811
|
-
expectedImprovement:
|
|
2812
|
-
successRate:
|
|
2813
|
-
latency:
|
|
2814
|
-
cost:
|
|
2923
|
+
currentModel: import_zod2.z.string(),
|
|
2924
|
+
suggestedModel: import_zod2.z.string(),
|
|
2925
|
+
reason: import_zod2.z.string(),
|
|
2926
|
+
confidence: import_zod2.z.number().min(0).max(1),
|
|
2927
|
+
expectedImprovement: import_zod2.z.object({
|
|
2928
|
+
successRate: import_zod2.z.number().optional(),
|
|
2929
|
+
latency: import_zod2.z.number().optional(),
|
|
2930
|
+
cost: import_zod2.z.number().optional()
|
|
2815
2931
|
}),
|
|
2816
|
-
sampleCount:
|
|
2817
|
-
createdAt:
|
|
2818
|
-
accepted:
|
|
2819
|
-
acceptedAt:
|
|
2932
|
+
sampleCount: import_zod2.z.number().int().positive(),
|
|
2933
|
+
createdAt: import_zod2.z.string(),
|
|
2934
|
+
accepted: import_zod2.z.boolean().optional(),
|
|
2935
|
+
acceptedAt: import_zod2.z.string().optional()
|
|
2820
2936
|
});
|
|
2821
2937
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2822
2938
|
0 && (module.exports = {
|
|
2939
|
+
DEFAULT_CONFIG,
|
|
2823
2940
|
DEFAULT_ENDPOINTS,
|
|
2824
2941
|
MODEL_MAPPING,
|
|
2825
2942
|
MODEL_PRICING,
|
|
@@ -2834,9 +2951,13 @@ var SuggestionSchema = import_zod.z.object({
|
|
|
2834
2951
|
TaskTypes,
|
|
2835
2952
|
calculateCost,
|
|
2836
2953
|
calculateSavings,
|
|
2954
|
+
getConfigPath,
|
|
2837
2955
|
getInferenceConfidence,
|
|
2838
2956
|
getModelPricing,
|
|
2957
|
+
getStrategy,
|
|
2839
2958
|
inferTaskType,
|
|
2840
|
-
|
|
2959
|
+
loadConfig,
|
|
2960
|
+
startProxy,
|
|
2961
|
+
watchConfig
|
|
2841
2962
|
});
|
|
2842
2963
|
//# sourceMappingURL=index.js.map
|