feat(telnyx): add Telnyx LLM plugin - #620
Conversation
📝 WalkthroughWalkthroughAdds a TelnyxLLM wrapper for Telnyx’s OpenAI-compatible Chat Completions endpoint, including API-key resolution, default model configuration, streaming, and tool-calling support through ChatCompletionsLLM. Exposes the wrapper as the Telnyx package’s LLM alias, adds the OpenAI plugin dependency and workspace mapping, updates documentation, and introduces unit and conditional integration tests. 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
plugins/telnyx/vision_agents/plugins/telnyx/llm.py (1)
16-16: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse modern nullable annotations.
Replace
Optional[...]with... | Noneand remove thetyping.Optionalimport. As per coding guidelines, use modernX | Yunions.Proposed change
-from typing import Optional - ... - api_key: Optional[str] = None, + api_key: str | None = None, ... - client: Optional[AsyncOpenAI] = None, + client: AsyncOpenAI | None = None,Also applies to: 44-46
Source: Coding guidelines
plugins/telnyx/tests/test_telnyx_llm.py (2)
17-94: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd annotations to test methods and fixtures.
The new tests omit parameter and return annotations. As per coding guidelines, use type annotations everywhere.
Examples
- def test_requires_api_key(self, monkeypatch): + def test_requires_api_key(self, monkeypatch: pytest.MonkeyPatch) -> None: - async def llm(self): + async def llm(self) -> LLM: - async def test_simple_response(self, llm): + async def test_simple_response(self, llm: LLM) -> None:Source: Coding guidelines
42-43: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMove
AsyncOpenAIto module scope.Local imports violate the repository import policy. As per coding guidelines, import at the top of the module.
Proposed change
+from openai import AsyncOpenAI from dotenv import load_dotenv ... - from openai import AsyncOpenAI -Source: Coding guidelines
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: e2163ae6-f03b-4670-8c68-be2cf3ebe986
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (5)
plugins/telnyx/README.mdplugins/telnyx/pyproject.tomlplugins/telnyx/tests/test_telnyx_llm.pyplugins/telnyx/vision_agents/plugins/telnyx/__init__.pyplugins/telnyx/vision_agents/plugins/telnyx/llm.py
Telnyx Inference serves an OpenAI-compatible /v2/ai/chat/completions endpoint, so the LLM is a thin ChatCompletionsLLM subclass pointed at the Telnyx base URL with bearer auth. Follows the plugins/sarvam precedent of one vendor plugin covering LLM, STT, and TTS.
There was a problem hiding this comment.
🧹 Nitpick comments (4)
plugins/telnyx/vision_agents/plugins/telnyx/llm.py (1)
16-16: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueUse modern union annotations.
Replace
Optional[str]andOptional[AsyncOpenAI]withstr | NoneandAsyncOpenAI | None.Proposed change
-from typing import Optional - ... - api_key: Optional[str] = None, + api_key: str | None = None, ... - client: Optional[AsyncOpenAI] = None, + client: AsyncOpenAI | None = None,As per coding guidelines, use modern
X | Yunions for nullable types.Also applies to: 44-46
Source: Coding guidelines
plugins/telnyx/tests/test_telnyx_llm.py (3)
17-17: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd test parameter and return annotations.
Annotate
monkeypatch, thellmfixture, fixture consumers, and function return types. As per coding guidelines, use type annotations everywhere.Also applies to: 22-22, 26-26, 30-30, 34-34, 38-38, 42-42, 57-57, 62-62, 69-69, 76-76
Source: Coding guidelines
30-48: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAvoid assertions on
LLM._client.Lines 32, 36, and 48 couple tests to private client storage and object identity. Cover endpoint/auth/client-injection through observable behavior or a stable public configuration contract instead. As per path instructions, tests must assert behavior and outputs rather than initialization or call paths.
Source: Path instructions
43-43: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueMove
AsyncOpenAIto module imports.Local imports are disallowed; place it with the other third-party imports. As per coding guidelines, do not use local imports.
Source: Coding guidelines
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 31ae4e5a-10e5-4f83-864e-3f16b43dafb1
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (5)
plugins/telnyx/README.mdplugins/telnyx/pyproject.tomlplugins/telnyx/tests/test_telnyx_llm.pyplugins/telnyx/vision_agents/plugins/telnyx/__init__.pyplugins/telnyx/vision_agents/plugins/telnyx/llm.py
🚧 Files skipped from review as they are similar to previous changes (1)
- plugins/telnyx/README.md
Adds a Telnyx LLM to the existing
plugins/telnyx/package, which today onlycontains the media streaming transport from #594.
Telnyx Inference serves
/v2/ai/chat/completionswith the same request andresponse shape as OpenAI, so this is a thin
ChatCompletionsLLMsubclass withthe base URL set to
https://api.telnyx.com/v2/aiand standard bearer auth.Streaming, tool calling, and conversation history come from the base class.
The pattern precedent is
plugins/sarvam/, which keepsllm.py,stt.py, andtts.pyin one vendor plugin. STT and TTS for Telnyx are separate PRs so eachlands independently.
What it adds
plugins/telnyx/vision_agents/plugins/telnyx/llm.pyLLM/TelnyxLLMexports in the plugin__init__.pyvision-agents-plugins-openaidependency in the pluginpyproject.tomlplugins/telnyx/tests/test_telnyx_llm.pyNotes
Model ids are not validated locally. The served catalogue comes from
GET /v2/ai/modelsand changes over time, so a hardcoded allowlist would gostale. The default is
meta-llama/Llama-3.3-70B-Instruct.Testing
Verified against the live Telnyx API, not from docs alone.
uv run ruff check .andruff format --check .passuv run dev.py mypyanddev.py mypy-pluginspassuv run dev.py validate-extraspassesuv run pytest -m "not integration" plugins/telnyx/tests/passes, 38 testsuv run pytest -m integration plugins/telnyx/tests/test_telnyx_llm.pypasseswith a real
TELNYX_API_KEY, 3 tests covering a simple response, streameddeltas, and a round trip through
register_functiontool callinguv.lockchanges by two lines, for the new workspace dependency.Relation to the other two Telnyx PRs
This is one of three independent PRs, each branched off
main, not stacked:#620 LLM, #621 TTS, #622 STT. Each touches the plugin
__init__.py,pyproject.toml,README.md, and two lines ofuv.lock, so whichever landsfirst leaves the other two with small conflicts in those four files. Happy to
rebase on request, or to fold all three into one PR if you would rather review
them together.