Skip to content

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_request describes what’s needed (question, request_type, tool_name/tool_args, and ui when the request offered specific options — e.g. [{"buttons": ["Retry now", "Skip Todoist"]}]). Resolve with respond_to_hitl(request_id, action=... | text=... | selection=...), which resumes the turn. When ui offered buttons/choice, action/selection must be one of those options — anything else is rejected with the valid list. Sending a new send_message also 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).