Skip to content

0.8.0: scouts.update(is_public), APIConnectionError for transport failures, lazy chat namespace#131

Merged
dhruvbatra merged 5 commits into
mainfrom
scouts-update-is-public-transport-errors
Jun 11, 2026
Merged

0.8.0: scouts.update(is_public), APIConnectionError for transport failures, lazy chat namespace#131
dhruvbatra merged 5 commits into
mainfrom
scouts-update-is-public-transport-errors

Conversation

@dhruvbatra

@dhruvbatra dhruvbatra commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Changes

scouts.update(is_public=...) — the developer API's PATCH already accepts is_public, but neither client exposed it on update() (only create()), so visibility couldn't be changed after creation through the SDK; yutori-mcp's edit_scout hit a TypeError. Added to both sync and async namespaces through the shared payload builder. Verified live against production: an is_public edit round-trips correctly.

APIConnectionError for transport failureshandle_response already wraps auth failures, redirects, status errors, and non-JSON bodies, but httpx transport errors (timeouts, DNS/connect failures) escaped _request raw — and some (e.g. ReadTimeout) stringify to "", giving callers a blank error. Both _request chokepoints now raise APIConnectionError with a message that always names the underlying httpx exception type. Exported from the package root.

Lazy chat namespace — the chat namespace eagerly built an OpenAI client (its own HTTP client + SSL context) in every client __init__ — measured at roughly half the construction cost — even for callers that never use chat completions (yutori-mcp builds a client per tool call). Now constructed on first attribute access; close() releases it inside try/finally so an HTTP-client close failure can't leak it.

Version → 0.8.0.

Tests

442 passed, 3 skipped. New coverage: is_public wire payload (sync + async, including False surviving the None-filter), status mutual-exclusion with is_public, transport-error wrapping (sync + async, including blank-stringifying timeout), lazy-chat construction and close-without-use.

Release ordering

yutori-mcp pins yutori>=0.8.0 and consumes all three changes (is_public edit, APIConnectionError mapping, per-call client cost). Sequence: deploy yutori-ai/yutori#10031 → publish this as 0.8.0 → release yutori-mcp.

🤖 Generated with Claude Code


Note

Low Risk
Additive SDK API and error-type changes with tests; no auth or server logic changes, though callers may need to catch APIConnectionError for network failures.

Overview
Release 0.8.0 bumps package and installer version strings; API docs now list is_public on scouts.update.

Scout visibility: Sync and async scouts.update() accept is_public, wired through the shared payload builder so PATCH can change public/private after create (including False, which is not dropped as None). Combining status with is_public still raises the existing mutual-exclusion ValueError.

Transport errors: Shared sync/async _request paths catch httpx.HTTPError and raise exported APIConnectionError with a message that always includes the httpx exception type (avoids blank messages from errors like ReadTimeout("")).

Client lifecycle: YutoriClient / AsyncYutoriClient defer building the chat namespace (OpenAI client) until first access; close() uses try/finally so a built chat client is released even if the main HTTP client close fails.

Reviewed by Cursor Bugbot for commit ba91ec6. Bugbot is set up for automated code reviews on this repo. Configure here.

dhruvbatra and others added 4 commits June 10, 2026 17:49
The developer API's PATCH /v1/scouting/tasks/{id} accepts is_public, but
neither client exposed it on update() — only create() — so visibility could
not be changed after creation through the SDK (yutori-mcp's edit_scout hit
TypeError trying). Adds the parameter to both sync and async namespaces,
threaded through the shared payload builder, with wire-payload tests
asserting False survives the None-filter and the status mutual-exclusion
still applies.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
handle_response already wraps auth failures, redirects, status errors, and
non-JSON bodies, but httpx transport errors (timeouts, DNS/connect failures)
escaped _request raw — and some (e.g. ReadTimeout) stringify to "", giving
callers a blank error. Both _request chokepoints now raise
APIConnectionError with a message that always names the underlying httpx
exception type. Exported from the package root.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The chat namespace eagerly constructed an OpenAI client (its own HTTP client
and SSL context) in every YutoriClient/AsyncYutoriClient __init__ — roughly
half the client construction cost — even for callers that never use chat
completions (e.g. yutori-mcp, which builds a client per tool call). It is
now constructed on first access, and close() releases it inside try/finally
so a failure closing the HTTP client no longer leaks it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
scripts/build_install.sh output tracks the package version; CI's install-sh
check requires it to be committed alongside version bumps.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ba91ec6. Configure here.

Comment thread yutori/_http.py
**self._request_kwargs(params, json),
)
except httpx.HTTPError as exc:
raise _to_connection_error(exc) from exc

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

CLI misses APIConnectionError handler

Medium Severity

_request now raises APIConnectionError for transport failures instead of raw httpx errors. cli_api_errors still catches only httpx.HTTPError, so CLI commands using a real YutoriClient can show a Typer traceback on timeouts or connection failures instead of the intended friendly network message.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit ba91ec6. Configure here.

@dhruvbatra dhruvbatra merged commit 91b2c21 into main Jun 11, 2026
9 checks passed
@dhruvbatra dhruvbatra deleted the scouts-update-is-public-transport-errors branch June 11, 2026 03:13
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