@khanglvm/llm-router 2.3.5 → 2.3.6

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.
@@ -1488,7 +1488,8 @@ export async function startWebConsoleServer(options = {}, deps = {}) {
1488
1488
  const endpointUrl = buildAmpClientEndpointUrl(settings);
1489
1489
  try {
1490
1490
  const state = await readFactoryDroidRoutingState({
1491
- endpointUrl
1491
+ endpointUrl,
1492
+ config
1492
1493
  });
1493
1494
  return {
1494
1495
  ...state,
@@ -1512,6 +1513,13 @@ export async function startWebConsoleServer(options = {}, deps = {}) {
1512
1513
  missionValidatorModel: "",
1513
1514
  reasoningEffort: ""
1514
1515
  },
1516
+ bindingIds: {
1517
+ defaultModel: "",
1518
+ missionOrchestratorModel: "",
1519
+ missionWorkerModel: "",
1520
+ missionValidatorModel: "",
1521
+ reasoningEffort: ""
1522
+ },
1515
1523
  endpointUrl,
1516
1524
  error: error instanceof Error ? error.message : String(error)
1517
1525
  };
@@ -1551,6 +1559,7 @@ export async function startWebConsoleServer(options = {}, deps = {}) {
1551
1559
  endpointUrl: nextEndpointUrl,
1552
1560
  apiKey: nextMasterKey,
1553
1561
  bindings,
1562
+ config: nextConfig,
1554
1563
  captureBackup: false
1555
1564
  });
1556
1565
  if (endpointOrKeyChanged) {
@@ -3487,6 +3496,7 @@ export async function startWebConsoleServer(options = {}, deps = {}) {
3487
3496
  endpointUrl,
3488
3497
  apiKey,
3489
3498
  bindings,
3499
+ config: nextConfig,
3490
3500
  captureBackup: true
3491
3501
  });
3492
3502
  addLog("success", "Factory Droid routing enabled.", patchResult.baseUrl);
@@ -3537,6 +3547,7 @@ export async function startWebConsoleServer(options = {}, deps = {}) {
3537
3547
  endpointUrl,
3538
3548
  apiKey,
3539
3549
  bindings,
3550
+ config: configState.normalizedConfig,
3540
3551
  captureBackup: false
3541
3552
  });
3542
3553
  addLog("success", "Factory Droid model bindings updated.", patchResult.bindings.defaultModel || "Default");
@@ -64,6 +64,139 @@ export const FACTORY_DROID_REASONING_EFFORT_VALUES = Object.freeze([
64
64
  "high"
65
65
  ]);
66
66
 
67
+ function stripFactoryDroidRouterModelIdPrefix(value) {
68
+ const normalized = String(value || "").trim();
69
+ if (normalized.startsWith("custom:")) return normalized.slice("custom:".length).trim();
70
+ return normalized;
71
+ }
72
+
73
+ function sanitizeFactoryDroidRouterModelIdPart(value) {
74
+ return String(value || "")
75
+ .trim()
76
+ .replace(/[/:]+/g, "-")
77
+ .replace(/\s+/g, "-")
78
+ .replace(/[^A-Za-z0-9._-]+/g, "-")
79
+ .replace(/-+/g, "-")
80
+ .replace(/^-+|-+$/g, "");
81
+ }
82
+
83
+ function formatFactoryDroidDisplayNameBase(value) {
84
+ const normalized = String(value || "").trim();
85
+ if (!normalized) return "";
86
+ if (/^gpt(?=[-\s.]|$)/i.test(normalized)) return `GPT${normalized.slice(3)}`;
87
+ if (/^glm(?=[-\s.]|$)/i.test(normalized)) return `GLM${normalized.slice(3)}`;
88
+ if (/^claude(?=[-\s.]|$)/i.test(normalized)) return `Claude${normalized.slice(6)}`;
89
+ return normalized;
90
+ }
91
+
92
+ export function isFactoryDroidRouterModelId(value) {
93
+ const normalized = stripFactoryDroidRouterModelIdPrefix(value);
94
+ return normalized.startsWith("llm-");
95
+ }
96
+
97
+ export function parseFactoryDroidRouterModelId(value) {
98
+ const normalized = stripFactoryDroidRouterModelIdPrefix(value);
99
+ if (!normalized.startsWith("llm-")) return null;
100
+
101
+ if (normalized.startsWith("llm-alias:")) {
102
+ const aliasId = normalized.slice("llm-alias:".length).trim();
103
+ return aliasId
104
+ ? {
105
+ kind: "alias",
106
+ aliasId,
107
+ routeRef: aliasId
108
+ }
109
+ : null;
110
+ }
111
+
112
+ if (normalized.startsWith("llm-alias-")) {
113
+ const aliasId = normalized.slice("llm-alias-".length).trim();
114
+ return aliasId
115
+ ? {
116
+ kind: "alias",
117
+ aliasId,
118
+ routeRef: ""
119
+ }
120
+ : null;
121
+ }
122
+
123
+ const body = normalized.slice("llm-".length);
124
+ const separatorIndex = body.indexOf(":");
125
+ if (separatorIndex <= 0) return null;
126
+
127
+ const providerId = body.slice(0, separatorIndex).trim();
128
+ const modelId = body.slice(separatorIndex + 1).trim();
129
+ if (!providerId || !modelId) return null;
130
+
131
+ return {
132
+ kind: "model",
133
+ providerId,
134
+ modelId,
135
+ routeRef: `${providerId}/${modelId}`
136
+ };
137
+ }
138
+
139
+ export function resolveFactoryDroidRouterModelRef(value) {
140
+ const normalized = String(value || "").trim();
141
+ if (!normalized) return "";
142
+ return parseFactoryDroidRouterModelId(normalized)?.routeRef || normalized;
143
+ }
144
+
145
+ export function buildFactoryDroidRouterModelId(modelRef, { kind = "" } = {}) {
146
+ const normalizedModelRef = String(modelRef || "").trim();
147
+ if (!normalizedModelRef) return "";
148
+ if (normalizedModelRef.startsWith("custom:llm-")) {
149
+ const parsed = parseFactoryDroidRouterModelId(normalizedModelRef);
150
+ return parsed?.routeRef
151
+ ? buildFactoryDroidRouterModelId(parsed.routeRef, { kind: parsed.kind })
152
+ : normalizedModelRef;
153
+ }
154
+ if (normalizedModelRef.startsWith("llm-")) {
155
+ const parsed = parseFactoryDroidRouterModelId(normalizedModelRef);
156
+ return parsed?.routeRef
157
+ ? buildFactoryDroidRouterModelId(parsed.routeRef, { kind: parsed.kind })
158
+ : `custom:${normalizedModelRef}`;
159
+ }
160
+
161
+ const explicitKind = String(kind || "").trim().toLowerCase();
162
+ if (explicitKind === "alias") {
163
+ const aliasId = sanitizeFactoryDroidRouterModelIdPart(normalizedModelRef);
164
+ return aliasId ? `custom:llm-alias-${aliasId}` : "";
165
+ }
166
+
167
+ if (explicitKind === "model") {
168
+ const separatorIndex = normalizedModelRef.indexOf("/");
169
+ if (separatorIndex <= 0 || separatorIndex >= normalizedModelRef.length - 1) return "";
170
+ const providerId = normalizedModelRef.slice(0, separatorIndex).trim();
171
+ const modelId = normalizedModelRef.slice(separatorIndex + 1).trim();
172
+ const providerSlug = sanitizeFactoryDroidRouterModelIdPart(providerId);
173
+ const modelSlug = sanitizeFactoryDroidRouterModelIdPart(modelId);
174
+ return providerSlug && modelSlug ? `custom:llm-${providerSlug}-${modelSlug}` : "";
175
+ }
176
+
177
+ if (!normalizedModelRef.includes("/")) {
178
+ return buildFactoryDroidRouterModelId(normalizedModelRef, { kind: "alias" });
179
+ }
180
+
181
+ return buildFactoryDroidRouterModelId(normalizedModelRef, { kind: "model" });
182
+ }
183
+
184
+ export function buildFactoryDroidRouterDisplayName(modelRef, { kind = "" } = {}) {
185
+ const normalizedModelRef = String(modelRef || "").trim();
186
+ if (!normalizedModelRef) return "";
187
+
188
+ const explicitKind = String(kind || "").trim().toLowerCase();
189
+ const inferredKind = explicitKind || (normalizedModelRef.includes("/") ? "model" : "alias");
190
+ if (inferredKind === "alias") {
191
+ return `[LLM Alias] ${formatFactoryDroidDisplayNameBase(normalizedModelRef)}`;
192
+ }
193
+
194
+ const modelName = normalizedModelRef.includes("/")
195
+ ? normalizedModelRef.slice(normalizedModelRef.indexOf("/") + 1).trim()
196
+ : normalizedModelRef;
197
+ return `[LLM] ${formatFactoryDroidDisplayNameBase(modelName)}`;
198
+ }
199
+
67
200
  export function normalizeFactoryDroidReasoningEffort(value) {
68
201
  const normalized = String(value || "").trim().toLowerCase();
69
202
  return FACTORY_DROID_REASONING_EFFORT_VALUES.includes(normalized) ? normalized : "";