Skip to content

Commit bd6f8a8

Browse files
CopilotSteake
andcommitted
repo-architect: avoid unavailable model selection after catalog lookup
Co-authored-by: Steake <530040+Steake@users.noreply.github.com>
1 parent a321856 commit bd6f8a8

File tree

3 files changed

+49
-20
lines changed

3 files changed

+49
-20
lines changed

.github/workflows/repo-architect.yml

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ jobs:
9393
]
9494
secondary = "google/gemini-3-pro"
9595
available = set()
96+
catalog_ok = False
9697
try:
9798
req = urllib.request.Request(
9899
"https://models.github.ai/catalog/models",
@@ -106,6 +107,7 @@ jobs:
106107
payload = json.loads(resp.read().decode("utf-8"))
107108
models = payload.get("data", payload) if isinstance(payload, dict) else payload
108109
if isinstance(models, list):
110+
catalog_ok = True
109111
for item in models:
110112
if isinstance(item, dict):
111113
model_id = item.get("id") or item.get("name") or item.get("model")
@@ -120,20 +122,30 @@ jobs:
120122
return candidate
121123
return None
122124
123-
if available:
124-
preferred = first_available(order)
125-
if preferred is None:
126-
preferred = secondary if secondary in available else order[0]
125+
def deterministic_available(exclude=None):
126+
candidates = sorted(m for m in available if m != exclude)
127+
return candidates[0] if candidates else None
128+
129+
if catalog_ok and available:
130+
preferred = (
131+
first_available(order)
132+
or (secondary if secondary in available else None)
133+
or deterministic_available()
134+
)
127135
else:
128136
preferred = order[0]
129137
130-
if secondary in available and secondary != preferred:
131-
fallback = secondary
138+
if catalog_ok and available:
139+
if secondary in available and secondary != preferred:
140+
fallback = secondary
141+
else:
142+
fallback = (
143+
first_available([c for c in order if c != preferred])
144+
or deterministic_available(exclude=preferred)
145+
or preferred
146+
)
132147
else:
133-
fallback = (
134-
first_available([c for c in order if c != preferred])
135-
or (secondary if secondary in available else order[-1])
136-
)
148+
fallback = secondary
137149
138150
if not isinstance(preferred, str) or not preferred:
139151
preferred = order[0]

repo_architect.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,6 +1498,7 @@ def workflow_yaml(secret_env_names: Sequence[str], cron: str, github_model: Opti
14981498
]
14991499
secondary = "google/gemini-3-pro"
15001500
available = set()
1501+
catalog_ok = False
15011502
try:
15021503
req = urllib.request.Request(
15031504
"https://models.github.ai/catalog/models",
@@ -1511,6 +1512,7 @@ def workflow_yaml(secret_env_names: Sequence[str], cron: str, github_model: Opti
15111512
payload = json.loads(resp.read().decode("utf-8"))
15121513
models = payload.get("data", payload) if isinstance(payload, dict) else payload
15131514
if isinstance(models, list):
1515+
catalog_ok = True
15141516
for item in models:
15151517
if isinstance(item, dict):
15161518
model_id = item.get("id") or item.get("name") or item.get("model")
@@ -1525,20 +1527,30 @@ def first_available(candidates):
15251527
return candidate
15261528
return None
15271529
1528-
if available:
1529-
preferred = first_available(order)
1530-
if preferred is None:
1531-
preferred = secondary if secondary in available else order[0]
1530+
def deterministic_available(exclude=None):
1531+
candidates = sorted(m for m in available if m != exclude)
1532+
return candidates[0] if candidates else None
1533+
1534+
if catalog_ok and available:
1535+
preferred = (
1536+
first_available(order)
1537+
or (secondary if secondary in available else None)
1538+
or deterministic_available()
1539+
)
15321540
else:
15331541
preferred = order[0]
15341542
1535-
if secondary in available and secondary != preferred:
1536-
fallback = secondary
1543+
if catalog_ok and available:
1544+
if secondary in available and secondary != preferred:
1545+
fallback = secondary
1546+
else:
1547+
fallback = (
1548+
first_available([c for c in order if c != preferred])
1549+
or deterministic_available(exclude=preferred)
1550+
or preferred
1551+
)
15371552
else:
1538-
fallback = (
1539-
first_available([c for c in order if c != preferred])
1540-
or (secondary if secondary in available else order[-1])
1541-
)
1553+
fallback = secondary
15421554
15431555
if not isinstance(preferred, str) or not preferred:
15441556
preferred = order[0]

tests/test_repo_architect.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,10 +299,15 @@ def test_workflow_yaml_resolves_models_via_catalog_and_keeps_blank_override_logi
299299
workflow = ra.workflow_yaml([], "17 * * * *", None)
300300
self.assertIn("Resolve GitHub Models configuration", workflow)
301301
self.assertIn("https://models.github.ai/catalog/models", workflow)
302+
self.assertIn("catalog_ok = False", workflow)
302303
self.assertIn('"anthropic/claude-sonnet-4.6"', workflow)
303304
self.assertIn('"anthropic/claude-sonnet-4.5"', workflow)
304305
self.assertIn('"openai/gpt-4.1"', workflow)
305306
self.assertIn('secondary = "google/gemini-3-pro"', workflow)
307+
self.assertIn("def deterministic_available(exclude=None):", workflow)
308+
self.assertIn("or deterministic_available()", workflow)
309+
self.assertIn("or deterministic_available(exclude=preferred)", workflow)
310+
self.assertIn("or preferred", workflow)
306311
self.assertIn("REPO_ARCHITECT_PREFERRED_MODEL={preferred}", workflow)
307312
self.assertIn("REPO_ARCHITECT_FALLBACK_MODEL={fallback}", workflow)
308313
self.assertIn('if [ -n "$MODEL" ]; then EXTRA_ARGS="$EXTRA_ARGS --github-model $MODEL"; fi', workflow)

0 commit comments

Comments
 (0)