Skip to content

fix: guard agents.models import in warm_up_llm against cross-thread partial-import race (#1248) - #1252

Open
not-knope wants to merge 1 commit into
usestrix:mainfrom
not-knope:fix/1248-agents-models-import-race
Open

fix: guard agents.models import in warm_up_llm against cross-thread partial-import race (#1248)#1252
not-knope wants to merge 1 commit into
usestrix:mainfrom
not-knope:fix/1248-agents-models-import-race

Conversation

@not-knope

@not-knope not-knope commented Sep 3, 2026

Copy link
Copy Markdown

Summary

  • Fresh (non-resume) scans crash at LLM warm-up with KeyError: 'agents.models' because warm_up_llm imported agents.models.interface on the main thread while the perf: take heavy imports off the startup path and pre-warm them in the background #1141 daemon was still populating that package (#1248).
  • Add an Event (_agents_models_ready) released after strix.core.runner finishes (it loads agents.models) or fails. wait_for_agents_models() blocks on that Event only — it does not join() the warm-up thread — then the original import runs. LiteLLM / Caido / Docker keep overlapping model preflight.
  • The Event is set in a finally so a failed warm-up (missing optional deps, etc.) cannot deadlock waiters. _purge_orphaned_modules is unchanged. --resume shares this warm_up_llm path, so it is covered rather than regressed.

Test plan

  • uv run pytest tests/test_import_warmup.py (8 passed), including: wait is a no-op without warm-up; wait does not join remaining modules; wait returns when the graph import fails; from agents.models.interface import ModelTracing after the wait succeeds.
  • ruff check / ruff format --check / mypy on the touched files.
  • Drive main() with Docker stubbed using --target http://example.com --instruction-file … --scan-mode quick --max-budget 2 --non-interactive: import survives; process reaches real model preflight (401 on a dummy key), not KeyError.
  • wait_for_agents_models() returns with LLM_API_KEY unset (warm-up is import-only).
  • Real CLI with Docker running and the sandbox image already cached (the [BUG] Fresh (non-resume) scans on v1.6.0 crash at warm-up: KeyError: 'agents.models' #1248 race window: pull_docker_image() is a local inspect, a few hundred milliseconds). 3/3 runs, no KeyError: 'agents.models'. The process gets past import warm-up and reaches live model preflight.

Real CLI logs (macOS arm64, source install, image cached)

uv run strix --target http://example.com \
  --instruction-file /tmp/strix-1248-instructions.txt \
  --scan-mode quick --max-budget 2 --non-interactive

STRIX_LLM=anthropic/claude-sonnet-5, dummy LLM_API_KEY (enough to prove we get past the import; the original crash happened before any provider call).

Run 1/2/3 — all exit 1 at preflight, none at agents.models:

╭─ STRIX ──────────────────────────────────────────────────────────────────────╮
│                                                                              │
│  LLM CONNECTION FAILED                                                       │
│                                                                              │
│  Could not establish connection to the language model.                       │
│  Please check your configuration and try again.                              │
│                                                                              │
│  Error: litellm.AuthenticationError: AnthropicException -                    │
│  {"type":"error","error":{"type":"authentication_error","message":"API key   │
│  is invalid."},"request_id":null}                                            │
│                                                                              │
╰──────────────────────────────────────────────────────────────────────────────╯

Exit 1 is expected (invalid key). Before this fix the same command died at warm_up_llm with KeyError: 'agents.models' and never sent a request.

Closes #1248.
Related: #1230 (same crash site on --resume; this guards that import without a full-thread join).

…artial-import race (usestrix#1248)

Wait on an Event for the agents graph instead of joining the whole warm-up thread, so LiteLLM/Docker/Caido still overlap model preflight.
@greptile-apps

greptile-apps Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR serializes the first cross-thread agents.models import against the background import warm-up without waiting for unrelated heavyweight modules.

  • Adds a readiness Event around the strix.core.runner portion of import warm-up.
  • Waits for that boundary in both headless and interactive model-preflight paths.
  • Adds subprocess regression coverage for no-warm-up, failure, partial-wait, and successful-import cases.

Confidence Score: 5/5

The PR appears safe to merge, with no concrete blocking or independently actionable non-blocking issue identified.

The new wait covers both model-preflight entry paths, releases safely on failed warm-up attempts, and does not block completion of unrelated background imports.

Important Files Changed

Filename Overview
strix/llm/warmup.py Introduces the readiness Event and isolates individual warm-up imports while preserving background overlap for later modules.
strix/interface/main.py Waits for the Agents model graph before the headless warm-up path imports ModelTracing.
strix/interface/scan_setup.py Applies the same readiness guard to the interactive model-preflight path.
tests/test_import_warmup.py Adds subprocess tests covering readiness signaling, failed graph imports, no-op behavior, and non-joining waits.

Reviews (1): Last reviewed commit: "fix: guard agents.models import in warm_..." | Re-trigger Greptile

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.

[BUG] Fresh (non-resume) scans on v1.6.0 crash at warm-up: KeyError: 'agents.models'

1 participant