feat(codex): expose personality controls#1009
Conversation
There was a problem hiding this comment.
Findings
-
[Major] Restored personality is dropped before Codex sees it —
runCodexnow seedscurrentPersonalityfromsessionInfo.personality, but the CLI API mapper still returns only throughcollaborationMode, so the parsed hub field is discarded before this added line uses it. Resuming an existing Codex session therefore starts with the default personality even when the hub session hasfriendly/pragmatic/none. Evidence:cli/src/codex/runCodex.ts:98, related mapper contextcli/src/api/api.ts:83andcli/src/api/api.ts:133.
Suggested fix:return { ..., collaborationMode: raw.collaborationMode, personality: raw.personality }
-
[Major] Keepalive personality updates are not broadcast to web clients — this branch mutates
session.personality, but thesession-updatedpatch emitted below still stops atcollaborationMode. Since/personality ...is handled locally and only pushes keepalive, the selector stays stale until a full refetch. Evidence:hub/src/sync/sessionCache.ts:253and omitted patch field athub/src/sync/sessionCache.ts:283.
Suggested fix:data: { active: true, activeAt: session.activeAt, thinking: session.thinking, permissionMode: session.permissionMode, model: session.model, modelReasoningEffort: session.modelReasoningEffort, effort: session.effort, serviceTier: session.serviceTier, collaborationMode: session.collaborationMode, personality: session.personality } satisfies SessionPatch
Questions
- None.
Summary
- Review mode: initial
- Two runtime gaps found: resume drops personality before Codex receives it, and keepalive broadcasts omit personality so web state can become stale.
Testing
- Not run (automation):
bun typecheckfailed becausebunis not on PATH in this environment.git diff --checkpassed.
HAPI Bot
There was a problem hiding this comment.
Findings
- [Minor] Personality selector can render stale state — the memoized overlay now reads
personalityandonPersonalityChange, but the dependency list was not updated. After changing personality, the session refetch/SSE can updateprops.session.personalitywhile the open menu keeps showing the old selected option because the overlay memo does not recompute. Evidence:web/src/components/AssistantChat/HappyComposer.tsx:923.
Suggested fix:handleServiceTierChange, handleSuggestionSelect, personality, onPersonalityChange, t
Questions
- None.
Summary
- Review mode: follow-up after new commits
- One minor UI state issue found in the new personality menu. The two previous bot findings appear addressed in the follow-up diff.
Testing
- Not run (automation):
bunis not available on PATH, so targeted tests andbun typecheckcould not run. git diff --checkpassed.
HAPI Bot
There was a problem hiding this comment.
Findings
- None.
Questions
- None.
Summary
- Review mode: follow-up after new commits
- No issues found in the current diff. The previous HAPI Bot memo-dependency finding is addressed in the follow-up commit. Residual risk: I could not run the Bun-based test/typecheck commands in this runner.
Testing
- Not run (automation):
bunis not available on PATH, sobun typecheckand targeted tests could not run.
HAPI Bot
There was a problem hiding this comment.
Findings
- [Major] Personality is dropped when an inactive Codex session is resumed from the web — the new
personalityconfig is accepted and cached for active sessions, butresumeSession()still seeds the runner only with model/effort/permission/service tier. After a user selectsfriendly/pragmatic, lets the session end, then resumes it remotely, the spawnedhapi codex resume ...process starts without that personality and the first resumed turn runs with the default. Evidence:hub/src/sync/syncEngine.ts:677adds personality to the config surface, but the resume spawn path still has no personality argument/payload.
Suggested fix:// hub/src/sync/syncEngine.ts await this.rpcGateway.spawnSession( targetMachine.id, directory, flavor, session.model ?? undefined, session.modelReasoningEffort ?? undefined, undefined, undefined, undefined, resumeToken, session.effort ?? undefined, preferredPermissionMode, session.serviceTier ?? undefined, session.personality ?? undefined ) // also thread `personality` through RpcGateway.spawnSession -> SpawnHappySession // -> cli SpawnSessionOptions -> buildCliArgs(`--personality`, value) -> codexCommand -> runCodex.
Questions
- None.
Summary
- Review mode: follow-up after new commits
- Found one resume-path regression in the current full diff. The live active-session RPC path has tests, but the remote resume/runner spawn path needs coverage for carrying personality into the new Codex process.
Testing
- Not run (automation): review only; did not execute PR code.
HAPI Bot
| effort?: string | null | ||
| serviceTier?: string | null | ||
| collaborationMode?: CodexCollaborationMode | ||
| personality?: Session['personality'] |
There was a problem hiding this comment.
[Major] Personality is dropped when an inactive Codex session is resumed from the web. This diff adds personality to the session config surface, but the resume spawn path still seeds the runner only with model/effort/permission/service tier. A user can select friendly/pragmatic, let the session end, and then resume it remotely; the spawned hapi codex resume ... process receives no personality, so the first resumed turn runs with the default.
Suggested fix:
// hub/src/sync/syncEngine.ts
await this.rpcGateway.spawnSession(
targetMachine.id,
directory,
flavor,
session.model ?? undefined,
session.modelReasoningEffort ?? undefined,
undefined,
undefined,
undefined,
resumeToken,
session.effort ?? undefined,
preferredPermissionMode,
session.serviceTier ?? undefined,
session.personality ?? undefined
)
// also thread `personality` through RpcGateway.spawnSession -> SpawnHappySession
// -> cli SpawnSessionOptions -> buildCliArgs(`--personality`, value) -> codexCommand -> runCodex.
Closes #1003
Summary
friendly,pragmatic, andnonepersonality state across shared schemas, keepalive, Hub config RPC, REST, and Web mutations/personalityquery/set/reset commandsnull/Default override instead of falling back to a persisted selectionWhy
Codex CLI exposes personality selection and app-server accepts it, but HAPI previously had no remote session state, composer control, slash command, or launcher wiring.
Validation
upstream/main: personality config/slash tests failed as expected and the shared catalog export was absentcodex-cli 0.144.1:model/listselectedgpt-5.5withsupportsPersonality: truepragmaticfriendlyand retained the same thread id4eebcec; selector memo refresh resolved in50e905fgit diff --check