Skip to content

bug(test): 8 atomic-fact extraction tests cannot run — the agent under test is never constructed #15043

Description

@mrveiss

Split out of #14979 during review of #15013, which cited #6994 for this deferral. That citation was wrong and known-wrong: #6994 closed on 2026-05-06 via #7076, and the TODO(#6994) in this file was planted by that same closing commit — it says on its face that the work below was out of scope for #6994. So nothing has tracked this since May. This issue is that tracker.

What is broken

autobot-backend/agents/atomic_facts_extraction_test.py holds 8 test_* methods in TestAtomicFactsExtraction. None of them can run, for two independent reasons:

  1. The class defines __init__, so pytest refuses it outright (PytestCollectionWarning) — the bug(test): 90 test_* methods sit in live-service validation drivers pytest cannot collect #14979 population.
  2. self.extraction_agent is never assigned. The constructor body at atomic_facts_extraction_test.py:29 is:
    def __init__(self):
        # TODO(#6994): wire MockLLMService once KnowledgeExtractionAgent
        # constructor + return-shape contract is re-validated.
        # ...
        pass  # Temporarily disabled — see TODO(#6994) above
        self.test_content = {...}

There are 13 references to self.extraction_agent across the 8 methods. Fixing (1) alone turns all 8 red with AttributeError, which is why #15013 left the file alone rather than renaming the class and calling it collected.

What it actually needs

A constructor that can be called offline. KnowledgeExtractionAgent.__init__ (agents/knowledge_extraction_agent.py:59) calls get_agent_provider_explicit, get_agent_endpoint_explicit and get_agent_model_explicit before it ever looks at the injected llm_interface. Each raises AgentConfigurationError when its AUTOBOT_KNOWLEDGE_EXTRACTION_* variable is unset (ssot_config.py:3119), so passing a mock is not sufficient — the agent reaches for SSOT config first. Either the test supplies that config, or the constructor defers the lookup until it is used.

A mock whose output the agent can parse. MockLLMService (tests/fixtures/mocks.py:476) exposes the chat(messages, **kwargs) surface the agent wants, but returns canned prose. The 8 methods assert on the parsed result — result.total_facts > 0, result.average_confidence > 0.0, len(result.temporal_type_distribution) > 1, facts_by_temporal_type(...), and that every element is an AtomicFact with a non-empty subject/predicate/object. That only holds if the mock returns fact-shaped output in whatever format extract_facts_from_text parses, for each of the three test_content bodies the fixture defines.

Then the ordinary #14979 conversion: __init__ → setup_method, drop the run_all_tests driver and its __main__, and replace the trailing return result each method ends on so they do not land in #14920's population.

Acceptance

  • KnowledgeExtractionAgent is constructible in a unit test with no live provider, either by test-supplied SSOT config or by deferring the explicit lookups
  • MockLLMService returns output extract_facts_from_text parses into AtomicFact objects for all three test_content bodies
  • The class is collected, all 8 methods assert rather than return, and the file's 8 come off autobot-backend's ceiling in repo_tests/test_methods_in_uncollected_classes_test.py in the same commit
  • Mutation-proved: break the extraction the tests name and confirm they go red
  • The TODO(#6994) comment goes with the fix — no TODO left behind

Deliberately not

Do not rename the class to Test* and stop there: it already is Test*, and it still collects zero because of the __init__. Do not skip the methods — the precondition is "this was never wired", which is not a service being down, and a skip there hides a broken test behind a condition that does not exist.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions