@oh-my-pi/pi-coding-agent 16.2.9 → 16.2.12

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 (110) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/dist/cli.js +3464 -3306
  3. package/dist/types/cli/bench-cli.d.ts +0 -5
  4. package/dist/types/cli/dry-balance-cli.d.ts +0 -5
  5. package/dist/types/cli/models-cli.d.ts +1 -1
  6. package/dist/types/config/inline-tool-descriptors-mode.d.ts +1 -2
  7. package/dist/types/config/model-registry.d.ts +1 -23
  8. package/dist/types/config/model-resolver.d.ts +10 -15
  9. package/dist/types/config/models-config-schema.d.ts +0 -6
  10. package/dist/types/config/models-config.d.ts +0 -6
  11. package/dist/types/config/settings-schema.d.ts +31 -1
  12. package/dist/types/eval/py/__tests__/runner-shell-output.test.d.ts +1 -0
  13. package/dist/types/extensibility/extensions/runner.d.ts +15 -0
  14. package/dist/types/extensibility/skills.d.ts +29 -0
  15. package/dist/types/lsp/client.d.ts +9 -3
  16. package/dist/types/modes/components/todo-reminder.d.ts +3 -1
  17. package/dist/types/modes/interactive-mode.d.ts +0 -1
  18. package/dist/types/modes/skill-command.d.ts +1 -1
  19. package/dist/types/modes/types.d.ts +0 -1
  20. package/dist/types/stt/asr-client.d.ts +7 -3
  21. package/dist/types/task/spawn-policy.d.ts +17 -0
  22. package/dist/types/task/spawn-policy.test.d.ts +1 -0
  23. package/dist/types/task/types.d.ts +8 -2
  24. package/dist/types/tools/__tests__/eval-description.test.d.ts +1 -0
  25. package/dist/types/tools/browser/cmux/cmux-tab.d.ts +2 -2
  26. package/dist/types/tools/browser/registry.d.ts +2 -0
  27. package/dist/types/tools/browser/run-cancellation.d.ts +4 -0
  28. package/dist/types/tools/browser/tab-supervisor.d.ts +30 -1
  29. package/dist/types/tools/eval.d.ts +3 -6
  30. package/dist/types/tools/write.d.ts +1 -1
  31. package/dist/types/utils/image-vision-fallback.d.ts +1 -1
  32. package/package.json +14 -13
  33. package/scripts/bundle-dist.ts +23 -4
  34. package/scripts/generate-docs-index.ts +116 -24
  35. package/src/advisor/__tests__/advisor.test.ts +1 -1
  36. package/src/async/job-manager.ts +27 -3
  37. package/src/auto-thinking/classifier.ts +1 -1
  38. package/src/cli/bench-cli.ts +3 -12
  39. package/src/cli/dry-balance-cli.ts +1 -6
  40. package/src/cli/grep-cli.ts +1 -1
  41. package/src/cli/models-cli.ts +3 -81
  42. package/src/commands/models.ts +1 -2
  43. package/src/commit/model-selection.ts +4 -4
  44. package/src/config/inline-tool-descriptors-mode.ts +1 -2
  45. package/src/config/model-discovery.ts +150 -82
  46. package/src/config/model-registry.ts +11 -225
  47. package/src/config/model-resolver.ts +23 -135
  48. package/src/config/models-config-schema.ts +0 -22
  49. package/src/config/prompt-templates.ts +20 -0
  50. package/src/config/settings-schema.ts +35 -1
  51. package/src/config/settings.ts +60 -24
  52. package/src/eval/__tests__/agent-bridge.test.ts +17 -3
  53. package/src/eval/agent-bridge.ts +7 -9
  54. package/src/eval/completion-bridge.ts +1 -1
  55. package/src/eval/py/__tests__/runner-shell-output.test.ts +157 -0
  56. package/src/eval/py/runner.py +169 -18
  57. package/src/extensibility/extensions/model-api.ts +1 -3
  58. package/src/extensibility/extensions/runner.ts +62 -5
  59. package/src/extensibility/skills.ts +77 -0
  60. package/src/internal-urls/docs-index.generated.txt +2 -2
  61. package/src/lsp/client.ts +162 -45
  62. package/src/lsp/config.ts +17 -3
  63. package/src/lsp/index.ts +31 -21
  64. package/src/main.ts +0 -1
  65. package/src/mcp/transports/http.ts +19 -17
  66. package/src/mcp/transports/stdio.test.ts +51 -1
  67. package/src/mcp/transports/stdio.ts +19 -9
  68. package/src/memories/index.ts +0 -1
  69. package/src/mnemopi/backend.ts +1 -1
  70. package/src/modes/acp/acp-agent.ts +6 -9
  71. package/src/modes/components/model-selector.ts +32 -186
  72. package/src/modes/components/todo-reminder.ts +5 -1
  73. package/src/modes/controllers/event-controller.ts +1 -16
  74. package/src/modes/controllers/selector-controller.ts +57 -36
  75. package/src/modes/interactive-mode.ts +0 -6
  76. package/src/modes/rpc/rpc-mode.ts +5 -8
  77. package/src/modes/skill-command.ts +8 -20
  78. package/src/modes/types.ts +0 -1
  79. package/src/prompts/system/subagent-system-prompt.md +2 -2
  80. package/src/prompts/system/tool-call-loop-redirect.md +8 -0
  81. package/src/prompts/tools/eval.md +2 -2
  82. package/src/prompts/tools/task.md +1 -1
  83. package/src/sdk.ts +2 -9
  84. package/src/session/agent-session.ts +89 -8
  85. package/src/session/session-context.ts +2 -1
  86. package/src/session/session-manager.ts +2 -1
  87. package/src/session/unexpected-stop-classifier.ts +1 -1
  88. package/src/stt/asr-client.ts +87 -27
  89. package/src/stt/downloader.ts +8 -2
  90. package/src/task/executor.ts +1 -3
  91. package/src/task/index.ts +37 -32
  92. package/src/task/spawn-policy.test.ts +63 -0
  93. package/src/task/spawn-policy.ts +58 -0
  94. package/src/task/types.ts +77 -6
  95. package/src/tools/__tests__/eval-description.test.ts +19 -0
  96. package/src/tools/ast-grep.ts +34 -12
  97. package/src/tools/browser/cmux/cmux-tab.ts +66 -24
  98. package/src/tools/browser/registry.ts +25 -0
  99. package/src/tools/browser/run-cancellation.ts +47 -0
  100. package/src/tools/browser/tab-supervisor.ts +120 -7
  101. package/src/tools/browser/tab-worker.ts +22 -10
  102. package/src/tools/browser.ts +1 -0
  103. package/src/tools/eval.ts +15 -10
  104. package/src/tools/grep.ts +11 -8
  105. package/src/tools/inspect-image.ts +1 -1
  106. package/src/tools/write.ts +49 -9
  107. package/src/utils/commit-message-generator.ts +0 -1
  108. package/src/utils/git.ts +22 -1
  109. package/src/utils/image-vision-fallback.ts +2 -3
  110. package/src/utils/title-generator.ts +1 -1
@@ -51,21 +51,7 @@ const LOCAL_PROVIDER_PLACEHOLDERS = new Set<string>(["llama-cpp-local", "lm-stud
51
51
  import type { ApiKeyResolver, FetchImpl } from "@oh-my-pi/pi-ai";
52
52
  import { registerOAuthProvider, unregisterOAuthProviders } from "@oh-my-pi/pi-ai/oauth";
53
53
  import type { OAuthCredentials, OAuthLoginCallbacks } from "@oh-my-pi/pi-ai/oauth/types";
54
- import {
55
- buildCanonicalModelIndex,
56
- buildCanonicalModelOrder,
57
- buildModelProviderPriorityRank,
58
- type CanonicalModelIndex,
59
- type CanonicalModelRecord,
60
- type CanonicalModelVariant,
61
- type CanonicalVariantPreferences,
62
- formatCanonicalVariantSelector,
63
- getBundledCanonicalReferenceData,
64
- getBundledModelReferenceIndex,
65
- type ModelEquivalenceConfig,
66
- resolveCanonicalVariant,
67
- resolveModelReference,
68
- } from "@oh-my-pi/pi-catalog/identity";
54
+ import { getBundledModelReferenceIndex, resolveModelReference } from "@oh-my-pi/pi-catalog/identity";
69
55
  import { isBunTestRuntime, isRecord, logger } from "@oh-my-pi/pi-utils";
70
56
  import { parseModelString, resolveProviderModelReference } from "../config/model-resolver";
71
57
  import type { AuthStorage, OAuthCredential } from "../session/auth-storage";
@@ -85,8 +71,6 @@ import { ModelsConfigFile, type ProviderValidationModel, validateProviderConfigu
85
71
  import type { ModelOverride, ModelsConfig, ProviderAuthMode } from "./models-config-schema";
86
72
  import { settings } from "./settings";
87
73
 
88
- export type { CanonicalModelIndex, CanonicalModelRecord, CanonicalModelVariant, ModelEquivalenceConfig };
89
-
90
74
  export const kNoAuth = "N/A";
91
75
 
92
76
  export function isAuthenticated(apiKey: string | undefined | null): apiKey is string {
@@ -243,17 +227,6 @@ export interface ProviderDiscoveryState {
243
227
  error?: string;
244
228
  }
245
229
 
246
- export interface CanonicalModelQueryOptions {
247
- availableOnly?: boolean;
248
- candidates?: readonly Model<Api>[];
249
- }
250
-
251
- /** A canonical record (with query-filtered variants) plus the variant model selected for it. */
252
- export interface CanonicalModelSelection {
253
- record: CanonicalModelRecord;
254
- model: Model<Api>;
255
- }
256
-
257
230
  /** Result of loading custom models from models.json */
258
231
  interface CustomModelsResult {
259
232
  models?: CustomModelOverlay[];
@@ -262,7 +235,6 @@ interface CustomModelsResult {
262
235
  keylessProviders?: Set<string>;
263
236
  discoverableProviders?: DiscoveryProviderConfig[];
264
237
  configuredProviders?: Set<string>;
265
- equivalence?: ModelEquivalenceConfig;
266
238
  error?: ConfigError;
267
239
  found: boolean;
268
240
  }
@@ -718,28 +690,17 @@ function getDisabledProviderIdsFromSettings(): Set<string> {
718
690
  }
719
691
  }
720
692
 
721
- function getConfiguredProviderOrderFromSettings(): string[] {
722
- try {
723
- return settings.get("modelProviderOrder");
724
- } catch {
725
- return [];
726
- }
727
- }
728
-
729
693
  /**
730
694
  * Model registry - loads and manages models, resolves API keys via AuthStorage.
731
695
  */
732
696
  export class ModelRegistry {
733
697
  #models: Model<Api>[] = [];
734
- #canonicalIndex: CanonicalModelIndex = { records: [], byId: new Map(), bySelector: new Map() };
735
- #canonicalIndexDirty: boolean = true;
736
698
  #customProviderApiKeys: Map<string, string> = new Map();
737
699
  #keylessProviders: Set<string> = new Set();
738
700
  #discoverableProviders: DiscoveryProviderConfig[] = [];
739
701
  #customModelOverlays: CustomModelOverlay[] = [];
740
702
  #providerOverrides: Map<string, ProviderOverride> = new Map();
741
703
  #modelOverrides: Map<string, Map<string, ModelOverride>> = new Map();
742
- #equivalenceConfig: ModelEquivalenceConfig | undefined;
743
704
  #configError: ConfigError | undefined = undefined;
744
705
  #modelsConfigFile: ConfigFile<ModelsConfig>;
745
706
  #lastStaticLoadMtime: number | null = null;
@@ -759,8 +720,6 @@ export class ModelRegistry {
759
720
  // Runtime model managers registered by extensions via fetchDynamicModels.
760
721
  // Keyed by provider name; use the same SQLite cache path as builtins.
761
722
  #runtimeModelManagers: Map<string, { options: ModelManagerOptions<Api>; sourceId: string }> = new Map();
762
- #rebuildPending: boolean = false;
763
- #rebuildSuspended: number = 0;
764
723
  #fetch: FetchImpl;
765
724
 
766
725
  #resolveCommandBackedApiKey(provider: string): CommandApiKeyResolution {
@@ -820,14 +779,9 @@ export class ModelRegistry {
820
779
  * Reload models from disk (built-in + custom from models.json).
821
780
  */
822
781
  async refresh(strategy: ModelRefreshStrategy = "online-if-uncached"): Promise<void> {
823
- this.#suspendRebuild();
824
- try {
825
- this.#reloadStaticModels();
826
- this.#suppressedSelectors.clear();
827
- await this.#refreshRuntimeDiscoveries(strategy);
828
- } finally {
829
- this.#resumeRebuild();
830
- }
782
+ this.#reloadStaticModels();
783
+ this.#suppressedSelectors.clear();
784
+ await this.#refreshRuntimeDiscoveries(strategy);
831
785
  }
832
786
 
833
787
  refreshInBackground(strategy: ModelRefreshStrategy = "online-if-uncached"): void {
@@ -849,18 +803,13 @@ export class ModelRegistry {
849
803
  }
850
804
 
851
805
  async refreshProvider(providerId: string, strategy: ModelRefreshStrategy = "online"): Promise<void> {
852
- this.#suspendRebuild();
853
- try {
854
- this.#reloadStaticModels();
855
- for (const selector of this.#suppressedSelectors.keys()) {
856
- if (selector.startsWith(`${providerId}/`)) {
857
- this.#suppressedSelectors.delete(selector);
858
- }
806
+ this.#reloadStaticModels();
807
+ for (const selector of this.#suppressedSelectors.keys()) {
808
+ if (selector.startsWith(`${providerId}/`)) {
809
+ this.#suppressedSelectors.delete(selector);
859
810
  }
860
- await this.#refreshRuntimeDiscoveries(strategy, new Set([providerId]));
861
- } finally {
862
- this.#resumeRebuild();
863
811
  }
812
+ await this.#refreshRuntimeDiscoveries(strategy, new Set([providerId]));
864
813
  }
865
814
 
866
815
  /**
@@ -910,7 +859,6 @@ export class ModelRegistry {
910
859
  this.#models = this.#models.map(candidate =>
911
860
  candidate.provider === current.provider && candidate.id === current.id ? patched : candidate,
912
861
  );
913
- this.#rebuildCanonicalIndex();
914
862
  return patched;
915
863
  }
916
864
 
@@ -927,18 +875,13 @@ export class ModelRegistry {
927
875
  if (this.#runtimeModelManagers.size === 0) {
928
876
  return;
929
877
  }
930
- this.#suspendRebuild();
931
- try {
932
- await this.#refreshRuntimeDiscoveries(strategy, new Set(this.#runtimeModelManagers.keys()));
933
- } finally {
934
- this.#resumeRebuild();
935
- }
878
+ await this.#refreshRuntimeDiscoveries(strategy, new Set(this.#runtimeModelManagers.keys()));
936
879
  }
937
880
 
938
881
  #reloadStaticModels(): void {
939
882
  const currentMtime = this.#modelsConfigFile.getMtimeMs();
940
883
  if (currentMtime !== null && currentMtime === this.#lastStaticLoadMtime) {
941
- // models.json unchanged since last load; reload + canonical rebuild would be redundant.
884
+ // models.json unchanged since last load; reloading would be redundant.
942
885
  return;
943
886
  }
944
887
  this.#modelsConfigFile.invalidate();
@@ -956,7 +899,6 @@ export class ModelRegistry {
956
899
  }
957
900
  this.#providerOverrides.clear();
958
901
  this.#modelOverrides.clear();
959
- this.#equivalenceConfig = undefined;
960
902
  this.#configError = undefined;
961
903
  this.#providerDiscoveryStates.clear();
962
904
  this.#loadModels();
@@ -978,7 +920,6 @@ export class ModelRegistry {
978
920
  keylessProviders = new Set(),
979
921
  discoverableProviders = [],
980
922
  configuredProviders = new Set(),
981
- equivalence,
982
923
  error: configError,
983
924
  } = this.#loadCustomModels();
984
925
  this.#configError = configError;
@@ -987,7 +928,6 @@ export class ModelRegistry {
987
928
  this.#customModelOverlays = customModels;
988
929
  this.#providerOverrides = overrides;
989
930
  this.#modelOverrides = modelOverrides;
990
- this.#equivalenceConfig = equivalence;
991
931
 
992
932
  this.#addImplicitDiscoverableProviders(configuredProviders);
993
933
  let builtInModels = this.#applyHardcodedModelPolicies(this.#loadBuiltInModels(overrides));
@@ -1024,7 +964,6 @@ export class ModelRegistry {
1024
964
  // collapse effort-tier variants here so X/X-thinking twins fold.
1025
965
  const withModelOverrides = this.#applyModelOverrides(collapseBuiltModelVariants(combined), this.#modelOverrides);
1026
966
  this.#models = this.#applyRuntimeProviderOverrides(withModelOverrides);
1027
- this.#rebuildCanonicalIndex();
1028
967
  this.#lastStaticLoadMtime = this.#modelsConfigFile.getMtimeMs();
1029
968
  }
1030
969
 
@@ -1373,7 +1312,6 @@ export class ModelRegistry {
1373
1312
  keylessProviders,
1374
1313
  discoverableProviders,
1375
1314
  configuredProviders,
1376
- equivalence: value.equivalence,
1377
1315
  found: true,
1378
1316
  };
1379
1317
  }
@@ -1423,7 +1361,6 @@ export class ModelRegistry {
1423
1361
  const combined = this.#mergeCustomModels(withConfigModels, this.#runtimeModelOverlays);
1424
1362
  const withModelOverrides = this.#applyModelOverrides(collapseBuiltModelVariants(combined), this.#modelOverrides);
1425
1363
  this.#models = this.#applyRuntimeProviderOverrides(withModelOverrides);
1426
- this.#rebuildCanonicalIndex();
1427
1364
  }
1428
1365
 
1429
1366
  #configuredDiscoveryCacheProviderId(providerConfig: DiscoveryProviderConfig): string {
@@ -1819,44 +1756,6 @@ export class ModelRegistry {
1819
1756
  });
1820
1757
  }
1821
1758
 
1822
- #rebuildCanonicalIndex(): void {
1823
- if (this.#rebuildSuspended > 0) {
1824
- this.#rebuildPending = true;
1825
- return;
1826
- }
1827
- // Defer the catalog-wide index build to first read. Boot model
1828
- // resolution reads it only when enabledModels or a default-role pattern
1829
- // is configured; the empty interactive launch never reads it pre-paint,
1830
- // so the ~200ms build over the full catalog moves off the first-paint
1831
- // critical path.
1832
- this.#canonicalIndexDirty = true;
1833
- this.#rebuildPending = false;
1834
- }
1835
-
1836
- #ensureCanonicalIndex(): CanonicalModelIndex {
1837
- if (this.#canonicalIndexDirty) {
1838
- this.#canonicalIndex = logger.time("buildCanonicalModelIndex", () =>
1839
- buildCanonicalModelIndex(this.#models, getBundledCanonicalReferenceData(), this.#equivalenceConfig),
1840
- );
1841
- this.#canonicalIndexDirty = false;
1842
- }
1843
- return this.#canonicalIndex;
1844
- }
1845
-
1846
- #suspendRebuild(): void {
1847
- this.#rebuildSuspended += 1;
1848
- }
1849
-
1850
- #resumeRebuild(): void {
1851
- if (this.#rebuildSuspended > 0) {
1852
- this.#rebuildSuspended -= 1;
1853
- }
1854
- if (this.#rebuildSuspended === 0 && this.#rebuildPending) {
1855
- this.#rebuildPending = false;
1856
- this.#canonicalIndexDirty = true;
1857
- }
1858
- }
1859
-
1860
1759
  #parseModels(config: ModelsConfig): CustomModelOverlay[] {
1861
1760
  const models: CustomModelOverlay[] = [];
1862
1761
  for (const [providerName, providerConfig] of Object.entries(config.providers ?? {})) {
@@ -1918,115 +1817,6 @@ export class ModelRegistry {
1918
1817
  };
1919
1818
  }
1920
1819
 
1921
- /**
1922
- * Build the shared per-query filter state for canonical model queries.
1923
- * Hoisted out of the per-record loop: building the candidate-selector set
1924
- * and availability memo once per query instead of once per record is what
1925
- * keeps `getCanonicalModelSelections` linear instead of O(records × candidates).
1926
- */
1927
- #canonicalQueryFilters(options: CanonicalModelQueryOptions | undefined): {
1928
- candidateKeys: Set<string> | undefined;
1929
- isAvailable: ((model: Model<Api>) => boolean) | undefined;
1930
- } {
1931
- return {
1932
- candidateKeys: options?.candidates
1933
- ? new Set(options.candidates.map(candidate => formatCanonicalVariantSelector(candidate)))
1934
- : undefined,
1935
- isAvailable: options?.availableOnly ? this.#createAvailabilityCheck() : undefined,
1936
- };
1937
- }
1938
-
1939
- #filterCanonicalVariants(
1940
- record: CanonicalModelRecord,
1941
- candidateKeys: ReadonlySet<string> | undefined,
1942
- isAvailable: ((model: Model<Api>) => boolean) | undefined,
1943
- ): CanonicalModelVariant[] {
1944
- return record.variants.filter(variant => {
1945
- if (candidateKeys && !candidateKeys.has(variant.selector)) {
1946
- return false;
1947
- }
1948
- if (isAvailable && !isAvailable(variant.model)) {
1949
- return false;
1950
- }
1951
- return true;
1952
- });
1953
- }
1954
-
1955
- #variantPreferences(candidates: readonly Model<Api>[]): CanonicalVariantPreferences {
1956
- return {
1957
- modelOrder: buildCanonicalModelOrder(candidates),
1958
- providerRank: buildModelProviderPriorityRank(getConfiguredProviderOrderFromSettings()),
1959
- };
1960
- }
1961
-
1962
- getCanonicalModels(options?: CanonicalModelQueryOptions): CanonicalModelRecord[] {
1963
- const { candidateKeys, isAvailable } = this.#canonicalQueryFilters(options);
1964
- const records: CanonicalModelRecord[] = [];
1965
- for (const record of this.#ensureCanonicalIndex().records) {
1966
- const variants = this.#filterCanonicalVariants(record, candidateKeys, isAvailable);
1967
- if (variants.length === 0) {
1968
- continue;
1969
- }
1970
- records.push({
1971
- id: record.id,
1972
- name: record.name,
1973
- variants,
1974
- });
1975
- }
1976
- return records;
1977
- }
1978
-
1979
- /**
1980
- * One-pass equivalent of `getCanonicalModels` + `resolveCanonicalModel` per
1981
- * record. The per-query state (candidate-selector set, availability memo,
1982
- * provider rank, candidate order) is built once, so the whole catalog
1983
- * resolves in O(records + candidates) instead of O(records × candidates).
1984
- * This is the path the model selector hydrates from synchronously on open.
1985
- */
1986
- getCanonicalModelSelections(options?: CanonicalModelQueryOptions): CanonicalModelSelection[] {
1987
- const { candidateKeys, isAvailable } = this.#canonicalQueryFilters(options);
1988
- const candidates = options?.candidates ?? (options?.availableOnly ? this.getAvailable() : this.getAll());
1989
- const preferences = this.#variantPreferences(candidates);
1990
- const selections: CanonicalModelSelection[] = [];
1991
- for (const record of this.#ensureCanonicalIndex().records) {
1992
- const variants = this.#filterCanonicalVariants(record, candidateKeys, isAvailable);
1993
- if (variants.length === 0) {
1994
- continue;
1995
- }
1996
- const resolved = resolveCanonicalVariant(variants, preferences);
1997
- if (!resolved) {
1998
- continue;
1999
- }
2000
- selections.push({
2001
- record: { id: record.id, name: record.name, variants },
2002
- model: resolved.model,
2003
- });
2004
- }
2005
- return selections;
2006
- }
2007
-
2008
- getCanonicalVariants(canonicalId: string, options?: CanonicalModelQueryOptions): CanonicalModelVariant[] {
2009
- const record = this.#ensureCanonicalIndex().byId.get(canonicalId.trim().toLowerCase());
2010
- if (!record) {
2011
- return [];
2012
- }
2013
- const { candidateKeys, isAvailable } = this.#canonicalQueryFilters(options);
2014
- return this.#filterCanonicalVariants(record, candidateKeys, isAvailable);
2015
- }
2016
-
2017
- resolveCanonicalModel(canonicalId: string, options?: CanonicalModelQueryOptions): Model<Api> | undefined {
2018
- const variants = this.getCanonicalVariants(canonicalId, options);
2019
- if (variants.length === 0) {
2020
- return undefined;
2021
- }
2022
- const candidates = options?.candidates ?? (options?.availableOnly ? this.getAvailable() : this.getAll());
2023
- return resolveCanonicalVariant(variants, this.#variantPreferences(candidates))?.model;
2024
- }
2025
-
2026
- getCanonicalId(model: Model<Api>): string | undefined {
2027
- return this.#ensureCanonicalIndex().bySelector.get(formatCanonicalVariantSelector(model).toLowerCase());
2028
- }
2029
-
2030
1820
  /**
2031
1821
  * Get only models that have auth configured.
2032
1822
  * This is a fast check that doesn't refresh OAuth tokens.
@@ -2187,7 +1977,6 @@ export class ModelRegistry {
2187
1977
  }
2188
1978
  this.#lastStaticLoadMtime = null;
2189
1979
  this.#reloadStaticModels();
2190
- this.#rebuildCanonicalIndex();
2191
1980
  }
2192
1981
 
2193
1982
  /**
@@ -2316,13 +2105,11 @@ export class ModelRegistry {
2316
2105
  const credential = this.authStorage.getOAuthCredential(providerName);
2317
2106
  if (credential) {
2318
2107
  this.#models = config.oauth.modifyModels(withRuntimeTransportOverride, credential);
2319
- this.#rebuildCanonicalIndex();
2320
2108
  return;
2321
2109
  }
2322
2110
  }
2323
2111
 
2324
2112
  this.#models = withRuntimeTransportOverride;
2325
- this.#rebuildCanonicalIndex();
2326
2113
  return;
2327
2114
  }
2328
2115
 
@@ -2393,7 +2180,6 @@ export class ModelRegistry {
2393
2180
  if (m.provider !== providerName) return m;
2394
2181
  return this.#applyProviderTransportOverride(m, transportOverride);
2395
2182
  });
2396
- this.#rebuildCanonicalIndex();
2397
2183
  }
2398
2184
  }
2399
2185