fix(warmup): import scan deps synchronously to avoid agents-SDK import race - #1163
Open
thehashes wants to merge 2 commits into
Open
fix(warmup): import scan deps synchronously to avoid agents-SDK import race#1163thehashes wants to merge 2 commits into
thehashes wants to merge 2 commits into
Conversation
…t race
start_import_warmup() ran the heavy dependency pre-import on a background
daemon thread to overlap it with CLI startup I/O. That races the main
thread: the warm-up imports strix.core.runner, which pulls in the agents
SDK, whose package graph has internal circular imports. CPython breaks
import cycles by exposing a partially initialized module, and that partial
state is visible across threads, so when the warm-up thread and the main
thread (warm_up_llm imports agents.model_settings / agents.models.interface)
import that graph concurrently they intermittently crash with:
KeyError: 'agents'
ImportError: cannot import name 'AgentOutputSchemaBase' from partially
initialized module 'agents.agent_output' (most likely due to a circular
import)
This reproduces reliably on some hosts (e.g. WSL2) and aborts every scan at
bootstrap. The per-module import lock does not help, because the import
system intentionally hands out partial modules mid-cycle to avoid deadlock.
Warm-up only runs on the scan path, which eagerly imports all of these
modules anyway, so importing synchronously on the calling thread adds no net
work; it only removes the unsound concurrent-import overlap. Replace the
daemon thread with a synchronous, run-once import guarded by the existing
lock. start_import_warmup() now returns None (its Thread return value was
never used).
Contributor
Greptile SummaryThe PR makes scan dependency warmup synchronous and run-once to prevent concurrent imports from exposing partially initialized Agents SDK modules.
Confidence Score: 4/5The PR appears safe to merge, with a non-blocking cold-start regression for help, version, update, and setup invocations that should be addressed by moving synchronous warmup onto the confirmed scan path. The import-race fix is coherent, but synchronous Files Needing Attention: strix/llm/warmup.py and strix/interface/main.py Important Files Changed
Prompt To Fix All With AI### Issue 1
strix/llm/warmup.py:69
**Synchronous imports delay non-scan commands**
`_warm(modules)` now blocks the caller, but the sole call occurs before argument parsing determines whether a scan will run. Consequently, cold `--help`, `--version`, `--update`, and interactive setup invocations wait for the full heavy scan dependency graph before responding; move the synchronous warmup onto the confirmed scan path.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "fix(warmup): import scan deps synchronou..." | Re-trigger Greptile |
start_import_warmup() ran before parse_arguments(), so cold --help, --version, --update and interactive setup paid the full scan import graph. Now that warm-up is synchronous the early placement buys nothing; move the call to the top of _bootstrap_scan(), which only runs when a scan actually proceeds (not args.needs_setup).
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.
Summary
start_import_warmup()pre-imports the heavy scan dependencies on a backgrounddaemon thread to overlap the cost with CLI startup I/O. This races the main
thread and crashes the scan at bootstrap on some hosts.
The warm-up imports
strix.core.runner, which pulls in the agents SDK, whosepackage graph has internal circular imports. CPython breaks import cycles by
exposing a partially initialized module, and that partial state is visible
across threads. When the warm-up thread and the main thread (
warm_up_llmimports
agents.model_settings/agents.models.interface) import that graphconcurrently, they intermittently observe each other's partial
agentspackageand crash.
Symptom
Every scan aborts during
_bootstrap_scan->warm_up_llmwith one of:This reproduces reliably on some environments (observed consistently on WSL2 /
Kali, Python 3.12 and 3.13, with the current pinned
openai-agents0.19.x). Theper-module import lock does not prevent it, because the import system
deliberately hands out partial modules mid-cycle to avoid deadlock.
Fix
Import the warm-up modules synchronously on the calling thread instead of on a
background daemon thread. Warm-up only runs on the scan path, which eagerly
imports all of these modules anyway, so importing here adds no net work; it only
removes the unsound concurrent-import overlap.
start_import_warmup()now performs a run-once synchronous import guarded bythe existing lock and returns
None(itsThreadreturn value was neverused).
was unsafe.
Testing
strix -n -t <target> ...aborts at bootstrap withKeyError: 'agents'.runs to completion.
start_import_warmup()has no other callers that use its return value, andthere is no existing test that depends on the daemon-thread behaviour.