agenthub-python 0.4.2__py3-none-any.whl → 0.4.3__py3-none-any.whl

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.
@@ -300,7 +300,9 @@ class AntMessagesClient(LLMClient):
300
300
  elif ant_event_type == "message_stop":
301
301
  event_type = "stop"
302
302
 
303
- elif ant_event_type in ["text", "thinking", "signature", "input_json"]:
303
+ elif ant_event_type in ["text", "thinking", "signature", "input_json", "ping"]:
304
+ # the SDK drops the "ping" heartbeat at the SSE layer; it reaches here only from
305
+ # gateways that relabel it onto another event
304
306
  event_type = "unused"
305
307
 
306
308
  else:
agenthub/auto_client.py CHANGED
@@ -47,10 +47,6 @@ class AutoLLMClient(LLMClient):
47
47
  ) -> LLMClient:
48
48
  """Create the appropriate client for the given model."""
49
49
  client_type = (client_type or os.getenv("CLIENT_TYPE") or model).lower()
50
- if client_type == "minimax-m3":
51
- from .minimax_m3 import MiniMaxM3Client
52
-
53
- return MiniMaxM3Client(model=model, api_key=api_key, base_url=base_url)
54
50
  # every Gemini generation shares the unified client ("gemini-3" also matches the
55
51
  # gemini-3.7/gemini-3.6/gemini-3.5-flash-lite client types)
56
52
  if any(
@@ -78,6 +74,10 @@ class AutoLLMClient(LLMClient):
78
74
  from .kimi_k3 import KimiK3Client
79
75
 
80
76
  return KimiK3Client(model=model, api_key=api_key, base_url=base_url)
77
+ elif client_type == "minimax-m3":
78
+ from .minimax_m3 import MiniMaxM3Client
79
+
80
+ return MiniMaxM3Client(model=model, api_key=api_key, base_url=base_url)
81
81
  elif "deepseek-v4" in client_type:
82
82
  from .deepseek_v4 import DeepSeekV4Client
83
83
 
@@ -349,7 +349,9 @@ class Claude5Client(LLMClient):
349
349
  elif claude_event_type == "message_stop":
350
350
  event_type = "stop"
351
351
 
352
- elif claude_event_type in ["text", "thinking", "signature", "input_json"]:
352
+ elif claude_event_type in ["text", "thinking", "signature", "input_json", "ping"]:
353
+ # the SDK drops the "ping" heartbeat at the SSE layer; it reaches here only from
354
+ # gateways that relabel it onto another event
353
355
  event_type = "unused"
354
356
 
355
357
  else:
@@ -206,7 +206,9 @@ class DeepSeekV4Client(LLMClient):
206
206
  usage_metadata: UsageMetadata | None = None
207
207
  finish_reason: FinishReason | None = None
208
208
 
209
- if len(model_output.choices) > 0:
209
+ # gateways inject content-free heartbeat chunks on long generations, whose choices
210
+ # the SDK leaves as None rather than an empty list
211
+ if model_output.choices:
210
212
  choice = model_output.choices[0]
211
213
  delta = choice.delta
212
214
 
@@ -376,6 +376,11 @@ class Gemini3_7Client(LLMClient):
376
376
  usage_metadata: UsageMetadata | None = None
377
377
  finish_reason: FinishReason | None = None
378
378
 
379
+ if not model_output.candidates and not model_output.usage_metadata:
380
+ # gateways inject heartbeat chunks on long generations; they map to a chunk with
381
+ # neither candidates nor usage, so there is nothing to emit
382
+ event_type = "unused"
383
+
379
384
  if model_output.candidates:
380
385
  candidate = model_output.candidates[0]
381
386
  content = getattr(candidate, "content", None)
@@ -511,6 +516,9 @@ class Gemini3_7Client(LLMClient):
511
516
  )
512
517
  async for chunk in response_stream:
513
518
  event = self.transform_model_output_to_uni_event(chunk)
519
+ if event["event_type"] == "unused":
520
+ continue
521
+
514
522
  for item in event["content_items"]:
515
523
  if item["type"] == "tool_call":
516
524
  # gemini 3.7 does not support partial tool call, mock a partial tool call event
agenthub/glm5_3/client.py CHANGED
@@ -239,7 +239,9 @@ class GLM5_3Client(LLMClient):
239
239
  usage_metadata: UsageMetadata | None = None
240
240
  finish_reason: FinishReason | None = None
241
241
 
242
- if len(model_output.choices) > 0:
242
+ # gateways inject content-free heartbeat chunks on long generations, whose choices
243
+ # the SDK leaves as None rather than an empty list
244
+ if model_output.choices:
243
245
  choice = model_output.choices[0]
244
246
  delta = choice.delta
245
247
 
agenthub/gpt5_6/client.py CHANGED
@@ -301,6 +301,7 @@ class GPT5_6Client(LLMClient):
301
301
  "response.reasoning_text.done",
302
302
  "response.content_part.added",
303
303
  "response.content_part.done",
304
+ "keepalive", # gateway heartbeat on long generations; carries no content
304
305
  ]:
305
306
  event_type = "unused"
306
307
 
@@ -267,7 +267,9 @@ class KimiK3Client(LLMClient):
267
267
  usage_metadata: UsageMetadata | None = None
268
268
  finish_reason: FinishReason | None = None
269
269
 
270
- if len(model_output.choices) > 0:
270
+ # gateways inject content-free heartbeat chunks on long generations, whose choices
271
+ # the SDK leaves as None rather than an empty list
272
+ if model_output.choices:
271
273
  choice = model_output.choices[0]
272
274
  delta = choice.delta
273
275
 
@@ -248,6 +248,7 @@ class MiniMaxM3Client(LLMClient):
248
248
  "response.output_item.done",
249
249
  "response.content_part.added",
250
250
  "response.content_part.done",
251
+ "keepalive", # gateway heartbeat on long generations; carries no content
251
252
  ):
252
253
  raise ValueError(f"Unknown output: {model_output}")
253
254
 
@@ -220,7 +220,9 @@ class OpenaiChatClient(LLMClient):
220
220
  usage_metadata: UsageMetadata | None = None
221
221
  finish_reason: FinishReason | None = None
222
222
 
223
- if len(model_output.choices) > 0:
223
+ # gateways inject content-free heartbeat chunks on long generations, whose choices
224
+ # the SDK leaves as None rather than an empty list
225
+ if model_output.choices:
224
226
  choice = model_output.choices[0]
225
227
  delta = choice.delta
226
228
 
@@ -298,6 +298,7 @@ class OpenaiResponsesClient(LLMClient):
298
298
  "response.reasoning_summary_text.done",
299
299
  "response.content_part.added",
300
300
  "response.content_part.done",
301
+ "keepalive", # gateway heartbeat on long generations; carries no content
301
302
  ):
302
303
  event_type = "unused"
303
304
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agenthub-python
3
- Version: 0.4.2
3
+ Version: 0.4.3
4
4
  Summary: AgentHub is the LLM API Hub for the Agent era, built for high-precision autonomous agents.
5
5
  Keywords: agent,llm,gemini,claude,gpt
6
6
  Author: PrismShadow
@@ -13,6 +13,7 @@ Requires-Dist: httpx>=0.27.0
13
13
  Requires-Dist: httpx[socks] ; extra == 'dev'
14
14
  Requires-Dist: pytest>=8.4.2 ; extra == 'dev'
15
15
  Requires-Dist: pytest-asyncio>=0.23.0 ; extra == 'dev'
16
+ Requires-Dist: pytest-xdist>=3.6.0 ; extra == 'dev'
16
17
  Requires-Dist: ruff>=0.14.3 ; extra == 'dev'
17
18
  Requires-Dist: pillow>=10.0.0 ; extra == 'dev'
18
19
  Requires-Python: >=3.11
@@ -1,36 +1,36 @@
1
1
  agenthub/__init__.py,sha256=_SCnAB0y78Te6432QxG1aYzNpmTZ_rCvpWbpyrSunQc,1186
2
2
  agenthub/abort_signal.py,sha256=_j99RBZluBPdHLuRpZMyo15amll_8ZzmLO8fjLwEsaM,3744
3
3
  agenthub/ant_messages/__init__.py,sha256=wEz05advA7ggsvOYBffat7g8PN9TkOxYRBdeYPuoihY,672
4
- agenthub/ant_messages/client.py,sha256=pFBQwd8Xega0W_jxqa_B2U9Cw1EUguiwF-ZP2bucbVc,18130
5
- agenthub/auto_client.py,sha256=FjChj4wp2JXCk-xQ5QWG2kIg5c2wsBDA3s5wRqmLkn8,7457
4
+ agenthub/ant_messages/client.py,sha256=xJTIPr_z81Qy0XIEjqSlAm64HWvx5Klvgs9b6QF45p4,18289
5
+ agenthub/auto_client.py,sha256=wpfFovXcoxFeKM5xOT0vOegv50OwEjAlnUFmDnG1IeU,7459
6
6
  agenthub/base_client.py,sha256=gOK63Guv2jX2O0aYqQLMEENMeDBgeSl3GJ--69P2qI4,14016
7
7
  agenthub/claude5/__init__.py,sha256=FzP_ijkZ67kK6W-VJwRYTswzSCt_YaWbOEcybQ_2FyM,664
8
- agenthub/claude5/client.py,sha256=fkJ45-KPc3v-1M4yxYSX9tGepcGQAVqX2X4PP6sdoII,19795
8
+ agenthub/claude5/client.py,sha256=Xlk_YolAGGcSCFLNpReToid1lYWgGfqQ9XOtbNJQTMo,19954
9
9
  agenthub/deepseek_v4/__init__.py,sha256=MEBBJlx2kicstbG3ncJp1gLpIeTG_fwNh_uZVsc7JcI,670
10
- agenthub/deepseek_v4/client.py,sha256=xZqAeMIZGS2dcnONdi7UeAQASc4hT5dtVFYslXsHIbU,15926
10
+ agenthub/deepseek_v4/client.py,sha256=lJScdTQhm7KS5DWC_VgpSf37kdAit1lIGkwj4LPSUoo,16067
11
11
  agenthub/errors.py,sha256=0eZ_oeAQHi-8tZnW0yWoYhugPwdtjKl9gsJTJ1Rb5Ow,3350
12
12
  agenthub/gemini3_7/__init__.py,sha256=bMyPUwyiuyGPU0h2q5bqmL4gfwh7FcSeqK_6kLn9WGI,668
13
- agenthub/gemini3_7/client.py,sha256=4QjGCWYfHJTqX9zGhf-N6X-HQEwjEDFPJLuRH_9F98M,23917
13
+ agenthub/gemini3_7/client.py,sha256=K1D7YLH8QPMBih7Gfk6Mynx-FzOg4qmFkLyhh3SXM-c,24267
14
14
  agenthub/glm5_3/__init__.py,sha256=DJhHMvliHikxdNA8HLNmxzRXLPASCc6aFJZTfpMX7fg,662
15
- agenthub/glm5_3/client.py,sha256=BkgTeJpT1p7qYwqrKTIGMyaMTWXth1JF4cEL_dDsZhE,19202
15
+ agenthub/glm5_3/client.py,sha256=TtB5B8-gC66I4wgsxlVIS2GP8GcxFGYhQPf4yAOpAhc,19343
16
16
  agenthub/gpt5_6/__init__.py,sha256=_KgiOi_VqTL82pf9Ks7VM-d_x5-at8v-N1KZDWLVvt8,662
17
- agenthub/gpt5_6/client.py,sha256=doVjU73cyMmY5mXk5hgGPdsw4J5suA27ZnvkqTfvFWk,16714
17
+ agenthub/gpt5_6/client.py,sha256=Ie3BK83J1T6oDWwlupbMYlIBCIV0GqQexeK7HhXZoLE,16800
18
18
  agenthub/integration/__init__.py,sha256=tlqmpVlFYm8uyMSa4RFebx5vi0FSS_GcES57JWVeu8c,600
19
19
  agenthub/integration/playground.py,sha256=mXoTVGnecCm1etP1CFoaOrfr3SxIYOMh1RqICLO3TrI,71380
20
20
  agenthub/integration/tracer.py,sha256=qAcU8rvnDJMgJHg4niwN9aANwSnxh8MrMaWpKBwLaZo,41963
21
21
  agenthub/kimi_k3/__init__.py,sha256=MnoMhqRI6tlaXmQCHEud-2BqAvyxa_7Bxv3X8khfC3g,662
22
- agenthub/kimi_k3/client.py,sha256=4HEOr2ZmpKc3LjYAn1cldZlmXQUFxrnT4SdOp43ZujU,20233
22
+ agenthub/kimi_k3/client.py,sha256=Kwf4fKfdPcpCembF61tXoc3PDAjaR7ejFM7OFv3OTd4,20374
23
23
  agenthub/minimax_m3/__init__.py,sha256=FTykS-0le7AdiU8zLeMjbj4QGBwR0oSIkOICqEFGoaw,668
24
- agenthub/minimax_m3/client.py,sha256=Fe3J3rfn-7haiDNdTgV131FNP0oqohSxK-FJ-Paw1UY,14182
24
+ agenthub/minimax_m3/client.py,sha256=AFfYPxJwE9gPJEy7mDgUz7C0QgX5v_cJWA7BpVqiH6U,14268
25
25
  agenthub/openai_chat/__init__.py,sha256=6X-4sX0Xy9MqSYVglW4ytt3NMSAzoRM3I_NFKwqOIVQ,670
26
- agenthub/openai_chat/client.py,sha256=zt_c7BI30FxpzRqv1qBwOxUDLGmlaC0nZ4eU5s8Uq5Y,17937
26
+ agenthub/openai_chat/client.py,sha256=vosIlnDixNyoRrG_E_vnJXGC6Ks9f3KBl8gbPowzpa4,18078
27
27
  agenthub/openai_embedding/__init__.py,sha256=t1W8kBvZUXICjDfgjTVxw-uIh5qoneUgmSsGIYan02s,680
28
28
  agenthub/openai_embedding/client.py,sha256=5j9p-zjYSmsdzpWM1ldrWY9UFea6EtDHdxG2YDBgGSo,3739
29
29
  agenthub/openai_responses/__init__.py,sha256=Y0YAAnkRYpIEq62phw5EpTfPt_osFXptujhpwBggM1E,680
30
- agenthub/openai_responses/client.py,sha256=UOjeUX4LQphTdv-rCIq8g-_nSGFeUfv1AMOpNmQWkh4,16529
30
+ agenthub/openai_responses/client.py,sha256=PmM6RH6bxfttkLipjUjNqqg-44Ly0YQyuCzte4jaAYI,16615
31
31
  agenthub/registry.py,sha256=FgJUkpjsmvYU1J6V20KlGIgkK3bCiiWS8RsELJPWiyY,21189
32
32
  agenthub/types.py,sha256=-hLYr5_K7FMOKLFK75M-i-HYg74v81Jl-gCzc3ZkX-o,5344
33
33
  agenthub/utils.py,sha256=A846vF-Tyo_BCWoWuB-R_fihRTSRoDuDPefqY0g8eLQ,1318
34
- agenthub_python-0.4.2.dist-info/WHEEL,sha256=4OL6Foqnnp3xRY5wMkjgc25_i5YJC6dKsC6LPcjqEoU,80
35
- agenthub_python-0.4.2.dist-info/METADATA,sha256=01ZWgsIDr1jMR0cjltWjGPJMCUMZ9qyeesW28tH2ba4,9060
36
- agenthub_python-0.4.2.dist-info/RECORD,,
34
+ agenthub_python-0.4.3.dist-info/WHEEL,sha256=4OL6Foqnnp3xRY5wMkjgc25_i5YJC6dKsC6LPcjqEoU,80
35
+ agenthub_python-0.4.3.dist-info/METADATA,sha256=idP-p5TzTMvdUCAz86jTj0sUREiEh4r_d_uCtm7HV80,9112
36
+ agenthub_python-0.4.3.dist-info/RECORD,,