agenthub-python 0.4.14__tar.gz → 0.4.15__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.
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/PKG-INFO +1 -1
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/deepseek_v4/client.py +53 -26
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/gpt6/client.py +53 -26
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/minimax_m3/client.py +51 -24
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/openai_responses/client.py +53 -26
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/types.py +3 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/pyproject.toml +1 -1
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/pyproject.toml.orig +1 -1
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/README.md +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/__init__.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/abort_signal.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/ant_messages/__init__.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/ant_messages/client.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/auto_client.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/base_client.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/claude5/__init__.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/claude5/client.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/deepseek_v4/__init__.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/errors.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/gemini3_8/__init__.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/gemini3_8/client.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/glm5_3/__init__.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/glm5_3/client.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/gpt6/__init__.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/integration/__init__.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/integration/playground.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/integration/tracer.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/kimi_k3/__init__.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/kimi_k3/client.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/minimax_m3/__init__.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/openai_chat/__init__.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/openai_chat/client.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/openai_chat_vllm_adapter/__init__.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/openai_chat_vllm_adapter/client.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/openai_embedding/__init__.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/openai_embedding/client.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/openai_responses/__init__.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/registry.py +0 -0
- {agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/utils.py +0 -0
|
@@ -260,6 +260,7 @@ class DeepSeekV4Client(LLMClient):
|
|
|
260
260
|
"name": model_output.item.name,
|
|
261
261
|
"arguments": "",
|
|
262
262
|
"tool_call_id": model_output.item.call_id,
|
|
263
|
+
"item_id": model_output.item.id,
|
|
263
264
|
}
|
|
264
265
|
)
|
|
265
266
|
else:
|
|
@@ -268,11 +269,27 @@ class DeepSeekV4Client(LLMClient):
|
|
|
268
269
|
elif deepseek_event_type == "response.function_call_arguments.delta":
|
|
269
270
|
event_type = "delta"
|
|
270
271
|
content_items.append(
|
|
271
|
-
{
|
|
272
|
+
{
|
|
273
|
+
"type": "partial_tool_call",
|
|
274
|
+
"name": "",
|
|
275
|
+
"arguments": model_output.delta,
|
|
276
|
+
"tool_call_id": "",
|
|
277
|
+
"item_id": model_output.item_id,
|
|
278
|
+
}
|
|
272
279
|
)
|
|
273
280
|
|
|
274
281
|
elif deepseek_event_type == "response.function_call_arguments.done":
|
|
282
|
+
# a stop naming the item closes that call
|
|
275
283
|
event_type = "stop"
|
|
284
|
+
content_items.append(
|
|
285
|
+
{
|
|
286
|
+
"type": "partial_tool_call",
|
|
287
|
+
"name": "",
|
|
288
|
+
"arguments": "",
|
|
289
|
+
"tool_call_id": "",
|
|
290
|
+
"item_id": model_output.item_id,
|
|
291
|
+
}
|
|
292
|
+
)
|
|
276
293
|
|
|
277
294
|
elif deepseek_event_type in ("response.completed", "response.incomplete"):
|
|
278
295
|
event_type = "stop"
|
|
@@ -334,51 +351,61 @@ class DeepSeekV4Client(LLMClient):
|
|
|
334
351
|
# Use unified message conversion
|
|
335
352
|
input_list = self.transform_uni_message_to_model_input(messages)
|
|
336
353
|
|
|
354
|
+
# Calls still streaming, keyed by the item id their fragments carry (the call id when a
|
|
355
|
+
# server sends none): a gateway may open several before closing any of them.
|
|
356
|
+
open_tool_calls: dict[str, dict] = {}
|
|
357
|
+
last_opened = ""
|
|
358
|
+
|
|
359
|
+
def key_of(item_id: str | None) -> str:
|
|
360
|
+
return item_id if item_id in open_tool_calls else last_opened
|
|
361
|
+
|
|
337
362
|
# Stream generate
|
|
338
|
-
partial_tool_call = {}
|
|
339
363
|
stream = await self._client.responses.create(**deepseek_config, input=input_list, stream=True)
|
|
340
|
-
async for
|
|
341
|
-
event = self.transform_model_output_to_uni_event(
|
|
364
|
+
async for model_event in stream:
|
|
365
|
+
event = self.transform_model_output_to_uni_event(model_event)
|
|
366
|
+
fragments = [item for item in event["content_items"] if item["type"] == "partial_tool_call"]
|
|
342
367
|
if event["event_type"] == "start":
|
|
343
|
-
for item in
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
yield event
|
|
368
|
+
for item in fragments:
|
|
369
|
+
last_opened = item.get("item_id") or item["tool_call_id"]
|
|
370
|
+
open_tool_calls[last_opened] = {
|
|
371
|
+
"name": item["name"],
|
|
372
|
+
"tool_call_id": item["tool_call_id"],
|
|
373
|
+
"arguments": "",
|
|
374
|
+
}
|
|
375
|
+
yield event
|
|
352
376
|
elif event["event_type"] == "delta":
|
|
353
|
-
for item in
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
377
|
+
for item in fragments:
|
|
378
|
+
tool_call = open_tool_calls.get(key_of(item.get("item_id")))
|
|
379
|
+
if tool_call is not None:
|
|
380
|
+
tool_call["arguments"] += item["arguments"]
|
|
358
381
|
yield event
|
|
359
382
|
elif event["event_type"] == "stop":
|
|
360
|
-
|
|
361
|
-
|
|
383
|
+
# a stop that names calls closes them; the end of the response closes whatever
|
|
384
|
+
# a gateway never closed on its own
|
|
385
|
+
closing = [key_of(item.get("item_id")) for item in fragments] or list(open_tool_calls)
|
|
386
|
+
for key in closing:
|
|
387
|
+
tool_call = open_tool_calls.pop(key, None)
|
|
388
|
+
if tool_call is None:
|
|
389
|
+
continue
|
|
362
390
|
yield {
|
|
363
391
|
"role": "assistant",
|
|
364
392
|
"event_type": "delta",
|
|
365
393
|
"content_items": [
|
|
366
394
|
{
|
|
367
395
|
"type": "tool_call",
|
|
368
|
-
"name":
|
|
396
|
+
"name": tool_call["name"],
|
|
369
397
|
"arguments": parse_tool_call_arguments(
|
|
370
|
-
|
|
398
|
+
tool_call["arguments"],
|
|
371
399
|
self.__class__.__name__,
|
|
372
|
-
|
|
373
|
-
|
|
400
|
+
tool_call["name"],
|
|
401
|
+
tool_call["tool_call_id"],
|
|
374
402
|
),
|
|
375
|
-
"tool_call_id":
|
|
403
|
+
"tool_call_id": tool_call["tool_call_id"],
|
|
376
404
|
}
|
|
377
405
|
],
|
|
378
406
|
"usage_metadata": None,
|
|
379
407
|
"finish_reason": None,
|
|
380
408
|
}
|
|
381
|
-
partial_tool_call = {}
|
|
382
409
|
|
|
383
410
|
if event["finish_reason"] or event["usage_metadata"]:
|
|
384
411
|
yield event
|
|
@@ -272,6 +272,7 @@ class GPT6Client(LLMClient):
|
|
|
272
272
|
"name": model_output.item.name,
|
|
273
273
|
"arguments": "",
|
|
274
274
|
"tool_call_id": model_output.item.call_id,
|
|
275
|
+
"item_id": model_output.item.id,
|
|
275
276
|
}
|
|
276
277
|
)
|
|
277
278
|
elif model_output.item.type == "message":
|
|
@@ -288,11 +289,27 @@ class GPT6Client(LLMClient):
|
|
|
288
289
|
elif openai_event_type == "response.function_call_arguments.delta":
|
|
289
290
|
event_type = "delta"
|
|
290
291
|
content_items.append(
|
|
291
|
-
{
|
|
292
|
+
{
|
|
293
|
+
"type": "partial_tool_call",
|
|
294
|
+
"name": "",
|
|
295
|
+
"arguments": model_output.delta,
|
|
296
|
+
"tool_call_id": "",
|
|
297
|
+
"item_id": model_output.item_id,
|
|
298
|
+
}
|
|
292
299
|
)
|
|
293
300
|
|
|
294
301
|
elif openai_event_type == "response.function_call_arguments.done":
|
|
302
|
+
# a stop naming the item closes that call
|
|
295
303
|
event_type = "stop"
|
|
304
|
+
content_items.append(
|
|
305
|
+
{
|
|
306
|
+
"type": "partial_tool_call",
|
|
307
|
+
"name": "",
|
|
308
|
+
"arguments": "",
|
|
309
|
+
"tool_call_id": "",
|
|
310
|
+
"item_id": model_output.item_id,
|
|
311
|
+
}
|
|
312
|
+
)
|
|
296
313
|
|
|
297
314
|
elif openai_event_type in ("response.completed", "response.incomplete"):
|
|
298
315
|
event_type = "stop"
|
|
@@ -382,51 +399,61 @@ class GPT6Client(LLMClient):
|
|
|
382
399
|
# Use unified message conversion
|
|
383
400
|
input_list = self.transform_uni_message_to_model_input(messages)
|
|
384
401
|
|
|
402
|
+
# Calls still streaming, keyed by the item id their fragments carry (the call id when a
|
|
403
|
+
# server sends none): a gateway may open several before closing any of them.
|
|
404
|
+
open_tool_calls: dict[str, dict] = {}
|
|
405
|
+
last_opened = ""
|
|
406
|
+
|
|
407
|
+
def key_of(item_id: str | None) -> str:
|
|
408
|
+
return item_id if item_id in open_tool_calls else last_opened
|
|
409
|
+
|
|
385
410
|
# Stream generate
|
|
386
|
-
partial_tool_call = {}
|
|
387
411
|
stream = await self._client.responses.create(**openai_config, input=input_list, stream=True)
|
|
388
|
-
async for
|
|
389
|
-
event = self.transform_model_output_to_uni_event(
|
|
412
|
+
async for model_event in stream:
|
|
413
|
+
event = self.transform_model_output_to_uni_event(model_event)
|
|
414
|
+
fragments = [item for item in event["content_items"] if item["type"] == "partial_tool_call"]
|
|
390
415
|
if event["event_type"] == "start":
|
|
391
|
-
for item in
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
yield event
|
|
416
|
+
for item in fragments:
|
|
417
|
+
last_opened = item.get("item_id") or item["tool_call_id"]
|
|
418
|
+
open_tool_calls[last_opened] = {
|
|
419
|
+
"name": item["name"],
|
|
420
|
+
"tool_call_id": item["tool_call_id"],
|
|
421
|
+
"arguments": "",
|
|
422
|
+
}
|
|
423
|
+
yield event
|
|
400
424
|
elif event["event_type"] == "delta":
|
|
401
|
-
for item in
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
425
|
+
for item in fragments:
|
|
426
|
+
tool_call = open_tool_calls.get(key_of(item.get("item_id")))
|
|
427
|
+
if tool_call is not None:
|
|
428
|
+
tool_call["arguments"] += item["arguments"]
|
|
406
429
|
yield event
|
|
407
430
|
elif event["event_type"] == "stop":
|
|
408
|
-
|
|
409
|
-
|
|
431
|
+
# a stop that names calls closes them; the end of the response closes whatever
|
|
432
|
+
# a gateway never closed on its own
|
|
433
|
+
closing = [key_of(item.get("item_id")) for item in fragments] or list(open_tool_calls)
|
|
434
|
+
for key in closing:
|
|
435
|
+
tool_call = open_tool_calls.pop(key, None)
|
|
436
|
+
if tool_call is None:
|
|
437
|
+
continue
|
|
410
438
|
yield {
|
|
411
439
|
"role": "assistant",
|
|
412
440
|
"event_type": "delta",
|
|
413
441
|
"content_items": [
|
|
414
442
|
{
|
|
415
443
|
"type": "tool_call",
|
|
416
|
-
"name":
|
|
444
|
+
"name": tool_call["name"],
|
|
417
445
|
"arguments": parse_tool_call_arguments(
|
|
418
|
-
|
|
446
|
+
tool_call["arguments"],
|
|
419
447
|
self.__class__.__name__,
|
|
420
|
-
|
|
421
|
-
|
|
448
|
+
tool_call["name"],
|
|
449
|
+
tool_call["tool_call_id"],
|
|
422
450
|
),
|
|
423
|
-
"tool_call_id":
|
|
451
|
+
"tool_call_id": tool_call["tool_call_id"],
|
|
424
452
|
}
|
|
425
453
|
],
|
|
426
454
|
"usage_metadata": None,
|
|
427
455
|
"finish_reason": None,
|
|
428
456
|
}
|
|
429
|
-
partial_tool_call = {}
|
|
430
457
|
|
|
431
458
|
if event["finish_reason"] or event["usage_metadata"]:
|
|
432
459
|
yield event
|
|
@@ -217,17 +217,34 @@ class MiniMaxM3Client(LLMClient):
|
|
|
217
217
|
"name": model_output.item.name,
|
|
218
218
|
"arguments": "",
|
|
219
219
|
"tool_call_id": model_output.item.call_id,
|
|
220
|
+
"item_id": model_output.item.id,
|
|
220
221
|
}
|
|
221
222
|
)
|
|
222
223
|
|
|
223
224
|
elif minimax_event_type == "response.function_call_arguments.delta":
|
|
224
225
|
event_type = "delta"
|
|
225
226
|
content_items.append(
|
|
226
|
-
{
|
|
227
|
+
{
|
|
228
|
+
"type": "partial_tool_call",
|
|
229
|
+
"name": "",
|
|
230
|
+
"arguments": model_output.delta,
|
|
231
|
+
"tool_call_id": "",
|
|
232
|
+
"item_id": model_output.item_id,
|
|
233
|
+
}
|
|
227
234
|
)
|
|
228
235
|
|
|
229
236
|
elif minimax_event_type == "response.function_call_arguments.done":
|
|
237
|
+
# a stop naming the item closes that call
|
|
230
238
|
event_type = "stop"
|
|
239
|
+
content_items.append(
|
|
240
|
+
{
|
|
241
|
+
"type": "partial_tool_call",
|
|
242
|
+
"name": "",
|
|
243
|
+
"arguments": "",
|
|
244
|
+
"tool_call_id": "",
|
|
245
|
+
"item_id": model_output.item_id,
|
|
246
|
+
}
|
|
247
|
+
)
|
|
231
248
|
|
|
232
249
|
elif minimax_event_type in ("response.completed", "response.incomplete"):
|
|
233
250
|
event_type = "stop"
|
|
@@ -279,50 +296,60 @@ class MiniMaxM3Client(LLMClient):
|
|
|
279
296
|
minimax_config = self.transform_uni_config_to_model_config(config)
|
|
280
297
|
input_list = self.transform_uni_message_to_model_input(messages)
|
|
281
298
|
|
|
282
|
-
|
|
299
|
+
# Calls still streaming, keyed by the item id their fragments carry (the call id when a
|
|
300
|
+
# server sends none): a gateway may open several before closing any of them.
|
|
301
|
+
open_tool_calls: dict[str, dict] = {}
|
|
302
|
+
last_opened = ""
|
|
303
|
+
|
|
304
|
+
def key_of(item_id: str | None) -> str:
|
|
305
|
+
return item_id if item_id in open_tool_calls else last_opened
|
|
306
|
+
|
|
283
307
|
stream = await self._client.responses.create(**minimax_config, input=input_list, stream=True)
|
|
284
308
|
async for model_event in stream:
|
|
285
309
|
event = self.transform_model_output_to_uni_event(model_event)
|
|
310
|
+
fragments = [item for item in event["content_items"] if item["type"] == "partial_tool_call"]
|
|
286
311
|
if event["event_type"] == "start":
|
|
287
|
-
for item in
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
yield event
|
|
312
|
+
for item in fragments:
|
|
313
|
+
last_opened = item.get("item_id") or item["tool_call_id"]
|
|
314
|
+
open_tool_calls[last_opened] = {
|
|
315
|
+
"name": item["name"],
|
|
316
|
+
"tool_call_id": item["tool_call_id"],
|
|
317
|
+
"arguments": "",
|
|
318
|
+
}
|
|
319
|
+
yield event
|
|
296
320
|
elif event["event_type"] == "delta":
|
|
297
|
-
for item in
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
321
|
+
for item in fragments:
|
|
322
|
+
tool_call = open_tool_calls.get(key_of(item.get("item_id")))
|
|
323
|
+
if tool_call is not None:
|
|
324
|
+
tool_call["arguments"] += item["arguments"]
|
|
302
325
|
yield event
|
|
303
326
|
elif event["event_type"] == "stop":
|
|
304
|
-
|
|
305
|
-
|
|
327
|
+
# a stop that names calls closes them; the end of the response closes whatever
|
|
328
|
+
# a gateway never closed on its own
|
|
329
|
+
closing = [key_of(item.get("item_id")) for item in fragments] or list(open_tool_calls)
|
|
330
|
+
for key in closing:
|
|
331
|
+
tool_call = open_tool_calls.pop(key, None)
|
|
332
|
+
if tool_call is None:
|
|
333
|
+
continue
|
|
306
334
|
yield {
|
|
307
335
|
"role": "assistant",
|
|
308
336
|
"event_type": "delta",
|
|
309
337
|
"content_items": [
|
|
310
338
|
{
|
|
311
339
|
"type": "tool_call",
|
|
312
|
-
"name":
|
|
340
|
+
"name": tool_call["name"],
|
|
313
341
|
"arguments": parse_tool_call_arguments(
|
|
314
|
-
|
|
342
|
+
tool_call["arguments"],
|
|
315
343
|
self.__class__.__name__,
|
|
316
|
-
|
|
317
|
-
|
|
344
|
+
tool_call["name"],
|
|
345
|
+
tool_call["tool_call_id"],
|
|
318
346
|
),
|
|
319
|
-
"tool_call_id":
|
|
347
|
+
"tool_call_id": tool_call["tool_call_id"],
|
|
320
348
|
}
|
|
321
349
|
],
|
|
322
350
|
"usage_metadata": None,
|
|
323
351
|
"finish_reason": None,
|
|
324
352
|
}
|
|
325
|
-
partial_tool_call = {}
|
|
326
353
|
|
|
327
354
|
if event["finish_reason"] or event["usage_metadata"]:
|
|
328
355
|
yield event
|
|
@@ -268,6 +268,7 @@ class OpenaiResponsesClient(LLMClient):
|
|
|
268
268
|
"name": model_output.item.name,
|
|
269
269
|
"arguments": "",
|
|
270
270
|
"tool_call_id": model_output.item.call_id,
|
|
271
|
+
"item_id": model_output.item.id,
|
|
271
272
|
}
|
|
272
273
|
)
|
|
273
274
|
elif model_output.item.type == "message" and getattr(model_output.item, "phase", None):
|
|
@@ -295,11 +296,27 @@ class OpenaiResponsesClient(LLMClient):
|
|
|
295
296
|
elif openai_event_type == "response.function_call_arguments.delta":
|
|
296
297
|
event_type = "delta"
|
|
297
298
|
content_items.append(
|
|
298
|
-
{
|
|
299
|
+
{
|
|
300
|
+
"type": "partial_tool_call",
|
|
301
|
+
"name": "",
|
|
302
|
+
"arguments": model_output.delta,
|
|
303
|
+
"tool_call_id": "",
|
|
304
|
+
"item_id": model_output.item_id,
|
|
305
|
+
}
|
|
299
306
|
)
|
|
300
307
|
|
|
301
308
|
elif openai_event_type == "response.function_call_arguments.done":
|
|
309
|
+
# a stop naming the item closes that call
|
|
302
310
|
event_type = "stop"
|
|
311
|
+
content_items.append(
|
|
312
|
+
{
|
|
313
|
+
"type": "partial_tool_call",
|
|
314
|
+
"name": "",
|
|
315
|
+
"arguments": "",
|
|
316
|
+
"tool_call_id": "",
|
|
317
|
+
"item_id": model_output.item_id,
|
|
318
|
+
}
|
|
319
|
+
)
|
|
303
320
|
|
|
304
321
|
elif openai_event_type in ("response.completed", "response.incomplete"):
|
|
305
322
|
event_type = "stop"
|
|
@@ -364,51 +381,61 @@ class OpenaiResponsesClient(LLMClient):
|
|
|
364
381
|
# Use unified message conversion
|
|
365
382
|
input_list = self.transform_uni_message_to_model_input(messages)
|
|
366
383
|
|
|
384
|
+
# Calls still streaming, keyed by the item id their fragments carry (the call id when a
|
|
385
|
+
# server sends none): a gateway may open several before closing any of them.
|
|
386
|
+
open_tool_calls: dict[str, dict] = {}
|
|
387
|
+
last_opened = ""
|
|
388
|
+
|
|
389
|
+
def key_of(item_id: str | None) -> str:
|
|
390
|
+
return item_id if item_id in open_tool_calls else last_opened
|
|
391
|
+
|
|
367
392
|
# Stream generate
|
|
368
|
-
partial_tool_call = {}
|
|
369
393
|
stream = await self._client.responses.create(**openai_config, input=input_list, stream=True)
|
|
370
|
-
async for
|
|
371
|
-
event = self.transform_model_output_to_uni_event(
|
|
394
|
+
async for model_event in stream:
|
|
395
|
+
event = self.transform_model_output_to_uni_event(model_event)
|
|
396
|
+
fragments = [item for item in event["content_items"] if item["type"] == "partial_tool_call"]
|
|
372
397
|
if event["event_type"] == "start":
|
|
373
|
-
for item in
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
yield event
|
|
398
|
+
for item in fragments:
|
|
399
|
+
last_opened = item.get("item_id") or item["tool_call_id"]
|
|
400
|
+
open_tool_calls[last_opened] = {
|
|
401
|
+
"name": item["name"],
|
|
402
|
+
"tool_call_id": item["tool_call_id"],
|
|
403
|
+
"arguments": "",
|
|
404
|
+
}
|
|
405
|
+
yield event
|
|
382
406
|
elif event["event_type"] == "delta":
|
|
383
|
-
for item in
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
407
|
+
for item in fragments:
|
|
408
|
+
tool_call = open_tool_calls.get(key_of(item.get("item_id")))
|
|
409
|
+
if tool_call is not None:
|
|
410
|
+
tool_call["arguments"] += item["arguments"]
|
|
388
411
|
yield event
|
|
389
412
|
elif event["event_type"] == "stop":
|
|
390
|
-
|
|
391
|
-
|
|
413
|
+
# a stop that names calls closes them; the end of the response closes whatever
|
|
414
|
+
# a gateway never closed on its own
|
|
415
|
+
closing = [key_of(item.get("item_id")) for item in fragments] or list(open_tool_calls)
|
|
416
|
+
for key in closing:
|
|
417
|
+
tool_call = open_tool_calls.pop(key, None)
|
|
418
|
+
if tool_call is None:
|
|
419
|
+
continue
|
|
392
420
|
yield {
|
|
393
421
|
"role": "assistant",
|
|
394
422
|
"event_type": "delta",
|
|
395
423
|
"content_items": [
|
|
396
424
|
{
|
|
397
425
|
"type": "tool_call",
|
|
398
|
-
"name":
|
|
426
|
+
"name": tool_call["name"],
|
|
399
427
|
"arguments": parse_tool_call_arguments(
|
|
400
|
-
|
|
428
|
+
tool_call["arguments"],
|
|
401
429
|
self.__class__.__name__,
|
|
402
|
-
|
|
403
|
-
|
|
430
|
+
tool_call["name"],
|
|
431
|
+
tool_call["tool_call_id"],
|
|
404
432
|
),
|
|
405
|
-
"tool_call_id":
|
|
433
|
+
"tool_call_id": tool_call["tool_call_id"],
|
|
406
434
|
}
|
|
407
435
|
],
|
|
408
436
|
"usage_metadata": None,
|
|
409
437
|
"finish_reason": None,
|
|
410
438
|
}
|
|
411
|
-
partial_tool_call = {}
|
|
412
439
|
|
|
413
440
|
if event["finish_reason"] or event["usage_metadata"]:
|
|
414
441
|
yield event
|
|
@@ -96,6 +96,9 @@ class PartialToolCallContentItem(TypedDict):
|
|
|
96
96
|
name: str
|
|
97
97
|
arguments: str
|
|
98
98
|
tool_call_id: str
|
|
99
|
+
# id of the streamed item this fragment belongs to, when the provider sends one (the
|
|
100
|
+
# Responses output item id); ties fragments to their call when several calls stream at once
|
|
101
|
+
item_id: NotRequired[str | None]
|
|
99
102
|
fidelity: NotRequired[Fidelity]
|
|
100
103
|
|
|
101
104
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/openai_chat_vllm_adapter/__init__.py
RENAMED
|
File without changes
|
{agenthub_python-0.4.14 → agenthub_python-0.4.15}/agenthub/openai_chat_vllm_adapter/client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|