Files
OpenJarvis/tests/learning/test_device_selection.py
T
05f2c02131 feat: Algolia DocSearch + learning subsystem reorganization (#43)
* chore: create learning subdirectory structure (routing, agents, intelligence)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: extract classify_query to routing/_utils.py

Move the classify_query() function and its regex patterns into a shared
utility module so multiple routing policies can import it without
depending on the full trace_policy module.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: move routing files to learning/routing/ subdirectory

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: create LearnedRouterPolicy merging trace-driven + SFT routing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add conditional Algolia DocSearch integration

Add Algolia DocSearch as an optional search upgrade — native lunr.js
search remains the default until credentials are configured. Includes
CDN assets, Jinja2 conditional config injection, init script with
graceful fallback, light/dark theme CSS, improved search tokenization
for snake_case/dotted identifiers, and search boosts for key pages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: move agent_evolver and skill_discovery to learning/agents/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: move learning/orchestrator to learning/intelligence/orchestrator

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: delete removed learning policies, rewrite __init__.py, clean up api_routes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add SFT/GRPO/DSPy/GEPA config dataclasses, update LearningConfig

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add general-purpose SFT trainer (intelligence/sft_trainer.py)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: update stale imports in multi_model_router example

Update imports to use new learning/routing/ paths after the
subdirectory reorganization. Replace BanditRouterPolicy with
LearnedRouterPolicy.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add general-purpose GRPO trainer (intelligence/grpo_trainer.py)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add DSPy agent optimizer (agents/dspy_optimizer.py)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add GEPA agent optimizer (agents/gepa_optimizer.py)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add learning-dspy and learning-gepa optional dependency extras

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: update integration test to check for learned policy instead of grpo

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: clean up stale APIs and unused params in examples

- deep_research: remove system_prompt and max_turns params not accepted
  by Jarvis.ask(), inline system prompt into the query instead
- doc_qa: remove unused --top-k CLI arg that was never passed to the API
- multi_model_router: fix select_model() call to match single-arg signature

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: import SFT/GRPO trainers in intelligence/__init__.py for registry

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: remove .md file changes from PR

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: restore search boost frontmatter for key docs pages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 21:34:31 -07:00

84 lines
2.4 KiB
Python

"""Tests for PyTorch device selection (cuda > mps > cpu)."""
from __future__ import annotations
class TestSelectTorchDevice:
"""Tests for _select_torch_device() logic in orchestrator trainers.
Since torch is not installed in the test environment, we test the
selection logic directly rather than through the function (which
returns None when torch is absent).
"""
def test_no_torch_returns_none(self):
"""Without torch, _select_torch_device returns None."""
from openjarvis.learning.intelligence.orchestrator.sft_trainer import (
_select_torch_device,
)
# torch is not installed in test env, so HAS_TORCH is False
assert _select_torch_device() is None
def test_cuda_preferred(self):
"""CUDA is selected when available (logic test)."""
has_cuda = True
has_mps = True
if has_cuda:
choice = "cuda"
elif has_mps:
choice = "mps"
else:
choice = "cpu"
assert choice == "cuda"
def test_mps_fallback(self):
"""MPS is selected when CUDA is not available but MPS is."""
has_cuda = False
has_mps = True
if has_cuda:
choice = "cuda"
elif has_mps:
choice = "mps"
else:
choice = "cpu"
assert choice == "mps"
def test_cpu_last_resort(self):
"""CPU is selected when neither CUDA nor MPS is available."""
has_cuda = False
has_mps = False
if has_cuda:
choice = "cuda"
elif has_mps:
choice = "mps"
else:
choice = "cpu"
assert choice == "cpu"
def test_function_exists_in_both_trainers(self):
"""_select_torch_device is defined in both trainers."""
from openjarvis.learning.intelligence.orchestrator.grpo_trainer import (
_select_torch_device as grpo_fn,
)
from openjarvis.learning.intelligence.orchestrator.sft_trainer import (
_select_torch_device as sft_fn,
)
assert callable(sft_fn)
assert callable(grpo_fn)
def test_exported_from_orchestrator_init(self):
"""_select_torch_device is exported from orchestrator package."""
from openjarvis.learning.intelligence.orchestrator import (
_select_torch_device,
)
assert callable(_select_torch_device)