Repository navigation
feat(notes): require an explicit llm.model; enum-validate provider - #564
Conversation
9ec230f to
930a4ab
Compare
de2c837 to
779356f
Compare
930a4ab to
dfb88c5
Compare
779356f to
0daf56d
Compare
dfb88c5 to
61f1373
Compare
0daf56d to
2cbb186
Compare
61f1373 to
037e4db
Compare
2cbb186 to
8a7837f
Compare
|
Both P1s (the CLI validation gap) addressed in the latest push: The |
037e4db to
65e6237
Compare
8a7837f to
920e7bc
Compare
65e6237 to
046a069
Compare
920e7bc to
7e27af4
Compare
|
Addressed the follow-up P1 (empty-string model): added |
…nfig opts out Every detected ecosystem is versioned and, where publishing is configured and authenticated, published by default; explicit config is only ever an opt-out. - publish.cargo.enabled / publish.pub.enabled now default true (was false) - add version.npm.enabled (default true) so package.json handling is opt-out-able like Cargo.toml/pubspec.yaml; wired into every version-stage package.json write - keep Cargo.toml (root and hybrid packages) versioned when npm handling is disabled — the npm gate must not skip or abandon cargo updates - reframe the enabled describe() text as opt-outs; regenerate schema + config docs Default-on is safe: an enabled registry that finds zero targets no-ops, and publishing without credentials fails/skips at the auth check. Refs #554 BREAKING CHANGE: crates.io and pub.dev publishing now default on for detected packages. Set publish.cargo.enabled / publish.pub.enabled to false to opt out (version and tag only). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011i1KvoyxATU3bz5V5Sf1Xu
046a069 to
56166dd
Compare
Resolve model-ID rot by requiring the consumer to name a current model rather than shipping curated defaults that rot every release — the openai default we would have shipped, gpt-4o-mini, is already deprecated. LLM enhancement is already an explicit opt-in (it needs an API key, or a running Ollama with a pulled model), so naming the model is a marginal, honest addition, and it removes a maintenance treadmill. - llm.model is required; a missing model fails at config validation, not silently inside the notes soft-fail catch. - provider is a Zod enum (openai | openai-compatible | anthropic | ollama), not a free-form string. - openai-compatible requires baseURL at the schema level. - the CLI --llm-* flags assemble a config that bypasses loadConfig's Zod pass, so validate it through LLMConfigSchema before use — a bad provider or missing model fails loud (non-zero exit) instead of degrading silently in the pipeline. - drop the curated-default machinery (LLM_DEFAULTS.models, resolveModelId, the per-provider `?? default` fallbacks). - docs: use a `<your-model>` placeholder in config examples (a real id would drift). - regenerate schema + config docs. Refs #541 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011i1KvoyxATU3bz5V5Sf1Xu
7e27af4 to
25bc9e9
Compare
|
Addressed the error-message P2: the CLI validation catch now surfaces the actual Zod issue messages ( |
Stacked on #563 (base branch
feat/unify-ecosystem-enablement) — review/merge #563 first.What (revised approach)
Instead of shipping curated per-provider default models (the original plan), require the consumer to name a model and fail loud if they don't. The evidence for the pivot: the openai default we would have shipped,
gpt-4o-mini, is already deprecated/removed from OpenAI's API — proving any default releasekit ships will rot and become a per-release maintenance treadmill (and a silent failure mode for consumers relying on it).llm.modelis required — a missing model fails at config validation (Zod), not silently inside the notes soft-fail catch. releasekit ships no model IDs, so there is nothing to rot or maintain.provideris a Zod enum (openai | openai-compatible | anthropic | ollama), not a free-form string — a typo errors at config load.openai-compatiblerequiresbaseURLat the schema level.createProviderenforces the required model for in-process configs too (the CLI--llm-*flags bypass schema parsing), with a clear message.LLM_DEFAULTS.models,resolveModelId, and the per-provider?? defaultfallbacks.releasekit.schema.json+docs/configuration.md.Why require, not default
LLM enhancement is already an explicit opt-in (needs an API key, or a running Ollama with a pulled model), so also naming the model is a marginal, honest addition — there is no true zero-config LLM path to protect. The consumer is best placed to pick a current model for their account/budget, and forcing an explicit, fail-loud choice is more robust than releasekit guessing with an ID that rots.
Tests
modelrequired for every provider; unknownproviderrejected (enum);openai-compatiblerequiresbaseURL.createProvider: a missing model throws a clearllm.model is requirederror;openai-compatiblerequiresbaseURL; valid configs construct the right provider.Closes #541
Greptile Summary
This PR makes
llm.modelan explicit requirement and validatesprovideras a Zod enum, replacing the earlier approach of shipping curated per-provider default model IDs that were already rotting (e.g.,gpt-4o-minideprecated). Both the config-file path (Zod at load time) and the CLI--llm-*flag path (newLLMConfigSchema.parseblock incommand.ts) now fail loudly with non-zero exit codes rather than silently degrading to non-LLM notes.LLMConfigSchemabecomesLLMConfigBaseSchema.superRefine(...)—modelgets.min(1)(empty string rejected),providerbecomes an enum, andopenai-compatiblerequiresbaseURLat config-validation time.command.tsnow runsLLMConfigSchema.parse(llm)on the CLI-assembled object before entering the pipeline; Zod errors are surfaced as a plainErrorcaught byhandleError(non-zero exit), not swallowed by the soft-fail catch.LLM_DEFAULTS.models,resolveModelId, and all per-provider?? defaultfallbacks are dropped; provider constructors now requiremodel: string(non-optional).Confidence Score: 5/5
Safe to merge — all three validation gaps flagged in the previous review round are now closed.
The CLI path now runs through LLMConfigSchema.parse before entering the pipeline, so a bad provider or missing model exits non-zero instead of silently degrading. The Zod schema adds .min(1) so an empty-string model is caught at config load. The provider field is an enum so typos are rejected at validation time. The JSON schema required array is correct. New tests cover all the new constraints. No residual gaps identified.
No files require special attention.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[User provides LLM config] --> B{Source?} B -->|Config file| C[loadConfig - Zod parses full config] B -->|CLI --llm flags| D[Assemble llm object in command.ts] C --> E{LLMConfigSchema valid?} D --> F[LLMConfigSchema.parse llm] F --> G{Valid?} E -->|No| H[ZodError - hard exit non-zero] E -->|Yes| I[config.releaseNotes.llm set] G -->|No| J[Error caught by handleError - hard exit non-zero] G -->|Yes| I I --> K[runPipeline - createProvider] K --> L{model truthy?} L -->|No| M[throw LLMError - soft-catch warn] L -->|Yes| N[Construct provider] N --> O[LLM enhancement runs]%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%% flowchart TD A[User provides LLM config] --> B{Source?} B -->|Config file| C[loadConfig - Zod parses full config] B -->|CLI --llm flags| D[Assemble llm object in command.ts] C --> E{LLMConfigSchema valid?} D --> F[LLMConfigSchema.parse llm] F --> G{Valid?} E -->|No| H[ZodError - hard exit non-zero] E -->|Yes| I[config.releaseNotes.llm set] G -->|No| J[Error caught by handleError - hard exit non-zero] G -->|Yes| I I --> K[runPipeline - createProvider] K --> L{model truthy?} L -->|No| M[throw LLMError - soft-catch warn] L -->|Yes| N[Construct provider] N --> O[LLM enhancement runs]Reviews (6): Last reviewed commit: "feat(notes): require an explicit llm.mod..." | Re-trigger Greptile