code-yeongyu / code-yeongyu/lazycodex
Document and guard against empty optional fields in Codex spawn_agent calls
- Dominant language
- TypeScript
- Stars
- 3.5k
- Forks
- 216
- PR merge metrics
- No merged PRs in 30d
Description
## Summary
LazyCodex's Codex-facing skill/rule guidance depends heavily on native `spawn_agent`, but current Codex tool parsing rejects common empty optional-field shapes. Until upstream normalizes those fields, LazyCodex should make its generated guidance and any spawn guardrails explicitly tell agents to omit unused optional keys, especially `items: []`, `message: \"\"`, `model: \"\"`, `reasoning_effort: \"\"`, and `service_tier: \"\"`.
Upstream issue filed: https://github.com/openai/codex/issues/37037
## Environment
- Codex CLI on PATH: `codex-cli 0.146.0`
- Runtime: Codex Desktop / ChatGPT-auth session exposing `multi_agent_v1.spawn_agent`
- OS: macOS 26.5.2, Darwin 25.5.0 arm64
- Node: `v26.6.0`
- LazyCodex source checked: `code-yeongyu/lazycodex` `main` at `fb48ddc4bc8be02a0cfe0a509a30cf3543edf72a`
- Upstream Codex source checked: `openai/codex` `main` at `1fe6be9719ac4a18ad08f8341b89f9a0f386105e`
## Repository Decision
- Target repository: `code-yeongyu/lazycodex`
- Why this belongs here: the root parser bug is upstream Codex, but LazyCodex ships the skills/rules that repeatedly instruct agents to dispatch subagents through `multi_agent_v1.spawn_agent` / flat `spawn_agent`. A downstream compatibility issue is useful so LazyCodex can harden its generated instructions and guardrails while waiting for upstream.
- LazyCodex evidence:
- `plugins/omo/skills/visual-qa/SKILL.md:6-22` maps OpenCode examples to Codex `multi_agent_v1.spawn_agent` calls.
- `plugins/omo/components/rules/bundled-rules/hephaestus/gpt-5.5.md:42-44` tells agents to spawn subagents via `multi_agent_v1.spawn_agent({"message":"...","fork_context":false})`.
- `plugins/omo/skills/ulw-loop/SKILL.md:56-66` already gives a good V2 warning not to set `agent_type` / `model` / `reasoning_effort`; V1 guidance could use similarly explicit "omit empty optional keys" wording.
- Upstream Codex evidence:
- `codex-rs/core/src/tools/handlers/multi_agents_common.rs:137-144` rejects `Some(message), Some(items)` without treating empty unused values as absent.
- `codex-rs/protocol/src/openai_models.rs:119-133` rejects empty `reasoning_effort` during deserialization.
## Reproduction
In a Codex session exposing `multi_agent_v1.spawn_agent`, attempts with serialized empty optional fields failed as follows:
1. `message: \"...task...\"` plus `items: []` returned:
```text
Provide either message or items, but not both
```
2. `items: [{ type: \"text\", text: \"...task...\" }]` plus `message: \"\"` returned:
```text
Provide either message or items, but not both
```
3. `reasoning_effort: \"\"` returned:
```text
failed to parse function arguments: reasoning_effort must not be empty at line 1 column 219
```
## Expected Behavior
LazyCodex-generated instructions should make the valid payload shape unambiguous for both tool surfaces:
- For V1: pass only `message`, `agent_type` when needed, and `fork_context`; omit `items`, `model`, `reasoning_effort`, and `service_tier` unless they are intentionally non-empty.
- For V2: pass only `task_name`, `message`, and `fork_turns` unless the active schema explicitly exposes additional non-empty fields.
- Never emit empty placeholder values for optional spawn fields.
## Actual Behavior
The current shipped guidance mostly shows minimal calls, but it does not consistently warn that empty optional fields are actively dangerous on the native tool surface. In a real visual QA workflow, this caused subagent dispatch to fail and forced the parent agent to continue single-threaded.
## Evidence
- Live Codex Desktop tool-call failures on 2026-08-05.
- Source-backed upstream root cause captured in https://github.com/openai/codex/issues/37037.
- LazyCodex source references above show the downstream surface area likely affected by this parser sharp edge.
## Root Cause
Upstream Codex currently treats empty optional values as supplied, while LazyCodex guidance assumes agents can safely follow the model-visible shape and omit optional fields. When a caller/tool wrapper serializes empty defaults, the upstream parser rejects the call before a subagent is spawned.
## Proposed Fix
- Update Codex subagent compatibility sections in shared LazyCodex skill/rule templates to explicitly say: omit optional keys entirely when unset; do not pass empty `items`, empty `message`, or empty override strings.
- Add a small regression/fixture in the skill sync or rule generation tests to preserve this warning in generated skills that mention `spawn_agent`.
- If LazyCodex has any hook or guard that inspects tool-call payloads before execution, consider warning when `spawn_agent` includes `items: []`, `message: \"\"`, or empty override strings.
## Verification Plan
- Regenerate/sync skills and confirm all shared Codex harness compatibility blocks contain the warning.
- Run LazyCodex skill/rule tests touching `sync-skills`, `ulw-loop`, `visual-qa`, and Hephaestus bundled rules.
- Manually validate a V1 spawn call with only non-empty keys in a Codex session.
---
This issue or PR was generated by LazyCodex.
Tag: lazycodex-generated
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with plugins/omo/skills/visual-qa/SKILL.md, plugins/omo/skills/ulw-loop/SKILL.md, and plugins/omo/components/rules/bundled-rules/hephaestus/gpt-5.5.md, then inspect the skill-sync or rule-generation tests. Run the sync-skills, ulw-loop, visual-qa, and Hephaestus rule tests; done means generated Codex guidance consistently says to omit unset optional spawn_agent keys and verifies valid V1 payloads.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- ai, tooling
- Issue type
- Documentation
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 75/100