Repository navigation
fix(codex): only Stop ends a hooked Codex turn, and its question box is a wait - #71
Conversation
|
@Stener1 is attempting to deploy a commit to the seanbrydonio's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
@sean-brydon here's the Codex half of #7 on its own, rebased on main, as you asked. It doesn't depend on turn check; #7 now has your three turn-check points addressed too (laptop-only settings with keys only to the default gateway, capped and redacted text, no default model); details are in its description. |
d77be54 to
61eeb6b
Compare
…is a wait Codex's notify (agent-turn-complete) comes at the end of each assistant message, not the turn's, so a long turn read as finished after its first message. Once a session's hooks have said a prompt started (SawStart), the ledger ignores a notify finish and the box does not publish it; Stop ends the turn. A Codex without hooks still finishes with notify. integrations install codex adds PreToolUse and PostToolUse. PreToolUse for request_user_input* (Codex's question box) is agent.waiting with reason question, never with the questions; any other tool use is agent.started with signal tool. A hooks.json without PreToolUse reads as outdated, so an upgrade adds them. Only the async question box (request_user_input_async, marked question_box: "async") keeps a session waiting after its turn ends: it returns at once, so the turn can stop before anyone answers. A question answered within the turn (Plan mode's, or a structured driver's) ends with the turn. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@sean-brydon the changelog entry here conflicts each time a release goes out. Should I keep rebasing it until it merges, or would you rather leave it and sort out the docs conflict when you merge? |
Yeah just leave them I can fix. I might honestly remove that changelog for now also |
Split out of #7, as asked there, and rebased on main. It no longer depends on turn check.
Codex turns showing Done while Codex is still working: three Codex signals Shipyard was missing or misreading, found with a hook probe on Codex CLI 0.160.1.
notifyfires at the end of each assistant message, not the turn. In one turn:notifyat 13:58:09, aPreToolUseat 13:58:10, the real end (Stop) at 13:58:15. Both map toagent.finished, so a long Codex turn read as finished after its first message and stayed that way while Codex worked.PreToolUse/PostToolUsehooks;integrations install codexdidn't write them. The adapter already mappedPostToolUse.PreToolUsewithtool_name: "request_user_input_async"(orrequest_user_inputin Plan mode, which blocks).Change
PreToolUseandPostToolUse. An install without them reads as outdated indoctor, so an upgrade adds them. If Codex asks, trust the new hooks once with/hooks.PreToolUseforrequest_user_input*→agent.waitingwithreason: question(only that it asks, never the questions); any otherPreToolUse→agent.startedwithsignal: tool, likePostToolUse. The async question's ownPostToolUsecomes back at once, before any answer, so it says nothing.notifyfinish is dropped for a session whose hooks have been heard (SawStart, set by a hook's own prompt start), soStopalone ends a hooked turn; Codex without hooks still finishes onnotify. Such a notify isn't published either, so it doesn't push "finished" to the phone mid-turn.question_box: "async". A question answered within the turn (Plan mode's blocking one, or the new structured Codex driver's) ends with the turn, and so does a turn where the agent worked on after asking.Rebased on main after #81 (structured Codex driver) and v0.3.20
Rebasing showed a real interaction:
TestAStructuredCodexSessionIsDrivenThroughItsAppServerfailed with this branch, because the driver's question is answered inside the turn, yet the "ends on its question" rule kept the session waiting. The rule now applies only to the async question box. The test passes, andTestATurnThatEndsOnItsQuestionStillWaitsgained the blocking case.go test -race ./internal/box/ ./internal/integrations/...passes, exceptTestLongPromptsOverTheAPI, which hit a race in the test's own cleanup once (a global reset inlongprompt_test.goagainst tmux lookup) and passes 5 of 5 alone, on this branch and on main. The changelog entry moved to a new Unreleased section above v0.3.20.Tested
TestCodexNotifyEndsATurnOnlyWithoutHooks,TestACodexQuestionWaitsUntilItIsAnswered,TestATurnThatEndsOnItsQuestionStillWaits,TestCodexToolHooksAreAddedToAnOlderInstallOnce,TestCodexAsyncQuestionStaysAWait; extendedTestTranslate,TestTranslateNeverCopiesContent(questions, a command and a tool response marked secret),TestEveryAgentAdapterMapsItsTurn.go build ./...,go vet,go test -race ./internal/box/ ./internal/integrations/...all pass.notifyinstalled as usual: a 34-second turn running three commands stayed running and finished once, atStop; an async question showed as waiting the moment it was asked (reason: question, from the hook) and stayed waiting through the turn's end, with no moment of finished in between (sampled every 1.5 s).request_user_input(it only exists in Plan mode); the adapter and ledger handle it the same way.🤖 Generated with Claude Code
https://claude.ai/code/session_01V7UV6sY16AabsdHtcyxyjL