feat: add modelCatalog manifest contract#71342
Conversation
Greptile SummaryThis PR introduces the Confidence Score: 3/5Safe to merge after fixing the tiered-cost type mismatch; no runtime paths are affected yet, but the type contract should be correct before consumers are added. One P1 finding (type/normalization contract divergence for tiered cost cacheRead/cacheWrite) pulls the score below the P1 ceiling of 4. Change is otherwise well-tested and isolated to manifest parsing with no live consumers yet. src/plugins/manifest.ts — PluginManifestModelCatalogTieredCost type definition and normalizeStringMap variable shadowing. Prompt To Fix All With AIThis is a comment left during a code review.
Path: src/plugins/manifest.ts
Line: 50-56
Comment:
**Type contract diverges from normalization for tiered cost**
`cacheRead` and `cacheWrite` are declared optional (`?`) in the type, but `normalizeModelCatalogTieredCost` silently drops any tier entry where either is `undefined` (lines 722–729). A plugin author reading the TypeScript type would reasonably omit these fields — and then watch their entire tier row disappear from the registry without any warning. The type should mark both fields as required to match the documented constraint ("requires complete tier rows") and the actual normalization behavior.
```suggestion
export type PluginManifestModelCatalogTieredCost = {
input: number;
output: number;
cacheRead: number;
cacheWrite: number;
range: [number, number] | [number];
};
```
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: src/plugins/manifest.ts
Line: 435
Comment:
**Variable shadows outer function parameter**
The local `const value` here shadows the `value: unknown` function parameter. After `Object.entries(value)` is already called this doesn't produce a runtime bug, but it can confuse readers and may trigger a `no-shadow` lint warning. Renaming the inner variable avoids the ambiguity.
```suggestion
const strValue = normalizeOptionalString(rawValue) ?? "";
```
…and update the subsequent usage on the next line accordingly:
```ts
if (key && strValue) {
normalized[key] = strValue;
}
```
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "fix: require complete model catalog pric..." | Re-trigger Greptile |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 25de885215
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
25de885 to
98d35ec
Compare
|
Landed via rebase onto current main.
Thanks @shakkernerd! |
This PR adds the first manifest-contract slice for the model catalog architecture. It does not change
models list, onboarding, configure, provider loading, or runtime behavior yet.What changed:
modelCatalogto plugin manifests.static,refreshable, orruntimemodelCatalogonPluginManifestRecord.docs/plugins/manifest.md.Contract boundaries:
modelCatalog.providersonly accepts provider ids owned by the manifest’s top-levelproviders.modelCatalog.discoveryonly accepts owned provider ids.modelCatalog.aliasesmay use any alias key, but the alias target must be an owned provider.modelCatalog.suppressionsmay reference other providers because suppression is explicitly cross-source.contextWindowandmaxTokensmust be positive numbers.contextTokensmust be a positive integer.modelCatalog.cost.tieredPricing[]requires complete tier rows:input,output,cacheRead,cacheWrite, andrange.compatonly preserves known typed model compatibility fields instead of accepting arbitrary objects.Why:
Verification:
pnpm test src/plugins/manifest-registry.test.tspnpm check:changedpnpm test src/plugins/manifest-registry.test.ts src/plugins/manifest-registry.ts src/plugins/manifest.ts