Skip to content

feat: add Google Gemini and HuggingFace provider adapters#17

Merged
arieradle merged 4 commits intomainfrom
feat/gemini-huggingface-adapters
Mar 12, 2026
Merged

feat: add Google Gemini and HuggingFace provider adapters#17
arieradle merged 4 commits intomainfrom
feat/gemini-huggingface-adapters

Conversation

@arieradle
Copy link
Owner

Summary

  • GeminiAdapter — patches google.genai.models.Models.generate_content (sync) and generate_content_stream (streaming) to track token usage via usage_metadata; supports fallback model validation for gemini provider
  • HuggingFaceAdapter — patches InferenceClient.chat_completion with OpenAI-compatible token extraction; gracefully handles missing usage in streaming responses
  • New pricing entries for gemini-2.0-flash, gemini-2.5-flash, gemini-2.5-pro
  • New optional extras: pip install shekel[gemini] and pip install shekel[huggingface]
  • Integration tests, unit tests, examples (examples/gemini_demo.py, examples/huggingface_demo.py), and docs (docs/integrations/gemini.md, docs/integrations/huggingface.md)
  • CI: adds HUGGING_FACE_API secret to integration test step

Test plan

  • Unit tests pass: pytest tests/providers/test_gemini_adapter.py tests/providers/test_huggingface_adapter.py -v
  • All non-integration tests pass: pytest tests/ --ignore=tests/integrations --ignore=tests/performance
  • Integration tests pass with valid GEMINI_API_KEY and HUGGING_FACE_API secrets set
  • Verify pip install shekel[gemini] and pip install shekel[huggingface] install correctly
  • Confirm docs render with mkdocs serve

🤖 Generated with Claude Code

- GeminiAdapter patches `google.genai.models.Models.generate_content` and
  `generate_content_stream` to track tokens via `usage_metadata`
- HuggingFaceAdapter patches `InferenceClient.chat_completion` with OpenAI-
  compatible token extraction; handles missing usage in streaming gracefully
- New pricing entries: gemini-2.0-flash, gemini-2.5-flash, gemini-2.5-pro
- Cross-provider fallback validation extended to gemini and huggingface
- Integration tests, unit tests, examples, and docs for both adapters
- New optional extras: `shekel[gemini]`, `shekel[huggingface]`
- CI: adds HUGGING_FACE_API secret to integration test step

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@codecov
Copy link

codecov bot commented Mar 12, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

arieradle and others added 3 commits March 12, 2026 19:01
Add tests for all previously uncovered lines in shekel/_patch.py,
shekel/providers/gemini.py, and shekel/providers/huggingface.py:

- _validate_same_provider: gemini/huggingface cross-provider rejection
- _gemini_sync_wrapper / _gemini_stream_wrapper: normal flow + no-original error
- _wrap_gemini_stream: attribute error handling + usage recording
- _extract_gemini_tokens: AttributeError and None usage_metadata paths
- _huggingface_sync_wrapper: non-stream, stream, and no-original paths
- _wrap_huggingface_stream: attribute error handling + usage recording
- GeminiAdapter.remove_patches(): ImportError path
- GeminiAdapter.wrap_stream(): AttributeError on broken usage_metadata
- HuggingFaceAdapter.remove_patches(): ImportError path
- HuggingFaceAdapter.wrap_stream(): AttributeError on broken usage

Key insight: budget() calls install_patches() on entry, which overwrites
_originals — tests that use budget() must include the adapter's sentinel keys
in patch.dict to prevent re-installation from overwriting test fakes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…files

Add CLAUDE.md naming rule: test files must be organized by domain,
not by implementation unit or coverage goal.

Deleted:
- tests/test_patch_coverage.py — generic coverage-focused file
- tests/test_patching.py — generic patching file

Added domain-organized files:
- tests/test_openai_wrappers.py   — OpenAI sync/async wrapper edge cases
- tests/test_anthropic_wrappers.py — Anthropic sync/async wrapper edge cases
- tests/test_litellm_wrappers.py  — LiteLLM sync/async wrapper edge cases
- tests/test_gemini_wrappers.py   — Gemini sync/stream wrapper edge cases
- tests/test_huggingface_wrappers.py — HuggingFace sync/stream wrapper edge cases

Moved into existing files:
- Cross-provider fallback validation tests → tests/test_fallback.py
- _record exception-swallowing tests → tests/test_budget.py

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ini and HuggingFace

Add test_gemini_import_error_is_swallowed and
test_huggingface_import_error_is_swallowed to TestAdapterRegistrySingleton,
following the existing litellm pattern: reload shekel.providers with the
submodule blocked in sys.modules to exercise lines 30-31 and 37-38.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@arieradle arieradle merged commit 107b917 into main Mar 12, 2026
9 checks passed
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