Skip to content

fix(llm_agent): initialize self.recorder so @record_model can attach it#232

Open
yashhzd wants to merge 1 commit intomesa:mainfrom
yashhzd:fix/recorder-init-218
Open

fix(llm_agent): initialize self.recorder so @record_model can attach it#232
yashhzd wants to merge 1 commit intomesa:mainfrom
yashhzd:fix/recorder-init-218

Conversation

@yashhzd
Copy link
Contributor

@yashhzd yashhzd commented Mar 16, 2026

Summary

LLMAgent.__init__ never initialized self.recorder, so the hasattr(agent, "recorder") check in _attach_recorder_to_agents() always returned False. This meant the @record_model decorator silently never attached the SimulationRecorder to any LLMAgent instance.

Changes

  • mesa_llm/llm_agent.py: Add self.recorder: SimulationRecorder | None = None in __init__, with a TYPE_CHECKING import to avoid circular imports.
  • tests/test_llm_agent.py: Add unit test verifying hasattr(agent, "recorder") returns True and defaults to None.
  • tests/test_recording/test_record_model.py: Add integration test verifying @record_model successfully propagates the recorder to LLMAgent instances created during model init.

Test plan

  • pytest tests/test_llm_agent.py::test_llm_agent_has_recorder_attribute -xvs passes
  • pytest tests/test_recording/test_record_model.py::TestRecordModelDecorator::test_recorder_attached_to_llm_agents -xvs passes
  • Full test suite (284 tests) passes with no regressions
  • ruff check and all pre-commit hooks pass

Closes #218

LLMAgent.__init__ never set self.recorder, so the hasattr() check in
_attach_recorder_to_agents always returned False and the recorder was
silently never attached to any LLMAgent instance.

Add self.recorder = None with a TYPE_CHECKING import to avoid circular
imports, and add tests verifying the attribute exists and that
@record_model successfully propagates the recorder.

Closes mesa#218
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 16, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b1de6a1f-8d39-4114-83ec-1dfa4bb49171

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can use your project's `ruff` configuration to improve the quality of Python code reviews.

Add a Ruff configuration file to your project to customize how CodeRabbit runs ruff.

@codecov
Copy link

codecov bot commented Mar 16, 2026

Codecov Report

❌ Patch coverage is 80.00000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 90.64%. Comparing base (8e47d7b) to head (1267dce).

Files with missing lines Patch % Lines
mesa_llm/llm_agent.py 80.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #232      +/-   ##
==========================================
- Coverage   90.67%   90.64%   -0.04%     
==========================================
  Files          19       19              
  Lines        1555     1560       +5     
==========================================
+ Hits         1410     1414       +4     
- Misses        145      146       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link

@IlamaranMagesh IlamaranMagesh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for opening a PR. Though this is clearly a bug, I'm still waiting for some clarifications from the maintainers (#219) that I mentioned in the issue #218

@BhoomiAgrawal12
Copy link
Contributor

hey @yashhzd! initializing self.recorder makes sense and fixes the issue of not attaching the recorder.

I had a small question regarding this part:

if TYPE_CHECKING:
    from mesa_llm.recording.simulation_recorder import SimulationRecorder

Since the file already uses future import annotations, the type hint should work without needing this import at all.

Given that SimulationRecorder isn’t directly used at runtime in this file, do we still need the TYPE_CHECKING block? Removing it might simplify things and also resolve the Codecov uncovered line.

@yashhzd
Copy link
Contributor Author

yashhzd commented Mar 19, 2026

Hey @BhoomiAgrawal12, great observation! I looked into this.

While from __future__ import annotations does make all annotations into strings at runtime, ruff's F821 rule still requires the name to be importable at static analysis time. Without the TYPE_CHECKING block, ruff reports Undefined name 'SimulationRecorder'. And using a string literal like "SimulationRecorder | None" triggers ruff's UP037 (remove quotes from type annotation) which then circles back to F821.

So both __future__ annotations and TYPE_CHECKING are actually needed together here:

  • TYPE_CHECKING → satisfies ruff's static analysis (name is defined for type checkers)
  • __future__ annotations → ensures the annotation is a string at runtime (prevents NameError since the import doesn't execute)

Regarding the Codecov patch failure — if TYPE_CHECKING: blocks are always False at runtime, which is a well-known coverage limitation. The project's [tool.coverage.report].exclude_lines in pyproject.toml doesn't currently include "if TYPE_CHECKING:". Adding it would be a project-wide config fix (not scoped to this PR). Happy to open a separate small PR for that if maintainers agree.

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: self.recorder not initialised in LLMAgent

3 participants