langchain-gmi 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,30 @@
1
+ name: CI
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ test:
7
+ runs-on: ubuntu-latest
8
+ strategy:
9
+ fail-fast: false
10
+ matrix:
11
+ python: ["3.10", "3.11", "3.12", "3.13"]
12
+ dependencies: [latest]
13
+ include:
14
+ - python: "3.10"
15
+ dependencies: minimum
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - uses: actions/setup-python@v5
19
+ with:
20
+ python-version: ${{ matrix.python }}
21
+ - run: python -m pip install -e ".[dev]"
22
+ - if: matrix.dependencies == 'minimum'
23
+ run: >-
24
+ python -m pip install
25
+ langchain-openai==0.2.0 langchain-core==0.3.0
26
+ httpx==0.27.0 openai==1.40.0 pydantic==2.5.2
27
+ - run: ruff check .
28
+ - run: ruff format --check .
29
+ - run: pytest
30
+ - run: python -m build
@@ -0,0 +1,16 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ .venv/
5
+ .venv-*/
6
+ .env
7
+ .env.*
8
+ !.env.example
9
+ dist/
10
+ build/
11
+ .pytest_cache/
12
+ .ruff_cache/
13
+ .coverage
14
+ htmlcov/
15
+ .idea/
16
+ .vscode/
@@ -0,0 +1,15 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 - 2026-11-14
4
+
5
+ Initial release of the community LangChain integration for GMI Cloud.
6
+
7
+ - `ChatGMI` with GMI authentication and endpoint defaults.
8
+ - Six convenience model aliases and arbitrary raw model IDs.
9
+ - Sync and async chat and streaming through Chat Completions.
10
+ - OpenAI-style tool calling and Pydantic structured output.
11
+ - Provider metadata for LangChain runs.
12
+ - `list_gmi_models` with API metadata and normalized context lengths.
13
+ - Offline tests, examples, MIT license, and CI configuration.
14
+
15
+ Live functional checks passed with `deepseek-ai/deepseek-v4.1-flash-1017`.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 langchain-gmi contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,236 @@
1
+ Metadata-Version: 2.5
2
+ Name: langchain-gmi
3
+ Version: 0.1.0
4
+ Summary: LangChain chat models for GMI Cloud's OpenAI-compatible Inference Engine
5
+ Project-URL: Homepage, https://github.com/dhruvil-codes/langchain-gmi
6
+ Project-URL: Documentation, https://github.com/dhruvil-codes/langchain-gmi#readme
7
+ Project-URL: Repository, https://github.com/dhruvil-codes/langchain-gmi
8
+ Project-URL: Issues, https://github.com/dhruvil-codes/langchain-gmi/issues
9
+ Project-URL: Changelog, https://github.com/dhruvil-codes/langchain-gmi/blob/main/CHANGELOG.md
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: gmi,inference,langchain,llm
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Typing :: Typed
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: httpx<1.0,>=0.27.0
23
+ Requires-Dist: langchain-core<2.0.0,>=0.3.0
24
+ Requires-Dist: langchain-openai<2.0.0,>=0.2.0
25
+ Requires-Dist: pydantic<3.0,>=2.0
26
+ Provides-Extra: dev
27
+ Requires-Dist: build>=1.2; extra == 'dev'
28
+ Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
29
+ Requires-Dist: pytest>=8; extra == 'dev'
30
+ Requires-Dist: ruff>=0.9; extra == 'dev'
31
+ Requires-Dist: twine>=6; extra == 'dev'
32
+ Description-Content-Type: text/markdown
33
+
34
+ # langchain-gmi
35
+
36
+ [![GMI Cloud](https://img.shields.io/badge/GMI%20Cloud-Inference-5B5BD6)](https://www.gmicloud.ai/en/developers) [![Python](https://img.shields.io/badge/Python-3.10%2B-blue)](https://www.python.org/)
37
+
38
+ LangChain integration for GMI Cloud's OpenAI-compatible Inference Engine. Access DeepSeek V3.2, Claude Sonnet 4.5, and open models through one endpoint, alongside GMI Cloud's NVIDIA H100 GPU inference infrastructure. This is a community integration.
39
+
40
+ ## Install
41
+
42
+ ```bash
43
+ pip install langchain-gmi
44
+ ```
45
+
46
+ Set an API key in your environment:
47
+
48
+ ```bash
49
+ export GMI_API_KEY="your-gmi-api-key"
50
+ ```
51
+
52
+ PowerShell:
53
+
54
+ ```powershell
55
+ $env:GMI_API_KEY = "your-gmi-api-key"
56
+ ```
57
+
58
+ Requires Python 3.10 or newer. The default endpoint is `https://api.gmi-serving.com/v1`. The integration accepts `gmi_api_key`, `api_key`, or `openai_api_key`; `GMI_API_KEY` is the environment variable fallback. Explicit credentials take precedence. Missing or empty credentials raise `ValueError` during construction. `OPENAI_API_KEY` and OpenAI endpoint environment variables are not used to configure this provider.
59
+
60
+ ```python
61
+ llm = ChatGMI(
62
+ model="deepseek-v3.2",
63
+ # gmi_api_key=secret_from_your_secret_manager,
64
+ base_url="https://api.gmi-serving.com/v1",
65
+ timeout=60,
66
+ max_retries=2,
67
+ metadata={"application": "support"},
68
+ )
69
+ ```
70
+
71
+ Runs include `provider="gmi-cloud"` metadata and `ls_provider="gmi-cloud"` for tracing. API keys use Pydantic secret fields and are excluded from provider-specific exports.
72
+
73
+ ## Quickstart
74
+
75
+ ```python
76
+ from langchain_gmi import ChatGMI
77
+
78
+ llm = ChatGMI(model="deepseek-v3.2")
79
+ response = llm.invoke("What makes GMI Cloud H100 clusters fast?")
80
+ print(response.content)
81
+ ```
82
+
83
+ `ChatGMI` inherits LangChain's chat model methods, including `invoke`/`ainvoke`, `stream`/`astream`, `bind_tools`, and `with_structured_output`. Availability and behavior of model capabilities depend on the selected model and the API's current support.
84
+
85
+ ## Async and streaming
86
+
87
+ ```python
88
+ import asyncio
89
+
90
+ from langchain_gmi import ChatGMI
91
+
92
+
93
+ async def main() -> None:
94
+ llm = ChatGMI(model="deepseek-v3.2")
95
+
96
+ response = await llm.ainvoke("Give me a one-sentence summary of inference APIs.")
97
+ print(response.content)
98
+
99
+ async for chunk in llm.astream("Count from one to three."):
100
+ print(chunk.content, end="", flush=True)
101
+ print()
102
+
103
+
104
+ if __name__ == "__main__":
105
+ asyncio.run(main())
106
+ ```
107
+
108
+ For synchronous streaming:
109
+
110
+ ```python
111
+ for chunk in llm.stream("Count from one to three."):
112
+ print(chunk.content, end="", flush=True)
113
+ ```
114
+
115
+ If your selected model supports usage reporting, pass `stream_options={"include_usage": True}` to `stream` or `astream` and inspect the final chunk's `usage_metadata`. Streaming usage requests are opt-in for this endpoint. Recent `langchain-openai` versions also accept `stream_usage=True`.
116
+
117
+ ## Tool calling
118
+
119
+ Bind LangChain tools to the model, then invoke it with a message. The model may return tool calls in `AIMessage.tool_calls`; your application is responsible for executing them and returning the results.
120
+
121
+ ```python
122
+ from langchain_core.tools import tool
123
+
124
+ from langchain_gmi import ChatGMI
125
+
126
+
127
+ @tool
128
+ def multiply(a: int, b: int) -> int:
129
+ """Multiply two integers."""
130
+ return a * b
131
+
132
+
133
+ llm = ChatGMI(model="deepseek-v3.2").bind_tools([multiply])
134
+ message = llm.invoke("What is 6 times 7?")
135
+ print(message.tool_calls)
136
+ ```
137
+
138
+ See [`examples/02_agent_with_tools.py`](https://github.com/dhruvil-codes/langchain-gmi/blob/main/examples/02_agent_with_tools.py) for a bounded tool loop with calculator and web search tools.
139
+
140
+ ## Structured output
141
+
142
+ Use a Pydantic model to validate extracted fields:
143
+
144
+ ```python
145
+ from pydantic import BaseModel, Field
146
+
147
+ from langchain_gmi import ChatGMI
148
+
149
+
150
+ class SupportTicket(BaseModel):
151
+ """Fields extracted from a short support request."""
152
+
153
+ category: str = Field(description="Short issue category")
154
+ urgency: int = Field(ge=1, le=5, description="Urgency from 1 (low) to 5 (high)")
155
+ summary: str
156
+
157
+
158
+ extract = ChatGMI(model="deepseek-v3.2").with_structured_output(SupportTicket)
159
+ ticket = extract.invoke("My account is locked and our team is blocked from a deadline.")
160
+ print(ticket)
161
+ ```
162
+
163
+ The integration's default structured-output strategy is `function_calling`. See [`examples/03_structured_output.py`](https://github.com/dhruvil-codes/langchain-gmi/blob/main/examples/03_structured_output.py).
164
+
165
+ ## Models and discovery
166
+
167
+ The short names below are convenience aliases. You can also pass a raw model ID from GMI Cloud's model catalog; other strings pass through unchanged.
168
+
169
+ | `ChatGMI` model | GMI model ID | Upstream context reference |
170
+ | --- | --- | --- |
171
+ | `deepseek-v3.2` | `gmi/deepseek-ai/DeepSeek-V3.2` | [163,840 configured positions](https://huggingface.co/deepseek-ai/DeepSeek-V3.2/blob/main/config.json) |
172
+ | `claude-sonnet-4.5` | `gmi/anthropic/claude-sonnet-4.5` | [200K tokens](https://platform.claude.com/docs/en/models/overview) |
173
+ | `claude-opus-4.5` | `gmi/anthropic/claude-opus-4.5` | [200K tokens](https://platform.claude.com/docs/en/models/overview) |
174
+ | `qwen3-vl` | `gmi/Qwen/Qwen3-VL-235B-A22B-Instruct-FP8` | [256K tokens, native](https://huggingface.co/Qwen/Qwen3-VL-235B-A22B-Instruct) |
175
+ | `gpt-5` | `gmi/openai/gpt-5` | [400,000 tokens](https://developers.openai.com/api/docs/models/gpt-5) |
176
+ | `gemini-3-flash` | `gmi/google/gemini-3-flash-preview` | [1,048,576 input tokens](https://ai.google.dev/gemini-api/docs/models/gemini-3-flash-preview) |
177
+
178
+ These are upstream references, not verified limits for GMI deployments. The DeepSeek value is its model configuration's position limit. Check the GMI catalog for deployment limits and current availability. The aliases above are fixed convenience mappings; use a raw ID from discovery if your account's catalog uses a different ID.
179
+
180
+ `list_gmi_models()` returns each API model record with a normalized `context_length` integer or `None` when the API does not report a value. It recognizes positive integer `context_length`, `max_model_len`, `max_context_length`, and `context_window` fields in that order. It preserves other API metadata and does not infer missing context lengths from this table.
181
+
182
+ ```python
183
+ from langchain_gmi import list_gmi_models
184
+
185
+ for model in list_gmi_models():
186
+ print(model["id"], model["context_length"])
187
+ ```
188
+
189
+ You can also call `list_gmi_models(api_key, base_url=..., timeout=30.0, client=httpx_client)`. A supplied HTTPX client stays open; internally created clients close after the request. HTTP errors raise `httpx.HTTPStatusError`, timeouts propagate, and malformed model-list responses raise `ValueError`. Discovery makes one request without automatic retries.
190
+
191
+ See [`examples/01_basic_chat.py`](https://github.com/dhruvil-codes/langchain-gmi/blob/main/examples/01_basic_chat.py) for chat, streaming, and discovery. GMI's [API reference](https://docs.gmicloud.ai/inference-engine/api-reference/llm-api-reference) documents `GET /v1/models` and `POST /v1/chat/completions`.
192
+
193
+ ## Live validation
194
+
195
+ The integration was tested against GMI Cloud on November 14, 2026 with the catalog model `deepseek-ai/deepseek-v4.1-flash-1017`:
196
+
197
+ ```python
198
+ llm = ChatGMI(model="deepseek-ai/deepseek-v4.1-flash-1017")
199
+ ```
200
+
201
+ Model discovery, sync/async chat, sync/async streaming, tool calling, and Pydantic structured output passed. See the [validation record](https://github.com/dhruvil-codes/langchain-gmi/blob/main/docs/live-validation.md) for scope and dependency versions. These are functional checks, not performance benchmarks.
202
+
203
+ ## How it fits together
204
+
205
+ ```mermaid
206
+ flowchart LR
207
+ A[Your application] --> B[LangChain ChatGMI]
208
+ B -->|OpenAI-compatible chat request| C[GMI Cloud API]
209
+ C --> D[Selected model]
210
+ D -->|chat response or streamed chunks| C
211
+ C --> B
212
+ B --> A
213
+ E[list_gmi_models] -->|GET /v1/models| C
214
+ ```
215
+
216
+ ## Development
217
+
218
+ From a checkout of this repository:
219
+
220
+ ```bash
221
+ pip install -e ".[dev]"
222
+ pytest
223
+ ruff check .
224
+ ruff format --check .
225
+ python -m build
226
+ twine check dist/*
227
+ ```
228
+
229
+ Tests use mocked HTTP transports, with live HTTP blocked. CI checks Python 3.10 through 3.13 and a minimum LangChain dependency configuration. The MIT license is in [LICENSE](https://github.com/dhruvil-codes/langchain-gmi/blob/main/LICENSE).
230
+
231
+ ## Links
232
+
233
+ - [GMI Cloud developers](https://www.gmicloud.ai/en/developers)
234
+ - [GMI Cloud inference API reference](https://docs.gmicloud.ai/inference-engine/api-reference/llm-api-reference)
235
+ - [LangChain chat models](https://docs.langchain.com/oss/python/langchain/models)
236
+ - [GMI Cloud console](https://console.gmicloud.ai/)
@@ -0,0 +1,203 @@
1
+ # langchain-gmi
2
+
3
+ [![GMI Cloud](https://img.shields.io/badge/GMI%20Cloud-Inference-5B5BD6)](https://www.gmicloud.ai/en/developers) [![Python](https://img.shields.io/badge/Python-3.10%2B-blue)](https://www.python.org/)
4
+
5
+ LangChain integration for GMI Cloud's OpenAI-compatible Inference Engine. Access DeepSeek V3.2, Claude Sonnet 4.5, and open models through one endpoint, alongside GMI Cloud's NVIDIA H100 GPU inference infrastructure. This is a community integration.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pip install langchain-gmi
11
+ ```
12
+
13
+ Set an API key in your environment:
14
+
15
+ ```bash
16
+ export GMI_API_KEY="your-gmi-api-key"
17
+ ```
18
+
19
+ PowerShell:
20
+
21
+ ```powershell
22
+ $env:GMI_API_KEY = "your-gmi-api-key"
23
+ ```
24
+
25
+ Requires Python 3.10 or newer. The default endpoint is `https://api.gmi-serving.com/v1`. The integration accepts `gmi_api_key`, `api_key`, or `openai_api_key`; `GMI_API_KEY` is the environment variable fallback. Explicit credentials take precedence. Missing or empty credentials raise `ValueError` during construction. `OPENAI_API_KEY` and OpenAI endpoint environment variables are not used to configure this provider.
26
+
27
+ ```python
28
+ llm = ChatGMI(
29
+ model="deepseek-v3.2",
30
+ # gmi_api_key=secret_from_your_secret_manager,
31
+ base_url="https://api.gmi-serving.com/v1",
32
+ timeout=60,
33
+ max_retries=2,
34
+ metadata={"application": "support"},
35
+ )
36
+ ```
37
+
38
+ Runs include `provider="gmi-cloud"` metadata and `ls_provider="gmi-cloud"` for tracing. API keys use Pydantic secret fields and are excluded from provider-specific exports.
39
+
40
+ ## Quickstart
41
+
42
+ ```python
43
+ from langchain_gmi import ChatGMI
44
+
45
+ llm = ChatGMI(model="deepseek-v3.2")
46
+ response = llm.invoke("What makes GMI Cloud H100 clusters fast?")
47
+ print(response.content)
48
+ ```
49
+
50
+ `ChatGMI` inherits LangChain's chat model methods, including `invoke`/`ainvoke`, `stream`/`astream`, `bind_tools`, and `with_structured_output`. Availability and behavior of model capabilities depend on the selected model and the API's current support.
51
+
52
+ ## Async and streaming
53
+
54
+ ```python
55
+ import asyncio
56
+
57
+ from langchain_gmi import ChatGMI
58
+
59
+
60
+ async def main() -> None:
61
+ llm = ChatGMI(model="deepseek-v3.2")
62
+
63
+ response = await llm.ainvoke("Give me a one-sentence summary of inference APIs.")
64
+ print(response.content)
65
+
66
+ async for chunk in llm.astream("Count from one to three."):
67
+ print(chunk.content, end="", flush=True)
68
+ print()
69
+
70
+
71
+ if __name__ == "__main__":
72
+ asyncio.run(main())
73
+ ```
74
+
75
+ For synchronous streaming:
76
+
77
+ ```python
78
+ for chunk in llm.stream("Count from one to three."):
79
+ print(chunk.content, end="", flush=True)
80
+ ```
81
+
82
+ If your selected model supports usage reporting, pass `stream_options={"include_usage": True}` to `stream` or `astream` and inspect the final chunk's `usage_metadata`. Streaming usage requests are opt-in for this endpoint. Recent `langchain-openai` versions also accept `stream_usage=True`.
83
+
84
+ ## Tool calling
85
+
86
+ Bind LangChain tools to the model, then invoke it with a message. The model may return tool calls in `AIMessage.tool_calls`; your application is responsible for executing them and returning the results.
87
+
88
+ ```python
89
+ from langchain_core.tools import tool
90
+
91
+ from langchain_gmi import ChatGMI
92
+
93
+
94
+ @tool
95
+ def multiply(a: int, b: int) -> int:
96
+ """Multiply two integers."""
97
+ return a * b
98
+
99
+
100
+ llm = ChatGMI(model="deepseek-v3.2").bind_tools([multiply])
101
+ message = llm.invoke("What is 6 times 7?")
102
+ print(message.tool_calls)
103
+ ```
104
+
105
+ See [`examples/02_agent_with_tools.py`](https://github.com/dhruvil-codes/langchain-gmi/blob/main/examples/02_agent_with_tools.py) for a bounded tool loop with calculator and web search tools.
106
+
107
+ ## Structured output
108
+
109
+ Use a Pydantic model to validate extracted fields:
110
+
111
+ ```python
112
+ from pydantic import BaseModel, Field
113
+
114
+ from langchain_gmi import ChatGMI
115
+
116
+
117
+ class SupportTicket(BaseModel):
118
+ """Fields extracted from a short support request."""
119
+
120
+ category: str = Field(description="Short issue category")
121
+ urgency: int = Field(ge=1, le=5, description="Urgency from 1 (low) to 5 (high)")
122
+ summary: str
123
+
124
+
125
+ extract = ChatGMI(model="deepseek-v3.2").with_structured_output(SupportTicket)
126
+ ticket = extract.invoke("My account is locked and our team is blocked from a deadline.")
127
+ print(ticket)
128
+ ```
129
+
130
+ The integration's default structured-output strategy is `function_calling`. See [`examples/03_structured_output.py`](https://github.com/dhruvil-codes/langchain-gmi/blob/main/examples/03_structured_output.py).
131
+
132
+ ## Models and discovery
133
+
134
+ The short names below are convenience aliases. You can also pass a raw model ID from GMI Cloud's model catalog; other strings pass through unchanged.
135
+
136
+ | `ChatGMI` model | GMI model ID | Upstream context reference |
137
+ | --- | --- | --- |
138
+ | `deepseek-v3.2` | `gmi/deepseek-ai/DeepSeek-V3.2` | [163,840 configured positions](https://huggingface.co/deepseek-ai/DeepSeek-V3.2/blob/main/config.json) |
139
+ | `claude-sonnet-4.5` | `gmi/anthropic/claude-sonnet-4.5` | [200K tokens](https://platform.claude.com/docs/en/models/overview) |
140
+ | `claude-opus-4.5` | `gmi/anthropic/claude-opus-4.5` | [200K tokens](https://platform.claude.com/docs/en/models/overview) |
141
+ | `qwen3-vl` | `gmi/Qwen/Qwen3-VL-235B-A22B-Instruct-FP8` | [256K tokens, native](https://huggingface.co/Qwen/Qwen3-VL-235B-A22B-Instruct) |
142
+ | `gpt-5` | `gmi/openai/gpt-5` | [400,000 tokens](https://developers.openai.com/api/docs/models/gpt-5) |
143
+ | `gemini-3-flash` | `gmi/google/gemini-3-flash-preview` | [1,048,576 input tokens](https://ai.google.dev/gemini-api/docs/models/gemini-3-flash-preview) |
144
+
145
+ These are upstream references, not verified limits for GMI deployments. The DeepSeek value is its model configuration's position limit. Check the GMI catalog for deployment limits and current availability. The aliases above are fixed convenience mappings; use a raw ID from discovery if your account's catalog uses a different ID.
146
+
147
+ `list_gmi_models()` returns each API model record with a normalized `context_length` integer or `None` when the API does not report a value. It recognizes positive integer `context_length`, `max_model_len`, `max_context_length`, and `context_window` fields in that order. It preserves other API metadata and does not infer missing context lengths from this table.
148
+
149
+ ```python
150
+ from langchain_gmi import list_gmi_models
151
+
152
+ for model in list_gmi_models():
153
+ print(model["id"], model["context_length"])
154
+ ```
155
+
156
+ You can also call `list_gmi_models(api_key, base_url=..., timeout=30.0, client=httpx_client)`. A supplied HTTPX client stays open; internally created clients close after the request. HTTP errors raise `httpx.HTTPStatusError`, timeouts propagate, and malformed model-list responses raise `ValueError`. Discovery makes one request without automatic retries.
157
+
158
+ See [`examples/01_basic_chat.py`](https://github.com/dhruvil-codes/langchain-gmi/blob/main/examples/01_basic_chat.py) for chat, streaming, and discovery. GMI's [API reference](https://docs.gmicloud.ai/inference-engine/api-reference/llm-api-reference) documents `GET /v1/models` and `POST /v1/chat/completions`.
159
+
160
+ ## Live validation
161
+
162
+ The integration was tested against GMI Cloud on November 14, 2026 with the catalog model `deepseek-ai/deepseek-v4.1-flash-1017`:
163
+
164
+ ```python
165
+ llm = ChatGMI(model="deepseek-ai/deepseek-v4.1-flash-1017")
166
+ ```
167
+
168
+ Model discovery, sync/async chat, sync/async streaming, tool calling, and Pydantic structured output passed. See the [validation record](https://github.com/dhruvil-codes/langchain-gmi/blob/main/docs/live-validation.md) for scope and dependency versions. These are functional checks, not performance benchmarks.
169
+
170
+ ## How it fits together
171
+
172
+ ```mermaid
173
+ flowchart LR
174
+ A[Your application] --> B[LangChain ChatGMI]
175
+ B -->|OpenAI-compatible chat request| C[GMI Cloud API]
176
+ C --> D[Selected model]
177
+ D -->|chat response or streamed chunks| C
178
+ C --> B
179
+ B --> A
180
+ E[list_gmi_models] -->|GET /v1/models| C
181
+ ```
182
+
183
+ ## Development
184
+
185
+ From a checkout of this repository:
186
+
187
+ ```bash
188
+ pip install -e ".[dev]"
189
+ pytest
190
+ ruff check .
191
+ ruff format --check .
192
+ python -m build
193
+ twine check dist/*
194
+ ```
195
+
196
+ Tests use mocked HTTP transports, with live HTTP blocked. CI checks Python 3.10 through 3.13 and a minimum LangChain dependency configuration. The MIT license is in [LICENSE](https://github.com/dhruvil-codes/langchain-gmi/blob/main/LICENSE).
197
+
198
+ ## Links
199
+
200
+ - [GMI Cloud developers](https://www.gmicloud.ai/en/developers)
201
+ - [GMI Cloud inference API reference](https://docs.gmicloud.ai/inference-engine/api-reference/llm-api-reference)
202
+ - [LangChain chat models](https://docs.langchain.com/oss/python/langchain/models)
203
+ - [GMI Cloud console](https://console.gmicloud.ai/)
@@ -0,0 +1,21 @@
1
+ # Live validation
2
+
3
+ On November 14, 2026, the package was tested against `https://api.gmi-serving.com/v1` using a private API key supplied by the maintainer. The key is not part of the source, release artifacts, or this record.
4
+
5
+ The selected catalog model was `deepseek-ai/deepseek-v4.1-flash-1017`. Discovery returned 75 models and reported `context_length=1048575` for the selected model. These values are a snapshot of that account's response.
6
+
7
+ | Check | Result | Observed behavior |
8
+ | --- | --- | --- |
9
+ | Model discovery | Passed | Authenticated `GET /v1/models` returned the catalog |
10
+ | Sync chat | Passed | `invoke` returned `OK` with finish reason `stop` |
11
+ | Async chat | Passed | `ainvoke` returned `OK` |
12
+ | Sync streaming | Passed | Streamed content assembled to `OK` |
13
+ | Async streaming | Passed | Async streamed content assembled to `OK` |
14
+ | Tool calling | Passed | Forced `Add` tool call returned arguments `a=2, b=3` |
15
+ | Structured output | Passed | Default function-calling strategy parsed `Answer(answer=5)` with no parsing error |
16
+
17
+ Live requests used `max_tokens=1024`, a 60-second timeout, and no automatic retries. The environment used Python 3.13.11, `langchain-openai==1.8.0`, `langchain-core==1.8.0`, `pydantic==2.14.3`, `httpx==0.28.1`, and `openai==3.51.0`.
18
+
19
+ Separately, all 73 offline tests passed under the current dependency configuration and under Python 3.11.11 with `langchain-openai==0.2.0`, `langchain-core==0.3.0`, `pydantic==2.5.2`, `httpx==0.27.0`, and `openai==1.40.0`. Ruff lint and format checks passed, and wheel and source distributions built successfully.
20
+
21
+ These checks establish basic functional compatibility for this model and account at the time of testing. They do not measure latency, throughput, GPU hardware, reliability under load, or feature support across every model.
@@ -0,0 +1,26 @@
1
+ """Basic ChatGMI usage and model discovery.
2
+
3
+ Set ``GMI_API_KEY`` before running. Calls are made only from ``main`` so this
4
+ file can be imported without contacting the API.
5
+ """
6
+
7
+ from langchain_gmi import ChatGMI, list_gmi_models
8
+
9
+
10
+ def main() -> None:
11
+ llm = ChatGMI(model="deepseek-v3.2")
12
+ response = llm.invoke("What makes GMI Cloud H100 clusters fast?")
13
+ print(response.content)
14
+
15
+ print("\nStreaming:")
16
+ for chunk in llm.stream("Explain GPU inference in one sentence."):
17
+ print(chunk.content, end="", flush=True)
18
+ print()
19
+
20
+ print("\nModels available to this API key:")
21
+ for model in list_gmi_models():
22
+ print(f"- {model['id']}: context_length={model['context_length']}")
23
+
24
+
25
+ if __name__ == "__main__":
26
+ main()