feat: add Codex subagent format support#260
Conversation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
CodeAnt AI is reviewing your PR. Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
Sequence DiagramThis PR adds full Codex subagent support by mapping required agent fields and new optional subagent metadata into canonical form, then restoring them back to TOML. It also enforces schema validation for required fields and valid sandbox values. sequenceDiagram
participant Caller
participant FromCodex
participant Canonical
participant ToCodex
participant SchemaValidator
Caller->>FromCodex: Submit Codex agent TOML
FromCodex->>Canonical: Parse name description and developer instructions
FromCodex->>Canonical: Preserve nickname model sandbox mcp servers and skills config
Caller->>ToCodex: Convert canonical package to Codex agent TOML
ToCodex->>ToCodex: Emit required fields and optional subagent fields
ToCodex->>SchemaValidator: Validate generated agent structure
SchemaValidator-->>Caller: Return schema valid result
Generated by CodeAnt AI |
🤖 My Senior Dev — Analysis Complete👤 For @khaliqgant📁 Expert in View your contributor analytics → 📊 9 files reviewed • 1 high risk • 2 need attention 🚨 High Risk:
🚀 Open Interactive Review →The full interface unlocks features not available in GitHub:
💬 Chat here: 📖 View all 12 personas & slash commandsYou can interact with me by mentioning In PR comments or on any line of code:
Slash commands:
AI Personas (mention to get their perspective):
For the best experience, view this PR on myseniordev.com — includes AI chat, file annotations, and interactive reviews. |
Code Review: Codex Subagent Format SupportChecklist Verification (adding-new-ai-format skill)Verified all steps from the integration checklist:
All 13 checklist steps: COMPLETE ✅ TOML Parsing Correctness
Schema Completeness
Roundtrip Conversion FidelityExcellent roundtrip coverage:
Test Coverage90 tests, all passing:
Edge Cases Covered
TypeScript Type Safety
Notable Positives
VerdictThis is a thorough, well-structured integration. The converters follow established patterns (matches OpenCode/Droid reference implementations), roundtrip fidelity is well-tested, and all integration points across the monorepo are covered. No missing steps from the checklist. LGTM ✅ |
There was a problem hiding this comment.
7 issues found across 9 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/converters/src/__tests__/cross-converters/codex-agent-role.test.ts">
<violation number="1" location="packages/converters/src/__tests__/cross-converters/codex-agent-role.test.ts:213">
P2: The invalid `sandbox_mode` test is now vacuous because it still omits required fields, so it can pass without exercising the enum validation.</violation>
</file>
<file name="packages/converters/docs/README.md">
<violation number="1" location="packages/converters/docs/README.md:31">
P2: The Codex `rule` entry links to the skills docs instead of the AGENTS.md instructions guide.</violation>
</file>
<file name="packages/converters/docs/codex.md">
<violation number="1" location="packages/converters/docs/codex.md:8">
P2: The `.opencommands` slash-command location is inaccurate for Codex. Codex's reusable command mechanism is user-scoped prompts under `~/.codex/prompts/`, and this repo already treats slash commands as an AGENTS.md fallback, so these lines would direct users to files Codex never loads.</violation>
</file>
<file name="packages/converters/src/to-codex.ts">
<violation number="1" location="packages/converters/src/to-codex.ts:133">
P2: Use the canonical display title as the fallback for Codex `name`; `pkg.name` is the registry slug, not the agent's display name.</violation>
<violation number="2" location="packages/converters/src/to-codex.ts:144">
P2: This conditional can omit required `developer_instructions` when the package has no instructions section and an empty description, producing invalid Codex agent TOML.</violation>
</file>
<file name="packages/converters/schemas/codex-agent-role.schema.json">
<violation number="1" location="packages/converters/schemas/codex-agent-role.schema.json:40">
P2: `mcp_servers` entries need a required launcher (`command` or `url`), otherwise malformed MCP configs pass schema validation.</violation>
<violation number="2" location="packages/converters/schemas/codex-agent-role.schema.json:62">
P2: `skills.config` should be an array of tables, not a single object, or valid Codex agent files using `[[skills.config]]` will be rejected.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| for (const mode of validModes) { | ||
| const result = validateFormat('codex', { sandbox_mode: mode }, 'agent'); | ||
| const result = validateFormat('codex', { | ||
| name: 'test-agent', |
There was a problem hiding this comment.
P2: The invalid sandbox_mode test is now vacuous because it still omits required fields, so it can pass without exercising the enum validation.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/converters/src/__tests__/cross-converters/codex-agent-role.test.ts, line 213:
<comment>The invalid `sandbox_mode` test is now vacuous because it still omits required fields, so it can pass without exercising the enum validation.</comment>
<file context>
@@ -209,7 +209,12 @@ describe('Codex Agent Role — schema validation', () => {
for (const mode of validModes) {
- const result = validateFormat('codex', { sandbox_mode: mode }, 'agent');
+ const result = validateFormat('codex', {
+ name: 'test-agent',
+ description: 'Test agent',
+ developer_instructions: 'Do something.',
</file context>
| | | `agents-md` | Agent configurations in markdown | [docs.factory.ai](https://docs.factory.ai/cli/configuration/agents-md) | | ||
| | **Codex** | `skill` | Agent Skills SKILL.md format | [developers.openai.com](https://developers.openai.com/codex/skills) | | ||
| | | `agent` | Subagent TOML configs with MCP and skills | [developers.openai.com](https://developers.openai.com/codex/multi-agent/) | | ||
| | | `rule` | AGENTS.md project instructions | [developers.openai.com](https://developers.openai.com/codex/skills) | |
There was a problem hiding this comment.
P2: The Codex rule entry links to the skills docs instead of the AGENTS.md instructions guide.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/converters/docs/README.md, line 31:
<comment>The Codex `rule` entry links to the skills docs instead of the AGENTS.md instructions guide.</comment>
<file context>
@@ -26,6 +26,9 @@ Complete overview of all supported formats, their subtypes, and official documen
| | `agents-md` | Agent configurations in markdown | [docs.factory.ai](https://docs.factory.ai/cli/configuration/agents-md) |
+| **Codex** | `skill` | Agent Skills SKILL.md format | [developers.openai.com](https://developers.openai.com/codex/skills) |
+| | `agent` | Subagent TOML configs with MCP and skills | [developers.openai.com](https://developers.openai.com/codex/multi-agent/) |
+| | `rule` | AGENTS.md project instructions | [developers.openai.com](https://developers.openai.com/codex/skills) |
| **OpenCode** | `agent` | AI agents with mode, tools, and permissions | [opencode.ai](https://opencode.ai/docs/agents/) |
| | `slash-command` | User-triggered prompts with templates and placeholders | [opencode.ai](https://opencode.ai/docs/commands/) |
</file context>
| | | `rule` | AGENTS.md project instructions | [developers.openai.com](https://developers.openai.com/codex/skills) | | |
| | | `rule` | AGENTS.md project instructions | [developers.openai.com](https://developers.openai.com/codex/guides/agents-md/) | |
| - Agents/Subagents (project): `.codex/agents/*.toml` | ||
| - Agents/Subagents (global): `~/.codex/agents/*.toml` | ||
| - Rules/Instructions: `AGENTS.md` | ||
| - Slash Commands: `.opencommands/*.md` |
There was a problem hiding this comment.
P2: The .opencommands slash-command location is inaccurate for Codex. Codex's reusable command mechanism is user-scoped prompts under ~/.codex/prompts/, and this repo already treats slash commands as an AGENTS.md fallback, so these lines would direct users to files Codex never loads.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/converters/docs/codex.md, line 8:
<comment>The `.opencommands` slash-command location is inaccurate for Codex. Codex's reusable command mechanism is user-scoped prompts under `~/.codex/prompts/`, and this repo already treats slash commands as an AGENTS.md fallback, so these lines would direct users to files Codex never loads.</comment>
<file context>
@@ -0,0 +1,181 @@
+- Agents/Subagents (project): `.codex/agents/*.toml`
+- Agents/Subagents (global): `~/.codex/agents/*.toml`
+- Rules/Instructions: `AGENTS.md`
+- Slash Commands: `.opencommands/*.md`
+
+**Format:** TOML (agents), Markdown with YAML frontmatter (skills), plain Markdown (AGENTS.md)
</file context>
| : undefined; | ||
|
|
||
| // Required subagent fields: name, description, developer_instructions | ||
| const agentName = codexAgent?.name || pkg.name; |
There was a problem hiding this comment.
P2: Use the canonical display title as the fallback for Codex name; pkg.name is the registry slug, not the agent's display name.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/converters/src/to-codex.ts, line 133:
<comment>Use the canonical display title as the fallback for Codex `name`; `pkg.name` is the registry slug, not the agent's display name.</comment>
<file context>
@@ -129,6 +129,27 @@ function convertToAgentRoleToml(
: undefined;
+ // Required subagent fields: name, description, developer_instructions
+ const agentName = codexAgent?.name || pkg.name;
+ role['name'] = agentName;
+
</file context>
| } else if (pkg.description) { | ||
| // Fall back to package description | ||
| role['developer_instructions'] = pkg.description; |
There was a problem hiding this comment.
P2: This conditional can omit required developer_instructions when the package has no instructions section and an empty description, producing invalid Codex agent TOML.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/converters/src/to-codex.ts, line 144:
<comment>This conditional can omit required `developer_instructions` when the package has no instructions section and an empty description, producing invalid Codex agent TOML.</comment>
<file context>
@@ -129,6 +129,27 @@ function convertToAgentRoleToml(
+ // Map instructions section to developer_instructions
+ if (instructionsSection?.type === 'instructions') {
+ role['developer_instructions'] = instructionsSection.content;
+ } else if (pkg.description) {
+ // Fall back to package description
+ role['developer_instructions'] = pkg.description;
</file context>
| } else if (pkg.description) { | |
| // Fall back to package description | |
| role['developer_instructions'] = pkg.description; | |
| } else { | |
| // Fall back to package description so the required field is always present | |
| role['developer_instructions'] = pkg.description || ''; | |
| } |
| "enum": ["read-only", "workspace-write", "danger-full-access"], | ||
| "description": "Filesystem/network sandbox policy: read-only (default), workspace-write, or danger-full-access (no sandbox)" | ||
| }, | ||
| "mcp_servers": { |
There was a problem hiding this comment.
P2: mcp_servers entries need a required launcher (command or url), otherwise malformed MCP configs pass schema validation.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/converters/schemas/codex-agent-role.schema.json, line 40:
<comment>`mcp_servers` entries need a required launcher (`command` or `url`), otherwise malformed MCP configs pass schema validation.</comment>
<file context>
@@ -14,14 +32,40 @@
"enum": ["read-only", "workspace-write", "danger-full-access"],
"description": "Filesystem/network sandbox policy: read-only (default), workspace-write, or danger-full-access (no sandbox)"
+ },
+ "mcp_servers": {
+ "type": "object",
+ "description": "MCP server configurations available to this agent",
</file context>
| "config": { | ||
| "type": "object", | ||
| "description": "Skill-specific configuration key-value pairs", | ||
| "additionalProperties": true | ||
| } |
There was a problem hiding this comment.
P2: skills.config should be an array of tables, not a single object, or valid Codex agent files using [[skills.config]] will be rejected.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/converters/schemas/codex-agent-role.schema.json, line 62:
<comment>`skills.config` should be an array of tables, not a single object, or valid Codex agent files using `[[skills.config]]` will be rejected.</comment>
<file context>
@@ -14,14 +32,40 @@
+ "type": "object",
+ "description": "Skills configuration for this agent",
+ "properties": {
+ "config": {
+ "type": "object",
+ "description": "Skill-specific configuration key-value pairs",
</file context>
| "config": { | |
| "type": "object", | |
| "description": "Skill-specific configuration key-value pairs", | |
| "additionalProperties": true | |
| } | |
| "config": { | |
| "type": "array", | |
| "description": "List of skill-specific configuration tables", | |
| "items": { | |
| "type": "object", | |
| "additionalProperties": true | |
| } | |
| } |
| ...metadata, | ||
| id: metadata.id, | ||
| name: metadata.name || metadata.id, | ||
| name: role.name || metadata.name || metadata.id, |
There was a problem hiding this comment.
Suggestion: pkg.name is a package identifier used across CLI/registry paths and manifest validation, but this line overwrites it with the TOML name display field (which can contain spaces or non-slug text). That breaks the package-name contract and can cause invalid package names downstream. Keep pkg.name sourced from metadata (metadata.name/metadata.id) and store the subagent display name only in metadataSection.data.title / codexAgent.name. [logic error]
Severity Level: Major ⚠️
- ⚠️ Codex agent parser can emit non-slug canonical names.
- ⚠️ Name constraints mismatch registry/package validation rules.
- ⚠️ Future codex-agent CLI integration risks invalid package identifiers.| name: role.name || metadata.name || metadata.id, | |
| name: metadata.name || metadata.id, |
Steps of Reproduction ✅
1. Use the existing Codex agent-role parsing path exercised in
`packages/converters/src/__tests__/cross-converters/codex-agent-role.test.ts:332-339`,
where TOML includes `name = "My Custom Agent"` and calls `fromCodexAgentRole(...)`.
2. In `packages/converters/src/from-codex.ts:257-263`, `pkg.name` is assigned from
`role.name`, so the canonical package name becomes `"My Custom Agent"` (contains
spaces/casing).
3. Verify Codex schema allows display-style names
(`packages/converters/schemas/codex-agent-role.schema.json:9-12` defines `name` as
unrestricted string), so this input is realistic and valid for source TOML.
4. Compare with package-name constraints used elsewhere
(`packages/registry/src/validation/package-validator.ts:87-93` rejects spaces/uppercase in
package names): this shows the parsed canonical `pkg.name` can violate downstream
package-name expectations.Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** packages/converters/src/from-codex.ts
**Line:** 259:259
**Comment:**
*Logic Error: `pkg.name` is a package identifier used across CLI/registry paths and manifest validation, but this line overwrites it with the TOML `name` display field (which can contain spaces or non-slug text). That breaks the package-name contract and can cause invalid package names downstream. Keep `pkg.name` sourced from metadata (`metadata.name`/`metadata.id`) and store the subagent display name only in `metadataSection.data.title` / `codexAgent.name`.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.| if (instructionsSection?.type === 'instructions') { | ||
| role['developer_instructions'] = instructionsSection.content; | ||
| } else if (pkg.description) { | ||
| // Fall back to package description | ||
| role['developer_instructions'] = pkg.description; | ||
| } |
There was a problem hiding this comment.
Suggestion: developer_instructions is marked as required for Codex agent-role output, but this branch skips setting it when there is no instructions section and pkg.description is empty. That produces TOML missing a required field and can fail schema validation or downstream loading. Always write developer_instructions with a deterministic fallback value. [logic error]
Severity Level: Major ⚠️
- ❌ Codex agent TOML can fail schema validation.
- ⚠️ Registry codex downloads may emit invalid agent files.
- ⚠️ CLI codex conversion may write missing required fields.| if (instructionsSection?.type === 'instructions') { | |
| role['developer_instructions'] = instructionsSection.content; | |
| } else if (pkg.description) { | |
| // Fall back to package description | |
| role['developer_instructions'] = pkg.description; | |
| } | |
| if (instructionsSection?.type === 'instructions' && instructionsSection.content.trim()) { | |
| role['developer_instructions'] = instructionsSection.content; | |
| } else { | |
| // Ensure required field is always present | |
| role['developer_instructions'] = agentDescription; | |
| } |
Steps of Reproduction ✅
1. Trigger Codex conversion through real entrypoints that call `toCodex(canonicalPkg)`:
registry download conversion (`packages/registry/src/services/conversion.ts:127`, called
from `packages/registry/src/routes/download.ts:130`) or CLI conversion
(`packages/cli/src/commands/convert.ts:476`).
2. Provide an agent canonical package with no `instructions` section and empty description
sources (`pkg.description === ''`, metadata description empty). This is allowed by current
parsers that default description to empty string
(`packages/converters/src/from-codex.ts:43`, `:165`).
3. In `convertToAgentRoleToml`, execution reaches the branch at
`packages/converters/src/to-codex.ts:142-147`; because there is no instructions section
and `pkg.description` is empty, `role['developer_instructions']` is never assigned.
4. Validate the emitted TOML object with the existing validator path used in tests
(`validateFormat('codex', parsed, 'agent')` at
`packages/converters/src/__tests__/cross-converters/codex-agent-role.test.ts:203-204`):
schema requires `developer_instructions`
(`packages/converters/schemas/codex-agent-role.schema.json:7`), so output is invalid.Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** packages/converters/src/to-codex.ts
**Line:** 142:147
**Comment:**
*Logic Error: `developer_instructions` is marked as required for Codex agent-role output, but this branch skips setting it when there is no instructions section and `pkg.description` is empty. That produces TOML missing a required field and can fail schema validation or downstream loading. Always write `developer_instructions` with a deterministic fallback value.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.|
CodeAnt AI finished reviewing your PR. |
User description
Adds support for Codex subagents as an AI format in PRPM.
What
Codex (OpenAI) now supports subagents — specialized agents spawned in parallel for complex tasks. Custom agents are defined as TOML files under
.codex/agents/(project) or~/.codex/agents/(global).Changes
from-codex.ts/to-codex.ts— parse and generate TOML agent definitionscodex-agent-role.schema.json— validates subagent fields (name, description, developer_instructions, nickname_candidates, model, sandbox_mode, mcp_servers, skills.config)codex.md— format specification and conversion notesCodex Agent Format
Built-in agents:
default,worker,explorerTypecheck and all 920 tests pass.
CodeAnt-AI Description
Add Codex subagent support and preserve subagent fields through conversion
What Changed
Impact
✅ Clearer subagent validation errors✅ Preserve subagent metadata across import/export✅ Easier creation of Codex subagents with required fields enforced💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.