unique_toolkit 2026.42.0.dev5__py3-none-any.whl → 2026.42.0.dev7__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.
@@ -1,6 +1,9 @@
1
1
  import logging
2
+ from collections.abc import Sequence
2
3
  from typing import Unpack
3
4
 
5
+ from openai.types.responses import ToolParam, response_create_params
6
+
4
7
  from unique_toolkit.agentic.loop_runner._responses_stream_handler_utils import (
5
8
  responses_stream_response,
6
9
  )
@@ -9,12 +12,44 @@ from unique_toolkit.agentic.loop_runner.base import (
9
12
  )
10
13
  from unique_toolkit.language_model.schemas import (
11
14
  LanguageModelTokenUsage,
15
+ LanguageModelToolDescription,
12
16
  ResponsesLanguageModelStreamResponse,
13
17
  )
14
18
 
15
19
  _LOGGER = logging.getLogger(__name__)
16
20
 
17
21
 
22
+ def _is_forced_function_choice(
23
+ tool_choice: response_create_params.ToolChoice,
24
+ ) -> bool:
25
+ return isinstance(tool_choice, dict) and tool_choice.get("type") == "function"
26
+
27
+
28
+ def _is_hosted_tool(tool: LanguageModelToolDescription | ToolParam) -> bool:
29
+ """Return whether OpenAI executes the tool."""
30
+ if isinstance(tool, LanguageModelToolDescription):
31
+ return False
32
+ return tool.get("type") != "function"
33
+
34
+
35
+ def _tools_for_forced_choice(
36
+ tools: Sequence[LanguageModelToolDescription | ToolParam] | None,
37
+ tool_choice: response_create_params.ToolChoice,
38
+ ) -> list[LanguageModelToolDescription | ToolParam] | None:
39
+ """Drop hosted tools from requests that force a function tool."""
40
+ if tools is None or not _is_forced_function_choice(tool_choice):
41
+ return list(tools) if tools is not None else None
42
+
43
+ remaining = [tool for tool in tools if not _is_hosted_tool(tool)]
44
+ dropped = len(tools) - len(remaining)
45
+ if dropped > 0:
46
+ _LOGGER.info(
47
+ "Dropped %d hosted tool(s) from the forced function request.",
48
+ dropped,
49
+ )
50
+ return remaining
51
+
52
+
18
53
  async def handle_responses_last_iteration(
19
54
  **kwargs: Unpack[_ResponsesLoopIterationRunnerKwargs],
20
55
  ) -> ResponsesLanguageModelStreamResponse:
@@ -47,9 +82,16 @@ async def handle_responses_forced_tools_iteration(
47
82
  responses: list[ResponsesLanguageModelStreamResponse] = []
48
83
 
49
84
  for opt in tool_choices:
50
- responses.append(
51
- await responses_stream_response(loop_runner_kwargs=kwargs, tool_choice=opt)
52
- )
85
+ tools = _tools_for_forced_choice(kwargs.get("tools"), opt)
86
+ if tools is None:
87
+ response = await responses_stream_response(
88
+ loop_runner_kwargs=kwargs, tool_choice=opt
89
+ )
90
+ else:
91
+ response = await responses_stream_response(
92
+ loop_runner_kwargs=kwargs, tool_choice=opt, tools=tools
93
+ )
94
+ responses.append(response)
53
95
 
54
96
  # Merge responses and refs:
55
97
  tool_calls = []
@@ -1825,7 +1825,9 @@ class LanguageModelInfo(BaseModel):
1825
1825
  ),
1826
1826
  info_cutoff_at=date(2026, 1, 1),
1827
1827
  published_at=date(2026, 2, 17),
1828
- supported_reasoning_efforts=[],
1828
+ # Effort includes max. xhigh is not accepted.
1829
+ default_options={"reasoning_effort": "medium"},
1830
+ supported_reasoning_efforts=["low", "medium", "high", "max"],
1829
1831
  )
1830
1832
  case (
1831
1833
  LanguageModelName.ANTHROPIC_CLAUDE_SONNET_5
@@ -1853,7 +1855,15 @@ class LanguageModelInfo(BaseModel):
1853
1855
  temperature_bounds=TemperatureBounds(
1854
1856
  min_temperature=1.0, max_temperature=1.0
1855
1857
  ),
1856
- supported_reasoning_efforts=[],
1858
+ # Effort includes xhigh and max.
1859
+ default_options={"reasoning_effort": "medium"},
1860
+ supported_reasoning_efforts=[
1861
+ "low",
1862
+ "medium",
1863
+ "high",
1864
+ "xhigh",
1865
+ "max",
1866
+ ],
1857
1867
  )
1858
1868
  case (
1859
1869
  LanguageModelName.ANTHROPIC_CLAUDE_SONNET_5_5
@@ -1879,7 +1889,15 @@ class LanguageModelInfo(BaseModel):
1879
1889
  ),
1880
1890
  info_cutoff_at=date(2026, 6, 1),
1881
1891
  published_at=date(2026, 9, 28),
1882
- supported_reasoning_efforts=[],
1892
+ # Effort includes xhigh and max.
1893
+ default_options={"reasoning_effort": "medium"},
1894
+ supported_reasoning_efforts=[
1895
+ "low",
1896
+ "medium",
1897
+ "high",
1898
+ "xhigh",
1899
+ "max",
1900
+ ],
1883
1901
  supports_forced_tool_choice=False,
1884
1902
  )
1885
1903
  case LanguageModelName.ANTHROPIC_CLAUDE_OPUS_4:
@@ -1943,7 +1961,9 @@ class LanguageModelInfo(BaseModel):
1943
1961
  ),
1944
1962
  info_cutoff_at=date(2025, 8, 1),
1945
1963
  published_at=date(2025, 11, 13),
1946
- supported_reasoning_efforts=[],
1964
+ # https://platform.claude.com/docs/en/build-with-claude/effort
1965
+ default_options={"reasoning_effort": "medium"},
1966
+ supported_reasoning_efforts=["low", "medium", "high"],
1947
1967
  )
1948
1968
  case (
1949
1969
  LanguageModelName.ANTHROPIC_CLAUDE_OPUS_4_6
@@ -1967,7 +1987,9 @@ class LanguageModelInfo(BaseModel):
1967
1987
  ),
1968
1988
  info_cutoff_at=date(2025, 8, 1),
1969
1989
  published_at=date(2026, 2, 5),
1970
- supported_reasoning_efforts=[],
1990
+ # Effort includes max. xhigh is not accepted.
1991
+ default_options={"reasoning_effort": "medium"},
1992
+ supported_reasoning_efforts=["low", "medium", "high", "max"],
1971
1993
  )
1972
1994
  case (
1973
1995
  LanguageModelName.ANTHROPIC_CLAUDE_OPUS_4_7
@@ -1992,7 +2014,15 @@ class LanguageModelInfo(BaseModel):
1992
2014
  ),
1993
2015
  info_cutoff_at=date(2026, 1, 1),
1994
2016
  published_at=date(2026, 4, 16),
1995
- supported_reasoning_efforts=[],
2017
+ # Effort includes xhigh and max.
2018
+ default_options={"reasoning_effort": "medium"},
2019
+ supported_reasoning_efforts=[
2020
+ "low",
2021
+ "medium",
2022
+ "high",
2023
+ "xhigh",
2024
+ "max",
2025
+ ],
1996
2026
  )
1997
2027
  case (
1998
2028
  LanguageModelName.ANTHROPIC_CLAUDE_OPUS_4_8
@@ -2017,7 +2047,15 @@ class LanguageModelInfo(BaseModel):
2017
2047
  ),
2018
2048
  info_cutoff_at=date(2026, 1, 1),
2019
2049
  published_at=date(2026, 5, 28),
2020
- supported_reasoning_efforts=[],
2050
+ # Effort includes xhigh and max.
2051
+ default_options={"reasoning_effort": "medium"},
2052
+ supported_reasoning_efforts=[
2053
+ "low",
2054
+ "medium",
2055
+ "high",
2056
+ "xhigh",
2057
+ "max",
2058
+ ],
2021
2059
  )
2022
2060
  case (
2023
2061
  LanguageModelName.ANTHROPIC_CLAUDE_OPUS_5
@@ -2042,7 +2080,15 @@ class LanguageModelInfo(BaseModel):
2042
2080
  ),
2043
2081
  info_cutoff_at=date(2026, 5, 1),
2044
2082
  published_at=date(2026, 7, 24),
2045
- supported_reasoning_efforts=[],
2083
+ # Effort includes xhigh and max.
2084
+ default_options={"reasoning_effort": "medium"},
2085
+ supported_reasoning_efforts=[
2086
+ "low",
2087
+ "medium",
2088
+ "high",
2089
+ "xhigh",
2090
+ "max",
2091
+ ],
2046
2092
  )
2047
2093
  case (
2048
2094
  LanguageModelName.ANTHROPIC_CLAUDE_OPUS_5_5
@@ -2068,7 +2114,15 @@ class LanguageModelInfo(BaseModel):
2068
2114
  ),
2069
2115
  info_cutoff_at=date(2026, 6, 1),
2070
2116
  published_at=date(2026, 9, 22),
2071
- supported_reasoning_efforts=[],
2117
+ # Effort includes xhigh and max. API default is medium.
2118
+ default_options={"reasoning_effort": "medium"},
2119
+ supported_reasoning_efforts=[
2120
+ "low",
2121
+ "medium",
2122
+ "high",
2123
+ "xhigh",
2124
+ "max",
2125
+ ],
2072
2126
  supports_forced_tool_choice=False,
2073
2127
  )
2074
2128
  case (
@@ -2094,7 +2148,15 @@ class LanguageModelInfo(BaseModel):
2094
2148
  ),
2095
2149
  info_cutoff_at=date(2026, 1, 1),
2096
2150
  published_at=date(2026, 7, 1),
2097
- supported_reasoning_efforts=[],
2151
+ # Effort includes xhigh and max.
2152
+ default_options={"reasoning_effort": "medium"},
2153
+ supported_reasoning_efforts=[
2154
+ "low",
2155
+ "medium",
2156
+ "high",
2157
+ "xhigh",
2158
+ "max",
2159
+ ],
2098
2160
  )
2099
2161
  case LanguageModelName.GEMINI_2_0_FLASH:
2100
2162
  return cls(
@@ -2283,7 +2345,9 @@ class LanguageModelInfo(BaseModel):
2283
2345
  ),
2284
2346
  info_cutoff_at=date(2025, 1, day=1),
2285
2347
  published_at=date(2026, 1, 19),
2286
- supported_reasoning_efforts=[],
2348
+ # thinkingLevel is low, medium, or high.
2349
+ default_options={"reasoning_effort": "medium"},
2350
+ supported_reasoning_efforts=["low", "medium", "high"],
2287
2351
  )
2288
2352
  case LanguageModelName.GEMINI_3_6_FLASH:
2289
2353
  return cls(
@@ -2305,6 +2369,7 @@ class LanguageModelInfo(BaseModel):
2305
2369
  ),
2306
2370
  info_cutoff_at=date(2026, 3, day=1),
2307
2371
  published_at=date(2026, 7, 21),
2372
+ default_options={"reasoning_effort": "medium"},
2308
2373
  supported_reasoning_efforts=["minimal", "low", "medium", "high"],
2309
2374
  )
2310
2375
  case (
@@ -2335,6 +2400,7 @@ class LanguageModelInfo(BaseModel):
2335
2400
  published_at=date(2026, 9, 2),
2336
2401
  # minimal is rejected; default thinking level is medium when unset.
2337
2402
  # https://ai.google.dev/gemini-api/docs/models/gemini-3.8-flash
2403
+ default_options={"reasoning_effort": "medium"},
2338
2404
  supported_reasoning_efforts=["low", "medium", "high"],
2339
2405
  )
2340
2406
  case LanguageModelName.GEMINI_3_FLASH_PREVIEW:
@@ -2356,7 +2422,9 @@ class LanguageModelInfo(BaseModel):
2356
2422
  ),
2357
2423
  info_cutoff_at=date(2025, 1, day=1),
2358
2424
  published_at=date(2025, 12, 17),
2359
- supported_reasoning_efforts=[],
2425
+ # thinkingLevel includes minimal. Default when unset is high.
2426
+ default_options={"reasoning_effort": "medium"},
2427
+ supported_reasoning_efforts=["minimal", "low", "medium", "high"],
2360
2428
  )
2361
2429
  case LanguageModelName.GEMINI_3_PRO_PREVIEW:
2362
2430
  return cls(
@@ -2377,7 +2445,9 @@ class LanguageModelInfo(BaseModel):
2377
2445
  ),
2378
2446
  info_cutoff_at=date(2025, 1, day=1),
2379
2447
  published_at=date(2025, 11, 13),
2380
- supported_reasoning_efforts=[],
2448
+ # thinkingLevel is low or high.
2449
+ default_options={"reasoning_effort": "low"},
2450
+ supported_reasoning_efforts=["low", "high"],
2381
2451
  )
2382
2452
  case LanguageModelName.GROK_4_1_FAST_NON_REASONING:
2383
2453
  return cls(
@@ -2446,6 +2516,7 @@ class LanguageModelInfo(BaseModel):
2446
2516
  ),
2447
2517
  info_cutoff_at=date(2026, 2, day=1),
2448
2518
  published_at=date(2026, 7, 16),
2519
+ default_options={"reasoning_effort": "medium"},
2449
2520
  supported_reasoning_efforts=["low", "medium", "high"],
2450
2521
  )
2451
2522
  case LanguageModelName.GROK_4_6:
@@ -3313,7 +3384,9 @@ class LanguageModelInfo(BaseModel):
3313
3384
  token_limit_input=1_000_000, token_limit_output=384_000
3314
3385
  ),
3315
3386
  published_at=date(2026, 1, 1),
3316
- supported_reasoning_efforts=[],
3387
+ # reasoning_effort is high or max.
3388
+ default_options={"reasoning_effort": "high"},
3389
+ supported_reasoning_efforts=["high", "max"],
3317
3390
  )
3318
3391
  case LanguageModelName.LITELLM_DEEPSEEK_V4_1_FLASH:
3319
3392
  return cls(
@@ -3337,7 +3410,9 @@ class LanguageModelInfo(BaseModel):
3337
3410
  token_limits=LanguageModelTokenLimits(
3338
3411
  token_limit_input=1_000_000, token_limit_output=384_000
3339
3412
  ),
3340
- supported_reasoning_efforts=[],
3413
+ # Same V4 effort scale as Pro: high or max.
3414
+ default_options={"reasoning_effort": "high"},
3415
+ supported_reasoning_efforts=["high", "max"],
3341
3416
  )
3342
3417
  case LanguageModelName.LITELLM_GLM_5_1:
3343
3418
  return cls(
@@ -3394,7 +3469,9 @@ class LanguageModelInfo(BaseModel):
3394
3469
  token_limit_input=1_000_000, token_limit_output=1_000_000
3395
3470
  ),
3396
3471
  published_at=date(2026, 7, 31), # HF repo creation date
3397
- supported_reasoning_efforts=[],
3472
+ # Phoeniqs accepts low, high, and max.
3473
+ default_options={"reasoning_effort": "low"},
3474
+ supported_reasoning_efforts=["low", "high", "max"],
3398
3475
  )
3399
3476
  case LanguageModelName.LITELLM_PHOENIQS_GEMMA_4_31B:
3400
3477
  return cls(
@@ -3433,7 +3510,9 @@ class LanguageModelInfo(BaseModel):
3433
3510
  2026, 6, 16
3434
3511
  ), # HF repo creation date — unlike the
3435
3512
  # Together AI entry above, not an unsourced placeholder.
3436
- supported_reasoning_efforts=[],
3513
+ # Phoeniqs accepts low and high.
3514
+ default_options={"reasoning_effort": "low"},
3515
+ supported_reasoning_efforts=["low", "high"],
3437
3516
  )
3438
3517
  case LanguageModelName.LITELLM_PHOENIQS_GLM_5_3_FLASH:
3439
3518
  return cls(
@@ -3516,7 +3595,9 @@ class LanguageModelInfo(BaseModel):
3516
3595
  token_limit_output=128_000,
3517
3596
  ),
3518
3597
  published_at=date(2026, 7, 27),
3519
- supported_reasoning_efforts=[],
3598
+ # reasoning_effort is low, high, or max.
3599
+ default_options={"reasoning_effort": "low"},
3600
+ supported_reasoning_efforts=["low", "high", "max"],
3520
3601
  )
3521
3602
  case LanguageModelName.LITELLM_QWEN_3:
3522
3603
  return cls(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: unique-toolkit
3
- Version: 2026.42.0.dev5
3
+ Version: 2026.42.0.dev7
4
4
  Summary:
5
5
  Author: Cedric Klinkert, Martin Fadler, Sadique Sheik, Fabian Schläpfer, Pascal Hauri, Ejiroghene Oki-Peter, Rami Azouz, Ricardo Visini, Sanzio Monti
6
6
  Author-email: Cedric Klinkert <cedric.klinkert@unique.ch>, Martin Fadler <martin.fadler@unique.ch>, Sadique Sheik <sadique@unique.ch>, Fabian Schläpfer <fabian@unique.ch>, Pascal Hauri <pascal@unique.ch>, Ejiroghene Oki-Peter <oki-peter.ejiroghene@unique.ai>, Rami Azouz <rami.ext@unique.ch>, Ricardo Visini <ricardo.visini@unique.ch>, Sanzio Monti <sanzio.monti@unique.ai>
@@ -120,7 +120,7 @@ unique_toolkit/agentic/history_manager/settings.py,sha256=Lrx3a8yXeU0MXrWlV6RZSH
120
120
  unique_toolkit/agentic/history_manager/utils.py,sha256=DiBip8xtah3I9-G-_Ul3OjlYKunrXR-5RJtzREHWV_0,6579
121
121
  unique_toolkit/agentic/loop_runner/__init__.py,sha256=bhwOIloPn2MZyCw60FkHy330twCCRovg3bgye9OjZRE,1496
122
122
  unique_toolkit/agentic/loop_runner/_iteration_handler_utils.py,sha256=y3tjTAtpkyL_Y7279_3v0fGaq9FUYN3UquwdIB3ZhgI,3831
123
- unique_toolkit/agentic/loop_runner/_responses_iteration_handler_utils.py,sha256=DuQRsToV0KLs7YcFjJVnEmrryhlX5q4isztx2jUxZcI,2064
123
+ unique_toolkit/agentic/loop_runner/_responses_iteration_handler_utils.py,sha256=SbfV5KCZ-3QiMRYjaDDUnY0JuBtfBCSBofF6sxTOugI,3615
124
124
  unique_toolkit/agentic/loop_runner/_responses_stream_handler_utils.py,sha256=6HXpSPGUp096a175-NvXqU2Gw7e8Msjo60CP4wGFOoM,2340
125
125
  unique_toolkit/agentic/loop_runner/_stream_handler_utils.py,sha256=ERk-qS8MG8FM2F2AEzaub_XsuZQD1tsD8-li692LKp0,1708
126
126
  unique_toolkit/agentic/loop_runner/base.py,sha256=OddFwxT7zOOLd2MlAef63BNhzH-NNET8RAsfaMcsHQE,3307
@@ -397,7 +397,7 @@ unique_toolkit/language_model/builder.py,sha256=KwBzsD6-fvQnB4p2I7M-5Tk6j4tmQ973
397
397
  unique_toolkit/language_model/constants.py,sha256=B-topqW0r83dkC_25DeQfnPk3n53qzIHUCBS7YJ0-1U,119
398
398
  unique_toolkit/language_model/default_language_model.py,sha256=mcyuFs_V6tp52C8xJSHiEHO4kFGj6xed1gvozvCRD7k,1181
399
399
  unique_toolkit/language_model/functions.py,sha256=W6JC4LUh-LZ9waDgph--xVmKeQ7Ls6NRAqDx9DwQdeY,26691
400
- unique_toolkit/language_model/infos.py,sha256=y4J53RwG-K5QjRY9EeYQ55ioX-JPZTINBZaenrVAIOo,174566
400
+ unique_toolkit/language_model/infos.py,sha256=O5NBD-3z_8GvifPjxWXGihx-RrUKKhi1wFMojdb7NdA,178580
401
401
  unique_toolkit/language_model/invocation_stats.py,sha256=CQbpUz394IsVd8eNTB1gPSMt5f0UXmkN1amNsqtAW6U,5857
402
402
  unique_toolkit/language_model/model_costs.py,sha256=ShuDAzMew1fUkJ3tzPgU5Zqjp6ivUZaG97BFh93tEn4,6358
403
403
  unique_toolkit/language_model/prompt.py,sha256=JSawaLjQg3VR-E2fK8engFyJnNdk21zaO8pPIodzN4Q,3991
@@ -426,6 +426,6 @@ unique_toolkit/short_term_memory/service.py,sha256=2JMBEBn6GoyK-a0xvdcWpPft-3C74
426
426
  unique_toolkit/smart_rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
427
427
  unique_toolkit/smart_rules/compile.py,sha256=vRe0aMJWuVIK-VsqomgxQImzke7MDmwgSxxJfYCa7zw,1386
428
428
  unique_toolkit/test_utilities/events.py,sha256=FLrhMh0A_mQutAUjoD0FdMcVQ4Gq31r35OVGzRjvLro,6760
429
- unique_toolkit-2026.42.0.dev5.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
430
- unique_toolkit-2026.42.0.dev5.dist-info/METADATA,sha256=zQfpXjEiup6e3ByDDnz0aKemSh-10qr0ujqFVkHJDWE,7821
431
- unique_toolkit-2026.42.0.dev5.dist-info/RECORD,,
429
+ unique_toolkit-2026.42.0.dev7.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
430
+ unique_toolkit-2026.42.0.dev7.dist-info/METADATA,sha256=lerw6mdP9Cp9f4mxf3nMFsJEZg9R_iak69i2o-uZcwU,7821
431
+ unique_toolkit-2026.42.0.dev7.dist-info/RECORD,,