Skip to content

feat(codex): Add support for codex /fast mode#393

Open
paulcalcraft wants to merge 1 commit intotiann:mainfrom
paulcalcraft:feat/support-codex-fast-service-tier
Open

feat(codex): Add support for codex /fast mode#393
paulcalcraft wants to merge 1 commit intotiann:mainfrom
paulcalcraft:feat/support-codex-fast-service-tier

Conversation

@paulcalcraft
Copy link
Copy Markdown

Codex has a fast inference mode that uses tokens at a higher rate. I've added support for that when creating a new session. I also added the full set of reasoning levels for codex to the dropdown.

GPT 5.4 xhigh in codex wrote the code, I've tested that it doesn't break the flow and it seems to work, but hard to know for certain that the fast mode is applied correctly (it seems fast at least!). Despite docs saying that serviceTier should be 'priority' for fast mode, if you pass that param, you actually get an error saying that it should be 'fast', so this patch uses 'fast'.

@paulcalcraft paulcalcraft changed the title Add support for codex /fast mode feat: Add support for codex /fast mode Apr 4, 2026
@paulcalcraft paulcalcraft changed the title feat: Add support for codex /fast mode feat(codex): Add support for codex /fast mode Apr 4, 2026
Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Findings

  • [Major] --service-tier is parsed but never reaches terminal-started Codex sessions. The new branch in cli/src/commands/codex.ts:81 stores the value in HAPI state, but local launches only forward session.codexArgs to the native Codex CLI (cli/src/codex/codexLocalLauncher.ts:18-49), so hapi codex --service-tier fast silently runs at the default tier.
  • [Major] Fast mode is not persisted for inactive-session resume. Initial spawn now threads serviceTier through hub/src/sync/syncEngine.ts:318-337, but resume still hardcodes undefined for both reasoning effort and service tier in hub/src/sync/syncEngine.ts:404-410, and the session schema still stores only model/effort/collaborationMode (shared/src/schemas.ts:161-180). A resumed Codex session will therefore drop back to the default tier.

Summary
Review mode: initial. 2 issues found in the new Codex fast-mode plumbing: terminal-started sessions ignore the new CLI flag, and resumed inactive Codex sessions lose the selected service tier.

Testing
Not run (bun is not installed in this environment).

HAPI Bot

throw new Error('Missing --model-reasoning-effort value')
}
options.modelReasoningEffort = parseReasoningEffort(effort)
} else if (arg === '--service-tier') {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MAJOR] --service-tier is swallowed in local/terminal mode.

This new branch parses the flag into options.serviceTier, but it never adds the original CLI args back into unknownArgs. The local launcher only forwards session.codexArgs to the native codex process (cli/src/codex/codexLocalLauncher.ts:18-49), so hapi codex --service-tier fast will silently start at the default tier.

Suggested fix:

} else if (arg === '--service-tier') {
    const serviceTier = commandArgs[++i]
    if (!serviceTier) {
        throw new Error('Missing --service-tier value')
    }
    options.serviceTier = parseServiceTier(serviceTier)
    unknownArgs.push('--service-tier', serviceTier)
}

agent: 'claude' | 'codex' | 'cursor' | 'gemini' | 'opencode' = 'claude',
model?: string,
modelReasoningEffort?: string,
serviceTier?: string,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MAJOR] Fast mode is wired for initial spawn only; inactive-session resume still drops it.

spawnSession() now accepts serviceTier, but resumeSession() still calls rpcGateway.spawnSession() with undefined for both modelReasoningEffort and serviceTier. Since the persisted session shape also lacks fields for those values (shared/src/schemas.ts:161-180), a resumed Codex session will come back on the default tier instead of the tier selected at creation time.

Suggested fix:

const spawnResult = await this.rpcGateway.spawnSession(
    targetMachine.id,
    metadata.path,
    flavor,
    session.model ?? undefined,
    session.modelReasoningEffort ?? undefined,
    session.serviceTier ?? undefined,
    undefined,
    undefined,
    resumeToken,
    session.effort ?? undefined
)

Persist modelReasoningEffort/serviceTier alongside the existing session model settings before replaying them here.

Copy link
Copy Markdown
Collaborator

@hqhq1025 hqhq1025 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The feature implementation is thorough — the web UI → hub → CLI → Codex data flow for the primary (remote) path is complete and correct. Good i18n coverage and test additions.

However, there's a critical bug that breaks session resume:

Critical: Positional argument misalignment in syncEngine.resumeSession

The PR inserts serviceTier as a new positional parameter in rpcGateway.spawnSession() (between modelReasoningEffort and yolo), but syncEngine.resumeSession() (line ~402) calls spawnSession() with positional args and is not updated.

After this PR, the resume call passes:

  • resumeTokenworktreeName (wrong!)
  • session.effortresumeSessionId (wrong!)
  • effort → undefined (lost!)

TypeScript won't catch this because all misaligned params are string?. The result: all inactive session resumes silently fail — they create a new session instead of resuming.

Fix: add undefined for serviceTier at position 6 in the resume call. Or better yet, refactor spawnSession to accept an options object instead of 11 positional parameters — this class of bug will recur every time a parameter is added.

Other issues

Local mode ignores --service-tier: commands/codex.ts parses the flag but doesn't forward it to the Codex child process args in local mode. Running hapi codex --service-tier fast locally does nothing. Consider at minimum logging a warning.

serviceTier not persisted in session schema: SessionSchema doesn't include serviceTier, so even after fixing the resume args, a resumed session loses the fast mode selection. (modelReasoningEffort has the same issue, but fast mode costs 2x usage so silent loss has higher impact.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants