fix(issue-14): keep the idle-timeout working grace alive on the pane busy token
The R1 grace after a subscriber idle timeout only asked herdr whether the agent was still `working`. herdr never reports that for codex, so a codex review longer than the idle timeout was closed as deadline_timeout mid-turn and its eventual `completed` refused - the same status blindness behind the agent_blocked misjudgement. `_agent_still_working` now also accepts the pane's own busy token, the evidence send_keys_safe already uses to confirm delivery. Adds a wrapper test where a codex-like agent (idle per herdr, busy per pane) idles out the subscriber and completes out of band afterwards. Refs #14 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
This commit is contained in:
1 parent
4b3134554a
commit
eaa49aaafe
2 files changed
+77
-27
No files matched your search
@@ -585,6 +585,17 @@ _inject_acknowledged() {
|
||||
done
|
||||
}
|
||||
|
||||
# ISSUE-14: herdr's agent_status is blind for some agents (codex stays `idle`
|
||||
# for the whole turn), so "still working" must also accept the pane's own busy
|
||||
# token - the same evidence send_keys_safe uses to confirm delivery. Without it
|
||||
# a codex review longer than the idle timeout was closed as deadline_timeout
|
||||
# mid-turn and its eventual `completed` refused.
|
||||
_agent_still_working() {
|
||||
local sess="$1" target="$2"
|
||||
[ "$(_sks_agent_status "$sess" "$target")" = "working" ] && return 0
|
||||
_pane_tail "$sess" 8 2>/dev/null | grep -Fq "esc to interrupt"
|
||||
}
|
||||
|
||||
_map_sub_rc() {
|
||||
local sub_rc="$1" job_id="$2"
|
||||
local job_status="running"
|
||||
@@ -661,23 +672,12 @@ finalize_unfinished() {
|
||||
local sess="${target_sess#herdr:}"
|
||||
local target_agent
|
||||
target_agent=$(_sanitize_herdr_agent_name "$sess")
|
||||
local agent_st=""
|
||||
local still_working=0
|
||||
if [ "$sess" != "human" ] && [ -n "$sess" ]; then
|
||||
local raw_st
|
||||
raw_st="$(_sks_herdr agent get "$target_agent" 2>/dev/null || _sks_herdr agent get "$sess" 2>/dev/null || true)"
|
||||
if [ -n "$raw_st" ]; then
|
||||
agent_st="$("$(_delegate_py_bin)" -c '
|
||||
import sys, json
|
||||
try:
|
||||
d = json.loads(sys.stdin.read())
|
||||
print((d.get("result", {}).get("agent", {}) or {}).get("agent_status", "") or "")
|
||||
except Exception:
|
||||
print("")
|
||||
' <<< "$raw_st" 2>/dev/null || true)"
|
||||
fi
|
||||
_agent_still_working "$sess" "$target_agent" && still_working=1
|
||||
fi
|
||||
|
||||
if [ "$agent_st" = "working" ]; then
|
||||
if [ "$still_working" = "1" ]; then
|
||||
local now elapsed remaining
|
||||
now=$(date +%s)
|
||||
elapsed=$(( now - ${START_TIME:-now} ))
|
||||
@@ -692,19 +692,7 @@ except Exception:
|
||||
[ "$disk_st" = "completed" ] && return 0
|
||||
break
|
||||
fi
|
||||
local cur_raw cur_st=""
|
||||
cur_raw="$(_sks_herdr agent get "$target_agent" 2>/dev/null || _sks_herdr agent get "$sess" 2>/dev/null || true)"
|
||||
if [ -n "$cur_raw" ]; then
|
||||
cur_st="$("$(_delegate_py_bin)" -c '
|
||||
import sys, json
|
||||
try:
|
||||
d = json.loads(sys.stdin.read())
|
||||
print((d.get("result", {}).get("agent", {}) or {}).get("agent_status", "") or "")
|
||||
except Exception:
|
||||
print("")
|
||||
' <<< "$cur_raw" 2>/dev/null || true)"
|
||||
fi
|
||||
if [ "$cur_st" != "working" ]; then
|
||||
if ! _agent_still_working "$sess" "$target_agent"; then
|
||||
sleep 1
|
||||
disk_st="$(_disk_status "$job_id")"
|
||||
if [ "$disk_st" = "completed" ] || [ "$disk_st" = "error" ] || [ "$disk_st" = "cancelled" ]; then
|
||||
|
||||
Reference in new issue
Block a user