Skip to content

feat(intelligence): wire MockLLMService — fix broken demo __main__ blocks (#6994) - #7076

Merged
mrveiss merged 1 commit into
Dev_new_guifrom
issue-6994
May 6, 2026
Merged

mrveiss merged 1 commit into
Dev_new_guifrom
issue-6994

Conversation

@mrveiss

@mrveiss mrveiss commented May 6, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes the two __main__ demo blocks under intelligence/ that have been broken since the fixture relocation in #458 — from tests.fixtures.mocks import ... raised ModuleNotFoundError because there is no tests/fixtures/ package inside autobot-backend/. On top of that, MockLLMInterface is the wrong shape for the demos: IntelligentAgent and StreamingCommandExecutor switched to the LLMService.chat(messages, **kwargs) surface during the #3185 retirement, but MockLLMInterface still exposes the old generate_response(prompt) API.

This PR wires a working canonical fixture path, adds MockLLMService matching the LLMService.chat() surface, and points the demos at it.

  • Add autobot-backend/tests/fixtures/__init__.py + mocks.py (canonical location for autobot-backend's own demos — no longer depends on the autobot-infrastructure/ fixture path).
  • New MockLLMService returns deterministic LLMResponse objects via .chat() / .chat_optimized() / .generate() / .get_metrics(), with a duck-typed shim fallback when llm_interface_pkg.models isn't importable.
  • Fix sys.path setup in intelligent_agent.py:872 and streaming_executor.py:648 (was parent.parent.parent = repo root, now parent.parent = autobot-backend/).
  • Swap MockLLMInterface() → MockLLMService() at construction in both demos.
  • Refresh the disabled-test TODO in agents/atomic_facts_extraction_test.py to point at feat(intelligence): wire-in MockLLMService — fix broken demo __main__ blocks (#6943 follow-up) #6994 and reference the new fixture path.
  • MockLLMInterface preserved in the new fixtures module (never delete code — wire it in).

Test plan

  • python3 -m py_compile clean across all 5 modified/new files
  • Smoke verification of the mock surface:
    PYTHONPATH=autobot-backend python3 -c "
    import asyncio
    from tests.fixtures.mocks import MockLLMService
    r = asyncio.run(MockLLMService().chat([{'role': 'user', 'content': 'parse a command'}]))
    print(r.content)"
    # → COMMAND: echo 'mock LLM response' / EXPLANATION: Demo path …
  • End-to-end demo execution requires autobot_shared + project venv (pre-existing env requirement, out of scope for this PR — blocked by missing system deps in CI sandbox).
  • All 5 mock surfaces (chat/generate/get_metrics, validator, KB, worker) verified operational.

Closes #6994

🤖 Generated with Claude Code

…ocks (#6994)

#6943 noted MockLLMInterface mocks a class deleted in #3185. Investigation
showed the two `__main__` demo blocks under intelligence/ had been broken
since the fixture relocation in #458 — `from tests.fixtures.mocks import ...`
raised ModuleNotFoundError on first import, with no working fixture path
inside autobot-backend.

- Add canonical fixture location at autobot-backend/tests/fixtures/mocks.py
  with the four mocks the demos use (Validator, KB, WorkerNode) plus a new
  MockLLMService matching the LLMService.chat(messages, **kwargs) surface
  callers depend on after the #3185 retirement. Returns deterministic
  LLMResponse objects; falls back to a duck-typed shim if llm_interface_pkg
  isn't importable.
- intelligent_agent.py:872 + streaming_executor.py:648 — fix sys.path to
  add autobot-backend root (parent.parent, not parent.parent.parent), and
  swap MockLLMInterface for MockLLMService at construction.
- atomic_facts_extraction_test.py — refresh the disabled-test TODO to
  point at #6994 and reference the new MockLLMService location.
- MockLLMInterface preserved in the new fixtures module per the
  "never delete code — wire it in" policy.

Verification:
  PYTHONPATH=autobot-backend python3 -c "from tests.fixtures.mocks import \
    MockLLMService; import asyncio; r = asyncio.run(MockLLMService().chat(\
    [{'role': 'user', 'content': 'parse a command'}])); print(r.content)"
  → COMMAND: echo 'mock LLM response' / EXPLANATION: Demo path …

The full demo binaries also need autobot_shared on PYTHONPATH (pre-existing
env requirement); this commit only addresses the wire-in surface
specified in #6994.

Closes #6994
@github-actions

github-actions Bot commented May 6, 2026

Copy link
Copy Markdown
Contributor

✅ SSOT Configuration Compliance: Passing

🎉 No hardcoded values detected that have SSOT config equivalents!

@mrveiss
mrveiss merged commit 336b18f into Dev_new_gui May 6, 2026
5 of 7 checks passed
@mrveiss
mrveiss deleted the issue-6994 branch May 6, 2026 09:01
mrveiss added a commit that referenced this pull request Aug 25, 2026
)

Review of #15013 found four red checks and one dishonest deferral.

File-size ratchet. takeover_manager_e2e_test.py shrank 663 -> 411, which is
under MAX_LINES (600), so its grandfather entries were DELETED from both
scripts/python_file_size_known_large.py and
repo_tests/python_file_size_ratchet_baseline.py rather than lowered -- the
audit's own message says an entry naming a compliant file exempts nothing
while looking authoritative. #14629 turned discovery on for this audit, which
is why it surfaced now.

The explanatory comment on the 77 -> 59 change grew the uncollected-class
guard 921 -> 926, past its recorded ceiling. A grandfathered exemption freezes
the size it was granted for, so the comment was condensed back to 921 instead;
the same two facts are still there, folded into the paragraph above the dict --
including the correction that 'every one of the remaining offenders is a
live-service driver' is no longer true.

Stale citation. atomic_facts_extraction_test.py was deferred citing #6994.
#6994 closed on 2026-05-06 via #7076, and the TODO(#6994) in that file was
planted by that same closing commit, which excluded this work from #6994's
scope on its face. Nothing has tracked it since. Filed as #15043 and the
comment now points there, saying plainly that self.extraction_agent is never
assigned so all 8 methods would raise AttributeError if collected. The dead no-op
statement goes with it. No behaviour change; the file's 8 stay inside the ceiling.

Decomposition (#560). temporal_invalidation_test.py was rewritten in this PR,
so the two functions over the 70-line threshold were split now rather than
carried: _setup_test_facts (79) is a table of seven rows plus a loop, and
test_invalidation_rule_matching (74) delegates to _assert_rule_matches and
_fresh_fact. Longest function in the file is now 31 lines. The three mutations
that cover it -- age, confidence and source-pattern rules -- were re-run after
the split and all three are still red.
mrveiss added a commit that referenced this pull request Aug 25, 2026
…#14979) (#15013)

* fix(test): collect two live-service driver suites that pytest refused (#14979)

SessionTakeoverTestSuite and TestTemporalInvalidation both defined __init__,
so pytest declined the class and 18 test_* methods were dead text while the
*_test.py name, the collected tree and the clean import all said they ran.

Neither actually needed a live service, which is what made them convertible
ahead of the rest of the #14979 population:

- takeover_manager_e2e_test.py drives WorkflowAutomationManager in-process and
  TerminalWebSocket through an AsyncMock socket. Its try/except ImportError
  wrapper is gone (every method opened with a silent return when it tripped),
  test_chat_integration now mocks the orchestrator instead of asserting
  "if workflow_id:" against a live planner, and test_command_risk_assessment
  asserts SecureCommandExecutor.assess_command_risk instead of a copy of the
  frontend classifier defined inside the test body. The run_demo_workflow
  driver became test_status_reports_every_step_of_a_multi_step_workflow.
- services/temporal_invalidation_test.py drives the service against an
  in-process fakeredis rule store. test_actual_invalidation_sweep had a hidden
  ordering dependency on the dry-run test; the fixtures built naive datetimes
  that make matches_fact raise TypeError; three assertions were conditional on
  the behaviour they checked; two rule branches tripped on age before the
  confidence and source-pattern paths were ever read.

Every method ended on a return value, which would have moved all 18 into
#14920's population on collection; those are gone.

Ratchet: autobot-backend 77 -> 59 uncollected test_* methods, lowered in this
commit with the reason inline.

* Auto-fix: code formatting

Applied Black, isort, and autoflake to match code-quality checks.
Triggered by workflow auto-fix-formatting.yml.

* fix(test): clear the file-size ratchet and re-point a stale TODO (#14979)

Review of #15013 found four red checks and one dishonest deferral.

File-size ratchet. takeover_manager_e2e_test.py shrank 663 -> 411, which is
under MAX_LINES (600), so its grandfather entries were DELETED from both
scripts/python_file_size_known_large.py and
repo_tests/python_file_size_ratchet_baseline.py rather than lowered -- the
audit's own message says an entry naming a compliant file exempts nothing
while looking authoritative. #14629 turned discovery on for this audit, which
is why it surfaced now.

The explanatory comment on the 77 -> 59 change grew the uncollected-class
guard 921 -> 926, past its recorded ceiling. A grandfathered exemption freezes
the size it was granted for, so the comment was condensed back to 921 instead;
the same two facts are still there, folded into the paragraph above the dict --
including the correction that 'every one of the remaining offenders is a
live-service driver' is no longer true.

Stale citation. atomic_facts_extraction_test.py was deferred citing #6994.
#6994 closed on 2026-05-06 via #7076, and the TODO(#6994) in that file was
planted by that same closing commit, which excluded this work from #6994's
scope on its face. Nothing has tracked it since. Filed as #15043 and the
comment now points there, saying plainly that self.extraction_agent is never
assigned so all 8 methods would raise AttributeError if collected. The dead no-op
statement goes with it. No behaviour change; the file's 8 stay inside the ceiling.

Decomposition (#560). temporal_invalidation_test.py was rewritten in this PR,
so the two functions over the 70-line threshold were split now rather than
carried: _setup_test_facts (79) is a table of seven rows plus a loop, and
test_invalidation_rule_matching (74) delegates to _assert_rule_matches and
_fresh_fact. Longest function in the file is now 31 lines. The three mutations
that cover it -- age, confidence and source-pattern rules -- were re-run after
the split and all three are still red.

* Auto-fix: code formatting

Applied Black, isort, and autoflake to match code-quality checks.
Triggered by workflow auto-fix-formatting.yml.

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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.

1 participant