fix: delegate default model selection to providers#48
Merged
Conversation
This was referenced Jul 10, 2026
b18fd9b to
4bcfab9
Compare
ebarti
added a commit
that referenced
this pull request
Jul 10, 2026
## What - separates side-effect-free package availability from explicit async execution readiness - adds `RuntimeReadiness`, `ReadinessStatus`, optional `RuntimeReadinessProvider`, and bounded `check_readiness()` - exposes readiness through the registry, AgentKit, provider diagnostics, and live smoke path - probes Claude credential signals without claiming local/provider chains are verified - probes Codex through the supported account API with guaranteed temporary-client cleanup - probes Antigravity API-key/ADC setup off the event loop and converts timeout/failure into secret-safe diagnostics ## Why `availability()` mixed package presence with potentially blocking credential discovery. In particular, Antigravity could read files or contact Google metadata services from a synchronous setup check, while Claude/Codex package success was easy to misread as execution readiness. ## Root cause One diagnostic type represented two different questions: “is the adapter installed?” and “is enough setup present to attempt a provider call?” Provider authentication mechanisms also differ in how safely they can be probed. ## Semantics - `availability()`: synchronous, package-only, side-effect-free - `READY_TO_ATTEMPT`: setup signal confirmed, not a guarantee of execution - `NOT_READY`: a concrete package/credential problem was established - `INDETERMINATE`: provider-owned/local chains, timeout, or probe failure require caller policy - readiness remains an optional extension, so the `AgentRuntime` protocol is unchanged ## Checks - `ruff check src tests` - strict `mypy` - full suite: 380 passed, 3 skipped in the all-extras verification environment - delegated run: 371 passed, 12 skipped; 90.92% coverage - `uv lock --check` - `uv build` plus wheel/sdist content inspection ## Stack - Base: #46 - Next: #48
1fe7c21 to
530d4f6
Compare
ebarti
added a commit
that referenced
this pull request
Jul 10, 2026
## Stack - Base: #48 - Next: none — stack halted after this PR as requested ## What this fixes The runtime protocol advertised cancellation, but every provider adapter implemented it as a no-op, and tasks had no portable execution deadline. That left callers unable to bound startup, process-reuse queueing, or in-flight provider work. ## Changes - add keyword-only, timezone-aware `AgentTask.deadline` - add `AgentKit.run(timeout=...)` as a finite non-negative seconds/`timedelta` convenience - add `AgentTaskTimeoutError` and `FinishReason.TIMED_OUT` - add immutable `CancellationReceipt` and explicit cancellation dispositions - make built-in Claude, Codex, Antigravity, and fake runtimes cancellation-aware - make `AgentKit.cancel()` target active cached runtimes without constructing new ones - preserve legacy third-party runtimes whose `cancel()` returns `None` - document cancellation's non-rollback semantics ## Adversarial race hardening Independent reproductions found concurrency defects beyond the initial green suite. Follow-up commits now: - bind cancellation to the exact asyncio task generation - reserve same-id tombstones while legacy task-id hooks settle, preventing ABA cancellation - remove cancellable lock windows from registration/unregistration - keep cancellation effective if the `AgentKit.cancel()` caller is cancelled - make completion-race receipts truthful - make timeout causality win once the deadline fires and emit at most one terminal - skip misleading started events for already-expired tasks - give provider/operation teardown a bounded five-second grace period - quarantine runtime instances while detached cleanup remains pending, rejecting overlap and recovering automatically when cleanup settles - validate deadline runtime types deliberately instead of leaking `AttributeError` ## Verification - all-extras full suite: 418 passed, 3 skipped - core-only full suite: 409 passed, 12 skipped - all-extras coverage: 90.33% (minimum 85%) - focused race/control suite: 22 passed - final independent quarantine reproductions: 3 passed; no pending-task warnings - `uv run ruff check .` - strict `mypy` - `uv lock --check` - `uv build` - `git diff --check` ## Stack health All 11 required GitHub checks pass on `bcd080c`; the opt-in upstream-latest workflow is skipped by design.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
model_sourceon every provider result and recordsmodelonly when knowndefault_model=as an explicit migration overrideWhy
Hard-coded adapter defaults age faster than the SDK and can override supported provider configuration. The SDK-evolution docs already described Claude and Antigravity as provider-native, but the adapters silently forced stale model names.
Root cause
Model resolution treated the library constructor default as mandatory rather than an optional override, and result metadata could not distinguish task, metadata, constructor, and provider-native selection.
Compatibility
This is an intentional pre-1.0 behavior change. Applications that need the prior pin can pass the same value through
default_model=; task and metadata overrides keep their existing precedence.Checks
ruff check src testsmypyuv lock --checkuv buildStack