proxitor 0.2.0 → 0.3.0

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.
Files changed (52) hide show
  1. package/README.md +221 -81
  2. package/dist/add.cjs +139 -0
  3. package/dist/add.cjs.map +1 -0
  4. package/dist/add.mjs +138 -0
  5. package/dist/add.mjs.map +1 -0
  6. package/dist/browse.cjs +88 -0
  7. package/dist/browse.cjs.map +1 -0
  8. package/dist/browse.mjs +87 -0
  9. package/dist/browse.mjs.map +1 -0
  10. package/dist/cli.cjs +148 -25
  11. package/dist/cli.cjs.map +1 -1
  12. package/dist/cli.mjs +149 -26
  13. package/dist/cli.mjs.map +1 -1
  14. package/dist/config.cjs +68 -0
  15. package/dist/config.cjs.map +1 -0
  16. package/dist/config.mjs +45 -0
  17. package/dist/config.mjs.map +1 -0
  18. package/dist/config2.cjs +75 -0
  19. package/dist/config2.cjs.map +1 -0
  20. package/dist/config2.mjs +74 -0
  21. package/dist/config2.mjs.map +1 -0
  22. package/dist/edit.cjs +82 -0
  23. package/dist/edit.cjs.map +1 -0
  24. package/dist/edit.mjs +81 -0
  25. package/dist/edit.mjs.map +1 -0
  26. package/dist/index.cjs +2 -0
  27. package/dist/index.d.cts +223 -53
  28. package/dist/index.d.cts.map +1 -1
  29. package/dist/index.d.mts +223 -53
  30. package/dist/index.d.mts.map +1 -1
  31. package/dist/index.mjs +2 -2
  32. package/dist/list.cjs +33 -0
  33. package/dist/list.cjs.map +1 -0
  34. package/dist/list.mjs +31 -0
  35. package/dist/list.mjs.map +1 -0
  36. package/dist/providers.cjs +376 -0
  37. package/dist/providers.cjs.map +1 -0
  38. package/dist/providers.mjs +279 -0
  39. package/dist/providers.mjs.map +1 -0
  40. package/dist/proxy.cjs +128 -8
  41. package/dist/proxy.cjs.map +1 -1
  42. package/dist/proxy.mjs +99 -9
  43. package/dist/proxy.mjs.map +1 -1
  44. package/dist/remove.cjs +38 -0
  45. package/dist/remove.cjs.map +1 -0
  46. package/dist/remove.mjs +37 -0
  47. package/dist/remove.mjs.map +1 -0
  48. package/dist/validate.cjs +26 -0
  49. package/dist/validate.cjs.map +1 -0
  50. package/dist/validate.mjs +25 -0
  51. package/dist/validate.mjs.map +1 -0
  52. package/package.json +10 -3
package/dist/edit.mjs ADDED
@@ -0,0 +1,81 @@
1
+ import { g as OpenRouterClient, n as selectProvidersByMode, r as selectRoutingMode, t as fetchProvidersForModel } from "./providers.mjs";
2
+ import { i as setModelOverride, r as requireConfigPath, t as getModelOverrides } from "./config.mjs";
3
+ import * as clack from "@clack/prompts";
4
+ import { isCancel } from "@clack/prompts";
5
+ //#region src/commands/config/edit.ts
6
+ function formatOverrideHint(override) {
7
+ if (!override?.provider) return "(no provider routing)";
8
+ return Object.keys(override.provider).map((k) => `${k}: ${JSON.stringify(override.provider?.[k])}`).join(", ");
9
+ }
10
+ function showCurrentConfig(modelKey, current) {
11
+ clack.log.info(`Current config for "${modelKey}":`);
12
+ if (current.provider) for (const [field, value] of Object.entries(current.provider)) clack.log.info(` provider.${field}: ${JSON.stringify(value)}`);
13
+ if (current.headers) for (const [name, value] of Object.entries(current.headers)) clack.log.info(` headers.${name}: ${value}`);
14
+ }
15
+ function withoutProvider(current) {
16
+ return current.headers ? { headers: current.headers } : {};
17
+ }
18
+ async function updateProviderRouting(configPath, modelKey, current, apiKey) {
19
+ const isPattern = modelKey.includes("*");
20
+ const client = new OpenRouterClient(apiKey);
21
+ const mode = await selectRoutingMode("Routing mode");
22
+ if (isCancel(mode)) return;
23
+ if (mode === "skip") {
24
+ setModelOverride(configPath, modelKey, withoutProvider(current));
25
+ clack.outro("✓ Override updated");
26
+ return;
27
+ }
28
+ const providerOptions = await fetchProvidersForModel(client, modelKey, isPattern);
29
+ if (!providerOptions) return;
30
+ const override = await selectProvidersByMode(mode, providerOptions);
31
+ if (override === null) return;
32
+ const updated = withoutProvider(current);
33
+ if (override.provider) updated.provider = override.provider;
34
+ const save = await clack.confirm({ message: "Save changes?" });
35
+ if (isCancel(save) || !save) {
36
+ clack.outro("Cancelled");
37
+ return;
38
+ }
39
+ setModelOverride(configPath, modelKey, updated);
40
+ clack.outro("✓ Override updated");
41
+ }
42
+ /** Run the interactive "Edit model override" flow. */
43
+ async function editOverrideCommand(apiKey) {
44
+ clack.intro("Edit Model Override");
45
+ const configPath = requireConfigPath();
46
+ const overrides = getModelOverrides(configPath);
47
+ const keys = Object.keys(overrides);
48
+ if (keys.length === 0) {
49
+ clack.log.warn("No model overrides found. Use Add instead.");
50
+ clack.outro("");
51
+ return;
52
+ }
53
+ const selected = await clack.select({
54
+ message: "Select override to edit",
55
+ options: keys.map((k) => ({
56
+ value: k,
57
+ label: k,
58
+ hint: formatOverrideHint(overrides[k])
59
+ }))
60
+ });
61
+ if (isCancel(selected)) return;
62
+ const modelKey = selected;
63
+ const current = overrides[modelKey] ?? {};
64
+ showCurrentConfig(modelKey, current);
65
+ const target = await clack.select({
66
+ message: "What to change?",
67
+ options: [{
68
+ value: "provider",
69
+ label: "Provider routing"
70
+ }, {
71
+ value: "replace",
72
+ label: "Replace entirely"
73
+ }]
74
+ });
75
+ if (isCancel(target)) return;
76
+ if (target === "provider" || target === "replace") await updateProviderRouting(configPath, modelKey, current, apiKey);
77
+ }
78
+ //#endregion
79
+ export { editOverrideCommand };
80
+
81
+ //# sourceMappingURL=edit.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit.mjs","names":[],"sources":["../src/commands/config/edit.ts"],"sourcesContent":["import * as clack from '@clack/prompts'\nimport { isCancel } from '@clack/prompts'\nimport type { ModelOverride } from '../../config-schema.js'\nimport { OpenRouterClient } from '../../openrouter/client.js'\nimport { getModelOverrides, requireConfigPath, setModelOverride } from './config.js'\nimport {\n fetchProvidersForModel,\n selectProvidersByMode,\n selectRoutingMode,\n} from './providers.js'\n\nfunction formatOverrideHint(override: ModelOverride | undefined): string {\n if (!override?.provider) return '(no provider routing)'\n const keys = Object.keys(override.provider)\n return keys\n .map(\n k => `${k}: ${JSON.stringify((override.provider as Record<string, unknown>)?.[k])}`,\n )\n .join(', ')\n}\n\nfunction showCurrentConfig(modelKey: string, current: ModelOverride): void {\n clack.log.info(`Current config for \"${modelKey}\":`)\n if (current.provider) {\n for (const [field, value] of Object.entries(current.provider)) {\n clack.log.info(` provider.${field}: ${JSON.stringify(value)}`)\n }\n }\n if (current.headers) {\n for (const [name, value] of Object.entries(current.headers)) {\n clack.log.info(` headers.${name}: ${value}`)\n }\n }\n}\n\nfunction withoutProvider(current: ModelOverride): ModelOverride {\n return current.headers ? { headers: current.headers } : {}\n}\n\nasync function updateProviderRouting(\n configPath: string,\n modelKey: string,\n current: ModelOverride,\n apiKey: string,\n): Promise<void> {\n const isPattern = modelKey.includes('*')\n const client = new OpenRouterClient(apiKey)\n\n const mode = await selectRoutingMode('Routing mode')\n if (isCancel(mode)) return\n\n if (mode === 'skip') {\n setModelOverride(configPath, modelKey, withoutProvider(current))\n clack.outro('✓ Override updated')\n return\n }\n\n const providerOptions = await fetchProvidersForModel(client, modelKey, isPattern)\n if (!providerOptions) return\n\n const override = await selectProvidersByMode(mode as string, providerOptions)\n if (override === null) return\n\n const updated = withoutProvider(current)\n if (override.provider) {\n updated.provider = override.provider as ModelOverride['provider']\n }\n\n const save = await clack.confirm({ message: 'Save changes?' })\n if (isCancel(save) || !save) {\n clack.outro('Cancelled')\n return\n }\n\n setModelOverride(configPath, modelKey, updated)\n clack.outro('✓ Override updated')\n}\n\n/** Run the interactive \"Edit model override\" flow. */\nexport async function editOverrideCommand(apiKey: string): Promise<void> {\n clack.intro('Edit Model Override')\n\n const configPath = requireConfigPath()\n const overrides = getModelOverrides(configPath)\n const keys = Object.keys(overrides)\n\n if (keys.length === 0) {\n clack.log.warn('No model overrides found. Use Add instead.')\n clack.outro('')\n return\n }\n\n const selected = await clack.select({\n message: 'Select override to edit',\n options: keys.map(k => ({\n value: k,\n label: k,\n hint: formatOverrideHint(overrides[k]),\n })),\n })\n if (isCancel(selected)) return\n\n const modelKey = selected as string\n const current: ModelOverride = overrides[modelKey] ?? {}\n\n showCurrentConfig(modelKey, current)\n\n const target = await clack.select({\n message: 'What to change?',\n options: [\n { value: 'provider', label: 'Provider routing' },\n { value: 'replace', label: 'Replace entirely' },\n ],\n })\n if (isCancel(target)) return\n\n if (target === 'provider' || target === 'replace') {\n await updateProviderRouting(configPath, modelKey, current, apiKey)\n }\n}\n"],"mappings":";;;;;AAWA,SAAS,mBAAmB,UAA6C;CACvE,IAAI,CAAC,UAAU,UAAU,OAAO;CAEhC,OADa,OAAO,KAAK,SAAS,QACxB,EACP,KACC,MAAK,GAAG,EAAE,IAAI,KAAK,UAAW,SAAS,WAAuC,EAAE,GAClF,EACC,KAAK,IAAI;AACd;AAEA,SAAS,kBAAkB,UAAkB,SAA8B;CACzE,MAAM,IAAI,KAAK,uBAAuB,SAAS,GAAG;CAClD,IAAI,QAAQ,UACV,KAAK,MAAM,CAAC,OAAO,UAAU,OAAO,QAAQ,QAAQ,QAAQ,GAC1D,MAAM,IAAI,KAAK,cAAc,MAAM,IAAI,KAAK,UAAU,KAAK,GAAG;CAGlE,IAAI,QAAQ,SACV,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,QAAQ,OAAO,GACxD,MAAM,IAAI,KAAK,aAAa,KAAK,IAAI,OAAO;AAGlD;AAEA,SAAS,gBAAgB,SAAuC;CAC9D,OAAO,QAAQ,UAAU,EAAE,SAAS,QAAQ,QAAQ,IAAI,CAAC;AAC3D;AAEA,eAAe,sBACb,YACA,UACA,SACA,QACe;CACf,MAAM,YAAY,SAAS,SAAS,GAAG;CACvC,MAAM,SAAS,IAAI,iBAAiB,MAAM;CAE1C,MAAM,OAAO,MAAM,kBAAkB,cAAc;CACnD,IAAI,SAAS,IAAI,GAAG;CAEpB,IAAI,SAAS,QAAQ;EACnB,iBAAiB,YAAY,UAAU,gBAAgB,OAAO,CAAC;EAC/D,MAAM,MAAM,oBAAoB;EAChC;CACF;CAEA,MAAM,kBAAkB,MAAM,uBAAuB,QAAQ,UAAU,SAAS;CAChF,IAAI,CAAC,iBAAiB;CAEtB,MAAM,WAAW,MAAM,sBAAsB,MAAgB,eAAe;CAC5E,IAAI,aAAa,MAAM;CAEvB,MAAM,UAAU,gBAAgB,OAAO;CACvC,IAAI,SAAS,UACX,QAAQ,WAAW,SAAS;CAG9B,MAAM,OAAO,MAAM,MAAM,QAAQ,EAAE,SAAS,gBAAgB,CAAC;CAC7D,IAAI,SAAS,IAAI,KAAK,CAAC,MAAM;EAC3B,MAAM,MAAM,WAAW;EACvB;CACF;CAEA,iBAAiB,YAAY,UAAU,OAAO;CAC9C,MAAM,MAAM,oBAAoB;AAClC;;AAGA,eAAsB,oBAAoB,QAA+B;CACvE,MAAM,MAAM,qBAAqB;CAEjC,MAAM,aAAa,kBAAkB;CACrC,MAAM,YAAY,kBAAkB,UAAU;CAC9C,MAAM,OAAO,OAAO,KAAK,SAAS;CAElC,IAAI,KAAK,WAAW,GAAG;EACrB,MAAM,IAAI,KAAK,4CAA4C;EAC3D,MAAM,MAAM,EAAE;EACd;CACF;CAEA,MAAM,WAAW,MAAM,MAAM,OAAO;EAClC,SAAS;EACT,SAAS,KAAK,KAAI,OAAM;GACtB,OAAO;GACP,OAAO;GACP,MAAM,mBAAmB,UAAU,EAAE;EACvC,EAAE;CACJ,CAAC;CACD,IAAI,SAAS,QAAQ,GAAG;CAExB,MAAM,WAAW;CACjB,MAAM,UAAyB,UAAU,aAAa,CAAC;CAEvD,kBAAkB,UAAU,OAAO;CAEnC,MAAM,SAAS,MAAM,MAAM,OAAO;EAChC,SAAS;EACT,SAAS,CACP;GAAE,OAAO;GAAY,OAAO;EAAmB,GAC/C;GAAE,OAAO;GAAW,OAAO;EAAmB,CAChD;CACF,CAAC;CACD,IAAI,SAAS,MAAM,GAAG;CAEtB,IAAI,WAAW,cAAc,WAAW,WACtC,MAAM,sBAAsB,YAAY,UAAU,SAAS,MAAM;AAErE"}
package/dist/index.cjs CHANGED
@@ -1,5 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_proxy = require("./proxy.cjs");
3
+ exports.ConfigParseError = require_proxy.ConfigParseError;
4
+ exports.ConfigValidationError = require_proxy.ConfigValidationError;
3
5
  exports.buildProviderRouting = require_proxy.buildProviderRouting;
4
6
  exports.createProxyServer = require_proxy.createProxyServer;
5
7
  exports.extractModel = require_proxy.extractModel;
package/dist/index.d.cts CHANGED
@@ -1,63 +1,233 @@
1
+ import { z } from "zod";
1
2
  import { ServerType } from "@hono/node-server";
2
3
 
3
- //#region src/config.d.ts
4
- /** Percentile cutoffs for performance thresholds */
5
- type PercentileCutoffs = {
6
- p50?: number;
7
- p75?: number;
8
- p90?: number;
9
- p99?: number;
10
- };
11
- /** Provider sorting options */
12
- type ProviderSort = 'price' | 'throughput' | 'latency' | {
13
- by: 'price' | 'throughput' | 'latency';
14
- partition?: 'model' | 'none';
15
- };
16
- /** Maximum pricing for a request */
17
- type MaxPrice = {
18
- prompt?: number;
19
- completion?: number;
20
- request?: number;
21
- image?: number;
22
- };
23
- type ProviderConfig = {
24
- /** Allow only these providers (e.g. "deepinfra" or ["anthropic", "openai"]) */only?: string | string[]; /** Try providers in this order (e.g. "anthropic" or ["openai", "together"]) */
25
- order?: string | string[]; /** Ignore these providers (mirror of only — skip specific providers) */
26
- ignore?: string | string[]; /** Allow fallback to other providers (default: true) */
27
- allowFallbacks?: boolean; /** Sort providers by price, throughput, or latency */
28
- sort?: ProviderSort; /** Filter by quantization levels (e.g. ["fp8", "int4"]) */
29
- quantizations?: string[]; /** Maximum pricing to accept */
30
- maxPrice?: MaxPrice; /** Only use providers that support all request parameters (default: false) */
31
- requireParameters?: boolean; /** Control data collection policy: "allow" or "deny" (default: "allow") */
32
- dataCollection?: 'allow' | 'deny'; /** Restrict routing to Zero Data Retention endpoints */
33
- zdr?: boolean; /** Restrict routing to models that allow text distillation */
34
- enforceDistillableText?: boolean; /** Preferred minimum throughput (tokens/sec) */
35
- preferredMinThroughput?: number | PercentileCutoffs; /** Preferred maximum latency (seconds) */
36
- preferredMaxLatency?: number | PercentileCutoffs;
37
- };
4
+ //#region src/config-schema.d.ts
5
+ /** Provider routing configuration */
6
+ declare const providerConfigSchema: z.ZodObject<{
7
+ only: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
8
+ order: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
9
+ ignore: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
10
+ allowFallbacks: z.ZodOptional<z.ZodBoolean>;
11
+ sort: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
12
+ price: "price";
13
+ throughput: "throughput";
14
+ latency: "latency";
15
+ }>, z.ZodObject<{
16
+ by: z.ZodEnum<{
17
+ price: "price";
18
+ throughput: "throughput";
19
+ latency: "latency";
20
+ }>;
21
+ partition: z.ZodOptional<z.ZodEnum<{
22
+ model: "model";
23
+ none: "none";
24
+ }>>;
25
+ }, z.core.$strict>]>>;
26
+ quantizations: z.ZodOptional<z.ZodArray<z.ZodString>>;
27
+ maxPrice: z.ZodOptional<z.ZodObject<{
28
+ prompt: z.ZodOptional<z.ZodNumber>;
29
+ completion: z.ZodOptional<z.ZodNumber>;
30
+ request: z.ZodOptional<z.ZodNumber>;
31
+ image: z.ZodOptional<z.ZodNumber>;
32
+ }, z.core.$strict>>;
33
+ requireParameters: z.ZodOptional<z.ZodBoolean>;
34
+ dataCollection: z.ZodOptional<z.ZodEnum<{
35
+ allow: "allow";
36
+ deny: "deny";
37
+ }>>;
38
+ zdr: z.ZodOptional<z.ZodBoolean>;
39
+ enforceDistillableText: z.ZodOptional<z.ZodBoolean>;
40
+ preferredMinThroughput: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodObject<{
41
+ p50: z.ZodOptional<z.ZodNumber>;
42
+ p75: z.ZodOptional<z.ZodNumber>;
43
+ p90: z.ZodOptional<z.ZodNumber>;
44
+ p99: z.ZodOptional<z.ZodNumber>;
45
+ }, z.core.$strict>]>>;
46
+ preferredMaxLatency: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodObject<{
47
+ p50: z.ZodOptional<z.ZodNumber>;
48
+ p75: z.ZodOptional<z.ZodNumber>;
49
+ p90: z.ZodOptional<z.ZodNumber>;
50
+ p99: z.ZodOptional<z.ZodNumber>;
51
+ }, z.core.$strict>]>>;
52
+ }, z.core.$strict>;
38
53
  /** Per-model override: layers on top of global config */
39
- type ModelOverride = {
40
- /** Override provider routing for matching models */provider?: ProviderConfig; /** Additional headers to merge for matching models */
41
- headers?: Record<string, string>;
42
- };
54
+ declare const modelOverrideSchema: z.ZodObject<{
55
+ provider: z.ZodOptional<z.ZodObject<{
56
+ only: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
57
+ order: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
58
+ ignore: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
59
+ allowFallbacks: z.ZodOptional<z.ZodBoolean>;
60
+ sort: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
61
+ price: "price";
62
+ throughput: "throughput";
63
+ latency: "latency";
64
+ }>, z.ZodObject<{
65
+ by: z.ZodEnum<{
66
+ price: "price";
67
+ throughput: "throughput";
68
+ latency: "latency";
69
+ }>;
70
+ partition: z.ZodOptional<z.ZodEnum<{
71
+ model: "model";
72
+ none: "none";
73
+ }>>;
74
+ }, z.core.$strict>]>>;
75
+ quantizations: z.ZodOptional<z.ZodArray<z.ZodString>>;
76
+ maxPrice: z.ZodOptional<z.ZodObject<{
77
+ prompt: z.ZodOptional<z.ZodNumber>;
78
+ completion: z.ZodOptional<z.ZodNumber>;
79
+ request: z.ZodOptional<z.ZodNumber>;
80
+ image: z.ZodOptional<z.ZodNumber>;
81
+ }, z.core.$strict>>;
82
+ requireParameters: z.ZodOptional<z.ZodBoolean>;
83
+ dataCollection: z.ZodOptional<z.ZodEnum<{
84
+ allow: "allow";
85
+ deny: "deny";
86
+ }>>;
87
+ zdr: z.ZodOptional<z.ZodBoolean>;
88
+ enforceDistillableText: z.ZodOptional<z.ZodBoolean>;
89
+ preferredMinThroughput: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodObject<{
90
+ p50: z.ZodOptional<z.ZodNumber>;
91
+ p75: z.ZodOptional<z.ZodNumber>;
92
+ p90: z.ZodOptional<z.ZodNumber>;
93
+ p99: z.ZodOptional<z.ZodNumber>;
94
+ }, z.core.$strict>]>>;
95
+ preferredMaxLatency: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodObject<{
96
+ p50: z.ZodOptional<z.ZodNumber>;
97
+ p75: z.ZodOptional<z.ZodNumber>;
98
+ p90: z.ZodOptional<z.ZodNumber>;
99
+ p99: z.ZodOptional<z.ZodNumber>;
100
+ }, z.core.$strict>]>>;
101
+ }, z.core.$strict>>;
102
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
103
+ }, z.core.$strict>;
104
+ /** Full proxy configuration */
105
+ declare const proxyConfigSchema: z.ZodObject<{
106
+ host: z.ZodString;
107
+ port: z.ZodNumber;
108
+ openrouterKey: z.ZodString;
109
+ openrouterBaseUrl: z.ZodString;
110
+ verbose: z.ZodBoolean;
111
+ bodyLimit: z.ZodString;
112
+ provider: z.ZodOptional<z.ZodObject<{
113
+ only: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
114
+ order: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
115
+ ignore: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
116
+ allowFallbacks: z.ZodOptional<z.ZodBoolean>;
117
+ sort: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
118
+ price: "price";
119
+ throughput: "throughput";
120
+ latency: "latency";
121
+ }>, z.ZodObject<{
122
+ by: z.ZodEnum<{
123
+ price: "price";
124
+ throughput: "throughput";
125
+ latency: "latency";
126
+ }>;
127
+ partition: z.ZodOptional<z.ZodEnum<{
128
+ model: "model";
129
+ none: "none";
130
+ }>>;
131
+ }, z.core.$strict>]>>;
132
+ quantizations: z.ZodOptional<z.ZodArray<z.ZodString>>;
133
+ maxPrice: z.ZodOptional<z.ZodObject<{
134
+ prompt: z.ZodOptional<z.ZodNumber>;
135
+ completion: z.ZodOptional<z.ZodNumber>;
136
+ request: z.ZodOptional<z.ZodNumber>;
137
+ image: z.ZodOptional<z.ZodNumber>;
138
+ }, z.core.$strict>>;
139
+ requireParameters: z.ZodOptional<z.ZodBoolean>;
140
+ dataCollection: z.ZodOptional<z.ZodEnum<{
141
+ allow: "allow";
142
+ deny: "deny";
143
+ }>>;
144
+ zdr: z.ZodOptional<z.ZodBoolean>;
145
+ enforceDistillableText: z.ZodOptional<z.ZodBoolean>;
146
+ preferredMinThroughput: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodObject<{
147
+ p50: z.ZodOptional<z.ZodNumber>;
148
+ p75: z.ZodOptional<z.ZodNumber>;
149
+ p90: z.ZodOptional<z.ZodNumber>;
150
+ p99: z.ZodOptional<z.ZodNumber>;
151
+ }, z.core.$strict>]>>;
152
+ preferredMaxLatency: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodObject<{
153
+ p50: z.ZodOptional<z.ZodNumber>;
154
+ p75: z.ZodOptional<z.ZodNumber>;
155
+ p90: z.ZodOptional<z.ZodNumber>;
156
+ p99: z.ZodOptional<z.ZodNumber>;
157
+ }, z.core.$strict>]>>;
158
+ }, z.core.$strict>>;
159
+ attributionReferer: z.ZodString;
160
+ attributionTitle: z.ZodString;
161
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
162
+ modelOverrides: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
163
+ provider: z.ZodOptional<z.ZodObject<{
164
+ only: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
165
+ order: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
166
+ ignore: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
167
+ allowFallbacks: z.ZodOptional<z.ZodBoolean>;
168
+ sort: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
169
+ price: "price";
170
+ throughput: "throughput";
171
+ latency: "latency";
172
+ }>, z.ZodObject<{
173
+ by: z.ZodEnum<{
174
+ price: "price";
175
+ throughput: "throughput";
176
+ latency: "latency";
177
+ }>;
178
+ partition: z.ZodOptional<z.ZodEnum<{
179
+ model: "model";
180
+ none: "none";
181
+ }>>;
182
+ }, z.core.$strict>]>>;
183
+ quantizations: z.ZodOptional<z.ZodArray<z.ZodString>>;
184
+ maxPrice: z.ZodOptional<z.ZodObject<{
185
+ prompt: z.ZodOptional<z.ZodNumber>;
186
+ completion: z.ZodOptional<z.ZodNumber>;
187
+ request: z.ZodOptional<z.ZodNumber>;
188
+ image: z.ZodOptional<z.ZodNumber>;
189
+ }, z.core.$strict>>;
190
+ requireParameters: z.ZodOptional<z.ZodBoolean>;
191
+ dataCollection: z.ZodOptional<z.ZodEnum<{
192
+ allow: "allow";
193
+ deny: "deny";
194
+ }>>;
195
+ zdr: z.ZodOptional<z.ZodBoolean>;
196
+ enforceDistillableText: z.ZodOptional<z.ZodBoolean>;
197
+ preferredMinThroughput: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodObject<{
198
+ p50: z.ZodOptional<z.ZodNumber>;
199
+ p75: z.ZodOptional<z.ZodNumber>;
200
+ p90: z.ZodOptional<z.ZodNumber>;
201
+ p99: z.ZodOptional<z.ZodNumber>;
202
+ }, z.core.$strict>]>>;
203
+ preferredMaxLatency: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodObject<{
204
+ p50: z.ZodOptional<z.ZodNumber>;
205
+ p75: z.ZodOptional<z.ZodNumber>;
206
+ p90: z.ZodOptional<z.ZodNumber>;
207
+ p99: z.ZodOptional<z.ZodNumber>;
208
+ }, z.core.$strict>]>>;
209
+ }, z.core.$strict>>;
210
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
211
+ }, z.core.$strict>>>;
212
+ }, z.core.$strict>;
213
+ type ProxyConfig = z.infer<typeof proxyConfigSchema>;
214
+ type ProviderConfig = z.infer<typeof providerConfigSchema>;
215
+ type ModelOverride = z.infer<typeof modelOverrideSchema>;
216
+ /** Wraps YAML/JSON parse errors with the config file path */
217
+ declare class ConfigParseError extends Error {
218
+ constructor(filePath: string, cause?: Error);
219
+ }
220
+ /** Formats zod validation issues into a readable multi-line message */
221
+ declare class ConfigValidationError extends Error {
222
+ constructor(filePath: string, zodError: z.ZodError);
223
+ }
224
+ //#endregion
225
+ //#region src/config.d.ts
43
226
  /** Result of merging global config with a model-specific override */
44
227
  type ResolvedModelConfig = {
45
228
  provider?: ProviderConfig;
46
229
  headers?: Record<string, string>;
47
230
  };
48
- type ProxyConfig = {
49
- host: string;
50
- port: number;
51
- openrouterKey: string;
52
- openrouterBaseUrl: string;
53
- verbose: boolean; /** Request body size limit (default: "50mb") */
54
- bodyLimit: string; /** Provider routing configuration (global default) */
55
- provider?: ProviderConfig; /** HTTP-Referer for OpenRouter attribution */
56
- attributionReferer: string; /** X-Title for OpenRouter attribution */
57
- attributionTitle: string; /** Custom headers to add to proxied requests (global default) */
58
- headers?: Record<string, string>; /** Per-model config overrides. Keys are exact model names or prefix patterns (e.g. "claude-*") */
59
- modelOverrides?: Record<string, ModelOverride>;
60
- };
61
231
  type LoadConfigOptions = {
62
232
  configPath?: string;
63
233
  noConfig?: boolean;
@@ -87,5 +257,5 @@ declare function toArray(value: string | string[] | undefined): string[] | undef
87
257
  /** Try to parse an ArrayBuffer as JSON. Returns undefined on failure or empty body. */
88
258
  declare function tryParseBody(raw: ArrayBuffer): Record<string, unknown> | undefined;
89
259
  //#endregion
90
- export { type ModelOverride, type ProviderConfig, type ProxyConfig, type ResolvedModelConfig, buildProviderRouting, createProxyServer, extractModel, loadConfig, matchScore, resolveModelConfig, toArray, tryParseBody };
260
+ export { ConfigParseError, ConfigValidationError, type ModelOverride, type ProviderConfig, type ProxyConfig, type ResolvedModelConfig, buildProviderRouting, createProxyServer, extractModel, loadConfig, matchScore, resolveModelConfig, toArray, tryParseBody };
91
261
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/config.ts","../src/proxy/inject.ts","../src/proxy.ts","../src/utils.ts"],"mappings":";;;;KAOY,iBAAA;EACV,GAAA;EACA,GAAA;EACA,GAAA;EACA,GAAA;AAAA;;KAIU,YAAA;EAIN,EAAA;EAAwC,SAAS;AAAA;AARlD;AAAA,KAWO,QAAA;EACV,MAAA;EACA,UAAA;EACA,OAAA;EACA,KAAA;AAAA;AAAA,KAGU,cAAA;iFAEV,IAAA,sBARA;EAUA,KAAA,sBARA;EAUA,MAAA,sBATK;EAWL,cAAA,YARU;EAUV,IAAA,GAAO,YAAA;EAEP,aAAA,aAEW;EAAX,QAAA,GAAW,QAAA,EAYoB;EAV/B,iBAAA,YAUgD;EARhD,cAAA,qBAdA;EAgBA,GAAA,YAZA;EAcA,sBAAA,YAZO;EAcP,sBAAA,YAAkC,iBAAA,EAVlC;EAYA,mBAAA,YAA+B,iBAAA;AAAA;;KAIrB,aAAA;EARV,oDAUA,QAAA,GAAW,cAAA,EARuB;EAUlC,OAAA,GAAU,MAAM;AAAA;;KAIN,mBAAA;EACV,QAAA,GAAW,cAAA;EACX,OAAA,GAAU,MAAM;AAAA;AAAA,KAGN,WAAA;EACV,IAAA;EACA,IAAA;EACA,aAAA;EACA,iBAAA;EACA,OAAA,WAdgB;EAgBhB,SAAA,UAZ6B;EAc7B,QAAA,GAAW,cAAA,EAZK;EAchB,kBAAA,UAfW;EAiBX,gBAAA,UAhBU;EAkBV,OAAA,GAAU,MAAA,kBAlBM;EAoBhB,cAAA,GAAiB,MAAA,SAAe,aAAA;AAAA;AAAA,KAc7B,iBAAA;EACH,UAAA;EACA,QAAA;EACA,IAAA;EACA,aAAA;EACA,IAAA;EACA,OAAA;AAAA;;iBAwBc,oBAAA,CACd,QAAA,GAAW,cAAA,GACV,MAAM;;iBA0BO,UAAA,CAAW,OAAA,UAAiB,SAAiB;;iBAW7C,kBAAA,CACd,MAAA,EAAQ,WAAA,EACR,SAAA,YACC,mBAAmB;AAAA,iBAgCA,UAAA,CAAW,OAAA,EAAS,iBAAA,GAAoB,OAAA,CAAQ,WAAA;;;;iBC5MtD,YAAA,CAAa,OAAoB,EAAX,WAAW;;;iBC0JjC,iBAAA,CAAkB,MAAA,EAAQ,WAAA,EAAa,OAAA,gBAAuB,UAAU;;;;iBC5JxE,OAAA,CAAQ,KAAoC;;iBAO5C,YAAA,CAAa,GAAA,EAAK,WAAA,GAAc,MAAM"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/config-schema.ts","../src/config.ts","../src/proxy/inject.ts","../src/proxy.ts","../src/utils.ts"],"mappings":";;;;;cAsCa,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAuBpB,mBAAA,EAAmB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAQnB,iBAAA,EAAiB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAuBlB,WAAA,GAAc,CAAA,CAAE,KAAK,QAAQ,iBAAA;AAAA,KAC7B,cAAA,GAAiB,CAAA,CAAE,KAAK,QAAQ,oBAAA;AAAA,KAChC,aAAA,GAAgB,CAAA,CAAE,KAAK,QAAQ,mBAAA;;cAU9B,gBAAA,SAAyB,KAAK;cAC7B,QAAA,UAAkB,KAAA,GAAQ,KAAA;AAAA;;cAU3B,qBAAA,SAA8B,KAAK;cAClC,QAAA,UAAkB,QAAA,EAAU,CAAA,CAAE,QAAA;AAAA;;;;KC5FhC,mBAAA;EACV,QAAA,GAAW,cAAA;EACX,OAAA,GAAU,MAAM;AAAA;AAAA,KAcb,iBAAA;EACH,UAAA;EACA,QAAA;EACA,IAAA;EACA,aAAA;EACA,IAAA;EACA,OAAA;AAAA;;iBAwBc,oBAAA,CACd,QAAA,GAAW,cAAA,GACV,MAAM;;iBA0BO,UAAA,CAAW,OAAA,UAAiB,SAAiB;;iBAW7C,kBAAA,CACd,MAAA,EAAQ,WAAA,EACR,SAAA,YACC,mBAAmB;AAAA,iBAgCA,UAAA,CAAW,OAAA,EAAS,iBAAA,GAAoB,OAAA,CAAQ,WAAA;;;;iBC7ItD,YAAA,CAAa,OAAoB,EAAX,WAAW;;;iBC0JjC,iBAAA,CAAkB,MAAA,EAAQ,WAAA,EAAa,OAAA,gBAAuB,UAAU;;;;iBC5JxE,OAAA,CAAQ,KAAoC;;iBAO5C,YAAA,CAAa,GAAA,EAAK,WAAA,GAAc,MAAM"}