← Back to Home

A first OSS bug fix with an AI coach

June 26, 2026 — by James Meadlock & Milo H

This post documents a small open-source contribution to Hermes Agent. The purpose was not to make a large code change. The purpose was to learn the contribution loop: select an issue, verify it, write a regression test, make a scoped fix, run checks, and open a pull request.

Result: pull request NousResearch/hermes-agent#53289 is open and linked to issue #53259.

Issue selected

FieldValue
RepositoryNousResearch/hermes-agent
Issue#53259: TTS tool fails when packages are installed via PYTHONPATH
ComponentText-to-speech provider import helpers
Files changedtools/tts_tool.py, tests/tools/test_tts_lazy_import_fallback.py
Pull request#53289

Before choosing this issue, we screened other candidate issues and skipped the ones that already had competing pull requests or unclear design direction. That screening step was useful: a small first contribution should be technically narrow and socially low-friction.

Bug summary

Hermes can lazily install optional TTS dependencies such as ElevenLabs or Edge TTS. The reported bug was that the import helpers gave up immediately when tools.lazy_deps.ensure() failed.

That is too strict for some valid deployments. In containers, shared environments, or custom installations, a package may be available on PYTHONPATH even though Hermes cannot install it into the active virtual environment.

The expected behavior is:

try lazy dependency setup
if that fails, continue to normal Python import
if the package is truly missing, let the normal import raise ImportError

Fix

The fix changed the TTS provider import helpers so that a lazy dependency failure is logged and the helper continues to the raw import path. This was applied to the relevant TTS import helpers, including Edge TTS, ElevenLabs, and Mistral.

The change was intentionally small. It did not redesign dependency management. It only corrected the fallback behavior.

Regression test

The new test file creates fake importable modules, forces tools.lazy_deps.ensure() to fail, then verifies that the corresponding TTS import helper still succeeds through the normal import path.

The test covers:

This made the failure mode reproducible without requiring real ElevenLabs, Edge TTS, or Mistral credentials.

Verification performed

CheckResult
New regression test before fixFailed, confirming the bug
New regression test after fixPassed
Relevant TTS test suite293 passed
Ruff on touched filesPassed
Broad tests/tools runTimed out due to broader environment/test-suite scope; not claimed as passing

The last row matters. A failed or timed-out broad run should not be represented as a successful full-suite verification. The PR evidence should say what was actually run.

Commit and PR details

commit fde29c270
fix(tts): fall back to raw imports after lazy install failure

2 files changed, 73 insertions(+), 7 deletions(-)
create mode 100644 tests/tools/test_tts_lazy_import_fallback.py

The branch was pushed from a fork using the standard fork-and-PR workflow:

jmeadlock:fix/53259-tts-lazy-import-fallback
→ NousResearch/hermes-agent:main

Process notes

The main value of the exercise was learning the contribution process rather than the size of the patch. The useful sequence was:

  1. Screen candidate issues for competing PRs and design ambiguity.
  2. Pick a narrow, recent, reproducible bug.
  3. Comment on the issue before starting work.
  4. Create a branch from a clean, current main.
  5. Write a regression test first.
  6. Make the smallest code change that fixes the failing behavior.
  7. Run scoped verification and lint.
  8. Review the diff before committing.
  9. Push to the fork and open a PR with verification notes.

Takeaway

A small bug is a good first contribution target. It keeps the technical surface area limited while still exercising the real workflow: issue triage, branching, tests, implementation, verification, and PR submission.

AI assistance helped with navigation, test construction, and review. It did not remove the need for process discipline. The useful pattern was not “ask an AI to write code.” It was using an AI coach to keep the work scoped, testable, and reviewable.


Published at al-engr.com/first-oss-bug-with-ai-coach.html.