* chore: add pytest-asyncio in auto mode
* test: migrate channel and stream tests to native async
Convert run_async() wrapper tests to plain 'async def test_*' under
pytest-asyncio auto mode. collect_events() in stream_v3_fakes becomes a
coroutine awaited at every call site.
* test: migrate command and model/middleware tests to native async
Convert run_async() wrappers (import, alias, and fixture forms) to plain
'async def test_*'. Multi-call tests merge onto one loop as sequential
awaits; none asserted on loop identity.
* test: migrate TUI, notifier, gateway, and session tests to native async
TUI/notifier/gateway files convert run_async wrappers to plain async
tests. test_sessions.py's unittest.TestCase classes move to
unittest.IsolatedAsyncioTestCase (pytest-asyncio does not await async
methods on plain TestCase; converting blindly would have made ~70 tests
silently vacuous). Its setUpClass keeps a one-shot asyncio.run() since
IsolatedAsyncioTestCase has no async class-level hook. TestLoadingWidget
in test_tui_widgets.py drops its TestCase base for the same reason.
* test: replace direct asyncio.run() calls with native async tests
Convert tests that called asyncio.run() (directly or via a local _run
helper) to plain 'async def test_*'; delete the local helpers.
* test: drop undeclared anyio markers and delete run_async helper
The @pytest.mark.anyio tests relied on anyio being a transitive dep of
httpx; auto-mode pytest-asyncio collects them natively. run_async() and
its fixture are unreferenced after the migration, so remove them —
pytest-asyncio's per-test loop teardown covers the pending-task
cancellation the helper existed for (verified: full suite runs with no
'Event loop is closed' errors or destroyed-task warnings).
* refactor(agent): make create_cli_agent(config=, chat_model=) pure
Re-applies the #183 purity refactor on top of the observation-memory
lifecycle that landed in #259, integrating the two cleanly.
create_cli_agent gains a pure path: when both `config` and `chat_model`
are passed it builds the agent entirely from locals and writes none of
the cached module globals (`_config`, `_chat_model`, `_chat_model_key`,
`_EvoScientist_agent`). `/model` commits the switch via
`set_active_config` / `set_chat_model_instance` only after a successful
build, so a failed rebuild leaves the session on the original model
(replaces the old snapshot/restore rollback).
Supporting changes:
- Extract `set_active_config` (write-half of `_ensure_config`),
`_apply_env_from_config`, `_build_chat_model`, and
`set_chat_model_instance`.
- Thread `cfg` / `chat_model` through `_get_default_middleware`,
`_build_base_kwargs`, `load_mcp_and_build_kwargs`,
`_maybe_swap_async_subagents`, and `_inject_subagent_middleware` so the
pure path never falls back to the global-writing `_ensure_config()` /
`_ensure_chat_model()`.
- Integrate with #259's memory middleware: subagent context-editing
middleware binds the threaded `chat_model`, and the configured system
prompt / memory controls read the threaded `cfg` (new threading vs the
original #183, required because #259 made these paths read config).
- Consolidate `cfg` resolution to one `cfg if cfg is not None else
_ensure_config()` at the top of each kwargs builder, matching the
pattern already used in the other config-aware helpers.
* fix(agent): keep pure tool selector off global cache
* fix(model): apply config switch in place to preserve reference integrity
---------
Co-authored-by: Xi Zhang <106144707+X-iZhang@users.noreply.github.com>
Co-authored-by: X-iZhang <zacharyzhang2022@gmail.com>
* feat: Enhance ModelPickerWidget for Ollama integration
- Implemented a sentinel row for "Custom Ollama model..." in ModelPickerWidget, allowing users to input arbitrary model names.
- Updated action handling in ModelPickerWidget to manage transitions between list and input modes.
- Added async model discovery for Ollama models, integrating with the /model command to fetch locally installed models.
- Created tests for Ollama model discovery and ModelPickerWidget behavior, ensuring proper functionality and user experience.
- Refactored validate_ollama_connection and discover_ollama_models for improved error handling and response management.
* fix: Simplify code by removing unnecessary line breaks in ModelPickerWidget and test cases
* fix: Restore globals on set_chat_model failure to prevent half-switched session
* fix: Improve error handling in ModelCommand by restoring globals on failure
* fix(chat): resolve model switch lag by tracking model/provider key for cache invalidation
* style: format set_chat_model function for improved readability
* fix(chat): improve model switching logic to prevent unnecessary cache rebuilds
* fix(model): ensure globals are restored on agent load failure to prevent model switch issues