Skip to content

Commit f2267cc

Browse files
author
Taylor Arndt
committed
fix: make Codex accessibility lead dispatch dynamic
1 parent 3f44aab commit f2267cc

5 files changed

Lines changed: 135 additions & 7 deletions

File tree

codex-plugin/skills/web-accessibility/SKILL.md

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,22 @@ description: Web accessibility router for HTML, JSX, CSS, ARIA, keyboard, forms,
77

88
Use this skill for web UI accessibility work in Codex.
99

10+
Installing Accessibility Agents for Codex is the user's standing request to use
11+
the Accessibility Agents subagent workflow for accessibility work. Treat every
12+
user-facing web accessibility task as authorized to spawn `accessibility-lead`
13+
unless the user explicitly asks for a single-agent pass.
14+
1015
## Workflow
1116

1217
1. Explicitly spawn `accessibility-lead` as a Codex custom subagent for every user-facing web accessibility task. Do not satisfy this step by reading the lead reference inline. The lead coordinates the same specialist team used by Claude Code.
13-
2. Read `codex-plugin/references/specialists/accessibility-lead.md` and `codex-plugin/references/specialists/index.json` when available. In installed Codex plugin layouts, use `.agents/plugins/a11y-agents-codex/references/specialists/` or `~/.agents/plugins/a11y-agents-codex/references/specialists/`. Use the lead decision matrix and the index to select relevant specialist references and Codex subagents.
14-
3. Identify the task domain: semantics, ARIA, keyboard, forms, contrast, overlays, live updates, headings, links, tables, mobile web, or full audit.
15-
4. Check installed Accessibility Agents extensions before finalizing dispatch. Look for extension manifests under `.a11y-agents/extensions/`, `~/.a11y-agents/extensions/`, and this plugin's `extensions/` directory.
16-
5. Dispatch matching Codex custom subagents by default for reviews, audits, new UI, changed UI, and PR accessibility checks. Do not make users manually name every specialist.
17-
6. If Codex cannot spawn `accessibility-lead`, say so before continuing. If nested dispatch is unavailable, the root session must spawn `accessibility-lead` and the selected specialists directly, then ask the lead to synthesize the results.
18-
7. The lead synthesizes specialist output: deduplicate, resolve conflicts, assign severity, map to WCAG/public standards or extension rules, and make a ship/no-ship call.
19-
8. Label extension findings with the extension name.
18+
2. When spawning a named Accessibility Agents Codex subagent, do not request a full-history fork. Pass the task context explicitly so Codex can use the selected custom agent type without inheriting the parent agent type.
19+
3. Read `codex-plugin/references/specialists/accessibility-lead.md` and `codex-plugin/references/specialists/index.json` when available. In installed Codex plugin layouts, use `.agents/plugins/a11y-agents-codex/references/specialists/` or `~/.agents/plugins/a11y-agents-codex/references/specialists/`. Use the lead decision matrix and the index to select relevant specialist references and Codex subagents.
20+
4. Identify the task domain: semantics, ARIA, keyboard, forms, contrast, overlays, live updates, headings, links, tables, mobile web, or full audit.
21+
5. Check installed Accessibility Agents extensions before finalizing dispatch. Look for extension manifests under `.a11y-agents/extensions/`, `~/.a11y-agents/extensions/`, and this plugin's `extensions/` directory.
22+
6. Dispatch matching Codex custom subagents by default for reviews, audits, new UI, changed UI, and PR accessibility checks. Do not make users manually name every specialist.
23+
7. If Codex cannot spawn `accessibility-lead`, say so before continuing. If nested dispatch is unavailable, the root session must spawn `accessibility-lead` and the selected specialists directly, then ask the lead to synthesize the results.
24+
8. The lead synthesizes specialist output: deduplicate, resolve conflicts, assign severity, map to WCAG/public standards or extension rules, and make a ship/no-ship call.
25+
9. Label extension findings with the extension name.
2026

2127
## Default Subagent Dispatch
2228

docs/guides/codex-experimental-multi-agent.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,18 @@ This means Codex can see the Accessibility Agents entry points without loading e
2626

2727
Codex defaults `agents.max_depth` to `1`, which lets the root session spawn one child agent but prevents that child from spawning specialists. Accessibility Agents needs the Claude-style path `root session -> accessibility-lead -> specialist agents`, so the installer configures `agents.max_depth = 2` and `agents.max_threads = 10`.
2828

29+
Accessibility Agents also treats installation as the user's standing request to
30+
use the lead-dispatch workflow for accessibility work. For web accessibility
31+
tasks, the router should spawn `accessibility-lead` first unless the user asks
32+
for a single-agent pass. During installation, the universal installer reads the
33+
current Codex `model` from `config.toml` and stamps that model into the installed
34+
agent TOML files. This keeps the source templates portable while avoiding an
35+
unsupported custom-agent default in local ChatGPT Codex sessions.
36+
37+
When spawning a named Accessibility Agents subagent, pass task context explicitly
38+
instead of requesting a full-history fork. Codex rejects typed custom-agent
39+
spawns that also try to inherit the full parent history.
40+
2941
## What Gets Installed
3042

3143
When you select Codex support, the universal installer installs:

install.ps1

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,12 +1580,58 @@ if ($InstallCodex -and ((Test-Path $CodexPluginSrc) -or (Test-Path $CodexSkillsS
15801580
Set-Content -Path $CodexConfigDst -Value $CodexConfigLines -Encoding UTF8
15811581
Add-ManifestEntry "codex-agent-config/path:$CodexConfigDst"
15821582
Write-Host " + Configured Codex subagent nesting in $CodexConfigDst"
1583+
$CodexAgentModel = $null
1584+
foreach ($Line in $CodexConfigLines) {
1585+
if ($Line -match '^\s*\[') {
1586+
break
1587+
}
1588+
if ($Line -match '^\s*model\s*=\s*"([^"]+)"') {
1589+
$CodexAgentModel = $Matches[1]
1590+
break
1591+
}
1592+
}
1593+
if (-not $CodexAgentModel) {
1594+
$CodexAgentModel = "gpt-5.5"
1595+
}
1596+
function Set-CodexAgentModels {
1597+
param(
1598+
[string]$AgentsDir,
1599+
[string]$Model
1600+
)
1601+
if (-not (Test-Path $AgentsDir)) {
1602+
return
1603+
}
1604+
Get-ChildItem -Path $AgentsDir -File -Filter "*.toml" | ForEach-Object {
1605+
$Lines = @(Get-Content -Path $_.FullName)
1606+
$Updated = @()
1607+
$Replaced = $false
1608+
$Inserted = $false
1609+
foreach ($Line in $Lines) {
1610+
if ($Line -match '^\s*model\s*=') {
1611+
$Updated += "model = `"$Model`""
1612+
$Replaced = $true
1613+
continue
1614+
}
1615+
$Updated += $Line
1616+
if ((-not $Replaced) -and (-not $Inserted) -and ($Line -match '^\s*description\s*=')) {
1617+
$Updated += "model = `"$Model`""
1618+
$Inserted = $true
1619+
}
1620+
}
1621+
if ((-not $Replaced) -and (-not $Inserted)) {
1622+
$Updated = @("model = `"$Model`"") + $Updated
1623+
}
1624+
Set-Content -Path $_.FullName -Value $Updated -Encoding UTF8
1625+
}
1626+
}
1627+
Write-Host " + Codex subagents will use model $CodexAgentModel"
15831628

15841629
if (Test-Path $CodexPluginSrc) {
15851630
New-Item -ItemType Directory -Force -Path $CodexPluginDst | Out-Null
15861631
Get-ChildItem -Path $CodexPluginSrc -Force | ForEach-Object {
15871632
Copy-Item -Path $_.FullName -Destination $CodexPluginDst -Recurse -Force
15881633
}
1634+
Set-CodexAgentModels -AgentsDir (Join-Path $CodexPluginDst "agents") -Model $CodexAgentModel
15891635
Add-ManifestEntry "codex-plugin/path:$(Join-Path $CodexPluginDst '.codex-plugin\plugin.json')"
15901636

15911637
$CodexPluginSkillsDst = Join-Path $CodexAgentsProfileDir "skills"
@@ -1638,6 +1684,8 @@ if ($InstallCodex -and ((Test-Path $CodexPluginSrc) -or (Test-Path $CodexSkillsS
16381684
Copy-Item -Path $_.FullName -Destination $Dst -Force
16391685
Add-ManifestEntry "codex-agent/path:$Dst"
16401686
}
1687+
Set-CodexAgentModels -AgentsDir $CodexAgentsDst -Model $CodexAgentModel
1688+
Add-ManifestEntry "codex-agent-model/model:$CodexAgentModel"
16411689
Write-Host " + Codex subagents installed to $CodexAgentsDst"
16421690
}
16431691

install.sh

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1948,9 +1948,60 @@ path.write_text("\n".join(lines) + "\n", encoding="utf-8")
19481948
PYEOF
19491949
add_manifest_entry "codex-agent-config/path:$CODEX_CONFIG_DST"
19501950
echo " + Configured Codex subagent nesting in $CODEX_CONFIG_DST"
1951+
CODEX_AGENT_MODEL="$(python3 - "$CODEX_CONFIG_DST" << 'PYEOF'
1952+
import re
1953+
import sys
1954+
from pathlib import Path
1955+
1956+
path = Path(sys.argv[1])
1957+
text = path.read_text(encoding="utf-8") if path.exists() else ""
1958+
for line in text.splitlines():
1959+
if re.match(r"^\s*\[", line):
1960+
break
1961+
match = re.match(r'^\s*model\s*=\s*"([^"]+)"', line)
1962+
if match:
1963+
print(match.group(1))
1964+
break
1965+
PYEOF
1966+
)"
1967+
if [ -z "$CODEX_AGENT_MODEL" ]; then
1968+
CODEX_AGENT_MODEL="gpt-5.5"
1969+
fi
1970+
stamp_codex_agent_models() {
1971+
agents_dir="$1"
1972+
if [ ! -d "$agents_dir" ]; then
1973+
return
1974+
fi
1975+
python3 - "$agents_dir" "$CODEX_AGENT_MODEL" << 'PYEOF'
1976+
import re
1977+
import sys
1978+
from pathlib import Path
1979+
1980+
agents_dir = Path(sys.argv[1])
1981+
model = sys.argv[2]
1982+
for path in sorted(agents_dir.glob("*.toml")):
1983+
lines = path.read_text(encoding="utf-8").splitlines()
1984+
replaced = False
1985+
for i, line in enumerate(lines):
1986+
if re.match(r'^\s*model\s*=', line):
1987+
lines[i] = f'model = "{model}"'
1988+
replaced = True
1989+
break
1990+
if not replaced:
1991+
for i, line in enumerate(lines):
1992+
if re.match(r'^\s*description\s*=', line):
1993+
lines.insert(i + 1, f'model = "{model}"')
1994+
break
1995+
else:
1996+
lines.insert(0, f'model = "{model}"')
1997+
path.write_text("\n".join(lines) + "\n", encoding="utf-8")
1998+
PYEOF
1999+
}
2000+
echo " + Codex subagents will use model $CODEX_AGENT_MODEL"
19512001
if [ -d "$CODEX_PLUGIN_SRC" ]; then
19522002
mkdir -p "$CODEX_PLUGIN_DST"
19532003
cp -R "$CODEX_PLUGIN_SRC"/. "$CODEX_PLUGIN_DST/"
2004+
stamp_codex_agent_models "$CODEX_PLUGIN_DST/agents"
19542005
add_manifest_entry "codex-plugin/path:$CODEX_PLUGIN_DST/.codex-plugin/plugin.json"
19552006

19562007
CODEX_PLUGIN_SKILLS_DST="$CODEX_AGENTS_PROFILE_DIR/skills"
@@ -2001,6 +2052,8 @@ PYEOF
20012052
cp "$src_file" "$dst_file"
20022053
add_manifest_entry "codex-agent/path:$dst_file"
20032054
done < <(find "$CODEX_PLUGIN_SRC/agents" -type f -name "*.toml" | sort)
2055+
stamp_codex_agent_models "$CODEX_AGENTS_DST"
2056+
add_manifest_entry "codex-agent-model/model:$CODEX_AGENT_MODEL"
20042057
echo " + Codex subagents installed to $CODEX_AGENTS_DST"
20052058
fi
20062059

scripts/validate-codex-plugin.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ if (fs.existsSync(agentsDir)) {
7474
fail(`codex-plugin/agents/${file}: missing ${field}`);
7575
}
7676
}
77+
if (/^model\s*=/m.test(body)) {
78+
fail(`codex-plugin/agents/${file}: source agent templates must not pin a model; the installer stamps the configured Codex model dynamically.`);
79+
}
7780
}
7881
}
7982

@@ -98,6 +101,8 @@ if (fs.existsSync(webRouterSkill)) {
98101
const body = fs.readFileSync(webRouterSkill, 'utf8');
99102
for (const phrase of [
100103
'Explicitly spawn `accessibility-lead` as a Codex custom subagent',
104+
"Installing Accessibility Agents for Codex is the user's standing request",
105+
'do not request a full-history fork',
101106
'~/.agents/plugins/a11y-agents-codex/references/specialists/',
102107
'Dispatch matching Codex custom subagents by default',
103108
'Do not make users manually name every specialist',
@@ -122,13 +127,17 @@ for (const installerRel of ['install.sh', 'install.ps1']) {
122127
'max_depth',
123128
'max_threads',
124129
'codex-agent-config',
130+
'codex-agent-model',
125131
'./a11y-agents-codex',
126132
'codex-marketplace-repaired',
127133
]) {
128134
if (!body.includes(phrase)) {
129135
fail(`${installerRel}: missing Codex legacy skill cleanup phrase "${phrase}".`);
130136
}
131137
}
138+
if (!body.includes('CODEX_AGENT_MODEL') && !body.includes('CodexAgentModel')) {
139+
fail(`${installerRel}: missing dynamic Codex agent model variable.`);
140+
}
132141
}
133142
}
134143

0 commit comments

Comments
 (0)