mirror of
https://github.com/garrytan/gstack.git
synced 2026-05-02 11:45:20 +02:00
da75ebaaa0
Follow-up to wintermute's initial Opus 4.7 migration commit (addresses
ship-quality review findings before v1.6.1.0 release).
Overlay split (model-overlays/):
- Move 4 Opus-4.7-specific nudges (Fan out, Effort-match, Batch your
questions, Literal interpretation) from claude.md into new
opus-4-7.md with {{INHERIT:claude}}
- claude.md now holds only model-agnostic nudges (Todo discipline,
Think before heavy, Dedicated tools over Bash)
- Prevents Opus-4.7-specific guidance leaking onto Sonnet/Haiku
- Uses existing {{INHERIT:claude}} mechanism at
scripts/resolvers/model-overlay.ts:28-43
scripts/models.ts:
- Add opus-4-7 to ALL_MODEL_NAMES
- resolveModel: claude-opus-4-7-* variants route to opus-4-7,
all other claude-* variants continue to route to claude
scripts/resolvers/utility.ts:
- Update coAuthor trailer fallback: Opus 4.6 -> Opus 4.7
(fallback was missed in the initial migration commit)
scripts/resolvers/preamble/generate-routing-injection.ts:
- Align policy with new SKILL.md.tmpl: soft "when in doubt, invoke"
instead of hard "ALWAYS invoke... Do NOT answer directly"
- Replace stale /checkpoint reference with /context-save +
/context-restore (skills were renamed in v1.0.1.0)
- Expand route coverage to match full skill inventory:
/plan-devex-review, /qa-only, /devex-review, /land-and-deploy,
/setup-deploy, /canary, /open-gstack-browser,
/setup-browser-cookies, /benchmark, /learn, /plan-tune, /health
scripts/resolvers/preamble/generate-voice-directive.ts:
- Voice example closing: "Want me to ship it?" -> "Want me to fix it?"
- Preserves directness while routing through review gates
SKILL.md.tmpl:
- Add routing triggers for skills that were missing from the list:
/plan-devex-review, /qa-only, /devex-review, /land-and-deploy,
/setup-deploy, /canary, /open-gstack-browser,
/setup-browser-cookies, /benchmark, /learn, /plan-tune, /health
- Within Opus 4.7 overlay, added scope boundary to
"Literal interpretation" nudge ("fix tests that this branch
introduced or is responsible for")
- Added pacing exception to "Batch your questions" nudge so skills
that require one-question-at-a-time pacing still win
Follow-up commit will regenerate SKILL.md files + update goldens.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
71 lines
2.5 KiB
TypeScript
71 lines
2.5 KiB
TypeScript
/**
|
|
* Model taxonomy — neutral module with no imports from hosts/ or resolvers/.
|
|
*
|
|
* Model families supported by model overlays in model-overlays/{family}.md.
|
|
* Host configs can reference these as `defaultModel` strings (validated at
|
|
* generation time), but the model axis is independent of the host axis.
|
|
*
|
|
* IMPORTANT: host ≠ model. Claude Code can run any Claude model (Opus, Sonnet,
|
|
* Haiku, future). Codex CLI runs GPT/o-series models. Cursor and OpenCode can
|
|
* front multiple providers. We do NOT auto-detect the model from the host —
|
|
* users pass --model explicitly. Default is 'claude'.
|
|
*/
|
|
|
|
export const ALL_MODEL_NAMES = [
|
|
'claude',
|
|
'opus-4-7',
|
|
'gpt',
|
|
'gpt-5.4',
|
|
'gemini',
|
|
'o-series',
|
|
] as const;
|
|
|
|
export type Model = (typeof ALL_MODEL_NAMES)[number];
|
|
|
|
/**
|
|
* Resolve a model argument from CLI input to a known Model family.
|
|
*
|
|
* Precedence rules:
|
|
* 1. Exact match against ALL_MODEL_NAMES → return as-is.
|
|
* 2. Family heuristics for common variants:
|
|
* - `gpt-5.4-mini`, `gpt-5.4-turbo`, `gpt-5.4-*` → `gpt-5.4`
|
|
* - `gpt-*` (anything else GPT) → `gpt`
|
|
* - `o3`, `o4`, `o4-mini`, `o1`, `o1-mini`, `o1-pro` → `o-series`
|
|
* - `claude-*` (sonnet, opus, haiku, any version) → `claude`
|
|
* - `gemini-*` (2.5-pro, flash, etc.) → `gemini`
|
|
* 3. Unknown input → returns null (caller decides: error, or fall back).
|
|
*
|
|
* The resolver file in model-overlays/{model}.md applies further fallback
|
|
* (e.g., missing gpt-5.4.md falls back to gpt.md). This function only
|
|
* normalizes CLI input to a family name.
|
|
*/
|
|
export function resolveModel(input: string): Model | null {
|
|
const s = input.trim();
|
|
if (!s) return null;
|
|
|
|
// Exact match first
|
|
if ((ALL_MODEL_NAMES as readonly string[]).includes(s)) {
|
|
return s as Model;
|
|
}
|
|
|
|
// Family heuristics
|
|
if (/^gpt-5\.4(-|$)/.test(s)) return 'gpt-5.4';
|
|
if (/^gpt(-|$)/.test(s)) return 'gpt';
|
|
if (/^o[0-9]+(-|$)/.test(s)) return 'o-series';
|
|
if (/^claude-opus-4-7(-|$)/.test(s)) return 'opus-4-7';
|
|
if (/^claude(-|$)/.test(s)) return 'claude';
|
|
if (/^gemini(-|$)/.test(s)) return 'gemini';
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Validate a string against ALL_MODEL_NAMES. Used by host-config validators
|
|
* when a HostConfig declares `defaultModel`. Returns an error message or null
|
|
* if valid.
|
|
*/
|
|
export function validateModel(input: string): string | null {
|
|
if ((ALL_MODEL_NAMES as readonly string[]).includes(input)) return null;
|
|
return `'${input}' is not a known model. Use ${ALL_MODEL_NAMES.join(', ')}.`;
|
|
}
|