Skip to content

Add structured daemon waiting input#848

Open
TZZheng wants to merge 2 commits into
Lingtai-AI:mainfrom
TZZheng:codex/daemon-waiting-input-20260710
Open

Add structured daemon waiting input#848
TZZheng wants to merge 2 commits into
Lingtai-AI:mainfrom
TZZheng:codex/daemon-waiting-input-20260710

Conversation

@TZZheng

@TZZheng TZZheng commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a structured waiting-input path for daemon CLI backends so a daemon can explicitly request parent/human input instead of burying a clarification question in final prose.

What changed

  • Adds daemon_common.ask_human(question, choices?, default?, reason?) for MCP-capable daemon backends.
  • Records the request via a dedicated input-request artifact and transitions the daemon into a runtime-owned waiting_input state.
  • Surfaces waiting-input state through daemon list/check output and notification/event metadata without consuming the existing once-only terminal notification semantics for done/failed/cancelled/timeout.
  • Keeps full request details in daemon state/check artifacts while bounding list previews to avoid context bloat.
  • Routes corrupt or invalid direct request artifacts to failed so a daemon cannot remain stuck as running if it bypasses MCP validation.
  • Documents the contract and Claude Code print-mode behavior.

Why

Claude Code print mode (claude --print) is not an interactive terminal: stdin is not a TTY, and clarification questions emitted as prose are only final/stdout text. A daemon needs a structured signal for "I need input" so the parent can receive a notification and decide whether to answer, ask the human, cancel, or rerun.

Non-goals / deferred

  • This does not pretend claude --print can block on stdin.
  • Automatic answer-to-resume state reconciliation is explicitly deferred; resumable CLI backends can receive a follow-up, but clearing/reconciling paused state after an answer remains follow-up lifecycle work.
  • This does not broaden GitHub, shell, or live-runtime permissions for daemon tasks.

Validation

  • git diff --check canonical/main...HEAD
  • PYTHONPATH=src python -m py_compile src/tools/daemon/__init__.py src/tools/daemon/run_dir.py src/lingtai/mcp_servers/daemon_common/server.py
  • PYTHONPATH=src python -m pytest -q tests/test_daemon_waiting_input.py tests/test_daemon_run_dir.py tests/test_daemon_terminal_state_gate.py tests/test_daemon_check.py — 111 passed
  • PYTHONPATH=src python -m pytest -q tests/test_daemon*.py — 479 passed

Review

  • Codex implementation and fix daemons completed local validation.
  • Independent Claude Code review initially requested changes for corrupt direct request artifacts; the follow-up commit fixed that blocker.
  • Claude Code re-review verdict: approve with nits. Remaining nits are non-blocking: a benign duplicate failure event on one backend path, choice-preview cap lacking an explicit truncation marker, and an existing permissive run_id: None behavior.

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.

1 participant