From 8c8c6e207a4575fd68694426d8fe9d340dd5ac9c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 11 Jun 2026 00:35:02 +0000 Subject: [PATCH 1/3] chore: bump version to 1.4.4 for hotfix --- .claude-plugin/plugin.json | 2 +- gemini-extension.json | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index fbf040169..1e4e7e869 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "gsd-core", "displayName": "GSD Core", - "version": "1.4.3", + "version": "1.4.4", "description": "GSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.", "author": { "name": "open-gsd", diff --git a/gemini-extension.json b/gemini-extension.json index 29f593ed8..7bf0294af 100644 --- a/gemini-extension.json +++ b/gemini-extension.json @@ -1,6 +1,6 @@ { "name": "gsd-core", - "version": "1.4.3", + "version": "1.4.4", "description": "GSD Core — a meta-prompting, context engineering, and spec-driven development system for AI coding agents. Loads gsd's operating context into every Gemini CLI session.", "contextFileName": "GEMINI.md" } diff --git a/package-lock.json b/package-lock.json index e2ecfdde2..0ee8d6eb6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@opengsd/gsd-core", - "version": "1.4.3", + "version": "1.4.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@opengsd/gsd-core", - "version": "1.4.3", + "version": "1.4.4", "license": "MIT", "dependencies": { "@anthropic-ai/claude-agent-sdk": "^0.2.84", diff --git a/package.json b/package.json index 1dc75d00a..8c2a096ed 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@opengsd/gsd-core", - "version": "1.4.3", + "version": "1.4.4", "description": "GSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.", "bin": { "gsd-core": "bin/install.js", From 6d9d0e638afc492163fa02abaa9acf8a630d58d0 Mon Sep 17 00:00:00 2001 From: Colin Johnson Date: Wed, 10 Jun 2026 20:32:26 -0400 Subject: [PATCH 2/3] feat(#1014): add Claude Fable 5 model config (#1015) (cherry picked from commit 76f42ddb4bde5688fc9cabbcef83573d63730ffe) --- .../1014-anthropic-fable-model-config.md | 5 ++ docs/CONFIGURATION.md | 6 +-- docs/ja-JP/CONFIGURATION.md | 2 +- docs/ko-KR/CONFIGURATION.md | 2 +- docs/pt-BR/CONFIGURATION.md | 8 +-- docs/zh-CN/CONFIGURATION.md | 8 +-- gsd-core/bin/shared/model-catalog.json | 5 ++ gsd-core/workflows/settings-advanced.md | 18 ++++--- tests/feat-49-model-policy-presets.test.cjs | 53 +++++++++++++++---- 9 files changed, 78 insertions(+), 29 deletions(-) create mode 100644 .changeset/1014-anthropic-fable-model-config.md diff --git a/.changeset/1014-anthropic-fable-model-config.md b/.changeset/1014-anthropic-fable-model-config.md new file mode 100644 index 000000000..fbc39da13 --- /dev/null +++ b/.changeset/1014-anthropic-fable-model-config.md @@ -0,0 +1,5 @@ +--- +type: Changed +pr: 1015 +--- +Added an opt-in `anthropic-fable` model policy provider preset for Claude Fable 5 high-budget routing while preserving the existing Anthropic Opus 4.8 defaults and `anthropic` provider preset. (#1014) diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index f18291470..578e4ff52 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -144,7 +144,7 @@ GSD stores project settings in `.planning/config.json`. Created during `/gsd-new | `model_profile` | enum | `quality`, `balanced`, `budget`, `adaptive`, `inherit` | `balanced` | Model tier for each agent (see [Model Profiles](#model-profiles)). `adaptive` was added per [#1713](https://github.com/open-gsd/gsd-core/issues/1713) / [#1806](https://github.com/open-gsd/gsd-core/issues/1806) and resolves the same way as the other tiers under runtime-aware profiles. | | `runtime` | string | `claude`, `codex`, or any string | (none) | Active runtime for [runtime-aware profile resolution](#runtime-aware-profiles-2517). When set, profile tiers (opus/sonnet/haiku) resolve to runtime-native model IDs. Today only the Codex install path emits per-agent model IDs from this resolver; other runtimes (`opencode`, `gemini`, `qwen`, `copilot`, …) consume the resolver at spawn time and gain dedicated install-path support in [#2612](https://github.com/open-gsd/gsd-core/issues/2612). When unset (default), behavior is unchanged from prior versions. Added in v1.39 | | `model_profile_overrides..` | string \| object | per-runtime tier override | (none) | Override the runtime-aware tier mapping for a specific `(runtime, tier)`. Tier is one of `opus`, `sonnet`, `haiku`. Value is either a model ID string (e.g. `"gpt-5-pro"`) or `{ model, reasoning_effort }`. See [Runtime-Aware Profiles](#runtime-aware-profiles-2517). Added in v1.39 | -| `model_policy.provider` | string | `openai`, `anthropic`, `google`, `qwen`, `generic` | (none) | Declares the model provider. Known providers (`openai`, `anthropic`, `google`, `qwen`) unlock catalog-backed presets. `generic` treats all model IDs as opaque strings — no prefix inference, no reasoning-effort defaults. `model_policy.runtime_tiers` resolves before legacy `model_profile_overrides`. See [Model Policy Presets](#model-policy-presets-model_policy--added-in-v142). Added in v1.42 ([#49](https://github.com/open-gsd/gsd-core/issues/49)) | +| `model_policy.provider` | string | `openai`, `anthropic`, `anthropic-fable`, `google`, `qwen`, `generic` | (none) | Declares the model provider. Known providers (`openai`, `anthropic`, `anthropic-fable`, `google`, `qwen`) unlock catalog-backed presets. `generic` treats all model IDs as opaque strings — no prefix inference, no reasoning-effort defaults. `model_policy.runtime_tiers` resolves before legacy `model_profile_overrides`. See [Model Policy Presets](#model-policy-presets-model_policy--added-in-v142). Added in v1.42 ([#49](https://github.com/open-gsd/gsd-core/issues/49)) | | `model_policy.budget` | enum | `high`, `medium`, `low` | (none) | Selects a budget tier when using a known provider. GSD materializes the matching catalog preset into explicit tier mappings at resolve time. Ignored when `provider` is `generic` or `custom`. Added in v1.42 ([#49](https://github.com/open-gsd/gsd-core/issues/49)) | | `model_policy.high` | string | model ID | (none) | High-cost tier model ID for `generic`/`custom` provider. Used when `provider: "generic"` or `"custom"`. Added in v1.42 ([#49](https://github.com/open-gsd/gsd-core/issues/49)) | | `model_policy.medium` | string | model ID | (none) | Medium-cost tier model ID for `generic`/`custom` provider. Added in v1.42 ([#49](https://github.com/open-gsd/gsd-core/issues/49)) | @@ -159,7 +159,7 @@ GSD stores project settings in `.planning/config.json`. Created during `/gsd-new | `project_code` | string | any short string | (none) | Prefix for phase directory names (e.g., `"ABC"` produces `ABC-01-setup/`). Added in v1.31 | | `phase_id_convention` | enum | `"milestone-prefixed"`, `null` | `null` | Phase ID naming convention. `null` = legacy numeric IDs (`Phase 1`, `Phase 2`). `"milestone-prefixed"` = globally unique IDs that encode the enclosing milestone (`Phase 1-01`, `Phase 1-02`). Run `gsd-tools roadmap upgrade --convention milestone-prefixed` to migrate an existing ROADMAP.md. | | `response_language` | string | language code | (none) | Language for agent responses (e.g., `"pt"`, `"ko"`, `"ja"`). Propagates to all spawned agents for cross-phase language consistency. Added in v1.32 | -| `context_window` | number | any integer | `200000` | Context window size in tokens. Set `1000000` for 1M-context models (e.g., `claude-opus-4-7[1m]`). Values `>= 500000` enable adaptive context enrichment (full-body reads of prior SUMMARY.md, deeper anti-pattern reads). Configured via `/gsd-config --advanced`. | +| `context_window` | number | any integer | `200000` | Context window size in tokens. Set `1000000` for 1M-context models (e.g., `claude-fable-5`). Values `>= 500000` enable adaptive context enrichment (full-body reads of prior SUMMARY.md, deeper anti-pattern reads). Configured via `/gsd-config --advanced`. | | `context_profile` | string | `dev`, `research`, `review` | (none) | Execution context preset that applies a pre-configured bundle of mode, model, and workflow settings for the current type of work. Added in v1.34 | | `claude_md_path` | string | any file path | `./CLAUDE.md` | Custom output path for the generated CLAUDE.md file. Useful for monorepos or projects that need CLAUDE.md in a non-root location. Defaults to `./CLAUDE.md` at the project root. Added in v1.36 | | `claude_md_assembly.mode` | enum | `embed`, `link` | `embed` | Controls how managed sections are written into CLAUDE.md. `embed` (default) inlines content between GSD markers. `link` writes `@.planning/` instead — Claude Code expands the reference at runtime, reducing CLAUDE.md size by ~65% on typical projects. `link` only applies to sections that have a real source file; `workflow` and fallback sections always embed. Per-block overrides: `claude_md_assembly.blocks.
` (e.g. `claude_md_assembly.blocks.architecture: link`). Added in v1.38 | @@ -1284,7 +1284,7 @@ Choose a provider and budget level via the settings workflow; GSD writes the can } ``` -Known providers: `openai`, `anthropic`, `google`, `qwen`. Budget levels: `high`, `medium`, `low`. +Known providers: `openai`, `anthropic`, `anthropic-fable`, `google`, `qwen`. Budget levels: `high`, `medium`, `low`. Use `anthropic` to keep the Opus 4.8-backed Claude preset, or `anthropic-fable` to opt into Claude Fable 5 for high-budget top-tier routing. For advanced per-runtime control, `runtime_tiers` accepts explicit entries using the internal profile tier names (`opus`, `sonnet`, `haiku`): diff --git a/docs/ja-JP/CONFIGURATION.md b/docs/ja-JP/CONFIGURATION.md index 9ea2ca621..cb6c3a416 100644 --- a/docs/ja-JP/CONFIGURATION.md +++ b/docs/ja-JP/CONFIGURATION.md @@ -331,7 +331,7 @@ GSD が非 Claude ランタイム向けにインストールされると、イ | 値 | 動作 | 使用場面 | |----|------|---------| | `false`(デフォルト) | Claude エイリアス(`opus`、`sonnet`、`haiku`)を返す | Claude Code + ネイティブ Anthropic API | -| `true` | エイリアスを完全な Claude モデル ID(`claude-opus-4-6`)にマッピング | 完全な ID が必要な API を使用する Claude Code | +| `true` | エイリアスを完全な Claude モデル ID(`claude-opus-4-8`)にマッピング | 完全な ID が必要な API を使用する Claude Code | | `"omit"` | 空文字列を返す(ランタイムがデフォルトを選択) | 非 Claude ランタイム(Codex、OpenCode、Gemini CLI、Kilo) | ### プロファイルの設計思想 diff --git a/docs/ko-KR/CONFIGURATION.md b/docs/ko-KR/CONFIGURATION.md index a8f67164c..152d647f8 100644 --- a/docs/ko-KR/CONFIGURATION.md +++ b/docs/ko-KR/CONFIGURATION.md @@ -331,7 +331,7 @@ quick 태스크 브랜칭 예시: | 값 | 동작 | 사용 시점 | |----|------|----------| | `false` (기본값) | Claude 별칭 반환 (`opus`, `sonnet`, `haiku`) | 네이티브 Anthropic API를 사용하는 Claude Code | -| `true` | 별칭을 전체 Claude 모델 ID로 매핑 (`claude-opus-4-6`) | 전체 ID가 필요한 API를 사용하는 Claude Code | +| `true` | 별칭을 전체 Claude 모델 ID로 매핑 (`claude-opus-4-8`) | 전체 ID가 필요한 API를 사용하는 Claude Code | | `"omit"` | 빈 문자열 반환 (런타임이 기본값 선택) | 비 Claude 런타임 (Codex, OpenCode, Gemini CLI, Kilo) | ### 프로필 철학 diff --git a/docs/pt-BR/CONFIGURATION.md b/docs/pt-BR/CONFIGURATION.md index 881afc846..c64c815e2 100644 --- a/docs/pt-BR/CONFIGURATION.md +++ b/docs/pt-BR/CONFIGURATION.md @@ -141,7 +141,7 @@ O GSD armazena as configurações do projeto em `.planning/config.json`. Criado | `model_profile` | enum | `quality`, `balanced`, `budget`, `adaptive`, `inherit` | `balanced` | Nível de modelo para cada agente (consulte [Perfis de Modelo](#model-profiles)). `adaptive` foi adicionado conforme [#1713](https://github.com/open-gsd/gsd-core/issues/1713) / [#1806](https://github.com/open-gsd/gsd-core/issues/1806) e resolve da mesma forma que os outros níveis em perfis com reconhecimento de runtime. | | `runtime` | string | `claude`, `codex`, ou qualquer string | (nenhum) | Runtime ativo para [resolução de perfil com reconhecimento de runtime](#runtime-aware-profiles-2517). Quando definido, os níveis de perfil (opus/sonnet/haiku) resolvem para IDs de modelo nativos do runtime. Atualmente, apenas o caminho de instalação do Codex emite IDs de modelo por agente a partir deste resolvedor; outros runtimes (`opencode`, `gemini`, `qwen`, `copilot`, …) consomem o resolvedor no momento do spawn e ganham suporte a caminho de instalação dedicado em [#2612](https://github.com/open-gsd/gsd-core/issues/2612). Quando não definido (padrão), o comportamento não se altera em relação às versões anteriores. Adicionado na v1.39 | | `model_profile_overrides..` | string \| object | substituição de nível por runtime | (nenhum) | Substitui o mapeamento de nível com reconhecimento de runtime para um `(runtime, tier)` específico. O nível é um de `opus`, `sonnet`, `haiku`. O valor é uma string de ID de modelo (por exemplo, `"gpt-5-pro"`) ou `{ model, reasoning_effort }`. Consulte [Perfis com Reconhecimento de Runtime](#runtime-aware-profiles-2517). Adicionado na v1.39 | -| `model_policy.provider` | string | `openai`, `anthropic`, `google`, `qwen`, `generic` | (nenhum) | Declara o provedor de modelo. Provedores conhecidos (`openai`, `anthropic`, `google`, `qwen`) desbloqueiam predefinições baseadas em catálogo. `generic` trata todos os IDs de modelo como strings opacas — sem inferência de prefixo, sem padrões de esforço de raciocínio. `model_policy.runtime_tiers` resolve antes do legado `model_profile_overrides`. Consulte [Predefinições de Política de Modelo](#model-policy-presets-model_policy--added-in-v142). Adicionado na v1.42 ([#49](https://github.com/open-gsd/gsd-core/issues/49)) | +| `model_policy.provider` | string | `openai`, `anthropic`, `anthropic-fable`, `google`, `qwen`, `generic` | (nenhum) | Declara o provedor de modelo. Provedores conhecidos (`openai`, `anthropic`, `anthropic-fable`, `google`, `qwen`) desbloqueiam predefinições baseadas em catálogo. `generic` trata todos os IDs de modelo como strings opacas — sem inferência de prefixo, sem padrões de esforço de raciocínio. `model_policy.runtime_tiers` resolve antes do legado `model_profile_overrides`. Consulte [Predefinições de Política de Modelo](#model-policy-presets-model_policy--added-in-v142). Adicionado na v1.42 ([#49](https://github.com/open-gsd/gsd-core/issues/49)) | | `model_policy.budget` | enum | `high`, `medium`, `low` | (nenhum) | Seleciona um nível de orçamento ao usar um provedor conhecido. O GSD materializa a predefinição de catálogo correspondente em mapeamentos de nível explícitos no momento da resolução. Ignorado quando `provider` é `generic` ou `custom`. Adicionado na v1.42 ([#49](https://github.com/open-gsd/gsd-core/issues/49)) | | `model_policy.high` | string | ID do modelo | (nenhum) | ID do modelo de nível de custo alto para provedor `generic`/`custom`. Usado quando `provider: "generic"` ou `"custom"`. Adicionado na v1.42 ([#49](https://github.com/open-gsd/gsd-core/issues/49)) | | `model_policy.medium` | string | ID do modelo | (nenhum) | ID do modelo de nível de custo médio para provedor `generic`/`custom`. Adicionado na v1.42 ([#49](https://github.com/open-gsd/gsd-core/issues/49)) | @@ -155,7 +155,7 @@ O GSD armazena as configurações do projeto em `.planning/config.json`. Criado | `project_code` | string | qualquer string curta | (nenhum) | Prefixo para nomes de diretórios de fase (por exemplo, `"ABC"` produz `ABC-01-setup/`). Adicionado na v1.31 | | `phase_id_convention` | enum | `"milestone-prefixed"`, `null` | `null` | Convenção de nomenclatura para IDs de fase. `null` = IDs numéricos legados (`Phase 1`, `Phase 2`). `"milestone-prefixed"` = IDs globalmente únicos que codificam o marco envolvente (`Phase 1-01`, `Phase 1-02`). Execute `gsd-tools roadmap upgrade --convention milestone-prefixed` para migrar um ROADMAP.md existente. | | `response_language` | string | código de idioma | (nenhum) | Idioma para respostas dos agentes (por exemplo, `"pt"`, `"ko"`, `"ja"`). Propagado para todos os agentes gerados para consistência de idioma entre fases. Adicionado na v1.32 | -| `context_window` | number | qualquer inteiro | `200000` | Tamanho da janela de contexto em tokens. Defina `1000000` para modelos com contexto de 1M (por exemplo, `claude-opus-4-7[1m]`). Valores `>= 500000` habilitam enriquecimento adaptativo de contexto (leituras completas de SUMMARY.md anteriores, leituras mais profundas de antipadrões). Configurado via `/gsd-config --advanced`. | +| `context_window` | number | qualquer inteiro | `200000` | Tamanho da janela de contexto em tokens. Defina `1000000` para modelos com contexto de 1M (por exemplo, `claude-fable-5`). Valores `>= 500000` habilitam enriquecimento adaptativo de contexto (leituras completas de SUMMARY.md anteriores, leituras mais profundas de antipadrões). Configurado via `/gsd-config --advanced`. | | `context_profile` | string | `dev`, `research`, `review` | (nenhum) | Predefinição de contexto de execução que aplica um conjunto pré-configurado de configurações de modo, modelo e fluxo de trabalho para o tipo atual de trabalho. Adicionado na v1.34 | | `claude_md_path` | string | qualquer caminho de arquivo | `./CLAUDE.md` | Caminho de saída personalizado para o arquivo CLAUDE.md gerado. Útil para monorepos ou projetos que precisam do CLAUDE.md em um local fora da raiz. Padrão é `./CLAUDE.md` na raiz do projeto. Adicionado na v1.36 | | `claude_md_assembly.mode` | enum | `embed`, `link` | `embed` | Controla como as seções gerenciadas são escritas no CLAUDE.md. `embed` (padrão) incorpora conteúdo entre marcadores GSD. `link` escreve `@.planning/` — o Claude Code expande a referência em tempo de execução, reduzindo o tamanho do CLAUDE.md em ~65% em projetos típicos. `link` aplica-se apenas a seções que possuem um arquivo-fonte real; as seções `workflow` e fallback sempre são incorporadas. Substituições por bloco: `claude_md_assembly.blocks.
` (por exemplo `claude_md_assembly.blocks.architecture: link`). Adicionado na v1.38 | @@ -994,7 +994,7 @@ O hint `reasoning_effort` por nível do catálogo de modelos é um campo legado 2. `effort.agent_overrides[]` 3. `effort.routing_tier_defaults[]` 4. `effort.default` -5. `"high"` (padrão universal do Anthropic Opus 4.8) +5. `"high"` (padrão universal do Claude) ```json { @@ -1229,7 +1229,7 @@ Escolha um provedor e nível de orçamento via o fluxo de configurações; o GSD } ``` -Provedores conhecidos: `openai`, `anthropic`, `google`, `qwen`. Níveis de orçamento: `high`, `medium`, `low`. +Provedores conhecidos: `openai`, `anthropic`, `anthropic-fable`, `google`, `qwen`. Níveis de orçamento: `high`, `medium`, `low`. Use `anthropic` para manter a predefinição Claude baseada em Opus 4.8, ou `anthropic-fable` para optar pelo Claude Fable 5 no roteamento de alto orçamento. Para controle avançado por runtime, `runtime_tiers` aceita entradas explícitas usando os nomes internos de nível de perfil (`opus`, `sonnet`, `haiku`): diff --git a/docs/zh-CN/CONFIGURATION.md b/docs/zh-CN/CONFIGURATION.md index 4e170d0ef..07aff134a 100644 --- a/docs/zh-CN/CONFIGURATION.md +++ b/docs/zh-CN/CONFIGURATION.md @@ -141,7 +141,7 @@ GSD 将项目设置存储在 `.planning/config.json` 中。该文件在 `/gsd-ne | `model_profile` | enum | `quality`, `balanced`, `budget`, `adaptive`, `inherit` | `balanced` | 每个 agent 的模型层级(参见[模型配置文件](#模型配置文件))。`adaptive` 根据 [#1713](https://github.com/open-gsd/gsd-core/issues/1713) / [#1806](https://github.com/open-gsd/gsd-core/issues/1806) 添加,在运行时感知的配置文件下与其他层级以相同方式解析。 | | `runtime` | string | `claude`, `codex` 或任意字符串 | (无) | [运行时感知配置文件解析](#运行时感知配置文件-2517)的活跃运行时。设置后,配置文件层级(opus/sonnet/haiku)解析为运行时原生模型 ID。目前仅 Codex 安装路径通过此解析器为每个 agent 生成模型 ID;其他运行时(`opencode`、`gemini`、`qwen`、`copilot` 等)在 spawn 时消费该解析器,并在 [#2612](https://github.com/open-gsd/gsd-core/issues/2612) 中获得专用安装路径支持。未设置时(默认),行为与之前版本相同。v1.39 新增 | | `model_profile_overrides..` | string \| object | 按运行时的层级覆盖 | (无) | 覆盖特定 `(runtime, tier)` 的运行时感知层级映射。层级为 `opus`、`sonnet`、`haiku` 之一。值为模型 ID 字符串(如 `"gpt-5-pro"`)或 `{ model, reasoning_effort }`。参见[运行时感知配置文件](#运行时感知配置文件-2517)。v1.39 新增 | -| `model_policy.provider` | string | `openai`, `anthropic`, `google`, `qwen`, `generic` | (无) | 声明模型提供商。已知提供商(`openai`、`anthropic`、`google`、`qwen`)启用基于目录的预设。`generic` 将所有模型 ID 视为不透明字符串——无前缀推断,无推理努力默认值。`model_policy.runtime_tiers` 在旧版 `model_profile_overrides` 之前解析。参见[模型策略预设](#模型策略预设-model_policy--v142-新增)。v1.42 新增([#49](https://github.com/open-gsd/gsd-core/issues/49)) | +| `model_policy.provider` | string | `openai`, `anthropic`, `anthropic-fable`, `google`, `qwen`, `generic` | (无) | 声明模型提供商。已知提供商(`openai`、`anthropic`、`anthropic-fable`、`google`、`qwen`)启用基于目录的预设。`generic` 将所有模型 ID 视为不透明字符串——无前缀推断,无推理努力默认值。`model_policy.runtime_tiers` 在旧版 `model_profile_overrides` 之前解析。参见[模型策略预设](#模型策略预设-model_policy--v142-新增)。v1.42 新增([#49](https://github.com/open-gsd/gsd-core/issues/49)) | | `model_policy.budget` | enum | `high`, `medium`, `low` | (无) | 使用已知提供商时选择预算层级。GSD 在解析时将匹配的目录预设具体化为显式层级映射。当 `provider` 为 `generic` 或 `custom` 时忽略。v1.42 新增([#49](https://github.com/open-gsd/gsd-core/issues/49)) | | `model_policy.high` | string | 模型 ID | (无) | `generic`/`custom` 提供商的高成本层级模型 ID。当 `provider: "generic"` 或 `"custom"` 时使用。v1.42 新增([#49](https://github.com/open-gsd/gsd-core/issues/49)) | | `model_policy.medium` | string | 模型 ID | (无) | `generic`/`custom` 提供商的中等成本层级模型 ID。v1.42 新增([#49](https://github.com/open-gsd/gsd-core/issues/49)) | @@ -155,7 +155,7 @@ GSD 将项目设置存储在 `.planning/config.json` 中。该文件在 `/gsd-ne | `project_code` | string | 任意短字符串 | (无) | 阶段目录名称的前缀(如 `"ABC"` 生成 `ABC-01-setup/`)。v1.31 新增 | | `phase_id_convention` | enum | `"milestone-prefixed"`, `null` | `null` | 阶段 ID 命名规范。`null` = 旧版数字 ID(`Phase 1`、`Phase 2`)。`"milestone-prefixed"` = 编码所属里程碑的全局唯一 ID(`Phase 1-01`、`Phase 1-02`)。运行 `gsd-tools roadmap upgrade --convention milestone-prefixed` 迁移现有 ROADMAP.md。 | | `response_language` | string | 语言代码 | (无) | agent 响应语言(如 `"pt"`、`"ko"`、`"ja"`)。传播至所有派生 agent,实现跨阶段语言一致性。v1.32 新增 | -| `context_window` | number | 任意整数 | `200000` | 上下文窗口大小(token 数)。对于 1M 上下文模型(如 `claude-opus-4-7[1m]`),设置为 `1000000`。`>= 500000` 的值启用自适应上下文增强(完整读取之前的 SUMMARY.md,更深入的反模式读取)。通过 `/gsd-config --advanced` 配置。 | +| `context_window` | number | 任意整数 | `200000` | 上下文窗口大小(token 数)。对于 1M 上下文模型(如 `claude-fable-5`),设置为 `1000000`。`>= 500000` 的值启用自适应上下文增强(完整读取之前的 SUMMARY.md,更深入的反模式读取)。通过 `/gsd-config --advanced` 配置。 | | `context_profile` | string | `dev`, `research`, `review` | (无) | 执行上下文预设,为当前工作类型应用预配置的模式、模型和工作流设置包。v1.34 新增 | | `claude_md_path` | string | 任意文件路径 | `./CLAUDE.md` | 生成的 CLAUDE.md 文件的自定义输出路径。适用于需要将 CLAUDE.md 放在非根目录位置的 monorepo 或项目。默认为项目根目录下的 `./CLAUDE.md`。v1.36 新增 | | `claude_md_assembly.mode` | enum | `embed`, `link` | `embed` | 控制如何将受管理的节写入 CLAUDE.md。`embed`(默认)在 GSD 标记之间内联内容。`link` 改为写入 `@.planning/`——Claude Code 在运行时展开引用,在典型项目中将 CLAUDE.md 大小减少约 65%。`link` 仅适用于有真实源文件的节;`workflow` 和回退节始终嵌入。按块覆盖:`claude_md_assembly.blocks.
`(如 `claude_md_assembly.blocks.architecture: link`)。v1.38 新增 | @@ -963,7 +963,7 @@ minimal < low < medium < high < xhigh < max 2. `effort.agent_overrides[]` 3. `effort.routing_tier_defaults[]` 4. `effort.default` -5. `"high"`(Anthropic Opus 4.8 通用默认值) +5. `"high"`(Claude 通用默认值) ```json { @@ -1198,7 +1198,7 @@ minimal < low < medium < high < xhigh < max } ``` -已知提供商:`openai`、`anthropic`、`google`、`qwen`。预算级别:`high`、`medium`、`low`。 +已知提供商:`openai`、`anthropic`、`anthropic-fable`、`google`、`qwen`。预算级别:`high`、`medium`、`low`。使用 `anthropic` 保留基于 Opus 4.8 的 Claude 预设,或使用 `anthropic-fable` 在高预算路由中选择 Claude Fable 5。 对于高级的按运行时控制,`runtime_tiers` 接受使用内部配置文件层级名称(`opus`、`sonnet`、`haiku`)的显式条目: diff --git a/gsd-core/bin/shared/model-catalog.json b/gsd-core/bin/shared/model-catalog.json index 8e0d37d97..67be8116b 100644 --- a/gsd-core/bin/shared/model-catalog.json +++ b/gsd-core/bin/shared/model-catalog.json @@ -89,6 +89,11 @@ "sonnet": { "low": { "model": "claude-haiku-4-5" }, "medium": { "model": "claude-sonnet-4-6" }, "high": { "model": "claude-opus-4-8" } }, "haiku": { "low": { "model": "claude-haiku-4-5" }, "medium": { "model": "claude-haiku-4-5" }, "high": { "model": "claude-sonnet-4-6" } } }, + "anthropic-fable": { + "opus": { "low": { "model": "claude-opus-4-5" }, "medium": { "model": "claude-opus-4-8" }, "high": { "model": "claude-fable-5" } }, + "sonnet": { "low": { "model": "claude-haiku-4-5" }, "medium": { "model": "claude-sonnet-4-6" }, "high": { "model": "claude-fable-5" } }, + "haiku": { "low": { "model": "claude-haiku-4-5" }, "medium": { "model": "claude-haiku-4-5" }, "high": { "model": "claude-sonnet-4-6" } } + }, "openai": { "opus": { "low": { "model": "gpt-5.3-codex", "reasoning_effort": "medium" }, "medium": { "model": "gpt-5.5", "reasoning_effort": "high" }, "high": { "model": "gpt-5.5", "reasoning_effort": "xhigh" } }, "sonnet": { "low": { "model": "gpt-5.4-mini", "reasoning_effort": "low" }, "medium": { "model": "gpt-5.3-codex", "reasoning_effort": "medium" }, "high": { "model": "gpt-5.5", "reasoning_effort": "medium" } }, diff --git a/gsd-core/workflows/settings-advanced.md b/gsd-core/workflows/settings-advanced.md index 7b67c6658..503daf243 100644 --- a/gsd-core/workflows/settings-advanced.md +++ b/gsd-core/workflows/settings-advanced.md @@ -84,7 +84,7 @@ Runtime Model Tiers: - `model_profile_overrides..haiku` (default: built-in for the runtime, or absent) Model Policy: -- `model_policy.provider` (default: `null` — known values: anthropic, openai, google, qwen) +- `model_policy.provider` (default: `null` — known values: anthropic, anthropic-fable, openai, google, qwen) - `model_policy.budget` (default: `null` — known values: high, medium, low) - `model_policy.high` (default: `null` — model ID for the high-cost tier; used by generic provider path) - `model_policy.medium` (default: `null` — model ID for the medium-cost tier; used by generic provider path) @@ -624,15 +624,16 @@ AskUserQuestion([ multiSelect: false, options: [ { label: "anthropic", description: "claude-opus-4-8 / claude-sonnet-4-6 / claude-haiku-4-5 (Anthropic / Claude)" }, + { label: "anthropic-fable", description: "claude-fable-5 / claude-sonnet-4-6 / claude-haiku-4-5 (Anthropic / Claude Fable opt-in)" }, { label: "openai", description: "gpt-5.5 / gpt-5.3-codex / gpt-5.4-mini (OpenAI / Codex)" }, - { label: "google", description: "gemini-3-pro / gemini-3-flash / gemini-2.5-flash-lite (Google Gemini)" }, - { label: "qwen", description: "qwen3-max-2026-01-23 / qwen3-coder-plus / qwen3-coder-next (Qwen)" } + { label: "Other known provider", description: "Type google or qwen; both still use the canonical tier mapping." } ] } ]) ``` -After the user picks a provider, ask: +If the user selects "Other known provider", ask them to type `google` or `qwen`. +Use the typed value as the provider. After the user picks or types a provider, ask: ```text AskUserQuestion([ @@ -653,9 +654,12 @@ Canonical tier mappings by provider and budget: | Provider | Budget | high | medium | low | |-----------|--------|----------------------------|----------------------------|----------------------------| -| anthropic | high | claude-opus-4-8 | claude-opus-4-8 | claude-opus-4-8 | +| anthropic | high | claude-opus-4-8 | claude-opus-4-8 | claude-sonnet-4-6 | | anthropic | medium | claude-opus-4-8 | claude-sonnet-4-6 | claude-haiku-4-5 | | anthropic | low | claude-haiku-4-5 | claude-haiku-4-5 | claude-haiku-4-5 | +| anthropic-fable | high | claude-fable-5 | claude-fable-5 | claude-sonnet-4-6 | +| anthropic-fable | medium | claude-opus-4-8 | claude-sonnet-4-6 | claude-haiku-4-5 | +| anthropic-fable | low | claude-haiku-4-5 | claude-haiku-4-5 | claude-haiku-4-5 | | openai | high | gpt-5.5 | gpt-5.5 | gpt-5.5 | | openai | medium | gpt-5.5 | gpt-5.3-codex | gpt-5.4-mini | | openai | low | gpt-5.4-mini | gpt-5.4-mini | gpt-5.4-mini | @@ -713,7 +717,7 @@ Proceed to Step E. ```bash # Known-provider path — write all four keys atomically: -gsd_run query config-set model_policy.provider "" # e.g., anthropic / openai / google / qwen +gsd_run query config-set model_policy.provider "" # e.g., anthropic / anthropic-fable / openai / google / qwen gsd_run query config-set model_policy.budget "" # high / medium / low gsd_run query config-set model_policy.high "" gsd_run query config-set model_policy.medium "" @@ -775,7 +779,7 @@ Display: | fast_mode.routing_tier_defaults.standard | {true/false} | | fast_mode.routing_tier_defaults.heavy | {true/false} | | fast_mode.agent_overrides. | {true/false} | -| model_policy.provider | {anthropic/openai/google/qwen/custom/null} | +| model_policy.provider | {anthropic/anthropic-fable/openai/google/qwen/custom/null} | | model_policy.budget | {high/medium/low/null} | | model_policy.high | {model-id/null} | | model_policy.medium | {model-id/null} | diff --git a/tests/feat-49-model-policy-presets.test.cjs b/tests/feat-49-model-policy-presets.test.cjs index e034ee83a..c0c3e9b28 100644 --- a/tests/feat-49-model-policy-presets.test.cjs +++ b/tests/feat-49-model-policy-presets.test.cjs @@ -5,7 +5,7 @@ * * { * "model_policy": { - * "provider": "anthropic", + * "provider": "anthropic-fable", * "budget": "high", * "runtime_tiers": { * "opencode": { @@ -120,9 +120,29 @@ describe('#49 resolveModelPolicy Sub-path B: provider presets', () => { const result = resolveModelPolicy(policy, 'opus'); assert.ok(typeof result === 'string' && result.length > 0, `expected a non-empty model ID string, got: ${JSON.stringify(result)}`); - // Anthropic opus model IDs contain "claude" and "opus" - assert.match(result, /claude.*opus|opus.*claude/i, - `expected anthropic opus model ID to contain "claude" and "opus", got: ${result}`); + assert.strictEqual(result, 'claude-opus-4-8', + `expected anthropic opus/high to resolve to claude-opus-4-8, got: ${result}`); + }); + + test('known provider "anthropic" + tier "sonnet" + budget "high" preserves Opus 4.8 routing', () => { + const policy = { provider: 'anthropic', budget: 'high' }; + const result = resolveModelPolicy(policy, 'sonnet'); + assert.strictEqual(result, 'claude-opus-4-8', + `expected anthropic sonnet/high to resolve to claude-opus-4-8, got: ${result}`); + }); + + test('known provider "anthropic-fable" + tier "opus" + budget "high" resolves to Claude Fable 5', () => { + const policy = { provider: 'anthropic-fable', budget: 'high' }; + const result = resolveModelPolicy(policy, 'opus'); + assert.strictEqual(result, 'claude-fable-5', + `expected anthropic-fable opus/high to resolve to claude-fable-5, got: ${result}`); + }); + + test('known provider "anthropic-fable" + tier "haiku" + budget "high" keeps low tier on Sonnet', () => { + const policy = { provider: 'anthropic-fable', budget: 'high' }; + const result = resolveModelPolicy(policy, 'haiku'); + assert.strictEqual(result, 'claude-sonnet-4-6', + `expected anthropic-fable haiku/high to resolve to claude-sonnet-4-6, got: ${result}`); }); test('known provider "openai" + tier "sonnet" + budget "low" returns model with reasoning_effort from preset', () => { @@ -287,9 +307,8 @@ describe('#49 resolveModelInternal: model_policy in the resolution chain', () => 'model_policy must fire before model_profile_overrides and win'); assert.ok(typeof result === 'string' && result.length > 0, 'must return a non-empty model ID'); - // model_policy anthropic/opus/high should return a claude opus model ID - assert.match(result, /claude.*opus|opus.*claude/i, - 'expected anthropic preset opus model, got: ' + result); + assert.strictEqual(result, 'claude-opus-4-8', + 'expected anthropic preset opus/high to resolve to claude-opus-4-8'); }); test('model_policy with provider:"anthropic" + budget:"high" + runtime:"opencode" resolves to preset model', () => { @@ -304,8 +323,22 @@ describe('#49 resolveModelInternal: model_policy in the resolution chain', () => const result = resolveModelInternal(projectDir, 'gsd-planner'); assert.ok(typeof result === 'string' && result.length > 0, 'expected a non-empty model ID'); - assert.match(result, /claude.*opus|opus.*claude/i, - 'anthropic/opus/high must resolve to an opus model ID'); + assert.strictEqual(result, 'claude-opus-4-8', + 'anthropic/opus/high must resolve to claude-opus-4-8'); + }); + + test('model_policy with provider:"anthropic-fable" + budget:"high" resolves to Fable preset model', () => { + writeConfig(projectDir, { + runtime: 'opencode', + model_profile: 'quality', + model_policy: { + provider: 'anthropic-fable', + budget: 'high', + }, + }); + const result = resolveModelInternal(projectDir, 'gsd-planner'); + assert.strictEqual(result, 'claude-fable-5', + 'anthropic-fable/opus/high must resolve to claude-fable-5'); }); test('model_policy is skipped when runtime is absent', () => { @@ -661,6 +694,8 @@ describe('#49 KNOWN_PROVIDERS exports from model-catalog.cjs and core.cjs', () = // 'anthropic' must be in the set since it is a required provider preset assert.ok(providers.includes('anthropic'), 'KNOWN_PROVIDERS must include "anthropic"'); + assert.ok(providers.includes('anthropic-fable'), + 'KNOWN_PROVIDERS must include "anthropic-fable"'); // 'generic' is a special fallback, not a real provider — it must NOT be in KNOWN_PROVIDERS // (KNOWN_PROVIDERS lists only providers with catalog entries) assert.ok(!providers.includes('generic'), From 380b2fb2db2bb9628ceea1333d2c484dee410a29 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 11 Jun 2026 00:47:57 +0000 Subject: [PATCH 3/3] chore: promote CHANGELOG for v1.4.4 --- .changeset/1014-anthropic-fable-model-config.md | 5 ----- CHANGELOG.md | 6 ++++++ 2 files changed, 6 insertions(+), 5 deletions(-) delete mode 100644 .changeset/1014-anthropic-fable-model-config.md diff --git a/.changeset/1014-anthropic-fable-model-config.md b/.changeset/1014-anthropic-fable-model-config.md deleted file mode 100644 index fbc39da13..000000000 --- a/.changeset/1014-anthropic-fable-model-config.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -type: Changed -pr: 1015 ---- -Added an opt-in `anthropic-fable` model policy provider preset for Claude Fable 5 high-budget routing while preserving the existing Anthropic Opus 4.8 defaults and `anthropic` provider preset. (#1014) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75a3a4a77..0151004ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## [Unreleased] +## [1.4.4] - 2026-06-11 + +### Changed + +- Added an opt-in `anthropic-fable` model policy provider preset for Claude Fable 5 high-budget routing while preserving the existing Anthropic Opus 4.8 defaults and `anthropic` provider preset. (#1014) (#1015) + ## [1.4.3] - 2026-06-09 ### Fixed