mslxdff 0.1.62 → 0.1.64

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/src/state.js CHANGED
@@ -395,6 +395,29 @@ function normalizeAllowedModel(model, providerId) {
395
395
  }
396
396
  return s;
397
397
  }
398
+ function normalizeEndpointPath(v) {
399
+ const s = String(v || "").trim();
400
+ if (!s) return "";
401
+ return s.startsWith("/") ? s : `/${s}`;
402
+ }
403
+ function defaultModelsPath(id) {
404
+ if (String(id).toLowerCase() === "workbuddy") return "/console/enterprises/personal/models";
405
+ return "/models";
406
+ }
407
+ function defaultChatPath(id) {
408
+ if (String(id).toLowerCase() === "workbuddy") return "/v2/chat/completions";
409
+ return "/chat/completions";
410
+ }
411
+ export function loadProviderModelsPath(id, { file = defaultStateFile() } = {}) {
412
+ const cfg = loadProviderConfigs({ file })[id];
413
+ if (cfg && typeof cfg.modelsPath === "string" && cfg.modelsPath.trim()) return normalizeEndpointPath(cfg.modelsPath);
414
+ return defaultModelsPath(id);
415
+ }
416
+ export function loadProviderChatPath(id, { file = defaultStateFile() } = {}) {
417
+ const cfg = loadProviderConfigs({ file })[id];
418
+ if (cfg && typeof cfg.chatPath === "string" && cfg.chatPath.trim()) return normalizeEndpointPath(cfg.chatPath);
419
+ return defaultChatPath(id);
420
+ }
398
421
 
399
422
  export function loadProviderConfigs({ file = defaultStateFile() } = {}) {
400
423
  const v = readState(file).providerConfigs;
@@ -411,7 +434,9 @@ export function loadProviderConfig(id, { file = defaultStateFile() } = {}) {
411
434
  const cfg = loadProviderConfigs({ file })[id];
412
435
  const allowedModels = cfg && Array.isArray(cfg.allowedModels) ? [...new Set(cfg.allowedModels.map((m) => normalizeAllowedModel(m, id)).filter(Boolean))] : [];
413
436
  const auths = cfg && Array.isArray(cfg.auths) ? normalizeAuths(cfg.auths) : [];
414
- if (baseUrl || envKeys.length || allowedModels.length || auths.length) return { baseUrl: normalizeBaseUrl(baseUrl), keys: envKeys, auths, allowedModels };
437
+ const modelsPath = cfg && typeof cfg.modelsPath === "string" && cfg.modelsPath.trim() ? normalizeEndpointPath(cfg.modelsPath) : defaultModelsPath(id);
438
+ const chatPath = cfg && typeof cfg.chatPath === "string" && cfg.chatPath.trim() ? normalizeEndpointPath(cfg.chatPath) : defaultChatPath(id);
439
+ if (baseUrl || envKeys.length || allowedModels.length || auths.length) return { baseUrl: normalizeBaseUrl(baseUrl), keys: envKeys, auths, allowedModels, modelsPath, chatPath };
415
440
  return null;
416
441
  }
417
442
  const configs = loadProviderConfigs({ file });
@@ -422,11 +447,13 @@ export function loadProviderConfig(id, { file = defaultStateFile() } = {}) {
422
447
  keys: Array.isArray(cfg.keys) ? [...new Set(cfg.keys.filter((x) => typeof x === "string" && x.trim().length))] : [],
423
448
  auths: normalizeAuths(cfg.auths),
424
449
  allowedModels: Array.isArray(cfg.allowedModels) ? [...new Set(cfg.allowedModels.map((m) => normalizeAllowedModel(m, id)).filter(Boolean))] : [],
450
+ modelsPath: typeof cfg.modelsPath === "string" && cfg.modelsPath.trim() ? normalizeEndpointPath(cfg.modelsPath) : defaultModelsPath(id),
451
+ chatPath: typeof cfg.chatPath === "string" && cfg.chatPath.trim() ? normalizeEndpointPath(cfg.chatPath) : defaultChatPath(id),
425
452
  };
426
453
  }
427
454
  // 兼容旧 providerKeys 形态:有 key 但无 configs 时视为通用供应商(baseUrl 为空,需后补)
428
455
  const keys = loadProviderKeys(id, { file });
429
- if (keys.length) return { baseUrl: String(id).toLowerCase() === "workbuddy" ? WORKBUDDY_DEFAULT_BASE_URL : "", keys, auths: [], allowedModels: [] };
456
+ if (keys.length) return { baseUrl: String(id).toLowerCase() === "workbuddy" ? WORKBUDDY_DEFAULT_BASE_URL : "", keys, auths: [], allowedModels: [], modelsPath: defaultModelsPath(id), chatPath: defaultChatPath(id) };
430
457
  return null;
431
458
  }
432
459
 
@@ -451,12 +478,16 @@ export function saveProviderAuths(id, list, { file = defaultStateFile() } = {})
451
478
  const baseUrl = normalizeBaseUrl(cur.baseUrl || loadProviderBaseUrl(id, { file }) || "");
452
479
  const keys = Array.isArray(cur.keys) ? [...new Set(cur.keys.filter((x) => typeof x === "string" && x.trim().length))] : loadProviderKeys(id, { file });
453
480
  const allowedModels = Array.isArray(cur.allowedModels) ? [...new Set(cur.allowedModels.map((m) => normalizeAllowedModel(m, id)).filter(Boolean))] : [];
454
- if (!baseUrl && !keys.length && !clean.length && !allowedModels.length) {
481
+ const modelsPath = typeof cur.modelsPath === "string" ? normalizeEndpointPath(cur.modelsPath) : "";
482
+ const chatPath = typeof cur.chatPath === "string" ? normalizeEndpointPath(cur.chatPath) : "";
483
+ if (!baseUrl && !keys.length && !clean.length && !allowedModels.length && !modelsPath && !chatPath) {
455
484
  delete configs[id];
456
485
  } else {
457
486
  configs[id] = { baseUrl, keys };
458
487
  if (clean.length) configs[id].auths = clean;
459
488
  if (allowedModels.length) configs[id].allowedModels = allowedModels;
489
+ if (modelsPath) configs[id].modelsPath = modelsPath;
490
+ if (chatPath) configs[id].chatPath = chatPath;
460
491
  }
461
492
  writeStateImmediate(file, { providerConfigs: configs });
462
493
  return clean;
@@ -469,33 +500,43 @@ export function saveProviderBaseUrl(id, baseUrl, { file = defaultStateFile() } =
469
500
  const keys = Array.isArray(cur.keys) ? cur.keys : loadProviderKeys(id, { file });
470
501
  const auths = normalizeAuths(cur.auths);
471
502
  const allowedModels = Array.isArray(cur.allowedModels) ? [...new Set(cur.allowedModels.map((m) => normalizeAllowedModel(m, id)).filter(Boolean))] : [];
472
- if (!clean && !keys.length && !auths.length && !allowedModels.length) {
503
+ const modelsPath = typeof cur.modelsPath === "string" ? normalizeEndpointPath(cur.modelsPath) : "";
504
+ const chatPath = typeof cur.chatPath === "string" ? normalizeEndpointPath(cur.chatPath) : "";
505
+ if (!clean && !keys.length && !auths.length && !allowedModels.length && !modelsPath && !chatPath) {
473
506
  delete configs[id];
474
507
  } else {
475
508
  configs[id] = { baseUrl: clean, keys };
476
509
  if (auths.length) configs[id].auths = auths;
477
510
  if (allowedModels.length) configs[id].allowedModels = allowedModels;
511
+ if (modelsPath) configs[id].modelsPath = modelsPath;
512
+ if (chatPath) configs[id].chatPath = chatPath;
478
513
  }
479
514
  writeStateImmediate(file, { providerConfigs: configs });
480
515
  return clean;
481
516
  }
482
517
 
483
- export function saveProviderConfig(id, { baseUrl, keys, auths, allowedModels }, { file = defaultStateFile() } = {}) {
518
+ export function saveProviderConfig(id, { baseUrl, keys, auths, allowedModels, modelsPath, chatPath }, { file = defaultStateFile() } = {}) {
484
519
  const cleanUrl = normalizeBaseUrl(baseUrl);
485
520
  const cleanKeys = [...new Set((Array.isArray(keys) ? keys : []).map((k) => String(k || "").trim()).filter(Boolean))];
486
521
  const cleanAuths = auths === undefined ? undefined : normalizeAuths(auths);
487
522
  const cleanAllowed = [...new Set((Array.isArray(allowedModels) ? allowedModels : []).map((m) => normalizeAllowedModel(m, id)).filter(Boolean))];
523
+ const cleanModelsPath = modelsPath === undefined ? undefined : (String(modelsPath).trim() ? normalizeEndpointPath(modelsPath) : "");
524
+ const cleanChatPath = chatPath === undefined ? undefined : (String(chatPath).trim() ? normalizeEndpointPath(chatPath) : "");
488
525
  const configs = { ...loadProviderConfigs({ file }) };
489
526
  const cur = configs[id] && typeof configs[id] === "object" ? configs[id] : {};
490
- // 保留已有的 allowedModels / auths 若本次未传入
527
+ // 保留已有的 allowedModels / auths / paths 若本次未传入
491
528
  const finalAllowed = allowedModels === undefined ? (Array.isArray(cur.allowedModels) ? [...new Set(cur.allowedModels.map((m) => normalizeAllowedModel(m, id)).filter(Boolean))] : []) : cleanAllowed;
492
529
  const finalAuths = cleanAuths === undefined ? normalizeAuths(cur.auths) : cleanAuths;
493
- if (!cleanUrl && !cleanKeys.length && !finalAllowed.length && !finalAuths.length) {
530
+ const finalModelsPath = cleanModelsPath === undefined ? (typeof cur.modelsPath === "string" ? normalizeEndpointPath(cur.modelsPath) : "") : cleanModelsPath;
531
+ const finalChatPath = cleanChatPath === undefined ? (typeof cur.chatPath === "string" ? normalizeEndpointPath(cur.chatPath) : "") : cleanChatPath;
532
+ if (!cleanUrl && !cleanKeys.length && !finalAllowed.length && !finalAuths.length && !finalModelsPath && !finalChatPath) {
494
533
  delete configs[id];
495
534
  } else {
496
535
  configs[id] = { baseUrl: cleanUrl, keys: cleanKeys };
497
536
  if (finalAuths.length) configs[id].auths = finalAuths;
498
537
  if (finalAllowed.length) configs[id].allowedModels = finalAllowed;
538
+ if (finalModelsPath) configs[id].modelsPath = finalModelsPath;
539
+ if (finalChatPath) configs[id].chatPath = finalChatPath;
499
540
  }
500
541
  // 同步清理旧 providerKeys 中同 id 的残留,避免双写
501
542
  const oldKeys = readState(file).providerKeys;
@@ -503,10 +544,10 @@ export function saveProviderConfig(id, { baseUrl, keys, auths, allowedModels },
503
544
  const nextKeys = { ...oldKeys };
504
545
  delete nextKeys[id];
505
546
  writeStateImmediate(file, { providerKeys: nextKeys, providerConfigs: configs });
506
- return { baseUrl: cleanUrl, keys: cleanKeys, auths: finalAuths, allowedModels: finalAllowed };
547
+ return { baseUrl: cleanUrl, keys: cleanKeys, auths: finalAuths, allowedModels: finalAllowed, modelsPath: finalModelsPath, chatPath: finalChatPath };
507
548
  }
508
549
  writeStateImmediate(file, { providerConfigs: configs });
509
- return { baseUrl: cleanUrl, keys: cleanKeys, auths: finalAuths, allowedModels: finalAllowed };
550
+ return { baseUrl: cleanUrl, keys: cleanKeys, auths: finalAuths, allowedModels: finalAllowed, modelsPath: finalModelsPath, chatPath: finalChatPath };
510
551
  }
511
552
 
512
553
  // ---- 供应商模型白名单:providerConfigs.<id>.allowedModels(空 = 不限) ----
@@ -525,12 +566,16 @@ export function saveProviderAllowedModels(id, list, { file = defaultStateFile()
525
566
  const baseUrl = normalizeBaseUrl(cur.baseUrl || loadProviderBaseUrl(id, { file }) || "");
526
567
  const keys = Array.isArray(cur.keys) ? cur.keys : loadProviderKeys(id, { file });
527
568
  const auths = normalizeAuths(cur.auths);
528
- if (!baseUrl && !keys.length && !auths.length && !clean.length) {
569
+ const modelsPath = typeof cur.modelsPath === "string" ? normalizeEndpointPath(cur.modelsPath) : "";
570
+ const chatPath = typeof cur.chatPath === "string" ? normalizeEndpointPath(cur.chatPath) : "";
571
+ if (!baseUrl && !keys.length && !auths.length && !clean.length && !modelsPath && !chatPath) {
529
572
  delete configs[id];
530
573
  } else {
531
574
  configs[id] = { baseUrl, keys };
532
575
  if (auths.length) configs[id].auths = auths;
533
576
  if (clean.length) configs[id].allowedModels = clean;
577
+ if (modelsPath) configs[id].modelsPath = modelsPath;
578
+ if (chatPath) configs[id].chatPath = chatPath;
534
579
  }
535
580
  writeStateImmediate(file, { providerConfigs: configs });
536
581
  return clean;