Skip to content

fix: parse waiting_for_user task status and return it from wait() - #8

Merged
AlexLiu190625 merged 1 commit into
xorbitsai:mainfrom
AlexLiu190625:fix/task-status-waiting-for-user
Jun 25, 2026
Merged

fix: parse waiting_for_user task status and return it from wait()#8
AlexLiu190625 merged 1 commit into
xorbitsai:mainfrom
AlexLiu190625:fix/task-status-waiting-for-user

Conversation

@AlexLiu190625

Copy link
Copy Markdown
Collaborator

The backend's task status enum includes waiting_for_user, and the /v1/chat/tasks endpoints serialize it into the status field, but TaskStatus omitted it. Any task that paused for user input made tasks.get() / tasks.wait() / tasks.run() raise a pydantic ValidationError in the parse layer instead of returning a usable status.

Changes

  • Add WAITING_FOR_USER to TaskStatus, matching the backend enum (6 values).
  • wait() / run() stop polling and return the TaskInfo on waiting_for_user as well as on the terminal states. It is not terminal, but the task can only advance once this caller sends the next turn via append(), so a passive poller would otherwise spin to timeout. _TERMINAL_STATUSES still mirrors the backend's terminal set (completed, failed), and PAUSED keeps polling (another caller can resume it).
  • Document the status and the append-to-resume flow in the README; cover both the parse and the wait() return in unit tests.

Verification

ruff + mypy --strict clean; pytest 217 passed (+2). The added enum value and wait()/run() return are checked against the canonical backend contract.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the WAITING_FOR_USER task status to the Python SDK, allowing the wait() and run() methods to stop polling and return control to the caller when user input is required. It also bumps the SDK version to 0.3.2 and adds corresponding unit tests. A review comment identifies an issue in the README documentation snippet where result.task_id is incorrectly used instead of result.info.task_id.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread python/README.md Outdated
The backend's task status enum includes waiting_for_user, which the
/v1/chat/tasks endpoints can return, but TaskStatus omitted it, so
tasks.get()/wait()/run() raised a pydantic ValidationError on any task
that paused for user input.

- Add WAITING_FOR_USER to TaskStatus.
- wait()/run() stop polling and return on waiting_for_user as well as on
  the terminal states. The status is not terminal, but the task can only
  advance once this caller sends the next turn via append(), so a passive
  poller would otherwise spin to timeout. _TERMINAL_STATUSES still mirrors
  the backend's terminal set (completed, failed) and PAUSED keeps polling.
- Document the status and the append-to-resume flow; cover parsing and the
  wait() return in unit tests.
@AlexLiu190625
AlexLiu190625 force-pushed the fix/task-status-waiting-for-user branch from bb9eea8 to 69e92d9 Compare June 25, 2026 06:22

@rogercloud rogercloud left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approve

Root-cause fix, not a patch: the backend emits waiting_for_user in the status field, but TaskStatus omitted it, so any task paused for user input crashed the parse layer with a pydantic ValidationError. Adding the enum value is the minimal correct fix.

The terminal-vs-returnable distinction is modeled well: _WAIT_RETURN_STATUSES = _TERMINAL_STATUSES | {WAITING_FOR_USER} cleanly separates "terminal" from "wait() should hand back to the caller". WAITING_FOR_USER is non-terminal but can only advance once this caller append()s the next turn, so a passive poller would otherwise spin to timeout — returning early is correct, while PAUSED rightly keeps polling. The reasoning is documented thoroughly in the docstrings/comments and fits the existing strict-parse style.

Verified locally:

  • pytest tests/unit/ → 217 passed (+2), matching the PR description.
  • New tests are meaningful: test_waiting_for_user_returns_to_caller asserts polling stops exactly when the status appears (2 polls); test_waiting_for_user_accepted asserts the parse layer no longer raises.
  • The earlier README finding (result.task_idresult.info.task_id) is fixed; RunResult exposes only output/status, so the corrected snippet is right.

No blocking issues. LGTM.

@AlexLiu190625
AlexLiu190625 merged commit 5f135a1 into xorbitsai:main Jun 25, 2026
3 checks passed
@AlexLiu190625

Copy link
Copy Markdown
Collaborator Author

Follow-up ownership:

  • Issue 10 synchronizes the existing Task lifecycle models, fixtures, and documentation, including removal of append-as-resume guidance.
  • Issue 11 adds strict typed interaction get/list/respond on the existing AgentClient.tasks surface.

This merged PR remains the client foundation. The follow-ups add no parallel transport-specific client facade and do not require rewriting this PR's history.

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.

2 participants