traceAI-minimax 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.
- traceai_minimax-0.1.0/PKG-INFO +291 -0
- traceai_minimax-0.1.0/README.md +259 -0
- traceai_minimax-0.1.0/pyproject.toml +41 -0
- traceai_minimax-0.1.0/traceai_minimax/__init__.py +106 -0
- traceai_minimax-0.1.0/traceai_minimax/_request_attributes_extractor.py +115 -0
- traceai_minimax-0.1.0/traceai_minimax/_response_attributes_extractor.py +190 -0
- traceai_minimax-0.1.0/traceai_minimax/_utils.py +91 -0
- traceai_minimax-0.1.0/traceai_minimax/_with_span.py +40 -0
- traceai_minimax-0.1.0/traceai_minimax/_wrappers.py +274 -0
- traceai_minimax-0.1.0/traceai_minimax/version.py +1 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: traceAI-minimax
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: OpenTelemetry instrumentation for MiniMax - chat completions via OpenAI-compatible API
|
|
5
|
+
License: Apache-2.0
|
|
6
|
+
Keywords: traceai,futureagi,opentelemetry,tracing,observability,llm,minimax
|
|
7
|
+
Author: Future AGI
|
|
8
|
+
Author-email: no-reply@futureagi.com
|
|
9
|
+
Requires-Python: >=3.10,<3.14
|
|
10
|
+
Classifier: Framework :: OpenTelemetry
|
|
11
|
+
Classifier: Framework :: OpenTelemetry :: Instrumentations
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
14
|
+
Classifier: Programming Language :: Python
|
|
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: Programming Language :: Python :: 3 :: Only
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Classifier: Topic :: System :: Monitoring
|
|
23
|
+
Requires-Dist: fi-instrumentation-otel (>=0.1.11)
|
|
24
|
+
Requires-Dist: openai (>=1.0.0)
|
|
25
|
+
Project-URL: Changelog, https://github.com/future-agi/traceAI/releases
|
|
26
|
+
Project-URL: Documentation, https://docs.futureagi.com/docs/tracing
|
|
27
|
+
Project-URL: Homepage, https://futureagi.com
|
|
28
|
+
Project-URL: Issues, https://github.com/future-agi/traceAI/issues
|
|
29
|
+
Project-URL: Repository, https://github.com/future-agi/traceAI/tree/dev/python/frameworks/minimax
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# TraceAI MiniMax Instrumentation
|
|
33
|
+
|
|
34
|
+
OpenTelemetry instrumentation for [MiniMax](https://www.minimax.io/) - chat completions via the OpenAI-compatible API.
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install traceai-minimax
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Features
|
|
43
|
+
|
|
44
|
+
- Automatic tracing of MiniMax API calls via OpenAI SDK
|
|
45
|
+
- Support for MiniMax-M2.7, MiniMax-M2.7-highspeed, MiniMax-M2.5, and MiniMax-M2.5-highspeed models
|
|
46
|
+
- Streaming response support
|
|
47
|
+
- Token usage tracking
|
|
48
|
+
- Function/tool calling support
|
|
49
|
+
- Full OpenTelemetry semantic conventions compliance
|
|
50
|
+
|
|
51
|
+
## Usage
|
|
52
|
+
|
|
53
|
+
### Basic Setup
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from openai import OpenAI
|
|
57
|
+
from opentelemetry import trace
|
|
58
|
+
from opentelemetry.sdk.trace import TracerProvider
|
|
59
|
+
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor
|
|
60
|
+
|
|
61
|
+
from traceai_minimax import MiniMaxInstrumentor
|
|
62
|
+
|
|
63
|
+
# Set up tracing
|
|
64
|
+
provider = TracerProvider()
|
|
65
|
+
provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))
|
|
66
|
+
trace.set_tracer_provider(provider)
|
|
67
|
+
|
|
68
|
+
# Instrument MiniMax
|
|
69
|
+
MiniMaxInstrumentor().instrument(tracer_provider=provider)
|
|
70
|
+
|
|
71
|
+
# Use MiniMax via OpenAI SDK
|
|
72
|
+
client = OpenAI(
|
|
73
|
+
api_key="your-minimax-api-key",
|
|
74
|
+
base_url="https://api.minimax.io/v1"
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
response = client.chat.completions.create(
|
|
78
|
+
model="MiniMax-M2.7",
|
|
79
|
+
messages=[{"role": "user", "content": "Hello!"}]
|
|
80
|
+
)
|
|
81
|
+
print(response.choices[0].message.content)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### MiniMax Chat
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
from openai import OpenAI
|
|
88
|
+
|
|
89
|
+
client = OpenAI(
|
|
90
|
+
api_key="your-minimax-api-key",
|
|
91
|
+
base_url="https://api.minimax.io/v1"
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
# Simple chat
|
|
95
|
+
response = client.chat.completions.create(
|
|
96
|
+
model="MiniMax-M2.7",
|
|
97
|
+
messages=[
|
|
98
|
+
{"role": "system", "content": "You are a helpful assistant."},
|
|
99
|
+
{"role": "user", "content": "What is machine learning?"}
|
|
100
|
+
],
|
|
101
|
+
temperature=0.7,
|
|
102
|
+
max_tokens=1024
|
|
103
|
+
)
|
|
104
|
+
print(response.choices[0].message.content)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Streaming Responses
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
from openai import OpenAI
|
|
111
|
+
|
|
112
|
+
client = OpenAI(
|
|
113
|
+
api_key="your-minimax-api-key",
|
|
114
|
+
base_url="https://api.minimax.io/v1"
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
# Streaming chat
|
|
118
|
+
stream = client.chat.completions.create(
|
|
119
|
+
model="MiniMax-M2.7",
|
|
120
|
+
messages=[{"role": "user", "content": "Tell me a story"}],
|
|
121
|
+
stream=True
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
for chunk in stream:
|
|
125
|
+
if chunk.choices[0].delta.content:
|
|
126
|
+
print(chunk.choices[0].delta.content, end="", flush=True)
|
|
127
|
+
print()
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Function Calling / Tools
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
from openai import OpenAI
|
|
134
|
+
import json
|
|
135
|
+
|
|
136
|
+
client = OpenAI(
|
|
137
|
+
api_key="your-minimax-api-key",
|
|
138
|
+
base_url="https://api.minimax.io/v1"
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
tools = [
|
|
142
|
+
{
|
|
143
|
+
"type": "function",
|
|
144
|
+
"function": {
|
|
145
|
+
"name": "get_weather",
|
|
146
|
+
"description": "Get the current weather for a location",
|
|
147
|
+
"parameters": {
|
|
148
|
+
"type": "object",
|
|
149
|
+
"properties": {
|
|
150
|
+
"location": {
|
|
151
|
+
"type": "string",
|
|
152
|
+
"description": "The city name"
|
|
153
|
+
},
|
|
154
|
+
"unit": {
|
|
155
|
+
"type": "string",
|
|
156
|
+
"enum": ["celsius", "fahrenheit"],
|
|
157
|
+
"description": "Temperature unit"
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
"required": ["location"]
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
|
|
166
|
+
response = client.chat.completions.create(
|
|
167
|
+
model="MiniMax-M2.7",
|
|
168
|
+
messages=[{"role": "user", "content": "What's the weather in Paris?"}],
|
|
169
|
+
tools=tools,
|
|
170
|
+
tool_choice="auto"
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
message = response.choices[0].message
|
|
174
|
+
if message.tool_calls:
|
|
175
|
+
for tool_call in message.tool_calls:
|
|
176
|
+
print(f"Function: {tool_call.function.name}")
|
|
177
|
+
print(f"Arguments: {tool_call.function.arguments}")
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Async Usage
|
|
181
|
+
|
|
182
|
+
```python
|
|
183
|
+
import asyncio
|
|
184
|
+
from openai import AsyncOpenAI
|
|
185
|
+
|
|
186
|
+
async def main():
|
|
187
|
+
client = AsyncOpenAI(
|
|
188
|
+
api_key="your-minimax-api-key",
|
|
189
|
+
base_url="https://api.minimax.io/v1"
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
response = await client.chat.completions.create(
|
|
193
|
+
model="MiniMax-M2.7",
|
|
194
|
+
messages=[{"role": "user", "content": "Hello!"}]
|
|
195
|
+
)
|
|
196
|
+
print(response.choices[0].message.content)
|
|
197
|
+
|
|
198
|
+
asyncio.run(main())
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### JSON Mode
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
from openai import OpenAI
|
|
205
|
+
|
|
206
|
+
client = OpenAI(
|
|
207
|
+
api_key="your-minimax-api-key",
|
|
208
|
+
base_url="https://api.minimax.io/v1"
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
response = client.chat.completions.create(
|
|
212
|
+
model="MiniMax-M2.7",
|
|
213
|
+
messages=[
|
|
214
|
+
{"role": "system", "content": "Output valid JSON only."},
|
|
215
|
+
{"role": "user", "content": "List 3 programming languages with their main use cases"}
|
|
216
|
+
],
|
|
217
|
+
response_format={"type": "json_object"}
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
import json
|
|
221
|
+
data = json.loads(response.choices[0].message.content)
|
|
222
|
+
print(data)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Configuration Options
|
|
226
|
+
|
|
227
|
+
### TraceConfig
|
|
228
|
+
|
|
229
|
+
```python
|
|
230
|
+
from fi_instrumentation import TraceConfig
|
|
231
|
+
from traceai_minimax import MiniMaxInstrumentor
|
|
232
|
+
|
|
233
|
+
config = TraceConfig(
|
|
234
|
+
hide_inputs=False,
|
|
235
|
+
hide_outputs=False,
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
MiniMaxInstrumentor().instrument(
|
|
239
|
+
tracer_provider=provider,
|
|
240
|
+
config=config
|
|
241
|
+
)
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Captured Attributes
|
|
245
|
+
|
|
246
|
+
### Common Attributes
|
|
247
|
+
|
|
248
|
+
| Attribute | Description |
|
|
249
|
+
|-----------|-------------|
|
|
250
|
+
| `fi.span.kind` | "LLM" |
|
|
251
|
+
| `llm.system` | "minimax" |
|
|
252
|
+
| `llm.provider` | "minimax" |
|
|
253
|
+
| `llm.model` | Model name (MiniMax-M2.7, MiniMax-M2.7-highspeed, MiniMax-M2.5, MiniMax-M2.5-highspeed) |
|
|
254
|
+
| `llm.token_count.prompt` | Input token count |
|
|
255
|
+
| `llm.token_count.completion` | Output token count |
|
|
256
|
+
| `llm.token_count.total` | Total token count |
|
|
257
|
+
|
|
258
|
+
### MiniMax-Specific Attributes
|
|
259
|
+
|
|
260
|
+
| Attribute | Description |
|
|
261
|
+
|-----------|-------------|
|
|
262
|
+
| `minimax.response_id` | Unique response ID |
|
|
263
|
+
| `minimax.finish_reason` | Response finish reason (stop, tool_calls, length) |
|
|
264
|
+
| `minimax.tool_calls_count` | Number of tool calls |
|
|
265
|
+
| `minimax.tools_count` | Number of tools provided |
|
|
266
|
+
|
|
267
|
+
## Available Models
|
|
268
|
+
|
|
269
|
+
| Model | Description |
|
|
270
|
+
|-------|-------------|
|
|
271
|
+
| `MiniMax-M2.7` | Latest flagship model with enhanced reasoning and coding |
|
|
272
|
+
| `MiniMax-M2.7-highspeed` | High-speed version of M2.7 for low-latency scenarios |
|
|
273
|
+
| `MiniMax-M2.5` | General-purpose model with 204K context window |
|
|
274
|
+
| `MiniMax-M2.5-highspeed` | Faster inference variant with 204K context window |
|
|
275
|
+
|
|
276
|
+
## Important Notes
|
|
277
|
+
|
|
278
|
+
1. **OpenAI SDK Required**: MiniMax uses the OpenAI-compatible API, so you need the `openai` package installed.
|
|
279
|
+
|
|
280
|
+
2. **Base URL**: Always set `base_url="https://api.minimax.io/v1"` when creating the client.
|
|
281
|
+
|
|
282
|
+
3. **API Key**: Get your API key from the [MiniMax Platform](https://platform.minimax.chat/).
|
|
283
|
+
|
|
284
|
+
4. **Selective Instrumentation**: The instrumentor only traces calls to MiniMax's API. Regular OpenAI API calls are not affected.
|
|
285
|
+
|
|
286
|
+
5. **Temperature**: MiniMax requires temperature to be in the range (0.0, 1.0]. A value of exactly 0 is not accepted.
|
|
287
|
+
|
|
288
|
+
## License
|
|
289
|
+
|
|
290
|
+
Apache-2.0
|
|
291
|
+
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# TraceAI MiniMax Instrumentation
|
|
2
|
+
|
|
3
|
+
OpenTelemetry instrumentation for [MiniMax](https://www.minimax.io/) - chat completions via the OpenAI-compatible API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install traceai-minimax
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- Automatic tracing of MiniMax API calls via OpenAI SDK
|
|
14
|
+
- Support for MiniMax-M2.7, MiniMax-M2.7-highspeed, MiniMax-M2.5, and MiniMax-M2.5-highspeed models
|
|
15
|
+
- Streaming response support
|
|
16
|
+
- Token usage tracking
|
|
17
|
+
- Function/tool calling support
|
|
18
|
+
- Full OpenTelemetry semantic conventions compliance
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
### Basic Setup
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
from openai import OpenAI
|
|
26
|
+
from opentelemetry import trace
|
|
27
|
+
from opentelemetry.sdk.trace import TracerProvider
|
|
28
|
+
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor
|
|
29
|
+
|
|
30
|
+
from traceai_minimax import MiniMaxInstrumentor
|
|
31
|
+
|
|
32
|
+
# Set up tracing
|
|
33
|
+
provider = TracerProvider()
|
|
34
|
+
provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))
|
|
35
|
+
trace.set_tracer_provider(provider)
|
|
36
|
+
|
|
37
|
+
# Instrument MiniMax
|
|
38
|
+
MiniMaxInstrumentor().instrument(tracer_provider=provider)
|
|
39
|
+
|
|
40
|
+
# Use MiniMax via OpenAI SDK
|
|
41
|
+
client = OpenAI(
|
|
42
|
+
api_key="your-minimax-api-key",
|
|
43
|
+
base_url="https://api.minimax.io/v1"
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
response = client.chat.completions.create(
|
|
47
|
+
model="MiniMax-M2.7",
|
|
48
|
+
messages=[{"role": "user", "content": "Hello!"}]
|
|
49
|
+
)
|
|
50
|
+
print(response.choices[0].message.content)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### MiniMax Chat
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from openai import OpenAI
|
|
57
|
+
|
|
58
|
+
client = OpenAI(
|
|
59
|
+
api_key="your-minimax-api-key",
|
|
60
|
+
base_url="https://api.minimax.io/v1"
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
# Simple chat
|
|
64
|
+
response = client.chat.completions.create(
|
|
65
|
+
model="MiniMax-M2.7",
|
|
66
|
+
messages=[
|
|
67
|
+
{"role": "system", "content": "You are a helpful assistant."},
|
|
68
|
+
{"role": "user", "content": "What is machine learning?"}
|
|
69
|
+
],
|
|
70
|
+
temperature=0.7,
|
|
71
|
+
max_tokens=1024
|
|
72
|
+
)
|
|
73
|
+
print(response.choices[0].message.content)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Streaming Responses
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from openai import OpenAI
|
|
80
|
+
|
|
81
|
+
client = OpenAI(
|
|
82
|
+
api_key="your-minimax-api-key",
|
|
83
|
+
base_url="https://api.minimax.io/v1"
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
# Streaming chat
|
|
87
|
+
stream = client.chat.completions.create(
|
|
88
|
+
model="MiniMax-M2.7",
|
|
89
|
+
messages=[{"role": "user", "content": "Tell me a story"}],
|
|
90
|
+
stream=True
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
for chunk in stream:
|
|
94
|
+
if chunk.choices[0].delta.content:
|
|
95
|
+
print(chunk.choices[0].delta.content, end="", flush=True)
|
|
96
|
+
print()
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Function Calling / Tools
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
from openai import OpenAI
|
|
103
|
+
import json
|
|
104
|
+
|
|
105
|
+
client = OpenAI(
|
|
106
|
+
api_key="your-minimax-api-key",
|
|
107
|
+
base_url="https://api.minimax.io/v1"
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
tools = [
|
|
111
|
+
{
|
|
112
|
+
"type": "function",
|
|
113
|
+
"function": {
|
|
114
|
+
"name": "get_weather",
|
|
115
|
+
"description": "Get the current weather for a location",
|
|
116
|
+
"parameters": {
|
|
117
|
+
"type": "object",
|
|
118
|
+
"properties": {
|
|
119
|
+
"location": {
|
|
120
|
+
"type": "string",
|
|
121
|
+
"description": "The city name"
|
|
122
|
+
},
|
|
123
|
+
"unit": {
|
|
124
|
+
"type": "string",
|
|
125
|
+
"enum": ["celsius", "fahrenheit"],
|
|
126
|
+
"description": "Temperature unit"
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
"required": ["location"]
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
|
|
135
|
+
response = client.chat.completions.create(
|
|
136
|
+
model="MiniMax-M2.7",
|
|
137
|
+
messages=[{"role": "user", "content": "What's the weather in Paris?"}],
|
|
138
|
+
tools=tools,
|
|
139
|
+
tool_choice="auto"
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
message = response.choices[0].message
|
|
143
|
+
if message.tool_calls:
|
|
144
|
+
for tool_call in message.tool_calls:
|
|
145
|
+
print(f"Function: {tool_call.function.name}")
|
|
146
|
+
print(f"Arguments: {tool_call.function.arguments}")
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Async Usage
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
import asyncio
|
|
153
|
+
from openai import AsyncOpenAI
|
|
154
|
+
|
|
155
|
+
async def main():
|
|
156
|
+
client = AsyncOpenAI(
|
|
157
|
+
api_key="your-minimax-api-key",
|
|
158
|
+
base_url="https://api.minimax.io/v1"
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
response = await client.chat.completions.create(
|
|
162
|
+
model="MiniMax-M2.7",
|
|
163
|
+
messages=[{"role": "user", "content": "Hello!"}]
|
|
164
|
+
)
|
|
165
|
+
print(response.choices[0].message.content)
|
|
166
|
+
|
|
167
|
+
asyncio.run(main())
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### JSON Mode
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
from openai import OpenAI
|
|
174
|
+
|
|
175
|
+
client = OpenAI(
|
|
176
|
+
api_key="your-minimax-api-key",
|
|
177
|
+
base_url="https://api.minimax.io/v1"
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
response = client.chat.completions.create(
|
|
181
|
+
model="MiniMax-M2.7",
|
|
182
|
+
messages=[
|
|
183
|
+
{"role": "system", "content": "Output valid JSON only."},
|
|
184
|
+
{"role": "user", "content": "List 3 programming languages with their main use cases"}
|
|
185
|
+
],
|
|
186
|
+
response_format={"type": "json_object"}
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
import json
|
|
190
|
+
data = json.loads(response.choices[0].message.content)
|
|
191
|
+
print(data)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Configuration Options
|
|
195
|
+
|
|
196
|
+
### TraceConfig
|
|
197
|
+
|
|
198
|
+
```python
|
|
199
|
+
from fi_instrumentation import TraceConfig
|
|
200
|
+
from traceai_minimax import MiniMaxInstrumentor
|
|
201
|
+
|
|
202
|
+
config = TraceConfig(
|
|
203
|
+
hide_inputs=False,
|
|
204
|
+
hide_outputs=False,
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
MiniMaxInstrumentor().instrument(
|
|
208
|
+
tracer_provider=provider,
|
|
209
|
+
config=config
|
|
210
|
+
)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Captured Attributes
|
|
214
|
+
|
|
215
|
+
### Common Attributes
|
|
216
|
+
|
|
217
|
+
| Attribute | Description |
|
|
218
|
+
|-----------|-------------|
|
|
219
|
+
| `fi.span.kind` | "LLM" |
|
|
220
|
+
| `llm.system` | "minimax" |
|
|
221
|
+
| `llm.provider` | "minimax" |
|
|
222
|
+
| `llm.model` | Model name (MiniMax-M2.7, MiniMax-M2.7-highspeed, MiniMax-M2.5, MiniMax-M2.5-highspeed) |
|
|
223
|
+
| `llm.token_count.prompt` | Input token count |
|
|
224
|
+
| `llm.token_count.completion` | Output token count |
|
|
225
|
+
| `llm.token_count.total` | Total token count |
|
|
226
|
+
|
|
227
|
+
### MiniMax-Specific Attributes
|
|
228
|
+
|
|
229
|
+
| Attribute | Description |
|
|
230
|
+
|-----------|-------------|
|
|
231
|
+
| `minimax.response_id` | Unique response ID |
|
|
232
|
+
| `minimax.finish_reason` | Response finish reason (stop, tool_calls, length) |
|
|
233
|
+
| `minimax.tool_calls_count` | Number of tool calls |
|
|
234
|
+
| `minimax.tools_count` | Number of tools provided |
|
|
235
|
+
|
|
236
|
+
## Available Models
|
|
237
|
+
|
|
238
|
+
| Model | Description |
|
|
239
|
+
|-------|-------------|
|
|
240
|
+
| `MiniMax-M2.7` | Latest flagship model with enhanced reasoning and coding |
|
|
241
|
+
| `MiniMax-M2.7-highspeed` | High-speed version of M2.7 for low-latency scenarios |
|
|
242
|
+
| `MiniMax-M2.5` | General-purpose model with 204K context window |
|
|
243
|
+
| `MiniMax-M2.5-highspeed` | Faster inference variant with 204K context window |
|
|
244
|
+
|
|
245
|
+
## Important Notes
|
|
246
|
+
|
|
247
|
+
1. **OpenAI SDK Required**: MiniMax uses the OpenAI-compatible API, so you need the `openai` package installed.
|
|
248
|
+
|
|
249
|
+
2. **Base URL**: Always set `base_url="https://api.minimax.io/v1"` when creating the client.
|
|
250
|
+
|
|
251
|
+
3. **API Key**: Get your API key from the [MiniMax Platform](https://platform.minimax.chat/).
|
|
252
|
+
|
|
253
|
+
4. **Selective Instrumentation**: The instrumentor only traces calls to MiniMax's API. Regular OpenAI API calls are not affected.
|
|
254
|
+
|
|
255
|
+
5. **Temperature**: MiniMax requires temperature to be in the range (0.0, 1.0]. A value of exactly 0 is not accepted.
|
|
256
|
+
|
|
257
|
+
## License
|
|
258
|
+
|
|
259
|
+
Apache-2.0
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "traceAI-minimax"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "OpenTelemetry instrumentation for MiniMax - chat completions via OpenAI-compatible API"
|
|
5
|
+
authors = ["Future AGI <no-reply@futureagi.com>"]
|
|
6
|
+
readme = "README.md"
|
|
7
|
+
packages = [
|
|
8
|
+
{ include = "traceai_minimax" }
|
|
9
|
+
]
|
|
10
|
+
license = "Apache-2.0"
|
|
11
|
+
keywords = ["traceai", "futureagi", "opentelemetry", "tracing", "observability", "llm", "minimax"]
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Intended Audience :: Developers",
|
|
14
|
+
"License :: OSI Approved :: Apache Software License",
|
|
15
|
+
"Programming Language :: Python",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
18
|
+
"Programming Language :: Python :: 3.10",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
22
|
+
"Framework :: OpenTelemetry",
|
|
23
|
+
"Framework :: OpenTelemetry :: Instrumentations",
|
|
24
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
25
|
+
"Topic :: System :: Monitoring",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
[tool.poetry.dependencies]
|
|
29
|
+
python = ">=3.10,<3.14"
|
|
30
|
+
fi-instrumentation-otel = ">=0.1.11"
|
|
31
|
+
openai = ">=1.0.0"
|
|
32
|
+
|
|
33
|
+
[tool.poetry.urls]
|
|
34
|
+
Homepage = "https://futureagi.com"
|
|
35
|
+
Documentation = "https://docs.futureagi.com/docs/tracing"
|
|
36
|
+
Repository = "https://github.com/future-agi/traceAI/tree/dev/python/frameworks/minimax"
|
|
37
|
+
Changelog = "https://github.com/future-agi/traceAI/releases"
|
|
38
|
+
Issues = "https://github.com/future-agi/traceAI/issues"
|
|
39
|
+
[build-system]
|
|
40
|
+
requires = ["poetry-core"]
|
|
41
|
+
build-backend = "poetry.core.masonry.api"
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from importlib import import_module
|
|
3
|
+
from typing import Any, Collection
|
|
4
|
+
|
|
5
|
+
logger = logging.getLogger(__name__)
|
|
6
|
+
|
|
7
|
+
from fi_instrumentation import FITracer, TraceConfig
|
|
8
|
+
from opentelemetry import trace as trace_api
|
|
9
|
+
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
|
10
|
+
from wrapt import wrap_function_wrapper
|
|
11
|
+
|
|
12
|
+
from traceai_minimax._wrappers import (
|
|
13
|
+
_AsyncChatCompletionWrapper,
|
|
14
|
+
_ChatCompletionWrapper,
|
|
15
|
+
)
|
|
16
|
+
from traceai_minimax.version import __version__
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
19
|
+
logger.addHandler(logging.NullHandler())
|
|
20
|
+
|
|
21
|
+
_instruments = ("openai >= 1.0.0",)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class MiniMaxInstrumentor(BaseInstrumentor):
|
|
25
|
+
"""
|
|
26
|
+
OpenTelemetry instrumentor for MiniMax.
|
|
27
|
+
|
|
28
|
+
MiniMax uses the OpenAI SDK with a custom base_url (https://api.minimax.io/v1).
|
|
29
|
+
This instrumentor wraps OpenAI client methods and only instruments calls
|
|
30
|
+
when the client is configured with a MiniMax base URL.
|
|
31
|
+
|
|
32
|
+
Supports:
|
|
33
|
+
- MiniMax-M2.7 (latest flagship model with enhanced reasoning and coding)
|
|
34
|
+
- MiniMax-M2.7-highspeed (high-speed version of M2.7 for low-latency scenarios)
|
|
35
|
+
- MiniMax-M2.5 (204K context window)
|
|
36
|
+
- MiniMax-M2.5-highspeed (204K context window, faster inference)
|
|
37
|
+
- Streaming and non-streaming responses
|
|
38
|
+
- Function/tool calling
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
__slots__ = (
|
|
42
|
+
"_original_chat_create",
|
|
43
|
+
"_original_async_chat_create",
|
|
44
|
+
"_tracer",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
def instrumentation_dependencies(self) -> Collection[str]:
|
|
48
|
+
return _instruments
|
|
49
|
+
|
|
50
|
+
def _instrument(self, **kwargs: Any) -> None:
|
|
51
|
+
if not (tracer_provider := kwargs.get("tracer_provider")):
|
|
52
|
+
tracer_provider = trace_api.get_tracer_provider()
|
|
53
|
+
if not (config := kwargs.get("config")):
|
|
54
|
+
config = TraceConfig()
|
|
55
|
+
else:
|
|
56
|
+
assert isinstance(config, TraceConfig)
|
|
57
|
+
|
|
58
|
+
self._tracer = FITracer(
|
|
59
|
+
trace_api.get_tracer(__name__, __version__, tracer_provider),
|
|
60
|
+
config=config,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
# Import openai module
|
|
64
|
+
try:
|
|
65
|
+
openai_module = import_module("openai")
|
|
66
|
+
except ImportError:
|
|
67
|
+
logger.warning("openai package not installed, MiniMax instrumentation skipped")
|
|
68
|
+
return
|
|
69
|
+
|
|
70
|
+
# Wrap OpenAI client chat.completions.create
|
|
71
|
+
# The wrapper checks if the client is configured for MiniMax
|
|
72
|
+
try:
|
|
73
|
+
# Sync client
|
|
74
|
+
if hasattr(openai_module, "OpenAI"):
|
|
75
|
+
from openai.resources.chat import completions
|
|
76
|
+
|
|
77
|
+
self._original_chat_create = completions.Completions.create
|
|
78
|
+
wrap_function_wrapper(
|
|
79
|
+
module="openai.resources.chat.completions",
|
|
80
|
+
name="Completions.create",
|
|
81
|
+
wrapper=_ChatCompletionWrapper(tracer=self._tracer),
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# Async client
|
|
85
|
+
if hasattr(openai_module, "AsyncOpenAI"):
|
|
86
|
+
from openai.resources.chat import completions as async_completions
|
|
87
|
+
|
|
88
|
+
self._original_async_chat_create = async_completions.AsyncCompletions.create
|
|
89
|
+
wrap_function_wrapper(
|
|
90
|
+
module="openai.resources.chat.completions",
|
|
91
|
+
name="AsyncCompletions.create",
|
|
92
|
+
wrapper=_AsyncChatCompletionWrapper(tracer=self._tracer),
|
|
93
|
+
)
|
|
94
|
+
except Exception as e:
|
|
95
|
+
logger.warning(f"Failed to instrument OpenAI for MiniMax: {e}")
|
|
96
|
+
|
|
97
|
+
def _uninstrument(self, **kwargs: Any) -> None:
|
|
98
|
+
try:
|
|
99
|
+
from openai.resources.chat import completions
|
|
100
|
+
|
|
101
|
+
if hasattr(self, "_original_chat_create"):
|
|
102
|
+
completions.Completions.create = self._original_chat_create
|
|
103
|
+
if hasattr(self, "_original_async_chat_create"):
|
|
104
|
+
completions.AsyncCompletions.create = self._original_async_chat_create
|
|
105
|
+
except Exception as e:
|
|
106
|
+
logger.warning(f"Failed to uninstrument: {e}")
|