|
| 1 | +# Adding (or Changing) a Selectable Bedrock Model — GenAI IDP Accelerator |
| 2 | + |
| 3 | +Use this skill whenever the task is "add support for model X" / "wire up the new |
| 4 | +Y model" / "bump the default model". A selectable model touches ~15 files across |
| 5 | +templates, config, client routing, UI, docs (both tiers), and tests — this skill |
| 6 | +makes it fast and safe. It supersedes the shorter checklist in |
| 7 | +`documentation.md` (which this expands). |
| 8 | + |
| 9 | +> **Golden rule:** never invent model facts. Model ID, regions, context/output |
| 10 | +> limits, tier support, caching support, and pricing all come from the AWS |
| 11 | +> Bedrock **model card** + **region-compatibility page** + **pricing page**. |
| 12 | +> Look them up first (see Step 0). |
| 13 | +
|
| 14 | +--- |
| 15 | + |
| 16 | +## Step 0 — Gather ground truth BEFORE editing (do not skip) |
| 17 | + |
| 18 | +Pull these from AWS docs (the `aws-knowledge` MCP `search_documentation` / |
| 19 | +`read_documentation` tools work well; the region page and model cards are the |
| 20 | +canonical sources): |
| 21 | + |
| 22 | +- [ ] **Exact model ID(s)** — including any `-variant` suffix (e.g. |
| 23 | + `openai.gpt-5.6-sol`) or region/`:1m` prefix/suffix. A "single" launch may |
| 24 | + ship as **several** model IDs (Sol/Terra/Luna). Confirm how many. |
| 25 | +- [ ] **Endpoint / API** — Converse/InvokeModel (normal path) vs |
| 26 | + `bedrock-mantle` Responses API (OpenAI GPT-5.x path). This decides whether |
| 27 | + any routing code is even involved. |
| 28 | +- [ ] **Regions** — In-Region list per model, and whether geo/global |
| 29 | + cross-region IDs (`us.`, `eu.`, `global.`) exist. GovCloud? Per-variant |
| 30 | + differences (one variant often lacks a region the others have). |
| 31 | +- [ ] **Context window + max output tokens.** |
| 32 | +- [ ] **Service tiers** (standard / priority / flex / reserved). |
| 33 | +- [ ] **Prompt caching** support (and whether it's implicit or explicit |
| 34 | + breakpoints). |
| 35 | +- [ ] **Input modalities** (text / image / document / audio…). |
| 36 | +- [ ] **Reasoning model?** (rejects temperature/top_p/top_k, uses effort). |
| 37 | +- [ ] **Pricing** — input / output / cache-read / cache-write per 1M tokens. |
| 38 | + The pricing MCP tool may be denied by IAM; fall back to the Bedrock |
| 39 | + pricing page. If unresolved, mark `TODO(pricing)` and flag for the user. |
| 40 | + |
| 41 | +Record findings in the proposal/PR description so reviewers can verify. |
| 42 | + |
| 43 | +--- |
| 44 | + |
| 45 | +## Step 1 — Find every touchpoint for the SIBLING model |
| 46 | + |
| 47 | +The safest way to be complete: pick the closest existing model and grep for it |
| 48 | +everywhere. That set of files IS your edit list. |
| 49 | + |
| 50 | +```bash |
| 51 | +# Replace with the closest sibling ID (family + region variants) |
| 52 | +SIB='gpt-5.5' # or 'claude-sonnet-5', 'nova-pro', ... |
| 53 | +grep -rniI "$SIB" . --include='*.py' --include='*.yaml' --include='*.yml' \ |
| 54 | + --include='*.json' --include='*.ts' --include='*.tsx' --include='*.md' -l |
| 55 | +# Count enum duplication inside the big template so you don't miss a site: |
| 56 | +grep -cn "\"openai.$SIB\"" patterns/unified/template.yaml |
| 57 | +``` |
| 58 | + |
| 59 | +Cross-check against the file map below. |
| 60 | + |
| 61 | +--- |
| 62 | + |
| 63 | +## Step 2 — The file map |
| 64 | + |
| 65 | +### A. Client routing (`idp_common/bedrock/`) — only if endpoint/params differ |
| 66 | +- [ ] `client.py` — `CACHEPOINT_SUPPORTED_MODELS`, effort model sets |
| 67 | + (`_CLAUDE_4_7_BASE_NAMES` etc.), sampling-param strips. For a normal |
| 68 | + Converse model in an existing family this is often a one-line add or |
| 69 | + nothing. |
| 70 | +- [ ] `openai_responses.py` — **mantle/GPT-5.x only**: `_RESPONSES_API_MODELS`, |
| 71 | + `_MODEL_REGIONS` (per-model!), `_MODEL_DEFAULT_REGION`, docstring. The |
| 72 | + `startswith("openai.gpt-5")` forward-compat guard means routing/rejects |
| 73 | + usually need **no change** — but VERIFY with a test. |
| 74 | +- [ ] `model_utils.py` — max-output-token docstrings/logic if the limit is new. |
| 75 | + |
| 76 | +### B. Config / pricing / limits |
| 77 | +- [ ] `config_library/pricing.yaml` — `bedrock/<model-id>` block per model |
| 78 | + (input/output/cacheRead/cacheWrite). One block per model ID. |
| 79 | +- [ ] `config_library/model_config_limits.yaml` — the `pattern:` is a **regex**; |
| 80 | + a new same-family variant often already matches (e.g. `openai\.gpt-5` |
| 81 | + matches `gpt-5.6-sol`). If limits differ, add/split a pattern. Update the |
| 82 | + `description`. |
| 83 | +- [ ] `lib/idp_common_pkg/idp_common/config/models.py` — only if the model needs |
| 84 | + a NEW inference parameter/field. Effort docstrings if the effort vocab |
| 85 | + changes. |
| 86 | +- [ ] `config/system_defaults/*.yaml` — only if changing a default model. |
| 87 | + |
| 88 | +### C. Templates (CloudFormation enums) — the high-miss-count area |
| 89 | +- [ ] `patterns/unified/template.yaml` — add the ID to **every** service `model` |
| 90 | + / `model_id` enum: extraction, per-class `extraction_model`, |
| 91 | + classification, assessment, summarization, confidence model, evaluation |
| 92 | + `llm_method`, chat. Use the grep count from Step 1 to confirm you hit them |
| 93 | + all. Put it in the correct region sub-list (US / EU / global). |
| 94 | +- [ ] `template.yaml` — IAM. If the model uses an existing endpoint namespace |
| 95 | + already granted (e.g. namespace-wide `bedrock-mantle:*` or |
| 96 | + `bedrock:InvokeModel*` on `foundation-model/*`), no change — VERIFY the |
| 97 | + comment blocks. Add ARNs only for a genuinely new action/endpoint. |
| 98 | +- [ ] `nested/multi-doc-discovery/template.yaml` and other nested templates — |
| 99 | + IAM / enums as applicable. |
| 100 | + |
| 101 | +### D. Region filtering + UI |
| 102 | +- [ ] `src/lambda/update_configuration/index.py` — `US_ONLY_MODELS` (or EU |
| 103 | + filtering). Keep explicit sets complete even when a `startswith` fallback |
| 104 | + covers the new ID. |
| 105 | +- [ ] `src/ui/src/constants/schemaConstants.ts` — dropdown `{label,value}` per |
| 106 | + model. |
| 107 | +- [ ] `src/ui/.../SchemaInspector.tsx` — any other hardcoded UI list. |
| 108 | + |
| 109 | +### E. Feature guards (models rejected for some features) |
| 110 | +- [ ] `discovery/classes_discovery.py`, `discovery/rules_discovery.py` — GPT-5.x |
| 111 | + is rejected for discovery (PDF document blocks unsupported). |
| 112 | +- [ ] `config/merge_utils.py` — `_validate_agentic_openai`, |
| 113 | + `_validate_discovery_openai` reject GPT-5.x for advanced/agentic + discovery. |
| 114 | +- [ ] `chat_with_document_processor/index.py` + its **vendored copy** in |
| 115 | + `chat_stream_processor/vendored/` — keep in sync. |
| 116 | + |
| 117 | +### F. Docs — BOTH tiers (see `documentation.md`) |
| 118 | +- [ ] `lib/idp_common_pkg/idp_common/bedrock/README.md` — module behavior, |
| 119 | + per-model regions/caching/caveats (canonical home for client behavior). |
| 120 | +- [ ] `docs/*.md` — every feature doc that lists models: `openai-models.md` (or |
| 121 | + a new dedicated guide if materially different), `configuration.md`, |
| 122 | + `discovery.md`, `extraction-and-confidence.md`, `service-tiers.md`, |
| 123 | + `web-ui.md`, `eu-region-model-support.md`, `policy-discovery.md`, |
| 124 | + `idp-cli.md`, `cross-account-bedrock.md`. |
| 125 | +- [ ] `docs/README.md` — index link if a new doc was added. |
| 126 | +- [ ] `CHANGELOG.md` — `[Unreleased]` entry stating what IS and IS NOT supported |
| 127 | + (regions, caching, GovCloud, agentic/discovery). |
| 128 | + |
| 129 | +### G. Tests |
| 130 | +- [ ] `tests/unit/test_bedrock_openai_responses.py` (mantle) or the relevant |
| 131 | + client test — routing + region resolution per model. |
| 132 | +- [ ] `tests/unit/config/test_validation.py` — reject cases for unsupported |
| 133 | + feature combos (advanced+GPT-5.x, discovery+GPT-5.x). |
| 134 | +- [ ] `tests/unit/discovery/test_classes_discovery.py` — reject case. |
| 135 | +- [ ] Any pricing/limits test that enumerates known models. |
| 136 | + |
| 137 | +--- |
| 138 | + |
| 139 | +## Step 3 — Validate |
| 140 | + |
| 141 | +```bash |
| 142 | +cd lib/idp_common_pkg && make test-unit |
| 143 | +make lint && make typecheck |
| 144 | +python3 -c "import yaml,sys; [yaml.safe_load(open(f)) for f in \ |
| 145 | + ['config_library/pricing.yaml','config_library/model_config_limits.yaml']]" |
| 146 | +# cfn-lint the templates (enum-only changes are low risk but lint anyway) |
| 147 | +``` |
| 148 | + |
| 149 | +Live smoke (per the e2e memory convention): create a **NEW named config |
| 150 | +version** pointing a service at the new model — **never** swap `Config#default`. |
| 151 | +Run one document in a region where the model is available; confirm routing and |
| 152 | +metering. Watch the model's Lambda log group under the stack-name prefix (use |
| 153 | +`AWS_PROFILE=default`). |
| 154 | + |
| 155 | +--- |
| 156 | + |
| 157 | +## Common traps |
| 158 | + |
| 159 | +- **Multiple model IDs from one "launch"** — check for variant suffixes. |
| 160 | +- **Enum duplication** in `patterns/unified/template.yaml` (often 9 sites). |
| 161 | +- **Vendored chat copy** drift (`chat_stream_processor/vendored/`). |
| 162 | +- **Regex limit patterns** already matching a new variant (verify, don't blindly |
| 163 | + add a duplicate pattern). |
| 164 | +- **Region drift on siblings** — AWS adds regions to existing models over time; |
| 165 | + the code snapshot may be stale. Refresh sibling `_MODEL_REGIONS` if you notice. |
| 166 | +- **Caching claims** — only add to `CACHEPOINT_SUPPORTED_MODELS` if the model |
| 167 | + card confirms it AND the invocation path actually emits cache points. Note the |
| 168 | + mechanism differs by model: Bedrock Converse uses `cachePoint` blocks; |
| 169 | + bedrock-mantle OpenAI models split into **automatic** (GPT-5.4/5.5: any prefix |
| 170 | + > 1024 tokens, no request change) vs **explicit** (GPT-5.6: request needs |
| 171 | + `prompt_cache_options: {mode: explicit}` + `prompt_cache_key` + |
| 172 | + `prompt_cache_breakpoint`). `CACHEPOINT_SUPPORTED_MODELS` is Converse-path only |
| 173 | + — mantle models handle caching in `openai_responses.py`, not that list. |
| 174 | +- **Pricing** — never guess; `TODO(pricing)` + flag to the user if unresolved. |
| 175 | +- **GovCloud** — check per-variant; don't assume the family's GovCloud status. |
0 commit comments