Chat lifecycle & polling
Chats execute asynchronously on a background worker — start_chat /
send_message return immediately with status: "accepted"; the turn runs after.
get_chat(chat_id) is the poll target. Its status:
- running — a turn is in flight. Keep polling.
- active — idle / turn finished. Read the last assistant message +
outcomes. - paused — waiting on a human.
pending_hitl_requestdescribes what’s needed (question,request_type,tool_name/tool_args, anduiwhen the request offered specific options — e.g.[{"buttons": ["Retry now", "Skip Todoist"]}]). Resolve withrespond_to_hitl(request_id, action=... | text=... | selection=...), which resumes the turn. Whenuiofferedbuttons/choice,action/selectionmust be one of those options — anything else is rejected with the valid list. Sending a newsend_messagealso resumes a paused chat. - errored — the turn failed.
Note a tool-only turn may produce no new assistant message — rely on status and
outcomes, not message presence. outcomes is where completed goals are recorded
(status success / failed / partial + a summary).