[tool system] Module-level global mutable state creates race conditions and testing difficulty #671
Labels
No labels
area:chat
area:core
area:llm
area:routes
area:tools
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
refactor
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
sleepy/odysseus#671
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Global mutable state across the tool system
The tool system relies on 5 module-level mutable globals that create hidden coupling and make testing/concurrent use difficult:
src/tool_implementations.py:71-72:_active_document_idand_active_model— set viaset_active_document()/set_active_model(), read globally. If two agent loops run concurrently (e.g. task scheduler), one overwrites the other's active document.src/agent_tools.py:68:_mcp_manager = None— global singleton MCP manager set once at startup.src/agent_loop.py:442-443:_cached_base_promptand_cached_base_prompt_key— module-level prompt cache. Not thread-safe. Could be invalidated by one coroutine while another reads stale data.src/agent_runs.py:36:_RUNS: Dict[str, _Run] = {}— in-memory run registry (unbounded growth potential).Problems
_active_document_idset_active_document()at any time, affecting all readersSuggested fix
active_documentandactive_modelas explicit parameters through the call chain (they already partially are —_build_system_promptreceivesactive_documentbut still sets the global)contextvars.ContextVar) for request-scoped state_cached_base_promptto an LRU cache or a class instanceFixed via PR #902 — replaced _active_document_id/_active_model with contextvars, _cached_base_prompt with _PromptCache class. _mcp_manager kept as singleton with doc comment.